Advertisement
Guest User

VAS_Autobalance-9_3_2012

a guest
Sep 13th, 2020
241
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 47.35 KB | None | 0 0
  1. diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
  2. index afa4b62..c67554c 100755
  3. --- a/src/server/game/Entities/Creature/Creature.cpp
  4. +++ b/src/server/game/Entities/Creature/Creature.cpp
  5. @@ -1181,6 +1181,7 @@ void Creature::SelectLevel(const CreatureTemplate* cinfo)
  6.  
  7.      SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, cinfo->attackpower * damagemod);
  8.  
  9. +    sScriptMgr->Creature_SelectLevel(cinfo, this);
  10.  }
  11.  
  12.  float Creature::_GetHealthMod(int32 Rank)
  13. diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
  14. index 5118b58..723d504 100755
  15. --- a/src/server/game/Entities/Unit/Unit.cpp
  16. +++ b/src/server/game/Entities/Unit/Unit.cpp
  17. @@ -942,6 +942,9 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
  18.      SpellSchoolMask damageSchoolMask = SpellSchoolMask(damageInfo->schoolMask);
  19.      uint32 crTypeMask = victim->GetCreatureTypeMask();
  20.  
  21. +    //Hook For CalculateSpellDamageTaken
  22. +    sScriptMgr->CalculateSpellDamageTaken(damageInfo, damage, spellInfo, attackType, crit);
  23. +
  24.      if (IsDamageReducedByArmor(damageSchoolMask, spellInfo))
  25.          damage = CalcArmorReducedDamage(victim, damage, spellInfo, attackType);
  26.  
  27. @@ -1120,6 +1123,9 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam
  28.      damage = MeleeDamageBonusDone(damageInfo->target, damage, damageInfo->attackType);
  29.      damage = damageInfo->target->MeleeDamageBonusTaken(this, damage, damageInfo->attackType);
  30.  
  31. +    //Hook For CalculateMeleeDamage
  32. +    sScriptMgr->CalculateMeleeDamage(victim, damage, damageInfo, attackType);
  33. +
  34.      // Calculate armor reduction
  35.      if (IsDamageReducedByArmor((SpellSchoolMask)(damageInfo->damageSchoolMask)))
  36.      {
  37. diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
  38. index fc56106..b69297b 100755
  39. --- a/src/server/game/Scripting/ScriptLoader.cpp
  40. +++ b/src/server/game/Scripting/ScriptLoader.cpp
  41. @@ -17,6 +17,9 @@
  42.  
  43.  #include "ScriptLoader.h"
  44.  
  45. +//VAS.AutoBalance
  46. +void AddSC_VAS_AutoBalance();
  47. +
  48.  //examples
  49.  void AddSC_example_creature();
  50.  void AddSC_example_escort();
  51. @@ -1265,6 +1268,7 @@ void AddCustomScripts()
  52.  {
  53.  #ifdef SCRIPTS
  54.      /* This is where custom scripts should be added. */
  55. +    AddSC_VAS_AutoBalance();
  56.  
  57.  #endif
  58.  }
  59. diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
  60. index 47ce6c1..a128323 100755
  61. --- a/src/server/game/Scripting/ScriptMgr.cpp
  62. +++ b/src/server/game/Scripting/ScriptMgr.cpp
  63. @@ -271,10 +271,12 @@ void ScriptMgr::Unload()
  64.      SCR_CLEAR(ServerScript);
  65.      SCR_CLEAR(WorldScript);
  66.      SCR_CLEAR(FormulaScript);
  67. +    SCR_CLEAR(AllMapScript);
  68.      SCR_CLEAR(WorldMapScript);
  69.      SCR_CLEAR(InstanceMapScript);
  70.      SCR_CLEAR(BattlegroundMapScript);
  71.      SCR_CLEAR(ItemScript);
  72. +    SCR_CLEAR(AllCreatureScript);
  73.      SCR_CLEAR(CreatureScript);
  74.      SCR_CLEAR(GameObjectScript);
  75.      SCR_CLEAR(AreaTriggerScript);
  76. @@ -291,6 +293,7 @@ void ScriptMgr::Unload()
  77.      SCR_CLEAR(PlayerScript);
  78.      SCR_CLEAR(GuildScript);
  79.      SCR_CLEAR(GroupScript);
  80. +    SCR_CLEAR(UnitScript);
  81.  
  82.      #undef SCR_CLEAR
  83.  }
  84. @@ -652,6 +655,8 @@ void ScriptMgr::OnUnloadGridMap(Map* map, GridMap* gmap, uint32 gx, uint32 gy)
  85.  
  86.  void ScriptMgr::OnPlayerEnterMap(Map* map, Player* player)
  87.  {
  88. +    FOREACH_SCRIPT(AllMapScript)->OnPlayerEnterAll(map, player);
  89. +
  90.      ASSERT(map);
  91.      ASSERT(player);
  92.  
  93. @@ -670,6 +675,8 @@ void ScriptMgr::OnPlayerEnterMap(Map* map, Player* player)
  94.  
  95.  void ScriptMgr::OnPlayerLeaveMap(Map* map, Player* player)
  96.  {
  97. +    FOREACH_SCRIPT(AllMapScript)->OnPlayerLeaveAll(map, player);
  98. +
  99.      ASSERT(map);
  100.      ASSERT(player);
  101.  
  102. @@ -863,12 +870,18 @@ GameObjectAI* ScriptMgr::GetGameObjectAI(GameObject* gameobject)
  103.  
  104.  void ScriptMgr::OnCreatureUpdate(Creature* creature, uint32 diff)
  105.  {
  106. +    FOREACH_SCRIPT(AllCreatureScript)->OnAllCreatureUpdate(creature, diff);
  107.      ASSERT(creature);
  108.  
  109.      GET_SCRIPT(CreatureScript, creature->GetScriptId(), tmpscript);
  110.      tmpscript->OnUpdate(creature, diff);
  111.  }
  112.  
  113. +void ScriptMgr::Creature_SelectLevel(const CreatureTemplate *cinfo, Creature* creature)
  114. +{
  115. +    FOREACH_SCRIPT(AllCreatureScript)->Creature_SelectLevel(cinfo, creature);
  116. +}
  117. +
  118.  bool ScriptMgr::OnGossipHello(Player* player, GameObject* go)
  119.  {
  120.      ASSERT(player);
  121. @@ -1186,6 +1199,23 @@ void ScriptMgr::OnShutdown()
  122.      FOREACH_SCRIPT(WorldScript)->OnShutdown();
  123.  }
  124.  
  125. +void ScriptMgr::SetInitialWorldSettings()
  126. +{
  127. +    FOREACH_SCRIPT(WorldScript)->SetInitialWorldSettings();
  128. +}
  129. +
  130. +float ScriptMgr::VAS_Script_Hooks()
  131. +{
  132. +    float VAS_Script_Hook_Version = 1.03f;
  133. +
  134. +    sLog->outInfo(LOG_FILTER_WORLDSERVER, "----------------------------------------------------");
  135. +    sLog->outInfo(LOG_FILTER_WORLDSERVER, "  Powered by {VAS} Script Hooks v%4.2f",VAS_Script_Hook_Version);
  136. +    sLog->outInfo(LOG_FILTER_WORLDSERVER, "----------------------------------------------------");
  137. +
  138. +    return VAS_Script_Hook_Version;
  139. +}
  140. +
  141. +
  142.  bool ScriptMgr::OnCriteriaCheck(AchievementCriteriaData const* data, Player* source, Unit* target)
  143.  {
  144.      ASSERT(source);
  145. @@ -1414,6 +1444,37 @@ void ScriptMgr::OnGroupDisband(Group* group)
  146.      FOREACH_SCRIPT(GroupScript)->OnDisband(group);
  147.  }
  148.  
  149. +//Called From Unit::DealDamage
  150. +uint32 ScriptMgr::DealDamage(Unit* AttackerUnit, Unit *pVictim, uint32 damage, DamageEffectType damagetype)
  151. +{
  152. +    FOR_SCRIPTS_RET(UnitScript, itr, end, damage)
  153. +        damage = itr->second->DealDamage(AttackerUnit, pVictim, damage, damagetype);
  154. +    return damage;
  155. +}
  156. +
  157. +uint32 ScriptMgr::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster, int32 damage)
  158. +{
  159. +    FOR_SCRIPTS_RET(UnitScript, itr, end, damage)
  160. +        damage = itr->second->HandlePeriodicDamageAurasTick(target, caster, damage);
  161. +    return damage;
  162. +}
  163. +
  164. +void ScriptMgr::CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType, bool crit)
  165. +{
  166. +    FOREACH_SCRIPT(UnitScript)->CalculateSpellDamageTaken(damageInfo, damage, spellInfo, attackType, crit);
  167. +}
  168. +
  169. +void ScriptMgr::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *damageInfo, WeaponAttackType attackType)
  170. +{
  171. +    FOREACH_SCRIPT(UnitScript)->CalculateMeleeDamage(pVictim, damage, damageInfo, attackType);
  172. +}
  173. +
  174. +UnitScript::UnitScript(const char* name)
  175. +: ScriptObject(name)
  176. +{
  177. +    ScriptRegistry<UnitScript>::AddScript(this);
  178. +}
  179. +
  180.  SpellScriptLoader::SpellScriptLoader(const char* name)
  181.      : ScriptObject(name)
  182.  {
  183. @@ -1438,6 +1499,12 @@ FormulaScript::FormulaScript(const char* name)
  184.      ScriptRegistry<FormulaScript>::AddScript(this);
  185.  }
  186.  
  187. +AllMapScript::AllMapScript(const char* name)
  188. +    : ScriptObject(name)
  189. +{
  190. +    ScriptRegistry<AllMapScript>::AddScript(this);
  191. +}
  192. +
  193.  WorldMapScript::WorldMapScript(const char* name, uint32 mapId)
  194.      : ScriptObject(name), MapScript<Map>(mapId)
  195.  {
  196. @@ -1471,6 +1538,12 @@ ItemScript::ItemScript(const char* name)
  197.      ScriptRegistry<ItemScript>::AddScript(this);
  198.  }
  199.  
  200. +AllCreatureScript::AllCreatureScript(const char* name)
  201. +: ScriptObject(name)
  202. +{
  203. +    ScriptRegistry<AllCreatureScript>::AddScript(this);
  204. +}
  205. +
  206.  CreatureScript::CreatureScript(const char* name)
  207.      : ScriptObject(name)
  208.  {
  209. @@ -1576,10 +1649,12 @@ template class ScriptRegistry<SpellScriptLoader>;
  210.  template class ScriptRegistry<ServerScript>;
  211.  template class ScriptRegistry<WorldScript>;
  212.  template class ScriptRegistry<FormulaScript>;
  213. +template class ScriptRegistry<AllMapScript>;
  214.  template class ScriptRegistry<WorldMapScript>;
  215.  template class ScriptRegistry<InstanceMapScript>;
  216.  template class ScriptRegistry<BattlegroundMapScript>;
  217.  template class ScriptRegistry<ItemScript>;
  218. +template class ScriptRegistry<AllCreatureScript>;
  219.  template class ScriptRegistry<CreatureScript>;
  220.  template class ScriptRegistry<GameObjectScript>;
  221.  template class ScriptRegistry<AreaTriggerScript>;
  222. @@ -1596,6 +1671,7 @@ template class ScriptRegistry<AchievementCriteriaScript>;
  223.  template class ScriptRegistry<PlayerScript>;
  224.  template class ScriptRegistry<GuildScript>;
  225.  template class ScriptRegistry<GroupScript>;
  226. +template class ScriptRegistry<UnitScript>;
  227.  
  228.  // Undefine utility macros.
  229.  #undef GET_SCRIPT_RET
  230. diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
  231. index 2701825..9b4fe2f 100755
  232. --- a/src/server/game/Scripting/ScriptMgr.h
  233. +++ b/src/server/game/Scripting/ScriptMgr.h
  234. @@ -190,6 +190,20 @@ template<class TObject> class UpdatableScript
  235.          virtual void OnUpdate(TObject* /*obj*/, uint32 /*diff*/) { }
  236.  };
  237.  
  238. +class UnitScript : public ScriptObject
  239. +{
  240. +    protected:
  241. +
  242. +        UnitScript(const char* name);
  243. +
  244. +    public:
  245. +
  246. +        virtual uint32 DealDamage(Unit* AttackerUnit, Unit *pVictim, uint32 damage, DamageEffectType damagetype) { return damage;}
  247. +        virtual uint32 HandlePeriodicDamageAurasTick(Unit* target, Unit* caster, int32 damage) { return damage; }
  248. +        virtual void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType, bool crit) { }
  249. +        virtual void CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *damageInfo, WeaponAttackType attackType) { }
  250. +};
  251. +
  252.  class SpellScriptLoader : public ScriptObject
  253.  {
  254.      protected:
  255. @@ -272,6 +286,9 @@ class WorldScript : public ScriptObject
  256.  
  257.          // Called when the world is actually shut down.
  258.          virtual void OnShutdown() { }
  259. +
  260. +        // Called at End of SetInitialWorldSettings.
  261. +        virtual void SetInitialWorldSettings() { }
  262.  };
  263.  
  264.  class FormulaScript : public ScriptObject
  265. @@ -344,6 +361,21 @@ template<class TMap> class MapScript : public UpdatableScript<TMap>
  266.          virtual void OnUpdate(TMap* /*map*/, uint32 /*diff*/) { }
  267.  };
  268.  
  269. +class AllMapScript : public ScriptObject
  270. +{
  271. +    protected:
  272. +
  273. +        AllMapScript(const char* name);
  274. +
  275. +    public:
  276. +
  277. +        // Called when a player enters any Map
  278. +        virtual void OnPlayerEnterAll(Map* /*map*/, Player* /*player*/) { }
  279. +
  280. +        // Called when a player leave any Map
  281. +        virtual void OnPlayerLeaveAll(Map* /*map*/, Player* /*player*/) { }
  282. +};
  283. +
  284.  class WorldMapScript : public ScriptObject, public MapScript<Map>
  285.  {
  286.      protected:
  287. @@ -436,6 +468,21 @@ class CreatureScript : public ScriptObject, public UpdatableScript<Creature>
  288.          virtual CreatureAI* GetAI(Creature* /*creature*/) const { return NULL; }
  289.  };
  290.  
  291. +class AllCreatureScript : public ScriptObject
  292. +{
  293. +    protected:
  294. +
  295. +        AllCreatureScript(const char* name);
  296. +
  297. +    public:
  298. +
  299. +        // Called from End of Creature Update.
  300. +        virtual void OnAllCreatureUpdate(Creature* /*creature*/, uint32 /*diff*/) { }
  301. +
  302. +        // Called from End of Creature SelectLevel.
  303. +        virtual void Creature_SelectLevel(const CreatureTemplate* /*cinfo*/, Creature* /*creature*/) { }
  304. +};
  305. +
  306.  class GameObjectScript : public ScriptObject, public UpdatableScript<GameObject>
  307.  {
  308.      protected:
  309. @@ -822,6 +869,13 @@ class ScriptMgr
  310.          ScriptMgr();
  311.          virtual ~ScriptMgr();
  312.  
  313. +    public: /* UnitScriptLoader */
  314. +
  315. +        uint32 DealDamage(Unit* AttackerUnit, Unit *pVictim,uint32 damage,DamageEffectType damagetype);
  316. +        uint32 HandlePeriodicDamageAurasTick(Unit* target, Unit* caster, int32 damage);
  317. +        void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType, bool crit);
  318. +        void CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *damageInfo, WeaponAttackType attackType);
  319. +
  320.      public: /* Initialization */
  321.  
  322.          void Initialize();
  323. @@ -837,6 +891,10 @@ class ScriptMgr
  324.  
  325.          void Unload();
  326.  
  327. +    public: /* {VAS} Script Hooks */
  328. +
  329. +        float VAS_Script_Hooks();
  330. +
  331.      public: /* SpellScriptLoader */
  332.  
  333.          void CreateSpellScripts(uint32 spellId, std::list<SpellScript*>& scriptVector);
  334. @@ -863,6 +921,7 @@ class ScriptMgr
  335.          void OnWorldUpdate(uint32 diff);
  336.          void OnStartup();
  337.          void OnShutdown();
  338. +        void SetInitialWorldSettings();
  339.  
  340.      public: /* FormulaScript */
  341.  
  342. @@ -874,6 +933,11 @@ class ScriptMgr
  343.          void OnGainCalculation(uint32& gain, Player* player, Unit* unit);
  344.          void OnGroupRateCalculation(float& rate, uint32 count, bool isRaid);
  345.  
  346. +    public: /* AllScript */
  347. +
  348. +        void OnPlayerEnterMapAll(Map* map, Player* player);
  349. +        void OnPlayerLeaveMapAll(Map* map, Player* player);
  350. +
  351.      public: /* MapScript */
  352.  
  353.          void OnCreateMap(Map* map);
  354. @@ -895,6 +959,11 @@ class ScriptMgr
  355.          bool OnItemUse(Player* player, Item* item, SpellCastTargets const& targets);
  356.          bool OnItemExpire(Player* player, ItemTemplate const* proto);
  357.  
  358. +    public: /* AllCreatureScript */
  359. +
  360. +        void OnAllCreatureUpdate(Creature* creature, uint32 diff);
  361. +        void Creature_SelectLevel(const CreatureTemplate *cinfo, Creature* creature);
  362. +
  363.      public: /* CreatureScript */
  364.  
  365.          bool OnDummyEffect(Unit* caster, uint32 spellId, SpellEffIndex effIndex, Creature* target);
  366. diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
  367. index bca26bd..5788edb 100755
  368. --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
  369. +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
  370. @@ -6172,6 +6172,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
  371.  
  372.      // ignore non positive values (can be result apply spellmods to aura damage
  373.      uint32 damage = std::max(GetAmount(), 0);
  374. +    damage = sScriptMgr->HandlePeriodicDamageAurasTick(target, caster, damage);
  375.  
  376.      if (GetAuraType() == SPELL_AURA_PERIODIC_DAMAGE)
  377.      {
  378. diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
  379. index ea74b6d..d0be8c0 100755
  380. --- a/src/server/game/World/World.cpp
  381. +++ b/src/server/game/World/World.cpp
  382. @@ -1201,6 +1201,21 @@ void World::LoadConfigSettings(bool reload)
  383.      m_bool_configs[CONFIG_PDUMP_NO_PATHS] = ConfigMgr::GetBoolDefault("PlayerDump.DisallowPaths", true);
  384.      m_bool_configs[CONFIG_PDUMP_NO_OVERWRITE] = ConfigMgr::GetBoolDefault("PlayerDump.DisallowOverwrite", true);
  385.  
  386. +    m_int_configs[VAS_VasDebug] = ConfigMgr::GetIntDefault ("VAS.AutoBalance.Debug", 1);
  387. +    m_int_configs[VAS_AutoInstance] = ConfigMgr::GetIntDefault ("VAS.AutoBalance.AutoInstance", 1);
  388. +    m_int_configs[VAS_PlayerChangeNotify] = ConfigMgr::GetIntDefault ("VAS.AutoBalance.PlayerChangeNotify", 1);
  389. +
  390. +    m_float_configs[VAS_Config_xPlayer] = ConfigMgr::GetFloatDefault("VAS.AutoBalance.XPlayer", 1.0f);
  391. +    m_float_configs[VAS_Min_D_Mod] = ConfigMgr::GetFloatDefault("Min.D.Mod", 0.10f);
  392. +    m_float_configs[VAS_Min_HP_Mod] = ConfigMgr::GetFloatDefault("Min.HP.Mod", 0.20f);
  393. +
  394. +    std::string VAS_AutoBalance_40_Name = ConfigMgr::GetStringDefault("VAS.AutoBalance.40.Name", "");
  395. +    std::string VAS_AutoBalance_25_Name = ConfigMgr::GetStringDefault("VAS.AutoBalance.25.Name", "");
  396. +    std::string VAS_AutoBalance_20_Name = ConfigMgr::GetStringDefault("VAS.AutoBalance.20.Name", "");
  397. +    std::string VAS_AutoBalance_10_Name = ConfigMgr::GetStringDefault("VAS.AutoBalance.10.Name", "");
  398. +    std::string VAS_AutoBalance_5_Name = ConfigMgr::GetStringDefault("VAS.AutoBalance.5.Name", "");
  399. +    std::string VAS_AutoBalance_2_Name = ConfigMgr::GetStringDefault("VAS.AutoBalance.2.Name", "");
  400. +
  401.      // call ScriptMgr if we're reloading the configuration
  402.      m_bool_configs[CONFIG_WINTERGRASP_ENABLE] = ConfigMgr::GetBoolDefault("Wintergrasp.Enable", false);
  403.      m_int_configs[CONFIG_WINTERGRASP_PLR_MAX] = ConfigMgr::GetIntDefault("Wintergrasp.PlayerMax", 100);
  404. @@ -1763,6 +1778,8 @@ void World::SetInitialWorldSettings()
  405.  
  406.      uint32 startupDuration = GetMSTimeDiffToNow(startupBegin);
  407.  
  408. +    sScriptMgr->SetInitialWorldSettings();
  409. +
  410.      sLog->outInfo(LOG_FILTER_WORLDSERVER, "World initialized in %u minutes %u seconds", (startupDuration / 60000), ((startupDuration % 60000) / 1000));
  411.      sLog->EnableDBAppenders();
  412.  }
  413. diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
  414. index a6cdd47..3f0ce51 100755
  415. --- a/src/server/game/World/World.h
  416. +++ b/src/server/game/World/World.h
  417. @@ -181,6 +181,9 @@ enum WorldFloatConfigs
  418.      CONFIG_CREATURE_FAMILY_ASSISTANCE_RADIUS,
  419.      CONFIG_THREAT_RADIUS,
  420.      CONFIG_CHANCE_OF_GM_SURVEY,
  421. +    VAS_Config_xPlayer,
  422. +    VAS_Min_D_Mod,
  423. +    VAS_Min_HP_Mod,
  424.      FLOAT_CONFIG_VALUE_COUNT
  425.  };
  426.  
  427. @@ -319,6 +322,9 @@ enum WorldIntConfigs
  428.      CONFIG_WARDEN_CLIENT_BAN_DURATION,
  429.      CONFIG_WARDEN_NUM_MEM_CHECKS,
  430.      CONFIG_WARDEN_NUM_OTHER_CHECKS,
  431. +    VAS_VasDebug,
  432. +    VAS_AutoInstance,
  433. +    VAS_PlayerChangeNotify,
  434.      CONFIG_WINTERGRASP_PLR_MAX,
  435.      CONFIG_WINTERGRASP_PLR_MIN,
  436.      CONFIG_WINTERGRASP_PLR_MIN_LVL,
  437. @@ -617,6 +623,14 @@ class World
  438.          /// Get the path where data (dbc, maps) are stored on disk
  439.          std::string GetDataPath() const { return m_dataPath; }
  440.  
  441. +        /// Return the Mob IDs to be Autobalanced
  442. +        std::string GetVAS40() const { return VAS_AutoBalance_40_Name; }
  443. +        std::string GetVAS25() const { return VAS_AutoBalance_25_Name; }
  444. +        std::string GetVAS20() const { return VAS_AutoBalance_20_Name; }
  445. +        std::string GetVAS10() const { return VAS_AutoBalance_10_Name; }
  446. +        std::string GetVAS5() const { return VAS_AutoBalance_5_Name; }
  447. +        std::string GetVAS2() const { return VAS_AutoBalance_2_Name; }
  448. +
  449.          /// When server started?
  450.          time_t const& GetStartTime() const { return m_startTime; }
  451.          /// What time is it?
  452. @@ -779,6 +793,15 @@ class World
  453.      private:
  454.          static ACE_Atomic_Op<ACE_Thread_Mutex, bool> m_stopEvent;
  455.          static uint8 m_ExitCode;
  456. +
  457. +        std::string VAS_AutoBalance_40_Name;
  458. +        std::string VAS_AutoBalance_25_Name;
  459. +        std::string VAS_AutoBalance_20_Name;
  460. +        std::string VAS_AutoBalance_10_Name;
  461. +        std::string VAS_AutoBalance_5_Name;
  462. +        std::string VAS_AutoBalance_2_Name;
  463. +        std::string VAS_color;
  464. +
  465.          uint32 m_ShutdownTimer;
  466.          uint32 m_ShutdownMask;
  467.  
  468. diff --git a/src/server/scripts/Custom/CMakeLists.txt b/src/server/scripts/Custom/CMakeLists.txt
  469. index 62abde2..7c59d51 100644
  470. --- a/src/server/scripts/Custom/CMakeLists.txt
  471. +++ b/src/server/scripts/Custom/CMakeLists.txt
  472. @@ -7,9 +7,9 @@
  473.  # This program is distributed in the hope that it will be useful, but
  474.  # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
  475.  # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  476. -
  477.  set(scripts_STAT_SRCS
  478.    ${scripts_STAT_SRCS}
  479. +  Custom/VAS_AutoBalance.cpp
  480.  )
  481.  
  482.  message("  -> Prepared: Custom")
  483. diff --git a/src/server/scripts/Custom/VAS_AutoBalance.cpp b/src/server/scripts/Custom/VAS_AutoBalance.cpp
  484. new file mode 100644
  485. index 0000000..149101e
  486. --- /dev/null
  487. +++ b/src/server/scripts/Custom/VAS_AutoBalance.cpp
  488. @@ -0,0 +1,499 @@
  489. +/*
  490. + * Copyright (C) 2012 CVMagic <http://www.trinitycore.org/f/topic/6551-vas-autobalance/>
  491. + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/>
  492. + * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
  493. + * Copyright (C) 1985-2010 {VAS} KalCorp  <http://vasserver.dyndns.org/>
  494. + *
  495. + * This program is free software; you can redistribute it and/or modify it
  496. + * under the terms of the GNU General Public License as published by the
  497. + * Free Software Foundation; either version 2 of the License, or (at your
  498. + * option) any later version.
  499. + *
  500. + * This program is distributed in the hope that it will be useful, but WITHOUT
  501. + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  502. + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  503. + * more details.
  504. + *
  505. + * You should have received a copy of the GNU General Public License along
  506. + * with this program. If not, see <http://www.gnu.org/licenses/>.
  507. + */
  508. +
  509. +/*
  510. + * Script Name: AutoBalance
  511. + * Original Authors: KalCorp and Vaughner
  512. + * Maintainer(s): CVMagic
  513. + * Original Script Name: VAS.AutoBalance
  514. + * Description: This script is intended to scale based on number of players, instance mobs & world bosses' health, mana, and damage.
  515. + */
  516. +
  517. +
  518. +#include "ScriptPCH.h"
  519. +#include "Configuration/Config.h"
  520. +#include "MapManager.h"
  521. +#include "Map.h"
  522. +#include <vector>
  523. +
  524. +#define BOOL_TO_STRING(b) ((b)? "true":"false")
  525. +
  526. +struct AutoBalanceCreatureInfo
  527. +{
  528. +    uint32 instancePlayerCount;
  529. +    float DamageMultiplier;
  530. +};
  531. +
  532. +static std::map<uint32, AutoBalanceCreatureInfo> CreatureInfo; // A hook should be added to remove the mapped entry when the creature is dead or this should be added into the creature object
  533. +static std::map<int, int> forcedCreatureIds;                   // The map values correspond with the VAS.AutoBalance.XX.Name entries in the configuration file.
  534. +
  535. +int GetValidDebugLevel()
  536. +{
  537. +    int debugLevel = sWorld->getIntConfig(VAS_VasDebug);
  538. +
  539. +    if ((debugLevel < 0) || (debugLevel > 3))
  540. +    {
  541. +        return 1;
  542. +    }
  543. +    return debugLevel;
  544. +}
  545. +
  546. +void LoadForcedCreatureIdsFromString(std::string creatureIds, int forcedPlayerCount) // Used for reading the string from the configuration file to for those creatures who need to be scaled for XX number of players.
  547. +{
  548. +    std::string delimitedValue;
  549. +    std::stringstream creatureIdsStream;
  550. +
  551. +    creatureIdsStream.str(creatureIds);
  552. +    while (std::getline(creatureIdsStream, delimitedValue, ',')) // Process each Creature ID in the string, delimited by the comma - ","
  553. +    {
  554. +        int creatureId = atoi(delimitedValue.c_str());
  555. +        if (creatureId >= 0)
  556. +        {
  557. +            forcedCreatureIds[creatureId] = forcedPlayerCount;
  558. +        }
  559. +    }
  560. +}
  561. +
  562. +int GetForcedCreatureId(int creatureId)
  563. +{
  564. +    if(forcedCreatureIds.find(creatureId) == forcedCreatureIds.end()) // Don't want the forcedCreatureIds map to blowup to a massive empty array
  565. +    {
  566. +        return 0;
  567. +    }
  568. +    return forcedCreatureIds[creatureId];
  569. +}
  570. +
  571. +class VAS_AutoBalance_WorldScript : public WorldScript
  572. +{
  573. +    public:
  574. +        VAS_AutoBalance_WorldScript()
  575. +            : WorldScript("VAS_AutoBalance_WorldScript")
  576. +        {
  577. +        }
  578. +
  579. +    void OnConfigLoad(bool /*reload*/)
  580. +    {
  581. +    }
  582. +
  583. +    void OnStartup()
  584. +    {
  585. +    }
  586. +
  587. +    void SetInitialWorldSettings()
  588. +    {
  589. +        // Load from the VAS.AutoBalance.XX.Name entries in the Configuration File
  590. +        forcedCreatureIds.clear();
  591. +        LoadForcedCreatureIdsFromString(sWorld->GetVAS40(), 40);
  592. +        LoadForcedCreatureIdsFromString(sWorld->GetVAS25(), 25);
  593. +        LoadForcedCreatureIdsFromString(sWorld->GetVAS10(), 10);
  594. +        LoadForcedCreatureIdsFromString(sWorld->GetVAS5(), 5);
  595. +        LoadForcedCreatureIdsFromString(sWorld->GetVAS2(), 2);
  596. +
  597. +        sLog->outInfo(LOG_FILTER_WORLDSERVER, "----------------------------------------------------");
  598. +        sLog->outInfo(LOG_FILTER_WORLDSERVER, "  Powered by {VAS} AutoBalance");
  599. +        sLog->outInfo(LOG_FILTER_WORLDSERVER, "----------------------------------------------------");
  600. +        sLog->outInfo(LOG_FILTER_WORLDSERVER, "  xPlayer = %4.1f ", sWorld->getFloatConfig(VAS_Config_xPlayer));
  601. +        sLog->outInfo(LOG_FILTER_WORLDSERVER, "  AutoInstance = %u ", sWorld->getIntConfig(VAS_AutoInstance));
  602. +        sLog->outInfo(LOG_FILTER_WORLDSERVER, "  PlayerChangeNotify = %u ", sWorld->getIntConfig(VAS_PlayerChangeNotify));
  603. +        sLog->outInfo(LOG_FILTER_WORLDSERVER, "  Min.D.Mod = %4.2f ", sWorld->getFloatConfig(VAS_Min_D_Mod));
  604. +        sLog->outInfo(LOG_FILTER_WORLDSERVER, "  Min.HP.Mod = %4.2f ", sWorld->getFloatConfig(VAS_Min_HP_Mod));
  605. +        sLog->outInfo(LOG_FILTER_WORLDSERVER, "  VasDebug   =  %u ", GetValidDebugLevel());
  606. +        sLog->outInfo(LOG_FILTER_WORLDSERVER, "----------------------------------------------------\n");
  607. +    }
  608. +
  609. +};
  610. +
  611. +class VAS_AutoBalance_PlayerScript : public PlayerScript
  612. +{
  613. +    public:
  614. +        VAS_AutoBalance_PlayerScript()
  615. +            : PlayerScript("VAS_AutoBalance_PlayerScript")
  616. +        {
  617. +        }
  618. +
  619. +    void OnLogin(Player *Player)
  620. +    {
  621. +
  622. +        if (GetValidDebugLevel() >= 3)
  623. +            sLog->outInfo(LOG_FILTER_PLAYER_LOADING, "### VAS_AutoBalance_PlayerScript - OnLogin Player=%s", Player->GetName());
  624. +    }
  625. +};
  626. +
  627. +class VAS_AutoBalance_UnitScript : public UnitScript
  628. +{
  629. +    public:
  630. +        VAS_AutoBalance_UnitScript()
  631. +            : UnitScript("VAS_AutoBalance_UnitScript")
  632. +        {
  633. +        }
  634. +
  635. +    uint32 DealDamage(Unit* AttackerUnit, Unit *playerVictim, uint32 damage, DamageEffectType damagetype)
  636. +    {
  637. +        if (AttackerUnit->GetMap()->IsDungeon() && playerVictim->GetMap()->IsDungeon())
  638. +            if (AttackerUnit->GetTypeId() != TYPEID_PLAYER)
  639. +            {
  640. +                if (GetValidDebugLevel() >= 3)
  641. +                    sLog->outInfo(LOG_FILTER_TSCR, "### VAS_AutoBalance_UnitScript - VAS_Unit_DealDamage Attacker=%s Victim=%s Start Damage=%u",AttackerUnit->GetName(),playerVictim->GetName(),damage);
  642. +                damage = VAS_Modifer_DealDamage(AttackerUnit,damage);
  643. +                if (GetValidDebugLevel() >= 3)
  644. +                    sLog->outInfo(LOG_FILTER_TSCR, "### VAS_AutoBalance_UnitScript - VAS_Unit_DealDamage Attacker=%s Victim=%s End Damage=%u",AttackerUnit->GetName(),playerVictim->GetName(),damage);
  645. +            }
  646. +            return damage;
  647. +    }
  648. +
  649. +    uint32 HandlePeriodicDamageAurasTick(Unit* target, Unit* caster, int32 damage)
  650. +    {
  651. +        if (caster->GetMap()->IsDungeon() && target->GetMap()->IsDungeon())
  652. +            if (caster->GetTypeId() != TYPEID_PLAYER)
  653. +            {
  654. +                if (GetValidDebugLevel() >= 3)
  655. +                    sLog->outInfo(LOG_FILTER_TSCR, "### VAS_AutoBalance_UnitScript - VAS_Unit_HandlePeriodicDamage Attacker=%s Victim=%s Start Damage=%u",caster->GetName(),target->GetName(),damage);
  656. +
  657. +                if (!((caster->isHunterPet() || caster->isPet() || caster->isSummon()) && caster->IsControlledByPlayer()))
  658. +                    damage = (float)damage * (float)CreatureInfo[caster->GetGUID()].DamageMultiplier;
  659. +
  660. +                if (GetValidDebugLevel() >= 3)
  661. +                    sLog->outInfo(LOG_FILTER_TSCR, "### VAS_AutoBalance_UnitScript - VAS_Unit_HandlePeriodicDamage Attacker=%s Victim=%s End Damage=%u",caster->GetName(),target->GetName(),damage);
  662. +            }
  663. +            return damage;
  664. +    }
  665. +
  666. +    void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType, bool crit)
  667. +    {
  668. +        if ((damageInfo->attacker->GetMap()->IsDungeon() && damageInfo->target->GetMap()->IsDungeon()) || ( damageInfo->attacker->GetMap()->IsBattleground() && damageInfo->target->GetMap()->IsBattleground()))
  669. +        {
  670. +            if (damageInfo->attacker->GetTypeId() != TYPEID_PLAYER)
  671. +            {
  672. +                if (GetValidDebugLevel() >= 3)
  673. +                    sLog->outInfo(LOG_FILTER_TSCR, "### VAS_AutoBalance_UnitScript - CalculateSpellDamageTaken Attacker=%s Victim=%s Start Damage=%u",damageInfo->attacker->GetName(),damageInfo->target->GetName(),damageInfo->damage);
  674. +
  675. +                if ((damageInfo->attacker->isHunterPet() || damageInfo->attacker->isPet() || damageInfo->attacker->isSummon()) && damageInfo->attacker->IsControlledByPlayer())
  676. +                    return;
  677. +
  678. +                damageInfo->damage = (float)damageInfo->damage * (float)CreatureInfo[damageInfo->attacker->GetGUID()].DamageMultiplier;
  679. +
  680. +                if (GetValidDebugLevel() >= 3)
  681. +                    sLog->outInfo(LOG_FILTER_TSCR, "### VAS_AutoBalance_UnitScript - CalculateSpellDamageTaken Attacker=%s Victim=%s End Damage=%u",damageInfo->attacker->GetName(),damageInfo->target->GetName(),damageInfo->damage);
  682. +            }
  683. +        }
  684. +            return;
  685. +    }
  686. +
  687. +    void CalculateMeleeDamage(Unit *playerVictim, uint32 damage, CalcDamageInfo *damageInfo, WeaponAttackType attackType)
  688. +    {
  689. +        // Make sure the Attacker and the Victim are in the same location, in addition that the attacker is not player.
  690. +        if (((damageInfo->attacker->GetMap()->IsDungeon() && damageInfo->target->GetMap()->IsDungeon()) || (damageInfo->attacker->GetMap()->IsBattleground() && damageInfo->target->GetMap()->IsBattleground())) && (damageInfo->attacker->GetTypeId() != TYPEID_PLAYER))
  691. +            if (!((damageInfo->attacker->isHunterPet() || damageInfo->attacker->isPet() || damageInfo->attacker->isSummon()) && damageInfo->attacker->IsControlledByPlayer())) // Make sure that the attacker is not a Pet of some sort
  692. +            {
  693. +                if (GetValidDebugLevel() >= 3)
  694. +                    sLog->outInfo(LOG_FILTER_TSCR, "### VAS_AutoBalance_UnitScript - CalculateMeleeDamage Attacker=%s Victim=%s Start Damage=%u",damageInfo->attacker->GetName(),damageInfo->target->GetName(),damageInfo->damage);
  695. +
  696. +                damageInfo->damage = (float)damageInfo->damage * (float)CreatureInfo[damageInfo->attacker->GetGUID()].DamageMultiplier;
  697. +
  698. +                if (GetValidDebugLevel() >= 3)
  699. +                    sLog->outInfo(LOG_FILTER_TSCR, "### VAS_AutoBalance_UnitScript - CalculateMeleeDamage Attacker=%s Victim=%s End Damage=%u",damageInfo->attacker->GetName(),damageInfo->target->GetName(),damageInfo->damage);
  700. +            }
  701. +            return;
  702. +    }
  703. +
  704. +    uint32 VAS_Modifer_DealDamage(Unit* AttackerUnit,uint32 damage)
  705. +    {
  706. +    if ((AttackerUnit->isHunterPet() || AttackerUnit->isPet() || AttackerUnit->isSummon()) && AttackerUnit->IsControlledByPlayer())
  707. +        return damage;
  708. +
  709. +    float damageMultiplier = CreatureInfo[AttackerUnit->GetGUID()].DamageMultiplier;
  710. +
  711. +    return damage * damageMultiplier;
  712. +
  713. +    }
  714. +
  715. +};
  716. +
  717. +
  718. +class VAS_AutoBalance_AllMapScript : public AllMapScript
  719. +{
  720. +    public:
  721. +        VAS_AutoBalance_AllMapScript()
  722. +            : AllMapScript("VAS_AutoBalance_AllMapScript")
  723. +        {
  724. +        }
  725. +
  726. +    void OnPlayerEnterAll(Map* map, Player* player)
  727. +    {
  728. +        if (GetValidDebugLevel() >= 2)
  729. +        {
  730. +            sLog->outInfo(LOG_FILTER_TSCR, "----------------------------------------------------");
  731. +            sLog->outInfo(LOG_FILTER_TSCR, "## VAS_AutoBalance_AllMapScript - OnPlayerEnterAll");
  732. +            sLog->outInfo(LOG_FILTER_TSCR, "## For InsatanceID %u",map->GetInstanceId());
  733. +            sLog->outInfo(LOG_FILTER_TSCR, "## IsDungeon= %u",map->GetEntry()->IsDungeon());
  734. +            sLog->outInfo(LOG_FILTER_TSCR, "## For Map %u",player->GetMapId());
  735. +            sLog->outInfo(LOG_FILTER_TSCR, "## PlayersInMap %u",map->GetPlayersCountExceptGMs());
  736. +            sLog->outInfo(LOG_FILTER_TSCR, "## pDifficulty %u",uint32(player->GetDifficulty(player->GetMap()->IsHeroic())));
  737. +            sLog->outInfo(LOG_FILTER_TSCR, "## pGetDungeonDifficulty %u",uint32(player->GetDungeonDifficulty()));
  738. +            sLog->outInfo(LOG_FILTER_TSCR, "## pGetRaidDifficulty %u",uint32(player->GetRaidDifficulty()));
  739. +            sLog->outInfo(LOG_FILTER_TSCR, "## maxPlayers %u",((InstanceMap*)sMapMgr->FindMap(player->GetMapId(), player->GetInstanceId()))->GetMaxPlayers());
  740. +            sLog->outInfo(LOG_FILTER_TSCR, "## IsHeroic=%s IsRaid=%s IsRegularDifficulty=%s IsRaidOrHeroicDungeon=%s IsNonRaidDungeon=%s",BOOL_TO_STRING(player->GetMap()->IsHeroic()),BOOL_TO_STRING(player->GetMap()->IsRaid()),BOOL_TO_STRING(player->GetMap()->IsRegularDifficulty()),BOOL_TO_STRING(player->GetMap()->IsRaidOrHeroicDungeon()),BOOL_TO_STRING(player->GetMap()->IsNonRaidDungeon()));
  741. +            sLog->outInfo(LOG_FILTER_TSCR, "----------------------------------------------------\n");
  742. +        }
  743. +
  744. +        if (sWorld->getIntConfig(VAS_PlayerChangeNotify) >= 1)
  745. +        {
  746. +            if ((map->GetEntry()->IsDungeon()) && !player->isGameMaster() )
  747. +            {
  748. +                Map::PlayerList const &playerList = map->GetPlayers();
  749. +                if (!playerList.isEmpty())
  750. +                {
  751. +                    for (Map::PlayerList::const_iterator playerIteration = playerList.begin(); playerIteration != playerList.end(); ++playerIteration)
  752. +                    {
  753. +                        if (Player* playerHandle = playerIteration->getSource())
  754. +                        {
  755. +                            ChatHandler chatHandle = ChatHandler(playerHandle);
  756. +                            chatHandle.PSendSysMessage("|cffFF0000 [AutoBalance]|r|cffFF8000 %s entered the Instance %s. Auto setting player count to %u |r",player->GetName(),map->GetMapName(),map->GetPlayersCountExceptGMs());
  757. +                        }
  758. +                    }
  759. +                }
  760. +            }
  761. +        }
  762. +    }
  763. +
  764. +    void OnPlayerLeaveAll(Map* map, Player* player)
  765. +    {
  766. +
  767. +        if (GetValidDebugLevel() >= 3)
  768. +            sLog->outInfo(LOG_FILTER_TSCR, "#### VAS_AutoBalance_AllMapScript - OnPlayerLeaveAll map=%s player=%s", map->GetMapName(),player->GetName());
  769. +
  770. +        int instancePlayerCount = map->GetPlayersCountExceptGMs() - 1;
  771. +
  772. +        if (instancePlayerCount >=1)
  773. +        {
  774. +            if (GetValidDebugLevel() >= 2)
  775. +            {
  776. +                sLog->outInfo(LOG_FILTER_TSCR, "----------------------------------------------------");
  777. +                sLog->outInfo(LOG_FILTER_TSCR, "## VAS_AutoBalance_AllMapScript - OnPlayerLeaveAll");
  778. +                sLog->outInfo(LOG_FILTER_TSCR, "## For InsatanceID %u",map->GetInstanceId());
  779. +                sLog->outInfo(LOG_FILTER_TSCR, "## IsDungeon= %u",map->GetEntry()->IsDungeon());
  780. +                sLog->outInfo(LOG_FILTER_TSCR, "## For Map %u",player->GetMapId());
  781. +                sLog->outInfo(LOG_FILTER_TSCR, "## PlayersInMap %u",instancePlayerCount);
  782. +                sLog->outInfo(LOG_FILTER_TSCR, "----------------------------------------------------\n");
  783. +            }
  784. +
  785. +            if (sWorld->getIntConfig(VAS_PlayerChangeNotify) >= 1)
  786. +            {
  787. +                if ((map->GetEntry()->IsDungeon()) && !player->isGameMaster())
  788. +                {
  789. +                    Map::PlayerList const &playerList = map->GetPlayers();
  790. +                    if (!playerList.isEmpty())
  791. +                    {
  792. +                        for (Map::PlayerList::const_iterator playerIteration = playerList.begin(); playerIteration != playerList.end(); ++playerIteration)
  793. +                        {
  794. +                            if (Player* playerHandle = playerIteration->getSource())
  795. +                            {
  796. +                                ChatHandler chatHandle = ChatHandler(playerHandle);
  797. +                                chatHandle.PSendSysMessage("|cffFF0000 [VAS-AutoBalance]|r|cffFF8000 %s left the Instance %s. Auto setting player count to %u |r",player->GetName(),map->GetMapName(),instancePlayerCount);
  798. +                            }
  799. +                        }
  800. +                    }
  801. +                }
  802. +            }
  803. +        }
  804. +    }
  805. +};
  806. +
  807. +class VAS_AutoBalance_WorldMapScript : public WorldMapScript
  808. +{
  809. +    public:
  810. +        VAS_AutoBalance_WorldMapScript()
  811. +            : WorldMapScript("VAS_AutoBalance_WorldMapScript",0)
  812. +        {
  813. +        }
  814. +
  815. +    void OnPlayerEnter(Map* map, Player* player)
  816. +    {
  817. +
  818. +        if (GetValidDebugLevel() >= 3)
  819. +            sLog->outInfo(LOG_FILTER_TSCR, "### VAS_AutoBalance_WorldMapScript - OnPlayerEnter Map=%s player=%s",map->GetMapName(),player->GetName());
  820. +    }
  821. +
  822. +    void OnPlayerLeave(Map* map, Player* player)
  823. +    {
  824. +
  825. +        if (GetValidDebugLevel() >= 3)
  826. +            sLog->outInfo(LOG_FILTER_TSCR, "### VAS_AutoBalance_WorldMapScript - OnPlayerLeave Map=%s player=%s",map->GetMapName(),player->GetName());
  827. +    }
  828. +};
  829. +
  830. +
  831. +class VAS_AutoBalance_AllCreatureScript : public AllCreatureScript
  832. +{
  833. +    public:
  834. +        VAS_AutoBalance_AllCreatureScript()
  835. +            : AllCreatureScript("VAS_AutoBalance_AllCreatureScript")
  836. +        {
  837. +        }
  838. +
  839. +
  840. +    void Creature_SelectLevel(const CreatureTemplate *creatureTemplate, Creature* creature)
  841. +    {
  842. +
  843. +        if (creature->GetMap()->IsDungeon())
  844. +        {
  845. +            ModifyCreatureAttributes(creature);
  846. +            CreatureInfo[creature->GetGUID()].instancePlayerCount = creature->GetMap()->GetPlayersCountExceptGMs();
  847. +        }
  848. +    }
  849. +
  850. +    void OnAllCreatureUpdate(Creature* creature, uint32 diff)
  851. +    {
  852. +        if(!(CreatureInfo[creature->GetGUID()].instancePlayerCount == creature->GetMap()->GetPlayersCountExceptGMs()))
  853. +        {
  854. +            if (creature->GetMap()->IsDungeon() || creature->GetMap()->IsBattleground())
  855. +                ModifyCreatureAttributes(creature);
  856. +            CreatureInfo[creature->GetGUID()].instancePlayerCount = creature->GetMap()->GetPlayersCountExceptGMs();
  857. +        }
  858. +    }
  859. +
  860. +    void ModifyCreatureAttributes(Creature* creature)
  861. +    {
  862. +        if(((creature->isHunterPet() || creature->isPet() || creature->isSummon()) && creature->IsControlledByPlayer()) || sWorld->getIntConfig(VAS_AutoInstance) < 1 || creature->GetMap()->GetPlayersCountExceptGMs() <= 0)
  863. +        {
  864. +            return;
  865. +        }
  866. +
  867. +        CreatureTemplate const *creatureTemplate = creature->GetCreatureTemplate();
  868. +        CreatureBaseStats const* creatureStats = sObjectMgr->GetCreatureBaseStats(creature->getLevel(), creatureTemplate->unit_class);
  869. +
  870. +        float damageMultiplier = 1.0f;
  871. +        float healthMultiplier = 1.0f;
  872. +
  873. +        uint32 baseHealth = creatureStats->GenerateHealth(creatureTemplate);
  874. +        uint32 baseMana = creatureStats->GenerateMana(creatureTemplate);
  875. +        uint32 instancePlayerCount = creature->GetMap()->GetPlayersCountExceptGMs();
  876. +        uint32 maxNumberOfPlayers = ((InstanceMap*)sMapMgr->FindMap(creature->GetMapId(), creature->GetInstanceId()))->GetMaxPlayers();
  877. +        uint32 scaledHealth = 0;
  878. +        uint32 scaledMana = 0;
  879. +
  880. +        //   VAS SOLO  - By MobID
  881. +        if(GetForcedCreatureId(creatureTemplate->Entry) > 0)
  882. +        {
  883. +            maxNumberOfPlayers = GetForcedCreatureId(creatureTemplate->Entry); // Force maxNumberOfPlayers to be changed to match the Configuration entry.
  884. +        }
  885. +
  886. +        // (tanh((X-2.2)/1.5) +1 )/2    // 5 Man formula X = Number of Players
  887. +        // (tanh((X-5)/2) +1 )/2        // 10 Man Formula X = Number of Players
  888. +        // (tanh((X-16.5)/6.5) +1 )/2   // 25 Man Formula X = Number of players
  889. +        //
  890. +        // Note: The 2.2, 5, and 16.5 are the number of players required to get 50% health.
  891. +        //       It's not required this be a whole number, you'd adjust this to raise or lower
  892. +        //       the hp modifier for per additional player in a non-whole group. These
  893. +        //       values will eventually be part of the configuration file once I finalize the mod.
  894. +        //
  895. +        //       The 1.5, 2, and 6.5 modify the rate of percentage increase between
  896. +        //       number of players. Generally the closer to the value of 1 you have this
  897. +        //       the less gradual the rate will be. For example in a 5 man it would take 3
  898. +        //       total players to face a mob at full health.
  899. +        //
  900. +        //       The +1 and /2 values raise the TanH function to a positive range and make
  901. +        //       sure the modifier never goes above the value or 1.0 or below 0.
  902. +        //
  903. +        //       Lastly this formula has one side effect on full groups Bosses and mobs will
  904. +        //       never have full health, this can be tested against by making sure the number
  905. +        //       of players match the maxNumberOfPlayers variable.
  906. +
  907. +        switch (maxNumberOfPlayers)
  908. +        {
  909. +        case 40:
  910. +            healthMultiplier = (float)instancePlayerCount / (float)maxNumberOfPlayers; // 40 Man Instances oddly enough scale better with the old formula
  911. +            break;
  912. +        case 25:
  913. +            healthMultiplier = (tanh((instancePlayerCount - 16.5f) / 1.5f) + 1.0f) / 2.0f;
  914. +            break;
  915. +        case 10:
  916. +            healthMultiplier = (tanh((instancePlayerCount - 4.5f) / 1.5f) + 1.0f) / 2.0f;
  917. +            break;
  918. +        case 2:
  919. +            healthMultiplier = (float)instancePlayerCount / (float)maxNumberOfPlayers;                   // Two Man Creatures are too easy if handled by the 5 man formula, this would only
  920. +            break;                                                                         // apply in the situation where it's specified in the configuration file.
  921. +        default:
  922. +            healthMultiplier = (tanh((instancePlayerCount - 2.2f) / 1.5f) + 1.0f) / 2.0f;    // default to a 5 man group
  923. +        }
  924. +
  925. +        //   VAS SOLO  - Map 0,1 and 530 ( World Mobs )                                                               // This may be where VAS_AutoBalance_CheckINIMaps might have come into play. None the less this is
  926. +        if((creature->GetMapId() == 0 || creature->GetMapId() == 1 || creature->GetMapId() == 530) && (creature->isElite() || creature->isWorldBoss()))  // specific to World Bosses and elites in those Maps, this is going to use the entry XPlayer in place of instancePlayerCount.
  927. +        {
  928. +            if(baseHealth > 800000){
  929. +                healthMultiplier = (tanh((sWorld->getFloatConfig(VAS_Config_xPlayer) - 5.0f) / 1.5f) + 1.0f) / 2.0f;
  930. +            }else{
  931. +                healthMultiplier = (tanh((sWorld->getFloatConfig(VAS_Config_xPlayer) - 2.2f) / 1.5f) + 1.0f) / 2.0f; // Assuming a 5 man configuration, as World Bosses have been relatively retired since BC so unless the boss has some substantial baseHealth
  932. +            }
  933. +
  934. +        }
  935. +
  936. +        // Ensure that the healthMultiplier is not lower than the configuration specified value. -- This may be Deprecated later.
  937. +        if(healthMultiplier <= sWorld->getFloatConfig(VAS_Min_HP_Mod) )
  938. +        {
  939. +            healthMultiplier = sWorld->getFloatConfig(VAS_Min_HP_Mod);
  940. +        }
  941. +
  942. +        //Getting the list of Classes in this group - this will be used later on to determine what additional scaling will be required based on the ratio of tank/dps/healer
  943. +        //GetPlayerClassList(creature, playerClassList); // Update playerClassList with the list of all the participating Classes
  944. +
  945. +
  946. +        scaledHealth = uint32((baseHealth * healthMultiplier) + 1.0f);
  947. +        // Now adjusting Mana, Mana is something that can be scaled linearly
  948. +        scaledMana = ((baseMana/maxNumberOfPlayers) * instancePlayerCount);
  949. +        // Now Adjusting Damage, this too is linear for now .... this will have to change I suspect.
  950. +        damageMultiplier = (float)instancePlayerCount / (float)maxNumberOfPlayers;
  951. +
  952. +        // Can not be less then Min_D_Mod
  953. +        if(damageMultiplier <= sWorld->getFloatConfig(VAS_Min_D_Mod))
  954. +        {
  955. +            damageMultiplier = sWorld->getFloatConfig(VAS_Min_D_Mod);
  956. +        }
  957. +
  958. +        if((GetValidDebugLevel() >= 3))
  959. +        {
  960. +            sLog->outInfo(LOG_FILTER_TSCR, "## VAS-AutoBalance MobID=%u MapID=%u creatureName=%s  GUID=%llu  instancePlayerCount=%u", creatureTemplate->Entry, creature->GetMapId(), creatureTemplate->Name.c_str(), creature->GetGUID(), instancePlayerCount);
  961. +            sLog->outInfo(LOG_FILTER_TSCR, "## VAS-AutoBalance MapDifficulty=%u Health=%u / %u healthMultiplier=%4.5f", creature->GetMap()->GetDifficulty(), scaledHealth, baseHealth, healthMultiplier);
  962. +            sLog->outInfo(LOG_FILTER_TSCR, "## VAS-AutoBalance maxNumberOfPlayers=%u IsRaid=%s", maxNumberOfPlayers, BOOL_TO_STRING(creature->GetMap()->IsRaid()));
  963. +            sLog->outInfo(LOG_FILTER_TSCR, "## VAS-AutoBalance Mana %u / %u", baseMana, scaledMana);
  964. +            sLog->outInfo(LOG_FILTER_TSCR, "## VAS-AutoBalance damageMultiplier=%4.2f", damageMultiplier);
  965. +        }
  966. +
  967. +        creature->SetCreateHealth(scaledHealth);
  968. +        creature->SetMaxHealth(scaledHealth);
  969. +        creature->ResetPlayerDamageReq();
  970. +        creature->SetCreateMana(scaledMana);
  971. +        creature->SetMaxPower(POWER_MANA, scaledMana);
  972. +        creature->SetPower(POWER_MANA, scaledMana);
  973. +        creature->SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, (float)scaledHealth);
  974. +        creature->SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, (float)scaledMana);
  975. +        CreatureInfo[creature->GetGUID()].DamageMultiplier = damageMultiplier;
  976. +    }
  977. +};
  978. +
  979. +void AddSC_VAS_AutoBalance()
  980. +{
  981. +    new VAS_AutoBalance_WorldScript;
  982. +    new VAS_AutoBalance_PlayerScript;
  983. +    new VAS_AutoBalance_UnitScript;
  984. +    new VAS_AutoBalance_AllCreatureScript;
  985. +    new VAS_AutoBalance_AllMapScript;
  986. +    new VAS_AutoBalance_WorldMapScript;
  987. +}
  988. diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
  989. index ce65517..da08d75 100644
  990. --- a/src/server/worldserver/worldserver.conf.dist
  991. +++ b/src/server/worldserver/worldserver.conf.dist
  992. @@ -26,6 +26,7 @@
  993.  #    CONSOLE AND REMOTE ACCESS
  994.  #    CHARACTER DELETE OPTIONS
  995.  #    CUSTOM SERVER OPTIONS
  996. +#    VAS AUTOBALANCE OPTIONS
  997.  #    LOGGING SYSTEM SETTINGS
  998.  #
  999.  ###################################################################################################
  1000. @@ -2645,6 +2646,77 @@ PlayerDump.DisallowOverwrite = 1
  1001.  ###################################################################################################
  1002.  
  1003.  ###################################################################################################
  1004. +# VAS AUTOBALANCE OPTIONS
  1005. +#
  1006. +#     VAS.AutoBalance.XPlayer
  1007. +#        Set Server to level of solo mode.
  1008. +#        Set to 0 to Disable VAS-SOLO Mod.
  1009. +#        Example: VAS.AutoBalance.XPlayer = 1 will set everything for a 1 player game.
  1010. +#        Default:     1
  1011. +
  1012. +VAS.AutoBalance.XPlayer = 1
  1013. +
  1014. +#
  1015. +#     VAS.AutoBalance.AutoInstance
  1016. +#        Set instances to Auto chance XPlayer depending on players in it.
  1017. +#        Default:     1 (1 = ON, 0 = OFF)
  1018. +
  1019. +VAS.AutoBalance.AutoInstance = 1
  1020. +
  1021. +#
  1022. +#     VAS.AutoBalance.Debug
  1023. +#        0 = None
  1024. +#        1 = Errors Only
  1025. +#        2 = Errors and Basic Information
  1026. +#        3 = All VAS Info
  1027. +#        Default:     1
  1028. +
  1029. +VAS.AutoBalance.Debug = 1
  1030. +
  1031. +#
  1032. +#     VAS.AutoBalance.PlayerChangeNotify
  1033. +#        Set Auto Notifications to all players in Instance that player count has changed.
  1034. +#        Default:     1 (1 = ON, 0 = OFF)
  1035. +
  1036. +VAS.AutoBalance.PlayerChangeNotify = 1
  1037. +
  1038. +#
  1039. +#     VAS.AutoBalance.Color
  1040. +#        In Game Color for mod information in chat window.
  1041. +#        Default:     cffFF8000 (Orange)
  1042. +
  1043. +VAS.AutoBalance.Color = cffFF8000
  1044. +
  1045. +#
  1046. +#     Min.HP.Mod
  1047. +#        Minimum Modifier setting for Health Modification
  1048. +#        Default:     0.20
  1049. +
  1050. +Min.HP.Mod = 0.20
  1051. +
  1052. +#
  1053. +#     Min.D.Mod
  1054. +#        Minimum Modifier setting for Damage Modification
  1055. +#        Default:     0.10
  1056. +
  1057. +Min.D.Mod = 0.10
  1058. +
  1059. +#
  1060. +#     VAS.AutoBalance.XX.Name
  1061. +#        Sets MobIDs for the group they belong to.
  1062. +#        All 5 Man Mobs should go in VAS.AutoBalance.5.Name
  1063. +#        All 10 Man Mobs should go in VAS.AutoBalance.10.Name etc.
  1064. +
  1065. +VAS.AutoBalance.40.Name = "11583,16441,30057,13020,15589,14435,18192,14889,14888,14887,14890,15302,15818,15742,15741,15740,18338"
  1066. +VAS.AutoBalance.25.Name = "22997,21966,21965,21964,21806,21215,21845,19728,12397,17711,18256,18192,"
  1067. +VAS.AutoBalance.10.Name = "15689,15550,16152,17521,17225,16028,29324,31099"
  1068. +VAS.AutoBalance.5.Name = "15203,15204,15205,15305,6109,26801,30508,26799,30495,26803,30497,27859,27249"
  1069. +VAS.AutoBalance.2.Name = "25549,24558,25574,24559,25556,25557,25578,24561,25555,24555,25541,24553,25550,24554,24552,25564,15931,29373"
  1070. +
  1071. +#
  1072. +###################################################################################################
  1073. +
  1074. +###################################################################################################
  1075.  #
  1076.  #  LOGGING SYSTEM SETTINGS
  1077.  #
  1078.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement