Jump to content

How to spawn lightning with forge 1.14


Tryhard

Recommended Posts

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

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

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 by larsgerrits

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

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.

Link to comment
Share on other sites

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 by Tryhard
Link to comment
Share on other sites

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 :( 

 

dsds.PNG.51687616b93d39128bfe08a62e1a8ddf.PNG

Link to comment
Share on other sites

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.

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

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

 

 

Link to comment
Share on other sites

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.

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

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 by Tryhard
Link to comment
Share on other sites

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.

 

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

...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.

 

 

 

 

Link to comment
Share on other sites

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).

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

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.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hello everyone, I'm making this post to seek help for my modded block, It's a special block called FrozenBlock supposed to take the place of an old block, then after a set amount of ticks, it's supposed to revert its Block State, Entity, data... to the old block like this :  The problem I have is that the system breaks when handling multi blocks (I tried some fix but none of them worked) :  The bug I have identified is that the function "setOldBlockFields" in the item's "setFrozenBlock" function gets called once for the 1st block of multiblock getting frozen (as it should), but gets called a second time BEFORE creating the first FrozenBlock with the data of the 1st block, hence giving the same data to the two FrozenBlock :   Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=head] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@73681674 BlockEntityData : id:"minecraft:bed",x:3,y:-60,z:-6} Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=3, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=2, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} here is the code inside my custom "freeze" item :    @Override     public @NotNull InteractionResult useOn(@NotNull UseOnContext pContext) {         if (!pContext.getLevel().isClientSide() && pContext.getHand() == InteractionHand.MAIN_HAND) {             BlockPos blockPos = pContext.getClickedPos();             BlockPos secondBlockPos = getMultiblockPos(blockPos, pContext.getLevel().getBlockState(blockPos));             if (secondBlockPos != null) {                 createFrozenBlock(pContext, secondBlockPos);             }             createFrozenBlock(pContext, blockPos);             return InteractionResult.SUCCESS;         }         return super.useOn(pContext);     }     public static void createFrozenBlock(UseOnContext pContext, BlockPos blockPos) {         BlockState oldState = pContext.getLevel().getBlockState(blockPos);         BlockEntity oldBlockEntity = oldState.hasBlockEntity() ? pContext.getLevel().getBlockEntity(blockPos) : null;         CompoundTag oldBlockEntityData = oldState.hasBlockEntity() ? oldBlockEntity.serializeNBT() : null;         if (oldBlockEntity != null) {             pContext.getLevel().removeBlockEntity(blockPos);         }         BlockState FrozenBlock = setFrozenBlock(oldState, oldBlockEntity, oldBlockEntityData);         pContext.getLevel().setBlockAndUpdate(blockPos, FrozenBlock);     }     public static BlockState setFrozenBlock(BlockState blockState, @Nullable BlockEntity blockEntity, @Nullable CompoundTag blockEntityData) {         BlockState FrozenBlock = BlockRegister.FROZEN_BLOCK.get().defaultBlockState();         ((FrozenBlock) FrozenBlock.getBlock()).setOldBlockFields(blockState, blockEntity, blockEntityData);         return FrozenBlock;     }  
    • It is an issue with quark - update it to this build: https://www.curseforge.com/minecraft/mc-mods/quark/files/3642325
    • Remove Instant Massive Structures Mod from your server     Add new crash-reports with sites like https://paste.ee/  
    • Update your drivers: https://www.amd.com/en/support/graphics/amd-radeon-r9-series/amd-radeon-r9-200-series/amd-radeon-r9-280x
  • Topics

×
×
  • Create New...

Important Information

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