713 lines
42 KiB
C++
713 lines
42 KiB
C++
#include <map>
|
|
#include "Log.h"
|
|
#include "Config.h"
|
|
#include "ScriptMgr.h"
|
|
#include "Unit.h"
|
|
#include "Player.h"
|
|
#include "Pet.h"
|
|
#include "Map.h"
|
|
#include "Group.h"
|
|
#include "InstanceScript.h"
|
|
#include "Chat.h"
|
|
#include <math.h>
|
|
#include <unordered_map>
|
|
|
|
bool SoloCraftEnable = 1;
|
|
bool SoloCraftAnnounceModule = 1;
|
|
bool SoloCraftDebuffEnable = 1;
|
|
bool SolocraftXPBalEnabled = 1;
|
|
bool SolocraftXPEnabled = 1;
|
|
bool SolocraftNoXPFlag = 0;
|
|
float SoloCraftSpellMult = 1.0;
|
|
float SoloCraftStatsMult = 100.0;
|
|
float SoloCraftXPMod = 1.0;
|
|
uint32 SolocraftLevelDiff = 1;
|
|
uint32 SolocraftDungeonLevel = 1;
|
|
std::unordered_map<uint8, uint32> classes;
|
|
std::unordered_map<uint32, uint32> dungeons;
|
|
std::unordered_map<uint32, float> diff_Multiplier;
|
|
std::unordered_map<uint32, float> diff_Multiplier_Heroics;
|
|
|
|
float D5 = 1.0;
|
|
float D10 = 1.0;
|
|
float D25 = 1.0;
|
|
float D40 = 1.0;
|
|
float D649H10 = 1.0;
|
|
float D649H25 = 1.0;
|
|
|
|
class SolocraftConfig : public WorldScript
|
|
{
|
|
public:
|
|
SolocraftConfig() : WorldScript("SolocraftConfig") {}
|
|
|
|
void OnBeforeConfigLoad(bool reload) override
|
|
{
|
|
if (!reload) {
|
|
// Load Configuration Settings
|
|
SetInitialWorldSettings();
|
|
}
|
|
}
|
|
|
|
// Load Configuration Settings
|
|
void SetInitialWorldSettings()
|
|
{
|
|
SoloCraftEnable = sConfigMgr->GetOption<bool>("Solocraft.Enable", 1);
|
|
SoloCraftAnnounceModule = sConfigMgr->GetOption<bool>("Solocraft.Announce", 1);
|
|
|
|
//Balancing
|
|
SoloCraftDebuffEnable = sConfigMgr->GetOption<bool>("SoloCraft.Debuff.Enable", 1);
|
|
SoloCraftSpellMult = sConfigMgr->GetOption<float>("SoloCraft.Spellpower.Mult", 2.5);
|
|
SoloCraftStatsMult = sConfigMgr->GetOption<float>("SoloCraft.Stats.Mult", 100.0);
|
|
classes =
|
|
{
|
|
{1, sConfigMgr->GetOption<uint8>("SoloCraft.WARRIOR", 100) },
|
|
{2, sConfigMgr->GetOption<uint8>("SoloCraft.PALADIN", 100) },
|
|
{3, sConfigMgr->GetOption<uint8>("SoloCraft.HUNTER", 100) },
|
|
{4, sConfigMgr->GetOption<uint8>("SoloCraft.ROGUE", 100) },
|
|
{5, sConfigMgr->GetOption<uint8>("SoloCraft.PRIEST", 100) },
|
|
{6, sConfigMgr->GetOption<uint8>("SoloCraft.DEATH_KNIGHT", 100) },
|
|
{7, sConfigMgr->GetOption<uint8>("SoloCraft.SHAMAN", 100) },
|
|
{8, sConfigMgr->GetOption<uint8>("SoloCraft.MAGE", 100) },
|
|
{9, sConfigMgr->GetOption<uint8>("SoloCraft.WARLOCK", 100) },
|
|
{11, sConfigMgr->GetOption<uint8>("SoloCraft.DRUID", 100) },
|
|
};
|
|
|
|
//XP Enabled
|
|
SolocraftXPEnabled = sConfigMgr->GetOption<bool>("Solocraft.XP.Enabled", 1);
|
|
|
|
//XP Balancing
|
|
SolocraftXPBalEnabled = sConfigMgr->GetOption<bool>("Solocraft.XPBal.Enabled", 1);
|
|
|
|
//Level Thresholds
|
|
SolocraftLevelDiff = sConfigMgr->GetOption<uint32>("Solocraft.Max.Level.Diff", 10);
|
|
|
|
//Catch All Dungeon Level Threshold
|
|
SolocraftDungeonLevel = sConfigMgr->GetOption<uint32>("Solocraft.Dungeon.Level", 80);
|
|
|
|
// Dungeon Base Level
|
|
dungeons =
|
|
{
|
|
// Wow Classic
|
|
{33, sConfigMgr->GetOption<uint32>("Solocraft.ShadowfangKeep.Level", 15) },
|
|
{34, sConfigMgr->GetOption<uint32>("Solocraft.Stockades.Level", 22) },
|
|
{36, sConfigMgr->GetOption<uint32>("Solocraft.Deadmines.Level", 18) },
|
|
{43, sConfigMgr->GetOption<uint32>("Solocraft.WailingCaverns.Level", 17) },
|
|
{47, sConfigMgr->GetOption<uint32>("Solocraft.RazorfenKraulInstance.Level", 30) },
|
|
{48, sConfigMgr->GetOption<uint32>("Solocraft.Blackfathom.Level", 20) },
|
|
{70, sConfigMgr->GetOption<uint32>("Solocraft.Uldaman.Level", 40) },
|
|
{90, sConfigMgr->GetOption<uint32>("Solocraft.GnomeragonInstance.Level", 24) },
|
|
{109, sConfigMgr->GetOption<uint32>("Solocraft.SunkenTemple.Level", 50) },
|
|
{129, sConfigMgr->GetOption<uint32>("Solocraft.RazorfenDowns.Level", 40) },
|
|
{189, sConfigMgr->GetOption<uint32>("Solocraft.MonasteryInstances.Level", 35) }, // Scarlet Monastery
|
|
{209, sConfigMgr->GetOption<uint32>("Solocraft.TanarisInstance.Level", 44) }, // Zul'Farrak
|
|
{229, sConfigMgr->GetOption<uint32>("Solocraft.BlackRockSpire.Level", 55) },
|
|
{230, sConfigMgr->GetOption<uint32>("Solocraft.BlackrockDepths.Level", 50) },
|
|
{249, sConfigMgr->GetOption<uint32>("Solocraft.OnyxiaLairInstance.Level", 60) },
|
|
{289, sConfigMgr->GetOption<uint32>("Solocraft.SchoolofNecromancy.Level", 55) }, // Scholomance
|
|
{309, sConfigMgr->GetOption<uint32>("Solocraft.Zul'gurub.Level", 60) },
|
|
{329, sConfigMgr->GetOption<uint32>("Solocraft.Stratholme.Level", 55) },
|
|
{349, sConfigMgr->GetOption<uint32>("Solocraft.Mauradon.Level", 48) },
|
|
{389, sConfigMgr->GetOption<uint32>("Solocraft.OrgrimmarInstance.Level", 15) }, // Ragefire Chasm
|
|
{409, sConfigMgr->GetOption<uint32>("Solocraft.MoltenCore.Level", 60) },
|
|
{429, sConfigMgr->GetOption<uint32>("Solocraft.DireMaul.Level", 48) },
|
|
{469, sConfigMgr->GetOption<uint32>("Solocraft.BlackwingLair.Level", 40) },
|
|
{509, sConfigMgr->GetOption<uint32>("Solocraft.AhnQiraj.Level", 60) }, // Ruins of Ahn'Qiraj
|
|
{531, sConfigMgr->GetOption<uint32>("Solocraft.AhnQirajTemple.Level", 60) },
|
|
|
|
// BC Instances
|
|
{269, sConfigMgr->GetOption<uint32>("Solocraft.CavernsOfTime.Level", 68) }, // The Black Morass
|
|
{532, sConfigMgr->GetOption<uint32>("Solocraft.Karazahn.Level", 68) },
|
|
{534, sConfigMgr->GetOption<uint32>("Solocraft.HyjalPast.Level", 70) }, // The Battle for Mount Hyjal - Hyjal Summit
|
|
{540, sConfigMgr->GetOption<uint32>("Solocraft.HellfireMilitary.Level", 68) }, // The Shattered Halls
|
|
{542, sConfigMgr->GetOption<uint32>("Solocraft.HellfireDemon.Level", 68) }, // The Blood Furnace
|
|
{543, sConfigMgr->GetOption<uint32>("Solocraft.HellfireRampart.Level", 68) },
|
|
{544, sConfigMgr->GetOption<uint32>("Solocraft.HellfireRaid.Level", 68) }, // Magtheridon's Lair
|
|
{545, sConfigMgr->GetOption<uint32>("Solocraft.CoilfangPumping.Level", 68) }, // The Steamvault
|
|
{546, sConfigMgr->GetOption<uint32>("Solocraft.CoilfangMarsh.Level", 68) }, // The Underbog
|
|
{547, sConfigMgr->GetOption<uint32>("Solocraft.CoilfangDraenei.Level", 68) }, // The Slavepens
|
|
{548, sConfigMgr->GetOption<uint32>("Solocraft.CoilfangRaid.Level", 70) }, // Serpentshrine Cavern
|
|
{550, sConfigMgr->GetOption<uint32>("Solocraft.TempestKeepRaid.Level", 70) }, // The Eye
|
|
{552, sConfigMgr->GetOption<uint32>("Solocraft.TempestKeepArcane.Level", 68) }, // The Arcatraz
|
|
{553, sConfigMgr->GetOption<uint32>("Solocraft.TempestKeepAtrium.Level", 68) }, // The Botanica
|
|
{554, sConfigMgr->GetOption<uint32>("Solocraft.TempestKeepFactory.Level", 68) }, // The Mechanar
|
|
{555, sConfigMgr->GetOption<uint32>("Solocraft.AuchindounShadow.Level", 68) }, // Shadow Labyrinth
|
|
{556, sConfigMgr->GetOption<uint32>("Solocraft.AuchindounDemon.Level", 68) }, // Sethekk Halls
|
|
{557, sConfigMgr->GetOption<uint32>("Solocraft.AuchindounEthereal.Level", 68) }, // Mana-Tombs
|
|
{558, sConfigMgr->GetOption<uint32>("Solocraft.AuchindounDraenei.Level", 68) }, // Auchenai Crypts
|
|
{560, sConfigMgr->GetOption<uint32>("Solocraft.HillsbradPast.Level", 68) }, // Old Hillsbrad Foothills
|
|
{564, sConfigMgr->GetOption<uint32>("Solocraft.BlackTemple.Level", 70) },
|
|
{565, sConfigMgr->GetOption<uint32>("Solocraft.GruulsLair.Level", 70) },
|
|
{568, sConfigMgr->GetOption<uint32>("Solocraft.ZulAman.Level", 68) },
|
|
{580, sConfigMgr->GetOption<uint32>("Solocraft.SunwellPlateau.Level", 70) },
|
|
{585, sConfigMgr->GetOption<uint32>("Solocraft.Sunwell5ManFix.Level", 68) }, // Magister's Terrace
|
|
|
|
// WOTLK Instances
|
|
{533, sConfigMgr->GetOption<uint32>("Solocraft.StratholmeRaid.Level", 78) }, // Naxxramas
|
|
{574, sConfigMgr->GetOption<uint32>("Solocraft.Valgarde70.Level", 78) }, // Utgarde Keep
|
|
{575, sConfigMgr->GetOption<uint32>("Solocraft.UtgardePinnacle.Level", 78) },
|
|
{576, sConfigMgr->GetOption<uint32>("Solocraft.Nexus70.Level", 78) }, // The Nexus
|
|
{578, sConfigMgr->GetOption<uint32>("Solocraft.Nexus80.Level", 78) }, // The Occulus
|
|
{595, sConfigMgr->GetOption<uint32>("Solocraft.StratholmeCOT.Level", 78) }, // The Culling of Stratholme
|
|
{599, sConfigMgr->GetOption<uint32>("Solocraft.Ulduar70.Level", 78) }, // Halls of Stone
|
|
{600, sConfigMgr->GetOption<uint32>("Solocraft.DrakTheronKeep.Level", 78) }, // Drak'Tharon Keep
|
|
{601, sConfigMgr->GetOption<uint32>("Solocraft.Azjol_Uppercity.Level", 78) }, // Azjol-Nerub
|
|
{602, sConfigMgr->GetOption<uint32>("Solocraft.Ulduar80.Level", 78) }, // Halls of Lighting
|
|
{603, sConfigMgr->GetOption<uint32>("Solocraft.UlduarRaid.Level", 80) }, // Ulduar
|
|
{604, sConfigMgr->GetOption<uint32>("Solocraft.GunDrak.Level", 78) },
|
|
{608, sConfigMgr->GetOption<uint32>("Solocraft.DalaranPrison.Level", 78) }, // Violet Hold
|
|
{615, sConfigMgr->GetOption<uint32>("Solocraft.ChamberOfAspectsBlack.Level", 80) }, // The Obsidian Sanctum
|
|
{616, sConfigMgr->GetOption<uint32>("Solocraft.NexusRaid.Level", 80) }, // The Eye of Eternity
|
|
{619, sConfigMgr->GetOption<uint32>("Solocraft.Azjol_LowerCity.Level", 78) }, // Ahn'kahet: The Old Kingdom
|
|
{631, sConfigMgr->GetOption<uint32>("Solocraft.IcecrownCitadel.Level", 80) }, // Icecrown Citadel
|
|
{632, sConfigMgr->GetOption<uint32>("Solocraft.IcecrownCitadel5Man.Level", 78) }, // The Forge of Souls
|
|
{649, sConfigMgr->GetOption<uint32>("Solocraft.ArgentTournamentRaid.Level", 80) }, // Trial of the Crusader
|
|
{650, sConfigMgr->GetOption<uint32>("Solocraft.ArgentTournamentDungeon.Level", 80) }, // Trial of the Champion
|
|
{658, sConfigMgr->GetOption<uint32>("Solocraft.QuarryOfTears.Level", 78) }, // Pit of Saron
|
|
{668, sConfigMgr->GetOption<uint32>("Solocraft.HallsOfReflection.Level", 78) }, // Halls of Reflection
|
|
{724, sConfigMgr->GetOption<uint32>("Solocraft.ChamberOfAspectsRed.Level", 80) }, // The Ruby Sanctum
|
|
};
|
|
|
|
// Dungeon Difficulty | Catch alls
|
|
D5 = sConfigMgr->GetOption<float>("Solocraft.Dungeon", 5.0);
|
|
D10 = sConfigMgr->GetOption<float>("Solocraft.Heroic", 10.0);
|
|
D25 = sConfigMgr->GetOption<float>("Solocraft.Raid25", 25.0);
|
|
D40 = sConfigMgr->GetOption<float>("Solocraft.Raid40", 40.0);
|
|
|
|
diff_Multiplier =
|
|
{
|
|
// WOW Classic Instances
|
|
{33, sConfigMgr->GetOption<float>("Solocraft.ShadowfangKeep", 5.0) },
|
|
{34, sConfigMgr->GetOption<float>("Solocraft.Stockades", 5.0) },
|
|
{36, sConfigMgr->GetOption<float>("Solocraft.Deadmines", 5.0) },
|
|
{43, sConfigMgr->GetOption<float>("Solocraft.WailingCaverns", 5.0) },
|
|
{47, sConfigMgr->GetOption<float>("Solocraft.RazorfenKraulInstance", 5.0) },
|
|
{48, sConfigMgr->GetOption<float>("Solocraft.Blackfathom", 5.0) },
|
|
{70, sConfigMgr->GetOption<float>("Solocraft.Uldaman", 5.0) },
|
|
{90, sConfigMgr->GetOption<float>("Solocraft.GnomeragonInstance", 5.0) },
|
|
{109, sConfigMgr->GetOption<float>("Solocraft.SunkenTemple", 5.0) },
|
|
{129, sConfigMgr->GetOption<float>("Solocraft.RazorfenDowns", 5.0) },
|
|
{189, sConfigMgr->GetOption<float>("Solocraft.MonasteryInstances", 5.0) }, // Scarlet
|
|
{209, sConfigMgr->GetOption<float>("Solocraft.TanarisInstance", 5.0) }, // Zul'Farrak
|
|
{229, sConfigMgr->GetOption<float>("Solocraft.BlackRockSpire", 10.0) },
|
|
{230, sConfigMgr->GetOption<float>("Solocraft.BlackrockDepths", 5.0) },
|
|
{249, sConfigMgr->GetOption<float>("Solocraft.OnyxiaLairInstance", 40.0) },
|
|
{289, sConfigMgr->GetOption<float>("Solocraft.SchoolofNecromancy", 5.0) }, // Scholo
|
|
{309, sConfigMgr->GetOption<float>("Solocraft.Zul'gurub", 20.0) },
|
|
{329, sConfigMgr->GetOption<float>("Solocraft.Stratholme", 5.0) },
|
|
{349, sConfigMgr->GetOption<float>("Solocraft.Mauradon", 5.0) },
|
|
{389, sConfigMgr->GetOption<float>("Solocraft.OrgrimmarInstance", 5.0) }, // Ragefire
|
|
{409, sConfigMgr->GetOption<float>("Solocraft.MoltenCore", 40.0) },
|
|
{429, sConfigMgr->GetOption<float>("Solocraft.DireMaul", 5.0) },
|
|
{469, sConfigMgr->GetOption<float>("Solocraft.BlackwingLair", 40.0) },
|
|
{509, sConfigMgr->GetOption<float>("Solocraft.AhnQiraj", 20.0) },
|
|
{531, sConfigMgr->GetOption<float>("Solocraft.AhnQirajTemple", 40.0) },
|
|
|
|
// BC Instances
|
|
{269, sConfigMgr->GetOption<float>("Solocraft.CavernsOfTime", 5.0) }, // Black Morass
|
|
{532, sConfigMgr->GetOption<float>("Solocraft.Karazahn", 10.0) },
|
|
{534, sConfigMgr->GetOption<float>("Solocraft.HyjalPast", 25.0) }, // Mount Hyjal
|
|
{540, sConfigMgr->GetOption<float>("Solocraft.HellfireMilitary", 5.0) }, // The Shattered Halls
|
|
{542, sConfigMgr->GetOption<float>("Solocraft.HellfireDemon", 5.0) }, // The Blood Furnace
|
|
{543, sConfigMgr->GetOption<float>("Solocraft.HellfireRampart", 5.0) },
|
|
{544, sConfigMgr->GetOption<float>("Solocraft.HellfireRaid", 25.0) }, // Magtheridon's Lair
|
|
{545, sConfigMgr->GetOption<float>("Solocraft.CoilfangPumping", 5.0) }, // The Steamvault
|
|
{546, sConfigMgr->GetOption<float>("Solocraft.CoilfangMarsh", 5.0) }, // The Underbog
|
|
{547, sConfigMgr->GetOption<float>("Solocraft.CoilfangDraenei", 5.0) }, // The Slavepens
|
|
{548, sConfigMgr->GetOption<float>("Solocraft.CoilfangRaid", 25.0) }, // Serpentshrine Cavern
|
|
{550, sConfigMgr->GetOption<float>("Solocraft.TempestKeepRaid", 25.0) }, // The Eye
|
|
{552, sConfigMgr->GetOption<float>("Solocraft.TempestKeepArcane", 5.0) }, // The Arcatraz
|
|
{553, sConfigMgr->GetOption<float>("Solocraft.TempestKeepAtrium", 5.0) }, // The Botanica
|
|
{554, sConfigMgr->GetOption<float>("Solocraft.TempestKeepFactory", 5.0) }, // The Mechanar
|
|
{555, sConfigMgr->GetOption<float>("Solocraft.AuchindounShadow", 5.0) }, // Shadow Labyrinth
|
|
{556, sConfigMgr->GetOption<float>("Solocraft.AuchindounDemon", 5.0) }, // Sethekk Halls
|
|
{557, sConfigMgr->GetOption<float>("Solocraft.AuchindounEthereal", 5.0) }, // Mana-Tombs
|
|
{558, sConfigMgr->GetOption<float>("Solocraft.AuchindounDraenei", 5.0) }, // Auchenai Crypts
|
|
{560, sConfigMgr->GetOption<float>("Solocraft.HillsbradPast", 5.0) }, // Old Hillsbrad Foothills
|
|
{564, sConfigMgr->GetOption<float>("Solocraft.BlackTemple", 25.0) },
|
|
{565, sConfigMgr->GetOption<float>("Solocraft.GruulsLair", 25.0) },
|
|
{568, sConfigMgr->GetOption<float>("Solocraft.ZulAman", 5.0) },
|
|
{580, sConfigMgr->GetOption<float>("Solocraft.SunwellPlateau", 25.0) },
|
|
{585, sConfigMgr->GetOption<float>("Solocraft.Sunwell5ManFix", 5.0) }, // Magister's Terrace
|
|
|
|
// WOTLK Instances
|
|
{533, sConfigMgr->GetOption<float>("Solocraft.StratholmeRaid", 10.0) }, // Nax 10
|
|
{574, sConfigMgr->GetOption<float>("Solocraft.Valgarde70", 5.0) }, // Utgarde Keep
|
|
{575, sConfigMgr->GetOption<float>("Solocraft.UtgardePinnacle", 5.0) },
|
|
{576, sConfigMgr->GetOption<float>("Solocraft.Nexus70", 5.0) }, // The Nexus
|
|
{578, sConfigMgr->GetOption<float>("Solocraft.Nexus80", 5.0) }, // The Occulus
|
|
{595, sConfigMgr->GetOption<float>("Solocraft.StratholmeCOT", 5.0) }, // The Culling of Stratholme
|
|
{599, sConfigMgr->GetOption<float>("Solocraft.Ulduar70", 5.0) }, // Halls of Stone
|
|
{600, sConfigMgr->GetOption<float>("Solocraft.DrakTheronKeep", 5.0) }, // Drak'Tharon Keep
|
|
{601, sConfigMgr->GetOption<float>("Solocraft.Azjol_Uppercity", 5.0) }, // Azjol-Nerub
|
|
{602, sConfigMgr->GetOption<float>("Solocraft.Ulduar80", 5.0) }, // Halls of Lighting
|
|
{603, sConfigMgr->GetOption<float>("Solocraft.UlduarRaid", 10.0) }, // Ulduar 10
|
|
{604, sConfigMgr->GetOption<float>("Solocraft.GunDrak", 5.0) },
|
|
{608, sConfigMgr->GetOption<float>("Solocraft.DalaranPrison", 5.0) }, // Violet Hold
|
|
{615, sConfigMgr->GetOption<float>("Solocraft.ChamberOfAspectsBlack", 10.0) }, // The Obsidian Sanctum 10
|
|
{616, sConfigMgr->GetOption<float>("Solocraft.NexusRaid", 10.0) }, // The Eye of Eternity 10
|
|
{619, sConfigMgr->GetOption<float>("Solocraft.Azjol_LowerCity", 5.0) }, // Ahn'kahet: The Old Kingdom
|
|
{631, sConfigMgr->GetOption<float>("Solocraft.IcecrownCitadel", 10.0) }, // Icecrown Citadel 10
|
|
{632, sConfigMgr->GetOption<float>("Solocraft.IcecrownCitadel5Man", 5.0) }, // The Forge of Souls
|
|
{649, sConfigMgr->GetOption<float>("Solocraft.ArgentTournamentRaid", 10.0) }, // Trial of the Crusader 10
|
|
{650, sConfigMgr->GetOption<float>("Solocraft.ArgentTournamentDungeon", 5.0) }, // Trial of the Champion
|
|
{658, sConfigMgr->GetOption<float>("Solocraft.QuarryOfTears", 5.0) }, // Pit of Saron
|
|
{668, sConfigMgr->GetOption<float>("Solocraft.HallsOfReflection", 5.0) }, // Halls of Reflection
|
|
{724, sConfigMgr->GetOption<float>("Solocraft.ChamberOfAspectsRed", 10.0) }, // The Ruby Sanctum 10
|
|
};
|
|
|
|
// Heroics
|
|
diff_Multiplier_Heroics =
|
|
{
|
|
// BC Instances Heroics
|
|
{269, sConfigMgr->GetOption<float>("Solocraft.CavernsOfTimeH", 5.0) }, // Black Morass H
|
|
{540, sConfigMgr->GetOption<float>("Solocraft.HellfireMilitaryH", 5.0) }, // The Shattered Halls H
|
|
{542, sConfigMgr->GetOption<float>("Solocraft.HellfireDemonH", 5.0) }, // The Blood Furnace H
|
|
{543, sConfigMgr->GetOption<float>("Solocraft.HellfireRampartH", 5.0) }, // Heroic
|
|
{545, sConfigMgr->GetOption<float>("Solocraft.CoilfangPumpingH", 5.0) }, // The Steamvault
|
|
{546, sConfigMgr->GetOption<float>("Solocraft.CoilfangMarshH", 5.0) }, // The Underbog
|
|
{547, sConfigMgr->GetOption<float>("Solocraft.CoilfangDraeneiH", 5.0) }, // The Slavepens H
|
|
{552, sConfigMgr->GetOption<float>("Solocraft.TempestKeepArcaneH", 5.0) }, // The Arcatraz H
|
|
{553, sConfigMgr->GetOption<float>("Solocraft.TempestKeepAtriumH", 5.0) }, // The Botanica H
|
|
{554, sConfigMgr->GetOption<float>("Solocraft.TempestKeepFactoryH", 5.0) }, // The Mechanar H
|
|
{555, sConfigMgr->GetOption<float>("Solocraft.AuchindounShadowH", 5.0) }, // Shadow Labyrinth H
|
|
{556, sConfigMgr->GetOption<float>("Solocraft.AuchindounDemonH", 5.0) }, // Sethekk Halls H
|
|
{557, sConfigMgr->GetOption<float>("Solocraft.AuchindounEtherealH", 5.0) }, // Mana-Tombs H
|
|
{558, sConfigMgr->GetOption<float>("Solocraft.AuchindounDraeneiH", 5.0) }, // Auchenai Crypts H
|
|
{560, sConfigMgr->GetOption<float>("Solocraft.HillsbradPastH", 5.0) }, // Old Hillsbrad Foothills H
|
|
{568, sConfigMgr->GetOption<float>("Solocraft.ZulAmanH", 5.0) }, // Zul'Aman H
|
|
{585, sConfigMgr->GetOption<float>("Solocraft.Sunwell5ManFixH", 5.0) }, // Magister's Terrace H
|
|
|
|
// WOTLK Instances Heroics
|
|
{533, sConfigMgr->GetOption<float>("Solocraft.StratholmeRaidH", 25.0) }, // Naxxramas 25
|
|
{574, sConfigMgr->GetOption<float>("Solocraft.Valgarde70H", 5.0) }, // Utgarde Keep H
|
|
{575, sConfigMgr->GetOption<float>("Solocraft.UtgardePinnacleH", 5.0) }, // Utgarde Pinnacle H
|
|
{576, sConfigMgr->GetOption<float>("Solocraft.Nexus70H", 5.0) }, // The Nexus H
|
|
{578, sConfigMgr->GetOption<float>("Solocraft.Nexus80H", 5.0) }, // The Occulus H
|
|
{595, sConfigMgr->GetOption<float>("Solocraft.StratholmeCOTH", 5.0) }, // The Culling of Stratholme H
|
|
{599, sConfigMgr->GetOption<float>("Solocraft.Ulduar70H", 5.0) }, // Halls of Stone H
|
|
{600, sConfigMgr->GetOption<float>("Solocraft.DrakTheronKeepH", 5.0) }, // Drak'Tharon Keep H
|
|
{601, sConfigMgr->GetOption<float>("Solocraft.Azjol_UppercityH", 5.0) }, // Azjol-Nerub H
|
|
{602, sConfigMgr->GetOption<float>("Solocraft.Ulduar80H", 5.0) }, // Halls of Lighting H
|
|
{603, sConfigMgr->GetOption<float>("Solocraft.UlduarRaidH", 25.0) }, // Ulduar 25
|
|
{604, sConfigMgr->GetOption<float>("Solocraft.GunDrakH", 5.0) }, // Gundrak H
|
|
{608, sConfigMgr->GetOption<float>("Solocraft.DalaranPrisonH", 5.0) }, // Violet Hold H
|
|
{615, sConfigMgr->GetOption<float>("Solocraft.ChamberOfAspectsBlackH", 25.0) }, // The Obsidian Sanctum 25
|
|
{616, sConfigMgr->GetOption<float>("Solocraft.NexusRaidH", 25.0) }, // The Eye of Eternity 25
|
|
{619, sConfigMgr->GetOption<float>("Solocraft.Azjol_LowerCityH", 5.0) }, // Ahn'kahet: The Old Kingdom H
|
|
{631, sConfigMgr->GetOption<float>("Solocraft.IcecrownCitadelH", 25.0) }, // Icecrown Citadel 25
|
|
{632, sConfigMgr->GetOption<float>("Solocraft.IcecrownCitadel5ManH", 5.0) }, // The Forge of Souls
|
|
{649, sConfigMgr->GetOption<float>("Solocraft.ArgentTournamentRaidH", 25.0) }, // Trial of the Crusader 25
|
|
{650, sConfigMgr->GetOption<float>("Solocraft.ArgentTournamentDungeonH", 5.0) }, // Trial of the Champion H
|
|
{658, sConfigMgr->GetOption<float>("Solocraft.QuarryOfTearsH", 5.0) }, // Pit of Saron H
|
|
{668, sConfigMgr->GetOption<float>("Solocraft.HallsOfReflectionH", 5.0) }, // Halls of Reflection H
|
|
{724, sConfigMgr->GetOption<float>("Solocraft.ChamberOfAspectsRedH", 25.0) }, // The Ruby Sanctum 25
|
|
};
|
|
|
|
//Unique Raids beyond the heroic and normal versions of themselves
|
|
D649H10 = sConfigMgr->GetOption<float>("Solocraft.ArgentTournamentRaidH10", 10.0); //Trial of the Crusader 10 Heroic
|
|
D649H25 = sConfigMgr->GetOption<float>("Solocraft.ArgentTournamentRaidH25", 25.0); //Trial of the Crusader 25 Heroic
|
|
}
|
|
};
|
|
|
|
class SolocraftAnnounce : public PlayerScript
|
|
{
|
|
public:
|
|
SolocraftAnnounce() : PlayerScript("SolocraftAnnounce") {}
|
|
|
|
void OnLogin(Player* player) override
|
|
{
|
|
if (SoloCraftEnable && SoloCraftAnnounceModule)
|
|
{
|
|
ChatHandler(player->GetSession()).SendSysMessage("This server is running the |cff4CFF00SoloCraft |rmodule.");
|
|
}
|
|
}
|
|
|
|
void OnLogout(Player* player) override
|
|
{
|
|
QueryResult result = CharacterDatabase.Query("SELECT `GUID` FROM `custom_solocraft_character_stats` WHERE `GUID`={}", player->GetGUID().GetCounter());
|
|
if (result)
|
|
{
|
|
//Remove database entry as the player has logged out
|
|
CharacterDatabase.Execute("DELETE FROM `custom_solocraft_character_stats` WHERE `GUID`={}", player->GetGUID().GetCounter());
|
|
}
|
|
}
|
|
|
|
void OnGiveXP(Player* /*player*/, uint32& amount, Unit* /*victim*/, uint8 /*xpSource*/) override
|
|
{
|
|
if (SolocraftXPBalEnabled)
|
|
{
|
|
// Decrease Experience based on number of players and difficulty of instance (0 to 100%)
|
|
amount = uint32(amount * SoloCraftXPMod);
|
|
}
|
|
}
|
|
};
|
|
|
|
class SolocraftPlayerInstanceHandler : public PlayerScript
|
|
{
|
|
public:
|
|
SolocraftPlayerInstanceHandler() : PlayerScript("SolocraftPlayerInstanceHandler") {}
|
|
|
|
void OnMapChanged(Player* player) override
|
|
{
|
|
if (sConfigMgr->GetOption<bool>("Solocraft.Enable", true))
|
|
{
|
|
Map* map = player->GetMap();
|
|
float difficulty = CalculateDifficulty(map);
|
|
uint32 dunLevel = CalculateDungeonLevel(map);
|
|
uint32 numInGroup = GetNumInGroup(player);
|
|
uint32 classBalance = GetClassBalance(player);
|
|
ApplyBuffs(player, map, difficulty, dunLevel, numInGroup, classBalance);
|
|
}
|
|
}
|
|
|
|
// Set the instance difficulty
|
|
float CalculateDifficulty(Map* map)
|
|
{
|
|
if (map)
|
|
{
|
|
if (map->Is25ManRaid())
|
|
{
|
|
if (map->IsHeroic() && map->GetId() == 649)
|
|
{
|
|
return D649H25;
|
|
}
|
|
else if (diff_Multiplier_Heroics.find(map->GetId()) == diff_Multiplier_Heroics.end())
|
|
{
|
|
return D25;
|
|
}
|
|
else
|
|
return diff_Multiplier_Heroics[map->GetId()];
|
|
}
|
|
|
|
if (map->IsHeroic())
|
|
{
|
|
if (map->GetId() == 649)
|
|
{
|
|
return D649H10;
|
|
}
|
|
else if (diff_Multiplier_Heroics.find(map->GetId()) == diff_Multiplier_Heroics.end())
|
|
{
|
|
return D10;
|
|
}
|
|
else
|
|
return diff_Multiplier_Heroics[map->GetId()];
|
|
}
|
|
|
|
if (diff_Multiplier.find(map->GetId()) == diff_Multiplier.end())
|
|
{
|
|
if (map->IsDungeon())
|
|
{
|
|
return D5;
|
|
}
|
|
else if (map->IsRaid())
|
|
{
|
|
return D40;
|
|
}
|
|
}
|
|
else
|
|
return diff_Multiplier[map->GetId()];
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Set the Dungeon Level
|
|
uint32 CalculateDungeonLevel(Map* map)
|
|
{
|
|
if (dungeons.find(map->GetId()) == dungeons.end())
|
|
{
|
|
return SolocraftDungeonLevel;
|
|
}
|
|
else
|
|
{
|
|
return dungeons[map->GetId()];
|
|
}
|
|
}
|
|
|
|
// Get the group's size
|
|
uint32 GetNumInGroup(Player* player)
|
|
{
|
|
uint32 numInGroup = 1;
|
|
Group* group = player->GetGroup();
|
|
|
|
if (group)
|
|
{
|
|
Group::MemberSlotList const& groupMembers = group->GetMemberSlots();
|
|
numInGroup = groupMembers.size();
|
|
}
|
|
|
|
return numInGroup;
|
|
}
|
|
|
|
// Get the Player's class balance debuff
|
|
uint32 GetClassBalance(Player* player)
|
|
{
|
|
uint32 classBalance = 100;
|
|
|
|
if (classes.find(player->getClass()) == classes.end())
|
|
{
|
|
return classBalance;
|
|
}
|
|
else if (classes[player->getClass()] >= 0 && classes[player->getClass()] <= 100)
|
|
{
|
|
return classes[player->getClass()];
|
|
}
|
|
else
|
|
return classBalance;
|
|
}
|
|
|
|
// Get the current group members GUIDS and return the total sum of the difficulty offset by all group members currently in the dungeon
|
|
float GetGroupDifficulty(Player* player)
|
|
{
|
|
float GroupDifficulty = 0.0;
|
|
Group* group = player->GetGroup();
|
|
|
|
if (group)
|
|
{
|
|
Group::MemberSlotList const& groupMembers = group->GetMemberSlots();
|
|
for (Group::member_citerator itr = groupMembers.begin(); itr != groupMembers.end(); ++itr)
|
|
{
|
|
if (itr->guid != player->GetGUID())
|
|
{
|
|
QueryResult result = CharacterDatabase.Query("SELECT `GUID`, `Difficulty`, `GroupSize` FROM `custom_solocraft_character_stats` WHERE `GUID`={}", itr->guid.GetCounter());
|
|
if (result)
|
|
{
|
|
if ((*result)[1].Get<float>() > 0)
|
|
{
|
|
GroupDifficulty = GroupDifficulty + (*result)[1].Get<float>();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return GroupDifficulty;
|
|
}
|
|
|
|
// Resets buffers
|
|
void ClearBuffs(Player* player)
|
|
{
|
|
//Database query to get offset from the last instance player exited
|
|
QueryResult result = CharacterDatabase.Query("SELECT `GUID`, `Difficulty`, `GroupSize`, `SpellPower`, `Stats` FROM `custom_solocraft_character_stats` WHERE `GUID`={}", player->GetGUID().GetCounter());
|
|
uint32 SpellPowerBonus = 0;
|
|
|
|
if (result)
|
|
{
|
|
float difficulty = (*result)[1].Get<float>();
|
|
SpellPowerBonus = (*result)[3].Get<uint32>();
|
|
float StatsMultPct = (*result)[4].Get<float>();
|
|
SoloCraftXPMod = 1.0;
|
|
|
|
for (uint32 i = STAT_STRENGTH; i < MAX_STATS; ++i)
|
|
{
|
|
player->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, difficulty * StatsMultPct, false);
|
|
}
|
|
|
|
if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN) && !SolocraftNoXPFlag)
|
|
{
|
|
player->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN);
|
|
}
|
|
|
|
SolocraftNoXPFlag = 0;
|
|
CharacterDatabase.Execute("DELETE FROM custom_solocraft_character_stats WHERE GUID = {}", player->GetGUID().GetCounter());
|
|
}
|
|
|
|
if (player->getPowerType() == POWER_MANA || player->getClass() == CLASS_DRUID)
|
|
{
|
|
player->ApplySpellPowerBonus(SpellPowerBonus, false);
|
|
}
|
|
}
|
|
|
|
// Apply the player buffs
|
|
void ApplyBuffs(Player* player, Map* map, float difficulty, int dunLevel, int numInGroup, int classBalance)
|
|
{
|
|
// Check whether to buff the player or check to debuff back to normal
|
|
if (difficulty != 0)
|
|
{
|
|
std::ostringstream ss;
|
|
|
|
int SpellPowerBonus = 0;
|
|
|
|
// Check for an existing No XP Gain flag - other mod compatibility
|
|
if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN))
|
|
{
|
|
SolocraftNoXPFlag = 1;
|
|
}
|
|
|
|
// If a player is too high level for dungeon don't buff but if in a group will count towards the group offset balancing.
|
|
if (player->getLevel() <= dunLevel + SolocraftLevelDiff)
|
|
{
|
|
|
|
// Get Current members total difficulty offset and if it exceeds the difficulty offset of the dungeon then debuff new group members coming in until all members leave and re-enter. This happens when a player already inside dungeon invite others to the group but the player already has the full difficulty offset.
|
|
float GroupDifficulty = GetGroupDifficulty(player);
|
|
|
|
// Check to either debuff or buff player entering dungeon. Debuff must be enabled in Config
|
|
if (GroupDifficulty >= difficulty && SoloCraftDebuffEnable == 1)
|
|
{
|
|
// Current dungeon offset exceeded - Debuff player modified by ClassBalance Adjustment
|
|
difficulty = (-abs(difficulty)) + ((((float)classBalance / 100) * difficulty) / numInGroup);
|
|
// Float variables suck
|
|
difficulty = roundf(difficulty * 100) / 100;
|
|
|
|
// Disable player XP gain if debuff applied
|
|
if (!player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN) && SolocraftXPBalEnabled)
|
|
{
|
|
player->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Current Dungeon offset not exceeded - Buff player
|
|
// Group difficulty and ClassBalance Adjustment
|
|
difficulty = (((float)classBalance / 100) * difficulty) / numInGroup;
|
|
// Float variables suck - two decimal rounding
|
|
difficulty = roundf(difficulty * 100) / 100;
|
|
|
|
// Set XP Modifier
|
|
SoloCraftXPMod = (1.04 / difficulty) - 0.02;
|
|
SoloCraftXPMod = roundf(SoloCraftXPMod * 100) / 100;
|
|
|
|
// Check for negative XP modifier - Disable XP Gain
|
|
if (SoloCraftXPMod < 0)
|
|
{
|
|
SoloCraftXPMod = 0;
|
|
if (!player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN) && SolocraftXPBalEnabled)
|
|
{
|
|
player->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN);
|
|
}
|
|
}
|
|
|
|
// Check XP modifier for over max limit and adjust
|
|
if (SoloCraftXPMod > 1)
|
|
{
|
|
SoloCraftXPMod = 1.0;
|
|
}
|
|
}
|
|
|
|
// Check Database for a current dungeon entry
|
|
QueryResult result = CharacterDatabase.Query("SELECT `GUID`, `Difficulty`, `GroupSize`, `SpellPower`, `Stats` FROM `custom_solocraft_character_stats` WHERE `GUID`={}", player->GetGUID().GetCounter());
|
|
|
|
// Modify Player Stats
|
|
// STATS defined/enum in SharedDefines.h
|
|
for (int32 i = STAT_STRENGTH; i < MAX_STATS; ++i)
|
|
{
|
|
// Check for Dungeon to Dungeon Transfer and remove old buff
|
|
if (result)
|
|
{
|
|
player->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, (*result)[1].Get<float>() * (*result)[4].Get<float>(), false);
|
|
}
|
|
// Buff the player
|
|
// Unitmods enum UNIT_MOD_STAT_START defined in Unit.h line 391
|
|
player->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, difficulty * SoloCraftStatsMult, true);
|
|
|
|
}
|
|
|
|
// Set player health
|
|
// Defined in Unit.h line 1524
|
|
player->SetFullHealth();
|
|
|
|
if (player->IsExistPet())
|
|
{
|
|
// Set Pet Health
|
|
player->CastSpell(player, 6962, true);
|
|
|
|
}
|
|
|
|
// Spellcaster Stat modify
|
|
if (player->getPowerType() == POWER_MANA || player->getClass() == CLASS_DRUID)
|
|
{
|
|
// Buff the player's mana
|
|
player->SetPower(POWER_MANA, player->GetMaxPower(POWER_MANA));
|
|
|
|
// Check for Dungeon to Dungeon Transfer and remove old Spellpower buff
|
|
if (result)
|
|
{
|
|
// remove spellpower bonus
|
|
player->ApplySpellPowerBonus((*result)[3].Get<uint32>() * (*result)[4].Get<float>(), false);
|
|
}
|
|
|
|
// Buff Spellpower
|
|
// Debuffed characters do not get spellpower
|
|
if (difficulty > 0)
|
|
{
|
|
SpellPowerBonus = static_cast<int>((player->getLevel() * SoloCraftSpellMult) * difficulty);
|
|
player->ApplySpellPowerBonus(SpellPowerBonus, true);
|
|
}
|
|
}
|
|
|
|
// XP Gain Disabled
|
|
if (!SolocraftXPEnabled)
|
|
{
|
|
SoloCraftXPMod = 0;
|
|
if (!player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN))
|
|
{
|
|
player->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN);
|
|
}
|
|
}
|
|
|
|
// Announcements
|
|
if (difficulty > 0)
|
|
{
|
|
// Announce to player - Buff
|
|
if (!SolocraftXPEnabled)
|
|
{
|
|
ss << "|cffFF0000[SoloCraft] |cffFF8000" << player->GetName() << " entered %s - Difficulty Offset: %0.2f. Spellpower Bonus: %i. Class Balance Weight: %i. XP Gain: |cffFF0000Disabled";
|
|
ChatHandler(player->GetSession()).PSendSysMessage(ss.str().c_str(), map->GetMapName(), difficulty, SpellPowerBonus, classBalance);
|
|
}
|
|
else
|
|
{
|
|
if (!SolocraftXPBalEnabled)
|
|
{
|
|
ss << "|cffFF0000[SoloCraft] |cffFF8000" << player->GetName() << " entered %s - Difficulty Offset: %0.2f. Spellpower Bonus: %i. Class Balance Weight: %i. XP Balancing: |cffFF0000Disabled";
|
|
ChatHandler(player->GetSession()).PSendSysMessage(ss.str().c_str(), map->GetMapName(), difficulty, SpellPowerBonus, classBalance);
|
|
}
|
|
else
|
|
{
|
|
ss << "|cffFF0000[SoloCraft] |cffFF8000" << player->GetName() << " entered %s - Difficulty Offset: %0.2f. Spellpower Bonus: %i. Class Balance Weight: %i. XP Balancing: |cff4CFF00Enabled";
|
|
ChatHandler(player->GetSession()).PSendSysMessage(ss.str().c_str(), map->GetMapName(), difficulty, SpellPowerBonus, classBalance);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Announce to player - Debuff
|
|
if (!SolocraftXPBalEnabled && SolocraftXPEnabled)
|
|
{
|
|
ss << "|cffFF0000[SoloCraft] |cffFF8000" << player->GetName() << " entered %s - |cffFF0000BE ADVISED - You have been debuffed by offset: %0.2f with a Class Balance Weight: %i. |cffFF8000 A group member already inside has the dungeon's full buff offset. No Spellpower buff will be applied to spell casters. ALL group members must exit the dungeon and re-enter to receive a balanced offset.";
|
|
ChatHandler(player->GetSession()).PSendSysMessage(ss.str().c_str(), map->GetMapName(), difficulty, classBalance);
|
|
}
|
|
else
|
|
{
|
|
ss << "|cffFF0000[SoloCraft] |cffFF8000" << player->GetName() << " entered %s - |cffFF0000BE ADVISED - You have been debuffed by offset: %0.2f with a Class Balance Weight: %i and no XP will be awarded. |cffFF8000 A group member already inside has the dungeon's full buff offset. No Spellpower buff will be applied to spell casters. ALL group members must exit the dungeon and re-enter to receive a balanced offset.";
|
|
ChatHandler(player->GetSession()).PSendSysMessage(ss.str().c_str(), map->GetMapName(), difficulty, classBalance);
|
|
}
|
|
}
|
|
|
|
// Save Player Dungeon Offsets to Database
|
|
CharacterDatabase.Execute("REPLACE INTO custom_solocraft_character_stats (GUID, Difficulty, GroupSize, SpellPower, Stats) VALUES ({}, {}, {}, {}, {})", player->GetGUID().GetCounter(), difficulty, numInGroup, SpellPowerBonus, SoloCraftStatsMult);
|
|
}
|
|
else
|
|
{
|
|
// Announce to player - Over Max Level Threshold
|
|
ss << "|cffFF0000[SoloCraft] |cffFF8000" << player->GetName() << " entered %s - |cffFF0000You have not been buffed. |cffFF8000 Your level is higher than the max level (%i) threshold for this dungeon.";
|
|
ChatHandler(player->GetSession()).PSendSysMessage(ss.str().c_str(), map->GetMapName(), dunLevel + SolocraftLevelDiff);
|
|
ClearBuffs(player); // Check to revert player back to normal
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ClearBuffs(player); // Check to revert player back to normal - Moving this here fixed logout and login while in instance buff and debuff issues
|
|
}
|
|
}
|
|
|
|
private:
|
|
std::map<uint32, float> _unitDifficulty;
|
|
};
|
|
|
|
void AddSolocraftScripts()
|
|
{
|
|
new SolocraftConfig();
|
|
new SolocraftAnnounce();
|
|
new SolocraftPlayerInstanceHandler();
|
|
}
|