aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/authserver/CMakeLists.txt2
-rw-r--r--src/server/authserver/Server/AuthSocket.cpp40
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedGossip.h4
-rw-r--r--src/server/game/Addons/AddonMgr.cpp68
-rw-r--r--src/server/game/Addons/AddonMgr.h16
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp10
-rw-r--r--src/server/game/Battlefield/Zones/BattlefieldWG.h20
-rw-r--r--src/server/game/Battlegrounds/BattlegroundQueue.cpp7
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp6
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundBE.h1
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp6
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundDS.h1
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp6
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundNA.h1
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp6
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundRL.h1
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp15
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundRV.h1
-rw-r--r--src/server/game/Chat/Chat.cpp15
-rw-r--r--src/server/game/DataStores/DBCStores.cpp20
-rw-r--r--src/server/game/DataStores/DBCStores.h3
-rw-r--r--src/server/game/DataStores/DBCStructure.h14
-rw-r--r--src/server/game/DataStores/DBCfmt.h2
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp44
-rw-r--r--src/server/game/Entities/Creature/GossipDef.h4
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp8
-rw-r--r--src/server/game/Entities/Player/Player.cpp68
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp93
-rw-r--r--src/server/game/Entities/Unit/Unit.h20
-rw-r--r--src/server/game/Events/GameEventMgr.cpp8
-rw-r--r--src/server/game/Events/GameEventMgr.h1
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp4
-rw-r--r--src/server/game/Guilds/Guild.cpp19
-rw-r--r--src/server/game/Guilds/Guild.h2
-rw-r--r--src/server/game/Handlers/AuctionHouseHandler.cpp14
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp1
-rw-r--r--src/server/game/Handlers/GroupHandler.cpp155
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp2
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp11
-rw-r--r--src/server/game/Handlers/PetHandler.cpp8
-rw-r--r--src/server/game/Handlers/TicketHandler.cpp9
-rw-r--r--src/server/game/Maps/Map.cpp6
-rw-r--r--src/server/game/Miscellaneous/Language.h7
-rw-r--r--src/server/game/Movement/MotionMaster.cpp2
-rw-r--r--src/server/game/Movement/PathGenerator.cpp27
-rw-r--r--src/server/game/Movement/PathGenerator.h58
-rw-r--r--src/server/game/OutdoorPvP/OutdoorPvP.cpp11
-rw-r--r--src/server/game/Scripting/ScriptLoader.cpp1
-rw-r--r--src/server/game/Server/WorldSession.cpp29
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp6
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp2
-rw-r--r--src/server/game/Spells/Spell.cpp4
-rw-r--r--src/server/game/Spells/SpellEffects.cpp13
-rw-r--r--src/server/game/Spells/SpellInfo.cpp87
-rw-r--r--src/server/game/Spells/SpellMgr.cpp52
-rw-r--r--src/server/game/Spells/SpellMgr.h6
-rw-r--r--src/server/game/Tickets/TicketMgr.cpp10
-rw-r--r--src/server/game/Tickets/TicketMgr.h5
-rw-r--r--src/server/game/World/World.cpp67
-rw-r--r--src/server/game/World/World.h7
-rw-r--r--src/server/scripts/Commands/cs_account.cpp60
-rw-r--r--src/server/scripts/Commands/cs_character.cpp121
-rw-r--r--src/server/scripts/Commands/cs_gobject.cpp3
-rw-r--r--src/server/scripts/Commands/cs_guild.cpp50
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp8
-rw-r--r--src/server/scripts/Commands/cs_mmaps.cpp12
-rw-r--r--src/server/scripts/Commands/cs_ticket.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp332
-rw-r--r--src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp12
-rw-r--r--src/server/scripts/Events/childrens_week.cpp2
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp32
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.h13
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp1
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp3
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp36
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp9
-rw-r--r--src/server/scripts/Northrend/zone_wintergrasp.cpp2
-rw-r--r--src/server/scripts/Outland/zone_shattrath_city.cpp196
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp50
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.cpp3
-rwxr-xr-xsrc/server/shared/Database/Implementation/CharacterDatabase.h2
-rw-r--r--src/server/shared/Database/Implementation/LoginDatabase.cpp6
-rw-r--r--src/server/shared/Database/Implementation/LoginDatabase.h4
-rw-r--r--src/server/shared/Database/Implementation/WorldDatabase.cpp1
-rw-r--r--src/server/shared/Database/Implementation/WorldDatabase.h1
-rw-r--r--src/server/worldserver/CMakeLists.txt2
-rw-r--r--src/server/worldserver/worldserver.conf.dist10
87 files changed, 1300 insertions, 811 deletions
diff --git a/src/server/authserver/CMakeLists.txt b/src/server/authserver/CMakeLists.txt
index f7c4b9cb8ca..57ab1ffa4ed 100644
--- a/src/server/authserver/CMakeLists.txt
+++ b/src/server/authserver/CMakeLists.txt
@@ -98,7 +98,7 @@ endif()
if( UNIX )
install(TARGETS authserver DESTINATION bin)
- install(FILES authserver.conf.dist DESTINATION etc)
+ install(FILES authserver.conf.dist DESTINATION ${CONF_DIR})
elseif( WIN32 )
install(TARGETS authserver DESTINATION "${CMAKE_INSTALL_PREFIX}")
install(FILES authserver.conf.dist DESTINATION "${CMAKE_INSTALL_PREFIX}")
diff --git a/src/server/authserver/Server/AuthSocket.cpp b/src/server/authserver/Server/AuthSocket.cpp
index 32ddf029f1c..a080a038314 100644
--- a/src/server/authserver/Server/AuthSocket.cpp
+++ b/src/server/authserver/Server/AuthSocket.cpp
@@ -386,17 +386,45 @@ bool AuthSocket::_HandleLogonChallenge()
sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), fields[3].GetCString());
sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Player address is '%s'", ip_address.c_str());
- if (strcmp(fields[3].GetCString(), ip_address.c_str()))
+ if (strcmp(fields[4].GetCString(), ip_address.c_str()))
{
sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account IP differs");
- pkt << (uint8) WOW_FAIL_SUSPENDED;
+ pkt << uint8(WOW_FAIL_LOCKED_ENFORCED);
locked = true;
}
else
sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account IP matches");
}
else
+ {
sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account '%s' is not locked to ip", _login.c_str());
+ std::string accountCountry = fields[3].GetString();
+ if (accountCountry.empty() || accountCountry == "00")
+ sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account '%s' is not locked to country", _login.c_str());
+ else if (!accountCountry.empty())
+ {
+ uint32 ip = inet_addr(ip_address.c_str());
+ EndianConvertReverse(ip);
+
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGON_COUNTRY);
+ stmt->setUInt32(0, ip);
+ if (PreparedQueryResult sessionCountryQuery = LoginDatabase.Query(stmt))
+ {
+ std::string loginCountry = (*sessionCountryQuery)[0].GetString();
+ sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account '%s' is locked to country: '%s' Player country is '%s'", _login.c_str(), accountCountry.c_str(), loginCountry.c_str());
+ if (loginCountry != accountCountry)
+ {
+ sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account country differs.");
+ pkt << uint8(WOW_FAIL_UNLOCKABLE_LOCK);
+ locked = true;
+ }
+ else
+ sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account country matches");
+ }
+ else
+ sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] IP2NATION Table empty");
+ }
+ }
if (!locked)
{
@@ -426,8 +454,8 @@ bool AuthSocket::_HandleLogonChallenge()
std::string rI = fields[0].GetString();
// Don't calculate (v, s) if there are already some in the database
- std::string databaseV = fields[5].GetString();
- std::string databaseS = fields[6].GetString();
+ std::string databaseV = fields[6].GetString();
+ std::string databaseS = fields[7].GetString();
sLog->outDebug(LOG_FILTER_NETWORKIO, "database authentication values: v='%s' s='%s'", databaseV.c_str(), databaseS.c_str());
@@ -484,7 +512,7 @@ bool AuthSocket::_HandleLogonChallenge()
if (securityFlags & 0x04) // Security token input
pkt << uint8(1);
- uint8 secLevel = fields[4].GetUInt8();
+ uint8 secLevel = fields[5].GetUInt8();
_accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR;
_localizationName.resize(4);
@@ -498,7 +526,7 @@ bool AuthSocket::_HandleLogonChallenge()
}
}
else //no account
- pkt << (uint8)WOW_FAIL_UNKNOWN_ACCOUNT;
+ pkt << uint8(WOW_FAIL_UNKNOWN_ACCOUNT);
}
socket().send((char const*)pkt.contents(), pkt.size());
diff --git a/src/server/game/AI/ScriptedAI/ScriptedGossip.h b/src/server/game/AI/ScriptedAI/ScriptedGossip.h
index 80142afd14b..93add2ae652 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedGossip.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedGossip.h
@@ -78,7 +78,11 @@ enum eTradeskill
// d - Action (identifys this Menu Item)
// e - Text to be displayed in pop up box
// f - Money value in pop up box
+// g - Coded
+// h - Menu ID from DB
+// i - Menu item ID from DB
#define ADD_GOSSIP_ITEM(a, b, c, d) PlayerTalkClass->GetGossipMenu().AddMenuItem(-1, a, b, c, d, "", 0)
+#define ADD_GOSSIP_ITEM_DB(h, i, c, d) PlayerTalkClass->GetGossipMenu().AddMenuItem(h, i, c, d)
#define ADD_GOSSIP_ITEM_EXTENDED(a, b, c, d, e, f, g) PlayerTalkClass->GetGossipMenu().AddMenuItem(-1, a, b, c, d, e, f, g)
// This fuction Sends the current menu to show to client, a - NPCTEXTID(uint32), b - npc guid(uint64)
diff --git a/src/server/game/Addons/AddonMgr.cpp b/src/server/game/Addons/AddonMgr.cpp
index 86a90d4d78a..3e1180727d0 100644
--- a/src/server/game/Addons/AddonMgr.cpp
+++ b/src/server/game/Addons/AddonMgr.cpp
@@ -18,10 +18,10 @@
#include "AddonMgr.h"
#include "DatabaseEnv.h"
+#include "DBCStores.h"
#include "Log.h"
#include "Timer.h"
-
-#include <list>
+#include <openssl/md5.h>
namespace AddonMgr
{
@@ -34,6 +34,8 @@ namespace
typedef std::list<SavedAddon> SavedAddonsList;
SavedAddonsList m_knownAddons;
+
+ BannedAddonList m_bannedAddons;
}
void LoadFromDB()
@@ -41,28 +43,57 @@ void LoadFromDB()
uint32 oldMSTime = getMSTime();
QueryResult result = CharacterDatabase.Query("SELECT name, crc FROM addons");
- if (!result)
+ if (result)
{
- sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 known addons. DB table `addons` is empty!");
- return;
- }
+ uint32 count = 0;
- uint32 count = 0;
+ do
+ {
+ Field* fields = result->Fetch();
- do
- {
- Field* fields = result->Fetch();
+ std::string name = fields[0].GetString();
+ uint32 crc = fields[1].GetUInt32();
- std::string name = fields[0].GetString();
- uint32 crc = fields[1].GetUInt32();
+ m_knownAddons.push_back(SavedAddon(name, crc));
- m_knownAddons.push_back(SavedAddon(name, crc));
+ ++count;
+ }
+ while (result->NextRow());
- ++count;
+ sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u known addons in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
- while (result->NextRow());
+ else
+ sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 known addons. DB table `addons` is empty!");
+
+ oldMSTime = getMSTime();
+ result = CharacterDatabase.Query("SELECT id, name, version, UNIX_TIMESTAMP(timestamp) FROM banned_addons");
+ if (result)
+ {
+ uint32 count = 0;
+ uint32 dbcMaxBannedAddon = sBannedAddOnsStore.GetNumRows();
+
+ do
+ {
+ Field* fields = result->Fetch();
- sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u known addons in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ BannedAddon addon;
+ addon.Id = fields[0].GetUInt32() + dbcMaxBannedAddon;
+ addon.Timestamp = uint32(fields[3].GetUInt64());
+
+ std::string name = fields[1].GetString();
+ std::string version = fields[2].GetString();
+
+ MD5(reinterpret_cast<uint8 const*>(name.c_str()), name.length(), addon.NameMD5);
+ MD5(reinterpret_cast<uint8 const*>(version.c_str()), version.length(), addon.VersionMD5);
+
+ m_bannedAddons.push_back(addon);
+
+ ++count;
+ }
+ while (result->NextRow());
+
+ sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u banned addons in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ }
}
void SaveAddon(AddonInfo const& addon)
@@ -91,4 +122,9 @@ SavedAddon const* GetAddonInfo(const std::string& name)
return NULL;
}
+BannedAddonList const* GetBannedAddons()
+{
+ return &m_bannedAddons;
+}
+
} // Namespace
diff --git a/src/server/game/Addons/AddonMgr.h b/src/server/game/Addons/AddonMgr.h
index 4d387fcfd4c..35e24e965b5 100644
--- a/src/server/game/Addons/AddonMgr.h
+++ b/src/server/game/Addons/AddonMgr.h
@@ -21,6 +21,7 @@
#include "Define.h"
#include <string>
+#include <list>
struct AddonInfo
{
@@ -37,7 +38,7 @@ struct AddonInfo
struct SavedAddon
{
- SavedAddon(const std::string& name, uint32 crc) : Name(name)
+ SavedAddon(std::string const& name, uint32 crc) : Name(name)
{
CRC = crc;
}
@@ -46,13 +47,24 @@ struct SavedAddon
uint32 CRC;
};
-#define STANDARD_ADDON_CRC 0x4c1c776d
+struct BannedAddon
+{
+ uint32 Id;
+ uint8 NameMD5[16];
+ uint8 VersionMD5[16];
+ uint32 Timestamp;
+};
+
+#define STANDARD_ADDON_CRC 0x4C1C776D
namespace AddonMgr
{
void LoadFromDB();
void SaveAddon(AddonInfo const& addon);
SavedAddon const* GetAddonInfo(const std::string& name);
+
+ typedef std::list<BannedAddon> BannedAddonList;
+ BannedAddonList const* GetBannedAddons();
}
#endif
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index ed03d1e1d04..b5019037862 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -660,12 +660,12 @@ void AuctionEntry::SaveToDB(SQLTransaction& trans) const
stmt->setUInt32(1, auctioneer);
stmt->setUInt32(2, itemGUIDLow);
stmt->setUInt32(3, owner);
- stmt->setInt32 (4, int32(buyout));
- stmt->setUInt64(5, uint64(expire_time));
+ stmt->setUInt32(4, buyout);
+ stmt->setUInt32(5, uint32(expire_time));
stmt->setUInt32(6, bidder);
- stmt->setInt32 (7, int32(bid));
- stmt->setInt32 (8, int32(startbid));
- stmt->setInt32 (9, int32(deposit));
+ stmt->setUInt32(7, bid);
+ stmt->setUInt32(8, startbid);
+ stmt->setUInt32(9, deposit);
trans->Append(stmt);
}
diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.h b/src/server/game/Battlefield/Zones/BattlefieldWG.h
index 047455ce8fb..e09ef0f1e05 100644
--- a/src/server/game/Battlefield/Zones/BattlefieldWG.h
+++ b/src/server/game/Battlefield/Zones/BattlefieldWG.h
@@ -171,13 +171,13 @@ enum WGGraveyardId
enum WGGossipText
{
- BATTLEFIELD_WG_GOSSIPTEXT_GY_NE = -1850501,
- BATTLEFIELD_WG_GOSSIPTEXT_GY_NW = -1850502,
- BATTLEFIELD_WG_GOSSIPTEXT_GY_SE = -1850504,
- BATTLEFIELD_WG_GOSSIPTEXT_GY_SW = -1850503,
- BATTLEFIELD_WG_GOSSIPTEXT_GY_KEEP = -1850500,
- BATTLEFIELD_WG_GOSSIPTEXT_GY_HORDE = -1850505,
- BATTLEFIELD_WG_GOSSIPTEXT_GY_ALLIANCE = -1850506
+ BATTLEFIELD_WG_GOSSIPTEXT_GY_NE = 20071,
+ BATTLEFIELD_WG_GOSSIPTEXT_GY_NW = 20072,
+ BATTLEFIELD_WG_GOSSIPTEXT_GY_SE = 20074,
+ BATTLEFIELD_WG_GOSSIPTEXT_GY_SW = 20073,
+ BATTLEFIELD_WG_GOSSIPTEXT_GY_KEEP = 20070,
+ BATTLEFIELD_WG_GOSSIPTEXT_GY_HORDE = 20075,
+ BATTLEFIELD_WG_GOSSIPTEXT_GY_ALLIANCE = 20076
};
enum WintergraspNpcs
@@ -1127,7 +1127,7 @@ struct BfWGGameObjectBuilding
build->SetDestructibleState(GO_DESTRUCTIBLE_REBUILDING, NULL, true);
if (build->GetEntry() == GO_WINTERGRASP_VAULT_GATE)
if (GameObject* go = build->FindNearestGameObject(GO_WINTERGRASP_KEEP_COLLISION_WALL, 50.0f))
- go->EnableCollision(true);
+ go->SetGoState(GO_STATE_READY);
// Update worldstate
m_State = BATTLEFIELD_WG_OBJECTSTATE_ALLIANCE_INTACT - (m_Team * 3);
@@ -1183,8 +1183,8 @@ struct BfWGGameObjectBuilding
break;
case BATTLEFIELD_WG_OBJECTTYPE_DOOR_LAST:
if (GameObject* build = m_WG->GetGameObject(m_BuildGUID))
- if (GameObject* go = build->FindNearestGameObject(GO_WINTERGRASP_KEEP_COLLISION_WALL, 10.0f))
- go->EnableCollision(false);
+ if (GameObject* go = build->FindNearestGameObject(GO_WINTERGRASP_KEEP_COLLISION_WALL, 50.0f))
+ go->SetGoState(GO_STATE_ACTIVE);
m_WG->SetRelicInteractible(true);
if (m_WG->GetRelic())
m_WG->GetRelic()->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE);
diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
index 11df69b0d11..76bf3523af1 100644
--- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
@@ -285,8 +285,6 @@ uint32 BattlegroundQueue::GetAverageQueueWaitTime(GroupQueueInfo* ginfo, Battleg
//remove player from queue and from group info, if group info is empty then remove it too
void BattlegroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount)
{
- //Player* player = ObjectAccessor::FindPlayer(guid);
-
int32 bracket_id = -1; // signed for proper for-loop finish
QueuedPlayersMap::iterator itr;
@@ -294,7 +292,10 @@ void BattlegroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount)
itr = m_QueuedPlayers.find(guid);
if (itr == m_QueuedPlayers.end())
{
- sLog->outError(LOG_FILTER_BATTLEGROUND, "BattlegroundQueue: couldn't find player to remove GUID: %u", GUID_LOPART(guid));
+ std::string playerName = "Unknown";
+ if (Player* player = ObjectAccessor::FindPlayer(guid))
+ playerName = player->GetName();
+ sLog->outError(LOG_FILTER_BATTLEGROUND, "BattlegroundQueue: couldn't find player %s (GUID: %u)", playerName.c_str(), GUID_LOPART(guid));
return;
}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp
index 9d1c12a8903..c09b42f1e7f 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp
@@ -94,12 +94,6 @@ void BattlegroundBE::HandleKillPlayer(Player* player, Player* killer)
CheckArenaWinConditions();
}
-bool BattlegroundBE::HandlePlayerUnderMap(Player* player)
-{
- player->TeleportTo(GetMapId(), 6238.930176f, 262.963470f, 0.889519f, player->GetOrientation());
- return true;
-}
-
void BattlegroundBE::HandleAreaTrigger(Player* player, uint32 trigger)
{
if (GetStatus() != STATUS_IN_PROGRESS)
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundBE.h b/src/server/game/Battlegrounds/Zones/BattlegroundBE.h
index 9953e548df6..f9a3028ddf6 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundBE.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundBE.h
@@ -59,7 +59,6 @@ class BattlegroundBE : public Battleground
void Reset();
void FillInitialWorldStates(WorldPacket &d);
void HandleKillPlayer(Player* player, Player* killer);
- bool HandlePlayerUnderMap(Player* player);
/* Scorekeeping */
void UpdatePlayerScore(Player* Source, uint32 type, uint32 value, bool doAddHonor = true);
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp
index e7462f970a3..fe1973d3daf 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp
@@ -201,12 +201,6 @@ void BattlegroundDS::HandleAreaTrigger(Player* player, uint32 trigger)
}
}
-bool BattlegroundDS::HandlePlayerUnderMap(Player* player)
-{
- player->TeleportTo(GetMapId(), 1299.046f, 784.825f, 9.338f, 2.422f);
- return true;
-}
-
void BattlegroundDS::FillInitialWorldStates(WorldPacket &data)
{
data << uint32(3610) << uint32(1); // 9 show
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundDS.h b/src/server/game/Battlegrounds/Zones/BattlegroundDS.h
index 43437595220..cdfbbc480bb 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundDS.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundDS.h
@@ -96,7 +96,6 @@ class BattlegroundDS : public Battleground
void Reset();
void FillInitialWorldStates(WorldPacket &d);
void HandleKillPlayer(Player* player, Player* killer);
- bool HandlePlayerUnderMap(Player* player);
private:
uint32 _waterfallTimer;
uint8 _waterfallStatus;
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp
index 4d0cdf08eba..d3ce5c1544e 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp
@@ -91,12 +91,6 @@ void BattlegroundNA::HandleKillPlayer(Player* player, Player* killer)
CheckArenaWinConditions();
}
-bool BattlegroundNA::HandlePlayerUnderMap(Player* player)
-{
- player->TeleportTo(GetMapId(), 4055.504395f, 2919.660645f, 13.611241f, player->GetOrientation());
- return true;
-}
-
void BattlegroundNA::HandleAreaTrigger(Player* player, uint32 trigger)
{
if (GetStatus() != STATUS_IN_PROGRESS)
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundNA.h b/src/server/game/Battlegrounds/Zones/BattlegroundNA.h
index d53f47787a4..e3633197253 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundNA.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundNA.h
@@ -58,6 +58,5 @@ class BattlegroundNA : public Battleground
void Reset();
void FillInitialWorldStates(WorldPacket &d);
void HandleKillPlayer(Player* player, Player* killer);
- bool HandlePlayerUnderMap(Player* player);
};
#endif
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp
index 1b18583827d..de7d6995120 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp
@@ -91,12 +91,6 @@ void BattlegroundRL::HandleKillPlayer(Player* player, Player* killer)
CheckArenaWinConditions();
}
-bool BattlegroundRL::HandlePlayerUnderMap(Player* player)
-{
- player->TeleportTo(GetMapId(), 1285.810547f, 1667.896851f, 39.957642f, player->GetOrientation());
- return true;
-}
-
void BattlegroundRL::HandleAreaTrigger(Player* player, uint32 trigger)
{
if (GetStatus() != STATUS_IN_PROGRESS)
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRL.h b/src/server/game/Battlegrounds/Zones/BattlegroundRL.h
index e5e55782005..877e0626271 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundRL.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundRL.h
@@ -54,6 +54,5 @@ class BattlegroundRL : public Battleground
void HandleAreaTrigger(Player* Source, uint32 Trigger);
bool SetupBattleground();
void HandleKillPlayer(Player* player, Player* killer);
- bool HandlePlayerUnderMap(Player* player);
};
#endif
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp
index 9f15bd29bed..68e961414f9 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp
@@ -64,8 +64,6 @@ void BattlegroundRV::PostUpdateImpl(uint32 diff)
setState(BG_RV_STATE_SWITCH_PILLARS);
break;
case BG_RV_STATE_SWITCH_PILLARS:
- for (uint8 i = BG_RV_OBJECT_PILAR_1; i <= BG_RV_OBJECT_PULLEY_2; ++i)
- DoorOpen(i);
TogglePillarCollision();
setTimer(BG_RV_PILLAR_SWITCH_TIMER);
break;
@@ -135,12 +133,6 @@ void BattlegroundRV::HandleKillPlayer(Player* player, Player* killer)
CheckArenaWinConditions();
}
-bool BattlegroundRV::HandlePlayerUnderMap(Player* player)
-{
- player->TeleportTo(GetMapId(), 763.5f, -284, 28.276f, 2.422f);
- return true;
-}
-
void BattlegroundRV::HandleAreaTrigger(Player* player, uint32 trigger)
{
if (GetStatus() != STATUS_IN_PROGRESS)
@@ -217,6 +209,13 @@ void BattlegroundRV::TogglePillarCollision()
{
bool apply = GetPillarCollision();
+ // Toggle visual pillars, pulley, gear, and collision based on previous state
+ for (uint8 i = BG_RV_OBJECT_PILAR_1; i <= BG_RV_OBJECT_GEAR_2; ++i)
+ apply ? DoorOpen(i) : DoorClose(i);
+
+ for (uint8 i = BG_RV_OBJECT_PILAR_2; i <= BG_RV_OBJECT_PULLEY_2; ++i)
+ apply ? DoorClose(i) : DoorOpen(i);
+
for (uint8 i = BG_RV_OBJECT_PILAR_1; i <= BG_RV_OBJECT_PILAR_COLLISION_4; ++i)
{
if (GameObject* gob = GetBgMap()->GetGameObject(BgObjects[i]))
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRV.h b/src/server/game/Battlegrounds/Zones/BattlegroundRV.h
index b6dc3775df8..a836e4e1af3 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundRV.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundRV.h
@@ -108,7 +108,6 @@ class BattlegroundRV : public Battleground
void HandleAreaTrigger(Player* Source, uint32 Trigger);
bool SetupBattleground();
void HandleKillPlayer(Player* player, Player* killer);
- bool HandlePlayerUnderMap(Player* player);
private:
uint32 Timer;
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index 62a148eae03..5bede353783 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -369,8 +369,19 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, co
{
Player* p = m_session->GetPlayer();
uint64 sel_guid = p->GetSelection();
- sLog->outCommand(m_session->GetAccountId(), "Command: %s [Player: %s (Account: %u) X: %f Y: %f Z: %f Map: %u Selected %s: %s (GUID: %u)]",
- fullcmd.c_str(), p->GetName().c_str(), m_session->GetAccountId(), p->GetPositionX(), p->GetPositionY(), p->GetPositionZ(), p->GetMapId(),
+ uint32 areaId = p->GetAreaId();
+ std::string areaName = "Unknown";
+ std::string zoneName = "Unknown";
+ if (AreaTableEntry const* area = GetAreaEntryByAreaID(areaId))
+ {
+ int locale = GetSessionDbcLocale();
+ areaName = area->area_name[locale];
+ if (AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone))
+ zoneName = zone->area_name[locale];
+ }
+
+ sLog->outCommand(m_session->GetAccountId(), "Command: %s [Player: %s (Guid: %u) (Account: %u) X: %f Y: %f Z: %f Map: %u (%s) Area: %u (%s) Zone: %s Selected %s: %s (GUID: %u)]",
+ fullcmd.c_str(), p->GetName().c_str(), GUID_LOPART(p->GetGUID()), m_session->GetAccountId(), p->GetPositionX(), p->GetPositionY(), p->GetPositionZ(), p->GetMapId(), p->GetMap() ? p->GetMap()->GetMapName() : "Unknown", areaId, areaName.c_str(), zoneName.c_str(),
GetLogNameForGuid(sel_guid), (p->GetSelectedUnit()) ? p->GetSelectedUnit()->GetName().c_str() : "", GUID_LOPART(sel_guid));
}
}
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index 05c9c7b3b0e..6183ba8b8fa 100644
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -63,6 +63,7 @@ DBCStorage <AreaTriggerEntry> sAreaTriggerStore(AreaTriggerEntryfmt);
DBCStorage <ArmorLocationEntry> sArmorLocationStore(ArmorLocationfmt);
DBCStorage <AuctionHouseEntry> sAuctionHouseStore(AuctionHouseEntryfmt);
DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt);
+DBCStorage <BannedAddOnsEntry> sBannedAddOnsStore(BannedAddOnsfmt);
DBCStorage <BattlemasterListEntry> sBattlemasterListStore(BattlemasterListEntryfmt);
DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore(BarberShopStyleEntryfmt);
DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore(CharStartOutfitEntryfmt);
@@ -105,6 +106,7 @@ DBCStorage <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore(GtChance
DBCStorage <GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore(GtChanceToMeleeCritfmt);
DBCStorage <GtChanceToSpellCritBaseEntry> sGtChanceToSpellCritBaseStore(GtChanceToSpellCritBasefmt);
DBCStorage <GtChanceToSpellCritEntry> sGtChanceToSpellCritStore(GtChanceToSpellCritfmt);
+DBCStorage <GtNPCManaCostScalerEntry> sGtNPCManaCostScalerStore(GtNPCManaCostScalerfmt);
DBCStorage <GtOCTClassCombatRatingScalarEntry> sGtOCTClassCombatRatingScalarStore(GtOCTClassCombatRatingScalarfmt);
DBCStorage <GtOCTRegenHPEntry> sGtOCTRegenHPStore(GtOCTRegenHPfmt);
//DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore(GtOCTRegenMPfmt); -- not used currently
@@ -336,6 +338,7 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales, bad_dbc_files, sAuctionHouseStore, dbcPath, "AuctionHouse.dbc");//15595
LoadDBC(availableDbcLocales, bad_dbc_files, sArmorLocationStore, dbcPath, "ArmorLocation.dbc");//15595
LoadDBC(availableDbcLocales, bad_dbc_files, sBankBagSlotPricesStore, dbcPath, "BankBagSlotPrices.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sBannedAddOnsStore, dbcPath, "BannedAddOns.dbc");
LoadDBC(availableDbcLocales, bad_dbc_files, sBattlemasterListStore, dbcPath, "BattlemasterList.dbc");//15595
LoadDBC(availableDbcLocales, bad_dbc_files, sBarberShopStyleStore, dbcPath, "BarberShopStyle.dbc");//15595
LoadDBC(availableDbcLocales, bad_dbc_files, sCharStartOutfitStore, dbcPath, "CharStartOutfit.dbc");//15595
@@ -413,6 +416,7 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToMeleeCritStore, dbcPath, "gtChanceToMeleeCrit.dbc");//15595
LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritBaseStore, dbcPath, "gtChanceToSpellCritBase.dbc");//15595
LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritStore, dbcPath, "gtChanceToSpellCrit.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sGtNPCManaCostScalerStore, dbcPath, "gtNPCManaCostScaler.dbc");
LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTClassCombatRatingScalarStore, dbcPath, "gtOCTClassCombatRatingScalar.dbc");//15595
//LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTRegenHPStore, dbcPath, "gtOCTRegenHP.dbc");//15595
LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTHpPerStaminaStore, dbcPath, "gtOCTHpPerStamina.dbc");//15595
@@ -1055,6 +1059,7 @@ CharStartOutfitEntry const* GetCharStartOutfitEntry(uint8 race, uint8 class_, ui
return itr->second;
}
+
uint32 GetPowerIndexByClass(uint32 powerType, uint32 classId)
{
return PowersByClass[classId][powerType];
@@ -1212,3 +1217,18 @@ uint32 ScalingStatValuesEntry::GetDPSAndDamageMultiplier(uint32 subClass, bool i
return 0;
}
+/// Returns LFGDungeonEntry for a specific map and difficulty. Will return first found entry if multiple dungeons use the same map (such as Scarlet Monastery)
+LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty)
+{
+ for (uint32 i = 0; i < sLFGDungeonStore.GetNumRows(); ++i)
+ {
+ LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(i);
+ if (!dungeon)
+ continue;
+
+ if (dungeon->map == mapId && Difficulty(dungeon->difficulty) == difficulty)
+ return dungeon;
+ }
+
+ return NULL;
+}
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index 60ab87a2876..b49a1a96bd2 100644
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -76,6 +76,7 @@ PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattlegroundB
CharStartOutfitEntry const* GetCharStartOutfitEntry(uint8 race, uint8 class_, uint8 gender);
uint32 GetPowerIndexByClass(uint32 powerType, uint32 classId);
+LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty);
extern DBCStorage <AchievementEntry> sAchievementStore;
extern DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore;
@@ -86,6 +87,7 @@ extern DBCStorage <AreaTriggerEntry> sAreaTriggerStore;
extern DBCStorage <ArmorLocationEntry> sArmorLocationStore;
extern DBCStorage <AuctionHouseEntry> sAuctionHouseStore;
extern DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore;
+extern DBCStorage <BannedAddOnsEntry> sBannedAddOnsStore;
extern DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore;
extern DBCStorage <BattlemasterListEntry> sBattlemasterListStore;
extern DBCStorage <ChatChannelsEntry> sChatChannelsStore;
@@ -120,6 +122,7 @@ extern DBCStorage <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore;
extern DBCStorage <GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore;
extern DBCStorage <GtChanceToSpellCritBaseEntry> sGtChanceToSpellCritBaseStore;
extern DBCStorage <GtChanceToSpellCritEntry> sGtChanceToSpellCritStore;
+extern DBCStorage <GtNPCManaCostScalerEntry> sGtNPCManaCostScalerStore;
extern DBCStorage <GtOCTClassCombatRatingScalarEntry> sGtOCTClassCombatRatingScalarStore;
//extern DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore; -- not used currently
extern DBCStorage <gtOCTHpPerStaminaEntry> sGtOCTHpPerStaminaStore;
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index f1938dd0cd4..64c116654f4 100644
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -630,6 +630,15 @@ struct BankBagSlotPricesEntry
uint32 price;
};
+struct BannedAddOnsEntry
+{
+ uint32 Id;
+ // uint32 NameMD5[4];
+ // uint32 VersionMD5[4];
+ // uint32 Timestamp;
+ // uint32 State;
+};
+
struct BarberShopStyleEntry
{
uint32 Id; // 0
@@ -1084,6 +1093,11 @@ struct GtChanceToSpellCritBaseEntry
float base;
};
+struct GtNPCManaCostScalerEntry
+{
+ float ratio;
+};
+
struct GtChanceToSpellCritEntry
{
float ratio;
diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h
index 96da1add537..cc10199c240 100644
--- a/src/server/game/DataStores/DBCfmt.h
+++ b/src/server/game/DataStores/DBCfmt.h
@@ -33,6 +33,7 @@ char const AreaTriggerEntryfmt[] = "nifffxxxfffff";
char const ArmorLocationfmt[] = "nfffff";
char const AuctionHouseEntryfmt[] = "niiix";
char const BankBagSlotPricesEntryfmt[] = "ni";
+char const BannedAddOnsfmt[] = "nxxxxxxxxxx";
char const BarberShopStyleEntryfmt[] = "nixxxiii";
char const BattlemasterListEntryfmt[] = "niiiiiiiiixsiiiixxxx";
char const CharStartOutfitEntryfmt[] = "dbbbXiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxii";
@@ -67,6 +68,7 @@ char const GtChanceToMeleeCritBasefmt[] = "xf";
char const GtChanceToMeleeCritfmt[] = "xf";
char const GtChanceToSpellCritBasefmt[] = "xf";
char const GtChanceToSpellCritfmt[] = "xf";
+char const GtNPCManaCostScalerfmt[] = "f";
char const GtOCTClassCombatRatingScalarfmt[] = "df";
char const GtOCTRegenHPfmt[] = "f";
//char const GtOCTRegenMPfmt[] = "f";
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp
index 3cd0a1223dd..02c09e0013d 100644
--- a/src/server/game/Entities/Creature/GossipDef.cpp
+++ b/src/server/game/Entities/Creature/GossipDef.cpp
@@ -65,6 +65,48 @@ void GossipMenu::AddMenuItem(int32 menuItemId, uint8 icon, std::string const& me
menuItem.BoxMoney = boxMoney;
}
+/**
+ * @name AddMenuItem
+ * @brief Adds a localized gossip menu item from db by menu id and menu item id.
+ * @param menuId Gossip menu id.
+ * @param menuItemId Gossip menu item id.
+ * @param sender Identifier of the current menu.
+ * @param action Custom action given to OnGossipHello.
+ */
+void GossipMenu::AddMenuItem(uint32 menuId, uint32 menuItemId, uint32 sender, uint32 action)
+{
+ /// Find items for given menu id.
+ GossipMenuItemsMapBounds bounds = sObjectMgr->GetGossipMenuItemsMapBounds(menuId);
+ /// Return if there are none.
+ if (bounds.first == bounds.second)
+ return;
+
+ /// Iterate over each of them.
+ for (GossipMenuItemsContainer::const_iterator itr = bounds.first; itr != bounds.second; ++itr)
+ {
+ /// Find the one with the given menu item id.
+ if (itr->second.OptionIndex != menuItemId)
+ continue;
+
+ /// Store texts for localization.
+ std::string strOptionText = itr->second.OptionText;
+ std::string strBoxText = itr->second.BoxText;
+
+ /// Check need of localization.
+ if (GetLocale() > LOCALE_enUS)
+ /// Find localizations from database.
+ if (GossipMenuItemsLocale const* no = sObjectMgr->GetGossipMenuItemsLocale(MAKE_PAIR32(menuId, menuItemId)))
+ {
+ /// Translate texts if there are any.
+ ObjectMgr::GetLocaleString(no->OptionText, GetLocale(), strOptionText);
+ ObjectMgr::GetLocaleString(no->BoxText, GetLocale(), strBoxText);
+ }
+
+ /// Add menu item with existing method. Menu item id -1 is also used in ADD_GOSSIP_ITEM macro.
+ AddMenuItem(-1, itr->second.OptionIcon, strOptionText, sender, action, strBoxText, itr->second.BoxMoney, itr->second.BoxCoded);
+ }
+}
+
void GossipMenu::AddGossipMenuItemData(uint32 menuItemId, uint32 gossipActionMenuId, uint32 gossipActionPoi)
{
GossipMenuItemData& itemData = _menuItemData[menuItemId];
@@ -108,6 +150,8 @@ void GossipMenu::ClearMenu()
PlayerMenu::PlayerMenu(WorldSession* session) : _session(session)
{
+ if (_session)
+ _gossipMenu.SetLocale(_session->GetSessionDbLocaleIndex());
}
PlayerMenu::~PlayerMenu()
diff --git a/src/server/game/Entities/Creature/GossipDef.h b/src/server/game/Entities/Creature/GossipDef.h
index 7d6d21cd9ad..c76febc0165 100644
--- a/src/server/game/Entities/Creature/GossipDef.h
+++ b/src/server/game/Entities/Creature/GossipDef.h
@@ -163,9 +163,12 @@ class GossipMenu
~GossipMenu();
void AddMenuItem(int32 menuItemId, uint8 icon, std::string const& message, uint32 sender, uint32 action, std::string const& boxMessage, uint32 boxMoney, bool coded = false);
+ void AddMenuItem(uint32 menuId, uint32 menuItemId, uint32 sender, uint32 action);
void SetMenuId(uint32 menu_id) { _menuId = menu_id; }
uint32 GetMenuId() const { return _menuId; }
+ void SetLocale(LocaleConstant locale) { _locale = locale; }
+ LocaleConstant GetLocale() const { return _locale; }
void AddGossipMenuItemData(uint32 menuItemId, uint32 gossipActionMenuId, uint32 gossipActionPoi);
@@ -212,6 +215,7 @@ class GossipMenu
GossipMenuItemContainer _menuItems;
GossipMenuItemDataContainer _menuItemData;
uint32 _menuId;
+ LocaleConstant _locale;
};
class QuestMenu
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 7ac40ad08a0..a1665b9c48f 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -1120,7 +1120,7 @@ void GameObject::Use(Unit* user)
Player* player = user->ToPlayer();
- player->PrepareGossipMenu(this, GetGOInfo()->questgiver.gossipID);
+ player->PrepareGossipMenu(this, GetGOInfo()->questgiver.gossipID, true);
player->SendPreparedGossip(this);
return;
}
@@ -1832,14 +1832,14 @@ void GameObject::ModifyHealth(int32 change, Unit* attackerOrHealer /*= NULL*/, u
Player* player = attackerOrHealer->GetCharmerOrOwnerPlayerOrPlayerItself();
// dealing damage, send packet
- /// @todo is there any packet for healing?
- if (change < 0 && player)
+ if (player)
{
WorldPacket data(SMSG_DESTRUCTIBLE_BUILDING_DAMAGE, 8 + 8 + 8 + 4 + 4);
data.appendPackGUID(GetGUID());
data.appendPackGUID(attackerOrHealer->GetGUID());
data.appendPackGUID(player->GetGUID());
- data << uint32(-change);
+ data << uint32(-change); // change < 0 triggers SPELL_BUILDING_HEAL combat log event
+ // change >= 0 triggers SPELL_BUILDING_DAMAGE event
data << uint32(spellId);
player->GetSession()->SendPacket(&data);
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index ab8f9690b5e..5838786bc3e 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -4723,7 +4723,7 @@ TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell
/**
* Deletes a character from the database
*
- * The way, how the characters will be deleted is decided based on the config option.
+ * The way characters will be deleted is decided based on the config option.
*
* @see Player::DeleteOldCharacters
*
@@ -4734,19 +4734,32 @@ TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell
*/
void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmChars, bool deleteFinally)
{
- // for not existed account avoid update realm
+ // Avoid realm-update for non-existing account
if (accountId == 0)
updateRealmChars = false;
+ // Convert guid to low GUID for CharacterNameData, but also other methods on success
+ uint32 guid = GUID_LOPART(playerguid);
uint32 charDelete_method = sWorld->getIntConfig(CONFIG_CHARDELETE_METHOD);
- uint32 charDelete_minLvl = sWorld->getIntConfig(CONFIG_CHARDELETE_MIN_LEVEL);
- // if we want to finally delete the character or the character does not meet the level requirement,
- // we set it to mode CHAR_DELETE_REMOVE
- if (deleteFinally || Player::GetLevelFromDB(playerguid) < charDelete_minLvl)
+ if (deleteFinally)
charDelete_method = CHAR_DELETE_REMOVE;
+ else if (CharacterNameData const* nameData = sWorld->GetCharacterNameData(guid)) // To avoid a query, we select loaded data. If it doesn't exist, return.
+ {
+ if (!nameData)
+ {
+ sLog->outError(LOG_FILTER_PLAYER, "Cannot find CharacterNameData entry for player %u from account %u. Could not delete character.", guid, accountId);
+ return;
+ }
- uint32 guid = GUID_LOPART(playerguid);
+ // Define the required variables
+ uint32 charDelete_minLvl = sWorld->getIntConfig(nameData->m_class != CLASS_DEATH_KNIGHT ? CONFIG_CHARDELETE_MIN_LEVEL : CONFIG_CHARDELETE_HEROIC_MIN_LEVEL);
+
+ // if we want to finalize the character removal or the character does not meet the level requirement of either heroic or non-heroic settings,
+ // we set it to mode CHAR_DELETE_REMOVE
+ if (nameData->m_level < charDelete_minLvl)
+ charDelete_method = CHAR_DELETE_REMOVE;
+ }
// convert corpse to bones if exist (to prevent exiting Corpse in World without DB entry)
// bones will be deleted by corpse/bones deleting thread shortly
@@ -5046,10 +5059,13 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
}
default:
sLog->outError(LOG_FILTER_PLAYER, "Player::DeleteFromDB: Unsupported delete method: %u.", charDelete_method);
+ return;
}
if (updateRealmChars)
sWorld->UpdateRealmCharCount(accountId);
+
+ sWorld->DeleteCharacterNameData(guid);
}
/**
@@ -6626,13 +6642,13 @@ 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().c_str(), MAX_ACTION_BUTTONS );
+ sLog->outError(LOG_FILTER_PLAYER, "Action %u not added into button %u for player %s (GUID: %u): button must be < %u", action, button, GetName().c_str(), GUID_LOPART(GetGUID()), 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().c_str(), MAX_ACTION_BUTTON_ACTION_VALUE);
+ sLog->outError(LOG_FILTER_PLAYER, "Action %u not added into button %u for player %s (GUID: %u): action must be < %u", action, button, GetName().c_str(), GUID_LOPART(GetGUID()), MAX_ACTION_BUTTON_ACTION_VALUE);
return false;
}
@@ -6641,20 +6657,20 @@ 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().c_str());
+ sLog->outError(LOG_FILTER_PLAYER, "Spell action %u not added into button %u for player %s (GUID: %u): spell not exist", action, button, GetName().c_str(), GUID_LOPART(GetGUID()));
return false;
}
if (!HasSpell(action))
{
- sLog->outError(LOG_FILTER_PLAYER, "Spell action %u not added into button %u for player %s: player don't known this spell", action, button, GetName().c_str());
+ sLog->outError(LOG_FILTER_PLAYER, "Spell action %u not added into button %u for player %s (GUID: %u): player don't known this spell", action, button, GetName().c_str(), GUID_LOPART(GetGUID()));
return false;
}
break;
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().c_str());
+ sLog->outError(LOG_FILTER_PLAYER, "Item action %u not added into button %u for player %s (GUID: %u): item not exist", action, button, GetName().c_str(), GUID_LOPART(GetGUID()));
return false;
}
break;
@@ -6992,14 +7008,11 @@ void Player::RewardReputation(Unit* victim, float rate)
if (GetChampioningFaction())
{
// support for: Championing - http://www.wowwiki.com/Championing
-
Map const* map = GetMap();
if (map && map->IsNonRaidDungeon())
- {
- if (AccessRequirement const* accessRequirement = sObjectMgr->GetAccessRequirement(map->GetId(), map->GetDifficulty()))
- if (accessRequirement->levelMin == 80)
+ if (LFGDungeonEntry const* dungeon = GetLFGDungeon(map->GetId(), map->GetDifficulty()))
+ if (dungeon->reclevel == 80)
ChampioningFaction = GetChampioningFaction();
- }
}
uint32 team = GetTeam();
@@ -14363,12 +14376,11 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool
if (source->GetTypeId() == TYPEID_UNIT)
{
npcflags = source->GetUInt32Value(UNIT_NPC_FLAGS);
- if (npcflags & UNIT_NPC_FLAG_QUESTGIVER && showQuests)
+ if (showQuests && npcflags & UNIT_NPC_FLAG_QUESTGIVER)
PrepareQuestMenu(source->GetGUID());
}
-
- if (source->GetTypeId() == TYPEID_GAMEOBJECT)
- if (source->ToGameObject()->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER)
+ else if (source->GetTypeId() == TYPEID_GAMEOBJECT)
+ if (showQuests && source->ToGameObject()->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER)
PrepareQuestMenu(source->GetGUID());
for (GossipMenuItemsContainer::const_iterator itr = menuItemBounds.first; itr != menuItemBounds.second; ++itr)
@@ -17007,7 +17019,9 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
PreparedQueryResult result = holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_FROM);
if (!result)
{
- sLog->outError(LOG_FILTER_PLAYER, "Player (GUID: %u) not found in table `characters`, can't load. ", guid);
+ std::string name = "<unknown>";
+ sObjectMgr->GetPlayerNameByGUID(guid, name);
+ sLog->outError(LOG_FILTER_PLAYER, "Player %s (GUID: %u) not found in table `characters`, can't load. ", name.c_str(), guid);
return false;
}
@@ -18636,14 +18650,16 @@ void Player::_LoadBoundInstances(PreparedQueryResult result)
bool deleteInstance = false;
MapEntry const* mapEntry = sMapStore.LookupEntry(mapId);
+ std::string mapname = mapEntry ? mapEntry->name : "Unknown";
+
if (!mapEntry || !mapEntry->IsDungeon())
{
- sLog->outError(LOG_FILTER_PLAYER, "_LoadBoundInstances: player %s(%d) has bind to not existed or not dungeon map %d", GetName().c_str(), GetGUIDLow(), mapId);
+ sLog->outError(LOG_FILTER_PLAYER, "_LoadBoundInstances: player %s(%d) has bind to not existed or not dungeon map %d (%s)", GetName().c_str(), GetGUIDLow(), mapId, mapname.c_str());
deleteInstance = true;
}
else if (difficulty >= MAX_DIFFICULTY)
{
- sLog->outError(LOG_FILTER_PLAYER, "_LoadBoundInstances: player %s(%d) has bind to not existed difficulty %d instance for map %u", GetName().c_str(), GetGUIDLow(), difficulty, mapId);
+ sLog->outError(LOG_FILTER_PLAYER, "_LoadBoundInstances: player %s(%d) has bind to not existed difficulty %d instance for map %u (%s)", GetName().c_str(), GetGUIDLow(), difficulty, mapId, mapname.c_str());
deleteInstance = true;
}
else
@@ -18651,12 +18667,12 @@ void Player::_LoadBoundInstances(PreparedQueryResult result)
MapDifficulty const* mapDiff = GetMapDifficultyData(mapId, Difficulty(difficulty));
if (!mapDiff)
{
- sLog->outError(LOG_FILTER_PLAYER, "_LoadBoundInstances: player %s(%d) has bind to not existed difficulty %d instance for map %u", GetName().c_str(), GetGUIDLow(), difficulty, mapId);
+ sLog->outError(LOG_FILTER_PLAYER, "_LoadBoundInstances: player %s(%d) has bind to not existed difficulty %d instance for map %u (%s)", GetName().c_str(), GetGUIDLow(), difficulty, mapId, mapname.c_str());
deleteInstance = true;
}
else if (!perm && group)
{
- sLog->outError(LOG_FILTER_PLAYER, "_LoadBoundInstances: player %s(%d) is in group %d but has a non-permanent character bind to map %d, %d, %d", GetName().c_str(), GetGUIDLow(), GUID_LOPART(group->GetGUID()), mapId, instanceId, difficulty);
+ sLog->outError(LOG_FILTER_PLAYER, "_LoadBoundInstances: player %s(%d) is in group %d but has a non-permanent character bind to map %d (%s), %d, %d", GetName().c_str(), GetGUIDLow(), GUID_LOPART(group->GetGUID()), mapId, mapname.c_str(), instanceId, difficulty);
deleteInstance = true;
}
}
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 6fb43f44a3c..ad66f5a7e6c 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -145,37 +145,30 @@ void DamageInfo::BlockDamage(uint32 amount)
m_damage -= amount;
}
-ProcEventInfo::ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget, uint32 typeMask, uint32 spellTypeMask, uint32 spellPhaseMask, uint32 hitMask, Spell* spell, DamageInfo* damageInfo, HealInfo* healInfo)
-:_actor(actor), _actionTarget(actionTarget), _procTarget(procTarget), _typeMask(typeMask), _spellTypeMask(spellTypeMask), _spellPhaseMask(spellPhaseMask),
-_hitMask(hitMask), _spell(spell), _damageInfo(damageInfo), _healInfo(healInfo)
-{
-}
+ProcEventInfo::ProcEventInfo(Unit* actor, Unit* actionTarget, Unit* procTarget,
+ uint32 typeMask, uint32 spellTypeMask,
+ uint32 spellPhaseMask, uint32 hitMask,
+ Spell* spell, DamageInfo* damageInfo,
+ HealInfo* healInfo) :
+ _actor(actor), _actionTarget(actionTarget), _procTarget(procTarget),
+ _typeMask(typeMask), _spellTypeMask(spellTypeMask),
+ _spellPhaseMask(spellPhaseMask), _hitMask(hitMask), _spell(spell),
+ _damageInfo(damageInfo), _healInfo(healInfo)
+{ }
// we can disable this warning for this since it only
// causes undefined behavior when passed to the base class constructor
#ifdef _MSC_VER
#pragma warning(disable:4355)
#endif
-Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject),
- m_movedPlayer(NULL),
- m_lastSanctuaryTime(0),
- m_TempSpeed(0.0f),
- IsAIEnabled(false),
- NeedChangeAI(false),
- m_ControlledByPlayer(false),
- movespline(new Movement::MoveSpline()),
- i_AI(NULL),
- i_disabledAI(NULL),
- m_AutoRepeatFirstCast(false),
- m_procDeep(0),
- m_removedAurasCount(0),
- i_motionMaster(this),
- m_ThreatManager(this),
- m_vehicle(NULL),
- m_vehicleKit(NULL),
- m_unitTypeMask(UNIT_MASK_NONE),
- m_HostileRefManager(this),
- _lastDamagedTime(0)
+Unit::Unit(bool isWorldObject) :
+ WorldObject(isWorldObject), m_movedPlayer(NULL), m_lastSanctuaryTime(0),
+ m_TempSpeed(0.0f), IsAIEnabled(false), NeedChangeAI(false),
+ m_ControlledByPlayer(false), movespline(new Movement::MoveSpline()),
+ i_AI(NULL), i_disabledAI(NULL), m_AutoRepeatFirstCast(false), m_procDeep(0),
+ m_removedAurasCount(0), i_motionMaster(this), m_ThreatManager(this),
+ m_vehicle(NULL), m_vehicleKit(NULL), m_unitTypeMask(UNIT_MASK_NONE),
+ m_HostileRefManager(this), _lastDamagedTime(0)
{
#ifdef _MSC_VER
#pragma warning(default:4355)
@@ -1442,7 +1435,6 @@ bool Unit::IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellInfo const* s
uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo const* spellInfo, WeaponAttackType /*attackType*/)
{
- uint32 newdamage = 0;
float armor = float(victim->GetArmor());
// bypass enemy armor by SPELL_AURA_BYPASS_ARMOR_FOR_CASTER
@@ -1460,8 +1452,8 @@ uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_IGNORE_ARMOR, armor);
- AuraEffectList const& ResIgnoreAuras = GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
- for (AuraEffectList::const_iterator j = ResIgnoreAuras.begin(); j != ResIgnoreAuras.end(); ++j)
+ AuraEffectList const& resIgnoreAuras = GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
+ for (AuraEffectList::const_iterator j = resIgnoreAuras.begin(); j != resIgnoreAuras.end(); ++j)
{
if ((*j)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)
armor = floor(AddPct(armor, -(*j)->GetAmount()));
@@ -1489,7 +1481,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo
float levelModifier = getLevel();
if (levelModifier > 59)
- levelModifier = levelModifier + (4.5f * (levelModifier - 59));
+ levelModifier = levelModifier + 4.5f * (levelModifier - 59);
float tmpvalue = 0.1f * armor / (8.5f * levelModifier + 40);
tmpvalue = tmpvalue / (1.0f + tmpvalue);
@@ -1499,9 +1491,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo
if (tmpvalue > 0.75f)
tmpvalue = 0.75f;
- newdamage = uint32(damage - (damage * tmpvalue));
-
- return (newdamage > 1) ? newdamage : 1;
+ return std::max<uint32>(damage * (1.0f - tmpvalue), 1);
}
void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffectType damagetype, uint32 const damage, uint32 *absorb, uint32 *resist, SpellInfo const* spellInfo)
@@ -1589,6 +1579,7 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe
if (((*itr)->GetAmount() > auraAbsorbMod) && (*itr)->IsAffectingSpell(spellInfo))
auraAbsorbMod = float((*itr)->GetAmount());
}
+
RoundToInterval(auraAbsorbMod, 0.0f, 100.0f);
// We're going to call functions which can modify content of the list during iteration over it's elements
@@ -1710,7 +1701,7 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe
// We're going to call functions which can modify content of the list during iteration over it's elements
// Let's copy the list so we can prevent iterator invalidation
AuraEffectList vSplitDamagePctCopy(victim->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_PCT));
- for (AuraEffectList::iterator itr = vSplitDamagePctCopy.begin(), next; (itr != vSplitDamagePctCopy.end()) && (dmgInfo.GetDamage() > 0); ++itr)
+ for (AuraEffectList::iterator itr = vSplitDamagePctCopy.begin(); itr != vSplitDamagePctCopy.end() && dmgInfo.GetDamage() > 0; ++itr)
{
// Check if aura was removed during iteration - we don't need to work on such auras
AuraApplication const* aurApp = (*itr)->GetBase()->GetApplicationOfTarget(victim->GetGUID());
@@ -2147,7 +2138,7 @@ bool Unit::isBlockCritical()
return false;
}
-int32 Unit::GetMechanicResistChance(const SpellInfo* spell)
+int32 Unit::GetMechanicResistChance(const SpellInfo* spell) const
{
if (!spell)
return 0;
@@ -2171,11 +2162,15 @@ bool Unit::CanUseAttackType(uint8 attacktype) const
{
switch (attacktype)
{
- case BASE_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
- case OFF_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_DISARM_OFFHAND);
- case RANGED_ATTACK: return !HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_DISARM_RANGED);
+ case BASE_ATTACK:
+ return !HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISARMED);
+ case OFF_ATTACK:
+ return !HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_DISARM_OFFHAND);
+ case RANGED_ATTACK:
+ return !HasFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_DISARM_RANGED);
+ default:
+ return true;
}
- return true;
}
// Melee based spells hit result calculations
@@ -4106,11 +4101,11 @@ bool Unit::HasAuraTypeWithValue(AuraType auratype, int32 value) const
return false;
}
-bool Unit::HasNegativeAuraWithInterruptFlag(uint32 flag, uint64 guid)
+bool Unit::HasNegativeAuraWithInterruptFlag(uint32 flag, uint64 guid) const
{
if (!(m_interruptMask & flag))
return false;
- for (AuraApplicationList::iterator iter = m_interruptableAuras.begin(); iter != m_interruptableAuras.end(); ++iter)
+ for (AuraApplicationList::const_iterator iter = m_interruptableAuras.begin(); iter != m_interruptableAuras.end(); ++iter)
{
if (!(*iter)->IsPositive() && (*iter)->GetBase()->GetSpellInfo()->AuraInterruptFlags & flag && (!guid || (*iter)->GetBase()->GetCasterGUID() == guid))
return true;
@@ -4118,9 +4113,9 @@ bool Unit::HasNegativeAuraWithInterruptFlag(uint32 flag, uint64 guid)
return false;
}
-bool Unit::HasNegativeAuraWithAttribute(uint32 flag, uint64 guid)
+bool Unit::HasNegativeAuraWithAttribute(uint32 flag, uint64 guid) const
{
- for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end(); ++iter)
+ for (AuraApplicationMap::const_iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end(); ++iter)
{
Aura const* aura = iter->second->GetBase();
if (!iter->second->IsPositive() && aura->GetSpellInfo()->Attributes & flag && (!guid || aura->GetCasterGUID() == guid))
@@ -4129,11 +4124,11 @@ bool Unit::HasNegativeAuraWithAttribute(uint32 flag, uint64 guid)
return false;
}
-bool Unit::HasAuraWithMechanic(uint32 mechanicMask)
+bool Unit::HasAuraWithMechanic(uint32 mechanicMask) const
{
- for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end(); ++iter)
+ for (AuraApplicationMap::const_iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end(); ++iter)
{
- SpellInfo const* spellInfo = iter->second->GetBase()->GetSpellInfo();
+ SpellInfo const* spellInfo = iter->second->GetBase()->GetSpellInfo();
if (spellInfo->Mechanic && (mechanicMask & (1 << spellInfo->Mechanic)))
return true;
@@ -4168,7 +4163,7 @@ uint32 Unit::GetDiseasesByCaster(uint64 casterGUID, bool remove)
};
uint32 diseases = 0;
- for (AuraType const* itr = &diseaseAuraTypes[0]; itr && itr[0] != SPELL_AURA_NONE; ++itr)
+ for (AuraType const* itr = diseaseAuraTypes; *itr != SPELL_AURA_NONE; ++itr)
{
for (AuraEffectList::iterator i = m_modAuras[*itr].begin(); i != m_modAuras[*itr].end();)
{
@@ -8648,9 +8643,11 @@ void Unit::SetCharm(Unit* charm, bool apply)
}
if (charm->GetTypeId() == TYPEID_PLAYER
- || !charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_MINION)
- || charm->GetOwnerGUID() != GetGUID())
+ || !charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_MINION)
+ || charm->GetOwnerGUID() != GetGUID())
+ {
m_Controlled.erase(charm);
+ }
}
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 8bedb7b231d..396a4c577f1 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1474,19 +1474,19 @@ class Unit : public WorldObject
uint32 GetCritDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_RESILIENCE_CRIT_TAKEN, 2.2f, 33.0f, damage); }
uint32 GetDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_RESILIENCE_PLAYER_DAMAGE_TAKEN, 2.0f, 100.0f, damage); }
- void ApplyResilience(const Unit* victim, int32 * damage, bool isCrit) const;
+ void ApplyResilience(Unit const* victim, int32 * damage, bool isCrit) const;
- float MeleeSpellMissChance(const Unit* victim, WeaponAttackType attType, uint32 spellId) const;
+ float MeleeSpellMissChance(Unit const* victim, WeaponAttackType attType, uint32 spellId) const;
SpellMissInfo MeleeSpellHitResult(Unit* victim, SpellInfo const* spell);
SpellMissInfo MagicSpellHitResult(Unit* victim, SpellInfo const* spell);
SpellMissInfo SpellHitResult(Unit* victim, SpellInfo const* spell, bool canReflect = false);
- float GetUnitDodgeChance() const;
- float GetUnitParryChance() const;
- float GetUnitBlockChance() const;
- float GetUnitMissChance(WeaponAttackType attType) const;
+ float GetUnitDodgeChance() const;
+ float GetUnitParryChance() const;
+ float GetUnitBlockChance() const;
+ float GetUnitMissChance(WeaponAttackType attType) const;
float GetUnitCriticalChance(WeaponAttackType attackType, const Unit* victim) const;
- int32 GetMechanicResistChance(const SpellInfo* spell);
+ int32 GetMechanicResistChance(const SpellInfo* spell) const;
bool CanUseAttackType(uint8 attacktype) const;
virtual uint32 GetBlockPercent() const { return 30; }
@@ -1784,9 +1784,9 @@ class Unit : public WorldObject
bool HasAuraTypeWithMiscvalue(AuraType auratype, int32 miscvalue) const;
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const* affectedSpell) const;
bool HasAuraTypeWithValue(AuraType auratype, int32 value) const;
- bool HasNegativeAuraWithInterruptFlag(uint32 flag, uint64 guid = 0);
- bool HasNegativeAuraWithAttribute(uint32 flag, uint64 guid = 0);
- bool HasAuraWithMechanic(uint32 mechanicMask);
+ bool HasNegativeAuraWithInterruptFlag(uint32 flag, uint64 guid = 0) const;
+ bool HasNegativeAuraWithAttribute(uint32 flag, uint64 guid = 0) const;
+ bool HasAuraWithMechanic(uint32 mechanicMask) const;
AuraEffect* IsScriptOverriden(SpellInfo const* spell, int32 script) const;
uint32 GetDiseasesByCaster(uint64 casterGUID, bool remove = false);
diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp
index 1b4f687d8c5..e727977df19 100644
--- a/src/server/game/Events/GameEventMgr.cpp
+++ b/src/server/game/Events/GameEventMgr.cpp
@@ -205,8 +205,8 @@ void GameEventMgr::LoadFromDB()
{
{
uint32 oldMSTime = getMSTime();
- // 0 1 2 3 4 5 6 7
- QueryResult result = WorldDatabase.Query("SELECT eventEntry, UNIX_TIMESTAMP(start_time), UNIX_TIMESTAMP(end_time), occurence, length, holiday, description, world_event FROM game_event");
+ // 0 1 2 3 4 5 6 7 8
+ QueryResult result = WorldDatabase.Query("SELECT eventEntry, UNIX_TIMESTAMP(start_time), UNIX_TIMESTAMP(end_time), occurence, length, holiday, description, world_event, announce FROM game_event");
if (!result)
{
mGameEvent.clear();
@@ -237,6 +237,7 @@ void GameEventMgr::LoadFromDB()
pGameEvent.state = (GameEventState)(fields[7].GetUInt8());
pGameEvent.nextstart = 0;
+ pGameEvent.announce = fields[8].GetUInt8();
if (pGameEvent.length == 0 && pGameEvent.state == GAMEEVENT_NORMAL) // length>0 is validity check
{
@@ -1105,7 +1106,8 @@ void GameEventMgr::UnApplyEvent(uint16 event_id)
void GameEventMgr::ApplyNewEvent(uint16 event_id)
{
- if (sWorld->getBoolConfig(CONFIG_EVENT_ANNOUNCE))
+ uint8 announce = mGameEvent[event_id].announce;
+ if (announce == 1 || (announce == 2 && sWorld->getBoolConfig(CONFIG_EVENT_ANNOUNCE)))
sWorld->SendWorldText(LANG_EVENTMESSAGE, mGameEvent[event_id].description.c_str());
sLog->outInfo(LOG_FILTER_GAMEEVENTS, "GameEvent %u \"%s\" started.", event_id, mGameEvent[event_id].description.c_str());
diff --git a/src/server/game/Events/GameEventMgr.h b/src/server/game/Events/GameEventMgr.h
index 192c441f50f..994f32f75d6 100644
--- a/src/server/game/Events/GameEventMgr.h
+++ b/src/server/game/Events/GameEventMgr.h
@@ -66,6 +66,7 @@ struct GameEventData
GameEventConditionMap conditions; // conditions to finish
std::set<uint16 /*gameevent id*/> prerequisite_events; // events that must be completed before starting this event
std::string description;
+ uint8 announce; // if 0 dont announce, if 1 announce, if 2 take config value
bool isValid() const { return length > 0 || state > GAMEEVENT_NORMAL; }
};
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 7982b8486b4..c6c239b6518 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -7930,13 +7930,13 @@ void ObjectMgr::AddSpellToTrainer(uint32 entry, uint32 spell, uint32 spellCost,
CreatureTemplate const* cInfo = GetCreatureTemplate(entry);
if (!cInfo)
{
- sLog->outError(LOG_FILTER_SQL, "Table `npc_trainer` contains an entry for a non-existing creature template (Entry: %u), ignoring", entry);
+ sLog->outError(LOG_FILTER_SQL, "Table `npc_trainer` contains entries for a non-existing creature template (Entry: %u), ignoring", entry);
return;
}
if (!(cInfo->npcflag & UNIT_NPC_FLAG_TRAINER))
{
- sLog->outError(LOG_FILTER_SQL, "Table `npc_trainer` contains an entry for a creature template (Entry: %u) without trainer flag, ignoring", entry);
+ sLog->outError(LOG_FILTER_SQL, "Table `npc_trainer` contains entries for a creature template (Entry: %u) without trainer flag, ignoring", entry);
return;
}
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index f559e581dd8..41d81dc39d2 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -1022,10 +1022,10 @@ void Guild::BankMoveItemData::LogAction(MoveItemData* pFrom) const
if (!pFrom->IsBank() && m_pPlayer->GetSession()->HasPermission(RBAC_PERM_LOG_GM_TRADE)) /// @todo Move this to scripts
{
sLog->outCommand(m_pPlayer->GetSession()->GetAccountId(),
- "GM %s (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank (Guild ID: %u)",
- m_pPlayer->GetName().c_str(), m_pPlayer->GetSession()->GetAccountId(),
+ "GM %s (Guid: %u) (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank named: %s (Guild ID: %u)",
+ m_pPlayer->GetName().c_str(), m_pPlayer->GetGUIDLow(), m_pPlayer->GetSession()->GetAccountId(),
pFrom->GetItem()->GetTemplate()->Name1.c_str(), pFrom->GetItem()->GetEntry(), pFrom->GetItem()->GetCount(),
- m_pGuild->GetId());
+ m_pGuild->GetName().c_str(), m_pGuild->GetId());
}
}
@@ -1356,6 +1356,19 @@ void Guild::OnPlayerStatusChange(Player* player, uint32 flag, bool state)
}
}
+bool Guild::SetName(std::string const& name)
+{
+ if (m_name == name || name.empty() || name.length() > 24 || sObjectMgr->IsReservedName(name) || !ObjectMgr::IsValidCharterName(name))
+ return false;
+
+ m_name = name;
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_NAME);
+ stmt->setString(0, m_name);
+ stmt->setUInt32(1, GetId());
+ CharacterDatabase.Execute(stmt);
+ return true;
+}
+
void Guild::HandleRoster(WorldSession* session /*= NULL*/)
{
ByteBuffer memberData(100);
diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h
index 0c41cc68a60..cf03cb58748 100644
--- a/src/server/game/Guilds/Guild.h
+++ b/src/server/game/Guilds/Guild.h
@@ -768,6 +768,8 @@ public:
std::string const& GetMOTD() const { return m_motd; }
std::string const& GetInfo() const { return m_info; }
+ bool SetName(std::string const& name);
+
// Handle client commands
void HandleRoster(WorldSession* session = NULL);
void HandleQuery(WorldSession* session);
diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp
index 33316338c9e..3fc36cf6f7c 100644
--- a/src/server/game/Handlers/AuctionHouseHandler.cpp
+++ b/src/server/game/Handlers/AuctionHouseHandler.cpp
@@ -151,6 +151,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
if (itemsCount > MAX_AUCTION_ITEMS)
{
SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR);
+ recvData.rfinish();
return;
}
@@ -159,8 +160,11 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
recvData >> itemGUIDs[i];
recvData >> count[i];
- if (!itemGUIDs[i] || !count[i] || count[i] > 1000 )
+ if (!itemGUIDs[i] || !count[i] || count[i] > 1000)
+ {
+ recvData.rfinish();
return;
+ }
}
recvData >> bid;
@@ -170,6 +174,14 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
if (!bid || !etime)
return;
+ if (bid > MAX_MONEY_AMOUNT || buyout > MAX_MONEY_AMOUNT)
+ {
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: HandleAuctionSellItem - Player %s (GUID %u) attempted to sell item with higher price than max gold amount.", _player->GetName().c_str(), _player->GetGUIDLow());
+ SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR);
+ return;
+ }
+
+
Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER);
if (!creature)
{
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 8ad49724b2e..ea8fd5a9d9d 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -763,7 +763,6 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket& recvData)
std::string IP_str = GetRemoteAddress();
sLog->outInfo(LOG_FILTER_CHARACTER, "Account: %d, IP: %s deleted character: %s, GUID: %u, Level: %u", accountId, IP_str.c_str(), name.c_str(), GUID_LOPART(guid), level);
sScriptMgr->OnPlayerDelete(guid);
- sWorld->DeleteCharacterNameData(GUID_LOPART(guid));
if (sLog->ShouldLog(LOG_FILTER_PLAYER_DUMP, LOG_LEVEL_INFO)) // optimize GetPlayerDump call
{
diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp
index ee28e0c30d5..d1a8bb8c3e5 100644
--- a/src/server/game/Handlers/GroupHandler.cpp
+++ b/src/server/game/Handlers/GroupHandler.cpp
@@ -942,10 +942,28 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke
{
if (player)
{
+ uint16 playerStatus = MEMBER_STATUS_ONLINE;
if (player->IsPvP())
- *data << uint16(MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP);
- else
- *data << uint16(MEMBER_STATUS_ONLINE);
+ playerStatus |= MEMBER_STATUS_PVP;
+
+ if (!player->isAlive())
+ {
+ if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
+ playerStatus |= MEMBER_STATUS_GHOST;
+ else
+ playerStatus |= MEMBER_STATUS_DEAD;
+ }
+
+ if (player->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
+ playerStatus |= MEMBER_STATUS_PVP_FFA;
+
+ if (player->isAFK())
+ playerStatus |= MEMBER_STATUS_AFK;
+
+ if (player->isDND())
+ playerStatus |= MEMBER_STATUS_DND;
+
+ *data << uint16(playerStatus);
}
else
*data << uint16(MEMBER_STATUS_OFFLINE);
@@ -977,7 +995,11 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke
*data << uint16(0);
if (mask & GROUP_UPDATE_FLAG_POSITION)
- *data << uint16(player->GetPositionX()) << uint16(player->GetPositionY()) << uint16(player->GetPositionZ());
+ {
+ *data << uint16(player->GetPositionX());
+ *data << uint16(player->GetPositionY());
+ *data << uint16(player->GetPositionZ());
+ }
if (mask & GROUP_UPDATE_FLAG_AURAS)
{
@@ -1079,14 +1101,6 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke
*data << uint16(0);
}
- if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
- {
- if (Vehicle* veh = player->GetVehicle())
- *data << uint32(veh->GetVehicleInfo()->m_seatID[player->m_movementInfo.t_seat]);
- else
- *data << uint32(0);
- }
-
if (mask & GROUP_UPDATE_FLAG_PET_AURAS)
{
if (pet)
@@ -1136,6 +1150,15 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke
*data << uint32(0); // count
// for (count) *data << uint16(phaseId)
}
+
+ if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
+ {
+ if (Vehicle* veh = player->GetVehicle())
+ *data << uint32(veh->GetVehicleInfo()->m_seatID[player->m_movementInfo.t_seat]);
+ else
+ *data << uint32(0);
+
+ }
}
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
@@ -1151,35 +1174,68 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData)
WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2);
data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
data.appendPackGUID(guid);
- data << (uint32) GROUP_UPDATE_FLAG_STATUS;
- data << (uint16) MEMBER_STATUS_OFFLINE;
+ data << uint32(GROUP_UPDATE_FLAG_STATUS);
+ data << uint16(MEMBER_STATUS_OFFLINE);
SendPacket(&data);
return;
}
Pet* pet = player->GetPet();
+ Powers powerType = player->getPowerType();
WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
data.append(player->GetPackGUID());
- uint32 mask1 = GROUP_UPDATE_FULL;
+ uint32 updateFlags = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP
+ | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER | GROUP_UPDATE_FLAG_LEVEL
+ | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION | GROUP_UPDATE_FLAG_AURAS
+ | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID | GROUP_UPDATE_FLAG_PET_AURAS;
- if (!pet)
- mask1 &= ~GROUP_UPDATE_PET;
+ if (powerType != POWER_MANA)
+ updateFlags |= GROUP_UPDATE_FLAG_POWER_TYPE;
- Powers powerType = player->getPowerType();
- data << uint32(mask1); // group update mask
- data << uint16(MEMBER_STATUS_ONLINE); // member's online status, GROUP_UPDATE_FLAG_STATUS
- data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP
- data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP
- data << uint8 (powerType); // GROUP_UPDATE_FLAG_POWER_TYPE
- data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER
- data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER
- data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL
- data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE
- data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION
- data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION
+ if (pet)
+ updateFlags |= GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP
+ | GROUP_UPDATE_FLAG_PET_POWER_TYPE | GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER;
+
+ if (player->GetVehicle())
+ updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT;
+
+ uint16 playerStatus = MEMBER_STATUS_ONLINE;
+ if (player->IsPvP())
+ playerStatus |= MEMBER_STATUS_PVP;
+
+ if (!player->isAlive())
+ {
+ if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
+ playerStatus |= MEMBER_STATUS_GHOST;
+ else
+ playerStatus |= MEMBER_STATUS_DEAD;
+ }
+
+ if (player->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP))
+ playerStatus |= MEMBER_STATUS_PVP_FFA;
+
+ if (player->isAFK())
+ playerStatus |= MEMBER_STATUS_AFK;
+
+ if (player->isDND())
+ playerStatus |= MEMBER_STATUS_DND;
+
+ data << uint32(updateFlags);
+ data << uint16(playerStatus); // GROUP_UPDATE_FLAG_STATUS
+ data << uint32(player->GetHealth()); // GROUP_UPDATE_FLAG_CUR_HP
+ data << uint32(player->GetMaxHealth()); // GROUP_UPDATE_FLAG_MAX_HP
+ if (updateFlags & GROUP_UPDATE_FLAG_POWER_TYPE)
+ data << uint8(powerType);
+
+ data << uint16(player->GetPower(powerType)); // GROUP_UPDATE_FLAG_CUR_POWER
+ data << uint16(player->GetMaxPower(powerType)); // GROUP_UPDATE_FLAG_MAX_POWER
+ data << uint16(player->getLevel()); // GROUP_UPDATE_FLAG_LEVEL
+ data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE
+ data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION
+ data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION
data << uint16(player->GetPositionZ()); // GROUP_UPDATE_FLAG_POSITION
// GROUP_UPDATE_FLAG_AURAS
@@ -1188,6 +1244,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData)
size_t maskPos = data.wpos();
data << uint64(auramask); // placeholder
data << uint32(MAX_AURAS); // count
+
for (uint8 i = 0; i < MAX_AURAS; ++i)
{
if (AuraApplication const* aurApp = player->GetVisibleAura(i))
@@ -1211,24 +1268,39 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData)
}
data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS
+ if (updateFlags & GROUP_UPDATE_FLAG_PET_GUID)
+ data << uint64(pet->GetGUID());
+
+ data << std::string(pet ? pet->GetName() : ""); // GROUP_UPDATE_FLAG_PET_NAME
+ data << uint16(pet ? pet->GetDisplayId() : 0); // GROUP_UPDATE_FLAG_PET_MODEL_ID
+
+ if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_HP)
+ data << uint32(pet->GetHealth());
+
+ if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_HP)
+ data << uint32(pet->GetMaxHealth());
+
+ if (updateFlags & GROUP_UPDATE_FLAG_PET_POWER_TYPE)
+ data << (uint8)pet->getPowerType();
+
+ if (updateFlags & GROUP_UPDATE_FLAG_PET_CUR_POWER)
+ data << uint16(pet->GetPower(pet->getPowerType()));
+
+ if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_POWER)
+ data << uint16(pet->GetMaxPower(pet->getPowerType()));
+
+ uint64 petAuraMask = 0;
+ maskPos = data.wpos();
+ data << uint64(petAuraMask); // placeholder
if (pet)
{
- Powers petpowertype = pet->getPowerType();
- data << uint64(pet->GetGUID()); // GROUP_UPDATE_FLAG_PET_GUID
- data << pet->GetName(); // GROUP_UPDATE_FLAG_PET_NAME
- data << uint16(pet->GetDisplayId()); // GROUP_UPDATE_FLAG_PET_MODEL_ID
- data << uint32(pet->GetHealth()); // GROUP_UPDATE_FLAG_PET_CUR_HP
- data << uint32(pet->GetMaxHealth()); // GROUP_UPDATE_FLAG_PET_MAX_HP
- data << uint8 (petpowertype); // GROUP_UPDATE_FLAG_PET_POWER_TYPE
- data << uint16(pet->GetPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_CUR_POWER
- data << uint16(pet->GetMaxPower(petpowertype)); // GROUP_UPDATE_FLAG_PET_MAX_POWER
-
// GROUP_UPDATE_FLAG_PET_AURAS
data << uint8(1);
uint64 petauramask = 0;
size_t petMaskPos = data.wpos();
data << uint64(petauramask); // placeholder
data << uint32(MAX_AURAS); // count
+
for (uint8 i = 0; i < MAX_AURAS; ++i)
{
if (AuraApplication const* aurApp = pet->GetVisibleAura(i))
@@ -1260,6 +1332,11 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData)
data << uint32(0); // count
// for (count) *data << uint16(phaseId)
+ data.put<uint64>(maskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS
+
+ if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
+ data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.t_seat]);
+
SendPacket(&data);
}
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 45d4b0198e6..af7d853bfc6 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -1451,7 +1451,7 @@ void WorldSession::HandleFarSightOpcode(WorldPacket& recvData)
if (WorldObject* target = _player->GetViewpoint())
_player->SetSeer(target);
else
- sLog->outError(LOG_FILTER_NETWORKIO, "Player %s requests non-existing seer " UI64FMTD, _player->GetName().c_str(), _player->GetUInt64Value(PLAYER_FARSIGHT));
+ sLog->outError(LOG_FILTER_NETWORKIO, "Player %s (GUID: %u) requests non-existing seer " UI64FMTD, _player->GetName().c_str(), GUID_LOPART(_player->GetGUID()), _player->GetUInt64Value(PLAYER_FARSIGHT));
}
else
{
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index 892a926d2c3..1a2e825441f 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -65,19 +65,20 @@ void WorldSession::HandleMoveWorldportAckOpcode()
GetPlayer()->m_InstanceValid = true;
Map* oldMap = GetPlayer()->GetMap();
+ Map* newMap = sMapMgr->CreateMap(loc.GetMapId(), GetPlayer());
+
if (GetPlayer()->IsInWorld())
{
- sLog->outError(LOG_FILTER_NETWORKIO, "Player (Name %s) is still in world when teleported from map %u to new map %u", GetPlayer()->GetName().c_str(), oldMap->GetId(), loc.GetMapId());
+ sLog->outError(LOG_FILTER_NETWORKIO, "Player %s (GUID: %u) is still in world when teleported from map %s (%u) to new map %s (%u)", GetPlayer()->GetName().c_str(), GUID_LOPART(GetPlayer()->GetGUID()), oldMap->GetMapName(), oldMap->GetId(), newMap ? newMap->GetMapName() : "Unknown", loc.GetMapId());
oldMap->RemovePlayerFromMap(GetPlayer(), false);
}
// relocate the player to the teleport destination
- Map* newMap = sMapMgr->CreateMap(loc.GetMapId(), GetPlayer());
// the CanEnter checks are done in TeleporTo but conditions may change
// while the player is in transit, for example the map may get full
if (!newMap || !newMap->CanEnter(GetPlayer()))
{
- sLog->outError(LOG_FILTER_NETWORKIO, "Map %d could not be created for player %d, porting player to homebind", loc.GetMapId(), GetPlayer()->GetGUIDLow());
+ sLog->outError(LOG_FILTER_NETWORKIO, "Map %d (%s) could not be created for player %d (%s), porting player to homebind", loc.GetMapId(), newMap ? newMap->GetMapName() : "Unknown", GetPlayer()->GetGUIDLow(), GetPlayer()->GetName().c_str());
GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation());
return;
}
@@ -90,8 +91,8 @@ void WorldSession::HandleMoveWorldportAckOpcode()
GetPlayer()->SendInitialPacketsBeforeAddToMap();
if (!GetPlayer()->GetMap()->AddPlayerToMap(GetPlayer()))
{
- sLog->outError(LOG_FILTER_NETWORKIO, "WORLD: failed to teleport player %s (%d) to map %d because of unknown reason!",
- GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow(), loc.GetMapId());
+ sLog->outError(LOG_FILTER_NETWORKIO, "WORLD: failed to teleport player %s (%d) to map %d (%s) because of unknown reason!",
+ GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow(), loc.GetMapId(), newMap ? newMap->GetMapName() : "Unknown");
GetPlayer()->ResetMap();
GetPlayer()->SetMap(oldMap);
GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation());
diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp
index 76185dcd6cd..8e6fe56150a 100644
--- a/src/server/game/Handlers/PetHandler.cpp
+++ b/src/server/game/Handlers/PetHandler.cpp
@@ -79,13 +79,13 @@ void WorldSession::HandlePetAction(WorldPacket& recvData)
if (!pet)
{
- sLog->outError(LOG_FILTER_NETWORKIO, "HandlePetAction: Pet (GUID: %u) doesn't exist for player '%s'", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName().c_str());
+ sLog->outError(LOG_FILTER_NETWORKIO, "HandlePetAction: Pet (GUID: %u) doesn't exist for player %s (GUID: %u)", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName().c_str(), GUID_LOPART(GetPlayer()->GetGUID()));
return;
}
if (pet != GetPlayer()->GetFirstControlled())
{
- sLog->outError(LOG_FILTER_NETWORKIO, "HandlePetAction: Pet (GUID: %u) does not belong to player '%s'", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName().c_str());
+ sLog->outError(LOG_FILTER_NETWORKIO, "HandlePetAction: Pet (GUID: %u) does not belong to player %s (GUID: %u)", uint32(GUID_LOPART(guid1)), GetPlayer()->GetName().c_str(), GUID_LOPART(GetPlayer()->GetGUID()));
return;
}
@@ -724,7 +724,7 @@ void WorldSession::HandlePetSpellAutocastOpcode(WorldPacket& recvPacket)
if (!pet || (pet != _player->GetGuardianPet() && pet != _player->GetCharm()))
{
- sLog->outError(LOG_FILTER_NETWORKIO, "HandlePetSpellAutocastOpcode.Pet %u isn't pet of player %s .", uint32(GUID_LOPART(guid)), GetPlayer()->GetName().c_str());
+ sLog->outError(LOG_FILTER_NETWORKIO, "HandlePetSpellAutocastOpcode.Pet %u isn't pet of player %s (GUID: %u).", uint32(GUID_LOPART(guid)), GetPlayer()->GetName().c_str(), GUID_LOPART(GetPlayer()->GetGUID()));
return;
}
@@ -769,7 +769,7 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
if (!caster || (caster != _player->GetGuardianPet() && caster != _player->GetCharm()))
{
- sLog->outError(LOG_FILTER_NETWORKIO, "HandlePetCastSpellOpcode: Pet %u isn't pet of player %s .", uint32(GUID_LOPART(guid)), GetPlayer()->GetName().c_str());
+ sLog->outError(LOG_FILTER_NETWORKIO, "HandlePetCastSpellOpcode: Pet %u isn't pet of player %s (GUID: %u).", uint32(GUID_LOPART(guid)), GetPlayer()->GetName().c_str(), GUID_LOPART(GetPlayer()->GetGUID()));
return;
}
diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp
index 2da2735a3f9..7b35462e7a2 100644
--- a/src/server/game/Handlers/TicketHandler.cpp
+++ b/src/server/game/Handlers/TicketHandler.cpp
@@ -41,10 +41,15 @@ void WorldSession::HandleGMTicketCreateOpcode(WorldPacket& recvData)
}
GMTicketResponse response = GMTICKET_RESPONSE_CREATE_ERROR;
+ GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID());
+
+ if (ticket && ticket->IsCompleted())
+ sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());;
+
// Player must not have ticket
- if (!sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID()))
+ if (!ticket || ticket->IsClosed())
{
- GmTicket* ticket = new GmTicket(GetPlayer(), recvData);
+ ticket = new GmTicket(GetPlayer(), recvData);
uint32 count;
std::list<uint32> times;
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index b73d6fd3c66..30316306882 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -2421,7 +2421,7 @@ bool InstanceMap::AddPlayerToMap(Player* player)
// cannot enter other instances if bound permanently
if (playerBind->save != mapSave)
{
- sLog->outError(LOG_FILTER_MAPS, "InstanceMap::Add: player %s(%d) is permanently bound to instance %d, %d, %d, %d, %d, %d but he is being put into instance %d, %d, %d, %d, %d, %d", player->GetName().c_str(), player->GetGUIDLow(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset());
+ sLog->outError(LOG_FILTER_MAPS, "InstanceMap::Add: player %s(%d) is permanently bound to instance %s %d, %d, %d, %d, %d, %d but he is being put into instance %s %d, %d, %d, %d, %d, %d", player->GetName().c_str(), player->GetGUIDLow(), GetMapName(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset(), GetMapName(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset());
return false;
}
}
@@ -2433,9 +2433,9 @@ bool InstanceMap::AddPlayerToMap(Player* player)
InstanceGroupBind* groupBind = group->GetBoundInstance(this);
if (playerBind && playerBind->save != mapSave)
{
- sLog->outError(LOG_FILTER_MAPS, "InstanceMap::Add: player %s(%d) is being put into instance %d, %d, %d, %d, %d, %d but he is in group %d and is bound to instance %d, %d, %d, %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), GUID_LOPART(group->GetLeaderGUID()), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset());
+ sLog->outError(LOG_FILTER_MAPS, "InstanceMap::Add: player %s(%d) is being put into instance %s %d, %d, %d, %d, %d, %d but he is in group %d and is bound to instance %d, %d, %d, %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), GetMapName(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), GUID_LOPART(group->GetLeaderGUID()), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset());
if (groupBind)
- sLog->outError(LOG_FILTER_MAPS, "InstanceMap::Add: the group is bound to the instance %d, %d, %d, %d, %d, %d", groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(), groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset());
+ sLog->outError(LOG_FILTER_MAPS, "InstanceMap::Add: the group is bound to the instance %s %d, %d, %d, %d, %d, %d", GetMapName(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(), groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset());
//ASSERT(false);
return false;
}
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index ca48fc8730d..62a0841405c 100644
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -119,7 +119,10 @@ enum TrinityStrings
LANG_RBAC_LIST_GROUPS_HEADER = 93,
LANG_RBAC_LIST_ROLES_HEADER = 94,
LANG_RBAC_LIST_PERMISSIONS_HEADER = 95,
- // Room for more level 0 96-99 not used
+ LANG_GUILD_RENAME_ALREADY_EXISTS = 96,
+ LANG_GUILD_RENAME_DONE = 97,
+ LANG_RENAME_PLAYER_ALREADY_EXISTS = 98,
+ LANG_RENAME_PLAYER_WITH_NEW_NAME = 99,
// level 1 chat
LANG_GLOBAL_NOTIFY = 100,
@@ -196,7 +199,7 @@ enum TrinityStrings
LANG_COMMAND_TELE_NOTFOUND = 164,
LANG_COMMAND_TELE_PARAMETER = 165,
LANG_COMMAND_TELE_NOLOCATION = 166,
- // 167 // not used
+ LANG_RESERVED_NAME = 167,
LANG_COMMAND_TELE_LOCATION = 168,
LANG_MAIL_SENT = 169,
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index 8e045b98dbb..a7148055376 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -426,7 +426,7 @@ void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id,
void MotionMaster::MoveCharge(PathGenerator const& path)
{
- Vector3 dest = path.GetActualEndPosition();
+ G3D::Vector3 dest = path.GetActualEndPosition();
MoveCharge(dest.x, dest.y, dest.z, SPEED_CHARGE, EVENT_CHARGE_PREPATH);
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index 07e33f353c7..046f24e67b2 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -28,9 +28,10 @@
////////////////// PathGenerator //////////////////
PathGenerator::PathGenerator(const Unit* owner) :
- _polyLength(0), _type(PATHFIND_BLANK),
- _useStraightPath(false), _forceDestination(false), _pointPathLimit(MAX_POINT_PATH_LENGTH),
- _endPosition(Vector3::zero()), _sourceUnit(owner), _navMesh(NULL), _navMeshQuery(NULL)
+ _polyLength(0), _type(PATHFIND_BLANK), _useStraightPath(false),
+ _forceDestination(false), _pointPathLimit(MAX_POINT_PATH_LENGTH),
+ _endPosition(G3D::Vector3::zero()), _sourceUnit(owner), _navMesh(NULL),
+ _navMeshQuery(NULL)
{
sLog->outDebug(LOG_FILTER_MAPS, "++ PathGenerator::PathGenerator for %u \n", _sourceUnit->GetGUIDLow());
@@ -58,10 +59,10 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo
if (!Trinity::IsValidMapCoord(destX, destY, destZ) || !Trinity::IsValidMapCoord(x, y, z))
return false;
- Vector3 dest(destX, destY, destZ);
+ G3D::Vector3 dest(destX, destY, destZ);
SetEndPosition(dest);
- Vector3 start(x, y, z);
+ G3D::Vector3 start(x, y, z);
SetStartPosition(start);
_forceDestination = forceDest;
@@ -151,7 +152,7 @@ dtPolyRef PathGenerator::GetPolyByLocation(float const* point, float* distance)
return INVALID_POLYREF;
}
-void PathGenerator::BuildPolyPath(Vector3 const& startPos, Vector3 const& endPos)
+void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos)
{
// *** getting start/end poly logic ***
@@ -202,7 +203,7 @@ void PathGenerator::BuildPolyPath(Vector3 const& startPos, Vector3 const& endPos
{
Creature* owner = (Creature*)_sourceUnit;
- Vector3 p = (distToStartPoly > 7.0f) ? startPos : endPos;
+ G3D::Vector3 const& p = (distToStartPoly > 7.0f) ? startPos : endPos;
if (_sourceUnit->GetBaseMap()->IsUnderWater(p.x, p.y, p.z))
{
sLog->outDebug(LOG_FILTER_MAPS, "++ BuildPolyPath :: underWater case\n");
@@ -230,7 +231,7 @@ void PathGenerator::BuildPolyPath(Vector3 const& startPos, Vector3 const& endPos
if (DT_SUCCESS == _navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint))
{
dtVcopy(endPoint, closestPoint);
- SetActualEndPosition(Vector3(endPoint[2], endPoint[0], endPoint[1]));
+ SetActualEndPosition(G3D::Vector3(endPoint[2], endPoint[0], endPoint[1]));
}
_type = PATHFIND_INCOMPLETE;
@@ -449,7 +450,7 @@ void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoin
_pathPoints.resize(pointCount);
for (uint32 i = 0; i < pointCount; ++i)
- _pathPoints[i] = Vector3(pathPoints[i*VERTEX_SIZE+2], pathPoints[i*VERTEX_SIZE], pathPoints[i*VERTEX_SIZE+1]);
+ _pathPoints[i] = G3D::Vector3(pathPoints[i*VERTEX_SIZE+2], pathPoints[i*VERTEX_SIZE], pathPoints[i*VERTEX_SIZE+1]);
NormalizePath();
@@ -563,7 +564,7 @@ NavTerrain PathGenerator::GetNavTerrain(float x, float y, float z)
}
}
-bool PathGenerator::HaveTile(const Vector3& p) const
+bool PathGenerator::HaveTile(const G3D::Vector3& p) const
{
int tx = -1, ty = -1;
float point[VERTEX_SIZE] = {p.y, p.z, p.x};
@@ -791,13 +792,13 @@ bool PathGenerator::InRangeYZX(const float* v1, const float* v2, float r, float
return (dx * dx + dz * dz) < r * r && fabsf(dy) < h;
}
-bool PathGenerator::InRange(Vector3 const& p1, Vector3 const& p2, float r, float h) const
+bool PathGenerator::InRange(G3D::Vector3 const& p1, G3D::Vector3 const& p2, float r, float h) const
{
- Vector3 d = p1 - p2;
+ G3D::Vector3 d = p1 - p2;
return (d.x * d.x + d.y * d.y) < r * r && fabsf(d.z) < h;
}
-float PathGenerator::Dist3DSqr(Vector3 const& p1, Vector3 const& p2) const
+float PathGenerator::Dist3DSqr(G3D::Vector3 const& p1, G3D::Vector3 const& p2) const
{
return (p1 - p2).squaredLength();
}
diff --git a/src/server/game/Movement/PathGenerator.h b/src/server/game/Movement/PathGenerator.h
index d41d3160db5..ac66b7cec57 100644
--- a/src/server/game/Movement/PathGenerator.h
+++ b/src/server/game/Movement/PathGenerator.h
@@ -24,9 +24,6 @@
#include "DetourNavMeshQuery.h"
#include "MoveSplineInitArgs.h"
-using Movement::Vector3;
-using Movement::PointsArray;
-
class Unit;
// 74*4.0f=296y number_of_points*interval = max_path_len
@@ -63,42 +60,43 @@ class PathGenerator
bool CalculatePath(float destX, float destY, float destZ, bool forceDest = false);
// option setters - use optional
- void SetUseStraightPath(bool useStraightPath) { _useStraightPath = useStraightPath; };
- void SetPathLengthLimit(float distance) { _pointPathLimit = std::min<uint32>(uint32(distance/SMOOTH_PATH_STEP_SIZE), MAX_POINT_PATH_LENGTH); };
+ void SetUseStraightPath(bool useStraightPath) { _useStraightPath = useStraightPath; }
+ void SetPathLengthLimit(float distance) { _pointPathLimit = std::min<uint32>(uint32(distance/SMOOTH_PATH_STEP_SIZE), MAX_POINT_PATH_LENGTH); }
// result getters
- Vector3 const& GetStartPosition() const { return _startPosition; }
- Vector3 const& GetEndPosition() const { return _endPosition; }
- Vector3 const& GetActualEndPosition() const { return _actualEndPosition; }
+ G3D::Vector3 const& GetStartPosition() const { return _startPosition; }
+ G3D::Vector3 const& GetEndPosition() const { return _endPosition; }
+ G3D::Vector3 const& GetActualEndPosition() const { return _actualEndPosition; }
+
+ Movement::PointsArray const& GetPath() const { return _pathPoints; }
- PointsArray const& GetPath() const { return _pathPoints; }
PathType GetPathType() const { return _type; }
private:
- dtPolyRef _pathPolyRefs[MAX_PATH_LENGTH]; // array of detour polygon references
- uint32 _polyLength; // number of polygons in the path
+ dtPolyRef _pathPolyRefs[MAX_PATH_LENGTH]; // array of detour polygon references
+ uint32 _polyLength; // number of polygons in the path
- PointsArray _pathPoints; // our actual (x,y,z) path to the target
- PathType _type; // tells what kind of path this is
+ Movement::PointsArray _pathPoints; // our actual (x,y,z) path to the target
+ PathType _type; // tells what kind of path this is
- bool _useStraightPath; // type of path will be generated
- bool _forceDestination; // when set, we will always arrive at given point
- uint32 _pointPathLimit; // limit point path size; min(this, MAX_POINT_PATH_LENGTH)
+ bool _useStraightPath; // type of path will be generated
+ bool _forceDestination; // when set, we will always arrive at given point
+ uint32 _pointPathLimit; // limit point path size; min(this, MAX_POINT_PATH_LENGTH)
- Vector3 _startPosition; // {x, y, z} of current location
- Vector3 _endPosition; // {x, y, z} of the destination
- Vector3 _actualEndPosition;// {x, y, z} of the closest possible point to given destination
+ G3D::Vector3 _startPosition; // {x, y, z} of current location
+ G3D::Vector3 _endPosition; // {x, y, z} of the destination
+ G3D::Vector3 _actualEndPosition; // {x, y, z} of the closest possible point to given destination
- Unit const* const _sourceUnit; // the unit that is moving
- dtNavMesh const* _navMesh; // the nav mesh
- dtNavMeshQuery const* _navMeshQuery; // the nav mesh query used to find the path
+ Unit const* const _sourceUnit; // the unit that is moving
+ dtNavMesh const* _navMesh; // the nav mesh
+ dtNavMeshQuery const* _navMeshQuery; // the nav mesh query used to find the path
- dtQueryFilter _filter; // use single filter for all movements, update it when needed
+ dtQueryFilter _filter; // use single filter for all movements, update it when needed
- void SetStartPosition(Vector3 Point) { _startPosition = Point; }
- void SetEndPosition(Vector3 Point) { _actualEndPosition = Point; _endPosition = Point; }
- void SetActualEndPosition(Vector3 Point) { _actualEndPosition = Point; }
+ void SetStartPosition(G3D::Vector3 const& point) { _startPosition = point; }
+ void SetEndPosition(G3D::Vector3 const& point) { _actualEndPosition = point; _endPosition = point; }
+ void SetActualEndPosition(G3D::Vector3 const& point) { _actualEndPosition = point; }
void NormalizePath();
void Clear()
@@ -107,15 +105,15 @@ class PathGenerator
_pathPoints.clear();
}
- bool InRange(Vector3 const& p1, Vector3 const& p2, float r, float h) const;
- float Dist3DSqr(Vector3 const& p1, Vector3 const& p2) const;
+ bool InRange(G3D::Vector3 const& p1, G3D::Vector3 const& p2, float r, float h) const;
+ float Dist3DSqr(G3D::Vector3 const& p1, G3D::Vector3 const& p2) const;
bool InRangeYZX(float const* v1, float const* v2, float r, float h) const;
dtPolyRef GetPathPolyByPosition(dtPolyRef const* polyPath, uint32 polyPathSize, float const* Point, float* Distance = NULL) const;
dtPolyRef GetPolyByLocation(float const* Point, float* Distance) const;
- bool HaveTile(Vector3 const& p) const;
+ bool HaveTile(G3D::Vector3 const& p) const;
- void BuildPolyPath(Vector3 const& startPos, Vector3 const& endPos);
+ void BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos);
void BuildPointPath(float const* startPoint, float const* endPoint);
void BuildShortcut();
diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.cpp b/src/server/game/OutdoorPvP/OutdoorPvP.cpp
index 93bf7edc7d5..684bc43ceaa 100644
--- a/src/server/game/OutdoorPvP/OutdoorPvP.cpp
+++ b/src/server/game/OutdoorPvP/OutdoorPvP.cpp
@@ -280,10 +280,17 @@ bool OPvPCapturePoint::Update(uint32 diff)
float radius = (float)m_capturePoint->GetGOInfo()->capturePoint.radius;
for (uint32 team = 0; team < 2; ++team)
- for (PlayerSet::iterator itr = m_activePlayers[team].begin(); itr != m_activePlayers[team].end(); ++itr)
- if (Player* player = ObjectAccessor::FindPlayer(*itr))
+ {
+ for (PlayerSet::iterator itr = m_activePlayers[team].begin(); itr != m_activePlayers[team].end();)
+ {
+ uint64 playerGuid = *itr;
+ ++itr;
+
+ if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
if (!m_capturePoint->IsWithinDistInMap(player, radius) || !player->IsOutdoorPvPActive())
HandlePlayerLeave(player);
+ }
+ }
std::list<Player*> players;
Trinity::AnyPlayerInObjectRangeCheck checker(m_capturePoint, radius);
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index d904e1365be..fbfd467e7eb 100644
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -640,6 +640,7 @@ void AddScripts()
AddKalimdorScripts();
AddOutlandScripts();
AddNorthrendScripts();
+ AddEventScripts();
AddBattlegroundScripts();
AddOutdoorPvPScripts();
AddCustomScripts();
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 074e04547f6..ae4f983b154 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -861,12 +861,7 @@ void WorldSession::ReadAddonsInfo(WorldPacket &data)
SavedAddon const* savedAddon = AddonMgr::GetAddonInfo(addonName);
if (savedAddon)
{
- bool match = true;
-
if (addon.CRC != savedAddon->CRC)
- match = false;
-
- if (!match)
sLog->outInfo(LOG_FILTER_GENERAL, "ADDON: %s was known, but didn't match known CRC (0x%x)!", addon.Name.c_str(), savedAddon->CRC);
else
sLog->outInfo(LOG_FILTER_GENERAL, "ADDON: %s was known, CRC is correct (0x%x)", addon.Name.c_str(), savedAddon->CRC);
@@ -885,9 +880,6 @@ void WorldSession::ReadAddonsInfo(WorldPacket &data)
uint32 currentTime;
addonInfo >> currentTime;
sLog->outDebug(LOG_FILTER_NETWORKIO, "ADDON: CurrentTime: %u", currentTime);
-
- if (addonInfo.rpos() != addonInfo.size())
- sLog->outDebug(LOG_FILTER_NETWORKIO, "packet under-read!");
}
else
sLog->outError(LOG_FILTER_GENERAL, "Addon packet uncompress error!");
@@ -938,18 +930,23 @@ void WorldSession::SendAddonsInfo()
data << uint32(0); /// @todo Find out the meaning of this.
}
- uint8 unk3 = 0; // 0 is sent here
- data << uint8(unk3);
- if (unk3)
- {
- // String, length 256 (null terminated)
- data << uint8(0);
- }
+ data << uint8(0); // uses URL
+ //if (usesURL)
+ // data << uint8(0); // URL
}
m_addonsList.clear();
- data << uint32(0); // count for an unknown for loop
+ AddonMgr::BannedAddonList const* bannedAddons = AddonMgr::GetBannedAddons();
+ data << uint32(bannedAddons->size());
+ for (AddonMgr::BannedAddonList::const_iterator itr = bannedAddons->begin(); itr != bannedAddons->end(); ++itr)
+ {
+ data << uint32(itr->Id);
+ data.append(itr->NameMD5, sizeof(itr->NameMD5));
+ data.append(itr->VersionMD5, sizeof(itr->VersionMD5));
+ data << uint32(itr->Timestamp);
+ data << uint32(1); // IsBanned
+ }
SendPacket(&data);
}
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index f75adc19258..9882b16dcd2 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -2990,12 +2990,10 @@ void AuraEffect::HandleAuraControlVehicle(AuraApplication const* aurApp, uint8 m
return;
Unit* target = aurApp->GetTarget();
-
if (!target->IsVehicle())
return;
Unit* caster = GetCaster();
-
if (!caster || caster == target)
return;
@@ -5840,8 +5838,8 @@ void AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick(Unit* target, Unit*
{
if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster() ? caster : target)
{
- int32 basepoints0 = GetAmount();
- triggerCaster->CastCustomSpell(target, triggerSpellId, &basepoints0, 0, 0, true, 0, this);
+ int32 basepoints = GetAmount();
+ triggerCaster->CastCustomSpell(target, triggerSpellId, &basepoints, &basepoints, &basepoints, true, 0, this);
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick: Spell %u Trigger %u", GetId(), triggeredSpellInfo->Id);
}
}
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 99fbd8fbe03..b22f1ef0837 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -1524,7 +1524,7 @@ bool Aura::CanStackWith(Aura const* existingAura) const
return true;
// Dynobj auras always stack
- if (existingAura->GetType() == DYNOBJ_AURA_TYPE)
+ if (GetType() == DYNOBJ_AURA_TYPE || existingAura->GetType() == DYNOBJ_AURA_TYPE)
return true;
SpellInfo const* existingSpellInfo = existingAura->GetSpellInfo();
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index ced288d8fa7..f61ac6f8f35 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -1374,7 +1374,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
m_targets.SetDst(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
return;
case TARGET_DEST_DB:
- if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id))
+ if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
{
/// @todo fix this check
if (m_spellInfo->HasEffect(SPELL_EFFECT_TELEPORT_UNITS) || m_spellInfo->HasEffect(SPELL_EFFECT_BIND))
@@ -7405,7 +7405,7 @@ WorldObjectSpellAreaTargetCheck::WorldObjectSpellAreaTargetCheck(float range, Po
bool WorldObjectSpellAreaTargetCheck::operator()(WorldObject* target)
{
- if (!target->IsWithinDist3d(_position, _range))
+ if (!target->IsWithinDist3d(_position, _range) && !(target->ToGameObject() && target->ToGameObject()->IsInRange(_position->GetPositionX(), _position->GetPositionY(), _position->GetPositionZ(), _range)))
return false;
return WorldObjectSpellTargetCheck::operator ()(target);
}
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 0266b98ecfb..015e90da34d 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -811,7 +811,6 @@ void Spell::EffectTriggerSpell(SpellEffIndex effIndex)
// set basepoints for trigger with value effect
if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE)
{
- // maybe need to set value only when basepoints == 0?
values.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
values.AddSpellMod(SPELLVALUE_BASE_POINT1, damage);
values.AddSpellMod(SPELLVALUE_BASE_POINT2, damage);
@@ -1826,7 +1825,7 @@ void Spell::SendLoot(uint64 guid, LootType loottype)
return;
case GAMEOBJECT_TYPE_QUESTGIVER:
- player->PrepareGossipMenu(gameObjTarget, gameObjTarget->GetGOInfo()->questgiver.gossipID);
+ player->PrepareGossipMenu(gameObjTarget, gameObjTarget->GetGOInfo()->questgiver.gossipID, true);
player->SendPreparedGossip(gameObjTarget);
return;
@@ -2239,8 +2238,6 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
case SUMMON_CATEGORY_VEHICLE:
// Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
// to cast a ride vehicle spell on the summoned unit.
- float x, y, z;
- m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
summon = m_originalCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster, m_spellInfo->Id);
if (!summon || !summon->IsVehicle())
return;
@@ -3087,7 +3084,7 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
// Blood-Caked Strike - Blood-Caked Blade
if (m_spellInfo->SpellIconID == 1736)
{
- AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) * 12.5f);
+ AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) * 50.0f);
break;
}
// Heart Strike
@@ -5837,7 +5834,7 @@ void Spell::EffectBind(SpellEffIndex effIndex)
player->SetHomebind(homeLoc, areaId);
// binding
- WorldPacket data(SMSG_BINDPOINTUPDATE, (4+4+4+4+4));
+ WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
data << float(homeLoc.GetPositionX());
data << float(homeLoc.GetPositionY());
data << float(homeLoc.GetPositionZ());
@@ -5849,8 +5846,8 @@ void Spell::EffectBind(SpellEffIndex effIndex)
homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
// zone update
- data.Initialize(SMSG_PLAYERBOUND, 8+4);
- data << uint64(player->GetGUID());
+ data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
+ data << uint64(m_caster->GetGUID());
data << uint32(areaId);
player->SendDirectMessage(&data);
}
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 7a9ef241ad3..b381249cdcc 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -508,6 +508,7 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const
value = caster->ApplyEffectModifiers(_spellInfo, _effIndex, value);
// amount multiplication based on caster's level
+/* REVIEW - MERGE <<<<<<< HEAD
if (!_spellInfo->GetSpellScaling() && !basePointsPerLevel && (_spellInfo->Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION && _spellInfo->SpellLevel) &&
Effect != SPELL_EFFECT_WEAPON_PERCENT_DAMAGE &&
Effect != SPELL_EFFECT_KNOCK_BACK &&
@@ -519,6 +520,58 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const
//there are many more: slow speed, -healing pct
value *= 0.25f * exp(caster->getLevel() * (70 - _spellInfo->SpellLevel) / 1000.0f);
//value = int32(value * (int32)getLevel() / (int32)(_spellInfo->spellLevel ? _spellInfo->spellLevel : 1));
+======= */
+ if (!caster->IsControlledByPlayer() &&
+ _spellInfo->SpellLevel && _spellInfo->SpellLevel != caster->getLevel() &&
+ !basePointsPerLevel && (_spellInfo->Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION))
+ {
+ bool canEffectScale = false;
+ switch (Effect)
+ {
+ case SPELL_EFFECT_SCHOOL_DAMAGE:
+ case SPELL_EFFECT_DUMMY:
+ case SPELL_EFFECT_POWER_DRAIN:
+ case SPELL_EFFECT_HEALTH_LEECH:
+ case SPELL_EFFECT_HEAL:
+ case SPELL_EFFECT_WEAPON_DAMAGE:
+ case SPELL_EFFECT_POWER_BURN:
+ case SPELL_EFFECT_SCRIPT_EFFECT:
+ case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
+ case SPELL_EFFECT_FORCE_CAST_WITH_VALUE:
+ case SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE:
+ case SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE:
+ canEffectScale = true;
+ break;
+ default:
+ break;
+ }
+
+ switch (ApplyAuraName)
+ {
+ case SPELL_AURA_PERIODIC_DAMAGE:
+ case SPELL_AURA_DUMMY:
+ case SPELL_AURA_PERIODIC_HEAL:
+ case SPELL_AURA_DAMAGE_SHIELD:
+ case SPELL_AURA_PROC_TRIGGER_DAMAGE:
+ case SPELL_AURA_PERIODIC_LEECH:
+ case SPELL_AURA_PERIODIC_MANA_LEECH:
+ case SPELL_AURA_SCHOOL_ABSORB:
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
+ canEffectScale = true;
+ break;
+ default:
+ break;
+ }
+
+ if (canEffectScale)
+ {
+ GtNPCManaCostScalerEntry const* spellScaler = sGtNPCManaCostScalerStore.LookupEntry(_spellInfo->SpellLevel - 1);
+ GtNPCManaCostScalerEntry const* casterScaler = sGtNPCManaCostScalerStore.LookupEntry(caster->getLevel() - 1);
+ if (spellScaler && casterScaler)
+ value *= casterScaler->ratio / spellScaler->ratio;
+ }
+ }
+// REVIEW - MERGE >>>>>>> master
}
return int32(value);
@@ -2313,15 +2366,41 @@ int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) c
continue;
powerCost += (*i)->GetAmount();
}
+
// Shiv - costs 20 + weaponSpeed*10 energy (apply only to non-triggered spell with energy cost)
if (AttributesEx4 & SPELL_ATTR4_SPELL_VS_EXTEND_COST)
- powerCost += caster->GetAttackTime(OFF_ATTACK) / 100;
+ {
+ uint32 speed = 0;
+/* REVIEW - MERGE
+ if (SpellShapeshiftEntry const* ss = sSpellShapeshiftStore.LookupEntry(caster->GetShapeshiftForm()))
+ speed = ss->attackSpeed;
+ else
+*/
+ {
+ WeaponAttackType slot = BASE_ATTACK;
+ if (AttributesEx3 & SPELL_ATTR3_REQ_OFFHAND)
+ slot = OFF_ATTACK;
+
+ speed = caster->GetAttackTime(slot);
+ }
+
+ powerCost += speed / 100;
+ }
+
// Apply cost mod by spell
if (Player* modOwner = caster->GetSpellModOwner())
modOwner->ApplySpellMod(Id, SPELLMOD_COST, powerCost);
- if (Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION)
- powerCost = int32(powerCost / (1.117f * SpellLevel / caster->getLevel() -0.1327f));
+ if (!caster->IsControlledByPlayer())
+ {
+ if (Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION)
+ {
+ GtNPCManaCostScalerEntry const* spellScaler = sGtNPCManaCostScalerStore.LookupEntry(SpellLevel - 1);
+ GtNPCManaCostScalerEntry const* casterScaler = sGtNPCManaCostScalerStore.LookupEntry(caster->getLevel() - 1);
+ if (spellScaler && casterScaler)
+ powerCost *= casterScaler->ratio / spellScaler->ratio;
+ }
+ }
// PCT mod from user auras by spell school and power type
Unit::AuraEffectList const& aurasPct = caster->GetAuraEffectsByType(SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT);
@@ -2611,7 +2690,7 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
continue;
// if non-positive trigger cast targeted to positive target this main cast is non-positive
// this will place this spell auras as debuffs
- if (_IsPositiveTarget(spellTriggeredProto->Effects[i].TargetA.GetTarget(), spellTriggeredProto->Effects[i].TargetB.GetTarget()) && !spellTriggeredProto->_IsPositiveEffect(i, true))
+ if (!_IsPositiveTarget(spellTriggeredProto->Effects[i].TargetA.GetTarget(), spellTriggeredProto->Effects[i].TargetB.GetTarget()) && !spellTriggeredProto->_IsPositiveEffect(i, true))
return false;
}
}
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 9ae8e7ec8f7..7da054b4f7a 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -620,9 +620,9 @@ bool SpellMgr::IsSpellLearnToSpell(uint32 spell_id1, uint32 spell_id2) const
return false;
}
-SpellTargetPosition const* SpellMgr::GetSpellTargetPosition(uint32 spell_id) const
+SpellTargetPosition const* SpellMgr::GetSpellTargetPosition(uint32 spell_id, SpellEffIndex effIndex) const
{
- SpellTargetPositionMap::const_iterator itr = mSpellTargetPositions.find(spell_id);
+ SpellTargetPositionMap::const_iterator itr = mSpellTargetPositions.find(std::make_pair(spell_id, effIndex));
if (itr != mSpellTargetPositions.end())
return &itr->second;
return NULL;
@@ -1554,8 +1554,8 @@ void SpellMgr::LoadSpellTargetPositions()
mSpellTargetPositions.clear(); // need for reload case
- // 0 1 2 3 4 5
- QueryResult result = WorldDatabase.Query("SELECT id, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM spell_target_position");
+ // 0 1 2 3 4 5 6
+ QueryResult result = WorldDatabase.Query("SELECT id, effIndex, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM spell_target_position");
if (!result)
{
sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 spell target coordinates. DB table `spell_target_position` is empty.");
@@ -1568,25 +1568,26 @@ void SpellMgr::LoadSpellTargetPositions()
Field* fields = result->Fetch();
uint32 Spell_ID = fields[0].GetUInt32();
+ SpellEffIndex effIndex = SpellEffIndex(fields[1].GetUInt8());
SpellTargetPosition st;
- st.target_mapId = fields[1].GetUInt16();
- st.target_X = fields[2].GetFloat();
- st.target_Y = fields[3].GetFloat();
- st.target_Z = fields[4].GetFloat();
- st.target_Orientation = fields[5].GetFloat();
+ st.target_mapId = fields[2].GetUInt16();
+ st.target_X = fields[3].GetFloat();
+ st.target_Y = fields[4].GetFloat();
+ st.target_Z = fields[5].GetFloat();
+ st.target_Orientation = fields[6].GetFloat();
MapEntry const* mapEntry = sMapStore.LookupEntry(st.target_mapId);
if (!mapEntry)
{
- sLog->outError(LOG_FILTER_SQL, "Spell (ID:%u) target map (ID: %u) does not exist in `Map.dbc`.", Spell_ID, st.target_mapId);
+ sLog->outError(LOG_FILTER_SQL, "Spell (Id: %u, effIndex: %u) target map (ID: %u) does not exist in `Map.dbc`.", Spell_ID, effIndex, st.target_mapId);
continue;
}
if (st.target_X==0 && st.target_Y==0 && st.target_Z==0)
{
- sLog->outError(LOG_FILTER_SQL, "Spell (ID:%u) target coordinates not provided.", Spell_ID);
+ sLog->outError(LOG_FILTER_SQL, "Spell (Id: %u, effIndex: %u) target coordinates not provided.", Spell_ID, effIndex);
continue;
}
@@ -1597,35 +1598,18 @@ void SpellMgr::LoadSpellTargetPositions()
continue;
}
- bool found = false;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ if (spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_DEST_DB || spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DB)
{
- if (spellInfo->Effects[i].TargetA.GetTarget() == TARGET_DEST_DB || spellInfo->Effects[i].TargetB.GetTarget() == TARGET_DEST_DB)
- {
- // additional requirements
- if (spellInfo->Effects[i].Effect == SPELL_EFFECT_BIND && spellInfo->Effects[i].MiscValue)
- {
- uint32 area_id = sMapMgr->GetAreaId(st.target_mapId, st.target_X, st.target_Y, st.target_Z);
- if (area_id != uint32(spellInfo->Effects[i].MiscValue))
- {
- sLog->outError(LOG_FILTER_SQL, "Spell (Id: %u) listed in `spell_target_position` expected point to zone %u bit point to zone %u.", Spell_ID, spellInfo->Effects[i].MiscValue, area_id);
- break;
- }
- }
-
- found = true;
- break;
- }
+ std::pair<uint32, SpellEffIndex> key = std::make_pair(Spell_ID, effIndex);
+ mSpellTargetPositions[key] = st;
+ ++count;
}
- if (!found)
+ else
{
- sLog->outError(LOG_FILTER_SQL, "Spell (Id: %u) listed in `spell_target_position` does not have target TARGET_DEST_DB (17).", Spell_ID);
+ sLog->outError(LOG_FILTER_SQL, "Spell (Id: %u, effIndex: %u) listed in `spell_target_position` does not have target TARGET_DEST_DB (17).", Spell_ID, effIndex);
continue;
}
- mSpellTargetPositions[Spell_ID] = st;
- ++count;
-
} while (result->NextRow());
/*
diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h
index d63aa679381..69eedf25186 100644
--- a/src/server/game/Spells/SpellMgr.h
+++ b/src/server/game/Spells/SpellMgr.h
@@ -377,6 +377,8 @@ struct SpellTargetPosition
float target_Orientation;
};
+typedef std::map<std::pair<uint32 /*spell_id*/, SpellEffIndex /*effIndex*/>, SpellTargetPosition> SpellTargetPositionMap;
+
// Enum with EffectRadiusIndex and their actual radius
enum EffectRadiusIndex
{
@@ -439,8 +441,6 @@ enum EffectRadiusIndex
EFFECT_RADIUS_80_YARDS_2 = 65
};
-typedef UNORDERED_MAP<uint32, SpellTargetPosition> SpellTargetPositionMap;
-
// Spell pet auras
class PetAura
{
@@ -643,7 +643,7 @@ class SpellMgr
bool IsSpellLearnToSpell(uint32 spell_id1, uint32 spell_id2) const;
// Spell target coordinates
- SpellTargetPosition const* GetSpellTargetPosition(uint32 spell_id) const;
+ SpellTargetPosition const* GetSpellTargetPosition(uint32 spell_id, SpellEffIndex effIndex) const;
// Spell Groups table
SpellSpellGroupMapBounds GetSpellSpellGroupMapBounds(uint32 spell_id) const;
diff --git a/src/server/game/Tickets/TicketMgr.cpp b/src/server/game/Tickets/TicketMgr.cpp
index 55b4d3f2e22..373f123b6a0 100644
--- a/src/server/game/Tickets/TicketMgr.cpp
+++ b/src/server/game/Tickets/TicketMgr.cpp
@@ -244,7 +244,10 @@ void GmTicket::SetChatLog(std::list<uint32> time, std::string const& log)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Ticket manager
-TicketMgr::TicketMgr() : _status(true), _lastTicketId(0), _lastSurveyId(0), _openTicketCount(0), _lastChange(time(NULL)) { }
+TicketMgr::TicketMgr() : _status(true), _lastTicketId(0), _lastSurveyId(0), _openTicketCount(0),
+ _lastChange(time(NULL))
+{
+}
TicketMgr::~TicketMgr()
{
@@ -252,7 +255,10 @@ TicketMgr::~TicketMgr()
delete itr->second;
}
-void TicketMgr::Initialize() { SetStatus(sWorld->getBoolConfig(CONFIG_ALLOW_TICKETS)); }
+void TicketMgr::Initialize()
+{
+ SetStatus(sWorld->getBoolConfig(CONFIG_ALLOW_TICKETS));
+}
void TicketMgr::ResetTickets()
{
diff --git a/src/server/game/Tickets/TicketMgr.h b/src/server/game/Tickets/TicketMgr.h
index 0fe45f81360..91ef98dda23 100644
--- a/src/server/game/Tickets/TicketMgr.h
+++ b/src/server/game/Tickets/TicketMgr.h
@@ -82,7 +82,7 @@ class GmTicket
{
public:
GmTicket();
- explicit GmTicket(Player* player, WorldPacket& recvData);
+ GmTicket(Player* player, WorldPacket& recvData);
~GmTicket();
bool IsClosed() const { return _closedBy; }
@@ -119,7 +119,8 @@ public:
else if (_escalatedStatus == TICKET_UNASSIGNED)
_escalatedStatus = TICKET_ASSIGNED;
}
- void SetClosedBy(const int64& value) { _closedBy = value; }
+ void SetClosedBy(int64 value) { _closedBy = value; }
+ void SetCompleted() { _completed = true; }
void SetMessage(std::string const& message)
{
_message = message;
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 71439254647..164ce463d65 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1135,6 +1135,7 @@ void World::LoadConfigSettings(bool reload)
///- Load the CharDelete related config options
m_int_configs[CONFIG_CHARDELETE_METHOD] = ConfigMgr::GetIntDefault("CharDelete.Method", 0);
m_int_configs[CONFIG_CHARDELETE_MIN_LEVEL] = ConfigMgr::GetIntDefault("CharDelete.MinLevel", 0);
+ m_int_configs[CONFIG_CHARDELETE_HEROIC_MIN_LEVEL] = ConfigMgr::GetIntDefault("CharDelete.Heroic.MinLevel", 0);
m_int_configs[CONFIG_CHARDELETE_KEEP_DAYS] = ConfigMgr::GetIntDefault("CharDelete.KeepDays", 30);
///- Read the "Data" directory from the config file
@@ -1837,7 +1838,7 @@ void World::SetInitialWorldSettings()
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Calculate random battleground reset time...");
InitRandomBGResetTime();
- sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Calculate Guild cap reset time...");
+ sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Calculate guild limitation(s) reset time...");
InitGuildResetTime();
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Calculate next currency reset time...");
@@ -1893,12 +1894,16 @@ void World::LoadAutobroadcasts()
uint32 oldMSTime = getMSTime();
m_Autobroadcasts.clear();
+ m_AutobroadcastsWeights.clear();
- QueryResult result = WorldDatabase.Query("SELECT text FROM autobroadcast");
+ uint32 realmId = ConfigMgr::GetIntDefault("RealmID", 0);
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_AUTOBROADCAST);
+ stmt->setInt32(0, realmId);
+ PreparedQueryResult result = LoginDatabase.Query(stmt);
if (!result)
{
- sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 autobroadcasts definitions. DB table `autobroadcast` is empty!");
+ sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 autobroadcasts definitions. DB table `autobroadcast` is empty for this realm!");
return;
}
@@ -1907,9 +1912,10 @@ void World::LoadAutobroadcasts()
do
{
Field* fields = result->Fetch();
- std::string message = fields[0].GetString();
+ uint8 id = fields[0].GetUInt8();
- m_Autobroadcasts.push_back(message);
+ m_Autobroadcasts[id] = fields[2].GetString();
+ m_AutobroadcastsWeights[id] = fields[1].GetUInt8();
++count;
} while (result->NextRow());
@@ -2671,9 +2677,35 @@ void World::SendAutoBroadcast()
if (m_Autobroadcasts.empty())
return;
+ uint32 weight = 0;
+ AutobroadcastsWeightMap selectionWeights;
std::string msg;
- msg = Trinity::Containers::SelectRandomContainerElement(m_Autobroadcasts);
+ for (AutobroadcastsWeightMap::const_iterator it = m_AutobroadcastsWeights.begin(); it != m_AutobroadcastsWeights.end(); ++it)
+ {
+ if (it->second)
+ {
+ weight += it->second;
+ selectionWeights[it->first] = it->second;
+ }
+ }
+
+ if (weight)
+ {
+ uint32 selectedWeight = urand(0, weight - 1);
+ weight = 0;
+ for (AutobroadcastsWeightMap::const_iterator it = selectionWeights.begin(); it != selectionWeights.end(); ++it)
+ {
+ weight += it->second;
+ if (selectedWeight < weight)
+ {
+ msg = m_Autobroadcasts[it->first];
+ break;
+ }
+ }
+ }
+ else
+ msg = m_Autobroadcasts[urand(0, m_Autobroadcasts.size())];
uint32 abcenter = sWorld->getIntConfig(CONFIG_AUTOBROADCAST_CENTER);
@@ -3129,6 +3161,27 @@ void World::ProcessQueryCallbacks()
}
}
+/**
+* @brief Loads several pieces of information on server startup with the low GUID
+* There is no further database query necessary.
+* These are a number of methods that work into the calling function.
+*
+* @param guid Requires a lowGUID to call
+* @return Name, Gender, Race, Class and Level of player character
+* Example Usage:
+* @code
+* CharacterNameData const* nameData = sWorld->GetCharacterNameData(lowGUID);
+* if (!nameData)
+* return;
+*
+* std::string playerName = nameData->m_name;
+* uint8 playerGender = nameData->m_gender;
+* uint8 playerRace = nameData->m_race;
+* uint8 playerClass = nameData->m_class;
+* uint8 playerLevel = nameData->m_level;
+* @endcode
+**/
+
void World::LoadCharacterNameData()
{
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading character name data");
@@ -3206,7 +3259,7 @@ void World::UpdatePhaseDefinitions()
void World::ReloadRBAC()
{
- // Pasive reload, we mark the data as invalidated and next time a permission is checked it will be reloaded
+ // Passive reload, we mark the data as invalidated and next time a permission is checked it will be reloaded
sLog->outInfo(LOG_FILTER_RBAC, "World::ReloadRBAC()");
for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
if (WorldSession* session = itr->second)
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 1aa93ce5486..ca76bef435d 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -312,6 +312,7 @@ enum WorldIntConfigs
CONFIG_CHARDELETE_KEEP_DAYS,
CONFIG_CHARDELETE_METHOD,
CONFIG_CHARDELETE_MIN_LEVEL,
+ CONFIG_CHARDELETE_HEROIC_MIN_LEVEL,
CONFIG_AUTOBROADCAST_CENTER,
CONFIG_AUTOBROADCAST_INTERVAL,
CONFIG_MAX_RESULTS_LOOKUP_COMMANDS,
@@ -843,7 +844,11 @@ class World
// used versions
std::string m_DBVersion;
- std::list<std::string> m_Autobroadcasts;
+ typedef std::map<uint8, std::string> AutobroadcastsMap;
+ AutobroadcastsMap m_Autobroadcasts;
+
+ typedef std::map<uint8, uint8> AutobroadcastsWeightMap;
+ AutobroadcastsWeightMap m_AutobroadcastsWeights;
std::map<uint32, CharacterNameData> _characterNameDataMap;
void LoadCharacterNameData();
diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp
index 3953beab3da..cf2816c985e 100644
--- a/src/server/scripts/Commands/cs_account.cpp
+++ b/src/server/scripts/Commands/cs_account.cpp
@@ -42,13 +42,19 @@ public:
{ "password", SEC_CONSOLE, true, &HandleAccountSetPasswordCommand, "", NULL },
{ NULL, SEC_PLAYER, false, NULL, "", NULL }
};
+ static ChatCommand accountLockCommandTable[] =
+ {
+ { "country", SEC_PLAYER, true, &HandleAccountLockCountryCommand, "", NULL },
+ { "ip", SEC_PLAYER, true, &HandleAccountLockIpCommand, "", NULL },
+ { NULL, SEC_PLAYER, false, NULL, "", NULL },
+ };
static ChatCommand accountCommandTable[] =
{
{ "addon", SEC_MODERATOR, false, &HandleAccountAddonCommand, "", NULL },
{ "create", SEC_CONSOLE, true, &HandleAccountCreateCommand, "", NULL },
{ "delete", SEC_CONSOLE, true, &HandleAccountDeleteCommand, "", NULL },
{ "onlinelist", SEC_CONSOLE, true, &HandleAccountOnlineListCommand, "", NULL },
- { "lock", SEC_PLAYER, false, &HandleAccountLockCommand, "", NULL },
+ { "lock", SEC_PLAYER, false, NULL, "", accountLockCommandTable },
{ "set", SEC_ADMINISTRATOR, true, NULL, "", accountSetCommandTable },
{ "password", SEC_PLAYER, false, &HandleAccountPasswordCommand, "", NULL },
{ "", SEC_PLAYER, false, &HandleAccountCommand, "", NULL },
@@ -245,7 +251,57 @@ public:
return true;
}
- static bool HandleAccountLockCommand(ChatHandler* handler, char const* args)
+ static bool HandleAccountLockCountryCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ {
+ handler->SendSysMessage(LANG_USE_BOL);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+ std::string param = (char*)args;
+
+ if (!param.empty())
+ {
+ if (param == "on")
+ {
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGON_COUNTRY);
+ uint32 ip = inet_addr(handler->GetSession()->GetRemoteAddress().c_str());
+ EndianConvertReverse(ip);
+ stmt->setUInt32(0, ip);
+ PreparedQueryResult result = LoginDatabase.Query(stmt);
+ if (result)
+ {
+ Field* fields = result->Fetch();
+ std::string country = fields[0].GetString();
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_LOCK_CONTRY);
+ stmt->setString(0, country);
+ stmt->setUInt32(1, handler->GetSession()->GetAccountId());
+ LoginDatabase.Execute(stmt);
+ handler->PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED);
+ }
+ else
+ {
+ handler->PSendSysMessage("[IP2NATION] Table empty");
+ sLog->outDebug(LOG_FILTER_AUTHSERVER, "[IP2NATION] Table empty");
+ }
+ }
+ else if (param == "off")
+ {
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_LOCK_CONTRY);
+ stmt->setString(0, "00");
+ stmt->setUInt32(1, handler->GetSession()->GetAccountId());
+ LoginDatabase.Execute(stmt);
+ handler->PSendSysMessage(LANG_COMMAND_ACCLOCKUNLOCKED);
+ }
+ return true;
+ }
+ handler->SendSysMessage(LANG_USE_BOL);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ static bool HandleAccountLockIpCommand(ChatHandler* handler, char const* args)
{
if (!*args)
{
diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp
index 1ed00f32b87..727aa55597f 100644
--- a/src/server/scripts/Commands/cs_character.cpp
+++ b/src/server/scripts/Commands/cs_character.cpp
@@ -308,28 +308,121 @@ public:
if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
return false;
- if (target)
+ char const* newNameStr = strtok(NULL, " ");
+
+ if (newNameStr)
{
- // check online security
- if (handler->HasLowerSecurity(target, 0))
+ std::string playerOldName;
+ std::string newName = newNameStr;
+
+ if (target)
+ {
+ // check online security
+ if (handler->HasLowerSecurity(target, 0))
+ return false;
+
+ playerOldName = target->GetName();
+ }
+ else
+ {
+ // check offline security
+ if (handler->HasLowerSecurity(NULL, targetGuid))
+ return false;
+
+ sObjectMgr->GetPlayerNameByGUID(targetGuid, playerOldName);
+ }
+
+ if (!normalizePlayerName(newName))
+ {
+ handler->SendSysMessage(LANG_BAD_VALUE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (ObjectMgr::CheckPlayerName(newName, true) != CHAR_NAME_SUCCESS)
+ {
+ handler->SendSysMessage(LANG_BAD_VALUE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (WorldSession* session = handler->GetSession())
+ {
+ if (!session->HasPermission(RBAC_PERM_SKIP_CHECK_CHARACTER_CREATION_RESERVEDNAME) && sObjectMgr->IsReservedName(newName))
+ {
+ handler->SendSysMessage(LANG_RESERVED_NAME);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+ }
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_NAME);
+ stmt->setString(0, newName);
+ PreparedQueryResult result = CharacterDatabase.Query(stmt);
+ if (result)
+ {
+ handler->PSendSysMessage(LANG_RENAME_PLAYER_ALREADY_EXISTS, newName.c_str());
+ handler->SetSentErrorMessage(true);
return false;
+ }
+
+ // Remove declined name from db
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_DECLINED_NAME);
+ stmt->setUInt32(0, targetGuid);
+ CharacterDatabase.Execute(stmt);
+
+ if (target)
+ {
+ target->SetName(newName);
+
+ if (WorldSession* session = target->GetSession())
+ session->KickPlayer();
+ }
+ else
+ {
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_NAME_BY_GUID);
+ stmt->setString(0, newName);
+ stmt->setUInt32(1, GUID_LOPART(targetGuid));
+ CharacterDatabase.Execute(stmt);
+ }
+
+ sWorld->UpdateCharacterNameData(targetGuid, newName);
- handler->PSendSysMessage(LANG_RENAME_PLAYER, handler->GetNameLink(target).c_str());
- target->SetAtLoginFlag(AT_LOGIN_RENAME);
+ handler->PSendSysMessage(LANG_RENAME_PLAYER_WITH_NEW_NAME, playerOldName.c_str(), newName.c_str());
+
+ if (WorldSession* session = handler->GetSession())
+ {
+ if (Player* player = session->GetPlayer())
+ sLog->outCommand(session->GetAccountId(), "GM %s (Account: %u) forced rename %s to player %s (Account: %u)", player->GetName().c_str(), session->GetAccountId(), newName.c_str(), playerOldName.c_str(), sObjectMgr->GetPlayerAccountIdByGUID(targetGuid));
+ }
+ else
+ sLog->outCommand(0, "CONSOLE forced rename '%s' to '%s' (GUID: %u)", playerOldName.c_str(), newName.c_str(), GUID_LOPART(targetGuid));
}
else
{
- // check offline security
- if (handler->HasLowerSecurity(NULL, targetGuid))
- return false;
+ if (target)
+ {
+ // check online security
+ if (handler->HasLowerSecurity(target, 0))
+ return false;
- std::string oldNameLink = handler->playerLink(targetName);
- handler->PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
+ handler->PSendSysMessage(LANG_RENAME_PLAYER, handler->GetNameLink(target).c_str());
+ target->SetAtLoginFlag(AT_LOGIN_RENAME);
+ }
+ else
+ {
+ // check offline security
+ if (handler->HasLowerSecurity(NULL, targetGuid))
+ return false;
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
- stmt->setUInt16(0, uint16(AT_LOGIN_RENAME));
- stmt->setUInt32(1, GUID_LOPART(targetGuid));
- CharacterDatabase.Execute(stmt);
+ std::string oldNameLink = handler->playerLink(targetName);
+ handler->PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
+ stmt->setUInt16(0, uint16(AT_LOGIN_RENAME));
+ stmt->setUInt32(1, GUID_LOPART(targetGuid));
+ CharacterDatabase.Execute(stmt);
+ }
}
return true;
diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp
index 3bdd0fbe132..414f673463f 100644
--- a/src/server/scripts/Commands/cs_gobject.cpp
+++ b/src/server/scripts/Commands/cs_gobject.cpp
@@ -592,7 +592,8 @@ public:
entry = object->GetEntry();
else
entry = atoi((char*)args);
- }
+ } else
+ entry = atoi((char*)args);
GameObjectTemplate const* gameObjectInfo = sObjectMgr->GetGameObjectTemplate(entry);
diff --git a/src/server/scripts/Commands/cs_guild.cpp b/src/server/scripts/Commands/cs_guild.cpp
index 05f4e2bde67..ffaf1360ad5 100644
--- a/src/server/scripts/Commands/cs_guild.cpp
+++ b/src/server/scripts/Commands/cs_guild.cpp
@@ -44,6 +44,7 @@ public:
{ "invite", SEC_GAMEMASTER, true, &HandleGuildInviteCommand, "", NULL },
{ "uninvite", SEC_GAMEMASTER, true, &HandleGuildUninviteCommand, "", NULL },
{ "rank", SEC_GAMEMASTER, true, &HandleGuildRankCommand, "", NULL },
+ { "rename", SEC_GAMEMASTER, true, &HandleGuildRenameCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand commandTable[] =
@@ -193,6 +194,55 @@ public:
uint8 newRank = uint8(atoi(rankStr));
return targetGuild->ChangeMemberRank(targetGuid, newRank);
}
+
+ static bool HandleGuildRenameCommand(ChatHandler* handler, char const* _args)
+ {
+ if (!*_args)
+ return false;
+
+ char *args = (char *)_args;
+
+ char const* oldGuildStr = handler->extractQuotedArg(args);
+ if (!oldGuildStr)
+ {
+ handler->SendSysMessage(LANG_BAD_VALUE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ char const* newGuildStr = handler->extractQuotedArg(strtok(NULL, ""));
+ if (!newGuildStr)
+ {
+ handler->SendSysMessage(LANG_INSERT_GUILD_NAME);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ Guild* guild = sGuildMgr->GetGuildByName(oldGuildStr);
+ if (!guild)
+ {
+ handler->PSendSysMessage(LANG_COMMAND_COULDNOTFIND, oldGuildStr);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (sGuildMgr->GetGuildByName(newGuildStr))
+ {
+ handler->PSendSysMessage(LANG_GUILD_RENAME_ALREADY_EXISTS, newGuildStr);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!guild->SetName(newGuildStr))
+ {
+ handler->SendSysMessage(LANG_BAD_VALUE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ handler->PSendSysMessage(LANG_GUILD_RENAME_DONE, oldGuildStr, newGuildStr);
+ return true;
+ }
};
void AddSC_guild_commandscript()
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 8357b0ec090..a953fe56e7e 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -1586,13 +1586,9 @@ public:
EndianConvertReverse(ip);
#endif
- PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_IP2NATION_COUNTRY);
-
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP2NATION_COUNTRY);
stmt->setUInt32(0, ip);
-
- PreparedQueryResult result2 = WorldDatabase.Query(stmt);
-
- if (result2)
+ if (PreparedQueryResult result2 = LoginDatabase.Query(stmt))
{
Field* fields2 = result2->Fetch();
lastIp.append(" (");
diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp
index 79cd0deb75e..55b6edbadbe 100644
--- a/src/server/scripts/Commands/cs_mmaps.cpp
+++ b/src/server/scripts/Commands/cs_mmaps.cpp
@@ -95,14 +95,14 @@ public:
path.SetUseStraightPath(useStraightPath);
bool result = path.CalculatePath(x, y, z);
- PointsArray const& pointPath = path.GetPath();
+ Movement::PointsArray const& pointPath = path.GetPath();
handler->PSendSysMessage("%s's path to %s:", target->GetName().c_str(), player->GetName().c_str());
handler->PSendSysMessage("Building: %s", useStraightPath ? "StraightPath" : "SmoothPath");
- handler->PSendSysMessage("Result: %s - Length: "SIZEFMTD" - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType());
+ handler->PSendSysMessage("Result: %s - Length: " SIZEFMTD " - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType());
- Vector3 start = path.GetStartPosition();
- Vector3 end = path.GetEndPosition();
- Vector3 actualEnd = path.GetActualEndPosition();
+ G3D::Vector3 const &start = path.GetStartPosition();
+ G3D::Vector3 const &end = path.GetEndPosition();
+ G3D::Vector3 const &actualEnd = path.GetActualEndPosition();
handler->PSendSysMessage("StartPosition (%.3f, %.3f, %.3f)", start.x, start.y, start.z);
handler->PSendSysMessage("EndPosition (%.3f, %.3f, %.3f)", end.x, end.y, end.z);
@@ -264,7 +264,7 @@ public:
if (!creatureList.empty())
{
- handler->PSendSysMessage("Found "SIZEFMTD" Creatures.", creatureList.size());
+ handler->PSendSysMessage("Found " SIZEFMTD " Creatures.", creatureList.size());
uint32 paths = 0;
uint32 uStartTime = getMSTime();
diff --git a/src/server/scripts/Commands/cs_ticket.cpp b/src/server/scripts/Commands/cs_ticket.cpp
index 95cbf70e1f8..0795b2ab90c 100644
--- a/src/server/scripts/Commands/cs_ticket.cpp
+++ b/src/server/scripts/Commands/cs_ticket.cpp
@@ -235,6 +235,10 @@ public:
if (player->IsInWorld())
ticket->SendResponse(player->GetSession());
+ SQLTransaction trans = SQLTransaction(NULL);
+ ticket->SetCompleted();
+ ticket->SaveToDB(trans);
+
sTicketMgr->UpdateLastChange();
return true;
}
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
index e4929eed313..020cdca8566 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
@@ -371,7 +371,7 @@ public:
creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_15);
- sCreatureTextMgr->SendChat(creature, SAY_EVENT_ATTACK, 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, player);
+ sCreatureTextMgr->SendChat(creature, SAY_DUEL, 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, player);
player->CastSpell(creature, SPELL_DUEL, false);
player->CastSpell(player, SPELL_DUEL_FLAG, true);
@@ -861,59 +861,82 @@ public:
## npc_scarlet_miner_cart
####*/
-enum Spells_SM
+enum ScarletMinerCart
{
- SPELL_CART_CHECK = 54173,
- SPELL_CART_DRAG = 52465
+ SPELL_CART_CHECK = 54173,
+ SPELL_SUMMON_CART = 52463,
+ SPELL_SUMMON_MINER = 52464,
+ SPELL_CART_DRAG = 52465,
+
+ NPC_MINER = 28841
};
class npc_scarlet_miner_cart : public CreatureScript
{
-public:
- npc_scarlet_miner_cart() : CreatureScript("npc_scarlet_miner_cart") { }
+ public:
+ npc_scarlet_miner_cart() : CreatureScript("npc_scarlet_miner_cart") { }
- CreatureAI* GetAI(Creature* creature) const
- {
- return new npc_scarlet_miner_cartAI(creature);
- }
-
- struct npc_scarlet_miner_cartAI : public PassiveAI
- {
- npc_scarlet_miner_cartAI(Creature* creature) : PassiveAI(creature), minerGUID(0)
+ struct npc_scarlet_miner_cartAI : public PassiveAI
{
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- me->SetDisplayId(me->GetCreatureTemplate()->Modelid1); // Modelid2 is a horse.
- }
+ npc_scarlet_miner_cartAI(Creature* creature) : PassiveAI(creature), _minerGUID(0), _playerGUID(0)
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ me->SetDisplayId(me->GetCreatureTemplate()->Modelid1); // Modelid2 is a horse.
+ }
- uint64 minerGUID;
+ void JustSummoned(Creature* summon)
+ {
+ if (summon->GetEntry() == NPC_MINER)
+ {
+ _minerGUID = summon->GetGUID();
+ summon->AI()->SetGUID(_playerGUID);
+ }
+ }
- void SetGUID(uint64 guid, int32 /*id*/)
- {
- minerGUID = guid;
- }
+ void SummonedCreatureDespawn(Creature* summon)
+ {
+ if (summon->GetEntry() == NPC_MINER)
+ _minerGUID = 0;
+ }
- void DoAction(int32 /*param*/)
- {
- if (Creature* miner = Unit::GetCreature(*me, minerGUID))
+ void DoAction(int32 /*param*/)
{
- me->SetWalk(false);
+ if (Creature* miner = ObjectAccessor::GetCreature(*me, _minerGUID))
+ {
+ me->SetWalk(false);
- //Not 100% correct, but movement is smooth. Sometimes miner walks faster
- //than normal, this speed is fast enough to keep up at those times.
- me->SetSpeed(MOVE_RUN, 1.25f);
+ // Not 100% correct, but movement is smooth. Sometimes miner walks faster
+ // than normal, this speed is fast enough to keep up at those times.
+ me->SetSpeed(MOVE_RUN, 1.25f);
- me->GetMotionMaster()->MoveFollow(miner, 1.0f, 0);
+ me->GetMotionMaster()->MoveFollow(miner, 1.0f, 0);
+ }
}
- }
- void PassengerBoarded(Unit* /*who*/, int8 /*seatId*/, bool apply)
+ void PassengerBoarded(Unit* who, int8 /*seatId*/, bool apply)
+ {
+ if (apply)
+ {
+ _playerGUID = who->GetGUID();
+ me->CastSpell((Unit*)NULL, SPELL_SUMMON_MINER, true);
+ }
+ else
+ {
+ _playerGUID = 0;
+ if (Creature* miner = ObjectAccessor::GetCreature(*me, _minerGUID))
+ miner->DespawnOrUnsummon();
+ }
+ }
+
+ private:
+ uint64 _minerGUID;
+ uint64 _playerGUID;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
{
- if (!apply)
- if (Creature* miner = Unit::GetCreature(*me, minerGUID))
- miner->DisappearAndDie();
+ return new npc_scarlet_miner_cartAI(creature);
}
- };
-
};
/*####
@@ -928,162 +951,130 @@ enum Says_SM
class npc_scarlet_miner : public CreatureScript
{
-public:
- npc_scarlet_miner() : CreatureScript("npc_scarlet_miner") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new npc_scarlet_minerAI(creature);
- }
+ public:
+ npc_scarlet_miner() : CreatureScript("npc_scarlet_miner") { }
- struct npc_scarlet_minerAI : public npc_escortAI
- {
- npc_scarlet_minerAI(Creature* creature) : npc_escortAI(creature)
+ struct npc_scarlet_minerAI : public npc_escortAI
{
- me->SetReactState(REACT_PASSIVE);
- }
+ npc_scarlet_minerAI(Creature* creature) : npc_escortAI(creature)
+ {
+ me->SetReactState(REACT_PASSIVE);
+ }
- uint32 IntroTimer;
- uint32 IntroPhase;
- uint64 carGUID;
+ uint32 IntroTimer;
+ uint32 IntroPhase;
+ uint64 carGUID;
- void Reset()
- {
- carGUID = 0;
- IntroTimer = 0;
- IntroPhase = 0;
- }
+ void Reset()
+ {
+ carGUID = 0;
+ IntroTimer = 0;
+ IntroPhase = 0;
+ }
- void InitWaypoint()
- {
- AddWaypoint(1, 2389.03f, -5902.74f, 109.014f, 5000);
- AddWaypoint(2, 2341.812012f, -5900.484863f, 102.619743f);
- AddWaypoint(3, 2306.561279f, -5901.738281f, 91.792419f);
- AddWaypoint(4, 2300.098389f, -5912.618652f, 86.014885f);
- AddWaypoint(5, 2294.142090f, -5927.274414f, 75.316849f);
- AddWaypoint(6, 2286.984375f, -5944.955566f, 63.714966f);
- AddWaypoint(7, 2280.001709f, -5961.186035f, 54.228283f);
- AddWaypoint(8, 2259.389648f, -5974.197754f, 42.359348f);
- AddWaypoint(9, 2242.882812f, -5984.642578f, 32.827850f);
- AddWaypoint(10, 2217.265625f, -6028.959473f, 7.675705f);
- AddWaypoint(11, 2202.595947f, -6061.325684f, 5.882018f);
- AddWaypoint(12, 2188.974609f, -6080.866699f, 3.370027f);
-
- if (urand(0, 1))
+ void IsSummonedBy(Unit* summoner)
{
- AddWaypoint(13, 2176.483887f, -6110.407227f, 1.855181f);
- AddWaypoint(14, 2172.516602f, -6146.752441f, 1.074235f);
- AddWaypoint(15, 2138.918457f, -6158.920898f, 1.342926f);
- AddWaypoint(16, 2129.866699f, -6174.107910f, 4.380779f);
- AddWaypoint(17, 2117.709473f, -6193.830078f, 13.3542f, 10000);
+ carGUID = summoner->GetGUID();
}
- else
+
+ void InitWaypoint()
{
- AddWaypoint(13, 2184.190186f, -6166.447266f, 0.968877f);
- AddWaypoint(14, 2234.265625f, -6163.741211f, 0.916021f);
- AddWaypoint(15, 2268.071777f, -6158.750977f, 1.822252f);
- AddWaypoint(16, 2270.028320f, -6176.505859f, 6.340538f);
- AddWaypoint(17, 2271.739014f, -6195.401855f, 13.3542f, 10000);
+ AddWaypoint(1, 2389.03f, -5902.74f, 109.014f, 5000);
+ AddWaypoint(2, 2341.812012f, -5900.484863f, 102.619743f);
+ AddWaypoint(3, 2306.561279f, -5901.738281f, 91.792419f);
+ AddWaypoint(4, 2300.098389f, -5912.618652f, 86.014885f);
+ AddWaypoint(5, 2294.142090f, -5927.274414f, 75.316849f);
+ AddWaypoint(6, 2286.984375f, -5944.955566f, 63.714966f);
+ AddWaypoint(7, 2280.001709f, -5961.186035f, 54.228283f);
+ AddWaypoint(8, 2259.389648f, -5974.197754f, 42.359348f);
+ AddWaypoint(9, 2242.882812f, -5984.642578f, 32.827850f);
+ AddWaypoint(10, 2217.265625f, -6028.959473f, 7.675705f);
+ AddWaypoint(11, 2202.595947f, -6061.325684f, 5.882018f);
+ AddWaypoint(12, 2188.974609f, -6080.866699f, 3.370027f);
+
+ if (urand(0, 1))
+ {
+ AddWaypoint(13, 2176.483887f, -6110.407227f, 1.855181f);
+ AddWaypoint(14, 2172.516602f, -6146.752441f, 1.074235f);
+ AddWaypoint(15, 2138.918457f, -6158.920898f, 1.342926f);
+ AddWaypoint(16, 2129.866699f, -6174.107910f, 4.380779f);
+ AddWaypoint(17, 2117.709473f, -6193.830078f, 13.3542f, 10000);
+ }
+ else
+ {
+ AddWaypoint(13, 2184.190186f, -6166.447266f, 0.968877f);
+ AddWaypoint(14, 2234.265625f, -6163.741211f, 0.916021f);
+ AddWaypoint(15, 2268.071777f, -6158.750977f, 1.822252f);
+ AddWaypoint(16, 2270.028320f, -6176.505859f, 6.340538f);
+ AddWaypoint(17, 2271.739014f, -6195.401855f, 13.3542f, 10000);
+ }
}
- }
- void InitCartQuest(Player* who)
- {
- carGUID = who->GetVehicleBase()->GetGUID();
- InitWaypoint();
- Start(false, false, who->GetGUID());
- SetDespawnAtFar(false);
- }
+ void SetGUID(uint64 guid, int32 /*id = 0*/)
+ {
+ InitWaypoint();
+ Start(false, false, guid);
+ SetDespawnAtFar(false);
+ }
- void WaypointReached(uint32 waypointId)
- {
- switch (waypointId)
+ void WaypointReached(uint32 waypointId)
{
- case 1:
- if (Unit* car = Unit::GetCreature(*me, carGUID))
- me->SetFacingToObject(car);
- Talk(SAY_SCARLET_MINER_0);
- SetRun(true);
- IntroTimer = 4000;
- IntroPhase = 1;
- break;
- case 17:
- if (Unit* car = Unit::GetCreature(*me, carGUID))
- {
- me->SetFacingToObject(car);
- car->Relocate(car->GetPositionX(), car->GetPositionY(), me->GetPositionZ() + 1);
- car->StopMoving();
- car->RemoveAura(SPELL_CART_DRAG);
- }
- Talk(SAY_SCARLET_MINER_1);
- break;
- default:
- break;
+ switch (waypointId)
+ {
+ case 1:
+ if (Unit* car = ObjectAccessor::GetCreature(*me, carGUID))
+ me->SetFacingToObject(car);
+ Talk(SAY_SCARLET_MINER_0);
+ SetRun(true);
+ IntroTimer = 4000;
+ IntroPhase = 1;
+ break;
+ case 17:
+ if (Unit* car = ObjectAccessor::GetCreature(*me, carGUID))
+ {
+ me->SetFacingToObject(car);
+ car->Relocate(car->GetPositionX(), car->GetPositionY(), me->GetPositionZ() + 1);
+ car->StopMoving();
+ car->RemoveAura(SPELL_CART_DRAG);
+ }
+ Talk(SAY_SCARLET_MINER_1);
+ break;
+ default:
+ break;
+ }
}
- }
- void UpdateAI(uint32 diff)
- {
- if (IntroPhase)
+ void UpdateAI(uint32 diff)
{
- if (IntroTimer <= diff)
+ if (IntroPhase)
{
- if (IntroPhase == 1)
+ if (IntroTimer <= diff)
{
- if (Creature* car = Unit::GetCreature(*me, carGUID))
- DoCast(car, SPELL_CART_DRAG);
- IntroTimer = 800;
- IntroPhase = 2;
+ if (IntroPhase == 1)
+ {
+ if (Creature* car = Unit::GetCreature(*me, carGUID))
+ DoCast(car, SPELL_CART_DRAG);
+ IntroTimer = 800;
+ IntroPhase = 2;
+ }
+ else
+ {
+ if (Creature* car = Unit::GetCreature(*me, carGUID))
+ car->AI()->DoAction(0);
+ IntroPhase = 0;
+ }
}
else
- {
- if (Creature* car = Unit::GetCreature(*me, carGUID))
- car->AI()->DoAction(0);
- IntroPhase = 0;
- }
- } else IntroTimer-=diff;
+ IntroTimer -= diff;
+ }
+ npc_escortAI::UpdateAI(diff);
}
- npc_escortAI::UpdateAI(diff);
- }
- };
+ };
-};
-
-/*######
-## go_inconspicuous_mine_car
-######*/
-
-enum Spells_Cart
-{
- SPELL_CART_SUMM = 52463
-};
-
-class go_inconspicuous_mine_car : public GameObjectScript
-{
-public:
- go_inconspicuous_mine_car() : GameObjectScript("go_inconspicuous_mine_car") { }
-
- bool OnGossipHello(Player* player, GameObject* /*go*/)
- {
- if (player->GetQuestStatus(12701) == QUEST_STATUS_INCOMPLETE)
+ CreatureAI* GetAI(Creature* creature) const
{
- // Hack Why Trinity Dont Support Custom Summon Location
- if (Creature* miner = player->SummonCreature(28841, 2383.869629f, -5900.312500f, 107.996086f, player->GetOrientation(), TEMPSUMMON_DEAD_DESPAWN, 1))
- {
- player->CastSpell(player, SPELL_CART_SUMM, true);
- if (Creature* car = player->GetVehicleCreatureBase())
- {
- if (car->GetEntry() == 28817)
- {
- car->AI()->SetGUID(miner->GetGUID());
- CAST_AI(npc_scarlet_miner::npc_scarlet_minerAI, miner->AI())->InitCartQuest(player);
- } else sLog->outError(LOG_FILTER_TSCR, "OnGossipHello vehicle entry is not correct.");
- } else sLog->outError(LOG_FILTER_TSCR, "OnGossipHello player is not on the vehicle.");
- } else sLog->outError(LOG_FILTER_TSCR, "OnGossipHello Scarlet Miner cant be found by script.");
+ return new npc_scarlet_minerAI(creature);
}
- return true;
- }
-
};
// npc 28912 quest 17217 boss 29001 mob 29007 go 191092
@@ -1101,5 +1092,4 @@ void AddSC_the_scarlet_enclave_c1()
new npc_scarlet_ghoul();
new npc_scarlet_miner();
new npc_scarlet_miner_cart();
- new go_inconspicuous_mine_car();
}
diff --git a/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp b/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp
index 7af7e1e78bc..156d31c804f 100644
--- a/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp
+++ b/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp
@@ -98,34 +98,32 @@ public:
npc_shadowfang_prisonerAI(Creature* creature) : npc_escortAI(creature)
{
instance = creature->GetInstanceScript();
- uiNpcEntry = creature->GetEntry();
}
InstanceScript* instance;
- uint32 uiNpcEntry;
void WaypointReached(uint32 waypointId)
{
switch (waypointId)
{
case 0:
- if (uiNpcEntry == NPC_ASH)
+ if (me->GetEntry() == NPC_ASH)
Talk(SAY_FREE_AS);
else
Talk(SAY_FREE_AD);
break;
case 10:
- if (uiNpcEntry == NPC_ASH)
+ if (me->GetEntry() == NPC_ASH)
Talk(SAY_OPEN_DOOR_AS);
else
Talk(SAY_OPEN_DOOR_AD);
break;
case 11:
- if (uiNpcEntry == NPC_ASH)
+ if (me->GetEntry() == NPC_ASH)
DoCast(me, SPELL_UNLOCK);
break;
case 12:
- if (uiNpcEntry == NPC_ASH)
+ if (me->GetEntry() == NPC_ASH)
Talk(SAY_POST_DOOR_AS);
else
Talk(SAY_POST1_DOOR_AD);
@@ -134,7 +132,7 @@ public:
instance->SetData(TYPE_FREE_NPC, DONE);
break;
case 13:
- if (uiNpcEntry != NPC_ASH)
+ if (me->GetEntry() != NPC_ASH)
Talk(SAY_POST2_DOOR_AD);
break;
}
diff --git a/src/server/scripts/Events/childrens_week.cpp b/src/server/scripts/Events/childrens_week.cpp
index 2ec5e1190c8..2ef776e4e76 100644
--- a/src/server/scripts/Events/childrens_week.cpp
+++ b/src/server/scripts/Events/childrens_week.cpp
@@ -684,7 +684,6 @@ class npc_the_etymidian : public CreatureScript
private:
uint32 timer;
int8 phase;
- uint32 GOtimer;
uint64 playerGUID;
uint64 orphanGUID;
@@ -847,7 +846,6 @@ class npc_alexstraza_the_lifebinder : public CreatureScript
uint32 timer;
uint64 playerGUID;
uint64 orphanGUID;
- uint64 alexstraszaGUID;
};
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
index 3d22bac4376..c335c90cc30 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/boss_scourgelord_tyrannus.cpp
@@ -136,9 +136,7 @@ class boss_tyrannus : public CreatureScript
void InitializeAI()
{
- if (!instance || static_cast<InstanceMap*>(me->GetMap())->GetScriptId() != sObjectMgr->GetScriptId(PoSScriptName))
- me->IsAIEnabled = false;
- else if (instance->GetBossState(DATA_TYRANNUS) != DONE)
+ if (instance->GetBossState(DATA_TYRANNUS) != DONE)
Reset();
else
me->DespawnOrUnsummon();
@@ -281,7 +279,7 @@ class boss_tyrannus : public CreatureScript
CreatureAI* GetAI(Creature* creature) const
{
- return new boss_tyrannusAI(creature);
+ return GetPitOfSaronAI<boss_tyrannusAI>(creature);
}
};
@@ -387,32 +385,32 @@ class boss_rimefang : public CreatureScript
class player_overlord_brandAI : public PlayerAI
{
public:
- player_overlord_brandAI(Player* player) : PlayerAI(player)
+ player_overlord_brandAI(Player* player) : PlayerAI(player), _tyrannus(0)
{
- tyrannus = NULL;
}
void SetGUID(uint64 guid, int32 /*type*/)
{
- tyrannus = ObjectAccessor::GetCreature(*me, guid);
- me->IsAIEnabled = tyrannus != NULL;
+ _tyrannus = guid;
}
void DamageDealt(Unit* /*victim*/, uint32& damage, DamageEffectType /*damageType*/)
{
- if (tyrannus->getVictim())
- me->CastCustomSpell(SPELL_OVERLORD_BRAND_DAMAGE, SPELLVALUE_BASE_POINT0, damage, tyrannus->getVictim(), true, NULL, NULL, tyrannus->GetGUID());
+ if (Creature* tyrannus = ObjectAccessor::GetCreature(*me, _tyrannus))
+ if (tyrannus->getVictim())
+ me->CastCustomSpell(SPELL_OVERLORD_BRAND_DAMAGE, SPELLVALUE_BASE_POINT0, damage, tyrannus->getVictim(), true, NULL, NULL, tyrannus->GetGUID());
}
void HealDone(Unit* /*target*/, uint32& addHealth)
{
- me->CastCustomSpell(SPELL_OVERLORD_BRAND_HEAL, SPELLVALUE_BASE_POINT0, int32(addHealth*5.5f), tyrannus, true, NULL, NULL, tyrannus->GetGUID());
+ if (Creature* tyrannus = ObjectAccessor::GetCreature(*me, _tyrannus))
+ me->CastCustomSpell(SPELL_OVERLORD_BRAND_HEAL, SPELLVALUE_BASE_POINT0, int32(addHealth*5.5f), tyrannus, true, NULL, NULL, tyrannus->GetGUID());
}
void UpdateAI(uint32 /*diff*/) { }
private:
- Creature* tyrannus;
+ uint64 _tyrannus;
};
class spell_tyrannus_overlord_brand : public SpellScriptLoader
@@ -424,6 +422,11 @@ class spell_tyrannus_overlord_brand : public SpellScriptLoader
{
PrepareAuraScript(spell_tyrannus_overlord_brand_AuraScript);
+ bool Load()
+ {
+ return GetCaster() && GetCaster()->GetEntry() == NPC_TYRANNUS;
+ }
+
void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetTarget()->GetTypeId() != TYPEID_PLAYER)
@@ -440,9 +443,10 @@ class spell_tyrannus_overlord_brand : public SpellScriptLoader
if (GetTarget()->GetTypeId() != TYPEID_PLAYER)
return;
- delete GetTarget()->GetAI();
- GetTarget()->SetAI(oldAI);
GetTarget()->IsAIEnabled = oldAIState;
+ UnitAI* thisAI = GetTarget()->GetAI();
+ GetTarget()->SetAI(oldAI);
+ delete thisAI;
}
void Register()
diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.h b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.h
index 94bca5ffaf7..a9b88ca3066 100644
--- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.h
+++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/pit_of_saron.h
@@ -18,6 +18,9 @@
#ifndef DEF_PIT_OF_SARON_H
#define DEF_PIT_OF_SARON_H
+#include "Map.h"
+#include "Creature.h"
+
#define PoSScriptName "instance_pit_of_saron"
#define MAX_ENCOUNTER 3
@@ -94,4 +97,14 @@ enum GameObjectIds
GO_HALLS_OF_REFLECTION_PORTCULLIS = 201848,
};
+template<class AI>
+AI* GetPitOfSaronAI(Creature* creature)
+{
+ if (InstanceMap* instance = creature->GetMap()->ToInstanceMap())
+ if (instance->GetInstanceScript())
+ if (instance->GetScriptId() == sObjectMgr->GetScriptId(PoSScriptName))
+ return new AI(creature);
+ return NULL;
+}
+
#endif
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
index 8e8fb9ba9ac..4fbfe4219d4 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
@@ -73,7 +73,6 @@ enum Spells
enum Shadowmourne
{
QUEST_BLOOD_INFUSION = 24756,
- ITEM_SHADOW_S_EDGE = 49888,
SPELL_GUSHING_WOUND = 72132,
SPELL_THIRST_QUENCHED = 72154,
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
index ea74d8ec61c..7294e4a5571 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
@@ -1131,7 +1131,8 @@ class spell_sindragosa_frost_breath : public SpellScriptLoader
if (!target)
return;
- if (target->GetQuestStatus(QUEST_FROST_INFUSION) != QUEST_STATUS_INCOMPLETE)
+ // Check difficulty and quest status
+ if (!(target->GetRaidDifficulty() & RAID_DIFFICULTY_MASK_25MAN) || target->GetQuestStatus(QUEST_FROST_INFUSION) != QUEST_STATUS_INCOMPLETE)
return;
// Check if player has Shadow's Edge equipped and not ready for infusion
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp
index 47fe7c8f80a..b558508f78a 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp
@@ -166,7 +166,7 @@ class boss_kologarn : public CreatureScript
left = apply;
if (!apply && isEncounterInProgress)
{
- who->ToCreature()->DisappearAndDie();
+ who->ToCreature()->DespawnOrUnsummon();
Talk(SAY_LEFT_ARM_GONE);
events.ScheduleEvent(EVENT_RESPAWN_LEFT_ARM, 40000);
}
@@ -177,7 +177,7 @@ class boss_kologarn : public CreatureScript
right = apply;
if (!apply && isEncounterInProgress)
{
- who->ToCreature()->DisappearAndDie();
+ who->ToCreature()->DespawnOrUnsummon();
Talk(SAY_RIGHT_ARM_GONE);
events.ScheduleEvent(EVENT_RESPAWN_RIGHT_ARM, 40000);
}
@@ -529,7 +529,7 @@ class spell_ulduar_stone_grip_absorb : public SpellScriptLoader
//! What we do here is remove all harmful aura's related and teleport to safe spot.
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
- if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL)
+ if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL)
return;
if (!GetOwner()->ToCreature())
@@ -568,22 +568,30 @@ class spell_ulduar_stone_grip : public SpellScriptLoader
owner->RemoveAurasDueToSpell(aurEff->GetAmount());
}
- void OnRemoveVehicle(AuraEffect const* /*aurEff*/, AuraEffectHandleModes mode)
+ void OnRemoveVehicle(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
- if (!(mode & AURA_EFFECT_HANDLE_REAL))
- return;
-
- if (GetOwner()->GetTypeId() != TYPEID_UNIT)
+ PreventDefaultAction();
+ Unit* caster = GetCaster();
+ if (!caster)
return;
- Player* caster = GetCaster() ? GetCaster()->ToPlayer() : NULL;
- if (!caster || !caster->IsOnVehicle(GetOwner()->ToUnit()))
- return;
+ Position exitPosition;
+ exitPosition.m_positionX = 1750.0f;
+ exitPosition.m_positionY = -7.5f + frand(-3.0f, 3.0f);
+ exitPosition.m_positionZ = 457.9322f;
+ // Remove pending passengers before exiting vehicle - might cause an Uninstall
+ GetTarget()->GetVehicleKit()->RemovePendingEventsForPassenger(caster);
+ caster->_ExitVehicle(&exitPosition);
caster->RemoveAurasDueToSpell(GetId());
- caster->ExitVehicle();
- caster->GetMotionMaster()->MoveJump(1756.25f + irand(-3, 3), -8.3f + irand(-3, 3), 448.8f, 5.0f, 5.0f);
- PreventDefaultAction();
+
+ // Temporarily relocate player to vehicle exit dest serverside to send proper fall movement
+ // beats me why blizzard sends these 2 spline packets one after another instantly
+ Position oldPos;
+ caster->GetPosition(&oldPos);
+ caster->Relocate(exitPosition);
+ caster->GetMotionMaster()->MoveFall();
+ caster->Relocate(oldPos);
}
void Register()
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
index 215630ac5fa..dfb12a03c33 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
@@ -30,13 +30,12 @@ enum Yells
{
//Yells Ingvar
YELL_AGGRO_1 = 0,
- YELL_AGGRO_2 = 1,
-
+ YELL_KILL_1 = 1,
YELL_DEAD_1 = 2,
- YELL_DEAD_2 = 3,
- YELL_KILL_1 = 4,
- YELL_KILL_2 = 5,
+ YELL_AGGRO_2 = 0,
+ YELL_KILL_2 = 1,
+ YELL_DEAD_2 = 2
};
enum Creatures
diff --git a/src/server/scripts/Northrend/zone_wintergrasp.cpp b/src/server/scripts/Northrend/zone_wintergrasp.cpp
index ce0eaefac90..1b944f9babb 100644
--- a/src/server/scripts/Northrend/zone_wintergrasp.cpp
+++ b/src/server/scripts/Northrend/zone_wintergrasp.cpp
@@ -40,7 +40,7 @@ enum WGqueuenpctext
WG_NPCQUEUE_TEXT_A_NOWAR = 14782,
WG_NPCQUEUE_TEXT_A_QUEUE = 14791,
WG_NPCQUEUE_TEXT_A_WAR = 14781,
- WG_NPCQUEUE_TEXTOPTION_JOIN = -1850507,
+ WG_NPCQUEUE_TEXTOPTION_JOIN = 20077,
};
enum Spells
diff --git a/src/server/scripts/Outland/zone_shattrath_city.cpp b/src/server/scripts/Outland/zone_shattrath_city.cpp
index 4af11191708..1fb0210bb73 100644
--- a/src/server/scripts/Outland/zone_shattrath_city.cpp
+++ b/src/server/scripts/Outland/zone_shattrath_city.cpp
@@ -19,7 +19,7 @@
/* ScriptData
SDName: Shattrath_City
SD%Complete: 100
-SDComment: Quest support: 10004, 10009, 10211, 10231. Flask vendors, Teleport to Caverns of Time
+SDComment: Quest support: 10004, 10009, 10211. Flask vendors, Teleport to Caverns of Time
SDCategory: Shattrath City
EndScriptData */
@@ -29,7 +29,6 @@ npc_salsalabim
npc_shattrathflaskvendors
npc_zephyr
npc_kservant
-npc_dirty_larry
npc_ishanah
npc_khadgar
EndContentData */
@@ -425,198 +424,6 @@ public:
};
/*######
-# npc_dirty_larry
-######*/
-
-#define GOSSIP_BOOK "Ezekiel said that you might have a certain book..."
-
-enum DirtyLarry
-{
- SAY_1 = 0,
- SAY_2 = 1,
- SAY_3 = 2,
- SAY_4 = 3,
- SAY_5 = 4,
- SAY_GIVEUP = 5,
-
- QUEST_WBI = 10231,
- NPC_CREEPJACK = 19726,
- NPC_MALONE = 19725
-};
-
-class npc_dirty_larry : public CreatureScript
-{
-public:
- npc_dirty_larry() : CreatureScript("npc_dirty_larry") { }
-
- struct npc_dirty_larryAI : public ScriptedAI
- {
- npc_dirty_larryAI(Creature* creature) : ScriptedAI(creature) {}
-
- bool Event;
- bool Attack;
- bool Done;
-
- uint64 PlayerGUID;
-
- uint32 SayTimer;
- uint32 Step;
-
- void Reset()
- {
- Event = false;
- Attack = false;
- Done = false;
-
- PlayerGUID = 0;
- SayTimer = 0;
- Step = 0;
-
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->setFaction(1194);
- if (Creature* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20))
- {
- Creepjack->AI()->EnterEvadeMode();
- Creepjack->setFaction(1194);
- Creepjack->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- }
-
- if (Creature* Malone = me->FindNearestCreature(NPC_MALONE, 20))
- {
- Malone->AI()->EnterEvadeMode();
- Malone->setFaction(1194);
- Malone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- }
- }
-
- uint32 NextStep(uint32 Step)
- {
- Player* player = Unit::GetPlayer(*me, PlayerGUID);
-
- switch (Step)
- {
- case 0:{ me->SetInFront(player);
- Unit* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20);
- if (Creepjack)
- Creepjack->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
- Unit* Malone = me->FindNearestCreature(NPC_MALONE, 20);
- if (Malone)
- Malone->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
- me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); }return 2000;
- case 1: Talk(SAY_1, player->GetGUID()); return 3000;
- case 2: Talk(SAY_2, player->GetGUID()); return 5000;
- case 3: Talk(SAY_3, player->GetGUID()); return 2000;
- case 4: Talk(SAY_4, player->GetGUID()); return 2000;
- case 5: Talk(SAY_5, player->GetGUID()); return 2000;
- case 6: Attack = true; return 2000;
- default: return 0;
- }
- }
-
- void EnterCombat(Unit* /*who*/){}
-
- void UpdateAI(uint32 diff)
- {
- if (SayTimer <= diff)
- {
- if (Event)
- SayTimer = NextStep(++Step);
- }
- else
- SayTimer -= diff;
-
- if (Attack)
- {
- me->setFaction(14);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- if (Player* player = Unit::GetPlayer(*me, PlayerGUID))
- {
- if (Creature* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20))
- {
- Creepjack->Attack(player, true);
- Creepjack->setFaction(14);
- Creepjack->GetMotionMaster()->MoveChase(player);
- Creepjack->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- }
-
- if (Creature* Malone = me->FindNearestCreature(NPC_MALONE, 20))
- {
- Malone->Attack(player, true);
- Malone->setFaction(14);
- Malone->GetMotionMaster()->MoveChase(player);
- Malone->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- }
- DoStartMovement(player);
- AttackStart(player);
- }
- Attack = false;
- }
-
- if (HealthBelowPct(5) && !Done)
- {
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->RemoveAllAuras();
-
- if (Creature* Creepjack = me->FindNearestCreature(NPC_CREEPJACK, 20))
- {
- Creepjack->AI()->EnterEvadeMode();
- Creepjack->setFaction(1194);
- Creepjack->GetMotionMaster()->MoveTargetedHome();
- Creepjack->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- }
-
- if (Creature* Malone = me->FindNearestCreature(NPC_MALONE, 20))
- {
- Malone->AI()->EnterEvadeMode();
- Malone->setFaction(1194);
- Malone->GetMotionMaster()->MoveTargetedHome();
- Malone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- }
- me->setFaction(1194);
- Done = true;
- Talk(SAY_GIVEUP);
- me->DeleteThreatList();
- me->CombatStop();
- me->GetMotionMaster()->MoveTargetedHome();
- if (Player* player = Unit::GetPlayer(*me, PlayerGUID))
- player->GroupEventHappens(QUEST_WBI, me);
- }
- DoMeleeAttackIfReady();
- }
- };
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
- {
- player->PlayerTalkClass->ClearMenus();
- if (action == GOSSIP_ACTION_INFO_DEF+1)
- {
- CAST_AI(npc_dirty_larry::npc_dirty_larryAI, creature->AI())->Event = true;
- CAST_AI(npc_dirty_larry::npc_dirty_larryAI, creature->AI())->PlayerGUID = player->GetGUID();
- player->CLOSE_GOSSIP_MENU();
- }
-
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature)
- {
- if (creature->isQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(QUEST_WBI) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BOOK, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new npc_dirty_larryAI (creature);
- }
-};
-
-/*######
# npc_ishanah
######*/
@@ -727,7 +534,6 @@ void AddSC_shattrath_city()
new npc_shattrathflaskvendors();
new npc_zephyr();
new npc_kservant();
- new npc_dirty_larry();
new npc_ishanah();
new npc_khadgar();
}
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 7d7cdb84861..a84f299167e 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -3585,6 +3585,55 @@ class spell_gen_darkflight : public SpellScriptLoader
}
};
+enum OrcDisguiseSpells
+{
+ SPELL_ORC_DISGUISE_TRIGGER = 45759,
+ SPELL_ORC_DISGUISE_MALE = 45760,
+ SPELL_ORC_DISGUISE_FEMALE = 45762,
+};
+
+class spell_gen_orc_disguise : public SpellScriptLoader
+{
+ public:
+ spell_gen_orc_disguise() : SpellScriptLoader("spell_gen_orc_disguise") { }
+
+ class spell_gen_orc_disguise_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gen_orc_disguise_SpellScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_ORC_DISGUISE_TRIGGER) || !sSpellMgr->GetSpellInfo(SPELL_ORC_DISGUISE_MALE) ||
+ !sSpellMgr->GetSpellInfo(SPELL_ORC_DISGUISE_FEMALE))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ if (Player* target = GetHitPlayer())
+ {
+ uint8 gender = target->getGender();
+ if (!gender)
+ caster->CastSpell(target, SPELL_ORC_DISGUISE_MALE, true);
+ else
+ caster->CastSpell(target, SPELL_ORC_DISGUISE_FEMALE, true);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_gen_orc_disguise_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_gen_orc_disguise_SpellScript();
+ }
+};
+
void AddSC_generic_spell_scripts()
{
new spell_gen_absorb0_hitlimit1();
@@ -3672,4 +3721,5 @@ void AddSC_generic_spell_scripts()
new spell_gen_running_wild();
new spell_gen_two_forms();
new spell_gen_darkflight();
+ new spell_gen_orc_disguise();
}
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index 811032f11c9..9704b709959 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -165,12 +165,15 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_MATCH_MAKER_RATING, "SELECT matchMakerRating FROM character_arena_stats WHERE guid = ? AND slot = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_CHARACTER_COUNT, "SELECT account, COUNT(guid) FROM characters WHERE account = ? GROUP BY account", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_NAME, "UPDATE characters set name = ?, at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_UPD_NAME_BY_GUID, "UPDATE characters SET name = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_DECLINED_NAME, "DELETE FROM character_declinedname WHERE guid = ?", CONNECTION_ASYNC);
// Guild handling
// 0: uint32, 1: string, 2: uint32, 3: string, 4: string, 5: uint64, 6-10: uint32, 11: uint64
PrepareStatement(CHAR_INS_GUILD, "INSERT INTO guild (guildid, name, leaderguid, info, motd, createdate, EmblemStyle, EmblemColor, BorderStyle, BorderColor, BackgroundColor, BankMoney) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GUILD, "DELETE FROM guild WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32
+ // 0: string, 1: uint32
+ PrepareStatement(CHAR_UPD_GUILD_NAME, "UPDATE guild SET name = ? WHERE guildid = ?", CONNECTION_ASYNC);
// 0: uint32, 1: uint32, 2: uint8, 4: string, 5: string
PrepareStatement(CHAR_INS_GUILD_MEMBER, "INSERT INTO guild_member (guildid, guid, rank, pnote, offnote) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GUILD_MEMBER, "DELETE FROM guild_member WHERE guid = ?", CONNECTION_ASYNC); // 0: uint32
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index ad146b8e98f..d9900d53f46 100755
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -161,11 +161,13 @@ enum CharacterDatabaseStatements
CHAR_SEL_MATCH_MAKER_RATING,
CHAR_SEL_CHARACTER_COUNT,
CHAR_UPD_NAME,
+ CHAR_UPD_NAME_BY_GUID,
CHAR_DEL_DECLINED_NAME,
CHAR_SEL_CHARACTER_DATA_BY_GUID,
CHAR_INS_GUILD,
CHAR_DEL_GUILD,
+ CHAR_UPD_GUILD_NAME,
CHAR_INS_GUILD_MEMBER,
CHAR_DEL_GUILD_MEMBER,
CHAR_DEL_GUILD_MEMBERS,
diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp
index a23294a038c..0118f637205 100644
--- a/src/server/shared/Database/Implementation/LoginDatabase.cpp
+++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp
@@ -37,7 +37,8 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_SEL_SESSIONKEY, "SELECT a.sessionkey, a.id, aa.gmlevel FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE username = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_UPD_VS, "UPDATE account SET v = ?, s = ? WHERE username = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_UPD_LOGONPROOF, "UPDATE account SET sessionkey = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE username = ?", CONNECTION_ASYNC);
- PrepareStatement(LOGIN_SEL_LOGONCHALLENGE, "SELECT a.sha_pass_hash, a.id, a.locked, a.last_ip, aa.gmlevel, a.v, a.s FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.username = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_SEL_LOGONCHALLENGE, "SELECT a.sha_pass_hash, a.id, a.locked, a.lock_country, a.last_ip, aa.gmlevel, a.v, a.s FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.username = ?", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_SEL_LOGON_COUNTRY, "SELECT country FROM ip2nation WHERE ip < ? ORDER BY ip DESC LIMIT 0,1", CONNECTION_SYNCH);
PrepareStatement(LOGIN_UPD_FAILEDLOGINS, "UPDATE account SET failed_logins = failed_logins + 1 WHERE username = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_SEL_FAILEDLOGINS, "SELECT id, failed_logins FROM account WHERE username = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_ACCOUNT_ID_BY_NAME, "SELECT id FROM account WHERE username = ?", CONNECTION_SYNCH);
@@ -59,6 +60,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_INS_REALM_CHARACTERS_INIT, "INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist, account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL", CONNECTION_ASYNC);
PrepareStatement(LOGIN_UPD_EXPANSION, "UPDATE account SET expansion = ? WHERE id = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_UPD_ACCOUNT_LOCK, "UPDATE account SET locked = ? WHERE id = ?", CONNECTION_ASYNC);
+ PrepareStatement(LOGIN_UPD_ACCOUNT_LOCK_CONTRY, "UPDATE account SET lock_country = ? WHERE id = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_INS_LOG, "INSERT INTO logs (time, realm, type, level, string) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(LOGIN_UPD_USERNAME, "UPDATE account SET v = 0, s = 0, username = ?, sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_UPD_PASSWORD, "UPDATE account SET v = 0, s = 0, sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC);
@@ -88,6 +90,8 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_SEL_ACCOUNT_WHOIS, "SELECT username, email, last_ip FROM account WHERE id = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_REALMLIST_SECURITY_LEVEL, "SELECT allowedSecurityLevel from realmlist WHERE id = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_DEL_ACCOUNT, "DELETE FROM account WHERE id = ?", CONNECTION_ASYNC);
+ PrepareStatement(LOGIN_SEL_IP2NATION_COUNTRY, "SELECT c.country FROM ip2nationCountries c, ip2nation i WHERE i.ip < ? AND c.code = i.country ORDER BY i.ip DESC LIMIT 0,1", CONNECTION_SYNCH);
+ PrepareStatement(LOGIN_SEL_AUTOBROADCAST, "SELECT id, weight, text FROM autobroadcast WHERE realmid = ? OR realmid = -1", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_ACCOUNT_ACCESS_BY_ID, "SELECT gmlevel, RealmID FROM account_access WHERE id = ? and (RealmID = ? OR RealmID = -1) ORDER BY gmlevel desc", CONNECTION_SYNCH);
diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h
index 939cc4b4790..97cf91fc178 100644
--- a/src/server/shared/Database/Implementation/LoginDatabase.h
+++ b/src/server/shared/Database/Implementation/LoginDatabase.h
@@ -56,6 +56,7 @@ enum LoginDatabaseStatements
LOGIN_UPD_VS,
LOGIN_UPD_LOGONPROOF,
LOGIN_SEL_LOGONCHALLENGE,
+ LOGIN_SEL_LOGON_COUNTRY,
LOGIN_UPD_FAILEDLOGINS,
LOGIN_SEL_FAILEDLOGINS,
LOGIN_SEL_ACCOUNT_ID_BY_NAME,
@@ -79,6 +80,7 @@ enum LoginDatabaseStatements
LOGIN_INS_REALM_CHARACTERS_INIT,
LOGIN_UPD_EXPANSION,
LOGIN_UPD_ACCOUNT_LOCK,
+ LOGIN_UPD_ACCOUNT_LOCK_CONTRY,
LOGIN_INS_LOG,
LOGIN_UPD_USERNAME,
LOGIN_UPD_PASSWORD,
@@ -108,6 +110,8 @@ enum LoginDatabaseStatements
LOGIN_SEL_ACCOUNT_WHOIS,
LOGIN_SEL_REALMLIST_SECURITY_LEVEL,
LOGIN_DEL_ACCOUNT,
+ LOGIN_SEL_IP2NATION_COUNTRY,
+ LOGIN_SEL_AUTOBROADCAST,
LOGIN_SEL_ACCOUNT_ACCESS_BY_ID,
LOGIN_SEL_RBAC_ACCOUNT_GROUPS,
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp
index 94c01dd6569..c6e520cfdde 100644
--- a/src/server/shared/Database/Implementation/WorldDatabase.cpp
+++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp
@@ -80,7 +80,6 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_SEL_COMMANDS, "SELECT name, security, help FROM command", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Mana_mod_extra, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?", CONNECTION_SYNCH);
- PrepareStatement(WORLD_SEL_IP2NATION_COUNTRY, "SELECT c.country FROM ip2nationCountries c, ip2nation i WHERE i.ip < ? AND c.code = i.country ORDER BY i.ip DESC LIMIT 0,1", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_ITEM_TEMPLATE_BY_NAME, "SELECT entry FROM item_template WHERE name = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_GAMEOBJECT_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM gameobject WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_", CONNECTION_SYNCH);
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.h b/src/server/shared/Database/Implementation/WorldDatabase.h
index 032baf29dd9..d8c3c69dbba 100644
--- a/src/server/shared/Database/Implementation/WorldDatabase.h
+++ b/src/server/shared/Database/Implementation/WorldDatabase.h
@@ -100,7 +100,6 @@ enum WorldDatabaseStatements
WORLD_SEL_COMMANDS,
WORLD_SEL_CREATURE_TEMPLATE,
WORLD_SEL_WAYPOINT_SCRIPT_BY_ID,
- WORLD_SEL_IP2NATION_COUNTRY,
WORLD_SEL_ITEM_TEMPLATE_BY_NAME,
WORLD_SEL_CREATURE_BY_ID,
WORLD_SEL_GAMEOBJECT_NEAREST,
diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt
index 840ae6ad0b6..1f9231ac0b8 100644
--- a/src/server/worldserver/CMakeLists.txt
+++ b/src/server/worldserver/CMakeLists.txt
@@ -196,7 +196,7 @@ endif()
if( UNIX )
install(TARGETS worldserver DESTINATION bin)
- install(FILES worldserver.conf.dist DESTINATION etc)
+ install(FILES worldserver.conf.dist DESTINATION ${CONF_DIR})
elseif( WIN32 )
install(TARGETS worldserver DESTINATION "${CMAKE_INSTALL_PREFIX}")
install(FILES worldserver.conf.dist DESTINATION "${CMAKE_INSTALL_PREFIX}")
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 448ea2930e3..622070c121d 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -2340,13 +2340,21 @@ CharDelete.Method = 0
#
# CharDelete.MinLevel
-# Description: Required level to use the unlinking method if enabled.
+# Description: Required level to use the unlinking method if enabled for non-heroic classes.
# Default: 0 - (Same method for every level)
# 1+ - (Only characters with the specified level will use the unlinking method)
CharDelete.MinLevel = 0
#
+# CharDelete.Heroic.MinLevel
+# Description: Required level to use the unlinking method if enabled for heroic classes.
+# Default: 0 - (Same method for every level)
+# 1+ - (Only characters with the specified level will use the unlinking method)
+
+CharDelete.Heroic.MinLevel = 0
+
+#
# CharDelete.KeepDays
# Description: Time (in days) before unlinked characters will be removed from the database.
# Default: 30 - (Enabled)