Minecraft从定制药水效果中添加新的药水效果

时间:2018-04-16 06:31:30

标签: java minecraft minecraft-forge

目前正试图创造一种药水效果,一旦它耗尽时间,就会向玩家施加其他药水效果。看似简单但我发现了一些错误和错误试图完成这个,

直接尝试添加效果

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

毋庸置疑,这会产生此错误

  

[16:10:04] [服务器线程/错误]:遇到意外的异常       net.minecraft.util.ReportedException:Ticking player         在net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:212)   〜[NetworkSystem.class:?]         at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:807)   〜[MinecraftServer.class:?]         在net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:688)   〜[MinecraftServer.class:?]         at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:156)   〜[IntegratedServer.class:?]         在net.minecraft.server.MinecraftServer.run(MinecraftServer.java:537)   [MinecraftServer.class:?]         在java.lang.Thread.run(未知来源)[?:1.8.0_161]       引起: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:?]         在net.minecraft.entity.Entity.onUpdate(Entity.java:436)〜[Entity.class:?]         at net.minecraft.entity.EntityLivingBase.onUpdate(EntityLivingBase.java:2144)   〜[EntityLivingBase.class:?]         在net.minecraft.entity.player.EntityPlayer.onUpdate(EntityPlayer.java:260)   〜[EntityPlayer.class:?]         at net.minecraft.entity.player.EntityPlayerMP.onUpdateEntity(EntityPlayerMP.java:345)   〜[EntityPlayerMP.class:?]         在net.minecraft.network.NetHandlerPlayServer.update(NetHandlerPlayServer.java:174)   〜[NetHandlerPlayServer.class:?]         在net.minecraftforge.fml.common.network.handshake.NetworkDispatcher $ 1.update(NetworkDispatcher.java:216)   〜[NetworkDispatcher $ 1.class :?]         在net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:309)   〜[NetworkManager.class:?]         在net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:197)   〜[NetworkSystem.class:?]         ......还有5个

好像我在勾选事件中运行它

在CommonProxy

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

然后对于EventManager本身

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

}

这很有效,但效果是无限的。

1 个答案:

答案 0 :(得分:2)

当你的魔药效果被循环时,你正在执行你的动作。这类似于在迭代时修改数组。不要那样做。

此外,请勿执行药水效果客户端等操作。 做客户端的唯一事情是图形和用户输入/输出。

必须在服务器上处理像药水这样的事情,否则服务器将覆盖您对下一个更新数据包的操作。

只需在ExtendPlayer实体中设置一个标志,然后onTick或玩家更新事件检查该标志是否存在,然后添加魔药。

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

类似于您的扩展播放器

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

从事件处理程序

调用扩展的播放器更新事件
 @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();
            }
        }