The Meaning of Life, the Universe, and Everything.
Join Date:
8/16/2011
Posts:
50
Minecraft:
dev909
Member Details
Just wondering how you can code an "collect one of each item type" trigger, or "upon right click use" trigger, or anything thats not onCrafted or onSmelted like mentioned in the http://www.minecraft..._an_Achievement tutorial.
I'm not entirely sure what you mean by a 'collect one of each item type' trigger, but as for upon use, Item.java has a method called onItemRightClick:
public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) {}
However, there's no Forge or ML hook for this afaik; for each item you want to check for, you would need to implement this method in their item class. If you wanted to implement it for all items, it would involve editing base classes.
The Meaning of Life, the Universe, and Everything.
Join Date:
8/16/2011
Posts:
50
Minecraft:
dev909
Member Details
I meant subTypes...sorry I should have mentioned that haha. I know the onItemRightClick (or onEaten) methods would be used, but how exactly would you register it with stats? For example lets keep it simple at the moment: You receive an item ( lets say an apple), and when you 'eat' it, you would get an achievement for it. How do you utilize onItemRightClick to work that?
Let's use the example achievement they made in the link you provided.
In the Apple's onEaten method, you would use player.addStat(TimeAchieve, 1). It's as simple as adding the stat in the onEaten or onItemRightClick method.
Like this:
public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) {
par3EntityPlayer.addStat(MyModClass.myAchievement, 1);
}
Note that the achievement in MyModClass would need to be static so that you can access it outside of your mod class properly.
edit: if this doesn't make sense would you mind posting what code you have now? It's difficult to explain without something to explain about.
The Meaning of Life, the Universe, and Everything.
Join Date:
8/16/2011
Posts:
50
Minecraft:
dev909
Member Details
Ok I can follow it. Just tested and it works. So that's our basic example. So how would you be able to code it so that when you onRightClick with each subType of the class, the achievement unlocks.
Here's my constructor and item declarations, along with the .addStat within the onEaten method.
public Berry(int par1, int par2, float par3, boolean par4) {
super(par1, par2, par3, par4);
this.setCreativeTab(cTabs.tabIngredients);
maxStackSize = 64;
}
public static Item blueBerry = (new Berry(baseModDS.blueBerryID, 0, 0, false)).setUnlocalizedName("Dev's Starved:Blueberry");
public static Item strawBerry = (new Berry(baseModDS.strawBerryID, 0, 0, false)).setUnlocalizedName("Dev's Starved:Strawberry");
public static Item blackBerry = (new Berry(baseModDS.blackBerryID, 0, 0, false)).setUnlocalizedName("Dev's Starved:Blackberry");
public static Item raspBerry = (new Berry(baseModDS.raspBerryID, 0, 0, false)).setUnlocalizedName("Dev's Starved:Raspberry");
public static Item cranBerry = (new Berry(baseModDS.cranBerryID, 0, 0, false)).setUnlocalizedName("Dev's Starved:Cranberry");
public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
{
--par1ItemStack.stackSize;
par3EntityPlayer.getFoodStats().addStats(this);
par3EntityPlayer.addStat(modDSAch.berryAch, 1);
par2World.playSoundAtEntity(par3EntityPlayer, "random.burp", 0.5F, par2World.rand.nextFloat() * 0.1F + 0.9F);
this.onFoodEaten(par1ItemStack, par2World, par3EntityPlayer);
return par1ItemStack;
}
The first parameter is an ItemStack. You can use this to get the item ID of the item that's being eaten:
int i = par1ItemStack.getItem().itemID - 256;
Note that we need to subtract 256 to get the ID you coded in for each berry, as the constructor for Item automatically adds 256 to the item ID you provide.
Then, you can use an if-then-else to check what item ID has been eaten:
Now, I'm not sure what's happening at this point. Are you assigning the achievement after every berry has been eaten at least once, or a different achievement for each berry type? If it's a different achievement for each berry type, just throw in the addStat in each if. However, if it's an achievement that requires you to eat at least one of each berry type, my advice would be to create a boolean for each berry type in your mod class:
// this is in your main mod class
public static boolean eatenBlueberry = false;
public static boolean eatenStrawberry = false;
public static boolean eatenBlackberry = false;
public static boolean eatenRaspberry = false;
public static boolean eatenCranberry = false;
And then, in each of the else-if statements from before, set the corresponding boolean to true:
public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
{
--par1ItemStack.stackSize;
par3EntityPlayer.getFoodStats().addStats(this);
if (berryAchCheck(par1ItemStack)) {
par3EntityPlayer.addStat(modDSAch.berryAch, 1);
}
par2World.playSoundAtEntity(par3EntityPlayer, "random.burp", 0.5F, par2World.rand.nextFloat() * 0.1F + 0.9F);
this.onFoodEaten(par1ItemStack, par2World, par3EntityPlayer);
return par1ItemStack;
}
protected boolean berryAchCheck(ItemStack par1ItemStack)
{
int i = par1ItemStack.getItem().itemID;
if (i == baseModDS.blueBerryID){
blue = true;
}
else if(i == baseModDS.strawBerryID){
straw = true;
}
else if(i == baseModDS.blackBerryID){
black = true;
}
else if(i == baseModDS.raspBerryID){
rasp = true;
}
else if(i == baseModDS.cranBerryID){
cran = true;
}
if (blue && straw && black && rasp && cran){
return true;
}
return false;
}
*Edit: I added the booleans within the class, not my basemod class.
I'd put them in the basemod class and make them static if I were you; if they're not static already, then each berry will have their own version of the variables, and only the corresponding boolean would be made true (for example, the Blueberry would change its blue boolean to true when eaten, but would never change the rasp boolean to true, because the ID of the item eaten would never equal the raspberry ID. It's the same for each of the other berries; they would change their own booleans to true, but would never change the others to true).
You're using par1ItemStack.getItem().itemID, but it should be par1ItemStack.getItem().itemID - 256. Constructor for Items adds 256 to the item ID automatically, when comparing to your hardcoded IDs you need to subtract 256 again.
The Meaning of Life, the Universe, and Everything.
Join Date:
8/16/2011
Posts:
50
Minecraft:
dev909
Member Details
Ahh right, I forgot I removed that. It works now! Kudos to you good gentleman :D.
As an extra bonus though, do you know why the achievement page for mods is so glitchy? First achievement has a full white background, while if you scroll to the y borders, the entire gui goes white.
Ahh right, I forgot I removed that. It works now! Kudos to you good gentleman .
As an extra bonus though, do you know why the achievement page for mods is so glitchy? First achievement has a full white background, while if you scroll to the y borders, the entire gui goes white.
I honestly have no idea. I don't work with achievements much, so I've never really noticed.
If it still helps there is a method in Item which is triggered when the item is picked up, might help a bit. It is called like onItemPickup or something (on phone so I can't check)
If it still helps there is a method in Item which is triggered when the item is picked up, might help a bit. It is called like onItemPickup or something (on phone so I can't check)
That can be helpful for other achievements I got planned. This one in particular is when the player uses the item. Thanks though!
However, there's no Forge or ML hook for this afaik; for each item you want to check for, you would need to implement this method in their item class. If you wanted to implement it for all items, it would involve editing base classes.
In the Apple's onEaten method, you would use player.addStat(TimeAchieve, 1). It's as simple as adding the stat in the onEaten or onItemRightClick method.
Like this:
Note that the achievement in MyModClass would need to be static so that you can access it outside of your mod class properly.
edit: if this doesn't make sense would you mind posting what code you have now? It's difficult to explain without something to explain about.
Here's my constructor and item declarations, along with the .addStat within the onEaten method.
You currently have this code for onEaten.
The first parameter is an ItemStack. You can use this to get the item ID of the item that's being eaten:
Note that we need to subtract 256 to get the ID you coded in for each berry, as the constructor for Item automatically adds 256 to the item ID you provide.
Then, you can use an if-then-else to check what item ID has been eaten:
Now, I'm not sure what's happening at this point. Are you assigning the achievement after every berry has been eaten at least once, or a different achievement for each berry type? If it's a different achievement for each berry type, just throw in the addStat in each if. However, if it's an achievement that requires you to eat at least one of each berry type, my advice would be to create a boolean for each berry type in your mod class:
And then, in each of the else-if statements from before, set the corresponding boolean to true:
And finally, add a check at the end of onEaten to determine that all the berries have been eaten, and add the stat if all the booleans are true.
*Edit: I added the booleans within the class, not my basemod class.
I'd put them in the basemod class and make them static if I were you; if they're not static already, then each berry will have their own version of the variables, and only the corresponding boolean would be made true (for example, the Blueberry would change its blue boolean to true when eaten, but would never change the rasp boolean to true, because the ID of the item eaten would never equal the raspberry ID. It's the same for each of the other berries; they would change their own booleans to true, but would never change the others to true).
As an extra bonus though, do you know why the achievement page for mods is so glitchy? First achievement has a full white background, while if you scroll to the y borders, the entire gui goes white.
I honestly have no idea. I don't work with achievements much, so I've never really noticed.
Anyways, glad I could help!
Art by me: MrPancakeWolfie@DeviantArt
That can be helpful for other achievements I got planned. This one in particular is when the player uses the item. Thanks though!