From cc0ff69ca4271614b4bb6f5813ea6267cc140edb Mon Sep 17 00:00:00 2001 From: Vincent-Michael Date: Fri, 3 Aug 2012 15:15:19 +0200 Subject: Core/Commands: * Add remove support for disable command * Add quest disables support * Add check for no existent entry * Fix problems with flags 0 * Fix code style --- src/server/scripts/Commands/cs_disable.cpp | 314 ++++++++++++++++++++++------- 1 file changed, 245 insertions(+), 69 deletions(-) (limited to 'src/server/scripts/Commands') diff --git a/src/server/scripts/Commands/cs_disable.cpp b/src/server/scripts/Commands/cs_disable.cpp index e7f33885036..a2a80edd43b 100644 --- a/src/server/scripts/Commands/cs_disable.cpp +++ b/src/server/scripts/Commands/cs_disable.cpp @@ -26,6 +26,7 @@ EndScriptData */ #include "ObjectMgr.h" #include "Chat.h" #include "DisableMgr.h" +#include "OutdoorPvP.h" class disable_commandscript : public CommandScript { @@ -34,56 +35,230 @@ public: ChatCommand* GetCommands() const { - - static ChatCommand disableCommandTable[] = + static ChatCommand removeDisableCommandTable[] = { - { "spell", SEC_GAMEMASTER, false, &HandleDisableSpellCommand, "", NULL }, - { "map", SEC_GAMEMASTER, false, &HandleDisableMapCommand, "", NULL }, - { "battleground", SEC_GAMEMASTER, false, &HandleDisableBattlegroundCommand, "", NULL }, - { "achievement_criteria", SEC_GAMEMASTER, false, &HandleDisableAchievementCriteriaCommand, "", NULL }, - { "outdoorpvp", SEC_GAMEMASTER, false, &HandleDisableOutdoorPvPCommand, "", NULL }, - { "vmap", SEC_GAMEMASTER, false, &HandleDisableVmapCommand, "", NULL }, - { NULL, 0, false, NULL, "", NULL } + { "spell", SEC_ADMINISTRATOR, true, &HandleRemoveDisableSpellCommand, "", NULL }, + { "quest", SEC_ADMINISTRATOR, true, &HandleRemoveDisableQuestCommand, "", NULL }, + { "map", SEC_ADMINISTRATOR, true, &HandleRemoveDisableMapCommand, "", NULL }, + { "battleground", SEC_ADMINISTRATOR, true, &HandleRemoveDisableBattlegroundCommand, "", NULL }, + { "achievement_criteria", SEC_ADMINISTRATOR, true, &HandleRemoveDisableAchievementCriteriaCommand, "", NULL }, + { "outdoorpvp", SEC_ADMINISTRATOR, true, &HandleRemoveDisableOutdoorPvPCommand, "", NULL }, + { "vmap", SEC_ADMINISTRATOR, true, &HandleRemoveDisableVmapCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; - + static ChatCommand addDisableCommandTable[] = + { + { "spell", SEC_ADMINISTRATOR, true, &HandleAddDisableSpellCommand, "", NULL }, + { "quest", SEC_ADMINISTRATOR, true, &HandleAddDisableQuestCommand, "", NULL }, + { "map", SEC_ADMINISTRATOR, true, &HandleAddDisableMapCommand, "", NULL }, + { "battleground", SEC_ADMINISTRATOR, true, &HandleAddDisableBattlegroundCommand, "", NULL }, + { "achievement_criteria", SEC_ADMINISTRATOR, true, &HandleAddDisableAchievementCriteriaCommand, "", NULL }, + { "outdoorpvp", SEC_ADMINISTRATOR, true, &HandleAddDisableOutdoorPvPCommand, "", NULL }, + { "vmap", SEC_ADMINISTRATOR, true, &HandleAddDisableVmapCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand disableCommandTable[] = + { + { "add", SEC_ADMINISTRATOR, true, NULL, "", addDisableCommandTable }, + { "remove", SEC_ADMINISTRATOR, true, NULL, "", removeDisableCommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; static ChatCommand commandTable[] = { - { "disable", SEC_GAMEMASTER, false, NULL, "", disableCommandTable }, - { NULL, 0, false, NULL, "", NULL } + { "disable", SEC_ADMINISTRATOR, false, NULL, "", disableCommandTable }, + { NULL, 0, false, NULL, "", NULL } }; return commandTable; } - - static void HandleDisables(ChatHandler* handler, char const* args, uint8 disableType) + static bool HandleAddDisables(ChatHandler* handler, char const* args, uint8 disableType) { - char* cEntry = strtok((char*)args, " "); - if (!cEntry || !atoi(cEntry)) - { - handler->SendSysMessage("No entry specified."); - return; - } + char* entryStr = strtok((char*)args, " "); + if (!entryStr || !atoi(entryStr)) + return false; + + char* flagsStr = strtok(NULL, " "); + uint8 flags = flagsStr ? uint8(atoi(flagsStr)) : 0; + + char* commentStr = strtok(NULL, ""); + if (!commentStr) + return false; - char* cFlags = strtok(NULL, " "); - if (!cFlags || !atoi(cFlags)) + std::string disableComment = commentStr; + uint32 entry = uint32(atoi(entryStr)); + + std::string disableTypeStr = ""; + + switch (disableType) { - handler->SendSysMessage("No flags specified."); - return; + case DISABLE_TYPE_SPELL: + { + if (!sSpellMgr->GetSpellInfo(entry)) + { + handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND); + handler->SetSentErrorMessage(true); + return false; + } + disableTypeStr = "spell"; + break; + } + case DISABLE_TYPE_QUEST: + { + if (!sObjectMgr->GetQuestTemplate(entry)) + { + handler->PSendSysMessage(LANG_COMMAND_QUEST_NOTFOUND, entry); + handler->SetSentErrorMessage(true); + return false; + } + disableTypeStr = "quest"; + break; + } + case DISABLE_TYPE_MAP: + { + if (!sMapStore.LookupEntry(entry)) + { + handler->PSendSysMessage(LANG_COMMAND_NOMAPFOUND); + handler->SetSentErrorMessage(true); + return false; + } + disableTypeStr = "map"; + break; + } + case DISABLE_TYPE_BATTLEGROUND: + { + if (!sBattlemasterListStore.LookupEntry(entry)) + { + handler->PSendSysMessage(LANG_COMMAND_NO_BATTLEGROUND_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + disableTypeStr = "battleground"; + break; + } + case DISABLE_TYPE_ACHIEVEMENT_CRITERIA: + { + if (!sAchievementCriteriaStore.LookupEntry(entry)) + { + handler->PSendSysMessage(LANG_COMMAND_NO_ACHIEVEMENT_CRITERIA_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + disableTypeStr = "achievement criteria"; + break; + } + case DISABLE_TYPE_OUTDOORPVP: + { + if (entry > MAX_OUTDOORPVP_TYPES) + { + handler->PSendSysMessage(LANG_COMMAND_NO_OUTDOOR_PVP_FORUND); + handler->SetSentErrorMessage(true); + return false; + } + disableTypeStr = "outdoorpvp"; + break; + } + case DISABLE_TYPE_VMAP: + { + if (!sMapStore.LookupEntry(entry)) + { + handler->PSendSysMessage(LANG_COMMAND_NOMAPFOUND); + handler->SetSentErrorMessage(true); + return false; + } + disableTypeStr = "vmap"; + break; + } + default: + break; } - - char* cComment = strtok(NULL, ""); - if (!cComment) + + PreparedStatement* stmt = NULL; + stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_DISABLES); + stmt->setUInt32(0, entry); + stmt->setUInt8(1, disableType); + PreparedQueryResult result = WorldDatabase.Query(stmt); + if (result) { - handler->SendSysMessage("No comment specified."); - return; + handler->PSendSysMessage("This %s (Id: %u) is already disabled.", disableTypeStr.c_str(), entry); + handler->SetSentErrorMessage(true); + return false; } - std::string entryStr = cEntry; - std::string disableComment = cComment; - uint32 entry = (uint32)atoi(cEntry); - uint8 flags = atoi(cFlags); + stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_DISABLES); + stmt->setUInt32(0, entry); + stmt->setUInt8(1, disableType); + stmt->setUInt16(2, flags); + stmt->setString(3, disableComment); + WorldDatabase.Execute(stmt); + + handler->PSendSysMessage("Add Disabled %s (Id: %u) for reason %s", disableTypeStr.c_str(), entry, disableComment.c_str()); + return true; + } + + static bool HandleAddDisableSpellCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + return HandleAddDisables(handler, args, DISABLE_TYPE_SPELL); + } + + static bool HandleAddDisableQuestCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + return HandleAddDisables(handler, args, DISABLE_TYPE_QUEST); + } + + static bool HandleAddDisableMapCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + return HandleAddDisables(handler, args, DISABLE_TYPE_MAP); + } + + static bool HandleAddDisableBattlegroundCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + return HandleAddDisables(handler, args, DISABLE_TYPE_BATTLEGROUND); + } + + static bool HandleAddDisableAchievementCriteriaCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + return HandleAddDisables(handler, args, DISABLE_TYPE_ACHIEVEMENT_CRITERIA); + } + + static bool HandleAddDisableOutdoorPvPCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + HandleAddDisables(handler, args, DISABLE_TYPE_OUTDOORPVP); + return true; + } + + static bool HandleAddDisableVmapCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + return HandleAddDisables(handler, args, DISABLE_TYPE_VMAP); + } + + static bool HandleRemoveDisables(ChatHandler* handler, char const* args, uint8 disableType) + { + char* entryStr = strtok((char*)args, " "); + if (!entryStr || !atoi(entryStr)) + return false; + uint32 entry = uint32(atoi(entryStr)); std::string disableTypeStr = ""; @@ -92,6 +267,9 @@ public: case DISABLE_TYPE_SPELL: disableTypeStr = "spell"; break; + case DISABLE_TYPE_QUEST: + disableTypeStr = "quest"; + break; case DISABLE_TYPE_MAP: disableTypeStr = "map"; break; @@ -109,87 +287,85 @@ public: break; } - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_DISABLES); + PreparedStatement* stmt = NULL; + stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_DISABLES); stmt->setUInt32(0, entry); - stmt->setUInt8(1, disableType); - PreparedQueryResult result = WorldDatabase.Query(stmt); - - - if (result) + stmt->setUInt8(1, disableType); + PreparedQueryResult result = WorldDatabase.Query(stmt); + if (!result) { - handler->PSendSysMessage("This %s (id %u) is already disabled.", disableTypeStr.c_str(), entry); - return; + handler->PSendSysMessage("This %s (Id: %u) is not disabled.", disableTypeStr.c_str(), entry); + handler->SetSentErrorMessage(true); + return false; } - PreparedStatement* stmt2 = WorldDatabase.GetPreparedStatement(WORLD_INS_DISABLES); - stmt2->setUInt32(0, entry); - stmt2->setUInt8(1, disableType); - stmt2->setUInt16(2, flags); - stmt2->setString(3, disableComment); - WorldDatabase.Execute(stmt2); - - handler->PSendSysMessage("Disabled %s %u for reason %s", disableTypeStr.c_str(), entry, disableComment.c_str()); - return; + stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_DISABLES); + stmt->setUInt32(0, entry); + stmt->setUInt8(1, disableType); + WorldDatabase.Execute(stmt); + handler->PSendSysMessage("Remove Disabled %s (Id: %u)", disableTypeStr.c_str(), entry); + return true; } - static bool HandleDisableSpellCommand(ChatHandler* handler, char const* args) + static bool HandleRemoveDisableSpellCommand(ChatHandler* handler, char const* args) { if (!*args) return false; - HandleDisables(handler, args, DISABLE_TYPE_SPELL); - return true; + return HandleRemoveDisables(handler, args, DISABLE_TYPE_SPELL); } - static bool HandleDisableMapCommand(ChatHandler* handler, char const* args) + static bool HandleRemoveDisableQuestCommand(ChatHandler* handler, char const* args) { if (!*args) return false; - HandleDisables(handler, args, DISABLE_TYPE_MAP); - return true; + return HandleRemoveDisables(handler, args, DISABLE_TYPE_QUEST); } - static bool HandleDisableBattlegroundCommand(ChatHandler* handler, char const* args) + static bool HandleRemoveDisableMapCommand(ChatHandler* handler, char const* args) { if (!*args) return false; - HandleDisables(handler, args, DISABLE_TYPE_BATTLEGROUND); - return true; + return HandleAddDisables(handler, args, DISABLE_TYPE_MAP); } - static bool HandleDisableAchievementCriteriaCommand(ChatHandler* handler, char const* args) + static bool HandleRemoveDisableBattlegroundCommand(ChatHandler* handler, char const* args) { if (!*args) return false; - HandleDisables(handler, args, DISABLE_TYPE_ACHIEVEMENT_CRITERIA); - return true; + return HandleRemoveDisables(handler, args, DISABLE_TYPE_BATTLEGROUND); } - static bool HandleDisableOutdoorPvPCommand(ChatHandler* handler, char const* args) + static bool HandleRemoveDisableAchievementCriteriaCommand(ChatHandler* handler, char const* args) { if (!*args) return false; - HandleDisables(handler, args, DISABLE_TYPE_OUTDOORPVP); - return true; + return HandleRemoveDisables(handler, args, DISABLE_TYPE_ACHIEVEMENT_CRITERIA); } - static bool HandleDisableVmapCommand(ChatHandler* handler, char const* args) + static bool HandleRemoveDisableOutdoorPvPCommand(ChatHandler* handler, char const* args) { if (!*args) return false; - HandleDisables(handler, args, DISABLE_TYPE_VMAP); - return true; + return HandleRemoveDisables(handler, args, DISABLE_TYPE_OUTDOORPVP); } + static bool HandleRemoveDisableVmapCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + return HandleRemoveDisables(handler, args, DISABLE_TYPE_VMAP); + } }; void AddSC_disable_commandscript() { new disable_commandscript(); -} \ No newline at end of file +} -- cgit v1.2.3 From 1bd8cb9a7cbaa1a3644328adcceb6a0bc3039156 Mon Sep 17 00:00:00 2001 From: Nay Date: Sun, 5 Aug 2012 19:56:16 +0100 Subject: Script/Commands: Fix a copy paste type in .reload item_set_names command --- src/server/scripts/Commands/cs_reload.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/server/scripts/Commands') diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index c8568feaeb6..3bb29f8abfe 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -949,7 +949,7 @@ public: static bool HandleReloadItemSetNamesCommand(ChatHandler* handler, const char* /*args*/) { sLog->outInfo(LOG_FILTER_GENERAL, "Re-Loading Item set names..."); - LoadRandomEnchantmentsTable(); + sObjectMgr->LoadItemSetNames(); handler->SendGlobalGMSysMessage("DB table `item_set_names` reloaded."); return true; } -- cgit v1.2.3 From 97c4b92eb02fc673d1230aadaee23aa7827a9761 Mon Sep 17 00:00:00 2001 From: Spp Date: Mon, 6 Aug 2012 12:10:33 +0200 Subject: Core/Logging: Try to simplify configuration of loggers and appenders Changed multiple lines to a simple format: - Logger.name=Type,LogLevel,Flags,AppenderList - Appender.name=Type,LogLevel,Flags,optional1,optional2 * Type = File: optional1 = File name, optiona2 = Mode * Type = Console: optional1 = Colors Created a default set of loggers and appenders. - Root logger defaults to Error, that means you will see nothing on console by default (not even loading) - You need to add the loggers to Loggers options if you want to enable them, otherwise Root logger will be used for all types Restored outSQLDriver (LOG_FILTER_SQL_DRIVER), outSQLDev (LOG_FILTER_SQL_DEV), outArena (LOG_FILTER_ARENA) and outChar (LOG_FILTER_CHARACTER) functionality by creating new types (LOG_FILTER_CHARACTER is a rename of LOG_FILTER_DELETE. Note: You need to update your config file... again (yeah sorry... trying to make it simpler) --- src/server/authserver/authserver.conf.dist | 196 ++++++-------- src/server/game/Battlegrounds/ArenaTeam.cpp | 20 +- src/server/game/Entities/Player/Player.cpp | 76 +++--- src/server/game/Handlers/CharacterHandler.cpp | 15 +- src/server/game/Server/WorldSession.cpp | 2 +- src/server/scripts/Commands/cs_account.cpp | 2 +- src/server/scripts/Commands/cs_debug.cpp | 2 +- src/server/shared/Database/DatabaseWorkerPool.h | 16 +- src/server/shared/Logging/Appender.cpp | 10 +- src/server/shared/Logging/Appender.h | 7 +- src/server/shared/Logging/Log.cpp | 107 ++++++-- src/server/worldserver/worldserver.conf.dist | 337 ++++++++++++------------ 12 files changed, 417 insertions(+), 373 deletions(-) (limited to 'src/server/scripts/Commands') diff --git a/src/server/authserver/authserver.conf.dist b/src/server/authserver/authserver.conf.dist index 30a319237a6..d1c92dcf1d0 100644 --- a/src/server/authserver/authserver.conf.dist +++ b/src/server/authserver/authserver.conf.dist @@ -149,123 +149,101 @@ LoginDatabase.WorkerThreads = 1 ################################################################################################### # # Logging system options. -# Note: As it uses dynamic option naming, all options related to one appender or logger are grouped. -# -# -# Appender config values: Given a appender "name" the following options -# can be read: -# -# Appender.name.Type -# Description: Type of appender. Extra appender config options -# will be read depending on this value -# Default: 0 - (None) -# 1 - (Console) -# 2 - (File) -# 3 - (DB) -# -# Appender.name.Level -# Description: Appender level of logging -# Default: 0 - (Disabled) -# 1 - (Trace) -# 2 - (Debug) -# 3 - (Info) -# 4 - (Warn) -# 5 - (Error) -# 6 - (Fatal) -# -# Appender.name.Colors -# Description: Colors for log messages -# (Format: "fatal error warn info debug trace"). -# (Only used with Type = 1) -# Default: "" - no colors -# Colors: 0 - BLACK -# 1 - RED -# 2 - GREEN -# 3 - BROWN -# 4 - BLUE -# 5 - MAGENTA -# 6 - CYAN -# 7 - GREY -# 8 - YELLOW -# 9 - LRED -# 10 - LGREEN -# 11 - LBLUE -# 12 - LMAGENTA -# 13 - LCYAN -# 14 - WHITE -# Example: "13 11 9 5 3 1" -# -# Appender.name.File -# Description: Name of the file -# Allows to use one "%u" to create dynamic files -# (Only used with Type = 2) -# -# Appender.name.Mode -# Description: Mode to open the file -# (Only used with Type = 2) -# Default: a - (Append) -# w - (Overwrite) -# -# Appender.name.Flags -# Description: -# Default: Console = 6, File = 7, DB = 0 -# 0 - None -# 1 - Prefix Timestamp to the text -# 2 - Prefix Log Level to the text -# 4 - Prefix Log Filter type to the text -# 8 - Append timestamp to the log file name. Format: YYYY-MM-DD_HH-MM-SS (Only used with Type = 2) -# 16 - Make a backup of existing file before overwrite (Only used with Mode = w) -# -# Logger config values: Given a logger "name" the following options -# can be read: -# -# Logger.name.Type -# Description: Type of logger. Logs anything related to... -# If no logger with type = 0 exists core will create -# it but disabled. Logger with type = 0 is the -# default one, used when there is no other specific -# logger configured for other logger types -# Default: 0 - Default. Each type that has no config will -# rely on this one. Core will create this logger -# (disabled) if it's not configured -# 7 - Network input/output, -# 30 - Authserver -# -# Logger.name.Level -# Description: Logger level of logging -# Default: 0 - (Disabled) -# 1 - (Trace) -# 2 - (Debug) -# 3 - (Info) -# 4 - (Warn) -# 5 - (Error) -# 6 - (Fatal) -# -# Logger.name.Appenders -# Description: List of appenders linked to logger +# +# Appender config values: Given a appender "name" +# Appender.name +# Description: Defines 'where to log' +# Format: Type,LogLevel,Flags,optional1,optional2 +# +# Type +# 0 - (None) +# 1 - (Console) +# 2 - (File) +# 3 - (DB) +# +# LogLevel +# 0 - (Disabled) +# 1 - (Trace) +# 2 - (Debug) +# 3 - (Info) +# 4 - (Warn) +# 5 - (Error) +# 6 - (Fatal) +# +# Flags: Default Console = 6, File = 7, DB = 0 +# 0 - None +# 1 - Prefix Timestamp to the text +# 2 - Prefix Log Level to the text +# 4 - Prefix Log Filter type to the text +# 8 - Append timestamp to the log file name. Format: YYYY-MM-DD_HH-MM-SS (Only used with Type = 2) +# 16 - Make a backup of existing file before overwrite (Only used with Mode = w) +# +# Colors (read as optional1 if Type = Console) +# Format: "fatal error warn info debug trace" +# 0 - BLACK +# 1 - RED +# 2 - GREEN +# 3 - BROWN +# 4 - BLUE +# 5 - MAGENTA +# 6 - CYAN +# 7 - GREY +# 8 - YELLOW +# 9 - LRED +# 10 - LGREEN +# 11 - LBLUE +# 12 - LMAGENTA +# 13 - LCYAN +# 14 - WHITE +# Example: "13 11 9 5 3 1" +# +# File: Name of the file (read as optional1 if Type = File) +# Allows to use one "%u" to create dynamic files +# +# Mode: Mode to open the file (read as optional2 if Type = File) +# a - (Append) +# w - (Overwrite) +# + +Appender.Console=1,2,6 +Appender.Auth=2,2,7,Auth.log,w + +# Logger config values: Given a logger "name" +# Logger.name +# Description: Defines 'What to log' +# Format: Type,LogLevel,AppenderList +# Type +# 0 - Default. Each type that has no config will +# rely on this one. Core will create this logger +# (disabled) if it's not configured +# 7 - Network input/output, +# 30 - Authserver + +Logger.Root=0,3,Console Auth + +# LogLevel +# 0 - (Disabled) +# 1 - (Trace) +# 2 - (Debug) +# 3 - (Info) +# 4 - (Warn) +# 5 - (Error) +# 6 - (Fatal) +# +# AppenderList: List of appenders linked to logger # (Using spaces as separator). # # Appenders # Description: List of Appenders to read from config # (Using spaces as separator). -# Default: "Console Auth" +# Default: "Console Server" + +Appenders=Console Auth + # # Loggers # Description: List of Loggers to read from config # (Using spaces as separator). # Default: "root" -Loggers=root -Appenders=Console Auth - -Appender.Console.Type=1 -Appender.Console.Level=2 - -Appender.Auth.Type=2 -Appender.Auth.Level=2 -Appender.Auth.File=Auth.log -Appender.Auth.Mode=w - -Logger.root.Type=0 -Logger.root.Level=3 -Logger.root.Appenders=Console Auth +Loggers=Root diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp index 7c6cabe37ba..b9ddabcf254 100755 --- a/src/server/game/Battlegrounds/ArenaTeam.cpp +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp @@ -87,7 +87,7 @@ bool ArenaTeam::Create(uint64 captainGuid, uint8 type, std::string teamName, uin // Add captain as member AddMember(CaptainGuid); - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "New ArenaTeam created [Id: %u] [Type: %u] [Captain low GUID: %u]", GetId(), GetType(), captainLowGuid); + sLog->outInfo(LOG_FILTER_ARENAS, "New ArenaTeam created [Id: %u] [Type: %u] [Captain low GUID: %u]", GetId(), GetType(), captainLowGuid); return true; } @@ -125,7 +125,7 @@ bool ArenaTeam::AddMember(uint64 playerGuid) // Check if player is already in a similar arena team if ((player && player->GetArenaTeamId(GetSlot())) || Player::GetArenaTeamIdFromDB(playerGuid, GetType()) != 0) { - sLog->outError(LOG_FILTER_BATTLEGROUND, "Arena: Player %s (guid: %u) already has an arena team of type %u", playerName.c_str(), GUID_LOPART(playerGuid), GetType()); + sLog->outDebug(LOG_FILTER_ARENAS, "Arena: Player %s (guid: %u) already has an arena team of type %u", playerName.c_str(), GUID_LOPART(playerGuid), GetType()); return false; } @@ -184,7 +184,7 @@ bool ArenaTeam::AddMember(uint64 playerGuid) player->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 1); } - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Player: %s [GUID: %u] joined arena team type: %u [Id: %u].", playerName.c_str(), GUID_LOPART(playerGuid), GetType(), GetId()); + sLog->outInfo(LOG_FILTER_ARENAS, "Player: %s [GUID: %u] joined arena team type: %u [Id: %u].", playerName.c_str(), GUID_LOPART(playerGuid), GetType(), GetId()); return true; } @@ -251,7 +251,7 @@ bool ArenaTeam::LoadMembersFromDB(QueryResult result) if (newMember.Name.empty()) { sLog->outError(LOG_FILTER_SQL, "ArenaTeam %u has member with empty name - probably player %u doesn't exist, deleting him from memberlist!", arenaTeamId, GUID_LOPART(newMember.Guid)); - this->DelMember(newMember.Guid, true); + DelMember(newMember.Guid, true); continue; } @@ -267,7 +267,7 @@ bool ArenaTeam::LoadMembersFromDB(QueryResult result) if (Empty() || !captainPresentInTeam) { // Arena team is empty or captain is not in team, delete from db - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "ArenaTeam %u does not have any members or its captain is not in team, disbanding it...", TeamId); + sLog->outDebug(LOG_FILTER_ARENAS, "ArenaTeam %u does not have any members or its captain is not in team, disbanding it...", TeamId); return false; } @@ -297,7 +297,7 @@ void ArenaTeam::SetCaptain(uint64 guid) newCaptain->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 0); char const* oldCaptainName = oldCaptain ? oldCaptain->GetName() : ""; uint32 oldCaptainLowGuid = oldCaptain ? oldCaptain->GetGUIDLow() : 0; - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Player: %s [GUID: %u] promoted player: %s [GUID: %u] to leader of arena team [Id: %u] [Type: %u].", + sLog->outInfo(LOG_FILTER_ARENAS, "Player: %s [GUID: %u] promoted player: %s [GUID: %u] to leader of arena team [Id: %u] [Type: %u].", oldCaptainName, oldCaptainLowGuid, newCaptain->GetName(), newCaptain->GetGUIDLow(), GetId(), GetType()); } } @@ -321,7 +321,7 @@ void ArenaTeam::DelMember(uint64 guid, bool cleanDb) // delete all info regarding this team for (uint32 i = 0; i < ARENA_TEAM_END; ++i) player->SetArenaTeamInfoField(GetSlot(), ArenaTeamInfoType(i), 0); - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Player: %s [GUID: %u] left arena team type: %u [Id: %u].", player->GetName(), player->GetGUIDLow(), GetType(), GetId()); + sLog->outInfo(LOG_FILTER_ARENAS, "Player: %s [GUID: %u] left arena team type: %u [Id: %u].", player->GetName(), player->GetGUIDLow(), GetType(), GetId()); } // Only used for single member deletion, for arena team disband we use a single query for more efficiency @@ -346,7 +346,7 @@ void ArenaTeam::Disband(WorldSession* session) BroadcastEvent(ERR_ARENA_TEAM_DISBANDED_S, 0, 2, session->GetPlayerName(), GetName(), ""); if (Player* player = session->GetPlayer()) - sLog->outDebug(LOG_FILTER_BATTLEGROUND, "Player: %s [GUID: %u] disbanded arena team type: %u [Id: %u].", player->GetName(), player->GetGUIDLow(), GetType(), GetId()); + sLog->outInfo(LOG_FILTER_ARENAS, "Player: %s [GUID: %u] disbanded arena team type: %u [Id: %u].", player->GetName(), player->GetGUIDLow(), GetType(), GetId()); } // Update database @@ -507,7 +507,7 @@ void ArenaTeam::BroadcastEvent(ArenaTeamEvents event, uint64 guid, uint8 strCoun data << str1 << str2 << str3; break; default: - sLog->outError(LOG_FILTER_BATTLEGROUND, "Unhandled strCount %u in ArenaTeam::BroadcastEvent", strCount); + sLog->outError(LOG_FILTER_ARENAS, "Unhandled strCount %u in ArenaTeam::BroadcastEvent", strCount); return; } @@ -529,7 +529,7 @@ uint8 ArenaTeam::GetSlotByType(uint32 type) default: break; } - sLog->outError(LOG_FILTER_BATTLEGROUND, "FATAL: Unknown arena team type %u for some arena team", type); + sLog->outError(LOG_FILTER_ARENAS, "FATAL: Unknown arena team type %u for some arena team", type); return 0xFF; } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 2fd80b7b843..0731046892d 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -1228,7 +1228,7 @@ bool Player::StoreNewItemInBestSlots(uint32 titem_id, uint32 titem_amount) } // item can't be added - sLog->outError(LOG_FILTER_PLAYER, "STORAGE: Can't equip or store initial item %u for race %u class %u, error msg = %u", titem_id, getRace(), getClass(), msg); + sLog->outError(LOG_FILTER_PLAYER_ITEMS, "STORAGE: Can't equip or store initial item %u for race %u class %u, error msg = %u", titem_id, getRace(), getClass(), msg); return false; } @@ -1534,7 +1534,7 @@ void Player::Update(uint32 p_time) { //sLog->outFatal(LOG_FILTER_PLAYER, "Player has m_pad %u during update!", m_pad); //if (m_spellModTakingSpell) - sLog->outFatal(LOG_FILTER_PLAYER, "Player has m_spellModTakingSpell %u during update!", m_spellModTakingSpell->m_spellInfo->Id); + sLog->outFatal(LOG_FILTER_SPELLS_AURAS, "Player has m_spellModTakingSpell %u during update!", m_spellModTakingSpell->m_spellInfo->Id); m_spellModTakingSpell = NULL; } @@ -1731,7 +1731,7 @@ void Player::Update(uint32 p_time) { // m_nextSave reseted in SaveToDB call SaveToDB(); - sLog->outInfo(LOG_FILTER_PLAYER, "Player '%s' (GUID: %u) saved", GetName(), GetGUIDLow()); + sLog->outDebug(LOG_FILTER_PLAYER, "Player '%s' (GUID: %u) saved", GetName(), GetGUIDLow()); } else m_nextSave -= p_time; @@ -1879,12 +1879,12 @@ bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data) PlayerInfo const* info = sObjectMgr->GetPlayerInfo(plrRace, plrClass); if (!info) { - sLog->outError(LOG_FILTER_PLAYER, "Player %u has incorrect race/class pair. Don't build enum.", guid); + sLog->outError(LOG_FILTER_PLAYER_LOADING, "Player %u has incorrect race/class pair. Don't build enum.", guid); return false; } else if (!IsValidGender(gender)) { - sLog->outError(LOG_FILTER_PLAYER, "Player (%u) has incorrect gender (%hu), don't build enum.", guid, gender); + sLog->outError(LOG_FILTER_PLAYER_LOADING, "Player (%u) has incorrect gender (%hu), don't build enum.", guid, gender); return false; } @@ -2066,14 +2066,14 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati { if (!MapManager::IsValidMapCoord(mapid, x, y, z, orientation)) { - sLog->outError(LOG_FILTER_PLAYER, "TeleportTo: invalid map (%d) or invalid coordinates (X: %f, Y: %f, Z: %f, O: %f) given when teleporting player (GUID: %u, name: %s, map: %d, X: %f, Y: %f, Z: %f, O: %f).", + sLog->outError(LOG_FILTER_MAPS, "TeleportTo: invalid map (%d) or invalid coordinates (X: %f, Y: %f, Z: %f, O: %f) given when teleporting player (GUID: %u, name: %s, map: %d, X: %f, Y: %f, Z: %f, O: %f).", mapid, x, y, z, orientation, GetGUIDLow(), GetName(), GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation()); return false; } if (AccountMgr::IsPlayerAccount(GetSession()->GetSecurity()) && DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, mapid, this)) { - sLog->outError(LOG_FILTER_PLAYER, "Player (GUID: %u, name: %s) tried to enter a forbidden map %u", GetGUIDLow(), GetName(), mapid); + sLog->outError(LOG_FILTER_MAPS, "Player (GUID: %u, name: %s) tried to enter a forbidden map %u", GetGUIDLow(), GetName(), mapid); SendTransferAborted(mapid, TRANSFER_ABORT_MAP_NOT_ALLOWED); return false; } @@ -2426,7 +2426,7 @@ void Player::RemoveFromWorld() { if (WorldObject* viewpoint = GetViewpoint()) { - sLog->outFatal(LOG_FILTER_PLAYER, "Player %s has viewpoint %u %u when removed from world", GetName(), viewpoint->GetEntry(), viewpoint->GetTypeId()); + sLog->outError(LOG_FILTER_PLAYER, "Player %s has viewpoint %u %u when removed from world", GetName(), viewpoint->GetEntry(), viewpoint->GetTypeId()); SetViewpoint(viewpoint, false); } } @@ -3355,7 +3355,7 @@ void Player::SendInitialSpells() GetSession()->SendPacket(&data); - sLog->outInfo(LOG_FILTER_PLAYER, "CHARACTER: Sent Initial Spells"); + sLog->outDebug(LOG_FILTER_NETWORKIO, "CHARACTER: Sent Initial Spells"); } void Player::RemoveMail(uint32 id) @@ -3436,7 +3436,7 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning) // do character spell book cleanup (all characters) if (!IsInWorld() && !learning) // spell load case { - sLog->outError(LOG_FILTER_PLAYER, "Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.", spellId); + sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.", spellId); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_SPELL); @@ -3445,7 +3445,7 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning) CharacterDatabase.Execute(stmt); } else - sLog->outError(LOG_FILTER_PLAYER, "Player::addSpell: Non-existed in SpellStore spell #%u request.", spellId); + sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::addSpell: Non-existed in SpellStore spell #%u request.", spellId); return false; } @@ -3455,7 +3455,7 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning) // do character spell book cleanup (all characters) if (!IsInWorld() && !learning) // spell load case { - sLog->outError(LOG_FILTER_PLAYER, "Player::addTalent: Broken spell #%u learning not allowed, deleting for all characters in `character_talent`.", spellId); + sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::addTalent: Broken spell #%u learning not allowed, deleting for all characters in `character_talent`.", spellId); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_SPELL); @@ -3464,7 +3464,7 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning) CharacterDatabase.Execute(stmt); } else - sLog->outError(LOG_FILTER_PLAYER, "Player::addTalent: Broken spell #%u learning not allowed.", spellId); + sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::addTalent: Broken spell #%u learning not allowed.", spellId); return false; } @@ -3509,7 +3509,7 @@ bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent // do character spell book cleanup (all characters) if (!IsInWorld() && !learning) // spell load case { - sLog->outError(LOG_FILTER_PLAYER, "Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.", spellId); + sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.", spellId); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_SPELL); @@ -3518,7 +3518,7 @@ bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent CharacterDatabase.Execute(stmt); } else - sLog->outError(LOG_FILTER_PLAYER, "Player::addSpell: Non-existed in SpellStore spell #%u request.", spellId); + sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::addSpell: Non-existed in SpellStore spell #%u request.", spellId); return false; } @@ -3528,7 +3528,7 @@ bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent // do character spell book cleanup (all characters) if (!IsInWorld() && !learning) // spell load case { - sLog->outError(LOG_FILTER_PLAYER, "Player::addSpell: Broken spell #%u learning not allowed, deleting for all characters in `character_spell`.", spellId); + sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::addSpell: Broken spell #%u learning not allowed, deleting for all characters in `character_spell`.", spellId); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_SPELL); @@ -3537,7 +3537,7 @@ bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent CharacterDatabase.Execute(stmt); } else - sLog->outError(LOG_FILTER_PLAYER, "Player::addSpell: Broken spell #%u learning not allowed.", spellId); + sLog->outError(LOG_FILTER_SPELLS_AURAS, "Player::addSpell: Broken spell #%u learning not allowed.", spellId); return false; } @@ -4291,7 +4291,7 @@ void Player::_LoadSpellCooldowns(PreparedQueryResult result) if (!sSpellMgr->GetSpellInfo(spell_id)) { - sLog->outError(LOG_FILTER_PLAYER, "Player %u has unknown spell %u in `character_spell_cooldown`, skipping.", GetGUIDLow(), spell_id); + sLog->outError(LOG_FILTER_PLAYER_LOADING, "Player %u has unknown spell %u in `character_spell_cooldown`, skipping.", GetGUIDLow(), spell_id); continue; } @@ -5003,7 +5003,7 @@ void Player::DeleteOldCharacters(uint32 keepDays) if (result) { - sLog->outInfo(LOG_FILTER_PLAYER, "Player::DeleteOldChars: Found " UI64FMTD " character(s) to delete", result->GetRowCount()); + sLog->outDebug(LOG_FILTER_PLAYER, "Player::DeleteOldChars: Found " UI64FMTD " character(s) to delete", result->GetRowCount()); do { Field* fields = result->Fetch(); @@ -5418,7 +5418,7 @@ uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool g DurabilityCostsEntry const* dcost = sDurabilityCostsStore.LookupEntry(ditemProto->ItemLevel); if (!dcost) { - sLog->outError(LOG_FILTER_PLAYER, "RepairDurability: Wrong item lvl %u", ditemProto->ItemLevel); + sLog->outError(LOG_FILTER_PLAYER_ITEMS, "RepairDurability: Wrong item lvl %u", ditemProto->ItemLevel); return TotalCost; } @@ -5426,7 +5426,7 @@ uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool g DurabilityQualityEntry const* dQualitymodEntry = sDurabilityQualityStore.LookupEntry(dQualitymodEntryId); if (!dQualitymodEntry) { - sLog->outError(LOG_FILTER_PLAYER, "RepairDurability: Wrong dQualityModEntry %u", dQualitymodEntryId); + sLog->outError(LOG_FILTER_PLAYER_ITEMS, "RepairDurability: Wrong dQualityModEntry %u", dQualitymodEntryId); return TotalCost; } @@ -5442,7 +5442,7 @@ uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool g { if (GetGuildId() == 0) { - sLog->outDebug(LOG_FILTER_PLAYER, "You are not member of a guild"); + sLog->outDebug(LOG_FILTER_PLAYER_ITEMS, "You are not member of a guild"); return TotalCost; } @@ -5457,7 +5457,7 @@ uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool g } else if (!HasEnoughMoney(costs)) { - sLog->outDebug(LOG_FILTER_PLAYER, "You do not have enough money"); + sLog->outDebug(LOG_FILTER_PLAYER_ITEMS, "You do not have enough money"); return TotalCost; } else @@ -5665,7 +5665,7 @@ void Player::HandleBaseModValue(BaseModGroup modGroup, BaseModType modType, floa { if (modGroup >= BASEMOD_END || modType >= MOD_END) { - sLog->outError(LOG_FILTER_PLAYER, "ERROR in HandleBaseModValue(): non existed BaseModGroup of wrong BaseModType!"); + sLog->outError(LOG_FILTER_SPELLS_AURAS, "ERROR in HandleBaseModValue(): non existed BaseModGroup of wrong BaseModType!"); return; } @@ -5696,7 +5696,7 @@ float Player::GetBaseModValue(BaseModGroup modGroup, BaseModType modType) const { if (modGroup >= BASEMOD_END || modType > MOD_END) { - sLog->outError(LOG_FILTER_PLAYER, "trial to access non existed BaseModGroup or wrong BaseModType!"); + sLog->outError(LOG_FILTER_SPELLS_AURAS, "trial to access non existed BaseModGroup or wrong BaseModType!"); return 0.0f; } @@ -5710,7 +5710,7 @@ float Player::GetTotalBaseModValue(BaseModGroup modGroup) const { if (modGroup >= BASEMOD_END) { - sLog->outError(LOG_FILTER_PLAYER, "wrong BaseModGroup in GetTotalBaseModValue()!"); + sLog->outError(LOG_FILTER_SPELLS_AURAS, "wrong BaseModGroup in GetTotalBaseModValue()!"); return 0.0f; } @@ -6432,7 +6432,7 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal) SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(id); if (!pSkill) { - sLog->outError(LOG_FILTER_PLAYER, "Skill not found in SkillLineStore: skill #%u", id); + sLog->outError(LOG_FILTER_PLAYER_SKILLS, "Skill not found in SkillLineStore: skill #%u", id); return; } @@ -6592,8 +6592,6 @@ int16 Player::GetSkillTempBonusValue(uint32 skill) const void Player::SendActionButtons(uint32 state) const { - sLog->outInfo(LOG_FILTER_PLAYER, "Sending Action Buttons for '%u' spec '%u'", GetGUIDLow(), m_activeSpec); - WorldPacket data(SMSG_ACTION_BUTTONS, 1+(MAX_ACTION_BUTTONS*4)); data << uint8(state); /* @@ -6615,20 +6613,20 @@ void Player::SendActionButtons(uint32 state) const } GetSession()->SendPacket(&data); - sLog->outInfo(LOG_FILTER_PLAYER, "Action Buttons for '%u' spec '%u' Sent", GetGUIDLow(), m_activeSpec); + sLog->outInfo(LOG_FILTER_NETWORKIO, "SMSG_ACTION_BUTTONS sent '%u' spec '%u' Sent", GetGUIDLow(), m_activeSpec); } bool Player::IsActionButtonDataValid(uint8 button, uint32 action, uint8 type) { if (button >= MAX_ACTION_BUTTONS) { - sLog->outError(LOG_FILTER_PLAYER, "Action %u not added into button %u for player %s: button must be < %u", action, button, GetName(), MAX_ACTION_BUTTONS); + sLog->outError(LOG_FILTER_PLAYER_LOADING, "Action %u not added into button %u for player %s: button must be < %u", action, button, GetName(), MAX_ACTION_BUTTONS); return false; } if (action >= MAX_ACTION_BUTTON_ACTION_VALUE) { - sLog->outError(LOG_FILTER_PLAYER, "Action %u not added into button %u for player %s: action must be < %u", action, button, GetName(), MAX_ACTION_BUTTON_ACTION_VALUE); + sLog->outError(LOG_FILTER_PLAYER_LOADING, "Action %u not added into button %u for player %s: action must be < %u", action, button, GetName(), MAX_ACTION_BUTTON_ACTION_VALUE); return false; } @@ -6637,7 +6635,7 @@ bool Player::IsActionButtonDataValid(uint8 button, uint32 action, uint8 type) case ACTION_BUTTON_SPELL: if (!sSpellMgr->GetSpellInfo(action)) { - sLog->outError(LOG_FILTER_PLAYER, "Spell action %u not added into button %u for player %s: spell not exist", action, button, GetName()); + sLog->outError(LOG_FILTER_PLAYER_LOADING, "Spell action %u not added into button %u for player %s: spell not exist", action, button, GetName()); return false; } @@ -6650,7 +6648,7 @@ bool Player::IsActionButtonDataValid(uint8 button, uint32 action, uint8 type) case ACTION_BUTTON_ITEM: if (!sObjectMgr->GetItemTemplate(action)) { - sLog->outError(LOG_FILTER_PLAYER, "Item action %u not added into button %u for player %s: item not exist", action, button, GetName()); + sLog->outError(LOG_FILTER_PLAYER_LOADING, "Item action %u not added into button %u for player %s: item not exist", action, button, GetName()); return false; } break; @@ -6672,7 +6670,7 @@ ActionButton* Player::addActionButton(uint8 button, uint32 action, uint8 type) // set data and update to CHANGED if not NEW ab.SetActionAndType(action, ActionButtonType(type)); - sLog->outInfo(LOG_FILTER_PLAYER, "Player '%u' Added Action '%u' (type %u) to Button '%u'", GetGUIDLow(), action, type, button); + sLog->outInfo(LOG_FILTER_PLAYER_LOADING, "Player '%u' Added Action '%u' (type %u) to Button '%u'", GetGUIDLow(), action, type, button); return &ab; } @@ -6687,7 +6685,7 @@ void Player::removeActionButton(uint8 button) else buttonItr->second.uState = ACTIONBUTTON_DELETED; // saved, will deleted at next save - sLog->outInfo(LOG_FILTER_PLAYER, "Action Button '%u' Removed from Player '%u'", button, GetGUIDLow()); + sLog->outInfo(LOG_FILTER_PLAYER_LOADING, "Action Button '%u' Removed from Player '%u'", button, GetGUIDLow()); } ActionButton const* Player::GetActionButton(uint8 button) @@ -7698,7 +7696,7 @@ void Player::_ApplyItemMods(Item* item, uint8 slot, bool apply) if (item->IsBroken()) return; - sLog->outInfo(LOG_FILTER_PLAYER, "applying mods for item %u ", item->GetGUIDLow()); + sLog->outInfo(LOG_FILTER_PLAYER_ITEMS, "applying mods for item %u ", item->GetGUIDLow()); uint8 attacktype = Player::GetAttackBySlot(slot); @@ -8290,7 +8288,7 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellData.SpellId); if (!spellInfo) { - sLog->outError(LOG_FILTER_PLAYER, "WORLD: unknown Item spellid %i", spellData.SpellId); + sLog->outError(LOG_FILTER_PLAYER_ITEMS, "WORLD: unknown Item spellid %i", spellData.SpellId); continue; } @@ -8359,7 +8357,7 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(pEnchant->spellid[s]); if (!spellInfo) { - sLog->outError(LOG_FILTER_PLAYER, "Player::CastItemCombatSpell(GUID: %u, name: %s, enchant: %i): unknown spell %i is casted, ignoring...", + sLog->outError(LOG_FILTER_PLAYER_ITEMS, "Player::CastItemCombatSpell(GUID: %u, name: %s, enchant: %i): unknown spell %i is casted, ignoring...", GetGUIDLow(), GetName(), pEnchant->ID, pEnchant->spellid[s]); continue; } diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index e4926bfad2e..7451bd2dc2a 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -658,8 +658,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte SendPacket(&data); std::string IP_str = GetRemoteAddress(); - sLog->outInfo(LOG_FILTER_NETWORKIO, "Account: %d (IP: %s) Create Character:[%s] (GUID: %u)", GetAccountId(), IP_str.c_str(), createInfo->Name.c_str(), newChar.GetGUIDLow()); - sLog->outDebug(LOG_FILTER_PLAYER, "Account: %d (IP: %s) Create Character:[%s] (GUID: %u)", GetAccountId(), IP_str.c_str(), createInfo->Name.c_str(), newChar.GetGUIDLow()); + sLog->outInfo(LOG_FILTER_CHARACTER, "Account: %d (IP: %s) Create Character:[%s] (GUID: %u)", GetAccountId(), IP_str.c_str(), createInfo->Name.c_str(), newChar.GetGUIDLow()); sScriptMgr->OnPlayerCreate(&newChar); sWorld->AddCharacterNameData(newChar.GetGUIDLow(), std::string(newChar.GetName()), newChar.getGender(), newChar.getRace(), newChar.getClass()); @@ -716,15 +715,15 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket & recv_data) return; std::string IP_str = GetRemoteAddress(); - sLog->outDebug(LOG_FILTER_PLAYER, "Account: %d (IP: %s) Delete Character:[%s] (GUID: %u)", GetAccountId(), IP_str.c_str(), name.c_str(), GUID_LOPART(guid)); + sLog->outInfo(LOG_FILTER_CHARACTER, "Account: %d (IP: %s) Delete Character:[%s] (GUID: %u)", GetAccountId(), IP_str.c_str(), name.c_str(), GUID_LOPART(guid)); sScriptMgr->OnPlayerDelete(guid); sWorld->DeleteCharaceterNameData(GUID_LOPART(guid)); - if (sLog->ShouldLog(LOG_FILTER_PLAYER_DELETE, LOG_LEVEL_INFO)) // optimize GetPlayerDump call + if (sLog->ShouldLog(LOG_FILTER_CHARACTER, LOG_LEVEL_DEBUG)) // optimize GetPlayerDump call { std::string dump; if (PlayerDumpWriter().GetDump(GUID_LOPART(guid), dump)) - sLog->outInfo(LOG_FILTER_PLAYER_DELETE, dump.c_str(), GetAccountId(), GUID_LOPART(guid), name.c_str()); + sLog->outDebug(LOG_FILTER_CHARACTER, dump.c_str(), GetAccountId(), GUID_LOPART(guid), name.c_str()); } Player::DeleteFromDB(guid, GetAccountId()); @@ -1002,7 +1001,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) SendNotification(LANG_GM_ON); std::string IP_str = GetRemoteAddress(); - sLog->outInfo(LOG_FILTER_PLAYER_LOADING, "Account: %d (IP: %s) Login Character:[%s] (GUID: %u) Level: %d", + sLog->outInfo(LOG_FILTER_CHARACTER, "Account: %d (IP: %s) Login Character:[%s] (GUID: %u) Level: %d", GetAccountId(), IP_str.c_str(), pCurrChar->GetName(), pCurrChar->GetGUIDLow(), pCurrChar->getLevel()); if (!pCurrChar->IsStandState() && !pCurrChar->HasUnitState(UNIT_STATE_STUNNED)) @@ -1179,7 +1178,7 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(PreparedQueryResult resu CharacterDatabase.Execute(stmt); - sLog->outDebug(LOG_FILTER_PLAYER, "Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", GetAccountId(), GetRemoteAddress().c_str(), oldName.c_str(), guidLow, newName.c_str()); + sLog->outInfo(LOG_FILTER_CHARACTER, "Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", GetAccountId(), GetRemoteAddress().c_str(), oldName.c_str(), guidLow, newName.c_str()); WorldPacket data(SMSG_CHAR_RENAME, 1+8+(newName.size()+1)); data << uint8(RESPONSE_SUCCESS); @@ -1446,7 +1445,7 @@ void WorldSession::HandleCharCustomize(WorldPacket& recv_data) if (result) { std::string oldname = result->Fetch()[0].GetString(); - sLog->outDebug(LOG_FILTER_PLAYER, "Account: %d (IP: %s), Character[%s] (guid:%u) Customized to: %s", GetAccountId(), GetRemoteAddress().c_str(), oldname.c_str(), GUID_LOPART(guid), newName.c_str()); + sLog->outInfo(LOG_FILTER_CHARACTER, "Account: %d (IP: %s), Character[%s] (guid:%u) Customized to: %s", GetAccountId(), GetRemoteAddress().c_str(), oldname.c_str(), GUID_LOPART(guid), newName.c_str()); } Player::Customize(guid, gender, skin, face, hairStyle, hairColor, facialHair); diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 6fdbf8a5358..118b0d68d5d 100755 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -534,7 +534,7 @@ void WorldSession::LogoutPlayer(bool Save) // e.g if he got disconnected during a transfer to another map // calls to GetMap in this case may cause crashes _player->CleanupsBeforeDelete(); - sLog->outInfo(LOG_FILTER_PLAYER_LOADING, "Account: %d (IP: %s) Logout Character:[%s] (GUID: %u) Level: %d", GetAccountId(), GetRemoteAddress().c_str(), _player->GetName(), _player->GetGUIDLow(), _player->getLevel()); + sLog->outInfo(LOG_FILTER_CHARACTER, "Account: %d (IP: %s) Logout Character:[%s] (GUID: %u) Level: %d", GetAccountId(), GetRemoteAddress().c_str(), _player->GetName(), _player->GetGUIDLow(), _player->getLevel()); if (Map* _map = _player->FindMap()) _map->RemovePlayerFromMap(_player, true); diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp index db975419a23..1024a3acf15 100644 --- a/src/server/scripts/Commands/cs_account.cpp +++ b/src/server/scripts/Commands/cs_account.cpp @@ -111,7 +111,7 @@ public: handler->PSendSysMessage(LANG_ACCOUNT_CREATED, accountName); if (handler->GetSession()) { - sLog->outDebug(LOG_FILTER_PLAYER, "Account: %d (IP: %s) Character:[%s] (GUID: %u) Change Password." + sLog->outInfo(LOG_FILTER_CHARACTER, "Account: %d (IP: %s) Character:[%s] (GUID: %u) Change Password." , handler->GetSession()->GetAccountId(),handler->GetSession()->GetRemoteAddress().c_str() , handler->GetSession()->GetPlayer()->GetName(), handler->GetSession()->GetPlayer()->GetGUIDLow()); } diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 355ff195cf5..7f25a11bcdd 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -1325,7 +1325,7 @@ public: { Player* player = handler->GetSession()->GetPlayer(); - sLog->outInfo(LOG_FILTER_SQL, "(@PATH, XX, %.3f, %.3f, %.5f, 0,0, 0,100, 0),", player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); + sLog->outInfo(LOG_FILTER_SQL_DEV, "(@PATH, XX, %.3f, %.3f, %.5f, 0,0, 0,100, 0),", player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); handler->PSendSysMessage("Waypoint SQL written to SQL Developer log"); return true; diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h index d86b99a062a..9d6fabb9dfa 100755 --- a/src/server/shared/Database/DatabaseWorkerPool.h +++ b/src/server/shared/Database/DatabaseWorkerPool.h @@ -64,7 +64,7 @@ class DatabaseWorkerPool bool res = true; _connectionInfo = MySQLConnectionInfo(infoString); - sLog->outWarn(LOG_FILTER_SQL, "Opening DatabasePool '%s'. Asynchronous connections: %u, synchronous connections: %u.", + sLog->outInfo(LOG_FILTER_SQL_DRIVER, "Opening DatabasePool '%s'. Asynchronous connections: %u, synchronous connections: %u.", GetDatabaseName(), async_threads, synch_threads); //! Open asynchronous connections (delayed operations) @@ -88,17 +88,17 @@ class DatabaseWorkerPool } if (res) - sLog->outWarn(LOG_FILTER_SQL, "DatabasePool '%s' opened successfully. %u total connections running.", GetDatabaseName(), + sLog->outInfo(LOG_FILTER_SQL_DRIVER, "DatabasePool '%s' opened successfully. %u total connections running.", GetDatabaseName(), (_connectionCount[IDX_SYNCH] + _connectionCount[IDX_ASYNC])); else - sLog->outError(LOG_FILTER_SQL, "DatabasePool %s NOT opened. There were errors opening the MySQL connections. Check your SQLDriverLogFile " + sLog->outError(LOG_FILTER_SQL_DRIVER, "DatabasePool %s NOT opened. There were errors opening the MySQL connections. Check your SQLDriverLogFile " "for specific errors.", GetDatabaseName()); return res; } void Close() { - sLog->outWarn(LOG_FILTER_SQL, "Closing down DatabasePool '%s'.", GetDatabaseName()); + sLog->outInfo(LOG_FILTER_SQL_DRIVER, "Closing down DatabasePool '%s'.", GetDatabaseName()); //! Shuts down delaythreads for this connection pool by underlying deactivate(). //! The next dequeue attempt in the worker thread tasks will result in an error, @@ -114,7 +114,7 @@ class DatabaseWorkerPool t->Close(); //! Closes the actualy MySQL connection. } - sLog->outWarn(LOG_FILTER_SQL, "Asynchronous connections on DatabasePool '%s' terminated. Proceeding with synchronous connections.", + sLog->outInfo(LOG_FILTER_SQL_DRIVER, "Asynchronous connections on DatabasePool '%s' terminated. Proceeding with synchronous connections.", GetDatabaseName()); //! Shut down the synchronous connections @@ -127,7 +127,7 @@ class DatabaseWorkerPool //! Deletes the ACE_Activation_Queue object and its underlying ACE_Message_Queue delete _queue; - sLog->outWarn(LOG_FILTER_SQL, "All connections on DatabasePool '%s' closed.", GetDatabaseName()); + sLog->outInfo(LOG_FILTER_SQL_DRIVER, "All connections on DatabasePool '%s' closed.", GetDatabaseName()); } /** @@ -351,10 +351,10 @@ class DatabaseWorkerPool switch (transaction->GetSize()) { case 0: - sLog->outWarn(LOG_FILTER_SQL, "Transaction contains 0 queries. Not executing."); + sLog->outDebug(LOG_FILTER_SQL_DRIVER, "Transaction contains 0 queries. Not executing."); return; case 1: - sLog->outWarn(LOG_FILTER_SQL, "Warning: Transaction only holds 1 query, consider removing Transaction context in code."); + sLog->outDebug(LOG_FILTER_SQL_DRIVER, "Warning: Transaction only holds 1 query, consider removing Transaction context in code."); break; default: break; diff --git a/src/server/shared/Logging/Appender.cpp b/src/server/shared/Logging/Appender.cpp index abb2649c468..be30a54ff02 100644 --- a/src/server/shared/Logging/Appender.cpp +++ b/src/server/shared/Logging/Appender.cpp @@ -201,8 +201,14 @@ char const* Appender::getLogFilterTypeString(LogFilterType type) return "GAMEEVENTS"; case LOG_FILTER_CALENDAR: return "CALENDAR"; - case LOG_FILTER_PLAYER_DELETE: - return "PLAYER_DELETE"; + case LOG_FILTER_CHARACTER: + return "CHARACTER"; + case LOG_FILTER_ARENAS: + return "ARENAS"; + case LOG_FILTER_SQL_DRIVER: + return "SQL DRIVER"; + case LOG_FILTER_SQL_DEV: + return "SQL DEV"; default: break; } diff --git a/src/server/shared/Logging/Appender.h b/src/server/shared/Logging/Appender.h index 323da3f2be8..7d7375a1edb 100644 --- a/src/server/shared/Logging/Appender.h +++ b/src/server/shared/Logging/Appender.h @@ -59,10 +59,13 @@ enum LogFilterType LOG_FILTER_WORLDSERVER, LOG_FILTER_GAMEEVENTS, LOG_FILTER_CALENDAR, - LOG_FILTER_PLAYER_DELETE + LOG_FILTER_CHARACTER, + LOG_FILTER_ARENAS, + LOG_FILTER_SQL_DRIVER, + LOG_FILTER_SQL_DEV }; -const uint8 MaxLogFilter = uint8(LOG_FILTER_PLAYER_DELETE) + 1; +const uint8 MaxLogFilter = uint8(LOG_FILTER_SQL_DEV) + 1; // Values assigned have their equivalent in enum ACE_Log_Priority enum LogLevel diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index cce670922f4..c9ba159cdea 100755 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -19,7 +19,7 @@ #include "Log.h" #include "Common.h" #include "Config.h" - +#include "Util.h" #include "AppenderConsole.h" #include "AppenderFile.h" #include "AppenderDB.h" @@ -82,30 +82,66 @@ void Log::CreateAppenderFromConfig(const char* name) if (!name || *name == '\0') return; - std::string base = "Appender."; - base.append(name); - base.push_back('.'); + // Format=type,level,flags,optional1,optional2 + // if type = File. optional1 = file and option2 = mode + // if type = Console. optional1 = Color + std::string options = "Appender."; + options.append(name); + options = ConfigMgr::GetStringDefault(options.c_str(), ""); + Tokens tokens(options, ','); + Tokens::iterator iter = tokens.begin(); + + if (tokens.size() < 2) + { + fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong configuration for appender %s. Config line: %s\n", name, options.c_str()); + return; + } - LogLevel level = LogLevel(GetConfigIntDefault(base, "Level", 0)); - AppenderType type = AppenderType(GetConfigIntDefault(base, "Type", 0)); + AppenderFlags flags = APPENDER_FLAGS_NONE; + AppenderType type = AppenderType(atoi(*iter)); + ++iter; + LogLevel level = LogLevel(atoi(*iter)); + if (level > LOG_LEVEL_FATAL) + { + fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong Log Level %u for appender %s\n", level, name); + return; + } - switch(type) + if (++iter != tokens.end()) + flags = AppenderFlags(atoi(*iter)); + + switch (type) { case APPENDER_CONSOLE: { - AppenderFlags flags = AppenderFlags(GetConfigIntDefault(base, "Flags", APPENDER_FLAGS_PREFIX_LOGLEVEL | APPENDER_FLAGS_PREFIX_LOGFILTERTYPE)); + if (flags == APPENDER_FLAGS_NONE) + flags = AppenderFlags(APPENDER_FLAGS_PREFIX_LOGLEVEL | APPENDER_FLAGS_PREFIX_LOGFILTERTYPE); + AppenderConsole* appender = new AppenderConsole(NextAppenderId(), name, level, flags); appenders[appender->getId()] = appender; - - appender->InitColors(GetConfigStringDefault(base, "Colors", "")); + if (++iter != tokens.end()) + appender->InitColors(*iter); //fprintf(stdout, "Log::CreateAppenderFromConfig: Created Appender %s (%u), Type CONSOLE, Mask %u\n", appender->getName().c_str(), appender->getId(), appender->getLogLevel()); // DEBUG - RemoveMe break; } case APPENDER_FILE: { - std::string filename = GetConfigStringDefault(base, "File", ""); - std::string mode = GetConfigStringDefault(base, "Mode", "a"); - AppenderFlags flags = AppenderFlags(GetConfigIntDefault(base, "Flags", APPENDER_FLAGS_PREFIX_TIMESTAMP | APPENDER_FLAGS_PREFIX_LOGLEVEL | APPENDER_FLAGS_PREFIX_LOGFILTERTYPE)); + std::string filename; + std::string mode = "a"; + + if (++iter == tokens.end()) + { + fprintf(stderr, "Log::CreateAppenderFromConfig: Missing file name for appender %s\n", name); + return; + } + + if (flags == APPENDER_FLAGS_NONE) + flags = AppenderFlags(APPENDER_FLAGS_PREFIX_LOGLEVEL | APPENDER_FLAGS_PREFIX_LOGFILTERTYPE | APPENDER_FLAGS_PREFIX_TIMESTAMP); + + filename = *iter; + + if (++iter != tokens.end()) + mode = *iter; if (flags & APPENDER_FLAGS_USE_TIMESTAMP) { @@ -121,13 +157,14 @@ void Log::CreateAppenderFromConfig(const char* name) //fprintf(stdout, "Log::CreateAppenderFromConfig: Created Appender %s (%u), Type FILE, Mask %u, File %s, Mode %s\n", name, id, level, filename.c_str(), mode.c_str()); // DEBUG - RemoveMe break; } - case APPENDER_DB: // TODO Set realm! + case APPENDER_DB: { uint8 id = NextAppenderId(); appenders[id] = new AppenderDB(id, name, level, realm); break; } default: + fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown type %u for appender %s\n", type, name); break; } } @@ -137,29 +174,49 @@ void Log::CreateLoggerFromConfig(const char* name) if (!name || *name == '\0') return; - std::string base = "Logger."; - base.append(name); - base.push_back('.'); + LogLevel level = LOG_LEVEL_DISABLED; + int32 type = -1; - LogLevel level = LogLevel(GetConfigIntDefault(base, "Level", 0)); - int32 type = GetConfigIntDefault(base, "Type", -1); + std::string options = "Logger."; + options.append(name); + options = ConfigMgr::GetStringDefault(options.c_str(), ""); - if (type < 0) + Tokens tokens(options, ','); + Tokens::iterator iter = tokens.begin(); + + if (tokens.size() != 3) { - fprintf(stderr, "Log::CreateLoggerFromConfig: Missing entry %sType in config. Logger ignored\n", name); + fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong configuration for logger %s. Config line: %s\n", name, options.c_str()); return; } - Logger& logger = loggers[type]; + type = atoi(*iter); + if (type > MaxLogFilter) + { + fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong type %u for logger %s\n", type, name); + return; + } + Logger& logger = loggers[type]; if (!logger.getName().empty()) - fprintf(stderr, "Error while configuring Logger %s. Replacing (name: %s, Type: %u, Level: %u) with (name: %s, Type: %u, Level: %u)\n", - name, logger.getName().c_str(), logger.getType(), logger.getLogLevel(), name, type, level); + { + fprintf(stderr, "Error while configuring Logger %s. Already defined\n", name); + return; + } + + ++iter; + level = LogLevel(atoi(*iter)); + if (level > LOG_LEVEL_FATAL) + { + fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong Log Level %u for logger %s\n", type, name); + return; + } logger.Create(name, LogFilterType(type), level); //fprintf(stdout, "Log::CreateLoggerFromConfig: Created Logger %s, Type %u, mask %u\n", name, LogFilterType(type), level); // DEBUG - RemoveMe - std::istringstream ss(GetConfigStringDefault(base, "Appenders", "")); + ++iter; + std::istringstream ss(*iter); std::string str; ss >> str; diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 3fe9ab4c37e..be5a452c7b4 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -1148,15 +1148,6 @@ Warden.NumMemChecks = 3 Warden.NumOtherChecks = 7 -# -# Warden.LogFile -# Description: Client check fails will be logged here. -# Default: "" - (Disabled) -# "Warden.log" - (Enabled) -# - -Warden.LogFile = "" - # # Warden.ClientResponseDelay # Description: Time (in seconds) before client is getting disconnecting for not responding. @@ -2580,174 +2571,186 @@ PlayerDump.DisallowOverwrite = 1 ################################################################################################### # # Logging system options. -# Note: As it uses dynamic option naming, all options related to one appender or logger are grouped. -# # -# Appender config values: Given a appender "name" the following options -# can be read: -# -# Appender.name.Type -# Description: Type of appender. Extra appender config options -# will be read depending on this value -# Default: 0 - (None) -# 1 - (Console) -# 2 - (File) -# 3 - (DB) -# -# Appender.name.Level -# Description: Appender level of logging -# Default: 0 - (Disabled) -# 1 - (Trace) -# 2 - (Debug) -# 3 - (Info) -# 4 - (Warn) -# 5 - (Error) -# 6 - (Fatal) -# -# Appender.name.Colors -# Description: Colors for log messages -# (Format: "fatal error warn info debug trace"). -# (Only used with Type = 1) -# Default: "" - no colors -# Colors: 0 - BLACK -# 1 - RED -# 2 - GREEN -# 3 - BROWN -# 4 - BLUE -# 5 - MAGENTA -# 6 - CYAN -# 7 - GREY -# 8 - YELLOW -# 9 - LRED -# 10 - LGREEN -# 11 - LBLUE -# 12 - LMAGENTA -# 13 - LCYAN -# 14 - WHITE -# Example: "13 11 9 5 3 1" -# -# Appender.name.File -# Description: Name of the file -# Allows to use one "%u" to create dynamic files -# (Only used with Type = 2) -# -# Appender.name.Mode -# Description: Mode to open the file -# (Only used with Type = 2) -# Default: a - (Append) -# w - (Overwrite) -# -# Appender.name.Flags -# Description: -# Default: Console = 6, File = 7, DB = 0 -# 0 - None -# 1 - Prefix Timestamp to the text -# 2 - Prefix Log Level to the text -# 4 - Prefix Log Filter type to the text -# 8 - Append timestamp to the log file name. Format: YYYY-MM-DD_HH-MM-SS (Only used with Type = 2) -# 16 - Make a backup of existing file before overwrite (Only used with Mode = w) -# -# Logger config values: Given a logger "name" the following options -# can be read: -# -# Logger.name.Type -# Description: Type of logger. Logs anything related to... -# If no logger with type = 0 exists core will create -# it but disabled. Logger with type = 0 is the -# default one, used when there is no other specific -# logger configured for other logger types -# Default: 0 - Default. Each type that has no config will -# rely on this one. Core will create this logger -# (disabled) if it's not configured -# 1 - Units that doesn't fit in other categories -# 2 - Pets -# 3 - Vehicles -# 4 - C++ AI, instance scripts, etc. -# 5 - DB AI, such as SAI, EAI, CreatureAI -# 6 - DB map scripts -# 7 - Network input/output, -# such as packet handlers and netcode logs -# 8 - Spellsystem and aurasystem -# 9 - Achievement system -# 10 - Condition system -# 11 - Pool system -# 12 - Auction house -# 13 - Arena's and battlegrounds -# 14 - Outdoor PVP -# 15 - Chat system -# 16 - LFG system -# 17 - Maps, instances (not scripts), -# grids, cells, visibility, etc. -# 18 - Player that doesn't fit in other categories. -# 19 - Player loading from DB -# (Player::_LoadXXX functions) -# 20 - Items -# 21 - Player skills (do not confuse with spells) -# 22 - Player chat logs -# 23 - loot -# 24 - guilds -# 25 - transports -# 26 - SQL. DB errors and SQL Driver -# 27 - GM Commands -# 28 - Remote Access Commands -# 29 - Warden -# 30 - Authserver -# 31 - Worldserver -# 32 - Game Events -# 33 - Calendar -# 34 - Player delete -# -# Logger.name.Level -# Description: Logger level of logging -# Default: 0 - (Disabled) -# 1 - (Trace) -# 2 - (Debug) -# 3 - (Info) -# 4 - (Warn) -# 5 - (Error) -# 6 - (Fatal) -# -# Logger.name.Appenders -# Description: List of appenders linked to logger +# Appender config values: Given a appender "name" +# Appender.name +# Description: Defines 'where to log' +# Format: Type,LogLevel,Flags,optional1,optional2 +# +# Type +# 0 - (None) +# 1 - (Console) +# 2 - (File) +# 3 - (DB) +# +# LogLevel +# 0 - (Disabled) +# 1 - (Trace) +# 2 - (Debug) +# 3 - (Info) +# 4 - (Warn) +# 5 - (Error) +# 6 - (Fatal) +# +# Flags: Default Console = 6, File = 7, DB = 0 +# 0 - None +# 1 - Prefix Timestamp to the text +# 2 - Prefix Log Level to the text +# 4 - Prefix Log Filter type to the text +# 8 - Append timestamp to the log file name. Format: YYYY-MM-DD_HH-MM-SS (Only used with Type = 2) +# 16 - Make a backup of existing file before overwrite (Only used with Mode = w) +# +# Colors (read as optional1 if Type = Console) +# Format: "fatal error warn info debug trace" +# 0 - BLACK +# 1 - RED +# 2 - GREEN +# 3 - BROWN +# 4 - BLUE +# 5 - MAGENTA +# 6 - CYAN +# 7 - GREY +# 8 - YELLOW +# 9 - LRED +# 10 - LGREEN +# 11 - LBLUE +# 12 - LMAGENTA +# 13 - LCYAN +# 14 - WHITE +# Example: "13 11 9 5 3 1" +# +# File: Name of the file (read as optional1 if Type = File) +# Allows to use one "%u" to create dynamic files +# +# Mode: Mode to open the file (read as optional2 if Type = File) +# a - (Append) +# w - (Overwrite) +# + +Appender.Console=1,2,6 +Appender.Server=2,2,7,Server.log,w +Appender.GM=2,2,7,GM.log +Appender.SQL=2,2,7,SQL.log +Appender.DBErrors=2,2,7,DBErrors.log +Appender.Char=2,2,7,Char.log,w +Appender.RA=2,2,7,RA.log +Appender.Arenas=2,2,7,Arena.log +Appender.SQLDev=2,2,7,SQLDev.log +Appender.SQLDriver=2,2,7,SQLDriver.log +Appender.Warden=2,2,7,Warden.log +Appender.Chat=2,2,7,Chat.log + +# Logger config values: Given a logger "name" +# Logger.name +# Description: Defines 'What to log' +# Format: Type,LogLevel,AppenderList +# Type +# 0 - Default. Each type that has no config will +# rely on this one. Core will create this logger +# (disabled) if it's not configured +# 1 - Units that doesn't fit in other categories +# 2 - Pets +# 3 - Vehicles +# 4 - C++ AI, instance scripts, etc. +# 5 - DB AI, such as SAI, EAI, CreatureAI +# 6 - DB map scripts +# 7 - Network input/output, +# such as packet handlers and netcode logs +# 8 - Spellsystem and aurasystem +# 9 - Achievement system +# 10 - Condition system +# 11 - Pool system +# 12 - Auction house +# 13 - Arena's and battlegrounds +# 14 - Outdoor PVP +# 15 - Chat system +# 16 - LFG system +# 17 - Maps, instances (not scripts), +# grids, cells, visibility, etc. +# 18 - Player that doesn't fit in other categories. +# 19 - Player loading from DB +# (Player::_LoadXXX functions) +# 20 - Items +# 21 - Player skills (do not confuse with spells) +# 22 - Player chat logs +# 23 - loot +# 24 - guilds +# 25 - transports +# 26 - SQL. DB errors +# 27 - GM Commands +# 28 - Remote Access Commands +# 29 - Warden +# 30 - Authserver +# 31 - Worldserver +# 32 - Game Events +# 33 - Calendar +# 34 - Character (Exclusive to log login, logout, create, rename, delete actions) +# 35 - Arenas +# 36 - SQL Driver +# 37 - SQL Dev + +Logger.Root=0,5,Console Server +Logger.Units=1,3,Console Server +Logger.Pets=2,3,Console Server +Logger.Vehicles=3,3,Console Server +Logger.TCSR=4,3,Console Server +Logger.AI=5,3,Console Server +Logger.MapScripts=6,3,Console Server +Logger.NetWork=7,3,Console Server +Logger.Spells=8,3,Console Server +Logger.Achievements=9,3,Console Server +Logger.Conditions=10,3,Console Server +Logger.Pool=11,3,Console Server +Logger.AuctionHouse=12,3,Console Server +Logger.Battlegrounds=13,3,Console Server +Logger.OutdoorPvP=14,3,Console Server +Logger.ChatSystem=15,3,Console Server +Logger.LFG=16,3,Console Server +Logger.Maps=17,3,Console Server +Logger.Player=18,3,Console Server +Logger.PlayerLoading=19,3,Console Server +Logger.PlayerItems=20,3,Console Server +Logger.PlayerSkills=21,3,Console Server +Logger.PlayerChat=22,3,Chat +Logger.Loot=23,3,Console Server +Logger.Guilds=24,3,Console Server +Logger.Transports=25,3,Console Server +Logger.SQL=26,2,Console Server SQL +Logger.GM=27,3,Console Server GM +Logger.RA=28,3,RA +Logger.Warden=29,3,Warden +Logger.Authserver=30,3,Console Server +Logger.Worldserver=31,3,Console Server +Logger.GameEvents=32,3,Console Server +Logger.Calendar=33,3,Console Server +Logger.Character=34,3,Char +Logger.Arenas=35,3,Arenas +Logger.SQLDriver=36,5,SQLDriver +Logger.SQLDev=37,3,SQLDev + +# LogLevel +# 0 - (Disabled) +# 1 - (Trace) +# 2 - (Debug) +# 3 - (Info) +# 4 - (Warn) +# 5 - (Error) +# 6 - (Fatal) +# +# AppenderList: List of appenders linked to logger # (Using spaces as separator). # # Appenders # Description: List of Appenders to read from config # (Using spaces as separator). # Default: "Console Server" + +Appenders=Console Server + # # Loggers # Description: List of Loggers to read from config # (Using spaces as separator). # Default: "root" -Loggers=root GM SQL -Appenders=Console Server GM SQL - -Appender.Console.Type=1 -Appender.Console.Level=2 - -Appender.Server.Type=2 -Appender.Server.Level=2 -Appender.Server.File=Server.log -Appender.Server.Mode=w - -Appender.GM.Type=2 -Appender.GM.Level=2 -Appender.GM.File=gm_#%u.log - -Appender.SQL.Type=2 -Appender.SQL.Level=2 -Appender.SQL.File=SQL.log - -Logger.root.Type=0 -Logger.root.Level=3 -Logger.root.Appenders=Console Server - -Logger.SQL.Type=26 -Logger.SQL.Level=3 -Logger.SQL.Appenders=Console Server SQL - -Logger.GM.Type=27 -Logger.GM.Level=3 -Logger.GM.Appenders=Console Server GM +Loggers=Root -- cgit v1.2.3 From f8cd39b2ed1056f409c2690ac8bb661fbcb68e18 Mon Sep 17 00:00:00 2001 From: Shauren Date: Tue, 7 Aug 2012 17:45:10 +0200 Subject: Core/Players: Improved alcohol handling, weeeeeeeeeeeeeeeee Closes #7293 --- sql/base/characters_database.sql | 2 +- .../2012_08_07_00_characters_characters.sql | 2 + src/server/game/Entities/Player/Player.cpp | 62 +++++++++++----------- src/server/game/Entities/Player/Player.h | 7 ++- src/server/game/Spells/SpellEffects.cpp | 14 ++--- src/server/scripts/Commands/cs_modify.cpp | 15 ++---- 6 files changed, 49 insertions(+), 53 deletions(-) create mode 100644 sql/updates/characters/2012_08_07_00_characters_characters.sql (limited to 'src/server/scripts/Commands') diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index b4a3af6e8ff..bbd5a70e933 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -1177,7 +1177,7 @@ CREATE TABLE `characters` ( `chosenTitle` int(10) unsigned NOT NULL DEFAULT '0', `knownCurrencies` bigint(20) unsigned NOT NULL DEFAULT '0', `watchedFaction` int(10) unsigned NOT NULL DEFAULT '0', - `drunk` smallint(5) unsigned NOT NULL DEFAULT '0', + `drunk` tinyint(3) unsigned NOT NULL DEFAULT '0', `health` int(10) unsigned NOT NULL DEFAULT '0', `power1` int(10) unsigned NOT NULL DEFAULT '0', `power2` int(10) unsigned NOT NULL DEFAULT '0', diff --git a/sql/updates/characters/2012_08_07_00_characters_characters.sql b/sql/updates/characters/2012_08_07_00_characters_characters.sql new file mode 100644 index 00000000000..e9bea82ad4b --- /dev/null +++ b/sql/updates/characters/2012_08_07_00_characters_characters.sql @@ -0,0 +1,2 @@ +UPDATE characters SET drunk = (drunk / 256) & 0xFF; +ALTER TABLE characters CHANGE drunk drunk tinyint(3) unsigned NOT NULL DEFAULT '0'; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 0731046892d..72c500513cd 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -726,7 +726,6 @@ Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_rep m_MirrorTimerFlagsLast = UNDERWATER_NONE; m_isInWater = false; m_drunkTimer = 0; - m_drunk = 0; m_restTime = 0; m_deathTimer = 0; m_deathExpireTime = 0; @@ -1458,49 +1457,51 @@ void Player::HandleDrowning(uint32 time_diff) m_MirrorTimerFlagsLast = m_MirrorTimerFlags; } -///The player sobers by 256 every 10 seconds +///The player sobers by 1% every 9 seconds void Player::HandleSobering() { m_drunkTimer = 0; - uint32 drunk = (m_drunk <= 256) ? 0 : (m_drunk - 256); + uint8 currentDrunkValue = GetDrunkValue(); + uint8 drunk = currentDrunkValue ? --currentDrunkValue : 0; SetDrunkValue(drunk); } -DrunkenState Player::GetDrunkenstateByValue(uint16 value) +DrunkenState Player::GetDrunkenstateByValue(uint8 value) { - if (value >= 23000) + if (value >= 90) return DRUNKEN_SMASHED; - if (value >= 12800) + if (value >= 50) return DRUNKEN_DRUNK; - if (value & 0xFFFE) + if (value) return DRUNKEN_TIPSY; return DRUNKEN_SOBER; } -void Player::SetDrunkValue(uint16 newDrunkenValue, uint32 itemId) +void Player::SetDrunkValue(uint8 newDrunkValue, uint32 itemId /*= 0*/) { - uint32 oldDrunkenState = Player::GetDrunkenstateByValue(m_drunk); + bool isSobering = newDrunkValue < GetDrunkValue(); + uint32 oldDrunkenState = Player::GetDrunkenstateByValue(GetDrunkValue()); + if (newDrunkValue > 100) + newDrunkValue = 100; // select drunk percent or total SPELL_AURA_MOD_FAKE_INEBRIATE amount, whichever is higher for visibility updates - int32 drunkPercent = newDrunkenValue * 100 / 0xFFFF; - drunkPercent = std::max(drunkPercent, GetTotalAuraModifier(SPELL_AURA_MOD_FAKE_INEBRIATE)); - + int32 drunkPercent = std::max(newDrunkValue, GetTotalAuraModifier(SPELL_AURA_MOD_FAKE_INEBRIATE)); if (drunkPercent) { m_invisibilityDetect.AddFlag(INVISIBILITY_DRUNK); m_invisibilityDetect.SetValue(INVISIBILITY_DRUNK, drunkPercent); } - else if (!HasAuraType(SPELL_AURA_MOD_FAKE_INEBRIATE) && !newDrunkenValue) + else if (!HasAuraType(SPELL_AURA_MOD_FAKE_INEBRIATE) && !newDrunkValue) m_invisibilityDetect.DelFlag(INVISIBILITY_DRUNK); - m_drunk = newDrunkenValue; - SetUInt32Value(PLAYER_BYTES_3, (GetUInt32Value(PLAYER_BYTES_3) & 0xFFFF0001) | (m_drunk & 0xFFFE)); - - uint32 newDrunkenState = Player::GetDrunkenstateByValue(m_drunk); - + uint32 newDrunkenState = Player::GetDrunkenstateByValue(newDrunkValue); + SetByteValue(PLAYER_BYTES_3, 1, newDrunkValue); UpdateObjectVisibility(); + if (!isSobering) + m_drunkTimer = 0; // reset sobering timer + if (newDrunkenState == oldDrunkenState) return; @@ -1508,7 +1509,6 @@ void Player::SetDrunkValue(uint16 newDrunkenValue, uint32 itemId) data << uint64(GetGUID()); data << uint32(newDrunkenState); data << uint32(itemId); - SendMessageToSet(&data, true); } @@ -1749,11 +1749,10 @@ void Player::Update(uint32 p_time) m_Last_tick = now; } - if (m_drunk) + if (GetDrunkValue()) { m_drunkTimer += p_time; - - if (m_drunkTimer > 10*IN_MILLISECONDS) + if (m_drunkTimer > 9 * IN_MILLISECONDS) HandleSobering(); } @@ -16748,7 +16747,8 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) SetUInt32Value(PLAYER_BYTES, fields[9].GetUInt32()); SetUInt32Value(PLAYER_BYTES_2, fields[10].GetUInt32()); - SetUInt32Value(PLAYER_BYTES_3, (fields[49].GetUInt16() & 0xFFFE) | fields[5].GetUInt8()); + SetByteValue(PLAYER_BYTES_3, 0, fields[5].GetUInt8()); + SetByteValue(PLAYER_BYTES_3, 1, fields[49].GetUInt8()); SetUInt32Value(PLAYER_FLAGS, fields[11].GetUInt32()); SetInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, fields[48].GetUInt32()); @@ -17058,13 +17058,11 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder) // set value, including drunk invisibility detection // calculate sobering. after 15 minutes logged out, the player will be sober again - float soberFactor; - if (time_diff > 15*MINUTE) - soberFactor = 0; - else - soberFactor = 1-time_diff/(15.0f*MINUTE); - uint16 newDrunkenValue = uint16(soberFactor*(GetUInt32Value(PLAYER_BYTES_3) & 0xFFFE)); - SetDrunkValue(newDrunkenValue); + uint8 newDrunkValue = 0; + if (time_diff < GetDrunkValue() * 9) + newDrunkValue = GetDrunkValue() - time_diff / 9; + + SetDrunkValue(newDrunkValue); m_cinematic = fields[18].GetUInt8(); m_Played_time[PLAYED_TIME_TOTAL]= fields[19].GetUInt32(); @@ -18658,7 +18656,7 @@ void Player::SaveToDB(bool create /*=false*/) stmt->setUInt32(index++, GetUInt32Value(PLAYER_CHOSEN_TITLE)); stmt->setUInt64(index++, GetUInt64Value(PLAYER_FIELD_KNOWN_CURRENCIES)); stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX)); - stmt->setUInt16(index++, (uint16)(GetUInt32Value(PLAYER_BYTES_3) & 0xFFFE)); + stmt->setUInt8(index++, GetDrunkValue()); stmt->setUInt32(index++, GetHealth()); for (uint32 i = 0; i < MAX_POWERS; ++i) @@ -18769,7 +18767,7 @@ void Player::SaveToDB(bool create /*=false*/) stmt->setUInt32(index++, GetUInt32Value(PLAYER_CHOSEN_TITLE)); stmt->setUInt64(index++, GetUInt64Value(PLAYER_FIELD_KNOWN_CURRENCIES)); stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX)); - stmt->setUInt16(index++, (uint16)(GetUInt32Value(PLAYER_BYTES_3) & 0xFFFE)); + stmt->setUInt8(index++, GetDrunkValue()); stmt->setUInt32(index++, GetHealth()); for (uint32 i = 0; i < MAX_POWERS; ++i) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 774e75104b1..413d7fae32c 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2050,9 +2050,9 @@ class Player : public Unit, public GridObject inline SpellCooldowns GetSpellCooldowns() const { return m_spellCooldowns; } - void SetDrunkValue(uint16 newDrunkValue, uint32 itemid=0); - uint16 GetDrunkValue() const { return m_drunk; } - static DrunkenState GetDrunkenstateByValue(uint16 value); + void SetDrunkValue(uint8 newDrunkValue, uint32 itemId = 0); + uint8 GetDrunkValue() const { return GetByteValue(PLAYER_BYTES_3, 1); } + static DrunkenState GetDrunkenstateByValue(uint8 value); uint32 GetDeathTimer() const { return m_deathTimer; } uint32 GetCorpseReclaimDelay(bool pvp) const; @@ -2720,7 +2720,6 @@ class Player : public Unit, public GridObject time_t m_lastDailyQuestTime; uint32 m_drunkTimer; - uint16 m_drunk; uint32 m_weaponChangeTimer; uint32 m_zoneUpdateId; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 484d03f1504..d30f6e593dd 100755 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -4772,16 +4772,18 @@ void Spell::EffectInebriate(SpellEffIndex /*effIndex*/) if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - Player* player = (Player*)unitTarget; - uint16 currentDrunk = player->GetDrunkValue(); - uint16 drunkMod = damage * 256; - if (currentDrunk + drunkMod > 0xFFFF) + Player* player = unitTarget->ToPlayer(); + uint8 currentDrunk = player->GetDrunkValue(); + uint8 drunkMod = damage; + if (currentDrunk + drunkMod > 100) { - currentDrunk = 0xFFFF; - player->CastSpell(player, 67468, false); + currentDrunk = 100; + if (rand_chance() < 25.0f) + player->CastSpell(player, 67468, false); // Drunken Vomit } else currentDrunk += drunkMod; + player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0); } diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index 1747b80efd5..a88c765c596 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -1130,20 +1130,15 @@ public: static bool HandleModifyDrunkCommand(ChatHandler* handler, const char* args) { - if (!*args) return false; + if (!*args) + return false; - uint32 drunklevel = (uint32)atoi(args); + uint8 drunklevel = (uint8)atoi(args); if (drunklevel > 100) drunklevel = 100; - uint16 drunkMod = drunklevel * 0xFFFF / 100; - - Player* target = handler->getSelectedPlayer(); - if (!target) - target = handler->GetSession()->GetPlayer(); - - if (target) - target->SetDrunkValue(drunkMod); + if (Player* target = handler->getSelectedPlayer()) + target->SetDrunkValue(drunklevel); return true; } -- cgit v1.2.3 From ca2bc35713895adebbae30e1b371d9ff2d970bff Mon Sep 17 00:00:00 2001 From: Nay Date: Wed, 15 Aug 2012 21:30:55 +0100 Subject: Misc: CRLF to LF, whitespace cleanup and tabs to spaces --- doc/LoggingHOWTO.txt | 82 +- src/server/scripts/Commands/cs_disable.cpp | 14 +- src/server/scripts/Commands/cs_misc.cpp | 5758 ++++++++++++++-------------- src/server/shared/Logging/AppenderDB.cpp | 2 +- src/server/shared/Logging/Log.cpp | 2 +- 5 files changed, 2929 insertions(+), 2929 deletions(-) (limited to 'src/server/scripts/Commands') diff --git a/doc/LoggingHOWTO.txt b/doc/LoggingHOWTO.txt index 12850eb06cf..4e61812d7d8 100644 --- a/doc/LoggingHOWTO.txt +++ b/doc/LoggingHOWTO.txt @@ -23,7 +23,7 @@ For example, sLog->outInfo(...) is a logging request of level INFO. A logging request is said to be enabled if its level is higher than or equal to the level of its logger. Otherwise, the request is said to be disabled. A logger -without an assigned level will inherit one from the hierarchy +without an assigned level will inherit one from the hierarchy Example Logger Name Assigned Level Inherited Level @@ -72,16 +72,16 @@ Its a list of elements separated by comma where each element has its own meaning 4 - (Warn) 5 - (Error) 6 - (Fatal) - Flags: Define some extra modifications to do to logging message + Flags: Define some extra modifications to do to logging message 1 - Prefix Timestamp to the text 2 - Prefix Log Level to the text 4 - Prefix Log Filter type to the text 8 - Append timestamp to the log file name. Format: YYYY-MM-DD_HH-MM-SS - (Only used with Type = 2) + (Only used with Type = 2) 16 - Make a backup of existing file before overwrite - (Only used with Mode = w) + (Only used with Mode = w) -Depending on the type, elements optional1 and optional2 will take different +Depending on the type, elements optional1 and optional2 will take different Colors (read as optional1 if Type = Console) Format: "fatal error warn info debug trace" @@ -111,22 +111,22 @@ Depending on the type, elements optional1 and optional2 will take different Example: Appender.Console1=1,2,6 - - Creates new appender to log to console any message with log level DEBUG - or higher and prefixes log type and level to the message. - - Appender.Console2=1,5,1,13 11 9 5 3 1 - - Creates new appender to log to console any message with log level ERROR - or higher and prefixes timestamp to the message using colored text. - - Appender.File=2,2,7,Auth.log,w - - Creates new appender to log to file "Auth.log" any message with log level - DEBUG or higher and prefixes timestamp, type and level to message - + + Creates new appender to log to console any message with log level DEBUG + or higher and prefixes log type and level to the message. + + Appender.Console2=1,5,1,13 11 9 5 3 1 + + Creates new appender to log to console any message with log level ERROR + or higher and prefixes timestamp to the message using colored text. + + Appender.File=2,2,7,Auth.log,w + + Creates new appender to log to file "Auth.log" any message with log level + DEBUG or higher and prefixes timestamp, type and level to message + In the example, having two different loggers to log to console is perfectly -legal but redundant. +legal but redundant. Once we have the list of loggers to read, system will try to configure a new logger from its config line. Logger config line follows the format: @@ -188,7 +188,7 @@ Its a list of elements separated by comma where each element has its own meaning 6 - (Fatal) AppenderList: List of appenders linked to logger (Using spaces as separator). - + --- EXAMPLES --- EXAMPLE 1 @@ -198,23 +198,23 @@ logs for this server run. File should prefix timestamp, type and log level to the messages. Console should prefix type and log level. Appenders=Console Server - Loggers=Root + Loggers=Root Appender.Console=1,5,6 Appender.Server=2,5,7,Server.log,w Logger.Root=0,5,Console Server Lets trace how system will log two different messages: 1) sLog->outError(LOG_FILTER_GUILD, "Guild 1 created"); - System will try to find logger of type GUILD, as no logger is configured - for GUILD it will use Root logger. As message Log Level is equal or higher - than the Log level of logger the message is sent to the Appenders - configured in the Logger. "Console" and "Server". - Console will write: "ERROR [GUILD ] Guild 1 created" - Server will write to file "2012-08-15 ERROR [GUILD ] Guild 1 created" - + System will try to find logger of type GUILD, as no logger is configured + for GUILD it will use Root logger. As message Log Level is equal or higher + than the Log level of logger the message is sent to the Appenders + configured in the Logger. "Console" and "Server". + Console will write: "ERROR [GUILD ] Guild 1 created" + Server will write to file "2012-08-15 ERROR [GUILD ] Guild 1 created" + 2) sLog->outInfo(LOG_FILTER_CHARACTER, "Player Name Logged in"); - System will try to find logger of type CHARACTER, as no logger is - configured for CHARACTER it will use Root logger. As message Log Level is + System will try to find logger of type CHARACTER, as no logger is + configured for CHARACTER it will use Root logger. As message Log Level is not equal or higher than the Log level of logger the message its discarted. EXAMPLE 2 @@ -223,23 +223,23 @@ Same example that above, but now i want to see all messages of level INFO on file and server file should add timestamp on creation. Appenders=Console Server - Loggers=Root + Loggers=Root Appender.Console=1,5,6 Appender.Server=2,4,15,Server.log Logger.Root=0,4,Console Server Lets trace how system will log two different messages: 1) sLog->outError(LOG_FILTER_GUILD, "Guild 1 created"); - Performs exactly as example 1. + Performs exactly as example 1. 2) sLog->outInfo(LOG_FILTER_CHARACTER, "Player Name Logged in"); - System will try to find logger of type CHARACTER, as no logger is - configured for CHARACTER it will use Root logger. As message Log Level is + System will try to find logger of type CHARACTER, as no logger is + configured for CHARACTER it will use Root logger. As message Log Level is equal or higher than the Log level of logger the message is sent to the - Appenders configured in the Logger. "Console" and "Server". + Appenders configured in the Logger. "Console" and "Server". Console will discard msg as Log Level is not higher or equal to this - appender - Server will write to file - "2012-08-15 INFO [CHARACTER ] Guild 1 Player Name Logged in" + appender + Server will write to file + "2012-08-15 INFO [CHARACTER ] Guild 1 Player Name Logged in" EXAMPLE 3 As a dev, i may be interested in logging just a particular part of the core @@ -249,11 +249,11 @@ so i want SQLDEV to be logged to file without prefixes. All other messages should only be logged to console, GUILD to TRACE and CHARACTER to INFO Appenders=Console SQLDev - Loggers=Guild Characters SQLDev + Loggers=Guild Characters SQLDev Appender.Console=1,1 Appender.SQLDev=2,2,0,SQLDev.log Logger.Guild=24,1,Console - Logger.Characters=34,3,Console + Logger.Characters=34,3,Console Logger.SQLDev=37,3,SQLDev With this config, any message logger with a Log type different to GUILD, diff --git a/src/server/scripts/Commands/cs_disable.cpp b/src/server/scripts/Commands/cs_disable.cpp index a2a80edd43b..0bb376b08dd 100644 --- a/src/server/scripts/Commands/cs_disable.cpp +++ b/src/server/scripts/Commands/cs_disable.cpp @@ -62,7 +62,7 @@ public: { "add", SEC_ADMINISTRATOR, true, NULL, "", addDisableCommandTable }, { "remove", SEC_ADMINISTRATOR, true, NULL, "", removeDisableCommandTable }, { NULL, 0, false, NULL, "", NULL } - }; + }; static ChatCommand commandTable[] = { { "disable", SEC_ADMINISTRATOR, false, NULL, "", disableCommandTable }, @@ -88,7 +88,7 @@ public: uint32 entry = uint32(atoi(entryStr)); std::string disableTypeStr = ""; - + switch (disableType) { case DISABLE_TYPE_SPELL: @@ -171,12 +171,12 @@ public: default: break; } - + PreparedStatement* stmt = NULL; stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_DISABLES); stmt->setUInt32(0, entry); - stmt->setUInt8(1, disableType); - PreparedQueryResult result = WorldDatabase.Query(stmt); + stmt->setUInt8(1, disableType); + PreparedQueryResult result = WorldDatabase.Query(stmt); if (result) { handler->PSendSysMessage("This %s (Id: %u) is already disabled.", disableTypeStr.c_str(), entry); @@ -290,8 +290,8 @@ public: PreparedStatement* stmt = NULL; stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_DISABLES); stmt->setUInt32(0, entry); - stmt->setUInt8(1, disableType); - PreparedQueryResult result = WorldDatabase.Query(stmt); + stmt->setUInt8(1, disableType); + PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { handler->PSendSysMessage("This %s (Id: %u) is not disabled.", disableTypeStr.c_str(), entry); diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 80847d7dec4..1edaaf5bcbf 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1,2879 +1,2879 @@ -/* - * Copyright (C) 2008-2012 TrinityCore - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#include "Chat.h" -#include "ScriptMgr.h" -#include "AccountMgr.h" -#include "ArenaTeamMgr.h" -#include "CellImpl.h" -#include "GridNotifiers.h" -#include "Group.h" -#include "InstanceSaveMgr.h" -#include "MovementGenerator.h" -#include "ObjectAccessor.h" -#include "SpellAuras.h" -#include "TargetedMovementGenerator.h" -#include "WeatherMgr.h" -#include "ace/INET_Addr.h" - -class misc_commandscript : public CommandScript -{ -public: - misc_commandscript() : CommandScript("misc_commandscript") { } - - ChatCommand* GetCommands() const - { - static ChatCommand groupCommandTable[] = - { - { "leader", SEC_ADMINISTRATOR, false, &HandleGroupLeaderCommand, "", NULL }, - { "disband", SEC_ADMINISTRATOR, false, &HandleGroupDisbandCommand, "", NULL }, - { "remove", SEC_ADMINISTRATOR, false, &HandleGroupRemoveCommand, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - static ChatCommand petCommandTable[] = - { - { "create", SEC_GAMEMASTER, false, &HandleCreatePetCommand, "", NULL }, - { "learn", SEC_GAMEMASTER, false, &HandlePetLearnCommand, "", NULL }, - { "unlearn", SEC_GAMEMASTER, false, &HandlePetUnlearnCommand, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - static ChatCommand sendCommandTable[] = - { - { "items", SEC_ADMINISTRATOR, true, &HandleSendItemsCommand, "", NULL }, - { "mail", SEC_MODERATOR, true, &HandleSendMailCommand, "", NULL }, - { "message", SEC_ADMINISTRATOR, true, &HandleSendMessageCommand, "", NULL }, - { "money", SEC_ADMINISTRATOR, true, &HandleSendMoneyCommand, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - static ChatCommand commandTable[] = - { - { "dev", SEC_ADMINISTRATOR, false, &HandleDevCommand, "", NULL }, - { "gps", SEC_ADMINISTRATOR, false, &HandleGPSCommand, "", NULL }, - { "aura", SEC_ADMINISTRATOR, false, &HandleAuraCommand, "", NULL }, - { "unaura", SEC_ADMINISTRATOR, false, &HandleUnAuraCommand, "", NULL }, - { "appear", SEC_MODERATOR, false, &HandleAppearCommand, "", NULL }, - { "summon", SEC_MODERATOR, false, &HandleSummonCommand, "", NULL }, - { "groupsummon", SEC_MODERATOR, false, &HandleGroupSummonCommand, "", NULL }, - { "commands", SEC_PLAYER, true, &HandleCommandsCommand, "", NULL }, - { "die", SEC_ADMINISTRATOR, false, &HandleDieCommand, "", NULL }, - { "revive", SEC_ADMINISTRATOR, true, &HandleReviveCommand, "", NULL }, - { "dismount", SEC_PLAYER, false, &HandleDismountCommand, "", NULL }, - { "guid", SEC_GAMEMASTER, false, &HandleGUIDCommand, "", NULL }, - { "help", SEC_PLAYER, true, &HandleHelpCommand, "", NULL }, - { "itemmove", SEC_GAMEMASTER, false, &HandleItemMoveCommand, "", NULL }, - { "cooldown", SEC_ADMINISTRATOR, false, &HandleCooldownCommand, "", NULL }, - { "distance", SEC_ADMINISTRATOR, false, &HandleGetDistanceCommand, "", NULL }, - { "recall", SEC_MODERATOR, false, &HandleRecallCommand, "", NULL }, - { "save", SEC_PLAYER, false, &HandleSaveCommand, "", NULL }, - { "saveall", SEC_MODERATOR, true, &HandleSaveAllCommand, "", NULL }, - { "kick", SEC_GAMEMASTER, true, &HandleKickPlayerCommand, "", NULL }, - { "start", SEC_PLAYER, false, &HandleStartCommand, "", NULL }, - { "taxicheat", SEC_MODERATOR, false, &HandleTaxiCheatCommand, "", NULL }, - { "linkgrave", SEC_ADMINISTRATOR, false, &HandleLinkGraveCommand, "", NULL }, - { "neargrave", SEC_ADMINISTRATOR, false, &HandleNearGraveCommand, "", NULL }, - { "explorecheat", SEC_ADMINISTRATOR, false, &HandleExploreCheatCommand, "", NULL }, - { "showarea", SEC_ADMINISTRATOR, false, &HandleShowAreaCommand, "", NULL }, - { "hidearea", SEC_ADMINISTRATOR, false, &HandleHideAreaCommand, "", NULL }, - { "additem", SEC_ADMINISTRATOR, false, &HandleAddItemCommand, "", NULL }, - { "additemset", SEC_ADMINISTRATOR, false, &HandleAddItemSetCommand, "", NULL }, - { "bank", SEC_ADMINISTRATOR, false, &HandleBankCommand, "", NULL }, - { "wchange", SEC_ADMINISTRATOR, false, &HandleChangeWeather, "", NULL }, - { "maxskill", SEC_ADMINISTRATOR, false, &HandleMaxSkillCommand, "", NULL }, - { "setskill", SEC_ADMINISTRATOR, false, &HandleSetSkillCommand, "", NULL }, - { "pinfo", SEC_GAMEMASTER, true, &HandlePInfoCommand, "", NULL }, - { "respawn", SEC_ADMINISTRATOR, false, &HandleRespawnCommand, "", NULL }, - { "send", SEC_MODERATOR, true, NULL, "", sendCommandTable }, - { "pet", SEC_GAMEMASTER, false, NULL, "", petCommandTable }, - { "mute", SEC_MODERATOR, true, &HandleMuteCommand, "", NULL }, - { "unmute", SEC_MODERATOR, true, &HandleUnmuteCommand, "", NULL }, - { "movegens", SEC_ADMINISTRATOR, false, &HandleMovegensCommand, "", NULL }, - { "cometome", SEC_ADMINISTRATOR, false, &HandleComeToMeCommand, "", NULL }, - { "damage", SEC_ADMINISTRATOR, false, &HandleDamageCommand, "", NULL }, - { "combatstop", SEC_GAMEMASTER, true, &HandleCombatStopCommand, "", NULL }, - { "flusharenapoints", SEC_ADMINISTRATOR, false, &HandleFlushArenaPointsCommand, "", NULL }, - { "repairitems", SEC_GAMEMASTER, true, &HandleRepairitemsCommand, "", NULL }, - { "waterwalk", SEC_GAMEMASTER, false, &HandleWaterwalkCommand, "", NULL }, - { "freeze", SEC_MODERATOR, false, &HandleFreezeCommand, "", NULL }, - { "unfreeze", SEC_MODERATOR, false, &HandleUnFreezeCommand, "", NULL }, - { "listfreeze", SEC_MODERATOR, false, &HandleListFreezeCommand, "", NULL }, - { "group", SEC_ADMINISTRATOR, false, NULL, "", groupCommandTable }, - { "possess", SEC_ADMINISTRATOR, false, HandlePossessCommand, "", NULL }, - { "unpossess", SEC_ADMINISTRATOR, false, HandleUnPossessCommand, "", NULL }, - { "bindsight", SEC_ADMINISTRATOR, false, HandleBindSightCommand, "", NULL }, - { "unbindsight", SEC_ADMINISTRATOR, false, HandleUnbindSightCommand, "", NULL }, - { "playall", SEC_GAMEMASTER, false, HandlePlayAllCommand, "", NULL }, - { NULL, 0, false, NULL, "", NULL } - }; - return commandTable; - } - - static bool HandleDevCommand(ChatHandler* handler, char const* args) - { - if (!*args) - { - if (handler->GetSession()->GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER)) - handler->GetSession()->SendNotification(LANG_DEV_ON); - else - handler->GetSession()->SendNotification(LANG_DEV_OFF); - return true; - } - - std::string argstr = (char*)args; - - if (argstr == "on") - { - handler->GetSession()->GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER); - handler->GetSession()->SendNotification(LANG_DEV_ON); - return true; - } - - if (argstr == "off") - { - handler->GetSession()->GetPlayer()->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER); - handler->GetSession()->SendNotification(LANG_DEV_OFF); - return true; - } - - handler->SendSysMessage(LANG_USE_BOL); - handler->SetSentErrorMessage(true); - return false; - } - - static bool HandleGPSCommand(ChatHandler* handler, char const* args) - { - WorldObject* object = NULL; - if (*args) - { - uint64 guid = handler->extractGuidFromLink((char*)args); - if (guid) - object = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*handler->GetSession()->GetPlayer(), guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT); - - if (!object) - { - handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); - handler->SetSentErrorMessage(true); - return false; - } - } - else - { - object = handler->getSelectedUnit(); - - if (!object) - { - handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - } - - CellCoord cellCoord = Trinity::ComputeCellCoord(object->GetPositionX(), object->GetPositionY()); - Cell cell(cellCoord); - - uint32 zoneId, areaId; - object->GetZoneAndAreaId(zoneId, areaId); - - MapEntry const* mapEntry = sMapStore.LookupEntry(object->GetMapId()); - AreaTableEntry const* zoneEntry = GetAreaEntryByAreaID(zoneId); - AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaId); - - float zoneX = object->GetPositionX(); - float zoneY = object->GetPositionY(); - - Map2ZoneCoordinates(zoneX, zoneY, zoneId); - - Map const* map = object->GetMap(); - float groundZ = map->GetHeight(object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), MAX_HEIGHT); - float floorZ = map->GetHeight(object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ()); - - GridCoord gridCoord = Trinity::ComputeGridCoord(object->GetPositionX(), object->GetPositionY()); - - // 63? WHY? - int gridX = 63 - gridCoord.x_coord; - int gridY = 63 - gridCoord.y_coord; - - uint32 haveMap = Map::ExistMap(object->GetMapId(), gridX, gridY) ? 1 : 0; - uint32 haveVMap = Map::ExistVMap(object->GetMapId(), gridX, gridY) ? 1 : 0; - - if (haveVMap) - { - if (map->IsOutdoors(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ())) - handler->PSendSysMessage("You are outdoors"); - else - handler->PSendSysMessage("You are indoors"); - } - else - handler->PSendSysMessage("no VMAP available for area info"); - - handler->PSendSysMessage(LANG_MAP_POSITION, - object->GetMapId(), (mapEntry ? mapEntry->name[handler->GetSessionDbcLocale()] : ""), - zoneId, (zoneEntry ? zoneEntry->area_name[handler->GetSessionDbcLocale()] : ""), - areaId, (areaEntry ? areaEntry->area_name[handler->GetSessionDbcLocale()] : ""), - object->GetPhaseMask(), - object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation(), - cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(), - zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap); - - LiquidData liquidStatus; - ZLiquidStatus status = map->getLiquidStatus(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus); - - if (status) - handler->PSendSysMessage(LANG_LIQUID_STATUS, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status); - - return true; - } - - static bool HandleAuraCommand(ChatHandler* handler, char const* args) - { - Unit* target = handler->getSelectedUnit(); - if (!target) - { - handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spellId = handler->extractSpellIdFromLink((char*)args); - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId)) - Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, target, target); - - return true; - } - - static bool HandleUnAuraCommand(ChatHandler* handler, char const* args) - { - Unit* target = handler->getSelectedUnit(); - if (!target) - { - handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - - std::string argstr = args; - if (argstr == "all") - { - target->RemoveAllAuras(); - return true; - } - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spellId = handler->extractSpellIdFromLink((char*)args); - if (!spellId) - return false; - - target->RemoveAurasDueToSpell(spellId); - - return true; - } - // Teleport to Player - static bool HandleAppearCommand(ChatHandler* handler, char const* args) - { - Player* target; - uint64 targetGuid; - std::string targetName; - if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) - return false; - - Player* _player = handler->GetSession()->GetPlayer(); - if (target == _player || targetGuid == _player->GetGUID()) - { - handler->SendSysMessage(LANG_CANT_TELEPORT_SELF); - handler->SetSentErrorMessage(true); - return false; - } - - if (target) - { - // check online security - if (handler->HasLowerSecurity(target, 0)) - return false; - - std::string chrNameLink = handler->playerLink(targetName); - - Map* map = target->GetMap(); - if (map->IsBattlegroundOrArena()) - { - // only allow if gm mode is on - if (!_player->isGameMaster()) - { - handler->PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM, chrNameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - // if both players are in different bgs - else if (_player->GetBattlegroundId() && _player->GetBattlegroundId() != target->GetBattlegroundId()) - _player->LeaveBattleground(false); // Note: should be changed so _player gets no Deserter debuff - - // all's well, set bg id - // when porting out from the bg, it will be reset to 0 - _player->SetBattlegroundId(target->GetBattlegroundId(), target->GetBattlegroundTypeId()); - // remember current position as entry point for return at bg end teleportation - if (!_player->GetMap()->IsBattlegroundOrArena()) - _player->SetBattlegroundEntryPoint(); - } - else if (map->IsDungeon()) - { - // we have to go to instance, and can go to player only if: - // 1) we are in his group (either as leader or as member) - // 2) we are not bound to any group and have GM mode on - if (_player->GetGroup()) - { - // we are in group, we can go only if we are in the player group - if (_player->GetGroup() != target->GetGroup()) - { - handler->PSendSysMessage(LANG_CANNOT_GO_TO_INST_PARTY, chrNameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - } - else - { - // we are not in group, let's verify our GM mode - if (!_player->isGameMaster()) - { - handler->PSendSysMessage(LANG_CANNOT_GO_TO_INST_GM, chrNameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - } - - // if the player or the player's group is bound to another instance - // the player will not be bound to another one - InstancePlayerBind* bind = _player->GetBoundInstance(target->GetMapId(), target->GetDifficulty(map->IsRaid())); - if (!bind) - { - Group* group = _player->GetGroup(); - // if no bind exists, create a solo bind - InstanceGroupBind* gBind = group ? group->GetBoundInstance(target) : NULL; // if no bind exists, create a solo bind - if (!gBind) - if (InstanceSave* save = sInstanceSaveMgr->GetInstanceSave(target->GetInstanceId())) - _player->BindToInstance(save, !save->CanReset()); - } - - if (map->IsRaid()) - _player->SetRaidDifficulty(target->GetRaidDifficulty()); - else - _player->SetDungeonDifficulty(target->GetDungeonDifficulty()); - } - - handler->PSendSysMessage(LANG_APPEARING_AT, chrNameLink.c_str()); - - // stop flight if need - if (_player->isInFlight()) - { - _player->GetMotionMaster()->MovementExpired(); - _player->CleanupAfterTaxiFlight(); - } - // save only in non-flight case - else - _player->SaveRecallPosition(); - - // to point to see at target with same orientation - float x, y, z; - target->GetContactPoint(_player, x, y, z); - - _player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE); - _player->SetPhaseMask(target->GetPhaseMask(), true); - } - else - { - // check offline security - if (handler->HasLowerSecurity(NULL, targetGuid)) - return false; - - std::string nameLink = handler->playerLink(targetName); - - handler->PSendSysMessage(LANG_APPEARING_AT, nameLink.c_str()); - - // to point where player stay (if loaded) - float x, y, z, o; - uint32 map; - bool in_flight; - if (!Player::LoadPositionFromDB(map, x, y, z, o, in_flight, targetGuid)) - return false; - - // stop flight if need - if (_player->isInFlight()) - { - _player->GetMotionMaster()->MovementExpired(); - _player->CleanupAfterTaxiFlight(); - } - // save only in non-flight case - else - _player->SaveRecallPosition(); - - _player->TeleportTo(map, x, y, z, _player->GetOrientation()); - } - - return true; - } - // Summon Player - static bool HandleSummonCommand(ChatHandler* handler, char const* args) - { - Player* target; - uint64 targetGuid; - std::string targetName; - if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) - return false; - - Player* _player = handler->GetSession()->GetPlayer(); - if (target == _player || targetGuid == _player->GetGUID()) - { - handler->PSendSysMessage(LANG_CANT_TELEPORT_SELF); - handler->SetSentErrorMessage(true); - return false; - } - - if (target) - { - std::string nameLink = handler->playerLink(targetName); - // check online security - if (handler->HasLowerSecurity(target, 0)) - return false; - - if (target->IsBeingTeleported()) - { - handler->PSendSysMessage(LANG_IS_TELEPORTED, nameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - - Map* map = handler->GetSession()->GetPlayer()->GetMap(); - - if (map->IsBattlegroundOrArena()) - { - // only allow if gm mode is on - if (!_player->isGameMaster()) - { - handler->PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM, nameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - // if both players are in different bgs - else if (target->GetBattlegroundId() && handler->GetSession()->GetPlayer()->GetBattlegroundId() != target->GetBattlegroundId()) - target->LeaveBattleground(false); // Note: should be changed so target gets no Deserter debuff - - // all's well, set bg id - // when porting out from the bg, it will be reset to 0 - target->SetBattlegroundId(handler->GetSession()->GetPlayer()->GetBattlegroundId(), handler->GetSession()->GetPlayer()->GetBattlegroundTypeId()); - // remember current position as entry point for return at bg end teleportation - if (!target->GetMap()->IsBattlegroundOrArena()) - target->SetBattlegroundEntryPoint(); - } - else if (map->IsDungeon()) - { - Map* map = target->GetMap(); - - if (map->Instanceable() && map->GetInstanceId() != map->GetInstanceId()) - target->UnbindInstance(map->GetInstanceId(), target->GetDungeonDifficulty(), true); - - // we are in instance, and can summon only player in our group with us as lead - if (!handler->GetSession()->GetPlayer()->GetGroup() || !target->GetGroup() || - (target->GetGroup()->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()) || - (handler->GetSession()->GetPlayer()->GetGroup()->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID())) - // the last check is a bit excessive, but let it be, just in case - { - handler->PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST, nameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - } - - handler->PSendSysMessage(LANG_SUMMONING, nameLink.c_str(), ""); - if (handler->needReportToTarget(target)) - ChatHandler(target).PSendSysMessage(LANG_SUMMONED_BY, handler->playerLink(_player->GetName()).c_str()); - - // stop flight if need - if (target->isInFlight()) - { - target->GetMotionMaster()->MovementExpired(); - target->CleanupAfterTaxiFlight(); - } - // save only in non-flight case - else - target->SaveRecallPosition(); - - // before GM - float x, y, z; - handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, target->GetObjectSize()); - target->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, target->GetOrientation()); - target->SetPhaseMask(handler->GetSession()->GetPlayer()->GetPhaseMask(), true); - } - else - { - // check offline security - if (handler->HasLowerSecurity(NULL, targetGuid)) - return false; - - std::string nameLink = handler->playerLink(targetName); - - handler->PSendSysMessage(LANG_SUMMONING, nameLink.c_str(), handler->GetTrinityString(LANG_OFFLINE)); - - // in point where GM stay - Player::SavePositionInDB(handler->GetSession()->GetPlayer()->GetMapId(), - handler->GetSession()->GetPlayer()->GetPositionX(), - handler->GetSession()->GetPlayer()->GetPositionY(), - handler->GetSession()->GetPlayer()->GetPositionZ(), - handler->GetSession()->GetPlayer()->GetOrientation(), - handler->GetSession()->GetPlayer()->GetZoneId(), - targetGuid); - } - - return true; - } - // Summon group of player - static bool HandleGroupSummonCommand(ChatHandler* handler, char const* args) - { - Player* target; - if (!handler->extractPlayerTarget((char*)args, &target)) - return false; - - // check online security - if (handler->HasLowerSecurity(target, 0)) - return false; - - Group* group = target->GetGroup(); - - std::string nameLink = handler->GetNameLink(target); - - if (!group) - { - handler->PSendSysMessage(LANG_NOT_IN_GROUP, nameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - - Map* gmMap = handler->GetSession()->GetPlayer()->GetMap(); - bool toInstance = gmMap->Instanceable(); - - // we are in instance, and can summon only player in our group with us as lead - if (toInstance && ( - !handler->GetSession()->GetPlayer()->GetGroup() || (group->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()) || - (handler->GetSession()->GetPlayer()->GetGroup()->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()))) - // the last check is a bit excessive, but let it be, just in case - { - handler->SendSysMessage(LANG_CANNOT_SUMMON_TO_INST); - handler->SetSentErrorMessage(true); - return false; - } - - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) - { - Player* player = itr->getSource(); - - if (!player || player == handler->GetSession()->GetPlayer() || !player->GetSession()) - continue; - - // check online security - if (handler->HasLowerSecurity(player, 0)) - return false; - - std::string plNameLink = handler->GetNameLink(player); - - if (player->IsBeingTeleported() == true) - { - handler->PSendSysMessage(LANG_IS_TELEPORTED, plNameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - - if (toInstance) - { - Map* playerMap = player->GetMap(); - - if (playerMap->Instanceable() && playerMap->GetInstanceId() != gmMap->GetInstanceId()) - { - // cannot summon from instance to instance - handler->PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST, plNameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - } - - handler->PSendSysMessage(LANG_SUMMONING, plNameLink.c_str(), ""); - if (handler->needReportToTarget(player)) - ChatHandler(player).PSendSysMessage(LANG_SUMMONED_BY, handler->GetNameLink().c_str()); - - // stop flight if need - if (player->isInFlight()) - { - player->GetMotionMaster()->MovementExpired(); - player->CleanupAfterTaxiFlight(); - } - // save only in non-flight case - else - player->SaveRecallPosition(); - - // before GM - float x, y, z; - handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, player->GetObjectSize()); - player->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, player->GetOrientation()); - } - - return true; - } - - static bool HandleCommandsCommand(ChatHandler* handler, char const* /*args*/) - { - handler->ShowHelpForCommand(handler->getCommandTable(), ""); - return true; - } - - static bool HandleDieCommand(ChatHandler* handler, char const* /*args*/) - { - Unit* target = handler->getSelectedUnit(); - - if (!target || !handler->GetSession()->GetPlayer()->GetSelection()) - { - handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - - if (target->GetTypeId() == TYPEID_PLAYER) - { - if (handler->HasLowerSecurity((Player*)target, 0, false)) - return false; - } - - if (target->isAlive()) - { - if (sWorld->getBoolConfig(CONFIG_DIE_COMMAND_MODE)) - handler->GetSession()->GetPlayer()->Kill(target); - else - handler->GetSession()->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - } - - return true; - } - - static bool HandleReviveCommand(ChatHandler* handler, char const* args) - { - Player* target; - uint64 targetGuid; - if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid)) - return false; - - if (target) - { - target->ResurrectPlayer(!AccountMgr::IsPlayerAccount(target->GetSession()->GetSecurity()) ? 1.0f : 0.5f); - target->SpawnCorpseBones(); - target->SaveToDB(); - } - else - // will resurrected at login without corpse - sObjectAccessor->ConvertCorpseForPlayer(targetGuid); - - return true; - } - - static bool HandleDismountCommand(ChatHandler* handler, char const* /*args*/) - { - Player* player = handler->GetSession()->GetPlayer(); - - // If player is not mounted, so go out :) - if (!player->IsMounted()) - { - handler->SendSysMessage(LANG_CHAR_NON_MOUNTED); - handler->SetSentErrorMessage(true); - return false; - } - - if (player->isInFlight()) - { - handler->SendSysMessage(LANG_YOU_IN_FLIGHT); - handler->SetSentErrorMessage(true); - return false; - } - - player->Dismount(); - player->RemoveAurasByType(SPELL_AURA_MOUNTED); - return true; - } - - static bool HandleGUIDCommand(ChatHandler* handler, char const* /*args*/) - { - uint64 guid = handler->GetSession()->GetPlayer()->GetSelection(); - - if (guid == 0) - { - handler->SendSysMessage(LANG_NO_SELECTION); - handler->SetSentErrorMessage(true); - return false; - } - - handler->PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid)); - return true; - } - - static bool HandleHelpCommand(ChatHandler* handler, char const* args) - { - char const* cmd = strtok((char*)args, " "); - if (!cmd) - { - handler->ShowHelpForCommand(handler->getCommandTable(), "help"); - handler->ShowHelpForCommand(handler->getCommandTable(), ""); - } - else - { - if (!handler->ShowHelpForCommand(handler->getCommandTable(), cmd)) - handler->SendSysMessage(LANG_NO_HELP_CMD); - } - - return true; - } - // move item to other slot - static bool HandleItemMoveCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - char const* param1 = strtok((char*)args, " "); - if (!param1) - return false; - - char const* param2 = strtok(NULL, " "); - if (!param2) - return false; - - uint8 srcSlot = uint8(atoi(param1)); - uint8 dstSlot = uint8(atoi(param2)); - - if (srcSlot == dstSlot) - return true; - - if (!handler->GetSession()->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0, srcSlot, true)) - return false; - - if (!handler->GetSession()->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0, dstSlot, false)) - return false; - - uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcSlot); - uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstSlot); - - handler->GetSession()->GetPlayer()->SwapItem(src, dst); - - return true; - } - - static bool HandleCooldownCommand(ChatHandler* handler, char const* args) - { - Player* target = handler->getSelectedPlayer(); - if (!target) - { - handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); - handler->SetSentErrorMessage(true); - return false; - } - - std::string nameLink = handler->GetNameLink(target); - - if (!*args) - { - target->RemoveAllSpellCooldown(); - handler->PSendSysMessage(LANG_REMOVEALL_COOLDOWN, nameLink.c_str()); - } - else - { - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spellIid = handler->extractSpellIdFromLink((char*)args); - if (!spellIid) - return false; - - if (!sSpellMgr->GetSpellInfo(spellIid)) - { - handler->PSendSysMessage(LANG_UNKNOWN_SPELL, target == handler->GetSession()->GetPlayer() ? handler->GetTrinityString(LANG_YOU) : nameLink.c_str()); - handler->SetSentErrorMessage(true); - return false; - } - - target->RemoveSpellCooldown(spellIid, true); - handler->PSendSysMessage(LANG_REMOVE_COOLDOWN, spellIid, target == handler->GetSession()->GetPlayer() ? handler->GetTrinityString(LANG_YOU) : nameLink.c_str()); - } - return true; - } - - static bool HandleGetDistanceCommand(ChatHandler* handler, char const* args) - { - WorldObject* obj = NULL; - - if (*args) - { - uint64 guid = handler->extractGuidFromLink((char*)args); - if (guid) - obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*handler->GetSession()->GetPlayer(), guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); - - if (!obj) - { - handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); - handler->SetSentErrorMessage(true); - return false; - } - } - else - { - obj = handler->getSelectedUnit(); - - if (!obj) - { - handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - } - - handler->PSendSysMessage(LANG_DISTANCE, handler->GetSession()->GetPlayer()->GetDistance(obj), handler->GetSession()->GetPlayer()->GetDistance2d(obj), handler->GetSession()->GetPlayer()->GetExactDist(obj), handler->GetSession()->GetPlayer()->GetExactDist2d(obj)); - return true; - } - // Teleport player to last position - static bool HandleRecallCommand(ChatHandler* handler, char const* args) - { - Player* target; - if (!handler->extractPlayerTarget((char*)args, &target)) - return false; - - // check online security - if (handler->HasLowerSecurity(target, 0)) - return false; - - if (target->IsBeingTeleported()) - { - handler->PSendSysMessage(LANG_IS_TELEPORTED, handler->GetNameLink(target).c_str()); - handler->SetSentErrorMessage(true); - return false; - } - - // stop flight if need - if (target->isInFlight()) - { - target->GetMotionMaster()->MovementExpired(); - target->CleanupAfterTaxiFlight(); - } - - target->TeleportTo(target->m_recallMap, target->m_recallX, target->m_recallY, target->m_recallZ, target->m_recallO); - return true; - } - - static bool HandleSaveCommand(ChatHandler* handler, char const* /*args*/) - { - Player* player = handler->GetSession()->GetPlayer(); - - // save GM account without delay and output message - if (!AccountMgr::IsPlayerAccount(handler->GetSession()->GetSecurity())) - { - if (Player* target = handler->getSelectedPlayer()) - target->SaveToDB(); - else - player->SaveToDB(); - handler->SendSysMessage(LANG_PLAYER_SAVED); - return true; - } - - // save if the player has last been saved over 20 seconds ago - uint32 saveInterval = sWorld->getIntConfig(CONFIG_INTERVAL_SAVE); - if (saveInterval == 0 || (saveInterval > 20 * IN_MILLISECONDS && player->GetSaveTimer() <= saveInterval - 20 * IN_MILLISECONDS)) - player->SaveToDB(); - - return true; - } - - // Save all players in the world - static bool HandleSaveAllCommand(ChatHandler* handler, char const* /*args*/) - { - sObjectAccessor->SaveAllPlayers(); - handler->SendSysMessage(LANG_PLAYERS_SAVED); - return true; - } - - // kick player - static bool HandleKickPlayerCommand(ChatHandler* handler, char const* args) - { - Player* target = NULL; - std::string playerName; - if (!handler->extractPlayerTarget((char*)args, &target, NULL, &playerName)) - return false; - - if (handler->GetSession() && target == handler->GetSession()->GetPlayer()) - { - handler->SendSysMessage(LANG_COMMAND_KICKSELF); - handler->SetSentErrorMessage(true); - return false; - } - - // check online security - if (handler->HasLowerSecurity(target, 0)) - return false; - - if (sWorld->getBoolConfig(CONFIG_SHOW_KICK_IN_WORLD)) - sWorld->SendWorldText(LANG_COMMAND_KICKMESSAGE, playerName.c_str()); - else - handler->PSendSysMessage(LANG_COMMAND_KICKMESSAGE, playerName.c_str()); - - target->GetSession()->KickPlayer(); - - return true; - } - - static bool HandleStartCommand(ChatHandler* handler, char const* /*args*/) - { - Player* player = handler->GetSession()->GetPlayer(); - - if (player->isInFlight()) - { - handler->SendSysMessage(LANG_YOU_IN_FLIGHT); - handler->SetSentErrorMessage(true); - return false; - } - - if (player->isInCombat()) - { - handler->SendSysMessage(LANG_YOU_IN_COMBAT); - handler->SetSentErrorMessage(true); - return false; - } - - if (player->isDead() || player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) - { - // if player is dead and stuck, send ghost to graveyard - player->RepopAtGraveyard(); - return true; - } - - // cast spell Stuck - player->CastSpell(player, 7355, false); - return true; - } - // Enable on\off all taxi paths - static bool HandleTaxiCheatCommand(ChatHandler* handler, char const* args) - { - if (!*args) - { - handler->SendSysMessage(LANG_USE_BOL); - handler->SetSentErrorMessage(true); - return false; - } - - std::string argStr = (char*)args; - - Player* chr = handler->getSelectedPlayer(); - - if (!chr) - chr = handler->GetSession()->GetPlayer(); - else if (handler->HasLowerSecurity(chr, 0)) // check online security - return false; - - if (argStr == "on") - { - chr->SetTaxiCheater(true); - handler->PSendSysMessage(LANG_YOU_GIVE_TAXIS, handler->GetNameLink(chr).c_str()); - if (handler->needReportToTarget(chr)) - ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_ADDED, handler->GetNameLink().c_str()); - return true; - } - - if (argStr == "off") - { - chr->SetTaxiCheater(false); - handler->PSendSysMessage(LANG_YOU_REMOVE_TAXIS, handler->GetNameLink(chr).c_str()); - if (handler->needReportToTarget(chr)) - ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_REMOVED, handler->GetNameLink().c_str()); - - return true; - } - - handler->SendSysMessage(LANG_USE_BOL); - handler->SetSentErrorMessage(true); - - return false; - } - - static bool HandleLinkGraveCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - char* px = strtok((char*)args, " "); - if (!px) - return false; - - uint32 graveyardId = uint32(atoi(px)); - - uint32 team; - - char* px2 = strtok(NULL, " "); - - if (!px2) - team = 0; - else if (strncmp(px2, "horde", 6) == 0) - team = HORDE; - else if (strncmp(px2, "alliance", 9) == 0) - team = ALLIANCE; - else - return false; - - WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(graveyardId); - - if (!graveyard) - { - handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, graveyardId); - handler->SetSentErrorMessage(true); - return false; - } - - Player* player = handler->GetSession()->GetPlayer(); - - uint32 zoneId = player->GetZoneId(); - - AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(zoneId); - if (!areaEntry || areaEntry->zone !=0) - { - handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, graveyardId, zoneId); - handler->SetSentErrorMessage(true); - return false; - } - - if (sObjectMgr->AddGraveYardLink(graveyardId, zoneId, team)) - handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, graveyardId, zoneId); - else - handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, graveyardId, zoneId); - - return true; - } - - static bool HandleNearGraveCommand(ChatHandler* handler, char const* args) - { - uint32 team; - - size_t argStr = strlen(args); - - if (!*args) - team = 0; - else if (strncmp((char*)args, "horde", argStr) == 0) - team = HORDE; - else if (strncmp((char*)args, "alliance", argStr) == 0) - team = ALLIANCE; - else - return false; - - Player* player = handler->GetSession()->GetPlayer(); - uint32 zone_id = player->GetZoneId(); - - WorldSafeLocsEntry const* graveyard = sObjectMgr->GetClosestGraveYard( - player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), team); - - if (graveyard) - { - uint32 graveyardId = graveyard->ID; - - GraveYardData const* data = sObjectMgr->FindGraveYardData(graveyardId, zone_id); - if (!data) - { - handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR, graveyardId); - handler->SetSentErrorMessage(true); - return false; - } - - team = data->team; - - std::string team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_NOTEAM); - - if (team == 0) - team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY); - else if (team == HORDE) - team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE); - else if (team == ALLIANCE) - team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE); - - handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, graveyardId, team_name.c_str(), zone_id); - } - else - { - std::string team_name; - - if (team == 0) - team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY); - else if (team == HORDE) - team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE); - else if (team == ALLIANCE) - team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE); - - if (team == ~uint32(0)) - handler->PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id); - else - handler->PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id, team_name.c_str()); - } - - return true; - } - - static bool HandleExploreCheatCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - int32 flag = int32(atoi((char*)args)); - - Player* playerTarget = handler->getSelectedPlayer(); - if (!playerTarget) - { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; - } - - if (flag != 0) - { - handler->PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, handler->GetNameLink(playerTarget).c_str()); - if (handler->needReportToTarget(playerTarget)) - ChatHandler(playerTarget).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL, handler->GetNameLink().c_str()); - } - else - { - handler->PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, handler->GetNameLink(playerTarget).c_str()); - if (handler->needReportToTarget(playerTarget)) - ChatHandler(playerTarget).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING, handler->GetNameLink().c_str()); - } - - for (uint8 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i) - { - if (flag != 0) - handler->GetSession()->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0xFFFFFFFF); - else - handler->GetSession()->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0); - } - - return true; - } - - static bool HandleShowAreaCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - Player* playerTarget = handler->getSelectedPlayer(); - if (!playerTarget) - { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; - } - - int32 area = GetAreaFlagByAreaID(atoi((char*)args)); - int32 offset = area / 32; - uint32 val = uint32((1 << (area % 32))); - - if (area<0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) - { - handler->SendSysMessage(LANG_BAD_VALUE); - handler->SetSentErrorMessage(true); - return false; - } - - uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); - playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields | val))); - - handler->SendSysMessage(LANG_EXPLORE_AREA); - return true; - } - - static bool HandleHideAreaCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - Player* playerTarget = handler->getSelectedPlayer(); - if (!playerTarget) - { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; - } - - int32 area = GetAreaFlagByAreaID(atoi((char*)args)); - int32 offset = area / 32; - uint32 val = uint32((1 << (area % 32))); - - if (area < 0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) - { - handler->SendSysMessage(LANG_BAD_VALUE); - handler->SetSentErrorMessage(true); - return false; - } - - uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); - playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields ^ val))); - - handler->SendSysMessage(LANG_UNEXPLORE_AREA); - return true; - } - - static bool HandleAddItemCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - uint32 itemId = 0; - - if (args[0] == '[') // [name] manual form - { - char const* itemNameStr = strtok((char*)args, "]"); - - if (itemNameStr && itemNameStr[0]) - { - std::string itemName = itemNameStr+1; - WorldDatabase.EscapeString(itemName); - - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_ITEM_TEMPLATE_BY_NAME); - stmt->setString(0, itemName); - PreparedQueryResult result = WorldDatabase.Query(stmt); - - if (!result) - { - handler->PSendSysMessage(LANG_COMMAND_COULDNOTFIND, itemNameStr+1); - handler->SetSentErrorMessage(true); - return false; - } - itemId = result->Fetch()->GetUInt32(); - } - else - return false; - } - else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r - { - char const* id = handler->extractKeyFromLink((char*)args, "Hitem"); - if (!id) - return false; - itemId = uint32(atol(id)); - } - - char const* ccount = strtok(NULL, " "); - - int32 count = 1; - - if (ccount) - count = strtol(ccount, NULL, 10); - - if (count == 0) - count = 1; - - Player* player = handler->GetSession()->GetPlayer(); - Player* playerTarget = handler->getSelectedPlayer(); - if (!playerTarget) - playerTarget = player; - - sLog->outDebug(LOG_FILTER_GENERAL, handler->GetTrinityString(LANG_ADDITEM), itemId, count); - - ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId); - if (!itemTemplate) - { - handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); - handler->SetSentErrorMessage(true); - return false; - } - - // Subtract - if (count < 0) - { - playerTarget->DestroyItemCount(itemId, -count, true, false); - handler->PSendSysMessage(LANG_REMOVEITEM, itemId, -count, handler->GetNameLink(playerTarget).c_str()); - return true; - } - - // Adding items - uint32 noSpaceForCount = 0; - - // check space and find places - ItemPosCountVec dest; - InventoryResult msg = playerTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount); - if (msg != EQUIP_ERR_OK) // convert to possible store amount - count -= noSpaceForCount; - - if (count == 0 || dest.empty()) // can't add any - { - handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); - handler->SetSentErrorMessage(true); - return false; - } - - Item* item = playerTarget->StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId)); - - // remove binding (let GM give it to another player later) - if (player == playerTarget) - for (ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr) - if (Item* item1 = player->GetItemByPos(itr->pos)) - item1->SetBinding(false); - - if (count > 0 && item) - { - player->SendNewItem(item, count, false, true); - if (player != playerTarget) - playerTarget->SendNewItem(item, count, true, false); - } - - if (noSpaceForCount > 0) - handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); - - return true; - } - - static bool HandleAddItemSetCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - char const* id = handler->extractKeyFromLink((char*)args, "Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r - if (!id) - return false; - - uint32 itemSetId = atol(id); - - // prevent generation all items with itemset field value '0' - if (itemSetId == 0) - { - handler->PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND, itemSetId); - handler->SetSentErrorMessage(true); - return false; - } - - Player* player = handler->GetSession()->GetPlayer(); - Player* playerTarget = handler->getSelectedPlayer(); - if (!playerTarget) - playerTarget = player; - - sLog->outDebug(LOG_FILTER_GENERAL, handler->GetTrinityString(LANG_ADDITEMSET), itemSetId); - - bool found = false; - ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore(); - for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr) - { - if (itr->second.ItemSet == itemSetId) - { - found = true; - ItemPosCountVec dest; - InventoryResult msg = playerTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itr->second.ItemId, 1); - if (msg == EQUIP_ERR_OK) - { - Item* item = playerTarget->StoreNewItem(dest, itr->second.ItemId, true); - - // remove binding (let GM give it to another player later) - if (player == playerTarget) - item->SetBinding(false); - - player->SendNewItem(item, 1, false, true); - if (player != playerTarget) - playerTarget->SendNewItem(item, 1, true, false); - } - else - { - player->SendEquipError(msg, NULL, NULL, itr->second.ItemId); - handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itr->second.ItemId, 1); - } - } - } - - if (!found) - { - handler->PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND, itemSetId); - handler->SetSentErrorMessage(true); - return false; - } - - return true; - } - - static bool HandleBankCommand(ChatHandler* handler, char const* /*args*/) - { - handler->GetSession()->SendShowBank(handler->GetSession()->GetPlayer()->GetGUID()); - return true; - } - - static bool HandleChangeWeather(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - // Weather is OFF - if (!sWorld->getBoolConfig(CONFIG_WEATHER)) - { - handler->SendSysMessage(LANG_WEATHER_DISABLED); - handler->SetSentErrorMessage(true); - return false; - } - - // *Change the weather of a cell - char const* px = strtok((char*)args, " "); - char const* py = strtok(NULL, " "); - - if (!px || !py) - return false; - - uint32 type = uint32(atoi(px)); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand - float grade = float(atof(py)); //0 to 1, sending -1 is instand good weather - - Player* player = handler->GetSession()->GetPlayer(); - uint32 zoneid = player->GetZoneId(); - - Weather* weather = WeatherMgr::FindWeather(zoneid); - - if (!weather) - weather = WeatherMgr::AddWeather(zoneid); - if (!weather) - { - handler->SendSysMessage(LANG_NO_WEATHER); - handler->SetSentErrorMessage(true); - return false; - } - - weather->SetWeather(WeatherType(type), grade); - - return true; - } - - - static bool HandleMaxSkillCommand(ChatHandler* handler, char const* /*args*/) - { - Player* SelectedPlayer = handler->getSelectedPlayer(); - if (!SelectedPlayer) - { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; - } - - // each skills that have max skill value dependent from level seted to current level max skill value - SelectedPlayer->UpdateSkillsToMaxSkillsForLevel(); - return true; - } - - static bool HandleSetSkillCommand(ChatHandler* handler, char const* args) - { - // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r - char const* skillStr = handler->extractKeyFromLink((char*)args, "Hskill"); - if (!skillStr) - return false; - - char const* levelStr = strtok(NULL, " "); - if (!levelStr) - return false; - - char const* maxPureSkill = strtok(NULL, " "); - - int32 skill = atoi(skillStr); - if (skill <= 0) - { - handler->PSendSysMessage(LANG_INVALID_SKILL_ID, skill); - handler->SetSentErrorMessage(true); - return false; - } - - int32 level = uint32(atol(levelStr)); - - Player* target = handler->getSelectedPlayer(); - if (!target) - { - handler->SendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; - } - - SkillLineEntry const* skillLine = sSkillLineStore.LookupEntry(skill); - if (!skillLine) - { - handler->PSendSysMessage(LANG_INVALID_SKILL_ID, skill); - handler->SetSentErrorMessage(true); - return false; - } - - std::string tNameLink = handler->GetNameLink(target); - - if (!target->GetSkillValue(skill)) - { - handler->PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, skillLine->name[handler->GetSessionDbcLocale()]); - handler->SetSentErrorMessage(true); - return false; - } - - uint16 max = maxPureSkill ? atol (maxPureSkill) : target->GetPureMaxSkillValue(skill); - - if (level <= 0 || level > max || max <= 0) - return false; - - target->SetSkill(skill, target->GetSkillStep(skill), level, max); - handler->PSendSysMessage(LANG_SET_SKILL, skill, skillLine->name[handler->GetSessionDbcLocale()], tNameLink.c_str(), level, max); - - return true; - } - // show info of player - static bool HandlePInfoCommand(ChatHandler* handler, char const* args) - { - Player* target; - uint64 targetGuid; - std::string targetName; - - uint32 parseGUID = MAKE_NEW_GUID(atol((char*)args), 0, HIGHGUID_PLAYER); - - if (sObjectMgr->GetPlayerNameByGUID(parseGUID, targetName)) - { - target = sObjectMgr->GetPlayerByLowGUID(parseGUID); - targetGuid = parseGUID; - } - else if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) - return false; - - uint32 accId = 0; - uint32 money = 0; - uint32 totalPlayerTime = 0; - uint8 level = 0; - uint32 latency = 0; - uint8 race; - uint8 Class; - int64 muteTime = 0; - int64 banTime = -1; - uint32 mapId; - uint32 areaId; - uint32 phase = 0; - - // get additional information from Player object - if (target) - { - // check online security - if (handler->HasLowerSecurity(target, 0)) - return false; - - accId = target->GetSession()->GetAccountId(); - money = target->GetMoney(); - totalPlayerTime = target->GetTotalPlayedTime(); - level = target->getLevel(); - latency = target->GetSession()->GetLatency(); - race = target->getRace(); - Class = target->getClass(); - muteTime = target->GetSession()->m_muteTime; - mapId = target->GetMapId(); - areaId = target->GetAreaId(); - phase = target->GetPhaseMask(); - } - // get additional information from DB - else - { - // check offline security - if (handler->HasLowerSecurity(NULL, targetGuid)) - return false; - - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PINFO); - stmt->setUInt32(0, GUID_LOPART(targetGuid)); - PreparedQueryResult result = CharacterDatabase.Query(stmt); - - if (!result) - return false; - - Field* fields = result->Fetch(); - totalPlayerTime = fields[0].GetUInt32(); - level = fields[1].GetUInt8(); - money = fields[2].GetUInt32(); - accId = fields[3].GetUInt32(); - race = fields[4].GetUInt8(); - Class = fields[5].GetUInt8(); - mapId = fields[6].GetUInt16(); - areaId = fields[7].GetUInt16(); - } - - std::string userName = handler->GetTrinityString(LANG_ERROR); - std::string eMail = handler->GetTrinityString(LANG_ERROR); - std::string lastIp = handler->GetTrinityString(LANG_ERROR); - uint32 security = 0; - std::string lastLogin = handler->GetTrinityString(LANG_ERROR); - - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO); - stmt->setInt32(0, int32(realmID)); - stmt->setUInt32(1, accId); - PreparedQueryResult result = LoginDatabase.Query(stmt); - - if (result) - { - Field* fields = result->Fetch(); - userName = fields[0].GetString(); - security = fields[1].GetUInt8(); - eMail = fields[2].GetString(); - muteTime = fields[5].GetUInt64(); - - if (eMail.empty()) - eMail = "-"; - - if (!handler->GetSession() || handler->GetSession()->GetSecurity() >= AccountTypes(security)) - { - lastIp = fields[3].GetString(); - lastLogin = fields[4].GetString(); - - uint32 ip = inet_addr(lastIp.c_str()); -#if TRINITY_ENDIAN == BIGENDIAN - EndianConvertReverse(ip); -#endif - - PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_IP2NATION_COUNTRY); - - stmt->setUInt32(0, ip); - - PreparedQueryResult result2 = WorldDatabase.Query(stmt); - - if (result2) - { - Field* fields2 = result2->Fetch(); - lastIp.append(" ("); - lastIp.append(fields2[0].GetString()); - lastIp.append(")"); - } - } - else - { - lastIp = "-"; - lastLogin = "-"; - } - } - - std::string nameLink = handler->playerLink(targetName); - - handler->PSendSysMessage(LANG_PINFO_ACCOUNT, (target ? "" : handler->GetTrinityString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(targetGuid), userName.c_str(), accId, eMail.c_str(), security, lastIp.c_str(), lastLogin.c_str(), latency); - - std::string bannedby = "unknown"; - std::string banreason = ""; - - stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO_BANS); - stmt->setUInt32(0, accId); - PreparedQueryResult result2 = LoginDatabase.Query(stmt); - if (!result2) - { - stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PINFO_BANS); - stmt->setUInt32(0, GUID_LOPART(targetGuid)); - result2 = CharacterDatabase.Query(stmt); - } - - if (result2) - { - Field* fields = result2->Fetch(); - banTime = int64(fields[1].GetBool() ? 0 : fields[0].GetUInt32()); - bannedby = fields[2].GetString(); - banreason = fields[3].GetString(); - } - - if (muteTime > 0) - handler->PSendSysMessage(LANG_PINFO_MUTE, secsToTimeString(muteTime - time(NULL), true).c_str()); - - if (banTime >= 0) - handler->PSendSysMessage(LANG_PINFO_BAN, banTime > 0 ? secsToTimeString(banTime - time(NULL), true).c_str() : "permanently", bannedby.c_str(), banreason.c_str()); - - std::string raceStr, ClassStr; - switch (race) - { - case RACE_HUMAN: - raceStr = "Human"; - break; - case RACE_ORC: - raceStr = "Orc"; - break; - case RACE_DWARF: - raceStr = "Dwarf"; - break; - case RACE_NIGHTELF: - raceStr = "Night Elf"; - break; - case RACE_UNDEAD_PLAYER: - raceStr = "Undead"; - break; - case RACE_TAUREN: - raceStr = "Tauren"; - break; - case RACE_GNOME: - raceStr = "Gnome"; - break; - case RACE_TROLL: - raceStr = "Troll"; - break; - case RACE_BLOODELF: - raceStr = "Blood Elf"; - break; - case RACE_DRAENEI: - raceStr = "Draenei"; - break; - } - - switch (Class) - { - case CLASS_WARRIOR: - ClassStr = "Warrior"; - break; - case CLASS_PALADIN: - ClassStr = "Paladin"; - break; - case CLASS_HUNTER: - ClassStr = "Hunter"; - break; - case CLASS_ROGUE: - ClassStr = "Rogue"; - break; - case CLASS_PRIEST: - ClassStr = "Priest"; - break; - case CLASS_DEATH_KNIGHT: - ClassStr = "Death Knight"; - break; - case CLASS_SHAMAN: - ClassStr = "Shaman"; - break; - case CLASS_MAGE: - ClassStr = "Mage"; - break; - case CLASS_WARLOCK: - ClassStr = "Warlock"; - break; - case CLASS_DRUID: - ClassStr = "Druid"; - break; - } - - std::string timeStr = secsToTimeString(totalPlayerTime, true, true); - uint32 gold = money /GOLD; - uint32 silv = (money % GOLD) / SILVER; - uint32 copp = (money % GOLD) % SILVER; - handler->PSendSysMessage(LANG_PINFO_LEVEL, raceStr.c_str(), ClassStr.c_str(), timeStr.c_str(), level, gold, silv, copp); - - // Add map, zone, subzone and phase to output - int locale = handler->GetSessionDbcLocale(); - std::string areaName = ""; - std::string zoneName = ""; - - MapEntry const* map = sMapStore.LookupEntry(mapId); - - AreaTableEntry const* area = GetAreaEntryByAreaID(areaId); - if (area) - { - areaName = area->area_name[locale]; - - AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone); - if (zone) - zoneName = zone->area_name[locale]; - } - - if (target) - { - if (!zoneName.empty()) - handler->PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name[locale], zoneName.c_str(), areaName.c_str(), phase); - else - handler->PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name[locale], areaName.c_str(), "", phase); - } - else - handler->PSendSysMessage(LANG_PINFO_MAP_OFFLINE, map->name[locale], areaName.c_str()); - - return true; - } - - static bool HandleRespawnCommand(ChatHandler* handler, char const* /*args*/) - { - Player* player = handler->GetSession()->GetPlayer(); - - // accept only explicitly selected target (not implicitly self targeting case) - Unit* target = handler->getSelectedUnit(); - if (player->GetSelection() && target) - { - if (target->GetTypeId() != TYPEID_UNIT || target->isPet()) - { - handler->SendSysMessage(LANG_SELECT_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - - if (target->isDead()) - target->ToCreature()->Respawn(); - return true; - } - - CellCoord p(Trinity::ComputeCellCoord(player->GetPositionX(), player->GetPositionY())); - Cell cell(p); - cell.SetNoCreate(); - - Trinity::RespawnDo u_do; - Trinity::WorldObjectWorker worker(player, u_do); - - TypeContainerVisitor, GridTypeMapContainer > obj_worker(worker); - cell.Visit(p, obj_worker, *player->GetMap(), *player, player->GetGridActivationRange()); - - return true; - } - // mute player for some times - static bool HandleMuteCommand(ChatHandler* handler, char const* args) - { - char* nameStr; - char* delayStr; - handler->extractOptFirstArg((char*)args, &nameStr, &delayStr); - if (!delayStr) - return false; - - char const* muteReason = strtok(NULL, "\r"); - std::string muteReasonStr = "No reason"; - if (muteReason != NULL) - muteReasonStr = muteReason; - - Player* target; - uint64 targetGuid; - std::string targetName; - if (!handler->extractPlayerTarget(nameStr, &target, &targetGuid, &targetName)) - return false; - - uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(targetGuid); - - // find only player from same account if any - if (!target) - if (WorldSession* session = sWorld->FindSession(accountId)) - target = session->GetPlayer(); - - uint32 notSpeakTime = uint32(atoi(delayStr)); - - // must have strong lesser security level - if (handler->HasLowerSecurity (target, targetGuid, true)) - return false; - - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); - - if (target) - { - // Target is online, mute will be in effect right away. - int64 muteTime = time(NULL) + notSpeakTime * MINUTE; - target->GetSession()->m_muteTime = muteTime; - stmt->setInt64(0, muteTime); - ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteReasonStr.c_str()); - } - else - { - // Target is offline, mute will be in effect starting from the next login. - int32 muteTime = -int32(notSpeakTime * MINUTE); - stmt->setInt64(0, muteTime); - } - - stmt->setUInt32(1, accountId); - LoginDatabase.Execute(stmt); - std::string nameLink = handler->playerLink(targetName); - - handler->PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); - - return true; - } - - // unmute player - static bool HandleUnmuteCommand(ChatHandler* handler, char const* args) - { - Player* target; - uint64 targetGuid; - std::string targetName; - if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) - return false; - - uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(targetGuid); - - // find only player from same account if any - if (!target) - if (WorldSession* session = sWorld->FindSession(accountId)) - target = session->GetPlayer(); - - // must have strong lesser security level - if (handler->HasLowerSecurity (target, targetGuid, true)) - return false; - - if (target) - { - if (target->CanSpeak()) - { - handler->SendSysMessage(LANG_CHAT_ALREADY_ENABLED); - handler->SetSentErrorMessage(true); - return false; - } - - target->GetSession()->m_muteTime = 0; - } - - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); - stmt->setInt64(0, 0); - stmt->setUInt32(1, accountId); - LoginDatabase.Execute(stmt); - - if (target) - ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_ENABLED); - - std::string nameLink = handler->playerLink(targetName); - - handler->PSendSysMessage(LANG_YOU_ENABLE_CHAT, nameLink.c_str()); - - return true; - } - - - static bool HandleMovegensCommand(ChatHandler* handler, char const* /*args*/) - { - Unit* unit = handler->getSelectedUnit(); - if (!unit) - { - handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - - handler->PSendSysMessage(LANG_MOVEGENS_LIST, (unit->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), unit->GetGUIDLow()); - - MotionMaster* motionMaster = unit->GetMotionMaster(); - float x, y, z; - motionMaster->GetDestination(x, y, z); - - for (uint8 i = 0; i < MAX_MOTION_SLOT; ++i) - { - MovementGenerator* movementGenerator = motionMaster->GetMotionSlot(i); - if (!movementGenerator) - { - handler->SendSysMessage("Empty"); - continue; - } - - switch (movementGenerator->GetMovementGeneratorType()) - { - case IDLE_MOTION_TYPE: - handler->SendSysMessage(LANG_MOVEGENS_IDLE); - break; - case RANDOM_MOTION_TYPE: - handler->SendSysMessage(LANG_MOVEGENS_RANDOM); - break; - case WAYPOINT_MOTION_TYPE: - handler->SendSysMessage(LANG_MOVEGENS_WAYPOINT); - break; - case ANIMAL_RANDOM_MOTION_TYPE: - handler->SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); - break; - case CONFUSED_MOTION_TYPE: - handler->SendSysMessage(LANG_MOVEGENS_CONFUSED); - break; - case CHASE_MOTION_TYPE: - { - Unit* target = NULL; - if (unit->GetTypeId() == TYPEID_PLAYER) - target = static_cast const*>(movementGenerator)->GetTarget(); - else - target = static_cast const*>(movementGenerator)->GetTarget(); - - if (!target) - handler->SendSysMessage(LANG_MOVEGENS_CHASE_NULL); - else if (target->GetTypeId() == TYPEID_PLAYER) - handler->PSendSysMessage(LANG_MOVEGENS_CHASE_PLAYER, target->GetName(), target->GetGUIDLow()); - else - handler->PSendSysMessage(LANG_MOVEGENS_CHASE_CREATURE, target->GetName(), target->GetGUIDLow()); - break; - } - case FOLLOW_MOTION_TYPE: - { - Unit* target = NULL; - if (unit->GetTypeId() == TYPEID_PLAYER) - target = static_cast const*>(movementGenerator)->GetTarget(); - else - target = static_cast const*>(movementGenerator)->GetTarget(); - - if (!target) - handler->SendSysMessage(LANG_MOVEGENS_FOLLOW_NULL); - else if (target->GetTypeId() == TYPEID_PLAYER) - handler->PSendSysMessage(LANG_MOVEGENS_FOLLOW_PLAYER, target->GetName(), target->GetGUIDLow()); - else - handler->PSendSysMessage(LANG_MOVEGENS_FOLLOW_CREATURE, target->GetName(), target->GetGUIDLow()); - break; - } - case HOME_MOTION_TYPE: - { - if (unit->GetTypeId() == TYPEID_UNIT) - handler->PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE, x, y, z); - else - handler->SendSysMessage(LANG_MOVEGENS_HOME_PLAYER); - break; - } - case FLIGHT_MOTION_TYPE: - handler->SendSysMessage(LANG_MOVEGENS_FLIGHT); - break; - case POINT_MOTION_TYPE: - { - handler->PSendSysMessage(LANG_MOVEGENS_POINT, x, y, z); - break; - } - case FLEEING_MOTION_TYPE: - handler->SendSysMessage(LANG_MOVEGENS_FEAR); - break; - case DISTRACT_MOTION_TYPE: - handler->SendSysMessage(LANG_MOVEGENS_DISTRACT); - break; - case EFFECT_MOTION_TYPE: - handler->SendSysMessage(LANG_MOVEGENS_EFFECT); - break; - default: - handler->PSendSysMessage(LANG_MOVEGENS_UNKNOWN, movementGenerator->GetMovementGeneratorType()); - break; - } - } - return true; - } - /* - ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator - Without this function 3rd party scripting library will get linking errors (unresolved external) - when attempting to use the PointMovementGenerator - */ - static bool HandleComeToMeCommand(ChatHandler* handler, char const* args) - { - char const* newFlagStr = strtok((char*)args, " "); - if (!newFlagStr) - return false; - - Creature* caster = handler->getSelectedCreature(); - if (!caster) - { - handler->SendSysMessage(LANG_SELECT_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - - Player* player = handler->GetSession()->GetPlayer(); - - caster->GetMotionMaster()->MovePoint(0, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); - - return true; - } - - static bool HandleDamageCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - Unit* target = handler->getSelectedUnit(); - if (!target || !handler->GetSession()->GetPlayer()->GetSelection()) - { - handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - - if (target->GetTypeId() == TYPEID_PLAYER) - { - if (handler->HasLowerSecurity((Player*)target, 0, false)) - return false; - } - - if (!target->isAlive()) - return true; - - char* damageStr = strtok((char*)args, " "); - if (!damageStr) - return false; - - int32 damage_int = atoi((char*)damageStr); - if (damage_int <= 0) - return true; - - uint32 damage = damage_int; - - char* schoolStr = strtok((char*)NULL, " "); - - // flat melee damage without resistence/etc reduction - if (!schoolStr) - { - handler->GetSession()->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - if (target != handler->GetSession()->GetPlayer()) - handler->GetSession()->GetPlayer()->SendAttackStateUpdate (HITINFO_AFFECTS_VICTIM, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_HIT, 0); - return true; - } - - uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL; - if (school >= MAX_SPELL_SCHOOL) - return false; - - SpellSchoolMask schoolmask = SpellSchoolMask(1 << school); - - if (Unit::IsDamageReducedByArmor(schoolmask)) - damage = handler->GetSession()->GetPlayer()->CalcArmorReducedDamage(target, damage, NULL, BASE_ATTACK); - - char* spellStr = strtok((char*)NULL, " "); - - // melee damage by specific school - if (!spellStr) - { - uint32 absorb = 0; - uint32 resist = 0; - - handler->GetSession()->GetPlayer()->CalcAbsorbResist(target, schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist); - - if (damage <= absorb + resist) - return true; - - damage -= absorb + resist; - - handler->GetSession()->GetPlayer()->DealDamageMods(target, damage, &absorb); - handler->GetSession()->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false); - handler->GetSession()->GetPlayer()->SendAttackStateUpdate (HITINFO_AFFECTS_VICTIM, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_HIT, 0); - return true; - } - - // non-melee damage - - // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form - uint32 spellid = handler->extractSpellIdFromLink((char*)args); - if (!spellid || !sSpellMgr->GetSpellInfo(spellid)) - return false; - - handler->GetSession()->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage); - return true; - } - - static bool HandleCombatStopCommand(ChatHandler* handler, char const* args) - { - Player* target = NULL; - - if (args && strlen(args) > 0) - { - target = sObjectAccessor->FindPlayerByName(args); - if (!target) - { - handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); - handler->SetSentErrorMessage(true); - return false; - } - } - - if (!target) - { - if (!handler->extractPlayerTarget((char*)args, &target)) - return false; - } - - // check online security - if (handler->HasLowerSecurity(target, 0)) - return false; - - target->CombatStop(); - target->getHostileRefManager().deleteReferences(); - return true; - } - - static bool HandleFlushArenaPointsCommand(ChatHandler* /*handler*/, char const* /*args*/) - { - sArenaTeamMgr->DistributeArenaPoints(); - return true; - } - - static bool HandleRepairitemsCommand(ChatHandler* handler, char const* args) - { - Player* target; - if (!handler->extractPlayerTarget((char*)args, &target)) - return false; - - // check online security - if (handler->HasLowerSecurity(target, 0)) - return false; - - // Repair items - target->DurabilityRepairAll(false, 0, false); - - handler->PSendSysMessage(LANG_YOU_REPAIR_ITEMS, handler->GetNameLink(target).c_str()); - if (handler->needReportToTarget(target)) - ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, handler->GetNameLink().c_str()); - - return true; - } - - static bool HandleWaterwalkCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - Player* player = handler->getSelectedPlayer(); - if (!player) - { - handler->PSendSysMessage(LANG_NO_CHAR_SELECTED); - handler->SetSentErrorMessage(true); - return false; - } - - // check online security - if (handler->HasLowerSecurity(player, 0)) - return false; - - if (strncmp(args, "on", 3) == 0) - player->SetMovement(MOVE_WATER_WALK); // ON - else if (strncmp(args, "off", 4) == 0) - player->SetMovement(MOVE_LAND_WALK); // OFF - else - { - handler->SendSysMessage(LANG_USE_BOL); - return false; - } - - handler->PSendSysMessage(LANG_YOU_SET_WATERWALK, args, handler->GetNameLink(player).c_str()); - if (handler->needReportToTarget(player)) - ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, handler->GetNameLink().c_str()); - return true; - } - - // Send mail by command - static bool HandleSendMailCommand(ChatHandler* handler, char const* args) - { - // format: name "subject text" "mail text" - Player* target; - uint64 targetGuid; - std::string targetName; - if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) - return false; - - char* tail1 = strtok(NULL, ""); - if (!tail1) - return false; - - char const* msgSubject = handler->extractQuotedArg(tail1); - if (!msgSubject) - return false; - - char* tail2 = strtok(NULL, ""); - if (!tail2) - return false; - - char const* msgText = handler->extractQuotedArg(tail2); - if (!msgText) - return false; - - // msgSubject, msgText isn't NUL after prev. check - std::string subject = msgSubject; - std::string text = msgText; - - // from console show not existed sender - MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); - - //- TODO: Fix poor design - SQLTransaction trans = CharacterDatabase.BeginTransaction(); - MailDraft(subject, text) - .SendMailTo(trans, MailReceiver(target, GUID_LOPART(targetGuid)), sender); - - CharacterDatabase.CommitTransaction(trans); - - std::string nameLink = handler->playerLink(targetName); - handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); - return true; - } - // Send items by mail - static bool HandleSendItemsCommand(ChatHandler* handler, char const* args) - { - // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12] - Player* receiver; - uint64 receiverGuid; - std::string receiverName; - if (!handler->extractPlayerTarget((char*)args, &receiver, &receiverGuid, &receiverName)) - return false; - - char* tail1 = strtok(NULL, ""); - if (!tail1) - return false; - - char const* msgSubject = handler->extractQuotedArg(tail1); - if (!msgSubject) - return false; - - char* tail2 = strtok(NULL, ""); - if (!tail2) - return false; - - char const* msgText = handler->extractQuotedArg(tail2); - if (!msgText) - return false; - - // msgSubject, msgText isn't NUL after prev. check - std::string subject = msgSubject; - std::string text = msgText; - - // extract items - typedef std::pair ItemPair; - typedef std::list< ItemPair > ItemPairs; - ItemPairs items; - - // get all tail string - char* tail = strtok(NULL, ""); - - // get from tail next item str - while (char* itemStr = strtok(tail, " ")) - { - // and get new tail - tail = strtok(NULL, ""); - - // parse item str - char const* itemIdStr = strtok(itemStr, ":"); - char const* itemCountStr = strtok(NULL, " "); - - uint32 itemId = atoi(itemIdStr); - if (!itemId) - return false; - - ItemTemplate const* item_proto = sObjectMgr->GetItemTemplate(itemId); - if (!item_proto) - { - handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); - handler->SetSentErrorMessage(true); - return false; - } - - uint32 itemCount = itemCountStr ? atoi(itemCountStr) : 1; - if (itemCount < 1 || (item_proto->MaxCount > 0 && itemCount > uint32(item_proto->MaxCount))) - { - handler->PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, itemCount, itemId); - handler->SetSentErrorMessage(true); - return false; - } - - while (itemCount > item_proto->GetMaxStackSize()) - { - items.push_back(ItemPair(itemId, item_proto->GetMaxStackSize())); - itemCount -= item_proto->GetMaxStackSize(); - } - - items.push_back(ItemPair(itemId, itemCount)); - - if (items.size() > MAX_MAIL_ITEMS) - { - handler->PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS); - handler->SetSentErrorMessage(true); - return false; - } - } - - // from console show not existed sender - MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); - - // fill mail - MailDraft draft(subject, text); - - SQLTransaction trans = CharacterDatabase.BeginTransaction(); - - for (ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr) - { - if (Item* item = Item::CreateItem(itr->first, itr->second, handler->GetSession() ? handler->GetSession()->GetPlayer() : 0)) - { - item->SaveToDB(trans); // save for prevent lost at next mail load, if send fail then item will deleted - draft.AddItem(item); - } - } - - draft.SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiverGuid)), sender); - CharacterDatabase.CommitTransaction(trans); - - std::string nameLink = handler->playerLink(receiverName); - handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); - return true; - } - /// Send money by mail - static bool HandleSendMoneyCommand(ChatHandler* handler, char const* args) - { - /// format: name "subject text" "mail text" money - - Player* receiver; - uint64 receiverGuid; - std::string receiverName; - if (!handler->extractPlayerTarget((char*)args, &receiver, &receiverGuid, &receiverName)) - return false; - - char* tail1 = strtok(NULL, ""); - if (!tail1) - return false; - - char* msgSubject = handler->extractQuotedArg(tail1); - if (!msgSubject) - return false; - - char* tail2 = strtok(NULL, ""); - if (!tail2) - return false; - - char* msgText = handler->extractQuotedArg(tail2); - if (!msgText) - return false; - - char* moneyStr = strtok(NULL, ""); - int32 money = moneyStr ? atoi(moneyStr) : 0; - if (money <= 0) - return false; - - // msgSubject, msgText isn't NUL after prev. check - std::string subject = msgSubject; - std::string text = msgText; - - // from console show not existed sender - MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); - - SQLTransaction trans = CharacterDatabase.BeginTransaction(); - - MailDraft(subject, text) - .AddMoney(money) - .SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiverGuid)), sender); - - CharacterDatabase.CommitTransaction(trans); - - std::string nameLink = handler->playerLink(receiverName); - handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); - return true; - } - /// Send a message to a player in game - static bool HandleSendMessageCommand(ChatHandler* handler, char const* args) - { - /// - Find the player - Player* player; - if (!handler->extractPlayerTarget((char*)args, &player)) - return false; - - char* msgStr = strtok(NULL, ""); - if (!msgStr) - return false; - - ///- Check that he is not logging out. - if (player->GetSession()->isLogingOut()) - { - handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); - handler->SetSentErrorMessage(true); - return false; - } - - /// - Send the message - // Use SendAreaTriggerMessage for fastest delivery. - player->GetSession()->SendAreaTriggerMessage("%s", msgStr); - player->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r"); - - // Confirmation message - std::string nameLink = handler->GetNameLink(player); - handler->PSendSysMessage(LANG_SENDMESSAGE, nameLink.c_str(), msgStr); - - return true; - } - - static bool HandleCreatePetCommand(ChatHandler* handler, char const* /*args*/) - { - Player* player = handler->GetSession()->GetPlayer(); - Creature* creatureTarget = handler->getSelectedCreature(); - - if (!creatureTarget || creatureTarget->isPet() || creatureTarget->GetTypeId() == TYPEID_PLAYER) - { - handler->PSendSysMessage(LANG_SELECT_CREATURE); - handler->SetSentErrorMessage(true); - return false; - } - - CreatureTemplate const* creatrueTemplate = sObjectMgr->GetCreatureTemplate(creatureTarget->GetEntry()); - // Creatures with family 0 crashes the server - if (!creatrueTemplate->family) - { - handler->PSendSysMessage("This creature cannot be tamed. (family id: 0)."); - handler->SetSentErrorMessage(true); - return false; - } - - if (player->GetPetGUID()) - { - handler->PSendSysMessage("You already have a pet"); - handler->SetSentErrorMessage(true); - return false; - } - - // Everything looks OK, create new pet - Pet* pet = new Pet(player, HUNTER_PET); - if (!pet->CreateBaseAtCreature(creatureTarget)) - { - delete pet; - handler->PSendSysMessage("Error 1"); - return false; - } - - creatureTarget->setDeathState(JUST_DIED); - creatureTarget->RemoveCorpse(); - creatureTarget->SetHealth(0); // just for nice GM-mode view - - pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, player->GetGUID()); - pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, player->getFaction()); - - if (!pet->InitStatsForLevel(creatureTarget->getLevel())) - { - sLog->outError(LOG_FILTER_GENERAL, "InitStatsForLevel() in EffectTameCreature failed! Pet deleted."); - handler->PSendSysMessage("Error 2"); - delete pet; - return false; - } - - // prepare visual effect for levelup - pet->SetUInt32Value(UNIT_FIELD_LEVEL, creatureTarget->getLevel()-1); - - pet->GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true); - // this enables pet details window (Shift+P) - pet->InitPetCreateSpells(); - pet->SetFullHealth(); - - pet->GetMap()->AddToMap(pet->ToCreature()); - - // visual effect for levelup - pet->SetUInt32Value(UNIT_FIELD_LEVEL, creatureTarget->getLevel()); - - player->SetMinion(pet, true); - pet->SavePetToDB(PET_SAVE_AS_CURRENT); - player->PetSpellInitialize(); - - return true; - } - - static bool HandlePetLearnCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - Player* player = handler->GetSession()->GetPlayer(); - Pet* pet = player->GetPet(); - - if (!pet) - { - handler->PSendSysMessage("You have no pet"); - handler->SetSentErrorMessage(true); - return false; - } - - uint32 spellId = handler->extractSpellIdFromLink((char*)args); - - if (!spellId || !sSpellMgr->GetSpellInfo(spellId)) - return false; - - // Check if pet already has it - if (pet->HasSpell(spellId)) - { - handler->PSendSysMessage("Pet already has spell: %u", spellId); - handler->SetSentErrorMessage(true); - return false; - } - - // Check if spell is valid - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); - if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo)) - { - handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId); - handler->SetSentErrorMessage(true); - return false; - } - - pet->learnSpell(spellId); - - handler->PSendSysMessage("Pet has learned spell %u", spellId); - return true; - } - - static bool HandlePetUnlearnCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - Player* player = handler->GetSession()->GetPlayer(); - Pet* pet = player->GetPet(); - if (!pet) - { - handler->PSendSysMessage("You have no pet"); - handler->SetSentErrorMessage(true); - return false; - } - - uint32 spellId = handler->extractSpellIdFromLink((char*)args); - - if (pet->HasSpell(spellId)) - pet->removeSpell(spellId, false); - else - handler->PSendSysMessage("Pet doesn't have that spell"); - - return true; - } - - static bool HandleFreezeCommand(ChatHandler* handler, char const* args) - { - std::string name; - Player* player; - char const* TargetName = strtok((char*)args, " "); // get entered name - if (!TargetName) // if no name entered use target - { - player = handler->getSelectedPlayer(); - if (player) //prevent crash with creature as target - { - name = player->GetName(); - normalizePlayerName(name); - } - } - else // if name entered - { - name = TargetName; - normalizePlayerName(name); - player = sObjectAccessor->FindPlayerByName(name.c_str()); - } - - if (!player) - { - handler->SendSysMessage(LANG_COMMAND_FREEZE_WRONG); - return true; - } - - if (player == handler->GetSession()->GetPlayer()) - { - handler->SendSysMessage(LANG_COMMAND_FREEZE_ERROR); - return true; - } - - // effect - if (player && (player != handler->GetSession()->GetPlayer())) - { - handler->PSendSysMessage(LANG_COMMAND_FREEZE, name.c_str()); - - // stop combat + make player unattackable + duel stop + stop some spells - player->setFaction(35); - player->CombatStop(); - if (player->IsNonMeleeSpellCasted(true)) - player->InterruptNonMeleeSpells(true); - player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - - // if player class = hunter || warlock remove pet if alive - if ((player->getClass() == CLASS_HUNTER) || (player->getClass() == CLASS_WARLOCK)) - { - if (Pet* pet = player->GetPet()) - { - pet->SavePetToDB(PET_SAVE_AS_CURRENT); - // not let dismiss dead pet - if (pet && pet->isAlive()) - player->RemovePet(pet, PET_SAVE_NOT_IN_SLOT); - } - } - - if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(9454)) - Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, player, player); - - // save player - player->SaveToDB(); - } - - return true; - } - - static bool HandleUnFreezeCommand(ChatHandler* handler, char const*args) - { - std::string name; - Player* player; - char* targetName = strtok((char*)args, " "); // Get entered name - - if (targetName) - { - name = targetName; - normalizePlayerName(name); - player = sObjectAccessor->FindPlayerByName(name.c_str()); - } - else // If no name was entered - use target - { - player = handler->getSelectedPlayer(); - if (player) - name = player->GetName(); - } - - if (player) - { - handler->PSendSysMessage(LANG_COMMAND_UNFREEZE, name.c_str()); - - // Reset player faction + allow combat + allow duels - player->setFactionForRace(player->getRace()); - player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - - // Remove Freeze spell (allowing movement and spells) - player->RemoveAurasDueToSpell(9454); - - // Save player - player->SaveToDB(); - } - else - { - if (targetName) - { - // Check for offline players - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_GUID_BY_NAME); - stmt->setString(0, name); - PreparedQueryResult result = CharacterDatabase.Query(stmt); - - if (!result) - { - handler->SendSysMessage(LANG_COMMAND_FREEZE_WRONG); - return true; - } - - // If player found: delete his freeze aura - Field* fields = result->Fetch(); - uint32 lowGuid = fields[0].GetUInt32(); - - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_AURA_FROZEN); - stmt->setUInt32(0, lowGuid); - CharacterDatabase.Execute(stmt); - - handler->PSendSysMessage(LANG_COMMAND_UNFREEZE, name.c_str()); - return true; - } - else - { - handler->SendSysMessage(LANG_COMMAND_FREEZE_WRONG); - return true; - } - } - - return true; - } - - static bool HandleListFreezeCommand(ChatHandler* handler, char const* /*args*/) - { - // Get names from DB - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_AURA_FROZEN); - PreparedQueryResult result = CharacterDatabase.Query(stmt); - if (!result) - { - handler->SendSysMessage(LANG_COMMAND_NO_FROZEN_PLAYERS); - return true; - } - - // Header of the names - handler->PSendSysMessage(LANG_COMMAND_LIST_FREEZE); - - // Output of the results - do - { - Field* fields = result->Fetch(); - std::string player = fields[0].GetString(); - handler->PSendSysMessage(LANG_COMMAND_FROZEN_PLAYERS, player.c_str()); - } - while (result->NextRow()); - - return true; - } - - static bool HandleGroupLeaderCommand(ChatHandler* handler, char const* args) - { - Player* player = NULL; - Group* group = NULL; - uint64 guid = 0; - char* nameStr = strtok((char*)args, " "); - - if (handler->GetPlayerGroupAndGUIDByName(nameStr, player, group, guid)) - if (group && group->GetLeaderGUID() != guid) - { - group->ChangeLeader(guid); - group->SendUpdate(); - } - - return true; - } - - static bool HandleGroupDisbandCommand(ChatHandler* handler, char const* args) - { - Player* player = NULL; - Group* group = NULL; - uint64 guid = 0; - char* nameStr = strtok((char*)args, " "); - - if (handler->GetPlayerGroupAndGUIDByName(nameStr, player, group, guid)) - if (group) - group->Disband(); - - return true; - } - - static bool HandleGroupRemoveCommand(ChatHandler* handler, char const* args) - { - Player* player = NULL; - Group* group = NULL; - uint64 guid = 0; - char* nameStr = strtok((char*)args, " "); - - if (handler->GetPlayerGroupAndGUIDByName(nameStr, player, group, guid, true)) - if (group) - group->RemoveMember(guid); - - return true; - } - - static bool HandlePlayAllCommand(ChatHandler* handler, char const* args) - { - if (!*args) - return false; - - uint32 soundId = atoi((char*)args); - - if (!sSoundEntriesStore.LookupEntry(soundId)) - { - handler->PSendSysMessage(LANG_SOUND_NOT_EXIST, soundId); - handler->SetSentErrorMessage(true); - return false; - } - - WorldPacket data(SMSG_PLAY_SOUND, 4); - data << uint32(soundId) << handler->GetSession()->GetPlayer()->GetGUID(); - sWorld->SendGlobalMessage(&data); - - handler->PSendSysMessage(LANG_COMMAND_PLAYED_TO_ALL, soundId); - return true; - } - - static bool HandlePossessCommand(ChatHandler* handler, char const* /*args*/) - { - Unit* unit = handler->getSelectedUnit(); - if (!unit) - return false; - - handler->GetSession()->GetPlayer()->CastSpell(unit, 530, true); - return true; - } - - static bool HandleUnPossessCommand(ChatHandler* handler, char const* /*args*/) - { - Unit* unit = handler->getSelectedUnit(); - if (!unit) - unit = handler->GetSession()->GetPlayer(); - - unit->RemoveCharmAuras(); - - return true; - } - - static bool HandleBindSightCommand(ChatHandler* handler, char const* /*args*/) - { - Unit* unit = handler->getSelectedUnit(); - if (!unit) - return false; - - handler->GetSession()->GetPlayer()->CastSpell(unit, 6277, true); - return true; - } - - static bool HandleUnbindSightCommand(ChatHandler* handler, char const* /*args*/) - { - Player* player = handler->GetSession()->GetPlayer(); - - if (player->isPossessing()) - return false; - - player->StopCastingBindSight(); - return true; - } -}; - -void AddSC_misc_commandscript() -{ - new misc_commandscript(); -} +/* + * Copyright (C) 2008-2012 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "Chat.h" +#include "ScriptMgr.h" +#include "AccountMgr.h" +#include "ArenaTeamMgr.h" +#include "CellImpl.h" +#include "GridNotifiers.h" +#include "Group.h" +#include "InstanceSaveMgr.h" +#include "MovementGenerator.h" +#include "ObjectAccessor.h" +#include "SpellAuras.h" +#include "TargetedMovementGenerator.h" +#include "WeatherMgr.h" +#include "ace/INET_Addr.h" + +class misc_commandscript : public CommandScript +{ +public: + misc_commandscript() : CommandScript("misc_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand groupCommandTable[] = + { + { "leader", SEC_ADMINISTRATOR, false, &HandleGroupLeaderCommand, "", NULL }, + { "disband", SEC_ADMINISTRATOR, false, &HandleGroupDisbandCommand, "", NULL }, + { "remove", SEC_ADMINISTRATOR, false, &HandleGroupRemoveCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand petCommandTable[] = + { + { "create", SEC_GAMEMASTER, false, &HandleCreatePetCommand, "", NULL }, + { "learn", SEC_GAMEMASTER, false, &HandlePetLearnCommand, "", NULL }, + { "unlearn", SEC_GAMEMASTER, false, &HandlePetUnlearnCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand sendCommandTable[] = + { + { "items", SEC_ADMINISTRATOR, true, &HandleSendItemsCommand, "", NULL }, + { "mail", SEC_MODERATOR, true, &HandleSendMailCommand, "", NULL }, + { "message", SEC_ADMINISTRATOR, true, &HandleSendMessageCommand, "", NULL }, + { "money", SEC_ADMINISTRATOR, true, &HandleSendMoneyCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand commandTable[] = + { + { "dev", SEC_ADMINISTRATOR, false, &HandleDevCommand, "", NULL }, + { "gps", SEC_ADMINISTRATOR, false, &HandleGPSCommand, "", NULL }, + { "aura", SEC_ADMINISTRATOR, false, &HandleAuraCommand, "", NULL }, + { "unaura", SEC_ADMINISTRATOR, false, &HandleUnAuraCommand, "", NULL }, + { "appear", SEC_MODERATOR, false, &HandleAppearCommand, "", NULL }, + { "summon", SEC_MODERATOR, false, &HandleSummonCommand, "", NULL }, + { "groupsummon", SEC_MODERATOR, false, &HandleGroupSummonCommand, "", NULL }, + { "commands", SEC_PLAYER, true, &HandleCommandsCommand, "", NULL }, + { "die", SEC_ADMINISTRATOR, false, &HandleDieCommand, "", NULL }, + { "revive", SEC_ADMINISTRATOR, true, &HandleReviveCommand, "", NULL }, + { "dismount", SEC_PLAYER, false, &HandleDismountCommand, "", NULL }, + { "guid", SEC_GAMEMASTER, false, &HandleGUIDCommand, "", NULL }, + { "help", SEC_PLAYER, true, &HandleHelpCommand, "", NULL }, + { "itemmove", SEC_GAMEMASTER, false, &HandleItemMoveCommand, "", NULL }, + { "cooldown", SEC_ADMINISTRATOR, false, &HandleCooldownCommand, "", NULL }, + { "distance", SEC_ADMINISTRATOR, false, &HandleGetDistanceCommand, "", NULL }, + { "recall", SEC_MODERATOR, false, &HandleRecallCommand, "", NULL }, + { "save", SEC_PLAYER, false, &HandleSaveCommand, "", NULL }, + { "saveall", SEC_MODERATOR, true, &HandleSaveAllCommand, "", NULL }, + { "kick", SEC_GAMEMASTER, true, &HandleKickPlayerCommand, "", NULL }, + { "start", SEC_PLAYER, false, &HandleStartCommand, "", NULL }, + { "taxicheat", SEC_MODERATOR, false, &HandleTaxiCheatCommand, "", NULL }, + { "linkgrave", SEC_ADMINISTRATOR, false, &HandleLinkGraveCommand, "", NULL }, + { "neargrave", SEC_ADMINISTRATOR, false, &HandleNearGraveCommand, "", NULL }, + { "explorecheat", SEC_ADMINISTRATOR, false, &HandleExploreCheatCommand, "", NULL }, + { "showarea", SEC_ADMINISTRATOR, false, &HandleShowAreaCommand, "", NULL }, + { "hidearea", SEC_ADMINISTRATOR, false, &HandleHideAreaCommand, "", NULL }, + { "additem", SEC_ADMINISTRATOR, false, &HandleAddItemCommand, "", NULL }, + { "additemset", SEC_ADMINISTRATOR, false, &HandleAddItemSetCommand, "", NULL }, + { "bank", SEC_ADMINISTRATOR, false, &HandleBankCommand, "", NULL }, + { "wchange", SEC_ADMINISTRATOR, false, &HandleChangeWeather, "", NULL }, + { "maxskill", SEC_ADMINISTRATOR, false, &HandleMaxSkillCommand, "", NULL }, + { "setskill", SEC_ADMINISTRATOR, false, &HandleSetSkillCommand, "", NULL }, + { "pinfo", SEC_GAMEMASTER, true, &HandlePInfoCommand, "", NULL }, + { "respawn", SEC_ADMINISTRATOR, false, &HandleRespawnCommand, "", NULL }, + { "send", SEC_MODERATOR, true, NULL, "", sendCommandTable }, + { "pet", SEC_GAMEMASTER, false, NULL, "", petCommandTable }, + { "mute", SEC_MODERATOR, true, &HandleMuteCommand, "", NULL }, + { "unmute", SEC_MODERATOR, true, &HandleUnmuteCommand, "", NULL }, + { "movegens", SEC_ADMINISTRATOR, false, &HandleMovegensCommand, "", NULL }, + { "cometome", SEC_ADMINISTRATOR, false, &HandleComeToMeCommand, "", NULL }, + { "damage", SEC_ADMINISTRATOR, false, &HandleDamageCommand, "", NULL }, + { "combatstop", SEC_GAMEMASTER, true, &HandleCombatStopCommand, "", NULL }, + { "flusharenapoints", SEC_ADMINISTRATOR, false, &HandleFlushArenaPointsCommand, "", NULL }, + { "repairitems", SEC_GAMEMASTER, true, &HandleRepairitemsCommand, "", NULL }, + { "waterwalk", SEC_GAMEMASTER, false, &HandleWaterwalkCommand, "", NULL }, + { "freeze", SEC_MODERATOR, false, &HandleFreezeCommand, "", NULL }, + { "unfreeze", SEC_MODERATOR, false, &HandleUnFreezeCommand, "", NULL }, + { "listfreeze", SEC_MODERATOR, false, &HandleListFreezeCommand, "", NULL }, + { "group", SEC_ADMINISTRATOR, false, NULL, "", groupCommandTable }, + { "possess", SEC_ADMINISTRATOR, false, HandlePossessCommand, "", NULL }, + { "unpossess", SEC_ADMINISTRATOR, false, HandleUnPossessCommand, "", NULL }, + { "bindsight", SEC_ADMINISTRATOR, false, HandleBindSightCommand, "", NULL }, + { "unbindsight", SEC_ADMINISTRATOR, false, HandleUnbindSightCommand, "", NULL }, + { "playall", SEC_GAMEMASTER, false, HandlePlayAllCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + static bool HandleDevCommand(ChatHandler* handler, char const* args) + { + if (!*args) + { + if (handler->GetSession()->GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER)) + handler->GetSession()->SendNotification(LANG_DEV_ON); + else + handler->GetSession()->SendNotification(LANG_DEV_OFF); + return true; + } + + std::string argstr = (char*)args; + + if (argstr == "on") + { + handler->GetSession()->GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER); + handler->GetSession()->SendNotification(LANG_DEV_ON); + return true; + } + + if (argstr == "off") + { + handler->GetSession()->GetPlayer()->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER); + handler->GetSession()->SendNotification(LANG_DEV_OFF); + return true; + } + + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + static bool HandleGPSCommand(ChatHandler* handler, char const* args) + { + WorldObject* object = NULL; + if (*args) + { + uint64 guid = handler->extractGuidFromLink((char*)args); + if (guid) + object = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*handler->GetSession()->GetPlayer(), guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT); + + if (!object) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + } + else + { + object = handler->getSelectedUnit(); + + if (!object) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + } + + CellCoord cellCoord = Trinity::ComputeCellCoord(object->GetPositionX(), object->GetPositionY()); + Cell cell(cellCoord); + + uint32 zoneId, areaId; + object->GetZoneAndAreaId(zoneId, areaId); + + MapEntry const* mapEntry = sMapStore.LookupEntry(object->GetMapId()); + AreaTableEntry const* zoneEntry = GetAreaEntryByAreaID(zoneId); + AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(areaId); + + float zoneX = object->GetPositionX(); + float zoneY = object->GetPositionY(); + + Map2ZoneCoordinates(zoneX, zoneY, zoneId); + + Map const* map = object->GetMap(); + float groundZ = map->GetHeight(object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), MAX_HEIGHT); + float floorZ = map->GetHeight(object->GetPhaseMask(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ()); + + GridCoord gridCoord = Trinity::ComputeGridCoord(object->GetPositionX(), object->GetPositionY()); + + // 63? WHY? + int gridX = 63 - gridCoord.x_coord; + int gridY = 63 - gridCoord.y_coord; + + uint32 haveMap = Map::ExistMap(object->GetMapId(), gridX, gridY) ? 1 : 0; + uint32 haveVMap = Map::ExistVMap(object->GetMapId(), gridX, gridY) ? 1 : 0; + + if (haveVMap) + { + if (map->IsOutdoors(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ())) + handler->PSendSysMessage("You are outdoors"); + else + handler->PSendSysMessage("You are indoors"); + } + else + handler->PSendSysMessage("no VMAP available for area info"); + + handler->PSendSysMessage(LANG_MAP_POSITION, + object->GetMapId(), (mapEntry ? mapEntry->name[handler->GetSessionDbcLocale()] : ""), + zoneId, (zoneEntry ? zoneEntry->area_name[handler->GetSessionDbcLocale()] : ""), + areaId, (areaEntry ? areaEntry->area_name[handler->GetSessionDbcLocale()] : ""), + object->GetPhaseMask(), + object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation(), + cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(), + zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap); + + LiquidData liquidStatus; + ZLiquidStatus status = map->getLiquidStatus(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus); + + if (status) + handler->PSendSysMessage(LANG_LIQUID_STATUS, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status); + + return true; + } + + static bool HandleAuraCommand(ChatHandler* handler, char const* args) + { + Unit* target = handler->getSelectedUnit(); + if (!target) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + + if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId)) + Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, target, target); + + return true; + } + + static bool HandleUnAuraCommand(ChatHandler* handler, char const* args) + { + Unit* target = handler->getSelectedUnit(); + if (!target) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + std::string argstr = args; + if (argstr == "all") + { + target->RemoveAllAuras(); + return true; + } + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + if (!spellId) + return false; + + target->RemoveAurasDueToSpell(spellId); + + return true; + } + // Teleport to Player + static bool HandleAppearCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + Player* _player = handler->GetSession()->GetPlayer(); + if (target == _player || targetGuid == _player->GetGUID()) + { + handler->SendSysMessage(LANG_CANT_TELEPORT_SELF); + handler->SetSentErrorMessage(true); + return false; + } + + if (target) + { + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + std::string chrNameLink = handler->playerLink(targetName); + + Map* map = target->GetMap(); + if (map->IsBattlegroundOrArena()) + { + // only allow if gm mode is on + if (!_player->isGameMaster()) + { + handler->PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM, chrNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + // if both players are in different bgs + else if (_player->GetBattlegroundId() && _player->GetBattlegroundId() != target->GetBattlegroundId()) + _player->LeaveBattleground(false); // Note: should be changed so _player gets no Deserter debuff + + // all's well, set bg id + // when porting out from the bg, it will be reset to 0 + _player->SetBattlegroundId(target->GetBattlegroundId(), target->GetBattlegroundTypeId()); + // remember current position as entry point for return at bg end teleportation + if (!_player->GetMap()->IsBattlegroundOrArena()) + _player->SetBattlegroundEntryPoint(); + } + else if (map->IsDungeon()) + { + // we have to go to instance, and can go to player only if: + // 1) we are in his group (either as leader or as member) + // 2) we are not bound to any group and have GM mode on + if (_player->GetGroup()) + { + // we are in group, we can go only if we are in the player group + if (_player->GetGroup() != target->GetGroup()) + { + handler->PSendSysMessage(LANG_CANNOT_GO_TO_INST_PARTY, chrNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + } + else + { + // we are not in group, let's verify our GM mode + if (!_player->isGameMaster()) + { + handler->PSendSysMessage(LANG_CANNOT_GO_TO_INST_GM, chrNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + } + + // if the player or the player's group is bound to another instance + // the player will not be bound to another one + InstancePlayerBind* bind = _player->GetBoundInstance(target->GetMapId(), target->GetDifficulty(map->IsRaid())); + if (!bind) + { + Group* group = _player->GetGroup(); + // if no bind exists, create a solo bind + InstanceGroupBind* gBind = group ? group->GetBoundInstance(target) : NULL; // if no bind exists, create a solo bind + if (!gBind) + if (InstanceSave* save = sInstanceSaveMgr->GetInstanceSave(target->GetInstanceId())) + _player->BindToInstance(save, !save->CanReset()); + } + + if (map->IsRaid()) + _player->SetRaidDifficulty(target->GetRaidDifficulty()); + else + _player->SetDungeonDifficulty(target->GetDungeonDifficulty()); + } + + handler->PSendSysMessage(LANG_APPEARING_AT, chrNameLink.c_str()); + + // stop flight if need + if (_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + // to point to see at target with same orientation + float x, y, z; + target->GetContactPoint(_player, x, y, z); + + _player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE); + _player->SetPhaseMask(target->GetPhaseMask(), true); + } + else + { + // check offline security + if (handler->HasLowerSecurity(NULL, targetGuid)) + return false; + + std::string nameLink = handler->playerLink(targetName); + + handler->PSendSysMessage(LANG_APPEARING_AT, nameLink.c_str()); + + // to point where player stay (if loaded) + float x, y, z, o; + uint32 map; + bool in_flight; + if (!Player::LoadPositionFromDB(map, x, y, z, o, in_flight, targetGuid)) + return false; + + // stop flight if need + if (_player->isInFlight()) + { + _player->GetMotionMaster()->MovementExpired(); + _player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + _player->SaveRecallPosition(); + + _player->TeleportTo(map, x, y, z, _player->GetOrientation()); + } + + return true; + } + // Summon Player + static bool HandleSummonCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + Player* _player = handler->GetSession()->GetPlayer(); + if (target == _player || targetGuid == _player->GetGUID()) + { + handler->PSendSysMessage(LANG_CANT_TELEPORT_SELF); + handler->SetSentErrorMessage(true); + return false; + } + + if (target) + { + std::string nameLink = handler->playerLink(targetName); + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + if (target->IsBeingTeleported()) + { + handler->PSendSysMessage(LANG_IS_TELEPORTED, nameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + Map* map = handler->GetSession()->GetPlayer()->GetMap(); + + if (map->IsBattlegroundOrArena()) + { + // only allow if gm mode is on + if (!_player->isGameMaster()) + { + handler->PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM, nameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + // if both players are in different bgs + else if (target->GetBattlegroundId() && handler->GetSession()->GetPlayer()->GetBattlegroundId() != target->GetBattlegroundId()) + target->LeaveBattleground(false); // Note: should be changed so target gets no Deserter debuff + + // all's well, set bg id + // when porting out from the bg, it will be reset to 0 + target->SetBattlegroundId(handler->GetSession()->GetPlayer()->GetBattlegroundId(), handler->GetSession()->GetPlayer()->GetBattlegroundTypeId()); + // remember current position as entry point for return at bg end teleportation + if (!target->GetMap()->IsBattlegroundOrArena()) + target->SetBattlegroundEntryPoint(); + } + else if (map->IsDungeon()) + { + Map* map = target->GetMap(); + + if (map->Instanceable() && map->GetInstanceId() != map->GetInstanceId()) + target->UnbindInstance(map->GetInstanceId(), target->GetDungeonDifficulty(), true); + + // we are in instance, and can summon only player in our group with us as lead + if (!handler->GetSession()->GetPlayer()->GetGroup() || !target->GetGroup() || + (target->GetGroup()->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()) || + (handler->GetSession()->GetPlayer()->GetGroup()->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID())) + // the last check is a bit excessive, but let it be, just in case + { + handler->PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST, nameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + } + + handler->PSendSysMessage(LANG_SUMMONING, nameLink.c_str(), ""); + if (handler->needReportToTarget(target)) + ChatHandler(target).PSendSysMessage(LANG_SUMMONED_BY, handler->playerLink(_player->GetName()).c_str()); + + // stop flight if need + if (target->isInFlight()) + { + target->GetMotionMaster()->MovementExpired(); + target->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + target->SaveRecallPosition(); + + // before GM + float x, y, z; + handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, target->GetObjectSize()); + target->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, target->GetOrientation()); + target->SetPhaseMask(handler->GetSession()->GetPlayer()->GetPhaseMask(), true); + } + else + { + // check offline security + if (handler->HasLowerSecurity(NULL, targetGuid)) + return false; + + std::string nameLink = handler->playerLink(targetName); + + handler->PSendSysMessage(LANG_SUMMONING, nameLink.c_str(), handler->GetTrinityString(LANG_OFFLINE)); + + // in point where GM stay + Player::SavePositionInDB(handler->GetSession()->GetPlayer()->GetMapId(), + handler->GetSession()->GetPlayer()->GetPositionX(), + handler->GetSession()->GetPlayer()->GetPositionY(), + handler->GetSession()->GetPlayer()->GetPositionZ(), + handler->GetSession()->GetPlayer()->GetOrientation(), + handler->GetSession()->GetPlayer()->GetZoneId(), + targetGuid); + } + + return true; + } + // Summon group of player + static bool HandleGroupSummonCommand(ChatHandler* handler, char const* args) + { + Player* target; + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + Group* group = target->GetGroup(); + + std::string nameLink = handler->GetNameLink(target); + + if (!group) + { + handler->PSendSysMessage(LANG_NOT_IN_GROUP, nameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + Map* gmMap = handler->GetSession()->GetPlayer()->GetMap(); + bool toInstance = gmMap->Instanceable(); + + // we are in instance, and can summon only player in our group with us as lead + if (toInstance && ( + !handler->GetSession()->GetPlayer()->GetGroup() || (group->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()) || + (handler->GetSession()->GetPlayer()->GetGroup()->GetLeaderGUID() != handler->GetSession()->GetPlayer()->GetGUID()))) + // the last check is a bit excessive, but let it be, just in case + { + handler->SendSysMessage(LANG_CANNOT_SUMMON_TO_INST); + handler->SetSentErrorMessage(true); + return false; + } + + for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + { + Player* player = itr->getSource(); + + if (!player || player == handler->GetSession()->GetPlayer() || !player->GetSession()) + continue; + + // check online security + if (handler->HasLowerSecurity(player, 0)) + return false; + + std::string plNameLink = handler->GetNameLink(player); + + if (player->IsBeingTeleported() == true) + { + handler->PSendSysMessage(LANG_IS_TELEPORTED, plNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + if (toInstance) + { + Map* playerMap = player->GetMap(); + + if (playerMap->Instanceable() && playerMap->GetInstanceId() != gmMap->GetInstanceId()) + { + // cannot summon from instance to instance + handler->PSendSysMessage(LANG_CANNOT_SUMMON_TO_INST, plNameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + } + + handler->PSendSysMessage(LANG_SUMMONING, plNameLink.c_str(), ""); + if (handler->needReportToTarget(player)) + ChatHandler(player).PSendSysMessage(LANG_SUMMONED_BY, handler->GetNameLink().c_str()); + + // stop flight if need + if (player->isInFlight()) + { + player->GetMotionMaster()->MovementExpired(); + player->CleanupAfterTaxiFlight(); + } + // save only in non-flight case + else + player->SaveRecallPosition(); + + // before GM + float x, y, z; + handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, player->GetObjectSize()); + player->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, player->GetOrientation()); + } + + return true; + } + + static bool HandleCommandsCommand(ChatHandler* handler, char const* /*args*/) + { + handler->ShowHelpForCommand(handler->getCommandTable(), ""); + return true; + } + + static bool HandleDieCommand(ChatHandler* handler, char const* /*args*/) + { + Unit* target = handler->getSelectedUnit(); + + if (!target || !handler->GetSession()->GetPlayer()->GetSelection()) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (target->GetTypeId() == TYPEID_PLAYER) + { + if (handler->HasLowerSecurity((Player*)target, 0, false)) + return false; + } + + if (target->isAlive()) + { + if (sWorld->getBoolConfig(CONFIG_DIE_COMMAND_MODE)) + handler->GetSession()->GetPlayer()->Kill(target); + else + handler->GetSession()->GetPlayer()->DealDamage(target, target->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + } + + return true; + } + + static bool HandleReviveCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid)) + return false; + + if (target) + { + target->ResurrectPlayer(!AccountMgr::IsPlayerAccount(target->GetSession()->GetSecurity()) ? 1.0f : 0.5f); + target->SpawnCorpseBones(); + target->SaveToDB(); + } + else + // will resurrected at login without corpse + sObjectAccessor->ConvertCorpseForPlayer(targetGuid); + + return true; + } + + static bool HandleDismountCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + // If player is not mounted, so go out :) + if (!player->IsMounted()) + { + handler->SendSysMessage(LANG_CHAR_NON_MOUNTED); + handler->SetSentErrorMessage(true); + return false; + } + + if (player->isInFlight()) + { + handler->SendSysMessage(LANG_YOU_IN_FLIGHT); + handler->SetSentErrorMessage(true); + return false; + } + + player->Dismount(); + player->RemoveAurasByType(SPELL_AURA_MOUNTED); + return true; + } + + static bool HandleGUIDCommand(ChatHandler* handler, char const* /*args*/) + { + uint64 guid = handler->GetSession()->GetPlayer()->GetSelection(); + + if (guid == 0) + { + handler->SendSysMessage(LANG_NO_SELECTION); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_OBJECT_GUID, GUID_LOPART(guid), GUID_HIPART(guid)); + return true; + } + + static bool HandleHelpCommand(ChatHandler* handler, char const* args) + { + char const* cmd = strtok((char*)args, " "); + if (!cmd) + { + handler->ShowHelpForCommand(handler->getCommandTable(), "help"); + handler->ShowHelpForCommand(handler->getCommandTable(), ""); + } + else + { + if (!handler->ShowHelpForCommand(handler->getCommandTable(), cmd)) + handler->SendSysMessage(LANG_NO_HELP_CMD); + } + + return true; + } + // move item to other slot + static bool HandleItemMoveCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + char const* param1 = strtok((char*)args, " "); + if (!param1) + return false; + + char const* param2 = strtok(NULL, " "); + if (!param2) + return false; + + uint8 srcSlot = uint8(atoi(param1)); + uint8 dstSlot = uint8(atoi(param2)); + + if (srcSlot == dstSlot) + return true; + + if (!handler->GetSession()->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0, srcSlot, true)) + return false; + + if (!handler->GetSession()->GetPlayer()->IsValidPos(INVENTORY_SLOT_BAG_0, dstSlot, false)) + return false; + + uint16 src = ((INVENTORY_SLOT_BAG_0 << 8) | srcSlot); + uint16 dst = ((INVENTORY_SLOT_BAG_0 << 8) | dstSlot); + + handler->GetSession()->GetPlayer()->SwapItem(src, dst); + + return true; + } + + static bool HandleCooldownCommand(ChatHandler* handler, char const* args) + { + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + std::string nameLink = handler->GetNameLink(target); + + if (!*args) + { + target->RemoveAllSpellCooldown(); + handler->PSendSysMessage(LANG_REMOVEALL_COOLDOWN, nameLink.c_str()); + } + else + { + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellIid = handler->extractSpellIdFromLink((char*)args); + if (!spellIid) + return false; + + if (!sSpellMgr->GetSpellInfo(spellIid)) + { + handler->PSendSysMessage(LANG_UNKNOWN_SPELL, target == handler->GetSession()->GetPlayer() ? handler->GetTrinityString(LANG_YOU) : nameLink.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + target->RemoveSpellCooldown(spellIid, true); + handler->PSendSysMessage(LANG_REMOVE_COOLDOWN, spellIid, target == handler->GetSession()->GetPlayer() ? handler->GetTrinityString(LANG_YOU) : nameLink.c_str()); + } + return true; + } + + static bool HandleGetDistanceCommand(ChatHandler* handler, char const* args) + { + WorldObject* obj = NULL; + + if (*args) + { + uint64 guid = handler->extractGuidFromLink((char*)args); + if (guid) + obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*handler->GetSession()->GetPlayer(), guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT); + + if (!obj) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + } + else + { + obj = handler->getSelectedUnit(); + + if (!obj) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + } + + handler->PSendSysMessage(LANG_DISTANCE, handler->GetSession()->GetPlayer()->GetDistance(obj), handler->GetSession()->GetPlayer()->GetDistance2d(obj), handler->GetSession()->GetPlayer()->GetExactDist(obj), handler->GetSession()->GetPlayer()->GetExactDist2d(obj)); + return true; + } + // Teleport player to last position + static bool HandleRecallCommand(ChatHandler* handler, char const* args) + { + Player* target; + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + if (target->IsBeingTeleported()) + { + handler->PSendSysMessage(LANG_IS_TELEPORTED, handler->GetNameLink(target).c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + // stop flight if need + if (target->isInFlight()) + { + target->GetMotionMaster()->MovementExpired(); + target->CleanupAfterTaxiFlight(); + } + + target->TeleportTo(target->m_recallMap, target->m_recallX, target->m_recallY, target->m_recallZ, target->m_recallO); + return true; + } + + static bool HandleSaveCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + // save GM account without delay and output message + if (!AccountMgr::IsPlayerAccount(handler->GetSession()->GetSecurity())) + { + if (Player* target = handler->getSelectedPlayer()) + target->SaveToDB(); + else + player->SaveToDB(); + handler->SendSysMessage(LANG_PLAYER_SAVED); + return true; + } + + // save if the player has last been saved over 20 seconds ago + uint32 saveInterval = sWorld->getIntConfig(CONFIG_INTERVAL_SAVE); + if (saveInterval == 0 || (saveInterval > 20 * IN_MILLISECONDS && player->GetSaveTimer() <= saveInterval - 20 * IN_MILLISECONDS)) + player->SaveToDB(); + + return true; + } + + // Save all players in the world + static bool HandleSaveAllCommand(ChatHandler* handler, char const* /*args*/) + { + sObjectAccessor->SaveAllPlayers(); + handler->SendSysMessage(LANG_PLAYERS_SAVED); + return true; + } + + // kick player + static bool HandleKickPlayerCommand(ChatHandler* handler, char const* args) + { + Player* target = NULL; + std::string playerName; + if (!handler->extractPlayerTarget((char*)args, &target, NULL, &playerName)) + return false; + + if (handler->GetSession() && target == handler->GetSession()->GetPlayer()) + { + handler->SendSysMessage(LANG_COMMAND_KICKSELF); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + if (sWorld->getBoolConfig(CONFIG_SHOW_KICK_IN_WORLD)) + sWorld->SendWorldText(LANG_COMMAND_KICKMESSAGE, playerName.c_str()); + else + handler->PSendSysMessage(LANG_COMMAND_KICKMESSAGE, playerName.c_str()); + + target->GetSession()->KickPlayer(); + + return true; + } + + static bool HandleStartCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + if (player->isInFlight()) + { + handler->SendSysMessage(LANG_YOU_IN_FLIGHT); + handler->SetSentErrorMessage(true); + return false; + } + + if (player->isInCombat()) + { + handler->SendSysMessage(LANG_YOU_IN_COMBAT); + handler->SetSentErrorMessage(true); + return false; + } + + if (player->isDead() || player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) + { + // if player is dead and stuck, send ghost to graveyard + player->RepopAtGraveyard(); + return true; + } + + // cast spell Stuck + player->CastSpell(player, 7355, false); + return true; + } + // Enable on\off all taxi paths + static bool HandleTaxiCheatCommand(ChatHandler* handler, char const* args) + { + if (!*args) + { + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + return false; + } + + std::string argStr = (char*)args; + + Player* chr = handler->getSelectedPlayer(); + + if (!chr) + chr = handler->GetSession()->GetPlayer(); + else if (handler->HasLowerSecurity(chr, 0)) // check online security + return false; + + if (argStr == "on") + { + chr->SetTaxiCheater(true); + handler->PSendSysMessage(LANG_YOU_GIVE_TAXIS, handler->GetNameLink(chr).c_str()); + if (handler->needReportToTarget(chr)) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_ADDED, handler->GetNameLink().c_str()); + return true; + } + + if (argStr == "off") + { + chr->SetTaxiCheater(false); + handler->PSendSysMessage(LANG_YOU_REMOVE_TAXIS, handler->GetNameLink(chr).c_str()); + if (handler->needReportToTarget(chr)) + ChatHandler(chr).PSendSysMessage(LANG_YOURS_TAXIS_REMOVED, handler->GetNameLink().c_str()); + + return true; + } + + handler->SendSysMessage(LANG_USE_BOL); + handler->SetSentErrorMessage(true); + + return false; + } + + static bool HandleLinkGraveCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + char* px = strtok((char*)args, " "); + if (!px) + return false; + + uint32 graveyardId = uint32(atoi(px)); + + uint32 team; + + char* px2 = strtok(NULL, " "); + + if (!px2) + team = 0; + else if (strncmp(px2, "horde", 6) == 0) + team = HORDE; + else if (strncmp(px2, "alliance", 9) == 0) + team = ALLIANCE; + else + return false; + + WorldSafeLocsEntry const* graveyard = sWorldSafeLocsStore.LookupEntry(graveyardId); + + if (!graveyard) + { + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDNOEXIST, graveyardId); + handler->SetSentErrorMessage(true); + return false; + } + + Player* player = handler->GetSession()->GetPlayer(); + + uint32 zoneId = player->GetZoneId(); + + AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(zoneId); + if (!areaEntry || areaEntry->zone !=0) + { + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDWRONGZONE, graveyardId, zoneId); + handler->SetSentErrorMessage(true); + return false; + } + + if (sObjectMgr->AddGraveYardLink(graveyardId, zoneId, team)) + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDLINKED, graveyardId, zoneId); + else + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDALRLINKED, graveyardId, zoneId); + + return true; + } + + static bool HandleNearGraveCommand(ChatHandler* handler, char const* args) + { + uint32 team; + + size_t argStr = strlen(args); + + if (!*args) + team = 0; + else if (strncmp((char*)args, "horde", argStr) == 0) + team = HORDE; + else if (strncmp((char*)args, "alliance", argStr) == 0) + team = ALLIANCE; + else + return false; + + Player* player = handler->GetSession()->GetPlayer(); + uint32 zone_id = player->GetZoneId(); + + WorldSafeLocsEntry const* graveyard = sObjectMgr->GetClosestGraveYard( + player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), team); + + if (graveyard) + { + uint32 graveyardId = graveyard->ID; + + GraveYardData const* data = sObjectMgr->FindGraveYardData(graveyardId, zone_id); + if (!data) + { + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDERROR, graveyardId); + handler->SetSentErrorMessage(true); + return false; + } + + team = data->team; + + std::string team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_NOTEAM); + + if (team == 0) + team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY); + else if (team == HORDE) + team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE); + else if (team == ALLIANCE) + team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE); + + handler->PSendSysMessage(LANG_COMMAND_GRAVEYARDNEAREST, graveyardId, team_name.c_str(), zone_id); + } + else + { + std::string team_name; + + if (team == 0) + team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ANY); + else if (team == HORDE) + team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_HORDE); + else if (team == ALLIANCE) + team_name = handler->GetTrinityString(LANG_COMMAND_GRAVEYARD_ALLIANCE); + + if (team == ~uint32(0)) + handler->PSendSysMessage(LANG_COMMAND_ZONENOGRAVEYARDS, zone_id); + else + handler->PSendSysMessage(LANG_COMMAND_ZONENOGRAFACTION, zone_id, team_name.c_str()); + } + + return true; + } + + static bool HandleExploreCheatCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + int32 flag = int32(atoi((char*)args)); + + Player* playerTarget = handler->getSelectedPlayer(); + if (!playerTarget) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + if (flag != 0) + { + handler->PSendSysMessage(LANG_YOU_SET_EXPLORE_ALL, handler->GetNameLink(playerTarget).c_str()); + if (handler->needReportToTarget(playerTarget)) + ChatHandler(playerTarget).PSendSysMessage(LANG_YOURS_EXPLORE_SET_ALL, handler->GetNameLink().c_str()); + } + else + { + handler->PSendSysMessage(LANG_YOU_SET_EXPLORE_NOTHING, handler->GetNameLink(playerTarget).c_str()); + if (handler->needReportToTarget(playerTarget)) + ChatHandler(playerTarget).PSendSysMessage(LANG_YOURS_EXPLORE_SET_NOTHING, handler->GetNameLink().c_str()); + } + + for (uint8 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i) + { + if (flag != 0) + handler->GetSession()->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0xFFFFFFFF); + else + handler->GetSession()->GetPlayer()->SetFlag(PLAYER_EXPLORED_ZONES_1+i, 0); + } + + return true; + } + + static bool HandleShowAreaCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* playerTarget = handler->getSelectedPlayer(); + if (!playerTarget) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + int32 area = GetAreaFlagByAreaID(atoi((char*)args)); + int32 offset = area / 32; + uint32 val = uint32((1 << (area % 32))); + + if (area<0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); + playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields | val))); + + handler->SendSysMessage(LANG_EXPLORE_AREA); + return true; + } + + static bool HandleHideAreaCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* playerTarget = handler->getSelectedPlayer(); + if (!playerTarget) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + int32 area = GetAreaFlagByAreaID(atoi((char*)args)); + int32 offset = area / 32; + uint32 val = uint32((1 << (area % 32))); + + if (area < 0 || offset >= PLAYER_EXPLORED_ZONES_SIZE) + { + handler->SendSysMessage(LANG_BAD_VALUE); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 currFields = playerTarget->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset); + playerTarget->SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, uint32((currFields ^ val))); + + handler->SendSysMessage(LANG_UNEXPLORE_AREA); + return true; + } + + static bool HandleAddItemCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + uint32 itemId = 0; + + if (args[0] == '[') // [name] manual form + { + char const* itemNameStr = strtok((char*)args, "]"); + + if (itemNameStr && itemNameStr[0]) + { + std::string itemName = itemNameStr+1; + WorldDatabase.EscapeString(itemName); + + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_ITEM_TEMPLATE_BY_NAME); + stmt->setString(0, itemName); + PreparedQueryResult result = WorldDatabase.Query(stmt); + + if (!result) + { + handler->PSendSysMessage(LANG_COMMAND_COULDNOTFIND, itemNameStr+1); + handler->SetSentErrorMessage(true); + return false; + } + itemId = result->Fetch()->GetUInt32(); + } + else + return false; + } + else // item_id or [name] Shift-click form |color|Hitem:item_id:0:0:0|h[name]|h|r + { + char const* id = handler->extractKeyFromLink((char*)args, "Hitem"); + if (!id) + return false; + itemId = uint32(atol(id)); + } + + char const* ccount = strtok(NULL, " "); + + int32 count = 1; + + if (ccount) + count = strtol(ccount, NULL, 10); + + if (count == 0) + count = 1; + + Player* player = handler->GetSession()->GetPlayer(); + Player* playerTarget = handler->getSelectedPlayer(); + if (!playerTarget) + playerTarget = player; + + sLog->outDebug(LOG_FILTER_GENERAL, handler->GetTrinityString(LANG_ADDITEM), itemId, count); + + ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId); + if (!itemTemplate) + { + handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); + handler->SetSentErrorMessage(true); + return false; + } + + // Subtract + if (count < 0) + { + playerTarget->DestroyItemCount(itemId, -count, true, false); + handler->PSendSysMessage(LANG_REMOVEITEM, itemId, -count, handler->GetNameLink(playerTarget).c_str()); + return true; + } + + // Adding items + uint32 noSpaceForCount = 0; + + // check space and find places + ItemPosCountVec dest; + InventoryResult msg = playerTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, count, &noSpaceForCount); + if (msg != EQUIP_ERR_OK) // convert to possible store amount + count -= noSpaceForCount; + + if (count == 0 || dest.empty()) // can't add any + { + handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); + handler->SetSentErrorMessage(true); + return false; + } + + Item* item = playerTarget->StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId)); + + // remove binding (let GM give it to another player later) + if (player == playerTarget) + for (ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr) + if (Item* item1 = player->GetItemByPos(itr->pos)) + item1->SetBinding(false); + + if (count > 0 && item) + { + player->SendNewItem(item, count, false, true); + if (player != playerTarget) + playerTarget->SendNewItem(item, count, true, false); + } + + if (noSpaceForCount > 0) + handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itemId, noSpaceForCount); + + return true; + } + + static bool HandleAddItemSetCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + char const* id = handler->extractKeyFromLink((char*)args, "Hitemset"); // number or [name] Shift-click form |color|Hitemset:itemset_id|h[name]|h|r + if (!id) + return false; + + uint32 itemSetId = atol(id); + + // prevent generation all items with itemset field value '0' + if (itemSetId == 0) + { + handler->PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND, itemSetId); + handler->SetSentErrorMessage(true); + return false; + } + + Player* player = handler->GetSession()->GetPlayer(); + Player* playerTarget = handler->getSelectedPlayer(); + if (!playerTarget) + playerTarget = player; + + sLog->outDebug(LOG_FILTER_GENERAL, handler->GetTrinityString(LANG_ADDITEMSET), itemSetId); + + bool found = false; + ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore(); + for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr) + { + if (itr->second.ItemSet == itemSetId) + { + found = true; + ItemPosCountVec dest; + InventoryResult msg = playerTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itr->second.ItemId, 1); + if (msg == EQUIP_ERR_OK) + { + Item* item = playerTarget->StoreNewItem(dest, itr->second.ItemId, true); + + // remove binding (let GM give it to another player later) + if (player == playerTarget) + item->SetBinding(false); + + player->SendNewItem(item, 1, false, true); + if (player != playerTarget) + playerTarget->SendNewItem(item, 1, true, false); + } + else + { + player->SendEquipError(msg, NULL, NULL, itr->second.ItemId); + handler->PSendSysMessage(LANG_ITEM_CANNOT_CREATE, itr->second.ItemId, 1); + } + } + } + + if (!found) + { + handler->PSendSysMessage(LANG_NO_ITEMS_FROM_ITEMSET_FOUND, itemSetId); + handler->SetSentErrorMessage(true); + return false; + } + + return true; + } + + static bool HandleBankCommand(ChatHandler* handler, char const* /*args*/) + { + handler->GetSession()->SendShowBank(handler->GetSession()->GetPlayer()->GetGUID()); + return true; + } + + static bool HandleChangeWeather(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + // Weather is OFF + if (!sWorld->getBoolConfig(CONFIG_WEATHER)) + { + handler->SendSysMessage(LANG_WEATHER_DISABLED); + handler->SetSentErrorMessage(true); + return false; + } + + // *Change the weather of a cell + char const* px = strtok((char*)args, " "); + char const* py = strtok(NULL, " "); + + if (!px || !py) + return false; + + uint32 type = uint32(atoi(px)); //0 to 3, 0: fine, 1: rain, 2: snow, 3: sand + float grade = float(atof(py)); //0 to 1, sending -1 is instand good weather + + Player* player = handler->GetSession()->GetPlayer(); + uint32 zoneid = player->GetZoneId(); + + Weather* weather = WeatherMgr::FindWeather(zoneid); + + if (!weather) + weather = WeatherMgr::AddWeather(zoneid); + if (!weather) + { + handler->SendSysMessage(LANG_NO_WEATHER); + handler->SetSentErrorMessage(true); + return false; + } + + weather->SetWeather(WeatherType(type), grade); + + return true; + } + + + static bool HandleMaxSkillCommand(ChatHandler* handler, char const* /*args*/) + { + Player* SelectedPlayer = handler->getSelectedPlayer(); + if (!SelectedPlayer) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // each skills that have max skill value dependent from level seted to current level max skill value + SelectedPlayer->UpdateSkillsToMaxSkillsForLevel(); + return true; + } + + static bool HandleSetSkillCommand(ChatHandler* handler, char const* args) + { + // number or [name] Shift-click form |color|Hskill:skill_id|h[name]|h|r + char const* skillStr = handler->extractKeyFromLink((char*)args, "Hskill"); + if (!skillStr) + return false; + + char const* levelStr = strtok(NULL, " "); + if (!levelStr) + return false; + + char const* maxPureSkill = strtok(NULL, " "); + + int32 skill = atoi(skillStr); + if (skill <= 0) + { + handler->PSendSysMessage(LANG_INVALID_SKILL_ID, skill); + handler->SetSentErrorMessage(true); + return false; + } + + int32 level = uint32(atol(levelStr)); + + Player* target = handler->getSelectedPlayer(); + if (!target) + { + handler->SendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + SkillLineEntry const* skillLine = sSkillLineStore.LookupEntry(skill); + if (!skillLine) + { + handler->PSendSysMessage(LANG_INVALID_SKILL_ID, skill); + handler->SetSentErrorMessage(true); + return false; + } + + std::string tNameLink = handler->GetNameLink(target); + + if (!target->GetSkillValue(skill)) + { + handler->PSendSysMessage(LANG_SET_SKILL_ERROR, tNameLink.c_str(), skill, skillLine->name[handler->GetSessionDbcLocale()]); + handler->SetSentErrorMessage(true); + return false; + } + + uint16 max = maxPureSkill ? atol (maxPureSkill) : target->GetPureMaxSkillValue(skill); + + if (level <= 0 || level > max || max <= 0) + return false; + + target->SetSkill(skill, target->GetSkillStep(skill), level, max); + handler->PSendSysMessage(LANG_SET_SKILL, skill, skillLine->name[handler->GetSessionDbcLocale()], tNameLink.c_str(), level, max); + + return true; + } + // show info of player + static bool HandlePInfoCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + std::string targetName; + + uint32 parseGUID = MAKE_NEW_GUID(atol((char*)args), 0, HIGHGUID_PLAYER); + + if (sObjectMgr->GetPlayerNameByGUID(parseGUID, targetName)) + { + target = sObjectMgr->GetPlayerByLowGUID(parseGUID); + targetGuid = parseGUID; + } + else if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + uint32 accId = 0; + uint32 money = 0; + uint32 totalPlayerTime = 0; + uint8 level = 0; + uint32 latency = 0; + uint8 race; + uint8 Class; + int64 muteTime = 0; + int64 banTime = -1; + uint32 mapId; + uint32 areaId; + uint32 phase = 0; + + // get additional information from Player object + if (target) + { + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + accId = target->GetSession()->GetAccountId(); + money = target->GetMoney(); + totalPlayerTime = target->GetTotalPlayedTime(); + level = target->getLevel(); + latency = target->GetSession()->GetLatency(); + race = target->getRace(); + Class = target->getClass(); + muteTime = target->GetSession()->m_muteTime; + mapId = target->GetMapId(); + areaId = target->GetAreaId(); + phase = target->GetPhaseMask(); + } + // get additional information from DB + else + { + // check offline security + if (handler->HasLowerSecurity(NULL, targetGuid)) + return false; + + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PINFO); + stmt->setUInt32(0, GUID_LOPART(targetGuid)); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + + if (!result) + return false; + + Field* fields = result->Fetch(); + totalPlayerTime = fields[0].GetUInt32(); + level = fields[1].GetUInt8(); + money = fields[2].GetUInt32(); + accId = fields[3].GetUInt32(); + race = fields[4].GetUInt8(); + Class = fields[5].GetUInt8(); + mapId = fields[6].GetUInt16(); + areaId = fields[7].GetUInt16(); + } + + std::string userName = handler->GetTrinityString(LANG_ERROR); + std::string eMail = handler->GetTrinityString(LANG_ERROR); + std::string lastIp = handler->GetTrinityString(LANG_ERROR); + uint32 security = 0; + std::string lastLogin = handler->GetTrinityString(LANG_ERROR); + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO); + stmt->setInt32(0, int32(realmID)); + stmt->setUInt32(1, accId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + if (result) + { + Field* fields = result->Fetch(); + userName = fields[0].GetString(); + security = fields[1].GetUInt8(); + eMail = fields[2].GetString(); + muteTime = fields[5].GetUInt64(); + + if (eMail.empty()) + eMail = "-"; + + if (!handler->GetSession() || handler->GetSession()->GetSecurity() >= AccountTypes(security)) + { + lastIp = fields[3].GetString(); + lastLogin = fields[4].GetString(); + + uint32 ip = inet_addr(lastIp.c_str()); +#if TRINITY_ENDIAN == BIGENDIAN + EndianConvertReverse(ip); +#endif + + PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_IP2NATION_COUNTRY); + + stmt->setUInt32(0, ip); + + PreparedQueryResult result2 = WorldDatabase.Query(stmt); + + if (result2) + { + Field* fields2 = result2->Fetch(); + lastIp.append(" ("); + lastIp.append(fields2[0].GetString()); + lastIp.append(")"); + } + } + else + { + lastIp = "-"; + lastLogin = "-"; + } + } + + std::string nameLink = handler->playerLink(targetName); + + handler->PSendSysMessage(LANG_PINFO_ACCOUNT, (target ? "" : handler->GetTrinityString(LANG_OFFLINE)), nameLink.c_str(), GUID_LOPART(targetGuid), userName.c_str(), accId, eMail.c_str(), security, lastIp.c_str(), lastLogin.c_str(), latency); + + std::string bannedby = "unknown"; + std::string banreason = ""; + + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PINFO_BANS); + stmt->setUInt32(0, accId); + PreparedQueryResult result2 = LoginDatabase.Query(stmt); + if (!result2) + { + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PINFO_BANS); + stmt->setUInt32(0, GUID_LOPART(targetGuid)); + result2 = CharacterDatabase.Query(stmt); + } + + if (result2) + { + Field* fields = result2->Fetch(); + banTime = int64(fields[1].GetBool() ? 0 : fields[0].GetUInt32()); + bannedby = fields[2].GetString(); + banreason = fields[3].GetString(); + } + + if (muteTime > 0) + handler->PSendSysMessage(LANG_PINFO_MUTE, secsToTimeString(muteTime - time(NULL), true).c_str()); + + if (banTime >= 0) + handler->PSendSysMessage(LANG_PINFO_BAN, banTime > 0 ? secsToTimeString(banTime - time(NULL), true).c_str() : "permanently", bannedby.c_str(), banreason.c_str()); + + std::string raceStr, ClassStr; + switch (race) + { + case RACE_HUMAN: + raceStr = "Human"; + break; + case RACE_ORC: + raceStr = "Orc"; + break; + case RACE_DWARF: + raceStr = "Dwarf"; + break; + case RACE_NIGHTELF: + raceStr = "Night Elf"; + break; + case RACE_UNDEAD_PLAYER: + raceStr = "Undead"; + break; + case RACE_TAUREN: + raceStr = "Tauren"; + break; + case RACE_GNOME: + raceStr = "Gnome"; + break; + case RACE_TROLL: + raceStr = "Troll"; + break; + case RACE_BLOODELF: + raceStr = "Blood Elf"; + break; + case RACE_DRAENEI: + raceStr = "Draenei"; + break; + } + + switch (Class) + { + case CLASS_WARRIOR: + ClassStr = "Warrior"; + break; + case CLASS_PALADIN: + ClassStr = "Paladin"; + break; + case CLASS_HUNTER: + ClassStr = "Hunter"; + break; + case CLASS_ROGUE: + ClassStr = "Rogue"; + break; + case CLASS_PRIEST: + ClassStr = "Priest"; + break; + case CLASS_DEATH_KNIGHT: + ClassStr = "Death Knight"; + break; + case CLASS_SHAMAN: + ClassStr = "Shaman"; + break; + case CLASS_MAGE: + ClassStr = "Mage"; + break; + case CLASS_WARLOCK: + ClassStr = "Warlock"; + break; + case CLASS_DRUID: + ClassStr = "Druid"; + break; + } + + std::string timeStr = secsToTimeString(totalPlayerTime, true, true); + uint32 gold = money /GOLD; + uint32 silv = (money % GOLD) / SILVER; + uint32 copp = (money % GOLD) % SILVER; + handler->PSendSysMessage(LANG_PINFO_LEVEL, raceStr.c_str(), ClassStr.c_str(), timeStr.c_str(), level, gold, silv, copp); + + // Add map, zone, subzone and phase to output + int locale = handler->GetSessionDbcLocale(); + std::string areaName = ""; + std::string zoneName = ""; + + MapEntry const* map = sMapStore.LookupEntry(mapId); + + AreaTableEntry const* area = GetAreaEntryByAreaID(areaId); + if (area) + { + areaName = area->area_name[locale]; + + AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone); + if (zone) + zoneName = zone->area_name[locale]; + } + + if (target) + { + if (!zoneName.empty()) + handler->PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name[locale], zoneName.c_str(), areaName.c_str(), phase); + else + handler->PSendSysMessage(LANG_PINFO_MAP_ONLINE, map->name[locale], areaName.c_str(), "", phase); + } + else + handler->PSendSysMessage(LANG_PINFO_MAP_OFFLINE, map->name[locale], areaName.c_str()); + + return true; + } + + static bool HandleRespawnCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + // accept only explicitly selected target (not implicitly self targeting case) + Unit* target = handler->getSelectedUnit(); + if (player->GetSelection() && target) + { + if (target->GetTypeId() != TYPEID_UNIT || target->isPet()) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (target->isDead()) + target->ToCreature()->Respawn(); + return true; + } + + CellCoord p(Trinity::ComputeCellCoord(player->GetPositionX(), player->GetPositionY())); + Cell cell(p); + cell.SetNoCreate(); + + Trinity::RespawnDo u_do; + Trinity::WorldObjectWorker worker(player, u_do); + + TypeContainerVisitor, GridTypeMapContainer > obj_worker(worker); + cell.Visit(p, obj_worker, *player->GetMap(), *player, player->GetGridActivationRange()); + + return true; + } + // mute player for some times + static bool HandleMuteCommand(ChatHandler* handler, char const* args) + { + char* nameStr; + char* delayStr; + handler->extractOptFirstArg((char*)args, &nameStr, &delayStr); + if (!delayStr) + return false; + + char const* muteReason = strtok(NULL, "\r"); + std::string muteReasonStr = "No reason"; + if (muteReason != NULL) + muteReasonStr = muteReason; + + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget(nameStr, &target, &targetGuid, &targetName)) + return false; + + uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(targetGuid); + + // find only player from same account if any + if (!target) + if (WorldSession* session = sWorld->FindSession(accountId)) + target = session->GetPlayer(); + + uint32 notSpeakTime = uint32(atoi(delayStr)); + + // must have strong lesser security level + if (handler->HasLowerSecurity (target, targetGuid, true)) + return false; + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); + + if (target) + { + // Target is online, mute will be in effect right away. + int64 muteTime = time(NULL) + notSpeakTime * MINUTE; + target->GetSession()->m_muteTime = muteTime; + stmt->setInt64(0, muteTime); + ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notSpeakTime, muteReasonStr.c_str()); + } + else + { + // Target is offline, mute will be in effect starting from the next login. + int32 muteTime = -int32(notSpeakTime * MINUTE); + stmt->setInt64(0, muteTime); + } + + stmt->setUInt32(1, accountId); + LoginDatabase.Execute(stmt); + std::string nameLink = handler->playerLink(targetName); + + handler->PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, nameLink.c_str(), notSpeakTime, muteReasonStr.c_str()); + + return true; + } + + // unmute player + static bool HandleUnmuteCommand(ChatHandler* handler, char const* args) + { + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(targetGuid); + + // find only player from same account if any + if (!target) + if (WorldSession* session = sWorld->FindSession(accountId)) + target = session->GetPlayer(); + + // must have strong lesser security level + if (handler->HasLowerSecurity (target, targetGuid, true)) + return false; + + if (target) + { + if (target->CanSpeak()) + { + handler->SendSysMessage(LANG_CHAT_ALREADY_ENABLED); + handler->SetSentErrorMessage(true); + return false; + } + + target->GetSession()->m_muteTime = 0; + } + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); + stmt->setInt64(0, 0); + stmt->setUInt32(1, accountId); + LoginDatabase.Execute(stmt); + + if (target) + ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_ENABLED); + + std::string nameLink = handler->playerLink(targetName); + + handler->PSendSysMessage(LANG_YOU_ENABLE_CHAT, nameLink.c_str()); + + return true; + } + + + static bool HandleMovegensCommand(ChatHandler* handler, char const* /*args*/) + { + Unit* unit = handler->getSelectedUnit(); + if (!unit) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + handler->PSendSysMessage(LANG_MOVEGENS_LIST, (unit->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), unit->GetGUIDLow()); + + MotionMaster* motionMaster = unit->GetMotionMaster(); + float x, y, z; + motionMaster->GetDestination(x, y, z); + + for (uint8 i = 0; i < MAX_MOTION_SLOT; ++i) + { + MovementGenerator* movementGenerator = motionMaster->GetMotionSlot(i); + if (!movementGenerator) + { + handler->SendSysMessage("Empty"); + continue; + } + + switch (movementGenerator->GetMovementGeneratorType()) + { + case IDLE_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_IDLE); + break; + case RANDOM_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_RANDOM); + break; + case WAYPOINT_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_WAYPOINT); + break; + case ANIMAL_RANDOM_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); + break; + case CONFUSED_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_CONFUSED); + break; + case CHASE_MOTION_TYPE: + { + Unit* target = NULL; + if (unit->GetTypeId() == TYPEID_PLAYER) + target = static_cast const*>(movementGenerator)->GetTarget(); + else + target = static_cast const*>(movementGenerator)->GetTarget(); + + if (!target) + handler->SendSysMessage(LANG_MOVEGENS_CHASE_NULL); + else if (target->GetTypeId() == TYPEID_PLAYER) + handler->PSendSysMessage(LANG_MOVEGENS_CHASE_PLAYER, target->GetName(), target->GetGUIDLow()); + else + handler->PSendSysMessage(LANG_MOVEGENS_CHASE_CREATURE, target->GetName(), target->GetGUIDLow()); + break; + } + case FOLLOW_MOTION_TYPE: + { + Unit* target = NULL; + if (unit->GetTypeId() == TYPEID_PLAYER) + target = static_cast const*>(movementGenerator)->GetTarget(); + else + target = static_cast const*>(movementGenerator)->GetTarget(); + + if (!target) + handler->SendSysMessage(LANG_MOVEGENS_FOLLOW_NULL); + else if (target->GetTypeId() == TYPEID_PLAYER) + handler->PSendSysMessage(LANG_MOVEGENS_FOLLOW_PLAYER, target->GetName(), target->GetGUIDLow()); + else + handler->PSendSysMessage(LANG_MOVEGENS_FOLLOW_CREATURE, target->GetName(), target->GetGUIDLow()); + break; + } + case HOME_MOTION_TYPE: + { + if (unit->GetTypeId() == TYPEID_UNIT) + handler->PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE, x, y, z); + else + handler->SendSysMessage(LANG_MOVEGENS_HOME_PLAYER); + break; + } + case FLIGHT_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_FLIGHT); + break; + case POINT_MOTION_TYPE: + { + handler->PSendSysMessage(LANG_MOVEGENS_POINT, x, y, z); + break; + } + case FLEEING_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_FEAR); + break; + case DISTRACT_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_DISTRACT); + break; + case EFFECT_MOTION_TYPE: + handler->SendSysMessage(LANG_MOVEGENS_EFFECT); + break; + default: + handler->PSendSysMessage(LANG_MOVEGENS_UNKNOWN, movementGenerator->GetMovementGeneratorType()); + break; + } + } + return true; + } + /* + ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator + Without this function 3rd party scripting library will get linking errors (unresolved external) + when attempting to use the PointMovementGenerator + */ + static bool HandleComeToMeCommand(ChatHandler* handler, char const* args) + { + char const* newFlagStr = strtok((char*)args, " "); + if (!newFlagStr) + return false; + + Creature* caster = handler->getSelectedCreature(); + if (!caster) + { + handler->SendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + Player* player = handler->GetSession()->GetPlayer(); + + caster->GetMotionMaster()->MovePoint(0, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); + + return true; + } + + static bool HandleDamageCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Unit* target = handler->getSelectedUnit(); + if (!target || !handler->GetSession()->GetPlayer()->GetSelection()) + { + handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + if (target->GetTypeId() == TYPEID_PLAYER) + { + if (handler->HasLowerSecurity((Player*)target, 0, false)) + return false; + } + + if (!target->isAlive()) + return true; + + char* damageStr = strtok((char*)args, " "); + if (!damageStr) + return false; + + int32 damage_int = atoi((char*)damageStr); + if (damage_int <= 0) + return true; + + uint32 damage = damage_int; + + char* schoolStr = strtok((char*)NULL, " "); + + // flat melee damage without resistence/etc reduction + if (!schoolStr) + { + handler->GetSession()->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + if (target != handler->GetSession()->GetPlayer()) + handler->GetSession()->GetPlayer()->SendAttackStateUpdate (HITINFO_AFFECTS_VICTIM, target, 1, SPELL_SCHOOL_MASK_NORMAL, damage, 0, 0, VICTIMSTATE_HIT, 0); + return true; + } + + uint32 school = schoolStr ? atoi((char*)schoolStr) : SPELL_SCHOOL_NORMAL; + if (school >= MAX_SPELL_SCHOOL) + return false; + + SpellSchoolMask schoolmask = SpellSchoolMask(1 << school); + + if (Unit::IsDamageReducedByArmor(schoolmask)) + damage = handler->GetSession()->GetPlayer()->CalcArmorReducedDamage(target, damage, NULL, BASE_ATTACK); + + char* spellStr = strtok((char*)NULL, " "); + + // melee damage by specific school + if (!spellStr) + { + uint32 absorb = 0; + uint32 resist = 0; + + handler->GetSession()->GetPlayer()->CalcAbsorbResist(target, schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist); + + if (damage <= absorb + resist) + return true; + + damage -= absorb + resist; + + handler->GetSession()->GetPlayer()->DealDamageMods(target, damage, &absorb); + handler->GetSession()->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false); + handler->GetSession()->GetPlayer()->SendAttackStateUpdate (HITINFO_AFFECTS_VICTIM, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_HIT, 0); + return true; + } + + // non-melee damage + + // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form + uint32 spellid = handler->extractSpellIdFromLink((char*)args); + if (!spellid || !sSpellMgr->GetSpellInfo(spellid)) + return false; + + handler->GetSession()->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage); + return true; + } + + static bool HandleCombatStopCommand(ChatHandler* handler, char const* args) + { + Player* target = NULL; + + if (args && strlen(args) > 0) + { + target = sObjectAccessor->FindPlayerByName(args); + if (!target) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + } + + if (!target) + { + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + } + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + target->CombatStop(); + target->getHostileRefManager().deleteReferences(); + return true; + } + + static bool HandleFlushArenaPointsCommand(ChatHandler* /*handler*/, char const* /*args*/) + { + sArenaTeamMgr->DistributeArenaPoints(); + return true; + } + + static bool HandleRepairitemsCommand(ChatHandler* handler, char const* args) + { + Player* target; + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + + // check online security + if (handler->HasLowerSecurity(target, 0)) + return false; + + // Repair items + target->DurabilityRepairAll(false, 0, false); + + handler->PSendSysMessage(LANG_YOU_REPAIR_ITEMS, handler->GetNameLink(target).c_str()); + if (handler->needReportToTarget(target)) + ChatHandler(target).PSendSysMessage(LANG_YOUR_ITEMS_REPAIRED, handler->GetNameLink().c_str()); + + return true; + } + + static bool HandleWaterwalkCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* player = handler->getSelectedPlayer(); + if (!player) + { + handler->PSendSysMessage(LANG_NO_CHAR_SELECTED); + handler->SetSentErrorMessage(true); + return false; + } + + // check online security + if (handler->HasLowerSecurity(player, 0)) + return false; + + if (strncmp(args, "on", 3) == 0) + player->SetMovement(MOVE_WATER_WALK); // ON + else if (strncmp(args, "off", 4) == 0) + player->SetMovement(MOVE_LAND_WALK); // OFF + else + { + handler->SendSysMessage(LANG_USE_BOL); + return false; + } + + handler->PSendSysMessage(LANG_YOU_SET_WATERWALK, args, handler->GetNameLink(player).c_str()); + if (handler->needReportToTarget(player)) + ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, handler->GetNameLink().c_str()); + return true; + } + + // Send mail by command + static bool HandleSendMailCommand(ChatHandler* handler, char const* args) + { + // format: name "subject text" "mail text" + Player* target; + uint64 targetGuid; + std::string targetName; + if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName)) + return false; + + char* tail1 = strtok(NULL, ""); + if (!tail1) + return false; + + char const* msgSubject = handler->extractQuotedArg(tail1); + if (!msgSubject) + return false; + + char* tail2 = strtok(NULL, ""); + if (!tail2) + return false; + + char const* msgText = handler->extractQuotedArg(tail2); + if (!msgText) + return false; + + // msgSubject, msgText isn't NUL after prev. check + std::string subject = msgSubject; + std::string text = msgText; + + // from console show not existed sender + MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); + + //- TODO: Fix poor design + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + MailDraft(subject, text) + .SendMailTo(trans, MailReceiver(target, GUID_LOPART(targetGuid)), sender); + + CharacterDatabase.CommitTransaction(trans); + + std::string nameLink = handler->playerLink(targetName); + handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); + return true; + } + // Send items by mail + static bool HandleSendItemsCommand(ChatHandler* handler, char const* args) + { + // format: name "subject text" "mail text" item1[:count1] item2[:count2] ... item12[:count12] + Player* receiver; + uint64 receiverGuid; + std::string receiverName; + if (!handler->extractPlayerTarget((char*)args, &receiver, &receiverGuid, &receiverName)) + return false; + + char* tail1 = strtok(NULL, ""); + if (!tail1) + return false; + + char const* msgSubject = handler->extractQuotedArg(tail1); + if (!msgSubject) + return false; + + char* tail2 = strtok(NULL, ""); + if (!tail2) + return false; + + char const* msgText = handler->extractQuotedArg(tail2); + if (!msgText) + return false; + + // msgSubject, msgText isn't NUL after prev. check + std::string subject = msgSubject; + std::string text = msgText; + + // extract items + typedef std::pair ItemPair; + typedef std::list< ItemPair > ItemPairs; + ItemPairs items; + + // get all tail string + char* tail = strtok(NULL, ""); + + // get from tail next item str + while (char* itemStr = strtok(tail, " ")) + { + // and get new tail + tail = strtok(NULL, ""); + + // parse item str + char const* itemIdStr = strtok(itemStr, ":"); + char const* itemCountStr = strtok(NULL, " "); + + uint32 itemId = atoi(itemIdStr); + if (!itemId) + return false; + + ItemTemplate const* item_proto = sObjectMgr->GetItemTemplate(itemId); + if (!item_proto) + { + handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 itemCount = itemCountStr ? atoi(itemCountStr) : 1; + if (itemCount < 1 || (item_proto->MaxCount > 0 && itemCount > uint32(item_proto->MaxCount))) + { + handler->PSendSysMessage(LANG_COMMAND_INVALID_ITEM_COUNT, itemCount, itemId); + handler->SetSentErrorMessage(true); + return false; + } + + while (itemCount > item_proto->GetMaxStackSize()) + { + items.push_back(ItemPair(itemId, item_proto->GetMaxStackSize())); + itemCount -= item_proto->GetMaxStackSize(); + } + + items.push_back(ItemPair(itemId, itemCount)); + + if (items.size() > MAX_MAIL_ITEMS) + { + handler->PSendSysMessage(LANG_COMMAND_MAIL_ITEMS_LIMIT, MAX_MAIL_ITEMS); + handler->SetSentErrorMessage(true); + return false; + } + } + + // from console show not existed sender + MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); + + // fill mail + MailDraft draft(subject, text); + + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + + for (ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr) + { + if (Item* item = Item::CreateItem(itr->first, itr->second, handler->GetSession() ? handler->GetSession()->GetPlayer() : 0)) + { + item->SaveToDB(trans); // save for prevent lost at next mail load, if send fail then item will deleted + draft.AddItem(item); + } + } + + draft.SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiverGuid)), sender); + CharacterDatabase.CommitTransaction(trans); + + std::string nameLink = handler->playerLink(receiverName); + handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); + return true; + } + /// Send money by mail + static bool HandleSendMoneyCommand(ChatHandler* handler, char const* args) + { + /// format: name "subject text" "mail text" money + + Player* receiver; + uint64 receiverGuid; + std::string receiverName; + if (!handler->extractPlayerTarget((char*)args, &receiver, &receiverGuid, &receiverName)) + return false; + + char* tail1 = strtok(NULL, ""); + if (!tail1) + return false; + + char* msgSubject = handler->extractQuotedArg(tail1); + if (!msgSubject) + return false; + + char* tail2 = strtok(NULL, ""); + if (!tail2) + return false; + + char* msgText = handler->extractQuotedArg(tail2); + if (!msgText) + return false; + + char* moneyStr = strtok(NULL, ""); + int32 money = moneyStr ? atoi(moneyStr) : 0; + if (money <= 0) + return false; + + // msgSubject, msgText isn't NUL after prev. check + std::string subject = msgSubject; + std::string text = msgText; + + // from console show not existed sender + MailSender sender(MAIL_NORMAL, handler->GetSession() ? handler->GetSession()->GetPlayer()->GetGUIDLow() : 0, MAIL_STATIONERY_GM); + + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + + MailDraft(subject, text) + .AddMoney(money) + .SendMailTo(trans, MailReceiver(receiver, GUID_LOPART(receiverGuid)), sender); + + CharacterDatabase.CommitTransaction(trans); + + std::string nameLink = handler->playerLink(receiverName); + handler->PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str()); + return true; + } + /// Send a message to a player in game + static bool HandleSendMessageCommand(ChatHandler* handler, char const* args) + { + /// - Find the player + Player* player; + if (!handler->extractPlayerTarget((char*)args, &player)) + return false; + + char* msgStr = strtok(NULL, ""); + if (!msgStr) + return false; + + ///- Check that he is not logging out. + if (player->GetSession()->isLogingOut()) + { + handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); + handler->SetSentErrorMessage(true); + return false; + } + + /// - Send the message + // Use SendAreaTriggerMessage for fastest delivery. + player->GetSession()->SendAreaTriggerMessage("%s", msgStr); + player->GetSession()->SendAreaTriggerMessage("|cffff0000[Message from administrator]:|r"); + + // Confirmation message + std::string nameLink = handler->GetNameLink(player); + handler->PSendSysMessage(LANG_SENDMESSAGE, nameLink.c_str(), msgStr); + + return true; + } + + static bool HandleCreatePetCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + Creature* creatureTarget = handler->getSelectedCreature(); + + if (!creatureTarget || creatureTarget->isPet() || creatureTarget->GetTypeId() == TYPEID_PLAYER) + { + handler->PSendSysMessage(LANG_SELECT_CREATURE); + handler->SetSentErrorMessage(true); + return false; + } + + CreatureTemplate const* creatrueTemplate = sObjectMgr->GetCreatureTemplate(creatureTarget->GetEntry()); + // Creatures with family 0 crashes the server + if (!creatrueTemplate->family) + { + handler->PSendSysMessage("This creature cannot be tamed. (family id: 0)."); + handler->SetSentErrorMessage(true); + return false; + } + + if (player->GetPetGUID()) + { + handler->PSendSysMessage("You already have a pet"); + handler->SetSentErrorMessage(true); + return false; + } + + // Everything looks OK, create new pet + Pet* pet = new Pet(player, HUNTER_PET); + if (!pet->CreateBaseAtCreature(creatureTarget)) + { + delete pet; + handler->PSendSysMessage("Error 1"); + return false; + } + + creatureTarget->setDeathState(JUST_DIED); + creatureTarget->RemoveCorpse(); + creatureTarget->SetHealth(0); // just for nice GM-mode view + + pet->SetUInt64Value(UNIT_FIELD_CREATEDBY, player->GetGUID()); + pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, player->getFaction()); + + if (!pet->InitStatsForLevel(creatureTarget->getLevel())) + { + sLog->outError(LOG_FILTER_GENERAL, "InitStatsForLevel() in EffectTameCreature failed! Pet deleted."); + handler->PSendSysMessage("Error 2"); + delete pet; + return false; + } + + // prepare visual effect for levelup + pet->SetUInt32Value(UNIT_FIELD_LEVEL, creatureTarget->getLevel()-1); + + pet->GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true); + // this enables pet details window (Shift+P) + pet->InitPetCreateSpells(); + pet->SetFullHealth(); + + pet->GetMap()->AddToMap(pet->ToCreature()); + + // visual effect for levelup + pet->SetUInt32Value(UNIT_FIELD_LEVEL, creatureTarget->getLevel()); + + player->SetMinion(pet, true); + pet->SavePetToDB(PET_SAVE_AS_CURRENT); + player->PetSpellInitialize(); + + return true; + } + + static bool HandlePetLearnCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* player = handler->GetSession()->GetPlayer(); + Pet* pet = player->GetPet(); + + if (!pet) + { + handler->PSendSysMessage("You have no pet"); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + + if (!spellId || !sSpellMgr->GetSpellInfo(spellId)) + return false; + + // Check if pet already has it + if (pet->HasSpell(spellId)) + { + handler->PSendSysMessage("Pet already has spell: %u", spellId); + handler->SetSentErrorMessage(true); + return false; + } + + // Check if spell is valid + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); + if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo)) + { + handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId); + handler->SetSentErrorMessage(true); + return false; + } + + pet->learnSpell(spellId); + + handler->PSendSysMessage("Pet has learned spell %u", spellId); + return true; + } + + static bool HandlePetUnlearnCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + Player* player = handler->GetSession()->GetPlayer(); + Pet* pet = player->GetPet(); + if (!pet) + { + handler->PSendSysMessage("You have no pet"); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 spellId = handler->extractSpellIdFromLink((char*)args); + + if (pet->HasSpell(spellId)) + pet->removeSpell(spellId, false); + else + handler->PSendSysMessage("Pet doesn't have that spell"); + + return true; + } + + static bool HandleFreezeCommand(ChatHandler* handler, char const* args) + { + std::string name; + Player* player; + char const* TargetName = strtok((char*)args, " "); // get entered name + if (!TargetName) // if no name entered use target + { + player = handler->getSelectedPlayer(); + if (player) //prevent crash with creature as target + { + name = player->GetName(); + normalizePlayerName(name); + } + } + else // if name entered + { + name = TargetName; + normalizePlayerName(name); + player = sObjectAccessor->FindPlayerByName(name.c_str()); + } + + if (!player) + { + handler->SendSysMessage(LANG_COMMAND_FREEZE_WRONG); + return true; + } + + if (player == handler->GetSession()->GetPlayer()) + { + handler->SendSysMessage(LANG_COMMAND_FREEZE_ERROR); + return true; + } + + // effect + if (player && (player != handler->GetSession()->GetPlayer())) + { + handler->PSendSysMessage(LANG_COMMAND_FREEZE, name.c_str()); + + // stop combat + make player unattackable + duel stop + stop some spells + player->setFaction(35); + player->CombatStop(); + if (player->IsNonMeleeSpellCasted(true)) + player->InterruptNonMeleeSpells(true); + player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + // if player class = hunter || warlock remove pet if alive + if ((player->getClass() == CLASS_HUNTER) || (player->getClass() == CLASS_WARLOCK)) + { + if (Pet* pet = player->GetPet()) + { + pet->SavePetToDB(PET_SAVE_AS_CURRENT); + // not let dismiss dead pet + if (pet && pet->isAlive()) + player->RemovePet(pet, PET_SAVE_NOT_IN_SLOT); + } + } + + if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(9454)) + Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, player, player); + + // save player + player->SaveToDB(); + } + + return true; + } + + static bool HandleUnFreezeCommand(ChatHandler* handler, char const*args) + { + std::string name; + Player* player; + char* targetName = strtok((char*)args, " "); // Get entered name + + if (targetName) + { + name = targetName; + normalizePlayerName(name); + player = sObjectAccessor->FindPlayerByName(name.c_str()); + } + else // If no name was entered - use target + { + player = handler->getSelectedPlayer(); + if (player) + name = player->GetName(); + } + + if (player) + { + handler->PSendSysMessage(LANG_COMMAND_UNFREEZE, name.c_str()); + + // Reset player faction + allow combat + allow duels + player->setFactionForRace(player->getRace()); + player->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + + // Remove Freeze spell (allowing movement and spells) + player->RemoveAurasDueToSpell(9454); + + // Save player + player->SaveToDB(); + } + else + { + if (targetName) + { + // Check for offline players + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_GUID_BY_NAME); + stmt->setString(0, name); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + + if (!result) + { + handler->SendSysMessage(LANG_COMMAND_FREEZE_WRONG); + return true; + } + + // If player found: delete his freeze aura + Field* fields = result->Fetch(); + uint32 lowGuid = fields[0].GetUInt32(); + + stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_AURA_FROZEN); + stmt->setUInt32(0, lowGuid); + CharacterDatabase.Execute(stmt); + + handler->PSendSysMessage(LANG_COMMAND_UNFREEZE, name.c_str()); + return true; + } + else + { + handler->SendSysMessage(LANG_COMMAND_FREEZE_WRONG); + return true; + } + } + + return true; + } + + static bool HandleListFreezeCommand(ChatHandler* handler, char const* /*args*/) + { + // Get names from DB + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_AURA_FROZEN); + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) + { + handler->SendSysMessage(LANG_COMMAND_NO_FROZEN_PLAYERS); + return true; + } + + // Header of the names + handler->PSendSysMessage(LANG_COMMAND_LIST_FREEZE); + + // Output of the results + do + { + Field* fields = result->Fetch(); + std::string player = fields[0].GetString(); + handler->PSendSysMessage(LANG_COMMAND_FROZEN_PLAYERS, player.c_str()); + } + while (result->NextRow()); + + return true; + } + + static bool HandleGroupLeaderCommand(ChatHandler* handler, char const* args) + { + Player* player = NULL; + Group* group = NULL; + uint64 guid = 0; + char* nameStr = strtok((char*)args, " "); + + if (handler->GetPlayerGroupAndGUIDByName(nameStr, player, group, guid)) + if (group && group->GetLeaderGUID() != guid) + { + group->ChangeLeader(guid); + group->SendUpdate(); + } + + return true; + } + + static bool HandleGroupDisbandCommand(ChatHandler* handler, char const* args) + { + Player* player = NULL; + Group* group = NULL; + uint64 guid = 0; + char* nameStr = strtok((char*)args, " "); + + if (handler->GetPlayerGroupAndGUIDByName(nameStr, player, group, guid)) + if (group) + group->Disband(); + + return true; + } + + static bool HandleGroupRemoveCommand(ChatHandler* handler, char const* args) + { + Player* player = NULL; + Group* group = NULL; + uint64 guid = 0; + char* nameStr = strtok((char*)args, " "); + + if (handler->GetPlayerGroupAndGUIDByName(nameStr, player, group, guid, true)) + if (group) + group->RemoveMember(guid); + + return true; + } + + static bool HandlePlayAllCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + uint32 soundId = atoi((char*)args); + + if (!sSoundEntriesStore.LookupEntry(soundId)) + { + handler->PSendSysMessage(LANG_SOUND_NOT_EXIST, soundId); + handler->SetSentErrorMessage(true); + return false; + } + + WorldPacket data(SMSG_PLAY_SOUND, 4); + data << uint32(soundId) << handler->GetSession()->GetPlayer()->GetGUID(); + sWorld->SendGlobalMessage(&data); + + handler->PSendSysMessage(LANG_COMMAND_PLAYED_TO_ALL, soundId); + return true; + } + + static bool HandlePossessCommand(ChatHandler* handler, char const* /*args*/) + { + Unit* unit = handler->getSelectedUnit(); + if (!unit) + return false; + + handler->GetSession()->GetPlayer()->CastSpell(unit, 530, true); + return true; + } + + static bool HandleUnPossessCommand(ChatHandler* handler, char const* /*args*/) + { + Unit* unit = handler->getSelectedUnit(); + if (!unit) + unit = handler->GetSession()->GetPlayer(); + + unit->RemoveCharmAuras(); + + return true; + } + + static bool HandleBindSightCommand(ChatHandler* handler, char const* /*args*/) + { + Unit* unit = handler->getSelectedUnit(); + if (!unit) + return false; + + handler->GetSession()->GetPlayer()->CastSpell(unit, 6277, true); + return true; + } + + static bool HandleUnbindSightCommand(ChatHandler* handler, char const* /*args*/) + { + Player* player = handler->GetSession()->GetPlayer(); + + if (player->isPossessing()) + return false; + + player->StopCastingBindSight(); + return true; + } +}; + +void AddSC_misc_commandscript() +{ + new misc_commandscript(); +} diff --git a/src/server/shared/Logging/AppenderDB.cpp b/src/server/shared/Logging/AppenderDB.cpp index 76abfca2d85..d85a4db9f7a 100644 --- a/src/server/shared/Logging/AppenderDB.cpp +++ b/src/server/shared/Logging/AppenderDB.cpp @@ -37,7 +37,7 @@ void AppenderDB::_write(LogMessage& message) case LOG_FILTER_SQL_DRIVER: case LOG_FILTER_SQL_DEV: break; // Avoid infinite loop, PExecute triggers Logging with LOG_FILTER_SQL type - default: + default: PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_LOG); stmt->setUInt64(0, message.mtime); stmt->setUInt32(1, realm); diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index 64f7e697f1f..8e740ba83b8 100755 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -109,7 +109,7 @@ void Log::CreateAppenderFromConfig(const char* name) if (++iter != tokens.end()) flags = AppenderFlags(atoi(*iter)); - + switch (type) { case APPENDER_CONSOLE: -- cgit v1.2.3 From d7a7a9800b734f71074da84338ba29a93009a198 Mon Sep 17 00:00:00 2001 From: Manuel Carrasco Date: Fri, 2 Mar 2012 22:00:26 -0300 Subject: Battlefield: Make sBattlefieldMgr a pointer. By Subv. --- src/server/game/Battlefield/Battlefield.cpp | 2 +- src/server/game/Battlefield/BattlefieldHandler.cpp | 6 +- src/server/game/Battlefield/BattlefieldMgr.h | 79 +++++++++ src/server/game/Entities/Object/Object.cpp | 8 + src/server/game/Entities/Player/Player.cpp | 10 +- src/server/game/Entities/Unit/Unit.cpp | 5 + src/server/game/Handlers/MiscHandler.cpp | 53 ++++++ src/server/game/Spells/Auras/SpellAuraEffects.cpp | 4 + src/server/game/Spells/Spell.cpp | 1 + src/server/game/Spells/SpellMgr.cpp | 4 +- src/server/game/World/World.cpp | 7 + src/server/scripts/Commands/cs_bf.cpp | 180 +++++++++++++++++++++ src/server/scripts/Northrend/wintergrasp.cpp | 14 +- 13 files changed, 359 insertions(+), 14 deletions(-) create mode 100644 src/server/game/Battlefield/BattlefieldMgr.h create mode 100644 src/server/scripts/Commands/cs_bf.cpp (limited to 'src/server/scripts/Commands') diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index 2e9e4607eec..f9c4e4736d4 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -494,7 +494,7 @@ void Battlefield::SendUpdateWorldState(uint32 field, uint32 value) void Battlefield::RegisterZone(uint32 zoneId) { - sBattlefieldMgr.AddZone(zoneId, this); + sBattlefieldMgr->AddZone(zoneId, this); } void Battlefield::HideNpc(Creature *p_Creature) diff --git a/src/server/game/Battlefield/BattlefieldHandler.cpp b/src/server/game/Battlefield/BattlefieldHandler.cpp index 7785fd3bff5..0b26ae8dc55 100644 --- a/src/server/game/Battlefield/BattlefieldHandler.cpp +++ b/src/server/game/Battlefield/BattlefieldHandler.cpp @@ -102,7 +102,7 @@ void WorldSession::HandleBfQueueInviteResponse(WorldPacket & recv_data) recv_data >> BattleId >> Accepted; sLog->outError("HandleQueueInviteResponse: BattleID:%u Accepted:%u", BattleId, Accepted); - Battlefield* Bf = sBattlefieldMgr.GetBattlefieldByBattleId(BattleId); + Battlefield* Bf = sBattlefieldMgr->GetBattlefieldByBattleId(BattleId); if (!Bf) return; @@ -120,7 +120,7 @@ void WorldSession::HandleBfEntryInviteResponse(WorldPacket & recv_data) recv_data >> BattleId >> Accepted; sLog->outError("HandleBattlefieldInviteResponse: BattleID:%u Accepted:%u", BattleId, Accepted); - Battlefield* Bf = sBattlefieldMgr.GetBattlefieldByBattleId(BattleId); + Battlefield* Bf = sBattlefieldMgr->GetBattlefieldByBattleId(BattleId); if (!Bf) return; @@ -142,7 +142,7 @@ void WorldSession::HandleBfExitRequest(WorldPacket & recv_data) recv_data >> BattleId; sLog->outError("HandleBfExitRequest: BattleID:%u ", BattleId); - Battlefield* Bf = sBattlefieldMgr.GetBattlefieldByBattleId(BattleId); + Battlefield* Bf = sBattlefieldMgr->GetBattlefieldByBattleId(BattleId); if (!Bf) return; diff --git a/src/server/game/Battlefield/BattlefieldMgr.h b/src/server/game/Battlefield/BattlefieldMgr.h new file mode 100644 index 00000000000..a447d787be7 --- /dev/null +++ b/src/server/game/Battlefield/BattlefieldMgr.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2008-2010 TrinityCore + * Copyright (C) 2005-2009 MaNGOS + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef BATTLEFIELD_MGR_H_ +#define BATTLEFIELD_MGR_H_ + +#include "Battlefield.h" +#include "ace/Singleton.h" + +class Player; +class GameObject; +class Creature; +class ZoneScript; +struct GossipMenuItems; + +// class to handle player enter / leave / areatrigger / GO use events +class BattlefieldMgr +{ + public: + // ctor + BattlefieldMgr(); + // dtor + ~BattlefieldMgr(); + + // create battlefield events + void InitBattlefield(); + // called when a player enters an battlefield area + void HandlePlayerEnterZone(Player * plr, uint32 areaflag); + // called when player leaves an battlefield area + void HandlePlayerLeaveZone(Player * plr, uint32 areaflag); + // called when player resurrects + void HandlePlayerResurrects(Player * plr, uint32 areaflag); + // return assigned battlefield + Battlefield *GetBattlefieldToZoneId(uint32 zoneid); + Battlefield *GetBattlefieldByBattleId(uint32 battleid); + + ZoneScript *GetZoneScript(uint32 zoneId); + + void AddZone(uint32 zoneid, Battlefield * handle); + + void Update(uint32 diff); + + void HandleGossipOption(Player * player, uint64 guid, uint32 gossipid); + + bool CanTalkTo(Player * player, Creature * creature, GossipMenuItems gso); + + void HandleDropFlag(Player * plr, uint32 spellId); + + typedef std::vector < Battlefield * >BattlefieldSet; + typedef std::map < uint32 /* zoneid */ , Battlefield * >BattlefieldMap; + private: + // contains all initiated battlefield events + // used when initing / cleaning up + BattlefieldSet m_BattlefieldSet; + // maps the zone ids to an battlefield event + // used in player event handling + BattlefieldMap m_BattlefieldMap; + // update interval + uint32 m_UpdateTimer; +}; + +#define sBattlefieldMgr ACE_Singleton::instance() + +#endif diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index b910fee951b..b265648d0c4 100755 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2329,9 +2329,17 @@ void WorldObject::SetZoneScript() if (map->IsDungeon()) m_zoneScript = (ZoneScript*)((InstanceMap*)map)->GetInstanceScript(); else if (!map->IsBattlegroundOrArena()) + { + if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(GetZoneId())) m_zoneScript = sOutdoorPvPMgr->GetZoneScript(GetZoneId()); } } + m_zoneScript = bf; + else + m_zoneScript = sOutdoorPvPMgr->GetZoneScript(GetZoneId()); + } + } +} TempSummon* WorldObject::SummonCreature(uint32 entry, const Position &pos, TempSummonType spwtype, uint32 duration, uint32 /*vehId*/) const { diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 2814b7dba64..2cb38d615ac 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2405,6 +2405,7 @@ void Player::RemoveFromWorld() StopCastingBindSight(); UnsummonPetTemporaryIfAny(); sOutdoorPvPMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId); + sBattlefieldMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId); } ///- Do not add/remove the player from the object storage @@ -5493,7 +5494,12 @@ void Player::RepopAtGraveyard() if (Battleground* bg = GetBattleground()) ClosestGrave = bg->GetClosestGraveYard(this); else - ClosestGrave = sObjectMgr->GetClosestGraveYard(GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId(), GetTeam()); + { + if (sBattlefieldMgr->GetBattlefieldToZoneId(GetZoneId())) + ClosestGrave = sBattlefieldMgr->GetBattlefieldToZoneId(GetZoneId())->GetClosestGraveYard(this); + else + ClosestGrave = sObjectMgr->GetClosestGraveYard(GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId(), GetTeam()); + } // stop countdown until repop m_deathTimer = 0; @@ -7413,6 +7419,8 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) { sOutdoorPvPMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId); sOutdoorPvPMgr->HandlePlayerEnterZone(this, newZone); + sBattlefieldMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId); + sBattlefieldMgr->HandlePlayerEnterZone(this, newZone); SendInitWorldStates(newZone, newArea); // only if really enters to new zone, not just area change, works strange... } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index d65d717c236..5e94ea3146a 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -15675,9 +15675,14 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) // outdoor pvp things, do these after setting the death state, else the player activity notify won't work... doh... // handle player kill only if not suicide (spirit of redemption for example) if (player && this != victim) + { if (OutdoorPvP* pvp = player->GetOutdoorPvP()) pvp->HandleKill(player, victim); + if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetZoneId())) + bf->HandleKill(player, victim); + } + //if (victim->GetTypeId() == TYPEID_PLAYER) // if (OutdoorPvP* pvp = victim->ToPlayer()->GetOutdoorPvP()) // pvp->HandlePlayerActivityChangedpVictim->ToPlayer(); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 02b0ef9fc05..26b41a62928 100755 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1687,11 +1687,64 @@ void WorldSession::SendSetPhaseShift(uint32 PhaseShift) SendPacket(&data); } +//Battlefield and Battleground +void WorldSession::HandleAreaSpiritHealerQueryOpcode(WorldPacket & recv_data) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_AREA_SPIRIT_HEALER_QUERY"); + + Battleground* bg = _player->GetBattleground(); + + uint64 guid; + recv_data >> guid; + + Creature* unit = GetPlayer()->GetMap()->GetCreature(guid); + if (!unit) + return; + + if (!unit->isSpiritService()) // it's not spirit service + return; + + if (bg) + sBattlegroundMgr->SendAreaSpiritHealerQueryOpcode(_player, bg, guid); + + if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId())) + bf->SendAreaSpiritHealerQueryOpcode(_player,guid); +} + +void WorldSession::HandleAreaSpiritHealerQueueOpcode(WorldPacket & recv_data) +{ + sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_AREA_SPIRIT_HEALER_QUEUE"); + + Battleground* bg = _player->GetBattleground(); + + uint64 guid; + recv_data >> guid; + + Creature* unit = GetPlayer()->GetMap()->GetCreature(guid); + if (!unit) + return; + + if (!unit->isSpiritService()) // it's not spirit service + return; + + if (bg) + bg->AddPlayerToResurrectQueue(guid, _player->GetGUID()); + + if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId())) + bf->AddPlayerToResurrectQueue(guid, _player->GetGUID()); +} + void WorldSession::HandleHearthAndResurrect(WorldPacket& /*recv_data*/) { if (_player->isInFlight()) return; + if(Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(_player->GetZoneId())) + { + // bf->PlayerAskToLeave(_player); FIXME + return; + } + AreaTableEntry const* atEntry = GetAreaEntryByAreaID(_player->GetAreaId()); if (!atEntry || !(atEntry->flags & AREA_FLAG_WINTERGRASP_2)) return; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 610cd7d1533..e8675d52b2d 100755 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -5016,8 +5016,12 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool case 2584: // Waiting to Resurrect // Waiting to resurrect spell cancel, we must remove player from resurrect queue if (target->GetTypeId() == TYPEID_PLAYER) + { if (Battleground* bg = target->ToPlayer()->GetBattleground()) bg->RemovePlayerFromResurrectQueue(target->GetGUID()); + if(Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(target->GetZoneId())) + bf->RemovePlayerFromResurrectQueue(target->GetGUID()); + } break; case 36730: // Flame Strike { diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 1dedf8ba916..5281eb16f0c 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5442,6 +5442,7 @@ SpellCastResult Spell::CheckCast(bool strict) // allow always ghost flight spells if (m_originalCaster && m_originalCaster->GetTypeId() == TYPEID_PLAYER && m_originalCaster->isAlive()) { + Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId()); if (AreaTableEntry const* pArea = GetAreaEntryByAreaID(m_originalCaster->GetAreaId())) if (pArea->flags & AREA_FLAG_NO_FLY_ZONE) return (_triggeredCastFlags & TRIGGERED_DONT_REPORT_CAST_ERROR) ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_NOT_HERE; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 1d929d00215..9545a03a9f4 100755 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -1127,7 +1127,7 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32 if (!player) return false; - Battlefield* Bf = sBattlefieldMgr.GetBattlefieldToZoneId(player->GetZoneId()); + Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetZoneId()); if (!Bf || Bf->CanFlyIn() || (!player->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !player->HasAuraType(SPELL_AURA_FLY))) return false; break; @@ -1153,7 +1153,7 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32 if (!player) return false; - Battlefield* bf = sBattlefieldMgr.GetBattlefieldToZoneId(player->GetZoneId()); + Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetZoneId()); if (!bf || bf->GetTypeId() != BATTLEFIELD_WG) return false; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index c0da783da71..c4ff906bc35 100755 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1729,6 +1729,10 @@ void World::SetInitialWorldSettings() sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Starting Outdoor PvP System"); sOutdoorPvPMgr->InitOutdoorPvP(); + ///- Initialize Battlefield + sLog->outString("Starting Battlefield System"); + sBattlefieldMgr->InitBattlefield(); + sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Transports..."); sMapMgr->LoadTransports(); @@ -1993,6 +1997,9 @@ void World::Update(uint32 diff) sOutdoorPvPMgr->Update(diff); RecordTimeDiff("UpdateOutdoorPvPMgr"); + sBattlefieldMgr->Update(diff); + RecordTimeDiff("BattlefieldMgr"); + ///- Delete all characters which have been deleted X days before if (m_timers[WUPDATE_DELETECHARS].Passed()) { diff --git a/src/server/scripts/Commands/cs_bf.cpp b/src/server/scripts/Commands/cs_bf.cpp new file mode 100644 index 00000000000..4eee7c391b0 --- /dev/null +++ b/src/server/scripts/Commands/cs_bf.cpp @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2008-2011 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/* ScriptData +Name: bf_commandscript +%Complete: 100 +Comment: All bf related commands +Category: commandscripts +EndScriptData */ + +#include "ScriptMgr.h" +#include "Chat.h" +#include "BattlefieldMgr.h" + +class bf_commandscript : public CommandScript +{ +public: + bf_commandscript() : CommandScript("bf_commandscript") { } + + ChatCommand* GetCommands() const + { + static ChatCommand battlefieldcommandTable[] = + { + { "start", SEC_ADMINISTRATOR, false, &HandleBattlefieldStart, "", NULL }, + { "stop", SEC_ADMINISTRATOR, false, &HandleBattlefieldEnd, "", NULL }, + { "switch", SEC_ADMINISTRATOR, false, &HandleBattlefieldSwitch, "", NULL }, + { "timer", SEC_ADMINISTRATOR, false, &HandleBattlefieldTimer, "", NULL }, + { "enable", SEC_ADMINISTRATOR, false, &HandleBattlefieldEnable, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand commandTable[] = + { + { "bf", SEC_ADMINISTRATOR, false, NULL, "", battlefieldcommandTable }, + { NULL, 0, false, NULL, "", NULL } + }; + return commandTable; + } + + static bool HandleBattlefieldStart(ChatHandler* handler, const char* args) + { + uint32 battleid = 0; + char* battleid_str = strtok((char*)args, " "); + if (!battleid_str) + return false; + + battleid = atoi(battleid_str); + + Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleid); + + if (!bf) + return false; + + bf->StartBattle(); + + if (battleid == 1) + handler->SendGlobalGMSysMessage("Wintergrasp (Command start used)"); + + return true; + } + + static bool HandleBattlefieldEnd(ChatHandler* handler, const char* args) + { + uint32 battleid = 0; + char* battleid_str = strtok((char*)args, " "); + if (!battleid_str) + return false; + + battleid = atoi(battleid_str); + + Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleid); + + if (!bf) + return false; + + bf->EndBattle(true); + + if (battleid == 1) + handler->SendGlobalGMSysMessage("Wintergrasp (Command stop used)"); + + return true; + } + + static bool HandleBattlefieldEnable(ChatHandler* handler, const char* args) + { + uint32 battleid = 0; + char* battleid_str = strtok((char*)args, " "); + if (!battleid_str) + return false; + + battleid = atoi(battleid_str); + + Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleid); + + if (!bf) + return false; + + if (bf->GetEnable()) + { + bf->SetEnable(false); + if (battleid == 1) + handler->SendGlobalGMSysMessage("Wintergrasp is disabled"); + } + else + { + bf->SetEnable(true); + if (battleid == 1) + handler->SendGlobalGMSysMessage("Wintergrasp is enabled"); + } + + return true; + } + + static bool HandleBattlefieldSwitch(ChatHandler* handler, const char* args) + { + uint32 battleid = 0; + char* battleid_str = strtok((char*)args, " "); + if (!battleid_str) + return false; + + battleid = atoi(battleid_str); + + Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleid); + + if (!bf) + return false; + + bf->EndBattle(false); + if (battleid == 1) + handler->SendGlobalGMSysMessage("Wintergrasp (Command switch used)"); + + return true; + } + + static bool HandleBattlefieldTimer(ChatHandler* handler, const char* args) + { + uint32 battleid = 0; + uint32 time = 0; + char* battleid_str = strtok((char*)args, " "); + if (!battleid_str) + return false; + char* time_str = strtok(NULL, " "); + if (!time_str) + return false; + + battleid = atoi(battleid_str); + + time = atoi(time_str); + + Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleid); + + if (!bf) + return false; + + bf->SetTimer(time * IN_MILLISECONDS); + bf->SendInitWorldStatesToAll(); + if (battleid == 1) + handler->SendGlobalGMSysMessage("Wintergrasp (Command timer used)"); + + return true; + } +}; + +void AddSC_bf_commandscript() +{ + new bf_commandscript(); +} diff --git a/src/server/scripts/Northrend/wintergrasp.cpp b/src/server/scripts/Northrend/wintergrasp.cpp index d7565fcfaf3..936be459f9b 100644 --- a/src/server/scripts/Northrend/wintergrasp.cpp +++ b/src/server/scripts/Northrend/wintergrasp.cpp @@ -63,7 +63,7 @@ class npc_wg_demolisher_engineer : public CreatureScript if (pCreature->isQuestGiver()) pPlayer->PrepareQuestMenu(pCreature->GetGUID()); - Battlefield* BfWG = sBattlefieldMgr.GetBattlefieldByBattleId(1); + Battlefield* BfWG = sBattlefieldMgr->GetBattlefieldByBattleId(1); if (!BfWG) return true; @@ -91,7 +91,7 @@ class npc_wg_demolisher_engineer : public CreatureScript { pPlayer->CLOSE_GOSSIP_MENU(); - Battlefield* BfWG = sBattlefieldMgr.GetBattlefieldByBattleId(1); + Battlefield* BfWG = sBattlefieldMgr->GetBattlefieldByBattleId(1); if (!BfWG) return true; @@ -132,7 +132,7 @@ class npc_wg_spirit_guide : public CreatureScript if (pCreature->isQuestGiver()) pPlayer->PrepareQuestMenu(pCreature->GetGUID()); - Battlefield* BfWG = sBattlefieldMgr.GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + Battlefield* BfWG = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); if (BfWG) { GraveYardVect gy = BfWG->GetGraveYardVect(); @@ -154,7 +154,7 @@ class npc_wg_spirit_guide : public CreatureScript { pPlayer->CLOSE_GOSSIP_MENU(); - Battlefield* BfWG = sBattlefieldMgr.GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + Battlefield* BfWG = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); if (BfWG) { GraveYardVect gy = BfWG->GetGraveYardVect(); @@ -183,7 +183,7 @@ class npc_wg_queue : public CreatureScript if (pCreature->isQuestGiver()) pPlayer->PrepareQuestMenu(pCreature->GetGUID()); - Battlefield* BfWG = sBattlefieldMgr.GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + Battlefield* BfWG = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); if (BfWG) { @@ -214,7 +214,7 @@ class npc_wg_queue : public CreatureScript { pPlayer->CLOSE_GOSSIP_MENU(); - Battlefield* BfWG = sBattlefieldMgr.GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + Battlefield* BfWG = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); if (BfWG) { if (BfWG->IsWarTime()) @@ -302,7 +302,7 @@ class npc_wg_quest_giver : public CreatureScript if (pCreature->isQuestGiver()) pPlayer->PrepareQuestMenu(pCreature->GetGUID()); - Battlefield* BfWG = sBattlefieldMgr.GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + Battlefield* BfWG = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); if (BfWG) { if (pCreature->isQuestGiver()) -- cgit v1.2.3 From e9323b2c2def116360b987532ae7634fcd116122 Mon Sep 17 00:00:00 2001 From: Kandera Date: Fri, 9 Mar 2012 09:37:05 -0500 Subject: Core/Battlefield: revert part of previous commit and correctly fix .bf stop crashing --- src/server/game/Battlefield/Zones/BattlefieldWG.cpp | 2 +- src/server/scripts/Commands/cs_bf.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/server/scripts/Commands') diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp index 7a3a1514671..6fafbf823e9 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp @@ -321,7 +321,7 @@ void BattlefieldWG::UpdateCounterVehicle(bool init) void BattlefieldWG::OnBattleEnd(bool endbytimer) { // Remove relic - if (m_relic && m_relic->isSpawned()) + if (m_relic) m_relic->RemoveFromWorld(); m_relic = NULL; diff --git a/src/server/scripts/Commands/cs_bf.cpp b/src/server/scripts/Commands/cs_bf.cpp index 4eee7c391b0..750550353ec 100644 --- a/src/server/scripts/Commands/cs_bf.cpp +++ b/src/server/scripts/Commands/cs_bf.cpp @@ -83,7 +83,7 @@ public: Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleid); - if (!bf) + if (!bf || !bf->IsWarTime()) return false; bf->EndBattle(true); -- cgit v1.2.3 From 00f88588380f5372cb66e31b67dae56e9da44de5 Mon Sep 17 00:00:00 2001 From: Kandera Date: Fri, 9 Mar 2012 09:39:28 -0500 Subject: Core/Battlefield: attempt to correctly fix again. --- src/server/game/Battlefield/Battlefield.cpp | 2 ++ src/server/scripts/Commands/cs_bf.cpp | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/server/scripts/Commands') diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index 501351f2e4d..e55000df320 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -327,6 +327,8 @@ void Battlefield::StartBattle() void Battlefield::EndBattle(bool endbytimer) { + if (!m_BattlefieldActive) + return false; m_BattlefieldActive = false; m_StartGrouping = false; diff --git a/src/server/scripts/Commands/cs_bf.cpp b/src/server/scripts/Commands/cs_bf.cpp index 750550353ec..d410ae890f9 100644 --- a/src/server/scripts/Commands/cs_bf.cpp +++ b/src/server/scripts/Commands/cs_bf.cpp @@ -61,7 +61,7 @@ public: Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleid); - if (!bf) + if (!bf || bf->) return false; bf->StartBattle(); @@ -83,7 +83,7 @@ public: Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleid); - if (!bf || !bf->IsWarTime()) + if (!bf) return false; bf->EndBattle(true); -- cgit v1.2.3 From 7491926e0c800c71a6ee409129b4eb71190339cf Mon Sep 17 00:00:00 2001 From: Kandera Date: Fri, 9 Mar 2012 09:45:44 -0500 Subject: Core/Battlefield: fix stupid mistakes. sorry! --- src/server/game/Battlefield/Battlefield.cpp | 3 ++- src/server/scripts/Commands/cs_bf.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/server/scripts/Commands') diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index e55000df320..3b1036ef3bd 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -328,7 +328,8 @@ void Battlefield::StartBattle() void Battlefield::EndBattle(bool endbytimer) { if (!m_BattlefieldActive) - return false; + return; + m_BattlefieldActive = false; m_StartGrouping = false; diff --git a/src/server/scripts/Commands/cs_bf.cpp b/src/server/scripts/Commands/cs_bf.cpp index d410ae890f9..4eee7c391b0 100644 --- a/src/server/scripts/Commands/cs_bf.cpp +++ b/src/server/scripts/Commands/cs_bf.cpp @@ -61,7 +61,7 @@ public: Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleid); - if (!bf || bf->) + if (!bf) return false; bf->StartBattle(); -- cgit v1.2.3 From 094f98d3a955009a3f800e2b53ff62261a191f68 Mon Sep 17 00:00:00 2001 From: Warpten Date: Wed, 21 Mar 2012 18:52:07 +0100 Subject: Battlefield/Wintergrasp: * Use correct spells on losing and winning factions * Enums renaming, lowerCamelCase wherever applicable * Rename some methods and class attributes for them to sound more English and less Engrish or even Frenglish (\o/) * Use correct spells when trying to build mechanical units at the Workshops. --- src/server/game/Battlefield/Battlefield.cpp | 397 ++++++------ src/server/game/Battlefield/Battlefield.h | 633 ++++++++++--------- src/server/game/Battlefield/BattlefieldHandler.cpp | 4 +- src/server/game/Battlefield/BattlefieldMgr.cpp | 9 +- .../game/Battlefield/Zones/BattlefieldWG.cpp | 591 ++++++++---------- src/server/game/Battlefield/Zones/BattlefieldWG.h | 684 ++++++++++----------- src/server/game/Globals/ObjectMgr.h | 5 - src/server/game/Server/WorldSession.h | 2 +- src/server/scripts/Commands/cs_bf.cpp | 6 +- src/server/scripts/Northrend/wintergrasp.cpp | 565 +++++++++-------- 10 files changed, 1430 insertions(+), 1466 deletions(-) (limited to 'src/server/scripts/Commands') diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index 5e1e530dbdb..2ad6b244058 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -32,12 +32,11 @@ #include "CreatureTextMgr.h" #include "GroupMgr.h" - Battlefield::Battlefield() { m_Timer = 0; - m_enable = true; - m_BattlefieldActive = false; + m_IsEnabled = true; + m_isActive = false; m_DefenderTeam = TEAM_NEUTRAL; m_TypeId = 0; @@ -51,7 +50,7 @@ Battlefield::Battlefield() m_TimeForAcceptInvite = 20; m_uiKickDontAcceptTimer = 1000; - m_uiKickAfkTimer = 1000; + m_uiKickAfkPlayersTimer = 1000; m_LastResurectTimer = 30 * IN_MILLISECONDS; m_StartGroupingTimer = 0; @@ -63,50 +62,49 @@ Battlefield::~Battlefield() { } -void Battlefield::HandlePlayerEnterZone(Player *player, uint32 /*zone */ ) +// Called when a player enters the zone +void Battlefield::HandlePlayerEnterZone(Player* player, uint32 /*zone*/) { - //If battle is start, - // if it not fully > invite player to join the war - // if it fully > announce to player that BF is full and kick after few second if he dont leave + // If battle is started, + // If not full of players > invite player to join the war + // If full of players > announce to player that BF is full and kick him after a few second if he desn't leave if (IsWarTime()) { - if (m_PlayersInWar[player->GetTeamId()].size() + m_InvitedPlayers[player->GetTeamId()].size() < m_MaxPlayer) //Not fully - { + if (m_PlayersInWar[player->GetTeamId()].size() + m_InvitedPlayers[player->GetTeamId()].size() < m_MaxPlayer) // Vacant spaces InvitePlayerToWar(player); - } - else //Full + else // No more vacant places { - //TODO:Send packet for announce it to player + // TODO: Send a packet to announce it to player m_PlayersWillBeKick[player->GetTeamId()][player->GetGUID()] = time(NULL) + 10; InvitePlayerToQueue(player); } } else { - //If time left is <15 minutes invite player to join queue + // If time left is < 15 minutes invite player to join queue if (m_Timer <= m_StartGroupingTimer) InvitePlayerToQueue(player); } - //Add player in list of player in zone + // Add player in the list of player in zone m_players[player->GetTeamId()].insert(player->GetGUID()); - OnPlayerEnterZone(player); //for scripting + OnPlayerEnterZone(player); } -//Called when a player leave the zone -void Battlefield::HandlePlayerLeaveZone(Player *player, uint32 /*zone */ ) +// Called when a player leave the zone +void Battlefield::HandlePlayerLeaveZone(Player* player, uint32 /*zone*/) { if (IsWarTime()) { - //if player is in war list + // If the player is participating to the battle if (m_PlayersInWar[player->GetTeamId()].find(player->GetGUID()) != m_PlayersInWar[player->GetTeamId()].end()) { m_PlayersInWar[player->GetTeamId()].erase(player->GetGUID()); player->GetSession()->SendBfLeaveMessage(m_BattleId); - if (Group* group = player->GetGroup()) // remove from raid group if player is member + if (Group* group = player->GetGroup()) // Remove the player from the raid group group->RemoveMember(player->GetGUID()); - OnPlayerLeaveWar(player); //For scripting + OnPlayerLeaveWar(player); } } @@ -118,55 +116,54 @@ void Battlefield::HandlePlayerLeaveZone(Player *player, uint32 /*zone */ ) m_players[player->GetTeamId()].erase(player->GetGUID()); SendRemoveWorldStates(player); RemovePlayerFromResurrectQueue(player->GetGUID()); - OnPlayerLeaveZone(player); //For scripting + OnPlayerLeaveZone(player); } bool Battlefield::Update(uint32 diff) { - //When global timer is end if (m_Timer <= diff) { - //Here end of battle by timer + // Battlefield ends on time if (IsWarTime()) EndBattle(true); - //Start of battle - else + else // Time to start a new battle! StartBattle(); } else m_Timer -= diff; - //Some times before battle start invite player to queue + // Invite players a few minutes before the battle's beginning if (!m_StartGrouping && m_Timer <= m_StartGroupingTimer) { m_StartGrouping = true; - InvitePlayerInZoneToQueue(); - OnStartGrouping(); // for scripting + InvitePlayersInZoneToQueue(); + OnStartGrouping(); } bool objective_changed = false; if (IsWarTime()) { - if (m_uiKickAfkTimer <= diff) + if (m_uiKickAfkPlayersTimer <= diff) { - m_uiKickAfkTimer = 1000; - KickAfk(); + m_uiKickAfkPlayersTimer = 1000; + KickAfkPlayers(); } else - m_uiKickAfkTimer -= diff; + m_uiKickAfkPlayersTimer -= diff; - //Here kick player witch dont have accept invitation to join the war when time is end (time of windows) + // Kick players who chose not to accept invitation to the battle if (m_uiKickDontAcceptTimer <= diff) { for (int team = 0; team < 2; team++) for (PlayerTimerMap::iterator itr = m_InvitedPlayers[team].begin(); itr != m_InvitedPlayers[team].end(); itr++) if ((*itr).second <= time(NULL)) - KickPlayerFromBf((*itr).first); - InvitePlayerInZoneToWar(); + KickPlayerFromBattlefield((*itr).first); + + InvitePlayersInZoneToWar(); for (int team = 0; team < 2; team++) for (PlayerTimerMap::iterator itr = m_PlayersWillBeKick[team].begin(); itr != m_PlayersWillBeKick[team].end(); itr++) if ((*itr).second <= time(NULL)) - KickPlayerFromBf((*itr).first); + KickPlayerFromBattlefield((*itr).first); m_uiKickDontAcceptTimer = 1000; } @@ -181,9 +178,9 @@ bool Battlefield::Update(uint32 diff) if (m_LastResurectTimer <= diff) { - for (uint8 i = 0; i < m_GraveYardList.size(); i++) - if (GetGraveYardById(i)) - m_GraveYardList[i]->Resurrect(); + for (uint8 i = 0; i < m_GraveyardList.size(); i++) + if (GetGraveyardById(i)) + m_GraveyardList[i]->Resurrect(); m_LastResurectTimer = RESURRECTION_INTERVAL; } else @@ -192,7 +189,7 @@ bool Battlefield::Update(uint32 diff) return objective_changed; } -void Battlefield::InvitePlayerInZoneToQueue() +void Battlefield::InvitePlayersInZoneToQueue() { for (uint8 team = 0; team < 2; ++team) for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) @@ -200,16 +197,16 @@ void Battlefield::InvitePlayerInZoneToQueue() InvitePlayerToQueue(player); } -void Battlefield::InvitePlayerToQueue(Player *player) +void Battlefield::InvitePlayerToQueue(Player* player) { if (m_PlayersInQueue[player->GetTeamId()].count(player->GetGUID())) return; - if (m_PlayersInQueue[player->GetTeam()].size() <= m_MinPlayer || m_PlayersInQueue[player->GetTeam() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE].size() >= m_MinPlayer) + if (m_PlayersInQueue[player->GetTeam()].size() <= m_MinPlayer || m_PlayersInQueue[GetOtherTeam(player->GetTeamId())].size() >= m_MinPlayer) player->GetSession()->SendBfInvitePlayerToQueue(m_BattleId); } -void Battlefield::InvitePlayerInQueueToWar() +void Battlefield::InvitePlayersInQueueToWar() { for (uint8 team = 0; team < BG_TEAMS_COUNT; ++team) { @@ -229,7 +226,7 @@ void Battlefield::InvitePlayerInQueueToWar() } } -void Battlefield::InvitePlayerInZoneToWar() +void Battlefield::InvitePlayersInZoneToWar() { for (uint8 team = 0; team < BG_TEAMS_COUNT; ++team) for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) @@ -240,16 +237,13 @@ void Battlefield::InvitePlayerInZoneToWar() continue; if (m_PlayersInWar[player->GetTeamId()].size() + m_InvitedPlayers[player->GetTeamId()].size() < m_MaxPlayer) InvitePlayerToWar(player); - else - { - //full + else // Battlefield is full of players m_PlayersWillBeKick[player->GetTeamId()][player->GetGUID()] = time(NULL) + 10; - } } } } -void Battlefield::InvitePlayerToWar(Player *player) +void Battlefield::InvitePlayerToWar(Player* player) { if (!player) return; @@ -264,13 +258,15 @@ void Battlefield::InvitePlayerToWar(Player *player) return; } + // If the player does not match minimal level requirements for the battlefield, kick him if (player->getLevel() < m_MinLevel) { if (m_PlayersWillBeKick[player->GetTeamId()].count(player->GetGUID()) == 0) m_PlayersWillBeKick[player->GetTeamId()][player->GetGUID()] = time(NULL) + 10; return; } - //Check if player is not already in war + + // Check if player is not already in war if (m_PlayersInWar[player->GetTeamId()].count(player->GetGUID()) || m_InvitedPlayers[player->GetTeamId()].count(player->GetGUID())) return; @@ -287,16 +283,16 @@ void Battlefield::InitStalker(uint32 entry, float x, float y, float z, float o) sLog->outError("Battlefield::InitStalker: could not spawn Stalker (Creature entry %u), zone messeges will be un-available", entry); } -void Battlefield::KickAfk() +void Battlefield::KickAfkPlayers() { for (uint8 team = 0; team < BG_TEAMS_COUNT; ++team) for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr) if (Player* player = sObjectAccessor->FindPlayer(*itr)) if (player->isAFK()) - KickPlayerFromBf(*itr); + KickPlayerFromBattlefield(*itr); } -void Battlefield::KickPlayerFromBf(uint64 guid) +void Battlefield::KickPlayerFromBattlefield(uint64 guid) { if (Player* player = sObjectAccessor->FindPlayer(guid)) if (player->GetZoneId() == GetZoneId()) @@ -305,7 +301,7 @@ void Battlefield::KickPlayerFromBf(uint64 guid) void Battlefield::StartBattle() { - if (m_BattlefieldActive) + if (m_isActive) return; for (int team = 0; team < BG_TEAMS_COUNT; team++) @@ -315,41 +311,41 @@ void Battlefield::StartBattle() } m_Timer = m_BattleTime; - m_BattlefieldActive = true; + m_isActive = true; - InvitePlayerInZoneToWar(); - InvitePlayerInQueueToWar(); + InvitePlayersInZoneToWar(); + InvitePlayersInQueueToWar(); - PlaySoundToAll(BF_START); + DoPlaySoundToAll(BF_START); OnBattleStart(); } -void Battlefield::EndBattle(bool endbytimer) +void Battlefield::EndBattle(bool endByTimer) { - if (!m_BattlefieldActive) + if (!m_isActive) return; - m_BattlefieldActive = false; + m_isActive = false; m_StartGrouping = false; - if (!endbytimer) + if (!endByTimer) SetDefenderTeam(GetAttackerTeam()); if (GetDefenderTeam() == TEAM_ALLIANCE) - PlaySoundToAll(BF_ALLIANCE_WINS); // alliance wins sound + DoPlaySoundToAll(BF_ALLIANCE_WINS); else - PlaySoundToAll(BF_HORDE_WINS); // horde wins sound + DoPlaySoundToAll(BF_HORDE_WINS); - OnBattleEnd(endbytimer); + OnBattleEnd(endByTimer); - // reset bf timer + // Reset battlefield timer m_Timer = m_NoWarBattleTime; SendInitWorldStatesToAll(); } -void Battlefield::PlaySoundToAll(uint32 SoundID) +void Battlefield::DoPlaySoundToAll(uint32 SoundID) { WorldPacket data; data.Initialize(SMSG_PLAY_SOUND, 4); @@ -357,34 +353,33 @@ void Battlefield::PlaySoundToAll(uint32 SoundID) for (int team = 0; team < BG_TEAMS_COUNT; team++) for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr) - { if (Player* player = sObjectAccessor->FindPlayer(*itr)) player->GetSession()->SendPacket(&data); - } } -bool Battlefield::HasPlayer(Player *player) const +bool Battlefield::HasPlayer(Player* player) const { return m_players[player->GetTeamId()].find(player->GetGUID()) != m_players[player->GetTeamId()].end(); } // Called in WorldSession::HandleBfQueueInviteResponse -void Battlefield::PlayerAcceptInviteToQueue(Player *player) +void Battlefield::PlayerAcceptInviteToQueue(Player* player) { - // Add player in queueVenez + // Add player in queue m_PlayersInQueue[player->GetTeamId()].insert(player->GetGUID()); // Send notification - player->GetSession()->SendBfQueueInviteResponce(m_BattleId, m_ZoneId); + player->GetSession()->SendBfQueueInviteResponse(m_BattleId, m_ZoneId); } + // Called in WorldSession::HandleBfExitRequest -void Battlefield::AskToLeaveQueue(Player *player) +void Battlefield::AskToLeaveQueue(Player* player) { // Remove player from queue m_PlayersInQueue[player->GetTeamId()].erase(player->GetGUID()); } // Called in WorldSession::HandleBfEntryInviteResponse -void Battlefield::PlayerAcceptInviteToWar(Player *player) +void Battlefield::PlayerAcceptInviteToWar(Player* player) { if (!IsWarTime()) return; @@ -394,7 +389,7 @@ void Battlefield::PlayerAcceptInviteToWar(Player *player) player->GetSession()->SendBfEntered(m_BattleId); m_PlayersInWar[player->GetTeamId()].insert(player->GetGUID()); m_InvitedPlayers[player->GetTeamId()].erase(player->GetGUID()); - //Remove player AFK + if (player->isAFK()) player->ToggleAFK(); @@ -407,14 +402,14 @@ void Battlefield::TeamCastSpell(TeamId team, int32 spellId) if (spellId > 0) for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr) if (Player* player = sObjectAccessor->FindPlayer(*itr)) - player->CastSpell(player, (uint32) spellId, true); + player->CastSpell(player, uint32(spellId), true); else for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr) if (Player* player = sObjectAccessor->FindPlayer(*itr)) - player->RemoveAuraFromStack((uint32) - spellId); + player->RemoveAuraFromStack(uint32(-spellId)); } -void Battlefield::BroadcastPacketZone(WorldPacket & data) const +void Battlefield::BroadcastPacketToZone(WorldPacket& data) const { for (uint8 team = 0; team < BG_TEAMS_COUNT; ++team) for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) @@ -422,7 +417,7 @@ void Battlefield::BroadcastPacketZone(WorldPacket & data) const player->GetSession()->SendPacket(&data); } -void Battlefield::BroadcastPacketQueue(WorldPacket & data) const +void Battlefield::BroadcastPacketToQueue(WorldPacket& data) const { for (uint8 team = 0; team < BG_TEAMS_COUNT; ++team) for (GuidSet::const_iterator itr = m_PlayersInQueue[team].begin(); itr != m_PlayersInQueue[team].end(); ++itr) @@ -430,7 +425,7 @@ void Battlefield::BroadcastPacketQueue(WorldPacket & data) const player->GetSession()->SendPacket(&data); } -void Battlefield::BroadcastPacketWar(WorldPacket & data) const +void Battlefield::BroadcastPacketToWar(WorldPacket& data) const { for (uint8 team = 0; team < BG_TEAMS_COUNT; ++team) for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr) @@ -477,14 +472,13 @@ void Battlefield::SendWarningToAllInZone(uint32 entry) WorldPacket data = BuildWarningAnnPacket(msg); BroadcastPacketWar(data); }*/ -void Battlefield::SendWarningToPlayer(Player *player, uint32 entry) -{ - if (!player) - return; - if (Unit* unit = sObjectAccessor->FindUnit(StalkerGuid)) - if (Creature* stalker = unit->ToCreature()) - sCreatureTextMgr->SendChat(stalker, (uint8)entry, player->GetGUID()); +void Battlefield::SendWarningToPlayer(Player* player, uint32 entry) +{ + if (player) + if (Unit* unit = sObjectAccessor->FindUnit(StalkerGuid)) + if (Creature* stalker = unit->ToCreature()) + sCreatureTextMgr->SendChat(stalker, (uint8)entry, player->GetGUID()); } void Battlefield::SendUpdateWorldState(uint32 field, uint32 value) @@ -500,38 +494,37 @@ void Battlefield::RegisterZone(uint32 zoneId) sBattlefieldMgr->AddZone(zoneId, this); } -void Battlefield::HideNpc(Creature *p_Creature) +void Battlefield::HideNpc(Creature* creature) { - p_Creature->CombatStop(); - p_Creature->SetReactState(REACT_PASSIVE); - p_Creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - p_Creature->SetPhaseMask(2, true); - p_Creature->DisappearAndDie(); - p_Creature->SetVisible(false); + creature->CombatStop(); + creature->SetReactState(REACT_PASSIVE); + creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + creature->SetPhaseMask(2, true); + creature->DisappearAndDie(); + creature->SetVisible(false); } -void Battlefield::ShowNpc(Creature *p_Creature, bool p_Aggressive) +void Battlefield::ShowNpc(Creature* creature, bool aggressive) { - p_Creature->SetPhaseMask(1, true); - p_Creature->SetVisible(true); - p_Creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - if (!p_Creature->isAlive()) - p_Creature->Respawn(true); - if (p_Aggressive) - p_Creature->SetReactState(REACT_AGGRESSIVE); + creature->SetPhaseMask(1, true); + creature->SetVisible(true); + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + if (!creature->isAlive()) + creature->Respawn(true); + if (aggressive) + creature->SetReactState(REACT_AGGRESSIVE); else { - p_Creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - p_Creature->SetReactState(REACT_PASSIVE); + creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + creature->SetReactState(REACT_PASSIVE); } } -//***************************************************** -//*******************Group System********************** -//***************************************************** -Group *Battlefield::GetFreeBfRaid(TeamId TeamId) +// **************************************************** +// ******************* Group System ******************* +// **************************************************** +Group* Battlefield::GetFreeBfRaid(TeamId TeamId) { - //if found free group we return it for (GuidSet::const_iterator itr = m_Groups[TeamId].begin(); itr != m_Groups[TeamId].end(); ++itr) if (Group* group = sGroupMgr->GetGroupByGUID(*itr)) if (!group->IsFull()) @@ -540,7 +533,7 @@ Group *Battlefield::GetFreeBfRaid(TeamId TeamId) return NULL; } -Group *Battlefield::GetGroupPlayer(uint64 guid, TeamId TeamId) +Group* Battlefield::GetGroupPlayer(uint64 guid, TeamId TeamId) { for (GuidSet::const_iterator itr = m_Groups[TeamId].begin(); itr != m_Groups[TeamId].end(); ++itr) if (Group* group = sGroupMgr->GetGroupByGUID(*itr)) @@ -550,7 +543,7 @@ Group *Battlefield::GetGroupPlayer(uint64 guid, TeamId TeamId) return NULL; } -bool Battlefield::AddOrSetPlayerToCorrectBfGroup(Player *player) +bool Battlefield::AddOrSetPlayerToCorrectBfGroup(Player* player) { if (!player->IsInWorld()) return false; @@ -583,97 +576,97 @@ bool Battlefield::AddOrSetPlayerToCorrectBfGroup(Player *player) //***************************************************** //***************Spirit Guide System******************* //***************************************************** + //-------------------- //-Battlefield Method- //-------------------- -BfGraveYard *Battlefield::GetGraveYardById(uint32 id) +BfGraveyard* Battlefield::GetGraveyardById(uint32 id) { - if (id < m_GraveYardList.size()) + if (id < m_GraveyardList.size()) { - if (m_GraveYardList[id]) - return m_GraveYardList[id]; + if (m_GraveyardList[id]) + return m_GraveyardList[id]; else - sLog->outError("Battlefield::GetGraveYardById Id:%u not existed", id); + sLog->outError("Battlefield::GetGraveyardById Id:%u not existed", id); } else - sLog->outError("Battlefield::GetGraveYardById Id:%u cant be found", id); + sLog->outError("Battlefield::GetGraveyardById Id:%u cant be found", id); return NULL; } -WorldSafeLocsEntry const *Battlefield::GetClosestGraveYard(Player *player) +WorldSafeLocsEntry const * Battlefield::GetClosestGraveYard(Player* player) { - BfGraveYard* closestGY = NULL; + BfGraveyard* closestGY = NULL; float maxdist = -1; - for (uint8 i = 0; i < m_GraveYardList.size(); i++) + for (uint8 i = 0; i < m_GraveyardList.size(); i++) { - if (m_GraveYardList[i]) + if (m_GraveyardList[i]) { - if (m_GraveYardList[i]->GetControlTeamId() != player->GetTeamId()) + if (m_GraveyardList[i]->GetControlTeamId() != player->GetTeamId()) continue; - float dist = m_GraveYardList[i]->GetDistance(player); + float dist = m_GraveyardList[i]->GetDistance(player); if (dist < maxdist || maxdist < 0) { - closestGY = m_GraveYardList[i]; + closestGY = m_GraveyardList[i]; maxdist = dist; } } } if (closestGY) - return sWorldSafeLocsStore.LookupEntry(closestGY->GetGraveYardId()); + return sWorldSafeLocsStore.LookupEntry(closestGY->GetGraveyardId()); return NULL; } -void Battlefield::AddPlayerToResurrectQueue(uint64 npc_guid, uint64 player_guid) +void Battlefield::AddPlayerToResurrectQueue(uint64 npcGuid, uint64 playerGuid) { - for (uint8 i = 0; i < m_GraveYardList.size(); i++) + for (uint8 i = 0; i < m_GraveyardList.size(); i++) { - if (!m_GraveYardList[i]) + if (!m_GraveyardList[i]) continue; - if (m_GraveYardList[i]->HasNpc(npc_guid)) + if (m_GraveyardList[i]->HasNpc(npcGuid)) { - m_GraveYardList[i]->AddPlayer(player_guid); + m_GraveyardList[i]->AddPlayer(playerGuid); break; } } } -void Battlefield::RemovePlayerFromResurrectQueue(uint64 player_guid) +void Battlefield::RemovePlayerFromResurrectQueue(uint64 playerGuid) { - for (uint8 i = 0; i < m_GraveYardList.size(); i++) + for (uint8 i = 0; i < m_GraveyardList.size(); i++) { - if (!m_GraveYardList[i]) + if (!m_GraveyardList[i]) continue; - if (m_GraveYardList[i]->HasPlayer(player_guid)) + if (m_GraveyardList[i]->HasPlayer(playerGuid)) { - m_GraveYardList[i]->RemovePlayer(player_guid); + m_GraveyardList[i]->RemovePlayer(playerGuid); break; } } } -void Battlefield::SendAreaSpiritHealerQueryOpcode(Player *pl, const uint64 &guid) +void Battlefield::SendAreaSpiritHealerQueryOpcode(Player* player, const uint64 &guid) { - sLog->outError("SendAreaSpiritHealerQueryOpcode"); WorldPacket data(SMSG_AREA_SPIRIT_HEALER_TIME, 12); uint32 time = m_LastResurectTimer; // resurrect every 30 seconds data << guid << time; - ASSERT(pl && pl->GetSession()); - pl->GetSession()->SendPacket(&data); + ASSERT(player && player->GetSession()); + player->GetSession()->SendPacket(&data); } -//-------------------- -//-BfGraveYard Method- -//-------------------- -BfGraveYard::BfGraveYard(Battlefield *Bf) +// ---------------------- +// - BfGraveyard Method - +// ---------------------- +BfGraveyard::BfGraveyard(Battlefield* battlefield) { - m_Bf = Bf; + m_Bf = battlefield; m_GraveyardId = 0; m_ControlTeam = TEAM_NEUTRAL; m_SpiritGuide[0] = NULL; @@ -681,17 +674,17 @@ BfGraveYard::BfGraveYard(Battlefield *Bf) m_ResurrectQueue.clear(); } -void BfGraveYard::Initialize(TeamId startcontrol, uint32 gy) +void BfGraveyard::Initialize(TeamId startControl, uint32 graveyardId) { - m_ControlTeam = startcontrol; - m_GraveyardId = gy; + m_ControlTeam = startControl; + m_GraveyardId = graveyardId; } -void BfGraveYard::SetSpirit(Creature* spirit, TeamId team) +void BfGraveyard::SetSpirit(Creature* spirit, TeamId team) { if (!spirit) { - sLog->outError(": Invalid Spirit."); + sLog->outError("BfGraveyard::SetSpirit: Invalid Spirit."); return; } @@ -699,32 +692,32 @@ void BfGraveYard::SetSpirit(Creature* spirit, TeamId team) spirit->SetReactState(REACT_PASSIVE); } -float BfGraveYard::GetDistance(Player *player) +float BfGraveyard::GetDistance(Player* player) { - const WorldSafeLocsEntry* ws = sWorldSafeLocsStore.LookupEntry(m_GraveyardId); - return player->GetDistance2d(ws->x, ws->y); + const WorldSafeLocsEntry* safeLoc = sWorldSafeLocsStore.LookupEntry(m_GraveyardId); + return player->GetDistance2d(safeLoc->x, safeLoc->y); } -void BfGraveYard::AddPlayer(uint64 player_guid) +void BfGraveyard::AddPlayer(uint64 playerGuid) { - if (!m_ResurrectQueue.count(player_guid)) + if (!m_ResurrectQueue.count(playerGuid)) { - m_ResurrectQueue.insert(player_guid); + m_ResurrectQueue.insert(playerGuid); - if (Player* player = sObjectAccessor->FindPlayer(player_guid)) + if (Player* player = sObjectAccessor->FindPlayer(playerGuid)) player->CastSpell(player, SPELL_WAITING_FOR_RESURRECT, true); } } -void BfGraveYard::RemovePlayer(uint64 player_guid) +void BfGraveyard::RemovePlayer(uint64 playerGuid) { - m_ResurrectQueue.erase(m_ResurrectQueue.find(player_guid)); + m_ResurrectQueue.erase(m_ResurrectQueue.find(playerGuid)); - if (Player* player = sObjectAccessor->FindPlayer(player_guid)) + if (Player* player = sObjectAccessor->FindPlayer(playerGuid)) player->RemoveAurasDueToSpell(SPELL_WAITING_FOR_RESURRECT); } -void BfGraveYard::Resurrect() +void BfGraveyard::Resurrect() { if (m_ResurrectQueue.empty()) return; @@ -736,7 +729,7 @@ void BfGraveYard::Resurrect() if (!player) continue; - // Check player isinworld and player is on good graveyard + // Check if the player is in world and on the good graveyard if (player->IsInWorld()) if (Unit* spirit = sObjectAccessor->FindUnit(m_SpiritGuide[m_ControlTeam])) spirit->CastSpell(spirit, SPELL_SPIRIT_HEAL, true); @@ -754,7 +747,7 @@ void BfGraveYard::Resurrect() } // For changing graveyard control -void BfGraveYard::ChangeControl(TeamId team) +void BfGraveyard::GiveControlTo(TeamId team) { // Guide switching // Note: Visiblity changes are made by phasing @@ -768,52 +761,51 @@ void BfGraveYard::ChangeControl(TeamId team) RelocateDeadPlayers(); } -void BfGraveYard::RelocateDeadPlayers() +void BfGraveyard::RelocateDeadPlayers() { - WorldSafeLocsEntry const* ClosestGrave = NULL; + WorldSafeLocsEntry const* closestGrave = NULL; for (GuidSet::const_iterator itr = m_ResurrectQueue.begin(); itr != m_ResurrectQueue.end(); ++itr) { Player* player = sObjectAccessor->FindPlayer(*itr); if (!player) continue; - if (ClosestGrave) - player->TeleportTo(player->GetMapId(), ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, player->GetOrientation()); + if (closestGrave) + player->TeleportTo(player->GetMapId(), closestGrave->x, closestGrave->y, closestGrave->z, player->GetOrientation()); else { - ClosestGrave = m_Bf->GetClosestGraveYard(player); - if (ClosestGrave) - player->TeleportTo(player->GetMapId(), ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, player->GetOrientation()); + closestGrave = m_Bf->GetClosestGraveYard(player); + if (closestGrave) + player->TeleportTo(player->GetMapId(), closestGrave->x, closestGrave->y, closestGrave->z, player->GetOrientation()); } } } -//***************End Spirit Guide system*************** +// ******************************************************* +// *************** End Spirit Guide system *************** +// ******************************************************* +// ********************** Misc *************************** +// ******************************************************* -//***************************************************** -//**********************Misc*************************** -//***************************************************** -//Method for spawn creature on map -Creature *Battlefield::SpawnCreature(uint32 entry, Position pos, TeamId team) +Creature* Battlefield::SpawnCreature(uint32 entry, Position pos, TeamId team) { return SpawnCreature(entry, pos.m_positionX, pos.m_positionY, pos.m_positionZ, pos.m_orientation, team); } -Creature *Battlefield::SpawnCreature(uint32 entry, float x, float y, float z, float o, TeamId team) +Creature* Battlefield::SpawnCreature(uint32 entry, float x, float y, float z, float o, TeamId team) { //Get map object Map* map = const_cast < Map * >(sMapMgr->CreateBaseMap(m_MapId)); if (!map) { - sLog->outError("Can't create creature entry: %u map not found", entry); + sLog->outError("Battlefield::SpawnCreature: Can't create creature entry: %u map not found", entry); return 0; } - //Create creature Creature* creature = new Creature; if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, PHASEMASK_NORMAL, entry, 0, team, x, y, z, o)) { - sLog->outError("Can't create creature entry: %u", entry); + sLog->outError("Battlefield::SpawnCreature: Can't create creature entry: %u", entry); delete creature; return NULL; } @@ -823,7 +815,7 @@ Creature *Battlefield::SpawnCreature(uint32 entry, float x, float y, float z, fl CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(entry); if (!cinfo) { - sLog->outErrorDb("Battleground::AddCreature: entry %u does not exist.", entry); + sLog->outErrorDb("Battlefield::SpawnCreature: entry %u does not exist.", entry); return NULL; } // force using DB speeds -- do we really need this? @@ -838,10 +830,10 @@ Creature *Battlefield::SpawnCreature(uint32 entry, float x, float y, float z, fl } // Method for spawning gameobject on map -GameObject *Battlefield::SpawnGameObject(uint32 entry, float x, float y, float z, float o) +GameObject* Battlefield::SpawnGameObject(uint32 entry, float x, float y, float z, float o) { // Get map object - Map* map = const_cast < Map * >(sMapMgr->CreateBaseMap(571)); + Map* map = const_cast(sMapMgr->CreateBaseMap(571)); // *vomits* if (!map) return 0; @@ -849,23 +841,24 @@ GameObject *Battlefield::SpawnGameObject(uint32 entry, float x, float y, float z GameObject* go = new GameObject; if (!go->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), entry, map, PHASEMASK_NORMAL, x, y, z, o, 0, 0, 0, 0, 100, GO_STATE_READY)) { - sLog->outErrorDb("Gameobject template %u not found in database! Battleground not created!", entry); - sLog->outError("Cannot create gameobject template %u! Battleground not created!", entry); + sLog->outErrorDb("Battlefield::SpawnGameObject: Gameobject template %u not found in database! Battlefield not created!", entry); + sLog->outError("Battlefield::SpawnGameObject: Cannot create gameobject template %u! Battlefield not created!", entry); delete go; return NULL; } - // Add in the world + // Add to world map->AddToMap(go); go->setActive(true); + return go; } -//***************************************************** -//*******************CapturePoint********************** -//***************************************************** +// ******************************************************* +// ******************* CapturePoint ********************** +// ******************************************************* -BfCapturePoint::BfCapturePoint(Battlefield *Bf):m_Bf(Bf), m_capturePoint(NULL) +BfCapturePoint::BfCapturePoint(Battlefield* battlefield) : m_Bf(battlefield), m_capturePoint(NULL) { m_team = TEAM_NEUTRAL; m_value = 0; @@ -877,28 +870,28 @@ BfCapturePoint::BfCapturePoint(Battlefield *Bf):m_Bf(Bf), m_capturePoint(NULL) m_maxSpeed = 0; } -bool BfCapturePoint::HandlePlayerEnter(Player *player) +bool BfCapturePoint::HandlePlayerEnter(Player* player) { if (m_capturePoint) { player->SendUpdateWorldState(m_capturePoint->GetGOInfo()->capturePoint.worldState1, 1); - player->SendUpdateWorldState(m_capturePoint->GetGOInfo()->capturePoint.worldstate2, (uint32) ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f)); + player->SendUpdateWorldState(m_capturePoint->GetGOInfo()->capturePoint.worldstate2, uint32(ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f))); player->SendUpdateWorldState(m_capturePoint->GetGOInfo()->capturePoint.worldstate3, m_neutralValuePct); } return m_activePlayers[player->GetTeamId()].insert(player->GetGUID()).second; } -GuidSet::iterator BfCapturePoint::HandlePlayerLeave(Player* plr) +GuidSet::iterator BfCapturePoint::HandlePlayerLeave(Player* player) { if (m_capturePoint) - plr->SendUpdateWorldState(m_capturePoint->GetGOInfo()->capturePoint.worldState1, 0); + player->SendUpdateWorldState(m_capturePoint->GetGOInfo()->capturePoint.worldState1, 0); - GuidSet::iterator current = m_activePlayers[plr->GetTeamId()].find(plr->GetGUID()); + GuidSet::iterator current = m_activePlayers[player->GetTeamId()].find(player->GetGUID()); - if (current == m_activePlayers[plr->GetTeamId()].end()) + if (current == m_activePlayers[player->GetTeamId()].end()) return current; // return end() - m_activePlayers[plr->GetTeamId()].erase(current++); + m_activePlayers[player->GetTeamId()].erase(current++); return current; } @@ -974,10 +967,10 @@ bool BfCapturePoint::Update(uint32 diff) { for (GuidSet::iterator itr = m_activePlayers[team].begin(); itr != m_activePlayers[team].end();) { - if (Player* plr = sObjectAccessor->FindPlayer(*itr)) + if (Player* player = sObjectAccessor->FindPlayer(*itr)) { - if (!m_capturePoint->IsWithinDistInMap(plr, radius) || !plr->IsOutdoorPvPActive()) - itr = HandlePlayerLeave(plr); + if (!m_capturePoint->IsWithinDistInMap(player, radius) || !player->IsOutdoorPvPActive()) + itr = HandlePlayerLeave(player); else ++itr; } @@ -1111,7 +1104,7 @@ void BfCapturePoint::SendObjectiveComplete(uint32 id, uint64 guid) player->KilledMonsterCredit(id, guid); } -bool BfCapturePoint::IsInsideObjective(Player *player) const +bool BfCapturePoint::IsInsideObjective(Player* player) const { return m_activePlayers[player->GetTeamId()].find(player->GetGUID()) != m_activePlayers[player->GetTeamId()].end(); } diff --git a/src/server/game/Battlefield/Battlefield.h b/src/server/game/Battlefield/Battlefield.h index 2bc7ccca408..217d6d62a26 100644 --- a/src/server/game/Battlefield/Battlefield.h +++ b/src/server/game/Battlefield/Battlefield.h @@ -68,342 +68,363 @@ class Creature; class Unit; class Battlefield; -class BfGraveYard; +class BfGraveyard; -typedef std::set < uint64 > GuidSet; -typedef std::vector < BfGraveYard * >GraveYardVect; -typedef std::map < uint64, uint32 > PlayerTimerMap; +typedef std::set GuidSet; +typedef std::vector GraveyardVect; +typedef std::map PlayerTimerMap; class BfCapturePoint { -public: - BfCapturePoint(Battlefield * bf); + public: + BfCapturePoint(Battlefield* bf); - virtual void FillInitialWorldStates(WorldPacket & /*data */ ) {} + virtual void FillInitialWorldStates(WorldPacket& /*data*/) {} - // send world state update to all players present - void SendUpdateWorldState(uint32 field, uint32 value); + // Send world state update to all players present + void SendUpdateWorldState(uint32 field, uint32 value); - // send kill notify to players in the controlling faction - void SendObjectiveComplete(uint32 id, uint64 guid); + // Send kill notify to players in the controlling faction + void SendObjectiveComplete(uint32 id, uint64 guid); - // used when player is activated/inactivated in the area - virtual bool HandlePlayerEnter(Player* player); - virtual GuidSet::iterator HandlePlayerLeave(Player* player); - //virtual void HandlePlayerActivityChanged(Player * player); + // Used when player is activated/inactivated in the area + virtual bool HandlePlayerEnter(Player* player); + virtual GuidSet::iterator HandlePlayerLeave(Player* player); + //virtual void HandlePlayerActivityChanged(Player* player); - // checks if player is in range of a capture credit marker - bool IsInsideObjective(Player * player) const; + // Checks if player is in range of a capture credit marker + bool IsInsideObjective(Player* player) const; - // returns true if the state of the objective has changed, in this case, the OutdoorPvP must send a world state ui update. - virtual bool Update(uint32 diff); - virtual void ChangeTeam(TeamId /*oldTeam */ ) {} - virtual void SendChangePhase(); + // Returns true if the state of the objective has changed, in this case, the OutdoorPvP must send a world state ui update. + virtual bool Update(uint32 diff); + virtual void ChangeTeam(TeamId /*oldTeam*/) {} + virtual void SendChangePhase(); - bool SetCapturePointData(GameObject* capturePoint); - GameObject* GetCapturePointGo() { return m_capturePoint; } + bool SetCapturePointData(GameObject* capturePoint); + GameObject* GetCapturePointGo() { return m_capturePoint; } - TeamId GetTeamId() {return m_team;} -protected: - bool DelCapturePoint(); + TeamId GetTeamId() { return m_team; } + protected: + bool DelCapturePoint(); - // active players in the area of the objective, 0 - alliance, 1 - horde - GuidSet m_activePlayers[2]; + // active Players in the area of the objective, 0 - alliance, 1 - horde + GuidSet m_activePlayers[2]; - // total shift needed to capture the objective - float m_maxValue; - float m_minValue; + // Total shift needed to capture the objective + float m_maxValue; + float m_minValue; - // maximum speed of capture - float m_maxSpeed; + // Maximum speed of capture + float m_maxSpeed; - // the status of the objective - float m_value; - TeamId m_team; + // The status of the objective + float m_value; + TeamId m_team; - // objective states - BattlefieldObjectiveStates m_OldState; - BattlefieldObjectiveStates m_State; + // Objective states + BattlefieldObjectiveStates m_OldState; + BattlefieldObjectiveStates m_State; - // neutral value on capture bar - uint32 m_neutralValuePct; + // Neutral value on capture bar + uint32 m_neutralValuePct; - // pointer to the Battlefield this objective belongs to - Battlefield *m_Bf; - uint32 m_capturePointEntry; - GameObject *m_capturePoint; + // Pointer to the Battlefield this objective belongs to + Battlefield* m_Bf; + + // Capture point entry + uint32 m_capturePointEntry; + + // Gameobject related to that capture point + GameObject* m_capturePoint; }; -class BfGraveYard +class BfGraveyard { -public: - BfGraveYard(Battlefield *Bf); - - // method for change who control the graveyard - void ChangeControl(TeamId team); - TeamId GetControlTeamId() { return m_ControlTeam; } - - // use for found the nearest graveyard - float GetDistance(Player * player); - void Initialize(TeamId startcontrol, uint32 gy); - void SetSpirit(Creature* spirit, TeamId team); - void AddPlayer(uint64 player_guid); - void RemovePlayer(uint64 player_guid); - - void Resurrect(); - void RelocateDeadPlayers(); - - bool HasNpc(uint64 guid) - { - // npcs could not be loaded in the map yet. - if (!m_SpiritGuide[0] || !m_SpiritGuide[1]) - return false; - - if (!sObjectAccessor->FindUnit(m_SpiritGuide[0]) || - !sObjectAccessor->FindUnit(m_SpiritGuide[1])) - return false; - - return (m_SpiritGuide[0] == guid || m_SpiritGuide[1] == guid); - } - bool HasPlayer(uint64 guid) { return m_ResurrectQueue.find(guid) != m_ResurrectQueue.end(); } - uint32 GetGraveYardId() { return m_GraveyardId; } - -protected: - - TeamId m_ControlTeam; - uint32 m_GraveyardId; - uint64 m_SpiritGuide[2]; - GuidSet m_ResurrectQueue; - Battlefield *m_Bf; + public: + BfGraveyard(Battlefield* Bf); + + // Method to changing who controls the graveyard + void GiveControlTo(TeamId team); + TeamId GetControlTeamId() { return m_ControlTeam; } + + // Find the nearest graveyard to a player + float GetDistance(Player* player); + + // Initialize the graveyard + void Initialize(TeamId startcontrol, uint32 gy); + + // Set spirit service for the graveyard + void SetSpirit(Creature* spirit, TeamId team); + + // Add a player to the graveyard + void AddPlayer(uint64 player_guid); + + // Remove a player from the graveyard + void RemovePlayer(uint64 player_guid); + + // Resurrect players + void Resurrect(); + + // Move players waiting to that graveyard on the nearest one + void RelocateDeadPlayers(); + + // Check if this graveyard has a spirit guide + bool HasNpc(uint64 guid) + { + if (!m_SpiritGuide[0] || !m_SpiritGuide[1]) + return false; + + if (!sObjectAccessor->FindUnit(m_SpiritGuide[0]) || + !sObjectAccessor->FindUnit(m_SpiritGuide[1])) + return false; + + return (m_SpiritGuide[0] == guid || m_SpiritGuide[1] == guid); + } + + // Check if a player is in this graveyard's ressurect queue + bool HasPlayer(uint64 guid) { return m_ResurrectQueue.find(guid) != m_ResurrectQueue.end(); } + + // Get the graveyard's ID. + uint32 GetGraveyardId() { return m_GraveyardId; } + + protected: + TeamId m_ControlTeam; + uint32 m_GraveyardId; + uint64 m_SpiritGuide[2]; + GuidSet m_ResurrectQueue; + Battlefield* m_Bf; }; class Battlefield : public ZoneScript { friend class BattlefieldMgr; - public: - /// Constructor - Battlefield(); - /// Destructor - virtual ~Battlefield(); - - /// typedef of map witch store capturepoint and the associate gameobject entry - typedef std::map < uint32 /*lowguid */ , BfCapturePoint * >BfCapturePointMap; - - /// Call this to init the Battlefield - virtual bool SetupBattlefield() { return true; } - - /// Generate packet which contain all worldstatedata of area - virtual void FillInitialWorldStates(WorldPacket & /*data */ ) {} - - /// Update data of a worldstate to all players present in zone - void SendUpdateWorldState(uint32 field, uint32 value); - - /** - * \brief Called every time for update bf data and time - * -Update timer for start/end battle - * -Invite player in zone to queue x minutes before start (x = m_StartGroupingTimer) - * -Kick Afk players - * \param diff : time ellapsed since last call (in ms) - */ - virtual bool Update(uint32 diff); - - /// Invite all player in zone, to join the queue, called x minutes before battle start in Update() - void InvitePlayerInZoneToQueue(); - /// Invite all player in queue to join battle on battle start - void InvitePlayerInQueueToWar(); - /// Invite all player in zone to join battle on battle start - void InvitePlayerInZoneToWar(); - - /// Called when a Unit is kill in battlefield zone - virtual void HandleKill(Player * /*killer */ , Unit * /*killed */ ) {}; - - uint32 GetTypeId() { return m_TypeId; } - uint32 GetZoneId() { return m_ZoneId; } - - void TeamApplyBuff(TeamId team, uint32 spellId, uint32 spellId2 = 0); - - /// Return true if battle is start, false if battle is not started - bool IsWarTime() { return m_BattlefieldActive; } - - /// Enable or Disable battlefield - void SetEnable(bool enable) { m_enable = enable; } - /// Return if battlefield is enable - bool GetEnable() { return m_enable; } - - /** - * \brief Kick player from battlefield and teleport him to kick-point location - * \param guid : guid of player who must be kick - */ - void KickPlayerFromBf(uint64 guid); - - /// Called when player (player) enter in zone - void HandlePlayerEnterZone(Player * player, uint32 zone); - /// Called when player (player) leave the zone - void HandlePlayerLeaveZone(Player * player, uint32 zone); - - // All-purpose data storage 64 bit - virtual uint64 GetData64(uint32 DataId) { return m_Data64[DataId]; } - virtual void SetData64(uint32 DataId, uint64 Value) { m_Data64[DataId] = Value; } - - // All-purpose data storage 32 bit - virtual uint32 GetData(uint32 DataId) { return m_Data32[DataId]; } - virtual void SetData(uint32 DataId, uint32 Value) { m_Data32[DataId] = Value; } - - // Battlefield - generic methods - TeamId GetDefenderTeam() { return m_DefenderTeam; } - TeamId GetAttackerTeam() { return TeamId(1 - m_DefenderTeam); } - void SetDefenderTeam(TeamId team) { m_DefenderTeam = team; } - - // Group methods - /** - * \brief Find a not full battlefield group, if there is no, create one - * \param TeamId : Id of player team for who we search a group (player->GetTeamId()) - */ - Group *GetFreeBfRaid(TeamId TeamId); - /// Return battlefield group where player is. - Group *GetGroupPlayer(uint64 guid, TeamId TeamId); - /// Force player to join a battlefield group - bool AddOrSetPlayerToCorrectBfGroup(Player * player); - - // Graveyard methods - // Find which graveyard the player must be teleported to to be resurrected by spiritguide - WorldSafeLocsEntry const *GetClosestGraveYard(Player * player); - - virtual void AddPlayerToResurrectQueue(uint64 npc_guid, uint64 player_guid); - void RemovePlayerFromResurrectQueue(uint64 player_guid); - void SetGraveyardNumber(uint32 number) { m_GraveYardList.resize(number); } - BfGraveYard *GetGraveYardById(uint32 id); - - // Misc methods - Creature *SpawnCreature(uint32 entry, float x, float y, float z, float o, TeamId team); - Creature *SpawnCreature(uint32 entry, Position pos, TeamId team); - GameObject *SpawnGameObject(uint32 entry, float x, float y, float z, float o); - - // Script-methods - - /// Called on start - virtual void OnBattleStart() {}; - /// Called at the end of battle - virtual void OnBattleEnd(bool /*endbytimer */ ) {}; - /// Called x minutes before battle start when player in zone are invite to join queue - virtual void OnStartGrouping() {}; - /// Called when a player accept to join the battle - virtual void OnPlayerJoinWar(Player * /*player */ ) {}; - /// Called when a player leave the battle - virtual void OnPlayerLeaveWar(Player * /*player */ ) {}; - /// Called when a player leave battlefield zone - virtual void OnPlayerLeaveZone(Player * /*player */ ) {}; - /// Called when a player enter in battlefield zone - virtual void OnPlayerEnterZone(Player * /*player */ ) {}; - - WorldPacket BuildWarningAnnPacket(std::string msg); - void SendWarningToAllInZone(uint32 entry); - //void SendWarningToAllInWar(int32 entry, ...); -- UNUSED - void SendWarningToPlayer(Player * player, uint32 entry); - - void PlayerAcceptInviteToQueue(Player * player); - void PlayerAcceptInviteToWar(Player * player); - uint32 GetBattleId() { return m_BattleId; } - void AskToLeaveQueue(Player * player); - - virtual void DoCompleteOrIncrementAchievement(uint32 /*achievement */ , Player * /*player */ , uint8 /*incrementNumber = 1 */ ) {}; - - /// Send all worldstate data to all player in zone. - virtual void SendInitWorldStatesToAll() {}; - - /// Return if we can use mount in battlefield - bool CanFlyIn() { return !m_BattlefieldActive; } // Used for check if we can use flying mount or not - void SendAreaSpiritHealerQueryOpcode(Player * pl, const uint64 & guid); - - void StartBattle(); - void EndBattle(bool endbytimer); - - void HideNpc(Creature * p_Creature); - void ShowNpc(Creature * p_Creature, bool p_Aggressive); - - GraveYardVect GetGraveYardVect() { return m_GraveYardList; } - - uint32 GetTimer() { return m_Timer; } - void SetTimer(uint32 timer) { m_Timer = timer; } - - void PlaySoundToAll(uint32 SoundID); - - void InvitePlayerToQueue(Player * player); - void InvitePlayerToWar(Player * player); - - void InitStalker(uint32 entry, float x, float y, float z, float o); - -protected: - uint64 StalkerGuid; - uint32 m_Timer; // Global timer for event - bool m_enable; - bool m_BattlefieldActive; - TeamId m_DefenderTeam; - - // the map of the objectives belonging to this outdoorpvp - BfCapturePointMap m_capturePoints; - - // the set of player - GuidSet m_players[BG_TEAMS_COUNT]; // Players in zone - GuidSet m_PlayersInQueue[BG_TEAMS_COUNT]; // Players in the queue - GuidSet m_PlayersInWar[BG_TEAMS_COUNT]; // Players in WG combat - PlayerTimerMap m_InvitedPlayers[BG_TEAMS_COUNT]; - PlayerTimerMap m_PlayersWillBeKick[BG_TEAMS_COUNT]; - - //Variables that must exist for each battlefield - uint32 m_TypeId; // See enum BattlefieldTypes - uint32 m_BattleId; // BattleID (for packet) - uint32 m_ZoneId; // ZoneID of Wintergrasp = 4197 - uint32 m_MapId; // MapId where is Battlefield - uint32 m_MaxPlayer; // Maximum number of player that participated to Battlefield - uint32 m_MinPlayer; // Minimum number of player for Battlefield start - uint32 m_MinLevel; // Required level to participate at Battlefield - uint32 m_BattleTime; // Length of a battle - uint32 m_NoWarBattleTime; // Time between two battles - uint32 m_RestartAfterCrash; // Delay to restart Wintergrasp if the server crashed during a running battle. - uint32 m_TimeForAcceptInvite; - uint32 m_uiKickDontAcceptTimer; - WorldLocation KickPosition; // Position where player is teleport if they switch to afk during battle or if they dont accept invitation - - uint32 m_uiKickAfkTimer; // Timer for check Afk in war - - //Graveyard variables - GraveYardVect m_GraveYardList; // Vector witch contain the different GY of the battle - uint32 m_LastResurectTimer; // Timer for resurect player every 30 sec - - uint32 m_StartGroupingTimer; // Timer for invite players in area 15 minute before start battle - bool m_StartGrouping; // bool for know if all players in area has been invited - - GuidSet m_Groups[BG_TEAMS_COUNT]; // Contain different raid group - - std::vector < uint64 > m_Data64; - std::vector < uint32 > m_Data32; - - void KickAfk(); - // use for switch off all worldstate for client - virtual void SendRemoveWorldStates(Player * /*player */ ) {} - - // use for send a packet for all player list - void BroadcastPacketZone(WorldPacket & data) const; - void BroadcastPacketQueue(WorldPacket & data) const; - void BroadcastPacketWar(WorldPacket & data) const; - - //CapturePoint system - void AddCapturePoint(BfCapturePoint * cp) { m_capturePoints[cp->GetCapturePointGo()->GetEntry()] = cp; } - - BfCapturePoint *GetCapturePoint(uint32 lowguid) const - { - Battlefield::BfCapturePointMap::const_iterator itr = m_capturePoints.find(lowguid); - if (itr != m_capturePoints.end()) - return itr->second; - return NULL; - } + public: + /// Constructor + Battlefield(); + /// Destructor + virtual ~Battlefield(); + + /// typedef of map witch store capturepoint and the associate gameobject entry + typedef std::map BfCapturePointMap; + + /// Call this to init the Battlefield + virtual bool SetupBattlefield() { return true; } + + /// Generate packet which contain all worldstatedata of area + virtual void FillInitialWorldStates(WorldPacket& /*data*/) {} + + /// Update data of a worldstate to all players present in zone + void SendUpdateWorldState(uint32 field, uint32 value); + + /** + * \brief Called every time for update bf data and time + * - Update timer for start/end battle + * - Invite player in zone to queue m_StartGroupingTimer minutes before start + * - Kick Afk players + * \param diff : time ellapsed since last call (in ms) + */ + virtual bool Update(uint32 diff); + + /// Invite all players in zone to join the queue, called x minutes before battle start in Update() + void InvitePlayersInZoneToQueue(); + /// Invite all players in queue to join battle on battle start + void InvitePlayersInQueueToWar(); + /// Invite all players in zone to join battle on battle start + void InvitePlayersInZoneToWar(); + + /// Called when a Unit is kill in battlefield zone + virtual void HandleKill(Player* /*killer*/, Unit* /*killed*/) {}; + + uint32 GetTypeId() { return m_TypeId; } + uint32 GetZoneId() { return m_ZoneId; } + + void TeamApplyBuff(TeamId team, uint32 spellId, uint32 spellId2 = 0); + + /// Return true if battle is start, false if battle is not started + bool IsWarTime() { return m_isActive; } + + /// Enable or Disable battlefield + void ToggleBattlefield(bool enable) { m_IsEnabled = enable; } + /// Return if battlefield is enable + bool IsEnabled() { return m_IsEnabled; } + + /** + * \brief Kick player from battlefield and teleport him to kick-point location + * \param guid : guid of player who must be kick + */ + void KickPlayerFromBattlefield(uint64 guid); + + /// Called when player (player) enter in zone + void HandlePlayerEnterZone(Player* player, uint32 zone); + /// Called when player (player) leave the zone + void HandlePlayerLeaveZone(Player* player, uint32 zone); + + // All-purpose data storage 64 bit + virtual uint64 GetData64(uint32 dataId) { return m_Data64[dataId]; } + virtual void SetData64(uint32 dataId, uint64 value) { m_Data64[dataId] = value; } + + // All-purpose data storage 32 bit + virtual uint32 GetData(uint32 dataId) { return m_Data32[dataId]; } + virtual void SetData(uint32 dataId, uint32 value) { m_Data32[dataId] = value; } + virtual void UpdateData(uint32 index, int32 pad) { m_Data32[index] += pad; } + + // Battlefield - generic methods + TeamId GetDefenderTeam() { return m_DefenderTeam; } + TeamId GetAttackerTeam() { return TeamId(1 - m_DefenderTeam); } + TeamId GetOtherTeam(TeamId team) { return (team == TEAM_HORDE ? TEAM_ALLIANCE : TEAM_HORDE); } + void SetDefenderTeam(TeamId team) { m_DefenderTeam = team; } + + // Group methods + /** + * \brief Find a not full battlefield group, if there is no, create one + * \param TeamId : Id of player team for who we search a group (player->GetTeamId()) + */ + Group* GetFreeBfRaid(TeamId TeamId); + /// Return battlefield group where player is. + Group* GetGroupPlayer(uint64 guid, TeamId TeamId); + /// Force player to join a battlefield group + bool AddOrSetPlayerToCorrectBfGroup(Player* player); + + // Graveyard methods + // Find which graveyard the player must be teleported to to be resurrected by spiritguide + WorldSafeLocsEntry const * GetClosestGraveYard(Player* player); + + virtual void AddPlayerToResurrectQueue(uint64 npc_guid, uint64 player_guid); + void RemovePlayerFromResurrectQueue(uint64 player_guid); + void SetGraveyardNumber(uint32 number) { m_GraveyardList.resize(number); } + BfGraveyard* GetGraveyardById(uint32 id); + + // Misc methods + Creature* SpawnCreature(uint32 entry, float x, float y, float z, float o, TeamId team); + Creature* SpawnCreature(uint32 entry, Position pos, TeamId team); + GameObject* SpawnGameObject(uint32 entry, float x, float y, float z, float o); + + // Script-methods + + /// Called on start + virtual void OnBattleStart() {}; + /// Called at the end of battle + virtual void OnBattleEnd(bool /*endByTimer*/) {}; + /// Called x minutes before battle start when player in zone are invite to join queue + virtual void OnStartGrouping() {}; + /// Called when a player accept to join the battle + virtual void OnPlayerJoinWar(Player* /*player*/) {}; + /// Called when a player leave the battle + virtual void OnPlayerLeaveWar(Player* /*player*/) {}; + /// Called when a player leave battlefield zone + virtual void OnPlayerLeaveZone(Player* /*player*/) {}; + /// Called when a player enter in battlefield zone + virtual void OnPlayerEnterZone(Player* /*player*/) {}; + + WorldPacket BuildWarningAnnPacket(std::string msg); + void SendWarningToAllInZone(uint32 entry); + //void SendWarningToAllInWar(int32 entry, ...); -- UNUSED + void SendWarningToPlayer(Player* player, uint32 entry); + + void PlayerAcceptInviteToQueue(Player* player); + void PlayerAcceptInviteToWar(Player* player); + uint32 GetBattleId() { return m_BattleId; } + void AskToLeaveQueue(Player* player); + + virtual void DoCompleteOrIncrementAchievement(uint32 /*achievement*/, Player* /*player*/, uint8 /*incrementNumber = 1*/) {}; + + /// Send all worldstate data to all player in zone. + virtual void SendInitWorldStatesToAll() {}; + + /// Return if we can use mount in battlefield + bool CanFlyIn() { return !m_isActive; } + + void SendAreaSpiritHealerQueryOpcode(Player* player, const uint64 & guid); + + void StartBattle(); + void EndBattle(bool endByTimer); + + void HideNpc(Creature* creature); + void ShowNpc(Creature* creature, bool aggressive); + + GraveyardVect GetGraveyardVector() { return m_GraveyardList; } + + uint32 GetTimer() { return m_Timer; } + void SetTimer(uint32 timer) { m_Timer = timer; } + + void DoPlaySoundToAll(uint32 SoundID); + + void InvitePlayerToQueue(Player* player); + void InvitePlayerToWar(Player* player); + + void InitStalker(uint32 entry, float x, float y, float z, float o); + + protected: + uint64 StalkerGuid; + uint32 m_Timer; // Global timer for event + bool m_IsEnabled; + bool m_isActive; + TeamId m_DefenderTeam; + + // Map of the objectives belonging to this OutdoorPvP + BfCapturePointMap m_capturePoints; + + // Players info maps + GuidSet m_players[BG_TEAMS_COUNT]; // Players in zone + GuidSet m_PlayersInQueue[BG_TEAMS_COUNT]; // Players in the queue + GuidSet m_PlayersInWar[BG_TEAMS_COUNT]; // Players in WG combat + PlayerTimerMap m_InvitedPlayers[BG_TEAMS_COUNT]; + PlayerTimerMap m_PlayersWillBeKick[BG_TEAMS_COUNT]; + + // Variables that must exist for each battlefield + uint32 m_TypeId; // See enum BattlefieldTypes + uint32 m_BattleId; // BattleID (for packet) + uint32 m_ZoneId; // ZoneID of Wintergrasp = 4197 + uint32 m_MapId; // MapId where is Battlefield + uint32 m_MaxPlayer; // Maximum number of player that participated to Battlefield + uint32 m_MinPlayer; // Minimum number of player for Battlefield start + uint32 m_MinLevel; // Required level to participate at Battlefield + uint32 m_BattleTime; // Length of a battle + uint32 m_NoWarBattleTime; // Time between two battles + uint32 m_RestartAfterCrash; // Delay to restart Wintergrasp if the server crashed during a running battle. + uint32 m_TimeForAcceptInvite; + uint32 m_uiKickDontAcceptTimer; + WorldLocation KickPosition; // Position where players are teleported if they switch to afk during the battle or if they don't accept invitation + + uint32 m_uiKickAfkPlayersTimer; // Timer for check Afk in war + + // Graveyard variables + GraveyardVect m_GraveyardList; // Vector witch contain the different GY of the battle + uint32 m_LastResurectTimer; // Timer for resurect player every 30 sec + + uint32 m_StartGroupingTimer; // Timer for invite players in area 15 minute before start battle + bool m_StartGrouping; // bool for know if all players in area has been invited + + GuidSet m_Groups[BG_TEAMS_COUNT]; // Contain different raid group + + std::vector m_Data64; + std::vector m_Data32; + + void KickAfkPlayers(); + + // use for switch off all worldstate for client + virtual void SendRemoveWorldStates(Player* /*player*/) {} + + // use for send a packet for all player list + void BroadcastPacketToZone(WorldPacket& data) const; + void BroadcastPacketToQueue(WorldPacket& data) const; + void BroadcastPacketToWar(WorldPacket& data) const; + + // CapturePoint system + void AddCapturePoint(BfCapturePoint* cp) { m_capturePoints[cp->GetCapturePointGo()->GetEntry()] = cp; } - void RegisterZone(uint32 zoneid); - bool HasPlayer(Player * player) const; - void TeamCastSpell(TeamId team, int32 spellId); + BfCapturePoint* GetCapturePoint(uint32 lowguid) const + { + Battlefield::BfCapturePointMap::const_iterator itr = m_capturePoints.find(lowguid); + if (itr != m_capturePoints.end()) + return itr->second; + return NULL; + } + void RegisterZone(uint32 zoneid); + bool HasPlayer(Player* player) const; + void TeamCastSpell(TeamId team, int32 spellId); }; #endif diff --git a/src/server/game/Battlefield/BattlefieldHandler.cpp b/src/server/game/Battlefield/BattlefieldHandler.cpp index 7f7613b3950..e10c5c136d9 100644 --- a/src/server/game/Battlefield/BattlefieldHandler.cpp +++ b/src/server/game/Battlefield/BattlefieldHandler.cpp @@ -60,7 +60,7 @@ void WorldSession::SendBfInvitePlayerToQueue(uint32 BattleId) //Param2:(ZoneId) the zone where the battle is (4197 for wg) //Param3:(CanQueue) if able to queue //Param4:(Full) on log in is full -void WorldSession::SendBfQueueInviteResponce(uint32 BattleId,uint32 ZoneId, bool CanQueue, bool Full) +void WorldSession::SendBfQueueInviteResponse(uint32 BattleId,uint32 ZoneId, bool CanQueue, bool Full) { WorldPacket data(SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE, 11); data << uint32(BattleId); @@ -132,7 +132,7 @@ void WorldSession::HandleBfEntryInviteResponse(WorldPacket & recv_data) else { if (_player->GetZoneId() == Bf->GetZoneId()) - Bf->KickPlayerFromBf(_player->GetGUID()); + Bf->KickPlayerFromBattlefield(_player->GetGUID()); } } diff --git a/src/server/game/Battlefield/BattlefieldMgr.cpp b/src/server/game/Battlefield/BattlefieldMgr.cpp index 095ec4fd18a..9f821871c2b 100644 --- a/src/server/game/Battlefield/BattlefieldMgr.cpp +++ b/src/server/game/Battlefield/BattlefieldMgr.cpp @@ -77,10 +77,9 @@ void BattlefieldMgr::HandlePlayerEnterZone(Player * player, uint32 zoneid) if (itr == m_BattlefieldMap.end()) return; - if (itr->second->HasPlayer(player)) - return; - if (itr->second->GetEnable() == false) + if (itr->second->HasPlayer(player) || !itr->second->IsEnabled()) return; + itr->second->HandlePlayerEnterZone(player, zoneid); sLog->outDebug(LOG_FILTER_BATTLEFIELD, "Player %u entered outdoorpvp id %u", player->GetGUIDLow(), itr->second->GetTypeId()); } @@ -106,7 +105,7 @@ Battlefield *BattlefieldMgr::GetBattlefieldToZoneId(uint32 zoneid) // no handle for this zone, return return NULL; } - if (itr->second->GetEnable() == false) + if (!itr->second->IsEnabled()) return NULL; return itr->second; } @@ -127,7 +126,7 @@ void BattlefieldMgr::Update(uint32 diff) if (m_UpdateTimer > BATTLEFIELD_OBJECTIVE_UPDATE_INTERVAL) { for (BattlefieldSet::iterator itr = m_BattlefieldSet.begin(); itr != m_BattlefieldSet.end(); ++itr) - if ((*itr)->GetEnable()) + if ((*itr)->IsEnabled()) (*itr)->Update(m_UpdateTimer); m_UpdateTimer = 0; } diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp index fac3b9cd04f..decc22105a4 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp @@ -25,7 +25,7 @@ #include "SpellAuras.h" #include "Vehicle.h" -enum WGBfData +enum WintergrastData { BATTLEFIELD_WG_ZONEID = 4197, // Wintergrasp BATTLEFIELD_WG_MAPID = 571, // Northrend @@ -49,7 +49,7 @@ bool BattlefieldWG::SetupBattlefield() m_MapId = BATTLEFIELD_WG_MAPID; m_MaxPlayer = sWorld->getIntConfig(CONFIG_WINTERGRASP_PLR_MAX); - m_enable = sWorld->getBoolConfig(CONFIG_WINTERGRASP_ENABLE); + m_IsEnabled = sWorld->getBoolConfig(CONFIG_WINTERGRASP_ENABLE); m_MinPlayer = sWorld->getIntConfig(CONFIG_WINTERGRASP_PLR_MIN); m_MinLevel = sWorld->getIntConfig(CONFIG_WINTERGRASP_PLR_MIN_LVL); m_BattleTime = sWorld->getIntConfig(CONFIG_WINTERGRASP_BATTLETIME) * MINUTE * IN_MILLISECONDS; @@ -72,39 +72,39 @@ bool BattlefieldWG::SetupBattlefield() m_saveTimer = 60000; // Init GraveYards - SetGraveyardNumber(BATTLEFIELD_WG_GY_MAX); + SetGraveyardNumber(BATTLEFIELD_WG_GRAVEYARD_MAX); // Load from db if ((sWorld->getWorldState(BATTLEFIELD_WG_WORLD_STATE_ACTIVE) == 0) && (sWorld->getWorldState(BATTLEFIELD_WG_WORLD_STATE_DEFENDER) == 0) && (sWorld->getWorldState(ClockWorldState[0]) == 0)) { - sWorld->setWorldState(BATTLEFIELD_WG_WORLD_STATE_ACTIVE, false); - sWorld->setWorldState(BATTLEFIELD_WG_WORLD_STATE_DEFENDER, urand(0, 1)); - sWorld->setWorldState(ClockWorldState[0], m_NoWarBattleTime); + sWorld->setWorldState(BATTLEFIELD_WG_WORLD_STATE_ACTIVE, uint64(false)); + sWorld->setWorldState(BATTLEFIELD_WG_WORLD_STATE_DEFENDER, uint64(urand(0, 1))); + sWorld->setWorldState(ClockWorldState[0], uint64(m_NoWarBattleTime)); } - m_BattlefieldActive = sWorld->getWorldState(BATTLEFIELD_WG_WORLD_STATE_ACTIVE); + m_isActive = bool(sWorld->getWorldState(BATTLEFIELD_WG_WORLD_STATE_ACTIVE)); m_DefenderTeam = TeamId(sWorld->getWorldState(BATTLEFIELD_WG_WORLD_STATE_DEFENDER)); - + m_Timer = sWorld->getWorldState(ClockWorldState[0]); - if (m_BattlefieldActive) + if (m_isActive) { - m_BattlefieldActive = false; + m_isActive = false; m_Timer = m_RestartAfterCrash; } - for (uint8 i = 0; i < BATTLEFIELD_WG_GY_MAX; i++) + for (uint8 i = 0; i < BATTLEFIELD_WG_GRAVEYARD_MAX; i++) { - BfGraveYardWG *gy = new BfGraveYardWG(this); + BfGraveyardWG* graveyard = new BfGraveyardWG(this); // When between games, the graveyard is controlled by the defending team if (WGGraveYard[i].startcontrol == TEAM_NEUTRAL) - gy->Initialize(m_DefenderTeam, WGGraveYard[i].gyid); + graveyard->Initialize(m_DefenderTeam, WGGraveYard[i].gyid); else - gy->Initialize(WGGraveYard[i].startcontrol, WGGraveYard[i].gyid); + graveyard->Initialize(WGGraveYard[i].startcontrol, WGGraveYard[i].gyid); - gy->SetTextId(WGGraveYard[i].textid); - m_GraveYardList[i] = gy; + graveyard->SetTextId(WGGraveYard[i].textid); + m_GraveyardList[i] = graveyard; } @@ -113,61 +113,68 @@ bool BattlefieldWG::SetupBattlefield() { WGWorkshop* workshop = new WGWorkshop(this, i); if (i < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST) - workshop->ChangeControl(GetAttackerTeam(), true); + workshop->GiveControlTo(GetAttackerTeam(), true); else - workshop->ChangeControl(GetDefenderTeam(), true); - - //Note: Capture point is added once the gameobject is created. + workshop->GiveControlTo(GetDefenderTeam(), true); + // Note: Capture point is added once the gameobject is created. WorkshopsList.insert(workshop); } - // Spawning npc in keep + // Spawn NPCs in the defender's keep, both Horde and Alliance for (uint8 i = 0; i < WG_MAX_KEEP_NPC; i++) { // Horde npc - if (Creature* creature = SpawnCreature(WGKeepNPC[i].entryh, WGKeepNPC[i].x, WGKeepNPC[i].y, WGKeepNPC[i].z, WGKeepNPC[i].o, TEAM_HORDE)) + if (Creature* creature = SpawnCreature(WGKeepNPC[i].entryHorde, WGKeepNPC[i].x, WGKeepNPC[i].y, WGKeepNPC[i].z, WGKeepNPC[i].o, TEAM_HORDE)) KeepCreature[TEAM_HORDE].insert(creature->GetGUID()); // Alliance npc - if (Creature* creature = SpawnCreature(WGKeepNPC[i].entrya, WGKeepNPC[i].x, WGKeepNPC[i].y, WGKeepNPC[i].z, WGKeepNPC[i].o, TEAM_ALLIANCE)) + if (Creature* creature = SpawnCreature(WGKeepNPC[i].entryAlliance, WGKeepNPC[i].x, WGKeepNPC[i].y, WGKeepNPC[i].z, WGKeepNPC[i].o, TEAM_ALLIANCE)) KeepCreature[TEAM_ALLIANCE].insert(creature->GetGUID()); } - // Hide keep npc + + // Hide NPCs from the Attacker's team in the keep for (GuidSet::const_iterator itr = KeepCreature[GetAttackerTeam()].begin(); itr != KeepCreature[GetAttackerTeam()].end(); ++itr) if (Unit* unit = sObjectAccessor->FindUnit(*itr)) if (Creature* creature = unit->ToCreature()) HideNpc(creature); - // Spawn out of keep npc - // Horde npc + + // Spawn Horde NPCs outside the keep for (uint8 i = 0; i < WG_OUTSIDE_ALLIANCE_NPC; i++) - if (Creature* creature = SpawnCreature(WGOutsideNPC[i].entryh, WGOutsideNPC[i].x, WGOutsideNPC[i].y, WGOutsideNPC[i].z, WGOutsideNPC[i].o, TEAM_HORDE)) + if (Creature* creature = SpawnCreature(WGOutsideNPC[i].entryHorde, WGOutsideNPC[i].x, WGOutsideNPC[i].y, WGOutsideNPC[i].z, WGOutsideNPC[i].o, TEAM_HORDE)) OutsideCreature[TEAM_HORDE].insert(creature->GetGUID()); - // Alliance npc + + // Spawn Alliance NPCs outside the keep for (uint8 i = WG_OUTSIDE_ALLIANCE_NPC; i < WG_MAX_OUTSIDE_NPC; i++) - if (Creature* creature = SpawnCreature(WGOutsideNPC[i].entrya, WGOutsideNPC[i].x, WGOutsideNPC[i].y, WGOutsideNPC[i].z, WGOutsideNPC[i].o, TEAM_ALLIANCE)) + if (Creature* creature = SpawnCreature(WGOutsideNPC[i].entryAlliance, WGOutsideNPC[i].x, WGOutsideNPC[i].y, WGOutsideNPC[i].z, WGOutsideNPC[i].o, TEAM_ALLIANCE)) OutsideCreature[TEAM_ALLIANCE].insert(creature->GetGUID()); - // Hide outside npc + + // Hide units outside the keep that are defenders for (GuidSet::const_iterator itr = OutsideCreature[GetDefenderTeam()].begin(); itr != OutsideCreature[GetDefenderTeam()].end(); ++itr) if (Unit* unit = sObjectAccessor->FindUnit(*itr)) if (Creature* creature = unit->ToCreature()) HideNpc(creature); + + // Spawn turrets and hide them per default for (uint8 i = 0; i < WG_MAX_TURRET; i++) { - if (Creature* creature = SpawnCreature(28366, WGTurret[i].x, WGTurret[i].y, WGTurret[i].z, WGTurret[i].o, TeamId(0))) + Position towerCannonPos; + WGTurret[i].GetPosition(&towerCannonPos); + if (Creature* creature = SpawnCreature(NPC_TOWER_CANNON, towerCannonPos, TEAM_ALLIANCE)) { CanonList.insert(creature->GetGUID()); HideNpc(creature); } } - // Spawning Buiding + + // Spawn all gameobjects for (uint8 i = 0; i < WG_MAX_OBJ; i++) { - GameObject* go = - SpawnGameObject(WGGameObjectBuillding[i].entry, WGGameObjectBuillding[i].x, WGGameObjectBuillding[i].y, WGGameObjectBuillding[i].z, WGGameObjectBuillding[i].o); - BfWGGameObjectBuilding *b = new BfWGGameObjectBuilding(this); - b->Init(go, WGGameObjectBuillding[i].type, WGGameObjectBuillding[i].WorldState, WGGameObjectBuillding[i].nameid); + GameObject* go = SpawnGameObject(WGGameObjectBuilding[i].entry, WGGameObjectBuilding[i].x, WGGameObjectBuilding[i].y, WGGameObjectBuilding[i].z, WGGameObjectBuilding[i].o); + BfWGGameObjectBuilding* b = new BfWGGameObjectBuilding(this); + b->Init(go, WGGameObjectBuilding[i].type, WGGameObjectBuilding[i].WorldState, WGGameObjectBuilding[i].nameId); BuildingsInZone.insert(b); } + // Spawning portal defender for (uint8 i = 0; i < WG_MAX_TELEPORTER; i++) { @@ -176,15 +183,15 @@ bool BattlefieldWG::SetupBattlefield() go->SetUInt32Value(GAMEOBJECT_FACTION, WintergraspFaction[GetDefenderTeam()]); } - // Spawn banner in keep + // Spawn banners in the keep for (uint8 i = 0; i < WG_KEEPGAMEOBJECT_MAX; i++) { - if (GameObject* go = SpawnGameObject(WGKeepGameObject[i].entryh, WGKeepGameObject[i].x, WGKeepGameObject[i].y, WGKeepGameObject[i].z, WGKeepGameObject[i].o)) + if (GameObject* go = SpawnGameObject(WGKeepGameObject[i].entryHorde, WGKeepGameObject[i].x, WGKeepGameObject[i].y, WGKeepGameObject[i].z, WGKeepGameObject[i].o)) { go->SetRespawnTime(GetDefenderTeam()? RESPAWN_ONE_DAY : RESPAWN_IMMEDIATELY); m_KeepGameObject[1].insert(go); } - if (GameObject* go = SpawnGameObject(WGKeepGameObject[i].entrya, WGKeepGameObject[i].x, WGKeepGameObject[i].y, WGKeepGameObject[i].z, WGKeepGameObject[i].o)) + if (GameObject* go = SpawnGameObject(WGKeepGameObject[i].entryAlliance, WGKeepGameObject[i].x, WGKeepGameObject[i].y, WGKeepGameObject[i].z, WGKeepGameObject[i].o)) { go->SetRespawnTime(GetDefenderTeam()? RESPAWN_IMMEDIATELY : RESPAWN_ONE_DAY); m_KeepGameObject[0].insert(go); @@ -208,7 +215,7 @@ bool BattlefieldWG::Update(uint32 diff) bool m_return = Battlefield::Update(diff); if (m_saveTimer <= diff) { - sWorld->setWorldState(BATTLEFIELD_WG_WORLD_STATE_ACTIVE, m_BattlefieldActive); + sWorld->setWorldState(BATTLEFIELD_WG_WORLD_STATE_ACTIVE, m_isActive); sWorld->setWorldState(BATTLEFIELD_WG_WORLD_STATE_DEFENDER, m_DefenderTeam); sWorld->setWorldState(ClockWorldState[0], m_Timer); m_saveTimer = 60 * IN_MILLISECONDS; @@ -222,13 +229,13 @@ bool BattlefieldWG::Update(uint32 diff) void BattlefieldWG::OnBattleStart() { // Spawn titan relic - m_relic = SpawnGameObject(BATTLEFIELD_WG_GAMEOBJECT_TITAN_RELIC, 5440.0f, 2840.8f, 430.43f, 0); - if (m_relic) + m_titansRelic = SpawnGameObject(GO_WINTERGRASP_TITAN_S_RELIC, 5440.0f, 2840.8f, 430.43f, 0); + if (m_titansRelic) { // Update faction of relic, only attacker can click on - m_relic->SetUInt32Value(GAMEOBJECT_FACTION, WintergraspFaction[GetAttackerTeam()]); + m_titansRelic->SetUInt32Value(GAMEOBJECT_FACTION, WintergraspFaction[GetAttackerTeam()]); // Set in use (not allow to click on before last door is broken) - m_relic->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); + m_titansRelic->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); } else sLog->outError("WG: Failed to spawn titan relic."); @@ -257,17 +264,15 @@ void BattlefieldWG::OnBattleStart() } } - m_Data32[BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT] = 0; - m_Data32[BATTLEFIELD_WG_DATA_BROKEN_TOWER_DEF] = 0; - m_Data32[BATTLEFIELD_WG_DATA_DAMAGED_TOWER_ATT] = 0; - m_Data32[BATTLEFIELD_WG_DATA_DAMAGED_TOWER_DEF] = 0; + SetData(BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT, 0); + SetData(BATTLEFIELD_WG_DATA_BROKEN_TOWER_DEF, 0); + SetData(BATTLEFIELD_WG_DATA_DAMAGED_TOWER_ATT, 0); + SetData(BATTLEFIELD_WG_DATA_DAMAGED_TOWER_DEF, 0); // Update graveyard (in no war time all graveyard is to deffender, in war time, depend of base) for (Workshop::const_iterator itr = WorkshopsList.begin(); itr != WorkshopsList.end(); ++itr) - { if (*itr) - (*itr)->UpdateGraveYardAndWorkshop(); - } + (*itr)->UpdateGraveyardAndWorkshop(); for (uint8 team = 0; team < 2; ++team) for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) @@ -292,32 +297,32 @@ void BattlefieldWG::UpdateCounterVehicle(bool init) { if (init) { - m_Data32[BATTLEFIELD_WG_DATA_VEHICLE_H] = 0; - m_Data32[BATTLEFIELD_WG_DATA_VEHICLE_A] = 0; + SetData(BATTLEFIELD_WG_DATA_VEHICLE_H, 0); + SetData(BATTLEFIELD_WG_DATA_VEHICLE_A, 0); } - m_Data32[BATTLEFIELD_WG_DATA_MAX_VEHICLE_H] = 0; - m_Data32[BATTLEFIELD_WG_DATA_MAX_VEHICLE_A] = 0; + SetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_H, 0); + SetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_A, 0); for (Workshop::const_iterator itr = WorkshopsList.begin(); itr != WorkshopsList.end(); ++itr) { if (WGWorkshop* workshop = (*itr)) { if (workshop->teamControl == TEAM_ALLIANCE) - m_Data32[BATTLEFIELD_WG_DATA_MAX_VEHICLE_A] = m_Data32[BATTLEFIELD_WG_DATA_MAX_VEHICLE_A] + 4; + UpdateData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_A, 4); else if (workshop->teamControl == TEAM_HORDE) - m_Data32[BATTLEFIELD_WG_DATA_MAX_VEHICLE_H] = m_Data32[BATTLEFIELD_WG_DATA_MAX_VEHICLE_H] + 4; + UpdateData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_H, 4); } } UpdateVehicleCountWG(); } -void BattlefieldWG::OnBattleEnd(bool endbytimer) +void BattlefieldWG::OnBattleEnd(bool endByTimer) { // Remove relic - if (m_relic) - m_relic->RemoveFromWorld(); - m_relic = NULL; + if (m_titansRelic) + m_titansRelic->RemoveFromWorld(); + m_titansRelic = NULL; // Remove turret for (GuidSet::const_iterator itr = CanonList.begin(); itr != CanonList.end(); ++itr) @@ -326,52 +331,42 @@ void BattlefieldWG::OnBattleEnd(bool endbytimer) { if (Creature* creature = unit->ToCreature()) { - if (!endbytimer) + if (!endByTimer) creature->setFaction(WintergraspFaction[GetDefenderTeam()]); HideNpc(creature); } } } - // If endbytimer is false, battle is end by clicking on relic - if (!endbytimer) + if (!endByTimer) // One player triggered the relic { // Change all npc in keep for (GuidSet::const_iterator itr = KeepCreature[GetAttackerTeam()].begin(); itr != KeepCreature[GetAttackerTeam()].end(); ++itr) - { if (Unit* unit = sObjectAccessor->FindUnit(*itr)) if (Creature* creature = unit->ToCreature()) HideNpc(creature); - } + for (GuidSet::const_iterator itr = KeepCreature[GetDefenderTeam()].begin(); itr != KeepCreature[GetDefenderTeam()].end(); ++itr) - { if (Unit* unit = sObjectAccessor->FindUnit(*itr)) if (Creature* creature = unit->ToCreature()) ShowNpc(creature, true); - } + // Change all npc out of keep for (GuidSet::const_iterator itr = OutsideCreature[GetDefenderTeam()].begin(); itr != OutsideCreature[GetDefenderTeam()].end(); ++itr) - { if (Unit* unit = sObjectAccessor->FindUnit(*itr)) if (Creature* creature = unit->ToCreature()) HideNpc(creature); - } + for (GuidSet::const_iterator itr = OutsideCreature[GetAttackerTeam()].begin(); itr != OutsideCreature[GetAttackerTeam()].end(); ++itr) - { if (Unit* unit = sObjectAccessor->FindUnit(*itr)) if (Creature* creature = unit->ToCreature()) ShowNpc(creature, true); - } } // Update all graveyard, control is to defender when no wartime for (uint8 i = 0; i < BATTLEFIELD_WG_GY_HORDE; i++) - { - if (GetGraveYardById(i)) - { - GetGraveYardById(i)->ChangeControl(GetDefenderTeam()); - } - } + if (BfGraveyard* graveyard = GetGraveyardById(i)) + graveyard->GiveControlTo(GetDefenderTeam()); for (GameObjectSet::const_iterator itr = m_KeepGameObject[GetDefenderTeam()].begin(); itr != m_KeepGameObject[GetDefenderTeam()].end(); ++itr) (*itr)->SetRespawnTime(RESPAWN_IMMEDIATELY); @@ -389,58 +384,23 @@ void BattlefieldWG::OnBattleEnd(bool endbytimer) for (Workshop::const_iterator itr = WorkshopsList.begin(); itr != WorkshopsList.end(); ++itr) (*itr)->Save(); - uint32 WinHonor = 0; - uint32 LossHonor = 0; - - if (!endbytimer) - { - WinHonor = 3000 + 400 * m_Data32[BATTLEFIELD_WG_DATA_BROKEN_TOWER_DEF] + 100 * m_Data32[BATTLEFIELD_WG_DATA_DAMAGED_TOWER_DEF]; - LossHonor = 1000 + 400 * m_Data32[BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT] + 100 * m_Data32[BATTLEFIELD_WG_DATA_DAMAGED_TOWER_ATT]; - } - else - { - WinHonor = 3000 + 400 * m_Data32[BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT] + 100 * m_Data32[BATTLEFIELD_WG_DATA_DAMAGED_TOWER_ATT]; - LossHonor = 1000 + 400 * m_Data32[BATTLEFIELD_WG_DATA_BROKEN_TOWER_DEF] + 100 * m_Data32[BATTLEFIELD_WG_DATA_DAMAGED_TOWER_DEF]; - } - for (GuidSet::const_iterator itr = m_PlayersInWar[GetDefenderTeam()].begin(); itr != m_PlayersInWar[GetDefenderTeam()].end(); ++itr) { if (Player* player = sObjectAccessor->FindPlayer(*itr)) { - player->AddAura(SPELL_ESSENCE_OF_WINTERGRASP, player); - if (player->HasAura(SPELL_LIEUTENANT)) - { - player->RewardHonor(NULL, 1, WinHonor); - RewardMarkOfHonor(player, 3); - } - else if (player->HasAura(SPELL_CORPORAL)) - { - player->RewardHonor(NULL, 1, WinHonor); - RewardMarkOfHonor(player, 2); - } + player->CastSpell(player, SPELL_ESSENCE_OF_WINTERGRASP, true); + player->CastSpell(player, SPELL_VICTORY_REWARD, true); // Send Wintergrasp victory achievement DoCompleteOrIncrementAchievement(ACHIEVEMENTS_WIN_WG, player); // Award achievement for succeeding in Wintergrasp in 10 minutes or less - if (!endbytimer && GetTimer() <= 10000) + if (!endByTimer && GetTimer() <= 10000) DoCompleteOrIncrementAchievement(ACHIEVEMENTS_WIN_WG_TIMER_10, player); } } + for (GuidSet::const_iterator itr = m_PlayersInWar[GetAttackerTeam()].begin(); itr != m_PlayersInWar[GetAttackerTeam()].end(); ++itr) - { if (Player* player = sObjectAccessor->FindPlayer(*itr)) - { - if (player->HasAura(SPELL_LIEUTENANT)) - { - player->RewardHonor(NULL, 1, LossHonor); - RewardMarkOfHonor(player, 1); - } - else if (player->HasAura(SPELL_CORPORAL)) - { - player->RewardHonor(NULL, 1, LossHonor); - RewardMarkOfHonor(player, 1); - } - } - } + player->CastSpell(player, SPELL_DEFEAT_REWARD, true); for (uint8 team = 0; team < 2; ++team) { @@ -448,19 +408,18 @@ void BattlefieldWG::OnBattleEnd(bool endbytimer) if (Player* player = sObjectAccessor->FindPlayer(*itr)) RemoveAurasFromPlayer(player); - m_PlayersInWar[team].clear(); + m_PlayersInWar[team].clear(); for (GuidSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr) - { if (Unit* unit = sObjectAccessor->FindUnit(*itr)) if (Creature* creature = unit->ToCreature()) if (creature->IsVehicle()) creature->GetVehicleKit()->Dismiss(); - } + m_vehicles[team].clear(); } - if (!endbytimer) + if (!endByTimer) { for (uint8 team = 0; team < 2; ++team) { @@ -475,72 +434,45 @@ void BattlefieldWG::OnBattleEnd(bool endbytimer) } } - if (!endbytimer) - { // win alli/horde + if (!endByTimer) // win alli/horde SendWarningToAllInZone((GetDefenderTeam() == TEAM_ALLIANCE) ? BATTLEFIELD_WG_TEXT_WIN_KEEP : BATTLEFIELD_WG_TEXT_WIN_KEEP + 1); - } - else - { // defend alli/horde + else // defend alli/horde SendWarningToAllInZone((GetDefenderTeam() == TEAM_ALLIANCE) ? BATTLEFIELD_WG_TEXT_DEFEND_KEEP : BATTLEFIELD_WG_TEXT_DEFEND_KEEP + 1); - } } -// ***************************************************** -// *******************Reward System********************* -// ***************************************************** -void BattlefieldWG::DoCompleteOrIncrementAchievement(uint32 achievement, Player *player, uint8 /*incrementNumber */ ) +// ******************************************************* +// ******************* Reward System ********************* +// ******************************************************* +void BattlefieldWG::DoCompleteOrIncrementAchievement(uint32 achievement, Player* player, uint8 /*incrementNumber*/) { - AchievementEntry const* AE = sAchievementStore.LookupEntry(achievement); + AchievementEntry const* achievementEntry = sAchievementStore.LookupEntry(achievement); + + if (!achievementEntry) + return; switch (achievement) { case ACHIEVEMENTS_WIN_WG_100: - { - // player->GetAchievementMgr().UpdateAchievementCriteria(); - } + { + // player->GetAchievementMgr().UpdateAchievementCriteria(); + } default: - { - if (player) - player->CompletedAchievement(AE); - } + { + if (player) + player->CompletedAchievement(achievementEntry); break; + } } } -void BattlefieldWG::RewardMarkOfHonor(Player* player, uint32 count) -{ - // 'Inactive' this aura prevents the player from gaining honor points and battleground tokens - if (count == 0) - return; - - ItemPosCountVec dest; - uint32 no_space_count = 0; - uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, WG_MARK_OF_HONOR, count, &no_space_count); - - if (msg == EQUIP_ERR_ITEM_NOT_FOUND) - { - return; - } - - if (msg != EQUIP_ERR_OK) // convert to possible store amount - count -= no_space_count; - - if (count != 0 && !dest.empty()) // can add some - if (Item * item = player->StoreNewItem(dest, WG_MARK_OF_HONOR, true, 0)) - player->SendNewItem(item, count, true, false); -} - void BattlefieldWG::OnStartGrouping() { - // Warn SendWarningToAllInZone(BATTLEFIELD_WG_TEXT_WILL_START); } uint8 BattlefieldWG::GetSpiritGraveyardId(uint32 areaId) { - uint8 graveyardId = 0; - switch (areaId) { case AREA_WINTERGRASP_FORTRESS: @@ -558,29 +490,27 @@ uint8 BattlefieldWG::GetSpiritGraveyardId(uint32 areaId) case AREA_THE_CHILLED_QUAGMIRE: return BATTLEFIELD_WG_GY_HORDE; default: - sLog->outError(": Unexpected Area Id %u", areaId); + sLog->outError("BattlefieldWG::GetSpiritGraveyardId: Unexpected Area Id %u", areaId); break; } - return graveyardId; + return 0; } -void BattlefieldWG::OnCreatureCreate(Creature *creature) +void BattlefieldWG::OnCreatureCreate(Creature* creature) { // Accessing to db spawned creatures switch (creature->GetEntry()) { - // Alliance Spirit case NPC_DWARVEN_SPIRIT_GUIDE: - // Horde Spirit case NPC_TAUNKA_SPIRIT_GUIDE: - { - TeamId teamId = creature->GetEntry() == NPC_DWARVEN_SPIRIT_GUIDE ? TEAM_ALLIANCE : TEAM_HORDE; - uint8 graveyardId = GetSpiritGraveyardId(creature->GetAreaId()); - if (m_GraveYardList[graveyardId]) - m_GraveYardList[graveyardId]->SetSpirit(creature, teamId); - } + { + TeamId teamId = (creature->GetEntry() == NPC_DWARVEN_SPIRIT_GUIDE ? TEAM_ALLIANCE : TEAM_HORDE); + uint8 graveyardId = GetSpiritGraveyardId(creature->GetAreaId()); + if (m_GraveyardList[graveyardId]) + m_GraveyardList[graveyardId]->SetSpirit(creature, teamId); break; + } } // untested code - not sure if it is valid. @@ -588,53 +518,53 @@ void BattlefieldWG::OnCreatureCreate(Creature *creature) { switch (creature->GetEntry()) { - case NPC_WG_SEIGE_ENGINE_ALLIANCE: - case NPC_WG_SEIGE_ENGINE_HORDE: - case NPC_WG_CATAPULT: - case NPC_WG_DEMOLISHER: + case NPC_WINTERGRASP_SIEGE_ENGINE_1: + case NPC_WINTERGRASP_SIEGE_ENGINE_2: + case NPC_WINTERGRASP_CATAPULT: + case NPC_WINTERGRASP_DEMOLISHER: + { + uint8 team; + if (creature->getFaction() == WintergraspFaction[TEAM_ALLIANCE]) + team = TEAM_ALLIANCE; + else if (creature->getFaction() == WintergraspFaction[TEAM_HORDE]) + team = TEAM_HORDE; + else + return; + + if (team == TEAM_HORDE) { - uint8 team; - if (creature->getFaction() == WintergraspFaction[TEAM_ALLIANCE]) - team = TEAM_ALLIANCE; - else if (creature->getFaction() == WintergraspFaction[TEAM_HORDE]) - team = TEAM_HORDE; + if (GetData(BATTLEFIELD_WG_DATA_VEHICLE_H) <= GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_H)) + { + UpdateData(BATTLEFIELD_WG_DATA_VEHICLE_H, 1); + creature->CastSpell(creature, SPELL_HORDE_FLAG, true); + m_vehicles[team].insert(creature->GetGUID()); + UpdateVehicleCountWG(); + } else + { + creature->setDeathState(DEAD); + creature->SetRespawnTime(RESPAWN_ONE_DAY); return; - - if (team == TEAM_HORDE) + } + } + else + { + if (GetData(BATTLEFIELD_WG_DATA_VEHICLE_A) <= GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_A)) { - if (GetData(BATTLEFIELD_WG_DATA_VEHICLE_H) <= GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_H)) - { - m_Data32[BATTLEFIELD_WG_DATA_VEHICLE_H]++; - creature->CastSpell(creature, SPELL_HORDE_FLAG, true); - m_vehicles[team].insert(creature->GetGUID()); - UpdateVehicleCountWG(); - } - else - { - creature->setDeathState(DEAD); - creature->SetRespawnTime(RESPAWN_ONE_DAY); - return; - } + UpdateData(BATTLEFIELD_WG_DATA_VEHICLE_A, 1); + creature->CastSpell(creature, SPELL_HORDE_FLAG, true); + m_vehicles[team].insert(creature->GetGUID()); + UpdateVehicleCountWG(); } else { - if (GetData(BATTLEFIELD_WG_DATA_VEHICLE_A) <= GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_A)) - { - m_Data32[BATTLEFIELD_WG_DATA_VEHICLE_A]++; - creature->CastSpell(creature, SPELL_ALLIANCE_FLAG, true); - m_vehicles[team].insert(creature->GetGUID()); - UpdateVehicleCountWG(); - } - else - { - creature->setDeathState(DEAD); - creature->SetRespawnTime(RESPAWN_ONE_DAY); - return; - } + creature->setDeathState(DEAD); + creature->SetRespawnTime(RESPAWN_ONE_DAY); + return; } - break; } + break; + } } } } @@ -645,28 +575,28 @@ void BattlefieldWG::OnCreatureRemove(Creature* creature) { switch (creature->GetEntry()) { - case NPC_WG_SEIGE_ENGINE_ALLIANCE: - case NPC_WG_SEIGE_ENGINE_HORDE: - case NPC_WG_CATAPULT: - case NPC_WG_DEMOLISHER: - { - uint8 team; - if (creature->getFaction() == WintergraspFaction[TEAM_ALLIANCE]) - team = TEAM_ALLIANCE; - else if (creature->getFaction() == WintergraspFaction[TEAM_HORDE]) - team = TEAM_HORDE; - else - return; - - m_vehicles[team].erase(creature->GetGUID()); - if (team == TEAM_HORDE) - m_Data32[BATTLEFIELD_WG_DATA_VEHICLE_H]--; - else - m_Data32[BATTLEFIELD_WG_DATA_VEHICLE_A]--; - UpdateVehicleCountWG(); - - break; - } + case NPC_WINTERGRASP_SIEGE_ENGINE_1: + case NPC_WINTERGRASP_SIEGE_ENGINE_2: + case NPC_WINTERGRASP_CATAPULT: + case NPC_WINTERGRASP_DEMOLISHER: + { + uint8 team; + if (creature->getFaction() == WintergraspFaction[TEAM_ALLIANCE]) + team = TEAM_ALLIANCE; + else if (creature->getFaction() == WintergraspFaction[TEAM_HORDE]) + team = TEAM_HORDE; + else + return; + + m_vehicles[team].erase(creature->GetGUID()); + if (team == TEAM_HORDE) + UpdateData(BATTLEFIELD_WG_DATA_VEHICLE_H, -1); + else + UpdateData(BATTLEFIELD_WG_DATA_VEHICLE_A, -1); + UpdateVehicleCountWG(); + + break; + } } } } @@ -678,40 +608,40 @@ void BattlefieldWG::OnGameObjectCreate(GameObject* go) switch (go->GetEntry()) { - case BATTLEFIELD_WG_GAMEOBJECT_FACTORY_BANNER_NE: + case GO_WINTERGRASP_FACTORY_BANNER_NE: isWorkshop = true; workshopId = BATTLEFIELD_WG_WORKSHOP_NE; break; - case BATTLEFIELD_WG_GAMEOBJECT_FACTORY_BANNER_NW: + case GO_WINTERGRASP_FACTORY_BANNER_NW: isWorkshop = true; workshopId = BATTLEFIELD_WG_WORKSHOP_NW; break; - case BATTLEFIELD_WG_GAMEOBJECT_FACTORY_BANNER_SE: + case GO_WINTERGRASP_FACTORY_BANNER_SE: isWorkshop = true; workshopId = BATTLEFIELD_WG_WORKSHOP_SE; break; - case BATTLEFIELD_WG_GAMEOBJECT_FACTORY_BANNER_SW: + case GO_WINTERGRASP_FACTORY_BANNER_SW: isWorkshop = true; workshopId = BATTLEFIELD_WG_WORKSHOP_SW; break; } - if (isWorkshop) + if (!isWorkshop) + return; + + for (Workshop::const_iterator itr = WorkshopsList.begin(); itr != WorkshopsList.end(); ++itr) { - for (Workshop::const_iterator itr = WorkshopsList.begin(); itr != WorkshopsList.end(); ++itr) + if (WGWorkshop* workshop = (*itr)) { - if (WGWorkshop* workshop = (*itr)) + if (workshop->workshopId == workshopId) { - if (workshop->workshopId == workshopId) - { - BfCapturePointWG* capturePoint = new BfCapturePointWG(this, GetAttackerTeam()); + WintergraspCapturePoint* capturePoint = new WintergraspCapturePoint(this, GetAttackerTeam()); - capturePoint->SetCapturePointData(go); - capturePoint->LinkToWorkShop(workshop); - AddCapturePoint(capturePoint); - break; - } + capturePoint->SetCapturePointData(go); + capturePoint->LinkToWorkshop(workshop); + AddCapturePoint(capturePoint); + break; } } } @@ -727,29 +657,20 @@ void BattlefieldWG::HandleKill(Player* killer, Unit* victim) if (victim->GetTypeId() == TYPEID_PLAYER) { for (GuidSet::const_iterator itr = m_PlayersInWar[killer->GetTeamId()].begin(); itr != m_PlayersInWar[killer->GetTeamId()].end(); ++itr) - { if (Player* player = sObjectAccessor->FindPlayer(*itr)) if (player->GetDistance2d(killer) < 40) PromotePlayer(player); - } return; } - for (GuidSet::const_iterator itr = m_vehicles[killer->GetTeamId()? TEAM_ALLIANCE : TEAM_HORDE].begin(); - itr != m_vehicles[killer->GetTeamId()? TEAM_ALLIANCE : TEAM_HORDE].end(); ++itr) - { + + for (GuidSet::const_iterator itr = m_vehicles[GetOtherTeam(killer->GetTeamId())].begin(); itr != m_vehicles[GetOtherTeam(killer->GetTeamId())].end(); ++itr) if (Unit* unit = sObjectAccessor->FindUnit(*itr)) - { if (Creature* creature = unit->ToCreature()) - { if (victim->GetEntry() == creature->GetEntry() && !again) - { again = true; - } - } - } - } - for (GuidSet::const_iterator itr = KeepCreature[killer->GetTeamId()? TEAM_ALLIANCE : TEAM_HORDE].begin(); - itr != KeepCreature[killer->GetTeamId()? TEAM_ALLIANCE : TEAM_HORDE].end(); ++itr) + + for (GuidSet::const_iterator itr = KeepCreature[GetOtherTeam(killer->GetTeamId())].begin(); + itr != KeepCreature[GetOtherTeam(killer->GetTeamId())].end(); ++itr) { if (Unit* unit = sObjectAccessor->FindUnit(*itr)) { @@ -759,11 +680,9 @@ void BattlefieldWG::HandleKill(Player* killer, Unit* victim) { again = true; for (GuidSet::const_iterator iter = m_PlayersInWar[killer->GetTeamId()].begin(); iter != m_PlayersInWar[killer->GetTeamId()].end(); ++iter) - { if (Player* player = sObjectAccessor->FindPlayer(*iter)) - if (player->GetDistance2d(killer) < 40) + if (player->GetDistance2d(killer) < 40.0f) PromotePlayer(player); - } } } } @@ -774,12 +693,12 @@ void BattlefieldWG::HandleKill(Player* killer, Unit* victim) // Update rank for player void BattlefieldWG::PromotePlayer(Player* killer) { - if (!m_BattlefieldActive) + if (!m_isActive) return; // Updating rank of player if (Aura* aur = killer->GetAura(SPELL_RECRUIT)) { - if (aur->GetStackAmount() >= 5) // 7 or more TODO: + if (aur->GetStackAmount() >= 5) { killer->RemoveAura(SPELL_RECRUIT); killer->CastSpell(killer, SPELL_CORPORAL, true); @@ -790,7 +709,7 @@ void BattlefieldWG::PromotePlayer(Player* killer) } else if (Aura* aur = killer->GetAura(SPELL_CORPORAL)) { - if (aur->GetStackAmount() >= 5) // 7 or more TODO: + if (aur->GetStackAmount() >= 5) { killer->RemoveAura(SPELL_CORPORAL); killer->CastSpell(killer, SPELL_LIEUTENANT, true); @@ -822,9 +741,7 @@ void BattlefieldWG::OnPlayerJoinWar(Player* player) if (player->GetZoneId() != m_ZoneId) { if (player->GetTeamId() == GetDefenderTeam()) - { player->TeleportTo(571, 5345, 2842, 410, 3.14f); - } else { if (player->GetTeamId() == TEAM_HORDE) @@ -838,13 +755,13 @@ void BattlefieldWG::OnPlayerJoinWar(Player* player) if (player->GetTeamId() == GetAttackerTeam()) { - if (3 - m_Data32[BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT] > 0) - player->SetAuraStack(SPELL_TOWER_CONTROL, player, 3 - m_Data32[BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT]); + if (GetData(BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT) < 3) + player->SetAuraStack(SPELL_TOWER_CONTROL, player, 3 - GetData(BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT)); } else { - if (m_Data32[BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT] > 0) - player->SetAuraStack(SPELL_TOWER_CONTROL, player, m_Data32[BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT]); + if (GetData(BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT) > 0) + player->SetAuraStack(SPELL_TOWER_CONTROL, player, GetData(BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT)); } SendInitWorldStatesTo(player); } @@ -858,6 +775,7 @@ void BattlefieldWG::OnPlayerLeaveWar(Player* player) player->GetVehicle()->Dismiss(); RemoveAurasFromPlayer(player); } + player->RemoveAurasDueToSpell(SPELL_HORDE_CONTROLS_FACTORY_PHASE_SHIFT); player->RemoveAurasDueToSpell(SPELL_ALLIANCE_CONTROLS_FACTORY_PHASE_SHIFT); player->RemoveAurasDueToSpell(SPELL_HORDE_CONTROL_PHASE_SHIFT); @@ -866,7 +784,7 @@ void BattlefieldWG::OnPlayerLeaveWar(Player* player) void BattlefieldWG::OnPlayerLeaveZone(Player* player) { - if (!m_BattlefieldActive) + if (!m_isActive) RemoveAurasFromPlayer(player); player->RemoveAurasDueToSpell(SPELL_HORDE_CONTROLS_FACTORY_PHASE_SHIFT); @@ -877,7 +795,7 @@ void BattlefieldWG::OnPlayerLeaveZone(Player* player) void BattlefieldWG::OnPlayerEnterZone(Player* player) { - if (!m_BattlefieldActive) + if (!m_isActive) RemoveAurasFromPlayer(player); player->AddAura(m_DefenderTeam == TEAM_HORDE ? SPELL_HORDE_CONTROL_PHASE_SHIFT : SPELL_ALLIANCE_CONTROL_PHASE_SHIFT, player); @@ -896,11 +814,8 @@ uint32 BattlefieldWG::GetData(uint32 data) case AREA_WESTPARK_WORKSHOP: case AREA_EASTPARK_WORKSHOP: // Graveyards and Workshops are controlled by the same team. - if (m_GraveYardList[GetSpiritGraveyardId(data)]) - return m_GraveYardList[GetSpiritGraveyardId(data)]->GetControlTeamId(); - default: - if (m_Data32[data]) - return m_Data32[data]; + if (m_GraveyardList[GetSpiritGraveyardId(data)]) + return m_GraveyardList[GetSpiritGraveyardId(data)]->GetControlTeamId(); } return Battlefield::GetData(data); @@ -918,8 +833,8 @@ WorldPacket BattlefieldWG::BuildInitWorldStates() data << uint32(BATTLEFIELD_WG_WORLD_STATE_ATTACKER) << uint32(GetAttackerTeam()); data << uint32(BATTLEFIELD_WG_WORLD_STATE_DEFENDER) << uint32(GetDefenderTeam()); - data << uint32(BATTLEFIELD_WG_WORLD_STATE_ACTIVE) << uint32(IsWarTime()? 0 : 1); - data << uint32(3710) << uint32(IsWarTime()? 1 : 0); + data << uint32(BATTLEFIELD_WG_WORLD_STATE_ACTIVE) << uint32(IsWarTime()? 0 : 1); // Note: cleanup these two, their names look awkward + data << uint32(BATTLEFIELD_WG_WORLD_STATE_SHOW_WORLDSTATE) << uint32(IsWarTime()? 1 : 0); for (uint32 i = 0; i < 2; ++i) data << ClockWorldState[i] << uint32(time(NULL) + (m_Timer / 1000)); @@ -930,20 +845,16 @@ WorldPacket BattlefieldWG::BuildInitWorldStates() data << uint32(BATTLEFIELD_WG_WORLD_STATE_MAX_VEHICLE_A) << GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_A); for (GameObjectBuilding::const_iterator itr = BuildingsInZone.begin(); itr != BuildingsInZone.end(); ++itr) - { data << (*itr)->m_WorldState << (*itr)->m_State; - } + for (Workshop::const_iterator itr = WorkshopsList.begin(); itr != WorkshopsList.end(); ++itr) - { - if (!*itr) - continue; + if (*itr) + data << WorkshopsData[(*itr)->workshopId].worldstate << (*itr)->state; - data << WorkshopsData[(*itr)->workshopId].worldstate << (*itr)->state; - } return data; } -void BattlefieldWG::SendInitWorldStatesTo(Player *player) +void BattlefieldWG::SendInitWorldStatesTo(Player* player) { WorldPacket data = BuildInitWorldStates(); player->GetSession()->SendPacket(&data); @@ -970,47 +881,44 @@ void BattlefieldWG::BrokenWallOrTower(TeamId team) } }*/ } + // Called when a tower is broke -void BattlefieldWG::AddBrokenTower(TeamId team) +void BattlefieldWG::UpdatedDestroyedTowerCount(TeamId team) { // Destroy an attack tower if (team == GetAttackerTeam()) { // Update counter - m_Data32[BATTLEFIELD_WG_DATA_DAMAGED_TOWER_ATT]--; - m_Data32[BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT]++; + UpdateData(BATTLEFIELD_WG_DATA_DAMAGED_TOWER_ATT, -1); + UpdateData(BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT, 1); - // Remove buff stack + // Remove buff stack on attackers for (GuidSet::const_iterator itr = m_PlayersInWar[GetAttackerTeam()].begin(); itr != m_PlayersInWar[GetAttackerTeam()].end(); ++itr) if (Player* player = sObjectAccessor->FindPlayer(*itr)) player->RemoveAuraFromStack(SPELL_TOWER_CONTROL); - // Add buff stack + // Add buff stack to defenders for (GuidSet::const_iterator itr = m_PlayersInWar[GetDefenderTeam()].begin(); itr != m_PlayersInWar[GetDefenderTeam()].end(); ++itr) if (Player* player = sObjectAccessor->FindPlayer(*itr)) { player->CastSpell(player, SPELL_TOWER_CONTROL, true); DoCompleteOrIncrementAchievement(ACHIEVEMENTS_WG_TOWER_DESTROY, player); } - // If the threw south tower is destroy - if (m_Data32[BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT] == 3) + + // If all three south towers are destroyed (ie. all attack towers), remove ten minutes from battle time + if (GetData(BATTLEFIELD_WG_DATA_BROKEN_TOWER_ATT) == 3) { - // Remove 10 minutes to battle time if (int32(m_Timer - 600000) < 0) - { m_Timer = 0; - } else - { m_Timer -= 600000; - } SendInitWorldStatesToAll(); } } else { - m_Data32[BATTLEFIELD_WG_DATA_DAMAGED_TOWER_DEF]--; - m_Data32[BATTLEFIELD_WG_DATA_BROKEN_TOWER_DEF]++; + UpdateData(BATTLEFIELD_WG_DATA_DAMAGED_TOWER_DEF, -1); + UpdateData(BATTLEFIELD_WG_DATA_BROKEN_TOWER_DEF, 1); } } @@ -1025,13 +933,12 @@ void BattlefieldWG::ProcessEvent(WorldObject *obj, uint32 eventId) return; // On click on titan relic - if (go->GetEntry() == BATTLEFIELD_WG_GAMEOBJECT_TITAN_RELIC) + if (go->GetEntry() == GO_WINTERGRASP_TITAN_S_RELIC) { - // Check that the door is break - if (m_CanClickOnOrb) + if (CanInteractWithRelic()) EndBattle(false); - else // if door is not break, respawn relic. - m_relic->SetRespawnTime(RESPAWN_IMMEDIATELY); + else + GetRelic()->SetRespawnTime(RESPAWN_IMMEDIATELY); } // if destroy or damage event, search the wall/tower and update worldstate/send warning message @@ -1051,40 +958,36 @@ void BattlefieldWG::ProcessEvent(WorldObject *obj, uint32 eventId) } // Called when a tower is damaged, used for honor reward calcul -void BattlefieldWG::AddDamagedTower(TeamId team) +void BattlefieldWG::UpdateDamagedTowerCount(TeamId team) { if (team == GetAttackerTeam()) - { - m_Data32[BATTLEFIELD_WG_DATA_DAMAGED_TOWER_ATT]++; - } + UpdateData(BATTLEFIELD_WG_DATA_DAMAGED_TOWER_ATT, 1); else - { - m_Data32[BATTLEFIELD_WG_DATA_DAMAGED_TOWER_DEF]++; - } + UpdateData(BATTLEFIELD_WG_DATA_DAMAGED_TOWER_DEF, 1); } // Update vehicle count WorldState to player void BattlefieldWG::UpdateVehicleCountWG() { - SendUpdateWorldState(BATTLEFIELD_WG_WORLD_STATE_VEHICLE_H, GetData(BATTLEFIELD_WG_DATA_VEHICLE_H)); + SendUpdateWorldState(BATTLEFIELD_WG_WORLD_STATE_VEHICLE_H, GetData(BATTLEFIELD_WG_DATA_VEHICLE_H)); SendUpdateWorldState(BATTLEFIELD_WG_WORLD_STATE_MAX_VEHICLE_H, GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_H)); - SendUpdateWorldState(BATTLEFIELD_WG_WORLD_STATE_VEHICLE_A, GetData(BATTLEFIELD_WG_DATA_VEHICLE_A)); + SendUpdateWorldState(BATTLEFIELD_WG_WORLD_STATE_VEHICLE_A, GetData(BATTLEFIELD_WG_DATA_VEHICLE_A)); SendUpdateWorldState(BATTLEFIELD_WG_WORLD_STATE_MAX_VEHICLE_A, GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_A)); } void BattlefieldWG::UpdateTenacity() { TeamId team = TEAM_NEUTRAL; - uint32 allianceNum = m_PlayersInWar[TEAM_ALLIANCE].size(); - uint32 hordeNum = m_PlayersInWar[TEAM_HORDE].size(); + uint32 alliancePlayers = m_PlayersInWar[TEAM_ALLIANCE].size(); + uint32 hordePlayers = m_PlayersInWar[TEAM_HORDE].size(); int32 newStack = 0; - if (allianceNum && hordeNum) + if (alliancePlayers && hordePlayers) { - if (allianceNum < hordeNum) - newStack = int32((float (hordeNum) / float (allianceNum) - 1) *4); // positive, should cast on alliance - else if (allianceNum > hordeNum) - newStack = int32((1 - float (allianceNum) / float (hordeNum)) *4); // negative, should cast on horde + if (alliancePlayers < hordePlayers) + newStack = int32((float(hordePlayers / alliancePlayers) - 1) * 4); // positive, should cast on alliance + else if (alliancePlayers > hordePlayers) + newStack = int32((1 - float(alliancePlayers / hordePlayers)) * 4); // negative, should cast on horde } if (newStack == int32(m_tenacityStack)) @@ -1121,13 +1024,17 @@ void BattlefieldWG::UpdateTenacity() newStack = 20; uint32 buff_honor = SPELL_GREATEST_HONOR; - buff_honor = (newStack < 15) ? (uint32) SPELL_GREATER_HONOR : buff_honor; - buff_honor = (newStack < 10) ? (uint32) SPELL_GREAT_HONOR : buff_honor; - buff_honor = (newStack < 5) ? 0 : buff_honor; + if (newStack < 15) + buff_honor = SPELL_GREATER_HONOR; + if (newStack < 10) + buff_honor = SPELL_GREAT_HONOR; + if (newStack < 5) + buff_honor = 0; for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr) if (Player* player = sObjectAccessor->FindPlayer(*itr)) player->SetAuraStack(SPELL_TENACITY, player, newStack); + for (GuidSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr) if (Unit* unit = sObjectAccessor->FindUnit(*itr)) if (Creature* creature = unit->ToCreature()) @@ -1137,27 +1044,27 @@ void BattlefieldWG::UpdateTenacity() { for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr) if (Player* player = sObjectAccessor->FindPlayer(*itr)) - player->AddAura(buff_honor, player); + player->CastSpell(player, buff_honor, true); for (GuidSet::const_iterator itr = m_vehicles[team].begin(); itr != m_vehicles[team].end(); ++itr) if (Unit* unit = sObjectAccessor->FindUnit(*itr)) if (Creature* creature = unit->ToCreature()) - creature->AddAura(buff_honor, creature); + creature->CastSpell(creature, buff_honor, true); } } } -void BfCapturePointWG::ChangeTeam(TeamId /*oldTeam */ ) +WintergraspCapturePoint::WintergraspCapturePoint(BattlefieldWG* battlefield, TeamId teamInControl) : BfCapturePoint(battlefield) { - m_WorkShop->ChangeControl(m_team, false); + m_Bf = battlefield; + m_team = teamInControl; } -BfCapturePointWG::BfCapturePointWG(BattlefieldWG* bf, TeamId control) : BfCapturePoint(bf) +void WintergraspCapturePoint::ChangeTeam(TeamId /*oldTeam*/) { - m_Bf = bf; - m_team = control; + m_Workshop->GiveControlTo(m_team, false); } -BfGraveYardWG::BfGraveYardWG(BattlefieldWG* bf) : BfGraveYard(bf) +BfGraveyardWG::BfGraveyardWG(BattlefieldWG* battlefield) : BfGraveyard(battlefield) { - m_Bf = bf; + m_Bf = battlefield; } diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.h b/src/server/game/Battlefield/Zones/BattlefieldWG.h index a7d1d185c8d..b2356e61d64 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.h +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.h @@ -23,38 +23,30 @@ #include "WorldPacket.h" #include "World.h" #include "Group.h" +#include "GroupMgr.h" #include "Battlefield.h" const uint32 VehNumWorldState[2] = { 3680, 3490 }; const uint32 MaxVehNumWorldState[2] = { 3681, 3491 }; const uint32 ClockWorldState[2] = { 3781, 4354 }; const uint32 WintergraspFaction[3] = { 1, 116, 35 }; - const float WintergraspStalkerPos[4] = { 0, 0, 0, 0 }; class BattlefieldWG; -class BfCapturePointWG; +class WintergraspCapturePoint; struct BfWGGameObjectBuilding; struct WGWorkshop; -typedef std::setGameObjectSet; -typedef std::set GameObjectBuilding; +typedef std::set GameObjectSet; +typedef std::set GameObjectBuilding; typedef std::set Workshop; -//typedef std::set CapturePointSet; unused ? -typedef std::set GroupSet; - -enum eWGItem -{ -// *INDENT-OFF* - WG_MARK_OF_HONOR = 43589, -// *INDENT-ON* -}; +typedef std::set GroupSet; +//typedef std::set CapturePointSet; unused ? -enum eWGSpell +enum WintergraspSpells { -// *INDENT-OFF* - // AWartime auras + // Wartime auras SPELL_RECRUIT = 37795, SPELL_CORPORAL = 33280, SPELL_LIEUTENANT = 55629, @@ -93,11 +85,9 @@ enum eWGSpell SPELL_HORDE_CONTROL_PHASE_SHIFT = 55773,// ADDS PHASE 64 SPELL_ALLIANCE_CONTROL_PHASE_SHIFT = 55774,// ADDS PHASE 128 - -// *INDENT-ON* }; -enum eWGData32 +enum WintergraspData { BATTLEFIELD_WG_DATA_DAMAGED_TOWER_DEF, BATTLEFIELD_WG_DATA_BROKEN_TOWER_DEF, @@ -110,9 +100,8 @@ enum eWGData32 BATTLEFIELD_WG_DATA_MAX, }; -enum WB_ACHIEVEMENTS +enum WintergraspAchievements { -// *INDENT-OFF* ACHIEVEMENTS_WIN_WG = 1717, ACHIEVEMENTS_WIN_WG_100 = 1718, // todo ACHIEVEMENTS_WG_GNOMESLAUGHTER = 1723, // todo @@ -129,10 +118,9 @@ enum WB_ACHIEVEMENTS ACHIEVEMENTS_WG_RANGER = 2199, // todo ACHIEVEMENTS_DESTRUCTION_DERBY_H = 2476, // todo ACHIEVEMENTS_WG_MASTER_H = 2776, // todo -// *INDENT-ON* }; -enum eWGWorldStates +enum WintergraspWorldStates { BATTLEFIELD_WG_WORLD_STATE_VEHICLE_H = 3490, BATTLEFIELD_WG_WORLD_STATE_MAX_VEHICLE_H = 3491, @@ -141,9 +129,10 @@ enum eWGWorldStates BATTLEFIELD_WG_WORLD_STATE_ACTIVE = 3801, BATTLEFIELD_WG_WORLD_STATE_DEFENDER = 3802, BATTLEFIELD_WG_WORLD_STATE_ATTACKER = 3803, + BATTLEFIELD_WG_WORLD_STATE_SHOW_WORLDSTATE = 3710, }; -enum WGAreaIds +enum WintergraspAreaIds { AREA_WINTERGRASP_FORTRESS = 4575, AREA_THE_SUNKEN_RING = 4538, @@ -155,18 +144,18 @@ enum WGAreaIds }; /*######################### -*####### Graveyards ######* -#########################*/ + *####### Graveyards ###### + *#########################*/ -class BfGraveYardWG : public BfGraveYard +class BfGraveyardWG : public BfGraveyard { - public: - BfGraveYardWG(BattlefieldWG *Bf); + public: + BfGraveyardWG(BattlefieldWG *Bf); - void SetTextId(uint32 textid) { m_GossipTextId = textid; } - uint32 GetTextId() { return m_GossipTextId; } - protected: - uint32 m_GossipTextId; + void SetTextId(uint32 textid) { m_GossipTextId = textid; } + uint32 GetTextId() { return m_GossipTextId; } + protected: + uint32 m_GossipTextId; }; enum WGGraveyardId @@ -178,12 +167,11 @@ enum WGGraveyardId BATTLEFIELD_WG_GY_KEEP, BATTLEFIELD_WG_GY_HORDE, BATTLEFIELD_WG_GY_ALLIANCE, - BATTLEFIELD_WG_GY_MAX, + BATTLEFIELD_WG_GRAVEYARD_MAX, }; enum eWGGossipText { -// *INDENT-OFF* BATTLEFIELD_WG_GOSSIPTEXT_GY_NE = -1850501, BATTLEFIELD_WG_GOSSIPTEXT_GY_NW = -1850502, BATTLEFIELD_WG_GOSSIPTEXT_GY_SE = -1850504, @@ -191,12 +179,10 @@ enum eWGGossipText BATTLEFIELD_WG_GOSSIPTEXT_GY_KEEP = -1850500, BATTLEFIELD_WG_GOSSIPTEXT_GY_HORDE = -1850505, BATTLEFIELD_WG_GOSSIPTEXT_GY_ALLIANCE = -1850506, -// *INDENT-ON* }; -enum eWGNpc +enum WintergraspNpcs { -// *INDENT-OFF* BATTLEFIELD_WG_NPC_GUARD_H = 30739, BATTLEFIELD_WG_NPC_GUARD_A = 30740, BATTLEFIELD_WG_NPC_STALKER = 15214, @@ -223,7 +209,13 @@ enum eWGNpc NPC_TAUNKA_SPIRIT_GUIDE = 31841, // Horde spirit guide for Wintergrasp NPC_DWARVEN_SPIRIT_GUIDE = 31842, // Alliance spirit guide for Wintergrasp -// *INDENT-ON* + NPC_TOWER_CANNON = 28366, + + NPC_WINTERGRASP_SIEGE_ENGINE_1 = 28312, + NPC_WINTERGRASP_SIEGE_ENGINE_2 = 32627, + NPC_WINTERGRASP_CATAPULT = 27881, + NPC_WINTERGRASP_DEMOLISHER = 28094, + NPC_WINTERGRASP_TOWER_CANNON = 28366, }; struct BfWGCoordGY @@ -243,7 +235,7 @@ const uint32 WGQuest[2][6] = { { 13185, 13183, 13223, 13539, 13178, 13180 }, }; // 7 in sql, 7 in header -const BfWGCoordGY WGGraveYard[BATTLEFIELD_WG_GY_MAX] = { +const BfWGCoordGY WGGraveYard[BATTLEFIELD_WG_GRAVEYARD_MAX] = { { 5104.750f, 2300.940f, 368.579f, 0.733038f, 1329, BATTLEFIELD_WG_GY_WORKSHOP_NE, BATTLEFIELD_WG_GOSSIPTEXT_GY_NE, TEAM_NEUTRAL }, { 5099.120f, 3466.036f, 368.484f, 5.317802f, 1330, BATTLEFIELD_WG_GY_WORKSHOP_NW, BATTLEFIELD_WG_GOSSIPTEXT_GY_NW, TEAM_NEUTRAL }, { 4314.648f, 2408.522f, 392.642f, 6.268125f, 1333, BATTLEFIELD_WG_GY_WORKSHOP_SE, BATTLEFIELD_WG_GOSSIPTEXT_GY_SE, TEAM_NEUTRAL }, @@ -253,136 +245,132 @@ const BfWGCoordGY WGGraveYard[BATTLEFIELD_WG_GY_MAX] = { { 5140.790f, 2179.120f, 390.950f, 1.972220f, 1332, BATTLEFIELD_WG_GY_ALLIANCE, BATTLEFIELD_WG_GOSSIPTEXT_GY_ALLIANCE, TEAM_ALLIANCE }, }; -/*######################### -* BfCapturePointWG * -#########################*/ +/* ######################### * + * WintergraspCapturePoint * + * ######################### */ -class BfCapturePointWG : public BfCapturePoint +class WintergraspCapturePoint : public BfCapturePoint { public: - BfCapturePointWG(BattlefieldWG* bf, TeamId control); + WintergraspCapturePoint(BattlefieldWG* battlefield, TeamId teamInControl); - void LinkToWorkShop(WGWorkshop* ws) - { - m_WorkShop = ws; - } + void LinkToWorkshop(WGWorkshop* workshop) { m_Workshop = workshop; } void ChangeTeam(TeamId oldteam); - TeamId GetTeam() const - { - return m_team; - } + TeamId GetTeam() const { return m_team; } protected: - WGWorkshop *m_WorkShop; + WGWorkshop* m_Workshop; }; -/*######################### -* WinterGrasp Battlefield * -#########################*/ +/* ######################### * + * WinterGrasp Battlefield * + * ######################### */ class BattlefieldWG : public Battlefield { public: /** * \brief Called when the battle start - * -Spawn relic and turret - * -Rebuild tower and wall - * -Invite player to war + * - Spawn relic and turret + * - Rebuild tower and wall + * - Invite player to war */ void OnBattleStart(); /** * \brief Called when battle end - * -Remove relic and turret - * -Change banner/npc in keep if it needed - * -Saving battlestate - * -Reward honor/mark to player - * -Remove vehicle - * \param endbytimer : true if battle end when timer is at 00:00, false if battle end by clicking on relic + * - Remove relic and turret + * - Change banner/npc in keep if it needed + * - Saving battlestate + * - Reward honor/mark to player + * - Remove vehicle + * \param endByTimer : true if battle ended when timer is at 00:00, false if battle ended by clicking on relic */ - void OnBattleEnd(bool endbytimer); + void OnBattleEnd(bool endByTimer); /** - * \brief Called when grouping start (15 minutes before battlestart) - * -Invite all player in zone to join queue + * \brief Called when grouping starts (15 minutes before battlestart) + * - Invite all player in zone to join queue */ void OnStartGrouping(); /** * \brief Called when player accept invite to join battle - * -Update aura - * -Teleport if it needed - * -Update worldstate - * -Update tenacity - * \param player: Player who accept invite + * - Update aura + * - Teleport if it needed + * - Update worldstate + * - Update tenacity + * \param player: Player who accepted invite */ - void OnPlayerJoinWar(Player *player); + void OnPlayerJoinWar(Player* player); /** - * \brief Called when player leave battle - * -Update player aura - * \param player : Player who leave battle + * \brief Called when player left the battle + * - Update player aura + * \param player : Player who left the battle */ - void OnPlayerLeaveWar(Player *player); + void OnPlayerLeaveWar(Player* player); /** - * \brief Called when player leave WG zone - * \param player : Player who leave zone + * \brief Called when player left the WG zone + * \param player : Player who left the zone */ - void OnPlayerLeaveZone(Player *player); + void OnPlayerLeaveZone(Player* player); /** - * \brief Called when player enter in WG zone - * -Update aura - * -Update worldstate - * \param player : Player who leave zone + * \brief Called when player enters in WG zone + * - Update aura + * - Update worldstate + * \param player : Player who enters the zone */ - void OnPlayerEnterZone(Player *player); + void OnPlayerEnterZone(Player* player); /** * \brief Called for update battlefield data - * -Save battle timer in database every minutes - * -Update imunity aura from graveyard - * -Update water aura, if player is in water (HACK) - * \param diff : time ellapsed since the last call (in ms) + * - Save battle timer in database every minutes + * - Update imunity aura from graveyard + * \param diff : time elapsed since the last call (in ms) */ bool Update(uint32 diff); /** * \brief Called when a creature is created - * -Update vehicle count + * - Update vehicle count */ - void OnCreatureCreate(Creature *creature); + void OnCreatureCreate(Creature* creature); - /** + /** * \brief Called when a creature is removed - * -Update vehicle count + * - Update vehicle count */ void OnCreatureRemove(Creature* creature); + /** + * \brief Called when a gameobject is created + */ void OnGameObjectCreate(GameObject* go); /** * \brief Called when a wall/tower is broken - * -Update quest + * - Update quest */ void BrokenWallOrTower(TeamId team); /** * \brief Called when a tower is damaged - * -Update tower count (for reward calcul) + * - Update tower count (for reward calcul) */ - void AddDamagedTower(TeamId team); + void UpdateDamagedTowerCount(TeamId team); /** * \brief Called when tower is broken - * -Update tower buff - * -check if three south tower is down for remove 10 minutes to wg + * - Update tower buff + * - check if three south tower is down for remove 10 minutes to wg */ - void AddBrokenTower(TeamId team); + void UpdatedDestroyedTowerCount(TeamId team); - void DoCompleteOrIncrementAchievement(uint32 achievement, Player *player, uint8 incrementNumber = 1); + void DoCompleteOrIncrementAchievement(uint32 achievement, Player* player, uint8 incrementNumber = 1); void RemoveAurasFromPlayer(Player* player); @@ -392,40 +380,26 @@ class BattlefieldWG : public Battlefield bool SetupBattlefield(); /// Return pointer to relic object - GameObject* GetRelic() - { - return m_relic; - } + GameObject* GetRelic() { return m_titansRelic; } /// Define relic object - void SetRelic(GameObject* relic) - { - m_relic = relic; - } + void SetRelic(GameObject* relic) { m_titansRelic = relic; } - /// Say if player can click or not on orb (last door broken) - bool CanClickOnOrb() - { - return m_CanClickOnOrb; - } + /// Check if players can interact with the relic (Only if the last door has been broken) + bool CanInteractWithRelic() { return m_isRelicInteractible; } - /// Define if player can click or not on orb (if last door broken) - void AllowToClickOnOrb(bool allow) - { - m_CanClickOnOrb = allow; - } - - void RewardMarkOfHonor(Player *player, uint32 count); + /// Define if player can interact with the relic + void SetRelicInteractible(bool allow) { m_isRelicInteractible = allow; } void UpdateVehicleCountWG(); void UpdateCounterVehicle(bool init); WorldPacket BuildInitWorldStates(); - void SendInitWorldStatesTo(Player * player); + void SendInitWorldStatesTo(Player* player); void SendInitWorldStatesToAll(); - void HandleKill(Player *killer, Unit *victim); - void PromotePlayer(Player *killer); + void HandleKill(Player* killer, Unit* victim); + void PromotePlayer(Player* killer); void UpdateTenacity(); void ProcessEvent(WorldObject *obj, uint32 eventId); @@ -435,23 +409,35 @@ class BattlefieldWG : public Battlefield uint32 GetData(uint32 data); protected: - bool m_CanClickOnOrb; - GameObject* m_relic; - GameObjectBuilding BuildingsInZone; - GuidSet KeepCreature[2]; - GuidSet OutsideCreature[2]; + bool m_isRelicInteractible; + Workshop WorkshopsList; - GuidSet CanonList; + GameObjectSet DefenderPortalList; GameObjectSet m_KeepGameObject[2]; + GameObjectBuilding BuildingsInZone; + GuidSet m_vehicles[2]; + GuidSet CanonList; + GuidSet KeepCreature[2]; + GuidSet OutsideCreature[2]; + uint32 m_tenacityStack; uint32 m_saveTimer; + + GameObject* m_titansRelic; }; -#define NORTHREND_WINTERGRASP 4197 +const uint32 NORTHREND_WINTERGRASP = 4197; +const uint8 WG_MAX_OBJ = 32; +const uint8 WG_KEEPGAMEOBJECT_MAX = 44; +const uint8 WG_MAX_TURRET = 15; +const uint8 WG_MAX_KEEP_NPC = 39; +const uint8 WG_MAX_OUTSIDE_NPC = 14; +const uint8 WG_OUTSIDE_ALLIANCE_NPC = 7; +const uint8 WG_MAX_TELEPORTER = 12; -enum eWGGameObjectBuildingType +enum WintergraspGameObjectBuildingType { BATTLEFIELD_WG_OBJECTTYPE_DOOR, BATTLEFIELD_WG_OBJECTTYPE_TITANRELIC, @@ -461,7 +447,7 @@ enum eWGGameObjectBuildingType BATTLEFIELD_WG_OBJECTTYPE_TOWER, }; -enum eWGGameObjectState +enum WintergraspGameObjectState { BATTLEFIELD_WG_OBJECTSTATE_NONE, BATTLEFIELD_WG_OBJECTSTATE_NEUTRAL_INTACT, @@ -475,7 +461,7 @@ enum eWGGameObjectState BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_DESTROY, }; -enum WGWorkshopId +enum WintergraspWorkshopIds { BATTLEFIELD_WG_WORKSHOP_NE, BATTLEFIELD_WG_WORKSHOP_NW, @@ -485,7 +471,7 @@ enum WGWorkshopId BATTLEFIELD_WG_WORKSHOP_KEEP_EAST, }; -enum WGWorldstate +enum WintergraspWorldstates { WORLDSTATE_WORKSHOP_NE = 3701, WORLDSTATE_WORKSHOP_NW = 3700, @@ -494,6 +480,7 @@ enum WGWorldstate WORLDSTATE_WORKSHOP_K_W = 3698, WORLDSTATE_WORKSHOP_K_E = 3699 }; + enum eWGTeamControl { BATTLEFIELD_WG_TEAM_ALLIANCE, @@ -504,7 +491,6 @@ enum eWGTeamControl // TODO: Handle this with creature_text ? enum eWGText { -// *INDENT-OFF* BATTLEFIELD_WG_TEXT_WORKSHOP_NAME_NE = 12055, BATTLEFIELD_WG_TEXT_WORKSHOP_NAME_NW = 12052, BATTLEFIELD_WG_TEXT_WORKSHOP_NAME_SE = 12053, @@ -528,34 +514,42 @@ enum eWGText BATTLEFIELD_WG_TEXT_TOWER_NAME_W = 12071, BATTLEFIELD_WG_TEXT_DEFEND_KEEP = 12068, BATTLEFIELD_WG_TEXT_WIN_KEEP = 12072, -// *INDENT-ON* }; -enum WGObject +enum WintergraspGameObject { -// *INDENT-OFF* - BATTLEFIELD_WG_GAMEOBJECT_FACTORY_BANNER_NE = 190475, - BATTLEFIELD_WG_GAMEOBJECT_FACTORY_BANNER_NW = 190487, - BATTLEFIELD_WG_GAMEOBJECT_FACTORY_BANNER_SE = 194959, - BATTLEFIELD_WG_GAMEOBJECT_FACTORY_BANNER_SW = 194962, - BATTLEFIELD_WG_GAMEOBJECT_TITAN_RELIC = 192829, -// *INDENT-ON* + GO_WINTERGRASP_FACTORY_BANNER_NE = 190475, + GO_WINTERGRASP_FACTORY_BANNER_NW = 190487, + GO_WINTERGRASP_FACTORY_BANNER_SE = 194959, + GO_WINTERGRASP_FACTORY_BANNER_SW = 194962, + + GO_WINTERGRASP_TITAN_S_RELIC = 192829, + + GO_WINTERGRASP_FORTRESS_TOWER_1 = 190221, + GO_WINTERGRASP_FORTRESS_TOWER_2 = 190373, + GO_WINTERGRASP_FORTRESS_TOWER_3 = 190377, + GO_WINTERGRASP_FORTRESS_TOWER_4 = 190378, + + GO_WINTERGRASP_SHADOWSIGHT_TOWER = 190356, + GO_WINTERGRASP_WINTER_S_EDGE_TOWER = 190357, + GO_WINTERGRASP_FLAMEWATCH_TOWER = 190358, }; -struct BfWGObjectPosition + +struct WintergraspObjectPositionData { float x; float y; float z; float o; - uint32 entryh; - uint32 entrya; + uint32 entryHorde; + uint32 entryAlliance; }; -// ********************************************************* -// ************Destructible (Wall,Tower..)****************** -// ********************************************************* +// ***************************************************** +// ************ Destructible (Wall,Tower..) ************ +// ***************************************************** -struct BfWGBuildingSpawnData +struct WintergraspBuildingSpawnData { uint32 entry; uint32 WorldState; @@ -564,13 +558,12 @@ struct BfWGBuildingSpawnData float z; float o; uint32 type; - uint32 nameid; + uint32 nameId; }; -#define WG_MAX_OBJ 32 -const BfWGBuildingSpawnData WGGameObjectBuillding[WG_MAX_OBJ] = { +const WintergraspBuildingSpawnData WGGameObjectBuilding[WG_MAX_OBJ] = { // Wall (Not spawned in db) - // Entry WS X Y Z O type NameID + // Entry WS X Y Z O type NameID { 190219, 3749, 5371.46f, 3047.47f, 407.571f, 3.14159f, BATTLEFIELD_WG_OBJECTTYPE_WALL, 0 }, { 190220, 3750, 5331.26f, 3047.1f, 407.923f, 0.052359f, BATTLEFIELD_WG_OBJECTTYPE_WALL, 0 }, { 191795, 3764, 5385.84f, 2909.49f, 409.713f, 0.00872f, BATTLEFIELD_WG_OBJECTTYPE_WALL, 0 }, @@ -660,8 +653,7 @@ const BfWGBuildingSpawnData WGGameObjectBuillding[WG_MAX_OBJ] = { // 192357 : 1 in sql, 1 in header // 192350 : 1 in sql, 1 in header // 192351 : 1 in sql, 1 in header -#define WG_KEEPGAMEOBJECT_MAX 44 -const BfWGObjectPosition WGKeepGameObject[WG_KEEPGAMEOBJECT_MAX] = { +const WintergraspObjectPositionData WGKeepGameObject[WG_KEEPGAMEOBJECT_MAX] = { { 5262.540039f, 3047.949951f, 432.054993f, 3.106650f, 192488, 192501 }, // Flag on tower { 5272.939941f, 2976.550049f, 444.492004f, 3.124120f, 192374, 192416 }, // Flag on Wall Intersect { 5235.189941f, 2941.899902f, 444.278015f, 1.588250f, 192375, 192416 }, // Flag on Wall Intersect @@ -708,42 +700,31 @@ const BfWGObjectPosition WGKeepGameObject[WG_KEEPGAMEOBJECT_MAX] = { { 5271.279785f, 2820.159912f, 445.200989f, -3.13286f, 192351, 192416 } // Flag on wall intersect }; -// Keep turret -struct BfWGTurretPos -{ - float x; - float y; - float z; - float o; -}; - -#define WG_MAX_TURRET 15 -const BfWGTurretPos WGTurret[WG_MAX_TURRET] = { - { 5391.19f, 3060.8f, 419.616f, 1.69557f }, - { 5266.75f, 2976.5f, 421.067f, 3.20354f }, - { 5234.86f, 2948.8f, 420.88f, 1.61311f }, - { 5323.05f, 2923.7f, 421.645f, 1.5817f }, +const Position WGTurret[WG_MAX_TURRET] = { + { 5391.19f, 3060.8f, 419.616f, 1.69557f }, + { 5266.75f, 2976.5f, 421.067f, 3.20354f }, + { 5234.86f, 2948.8f, 420.88f, 1.61311f }, + { 5323.05f, 2923.7f, 421.645f, 1.5817f }, { 5363.82f, 2923.87f, 421.709f, 1.60527f }, { 5264.04f, 2861.34f, 421.587f, 3.21142f }, { 5264.68f, 2819.78f, 421.656f, 3.15645f }, { 5322.16f, 2756.69f, 421.646f, 4.69978f }, { 5363.78f, 2756.77f, 421.629f, 4.78226f }, - { 5236.2f, 2732.68f, 421.649f, 4.72336f }, - { 5265.02f, 2704.63f, 421.7f, 3.12507f }, + { 5236.2f, 2732.68f, 421.649f, 4.72336f }, + { 5265.02f, 2704.63f, 421.7f, 3.12507f }, { 5350.87f, 2616.03f, 421.243f, 4.72729f }, - { 5390.95f, 2615.5f, 421.126f, 4.6409f }, - { 5148.8f, 2820.24f, 421.621f, 3.16043f }, - { 5147.98f, 2861.93f, 421.63f, 3.18792f }, + { 5390.95f, 2615.5f, 421.126f, 4.6409f }, + { 5148.8f, 2820.24f, 421.621f, 3.16043f }, + { 5147.98f, 2861.93f, 421.63f, 3.18792f }, }; - // Here there is all npc keeper spawn point -#define WG_MAX_KEEP_NPC 39 -const BfWGObjectPosition WGKeepNPC[WG_MAX_KEEP_NPC] = { +const WintergraspObjectPositionData WGKeepNPC[WG_MAX_KEEP_NPC] = +{ // X Y Z O horde alliance // North East { 5326.203125f, 2660.026367f, 409.100891f, 2.543383f, BATTLEFIELD_WG_NPC_GUARD_H, BATTLEFIELD_WG_NPC_GUARD_A }, // Roaming Guard - { 5298.430176f, 2738.760010f, 409.316010f, 3.971740f, BATTLEFIELD_WG_NPC_VIERON_BLAZEFEATHER, BATTLEFIELD_WG_NPC_BOWYER_RANDOLPH }, // Vieron Plumembrase + { 5298.430176f, 2738.760010f, 409.316010f, 3.971740f, BATTLEFIELD_WG_NPC_VIERON_BLAZEFEATHER, BATTLEFIELD_WG_NPC_BOWYER_RANDOLPH }, // Vieron Blazefeather { 5335.310059f, 2764.110107f, 409.274994f, 4.834560f, BATTLEFIELD_WG_NPC_GUARD_H, BATTLEFIELD_WG_NPC_GUARD_A }, // Standing Guard { 5349.810059f, 2763.629883f, 409.333008f, 4.660030f, BATTLEFIELD_WG_NPC_GUARD_H, BATTLEFIELD_WG_NPC_GUARD_A }, // Standing Guard // North @@ -789,9 +770,7 @@ const BfWGObjectPosition WGKeepNPC[WG_MAX_KEEP_NPC] = { { 5316.770996f, 2619.430176f, 409.027740f, 5.363431f, BATTLEFIELD_WG_NPC_GUARD_H, BATTLEFIELD_WG_NPC_GUARD_A } // Standing Guard }; -#define WG_MAX_OUTSIDE_NPC 14 -#define WG_OUTSIDE_ALLIANCE_NPC 7 -const BfWGObjectPosition WGOutsideNPC[WG_MAX_OUTSIDE_NPC] = +const WintergraspObjectPositionData WGOutsideNPC[WG_MAX_OUTSIDE_NPC] = { { 5032.04f, 3681.79f, 362.980f, 4.210f, BATTLEFIELD_WG_NPC_VIERON_BLAZEFEATHER, 0 }, { 5020.71f, 3626.19f, 360.150f, 4.640f, BATTLEFIELD_WG_NPC_HOODOO_MASTER_FU_JIN, 0 }, @@ -809,17 +788,16 @@ const BfWGObjectPosition WGOutsideNPC[WG_MAX_OUTSIDE_NPC] = { 5080.40f, 2199.00f, 359.489f, 2.967f, 0, BATTLEFIELD_WG_NPC_SENIOR_DEMOLITIONIST_LEGOSO }, }; -struct BfWGWGTeleporterData +struct WintergraspTeleporterData { - uint32 entry; // gameobject entry + uint32 entry; float x; float y; float z; float o; }; -#define WG_MAX_TELEPORTER 12 -const BfWGWGTeleporterData WGPortalDefenderData[WG_MAX_TELEPORTER] = +const WintergraspTeleporterData WGPortalDefenderData[WG_MAX_TELEPORTER] = { // Player teleporter { 190763, 5153.41f, 2901.35f, 409.191f, -0.069f }, @@ -841,23 +819,23 @@ const BfWGWGTeleporterData WGPortalDefenderData[WG_MAX_TELEPORTER] = // **********Tower Element(GameObject,Creature)************* // ********************************************************* -struct BfWGTowerData +struct WintergraspTowerData { - uint32 towerentry; // Gameobject id of tower + uint32 towerEntry; // Gameobject id of tower uint8 nbObject; // Number of gameobjects spawned on this point - BfWGObjectPosition GameObject[6]; // Gameobject position and entry (Horde/Alliance) + WintergraspObjectPositionData GameObject[6]; // Gameobject position and entry (Horde/Alliance) // Creature : Turrets and Guard, TODO: check if killed on tower destruction? tower damage? uint8 nbCreatureBottom; - BfWGObjectPosition CreatureBottom[9]; + WintergraspObjectPositionData CreatureBottom[9]; uint8 nbCreatureTop; - BfWGObjectPosition CreatureTop[5]; + WintergraspObjectPositionData CreatureTop[5]; }; -#define WG_MAX_ATTACKTOWERS 3 +uint8 const WG_MAX_ATTACKTOWERS = 3; // 192414 : 0 in sql, 1 in header // 192278 : 0 in sql, 3 in header -const BfWGTowerData AttackTowers[WG_MAX_ATTACKTOWERS] = { +const WintergraspTowerData AttackTowers[WG_MAX_ATTACKTOWERS] = { // West tower { 190356, @@ -961,18 +939,18 @@ const BfWGTowerData AttackTowers[WG_MAX_ATTACKTOWERS] = { }, }; -struct BfWGTurretData +struct WintergraspTowerCannonData { - uint32 towerentry; - uint8 nbTurretBottom; - BfWGTurretPos TurretBottom[5]; + uint32 towerEntry; + uint8 nbTowerCannonBottom; + Position TowerCannonBottom[5]; uint8 nbTurretTop; - BfWGTurretPos TurretTop[5]; + Position TurretTop[5]; }; -#define WG_MAX_TOWERTURRET 7 +const uint8 WG_MAX_TOWER_CANNON = 7; -const BfWGTurretData TowerTurret[WG_MAX_TOWERTURRET] = +const WintergraspTowerCannonData TowerCannon[WG_MAX_TOWER_CANNON] = { { 190221, @@ -1113,7 +1091,7 @@ const BfWGTurretData TowerTurret[WG_MAX_TOWERTURRET] = // *****************WorkShop Data & Element***************** // ********************************************************* -#define WG_MAX_WORKSHOP 6 +uint8 const WG_MAX_WORKSHOP = 6; struct WGWorkshopData { @@ -1162,7 +1140,7 @@ struct BfWGGameObjectBuilding BattlefieldWG *m_WG; // Linked gameobject - GameObject *m_Build; + GameObject* m_Build; // eWGGameObjectBuildingType uint32 m_Type; @@ -1182,7 +1160,7 @@ struct BfWGGameObjectBuilding // Creature associations GuidSet m_CreatureBottomList[2]; GuidSet m_CreatureTopList[2]; - GuidSet m_TurretBottomList; + GuidSet m_TowerCannonBottomList; GuidSet m_TurretTopList; void Rebuild() @@ -1235,9 +1213,9 @@ struct BfWGGameObjectBuilding m_WG->HideNpc(creature); if (m_Type == BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER) - m_WG->AddDamagedTower(m_WG->GetDefenderTeam()); + m_WG->UpdateDamagedTowerCount(m_WG->GetDefenderTeam()); else if (m_Type == BATTLEFIELD_WG_OBJECTTYPE_TOWER) - m_WG->AddDamagedTower(m_WG->GetAttackerTeam()); + m_WG->UpdateDamagedTowerCount(m_WG->GetAttackerTeam()); } // Called when associated gameobject is destroyed @@ -1256,14 +1234,14 @@ struct BfWGGameObjectBuilding // Inform the global wintergrasp script of the destruction of this object case BATTLEFIELD_WG_OBJECTTYPE_TOWER: case BATTLEFIELD_WG_OBJECTTYPE_KEEP_TOWER: - m_WG->AddBrokenTower(TeamId(m_Team)); + m_WG->UpdatedDestroyedTowerCount(TeamId(m_Team)); break; case BATTLEFIELD_WG_OBJECTTYPE_DOOR_LAST: - m_WG->AllowToClickOnOrb(true); + m_WG->SetRelicInteractible(true); if (m_WG->GetRelic()) m_WG->GetRelic()->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); else - sLog->outError("BATTLEFIELD: WG: Relic cant be clickable"); + sLog->outError("BattlefieldWG: Relic not found."); break; } @@ -1323,58 +1301,58 @@ struct BfWGGameObjectBuilding int32 towerid = -1; switch (go->GetEntry()) { - case 190221: + case GO_WINTERGRASP_FORTRESS_TOWER_1: towerid = 0; break; - case 190373: + case GO_WINTERGRASP_FORTRESS_TOWER_2: towerid = 1; break; - case 190377: + case GO_WINTERGRASP_FORTRESS_TOWER_3: towerid = 2; break; - case 190378: + case GO_WINTERGRASP_FORTRESS_TOWER_4: towerid = 3; break; - case 190356: + case GO_WINTERGRASP_SHADOWSIGHT_TOWER: towerid = 4; break; - case 190357: + case GO_WINTERGRASP_WINTER_S_EDGE_TOWER: towerid = 5; break; - case 190358: + case GO_WINTERGRASP_FLAMEWATCH_TOWER: towerid = 6; break; } - if (towerid > 3) + if (towerid > 3) // Attacker towers { // Spawn associate gameobjects for (uint8 i = 0; i < AttackTowers[towerid - 4].nbObject; i++) { - BfWGObjectPosition gob = AttackTowers[towerid - 4].GameObject[i]; - if (GameObject *go = m_WG->SpawnGameObject(gob.entryh, gob.x, gob.y, gob.z, gob.o)) + WintergraspObjectPositionData gobData = AttackTowers[towerid - 4].GameObject[i]; + if (GameObject* go = m_WG->SpawnGameObject(gobData.entryHorde, gobData.x, gobData.y, gobData.z, gobData.o)) m_GameObjectList[TEAM_HORDE].insert(go); - if (GameObject *go = m_WG->SpawnGameObject(gob.entrya, gob.x, gob.y, gob.z, gob.o)) + if (GameObject* go = m_WG->SpawnGameObject(gobData.entryAlliance, gobData.x, gobData.y, gobData.z, gobData.o)) m_GameObjectList[TEAM_ALLIANCE].insert(go); } // Spawn associate npc bottom for (uint8 i = 0; i < AttackTowers[towerid - 4].nbCreatureBottom; i++) { - BfWGObjectPosition crea = AttackTowers[towerid - 4].CreatureBottom[i]; - if (Creature *creature = m_WG->SpawnCreature(crea.entryh, crea.x, crea.y, crea.z, crea.o, TEAM_HORDE)) + WintergraspObjectPositionData creatureData = AttackTowers[towerid - 4].CreatureBottom[i]; + if (Creature* creature = m_WG->SpawnCreature(creatureData.entryHorde, creatureData.x, creatureData.y, creatureData.z, creatureData.o, TEAM_HORDE)) m_CreatureBottomList[TEAM_HORDE].insert(creature->GetGUID()); - if (Creature *creature = m_WG->SpawnCreature(crea.entrya, crea.x, crea.y, crea.z, crea.o, TEAM_ALLIANCE)) + if (Creature* creature = m_WG->SpawnCreature(creatureData.entryAlliance, creatureData.x, creatureData.y, creatureData.z, creatureData.o, TEAM_ALLIANCE)) m_CreatureBottomList[TEAM_ALLIANCE].insert(creature->GetGUID()); } // Spawn associate npc top for (uint8 i = 0; i < AttackTowers[towerid - 4].nbCreatureTop; i++) { - BfWGObjectPosition crea = AttackTowers[towerid - 4].CreatureTop[i]; - if (Creature *creature = m_WG->SpawnCreature(crea.entryh, crea.x, crea.y, crea.z, crea.o, TEAM_HORDE)) + WintergraspObjectPositionData creatureData = AttackTowers[towerid - 4].CreatureTop[i]; + if (Creature* creature = m_WG->SpawnCreature(creatureData.entryHorde, creatureData.x, creatureData.y, creatureData.z, creatureData.o, TEAM_HORDE)) m_CreatureTopList[TEAM_HORDE].insert(creature->GetGUID()); - if (Creature *creature = m_WG->SpawnCreature(crea.entrya, crea.x, crea.y, crea.z, crea.o, TEAM_ALLIANCE)) + if (Creature* creature = m_WG->SpawnCreature(creatureData.entryAlliance, creatureData.x, creatureData.y, creatureData.z, creatureData.o, TEAM_ALLIANCE)) m_CreatureTopList[TEAM_ALLIANCE].insert(creature->GetGUID()); } } @@ -1382,58 +1360,52 @@ struct BfWGGameObjectBuilding if (towerid >= 0) { // Spawn Turret bottom - for (uint8 i = 0; i < TowerTurret[towerid].nbTurretBottom; i++) + for (uint8 i = 0; i < TowerCannon[towerid].nbTowerCannonBottom; i++) { - BfWGTurretPos turretpos = TowerTurret[towerid].TurretBottom[i]; - if (Creature *turret = m_WG->SpawnCreature(28366, turretpos.x, turretpos.y, turretpos.z, turretpos.o, TeamId(0))) + Position turretPos; + TowerCannon[towerid].TowerCannonBottom[i].GetPosition(&turretPos); + if (Creature* turret = m_WG->SpawnCreature(NPC_WINTERGRASP_TOWER_CANNON, turretPos, TEAM_ALLIANCE)) { - m_TurretBottomList.insert(turret->GetGUID()); + m_TowerCannonBottomList.insert(turret->GetGUID()); switch (go->GetEntry()) { - case 190221: - case 190373: - case 190377: - case 190378: - { - turret->setFaction(WintergraspFaction[m_WG->GetDefenderTeam()]); - break; - } - case 190356: - case 190357: - case 190358: - { - turret->setFaction(WintergraspFaction[m_WG->GetAttackerTeam()]); - break; - } + case GO_WINTERGRASP_FORTRESS_TOWER_1: + case GO_WINTERGRASP_FORTRESS_TOWER_2: + case GO_WINTERGRASP_FORTRESS_TOWER_3: + case GO_WINTERGRASP_FORTRESS_TOWER_4: + turret->setFaction(WintergraspFaction[m_WG->GetDefenderTeam()]); + break; + case GO_WINTERGRASP_SHADOWSIGHT_TOWER: + case GO_WINTERGRASP_WINTER_S_EDGE_TOWER: + case GO_WINTERGRASP_FLAMEWATCH_TOWER: + turret->setFaction(WintergraspFaction[m_WG->GetAttackerTeam()]); + break; } m_WG->HideNpc(turret); } } // Spawn Turret top - for (uint8 i = 0; i < TowerTurret[towerid].nbTurretTop; i++) + for (uint8 i = 0; i < TowerCannon[towerid].nbTurretTop; i++) { - BfWGTurretPos turretpos = TowerTurret[towerid].TurretTop[i]; - if (Creature *turret = m_WG->SpawnCreature(28366, turretpos.x, turretpos.y, turretpos.z, turretpos.o, TeamId(0))) + Position towerCannonPos; + TowerCannon[towerid].TurretTop[i].GetPosition(&towerCannonPos); + if (Creature *turret = m_WG->SpawnCreature(28366, towerCannonPos, TeamId(0))) { m_TurretTopList.insert(turret->GetGUID()); switch (go->GetEntry()) { - case 190221: - case 190373: - case 190377: - case 190378: - { - turret->setFaction(WintergraspFaction[m_WG->GetDefenderTeam()]); - break; - } - case 190356: - case 190357: - case 190358: - { - turret->setFaction(WintergraspFaction[m_WG->GetAttackerTeam()]); - break; - } + case GO_WINTERGRASP_FORTRESS_TOWER_1: + case GO_WINTERGRASP_FORTRESS_TOWER_2: + case GO_WINTERGRASP_FORTRESS_TOWER_3: + case GO_WINTERGRASP_FORTRESS_TOWER_4: + turret->setFaction(WintergraspFaction[m_WG->GetDefenderTeam()]); + break; + case GO_WINTERGRASP_SHADOWSIGHT_TOWER: + case GO_WINTERGRASP_WINTER_S_EDGE_TOWER: + case GO_WINTERGRASP_FLAMEWATCH_TOWER: + turret->setFaction(WintergraspFaction[m_WG->GetAttackerTeam()]); + break; } m_WG->HideNpc(turret); } @@ -1473,7 +1445,7 @@ struct BfWGGameObjectBuilding void UpdateTurretAttack(bool disable) { - for (GuidSet::const_iterator itr = m_TurretBottomList.begin(); itr != m_TurretBottomList.end(); ++itr) + for (GuidSet::const_iterator itr = m_TowerCannonBottomList.begin(); itr != m_TowerCannonBottomList.end(); ++itr) { if (Unit* unit = sObjectAccessor->FindUnit(*itr)) { @@ -1607,14 +1579,13 @@ struct WGWorkshop WGWorkshop(BattlefieldWG* _bf, uint8 _workshopId) { - ASSERT(_bf); - ASSERT(_workshopId < WG_MAX_WORKSHOP); + ASSERT(_bf || _workshopId < WG_MAX_WORKSHOP); bf = _bf; workshopId = _workshopId; } - void ChangeControl(uint8 team, bool init /* for first call in setup */ ) + void GiveControlTo(uint8 team, bool init /* for first call in setup*/) { switch (team) { @@ -1638,8 +1609,8 @@ struct WGWorkshop // Found associate graveyard and update it if (workshopId < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST) - if (bf->GetGraveYardById(workshopId)) - bf->GetGraveYardById(workshopId)->ChangeControl(team == BATTLEFIELD_WG_TEAM_ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE); + if (bf->GetGraveyardById(workshopId)) + bf->GetGraveyardById(workshopId)->GiveControlTo(team == BATTLEFIELD_WG_TEAM_ALLIANCE ? TEAM_ALLIANCE : TEAM_HORDE); teamControl = team; break; @@ -1650,12 +1621,12 @@ struct WGWorkshop bf->UpdateCounterVehicle(false); } - void UpdateGraveYardAndWorkshop() + void UpdateGraveyardAndWorkshop() { if (workshopId < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST) - bf->GetGraveYardById(workshopId)->ChangeControl(TeamId(teamControl)); + bf->GetGraveyardById(workshopId)->GiveControlTo(TeamId(teamControl)); else - ChangeControl(bf->GetDefenderTeam(), true); + GiveControlTo(bf->GetDefenderTeam(), true); } void Save() @@ -1665,9 +1636,9 @@ struct WGWorkshop }; // Structure for the 6 workshop -struct BfWGWorkShopData +struct WintergraspWorkshopData { - BattlefieldWG* m_WG; // Object du joug + BattlefieldWG* m_WG; // Pointer to wintergrasp GameObject* m_Build; uint32 m_Type; uint32 m_State; // For worldstate @@ -1677,7 +1648,7 @@ struct BfWGWorkShopData GameObjectSet m_GameObjectOnPoint[2]; // Contain all Gameobject associate to this point uint32 m_NameId; // Id of trinity_string witch contain name of this node, using for alert message - BfWGWorkShopData(BattlefieldWG * WG) + WintergraspWorkshopData(BattlefieldWG * WG) { m_WG = WG; m_Build = NULL; @@ -1689,22 +1660,21 @@ struct BfWGWorkShopData } // Spawning associate creature and store them - void AddCreature(BfWGObjectPosition obj) + void AddCreature(WintergraspObjectPositionData obj) { - if (Creature *creature = m_WG->SpawnCreature(obj.entryh, obj.x, obj.y, obj.z, obj.o, TEAM_HORDE)) + if (Creature* creature = m_WG->SpawnCreature(obj.entryHorde, obj.x, obj.y, obj.z, obj.o, TEAM_HORDE)) m_CreatureOnPoint[TEAM_HORDE].insert(creature->GetGUID()); - if (Creature *creature = m_WG->SpawnCreature(obj.entrya, obj.x, obj.y, obj.z, obj.o, TEAM_ALLIANCE)) + if (Creature* creature = m_WG->SpawnCreature(obj.entryAlliance, obj.x, obj.y, obj.z, obj.o, TEAM_ALLIANCE)) m_CreatureOnPoint[TEAM_ALLIANCE].insert(creature->GetGUID()); - } // Spawning Associate gameobject and store them - void AddGameObject(BfWGObjectPosition obj) + void AddGameObject(WintergraspObjectPositionData obj) { - if (GameObject *gameobject = m_WG->SpawnGameObject(obj.entryh, obj.x, obj.y, obj.z, obj.o)) + if (GameObject *gameobject = m_WG->SpawnGameObject(obj.entryHorde, obj.x, obj.y, obj.z, obj.o)) m_GameObjectOnPoint[TEAM_HORDE].insert(gameobject); - if (GameObject *gameobject = m_WG->SpawnGameObject(obj.entrya, obj.x, obj.y, obj.z, obj.o)) + if (GameObject *gameobject = m_WG->SpawnGameObject(obj.entryAlliance, obj.x, obj.y, obj.z, obj.o)) m_GameObjectOnPoint[TEAM_ALLIANCE].insert(gameobject); } @@ -1717,105 +1687,105 @@ struct BfWGWorkShopData } // Called on change faction in CapturePoint class - void ChangeControl(uint8 team, bool init /* for first call in setup */ ) + void GiveControlTo(uint8 team, bool init /* for first call in setup*/) { switch (team) { case BATTLEFIELD_WG_TEAM_NEUTRAL: - { - // Send warning message to all player for inform a faction attack a workshop - // alliance / horde attacking workshop - m_WG->SendWarningToAllInZone(m_TeamControl ? m_NameId : m_NameId + 1); - break; - } + { + // Send warning message to all player for inform a faction attack a workshop + // alliance / horde attacking workshop + m_WG->SendWarningToAllInZone(m_TeamControl ? m_NameId : m_NameId + 1); + break; + } case BATTLEFIELD_WG_TEAM_ALLIANCE: - { - // Show Alliance creature - for (GuidSet::const_iterator itr = m_CreatureOnPoint[TEAM_ALLIANCE].begin(); itr != m_CreatureOnPoint[TEAM_ALLIANCE].end(); ++itr) - if (Unit* unit = sObjectAccessor->FindUnit(*itr)) - if (Creature* creature = unit->ToCreature()) - m_WG->ShowNpc(creature, creature->GetEntry() != 30499); - - // Hide Horde creature - for (GuidSet::const_iterator itr = m_CreatureOnPoint[TEAM_HORDE].begin(); itr != m_CreatureOnPoint[TEAM_HORDE].end(); ++itr) - if (Unit* unit = sObjectAccessor->FindUnit(*itr)) - if (Creature* creature = unit->ToCreature()) - m_WG->HideNpc(creature); + { + // Show Alliance creature + for (GuidSet::const_iterator itr = m_CreatureOnPoint[TEAM_ALLIANCE].begin(); itr != m_CreatureOnPoint[TEAM_ALLIANCE].end(); ++itr) + if (Unit* unit = sObjectAccessor->FindUnit(*itr)) + if (Creature* creature = unit->ToCreature()) + m_WG->ShowNpc(creature, creature->GetEntry() != 30499); + + // Hide Horde creature + for (GuidSet::const_iterator itr = m_CreatureOnPoint[TEAM_HORDE].begin(); itr != m_CreatureOnPoint[TEAM_HORDE].end(); ++itr) + if (Unit* unit = sObjectAccessor->FindUnit(*itr)) + if (Creature* creature = unit->ToCreature()) + m_WG->HideNpc(creature); - // Show Alliance gameobject - for (GameObjectSet::const_iterator itr = m_GameObjectOnPoint[TEAM_ALLIANCE].begin(); itr != m_GameObjectOnPoint[TEAM_ALLIANCE].end(); ++itr) - (*itr)->SetRespawnTime(RESPAWN_IMMEDIATELY); + // Show Alliance gameobject + for (GameObjectSet::const_iterator itr = m_GameObjectOnPoint[TEAM_ALLIANCE].begin(); itr != m_GameObjectOnPoint[TEAM_ALLIANCE].end(); ++itr) + (*itr)->SetRespawnTime(RESPAWN_IMMEDIATELY); - // Hide Horde gameobject - for (GameObjectSet::const_iterator itr = m_GameObjectOnPoint[TEAM_HORDE].begin(); itr != m_GameObjectOnPoint[TEAM_HORDE].end(); ++itr) - (*itr)->SetRespawnTime(RESPAWN_ONE_DAY); + // Hide Horde gameobject + for (GameObjectSet::const_iterator itr = m_GameObjectOnPoint[TEAM_HORDE].begin(); itr != m_GameObjectOnPoint[TEAM_HORDE].end(); ++itr) + (*itr)->SetRespawnTime(RESPAWN_ONE_DAY); - // Updating worldstate - m_State = BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT; - m_WG->SendUpdateWorldState(m_WorldState, m_State); + // Updating worldstate + m_State = BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT; + m_WG->SendUpdateWorldState(m_WorldState, m_State); - // Warning message - if (!init) // workshop taken - alliance - m_WG->SendWarningToAllInZone(m_NameId); + // Warning message + if (!init) // workshop taken - alliance + m_WG->SendWarningToAllInZone(m_NameId); - // Found associate graveyard and update it - if (m_Type < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST) - if (m_WG && m_WG->GetGraveYardById(m_Type)) - m_WG->GetGraveYardById(m_Type)->ChangeControl(TEAM_ALLIANCE); + // Found associate graveyard and update it + if (m_Type < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST) + if (m_WG && m_WG->GetGraveyardById(m_Type)) + m_WG->GetGraveyardById(m_Type)->GiveControlTo(TEAM_ALLIANCE); - m_TeamControl = team; - break; - } + m_TeamControl = team; + break; + } case BATTLEFIELD_WG_TEAM_HORDE: - { - // Show Horde creature - for (GuidSet::const_iterator itr = m_CreatureOnPoint[TEAM_HORDE].begin(); itr != m_CreatureOnPoint[TEAM_HORDE].end(); ++itr) - if (Unit* unit = sObjectAccessor->FindUnit(*itr)) - if (Creature* creature = unit->ToCreature()) - m_WG->ShowNpc(creature, creature->GetEntry() != 30400); - - // Hide Alliance creature - for (GuidSet::const_iterator itr = m_CreatureOnPoint[TEAM_ALLIANCE].begin(); itr != m_CreatureOnPoint[TEAM_ALLIANCE].end(); ++itr) - if (Unit* unit = sObjectAccessor->FindUnit(*itr)) - if (Creature* creature = unit->ToCreature()) - m_WG->HideNpc(creature); + { + // Show Horde creature + for (GuidSet::const_iterator itr = m_CreatureOnPoint[TEAM_HORDE].begin(); itr != m_CreatureOnPoint[TEAM_HORDE].end(); ++itr) + if (Unit* unit = sObjectAccessor->FindUnit(*itr)) + if (Creature* creature = unit->ToCreature()) + m_WG->ShowNpc(creature, creature->GetEntry() != 30400); + + // Hide Alliance creature + for (GuidSet::const_iterator itr = m_CreatureOnPoint[TEAM_ALLIANCE].begin(); itr != m_CreatureOnPoint[TEAM_ALLIANCE].end(); ++itr) + if (Unit* unit = sObjectAccessor->FindUnit(*itr)) + if (Creature* creature = unit->ToCreature()) + m_WG->HideNpc(creature); - // Hide Alliance gameobject - for (GameObjectSet::const_iterator itr = m_GameObjectOnPoint[TEAM_ALLIANCE].begin(); itr != m_GameObjectOnPoint[TEAM_ALLIANCE].end(); ++itr) - (*itr)->SetRespawnTime(RESPAWN_ONE_DAY); + // Hide Alliance gameobject + for (GameObjectSet::const_iterator itr = m_GameObjectOnPoint[TEAM_ALLIANCE].begin(); itr != m_GameObjectOnPoint[TEAM_ALLIANCE].end(); ++itr) + (*itr)->SetRespawnTime(RESPAWN_ONE_DAY); - // Show Horde gameobject - for (GameObjectSet::const_iterator itr = m_GameObjectOnPoint[TEAM_HORDE].begin(); itr != m_GameObjectOnPoint[TEAM_HORDE].end(); ++itr) - (*itr)->SetRespawnTime(RESPAWN_IMMEDIATELY); + // Show Horde gameobject + for (GameObjectSet::const_iterator itr = m_GameObjectOnPoint[TEAM_HORDE].begin(); itr != m_GameObjectOnPoint[TEAM_HORDE].end(); ++itr) + (*itr)->SetRespawnTime(RESPAWN_IMMEDIATELY); - // Update worlstate - m_State = BATTLEFIELD_WG_OBJECTSTATE_HORDE_INTACT; - m_WG->SendUpdateWorldState(m_WorldState, m_State); + // Update worlstate + m_State = BATTLEFIELD_WG_OBJECTSTATE_HORDE_INTACT; + m_WG->SendUpdateWorldState(m_WorldState, m_State); - // Warning message - if (!init) // workshop taken - horde - m_WG->SendWarningToAllInZone(m_NameId + 1); + // Warning message + if (!init) // workshop taken - horde + m_WG->SendWarningToAllInZone(m_NameId + 1); - // Update graveyard control - if (m_Type < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST) - if (m_WG && m_WG->GetGraveYardById(m_Type)) - m_WG->GetGraveYardById(m_Type)->ChangeControl(TEAM_HORDE); + // Update graveyard control + if (m_Type < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST) + if (m_WG && m_WG->GetGraveyardById(m_Type)) + m_WG->GetGraveyardById(m_Type)->GiveControlTo(TEAM_HORDE); - m_TeamControl = team; - break; - } + m_TeamControl = team; + break; + } } if (!init) m_WG->UpdateCounterVehicle(false); } - void UpdateGraveYardAndWorkshop() + void UpdateGraveyardAndWorkshop() { if (m_Type < BATTLEFIELD_WG_WORKSHOP_KEEP_WEST) - m_WG->GetGraveYardById(m_Type)->ChangeControl(TeamId(m_TeamControl)); + m_WG->GetGraveyardById(m_Type)->GiveControlTo(TeamId(m_TeamControl)); else - ChangeControl(m_WG->GetDefenderTeam(), true); + GiveControlTo(m_WG->GetDefenderTeam(), true); } void Save() diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 044bf7fb32e..da0d37cf27a 100755 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -821,11 +821,6 @@ class ObjectMgr return &_creatureQuestRelations; } - QuestRelations* GetCreatureQuestInvolvedRelation() - { - return &_creatureQuestInvolvedRelations; - } - QuestRelationBounds GetCreatureQuestRelationBounds(uint32 creature_entry) { return _creatureQuestRelations.equal_range(creature_entry); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 8bddd63170d..98a8f3e5641 100755 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -800,7 +800,7 @@ class WorldSession // Battlefield void SendBfInvitePlayerToWar(uint32 BattleId,uint32 ZoneId,uint32 time); void SendBfInvitePlayerToQueue(uint32 BattleId); - void SendBfQueueInviteResponce(uint32 BattleId,uint32 ZoneId, bool CanQueue = true, bool Full = false); + void SendBfQueueInviteResponse(uint32 BattleId,uint32 ZoneId, bool CanQueue = true, bool Full = false); void SendBfEntered(uint32 BattleId); void SendBfLeaveMessage(uint32 BattleId, BFLeaveReason reason = BF_LEAVE_REASON_EXITED); void HandleBfQueueInviteResponse(WorldPacket &recv_data); diff --git a/src/server/scripts/Commands/cs_bf.cpp b/src/server/scripts/Commands/cs_bf.cpp index 4eee7c391b0..7284e6ad6b7 100644 --- a/src/server/scripts/Commands/cs_bf.cpp +++ b/src/server/scripts/Commands/cs_bf.cpp @@ -108,15 +108,15 @@ public: if (!bf) return false; - if (bf->GetEnable()) + if (bf->IsEnabled()) { - bf->SetEnable(false); + bf->ToggleBattlefield(false); if (battleid == 1) handler->SendGlobalGMSysMessage("Wintergrasp is disabled"); } else { - bf->SetEnable(true); + bf->ToggleBattlefield(true); if (battleid == 1) handler->SendGlobalGMSysMessage("Wintergrasp is enabled"); } diff --git a/src/server/scripts/Northrend/wintergrasp.cpp b/src/server/scripts/Northrend/wintergrasp.cpp index c7c6cc3725e..787531b496f 100644 --- a/src/server/scripts/Northrend/wintergrasp.cpp +++ b/src/server/scripts/Northrend/wintergrasp.cpp @@ -38,372 +38,414 @@ enum eWGqueuenpctext WG_NPCQUEUE_TEXTOPTION_JOIN = -1850507, }; -enum WGscriptdata +enum Spells { - // engineer spells - SPELL_BUILD_CATAPULT = 56663, - SPELL_BUILD_DEMOLISHER = 56575, - SPELL_BUILD_SIEGE_ENGINE = 61408, - SPELL_BUILD_SIEGE_ENGINE2 = 56661, // does it's really needed here? - SPELL_ACTIVATE_ROBOTIC_ARMS = 49899, - - // teleporter spells - SPELL_VEHICLE_TELEPORT = 49759, - - // npcs - NPC_ROBOTIC_ARMS = 27852, - NPC_WORLD_TRIGGER_WG = 23472, + // Demolisher engineers spells + SPELL_BUILD_SIEGE_VEHICLE_FORCE_1 = 61409, // + SPELL_BUILD_SIEGE_VEHICLE_FORCE_2 = 56662, // Which faction uses which ? + SPELL_BUILD_CATAPULT_FORCE = 56664, + SPELL_BUILD_DEMOLISHER_FORCE = 56659, + SPELL_ACTIVATE_CONTROL_ARMS = 49899, + + SPELL_VEHICLE_TELEPORT = 49759, + + // Spirit guide + SPELL_CHANNEL_SPIRIT_HEAL = 22011, }; -class npc_wg_demolisher_engineer : public CreatureScript +enum CreatureIds { - public: - npc_wg_demolisher_engineer() : CreatureScript("npc_wg_demolisher_engineer") - { - } + NPC_GOBLIN_MECHANIC = 30400, + NPC_GNOMISH_ENGINEER = 30499, - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); + NPC_WINTERGRASP_CONTROL_ARMS = 27852, - Battlefield* BfWG = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + NPC_WORLD_TRIGGER_LARGE_AOI_NOT_IMMUNE_PC_NPC = 23742, +}; - if (!BfWG) - return true; +enum QuestIds +{ + QUEST_BONES_AND_ARROWS_HORDE_ATT = 13193, + QUEST_JINXING_THE_WALLS_HORDE_ATT = 13202, + QUEST_SLAY_THEM_ALL_HORDE_ATT = 13180, + QUEST_FUELING_THE_DEMOLISHERS_HORDE_ATT = 13200, + QUEST_HEALING_WITH_ROSES_HORDE_ATT = 13201, + QUEST_DEFEND_THE_SIEGE_HORDE_ATT = 13223, + + QUEST_BONES_AND_ARROWS_HORDE_DEF = 13199, + QUEST_WARDING_THE_WALLS_HORDE_DEF = 13192, + QUEST_SLAY_THEM_ALL_HORDE_DEF = 13178, + QUEST_FUELING_THE_DEMOLISHERS_HORDE_DEF = 13191, + QUEST_HEALING_WITH_ROSES_HORDE_DEF = 13194, + QUEST_TOPPLING_THE_TOWERS_HORDE_DEF = 13539, + QUEST_STOP_THE_SIEGE_HORDE_DEF = 13185, + + QUEST_BONES_AND_ARROWS_ALLIANCE_ATT = 13196, + QUEST_WARDING_THE_WARRIORS_ALLIANCE_ATT = 13198, + QUEST_NO_MERCY_FOR_THE_MERCILESS_ALLIANCE_ATT = 13179, + QUEST_DEFEND_THE_SIEGE_ALLIANCE_ATT = 13222, + QUEST_A_RARE_HERB_ALLIANCE_ATT = 13195, + + QUEST_BONES_AND_ARROWS_ALLIANCE_DEF = 13154, + QUEST_WARDING_THE_WARRIORS_ALLIANCE_DEF = 13153, + QUEST_NO_MERCY_FOR_THE_MERCILESS_ALLIANCE_DEF = 13177, + QUEST_SHOUTHERN_SABOTAGE_ALLIANCE_DEF = 13538, + QUEST_STOP_THE_SIEGE_ALLIANCE_DEF = 13186, + QUEST_A_RARE_HERB_ALLIANCE_DEF = 13156, +}; + +uint8 const MAX_WINTERGRASP_VEHICLES = 4; + +uint32 const vehiclesList[MAX_WINTERGRASP_VEHICLES] = { + NPC_WINTERGRASP_CATAPULT, + NPC_WINTERGRASP_DEMOLISHER, + NPC_WINTERGRASP_SIEGE_ENGINE_1, + NPC_WINTERGRASP_SIEGE_ENGINE_2 +}; + +class npc_wg_demolisher_engineer : public CreatureScript +{ + public: + npc_wg_demolisher_engineer() : CreatureScript("npc_wg_demolisher_engineer") { } - if (BfWG->GetData(creature->GetEntry() == 30400 ? BATTLEFIELD_WG_DATA_MAX_VEHICLE_H : BATTLEFIELD_WG_DATA_MAX_VEHICLE_A) > - BfWG->GetData(creature->GetEntry() == 30400 ? BATTLEFIELD_WG_DATA_VEHICLE_H : BATTLEFIELD_WG_DATA_VEHICLE_A)) + bool OnGossipHello(Player* player, Creature* creature) { - if (player->HasAura(SPELL_CORPORAL)) - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - else if (player->HasAura(SPELL_LIEUTENANT)) + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(1); + + if (canBuild(creature)) { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + if (player->HasAura(SPELL_CORPORAL)) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + else if (player->HasAura(SPELL_LIEUTENANT)) + { + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + } } - } - else - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9); + else + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_DEMO4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender */ , uint32 action) - { - player->CLOSE_GOSSIP_MENU(); + bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender */ , uint32 action) + { + player->CLOSE_GOSSIP_MENU(); - Battlefield* BfWG = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + Battlefield* wintergrasp= sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); - if (!BfWG) + if (canBuild(creature)) + { + switch (action - GOSSIP_ACTION_INFO_DEF) + { + case 0: + creature->CastSpell(player, SPELL_BUILD_CATAPULT_FORCE, true); + break; + case 1: + creature->CastSpell(player, SPELL_BUILD_DEMOLISHER_FORCE, true); + break; + case 2: + creature->CastSpell(player, player->GetTeamId() == TEAM_ALLIANCE ? SPELL_BUILD_SIEGE_VEHICLE_FORCE_1 : SPELL_BUILD_SIEGE_VEHICLE_FORCE_2, true); + break; + } + if (Creature* controlArms = creature->FindNearestCreature(NPC_WINTERGRASP_CONTROL_ARMS, 30.0f, true)) + creature->CastSpell(controlArms, SPELL_ACTIVATE_CONTROL_ARMS, true); + } return true; + } - if (BfWG->GetData(creature->GetEntry() == 30400 ? BATTLEFIELD_WG_DATA_MAX_VEHICLE_H : BATTLEFIELD_WG_DATA_MAX_VEHICLE_A) > - BfWG->GetData(creature->GetEntry() == 30400 ? BATTLEFIELD_WG_DATA_VEHICLE_H : BATTLEFIELD_WG_DATA_VEHICLE_A)) + private: + bool canBuild(Creature* creature) { - switch (action - GOSSIP_ACTION_INFO_DEF) + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + + if (!wintergrasp) + return false; + switch (creature->GetEntry()) { - case 0: - player->CastSpell(player, SPELL_BUILD_CATAPULT, false, NULL, NULL, creature->GetGUID()); - break; - case 1: - player->CastSpell(player, SPELL_BUILD_DEMOLISHER, false, NULL, NULL, creature->GetGUID()); - break; - case 2: - player->CastSpell(player, player->GetTeamId() ? SPELL_BUILD_SIEGE_ENGINE : SPELL_BUILD_SIEGE_ENGINE2, false, NULL, NULL, creature->GetGUID()); - break; + case NPC_GOBLIN_MECHANIC: + return (wintergrasp->GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_H) > wintergrasp->GetData(BATTLEFIELD_WG_DATA_VEHICLE_H)); + case NPC_GNOMISH_ENGINEER: + return (wintergrasp->GetData(BATTLEFIELD_WG_DATA_MAX_VEHICLE_A) > wintergrasp->GetData(BATTLEFIELD_WG_DATA_VEHICLE_A)); + default: + return false; } - //spell 49899 Emote : 406 from sniff - //INSERT INTO `spell_scripts` (`id`, `delay`, `command`, `datalong`, `datalong2`, `dataint`, `x`, `y`, `z`, `o`) VALUES ('49899', '0', '1', '406', '0', '0', '0', '0', '0', '0'); - if (Creature* mechCreature = creature->FindNearestCreature(NPC_ROBOTIC_ARMS, 30.0f, true)) - creature->CastSpell(mechCreature, SPELL_ACTIVATE_ROBOTIC_ARMS, true); } - return true; - } }; class npc_wg_spirit_guide : public CreatureScript { - public: - npc_wg_spirit_guide() : CreatureScript("npc_wg_spirit_guide") - { - } + public: + npc_wg_spirit_guide() : CreatureScript("npc_wg_spirit_guide") { } - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); + bool OnGossipHello(Player* player, Creature* creature) + { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + if (!wintergrasp) + return true; - Battlefield* BfWG = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); - if (BfWG) + GraveyardVect graveyard = wintergrasp->GetGraveyardVector(); + for (uint8 i = 0; i < graveyard.size(); i++) + if (graveyard[i]->GetControlTeamId() == player->GetTeamId()) + player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, sObjectMgr->GetTrinityStringForDBCLocale(((BfGraveyardWG*)graveyard[i])->GetTextId()), GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + i); + + player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player* player, Creature* /*creature */ , uint32 /*sender */ , uint32 action) { - GraveYardVect gy = BfWG->GetGraveYardVect(); - for (uint8 i = 0; i < gy.size(); i++) + player->CLOSE_GOSSIP_MENU(); + + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + if (wintergrasp) { - if (gy[i]->GetControlTeamId() == player->GetTeamId()) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, sObjectMgr->GetTrinityStringForDBCLocale(((BfGraveYardWG *) gy[i])->GetTextId()), GOSSIP_SENDER_MAIN, - GOSSIP_ACTION_INFO_DEF + i); - } + GraveyardVect gy = wintergrasp->GetGraveyardVector(); + for (uint8 i = 0; i < gy.size(); i++) + if (action - GOSSIP_ACTION_INFO_DEF == i && gy[i]->GetControlTeamId() == player->GetTeamId()) + if (WorldSafeLocsEntry const* safeLoc = sWorldSafeLocsStore.LookupEntry(gy[i]->GetGraveyardId())) + player->TeleportTo(safeLoc->map_id, safeLoc->x, safeLoc->y, safeLoc->z, 0); } + return true; } - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* /*creature */ , uint32 /*sender */ , uint32 action) - { - player->CLOSE_GOSSIP_MENU(); - - Battlefield* BfWG = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); - if (BfWG) + struct npc_wg_spirit_guideAI : public ScriptedAI { - GraveYardVect gy = BfWG->GetGraveYardVect(); - for (uint8 i = 0; i < gy.size(); i++) + npc_wg_spirit_guideAI(Creature* creature) : ScriptedAI(creature) + { } + + void UpdateAI(const uint32 /* diff */) { - if (action - GOSSIP_ACTION_INFO_DEF == i && gy[i]->GetControlTeamId() == player->GetTeamId()) - { - WorldSafeLocsEntry const* ws = sWorldSafeLocsStore.LookupEntry(gy[i]->GetGraveYardId()); - player->TeleportTo(ws->map_id, ws->x, ws->y, ws->z, 0); - } + if (!me->HasUnitState(UNIT_STATE_CASTING)) + DoCast(me, SPELL_CHANNEL_SPIRIT_HEAL); } + }; + + CreatureAI *GetAI(Creature* creature) const + { + return new npc_wg_spirit_guideAI(creature); } - return true; - } }; class npc_wg_queue : public CreatureScript { - public: - npc_wg_queue() : CreatureScript("npc_wg_queue") - { - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); + public: + npc_wg_queue() : CreatureScript("npc_wg_queue") { } - Battlefield* BfWG = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); - if (BfWG) + bool OnGossipHello(Player* player, Creature* creature) { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + if (!wintergrasp) + return true; - if (BfWG->IsWarTime()) + if (wintergrasp->IsWarTime()) { player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, sObjectMgr->GetTrinityStringForDBCLocale(WG_NPCQUEUE_TEXTOPTION_JOIN), GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - player->SEND_GOSSIP_MENU(BfWG->GetDefenderTeam()? WG_NPCQUEUE_TEXT_H_WAR : WG_NPCQUEUE_TEXT_A_WAR, creature->GetGUID()); + player->SEND_GOSSIP_MENU(wintergrasp->GetDefenderTeam()? WG_NPCQUEUE_TEXT_H_WAR : WG_NPCQUEUE_TEXT_A_WAR, creature->GetGUID()); } else { - uint32 uiTime = BfWG->GetTimer() / 1000; - player->SendUpdateWorldState(4354, time(NULL) + uiTime); - if (uiTime < 15 * MINUTE) + uint32 timer = wintergrasp->GetTimer() / 1000; + player->SendUpdateWorldState(4354, time(NULL) + timer); + if (timer < 15 * MINUTE) { player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, sObjectMgr->GetTrinityStringForDBCLocale(WG_NPCQUEUE_TEXTOPTION_JOIN), GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - player->SEND_GOSSIP_MENU(BfWG->GetDefenderTeam() ? WG_NPCQUEUE_TEXT_H_QUEUE : WG_NPCQUEUE_TEXT_A_QUEUE, creature->GetGUID()); + player->SEND_GOSSIP_MENU(wintergrasp->GetDefenderTeam() ? WG_NPCQUEUE_TEXT_H_QUEUE : WG_NPCQUEUE_TEXT_A_QUEUE, creature->GetGUID()); } else - { - player->SEND_GOSSIP_MENU(BfWG->GetDefenderTeam() ? WG_NPCQUEUE_TEXT_H_NOWAR : WG_NPCQUEUE_TEXT_A_NOWAR, creature->GetGUID()); - } + player->SEND_GOSSIP_MENU(wintergrasp->GetDefenderTeam() ? WG_NPCQUEUE_TEXT_H_NOWAR : WG_NPCQUEUE_TEXT_A_NOWAR, creature->GetGUID()); } + return true; } - return true; - } - - bool OnGossipSelect(Player* player, Creature* /*creature */ , uint32 /*sender */ , uint32 /*action */ ) - { - player->CLOSE_GOSSIP_MENU(); - Battlefield* BfWG = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); - if (BfWG) + bool OnGossipSelect(Player* player, Creature* /*creature */ , uint32 /*sender */ , uint32 /*action*/) { - if (BfWG->IsWarTime()) - { - BfWG->InvitePlayerToWar(player); - } + player->CLOSE_GOSSIP_MENU(); + + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + if (!wintergrasp) + return true; + + if (wintergrasp->IsWarTime()) + wintergrasp->InvitePlayerToWar(player); else { - uint32 uiTime = BfWG->GetTimer() / 1000; - if (uiTime < 15 * MINUTE) - BfWG->InvitePlayerToQueue(player); + uint32 timer = wintergrasp->GetTimer() / 1000; + if (timer < 15 * MINUTE) + wintergrasp->InvitePlayerToQueue(player); } + return true; } - return true; - } }; -const uint32 Vehicules[4] = { 32627, 28312, 28094, 27881 }; - class go_wg_vehicle_teleporter : public GameObjectScript { - public: - go_wg_vehicle_teleporter() : GameObjectScript("go_wg_vehicle_teleporter") - { - } + public: + go_wg_vehicle_teleporter() : GameObjectScript("go_wg_vehicle_teleporter") { } - struct go_wg_vehicle_teleporterAI : public GameObjectAI - { - go_wg_vehicle_teleporterAI(GameObject* g) : GameObjectAI(g) + struct go_wg_vehicle_teleporterAI : public GameObjectAI { - uiCheckTimer = 1000; - } + go_wg_vehicle_teleporterAI(GameObject* gameObject) : GameObjectAI(gameObject), + _checkTimer(1000) + { } - void UpdateAI(const uint32 diff) - { - if (uiCheckTimer <= diff) + void UpdateAI(const uint32 diff) { - for (uint8 i = 0; i < 4; i++) - if (Creature* vehicleCreature = go->FindNearestCreature(Vehicules[i], 3.0f, true)) - if (!vehicleCreature->HasAura(SPELL_VEHICLE_TELEPORT)) - if (Vehicle* vehicle = vehicleCreature->GetVehicle()) - if (Unit* passenger = vehicle->GetPassenger(0)) - { - uint32 gofaction = go->GetUInt32Value(GAMEOBJECT_FACTION); - uint32 plfaction = passenger->getFaction(); - if (gofaction == plfaction) - { - if (Creature* teleportTrigger = vehicleCreature->FindNearestCreature(NPC_WORLD_TRIGGER_WG,100.0f,true)) - teleportTrigger->CastSpell(vehicleCreature, SPELL_VEHICLE_TELEPORT, true); - } - } - - uiCheckTimer = 1000; + if (_checkTimer <= diff) + { + // Tabulation madness in the hole! + for (uint8 i = 0; i < MAX_WINTERGRASP_VEHICLES; i++) + if (Creature* vehicleCreature = go->FindNearestCreature(vehiclesList[i], 3.0f, true)) + if (!vehicleCreature->HasAura(SPELL_VEHICLE_TELEPORT)) + if (Vehicle* vehicle = vehicleCreature->GetVehicle()) + if (Unit* passenger = vehicle->GetPassenger(0)) + if (go->GetUInt32Value(GAMEOBJECT_FACTION) == passenger->getFaction()) + if (Creature* teleportTrigger = vehicleCreature->FindNearestCreature(NPC_WORLD_TRIGGER_LARGE_AOI_NOT_IMMUNE_PC_NPC, 100.0f, true)) + teleportTrigger->CastSpell(vehicleCreature, SPELL_VEHICLE_TELEPORT, true); + + _checkTimer = 1000; + } + else _checkTimer -= diff; } - else - uiCheckTimer -= diff; - } - private: - uint32 uiCheckTimer; - }; + private: + uint32 _checkTimer; + }; - GameObjectAI *GetAI(GameObject* go) const - { - return new go_wg_vehicle_teleporterAI(go); - } + GameObjectAI* GetAI(GameObject* go) const + { + return new go_wg_vehicle_teleporterAI(go); + } }; class npc_wg_quest_giver : public CreatureScript { - public: - npc_wg_quest_giver() : CreatureScript("npc_wg_quest_giver") - { - } - - bool OnGossipHello(Player* player, Creature* creature) - { - if (creature->isQuestGiver()) - player->PrepareQuestMenu(creature->GetGUID()); + public: + npc_wg_quest_giver() : CreatureScript("npc_wg_quest_giver") { } - Battlefield* BfWG = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); - if (BfWG) + bool OnGossipHello(Player* player, Creature* creature) { + if (creature->isQuestGiver()) + player->PrepareQuestMenu(creature->GetGUID()); + + Battlefield* wintergrasp = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG); + if (!wintergrasp) + return true; + if (creature->isQuestGiver()) { - Object* object = (Object *) creature; - QuestRelations* objectQR = sObjectMgr->GetCreatureQuestRelationMap(); - QuestRelations* objectQIR = sObjectMgr->GetCreatureQuestInvolvedRelation(); + QuestRelationBounds objectQR = sObjectMgr->GetCreatureQuestRelationBounds(creature->GetEntry()); + QuestRelationBounds objectQIR = sObjectMgr->GetCreatureQuestInvolvedRelationBounds(creature->GetEntry()); - QuestMenu & qm = player->PlayerTalkClass->GetQuestMenu(); + QuestMenu& qm = player->PlayerTalkClass->GetQuestMenu(); qm.ClearMenu(); - for (QuestRelations::const_iterator i = objectQIR->lower_bound(object->GetEntry()); i != objectQIR->upper_bound(object->GetEntry()); ++i) + for (QuestRelations::const_iterator i = objectQIR.first; i != objectQIR.second; ++i) { uint32 quest_id = i->second; QuestStatus status = player->GetQuestStatus(quest_id); - if (status == QUEST_STATUS_COMPLETE && !player->GetQuestRewardStatus(quest_id)) + if (status == QUEST_STATUS_COMPLETE) qm.AddMenuItem(quest_id, 4); else if (status == QUEST_STATUS_INCOMPLETE) qm.AddMenuItem(quest_id, 4); + //else if (status == QUEST_STATUS_AVAILABLE) + // qm.AddMenuItem(quest_id, 2); } - for (QuestRelations::const_iterator i = objectQR->lower_bound(object->GetEntry()); i != objectQR->upper_bound(object->GetEntry()); ++i) + for (QuestRelations::const_iterator i = objectQR.first; i != objectQR.second; ++i) { - uint32 quest_id = i->second; - Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id); + uint32 questId = i->second; + Quest const* quest = sObjectMgr->GetQuestTemplate(questId); if (!quest) continue; - switch (quest_id) + switch (questId) { // Horde attacker - case 13193: - case 13202: - case 13180: - case 13200: - case 13201: - case 13223: - if (BfWG->GetAttackerTeam() == TEAM_HORDE) + case QUEST_BONES_AND_ARROWS_HORDE_ATT: + case QUEST_JINXING_THE_WALLS_HORDE_ATT: + case QUEST_SLAY_THEM_ALL_HORDE_ATT: + case QUEST_FUELING_THE_DEMOLISHERS_HORDE_ATT: + case QUEST_HEALING_WITH_ROSES_HORDE_ATT: + case QUEST_DEFEND_THE_SIEGE_HORDE_ATT: + if (wintergrasp->GetAttackerTeam() == TEAM_HORDE) { - QuestStatus status = player->GetQuestStatus(quest_id); + QuestStatus status = player->GetQuestStatus(questId); if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(quest_id, 4); + qm.AddMenuItem(questId, 4); else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(quest_id, 2); + qm.AddMenuItem(questId, 2); } break; // Horde defender - case 13199: - case 13192: - case 13178: - case 13191: - case 13194: - case 13539: - case 13185: - if (BfWG->GetDefenderTeam() == TEAM_HORDE) + case QUEST_BONES_AND_ARROWS_HORDE_DEF: + case QUEST_WARDING_THE_WALLS_HORDE_DEF: + case QUEST_SLAY_THEM_ALL_HORDE_DEF: + case QUEST_FUELING_THE_DEMOLISHERS_HORDE_DEF: + case QUEST_HEALING_WITH_ROSES_HORDE_DEF: + case QUEST_TOPPLING_THE_TOWERS_HORDE_DEF: + case QUEST_STOP_THE_SIEGE_HORDE_DEF: + if (wintergrasp->GetDefenderTeam() == TEAM_HORDE) { - QuestStatus status = player->GetQuestStatus(quest_id); + QuestStatus status = player->GetQuestStatus(questId); if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(quest_id, 4); + qm.AddMenuItem(questId, 4); else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(quest_id, 2); + qm.AddMenuItem(questId, 2); } break; // Alliance attacker - case 13196: - case 13198: - case 13179: - case 13222: - case 13195: - if (BfWG->GetAttackerTeam() == TEAM_ALLIANCE) + case QUEST_BONES_AND_ARROWS_ALLIANCE_ATT: + case QUEST_WARDING_THE_WARRIORS_ALLIANCE_ATT: + case QUEST_NO_MERCY_FOR_THE_MERCILESS_ALLIANCE_ATT: + case QUEST_DEFEND_THE_SIEGE_ALLIANCE_ATT: + case QUEST_A_RARE_HERB_ALLIANCE_ATT: + if (wintergrasp->GetAttackerTeam() == TEAM_ALLIANCE) { - QuestStatus status = player->GetQuestStatus(quest_id); + QuestStatus status = player->GetQuestStatus(questId); if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(quest_id, 4); + qm.AddMenuItem(questId, 4); else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(quest_id, 2); + qm.AddMenuItem(questId, 2); } break; // Alliance defender - case 13154: - case 13153: - case 13177: - case 13538: - case 13186: - case 13156: - if (BfWG->GetDefenderTeam() == TEAM_ALLIANCE) + case QUEST_BONES_AND_ARROWS_ALLIANCE_DEF: + case QUEST_WARDING_THE_WARRIORS_ALLIANCE_DEF: + case QUEST_NO_MERCY_FOR_THE_MERCILESS_ALLIANCE_DEF: + case QUEST_SHOUTHERN_SABOTAGE_ALLIANCE_DEF: + case QUEST_STOP_THE_SIEGE_ALLIANCE_DEF: + case QUEST_A_RARE_HERB_ALLIANCE_DEF: + if (wintergrasp->GetDefenderTeam() == TEAM_ALLIANCE) { - QuestStatus status = player->GetQuestStatus(quest_id); + QuestStatus status = player->GetQuestStatus(questId); if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(quest_id, 4); + qm.AddMenuItem(questId, 4); else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(quest_id, 2); + qm.AddMenuItem(questId, 2); } break; default: - QuestStatus status = player->GetQuestStatus(quest_id); + QuestStatus status = player->GetQuestStatus(questId); if (quest->IsAutoComplete() && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(quest_id, 4); + qm.AddMenuItem(questId, 4); else if (status == QUEST_STATUS_NONE && player->CanTakeQuest(quest, false)) - qm.AddMenuItem(quest_id, 2); + qm.AddMenuItem(questId, 2); break; } } @@ -411,8 +453,43 @@ class npc_wg_quest_giver : public CreatureScript player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); return true; } - return true; - } +}; + +class spell_wintergrasp_force_building : public SpellScriptLoader +{ + public: + spell_wintergrasp_force_building() : SpellScriptLoader("spell_wintergrasp_force_building") { } + + class spell_wintergrasp_force_building_SpellScript : public SpellScript + { + PrepareSpellScript(spell_wintergrasp_force_building_SpellScript); + + bool Validate(SpellInfo const* /*spell*/) + { + if (!sSpellMgr->GetSpellInfo(SPELL_BUILD_CATAPULT_FORCE) + || !sSpellMgr->GetSpellInfo(SPELL_BUILD_DEMOLISHER_FORCE) + || !sSpellMgr->GetSpellInfo(SPELL_BUILD_SIEGE_VEHICLE_FORCE_1) + || !sSpellMgr->GetSpellInfo(SPELL_BUILD_SIEGE_VEHICLE_FORCE_2)) + return false; + return true; + } + + void HandleScript(SpellEffIndex effIndex) + { + PreventHitDefaultEffect(effIndex); + GetHitUnit()->CastSpell(GetHitUnit(), GetEffectValue(), true); + } + + void Register() + { + OnEffectHitTarget += SpellEffectFn(spell_wintergrasp_force_building_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_wintergrasp_force_building_SpellScript(); + } }; class achievement_wg_didnt_stand_a_chance : public AchievementCriteriaScript @@ -444,7 +521,9 @@ void AddSC_wintergrasp() new npc_wg_queue(); new npc_wg_spirit_guide(); new npc_wg_demolisher_engineer(); - new go_wg_vehicle_teleporter(); new npc_wg_quest_giver(); new achievement_wg_didnt_stand_a_chance(); + new spell_wintergrasp_force_building(); + + new go_wg_vehicle_teleporter(); } -- cgit v1.2.3