Итем с эффектом и текстурой.

Версия Minecraft
1.7.10
929
30
66
Всем привет.

Как сделать итему эффект ночного зрения (одевать на новыеслоты) , и чтобы появлялась на голове(типо шлем).
 
Решение
Ок. Пример с добавлением ночного видения при надевании кольчужного шлема.

Это слот:
Java:
public class CustomSlot extends Slot {

    private final EntityPlayer player;

    public CustomSlot(EntityPlayer player, IInventory inventory, int slotIndex, int xPos, int yPos) {
   
        super(inventory, slotIndex, xPos, yPos);
   
        this.player = player;
    }

    //При доставании из слота.
    @Override
    public void onPickupFromSlot(EntityPlayer player, ItemStack itemStack) {
                
        this.onSlotChanged();
        
        if (!this.player.worldObj.isRemote)
        if (this.getSlotIndex() == 0 /*индекс твоего слота*/ && (this.getStack() == null || this.getStack().getItem() != Items.chainmail_helmet)) {...
929
30
66
Так же смотрел в моде lastdayz дам он как шлем,но есть на шлем одеть ничего не будет, а на доп слот(через контейнер) , то и текстура на лице и эффект

в baubles mod'e , тоже контейнеры , там даётся за кольцо ускорение,но где проверка ХЗ
 
Последнее редактирование:
929
30
66
@timaxa007 вот из bubles эвент
Java:
 @SubscribeEvent
   public void playerTick(LivingUpdateEvent event) {
      if(event.entity instanceof EntityPlayer) {
         EntityPlayer player = (EntityPlayer)event.entity;
         InventoryBaubles baubles = PlayerHandler.getPlayerBaubles(player);

         for(int a = 0; a < baubles.getSizeInventory(); ++a) {
            if(baubles.getStackInSlot(a) != null && baubles.getStackInSlot(a).getItem() instanceof IBauble) {
               ((IBauble)baubles.getStackInSlot(a).getItem()).onWornTick(baubles.getStackInSlot(a), player);
            }
         }
      }

   }

Если потом в итем дать эффект через OnWornTick и тот эвент поставить , это будет как проверка ?
 

timaxa007

Модератор
5,831
409
672
вот из bubles эвент
И что? А у меня это:
Java:
    @SubscribeEvent
    public void onLivingEvent(LivingEvent.LivingUpdateEvent event) {
        if (event.entity instanceof EntityPlayer) {
            PlayerInv pi = PlayerInv.get((EntityPlayer)event.entity);
            if (pi != null) pi.update((EntityPlayer)event.entity);
        }
    }
Который вызывает это:
Java:
    public void update(EntityPlayer player) {
        ItemStack pnv = inv.getStackInSlot(0);
        if (pnv != null && pnv.getItem() instanceof ItemCustomArmorDummy)
            usedPNV = true; else usedPNV = false;

        if (usedPNV && !last_usedPNV) player.addPotionEffect(new PotionEffect(Potion.nightVision.id, Integer.MAX_VALUE, 0, true));
        if (!usedPNV && last_usedPNV) player.removePotionEffect(Potion.nightVision.id);

        last_usedPNV = usedPNV;
    }
 
929
30
66
[1.7.10] (с использованием эвента)
Container и GuiContainer - брал от сундука
Java:
public class PlayerInv implements IExtendedEntityProperties {

    public final static String TAG = SMTCommon.MODID + ":AddInv";

    public final InventoryBasic inv = new InventoryBasic(null, false, 8 * 3);

    public PlayerInv() {}

    boolean usedPNV, last_usedPNV;

    public void update(EntityPlayer player) {
        ItemStack pnv = inv.getStackInSlot(0);
        if (pnv != null && pnv.getItem() instanceof ItemCustomArmorDummy)
            usedPNV = true; else usedPNV = false;

        if (usedPNV && !last_usedPNV) player.addPotionEffect(new PotionEffect(Potion.nightVision.id, Integer.MAX_VALUE, 0, true));
        if (!usedPNV && last_usedPNV) player.removePotionEffect(Potion.nightVision.id);

        last_usedPNV = usedPNV;
    }

    @Override
    public void init(Entity entity, World world) {

    }

    public static void reg(Entity entity) {
        entity.registerExtendedProperties(PlayerInv.TAG, new PlayerInv());
    }

    public static PlayerInv get(Entity entity) {
        return entity != null ? (PlayerInv)entity.getExtendedProperties(TAG) : null;
    }

    @Override
    public void saveNBTData(NBTTagCompound nbt) {
        NBTTagCompound compound = new NBTTagCompound();
        NBTTagList list = new NBTTagList();
        for (int i = 0; i < inv.getSizeInventory(); ++i) {
            if (inv.getStackInSlot(i) == null) continue;
            NBTTagCompound slot_nbt = new NBTTagCompound();
            inv.getStackInSlot(i).writeToNBT(slot_nbt);
            slot_nbt.setByte("Slot", (byte)i);
            list.appendTag(slot_nbt);
        }
        compound.setTag("Inventory", list);
        nbt.setTag(TAG, compound);
    }

    @Override
    public void loadNBTData(NBTTagCompound nbt) {
        if (nbt.hasKey(TAG)) {
            NBTTagCompound compound = (NBTTagCompound)nbt.getTag(TAG);
            if (compound.hasKey("Inventory", NBT.TAG_LIST)) {
                NBTTagList list = compound.getTagList("Inventory", NBT.TAG_COMPOUND);
                for (int i = 0; i < list.tagCount(); ++i) {
                    NBTTagCompound slot_nbt = list.getCompoundTagAt(i);
                    inv.setInventorySlotContents((slot_nbt.getByte("Slot") & 255), ItemStack.loadItemStackFromNBT(slot_nbt));
                }
            }
        }
    }

}
Общий EventHandler (Forge шина)
Java:
    @SubscribeEvent
    public void addEntityConstructing(EntityEvent.EntityConstructing event) {
        if (event.entity instanceof EntityPlayer) {
            if (PlayerInv.get((EntityPlayer)event.entity) == null)
                PlayerInv.reg((EntityPlayer)event.entity);
        }
    }

    @SubscribeEvent
    public void onLivingEvent(LivingEvent.LivingUpdateEvent event) {
        if (event.entity instanceof EntityPlayer) {
            PlayerInv pi = PlayerInv.get((EntityPlayer)event.entity);
            if (pi != null) pi.update((EntityPlayer)event.entity);
        }
    }
Клиентский EventHandler (Forge шина)
Java:
    @SubscribeEvent
    public void onRenderModelForPlayer(RenderPlayerEvent.Specials.Post event) {
        PlayerInv pi = PlayerInv.get((EntityPlayer)event.entity);
        if (pi == null) return;

        ItemStack pnv = pi.inv.getStackInSlot(0);
        if (pnv == null || !(pnv.getItem() instanceof ItemCustomArmorDummy)) return;
        ItemCustomArmorDummy ivcad = (ItemCustomArmorDummy)pnv.getItem();
        ArmorCustomModel acm = ivcad.getModel(event.entityPlayer, pnv, -1);
        if (acm != null) {
            acm.partHead.set(event.renderer.modelBipedMain.bipedHead);
            acm.partBody.set(event.renderer.modelBipedMain.bipedBody);
            acm.partRightArm.set(event.renderer.modelBipedMain.bipedRightArm);
            acm.partLeftArm.set(event.renderer.modelBipedMain.bipedLeftArm);
            acm.partRightLeg.set(event.renderer.modelBipedMain.bipedRightLeg);
            acm.partLeftLeg.set(event.renderer.modelBipedMain.bipedLeftLeg);
            acm.render(event.entityPlayer);
        }
    }
Я всё же не понял, а где тут указывается слот ??(проверяется )
 

timaxa007

Модератор
5,831
409
672
-_-
Переменная - "ItemStack pnv = inv.getStackInSlot(0);", берётся слот "inv.getStackInSlot(0);"
inv это "public final InventoryBasic inv = new InventoryBasic(null, false, 8 * 3);" в PlayerInv.
У тебя место inv может быть inventory.
 

timaxa007

Модератор
5,831
409
672
Ну а смысл от своего контейнера, если он не постоянно будет открыт? Рендер и давания эффекта будет если открыт твой контейнер, закрыт его рендера не будет, а каким нибудь багом возможен оставления эффекта без наличии в слоте ПНВ.
 

timaxa007

Модератор
5,831
409
672
На счёт этого, нет. По сути это ещё можно реализовать. Эффект останиться, если сделать правильные условия.
Но рендер исчезнит. Хотя и тут можно сделать так, чтобы рендер остался.
Но лучше сделать с проверкой не через контейнер.
 

timaxa007

Модератор
5,831
409
672
У тебя не только контейнеры, У тебя есть InventoryCustomPlayer, через него наверное можно попробовать.
Java:
InventoryCustomPlayer icp = new InventoryCustomPlayer(player);//или другой объект где уже храниться нужная информация
ItemStack pnv = icp.inventory[1];
if (pnv != null && pnv.getItem() == HarvestItems.pnv) {
//клиент - рендер, сервер - эффект
}
Но я не знаю точно будет у тебя работать, так как сам по себе код твой может быть не так работать как надо.
Или надо место
Java:
InventoryCustomPlayer icp = new InventoryCustomPlayer(player);
ItemStack pnv = icp.inventory[1];
надо
Java:
ItemStack pnv = ExtendedPlayer.get(player).inventory.inventory[1];
Я не знаю, как там у тебя работает код.
 
Последнее редактирование:
929
30
66
@timaxa007 вот так)
Java:
public class InventoryCustomPlayer extends InventoryPlayer implements IInventory {

   private final String name = "Inventory";
   private final String tagName = "CustomInvTag";
   public static final int INV_SIZE = 2;
   public ItemStack[] inventory = new ItemStack[INV_SIZE];


   public InventoryCustomPlayer(EntityPlayer player) {
      super(player);
      super.player = player;
   }

   public void copy(InventoryCustomPlayer inv) {
      for(int i = 0; i < inv.getSizeInventory(); ++i) {
         ItemStack stack = inv.getStackInSlot(i);
         this.inventory[i] = stack == null?null:stack.copy();
      }

      this.markDirty();
   }

   public int getSizeInventory() {
      return this.inventory.length;
   }

   public ItemStack getStackInSlot(int slot) {
      return this.inventory[slot];
   }

   public ItemStack decrStackSize(int slot, int amount) {
      ItemStack stack = this.getStackInSlot(slot);
      if(stack != null) {
         if(stack.stackSize > amount) {
            stack = stack.splitStack(amount);
            this.markDirty();
         } else {
            this.setInventorySlotContents(slot, (ItemStack)null);
         }
      }

      return stack;
   }

   public ItemStack getStackInSlotOnClosing(int slot) {
      ItemStack stack = this.getStackInSlot(slot);
      this.setInventorySlotContents(slot, (ItemStack)null);
      return stack;
   }

   public void setInventorySlotContents(int slot, ItemStack stack) {
      this.inventory[slot] = stack;
      if(stack != null && stack.stackSize > this.getInventoryStackLimit()) {
         stack.stackSize = this.getInventoryStackLimit();
      }

      this.markDirty();
   }

   public String getInventoryName() {
      return "Inventory";
   }

   public boolean hasCustomInventoryName() {
      return "Inventory".length() > 0;
   }

   public int getInventoryStackLimit() {
      return 1;
   }

   public void markDirty() {
      for(int i = 0; i < this.getSizeInventory(); ++i) {
         if(this.getStackInSlot(i) != null && this.getStackInSlot(i).stackSize == 0) {
            this.inventory[i] = null;
         }
      }

   }

   public boolean isUseableByPlayer(EntityPlayer player) {
      return true;
   }

   public void openInventory() {}

   public void closeInventory() {}

   public boolean isItemValidForSlot(int slot, ItemStack stack) {
      return false;
   }

   public void writeToNBT(NBTTagCompound compound) {
      NBTTagList items = new NBTTagList();

      for(int i = 0; i < this.getSizeInventory(); ++i) {
         if(this.getStackInSlot(i) != null) {
            NBTTagCompound item = new NBTTagCompound();
            item.setByte("Slot", (byte)i);
            this.getStackInSlot(i).writeToNBT(item);
            items.appendTag(item);
         }
      }

      compound.setTag("CustomInvTag", items);
   }

   public void readFromNBT(NBTTagCompound compound) {
      NBTTagList items = compound.getTagList("CustomInvTag", compound.getId());

      for(int i = 0; i < items.tagCount(); ++i) {
         NBTTagCompound item = items.getCompoundTagAt(i);
         byte slot = item.getByte("Slot");
         if(slot >= 0 && slot < this.getSizeInventory()) {
            this.inventory[slot] = ItemStack.loadItemStackFromNBT(item);
         }
      }

   }
}
 
929
30
66
У тебя не только контейнеры, У тебя есть InventoryCustomPlayer, через него наверное можно попробовать.
Java:
InventoryCustomPlayer icp = new InventoryCustomPlayer(player);//или другой объект где уже храниться нужная информация
ItemStack pnv = icp.inventory[1];
if (pnv != null && pnv.getItem() == HarvestItems.pnv) {
//клиент - рендер, сервер - эффект
}
Но я не знаю точно будет у тебя работать, так как сам по себе код твой может быть не так работать как надо.
Или надо место
Java:
InventoryCustomPlayer icp = new InventoryCustomPlayer(player);
ItemStack pnv = icp.inventory[1];
надо
Java:
ItemStack pnv = ExtendedPlayer.get(player).inventory.inventory[1];
Я не знаю, как там у тебя работает код.

Через onUpdate ?
 
243
28
202
Чувак, ты замахнулся на сложную тему для твоего текущего уровня, но я могу подсказать неплохой вариант.

Я предлагаю все проверки и действия делать прямо в твоем Slot в методах putStack() и onTake() (в 1.7.10 не помню как называется), раз он у тебя все равно свой. Тебе понадобится в конструктор слота дополнительно добавить аргумент EntityPlayer для доступа к игроку (для добавления эффектов, удаления и т.д. в объекте слота) и передать егь в конструктор слота, когда ты добавляешь его в контейнер. В слоте делаешь поле EntityPlayer и инициализируешь его в конструкторе переданным игроком.

Все действия делаешь в двух методах, которые я указал выше. Тебе необходимо проверить что действия на сервере (EntityPlayer#worldObj#isRemote == false) и вешать или удалять свои эффекты.

Для рендера чего либо из слота нужен какой нибудь клиентский тикер, как советовали выше.

Вот тут как раз есть решение твоей проблемы (пример под твои запросы, смотри только действия над Slot - все остальнон тебе не нужно, так как он свой у тебя) - Тык
 
Сверху