Спавнить частицы дыма после выстрела

Версия Minecraft
1.8.9
37
2
В общем, никак не могу решить одну проблему. Нужно после выстрела заспавнить линию партиклов перед итемом. В моддинге новичок, сильно не ругайтесь:)
 
Решение
Если такой вариант тебя устроит , то ниже прилагаю код(для 1.12 ).
(Указал на примере снежка + идет спавн какого-то непонятного дополнительного , не существующего снежка ( как бороться с этим не знаю))

Entity BULLET
Здесь всё до безобразия просто. Всё украдено с EntitySnowball и метод OnUpdate с EntityThrowable + переменные оттуда же.
К onUpdate В конце дописал спавн партиклов.
(p.s. ты можешь создать свой Ентити пульку с красивой моделькой квадратной пули)
Java:
public class Bullet extends EntitySnowball {
   
    private int xTile;
    private int yTile;
    private int zTile;
    private Block inTile;
    protected boolean inGround;
    public int throwableShake;
    /** The entity that threw this throwable item. */...
37
2
К сожалению, так с остальными
 
37
2
Н типа потыкал я, что-то такое сделал:
Java:
((WorldServer)this.worldObj).spawnParticle(EnumParticleTypes.SMOKE_NORMAL, true, this.posX + this.motionX * 1.13, this.posY + this.motionY * 1.05,
this.posZ + this.motionZ * 1.13, 8,0, 0, 0, 0.01D, new int[] {0});
В костыльном способе. Уже более похоже на то, что я хотел.
 
37
2
up
 
112
5
16
Если такой вариант тебя устроит , то ниже прилагаю код(для 1.12 ).
(Указал на примере снежка + идет спавн какого-то непонятного дополнительного , не существующего снежка ( как бороться с этим не знаю))

Entity BULLET
Здесь всё до безобразия просто. Всё украдено с EntitySnowball и метод OnUpdate с EntityThrowable + переменные оттуда же.
К onUpdate В конце дописал спавн партиклов.
(p.s. ты можешь создать свой Ентити пульку с красивой моделькой квадратной пули)
Java:
public class Bullet extends EntitySnowball {
   
    private int xTile;
    private int yTile;
    private int zTile;
    private Block inTile;
    protected boolean inGround;
    public int throwableShake;
    /** The entity that threw this throwable item. */
    protected EntityLivingBase thrower;
    private String throwerName;
    private int ticksInGround;
    private int ticksInAir;
    public Entity ignoreEntity;
    private int ignoreTime;
    public Bullet(World worldIn)
    {
        super(worldIn);
    }

    public Bullet(World worldIn, EntityLivingBase throwerIn)
    {
        super(worldIn, throwerIn);
    }

    public Bullet(World worldIn, double x, double y, double z)
    {
        super(worldIn, x, y, z);
    }

    public static void registerFixesSnowball(DataFixer fixer)
    {
        EntityThrowable.registerFixesThrowable(fixer, "");
    }
    protected void onImpact(RayTraceResult result)
    {
        if (result.entityHit != null)
        {
           
            result.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), (float)20.0F);
        }

        if (!this.world.isRemote)
        {
            this.world.setEntityState(this, (byte)3);
            this.setDead();
        }
    }
    public void onUpdate()
    {
        this.lastTickPosX = this.posX;
        this.lastTickPosY = this.posY;
        this.lastTickPosZ = this.posZ;
        super.onUpdate();

        if (this.throwableShake > 0)
        {
            --this.throwableShake;
        }

        if (this.inGround)
        {
            if (this.world.getBlockState(new BlockPos(this.xTile, this.yTile, this.zTile)).getBlock() == this.inTile)
            {
                ++this.ticksInGround;

                if (this.ticksInGround == 1200)
                {
                    this.setDead();
                }

                return;
            }

            this.inGround = false;
            this.motionX *= (double)(this.rand.nextFloat() * 0.2F);
            this.motionY *= (double)(this.rand.nextFloat() * 0.2F);
            this.motionZ *= (double)(this.rand.nextFloat() * 0.2F);
            this.ticksInGround = 0;
            this.ticksInAir = 0;
        }
        else
        {
            ++this.ticksInAir;
        }

        Vec3d vec3d = new Vec3d(this.posX, this.posY, this.posZ);
        Vec3d vec3d1 = new Vec3d(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);
        RayTraceResult raytraceresult = this.world.rayTraceBlocks(vec3d, vec3d1);
        vec3d = new Vec3d(this.posX, this.posY, this.posZ);
        vec3d1 = new Vec3d(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ);

        if (raytraceresult != null)
        {
            vec3d1 = new Vec3d(raytraceresult.hitVec.x, raytraceresult.hitVec.y, raytraceresult.hitVec.z);
        }

        Entity entity = null;
        List<Entity> list = this.world.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().expand(this.motionX, this.motionY, this.motionZ).grow(1.0D));
        double d0 = 0.0D;
        boolean flag = false;

        for (int i = 0; i < list.size(); ++i)
        {
            Entity entity1 = list.get(i);

            if (entity1.canBeCollidedWith())
            {
                if (entity1 == this.ignoreEntity)
                {
                    flag = true;
                }
                else if (this.thrower != null && this.ticksExisted < 2 && this.ignoreEntity == null)
                {
                    this.ignoreEntity = entity1;
                    flag = true;
                }
                else
                {
                    flag = false;
                    AxisAlignedBB axisalignedbb = entity1.getEntityBoundingBox().grow(0.30000001192092896D);
                    RayTraceResult raytraceresult1 = axisalignedbb.calculateIntercept(vec3d, vec3d1);

                    if (raytraceresult1 != null)
                    {
                        double d1 = vec3d.squareDistanceTo(raytraceresult1.hitVec);

                        if (d1 < d0 || d0 == 0.0D)
                        {
                            entity = entity1;
                            d0 = d1;
                        }
                    }
                }
            }
        }

        if (this.ignoreEntity != null)
        {
            if (flag)
            {
                this.ignoreTime = 2;
            }
            else if (this.ignoreTime-- <= 0)
            {
                this.ignoreEntity = null;
            }
        }

        if (entity != null)
        {
            raytraceresult = new RayTraceResult(entity);
        }

        if (raytraceresult != null)
        {
            if (raytraceresult.typeOfHit == RayTraceResult.Type.BLOCK && this.world.getBlockState(raytraceresult.getBlockPos()).getBlock() == Blocks.PORTAL)
            {
                this.setPortal(raytraceresult.getBlockPos());
            }
            else if (!net.minecraftforge.event.ForgeEventFactory.onProjectileImpact(this, raytraceresult))
            {
                this.onImpact(raytraceresult);
            }
        }

        this.posX += this.motionX;
        this.posY += this.motionY;
        this.posZ += this.motionZ;
        float f = MathHelper.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ);
        this.rotationYaw = (float)(MathHelper.atan2(this.motionX, this.motionZ) * (180D / Math.PI));

        for (this.rotationPitch = (float)(MathHelper.atan2(this.motionY, (double)f) * (180D / Math.PI)); this.rotationPitch - this.prevRotationPitch < -180.0F; this.prevRotationPitch -= 360.0F)
        {
            ;
        }

        while (this.rotationPitch - this.prevRotationPitch >= 180.0F)
        {
            this.prevRotationPitch += 360.0F;
        }

        while (this.rotationYaw - this.prevRotationYaw < -180.0F)
        {
            this.prevRotationYaw -= 360.0F;
        }

        while (this.rotationYaw - this.prevRotationYaw >= 180.0F)
        {
            this.prevRotationYaw += 360.0F;
        }

        this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F;
        this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F;
        float f1 = 0.99F;
        float f2 = this.getGravityVelocity();

        if (this.isInWater())
        {
            for (int j = 0; j < 4; ++j)
            {
                float f3 = 0.25F;
                this.world.spawnParticle(EnumParticleTypes.WATER_BUBBLE, this.posX - this.motionX * 0.25D, this.posY - this.motionY * 0.25D, this.posZ - this.motionZ * 0.25D, this.motionX, this.motionY, this.motionZ);
            }

            f1 = 0.8F;
        }

        this.motionX *= (double)f1;
        this.motionY *= (double)f1;
        this.motionZ *= (double)f1;

        if (!this.hasNoGravity())
        {
            this.motionY -= (double)f2;
        }

        this.setPosition(this.posX, this.posY, this.posZ);
        world.spawnParticle(EnumParticleTypes.CLOUD, this.posX, this.posY, this.posZ, 0.1F , 0.1F , 0.1F, null);
    }

}

Собственно сам предмет , точнее методы спавна "пульки" , в методе OnItemUseFinish задаем скорость + начальное положение пульки.
Код:
@Override
    public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand ) {
        ItemStack itemstack = player.getHeldItem(hand);
        player.setActiveHand(hand);
      
        return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, player.getHeldItem(hand));
       
    }
   
    @Override
    public ItemStack onItemUseFinish(ItemStack stack, World world, EntityLivingBase entityLiving){
            EntityPlayer player = (EntityPlayer)entityLiving;
            Vec3d look = player.getLookVec();
            Bullet bullet = new Bullet(world, 1D, 1D, 1D);
            bullet.setPosition(player.posX + look.x*1.5D, player.posY + look.y * 1.5D, player.posZ + look.z * 1.5D);
            bullet.motionX = look.x * 7.5D;
            bullet.motionY = look.y * 7.5D;
            bullet.motionZ = look.z * 7.5D;
            player.playSound(SoundHandler.FIREGUN, 1F, 1F);
            world.spawnEntity(bullet);
        return stack;
    }
   
    @Override
    public int getMaxItemUseDuration(ItemStack stack){
        return 15;
    }
   
    @Override
    public EnumAction getItemUseAction(ItemStack stack){
        return EnumAction.BOW;
    }

Результат сие можно наблюдать на видеофрагменте.
Чем смог , тем помог.

UPD
Если тебе нужна просто линия партиклов, типо пороховой остаток от выстрела, то не трогай Ентити пульку, а через Vec3d лови направление взгляда игрока и спавни партиклы перед ними типо
Код:
world.spawnParticle(EnumParticleTypes.CLOUD, this.posX + look.x*1.5D, this.posY+lool.y*1.5D, this.posZ+look.z*1.5D, 0.F , 0.3F , 0.0F, null);
и таких несколько только вместо 1.5D вставляй другие значения
 
Последнее редактирование:
37
2
Спасибо) Буду разбираться
 
Сверху