Jump to content

making an item decay with time; adding decay in chest?


Yagoki

Recommended Posts

I'm trying to make an item which will decay/take damage over time to make a fairly OP branch of my mod a bit harder to reach. At the moment I can only make it decay using the "onUsingItemTick" method. Is there a way I can make it decay when it is just in the inventory or in the world?

 

Thanks in advance  :)

Link to comment
Share on other sites

Fixed it.

 

Changed the code to this and it seems to work fine for now

 

public void onUpdate(ItemStack stack, World world, Entity entity, int par4, boolean par5)
{
	if(stack.getItemDamage() == 1)
	{
		stack.itemID = 1;
	}else if(stack.getItemDamage() > 1 ){
		stack.setItemDamage(stack.getItemDamage() - 1);
	}else{
		stack.setItemDamage(20);
	}

}

 

the 1 for the final item id is just temp id to see if it was working, and the method feels a tad hackey, so if anyone can think of a better way let me know :)

Link to comment
Share on other sites

Just playing with the code as it is i found the item would not decay when in a chest (Haven't checked furnaces). Is there a way i could do this better so that its location does not matter?

 

also would not decay as an entity in the world, could this also be solved?

Link to comment
Share on other sites

  • 1 month later...

I happened upon this thread, as I'm also working on a mod that would benefit greatly from natural item decay.

 

A possible solution would be to compress the Minecraft date into the item's metadata, or create an NBTTag if you need more sophisticated functionality. Then, do an occasional check/update on one of the render passes. I'm new to modding, especially with Forge, so there may be a better function hook to use than the render ticks, but this would ensure that it would always update when visible.

 

As an example, say that you wanted your item to change/break after N minecraft days. Simply store the in-world date to the item's NBTTag when an instance is created. Then, whenever it is updated, calculate the difference in time (getTotalWorldTime() - NBTTag time) and compare to N*worldTimePerDay (set that constant yourself if it isn't somewhere in MC). If it's greater than N*worldTimePerDay, change/break the item by setting the nibble or replacing the ItemID for that instance. Otherwise, do nothing.

 

Possible classes/functions to accomplish this are:

getTotalWorldTime() in net.minecraft.world World

NBTTagCompound in net.minecraft.nbt

 

Let me know if you get this to work, I'm still in the planning stages of the mod that would use this. Knowing whether or not I can make items decay would change the core mechanics significantly enough to where I'd pursue a different path when coding the core mod classes. I'll post a reply if I get to it before you have a chance.

 

Link to comment
Share on other sites

Okay, so to my knowledge there is no way to make the items *actually* update in the chests/dispensers/furnaces/etc without modifying core classes, but there is a way to keep this fact hidden from the player, which can be accomplished by hijacking the getIconIndex method. When the GUI is launched for the inventory, render calls are made to getIconIndex(ItemStack stack, int pass) if you set requiresAdditionalRenderPasses() to return true.

 

Here is a generalized version.

public class Decay extends Item{
...
private long currentTime;
private final static int tickDelay = 5;
...
public boolean requiresMultipleRenderPasses(){
return true;
}
...
public boolean isDecayed(ItemStack stack){
//TODO: Add your final decay check here
if(stack.stackTagCompound!=null)
	return stack.stackTagCompound.getInteger("decaySum")>200;
return false;
}
...
public int getIconIndex(ItemStack stack, int pass){
    	if(Minecraft.getMinecraft().theWorld.getWorldTime()-this.currentTime>Decay.tickDelay){
    		this.currentTime = Minecraft.getMinecraft().theWorld.getWorldTime();
	//TODO: Add code here to handle item decay updates/increments/damage, etc
	if(isDecayed(stack))
		return ModClass.otherStaticFinalItem.getIconFromDamageForRenderPass(stack.getItemDamage(), pass);
		//Special item icon, if needed, until onUpdate() can swap out inventory
    	}
//Normal item icon
    	return getIconFromDamageForRenderPass(stack.getItemDamage(), pass);
    }
}

 

As it turns out, getTotalWorldTime() does not change with normal time add/set commands, but getWorldTime() does.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

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