Flandre923
614 words
3 minutes
32 AI

32 AI#

实体AI,对于生物有自己的AI逻辑,表示了该实体有哪些动作和逻辑,例如羊和繁殖,可以吃草,会追随玩家的小麦。僵尸会攻击玩家,攻击村民等等。

通过mixin进入到羊驼的AI(goal)中,然后实现羊驼可以一直吐口水

// 定义了包的名称,表示代码属于哪个模块。
package com.mafuyu33.neomafishmod.mixin.mobmixin.llamaspitforever;

// 导入了相关的类和接口,用于支持Mixin和Minecraft的实体行为。
// ...

// 使用@Mixin注解标记这个类,表示它将混入(Mixin)到Llama.LlamaHurtByTargetGoal类中。
@Mixin(Llama.LlamaHurtByTargetGoal.class)
public abstract class LlamaEntity_SpitRevengeGoalMixin extends HurtByTargetGoal {

    // 构造函数,传入一个PathfinderMob类型的实体和一个要忽略伤害的类数组。
    public LlamaEntity_SpitRevengeGoalMixin(PathfinderMob mob, Class<?>... toIgnoreDamage) {
        super(mob, toIgnoreDamage);
    }

    // 使用@Inject注解标记这个方法,表示它将在HurtByTargetGoal类的canContinueToUse方法执行时被调用。
    // at = "INVOKE" 表示在调用指定方法时注入代码。
    // cancellable = true 表示可以取消原方法的返回值。
    @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/animal/horse/Llama;setDidSpit(Z)V"), method = "canContinueToUse", cancellable = true)
    private void init(CallbackInfoReturnable<Boolean> cir) {
        // 从配置文件中获取是否启用"永远吐口水"的选项。
        boolean isLlamaSpitForever = Config.isLlamaSpitForever();
        if(isLlamaSpitForever) {
            // 如果启用了"永远吐口水",并且目标实体不为空且存活,则允许继续使用这个目标。
            if(targetMob!=null && targetMob.isAlive()) {
                cir.setReturnValue(true);
            }
        }
    }
}
// 定义了包的名称,表示代码属于哪个模块。
package com.mafuyu33.neomafishmod.mixin.mobmixin.llamaspitforever;

// 导入了相关的类和接口,用于支持Mixin和Minecraft的实体行为。
// ...

// 使用@Mixin注解标记这个类,表示它将混入(Mixin)到Llama类中。
@Mixin(Llama.class)
public abstract class LlamaEntityMixin {
    // 使用@Inject注解标记这个方法,表示它将在Llama类的registerGoals方法执行时被调用。
    // at = "HEAD" 表示在方法开始时注入代码。
    @Inject(at = @At(value = "HEAD"), method = "registerGoals")
    private void init(CallbackInfo ci) {
        // 从配置文件中获取是否启用"永远吐口水"的选项。
        boolean isLlamaSpitForever = Config.isLlamaSpitForever();
        Llama self = (Llama) (Object) this;
        if(isLlamaSpitForever) {
            // 如果启用了"永远吐口水",移除所有远程攻击目标,并添加一个新的远程攻击目标。
            self.goalSelector.getAvailableGoals().removeIf(goal -> goal.getGoal() instanceof RangedAttackGoal);
            self.goalSelector.addGoal(3, new RangedAttackGoal(self, 1.25, 1, 20.0F));
        } else {
            // 如果没有启用"永远吐口水",也移除所有远程攻击目标,并添加一个新的远程攻击目标,但参数不同。
            self.goalSelector.getAvailableGoals().removeIf(goal -> goal.getGoal() instanceof RangedAttackGoal);
            self.goalSelector.addGoal(3, new RangedAttackGoal(self, 1.25, 40, 20.0F)); // 主要是修改了间隔时间
        }
    }
}

32 AI
https://fuwari.vercel.app/posts/minecraft1_21_0/32_ai/
Author
Flandre923
Published at
2024-08-24