From ff59255e636edb447106d90d44e4cfc37a12d539 Mon Sep 17 00:00:00 2001 From: Noudess Date: Tue, 22 Oct 2019 10:45:54 -0400 Subject: [PATCH 1/6] Eye of Zomm needed support in OP_ClientUpdate. --- zone/client_packet.cpp | 16 +++++++++++++++- zone/mob_movement_manager.cpp | 11 ++++++++++- zone/mob_movement_manager.h | 3 ++- zone/spell_effects.cpp | 2 +- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index a7460b5d7..0023883bd 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4384,7 +4384,21 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { /* Update the boat's position on the server, without sending an update */ boat->GMMove(ppu->x_pos, ppu->y_pos, ppu->z_pos, EQ12toFloat(ppu->heading), false); return; - } else return; + } + else { + // Eye of Zomm needs code here to track position of the eye on server + // so that other clients see it. I could add a check here for eye of zomm + // race, to limit this code, but this should handle any client controlled + // mob that gets updates from OP_ClientUpdate + Mob *cmob = entity_list.GetMob(ppu->spawn_id); + if (cmob != nullptr) { + cmob->SetPosition(ppu->x_pos, ppu->y_pos, ppu->z_pos); + cmob->SetHeading(EQ12toFloat(ppu->heading)); + mMovementManager->SendCommandToClients(cmob, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny, nullptr, this); + cmob->CastToNPC()->SaveGuardSpot(glm::vec4(ppu->x_pos, ppu->y_pos, ppu->z_pos, EQ12toFloat(ppu->heading))); + } + } + return; } if (IsDraggingCorpse()) diff --git a/zone/mob_movement_manager.cpp b/zone/mob_movement_manager.cpp index 2f87a1912..5e40dfeee 100644 --- a/zone/mob_movement_manager.cpp +++ b/zone/mob_movement_manager.cpp @@ -727,7 +727,8 @@ void MobMovementManager::SendCommandToClients( float delta_heading, int anim, ClientRange range, - Client* single_client + Client* single_client, + Client* ignore_client ) { if (range == ClientRangeNone) { @@ -745,6 +746,10 @@ void MobMovementManager::SendCommandToClients( continue; } + if (ignore_client && c == ignore_client) { + continue; + } + _impl->Stats.TotalSent++; if (anim != 0) { @@ -769,6 +774,10 @@ void MobMovementManager::SendCommandToClients( continue; } + if (ignore_client && c == ignore_client) { + continue; + } + float distance = c->CalculateDistance(mob->GetX(), mob->GetY(), mob->GetZ()); bool match = false; diff --git a/zone/mob_movement_manager.h b/zone/mob_movement_manager.h index 3c616cc5a..ff7e08436 100644 --- a/zone/mob_movement_manager.h +++ b/zone/mob_movement_manager.h @@ -59,7 +59,8 @@ public: float delta_heading, int anim, ClientRange range, - Client* single_client = nullptr + Client* single_client = nullptr, + Client* ignore_client = nullptr ); float FixHeading(float in); diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 501cf752a..841d6fc0b 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -1561,7 +1561,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove char eye_name[64]; snprintf(eye_name, sizeof(eye_name), "Eye_of_%s", caster->GetCleanName()); int duration = CalcBuffDuration(caster, this, spell_id) * 6; - caster->TemporaryPets(spell_id, nullptr, eye_name, duration); + caster->TemporaryPets(spell_id, nullptr, eye_name, duration, false); } break; } From 8f5bd52e244dcba70a3584b6084222522628088f Mon Sep 17 00:00:00 2001 From: Noudess Date: Wed, 23 Oct 2019 13:58:52 -0400 Subject: [PATCH 2/6] Make sure eye os zomm updates are the actual eye --- zone/client_packet.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 0023883bd..829ca6a95 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4392,10 +4392,17 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { // mob that gets updates from OP_ClientUpdate Mob *cmob = entity_list.GetMob(ppu->spawn_id); if (cmob != nullptr) { - cmob->SetPosition(ppu->x_pos, ppu->y_pos, ppu->z_pos); - cmob->SetHeading(EQ12toFloat(ppu->heading)); - mMovementManager->SendCommandToClients(cmob, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny, nullptr, this); - cmob->CastToNPC()->SaveGuardSpot(glm::vec4(ppu->x_pos, ppu->y_pos, ppu->z_pos, EQ12toFloat(ppu->heading))); + // Make sure it's their eye.. + char eye_name[64]; + snprintf(eye_name, sizeof(eye_name),"Eye of %s",GetCleanName()); + if (!strcmp(eye_name, cmob->GetCleanName())) { + cmob->SetPosition(ppu->x_pos, ppu->y_pos, ppu->z_pos); + cmob->SetHeading(EQ12toFloat(ppu->heading)); + mMovementManager->SendCommandToClients(cmob, 0.0, 0.0, 0.0, + 0.0, 0, ClientRangeAny, nullptr, this); + cmob->CastToNPC()->SaveGuardSpot(glm::vec4(ppu->x_pos, + ppu->y_pos, ppu->z_pos, EQ12toFloat(ppu->heading))); + } } } return; From 194c61a4672291e921f6a34aa3f6b2cd76b4dd6a Mon Sep 17 00:00:00 2001 From: Noudess Date: Sat, 26 Oct 2019 10:42:00 -0400 Subject: [PATCH 3/6] Modify eye of zomm support to be more efficient. --- common/spdat.h | 1 + zone/aa.cpp | 8 +++++++- zone/client.cpp | 1 + zone/client.h | 2 ++ zone/client_packet.cpp | 9 +++------ zone/spell_effects.cpp | 9 +++++++++ 6 files changed, 23 insertions(+), 7 deletions(-) diff --git a/common/spdat.h b/common/spdat.h index 416f63561..c88942018 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -32,6 +32,7 @@ #define SPELL_HARM_TOUCH2 2821 #define SPELL_IMP_HARM_TOUCH 2774 #define SPELL_NPC_HARM_TOUCH 929 +#define SPELL_EYE_OF_ZOMM 323 #define EFFECT_COUNT 12 diff --git a/zone/aa.cpp b/zone/aa.cpp index b4977a5b9..09a8d0306 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -109,6 +109,8 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u glm::vec2(8, 8), glm::vec2(-8, 8), glm::vec2(8, -8), glm::vec2(-8, -8) }; + NPC* swarm_pet_npc; + while (summon_count > 0) { int pet_duration = pet.duration; if (duration_override > 0) @@ -122,7 +124,7 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u memcpy(npc_dup, made_npc, sizeof(NPCType)); } - NPC* swarm_pet_npc = new NPC( + swarm_pet_npc = new NPC( (npc_dup != nullptr) ? npc_dup : npc_type, //make sure we give the NPC the correct data pointer 0, GetPosition() + glm::vec4(swarmPetLocations[summon_count], 0.0f, 0.0f), @@ -162,6 +164,10 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u summon_count--; } + if (IsClient() && spell_id == SPELL_EYE_OF_ZOMM) { + CastToClient()->SetControlledMobId(swarm_pet_npc->GetID()); + } + //the target of these swarm pets will take offense to being cast on... if (targ != nullptr) targ->AddToHateList(this, 1, 0); diff --git a/zone/client.cpp b/zone/client.cpp index 3c16b8a9b..9a517b380 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -265,6 +265,7 @@ Client::Client(EQStreamInterface* ieqs) PendingTranslocate = false; PendingSacrifice = false; controlling_boat_id = 0; + controlled_mob_id = 0; if (!RuleB(Character, PerCharacterQglobalMaxLevel) && !RuleB(Character, PerCharacterBucketMaxLevel)) { SetClientMaxLevel(0); diff --git a/zone/client.h b/zone/client.h index 3ade2e6fe..be4b12341 100644 --- a/zone/client.h +++ b/zone/client.h @@ -796,6 +796,7 @@ public: void SummonHorse(uint16 spell_id); void SetHorseId(uint16 horseid_in); + inline void SetControlledMobId(uint16 mob_id_in) { controlled_mob_id = mob_id_in; } uint16 GetHorseId() const { return horseId; } bool CanMedOnHorse(); @@ -1431,6 +1432,7 @@ private: bool berserk; bool dead; uint16 controlling_boat_id; + uint16 controlled_mob_id; uint16 TrackingID; uint16 CustomerID; uint16 TraderID; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 829ca6a95..79361b637 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4390,12 +4390,9 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { // so that other clients see it. I could add a check here for eye of zomm // race, to limit this code, but this should handle any client controlled // mob that gets updates from OP_ClientUpdate - Mob *cmob = entity_list.GetMob(ppu->spawn_id); - if (cmob != nullptr) { - // Make sure it's their eye.. - char eye_name[64]; - snprintf(eye_name, sizeof(eye_name),"Eye of %s",GetCleanName()); - if (!strcmp(eye_name, cmob->GetCleanName())) { + if (ppu->spawn_id == controlled_mob_id) { + Mob *cmob = entity_list.GetMob(ppu->spawn_id); + if (cmob != nullptr) { cmob->SetPosition(ppu->x_pos, ppu->y_pos, ppu->z_pos); cmob->SetHeading(EQ12toFloat(ppu->heading)); mMovementManager->SendCommandToClients(cmob, 0.0, 0.0, 0.0, diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 841d6fc0b..9cc58ed60 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -4039,6 +4039,15 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses) SetLevel(GetOrigLevel()); break; } + + case SE_EyeOfZomm: + { + if (IsClient()) + { + CastToClient()->SetControlledMobId(0); + } + } + } } From 566e6ea307c9708863ef931924c1de021a2fa59b Mon Sep 17 00:00:00 2001 From: Noudess Date: Mon, 28 Oct 2019 19:48:31 -0400 Subject: [PATCH 4/6] Added support for all SE_EyeOfZomm and some other small changes --- zone/aa.cpp | 6 +++--- zone/client_packet.cpp | 2 +- zone/mob.cpp | 2 +- zone/mob.h | 2 +- zone/spell_effects.cpp | 6 +++++- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/zone/aa.cpp b/zone/aa.cpp index 09a8d0306..472f90d5d 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -36,7 +36,7 @@ Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) extern QueryServ* QServ; -void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, uint32 duration_override, bool followme, bool sticktarg) { +void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, uint32 duration_override, bool followme, bool sticktarg, uint16 *eye_id) { //It might not be a bad idea to put these into the database, eventually.. @@ -164,8 +164,8 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u summon_count--; } - if (IsClient() && spell_id == SPELL_EYE_OF_ZOMM) { - CastToClient()->SetControlledMobId(swarm_pet_npc->GetID()); + if (IsClient() && eye_id != nullptr) { + *eye_id = swarm_pet_npc->GetID(); } //the target of these swarm pets will take offense to being cast on... diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 79361b637..837d83864 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -10784,7 +10784,7 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app) } char buf[16]; - sprintf(buf, "%d\0", popup_response->popupid); + sprintf(buf, "%d", popup_response->popupid); parse->EventPlayer(EVENT_POPUP_RESPONSE, this, buf, 0); diff --git a/zone/mob.cpp b/zone/mob.cpp index edaf87001..d5b95a298 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -1208,7 +1208,7 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) // Changing the second string made no visible difference sprintf(ns->spawn.DestructibleName2, "%s", ns->spawn.name); // Putting a string in the final one that was previously empty had no visible effect. - sprintf(ns->spawn.DestructibleString, ""); + ns->spawn.DestructibleString[0] = '\0'; // Sets damage appearance level of the object. ns->spawn.DestructibleAppearance = luclinface; // Was 0x00000000 diff --git a/zone/mob.h b/zone/mob.h index 21003fbd6..bcf3adcca 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -762,7 +762,7 @@ public: virtual void UnStun(); inline void Silence(bool newval) { silenced = newval; } inline void Amnesia(bool newval) { amnesiad = newval; } - void TemporaryPets(uint16 spell_id, Mob *target, const char *name_override = nullptr, uint32 duration_override = 0, bool followme=true, bool sticktarg=false); + void TemporaryPets(uint16 spell_id, Mob *target, const char *name_override = nullptr, uint32 duration_override = 0, bool followme=true, bool sticktarg=false, uint16 *controlled_pet_id = nullptr); void TypesTemporaryPets(uint32 typesid, Mob *target, const char *name_override = nullptr, uint32 duration_override = 0, bool followme=true, bool sticktarg=false); void WakeTheDead(uint16 spell_id, Mob *target, uint32 duration); void Spin(); diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 9cc58ed60..406a801d0 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -1561,7 +1561,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove char eye_name[64]; snprintf(eye_name, sizeof(eye_name), "Eye_of_%s", caster->GetCleanName()); int duration = CalcBuffDuration(caster, this, spell_id) * 6; - caster->TemporaryPets(spell_id, nullptr, eye_name, duration, false); + uint16 eye_id=0; + caster->TemporaryPets(spell_id, nullptr, eye_name, duration, false, false, &eye_id); + if (eye_id != 0) { + caster->CastToClient()->SetControlledMobId(eye_id); + } } break; } From a7bcc12eb6ccb28b74d4837b2b28ed9a543ca5cb Mon Sep 17 00:00:00 2001 From: Noudess Date: Mon, 28 Oct 2019 19:50:28 -0400 Subject: [PATCH 5/6] Removed constant no longer used --- common/spdat.h | 1 - 1 file changed, 1 deletion(-) diff --git a/common/spdat.h b/common/spdat.h index c88942018..416f63561 100644 --- a/common/spdat.h +++ b/common/spdat.h @@ -32,7 +32,6 @@ #define SPELL_HARM_TOUCH2 2821 #define SPELL_IMP_HARM_TOUCH 2774 #define SPELL_NPC_HARM_TOUCH 929 -#define SPELL_EYE_OF_ZOMM 323 #define EFFECT_COUNT 12 From f012d13f0ce6db17ae0a7f1eb522167ad5cf5499 Mon Sep 17 00:00:00 2001 From: Noudess Date: Thu, 7 Nov 2019 09:31:50 -0500 Subject: [PATCH 6/6] Some quick additions of sanity checks for pointers and variables --- zone/aa.cpp | 4 ++-- zone/client_packet.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/zone/aa.cpp b/zone/aa.cpp index 472f90d5d..09a954331 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -109,7 +109,7 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u glm::vec2(8, 8), glm::vec2(-8, 8), glm::vec2(8, -8), glm::vec2(-8, -8) }; - NPC* swarm_pet_npc; + NPC* swarm_pet_npc = nullptr; while (summon_count > 0) { int pet_duration = pet.duration; @@ -164,7 +164,7 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u summon_count--; } - if (IsClient() && eye_id != nullptr) { + if (swarm_pet_npc && IsClient() && eye_id != nullptr) { *eye_id = swarm_pet_npc->GetID(); } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 837d83864..0bb319a20 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4365,7 +4365,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { /* Boat handling */ if (ppu->spawn_id != GetID()) { /* If player is controlling boat */ - if (ppu->spawn_id == controlling_boat_id) { + if (ppu->spawn_id && ppu->spawn_id == controlling_boat_id) { Mob *boat = entity_list.GetMob(controlling_boat_id); if (boat == 0) { controlling_boat_id = 0;