Jump to content

Player capability data reset on respawn


Toma™

Recommended Posts

Okay, it's me again with another problem. I implemented my custom capability and attached it to player, but every time the player respawns, it should write some data into capability, however it doesn't work. I made custom overlay rendering which should display the data, but on respawn I see the data set to the value I want and next tick the data is gone. I managed to make the data persist after player disconnects so my syncing packet should be okay. The only problem I have is the respawn event. I subscribed to PlayerEvent.Clone (on server, since I think it is supposed to be handled from server, but I'm not sure about that) and registered it in server proxy.

There's the related code:

Spoiler

	@SubscribeEvent
	public void onPlayerClone(PlayerEvent.Clone e)
	{
		if(e.isWasDeath())
		{
			IPlayerData data = e.getEntityPlayer().getCapability(PlayerDataProvider.PLAYER_DATA, null);
			data.setThirst(20f);
			data.setBloodLevel(100f);
			data.setInfectionLevel(0);
			data.setBleeding(false);
			
			PacketSPSyncPlayerData packet = new PacketSPSyncPlayerData();
			packet.setThirst(data.getThirst());
			packet.setBlood(data.getBloodLevel());
			packet.setInfection(data.getInfectionLevel());
			packet.setBleeding(data.isBleeding());
			PacketHandler.INSTANCE.sendTo(packet, (EntityPlayerMP)e.getEntityPlayer());
		}
	}

 

 

and the packet just in case: (it is registered for client side)

Spoiler

public class PacketSPSyncPlayerData implements IMessage, IMessageHandler<PacketSPSyncPlayerData, IMessage>
{
	private float thirst;
	private float blood;
	private int infection;
	private boolean bleeding;
	
	@Override
	public void toBytes(ByteBuf buf)
	{
		buf.writeFloat(this.thirst);
		buf.writeFloat(this.blood);
		buf.writeInt(this.infection);
		buf.writeBoolean(this.bleeding);
	}
	
	@Override
	public void fromBytes(ByteBuf buf) 
	{
		thirst = buf.readFloat();
		blood = buf.readFloat();
		infection = buf.readInt();
		bleeding = buf.readBoolean();
	}
	
	@Override
	public IMessage onMessage(PacketSPSyncPlayerData message, MessageContext ctx)
	{
		if(ctx.side.isClient())
		{
			EntityPlayerSP player = Minecraft.getMinecraft().player;
			if(player != null)
			{
				if(player.getCapability(PlayerDataProvider.PLAYER_DATA, null) != null)
				{
					IPlayerData data = player.getCapability(PlayerDataProvider.PLAYER_DATA, null);
					data.setThirst(message.thirst);
					data.setBloodLevel(message.blood);
					data.setInfectionLevel(message.infection);
					data.setBleeding(message.bleeding);
				}
			}
		}
		return null;
	}
	
	public float setThirst(float thirst)
	{
		return this.thirst = thirst;
	}
	
	public float getThirst()
	{
		return this.thirst;
	}
	
	public void setBlood(float blood)
	{
		this.blood = blood;
	}
	
	public float getBlood()
	{
		return blood;
	}
	
	public void setInfection(int infection)
	{
		this.infection = infection;
	}
	
	public int getInfection()
	{
		return infection;
	}
	
	public void setBleeding(boolean bleeding) 
	{
		this.bleeding = bleeding;
	}
	
	public boolean isBleeding()
	{
		return bleeding;
	}

 

What am I doing wrong here?

Link to comment
Share on other sites

33 minutes ago, diesieben07 said:

@SidedProxy is for distinguishing physical sides. That is not what you want here. The event only fires on the logical server, so register it from your main mod class.

I suggest refreshing your info on how sides work: https://mcforge.readthedocs.io/en/latest/concepts/sides/.

Okay I changed it as you suggested. 

 

However now I have to worry about the issue I described above. 

Link to comment
Share on other sites

2 minutes ago, diesieben07 said:

This will crash on a dedicated server. Code that is specific to a physical side (client in this case) must be encapsulated using @SidedProxy.

 

Problematic code, Issue 16.

Oh well, I didn't know that. For some reason I thought that the ctx.side.isClient will prevent that

 

4 minutes ago, diesieben07 said:

PlayerEvent.Clone is not the right event to send packets or set any data. It's sole purpose is to copy data from the player entity that died to the new player entity. Do not use it for anything else. If you want to do something on respawn, use PlayerEvent.PlayerRespawnEvent.

But this still has to be used to copy the data when player switches dimensions, am I right?

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.



×
×
  • Create New...

Important Information

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