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

Hi!
I was trying to create a smoke projectile, that when hits the ground spawn some particles for a certain duration.
The problem is that, when the entity hits the ground, it don't spawn the particles at all.

Here is my projectile:

@OnlyIn(value = Dist.CLIENT, _interface = IRendersAsItem.class)
public class SmokeBulletEntity extends DamagingProjectileEntity implements IRendersAsItem {

    private static final ItemStack STACK = new ItemStack(ModItems.BULLET.get());

    private boolean activated;
    private int duration;

    public SmokeBulletEntity(World world) {
        super(ModEntities.SMOKE_BULLET.get(), world);
        this.activated = false;
    }

    @Override
    public ItemStack getItem() {
        return STACK;
    }

    @Override
    protected void onHitBlock(BlockRayTraceResult rayTraceResult) {
        if (this.activated)
            return;
        if (!this.level.isClientSide) {
            this.activate();
        }
        super.onHitBlock(rayTraceResult);
    }

    @Override
    protected void onHitEntity(EntityRayTraceResult entityRayTraceResult) {
        //Must be Empty
    }

    private void activate() {
        this.activated = true;
        this.duration = 200;
        this.setDeltaMovement(0, 0, 0);
        this.xPower = 0;
        this.yPower = 0;
        this.zPower = 0;
        System.out.println("Active Smoke Projectile");
    }

    @Override
    public void tick() {
        if (this.activated && !this.level.isClientSide) {
            //System.out.println(String.format("%f, %f, %f", this.getX(), this.getY(), this.getZ()));
            for (int i = 0; i < 100; i++) {
                this.level.addParticle(ParticleTypes.FLAME, this.getX(), this.getY() + i, this.getZ(), 0, 0, 0);
            }
            this.duration--;
            if (this.duration <= 0) {
                this.remove();
            }
        } else {
            super.tick();
        }
    }

    @Override
    public void addAdditionalSaveData(CompoundNBT nbt) {
        super.addAdditionalSaveData(nbt);
        nbt.putBoolean("activated", this.activated);
        nbt.putInt("duration", this.duration);
    }

    @Override
    public void readAdditionalSaveData(CompoundNBT nbt) {
        super.readAdditionalSaveData(nbt);
        if (nbt.contains("activated")) {
            this.activated = nbt.getBoolean("activated");
        }
        if (nbt.contains("duration")) {
            this.duration = nbt.getInt("duration");
        }
    }

    @Override
    public IPacket<?> getAddEntityPacket() {
        return NetworkHooks.getEntitySpawningPacket(this);
    }
}

Can somebody explain me why?

Thanks!

  • Author

Ok so, i changed the function Entity#tick

public void tick() {
        if (this.activated) {
            for (int i = 0; i < 100; i++) {
                this.level.addParticle(ParticleTypes.FLAME, this.getX(), this.getY() + i, this.getZ(), 0, 0, 0);
            }
            this.duration--;
            if (this.duration <= 0) {
                this.remove();
            }
        } else {
            super.tick();
        }
    }

But still the bullet does not show the particles. There are only those of the basic bullet:

image.png.86e222a6691e6ba0b83231925f45521f.png

Why this happen?

  • Author

How can i set the data on the client side?

The methods Entity#addAdditionalSaveData and Entity#readAdditionalSaveData doesn't do that?

54 minutes ago, Yurim64 said:

How can i set the data on the client side?

The methods Entity#addAdditionalSaveData and Entity#readAdditionalSaveData doesn't do that?

if the code above is still partly up-to-date, then it is due to the onHitBlock method because you only set the activate method on the server side

Edit: Entity#addAdditionalSaveData and Entity#readAdditionalSaveData these methods only save and write the data of the entity

Edited by Luis_ST

  • Author

Ok so, i changed the entity in this way:

 

public class SmokeBulletEntity extends DamagingProjectileEntity implements IRendersAsItem {


    private static final DataParameter<Boolean> ACTIVATED = EntityDataManager.defineId(SmokeBulletEntity.class, DataSerializers.BOOLEAN);
    private static final ItemStack STACK = new ItemStack(ModItems.BULLET.get());

    private int duration;

    public SmokeBulletEntity(World world) {
        super(ModEntities.SMOKE_BULLET.get(), world);
    }

    @Override
    public ItemStack getItem() {
        return STACK;
    }

    @Override
    protected void onHitBlock(BlockRayTraceResult rayTraceResult) {
        if (this.isActivated())
            return;
        if (!this.level.isClientSide) {
            this.activate();
        }
        super.onHitBlock(rayTraceResult);
    }

    @Override
    protected void onHitEntity(EntityRayTraceResult entityRayTraceResult) {
        //Must be Empty
    }

    private void activate() {
        this.setActivated(true);
        this.duration = 200;
        this.setDeltaMovement(0, 0, 0);
        this.xPower = 0;
        this.yPower = 0;
        this.zPower = 0;
        System.out.println("Active Smoke Projectile");
    }

    @Override
    public void tick() {
        if (this.isActivated()) {
            for (int i = 0; i < 100; i++) {
                this.level.addParticle(ParticleTypes.FLAME, this.getX(), this.getY() + i, this.getZ(), 0, 0, 0);
            }
            this.duration--;
            if (this.duration <= 0) {
                this.remove();
            }
        } else {
            super.tick();
        }
    }

    @Override
    public void addAdditionalSaveData(CompoundNBT nbt) {
        super.addAdditionalSaveData(nbt);
        nbt.putBoolean("activated", this.isActivated());
        nbt.putInt("duration", this.duration);
    }

    @Override
    protected void defineSynchedData() {
        super.defineSynchedData();
        this.entityData.set(ACTIVATED, false);
    }

    public void setActivated(boolean activated) {
        this.entityData.set(ACTIVATED, activated);
    }

    public boolean isActivated() {
        return this.entityData.get(ACTIVATED);
    }

    @Override
    public EntityDataManager getEntityData() {
        return super.getEntityData();
    }

    @Override
    public void readAdditionalSaveData(CompoundNBT nbt) {
        super.readAdditionalSaveData(nbt);
        if (nbt.contains("activated")) {
            this.setActivated(nbt.getBoolean("activated"));
        }
        if (nbt.contains("duration")) {
            this.duration = nbt.getInt("duration");
        }
    }

    @Override
    public IPacket<?> getAddEntityPacket() {
        return NetworkHooks.getEntitySpawningPacket(this);
    }
}

But now, when i spawn it i encounter this error:

[15:39:10] [Server thread/FATAL] [minecraft/ThreadTaskExecutor]: Error executing task on Server
java.lang.NullPointerException: null
	at net.minecraft.network.datasync.EntityDataManager.set(EntityDataManager.java:122) ~[forge:?] {re:classloading}
	at com.ike.gunmod.entity.SmokeBulletEntity.defineSynchedData(SmokeBulletEntity.java:93) ~[?:?] {re:classloading,pl:runtimedistcleaner:A}
	at net.minecraft.entity.Entity.<init>(Entity.java:216) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.entity.projectile.ProjectileEntity.<init>(ProjectileEntity.java:25) ~[forge:?] {re:classloading}
	at net.minecraft.entity.projectile.DamagingProjectileEntity.<init>(DamagingProjectileEntity.java:26) ~[forge:?] {re:classloading}
	at com.ike.gunmod.entity.SmokeBulletEntity.<init>(SmokeBulletEntity.java:35) ~[?:?] {re:classloading,pl:runtimedistcleaner:A}
	at com.ike.gunmod.item.gun.SmokeGunItem.getBullet(SmokeGunItem.java:32) ~[?:?] {re:classloading}
	at com.ike.gunmod.item.gun.AbstractGunItem.use(AbstractGunItem.java:42) ~[?:?] {re:classloading}
	at net.minecraft.item.ItemStack.use(ItemStack.java:217) ~[forge:?] {re:classloading,xf:fml:forge:filled_map.4,xf:fml:forge:itemstack}
	at net.minecraft.server.management.PlayerInteractionManager.useItem(PlayerInteractionManager.java:287) ~[forge:?] {re:classloading}
	at net.minecraft.network.play.ServerPlayNetHandler.handleUseItem(ServerPlayNetHandler.java:982) ~[forge:?] {re:classloading}
	at net.minecraft.network.play.client.CPlayerTryUseItemPacket.handle(CPlayerTryUseItemPacket.java:28) ~[forge:?] {re:classloading}
	at net.minecraft.network.play.client.CPlayerTryUseItemPacket.handle(CPlayerTryUseItemPacket.java:9) ~[forge:?] {re:classloading}
	at net.minecraft.network.PacketThreadUtil.lambda$ensureRunningOnSameThread$0(PacketThreadUtil.java:19) ~[forge:?] {re:classloading}
	at net.minecraft.util.concurrent.TickDelayedTask.run(TickDelayedTask.java:17) ~[forge:?] {re:classloading}
	at net.minecraft.util.concurrent.ThreadTaskExecutor.doRunTask(ThreadTaskExecutor.java:136) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.util.concurrent.RecursiveEventLoop.doRunTask(RecursiveEventLoop.java:22) ~[forge:?] {re:classloading}
	at net.minecraft.server.MinecraftServer.doRunTask(MinecraftServer.java:734) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.doRunTask(MinecraftServer.java:159) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.util.concurrent.ThreadTaskExecutor.pollTask(ThreadTaskExecutor.java:109) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.pollTaskInternal(MinecraftServer.java:717) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.pollTask(MinecraftServer.java:711) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.util.concurrent.ThreadTaskExecutor.managedBlock(ThreadTaskExecutor.java:119) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.waitUntilNextTick(MinecraftServer.java:697) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:646) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:232) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_231] {}

Why this happen?

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.