Added entity goals in for 1_18_R1, minor refactoring

This commit is contained in:
Auxilor
2022-03-01 21:10:02 +00:00
parent 957af5c5bf
commit a02dd06c20
9 changed files with 684 additions and 33 deletions

View File

@@ -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>

View File

@@ -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
) {
}

View File

@@ -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.
*/

View File

@@ -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

View File

@@ -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)
}
}

View File

@@ -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
}
}

View File

@@ -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
)
}
}

View File

@@ -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
}

View File

@@ -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
)
}
}