Tryhard Posted September 18, 2019 Share Posted September 18, 2019 The idea is to summon a lightningbolt where the player is looking, so far i've got this: package mod.joanalbert.testmod.item.items; import mod.joanalbert.testmod.ModSetup; import net.minecraft.client.Minecraft; import net.minecraft.client.MinecraftGame; import net.minecraft.client.renderer.entity.EntityRendererManager; import net.minecraft.client.renderer.entity.LightningBoltRenderer; import net.minecraft.entity.effect.LightningBoltEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Rarity; import net.minecraft.network.play.client.CPlayerTryUseItemPacket; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; import net.minecraftforge.client.event.DrawBlockHighlightEvent; import net.minecraftforge.client.event.InputEvent; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.EntityJoinWorldEvent; import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import java.util.Iterator; public class TestSword extends Item { public static final String REGISTRY_NAME = "testmod:test_sword"; public static final String DISPLAY_NAME = "Test Sword"; private World world; private PlayerEntity player; public BlockPos lookingAt; public TestSword(){ super(new Item.Properties().group(ModSetup.itemGroup).maxStackSize(3).rarity(Rarity.EPIC)); this.setRegistryName(this.REGISTRY_NAME); MinecraftForge.EVENT_BUS.register(this); } @SubscribeEvent public void lightning(InputEvent.MouseInputEvent event){ if(event.getButton() != 1 || this.lookingAt == null) return; System.out.println(this.lookingAt.getX()+" "+this.lookingAt.getY()+" "+this.lookingAt.getZ()); LightningBoltEntity l = new LightningBoltEntity(this.world, this.lookingAt.getX(), this.lookingAt.getY(), this.lookingAt.getZ(), false); this.world.addEntity(l); } @SubscribeEvent public void updatePos(DrawBlockHighlightEvent event){ RayTraceResult result = event.getTarget(); this.lookingAt = new BlockPos(result.getHitVec().getX(), result.getHitVec().getY(), result.getHitVec().getZ()); } @SubscribeEvent public void test(EntityJoinWorldEvent event){ if(event.getEntity() instanceof PlayerEntity){ this.world = event.getWorld(); this.player = (PlayerEntity) event.getEntity(); } } } I don't really know what i'm doing, im new to this. This isn't quite working... what am i missing and what could i be doing better? Quote Link to comment Share on other sites More sharing options...
Tryhard Posted September 19, 2019 Author Share Posted September 19, 2019 woow so useful this forum Quote Link to comment Share on other sites More sharing options...
cinsiian Posted September 19, 2019 Share Posted September 19, 2019 22 hours ago, Tryhard said: private World world; private PlayerEntity player; I dont think this is the correct way to save values, just use the player and the world(player.getEntityWorld) provided by the event. 22 hours ago, Tryhard said: InputEvent.MouseInputEvent event I suggest to use a PlayerInteractEvent instead of InputEvent, you can get the player/world from there. Quote Link to comment Share on other sites More sharing options...
Animefan8888 Posted September 19, 2019 Share Posted September 19, 2019 On 9/18/2019 at 10:34 AM, Tryhard said: private World world; private PlayerEntity player; public BlockPos lookingAt; No dont do this. On 9/18/2019 at 10:34 AM, Tryhard said: @SubscribeEvent public void lightning(InputEvent.MouseInputEvent event){ if(event.getButton() != 1 || this.lookingAt == null) return; System.out.println(this.lookingAt.getX()+" "+this.lookingAt.getY()+" "+this.lookingAt.getZ()); LightningBoltEntity l = new LightningBoltEntity(this.world, this.lookingAt.getX(), this.lookingAt.getY(), this.lookingAt.getZ(), false); this.world.addEntity(l); } @SubscribeEvent public void updatePos(DrawBlockHighlightEvent event){ RayTraceResult result = event.getTarget(); this.lookingAt = new BlockPos(result.getHitVec().getX(), result.getHitVec().getY(), result.getHitVec().getZ()); } @SubscribeEvent public void test(EntityJoinWorldEvent event){ if(event.getEntity() instanceof PlayerEntity){ this.world = event.getWorld(); this.player = (PlayerEntity) event.getEntity(); } } Or any of this. Instead use onItemRightClick perform your own RayTracing then spawn the LightningBolt using ServerWorld#addLightningBolt Quote VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator. Link to comment Share on other sites More sharing options...
larsgerrits Posted September 19, 2019 Share Posted September 19, 2019 (edited) On 9/18/2019 at 7:34 PM, Tryhard said: private World world; private PlayerEntity player; public BlockPos lookingAt; You can't store variables like this in your Item. They are singletons and the data would be shared between all items of that type. Assuming you want to spawn a lightning bolt when the user uses your item (i.e. right clicks the item), override the Item#onItemRightClick method. You don't need any of the events. 5 hours ago, Tryhard said: woow so useful this forum And definitely don't do this. We are spending our free time here (which we don't have a lot of) to help people. Saying this makes you sound like an entitled piece of ****. Edited September 19, 2019 by larsgerrits Quote Don't PM me with questions. They will be ignored! Make a thread on the appropriate board for support. 1.12 -> 1.13 primer by williewillus. 1.7.10 and older versions of Minecraft are no longer supported due to it's age! Update to the latest version for support. http://www.howoldisminecraft1710.today/ Link to comment Share on other sites More sharing options...
Tryhard Posted September 19, 2019 Author Share Posted September 19, 2019 Thank you all for your suggestions/corrections people. How Would i get a ServerWorld object? (to do this: ServerWorld#addLightningBolt). What are the differences between World and ServerWorld?? I'll get rid of those events and override #onItemRightClick. And i apologize for that thing i wrote up there, but after almost two days of not getting any response, i thought this post would end up just being ignored. Anyway, thanks alot for your help. I will update on the changes i make. Btw my World instance doesn't have the addWeatherEffect, is that because i shouldn't be using "World" at all? I'm currently using forge 1.14.4. Quote Link to comment Share on other sites More sharing options...
Tryhard Posted September 19, 2019 Author Share Posted September 19, 2019 (edited) 4 hours ago, Animefan8888 said: Perform your own RayTracing Can you go a bit more in depth on the RayTracing thing? i'm completely new to this concept, what is it used for? I'm assuming it is to get the location the player is looking at, but, how should i handle it? Edited September 19, 2019 by Tryhard Quote Link to comment Share on other sites More sharing options...
Tryhard Posted September 19, 2019 Author Share Posted September 19, 2019 I saw someone use this code for RayTracing the position the player is looking at: public RayTraceResult rayTrace(EntityPlayer playerIn, double blockReachDistance, float partialTicks){ Vec3d vec3d = playerIn.getPositionEyes(partialTicks); Vec3d vec3d1 = playerIn.getLook(partialTicks); Vec3d vec3d2 = vec3d.addVector(vec3d1.x * blockReachDistance, vec3d1.y * blockReachDistance, vec3d1.z * blockReachDistance); return playerIn.world.rayTraceBlocks(vec3d, vec3d2, false, false, true); } I don't want to just copy it, i want to understand it. Can someone pls explain what is this method really doing? Also, i'm having trouble spawning the LightningBoltEntity, because "World", for some reason, doesn't have any #addLightningBolt method Quote Link to comment Share on other sites More sharing options...
Animefan8888 Posted September 20, 2019 Share Posted September 20, 2019 2 hours ago, Tryhard said: What are the differences between World and ServerWorld?? ServerWorld only exists on the server and it represents a world on the server. 2 hours ago, Tryhard said: How Would i get a ServerWorld object? Cast world to ServerWorld. 35 minutes ago, Tryhard said: Can someone pls explain what is this method really doing? Look up what Ray Tracing does. Quote VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator. Link to comment Share on other sites More sharing options...
Tryhard Posted September 20, 2019 Author Share Posted September 20, 2019 Okey @Override public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn){ ServerWorld world = (ServerWorld) worldIn; world.addLightningBolt(new LightningBoltEntity(world, playerIn.posX, playerIn.posY, playerIn.posZ, false)); return new ActionResult<>(ActionResultType.SUCCESS, playerIn.getHeldItem(handIn)); } It won't allow me to do cast it like this. It crashes. The crash report say the following: java.lang.ClassCastException: net.minecraft.client.world.ClientWorld cannot be cast to net.minecraft.world.server.ServerWorld Quote Link to comment Share on other sites More sharing options...
Animefan8888 Posted September 20, 2019 Share Posted September 20, 2019 20 minutes ago, Tryhard said: java.lang.ClassCastException: net.minecraft.client.world.ClientWorld cannot be cast to net.minecraft.world.server.ServerWorld That's a Java error if you don't know how to solve that look it up elsewhere we are not here to teach basic Java concepts. Quote VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator. Link to comment Share on other sites More sharing options...
Tryhard Posted September 20, 2019 Author Share Posted September 20, 2019 (edited) 12 hours ago, Animefan8888 said: look it up elsewhere we are not here to teach basic Java concepts. wow, talk about: 19 hours ago, larsgerrits said: Sounding like an entitled piece of ****. I know what exceptions are... and i know why i am getting this one. I'm downcasting to a type which "worldIn" isn't an instance of... what i was asking is: how am i supposed to get access to #addLightningBolt then? I've also been researching this on my own of course... but i found nothing too useful, i thought: "hey whats the best place to look for help on this minecraft forge related problem i'm facing? oh, how about the minecraft forge forum Well, i guess it's not, sunce i'm practically been told to *uck off... Edited September 20, 2019 by Tryhard Quote Link to comment Share on other sites More sharing options...
TrazorMC Posted September 20, 2019 Share Posted September 20, 2019 I believe the method you are using is called on the client and the server. You can use worldIn#isRemote to check if you are on the server before casting to ServerWorld. 1 Quote Link to comment Share on other sites More sharing options...
Animefan8888 Posted September 20, 2019 Share Posted September 20, 2019 9 hours ago, Tryhard said: hey whats the best place to look for help on this minecraft forge related problem i'm facing? oh, how about the minecraft forge forum I can't say that 22 hours ago, Tryhard said: java.lang.ClassCastException: net.minecraft.client.world.ClientWorld cannot be cast to net.minecraft.world.server.ServerWorld Is a minecraft forge related problem. You can change those class names to anything else and it would still be the same problem. Also 7 hours ago, diesieben07 said: I wonder if there is an operator in Java to check if something is an instance of some class. Oh right. instanceof. Quote VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator. Link to comment Share on other sites More sharing options...
Tryhard Posted September 21, 2019 Author Share Posted September 21, 2019 ...Yes, thanks alot for instanceof, already knew about it. What i didn't know, however, is that #onItemRightClick runs twice per click (client & server) and only once is the argument "worldIn" a ServerWorld... That doesn't seem like "basic java concepts" to me... more like basic forge concepts (which i'm completely new to) To me, it' didn't make sense to use instanceof without knowing that "little" detail about #onItemRightClick. It makes complete sense now, i have to run the code only when worldIn is a serverworld, otherwise i get a class cast exception. Now it's working tho. Thanks to TrazorMC for actually pointing that out! The only thing left now, is to get the correct BlockPos to spawn the LightningBoltEntity on. It seems i need to use raytracing for that. I've been looking it up but i still don't quite get it. I've seen that on older versions they used PlayerEntity#rayTrace, but that class no longer has that method. Actually as i was writting this, i found this method with a weird name on the Entity class. (does that annotation mean that this method should only run on the client or something like that?) @OnlyIn(Dist.CLIENT) public RayTraceResult func_213324_a(double p_213324_1_, float p_213324_3_, boolean p_213324_4_) { Vec3d vec3d = this.getEyePosition(p_213324_3_); Vec3d vec3d1 = this.getLook(p_213324_3_); Vec3d vec3d2 = vec3d.add(vec3d1.x * p_213324_1_, vec3d1.y * p_213324_1_, vec3d1.z * p_213324_1_); return this.world.rayTraceBlocks(new RayTraceContext(vec3d, vec3d2, RayTraceContext.BlockMode.OUTLINE, p_213324_4_ ? RayTraceContext.FluidMode.ANY : RayTraceContext.FluidMode.NONE, this)); } It is working now. I still don't know what RayTraceContext is for, and what its enumerations mean, or what the arguments of this function do (why those names tho). But it seems it is all done now. The class of my item looks like this now. public class TestSword extends Item { public static final String REGISTRY_NAME = "testmod:test_sword"; public static final String DISPLAY_NAME = "Test Sword"; public TestSword(){ super(new Item.Properties().group(ModSetup.itemGroup).maxStackSize(3).rarity(Rarity.EPIC)); this.setRegistryName(this.REGISTRY_NAME); MinecraftForge.EVENT_BUS.register(this); } @Override public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn){ //test the side if(!(worldIn instanceof ServerWorld)) return new ActionResult<>(ActionResultType.PASS, playerIn.getHeldItem(handIn)); //cast World to ServerWorld ServerWorld world = (ServerWorld) worldIn; //get the correct position RayTraceResult rts = playerIn.func_213324_a(100, 1, false); BlockPos pos = new BlockPos(rts.getHitVec().getX(), rts.getHitVec().getY(), rts.getHitVec().getZ()); System.out.println(pos.getX()+" "+pos.getY()+" "+pos.getZ()); //create & spawn entity LightningBoltEntity l = new LightningBoltEntity(world, pos.getX(), pos.getY(), pos.getZ(), false); world.addLightningBolt(l); return new ActionResult<>(ActionResultType.SUCCESS, playerIn.getHeldItem(handIn)); } } I'm totally sure this can be improved. I'd love to hear what the seniors have to say. Quote Link to comment Share on other sites More sharing options...
Animefan8888 Posted September 21, 2019 Share Posted September 21, 2019 28 minutes ago, Tryhard said: RayTraceResult rts = playerIn.func_213324_a(100, 1, false); This will crash the dedicated server, since the function you are calling is marked @SideOnly(Side.CLIENT) What you have to do is copy what it does inside the method. 29 minutes ago, Tryhard said: That doesn't seem like "basic java concepts" to me more like basic forge concepts Yes the fact that it runs twice would be a basic forge concept, but that crash is something you could have solved yourself then came to the conclusion that it runs twice... Also it would be basic Java concept to check if something is an instanceof "ClassName" before you cast to it. You don't just willy-nilly cast one thing to another. 32 minutes ago, Tryhard said: RayTraceContext A RayTraceContext contains all the information to perform a ray trace. It knows if you want it to consider fluids, along what vector do I ray trace for(vec3d->vec3d2). Quote VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect. Forge and vanilla BlockState generator. Link to comment Share on other sites More sharing options...
Recommended Posts
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.