Initial fix for new methods

This commit is contained in:
Flerp 2025-11-14 17:37:26 -08:00
commit 1b208f2b1b
12 changed files with 1217 additions and 0 deletions

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 AzerothCore
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

26
README.md Normal file
View File

@ -0,0 +1,26 @@
# AzerothCore Challenge Modes
Challenge Modes Module for AzerothCore
This module adds the following challenge modes:
- **Hardcore** - Players who die are permanently ghosts and can never be revived.
- **Semi-Hardcore** - Players who die lose all worn equipment and carried gold.
- **Self Crafted** - Players can only wear equipment that they have crafted.
- **Item Quality Level** - Players can only wear equipment that is of Normal or Poor quality
- **Slow XP Gain** - Players receive 0.5x the normal amount of XP.
- **Very Slow XP Gain** - Players receive 0.25x the normal amount of XP.
- **Quest XP Only** - Players can receive XP only from quests
- **Iron Man Mode** - Enforces the [Iron Man Ruleset](https://wowchallenges.com/challangeinfo/iron-man/)
Challenges can be activated per-character by interacting with the Shrine of Challenge added near the graveyard of each starting area.
Challenges can only be enabled on characters at level 1 (or level 55 for Death Knights).
Multiple challenges can be activated on a single character as long as they do not conflict, such as Hardcore and Semi-Hardcore.
Rewards for reaching level thresholds for each challenge can be added using the Config file, and can include:
- Items
- Titles
- Talent Points
- Increased XP Rate
Please note that this module uses Player Settings to store enabled challenges, so please ensure EnablePlayerSettings is set to 1 in your worldserver.conf.

View File

@ -0,0 +1,132 @@
#
# Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
#
[worldserver]
########################################
# Challenge Mods Config
########################################
# ChallengeModes.Enable
# Description: Enable challenge modes.
# If set to 0, all challenges will be disabled, and the challenge mode selection object will not be present in starting areas.
# Default: 0 - Disabled
# 1 - Enabled
#
ChallengeModes.Enable = 1
#
# The following challenge modes are available:
# Hardcore - Players who die are permanently ghosts and can never be revived.
# SemiHardcore - Players who die lose all worn equipment and carried gold. Cannot be enabled at the same time as Hardcore.
# SelfCrafted - Players can only wear equipment that they have crafted.
# ItemQualityLevel - Players can only wear equipment that is of Normal or Poor quality
# SlowXpGain - Players receive 0.5x the normal amount of XP.
# VerySlowXpGain - Players receive 0.25x the normal amount of XP. Provides all rewards of SlowXpGain as well.
# QuestXpOnly - Players can receive XP only from quests
# IronManMode - Enforces the Iron Man ruleset (https://wowchallenges.com/challangeinfo/iron-man/)
#
#
# The options for each mode follow the same format. "<Challenge>" is replaced with the name of the challenge, such as Hardcore. The following options are possible:
# <Challenge>.Enable = 1
# If set to 0, this challenge option will not be selectable at the challenge modes object.
# <Challenge>.TitleRewards = ""
# Rewards titles for players when reaching the given levels with the challenge enabled.
# The IDs used are from CharTitles.dbc. The format is the level followed by the title ID, separated by commas.
# Example: <Challenge>.TitleRewards = "60 143, 70 123, 80 145"
# <Challenge>.XPMultiplier = ""
# Multiplies XP the player gains if this challege is enabled. This is a multiplier values, so bonus are applied multiplicatively.
# This reward option is not available for SlowXpGain and VerySlowXpGain
# Example: <Challenge>.XPMultiplier = "1.5"
# <Challenge>.TalentRewards = ""
# Rewards talent points for players when reaching the given levels with the challenge enabled.
# The format is the level followed by the number of talent points given at that level, separated by commas.
# Example: <Challenge>.TalentRewards = "30 1, 35 1, 40 1, 45 1, 50 1, 60 2, 70 2, 80 5"
# <Challenge>.ItemRewards = ""
# Rewards items for players when reaching the given levels with the challenge enabled.
# The IDs used are item entry IDs. The format is the level followed by the item ID, separated by commas.
# Example: <Challenge>.ItemRewards = "80 54811"
# <Challenge>.DisableLevel = ""
# When the player reaches this level, the challenge will be automatically disabled.
# To never disable a challenge, set to 0.
# Example: <Challenge>.DisableLevel = 80
# <Challenge>.ItemRewardAmount = 1
# Rewards a set amount of <Challenge>.ItemRewards for players when reaching the given levels with the challenge enabled.
# Example: <Challenge>.ItemRewards = 1
# <Challenge>.AchievementReward = ""
# Rewards an achievement for players when reaching the given levels with the challenge enabled.
# The IDs used are achievement entry IDs. The format is the level followed by the achievement ID, separated by commas.
# Example: <Challenge>.AchievementReward = "80 1234"
#
Hardcore.Enable = 1
Hardcore.TitleRewards = ""
Hardcore.XPMultiplier = 1
Hardcore.TalentRewards = ""
Hardcore.ItemRewards = ""
Hardcore.ItemRewardAmount = 1
Hardcore.DisableLevel = 0
Hardcore.AchievementReward = ""
SemiHardcore.Enable = 1
SemiHardcore.TitleRewards = ""
SemiHardcore.XPMultiplier = 1
SemiHardcore.TalentRewards = ""
SemiHardcore.ItemRewards = ""
SemiHardcore.ItemRewardAmount = 1
SemiHardcore.DisableLevel = 0
SemiHardcore.AchievementReward = ""
SelfCrafted.Enable = 1
SelfCrafted.TitleRewards = ""
SelfCrafted.XPMultiplier = 1
SelfCrafted.TalentRewards = ""
SelfCrafted.ItemRewards = ""
SelfCrafted.ItemRewardAmount = 1
SelfCrafted.DisableLevel = 0
SelfCrafted.AchievementReward = ""
ItemQualityLevel.Enable = 1
ItemQualityLevel.TitleRewards = ""
ItemQualityLevel.XPMultiplier = 1
ItemQualityLevel.TalentRewards = ""
ItemQualityLevel.ItemRewards = ""
ItemQualityLevel.ItemRewardAmount = 1
ItemQualityLevel.DisableLevel = 0
ItemQualityLevel.AchievementReward = ""
SlowXpGain.Enable = 1
SlowXpGain.TitleRewards = ""
SlowXpGain.TalentRewards = ""
SlowXpGain.ItemRewards = ""
SlowXpGain.ItemRewardAmount = 1
SlowXpGain.DisableLevel = 0
SlowXpGain.XPMultiplier = 0.50
SlowXpGain.AchievementReward = ""
VerySlowXpGain.Enable = 1
VerySlowXpGain.TitleRewards = ""
VerySlowXpGain.TalentRewards = ""
VerySlowXpGain.ItemRewards = ""
VerySlowXpGain.ItemRewardAmount = 1
VerySlowXpGain.DisableLevel = 0
VerySlowXpGain.XPMultiplier = 0.25
VerySlowXpGain.AchievementReward = ""
QuestXpOnly.Enable = 1
QuestXpOnly.TitleRewards = ""
QuestXpOnly.XPMultiplier = 1
QuestXpOnly.TalentRewards = ""
QuestXpOnly.ItemRewards = ""
QuestXpOnly.ItemRewardAmount = 1
QuestXpOnly.DisableLevel = 0
QuestXpOnly.AchievementReward = ""
IronMan.Enable = 1
IronMan.TitleRewards = ""
IronMan.TalentRewards = ""
IronMan.ItemRewards = ""
IronMan.ItemRewardAmount = 1
IronMan.DisableLevel = 0
IronMan.XPMultiplier = 1
IronMan.AchievementReward = ""

32
conf/conf.sh.dist Normal file
View File

@ -0,0 +1,32 @@
#!/usr/bin/env bash
## CUSTOM SQL - Important file used by the db_assembler.sh
## Keep only the required variables (base sql files or updates, depending on the DB)
## BASE SQL
DB_AUTH_CUSTOM_PATHS+=(
"$MOD_SKELETON_ROOT/data/sql/db-auth/base/"
)
DB_CHARACTERS_CUSTOM_PATHS+=(
"$MOD_SKELETON_ROOT/data/sql/db-characters/base/"
)
DB_WORLD_CUSTOM_PATHS+=(
"$MOD_SKELETON_ROOT/data/sql/db-world/base/"
)
## UPDATES
DB_AUTH_UPDATES_PATHS+=(
"$MOD_SKELETON_ROOT/data/sql/db-auth/updates/"
)
DB_CHARACTERS_UPDATES_PATHS+=(
"$MOD_SKELETON_ROOT/data/sql/db-characters/updates/"
)
DB_WORLD_UPDATES_PATHS+=(
"$MOD_SKELETON_ROOT/data/sql/db-world/updates/"
)

View File

View File

View File

@ -0,0 +1,15 @@
DELETE FROM `gameobject_template` WHERE `entry`=254605;
INSERT INTO `gameobject_template` (`entry`, `type`, `displayId`, `name`, `IconName`, `castBarCaption`, `unk1`, `size`, `Data0`, `Data1`, `Data2`, `Data3`, `Data4`, `Data5`, `Data6`, `Data7`, `Data8`, `Data9`, `Data10`, `Data11`, `Data12`, `Data13`, `Data14`, `Data15`, `Data16`, `Data17`, `Data18`, `Data19`, `Data20`, `Data21`, `Data22`, `Data23`, `AIName`, `ScriptName`, `VerifiedBuild`) VALUES
(254605, 2, 6925, 'Shrine of Challenge', '', '', '', 1.2, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 'gobject_challenge_modes', 0);
DELETE FROM `gameobject` WHERE `guid` BETWEEN 5530536 AND 5530544;
INSERT INTO `gameobject` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnMask`, `phaseMask`, `position_x`, `position_y`, `position_z`, `orientation`, `rotation0`, `rotation1`, `rotation2`, `rotation3`, `spawntimesecs`, `animprogress`, `state`, `ScriptName`, `VerifiedBuild`) VALUES
(5530536, 254605, 0, 0, 0, 1, 1, -8920.64, -178.191, 80.891, 4.3208, -0, -0, -0.83116, 0.556033, 300, 0, 1, '', 0),
(5530537, 254605, 0, 0, 0, 1, 1, -6135.29, 336.119, 402.238, 5.55195, -0, -0, -0.357526, 0.933903, 300, 0, 1, '', 0),
(5530538, 254605, 1, 0, 0, 1, 1, 10415.2, 809.575, 1318.19, 2.37082, -0, -0, -0.926654, -0.375916, 300, 0, 1, '', 0),
(5530539, 254605, 530, 0, 0, 1, 1, -4147.11, -13667.7, 75.8166, 5.06421, -0, -0, -0.572447, 0.819942, 300, 0, 1, '', 0),
(5530540, 254605, 1, 0, 0, 1, 1, -658.88, -4311.88, 45.666, 3.06225, -0, -0, -0.999213, -0.0396603, 300, 0, 1, '', 0),
(5530541, 254605, 0, 0, 0, 1, 1, 1842.91, 1651.33, 95.6206, 1.58336, -0, -0, -0.711535, -0.702651, 300, 0, 1, '', 0),
(5530542, 254605, 1, 0, 0, 1, 1, -2994.22, -136.321, 77.9491, 1.05411, -0, -0, -0.502992, -0.864291, 300, 0, 1, '', 0),
(5530543, 254605, 530, 0, 0, 1, 1, 10452, -6389.91, 43.7962, 1.84851, -0, -0, -0.798173, -0.602429, 300, 0, 1, '', 0),
(5530544, 254605, 609, 0, 0, 1, 1, 2415.84, -5649.91, 376.819, 1.87356, -0, -0, -0.805655, -0.592385, 300, 0, 1, '', 0);

View File

10
include.sh Normal file
View File

@ -0,0 +1,10 @@
#!/usr/bin/env bash
## GETS THE CURRENT MODULE ROOT DIRECTORY
MOD_SKELETON_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )/" && pwd )"
source $MOD_SKELETON_ROOT"/conf/conf.sh.dist"
if [ -f $MOD_SKELETON_ROOT"/conf/conf.sh" ]; then
source $MOD_SKELETON_ROOT"/conf/conf.sh"
fi

861
src/ChallengeModes.cpp Normal file
View File

@ -0,0 +1,861 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
*/
#include "ChallengeModes.h"
ChallengeModes* ChallengeModes::instance()
{
static ChallengeModes instance;
return &instance;
}
bool ChallengeModes::challengeEnabledForPlayer(ChallengeModeSettings setting, Player* player) const
{
if (!enabled() || !challengeEnabled(setting))
{
return false;
}
return player->GetPlayerSetting("mod-challenge-modes", setting).value;
}
bool ChallengeModes::challengeEnabled(ChallengeModeSettings setting) const
{
switch (setting)
{
case SETTING_HARDCORE:
return hardcoreEnable;
case SETTING_SEMI_HARDCORE:
return semiHardcoreEnable;
case SETTING_SELF_CRAFTED:
return selfCraftedEnable;
case SETTING_ITEM_QUALITY_LEVEL:
return itemQualityLevelEnable;
case SETTING_SLOW_XP_GAIN:
return slowXpGainEnable;
case SETTING_VERY_SLOW_XP_GAIN:
return verySlowXpGainEnable;
case SETTING_QUEST_XP_ONLY:
return questXpOnlyEnable;
case SETTING_IRON_MAN:
return ironManEnable;
case HARDCORE_DEAD:
break;
}
return false;
}
uint32 ChallengeModes::getDisableLevel(ChallengeModeSettings setting) const
{
switch (setting)
{
case SETTING_HARDCORE:
return hardcoreDisableLevel;
case SETTING_SEMI_HARDCORE:
return semiHardcoreDisableLevel;
case SETTING_SELF_CRAFTED:
return selfCraftedDisableLevel;
case SETTING_ITEM_QUALITY_LEVEL:
return itemQualityLevelDisableLevel;
case SETTING_SLOW_XP_GAIN:
return slowXpGainDisableLevel;
case SETTING_VERY_SLOW_XP_GAIN:
return verySlowXpGainDisableLevel;
case SETTING_QUEST_XP_ONLY:
return questXpOnlyDisableLevel;
case SETTING_IRON_MAN:
return ironManDisableLevel;
case HARDCORE_DEAD:
break;
}
return 0;
}
float ChallengeModes::getXpBonusForChallenge(ChallengeModeSettings setting) const
{
switch (setting)
{
case SETTING_HARDCORE:
return hardcoreXpBonus;
case SETTING_SEMI_HARDCORE:
return semiHardcoreXpBonus;
case SETTING_SELF_CRAFTED:
return selfCraftedXpBonus;
case SETTING_ITEM_QUALITY_LEVEL:
return itemQualityLevelXpBonus;
case SETTING_SLOW_XP_GAIN:
return slowXpGainBonus;
case SETTING_VERY_SLOW_XP_GAIN:
return verySlowXpGainBonus;
case SETTING_QUEST_XP_ONLY:
return questXpOnlyXpBonus;
case SETTING_IRON_MAN:
return ironManXpBonus;
case HARDCORE_DEAD:
break;
}
return 1;
}
const std::unordered_map<uint8, uint32> *ChallengeModes::getTitleMapForChallenge(ChallengeModeSettings setting) const
{
switch (setting)
{
case SETTING_HARDCORE:
return &hardcoreTitleRewards;
case SETTING_SEMI_HARDCORE:
return &semiHardcoreTitleRewards;
case SETTING_SELF_CRAFTED:
return &selfCraftedTitleRewards;
case SETTING_ITEM_QUALITY_LEVEL:
return &itemQualityLevelTitleRewards;
case SETTING_SLOW_XP_GAIN:
return &slowXpGainTitleRewards;
case SETTING_VERY_SLOW_XP_GAIN:
return &verySlowXpGainTitleRewards;
case SETTING_QUEST_XP_ONLY:
return &questXpOnlyTitleRewards;
case SETTING_IRON_MAN:
return &ironManTitleRewards;
case HARDCORE_DEAD:
break;
}
return {};
}
const std::unordered_map<uint8, uint32> *ChallengeModes::getTalentMapForChallenge(ChallengeModeSettings setting) const
{
switch (setting)
{
case SETTING_HARDCORE:
return &hardcoreTalentRewards;
case SETTING_SEMI_HARDCORE:
return &semiHardcoreTalentRewards;
case SETTING_SELF_CRAFTED:
return &selfCraftedTalentRewards;
case SETTING_ITEM_QUALITY_LEVEL:
return &itemQualityLevelTalentRewards;
case SETTING_SLOW_XP_GAIN:
return &slowXpGainTalentRewards;
case SETTING_VERY_SLOW_XP_GAIN:
return &verySlowXpGainTalentRewards;
case SETTING_QUEST_XP_ONLY:
return &questXpOnlyTalentRewards;
case SETTING_IRON_MAN:
return &ironManTalentRewards;
case HARDCORE_DEAD:
break;
}
return {};
}
const std::unordered_map<uint8, uint32> *ChallengeModes::getItemMapForChallenge(ChallengeModeSettings setting) const
{
switch (setting)
{
case SETTING_HARDCORE:
return &hardcoreItemRewards;
case SETTING_SEMI_HARDCORE:
return &semiHardcoreItemRewards;
case SETTING_SELF_CRAFTED:
return &selfCraftedItemRewards;
case SETTING_ITEM_QUALITY_LEVEL:
return &itemQualityLevelItemRewards;
case SETTING_SLOW_XP_GAIN:
return &slowXpGainItemRewards;
case SETTING_VERY_SLOW_XP_GAIN:
return &verySlowXpGainItemRewards;
case SETTING_QUEST_XP_ONLY:
return &questXpOnlyItemRewards;
case SETTING_IRON_MAN:
return &ironManItemRewards;
case HARDCORE_DEAD:
break;
}
return {};
}
uint32 ChallengeModes::getItemRewardAmount(ChallengeModeSettings setting) const
{
switch (setting)
{
case SETTING_HARDCORE:
return hardcoreItemRewardAmount;
case SETTING_SEMI_HARDCORE:
return semiHardcoreItemRewardAmount;
case SETTING_SELF_CRAFTED:
return selfCraftedItemRewardAmount;
case SETTING_ITEM_QUALITY_LEVEL:
return itemQualityLevelItemRewardAmount;
case SETTING_SLOW_XP_GAIN:
return slowXpGainItemRewardAmount;
case SETTING_VERY_SLOW_XP_GAIN:
return verySlowXpGainItemRewardAmount;
case SETTING_QUEST_XP_ONLY:
return questXpOnlyItemRewardAmount;
case SETTING_IRON_MAN:
return ironManItemRewardAmount;
case HARDCORE_DEAD:
break;
}
return 0;
}
const std::unordered_map<uint8, uint32> *ChallengeModes::getAchievementMapForChallenge(ChallengeModeSettings setting) const
{
switch (setting)
{
case SETTING_HARDCORE:
return &hardcoreAchievementReward;
case SETTING_SEMI_HARDCORE:
return &semiHardcoreAchievementReward;
case SETTING_SELF_CRAFTED:
return &selfCraftedAchievementReward;
case SETTING_ITEM_QUALITY_LEVEL:
return &itemQualityLevelAchievementReward;
case SETTING_SLOW_XP_GAIN:
return &slowXpGainAchievementReward;
case SETTING_VERY_SLOW_XP_GAIN:
return &verySlowXpGainAchievementReward;
case SETTING_QUEST_XP_ONLY:
return &questXpOnlyAchievementReward;
case SETTING_IRON_MAN:
return &ironManAchievementReward;
case HARDCORE_DEAD:
break;
}
return {};
}
class ChallengeModes_WorldScript : public WorldScript
{
public:
ChallengeModes_WorldScript()
: WorldScript("ChallengeModes_WorldScript")
{}
void OnBeforeConfigLoad(bool /*reload*/) override
{
LoadConfig();
}
private:
static void LoadStringToMap(std::unordered_map<uint8, uint32> &mapToLoad, const std::string &configString)
{
std::string delimitedValue;
std::stringstream configIdStream;
configIdStream.str(configString);
// Process each config ID in the string, delimited by the comma - "," and then space " "
while (std::getline(configIdStream, delimitedValue, ','))
{
std::string pairOne, pairTwo;
std::stringstream configPairStream(delimitedValue);
configPairStream>>pairOne>>pairTwo;
auto configLevel = atoi(pairOne.c_str());
auto rewardValue = atoi(pairTwo.c_str());
mapToLoad[configLevel] = rewardValue;
}
}
static void LoadConfig()
{
sChallengeModes->challengesEnabled = sConfigMgr->GetOption<bool>("ChallengeModes.Enable", false);
if (sChallengeModes->enabled())
{
for (auto& [confName, rewardMap] : sChallengeModes->rewardConfigMap)
{
rewardMap->clear();
LoadStringToMap(*rewardMap, sConfigMgr->GetOption<std::string>(confName, ""));
}
sChallengeModes->hardcoreEnable = sConfigMgr->GetOption<bool>("Hardcore.Enable", true);
sChallengeModes->semiHardcoreEnable = sConfigMgr->GetOption<bool>("SemiHardcore.Enable", true);
sChallengeModes->selfCraftedEnable = sConfigMgr->GetOption<bool>("SelfCrafted.Enable", true);
sChallengeModes->itemQualityLevelEnable = sConfigMgr->GetOption<bool>("ItemQualityLevel.Enable", true);
sChallengeModes->slowXpGainEnable = sConfigMgr->GetOption<bool>("SlowXpGain.Enable", true);
sChallengeModes->verySlowXpGainEnable = sConfigMgr->GetOption<bool>("VerySlowXpGain.Enable", true);
sChallengeModes->questXpOnlyEnable = sConfigMgr->GetOption<bool>("QuestXpOnly.Enable", true);
sChallengeModes->ironManEnable = sConfigMgr->GetOption<bool>("IronMan.Enable", true);
sChallengeModes->hardcoreDisableLevel = sConfigMgr->GetOption<uint32>("Hardcore.DisableLevel", 0);
sChallengeModes->semiHardcoreDisableLevel = sConfigMgr->GetOption<uint32>("SemiHardcore.DisableLevel", 0);
sChallengeModes->selfCraftedDisableLevel = sConfigMgr->GetOption<uint32>("SelfCrafted.DisableLevel", 0);
sChallengeModes->itemQualityLevelDisableLevel = sConfigMgr->GetOption<uint32>("ItemQualityLevel.DisableLevel", 0);
sChallengeModes->slowXpGainDisableLevel = sConfigMgr->GetOption<uint32>("SlowXpGain.DisableLevel", 0);
sChallengeModes->verySlowXpGainDisableLevel = sConfigMgr->GetOption<uint32>("VerySlowXpGain.DisableLevel", 0);
sChallengeModes->questXpOnlyDisableLevel = sConfigMgr->GetOption<uint32>("QuestXpOnly.DisableLevel", 0);
sChallengeModes->ironManDisableLevel = sConfigMgr->GetOption<uint32>("IronMan.DisableLevel", 0);
sChallengeModes->hardcoreXpBonus = sConfigMgr->GetOption<float>("Hardcore.XPMultiplier", 1.0f);
sChallengeModes->semiHardcoreXpBonus = sConfigMgr->GetOption<float>("SemiHardcore.XPMultiplier", 1.0f);
sChallengeModes->selfCraftedXpBonus = sConfigMgr->GetOption<float>("SelfCrafted.XPMultiplier", 1.0f);
sChallengeModes->itemQualityLevelXpBonus = sConfigMgr->GetOption<float>("ItemQualityLevel.XPMultiplier", 1.0f);
sChallengeModes->questXpOnlyXpBonus = sConfigMgr->GetOption<float>("QuestXpOnly.XPMultiplier", 1.0f);
sChallengeModes->slowXpGainBonus = sConfigMgr->GetOption<float>("SlowXpGain.XPMultiplier", 0.50f);
sChallengeModes->verySlowXpGainBonus = sConfigMgr->GetOption<float>("VerySlowXpGain.XPMultiplier", 0.25f);
sChallengeModes->ironManXpBonus = sConfigMgr->GetOption<float>("IronMan.XPMultiplier", 1.0f);
sChallengeModes->hardcoreItemRewardAmount = sConfigMgr->GetOption<uint32>("Hardcore.ItemRewardAmount", 1);
sChallengeModes->semiHardcoreItemRewardAmount = sConfigMgr->GetOption<uint32>("SemiHardcore.ItemRewardAmount", 1);
sChallengeModes->selfCraftedItemRewardAmount = sConfigMgr->GetOption<uint32>("SelfCrafted.ItemRewardAmount", 1);
sChallengeModes->itemQualityLevelItemRewardAmount = sConfigMgr->GetOption<uint32>("ItemQualityLevel.ItemRewardAmount", 1);
sChallengeModes->slowXpGainItemRewardAmount = sConfigMgr->GetOption<uint32>("SlowXpGain.ItemRewardAmount", 1);
sChallengeModes->verySlowXpGainItemRewardAmount = sConfigMgr->GetOption<uint32>("VerySlowXpGain.ItemRewardAmount", 1);
sChallengeModes->questXpOnlyItemRewardAmount = sConfigMgr->GetOption<uint32>("QuestXpOnly.ItemRewardAmount", 1);
sChallengeModes->ironManItemRewardAmount = sConfigMgr->GetOption<uint32>("IronMan.ItemRewardAmount", 1);
LoadStringToMap(sChallengeModes->hardcoreAchievementReward, sConfigMgr->GetOption<std::string>("Hardcore.AchievementReward", ""));
LoadStringToMap(sChallengeModes->semiHardcoreAchievementReward, sConfigMgr->GetOption<std::string>("SemiHardcore.AchievementReward", ""));
LoadStringToMap(sChallengeModes->selfCraftedAchievementReward, sConfigMgr->GetOption<std::string>("SelfCrafted.AchievementReward", ""));
LoadStringToMap(sChallengeModes->itemQualityLevelAchievementReward, sConfigMgr->GetOption<std::string>("ItemQualityLevel.AchievementReward", ""));
LoadStringToMap(sChallengeModes->slowXpGainAchievementReward, sConfigMgr->GetOption<std::string>("SlowXpGain.AchievementReward", ""));
LoadStringToMap(sChallengeModes->verySlowXpGainAchievementReward, sConfigMgr->GetOption<std::string>("VerySlowXpGain.AchievementReward", ""));
LoadStringToMap(sChallengeModes->questXpOnlyAchievementReward, sConfigMgr->GetOption<std::string>("QuestXpOnly.AchievementReward", ""));
LoadStringToMap(sChallengeModes->ironManAchievementReward, sConfigMgr->GetOption<std::string>("IronMan.AchievementReward", ""));
}
}
};
class ChallengeMode : public PlayerScript
{
public:
explicit ChallengeMode(const char *scriptName,
ChallengeModeSettings settingName)
: PlayerScript(scriptName), settingName(settingName)
{ }
static bool mapContainsKey(const std::unordered_map<uint8, uint32>* mapToCheck, uint8 key)
{
return (mapToCheck->find(key) != mapToCheck->end());
}
void OnPlayerGiveXP(Player* player, uint32& amount, Unit* /*victim*/, uint8 /*xpSource*/) override
{
if (!sChallengeModes->challengeEnabledForPlayer(settingName, player))
{
return;
}
amount *= sChallengeModes->getXpBonusForChallenge(settingName);
}
void OnPlayerLevelChanged(Player* player, uint8 /*oldlevel*/) override
{
if (!sChallengeModes->challengeEnabledForPlayer(settingName, player))
{
return;
}
const std::unordered_map<uint8, uint32>* titleRewardMap = sChallengeModes->getTitleMapForChallenge(settingName);
const std::unordered_map<uint8, uint32>* talentRewardMap = sChallengeModes->getTalentMapForChallenge(settingName);
const std::unordered_map<uint8, uint32>* itemRewardMap = sChallengeModes->getItemMapForChallenge(settingName);
const std::unordered_map<uint8, uint32>* achievementRewardMap = sChallengeModes->getAchievementMapForChallenge(settingName);
uint8 level = player->GetLevel();
if (mapContainsKey(titleRewardMap, level))
{
CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(titleRewardMap->at(level));
if (!titleInfo)
{
LOG_ERROR("mod-challenge-modes", "Invalid title ID {}!", titleRewardMap->at(level));
return;
}
ChatHandler handler(player->GetSession());
std::string tNameLink = handler.GetNameLink(player);
std::string titleNameStr = Acore::StringFormat(player->getGender() == GENDER_MALE ? titleInfo->nameMale[handler.GetSessionDbcLocale()] : titleInfo->nameFemale[handler.GetSessionDbcLocale()], player->GetName());
player->SetTitle(titleInfo);
}
if (mapContainsKey(talentRewardMap, level))
{
player->RewardExtraBonusTalentPoints(talentRewardMap->at(level));
}
if (mapContainsKey(achievementRewardMap, level))
{
AchievementEntry const* achievementInfo = sAchievementStore.LookupEntry(achievementRewardMap->at(level));
if (!achievementInfo)
{
LOG_ERROR("mod-challenge-modes", "Invalid Achievement ID {}!", achievementRewardMap->at(level));
return;
}
ChatHandler handler(player->GetSession());
std::string tNameLink = handler.GetNameLink(player);
player->CompletedAchievement(achievementInfo);
}
if (mapContainsKey(itemRewardMap, level))
{
uint32 itemEntry = itemRewardMap->at(level);
uint32 itemAmount = sChallengeModes->getItemRewardAmount(settingName); // Fetch item amount from config
player->SendItemRetrievalMail({ { itemEntry, itemAmount } });
}
if (sChallengeModes->getDisableLevel(settingName) && sChallengeModes->getDisableLevel(settingName) <= level)
{
player->UpdatePlayerSetting("mod-challenge-modes", settingName, 0);
}
}
private:
ChallengeModeSettings settingName;
};
class ChallengeMode_Hardcore : public ChallengeMode
{
public:
ChallengeMode_Hardcore() : ChallengeMode("ChallengeMode_Hardcore", SETTING_HARDCORE) {}
void OnPlayerLogin(Player* player) override
{
if (!sChallengeModes->challengeEnabledForPlayer(SETTING_HARDCORE, player) || !sChallengeModes->challengeEnabledForPlayer(HARDCORE_DEAD, player))
{
return;
}
player->KillPlayer();
player->GetSession()->KickPlayer("Hardcore character died");
}
void OnPlayerReleasedGhost(Player* player) override
{
if (!sChallengeModes->challengeEnabledForPlayer(SETTING_HARDCORE, player))
{
return;
}
player->UpdatePlayerSetting("mod-challenge-modes", HARDCORE_DEAD, 1);
player->GetSession()->KickPlayer("Hardcore character died");
}
void OnPlayerPVPKill(Player* /*killer*/, Player* killed) override
{
if (!sChallengeModes->challengeEnabledForPlayer(SETTING_HARDCORE, killed))
{
return;
}
killed->UpdatePlayerSetting("mod-challenge-modes", HARDCORE_DEAD, 1);
}
void OnPlayerKilledByCreature(Creature* /*killer*/, Player* killed) override
{
if (!sChallengeModes->challengeEnabledForPlayer(SETTING_HARDCORE, killed))
{
return;
}
killed->UpdatePlayerSetting("mod-challenge-modes", HARDCORE_DEAD, 1);
}
void OnPlayerResurrect(Player* player, float /*restore_percent*/, bool /*applySickness*/) override
{
if (!sChallengeModes->challengeEnabledForPlayer(SETTING_HARDCORE, player))
{
return;
}
// A better implementation is to not allow the resurrect but this will need a new hook added first
player->UpdatePlayerSetting("mod-challenge-modes", HARDCORE_DEAD, 1);
player->KillPlayer();
player->GetSession()->KickPlayer("Hardcore character died");
}
void OnPlayerGiveXP(Player* player, uint32& amount, Unit* victim, uint8 xpSource) override
{
ChallengeMode::OnPlayerGiveXP(player, amount, victim, xpSource);
}
void OnPlayerLevelChanged(Player* player, uint8 oldlevel) override
{
ChallengeMode::OnPlayerLevelChanged(player, oldlevel);
}
};
class ChallengeMode_SemiHardcore : public ChallengeMode
{
public:
ChallengeMode_SemiHardcore() : ChallengeMode("ChallengeMode_SemiHardcore", SETTING_SEMI_HARDCORE) {}
void OnPlayerKilledByCreature(Creature* /*killer*/, Player* player) override
{
if (!sChallengeModes->challengeEnabledForPlayer(SETTING_SEMI_HARDCORE, player))
{
return;
}
for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
{
if (Item* pItem = player->GetItemByPos(INVENTORY_SLOT_BAG_0, i))
{
if (pItem->GetTemplate() && !pItem->IsEquipped())
continue;
uint8 slot = pItem->GetSlot();
ChatHandler(player->GetSession()).PSendSysMessage("|cffDA70D6You have lost your |cffffffff|Hitem:%d:0:0:0:0:0:0:0:0|h[%s]|h|r", pItem->GetEntry(), pItem->GetTemplate()->Name1.c_str());
player->DestroyItem(INVENTORY_SLOT_BAG_0, slot, true);
}
}
player->SetMoney(0);
}
void OnPlayerGiveXP(Player* player, uint32& amount, Unit* victim, uint8 xpSource) override
{
ChallengeMode::OnPlayerGiveXP(player, amount, victim, xpSource);
}
void OnPlayerLevelChanged(Player* player, uint8 oldlevel) override
{
ChallengeMode::OnPlayerLevelChanged(player, oldlevel);
}
};
class ChallengeMode_SelfCrafted : public ChallengeMode
{
public:
ChallengeMode_SelfCrafted() : ChallengeMode("ChallengeMode_SelfCrafted", SETTING_SELF_CRAFTED) {}
bool OnPlayerCanEquipItem(Player* player, uint8 /*slot*/, uint16& /*dest*/, Item* pItem, bool /*swap*/, bool /*not_loading*/) override
{
if (!sChallengeModes->challengeEnabledForPlayer(SETTING_SELF_CRAFTED, player))
{
return true;
}
if (!pItem->GetTemplate()->HasSignature())
{
return false;
}
return pItem->GetGuidValue(ITEM_FIELD_CREATOR) == player->GetGUID();
}
void OnPlayerGiveXP(Player* player, uint32& amount, Unit* victim, uint8 xpSource) override
{
ChallengeMode::OnPlayerGiveXP(player, amount, victim, xpSource);
}
void OnPlayerLevelChanged(Player* player, uint8 oldlevel) override
{
ChallengeMode::OnPlayerLevelChanged(player, oldlevel);
}
};
class ChallengeMode_ItemQualityLevel : public ChallengeMode
{
public:
ChallengeMode_ItemQualityLevel() : ChallengeMode("ChallengeMode_ItemQualityLevel", SETTING_ITEM_QUALITY_LEVEL) {}
bool OnPlayerCanEquipItem(Player* player, uint8 /*slot*/, uint16& /*dest*/, Item* pItem, bool /*swap*/, bool /*not_loading*/) override
{
if (!sChallengeModes->challengeEnabledForPlayer(SETTING_ITEM_QUALITY_LEVEL, player))
{
return true;
}
return pItem->GetTemplate()->Quality <= ITEM_QUALITY_NORMAL;
}
void OnPlayerGiveXP(Player* player, uint32& amount, Unit* victim, uint8 xpSource) override
{
ChallengeMode::OnPlayerGiveXP(player, amount, victim, xpSource);
}
void OnPlayerLevelChanged(Player* player, uint8 oldlevel) override
{
ChallengeMode::OnPlayerLevelChanged(player, oldlevel);
}
};
class ChallengeMode_SlowXpGain : public ChallengeMode
{
public:
ChallengeMode_SlowXpGain() : ChallengeMode("ChallengeMode_SlowXpGain", SETTING_SLOW_XP_GAIN) {}
void OnPlayerGiveXP(Player* player, uint32& amount, Unit* victim, uint8 xpSource) override
{
ChallengeMode::OnPlayerGiveXP(player, amount, victim, xpSource);
}
void OnPlayerLevelChanged(Player* player, uint8 oldlevel) override
{
ChallengeMode::OnPlayerLevelChanged(player, oldlevel);
}
};
class ChallengeMode_VerySlowXpGain : public ChallengeMode
{
public:
ChallengeMode_VerySlowXpGain() : ChallengeMode("ChallengeMode_VerySlowXpGain", SETTING_VERY_SLOW_XP_GAIN) {}
void OnPlayerGiveXP(Player* player, uint32& amount, Unit* victim, uint8 xpSource) override
{
ChallengeMode::OnPlayerGiveXP(player, amount, victim, xpSource);
}
void OnPlayerLevelChanged(Player* player, uint8 oldlevel) override
{
ChallengeMode::OnPlayerLevelChanged(player, oldlevel);
}
};
class ChallengeMode_QuestXpOnly : public ChallengeMode
{
public:
ChallengeMode_QuestXpOnly() : ChallengeMode("ChallengeMode_QuestXpOnly", SETTING_QUEST_XP_ONLY) {}
void OnPlayerGiveXP(Player* player, uint32& amount, Unit* victim, uint8 xpSource) override
{
if (!sChallengeModes->challengeEnabledForPlayer(SETTING_QUEST_XP_ONLY, player))
{
return;
}
if (victim)
{
// Still award XP to pets - they won't be able to pass the player's level
Pet* pet = player->GetPet();
if (pet && xpSource == XPSOURCE_KILL)
pet->GivePetXP(player->GetGroup() ? amount / 2 : amount);
amount = 0;
}
else
{
ChallengeMode::OnPlayerGiveXP(player, amount, victim, xpSource);
}
}
void OnPlayerLevelChanged(Player* player, uint8 oldlevel) override
{
ChallengeMode::OnPlayerLevelChanged(player, oldlevel);
}
};
class ChallengeMode_IronMan : public ChallengeMode
{
public:
ChallengeMode_IronMan() : ChallengeMode("ChallengeMode_IronMan", SETTING_IRON_MAN) {}
void OnPlayerResurrect(Player* player, float /*restore_percent*/, bool /*applySickness*/) override
{
if (!sChallengeModes->challengeEnabledForPlayer(SETTING_IRON_MAN, player))
{
return;
}
// A better implementation is to not allow the resurrect but this will need a new hook added first
player->KillPlayer();
}
void OnPlayerGiveXP(Player* player, uint32& amount, Unit* victim, uint8 xpSource) override
{
ChallengeMode::OnPlayerGiveXP(player, amount, victim, xpSource);
}
void OnPlayerLevelChanged(Player* player, uint8 oldlevel) override
{
if (!sChallengeModes->challengeEnabledForPlayer(SETTING_IRON_MAN, player))
{
return;
}
player->SetFreeTalentPoints(0); // Remove all talent points
ChallengeMode::OnPlayerLevelChanged(player, oldlevel);
}
void OnPlayerTalentsReset(Player* player, bool /*noCost*/) override
{
if (!sChallengeModes->challengeEnabledForPlayer(SETTING_IRON_MAN, player))
{
return;
}
player->SetFreeTalentPoints(0); // Remove all talent points
}
bool OnPlayerCanEquipItem(Player* player, uint8 /*slot*/, uint16& /*dest*/, Item* pItem, bool /*swap*/, bool /*not_loading*/) override
{
if (!sChallengeModes->challengeEnabledForPlayer(SETTING_IRON_MAN, player))
{
return true;
}
return pItem->GetTemplate()->Quality <= ITEM_QUALITY_NORMAL;
}
bool OnPlayerCanApplyEnchantment(Player* player, Item* /*item*/, EnchantmentSlot /*slot*/, bool /*apply*/, bool /*apply_dur*/, bool /*ignore_condition*/) override
{
if (!sChallengeModes->challengeEnabledForPlayer(SETTING_IRON_MAN, player))
{
return true;
}
// Are there any exceptions in WotLK? If so need to be added here
return false;
}
void OnPlayerLearnSpell(Player* player, uint32 spellID) override
{
if (!sChallengeModes->challengeEnabledForPlayer(SETTING_IRON_MAN, player))
{
return;
}
// These professions are class skills so they are always acceptable
switch (spellID)
{
case RUNEFORGING:
case POISONS:
case BEAST_TRAINING:
return;
default:
break;
}
// Do not allow learning any trade skills
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID);
if (!spellInfo)
return;
bool shouldForget = false;
for (uint8 i = 0; i < 3; i++)
{
if (spellInfo->Effects[i].Effect == SPELL_EFFECT_TRADE_SKILL)
{
shouldForget = true;
}
}
if (shouldForget)
{
player->removeSpell(spellID, SPEC_MASK_ALL, false);
}
}
bool CanUseItem(Player* player, ItemTemplate const* proto, InventoryResult& /*result*/) override
{
if (!sChallengeModes->challengeEnabledForPlayer(SETTING_IRON_MAN, player))
{
return true;
}
// Do not allow using elixir, potion, or flask
if (proto->Class == ITEM_CLASS_CONSUMABLE &&
(proto->SubClass == ITEM_SUBCLASS_POTION ||
proto->SubClass == ITEM_SUBCLASS_ELIXIR ||
proto->SubClass == ITEM_SUBCLASS_FLASK))
{
return false;
}
// Do not allow food that gives food buffs
if (proto->Class == ITEM_CLASS_CONSUMABLE && proto->SubClass == ITEM_SUBCLASS_FOOD)
{
for (const auto & Spell : proto->Spells)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(Spell.SpellId);
if (!spellInfo)
continue;
for (uint8 i = 0; i < 3; i++)
{
if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_PERIODIC_TRIGGER_SPELL)
{
return false;
}
}
}
}
return true;
}
bool CanGroupInvite(Player* player, std::string& /*membername*/) override
{
if (!sChallengeModes->challengeEnabledForPlayer(SETTING_IRON_MAN, player))
{
return true;
}
return false;
}
bool OnPlayerCanGroupAccept(Player* player, Group* /*group*/) override
{
if (!sChallengeModes->challengeEnabledForPlayer(SETTING_IRON_MAN, player))
{
return true;
}
return false;
}
};
class gobject_challenge_modes : public GameObjectScript
{
private:
static bool playerSettingEnabled(Player* player, uint8 settingIndex)
{
return player->GetPlayerSetting("mod-challenge-modes", settingIndex).value;
}
public:
gobject_challenge_modes() : GameObjectScript("gobject_challenge_modes") { }
struct gobject_challenge_modesAI: GameObjectAI
{
explicit gobject_challenge_modesAI(GameObject* object) : GameObjectAI(object) { };
bool CanBeSeen(Player const* player) override
{
if ((player->GetLevel() > 1 && player->getClass() != CLASS_DEATH_KNIGHT) || (player->GetLevel() > 55))
{
return false;
}
return sChallengeModes->enabled();
}
};
bool OnGossipHello(Player* player, GameObject* go) override
{
if (sChallengeModes->challengeEnabled(SETTING_HARDCORE) && !playerSettingEnabled(player, SETTING_HARDCORE) && !playerSettingEnabled(player, SETTING_SEMI_HARDCORE))
{
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Enable Hardcore Mode", 0, SETTING_HARDCORE);
}
if (sChallengeModes->challengeEnabled(SETTING_SEMI_HARDCORE) && !playerSettingEnabled(player, SETTING_HARDCORE) && !playerSettingEnabled(player, SETTING_SEMI_HARDCORE))
{
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Enable Semi-Hardcore Mode", 0, SETTING_SEMI_HARDCORE);
}
if (sChallengeModes->challengeEnabled(SETTING_SELF_CRAFTED) && !playerSettingEnabled(player, SETTING_SELF_CRAFTED) && !playerSettingEnabled(player, SETTING_IRON_MAN))
{
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Enable Self-Crafted Mode", 0, SETTING_SELF_CRAFTED);
}
if (sChallengeModes->challengeEnabled(SETTING_ITEM_QUALITY_LEVEL) && !playerSettingEnabled(player, SETTING_ITEM_QUALITY_LEVEL))
{
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Enable Low Quality Item Mode", 0, SETTING_ITEM_QUALITY_LEVEL);
}
if (sChallengeModes->challengeEnabled(SETTING_SLOW_XP_GAIN) && !playerSettingEnabled(player, SETTING_SLOW_XP_GAIN) && !playerSettingEnabled(player, SETTING_VERY_SLOW_XP_GAIN))
{
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Enable Slow XP Mode", 0, SETTING_SLOW_XP_GAIN);
}
if (sChallengeModes->challengeEnabled(SETTING_VERY_SLOW_XP_GAIN) && !playerSettingEnabled(player, SETTING_SLOW_XP_GAIN) && !playerSettingEnabled(player, SETTING_VERY_SLOW_XP_GAIN))
{
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Enable Very Slow XP Mode", 0, SETTING_VERY_SLOW_XP_GAIN);
}
if (sChallengeModes->challengeEnabled(SETTING_QUEST_XP_ONLY) && !playerSettingEnabled(player, SETTING_QUEST_XP_ONLY))
{
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Enable Quest XP Only Mode", 0, SETTING_QUEST_XP_ONLY);
}
if (sChallengeModes->challengeEnabled(SETTING_IRON_MAN) && !playerSettingEnabled(player, SETTING_IRON_MAN) && !playerSettingEnabled(player, SETTING_SELF_CRAFTED))
{
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Enable Iron Man Mode", 0, SETTING_IRON_MAN);
}
SendGossipMenuFor(player, 12669, go->GetGUID());
return true;
}
bool OnGossipSelect(Player* player, GameObject* /*go*/, uint32 /*sender*/, uint32 action) override
{
player->UpdatePlayerSetting("mod-challenge-modes", action, 1);
ChatHandler(player->GetSession()).PSendSysMessage("Challenge enabled.");
CloseGossipMenuFor(player);
return true;
}
GameObjectAI* GetAI(GameObject* object) const override
{
return new gobject_challenge_modesAI(object);
}
};
// Add all scripts in one
void AddSC_mod_challenge_modes()
{
new ChallengeModes_WorldScript();
new gobject_challenge_modes();
new ChallengeMode_Hardcore();
new ChallengeMode_SemiHardcore();
new ChallengeMode_SelfCrafted();
new ChallengeMode_ItemQualityLevel();
new ChallengeMode_SlowXpGain();
new ChallengeMode_VerySlowXpGain();
new ChallengeMode_QuestXpOnly();
new ChallengeMode_IronMan();
}

106
src/ChallengeModes.h Normal file
View File

@ -0,0 +1,106 @@
#ifndef AZEROTHCORE_CHALLENGEMODES_H
#define AZEROTHCORE_CHALLENGEMODES_H
#include "ScriptMgr.h"
#include "Player.h"
#include "Config.h"
#include "Chat.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "SpellMgr.h"
#include "Item.h"
#include "ItemTemplate.h"
#include "GameObjectAI.h"
#include "Pet.h"
#include <map>
enum ChallengeModeSettings
{
SETTING_HARDCORE = 0,
SETTING_SEMI_HARDCORE = 1,
SETTING_SELF_CRAFTED = 2,
SETTING_ITEM_QUALITY_LEVEL = 3,
SETTING_SLOW_XP_GAIN = 4,
SETTING_VERY_SLOW_XP_GAIN = 5,
SETTING_QUEST_XP_ONLY = 6,
SETTING_IRON_MAN = 7,
HARDCORE_DEAD = 8
};
enum AllowedProfessions
{
RUNEFORGING = 53428,
POISONS = 2842,
BEAST_TRAINING = 5149
};
class ChallengeModes
{
public:
static ChallengeModes* instance();
bool challengesEnabled, hardcoreEnable, semiHardcoreEnable, selfCraftedEnable, itemQualityLevelEnable, slowXpGainEnable, verySlowXpGainEnable, questXpOnlyEnable, ironManEnable;
uint32 hardcoreDisableLevel, semiHardcoreDisableLevel, selfCraftedDisableLevel, itemQualityLevelDisableLevel, slowXpGainDisableLevel, verySlowXpGainDisableLevel, questXpOnlyDisableLevel, ironManDisableLevel, hardcoreItemRewardAmount, semiHardcoreItemRewardAmount, selfCraftedItemRewardAmount, itemQualityLevelItemRewardAmount, slowXpGainItemRewardAmount, verySlowXpGainItemRewardAmount, questXpOnlyItemRewardAmount, ironManItemRewardAmount;
float hardcoreXpBonus, semiHardcoreXpBonus, selfCraftedXpBonus, itemQualityLevelXpBonus, questXpOnlyXpBonus, slowXpGainBonus, verySlowXpGainBonus, ironManXpBonus;
std::unordered_map<uint8, uint32> hardcoreTitleRewards, semiHardcoreTitleRewards, selfCraftedTitleRewards, itemQualityLevelTitleRewards, slowXpGainTitleRewards, verySlowXpGainTitleRewards, questXpOnlyTitleRewards, ironManTitleRewards;
std::unordered_map<uint8, uint32> hardcoreItemRewards, semiHardcoreItemRewards, selfCraftedItemRewards, itemQualityLevelItemRewards, slowXpGainItemRewards, verySlowXpGainItemRewards, questXpOnlyItemRewards, ironManItemRewards;
std::unordered_map<uint8, uint32> hardcoreTalentRewards, semiHardcoreTalentRewards, selfCraftedTalentRewards, itemQualityLevelTalentRewards, slowXpGainTalentRewards, verySlowXpGainTalentRewards, questXpOnlyTalentRewards, ironManTalentRewards;
std::unordered_map<uint8, uint32> hardcoreAchievementReward, semiHardcoreAchievementReward, selfCraftedAchievementReward, itemQualityLevelAchievementReward, slowXpGainAchievementReward, verySlowXpGainAchievementReward, questXpOnlyAchievementReward, ironManAchievementReward;
std::unordered_map<std::string, std::unordered_map<uint8, uint32>*> rewardConfigMap =
{
{ "Hardcore.TitleRewards", &hardcoreTitleRewards },
{ "SemiHardcore.TitleRewards", &semiHardcoreTitleRewards },
{ "SelfCrafted.TitleRewards", &selfCraftedTitleRewards },
{ "ItemQualityLevel.TitleRewards", &itemQualityLevelTitleRewards },
{ "SlowXpGain.TitleRewards", &slowXpGainTitleRewards },
{ "VerySlowXpGain.TitleRewards", &verySlowXpGainTitleRewards },
{ "QuestXpOnly.TitleRewards", &questXpOnlyTitleRewards },
{ "IronMan.TitleRewards", &ironManTitleRewards },
{ "Hardcore.TalentRewards", &hardcoreTalentRewards },
{ "SemiHardcore.TalentRewards", &semiHardcoreTalentRewards },
{ "SelfCrafted.TalentRewards", &selfCraftedTalentRewards },
{ "ItemQualityLevel.TalentRewards", &itemQualityLevelTalentRewards },
{ "SlowXpGain.TalentRewards", &slowXpGainTalentRewards },
{ "VerySlowXpGain.TalentRewards", &verySlowXpGainTalentRewards },
{ "QuestXpOnly.TalentRewards", &questXpOnlyTalentRewards },
{ "IronMan.TalentRewards", &ironManTalentRewards },
{ "Hardcore.ItemRewards", &hardcoreItemRewards },
{ "SemiHardcore.ItemRewards", &semiHardcoreItemRewards },
{ "SelfCrafted.ItemRewards", &selfCraftedItemRewards },
{ "ItemQualityLevel.ItemRewards", &itemQualityLevelItemRewards },
{ "SlowXpGain.ItemRewards", &slowXpGainItemRewards },
{ "VerySlowXpGain.ItemRewards", &verySlowXpGainItemRewards },
{ "QuestXpOnly.ItemRewards", &questXpOnlyItemRewards },
{ "IronMan.ItemRewards", &ironManItemRewards },
{ "Hardcore.AchievementReward", &hardcoreAchievementReward },
{ "SemiHardcore.AchievementReward", &semiHardcoreAchievementReward },
{ "SelfCrafted.AchievementReward", &selfCraftedAchievementReward },
{ "ItemQualityLevel.AchievementReward", &itemQualityLevelAchievementReward },
{ "SlowXpGain.AchievementReward", &slowXpGainAchievementReward },
{ "VerySlowXpGain.AchievementReward", &verySlowXpGainAchievementReward },
{ "QuestXpOnly.AchievementReward", &questXpOnlyAchievementReward },
{ "IronMan.AchievementReward", &ironManAchievementReward }
};
[[nodiscard]] bool enabled() const { return challengesEnabled; }
[[nodiscard]] bool challengeEnabled(ChallengeModeSettings setting) const;
[[nodiscard]] uint32 getDisableLevel(ChallengeModeSettings setting) const;
[[nodiscard]] float getXpBonusForChallenge(ChallengeModeSettings setting) const;
bool challengeEnabledForPlayer(ChallengeModeSettings setting, Player* player) const;
[[nodiscard]] const std::unordered_map<uint8, uint32> *getTitleMapForChallenge(ChallengeModeSettings setting) const;
[[nodiscard]] const std::unordered_map<uint8, uint32> *getTalentMapForChallenge(ChallengeModeSettings setting) const;
[[nodiscard]] const std::unordered_map<uint8, uint32> *getItemMapForChallenge(ChallengeModeSettings setting) const;
[[nodiscard]] const std::unordered_map<uint8, uint32> *getAchievementMapForChallenge(ChallengeModeSettings setting) const;
[[nodiscard]] uint32 getItemRewardAmount(ChallengeModeSettings setting) const;
};
#define sChallengeModes ChallengeModes::instance()
#endif //AZEROTHCORE_CHALLENGEMODES_H

View File

@ -0,0 +1,14 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
*/
// From SC
void AddSC_mod_challenge_modes();
// Add all
// cf. the naming convention https://github.com/azerothcore/azerothcore-wotlk/blob/master/doc/changelog/master.md#how-to-upgrade-4
// additionally replace all '-' in the module folder name with '_' here
void Addmod_challenge_modesScripts()
{
AddSC_mod_challenge_modes();
}