Jump to content

[1.8] [90% SOLVED] Cannot Interact With CustomFire E.G. Hit to Extinguish


Recommended Posts

Posted

As the title says, I have having trouble being able to interact with a custom fire I am adding, I cannot hit it to put it out, I either have to place a block on it, or break the block it's on to get rid of it. My code for the block is here. Does anyone have an idea as to how to get it to work? I have looked at BlockFire and cannot figure it out.

 

EDIT: Please read through the ENTIRE thread before commenting to use PlayerInteractEvent. I have answered why that does not work for this several times.

  • Replies 70
  • Created
  • Last Reply

Top Posters In This Topic

Posted

So I just added an event handler and really at this point all it's doing is adding the fizz sound. If you are in creative it's still destroying the block the fire is on, I know I can cancel the event and continue to remove the fire, but that way causes the block to disappear and reappear which looks terrible. How can I cancel the BlockBreak event without having block still "break" and come back?

Posted

I have added a player event handler for the interact event.

So what is happening, I click the fire and get the fizz sound indicating that the fire is out, but it still break the block the fire is on. I know i can do event.setCanceled(true); to stop the block from breaking, but it just replaces the block and stops the block from dropping anything.

 

 

 

package com.saxon564.mochickens.events;

import com.saxon564.mochickens.MoChickens;

import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent.PlayerTickEvent;

public class PlayerEventHandler {

@SubscribeEvent
public void onPlayerInteract(PlayerInteractEvent event) {
	if (event.action == Action.LEFT_CLICK_BLOCK) {
		EntityPlayer player = event.entityPlayer;
		World world = player.worldObj;

		EnumFacing face = event.face;
		BlockPos pos = event.pos;
		Block block = world.getBlockState(pos).getBlock();

		if (block != null) {
			this.extinguishFire(player, pos, face, world, event);
		}
	}
}

@SubscribeEvent
public void onPlayerMovement(PlayerTickEvent event) {
	EntityPlayer player = event.player;
	BlockPos pos = player.getPosition();
	World world = player.worldObj;
	Block block = world.getBlockState(pos).getBlock();
	if ((block == MoChickens.blockChickenFire) || (world.getBlockState(pos.up()).getBlock() == MoChickens.blockChickenFire)) {
		player.setFire(;
	}
}

private void extinguishFire(EntityPlayer player, BlockPos pos, EnumFacing face, World world, PlayerInteractEvent event) {
	 pos = pos.offset(face);

        if (world.getBlockState(pos).getBlock() == MoChickens.blockChickenFire)
        {
        	world.playSoundEffect(player.posX, player.posY, player.posZ, "random.fizz", 1.0F, 1.0F);
        	world.setBlockToAir(pos);
        }

}

}

 

 

Unless you mean to call it in the class for my fire block. Though I'm not sure what good that would do since fire is ignored as a breakable block so none of the general block interaction methods would be firing on it.

Posted

private void extinguishFire(EntityPlayer player, BlockPos pos, EnumFacing face, World world, PlayerInteractEvent event) {
	 pos = pos.offset(face);

        if (world.getBlockState(pos).getBlock() == MoChickens.blockChickenFire)
        {
        	world.playSoundEffect(player.posX, player.posY, player.posZ, "random.fizz", 1.0F, 1.0F);
        	world.setBlockToAir(pos);
        	event.setCanceled(true);
        }

}

Where I put the setCanceled(true) is in this method, should I put it sooner in the event?

Posted

ok. Well I'm playing around with it and it seems that if you cancel MouseEvent it causes the event to freak out and just spam click.

 

Here is what I have for testing this, as I said, I'm playing around with it. What do you think?

 

 

package com.saxon564.mochickens.events;

import com.saxon564.mochickens.MoChickens;

import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import net.minecraftforge.client.event.MouseEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent.PlayerTickEvent;

public class PlayerEventHandler {
private Boolean click = false;
@SubscribeEvent
public void onMouseEvent(MouseEvent event) {
	int button = event.button;
	if (click) {
		MoChickens.logger.info("~~~~~~~~~~~~~~~~~~~Left Click~~~~~~~~~~~~~~~~~~~~~");
		click = false;
		event.setCanceled(true);
	}
}

@SubscribeEvent
public void onPlayerInteract(PlayerInteractEvent event) {
	if (event.action == Action.LEFT_CLICK_BLOCK) {
		EntityPlayer player = event.entityPlayer;
		World world = player.worldObj;

		EnumFacing face = event.face;
		BlockPos pos = event.pos;
		Block block = world.getBlockState(pos).getBlock();

		if (block != null) {
			this.extinguishFire(player, pos, face, world, event);
		}
	}
}

@SubscribeEvent
public void onPlayerMovement(PlayerTickEvent event) {
	EntityPlayer player = event.player;
	BlockPos pos = player.getPosition();
	World world = player.worldObj;
	Block block = world.getBlockState(pos).getBlock();
	if (((block == MoChickens.blockChickenFire) || (world.getBlockState(pos.up()).getBlock() == MoChickens.blockChickenFire)) && (!player.capabilities.isCreativeMode)) {
		player.setFire(;
	}
}

private void extinguishFire(EntityPlayer player, BlockPos pos, EnumFacing face, World world, PlayerInteractEvent event) {
	 pos = pos.offset(face);

        if (world.getBlockState(pos).getBlock() == MoChickens.blockChickenFire)
        {
    		click = true;
        	world.playSoundEffect(player.posX, player.posY, player.posZ, "random.fizz", 1.0F, 1.0F);
        	world.setBlockToAir(pos);
        	event.setCanceled(true);
        }

}

}

 

 

Posted

ok, ok. As I said, I'm playing around with it. my only issue with the MouseEvent is you have no info from in game. I am not finding any info out as to how to get anything from the game, such as the player and the block pos.

Posted

MouseEvent is client-only, so you can use the stuff from the Minecraft class. It has fields for the player (

thePlayer

), the world (

theWorld

) and also the block the mouse is currently over (

objectMouseOver

).

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/

Posted

Ok, thank you. Now hopefully my final question here, do you know of any good tutorials on the basics of packets? I have never even looked into them before so I have no idea what I need to be doing with them.

Posted

I have added the network handlers that I need, but for some reason null information is being sent.

 

here are my updated classes

Registering the Messaging Class:

public static SimpleNetworkWrapper network;

@EventHandler
    public void preInit(FMLPreInitializationEvent event) {
        network = NetworkRegistry.INSTANCE.newSimpleChannel("moChickens");
        network.registerMessage(FireMessage.Handler.class, FireMessage.class, 0, Side.SERVER);
    }

 

Event Handler:

 

 

package com.saxon564.mochickens.events;

import com.saxon564.mochickens.MoChickens;
import com.saxon564.mochickens.network.FireMessage;

import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import net.minecraftforge.client.event.MouseEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent.PlayerTickEvent;

public class PlayerEventHandler {

@SubscribeEvent
public void onMouseEvent(MouseEvent event) {
	int button = event.button;
	EntityPlayer player = Minecraft.getMinecraft().thePlayer;
	World world = Minecraft.getMinecraft().theWorld;

	BlockPos pos = Minecraft.getMinecraft().objectMouseOver.getBlockPos();
	EnumFacing face = Minecraft.getMinecraft().objectMouseOver.sideHit;

	if (button == 0) {
		if (world.getBlockState(pos).getBlock()!= null) {
			this.extinguishFire(player, pos, face, world, event);
		}
	}
}

@SubscribeEvent
public void onPlayerMovement(PlayerTickEvent event) {
	EntityPlayer player = event.player;
	BlockPos pos = player.getPosition();
	World world = player.worldObj;
	Block block = world.getBlockState(pos).getBlock();
	if (((block == MoChickens.blockChickenFire) || (world.getBlockState(pos.up()).getBlock() == MoChickens.blockChickenFire)) && (!player.capabilities.isCreativeMode)) {
		player.setFire(;
	}
}

private void extinguishFire(EntityPlayer player, BlockPos pos, EnumFacing face, World world, MouseEvent event) {
	 pos = pos.offset(face);

        if (world.getBlockState(pos).getBlock() == MoChickens.blockChickenFire)
        {
        	world.playSoundEffect(player.posX, player.posY, player.posZ, "random.fizz", 1.0F, 1.0F);
        	world.setBlockToAir(pos);
        	MoChickens.network.sendToServer(new FireMessage(player, face));
        	event.setCanceled(true);
        }

}
}

 

 

 

Message Class:

 

 

package com.saxon564.mochickens.network;

import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.BlockPos;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;

public class FireMessage implements IMessage {
    
    private String text;
    private String player;
    private int face;

    public FireMessage() { }

    public FireMessage(EntityPlayer playerIn, EnumFacing faceIn) {
        player = playerIn.toString();
        face = faceIn.getIndex();
    }

    @Override
    public void fromBytes(ByteBuf buf) {
        player = ByteBufUtils.readUTF8String(buf);
        face = ByteBufUtils.readVarInt(buf, 5);
    }

    @Override
    public void toBytes(ByteBuf buf) {
        ByteBufUtils.writeUTF8String(buf, player);
        ByteBufUtils.writeVarInt(buf, face, 5);
    }

    public static class Handler implements IMessageHandler<FireMessage, IMessage> {
        
        @Override
        public IMessage onMessage(FireMessage message, MessageContext ctx) {
            System.out.println(String.format("Received %s from %s", message.text, ctx.getServerHandler().playerEntity.getDisplayName()));
            return null;
        }
    }
}

 

 

Posted

UhM... Dont do the mouse hackery...

 

Just send a datapacket to the client to spawn smoke particles or whatever you want for fx And do a playsound.

 

That way not only you get the correct behavour but players around you too.

 

Pet peeve of mine is thaumcraft warded particles only showing for player hitting the block.

Let the server decide which particles where and how, the update all players in vicinity with the data

 

How much wood could a woodchuck chuck if a wood chuck could chuck wood - Guybrush Treepwood

 

I wrote my own mod ish... still a few bugs to fix. http://thaumcraft.duckdns.org/downloads/MagicCookies-1.0.6.4.jar

Posted

UhM... Dont do the mouse hackery...

 

Just send a datapacket to the client to spawn smoke particles or whatever you want for fx And do a playsound.

 

That way not only you get the correct behavour but players around you too.

 

Pet peeve of mine is thaumcraft warded particles only showing for player hitting the block.

Let the server decide which particles where and how, the update all players in vicinity with the data

Ummm Im sorry, but do you actually read topics? I cant say how many times ive seen you comment on topics and clearly dont know what the topic was about to begin with. How does particles have anything to do with putting out a fire? I am doing what I need to do to get the fire to go out on the server and client.

Posted

Well i read your topic.

 

You have a custom fire and you try to extinguish it by hitting it.

This can all be accomplished server side by the iteminteract event.

Then when you extinguish it you wish to kill it without breaking the block behind it.

This is a simple matter of setblocktoair where the fire is at where it was hit.

If you are worrield about the blockpos being 0 0 0 with click air you can still calculate where was looked from the entityplayer.

Heck. If you wish to extinguish one flame instead of multiple in the block you can use the face hit and intrepolate the flame to extinguish and update the blockstate. Id add a cooldown for that side so it cant catch fire quickly again.

This is all serverside.

Then the server sends to clients the instruction to spawn a few fx smoke particles and play the sound at clients.

 

Seriously. I read.

 

I just thaught id respond cause i tackled a similar problem today. Just trying to help. But i guess this forum doesnt need help with such hostile atmosphere.

 

Just to continue the atmosphere: this is a dead simple problem.

How much wood could a woodchuck chuck if a wood chuck could chuck wood - Guybrush Treepwood

 

I wrote my own mod ish... still a few bugs to fix. http://thaumcraft.duckdns.org/downloads/MagicCookies-1.0.6.4.jar

Posted

Well i read your topic.

 

You have a custom fire and you try to extinguish it by hitting it.

This can all be accomplished server side by the iteminteract event.

Then when you extinguish it you wish to kill it without breaking the block behind it.

This is a simple matter of setblocktoair where the fire is at where it was hit.

If you are worrield about the blockpos being 0 0 0 with click air you can still calculate where was looked from the entityplayer.

Heck. If you wish to extinguish one flame instead of multiple in the block you can use the face hit and intrepolate the flame to extinguish and update the blockstate. Id add a cooldown for that side so it cant catch fire quickly again.

This is all serverside.

Then the server sends to clients the instruction to spawn a few fx smoke particles and play the sound at clients.

 

Seriously. I read.

 

I just thaught id respond cause i tackled a similar problem today. Just trying to help. But i guess this forum doesnt need help with such hostile atmosphere.

 

Just to continue the atmosphere: this is a dead simple problem.

Heres the issue, I am not finding a ItemInteractEvent. There is a PlayerInteractEvent and an EntityInteractEvent, both of which as far as I am aware are on the server side and do not send the information to the client. MouseEvent is not hackery, otherwise it wouldn't be an event added by MinecraftForge to use. Currently MouseEvent is the only thing that will work due to the bit of code

public boolean isCollidable {
    return false;
}

if it wasnt for that, I could easily remove the fire, but that removes the hitbox and you have to use another block to find the fire.

 

P.S. I am sorry for how I responded, I was thinking of someone on another topic that didnt bother to read the topic and gave answers that had nothing to do with the issue. For some reason I was thinking it was you, but I did go back and look at that topic again and realized my mistake.

Posted

Instead of returning false for isCollidable, return null for the bounding box:

// 1.7.10 method signature, but probably something similar in 1.8
@Override
public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) {
	return null;
}

Then your block can still respond to onBlockClicked / onBlockActivated, and you don't need any events at all. I have a fire block that does just that, yet players and other entities can walk right on through it.

Posted

Instead of returning false for isCollidable, return null for the bounding box:

// 1.7.10 method signature, but probably something similar in 1.8
@Override
public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) {
	return null;
}

Then your block can still respond to onBlockClicked / onBlockActivated, and you don't need any events at all. I have a fire block that does just that, yet players and other entities can walk right on through it.

The idea is that player should be able to swing their weapons through the fire too, to do it your way, they will have to do an extra click because they will have to break the fire before they can hit anything beyond it. I am trying to get my fire to work exactly like the vanilla fire works.

Posted

The idea is that player should be able to swing their weapons through the fire too, to do that, they will have to do an extra click because they will have to break the fire before they can hit anything beyond it. I am trying to get my fire to work exactly like the vanilla fire works.

Ah, I see. In that case, then you will have to use the PlayerInteractEvent for LEFT_CLICK_BLOCK, then check if the block ABOVE the block clicked is your custom fire; if so, set your fire to air and cancel the event. That's what I would do, anyway.

Posted

The idea is that player should be able to swing their weapons through the fire too, to do that, they will have to do an extra click because they will have to break the fire before they can hit anything beyond it. I am trying to get my fire to work exactly like the vanilla fire works.

Ah, I see. In that case, then you will have to use the PlayerInteractEvent for LEFT_CLICK_BLOCK, then check if the block ABOVE the block clicked is your custom fire; if so, set your fire to air and cancel the event. That's what I would do, anyway.

Diesieben has already shared this idea, and found out it is only on the server, not client, so the client side isnt smooth and causes the block to break and return if you are in creative or if the block is a block that takes 1 hit to break. I think I am getting somewhere with it though. I'm starting to get things going to the server through packets that will allow the server and client to be in sync.

Posted

Oh, I remember running into problems like that. I found that using 'event.useBlock = Result.DENY;' works to prevent the block from getting destroyed, whereas canceling the event didn't work as well.

 

Anyway, if you're having issues with the client side, MouseEvent is definitely the way to go except that people can change their keybindings / use a gamepad - a better alternative may be to listen for KeyInputEvent and check for mc.gameSettings.keyBindAttack.

Posted

Oh, I remember running into problems like that. I found that using 'event.useBlock = Result.DENY;' works to prevent the block from getting destroyed, whereas canceling the event didn't work as well.

 

Anyway, if you're having issues with the client side, MouseEvent is definitely the way to go except that people can change their keybindings / use a gamepad - a better alternative may be to listen for KeyInputEvent and check for mc.gameSettings.keyBindAttack.

Thats a good idea, but how would I get the key that was pressed? I dont see anything for that event that will tell me what was pressed.

 

Posted

Its all cool then and apology accepted.

 

Yea. I meant the PlayerInteractEvent. Im doing this all from mobile :-)

 

If you have left click event on the block where the fire is you can use event.world.getBlockState(event.pos.offset(event.face)) to get the block you want to check if its fire.

You might want to check first if the click was a left click and the item held is an "approved" item to extinguish the fire(bare hand, non weapon item, chicken feathers)

 

You can then use the face even to decide to extinguish only one flame or all flames.(i would choose the one flame on the hit side but thats just me)

 

When you update the blockstate it should automatically push to the client.

 

Maybe worth to check that you are running the changing blockstate code only serverside(the firespread)

 

How much wood could a woodchuck chuck if a wood chuck could chuck wood - Guybrush Treepwood

 

I wrote my own mod ish... still a few bugs to fix. http://thaumcraft.duckdns.org/downloads/MagicCookies-1.0.6.4.jar

Posted

Keyboard.getEventKey() gives you the key code of the current key being pressed.

 

EDIT: Oops, pasted the wrong thing - Keyboard.getEventKey() is the key code, Keyboard.getEventKeyState() is true if pressed, false if released.

I figured that out, but it seems to crash saying that the event cannot be canceled. Plus it doesnt do MouseInput so I would have to have both Events anyway. Im thinking once I get one of them completed, then it should be easy to add the other one.

 

Its all cool then and apology accepted.

 

If you have left click event on the block where the fire is you can use event.world.getBlockState(event.pos.offset(event.face)) to get the block you want to check if its fire.

 

You can then use the face even to decide to extinguish only one flame or all flames.(i would choose the one flame on the hit side but thats just me)

 

When you update the blockstate it should automatically push to the client.

 

Maybe worth to check that you are running the changing blockstate code only serverside(the firespread)

So you are saying to use onBlockClicked in my fire class,  to update the blockstate? I'm not sure that would work, again because collidable is false, it has no hitbox to interact with, so you would have to be checking for the hit on the block it's next to, which unless it's one of your own blocks the only way to do it would be via an Event. I could be misunderstanding what you are saying, but that is what I am getting from what you are saying. If I'm wrong, post a bit of "sample" code just to give me an idea of what you are talking about, and when I say "sample" I mean just through something together using b.s. variables so you cant say you gave me the code. :P

Posted

Yea. I meant the PlayerInteractEvent. Im doing this all from mobile :-)

Ahh ok, I will see what I can figure out using that. But the issue, as I have told CoolAlias, its not that it doesnt work, it does, but the block the fire is on still breaks on the client, then the server tells that client to put the block back, so it isnt as smooth of a process as I'd like it that way.

Posted

Its really simple.

 

First of all. Rule number 1 all non gui code must happen on server.

Currently you are running code simultanouslyserverside and clientside.

Anything that has to do witch changing blockstates has to be serverside.

 

Now in your example im going to presume your fire will always be on another block.

 

This where you use the PlayerInteractEvent to detect if your fireblock is a possible target

 

Some pseudocode(im on mobile)

@Eventhandler
Public void userclick(PlayerInteractEvent event) {
If(!event.world.isRemote) {
If(event.action == Action.LEFT_CLICK) {
if(event.world.getBlockState(event.pos.offset(event.face)).getBlock() == MyCustomChickenFire) {
Event.world.setBlockToAir(event.world.getBlockState(event.pos.offset(event.face)) );
//playsound hiss
//spawn smoke fx via networkpacket to client to tell it to spawn the fx
}
}
}
}

How much wood could a woodchuck chuck if a wood chuck could chuck wood - Guybrush Treepwood

 

I wrote my own mod ish... still a few bugs to fix. http://thaumcraft.duckdns.org/downloads/MagicCookies-1.0.6.4.jar

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




×
×
  • Create New...

Important Information

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