Added entity goals in for 1_18_R1, minor refactoring
This commit is contained in:
@@ -13,29 +13,67 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public interface EntityController<T extends Mob> {
|
||||
/**
|
||||
* Add a target to the entity.
|
||||
* Add a target goal to the entity.
|
||||
* <p>
|
||||
* Mutates the instance.
|
||||
*
|
||||
* @param priority The priority.
|
||||
* @param goal The goal.
|
||||
* @return The entity.
|
||||
* @return The entity controller.
|
||||
*/
|
||||
EntityController<T> addTargetGoal(int priority,
|
||||
@NotNull TargetGoal goal);
|
||||
|
||||
/**
|
||||
* Add a goal to the entity.
|
||||
* Remove all target goals from the entity.
|
||||
* <p>
|
||||
* Mutates the instance.
|
||||
*
|
||||
* @return The entity controller.
|
||||
*/
|
||||
EntityController<T> clearTargetGoals();
|
||||
|
||||
/**
|
||||
* Remove a target goal from the entity.
|
||||
* <p>
|
||||
* Mutates the instance.
|
||||
*
|
||||
* @param goal The goal.
|
||||
* @return The entity controller.
|
||||
*/
|
||||
EntityController<T> removeTargetGoal(@NotNull TargetGoal goal);
|
||||
|
||||
/**
|
||||
* Add an entity goal to the entity.
|
||||
* <p>
|
||||
* Mutates the instance.
|
||||
*
|
||||
* @param priority The priority.
|
||||
* @param goal The goal.
|
||||
* @return The entity.
|
||||
* @return The entity controller.
|
||||
*/
|
||||
EntityController<T> addEntityGoal(int priority,
|
||||
@NotNull EntityGoal goal);
|
||||
|
||||
/**
|
||||
* Remove an entity goal from the entity.
|
||||
* <p>
|
||||
* Mutates the instance.
|
||||
*
|
||||
* @param goal The goal.
|
||||
* @return The entity controller.
|
||||
*/
|
||||
EntityController<T> removeEntityGoal(@NotNull EntityGoal goal);
|
||||
|
||||
/**
|
||||
* Remove all entity goals from the entity.
|
||||
* <p>
|
||||
* Mutates the instance.
|
||||
*
|
||||
* @return The entity controller.
|
||||
*/
|
||||
EntityController<T> clearEntityGoals();
|
||||
|
||||
/**
|
||||
* Get the mob back from the controlled entity.
|
||||
* <p>
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.willfp.eco.core.entities.ai.goals;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A prioritized goal is a goal that has been registered with an entity.
|
||||
*
|
||||
* @param goal The goal.
|
||||
* @param priority The priority.
|
||||
* @param <T> The type of goal.
|
||||
*/
|
||||
public record PrioritizedGoal<T>(
|
||||
@NotNull T goal,
|
||||
int priority
|
||||
) {
|
||||
|
||||
}
|
||||
@@ -13,7 +13,7 @@ public record TargetGoalHurtBy(
|
||||
@NotNull Class<? extends LivingEntity>... blacklist
|
||||
) implements TargetGoal {
|
||||
/**
|
||||
* Create target goal.
|
||||
* Hurt by entity.
|
||||
*
|
||||
* @param blacklist The entities not to attack when hurt by.
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.willfp.eco.internal.spigot.proxy.v1_17_R1.ai
|
||||
|
||||
import com.willfp.eco.core.entities.ai.EntityController
|
||||
import com.willfp.eco.core.entities.ai.goals.EntityGoal
|
||||
import com.willfp.eco.core.entities.ai.goals.PrioritizedGoal
|
||||
import com.willfp.eco.core.entities.ai.goals.TargetGoal
|
||||
import net.minecraft.world.entity.PathfinderMob
|
||||
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity
|
||||
@@ -37,18 +36,11 @@ class EcoEntityController<T : Mob>(
|
||||
return this
|
||||
}
|
||||
|
||||
override fun getEntityGoals(): Set<PrioritizedGoal<EntityGoal>> {
|
||||
val nms = getNms() ?: return emptySet()
|
||||
return nms.goalSelector.availableGoals.map {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun addTargetGoal(priority: Int, goal: TargetGoal): EntityController<T> {
|
||||
val nms = getNms() ?: return this
|
||||
|
||||
nms.targetSelector.addGoal(
|
||||
priority, goal.getGoalFactory().create(goal, nms) ?: return this
|
||||
priority, goal.getGoalFactory()?.create(goal, nms) ?: return this
|
||||
)
|
||||
|
||||
nms.targetSelector
|
||||
@@ -56,10 +48,10 @@ class EcoEntityController<T : Mob>(
|
||||
return this
|
||||
}
|
||||
|
||||
override fun removeTargetGoal(goal: EntityGoal): EntityController<T> {
|
||||
override fun removeTargetGoal(goal: TargetGoal): EntityController<T> {
|
||||
val nms = getNms() ?: return this
|
||||
nms.targetSelector.removeGoal(
|
||||
goal.getGoalFactory().create(goal, nms) ?: return this
|
||||
goal.getGoalFactory()?.create(goal, nms) ?: return this
|
||||
)
|
||||
|
||||
return this
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
|
||||
|
||||
import com.willfp.eco.core.entities.ai.EntityController
|
||||
import com.willfp.eco.internal.spigot.proxy.EntityControllerFactoryProxy
|
||||
import com.willfp.eco.internal.spigot.proxy.v1_18_R1.ai.EcoEntityController
|
||||
import org.bukkit.entity.Mob
|
||||
|
||||
class EntityControllerFactory : EntityControllerFactoryProxy {
|
||||
override fun <T : Mob> createEntityController(entity: T): EntityController<T> {
|
||||
return EcoEntityController(entity)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.willfp.eco.internal.spigot.proxy.v1_18_R1.ai
|
||||
|
||||
import com.willfp.eco.core.entities.ai.EntityController
|
||||
import com.willfp.eco.core.entities.ai.goals.EntityGoal
|
||||
import com.willfp.eco.core.entities.ai.goals.TargetGoal
|
||||
import net.minecraft.world.entity.PathfinderMob
|
||||
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftEntity
|
||||
import org.bukkit.entity.Mob
|
||||
|
||||
class EcoEntityController<T : Mob>(
|
||||
private val handle: T
|
||||
) : EntityController<T> {
|
||||
override fun addEntityGoal(priority: Int, goal: EntityGoal): EntityController<T> {
|
||||
val nms = getNms() ?: return this
|
||||
|
||||
nms.goalSelector.addGoal(
|
||||
priority,
|
||||
goal.getGoalFactory()?.create(goal, nms) ?: return this
|
||||
)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
override fun removeEntityGoal(goal: EntityGoal): EntityController<T> {
|
||||
val nms = getNms() ?: return this
|
||||
nms.goalSelector.removeGoal(
|
||||
goal.getGoalFactory()?.create(goal, nms) ?: return this
|
||||
)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
override fun clearEntityGoals(): EntityController<T> {
|
||||
val nms = getNms() ?: return this
|
||||
nms.goalSelector.availableGoals.clear()
|
||||
return this
|
||||
}
|
||||
|
||||
override fun addTargetGoal(priority: Int, goal: TargetGoal): EntityController<T> {
|
||||
val nms = getNms() ?: return this
|
||||
|
||||
nms.targetSelector.addGoal(
|
||||
priority, goal.getGoalFactory()?.create(goal, nms) ?: return this
|
||||
)
|
||||
|
||||
nms.targetSelector
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
override fun removeTargetGoal(goal: TargetGoal): EntityController<T> {
|
||||
val nms = getNms() ?: return this
|
||||
nms.targetSelector.removeGoal(
|
||||
goal.getGoalFactory()?.create(goal, nms) ?: return this
|
||||
)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
override fun clearTargetGoals(): EntityController<T> {
|
||||
val nms = getNms() ?: return this
|
||||
nms.targetSelector.availableGoals.clear()
|
||||
return this
|
||||
}
|
||||
|
||||
private fun getNms(): PathfinderMob? {
|
||||
val craft = handle as? CraftEntity ?: return null
|
||||
return craft.handle as? PathfinderMob
|
||||
}
|
||||
|
||||
override fun getEntity(): T {
|
||||
return handle
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,429 @@
|
||||
package com.willfp.eco.internal.spigot.proxy.v1_18_R1.ai
|
||||
|
||||
import com.willfp.eco.core.entities.ai.goals.EntityGoal
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalAvoidEntity
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalBreakDoor
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalBreatheAir
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalEatBlock
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalFleeSun
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalFloat
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalFollowBoats
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalFollowMobs
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalInteract
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalLeapAtTarget
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalLookAtPlayer
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalMeleeAttack
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalMoveBackToVillage
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalMoveThroughVillage
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalMoveTowardsRestriction
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalMoveTowardsTarget
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalOcelotAttack
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalOpenDoors
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalPanic
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalRandomLookAround
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalRandomStroll
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalRandomSwimming
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalRangedAttack
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalRangedBowAttack
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalRangedCrossbowAttack
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalRestrictSun
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalStrollThroughVillage
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalTempt
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalTryFindWater
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalUseItem
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalWaterAvoidingRandomFlying
|
||||
import com.willfp.eco.core.entities.ai.goals.entity.EntityGoalWaterAvoidingRandomStroll
|
||||
import net.minecraft.sounds.SoundEvent
|
||||
import net.minecraft.world.entity.PathfinderMob
|
||||
import net.minecraft.world.entity.ai.goal.AvoidEntityGoal
|
||||
import net.minecraft.world.entity.ai.goal.BreakDoorGoal
|
||||
import net.minecraft.world.entity.ai.goal.BreathAirGoal
|
||||
import net.minecraft.world.entity.ai.goal.EatBlockGoal
|
||||
import net.minecraft.world.entity.ai.goal.FleeSunGoal
|
||||
import net.minecraft.world.entity.ai.goal.FloatGoal
|
||||
import net.minecraft.world.entity.ai.goal.FollowBoatGoal
|
||||
import net.minecraft.world.entity.ai.goal.FollowMobGoal
|
||||
import net.minecraft.world.entity.ai.goal.Goal
|
||||
import net.minecraft.world.entity.ai.goal.InteractGoal
|
||||
import net.minecraft.world.entity.ai.goal.LeapAtTargetGoal
|
||||
import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal
|
||||
import net.minecraft.world.entity.ai.goal.MeleeAttackGoal
|
||||
import net.minecraft.world.entity.ai.goal.MoveBackToVillageGoal
|
||||
import net.minecraft.world.entity.ai.goal.MoveThroughVillageGoal
|
||||
import net.minecraft.world.entity.ai.goal.MoveTowardsRestrictionGoal
|
||||
import net.minecraft.world.entity.ai.goal.MoveTowardsTargetGoal
|
||||
import net.minecraft.world.entity.ai.goal.OcelotAttackGoal
|
||||
import net.minecraft.world.entity.ai.goal.OpenDoorGoal
|
||||
import net.minecraft.world.entity.ai.goal.PanicGoal
|
||||
import net.minecraft.world.entity.ai.goal.RandomLookAroundGoal
|
||||
import net.minecraft.world.entity.ai.goal.RandomStrollGoal
|
||||
import net.minecraft.world.entity.ai.goal.RandomSwimmingGoal
|
||||
import net.minecraft.world.entity.ai.goal.RangedAttackGoal
|
||||
import net.minecraft.world.entity.ai.goal.RangedBowAttackGoal
|
||||
import net.minecraft.world.entity.ai.goal.RangedCrossbowAttackGoal
|
||||
import net.minecraft.world.entity.ai.goal.RestrictSunGoal
|
||||
import net.minecraft.world.entity.ai.goal.StrollThroughVillageGoal
|
||||
import net.minecraft.world.entity.ai.goal.TemptGoal
|
||||
import net.minecraft.world.entity.ai.goal.TryFindWaterGoal
|
||||
import net.minecraft.world.entity.ai.goal.UseItemGoal
|
||||
import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomFlyingGoal
|
||||
import net.minecraft.world.entity.ai.goal.WaterAvoidingRandomStrollGoal
|
||||
import net.minecraft.world.entity.monster.RangedAttackMob
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.crafting.Ingredient
|
||||
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack
|
||||
import org.bukkit.craftbukkit.v1_18_R1.util.CraftNamespacedKey
|
||||
|
||||
fun <T : EntityGoal> T.getGoalFactory(): EntityGoalFactory<T>? {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return when (this) {
|
||||
is EntityGoalAvoidEntity -> AvoidEntityGoalFactory
|
||||
is EntityGoalBreakDoor -> BreakDoorGoalFactory
|
||||
is EntityGoalBreatheAir -> BreatheAirGoalFactory
|
||||
is EntityGoalEatBlock -> EatBlockGoalFactory
|
||||
is EntityGoalFleeSun -> FleeSunGoalFactory
|
||||
is EntityGoalFloat -> FloatGoalFactory
|
||||
is EntityGoalFollowBoats -> FollowBoatsGoalFactory
|
||||
is EntityGoalFollowMobs -> FollowMobsGoalFactory
|
||||
is EntityGoalInteract -> InteractGoalFactory
|
||||
is EntityGoalLeapAtTarget -> LeapAtTargetGoalFactory
|
||||
is EntityGoalLookAtPlayer -> LookAtPlayerGoalFactory
|
||||
is EntityGoalMeleeAttack -> MeleeAttackGoalFactory
|
||||
is EntityGoalMoveBackToVillage -> MoveBackToVillageGoalFactory
|
||||
is EntityGoalMoveThroughVillage -> MoveThroughVillageGoalFactory
|
||||
is EntityGoalMoveTowardsRestriction -> MoveTowardsRestrictionGoalFactory
|
||||
is EntityGoalMoveTowardsTarget -> MoveTowardsTargetGoalFactory
|
||||
is EntityGoalOcelotAttack -> OcelotAttackGoalFactory
|
||||
is EntityGoalOpenDoors -> OpenDoorsGoalFactory
|
||||
is EntityGoalPanic -> PanicGoalFactory
|
||||
is EntityGoalRandomLookAround -> RandomLookAroundGoalFactory
|
||||
is EntityGoalRandomStroll -> RandomStrollGoalFactory
|
||||
is EntityGoalRandomSwimming -> RandomSwimmingGoalFactory
|
||||
is EntityGoalRangedAttack -> RangedAttackGoalFactory
|
||||
is EntityGoalRangedBowAttack -> RangedBowAttackGoalFactory
|
||||
is EntityGoalRangedCrossbowAttack -> RangedCrossbowAttackGoalFactory
|
||||
is EntityGoalRestrictSun -> RestrictSunGoalFactory
|
||||
is EntityGoalStrollThroughVillage -> StrollThroughVillageGoalFactory
|
||||
is EntityGoalTempt -> TemptGoalFactory
|
||||
is EntityGoalTryFindWater -> TryFindWaterGoalFactory
|
||||
is EntityGoalUseItem -> UseItemGoalFactory
|
||||
is EntityGoalWaterAvoidingRandomFlying -> WaterAvoidingRandomFlyingGoalFactory
|
||||
is EntityGoalWaterAvoidingRandomStroll -> WaterAvoidingRandomStrollGoalFactory
|
||||
else -> null
|
||||
} as EntityGoalFactory<T>?
|
||||
}
|
||||
|
||||
interface EntityGoalFactory<T : EntityGoal> {
|
||||
fun create(apiGoal: T, entity: PathfinderMob): Goal?
|
||||
}
|
||||
|
||||
object AvoidEntityGoalFactory : EntityGoalFactory<EntityGoalAvoidEntity> {
|
||||
override fun create(apiGoal: EntityGoalAvoidEntity, entity: PathfinderMob): Goal {
|
||||
return AvoidEntityGoal(
|
||||
entity,
|
||||
apiGoal.avoidClass.toNMSClass(),
|
||||
apiGoal.fleeDistance.toFloat(),
|
||||
apiGoal.slowSpeed,
|
||||
apiGoal.fastSpeed
|
||||
) { apiGoal.filter.test(it.toBukkitEntity()) }
|
||||
}
|
||||
}
|
||||
|
||||
object BreakDoorGoalFactory : EntityGoalFactory<EntityGoalBreakDoor> {
|
||||
override fun create(apiGoal: EntityGoalBreakDoor, entity: PathfinderMob): Goal {
|
||||
return BreakDoorGoal(
|
||||
entity,
|
||||
apiGoal.maxProgress
|
||||
) { true }
|
||||
}
|
||||
}
|
||||
|
||||
object BreatheAirGoalFactory : EntityGoalFactory<EntityGoalBreatheAir> {
|
||||
override fun create(apiGoal: EntityGoalBreatheAir, entity: PathfinderMob): Goal {
|
||||
return BreathAirGoal(
|
||||
entity
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object EatBlockGoalFactory : EntityGoalFactory<EntityGoalEatBlock> {
|
||||
override fun create(apiGoal: EntityGoalEatBlock, entity: PathfinderMob): Goal {
|
||||
return EatBlockGoal(
|
||||
entity
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object FleeSunGoalFactory : EntityGoalFactory<EntityGoalFleeSun> {
|
||||
override fun create(apiGoal: EntityGoalFleeSun, entity: PathfinderMob): Goal {
|
||||
return FleeSunGoal(
|
||||
entity,
|
||||
apiGoal.speed
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object FloatGoalFactory : EntityGoalFactory<EntityGoalFloat> {
|
||||
override fun create(apiGoal: EntityGoalFloat, entity: PathfinderMob): Goal {
|
||||
return FloatGoal(
|
||||
entity
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object FollowBoatsGoalFactory : EntityGoalFactory<EntityGoalFollowBoats> {
|
||||
override fun create(apiGoal: EntityGoalFollowBoats, entity: PathfinderMob): Goal {
|
||||
return FollowBoatGoal(
|
||||
entity
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object FollowMobsGoalFactory : EntityGoalFactory<EntityGoalFollowMobs> {
|
||||
override fun create(apiGoal: EntityGoalFollowMobs, entity: PathfinderMob): Goal {
|
||||
return FollowMobGoal(
|
||||
entity,
|
||||
apiGoal.speed,
|
||||
apiGoal.minDistance.toFloat(),
|
||||
apiGoal.maxDistance.toFloat(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object InteractGoalFactory : EntityGoalFactory<EntityGoalInteract> {
|
||||
override fun create(apiGoal: EntityGoalInteract, entity: PathfinderMob): Goal {
|
||||
return InteractGoal(
|
||||
entity,
|
||||
apiGoal.targetClass.toNMSClass(),
|
||||
apiGoal.range.toFloat(),
|
||||
apiGoal.chance.toFloat() / 100f,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object LeapAtTargetGoalFactory : EntityGoalFactory<EntityGoalLeapAtTarget> {
|
||||
override fun create(apiGoal: EntityGoalLeapAtTarget, entity: PathfinderMob): Goal {
|
||||
return LeapAtTargetGoal(
|
||||
entity,
|
||||
apiGoal.velocity.toFloat()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object LookAtPlayerGoalFactory : EntityGoalFactory<EntityGoalLookAtPlayer> {
|
||||
override fun create(apiGoal: EntityGoalLookAtPlayer, entity: PathfinderMob): Goal {
|
||||
return LookAtPlayerGoal(
|
||||
entity,
|
||||
Player::class.java,
|
||||
apiGoal.range.toFloat(),
|
||||
apiGoal.chance.toFloat() / 100f,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object MeleeAttackGoalFactory : EntityGoalFactory<EntityGoalMeleeAttack> {
|
||||
override fun create(apiGoal: EntityGoalMeleeAttack, entity: PathfinderMob): Goal {
|
||||
return MeleeAttackGoal(
|
||||
entity,
|
||||
apiGoal.speed,
|
||||
apiGoal.pauseWhenMobIdle
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object MoveBackToVillageGoalFactory : EntityGoalFactory<EntityGoalMoveBackToVillage> {
|
||||
override fun create(apiGoal: EntityGoalMoveBackToVillage, entity: PathfinderMob): Goal {
|
||||
return MoveBackToVillageGoal(
|
||||
entity,
|
||||
apiGoal.speed,
|
||||
apiGoal.canDespawn
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object MoveThroughVillageGoalFactory : EntityGoalFactory<EntityGoalMoveThroughVillage> {
|
||||
override fun create(apiGoal: EntityGoalMoveThroughVillage, entity: PathfinderMob): Goal {
|
||||
return MoveThroughVillageGoal(
|
||||
entity,
|
||||
apiGoal.speed,
|
||||
apiGoal.onlyAtNight,
|
||||
apiGoal.distance,
|
||||
apiGoal.canPassThroughDoorsGetter
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object MoveTowardsRestrictionGoalFactory : EntityGoalFactory<EntityGoalMoveTowardsRestriction> {
|
||||
override fun create(apiGoal: EntityGoalMoveTowardsRestriction, entity: PathfinderMob): Goal {
|
||||
return MoveTowardsRestrictionGoal(
|
||||
entity,
|
||||
apiGoal.speed
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object MoveTowardsTargetGoalFactory : EntityGoalFactory<EntityGoalMoveTowardsTarget> {
|
||||
override fun create(apiGoal: EntityGoalMoveTowardsTarget, entity: PathfinderMob): Goal {
|
||||
return MoveTowardsTargetGoal(
|
||||
entity,
|
||||
apiGoal.speed,
|
||||
apiGoal.maxDistance.toFloat()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object OcelotAttackGoalFactory : EntityGoalFactory<EntityGoalOcelotAttack> {
|
||||
override fun create(apiGoal: EntityGoalOcelotAttack, entity: PathfinderMob): Goal {
|
||||
return OcelotAttackGoal(
|
||||
entity
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object OpenDoorsGoalFactory : EntityGoalFactory<EntityGoalOpenDoors> {
|
||||
override fun create(apiGoal: EntityGoalOpenDoors, entity: PathfinderMob): Goal {
|
||||
return OpenDoorGoal(
|
||||
entity,
|
||||
apiGoal.delayedClose
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object PanicGoalFactory : EntityGoalFactory<EntityGoalPanic> {
|
||||
override fun create(apiGoal: EntityGoalPanic, entity: PathfinderMob): Goal {
|
||||
return PanicGoal(
|
||||
entity,
|
||||
apiGoal.speed
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object RandomLookAroundGoalFactory : EntityGoalFactory<EntityGoalRandomLookAround> {
|
||||
override fun create(apiGoal: EntityGoalRandomLookAround, entity: PathfinderMob): Goal {
|
||||
return RandomLookAroundGoal(
|
||||
entity
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object RandomStrollGoalFactory : EntityGoalFactory<EntityGoalRandomStroll> {
|
||||
override fun create(apiGoal: EntityGoalRandomStroll, entity: PathfinderMob): Goal {
|
||||
return RandomStrollGoal(
|
||||
entity,
|
||||
apiGoal.speed,
|
||||
apiGoal.interval,
|
||||
apiGoal.canDespawn
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object RandomSwimmingGoalFactory : EntityGoalFactory<EntityGoalRandomSwimming> {
|
||||
override fun create(apiGoal: EntityGoalRandomSwimming, entity: PathfinderMob): Goal {
|
||||
return RandomSwimmingGoal(
|
||||
entity,
|
||||
apiGoal.speed,
|
||||
apiGoal.interval
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object RangedAttackGoalFactory : EntityGoalFactory<EntityGoalRangedAttack> {
|
||||
override fun create(apiGoal: EntityGoalRangedAttack, entity: PathfinderMob): Goal? {
|
||||
return RangedAttackGoal(
|
||||
entity as? RangedAttackMob ?: return null,
|
||||
apiGoal.mobSpeed,
|
||||
apiGoal.minInterval,
|
||||
apiGoal.maxInterval,
|
||||
apiGoal.maxRange.toFloat()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object RangedBowAttackGoalFactory : EntityGoalFactory<EntityGoalRangedBowAttack> {
|
||||
override fun create(apiGoal: EntityGoalRangedBowAttack, entity: PathfinderMob): Goal? {
|
||||
return RangedBowAttackGoal(
|
||||
entity.tryCast() ?: return null,
|
||||
apiGoal.speed,
|
||||
apiGoal.attackInterval,
|
||||
apiGoal.range.toFloat()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object RangedCrossbowAttackGoalFactory : EntityGoalFactory<EntityGoalRangedCrossbowAttack> {
|
||||
override fun create(apiGoal: EntityGoalRangedCrossbowAttack, entity: PathfinderMob): Goal? {
|
||||
return RangedCrossbowAttackGoal(
|
||||
entity.tryCast() ?: return null,
|
||||
apiGoal.speed,
|
||||
apiGoal.range.toFloat()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object RestrictSunGoalFactory : EntityGoalFactory<EntityGoalRestrictSun> {
|
||||
override fun create(apiGoal: EntityGoalRestrictSun, entity: PathfinderMob): Goal {
|
||||
return RestrictSunGoal(
|
||||
entity
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object StrollThroughVillageGoalFactory : EntityGoalFactory<EntityGoalStrollThroughVillage> {
|
||||
override fun create(apiGoal: EntityGoalStrollThroughVillage, entity: PathfinderMob): Goal {
|
||||
return StrollThroughVillageGoal(
|
||||
entity,
|
||||
apiGoal.searchRange
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object TemptGoalFactory : EntityGoalFactory<EntityGoalTempt> {
|
||||
override fun create(apiGoal: EntityGoalTempt, entity: PathfinderMob): Goal {
|
||||
return TemptGoal(
|
||||
entity,
|
||||
apiGoal.speed,
|
||||
Ingredient.of(*apiGoal.items.map { CraftItemStack.asNMSCopy(it) }.toTypedArray()),
|
||||
apiGoal.canBeScared
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object TryFindWaterGoalFactory : EntityGoalFactory<EntityGoalTryFindWater> {
|
||||
override fun create(apiGoal: EntityGoalTryFindWater, entity: PathfinderMob): Goal {
|
||||
return TryFindWaterGoal(
|
||||
entity
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object UseItemGoalFactory : EntityGoalFactory<EntityGoalUseItem> {
|
||||
override fun create(apiGoal: EntityGoalUseItem, entity: PathfinderMob): Goal {
|
||||
return UseItemGoal(
|
||||
entity,
|
||||
CraftItemStack.asNMSCopy(apiGoal.item),
|
||||
SoundEvent(CraftNamespacedKey.toMinecraft(apiGoal.sound.key)),
|
||||
) {
|
||||
apiGoal.condition.test(it.toBukkitEntity())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object WaterAvoidingRandomFlyingGoalFactory : EntityGoalFactory<EntityGoalWaterAvoidingRandomFlying> {
|
||||
override fun create(apiGoal: EntityGoalWaterAvoidingRandomFlying, entity: PathfinderMob): Goal {
|
||||
return WaterAvoidingRandomFlyingGoal(
|
||||
entity,
|
||||
apiGoal.speed
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object WaterAvoidingRandomStrollGoalFactory : EntityGoalFactory<EntityGoalWaterAvoidingRandomStroll> {
|
||||
override fun create(apiGoal: EntityGoalWaterAvoidingRandomStroll, entity: PathfinderMob): Goal {
|
||||
return WaterAvoidingRandomStrollGoal(
|
||||
entity,
|
||||
apiGoal.speed,
|
||||
apiGoal.chance.toFloat() / 100
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.willfp.eco.internal.spigot.proxy.v1_18_R1.ai
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Caffeine
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache
|
||||
import net.minecraft.world.entity.AgeableMob
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraft.world.entity.PathfinderMob
|
||||
import net.minecraft.world.entity.TamableAnimal
|
||||
import net.minecraft.world.entity.ambient.AmbientCreature
|
||||
import net.minecraft.world.entity.animal.Animal
|
||||
import net.minecraft.world.entity.monster.AbstractIllager
|
||||
import net.minecraft.world.entity.monster.SpellcasterIllager
|
||||
import net.minecraft.world.entity.monster.piglin.AbstractPiglin
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.craftbukkit.v1_18_R1.CraftServer
|
||||
import org.bukkit.craftbukkit.v1_18_R1.CraftWorld
|
||||
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftEntity
|
||||
import org.bukkit.entity.AbstractHorse
|
||||
import org.bukkit.entity.AbstractSkeleton
|
||||
import org.bukkit.entity.AbstractVillager
|
||||
import org.bukkit.entity.Ageable
|
||||
import org.bukkit.entity.Ambient
|
||||
import org.bukkit.entity.Animals
|
||||
import org.bukkit.entity.HumanEntity
|
||||
import org.bukkit.entity.Illager
|
||||
import org.bukkit.entity.Mob
|
||||
import org.bukkit.entity.Monster
|
||||
import org.bukkit.entity.PiglinAbstract
|
||||
import org.bukkit.entity.Spellcaster
|
||||
import org.bukkit.entity.Tameable
|
||||
import java.util.Optional
|
||||
|
||||
private val mappedClasses = mapOf(
|
||||
Pair(AbstractHorse::class.java, net.minecraft.world.entity.animal.horse.AbstractHorse::class.java),
|
||||
Pair(AbstractSkeleton::class.java, net.minecraft.world.entity.monster.AbstractSkeleton::class.java),
|
||||
Pair(AbstractVillager::class.java, net.minecraft.world.entity.npc.AbstractVillager::class.java),
|
||||
Pair(Ageable::class.java, AgeableMob::class.java),
|
||||
Pair(Ambient::class.java, AmbientCreature::class.java),
|
||||
Pair(Animals::class.java, Animal::class.java),
|
||||
Pair(HumanEntity::class.java, Player::class.java), // Can't spawn players
|
||||
Pair(Illager::class.java, AbstractIllager::class.java),
|
||||
Pair(Mob::class.java, net.minecraft.world.entity.Mob::class.java),
|
||||
Pair(Monster::class.java, net.minecraft.world.entity.monster.Monster::class.java),
|
||||
Pair(PiglinAbstract::class.java, AbstractPiglin::class.java),
|
||||
Pair(org.bukkit.entity.Player::class.java, Player::class.java), // Can't spawn players
|
||||
Pair(Spellcaster::class.java, SpellcasterIllager::class.java),
|
||||
Pair(Tameable::class.java, TamableAnimal::class.java)
|
||||
)
|
||||
|
||||
private val cache: LoadingCache<Class<out org.bukkit.entity.LivingEntity>, Optional<Class<out LivingEntity>>> =
|
||||
Caffeine.newBuilder()
|
||||
.build {
|
||||
val mapped = mappedClasses[it]
|
||||
if (mapped != null) {
|
||||
return@build Optional.of(mapped)
|
||||
}
|
||||
|
||||
val world = Bukkit.getWorlds().first() as CraftWorld
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val nmsClass = Optional.ofNullable(runCatching {
|
||||
world.createEntity(
|
||||
Location(world, 0.0, 100.0, 0.0),
|
||||
it
|
||||
)::class.java as Class<out LivingEntity>
|
||||
}.getOrNull())
|
||||
|
||||
return@build nmsClass
|
||||
}
|
||||
|
||||
fun <T : org.bukkit.entity.LivingEntity> Class<T>.toNMSClass(): Class<out LivingEntity> =
|
||||
cache.get(this).orElseThrow { IllegalArgumentException("Invalid/Unsupported entity type!") }
|
||||
|
||||
fun LivingEntity.toBukkitEntity(): org.bukkit.entity.LivingEntity? =
|
||||
CraftEntity.getEntity(Bukkit.getServer() as CraftServer, this) as? org.bukkit.entity.LivingEntity
|
||||
|
||||
fun <T> PathfinderMob.tryCast(): T? {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return this as? T
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.willfp.eco.internal.spigot.proxy.v1_18_R1.ai
|
||||
|
||||
import com.willfp.eco.core.entities.ai.goals.TargetGoal
|
||||
import com.willfp.eco.core.entities.ai.goals.target.TargetGoalHurtBy
|
||||
import com.willfp.eco.core.entities.ai.goals.target.TargetGoalNearestAttackable
|
||||
import net.minecraft.world.entity.PathfinderMob
|
||||
import net.minecraft.world.entity.ai.goal.Goal
|
||||
import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal
|
||||
import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal
|
||||
|
||||
fun <T : TargetGoal> T.getGoalFactory(): TargetGoalFactory<T>? {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return when (this) {
|
||||
is TargetGoalHurtBy -> HurtByGoalFactory
|
||||
is TargetGoalNearestAttackable -> NearestAttackableGoalFactory
|
||||
else -> null
|
||||
} as TargetGoalFactory<T>?
|
||||
}
|
||||
|
||||
interface TargetGoalFactory<T : TargetGoal> {
|
||||
fun create(apiGoal: T, entity: PathfinderMob): Goal?
|
||||
}
|
||||
|
||||
object HurtByGoalFactory : TargetGoalFactory<TargetGoalHurtBy> {
|
||||
override fun create(apiGoal: TargetGoalHurtBy, entity: PathfinderMob): Goal {
|
||||
return HurtByTargetGoal(
|
||||
entity,
|
||||
*apiGoal.blacklist.map { it.toNMSClass() }.toTypedArray()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object NearestAttackableGoalFactory : TargetGoalFactory<TargetGoalNearestAttackable> {
|
||||
override fun create(apiGoal: TargetGoalNearestAttackable, entity: PathfinderMob): Goal {
|
||||
return NearestAttackableTargetGoal(
|
||||
entity,
|
||||
apiGoal.targetClass.toNMSClass(),
|
||||
apiGoal.checkVisibility
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user