diff --git a/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/cloth/MenuIntegration.java b/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/cloth/MenuIntegration.java index 85e800480..10bd71648 100644 --- a/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/cloth/MenuIntegration.java +++ b/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/cloth/MenuIntegration.java @@ -183,6 +183,21 @@ private static void maidConfig(ConfigBuilder root, ConfigEntryBuilder entryBuild } MaidConfig.MAID_EATEN_RETURN_CONTAINER_LIST.set(maidMealContainerList); }).build()); + + maid.addEntry(entryBuilder.startIntField(new TranslatableComponent("config.touhou_little_maid.maid.maid_gun_long_distance"), MaidConfig.MAID_GUN_LONG_DISTANCE.get()) + .setDefaultValue(64).setMin(0).setMax(512).requireRestart() + .setTooltip(new TranslatableComponent("config.touhou_little_maid.maid.maid_gun_long_distance.tooltip")) + .setSaveConsumer(i -> MaidConfig.MAID_GUN_LONG_DISTANCE.set(i)).build()); + + maid.addEntry(entryBuilder.startIntField(new TranslatableComponent("config.touhou_little_maid.maid.maid_gun_medium_distance"), MaidConfig.MAID_GUN_MEDIUM_DISTANCE.get()) + .setDefaultValue(48).setMin(0).setMax(512).requireRestart() + .setTooltip(new TranslatableComponent("config.touhou_little_maid.maid.maid_gun_medium_distance.tooltip")) + .setSaveConsumer(i -> MaidConfig.MAID_GUN_MEDIUM_DISTANCE.set(i)).build()); + + maid.addEntry(entryBuilder.startIntField(new TranslatableComponent("config.touhou_little_maid.maid.maid_gun_near_distance"), MaidConfig.MAID_GUN_NEAR_DISTANCE.get()) + .setDefaultValue(32).setMin(0).setMax(512).requireRestart() + .setTooltip(new TranslatableComponent("config.touhou_little_maid.maid.maid_gun_near_distance.tooltip")) + .setSaveConsumer(i -> MaidConfig.MAID_GUN_NEAR_DISTANCE.set(i)).build()); } private static void chairConfig(ConfigBuilder root, ConfigEntryBuilder entryBuilder) { diff --git a/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/TacCompat.java b/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/TacCompat.java index ce81a11a7..7cdc52b1f 100644 --- a/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/TacCompat.java +++ b/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/TacCompat.java @@ -8,6 +8,8 @@ import com.github.tartaricacid.touhoulittlemaid.compat.tacz.client.GunMaidRender; import com.github.tartaricacid.touhoulittlemaid.compat.tacz.event.GunHurtMaidEvent; import com.github.tartaricacid.touhoulittlemaid.compat.tacz.task.TaskGunAttack; +import com.github.tartaricacid.touhoulittlemaid.compat.tacz.utils.GunNearestLivingEntitySensor; +import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid; import com.github.tartaricacid.touhoulittlemaid.entity.task.TaskManager; import com.github.tartaricacid.touhoulittlemaid.geckolib3.core.PlayState; import com.github.tartaricacid.touhoulittlemaid.geckolib3.core.builder.ILoopType; @@ -16,6 +18,7 @@ import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.item.ItemStack; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -48,6 +51,19 @@ public static boolean isGrenade(ItemStack itemStack) { return false; } + public static boolean isGunTask(EntityMaid maid) { + if (INSTALLED) { + return GunNearestLivingEntitySensor.isGunTask(maid); + } + return false; + } + + public static void doGunTick(ServerLevel world, EntityMaid maid) { + if (INSTALLED) { + GunNearestLivingEntitySensor.doGunTick(world, maid); + } + } + @Nullable public static ResourceLocation getGunId(ItemStack stack) { if (INSTALLED) { diff --git a/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/ai/GunAttackStrafingTask.java b/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/ai/GunAttackStrafingTask.java index 427edb2fa..af3fd1276 100644 --- a/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/ai/GunAttackStrafingTask.java +++ b/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/ai/GunAttackStrafingTask.java @@ -1,5 +1,6 @@ package com.github.tartaricacid.touhoulittlemaid.compat.tacz.ai; +import com.github.tartaricacid.touhoulittlemaid.config.subconfig.MaidConfig; import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid; import com.google.common.collect.ImmutableMap; import com.tacz.guns.api.item.IGun; @@ -30,7 +31,6 @@ protected boolean checkExtraStartConditions(ServerLevel worldIn, EntityMaid owne return IGun.mainhandHoldGun(owner) && owner.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET) .filter(Entity::isAlive) - .filter(e -> owner.isWithinRestriction(e.blockPosition())) .isPresent(); } @@ -45,8 +45,8 @@ protected void tick(ServerLevel worldIn, EntityMaid owner, long gameTime) { double distance = owner.distanceTo(target); float maxAttackDistance = owner.getRestrictRadius(); - // 如果在最大攻击距离之内,而且看见的时长足够长 - if (distance < maxAttackDistance) { + // 如果在最大攻击距离(128)之内,而且看见的时长足够长 + if (distance < MaidConfig.MAID_GUN_LONG_DISTANCE.get()) { ++this.strafingTime; } else { this.strafingTime = -1; diff --git a/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/ai/GunShootTargetTask.java b/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/ai/GunShootTargetTask.java index 2250529f4..da484da76 100644 --- a/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/ai/GunShootTargetTask.java +++ b/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/ai/GunShootTargetTask.java @@ -1,5 +1,6 @@ package com.github.tartaricacid.touhoulittlemaid.compat.tacz.ai; +import com.github.tartaricacid.touhoulittlemaid.compat.tacz.utils.GunBehaviorUtils; import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid; import com.google.common.collect.ImmutableMap; import com.tacz.guns.api.TimelessAPI; @@ -14,7 +15,6 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.ai.behavior.Behavior; -import net.minecraft.world.entity.ai.behavior.BehaviorUtils; import net.minecraft.world.entity.ai.memory.MemoryModuleType; import net.minecraft.world.entity.ai.memory.MemoryStatus; import net.minecraft.world.item.ItemStack; @@ -35,7 +35,7 @@ protected boolean checkExtraStartConditions(ServerLevel worldIn, EntityMaid owne Optional memory = owner.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET); if (memory.isPresent()) { LivingEntity target = memory.get(); - return IGun.mainhandHoldGun(owner) && BehaviorUtils.canSee(owner, target); + return IGun.mainhandHoldGun(owner) && GunBehaviorUtils.canSee(owner, target); } return false; } @@ -53,9 +53,9 @@ protected void start(ServerLevel worldIn, EntityMaid entityIn, long gameTimeIn) @Override protected void tick(ServerLevel worldIn, EntityMaid owner, long gameTime) { owner.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).ifPresent((target) -> { - BehaviorUtils.lookAtEntity(owner, target); - - boolean canSee = BehaviorUtils.canSee(owner, target); + //实际上按照原版mc判定是看不见的,强行看见并朝向(没关就是开了?) + owner.getLookControl().setLookAt(target.getX(), target.getY(), target.getZ()); + boolean canSee = GunBehaviorUtils.canSee(owner, target); boolean seeTimeMoreThanZero = this.seeTime > 0; // 如果两者不一致,重置看见时间 @@ -93,6 +93,8 @@ public void performGunAttack(EntityMaid shooter, LivingEntity target, ItemStack float yaw = (float) -Math.toDegrees(Math.atan2(x, z)); float pitch = (float) -Math.toDegrees(Math.atan2(y, Math.sqrt(x * x + z * z))); + float radius = shooter.getRestrictRadius(); + IGunOperator gunOperator = IGunOperator.fromLivingEntity(shooter); ShootResult result = gunOperator.shoot(() -> pitch, () -> yaw); @@ -110,12 +112,21 @@ public void performGunAttack(EntityMaid shooter, LivingEntity target, ItemStack return; } - // 如果是非狙击枪,就不要瞄准了,不然太超模了 - if (!gunIndex.getType().equals(sniper) && gunOperator.getSynIsAiming()) { - gunOperator.aim(false); - // 多加 2 tick,用来平衡延迟 - this.attackCooldown = Math.round(gunData.getAimTime() * 20) + 2; - return; + // 如果是非狙击枪,超出 radius 范围,那么也瞄准 + if (!gunIndex.getType().equals(sniper)) { + float distance = shooter.distanceTo(target); + if (distance <= radius && gunOperator.getSynIsAiming()) { + gunOperator.aim(false); + // 多加 2 tick,用来平衡延迟 + this.attackCooldown = Math.round(gunData.getAimTime() * 20) + 2; + return; + } + if (distance > radius && !gunOperator.getSynIsAiming()) { + gunOperator.aim(true); + // 多加 2 tick,用来平衡延迟 + this.attackCooldown = Math.round(gunData.getAimTime() * 20) + 2; + return; + } } if (result == ShootResult.NOT_DRAW) { diff --git a/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/ai/GunWalkToTarget.java b/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/ai/GunWalkToTarget.java index e4308e340..a8fafaf40 100644 --- a/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/ai/GunWalkToTarget.java +++ b/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/ai/GunWalkToTarget.java @@ -1,5 +1,7 @@ package com.github.tartaricacid.touhoulittlemaid.compat.tacz.ai; +import com.github.tartaricacid.touhoulittlemaid.compat.tacz.utils.GunBehaviorUtils; +import com.github.tartaricacid.touhoulittlemaid.compat.tacz.utils.GunNearestLivingEntitySensor; import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid; import com.google.common.collect.ImmutableMap; import net.minecraft.server.level.ServerLevel; @@ -29,7 +31,7 @@ public GunWalkToTarget(Function speedModifier) { @Override protected void start(ServerLevel level, EntityMaid maid, long pGameTime) { LivingEntity livingentity = maid.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET).get(); - if (BehaviorUtils.canSee(maid, livingentity) && isWithinRestriction(maid, livingentity)) { + if (GunBehaviorUtils.canSee(maid, livingentity) && isWithinRestriction(maid, livingentity)) { this.clearWalkTarget(maid); } else { this.setWalkAndLookTarget(maid, livingentity); diff --git a/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/task/TaskGunAttack.java b/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/task/TaskGunAttack.java index 92b679013..8c9902399 100644 --- a/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/task/TaskGunAttack.java +++ b/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/task/TaskGunAttack.java @@ -5,6 +5,8 @@ import com.github.tartaricacid.touhoulittlemaid.compat.tacz.ai.GunAttackStrafingTask; import com.github.tartaricacid.touhoulittlemaid.compat.tacz.ai.GunShootTargetTask; import com.github.tartaricacid.touhoulittlemaid.compat.tacz.ai.GunWalkToTarget; +import com.github.tartaricacid.touhoulittlemaid.compat.tacz.utils.GunBehaviorUtils; +import com.github.tartaricacid.touhoulittlemaid.config.subconfig.MaidConfig; import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid; import com.github.tartaricacid.touhoulittlemaid.init.InitSounds; import com.github.tartaricacid.touhoulittlemaid.util.SoundUtil; @@ -54,7 +56,7 @@ public boolean enableLookAndRandomWalk(EntityMaid maid) { @Override public List>> createBrainTasks(EntityMaid maid) { RunIf supplementedTask = new RunIf<>(this::mainhandHoldGun, - new StartAttacking<>(IAttackTask::findFirstValidAttackTarget)); + new StartAttacking<>(GunBehaviorUtils::findFirstValidAttackTarget)); StopAttackingIfTargetInvalid findTargetTask = new StopAttackingIfTargetInvalid<>( (target) -> !mainhandHoldGun(maid) || farAway(target, maid)); Behavior gunWalkTargetTask = new GunWalkToTarget(0.6f); @@ -80,6 +82,6 @@ private boolean mainhandHoldGun(EntityMaid maid) { } private boolean farAway(LivingEntity target, EntityMaid maid) { - return maid.distanceTo(target) > maid.getRestrictRadius(); + return maid.distanceTo(target) > MaidConfig.MAID_GUN_LONG_DISTANCE.get(); } } diff --git a/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/utils/GunBehaviorUtils.java b/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/utils/GunBehaviorUtils.java new file mode 100644 index 000000000..de84c5a76 --- /dev/null +++ b/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/utils/GunBehaviorUtils.java @@ -0,0 +1,60 @@ +package com.github.tartaricacid.touhoulittlemaid.compat.tacz.utils; + +import com.github.tartaricacid.touhoulittlemaid.config.subconfig.MaidConfig; +import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid; +import com.tacz.guns.api.TimelessAPI; +import com.tacz.guns.api.item.GunTabType; +import com.tacz.guns.api.item.IGun; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.behavior.BehaviorUtils; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.targeting.TargetingConditions; +import net.minecraft.world.item.ItemStack; + +import java.util.List; +import java.util.Locale; +import java.util.Optional; + +public class GunBehaviorUtils { + // 可见性校验工具,来自于 Sensor + // 依据枪械种类,可以区分为远、中、近三类 + private static final TargetingConditions LONG_DISTANCE_TARGET_CONDITIONS = TargetingConditions.forNonCombat().range(MaidConfig.MAID_GUN_LONG_DISTANCE.get()); + private static final TargetingConditions MEDIUM_DISTANCE_TARGET_CONDITIONS = TargetingConditions.forNonCombat().range(MaidConfig.MAID_GUN_MEDIUM_DISTANCE.get()); + private static final TargetingConditions NEAR_DISTANCE_TARGET_CONDITIONS = TargetingConditions.forNonCombat().range(MaidConfig.MAID_GUN_NEAR_DISTANCE.get()); + + //可见性方法,来自于Sensor类 + public static boolean canSee(EntityMaid maid, LivingEntity target) { + ItemStack handItem = maid.getMainHandItem(); + IGun iGun = IGun.getIGunOrNull(handItem); + if (iGun != null) { + ResourceLocation gunId = iGun.getGunId(handItem); + return TimelessAPI.getCommonGunIndex(gunId).map(index -> { + String type = index.getType(); + // 狙击枪?用远距离模式 + String sniper = GunTabType.SNIPER.name().toLowerCase(Locale.ENGLISH); + if (sniper.equals(type)) { + return LONG_DISTANCE_TARGET_CONDITIONS.test(maid, target); + } + // 霰弹枪?手枪?近距离模式 + String shotgun = GunTabType.SHOTGUN.name().toLowerCase(Locale.ENGLISH); + String pistol = GunTabType.PISTOL.name().toLowerCase(Locale.ENGLISH); + if (shotgun.equals(type) || pistol.equals(type)) { + return NEAR_DISTANCE_TARGET_CONDITIONS.test(maid, target); + } + // 其他情况,中等距离 + return MEDIUM_DISTANCE_TARGET_CONDITIONS.test(maid, target); + }).orElse(BehaviorUtils.canSee(maid, target)); + } + return BehaviorUtils.canSee(maid, target); + } + + // 寻找第一个可见目标,使用独立的方法,区别于 IAttackTask + public static Optional findFirstValidAttackTarget(EntityMaid maid) { + if (maid.getBrain().getMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES).isPresent()) { + List list = maid.getBrain().getMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES).get(); + return list.stream().filter(e -> maid.canAttack(e) && GunBehaviorUtils.canSee(maid, e)).findAny(); + } + return Optional.empty(); + } +} diff --git a/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/utils/GunNearestLivingEntitySensor.java b/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/utils/GunNearestLivingEntitySensor.java new file mode 100644 index 000000000..a2051f3bd --- /dev/null +++ b/src/main/java/com/github/tartaricacid/touhoulittlemaid/compat/tacz/utils/GunNearestLivingEntitySensor.java @@ -0,0 +1,37 @@ +package com.github.tartaricacid.touhoulittlemaid.compat.tacz.utils; + +import com.github.tartaricacid.touhoulittlemaid.compat.tacz.task.TaskGunAttack; +import com.github.tartaricacid.touhoulittlemaid.config.subconfig.MaidConfig; +import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid; +import com.tacz.guns.api.item.IGun; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.Brain; +import net.minecraft.world.entity.ai.memory.MemoryModuleType; +import net.minecraft.world.entity.ai.memory.NearestVisibleLivingEntities; +import net.minecraft.world.entity.schedule.Activity; +import net.minecraft.world.phys.AABB; + +import java.util.Comparator; +import java.util.List; + +public class GunNearestLivingEntitySensor { + public static boolean isGunTask(EntityMaid maid) { + return maid.getTask().getUid().equals(TaskGunAttack.UID) && maid.getScheduleDetail() == Activity.WORK && IGun.mainhandHoldGun(maid); + } + + public static void doGunTick(ServerLevel world, EntityMaid maid) { + AABB aabb; + int searchRange = MaidConfig.MAID_GUN_LONG_DISTANCE.get(); + if (maid.hasRestriction()) { + aabb = new AABB(maid.getRestrictCenter()).inflate(searchRange); + } else { + aabb = maid.getBoundingBox().inflate(searchRange); + } + List list = world.getEntitiesOfClass(LivingEntity.class, aabb, (entity) -> entity != maid && entity.isAlive()); + list.sort(Comparator.comparingDouble(maid::distanceToSqr)); + Brain brain = maid.getBrain(); + brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, list); + brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(maid, list)); + } +} diff --git a/src/main/java/com/github/tartaricacid/touhoulittlemaid/config/subconfig/MaidConfig.java b/src/main/java/com/github/tartaricacid/touhoulittlemaid/config/subconfig/MaidConfig.java index 539eb8cb1..ba33c5662 100644 --- a/src/main/java/com/github/tartaricacid/touhoulittlemaid/config/subconfig/MaidConfig.java +++ b/src/main/java/com/github/tartaricacid/touhoulittlemaid/config/subconfig/MaidConfig.java @@ -36,6 +36,10 @@ public final class MaidConfig { public static ForgeConfigSpec.ConfigValue> MAID_HEAL_MEALS_BLOCK_LIST_REGEX; public static ForgeConfigSpec.ConfigValue>> MAID_EATEN_RETURN_CONTAINER_LIST; + public static ForgeConfigSpec.IntValue MAID_GUN_LONG_DISTANCE; + public static ForgeConfigSpec.IntValue MAID_GUN_MEDIUM_DISTANCE; + public static ForgeConfigSpec.IntValue MAID_GUN_NEAR_DISTANCE; + public static void init(ForgeConfigSpec.Builder builder) { builder.push("maid"); @@ -125,6 +129,15 @@ public static void init(ForgeConfigSpec.Builder builder) { builder.comment("These entries configure the container returned after a maid has eaten", "Eg: [\"minecraft:beetroot_soup\", \"minecraft:bowl\"]"); MAID_EATEN_RETURN_CONTAINER_LIST = builder.define("MaidEatenReturnContainerList", Lists.newArrayList()); + builder.comment("Recognition distance of a maid under the gun task, Suitable for sniper rifles"); + MAID_GUN_LONG_DISTANCE = builder.defineInRange("MaidGunLongDistance", 64, 0, 512); + + builder.comment("Recognition distance of a maid under the gun task, Suitable for most types"); + MAID_GUN_MEDIUM_DISTANCE = builder.defineInRange("MaidGunMediumDistance", 48, 0, 512); + + builder.comment("Recognition distance of a maid under the gun task, Suitable for pistols and shotguns"); + MAID_GUN_NEAR_DISTANCE = builder.defineInRange("MaidGunNearDistance", 32, 0, 512); + builder.pop(); } } diff --git a/src/main/java/com/github/tartaricacid/touhoulittlemaid/entity/ai/brain/sensor/MaidNearestLivingEntitySensor.java b/src/main/java/com/github/tartaricacid/touhoulittlemaid/entity/ai/brain/sensor/MaidNearestLivingEntitySensor.java index 3ebbf0375..e23e58f32 100644 --- a/src/main/java/com/github/tartaricacid/touhoulittlemaid/entity/ai/brain/sensor/MaidNearestLivingEntitySensor.java +++ b/src/main/java/com/github/tartaricacid/touhoulittlemaid/entity/ai/brain/sensor/MaidNearestLivingEntitySensor.java @@ -1,5 +1,6 @@ package com.github.tartaricacid.touhoulittlemaid.entity.ai.brain.sensor; +import com.github.tartaricacid.touhoulittlemaid.compat.tacz.TacCompat; import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid; import com.google.common.collect.ImmutableSet; import net.minecraft.server.level.ServerLevel; @@ -17,7 +18,15 @@ public class MaidNearestLivingEntitySensor extends Sensor { private static final int VERTICAL_SEARCH_RANGE = 4; + @Override protected void doTick(ServerLevel world, EntityMaid maid) { + // 兼容 tac + if (TacCompat.isGunTask(maid)) { + TacCompat.doGunTick(world, maid); + return; + } + + // 正常搜索 float radius = maid.getRestrictRadius(); AABB aabb; if (maid.hasRestriction()) { diff --git a/src/main/java/com/github/tartaricacid/touhoulittlemaid/entity/monster/EntityFairy.java b/src/main/java/com/github/tartaricacid/touhoulittlemaid/entity/monster/EntityFairy.java index e49b56162..ff15ce5bf 100644 --- a/src/main/java/com/github/tartaricacid/touhoulittlemaid/entity/monster/EntityFairy.java +++ b/src/main/java/com/github/tartaricacid/touhoulittlemaid/entity/monster/EntityFairy.java @@ -4,12 +4,15 @@ import com.github.tartaricacid.touhoulittlemaid.entity.ai.goal.FairyAttackGoal; import com.github.tartaricacid.touhoulittlemaid.entity.passive.EntityMaid; import com.github.tartaricacid.touhoulittlemaid.entity.projectile.DanmakuShoot; +import com.github.tartaricacid.touhoulittlemaid.init.InitPoi; import com.github.tartaricacid.touhoulittlemaid.init.InitSounds; +import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvent; import net.minecraft.world.Difficulty; import net.minecraft.world.DifficultyInstance; @@ -22,6 +25,7 @@ import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal; import net.minecraft.world.entity.ai.navigation.FlyingPathNavigation; import net.minecraft.world.entity.ai.navigation.PathNavigation; +import net.minecraft.world.entity.ai.village.poi.PoiManager; import net.minecraft.world.entity.animal.FlyingAnimal; import net.minecraft.world.entity.animal.IronGolem; import net.minecraft.world.entity.monster.Monster; @@ -31,6 +35,7 @@ import net.minecraft.world.level.ServerLevelAccessor; import javax.annotation.Nullable; +import java.util.Random; public class EntityFairy extends Monster implements RangedAttackMob, FlyingAnimal, IHasPowerPoint { public static final EntityType TYPE = EntityType.Builder.of(EntityFairy::new, MobCategory.MONSTER) @@ -58,6 +63,15 @@ public static AttributeSupplier.Builder createFairyAttributes() { .add(Attributes.FLYING_SPEED, 0.4); } + public static boolean checkFairySpawnRules(EntityType entityType, ServerLevelAccessor levelAccessor, MobSpawnType spawnType, BlockPos pos, Random randomSource) { + if (Monster.checkMonsterSpawnRules(entityType, levelAccessor, spawnType, pos, randomSource) && levelAccessor instanceof ServerLevel level) { + int scarecrowRange = MiscConfig.SCARECROW_RANGE.get(); + long findCount = level.getPoiManager().getInSquare(type -> type.equals(InitPoi.SCARECROW.get()), pos, scarecrowRange, PoiManager.Occupancy.ANY).count(); + return findCount <= 0; + } + return false; + } + @Override protected void registerGoals() { goalSelector.addGoal(0, new FloatGoal(this)); diff --git a/src/main/java/com/github/tartaricacid/touhoulittlemaid/init/InitEntities.java b/src/main/java/com/github/tartaricacid/touhoulittlemaid/init/InitEntities.java index dc293b133..52e6b2b56 100644 --- a/src/main/java/com/github/tartaricacid/touhoulittlemaid/init/InitEntities.java +++ b/src/main/java/com/github/tartaricacid/touhoulittlemaid/init/InitEntities.java @@ -99,6 +99,6 @@ public static void addEntityAttributeEvent(EntityAttributeCreationEvent event) { @SubscribeEvent public static void addEntitySpawnPlacement(FMLCommonSetupEvent event) { - SpawnPlacements.register(InitEntities.FAIRY.get(), SpawnPlacements.Type.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, Monster::checkMonsterSpawnRules); + SpawnPlacements.register(InitEntities.FAIRY.get(), SpawnPlacements.Type.ON_GROUND, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EntityFairy::checkFairySpawnRules); } } diff --git a/src/main/java/com/github/tartaricacid/touhoulittlemaid/init/registry/MobSpawnInfoRegistry.java b/src/main/java/com/github/tartaricacid/touhoulittlemaid/init/registry/MobSpawnInfoRegistry.java index 1f2d2579c..6c4a0b7f0 100644 --- a/src/main/java/com/github/tartaricacid/touhoulittlemaid/init/registry/MobSpawnInfoRegistry.java +++ b/src/main/java/com/github/tartaricacid/touhoulittlemaid/init/registry/MobSpawnInfoRegistry.java @@ -2,12 +2,10 @@ import com.github.tartaricacid.touhoulittlemaid.config.subconfig.MiscConfig; import com.github.tartaricacid.touhoulittlemaid.init.InitEntities; -import com.github.tartaricacid.touhoulittlemaid.init.InitPoi; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MobCategory; -import net.minecraft.world.entity.ai.village.poi.PoiManager; import net.minecraft.world.level.biome.MobSpawnSettings; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; @@ -33,21 +31,10 @@ public static void addMobSpawnInfo(WorldEvent.PotentialSpawns event) { if (event.getMobCategory() == MobCategory.MONSTER && dimensionIsOkay(dimension)) { List spawnerData = event.getSpawnerDataList(); boolean canZombieSpawn = spawnerData.stream().anyMatch(data -> data.type.equals(EntityType.ZOMBIE)); - if (SPAWNER_DATA == null) { + if (SPAWNER_DATA == null || SPAWNER_DATA.getWeight().asInt() != spawnProbability) { SPAWNER_DATA = new MobSpawnSettings.SpawnerData(InitEntities.FAIRY.get(), spawnProbability, 2, 4); } - if (!canZombieSpawn) { - return; - } - // 检查稻草人 - int scarecrowRange = MiscConfig.SCARECROW_RANGE.get(); - // 优先判断等于 0 的情况,减少性能消耗 - if (scarecrowRange <= 0) { - event.addSpawnerData(SPAWNER_DATA); - return; - } - long findCount = level.getPoiManager().getInSquare(type -> type.equals(InitPoi.SCARECROW.get()), event.getPos(), scarecrowRange, PoiManager.Occupancy.ANY).count(); - if (findCount <= 0) { + if (canZombieSpawn) { event.addSpawnerData(SPAWNER_DATA); } } diff --git a/src/main/resources/assets/touhou_little_maid/lang/en_us.json b/src/main/resources/assets/touhou_little_maid/lang/en_us.json index a1df0bf39..aaa689342 100644 --- a/src/main/resources/assets/touhou_little_maid/lang/en_us.json +++ b/src/main/resources/assets/touhou_little_maid/lang/en_us.json @@ -371,6 +371,12 @@ "config.touhou_little_maid.maid.maid_heal_meals_block_list_regex.tooltip": "These items cannot be used as a maid's heal meals which match the regex, all words have to match", "config.touhou_little_maid.maid.maid_eaten_return_container_list": "Maid Eaten Return Container List", "config.touhou_little_maid.maid.maid_eaten_return_container_list.tooltip": "These entries configure the container returned after a maid has eaten \nEg: §eminecraft:beetroot_soup§c,§eminecraft:bowl", + "config.touhou_little_maid.maid.maid_gun_long_distance": "Maid Gun Long Distance", + "config.touhou_little_maid.maid.maid_gun_long_distance.tooltip": "Recognition distance of a maid under the gun task, Suitable for sniper rifles", + "config.touhou_little_maid.maid.maid_gun_medium_distance": "Maid Gun Medium Distance", + "config.touhou_little_maid.maid.maid_gun_medium_distance.tooltip": "Recognition distance of a maid under the gun task, Suitable for most types", + "config.touhou_little_maid.maid.maid_gun_near_distance": "Maid Gun Near Distance", + "config.touhou_little_maid.maid.maid_gun_near_distance.tooltip": "Recognition distance of a maid under the gun task, Suitable for pistols and shotguns", "config.touhou_little_maid.chair": "Chair", "config.touhou_little_maid.chair.chair_change_model": "Chair Change Model", "config.touhou_little_maid.chair.chair_change_model.tooltip": "Chair can switch models freely", diff --git a/src/main/resources/assets/touhou_little_maid/lang/zh_cn.json b/src/main/resources/assets/touhou_little_maid/lang/zh_cn.json index a46a6441a..c33b16f49 100644 --- a/src/main/resources/assets/touhou_little_maid/lang/zh_cn.json +++ b/src/main/resources/assets/touhou_little_maid/lang/zh_cn.json @@ -371,6 +371,12 @@ "config.touhou_little_maid.maid.maid_heal_meals_block_list_regex.tooltip": "匹配的物品不能用于女仆的回血餐,请使用正则全词匹配", "config.touhou_little_maid.maid.maid_eaten_return_container_list": "女仆用餐后返回容器的列表", "config.touhou_little_maid.maid.maid_eaten_return_container_list.tooltip": "这些条目配置了女仆用餐后要返回的容器\n例如: §eminecraft:beetroot_soup§c,§eminecraft:bowl", + "config.touhou_little_maid.maid.maid_gun_long_distance": "远距枪械距离", + "config.touhou_little_maid.maid.maid_gun_long_distance.tooltip": "枪械模式下女仆的识别距离,适用于狙击枪", + "config.touhou_little_maid.maid.maid_gun_medium_distance": "中等枪械距离", + "config.touhou_little_maid.maid.maid_gun_medium_distance.tooltip": "枪械模式下女仆的识别距离,适用于大多数枪械", + "config.touhou_little_maid.maid.maid_gun_near_distance": "近枪械距离", + "config.touhou_little_maid.maid.maid_gun_near_distance.tooltip": "枪械模式下女仆的识别距离,适用于手枪和霰弹枪", "config.touhou_little_maid.chair": "坐垫", "config.touhou_little_maid.chair.chair_change_model": "坐垫能否切换模型", "config.touhou_little_maid.chair.chair_change_model.tooltip": "坐垫能否自由切换模型", diff --git a/src/main/resources/assets/touhou_little_maid/tlm_custom_pack/touhou_little_maid-1.0.0.zip b/src/main/resources/assets/touhou_little_maid/tlm_custom_pack/touhou_little_maid-1.0.0.zip index 3ecb5d660..de0ee6ffe 100644 Binary files a/src/main/resources/assets/touhou_little_maid/tlm_custom_pack/touhou_little_maid-1.0.0.zip and b/src/main/resources/assets/touhou_little_maid/tlm_custom_pack/touhou_little_maid-1.0.0.zip differ