1. The forums will be archived and moved to a read only mode in about 2 weeks (mid march).

Mob Equipment

Discussion in 'Development' started by kniffo80, Mar 3, 2017.

  1. kniffo80

    kniffo80 Silverfish

    Messages:
    24
    GitHub:
    kniffo80
    Hi guys,

    I'm currently testing out some mob equipment. As far as I have it running now I am working with
    MobArmorEquipmentPacket which is sent to all players when the entity wears armor:

    PHP:
    $pk = new MobArmorEquipmentPacket();
            
    $pk->eid $this->entity->getId();
            
    $pk->slots = [
                
    $this->boots !== null $this->boots->getId() : ItemIds::AIR,
                
    $this->leggings !== null $this->leggings->getId() : ItemIds::AIR,
                
    $this->chestplate !== null $this->chestplate->getId() : ItemIds::AIR,
                
    $this->helmet !== null $this->helmet->getId() : ItemIds::AIR
            
    ];
            
    $pk->encode();
            
    $pk->isEncoded true;
            
    $this->sendPacketToPlayers($pk);
    This works just fine when Entity is spawned. I can see that the Entity wears some armor stuff. But when logging out and logging in back again - of course - the entity doesn't wear any items anymore. So my thoughts were: when a player logs in - send a packet for each entity which has equipped something to the player. Is that correct? I don't think so.

    My specific question: do we need to set data properties on the entity additionally - or is NBT data sufficient? The NBT data then looks like this:

    PHP:
    // feet, legs, chest, head - store armor content to NBT
            
    $armor[0] = new CompoundTag("0", [
                
    "Count" => new IntTag("Count"1),
                
    "Damage" => new IntTag("Damage"10),
                
    "id" => new IntTag("id"$this->boots !== null $this->boots->getId() : ItemIds::AIR),
            ]);
            
    $armor[1] = new CompoundTag("1", [
                
    "Count" => new IntTag("Count"1),
                
    "Damage" => new IntTag("Damage"10),
                
    "id" => new IntTag("id"$this->leggings !== null $this->leggings->getId() : ItemIds::AIR),
            ]);
            
    $armor[2] = new CompoundTag("2", [
                
    "Count" => new IntTag("Count"1),
                
    "Damage" => new IntTag("Damage"10),
                
    "id" => new IntTag("id"$this->chestplate !== null $this->chestplate->getId() : ItemIds::AIR),
            ]);
            
    $armor[3] = new CompoundTag("3", [
                
    "Count" => new IntTag("Count"1),
                
    "Damage" => new IntTag("Damage"10),
                
    "id" => new IntTag("id"$this->helmet !== null $this->helmet->getId() : ItemIds::AIR),
            ]);

            
    $this->entity->namedtag->ArmorItems = new ListTag(self::NBT_KEY_ARMOR_ITEMS$armor);
    This are just examples!

    I assume that the client doesn't really bother about NBT - as far as i saw - NBT is only used for storing / reading data from NBT store. So I assume that I need to set data properties or data flags on the entity. But at the moment I have no clue which to set.

    Any help would be really appreciated.
     
    Last edited: Mar 3, 2017
  2. robske_110 (Tim)

    robske_110 (Tim) Wither Skeleton Poggit Reviewer

    Messages:
    1,342
    GitHub:
    robske110
    This is a perfect example of the confusion created by using NBT for in memory stuff, Blame :shoghicp:

    NBT is, like you said, only to be used for storage. So actually what you want to do is store the armoritems on the entity (with NBT) and read them out on each player join and then send the MobArmorEquipmentPacket using the data you read. PM apparently doesn't do that yet, proper entity support is ToDo.
     
    jasonwynn10 likes this.
  3. kniffo80

    kniffo80 Silverfish

    Messages:
    24
    GitHub:
    kniffo80
    Perfect answer. Thanks a lot.
     
  4. kniffo80

    kniffo80 Silverfish

    Messages:
    24
    GitHub:
    kniffo80
    I've to say that sending the MobArmorEquipmentPacket/MobEquipmentPacket doesn't work with PlayerJoinEvent. It seems, that the Entity is not completely spawned (when the server is restarted e.g.) or there's something not really initialized with the Player - so the Packet seems to be not recognized by the client - the entities just hold nothing.

    What i made now: every time a player joins - all entities that have equipment set a flag which is used in onUpdate of the entity. When the flag is set - the entity "broadcasts" its equipment again to all players. This is not nice and a workaround - but for now i don't see another way to do it.

    Just wanted to report back - in case any other developer stumbles across this.
     
  5. jasonwynn10

    jasonwynn10 Moderator Poggit Reviewer

    Messages:
    1,489
    GitHub:
    jasonwynn10
    Maybe call a delayed task in the event? that should give the player enough time to intiialize
     
  6. kniffo80

    kniffo80 Silverfish

    Messages:
    24
    GitHub:
    kniffo80
    It's always a hassle with delayed tasks. Sometimes it takes longer to initialize, sometimes shorter. I've enough experience to tell you, that when it comes to async tasks - you have to keep a lot of things in mind. And additionally, there can be graphical glitches (you see an entity wearing nothing, a second later - it wears something) - of course it's also possible with the onUpdate method. But the onUpdate workaround is more specific and more "safe" I would say.

    But anyway - your proposal may also be a way to go - thanks for your help ;)
     
  7. jasonwynn10

    jasonwynn10 Moderator Poggit Reviewer

    Messages:
    1,489
    GitHub:
    jasonwynn10
    I'm not talking about async tasks. Just run a delayed task a few ticks after the join event so that the player can load in the surrounding chunks before trying to send them the entities with their data.
     
  8. kniffo80

    kniffo80 Silverfish

    Messages:
    24
    GitHub:
    kniffo80
    I'll give it a try this weekend ;)

    EDIT: works. Need some more testing. But in general the delayed approach works. Thanks again for your thoughts!
     
    Last edited: Mar 3, 2017
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.