Jump to content

Trying to spawn particles on the server side.


kitsushadow

Recommended Posts

How can i properly spawn particles on the server side for all players to see.

 

 

public void updateEntity() {

 

World world = this.getWorldObj();

int x = this.xCoord;

int y = this.yCoord;

int z = this.zCoord;

if(!world.isRemote){

forgeMaint(world,x,y,z);

heatIngot(world, x, y, z);

fireboxFuelDec(world, x, y, z,this.getStackInSlot(0), this.ticks);

fireboxFuelDec2(world, x, y, z,this.getStackInSlot(1), this.ticks);

if(isBurning==true){

System.out.println("Is Burning");

world.spawnParticle("fire",  (double)x+0.5f, (double)y+1.1f, (double)z+0.5f, 0.0D, 0.0D, 0.0D);

world.spawnParticle("flame", (double)x+0.5f, (double)y+1.1f, (double)z+0.5f, 0.0D, 0.0D, 0.0D);

world.spawnParticle("smoke", (double)x+0.5f, (double)y+1.1f, (double)z+0.5f, 0.0D, 0.0D, 0.0D);

}

}

}

 

 

Any suggestions would be excellent. Thank You

Link to comment
Share on other sites

As my predecessor, to clear it up:

 

Particles are "special" entities that are for client ONLY.

You can spawn them only from client thread. To spawn them for all player - use Packets (SimpleNetworkWrapper), DataWatcher, or anything that can perform action (TileEntity, Block, whatever).

 

SNW tutorial:

http://www.minecraftforge.net/forum/index.php/topic,20135.0.html

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

You technically can't spawn particles on the server, but you can either spawn them on the client (i.e. when the world IS remote) since all client players will have the tile entity also ticking on the client, or use Block#randomDisplayTick, which is what furnaces do.

 

I attempted the randomDisplayTick that the furnace uses with packet handleing as well. The issue I ran into was that all of the Blocks would turn on and off together. When i made a packet handler for x y z and passed those through only one of the blocks could ever produce particle effects.

 

Block randomDisplayTick

 

@Override

@SideOnly(Side.CLIENT)

public void randomDisplayTick(World world, int x, int y, int z, Random rand)

{

super.randomDisplayTick(world, x, y, z, random);

 

if(this.furnaceParts == true){

int l;

float f;

float f1;

float f2;

for (l = 0; l < 3; ++l)

{

f = (float)(locX+0.25) + (rand.nextFloat()/2);

f1 = (float)locY + rand.nextFloat() * 0.4F + 0.3F;

f2 = (float)(locZ+0.25) + (rand.nextFloat()/2);

world.spawnParticle("fire", (double)f, (double)f1, (double)f2, 0.0D, 0.0D, 0.0D);

world.spawnParticle("flame", (double)f, (double)f1, (double)f2, 0.0D, 0.0D, 0.0D);

//world.spawnParticle("smoke", (double)f, (double)f1, (double)f2, 0.0D, 0.0D, 0.0D);

}

 

}

if(this.coalParts == true){

int l;

float f;

float f1;

float f2;

for (l = 0; l < 3; ++l)

{

f = (float)(locX+0.25) + (rand.nextFloat()/2);

//f1 = (float)y + rand.nextFloat() * 0.4F + 0.3F;

f1 = locY+1.1f;

f2 = (float)(locZ+0.25) + (rand.nextFloat()/2);

world.spawnParticle("fire", (double)f, (double)f1, (double)f2, 0.0D, 0.0D, 0.0D);

world.spawnParticle("flame", (double)f, (double)f1, (double)f2, 0.0D, 0.0D, 0.0D);

world.spawnParticle("smoke", (double)f, (double)f1, (double)f2, 0.0D, 0.0D, 0.0D);

}

}

}

 

onBlockActivated where the packet is sent from

the tileEntity locX, locY, and locZ are supplied from the TileEntity

 

if(!world.isRemote){

if(player.inventory.getCurrentItem()!=null){

if((player.inventory.getCurrentItem().getItem()==Item.getItemFromBlock(Blocks.torch))||

(player.inventory.getCurrentItem().getItem()==Items.flint_and_steel)||

(player.inventory.getCurrentItem().getItem()==ModItems.fireBow)){

tileEnt.isBurning=true;

tileEnt.markForUpdate();

TargetPoint point = new TargetPoint(0, x, y, z, 10);

//Main.sNet.sendToAll(new MsgPacketOn(tileEnt.isBurning));

Main.sNet.sendToAllAround(new MsgPacketOn(tileEnt.isBurning), point );

if(tileEnt.getStackInSlot(1)!=null){

tileEnt.isOn=true;

Main.sNet.sendToAll(new MsgPacketBurning(tileEnt.isOn));

}

}

}

 

Link to comment
Share on other sites

1. Update your forge

 

2. randomDisplayTick runs from Block - there is only one BLock instance for given block - it will run for all the same way.

What you can ONLY do is to:

2.1. Use metadata of block in given x/y/z to save boolean if given block should be "burning"

2.2. Pull that boolean (isBurning) from TileEntity at given x/y/z

 

3. this.furnaceParts and this.coalParts == true is wrong.

Again - there is only ONE Block. Anything in Block class (this) will be shared for all blocks of this type.

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

1. Update your forge

 

2. randomDisplayTick runs from Block - there is only one BLock instance for given block - it will run for all the same way.

What you can ONLY do is to:

2.1. Use metadata of block in given x/y/z to save boolean if given block should be "burning"

2.2. Pull that boolean (isBurning) from TileEntity at given x/y/z

 

3. this.furnaceParts and this.coalParts == true is wrong.

Again - there is only ONE Block. Anything in Block class (this) will be shared for all blocks of this type.

 

i use metadata for rotation. will that be a problem?

Link to comment
Share on other sites

Metadata can represent up to 16 states, but when you start combining states you quickly lose that versatility. Since you already have a TileEntity and it already knows if it is burning or not, why not just use that?

TileEntity te = world.getTileEntity(x, y, z);
if (te instanceof MyTileEntity) {
  boolean isBurning = ((MyTileEntity) te).isBurning;
}

Just make sure that the client side also knows about the state - you can do so either by using your custom packets or marking the block for an update if you have overridden getDescriptionPacket.

Link to comment
Share on other sites

You technically can't spawn particles on the server, but you can either spawn them on the client (i.e. when the world IS remote) since all client players will have the tile entity also ticking on the client, or use Block#randomDisplayTick, which is what furnaces do.

 

To clear up some confusion on this.

 

If you're trying to spawn vanilla particles, you DO "initiate" the spawn on the server. This works even though EntityFX is client side only class because the spawn particle method doesn't actually use the EntityFX class (which is not available to the server) but instead has a mapping to a string particle name. When you do this, the server will take care of notifying all clients, each of which will create the actual instance of the EntityFX class. So I would still sort of call this "spawn on the server" since you initiate it on server side.

 

If you're trying to spawn custom particles, you should still initiate on the server, but you have to implement the packets yourself to tell each client to instantiate the EntityFX.

 

The point of saying "spawn particles on the server" is that you want your code to initiate the process on server side only, and then the server should take care (either using built-in sync for vanilla particles, or using custom packets for custom particles) of syncing the clients.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

If you're trying to spawn vanilla particles, you DO "initiate" the spawn on the server.

No, you don't. World#spawnParticle calls IWorldAccess#spawnParticle, and the server implementation (in WorldManager) literally does nothing. If you try to spawn them on the server, nothing will happen.

 

You either send a packet or spawn them directly on the client side, depending on the situation.

 

There is IWorldAccess#playAuxSFX, and THIS one actually sends a packet to all around when called on the server, so you can play sound, spawn particles, or whatever else on the server as dictated by the specific SFX.

Link to comment
Share on other sites

If you're trying to spawn vanilla particles, you DO "initiate" the spawn on the server.

No, you don't. World#spawnParticle calls IWorldAccess#spawnParticle, and the server implementation (in WorldManager) literally does nothing. If you try to spawn them on the server, nothing will happen.

 

You either send a packet or spawn them directly on the client side, depending on the situation.

 

You misunderstood my statement. I said you "initiate" the spawn. That does not mean you use any world spawn method. I mean you use your own code to send a packet to all the clients.

 

This is the confusion -- the impetus for spawning particles should be on the server. The actual instance of the particles is only created on the clients.

 

The problem is the terminology "spawn". Spawn doesn't mean create an instance, it means to start the process to create something (whatever that means for the case involved). For example, you could say that placing a block is "spawning" a block -- even though no new instance is created at all. In the case of actual entities, you actually instantiate them on the server. In the case of particles you initiate the spawn on server but instantiate on the clients, and in case of blocks you initiate the spawn on the server and it is never instantiated in the Java sense. All of that is spawning, and all of those cases start on the server.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

You misunderstood my statement. I said you "initiate" the spawn. That does not mean you use any world spawn method. I mean you use your own code to send a packet to all the clients.

 

This is the confusion -- the impetus for spawning particles should be on the server. The actual instance of the particles is only created on the clients.

There is no reason that particle spawning must be initiated on the server - it is one of the few cases where it is perfectly fine to do it only on the client. The times when you do initiate it on the server are typically when a. the trigger happens there, such as when a villager is struck, or b. you want the particles visible to all players and it is not run in a method that happens consistently client side.

 

Things like Block#randomDisplayTick or any update tick method that happens on the client (such as for spawning critical particles for the EntityArrow) are perfectly valid places to initiate particle spawning and need never go through the server.

Link to comment
Share on other sites

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



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • They were already updated, and just to double check I even did a cleanup and fresh update from that same page. I'm quite sure drivers are not the problem here. 
    • i tried downloading the drivers but it says no AMD graphics hardware has been detected    
    • Update your AMD/ATI drivers - get the drivers from their website - do not update via system  
    • As the title says i keep on crashing on forge 1.20.1 even without any mods downloaded, i have the latest drivers (nvidia) and vanilla minecraft works perfectly fine for me logs: https://pastebin.com/5UR01yG9
    • Hello everyone, I'm making this post to seek help for my modded block, It's a special block called FrozenBlock supposed to take the place of an old block, then after a set amount of ticks, it's supposed to revert its Block State, Entity, data... to the old block like this :  The problem I have is that the system breaks when handling multi blocks (I tried some fix but none of them worked) :  The bug I have identified is that the function "setOldBlockFields" in the item's "setFrozenBlock" function gets called once for the 1st block of multiblock getting frozen (as it should), but gets called a second time BEFORE creating the first FrozenBlock with the data of the 1st block, hence giving the same data to the two FrozenBlock :   Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=head] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@73681674 BlockEntityData : id:"minecraft:bed",x:3,y:-60,z:-6} Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=3, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=2, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} here is the code inside my custom "freeze" item :    @Override     public @NotNull InteractionResult useOn(@NotNull UseOnContext pContext) {         if (!pContext.getLevel().isClientSide() && pContext.getHand() == InteractionHand.MAIN_HAND) {             BlockPos blockPos = pContext.getClickedPos();             BlockPos secondBlockPos = getMultiblockPos(blockPos, pContext.getLevel().getBlockState(blockPos));             if (secondBlockPos != null) {                 createFrozenBlock(pContext, secondBlockPos);             }             createFrozenBlock(pContext, blockPos);             return InteractionResult.SUCCESS;         }         return super.useOn(pContext);     }     public static void createFrozenBlock(UseOnContext pContext, BlockPos blockPos) {         BlockState oldState = pContext.getLevel().getBlockState(blockPos);         BlockEntity oldBlockEntity = oldState.hasBlockEntity() ? pContext.getLevel().getBlockEntity(blockPos) : null;         CompoundTag oldBlockEntityData = oldState.hasBlockEntity() ? oldBlockEntity.serializeNBT() : null;         if (oldBlockEntity != null) {             pContext.getLevel().removeBlockEntity(blockPos);         }         BlockState FrozenBlock = setFrozenBlock(oldState, oldBlockEntity, oldBlockEntityData);         pContext.getLevel().setBlockAndUpdate(blockPos, FrozenBlock);     }     public static BlockState setFrozenBlock(BlockState blockState, @Nullable BlockEntity blockEntity, @Nullable CompoundTag blockEntityData) {         BlockState FrozenBlock = BlockRegister.FROZEN_BLOCK.get().defaultBlockState();         ((FrozenBlock) FrozenBlock.getBlock()).setOldBlockFields(blockState, blockEntity, blockEntityData);         return FrozenBlock;     }  
  • Topics

×
×
  • Create New...

Important Information

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