вывод из самбомудлей модов для азероткор
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#ifndef __AB_ALL_CREATURE_SCRIPT_H
|
||||
#define __AB_ALL_CREATURE_SCRIPT_H
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
|
||||
class AutoBalance_AllCreatureScript : public AllCreatureScript
|
||||
{
|
||||
public:
|
||||
AutoBalance_AllCreatureScript()
|
||||
: AllCreatureScript("AutoBalance_AllCreatureScript")
|
||||
{
|
||||
}
|
||||
|
||||
void OnBeforeCreatureSelectLevel(const CreatureTemplate* /*creatureTemplate*/, Creature* creature, uint8& level) override;
|
||||
void Creature_SelectLevel(const CreatureTemplate* /* cinfo */, Creature* creature) override;
|
||||
void OnCreatureAddWorld(Creature* creature) override;
|
||||
void OnCreatureRemoveWorld(Creature* creature) override;
|
||||
void OnAllCreatureUpdate(Creature* creature, uint32 /*diff*/) override;
|
||||
|
||||
// Reset the passed creature to stock if the config has changed
|
||||
bool ResetCreatureIfNeeded(Creature* creature);
|
||||
void ModifyCreatureAttributes(Creature* creature);
|
||||
|
||||
private:
|
||||
bool _isSummonCloneOfSummoner(Creature* summon);
|
||||
};
|
||||
|
||||
#endif /* __AB_ALL_CREATURE_SCRIPT_H */
|
||||
@@ -0,0 +1,227 @@
|
||||
#include "ABAllMapScript.h"
|
||||
|
||||
#include "ABConfig.h"
|
||||
#include "ABMapInfo.h"
|
||||
#include "ABUtils.h"
|
||||
|
||||
#include "Chat.h"
|
||||
#include "Message.h"
|
||||
|
||||
|
||||
void AutoBalance_AllMapScript::OnPlayerEnterAll(Map* map, Player* player)
|
||||
{
|
||||
if (!EnableGlobal)
|
||||
return;
|
||||
|
||||
if (!map->IsDungeon())
|
||||
return;
|
||||
|
||||
LOG_DEBUG("module.AutoBalance", "AutoBalance:: ------------------------------------------------");
|
||||
|
||||
LOG_DEBUG("module.AutoBalance", "AutoBalance_AllMapScript::OnPlayerEnterAll: Player {}{} | enters {} ({}{})",
|
||||
player->GetName(),
|
||||
player->IsGameMaster() ? " (GM)" : "",
|
||||
map->GetMapName(),
|
||||
map->GetId(),
|
||||
map->GetInstanceId() ? "-" + std::to_string(map->GetInstanceId()) : ""
|
||||
);
|
||||
|
||||
// get the map's info
|
||||
AutoBalanceMapInfo* mapABInfo = GetMapInfo(map);
|
||||
|
||||
// store the previous difficulty for comparison later
|
||||
int prevAdjustedPlayerCount = mapABInfo->adjustedPlayerCount;
|
||||
|
||||
// add player to this map's player list
|
||||
AddPlayerToMap(map, player);
|
||||
|
||||
// recalculate the zone's level stats
|
||||
mapABInfo->highestCreatureLevel = 0;
|
||||
mapABInfo->lowestCreatureLevel = 0;
|
||||
//mapABInfo->avgCreatureLevel = 0;
|
||||
mapABInfo->activeCreatureCount = 0;
|
||||
|
||||
WorldSession* session = player->GetSession();
|
||||
LocaleConstant locale = session->GetSessionDbLocaleIndex();
|
||||
|
||||
// if the previous player count is the same as the new player count, update without force
|
||||
if ((prevAdjustedPlayerCount == mapABInfo->adjustedPlayerCount) && (mapABInfo->adjustedPlayerCount != 1))
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance", "AutoBalance_AllMapScript::OnPlayerEnterAll: Player difficulty unchanged at {}. Updating map data (no force).",
|
||||
mapABInfo->adjustedPlayerCount
|
||||
);
|
||||
|
||||
// Update the map's data
|
||||
UpdateMapDataIfNeeded(map, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance", "AutoBalance_AllMapScript::OnPlayerEnterAll: Player difficulty changed from ({})->({}). Updating map data (force).",
|
||||
prevAdjustedPlayerCount,
|
||||
mapABInfo->adjustedPlayerCount
|
||||
);
|
||||
|
||||
// Update the map's data, forced
|
||||
UpdateMapDataIfNeeded(map, true);
|
||||
}
|
||||
|
||||
// see which existing creatures are active
|
||||
for (std::vector<Creature*>::iterator creatureIterator = mapABInfo->allMapCreatures.begin(); creatureIterator != mapABInfo->allMapCreatures.end(); ++creatureIterator)
|
||||
{
|
||||
AddCreatureToMapCreatureList(*creatureIterator, false, true);
|
||||
}
|
||||
|
||||
// Notify players of the change
|
||||
if (PlayerChangeNotify && mapABInfo->enabled)
|
||||
{
|
||||
if (map->GetEntry()->IsDungeon() && player)
|
||||
{
|
||||
if (mapABInfo->playerCount)
|
||||
{
|
||||
for (std::vector<Player*>::const_iterator playerIterator = mapABInfo->allMapPlayers.begin(); playerIterator != mapABInfo->allMapPlayers.end(); ++playerIterator)
|
||||
{
|
||||
Player* thisPlayer = *playerIterator;
|
||||
if (thisPlayer)
|
||||
{
|
||||
ChatHandler chatHandle = ChatHandler(thisPlayer->GetSession());
|
||||
InstanceMap* instanceMap = map->ToInstanceMap();
|
||||
|
||||
std::string instanceDifficulty; if (instanceMap->IsHeroic()) instanceDifficulty = "Heroic"; else instanceDifficulty = "Normal";
|
||||
|
||||
if (thisPlayer && thisPlayer == player) // This is the player that entered
|
||||
{
|
||||
chatHandle.PSendSysMessage(ABGetLocaleText(locale, "welcome_to_player").c_str(),
|
||||
map->GetMapName(),
|
||||
instanceMap->GetMaxPlayers(),
|
||||
instanceDifficulty.c_str(),
|
||||
mapABInfo->playerCount,
|
||||
mapABInfo->adjustedPlayerCount);
|
||||
|
||||
// notify GMs that they won't be accounted for
|
||||
if (player->IsGameMaster())
|
||||
chatHandle.PSendSysMessage(ABGetLocaleText(locale, "welcome_to_gm").c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
// announce non-GMs entering the instance only
|
||||
if (!player->IsGameMaster())
|
||||
chatHandle.PSendSysMessage(ABGetLocaleText(locale, "announce_non_gm_entering_instance").c_str(), player->GetName().c_str(), mapABInfo->playerCount, mapABInfo->adjustedPlayerCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AutoBalance_AllMapScript::OnPlayerLeaveAll(Map* map, Player* player)
|
||||
{
|
||||
if (!EnableGlobal)
|
||||
return;
|
||||
|
||||
if (!map->IsDungeon())
|
||||
return;
|
||||
|
||||
LOG_DEBUG("module.AutoBalance", "AutoBalance:: ------------------------------------------------");
|
||||
|
||||
LOG_DEBUG("module.AutoBalance", "AutoBalance_AllMapScript::OnPlayerLeaveAll: Player {}{} | exits {} ({}{})",
|
||||
player->GetName(),
|
||||
player->IsGameMaster() ? " (GM)" : "",
|
||||
map->GetMapName(),
|
||||
map->GetId(),
|
||||
map->GetInstanceId() ? "-" + std::to_string(map->GetInstanceId()) : ""
|
||||
);
|
||||
|
||||
// get the map's info
|
||||
AutoBalanceMapInfo* mapABInfo = GetMapInfo(map);
|
||||
|
||||
// store the previous difficulty for comparison later
|
||||
int prevAdjustedPlayerCount = mapABInfo->adjustedPlayerCount;
|
||||
|
||||
// remove this player from this map's player list
|
||||
bool playerWasRemoved = RemovePlayerFromMap(map, player);
|
||||
|
||||
// report the number of players in the map
|
||||
LOG_DEBUG("module.AutoBalance", "AutoBalance_AllMapScript::OnPlayerLeaveAll: There are {} player(s) left in the map.", mapABInfo->allMapPlayers.size());
|
||||
|
||||
// if a player was NOT removed, return now - stats don't need to be updated
|
||||
if (!playerWasRemoved)
|
||||
return;
|
||||
|
||||
// recalculate the zone's level stats
|
||||
mapABInfo->highestCreatureLevel = 0;
|
||||
mapABInfo->lowestCreatureLevel = 0;
|
||||
//mapABInfo->avgCreatureLevel = 0;
|
||||
mapABInfo->activeCreatureCount = 0;
|
||||
|
||||
// see which existing creatures are active
|
||||
for (std::vector<Creature*>::iterator creatureIterator = mapABInfo->allMapCreatures.begin(); creatureIterator != mapABInfo->allMapCreatures.end(); ++creatureIterator)
|
||||
AddCreatureToMapCreatureList(*creatureIterator, false, true);
|
||||
|
||||
// if the previous player count is the same as the new player count, update without force
|
||||
if (prevAdjustedPlayerCount == mapABInfo->adjustedPlayerCount)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance", "AutoBalance_AllMapScript::OnPlayerLeaveAll: Player difficulty unchanged at {}. Updating map data (no force).",
|
||||
mapABInfo->adjustedPlayerCount
|
||||
);
|
||||
|
||||
// Update the map's data
|
||||
UpdateMapDataIfNeeded(map, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance", "AutoBalance_AllMapScript::OnPlayerLeaveAll: Player difficulty changed from ({})->({}). Updating map data (force).",
|
||||
prevAdjustedPlayerCount,
|
||||
mapABInfo->adjustedPlayerCount
|
||||
);
|
||||
|
||||
// Update the map's data, forced
|
||||
UpdateMapDataIfNeeded(map, true);
|
||||
}
|
||||
|
||||
// updates the player count and levels for the map
|
||||
if (map->GetEntry() && map->GetEntry()->IsDungeon())
|
||||
{
|
||||
{
|
||||
mapABInfo->playerCount = mapABInfo->allMapPlayers.size();
|
||||
LOG_DEBUG("module.AutoBalance", "AutoBalance_AllMapScript::OnPlayerLeaveAll: Player {} left the instance.",
|
||||
player->GetName(),
|
||||
mapABInfo->playerCount,
|
||||
mapABInfo->adjustedPlayerCount
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Notify remaining players in the instance that a player left
|
||||
if (PlayerChangeNotify && mapABInfo->enabled)
|
||||
{
|
||||
if (map->GetEntry()->IsDungeon() && player && !player->IsGameMaster())
|
||||
{
|
||||
if (mapABInfo->playerCount)
|
||||
{
|
||||
for (std::vector<Player*>::const_iterator playerIterator = mapABInfo->allMapPlayers.begin(); playerIterator != mapABInfo->allMapPlayers.end(); ++playerIterator)
|
||||
{
|
||||
Player* thisPlayer = *playerIterator;
|
||||
if (thisPlayer && thisPlayer != player)
|
||||
{
|
||||
ChatHandler chatHandle = ChatHandler(thisPlayer->GetSession());
|
||||
|
||||
if (mapABInfo->combatLocked)
|
||||
{
|
||||
chatHandle.PSendSysMessage(ABGetLocaleText(thisPlayer->GetSession()->GetSessionDbLocaleIndex(), "leaving_instance_combat").c_str(),
|
||||
player->GetName().c_str(),
|
||||
mapABInfo->adjustedPlayerCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
chatHandle.PSendSysMessage(ABGetLocaleText(thisPlayer->GetSession()->GetSessionDbLocaleIndex(), "leaving_instance").c_str(),
|
||||
player->GetName().c_str(),
|
||||
mapABInfo->playerCount,
|
||||
mapABInfo->adjustedPlayerCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#ifndef __AB_ALL_MAP_SCRIPT_H
|
||||
#define __AB_ALL_MAP_SCRIPT_H
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
|
||||
class AutoBalance_AllMapScript : public AllMapScript
|
||||
{
|
||||
public:
|
||||
AutoBalance_AllMapScript()
|
||||
: AllMapScript("AutoBalance_AllMapScript", {
|
||||
ALLMAPHOOK_ON_PLAYER_ENTER_ALL,
|
||||
ALLMAPHOOK_ON_PLAYER_LEAVE_ALL
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
// hook triggers after the player has already entered the world
|
||||
void OnPlayerEnterAll(Map* map, Player* player) override;
|
||||
// hook triggers just before the player left the world
|
||||
void OnPlayerLeaveAll(Map* map, Player* player) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,186 @@
|
||||
#include "ABCommandScript.h"
|
||||
|
||||
#include "ABConfig.h"
|
||||
#include "ABCreatureInfo.h"
|
||||
#include "ABMapInfo.h"
|
||||
#include "ABUtils.h"
|
||||
#include "Message.h"
|
||||
|
||||
bool AutoBalance_CommandScript::HandleABSetOffsetCommand(ChatHandler* handler, const char* args)
|
||||
{
|
||||
if (!*args)
|
||||
{
|
||||
handler->PSendSysMessage(".autobalance setoffset #");
|
||||
handler->PSendSysMessage(ABGetLocaleText(handler->GetSession()->GetSessionDbLocaleIndex(), "set_offset_command_description").c_str());
|
||||
return false;
|
||||
}
|
||||
char* offset = strtok((char*)args, " ");
|
||||
int32 offseti = -1;
|
||||
|
||||
if (offset)
|
||||
{
|
||||
offseti = (uint32)atoi(offset);
|
||||
std::vector<std::string> args = { std::to_string(offseti) };
|
||||
handler->PSendSysMessage(ABGetLocaleText(handler->GetSession()->GetSessionDbLocaleIndex(), "set_offset_command_success").c_str(), offseti);
|
||||
PlayerCountDifficultyOffset = offseti;
|
||||
globalConfigTime = GetCurrentConfigTime();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
handler->PSendSysMessage(ABGetLocaleText(handler->GetSession()->GetSessionDbLocaleIndex(), "set_offset_command_error").c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AutoBalance_CommandScript::HandleABGetOffsetCommand(ChatHandler* handler, const char* /*args*/)
|
||||
{
|
||||
handler->PSendSysMessage(ABGetLocaleText(handler->GetSession()->GetSessionDbLocaleIndex(), "get_offset_command_success").c_str(), PlayerCountDifficultyOffset);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AutoBalance_CommandScript::HandleABMapStatsCommand(ChatHandler* handler, const char* /*args*/)
|
||||
{
|
||||
Player* player = handler->GetPlayer();
|
||||
auto locale = handler->GetSession()->GetSessionDbLocaleIndex();
|
||||
|
||||
AutoBalanceMapInfo* mapABInfo = GetMapInfo(player->GetMap());
|
||||
|
||||
if (player->GetMap()->IsDungeon())
|
||||
{
|
||||
handler->PSendSysMessage("---");
|
||||
// Map basics
|
||||
handler->PSendSysMessage("{} ({}-player {}) | ID {}-{}{}",
|
||||
player->GetMap()->GetMapName(),
|
||||
player->GetMap()->ToInstanceMap()->GetMaxPlayers(),
|
||||
player->GetMap()->ToInstanceMap()->IsHeroic() ? "Heroic" : "Normal",
|
||||
player->GetMapId(),
|
||||
player->GetInstanceId(),
|
||||
mapABInfo->enabled ? "" : " | AutoBalance DISABLED");
|
||||
|
||||
// if the map isn't enabled, don't display anything else
|
||||
// if (!mapABInfo->enabled) { return true; }
|
||||
|
||||
// Player stats
|
||||
handler->PSendSysMessage("Players on map: {} (Lvl {} - {})",
|
||||
mapABInfo->playerCount,
|
||||
mapABInfo->lowestPlayerLevel,
|
||||
mapABInfo->highestPlayerLevel
|
||||
);
|
||||
|
||||
// Adjusted player count (multiple scenarios)
|
||||
if (mapABInfo->combatLockTripped)
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "adjusted_player_count_combat_locked").c_str(), mapABInfo->adjustedPlayerCount);
|
||||
else if (mapABInfo->playerCount < mapABInfo->minPlayers && !PlayerCountDifficultyOffset)
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "adjusted_player_count_map_minimum").c_str(), mapABInfo->adjustedPlayerCount);
|
||||
else if (mapABInfo->playerCount < mapABInfo->minPlayers && PlayerCountDifficultyOffset)
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "adjusted_player_count_map_minimum_difficulty_offset").c_str(), mapABInfo->adjustedPlayerCount, PlayerCountDifficultyOffset);
|
||||
else if (PlayerCountDifficultyOffset)
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "adjusted_player_count_difficulty_offset").c_str(), mapABInfo->adjustedPlayerCount, PlayerCountDifficultyOffset);
|
||||
else
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "adjusted_player_count").c_str(), mapABInfo->adjustedPlayerCount);
|
||||
|
||||
// LFG levels
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "lfg_range").c_str(), mapABInfo->lfgMinLevel, mapABInfo->lfgMaxLevel, mapABInfo->lfgTargetLevel);
|
||||
|
||||
// Calculated map level (creature average)
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "map_level").c_str(),
|
||||
(uint8)(mapABInfo->avgCreatureLevel + 0.5f),
|
||||
mapABInfo->isLevelScalingEnabled && mapABInfo->enabled ? "->" + std::to_string(mapABInfo->highestPlayerLevel) + ABGetLocaleText(locale, "level_scaling_enabled").c_str() : ABGetLocaleText(locale, "level_scaling_disabled").c_str()
|
||||
);
|
||||
|
||||
// World Health Multiplier
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "world_health_multiplier").c_str(), mapABInfo->worldHealthMultiplier);
|
||||
|
||||
// World Damage and Healing Multiplier
|
||||
if (mapABInfo->worldDamageHealingMultiplier != mapABInfo->scaledWorldDamageHealingMultiplier)
|
||||
{
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "world_hostile_damage_healing_multiplier_to").c_str(),
|
||||
mapABInfo->worldDamageHealingMultiplier,
|
||||
mapABInfo->scaledWorldDamageHealingMultiplier
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "world_hostile_damage_healing_multiplier").c_str(),
|
||||
mapABInfo->worldDamageHealingMultiplier
|
||||
);
|
||||
}
|
||||
|
||||
// Creature Stats
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "original_creature_level_range").c_str(),
|
||||
mapABInfo->lowestCreatureLevel,
|
||||
mapABInfo->highestCreatureLevel,
|
||||
mapABInfo->avgCreatureLevel
|
||||
);
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "active_total_creatures_in_map").c_str(),
|
||||
mapABInfo->activeCreatureCount,
|
||||
mapABInfo->allMapCreatures.size()
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "ab_command_only_in_instance").c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool AutoBalance_CommandScript::HandleABCreatureStatsCommand(ChatHandler* handler, const char* /*args*/)
|
||||
{
|
||||
Creature* target = handler->getSelectedCreature();
|
||||
|
||||
auto locale = handler->GetSession()->GetSessionDbLocaleIndex();
|
||||
|
||||
if (!target)
|
||||
{
|
||||
handler->SendSysMessage(LANG_SELECT_CREATURE);
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
else if (!target->GetMap()->IsDungeon())
|
||||
{
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "target_no_in_instance").c_str());
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
AutoBalanceCreatureInfo* targetABInfo = target->CustomData.GetDefault<AutoBalanceCreatureInfo>("AutoBalanceCreatureInfo");
|
||||
|
||||
handler->PSendSysMessage("---");
|
||||
handler->PSendSysMessage("{} ({}{}{}), {}",
|
||||
target->GetName(),
|
||||
targetABInfo->UnmodifiedLevel,
|
||||
isCreatureRelevant(target) && targetABInfo->UnmodifiedLevel != target->GetLevel() ? "->" + std::to_string(targetABInfo->selectedLevel) : "",
|
||||
isBossOrBossSummon(target) ? " | Boss" : "",
|
||||
targetABInfo->isActive ? ABGetLocaleText(locale, "active_for_map_stats").c_str() : ABGetLocaleText(locale, "ignored_for_map_stats").c_str());
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "creature_difficulty_level").c_str(), targetABInfo->instancePlayerCount);
|
||||
|
||||
// summon
|
||||
if (target->IsSummon() && targetABInfo->summoner && targetABInfo->isCloneOfSummoner)
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "clone_of_summon").c_str(), targetABInfo->summonerName, targetABInfo->summonerLevel);
|
||||
else if (target->IsSummon() && targetABInfo->summoner)
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "summon_of_summon").c_str(), targetABInfo->summonerName, targetABInfo->summonerLevel);
|
||||
else if (target->IsSummon())
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "summon_without_summoner").c_str());
|
||||
|
||||
// level scaled
|
||||
if (targetABInfo->UnmodifiedLevel != target->GetLevel())
|
||||
{
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "health_multiplier_to").c_str(), targetABInfo->HealthMultiplier, targetABInfo->ScaledHealthMultiplier);
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "mana_multiplier_to").c_str(), targetABInfo->ManaMultiplier, targetABInfo->ScaledManaMultiplier);
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "armor_multiplier_to").c_str(), targetABInfo->ArmorMultiplier, targetABInfo->ScaledArmorMultiplier);
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "damage_multiplier_to").c_str(), targetABInfo->DamageMultiplier, targetABInfo->ScaledDamageMultiplier);
|
||||
}
|
||||
// not level scaled
|
||||
else
|
||||
{
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "health_multiplier").c_str(), targetABInfo->HealthMultiplier);
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "mana_multiplier").c_str(), targetABInfo->ManaMultiplier);
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "armor_multiplier").c_str(), targetABInfo->ArmorMultiplier);
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "damage_multiplier").c_str(), targetABInfo->DamageMultiplier);
|
||||
}
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "cc_duration_multiplier").c_str(), targetABInfo->CCDurationMultiplier);
|
||||
handler->PSendSysMessage(ABGetLocaleText(locale, "xp_money_multiplier").c_str(), targetABInfo->XPModifier, targetABInfo->MoneyModifier);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#ifndef __AB_COMMAND_SCRIPT_H
|
||||
#define __AB_COMMAND_SCRIPT_H
|
||||
|
||||
#include "Chat.h"
|
||||
#include "Config.h"
|
||||
#include "ScriptMgr.h"
|
||||
|
||||
using namespace Acore::ChatCommands;
|
||||
|
||||
class AutoBalance_CommandScript : public CommandScript
|
||||
{
|
||||
public:
|
||||
AutoBalance_CommandScript() : CommandScript("AutoBalance_CommandScript") { }
|
||||
|
||||
ChatCommandTable GetCommands() const override
|
||||
{
|
||||
static ChatCommandTable ABCommandTable =
|
||||
{
|
||||
{ "setoffset", HandleABSetOffsetCommand, SEC_GAMEMASTER, Console::Yes },
|
||||
{ "getoffset", HandleABGetOffsetCommand, SEC_PLAYER, Console::Yes },
|
||||
{ "mapstat", HandleABMapStatsCommand, SEC_PLAYER, Console::Yes },
|
||||
{ "creaturestat", HandleABCreatureStatsCommand, SEC_PLAYER, Console::Yes }
|
||||
};
|
||||
|
||||
static ChatCommandTable commandTable =
|
||||
{
|
||||
{ "autobalance", ABCommandTable },
|
||||
{ "ab", ABCommandTable },
|
||||
};
|
||||
|
||||
return commandTable;
|
||||
};
|
||||
|
||||
static bool HandleABSetOffsetCommand(ChatHandler* handler, const char* args);
|
||||
static bool HandleABGetOffsetCommand(ChatHandler* handler, const char* args);
|
||||
static bool HandleABMapStatsCommand(ChatHandler* handler, const char* args);
|
||||
static bool HandleABCreatureStatsCommand(ChatHandler* handler, const char* args);
|
||||
};
|
||||
|
||||
#endif /* __AB_COMMAND_SCRIPT_H */
|
||||
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#include "ABConfig.h"
|
||||
#include "ABUtils.h"
|
||||
|
||||
std::map <int, int> forcedCreatureIds;
|
||||
std::list<uint32> disabledDungeonIds;
|
||||
|
||||
uint32 minPlayersNormal;
|
||||
uint32 minPlayersHeroic;
|
||||
uint32 minPlayersRaid;
|
||||
uint32 minPlayersRaidHeroic;
|
||||
std::map<uint32, uint8> minPlayersPerDungeonIdMap;
|
||||
std::map<uint32, uint8> minPlayersPerHeroicDungeonIdMap;
|
||||
|
||||
std::map<uint32, AutoBalanceInflectionPointSettings> dungeonOverrides;
|
||||
std::map<uint32, AutoBalanceInflectionPointSettings> bossOverrides;
|
||||
std::map<uint32, AutoBalanceStatModifiers> statModifierOverrides;
|
||||
std::map<uint32, AutoBalanceStatModifiers> statModifierBossOverrides;
|
||||
std::map<uint32, AutoBalanceStatModifiers> statModifierCreatureOverrides;
|
||||
std::map<uint8, AutoBalanceLevelScalingDynamicLevelSettings> levelScalingDynamicLevelOverrides;
|
||||
std::map<uint32, uint32> levelScalingDistanceCheckOverrides;
|
||||
|
||||
// spell IDs that spend player health
|
||||
// player abilities don't actually appear to be caught by `ModifySpellDamageTaken`,
|
||||
// but I'm leaving them here in case they ever DO get caught by it
|
||||
std::list<uint32> spellIdsThatSpendPlayerHealth =
|
||||
{
|
||||
45529, // Blood Tap
|
||||
2687, // Bloodrage
|
||||
27869, // Dark Rune
|
||||
16666, // Demonic Rune
|
||||
755, // Health Funnel (Rank 1)
|
||||
3698, // Health Funnel (Rank 2)
|
||||
3699, // Health Funnel (Rank 3)
|
||||
3700, // Health Funnel (Rank 4)
|
||||
11693, // Health Funnel (Rank 5)
|
||||
11694, // Health Funnel (Rank 6)
|
||||
11695, // Health Funnel (Rank 7)
|
||||
27259, // Health Funnel (Rank 8)
|
||||
47856, // Health Funnel (Rank 9)
|
||||
1454, // Life Tap (Rank 1)
|
||||
1455, // Life Tap (Rank 2)
|
||||
1456, // Life Tap (Rank 3)
|
||||
11687, // Life Tap (Rank 4)
|
||||
11688, // Life Tap (Rank 5)
|
||||
11689, // Life Tap (Rank 6)
|
||||
27222, // Life Tap (Rank 7)
|
||||
57946, // Life Tap (Rank 8)
|
||||
29858, // Soulshatter
|
||||
55213 // Unholy Frenzy
|
||||
};
|
||||
|
||||
// spell IDs that should never be modified
|
||||
// handles cases where a spell is reflecting damage or otherwise converting player damage to something else
|
||||
std::list<uint32> spellIdsToNeverModify =
|
||||
{
|
||||
1177 // Twin Empathy (AQ40 Twin Emperors, only in `spell_dbc` database table)
|
||||
};
|
||||
|
||||
// creature IDs that should never be considered clones
|
||||
// handles cases where a creature is spawned by another creature, but is not a clone (doesn't retain health/mana values)
|
||||
std::list<uint32> creatureIDsThatAreNotClones =
|
||||
{
|
||||
16152 // Attumen the Huntsman (Karazhan) combined form
|
||||
};
|
||||
|
||||
int8 PlayerCountDifficultyOffset;
|
||||
|
||||
bool LevelScaling;
|
||||
int8 LevelScalingSkipHigherLevels;
|
||||
int8 LevelScalingSkipLowerLevels;
|
||||
int8 LevelScalingDynamicLevelCeilingDungeons;
|
||||
int8 LevelScalingDynamicLevelFloorDungeons;
|
||||
int8 LevelScalingDynamicLevelCeilingRaids;
|
||||
int8 LevelScalingDynamicLevelFloorRaids;
|
||||
int8 LevelScalingDynamicLevelCeilingHeroicDungeons;
|
||||
int8 LevelScalingDynamicLevelFloorHeroicDungeons;
|
||||
int8 LevelScalingDynamicLevelCeilingHeroicRaids;
|
||||
int8 LevelScalingDynamicLevelFloorHeroicRaids;
|
||||
ScalingMethod LevelScalingMethod;
|
||||
|
||||
uint32 rewardRaid;
|
||||
uint32 rewardDungeon;
|
||||
uint32 MinPlayerReward;
|
||||
|
||||
bool Announcement;
|
||||
|
||||
bool LevelScalingEndGameBoost;
|
||||
bool PlayerChangeNotify;
|
||||
bool rewardEnabled;
|
||||
|
||||
float MinHPModifier;
|
||||
float MinManaModifier;
|
||||
float MinDamageModifier;
|
||||
float MinCCDurationModifier;
|
||||
float MaxCCDurationModifier;
|
||||
|
||||
//
|
||||
// RewardScaling.*
|
||||
//
|
||||
|
||||
ScalingMethod RewardScalingMethod;
|
||||
bool RewardScalingXP;
|
||||
bool RewardScalingMoney;
|
||||
float RewardScalingXPModifier;
|
||||
float RewardScalingMoneyModifier;
|
||||
|
||||
uint64_t globalConfigTime = GetCurrentConfigTime();
|
||||
|
||||
//
|
||||
// Enable.*
|
||||
//
|
||||
|
||||
bool EnableGlobal;
|
||||
bool Enable5M;
|
||||
bool Enable10M;
|
||||
bool Enable15M;
|
||||
bool Enable20M;
|
||||
bool Enable25M;
|
||||
bool Enable40M;
|
||||
bool Enable5MHeroic;
|
||||
bool Enable10MHeroic;
|
||||
bool Enable25MHeroic;
|
||||
bool EnableOtherNormal;
|
||||
bool EnableOtherHeroic;
|
||||
|
||||
//
|
||||
// InflectionPoint*
|
||||
//
|
||||
|
||||
float InflectionPoint;
|
||||
float InflectionPointCurveFloor;
|
||||
float InflectionPointCurveCeiling;
|
||||
float InflectionPointBoss;
|
||||
|
||||
float InflectionPointHeroic;
|
||||
float InflectionPointHeroicCurveFloor;
|
||||
float InflectionPointHeroicCurveCeiling;
|
||||
float InflectionPointHeroicBoss;
|
||||
|
||||
float InflectionPointRaid;
|
||||
float InflectionPointRaidCurveFloor;
|
||||
float InflectionPointRaidCurveCeiling;
|
||||
float InflectionPointRaidBoss;
|
||||
|
||||
float InflectionPointRaidHeroic;
|
||||
float InflectionPointRaidHeroicCurveFloor;
|
||||
float InflectionPointRaidHeroicCurveCeiling;
|
||||
float InflectionPointRaidHeroicBoss;
|
||||
|
||||
float InflectionPointRaid10M;
|
||||
float InflectionPointRaid10MCurveFloor;
|
||||
float InflectionPointRaid10MCurveCeiling;
|
||||
float InflectionPointRaid10MBoss;
|
||||
|
||||
float InflectionPointRaid10MHeroic;
|
||||
float InflectionPointRaid10MHeroicCurveFloor;
|
||||
float InflectionPointRaid10MHeroicCurveCeiling;
|
||||
float InflectionPointRaid10MHeroicBoss;
|
||||
|
||||
float InflectionPointRaid15M;
|
||||
float InflectionPointRaid15MCurveFloor;
|
||||
float InflectionPointRaid15MCurveCeiling;
|
||||
float InflectionPointRaid15MBoss;
|
||||
|
||||
float InflectionPointRaid20M;
|
||||
float InflectionPointRaid20MCurveFloor;
|
||||
float InflectionPointRaid20MCurveCeiling;
|
||||
float InflectionPointRaid20MBoss;
|
||||
|
||||
float InflectionPointRaid25M;
|
||||
float InflectionPointRaid25MCurveFloor;
|
||||
float InflectionPointRaid25MCurveCeiling;
|
||||
float InflectionPointRaid25MBoss;
|
||||
|
||||
float InflectionPointRaid25MHeroic;
|
||||
float InflectionPointRaid25MHeroicCurveFloor;
|
||||
float InflectionPointRaid25MHeroicCurveCeiling;
|
||||
float InflectionPointRaid25MHeroicBoss;
|
||||
|
||||
float InflectionPointRaid40M;
|
||||
float InflectionPointRaid40MCurveFloor;
|
||||
float InflectionPointRaid40MCurveCeiling;
|
||||
float InflectionPointRaid40MBoss;
|
||||
|
||||
//
|
||||
// StatModifier*
|
||||
//
|
||||
|
||||
float StatModifier_Global;
|
||||
float StatModifier_Health;
|
||||
float StatModifier_Mana;
|
||||
float StatModifier_Armor;
|
||||
float StatModifier_Damage;
|
||||
float StatModifier_CCDuration;
|
||||
|
||||
float StatModifierHeroic_Global;
|
||||
float StatModifierHeroic_Health;
|
||||
float StatModifierHeroic_Mana;
|
||||
float StatModifierHeroic_Armor;
|
||||
float StatModifierHeroic_Damage;
|
||||
float StatModifierHeroic_CCDuration;
|
||||
|
||||
float StatModifierRaid_Global;
|
||||
float StatModifierRaid_Health;
|
||||
float StatModifierRaid_Mana;
|
||||
float StatModifierRaid_Armor;
|
||||
float StatModifierRaid_Damage;
|
||||
float StatModifierRaid_CCDuration;
|
||||
|
||||
float StatModifierRaidHeroic_Global;
|
||||
float StatModifierRaidHeroic_Health;
|
||||
float StatModifierRaidHeroic_Mana;
|
||||
float StatModifierRaidHeroic_Armor;
|
||||
float StatModifierRaidHeroic_Damage;
|
||||
float StatModifierRaidHeroic_CCDuration;
|
||||
|
||||
float StatModifierRaid10M_Global;
|
||||
float StatModifierRaid10M_Health;
|
||||
float StatModifierRaid10M_Mana;
|
||||
float StatModifierRaid10M_Armor;
|
||||
float StatModifierRaid10M_Damage;
|
||||
float StatModifierRaid10M_CCDuration;
|
||||
|
||||
float StatModifierRaid10MHeroic_Global;
|
||||
float StatModifierRaid10MHeroic_Health;
|
||||
float StatModifierRaid10MHeroic_Mana;
|
||||
float StatModifierRaid10MHeroic_Armor;
|
||||
float StatModifierRaid10MHeroic_Damage;
|
||||
float StatModifierRaid10MHeroic_CCDuration;
|
||||
|
||||
float StatModifierRaid15M_Global;
|
||||
float StatModifierRaid15M_Health;
|
||||
float StatModifierRaid15M_Mana;
|
||||
float StatModifierRaid15M_Armor;
|
||||
float StatModifierRaid15M_Damage;
|
||||
float StatModifierRaid15M_CCDuration;
|
||||
|
||||
float StatModifierRaid20M_Global;
|
||||
float StatModifierRaid20M_Health;
|
||||
float StatModifierRaid20M_Mana;
|
||||
float StatModifierRaid20M_Armor;
|
||||
float StatModifierRaid20M_Damage;
|
||||
float StatModifierRaid20M_CCDuration;
|
||||
|
||||
float StatModifierRaid25M_Global;
|
||||
float StatModifierRaid25M_Health;
|
||||
float StatModifierRaid25M_Mana;
|
||||
float StatModifierRaid25M_Armor;
|
||||
float StatModifierRaid25M_Damage;
|
||||
float StatModifierRaid25M_CCDuration;
|
||||
|
||||
float StatModifierRaid25MHeroic_Global;
|
||||
float StatModifierRaid25MHeroic_Health;
|
||||
float StatModifierRaid25MHeroic_Mana;
|
||||
float StatModifierRaid25MHeroic_Armor;
|
||||
float StatModifierRaid25MHeroic_Damage;
|
||||
float StatModifierRaid25MHeroic_CCDuration;
|
||||
|
||||
float StatModifierRaid40M_Global;
|
||||
float StatModifierRaid40M_Health;
|
||||
float StatModifierRaid40M_Mana;
|
||||
float StatModifierRaid40M_Armor;
|
||||
float StatModifierRaid40M_Damage;
|
||||
float StatModifierRaid40M_CCDuration;
|
||||
|
||||
//
|
||||
// StatModifier* (Boss)
|
||||
//
|
||||
|
||||
float StatModifier_Boss_Global;
|
||||
float StatModifier_Boss_Health;
|
||||
float StatModifier_Boss_Mana;
|
||||
float StatModifier_Boss_Armor;
|
||||
float StatModifier_Boss_Damage;
|
||||
float StatModifier_Boss_CCDuration;
|
||||
|
||||
float StatModifierHeroic_Boss_Global;
|
||||
float StatModifierHeroic_Boss_Health;
|
||||
float StatModifierHeroic_Boss_Mana;
|
||||
float StatModifierHeroic_Boss_Armor;
|
||||
float StatModifierHeroic_Boss_Damage;
|
||||
float StatModifierHeroic_Boss_CCDuration;
|
||||
|
||||
float StatModifierRaid_Boss_Global;
|
||||
float StatModifierRaid_Boss_Health;
|
||||
float StatModifierRaid_Boss_Mana;
|
||||
float StatModifierRaid_Boss_Armor;
|
||||
float StatModifierRaid_Boss_Damage;
|
||||
float StatModifierRaid_Boss_CCDuration;
|
||||
|
||||
float StatModifierRaidHeroic_Boss_Global;
|
||||
float StatModifierRaidHeroic_Boss_Health;
|
||||
float StatModifierRaidHeroic_Boss_Mana;
|
||||
float StatModifierRaidHeroic_Boss_Armor;
|
||||
float StatModifierRaidHeroic_Boss_Damage;
|
||||
float StatModifierRaidHeroic_Boss_CCDuration;
|
||||
|
||||
float StatModifierRaid10M_Boss_Global;
|
||||
float StatModifierRaid10M_Boss_Health;
|
||||
float StatModifierRaid10M_Boss_Mana;
|
||||
float StatModifierRaid10M_Boss_Armor;
|
||||
float StatModifierRaid10M_Boss_Damage;
|
||||
float StatModifierRaid10M_Boss_CCDuration;
|
||||
|
||||
float StatModifierRaid10MHeroic_Boss_Global;
|
||||
float StatModifierRaid10MHeroic_Boss_Health;
|
||||
float StatModifierRaid10MHeroic_Boss_Mana;
|
||||
float StatModifierRaid10MHeroic_Boss_Armor;
|
||||
float StatModifierRaid10MHeroic_Boss_Damage;
|
||||
float StatModifierRaid10MHeroic_Boss_CCDuration;
|
||||
|
||||
float StatModifierRaid15M_Boss_Global;
|
||||
float StatModifierRaid15M_Boss_Health;
|
||||
float StatModifierRaid15M_Boss_Mana;
|
||||
float StatModifierRaid15M_Boss_Armor;
|
||||
float StatModifierRaid15M_Boss_Damage;
|
||||
float StatModifierRaid15M_Boss_CCDuration;
|
||||
|
||||
float StatModifierRaid20M_Boss_Global;
|
||||
float StatModifierRaid20M_Boss_Health;
|
||||
float StatModifierRaid20M_Boss_Mana;
|
||||
float StatModifierRaid20M_Boss_Armor;
|
||||
float StatModifierRaid20M_Boss_Damage;
|
||||
float StatModifierRaid20M_Boss_CCDuration;
|
||||
|
||||
float StatModifierRaid25M_Boss_Global;
|
||||
float StatModifierRaid25M_Boss_Health;
|
||||
float StatModifierRaid25M_Boss_Mana;
|
||||
float StatModifierRaid25M_Boss_Armor;
|
||||
float StatModifierRaid25M_Boss_Damage;
|
||||
float StatModifierRaid25M_Boss_CCDuration;
|
||||
|
||||
float StatModifierRaid25MHeroic_Boss_Global;
|
||||
float StatModifierRaid25MHeroic_Boss_Health;
|
||||
float StatModifierRaid25MHeroic_Boss_Mana;
|
||||
float StatModifierRaid25MHeroic_Boss_Armor;
|
||||
float StatModifierRaid25MHeroic_Boss_Damage;
|
||||
float StatModifierRaid25MHeroic_Boss_CCDuration;
|
||||
|
||||
float StatModifierRaid40M_Boss_Global;
|
||||
float StatModifierRaid40M_Boss_Health;
|
||||
float StatModifierRaid40M_Boss_Mana;
|
||||
float StatModifierRaid40M_Boss_Armor;
|
||||
float StatModifierRaid40M_Boss_Damage;
|
||||
float StatModifierRaid40M_Boss_CCDuration;
|
||||
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#ifndef __AB_CONFIG_H
|
||||
#define __AB_CONFIG_H
|
||||
|
||||
#include "ABInflectionPointSettings.h"
|
||||
#include "ABLevelScalingDynamicLevelSettings.h"
|
||||
#include "ABStatModifiers.h"
|
||||
#include "AutoBalance.h"
|
||||
|
||||
#include "SharedDefines.h"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
extern std::map<uint32, AutoBalanceInflectionPointSettings> dungeonOverrides;
|
||||
extern std::map<uint32, AutoBalanceInflectionPointSettings> bossOverrides;
|
||||
extern std::map<uint32, AutoBalanceStatModifiers> statModifierOverrides;
|
||||
extern std::map<uint32, AutoBalanceStatModifiers> statModifierBossOverrides;
|
||||
extern std::map<uint32, AutoBalanceStatModifiers> statModifierCreatureOverrides;
|
||||
extern std::map<uint8 , AutoBalanceLevelScalingDynamicLevelSettings> levelScalingDynamicLevelOverrides;
|
||||
extern std::map<uint32, uint32> levelScalingDistanceCheckOverrides;
|
||||
|
||||
extern std::map <int, int> forcedCreatureIds;
|
||||
extern std::list<uint32> disabledDungeonIds;
|
||||
|
||||
extern uint32 minPlayersNormal;
|
||||
extern uint32 minPlayersHeroic;
|
||||
extern uint32 minPlayersRaid;
|
||||
extern uint32 minPlayersRaidHeroic;
|
||||
extern std::map<uint32, uint8> minPlayersPerDungeonIdMap;
|
||||
extern std::map<uint32, uint8> minPlayersPerHeroicDungeonIdMap;
|
||||
|
||||
extern std::list<uint32> spellIdsThatSpendPlayerHealth;
|
||||
extern std::list<uint32> spellIdsToNeverModify;
|
||||
extern std::list<uint32> creatureIDsThatAreNotClones;
|
||||
|
||||
extern int8 PlayerCountDifficultyOffset;
|
||||
|
||||
extern bool LevelScaling;
|
||||
extern int8 LevelScalingSkipHigherLevels;
|
||||
extern int8 LevelScalingSkipLowerLevels;
|
||||
extern int8 LevelScalingDynamicLevelCeilingDungeons;
|
||||
extern int8 LevelScalingDynamicLevelFloorDungeons;
|
||||
extern int8 LevelScalingDynamicLevelCeilingRaids;
|
||||
extern int8 LevelScalingDynamicLevelFloorRaids;
|
||||
extern int8 LevelScalingDynamicLevelCeilingHeroicDungeons;
|
||||
extern int8 LevelScalingDynamicLevelFloorHeroicDungeons;
|
||||
extern int8 LevelScalingDynamicLevelCeilingHeroicRaids;
|
||||
extern int8 LevelScalingDynamicLevelFloorHeroicRaids;
|
||||
extern ScalingMethod LevelScalingMethod;
|
||||
|
||||
extern uint32 rewardRaid;
|
||||
extern uint32 rewardDungeon;
|
||||
extern uint32 MinPlayerReward;
|
||||
|
||||
extern bool Announcement;
|
||||
|
||||
extern bool LevelScalingEndGameBoost;
|
||||
extern bool PlayerChangeNotify;
|
||||
extern bool rewardEnabled;
|
||||
|
||||
extern float MinHPModifier;
|
||||
extern float MinManaModifier;
|
||||
extern float MinDamageModifier;
|
||||
extern float MinCCDurationModifier;
|
||||
extern float MaxCCDurationModifier;
|
||||
|
||||
//
|
||||
// RewardScaling.*
|
||||
//
|
||||
|
||||
extern ScalingMethod RewardScalingMethod;
|
||||
extern bool RewardScalingXP;
|
||||
extern bool RewardScalingMoney;
|
||||
extern float RewardScalingXPModifier;
|
||||
extern float RewardScalingMoneyModifier;
|
||||
|
||||
extern uint64_t globalConfigTime;
|
||||
|
||||
//
|
||||
// Enable.*
|
||||
//
|
||||
|
||||
extern bool EnableGlobal;
|
||||
extern bool Enable5M;
|
||||
extern bool Enable10M;
|
||||
extern bool Enable15M;
|
||||
extern bool Enable20M;
|
||||
extern bool Enable25M;
|
||||
extern bool Enable40M;
|
||||
extern bool Enable5MHeroic;
|
||||
extern bool Enable10MHeroic;
|
||||
extern bool Enable25MHeroic;
|
||||
extern bool EnableOtherNormal;
|
||||
extern bool EnableOtherHeroic;
|
||||
|
||||
//
|
||||
// InflectionPoint*
|
||||
//
|
||||
|
||||
extern float InflectionPoint;
|
||||
extern float InflectionPointCurveFloor;
|
||||
extern float InflectionPointCurveCeiling;
|
||||
extern float InflectionPointBoss;
|
||||
|
||||
extern float InflectionPointHeroic;
|
||||
extern float InflectionPointHeroicCurveFloor;
|
||||
extern float InflectionPointHeroicCurveCeiling;
|
||||
extern float InflectionPointHeroicBoss;
|
||||
|
||||
extern float InflectionPointRaid;
|
||||
extern float InflectionPointRaidCurveFloor;
|
||||
extern float InflectionPointRaidCurveCeiling;
|
||||
extern float InflectionPointRaidBoss;
|
||||
|
||||
extern float InflectionPointRaidHeroic;
|
||||
extern float InflectionPointRaidHeroicCurveFloor;
|
||||
extern float InflectionPointRaidHeroicCurveCeiling;
|
||||
extern float InflectionPointRaidHeroicBoss;
|
||||
|
||||
extern float InflectionPointRaid10M;
|
||||
extern float InflectionPointRaid10MCurveFloor;
|
||||
extern float InflectionPointRaid10MCurveCeiling;
|
||||
extern float InflectionPointRaid10MBoss;
|
||||
|
||||
extern float InflectionPointRaid10MHeroic;
|
||||
extern float InflectionPointRaid10MHeroicCurveFloor;
|
||||
extern float InflectionPointRaid10MHeroicCurveCeiling;
|
||||
extern float InflectionPointRaid10MHeroicBoss;
|
||||
|
||||
extern float InflectionPointRaid15M;
|
||||
extern float InflectionPointRaid15MCurveFloor;
|
||||
extern float InflectionPointRaid15MCurveCeiling;
|
||||
extern float InflectionPointRaid15MBoss;
|
||||
|
||||
extern float InflectionPointRaid20M;
|
||||
extern float InflectionPointRaid20MCurveFloor;
|
||||
extern float InflectionPointRaid20MCurveCeiling;
|
||||
extern float InflectionPointRaid20MBoss;
|
||||
|
||||
extern float InflectionPointRaid25M;
|
||||
extern float InflectionPointRaid25MCurveFloor;
|
||||
extern float InflectionPointRaid25MCurveCeiling;
|
||||
extern float InflectionPointRaid25MBoss;
|
||||
|
||||
extern float InflectionPointRaid25MHeroic;
|
||||
extern float InflectionPointRaid25MHeroicCurveFloor;
|
||||
extern float InflectionPointRaid25MHeroicCurveCeiling;
|
||||
extern float InflectionPointRaid25MHeroicBoss;
|
||||
|
||||
extern float InflectionPointRaid40M;
|
||||
extern float InflectionPointRaid40MCurveFloor;
|
||||
extern float InflectionPointRaid40MCurveCeiling;
|
||||
extern float InflectionPointRaid40MBoss;
|
||||
|
||||
//
|
||||
// StatModifier*
|
||||
//
|
||||
|
||||
extern float StatModifier_Global;
|
||||
extern float StatModifier_Health;
|
||||
extern float StatModifier_Mana;
|
||||
extern float StatModifier_Armor;
|
||||
extern float StatModifier_Damage;
|
||||
extern float StatModifier_CCDuration;
|
||||
|
||||
extern float StatModifierHeroic_Global;
|
||||
extern float StatModifierHeroic_Health;
|
||||
extern float StatModifierHeroic_Mana;
|
||||
extern float StatModifierHeroic_Armor;
|
||||
extern float StatModifierHeroic_Damage;
|
||||
extern float StatModifierHeroic_CCDuration;
|
||||
|
||||
extern float StatModifierRaid_Global;
|
||||
extern float StatModifierRaid_Health;
|
||||
extern float StatModifierRaid_Mana;
|
||||
extern float StatModifierRaid_Armor;
|
||||
extern float StatModifierRaid_Damage;
|
||||
extern float StatModifierRaid_CCDuration;
|
||||
|
||||
extern float StatModifierRaidHeroic_Global;
|
||||
extern float StatModifierRaidHeroic_Health;
|
||||
extern float StatModifierRaidHeroic_Mana;
|
||||
extern float StatModifierRaidHeroic_Armor;
|
||||
extern float StatModifierRaidHeroic_Damage;
|
||||
extern float StatModifierRaidHeroic_CCDuration;
|
||||
|
||||
extern float StatModifierRaid10M_Global;
|
||||
extern float StatModifierRaid10M_Health;
|
||||
extern float StatModifierRaid10M_Mana;
|
||||
extern float StatModifierRaid10M_Armor;
|
||||
extern float StatModifierRaid10M_Damage;
|
||||
extern float StatModifierRaid10M_CCDuration;
|
||||
|
||||
extern float StatModifierRaid10MHeroic_Global;
|
||||
extern float StatModifierRaid10MHeroic_Health;
|
||||
extern float StatModifierRaid10MHeroic_Mana;
|
||||
extern float StatModifierRaid10MHeroic_Armor;
|
||||
extern float StatModifierRaid10MHeroic_Damage;
|
||||
extern float StatModifierRaid10MHeroic_CCDuration;
|
||||
|
||||
extern float StatModifierRaid15M_Global;
|
||||
extern float StatModifierRaid15M_Health;
|
||||
extern float StatModifierRaid15M_Mana;
|
||||
extern float StatModifierRaid15M_Armor;
|
||||
extern float StatModifierRaid15M_Damage;
|
||||
extern float StatModifierRaid15M_CCDuration;
|
||||
|
||||
extern float StatModifierRaid20M_Global;
|
||||
extern float StatModifierRaid20M_Health;
|
||||
extern float StatModifierRaid20M_Mana;
|
||||
extern float StatModifierRaid20M_Armor;
|
||||
extern float StatModifierRaid20M_Damage;
|
||||
extern float StatModifierRaid20M_CCDuration;
|
||||
|
||||
extern float StatModifierRaid25M_Global;
|
||||
extern float StatModifierRaid25M_Health;
|
||||
extern float StatModifierRaid25M_Mana;
|
||||
extern float StatModifierRaid25M_Armor;
|
||||
extern float StatModifierRaid25M_Damage;
|
||||
extern float StatModifierRaid25M_CCDuration;
|
||||
|
||||
extern float StatModifierRaid25MHeroic_Global;
|
||||
extern float StatModifierRaid25MHeroic_Health;
|
||||
extern float StatModifierRaid25MHeroic_Mana;
|
||||
extern float StatModifierRaid25MHeroic_Armor;
|
||||
extern float StatModifierRaid25MHeroic_Damage;
|
||||
extern float StatModifierRaid25MHeroic_CCDuration;
|
||||
|
||||
extern float StatModifierRaid40M_Global;
|
||||
extern float StatModifierRaid40M_Health;
|
||||
extern float StatModifierRaid40M_Mana;
|
||||
extern float StatModifierRaid40M_Armor;
|
||||
extern float StatModifierRaid40M_Damage;
|
||||
extern float StatModifierRaid40M_CCDuration;
|
||||
|
||||
//
|
||||
// StatModifier* (Boss)
|
||||
//
|
||||
|
||||
extern float StatModifier_Boss_Global;
|
||||
extern float StatModifier_Boss_Health;
|
||||
extern float StatModifier_Boss_Mana;
|
||||
extern float StatModifier_Boss_Armor;
|
||||
extern float StatModifier_Boss_Damage;
|
||||
extern float StatModifier_Boss_CCDuration;
|
||||
|
||||
extern float StatModifierHeroic_Boss_Global;
|
||||
extern float StatModifierHeroic_Boss_Health;
|
||||
extern float StatModifierHeroic_Boss_Mana;
|
||||
extern float StatModifierHeroic_Boss_Armor;
|
||||
extern float StatModifierHeroic_Boss_Damage;
|
||||
extern float StatModifierHeroic_Boss_CCDuration;
|
||||
|
||||
extern float StatModifierRaid_Boss_Global;
|
||||
extern float StatModifierRaid_Boss_Health;
|
||||
extern float StatModifierRaid_Boss_Mana;
|
||||
extern float StatModifierRaid_Boss_Armor;
|
||||
extern float StatModifierRaid_Boss_Damage;
|
||||
extern float StatModifierRaid_Boss_CCDuration;
|
||||
|
||||
extern float StatModifierRaidHeroic_Boss_Global;
|
||||
extern float StatModifierRaidHeroic_Boss_Health;
|
||||
extern float StatModifierRaidHeroic_Boss_Mana;
|
||||
extern float StatModifierRaidHeroic_Boss_Armor;
|
||||
extern float StatModifierRaidHeroic_Boss_Damage;
|
||||
extern float StatModifierRaidHeroic_Boss_CCDuration;
|
||||
|
||||
extern float StatModifierRaid10M_Boss_Global;
|
||||
extern float StatModifierRaid10M_Boss_Health;
|
||||
extern float StatModifierRaid10M_Boss_Mana;
|
||||
extern float StatModifierRaid10M_Boss_Armor;
|
||||
extern float StatModifierRaid10M_Boss_Damage;
|
||||
extern float StatModifierRaid10M_Boss_CCDuration;
|
||||
|
||||
extern float StatModifierRaid10MHeroic_Boss_Global;
|
||||
extern float StatModifierRaid10MHeroic_Boss_Health;
|
||||
extern float StatModifierRaid10MHeroic_Boss_Mana;
|
||||
extern float StatModifierRaid10MHeroic_Boss_Armor;
|
||||
extern float StatModifierRaid10MHeroic_Boss_Damage;
|
||||
extern float StatModifierRaid10MHeroic_Boss_CCDuration;
|
||||
|
||||
extern float StatModifierRaid15M_Boss_Global;
|
||||
extern float StatModifierRaid15M_Boss_Health;
|
||||
extern float StatModifierRaid15M_Boss_Mana;
|
||||
extern float StatModifierRaid15M_Boss_Armor;
|
||||
extern float StatModifierRaid15M_Boss_Damage;
|
||||
extern float StatModifierRaid15M_Boss_CCDuration;
|
||||
|
||||
extern float StatModifierRaid40M_Boss_Damage;
|
||||
extern float StatModifierRaid20M_Boss_Global;
|
||||
extern float StatModifierRaid20M_Boss_Health;
|
||||
extern float StatModifierRaid20M_Boss_Mana;
|
||||
extern float StatModifierRaid20M_Boss_Armor;
|
||||
extern float StatModifierRaid20M_Boss_Damage;
|
||||
extern float StatModifierRaid20M_Boss_CCDuration;
|
||||
|
||||
extern float StatModifierRaid25M_Boss_Global;
|
||||
extern float StatModifierRaid25M_Boss_Health;
|
||||
extern float StatModifierRaid25M_Boss_Mana;
|
||||
extern float StatModifierRaid25M_Boss_Armor;
|
||||
extern float StatModifierRaid25M_Boss_Damage;
|
||||
extern float StatModifierRaid25M_Boss_CCDuration;
|
||||
|
||||
extern float StatModifierRaid25MHeroic_Boss_Global;
|
||||
extern float StatModifierRaid25MHeroic_Boss_Health;
|
||||
extern float StatModifierRaid25MHeroic_Boss_Mana;
|
||||
extern float StatModifierRaid25MHeroic_Boss_Armor;
|
||||
extern float StatModifierRaid25MHeroic_Boss_Damage;
|
||||
extern float StatModifierRaid25MHeroic_Boss_CCDuration;
|
||||
|
||||
extern float StatModifierRaid40M_Boss_Global;
|
||||
extern float StatModifierRaid40M_Boss_Health;
|
||||
extern float StatModifierRaid40M_Boss_Mana;
|
||||
extern float StatModifierRaid40M_Boss_Armor;
|
||||
extern float StatModifierRaid40M_Boss_CCDuration;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#ifndef __AB_CREATURE_INFO_H
|
||||
#define __AB_CREATURE_INFO_H
|
||||
|
||||
#include "AutoBalance.h"
|
||||
|
||||
#include "Creature.h"
|
||||
#include "DataMap.h"
|
||||
|
||||
class AutoBalanceCreatureInfo : public DataMap::Base
|
||||
{
|
||||
public:
|
||||
AutoBalanceCreatureInfo() {}
|
||||
|
||||
uint64_t mapConfigTime = 1; // The last map config time that this creature was updated
|
||||
|
||||
uint32 instancePlayerCount = 0; // The number of players this creature has been scaled for
|
||||
uint8 selectedLevel = 0; // The level that this creature should be set to
|
||||
|
||||
float DamageMultiplier = 1.0f; // Per-player damage multiplier (no level scaling)
|
||||
float ScaledDamageMultiplier = 1.0f; // Per-player and level scaling damage multiplier
|
||||
|
||||
float HealthMultiplier = 1.0f; // Per-player health multiplier (no level scaling)
|
||||
float ScaledHealthMultiplier = 1.0f; // Per-player and level scaling health multiplier
|
||||
|
||||
float ManaMultiplier = 1.0f; // Per-player mana multiplier (no level scaling)
|
||||
float ScaledManaMultiplier = 1.0f; // Per-player and level scaling mana multiplier
|
||||
|
||||
float ArmorMultiplier = 1.0f; // Per-player armor multiplier (no level scaling)
|
||||
float ScaledArmorMultiplier = 1.0f; // Per-player and level scaling armor multiplier
|
||||
|
||||
float CCDurationMultiplier = 1.0f; // Per-player crowd control duration multiplier (level scaling doesn't affect this)
|
||||
|
||||
float XPModifier = 1.0f; // Per-player XP modifier (level scaling provided by normal XP distribution)
|
||||
float MoneyModifier = 1.0f; // Per-player money modifier (no level scaling)
|
||||
|
||||
uint8 UnmodifiedLevel = 0; // Original level of the creature as determined by the game
|
||||
|
||||
bool isActive = false; // Whether or not the current creature is affecting map stats. May change as conditions change.
|
||||
bool wasAliveNowDead = false; // Whether or not the creature was alive and is now dead
|
||||
bool isInCreatureList = false; // Whether or not the creature is in the map's creature list
|
||||
bool isBrandNew = false; // Whether or not the creature is brand new to the map (hasn't been added to the world yet)
|
||||
bool neverLevelScale = false; // Whether or not the creature should never be level scaled (can still be player scaled)
|
||||
|
||||
uint32 initialMaxHealth = 0; // Stored max health value to be applied just before being added to the world
|
||||
|
||||
// creature->IsSummon() // Whether or not the creature is a summon
|
||||
Creature* summoner = nullptr; // The creature that summoned this creature
|
||||
std::string summonerName = ""; // The name of the creature that summoned this creature
|
||||
uint8 summonerLevel = 0; // The level of the creature that summoned this creature
|
||||
bool isCloneOfSummoner = false; // Whether or not the creature is a clone of its summoner
|
||||
|
||||
Relevance relevance = AUTOBALANCE_RELEVANCE_UNCHECKED; // Whether or not the creature is relevant for scaling
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,176 @@
|
||||
#include "ABGameObjectScript.h"
|
||||
|
||||
#include "ABConfig.h"
|
||||
#include "ABMapInfo.h"
|
||||
#include "ABUtils.h"
|
||||
|
||||
void AutoBalance_GameObjectScript::OnGameObjectModifyHealth(GameObject* target, Unit* source, int32& amount, SpellInfo const* spellInfo)
|
||||
{
|
||||
// uncomment to debug this hook
|
||||
bool _debug_damage_and_healing = (source && target && (source->GetTypeId() == TYPEID_PLAYER || source->IsControlledByPlayer()));
|
||||
|
||||
if (_debug_damage_and_healing)
|
||||
_Debug_Output("OnGameObjectModifyHealth", target, source, amount, "BEFORE:", spellInfo->SpellName[0], spellInfo->Id);
|
||||
|
||||
// modify the amount
|
||||
amount = _Modify_GameObject_Damage_Healing(target, source, amount, spellInfo);
|
||||
|
||||
if (_debug_damage_and_healing)
|
||||
_Debug_Output("OnGameObjectModifyHealth", target, source, amount, "AFTER:", spellInfo->SpellName[0], spellInfo->Id);
|
||||
}
|
||||
|
||||
void AutoBalance_GameObjectScript::_Debug_Output(std::string function_name, GameObject* target, Unit* source, int32 amount, std::string prefix, std::string spell_name, uint32 spell_id)
|
||||
{
|
||||
if (target && source && amount)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_GameObjectScript::{}: {} {} {} {} ({} - {})",
|
||||
function_name,
|
||||
prefix,
|
||||
source->GetName(),
|
||||
amount,
|
||||
target->GetName(),
|
||||
spell_name,
|
||||
spell_id
|
||||
);
|
||||
}
|
||||
else if (target && source)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_GameObjectScript::{}: {} {} 0 {} ({} - {})",
|
||||
function_name,
|
||||
prefix,
|
||||
source->GetName(),
|
||||
target->GetName(),
|
||||
spell_name,
|
||||
spell_id
|
||||
);
|
||||
}
|
||||
else if (target && amount)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_GameObjectScript::{}: {} ?? {} {} ({} - {})",
|
||||
function_name,
|
||||
prefix,
|
||||
amount,
|
||||
target->GetName(),
|
||||
spell_name,
|
||||
spell_id
|
||||
);
|
||||
}
|
||||
else if (target)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_GameObjectScript::{}: {} ?? ?? {} ({} - {})",
|
||||
function_name,
|
||||
prefix,
|
||||
target->GetName(),
|
||||
spell_name,
|
||||
spell_id
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_GameObjectScript::{}: {} W? T? F? ({} - {})",
|
||||
function_name,
|
||||
prefix,
|
||||
spell_name,
|
||||
spell_id
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
int32 AutoBalance_GameObjectScript::_Modify_GameObject_Damage_Healing(GameObject* target, Unit* source, int32 amount, SpellInfo const* spellInfo)
|
||||
{
|
||||
//
|
||||
// Pre-flight Checks
|
||||
//
|
||||
|
||||
// uncomment to debug this function
|
||||
bool _debug_damage_and_healing = (source && target && (source->GetTypeId() == TYPEID_PLAYER || source->IsControlledByPlayer()));
|
||||
|
||||
// check that we're enabled globally, else return the original value
|
||||
if (!EnableGlobal)
|
||||
{
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_GameObjectScript::_Modify_GameObject_Damage_Healing: EnableGlobal is false, returning original value of ({}).", amount);
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
// make sure the target is in an instance, else return the original damage
|
||||
if (!(target->GetMap()->IsDungeon()))
|
||||
{
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_GameObjectScript::_Modify_GameObject_Damage_Healing: Target is not in an instance, returning original value of ({}).", amount);
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
// make sure the target is in the world, else return the original value
|
||||
if (!target->IsInWorld())
|
||||
{
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_GameObjectScript::_Modify_GameObject_Damage_Healing: Target does not exist in the world, returning original value of ({}).", amount);
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
// if the spell ID is in our "never modify" list, return the original value
|
||||
if
|
||||
(
|
||||
spellInfo &&
|
||||
spellInfo->Id &&
|
||||
std::find
|
||||
(
|
||||
spellIdsToNeverModify.begin(),
|
||||
spellIdsToNeverModify.end(),
|
||||
spellInfo->Id
|
||||
) != spellIdsToNeverModify.end()
|
||||
)
|
||||
{
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Spell {}({}) is in the never modify list, returning original value of ({}).",
|
||||
spellInfo->SpellName[0],
|
||||
spellInfo->Id,
|
||||
amount
|
||||
);
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
// get the map's info
|
||||
AutoBalanceMapInfo* targetMapABInfo = GetMapInfo(target->GetMap());
|
||||
|
||||
// if the target's map is not enabled, return the original damage
|
||||
if (!targetMapABInfo->enabled)
|
||||
{
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_GameObjectScript::_Modify_GameObject_Damage_Healing: Target's map is not enabled, returning original value of ({}).", amount);
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
//
|
||||
// Multiplier calculation
|
||||
//
|
||||
|
||||
// calculate the new damage amount using the map's World Health Multiplier
|
||||
int32 newAmount = _Calculate_Amount_For_GameObject(target, amount, targetMapABInfo->worldHealthMultiplier);
|
||||
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_GameObjectScript::_Modify_GameObject_Damage_Healing: Returning modified damage: ({}) -> ({})", amount, newAmount);
|
||||
|
||||
return newAmount;
|
||||
}
|
||||
|
||||
int32 AutoBalance_GameObjectScript::_Calculate_Amount_For_GameObject(GameObject* target, int32 amount, float multiplier)
|
||||
{
|
||||
// since it would be very complicated to reduce the real health of destructible game objects, instead we will
|
||||
// adjust the damage to them as though their health were scaled. Damage will usually be dealt by vehicles and
|
||||
// other non-player sources, so this effect shouldn't be as noticable as if we applied it to the player.
|
||||
uint32 realMaxHealth = target->GetGOValue()->Building.MaxHealth;
|
||||
|
||||
uint32 scaledMaxHealth = realMaxHealth * multiplier;
|
||||
float percentDamageOfScaledMaxHealth = (float)amount / (float)scaledMaxHealth;
|
||||
|
||||
uint32 scaledAmount = realMaxHealth * percentDamageOfScaledMaxHealth;
|
||||
|
||||
return scaledAmount;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#ifndef __AB_GAME_OBJECT_SCRIPT_H
|
||||
#define __AB_GAME_OBJECT_SCRIPT_H
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "Unit.h"
|
||||
|
||||
class AutoBalance_GameObjectScript : public AllGameObjectScript
|
||||
{
|
||||
public:
|
||||
AutoBalance_GameObjectScript()
|
||||
: AllGameObjectScript("AutoBalance_GameObjectScript")
|
||||
{}
|
||||
|
||||
void OnGameObjectModifyHealth(GameObject* target, Unit* source, int32& amount, SpellInfo const* spellInfo) override;
|
||||
|
||||
private:
|
||||
|
||||
[[maybe_unused]] bool _debug_damage_and_healing = false; // defaults to false, overwritten in each function
|
||||
|
||||
void _Debug_Output(std::string function_name, GameObject* target, Unit* source, int32 amount, std::string prefix = "", std::string spell_name = "Unknown Spell", uint32 spell_id = 0);
|
||||
int32 _Modify_GameObject_Damage_Healing(GameObject* target, Unit* source, int32 amount, SpellInfo const* spellInfo);
|
||||
int32 _Calculate_Amount_For_GameObject(GameObject* target, int32 amount, float multiplier);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "ABGlobalScript.h"
|
||||
|
||||
#include "ABConfig.h"
|
||||
#include "ABMapInfo.h"
|
||||
#include "ABUtils.h"
|
||||
|
||||
void AutoBalance_GlobalScript::OnAfterUpdateEncounterState(Map* map, EncounterCreditType type, uint32 /*creditEntry*/, Unit* /*source*/, Difficulty /*difficulty_fixed*/, DungeonEncounterList const* /*encounters*/, uint32 /*dungeonCompleted*/, bool updated)
|
||||
{
|
||||
//if (!dungeonCompleted)
|
||||
// return;
|
||||
|
||||
if (!rewardEnabled || !updated)
|
||||
return;
|
||||
|
||||
AutoBalanceMapInfo* mapABInfo = GetMapInfo(map);
|
||||
|
||||
if (mapABInfo->adjustedPlayerCount < MinPlayerReward)
|
||||
return;
|
||||
|
||||
// skip if it's not a pre-wotlk dungeon/raid and if it's not scaled
|
||||
if (!LevelScaling || mapABInfo->mapLevel <= 70 || mapABInfo->lfgMinLevel <= 70
|
||||
// skip when not in dungeon or not kill credit
|
||||
|| type != ENCOUNTER_CREDIT_KILL_CREATURE || !map->IsDungeon())
|
||||
return;
|
||||
|
||||
Map::PlayerList const& playerList = map->GetPlayers();
|
||||
|
||||
if (playerList.IsEmpty())
|
||||
return;
|
||||
|
||||
uint32 reward = map->ToInstanceMap()->GetMaxPlayers() > 5 ? rewardRaid : rewardDungeon;
|
||||
if (!reward)
|
||||
return;
|
||||
|
||||
//instanceStart=0, endTime;
|
||||
uint8 difficulty = map->GetDifficulty();
|
||||
|
||||
for (Map::PlayerList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr)
|
||||
{
|
||||
if (!itr->GetSource() || itr->GetSource()->IsGameMaster() || itr->GetSource()->GetLevel() < DEFAULT_MAX_LEVEL)
|
||||
continue;
|
||||
|
||||
itr->GetSource()->AddItem(reward, 1 + difficulty); // difficulty boost
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#ifndef __AB_GLOBAL_SCRIPT_H
|
||||
#define __AB_GLOBAL_SCRIPT_H
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
|
||||
class AutoBalance_GlobalScript : public GlobalScript {
|
||||
public:
|
||||
AutoBalance_GlobalScript() : GlobalScript("AutoBalance_GlobalScript", {
|
||||
GLOBALHOOK_ON_AFTER_UPDATE_ENCOUNTER_STATE
|
||||
}) { }
|
||||
|
||||
void OnAfterUpdateEncounterState(Map* map, EncounterCreditType type, uint32 creditEntry, Unit* source, Difficulty difficulty_fixed, DungeonEncounterList const* encounters, uint32 dungeonCompleted, bool updated) override;
|
||||
};
|
||||
|
||||
#endif /* __AB_GLOBAL_SCRIPT_H */
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#ifndef __AB_INFLECTION_POINT_SETTINGS_H
|
||||
#define __AB_INFLECTION_POINT_SETTINGS_H
|
||||
|
||||
#include "DataMap.h"
|
||||
|
||||
class AutoBalanceInflectionPointSettings : public DataMap::Base
|
||||
{
|
||||
public:
|
||||
AutoBalanceInflectionPointSettings() {}
|
||||
AutoBalanceInflectionPointSettings(float value, float curveFloor, float curveCeiling) :
|
||||
value(value), curveFloor(curveFloor), curveCeiling(curveCeiling) {}
|
||||
|
||||
float value = 0.5;
|
||||
float curveFloor = 0.0;
|
||||
float curveCeiling = 1.0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#ifndef __AB_LEVEL_SCALING_DYNAMIC_LEVEL_SETTINGS_H
|
||||
#define __AB_LEVEL_SCALING_DYNAMIC_LEVEL_SETTINGS_H
|
||||
|
||||
#include "DataMap.h"
|
||||
|
||||
class AutoBalanceLevelScalingDynamicLevelSettings : public DataMap::Base
|
||||
{
|
||||
public:
|
||||
AutoBalanceLevelScalingDynamicLevelSettings() {}
|
||||
AutoBalanceLevelScalingDynamicLevelSettings(int skipHigher, int skipLower, int ceiling, int floor) :
|
||||
skipHigher(skipHigher), skipLower(skipLower), ceiling(ceiling), floor(floor) {}
|
||||
|
||||
int skipHigher = 0;
|
||||
int skipLower = 0;
|
||||
int ceiling = 1;
|
||||
int floor = 1;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#ifndef __AB_MAP_INFO_H
|
||||
#define __AB_MAP_INFO_H
|
||||
|
||||
#include "Creature.h"
|
||||
#include "DataMap.h"
|
||||
#include "Player.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class AutoBalanceMapInfo : public DataMap::Base
|
||||
{
|
||||
public:
|
||||
AutoBalanceMapInfo() {}
|
||||
|
||||
std::vector<Creature*> allMapCreatures; // All creatures in the map, active and non-active
|
||||
std::vector<Player*> allMapPlayers; // All players that are currently in the map
|
||||
|
||||
bool enabled = false; // Should AutoBalance make any changes to this map or its creatures?
|
||||
|
||||
uint64_t globalConfigTime = 1; // The last global config time that this map was updated
|
||||
uint64_t mapConfigTime = 1; // The last map config time that this map was updated
|
||||
|
||||
uint8 playerCount = 0; // The actual number of non-GM players in the map
|
||||
uint8 adjustedPlayerCount = 0; // The currently difficulty level expressed as number of players
|
||||
uint8 minPlayers = 1; // Will be set by the config
|
||||
|
||||
uint8 mapLevel = 0; // Calculated from the avgCreatureLevel
|
||||
uint8 lowestPlayerLevel = 0; // The lowest-level player in the map
|
||||
uint8 highestPlayerLevel = 0; // The highest-level player in the map
|
||||
|
||||
uint8 lfgMinLevel = 0; // The minimum level for the map according to LFG
|
||||
uint8 lfgTargetLevel = 0; // The target level for the map according to LFG
|
||||
uint8 lfgMaxLevel = 0; // The maximum level for the map according to LFG
|
||||
|
||||
uint8 worldMultiplierTargetLevel = 0; // The level of the pseudo-creature that the world modifiers scale to
|
||||
float worldDamageHealingMultiplier = 1.0f; // The damage/healing multiplier for the world (where source isn't an enemy creature)
|
||||
float scaledWorldDamageHealingMultiplier = 1.0f; // The damage/healing multiplier for the world (where source isn't an enemy creature)
|
||||
float worldHealthMultiplier = 1.0f; // The "health" multiplier for any destructible buildings in the map
|
||||
|
||||
bool combatLocked = false; // Whether or not the map is combat locked
|
||||
bool combatLockTripped = false; // Set to true when combat locking was needed during this current combat (some tried to leave)
|
||||
uint8 combatLockMinPlayers = 0; // The instance cannot be set to less than this number of players until combat ends
|
||||
|
||||
uint8 highestCreatureLevel = 0; // The highest-level creature in the map
|
||||
uint8 lowestCreatureLevel = 0; // The lowest-level creature in the map
|
||||
float avgCreatureLevel = 0; // The average level of all active creatures in the map (continuously updated)
|
||||
uint32 activeCreatureCount = 0; // The number of creatures in the map that are included in the map's stats (not necessarily alive)
|
||||
|
||||
bool isLevelScalingEnabled = false; // Whether level scaling is enabled on this map
|
||||
uint8 levelScalingSkipHigherLevels = 0; // Used to determine if this map should scale or not
|
||||
uint8 levelScalingSkipLowerLevels = 0; // Used to determine if this map should scale or not
|
||||
uint8 levelScalingDynamicCeiling = 0; // How many levels MORE than the highestPlayerLevel creature should be scaled to
|
||||
uint8 levelScalingDynamicFloor = 0; // How many levels LESS than the highestPlayerLevel creature should be scaled to
|
||||
|
||||
uint8 prevMapLevel = 0; // Used to reduce calculations when they are not necessary
|
||||
bool initialized = false; // Whether or not the map has been initialized
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#include "ABModuleScript.h"
|
||||
|
||||
ABModuleScript::ABModuleScript(const char* name)
|
||||
: ModuleScript(name)
|
||||
{
|
||||
ScriptRegistry<ABModuleScript>::AddScript(this);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#ifndef __AB_MODULE_SCRIPT_H
|
||||
#define __AB_MODULE_SCRIPT_H
|
||||
|
||||
#include "Creature.h"
|
||||
#include "ScriptMgr.h"
|
||||
|
||||
/*
|
||||
* Dedicated hooks for Autobalance Module
|
||||
* Can be used to extend/customize this system
|
||||
*/
|
||||
class ABModuleScript : public ModuleScript
|
||||
{
|
||||
protected:
|
||||
|
||||
ABModuleScript(const char* name);
|
||||
|
||||
public:
|
||||
virtual bool OnBeforeModifyAttributes(Creature* /*creature*/, uint32& /*instancePlayerCount*/) { return true; }
|
||||
virtual bool OnAfterDefaultMultiplier(Creature* /*creature*/, float& /*defaultMultiplier*/) { return true; }
|
||||
virtual bool OnBeforeUpdateStats (Creature* /*creature*/, uint32& /*scaledHealth*/, uint32& /*scaledMana*/, float& /*damageMultiplier*/, uint32& /*newBaseArmor*/) { return true; }
|
||||
};
|
||||
|
||||
template class ScriptRegistry<ABModuleScript>;
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,242 @@
|
||||
#include <string>
|
||||
|
||||
#include "ABConfig.h"
|
||||
#include "ABCreatureInfo.h"
|
||||
#include "ABMapInfo.h"
|
||||
#include "ABPlayerScript.h"
|
||||
#include "ABUtils.h"
|
||||
|
||||
#include "Chat.h"
|
||||
#include "Message.h"
|
||||
|
||||
void AutoBalance_PlayerScript::OnPlayerLogin(Player* Player)
|
||||
{
|
||||
if (EnableGlobal && Announcement)
|
||||
ChatHandler(Player->GetSession()).SendSysMessage("This server is running the |cff4CFF00AutoBalance |rmodule.");
|
||||
}
|
||||
|
||||
void AutoBalance_PlayerScript::OnPlayerLevelChanged(Player* player, uint8 oldlevel)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance", "AutoBalance:: ------------------------------------------------");
|
||||
|
||||
LOG_DEBUG("module.AutoBalance", "AutoBalance_PlayerScript::OnLevelChanged: {} has leveled ({}->{})", player->GetName(), oldlevel, player->GetLevel());
|
||||
if (!player || player->IsGameMaster())
|
||||
return;
|
||||
|
||||
Map* map = player->GetMap();
|
||||
|
||||
if (!map || !map->IsDungeon())
|
||||
return;
|
||||
|
||||
// update the map's player stats
|
||||
UpdateMapPlayerStats(map);
|
||||
|
||||
// schedule all creatures for an update
|
||||
AutoBalanceMapInfo* mapABInfo = GetMapInfo(map);
|
||||
mapABInfo->mapConfigTime = GetCurrentConfigTime();
|
||||
}
|
||||
|
||||
void AutoBalance_PlayerScript::OnPlayerGiveXP(Player* player, uint32& amount, Unit* victim, uint8 /*xpSource*/)
|
||||
{
|
||||
Map* map = player->GetMap();
|
||||
|
||||
// If this isn't a dungeon, make no changes
|
||||
if (!map->IsDungeon() || !map->GetInstanceId() || !victim)
|
||||
return;
|
||||
|
||||
AutoBalanceMapInfo* mapABInfo = GetMapInfo(map);
|
||||
|
||||
if (victim && RewardScalingXP && mapABInfo->enabled)
|
||||
{
|
||||
Map* map = player->GetMap();
|
||||
|
||||
AutoBalanceCreatureInfo* creatureABInfo = victim->CustomData.GetDefault<AutoBalanceCreatureInfo>("AutoBalanceCreatureInfo");
|
||||
|
||||
if (map->IsDungeon())
|
||||
{
|
||||
if (RewardScalingMethod == AUTOBALANCE_SCALING_DYNAMIC)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance", "AutoBalance_PlayerScript::OnGiveXP: Distributing XP from '{}' to '{}' in dynamic mode - {}->{}",
|
||||
victim->GetName(), player->GetName(), amount, uint32(amount * creatureABInfo->XPModifier));
|
||||
amount = uint32(amount * creatureABInfo->XPModifier);
|
||||
}
|
||||
else if (RewardScalingMethod == AUTOBALANCE_SCALING_FIXED)
|
||||
{
|
||||
// Ensure that the players always get the same XP, even when entering the dungeon alone
|
||||
auto maxPlayerCount = map->ToInstanceMap()->GetMaxPlayers();
|
||||
auto currentPlayerCount = mapABInfo->playerCount;
|
||||
LOG_DEBUG("module.AutoBalance", "AutoBalance_PlayerScript::OnGiveXP: Distributing XP from '{}' to '{}' in fixed mode - {}->{}",
|
||||
victim->GetName(), player->GetName(), amount, uint32(amount * creatureABInfo->XPModifier * ((float)currentPlayerCount / maxPlayerCount)));
|
||||
amount = uint32(amount * creatureABInfo->XPModifier * ((float)currentPlayerCount / maxPlayerCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AutoBalance_PlayerScript::OnPlayerBeforeLootMoney(Player* player, Loot* loot)
|
||||
{
|
||||
Map* map = player->GetMap();
|
||||
|
||||
// If this isn't a dungeon, make no changes
|
||||
if (!map->IsDungeon())
|
||||
return;
|
||||
|
||||
AutoBalanceMapInfo* mapABInfo = GetMapInfo(map);
|
||||
ObjectGuid sourceGuid = loot->sourceWorldObjectGUID;
|
||||
|
||||
if (mapABInfo->enabled && RewardScalingMoney)
|
||||
{
|
||||
// if the loot source is a creature, honor the modifiers for that creature
|
||||
if (sourceGuid.IsCreature())
|
||||
{
|
||||
Creature* sourceCreature = ObjectAccessor::GetCreature(*player, sourceGuid);
|
||||
AutoBalanceCreatureInfo* creatureABInfo = sourceCreature->CustomData.GetDefault<AutoBalanceCreatureInfo>("AutoBalanceCreatureInfo");
|
||||
|
||||
// Dynamic Mode
|
||||
if (RewardScalingMethod == AUTOBALANCE_SCALING_DYNAMIC)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance", "AutoBalance_PlayerScript::OnBeforeLootMoney: Distributing money from '{}' in dynamic mode - {}->{}",
|
||||
sourceCreature->GetName(), loot->gold, uint32(loot->gold * creatureABInfo->MoneyModifier));
|
||||
loot->gold = uint32(loot->gold * creatureABInfo->MoneyModifier);
|
||||
}
|
||||
// Fixed Mode
|
||||
else if (RewardScalingMethod == AUTOBALANCE_SCALING_FIXED)
|
||||
{
|
||||
// Ensure that the players always get the same money, even when entering the dungeon alone
|
||||
auto maxPlayerCount = map->ToInstanceMap()->GetMaxPlayers();
|
||||
auto currentPlayerCount = mapABInfo->playerCount;
|
||||
LOG_DEBUG("module.AutoBalance", "AutoBalance_PlayerScript::OnBeforeLootMoney: Distributing money from '{}' in fixed mode - {}->{}",
|
||||
sourceCreature->GetName(), loot->gold, uint32(loot->gold * creatureABInfo->MoneyModifier * ((float)currentPlayerCount / maxPlayerCount)));
|
||||
loot->gold = uint32(loot->gold * creatureABInfo->MoneyModifier * ((float)currentPlayerCount / maxPlayerCount));
|
||||
}
|
||||
}
|
||||
// for all other loot sources, just distribute in Fixed mode as though the instance was full
|
||||
else
|
||||
{
|
||||
auto maxPlayerCount = map->ToInstanceMap()->GetMaxPlayers();
|
||||
auto currentPlayerCount = mapABInfo->playerCount;
|
||||
LOG_DEBUG("module.AutoBalance", "AutoBalance_PlayerScript::OnBeforeLootMoney: Distributing money from a non-creature in fixed mode - {}->{}",
|
||||
loot->gold, uint32(loot->gold * ((float)currentPlayerCount / maxPlayerCount)));
|
||||
loot->gold = uint32(loot->gold * ((float)currentPlayerCount / maxPlayerCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AutoBalance_PlayerScript::OnPlayerEnterCombat(Player* player, Unit* /*enemy*/)
|
||||
{
|
||||
// if the player or their map is gone, return
|
||||
if (!player || !player->GetMap())
|
||||
return;
|
||||
|
||||
Map* map = player->GetMap();
|
||||
|
||||
// If this isn't a dungeon, no work to do
|
||||
if (!map || !map->IsDungeon())
|
||||
return;
|
||||
|
||||
LOG_DEBUG("module.AutoBalance_CombatLocking", "AutoBalance_PlayerScript::OnPlayerEnterCombat: {} enters combat.", player->GetName());
|
||||
|
||||
AutoBalanceMapInfo* mapABInfo = GetMapInfo(map);
|
||||
|
||||
// if this map isn't enabled, no work to do
|
||||
if (!mapABInfo->enabled)
|
||||
return;
|
||||
|
||||
// lock the current map
|
||||
if (!mapABInfo->combatLocked)
|
||||
{
|
||||
mapABInfo->combatLocked = true;
|
||||
mapABInfo->combatLockMinPlayers = mapABInfo->playerCount;
|
||||
|
||||
LOG_DEBUG("module.AutoBalance_CombatLocking", "AutoBalance_PlayerScript::OnPlayerEnterCombat: Map {} ({}{}) | Locking difficulty to no less than ({}) as {} enters combat.",
|
||||
map->GetMapName(),
|
||||
map->GetId(),
|
||||
map->GetInstanceId() ? "-" + std::to_string(map->GetInstanceId()) : "",
|
||||
mapABInfo->combatLockMinPlayers,
|
||||
player->GetName()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void AutoBalance_PlayerScript::OnPlayerLeaveCombat(Player* player)
|
||||
{
|
||||
// if the player or their map is gone, return
|
||||
if (!player || !player->GetMap())
|
||||
return;
|
||||
|
||||
Map* map = player->GetMap();
|
||||
|
||||
// If this isn't a dungeon, no work to do
|
||||
if (!map || !map->IsDungeon())
|
||||
return;
|
||||
|
||||
// this hook can get called even if the player isn't in combat
|
||||
// I believe this happens whenever AC attempts to remove combat, but it doesn't check to see if the player is in combat first
|
||||
// unfortunately, `player->IsInCombat()` doesn't work here
|
||||
LOG_DEBUG("module.AutoBalance_CombatLocking", "AutoBalance_PlayerScript::OnPlayerLeaveCombat: {} leaves (or wasn't in) combat.", player->GetName());
|
||||
|
||||
AutoBalanceMapInfo* mapABInfo = GetMapInfo(map);
|
||||
|
||||
// if this map isn't enabled, no work to do
|
||||
if (!mapABInfo->enabled)
|
||||
return;
|
||||
|
||||
// check to see if any of the other players are in combat
|
||||
bool anyPlayersInCombat = false;
|
||||
for (auto player : mapABInfo->allMapPlayers)
|
||||
{
|
||||
if (player && player->IsInCombat())
|
||||
{
|
||||
anyPlayersInCombat = true;
|
||||
|
||||
LOG_DEBUG("module.AutoBalance_CombatLocking", "AutoBalance_PlayerScript::OnPlayerLeaveCombat: Map {} ({}{}) | Player {} (and potentially others) are still in combat.",
|
||||
map->GetMapName(),
|
||||
map->GetId(),
|
||||
map->GetInstanceId() ? "-" + std::to_string(map->GetInstanceId()) : "",
|
||||
player->GetName()
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto locale = player->GetSession()->GetSessionDbLocaleIndex();
|
||||
|
||||
// if no players are in combat, unlock the map
|
||||
if (!anyPlayersInCombat && mapABInfo->combatLocked)
|
||||
{
|
||||
mapABInfo->combatLocked = false;
|
||||
mapABInfo->combatLockMinPlayers = 0;
|
||||
|
||||
LOG_DEBUG("module.AutoBalance_CombatLocking", "AutoBalance_PlayerScript::OnPlayerLeaveCombat: Map {} ({}{}) | Unlocking difficulty as {} leaves combat.",
|
||||
map->GetMapName(),
|
||||
map->GetId(),
|
||||
map->GetInstanceId() ? "-" + std::to_string(map->GetInstanceId()) : "",
|
||||
player->GetName()
|
||||
);
|
||||
|
||||
// if the combat lock needed to be used, notify the players of it lifting
|
||||
if (mapABInfo->combatLockTripped)
|
||||
{
|
||||
for (auto player : mapABInfo->allMapPlayers)
|
||||
{
|
||||
if (player && player->GetSession())
|
||||
ChatHandler(player->GetSession()).PSendSysMessage(ABGetLocaleText(locale, "leaving_instance_combat_change").c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// if the number of players changed while combat was in progress, schedule the map for an update
|
||||
if (mapABInfo->combatLockTripped && mapABInfo->playerCount != mapABInfo->combatLockMinPlayers)
|
||||
{
|
||||
mapABInfo->mapConfigTime = 1;
|
||||
LOG_DEBUG("module.AutoBalance_CombatLocking", "AutoBalance_PlayerScript::OnPlayerLeaveCombat: Map {} ({}{}) | Reset map config time to ({}).",
|
||||
map->GetMapName(),
|
||||
map->GetId(),
|
||||
map->GetInstanceId() ? "-" + std::to_string(map->GetInstanceId()) : "",
|
||||
mapABInfo->mapConfigTime
|
||||
);
|
||||
|
||||
mapABInfo->combatLockTripped = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#ifndef __AB_PLAYER_SCRIPT_H
|
||||
#define __AB_PLAYER_SCRIPT_H
|
||||
|
||||
#include "Player.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "Unit.h"
|
||||
|
||||
class AutoBalance_PlayerScript : public PlayerScript
|
||||
{
|
||||
public:
|
||||
AutoBalance_PlayerScript()
|
||||
: PlayerScript("AutoBalance_PlayerScript")
|
||||
{
|
||||
}
|
||||
|
||||
void OnPlayerLogin(Player* Player) override;
|
||||
virtual void OnPlayerLevelChanged(Player* player, uint8 oldlevel) override;
|
||||
void OnPlayerGiveXP(Player* player, uint32& amount, Unit* victim, uint8 xpSource) override;
|
||||
void OnPlayerBeforeLootMoney(Player* player, Loot* loot) override;
|
||||
virtual void OnPlayerEnterCombat(Player* player, Unit* enemy) override;
|
||||
virtual void OnPlayerLeaveCombat(Player* player) override;
|
||||
};
|
||||
|
||||
#endif /* __AB_PLAYER_SCRIPT_H */
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#include "ABModuleScript.h"
|
||||
#include "ABScriptMgr.h"
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptMgrMacros.h"
|
||||
|
||||
ABScriptMgr* ABScriptMgr::instance()
|
||||
{
|
||||
static ABScriptMgr instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
bool ABScriptMgr::OnBeforeModifyAttributes(Creature* creature, uint32& instancePlayerCount)
|
||||
{
|
||||
auto ret = IsValidBoolScript<ABModuleScript>([&](ABModuleScript* script)
|
||||
{
|
||||
return !script->OnBeforeModifyAttributes(creature, instancePlayerCount);
|
||||
});
|
||||
|
||||
if (ret && *ret)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ABScriptMgr::OnAfterDefaultMultiplier(Creature* creature, float& defaultMultiplier)
|
||||
{
|
||||
auto ret = IsValidBoolScript<ABModuleScript>([&](ABModuleScript* script)
|
||||
{
|
||||
return !script->OnAfterDefaultMultiplier(creature, defaultMultiplier);
|
||||
});
|
||||
|
||||
if (ret && *ret)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ABScriptMgr::OnBeforeUpdateStats(Creature* creature, uint32& scaledHealth, uint32& scaledMana, float& damageMultiplier, uint32& newBaseArmor)
|
||||
{
|
||||
auto ret = IsValidBoolScript<ABModuleScript>([&](ABModuleScript* script)
|
||||
{
|
||||
return !script->OnBeforeUpdateStats(creature, scaledHealth, scaledMana, damageMultiplier, newBaseArmor);
|
||||
});
|
||||
|
||||
if (ret && *ret)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#ifndef __AB_SCRIPT_MGR_H
|
||||
#define __AB_SCRIPT_MGR_H
|
||||
|
||||
#include "Creature.h"
|
||||
#include "ScriptMgr.h"
|
||||
|
||||
// Manages registration, loading, and execution of scripts.
|
||||
class ABScriptMgr
|
||||
{
|
||||
public: /* Initialization */
|
||||
|
||||
static ABScriptMgr* instance();
|
||||
|
||||
// Called at the start of ModifyCreatureAttributes method.
|
||||
// It can be used to add some condition to skip autobalancing system for example.
|
||||
bool OnBeforeModifyAttributes(Creature* creature, uint32 & instancePlayerCount);
|
||||
|
||||
// Called right after default multiplier has been set, you can use it to change.
|
||||
// Current scaling formula based on number of players or just skip modifications
|
||||
bool OnAfterDefaultMultiplier(Creature* creature, float &defaultMultiplier);
|
||||
|
||||
// Called before change creature values, to tune some values or skip modifications.
|
||||
bool OnBeforeUpdateStats (Creature* creature, uint32 &scaledHealth, uint32 &scaledMana, float &damageMultiplier, uint32 &newBaseArmor);
|
||||
};
|
||||
|
||||
#define sABScriptMgr ABScriptMgr::instance()
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#ifndef __AB_MODULE_STAT_MODIFIERS_H
|
||||
#define __AB_MODULE_STAT_MODIFIERS_H
|
||||
|
||||
#include "DataMap.h"
|
||||
|
||||
class AutoBalanceStatModifiers : public DataMap::Base
|
||||
{
|
||||
public:
|
||||
AutoBalanceStatModifiers() {}
|
||||
AutoBalanceStatModifiers(float global, float health, float mana, float armor, float damage, float ccduration) :
|
||||
global(global), health(health), mana(mana), armor(armor), damage(damage), ccduration(ccduration) {}
|
||||
|
||||
float global = 1.0;
|
||||
float health = 1.0;
|
||||
float mana = 1.0;
|
||||
float armor = 1.0;
|
||||
float damage = 1.0;
|
||||
float ccduration = 1.0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,557 @@
|
||||
#include "ABUnitScript.h"
|
||||
|
||||
#include "ABConfig.h"
|
||||
#include "ABCreatureInfo.h"
|
||||
#include "ABMapInfo.h"
|
||||
#include "ABUtils.h"
|
||||
|
||||
void AutoBalance_UnitScript::ModifyPeriodicDamageAurasTick(Unit* target, Unit* source, uint32& amount, SpellInfo const* spellInfo)
|
||||
{
|
||||
// if the spell is negative (damage), we need to flip the sign
|
||||
// if the spell is positive (healing or other) we keep it the same
|
||||
int32 adjustedAmount = !spellInfo->IsPositive() ? amount * -1 : amount;
|
||||
|
||||
// only debug if the source or target is a player
|
||||
bool _debug_damage_and_healing = ((source && (source->GetTypeId() == TYPEID_PLAYER || source->IsControlledByPlayer())) || (target && target->GetTypeId() == TYPEID_PLAYER));
|
||||
_debug_damage_and_healing = (source && source->GetMap()->GetInstanceId());
|
||||
|
||||
if (_debug_damage_and_healing)
|
||||
_Debug_Output("ModifyPeriodicDamageAurasTick", target, source, adjustedAmount, AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_BEFORE, spellInfo->SpellName[0], spellInfo->Id);
|
||||
|
||||
// set amount to the absolute value of the function call
|
||||
// the provided amount doesn't indicate whether it's a positive or negative value
|
||||
adjustedAmount = _Modify_Damage_Healing(target, source, adjustedAmount, spellInfo);
|
||||
amount = abs(adjustedAmount);
|
||||
|
||||
if (_debug_damage_and_healing)
|
||||
_Debug_Output("ModifyPeriodicDamageAurasTick", target, source, adjustedAmount, AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_AFTER, spellInfo->SpellName[0], spellInfo->Id);
|
||||
}
|
||||
|
||||
void AutoBalance_UnitScript::ModifySpellDamageTaken(Unit* target, Unit* source, int32& amount, SpellInfo const* spellInfo)
|
||||
{
|
||||
// if the spell is negative (damage), we need to flip the sign to negative
|
||||
// if the spell is positive (healing or other) we keep it the same (positive)
|
||||
int32 adjustedAmount = !spellInfo->IsPositive() ? amount * -1 : amount;
|
||||
|
||||
// only debug if the source or target is a player
|
||||
bool _debug_damage_and_healing = ((source && (source->GetTypeId() == TYPEID_PLAYER || source->IsControlledByPlayer())) || (target && target->GetTypeId() == TYPEID_PLAYER));
|
||||
_debug_damage_and_healing = (source && source->GetMap()->GetInstanceId());
|
||||
|
||||
if (_debug_damage_and_healing)
|
||||
_Debug_Output("ModifySpellDamageTaken", target, source, adjustedAmount, AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_BEFORE, spellInfo->SpellName[0], spellInfo->Id);
|
||||
|
||||
// set amount to the absolute value of the function call
|
||||
// the provided amount doesn't indicate whether it's a positive or negative value
|
||||
adjustedAmount = _Modify_Damage_Healing(target, source, adjustedAmount, spellInfo);
|
||||
amount = abs(adjustedAmount);
|
||||
|
||||
if (_debug_damage_and_healing)
|
||||
_Debug_Output("ModifySpellDamageTaken", target, source, adjustedAmount, AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_AFTER, spellInfo->SpellName[0], spellInfo->Id);
|
||||
}
|
||||
|
||||
void AutoBalance_UnitScript::ModifyMeleeDamage(Unit* target, Unit* source, uint32& amount)
|
||||
{
|
||||
// melee damage is always negative, so we need to flip the sign to negative
|
||||
int32 adjustedAmount = amount * -1;
|
||||
|
||||
// only debug if the source or target is a player
|
||||
bool _debug_damage_and_healing = ((source && (source->GetTypeId() == TYPEID_PLAYER || source->IsControlledByPlayer())) || (target && target->GetTypeId() == TYPEID_PLAYER));
|
||||
_debug_damage_and_healing = (source && source->GetMap()->GetInstanceId());
|
||||
|
||||
if (_debug_damage_and_healing)
|
||||
_Debug_Output("ModifyMeleeDamage", target, source, adjustedAmount, AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_BEFORE, "Melee");
|
||||
|
||||
// set amount to the absolute value of the function call
|
||||
adjustedAmount = _Modify_Damage_Healing(target, source, adjustedAmount);
|
||||
amount = abs(adjustedAmount);
|
||||
|
||||
if (_debug_damage_and_healing)
|
||||
_Debug_Output("ModifyMeleeDamage", target, source, adjustedAmount, AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_AFTER, "Melee");
|
||||
}
|
||||
|
||||
void AutoBalance_UnitScript::ModifyHealReceived(Unit* target, Unit* source, uint32& amount, SpellInfo const* spellInfo)
|
||||
{
|
||||
// healing is always positive, no need for any sign flip
|
||||
|
||||
// only debug if the source or target is a player
|
||||
bool _debug_damage_and_healing = ((source && (source->GetTypeId() == TYPEID_PLAYER || source->IsControlledByPlayer())) || (target && target->GetTypeId() == TYPEID_PLAYER));
|
||||
_debug_damage_and_healing = (source && source->GetMap()->GetInstanceId());
|
||||
|
||||
if (_debug_damage_and_healing)
|
||||
_Debug_Output("ModifyHealReceived", target, source, amount, AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_BEFORE, spellInfo->SpellName[0], spellInfo->Id);
|
||||
|
||||
amount = _Modify_Damage_Healing(target, source, amount, spellInfo);
|
||||
|
||||
if (_debug_damage_and_healing)
|
||||
_Debug_Output("ModifyHealReceived", target, source, amount, AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_AFTER, spellInfo->SpellName[0], spellInfo->Id);
|
||||
}
|
||||
|
||||
void AutoBalance_UnitScript::OnAuraApply(Unit* unit, Aura* aura)
|
||||
{
|
||||
// only debug if the source or target is a player
|
||||
bool _debug_damage_and_healing = (unit && unit->GetTypeId() == TYPEID_PLAYER);
|
||||
_debug_damage_and_healing = (unit && unit->GetMap()->GetInstanceId());
|
||||
|
||||
// Only if this aura has a duration
|
||||
if (aura && (aura->GetDuration() > 0 || aura->GetMaxDuration() > 0))
|
||||
{
|
||||
uint32 auraDuration = _Modifier_CCDuration(unit, aura->GetCaster(), aura);
|
||||
|
||||
// only update if we decided to change it
|
||||
if (auraDuration != (float)aura->GetDuration())
|
||||
{
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::OnAuraApply(): Spell '{}' had it's duration adjusted ({}->{}).",
|
||||
aura->GetSpellInfo()->SpellName[0],
|
||||
aura->GetMaxDuration() / 1000,
|
||||
auraDuration / 1000
|
||||
);
|
||||
|
||||
aura->SetMaxDuration(auraDuration);
|
||||
aura->SetDuration(auraDuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AutoBalance_UnitScript::_Debug_Output(std::string function_name, Unit* target, Unit* source, int32 amount, Damage_Healing_Debug_Phase phase, std::string spell_name, uint32 spell_id)
|
||||
{
|
||||
if (phase == AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_BEFORE)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance:: ------------------------------------------------");
|
||||
}
|
||||
|
||||
if (target && source && amount)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::{}: {}: {}{} {} {}{} with {}{} for ({})",
|
||||
function_name,
|
||||
phase ? "AFTER" : "BEFORE",
|
||||
source->GetName(),
|
||||
source->GetEntry() ? " (" + std::to_string(source->GetEntry()) + ")" : "",
|
||||
amount > 0 ? "heals" : "damages",
|
||||
target->GetName(),
|
||||
target->GetEntry() ? " (" + std::to_string(target->GetEntry()) + ")" : "",
|
||||
spell_name,
|
||||
spell_id ? " (" + std::to_string(spell_id) + ")" : "",
|
||||
amount
|
||||
);
|
||||
}
|
||||
else if (target && source)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::{}: {}: {}{} damages {}{} with {}{} for (0)",
|
||||
function_name,
|
||||
phase ? "AFTER" : "BEFORE",
|
||||
source->GetName(),
|
||||
source->GetEntry() ? " (" + std::to_string(source->GetEntry()) + ")" : "",
|
||||
target->GetName(),
|
||||
target->GetEntry() ? " (" + std::to_string(target->GetEntry()) + ")" : "",
|
||||
spell_name,
|
||||
spell_id ? " (" + std::to_string(spell_id) + ")" : ""
|
||||
);
|
||||
}
|
||||
else if (target && amount)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::{}: {}: ?? {} {}{} with {}{} for ({})",
|
||||
function_name,
|
||||
phase ? "AFTER" : "BEFORE",
|
||||
amount > 0 ? "heals" : "damages",
|
||||
target->GetName(),
|
||||
target->GetEntry() ? " (" + std::to_string(target->GetEntry()) + ")" : "",
|
||||
spell_name,
|
||||
spell_id ? " (" + std::to_string(spell_id) + ")" : "",
|
||||
amount
|
||||
);
|
||||
}
|
||||
else if (target)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::{}: {}: ?? affects {}{} with {}{}",
|
||||
function_name,
|
||||
phase ? "AFTER" : "BEFORE",
|
||||
target->GetName(),
|
||||
target->GetEntry() ? " (" + std::to_string(target->GetEntry()) + ")" : "",
|
||||
spell_name,
|
||||
spell_id ? " (" + std::to_string(spell_id) + ")" : ""
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::{}: {}: W? T? F? with {}{}",
|
||||
function_name,
|
||||
phase ? "AFTER" : "BEFORE",
|
||||
spell_name,
|
||||
spell_id ? " (" + std::to_string(spell_id) + ")" : ""
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
int32 AutoBalance_UnitScript::_Modify_Damage_Healing(Unit* target, Unit* source, int32 amount, SpellInfo const* spellInfo)
|
||||
{
|
||||
//
|
||||
// Pre-flight Checks
|
||||
//
|
||||
|
||||
// only debug if the source or target is a player
|
||||
bool _debug_damage_and_healing = ((source && (source->GetTypeId() == TYPEID_PLAYER || source->IsControlledByPlayer())) || (target && target->GetTypeId() == TYPEID_PLAYER));
|
||||
_debug_damage_and_healing = (source && source->GetMap()->GetInstanceId());
|
||||
|
||||
// check that we're enabled globally, else return the original value
|
||||
if (!EnableGlobal)
|
||||
{
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: EnableGlobal is false, returning original value of ({}).", amount);
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
// if the source is gone (logged off? despawned?), use the same target and source.
|
||||
// hacky, but better than crashing or having the damage go to 1.0x
|
||||
if (!source)
|
||||
{
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source is null, using target as source.");
|
||||
|
||||
source = target;
|
||||
}
|
||||
|
||||
// make sure the source and target are in an instance, else return the original damage
|
||||
if (!(source->GetMap()->IsDungeon() && target->GetMap()->IsDungeon()))
|
||||
{
|
||||
//if (_debug_damage_and_healing)
|
||||
// LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Not in an instance, returning original value of ({}).", amount);
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
// make sure that the source is in the world, else return the original value
|
||||
if (!source->IsInWorld())
|
||||
{
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source does not exist in the world, returning original value of ({}).", amount);
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
// if the spell ID is in our "never modify" list, return the original value
|
||||
if
|
||||
(
|
||||
spellInfo &&
|
||||
spellInfo->Id &&
|
||||
std::find
|
||||
(
|
||||
spellIdsToNeverModify.begin(),
|
||||
spellIdsToNeverModify.end(),
|
||||
spellInfo->Id
|
||||
) != spellIdsToNeverModify.end()
|
||||
)
|
||||
{
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Spell {}({}) is in the never modify list, returning original value of ({}).",
|
||||
spellInfo->SpellName[0],
|
||||
spellInfo->Id,
|
||||
amount
|
||||
);
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
// get the maps' info
|
||||
AutoBalanceMapInfo* sourceMapABInfo = GetMapInfo(source->GetMap());
|
||||
AutoBalanceMapInfo* targetMapABInfo = GetMapInfo(target->GetMap());
|
||||
|
||||
// if either the target or the source's maps are not enabled, return the original damage
|
||||
if (!sourceMapABInfo->enabled || !targetMapABInfo->enabled)
|
||||
{
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source or Target's map is not enabled, returning original value of ({}).", amount);
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
//
|
||||
// Source and Target Checking
|
||||
//
|
||||
|
||||
// if the source is a player and they are healing themselves, return the original value
|
||||
if (source->GetTypeId() == TYPEID_PLAYER && source->GetGUID() == target->GetGUID() && amount >= 0)
|
||||
{
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source is a player that is self-healing, returning original value of ({}).", amount);
|
||||
|
||||
return amount;
|
||||
}
|
||||
// if the source is a player and they are damaging themselves, log to debug but continue
|
||||
else if (source->GetTypeId() == TYPEID_PLAYER && source->GetGUID() == target->GetGUID() && amount < 0)
|
||||
{
|
||||
// if the spell used is in our list of spells to ignore, return the original value
|
||||
if
|
||||
(
|
||||
spellInfo &&
|
||||
spellInfo->Id &&
|
||||
std::find
|
||||
(
|
||||
spellIdsThatSpendPlayerHealth.begin(),
|
||||
spellIdsThatSpendPlayerHealth.end(),
|
||||
spellInfo->Id
|
||||
) != spellIdsThatSpendPlayerHealth.end()
|
||||
)
|
||||
{
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source is a player that is self-damaging with a spell that is ignored, returning original value of ({}).", amount);
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source is a player that is self-damaging, continuing.");
|
||||
}
|
||||
// if the source is a player and they are damaging unit that is friendly, log to debug but continue
|
||||
else if (source->GetTypeId() == TYPEID_PLAYER && target->IsFriendlyTo(source) && amount < 0)
|
||||
{
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source is a player that is damaging a friendly unit, continuing.");
|
||||
}
|
||||
// if the source is a player under any other condition, return the original value
|
||||
else if (source->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source is an enemy player, returning original value of ({}).", amount);
|
||||
|
||||
return amount;
|
||||
}
|
||||
// if the creature is attacking itself with an aura with effect type SPELL_AURA_SHARE_DAMAGE_PCT, return the orginal damage
|
||||
else if
|
||||
(
|
||||
source->GetTypeId() == TYPEID_UNIT &&
|
||||
source->GetTypeId() != TYPEID_PLAYER &&
|
||||
source->GetGUID() == target->GetGUID() &&
|
||||
_isAuraWithEffectType(spellInfo, SPELL_AURA_SHARE_DAMAGE_PCT)
|
||||
)
|
||||
{
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source is a creature that is self-damaging with an aura that shares damage, returning original value of ({}).", amount);
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
// if the source is under the control of the player, return the original damage
|
||||
// noteably, this should NOT include mind control targets
|
||||
if ((source->IsHunterPet() || source->IsPet() || source->IsSummon()) && source->IsControlledByPlayer())
|
||||
{
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source is a player-controlled pet or summon, returning original value of ({}).", amount);
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
//
|
||||
// Multiplier calculation
|
||||
//
|
||||
float damageMultiplier = 1.0f;
|
||||
|
||||
// if the source is a player AND the target is that same player AND the value is damage (negative), use the map's multiplier
|
||||
if (source->GetTypeId() == TYPEID_PLAYER && source->GetGUID() == target->GetGUID() && amount < 0)
|
||||
{
|
||||
// if this aura damages based on a percent of the player's max health, use the un-level-scaled multiplier
|
||||
if (_isAuraWithEffectType(spellInfo, SPELL_AURA_PERIODIC_DAMAGE_PERCENT))
|
||||
{
|
||||
damageMultiplier = sourceMapABInfo->worldDamageHealingMultiplier;
|
||||
if (_debug_damage_and_healing)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Spell damage based on percent of max health. Ignore level scaling.");
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC",
|
||||
"AutoBalance_UnitScript::_Modify_Damage_Healing: Source is a player and the target is that same player, using the map's (level-scaling ignored) multiplier: ({})",
|
||||
damageMultiplier
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
damageMultiplier = sourceMapABInfo->scaledWorldDamageHealingMultiplier;
|
||||
if (_debug_damage_and_healing)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC",
|
||||
"AutoBalance_UnitScript::_Modify_Damage_Healing: Source is a player and the target is that same player, using the map's multiplier: ({})",
|
||||
damageMultiplier
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if the target is a player AND the value is healing (positive), use the map's damage multiplier
|
||||
// (player to player healing was already eliminated in the Source and Target Checking section)
|
||||
else if (target->GetTypeId() == TYPEID_PLAYER && amount >= 0)
|
||||
{
|
||||
damageMultiplier = targetMapABInfo->scaledWorldDamageHealingMultiplier;
|
||||
if (_debug_damage_and_healing)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC",
|
||||
"AutoBalance_UnitScript::_Modify_Damage_Healing: A non-player is healing a player, using the map's multiplier: ({})",
|
||||
damageMultiplier
|
||||
);
|
||||
}
|
||||
}
|
||||
// if the target is a player AND the source is not a creature, use the map's multiplier
|
||||
else if (target->GetTypeId() == TYPEID_PLAYER && source->GetTypeId() != TYPEID_UNIT && amount < 0)
|
||||
{
|
||||
// if this aura damages based on a percent of the player's max health, use the un-level-scaled multiplier
|
||||
if (_isAuraWithEffectType(spellInfo, SPELL_AURA_PERIODIC_DAMAGE_PERCENT))
|
||||
{
|
||||
damageMultiplier = targetMapABInfo->worldDamageHealingMultiplier;
|
||||
if (_debug_damage_and_healing)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Spell damage based on percent of max health. Ignore level scaling.");
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC",
|
||||
"AutoBalance_UnitScript::_Modify_Damage_Healing: Target is a player and the source is not a creature, using the map's (level-scaling-ignored) multiplier: ({})",
|
||||
damageMultiplier
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
damageMultiplier = targetMapABInfo->scaledWorldDamageHealingMultiplier;
|
||||
if (_debug_damage_and_healing)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC",
|
||||
"AutoBalance_UnitScript::_Modify_Damage_Healing: Target is a player and the source is not a creature, using the map's multiplier: ({})",
|
||||
damageMultiplier
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
// otherwise, use the source creature's damage multiplier
|
||||
else
|
||||
{
|
||||
// if this aura damages based on a percent of the player's max health, use the un-level-scaled multiplier
|
||||
if (_isAuraWithEffectType(spellInfo, SPELL_AURA_PERIODIC_DAMAGE_PERCENT))
|
||||
{
|
||||
damageMultiplier = source->CustomData.GetDefault<AutoBalanceCreatureInfo>("AutoBalanceCreatureInfo")->DamageMultiplier;
|
||||
if (_debug_damage_and_healing)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Spell damage based on percent of max health. Ignore level scaling.");
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC",
|
||||
"AutoBalance_UnitScript::_Modify_Damage_Healing: Using the source creature's (level-scaling ignored) damage multiplier: ({})",
|
||||
damageMultiplier
|
||||
);
|
||||
}
|
||||
}
|
||||
// non percent-based, used the normal multiplier
|
||||
else
|
||||
{
|
||||
damageMultiplier = source->CustomData.GetDefault<AutoBalanceCreatureInfo>("AutoBalanceCreatureInfo")->ScaledDamageMultiplier;
|
||||
if (_debug_damage_and_healing)
|
||||
{
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC",
|
||||
"AutoBalance_UnitScript::_Modify_Damage_Healing: Using the source creature's damage multiplier: ({})",
|
||||
damageMultiplier
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we are good to go, return the original damage times the multiplier
|
||||
if (_debug_damage_and_healing)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Returning modified {}: ({}) * ({}) = ({})",
|
||||
amount <= 0 ? "damage" : "healing",
|
||||
amount,
|
||||
damageMultiplier,
|
||||
amount * damageMultiplier
|
||||
);
|
||||
|
||||
return amount * damageMultiplier;
|
||||
}
|
||||
|
||||
uint32 AutoBalance_UnitScript::_Modifier_CCDuration(Unit* target, Unit* caster, Aura* aura)
|
||||
{
|
||||
// store the original duration of the aura
|
||||
float originalDuration = (float)aura->GetDuration();
|
||||
|
||||
// check that we're enabled globally, else return the original duration
|
||||
if (!EnableGlobal)
|
||||
return originalDuration;
|
||||
|
||||
// ensure that both the target and the caster are defined
|
||||
if (!target || !caster)
|
||||
return originalDuration;
|
||||
|
||||
// if the aura wasn't cast just now, don't change it
|
||||
if (aura->GetDuration() != aura->GetMaxDuration())
|
||||
return originalDuration;
|
||||
|
||||
// if the target isn't a player or the caster is a player, return the original duration
|
||||
if (!target->IsPlayer() || caster->IsPlayer())
|
||||
return originalDuration;
|
||||
|
||||
// make sure we're in an instance, else return the original duration
|
||||
if (!(target->GetMap()->IsDungeon() && caster->GetMap()->IsDungeon()))
|
||||
return originalDuration;
|
||||
|
||||
// get the current creature's CC duration multiplier
|
||||
float ccDurationMultiplier = caster->CustomData.GetDefault<AutoBalanceCreatureInfo>("AutoBalanceCreatureInfo")->CCDurationMultiplier;
|
||||
|
||||
// if it's the default of 1.0, return the original damage
|
||||
if (ccDurationMultiplier == 1)
|
||||
return originalDuration;
|
||||
|
||||
// if the aura was cast by a pet or summon, return the original duration
|
||||
if ((caster->IsHunterPet() || caster->IsPet() || caster->IsSummon()) && caster->IsControlledByPlayer())
|
||||
return originalDuration;
|
||||
|
||||
// only if this aura is a CC
|
||||
if (
|
||||
aura->HasEffectType(SPELL_AURA_MOD_CHARM) ||
|
||||
aura->HasEffectType(SPELL_AURA_MOD_CONFUSE) ||
|
||||
aura->HasEffectType(SPELL_AURA_MOD_DISARM) ||
|
||||
aura->HasEffectType(SPELL_AURA_MOD_FEAR) ||
|
||||
aura->HasEffectType(SPELL_AURA_MOD_PACIFY) ||
|
||||
aura->HasEffectType(SPELL_AURA_MOD_POSSESS) ||
|
||||
aura->HasEffectType(SPELL_AURA_MOD_SILENCE) ||
|
||||
aura->HasEffectType(SPELL_AURA_MOD_STUN) ||
|
||||
aura->HasEffectType(SPELL_AURA_MOD_SPEED_SLOW_ALL)
|
||||
)
|
||||
{
|
||||
return originalDuration * ccDurationMultiplier;
|
||||
}
|
||||
else
|
||||
return originalDuration;
|
||||
}
|
||||
|
||||
bool AutoBalance_UnitScript::_isAuraWithEffectType(SpellInfo const* spellInfo, AuraType auraType, bool log)
|
||||
{
|
||||
// if the spell is not defined, return false
|
||||
if (!spellInfo)
|
||||
{
|
||||
if (log)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_isAuraWithEffectType: SpellInfo is null, returning false.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// if the spell doesn't have any effects, return false
|
||||
if (!spellInfo->GetEffects().size())
|
||||
{
|
||||
if (log)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_isAuraWithEffectType: SpellInfo has no effects, returning false.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// iterate through the spell effects
|
||||
for (SpellEffectInfo effect : spellInfo->GetEffects())
|
||||
{
|
||||
// if the effect is not an aura, continue to next effect
|
||||
if (!effect.IsAura())
|
||||
{
|
||||
if (log)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_isAuraWithEffectType: SpellInfo has an effect that is not an aura, continuing to next effect.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (effect.ApplyAuraName == auraType)
|
||||
{
|
||||
// if the effect is an aura of the target type, return true
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_isAuraWithEffectType: SpellInfo has an aura of the target type, returning true.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// if no aura effect of type auraType was found, return false
|
||||
if (log)
|
||||
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_isAuraWithEffectType: SpellInfo has no aura of the target type, returning false.");
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#ifndef __AB_UNIT_SCRIPT_H
|
||||
#define __AB_UNIT_SCRIPT_H
|
||||
|
||||
#include "AutoBalance.h"
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
class AutoBalance_UnitScript : public UnitScript
|
||||
{
|
||||
public:
|
||||
AutoBalance_UnitScript()
|
||||
: UnitScript("AutoBalance_UnitScript", true, {
|
||||
UNITHOOK_MODIFY_PERIODIC_DAMAGE_AURAS_TICK,
|
||||
UNITHOOK_MODIFY_SPELL_DAMAGE_TAKEN,
|
||||
UNITHOOK_MODIFY_MELEE_DAMAGE,
|
||||
UNITHOOK_MODIFY_HEAL_RECEIVED,
|
||||
UNITHOOK_ON_AURA_APPLY
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
void ModifyPeriodicDamageAurasTick(Unit* target, Unit* source, uint32& amount, SpellInfo const* spellInfo) override;
|
||||
void ModifySpellDamageTaken(Unit* target, Unit* source, int32& amount, SpellInfo const* spellInfo) override;
|
||||
void ModifyMeleeDamage(Unit* target, Unit* source, uint32& amount) override;
|
||||
void ModifyHealReceived(Unit* target, Unit* source, uint32& amount, SpellInfo const* spellInfo) override;
|
||||
void OnAuraApply(Unit* unit, Aura* aura) override;
|
||||
|
||||
private:
|
||||
[[maybe_unused]] bool _debug_damage_and_healing = false; // defaults to false, overwritten in each function
|
||||
|
||||
void _Debug_Output(std::string function_name, Unit* target, Unit* source, int32 amount, Damage_Healing_Debug_Phase phase, std::string spell_name = "Unknown Spell", uint32 spell_id = 0);
|
||||
int32 _Modify_Damage_Healing(Unit* target, Unit* source, int32 amount, SpellInfo const* spellInfo = nullptr);
|
||||
uint32 _Modifier_CCDuration(Unit* target, Unit* caster, Aura* aura);
|
||||
bool _isAuraWithEffectType(SpellInfo const* spellInfo, AuraType auraType, bool log = false);
|
||||
};
|
||||
|
||||
|
||||
#endif /* __AB_UNIT_SCRIPT_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#ifndef __AB_UTILS_H
|
||||
#define __AB_UTILS_H
|
||||
|
||||
#include "ABInflectionPointSettings.h"
|
||||
#include "ABLevelScalingDynamicLevelSettings.h"
|
||||
#include "ABMapInfo.h"
|
||||
#include "ABStatModifiers.h"
|
||||
#include "AutoBalance.h"
|
||||
|
||||
#include "Creature.h"
|
||||
#include "Map.h"
|
||||
#include "SharedDefines.h"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
void AddCreatureToMapCreatureList(Creature* creature, bool addToCreatureList = true, bool forceRecalculation = false);
|
||||
void RemoveCreatureFromMapData(Creature* creature);
|
||||
|
||||
uint64_t GetCurrentConfigTime();
|
||||
uint32 getBaseExpansionValueForLevel(const uint32 baseValues[3], uint8 targetLevel);
|
||||
float getBaseExpansionValueForLevel(const float baseValues[3], uint8 targetLevel);
|
||||
float getDefaultMultiplier(Map* map, AutoBalanceInflectionPointSettings inflectionPointSettings);
|
||||
int GetForcedNumPlayers(int creatureId);
|
||||
World_Multipliers getWorldMultiplier(Map* map, BaseValueType baseValueType);
|
||||
AutoBalanceInflectionPointSettings getInflectionPointSettings(InstanceMap* instanceMap, bool isBoss = false);
|
||||
void getStatModifiersDebug(Map* map, Creature* creature, std::string message);
|
||||
AutoBalanceStatModifiers getStatModifiers(Map* map, Creature* creature = nullptr);
|
||||
|
||||
bool hasBossOverride(uint32 dungeonId);
|
||||
bool hasDungeonOverride(uint32 dungeonId);
|
||||
bool hasDynamicLevelOverride(uint32 dungeonId);
|
||||
bool hasLevelScalingDistanceCheckOverride(uint32 dungeonId);
|
||||
bool hasStatModifierBossOverride(uint32 dungeonId);
|
||||
bool hasStatModifierCreatureOverride(uint32 creatureId);
|
||||
bool hasStatModifierOverride(uint32 dungeonId);
|
||||
|
||||
bool isBossOrBossSummon(Creature* creature, bool log = false);
|
||||
bool isCreatureRelevant(Creature* creature);
|
||||
bool isDungeonInDisabledDungeonIds(uint32 dungeonId);
|
||||
bool isDungeonInMinPlayerMap(uint32 dungeonId, bool isHeroic);
|
||||
|
||||
void LoadForcedCreatureIdsFromString(std::string creatureIds, int forcedPlayerCount);
|
||||
std::list<uint32> LoadDisabledDungeons(std::string dungeonIdString);
|
||||
std::map <uint32, uint32> LoadDistanceCheckOverrides(std::string dungeonIdString);
|
||||
std::map <uint8 , AutoBalanceLevelScalingDynamicLevelSettings> LoadDynamicLevelOverrides(std::string dungeonIdString);
|
||||
std::map <uint32, AutoBalanceInflectionPointSettings> LoadInflectionPointOverrides(std::string dungeonIdString);
|
||||
void LoadMapSettings(Map* map);
|
||||
std::map <uint32, uint8> LoadMinPlayersPerDungeonId(std::string minPlayersString);
|
||||
std::map <uint32, AutoBalanceStatModifiers> LoadStatModifierOverrides(std::string dungeonIdString);
|
||||
|
||||
bool ShouldMapBeEnabled (Map* map);
|
||||
void UpdateMapPlayerStats (Map* map);
|
||||
void AddPlayerToMap(Map* map, Player* player);
|
||||
bool RemovePlayerFromMap(Map* map, Player* player);
|
||||
bool UpdateMapDataIfNeeded(Map* map, bool force = false);
|
||||
AutoBalanceMapInfo* GetMapInfo(Map* map);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,509 @@
|
||||
#include "ABWorldScript.h"
|
||||
|
||||
#include "ABConfig.h"
|
||||
#include "ABUtils.h"
|
||||
|
||||
#include "Configuration/Config.h"
|
||||
#include "Log.h"
|
||||
|
||||
void AutoBalance_WorldScript::OnBeforeConfigLoad(bool /*reload*/)
|
||||
{
|
||||
SetInitialWorldSettings();
|
||||
globalConfigTime = GetCurrentConfigTime();
|
||||
|
||||
LOG_INFO("module.AutoBalance", "AutoBalance::OnBeforeConfigLoad: Config loaded. Global config time set to ({}).", globalConfigTime);
|
||||
}
|
||||
|
||||
void AutoBalance_WorldScript::SetInitialWorldSettings()
|
||||
{
|
||||
forcedCreatureIds.clear();
|
||||
disabledDungeonIds.clear();
|
||||
dungeonOverrides.clear();
|
||||
bossOverrides.clear();
|
||||
statModifierOverrides.clear();
|
||||
statModifierBossOverrides.clear();
|
||||
statModifierCreatureOverrides.clear();
|
||||
levelScalingDynamicLevelOverrides.clear();
|
||||
levelScalingDistanceCheckOverrides.clear();
|
||||
|
||||
LoadForcedCreatureIdsFromString(sConfigMgr->GetOption<std::string>("AutoBalance.ForcedID40", ""), 40);
|
||||
LoadForcedCreatureIdsFromString(sConfigMgr->GetOption<std::string>("AutoBalance.ForcedID25", ""), 25);
|
||||
LoadForcedCreatureIdsFromString(sConfigMgr->GetOption<std::string>("AutoBalance.ForcedID10", ""), 10);
|
||||
LoadForcedCreatureIdsFromString(sConfigMgr->GetOption<std::string>("AutoBalance.ForcedID5" , ""), 5);
|
||||
LoadForcedCreatureIdsFromString(sConfigMgr->GetOption<std::string>("AutoBalance.ForcedID2" , ""), 2);
|
||||
LoadForcedCreatureIdsFromString(sConfigMgr->GetOption<std::string>("AutoBalance.DisabledID", ""), 0);
|
||||
|
||||
//
|
||||
// Disabled Dungeon IDs
|
||||
//
|
||||
|
||||
disabledDungeonIds = LoadDisabledDungeons(sConfigMgr->GetOption<std::string>("AutoBalance.Disable.PerInstance", ""));
|
||||
|
||||
//
|
||||
// Min Players
|
||||
//
|
||||
|
||||
minPlayersNormal = sConfigMgr->GetOption<int>("AutoBalance.MinPlayers", 1);
|
||||
minPlayersHeroic = sConfigMgr->GetOption<int>("AutoBalance.MinPlayers.Heroic", 1);
|
||||
minPlayersRaid = sConfigMgr->GetOption<int>("AutoBalance.MinPlayers.Raid", minPlayersNormal);
|
||||
minPlayersRaidHeroic = sConfigMgr->GetOption<int>("AutoBalance.MinPlayers.RaidHeroic", minPlayersHeroic);
|
||||
|
||||
if (sConfigMgr->GetOption<float>("AutoBalance.PerDungeonPlayerCounts", false, false))
|
||||
LOG_WARN("server.loading", "mod-autobalance: deprecated value `AutoBalance.PerDungeonPlayerCounts` defined in `AutoBalance.conf`. This variable will be removed in a future release. Please see `AutoBalance.conf.dist` for more details.");
|
||||
|
||||
minPlayersPerDungeonIdMap = LoadMinPlayersPerDungeonId(
|
||||
sConfigMgr->GetOption<std::string>("AutoBalance.MinPlayers.PerInstance",
|
||||
sConfigMgr->GetOption<std::string>("AutoBalance.PerDungeonPlayerCounts", "", false), false)); // `AutoBalance.PerDungeonPlayerCounts` for backwards compatibility
|
||||
|
||||
minPlayersPerHeroicDungeonIdMap = LoadMinPlayersPerDungeonId(
|
||||
sConfigMgr->GetOption<std::string>("AutoBalance.MinPlayers.Heroic.PerInstance",
|
||||
sConfigMgr->GetOption<std::string>("AutoBalance.PerDungeonPlayerCounts", "", false), false)); // `AutoBalance.PerDungeonPlayerCounts` for backwards compatibility
|
||||
|
||||
//
|
||||
// Overrides
|
||||
//
|
||||
|
||||
if (sConfigMgr->GetOption<float>("AutoBalance.PerDungeonScaling", false, false))
|
||||
LOG_WARN("server.loading", "mod-autobalance: deprecated value `AutoBalance.PerDungeonScaling` defined in `AutoBalance.conf`. This variable will be removed in a future release. Please see `AutoBalance.conf.dist` for more details.");
|
||||
|
||||
dungeonOverrides = LoadInflectionPointOverrides(
|
||||
sConfigMgr->GetOption<std::string>("AutoBalance.InflectionPoint.PerInstance",
|
||||
sConfigMgr->GetOption<std::string>("AutoBalance.PerDungeonScaling", "", false), false)); // `AutoBalance.PerDungeonScaling` for backwards compatibility
|
||||
|
||||
if (sConfigMgr->GetOption<float>("AutoBalance.PerDungeonBossScaling", false, false))
|
||||
LOG_WARN("server.loading", "mod-autobalance: deprecated value `AutoBalance.PerDungeonBossScaling` defined in `AutoBalance.conf`. This variable will be removed in a future release. Please see `AutoBalance.conf.dist` for more details.");
|
||||
|
||||
bossOverrides = LoadInflectionPointOverrides(
|
||||
sConfigMgr->GetOption<std::string>("AutoBalance.InflectionPoint.Boss.PerInstance",
|
||||
sConfigMgr->GetOption<std::string>("AutoBalance.PerDungeonBossScaling", "", false), false)); // `AutoBalance.PerDungeonBossScaling` for backwards compatibility
|
||||
|
||||
statModifierOverrides = LoadStatModifierOverrides(
|
||||
sConfigMgr->GetOption<std::string>("AutoBalance.StatModifier.PerInstance", "", false));
|
||||
|
||||
statModifierBossOverrides = LoadStatModifierOverrides(
|
||||
sConfigMgr->GetOption<std::string>("AutoBalance.StatModifier.Boss.PerInstance", "", false));
|
||||
|
||||
statModifierCreatureOverrides = LoadStatModifierOverrides(
|
||||
sConfigMgr->GetOption<std::string>("AutoBalance.StatModifier.PerCreature", "", false));
|
||||
|
||||
levelScalingDynamicLevelOverrides = LoadDynamicLevelOverrides(
|
||||
sConfigMgr->GetOption<std::string>("AutoBalance.LevelScaling.DynamicLevel.PerInstance", "", false));
|
||||
|
||||
levelScalingDistanceCheckOverrides = LoadDistanceCheckOverrides(
|
||||
sConfigMgr->GetOption<std::string>("AutoBalance.LevelScaling.DynamicLevel.DistanceCheck.PerInstance", "", false));
|
||||
|
||||
//
|
||||
// AutoBalance.Enable.*
|
||||
// Deprecated setting warning
|
||||
//
|
||||
if (sConfigMgr->GetOption<int>("AutoBalance.enable", -1, false) != -1)
|
||||
LOG_WARN("server.loading", "mod-autobalance: deprecated value `AutoBalance.enable` defined in `AutoBalance.conf`. This variable will be removed in a future release. Please see `AutoBalance.conf.dist` for more details.");
|
||||
|
||||
EnableGlobal = sConfigMgr->GetOption<bool>("AutoBalance.Enable.Global" , sConfigMgr->GetOption<bool>("AutoBalance.enable", 1, false)); // `AutoBalance.enable` for backwards compatibility
|
||||
|
||||
Enable5M = sConfigMgr->GetOption<bool>("AutoBalance.Enable.5M" , sConfigMgr->GetOption<bool>("AutoBalance.enable", 1, false));
|
||||
Enable10M = sConfigMgr->GetOption<bool>("AutoBalance.Enable.10M" , sConfigMgr->GetOption<bool>("AutoBalance.enable", 1, false));
|
||||
Enable15M = sConfigMgr->GetOption<bool>("AutoBalance.Enable.15M" , sConfigMgr->GetOption<bool>("AutoBalance.enable", 1, false));
|
||||
Enable20M = sConfigMgr->GetOption<bool>("AutoBalance.Enable.20M" , sConfigMgr->GetOption<bool>("AutoBalance.enable", 1, false));
|
||||
Enable25M = sConfigMgr->GetOption<bool>("AutoBalance.Enable.25M" , sConfigMgr->GetOption<bool>("AutoBalance.enable", 1, false));
|
||||
Enable40M = sConfigMgr->GetOption<bool>("AutoBalance.Enable.40M" , sConfigMgr->GetOption<bool>("AutoBalance.enable", 1, false));
|
||||
EnableOtherNormal = sConfigMgr->GetOption<bool>("AutoBalance.Enable.OtherNormal", sConfigMgr->GetOption<bool>("AutoBalance.enable", 1, false));
|
||||
|
||||
Enable5MHeroic = sConfigMgr->GetOption<bool>("AutoBalance.Enable.5MHeroic" , sConfigMgr->GetOption<bool>("AutoBalance.enable", 1, false));
|
||||
Enable10MHeroic = sConfigMgr->GetOption<bool>("AutoBalance.Enable.10MHeroic" , sConfigMgr->GetOption<bool>("AutoBalance.enable", 1, false));
|
||||
Enable25MHeroic = sConfigMgr->GetOption<bool>("AutoBalance.Enable.25MHeroic" , sConfigMgr->GetOption<bool>("AutoBalance.enable", 1, false));
|
||||
EnableOtherHeroic = sConfigMgr->GetOption<bool>("AutoBalance.Enable.OtherHeroic", sConfigMgr->GetOption<bool>("AutoBalance.enable", 1, false));
|
||||
|
||||
//
|
||||
// Deprecated setting warning
|
||||
//
|
||||
|
||||
if (sConfigMgr->GetOption<int>("AutoBalance.DungeonsOnly", -1, false) != -1)
|
||||
LOG_WARN("server.loading", "mod-autobalance: deprecated value `AutoBalance.DungeonsOnly` defined in `AutoBalance.conf`. This variable has been removed and has no effect. Please see `AutoBalance.conf.dist` for more details.");
|
||||
|
||||
if (sConfigMgr->GetOption<int>("AutoBalance.levelUseDbValuesWhenExists", -1, false) != -1)
|
||||
LOG_WARN("server.loading", "mod-autobalance: deprecated value `AutoBalance.levelUseDbValuesWhenExists` defined in `AutoBalance.conf`. This variable has been removed and has no effect. Please see `AutoBalance.conf.dist` for more details.");
|
||||
|
||||
//
|
||||
// Misc Settings
|
||||
// TODO: Organize and standardize variable names
|
||||
//
|
||||
|
||||
PlayerChangeNotify = sConfigMgr->GetOption<bool> ("AutoBalance.PlayerChangeNotify", 1);
|
||||
|
||||
rewardEnabled = sConfigMgr->GetOption<bool> ("AutoBalance.reward.enable", 1);
|
||||
PlayerCountDifficultyOffset = sConfigMgr->GetOption<uint32>("AutoBalance.playerCountDifficultyOffset", 0);
|
||||
rewardRaid = sConfigMgr->GetOption<uint32>("AutoBalance.reward.raidToken", 49426);
|
||||
rewardDungeon = sConfigMgr->GetOption<uint32>("AutoBalance.reward.dungeonToken", 47241);
|
||||
MinPlayerReward = sConfigMgr->GetOption<float> ("AutoBalance.reward.MinPlayerReward", 1);
|
||||
|
||||
//
|
||||
// InflectionPoint*
|
||||
// warn the console if deprecated values are detected
|
||||
//
|
||||
|
||||
if (sConfigMgr->GetOption<float>("AutoBalance.BossInflectionMult", false, false))
|
||||
LOG_WARN("server.loading", "mod-autobalance: deprecated value `AutoBalance.BossInflectionMult` defined in `AutoBalance.conf`. This variable will be removed in a future release. Please see `AutoBalance.conf.dist` for more details.");
|
||||
|
||||
InflectionPoint = sConfigMgr->GetOption<float>("AutoBalance.InflectionPoint", 0.5f, false);
|
||||
InflectionPointCurveFloor = sConfigMgr->GetOption<float>("AutoBalance.InflectionPoint.CurveFloor", 0.0f, false);
|
||||
InflectionPointCurveCeiling = sConfigMgr->GetOption<float>("AutoBalance.InflectionPoint.CurveCeiling", 1.0f, false);
|
||||
InflectionPointBoss = sConfigMgr->GetOption<float>("AutoBalance.InflectionPoint.BossModifier", sConfigMgr->GetOption<float>("AutoBalance.BossInflectionMult", 1.0f, false), false); // `AutoBalance.BossInflectionMult` for backwards compatibility
|
||||
|
||||
InflectionPointHeroic = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointHeroic", 0.5f, false);
|
||||
InflectionPointHeroicCurveFloor = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointHeroic.CurveFloor", 0.0f, false);
|
||||
InflectionPointHeroicCurveCeiling = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointHeroic.CurveCeiling", 1.0f, false);
|
||||
InflectionPointHeroicBoss = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointHeroic.BossModifier", sConfigMgr->GetOption<float>("AutoBalance.BossInflectionMult", 1.0f, false), false); // `AutoBalance.BossInflectionMult` for backwards compatibility
|
||||
|
||||
InflectionPointRaid = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid", 0.5f, false);
|
||||
InflectionPointRaidCurveFloor = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid.CurveFloor", 0.0f, false);
|
||||
InflectionPointRaidCurveCeiling = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid.CurveCeiling", 1.0f, false);
|
||||
InflectionPointRaidBoss = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid.BossModifier", sConfigMgr->GetOption<float>("AutoBalance.BossInflectionMult", 1.0f, false), false); // `AutoBalance.BossInflectionMult` for backwards compatibility
|
||||
|
||||
InflectionPointRaidHeroic = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaidHeroic", 0.5f, false);
|
||||
InflectionPointRaidHeroicCurveFloor = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaidHeroic.CurveFloor", 0.0f, false);
|
||||
InflectionPointRaidHeroicCurveCeiling = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaidHeroic.CurveCeiling", 1.0f, false);
|
||||
InflectionPointRaidHeroicBoss = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaidHeroic.BossModifier", sConfigMgr->GetOption<float>("AutoBalance.BossInflectionMult", 1.0f, false), false); // `AutoBalance.BossInflectionMult` for backwards compatibility
|
||||
|
||||
InflectionPointRaid10M = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid10M", InflectionPointRaid, false);
|
||||
InflectionPointRaid10MCurveFloor = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid10M.CurveFloor", InflectionPointRaidCurveFloor, false);
|
||||
InflectionPointRaid10MCurveCeiling = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid10M.CurveCeiling", InflectionPointRaidCurveCeiling, false);
|
||||
InflectionPointRaid10MBoss = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid10M.BossModifier", InflectionPointRaidBoss, false);
|
||||
|
||||
InflectionPointRaid10MHeroic = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid10MHeroic", InflectionPointRaidHeroic, false);
|
||||
InflectionPointRaid10MHeroicCurveFloor = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid10MHeroic.CurveFloor", InflectionPointRaidHeroicCurveFloor, false);
|
||||
InflectionPointRaid10MHeroicCurveCeiling = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid10MHeroic.CurveCeiling", InflectionPointRaidHeroicCurveCeiling, false);
|
||||
InflectionPointRaid10MHeroicBoss = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid10MHeroic.BossModifier", InflectionPointRaidHeroicBoss, false);
|
||||
|
||||
InflectionPointRaid15M = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid15M", InflectionPointRaid, false);
|
||||
InflectionPointRaid15MCurveFloor = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid15M.CurveFloor", InflectionPointRaidCurveFloor, false);
|
||||
InflectionPointRaid15MCurveCeiling = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid15M.CurveCeiling", InflectionPointRaidCurveCeiling, false);
|
||||
InflectionPointRaid15MBoss = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid15M.BossModifier", InflectionPointRaidBoss, false);
|
||||
|
||||
InflectionPointRaid20M = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid20M", InflectionPointRaid, false);
|
||||
InflectionPointRaid20MCurveFloor = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid20M.CurveFloor", InflectionPointRaidCurveFloor, false);
|
||||
InflectionPointRaid20MCurveCeiling = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid20M.CurveCeiling", InflectionPointRaidCurveCeiling, false);
|
||||
InflectionPointRaid20MBoss = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid20M.BossModifier", InflectionPointRaidBoss, false);
|
||||
|
||||
InflectionPointRaid25M = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid25M", InflectionPointRaid, false);
|
||||
InflectionPointRaid25MCurveFloor = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid25M.CurveFloor", InflectionPointRaidCurveFloor, false);
|
||||
InflectionPointRaid25MCurveCeiling = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid25M.CurveCeiling", InflectionPointRaidCurveCeiling, false);
|
||||
InflectionPointRaid25MBoss = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid25M.BossModifier", InflectionPointRaidBoss, false);
|
||||
|
||||
InflectionPointRaid25MHeroic = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid25MHeroic", InflectionPointRaidHeroic, false);
|
||||
InflectionPointRaid25MHeroicCurveFloor = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid25MHeroic.CurveFloor", InflectionPointRaidHeroicCurveFloor, false);
|
||||
InflectionPointRaid25MHeroicCurveCeiling = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid25MHeroic.CurveCeiling", InflectionPointRaidHeroicCurveCeiling, false);
|
||||
InflectionPointRaid25MHeroicBoss = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid25MHeroic.BossModifier", InflectionPointRaidHeroicBoss, false);
|
||||
|
||||
InflectionPointRaid40M = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid40M", InflectionPointRaid, false);
|
||||
InflectionPointRaid40MCurveFloor = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid40M.CurveFloor", InflectionPointRaidCurveFloor, false);
|
||||
InflectionPointRaid40MCurveCeiling = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid40M.CurveCeiling", InflectionPointRaidCurveCeiling, false);
|
||||
InflectionPointRaid40MBoss = sConfigMgr->GetOption<float>("AutoBalance.InflectionPointRaid40M.BossModifier", InflectionPointRaidBoss, false);
|
||||
|
||||
//
|
||||
// StatModifier*
|
||||
// warn the console if deprecated values are detected
|
||||
//
|
||||
|
||||
if (sConfigMgr->GetOption<float>("AutoBalance.rate.global", false, false))
|
||||
LOG_WARN("server.loading", "mod-autobalance: deprecated value `AutoBalance.rate.global` defined in `AutoBalance.conf`. This variable will be removed in a future release. Please see `AutoBalance.conf.dist` for more details.");
|
||||
if (sConfigMgr->GetOption<float>("AutoBalance.rate.health", false, false))
|
||||
LOG_WARN("server.loading", "mod-autobalance: deprecated value `AutoBalance.rate.health` defined in `AutoBalance.conf`. This variable will be removed in a future release. Please see `AutoBalance.conf.dist` for more details.");
|
||||
if (sConfigMgr->GetOption<float>("AutoBalance.rate.mana", false, false))
|
||||
LOG_WARN("server.loading", "mod-autobalance: deprecated value `AutoBalance.rate.mana` defined in `AutoBalance.conf`. This variable will be removed in a future release. Please see `AutoBalance.conf.dist` for more details.");
|
||||
if (sConfigMgr->GetOption<float>("AutoBalance.rate.armor", false, false))
|
||||
LOG_WARN("server.loading", "mod-autobalance: deprecated value `AutoBalance.rate.armor` defined in `AutoBalance.conf`. This variable will be removed in a future release. Please see `AutoBalance.conf.dist` for more details.");
|
||||
if (sConfigMgr->GetOption<float>("AutoBalance.rate.damage", false, false))
|
||||
LOG_WARN("server.loading", "mod-autobalance: deprecated value `AutoBalance.rate.damage` defined in `AutoBalance.conf`. This variable will be removed in a future release. Please see `AutoBalance.conf.dist` for more details.");
|
||||
|
||||
//
|
||||
// 5-player dungeons
|
||||
//
|
||||
|
||||
StatModifier_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifier.Global", sConfigMgr->GetOption<float>("AutoBalance.rate.global", 1.0f, false), false); // `AutoBalance.rate.global` for backwards compatibility
|
||||
StatModifier_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifier.Health", sConfigMgr->GetOption<float>("AutoBalance.rate.health", 1.0f, false), false); // `AutoBalance.rate.health` for backwards compatibility
|
||||
StatModifier_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifier.Mana", sConfigMgr->GetOption<float>("AutoBalance.rate.mana", 1.0f, false), false); // `AutoBalance.rate.mana` for backwards compatibility
|
||||
StatModifier_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifier.Armor", sConfigMgr->GetOption<float>("AutoBalance.rate.armor", 1.0f, false), false); // `AutoBalance.rate.armor` for backwards compatibility
|
||||
StatModifier_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifier.Damage", sConfigMgr->GetOption<float>("AutoBalance.rate.damage", 1.0f, false), false); // `AutoBalance.rate.damage` for backwards compatibility
|
||||
StatModifier_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifier.CCDuration", -1.0f, false);
|
||||
|
||||
StatModifier_Boss_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifier.Boss.Global", sConfigMgr->GetOption<float>("AutoBalance.rate.global", 1.0f, false), false); // `AutoBalance.rate.global` for backwards compatibility
|
||||
StatModifier_Boss_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifier.Boss.Health", sConfigMgr->GetOption<float>("AutoBalance.rate.health", 1.0f, false), false); // `AutoBalance.rate.health` for backwards compatibility
|
||||
StatModifier_Boss_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifier.Boss.Mana", sConfigMgr->GetOption<float>("AutoBalance.rate.mana", 1.0f, false), false); // `AutoBalance.rate.mana` for backwards compatibility
|
||||
StatModifier_Boss_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifier.Boss.Armor", sConfigMgr->GetOption<float>("AutoBalance.rate.armor", 1.0f, false), false); // `AutoBalance.rate.armor` for backwards compatibility
|
||||
StatModifier_Boss_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifier.Boss.Damage", sConfigMgr->GetOption<float>("AutoBalance.rate.damage", 1.0f, false), false); // `AutoBalance.rate.damage` for backwards compatibility
|
||||
StatModifier_Boss_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifier.Boss.CCDuration", -1.0f, false);
|
||||
|
||||
//
|
||||
// 5-player heroic dungeons
|
||||
//
|
||||
|
||||
StatModifierHeroic_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierHeroic.Global", sConfigMgr->GetOption<float>("AutoBalance.rate.global", 1.0f, false), false); // `AutoBalance.rate.global` for backwards compatibility
|
||||
StatModifierHeroic_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierHeroic.Health", sConfigMgr->GetOption<float>("AutoBalance.rate.health", 1.0f, false), false); // `AutoBalance.rate.health` for backwards compatibility
|
||||
StatModifierHeroic_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierHeroic.Mana", sConfigMgr->GetOption<float>("AutoBalance.rate.mana", 1.0f, false), false); // `AutoBalance.rate.mana` for backwards compatibility
|
||||
StatModifierHeroic_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierHeroic.Armor", sConfigMgr->GetOption<float>("AutoBalance.rate.armor", 1.0f, false), false); // `AutoBalance.rate.armor` for backwards compatibility
|
||||
StatModifierHeroic_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierHeroic.Damage", sConfigMgr->GetOption<float>("AutoBalance.rate.damage", 1.0f, false), false); // `AutoBalance.rate.damage` for backwards compatibility
|
||||
StatModifierHeroic_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierHeroic.CCDuration", -1.0f, false);
|
||||
|
||||
StatModifierHeroic_Boss_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierHeroic.Boss.Global", sConfigMgr->GetOption<float>("AutoBalance.rate.global", 1.0f, false), false); // `AutoBalance.rate.global` for backwards compatibility
|
||||
StatModifierHeroic_Boss_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierHeroic.Boss.Health", sConfigMgr->GetOption<float>("AutoBalance.rate.health", 1.0f, false), false); // `AutoBalance.rate.health` for backwards compatibility
|
||||
StatModifierHeroic_Boss_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierHeroic.Boss.Mana", sConfigMgr->GetOption<float>("AutoBalance.rate.mana", 1.0f, false), false); // `AutoBalance.rate.mana` for backwards compatibility
|
||||
StatModifierHeroic_Boss_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierHeroic.Boss.Armor", sConfigMgr->GetOption<float>("AutoBalance.rate.armor", 1.0f, false), false); // `AutoBalance.rate.armor` for backwards compatibility
|
||||
StatModifierHeroic_Boss_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierHeroic.Boss.Damage", sConfigMgr->GetOption<float>("AutoBalance.rate.damage", 1.0f, false), false); // `AutoBalance.rate.damage` for backwards compatibility
|
||||
StatModifierHeroic_Boss_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierHeroic.Boss.CCDuration", -1.0f, false);
|
||||
|
||||
//
|
||||
// Default for all raids
|
||||
//
|
||||
|
||||
StatModifierRaid_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid.Global", sConfigMgr->GetOption<float>("AutoBalance.rate.global", 1.0f, false), false); // `AutoBalance.rate.global` for backwards compatibility
|
||||
StatModifierRaid_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid.Health", sConfigMgr->GetOption<float>("AutoBalance.rate.health", 1.0f, false), false); // `AutoBalance.rate.health` for backwards compatibility
|
||||
StatModifierRaid_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid.Mana", sConfigMgr->GetOption<float>("AutoBalance.rate.mana", 1.0f, false), false); // `AutoBalance.rate.mana` for backwards compatibility
|
||||
StatModifierRaid_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid.Armor", sConfigMgr->GetOption<float>("AutoBalance.rate.armor", 1.0f, false), false); // `AutoBalance.rate.armor` for backwards compatibility
|
||||
StatModifierRaid_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid.Damage", sConfigMgr->GetOption<float>("AutoBalance.rate.damage", 1.0f, false), false); // `AutoBalance.rate.damage` for backwards compatibility
|
||||
StatModifierRaid_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid.CCDuration", -1.0f, false);
|
||||
|
||||
StatModifierRaid_Boss_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid.Boss.Global", sConfigMgr->GetOption<float>("AutoBalance.rate.global", 1.0f, false), false); // `AutoBalance.rate.global` for backwards compatibility
|
||||
StatModifierRaid_Boss_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid.Boss.Health", sConfigMgr->GetOption<float>("AutoBalance.rate.health", 1.0f, false), false); // `AutoBalance.rate.health` for backwards compatibility
|
||||
StatModifierRaid_Boss_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid.Boss.Mana", sConfigMgr->GetOption<float>("AutoBalance.rate.mana", 1.0f, false), false); // `AutoBalance.rate.mana` for backwards compatibility
|
||||
StatModifierRaid_Boss_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid.Boss.Armor", sConfigMgr->GetOption<float>("AutoBalance.rate.armor", 1.0f, false), false); // `AutoBalance.rate.armor` for backwards compatibility
|
||||
StatModifierRaid_Boss_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid.Boss.Damage", sConfigMgr->GetOption<float>("AutoBalance.rate.damage", 1.0f, false), false); // `AutoBalance.rate.damage` for backwards compatibility
|
||||
StatModifierRaid_Boss_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid.Boss.CCDuration", -1.0f, false);
|
||||
|
||||
//
|
||||
// Default for all heroic raids
|
||||
//
|
||||
|
||||
StatModifierRaidHeroic_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaidHeroic.Global", sConfigMgr->GetOption<float>("AutoBalance.rate.global", 1.0f, false), false); // `AutoBalance.rate.global` for backwards compatibility
|
||||
StatModifierRaidHeroic_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaidHeroic.Health", sConfigMgr->GetOption<float>("AutoBalance.rate.health", 1.0f, false), false); // `AutoBalance.rate.health` for backwards compatibility
|
||||
StatModifierRaidHeroic_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaidHeroic.Mana", sConfigMgr->GetOption<float>("AutoBalance.rate.mana", 1.0f, false), false); // `AutoBalance.rate.mana` for backwards compatibility
|
||||
StatModifierRaidHeroic_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaidHeroic.Armor", sConfigMgr->GetOption<float>("AutoBalance.rate.armor", 1.0f, false), false); // `AutoBalance.rate.armor` for backwards compatibility
|
||||
StatModifierRaidHeroic_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaidHeroic.Damage", sConfigMgr->GetOption<float>("AutoBalance.rate.damage", 1.0f, false), false); // `AutoBalance.rate.damage` for backwards compatibility
|
||||
StatModifierRaidHeroic_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaidHeroic.CCDuration", -1.0f, false);
|
||||
|
||||
StatModifierRaidHeroic_Boss_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaidHeroic.Boss.Global", sConfigMgr->GetOption<float>("AutoBalance.rate.global", 1.0f, false), false); // `AutoBalance.rate.global` for backwards compatibility
|
||||
StatModifierRaidHeroic_Boss_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaidHeroic.Boss.Health", sConfigMgr->GetOption<float>("AutoBalance.rate.health", 1.0f, false), false); // `AutoBalance.rate.health` for backwards compatibility
|
||||
StatModifierRaidHeroic_Boss_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaidHeroic.Boss.Mana", sConfigMgr->GetOption<float>("AutoBalance.rate.mana", 1.0f, false), false); // `AutoBalance.rate.mana` for backwards compatibility
|
||||
StatModifierRaidHeroic_Boss_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaidHeroic.Boss.Armor", sConfigMgr->GetOption<float>("AutoBalance.rate.armor", 1.0f, false), false); // `AutoBalance.rate.armor` for backwards compatibility
|
||||
StatModifierRaidHeroic_Boss_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaidHeroic.Boss.Damage", sConfigMgr->GetOption<float>("AutoBalance.rate.damage", 1.0f, false), false); // `AutoBalance.rate.damage` for backwards compatibility
|
||||
StatModifierRaidHeroic_Boss_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaidHeroic.Boss.CCDuration", -1.0f, false);
|
||||
|
||||
//
|
||||
// 10-player raids
|
||||
//
|
||||
|
||||
StatModifierRaid10M_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10M.Global", StatModifierRaid_Global, false);
|
||||
StatModifierRaid10M_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10M.Health", StatModifierRaid_Health, false);
|
||||
StatModifierRaid10M_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10M.Mana", StatModifierRaid_Mana, false);
|
||||
StatModifierRaid10M_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10M.Armor", StatModifierRaid_Armor, false);
|
||||
StatModifierRaid10M_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10M.Damage", StatModifierRaid_Damage, false);
|
||||
StatModifierRaid10M_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10M.CCDuration", StatModifierRaid_CCDuration, false);
|
||||
|
||||
StatModifierRaid10M_Boss_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10M.Boss.Global", StatModifierRaid_Boss_Global, false);
|
||||
StatModifierRaid10M_Boss_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10M.Boss.Health", StatModifierRaid_Boss_Health, false);
|
||||
StatModifierRaid10M_Boss_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10M.Boss.Mana", StatModifierRaid_Boss_Mana, false);
|
||||
StatModifierRaid10M_Boss_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10M.Boss.Armor", StatModifierRaid_Boss_Armor, false);
|
||||
StatModifierRaid10M_Boss_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10M.Boss.Damage", StatModifierRaid_Boss_Damage, false);
|
||||
StatModifierRaid10M_Boss_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10M.Boss.CCDuration", StatModifierRaid_Boss_CCDuration, false);
|
||||
|
||||
//
|
||||
// 10-player heroic raids
|
||||
//
|
||||
|
||||
StatModifierRaid10MHeroic_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10MHeroic.Global", StatModifierRaidHeroic_Global, false);
|
||||
StatModifierRaid10MHeroic_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10MHeroic.Health", StatModifierRaidHeroic_Health, false);
|
||||
StatModifierRaid10MHeroic_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10MHeroic.Mana", StatModifierRaidHeroic_Mana, false);
|
||||
StatModifierRaid10MHeroic_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10MHeroic.Armor", StatModifierRaidHeroic_Armor, false);
|
||||
StatModifierRaid10MHeroic_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10MHeroic.Damage", StatModifierRaidHeroic_Damage, false);
|
||||
StatModifierRaid10MHeroic_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10MHeroic.CCDuration", StatModifierRaidHeroic_CCDuration, false);
|
||||
|
||||
StatModifierRaid10MHeroic_Boss_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10MHeroic.Boss.Global", StatModifierRaidHeroic_Boss_Global, false);
|
||||
StatModifierRaid10MHeroic_Boss_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10MHeroic.Boss.Health", StatModifierRaidHeroic_Boss_Health, false);
|
||||
StatModifierRaid10MHeroic_Boss_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10MHeroic.Boss.Mana", StatModifierRaidHeroic_Boss_Mana, false);
|
||||
StatModifierRaid10MHeroic_Boss_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10MHeroic.Boss.Armor", StatModifierRaidHeroic_Boss_Armor, false);
|
||||
StatModifierRaid10MHeroic_Boss_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10MHeroic.Boss.Damage", StatModifierRaidHeroic_Boss_Damage, false);
|
||||
StatModifierRaid10MHeroic_Boss_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid10MHeroic.Boss.CCDuration", StatModifierRaidHeroic_Boss_CCDuration, false);
|
||||
|
||||
//
|
||||
// 15-player raids
|
||||
//
|
||||
|
||||
StatModifierRaid15M_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid15M.Global", StatModifierRaid_Global, false);
|
||||
StatModifierRaid15M_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid15M.Health", StatModifierRaid_Health, false);
|
||||
StatModifierRaid15M_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid15M.Mana", StatModifierRaid_Mana, false);
|
||||
StatModifierRaid15M_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid15M.Armor", StatModifierRaid_Armor, false);
|
||||
StatModifierRaid15M_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid15M.Damage", StatModifierRaid_Damage, false);
|
||||
StatModifierRaid15M_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid15M.CCDuration", StatModifierRaid_CCDuration, false);
|
||||
|
||||
StatModifierRaid15M_Boss_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid15M.Boss.Global", StatModifierRaid_Boss_Global, false);
|
||||
StatModifierRaid15M_Boss_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid15M.Boss.Health", StatModifierRaid_Boss_Health, false);
|
||||
StatModifierRaid15M_Boss_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid15M.Boss.Mana", StatModifierRaid_Boss_Mana, false);
|
||||
StatModifierRaid15M_Boss_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid15M.Boss.Armor", StatModifierRaid_Boss_Armor, false);
|
||||
StatModifierRaid15M_Boss_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid15M.Boss.Damage", StatModifierRaid_Boss_Damage, false);
|
||||
StatModifierRaid15M_Boss_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid15M.Boss.CCDuration", StatModifierRaid_Boss_CCDuration, false);
|
||||
|
||||
//
|
||||
// 20-player raids
|
||||
//
|
||||
|
||||
StatModifierRaid20M_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid20M.Global", StatModifierRaid_Global, false);
|
||||
StatModifierRaid20M_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid20M.Health", StatModifierRaid_Health, false);
|
||||
StatModifierRaid20M_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid20M.Mana", StatModifierRaid_Mana, false);
|
||||
StatModifierRaid20M_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid20M.Armor", StatModifierRaid_Armor, false);
|
||||
StatModifierRaid20M_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid20M.Damage", StatModifierRaid_Damage, false);
|
||||
StatModifierRaid20M_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid20M.CCDuration", StatModifierRaid_CCDuration, false);
|
||||
|
||||
StatModifierRaid20M_Boss_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid20M.Boss.Global", StatModifierRaid_Boss_Global, false);
|
||||
StatModifierRaid20M_Boss_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid20M.Boss.Health", StatModifierRaid_Boss_Health, false);
|
||||
StatModifierRaid20M_Boss_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid20M.Boss.Mana", StatModifierRaid_Boss_Mana, false);
|
||||
StatModifierRaid20M_Boss_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid20M.Boss.Armor", StatModifierRaid_Boss_Armor, false);
|
||||
StatModifierRaid20M_Boss_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid20M.Boss.Damage", StatModifierRaid_Boss_Damage, false);
|
||||
StatModifierRaid20M_Boss_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid20M.Boss.CCDuration", StatModifierRaid_Boss_CCDuration, false);
|
||||
|
||||
//
|
||||
// 25-player raids
|
||||
//
|
||||
|
||||
StatModifierRaid25M_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25M.Global", StatModifierRaid_Global, false);
|
||||
StatModifierRaid25M_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25M.Health", StatModifierRaid_Health, false);
|
||||
StatModifierRaid25M_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25M.Mana", StatModifierRaid_Mana, false);
|
||||
StatModifierRaid25M_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25M.Armor", StatModifierRaid_Armor, false);
|
||||
StatModifierRaid25M_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25M.Damage", StatModifierRaid_Damage, false);
|
||||
StatModifierRaid25M_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25M.CCDuration", StatModifierRaid_CCDuration, false);
|
||||
|
||||
StatModifierRaid25M_Boss_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25M.Boss.Global", StatModifierRaid_Boss_Global, false);
|
||||
StatModifierRaid25M_Boss_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25M.Boss.Health", StatModifierRaid_Boss_Health, false);
|
||||
StatModifierRaid25M_Boss_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25M.Boss.Mana", StatModifierRaid_Boss_Mana, false);
|
||||
StatModifierRaid25M_Boss_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25M.Boss.Armor", StatModifierRaid_Boss_Armor, false);
|
||||
StatModifierRaid25M_Boss_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25M.Boss.Damage", StatModifierRaid_Boss_Damage, false);
|
||||
StatModifierRaid25M_Boss_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25M.Boss.CCDuration", StatModifierRaid_Boss_CCDuration, false);
|
||||
|
||||
//
|
||||
// 25-player heroic raids
|
||||
//
|
||||
|
||||
StatModifierRaid25MHeroic_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25MHeroic.Global", StatModifierRaidHeroic_Global, false);
|
||||
StatModifierRaid25MHeroic_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25MHeroic.Health", StatModifierRaidHeroic_Health, false);
|
||||
StatModifierRaid25MHeroic_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25MHeroic.Mana", StatModifierRaidHeroic_Mana, false);
|
||||
StatModifierRaid25MHeroic_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25MHeroic.Armor", StatModifierRaidHeroic_Armor, false);
|
||||
StatModifierRaid25MHeroic_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25MHeroic.Damage", StatModifierRaidHeroic_Damage, false);
|
||||
StatModifierRaid25MHeroic_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25MHeroic.CCDuration", StatModifierRaidHeroic_CCDuration, false);
|
||||
|
||||
StatModifierRaid25MHeroic_Boss_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25MHeroic.Boss.Global", StatModifierRaidHeroic_Boss_Global, false);
|
||||
StatModifierRaid25MHeroic_Boss_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25MHeroic.Boss.Health", StatModifierRaidHeroic_Boss_Health, false);
|
||||
StatModifierRaid25MHeroic_Boss_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25MHeroic.Boss.Mana", StatModifierRaidHeroic_Boss_Mana, false);
|
||||
StatModifierRaid25MHeroic_Boss_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25MHeroic.Boss.Armor", StatModifierRaidHeroic_Boss_Armor, false);
|
||||
StatModifierRaid25MHeroic_Boss_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25MHeroic.Boss.Damage", StatModifierRaidHeroic_Boss_Damage, false);
|
||||
StatModifierRaid25MHeroic_Boss_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid25MHeroic.Boss.CCDuration", StatModifierRaidHeroic_Boss_CCDuration, false);
|
||||
|
||||
//
|
||||
// 40-player raids
|
||||
//
|
||||
|
||||
StatModifierRaid40M_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid40M.Global", StatModifierRaid_Global, false);
|
||||
StatModifierRaid40M_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid40M.Health", StatModifierRaid_Health, false);
|
||||
StatModifierRaid40M_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid40M.Mana", StatModifierRaid_Mana, false);
|
||||
StatModifierRaid40M_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid40M.Armor", StatModifierRaid_Armor, false);
|
||||
StatModifierRaid40M_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid40M.Damage", StatModifierRaid_Damage, false);
|
||||
StatModifierRaid40M_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid40M.CCDuration", StatModifierRaid_CCDuration, false);
|
||||
|
||||
StatModifierRaid40M_Boss_Global = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid40M.Boss.Global", StatModifierRaid_Boss_Global, false);
|
||||
StatModifierRaid40M_Boss_Health = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid40M.Boss.Health", StatModifierRaid_Boss_Health, false);
|
||||
StatModifierRaid40M_Boss_Mana = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid40M.Boss.Mana", StatModifierRaid_Boss_Mana, false);
|
||||
StatModifierRaid40M_Boss_Armor = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid40M.Boss.Armor", StatModifierRaid_Boss_Armor, false);
|
||||
StatModifierRaid40M_Boss_Damage = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid40M.Boss.Damage", StatModifierRaid_Boss_Damage, false);
|
||||
StatModifierRaid40M_Boss_CCDuration = sConfigMgr->GetOption<float>("AutoBalance.StatModifierRaid40M.Boss.CCDuration", StatModifierRaid_Boss_CCDuration, false);
|
||||
|
||||
//
|
||||
// Modifier Min/Max
|
||||
//
|
||||
|
||||
MinHPModifier = sConfigMgr->GetOption<float>("AutoBalance.MinHPModifier", 0.1f);
|
||||
MinManaModifier = sConfigMgr->GetOption<float>("AutoBalance.MinManaModifier", 0.01f);
|
||||
MinDamageModifier = sConfigMgr->GetOption<float>("AutoBalance.MinDamageModifier", 0.01f);
|
||||
MinCCDurationModifier = sConfigMgr->GetOption<float>("AutoBalance.MinCCDurationModifier", 0.25f);
|
||||
MaxCCDurationModifier = sConfigMgr->GetOption<float>("AutoBalance.MaxCCDurationModifier", 1.0f);
|
||||
|
||||
//
|
||||
// LevelScaling.*
|
||||
//
|
||||
|
||||
LevelScaling = sConfigMgr->GetOption<bool>("AutoBalance.LevelScaling", true);
|
||||
|
||||
std::string LevelScalingMethodString = sConfigMgr->GetOption<std::string>("AutoBalance.LevelScaling.Method", "dynamic", false);
|
||||
|
||||
if (LevelScalingMethodString == "fixed")
|
||||
LevelScalingMethod = AUTOBALANCE_SCALING_FIXED;
|
||||
else if (LevelScalingMethodString == "dynamic")
|
||||
LevelScalingMethod = AUTOBALANCE_SCALING_DYNAMIC;
|
||||
else
|
||||
{
|
||||
LOG_ERROR("server.loading", "mod-autobalance: invalid value `{}` for `AutoBalance.LevelScaling.Method` defined in `AutoBalance.conf`. Defaulting to a value of `dynamic`.", LevelScalingMethodString);
|
||||
LevelScalingMethod = AUTOBALANCE_SCALING_DYNAMIC;
|
||||
}
|
||||
|
||||
if (sConfigMgr->GetOption<float>("AutoBalance.LevelHigherOffset", false, false))
|
||||
LOG_WARN("server.loading", "mod-autobalance: deprecated value `AutoBalance.LevelHigherOffset` defined in `AutoBalance.conf`. This variable will be removed in a future release. Please see `AutoBalance.conf.dist` for more details.");
|
||||
|
||||
LevelScalingSkipHigherLevels = sConfigMgr->GetOption<uint8>("AutoBalance.LevelScaling.SkipHigherLevels", sConfigMgr->GetOption<uint32>("AutoBalance.LevelHigherOffset", 3, false), true);
|
||||
|
||||
if (sConfigMgr->GetOption<float>("AutoBalance.LevelLowerOffset", false, false))
|
||||
LOG_WARN("server.loading", "mod-autobalance: deprecated value `AutoBalance.LevelLowerOffset` defined in `AutoBalance.conf`. This variable will be removed in a future release. Please see `AutoBalance.conf.dist` for more details.");
|
||||
|
||||
LevelScalingSkipLowerLevels = sConfigMgr->GetOption<uint8>("AutoBalance.LevelScaling.SkipLowerLevels", sConfigMgr->GetOption<uint32>("AutoBalance.LevelLowerOffset", 5, false), true);
|
||||
|
||||
LevelScalingDynamicLevelCeilingDungeons = sConfigMgr->GetOption<uint8>("AutoBalance.LevelScaling.DynamicLevel.Ceiling.Dungeons", 1);
|
||||
LevelScalingDynamicLevelFloorDungeons = sConfigMgr->GetOption<uint8>("AutoBalance.LevelScaling.DynamicLevel.Floor.Dungeons", 5);
|
||||
LevelScalingDynamicLevelCeilingHeroicDungeons = sConfigMgr->GetOption<uint8>("AutoBalance.LevelScaling.DynamicLevel.Ceiling.HeroicDungeons", 2);
|
||||
LevelScalingDynamicLevelFloorHeroicDungeons = sConfigMgr->GetOption<uint8>("AutoBalance.LevelScaling.DynamicLevel.Floor.HeroicDungeons", 5);
|
||||
LevelScalingDynamicLevelCeilingRaids = sConfigMgr->GetOption<uint8>("AutoBalance.LevelScaling.DynamicLevel.Ceiling.Raids", 3);
|
||||
LevelScalingDynamicLevelFloorRaids = sConfigMgr->GetOption<uint8>("AutoBalance.LevelScaling.DynamicLevel.Floor.Raids", 5);
|
||||
LevelScalingDynamicLevelCeilingHeroicRaids = sConfigMgr->GetOption<uint8>("AutoBalance.LevelScaling.DynamicLevel.Ceiling.HeroicRaids", 3);
|
||||
LevelScalingDynamicLevelFloorHeroicRaids = sConfigMgr->GetOption<uint8>("AutoBalance.LevelScaling.DynamicLevel.Floor.HeroicRaids", 5);
|
||||
|
||||
if (sConfigMgr->GetOption<float>("AutoBalance.LevelEndGameBoost", false, false))
|
||||
LOG_WARN("server.loading", "mod-autobalance: deprecated value `AutoBalance.LevelEndGameBoost` defined in `AutoBalance.conf`. This variable will be removed in a future release. Please see `AutoBalance.conf.dist` for more details.");
|
||||
|
||||
LevelScalingEndGameBoost = sConfigMgr->GetOption<bool>("AutoBalance.LevelScaling.EndGameBoost", sConfigMgr->GetOption<bool>("AutoBalance.LevelEndGameBoost", 1, false), true);
|
||||
|
||||
if (LevelScalingEndGameBoost)
|
||||
{
|
||||
LOG_WARN("server.loading", "mod-autobalance: `AutoBalance.LevelScaling.EndGameBoost` is enabled in the configuration, but is not currently implemented. No effect.");
|
||||
LevelScalingEndGameBoost = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// RewardScaling.*
|
||||
// warn the console if deprecated values are detected
|
||||
//
|
||||
|
||||
if (sConfigMgr->GetOption<float>("AutoBalance.DungeonScaleDownXP", false, false))
|
||||
LOG_WARN("server.loading", "mod-autobalance: deprecated value `AutoBalance.DungeonScaleDownXP` defined in `AutoBalance.conf`. This variable will be removed in a future release. Please see `AutoBalance.conf.dist` for more details.");
|
||||
|
||||
if (sConfigMgr->GetOption<float>("AutoBalance.DungeonScaleDownMoney", false, false))
|
||||
LOG_WARN("server.loading", "mod-autobalance: deprecated value `AutoBalance.DungeonScaleDownMoney` defined in `AutoBalance.conf`. This variable will be removed in a future release. Please see `AutoBalance.conf.dist` for more details.");
|
||||
|
||||
std::string RewardScalingMethodString = sConfigMgr->GetOption<std::string>("AutoBalance.RewardScaling.Method", "dynamic", false);
|
||||
|
||||
if (RewardScalingMethodString == "fixed")
|
||||
RewardScalingMethod = AUTOBALANCE_SCALING_FIXED;
|
||||
else if (RewardScalingMethodString == "dynamic")
|
||||
RewardScalingMethod = AUTOBALANCE_SCALING_DYNAMIC;
|
||||
else
|
||||
{
|
||||
LOG_ERROR("server.loading", "mod-autobalance: invalid value `{}` for `AutoBalance.RewardScaling.Method` defined in `AutoBalance.conf`. Defaulting to a value of `dynamic`.", RewardScalingMethodString);
|
||||
RewardScalingMethod = AUTOBALANCE_SCALING_DYNAMIC;
|
||||
}
|
||||
|
||||
RewardScalingXP = sConfigMgr->GetOption<bool>("AutoBalance.RewardScaling.XP", sConfigMgr->GetOption<bool>("AutoBalance.DungeonScaleDownXP", true, false));
|
||||
RewardScalingXPModifier = sConfigMgr->GetOption<float>("AutoBalance.RewardScaling.XP.Modifier", 1.0f, false);
|
||||
|
||||
RewardScalingMoney = sConfigMgr->GetOption<bool>("AutoBalance.RewardScaling.Money", sConfigMgr->GetOption<bool>("AutoBalance.DungeonScaleDownMoney", true, false));
|
||||
RewardScalingMoneyModifier = sConfigMgr->GetOption<float>("AutoBalance.RewardScaling.Money.Modifier", 1.0f, false);
|
||||
|
||||
//
|
||||
// Announcement
|
||||
//
|
||||
|
||||
Announcement = sConfigMgr->GetOption<bool>("AutoBalanceAnnounce.enable", true);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
#ifndef __AB_WORLD_SCRIPT_H
|
||||
#define __AB_WORLD_SCRIPT_H
|
||||
|
||||
#include "WorldScript.h"
|
||||
|
||||
class AutoBalance_WorldScript : public WorldScript
|
||||
{
|
||||
public:
|
||||
AutoBalance_WorldScript()
|
||||
: WorldScript("AutoBalance_WorldScript", {
|
||||
WORLDHOOK_ON_BEFORE_CONFIG_LOAD
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
void OnBeforeConfigLoad(bool /*reload*/) override;
|
||||
|
||||
void SetInitialWorldSettings();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,6 @@
|
||||
void AddAutoBalanceScripts();
|
||||
|
||||
void Addmod_autobalanceScripts()
|
||||
{
|
||||
AddAutoBalanceScripts();
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2018 AzerothCore <http://www.azerothcore.org>
|
||||
* Copyright (C) 2012 CVMagic <http://www.trinitycore.org/f/topic/6551-vas-autobalance/>
|
||||
* Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/>
|
||||
* Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
|
||||
* Copyright (C) 1985-2010 KalCorp <http://vasserver.dyndns.org/>
|
||||
*
|
||||
* 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; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Script Name: AutoBalance
|
||||
* Original Authors: KalCorp and Vaughner
|
||||
* Maintainer(s): AzerothCore
|
||||
* Original Script Name: AutoBalance
|
||||
* Description: This script is intended to scale based on number of players,
|
||||
* instance mobs & world bosses' level, health, mana, and damage.
|
||||
*/
|
||||
|
||||
#include "AutoBalance.h"
|
||||
|
||||
#include "ABAllCreatureScript.h"
|
||||
#include "ABAllMapScript.h"
|
||||
#include "ABCommandScript.h"
|
||||
#include "ABConfig.h"
|
||||
#include "ABCreatureInfo.h"
|
||||
#include "ABGameObjectScript.h"
|
||||
#include "ABGlobalScript.h"
|
||||
#include "ABInflectionPointSettings.h"
|
||||
#include "ABLevelScalingDynamicLevelSettings.h"
|
||||
#include "ABMapInfo.h"
|
||||
#include "ABModuleScript.h"
|
||||
#include "ABPlayerScript.h"
|
||||
#include "ABScriptMgr.h"
|
||||
#include "ABStatModifiers.h"
|
||||
#include "ABUnitScript.h"
|
||||
#include "ABUtils.h"
|
||||
#include "ABWorldScript.h"
|
||||
|
||||
#include "Configuration/Config.h"
|
||||
#include "Chat.h"
|
||||
#include "Creature.h"
|
||||
#include "Group.h"
|
||||
#include "Language.h"
|
||||
#include "Log.h"
|
||||
#include "Map.h"
|
||||
#include "MapMgr.h"
|
||||
#include "Message.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptMgrMacros.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "Unit.h"
|
||||
#include "World.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
|
||||
#if AC_COMPILER == AC_COMPILER_GNU
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
void AddAutoBalanceScripts()
|
||||
{
|
||||
new AutoBalance_WorldScript();
|
||||
new AutoBalance_PlayerScript();
|
||||
new AutoBalance_UnitScript();
|
||||
new AutoBalance_GameObjectScript();
|
||||
new AutoBalance_AllCreatureScript();
|
||||
new AutoBalance_AllMapScript();
|
||||
new AutoBalance_CommandScript();
|
||||
new AutoBalance_GlobalScript();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef MOD_AUTOBALANCE_H
|
||||
#define MOD_AUTOBALANCE_H
|
||||
|
||||
enum ScalingMethod
|
||||
{
|
||||
AUTOBALANCE_SCALING_FIXED,
|
||||
AUTOBALANCE_SCALING_DYNAMIC
|
||||
};
|
||||
|
||||
enum BaseValueType
|
||||
{
|
||||
AUTOBALANCE_HEALTH,
|
||||
AUTOBALANCE_DAMAGE_HEALING
|
||||
};
|
||||
|
||||
enum Relevance
|
||||
{
|
||||
AUTOBALANCE_RELEVANCE_FALSE,
|
||||
AUTOBALANCE_RELEVANCE_TRUE,
|
||||
AUTOBALANCE_RELEVANCE_UNCHECKED
|
||||
};
|
||||
|
||||
enum Damage_Healing_Debug_Phase
|
||||
{
|
||||
AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_BEFORE,
|
||||
AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_AFTER
|
||||
};
|
||||
|
||||
struct World_Multipliers
|
||||
{
|
||||
float scaled = 1.0f;
|
||||
float unscaled = 1.0f;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,569 @@
|
||||
#include "Message.h"
|
||||
|
||||
#include "DatabaseEnv.h"
|
||||
#include "ItemTemplate.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_WELCOME_TO_PLAYER = {
|
||||
{LOCALE_enUS, "|cffc3dbff [AutoBalance]|r|cffFF8000 Welcome to {} ({}-player {}). There are {} player(s) in this instance. Difficulty set to {} player(s).|r"},
|
||||
{LOCALE_koKR, "|cffc3dbff [AutoBalance]|r|cffFF8000 {} ({}-player {})에 오신 것을 환영합니다. 이 인스턴스에는 {}명의 플레이어가 있습니다. 난이도가 {}명으로 설정되었습니다.|r"},
|
||||
{LOCALE_frFR, "|cffc3dbff [AutoBalance]|r|cffFF8000 Bienvenue dans {} ({} {}). Il y a {} joueur(s) dans cette instance. La difficulté est réglée sur {} joueur(s).|r"},
|
||||
{LOCALE_deDE, "|cffc3dbff [AutoBalance]|r|cffFF8000 Willkommen in {} ({} Spieler {}). Es gibt {} Spieler in dieser Instanz. Schwierigkeit auf {} Spieler eingestellt.|r"},
|
||||
{LOCALE_zhCN, "|cffc3dbff [AutoBalance]|r|cffFF8000 欢迎来到 {}({}人 {})。此副本中有 {} 名玩家。难度设置为 {} 名玩家。|r"},
|
||||
{LOCALE_zhTW, "|cffc3dbff [AutoBalance]|r|cffFF8000 歡迎來到 {}({}人 {})。此副本中有 {} 名玩家。難度設定為 {} 名玩家。|r"},
|
||||
{LOCALE_esES, "|cffc3dbff [AutoBalance]|r|cffFF8000 Bienvenido a {} ({} jugador {}). Hay {} jugador(es) en esta instancia. La dificultad se establece en {} jugador(es).|r"},
|
||||
{LOCALE_esMX, "|cffc3dbff [AutoBalance]|r|cffFF8000 Bienvenido a {} ({} jugador {}). Hay {} jugador(es) en esta instancia. La dificultad se establece en {} jugador(es).|r"},
|
||||
{LOCALE_ruRU, "|cffc3dbff [AutoBalance]|r|cffFF8000 Добро пожаловать в {} ({} игрок {}). В этом экземпляре {} игроков. Сложность установлена на {} игроков.|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_WELCOME_TO_GM = {
|
||||
{LOCALE_enUS, "|cffc3dbff [AutoBalance]|r|cffFF8000 Your GM flag is turned on. AutoBalance will ignore you. Please turn GM off and exit/re-enter the instance if you'd like to be considering for AutoBalancing.|r"},
|
||||
{LOCALE_koKR, "|cffc3dbff [AutoBalance]|r|cffFF8000 GM 플래그가 켜져 있습니다. AutoBalance는 당신을 무시합니다. AutoBalancing을 고려하려면 GM을 끄고 인스턴스를 나가고 다시 들어가십시오.|r"},
|
||||
{LOCALE_frFR, "|cffc3dbff [AutoBalance]|r|cffFF8000 Votre drapeau GM est activé. AutoBalance vous ignorera. Veuillez désactiver GM et sortir/revenir dans l'instance si vous souhaitez être pris en compte pour l'AutoBalancing.|r"},
|
||||
{LOCALE_deDE, "|cffc3dbff [AutoBalance]|r|cffFF8000 Ihre GM-Flagge ist eingeschaltet. AutoBalance wird Sie ignorieren. Bitte schalten Sie GM aus und verlassen Sie das Instanz, wenn Sie für das AutoBalancing berücksichtigt werden möchten.|r"},
|
||||
{LOCALE_zhCN, "|cffc3dbff [AutoBalance]|r|cffFF8000 您的GM模式已打开。AutoBalance将忽略。如果您希望考虑自动平衡,请关闭GM并退出/重新进入副本。|r"},
|
||||
{LOCALE_zhTW, "|cffc3dbff [AutoBalance]|r|cffFF8000 您的GM模式已打開。AutoBalance將忽略。如果您希望考慮自動平衡,請關閉GM並退出/重新進入副本。|r"},
|
||||
{LOCALE_esES, "|cffc3dbff [AutoBalance]|r|cffFF8000 Su bandera de GM está encendida. AutoBalance te ignorará. Por favor, apague GM y salga/vuelva a entrar en la instancia si desea ser considerado para el AutoBalance.|r"},
|
||||
{LOCALE_esMX, "|cffc3dbff [AutoBalance]|r|cffFF8000 Su bandera de GM está encendida. AutoBalance te ignorará. Por favor, apague GM y salga/vuelva a entrar en la instancia si desea ser considerado para el AutoBalance.|r"},
|
||||
{LOCALE_ruRU, "|cffc3dbff [AutoBalance]|r|cffFF8000 Ваш флаг GM включен. AutoBalance будет игнорировать вас. Пожалуйста, отключите GM и выйдите/войдите в экземпляр, если хотите, чтобы вас учитывали при автобалансировке.|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_ANNOUNCE_NON_GM_ENTERING_INSTANCE = {
|
||||
{LOCALE_enUS, "|cffc3dbff [AutoBalance]|r|cffFF8000 {} enters the instance. There are {} player(s) in this instance. Difficulty set to {} player(s).|r"},
|
||||
{LOCALE_koKR, "|cffc3dbff [AutoBalance]|r|cffFF8000 {}이(가) 인스턴스에 들어왔습니다. 이 인스턴스에는 {}명의 플레이어가 있습니다. 난이도가 {}명으로 설정되었습니다.|r"},
|
||||
{LOCALE_frFR, "|cffc3dbff [AutoBalance]|r|cffFF8000 {} entre dans l'instance. Il y a {} joueur(s) dans cette instance. La difficulté est réglée sur {} joueur(s).|r"},
|
||||
{LOCALE_deDE, "|cffc3dbff [AutoBalance]|r|cffFF8000 {} betritt die Instanz. Es gibt {} Spieler in dieser Instanz. Schwierigkeit auf {} Spieler eingestellt.|r"},
|
||||
{LOCALE_zhCN, "|cffc3dbff [AutoBalance]|r|cffFF8000 {}进入了副本。此副本中有 {} 名玩家。难度设置为 {} 名玩家。|r"},
|
||||
{LOCALE_zhTW, "|cffc3dbff [AutoBalance]|r|cffFF8000 {}進入了副本。此副本中有 {} 名玩家。難度設定為 {} 名玩家。|r"},
|
||||
{LOCALE_esES, "|cffc3dbff [AutoBalance]|r|cffFF8000 {} entra en la instancia. Hay {} jugador(es) en esta instancia. La dificultad se establece en {} jugador(es).|r"},
|
||||
{LOCALE_esMX, "|cffc3dbff [AutoBalance]|r|cffFF8000 {} entra en la instancia. Hay {} jugador(es) en esta instancia. La dificultad se establece en {} jugador(es).|r"},
|
||||
{LOCALE_ruRU, "|cffc3dbff [AutoBalance]|r|cffFF8000 {} входит в экземпляр. В этом экземпляре {} игроков. Сложность установлена на {} игроков.|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_LEAVING_INSTANCE_COMBAT = {
|
||||
{LOCALE_enUS, "|cffc3dbff [AutoBalance]|r|cffFF8000 {} left the instance while combat was in progress. Difficulty locked to no less than {} players until combat ends.|r"},
|
||||
{LOCALE_koKR, "|cffc3dbff [AutoBalance]|r|cffFF8000 {}이(가) 전투 중에 인스턴스를 떠났습니다. 전투가 끝날 때까지 난이도가 {}명 미만으로 잠겨 있습니다.|r"},
|
||||
{LOCALE_frFR, "|cffc3dbff [AutoBalance]|r|cffFF8000 {} a quitté l'instance alors que le combat était en cours. La difficulté est verrouillée à pas moins de {} joueur(s) jusqu'à la fin du combat.|r"},
|
||||
{LOCALE_deDE, "|cffc3dbff [AutoBalance]|r|cffFF8000 {} hat die Instanz verlassen, während der Kampf im Gange war. Die Schwierigkeit ist gesperrt, bis der Kampf endet, auf nicht weniger als {} Spieler.|r"},
|
||||
{LOCALE_zhCN, "|cffc3dbff [AutoBalance]|r|cffFF8000 {}在战斗进行中离开了副本。直到战斗结束,难度锁定为不少于 {} 名玩家。|r"},
|
||||
{LOCALE_zhTW, "|cffc3dbff [AutoBalance]|r|cffFF8000 {}在戰鬥進行中離開了副本。直到戰鬥結束,難度鎖定為不少於 {} 名玩家。|r"},
|
||||
{LOCALE_esES, "|cffc3dbff [AutoBalance]|r|cffFF8000 {} salió de la instancia mientras el combate estaba en progreso. La dificultad está bloqueada a no menos de {} jugador(es) hasta que termine el combate.|r"}
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_LEAVING_INSTANCE = {
|
||||
{LOCALE_enUS, "|cffc3dbff [AutoBalance]|r|cffFF8000 {} left the instance. There are {} player(s) in this instance. Difficulty set to {} player(s).|r"},
|
||||
{LOCALE_koKR, "|cffc3dbff [AutoBalance]|r|cffFF8000 {}이(가) 인스턴스를 떠났습니다. 이 인스턴스에는 {}명의 플레이어가 있습니다. 난이도가 {}명으로 설정되었습니다.|r"},
|
||||
{LOCALE_frFR, "|cffc3dbff [AutoBalance]|r|cffFF8000 {} a quitté l'instance. Il y a {} joueur(s) dans cette instance. La difficulté est réglée sur {} joueur(s).|r"},
|
||||
{LOCALE_deDE, "|cffc3dbff [AutoBalance]|r|cffFF8000 {} hat die Instanz verlassen. Es gibt {} Spieler in dieser Instanz. Schwierigkeit auf {} Spieler eingestellt.|r"},
|
||||
{LOCALE_zhCN, "|cffc3dbff [AutoBalance]|r|cffFF8000 {}离开了副本。此副本中有 {} 名玩家。难度设置为 {} 名玩家。|r"},
|
||||
{LOCALE_zhTW, "|cffc3dbff [AutoBalance]|r|cffFF8000 {}離開了副本。此副本中有 {} 名玩家。難度設定為 {} 名玩家。|r"},
|
||||
{LOCALE_esES, "|cffc3dbff [AutoBalance]|r|cffFF8000 {} salió de la instancia. Hay {} jugador(es) en esta instancia. La dificultad se establece en {} jugador(es).|r"},
|
||||
{LOCALE_esMX, "|cffc3dbff [AutoBalance]|r|cffFF8000 {} salió de la instancia. Hay {} jugador(es) en esta instancia. La dificultad se establece en {}"}
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_SET_OFFSET_COMMAND_DESCRIPTION = {
|
||||
{LOCALE_enUS, "Set the player difficulty offset for this instance. Usage: .ab offset <number>.|r"},
|
||||
{LOCALE_koKR, "이 인스턴스의 플레이어 난이도 오프셋을 설정합니다. 사용법: .ab offset <숫자>.|r"},
|
||||
{LOCALE_frFR, "Définissez le décalage de difficulté du joueur pour cette instance. Utilisation : .ab offset <nombre>.|r"},
|
||||
{LOCALE_deDE, "Legen Sie den Spieler-Schwierigkeits-Offset für diese Instanz fest. Verwendung: .ab offset <Nummer>.|r"},
|
||||
{LOCALE_zhCN, "设置此副本的玩家难度。用法:.ab offset <数字>。|r"},
|
||||
{LOCALE_zhTW, "設定此副本的玩家難度。用法:.ab offset <數字>。|r"},
|
||||
{LOCALE_esES, "Establece el desplazamiento de dificultad del jugador para esta instancia. Uso: .ab offset <número>.|r"},
|
||||
{LOCALE_esMX, "Establece el desplazamiento de dificultad del jugador para esta instancia. Uso: .ab offset <número>.|r"},
|
||||
{LOCALE_ruRU, "Устанавливает смещение сложности игрока для этого экземп"}
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_SET_OFFSET_COMMAND_SUCCESS = {
|
||||
{LOCALE_enUS, "Changing Player Difficulty Offset to {}.|r"},
|
||||
{LOCALE_koKR, "플레이어 난이도 오프셋을 {}(으)로 변경합니다.|r"},
|
||||
{LOCALE_frFR, "Modification du décalage de difficulté du joueur à {}.|r"},
|
||||
{LOCALE_deDE, "Spieler-Schwierigkeits-Offset auf {} ändern.|r"},
|
||||
{LOCALE_zhCN, "将玩家难度更改为 {}。|r"},
|
||||
{LOCALE_zhTW, "將玩家難度更改為 {}。|r"},
|
||||
{LOCALE_esES, "Cambiando el desplazamiento de dificultad del jugador a {}.|r"},
|
||||
{LOCALE_esMX, "Cambiando el desplazamiento de dificultad del jugador a {}.|r"},
|
||||
{LOCALE_ruRU, "Изменение смещения сложности игрока на {}.|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_SET_OFFSET_COMMAND_ERROR = {
|
||||
{LOCALE_enUS, "Error changing Player Difficulty Offset! Please try again.|r"},
|
||||
{LOCALE_koKR, "플레이어 난이도 오프셋 변경 중 오류가 발생했습니다! 다시 시도하십시오.|r"},
|
||||
{LOCALE_frFR, "Erreur lors de la modification du décalage de difficulté du joueur ! Veuillez réessayer.|r"},
|
||||
{LOCALE_deDE, "Fehler beim Ändern des Spieler-Schwierigkeits-Offsets! Bitte versuchen Sie es erneut.|r"},
|
||||
{LOCALE_zhCN, "更改玩家难度时出错!请重试。|r"},
|
||||
{LOCALE_zhTW, "更改玩家難度時出錯!請重試。|r"},
|
||||
{LOCALE_esES, "¡Error al cambiar el desplazamiento de dificultad del jugador! Por favor, inténtelo de nuevo.|r"},
|
||||
{LOCALE_esMX, "¡Error al cambiar el desplazamiento de dificultad del jugador! Por favor, inténtelo de nuevo.|r"},
|
||||
{LOCALE_ruRU, "Ошибка при изменении смещения сложности игрока! Пожалуйста, попробуйте еще раз.|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_GET_OFFSET_COMMAND_SUCCESS = {
|
||||
{LOCALE_enUS, "Current Player Difficulty Offset = {}.|r"},
|
||||
{LOCALE_koKR, "현재 플레이어 난이도 오프셋 = {}.|r"},
|
||||
{LOCALE_frFR, "Décalage de difficulté actuel du joueur = {}.|r"},
|
||||
{LOCALE_deDE, "Aktueller Spieler-Schwierigkeits-Offset = {}.|r"},
|
||||
{LOCALE_zhCN, "当前玩家难度偏移 = {}。|r"},
|
||||
{LOCALE_zhTW, "當前玩家難度偏移 = {}。|r"},
|
||||
{LOCALE_esES, "Desplazamiento de dificultad actual del jugador = {}.|r"},
|
||||
{LOCALE_esMX, "Desplazamiento de dificultad actual del jugador = {}.|r"},
|
||||
{LOCALE_ruRU, "Текущее смещение сложности игрока = {}.|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_ADJUSTED_PLAYER_COUNT_COMBAT_LOCKED = {
|
||||
{LOCALE_enUS, "Adjusted Player Count: {} (Combat Locked)|r"},
|
||||
{LOCALE_koKR, "조정된 플레이어 수: {} (전투 잠금됨)|r"},
|
||||
{LOCALE_frFR, "Nombre de joueurs ajusté : {} (verrouillé en combat)|r"},
|
||||
{LOCALE_deDE, "Angepasste Spieleranzahl: {} (Kampf gesperrt)|r"},
|
||||
{LOCALE_zhCN, "调整后的玩家数量:{}(战斗锁定)|r"},
|
||||
{LOCALE_zhTW, "調整後的玩家數量:{}(戰鬥鎖定)|r"},
|
||||
{LOCALE_esES, "Cantidad de jugadores ajustada: {} (bloqueada en combate)|r"},
|
||||
{LOCALE_esMX, "Cantidad de jugadores ajustada: {} (bloqueada en combate)|r"},
|
||||
{LOCALE_ruRU, "Количество игроков, отрегулированное: {} (заблокировано в бою)|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_ADJUSTED_PLAYER_COUNT_MAP_MINIMUM = {
|
||||
{LOCALE_enUS, "Adjusted Player Count: {} (Map Minimum)|r"},
|
||||
{LOCALE_koKR, "조정된 플레이어 수: {} (지도 최소)|r"},
|
||||
{LOCALE_frFR, "Nombre de joueurs ajusté : {} (minimum de la carte)|r"},
|
||||
{LOCALE_deDE, "Angepasste Spieleranzahl: {} (Kartenminimum)|r"},
|
||||
{LOCALE_zhCN, "调整后的玩家数量:{}(地图最小)|r"},
|
||||
{LOCALE_zhTW, "調整後的玩家數量:{}(地圖最小)|r"},
|
||||
{LOCALE_esES, "Cantidad de jugadores ajustada: {} (mínimo del mapa)|r"},
|
||||
{LOCALE_esMX, "Cantidad de jugadores ajustada: {} (mínimo del mapa)|r"},
|
||||
{LOCALE_ruRU, "Количество игроков, отрегулированное: {} (минимальное для карты)|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_ADJUSTED_PLAYER_COUNT_MAP_MINIMUM_DIFFICULTY_OFFSET = {
|
||||
{LOCALE_enUS, "Adjusted Player Count: {} (Map Minimum + Difficulty Offset of {})|r"},
|
||||
{LOCALE_koKR, "조정된 플레이어 수: {} (지도 최소 + {}의 난이도 오프셋)|r"},
|
||||
{LOCALE_frFR, "Nombre de joueurs ajusté : {} (minimum de la carte + décalage de difficulté de {})|r"},
|
||||
{LOCALE_deDE, "Angepasste Spieleranzahl: {} (Kartenminimum + Schwierigkeits-Offset von {})|r"},
|
||||
{LOCALE_zhCN, "调整后的玩家数量:{}(地图最小 + {}的难度修正)|r"},
|
||||
{LOCALE_zhTW, "調整後的玩家數量:{}(地圖最小 + {}的難度修正)|r"},
|
||||
{LOCALE_esES, "Cantidad de jugadores ajustada: {} (mínimo del mapa + desplazamiento de dificultad de {})|r"},
|
||||
{LOCALE_esMX, "Cantidad de jugadores ajustada: {} (mínimo del mapa + desplazamiento de dificultad de {})|r"},
|
||||
{LOCALE_ruRU, "Количество игроков, отрегулированное: {} (минимальное для карты"}
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_ADJUSTED_PLAYER_COUNT_DIFFICULTY_OFFSET = {
|
||||
{LOCALE_enUS, "Adjusted Player Count: {} (Difficulty Offset of {})|r"},
|
||||
{LOCALE_koKR, "조정된 플레이어 수: {} ({}의 난이도 오프셋)|r"},
|
||||
{LOCALE_frFR, "Nombre de joueurs ajusté : {} (décalage de difficulté de {})|r"},
|
||||
{LOCALE_deDE, "Angepasste Spieleranzahl: {} (Schwierigkeits-Offset von {})|r"},
|
||||
{LOCALE_zhCN, "调整后的玩家数量:{}({}的难度修正)|r"},
|
||||
{LOCALE_zhTW, "調整後的玩家數量:{}({}的難度修正)|r"},
|
||||
{LOCALE_esES, "Cantidad de jugadores ajustada: {} (desplazamiento de dificultad de {})|r"},
|
||||
{LOCALE_esMX, "Cantidad de jugadores ajustada: {} (desplazamiento de dificultad de {})|r"},
|
||||
{LOCALE_ruRU, "Количество игроков, отрегулированное: {} (смещение сложности {})|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_ADJUSTED_PLAYER_COUNT = {
|
||||
{LOCALE_enUS, "Adjusted Player Count: {}|r"},
|
||||
{LOCALE_koKR, "조정된 플레이어 수: {}|r"},
|
||||
{LOCALE_frFR, "Nombre de joueurs ajusté : {}|r"},
|
||||
{LOCALE_deDE, "Angepasste Spieleranzahl: {}|r"},
|
||||
{LOCALE_zhCN, "调整后的玩家数量:{}|r"},
|
||||
{LOCALE_zhTW, "調整後的玩家數量:{}|r"},
|
||||
{LOCALE_esES, "Cantidad de jugadores ajustada: {}|r"},
|
||||
{LOCALE_esMX, "Cantidad de jugadores ajustada: {}|r"},
|
||||
{LOCALE_ruRU, "Количество игроков, отрегулированное: {}|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_LFG_RANGE = {
|
||||
{LOCALE_enUS, "LFG Range: Lvl {} - {} (Target: Lvl {})|r"},
|
||||
{LOCALE_koKR, "LFG 범위: 레벨 {} - {} (대상: 레벨 {})|r"},
|
||||
{LOCALE_frFR, "Plage LFG : Niveau {} - {} (Cible : Niveau {})|r"},
|
||||
{LOCALE_deDE, "LFG-Bereich: Stufe {} - {} (Ziel: Stufe {})|r"},
|
||||
{LOCALE_zhCN, "LFG范围:等级 {} - {}(目标:等级 {})|r"},
|
||||
{LOCALE_zhTW, "LFG範圍:等級 {} - {}(目標:等級 {})|r"},
|
||||
{LOCALE_esES, "Rango de LFG: Nivel {} - {} (Objetivo: Nivel {})|r"},
|
||||
{LOCALE_esMX, "Rango de LFG: Nivel {} - {} (Objetivo: Nivel {})|r"},
|
||||
{LOCALE_ruRU, "Диапазон поиска группы: Ур. {} - {} (Цель: Ур. {})|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_MAP_LEVEL = {
|
||||
{LOCALE_enUS, "Map Level: {}{}|r"},
|
||||
{LOCALE_koKR, "지도 레벨: {}{}|r"},
|
||||
{LOCALE_frFR, "Niveau de la carte : {}{}|r"},
|
||||
{LOCALE_deDE, "Kartenlevel: {}{}|r"},
|
||||
{LOCALE_zhCN, "地图等级:{}{}|r"},
|
||||
{LOCALE_zhTW, "地圖等級:{}{}|r"},
|
||||
{LOCALE_esES, "Nivel del mapa: {}{}|r"},
|
||||
{LOCALE_esMX, "Nivel del mapa: {}{}|r"},
|
||||
{LOCALE_ruRU, "Уровень карты: {}{}|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_LEVEL_SCALING_ENABLED = {
|
||||
{LOCALE_enUS, " (Level Scaling Enabled)|r"},
|
||||
{LOCALE_koKR, " (레벨 스케일링 활성화됨)|r"},
|
||||
{LOCALE_frFR, " (Mise à l'échelle des niveaux activée)|r"},
|
||||
{LOCALE_deDE, " (Stufenanpassung aktiviert)|r"},
|
||||
{LOCALE_zhCN, " (启用等级自动平衡)|r"},
|
||||
{LOCALE_zhTW, " (啟用等級縮放平衡)|r"},
|
||||
{LOCALE_esES, " (Escalado de nivel activado)|r"},
|
||||
{LOCALE_esMX, " (Escalado de nivel activado)|r"},
|
||||
{LOCALE_ruRU, " (Масштабирование уровней включено)|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_LEVEL_SCALING_DISABLED = {
|
||||
{LOCALE_enUS, " (Level Scaling Disabled)|r"},
|
||||
{LOCALE_koKR, " (레벨 스케일링 비활성화됨)|r"},
|
||||
{LOCALE_frFR, " (Mise à l'échelle des niveaux désactivée)|r"},
|
||||
{LOCALE_deDE, " (Stufenanpassung deaktiviert)|r"},
|
||||
{LOCALE_zhCN, " (禁用等级自动平衡)|r"},
|
||||
{LOCALE_zhTW, " (停用等級縮放平衡)|r"},
|
||||
{LOCALE_esES, " (Escalado de nivel desactivado)|r"},
|
||||
{LOCALE_esMX, " (Escalado de nivel desactivado)|r"},
|
||||
{LOCALE_ruRU, " (Масштабирование уровней отключено)|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_WORLD_HEALTH_MULTIPLIER = {
|
||||
{LOCALE_enUS, "World health multiplier: {:.3f}|r"},
|
||||
{LOCALE_koKR, "월드 체력 배율: {:.3f}|r"},
|
||||
{LOCALE_frFR, "Multiplicateur de santé mondiale : {:.3f}|r"},
|
||||
{LOCALE_deDE, "Weltgesundheitsmultiplikator: {:.3f}|r"},
|
||||
{LOCALE_zhCN, "全局生命值倍率:{:.3f}|r"},
|
||||
{LOCALE_zhTW, "全局生命值倍增器:{:.3f}|r"},
|
||||
{LOCALE_esES, "Multiplicador de salud mundial: {:.3f}|r"},
|
||||
{LOCALE_esMX, "Multiplicador de salud mundial: {:.3f}|r"},
|
||||
{LOCALE_ruRU, "Множитель здоровья мира: {:.3f}|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_WORLD_HOSTILE_DAMAGE_HEALING_MULTIPLIER_TO = {
|
||||
{LOCALE_enUS, "World hostile damage and healing multiplier: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_koKR, "월드 적 대미지 및 치유 배율: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_frFR, "Multiplicateur de dégâts et de soins hostiles mondiaux : {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_deDE, "Weltweiter feindlicher Schadens- und Heilungs-Multiplikator: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_zhCN, "全局伤害和治疗倍率:{:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_zhTW, "全局敵對傷害和治療倍增器:{:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_esES, "Multiplicador de daño y curación hostil mundial: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_esMX, "Multiplicador de daño y curación hostil mundial: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_ruRU, "Множитель урона и лечения мира: {:.3f} -> {:.3f}|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_WORLD_HOSTILE_DAMAGE_HEALING_MULTIPLIER = {
|
||||
{LOCALE_enUS, "World hostile damage and healing multiplier: {:.3f}|r"},
|
||||
{LOCALE_koKR, "월드 적 대미지 및 치유 배율: {:.3f}|r"},
|
||||
{LOCALE_frFR, "Multiplicateur de dégâts et de soins hostiles mondiaux : {:.3f}|r"},
|
||||
{LOCALE_deDE, "Weltweiter feindlicher Schadens- und Heilungs-Multiplikator: {:.3f}|r"},
|
||||
{LOCALE_zhCN, "全局伤害和治疗倍率:{:.3f}|r"},
|
||||
{LOCALE_zhTW, "全局敵對傷害和治療倍增器:{:.3f}|r"},
|
||||
{LOCALE_esES, "Multiplicador de daño y curación hostil mundial: {:.3f}|r"},
|
||||
{LOCALE_esMX, "Multiplicador de daño y curación hostil mundial: {:.3f}|r"},
|
||||
{LOCALE_ruRU, "Множитель урона и лечения мира: {:.3f}|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_ORIGINAL_CREATURE_LEVEL_RANGE = {
|
||||
{LOCALE_enUS, "Original Creature Level Range: {} - {} (Avg: {:.2f})|r"},
|
||||
{LOCALE_koKR, "원래 크리쳐 레벨 범위: {} - {} (평균: {:.2f})|r"},
|
||||
{LOCALE_frFR, "Plage de niveaux de créatures d'origine : {} - {} (Moyenne : {:.2f})|r"},
|
||||
{LOCALE_deDE, "Originaler Kreaturenlevelbereich: {} - {} (Durchschnitt: {:.2f})|r"},
|
||||
{LOCALE_zhCN, "原始生物等级范围:{} - {}(平均:{:2.f})|r"},
|
||||
{LOCALE_zhTW, "原始生物等級範圍:{} - {}(平均:{:2.f})|r"},
|
||||
{LOCALE_esES, "Rango de niveles de criaturas originales: {} - {} (Promedio: {:.2f})|r"},
|
||||
{LOCALE_esMX, "Rango de niveles de criaturas originales: {} - {} (Promedio: {:.2f})|r"},
|
||||
{LOCALE_ruRU, "Исходный диапазон уровней существ: {} - {} (Среднее: {:.2f})|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_ACTIVE_TOTAL_CREATURES_IN_MAP = {
|
||||
{LOCALE_enUS, "Active | Total Creatures in map: {} | {}|r"},
|
||||
{LOCALE_koKR, "활성 | 지도 내 총 크리쳐: {} | {}|r"},
|
||||
{LOCALE_frFR, "Actif | Créatures totales dans la carte : {} | {}|r"},
|
||||
{LOCALE_deDE, "Aktiv | Gesamte Kreaturen in der Karte: {} | {}|r"},
|
||||
{LOCALE_zhCN, "Active | 地图中的总生物: {} | {}|r"},
|
||||
{LOCALE_zhTW, "Active | 地圖中的總生物: {} | {}|r"},
|
||||
{LOCALE_esES, "Activo | Criaturas totales en el mapa: {} | {}|r"},
|
||||
{LOCALE_esMX, "Activo | Criaturas totales en el mapa: {} | {}|r"},
|
||||
{LOCALE_ruRU, "Активные | Всего существ на карте: {} | {}|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_COMMAND_ONLY_IN_INSTANCE = {
|
||||
{LOCALE_enUS, "This command can only be used in a dungeon or raid.|r"},
|
||||
{LOCALE_koKR, "이 명령은 던전이나 공격대에서만 사용할 수 있습니다.|r"},
|
||||
{LOCALE_frFR, "Cette commande ne peut être utilisée que dans un donjon ou un raid.|r"},
|
||||
{LOCALE_deDE, "Dieser Befehl kann nur in einem Dungeon oder Schlachtzug verwendet werden.|r"},
|
||||
{LOCALE_zhCN, "此命令只能在地下城或团队副本中使用。|r"},
|
||||
{LOCALE_zhTW, "此命令只能在地城或團隊副本中使用。|r"},
|
||||
{LOCALE_esES, "Este comando solo se puede usar en una mazmorra o banda.|r"},
|
||||
{LOCALE_esMX, "Este comando solo se puede usar en una mazmorra o banda.|r"},
|
||||
{LOCALE_ruRU, "Эту команду можно использовать только в подземелье или рейде.|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_TARGET_NO_IN_INSTANCE = {
|
||||
{LOCALE_enUS, "That target is not in an instance.|r"},
|
||||
{LOCALE_koKR, "그 대상은 인스턴스에 있지 않습니다.|r"},
|
||||
{LOCALE_frFR, "Cette cible n'est pas dans une instance.|r"},
|
||||
{LOCALE_deDE, "Dieses Ziel befindet sich nicht in einer Instanz.|r"},
|
||||
{LOCALE_zhCN, "该目标不在副本中。|r"},
|
||||
{LOCALE_zhTW, "該目標不在副本中。|r"},
|
||||
{LOCALE_esES, "Ese objetivo no está en una instancia.|r"},
|
||||
{LOCALE_esMX, "Ese objetivo no está en una instancia.|r"},
|
||||
{LOCALE_ruRU, "Эта цель не находится в подземелье.|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_ACTIVE_FOR_MAP_STATS = {
|
||||
{LOCALE_enUS, "Active for Map Stats|r"},
|
||||
{LOCALE_koKR, "지도 통계용 활성|r"},
|
||||
{LOCALE_frFR, "Actif pour les statistiques de la carte|r"},
|
||||
{LOCALE_deDE, "Aktiv für Kartenstatistiken|r"},
|
||||
{LOCALE_zhCN, "地图平衡激活|r"},
|
||||
{LOCALE_zhTW, "地圖平衡激活|r"},
|
||||
{LOCALE_esES, "Activo para estadísticas del mapa|r"},
|
||||
{LOCALE_esMX, "Activo para estadísticas del mapa|r"},
|
||||
{LOCALE_ruRU, "Активно для статистики карты|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_IGNORED_FOR_MAP_STATS = {
|
||||
{LOCALE_enUS, "Ignored for Map Stats|r"},
|
||||
{LOCALE_koKR, "지도 통계용 무시됨|r"},
|
||||
{LOCALE_frFR, "Ignoré pour les statistiques de la carte|r"},
|
||||
{LOCALE_deDE, "Ignoriert für Kartenstatistiken|r"},
|
||||
{LOCALE_zhCN, "地图平衡已忽略|r"},
|
||||
{LOCALE_zhTW, "地圖平衡已忽略|r"},
|
||||
{LOCALE_esES, "Ignorado para estadísticas del mapa|r"},
|
||||
{LOCALE_esMX, "Ignorado para estadísticas del mapa|r"},
|
||||
{LOCALE_ruRU, "Игнорируется для статистики карты|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_CREATURE_DIFFICULTY_LEVEL = {
|
||||
{LOCALE_enUS, "Creature difficulty level: {} player(s)|r"},
|
||||
{LOCALE_koKR, "생물 난이도 레벨: {} 플레이어|r"},
|
||||
{LOCALE_frFR, "Niveau de difficulté de la créature : {} joueur(s)|r"},
|
||||
{LOCALE_deDE, "Kreaturschwierigkeitsstufe: {} Spieler|r"},
|
||||
{LOCALE_zhCN, "生物难度等级:{} 玩家|r"},
|
||||
{LOCALE_zhTW, "生物難度等級:{} 玩家|r"},
|
||||
{LOCALE_esES, "Nivel de dificultad de la criatura: {} jugador(es)|r"},
|
||||
{LOCALE_esMX, "Nivel de dificultad de la criatura: {} jugador(es)|r"},
|
||||
{LOCALE_ruRU, "Уровень сложности существа: {} игрок(ов)|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_CLONE_OF_SUMMON = {
|
||||
{LOCALE_enUS, "Clone of {} ({})|r"},
|
||||
{LOCALE_koKR, "{}의 복제 ({})|r"},
|
||||
{LOCALE_frFR, "Clone de {} ({})|r"},
|
||||
{LOCALE_deDE, "Klon von {} ({})|r"},
|
||||
{LOCALE_zhCN, "{}的克隆({})|r"},
|
||||
{LOCALE_zhTW, "{}的克隆({})|r"},
|
||||
{LOCALE_esES, "Clon de {} ({})|r"},
|
||||
{LOCALE_esMX, "Clon de {} ({})|r"},
|
||||
{LOCALE_ruRU, "Клон {} ({})|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_SUMMON_OF_SUMMON = {
|
||||
{LOCALE_enUS, "Summon of {} ({})|r"},
|
||||
{LOCALE_koKR, "{}의 소환 ({})|r"},
|
||||
{LOCALE_frFR, "Invocation de {} ({})|r"},
|
||||
{LOCALE_deDE, "Beschwörung von {} ({})|r"},
|
||||
{LOCALE_zhCN, "{}的召唤({})|r"},
|
||||
{LOCALE_zhTW, "{}的召喚({})|r"},
|
||||
{LOCALE_esES, "Invocación de {} ({})|r"},
|
||||
{LOCALE_esMX, "Invocación de {} ({})|r"},
|
||||
{LOCALE_ruRU, "Призыв {} ({})|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_SUMMON_WITHOUT_SUMMONER = {
|
||||
{LOCALE_enUS, "Summon without a summoner.|r"},
|
||||
{LOCALE_koKR, "소환사 없는 소환.|r"},
|
||||
{LOCALE_frFR, "Invocation sans invocateur.|r"},
|
||||
{LOCALE_deDE, "Beschwörung ohne Beschwörer.|r"},
|
||||
{LOCALE_zhCN, "没有召唤者的召唤物。|r"},
|
||||
{LOCALE_zhTW, "沒有召喚者的召喚物。|r"},
|
||||
{LOCALE_esES, "Invocación sin invocador.|r"},
|
||||
{LOCALE_esMX, "Invocación sin invocador.|r"},
|
||||
{LOCALE_ruRU, "Призыв без призывателя.|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_HEALTH_MULTIPLIER_TO = {
|
||||
{LOCALE_enUS, "Health multiplier: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_koKR, "체력 배율: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_frFR, "Multiplicateur de santé : {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_deDE, "Gesundheitsmultiplikator: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_zhCN, "生命值倍率:{:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_zhTW, "生命值倍增器:{:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_esES, "Multiplicador de salud: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_esMX, "Multiplicador de salud: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_ruRU, "Множитель здоровья: {:.3f} -> {:.3f}|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_MANA_MULTIPLIER_TO = {
|
||||
{LOCALE_enUS, "Mana multiplier: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_koKR, "마나 배율: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_frFR, "Multiplicateur de mana : {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_deDE, "Manamultiplikator: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_zhCN, "法力值倍率:{:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_zhTW, "法力值倍增器:{:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_esES, "Multiplicador de maná: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_esMX, "Multiplicador de maná: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_ruRU, "Множитель маны: {:.3f} -> {:.3f}|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_ARMOR_MULTIPLIER_TO = {
|
||||
{LOCALE_enUS, "Armor multiplier: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_koKR, "방어구 배율: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_frFR, "Multiplicateur d'armure : {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_deDE, "Rüstungsmultiplikator: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_zhCN, "护甲倍率:{:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_zhTW, "護甲倍增器:{:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_esES, "Multiplicador de armadura: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_esMX, "Multiplicador de armadura: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_ruRU, "Множитель брони: {:.3f} -> {:.3f}|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_DAMAGE_MULTIPLIER_TO = {
|
||||
{LOCALE_enUS, "Damage multiplier: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_koKR, "피해 배율: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_frFR, "Multiplicateur de dégâts : {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_deDE, "Schadensmultiplikator: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_zhCN, "伤害倍率:{:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_zhTW, "傷害倍增器:{:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_esES, "Multiplicador de daño: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_esMX, "Multiplicador de daño: {:.3f} -> {:.3f}|r"},
|
||||
{LOCALE_ruRU, "Множитель урона: {:.3f} -> {:.3f}|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_HEALTH_MULTIPLIER = {
|
||||
{LOCALE_enUS, "Health multiplier: {:.3f}|r"},
|
||||
{LOCALE_koKR, "체력 배율: {:.3f}|r"},
|
||||
{LOCALE_frFR, "Multiplicateur de santé : {:.3f}|r"},
|
||||
{LOCALE_deDE, "Gesundheitsmultiplikator: {:.3f}|r"},
|
||||
{LOCALE_zhCN, "生命值倍率:{:.3f}|r"},
|
||||
{LOCALE_zhTW, "生命值倍增器:{:.3f}|r"},
|
||||
{LOCALE_esES, "Multiplicador de salud: {:.3f}|r"},
|
||||
{LOCALE_esMX, "Multiplicador de salud: {:.3f}|r"},
|
||||
{LOCALE_ruRU, "Множитель здоровья: {:.3f}|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_MANA_MULTIPLIER = {
|
||||
{LOCALE_enUS, "Mana multiplier: {:.3f}|r"},
|
||||
{LOCALE_koKR, "마나 배율: {:.3f}|r"},
|
||||
{LOCALE_frFR, "Multiplicateur de mana : {:.3f}|r"},
|
||||
{LOCALE_deDE, "Manamultiplikator: {:.3f}|r"},
|
||||
{LOCALE_zhCN, "法力值倍率:{:.3f}|r"},
|
||||
{LOCALE_zhTW, "法力值倍增器:{:.3f}|r"},
|
||||
{LOCALE_esES, "Multiplicador de maná: {:.3f}|r"},
|
||||
{LOCALE_esMX, "Multiplicador de maná: {:.3f}|r"},
|
||||
{LOCALE_ruRU, "Множитель маны: {:.3f}|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_ARMOR_MULTIPLIER = {
|
||||
{LOCALE_enUS, "Armor multiplier: {:.3f}|r"},
|
||||
{LOCALE_koKR, "방어구 배율: {:.3f}|r"},
|
||||
{LOCALE_frFR, "Multiplicateur d'armure : {:.3f}|r"},
|
||||
{LOCALE_deDE, "Rüstungsmultiplikator: {:.3f}|r"},
|
||||
{LOCALE_zhCN, "护甲倍率:{:.3f}|r"},
|
||||
{LOCALE_zhTW, "護甲倍增器:{:.3f}|r"},
|
||||
{LOCALE_esES, "Multiplicador de armadura: {:.3f}|r"},
|
||||
{LOCALE_esMX, "Multiplicador de armadura: {:.3f}|r"},
|
||||
{LOCALE_ruRU, "Множитель брони: {:.3f}|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_DAMAGE_MULTIPLIER = {
|
||||
{LOCALE_enUS, "Damage multiplier: {:.3f}|r"},
|
||||
{LOCALE_koKR, "피해 배율: {:.3f}|r"},
|
||||
{LOCALE_frFR, "Multiplicateur de dégâts : {:.3f}|r"},
|
||||
{LOCALE_deDE, "Schadensmultiplikator: {:.3f}|r"},
|
||||
{LOCALE_zhCN, "伤害倍率:{:.3f}|r"},
|
||||
{LOCALE_zhTW, "傷害倍增器:{:.3f}|r"},
|
||||
{LOCALE_esES, "Multiplicador de daño: {:.3f}|r"},
|
||||
{LOCALE_esMX, "Multiplicador de daño: {:.3f}|r"},
|
||||
{LOCALE_ruRU, "Множитель урона: {:.3f}|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_CC_DURATION_MULTIPLIER = {
|
||||
{LOCALE_enUS, "CC Duration multiplier: {:.3f}|r"},
|
||||
{LOCALE_koKR, "CC 지속시간 배율: {:.3f}|r"},
|
||||
{LOCALE_frFR, "Multiplicateur de durée de la CC : {:.3f}|r"},
|
||||
{LOCALE_deDE, "CC-Dauer-Multiplikator: {:.3f}|r"},
|
||||
{LOCALE_zhCN, "控制持续时间倍率:{:.3f}|r"},
|
||||
{LOCALE_zhTW, "控制持續時間倍增器:{:.3f}|r"},
|
||||
{LOCALE_esES, "Multiplicador de duración de CC: {:.3f}|r"},
|
||||
{LOCALE_esMX, "Multiplicador de duración de CC: {:.3f}|r"},
|
||||
{LOCALE_ruRU, "Множитель длительности контроля: {:.3f}|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_XP_MONEY_MULTIPLIER = {
|
||||
{LOCALE_enUS, "XP multiplier: {:.3f} Money multiplier: {:.3f}|r"},
|
||||
{LOCALE_koKR, "경험치 배율: {:.3f} 돈 배율: {:.3f}|r"},
|
||||
{LOCALE_frFR, "Multiplicateur d'XP : {:.3f} Multiplicateur d'argent : {:.3f}|r"},
|
||||
{LOCALE_deDE, "XP-Multiplikator: {:.3f} Geldmultiplikator: {:.3f}|r"},
|
||||
{LOCALE_zhCN, "经验值倍率:{:.3f} 金钱倍率:{:.3f}|r"},
|
||||
{LOCALE_zhTW, "經驗值倍增器:{:.3f} 金錢倍增器:{:.3f}|r"},
|
||||
{LOCALE_esES, "Multiplicador de XP: {:.3f} Multiplicador de dinero: {:.3f}|r"},
|
||||
{LOCALE_esMX, "Multiplicador de XP: {:.3f} Multiplicador de dinero: {:.3f}|r"},
|
||||
{LOCALE_ruRU, "Множитель опыта: {:.3f} Множитель денег: {:.3f}|r"},
|
||||
};
|
||||
|
||||
const std::unordered_map<LocaleConstant, std::string> AB_LEAVING_INSTANCE_COMBAT_CHANGE = {
|
||||
{LOCALE_enUS, "|cffc3dbff [AutoBalance]|r|cffFF8000 Combat has ended. Difficulty is no longer locked.|r"},
|
||||
{LOCALE_koKR, "|cffc3dbff [AutoBalance]|r|cffFF8000 전투가 종료되었습니다. 난이도가 더 이상 잠겨 있지 않습니다.|r"},
|
||||
{LOCALE_frFR, "|cffc3dbff [AutoBalance]|r|cffFF8000 Le combat est terminé. La difficulté n'est plus verrouillée.|r"},
|
||||
{LOCALE_deDE, "|cffc3dbff [AutoBalance]|r|cffFF8000 Der Kampf ist vorbei. Die Schwierigkeit ist nicht mehr gesperrt.|r"},
|
||||
{LOCALE_zhCN, "|cffc3dbff [AutoBalance]|r|cffFF8000 战斗结束了。难度不再被锁定。|r"},
|
||||
{LOCALE_zhTW, "|cffc3dbff [AutoBalance]|r|cffFF8000 戰鬥已結束。難度不再被鎖定。|r"},
|
||||
{LOCALE_esES, "|cffc3dbff [AutoBalance]|r|cffFF8000 El combate ha terminado. La dificultad ya no está bloqueada.|r"},
|
||||
{LOCALE_esMX, "|cffc3dbff [AutoBalance]|r|cffFF8000 El combate ha terminado. La dificultad ya no está bloqueada.|r"},
|
||||
{LOCALE_ruRU, "|cffc3dbff [AutoBalance]|r|cffFF8000 Бой окончен. Сложность больше не заблокирована.|r"},
|
||||
};
|
||||
|
||||
std::unordered_map<std::string, const std::unordered_map<LocaleConstant, std::string>*> abTextMaps = {
|
||||
{"welcome_to_player", &AB_WELCOME_TO_PLAYER},
|
||||
{"welcome_to_gm", &AB_WELCOME_TO_GM},
|
||||
{"announce_non_gm_entering_instance", &AB_ANNOUNCE_NON_GM_ENTERING_INSTANCE},
|
||||
{"leaving_instance_combat", &AB_LEAVING_INSTANCE_COMBAT},
|
||||
{"leaving_instance", &AB_LEAVING_INSTANCE},
|
||||
{"set_offset_command_description", &AB_SET_OFFSET_COMMAND_DESCRIPTION},
|
||||
{"set_offset_command_success", &AB_SET_OFFSET_COMMAND_SUCCESS},
|
||||
{"set_offset_command_error", &AB_SET_OFFSET_COMMAND_ERROR},
|
||||
{"get_offset_command_success", &AB_GET_OFFSET_COMMAND_SUCCESS},
|
||||
{"adjusted_player_count_combat_locked", &AB_ADJUSTED_PLAYER_COUNT_COMBAT_LOCKED},
|
||||
{"adjusted_player_count_map_minimum", &AB_ADJUSTED_PLAYER_COUNT_MAP_MINIMUM},
|
||||
{"adjusted_player_count_map_minimum_difficulty_offset", &AB_ADJUSTED_PLAYER_COUNT_MAP_MINIMUM_DIFFICULTY_OFFSET},
|
||||
{"adjusted_player_count_difficulty_offset", &AB_ADJUSTED_PLAYER_COUNT_DIFFICULTY_OFFSET},
|
||||
{"adjusted_player_count", &AB_ADJUSTED_PLAYER_COUNT},
|
||||
{"lfg_range", &AB_LFG_RANGE},
|
||||
{"map_level", &AB_MAP_LEVEL},
|
||||
{"level_scaling_enabled", &AB_LEVEL_SCALING_ENABLED},
|
||||
{"level_scaling_disabled", &AB_LEVEL_SCALING_DISABLED},
|
||||
{"world_health_multiplier", &AB_WORLD_HEALTH_MULTIPLIER},
|
||||
{"world_hostile_damage_healing_multiplier_to", &AB_WORLD_HOSTILE_DAMAGE_HEALING_MULTIPLIER_TO},
|
||||
{"world_hostile_damage_healing_multiplier", &AB_WORLD_HOSTILE_DAMAGE_HEALING_MULTIPLIER},
|
||||
{"original_creature_level_range", &AB_ORIGINAL_CREATURE_LEVEL_RANGE},
|
||||
{"active_total_creatures_in_map", &AB_ACTIVE_TOTAL_CREATURES_IN_MAP},
|
||||
{"ab_command_only_in_instance", &AB_COMMAND_ONLY_IN_INSTANCE},
|
||||
{"target_no_in_instance", &AB_TARGET_NO_IN_INSTANCE},
|
||||
{"active_for_map_stats", &AB_ACTIVE_FOR_MAP_STATS},
|
||||
{"ignored_for_map_stats", &AB_IGNORED_FOR_MAP_STATS},
|
||||
{"creature_difficulty_level", &AB_CREATURE_DIFFICULTY_LEVEL},
|
||||
{"clone_of_summon", &AB_CLONE_OF_SUMMON},
|
||||
{"summon_of_summon", &AB_SUMMON_OF_SUMMON},
|
||||
{"summon_without_summoner", &AB_SUMMON_WITHOUT_SUMMONER},
|
||||
{"health_multiplier_to", &AB_HEALTH_MULTIPLIER_TO},
|
||||
{"mana_multiplier_to", &AB_MANA_MULTIPLIER_TO},
|
||||
{"armor_multiplier_to", &AB_ARMOR_MULTIPLIER_TO},
|
||||
{"damage_multiplier_to", &AB_DAMAGE_MULTIPLIER_TO},
|
||||
{"health_multiplier", &AB_HEALTH_MULTIPLIER},
|
||||
{"mana_multiplier", &AB_MANA_MULTIPLIER},
|
||||
{"armor_multiplier", &AB_ARMOR_MULTIPLIER},
|
||||
{"damage_multiplier", &AB_DAMAGE_MULTIPLIER},
|
||||
{"cc_duration_multiplier", &AB_CC_DURATION_MULTIPLIER},
|
||||
{"xp_money_multiplier", &AB_XP_MONEY_MULTIPLIER},
|
||||
{"leaving_instance_combat_change", &AB_LEAVING_INSTANCE_COMBAT_CHANGE},
|
||||
};
|
||||
|
||||
std::string ABGetLocaleText(LocaleConstant locale, const std::string& titleType) {
|
||||
auto textMapIt = abTextMaps.find(titleType);
|
||||
if (textMapIt != abTextMaps.end())
|
||||
{
|
||||
const std::unordered_map<LocaleConstant, std::string>* textMap = textMapIt->second;
|
||||
auto it = textMap->find(locale);
|
||||
if (it != textMap->end())
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// Message.h
|
||||
#ifndef AB_MESSAGE_H
|
||||
#define AB_MESSAGE_H
|
||||
|
||||
#include "Common.h"
|
||||
#include "ItemTemplate.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
std::string ABGetLocaleText(LocaleConstant locale, const std::string& titleType);
|
||||
|
||||
#endif // AB_MESSAGE_H
|
||||
Reference in New Issue
Block a user