Предмет и индикатором. Проблема при игре через сервер.

127
0
Добрый день,

Я сделал, предмет, который вставляется прибор. При работе прибора предмет теряет прочность, отображая прочность  в виде полоски индикатора.
При игре через сервер возникла проблема, полоска начинает моргать, то появляется то не появляется, и если появляется то всегда целая. Подскажите в чем может быть дело, в какую сторону копать?
 Код предмета:
Код:
public class ItemLens extends Item {
    public static enum TypeLens {
        base,
        normal,
        advance,
        perfect
    }
    private int maxDmg;
    private TypeLens typeLens;

    public ItemLens(int i, int maxDmg, TypeLens typeLens) {
        super(i);
        this.maxDmg = maxDmg;
        this.setMaxStackSize(1);
        this.setMaxDamage(this.maxDmg);
        this.setNoRepair();
        this.typeLens = typeLens;
    }   

    @SideOnly(Side.CLIENT)
    public void addInformation(ItemStack stack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) {
        super.addInformation(stack, par2EntityPlayer, par3List, par4);
        Integer dmg = getDamageOfStack(stack);
        par3List.add(EnumChatFormatting.YELLOW + "Максимальный: " + maxDmg);
        par3List.add(EnumChatFormatting.RED + "Получено: " + dmg);
    }

    @SideOnly(Side.CLIENT)
    public EnumRarity getRarity(ItemStack var1) {
        return EnumRarity.uncommon;
    }

    public void setDamageForStack(ItemStack stack, int advDmg) {
        NBTTagCompound nbtData = ItemStackUtil.getOrCreateNbtData(stack);
          nbtData.setInteger("advDmg", advDmg);
          if(this.maxDmg > 0) {
             double p = (double)advDmg / (double)this.maxDmg;
             int newDmg = (int)((double)stack.getMaxDamage() * p);
             if(newDmg >= stack.getMaxDamage()) {
                newDmg = stack.getMaxDamage() - 1;
             }

             stack.setItemDamage(newDmg);
          }

    }

    public int getDamageOfStack(ItemStack stack) {
        NBTTagCompound nbtData = ItemStackUtil.getOrCreateNbtData(stack);
        return nbtData.getInteger("advDmg");
    }

    public int getMaxDamageEx() {
        return this.maxDmg;
    }

    public void damageItemStack(ItemStack stack, int Dmg) {
        this.setDamageForStack(stack, this.getDamageOfStack(stack) + Dmg);    
    }
    
    public boolean isDamagest(ItemStack stack){
        return this.getDamageOfStack(stack) >= this.maxDmg;
    }
}
[merge_posts_bbcode]Добавлено: 18.06.2015 19:41:51[/merge_posts_bbcode]

Код прибора:
Код:
public void updateEntity() {
      super.updateEntity();
      if(!this.initialized && super.worldObj != null) {
         this.intialize();
      }

      if(!super.worldObj.isRemote) {
         if(this.lastX != super.xCoord || this.lastZ != super.zCoord || this.lastY != super.yCoord) {
            this.lastX = super.xCoord;
            this.lastY = super.yCoord;
            this.lastZ = super.zCoord;
            this.onUnloaded();
            this.intialize();
         }
         
         this.gainFuel();
         if(this.generating > 0) {
             int dmg = this.generating;
            if(this.storage + this.generating <= this.maxStorage) {
               this.storage += this.generating;
            } else {
                dmg = this.maxStorage - this.storage;
               this.storage = this.maxStorage;
            }
            dmgLens(dmg);
         }

         boolean needInvUpdate = false;
         boolean sentPacket = false;

         for(int i = 0; i < this.chargeSlots.length; ++i) {
            if(this.chargeSlots[i] != null && Item.itemsList[this.chargeSlots[i].itemID] instanceof IElectricItem && this.storage > 0) {
               int var4 = ElectricItem.manager.charge(this.chargeSlots[i], this.storage, 4, false, false);
               if(var4 > 0) {
                  needInvUpdate = true;
               }

               this.storage -= var4;
            }
         }

         if(needInvUpdate) {
            this.onInventoryChanged();
         }

      }
   }

public void dmgLens(int dmg) {
        ItemStack stack = getLens();
        if (stack != null && stack.getItem() instanceof ItemLens) {
            ItemLens lens = (ItemLens) stack.getItem();
            lens.damageItemStack(stack, dmg);
            if(lens.isDamagest(stack)){
                setInventorySlotLens(null);
            }
        }
    }
 
travnik, твой полоска моргает в приборе? Может сам прибор виноват?
 
Да полоска то появляется то исчезает, но даже когда она появляется, он всегда полная, даже если взять предмет в инвентарь, полоска всегда целая. И только через сервер наблюдается.
 
travnik, код прибора не полный. Так-что трудно предположить в чём проблема.
[merge_posts_bbcode]Добавлено: 18.06.2015 19:52:03[/merge_posts_bbcode]

minecraftsrv, и что? А по мойму похоже на энергоячейку. А так твоё сообщение считаю оффтопом.
 
Прибор является генератором энергии и работает при наличии этого объекта в слоте.
Полный код прибора
Код:
public class TileEntitySolarPanel extends TileEntityBase implements IEnergyTile, IWrenchable, IEnergySource, IInventory, INetworkDataProvider, INetworkUpdateListener, ISidedInventory {
    private static final int[] slots_top = new int[] { 4 };
    private static final int[] slots_bottom = new int[] { 4, 4 };
    private static final int[] slots_sides = new int[] { 4 };
   public static Random randomizer = new Random();
   public int ticker;
   public int generating;
   public int genDay;
   public int genNight;
   public boolean initialized;
   public boolean sunIsUp;
   public boolean skyIsVisible;
   private short facing = 2;
   private boolean noSunWorld;
   private boolean wetBiome;
   public boolean addedToEnergyNet;
   private boolean created = false;
   private ItemStack[] chargeSlots;
   private final int lensSlotIndex = 4;
   public int fuel;
   private int lastX;
   private int lastY;
   private int lastZ;
   public int storage;
   private int solarType;
   public String panelName;
   public int production;
   public int maxStorage;
   public boolean loaded = false;
   private static List<String> fields = Arrays.asList(new String[0]);


   public TileEntitySolarPanel(String gName, int typeSolar, int gDay, int gNight, int gOutput, int gmaxStorage) {
      this.solarType = typeSolar;
      this.genDay = gDay;
      this.genNight = gNight;
      this.storage = 0;
      this.panelName = gName;
      this.sunIsUp = false;
      this.skyIsVisible = false;
      this.maxStorage = gmaxStorage;
      this.chargeSlots = new ItemStack[getSizeInventory()];
      this.initialized = false;
      this.production = gOutput;
      this.ticker = randomizer.nextInt(this.tickRate());
      this.lastX = super.xCoord;
      this.lastY = super.yCoord;
      this.lastZ = super.zCoord;
   }

   public void validate() {
      super.validate();
      if(!this.isInvalid() && super.worldObj.blockExists(super.xCoord, super.yCoord, super.zCoord)) {
         this.onLoaded();
      }
   }

   public void invalidate() {
      if(this.loaded) {
         this.onUnloaded();
      }

      super.invalidate();
   }

   public void onLoaded() {
      if(!super.worldObj.isRemote) {
         MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this));
         this.addedToEnergyNet = true;
      }

      this.loaded = true;
   }

   public void onChunkUnload() {
      if(this.loaded) {
         this.onUnloaded();
      }

      super.onChunkUnload();
   }

   public void onUnloaded() {
      if(!super.worldObj.isRemote && this.addedToEnergyNet) {
         MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this));
         this.addedToEnergyNet = false;
      }

      this.loaded = false;
   }

   public void intialize() {
      this.wetBiome = super.worldObj.getWorldChunkManager().getBiomeGenAt(super.xCoord, super.zCoord).getIntRainfall() > 0;
      this.noSunWorld = super.worldObj.provider.hasNoSky;
      this.updateVisibility();
      this.initialized = true;
      if(!this.addedToEnergyNet) {
         this.onLoaded();
      }

   }

   public void updateEntity() {
      super.updateEntity();
      if(!this.initialized && super.worldObj != null) {
         this.intialize();
      }

      if(!super.worldObj.isRemote) {
         if(this.lastX != super.xCoord || this.lastZ != super.zCoord || this.lastY != super.yCoord) {
            this.lastX = super.xCoord;
            this.lastY = super.yCoord;
            this.lastZ = super.zCoord;
            this.onUnloaded();
            this.intialize();
         }
         
         this.gainFuel();
         if(this.generating > 0) {
             int dmg = this.generating;
            if(this.storage + this.generating <= this.maxStorage) {
               this.storage += this.generating;
            } else {
                dmg = this.maxStorage - this.storage;
               this.storage = this.maxStorage;
            }
            dmgLens(dmg);
         }

         boolean needInvUpdate = false;
         boolean sentPacket = false;

         for(int i = 0; i < this.chargeSlots.length; ++i) {
            if(this.chargeSlots[i] != null && Item.itemsList[this.chargeSlots[i].itemID] instanceof IElectricItem && this.storage > 0) {
               int var4 = ElectricItem.manager.charge(this.chargeSlots[i], this.storage, 4, false, false);
               if(var4 > 0) {
                  needInvUpdate = true;
               }

               this.storage -= var4;
            }
         }

         if(needInvUpdate) {
            this.onInventoryChanged();
         }

      }
   }

   public int gainFuel() {
      if(this.ticker++ % this.tickRate() == 0) {
         this.updateVisibility();
      }

      if(getLens() == null){
          this.generating = 0;
          return this.generating;
      }
 
      
      if(this.sunIsUp && this.skyIsVisible) {
         this.generating = 0 + this.genDay;
         return this.generating;
      } else if(this.skyIsVisible) {
         this.generating = 0 + this.genNight;
         return this.generating;
      } else {
         this.generating = 0;
         return this.generating;
      }
   }
   
    public void dmgLens(int dmg) {
        ItemStack stack = getLens();
        if (stack != null && stack.getItem() instanceof ItemLens) {
            ItemLens lens = (ItemLens) stack.getItem();
            lens.damageItemStack(stack, dmg);
            if(lens.isDamagest(stack)){
                setInventorySlotLens(null);
            }
        }
    }

   public void updateVisibility() {
      Boolean rainWeather = Boolean.valueOf(this.wetBiome && (super.worldObj.isRaining() || super.worldObj.isThundering()));
      if(super.worldObj.isDaytime() && !rainWeather.booleanValue()) {
         this.sunIsUp = true;
      } else {
         this.sunIsUp = false;
      }

      if(super.worldObj.canBlockSeeTheSky(super.xCoord, super.yCoord + 1, super.zCoord) && !this.noSunWorld) {
         this.skyIsVisible = true;
      } else {
         this.skyIsVisible = false;
      }

   }

   public void readFromNBT(NBTTagCompound nbttagcompound) {
      super.readFromNBT(nbttagcompound);
      this.storage = nbttagcompound.getInteger("storage");
      this.lastX = nbttagcompound.getInteger("lastX");
      this.lastY = nbttagcompound.getInteger("lastY");
      this.lastZ = nbttagcompound.getInteger("lastZ");
      NBTTagList nbttaglist = nbttagcompound.getTagList("Items");
      this.chargeSlots = new ItemStack[this.getSizeInventory()];

      for(int i = 0; i < nbttaglist.tagCount(); ++i) {
         NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i);
         int j = nbttagcompound1.getByte("Slot") & 255;
         if(j >= 0 && j < this.chargeSlots.length) {
            this.chargeSlots[j] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
         }
      }
   }

   public void writeToNBT(NBTTagCompound nbttagcompound) {
      super.writeToNBT(nbttagcompound);
      NBTTagList nbttaglist = new NBTTagList();
      nbttagcompound.setInteger("storage", this.storage);
      nbttagcompound.setInteger("lastX", this.lastX);
      nbttagcompound.setInteger("lastY", this.lastY);
      nbttagcompound.setInteger("lastZ", this.lastZ);

      for(int i = 0; i < this.chargeSlots.length; ++i) {
         if(this.chargeSlots[i] != null) {
            NBTTagCompound nbttagcompound1 = new NBTTagCompound();
            nbttagcompound1.setByte("Slot", (byte)i);
            this.chargeSlots[i].writeToNBT(nbttagcompound1);
            nbttaglist.appendTag(nbttagcompound1);
         }
      }

      nbttagcompound.setTag("Items", nbttaglist);
   }

   public boolean isAddedToEnergyNet() {
      return this.addedToEnergyNet;
   }

   public int getMaxEnergyOutput() {
      return this.production;
   }

   public int gaugeEnergyScaled(int i) {
      return this.storage * i / this.maxStorage;
   }

   public int gaugeFuelScaled(int i) {
      return i;
   }

   public boolean isUseableByPlayer(EntityPlayer entityplayer) {
      return entityplayer.getDistance((double)super.xCoord + 0.5D, (double)super.yCoord + 0.5D, (double)super.zCoord + 0.5D) <= 64.0D;
   }

   public int tickRate() {
      return 128;
   }

   public short getFacing() {
      return this.facing;
   }

   public void setFacing(short facing) {
      this.facing = facing;
   }

   public boolean wrenchCanSetFacing(EntityPlayer entityplayer, int i) {
      return false;
   }

   public boolean wrenchCanRemove(EntityPlayer entityplayer) {
      return true;
   }

   public float getWrenchDropRate() {
      return 1.0F;
   }

   public ItemStack getWrenchDrop(EntityPlayer entityPlayer) {
      return new ItemStack(super.worldObj.getBlockId(super.xCoord, super.yCoord, super.zCoord), 1, super.worldObj.getBlockMetadata(super.xCoord, super.yCoord, super.zCoord));
   }

   public ItemStack[] getContents() {
      return this.chargeSlots;
   }

   public int getSizeInventory() {
      return 5;
   }

   public ItemStack getStackInSlot(int i) {
      return this.chargeSlots[i];
   }
   
   public ItemStack getLens() {
       return getStackInSlot(this.lensSlotIndex);
   }
   
   public void setInventorySlotLens(ItemStack itemstack) {
       this.chargeSlots[this.lensSlotIndex] = itemstack;
          if(itemstack != null && itemstack.stackSize > this.getInventoryStackLimit()) {
             itemstack.stackSize = this.getInventoryStackLimit();
          }

          this.onInventoryChanged();
   }

   public ItemStack decrStackSize(int i, int j) {
      if(this.chargeSlots[i] != null) {
         ItemStack itemstack1;
         if(this.chargeSlots[i].stackSize <= j) {
            itemstack1 = this.chargeSlots[i];
            this.chargeSlots[i] = null;
            this.onInventoryChanged();
            return itemstack1;
         } else {
            itemstack1 = this.chargeSlots[i].splitStack(j);
            if(this.chargeSlots[i].stackSize == 0) {
               this.chargeSlots[i] = null;
            }

            this.onInventoryChanged();
            return itemstack1;
         }
      } else {
         return null;
      }
   }

   public void setInventorySlotContents(int i, ItemStack itemstack) {
       if(i == this.lensSlotIndex && itemstack != null && !(itemstack.getItem() instanceof ItemLens) ){
               return;
           }
      this.chargeSlots[i] = itemstack;
      if(itemstack != null && itemstack.stackSize > this.getInventoryStackLimit()) {
         itemstack.stackSize = this.getInventoryStackLimit();
      }

      this.onInventoryChanged();
   }

   public int getInventoryStackLimit() {
      return 64;
   }

   public void openChest() {}

   public void closeChest() {}

   public Container getGuiContainer(InventoryPlayer inventoryplayer) {
      return new ContainerAdvSolarPanel(inventoryplayer, this);
   }

   public String getInvName() {
      return null;
   }

   public ItemStack getStackInSlotOnClosing(int var1) {
      if(this.chargeSlots[var1] != null) {
         ItemStack var2 = this.chargeSlots[var1];
         this.chargeSlots[var1] = null;
         return var2;
      } else {
         return null;
      }
   }

   public boolean isInvNameLocalized() {
      return false;
   }

   public boolean isItemValidForSlot(int i, ItemStack itemstack) {
      return true;
   }

   public void onNetworkUpdate(String field) {}

   public List<String> getNetworkedFields() {
      return fields;
   }

   public boolean emitsEnergyTo(TileEntity receiver, ForgeDirection direction) {
      return true;
   }

   public double getOfferedEnergy() {
      return (double)Math.min(this.production, this.storage);
   }

   public void drawEnergy(double amount) {
      this.storage = (int)((double)this.storage - amount);
   }

    public int[] getAccessibleSlotsFromSide(int side) {
        return side == 0?slots_bottom:(side == 1?slots_top:slots_sides);
    }

    public boolean canInsertItem(int index, ItemStack itemStack, int side) {
        return index == lensSlotIndex;
    }

    public boolean canExtractItem(int index, ItemStack itemStack, int side) {
        return true;
    }

}
 
travnik, ты используешь методы: "getDescriptionPacket" и "onDataPacket" в твоём TileEntity?
Это для 1.7.10.
Код:
    public Packet getDescriptionPacket() {
        NBTTagCompound nbt = new NBTTagCompound();
        writeToNBT(nbt);
        return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 0, nbt);
    }

    public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity packet) {
        readFromNBT(packet.func_148857_g());
    }
Я не вижу их, но я заметил "TileEntityBase", а я не знаю что в нём. И с таким кодом можно провозиться и только тычиться в коде.
[merge_posts_bbcode]Добавлено: 18.06.2015 20:00:36[/merge_posts_bbcode]

И на какую версию Minecraft ты делаешь этот код?
 
Майн 1.6.4
Код:
public class TileEntityBase extends TileEntity implements IWrenchable, INetworkDataProvider, INetworkTileEntityEventListener {

   public boolean active = false;
   public short facing = 5;
   public boolean prevActive = false;
   public short prevFacing = 0;


   public boolean getActive() {
      return this.active;
   }

   public short getFacing() {
      return this.facing;
   }

   public boolean wrenchCanSetFacing(EntityPlayer var1, int facingToSet) {
      return facingToSet >= 2 && facingToSet != this.facing;
   }

   public void setFacing(short var1) {
      this.facing = var1;
      NetworkHelper.updateTileEntityField(this, "facing");
      this.prevFacing = var1;
      NetworkHelper.announceBlockUpdate(super.worldObj, super.xCoord, super.yCoord, super.zCoord);
   }

   public void onNetworkEvent(int event) {}

   public List<String> getNetworkedFields() {
      return null;
   }

   public boolean wrenchCanRemove(EntityPlayer entityPlayer) {
      return true;
   }

   public float getWrenchDropRate() {
      return 1.0F;
   }

   public ItemStack getWrenchDrop(EntityPlayer entityPlayer) {
      return new ItemStack(super.worldObj.getBlockId(super.xCoord, super.yCoord, super.zCoord), 1, super.worldObj.getBlockMetadata(super.xCoord, super.yCoord, super.zCoord));
   }
}
 
Такое ощущение, что обнуляется значение ItemDamage и поэтому полоска пропадает
[merge_posts_bbcode]Добавлено: 19.06.2015 12:39:26[/merge_posts_bbcode]

Проверил, урон ([font=Verdana, Helvetica, Arial, sans-serif]ItemDamage[/font]) у предмета доходит до 32768 и обнуляется, стоит на нуле и через некоторое время опять начинает набирать урон до 32768. Из-за этого и полоска то появляется то пропадает.
 
32768 = 256*128, раньше было вообще просто 256.
Просто используй меньшее значение, мне кажется 32768 и так дохера для какого то урона.
В любом случае, всегда есть NBTagCompound у ItemStack, можешь хранить там хитровы###ные значения.
 
Да в [font=Verdana, Helvetica, Arial, sans-serif]NBTagCompound и храню эти значения. Мне и int не хватает если честно, хотя нужна прочность больше 2х миллиардов.[/font]
 
Все спасибо, решил проблему. Храню в itemdamage процентный урон.
Код:
double p = (double)advDmg / (double)this.maxDmg;
             int newDmg = (int)((double)stack.getMaxDamage() * p);
             if(newDmg >= stack.getMaxDamage()) {
                newDmg = stack.getMaxDamage() - 1;
             }

             stack.setItemDamage(newDmg);
 
Назад
Сверху