javaminecraftminecraft-forge

How do I get the Living Entity in this class? (Minecraft Modding 1.18.2)


I'm trying to make a food item (meth) that when you eat it it will stack the effect Amplifier each time. So I made this method to try and figure out if the player already has the effect and if so to make the effect amplifier 2 instead of the default 0. My big problem is when I try to use the method it of course requires a LivingEntity(the player) to use the method, what should I put in the methods parameters and how can I get the LivingEntity.

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


}

I've already tried using some other techniques or possible methods to get the player but I don't know what else I can do. I'm sure the solution is simple.

update(MobEffectInstance) Method Isolated:

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

ModMobEffectInstanceClass:


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_);
    }




}

MethItemClass:

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();



}

Solution

  • You can't get a LivingEntity in that declaration because it is independent of any entities. It is declared before any entity even exists. You need to find your entity when the effect is applied.

    One way to do so is by subscribing to the PotionAddedEvent and putting your logic in the event handler.

    First, you need to check if the same kind of effect is already on the LivingEntity. You can get the old effect from the PotionEvent.PotionAddedEvent.getOldPotionEffect() method. The method will return null if and only if the entity does not have the same type of effect yet.

    Secondly, you need to check if the added effect is your effect in order to not interfere with other effects. You can get the added effect from the PotionEvent.PotionAddedEvent.getPotionEffect() method.

    You probably will have to apply the effect a second time with the higher amplifier here because the event is not cancellable which is not super clean. Also make sure you don't cause an infinite loop of applying effects here.

    Finally, you can update the added effect with a new MobEffectInstance with a higher amplifier by calling the MobEffectInstance.update(MobEffectInstance) method.

    This is what the final event handler looks like:

        @SubscribeEvent
        public void onPotionAdded(PotionEvent.PotionAddedEvent event) {
            MobEffectInstance effect = event.getPotionEffect();
            if(event.getOldPotionEffect() == null) {
                return;
            }
            if (effect.getEffect().equals(ModEffects.METH_EFFECT.get())) {
                MobEffectInstance amplifiedEffect = new MobEffectInstance(effect.getEffect(), effect.getDuration(), effect.getAmplifier() + 1);         
                effect.update(amplifiedEffect);
            }
        }
    

    Alternatively, you can probably create your own subclass of `MobEffectInstance` which overrides the `update(MobEffectInstance)` method. This is the method that is called whenever an effect is applied and the same effect already exists on that entity. Here you could create your own logic specialized for your item. You can then use your custom class in the declaration of your `METH` object. This is probably the cleaner but possibly more difficult way.