I'm sorry for two posts in a day, but something is really troubling me. Here is my code:
package com.AMurloc.item;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
public class ChargeBlade extends ItemCore{
int i = 0;
public ChargeBlade(String name) {
super(name);
}
public ActionResult<ItemStack> onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn, EnumHand hand)
{
if(playerIn.onGround){
playerIn.setVelocity(0, 1, 0);
i = 1;
}
if (i == 1 && playerIn.onGround){
worldIn.createExplosion(playerIn, playerIn.posX, playerIn.posY, playerIn.posZ, 5.0F, false);
i = 0;
}
return new ActionResult(EnumActionResult.PASS, itemStackIn);
}
}
When I right click with the item, it creates the explosion as soon as it shoots me into the air when my objective is to create an explosion when I hit the ground.
All i can think of is that before the player gets the velocity, it sees the player is on the ground already and the "i" variable is being set to 1 too soon. You could have a for loop that iterates like 7 or so times, and replace i == 1 with i == 7, that might not be the most optimized way of doing things though. Also, i would change "i" to something else, in case you want to be consistent with for loop variables.
All code that is in one method happens basically at the same time so your player is still on the ground when you're running your explosion code. Easiest way to do this would probably be creating a separate tick handler for this.
All code that is in one method happens basically at the same time so your player is still on the ground when you're running your explosion code. Easiest way to do this would probably be creating a separate tick handler for this.
Thanks! How would I go about creating this? I'm still very new to the forge API.
Thanks! How would I go about creating this? I'm still very new to the forge API.
Here's the official forge doc on events. I recommend creating a static method with a @SubscribeEvent annotation and marking your class with the @Mod.EventBusSubscriber annotation. Once you've read it and understood everything look here for the full list of forge events. The most fitting event I could find was the playerTickEvent. Inside your handler method you can check if the entity is holding your item and if it is flying, then apply the rest of your actions.
On a side note, you could use item nbt to handle this, but I'm not sure if that would be better since your actions wouldn't work if the item is not being held.
Here's the official forge doc on events. I recommend creating a static method with a @SubscribeEvent annotation and marking your class with the @Mod.EventBusSubscriber annotation. Once you've read it and understood everything look here for the full list of forge events. The most fitting event I could find was the playerTickEvent. Inside your handler method you can check if the entity is holding your item and if it is flying, then apply the rest of your actions.
On a side note, you could use item nbt to handle this, but I'm not sure if that would be better since your actions wouldn't work if the item is not being held.
you could also use the item's Item#onUpdate() method instead of the player tick event since that is fired every tick the item is in the player's inventory (not necessarily selected or in the hotbar even).
you could then just set a flag in the item's nbt when right clicking so you can cancel further processing of the explosion code if the nbt flag is not set.
you could also use the item's Item#onUpdate() method instead of the player tick event since that is fired every tick the item is in the player's inventory (not necessarily selected or in the hotbar even).
you could then just set a flag in the item's nbt when right clicking so you can cancel further processing of the explosion code if the nbt flag is not set.
Again as I said, the problem with nbt and onUpdate() is that it will not function if the item is not held.
You could just swap the two "if" statements around. That way the player is flung into the air and the explosion code won't be happen as soon as you right click, but will the next time the player is on the ground.
You could just swap the two "if" statements around. That way the player is flung into the air and the explosion code won't be happen as soon as you right click, but will the next time the player is on the ground.
Oh right yeah... I forgot it's in the right click method. Yeah you'll need to handle the explosion part with an event handler. There's an event for when an entity or player falls. I suggest that when you right click, you tell the handler class that the player has right clicked your item, and so add the player's UUID to a list. Then, when the fall event fires, check if it's a player that's UUID is in the list, and if it is then create the explosion and remove them from the list.
That's the best I can come up with. It's much more efficient than a tick handler since you're not checking every tick.
it will, though, as Item#onUpdate() is called everytime the item is in a player's inventory...
Ahh now I feel stupid XD I shouldn't be doing helping when I'm tired and haven't been modding for a while...
Well, using the fall event handler will cover situations where the item may leave your inventory after you've right clicked the item. But that's up to the OP if they want to go the extra mile for that little extra functionality. It's be simpler to use the Item#onUpdate checking, buy more efficient to use the event handler.
Ahh now I feel stupid XD I shouldn't be doing helping when I'm tired and haven't been modding for a while...
Well, using the fall event handler will cover situations where the item may leave your inventory after you've right clicked the item. But that's up to the OP if they want to go the extra mile for that little extra functionality. It's be simpler to use the Item#onUpdate checking, buy more efficient to use the event handler.
Ok, I decided to go with the Item#onUpdate check, but my code isn't running when this item is in my inventory, here is my code:
package com.AMurloc.item;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.world.World;
import net.minecraftforge.event.entity.player.EntityItemPickupEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent.PlayerTickEvent;
public class ChargeBlade extends ItemCore{
public ChargeBlade(String name) {
super(name);
}
int i = 0;
public ActionResult<ItemStack> onUpdate (ItemStack itemStackIn, World worldIn, EntityPlayer playerIn, EnumHand hand){
System.out.println("Test");
if(playerIn.onGround){
i = 0;
}else{
i = 1;
}
if (i == 2 && playerIn.onGround){
worldIn.createExplosion(playerIn, playerIn.posX, playerIn.posY, playerIn.posZ, 2.0F, false);
i = 0;
}
return new ActionResult(EnumActionResult.PASS, itemStackIn);
}
public ActionResult<ItemStack> onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn, EnumHand hand){
i = 2;
playerIn.setVelocity(0, 1, 0);
return new ActionResult(EnumActionResult.PASS, itemStackIn);
}
}
I'm sorry for two posts in a day, but something is really troubling me. Here is my code:
When I right click with the item, it creates the explosion as soon as it shoots me into the air when my objective is to create an explosion when I hit the ground.
All i can think of is that before the player gets the velocity, it sees the player is on the ground already and the "i" variable is being set to 1 too soon. You could have a for loop that iterates like 7 or so times, and replace i == 1 with i == 7, that might not be the most optimized way of doing things though. Also, i would change "i" to something else, in case you want to be consistent with for loop variables.
All code that is in one method happens basically at the same time so your player is still on the ground when you're running your explosion code. Easiest way to do this would probably be creating a separate tick handler for this.
Thanks! How would I go about creating this? I'm still very new to the forge API.
Here's the official forge doc on events. I recommend creating a static method with a @SubscribeEvent annotation and marking your class with the @Mod.EventBusSubscriber annotation. Once you've read it and understood everything look here for the full list of forge events. The most fitting event I could find was the playerTickEvent. Inside your handler method you can check if the entity is holding your item and if it is flying, then apply the rest of your actions.
On a side note, you could use item nbt to handle this, but I'm not sure if that would be better since your actions wouldn't work if the item is not being held.
Am I wrong to think that this executes every tick? Because I put:
inside of it and I didn't see anything in the console...
you could also use the item's Item#onUpdate() method instead of the player tick event since that is fired every tick the item is in the player's inventory (not necessarily selected or in the hotbar even).
you could then just set a flag in the item's nbt when right clicking so you can cancel further processing of the explosion code if the nbt flag is not set.
Again as I said, the problem with nbt and onUpdate() is that it will not function if the item is not held.
You could just swap the two "if" statements around. That way the player is flung into the air and the explosion code won't be happen as soon as you right click, but will the next time the player is on the ground.
May I ask what you mean by that?
Excuse the terrible formatting, but I'm on mobile.
Basically this. I just swapped the two statements around.
public ActionResult<ItemStack> onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn, EnumHand hand)
{
if (i == 1 && playerIn.onGround){
worldIn.createExplosion(playerIn, playerIn.posX, playerIn.posY, playerIn.posZ, 5.0F, false);
i = 0;
}
if(playerIn.onGround){
playerIn.setVelocity(0, 1, 0);
i = 1;
}
return new ActionResult(EnumActionResult.PASS, itemStackIn);
}
@Bright_Spark
Your isn't working and I have no idea why...
Oh right yeah... I forgot it's in the right click method. Yeah you'll need to handle the explosion part with an event handler. There's an event for when an entity or player falls. I suggest that when you right click, you tell the handler class that the player has right clicked your item, and so add the player's UUID to a list. Then, when the fall event fires, check if it's a player that's UUID is in the list, and if it is then create the explosion and remove them from the list.
That's the best I can come up with. It's much more efficient than a tick handler since you're not checking every tick.
why shouldn't that work?
but yeah as bright_spark suggested storing all players in a list somewhere might be the better approach here.
He literally explained why in that same post...
"it will not function if the item is not held"
it will, though, as Item#onUpdate() is called everytime the item is in a player's inventory...
Ahh now I feel stupid XD I shouldn't be doing helping when I'm tired and haven't been modding for a while...
Well, using the fall event handler will cover situations where the item may leave your inventory after you've right clicked the item. But that's up to the OP if they want to go the extra mile for that little extra functionality. It's be simpler to use the Item#onUpdate checking, buy more efficient to use the event handler.
Ok, I decided to go with the Item#onUpdate check, but my code isn't running when this item is in my inventory, here is my code:
Is the sysout working? Or is the method not being called at all?
Nope, no code in Item#onUpdate is running. But when I right click, it still flings me into the air.