Jump to content

JimiIT92

Members
  • Posts

    866
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by JimiIT92

  1. Main mod file (where i register the packet handler) public static SimpleNetworkWrapper network; @EventHandler public void preInit(FMLPreInitializationEvent event) { network = NetworkRegistry.INSTANCE.newSimpleChannel("BL_Channel"); network.registerMessage(NetworkMessage.Handler.class, NetworkMessage.class, 0, Side.SERVER); ... } In the ClientProxy MinecraftForge.EVENT_BUS.register(new EventReceiver()); The NetworkMessage class (with Handler inner class) package blaze.proxy; import io.netty.buffer.ByteBuf; import net.minecraft.util.IThreadListener; import net.minecraft.world.WorldServer; import net.minecraftforge.fml.common.network.ByteBufUtils; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; public class NetworkMessage implements IMessage { private String text; public NetworkMessage() { } public NetworkMessage(String text) { this.text = text; } @Override public void fromBytes(ByteBuf buf) { text = ByteBufUtils.readUTF8String(buf); } @Override public void toBytes(ByteBuf buf) { ByteBufUtils.writeUTF8String(buf, text); } public static class Handler implements IMessageHandler<NetworkMessage, IMessage> { @Override public IMessage onMessage(final NetworkMessage message, final MessageContext ctx) { IThreadListener mainThread = (WorldServer) ctx.getServerHandler().playerEntity.worldObj; mainThread.addScheduledTask(new Runnable() { @Override public void run() { //TODO What's going on here?? } }); return null; } } } The container class package blaze.gui.container; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.init.Blocks; import net.minecraft.inventory.Container; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.inventory.Slot; import net.minecraft.inventory.SlotCrafting; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.util.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; public class ContainerNewWorkbench extends Container { /** The crafting matrix inventory (3x3). */ public InventoryCrafting craftMatrix = new InventoryCrafting(this, 3, 3); public IInventory craftResult = new InventoryCraftResult(); private World worldObj; private BlockPos pos; public ContainerNewWorkbench(final InventoryPlayer playerInventory, World worldIn, BlockPos position) { this.worldObj = worldIn; this.pos = position; this.addSlotToContainer(new SlotCrafting(playerInventory.player, this.craftMatrix, this.craftResult, 0, 124, 35)); int i; int j; /** * SLOT 0-8 */ for (i = 0; i < 3; ++i) { for (j = 0; j < 3; ++j) { this.addSlotToContainer(new Slot(this.craftMatrix, j + i * 3, 30 + j * 18, 17 + i * 18)); } } /** * SLOT 9-35 */ for (i = 0; i < 3; ++i) { for (j = 0; j < 9; ++j) { this.addSlotToContainer(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); } } /** * SLOT 36-44 */ for (i = 0; i < 9; ++i) { this.addSlotToContainer(new Slot(playerInventory, i, 8 + i * 18, 142)); } /** * 45-48 */ for(i = 0; i < 4; i++) { final int k = i; this.addSlotToContainer(new Slot(playerInventory, playerInventory.getSizeInventory() - 1 - i, 8 + 9 * 18, 84 + i * 18) { /** * Returns the maximum stack size for a given slot (usually the same as getInventoryStackLimit(), but 1 * in the case of armor slots) */ public int getSlotStackLimit() { return 1; } /** * Check if the stack is a valid item for this slot. Always true beside for the armor slots. */ public boolean isItemValid(ItemStack stack) { if (stack == null) return false; return stack.getItem().isValidArmor(stack, k, playerInventory.player); } @SideOnly(Side.CLIENT) public String getSlotTexture() { return ItemArmor.EMPTY_SLOT_NAMES[k]; } }); } this.onCraftMatrixChanged(this.craftMatrix); } /** * Callback for when the crafting matrix is changed. */ public void onCraftMatrixChanged(IInventory inventoryIn) { this.craftResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.worldObj)); } /** * Called when the container is closed. */ public void onContainerClosed(EntityPlayer playerIn) { super.onContainerClosed(playerIn); if (!this.worldObj.isRemote) { for (int i = 0; i < 9; ++i) { ItemStack itemstack = this.craftMatrix.getStackInSlotOnClosing(i); if (itemstack != null) { playerIn.dropPlayerItemWithRandomChoice(itemstack, false); } } } } public boolean canInteractWith(EntityPlayer playerIn) { return this.worldObj.getBlockState(this.pos).getBlock() != Blocks.crafting_table ? false : playerIn.getDistanceSq((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.5D, (double)this.pos.getZ() + 0.5D) <= 64.0D; } /** * Take a stack from the specified inventory slot. */ public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) { ItemStack itemstack = null; Slot slot = (Slot)this.inventorySlots.get(index); if (slot != null && slot.getHasStack()) { ItemStack itemstack1 = slot.getStack(); itemstack = itemstack1.copy(); /** * FROM THE CRAFT RESULT SLOT */ if (index == 0) { if (!this.mergeItemStack(itemstack1, 10, 46, true)) { return null; } slot.onSlotChange(itemstack1, itemstack); } /** * FROM THE INV */ else if (index >= 10 && index < 37) { System.out.println("INV"); if (!this.mergeItemStack(itemstack1, 37, 46, false)) { return null; } } /** * FROM THE HOTBAR */ else if (index >= 37 && index < 46) { System.out.println("HOTBAR"); if (!this.mergeItemStack(itemstack1, 10, 37, false)) { return null; } } /** * FROM THE ARMOR */ else if ((index >= 47 && index < 50) && itemstack.getItem() instanceof ItemArmor && !((Slot)this.inventorySlots.get(47 + ((ItemArmor)itemstack.getItem()).armorType)).getHasStack()) { System.out.println("ARMOR"); int j = 47 + ((ItemArmor)itemstack.getItem()).armorType; if (!this.mergeItemStack(itemstack1, j, j + 1, false)) { return null; } } /** * FROM CRAFTING GRID */ else if (!this.mergeItemStack(itemstack1, 10, 46, false)) { System.out.println("GRID!"); return null; } if (itemstack1.stackSize == 0) { slot.putStack((ItemStack)null); } else { slot.onSlotChanged(); } if (itemstack1.stackSize == itemstack.stackSize) { return null; } slot.onPickupFromSlot(playerIn, itemstack1); } return itemstack; } /** * Called to determine if the current slot is valid for the stack merging (double-click) code. The stack passed in * is null for the initial slot that was double-clicked. */ public boolean canMergeSlot(ItemStack itemstack, Slot slot) { return slot.inventory != this.craftResult && super.canMergeSlot(itemstack, slot); } } The GUI Class package blaze.gui; import blaze.gui.container.ContainerNewWorkbench; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.util.BlockPos; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) public class GUINewWorkbench extends GuiContainer { private static final ResourceLocation craftingTableGuiTextures = new ResourceLocation("blaze:textures/gui/container/crafting_table.png"); public GUINewWorkbench(InventoryPlayer playerInv, World worldIn) { this(playerInv, worldIn, BlockPos.ORIGIN); } public GUINewWorkbench(InventoryPlayer playerInv, World worldIn, BlockPos blockPosition) { super(new ContainerNewWorkbench(playerInv, worldIn, blockPosition)); } /** * Draw the foreground layer for the GuiContainer (everything in front of the items). Args : mouseX, mouseY */ protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { this.fontRendererObj.drawString(I18n.format("container.crafting", new Object[0]), 28, 6, 4210752); this.fontRendererObj.drawString(I18n.format("container.inventory", new Object[0]), 8, this.ySize - 96 + 2, 4210752); } /** * Args : renderPartialTicks, mouseX, mouseY */ protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); this.mc.getTextureManager().bindTexture(craftingTableGuiTextures); int k = (this.width - this.xSize) / 2; int l = (this.height - this.ySize) / 2; this.drawTexturedModalRect(k, l, 0, 0, 194, this.ySize); } } The GUIHandler Class package blaze.gui; import blaze.gui.container.ContainerNewWorkbench; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.common.network.IGuiHandler; public class GUINewWorkbenchHandler implements IGuiHandler { public GUINewWorkbenchHandler() { // TODO Auto-generated constructor stub } //returns an instance of the Container you made earlier @Override public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { System.out.println("SERVER: " + id); return new ContainerNewWorkbench(player.inventory, world, new BlockPos(x, y , z)); } //returns an instance of the Gui you made earlier @Override public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { System.out.println("CLIENT: " + id); return new GUINewWorkbench(player.inventory, world, new BlockPos(x, y , z)); } } If i missed something please tell me and i will provide any missing class EDIT: in the EventReceiver class @SubscribeEvent public void onEvent(GuiOpenEvent event) { if(event.gui instanceof GuiCrafting) { BL.network.sendToServer(new NetworkMessage("craftingTable")); event.gui = new GUINewWorkbench(Minecraft.getMinecraft().thePlayer.inventory, Minecraft.getMinecraft().theWorld); } }
  2. The tutorial says: call NetworkRegistry.INSTANCE.newSimpleChannel("myChannel"). Store the result in a static field in your Mod class. DONE register your Packet, call registerMessage(MyMessageHandler.class, MyMessage.class, packetID, receivingSide) on the wrapper you obtained. DONE Implementing the packet class and the packet handler. DONE, it's the same class of the tutorial send IMessage instances to various targets. DONE. If i have a println in the run method it prints The only thing i really don't understand is this The IMessageHandler simply requires one method, onMessage. Do whatever you want your packet to do in this method. Since i've never worked before with packets and all this stuff i don't know what to place in that method. A new instance of the container? A new one of the GUIHandler? I don't really know
  3. So i need to do this? BL.network.sendToServer(new NetworkMessage("craftingTable")); Where NetworkMessage is my IMessage class package blaze.proxy; import io.netty.buffer.ByteBuf; import net.minecraft.util.IThreadListener; import net.minecraft.world.WorldServer; import net.minecraftforge.fml.common.network.ByteBufUtils; import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; public class NetworkMessage implements IMessage { private String text; public NetworkMessage() { } public NetworkMessage(String text) { this.text = text; } @Override public void fromBytes(ByteBuf buf) { text = ByteBufUtils.readUTF8String(buf); } @Override public void toBytes(ByteBuf buf) { ByteBufUtils.writeUTF8String(buf, text); } public static class Handler implements IMessageHandler<NetworkMessage, IMessage> { @Override public IMessage onMessage(final NetworkMessage message, final MessageContext ctx) { IThreadListener mainThread = (WorldServer) ctx.getServerHandler().playerEntity.worldObj; mainThread.addScheduledTask(new Runnable() { @Override public void run() { System.out.println(String.format("Received %s from %s", message.text, ctx.getServerHandler().playerEntity.getDisplayName())); } }); return null; } } } and it's registered like this network = NetworkRegistry.INSTANCE.newSimpleChannel("BL_Channel"); network.registerMessage(NetworkMessage.Handler.class, NetworkMessage.class, 0, Side.SERVER); I've tried this but nothing changed EDIT: in the EventReceiver class @SubscribeEvent public void onEvent(GuiOpenEvent event) { if(event.gui instanceof GuiCrafting) { BL.network.sendToServer(new NetworkMessage("craftingTable")); event.gui = new GUINewWorkbench(Minecraft.getMinecraft().thePlayer.inventory, Minecraft.getMinecraft().theWorld); } }
  4. I'm opening the GUI from this Event Handler @SubscribeEvent public void onEvent(GuiOpenEvent event) { if(event.gui instanceof GuiCrafting) { event.gui = new GUINewWorkbench(Minecraft.getMinecraft().thePlayer.inventory, Minecraft.getMinecraft().theWorld); } } So basically right-clicking on the crafting table will open my custom GUI (and it actually does). This could be the reason why the GUIHandler is never called i guess
  5. I've tried doing this in the main mod init method NetworkRegistry.INSTANCE.registerGuiHandler(this, new GUINewWorkbenchHandler()); With this handler package blaze.gui; import blaze.container.ContainerNewWorkbench; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.common.network.IGuiHandler; public class GUINewWorkbenchHandler implements IGuiHandler { //returns an instance of the Container you made earlier @Override public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { System.out.println("SERVER: " + id); return new ContainerNewWorkbench(player.inventory, world, new BlockPos(x, y , z)); } //returns an instance of the Gui you made earlier @Override public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { System.out.println("CLIENT: " + id); return new GUINewWorkbench(player.inventory, world, new BlockPos(x, y , z)); } } But it doesn't work Also the handler code is never called
  6. How can i send that packet? I'm asking you this since it's the first time i work with GUI and events in general The GUI works right now, except for the 4 extra slots, they accept only respective armor items but i can't pick up anything from that slots, it disappear and it gives me that error. It's like that slots doesn't exist for the game
  7. Any idea? I really don't understand why it gives me the out of bound exception since the inv size is greater than the selected slot
  8. I've looked into vanilla inventory container class, so now the extra slot works as normal armor slots The only problem is that when i click in it it gives an outOfBoundException, and also the item disappear (but when reopening the GUI is in inventory) So this is the Container class right now package blaze.container; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.init.Blocks; import net.minecraft.inventory.Container; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.inventory.Slot; import net.minecraft.inventory.SlotCrafting; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.util.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; public class ContainerNewWorkbench extends Container { /** The crafting matrix inventory (3x3). */ public InventoryCrafting craftMatrix = new InventoryCrafting(this, 3, 3); public IInventory craftResult = new InventoryCraftResult(); private World worldObj; private BlockPos pos; public ContainerNewWorkbench(final InventoryPlayer playerInventory, World worldIn, BlockPos position) { this.worldObj = worldIn; this.pos = position; this.addSlotToContainer(new SlotCrafting(playerInventory.player, this.craftMatrix, this.craftResult, 0, 124, 35)); int i; int j; for (i = 0; i < 3; ++i) { for (j = 0; j < 3; ++j) { this.addSlotToContainer(new Slot(this.craftMatrix, j + i * 3, 30 + j * 18, 17 + i * 18)); } } for (i = 0; i < 3; ++i) { for (j = 0; j < 9; ++j) { this.addSlotToContainer(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); } } for (i = 0; i < 9; ++i) { this.addSlotToContainer(new Slot(playerInventory, i, 8 + i * 18, 142)); } for(i = 0; i < 4; i++) { final int k = i; this.addSlotToContainer(new Slot(playerInventory, playerInventory.getSizeInventory() - 1 - i, 8 + 9 * 18, 84 + i * 18) { /** * Returns the maximum stack size for a given slot (usually the same as getInventoryStackLimit(), but 1 * in the case of armor slots) */ public int getSlotStackLimit() { return 1; } /** * Check if the stack is a valid item for this slot. Always true beside for the armor slots. */ public boolean isItemValid(ItemStack stack) { if (stack == null) return false; return stack.getItem().isValidArmor(stack, k, playerInventory.player); } @SideOnly(Side.CLIENT) public String getSlotTexture() { return ItemArmor.EMPTY_SLOT_NAMES[k]; } }); } this.onCraftMatrixChanged(this.craftMatrix); } /** * Callback for when the crafting matrix is changed. */ public void onCraftMatrixChanged(IInventory inventoryIn) { this.craftResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.worldObj)); } /** * Called when the container is closed. */ public void onContainerClosed(EntityPlayer playerIn) { super.onContainerClosed(playerIn); if (!this.worldObj.isRemote) { for (int i = 0; i < 9; ++i) { ItemStack itemstack = this.craftMatrix.getStackInSlotOnClosing(i); if (itemstack != null) { playerIn.dropPlayerItemWithRandomChoice(itemstack, false); } } } } public boolean canInteractWith(EntityPlayer playerIn) { return this.worldObj.getBlockState(this.pos).getBlock() != Blocks.crafting_table ? false : playerIn.getDistanceSq((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.5D, (double)this.pos.getZ() + 0.5D) <= 64.0D; } /** * Take a stack from the specified inventory slot. */ public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) { ItemStack itemstack = null; Slot slot = (Slot)this.inventorySlots.get(index); if (slot != null && slot.getHasStack()) { ItemStack itemstack1 = slot.getStack(); itemstack = itemstack1.copy(); if (index == 0) { if (!this.mergeItemStack(itemstack1, 10, 46, true)) { return null; } slot.onSlotChange(itemstack1, itemstack); } else if (index >= 10 && index < 37) { if (!this.mergeItemStack(itemstack1, 37, 46, false)) { return null; } } else if (index >= 37 && index < 46) { if (!this.mergeItemStack(itemstack1, 10, 37, false)) { return null; } } else if (!this.mergeItemStack(itemstack1, 10, 46, false)) { return null; } else if (itemstack.getItem() instanceof ItemArmor && !((Slot)this.inventorySlots.get(36 + ((ItemArmor)itemstack.getItem()).armorType)).getHasStack()) { int j = 36 + ((ItemArmor)itemstack.getItem()).armorType; if (!this.mergeItemStack(itemstack1, j, j + 1, false)) { return null; } } if (itemstack1.stackSize == 0) { slot.putStack((ItemStack)null); } else { slot.onSlotChanged(); } if (itemstack1.stackSize == itemstack.stackSize) { return null; } slot.onPickupFromSlot(playerIn, itemstack1); } return itemstack; } /** * Called to determine if the current slot is valid for the stack merging (double-click) code. The stack passed in * is null for the initial slot that was double-clicked. */ public boolean canMergeSlot(ItemStack itemstack, Slot slot) { return slot.inventory != this.craftResult && super.canMergeSlot(itemstack, slot); } } And this is the behavior described above https://www.youtube.com/watch?v=X8t39b5utVI and this is the error that it gives in eclipse [15:16:38] [server thread/FATAL] [FML]: Exception caught executing FutureTask: java.util.concurrent.ExecutionException: java.lang.IndexOutOfBoundsException: Index: 46, Size: 46 java.util.concurrent.ExecutionException: java.lang.IndexOutOfBoundsException: Index: 46, Size: 46 at java.util.concurrent.FutureTask.report(Unknown Source) ~[?:1.8.0_51] at java.util.concurrent.FutureTask.get(Unknown Source) ~[?:1.8.0_51] at net.minecraftforge.fml.common.FMLCommonHandler.callFuture(FMLCommonHandler.java:710) [FMLCommonHandler.class:?] at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:726) [MinecraftServer.class:?] at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:669) [MinecraftServer.class:?] at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:171) [integratedServer.class:?] at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:540) [MinecraftServer.class:?] at java.lang.Thread.run(Unknown Source) [?:1.8.0_51] Caused by: java.lang.IndexOutOfBoundsException: Index: 46, Size: 46 at java.util.ArrayList.rangeCheck(Unknown Source) ~[?:1.8.0_51] at java.util.ArrayList.get(Unknown Source) ~[?:1.8.0_51] at net.minecraft.inventory.Container.slotClick(Container.java:473) ~[Container.class:?] at net.minecraft.network.NetHandlerPlayServer.processClickWindow(NetHandlerPlayServer.java:1039) ~[NetHandlerPlayServer.class:?] at net.minecraft.network.play.client.C0EPacketClickWindow.processPacket(C0EPacketClickWindow.java:46) ~[C0EPacketClickWindow.class:?] at net.minecraft.network.play.client.C0EPacketClickWindow.processPacket(C0EPacketClickWindow.java:110) ~[C0EPacketClickWindow.class:?] at net.minecraft.network.PacketThreadUtil$1.run(PacketThreadUtil.java:24) ~[PacketThreadUtil$1.class:?] at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:1.8.0_51] at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_51] at net.minecraftforge.fml.common.FMLCommonHandler.callFuture(FMLCommonHandler.java:709) ~[FMLCommonHandler.class:?] ... 5 more
  9. The skeleton horse code is in the EntityHorse class For the armor i've tried overriding the get/setHorseType function to return 0, but nothing changed. What i'm trying to figure out is why the horse sometimes spawned un-tamed and i can't tame it
  10. Ok, quick update, if i click on the extra slot it gives me this error [20:33:38] [server thread/FATAL] [FML]: Exception caught executing FutureTask: java.util.concurrent.ExecutionException: java.lang.IndexOutOfBoundsException: Index: 48, Size: 46 java.util.concurrent.ExecutionException: java.lang.IndexOutOfBoundsException: Index: 48, Size: 46 at java.util.concurrent.FutureTask.report(Unknown Source) ~[?:1.8.0_51] at java.util.concurrent.FutureTask.get(Unknown Source) ~[?:1.8.0_51] at net.minecraftforge.fml.common.FMLCommonHandler.callFuture(FMLCommonHandler.java:710) [FMLCommonHandler.class:?] at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:726) [MinecraftServer.class:?] at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:669) [MinecraftServer.class:?] at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:171) [integratedServer.class:?] at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:540) [MinecraftServer.class:?] at java.lang.Thread.run(Unknown Source) [?:1.8.0_51] Caused by: java.lang.IndexOutOfBoundsException: Index: 48, Size: 46 at java.util.ArrayList.rangeCheck(Unknown Source) ~[?:1.8.0_51] at java.util.ArrayList.get(Unknown Source) ~[?:1.8.0_51] at net.minecraft.inventory.Container.slotClick(Container.java:473) ~[Container.class:?] at net.minecraft.network.NetHandlerPlayServer.processClickWindow(NetHandlerPlayServer.java:1039) ~[NetHandlerPlayServer.class:?] at net.minecraft.network.play.client.C0EPacketClickWindow.processPacket(C0EPacketClickWindow.java:46) ~[C0EPacketClickWindow.class:?] at net.minecraft.network.play.client.C0EPacketClickWindow.processPacket(C0EPacketClickWindow.java:110) ~[C0EPacketClickWindow.class:?] at net.minecraft.network.PacketThreadUtil$1.run(PacketThreadUtil.java:24) ~[PacketThreadUtil$1.class:?] at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:1.8.0_51] at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_51] at net.minecraftforge.fml.common.FMLCommonHandler.callFuture(FMLCommonHandler.java:709) ~[FMLCommonHandler.class:?] ... 5 more
  11. As by title i want to add a GUI to the Vanilla Armor Stand. I've tried to check this event @SubscribeEvent public void onRightClick(EntityInteractEvent event) { if(event.target instanceof EntityArmorStand) { System.out.println("STAND"); } } But when i right click the armor stand nothing happens, there is no print How can i check if the player is right clicking the armor stand? And also how can i show then the GUI?
  12. Thank you, deleting that function now generate only one mushroom as well
  13. This is my BlockMushroom class package hl.blocks; import java.util.Random; import hl.core.HLBlocks; import hl.core.HLFlowers; import hl.core.HLTabs; import net.minecraft.block.Block; import net.minecraft.block.BlockMushroom; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.BlockPos; import net.minecraft.world.World; import net.minecraft.world.gen.feature.WorldGenBigMushroom; public class BlockMushroomGlow extends BlockMushroom { public BlockMushroomGlow() { super(); this.setCreativeTab(HLTabs.tabDecorations); this.setStepSound(soundTypeGrass); this.setLightLevel(0.225F); } @Override protected boolean canPlaceBlockOn(Block ground) { return ground != HLFlowers.mushroomGlow; } /** * Whether this IGrowable can grow */ @Override public boolean canGrow(World worldIn, BlockPos pos, IBlockState state, boolean isClient) { return false; } @Override public boolean canUseBonemeal(World worldIn, Random rand, BlockPos pos, IBlockState state) { return false; } @Override public void grow(World worldIn, Random rand, BlockPos pos, IBlockState state) { } @Override public boolean generateBigMushroom(World worldIn, BlockPos pos, IBlockState state, Random rand) { return false; } }
  14. Vanilla uses this in the ChunkPoviderHell class. I've looked it and it does this BlockPos pos = new BlockPos(x, 0, z); boolean doGen = TerrainGen.decorate(world, random, pos, SHROOM); if (doGen && random.nextBoolean()) { new GenMushrooms((BlockBush)HLFlowers.mushroomGlow).generate(world, random, pos.add(random.nextInt(16) + 8, random.nextInt(128), random.nextInt(16) + ); } So i've this in my WorldGenMinable class package hl.world; import static net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.SHROOM; import java.util.Random; import com.google.common.base.Predicate; import hl.blocks.BlockHive; import hl.core.HLBlocks; import hl.core.HLFlowers; import hl.core.HLSummons; import net.minecraft.block.Block; import net.minecraft.block.BlockBush; import net.minecraft.block.BlockFlower; import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.pattern.BlockHelper; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.util.BlockPos; import net.minecraft.world.World; import net.minecraft.world.biome.BiomeGenBase; import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.gen.GeneratorBushFeature; import net.minecraft.world.gen.feature.WorldGenBlockBlob; import net.minecraft.world.gen.feature.WorldGenFlowers; import net.minecraft.world.gen.feature.WorldGenMinable; import net.minecraftforge.event.terraingen.TerrainGen; import net.minecraftforge.fml.common.IWorldGenerator; import sun.net.www.protocol.http.logging.HttpLogFormatter; public class WorldGenMinableHL implements IWorldGenerator { @Override public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) { switch(world.provider.getDimensionId()) { case 0: generateOverworld(random, world, chunkX*16, chunkZ*16); break; case -1: generateNether(random, world, chunkX*16, chunkZ*16); break; case 1: generateEnd(random, world, chunkX*16, chunkZ*16); break; default: generateOverworld(random, world, chunkX*16, chunkZ*16); } } private void generateOverworld(Random random, World world, int x, int z) { addOres(HLBlocks.limestone, world, random, x, z, 70, 20, 15, 252); addOres(HLBlocks.dirtDry, world, random, x, z, 70, 20, 15, 252); addOres(HLBlocks.lavastone, world, random, x, z, 15, 18, 15, 252); addMetaOres(HLBlocks.oreMythril.getStateFromMeta(0), world, random, x, z, 4, 10, 15, 20); for(int i = 0; i < 1; i++) { int randPosX = x + random.nextInt(16) + 8; int randPosY = random.nextInt(200); int randPosZ = z + random.nextInt(16) + 8; (new WorldGenFlowers((BlockFlower)HLFlowers.flowerPurple, BlockFlower.EnumFlowerType.DANDELION)).generate(world, random, new BlockPos(randPosX, randPosY, randPosZ)); } for(int i = 0; i < 1; i++) { int randPosX = x + random.nextInt(16) + 8; int randPosY = random.nextInt(200); int randPosZ = z + random.nextInt(16) + 8; (new WorldGenFlowers((BlockFlower)HLFlowers.flowerWhite, BlockFlower.EnumFlowerType.DANDELION)).generate(world, random, new BlockPos(randPosX, randPosY, randPosZ)); } BlockPos pos = new BlockPos(x, 0, z); boolean doGen = TerrainGen.decorate(world, random, pos, SHROOM); if (doGen && random.nextBoolean()) { new GenMushrooms((BlockBush)HLFlowers.mushroomGlow).generate(world, random, pos.add(random.nextInt(16) + 8, random.nextInt(128), random.nextInt(16) + ); } for(int i = 0; i < 20; i++) { int randPosX = x + random.nextInt(16) + 8; int randPosY = random.nextInt(100) + 50; int randPosZ = z + random.nextInt(16) + 8; new WorldGenHive().generate(world, random, new BlockPos(randPosX, randPosY, randPosZ)); } for (int j = 0; j < 15; j++) { int chance = random.nextInt(2); int randPosX = x + random.nextInt(16) + 8; int randPosZ = z + random.nextInt(16) + 8; int randPosY = random.nextInt(200); if(chance == 1) { (new WorldGenBush(HLBlocks.bush, 1)).generate(world, random, new BlockPos(randPosX, randPosY, randPosZ)); } } for(int i = 0; i < 15; i++) { int randPosX = x + random.nextInt(16); //DO NOT CHANGE THIS NUMBER int randPosY = random.nextInt(75); //ONLY CHANGE THIS ONE, IT SETS THE MAX HEIGHT AT WHICH IT GENERATES int randPosZ = z + random.nextInt(16); //DO NOT CHANGE THIS NUMBER BlockPos new_pos = new BlockPos(randPosX, randPosY, randPosZ); if(world.getBiomeGenForCoords(new_pos).equals(BiomeGenBase.beach)) { new WorldGenPalmTree().generate(world, random, new_pos); } } } private void generateEnd(Random random, World world, int x, int z) { addEndOres(HLBlocks.oreMythril.getStateFromMeta(1), world, random, x, z, 50, 15, 0, 200); } private void generateNether(Random random, World world, int x, int z) { for(int i = 0; i < 250; i++) { int randPosX = x + random.nextInt(16) + 8; int randPosY = random.nextInt(255); int randPosZ = z + random.nextInt(16) + 8; new WorldGenFireLily().generate(world, random, new BlockPos(randPosX, randPosY, randPosZ)); } } private void addOres(Block block, World world, Random random, int blockXpos, int blockZpos, int MaxVein, int spawnChance, int minY, int maxY) { WorldGenMinable minable = new WorldGenMinable(block.getDefaultState(), random.nextInt(MaxVein)); for (int i = 0; i < spawnChance; i++) { int posX = blockXpos + random.nextInt(16); int posZ = blockZpos + random.nextInt(16); int posY = minY + random.nextInt(maxY - minY); minable.generate(world, random, new BlockPos(posX, posY, posZ)); } } private void addEndOres(IBlockState block, World world, Random random, int blockXpos, int blockZpos, int MaxVein, int spawnChance, int minY, int maxY) { WorldGenMinable minable = new WorldGenMinable(block, random.nextInt(MaxVein), BlockHelper.forBlock(Blocks.end_stone)); for (int i = 0; i < spawnChance; i++) { int posX = blockXpos + random.nextInt(16); int posZ = blockZpos + random.nextInt(16); int posY = minY + random.nextInt(maxY - minY); minable.generate(world, random, new BlockPos(posX, posY, posZ)); } } private void addMetaOres(IBlockState block, World world, Random random, int blockXpos, int blockZpos, int MaxVein, int spawnChance, int minY, int maxY) { WorldGenMinable minable = new WorldGenMinable(block, random.nextInt(MaxVein)); for (int i = 0; i < spawnChance; i++) { int posX = blockXpos + random.nextInt(16); int posZ = blockZpos + random.nextInt(16); int posY = minY + random.nextInt(maxY - minY); minable.generate(world, random, new BlockPos(posX, posY, posZ)); } } } But nothing changed Still spawning like this
  15. Thanks for your help I've created the GUI and now I have this handler package blaze.gui; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.init.Blocks; import net.minecraft.inventory.Container; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.InventoryCraftResult; import net.minecraft.inventory.InventoryCrafting; import net.minecraft.inventory.Slot; import net.minecraft.inventory.SlotCrafting; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.CraftingManager; import net.minecraft.util.BlockPos; import net.minecraft.world.World; public class ContainerNewWorkbench extends Container { /** The crafting matrix inventory (3x3). */ public InventoryCrafting craftMatrix = new InventoryCrafting(this, 3, 3); public IInventory craftResult = new InventoryCraftResult(); private World worldObj; private BlockPos pos; public ContainerNewWorkbench(InventoryPlayer playerInventory, World worldIn, BlockPos position) { this.worldObj = worldIn; this.pos = position; this.addSlotToContainer(new SlotCrafting(playerInventory.player, this.craftMatrix, this.craftResult, 0, 124, 35)); int i; int j; /** * SLOTS CRAFTING 0-9 */ for (i = 0; i < 3; ++i) { for (j = 0; j < 3; ++j) { this.addSlotToContainer(new Slot(this.craftMatrix, j + i * 3, 30 + j * 18, 17 + i * 18)); } } /** * SLOTS 9-35 */ for (i = 0; i < 3; ++i) { for (j = 0; j < 9; ++j) { this.addSlotToContainer(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)); } } /** * SLOTS 0-9 */ for (i = 0; i < 9; ++i) { this.addSlotToContainer(new Slot(playerInventory, i, 8 + i * 18, 142)); } /** * START ADDING THE ADDITIONAL 4 SLOTS, THEY WILL BE THE SLOTS FOR THE HELMET, THE CHESTPLATE AND THE LEGGINGS AND THE BOOTS. * THIS SLOTS MUST BE AUTOMATICALLY FILLED WITH THE CURRENT ARMOR WEARED, ALSO IN CRAFTING * IF THE PLAYER CRAFT AN ARMOR THIS WILL AUTOMATICALLY BE PUTTED HERE IF EMPTY, SO THE PLAYER * WILL WEAR IT AS SOON AS HE CRAFTED IT * SLOTS 36-39 */ for (i = 0; i < 4; ++i) { this.addSlotToContainer(new Slot(playerInventory, 36 + i, 8 + 9 * 18, 84 + i * 18)); } this.onCraftMatrixChanged(this.craftMatrix); } /** * Callback for when the crafting matrix is changed. */ public void onCraftMatrixChanged(IInventory inventoryIn) { this.craftResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.worldObj)); } /** * Called when the container is closed. */ public void onContainerClosed(EntityPlayer playerIn) { super.onContainerClosed(playerIn); if (!this.worldObj.isRemote) { for (int i = 0; i < 9; ++i) { ItemStack itemstack = this.craftMatrix.getStackInSlotOnClosing(i); if (itemstack != null) { playerIn.dropPlayerItemWithRandomChoice(itemstack, false); } } } } public boolean canInteractWith(EntityPlayer playerIn) { return this.worldObj.getBlockState(this.pos).getBlock() != Blocks.crafting_table ? false : playerIn.getDistanceSq((double)this.pos.getX() + 0.5D, (double)this.pos.getY() + 0.5D, (double)this.pos.getZ() + 0.5D) <= 64.0D; } /** * Take a stack from the specified inventory slot. */ public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) { ItemStack itemstack = null; Slot slot = (Slot)this.inventorySlots.get(index); if (slot != null && slot.getHasStack()) { ItemStack itemstack1 = slot.getStack(); itemstack = itemstack1.copy(); if (index == 0) { if (!this.mergeItemStack(itemstack1, 10, 51, true)) { return null; } slot.onSlotChange(itemstack1, itemstack); } else if (index >= 10 && index < 37) { if (!this.mergeItemStack(itemstack1, 37, 51, false)) { return null; } } else if (index >= 37 && index < 46) { if (!this.mergeItemStack(itemstack1, 10, 37, false)) { return null; } } else if (index >= 47 && index < 51) { if (!this.mergeItemStack(itemstack1, 10, 47, false)) { return null; } } else if (!this.mergeItemStack(itemstack1, 10, 51, false)) { return null; } if (itemstack1.stackSize == 0) { slot.putStack((ItemStack)null); } else { slot.onSlotChanged(); } if (itemstack1.stackSize == itemstack.stackSize) { return null; } slot.onPickupFromSlot(playerIn, itemstack1); } return itemstack; } /** * Called to determine if the current slot is valid for the stack merging (double-click) code. The stack passed in * is null for the initial slot that was double-clicked. */ public boolean canMergeSlot(ItemStack itemstack, Slot slot) { return slot.inventory != this.craftResult && super.canMergeSlot(itemstack, slot); } } But there are a lot of problems with the additional slots. The 4 new slots should be automatically filled with the current armor weared. Actually they do but reversed (video below). Also i want that in that 4 slots only armor pieces can be putted (or everything else that can be weared (like skulls or pumpkins). Also if i craft an armor piece this should go in the correspective new slot, so the player will instantly wear it How can i do that? Another serious problem is that if i try to get something from that slot it disappear, gone forever, but if i try to put in ther it duplicates https://www.youtube.com/watch?v=cojKwg4i1T8&feature=youtu.be
  16. Thanks for your help Drawing all the texts after solve the problem
  17. I've done this for(int i = 0; i < 2; i++) { int randPosX = x + random.nextInt(16) + 8; int randPosY = random.nextInt(64); int randPosZ = z + random.nextInt(16) + 8; new GeneratorBushFeature((BlockBush) HLFlowers.mushroomGlow).generate(world, random, new BlockPos(randPosX, randPosY, randPosX)); } But it still spawns as an ore
  18. So i'm implementing the Buff Status Bar from the Minecraft Forge Wiki, the bar itself works fine but i've tried adding under the icon the duration of the effect. Duration works as well, is displayed correctly, but the icon for the effects are wrong So here is the status bar class package blaze.events; import java.util.Collection; import java.util.Iterator; import org.lwjgl.opengl.GL11; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.Gui; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; public class GUIBuffBar extends Gui { private Minecraft mc; FontRenderer fontRender; public GUIBuffBar(Minecraft mc) { super(); this.mc = mc; } private static final int BUFF_ICON_SIZE = 18; private static final int BUFF_ICON_SPACING = BUFF_ICON_SIZE + 5; // 2 pixels between buff icons private static final int BUFF_ICON_BASE_U_OFFSET = 0; private static final int BUFF_ICON_BASE_V_OFFSET = 198; private static final int BUFF_ICONS_PER_ROW = 8; @SubscribeEvent(priority = EventPriority.NORMAL) public void onRenderExperienceBar(RenderGameOverlayEvent event) { if(event.isCancelable() || event.type != ElementType.EXPERIENCE) { return; } int xPos = 2; int yPos = 2; fontRender = mc.fontRendererObj; Collection collection = this.mc.thePlayer.getActivePotionEffects(); if (!collection.isEmpty()) { GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); GL11.glDisable(GL11.GL_LIGHTING); this.mc.renderEngine.bindTexture(new ResourceLocation("textures/gui/container/inventory.png")); for (Iterator iterator = this.mc.thePlayer.getActivePotionEffects().iterator(); iterator.hasNext(); xPos += BUFF_ICON_SPACING) { PotionEffect potioneffect = (PotionEffect) iterator.next(); Potion potion = Potion.potionTypes[potioneffect.getPotionID()]; if (potion.hasStatusIcon()) { int iconIndex = potion.getStatusIconIndex(); this.drawTexturedModalRect( xPos, yPos, BUFF_ICON_BASE_U_OFFSET + iconIndex % BUFF_ICONS_PER_ROW * BUFF_ICON_SIZE, BUFF_ICON_BASE_V_OFFSET + iconIndex / BUFF_ICONS_PER_ROW * BUFF_ICON_SIZE, BUFF_ICON_SIZE, BUFF_ICON_SIZE); fontRender.drawStringWithShadow(potion.getDurationString(potioneffect), xPos, yPos + 20, 0xFFFFFF); } } } } } And this is what it looks like when multiple effects are active Thanks in advance for all who will help me
  19. I don't understand what the YourNewInventory class should looks like. I'm following this example to create a GUI http://www.minecraftforge.net/wiki/Containers_and_GUIs but i can't figure out why you pass only the player to the constructor (since the class takes a TileEntity as second parameter)
  20. How can i display a different GUI from a Vanilla Block? For example, i want to display this GUI when clicking on the crafting table where the additional 4 slots should be automatically filled with the current armor. Is there any way to make this? And if there is, how can i make it (any links to a tutorial or a previous post like this?)
  21. Also sometimes is not tamed when spawned. So i want that my custom horse is by default tamed and with a saddle. I've this class but as you can see in the video below the horse spawns tamed but without a saddle (or sometimes even spawn not tamed) package blaze.entities; import java.util.Iterator; import java.util.List; import com.google.common.base.Predicate; import blaze.core.BLItems; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityAgeable; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EnumCreatureAttribute; import net.minecraft.entity.IEntityLivingData; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.EntityAIFollowParent; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAIMate; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAIPanic; import net.minecraft.entity.ai.EntityAIRunAroundLikeCrazy; import net.minecraft.entity.ai.EntityAISwimming; import net.minecraft.entity.ai.EntityAITempt; import net.minecraft.entity.ai.EntityAIWander; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.ai.attributes.IAttribute; import net.minecraft.entity.ai.attributes.IAttributeInstance; import net.minecraft.entity.ai.attributes.RangedAttribute; import net.minecraft.entity.monster.EntitySkeleton; import net.minecraft.entity.passive.EntityAnimal; import net.minecraft.entity.passive.EntityHorse; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.inventory.AnimalChest; import net.minecraft.inventory.IInvBasic; import net.minecraft.inventory.InventoryBasic; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.pathfinding.PathNavigateGround; import net.minecraft.potion.Potion; import net.minecraft.server.management.PreYggdrasilConverter; import net.minecraft.util.BlockPos; import net.minecraft.util.DamageSource; import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.MathHelper; import net.minecraft.util.StatCollector; import net.minecraft.world.DifficultyInstance; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; public class EntityWitherHorse extends EntityHorse implements IInvBasic { private static final IAttribute horseJumpStrength = (new RangedAttribute((IAttribute)null, "horse.jumpStrength", 0.7D, 0.0D, 2.0D)).setDescription("Jump Strength").setShouldWatch(true); private static final String[] horseTextures = new String[] {"blaze:textures/entity/mobs/horse_skeleton_wither"}; private int eatingHaystackCounter; private int openMouthCounter; private int jumpRearingCounter; private float rearingAmount; private float prevRearingAmount; private float mouthOpenness; private float prevMouthOpenness; private AnimalChest horseChest; public EntityWitherHorse(World worldIn) { super(worldIn); this.isImmuneToFire = true; this.func_110226_cD(); } private void func_110226_cD() { AnimalChest animalchest = this.horseChest; this.horseChest = new AnimalChest("HorseChest", this.func_110225_cC()); this.horseChest.setCustomName(this.getName()); if (animalchest != null) { animalchest.func_110132_b(this); int i = Math.min(animalchest.getSizeInventory(), this.horseChest.getSizeInventory()); for (int j = 0; j < i; ++j) { ItemStack itemstack = animalchest.getStackInSlot(j); if (itemstack != null) { this.horseChest.setInventorySlotContents(j, itemstack.copy()); } } } this.horseChest.func_110134_a(this); this.func_110232_cE(); } private void func_110232_cE() { if (!this.worldObj.isRemote) { this.setHorseSaddled(this.horseChest.getStackInSlot(0) != null); if (this.canWearArmor()) { this.setHorseArmorStack(this.horseChest.getStackInSlot(1)); } } } private int func_110225_cC() { int i = this.getHorseType(); return this.isChested() && (i == 1 || i == 2) ? 17 : 2; } protected void entityInit() { super.entityInit(); } /** * Gets the name of this command sender (usually username, but possibly "Rcon") */ public String getName() { if (this.hasCustomName()) { return this.getCustomNameTag(); } else { return StatCollector.translateToLocal("entity.witherskeletonhorse.name"); } } private void setHorseWatchableBoolean(int par1, boolean par2) { int j = this.dataWatcher.getWatchableObjectInt(16); if (par2) { this.dataWatcher.updateObject(16, Integer.valueOf(j | par1)); } else { this.dataWatcher.updateObject(16, Integer.valueOf(j & ~par1)); } } /** * Returns the sound this mob makes on death. */ protected String getDeathSound() { this.openHorseMouth(); return "mob.horse.skeleton.death"; } protected Item getDropItem() { boolean flag = this.rand.nextInt(4) == 0; return flag ? Items.coal : Items.bone; } /** * Returns the sound this mob makes when it is hurt. */ protected String getHurtSound() { this.openHorseMouth(); if (this.rand.nextInt(3) == 0) { this.makeHorseRear(); } return "mob.horse.skeleton.hit"; } /** * Returns the sound this mob makes while it's alive. */ protected String getLivingSound() { this.openHorseMouth(); if (this.rand.nextInt(10) == 0 && !this.isMovementBlocked()) { this.makeHorseRear(); } return "mob.horse.skeleton.idle"; } /** * Dead and sleeping entities cannot move */ protected boolean isMovementBlocked() { return false; } @Override public boolean canWearArmor() { return false; } /** * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons * use this to react to sunlight and start to burn. */ @Override public void onLivingUpdate() { super.onLivingUpdate(); float f = (float)this.getEntityBoundingBox().minY; float f1 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F; float f2 = (this.rand.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F; if(this.rand.nextInt(5) == 0) { this.worldObj.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, this.posX + (double)f1, (double)(f + 0.8F), this.posZ + (double)f2, this.motionX, this.motionY, this.motionZ, new int[0]); } this.worldObj.spawnParticle(EnumParticleTypes.SPELL_MOB, this.posX + (double)f1, (double)(f + 0.8F), this.posZ + (double)f2, this.motionX, this.motionY, this.motionZ, new int[0]); } private void openHorseMouth() { if (!this.worldObj.isRemote) { this.openMouthCounter = 1; this.setHorseWatchableBoolean(128, true); } } private void makeHorseRear() { if (!this.worldObj.isRemote) { this.jumpRearingCounter = 1; this.setRearing(true); } } @Override public boolean isEntityInvulnerable(DamageSource source) { if(source.damageType.equals("lightningBolt")) return true; else return false; } public IEntityLivingData func_180482_a(DifficultyInstance difficulty, IEntityLivingData entity) { Object object = super.func_180482_a(difficulty, entity); boolean flag = false; int i = 0; int l; this.setHorseSaddled(true); this.horseChest.setInventorySlotContents(0, new ItemStack(Items.saddle)); this.setHorseTamed(true); EntityWitherSkeleton entityskeleton = new EntityWitherSkeleton(this.worldObj); entityskeleton.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F); entityskeleton.func_180482_a(difficulty, (IEntityLivingData)null); this.worldObj.spawnEntityInWorld(entityskeleton); entityskeleton.mountEntity(this); if (object instanceof EntityWitherHorse.GroupData) { l = ((EntityWitherHorse.GroupData)object).field_111107_a; i = ((EntityWitherHorse.GroupData)object).field_111106_b & 255 | this.rand.nextInt(5) << 8; } else { if (this.rand.nextInt(10) == 0) { l = 1; } else { int j = this.rand.nextInt(7); int k = this.rand.nextInt(5); l = 0; i = j | k << 8; } object = new EntityWitherHorse.GroupData(l, i); } this.setHorseType(l); this.setHorseVariant(i); if (this.rand.nextInt(5) == 0) { this.setGrowingAge(-24000); } if (l != 4 && l != 3) { this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue((double)this.func_110267_cL()); if (l == 0) { this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(this.func_110203_cN()); } else { this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.17499999701976776D); } } else { this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(15.0D); this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.20000000298023224D); } if (l != 2 && l != 1) { this.getEntityAttribute(horseJumpStrength).setBaseValue(this.func_110245_cM()); } else { this.getEntityAttribute(horseJumpStrength).setBaseValue(0.5D); } this.setHealth(this.getMaxHealth()); return (IEntityLivingData)object; } @SideOnly(Side.CLIENT) public float getRearingAmount(float par1) { return this.prevRearingAmount + (this.rearingAmount - this.prevRearingAmount) * par1; } @SideOnly(Side.CLIENT) public float func_110201_q(float par1) { return this.prevMouthOpenness + (this.mouthOpenness - this.prevMouthOpenness) * par1; } private float func_110267_cL() { return 15.0F + (float)this.rand.nextInt( + (float)this.rand.nextInt(9); } private double func_110245_cM() { return 0.4000000059604645D + this.rand.nextDouble() * 0.2D + this.rand.nextDouble() * 0.2D + this.rand.nextDouble() * 0.2D; } private double func_110203_cN() { return (0.44999998807907104D + this.rand.nextDouble() * 0.3D + this.rand.nextDouble() * 0.3D + this.rand.nextDouble() * 0.3D) * 0.25D; } public static class GroupData implements IEntityLivingData { public int field_111107_a; public int field_111106_b; public GroupData(int par1, int par2) { this.field_111107_a = par1; this.field_111106_b = par2; } } } Video here: https://www.youtube.com/watch?v=XDGvPwquDgg&feature=youtu.be is ther something that i'm missing?
  22. Could you please send me a link to a LivingDeathEvent example? For the despawn i can think a workaround: if the player dies in the fight despawn all the zombies (so the reward is spawned only if the player wins)
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.