Jarrod Muddyman
Jarrod Muddyman

Reputation: 21

Minecraft add new potion effects from custom potion effect

Currently trying to create a potion effect that once it runs out of time, applies other potion effects to the player. Seemed simple enough yet I found a few errors and bugs trying to accomplish this,

Directly trying to add the effect

    @Override
    public void performEffect(EntityLivingBase entity, int amplifier){
        if (entity instanceof EntityPlayer)
        {
            EntityPlayer player = (EntityPlayer)entity;
            if(player != null){
                if(player.getActivePotionEffect(PotionRegistry.effectBuzz) != null){
                int duraction = player.getActivePotionEffect(PotionRegistry.effectBuzz).getDuration();
                    if(duration <= 2){
                        player.addPotionEffect(new PotionEffect(MobEffects.WEAKNESS, 1200));
                    }
                }
            }
        }
    }

Needless to say this produces this error

[16:10:04] [Server thread/ERROR]: Encountered an unexpected exception net.minecraft.util.ReportedException: Ticking player at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:212) ~[NetworkSystem.class:?] at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:807) ~[MinecraftServer.class:?] at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:688) ~[MinecraftServer.class:?] at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:156) ~[IntegratedServer.class:?] at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:537) [MinecraftServer.class:?] at java.lang.Thread.run(Unknown Source) [?:1.8.0_161] Caused by: java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode(Unknown Source) ~[?:1.8.0_161] at java.util.HashMap$KeyIterator.next(Unknown Source) ~[?:1.8.0_161] at net.minecraft.entity.EntityLivingBase.updatePotionEffects(EntityLivingBase.java:650) ~[EntityLivingBase.class:?] at net.minecraft.entity.EntityLivingBase.onEntityUpdate(EntityLivingBase.java:383) ~[EntityLivingBase.class:?] at net.minecraft.entity.Entity.onUpdate(Entity.java:436) ~[Entity.class:?] at net.minecraft.entity.EntityLivingBase.onUpdate(EntityLivingBase.java:2144) ~[EntityLivingBase.class:?] at net.minecraft.entity.player.EntityPlayer.onUpdate(EntityPlayer.java:260) ~[EntityPlayer.class:?] at net.minecraft.entity.player.EntityPlayerMP.onUpdateEntity(EntityPlayerMP.java:345) ~[EntityPlayerMP.class:?] at net.minecraft.network.NetHandlerPlayServer.update(NetHandlerPlayServer.java:174) ~[NetHandlerPlayServer.class:?] at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher$1.update(NetworkDispatcher.java:216) ~[NetworkDispatcher$1.class:?] at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:309) ~[NetworkManager.class:?] at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:197) ~[NetworkSystem.class:?] ... 5 more

Where as if I run this in a tick event

In CommonProxy

MinecraftForge.EVENT_BUS.register(new EventManager());

And then For the EventManager itself

public class EventManager {

public static PotionEffect potion = new PotionEffect(MobEffects.WEAKNESS, 1200);
public static PotionEffect potion2 = new PotionEffect(MobEffects.HUNGER, 600);
public static PotionEffect potion3 = new PotionEffect(MobEffects.UNLUCK, 1200);

@SubscribeEvent
public void onTick(WorldTickEvent event){
    EntityPlayer player = Minecraft.getMinecraft().thePlayer;
    World world = Minecraft.getMinecraft().theWorld;
    if(player != null){
        boolean hasEffect = player.isPotionActive(PotionRegistry.effectBuzz);
        int applyIt = 0;

        if(hasEffect){
            applyIt = 1;
        } else if(!player.isPotionActive(potion.getPotion()) && applyIt == 1){
            applyIt = 2;
        } else {
            applyIt = 0;
        }

        if(player != null && applyIt == 2){
            player.addPotionEffect(potion);
        }
    }
}

}

This works, yet the effects are infinite.

Upvotes: 1

Views: 3326

Answers (1)

Tschallacka
Tschallacka

Reputation: 28742

You're performing your action whilst the potion effects are being looped. This is akin to modifying an array whilst iterating it. Don't do that.

Also, don't perform actions like potion effects client side. The ONLY thing to do client side is graphics and user input/output.

Things like potions must be handled on the server, otherwise the server will overwrite your actions on the next update packet.

Just set a flag in your ExtendPlayer entity, and then onTick or player update event check for that flag existance and then add the potions.

@Override
public void performEffect(EntityLivingBase entity, int amplifier){
    if (entity instanceof EntityPlayer)
    {
        EntityPlayer player = (EntityPlayer)entity;
        if(player != null){
            if(player.getActivePotionEffect(PotionRegistry.effectBuzz) != null){
            int duraction = player.getActivePotionEffect(PotionRegistry.effectBuzz).getDuration();
                if(duration <= 2){
                    ExtendedPlayer ePlayer = ExtendedPlayer.get(player);
                    ePlayer.enableBuzz();
                }
            }
        }
    }
}

Something akin to your Extended player

public class ExtendedPlayer implements IExtendedEntityProperties {

     ... Extended player setup here

     protected boolean startBuzz = false;

     public void enableBuzz() 
     {
          this.startBuzz = true;
     }
     public static final ExtendedPlayer get(EntityPlayer player) {
        return (ExtendedPlayer) player.getExtendedProperties("MuddymansExtendedPlayer");
    }

    public EntityPlayer getPlayer() {
        return this.player;
    }

    /**
    * Updates anything that needs to be updated each tick
    * NOT called automatically, so you must call it yourself from LivingUpdateEvent or a TickHandler
    */
    public void onUpdate() {
        if(!player.worldObj.isRemote) {
            if(this.enableBuzz) {
                Player player = this.getPlayer()
                player.addPotionEffect(new PotionEffect(MobEffects.WEAKNESS, 1200));
                player.addPotionEffect(new PotionEffect(MobEffects.HUNGER, 600));
                player.addPotionEffect(new PotionEffect(MobEffects.UNLUCK, 1200));
                this.startBuzz = false;
            }
        }
    } 
}

Call the exteded player update event from an event handler

 @SubscribeEvent
 public void livingTick(final LivingUpdateEvent event) {
        if (event.entity != null && event.entity instanceof EntityPlayer) {
            if(!event.entity.isDead) {
                ExtendedPlayer.get((EntityPlayer)event.entity).onUpdate();
            }
        }

Upvotes: 2

Related Questions