You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Minecraft 1.18.2模组开发:如何获取LivingEntity实现效果叠加?

解决Minecraft模组中Meth食物效果放大器叠加问题

我正在制作名为meth的食物物品,希望玩家食用时每次都能叠加效果放大器(Amplifier)。最初写了isAlreadyHigh方法判断玩家是否已有该效果,存在就把放大器设为2而非默认0,但调用时不知道怎么传入LivingEntity参数,也不清楚如何获取玩家实例。之后尝试重写update方法实现叠加,但也没成功。


原始尝试代码

最初的MethFood类

package net.tyrique.banhammermod.item.custom;

import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.food.FoodProperties;
import net.tyrique.banhammermod.effect.ModEffects;

public class MethFood {

    public static final FoodProperties METH = (new FoodProperties.Builder()).alwaysEat().nutrition(0).saturationMod(0F).effect(
            () -> new MobEffectInstance(ModEffects.METH_EFFECT.get(), 1500, isAlreadyHigh(**WHAT DO I PUT HERE!?**)), 1.0F).fast().build();

    private static int isAlreadyHigh(LivingEntity player) {
        int lvl = 0;
        if (player.hasEffect(ModEffects.METH_EFFECT.get())) {
            lvl = 2;
        }
        return lvl;
    }
}

尝试重写update方法的片段

@Override
public boolean update(MobEffectInstance p_19559_) {
    int newamp = p_19559_.getAmplifier() + 1;
    p_19559_ = new MobEffectInstance(p_19559_.getEffect(), p_19559_.getDuration(), newamp);
    return super.update(p_19559_);
}

自定义ModMobEffectInstance类

public class ModMobEffectInstance extends MobEffectInstance {

    public ModMobEffectInstance(MobEffect effect, int duration, int amplifier) {
        super(effect, duration, amplifier);
    }

    @Override
    public boolean update(MobEffectInstance p_19559_) {
        int newamp = p_19559_.getAmplifier() + 1;
        p_19559_ = new ModMobEffectInstance(p_19559_.getEffect(), p_19559_.getDuration(), newamp);
        return super.update(p_19559_);
    }
}

修改后的MethFood类

public class MethFood {

    public static final FoodProperties METH = (new FoodProperties.Builder()).alwaysEat().nutrition(-1).saturationMod(0F).effect(
            () -> new ModMobEffectInstance(ModEffects.METH_EFFECT.get(), 1500, 0), 1.0F).fast().build();
}

正确解决方案

问题根源

  1. FoodProperties.Builder.effect()的Supplier是在食物属性初始化时执行,而非玩家食用阶段,此时没有玩家上下文,根本拿不到LivingEntity实例。
  2. 重写MobEffectInstance.update()的思路方向对,但实现错误——该方法不能直接替换传入的实例对象,修改引用不会影响原有的效果实例。

方案一:自定义食物类,在食用时处理叠加

直接创建自定义Item类,重写finishUsingItem方法,这里能直接拿到食用的玩家实例,灵活处理效果叠加:

package net.tyrique.banhammermod.item.custom;

import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.UseAnim;
import net.minecraft.world.level.Level;
import net.tyrique.banhammermod.effect.ModEffects;

public class MethItem extends Item {
    public MethItem(Properties properties) {
        // 仅设置基础食物属性,效果在食用时手动添加
        super(properties.alwaysEat().food(new FoodProperties.Builder().nutrition(0).saturationMod(0F).fast().build()));
    }

    @Override
    public ItemStack finishUsingItem(ItemStack stack, Level level, LivingEntity entity) {
        if (entity instanceof net.minecraft.world.entity.player.Player player) {
            int amplifier = 0;
            // 检查玩家已有效果,叠加放大器(这里改成+1实现递增,你之前写的设为2可以按需调整)
            if (player.hasEffect(ModEffects.METH_EFFECT.get())) {
                amplifier = player.getEffect(ModEffects.METH_EFFECT.get()).getAmplifier() + 1;
            }
            // 添加效果,时长可选择叠加或重置,这里保持1500 ticks
            player.addEffect(new MobEffectInstance(ModEffects.METH_EFFECT.get(), 1500, amplifier, false, true));
        }
        // 调用父类方法处理物品消耗逻辑
        return super.finishUsingItem(stack, level, entity);
    }

    @Override
    public UseAnim getUseAnimation(ItemStack stack) {
        return UseAnim.EAT;
    }
}

然后在模组注册类中注册这个自定义物品:

// 示例注册代码,替换成你的模组注册逻辑
public static final RegistryObject<Item> METH = ITEMS.register("meth", () -> new MethItem(new Item.Properties().tab(ModCreativeModeTabs.BANHAMMER_TAB)));

方案二:重写效果类实现自动叠加

如果希望所有该效果的应用场景都自动叠加放大器,可以重写MobEffect的updateEffectInstance方法,让效果本身支持合并叠加:

package net.tyrique.banhammermod.effect;

import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectCategory;
import net.minecraft.world.effect.MobEffectInstance;

public class MethEffect extends MobEffect {
    public MethEffect() {
        super(MobEffectCategory.BENEFICIAL, 0xFF00FF); // 自定义效果颜色
    }

    @Override
    public void applyEffectTick(LivingEntity entity, int amplifier) {
        // 这里写效果每tick的执行逻辑
        super.applyEffectTick(entity, amplifier);
    }

    @Override
    public boolean isDurationEffectTick(int duration, int amplifier) {
        return true; // 根据需求调整是否每tick生效
    }

    @Override
    public boolean updateEffectInstance(MobEffectInstance oldInstance, MobEffectInstance newInstance) {
        // 合并效果:保留最长时长,放大器叠加+1
        int newAmplifier = oldInstance.getAmplifier() + 1;
        int newDuration = Math.max(oldInstance.getDuration(), newInstance.getDuration());
        oldInstance.setDuration(newDuration);
        oldInstance.setAmplifier(newAmplifier);
        return true; // 返回true表示已合并,无需添加新实例
    }
}

这种方式下,食物只需要正常配置基础效果即可,不需要自定义Item类:

public static final FoodProperties METH_FOOD = new FoodProperties.Builder()
        .alwaysEat()
        .nutrition(0)
        .saturationMod(0F)
        .effect(() -> new MobEffectInstance(ModEffects.METH_EFFECT.get(), 1500, 0), 1.0F)
        .fast()
        .build();

内容的提问来源于stack exchange,提问作者TheRatKing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 15:12:03