Added more changes so mobs armor will appear correctly (pc races only)

when the spawn vie gm command or normally with loot tables that equip.

Refined previous changes that fixed the issue with zoning in and not seeing
previosuly spawned armor by sharing the same module.
This commit is contained in:
Paul Coene 2015-04-02 13:25:12 -04:00
parent 026278504f
commit bf93d72a43
3 changed files with 40 additions and 15 deletions

View File

@ -618,6 +618,7 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue)
EQApplicationPacket *app = new EQApplicationPacket; EQApplicationPacket *app = new EQApplicationPacket;
npc->CreateSpawnPacket(app, npc); npc->CreateSpawnPacket(app, npc);
QueueClients(npc, app); QueueClients(npc, app);
npc->SendArmorAppearance();
safe_delete(app); safe_delete(app);
} else { } else {
NewSpawn_Struct *ns = new NewSpawn_Struct; NewSpawn_Struct *ns = new NewSpawn_Struct;
@ -726,10 +727,16 @@ void EntityList::CheckSpawnQueue()
EQApplicationPacket *outapp = 0; EQApplicationPacket *outapp = 0;
iterator.Reset(); iterator.Reset();
NewSpawn_Struct *ns;
while(iterator.MoreElements()) { while(iterator.MoreElements()) {
outapp = new EQApplicationPacket; outapp = new EQApplicationPacket;
Mob::CreateSpawnPacket(outapp, iterator.GetData()); ns = iterator.GetData();
Mob::CreateSpawnPacket(outapp, ns);
QueueClients(0, outapp); QueueClients(0, outapp);
auto it = npc_list.find(ns->spawn.spawnId);
NPC *pnpc = it->second;
pnpc->SendArmorAppearance();
safe_delete(outapp); safe_delete(outapp);
iterator.RemoveCurrent(); iterator.RemoveCurrent();
} }
@ -1179,20 +1186,9 @@ void EntityList::SendZoneSpawnsBulk(Client *client)
bzsp->AddSpawn(&ns); bzsp->AddSpawn(&ns);
} }
// On NPCs wearing gear from loottable or previously traded // Despite being sent in the OP_ZoneSpawns packet, the client
// to them, mass spawn does not properly update the visual look. // does not display worn armor correctly so display it.
// (Bulk packet sends the same info - client just doesn't use it. spawn->SendArmorAppearance(client);
// except on primary/secondary - tested on multiple client types)
// Do that using a Wear Change now.
if (!spawn->IsClient()) {
const Item_Struct *item;
for (int i=0; i< 7 ; ++i) {
item=database.GetItem(spawn->GetEquipment(i));
if (item != 0) {
spawn->SendWearChange(i,client);
}
}
}
} }
} }
safe_delete(bzsp); safe_delete(bzsp);

View File

@ -2552,6 +2552,34 @@ uint32 NPC::GetEquipment(uint8 material_slot) const
return equipment[invslot]; return equipment[invslot];
} }
void Mob::SendArmorAppearance(Client *one_client)
{
// one_client of 0 means sent to all clients
//
// Despite the fact that OP_NewSpawn and OP_ZoneSpawns include the
// armor being worn and its mats, the client doesn't update the display
// on arrival of these packets reliably.
//
// Send Wear changes if mob is a PC race and item is an armor slot.
// The other packets work for primary/secondary.
if (IsPlayerRace(race))
{
if (!IsClient())
{
const Item_Struct *item;
for (int i=0; i< 7 ; ++i)
{
item=database.GetItem(GetEquipment(i));
if (item != 0)
{
SendWearChange(i,one_client);
}
}
}
}
}
void Mob::SendWearChange(uint8 material_slot, Client *one_client) void Mob::SendWearChange(uint8 material_slot, Client *one_client)
{ {
EQApplicationPacket* outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct)); EQApplicationPacket* outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct));

View File

@ -171,6 +171,7 @@ public:
void SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5, void SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5,
Client *specific_target=nullptr); Client *specific_target=nullptr);
void SendTargetable(bool on, Client *specific_target = nullptr); void SendTargetable(bool on, Client *specific_target = nullptr);
virtual void SendArmorAppearance(Client *one_client = nullptr);
virtual void SendWearChange(uint8 material_slot, Client *one_client = nullptr); virtual void SendWearChange(uint8 material_slot, Client *one_client = nullptr);
virtual void SendTextureWC(uint8 slot, uint16 texture, uint32 hero_forge_model = 0, uint32 elite_material = 0, virtual void SendTextureWC(uint8 slot, uint16 texture, uint32 hero_forge_model = 0, uint32 elite_material = 0,
uint32 unknown06 = 0, uint32 unknown18 = 0); uint32 unknown06 = 0, uint32 unknown18 = 0);