Jump to content

Recommended Posts

Posted (edited)

I made sure my item spawns my entity only on the server side, however when testing I see the impact method ran 3 times, 2 times for the client and 1 time on the server. Note that the one of the client methods returns the correct value, while the other collides with the player, which I specified not to. I'm pretty sure the collision happens because the caster variable is null, however I don't know why.

 

Here's the base class: https://pastebin.com/9ezYndWt

The entity I'm spawning: https://pastebin.com/7PsYLHxx

And the item that spawns the entity: https://pastebin.com/muPFHwMu

Edited by Melonslise
Posted (edited)
7 minutes ago, diesieben07 said:

Show your code.

Sorry I created the thread by accident before I could finish writing. The code is in the first post.

Edited by Melonslise
Posted
12 minutes ago, diesieben07 said:

What exactly makes you think the entity is spawned on the client?

Take a look at the EntityFirebolt class and it's onImpact() method. The sysout gets printed 3 times when I right click with my item, 2 times on the client and once on the server. Its seems that the first print on the client gives me a correct ray trace entity, however the second print on the client tells me that it collided with the player, which I specified no to happen in the base EntityProjectile class.

Posted (edited)
9 minutes ago, diesieben07 said:

The client does not magically know the value of either caster or casterName. Moreover, do not use usernames, they can change. Only use the UUID.

Well the thing is that I do not spawn the entity on the client, so it doesn't need to know those values. Also I have no idea why there are 2 client entities. I use usernames because I just copied the code from EntityThrowable.

Edited by Melonslise
Posted (edited)
41 minutes ago, diesieben07 said:

You don't, but Minecraft does. Every entity is spawned on the client, otherwise you would not be able to see any on screen.

 

There aren't. The entity is just colliding twice.

 

This does not make it any less broken.

So you think that vanilla code is broken?

Anyway, I think I understand what the problem is. It looks like I'm killing off the entity only on the server side so the client entity keeps moving. But in the vanilla code entities are always killed on the server side. Is vanilla broken or am I missing something? I thought the server would update the client automatically.

Edited by Melonslise
Posted (edited)
15 minutes ago, diesieben07 said:

Not sure what you are saying. Which part of vanilla is broken?

EDIT: Actually no, it looks like my client side entity isn't receiving the player who cast the spell.

Edited by Melonslise
Posted (edited)
40 minutes ago, diesieben07 said:

You need to use the EntityDataManager. Check out the examples in vanilla.

So I'm going to need to create a new DataParameter, register it and then get/set the player using the entity DataManager? Does that mean I don't need to create variables in the entity class and instead just use DataManager.get/set? Also why don't the vanilla classes like EntityFireball/EntityThrowable use DataManager?

Edited by Melonslise
Posted (edited)
3 hours ago, diesieben07 said:

The client does not magically know the value of either caster or casterName. Moreover, do not use usernames, they can change. Only use the UUID.

The DataParameter cannot store Entities so I'll have to store player by either name or UUID. I'm going to use UUID, but I'd like to know how to obtain a player's UUID and if I can compare an EntityLiving's UUID with a player's.

Edited by Melonslise
Posted
29 minutes ago, diesieben07 said:

On the server: WorldServer::getEntityFromUuid. For the client you are better off using the entity ID (Entity::getEntityId, World::getEntityByID). The ID is guaranteed to stay constant while the entity object is alive and it is consistent between client and server.

So get the player/entity on the server using getEntityFromUUID (for players better use PlayerList::getPlayerByUUID) and then send the ID to the client.

Is there any way to get the list of all players on the server? Since servers can have different worlds afaik.

Posted
1 hour ago, Melonslise said:

Is there any way to get the list of all players on the server? Since servers can have different worlds afaik.

 

Use PlayerList#getPlayers to get a list of players on the server or PlayerList#getPlayerByUUID to find a player by their UUID. Use MinecraftServer#getPlayerList to get the server's PlayerList instance.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Posted (edited)

So to pass the entity's id I'll need yet another DataManager or is there an easier way?

Here's the method code:

 

@Nullable
public EntityLivingBase getCaster()
{
	if(this.worldObj instanceof WorldServer)
	{
		return ((WorldServer) this.worldObj).getEntityFromUuid(this.getCasterUUID());
	}
	else
	{
		?
	}
}
	

 

Edited by Melonslise
Posted
4 hours ago, diesieben07 said:

You only need the ID in the data manager.

I'm getting a nullpointer error when trying to retrieve an optional uuid from the DataManager. Do you have any ideas?

Posted
6 minutes ago, diesieben07 said:

Post updated code.

And you should not have the UUID in the data manager, only the ID.

The compiler is pointing at the getCasterUUID() method. I am going to add the ID to the DataManager once I get this fixed. I don't understand why you're recommending to use regular ID, though, since it's quite unreliable afaik. Can't the client get an entity's UUID?

Posted (edited)
4 minutes ago, diesieben07 said:

The client cannot obtain an Entity by UUID in an efficient manner, you would have to loop through every loaded entity and check it's UUID.

The ID is not unreliable at all, if used correctly.

Ow sorry I forgot to add the pastebin link.

Edited by Melonslise
Posted
1 hour ago, diesieben07 said:

Ok, here is how you need to go about this:

  • Have a normal field for the owner's UUID, saved to and loaded from NBT (this is in fact the only thing you save to NBT for the owner).
  • Have a data parameter for the owner's entity ID.
  • Have a normal field for the owner's Entity, wrapped in a WeakReference to avoid keeping it loaded. In a getOwner method you first check if the reference to the owner is valid and if so, return it. Otherwise you you get the owner by UUID (on the server) or the ID (on the client).

I did what you told me to (I was going to anyway) and I'm now getting an error when retrieving the int entity id from the DataManager. So basically the same problem again.

Posted
Just now, diesieben07 said:

How should it know what value to set it to? Magic?

Well the DataManager#register method takes a value param, so I thought that's what would be stored.

Posted
Just now, diesieben07 said:

Ok. Which error are you getting?

I'm getting a ticking entity: nullpointer error and the compiler is pointing at my getCaster() method at line 220 where I get the key from DataManager.

Posted (edited)
2 hours ago, diesieben07 said:

Use the debugger to find out what is null

I used the debugger to check the entries in the entity's DataManager and it looks like my integer id value is not on the list. I saw six entries each corresponding to each DataParameter declared in in the Entity base class. I don't understand why mine isn't there though.

Edited by Melonslise
Posted
1 minute ago, diesieben07 said:

You are not registering the parameter in the constructor that is called on the client.

So does this mean I'll need to spawn the entity on both sides?

Posted
9 minutes ago, diesieben07 said:

No. That is not at all what I said. You need to register the parameter on both sides. Currently you only do it on the server.

Right, so how do I do that? Through packets? Then why don't the vanilla mobs use packets?

Posted
3 minutes ago, diesieben07 said:

The vanilla mobs do use packets, but that's not what you need here.

 

The issue is that the constructor that is used on the client completely ignores the data parameter.

Why would it if I made it static? How do I fix that?

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.