-
Posts
424 -
Joined
-
Last visited
Everything posted by Daeruin
-
Here's how you use ItemStackHandler capability: private ItemStackHandler inventory; public ModTileEntity() { this.inventory = new ItemStackHandler(<number of slots needed>); } Then you can use the methods in ItemStackHandler to manipulate your inventory.
-
[1.10.2] [SOLVED] Spawning particles in onBlockActivated
Daeruin replied to Daeruin's topic in Modder Support
I'm using 1.10.2, as stated in the post title. Pretty sure my override is fine, as my version of Block shows this: public boolean onBlockActivated(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, @Nullable ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) -
I want to spawn some fire particles in my block's onBlockActivated method, when a variable in my tile entity is the right value (basically, you have to "activate" the block 3 times within a small window of time before the particles will spawn, and I'm saving the number of times and time elapsed in my tile entity). I have read about a million posts on this, and everything says that you should be able to spawn vanilla particles from the server. I swear I have seen examples of other mods doing this, too, but I can't get it to work. I know the code is running, because the println statement fires. I also tried sending a packet, but it didn't work. I didn't include that code since I don't really think I should have to do that anyway. Please correct me if I'm wrong. I also tried spawning the particles on the client, but even after grabbing a copy of my tile entity from the BlockPos parameter, I can't seem to access the variables (they don't change like they should). @Override public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) { EnumCampfireState campfireState = state.getValue(CAMPFIRE_STATE); TileEntity tileEntity = world.getTileEntity(pos); int stokeTime = ((PrimalTileEntityCampfire) tileEntity).tinderStokeTime; int timesBlown = ((PrimalTileEntityCampfire) tileEntity).tinderTimesBlown; if (world.isRemote) // client { // do stuff } else // server { if (heldItem == null && campfireState == EnumCampfireState.TINDER_STOKED) { if (stokeTime < 40) { ((PrimalTileEntityCampfire) tileEntity).tinderStokeTime = 60; ((PrimalTileEntityCampfire) tileEntity).tinderTimesBlown += 1; PrimalPacketHandler.INSTANCE.sendTo(new PrimalCampfirePacket(player, 0, pos), (EntityPlayerMP) player); } if (timesBlown > 3) { System.out.println("Spawning particle"); world.spawnParticle(EnumParticleTypes.FLAME, (double) pos.getX(), (double) pos.getY(), (double) pos.getZ(), 0.0D, 0.0D, 0.0D, new int[0]); } } } return true; }
-
[1.10.2] [SOLVED] Changing block state wipes out tile entity data?
Daeruin replied to Daeruin's topic in Modder Support
I think I've got it. I should have read your earlier comment more carefully. It seems like you could either check that the old and new block from the IBlockStates are NOT the same, and return true, else return false, like this: @Override public boolean shouldRefresh(World world, BlockPos pos, IBlockState oldState, IBlockState newState) { if (oldState.getBlock() != newState.getBlock()) return true; else return false; } Or check that the old and new block ARE the same, and return false. But don't just return false every time. -
[1.10.2] [SOLVED] Changing block state wipes out tile entity data?
Daeruin replied to Daeruin's topic in Modder Support
Worked like a charm! However, I have a question about this comment in the documentation: What does that mean? How should I "use it properly"? -
[1.10.2] [SOLVED] Changing block state wipes out tile entity data?
Daeruin replied to Daeruin's topic in Modder Support
Thank you, I'll try that and let you know how it goes! -
[1.10.2] [SOLVED] Changing block state wipes out tile entity data?
Daeruin replied to Daeruin's topic in Modder Support
Yes, I cut out a bunch of stuff that wasn't relevant to the question. -
I have a block with a tile entity. The block has several different states. In the block's onBlockActivated, when it is clicked on with a specific item, I want to change the block to a different state and set off a timer in my tile entity. I can get the timer part to work on its own, but when I change the block's state, the timer seems to be wiped out. ModBlock#onBlockActivated @Override public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ) { if (world.isRemote) { // spawn particles return false; } else return true; } else { TileEntity tileEntity = world.getTileEntity(pos); if (heldItem != null) { if (heldItem.getItem() instanceof PrimalItemGlowingEmber && state.getValue(CAMPFIRE_STATE) == EnumCampfireState.TINDER) { if (((PrimalTileEntityCampfire) tileEntity).tinderStokeTime == 0) { ((PrimalTileEntityCampfire) tileEntity).tinderStokeTime = 60; world.setBlockState(pos, getDefaultState().withProperty(CAMPFIRE_STATE, EnumCampfireState.TINDER_STOKED)); } return false; } return true; } } ModTileEntity#update public void update() { if (!this.world.isRemote) { EnumCampfireState campfireState = world.getBlockState(this.pos).getValue(PrimalBlockCampfire.CAMPFIRE_STATE); if (this.tinderStokeTime > 0) { --this.tinderStokeTime; } } If I remove the "world.setBlockState..." line from onBlockActivated, the timer variable gets set and decrements correctly. As soon as I add that line back in, the variable doesn't get set correctly (or gets reset somehow). I didn't think the state of my block would have anything to do with the tile entity data.
-
I hate when I answer my own questions 5 minutes after posting. Looks like I was thinking of it right. I used an anonymous class to override setStackInSlot, and it seems to be working OK. this.inventory = new ItemStackHandler(3) { @Override public void setStackInSlot(int slot, ItemStack stack) { validateSlotIndex(slot); if (ItemStack.areItemStacksEqual(this.stacks[slot], stack)) return; this.stacks[slot] = stack; if (slot == SLOT_INPUT) { setField(FIELD_TOTAL_COOK_TIME, getCookTime(stack)); } onContentsChanged(slot); } I have seen at least one case of someone using an anonymous class like this, where they accessed, say, setField using the class name, like TileEntityFurnace.this.setField(...). Is that important, and why?
-
I have created a custom furnace but am having trouble getting part of it working. In the vanilla furnace, it overrides setInventorySlotContents to watch for items getting put into the input slot, and sets the totalCookTime field based on that. The GUI checks the value in that field to update the white progress arrow. However, setInventorySlotContents is a method from IInventory. I am using ItemStackHandler. I am guessing I need to override setStackInSlot, or perhaps insertItem, with similar code to setInventorySlotContents. Am I thinking of that right? Here's setInventorySlotContents for reference:
-
I did this for my containers, because I wanted them to retain their inventory when broken. I created a method in my Tile Entity that looked like this: public void dropContainerWithInventory(World world, BlockPos pos, IBlockState state, EntityPlayer player, TileEntity tileEntity) { if (tileEntity != null && Item.getItemFromBlock(state.getBlock()) != null) { ItemStack stack = new ItemStack(this); NBTTagCompound inventoryTag = new NBTTagCompound(); tileEntity.writeToNBT(inventoryTag); NBTTagCompound masterTag = new NBTTagCompound(); masterTag.setTag("BlockEntityTag", inventoryTag); stack.setTagCompound(masterTag); spawnAsEntity(world, pos, stack); } world.setBlockToAir(pos); } If I remember right, you can delay the deletion of the tile entity by overriding removedByPlayer to return true if the willHarvest parameter is true.
-
I asked this same question just a few weeks ago. I'm sure others will have their own advice, but personally I think it's mostly a matter of style and organization. What will help you make sense of the code when you need to update to the next version of Forge 6 months from now? What would help others make sense of it when they write an add-on or want to help you fix a big? In my case, I have two capabilities set up so far--one to keep track of player thirst, and one for a whole set of booleans that keep track of whether the player has seen certain hints I give out. If I add a new capability that's closely related to thirst or relies somehow on thirst, like maybe temperature or drunkenness, I might piggy back on my existing thirst capability. But in general I think it's good to keep them separated just for organization's sake.
-
See definition #2: https://www.merriam-webster.com/dictionary/worthies "a worthy or prominent person"
-
Good idea. The first method (EntityItemPickupEvent.getItem) is actually Forge code. Would that suggestion also be made via MCPBot Issue Tracker?
-
Thanks. It's actually EntityItem#getEntityItem. I overlooked it before. The method names could perhaps be improved. The end result is pretty confusing: event.getItem().getEntityItem().getItem() == youritem The first method returns an EntityItem (not an Item), the second method returns an ItemStack (not an EntityItem), and the third method actually returns an Item.
-
This is probably something dumb, but I can't figure out how to find out if an EntityItem is a certain item. I'm using EntityItemPickupEvent, which can give you an EntityItem with event.getItem(). I can't see any method to return an Item type, and from Item I can't see any method to return an EntityItem. I've searched all over Google and haven't found anything recent that does this (1.7.10 and earlier seem to have different methods than 1.10.2). It seem like this sort of thing ought to be really common and easy to do for this event. Am I missing something?
-
Updating a Mod - How to do it correctly?
Daeruin replied to Mister__Magister's topic in Modder Support
Jabelar also has lots of good advice: http://jabelarminecraft.blogspot.com/p/minecraft-modding-general-tips-for.html http://jabelarminecraft.blogspot.com/p/minecraft-forge-upgrading.html -
For more up-to-date tutorials, I would recommend Shadowfacts. https://shadowfacts.net/tutorials/forge-modding-1102/
-
I have also found Shadowfacts' tutorials to be very helpful. There's no more up-to-date tutorial on containers with a GUI that I have been able to find. I created a tile entity with inventory and a GUI in 1.8.9 and recently updated to 1.10.2. I think I used BedrockMiner's tutorial that you linked to, and it worked great back then. Everything worked fine after updating to 1.10.2, other than a few minor tweaks to methods like you're seeing. The update to using ItemStackHandlers wasn't strictly necessary, but I went ahead since that seems to be the direction of the future. It was fairly painful to me, as you can see if you look up some of my more recent threads here on the forum. You can find a lot of my source code in those threads, which may also be helpful.
-
[1.10.2] Problems with custom slot in GUI on both client and server
Daeruin replied to Spyeedy's topic in Modder Support
Yes, move to last line of constructor. It changes the index of the slot in the player's overall inventory. If you do that, you will also need to adjust your constants and all the index numbers in transferStackInSlot as well. -
[1.10.2] Problems with custom slot in GUI on both client and server
Daeruin replied to Spyeedy's topic in Modder Support
It's too bad some of the more experienced modders haven't chimed in. I'm grasping at straws here, but you might try adding your custom slot last. That fixed a lot of problems for me, but I think that was because I was trying to replace the standard player inventory which is relied on in both survival and creative inventories, with different numbers of slots. I also noticed you reuse the variable i to add both the hot bar slots and the regular inventory slots. Probably not an issue, but it would be cleaner to use a different variable anyway. The shift-click problems definitely point to problems with transferStackInSlot. You could try putting a break point in and follow the program as it traces through the logic of that method. -
[1.10.2] hasContainerItem/getContainerItem no longer working
Daeruin replied to Daeruin's topic in Modder Support
Indeed, you're right. Many thanks. How did you know? I keep thinking I should be able to figure these things out on my own, but I guess I don't know where to look. -
[SOLVED] [1.10.2] Container won't save contents and gives error on login
Daeruin replied to Daeruin's topic in Modder Support
Very true. Alright, I'm calling this done. Thanks to everyone who helped out on this one. I couldn't have done it without you. -
[SOLVED] [1.10.2] Container won't save contents and gives error on login
Daeruin replied to Daeruin's topic in Modder Support
Well, for the love of all that's holy. It seems to be working now. Surely this isn't always needed. Shadowfacts' fine tutorial doesn't mention it at all, for example. http://shadowfacts.net/tutorials/forge-modding-1102/tile-entities-inventory/ -
[SOLVED] [1.10.2] Container won't save contents and gives error on login
Daeruin replied to Daeruin's topic in Modder Support
I was worried about that in my OP but nobody said anything about it. Do I need to do something to explicitly sync between client and server? I don't recall ever having to do that explicitly before updating to capabilities.