diff --git a/conf/individualProgression.conf.dist b/conf/individualProgression.conf.dist index 426ed13..e6c6b66 100644 --- a/conf/individualProgression.conf.dist +++ b/conf/individualProgression.conf.dist @@ -228,3 +228,33 @@ IndividualProgression.QuestMoneyAtLevelCap = 1 # IndividualProgression.RepeatableVanillaQuestsXP = 1 +# +# IndividualProgression.TbcRacesUnlockProgression +# Description: The progression level at which TBC races will be unlocked. +# Races will be unlocked when the player reaches this level with any character on the account. +# Disable to have TBC races available by default. +# Please refer to IndividualProgression.h/ProgressionState enum for progression stage values. +# +# Default: 0 - TBC Races always available +# 1-16 - Required progression level to create TBC Race characters +# +# + +IndividualProgression.TbcRacesUnlockProgression = 0 +# +# IndividualProgression.DeathKnightUnlockProgression +# Description: The progression level at which Death Knight characters can be created. +# Death Knights will be available when the player reaches this levl with any character on the account. +# Disable to Individual Progression not influence DK creation. +# Please note that all other Death Knight creation restrictions from worldserver.conf still apply. +# The default value is to not allow Death Knight creation until TBC content is cleared. +# This is due to the game not having a proper progression balancing for Death Knights until WotLK, +# but please adjust as desired. +# +# Default: 11 - TBC must be completed to create Death Knights +# 0 - Disabled +# 1-16 - Required progression +# +# + +IndividualProgression.DeathKnightUnlockProgression = 11 diff --git a/src/IndividualProgression.cpp b/src/IndividualProgression.cpp index 6d4de12..c42c18f 100644 --- a/src/IndividualProgression.cpp +++ b/src/IndividualProgression.cpp @@ -3,6 +3,7 @@ */ #include "IndividualProgression.h" +#include "Tokenize.h" IndividualProgression* IndividualProgression::instance() { @@ -176,7 +177,37 @@ void IndividualProgression::AdjustStats(Player* player, float computedAdjustment player->CastCustomSpell(player, HEALING_DONE_SPELL, &bp1Healing, nullptr, nullptr, false); } - +/** + * Gets the highest progression level achieved by an account + * Note that this method makes a direct, non-sync DB call and should be used sparingly + * + * @return progression level + */ +uint8 IndividualProgression::GetAccountProgression(uint32 accountId) +{ + uint8 progressionLevel = 0; + if (!sWorld->getBoolConfig(CONFIG_PLAYER_SETTINGS_ENABLED)) + { + // Prevent crash if player settings are not enabled + return 0; + } + QueryResult result = CharacterDatabase.Query("SELECT `data` FROM `character_settings` WHERE `source` = 'mod-individual-progression' AND `guid` IN (SELECT `guid` FROM `characters` WHERE `account` = {});", accountId); + if (result) + { + do + { + std::string dataOne; + std::stringstream dataString((*result)[0].Get()); + dataString>>dataOne; + uint8 resultValue = atoi(dataOne.c_str()); + if (resultValue > progressionLevel) + { + progressionLevel = resultValue; + } + } while (result->NextRow()); + } + return progressionLevel; +} class IndividualPlayerProgression_WorldScript : public WorldScript @@ -202,6 +233,8 @@ private: sIndividualProgression->startingProgression = sConfigMgr->GetOption("IndividualProgression.StartingProgression", 0); sIndividualProgression->questMoneyAtLevelCap = sConfigMgr->GetOption("IndividualProgression.QuestMoneyAtLevelCap", true); sIndividualProgression->repeatableVanillaQuestsXp = sConfigMgr->GetOption("IndividualProgression.RepeatableVanillaQuestsXP", true); + sIndividualProgression->tbcRacesProgressionLevel = sConfigMgr->GetOption("IndividualProgression.TbcRacesUnlockProgression", 0); + sIndividualProgression->deathKnightProgressionLevel = sConfigMgr->GetOption("IndividualProgression.DeathKnightUnlockProgression", 11); } static void LoadXpValues() diff --git a/src/IndividualProgression.h b/src/IndividualProgression.h index 60a8a28..65fbfbc 100644 --- a/src/IndividualProgression.h +++ b/src/IndividualProgression.h @@ -120,7 +120,7 @@ public: questXpMapType questXpMap; float vanillaPowerAdjustment, vanillaHealthAdjustment, tbcPowerAdjustment, tbcHealthAdjustment, vanillaHealingAdjustment, tbcHealingAdjustment, previousGearTuning; bool enabled, questXpFix, hunterPetLevelFix, requirePreAQQuests, enforceGroupRules, fishingFix, simpleConfigOverride, questMoneyAtLevelCap, repeatableVanillaQuestsXp; - int progressionLimit, startingProgression; + int progressionLimit, startingProgression, tbcRacesProgressionLevel, deathKnightProgressionLevel; bool hasPassedProgression(Player* player, ProgressionState state) const; static bool isBeforeProgression(Player* player, ProgressionState state) ; @@ -133,6 +133,7 @@ public: void AdjustTBCStats(Player* player) const; void AdjustWotLKStats(Player* player) const; static void AdjustStats(Player* player, float computedAdjustment, float computedHealingAdjustment); + static uint8 GetAccountProgression(uint32 accountId); }; #define sIndividualProgression IndividualProgression::instance() diff --git a/src/IndividualProgressionPlayer.cpp b/src/IndividualProgressionPlayer.cpp index 5075c17..5beaaf5 100644 --- a/src/IndividualProgressionPlayer.cpp +++ b/src/IndividualProgressionPlayer.cpp @@ -320,6 +320,43 @@ public: } }; +class IndividualPlayerProgression_AccountScript: public AccountScript +{ +public: + IndividualPlayerProgression_AccountScript() : AccountScript("IndividualProgression_AccountScript") + {} + + // Waiting for PR: https://github.com/azerothcore/azerothcore-wotlk/pull/13060 +// bool CanAccountCreateCharacter(uint32 accountId, uint8 charRace, uint8 charClass) override +// { +// if ((!sIndividualProgression->enabled) || +// (charRace != RACE_DRAENEI && charRace != RACE_BLOODELF && charClass != CLASS_DEATH_KNIGHT) || +// (!sIndividualProgression->tbcRacesProgressionLevel && !sIndividualProgression->deathKnightProgressionLevel)) +// { +// return true; +// } +// uint8 highestProgression = sIndividualProgression->GetAccountProgression(accountId); +// if (charRace == RACE_DRAENEI || charRace == RACE_BLOODELF) +// { +// if (sIndividualProgression->tbcRacesProgressionLevel) +// { +// if (highestProgression < sIndividualProgression->tbcRacesProgressionLevel) +// { +// return false; +// } +// } +// } +// if (charClass == CLASS_DEATH_KNIGHT && sIndividualProgression->deathKnightProgressionLevel) +// { +// if (highestProgression < sIndividualProgression->deathKnightProgressionLevel) +// { +// return false; +// } +// } +// return true; +// } +}; + class IndividualPlayerProgression_PetScript : public PetScript { @@ -397,4 +434,5 @@ void AddSC_mod_individual_progression_player() { new IndividualPlayerProgression(); new IndividualPlayerProgression_PetScript(); + new IndividualPlayerProgression_AccountScript(); }