Amazon Ad

Sunday, February 12, 2017

Bonus Material: Raytrace and onItemRightClick event

Hello, my name is Alex and I am going to show you how to create a mod for minecraft forge 1.11.2. There's not a lot of tutorials on 1.11 so I am creating one for those that want to get started.

WARNING: IF YOU DO NOT KNOW BASIC JAVA, THIS MAY NOT BE RIGHT FOR YOU!!!

I'm gonna show you some bonus material for your minecraft mod. It was asked that I cover item properties, such as a specific ability when you right click with the item in your hand. Let's get started, shall we?

Let's start by creating an item that spawns lightning right where the player is looking. Create the texture for it first. I'm gonna use this texture:


You can use the texture too, you can download it from here.

Let's create an item and a class for this item.

1
public static Item lightningSpawner;

initialize it with our new ItemLightningSpawner class that we will create momentarily. Give it the parameters of name, and creative tab. But this time we are gonna give it a third parameter of maxStackSize, we will make it NOT stack. This is done by putting 1 as our third parameter.

Let's create the class and it's constructor just like our last item, extending to ModItem.

1
2
3
4
5
public class ItemLightningSpawner extends ModItem {
 public ItemLightningSpawner(String name, CreativeTabs tab, int size) {
  super(name, tab, size);
 }
}

Now we need to override the super's method onItemRightClick. This is one of the super methods inherited from the Item class that is activated when you hold an item in your hand and right click with it. There is this and onItemUse which the difference between the two is that the latter is only called when the cursor is on a block and you right click. We need to override the former and tell it to get the raytrace of the cursor, get the block position that it is on, and then spawn a lightning bolt right where it is.

1
2
3
@Override
public ActionResult<ItemStack> onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) {
}

Let's start by testing if the side is a server or not by calling world.isRemote. This just specifies whether it is a client or not.

1
2
if(!worldIn.isRemote){
}

So we are testing if the world is on the client side or the server side because we want to spawn the lightning bolt as an entity in the world and we want it to show up for both the client and the server. Within this we need to create an object that stores the raytrace information of the player.

1
RayTraceResult pos = playerIn.rayTrace(100, 20);

The raytrace is the current position of the cursor in the world. It stores information like what block the player is looking at, what direction in the world the player is facing, what kind of block the player is looking at, etc. What we want is the block position of the cursor. We are setting the first value to 100 so that it gets the block position within 100 blocks. I don't know what the second position is but I believe it's the timespan the vector looks back in and whatever blockpos you were looking at during that time. So this example does 20 ticks, so whatever block pos you were looking at 20 ticks ago, it gets that information. I could be wrong though, so please correct me if I am wrong.

Next, we need to get the x, y, and z coordinates of the raytrace block position.

1
2
3
double x = pos.getBlockPos().getX();
double y = pos.getBlockPos().getY();
double z = pos.getBlockPos().getZ();

This does exactly what we want. It gets the x, y, and z coordinates of the current look vector of the player. Next we need to add the weather effect, and return the ActionResult as a success.


1
worldIn.addWeatherEffect(new EntityLightningBolt(worldIn, x, y, z, true));

This line of code just spawns in a new weather effect as an entity in the world. We create a new instance of EntityLightningBolt and we give it the parameters of world, x, y, z, true. It needs the world and the position it's spawning in. The true parameter, I honestly don't know what it does, but I'll look into it and update when I find out.


1
return new ActionResult(EnumActionResult.SUCCESS, new ItemStack(this));

This returns a successful action result event. I don't know much about it except that it is necessary. We pass in our class as the item for the item stack.

We need to complete the check we did earlier but including an else statement to our if.


1
2
3
else{
    return new ActionResult(EnumActionResult.FAIL, new ItemStack(this));
}

This ensures that whether the world is on client side, it doesn't fire for only the player, but for the entire server world.

Now we need models. Create the models for the item and texture and fire up the game. Get the item out of the creative tab and right click with it in your hand. Play with the lightning. It's fun!

6 comments:

  1. Replies
    1. I definitely will. I'm trying to work on the next part but I am also tied with a project on the side so possibly by mid-March? :)

      Delete
  2. Getting a method not found exception: java.lang.NoSuchMethodError: net.minecraft.entity.player.EntityPlayer.func_174822_a(DF)Lnet/minecraft/util/math/RayTraceResult

    Full stack trace:
    [16:36:18] [Server thread/FATAL]: Error executing task
    java.util.concurrent.ExecutionException: java.lang.NoSuchMethodError: net.minecraft.entity.player.EntityPlayer.func_174822_a(DF)Lnet/minecraft/util/math/RayTraceResult;
    at java.util.concurrent.FutureTask.report(Unknown Source) ~[?:1.8.0_111]
    at java.util.concurrent.FutureTask.get(Unknown Source) ~[?:1.8.0_111]
    at net.minecraft.util.Util.func_181617_a(SourceFile:47) [h.class:?]
    at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:679) [MinecraftServer.class:?]
    at net.minecraft.server.dedicated.DedicatedServer.func_71190_q(DedicatedServer.java:384) [lh.class:?]
    at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:624) [MinecraftServer.class:?]
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:482) [MinecraftServer.class:?]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_111]
    Caused by: java.lang.NoSuchMethodError: net.minecraft.entity.player.EntityPlayer.func_174822_a(DF)Lnet/minecraft/util/math/RayTraceResult;
    at me.dougclarknc.minecraftmods.minerseye.item.LightningRod.func_77659_a(LightningRod.java:22) ~[LightningRod.class:?]
    at net.minecraft.item.ItemStack.func_77957_a(ItemStack.java:196) ~[afj.class:?]
    at net.minecraft.server.management.PlayerInteractionManager.func_187250_a(PlayerInteractionManager.java:359) ~[lz.class:?]
    at net.minecraft.network.NetHandlerPlayServer.func_147346_a(NetHandlerPlayServer.java:709) ~[mi.class:?]
    at net.minecraft.network.play.client.CPacketPlayerTryUseItem.func_148833_a(SourceFile:32) ~[jn.class:?]
    at net.minecraft.network.play.client.CPacketPlayerTryUseItem.func_148833_a(SourceFile:9) ~[jn.class:?]
    at net.minecraft.network.PacketThreadUtil$1.run(SourceFile:13) ~[fo$1.class:?]
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:1.8.0_111]
    at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:1.8.0_111]
    at net.minecraft.util.Util.func_181617_a(SourceFile:46) ~[h.class:?]
    ... 5 more

    ReplyDelete
  3. Hello There. I found your blog using msn. This is an extremely well written article. I will be sure to bookmark it and return to read more of your useful information. Thanks for the post. I’ll certainly comeback.
    Minecraft Servers

    ReplyDelete