diff --git a/common/repositories/base/base_npc_scale_global_base_repository.h b/common/repositories/base/base_npc_scale_global_base_repository.h index c8f6642c8..d09165c5c 100644 --- a/common/repositories/base/base_npc_scale_global_base_repository.h +++ b/common/repositories/base/base_npc_scale_global_base_repository.h @@ -16,11 +16,14 @@ #include "../../strings.h" #include + class BaseNpcScaleGlobalBaseRepository { public: struct NpcScaleGlobalBase { int32_t type; int32_t level; + uint32_t zone_id; + int32_t instance_version; int32_t ac; int32_t hp; int32_t accuracy; @@ -59,6 +62,8 @@ public: return { "type", "level", + "zone_id", + "instance_version", "ac", "hp", "accuracy", @@ -93,6 +98,8 @@ public: return { "type", "level", + "zone_id", + "instance_version", "ac", "hp", "accuracy", @@ -161,6 +168,8 @@ public: e.type = 0; e.level = 0; + e.zone_id = 0; + e.instance_version = -1; e.ac = 0; e.hp = 0; e.accuracy = 0; @@ -212,8 +221,9 @@ public: { auto results = db.QueryDatabase( fmt::format( - "{} WHERE id = {} LIMIT 1", + "{} WHERE {} = {} LIMIT 1", BaseSelect(), + PrimaryKey(), npc_scale_global_base_id ) ); @@ -224,32 +234,34 @@ public: e.type = static_cast(atoi(row[0])); e.level = static_cast(atoi(row[1])); - e.ac = static_cast(atoi(row[2])); - e.hp = static_cast(atoi(row[3])); - e.accuracy = static_cast(atoi(row[4])); - e.slow_mitigation = static_cast(atoi(row[5])); - e.attack = static_cast(atoi(row[6])); - e.strength = static_cast(atoi(row[7])); - e.stamina = static_cast(atoi(row[8])); - e.dexterity = static_cast(atoi(row[9])); - e.agility = static_cast(atoi(row[10])); - e.intelligence = static_cast(atoi(row[11])); - e.wisdom = static_cast(atoi(row[12])); - e.charisma = static_cast(atoi(row[13])); - e.magic_resist = static_cast(atoi(row[14])); - e.cold_resist = static_cast(atoi(row[15])); - e.fire_resist = static_cast(atoi(row[16])); - e.poison_resist = static_cast(atoi(row[17])); - e.disease_resist = static_cast(atoi(row[18])); - e.corruption_resist = static_cast(atoi(row[19])); - e.physical_resist = static_cast(atoi(row[20])); - e.min_dmg = static_cast(atoi(row[21])); - e.max_dmg = static_cast(atoi(row[22])); - e.hp_regen_rate = static_cast(atoi(row[23])); - e.attack_delay = static_cast(atoi(row[24])); - e.spell_scale = static_cast(atoi(row[25])); - e.heal_scale = static_cast(atoi(row[26])); - e.special_abilities = row[27] ? row[27] : ""; + e.zone_id = static_cast(strtoul(row[2], nullptr, 10)); + e.instance_version = static_cast(atoi(row[3])); + e.ac = static_cast(atoi(row[4])); + e.hp = static_cast(atoi(row[5])); + e.accuracy = static_cast(atoi(row[6])); + e.slow_mitigation = static_cast(atoi(row[7])); + e.attack = static_cast(atoi(row[8])); + e.strength = static_cast(atoi(row[9])); + e.stamina = static_cast(atoi(row[10])); + e.dexterity = static_cast(atoi(row[11])); + e.agility = static_cast(atoi(row[12])); + e.intelligence = static_cast(atoi(row[13])); + e.wisdom = static_cast(atoi(row[14])); + e.charisma = static_cast(atoi(row[15])); + e.magic_resist = static_cast(atoi(row[16])); + e.cold_resist = static_cast(atoi(row[17])); + e.fire_resist = static_cast(atoi(row[18])); + e.poison_resist = static_cast(atoi(row[19])); + e.disease_resist = static_cast(atoi(row[20])); + e.corruption_resist = static_cast(atoi(row[21])); + e.physical_resist = static_cast(atoi(row[22])); + e.min_dmg = static_cast(atoi(row[23])); + e.max_dmg = static_cast(atoi(row[24])); + e.hp_regen_rate = static_cast(atoi(row[25])); + e.attack_delay = static_cast(atoi(row[26])); + e.spell_scale = static_cast(atoi(row[27])); + e.heal_scale = static_cast(atoi(row[28])); + e.special_abilities = row[29] ? row[29] : ""; return e; } @@ -285,32 +297,34 @@ public: v.push_back(columns[0] + " = " + std::to_string(e.type)); v.push_back(columns[1] + " = " + std::to_string(e.level)); - v.push_back(columns[2] + " = " + std::to_string(e.ac)); - v.push_back(columns[3] + " = " + std::to_string(e.hp)); - v.push_back(columns[4] + " = " + std::to_string(e.accuracy)); - v.push_back(columns[5] + " = " + std::to_string(e.slow_mitigation)); - v.push_back(columns[6] + " = " + std::to_string(e.attack)); - v.push_back(columns[7] + " = " + std::to_string(e.strength)); - v.push_back(columns[8] + " = " + std::to_string(e.stamina)); - v.push_back(columns[9] + " = " + std::to_string(e.dexterity)); - v.push_back(columns[10] + " = " + std::to_string(e.agility)); - v.push_back(columns[11] + " = " + std::to_string(e.intelligence)); - v.push_back(columns[12] + " = " + std::to_string(e.wisdom)); - v.push_back(columns[13] + " = " + std::to_string(e.charisma)); - v.push_back(columns[14] + " = " + std::to_string(e.magic_resist)); - v.push_back(columns[15] + " = " + std::to_string(e.cold_resist)); - v.push_back(columns[16] + " = " + std::to_string(e.fire_resist)); - v.push_back(columns[17] + " = " + std::to_string(e.poison_resist)); - v.push_back(columns[18] + " = " + std::to_string(e.disease_resist)); - v.push_back(columns[19] + " = " + std::to_string(e.corruption_resist)); - v.push_back(columns[20] + " = " + std::to_string(e.physical_resist)); - v.push_back(columns[21] + " = " + std::to_string(e.min_dmg)); - v.push_back(columns[22] + " = " + std::to_string(e.max_dmg)); - v.push_back(columns[23] + " = " + std::to_string(e.hp_regen_rate)); - v.push_back(columns[24] + " = " + std::to_string(e.attack_delay)); - v.push_back(columns[25] + " = " + std::to_string(e.spell_scale)); - v.push_back(columns[26] + " = " + std::to_string(e.heal_scale)); - v.push_back(columns[27] + " = '" + Strings::Escape(e.special_abilities) + "'"); + v.push_back(columns[2] + " = " + std::to_string(e.zone_id)); + v.push_back(columns[3] + " = " + std::to_string(e.instance_version)); + v.push_back(columns[4] + " = " + std::to_string(e.ac)); + v.push_back(columns[5] + " = " + std::to_string(e.hp)); + v.push_back(columns[6] + " = " + std::to_string(e.accuracy)); + v.push_back(columns[7] + " = " + std::to_string(e.slow_mitigation)); + v.push_back(columns[8] + " = " + std::to_string(e.attack)); + v.push_back(columns[9] + " = " + std::to_string(e.strength)); + v.push_back(columns[10] + " = " + std::to_string(e.stamina)); + v.push_back(columns[11] + " = " + std::to_string(e.dexterity)); + v.push_back(columns[12] + " = " + std::to_string(e.agility)); + v.push_back(columns[13] + " = " + std::to_string(e.intelligence)); + v.push_back(columns[14] + " = " + std::to_string(e.wisdom)); + v.push_back(columns[15] + " = " + std::to_string(e.charisma)); + v.push_back(columns[16] + " = " + std::to_string(e.magic_resist)); + v.push_back(columns[17] + " = " + std::to_string(e.cold_resist)); + v.push_back(columns[18] + " = " + std::to_string(e.fire_resist)); + v.push_back(columns[19] + " = " + std::to_string(e.poison_resist)); + v.push_back(columns[20] + " = " + std::to_string(e.disease_resist)); + v.push_back(columns[21] + " = " + std::to_string(e.corruption_resist)); + v.push_back(columns[22] + " = " + std::to_string(e.physical_resist)); + v.push_back(columns[23] + " = " + std::to_string(e.min_dmg)); + v.push_back(columns[24] + " = " + std::to_string(e.max_dmg)); + v.push_back(columns[25] + " = " + std::to_string(e.hp_regen_rate)); + v.push_back(columns[26] + " = " + std::to_string(e.attack_delay)); + v.push_back(columns[27] + " = " + std::to_string(e.spell_scale)); + v.push_back(columns[28] + " = " + std::to_string(e.heal_scale)); + v.push_back(columns[29] + " = '" + Strings::Escape(e.special_abilities) + "'"); auto results = db.QueryDatabase( fmt::format( @@ -334,6 +348,8 @@ public: v.push_back(std::to_string(e.type)); v.push_back(std::to_string(e.level)); + v.push_back(std::to_string(e.zone_id)); + v.push_back(std::to_string(e.instance_version)); v.push_back(std::to_string(e.ac)); v.push_back(std::to_string(e.hp)); v.push_back(std::to_string(e.accuracy)); @@ -391,6 +407,8 @@ public: v.push_back(std::to_string(e.type)); v.push_back(std::to_string(e.level)); + v.push_back(std::to_string(e.zone_id)); + v.push_back(std::to_string(e.instance_version)); v.push_back(std::to_string(e.ac)); v.push_back(std::to_string(e.hp)); v.push_back(std::to_string(e.accuracy)); @@ -452,32 +470,34 @@ public: e.type = static_cast(atoi(row[0])); e.level = static_cast(atoi(row[1])); - e.ac = static_cast(atoi(row[2])); - e.hp = static_cast(atoi(row[3])); - e.accuracy = static_cast(atoi(row[4])); - e.slow_mitigation = static_cast(atoi(row[5])); - e.attack = static_cast(atoi(row[6])); - e.strength = static_cast(atoi(row[7])); - e.stamina = static_cast(atoi(row[8])); - e.dexterity = static_cast(atoi(row[9])); - e.agility = static_cast(atoi(row[10])); - e.intelligence = static_cast(atoi(row[11])); - e.wisdom = static_cast(atoi(row[12])); - e.charisma = static_cast(atoi(row[13])); - e.magic_resist = static_cast(atoi(row[14])); - e.cold_resist = static_cast(atoi(row[15])); - e.fire_resist = static_cast(atoi(row[16])); - e.poison_resist = static_cast(atoi(row[17])); - e.disease_resist = static_cast(atoi(row[18])); - e.corruption_resist = static_cast(atoi(row[19])); - e.physical_resist = static_cast(atoi(row[20])); - e.min_dmg = static_cast(atoi(row[21])); - e.max_dmg = static_cast(atoi(row[22])); - e.hp_regen_rate = static_cast(atoi(row[23])); - e.attack_delay = static_cast(atoi(row[24])); - e.spell_scale = static_cast(atoi(row[25])); - e.heal_scale = static_cast(atoi(row[26])); - e.special_abilities = row[27] ? row[27] : ""; + e.zone_id = static_cast(strtoul(row[2], nullptr, 10)); + e.instance_version = static_cast(atoi(row[3])); + e.ac = static_cast(atoi(row[4])); + e.hp = static_cast(atoi(row[5])); + e.accuracy = static_cast(atoi(row[6])); + e.slow_mitigation = static_cast(atoi(row[7])); + e.attack = static_cast(atoi(row[8])); + e.strength = static_cast(atoi(row[9])); + e.stamina = static_cast(atoi(row[10])); + e.dexterity = static_cast(atoi(row[11])); + e.agility = static_cast(atoi(row[12])); + e.intelligence = static_cast(atoi(row[13])); + e.wisdom = static_cast(atoi(row[14])); + e.charisma = static_cast(atoi(row[15])); + e.magic_resist = static_cast(atoi(row[16])); + e.cold_resist = static_cast(atoi(row[17])); + e.fire_resist = static_cast(atoi(row[18])); + e.poison_resist = static_cast(atoi(row[19])); + e.disease_resist = static_cast(atoi(row[20])); + e.corruption_resist = static_cast(atoi(row[21])); + e.physical_resist = static_cast(atoi(row[22])); + e.min_dmg = static_cast(atoi(row[23])); + e.max_dmg = static_cast(atoi(row[24])); + e.hp_regen_rate = static_cast(atoi(row[25])); + e.attack_delay = static_cast(atoi(row[26])); + e.spell_scale = static_cast(atoi(row[27])); + e.heal_scale = static_cast(atoi(row[28])); + e.special_abilities = row[29] ? row[29] : ""; all_entries.push_back(e); } @@ -504,32 +524,34 @@ public: e.type = static_cast(atoi(row[0])); e.level = static_cast(atoi(row[1])); - e.ac = static_cast(atoi(row[2])); - e.hp = static_cast(atoi(row[3])); - e.accuracy = static_cast(atoi(row[4])); - e.slow_mitigation = static_cast(atoi(row[5])); - e.attack = static_cast(atoi(row[6])); - e.strength = static_cast(atoi(row[7])); - e.stamina = static_cast(atoi(row[8])); - e.dexterity = static_cast(atoi(row[9])); - e.agility = static_cast(atoi(row[10])); - e.intelligence = static_cast(atoi(row[11])); - e.wisdom = static_cast(atoi(row[12])); - e.charisma = static_cast(atoi(row[13])); - e.magic_resist = static_cast(atoi(row[14])); - e.cold_resist = static_cast(atoi(row[15])); - e.fire_resist = static_cast(atoi(row[16])); - e.poison_resist = static_cast(atoi(row[17])); - e.disease_resist = static_cast(atoi(row[18])); - e.corruption_resist = static_cast(atoi(row[19])); - e.physical_resist = static_cast(atoi(row[20])); - e.min_dmg = static_cast(atoi(row[21])); - e.max_dmg = static_cast(atoi(row[22])); - e.hp_regen_rate = static_cast(atoi(row[23])); - e.attack_delay = static_cast(atoi(row[24])); - e.spell_scale = static_cast(atoi(row[25])); - e.heal_scale = static_cast(atoi(row[26])); - e.special_abilities = row[27] ? row[27] : ""; + e.zone_id = static_cast(strtoul(row[2], nullptr, 10)); + e.instance_version = static_cast(atoi(row[3])); + e.ac = static_cast(atoi(row[4])); + e.hp = static_cast(atoi(row[5])); + e.accuracy = static_cast(atoi(row[6])); + e.slow_mitigation = static_cast(atoi(row[7])); + e.attack = static_cast(atoi(row[8])); + e.strength = static_cast(atoi(row[9])); + e.stamina = static_cast(atoi(row[10])); + e.dexterity = static_cast(atoi(row[11])); + e.agility = static_cast(atoi(row[12])); + e.intelligence = static_cast(atoi(row[13])); + e.wisdom = static_cast(atoi(row[14])); + e.charisma = static_cast(atoi(row[15])); + e.magic_resist = static_cast(atoi(row[16])); + e.cold_resist = static_cast(atoi(row[17])); + e.fire_resist = static_cast(atoi(row[18])); + e.poison_resist = static_cast(atoi(row[19])); + e.disease_resist = static_cast(atoi(row[20])); + e.corruption_resist = static_cast(atoi(row[21])); + e.physical_resist = static_cast(atoi(row[22])); + e.min_dmg = static_cast(atoi(row[23])); + e.max_dmg = static_cast(atoi(row[24])); + e.hp_regen_rate = static_cast(atoi(row[25])); + e.attack_delay = static_cast(atoi(row[26])); + e.spell_scale = static_cast(atoi(row[27])); + e.heal_scale = static_cast(atoi(row[28])); + e.special_abilities = row[29] ? row[29] : ""; all_entries.push_back(e); } diff --git a/common/version.h b/common/version.h index 795931a1c..3cd72fec1 100644 --- a/common/version.h +++ b/common/version.h @@ -42,7 +42,7 @@ * Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt */ -#define CURRENT_BINARY_DATABASE_VERSION 9220 +#define CURRENT_BINARY_DATABASE_VERSION 9221 #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9038 #endif diff --git a/utils/sql/db_update_manifest.txt b/utils/sql/db_update_manifest.txt index 9e2532432..f328dda36 100644 --- a/utils/sql/db_update_manifest.txt +++ b/utils/sql/db_update_manifest.txt @@ -474,6 +474,7 @@ 9218|2023_01_24_item_recast.sql|show columns from character_item_recast like '%recast_type%'|contains|smallint 9219|2023_01_29_merchant_status_requirements.sql|SHOW COLUMNS FROM merchantlist LIKE 'min_status'|empty| 9220|2022_12_19_player_events_tables.sql|SHOW TABLES LIKE 'player_event_logs'|empty| +9221|2023_02_24_npc_scaling_zone_id_instance_version|SHOW COLUMNS FROM `npc_scale_global_base` LIKE 'zone_id'|empty| # Upgrade conditions: # This won't be needed after this system is implemented, but it is used database that are not diff --git a/utils/sql/git/required/2023_02_24_npc_scaling_zone_id_instance_version.sql b/utils/sql/git/required/2023_02_24_npc_scaling_zone_id_instance_version.sql new file mode 100644 index 000000000..560aa4961 --- /dev/null +++ b/utils/sql/git/required/2023_02_24_npc_scaling_zone_id_instance_version.sql @@ -0,0 +1,5 @@ +ALTER TABLE `npc_scale_global_base` +ADD COLUMN `zone_id` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `level`, +ADD COLUMN `instance_version` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `zone_id`, +DROP PRIMARY KEY, +ADD PRIMARY KEY (`type`, `level`, `zone_id`, `instance_version`) USING BTREE; diff --git a/zone/mob.cpp b/zone/mob.cpp index c6de6b009..6b5ade57b 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -4205,7 +4205,11 @@ void Mob::ExecWeaponProc(const EQ::ItemInstance *inst, uint16 spell_id, Mob *on, } uint32 Mob::GetZoneID() const { - return(zone->GetZoneID()); + return zone->GetZoneID(); +} + +uint16 Mob::GetInstanceVersion() const { + return zone->GetInstanceVersion(); } int Mob::GetHaste() diff --git a/zone/mob.h b/zone/mob.h index 797dc445d..1a59576da 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -1239,6 +1239,7 @@ public: bool Charmed() const { return typeofpet == petCharmed; } static uint32 GetLevelHP(uint8 tlevel); uint32 GetZoneID() const; //for perl + uint16 GetInstanceVersion() const; //for perl virtual int32 CheckAggroAmount(uint16 spell_id, Mob *target, bool isproc = false); virtual int32 CheckHealAggroAmount(uint16 spell_id, Mob *target, uint32 heal_possible = 0); diff --git a/zone/mob_info.cpp b/zone/mob_info.cpp index ef5f58063..1a2c7e421 100644 --- a/zone/mob_info.cpp +++ b/zone/mob_info.cpp @@ -795,21 +795,19 @@ void Mob::DisplayInfo(Mob *mob) window_text += WriteDisplayInfoSection(mob, "Proximity", npc_proximity, 1, true); } - int8 npc_type = npc_scale_manager->GetNPCScalingType(npc); - std::string npc_type_string = npc_scale_manager->GetNPCScalingTypeName(npc); - client->Message( - 0, - "| # Target: %s Type: %i (%s)", - npc->GetCleanName(), - npc_type, - npc_type_string.c_str()); + Chat::White, + fmt::format( + "| # Target: {} Type: {} ({})", + npc->GetCleanName(), + npc_scale_manager->GetNPCScalingType(npc), + npc_scale_manager->GetNPCScalingTypeName(npc) + ).c_str() + ); NPCCommandsMenu(client, npc); } - // std::cout << "Window Length: " << window_text.length() << std::endl; - if (client->GetDisplayMobInfoWindow()) { client->SendFullPopup( "GM: Entity Info", diff --git a/zone/npc_scale_manager.cpp b/zone/npc_scale_manager.cpp index f19b8fe08..512876f8c 100644 --- a/zone/npc_scale_manager.cpp +++ b/zone/npc_scale_manager.cpp @@ -30,21 +30,27 @@ void NpcScaleManager::ScaleNPC( NPC *npc, bool always_scale, bool override_special_abilities -) -{ +) { if (npc->IsSkipAutoScale() || npc->GetNPCTypeID() == 0) { return; } - int8 npc_type = GetNPCScalingType(npc); - int npc_level = npc->GetLevel(); - bool is_auto_scaled = IsAutoScaled(npc); + auto npc_type = GetNPCScalingType(npc); + auto npc_level = npc->GetLevel(); + auto is_auto_scaled = IsAutoScaled(npc); + auto zone_id = zone->GetZoneID(); + auto instance_version = zone->GetInstanceVersion(); - global_npc_scale scale_data = GetGlobalScaleDataForTypeLevel(npc_type, npc_level); + global_npc_scale scale_data = GetGlobalScaleDataForTypeLevel( + npc_type, + npc_level, + zone_id, + instance_version + ); if (!scale_data.level) { LogNPCScaling( - "NPC: [{}] - scaling data not found for type: [{}] level: [{}]", + "NPC: [{}] - scaling data not found for type [{}] level [{}]", npc->GetCleanName(), npc_type, npc_level @@ -209,11 +215,13 @@ void NpcScaleManager::ResetNPCScaling(NPC* npc) bool NpcScaleManager::LoadScaleData() { auto rows = NpcScaleGlobalBaseRepository::All(content_db); - for (auto &s: rows) { + for (const auto &s : rows) { global_npc_scale scale_data; scale_data.type = s.type; scale_data.level = s.level; + scale_data.zone_id = s.zone_id; + scale_data.instance_version = s.instance_version; scale_data.ac = s.ac; scale_data.hp = s.hp; scale_data.accuracy = s.accuracy; @@ -246,7 +254,12 @@ bool NpcScaleManager::LoadScaleData() npc_global_base_scaling_data.insert( std::make_pair( - std::make_pair(scale_data.type, scale_data.level), + std::make_tuple( + scale_data.type, + scale_data.level, + scale_data.zone_id, + scale_data.instance_version + ), scale_data ) ); @@ -262,9 +275,45 @@ bool NpcScaleManager::LoadScaleData() * @param npc_level * @return NpcScaleManager::global_npc_scale */ -NpcScaleManager::global_npc_scale NpcScaleManager::GetGlobalScaleDataForTypeLevel(int8 npc_type, int npc_level) -{ - auto iter = npc_global_base_scaling_data.find(std::make_pair(npc_type, npc_level)); +NpcScaleManager::global_npc_scale NpcScaleManager::GetGlobalScaleDataForTypeLevel( + int8 npc_type, + uint8 npc_level, + uint32 zone_id, + uint16 instance_version +) { + auto iter = npc_global_base_scaling_data.find( + std::make_tuple( + npc_type, + npc_level, + zone_id, + instance_version + ) + ); + + if (iter != npc_global_base_scaling_data.end()) { + return iter->second; + } + + iter = npc_global_base_scaling_data.find( + std::make_tuple( + npc_type, + npc_level, + zone_id, + 0 + ) + ); + if (iter != npc_global_base_scaling_data.end()) { + return iter->second; + } + + iter = npc_global_base_scaling_data.find( + std::make_tuple( + npc_type, + npc_level, + 0, + 0 + ) + ); if (iter != npc_global_base_scaling_data.end()) { return iter->second; } @@ -487,14 +536,21 @@ bool NpcScaleManager::IsAutoScaled(NPC* npc) */ bool NpcScaleManager::ApplyGlobalBaseScalingToNPCStatically(NPC *&npc) { - int8 npc_type = GetNPCScalingType(npc); - int npc_level = npc->GetLevel(); + auto npc_type = GetNPCScalingType(npc); + auto npc_level = npc->GetLevel(); + auto zone_id = zone->GetZoneID(); + auto instance_version = zone->GetInstanceVersion(); - global_npc_scale g = GetGlobalScaleDataForTypeLevel(npc_type, npc_level); + global_npc_scale g = GetGlobalScaleDataForTypeLevel( + npc_type, + npc_level, + zone_id, + instance_version + ); if (!g.level) { LogNPCScaling( - "NPC: [{}] - scaling data not found for type: [{}] level: [{}]", + "NPC: [{}] - scaling data not found for type [{}] level [{}]", npc->GetCleanName(), npc_type, npc_level @@ -503,7 +559,7 @@ bool NpcScaleManager::ApplyGlobalBaseScalingToNPCStatically(NPC *&npc) return false; } - auto n = NpcTypesRepository::FindOne(content_db, (int) npc->GetNPCTypeID()); + auto n = NpcTypesRepository::FindOne(content_db, static_cast(npc->GetNPCTypeID())); if (n.id > 0) { n.AC = g.ac; n.hp = g.hp; @@ -528,8 +584,8 @@ bool NpcScaleManager::ApplyGlobalBaseScalingToNPCStatically(NPC *&npc) n.maxdmg = g.max_dmg; n.hp_regen_rate = g.hp_regen_rate; n.attack_delay = g.attack_delay; - n.spellscale = (float) g.spell_scale; - n.healscale = (float) g.heal_scale; + n.spellscale = static_cast(g.spell_scale); + n.healscale = static_cast(g.heal_scale); n.special_abilities = g.special_abilities; return NpcTypesRepository::UpdateOne(content_db, n); @@ -545,14 +601,21 @@ bool NpcScaleManager::ApplyGlobalBaseScalingToNPCStatically(NPC *&npc) */ bool NpcScaleManager::ApplyGlobalBaseScalingToNPCDynamically(NPC *&npc) { - int8 npc_type = GetNPCScalingType(npc); - int npc_level = npc->GetLevel(); + auto npc_type = GetNPCScalingType(npc); + auto npc_level = npc->GetLevel(); + auto zone_id = zone->GetZoneID(); + auto instance_version = zone->GetInstanceVersion(); - global_npc_scale d = GetGlobalScaleDataForTypeLevel(npc_type, npc_level); + global_npc_scale d = GetGlobalScaleDataForTypeLevel( + npc_type, + npc_level, + zone_id, + instance_version + ); if (!d.level) { LogNPCScaling( - "NPC: [{}] - scaling data not found for type: [{}] level: [{}]", + "NPC: [{}] - scaling data not found for type [{}] level [{}]", npc->GetCleanName(), npc_type, npc_level @@ -561,7 +624,7 @@ bool NpcScaleManager::ApplyGlobalBaseScalingToNPCDynamically(NPC *&npc) return false; } - auto n = NpcTypesRepository::FindOne(content_db, (int) npc->GetNPCTypeID()); + auto n = NpcTypesRepository::FindOne(content_db, static_cast(npc->GetNPCTypeID())); if (n.id > 0) { n.AC = 0; n.hp = 0; diff --git a/zone/npc_scale_manager.h b/zone/npc_scale_manager.h index 0a185bdc2..46a0020b9 100644 --- a/zone/npc_scale_manager.h +++ b/zone/npc_scale_manager.h @@ -22,37 +22,41 @@ #define EQEMU_NPC_SCALE_MANAGER_H #include "npc.h" +#include "zone.h" +extern Zone* zone; class NpcScaleManager { public: struct global_npc_scale { - int type; - int level; - int ac; - int64 hp; - int accuracy; - int slow_mitigation; - int attack; - int strength; - int stamina; - int dexterity; - int agility; - int intelligence; - int wisdom; - int charisma; - int magic_resist; - int cold_resist; - int fire_resist; - int poison_resist; - int disease_resist; - int corruption_resist; - int physical_resist; - int min_dmg; - int max_dmg; - int64 hp_regen_rate; - int attack_delay; - int spell_scale; - int heal_scale; + int8 type; + uint8 level; + uint32 zone_id; + uint16 instance_version; + int ac; + int64 hp; + int accuracy; + int slow_mitigation; + int attack; + int strength; + int stamina; + int dexterity; + int agility; + int intelligence; + int wisdom; + int charisma; + int magic_resist; + int cold_resist; + int fire_resist; + int poison_resist; + int disease_resist; + int corruption_resist; + int physical_resist; + int min_dmg; + int max_dmg; + int64 hp_regen_rate; + int attack_delay; + int spell_scale; + int heal_scale; std::string special_abilities; }; @@ -91,9 +95,14 @@ public: bool IsAutoScaled(NPC* npc); bool LoadScaleData(); - global_npc_scale GetGlobalScaleDataForTypeLevel(int8 npc_type, int npc_level); + global_npc_scale GetGlobalScaleDataForTypeLevel( + int8 npc_type, + uint8 npc_level, + uint32 zone_id, + uint16 instance_version + ); - std::map, global_npc_scale> npc_global_base_scaling_data; + std::map, global_npc_scale> npc_global_base_scaling_data; int8 GetNPCScalingType(NPC * &npc); std::string GetNPCScalingTypeName(NPC * &npc);