Jump to content

[Solved][1.8.8] Mathematical operation in item's onUsage() method


Recommended Posts

Posted

Hi everyone !

 

First of all I'd like to apologize about my English, I'm French and I don't speak English fluently yet.

Also, I'd like to add that I began coding with Minecraft Forge 4 days ago, although I have a good experience with Java.

 

My problem lies in the onUsage() method of a custom item I made, a simple dosimeter that mesure the irradiation dose that the player get by being exposed to radiation sources.

In that method, I use the item NBTTagCompound to store the radiation measure made by another item (a geiger counter) and the irradiation related. I perform (successfuly) the following calculation : irradiation += radiationMeasure. In the code, it looks like this :

 

 

nbtDosimeter.setDouble("irradiation", nbtDosimeter.getDouble("irradiation") + nbtDosimeter.getDouble("radiationMeasure") / 72000);

 

 

Even if the calculation is correctly executed and the mathematical behavior matches my expectations, I have a sort of "bug" or strange behavior in the item. Indeed, my item moves continuously as if it was right-clicked on a block every tick. To show you, I recorded a short video that I posted on my Youtube Channel :

https://www.youtube.com/watch?v=CsxCDbUtz7U

 

To identify the problem, I tried to store each NBTTagCompound double value in an independant standard Java double variable, and then performed the calculation as follows :

 

 

nbtDosimeter.setDouble("irradiation", a + b);

 

 

I also tried to perform the operation in a third double value, and to set the "irradiation" value from that variable. As you can guess, I didn't change anything. Concerned by this very weird problem, I tried to perform a simple c = a + b operation in the method without assigning any NBTTagCompound with the result, just as I would do in a simple Java console program, and then of course the movement stopped (as the item NBTTagCompound values weren't modified).

 

Here is my full ItemDosimeter.java file :

 

 

package stericraft.nuclei.items;

import java.util.List;

import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import stericraft.nuclei.init.NucleiItems;



/*
* Cet item mesure l'exposition à la radiation en fonction
* de ce que mesure le compteur geiger.
* Il faut donc un compteur geiger dans l'inventaire pour
* que le dosimètre fonctionne.
* La radiation réellement reçue est directement gérée par
* le joueur.
*/

public class ItemDosimeter extends Item {

public ItemDosimeter() {
	super();
	this.setMaxStackSize(1); // Un seul dosimètre à la fois
}

@Override
public void onUpdate(ItemStack stack, World worldIn, Entity entityIn, int itemSlot, boolean isSelected) {
	if (!stack.hasTagCompound()) {
		stack.setTagCompound(new NBTTagCompound()); // On créé la structure de donné de l'item

		stack.getTagCompound().setDouble("irradiation", 0.0); // On ajoute une variable d'irradiation
		stack.getTagCompound().setDouble("radiationMeasure", 0.15); // Une variable de mesure de radiation
		stack.getTagCompound().setInteger("pastTime", 0); // Une mesure du temps passé
	}

	NBTTagCompound nbtDosimeter = stack.getTagCompound(); // On récupère la structure de donnée de l'item

	// Mesure dosimétrique de la radioactivité
	//radiationMeasure = geiger.getMeasure(); // A TERMINE

	// On ajoute la dose reçue en 1 tick (1/3600 de µS/h, / 20 ticks)
	//double a = nbtDosimeter.getDouble("irradiation");
	//double b = nbtDosimeter.getDouble("radiationMeasure");
	//double c = a + b;
	//nbtDosimeter.setDouble("irradiation", c);

	nbtDosimeter.setDouble("irradiation", nbtDosimeter.getDouble("irradiation") + nbtDosimeter.getDouble("radiationMeasure") / 72000);

	if (nbtDosimeter.getDouble("irradiation") >= 100000) { // En cas d'irradiation supérieure à 100 milliSievert, alarme
		if (entityIn.ticksExisted - nbtDosimeter.getInteger("pastTime") >= 40) {
			worldIn.playSoundAtEntity(entityIn, "nuc:dosimeter_alarm", 1.0F, 1.0F);
			nbtDosimeter.setInteger("pastTime", entityIn.ticksExisted);
		}
	}
}

// Cliquer droit avec cet item réinitialise la mesure
/*@Override
public boolean onItemUse(ItemStack stack, EntityPlayer playerIn, World worldIn, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ)
    {
	stack.getTagCompound().setDouble("irradiation", 0.0);

        return false;
    }*/

@Override
@SideOnly(Side.CLIENT) // Valable uniquement côté client
    public void addInformation(ItemStack stack, EntityPlayer playerIn, List<String> tooltip, boolean advanced)
    {	
	NBTTagCompound nbtDosimeter = stack.getTagCompound(); // On récupère la structure de donnée de l'item

	if (nbtDosimeter.getDouble("irradiation") < 1)
		tooltip.add((double)(int)(nbtDosimeter.getDouble("irradiation") * 100000) / 100 + " nS"); // En nS
	else if (nbtDosimeter.getDouble("irradiation") < 1000)
		tooltip.add((double)(int)(nbtDosimeter.getDouble("irradiation") * 100) / 100 + " uS"); // En µS
	else if (nbtDosimeter.getDouble("irradiation") < 1000000)
		tooltip.add((double)(int)(nbtDosimeter.getDouble("irradiation") / 10) / 100 + " mS"); // En mS
	else
		tooltip.add((double)(int)(nbtDosimeter.getDouble("irradiation") / 10000) / 100 + " S"); // En S

	if (!playerIn.inventory.hasItem(NucleiItems.item_geiger_counter)) {
		tooltip.add("Geiger Counter needed to measure");
	}
    }
}

 

 

Does anyone of you have an idea why that happens ? And possibly a solution ?

 

Thank you for reading, and sorry if I missed a post in the past that talked about this problem already. As I said my English isn't perfect yet and maybe I didn't search for the right thing before to post.

 

SteriCraft

Posted

The item "moves" every tick because when you modify the stackTagCompound Minecraft sees it as being a new item stack, not the same item stack.

 

I believe there is a method in the Item class called

shouldRefresh

or similar.  You'll need to override that to return false.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Thank you for you quick and efficient answer !

I searched for a method like the one you suggested and found shouldCauseReequipAnimation(). I overrided it with return false; and now it works !

 

For the people who would have the same problem, there is the full overrided method :

 

 

@Override
public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged)
{
    return false;
}

 

Posted

That's the one. I haven't migrated to 1.8 yet, but I have heard about the method.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted

Btw, you usually don't want to override it to always return false unless you NEVER want the re-equip animation; but what about when the player legitimately changes items, whether by changing their current slot or having the item in their current slot change?

 

Something along these lines is usually decent, but it depends on how you define what does and does not count as the same item for your Item:

return slotChanged || !ItemStack.areItemsEqual(oldStack, newStack);

Posted

 

this post give me hope may i could fix that anoying behaveours in mi fire guns mod and tools

width=100 height=100http://s9.postimg.org/s8zoopo7v/its_something.jpg[/img]  so thanks for that

 

 

long ago i make i lot of post trying to find a way to disable this betwin other animations

efects that com by default whith the item class

 

this one actualy cancel the molest animation of the item going down and up again every time you change something in the nbtTag

 

 

can you tell me if its posible to also cancel the animation of the item going down and up hapening when the item enter in use

 

coz this piece of code

@Override
public ItemStack onItemRightClick(ItemStack pistola, World worldIn, EntityPlayer playerIn) {

                //this causes the animation again
	playerIn.setItemInUse(pistola, this.getMaxItemUseDuration(pistola));

	return pistola;
}

 

 

and the other i dont find how to disable is the bow thigthen animation the first view part

https://drive.google.com/file/d/0B8sU_NyZQBd7NnNBRmtZbThkbHc/view?usp=sharing

 

@Override
public EnumAction getItemUseAction(ItemStack pistola) {
	return EnumAction.BOW;
}

 

but keeping this part

https://drive.google.com/file/d/0B8sU_NyZQBd7RENUN21Lam1TNnM/view?usp=sharing

 

i set EnumAction  to BOW soo the player raise his arms and aim the pistol gun in the thirth view

but this also play the bow animation in first view and is anoying and incongruend whith a pistol behaveour

 

is posible to disable also this first view animation ?? 

and keeping the rise arms animation in thirth view

 

Posted

well

when the player legitimately changes items,

in mi guns long ago i add serial number system

soo when one of mi guns  initialize for first time it add a 8 int  number soo i could make

 

// ######################################################################################3

@Override
public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged)
{


	int oldStackSN = util.getInttag(oldStack, "numerodeserie");
	int newStackSN = util.getInttag(newStack, "numerodeserie");

	if (oldStackSN == newStackSN)
	{
		return false;
	}


    return true;
}
// ######################################################################################3

 

and its works

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.

×
×
  • Create New...

Important Information

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