Began entity controller system

This commit is contained in:
Auxilor
2022-03-01 18:04:27 +00:00
parent 92f8787eb9
commit 32ef8d8c5c
10 changed files with 170 additions and 0 deletions

View File

@@ -5,6 +5,7 @@ import com.willfp.eco.core.config.wrapper.ConfigFactory;
import com.willfp.eco.core.data.ProfileHandler;
import com.willfp.eco.core.data.keys.KeyRegistry;
import com.willfp.eco.core.drops.DropQueueFactory;
import com.willfp.eco.core.entities.ai.ControlledEntity;
import com.willfp.eco.core.events.EventManager;
import com.willfp.eco.core.extensions.ExtensionLoader;
import com.willfp.eco.core.factory.MetadataValueFactory;
@@ -20,6 +21,7 @@ import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Mob;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
@@ -262,4 +264,13 @@ public interface Handler {
@NotNull
PluginProps getProps(@Nullable PluginProps existing,
@NotNull Class<? extends EcoPlugin> plugin);
/**
* Create controlled entity from a mob.
*
* @param mob The mob.
* @return The controlled entity.
*/
@NotNull
ControlledEntity createControlledEntity(@NotNull Mob mob);
}

View File

@@ -0,0 +1,48 @@
package com.willfp.eco.core.entities.ai;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.entities.ai.goals.EntityGoal;
import org.bukkit.entity.Mob;
import org.jetbrains.annotations.NotNull;
/**
* A controlled entity allows for adding targets and goals to entities.
*/
public interface ControlledEntity {
/**
* Add a target to the entity.
*
* @param priority The priority.
* @param goal The goal.
* @return The entity.
*/
ControlledEntity addTarget(int priority,
@NotNull EntityGoal goal);
/**
* Add a goal to the entity.
*
* @param priority The priority.
* @param goal The goal.
* @return The entity.
*/
ControlledEntity addGoal(int priority,
@NotNull EntityGoal goal);
/**
* Get the mob back from the controlled entity.
*
* @return The mob.
*/
Mob getEntity();
/**
* Wrap an entity into a controlled entity in order to modify targets and goals.
*
* @param entity The entity.
* @return The controlled entity.
*/
static ControlledEntity from(@NotNull final Mob entity) {
return Eco.getHandler().createControlledEntity(entity);
}
}

View File

@@ -0,0 +1,8 @@
package com.willfp.eco.core.entities.ai.goals;
/**
* A goal for entity AI.
*/
public interface EntityGoal {
}

View File

@@ -0,0 +1,11 @@
package com.willfp.eco.core.entities.ai.goals;
import org.bukkit.entity.LivingEntity;
import org.jetbrains.annotations.NotNull;
public record EntityGoalNearestAttackableTarget(
@NotNull Class<? extends LivingEntity> targetClass,
boolean checkVisibility
) implements EntityGoal {
}

View File

@@ -0,0 +1,12 @@
package com.willfp.eco.internal.spigot.proxy.v1_17_R1
import com.willfp.eco.core.entities.ai.ControlledEntity
import com.willfp.eco.internal.spigot.proxy.ControlledEntityFactoryProxy
import com.willfp.eco.internal.spigot.proxy.v1_17_R1.ai.EcoControlledEntity
import org.bukkit.entity.Mob
class ControlledEntityFactory : ControlledEntityFactoryProxy {
override fun createControlledEntity(entity: Mob): ControlledEntity {
return EcoControlledEntity(entity)
}
}

View File

@@ -0,0 +1,32 @@
package com.willfp.eco.internal.spigot.proxy.v1_17_R1.ai
import com.willfp.eco.core.entities.ai.ControlledEntity
import com.willfp.eco.core.entities.ai.goals.EntityGoal
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity
import org.bukkit.entity.Mob
class EcoControlledEntity(
private val handle: Mob
) : ControlledEntity {
override fun addGoal(priority: Int, goal: EntityGoal): ControlledEntity {
val craft = handle as? CraftEntity ?: return this
val nms = craft.handle as? net.minecraft.world.entity.Mob ?: return this
nms.goalSelector.addGoal(priority, GoalFactory.getImplementation(goal).generateNMSGoal(goal, nms))
return this
}
override fun addTarget(priority: Int, goal: EntityGoal): ControlledEntity {
val craft = handle as? CraftEntity ?: return this
val nms = craft.handle as? net.minecraft.world.entity.Mob ?: return this
nms.targetSelector.addGoal(priority, GoalFactory.getImplementation(goal).generateNMSGoal(goal, nms))
return this
}
override fun getEntity(): Mob {
return handle
}
}

View File

@@ -0,0 +1,17 @@
package com.willfp.eco.internal.spigot.proxy.v1_17_R1.ai
import com.willfp.eco.core.entities.ai.goals.EntityGoal
import com.willfp.eco.core.entities.ai.goals.EntityGoalNearestAttackableTarget
import net.minecraft.world.entity.Mob
import net.minecraft.world.entity.ai.goal.Goal
import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal
interface EcoEntityGoal<T : EntityGoal> {
fun generateNMSGoal(apiGoal: T, entity: Mob): Goal
}
class NearestAttackableTargetImpl : EcoEntityGoal<EntityGoalNearestAttackableTarget> {
override fun generateNMSGoal(apiGoal: EntityGoalNearestAttackableTarget, entity: Mob): Goal {
return NearestAttackableTargetGoal(entity, apiGoal.targetClass, apiGoal.checkVisibility)
}
}

View File

@@ -0,0 +1,14 @@
package com.willfp.eco.internal.spigot.proxy.v1_17_R1.ai
import com.willfp.eco.core.entities.ai.goals.EntityGoal
import com.willfp.eco.core.entities.ai.goals.EntityGoalNearestAttackableTarget
object GoalFactory {
fun <T : EntityGoal> getImplementation(apiGoal: T): EcoEntityGoal<T> {
@Suppress("UNCHECKED_CAST")
return when (apiGoal) {
is EntityGoalNearestAttackableTarget -> NearestAttackableTargetImpl()
else -> throw IllegalArgumentException("Unknown API goal!")
} as EcoEntityGoal<T>
}
}

View File

@@ -3,6 +3,7 @@ package com.willfp.eco.internal.spigot
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.Handler
import com.willfp.eco.core.PluginProps
import com.willfp.eco.core.entities.ai.ControlledEntity
import com.willfp.eco.core.fast.FastItemStack
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration
import com.willfp.eco.internal.EcoCleaner
@@ -28,12 +29,14 @@ import com.willfp.eco.internal.spigot.data.DataYml
import com.willfp.eco.internal.spigot.data.EcoKeyRegistry
import com.willfp.eco.internal.spigot.data.EcoProfileHandler
import com.willfp.eco.internal.spigot.integrations.bstats.MetricHandler
import com.willfp.eco.internal.spigot.proxy.ControlledEntityFactoryProxy
import com.willfp.eco.internal.spigot.proxy.DummyEntityFactoryProxy
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
import net.kyori.adventure.platform.bukkit.BukkitAudiences
import org.bukkit.Location
import org.bukkit.NamespacedKey
import org.bukkit.entity.Entity
import org.bukkit.entity.Mob
import org.bukkit.inventory.ItemStack
import java.util.logging.Logger
@@ -160,4 +163,8 @@ class EcoHandler : EcoSpigotPlugin(), Handler {
override fun getProps(existing: PluginProps?, plugin: Class<out EcoPlugin>): PluginProps {
return existing ?: EcoPropsParser.parseForPlugin(plugin)
}
override fun createControlledEntity(mob: Mob): ControlledEntity {
return getProxy(ControlledEntityFactoryProxy::class.java).createControlledEntity(mob)
}
}

View File

@@ -0,0 +1,10 @@
package com.willfp.eco.internal.spigot.proxy
import com.willfp.eco.core.entities.ai.ControlledEntity
import org.bukkit.entity.Mob
interface ControlledEntityFactoryProxy {
fun createControlledEntity(
entity: Mob
): ControlledEntity
}