Merge pull request #395 from noudess/master

Some illusions and some NPC gear not showing up on zone-in & initial spawn if in zone when it occurs
This commit is contained in:
Alex 2015-04-28 16:34:01 -07:00
commit 41f3b721d6
4 changed files with 73 additions and 7 deletions

View File

@ -47,6 +47,8 @@
#define IKSAR 128
#define VAHSHIR 130
#define CONTROLLED_BOAT 141
#define MINOR_ILL_OBJ 142
#define TREE 143
#define IKSAR_SKELETON 161
#define FROGLOK 330
#define FROGLOK2 74 // Not sure why /who all reports race as 74 for frogloks

View File

@ -618,6 +618,7 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue)
EQApplicationPacket *app = new EQApplicationPacket;
npc->CreateSpawnPacket(app, npc);
QueueClients(npc, app);
npc->SendArmorAppearance();
safe_delete(app);
} else {
NewSpawn_Struct *ns = new NewSpawn_Struct;
@ -726,10 +727,16 @@ void EntityList::CheckSpawnQueue()
EQApplicationPacket *outapp = 0;
iterator.Reset();
NewSpawn_Struct *ns;
while(iterator.MoreElements()) {
outapp = new EQApplicationPacket;
Mob::CreateSpawnPacket(outapp, iterator.GetData());
ns = iterator.GetData();
Mob::CreateSpawnPacket(outapp, ns);
QueueClients(0, outapp);
auto it = npc_list.find(ns->spawn.spawnId);
NPC *pnpc = it->second;
pnpc->SendArmorAppearance();
safe_delete(outapp);
iterator.RemoveCurrent();
}
@ -1149,19 +1156,39 @@ void EntityList::SendZoneSpawnsBulk(Client *client)
NewSpawn_Struct ns;
Mob *spawn;
uint32 maxspawns = 100;
EQApplicationPacket *app;
if (maxspawns > mob_list.size())
maxspawns = mob_list.size();
BulkZoneSpawnPacket *bzsp = new BulkZoneSpawnPacket(client, maxspawns);
int32 race=-1;
for (auto it = mob_list.begin(); it != mob_list.end(); ++it) {
spawn = it->second;
if (spawn && spawn->InZone()) {
if (spawn->IsClient() && (spawn->CastToClient()->GMHideMe(client) ||
spawn->CastToClient()->IsHoveringForRespawn()))
continue;
memset(&ns, 0, sizeof(NewSpawn_Struct));
spawn->FillSpawnStruct(&ns, client);
bzsp->AddSpawn(&ns);
race = spawn->GetRace();
// Illusion races on PCs don't work as a mass spawn
// But they will work as an add_spawn AFTER CLIENT_CONNECTED.
if (spawn->IsClient() && (race == MINOR_ILL_OBJ || race == TREE)) {
app = new EQApplicationPacket;
spawn->CreateSpawnPacket(app);
client->QueuePacket(app, true, Client::CLIENT_CONNECTED);
safe_delete(app);
}
else {
memset(&ns, 0, sizeof(NewSpawn_Struct));
spawn->FillSpawnStruct(&ns, client);
bzsp->AddSpawn(&ns);
}
// Despite being sent in the OP_ZoneSpawns packet, the client
// does not display worn armor correctly so display it.
spawn->SendArmorAppearance(client);
}
}
safe_delete(bzsp);

View File

@ -2552,7 +2552,35 @@ uint32 NPC::GetEquipment(uint8 material_slot) const
return equipment[invslot];
}
void Mob::SendWearChange(uint8 material_slot)
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)
{
EQApplicationPacket* outapp = new EQApplicationPacket(OP_WearChange, sizeof(WearChange_Struct));
WearChange_Struct* wc = (WearChange_Struct*)outapp->pBuffer;
@ -2564,7 +2592,15 @@ void Mob::SendWearChange(uint8 material_slot)
wc->color.Color = GetEquipmentColor(material_slot);
wc->wear_slot_id = material_slot;
entity_list.QueueClients(this, outapp);
if (!one_client)
{
entity_list.QueueClients(this, outapp);
}
else
{
one_client->QueuePacket(outapp, false, Client::CLIENT_CONNECTED);
}
safe_delete(outapp);
}

View File

@ -171,7 +171,8 @@ public:
void SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5,
Client *specific_target=nullptr);
void SendTargetable(bool on, Client *specific_target = nullptr);
virtual void SendWearChange(uint8 material_slot);
virtual void SendArmorAppearance(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,
uint32 unknown06 = 0, uint32 unknown18 = 0);
virtual void SetSlotTint(uint8 material_slot, uint8 red_tint, uint8 green_tint, uint8 blue_tint);