Jump to content

[1.7.2] How to do ThrowableEntity that generates particles on hitting entities?


Recommended Posts

Posted

I have a smokebomb.  It's kind of like a snowball, but instead of splitting into snow particles when you throw it at solid stuff, it generates a cloud of smoke instead.

Well, currently a smokecube, because I haven't yet found a good tutorial for 1.7.2 ThrowableEntity renderers, and what I've found for 1.6 doesn't seem to work. Not my current issue, at any rate.

 

I want my smokecube to explode into smoke when it hits anything. I'm not having any issues with the smokecube and the ground, but when it gets tossed at an entity, it just deals 0 damage (not a problem) and vanishes without generating any particles (problem). I want a cloud of smoke even if an entity blocks the smokecube with their face.

 

I've tried putting a copy of the particle generation loop in the conditional section that checks if it hit an entity, but that doesn't change anything whether placed before or after the line saying it deals 0 damage to the entity. I've also, by trial and error, attempted to use blockX, blockY and blockZ from par1MovingObjectPosition.entityHit in place of the this.usual posX, this.posY and this.posZ in this.worldObj.spawnParticle(), but again that did nothing.

Does anyone know how to make a ThrowableEntity do particle stuff when/after hitting an entity, rather than just dealing damage (if applicable) and vanishing?

 

package com.feldherren.smokebomb;

import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.projectile.EntityThrowable;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.world.World;

public class EntityGreySmokebomb extends EntityThrowable
{

int amount = 10;

    public EntityGreySmokebomb(World par1World)
    {
        super(par1World);
    }

    public EntityGreySmokebomb(World par1World, EntityLivingBase par2EntityLivingBase)
    {
        super(par1World, par2EntityLivingBase);
    }

    public EntityGreySmokebomb(World par1World, double par2, double par4, double par6)
    {
        super(par1World, par2, par4, par6);
    }

    /**
     * Called when this EntityThrowable hits a block or entity.
     */
    protected void onImpact(MovingObjectPosition par1MovingObjectPosition)
    {
        if (par1MovingObjectPosition.entityHit != null)
        {            
            par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, getThrower()), 0.0F);
            
        }
        
        for (int var3 = 0; var3 < amount; ++var3)
        {
            this.worldObj.spawnParticle("hugeexplosion", this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D);
        }
        
        if (!this.worldObj.isRemote)
        {
            this.setDead();
        } 
    }
}

Posted

I think I see your problem

 

int amount = 10;

 

This snippit is in the base class without any modifiers. The default one will apply but in practice it is always better to put one - and it looks out of place like that. This may not fix the problem, but change the line to

private int amount = 10;

 

After this, I would recommend putting a println inside the for loop where you spawn the particles to make sure it is running. Seeing as it's the same as in EntitySnowball it *should* be working, but it obviously isn't.

 

Also just for bug-fixing, consider changing the particle line to directly copied from the EntitySnowball class. Once you get it working with that particle you can change it. Your problem may just be that you are asking for a particle that you can't see!

Posted

That 'int amount' was actually just there to make sure the loop that outputs particles would do the same from in the 'has hit something' part as outside, when I had two copies of it, and from when I was testing to see what works best for a cloud of smoke - ten particles look good, a hundred particles look stupidly-synchronised.

That said, tried that. Unfortunately it didn't help, but changing it didn't break anything and I should probably remember to set things private in future.

 

The problem with copying the snowball code exactly is... snowballs show exactly the same behaviour. You're assuming they emit particles when you hit an entity like a sheep with them, but they don't. The behaviour of unmodified snowballs was one of the first things I checked, since EntityGreySmokebomb here is very obviously copied from EntitySnowball. I've checked this on a vanilla copy of Minecraft, too. (This is why I asked about ThrowableEntity and not 'my throwable thing', but I thought I'd mentioned it in the original post. Checking it, I guess I didn't.)

 

These smokebombs do work when they hit the environment. They generate a very obvious cloud of smoke. The particle certainly isn't invisible.

Posted

I don't know. Would that cause particles to be generated and visible to at least the thrower when the smokebomb or snowball entity hits a block, but cause particles to (apparently) not to be generated when the projectile hits a sheep?

 

How can I tell?

Posted

That sheep must be to fluffy.

 

Side from that. Try looking into EntityArrow? Could help

We all stuff up sometimes... But I seem to be at the bottom of that pot.

Posted

The impact block and impact entity is different sections.  Haven't traced it out to see if it registers correctly.

Long time Bukkit & Forge Programmer

Happy to try and help

Posted

This has been solved, but I'm not sure if I can competently explain it.

 

As far as I'm aware, when an entity rather than the environment was hit, the spawnParticle() method ended up rendering them to the server, not the client, so I as a player saw nothing.

I (with the help of a better-coder friend) ended up using packets to get the client to render the particles.

 

So, should anyone need an example:

 

In preInit() in the main class:

		snw = NetworkRegistry.INSTANCE.newSimpleChannel(SmokebombMain.MODID);
		snw.registerMessage(PacketHugeExplosion.class, PacketHugeExplosion.class, 0, Side.CLIENT); 

 

EntityGreySmokebomb:

package com.feldherren.smokebomb;

import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityThrowable;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.world.World;
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;

public class EntityGreySmokebomb extends EntityThrowable
{

private int amount = 10;

    public EntityGreySmokebomb(World par1World)
    {
        super(par1World);
    }

    public EntityGreySmokebomb(World par1World, EntityLivingBase par2EntityLivingBase)
    {
        super(par1World, par2EntityLivingBase);
    }

    public EntityGreySmokebomb(World par1World, double par2, double par4, double par6)
    {
        super(par1World, par2, par4, par6);
    }

    /**
     * Called when this EntityThrowable hits a block or entity.
     */
    protected void onImpact(MovingObjectPosition par1MovingObjectPosition)
    {
        if (par1MovingObjectPosition.entityHit != null)
        {
        	EntityPlayer player = (EntityPlayer)this.getThrower();
        	TargetPoint point = new TargetPoint(par1MovingObjectPosition.entityHit.dimension, 100, par1MovingObjectPosition.entityHit.posX, par1MovingObjectPosition.entityHit.posY, par1MovingObjectPosition.entityHit.posZ);
        	PacketHugeExplosion packetHugeExplosion = new PacketHugeExplosion(par1MovingObjectPosition.entityHit.posX,par1MovingObjectPosition.entityHit.posY, par1MovingObjectPosition.entityHit.posZ, amount);
        	SmokebombMain.snw.sendToAllAround(packetHugeExplosion, point);
        	
            par1MovingObjectPosition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, getThrower()), 0.0F);
        }
        
        for (int var3 = 0; var3 < amount; ++var3)
        {
            this.worldObj.spawnParticle("hugeexplosion", this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D);
        }
        
        if (!this.worldObj.isRemote)
        {
            this.setDead();
        } 
    }
}

 

PacketHugeExplosion:

package com.feldherren.smokebomb;

import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;

public class PacketHugeExplosion implements IMessage, IMessageHandler<PacketHugeExplosion, IMessage>
{

double posX, posY, posZ;
int amount;

public PacketHugeExplosion()
{
}

public PacketHugeExplosion(EntityPlayer player, int amount)
{
	this(player.posX, player.posY, player.posZ, amount);
}

public PacketHugeExplosion(double posX, double posY, double posZ, int amount)
{
	this.posX = posX;
	this.posY = posY;
	this.posZ = posZ;
	this.amount = amount;
}

@Override
public void fromBytes(ByteBuf buf) 
{
	// TODO Auto-generated method stub
	this.posX = buf.readDouble();
	this.posY = buf.readDouble();
	this.posZ = buf.readDouble();
	this.amount = buf.readInt();
}

@Override
public void toBytes(ByteBuf buf) 
{
	// TODO Auto-generated method stub
	buf.writeDouble(posX);
	buf.writeDouble(posY);
	buf.writeDouble(posZ);
	buf.writeInt(amount);
}

@Override
public IMessage onMessage(PacketHugeExplosion message, MessageContext ctx)
{
        for (int var3 = 0; var3 < message.amount; ++var3)
        {
        	 FMLClientHandler.instance().getClient().theWorld.spawnParticle("hugeexplosion", message.posX, message.posY+1, message.posZ, 0.0D, 0.0D, 0.0D);
        }
	// TODO Auto-generated method stub
	return null;
}
}

 

I don't think I missed anything out here, so this should serve as an example of how to do it. Seems solved now that it does detonate on sheep, too.

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.