Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Posted

Due to the popularity of the question on how to stop or manipulate explosions without needing a core mod, I decided to tackle/post the following.

 

What I've illustrated here is how to silently replace tnt with custom tnt, with the players being none-the-wiser. This allows you to write a custom tnt that looks/feels just like tnt, but you can override methods and add custom fields/methods/etc, giving you complete manipulation of tnt on your server.

 

Just replace bedrock in the following example with your custom tnt and voila!

 

 

import java.util.List;

import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityItemFrame;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.util.AxisAlignedBB;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;

import cpw.mods.fml.common.eventhandler.SubscribeEvent;

public class BuildEventHook {	

@SubscribeEvent
public void onClick(PlayerInteractEvent event) {		

	if (event.action == event.action.RIGHT_CLICK_BLOCK) {			

		if(event.entityPlayer.inventory.mainInventory[event.entityPlayer.inventory.currentItem].getItem() == Item.getItemFromBlock(Blocks.tnt)){
			int i = event.face;
			int x = event.x;
			int y = event.y;
			int z = event.z;
			boolean can = false;

			// bottom top north south west east
			if(i == 0){
				y--;
			}
			else if(i == 1){
				y++;
			}
			else if(i == 2){
				z--;
			}
			else if(i == 3){
				z++;
			}
			else if(i == 4){
				x--;
			}
			else if(i == 5){
				x++;
			}

			if(event.world.isAirBlock(x, y, z))
				can = true;

			List l = event.world.getEntitiesWithinAABB(
					Entity.class,
					AxisAlignedBB.getBoundingBox(
							(double) x,
							(double) y,
							(double) z,
							(double) x + 1.0d,
							(double) y + 1.0d,
							(double) z + 1.0d));
			if(l.size() > 0)
				can = false;

			if(can){
				event.world.setBlock(x, y, z, Blocks.bedrock);					
			}
			event.setCanceled(true);
		}
	}

}	

}

I'll need help, and I'll give help. Just ask, you know I will!

  • Author

Note: to use a clone of vanilla tnt, you will have to create and register a new entity for the tnt, which can be cloned from EntityTNTPrimed (notice it extends the vanilla):

 

 

public class NewTNTPrimed extends EntityTNTPrimed
{
    /** How long the fuse is */
    public int fuse;
    private EntityLivingBase tntPlacedBy;
    
    public NewTNTPrimed(World p_i1729_1_)
    {
        super(p_i1729_1_);
        this.preventEntitySpawning = true;
        this.setSize(0.98F, 0.98F);
        this.yOffset = this.height / 2.0F;
        this.fuse = 80;
        
    }

    public NewTNTPrimed(World p_i1730_1_, double p_i1730_2_, double p_i1730_4_, double p_i1730_6_, EntityLivingBase p_i1730_8_)
    {
        this(p_i1730_1_);
        this.setPosition(p_i1730_2_, p_i1730_4_, p_i1730_6_);
        float f = (float)(Math.random() * Math.PI * 2.0D);
        this.motionX = (double)(-((float)Math.sin((double)f)) * 0.02F);
        this.motionY = 0.20000000298023224D;
        this.motionZ = (double)(-((float)Math.cos((double)f)) * 0.02F);
        this.fuse = 80;
        this.prevPosX = p_i1730_2_;
        this.prevPosY = p_i1730_4_;
        this.prevPosZ = p_i1730_6_;
        this.tntPlacedBy = p_i1730_8_;
    }

    protected void entityInit() {}

    /**
     * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
     * prevent them from trampling crops
     */
    protected boolean canTriggerWalking()
    {
        return false;
    }

    /**
     * Returns true if other Entities should be prevented from moving through this Entity.
     */
    public boolean canBeCollidedWith()
    {
        return !this.isDead;
    }

    /**
     * Called to update the entity's position/logic.
     */
    public void onUpdate()
    {
        this.prevPosX = this.posX;
        this.prevPosY = this.posY;
        this.prevPosZ = this.posZ;
        this.motionY -= 0.03999999910593033D;
        this.moveEntity(this.motionX, this.motionY, this.motionZ);
        this.motionX *= 0.9800000190734863D;
        this.motionY *= 0.9800000190734863D;
        this.motionZ *= 0.9800000190734863D;

        if (this.onGround)
        {
            this.motionX *= 0.699999988079071D;
            this.motionZ *= 0.699999988079071D;
            this.motionY *= -0.5D;
        }

        if (this.fuse-- <= 0)
        {
            this.setDead();

            if (!this.worldObj.isRemote)
            {
            	if(Events.onTNTExplode(this, (EntityPlayer)this.tntPlacedBy))
            		this.explode();                
            }
        }
        else
        {
            this.worldObj.spawnParticle("smoke", this.posX, this.posY + 0.5D, this.posZ, 0.0D, 0.0D, 0.0D);
        }
    }

    private void explode()
    {
        float f = 4.0F;
        this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, f, true);
    }

    /**
     * (abstract) Protected helper method to write subclass entity data to NBT.
     */
    protected void writeEntityToNBT(NBTTagCompound p_70014_1_)
    {
        p_70014_1_.setByte("NFuse", (byte)this.fuse);
    }

    /**
     * (abstract) Protected helper method to read subclass entity data from NBT.
     */
    protected void readEntityFromNBT(NBTTagCompound p_70037_1_)
    {
        this.fuse = p_70037_1_.getByte("NFuse");
    }

    @SideOnly(Side.CLIENT)
    public float getShadowSize()
    {
        return 0.0F;
    }

    /**
     * returns null or the entityliving it was placed or ignited by
     */
    public EntityLivingBase getTntPlacedBy()
    {
        return this.tntPlacedBy;
    }
}

 

take note of this line:

if(Events.onTNTExplode(this, (EntityPlayer)this.tntPlacedBy)) this.explode();

 

...it will let you create an explosion event handler as such:

 

	/**
 * Fired just before a tnt explosion
 * @param tnt
 * @param player = null often! be careful!
 * @return false will cancel the explosion
 */
public static boolean onTNTExplode(NewTNTPrimed tnt, EntityPlayer player) {



	return true;
}

 

Also, your tnt may not render correctly after lighting it. Be sure to register the renderer in your proxy! I suggest using the same renderer as vanilla tnt.

 

RenderingRegistry.registerEntityRenderingHandler(NewTNTPrimed.class, new RenderTNTPrimed());

 

I'll need help, and I'll give help. Just ask, you know I will!

  • Author

Edit: Sorry, be sure to put

if(!event.world.isRemote){

in your PlayerInteractEvent check. The check should actually look as follows.

if(!event.world.isRemote){
			if(event.entityPlayer.inventory.mainInventory[event.entityPlayer.inventory.currentItem].getItem() == Item.getItemFromBlock(Blocks.tnt)){
				int i = event.face;
				int x = event.x;
				int y = event.y;
				int z = event.z;
				boolean can = false;

				// bottom top north south west east
				if(i == 0){
					y--;
				}
				else if(i == 1){
					y++;
				}
				else if(i == 2){
					z--;
				}
				else if(i == 3){
					z++;
				}
				else if(i == 4){
					x--;
				}
				else if(i == 5){
					x++;
				}

				if(event.world.isAirBlock(x, y, z))
					can = true;

				List l = event.world.getEntitiesWithinAABB(
						Entity.class,
						AxisAlignedBB.getBoundingBox(
								(double) x,
								(double) y,
								(double) z,
								(double) x + 1.0d,
								(double) y + 1.0d,
								(double) z + 1.0d));
				if(l.size() > 0)
					can = false;

				if(can){
					event.world.setBlock(x, y, z, IFaction.NewTNT);		
					event.world.notifyBlockOfNeighborChange(x, y, z, IFaction.NewTNT);
				}
				event.setCanceled(true);
			}

I'll need help, and I'll give help. Just ask, you know I will!

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

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.