diff --git a/zone/CMakeLists.txt b/zone/CMakeLists.txt index 2510dcddb..4340ff6da 100644 --- a/zone/CMakeLists.txt +++ b/zone/CMakeLists.txt @@ -125,6 +125,7 @@ SET(zone_sources SET(zone_headers aa.h + aa_ability.h basic_functions.h beacon.h bot.h diff --git a/zone/aa.cpp b/zone/aa.cpp index b6e220d60..c98e31372 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -2070,3 +2070,129 @@ Mob *AA_SwarmPetInfo::GetOwner() { return entity_list.GetMobID(owner_id); } + +//New AA +void Zone::LoadAlternateAdvancement() { + Log.Out(Logs::General, Logs::Status, "Loading Alternate Advancement Data..."); + if(!database.LoadAlternateAdvancementAbilities(zone->aa_abilities, + zone->aa_ranks)) + { + zone->aa_abilities.clear(); + zone->aa_ranks.clear(); + Log.Out(Logs::General, Logs::Status, "Failed to load Alternate Advancement Data"); + return; + } + + Log.Out(Logs::General, Logs::Status, "Loaded Alternate Advancement Data"); +} + +bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_map> &abilities, + std::unordered_map> &ranks) +{ + Log.Out(Logs::General, Logs::Status, "Loading Alternate Advancement Abilities..."); + abilities.clear(); + std::string query = "SELECT id, name, expansion, category, classes, expendable, first_rank_id FROM aa_ability"; + auto results = QueryDatabase(query); + if(results.Success()) { + for(auto row = results.begin(); row != results.end(); ++row) { + AA::Ability *ability = new AA::Ability; + int id = atoi(row[0]); + + ability->name = row[1]; + ability->expansion = atoi(row[2]); + ability->category = atoi(row[3]); + ability->classes = atoi(row[4]); + ability->expendable = atoi(row[5]) != 0 ? true : false; + ability->first_rank_id = atoi(row[6]); + + abilities[id] = std::unique_ptr(ability); + } + } else { + Log.Out(Logs::General, Logs::Error, "Failed to load Alternate Advancement Abilities"); + return false; + } + + Log.Out(Logs::General, Logs::Status, "Loaded %d Alternate Advancement Abilities", (int)abilities.size()); + + Log.Out(Logs::General, Logs::Status, "Loading Alternate Advancement Ability Ranks..."); + ranks.clear(); + query = "SELECT id, upper_hotkey_sid, lower_hotkey_sid, title_sid, desc_sid, cost, level_req, spell, spell_type, recast_time, " + "prev_id, next_id FROM aa_ranks"; + results = QueryDatabase(query); + if(results.Success()) { + for(auto row = results.begin(); row != results.end(); ++row) { + AA::Rank *rank = new AA::Rank; + int id = atoi(row[0]); + rank->upper_hotkey_sid = atoi(row[1]); + rank->lower_hotkey_sid = atoi(row[2]); + rank->title_sid = atoi(row[3]); + rank->desc_sid = atoi(row[4]); + rank->cost = atoi(row[5]); + rank->level_req = atoi(row[6]); + rank->spell = atoi(row[7]); + rank->spell_type = atoi(row[8]); + rank->recast_time = atoi(row[9]); + rank->prev_id = atoi(row[10]); + rank->next_id = atoi(row[11]); + + ranks[id] = std::unique_ptr(rank); + } + } else { + Log.Out(Logs::General, Logs::Error, "Failed to load Alternate Advancement Ability Ranks"); + return false; + } + + Log.Out(Logs::General, Logs::Status, "Loaded %d Alternate Advancement Ability Ranks", (int)ranks.size()); + + Log.Out(Logs::General, Logs::Status, "Loading Alternate Advancement Ability Rank Effects..."); + query = "SELECT rank_id, slot, effect_id, base1, base2 FROM aa_rank_effects"; + results = QueryDatabase(query); + if(results.Success()) { + for(auto row = results.begin(); row != results.end(); ++row) { + AA::RankEffect effect; + int rank_id = atoi(row[0]); + int slot = atoi(row[1]); + effect.effect_id = atoi(row[2]); + effect.base1 = atoi(row[3]); + effect.base2 = atoi(row[4]); + + if(slot < 1 || slot > 12) + continue; + + if(ranks.count(rank_id) > 0) { + AA::Rank *rank = ranks[rank_id].get(); + rank->effects[slot] = effect; + } + } + } else { + Log.Out(Logs::General, Logs::Error, "Failed to load Alternate Advancement Ability Rank Effects"); + return false; + } + + Log.Out(Logs::General, Logs::Status, "Loaded Alternate Advancement Ability Rank Effects"); + + Log.Out(Logs::General, Logs::Status, "Loading Alternate Advancement Ability Rank Prereqs..."); + query = "SELECT rank_id, aa_id, points FROM aa_rank_prereqs"; + results = QueryDatabase(query); + if(results.Success()) { + for(auto row = results.begin(); row != results.end(); ++row) { + AA::RankPrereq prereq; + int rank_id = atoi(row[0]); + prereq.aa_id = atoi(row[1]); + prereq.points = atoi(row[1]); + + if(ranks.count(rank_id) > 0) { + AA::Rank *rank = ranks[rank_id].get(); + rank->prereqs.push_back(prereq); + } + } + } else { + Log.Out(Logs::General, Logs::Error, "Failed to load Alternate Advancement Ability Rank Prereqs"); + return false; + } + + Log.Out(Logs::General, Logs::Status, "Loaded Alternate Advancement Ability Rank Prereqs"); + + return true; +} + diff --git a/zone/aa_ability.h b/zone/aa_ability.h new file mode 100644 index 000000000..bb9148689 --- /dev/null +++ b/zone/aa_ability.h @@ -0,0 +1,45 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef EQEMU_ZONE_AA_ABILITY_H +#define EQEMU_ZONE_AA_ABILITY_H + +#include "../common/global_define.h" +#include +#include +#include +#include "aa_rank_effects.h" +#include "aa_rank_prereqs.h" +#include "aa_rank.h" + +namespace AA +{ + +struct Ability +{ + std::string name; + int expansion; + int category; + int classes; + bool expendable; + int first_rank_id; +}; + +} + +#endif diff --git a/zone/aa_rank.h b/zone/aa_rank.h new file mode 100644 index 000000000..ec1cc4115 --- /dev/null +++ b/zone/aa_rank.h @@ -0,0 +1,44 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef EQEMU_ZONE_AA_RANK_H +#define EQEMU_ZONE_AA_RANK_H + +namespace AA +{ + +struct Rank +{ + int upper_hotkey_sid; + int lower_hotkey_sid; + int title_sid; + int desc_sid; + int cost; + int level_req; + int spell; + int spell_type; + int recast_time; + int prev_id; + int next_id; + std::unordered_map effects; + std::vector prereqs; +}; + +} + +#endif diff --git a/zone/aa_rank_effects.h b/zone/aa_rank_effects.h new file mode 100644 index 000000000..fd65d507f --- /dev/null +++ b/zone/aa_rank_effects.h @@ -0,0 +1,37 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef EQEMU_ZONE_AA_RANK_EFFECTS_H +#define EQEMU_ZONE_AA_RANK_EFFECTS_H + +#include "../common/global_define.h" +#include + +namespace AA +{ + +struct RankEffect +{ + int effect_id; + int base1; + int base2; +}; + +} + +#endif diff --git a/zone/aa_rank_prereqs.h b/zone/aa_rank_prereqs.h new file mode 100644 index 000000000..b1620be6c --- /dev/null +++ b/zone/aa_rank_prereqs.h @@ -0,0 +1,33 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef EQEMU_ZONE_AA_RANK_PREREQS_H +#define EQEMU_ZONE_AA_RANK_PREREQS_H + +namespace AA +{ + +struct RankPrereq +{ + int aa_id; + int points; +}; + +} + +#endif diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 8a7b8a133..112e8f33f 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -1091,6 +1091,7 @@ void Client::Handle_Connect_OP_SendAAStats(const EQApplicationPacket *app) void Client::Handle_Connect_OP_SendAATable(const EQApplicationPacket *app) { + Log.Out(Logs::General, Logs::Error, "SendAAList()"); SendAAList(); return; } @@ -1152,6 +1153,7 @@ void Client::Handle_Connect_OP_TGB(const EQApplicationPacket *app) void Client::Handle_Connect_OP_UpdateAA(const EQApplicationPacket *app) { + Log.Out(Logs::General, Logs::Error, "SendAATable()"); SendAATable(); } diff --git a/zone/entity.cpp b/zone/entity.cpp index baa4f4354..a73b21f4d 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -58,7 +58,6 @@ extern uint32 numclients; extern PetitionList petition_list; extern char errorname[32]; -extern uint16 adverrornum; Entity::Entity() { diff --git a/zone/net.cpp b/zone/net.cpp index ef6b46836..0178eff21 100644 --- a/zone/net.cpp +++ b/zone/net.cpp @@ -96,7 +96,6 @@ EntityList entity_list; WorldServer worldserver; uint32 numclients = 0; char errorname[32]; -uint16 adverrornum = 0; extern Zone* zone; EQStreamFactory eqsf(ZoneStream); npcDecayTimes_Struct npcCorpseDecayTimes[100]; diff --git a/zone/zone.cpp b/zone/zone.cpp index e58bea24a..31bc27b41 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -68,7 +68,6 @@ extern bool staticzone; extern NetConnection net; extern PetitionList petition_list; extern QuestParserCollection* parse; -extern uint16 adverrornum; extern uint32 numclients; extern WorldServer worldserver; extern Zone* zone; @@ -954,15 +953,14 @@ bool Zone::Init(bool iStaticZone) { zone->LoadNPCEmotes(&NPCEmoteList); //Load AA information - adverrornum = 500; LoadAAs(); + LoadAlternateAdvancement(); + //Load merchant data - adverrornum = 501; zone->GetMerchantDataForZoneLoad(); //Load temporary merchant data - adverrornum = 502; zone->LoadTempMerchantData(); // Merc data @@ -974,7 +972,6 @@ bool Zone::Init(bool iStaticZone) { if (RuleB(Zone, LevelBasedEXPMods)) zone->LoadLevelEXPMods(); - adverrornum = 503; petition_list.ClearPetitions(); petition_list.ReadDatabase(); diff --git a/zone/zone.h b/zone/zone.h index 7b1b855a7..274a1a021 100644 --- a/zone/zone.h +++ b/zone/zone.h @@ -27,6 +27,7 @@ #include "qglobals.h" #include "spawn2.h" #include "spawngroup.h" +#include "aa_ability.h" struct ZonePoint { @@ -113,12 +114,17 @@ public: inline const uint32& GetMaxClients() { return pMaxClients; } + //new AA + void LoadAlternateAdvancement(); + + //old AA void LoadAAs(); int GetTotalAAs() { return totalAAs; } SendAA_Struct* GetAABySequence(uint32 seq) { return aas[seq]; } SendAA_Struct* FindAA(uint32 id); uint8 GetTotalAALevels(uint32 skill_id); - void LoadZoneDoors(const char* zone, int16 version); + + void LoadZoneDoors(const char* zone, int16 version); bool LoadZoneObjects(); bool LoadGroundSpawns(); void ReloadStaticData(); @@ -313,6 +319,11 @@ private: int totalBS; ZoneSpellsBlocked *blocked_spells; + //new AA + std::unordered_map> aa_abilities; + std::unordered_map> aa_ranks; + + //old AA int totalAAs; SendAA_Struct **aas; //array of AA structs diff --git a/zone/zonedb.h b/zone/zonedb.h index cac380a96..dda01b7dc 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -6,6 +6,7 @@ #include "position.h" #include "../common/faction.h" #include "../common/eqemu_logsys.h" +#include "aa_ability.h" class Client; class Corpse; @@ -339,7 +340,11 @@ public: bool SetCharacterFactionLevel(uint32 char_id, int32 faction_id, int32 value, uint8 temp, faction_map &val_list); // needed for factions Dec, 16 2001 bool LoadFactionData(); - /* AAs */ + /* AAs New */ + bool LoadAlternateAdvancementAbilities(std::unordered_map> &abilities, + std::unordered_map> &ranks); + + /* AAs Old */ bool LoadAAEffects(); bool LoadAAEffects2(); bool LoadSwarmSpells();