From 89fdd842e12dac7c7b508fbe4ae24a0b9fe5abab Mon Sep 17 00:00:00 2001 From: Chris Miles Date: Thu, 1 Sep 2022 18:48:28 -0500 Subject: [PATCH] [Code Cleanup] Zone Data Loading Refactor (#2388) * [Code Cleanup] Zone data loading refactor * Update client_packet.cpp * strcpy adjustments * Ensure safe points get reloaded properly * Simplify GetPEQZone and getZoneShutDownDelay * Bring in zone_store where needed * Update client.cpp * Signature * Signature * Convert helpers to using pointers * PR comment * Update worlddb.cpp * Fix loading for instances * Fix zoning with fallback as well * Another place for instance fallback --- client_files/export/main.cpp | 2 + client_files/import/main.cpp | 2 + common/CMakeLists.txt | 2 + common/database.cpp | 106 +--------------- common/database.h | 2 - common/eq_packet_structs.h | 22 ++-- common/patches/rof.cpp | 12 +- common/patches/rof2.cpp | 42 +++---- common/patches/rof2_structs.h | 72 +++++------ common/patches/rof_structs.h | 64 +++++----- common/patches/sod.cpp | 16 +-- common/patches/sod_structs.h | 60 ++++----- common/patches/sof.cpp | 12 +- common/patches/sof_structs.h | 52 ++++---- common/patches/uf.cpp | 14 +-- common/patches/uf_structs.h | 62 +++++----- common/servertalk.h | 1 + {zone => common}/zone_store.cpp | 62 +++++++--- {zone => common}/zone_store.h | 31 +++-- shared_memory/main.cpp | 2 + world/CMakeLists.txt | 2 - world/adventure.cpp | 2 +- world/adventure_manager.cpp | 2 +- world/client.cpp | 9 +- world/clientlist.cpp | 2 +- world/console.cpp | 2 +- world/eql_config.cpp | 2 +- world/main.cpp | 4 +- world/world_boot.cpp | 5 +- world/world_store.cpp | 152 ----------------------- world/world_store.h | 70 ----------- world/worlddb.cpp | 203 +++++++++++++++--------------- world/worlddb.h | 2 +- world/zonelist.cpp | 2 +- world/zoneserver.cpp | 3 +- zone/CMakeLists.txt | 2 - zone/aa.cpp | 2 +- zone/api_service.cpp | 2 +- zone/bot.cpp | 6 +- zone/bot.h | 2 +- zone/bot_command.cpp | 2 +- zone/bot_database.cpp | 2 +- zone/client.cpp | 19 ++- zone/client.h | 2 +- zone/client_mods.cpp | 6 +- zone/client_packet.cpp | 16 +-- zone/client_process.cpp | 2 +- zone/data_bucket.cpp | 2 +- zone/doors.cpp | 2 +- zone/effects.cpp | 2 +- zone/forage.cpp | 2 +- zone/gm_commands/gmzone.cpp | 45 ++++--- zone/gm_commands/reload.cpp | 26 ++-- zone/gm_commands/zheader.cpp | 4 +- zone/gm_commands/zone.cpp | 4 +- zone/gm_commands/zstats.cpp | 14 +-- zone/guild_mgr.cpp | 2 +- zone/inventory.cpp | 2 +- zone/loottables.cpp | 2 +- zone/lua_expedition.cpp | 2 +- zone/main.cpp | 5 +- zone/merc.cpp | 6 +- zone/mob_ai.cpp | 2 +- zone/mob_appearance.cpp | 2 +- zone/mod_functions_base.cpp | 2 +- zone/npc.h | 2 +- zone/object.cpp | 2 +- zone/perl_expedition.cpp | 2 +- zone/petitions.h | 2 +- zone/pets.cpp | 2 +- zone/questmgr.cpp | 8 +- zone/spawn2.cpp | 2 +- zone/spawngroup.cpp | 2 +- zone/task_client_state.cpp | 2 +- zone/tradeskills.cpp | 2 +- zone/worldserver.cpp | 7 ++ zone/zone.cpp | 213 +++++++++++++++++++++++--------- zone/zone.h | 20 +-- zone/zonedb.cpp | 194 +---------------------------- zone/zonedb.h | 21 +--- zone/zoning.cpp | 113 ++++++++--------- 81 files changed, 753 insertions(+), 1130 deletions(-) rename {zone => common}/zone_store.cpp (69%) rename {zone => common}/zone_store.h (69%) delete mode 100644 world/world_store.cpp delete mode 100644 world/world_store.h diff --git a/client_files/export/main.cpp b/client_files/export/main.cpp index 6284e6191..491f23761 100644 --- a/client_files/export/main.cpp +++ b/client_files/export/main.cpp @@ -27,9 +27,11 @@ #include "../../common/rulesys.h" #include "../../common/strings.h" #include "../../common/content/world_content_service.h" +#include "../../common/zone_store.h" EQEmuLogSys LogSys; WorldContentService content_service; +ZoneStore zone_store; void ExportSpells(SharedDatabase *db); void ExportSkillCaps(SharedDatabase *db); diff --git a/client_files/import/main.cpp b/client_files/import/main.cpp index 96ed82098..da230d73b 100644 --- a/client_files/import/main.cpp +++ b/client_files/import/main.cpp @@ -25,9 +25,11 @@ #include "../../common/rulesys.h" #include "../../common/strings.h" #include "../../common/content/world_content_service.h" +#include "../../common/zone_store.h" EQEmuLogSys LogSys; WorldContentService content_service; +ZoneStore zone_store; void ImportSpells(SharedDatabase *db); void ImportSkillCaps(SharedDatabase *db); diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 26ec3f482..1159cdb8c 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -84,6 +84,7 @@ SET(common_sources unix.cpp platform.cpp json/jsoncpp.cpp + zone_store.cpp net/console_server.cpp net/console_server_connection.cpp net/crc32.cpp @@ -597,6 +598,7 @@ SET(common_headers useperl.h version.h zone_numbers.h + zone_store.h event/event_loop.h event/task.h event/timer.h diff --git a/common/database.cpp b/common/database.cpp index 67673640a..20bbbc390 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -51,6 +51,7 @@ #include "http/uri.h" #include "repositories/zone_repository.h" +#include "zone_store.h" extern Client client; @@ -1018,97 +1019,6 @@ void Database::SetAccountCRCField(uint32 account_id, std::string field_name, uin ); } -// Get zone starting points from DB -bool Database::GetSafePoints(const char* zone_short_name, uint32 instance_version, float* safe_x, float* safe_y, float* safe_z, float* safe_heading, int16* min_status, uint8* min_level, char *flag_needed) { - - if (zone_short_name == nullptr) - return false; - - std::string query = fmt::format( - SQL( - SELECT - `safe_x`, `safe_y`, `safe_z`, `safe_heading`, `min_status`, `min_level`, `flag_needed` - FROM - zone - WHERE - `short_name` = '{}' - AND - (`version` = {} OR `version` = 0) - ORDER BY `version` DESC - ), zone_short_name, instance_version - ); - auto results = QueryDatabase(query); - - if (!results.Success()) - return false; - - if (results.RowCount() == 0) - return false; - - auto row = results.begin(); - - if (safe_x != nullptr) - *safe_x = atof(row[0]); - - if (safe_y != nullptr) - *safe_y = atof(row[1]); - - if (safe_z != nullptr) - *safe_z = atof(row[2]); - - if (safe_heading != nullptr) - *safe_heading = atof(row[3]); - - if (min_status != nullptr) - *min_status = atoi(row[4]); - - if (min_level != nullptr) - *min_level = atoi(row[5]); - - if (flag_needed != nullptr) - strcpy(flag_needed, row[6]); - - return true; -} - -bool Database::GetZoneLongName(const char* short_name, char** long_name, char* file_name, float* safe_x, float* safe_y, float* safe_z, uint32* graveyard_id, uint32* maxclients) { - - std::string query = StringFormat("SELECT long_name, file_name, safe_x, safe_y, safe_z, graveyard_id, maxclients FROM zone WHERE short_name='%s' AND version=0", short_name); - auto results = QueryDatabase(query); - - if (!results.Success()) { - return false; - } - - if (results.RowCount() == 0) - return false; - - auto row = results.begin(); - - if (long_name != nullptr) - *long_name = strcpy(new char[strlen(row[0])+1], row[0]); - - if (file_name != nullptr) { - if (row[1] == nullptr) - strcpy(file_name, short_name); - else - strcpy(file_name, row[1]); - } - - if (safe_x != nullptr) - *safe_x = atof(row[2]); - if (safe_y != nullptr) - *safe_y = atof(row[3]); - if (safe_z != nullptr) - *safe_z = atof(row[4]); - if (graveyard_id != nullptr) - *graveyard_id = atoi(row[5]); - if (maxclients != nullptr) - *maxclients = atoi(row[6]); - - return true; -} - bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid, float* graveyard_x, float* graveyard_y, float* graveyard_z, float* graveyard_heading) { std::string query = StringFormat("SELECT zone_id, x, y, z, heading FROM graveyard WHERE id=%i", graveyard_id); @@ -1138,20 +1048,10 @@ bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zon } uint8 Database::GetPEQZone(uint32 zone_id, uint32 version){ - std::string query = fmt::format( - "SELECT peqzone FROM zone WHERE zoneidnumber = {} AND (version = {} OR version = 0) ORDER BY version DESC LIMIT 1", - zone_id, - version - ); - auto results = QueryDatabase(query); - if (!results.Success() || !results.RowCount()) { - return 0; - } + auto z = GetZoneVersionWithFallback(zone_id, version); - auto row = results.begin(); - - return static_cast(std::stoi(row[0])); + return z ? z->peqzone : 0; } bool Database::CheckNameFilter(std::string name, bool surname) diff --git a/common/database.h b/common/database.h index 9a1933b33..3bd7f6ee4 100644 --- a/common/database.h +++ b/common/database.h @@ -246,9 +246,7 @@ public: /* General Queries */ - bool GetSafePoints(const char* zone_short_name, uint32 instance_version, float* safe_x = 0, float* safe_y = 0, float* safe_z = 0, float* safe_heading = 0, int16* minstatus = 0, uint8* minlevel = 0, char *flag_needed = nullptr); bool GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid = 0, float* graveyard_x = 0, float* graveyard_y = 0, float* graveyard_z = 0, float* graveyard_heading = 0); - bool GetZoneLongName(const char* short_name, char** long_name, char* file_name = 0, float* safe_x = 0, float* safe_y = 0, float* safe_z = 0, uint32* graveyard_id = 0, uint32* maxclients = 0); bool LoadPTimers(uint32 charid, PTimerList &into); uint8 GetPEQZone(uint32 zone_id, uint32 version); diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index b0fce1f49..b178cb28b 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -374,18 +374,18 @@ struct NewZone_Struct { /*0684*/ uint16 zone_id; /*0686*/ uint16 zone_instance; /*0688*/ uint32 unknown688; -/*0692*/ uint8 unknown692[8]; +/*0692*/ uint8 unknown692[8]; // Titanium doesn't have a translator, but we can still safely add stuff under here without issues since client memcpy's only what it knows // Just wastes some bandwidth sending to tit clients /shrug -/*0700*/ float fog_density; -/*0704*/ uint32 SuspendBuffs; -/*0708*/ uint32 FastRegenHP; -/*0712*/ uint32 FastRegenMana; -/*0716*/ uint32 FastRegenEndurance; -/*0720*/ uint32 NPCAggroMaxDist; -/*0724*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, if this value is 0, it prevents you from running off edges that would end up underworld -/*0728*/ uint32 LavaDamage; // Seen 50 -/*0732*/ uint32 MinLavaDamage; // Seen 10 +/*0700*/ float fog_density; +/*0704*/ uint32 suspend_buffs; +/*0708*/ uint32 fast_regen_hp; +/*0712*/ uint32 fast_regen_mana; +/*0716*/ uint32 fast_regen_endurance; +/*0720*/ uint32 npc_aggro_max_dist; +/*0724*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, if this value is 0, it prevents you from running off edges that would end up underworld +/*0728*/ uint32 lava_damage; // Seen 50 +/*0732*/ uint32 min_lava_damage; // Seen 10 /*0736*/ }; @@ -3642,7 +3642,7 @@ struct MerchantList { uint8 probability; std::string bucket_name; std::string bucket_value; - uint8 bucket_comparison; + uint8 bucket_comparison; }; struct TempMerchantList { diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index 67969d1dc..e86fcf340 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -1814,10 +1814,10 @@ namespace RoF OUT_str(zone_short_name2); OUT(zone_id); OUT(zone_instance); - OUT(SuspendBuffs); - OUT(FastRegenHP); - OUT(FastRegenMana); - OUT(FastRegenEndurance); + OUT(suspend_buffs); + OUT(fast_regen_hp); + OUT(fast_regen_mana); + OUT(fast_regen_endurance); OUT(underworld_teleport_index); eq->FogDensity = emu->fog_density; @@ -1825,8 +1825,8 @@ namespace RoF /*fill in some unknowns with observed values, hopefully it will help */ eq->unknown800 = -1; eq->unknown844 = 600; - OUT(LavaDamage); - OUT(MinLavaDamage); + OUT(lava_damage); + OUT(min_lava_damage); eq->unknown888 = 1; eq->unknown889 = 0; eq->unknown890 = 1; diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 6e418d113..828452171 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -1863,13 +1863,13 @@ namespace RoF2 OUT_str(zone_short_name2); OUT(zone_id); OUT(zone_instance); - OUT(SuspendBuffs); - OUT(FastRegenHP); - OUT(FastRegenMana); - OUT(FastRegenEndurance); + OUT(suspend_buffs); + OUT(fast_regen_hp); + OUT(fast_regen_mana); + OUT(fast_regen_endurance); OUT(underworld_teleport_index); - eq->FogDensity = emu->fog_density; + eq->fog_density = emu->fog_density; /*fill in some unknowns with observed values, hopefully it will help */ eq->ZoneTimeZone = 0; @@ -1881,22 +1881,22 @@ namespace RoF2 eq->SkyRelated2 = -1; eq->NPCAggroMaxDist = 600; eq->FilterID = 2008; // Guild Lobby observed value - OUT(LavaDamage); - OUT(MinLavaDamage); - eq->bDisallowManaStone = 1; - eq->bNoBind = 0; - eq->bNoAttack = 0; - eq->bNoCallOfHero = 0; - eq->bNoFlux = 0; - eq->bNoFear = 0; - eq->fall_damage = 0; // 0 = Fall Damage on, 1 = Fall Damage off - eq->unknown895 = 0; - eq->CanPlaceCampsite = 2; - eq->CanPlaceGuildBanner = 2; - eq->FishingRelated = -1; // Set from PoK Example - eq->ForageRelated = -1; // Set from PoK Example - eq->bNoLevitate = 0; - eq->Blooming = 1.0; // Set from PoK Example + OUT(lava_damage); + OUT(min_lava_damage); + eq->bDisallowManaStone = 1; + eq->bNoBind = 0; + eq->bNoAttack = 0; + eq->bNoCallOfHero = 0; + eq->bNoFlux = 0; + eq->bNoFear = 0; + eq->fall_damage = 0; // 0 = Fall Damage on, 1 = Fall Damage off + eq->unknown895 = 0; + eq->can_place_campsite = 2; + eq->can_place_guild_banner = 2; + eq->fishing_related = -1; // Set from PoK Example + eq->forage_related = -1; // Set from PoK Example + eq->b_no_levitate = 0; + eq->blooming = 1.0; // Set from PoK Example FINISH_ENCODE(); } diff --git a/common/patches/rof2_structs.h b/common/patches/rof2_structs.h index d3692ba0a..037574861 100644 --- a/common/patches/rof2_structs.h +++ b/common/patches/rof2_structs.h @@ -1,5 +1,5 @@ /* EQEMu: Everquest Server Emulator - + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) This program is free software; you can redistribute it and/or modify @@ -620,40 +620,40 @@ struct NewZone_Struct { /*0800*/ int32 SkyRelated2; //seen -1 -- maybe some default sky time? /*0804*/ char WeatherString2[32]; // /*0836*/ float WeatherChangeTime; // not sure :P - /*0840*/ uint32 Climate; - /*0844*/ int32 NPCAggroMaxDist; //seen 600 - /*0848*/ int32 FilterID; //seen 2008 -- maybe zone guide related? - /*0852*/ uint16 zone_id; // this might just be instance ID got 1736 for time - /*0854*/ uint16 zone_instance; - /*0856*/ uint32 scriptNPCReceivedanItem; - /*0860*/ uint32 bCheck; // padded bool - /*0864*/ uint32 scriptIDSomething; - /*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions - /*0872*/ uint32 scriptIDSomething3; - /*0876*/ uint32 SuspendBuffs; // padded bool - /*0880*/ uint32 LavaDamage; // LavaDamage value - /*0884*/ uint32 MinLavaDamage; // min cap after resist calcs - /*0888*/ uint8 bDisallowManaStone; // can't use manastone in this zone - /*0889*/ uint8 bNoBind; // can't bind even if outdoor says we can! - /*0890*/ uint8 bNoAttack; // non-attack zone - /*0891*/ uint8 bNoCallOfHero; // coth line disabled - /*0892*/ uint8 bNoFlux; // gflux no worky - /*0893*/ uint8 bNoFear; // fear spells no worky - /*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off MQ2 calls bNoEncumber - /*0895*/ uint8 unknown895; // padding - /*0896*/ uint32 FastRegenHP; // percentage I think? - /*0900*/ uint32 FastRegenMana; // percentage I think? - /*0904*/ uint32 FastRegenEndurance; // percentage I think? - /*0908*/ uint32 CanPlaceCampsite; // 0 = no, 1 = can place, 2 = place and goto - /*0912*/ uint32 CanPlaceGuildBanner; // ^ - /*0916*/ float FogDensity; // Most zones have this set to 0.33 Blightfire had 0.16 - /*0920*/ uint32 bAdjustGamma; // padded bool - /*0924*/ uint32 TimeStringID; // Seen 0 - /*0928*/ uint32 bNoMercenaries; // padded bool - /*0932*/ int32 FishingRelated; // Seen -1 idk - /*0936*/ int32 ForageRelated; // Seen -1 idk - /*0940*/ uint32 bNoLevitate; // padded bool - /*0944*/ float Blooming; // Seen 1.0 in PoK, and 0.25 in Guild Lobby + /*0840*/ uint32 Climate; + /*0844*/ int32 NPCAggroMaxDist; //seen 600 + /*0848*/ int32 FilterID; //seen 2008 -- maybe zone guide related? + /*0852*/ uint16 zone_id; // this might just be instance ID got 1736 for time + /*0854*/ uint16 zone_instance; + /*0856*/ uint32 scriptNPCReceivedanItem; + /*0860*/ uint32 bCheck; // padded bool + /*0864*/ uint32 scriptIDSomething; + /*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions + /*0872*/ uint32 scriptIDSomething3; + /*0876*/ uint32 suspend_buffs; // padded bool + /*0880*/ uint32 lava_damage; // lava_damage value + /*0884*/ uint32 min_lava_damage; // min cap after resist calcs + /*0888*/ uint8 bDisallowManaStone; // can't use manastone in this zone + /*0889*/ uint8 bNoBind; // can't bind even if outdoor says we can! + /*0890*/ uint8 bNoAttack; // non-attack zone + /*0891*/ uint8 bNoCallOfHero; // coth line disabled + /*0892*/ uint8 bNoFlux; // gflux no worky + /*0893*/ uint8 bNoFear; // fear spells no worky + /*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off MQ2 calls bNoEncumber + /*0895*/ uint8 unknown895; // padding + /*0896*/ uint32 fast_regen_hp; // percentage I think? + /*0900*/ uint32 fast_regen_mana; // percentage I think? + /*0904*/ uint32 fast_regen_endurance; // percentage I think? + /*0908*/ uint32 can_place_campsite; // 0 = no, 1 = can place, 2 = place and goto + /*0912*/ uint32 can_place_guild_banner; // ^ + /*0916*/ float fog_density; // Most zones have this set to 0.33 Blightfire had 0.16 + /*0920*/ uint32 b_adjust_gamma; // padded bool + /*0924*/ uint32 time_string_id; // Seen 0 + /*0928*/ uint32 b_no_mercenaries; // padded bool + /*0932*/ int32 fishing_related; // Seen -1 idk + /*0936*/ int32 forage_related; // Seen -1 idk + /*0940*/ uint32 b_no_levitate; // padded bool + /*0944*/ float blooming; // Seen 1.0 in PoK, and 0.25 in Guild Lobby /*0948*/ }; @@ -3476,7 +3476,7 @@ struct TraderClick_Struct{ /*000*/ uint32 Code; /*004*/ uint32 TraderID; /*008*/ uint32 Approval; - /*012*/ + /*012*/ }; struct FormattedMessage_Struct{ diff --git a/common/patches/rof_structs.h b/common/patches/rof_structs.h index bfc91719d..3c81505d4 100644 --- a/common/patches/rof_structs.h +++ b/common/patches/rof_structs.h @@ -1,5 +1,5 @@ /* EQEMu: Everquest Server Emulator - + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) This program is free software; you can redistribute it and/or modify @@ -571,39 +571,39 @@ struct NewZone_Struct { /*0704*/ char zone_short_name2[96]; //zone file name? excludes instance number which can be in previous version. /*0800*/ int32 unknown800; //seen -1 /*0804*/ char unknown804[40]; // -/*0844*/ int32 unknown844; //seen 600 -/*0848*/ int32 unknown848; -/*0852*/ uint16 zone_id; -/*0854*/ uint16 zone_instance; -/*0856*/ uint32 scriptNPCReceivedanItem; -/*0860*/ uint32 bCheck; // padded bool -/*0864*/ uint32 scriptIDSomething; -/*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions -/*0872*/ uint32 scriptIDSomething3; -/*0876*/ uint32 SuspendBuffs; -/*0880*/ uint32 LavaDamage; // Seen 50 -/*0884*/ uint32 MinLavaDamage; // Seen 10 -/*0888*/ uint8 unknown888; // Seen 1 -/*0889*/ uint8 unknown889; // Seen 0 (POK) or 1 (rujj) -/*0890*/ uint8 unknown890; // Seen 1 -/*0891*/ uint8 unknown891; // Seen 0 -/*0892*/ uint8 unknown892; // Seen 0 -/*0893*/ uint8 unknown893; // Seen 0 - 00 -/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off -/*0895*/ uint8 unknown895; // Seen 0 - 00 -/*0896*/ uint32 FastRegenHP; // Seen 180 -/*0900*/ uint32 FastRegenMana; // Seen 180 -/*0904*/ uint32 FastRegenEndurance; // Seen 180 -/*0908*/ uint32 unknown908; // Seen 2 -/*0912*/ uint32 unknown912; // Seen 2 -/*0916*/ float FogDensity; // Most zones have this set to 0.33 Blightfire had 0.16 -/*0920*/ uint32 unknown920; // Seen 0 -/*0924*/ uint32 unknown924; // Seen 0 -/*0928*/ uint32 unknown928; // Seen 0 +/*0844*/ int32 unknown844; //seen 600 +/*0848*/ int32 unknown848; +/*0852*/ uint16 zone_id; +/*0854*/ uint16 zone_instance; +/*0856*/ uint32 scriptNPCReceivedanItem; +/*0860*/ uint32 bCheck; // padded bool +/*0864*/ uint32 scriptIDSomething; +/*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions +/*0872*/ uint32 scriptIDSomething3; +/*0876*/ uint32 suspend_buffs; +/*0880*/ uint32 lava_damage; // Seen 50 +/*0884*/ uint32 min_lava_damage; // Seen 10 +/*0888*/ uint8 unknown888; // Seen 1 +/*0889*/ uint8 unknown889; // Seen 0 (POK) or 1 (rujj) +/*0890*/ uint8 unknown890; // Seen 1 +/*0891*/ uint8 unknown891; // Seen 0 +/*0892*/ uint8 unknown892; // Seen 0 +/*0893*/ uint8 unknown893; // Seen 0 - 00 +/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off +/*0895*/ uint8 unknown895; // Seen 0 - 00 +/*0896*/ uint32 fast_regen_hp; // Seen 180 +/*0900*/ uint32 fast_regen_mana; // Seen 180 +/*0904*/ uint32 fast_regen_endurance; // Seen 180 +/*0908*/ uint32 unknown908; // Seen 2 +/*0912*/ uint32 unknown912; // Seen 2 +/*0916*/ float FogDensity; // Most zones have this set to 0.33 Blightfire had 0.16 +/*0920*/ uint32 unknown920; // Seen 0 +/*0924*/ uint32 unknown924; // Seen 0 +/*0928*/ uint32 unknown928; // Seen 0 /*0932*/ int32 unknown932; // Seen -1 /*0936*/ int32 unknown936; // Seen -1 -/*0940*/ uint32 unknown940; // Seen 0 -/*0944*/ float unknown944; // Seen 1.0 +/*0940*/ uint32 unknown940; // Seen 0 +/*0944*/ float unknown944; // Seen 1.0 /*0948*/ }; diff --git a/common/patches/sod.cpp b/common/patches/sod.cpp index 0fc92130e..0a3c5e159 100644 --- a/common/patches/sod.cpp +++ b/common/patches/sod.cpp @@ -1341,17 +1341,17 @@ namespace SoD OUT_str(zone_short_name2); OUT(zone_id); OUT(zone_instance); - OUT(SuspendBuffs); - OUT(FastRegenHP); - OUT(FastRegenMana); - OUT(FastRegenEndurance); + OUT(suspend_buffs); + OUT(fast_regen_hp); + OUT(fast_regen_mana); + OUT(fast_regen_endurance); OUT(underworld_teleport_index); /*fill in some unknowns with observed values, hopefully it will help */ eq->unknown800 = -1; eq->unknown844 = 600; - OUT(LavaDamage); - OUT(MinLavaDamage); + OUT(lava_damage); + OUT(min_lava_damage); eq->unknown888 = 1; eq->unknown889 = 0; eq->unknown890 = 1; @@ -1361,8 +1361,8 @@ namespace SoD eq->fall_damage = 0; // 0 = Fall Damage on, 1 = Fall Damage off eq->unknown895 = 0; eq->unknown908 = 2; - eq->unknown912 = 2; - eq->FogDensity = emu->fog_density; + eq->unknown912 = 2; + eq->fog_density = emu->fog_density; FINISH_ENCODE(); } diff --git a/common/patches/sod_structs.h b/common/patches/sod_structs.h index 978fefb54..fdfb42706 100644 --- a/common/patches/sod_structs.h +++ b/common/patches/sod_structs.h @@ -1,5 +1,5 @@ /* EQEMu: Everquest Server Emulator - + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) This program is free software; you can redistribute it and/or modify @@ -440,35 +440,35 @@ struct NewZone_Struct { /*0704*/ char zone_short_name2[96]; //zone file name? excludes instance number which can be in previous version. /*0800*/ int32 unknown800; //seen -1 /*0804*/ char unknown804[40]; // -/*0844*/ int32 unknown844; //seen 600 -/*0848*/ int32 unknown848; -/*0852*/ uint16 zone_id; -/*0854*/ uint16 zone_instance; -/*0856*/ uint32 scriptNPCReceivedanItem; -/*0860*/ uint32 bCheck; // padded bool -/*0864*/ uint32 scriptIDSomething; -/*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions -/*0872*/ uint32 scriptIDSomething3; -/*0876*/ uint32 SuspendBuffs; -/*0880*/ uint32 LavaDamage; //seen 50 -/*0884*/ uint32 MinLavaDamage; //seen 10 -/*0888*/ uint8 unknown888; //seen 1 -/*0889*/ uint8 unknown889; //seen 0 (POK) or 1 (rujj) -/*0890*/ uint8 unknown890; //seen 1 -/*0891*/ uint8 unknown891; //seen 0 -/*0892*/ uint8 unknown892; //seen 0 -/*0893*/ uint8 unknown893; //seen 0 - 00 -/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off -/*0895*/ uint8 unknown895; //seen 0 - 00 -/*0896*/ uint32 FastRegenHP; //seen 180 -/*0900*/ uint32 FastRegenMana; //seen 180 -/*0904*/ uint32 FastRegenEndurance; //seen 180 -/*0908*/ uint32 unknown908; //seen 2 -/*0912*/ uint32 unknown912; //seen 2 -/*0916*/ float FogDensity; //Of about 10 or so zones tested, all but one have this set to 0.33 Blightfire had 0.16 -/*0920*/ uint32 unknown920; //seen 0 -/*0924*/ uint32 unknown924; //seen 0 -/*0928*/ uint32 unknown928; //seen 0 +/*0844*/ int32 unknown844; //seen 600 +/*0848*/ int32 unknown848; +/*0852*/ uint16 zone_id; +/*0854*/ uint16 zone_instance; +/*0856*/ uint32 scriptNPCReceivedanItem; +/*0860*/ uint32 bCheck; // padded bool +/*0864*/ uint32 scriptIDSomething; +/*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions +/*0872*/ uint32 scriptIDSomething3; +/*0876*/ uint32 suspend_buffs; +/*0880*/ uint32 lava_damage; //seen 50 +/*0884*/ uint32 min_lava_damage; //seen 10 +/*0888*/ uint8 unknown888; //seen 1 +/*0889*/ uint8 unknown889; //seen 0 (POK) or 1 (rujj) +/*0890*/ uint8 unknown890; //seen 1 +/*0891*/ uint8 unknown891; //seen 0 +/*0892*/ uint8 unknown892; //seen 0 +/*0893*/ uint8 unknown893; //seen 0 - 00 +/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off +/*0895*/ uint8 unknown895; //seen 0 - 00 +/*0896*/ uint32 fast_regen_hp; //seen 180 +/*0900*/ uint32 fast_regen_mana; //seen 180 +/*0904*/ uint32 fast_regen_endurance; //seen 180 +/*0908*/ uint32 unknown908; //seen 2 +/*0912*/ uint32 unknown912; //seen 2 +/*0916*/ float fog_density; //Of about 10 or so zones tested, all but one have this set to 0.33 Blightfire had 0.16 +/*0920*/ uint32 unknown920; //seen 0 +/*0924*/ uint32 unknown924; //seen 0 +/*0928*/ uint32 unknown928; //seen 0 /*0932*/ }; diff --git a/common/patches/sof.cpp b/common/patches/sof.cpp index 251f64d79..7a3198d6d 100644 --- a/common/patches/sof.cpp +++ b/common/patches/sof.cpp @@ -1019,17 +1019,17 @@ namespace SoF OUT_str(zone_short_name2); OUT(zone_id); OUT(zone_instance); - OUT(SuspendBuffs); - OUT(FastRegenHP); - OUT(FastRegenMana); - OUT(FastRegenEndurance); + OUT(suspend_buffs); + OUT(fast_regen_hp); + OUT(fast_regen_mana); + OUT(fast_regen_endurance); OUT(underworld_teleport_index); /*fill in some unknowns with observed values, hopefully it will help */ eq->unknown796 = -1; eq->unknown840 = 600; - OUT(LavaDamage); - OUT(MinLavaDamage); + OUT(lava_damage); + OUT(min_lava_damage); eq->unknown884 = 1; eq->unknown885 = 0; eq->unknown886 = 1; diff --git a/common/patches/sof_structs.h b/common/patches/sof_structs.h index 8e034e606..bda416d73 100644 --- a/common/patches/sof_structs.h +++ b/common/patches/sof_structs.h @@ -1,5 +1,5 @@ /* EQEMu: Everquest Server Emulator - + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) This program is free software; you can redistribute it and/or modify @@ -444,31 +444,31 @@ struct NewZone_Struct { /*0700*/ char zone_short_name2[96]; //zone file name? excludes instance number which can be in previous version. /*0796*/ int32 unknown796; //seen -1 /*0800*/ char unknown800[40]; // -/*0840*/ int32 unknown840; //seen 600 -/*0844*/ int32 unknown844; -/*0848*/ uint16 zone_id; -/*0850*/ uint16 zone_instance; -/*0852*/ uint32 scriptNPCReceivedanItem; -/*0856*/ uint32 bCheck; // padded bool -/*0860*/ uint32 scriptIDSomething; -/*0864*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions -/*0868*/ uint32 scriptIDSomething3; -/*0872*/ uint32 SuspendBuffs; -/*0876*/ uint32 LavaDamage; //seen 50 -/*0880*/ uint32 MinLavaDamage; //seen 10 -/*0884*/ uint8 unknown884; //seen 1 -/*0885*/ uint8 unknown885; //seen 0 (POK) or 1 (rujj) -/*0886*/ uint8 unknown886; //seen 1 -/*0887*/ uint8 unknown887; //seen 0 -/*0888*/ uint8 unknown888; //seen 0 -/*0893*/ uint8 unknown889; //seen 0 - 00 -/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off -/*0895*/ uint8 unknown891; //seen 0 - 00 -/*0892*/ uint32 FastRegenHP; //seen 180 -/*0896*/ uint32 FastRegenMana; //seen 180 -/*0900*/ uint32 FastRegenEndurance; //seen 180 -/*0904*/ uint32 unknown904; //seen 2 -/*0908*/ uint32 unknown908; //seen 2 +/*0840*/ int32 unknown840; //seen 600 +/*0844*/ int32 unknown844; +/*0848*/ uint16 zone_id; +/*0850*/ uint16 zone_instance; +/*0852*/ uint32 scriptNPCReceivedanItem; +/*0856*/ uint32 bCheck; // padded bool +/*0860*/ uint32 scriptIDSomething; +/*0864*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions +/*0868*/ uint32 scriptIDSomething3; +/*0872*/ uint32 suspend_buffs; +/*0876*/ uint32 lava_damage; //seen 50 +/*0880*/ uint32 min_lava_damage; //seen 10 +/*0884*/ uint8 unknown884; //seen 1 +/*0885*/ uint8 unknown885; //seen 0 (POK) or 1 (rujj) +/*0886*/ uint8 unknown886; //seen 1 +/*0887*/ uint8 unknown887; //seen 0 +/*0888*/ uint8 unknown888; //seen 0 +/*0893*/ uint8 unknown889; //seen 0 - 00 +/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off +/*0895*/ uint8 unknown891; //seen 0 - 00 +/*0892*/ uint32 fast_regen_hp; //seen 180 +/*0896*/ uint32 fast_regen_mana; //seen 180 +/*0900*/ uint32 fast_regen_endurance; //seen 180 +/*0904*/ uint32 unknown904; //seen 2 +/*0908*/ uint32 unknown908; //seen 2 /*0912*/ }; diff --git a/common/patches/uf.cpp b/common/patches/uf.cpp index 236b89d52..8d23df49f 100644 --- a/common/patches/uf.cpp +++ b/common/patches/uf.cpp @@ -1565,19 +1565,19 @@ namespace UF OUT_str(zone_short_name2); OUT(zone_id); OUT(zone_instance); - OUT(SuspendBuffs); - OUT(FastRegenHP); - OUT(FastRegenMana); - OUT(FastRegenEndurance); + OUT(suspend_buffs); + OUT(fast_regen_hp); + OUT(fast_regen_mana); + OUT(fast_regen_endurance); OUT(underworld_teleport_index); - eq->FogDensity = emu->fog_density; + eq->fog_density = emu->fog_density; /*fill in some unknowns with observed values, hopefully it will help */ eq->unknown800 = -1; eq->unknown844 = 600; - OUT(LavaDamage); - OUT(MinLavaDamage); + OUT(lava_damage); + OUT(min_lava_damage); eq->unknown888 = 1; eq->unknown889 = 0; eq->unknown890 = 1; diff --git a/common/patches/uf_structs.h b/common/patches/uf_structs.h index 50fb1f392..86d6034f0 100644 --- a/common/patches/uf_structs.h +++ b/common/patches/uf_structs.h @@ -1,5 +1,5 @@ /* EQEMu: Everquest Server Emulator - + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) This program is free software; you can redistribute it and/or modify @@ -440,35 +440,35 @@ struct NewZone_Struct { /*0704*/ char zone_short_name2[96]; //zone file name? excludes instance number which can be in previous version. /*0800*/ int32 unknown800; //seen -1 /*0804*/ char unknown804[40]; // -/*0844*/ int32 unknown844; //seen 600 -/*0848*/ int32 unknown848; -/*0852*/ uint16 zone_id; -/*0854*/ uint16 zone_instance; -/*0856*/ uint32 scriptNPCReceivedanItem; -/*0860*/ uint32 bCheck; // padded bool -/*0864*/ uint32 scriptIDSomething; -/*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions -/*0872*/ uint32 scriptIDSomething3; -/*0876*/ uint32 SuspendBuffs; -/*0880*/ uint32 LavaDamage; //seen 50 -/*0884*/ uint32 MinLavaDamage; //seen 10 -/*0888*/ uint8 unknown888; //seen 1 -/*0889*/ uint8 unknown889; //seen 0 (POK) or 1 (rujj) -/*0890*/ uint8 unknown890; //seen 1 -/*0891*/ uint8 unknown891; //seen 0 -/*0892*/ uint8 unknown892; //seen 0 -/*0893*/ uint8 unknown893; //seen 0 - 00 -/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off -/*0895*/ uint8 unknown895; //seen 0 - 00 -/*0896*/ uint32 FastRegenHP; //seen 180 -/*0900*/ uint32 FastRegenMana; //seen 180 -/*0904*/ uint32 FastRegenEndurance; //seen 180 -/*0908*/ uint32 unknown908; //seen 2 -/*0912*/ uint32 unknown912; //seen 2 -/*0916*/ float FogDensity; //Of about 10 or so zones tested, all but one have this set to 0.33 Blightfire had 0.16 -/*0920*/ uint32 unknown920; //seen 0 -/*0924*/ uint32 unknown924; //seen 0 -/*0928*/ uint32 unknown928; //seen 0 +/*0844*/ int32 unknown844; //seen 600 +/*0848*/ int32 unknown848; +/*0852*/ uint16 zone_id; +/*0854*/ uint16 zone_instance; +/*0856*/ uint32 scriptNPCReceivedanItem; +/*0860*/ uint32 bCheck; // padded bool +/*0864*/ uint32 scriptIDSomething; +/*0868*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, -1 affects some collisions +/*0872*/ uint32 scriptIDSomething3; +/*0876*/ uint32 suspend_buffs; +/*0880*/ uint32 lava_damage; //seen 50 +/*0884*/ uint32 min_lava_damage; //seen 10 +/*0888*/ uint8 unknown888; //seen 1 +/*0889*/ uint8 unknown889; //seen 0 (POK) or 1 (rujj) +/*0890*/ uint8 unknown890; //seen 1 +/*0891*/ uint8 unknown891; //seen 0 +/*0892*/ uint8 unknown892; //seen 0 +/*0893*/ uint8 unknown893; //seen 0 - 00 +/*0894*/ uint8 fall_damage; // 0 = Fall Damage on, 1 = Fall Damage off +/*0895*/ uint8 unknown895; //seen 0 - 00 +/*0896*/ uint32 fast_regen_hp; //seen 180 +/*0900*/ uint32 fast_regen_mana; //seen 180 +/*0904*/ uint32 fast_regen_endurance; //seen 180 +/*0908*/ uint32 unknown908; //seen 2 +/*0912*/ uint32 unknown912; //seen 2 +/*0916*/ float fog_density; //Of about 10 or so zones tested, all but one have this set to 0.33 Blightfire had 0.16 +/*0920*/ uint32 unknown920; //seen 0 +/*0924*/ uint32 unknown924; //seen 0 +/*0928*/ uint32 unknown928; //seen 0 /*0932*/ uint8 unknown932[12]; }; @@ -3997,7 +3997,7 @@ struct ItemSerializationHeaderFinish { uint16 ornamentIcon; /*060*/ uint8 unknown060; //0 - /*061*/ uint8 unknown061; //0 - + /*061*/ uint8 unknown061; //0 - /*062*/ uint8 isCopied; // New to Underfoot // Copied flag on item /*063*/ uint8 ItemClass; //0, 1, or 2 }; diff --git a/common/servertalk.h b/common/servertalk.h index 3ad54d289..939f44678 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -246,6 +246,7 @@ #define ServerOP_ReloadWorld 0x4120 #define ServerOP_ReloadZonePoints 0x4121 #define ServerOP_ReloadDzTemplates 0x4122 +#define ServerOP_ReloadZoneData 0x4123 #define ServerOP_CZDialogueWindow 0x4500 #define ServerOP_CZLDoNUpdate 0x4501 diff --git a/zone/zone_store.cpp b/common/zone_store.cpp similarity index 69% rename from zone/zone_store.cpp rename to common/zone_store.cpp index 1ddcc2e4f..27e112c91 100644 --- a/zone/zone_store.cpp +++ b/common/zone_store.cpp @@ -19,15 +19,17 @@ */ #include "zone_store.h" -#include "../common/repositories/content_flags_repository.h" #include "../common/content/world_content_service.h" ZoneStore::ZoneStore() = default; ZoneStore::~ZoneStore() = default; -void ZoneStore::LoadZones() +// cache record of zones for fast successive retrieval +void ZoneStore::LoadZones(Database &db) { - zones = ZoneRepository::All(content_db); + m_zones = ZoneRepository::All(db); + + LogInfo("[ZoneStore] Loaded [{}] zones", m_zones.size()); } /** @@ -51,7 +53,7 @@ uint32 ZoneStore::GetZoneID(const char *in_zone_name) */ uint32 ZoneStore::GetZoneID(std::string zone_name) { - for (auto &z: zones) { + for (auto &z: m_zones) { if (z.short_name == zone_name) { return z.zoneidnumber; } @@ -67,7 +69,7 @@ uint32 ZoneStore::GetZoneID(std::string zone_name) */ const char *ZoneStore::GetZoneName(uint32 zone_id, bool error_unknown) { - for (auto &z: zones) { + for (auto &z: m_zones) { if (z.zoneidnumber == zone_id) { return z.short_name.c_str(); } @@ -87,7 +89,7 @@ const char *ZoneStore::GetZoneName(uint32 zone_id, bool error_unknown) */ const char *ZoneStore::GetZoneLongName(uint32 zone_id, bool error_unknown) { - for (auto &z: zones) { + for (auto &z: m_zones) { if (z.zoneidnumber == zone_id) { return z.long_name.c_str(); } @@ -106,13 +108,13 @@ const char *ZoneStore::GetZoneLongName(uint32 zone_id, bool error_unknown) */ std::string ZoneStore::GetZoneName(uint32 zone_id) { - for (auto &z: zones) { + for (auto &z: m_zones) { if (z.zoneidnumber == zone_id) { return z.short_name; } } - return std::string(); + return {}; } /** @@ -121,13 +123,13 @@ std::string ZoneStore::GetZoneName(uint32 zone_id) */ std::string ZoneStore::GetZoneLongName(uint32 zone_id) { - for (auto &z: zones) { + for (auto &z: m_zones) { if (z.zoneidnumber == zone_id) { return z.long_name; } } - return std::string(); + return {}; } /** @@ -135,28 +137,52 @@ std::string ZoneStore::GetZoneLongName(uint32 zone_id) * @param version * @return */ -ZoneRepository::Zone ZoneStore::GetZone(uint32 zone_id, int version) +ZoneRepository::Zone *ZoneStore::GetZone(uint32 zone_id, int version) { - for (auto &z: zones) { + for (auto &z: m_zones) { if (z.zoneidnumber == zone_id && z.version == version) { - return z; + return &z; } } - return ZoneRepository::Zone(); + return nullptr; } /** * @param in_zone_name * @return */ -ZoneRepository::Zone ZoneStore::GetZone(const char *in_zone_name) +ZoneRepository::Zone *ZoneStore::GetZone(const char *in_zone_name) { - for (auto &z: zones) { + for (auto &z: m_zones) { if (z.short_name == in_zone_name) { - return z; + return &z; } } - return ZoneRepository::Zone(); + return nullptr; +} + +const std::vector &ZoneStore::GetZones() const +{ + return m_zones; +} + +// gets zone data by using explicit version and falling back to version 0 if not found +ZoneRepository::Zone *ZoneStore::GetZoneWithFallback(uint32 zone_id, int version) +{ + for (auto &z: m_zones) { + if (z.zoneidnumber == zone_id && z.version == version) { + return &z; + } + } + + // second pass, default to version 0 if specific doesn't exist + for (auto &z: m_zones) { + if (z.zoneidnumber == zone_id && z.version == 0) { + return &z; + } + } + + return nullptr; } diff --git a/zone/zone_store.h b/common/zone_store.h similarity index 69% rename from zone/zone_store.h rename to common/zone_store.h index 7238b0ade..6fe559137 100644 --- a/zone/zone_store.h +++ b/common/zone_store.h @@ -21,7 +21,6 @@ #ifndef EQEMU_ZONE_STORE_H #define EQEMU_ZONE_STORE_H -#include "zonedb.h" #include "../common/repositories/zone_repository.h" #include "../common/repositories/base/base_content_flags_repository.h" @@ -30,18 +29,21 @@ public: ZoneStore(); virtual ~ZoneStore(); - std::vector zones; + const std::vector &GetZones() const; - void LoadZones(); + void LoadZones(Database &db); - ZoneRepository::Zone GetZone(uint32 zone_id, int version = 0); - ZoneRepository::Zone GetZone(const char *in_zone_name); + ZoneRepository::Zone *GetZone(uint32 zone_id, int version = 0); + ZoneRepository::Zone *GetZone(const char *in_zone_name); uint32 GetZoneID(const char *in_zone_name); uint32 GetZoneID(std::string zone_name); std::string GetZoneName(uint32 zone_id); std::string GetZoneLongName(uint32 zone_id); const char *GetZoneName(uint32 zone_id, bool error_unknown = false); const char *GetZoneLongName(uint32 zone_id, bool error_unknown = false); + ZoneRepository::Zone *GetZoneWithFallback(uint32 zone_id, int version = 0); +private: + std::vector m_zones; }; extern ZoneStore zone_store; @@ -65,7 +67,22 @@ inline const char *ZoneLongName(uint32 zone_id, bool error_unknown = false) error_unknown ); } -inline ZoneRepository::Zone GetZone(uint32 zone_id, int version = 0) { return zone_store.GetZone(zone_id, version); }; -inline ZoneRepository::Zone GetZone(const char *in_zone_name) { return zone_store.GetZone(in_zone_name); }; +inline ZoneRepository::Zone *GetZone(uint32 zone_id, int version = 0) { return zone_store.GetZone(zone_id, version); }; +inline ZoneRepository::Zone *GetZone(const char *in_zone_name) { return zone_store.GetZone(in_zone_name); }; +inline ZoneRepository::Zone *GetZone(const char *in_zone_name, int version = 0) +{ + return zone_store.GetZone( + ZoneID( + in_zone_name + ), version + ); +}; +inline ZoneRepository::Zone *GetZoneVersionWithFallback(uint32 zone_id, int version = 0) +{ + return zone_store.GetZoneWithFallback( + zone_id, + version + ); +}; #endif //EQEMU_ZONE_STORE_H diff --git a/shared_memory/main.cpp b/shared_memory/main.cpp index 6e9453a54..cdbb6cf74 100644 --- a/shared_memory/main.cpp +++ b/shared_memory/main.cpp @@ -34,9 +34,11 @@ #include "spells.h" #include "base_data.h" #include "../common/content/world_content_service.h" +#include "../common/zone_store.h" EQEmuLogSys LogSys; WorldContentService content_service; +ZoneStore zone_store; #ifdef _WINDOWS #include diff --git a/world/CMakeLists.txt b/world/CMakeLists.txt index fbd040e60..de58f2f4e 100644 --- a/world/CMakeLists.txt +++ b/world/CMakeLists.txt @@ -32,7 +32,6 @@ SET(world_sources world_server_command_handler.cpp worlddb.cpp world_boot.cpp - world_store.cpp zonelist.cpp zoneserver.cpp ) @@ -71,7 +70,6 @@ SET(world_headers worlddb.h world_boot.h world_event_scheduler.h - world_store.h zonelist.h zoneserver.h ) diff --git a/world/adventure.cpp b/world/adventure.cpp index 8b6b67a0f..2e5a58fc1 100644 --- a/world/adventure.cpp +++ b/world/adventure.cpp @@ -11,7 +11,7 @@ #include "zonelist.h" #include "clientlist.h" #include "cliententry.h" -#include "world_store.h" +#include "../common/zone_store.h" extern ZSList zoneserver_list; extern ClientList client_list; diff --git a/world/adventure_manager.cpp b/world/adventure_manager.cpp index 62a473256..2f894134f 100644 --- a/world/adventure_manager.cpp +++ b/world/adventure_manager.cpp @@ -10,7 +10,7 @@ #include "zonelist.h" #include "clientlist.h" #include "cliententry.h" -#include "world_store.h" +#include "../common/zone_store.h" #include #include diff --git a/world/client.cpp b/world/client.cpp index fc9aa73af..e4143df68 100644 --- a/world/client.cpp +++ b/world/client.cpp @@ -46,7 +46,7 @@ #include "clientlist.h" #include "wguild_mgr.h" #include "sof_char_create_data.h" -#include "world_store.h" +#include "../common/zone_store.h" #include "../common/repositories/account_repository.h" #include @@ -1733,7 +1733,12 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc) /* Overrides if we have the tutorial flag set! */ if (cc->tutorial && RuleB(World, EnableTutorialButton)) { pp.zone_id = RuleI(World, TutorialZoneID); - content_db.GetSafePoints(ZoneName(pp.zone_id), 0, &pp.x, &pp.y, &pp.z); + auto z = GetZone(pp.zone_id); + if (z) { + pp.x = z->safe_x; + pp.y = z->safe_y; + pp.z = z->safe_z; + } } /* Will either be the same as home or tutorial if enabled. */ diff --git a/world/clientlist.cpp b/world/clientlist.cpp index 1c2b7705b..d4797d84e 100644 --- a/world/clientlist.cpp +++ b/world/clientlist.cpp @@ -33,7 +33,7 @@ #include "../common/event_sub.h" #include "web_interface.h" #include "wguild_mgr.h" -#include "world_store.h" +#include "../common/zone_store.h" #include extern WebInterfaceList web_interface; diff --git a/world/console.cpp b/world/console.cpp index 57f35a188..25822e3ef 100644 --- a/world/console.cpp +++ b/world/console.cpp @@ -30,7 +30,7 @@ #include "../common/strings.h" #include "../common/md5.h" #include "eqemu_api_world_data_service.h" -#include "world_store.h" +#include "../common/zone_store.h" #include extern ClientList client_list; diff --git a/world/eql_config.cpp b/world/eql_config.cpp index c42883497..d35429aae 100644 --- a/world/eql_config.cpp +++ b/world/eql_config.cpp @@ -21,7 +21,7 @@ #include "launcher_link.h" #include "launcher_list.h" #include "../common/strings.h" -#include "world_store.h" +#include "../common/zone_store.h" #include #include diff --git a/world/main.cpp b/world/main.cpp index badfa24f7..ddbbca8b5 100644 --- a/world/main.cpp +++ b/world/main.cpp @@ -91,12 +91,12 @@ union semun { #include "world_server_command_handler.h" #include "../common/content/world_content_service.h" #include "../common/repositories/character_task_timers_repository.h" -#include "world_store.h" +#include "../common/zone_store.h" #include "world_event_scheduler.h" #include "shared_task_manager.h" #include "world_boot.h" -WorldStore world_store; +ZoneStore zone_store; ClientList client_list; GroupLFPList LFPGroupList; ZSList zoneserver_list; diff --git a/world/world_boot.cpp b/world/world_boot.cpp index 78f413bbc..0a60e86e9 100644 --- a/world/world_boot.cpp +++ b/world/world_boot.cpp @@ -19,11 +19,12 @@ #include "world_config.h" #include "world_event_scheduler.h" #include "world_server_command_handler.h" -#include "world_store.h" +#include "../common/zone_store.h" #include "worlddb.h" #include "zonelist.h" #include "zoneserver.h" #include "../common/ip_util.h" +#include "../common/zone_store.h" extern ZSList zoneserver_list; extern WorldConfig Config; @@ -310,7 +311,7 @@ bool WorldBoot::DatabaseLoadRoutines(int argc, char **argv) LogInfo("Loading zones"); - world_store.LoadZones(); + zone_store.LoadZones(content_db); LogInfo("Clearing groups"); database.ClearGroup(); diff --git a/world/world_store.cpp b/world/world_store.cpp deleted file mode 100644 index cb114e614..000000000 --- a/world/world_store.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/** - * EQEmulator: Everquest Server Emulator - * Copyright (C) 2001-2020 EQEmulator Development Team (https://github.com/EQEmu/Server) - * - * 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 - * - */ - -#include "world_store.h" - -WorldStore::WorldStore() = default; -WorldStore::~WorldStore() = default; - -void WorldStore::LoadZones() -{ - zones = ZoneRepository::All(content_db); -} - -uint32 WorldStore::GetZoneID(const char *in_zone_name) -{ - if (in_zone_name == nullptr) { - return 0; - } - - std::string zone_name = Strings::ToLower(in_zone_name); - - return GetZoneID(zone_name); -} - -uint32 WorldStore::GetZoneID(std::string zone_name) -{ - for (auto &z: zones) { - if (z.short_name == zone_name) { - return z.zoneidnumber; - } - } - - return 0; -} - -/** - * @param zone_id - * @param error_unknown - * @return - */ -const char *WorldStore::GetZoneName(uint32 zone_id, bool error_unknown) -{ - for (auto &z: zones) { - if (z.zoneidnumber == zone_id) { - return z.short_name.c_str(); - } - } - - if (error_unknown) { - return "UNKNOWN"; - } - - return nullptr; -} - -/** - * @param zone_id - * @return - */ -std::string WorldStore::GetZoneName(uint32 zone_id) -{ - for (auto &z: zones) { - if (z.zoneidnumber == zone_id) { - return z.short_name; - } - } - - return std::string(); -} - -/** - * @param zone_id - * @param error_unknown - * @return - */ -const char *WorldStore::GetZoneLongName(uint32 zone_id, bool error_unknown) -{ - for (auto &z: zones) { - if (z.zoneidnumber == zone_id) { - return z.long_name.c_str(); - } - } - - if (error_unknown) { - return "UNKNOWN"; - } - - return nullptr; -} - -/** - * @param zone_id - * @return - */ -std::string WorldStore::GetZoneLongName(uint32 zone_id) -{ - for (auto &z: zones) { - if (z.zoneidnumber == zone_id) { - return z.long_name; - } - } - - return std::string(); -} - -/** - * @param zone_id - * @param version - * @return - */ -ZoneRepository::Zone WorldStore::GetZone(uint32 zone_id, int version) -{ - for (auto &z: zones) { - if (z.zoneidnumber == zone_id && z.version == version) { - return z; - } - } - - return ZoneRepository::Zone(); -} - -/** - * @param in_zone_name - * @return - */ -ZoneRepository::Zone WorldStore::GetZone(const char *in_zone_name) -{ - for (auto &z: zones) { - if (z.short_name == in_zone_name) { - return z; - } - } - - return ZoneRepository::Zone(); -} diff --git a/world/world_store.h b/world/world_store.h deleted file mode 100644 index ecbba4b5e..000000000 --- a/world/world_store.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * EQEmulator: Everquest Server Emulator - * Copyright (C) 2001-2020 EQEmulator Development Team (https://github.com/EQEmu/Server) - * - * 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_WORLD_STORE_H -#define EQEMU_WORLD_STORE_H - -#include "worlddb.h" -#include "../common/repositories/zone_repository.h" - -class WorldStore { -public: - WorldStore(); - virtual ~WorldStore(); - - std::vector zones{}; - - void LoadZones(); - - ZoneRepository::Zone GetZone(uint32 zone_id, int version = 0); - ZoneRepository::Zone GetZone(const char *in_zone_name); - uint32 GetZoneID(const char *in_zone_name); - uint32 GetZoneID(std::string zone_name); - std::string GetZoneName(uint32 zone_id); - std::string GetZoneLongName(uint32 zone_id); - const char *GetZoneName(uint32 zone_id, bool error_unknown = false); - const char *GetZoneLongName(uint32 zone_id, bool error_unknown = false); -}; - -extern WorldStore world_store; - -/** - * Global helpers - */ -inline uint32 ZoneID(const char *in_zone_name) { return world_store.GetZoneID(in_zone_name); } -inline uint32 ZoneID(std::string zone_name) { return world_store.GetZoneID(zone_name); } -inline const char *ZoneName(uint32 zone_id, bool error_unknown = false) -{ - return world_store.GetZoneName( - zone_id, - error_unknown - ); -} -inline const char *ZoneLongName(uint32 zone_id, bool error_unknown = false) -{ - return world_store.GetZoneLongName( - zone_id, - error_unknown - ); -} -inline ZoneRepository::Zone GetZone(uint32 zone_id, int version = 0) { return world_store.GetZone(zone_id, version); }; -inline ZoneRepository::Zone GetZone(const char *in_zone_name) { return world_store.GetZone(in_zone_name); }; - -#endif //EQEMU_WORLD_STORE_H diff --git a/world/worlddb.cpp b/world/worlddb.cpp index 8b2b27c6f..70033d988 100644 --- a/world/worlddb.cpp +++ b/world/worlddb.cpp @@ -27,7 +27,7 @@ #include "sof_char_create_data.h" #include "../common/repositories/character_instance_safereturns_repository.h" #include "../common/repositories/criteria/content_filter_criteria.h" -#include "world_store.h" +#include "../common/zone_store.h" WorldDatabase database; WorldDatabase content_db; @@ -113,10 +113,10 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, EQApplicationPacket **o buff_ptr += sizeof(CharacterSelect_Struct); for (auto row = results.begin(); row != results.end(); ++row) { CharacterSelectEntry_Struct *p_character_select_entry_struct = (CharacterSelectEntry_Struct *) buff_ptr; - PlayerProfile_Struct player_profile_struct; - EQ::InventoryProfile inventory_profile; + PlayerProfile_Struct pp; + EQ::InventoryProfile inventory_profile; - player_profile_struct.SetPlayerProfileVersion(EQ::versions::ConvertClientVersionToMobVersion(client_version)); + pp.SetPlayerProfileVersion(EQ::versions::ConvertClientVersionToMobVersion(client_version)); inventory_profile.SetInventoryVersion(client_version); inventory_profile.SetGMInventory(true); // charsel can not interact with items..but, no harm in setting to full expansion support @@ -124,7 +124,7 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, EQApplicationPacket **o uint8 has_home = 0; uint8 has_bind = 0; - memset(&player_profile_struct, 0, sizeof(PlayerProfile_Struct)); + memset(&pp, 0, sizeof(PlayerProfile_Struct)); memset(p_character_select_entry_struct->Name, 0, sizeof(p_character_select_entry_struct->Name)); strcpy(p_character_select_entry_struct->Name, row[1]); p_character_select_entry_struct->Class = (uint8) atoi(row[4]); @@ -198,12 +198,12 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, EQApplicationPacket **o has_home = 1; // If our bind count is less than 5, we need to actually make use of this data so lets parse it if (bind_count < 5) { - player_profile_struct.binds[4].zone_id = atoi(row_b[0]); - player_profile_struct.binds[4].instance_id = atoi(row_b[1]); - player_profile_struct.binds[4].x = atof(row_b[2]); - player_profile_struct.binds[4].y = atof(row_b[3]); - player_profile_struct.binds[4].z = atof(row_b[4]); - player_profile_struct.binds[4].heading = atof(row_b[5]); + pp.binds[4].zone_id = atoi(row_b[0]); + pp.binds[4].instance_id = atoi(row_b[1]); + pp.binds[4].x = atof(row_b[2]); + pp.binds[4].y = atof(row_b[3]); + pp.binds[4].z = atof(row_b[4]); + pp.binds[4].heading = atof(row_b[5]); } } @@ -234,40 +234,39 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, EQApplicationPacket **o for (auto row_d = results_bind.begin(); row_d != results_bind.end(); ++row_d) { /* If a bind_id is specified, make them start there */ if (atoi(row_d[1]) != 0) { - player_profile_struct.binds[4].zone_id = (uint32) atoi(row_d[1]); - content_db.GetSafePoints( - ZoneName(player_profile_struct.binds[4].zone_id, true), - 0, - &player_profile_struct.binds[4].x, - &player_profile_struct.binds[4].y, - &player_profile_struct.binds[4].z, - &player_profile_struct.binds[4].heading - ); + pp.binds[4].zone_id = (uint32) atoi(row_d[1]); + + auto z = GetZone(pp.binds[4].zone_id); + if (z) { + pp.binds[4].x = z->safe_x; + pp.binds[4].y = z->safe_y; + pp.binds[4].z = z->safe_z; + pp.binds[4].heading = z->safe_heading; + } } /* Otherwise, use the zone and coordinates given */ else { - player_profile_struct.binds[4].zone_id = (uint32) atoi(row_d[0]); + pp.binds[4].zone_id = (uint32) atoi(row_d[0]); float x = atof(row_d[2]); float y = atof(row_d[3]); float z = atof(row_d[4]); float heading = atof(row_d[5]); if (x == 0 && y == 0 && z == 0 && heading == 0) { - content_db.GetSafePoints( - ZoneName(player_profile_struct.binds[4].zone_id, true), - 0, - &x, - &y, - &z, - &heading - ); + auto zone = GetZone(pp.binds[4].zone_id); + if (zone) { + x = zone->safe_x; + y = zone->safe_y; + z = zone->safe_z; + heading = zone->safe_heading; + } } - player_profile_struct.binds[4].x = x; - player_profile_struct.binds[4].y = y; - player_profile_struct.binds[4].z = z; - player_profile_struct.binds[4].heading = heading; + pp.binds[4].x = x; + pp.binds[4].y = y; + pp.binds[4].z = z; + pp.binds[4].heading = heading; } } - player_profile_struct.binds[0] = player_profile_struct.binds[4]; + pp.binds[0] = pp.binds[4]; /* If no home bind set, set it */ if (has_home == 0) { std::string query = fmt::format( @@ -278,12 +277,12 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, EQApplicationPacket **o VALUES ({}, {}, {}, {}, {}, {}, {}, {}) ), character_id, - player_profile_struct.binds[4].zone_id, + pp.binds[4].zone_id, 0, - player_profile_struct.binds[4].x, - player_profile_struct.binds[4].y, - player_profile_struct.binds[4].z, - player_profile_struct.binds[4].heading, + pp.binds[4].x, + pp.binds[4].y, + pp.binds[4].z, + pp.binds[4].heading, 4 ); auto results_bset = QueryDatabase(query); @@ -298,12 +297,12 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, EQApplicationPacket **o VALUES ({}, {}, {}, {}, {}, {}, {}, {}) ), character_id, - player_profile_struct.binds[0].zone_id, + pp.binds[0].zone_id, 0, - player_profile_struct.binds[0].x, - player_profile_struct.binds[0].y, - player_profile_struct.binds[0].z, - player_profile_struct.binds[0].heading, + pp.binds[0].x, + pp.binds[0].y, + pp.binds[0].z, + pp.binds[0].heading, 0 ); auto results_bset = QueryDatabase(query); @@ -314,7 +313,7 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, EQApplicationPacket **o // we know that home and main bind must be valid here, so we don't check those // we also use home to fill in the null data like live does. for (int i = 1; i < 4; i++) { - if (player_profile_struct.binds[i].zone_id != 0) // we assume 0 is the only invalid one ... + if (pp.binds[i].zone_id != 0) // we assume 0 is the only invalid one ... continue; std::string query = fmt::format( @@ -325,12 +324,12 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, EQApplicationPacket **o VALUES ({}, {}, {}, {}, {}, {}, {}, {}) ), character_id, - player_profile_struct.binds[4].zone_id, + pp.binds[4].zone_id, 0, - player_profile_struct.binds[4].x, - player_profile_struct.binds[4].y, - player_profile_struct.binds[4].z, - player_profile_struct.binds[4].heading, + pp.binds[4].x, + pp.binds[4].y, + pp.binds[4].z, + pp.binds[4].heading, i ); auto results_bset = QueryDatabase(query); @@ -352,10 +351,10 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, EQApplicationPacket **o uint8 slot = 0; for (auto row_b = results_b.begin(); row_b != results_b.end(); ++row_b) { slot = atoi(row_b[0]); - player_profile_struct.item_tint.Slot[slot].Red = atoi(row_b[1]); - player_profile_struct.item_tint.Slot[slot].Green = atoi(row_b[2]); - player_profile_struct.item_tint.Slot[slot].Blue = atoi(row_b[3]); - player_profile_struct.item_tint.Slot[slot].UseTint = atoi(row_b[4]); + pp.item_tint.Slot[slot].Red = atoi(row_b[1]); + pp.item_tint.Slot[slot].Green = atoi(row_b[2]); + pp.item_tint.Slot[slot].Blue = atoi(row_b[3]); + pp.item_tint.Slot[slot].UseTint = atoi(row_b[4]); } if (GetCharSelInventory(account_id, p_character_select_entry_struct->Name, &inventory_profile)) { @@ -394,8 +393,8 @@ void WorldDatabase::GetCharSelectInfo(uint32 account_id, EQApplicationPacket **o } else { // Armor Materials/Models uint32 color = ( - player_profile_struct.item_tint.Slot[matslot].UseTint ? - player_profile_struct.item_tint.Slot[matslot].Color : + pp.item_tint.Slot[matslot].UseTint ? + pp.item_tint.Slot[matslot].Color : inst->GetColor() ); p_character_select_entry_struct->Equip[matslot].Material = item->Material; @@ -527,7 +526,7 @@ int WorldDatabase::MoveCharacterToInstanceSafeReturn( } bool WorldDatabase::GetStartZone( - PlayerProfile_Struct *p_player_profile_struct, + PlayerProfile_Struct *pp, CharCreate_Struct *p_char_create_struct, bool is_titanium ) @@ -539,20 +538,20 @@ bool WorldDatabase::GetStartZone( // For now, if no row matching row is found, send them to Crescent Reach, as that is probably the most likely // reason for no match being found. // - if (!p_player_profile_struct || !p_char_create_struct) { + if (!pp || !p_char_create_struct) { return false; } - p_player_profile_struct->x = 0; - p_player_profile_struct->y = 0; - p_player_profile_struct->z = 0; - p_player_profile_struct->heading = 0; - p_player_profile_struct->zone_id = 0; - p_player_profile_struct->binds[0].x = 0; - p_player_profile_struct->binds[0].y = 0; - p_player_profile_struct->binds[0].z = 0; - p_player_profile_struct->binds[0].zone_id = 0; - p_player_profile_struct->binds[0].instance_id = 0; + pp->x = 0; + pp->y = 0; + pp->z = 0; + pp->heading = 0; + pp->zone_id = 0; + pp->binds[0].x = 0; + pp->binds[0].y = 0; + pp->binds[0].z = 0; + pp->binds[0].zone_id = 0; + pp->binds[0].instance_id = 0; // see if we have an entry for start_zone. We can support both titanium & SOF+ by having two entries per class/race/deity combo with different zone_ids std::string query; @@ -592,53 +591,51 @@ bool WorldDatabase::GetStartZone( if (results.RowCount() == 0) { printf("No start_zones entry in database, using defaults\n"); - is_titanium ? SetTitaniumDefaultStartZone(p_player_profile_struct, p_char_create_struct) : SetSoFDefaultStartZone(p_player_profile_struct, p_char_create_struct); + is_titanium ? SetTitaniumDefaultStartZone(pp, p_char_create_struct) : SetSoFDefaultStartZone(pp, p_char_create_struct); } else { LogInfo("Found starting location in start_zones"); auto row = results.begin(); - p_player_profile_struct->x = atof(row[0]); - p_player_profile_struct->y = atof(row[1]); - p_player_profile_struct->z = atof(row[2]); - p_player_profile_struct->heading = atof(row[3]); - p_player_profile_struct->zone_id = atoi(row[4]); - p_player_profile_struct->binds[0].zone_id = atoi(row[5]); - p_player_profile_struct->binds[0].x = atof(row[6]); - p_player_profile_struct->binds[0].y = atof(row[7]); - p_player_profile_struct->binds[0].z = atof(row[8]); - p_player_profile_struct->binds[0].heading = atof(row[3]); + pp->x = atof(row[0]); + pp->y = atof(row[1]); + pp->z = atof(row[2]); + pp->heading = atof(row[3]); + pp->zone_id = atoi(row[4]); + pp->binds[0].zone_id = atoi(row[5]); + pp->binds[0].x = atof(row[6]); + pp->binds[0].y = atof(row[7]); + pp->binds[0].z = atof(row[8]); + pp->binds[0].heading = atof(row[3]); } if ( - p_player_profile_struct->x == 0 && - p_player_profile_struct->y == 0 && - p_player_profile_struct->z == 0 && - p_player_profile_struct->heading == 0 + pp->x == 0 && + pp->y == 0 && + pp->z == 0 && + pp->heading == 0 ) { - content_db.GetSafePoints( - ZoneName(p_player_profile_struct->zone_id, true), - 0, - &p_player_profile_struct->x, - &p_player_profile_struct->y, - &p_player_profile_struct->z, - &p_player_profile_struct->heading - ); + auto zone = GetZone(pp->zone_id); + if (zone) { + pp->x = zone->safe_x; + pp->y = zone->safe_y; + pp->z = zone->safe_z; + pp->heading = zone->safe_heading; + } } if ( - p_player_profile_struct->binds[0].x == 0 && - p_player_profile_struct->binds[0].y == 0 && - p_player_profile_struct->binds[0].z == 0 && - p_player_profile_struct->binds[0].heading == 0 + pp->binds[0].x == 0 && + pp->binds[0].y == 0 && + pp->binds[0].z == 0 && + pp->binds[0].heading == 0 ) { - content_db.GetSafePoints( - ZoneName(p_player_profile_struct->binds[0].zone_id, true), - 0, - &p_player_profile_struct->binds[0].x, - &p_player_profile_struct->binds[0].y, - &p_player_profile_struct->binds[0].z, - &p_player_profile_struct->binds[0].heading - ); + auto zone = GetZone(pp->binds[0].zone_id); + if (zone) { + pp->binds[0].x = zone->safe_x; + pp->binds[0].y = zone->safe_y; + pp->binds[0].z = zone->safe_z; + pp->binds[0].heading = zone->safe_heading; + } } return true; diff --git a/world/worlddb.h b/world/worlddb.h index ae26b0ff7..d5bfdf3f5 100644 --- a/world/worlddb.h +++ b/world/worlddb.h @@ -29,7 +29,7 @@ struct CharacterSelect_Struct; class WorldDatabase : public SharedDatabase { public: - bool GetStartZone(PlayerProfile_Struct* p_player_profile_struct, CharCreate_Struct* p_char_create_struct, bool is_titanium); + bool GetStartZone(PlayerProfile_Struct* pp, CharCreate_Struct* p_char_create_struct, bool is_titanium); void GetCharSelectInfo(uint32 account_id, EQApplicationPacket **out_app, uint32 client_version_bit); int MoveCharacterToBind(int character_id, uint8 bind_number = 0); int MoveCharacterToInstanceSafeReturn(int character_id, int instance_zone_id, int instance_id); diff --git a/world/zonelist.cpp b/world/zonelist.cpp index 4e79369e9..d5cff024f 100644 --- a/world/zonelist.cpp +++ b/world/zonelist.cpp @@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "../common/json/json.h" #include "../common/event_sub.h" #include "web_interface.h" -#include "world_store.h" +#include "../common/zone_store.h" extern uint32 numzones; extern EQ::Random emu_random; diff --git a/world/zoneserver.cpp b/world/zoneserver.cpp index ffff59b28..abad27af1 100644 --- a/world/zoneserver.cpp +++ b/world/zoneserver.cpp @@ -35,7 +35,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "adventure_manager.h" #include "ucs.h" #include "queryserv.h" -#include "world_store.h" +#include "../common/zone_store.h" #include "dynamic_zone.h" #include "dynamic_zone_manager.h" #include "expedition_message.h" @@ -1324,6 +1324,7 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) { case ServerOP_ReloadVeteranRewards: case ServerOP_ReloadWorld: case ServerOP_ReloadZonePoints: + case ServerOP_ReloadZoneData: case ServerOP_RezzPlayerAccept: case ServerOP_SpawnStatusChange: case ServerOP_UpdateSpawn: diff --git a/zone/CMakeLists.txt b/zone/CMakeLists.txt index 51fc7f875..5cd5475b1 100644 --- a/zone/CMakeLists.txt +++ b/zone/CMakeLists.txt @@ -161,7 +161,6 @@ SET(zone_sources zonedb.cpp zone_event_scheduler.cpp zone_reload.cpp - zone_store.cpp zoning.cpp ) @@ -284,7 +283,6 @@ SET(zone_headers zonedb.h zonedump.h zone_reload.h - zone_store.h ) ADD_EXECUTABLE(zone ${zone_sources} ${zone_headers}) diff --git a/zone/aa.cpp b/zone/aa.cpp index e23dbba15..5b4a8a6ee 100644 --- a/zone/aa.cpp +++ b/zone/aa.cpp @@ -33,7 +33,7 @@ Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net) #include "string_ids.h" #include "titles.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" extern QueryServ* QServ; diff --git a/zone/api_service.cpp b/zone/api_service.cpp index 43fe02ea0..307cebf17 100644 --- a/zone/api_service.cpp +++ b/zone/api_service.cpp @@ -22,7 +22,7 @@ #include "../common/net/websocket_server.h" #include "../common/eqemu_logsys.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "client.h" #include "entity.h" #include "corpse.h" diff --git a/zone/bot.cpp b/zone/bot.cpp index 27cbfbee8..1fbc3ffe1 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -8184,9 +8184,9 @@ void Bot::CalcRestState() { } } - RestRegenHP = 6 * (GetMaxHP() / zone->newzone_data.FastRegenHP); - RestRegenMana = 6 * (GetMaxMana() / zone->newzone_data.FastRegenMana); - RestRegenEndurance = 6 * (GetMaxEndurance() / zone->newzone_data.FastRegenEndurance); + RestRegenHP = 6 * (GetMaxHP() / zone->newzone_data.fast_regen_hp); + RestRegenMana = 6 * (GetMaxMana() / zone->newzone_data.fast_regen_mana); + RestRegenEndurance = 6 * (GetMaxEndurance() / zone->newzone_data.fast_regen_endurance); } int32 Bot::LevelRegen() { diff --git a/zone/bot.h b/zone/bot.h index 48d60b246..1f1bd1724 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -29,7 +29,7 @@ #include "groups.h" #include "corpse.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "string_ids.h" #include "../common/misc_functions.h" #include "../common/global_define.h" diff --git a/zone/bot_command.cpp b/zone/bot_command.cpp index 0de652e28..f14de45a4 100644 --- a/zone/bot_command.cpp +++ b/zone/bot_command.cpp @@ -61,7 +61,7 @@ #include "bot_command.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "guild_mgr.h" #include "map.h" #include "doors.h" diff --git a/zone/bot_database.cpp b/zone/bot_database.cpp index 464e0bd70..e3db3781a 100644 --- a/zone/bot_database.cpp +++ b/zone/bot_database.cpp @@ -24,7 +24,7 @@ #include "../common/eqemu_logsys.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "bot.h" #include "client.h" diff --git a/zone/client.cpp b/zone/client.cpp index 1f580f009..74a9a8888 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -46,7 +46,7 @@ extern volatile bool RunLoops; #include "position.h" #include "worldserver.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "petitions.h" #include "command.h" #include "water_map.h" @@ -5371,14 +5371,13 @@ void Client::SetStartZone(uint32 zoneid, float x, float y, float z, float headin } if (x == 0 && y == 0 && z == 0) { - content_db.GetSafePoints( - ZoneName(m_pp.binds[4].zone_id), - 0, - &m_pp.binds[4].x, - &m_pp.binds[4].y, - &m_pp.binds[4].z, - &m_pp.binds[4].heading - ); + auto zd = GetZone(m_pp.binds[4].zone_id); + if (zd) { + m_pp.binds[4].x = zd->safe_x; + m_pp.binds[4].y = zd->safe_y; + m_pp.binds[4].z = zd->safe_z; + m_pp.binds[4].heading = zd->safe_heading; + } } else { m_pp.binds[4].x = x; @@ -9427,7 +9426,7 @@ bool Client::GotoPlayerRaid(const std::string& player_name) if (!GetRaid()) { return GotoPlayer(player_name); } - + for (auto &m: GetRaid()->members) { if (m.member && m.member->IsClient()) { auto c = m.member->CastToClient(); diff --git a/zone/client.h b/zone/client.h index efa64ba96..0ae846e14 100644 --- a/zone/client.h +++ b/zone/client.h @@ -63,7 +63,7 @@ namespace EQ #include "questmgr.h" #include "zone.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "task_manager.h" #include "task_client_state.h" #include "cheat_manager.h" diff --git a/zone/client_mods.cpp b/zone/client_mods.cpp index 1394d7695..2d18733c5 100644 --- a/zone/client_mods.cpp +++ b/zone/client_mods.cpp @@ -292,7 +292,7 @@ int64 Client::CalcHPRegen(bool bCombat) if (!bCombat && CanFastRegen() && (IsSitting() || CanMedOnHorse())) { auto max_hp = GetMaxHP(); - int fast_regen = 6 * (max_hp / zone->newzone_data.FastRegenHP); + int fast_regen = 6 * (max_hp / zone->newzone_data.fast_regen_hp); if (base < fast_regen) // weird, but what the client is doing base = fast_regen; } @@ -771,7 +771,7 @@ int64 Client::CalcManaRegen(bool bCombat) if (!bCombat && CanFastRegen() && (IsSitting() || CanMedOnHorse())) { auto max_mana = GetMaxMana(); - int fast_regen = 6 * (max_mana / zone->newzone_data.FastRegenMana); + int fast_regen = 6 * (max_mana / zone->newzone_data.fast_regen_mana); if (regen < fast_regen) // weird, but what the client is doing regen = fast_regen; } @@ -1801,7 +1801,7 @@ int64 Client::CalcEnduranceRegen(bool bCombat) int64 regen = base; if (!bCombat && CanFastRegen() && (IsSitting() || CanMedOnHorse())) { auto max_end = GetMaxEndurance(); - int fast_regen = 6 * (max_end / zone->newzone_data.FastRegenEndurance); + int fast_regen = 6 * (max_end / zone->newzone_data.fast_regen_endurance); if (aa_regen < fast_regen) // weird, but what the client is doing aa_regen = fast_regen; } diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index d258dbf9f..10bc7042e 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -6638,17 +6638,13 @@ void Client::Handle_OP_GMZoneRequest(const EQApplicationPacket *app) strcpy(target_zone, zone_short_name); // this both loads the safe points and does a sanity check on zone name - if (!content_db.GetSafePoints( - target_zone, - 0, - &target_x, - &target_y, - &target_z, - &target_heading, - &min_status, - &min_level - )) { + auto z = GetZone(target_zone, 0); + if (z) { target_zone[0] = 0; + target_x = z->safe_x; + target_y = z->safe_y; + target_z = z->safe_z; + target_heading = z->safe_heading; } auto outapp = new EQApplicationPacket(OP_GMZoneRequest, sizeof(GMZoneRequest_Struct)); diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 4f2cb777e..eb8c53249 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -54,7 +54,7 @@ #include "worldserver.h" #include "zone.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" extern QueryServ* QServ; extern Zone* zone; diff --git a/zone/data_bucket.cpp b/zone/data_bucket.cpp index 59b9a1b76..58b2d6d8e 100644 --- a/zone/data_bucket.cpp +++ b/zone/data_bucket.cpp @@ -2,7 +2,7 @@ #include #include "../common/strings.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include #include #include diff --git a/zone/doors.cpp b/zone/doors.cpp index 963e58fe4..e824df1c8 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -28,7 +28,7 @@ #include "string_ids.h" #include "worldserver.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "../common/repositories/criteria/content_filter_criteria.h" #include diff --git a/zone/effects.cpp b/zone/effects.cpp index 1515b7122..bbced07f8 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -28,7 +28,7 @@ #include "string_ids.h" #include "worldserver.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "position.h" float Mob::GetActSpellRange(uint16 spell_id, float range, bool IsBard) diff --git a/zone/forage.cpp b/zone/forage.cpp index 58ea6f026..21074b4a4 100644 --- a/zone/forage.cpp +++ b/zone/forage.cpp @@ -30,7 +30,7 @@ #include "titles.h" #include "water_map.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "../common/repositories/criteria/content_filter_criteria.h" #include diff --git a/zone/gm_commands/gmzone.cpp b/zone/gm_commands/gmzone.cpp index d0914ab5a..94b462706 100755 --- a/zone/gm_commands/gmzone.cpp +++ b/zone/gm_commands/gmzone.cpp @@ -11,10 +11,10 @@ void command_gmzone(Client *c, const Seperator *sep) std::string zone_short_name = Strings::ToLower( sep->IsNumber(1) ? - ZoneName(std::stoul(sep->arg[1]), true) : - sep->arg[1] + ZoneName(std::stoul(sep->arg[1]), true) : + sep->arg[1] ); - bool is_unknown_zone = zone_short_name.find("unknown") != std::string::npos; + bool is_unknown_zone = zone_short_name.find("unknown") != std::string::npos; if (is_unknown_zone) { c->Message( Chat::White, @@ -41,14 +41,14 @@ void command_gmzone(Client *c, const Seperator *sep) auto zone_version = ( sep->IsNumber(2) ? - std::stoul(sep->arg[2]) : - 0 + std::stoul(sep->arg[2]) : + 0 ); std::string instance_identifier = ( sep->arg[3] ? - sep->arg[3] : - "gmzone" + sep->arg[3] : + "gmzone" ); auto bucket_key = fmt::format( @@ -58,9 +58,9 @@ void command_gmzone(Client *c, const Seperator *sep) zone_version ); - auto existing_zone_instance = DataBucket::GetData(bucket_key); - uint16 instance_id = 0; - uint32 duration = 100000000; + auto existing_zone_instance = DataBucket::GetData(bucket_key); + uint16 instance_id = 0; + uint32 duration = 100000000; if (!existing_zone_instance.empty()) { instance_id = std::stoi(existing_zone_instance); @@ -106,21 +106,12 @@ void command_gmzone(Client *c, const Seperator *sep) if (instance_id) { float target_x = -1, target_y = -1, target_z = -1, target_heading = -1; - int16 min_status = AccountStatus::Player; - uint8 min_level = 0; - if ( - !content_db.GetSafePoints( - zone_short_name.c_str(), - zone_version, - &target_x, - &target_y, - &target_z, - &target_heading, - &min_status, - &min_level - ) - ) { + auto z = GetZoneVersionWithFallback( + ZoneID(zone_short_name.c_str()), + zone_version + ); + if (!z) { c->Message( Chat::White, fmt::format( @@ -130,8 +121,14 @@ void command_gmzone(Client *c, const Seperator *sep) zone_short_name ).c_str() ); + return; } + target_x = z->safe_x; + target_y = z->safe_y; + target_z = z->safe_z; + target_heading = z->safe_heading; + c->Message( Chat::White, fmt::format( diff --git a/zone/gm_commands/reload.cpp b/zone/gm_commands/reload.cpp index 99d91ed6d..eeb5c20d8 100644 --- a/zone/gm_commands/reload.cpp +++ b/zone/gm_commands/reload.cpp @@ -68,13 +68,13 @@ void command_reload(Client *c, const Seperator *sep) ServerPacket* pack = nullptr; if (is_aa) { - c->Message(Chat::White, "Attempting to reload Alternate Advancement Data globally."); + c->Message(Chat::White, "Attempting to reload Alternate Advancement Data globally."); pack = new ServerPacket(ServerOP_ReloadAAData, 0); } else if (is_alternate_currencies) { - c->Message(Chat::White, "Attempting to reload Alternate Currencies globally."); + c->Message(Chat::White, "Attempting to reload Alternate Currencies globally."); pack = new ServerPacket(ServerOP_ReloadAlternateCurrencies, 0); } else if (is_blocked_spells) { - c->Message(Chat::White, "Attempting to reload Blocked Spells globally."); + c->Message(Chat::White, "Attempting to reload Blocked Spells globally."); pack = new ServerPacket(ServerOP_ReloadBlockedSpells, 0); } else if (is_commands) { c->Message(Chat::White, "Attempting to reload Commands globally."); @@ -83,20 +83,20 @@ void command_reload(Client *c, const Seperator *sep) c->Message(Chat::White, "Attempting to reload Content Flags globally."); pack = new ServerPacket(ServerOP_ReloadContentFlags, 0); } else if (is_doors) { - c->Message(Chat::White, "Attempting to reload Doors globally."); + c->Message(Chat::White, "Attempting to reload Doors globally."); pack = new ServerPacket(ServerOP_ReloadDoors, 0); } else if (is_dztemplates) { c->Message(Chat::White, "Attempting to reload Dynamic Zone Templates globally."); pack = new ServerPacket(ServerOP_ReloadDzTemplates, 0); } else if (is_ground_spawns) { - c->Message(Chat::White, "Attempting to reload Ground Spawns globally."); + c->Message(Chat::White, "Attempting to reload Ground Spawns globally."); pack = new ServerPacket(ServerOP_ReloadGroundSpawns, 0); } else if (is_level_mods) { if (!RuleB(Zone, LevelBasedEXPMods)) { c->Message(Chat::White, "Level Based Experience Modifiers are disabled."); return; } - + c->Message(Chat::White, "Attempting to reload Level Based Experience Modifiers globally."); pack = new ServerPacket(ServerOP_ReloadLevelEXPMods, 0); } else if (is_logs) { @@ -137,7 +137,7 @@ void command_reload(Client *c, const Seperator *sep) } else if (is_rules) { c->Message(Chat::White, "Attempting to reload Rules globally."); pack = new ServerPacket(ServerOP_ReloadRules, 0); - } else if (is_static) { + } else if (is_static) { c->Message(Chat::White, "Attempting to reload Static Zone Data globally."); pack = new ServerPacket(ServerOP_ReloadStaticZoneData, 0); } else if (is_tasks) { @@ -148,11 +148,11 @@ void command_reload(Client *c, const Seperator *sep) } else { task_id = std::stoul(sep->arg[2]); } - + auto rts = (ReloadTasks_Struct*) pack->pBuffer; rts->reload_type = RELOADTASKS; rts->task_id = task_id; - } else if (is_titles) { + } else if (is_titles) { c->Message(Chat::White, "Attempting to reload Titles globally."); pack = new ServerPacket(ServerOP_ReloadTitles, 0); } else if (is_traps) { @@ -221,6 +221,8 @@ void command_reload(Client *c, const Seperator *sep) auto RW = (ReloadWorld_Struct *) pack->pBuffer; RW->global_repop = global_repop; } else if (is_zone) { + zone_store.LoadZones(content_db); + if (arguments < 2) { c->Message( Chat::White, @@ -260,7 +262,7 @@ void command_reload(Client *c, const Seperator *sep) std::stoul(sep->arg[3]) : 0 ); - + auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); entity_list.QueueClients(c, outapp); @@ -287,11 +289,11 @@ void command_reload(Client *c, const Seperator *sep) ) ).c_str() ); - } else if (is_zone_points) { + } else if (is_zone_points) { c->Message(Chat::White, "Attempting to reloading Zone Points globally."); pack = new ServerPacket(ServerOP_ReloadZonePoints, 0); } - + if (pack) { worldserver.SendPacket(pack); } diff --git a/zone/gm_commands/zheader.cpp b/zone/gm_commands/zheader.cpp index c50608767..f7449344c 100755 --- a/zone/gm_commands/zheader.cpp +++ b/zone/gm_commands/zheader.cpp @@ -31,12 +31,14 @@ void command_zheader(Client *c, const Seperator *sep) std::stoul(sep->arg[3]) : 0 ); - + auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size); entity_list.QueueClients(c, outapp); safe_delete(outapp); + zone_store.LoadZones(content_db); + c->Message( Chat::White, fmt::format( diff --git a/zone/gm_commands/zone.cpp b/zone/gm_commands/zone.cpp index ee15e7f9a..e982a176a 100644 --- a/zone/gm_commands/zone.cpp +++ b/zone/gm_commands/zone.cpp @@ -59,12 +59,14 @@ void command_zone(Client *c, const Seperator *sep) auto z = sep->IsNumber(4) ? std::stof(sep->arg[4]) : 0.0f; auto zone_mode = sep->IsNumber(2) ? ZoneSolicited : ZoneToSafeCoords; + auto zd = GetZone(zone_id); + c->MovePC( zone_id, x, y, z, - 0.0f, + zd ? zd->safe_heading : 0.0f, 0, zone_mode ); diff --git a/zone/gm_commands/zstats.cpp b/zone/gm_commands/zstats.cpp index 7468cf1b2..ab9c65ec9 100755 --- a/zone/gm_commands/zstats.cpp +++ b/zone/gm_commands/zstats.cpp @@ -159,7 +159,7 @@ void command_zstats(Client *c, const Seperator *sep) Chat::White, fmt::format( "Suspend Buffs: {}", - zone->newzone_data.SuspendBuffs + zone->newzone_data.suspend_buffs ).c_str() ); @@ -168,9 +168,9 @@ void command_zstats(Client *c, const Seperator *sep) Chat::White, fmt::format( "Regen | Health: {} Mana: {} Endurance: {}", - zone->newzone_data.FastRegenHP, - zone->newzone_data.FastRegenMana, - zone->newzone_data.FastRegenEndurance + zone->newzone_data.fast_regen_hp, + zone->newzone_data.fast_regen_mana, + zone->newzone_data.fast_regen_endurance ).c_str() ); @@ -179,7 +179,7 @@ void command_zstats(Client *c, const Seperator *sep) Chat::White, fmt::format( "NPC Max Aggro Distance: {}", - zone->newzone_data.NPCAggroMaxDist + zone->newzone_data.npc_aggro_max_dist ).c_str() ); @@ -197,8 +197,8 @@ void command_zstats(Client *c, const Seperator *sep) Chat::White, fmt::format( "Lava Damage | Min: {} Max: {}", - zone->newzone_data.MinLavaDamage, - zone->newzone_data.LavaDamage + zone->newzone_data.min_lava_damage, + zone->newzone_data.lava_damage ).c_str() ); } diff --git a/zone/guild_mgr.cpp b/zone/guild_mgr.cpp index 146651acf..07275f078 100644 --- a/zone/guild_mgr.cpp +++ b/zone/guild_mgr.cpp @@ -24,7 +24,7 @@ #include "guild_mgr.h" #include "worldserver.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" ZoneGuildManager guild_mgr; GuildBankManager *GuildBanks; diff --git a/zone/inventory.cpp b/zone/inventory.cpp index b7b5d33ce..8376b9f9f 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -23,7 +23,7 @@ #include "quest_parser_collection.h" #include "worldserver.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" extern WorldServer worldserver; diff --git a/zone/loottables.cpp b/zone/loottables.cpp index f4cc8d767..27408a7fc 100644 --- a/zone/loottables.cpp +++ b/zone/loottables.cpp @@ -26,7 +26,7 @@ #include "mob.h" #include "npc.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "global_loot_manager.h" #include "../common/repositories/criteria/content_filter_criteria.h" #include "../common/say_link.h" diff --git a/zone/lua_expedition.cpp b/zone/lua_expedition.cpp index 6955e54cb..105b5782a 100644 --- a/zone/lua_expedition.cpp +++ b/zone/lua_expedition.cpp @@ -2,7 +2,7 @@ #include "lua_expedition.h" #include "expedition.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "lua.hpp" #include #include diff --git a/zone/main.cpp b/zone/main.cpp index 627f9e9b4..bb74b00e4 100644 --- a/zone/main.cpp +++ b/zone/main.cpp @@ -49,7 +49,7 @@ #include "bot_command.h" #endif #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "titles.h" #include "guild_mgr.h" #include "task_manager.h" @@ -78,7 +78,6 @@ #else #include #include "../common/unix.h" -#include "zone_store.h" #include "zone_event_scheduler.h" #endif @@ -303,7 +302,7 @@ int main(int argc, char** argv) { LogInfo("Loading zone names"); - zone_store.LoadZones(); + zone_store.LoadZones(content_db); LogInfo("Loading items"); if (!database.LoadItems(hotfix_name)) { diff --git a/zone/merc.cpp b/zone/merc.cpp index f452a1a3f..687c8068f 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -1168,11 +1168,11 @@ void Merc::CalcRestState() { } } - RestRegenHP = 6 * (GetMaxHP() / zone->newzone_data.FastRegenHP); + RestRegenHP = 6 * (GetMaxHP() / zone->newzone_data.fast_regen_hp); - RestRegenMana = 6 * (GetMaxMana() / zone->newzone_data.FastRegenMana); + RestRegenMana = 6 * (GetMaxMana() / zone->newzone_data.fast_regen_mana); - RestRegenEndurance = 6 * (GetMaxEndurance() / zone->newzone_data.FastRegenEndurance); + RestRegenEndurance = 6 * (GetMaxEndurance() / zone->newzone_data.fast_regen_endurance); } bool Merc::HasSkill(EQ::skills::SkillType skill_id) const { diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 8fd428920..e0596ec8e 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -1075,7 +1075,7 @@ void Mob::AI_Process() { // NPCs will forget people after 10 mins of not interacting with them or out of range // both of these maybe zone specific, hardcoded for now if (hate_list_cleanup_timer.Check()) { - hate_list.RemoveStaleEntries(600000, static_cast(zone->newzone_data.NPCAggroMaxDist)); + hate_list.RemoveStaleEntries(600000, static_cast(zone->newzone_data.npc_aggro_max_dist)); if (hate_list.IsHateListEmpty()) { AI_Event_NoLongerEngaged(); zone->DelAggroMob(); diff --git a/zone/mob_appearance.cpp b/zone/mob_appearance.cpp index 19a81dd9c..7cff37de4 100644 --- a/zone/mob_appearance.cpp +++ b/zone/mob_appearance.cpp @@ -27,7 +27,7 @@ #include "mob.h" #include "quest_parser_collection.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #ifdef BOTS #include "bot.h" diff --git a/zone/mod_functions_base.cpp b/zone/mod_functions_base.cpp index 3f30b066a..a6ce9e8d5 100644 --- a/zone/mod_functions_base.cpp +++ b/zone/mod_functions_base.cpp @@ -8,7 +8,7 @@ #include "zone.h" #include "spawngroup.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "npc.h" #include "mob.h" #include "client.h" diff --git a/zone/npc.h b/zone/npc.h index 7c86cc894..1417cb2d6 100644 --- a/zone/npc.h +++ b/zone/npc.h @@ -23,7 +23,7 @@ #include "mob.h" #include "qglobals.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "zonedump.h" #include "../common/loottable.h" diff --git a/zone/object.cpp b/zone/object.cpp index 34769c6e1..6af66895f 100644 --- a/zone/object.cpp +++ b/zone/object.cpp @@ -26,7 +26,7 @@ #include "quest_parser_collection.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "../common/repositories/criteria/content_filter_criteria.h" #include diff --git a/zone/perl_expedition.cpp b/zone/perl_expedition.cpp index b757aed39..c46cb907c 100644 --- a/zone/perl_expedition.cpp +++ b/zone/perl_expedition.cpp @@ -4,7 +4,7 @@ #include "embperl.h" #include "expedition.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "../common/global_define.h" void Perl_Expedition_AddLockout(Expedition* self, std::string event_name, uint32_t seconds) diff --git a/zone/petitions.h b/zone/petitions.h index 4a6e9d2ff..2e8ee96a6 100644 --- a/zone/petitions.h +++ b/zone/petitions.h @@ -25,7 +25,7 @@ #include "client.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" class Client; diff --git a/zone/pets.cpp b/zone/pets.cpp index a1bdd9248..f8156ffd5 100644 --- a/zone/pets.cpp +++ b/zone/pets.cpp @@ -27,7 +27,7 @@ #include "pets.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index ea6486ab9..2c65923e3 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -35,7 +35,7 @@ #include "worldserver.h" #include "zone.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "dialogue_window.h" #include "string_ids.h" @@ -3364,11 +3364,11 @@ void QuestManager::UpdateZoneHeader(std::string type, std::string value) { } else if (strcasecmp(type.c_str(), "fog_density") == 0) { zone->newzone_data.fog_density = atof(value.c_str()); } else if (strcasecmp(type.c_str(), "suspendbuffs") == 0) { - zone->newzone_data.SuspendBuffs = atoi(value.c_str()); + zone->newzone_data.suspend_buffs = atoi(value.c_str()); } else if (strcasecmp(type.c_str(), "lavadamage") == 0) { - zone->newzone_data.LavaDamage = atoi(value.c_str()); + zone->newzone_data.lava_damage = atoi(value.c_str()); } else if (strcasecmp(type.c_str(), "minlavadamage") == 0) { - zone->newzone_data.MinLavaDamage = atoi(value.c_str()); + zone->newzone_data.min_lava_damage = atoi(value.c_str()); } auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct)); diff --git a/zone/spawn2.cpp b/zone/spawn2.cpp index 0495a051b..c478db1e4 100644 --- a/zone/spawn2.cpp +++ b/zone/spawn2.cpp @@ -26,7 +26,7 @@ #include "worldserver.h" #include "zone.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" extern EntityList entity_list; extern Zone* zone; diff --git a/zone/spawngroup.cpp b/zone/spawngroup.cpp index 84ae2a8f9..7f0c1b4e1 100644 --- a/zone/spawngroup.cpp +++ b/zone/spawngroup.cpp @@ -24,7 +24,7 @@ #include "spawngroup.h" #include "zone.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "../common/repositories/criteria/content_filter_criteria.h" extern EntityList entity_list; diff --git a/zone/task_client_state.cpp b/zone/task_client_state.cpp index 0d90337bb..d57d96c3a 100644 --- a/zone/task_client_state.cpp +++ b/zone/task_client_state.cpp @@ -2410,7 +2410,7 @@ void ClientTaskState::CreateTaskDynamicZone(Client* client, int task_id, Dynamic // dz should be named the version-based zone name (used in choose zone window and dz window on live) auto zone_info = zone_store.GetZone(dz_request.GetZoneID(), dz_request.GetZoneVersion()); - dz_request.SetName(zone_info.long_name.empty() ? task->title : zone_info.long_name); + dz_request.SetName(zone_info->long_name.empty() ? task->title : zone_info->long_name); dz_request.SetMinPlayers(task->min_players); dz_request.SetMaxPlayers(task->max_players); diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index 970f47795..1d3f95be0 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -33,8 +33,8 @@ #include "string_ids.h" #include "titles.h" #include "zonedb.h" -#include "zone_store.h" #include "../common/repositories/char_recipe_list_repository.h" +#include "../common/zone_store.h" #include "../common/repositories/tradeskill_recipe_repository.h" extern QueryServ* QServ; diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index ada8778a6..b8509c1ad 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -2041,6 +2041,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) content_db.LoadStaticZonePoints(&zone->zone_point_list, zone->GetShortName(), zone->GetInstanceVersion()); break; } + case ServerOP_ReloadZoneData: + { + zone_store.LoadZones(content_db); + zone->LoadZoneCFG(zone->GetShortName(), zone->GetInstanceVersion()); + zone->SendReloadMessage("Zone Data"); + break; + } case ServerOP_CameraShake: { if (zone) diff --git a/zone/zone.cpp b/zone/zone.cpp index 0f9cb2fc3..9946f7458 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -950,14 +950,14 @@ void Zone::LoadZoneDoors() } Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name) -: initgrids_timer(10000), - autoshutdown_timer((RuleI(Zone, AutoShutdownDelay))), - clientauth_timer(AUTHENTICATION_TIMEOUT * 1000), - spawn2_timer(1000), - hot_reload_timer(1000), - qglobal_purge_timer(30000), - m_SafePoint(0.0f,0.0f,0.0f,0.0f), - m_Graveyard(0.0f,0.0f,0.0f,0.0f) +: initgrids_timer(10000), + autoshutdown_timer((RuleI(Zone, AutoShutdownDelay))), + clientauth_timer(AUTHENTICATION_TIMEOUT * 1000), + spawn2_timer(1000), + hot_reload_timer(1000), + qglobal_purge_timer(30000), + m_safe_points(0.0f, 0.0f, 0.0f, 0.0f), + m_graveyard(0.0f, 0.0f, 0.0f, 0.0f) { zoneid = in_zoneid; instanceid = in_instanceid; @@ -977,7 +977,7 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name) tradevar = 0; lootvar = 0; - if(RuleB(TaskSystem, EnableTaskSystem)) { + if (RuleB(TaskSystem, EnableTaskSystem)) { task_manager->LoadProximities(zoneid); } @@ -985,21 +985,41 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name) strlwr(short_name); memset(file_name, 0, sizeof(file_name)); long_name = 0; - aggroedmobs =0; - pgraveyard_id = 0; + aggroedmobs =0; + m_graveyard_id = 0; pgraveyard_zoneid = 0; - pMaxClients = 0; - pvpzone = false; - if(database.GetServerType() == 1) + m_max_clients = 0; + pvpzone = false; + + if (database.GetServerType() == 1) { pvpzone = true; - content_db.GetZoneLongName(short_name, &long_name, file_name, &m_SafePoint.x, &m_SafePoint.y, &m_SafePoint.z, &pgraveyard_id, &pMaxClients); - if(graveyard_id() > 0) - { + } + + auto z = GetZoneVersionWithFallback(ZoneID(short_name), instanceversion); + if (z) { + long_name = strcpy(new char[strlen(z->long_name.c_str()) + 1], z->long_name.c_str()); + + m_safe_points.x = z->safe_x; + m_safe_points.y = z->safe_y; + m_safe_points.z = z->safe_z; + m_safe_points.w = z->safe_heading; + m_graveyard_id = z->graveyard_id; + m_max_clients = z->maxclients; + + if (z->file_name.empty()) { + strcpy(file_name, short_name); + } + else { + strcpy(file_name, z->file_name.c_str()); + } + } + + if (graveyard_id() > 0) { LogDebug("Graveyard ID is [{}]", graveyard_id()); - bool GraveYardLoaded = content_db.GetZoneGraveyard(graveyard_id(), &pgraveyard_zoneid, &m_Graveyard.x, &m_Graveyard.y, &m_Graveyard.z, &m_Graveyard.w); + bool GraveYardLoaded = content_db.GetZoneGraveyard(graveyard_id(), &pgraveyard_zoneid, &m_graveyard.x, &m_graveyard.y, &m_graveyard.z, &m_graveyard.w); if (GraveYardLoaded) { - LogDebug("Loaded a graveyard for zone [{}]: graveyard zoneid is [{}] at [{}]", short_name, graveyard_zoneid(), to_string(m_Graveyard).c_str()); + LogDebug("Loaded a graveyard for zone [{}]: graveyard zoneid is [{}] at [{}]", short_name, graveyard_zoneid(), to_string(m_graveyard).c_str()); } else { LogError("Unable to load the graveyard id [{}] for zone [{}]", graveyard_id(), short_name); @@ -1280,52 +1300,125 @@ void Zone::ReloadStaticData() { bool Zone::LoadZoneCFG(const char* filename, uint16 instance_version) { + auto z = zone_store.GetZoneWithFallback(ZoneID(filename), instance_version); + + if (!z) { + LogError("[LoadZoneCFG] Failed to load zone data for [{}] instance_version [{}]", filename, instance_version); + return false; + } memset(&newzone_data, 0, sizeof(NewZone_Struct)); map_name = nullptr; + map_name = new char[100]; + newzone_data.zone_id = zoneid; - if (!content_db.GetZoneCFG( - ZoneID(filename), - instance_version, - &newzone_data, - can_bind, - can_combat, - can_levitate, - can_castoutdoor, - is_city, - is_hotzone, - allow_mercs, - max_movement_update_range, - zone_type, - default_ruleset, - &map_name - )) { - // If loading a non-zero instance failed, try loading the default - if (instance_version != 0) { - safe_delete_array(map_name); - if (!content_db.GetZoneCFG( - ZoneID(filename), - 0, - &newzone_data, - can_bind, - can_combat, - can_levitate, - can_castoutdoor, - is_city, - is_hotzone, - allow_mercs, - max_movement_update_range, - zone_type, - default_ruleset, - &map_name - )) { - LogError("Error loading the Zone Config"); - return false; - } - } + strcpy(map_name, "default"); + + newzone_data.ztype = z->ztype; + zone_type = newzone_data.ztype; + + // fog:red + newzone_data.fog_red[0] = z->fog_red; + newzone_data.fog_red[1] = z->fog_red2; + newzone_data.fog_red[2] = z->fog_red3; + newzone_data.fog_red[3] = z->fog_red4; + + // fog:blue + newzone_data.fog_blue[0] = z->fog_blue; + newzone_data.fog_blue[1] = z->fog_blue2; + newzone_data.fog_blue[2] = z->fog_blue3; + newzone_data.fog_blue[3] = z->fog_blue4; + + // fog:green + newzone_data.fog_green[0] = z->fog_green; + newzone_data.fog_green[1] = z->fog_green2; + newzone_data.fog_green[2] = z->fog_green3; + newzone_data.fog_green[3] = z->fog_green4; + + // fog:minclip + newzone_data.fog_minclip[0] = z->fog_minclip; + newzone_data.fog_minclip[1] = z->fog_minclip2; + newzone_data.fog_minclip[2] = z->fog_minclip3; + newzone_data.fog_minclip[3] = z->fog_minclip4; + + // fog:maxclip + newzone_data.fog_maxclip[0] = z->fog_maxclip; + newzone_data.fog_maxclip[1] = z->fog_maxclip2; + newzone_data.fog_maxclip[2] = z->fog_maxclip3; + newzone_data.fog_maxclip[3] = z->fog_maxclip4; + + // rain_chance + newzone_data.rain_chance[0] = z->rain_chance1; + newzone_data.rain_chance[1] = z->rain_chance2; + newzone_data.rain_chance[2] = z->rain_chance3; + newzone_data.rain_chance[3] = z->rain_chance4; + + // rain_duration + newzone_data.rain_duration[0] = z->rain_duration1; + newzone_data.rain_duration[1] = z->rain_duration2; + newzone_data.rain_duration[2] = z->rain_duration3; + newzone_data.rain_duration[3] = z->rain_duration4; + + // snow_chance + newzone_data.snow_chance[0] = z->snow_chance1; + newzone_data.snow_chance[1] = z->snow_chance2; + newzone_data.snow_chance[2] = z->snow_chance3; + newzone_data.snow_chance[3] = z->snow_chance4; + + // snow_duration + newzone_data.snow_duration[0] = z->snow_duration1; + newzone_data.snow_duration[1] = z->snow_duration2; + newzone_data.snow_duration[2] = z->snow_duration3; + newzone_data.snow_duration[3] = z->snow_duration4; + + // misc + newzone_data.fog_density = z->fog_density; + newzone_data.sky = z->sky; + newzone_data.zone_exp_multiplier = z->zone_exp_multiplier; + newzone_data.safe_x = z->safe_x; + newzone_data.safe_y = z->safe_y; + newzone_data.safe_z = z->safe_z; + newzone_data.underworld = z->underworld; + newzone_data.minclip = z->minclip; + newzone_data.maxclip = z->maxclip; + newzone_data.time_type = z->time_type; + newzone_data.gravity = z->gravity; + newzone_data.fast_regen_hp = z->fast_regen_hp; + newzone_data.fast_regen_mana = z->fast_regen_mana; + newzone_data.fast_regen_endurance = z->fast_regen_endurance; + newzone_data.npc_aggro_max_dist = z->npc_max_aggro_dist; + newzone_data.underworld_teleport_index = z->underworld_teleport_index; + newzone_data.lava_damage = z->lava_damage; + newzone_data.min_lava_damage = z->min_lava_damage; + newzone_data.suspend_buffs = z->suspendbuffs; + + // local attributes + can_bind = z->canbind != 0; + is_city = z->canbind == 2; + can_combat = z->cancombat != 0; + can_levitate = z->canlevitate != 0; + can_castoutdoor = z->castoutdoor != 0; + is_hotzone = z->hotzone != 0; + max_movement_update_range = z->max_movement_update_range; + default_ruleset = z->ruleset; + allow_mercs = true; + m_graveyard_id = z->graveyard_id; + m_max_clients = z->maxclients; + + // safe coordinates + m_safe_points.x = z->safe_x; + m_safe_points.y = z->safe_y; + m_safe_points.z = z->safe_z; + m_safe_points.w = z->safe_heading; + + if (!z->map_file_name.empty()) { + strcpy(map_name, z->map_file_name.c_str()); + } + else { + strcpy(map_name, z->short_name.c_str()); } - //overwrite with our internal variables + // overwrite with our internal variables strcpy(newzone_data.zone_short_name, GetShortName()); strcpy(newzone_data.zone_long_name, GetLongName()); strcpy(newzone_data.zone_short_name2, GetShortName()); @@ -2137,7 +2230,7 @@ bool Zone::HasGraveyard() { void Zone::SetGraveyard(uint32 zoneid, const glm::vec4& graveyardPosition) { pgraveyard_zoneid = zoneid; - m_Graveyard = graveyardPosition; + m_graveyard = graveyardPosition; } void Zone::LoadZoneBlockedSpells() diff --git a/zone/zone.h b/zone/zone.h index 28bd76141..ddb0fe294 100755 --- a/zone/zone.h +++ b/zone/zone.h @@ -25,7 +25,7 @@ #include "../common/random.h" #include "../common/strings.h" #include "zonedb.h" -#include "zone_store.h" +#include "../common/zone_store.h" #include "../common/repositories/grid_repository.h" #include "../common/repositories/grid_entries_repository.h" #include "../common/repositories/zone_points_repository.h" @@ -155,7 +155,7 @@ public: ZonePoint * GetClosestZonePoint(const glm::vec3 &location, const char *to_name, Client *client, float max_distance = 40000.0f); - inline bool BuffTimersSuspended() const { return newzone_data.SuspendBuffs != 0; }; + inline bool BuffTimersSuspended() const { return newzone_data.suspend_buffs != 0; }; inline bool HasMap() { return zonemap != nullptr; } inline bool HasWaterMap() { return watermap != nullptr; } inline bool InstantGrids() { return (!initgrids_timer.Enabled()); } @@ -166,13 +166,13 @@ public: inline const char *GetShortName() { return short_name; } inline const uint8 GetZoneType() const { return zone_type; } inline const uint16 GetInstanceVersion() const { return instanceversion; } - inline const uint32 &GetMaxClients() { return pMaxClients; } - inline const uint32 &graveyard_id() { return pgraveyard_id; } + inline const uint32 &GetMaxClients() { return m_max_clients; } + inline const uint32 &graveyard_id() { return m_graveyard_id; } inline const uint32 &graveyard_zoneid() { return pgraveyard_zoneid; } inline const uint32 GetInstanceID() const { return instanceid; } inline const uint32 GetZoneID() const { return zoneid; } - inline glm::vec4 GetSafePoint() { return m_SafePoint; } - inline glm::vec4 GetGraveyardPoint() { return m_Graveyard; } + inline glm::vec4 GetSafePoint() { return m_safe_points; } + inline glm::vec4 GetGraveyardPoint() { return m_graveyard; } inline std::vector GetGlobalLootTables(NPC *mob) const { return m_global_loot.GetGlobalLootTables(mob); } inline Timer *GetInstanceTimer() { return Instance_Timer; } inline void AddGlobalLootEntry(GlobalLootEntry &in) { return m_global_loot.AddEntry(in); } @@ -409,8 +409,8 @@ private: char *map_name; char *short_name; char file_name[16]; - glm::vec4 m_SafePoint; - glm::vec4 m_Graveyard; + glm::vec4 m_safe_points; + glm::vec4 m_graveyard; int default_ruleset; int zone_total_blocked_spells; int npc_position_update_distance; @@ -419,8 +419,8 @@ private: uint16 instanceversion; uint32 instanceid; uint32 instance_time_remaining; - uint32 pgraveyard_id, pgraveyard_zoneid; - uint32 pMaxClients; + uint32 m_graveyard_id, pgraveyard_zoneid; + uint32 m_max_clients; uint32 zoneid; uint32 m_last_ucss_update; diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 305b6b7d4..ef4d4598d 100755 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -11,7 +11,6 @@ #include "merc.h" #include "zone.h" #include "zonedb.h" -#include "zone_store.h" #include "aura.h" #include "../common/repositories/criteria/content_filter_criteria.h" #include "../common/repositories/npc_types_repository.h" @@ -95,182 +94,6 @@ bool ZoneDatabase::SaveZoneCFG(uint32 zoneid, uint16 instance_version, NewZone_S return true; } -bool ZoneDatabase::GetZoneCFG( - uint32 zoneid, - uint16 instance_version, - NewZone_Struct *zone_data, - bool &can_bind, - bool &can_combat, - bool &can_levitate, - bool &can_castoutdoor, - bool &is_city, - bool &is_hotzone, - bool &allow_mercs, - double &max_movement_update_range, - uint8 &zone_type, - int &ruleset, - char **map_filename) { - - *map_filename = new char[100]; - zone_data->zone_id = zoneid; - - std::string query = fmt::format( - "SELECT " - "ztype, " // 0 - "fog_red, " // 1 - "fog_green, " // 2 - "fog_blue, " // 3 - "fog_minclip, " // 4 - "fog_maxclip, " // 5 - "fog_red2, " // 6 - "fog_green2, " // 7 - "fog_blue2, " // 8 - "fog_minclip2, " // 9 - "fog_maxclip2, " // 10 - "fog_red3, " // 11 - "fog_green3, " // 12 - "fog_blue3, " // 13 - "fog_minclip3, " // 14 - "fog_maxclip3, " // 15 - "fog_red4, " // 16 - "fog_green4, " // 17 - "fog_blue4, " // 18 - "fog_minclip4, " // 19 - "fog_maxclip4, " // 20 - "fog_density, " // 21 - "sky, " // 22 - "zone_exp_multiplier, " // 23 - "safe_x, " // 24 - "safe_y, " // 25 - "safe_z, " // 26 - "underworld, " // 27 - "minclip, " // 28 - "maxclip, " // 29 - "time_type, " // 30 - "canbind, " // 31 - "cancombat, " // 32 - "canlevitate, " // 33 - "castoutdoor, " // 34 - "hotzone, " // 35 - "ruleset, " // 36 - "suspendbuffs, " // 37 - "map_file_name, " // 38 - "short_name, " // 39 - "rain_chance1, " // 40 - "rain_chance2, " // 41 - "rain_chance3, " // 42 - "rain_chance4, " // 43 - "rain_duration1, " // 44 - "rain_duration2, " // 45 - "rain_duration3, " // 46 - "rain_duration4, " // 47 - "snow_chance1, " // 48 - "snow_chance2, " // 49 - "snow_chance3, " // 50 - "snow_chance4, " // 51 - "snow_duration1, " // 52 - "snow_duration2, " // 53 - "snow_duration3, " // 54 - "snow_duration4, " // 55 - "gravity, " // 56 - "fast_regen_hp, " // 57 - "fast_regen_mana, " // 58 - "fast_regen_endurance, " // 59 - "npc_max_aggro_dist, " // 60 - "max_movement_update_range, " // 61 - "underworld_teleport_index, " // 62 - "lava_damage, " // 63 - "min_lava_damage " // 64 - "FROM zone WHERE zoneidnumber = {} AND version = {} {}", - zoneid, - instance_version, - ContentFilterCriteria::apply() - ); - auto results = QueryDatabase(query); - if (!results.Success()) { - strcpy(*map_filename, "default"); - return false; - } - - if (results.RowCount() == 0) { - strcpy(*map_filename, "default"); - return false; - } - - auto& row = results.begin(); - - memset(zone_data, 0, sizeof(NewZone_Struct)); - zone_data->ztype = atoi(row[0]); - zone_type = zone_data->ztype; - - int index; - for (index = 0; index < 4; index++) { - zone_data->fog_red[index] = atoi(row[1 + index * 5]); - zone_data->fog_green[index] = atoi(row[2 + index * 5]); - zone_data->fog_blue[index] = atoi(row[3 + index * 5]); - zone_data->fog_minclip[index] = atof(row[4 + index * 5]); - zone_data->fog_maxclip[index] = atof(row[5 + index * 5]); - } - - zone_data->fog_density = atof(row[21]); - zone_data->sky = atoi(row[22]); - zone_data->zone_exp_multiplier = atof(row[23]); - zone_data->safe_x = atof(row[24]); - zone_data->safe_y = atof(row[25]); - zone_data->safe_z = atof(row[26]); - zone_data->underworld = atof(row[27]); - zone_data->minclip = atof(row[28]); - zone_data->maxclip = atof(row[29]); - zone_data->time_type = atoi(row[30]); - - //not in the DB yet: - zone_data->gravity = atof(row[56]); - LogDebug("Zone Gravity is [{}]", zone_data->gravity); - allow_mercs = true; - - zone_data->FastRegenHP = atoi(row[57]); - zone_data->FastRegenMana = atoi(row[58]); - zone_data->FastRegenEndurance = atoi(row[59]); - zone_data->NPCAggroMaxDist = atoi(row[60]); - zone_data->underworld_teleport_index = atoi(row[62]); - zone_data->LavaDamage = atoi(row[63]); - zone_data->MinLavaDamage = atoi(row[64]); - - int bindable = 0; - bindable = atoi(row[31]); - - can_bind = bindable == 0 ? false : true; - is_city = bindable == 2 ? true : false; - can_combat = atoi(row[32]) == 0 ? false : true; - can_levitate = atoi(row[33]) == 0 ? false : true; - can_castoutdoor = atoi(row[34]) == 0 ? false : true; - is_hotzone = atoi(row[35]) == 0 ? false : true; - max_movement_update_range = atof(row[61]); - - ruleset = atoi(row[36]); - zone_data->SuspendBuffs = atoi(row[37]); - - char *file = row[38]; - if (file) - strcpy(*map_filename, file); - else - strcpy(*map_filename, row[39]); - - for (index = 0; index < 4; index++) - zone_data->rain_chance[index] = atoi(row[40 + index]); - - for (index = 0; index < 4; index++) - zone_data->rain_duration[index] = atoi(row[44 + index]); - - for (index = 0; index < 4; index++) - zone_data->snow_chance[index] = atoi(row[48 + index]); - - for (index = 0; index < 4; index++) - zone_data->snow_duration[index] = atof(row[52 + index]); - - return true; -} - void ZoneDatabase::UpdateRespawnTime(uint32 spawn2_id, uint16 instance_id, uint32 time_left) { @@ -3321,22 +3144,9 @@ bool ZoneDatabase::LoadBlockedSpells(int32 blockedSpellsCount, ZoneSpellsBlocked int ZoneDatabase::getZoneShutDownDelay(uint32 zoneID, uint32 version) { - std::string query = StringFormat("SELECT shutdowndelay FROM zone " - "WHERE zoneidnumber = %i AND (version=%i OR version=0) " - "ORDER BY version DESC", zoneID, version); - auto results = QueryDatabase(query); - if (!results.Success()) { - return (RuleI(Zone, AutoShutdownDelay)); - } + auto z = GetZoneVersionWithFallback(zoneID, version); - if (results.RowCount() == 0) { - std::cerr << "Error in getZoneShutDownDelay no result '" << query << "' " << std::endl; - return (RuleI(Zone, AutoShutdownDelay)); - } - - auto& row = results.begin(); - - return atoi(row[0]); + return z ? z->shutdowndelay : RuleI(Zone, AutoShutdownDelay); } uint32 ZoneDatabase::GetKarma(uint32 acct_id) diff --git a/zone/zonedb.h b/zone/zonedb.h index 03675d049..b181da243 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -246,7 +246,7 @@ struct ClientMercEntry { uint32 npcid; }; -namespace BeastlordPetData { +namespace BeastlordPetData { struct PetStruct { uint16 race_id = WOLF; uint8 texture = 0; @@ -369,7 +369,7 @@ public: bool SaveCharacterSkill(uint32 character_id, uint32 skill_id, uint32 value); bool SaveCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id); bool SaveCharacterTribute(uint32 character_id, PlayerProfile_Struct* pp); - + double GetAAEXPModifier(uint32 character_id, uint32 zone_id, int16 instance_version = -1) const; double GetEXPModifier(uint32 character_id, uint32 zone_id, int16 instance_version = -1) const; void SetAAEXPModifier(uint32 character_id, uint32 zone_id, double aa_modifier, int16 instance_version = -1); @@ -386,7 +386,7 @@ public: void DivergeCharacterInvSnapshotFromInventory(uint32 character_id, uint32 timestamp, std::list> &compare_list); void DivergeCharacterInventoryFromInvSnapshot(uint32 character_id, uint32 timestamp, std::list> &compare_list); bool RestoreCharacterInvSnapshot(uint32 character_id, uint32 timestamp); - + /* Corpses */ bool DeleteItemOffCharacterCorpse(uint32 db_id, uint32 equip_slot, uint32 item_id); uint32 GetCharacterCorpseItemCount(uint32 corpse_id); @@ -432,21 +432,6 @@ public: bool LoadAlternateAdvancement(Client *c); /* Zone related */ - bool GetZoneCFG( - uint32 zoneid, - uint16 instance_version, - NewZone_Struct *data, - bool &can_bind, - bool &can_combat, - bool &can_levitate, - bool &can_castoutdoor, - bool &is_city, - bool &is_hotzone, - bool &allow_mercs, - double &max_movement_update_range, - uint8 &zone_type, - int &ruleset, - char **map_filename); bool SaveZoneCFG(uint32 zoneid, uint16 instance_version, NewZone_Struct* zd); bool LoadStaticZonePoints(LinkedList* zone_point_list,const char* zonename, uint32 version); int getZoneShutDownDelay(uint32 zoneID, uint32 version); diff --git a/zone/zoning.cpp b/zone/zoning.cpp index aaca8f132..ef5517bd8 100644 --- a/zone/zoning.cpp +++ b/zone/zoning.cpp @@ -179,29 +179,32 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { return; } - /* Load up the Safe Coordinates, restrictions and verify the zone name*/ - float safe_x, safe_y, safe_z, safe_heading; - int16 min_status = AccountStatus::Player; - uint8 min_level = 0; - char flag_needed[128]; - if(!content_db.GetSafePoints( - target_zone_name, - database.GetInstanceVersion(target_instance_id), - &safe_x, - &safe_y, - &safe_z, - &safe_heading, - &min_status, - &min_level, - flag_needed - )) { - //invalid zone... + auto zone_data = GetZoneVersionWithFallback( + ZoneID(target_zone_name), + database.GetInstanceVersion(target_instance_id) + ); + if (!zone_data) { Message(Chat::Red, "Invalid target zone while getting safe points."); LogError("Zoning [{}]: Unable to get safe coordinates for zone [{}]", GetName(), target_zone_name); SendZoneCancel(zc); return; } + float safe_x, safe_y, safe_z, safe_heading; + int16 min_status = AccountStatus::Player; + uint8 min_level = 0; + char flag_needed[128]; + + if (!zone_data->flag_needed.empty()) { + strcpy(flag_needed, zone_data->flag_needed.c_str()); + } + + safe_x = zone_data->safe_x; + safe_y = zone_data->safe_y; + safe_z = zone_data->safe_z; + min_status = zone_data->min_status; + min_level = zone_data->min_level; + std::string export_string = fmt::format( "{} {}", zone->GetZoneID(), @@ -318,7 +321,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { //not sure when we would use ZONE_ERROR_NOTREADY //enforce min status and level - if (!ignore_restrictions && (Admin() < min_status || GetLevel() < min_level)) + if (!ignore_restrictions && (Admin() < min_status || GetLevel() < zone_data->min_level)) { myerror = ZONE_ERROR_NOEXPERIENCE; } @@ -344,7 +347,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { */ bool meets_zone_expansion_check = false; bool found_zone = false; - for (auto &z: zone_store.zones) { + for (auto &z: zone_store.GetZones()) { if (z.short_name == target_zone_name && z.version == 0) { found_zone = true; if (z.expansion <= content_service.GetCurrentExpansion() || z.bypass_expansion_check) { @@ -664,7 +667,11 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z char* pZoneName = nullptr; pShortZoneName = ZoneName(zoneID); - content_db.GetZoneLongName(pShortZoneName, &pZoneName); + + auto zd = GetZoneVersionWithFallback(zoneID, zone->GetInstanceVersion()); + if (zd) { + pZoneName = strcpy(new char[strlen(zd->long_name.c_str()) + 1], zd->long_name.c_str()); + } cheat_manager.SetExemptStatus(Port, true); @@ -1047,21 +1054,10 @@ void Client::SendZoneFlagInfo(Client *to) const { const char* zone_short_name = ZoneName(zone_id, true); if (strncmp(zone_short_name, "UNKNOWN", strlen(zone_short_name)) != 0) { std::string zone_long_name = ZoneLongName(zone_id); - float safe_x, safe_y, safe_z, safe_heading; - int16 min_status = AccountStatus::Player; - uint8 min_level = 0; char flag_name[128]; - if (!content_db.GetSafePoints( - zone_short_name, - 0, - &safe_x, - &safe_y, - &safe_z, - &safe_heading, - &min_status, - &min_level, - flag_name - )) { + + auto z = GetZone(zone_id); + if (!z) { strcpy(flag_name, "ERROR"); } @@ -1236,43 +1232,50 @@ bool Client::CanBeInZone() { //only enforce rules here which are serious enough to warrant being kicked from //the zone - if(Admin() >= RuleI(GM, MinStatusToZoneAnywhere)) - return(true); + if (Admin() >= RuleI(GM, MinStatusToZoneAnywhere)) { + return (true); + } float safe_x, safe_y, safe_z, safe_heading; int16 min_status = AccountStatus::Player; uint8 min_level = 0; char flag_needed[128]; - if(!content_db.GetSafePoints( - zone->GetShortName(), - zone->GetInstanceVersion(), - &safe_x, - &safe_y, - &safe_z, - &safe_heading, - &min_status, - &min_level, - flag_needed - )) { + + auto z = GetZoneVersionWithFallback( + ZoneID(zone->GetShortName()), + zone->GetInstanceVersion() + ); + if (!z) { //this should not happen... LogDebug("[CLIENT] Unable to query zone info for ourself [{}]", zone->GetShortName()); - return(false); + return false; } - if(GetLevel() < min_level) { + safe_x = z->safe_x; + safe_y = z->safe_y; + safe_z = z->safe_z; + safe_heading = z->safe_heading; + min_status = z->min_status; + min_level = z->min_level; + + if (!z->flag_needed.empty()) { + strcpy(flag_needed, z->flag_needed.c_str()); + } + + if (GetLevel() < min_level) { LogDebug("[CLIENT] Character does not meet min level requirement ([{}] < [{}])!", GetLevel(), min_level); - return(false); + return (false); } - if(Admin() < min_status) { + if (Admin() < min_status) { LogDebug("[CLIENT] Character does not meet min status requirement ([{}] < [{}])!", Admin(), min_status); - return(false); + return (false); } - if(flag_needed[0] != '\0') { + if (flag_needed[0] != '\0') { //the flag needed string is not empty, meaning a flag is required. - if(Admin() < minStatusToIgnoreZoneFlags && !HasZoneFlag(zone->GetZoneID())) { + if (Admin() < minStatusToIgnoreZoneFlags && !HasZoneFlag(zone->GetZoneID())) { LogDebug("[CLIENT] Character does not have the flag to be in this zone ([{}])!", flag_needed); - return(false); + return (false); } }