From fe8c55ac631c6d346d1c8ea42c369511007ca693 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Tue, 18 Jul 2017 17:52:39 -0400 Subject: [PATCH] Auras now zone --- utils/sql/git/required/2017_07_xx_aura.sql | 8 ++++++ zone/aura.cpp | 16 ++++++++++- zone/aura.h | 6 ++++ zone/client_packet.cpp | 2 ++ zone/client_process.cpp | 2 ++ zone/mob.h | 2 ++ zone/zonedb.cpp | 32 ++++++++++++++++++++++ zone/zonedb.h | 2 ++ 8 files changed, 69 insertions(+), 1 deletion(-) diff --git a/utils/sql/git/required/2017_07_xx_aura.sql b/utils/sql/git/required/2017_07_xx_aura.sql index 9437d1c7c..96ea45185 100644 --- a/utils/sql/git/required/2017_07_xx_aura.sql +++ b/utils/sql/git/required/2017_07_xx_aura.sql @@ -12,3 +12,11 @@ CREATE TABLE `auras` ( `cast_time` INT(10) NOT NULL DEFAULT 0, PRIMARY KEY(`type`) ) + +CREATE TABLE `character_auras` ( + `id` INT(10) NOT NULL, + `slot` TINYINT(10) NOT NULL, + `spell_id` INT(10) NOT NULL, + PRIMARY KEY (`id`, `slot`) +); + diff --git a/zone/aura.cpp b/zone/aura.cpp index 47f486bdd..0bbe86b8d 100644 --- a/zone/aura.cpp +++ b/zone/aura.cpp @@ -7,7 +7,7 @@ Aura::Aura(NPCType *type_data, Mob *owner, AuraRecord &record) : NPC(type_data, 0, owner->GetPosition(), FlyMode3), spell_id(record.spell_id), distance(record.distance), - remove_timer(record.duration), movement_timer(100), process_timer(100) + remove_timer(record.duration), movement_timer(100), process_timer(100), aura_id(-1) { GiveNPCTypeData(type_data); // we will delete this later on m_owner = owner->GetID(); @@ -584,6 +584,7 @@ void Aura::Depop(bool unused) p_depop = true; } +// This creates an aura from a casted spell void Mob::MakeAura(uint16 spell_id) { // TODO: verify room in AuraMgr @@ -639,6 +640,7 @@ void Mob::MakeAura(uint16 spell_id) strn0cpy(npc_type->name, record.name, 64); auto npc = new Aura(npc_type, this, record); + npc->SetAuraID(spell_id); entity_list.AddNPC(npc, true, true); if (trap) @@ -732,6 +734,13 @@ bool Mob::CanSpawnAura(bool trap) void Mob::RemoveAllAuras() { + if (IsClient()) { + database.SaveAuras(CastToClient()); + EQApplicationPacket outapp(OP_UpdateAura, 4); + outapp.WriteUInt32(2); + CastToClient()->QueuePacket(&outapp); + } + // this is sent on camp/zone, so it just despawns? if (aura_mgr.count) { for (auto &e : aura_mgr.auras) { @@ -740,12 +749,17 @@ void Mob::RemoveAllAuras() } } + aura_mgr.count = 0; + if (trap_mgr.count) { for (auto &e : trap_mgr.auras) { if (e.aura) e.aura->Depop(); } } + + trap_mgr.count = 0; + return; } diff --git a/zone/aura.h b/zone/aura.h index 8d467d945..7980f0b0a 100644 --- a/zone/aura.h +++ b/zone/aura.h @@ -57,8 +57,14 @@ public: void ProcessEnterTrap(Mob *owner); void ProcessExitTrap(Mob *owner); + // we only save auras that follow you, and player casted + inline bool AuraZones() { return movement_type == AuraMovement::Follow && aura_id > -1; } + inline int GetSpellID() { return spell_id; } + inline int GetAuraID() { return aura_id; } + inline void SetAuraID(int in) { aura_id = in; } private: int m_owner; + int aura_id; // spell ID of the aura spell -1 if aura isn't from a casted spell int spell_id; // spell we cast int distance; // distance we remove Timer remove_timer; // when we depop diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 752d43eee..3a52fc19e 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -883,6 +883,8 @@ void Client::CompleteConnect() SetPetCommandState(PET_BUTTON_SPELLHOLD, 0); } + database.LoadAuras(this); // this ends up spawning them so probably safer to load this later (here) + entity_list.RefreshClientXTargets(this); worldserver.RequestTellQueue(GetName()); diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 672848acc..3e08c1fba 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -723,6 +723,8 @@ void Client::OnDisconnect(bool hard_disconnect) { } } + RemoveAllAuras(); + Mob *Other = trade->With(); if(Other) { diff --git a/zone/mob.h b/zone/mob.h index 8e980519a..4fcc81b5a 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -625,6 +625,7 @@ public: bool PlotPositionAroundTarget(Mob* target, float &x_dest, float &y_dest, float &z_dest, bool lookForAftArc = true); + // aura functions void MakeAura(uint16 spell_id); inline int GetAuraSlots() { return 1 + aabonuses.aura_slots + itembonuses.aura_slots + spellbonuses.aura_slots; } inline int GetTrapSlots() { return 1 + aabonuses.trap_slots + itembonuses.trap_slots + spellbonuses.trap_slots; } @@ -635,6 +636,7 @@ public: bool CanSpawnAura(bool trap); void RemoveAura(int spawn_id, bool expired = false); void RemoveAllAuras(); + inline AuraMgr &GetAuraMgr() { return aura_mgr; } // mainly used for zone db loading/saving //Procs void TriggerDefensiveProcs(Mob *on, uint16 hand = EQEmu::inventory::slotPrimary, bool FromSkillProc = false, int damage = 0); diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index d647dcbf7..e48990c6a 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -11,6 +11,7 @@ #include "merc.h" #include "zone.h" #include "zonedb.h" +#include "aura.h" #include #include @@ -3148,6 +3149,37 @@ void ZoneDatabase::LoadBuffs(Client *client) } } +void ZoneDatabase::SaveAuras(Client *c) +{ + auto query = StringFormat("DELETE FROM `character_auras` WHERE `id` = %u", c->CharacterID()); + auto results = database.QueryDatabase(query); + if (!results.Success()) + return; + + const auto &auras = c->GetAuraMgr(); + for (int i = 0; i < auras.count; ++i) { + auto aura = auras.auras[i].aura; + if (aura && aura->AuraZones()) { + query = StringFormat("INSERT INTO `character_auras` (id, slot, spell_id) VALUES(%u, %d, %d)", + c->CharacterID(), i, aura->GetAuraID()); + auto results = database.QueryDatabase(query); + if (!results.Success()) + return; + } + } +} + +void ZoneDatabase::LoadAuras(Client *c) +{ + auto query = StringFormat("SELECT `spell_id` FROM `character_auras` WHERE `id` = %u ORDER BY `slot`", c->CharacterID()); + auto results = database.QueryDatabase(query); + if (!results.Success()) + return; + + for (auto row = results.begin(); row != results.end(); ++row) + c->MakeAura(atoi(row[0])); +} + void ZoneDatabase::SavePetInfo(Client *client) { PetInfo *petinfo = nullptr; diff --git a/zone/zonedb.h b/zone/zonedb.h index b91ea3cdd..a8ab3659f 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -273,6 +273,8 @@ public: void SaveBuffs(Client *c); void LoadBuffs(Client *c); + void SaveAuras(Client *c); + void LoadAuras(Client *c); void LoadPetInfo(Client *c); void SavePetInfo(Client *c); void RemoveTempFactions(Client *c);