aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCraftedRO <24683355+CraftedRO@users.noreply.github.com>2024-06-27 19:54:31 +0300
committerGitHub <noreply@github.com>2024-06-27 18:54:31 +0200
commitc5a9ab65af58c8642f914c31f327f09ca3a0ce0c (patch)
tree14d02252a2e0e9306cc9caa16a022c752d11cc5c /src
parent6c15d7f7502d50520b502067c6401a4bf11075a2 (diff)
Core/Players: Add level restrictions for faction changes (#30057)
Co-authored-by: Shauren <shauren.trinity@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.cpp2
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp13
-rw-r--r--src/server/game/Miscellaneous/Language.h4
-rw-r--r--src/server/scripts/Commands/cs_character.cpp18
4 files changed, 35 insertions, 2 deletions
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp
index 10b2a3307f2..35c9d4d5537 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp
@@ -420,7 +420,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_CHARACTER_AT_LOGIN, "SELECT at_login FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_CLASS_LVL_AT_LOGIN, "SELECT class, level, at_login, knownTitles FROM characters WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_CUSTOMIZE_INFO, "SELECT name, race, class, gender, at_login FROM characters WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_CHAR_RACE_OR_FACTION_CHANGE_INFOS, "SELECT c.at_login, c.knownTitles, gm.guid FROM characters c LEFT JOIN group_member gm ON c.guid = gm.memberGuid WHERE c.guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_CHAR_RACE_OR_FACTION_CHANGE_INFOS, "SELECT c.at_login, c.knownTitles, gm.guid, c.map FROM characters c LEFT JOIN group_member gm ON c.guid = gm.memberGuid WHERE c.guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_INSTANCE, "SELECT data, completedEncounters FROM instance WHERE map = ? AND id = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_PERM_BIND_BY_INSTANCE, "SELECT guid FROM character_instance WHERE instance = ? and permanent = 1", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHAR_COD_ITEM_MAIL, "SELECT id, messageType, mailTemplateId, sender, subject, body, money, has_items FROM mail WHERE receiver = ? AND has_items <> 0 AND cod <> 0", CONNECTION_SYNCH);
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 29b39902a5e..706384c9b55 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -1670,6 +1670,7 @@ void WorldSession::HandleCharFactionOrRaceChangeCallback(std::shared_ptr<Charact
uint32 atLoginFlags = fields[0].GetUInt16();
std::string knownTitlesStr = fields[1].GetString();
uint32 groupId = !fields[2].IsNull() ? fields[2].GetUInt32() : 0;
+ uint32 mapId = fields[3].GetUInt16();
uint32 usedLoginFlag = (factionChangeInfo->FactionChange ? AT_LOGIN_CHANGE_FACTION : AT_LOGIN_CHANGE_RACE);
if (!(atLoginFlags & usedLoginFlag))
@@ -1678,6 +1679,18 @@ void WorldSession::HandleCharFactionOrRaceChangeCallback(std::shared_ptr<Charact
return;
}
+ if (level < 10)
+ {
+ SendCharFactionChange(CHAR_CREATE_ERROR, factionChangeInfo.get());
+ return;
+ }
+
+ if (playerClass == CLASS_DEATH_KNIGHT && (level < 60 || mapId == 609))
+ {
+ SendCharFactionChange(CHAR_CREATE_RESTRICTED_RACECLASS, factionChangeInfo.get());
+ return;
+ }
+
uint32 newTeam = Player::TeamForRace(factionChangeInfo->Race);
if (factionChangeInfo->FactionChange == (Player::TeamForRace(oldRace) == newTeam))
{
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index 073c0294f71..c0200ef61e1 100644
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -449,7 +449,9 @@ enum TrinityStrings
LANG_COMMAND_LEARN_ALL_PETTALENT_HELP = 394,
LANG_COMMAND_BG_START_HELP = 395,
LANG_COMMAND_BG_STOP_HELP = 396,
- // Room for more level 2 397-399 not used
+ LANG_CHANGEFACTION_NOT_ELIGIBLE_10 = 397,
+ LANG_CHANGEFACTION_NOT_ELIGIBLE_60 = 398,
+ // Room for more level 2 399 not used
// level 3 chat
LANG_SCRIPTS_RELOADED = 400,
diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp
index b8c175f0fa1..2633b8313a2 100644
--- a/src/server/scripts/Commands/cs_character.cpp
+++ b/src/server/scripts/Commands/cs_character.cpp
@@ -422,6 +422,24 @@ public:
if (!player)
return false;
+ CharacterCacheEntry const* characterInfo = sCharacterCache->GetCharacterCacheByGuid(player->GetGUID());
+ if (!characterInfo)
+ return false;
+
+ if (characterInfo->Level < 10)
+ {
+ handler->PSendSysMessage(LANG_CHANGEFACTION_NOT_ELIGIBLE_10);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (characterInfo->Class == CLASS_DEATH_KNIGHT && characterInfo->Level < 60)
+ {
+ handler->PSendSysMessage(LANG_CHANGEFACTION_NOT_ELIGIBLE_60);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
if (Player* target = player->GetConnectedPlayer())
{
handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER, handler->GetNameLink(target).c_str());