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); + } + } + } }