Skip to content

Instantly share code, notes, and snippets.

@callmephil
Last active August 29, 2015 14:12
Show Gist options
  • Save callmephil/0acc54f7f0d1549733c9 to your computer and use it in GitHub Desktop.
Save callmephil/0acc54f7f0d1549733c9 to your computer and use it in GitHub Desktop.
Individual {xp/loot} rate (4.3.4)
/*
SQL : CHARACTERS
DROP TABLE IF EXISTS `character_loot_rate`;
CREATE TABLE `character_loot_rate` (
`guid` int(10) unsigned NOT NULL,
`loot_rate` int(10) unsigned NOT NULL DEFAULT '1',
PRIMARY KEY (`guid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Player Loot Rate System';
DROP TABLE IF EXISTS `character_xp_rate`;
CREATE TABLE `character_xp_rate` (
`guid` int(10) UNSIGNED NOT NULL,
`xp_rate` int(10) UNSIGNED NOT NULL DEFAULT '1',
PRIMARY KEY (`guid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Player XP Rate System';
SQL : WORLD
insert into `command`(`name`,`permission`,`help`) values
('rate xp',195,'Syntax: .rate xp $value\r\nSets your XP multiplier to $value. If no parameter is provided, it will show your current XP rate.'),
('rate loot',195,'Syntax: .rate loot $value\r\nSets your loot multiplier to $value. If no parameter is provided, it will show your current loot rate. A $value of 0 means you won\'t be able to loot anything.');
*/
#include "ScriptMgr.h"
#include "Chat.h"
#include "Language.h"
class CustomRates
{
private:
static int32 GetRateFromDB(const Player *player, CharacterDatabaseStatements statement)
{
PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(statement);
stmt->setUInt32(0, player->GetGUIDLow());
PreparedQueryResult result = CharacterDatabase.Query(stmt);
if (result)
return static_cast<int32>((*result)[0].GetUInt32());
return -1;
}
static void SaveRateToDB(const Player *player, uint32 rate, bool update, CharacterDatabaseStatements uStmt, CharacterDatabaseStatements iStmt)
{
if (update)
{
PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(uStmt);
stmt->setUInt32(0, rate);
stmt->setUInt32(1, player->GetGUIDLow());
CharacterDatabase.Execute(stmt);
}
else
{
PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(iStmt);
stmt->setUInt32(0, player->GetGUIDLow());
stmt->setUInt32(1, rate);
CharacterDatabase.Execute(stmt);
}
}
public:
/* TO FIX
static void DeleteRateFromDB(const Player* player, CharacterDatabaseStatements statement)
{
PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(statement);
stmt->setUInt32(0, player->GetGUID());
CharacterDatabase.Execute(stmt);
}
*/
static int32 GetXpRateFromDB(const Player *player)
{
return GetRateFromDB(player, CHAR_SEL_INDIVIDUAL_XP_RATE);
}
static int32 GetLootRateFromDB(const Player *player)
{
return GetRateFromDB(player, CHAR_SEL_INDIVIDUAL_LOOT_RATE);
}
static void SaveXpRateToDB(const Player *player, uint32 rate, bool update)
{
SaveRateToDB(player, rate, update, CHAR_UPD_INDIVIDUAL_XP_RATE, CHAR_INS_INDIVIDUAL_XP_RATE);
}
static void SaveLootRateToDB(const Player *player, uint32 rate, bool update)
{
SaveRateToDB(player, rate, update, CHAR_UPD_INDIVIDUAL_LOOT_RATE, CHAR_INS_INDIVIDUAL_LOOT_RATE);
}
};
class add_del_rates : public PlayerScript
{
public:
add_del_rates() : PlayerScript("add_del_rates") {}
/* TO FIX
void OnDelete(uint64 guid, uint32)
{
CustomRates::DeleteRateFromDB(guid, CHAR_DEL_INDIVIDUAL_XP_RATE);
CustomRates::DeleteRateFromDB(guid, CHAR_DEL_INDIVIDUAL_LOOT_RATE);
}
*/
void OnLogin(Player *player, bool)
{
// show custom XP rate on login
int32 rate = CustomRates::GetXpRateFromDB(player);
if (rate != -1 && player->getLevel() != sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
{
uint32 uRate = static_cast<uint32>(rate);
player->SetCustomXpRate(uRate);
if (sWorld->getBoolConfig(CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SHOW_ON_LOGIN))
{
if (uRate)
ChatHandler(player->GetSession()).PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Your XP rate was set to %u.", uRate);
else
ChatHandler(player->GetSession()).SendSysMessage("|CFF7BBEF7[Custom Rates]|r: Your XP rate was set to 0. You won't gain any XP anymore.");
}
}
// show custom loot rate on login
rate = CustomRates::GetLootRateFromDB(player);
if (rate != -1)
{
uint32 uRate = static_cast<uint32>(rate);
player->SetCustomLootRate(uRate);
if (sWorld->getBoolConfig(CONFIG_PLAYER_INDIVIDUAL_LOOT_RATE_SHOW_ON_LOGIN))
{
if (uRate)
ChatHandler(player->GetSession()).PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Your loot rate was set to %u.", uRate);
else
ChatHandler(player->GetSession()).SendSysMessage("|CFF7BBEF7[Custom Rates]|r: Your loot rate was set to 0. You won't be able to loot anything.");
}
}
}
};
class custom_rate_commands : public CommandScript
{
private:
public:
custom_rate_commands() : CommandScript("custom_rate_commands") {}
ChatCommand *GetCommands() const
{
static ChatCommand rateCommandTable[] =
{
{ "xp", SEC_PLAYER, false, &HandleRateXpCommand, "", NULL },
{ "loot", SEC_PLAYER, false, &HandleRateLootCommand, "", NULL },
{ NULL, SEC_PLAYER, false, NULL, "", NULL }
};
static ChatCommand commandTable[] =
{
{ "rate", SEC_PLAYER, false, NULL, "", rateCommandTable },
{ NULL, SEC_PLAYER, false, NULL, "", NULL }
};
return commandTable;
}
static bool HandleRateXpCommand(ChatHandler *handler, const char *args)
{
// take a pointer to the player who uses the command
Player *me = handler->GetSession() ? handler->GetSession()->GetPlayer() : NULL;
if (!me)
return false;
// already at max level, no point in using the command at all
if (me->getLevel() == sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
{
handler->SendSysMessage("|CFF7BBEF7[Custom Rates]|r: You are already at maximum level.");
return true;
}
// no arguments, show current XP rate
if (!*args)
{
handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Your current XP rate is %u.", me->GetCustomXpRate());
return true;
}
// first, check if I can use the command
if (me->GetSession()->GetSecurity() < (int)sWorld->getIntConfig(CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SECURITY))
{
handler->SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
handler->SetSentErrorMessage(true);
return false;
}
// take a pointer to player's selection
Player *target = handler->getSelectedPlayer();
if (!target || !target->GetSession())
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
handler->SetSentErrorMessage(true);
return false;
}
// extract value
int rate = atoi((char *)args);
int maxRate = sWorld->getIntConfig(CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_XP_RATE);
if (rate < 0 || rate > maxRate)
{
handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Invalid rate specified, must be in interval [0,%i].", maxRate);
handler->SetSentErrorMessage(true);
return false;
}
// take a pointer to the player we need to set xp rate to
// can be either player itself, or his selection, if
// selection security is lower than his security
Player *player = NULL;
if (target == me)
player = me;
else
{
if (me->GetSession()->GetSecurity() > target->GetSession()->GetSecurity())
player = target;
else
{
handler->SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
handler->SetSentErrorMessage(true);
return false;
}
}
// set player custom XP rate and save it in DB for later use
uint32 uRate = static_cast<uint32>(rate);
player->SetCustomXpRate(uRate);
int32 rateFromDB = CustomRates::GetXpRateFromDB(player);
if (rateFromDB == -1)
CustomRates::SaveXpRateToDB(player, uRate, false);
else
CustomRates::SaveXpRateToDB(player, uRate, true);
// show a message indicating custom XP rate change
if (player == me)
handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: You have set your XP rate to %u.", uRate);
else
{
handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: You have set %s's XP rate to %u.", handler->GetNameLink(player).c_str(), uRate);
ChatHandler(player->GetSession()).PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: %s has set your XP rate to %u.", handler->GetNameLink().c_str(), uRate);
}
return true;
}
static bool HandleRateLootCommand(ChatHandler *handler, const char *args)
{
// take a pointer to the player who uses the command
Player *me = handler->GetSession() ? handler->GetSession()->GetPlayer() : NULL;
if (!me)
return false;
// no arguments, show current loot rate
if (!*args)
{
handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Your current loot rate is %u.", me->GetCustomLootRate());
return true;
}
// first, check if I can use the command
if (me->GetSession()->GetSecurity() < (int)sWorld->getIntConfig(CONFIG_PLAYER_INDIVIDUAL_LOOT_RATE_SECURITY))
{
handler->SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
handler->SetSentErrorMessage(true);
return false;
}
// take a pointer to player's selection
Player *target = handler->getSelectedPlayer();
if (!target || !target->GetSession())
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
handler->SetSentErrorMessage(true);
return false;
}
// extract value
int rate = atoi((char *)args);
int maxRate = sWorld->getIntConfig(CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_LOOT_RATE);
if (rate < 0 || rate > maxRate)
{
handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: Invalid rate specified, must be in interval [0,%i].", maxRate);
handler->SetSentErrorMessage(true);
return false;
}
// take a pointer to the player we need to set xp rate to
// can be either player itself, or his selection, if
// selection security is lower than his security
Player *player = NULL;
if (target == me)
player = me;
else
{
if (me->GetSession()->GetSecurity() > target->GetSession()->GetSecurity())
player = target;
else
{
handler->SendSysMessage(LANG_YOURS_SECURITY_IS_LOW);
handler->SetSentErrorMessage(true);
return false;
}
}
// set player custom loot rate and save it in DB for later use
uint32 uRate = static_cast<uint32>(rate);
player->SetCustomLootRate(uRate);
int32 rateFromDB = CustomRates::GetLootRateFromDB(player);
if (rateFromDB == -1)
CustomRates::SaveLootRateToDB(player, uRate, false);
else
CustomRates::SaveLootRateToDB(player, uRate, true);
// show a message indicating custom XP rate change
if (player == me)
handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: You have set your loot rate to %u.", uRate);
else
{
handler->PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: You have set %s's loot rate to %u.", handler->GetNameLink(player).c_str(), uRate);
ChatHandler(player->GetSession()).PSendSysMessage("|CFF7BBEF7[Custom Rates]|r: %s has set your loot rate to %u.", handler->GetNameLink().c_str(), uRate);
}
return true;
}
};
void AddSC_Custom_Rates()
{
new add_del_rates();
new custom_rate_commands();
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 0b7f358..b043e2f 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -916,6 +916,10 @@ Player::Player(WorldSession* session): Unit(true)
m_achievementMgr = new AchievementMgr<Player>(this);
m_reputationMgr = new ReputationMgr(this);
+
+ // Custom Rate 4.3.4
+ m_CustomXpRate = 1;
+ m_CustomLootRate = 1;
}
Player::~Player()
@@ -6821,6 +6825,8 @@ void Player::CheckAreaExploreAndOutdoor()
XP = uint32(sObjectMgr->GetBaseXP(areaEntry->area_level)*sWorld->getRate(RATE_XP_EXPLORE));
}
+ // Custom Rate 4.3.4
+ XP *= GetCustomXpRate();
GiveXP(XP, NULL);
SendExplorationExperience(area, XP);
}
@@ -15373,7 +15379,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
bool rewarded = (m_RewardedQuests.find(quest_id) != m_RewardedQuests.end());
// Not give XP in case already completed once repeatable quest
- uint32 XP = rewarded && !quest->IsDFQuest() ? 0 : uint32(quest->XPValue(this) * sWorld->getRate(RATE_XP_QUEST));
+ uint32 XP = rewarded && !quest->IsDFQuest() ? 0 : uint32(quest->XPValue(this) * sWorld->getRate(RATE_XP_QUEST) * GetCustomXpRate());
// handle SPELL_AURA_MOD_XP_QUEST_PCT auras
Unit::AuraEffectList const& ModXPPctAuras = GetAuraEffectsByType(SPELL_AURA_MOD_XP_QUEST_PCT);
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 2d4d518..356d795 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -2555,6 +2555,12 @@ class Player : public Unit, public GridObject<Player>
//! Return collision height sent to client
float GetCollisionHeight(bool mounted) const;
+
+ void SetCustomXpRate(uint32 rate) { m_CustomXpRate = rate; }
+ uint32 GetCustomXpRate() const { return m_CustomXpRate; }
+
+ void SetCustomLootRate(uint32 rate) { m_CustomLootRate = rate; }
+ uint32 GetCustomLootRate() const { return m_CustomLootRate; }
std::string GetMapAreaAndZoneString();
std::string GetCoordsMapAreaAndZoneString();
@@ -2926,6 +2932,9 @@ class Player : public Unit, public GridObject<Player>
uint32 _activeCheats;
uint32 _maxPersonalArenaRate;
+
+ uint32 m_CustomXpRate;
+ uint32 m_CustomLootRate;
};
void AddItemsSetItem(Player* player, Item* item);
diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp
index 4a30b4f..9b2d5b3 100644
--- a/src/server/game/Loot/LootMgr.cpp
+++ b/src/server/game/Loot/LootMgr.cpp
@@ -283,17 +283,17 @@ void LootStore::ReportNonExistingId(uint32 id) const
// Checks if the entry (quest, non-quest, reference) takes it's chance (at loot generation)
// RATE_DROP_ITEMS is no longer used for all types of entries
-bool LootStoreItem::Roll(bool rate) const
+bool LootStoreItem::Roll(bool rate, uint32 customRate) const
{
if (chance >= 100.0f)
return true;
if (reference > 0) // reference case
- return roll_chance_f(chance* (rate ? sWorld->getRate(RATE_DROP_ITEM_REFERENCED) : 1.0f));
+ return roll_chance_f(chance* (rate ? sWorld->getRate(RATE_DROP_ITEM_REFERENCED) * customRate : 1.0f));
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(itemid);
- float qualityModifier = pProto && rate ? sWorld->getRate(qualityToRate[pProto->Quality]) : 1.0f;
+ float qualityModifier = pProto && rate ? sWorld->getRate(qualityToRate[pProto->Quality]) * customRate : 1.0f;
return roll_chance_f(chance*qualityModifier);
}
@@ -459,7 +459,7 @@ bool Loot::FillLoot(uint32 lootId, LootStore const& store, Player* lootOwner, bo
items.reserve(MAX_NR_LOOT_ITEMS);
quest_items.reserve(MAX_NR_QUEST_ITEMS);
- tab->Process(*this, store.IsRatesAllowed(), lootMode); // Processing is done there, callback via Loot::AddItem()
+ tab->Process(*this, store.IsRatesAllowed(), lootMode, 0, lootOwner->GetCustomLootRate()); // Processing is done there, callback via Loot::AddItem()
// Setting access rights for group loot case
Group* group = lootOwner->GetGroup();
@@ -1296,7 +1296,7 @@ void LootTemplate::CopyConditions(LootItem* li) const
}
// Rolls for every item in the template and adds the rolled items the the loot
-void LootTemplate::Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId) const
+void LootTemplate::Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId, uint32 customRate) const
{
if (groupId) // Group reference uses own processing of the group
{
@@ -1317,7 +1317,7 @@ void LootTemplate::Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId
if (!(item->lootmode & lootMode)) // Do not add if mode mismatch
continue;
- if (!item->Roll(rate))
+ if (!item->Roll(rate, customRate))
continue; // Bad luck for the entry
if (item->reference > 0) // References processing
diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h
index 1685996..d733632 100644
--- a/src/server/game/Loot/LootMgr.h
+++ b/src/server/game/Loot/LootMgr.h
@@ -141,7 +141,7 @@ struct LootStoreItem
needs_quest(_needs_quest), groupid(_groupid), mincount(_mincount), maxcount(_maxcount)
{ }
- bool Roll(bool rate) const; // Checks if the entry takes it's chance (at loot generation)
+ bool Roll(bool rate, uint32 customRate) const; // Checks if the entry takes it's chance (at loot generation)
bool IsValid(LootStore const& store, uint32 entry) const;
// Checks correctness of values
};
@@ -251,7 +251,7 @@ class LootTemplate
// Adds an entry to the group (at loading stage)
void AddEntry(LootStoreItem* item);
// Rolls for every item in the template and adds the rolled items the the loot
- void Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId = 0) const;
+ void Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId = 0, uint32 customRate = 1) const;
void CopyConditions(const ConditionList& conditions);
void CopyConditions(LootItem* li) const;
diff --git a/src/server/game/Miscellaneous/Formulas.h b/src/server/game/Miscellaneous/Formulas.h
index 537fa75..924c684 100644
--- a/src/server/game/Miscellaneous/Formulas.h
+++ b/src/server/game/Miscellaneous/Formulas.h
@@ -188,7 +188,7 @@ namespace Trinity
}
xpMod *= sWorld->getRate(RATE_XP_KILL);
- gain = uint32(gain * xpMod);
+ gain = uint32((gain * xpMod) * player->GetCustomXpRate());
}
sScriptMgr->OnGainCalculation(gain, player, u);
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index 89ca374..a1469ae 100644
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -269,7 +269,8 @@ void Quest::BuildExtraQuestInfo(WorldPacket& data, Player* player) const
}
data << uint32(GetRewOrReqMoney());
- data << uint32(XPValue(player) * sWorld->getRate(RATE_XP_QUEST));
+ // Custom Rates 4.3.4
+ data << uint32(XPValue(player) * sWorld->getRate(RATE_XP_QUEST) * player->GetCustomXpRate());
data << uint32(GetCharTitleId());
data << uint32(0); // unk
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index 56a913b..18dcd17 100644
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -1454,6 +1454,10 @@ void AddBattlegroundScripts()
/* This is where custom scripts' loading functions should be declared. */
+ void AddSC_Custom_Rates();
#endif
void AddCustomScripts()
@@ -1462,5 +1466,9 @@ void AddCustomScripts()
/* This is where custom scripts should be added. */
+ AddSC_Custom_Rates();
#endif
}
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 3a183ec..af31a94 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1282,6 +1282,48 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_WINTERGRASP_BATTLETIME] = sConfigMgr->GetIntDefault("Wintergrasp.BattleTimer", 30);
m_int_configs[CONFIG_WINTERGRASP_NOBATTLETIME] = sConfigMgr->GetIntDefault("Wintergrasp.NoBattleTimer", 150);
m_int_configs[CONFIG_WINTERGRASP_RESTART_AFTER_CRASH] = sConfigMgr->GetIntDefault("Wintergrasp.CrashRestartTimer", 10);
+
+ // Individual XP/loot rates
+ int sec = sConfigMgr->GetIntDefault("Player.XpRateSecurity", 0);
+ if (sec < SEC_PLAYER || sec > SEC_ADMINISTRATOR)
+ {
+ TC_LOG_ERROR("LOG_FILTER_SERVER_LOADING", "Player.XpRateSecurity has invalid security `%i`, must be between `%i and `%i`, defaulting to 0 ...",
+ sec, SEC_PLAYER, SEC_ADMINISTRATOR);
+ m_int_configs[CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SECURITY] = 0;
+ }
+ else
+ m_int_configs[CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SECURITY] = sec;
+
+ sec = sConfigMgr->GetIntDefault("Player.LootRateSecurity", 0);
+ if (sec < SEC_PLAYER || sec > SEC_ADMINISTRATOR)
+ {
+ TC_LOG_ERROR("LOG_FILTER_SERVER_LOADING", "Player.LootRateSecurity has invalid security `%i`, must be between `%i and `%i`, defaulting to 0 ...",
+ sec, SEC_PLAYER, SEC_ADMINISTRATOR);
+ m_int_configs[CONFIG_PLAYER_INDIVIDUAL_LOOT_RATE_SECURITY] = 0;
+ }
+ else
+ m_int_configs[CONFIG_PLAYER_INDIVIDUAL_LOOT_RATE_SECURITY] = sec;
+
+ int maxXpRate = sConfigMgr->GetIntDefault("Player.MaximumXpRate", 1);
+ if (maxXpRate < 1)
+ {
+ TC_LOG_ERROR("LOG_FILTER_SERVER_LOADING", "Player.MaximumXpRate has too low value `%i`, defaulting to 1 ...", maxXpRate);
+ m_int_configs[CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_XP_RATE] = 1;
+ }
+ else
+ m_int_configs[CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_XP_RATE] = maxXpRate;
+
+ maxXpRate = sConfigMgr->GetIntDefault("Player.MaximumLootRate", 1);
+ if (maxXpRate < 1)
+ {
+ TC_LOG_ERROR("LOG_FILTER_SERVER_LOADING", "Player.MaximumLootRate has too low value `%i`, defaulting to 1 ...", maxXpRate);
+ m_int_configs[CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_LOOT_RATE] = 1;
+ }
+ else
+ m_int_configs[CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_LOOT_RATE] = maxXpRate;
+
+ m_bool_configs[CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SHOW_ON_LOGIN] = sConfigMgr->GetBoolDefault("Player.ShowXpRateOnLogin", true);
+ m_bool_configs[CONFIG_PLAYER_INDIVIDUAL_LOOT_RATE_SHOW_ON_LOGIN] = sConfigMgr->GetBoolDefault("Player.ShowLootRateOnLogin", true);
// Stats limits
m_bool_configs[CONFIG_STATS_LIMITS_ENABLE] = sConfigMgr->GetBoolDefault("Stats.Limits.Enable", false);
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 3bbc4e4..a4ee4f4 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -162,6 +162,8 @@ enum WorldBoolConfigs
CONFIG_GUILD_LEVELING_ENABLED,
CONFIG_UI_QUESTLEVELS_IN_DIALOGS, // Should we add quest levels to the title in the NPC dialogs?
CONFIG_EVENT_ANNOUNCE,
+ CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SHOW_ON_LOGIN,
+ CONFIG_PLAYER_INDIVIDUAL_LOOT_RATE_SHOW_ON_LOGIN,
CONFIG_STATS_LIMITS_ENABLE,
CONFIG_INSTANCES_RESET_ANNOUNCE,
CONFIG_IP_BASED_ACTION_LOGGING,
@@ -337,6 +339,10 @@ enum WorldIntConfigs
CONFIG_WINTERGRASP_BATTLETIME,
CONFIG_WINTERGRASP_NOBATTLETIME,
CONFIG_WINTERGRASP_RESTART_AFTER_CRASH,
+ CONFIG_PLAYER_INDIVIDUAL_XP_RATE_SECURITY,
+ CONFIG_PLAYER_INDIVIDUAL_LOOT_RATE_SECURITY ,
+ CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_XP_RATE,
+ CONFIG_PLAYER_MAXIMUM_INDIVIDUAL_LOOT_RATE,
CONFIG_GUILD_SAVE_INTERVAL,
CONFIG_GUILD_MAX_LEVEL,
CONFIG_GUILD_UNDELETABLE_LEVEL,
diff --git a/src/server/scripts/Custom/CMakeLists.txt b/src/server/scripts/Custom/CMakeLists.txt
index 358401d..d702e4d 100644
--- a/src/server/scripts/Custom/CMakeLists.txt
+++ b/src/server/scripts/Custom/CMakeLists.txt
@@ -13,9 +13,13 @@
set(scripts_STAT_SRCS
${scripts_STAT_SRCS}
# ${sources_Custom}
+ Custom/Custom_Rates.cpp
)
message(" -> Prepared: Custom")
@JustZerooo
Copy link

https://gist.github.com/callmephil/0acc54f7f0d1549733c9#file-rate-diff-L145

Loooong time outdated :) I have fixxed it on my testserver !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment