aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Player/Player.cpp8
-rw-r--r--src/server/game/Miscellaneous/Formulas.h7
-rw-r--r--src/server/game/Quests/QuestDef.cpp27
-rw-r--r--src/server/game/Quests/QuestDef.h3
-rw-r--r--src/server/game/World/World.cpp22
-rw-r--r--src/server/game/World/World.h3
-rw-r--r--src/server/worldserver/worldserver.conf.dist28
7 files changed, 89 insertions, 9 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index a4db0980f70..70e7286f1f7 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -6111,6 +6111,12 @@ void Player::CheckAreaExploreAndOutdoor()
XP = uint32(sObjectMgr->GetBaseXP(areaLevel) * sWorld->getRate(RATE_XP_EXPLORE));
}
+ if (sWorld->getIntConfig(CONFIG_MIN_DISCOVERED_SCALED_XP_RATIO))
+ {
+ uint32 minScaledXP = uint32(sObjectMgr->GetBaseXP(areaLevel)*sWorld->getRate(RATE_XP_EXPLORE)) * sWorld->getIntConfig(CONFIG_MIN_DISCOVERED_SCALED_XP_RATIO) / 100;
+ XP = std::max(minScaledXP, XP);
+ }
+
GiveXP(XP, nullptr);
SendExplorationExperience(areaId, XP);
}
@@ -25471,7 +25477,7 @@ bool Player::isHonorOrXPTarget(Unit const* victim) const
uint8 k_grey = Trinity::XP::GetGrayLevel(getLevel());
// Victim level less gray level
- if (v_level < k_grey)
+ if (v_level < k_grey && !sWorld->getIntConfig(CONFIG_MIN_CREATURE_SCALED_XP_RATIO))
return false;
if (Creature const* const creature = victim->ToCreature())
diff --git a/src/server/game/Miscellaneous/Formulas.h b/src/server/game/Miscellaneous/Formulas.h
index c49dc93d86a..aad2bc5c4f0 100644
--- a/src/server/game/Miscellaneous/Formulas.h
+++ b/src/server/game/Miscellaneous/Formulas.h
@@ -163,6 +163,13 @@ namespace Trinity
baseGain = 0;
}
+ if (sWorld->getIntConfig(CONFIG_MIN_CREATURE_SCALED_XP_RATIO) && pl_level != mob_level)
+ {
+ // Use mob level instead of player level to avoid overscaling on gain in a min is enforced
+ uint32 baseGainMin = BaseGain(pl_level, pl_level) * sWorld->getIntConfig(CONFIG_MIN_CREATURE_SCALED_XP_RATIO) / 100;
+ baseGain = std::max(baseGainMin, baseGain);
+ }
+
sScriptMgr->OnBaseGainCalculation(baseGain, pl_level, mob_level);
return baseGain;
}
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index 3dbd3d173d0..c252076c3c4 100644
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -291,14 +291,13 @@ uint32 Quest::XPValue(Player const* player) const
if (player->getLevel() >= GetMaxLevelForExpansion(CURRENT_EXPANSION - 1) && player->GetSession()->GetExpansion() == CURRENT_EXPANSION && _expansion < CURRENT_EXPANSION)
xp = uint32(xp / 9.0f);
- if (xp <= 100)
- xp = 5 * ((xp + 2) / 5);
- else if (xp <= 500)
- xp = 10 * ((xp + 5) / 10);
- else if (xp <= 1000)
- xp = 25 * ((xp + 12) / 25);
- else
- xp = 50 * ((xp + 25) / 50);
+ xp = RoundXPValue(xp);
+
+ if (sWorld->getIntConfig(CONFIG_MIN_QUEST_SCALED_XP_RATIO))
+ {
+ uint32 minScaledXP = RoundXPValue(questXp->Difficulty[_rewardXPDifficulty] * _rewardXPMultiplier) * sWorld->getIntConfig(CONFIG_MIN_QUEST_SCALED_XP_RATIO) / 100;
+ xp = std::max(minScaledXP, xp);
+ }
return xp;
}
@@ -597,3 +596,15 @@ WorldPacket Quest::BuildQueryData(LocaleConstant loc) const
return *response.Write();
}
+
+uint32 Quest::RoundXPValue(uint32 xp)
+{
+ if (xp <= 100)
+ return 5 * ((xp + 2) / 5);
+ else if (xp <= 500)
+ return 10 * ((xp + 5) / 10);
+ else if (xp <= 1000)
+ return 25 * ((xp + 12) / 25);
+ else
+ return 50 * ((xp + 25) / 50);
+}
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index 2fb49a684e5..600111bd856 100644
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -665,6 +665,9 @@ class TC_GAME_API Quest
uint32 _rewardMailSenderEntry = 0;
uint32 _specialFlags = 0; // custom flags, not sniffed/WDB
uint32 _scriptId = 0;
+
+ // Helpers
+ static uint32 RoundXPValue(uint32 xp);
};
struct QuestStatusData
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 9262ec58840..ac3e096e1fd 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -817,6 +817,28 @@ void World::LoadConfigSettings(bool reload)
m_float_configs[CONFIG_GROUP_XP_DISTANCE] = sConfigMgr->GetFloatDefault("MaxGroupXPDistance", 74.0f);
m_float_configs[CONFIG_MAX_RECRUIT_A_FRIEND_DISTANCE] = sConfigMgr->GetFloatDefault("MaxRecruitAFriendBonusDistance", 100.0f);
+ m_int_configs[CONFIG_MIN_QUEST_SCALED_XP_RATIO] = sConfigMgr->GetIntDefault("MinQuestScaledXPRatio", 0);
+ if (m_int_configs[CONFIG_MIN_QUEST_SCALED_XP_RATIO] > 100)
+ {
+ TC_LOG_ERROR("server.loading", "MinQuestScaledXPRatio (%i) must be in range 0..100. Set to 0.", m_int_configs[CONFIG_MIN_QUEST_SCALED_XP_RATIO]);
+ m_int_configs[CONFIG_MIN_QUEST_SCALED_XP_RATIO] = 0;
+ }
+
+ m_int_configs[CONFIG_MIN_CREATURE_SCALED_XP_RATIO] = sConfigMgr->GetIntDefault("MinCreatureScaledXPRatio", 0);
+ if (m_int_configs[CONFIG_MIN_CREATURE_SCALED_XP_RATIO] > 100)
+ {
+ TC_LOG_ERROR("server.loading", "MinCreatureScaledXPRatio (%i) must be in range 0..100. Set to 0.", m_int_configs[CONFIG_MIN_CREATURE_SCALED_XP_RATIO]);
+ m_int_configs[CONFIG_MIN_CREATURE_SCALED_XP_RATIO] = 0;
+ }
+
+ m_int_configs[CONFIG_MIN_DISCOVERED_SCALED_XP_RATIO] = sConfigMgr->GetIntDefault("MinDiscoveredScaledXPRatio", 0);
+ if (m_int_configs[CONFIG_MIN_DISCOVERED_SCALED_XP_RATIO] > 100)
+ {
+ TC_LOG_ERROR("server.loading", "MinDiscoveredScaledXPRatio (%i) must be in range 0..100. Set to 0.", m_int_configs[CONFIG_MIN_DISCOVERED_SCALED_XP_RATIO]);
+ m_int_configs[CONFIG_MIN_DISCOVERED_SCALED_XP_RATIO] = 0;
+ }
+
+ /// @todo Add MonsterSight (with meaning) in worldserver.conf or put them as define
m_float_configs[CONFIG_SIGHT_MONSTER] = sConfigMgr->GetFloatDefault("MonsterSight", 50.0f);
if (reload)
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 46fbdf9610f..1dcc407b997 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -267,6 +267,9 @@ enum WorldIntConfigs
CONFIG_DAILY_QUEST_RESET_TIME_HOUR,
CONFIG_MAX_PRIMARY_TRADE_SKILL,
CONFIG_MIN_PETITION_SIGNS,
+ CONFIG_MIN_QUEST_SCALED_XP_RATIO,
+ CONFIG_MIN_CREATURE_SCALED_XP_RATIO,
+ CONFIG_MIN_DISCOVERED_SCALED_XP_RATIO,
CONFIG_GM_LOGIN_STATE,
CONFIG_GM_VISIBLE_STATE,
CONFIG_GM_CHAT,
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 1548d3eb2bd..cdcefa5748e 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -1154,6 +1154,34 @@ MaxGroupXPDistance = 74
MaxRecruitAFriendBonusDistance = 100
#
+# MinQuestScaledXPRatio
+# Description: Min ratio of experience that a quest can grant when player level scaling is factored.
+# Example: 50 (No less than 50% experience granted from a lower leveled quests completion)
+# 100 (Quests always grant full experience upon completion)
+# Default: 0 - (Quests too low may grant no experience)
+
+MinQuestScaledXPRatio = 0
+
+#
+# MinCreatureScaledXPRatio
+# Description: Min ratio of experience that a creature kill can grant when player level scaling is factored. This
+# will also allow spell procs to trigger, such as Drain Soul, if > 0 and exp is grantable.
+# Example: 50 (No less than 50% experience granted from a lower leveled creature kill)
+# 100 (Creature kills always grant full experience upon kill)
+# Default: 0 - (Creatures too low may grant no experience)
+
+MinCreatureScaledXPRatio = 0
+
+#
+# MinDiscoveredScaledXPRatio
+# Description: Min ratio of experience that an area discovery event will grant when player level scaling is factored.
+# Example: 50 (No less than 50% experience granted from discovering a new section of map)
+# 100 (Map exploration always grant full experience upon discovery)
+# Default: 0 - (No experience granted when discovered area is too low level)
+
+MinDiscoveredScaledXPRatio = 0
+
+#
# MailDeliveryDelay
# Description: Time (in seconds) mail delivery is delayed when sending items.
# Default: 3600 - (1 hour)