Skip to content

Commit

Permalink
完成 1.20 的同步
Browse files Browse the repository at this point in the history
  • Loading branch information
TartaricAcid committed Sep 20, 2024
1 parent cbd6bcb commit a4a07b0
Show file tree
Hide file tree
Showing 16 changed files with 211 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,21 @@ private static void maidConfig(ConfigBuilder root, ConfigEntryBuilder entryBuild
}
MaidConfig.MAID_EATEN_RETURN_CONTAINER_LIST.set(maidMealContainerList);
}).build());

maid.addEntry(entryBuilder.startIntField(Component.translatable("config.touhou_little_maid.maid.maid_gun_long_distance"), MaidConfig.MAID_GUN_LONG_DISTANCE.get())
.setDefaultValue(64).setMin(0).setMax(512).requireRestart()
.setTooltip(Component.translatable("config.touhou_little_maid.maid.maid_gun_long_distance.tooltip"))
.setSaveConsumer(i -> MaidConfig.MAID_GUN_LONG_DISTANCE.set(i)).build());

maid.addEntry(entryBuilder.startIntField(Component.translatable("config.touhou_little_maid.maid.maid_gun_medium_distance"), MaidConfig.MAID_GUN_MEDIUM_DISTANCE.get())
.setDefaultValue(48).setMin(0).setMax(512).requireRestart()
.setTooltip(Component.translatable("config.touhou_little_maid.maid.maid_gun_medium_distance.tooltip"))
.setSaveConsumer(i -> MaidConfig.MAID_GUN_MEDIUM_DISTANCE.set(i)).build());

maid.addEntry(entryBuilder.startIntField(Component.translatable("config.touhou_little_maid.maid.maid_gun_near_distance"), MaidConfig.MAID_GUN_NEAR_DISTANCE.get())
.setDefaultValue(32).setMin(0).setMax(512).requireRestart()
.setTooltip(Component.translatable("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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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();
}

Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand All @@ -35,7 +35,7 @@ protected boolean checkExtraStartConditions(ServerLevel worldIn, EntityMaid owne
Optional<LivingEntity> 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;
}
Expand All @@ -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;

// 如果两者不一致,重置看见时间
Expand Down Expand Up @@ -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);

Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -29,7 +31,7 @@ public GunWalkToTarget(Function<LivingEntity, Float> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -54,7 +56,7 @@ public boolean enableLookAndRandomWalk(EntityMaid maid) {
@Override
public List<Pair<Integer, Behavior<? super EntityMaid>>> createBrainTasks(EntityMaid maid) {
RunIf<EntityMaid> supplementedTask = new RunIf<>(this::mainhandHoldGun,
new StartAttacking<>(IAttackTask::findFirstValidAttackTarget));
new StartAttacking<>(GunBehaviorUtils::findFirstValidAttackTarget));
StopAttackingIfTargetInvalid<EntityMaid> findTargetTask = new StopAttackingIfTargetInvalid<>(
(target) -> !mainhandHoldGun(maid) || farAway(target, maid));
Behavior<EntityMaid> gunWalkTargetTask = new GunWalkToTarget(0.6f);
Expand All @@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -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<? extends LivingEntity> findFirstValidAttackTarget(EntityMaid maid) {
if (maid.getBrain().getMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES).isPresent()) {
List<LivingEntity> 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();
}
}
Original file line number Diff line number Diff line change
@@ -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<LivingEntity> list = world.getEntitiesOfClass(LivingEntity.class, aabb, (entity) -> entity != maid && entity.isAlive());
list.sort(Comparator.comparingDouble(maid::distanceToSqr));
Brain<EntityMaid> brain = maid.getBrain();
brain.setMemory(MemoryModuleType.NEAREST_LIVING_ENTITIES, list);
brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, new NearestVisibleLivingEntities(maid, list));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ public final class MaidConfig {
public static ForgeConfigSpec.ConfigValue<List<String>> MAID_HEAL_MEALS_BLOCK_LIST_REGEX;
public static ForgeConfigSpec.ConfigValue<List<List<String>>> 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");

Expand Down Expand Up @@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -17,7 +18,15 @@
public class MaidNearestLivingEntitySensor extends Sensor<EntityMaid> {
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()) {
Expand Down
Loading

0 comments on commit a4a07b0

Please sign in to comment.