aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/Collision/Management/MMapManager.cpp2
-rw-r--r--src/common/Common.h1
-rw-r--r--src/common/Debugging/Errors.cpp19
-rw-r--r--src/common/Debugging/Errors.h4
-rw-r--r--src/common/Utilities/Util.h2
-rw-r--r--src/server/authserver/Realms/RealmList.cpp2
-rw-r--r--src/server/authserver/authserver.conf.dist2
-rw-r--r--src/server/database/Database/DatabaseWorkerPool.h2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp9
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h3
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp2
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp12
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp4
-rw-r--r--src/server/game/Chat/Chat.cpp28
-rw-r--r--src/server/game/Chat/Chat.h4
-rw-r--r--src/server/game/DataStores/DBCStores.cpp2
-rw-r--r--src/server/game/DataStores/DBCStructure.h15
-rw-r--r--src/server/game/DungeonFinding/LFGQueue.cpp48
-rw-r--r--src/server/game/DungeonFinding/LFGQueue.h2
-rw-r--r--src/server/game/Entities/Creature/CreatureGroups.cpp7
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp32
-rw-r--r--src/server/game/Entities/Creature/TemporarySummon.cpp2
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h2
-rw-r--r--src/server/game/Entities/Item/Item.cpp2
-rw-r--r--src/server/game/Entities/Object/Object.cpp8
-rw-r--r--src/server/game/Entities/Pet/Pet.h4
-rw-r--r--src/server/game/Entities/Player/Player.cpp74
-rw-r--r--src/server/game/Entities/Player/Player.h2
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp18
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp146
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp2
-rw-r--r--src/server/game/Handlers/TaxiHandler.cpp64
-rw-r--r--src/server/game/Maps/Map.cpp10
-rw-r--r--src/server/game/Maps/MapInstanced.cpp6
-rw-r--r--src/server/game/Maps/TransportMgr.cpp8
-rw-r--r--src/server/game/Maps/TransportMgr.h2
-rw-r--r--src/server/game/Movement/MotionMaster.cpp3
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp109
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h38
-rw-r--r--src/server/game/Movement/Spline/Spline.h2
-rw-r--r--src/server/game/Movement/Waypoints/Path.h100
-rw-r--r--src/server/game/Quests/QuestDef.cpp49
-rw-r--r--src/server/game/Quests/QuestDef.h66
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp4
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp8
-rw-r--r--src/server/game/Spells/Spell.cpp4
-rw-r--r--src/server/scripts/Commands/cs_lfg.cpp2
-rw-r--r--src/server/scripts/Commands/cs_ticket.cpp27
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp74
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp80
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp164
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp4
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp14
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h23
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp42
-rw-r--r--src/server/scripts/World/npcs_special.cpp67
-rw-r--r--src/server/worldserver/Main.cpp2
57 files changed, 784 insertions, 650 deletions
diff --git a/src/common/Collision/Management/MMapManager.cpp b/src/common/Collision/Management/MMapManager.cpp
index a5685c65d9c..00985e4fa1d 100644
--- a/src/common/Collision/Management/MMapManager.cpp
+++ b/src/common/Collision/Management/MMapManager.cpp
@@ -230,7 +230,7 @@ namespace MMAP
// if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used
// we cannot recover from this error - assert out
TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, x, y);
- ASSERT(false);
+ ABORT();
}
else
{
diff --git a/src/common/Common.h b/src/common/Common.h
index 09d64acc795..4c209f89ec8 100644
--- a/src/common/Common.h
+++ b/src/common/Common.h
@@ -39,6 +39,7 @@
#include <sstream>
#include <algorithm>
#include <memory>
+#include <vector>
#include "Debugging/Errors.h"
diff --git a/src/common/Debugging/Errors.cpp b/src/common/Debugging/Errors.cpp
index cebd9d4cf2f..f2da96b86bf 100644
--- a/src/common/Debugging/Errors.cpp
+++ b/src/common/Debugging/Errors.cpp
@@ -29,8 +29,7 @@ void Assert(char const* file, int line, char const* function, char const* messag
{
fprintf(stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n",
file, line, function, message);
- *((volatile int*)NULL) = 0;
- exit(1);
+ abort();
}
void Assert(char const* file, int line, char const* function, char const* message, char const* format, ...)
@@ -44,8 +43,7 @@ void Assert(char const* file, int line, char const* function, char const* messag
fflush(stderr);
va_end(args);
- *((volatile int*)NULL) = 0;
- exit(1);
+ abort();
}
void Fatal(char const* file, int line, char const* function, char const* message)
@@ -54,16 +52,14 @@ void Fatal(char const* file, int line, char const* function, char const* message
file, line, function, message);
std::this_thread::sleep_for(std::chrono::seconds(10));
- *((volatile int*)NULL) = 0;
- exit(1);
+ abort();
}
void Error(char const* file, int line, char const* function, char const* message)
{
fprintf(stderr, "\n%s:%i in %s ERROR:\n %s\n",
file, line, function, message);
- *((volatile int*)NULL) = 0;
- exit(1);
+ abort();
}
void Warning(char const* file, int line, char const* function, char const* message)
@@ -72,4 +68,11 @@ void Warning(char const* file, int line, char const* function, char const* messa
file, line, function, message);
}
+void Abort(char const* file, int line, char const* function)
+{
+ fprintf(stderr, "\n%s:%i in %s ABORTED\n",
+ file, line, function);
+ abort();
+}
+
} // namespace Trinity
diff --git a/src/common/Debugging/Errors.h b/src/common/Debugging/Errors.h
index 4d4624b63dd..edf56b29136 100644
--- a/src/common/Debugging/Errors.h
+++ b/src/common/Debugging/Errors.h
@@ -29,6 +29,8 @@ namespace Trinity
DECLSPEC_NORETURN void Fatal(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
DECLSPEC_NORETURN void Error(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
+
+ DECLSPEC_NORETURN void Abort(char const* file, int line, char const* function) ATTR_NORETURN;
void Warning(char const* file, int line, char const* function, char const* message);
@@ -46,8 +48,10 @@ namespace Trinity
#define WPFatal(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Fatal(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END
#define WPError(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Error(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END
#define WPWarning(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Warning(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END
+#define WPAbort() ASSERT_BEGIN do { Trinity::Abort(__FILE__, __LINE__, __FUNCTION__); } while(0) ASSERT_END
#define ASSERT WPAssert
+#define ABORT WPAbort
template <typename T> inline T* ASSERT_NOTNULL(T* pointer)
{
diff --git a/src/common/Utilities/Util.h b/src/common/Utilities/Util.h
index 3da1c800410..6a872b44a60 100644
--- a/src/common/Utilities/Util.h
+++ b/src/common/Utilities/Util.h
@@ -537,7 +537,7 @@ bool CompareValues(ComparisionType type, T val1, T val2)
return val1 <= val2;
default:
// incorrect parameter
- ASSERT(false);
+ ABORT();
return false;
}
}
diff --git a/src/server/authserver/Realms/RealmList.cpp b/src/server/authserver/Realms/RealmList.cpp
index 59cb2392063..f5461d5f42e 100644
--- a/src/server/authserver/Realms/RealmList.cpp
+++ b/src/server/authserver/Realms/RealmList.cpp
@@ -145,7 +145,7 @@ void RealmList::UpdateRealms(bool init)
catch (std::exception& ex)
{
TC_LOG_ERROR("server.authserver", "Realmlist::UpdateRealms has thrown an exception: %s", ex.what());
- ASSERT(false);
+ ABORT();
}
}
while (result->NextRow());
diff --git a/src/server/authserver/authserver.conf.dist b/src/server/authserver/authserver.conf.dist
index ba9cb5b23b4..437ec221e94 100644
--- a/src/server/authserver/authserver.conf.dist
+++ b/src/server/authserver/authserver.conf.dist
@@ -182,7 +182,7 @@ Updates.EnableDatabases = 0
Updates.SourcePath = ""
#
-# Updates.SourcePath
+# Updates.MySqlCLIPath
# Description: The path to your mysql cli binary.
# If the path is left empty, built-in path from cmake is used.
# Example: "C:/Program Files/MySQL/MySQL Server 5.6/bin/mysql.exe"
diff --git a/src/server/database/Database/DatabaseWorkerPool.h b/src/server/database/Database/DatabaseWorkerPool.h
index f5002c6943b..6a0cf71cca6 100644
--- a/src/server/database/Database/DatabaseWorkerPool.h
+++ b/src/server/database/Database/DatabaseWorkerPool.h
@@ -482,7 +482,7 @@ class DatabaseWorkerPool
else if (type == IDX_SYNCH)
t = new T(*_connectionInfo);
else
- ASSERT(false);
+ ABORT();
_connections[type][i] = t;
++_connectionCount[type];
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 9fa2269fd8b..dadffe735d2 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -123,13 +123,18 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
ObjectList* targets = GetTargets(e, unit);
Creature* talker = me;
Player* targetPlayer = NULL;
+ Unit* talkTarget = NULL;
+
if (targets)
{
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
if (IsCreature(*itr) && !(*itr)->ToCreature()->IsPet()) // Prevented sending text to pets.
{
- talker = (*itr)->ToCreature();
+ if (e.action.talk.useTalkTarget)
+ talkTarget = (*itr)->ToCreature();
+ else
+ talker = (*itr)->ToCreature();
break;
}
else if (IsPlayer(*itr))
@@ -148,7 +153,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
mTalkerEntry = talker->GetEntry();
mLastTextID = e.action.talk.textGroupID;
mTextTimer = e.action.talk.duration;
- Unit* talkTarget = NULL;
+
if (IsPlayer(GetLastInvoker())) // used for $vars in texts and whisper target
talkTarget = GetLastInvoker();
else if (targetPlayer)
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index 8565c5d3497..60a4ce5e8ed 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -426,7 +426,7 @@ enum SMART_SCRIPT_RESPAWN_CONDITION
enum SMART_ACTION
{
SMART_ACTION_NONE = 0, // No action
- SMART_ACTION_TALK = 1, // groupID from creature_text, duration to wait before TEXT_OVER event is triggered
+ SMART_ACTION_TALK = 1, // groupID from creature_text, duration to wait before TEXT_OVER event is triggered, useTalkTarget (0/1) - use target as talk target
SMART_ACTION_SET_FACTION = 2, // FactionId (or 0 for default)
SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL = 3, // Creature_template entry(param1) OR ModelId (param2) (or 0 for both to demorph)
SMART_ACTION_SOUND = 4, // SoundId, onlySelf
@@ -553,6 +553,7 @@ struct SmartAction
{
uint32 textGroupID;
uint32 duration;
+ uint32 useTalkTarget;
} talk;
struct
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
index 00b6862369d..26b7f672cfa 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
@@ -309,7 +309,7 @@ int32 BattlegroundAB::_GetNodeNameId(uint8 node)
case BG_AB_NODE_LUMBER_MILL:return LANG_BG_AB_NODE_LUMBER_MILL;
case BG_AB_NODE_GOLD_MINE: return LANG_BG_AB_NODE_GOLD_MINE;
default:
- ASSERT(false);
+ ABORT();
}
return 0;
}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
index 9c654a1793c..d4e51315e92 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
@@ -789,7 +789,7 @@ BG_AV_Nodes BattlegroundAV::GetNodeThroughObject(uint32 object)
if (object == BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE)
return BG_AV_NODES_SNOWFALL_GRAVE;
TC_LOG_ERROR("bg.battleground", "BattlegroundAV: ERROR! GetPlace got a wrong object :(");
- ASSERT(false);
+ ABORT();
return BG_AV_Nodes(0);
}
@@ -827,7 +827,7 @@ uint32 BattlegroundAV::GetObjectThroughNode(BG_AV_Nodes node)
else if (m_Nodes[node].Owner == AV_NEUTRAL_TEAM)
return BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE;
TC_LOG_ERROR("bg.battleground", "BattlegroundAV: Error! GetPlaceNode couldn't resolve node %i", node);
- ASSERT(false);
+ ABORT();
return 0;
}
@@ -1402,22 +1402,22 @@ void BattlegroundAV::AssaultNode(BG_AV_Nodes node, uint16 team)
if (m_Nodes[node].TotalOwner == team)
{
TC_LOG_FATAL("bg.battleground", "Assaulting team is TotalOwner of node");
- ASSERT(false);
+ ABORT();
}
if (m_Nodes[node].Owner == team)
{
TC_LOG_FATAL("bg.battleground", "Assaulting team is owner of node");
- ASSERT(false);
+ ABORT();
}
if (m_Nodes[node].State == POINT_DESTROYED)
{
TC_LOG_FATAL("bg.battleground", "Destroyed node is being assaulted");
- ASSERT(false);
+ ABORT();
}
if (m_Nodes[node].State == POINT_ASSAULTED && m_Nodes[node].TotalOwner) //only assault an assaulted node if no totalowner exists
{
TC_LOG_FATAL("bg.battleground", "Assault on an not assaulted node with total owner");
- ASSERT(false);
+ ABORT();
}
//the timer gets another time, if the previous owner was 0 == Neutral
m_Nodes[node].Timer = (m_Nodes[node].PrevOwner)? BG_AV_CAPTIME : BG_AV_SNOWFALL_FIRSTCAP;
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp
index f267bf7c6c6..c7d8132053c 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp
@@ -744,7 +744,7 @@ bool BattlegroundSA::CanInteractWithObject(uint32 objectId)
return false;
break;
default:
- ASSERT(false);
+ ABORT();
break;
}
@@ -877,7 +877,7 @@ void BattlegroundSA::CaptureGraveyard(BG_SA_Graveyards i, Player* Source)
break;
default:
- ASSERT(false);
+ ABORT();
break;
};
}
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index 5a74ad05b66..0d6816fc80d 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -186,13 +186,33 @@ bool ChatHandler::hasStringAbbr(const char* name, const char* part)
return true;
}
-void ChatHandler::SendSysMessage(const char *str)
+void ChatHandler::SendSysMessage(const char *str, bool escapeCharacters)
{
WorldPacket data;
// need copy to prevent corruption by strtok call in LineFromMessage original string
- char* buf = strdup(str);
- char* pos = buf;
+ char* buf;
+ char* pos;
+
+ if (escapeCharacters && strchr(str, '|'))
+ {
+ size_t startPos = 0;
+ std::ostringstream o;
+ while (const char* charPos = strchr(str + startPos, '|'))
+ {
+ o.write(str + startPos, charPos - str - startPos);
+ o << "||";
+ startPos = charPos - str + 1;
+ }
+ o.write(str + startPos, strlen(str) - startPos);
+ buf = strdup(o.str().c_str());
+ }
+ else
+ {
+ buf = strdup(str);
+ }
+
+ pos = buf;
while (char* line = LineFromMessage(pos))
{
@@ -1223,7 +1243,7 @@ bool CliHandler::isAvailable(ChatCommand const& cmd) const
return cmd.AllowConsole;
}
-void CliHandler::SendSysMessage(const char *str)
+void CliHandler::SendSysMessage(const char *str, bool /*escapeCharacters*/)
{
m_print(m_callbackArg, str);
m_print(m_callbackArg, "\r\n");
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
index 1b095534ad0..72d80aba7e6 100644
--- a/src/server/game/Chat/Chat.h
+++ b/src/server/game/Chat/Chat.h
@@ -66,7 +66,7 @@ class ChatHandler
// function with different implementation for chat/console
virtual char const* GetTrinityString(uint32 entry) const;
- virtual void SendSysMessage(char const* str);
+ virtual void SendSysMessage(char const* str, bool escapeCharacters = false);
void SendSysMessage(uint32 entry);
@@ -166,7 +166,7 @@ class CliHandler : public ChatHandler
char const* GetTrinityString(uint32 entry) const override;
bool isAvailable(ChatCommand const& cmd) const override;
bool HasPermission(uint32 /*permission*/) const override { return true; }
- void SendSysMessage(const char *str) override;
+ void SendSysMessage(const char *str, bool escapeCharacters) override;
std::string GetNameLink() const override;
bool needReportToTarget(Player* chr) const override;
LocaleConstant GetSessionDbcLocale() const override;
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index d9061dfb106..e268b376b34 100644
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -570,7 +570,7 @@ void LoadDBCStores(const std::string& dataPath)
// fill data
for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i)
if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i))
- sTaxiPathNodesByPath[entry->PathID].set(entry->NodeIndex, entry);
+ sTaxiPathNodesByPath[entry->PathID][entry->NodeIndex] = entry;
// Initialize global taxinodes mask
// include existed nodes that have at least single not spell base (scripted) path
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index c680494cd72..092ef714145 100644
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -22,13 +22,8 @@
#include "Common.h"
#include "DBCEnums.h"
#include "Define.h"
-#include "Path.h"
#include "Util.h"
-#include <map>
-#include <set>
-#include <vector>
-
// Structures using to access raw DBC data and required packing to portability
#pragma pack(push, 1)
@@ -2211,15 +2206,7 @@ struct TaxiPathBySourceAndDestination
typedef std::map<uint32, TaxiPathBySourceAndDestination> TaxiPathSetForSource;
typedef std::map<uint32, TaxiPathSetForSource> TaxiPathSetBySource;
-struct TaxiPathNodePtr
-{
- TaxiPathNodePtr() : i_ptr(NULL) { }
- TaxiPathNodePtr(TaxiPathNodeEntry const* ptr) : i_ptr(ptr) { }
- TaxiPathNodeEntry const* i_ptr;
- operator TaxiPathNodeEntry const& () const { return *i_ptr; }
-};
-
-typedef Path<TaxiPathNodePtr, TaxiPathNodeEntry const> TaxiPathNodeList;
+typedef std::vector<TaxiPathNodeEntry const*> TaxiPathNodeList;
typedef std::vector<TaxiPathNodeList> TaxiPathNodesByPath;
#define TaxiMaskSize 14
diff --git a/src/server/game/DungeonFinding/LFGQueue.cpp b/src/server/game/DungeonFinding/LFGQueue.cpp
index d2140a96a46..86b010a9ace 100644
--- a/src/server/game/DungeonFinding/LFGQueue.cpp
+++ b/src/server/game/DungeonFinding/LFGQueue.cpp
@@ -72,7 +72,7 @@ char const* GetCompatibleString(LfgCompatibility compatibles)
case LFG_INCOMPATIBLES_NO_ROLES:
return "Incompatible roles";
case LFG_INCOMPATIBLES_TOO_MUCH_PLAYERS:
- return "Too much players";
+ return "Too many players";
case LFG_INCOMPATIBLES_WRONG_GROUP_SIZE:
return "Wrong group size";
default:
@@ -80,7 +80,7 @@ char const* GetCompatibleString(LfgCompatibility compatibles)
}
}
-std::string LFGQueue::GetDetailedMatchRoles(GuidList const& check)
+std::string LFGQueue::GetDetailedMatchRoles(GuidList const& check) const
{
if (check.empty())
return "";
@@ -92,31 +92,25 @@ std::string LFGQueue::GetDetailedMatchRoles(GuidList const& check)
GuidSet::const_iterator it = guids.begin();
o << it->GetRawValue();
- LfgQueueDataContainer::iterator itQueue = QueueDataStore.find(*it);
- if (itQueue == QueueDataStore.end())
- {
- TC_LOG_ERROR("lfg.queue.data.details", "Queue data not found for [%s]", it->ToString().c_str());
- o << ' ' << GetRolesString(PLAYER_ROLE_NONE);
- }
- else
+ LfgQueueDataContainer::const_iterator itQueue = QueueDataStore.find(*it);
+ if (itQueue != QueueDataStore.end())
{
// skip leader flag, log only dps/tank/healer
- o << ' ' << GetRolesString(itQueue->second.roles[*it] & uint8(~PLAYER_ROLE_LEADER));
+ auto role = itQueue->second.roles.find(*it);
+ if (role != itQueue->second.roles.end())
+ o << ' ' << GetRolesString(itQueue->second.roles.at(*it) & uint8(~PLAYER_ROLE_LEADER));
}
for (++it; it != guids.end(); ++it)
{
o << '|' << it->GetRawValue();
itQueue = QueueDataStore.find(*it);
- if (itQueue == QueueDataStore.end())
- {
- TC_LOG_ERROR("lfg.queue.data.details", "Queue data not found for [%s]", it->ToString().c_str());
- o << ' ' << GetRolesString(PLAYER_ROLE_NONE);
- }
- else
+ if (itQueue != QueueDataStore.end())
{
// skip leader flag, log only dps/tank/healer
- o << ' ' << GetRolesString(itQueue->second.roles[*it] & uint8(~PLAYER_ROLE_LEADER));
+ auto role = itQueue->second.roles.find(*it);
+ if (role != itQueue->second.roles.end())
+ o << ' ' << GetRolesString(itQueue->second.roles.at(*it) & uint8(~PLAYER_ROLE_LEADER));
}
}
@@ -438,7 +432,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check)
if (numPlayers > MAXGROUPSIZE)
{
- TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) Too much players (%u)", GetDetailedMatchRoles(check).c_str(), numPlayers);
+ TC_LOG_DEBUG("lfg.queue.match.compatibility.check", "Guids: (%s) Too many players (%u)", GetDetailedMatchRoles(check).c_str(), numPlayers);
SetCompatibles(strGuids, LFG_INCOMPATIBLES_TOO_MUCH_PLAYERS);
return LFG_INCOMPATIBLES_TOO_MUCH_PLAYERS;
}
@@ -666,7 +660,23 @@ std::string LFGQueue::DumpCompatibleInfo(bool full /* = false */) const
o << "Compatible Map size: " << CompatibleMapStore.size() << "\n";
if (full)
for (LfgCompatibleContainer::const_iterator itr = CompatibleMapStore.begin(); itr != CompatibleMapStore.end(); ++itr)
- o << "(" << itr->first << "): " << GetCompatibleString(itr->second.compatibility) << "\n";
+ {
+ o << "(" << itr->first << "): " << GetCompatibleString(itr->second.compatibility);
+ if (!itr->second.roles.empty())
+ {
+ o << " (";
+ bool first = true;
+ for (const auto& role : itr->second.roles)
+ {
+ if (!first)
+ o << "|";
+ o << role.first.GetRawValue() << " " << GetRolesString(role.second & uint8(~PLAYER_ROLE_LEADER));
+ first = false;
+ }
+ o << ")";
+ }
+ o << "\n";
+ }
return o.str();
}
diff --git a/src/server/game/DungeonFinding/LFGQueue.h b/src/server/game/DungeonFinding/LFGQueue.h
index 77683614d49..f72e9b4fd6d 100644
--- a/src/server/game/DungeonFinding/LFGQueue.h
+++ b/src/server/game/DungeonFinding/LFGQueue.h
@@ -88,7 +88,7 @@ class LFGQueue
public:
// Add/Remove from queue
- std::string GetDetailedMatchRoles(GuidList const& check);
+ std::string GetDetailedMatchRoles(GuidList const& check) const;
void AddToQueue(ObjectGuid guid);
void RemoveFromQueue(ObjectGuid guid);
void AddQueueData(ObjectGuid guid, time_t joinTime, LfgDungeonSet const& dungeons, LfgRolesMap const& rolesMap);
diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp
index 2ccf4471788..505d41f63e7 100644
--- a/src/server/game/Entities/Creature/CreatureGroups.cpp
+++ b/src/server/game/Entities/Creature/CreatureGroups.cpp
@@ -228,10 +228,11 @@ void CreatureGroup::LeaderMoveTo(float x, float y, float z)
if (itr->second->point_1)
{
- if (m_leader->GetCurrentWaypointID() == itr->second->point_1)
+ if (m_leader->GetCurrentWaypointID() == itr->second->point_1 - 1)
itr->second->follow_angle = (2 * float(M_PI)) - itr->second->follow_angle;
- if (m_leader->GetCurrentWaypointID() == itr->second->point_2)
- itr->second->follow_angle = (2 * float(M_PI)) + itr->second->follow_angle;
+
+ if (m_leader->GetCurrentWaypointID() == itr->second->point_2 - 1)
+ itr->second->follow_angle = (float(M_PI)) + itr->second->follow_angle;
}
float angle = itr->second->follow_angle;
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp
index 63be8d06739..db67f1f74f1 100644
--- a/src/server/game/Entities/Creature/GossipDef.cpp
+++ b/src/server/game/Entities/Creature/GossipDef.cpp
@@ -381,10 +381,10 @@ void PlayerMenu::SendQuestGiverStatus(uint8 questStatus, ObjectGuid npcGUID) con
void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGUID, bool activateAccept) const
{
- std::string questTitle = quest->GetTitle();
- std::string questDetails = quest->GetDetails();
- std::string questObjectives = quest->GetObjectives();
- std::string questEndText = quest->GetEndText();
+ std::string questTitle = quest->GetTitle();
+ std::string questDetails = quest->GetDetails();
+ std::string questObjectives = quest->GetObjectives();
+ std::string questAreaDescription = quest->GetAreaDescription();
int32 locale = _session->GetSessionDbLocaleIndex();
if (locale >= 0)
@@ -394,7 +394,7 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGU
ObjectMgr::GetLocaleString(localeData->Title, locale, questTitle);
ObjectMgr::GetLocaleString(localeData->Details, locale, questDetails);
ObjectMgr::GetLocaleString(localeData->Objectives, locale, questObjectives);
- ObjectMgr::GetLocaleString(localeData->EndText, locale, questEndText);
+ ObjectMgr::GetLocaleString(localeData->AreaDescription, locale, questAreaDescription);
}
}
@@ -489,11 +489,11 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGU
void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const
{
- std::string questTitle = quest->GetTitle();
- std::string questDetails = quest->GetDetails();
- std::string questObjectives = quest->GetObjectives();
- std::string questEndText = quest->GetEndText();
- std::string questCompletedText = quest->GetCompletedText();
+ std::string questTitle = quest->GetTitle();
+ std::string questDetails = quest->GetDetails();
+ std::string questObjectives = quest->GetObjectives();
+ std::string questAreaDescription = quest->GetAreaDescription();
+ std::string questCompletedText = quest->GetCompletedText();
std::string questObjectiveText[QUEST_OBJECTIVES_COUNT];
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
@@ -507,7 +507,7 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const
ObjectMgr::GetLocaleString(localeData->Title, locale, questTitle);
ObjectMgr::GetLocaleString(localeData->Details, locale, questDetails);
ObjectMgr::GetLocaleString(localeData->Objectives, locale, questObjectives);
- ObjectMgr::GetLocaleString(localeData->EndText, locale, questEndText);
+ ObjectMgr::GetLocaleString(localeData->AreaDescription, locale, questAreaDescription);
ObjectMgr::GetLocaleString(localeData->CompletedText, locale, questCompletedText);
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
@@ -585,9 +585,9 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // unk (0)
data << int32(quest->RewardFactionValueIdOverride[i]);
- data << uint32(quest->GetPointMapId());
- data << float(quest->GetPointX());
- data << float(quest->GetPointY());
+ data << uint32(quest->GetPOIContinent());
+ data << float(quest->GetPOIx());
+ data << float(quest->GetPOIy());
data << uint32(quest->GetPointOpt());
if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS))
@@ -596,7 +596,7 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const
data << questTitle;
data << questObjectives;
data << questDetails;
- data << questEndText;
+ data << questAreaDescription;
data << questCompletedText; // display in quest objectives window once all objectives are completed
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
@@ -607,7 +607,7 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const
data << uint32(quest->RequiredNpcOrGo[i]);
data << uint32(quest->RequiredNpcOrGoCount[i]);
- data << uint32(quest->RequiredSourceItemId[i]);
+ data << uint32(quest->ItemDrop[i]);
data << uint32(0); // req source count?
}
diff --git a/src/server/game/Entities/Creature/TemporarySummon.cpp b/src/server/game/Entities/Creature/TemporarySummon.cpp
index 2a3e91b7574..46422444bbb 100644
--- a/src/server/game/Entities/Creature/TemporarySummon.cpp
+++ b/src/server/game/Entities/Creature/TemporarySummon.cpp
@@ -368,7 +368,7 @@ void Puppet::InitSummon()
{
Minion::InitSummon();
if (!SetCharmedBy(GetOwner(), CHARM_TYPE_POSSESS))
- ASSERT(false);
+ ABORT();
}
void Puppet::Update(uint32 time)
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index 7ef8ef2737d..e12bec768fb 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -680,7 +680,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map
// Owner already found and different than expected owner - remove object from old owner
if (owner && GetOwnerGUID() && GetOwnerGUID() != owner)
{
- ASSERT(false);
+ ABORT();
}
m_spawnedByDefault = false; // all object with owner is despawned after delay
SetGuidValue(OBJECT_FIELD_CREATED_BY, owner);
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index 141bac5e50f..4f91423d769 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -1070,7 +1070,7 @@ Item* Item::CreateItem(uint32 itemEntry, uint32 count, Player const* player)
delete item;
}
else
- ASSERT(false);
+ ABORT();
return NULL;
}
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index fc55c09bffa..6087e03b1bb 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -67,7 +67,7 @@ WorldObject::~WorldObject()
{
TC_LOG_FATAL("misc", "WorldObject::~WorldObject Corpse Type: %d (%s) deleted but still in map!!",
ToCorpse()->GetType(), GetGUID().ToString().c_str());
- ASSERT(false);
+ ABORT();
}
ResetMap();
}
@@ -80,14 +80,14 @@ Object::~Object()
TC_LOG_FATAL("misc", "Object::~Object %s deleted but still in world!!", GetGUID().ToString().c_str());
if (isType(TYPEMASK_ITEM))
TC_LOG_FATAL("misc", "Item slot %u", ((Item*)this)->GetSlot());
- ASSERT(false);
+ ABORT();
RemoveFromWorld();
}
if (m_objectUpdated)
{
TC_LOG_FATAL("misc", "Object::~Object %s deleted but still in update list!!", GetGUID().ToString().c_str());
- ASSERT(false);
+ ABORT();
sObjectAccessor->RemoveUpdateObject(this);
}
@@ -1795,7 +1795,7 @@ void WorldObject::SetMap(Map* map)
if (m_currMap)
{
TC_LOG_FATAL("misc", "WorldObject::SetMap: obj %u new map %u %u, old map %u %u", (uint32)GetTypeId(), map->GetId(), map->GetInstanceId(), m_currMap->GetId(), m_currMap->GetInstanceId());
- ASSERT(false);
+ ABORT();
}
m_currMap = map;
m_mapId = map->GetId();
diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h
index b1d7fcaa28a..e47bf220195 100644
--- a/src/server/game/Entities/Pet/Pet.h
+++ b/src/server/game/Entities/Pet/Pet.h
@@ -159,11 +159,11 @@ class Pet : public Guardian
private:
void SaveToDB(uint32, uint8, uint32) override // override of Creature::SaveToDB - must not be called
{
- ASSERT(false);
+ ABORT();
}
void DeleteFromDB() override // override of Creature::DeleteFromDB - must not be called
{
- ASSERT(false);
+ ABORT();
}
};
#endif
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 88d7dfa6381..e4e07cfeb53 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -8335,9 +8335,6 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8
return;
}
- // use triggered flag only for items with many spell casts and for not first cast
- uint8 count = 0;
-
// item spells cast at use
for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
{
@@ -8358,13 +8355,12 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8
continue;
}
- Spell* spell = new Spell(this, spellInfo, (count > 0) ? TRIGGERED_FULL_MASK : TRIGGERED_NONE);
+ Spell* spell = new Spell(this, spellInfo, TRIGGERED_NONE);
spell->m_CastItem = item;
spell->m_cast_count = cast_count; // set count of casts
spell->m_glyphIndex = glyphIndex; // glyph index
spell->prepare(&targets);
-
- ++count;
+ return;
}
// Item enchantments spells cast at use
@@ -8386,13 +8382,12 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8
continue;
}
- Spell* spell = new Spell(this, spellInfo, (count > 0) ? TRIGGERED_FULL_MASK : TRIGGERED_NONE);
+ Spell* spell = new Spell(this, spellInfo, TRIGGERED_NONE);
spell->m_CastItem = item;
spell->m_cast_count = cast_count; // set count of casts
spell->m_glyphIndex = glyphIndex; // glyph index
spell->prepare(&targets);
-
- ++count;
+ return;
}
}
}
@@ -15065,15 +15060,15 @@ void Player::AddQuest(Quest const* quest, Object* questGiver)
uint32 qtime = 0;
if (quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED))
{
- uint32 limittime = quest->GetLimitTime();
+ uint32 timeAllowed = quest->GetTimeAllowed();
// shared timed quest
if (questGiver && questGiver->GetTypeId() == TYPEID_PLAYER)
- limittime = questGiver->ToPlayer()->getQuestStatusMap()[quest_id].Timer / IN_MILLISECONDS;
+ timeAllowed = questGiver->ToPlayer()->getQuestStatusMap()[quest_id].Timer / IN_MILLISECONDS;
AddTimedQuest(quest_id);
- questStatusData.Timer = limittime * IN_MILLISECONDS;
- qtime = static_cast<uint32>(time(NULL)) + limittime;
+ questStatusData.Timer = timeAllowed * IN_MILLISECONDS;
+ qtime = static_cast<uint32>(time(NULL)) + timeAllowed;
}
else
questStatusData.Timer = 0;
@@ -15163,10 +15158,10 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
for (uint8 i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
{
- if (quest->RequiredSourceItemId[i])
+ if (quest->ItemDrop[i])
{
- uint32 count = quest->RequiredSourceItemCount[i];
- DestroyItemCount(quest->RequiredSourceItemId[i], count ? count : 9999, true);
+ uint32 count = quest->ItemDropQuantity[i];
+ DestroyItemCount(quest->ItemDrop[i], count ? count : 9999, true);
}
}
@@ -15373,9 +15368,9 @@ void Player::FailQuest(uint32 questId)
// Destroy items received on starting the quest.
DestroyItemCount(quest->RequiredItemId[i], quest->RequiredItemCount[i], true, true);
for (uint8 i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
- if (quest->RequiredSourceItemId[i] > 0 && quest->RequiredSourceItemCount[i] > 0)
+ if (quest->ItemDrop[i] > 0 && quest->ItemDropQuantity[i] > 0)
// Destroy items received during the quest.
- DestroyItemCount(quest->RequiredSourceItemId[i], quest->RequiredSourceItemCount[i], true, true);
+ DestroyItemCount(quest->ItemDrop[i], quest->ItemDropQuantity[i], true, true);
}
}
@@ -15557,7 +15552,7 @@ bool Player::SatisfyQuestClass(Quest const* qInfo, bool msg) const
bool Player::SatisfyQuestRace(Quest const* qInfo, bool msg)
{
- uint32 reqraces = qInfo->GetRequiredRaces();
+ uint32 reqraces = qInfo->GetAllowableRaces();
if (reqraces == 0)
return true;
if ((reqraces & getRaceMask()) == 0)
@@ -16678,7 +16673,7 @@ bool Player::HasQuestForItem(uint32 itemid) const
for (uint8 j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j)
{
// examined item is a source item
- if (qinfo->RequiredSourceItemId[j] == itemid)
+ if (qinfo->ItemDrop[j] == itemid)
{
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(itemid);
@@ -16687,9 +16682,9 @@ bool Player::HasQuestForItem(uint32 itemid) const
return true;
// allows custom amount drop when not 0
- if (qinfo->RequiredSourceItemCount[j])
+ if (qinfo->ItemDropQuantity[j])
{
- if (GetItemCount(itemid, true) < qinfo->RequiredSourceItemCount[j])
+ if (GetItemCount(itemid, true) < qinfo->ItemDropQuantity[j])
return true;
} else if (GetItemCount(itemid, true) < pProto->GetMaxStackSize())
return true;
@@ -20445,7 +20440,7 @@ void Player::StopCastingCharm()
if (charm->GetCharmerGUID())
{
TC_LOG_FATAL("entities.player", "Charmed unit has charmer %s", charm->GetCharmerGUID().ToString().c_str());
- ASSERT(false);
+ ABORT();
}
else
SetCharm(charm, false);
@@ -21163,6 +21158,7 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
// fill destinations path tail
uint32 sourcepath = 0;
uint32 totalcost = 0;
+ uint32 firstcost = 0;
uint32 prevnode = sourcenode;
uint32 lastnode = 0;
@@ -21181,6 +21177,8 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
}
totalcost += cost;
+ if (i == 1)
+ firstcost = cost;
if (prevnode == sourcenode)
sourcepath = path;
@@ -21219,8 +21217,6 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
}
//Checks and preparations done, DO FLIGHT
- ModifyMoney(-(int32)totalcost);
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, totalcost);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN, 1);
// prevent stealth flight
@@ -21231,11 +21227,15 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
TaxiNodesEntry const* lastPathNode = sTaxiNodesStore.LookupEntry(nodes[nodes.size()-1]);
ASSERT(lastPathNode);
m_taxi.ClearTaxiDestinations();
+ ModifyMoney(-(int32)totalcost);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, totalcost);
TeleportTo(lastPathNode->map_id, lastPathNode->x, lastPathNode->y, lastPathNode->z, GetOrientation());
return false;
}
else
{
+ ModifyMoney(-(int32)firstcost);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, firstcost);
GetSession()->SendActivateTaxiReply(ERR_TAXIOK);
GetSession()->SendDoFlight(mount_display_id, sourcepath);
}
@@ -21286,30 +21286,30 @@ void Player::ContinueTaxiFlight()
float distPrev = MAP_SIZE*MAP_SIZE;
float distNext =
- (nodeList[0].LocX-GetPositionX())*(nodeList[0].LocX-GetPositionX())+
- (nodeList[0].LocY-GetPositionY())*(nodeList[0].LocY-GetPositionY())+
- (nodeList[0].LocZ-GetPositionZ())*(nodeList[0].LocZ-GetPositionZ());
+ (nodeList[0]->LocX - GetPositionX())*(nodeList[0]->LocX - GetPositionX()) +
+ (nodeList[0]->LocY - GetPositionY())*(nodeList[0]->LocY - GetPositionY()) +
+ (nodeList[0]->LocZ - GetPositionZ())*(nodeList[0]->LocZ - GetPositionZ());
for (uint32 i = 1; i < nodeList.size(); ++i)
{
- TaxiPathNodeEntry const& node = nodeList[i];
- TaxiPathNodeEntry const& prevNode = nodeList[i-1];
+ TaxiPathNodeEntry const* node = nodeList[i];
+ TaxiPathNodeEntry const* prevNode = nodeList[i-1];
// skip nodes at another map
- if (node.MapID != GetMapId())
+ if (node->MapID != GetMapId())
continue;
distPrev = distNext;
distNext =
- (node.LocX-GetPositionX())*(node.LocX-GetPositionX())+
- (node.LocY-GetPositionY())*(node.LocY-GetPositionY())+
- (node.LocZ-GetPositionZ())*(node.LocZ-GetPositionZ());
+ (node->LocX - GetPositionX())*(node->LocX - GetPositionX()) +
+ (node->LocY - GetPositionY())*(node->LocY - GetPositionY()) +
+ (node->LocZ - GetPositionZ())*(node->LocZ - GetPositionZ());
float distNodes =
- (node.LocX-prevNode.LocX)*(node.LocX-prevNode.LocX)+
- (node.LocY-prevNode.LocY)*(node.LocY-prevNode.LocY)+
- (node.LocZ-prevNode.LocZ)*(node.LocZ-prevNode.LocZ);
+ (node->LocX - prevNode->LocX)*(node->LocX - prevNode->LocX) +
+ (node->LocY - prevNode->LocY)*(node->LocY - prevNode->LocY) +
+ (node->LocZ - prevNode->LocZ)*(node->LocZ - prevNode->LocZ);
if (distNext + distPrev < distNodes)
{
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index a031840a1d8..94d0fa5697c 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -952,6 +952,8 @@ class PlayerTaxi
m_TaxiDestinations.pop_front();
return GetTaxiDestination();
}
+
+ std::deque<uint32> const& GetPath() const { return m_TaxiDestinations; }
bool empty() const { return m_TaxiDestinations.empty(); }
friend std::ostringstream& operator<< (std::ostringstream& ss, PlayerTaxi const& taxi);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index d02a22d43f4..f8810c9d14f 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -3520,7 +3520,7 @@ void Unit::_UnapplyAura(AuraApplication * aurApp, AuraRemoveMode removeMode)
else
++iter;
}
- ASSERT(false);
+ ABORT();
}
void Unit::_RemoveNoStackAurasDueToAura(Aura* aura)
@@ -3630,7 +3630,7 @@ void Unit::RemoveOwnedAura(Aura* aura, AuraRemoveMode removeMode)
}
}
- ASSERT(false);
+ ABORT();
}
Aura* Unit::GetOwnedAura(uint32 spellId, ObjectGuid casterGUID, ObjectGuid itemCasterGUID, uint8 reqEffMask, Aura* except) const
@@ -9450,7 +9450,7 @@ void Unit::SetMinion(Minion *minion, bool apply)
{
OutDebugInfo();
(*itr)->OutDebugInfo();
- ASSERT(false);
+ ABORT();
}
ASSERT((*itr)->GetTypeId() == TYPEID_UNIT);
@@ -13171,6 +13171,10 @@ bool Unit::IsInFeralForm() const
bool Unit::IsInDisallowedMountForm() const
{
+ if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(getTransForm()))
+ if (transformSpellInfo->HasAttribute(SPELL_ATTR0_CASTABLE_WHILE_MOUNTED))
+ return false;
+
if (ShapeshiftForm form = GetShapeshiftForm())
{
SpellShapeshiftEntry const* shapeshift = sSpellShapeshiftStore.LookupEntry(form);
@@ -13600,7 +13604,7 @@ void Unit::RemoveFromWorld()
if (GetCharmerGUID())
{
TC_LOG_FATAL("entities.unit", "Unit %u has charmer guid when removed from world", GetEntry());
- ASSERT(false);
+ ABORT();
}
if (Unit* owner = GetOwner())
@@ -13608,7 +13612,7 @@ void Unit::RemoveFromWorld()
if (owner->m_Controlled.find(this) != owner->m_Controlled.end())
{
TC_LOG_FATAL("entities.unit", "Unit %u is in controlled list of %u when removed from world", GetEntry(), owner->GetEntry());
- ASSERT(false);
+ ABORT();
}
}
@@ -15976,7 +15980,7 @@ void Unit::RemoveCharmedBy(Unit* charmer)
{
// TC_LOG_FATAL("entities.unit", "Unit::RemoveCharmedBy: this: " UI64FMTD " true charmer: " UI64FMTD " false charmer: " UI64FMTD,
// GetGUID(), GetCharmerGUID(), charmer->GetGUID());
-// ASSERT(false);
+// ABORT();
return;
}
@@ -17273,7 +17277,7 @@ void Unit::SendChangeCurrentVictimOpcode(HostileReference* pHostileReference)
for (ThreatContainer::StorageType::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr)
{
data << (*itr)->getUnitGuid().WriteAsPacked();
- data << uint32((*itr)->getThreat());
+ data << uint32((*itr)->getThreat() * 100);
}
SendMessageToSet(&data, false);
}
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index a568409d918..524bb442868 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -3966,31 +3966,31 @@ void ObjectMgr::LoadQuests()
mExclusiveQuestGroups.clear();
QueryResult result = WorldDatabase.Query("SELECT "
- //0 1 2 3 4 5 6 7 8
- "ID, Method, QuestLevel, MinLevel, QuestSortID, QuestType, SuggestedGroupNum, LimitTime, RequiredRaces,"
+ //0 1 2 3 4 5 6 7 8
+ "ID, QuestType, QuestLevel, MinLevel, QuestSortID, QuestInfoID, SuggestedGroupNum, TimeAllowed, AllowableRaces,"
// 9 10 11 12
"RequiredFactionId1, RequiredFactionId2, RequiredFactionValue1, RequiredFactionValue2, "
- // 13 14 15 16 17 18 19 20
- "NextQuestIdChain, RewardXPId, RewardOrRequiredMoney, RewardMoneyMaxLevel, RewardSpell, RewardSpellCast, RewardHonor, RewardHonorMultiplier, "
- // 21 22 23 24 25 26
- "SourceItemId, Flags, RewardTitle, RequiredPlayerKills, RewardTalents, RewardArenaPoints, "
+ // 13 14 15 16 17 18 19 20
+ "RewardNextQuest, RewardXPDifficulty, RewardMoney, RewardBonusMoney, RewardDisplaySpell, RewardSpell, RewardHonor, RewardKillHonor, "
+ // 21 22 23 24 25 26
+ "StartItem, Flags, RewardTitle, RequiredPlayerKills, RewardTalents, RewardArenaPoints, "
// 27 28 29 30 31 32 33 34
"RewardItem1, RewardAmount1, RewardItem2, RewardAmount2, RewardItem3, RewardAmount3, RewardItem4, RewardAmount4, "
// 35 36 37 38 39 40 41 42 43 44 45 46
"RewardChoiceItemID1, RewardChoiceItemQuantity1, RewardChoiceItemID2, RewardChoiceItemQuantity2, RewardChoiceItemID3, RewardChoiceItemQuantity3, RewardChoiceItemID4, RewardChoiceItemQuantity4, RewardChoiceItemID5, RewardChoiceItemQuantity5, RewardChoiceItemID6, RewardChoiceItemQuantity6, "
// 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
"RewardFactionID1, RewardFactionValue1, RewardFactionOverride1, RewardFactionID2, RewardFactionValue2, RewardFactionOverride2, RewardFactionID3, RewardFactionValue3, RewardFactionOverride3, RewardFactionID4, RewardFactionValue4, RewardFactionOverride4, RewardFactionID5, RewardFactionValue5, RewardFactionOverride5,"
- // 62 63 64 65
- "PointMapId, PointX, PointY, PointOption, "
- // 66 67 68 69 70
- "LogTitle, LogDescription, QuestDescription, EndText, QuestCompletionLog, "
+ // 62 63 64 65
+ "POIContinent, POIx, POIy, POIPriority, "
+ // 66 67 68 69 70
+ "LogTitle, LogDescription, QuestDescription, AreaDescription, QuestCompletionLog, "
// 71 72 73 74 75 76 77 78
"RequiredNpcOrGo1, RequiredNpcOrGo2, RequiredNpcOrGo3, RequiredNpcOrGo4, RequiredNpcOrGoCount1, RequiredNpcOrGoCount2, RequiredNpcOrGoCount3, RequiredNpcOrGoCount4, "
- // 79 80 81 82 83 84 85 86
- "RequiredSourceItemId1, RequiredSourceItemId2, RequiredSourceItemId3, RequiredSourceItemId4, RequiredSourceItemCount1, RequiredSourceItemCount2, RequiredSourceItemCount3, RequiredSourceItemCount4, "
+ // 79 80 81 82 83 84 85 86
+ "ItemDrop1, ItemDrop2, ItemDrop3, ItemDrop4, ItemDropQuantity1, ItemDropQuantity2, ItemDropQuantity3, ItemDropQuantity4, "
// 87 88 89 90 91 92 93 94 95 96 97 98
"RequiredItemId1, RequiredItemId2, RequiredItemId3, RequiredItemId4, RequiredItemId5, RequiredItemId6, RequiredItemCount1, RequiredItemCount2, RequiredItemCount3, RequiredItemCount4, RequiredItemCount5, RequiredItemCount6, "
- // 99 100 101 102 103
+ // 99 100 101 102 103
"Unknown0, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4"
" FROM quest_template");
if (!result)
@@ -4011,7 +4011,7 @@ void ObjectMgr::LoadQuests()
} while (result->NextRow());
std::map<uint32, uint32> usedMailTemplates;
-
+
// Load `quest_details`
// 0 1 2 3 4 5 6 7 8
result = WorldDatabase.Query("SELECT ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4 FROM quest_details");
@@ -4215,13 +4215,13 @@ void ObjectMgr::LoadQuests()
qinfo->RequiredClasses = 0;
}
}
- // RequiredRaces, can be 0/RACEMASK_ALL_PLAYABLE to allow any race
- if (qinfo->RequiredRaces)
+ // AllowableRaces, can be 0/RACEMASK_ALL_PLAYABLE to allow any race
+ if (qinfo->AllowableRaces)
{
- if (!(qinfo->RequiredRaces & RACEMASK_ALL_PLAYABLE))
+ if (!(qinfo->AllowableRaces & RACEMASK_ALL_PLAYABLE))
{
- TC_LOG_ERROR("sql.sql", "Quest %u does not contain any playable races in `RequiredRaces` (%u), value set to 0 (all races).", qinfo->GetQuestId(), qinfo->RequiredRaces);
- qinfo->RequiredRaces = 0;
+ TC_LOG_ERROR("sql.sql", "Quest %u does not contain any playable races in `AllowableRaces` (%u), value set to 0 (all races).", qinfo->GetQuestId(), qinfo->AllowableRaces);
+ qinfo->AllowableRaces = 0;
}
}
// RequiredSkillId, can be 0
@@ -4323,26 +4323,26 @@ void ObjectMgr::LoadQuests()
// quest can't reward this title
}
- if (qinfo->SourceItemId)
+ if (qinfo->StartItem)
{
- if (!sObjectMgr->GetItemTemplate(qinfo->SourceItemId))
+ if (!sObjectMgr->GetItemTemplate(qinfo->StartItem))
{
- TC_LOG_ERROR("sql.sql", "Quest %u has `SourceItemId` = %u but item with entry %u does not exist, quest can't be done.",
- qinfo->GetQuestId(), qinfo->SourceItemId, qinfo->SourceItemId);
- qinfo->SourceItemId = 0; // quest can't be done for this requirement
+ TC_LOG_ERROR("sql.sql", "Quest %u has `StartItem` = %u but item with entry %u does not exist, quest can't be done.",
+ qinfo->GetQuestId(), qinfo->StartItem, qinfo->StartItem);
+ qinfo->StartItem = 0; // quest can't be done for this requirement
}
- else if (qinfo->SourceItemIdCount == 0)
+ else if (qinfo->StartItemCount == 0)
{
- TC_LOG_ERROR("sql.sql", "Quest %u has `SourceItemId` = %u but `SourceItemIdCount` = 0, set to 1 but need fix in DB.",
- qinfo->GetQuestId(), qinfo->SourceItemId);
- qinfo->SourceItemIdCount = 1; // update to 1 for allow quest work for backward compatibility with DB
+ TC_LOG_ERROR("sql.sql", "Quest %u has `StartItem` = %u but `StartItemCount` = 0, set to 1 but need fix in DB.",
+ qinfo->GetQuestId(), qinfo->StartItem);
+ qinfo->StartItemCount = 1; // update to 1 for allow quest work for backward compatibility with DB
}
}
- else if (qinfo->SourceItemIdCount>0)
+ else if (qinfo->StartItemCount>0)
{
- TC_LOG_ERROR("sql.sql", "Quest %u has `SourceItemId` = 0 but `SourceItemIdCount` = %u, useless value.",
- qinfo->GetQuestId(), qinfo->SourceItemIdCount);
- qinfo->SourceItemIdCount=0; // no quest work changes in fact
+ TC_LOG_ERROR("sql.sql", "Quest %u has `StartItem` = 0 but `StartItemCount` = %u, useless value.",
+ qinfo->GetQuestId(), qinfo->StartItemCount);
+ qinfo->StartItemCount=0; // no quest work changes in fact
}
if (qinfo->SourceSpellid)
@@ -4393,22 +4393,22 @@ void ObjectMgr::LoadQuests()
for (uint8 j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j)
{
- uint32 id = qinfo->RequiredSourceItemId[j];
+ uint32 id = qinfo->ItemDrop[j];
if (id)
{
if (!sObjectMgr->GetItemTemplate(id))
{
- TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredSourceItemId%d` = %u but item with entry %u does not exist, quest can't be done.",
+ TC_LOG_ERROR("sql.sql", "Quest %u has `ItemDrop%d` = %u but item with entry %u does not exist, quest can't be done.",
qinfo->GetQuestId(), j+1, id, id);
// no changes, quest can't be done for this requirement
}
}
else
{
- if (qinfo->RequiredSourceItemCount[j]>0)
+ if (qinfo->ItemDropQuantity[j]>0)
{
- TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredSourceItemId%d` = 0 but `RequiredSourceItemCount%d` = %u.",
- qinfo->GetQuestId(), j+1, j+1, qinfo->RequiredSourceItemCount[j]);
+ TC_LOG_ERROR("sql.sql", "Quest %u has `ItemDrop%d` = 0 but `ItemDropQuantity%d` = %u.",
+ qinfo->GetQuestId(), j+1, j+1, qinfo->ItemDropQuantity[j]);
// no changes, quest ignore this data
}
}
@@ -4529,55 +4529,55 @@ void ObjectMgr::LoadQuests()
}
}
- if (qinfo->RewardSpell)
+ if (qinfo->RewardDisplaySpell)
{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardSpell);
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardDisplaySpell);
if (!spellInfo)
{
- TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpell` = %u but spell %u does not exist, spell removed as display reward.",
- qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
- qinfo->RewardSpell = 0; // no spell reward will display for this quest
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RewardDisplaySpell` = %u but spell %u does not exist, spell removed as display reward.",
+ qinfo->GetQuestId(), qinfo->RewardDisplaySpell, qinfo->RewardDisplaySpell);
+ qinfo->RewardDisplaySpell = 0; // no spell reward will display for this quest
}
else if (!SpellMgr::IsSpellValid(spellInfo))
{
- TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpell` = %u but spell %u is broken, quest will not have a spell reward.",
- qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
- qinfo->RewardSpell = 0; // no spell reward will display for this quest
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RewardDisplaySpell` = %u but spell %u is broken, quest will not have a spell reward.",
+ qinfo->GetQuestId(), qinfo->RewardDisplaySpell, qinfo->RewardDisplaySpell);
+ qinfo->RewardDisplaySpell = 0; // no spell reward will display for this quest
}
- else if (GetTalentSpellCost(qinfo->RewardSpell))
+ else if (GetTalentSpellCost(qinfo->RewardDisplaySpell))
{
- TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpell` = %u but spell %u is talent, quest will not have a spell reward.",
- qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
- qinfo->RewardSpell = 0; // no spell reward will display for this quest
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RewardDisplaySpell` = %u but spell %u is talent, quest will not have a spell reward.",
+ qinfo->GetQuestId(), qinfo->RewardDisplaySpell, qinfo->RewardDisplaySpell);
+ qinfo->RewardDisplaySpell = 0; // no spell reward will display for this quest
}
}
- if (qinfo->RewardSpellCast > 0)
+ if (qinfo->RewardSpell > 0)
{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardSpellCast);
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardSpell);
if (!spellInfo)
{
- TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpellCast` = %u but spell %u does not exist, quest will not have a spell reward.",
- qinfo->GetQuestId(), qinfo->RewardSpellCast, qinfo->RewardSpellCast);
- qinfo->RewardSpellCast = 0; // no spell will be cast on player
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpell` = %u but spell %u does not exist, quest will not have a spell reward.",
+ qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
+ qinfo->RewardSpell = 0; // no spell will be cast on player
}
else if (!SpellMgr::IsSpellValid(spellInfo))
{
- TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpellCast` = %u but spell %u is broken, quest will not have a spell reward.",
- qinfo->GetQuestId(), qinfo->RewardSpellCast, qinfo->RewardSpellCast);
- qinfo->RewardSpellCast = 0; // no spell will be cast on player
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpell` = %u but spell %u is broken, quest will not have a spell reward.",
+ qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
+ qinfo->RewardSpell = 0; // no spell will be cast on player
}
- else if (GetTalentSpellCost(qinfo->RewardSpellCast))
+ else if (GetTalentSpellCost(qinfo->RewardSpell))
{
- TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpell` = %u but spell %u is talent, quest will not have a spell reward.",
- qinfo->GetQuestId(), qinfo->RewardSpellCast, qinfo->RewardSpellCast);
- qinfo->RewardSpellCast = 0; // no spell will be cast on player
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RewardDisplaySpell` = %u but spell %u is talent, quest will not have a spell reward.",
+ qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
+ qinfo->RewardSpell = 0; // no spell will be cast on player
}
}
@@ -4602,14 +4602,14 @@ void ObjectMgr::LoadQuests()
usedMailTemplates[qinfo->RewardMailTemplateId] = qinfo->GetQuestId();
}
- if (qinfo->NextQuestIdChain)
+ if (qinfo->RewardNextQuest)
{
- QuestMap::iterator qNextItr = _questTemplates.find(qinfo->NextQuestIdChain);
+ QuestMap::iterator qNextItr = _questTemplates.find(qinfo->RewardNextQuest);
if (qNextItr == _questTemplates.end())
{
- TC_LOG_ERROR("sql.sql", "Quest %u has `NextQuestIdChain` = %u but quest %u does not exist, quest chain will not work.",
- qinfo->GetQuestId(), qinfo->NextQuestIdChain, qinfo->NextQuestIdChain);
- qinfo->NextQuestIdChain = 0;
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RewardNextQuest` = %u but quest %u does not exist, quest chain will not work.",
+ qinfo->GetQuestId(), qinfo->RewardNextQuest, qinfo->RewardNextQuest);
+ qinfo->RewardNextQuest = 0;
}
else
qNextItr->second->prevChainQuests.push_back(qinfo->GetQuestId());
@@ -4644,7 +4644,7 @@ void ObjectMgr::LoadQuests()
if (qinfo->ExclusiveGroup)
mExclusiveQuestGroups.insert(std::pair<int32, uint32>(qinfo->ExclusiveGroup, qinfo->GetQuestId()));
- if (qinfo->LimitTime)
+ if (qinfo->TimeAllowed)
qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED);
if (qinfo->RequiredPlayerKills)
qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_PLAYER_KILL);
@@ -4720,7 +4720,7 @@ void ObjectMgr::LoadQuestLocales()
AddLocaleString(fields[1 + 11 * (i - 1) + 2].GetString(), locale, data.Objectives);
AddLocaleString(fields[1 + 11 * (i - 1) + 3].GetString(), locale, data.OfferRewardText);
AddLocaleString(fields[1 + 11 * (i - 1) + 4].GetString(), locale, data.RequestItemsText);
- AddLocaleString(fields[1 + 11 * (i - 1) + 5].GetString(), locale, data.EndText);
+ AddLocaleString(fields[1 + 11 * (i - 1) + 5].GetString(), locale, data.AreaDescription);
AddLocaleString(fields[1 + 11 * (i - 1) + 6].GetString(), locale, data.CompletedText);
for (uint8 k = 0; k < 4; ++k)
@@ -5090,13 +5090,13 @@ void ObjectMgr::LoadEventScripts()
{
for (size_t node_idx = 0; node_idx < sTaxiPathNodesByPath[path_idx].size(); ++node_idx)
{
- TaxiPathNodeEntry const& node = sTaxiPathNodesByPath[path_idx][node_idx];
+ TaxiPathNodeEntry const* node = sTaxiPathNodesByPath[path_idx][node_idx];
- if (node.ArrivalEventID)
- evt_scripts.insert(node.ArrivalEventID);
+ if (node->ArrivalEventID)
+ evt_scripts.insert(node->ArrivalEventID);
- if (node.DepartureEventID)
- evt_scripts.insert(node.DepartureEventID);
+ if (node->DepartureEventID)
+ evt_scripts.insert(node->DepartureEventID);
}
}
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 11b31d98cc8..b6e8d3c3ede 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -1942,7 +1942,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
{
Quest const* quest = iter->second;
uint32 newRaceMask = (team == TEAM_ALLIANCE) ? RACEMASK_ALLIANCE : RACEMASK_HORDE;
- if (!(quest->GetRequiredRaces() & newRaceMask))
+ if (!(quest->GetAllowableRaces() & newRaceMask))
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST);
stmt->setUInt32(0, lowGuid);
diff --git a/src/server/game/Handlers/TaxiHandler.cpp b/src/server/game/Handlers/TaxiHandler.cpp
index af0f5b0fc75..a671250c17d 100644
--- a/src/server/game/Handlers/TaxiHandler.cpp
+++ b/src/server/game/Handlers/TaxiHandler.cpp
@@ -24,7 +24,6 @@
#include "Log.h"
#include "ObjectMgr.h"
#include "Player.h"
-#include "Path.h"
#include "WaypointMovementGenerator.h"
void WorldSession::HandleTaxiNodeStatusQueryOpcode(WorldPacket& recvData)
@@ -212,7 +211,7 @@ void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recvData)
MovementInfo movementInfo; // used only for proper packet read
ReadMovementInfo(recvData, &movementInfo);
- recvData.read_skip<uint32>(); // unk
+ recvData.read_skip<uint32>(); // spline id
// in taxi flight packet received in 2 case:
// 1) end taxi path in far (multi-node) flight
@@ -220,59 +219,32 @@ void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recvData)
// we need process only (1)
uint32 curDest = GetPlayer()->m_taxi.GetTaxiDestination();
- if (!curDest)
- return;
-
- TaxiNodesEntry const* curDestNode = sTaxiNodesStore.LookupEntry(curDest);
-
- // far teleport case
- if (curDestNode && curDestNode->map_id != GetPlayer()->GetMapId())
+ if (curDest)
{
- if (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE)
- {
- // short preparations to continue flight
- FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top());
-
- flight->SetCurrentNodeAfterTeleport();
- TaxiPathNodeEntry const& node = flight->GetPath()[flight->GetCurrentNode()];
- flight->SkipCurrentNode();
+ TaxiNodesEntry const* curDestNode = sTaxiNodesStore.LookupEntry(curDest);
- GetPlayer()->TeleportTo(curDestNode->map_id, node.LocX, node.LocY, node.LocZ, GetPlayer()->GetOrientation());
- }
- return;
- }
-
- uint32 destinationnode = GetPlayer()->m_taxi.NextTaxiDestination();
- if (destinationnode > 0) // if more destinations to go
- {
- // current source node for next destination
- uint32 sourcenode = GetPlayer()->m_taxi.GetTaxiSource();
-
- // Add to taximask middle hubs in taxicheat mode (to prevent having player with disabled taxicheat and not having back flight path)
- if (GetPlayer()->isTaxiCheater())
+ // far teleport case
+ if (curDestNode && curDestNode->map_id != GetPlayer()->GetMapId())
{
- if (GetPlayer()->m_taxi.SetTaximaskNode(sourcenode))
+ if (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE)
{
- WorldPacket data(SMSG_NEW_TAXI_PATH, 0);
- _player->GetSession()->SendPacket(&data);
- }
- }
+ // short preparations to continue flight
+ FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top());
- TC_LOG_DEBUG("network", "WORLD: Taxi has to go from %u to %u", sourcenode, destinationnode);
+ flight->SetCurrentNodeAfterTeleport();
+ TaxiPathNodeEntry const* node = flight->GetPath()[flight->GetCurrentNode()];
+ flight->SkipCurrentNode();
- uint32 mountDisplayId = sObjectMgr->GetTaxiMountDisplayId(sourcenode, GetPlayer()->GetTeam());
-
- uint32 path, cost;
- sObjectMgr->GetTaxiPath(sourcenode, destinationnode, path, cost);
+ GetPlayer()->TeleportTo(curDestNode->map_id, node->LocX, node->LocY, node->LocZ, GetPlayer()->GetOrientation());
+ }
+ }
- if (path && mountDisplayId)
- SendDoFlight(mountDisplayId, path, 1); // skip start fly node
- else
- GetPlayer()->m_taxi.ClearTaxiDestinations(); // clear problematic path and next
return;
}
- else
- GetPlayer()->m_taxi.ClearTaxiDestinations(); // not destinations, clear source node
+
+ // at this point only 1 node is expected (final destination)
+ if (GetPlayer()->m_taxi.GetPath().size() != 1)
+ return;
GetPlayer()->CleanupAfterTaxiFlight();
GetPlayer()->SetFallInformation(0, GetPlayer()->GetPositionZ());
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 354bbe4e269..c758d132d6e 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -2571,7 +2571,7 @@ inline void Map::setNGrid(NGridType *grid, uint32 x, uint32 y)
if (x >= MAX_NUMBER_OF_GRIDS || y >= MAX_NUMBER_OF_GRIDS)
{
TC_LOG_ERROR("maps", "map::setNGrid() Invalid grid coordinates found: %d, %d!", x, y);
- ASSERT(false);
+ ABORT();
}
i_grids[x][y] = grid;
}
@@ -2630,7 +2630,7 @@ void Map::AddObjectToSwitchList(WorldObject* obj, bool on)
else if (itr->second != on)
i_objectsToSwitch.erase(itr);
else
- ASSERT(false);
+ ABORT();
}
void Map::RemoveAllObjectsInRemoveList()
@@ -2867,7 +2867,7 @@ bool InstanceMap::CanEnter(Player* player)
if (player->GetMapRef().getTarget() == this)
{
TC_LOG_ERROR("maps", "InstanceMap::CanEnter - player %s(%u) already in map %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), GetId(), GetInstanceId(), GetSpawnMode());
- ASSERT(false);
+ ABORT();
return false;
}
@@ -2976,7 +2976,7 @@ bool InstanceMap::AddPlayerToMap(Player* player)
TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is being put into instance %s %d, %d, %d, %d, %d, %d but he is in group %s 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(), group->GetLeaderGUID().ToString().c_str(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset());
if (groupBind)
TC_LOG_ERROR("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);
+ //ABORT();
return false;
}
// bind to the group or keep using the group save
@@ -3256,7 +3256,7 @@ bool BattlegroundMap::CanEnter(Player* player)
if (player->GetMapRef().getTarget() == this)
{
TC_LOG_ERROR("maps", "BGMap::CanEnter - player %u is already in map!", player->GetGUIDLow());
- ASSERT(false);
+ ABORT();
return false;
}
diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp
index e4632bb7515..32c10cae16f 100644
--- a/src/server/game/Maps/MapInstanced.cpp
+++ b/src/server/game/Maps/MapInstanced.cpp
@@ -194,13 +194,13 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave* save,
if (!entry)
{
TC_LOG_ERROR("maps", "CreateInstance: no entry for map %d", GetId());
- ASSERT(false);
+ ABORT();
}
const InstanceTemplate* iTemplate = sObjectMgr->GetInstanceTemplate(GetId());
if (!iTemplate)
{
TC_LOG_ERROR("maps", "CreateInstance: no instance template for map %d", GetId());
- ASSERT(false);
+ ABORT();
}
// some instances only have one difficulty
@@ -279,6 +279,6 @@ bool MapInstanced::DestroyInstance(InstancedMaps::iterator &itr)
bool MapInstanced::CanEnter(Player* /*player*/)
{
- //ASSERT(false);
+ //ABORT();
return true;
}
diff --git a/src/server/game/Maps/TransportMgr.cpp b/src/server/game/Maps/TransportMgr.cpp
index dadc2eeeac3..e5815a415e7 100644
--- a/src/server/game/Maps/TransportMgr.cpp
+++ b/src/server/game/Maps/TransportMgr.cpp
@@ -112,7 +112,7 @@ void TransportMgr::GeneratePath(GameObjectTemplate const* goInfo, TransportTempl
Movement::PointsArray splinePath, allPoints;
bool mapChange = false;
for (size_t i = 0; i < path.size(); ++i)
- allPoints.push_back(G3D::Vector3(path[i].LocX, path[i].LocY, path[i].LocZ));
+ allPoints.push_back(G3D::Vector3(path[i]->LocX, path[i]->LocY, path[i]->LocZ));
// Add extra points to allow derivative calculations for all path nodes
allPoints.insert(allPoints.begin(), allPoints.front().lerp(allPoints[1], -0.2f));
@@ -128,8 +128,8 @@ void TransportMgr::GeneratePath(GameObjectTemplate const* goInfo, TransportTempl
{
if (!mapChange)
{
- TaxiPathNodeEntry const& node_i = path[i];
- if (i != path.size() - 1 && (node_i.Flags & 1 || node_i.MapID != path[i + 1].MapID))
+ TaxiPathNodeEntry const* node_i = path[i];
+ if (i != path.size() - 1 && (node_i->Flags & 1 || node_i->MapID != path[i + 1]->MapID))
{
keyFrames.back().Teleport = true;
mapChange = true;
@@ -142,7 +142,7 @@ void TransportMgr::GeneratePath(GameObjectTemplate const* goInfo, TransportTempl
k.InitialOrientation = Position::NormalizeOrientation(std::atan2(h.y, h.x) + float(M_PI));
keyFrames.push_back(k);
- splinePath.push_back(G3D::Vector3(node_i.LocX, node_i.LocY, node_i.LocZ));
+ splinePath.push_back(G3D::Vector3(node_i->LocX, node_i->LocY, node_i->LocZ));
transport->mapsUsed.insert(k.Node->MapID);
}
}
diff --git a/src/server/game/Maps/TransportMgr.h b/src/server/game/Maps/TransportMgr.h
index fff7b9d8afa..c273ea7fb15 100644
--- a/src/server/game/Maps/TransportMgr.h
+++ b/src/server/game/Maps/TransportMgr.h
@@ -37,7 +37,7 @@ typedef std::unordered_map<uint32, std::set<uint32> > TransportInstanceMap;
struct KeyFrame
{
- explicit KeyFrame(TaxiPathNodeEntry const& _node) : Index(0), Node(&_node), InitialOrientation(0.0f),
+ explicit KeyFrame(TaxiPathNodeEntry const* node) : Index(0), Node(node), InitialOrientation(0.0f),
DistSinceStop(-1.0f), DistUntilStop(-1.0f), DistFromPrev(-1.0f), TimeFrom(0.0f), TimeTo(0.0f),
Teleport(false), ArriveTime(0), DepartureTime(0), Spline(NULL), NextDistFromPrev(0.0f), NextArriveTime(0)
{
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index b69322f5720..2bcb4aeb3b3 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -563,7 +563,8 @@ void MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode)
if (path < sTaxiPathNodesByPath.size())
{
TC_LOG_DEBUG("misc", "%s taxi to (Path %u node %u)", _owner->GetName().c_str(), path, pathnode);
- FlightPathMovementGenerator* mgen = new FlightPathMovementGenerator(sTaxiPathNodesByPath[path], pathnode);
+ FlightPathMovementGenerator* mgen = new FlightPathMovementGenerator(pathnode);
+ mgen->LoadPath(_owner->ToPlayer());
Mutate(mgen, MOTION_SLOT_CONTROLLED);
}
else
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
index f91fc1985d5..8a5ac387f19 100755
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
@@ -245,17 +245,62 @@ bool WaypointMovementGenerator<Creature>::GetResetPos(Creature*, float& x, float
uint32 FlightPathMovementGenerator::GetPathAtMapEnd() const
{
- if (i_currentNode >= i_path->size())
- return i_path->size();
+ if (i_currentNode >= i_path.size())
+ return i_path.size();
- uint32 curMapId = (*i_path)[i_currentNode].MapID;
- for (uint32 i = i_currentNode; i < i_path->size(); ++i)
- {
- if ((*i_path)[i].MapID != curMapId)
+ uint32 curMapId = i_path[i_currentNode]->MapID;
+ for (uint32 i = i_currentNode; i < i_path.size(); ++i)
+ if (i_path[i]->MapID != curMapId)
return i;
- }
- return i_path->size();
+ return i_path.size();
+}
+
+#define SKIP_SPLINE_POINT_DISTANCE_SQ (40.0f * 40.0f)
+
+bool IsNodeIncludedInShortenedPath(TaxiPathNodeEntry const* p1, TaxiPathNodeEntry const* p2)
+{
+ return p1->MapID != p2->MapID || std::pow(p1->LocX - p2->LocX, 2) + std::pow(p1->LocY - p2->LocY, 2) > SKIP_SPLINE_POINT_DISTANCE_SQ;
+}
+
+void FlightPathMovementGenerator::LoadPath(Player* player)
+{
+ _pointsForPathSwitch.clear();
+ std::deque<uint32> const& taxi = player->m_taxi.GetPath();
+ for (uint32 src = 0, dst = 1; dst < taxi.size(); src = dst++)
+ {
+ uint32 path, cost;
+ sObjectMgr->GetTaxiPath(taxi[src], taxi[dst], path, cost);
+ if (path > sTaxiPathNodesByPath.size())
+ return;
+
+ TaxiPathNodeList const& nodes = sTaxiPathNodesByPath[path];
+ if (!nodes.empty())
+ {
+ TaxiPathNodeEntry const* start = nodes[0];
+ TaxiPathNodeEntry const* end = nodes[nodes.size() - 1];
+ bool passedPreviousSegmentProximityCheck = false;
+ for (uint32 i = 0; i < nodes.size(); ++i)
+ {
+ if (passedPreviousSegmentProximityCheck || !src || i_path.empty() || IsNodeIncludedInShortenedPath(i_path[i_path.size() - 1], nodes[i]))
+ {
+ if ((!src || (IsNodeIncludedInShortenedPath(start, nodes[i]) && i >= 2)) &&
+ (dst == taxi.size() - 1 || (IsNodeIncludedInShortenedPath(end, nodes[i]) && i < nodes.size() - 1)))
+ {
+ passedPreviousSegmentProximityCheck = true;
+ i_path.push_back(nodes[i]);
+ }
+ }
+ else
+ {
+ i_path.pop_back();
+ --_pointsForPathSwitch.back().PathIndex;
+ }
+ }
+ }
+
+ _pointsForPathSwitch.push_back({ uint32(i_path.size() - 1), int32(cost) });
+ }
}
void FlightPathMovementGenerator::DoInitialize(Player* player)
@@ -296,7 +341,7 @@ void FlightPathMovementGenerator::DoReset(Player* player)
uint32 end = GetPathAtMapEnd();
for (uint32 i = GetCurrentNode(); i != end; ++i)
{
- G3D::Vector3 vertice((*i_path)[i].LocX, (*i_path)[i].LocY, (*i_path)[i].LocZ);
+ G3D::Vector3 vertice(i_path[i]->LocX, i_path[i]->LocY, i_path[i]->LocZ);
init.Path().push_back(vertice);
}
init.SetFirstPointId(GetCurrentNode());
@@ -313,9 +358,21 @@ bool FlightPathMovementGenerator::DoUpdate(Player* player, uint32 /*diff*/)
bool departureEvent = true;
do
{
- DoEventIfAny(player, (*i_path)[i_currentNode], departureEvent);
+ DoEventIfAny(player, i_path[i_currentNode], departureEvent);
+ while (!_pointsForPathSwitch.empty() && _pointsForPathSwitch.front().PathIndex <= i_currentNode)
+ {
+ _pointsForPathSwitch.pop_front();
+ player->m_taxi.NextTaxiDestination();
+ if (!_pointsForPathSwitch.empty())
+ {
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, _pointsForPathSwitch.front().Cost);
+ player->ModifyMoney(-_pointsForPathSwitch.front().Cost);
+ }
+ }
+
if (pointId == i_currentNode)
break;
+
if (i_currentNode == _preloadTargetNode)
PreloadEndGrid();
i_currentNode += (uint32)departureEvent;
@@ -324,18 +381,18 @@ bool FlightPathMovementGenerator::DoUpdate(Player* player, uint32 /*diff*/)
while (true);
}
- return i_currentNode < (i_path->size()-1);
+ return i_currentNode < (i_path.size() - 1);
}
void FlightPathMovementGenerator::SetCurrentNodeAfterTeleport()
{
- if (i_path->empty())
+ if (i_path.empty() || i_currentNode >= i_path.size())
return;
- uint32 map0 = (*i_path)[0].MapID;
- for (size_t i = 1; i < i_path->size(); ++i)
+ uint32 map0 = i_path[i_currentNode]->MapID;
+ for (size_t i = i_currentNode + 1; i < i_path.size(); ++i)
{
- if ((*i_path)[i].MapID != map0)
+ if (i_path[i]->MapID != map0)
{
i_currentNode = i;
return;
@@ -343,19 +400,21 @@ void FlightPathMovementGenerator::SetCurrentNodeAfterTeleport()
}
}
-void FlightPathMovementGenerator::DoEventIfAny(Player* player, TaxiPathNodeEntry const& node, bool departure)
+void FlightPathMovementGenerator::DoEventIfAny(Player* player, TaxiPathNodeEntry const* node, bool departure)
{
- if (uint32 eventid = departure ? node.DepartureEventID : node.ArrivalEventID)
+ if (uint32 eventid = departure ? node->DepartureEventID : node->ArrivalEventID)
{
- TC_LOG_DEBUG("maps.script", "Taxi %s event %u of node %u of path %u for player %s", departure ? "departure" : "arrival", eventid, node.NodeIndex, node.PathID, player->GetName().c_str());
+ TC_LOG_DEBUG("maps.script", "Taxi %s event %u of node %u of path %u for player %s", departure ? "departure" : "arrival", eventid, node->NodeIndex, node->PathID, player->GetName().c_str());
player->GetMap()->ScriptsStart(sEventScripts, eventid, player, player);
}
}
bool FlightPathMovementGenerator::GetResetPos(Player*, float& x, float& y, float& z)
{
- const TaxiPathNodeEntry& node = (*i_path)[i_currentNode];
- x = node.LocX; y = node.LocY; z = node.LocZ;
+ TaxiPathNodeEntry const* node = i_path[i_currentNode];
+ x = node->LocX;
+ y = node->LocY;
+ z = node->LocZ;
return true;
}
@@ -363,11 +422,11 @@ void FlightPathMovementGenerator::InitEndGridInfo()
{
/*! Storage to preload flightmaster grid at end of flight. For multi-stop flights, this will
be reinitialized for each flightmaster at the end of each spline (or stop) in the flight. */
- uint32 nodeCount = (*i_path).size(); //! Number of nodes in path.
- _endMapId = (*i_path)[nodeCount - 1].MapID; //! MapId of last node
+ uint32 nodeCount = i_path.size(); //! Number of nodes in path.
+ _endMapId = i_path[nodeCount - 1]->MapID; //! MapId of last node
_preloadTargetNode = nodeCount - 3;
- _endGridX = (*i_path)[nodeCount - 1].LocX;
- _endGridY = (*i_path)[nodeCount - 1].LocY;
+ _endGridX = i_path[nodeCount - 1]->LocX;
+ _endGridY = i_path[nodeCount - 1]->LocY;
}
void FlightPathMovementGenerator::PreloadEndGrid()
@@ -378,7 +437,7 @@ void FlightPathMovementGenerator::PreloadEndGrid()
// Load the grid
if (endMap)
{
- TC_LOG_DEBUG("misc", "Preloading rid (%f, %f) for map %u at node index %u/%u", _endGridX, _endGridY, _endMapId, _preloadTargetNode, (uint32)(i_path->size()-1));
+ TC_LOG_DEBUG("misc", "Preloading rid (%f, %f) for map %u at node index %u/%u", _endGridX, _endGridY, _endMapId, _preloadTargetNode, (uint32)(i_path.size() - 1));
endMap->LoadGrid(_endGridX, _endGridY);
}
else
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
index eb8533159a9..caf76b5ea19 100755
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
@@ -27,13 +27,8 @@
#include "MovementGenerator.h"
#include "WaypointManager.h"
-#include "Path.h"
-
#include "Player.h"
-#include <vector>
-#include <set>
-
#define FLIGHT_TRAVEL_UPDATE 100
#define STOP_TIME_FOR_PLAYER 3 * MINUTE * IN_MILLISECONDS // 3 Minutes
#define TIMEDIFF_NEXT_WP 250
@@ -42,11 +37,9 @@ template<class T, class P>
class PathMovementBase
{
public:
- PathMovementBase() : i_path(NULL), i_currentNode(0) { }
+ PathMovementBase() : i_path(), i_currentNode(0) { }
virtual ~PathMovementBase() { };
- // template pattern, not defined .. override required
- void LoadPath(T &);
uint32 GetCurrentNode() const { return i_currentNode; }
protected:
@@ -110,30 +103,30 @@ class WaypointMovementGenerator<Creature> : public MovementGeneratorMedium< Crea
* and hence generates ground and activities for the player.
*/
class FlightPathMovementGenerator : public MovementGeneratorMedium< Player, FlightPathMovementGenerator >,
- public PathMovementBase<Player, TaxiPathNodeList const*>
+ public PathMovementBase<Player, TaxiPathNodeList>
{
public:
- explicit FlightPathMovementGenerator(TaxiPathNodeList const& pathnodes, uint32 startNode = 0)
+ explicit FlightPathMovementGenerator(uint32 startNode = 0)
{
- i_path = &pathnodes;
i_currentNode = startNode;
_endGridX = 0.0f;
_endGridY = 0.0f;
_endMapId = 0;
_preloadTargetNode = 0;
}
+ void LoadPath(Player* player);
void DoInitialize(Player*);
void DoReset(Player*);
void DoFinalize(Player*);
bool DoUpdate(Player*, uint32);
MovementGeneratorType GetMovementGeneratorType() const override { return FLIGHT_MOTION_TYPE; }
- TaxiPathNodeList const& GetPath() { return *i_path; }
+ TaxiPathNodeList const& GetPath() { return i_path; }
uint32 GetPathAtMapEnd() const;
- bool HasArrived() const { return (i_currentNode >= i_path->size()); }
+ bool HasArrived() const { return (i_currentNode >= i_path.size()); }
void SetCurrentNodeAfterTeleport();
void SkipCurrentNode() { ++i_currentNode; }
- void DoEventIfAny(Player* player, TaxiPathNodeEntry const& node, bool departure);
+ void DoEventIfAny(Player* player, TaxiPathNodeEntry const* node, bool departure);
bool GetResetPos(Player*, float& x, float& y, float& z);
@@ -141,9 +134,18 @@ class FlightPathMovementGenerator : public MovementGeneratorMedium< Player, Flig
void PreloadEndGrid();
private:
- float _endGridX; //! X coord of last node location
- float _endGridY; //! Y coord of last node location
- uint32 _endMapId; //! map Id of last node location
- uint32 _preloadTargetNode; //! node index where preloading starts
+
+ float _endGridX; //! X coord of last node location
+ float _endGridY; //! Y coord of last node location
+ uint32 _endMapId; //! map Id of last node location
+ uint32 _preloadTargetNode; //! node index where preloading starts
+
+ struct TaxiNodeChangeInfo
+ {
+ uint32 PathIndex;
+ int32 Cost;
+ };
+
+ std::deque<TaxiNodeChangeInfo> _pointsForPathSwitch; //! node indexes and costs where TaxiPath changes
};
#endif
diff --git a/src/server/game/Movement/Spline/Spline.h b/src/server/game/Movement/Spline/Spline.h
index c8b7a19c943..59f514bed75 100644
--- a/src/server/game/Movement/Spline/Spline.h
+++ b/src/server/game/Movement/Spline/Spline.h
@@ -82,7 +82,7 @@ protected:
typedef void (SplineBase::*InitMethtod)(const Vector3*, index_type, index_type);
static InitMethtod initializers[ModesEnd];
- void UninitializedSpline() const { ASSERT(false);}
+ void UninitializedSpline() const { ABORT();}
public:
diff --git a/src/server/game/Movement/Waypoints/Path.h b/src/server/game/Movement/Waypoints/Path.h
deleted file mode 100644
index bb8abc37eb3..00000000000
--- a/src/server/game/Movement/Waypoints/Path.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TRINITYCORE_PATH_H
-#define TRINITYCORE_PATH_H
-
-#include "Common.h"
-#include <deque>
-
-struct PathNode
-{
- PathNode(): x(0.0f), y(0.0f), z(0.0f) { }
- PathNode(float _x, float _y, float _z): x(_x), y(_y), z(_z) { }
- float x, y, z;
-};
-template<typename PathElem, typename PathNode = PathElem>
-
-class Path
-{
- public:
- size_t size() const { return i_nodes.size(); }
- bool empty() const { return i_nodes.empty(); }
- void resize(unsigned int sz) { i_nodes.resize(sz); }
- void clear() { i_nodes.clear(); }
- void erase(uint32 idx) { i_nodes.erase(i_nodes.begin()+idx); }
- void crop(unsigned int start, unsigned int end)
- {
- while (start && !i_nodes.empty())
- {
- i_nodes.pop_front();
- --start;
- }
-
- while (end && !i_nodes.empty())
- {
- i_nodes.pop_back();
- --end;
- }
- }
-
- float GetTotalLength(uint32 start, uint32 end) const
- {
- float len = 0.0f;
- for (uint32 idx=start+1; idx < end; ++idx)
- {
- PathNode const& node = i_nodes[idx];
- PathNode const& prev = i_nodes[idx-1];
- float xd = node.x - prev.x;
- float yd = node.y - prev.y;
- float zd = node.z - prev.z;
- len += std::sqrt(xd*xd + yd*yd + zd*zd);
- }
- return len;
- }
-
- float GetTotalLength() const { return GetTotalLength(0, size()); }
-
- float GetPassedLength(uint32 curnode, float x, float y, float z) const
- {
- float len = GetTotalLength(0, curnode);
-
- if (curnode > 0)
- {
- PathNode const& node = i_nodes[curnode-1];
- float xd = x - node.x;
- float yd = y - node.y;
- float zd = z - node.z;
- len += std::sqrt(xd*xd + yd*yd + zd*zd);
- }
-
- return len;
- }
-
- PathNode& operator[](size_t idx) { return i_nodes[idx]; }
- PathNode const& operator[](size_t idx) const { return i_nodes[idx]; }
-
- void set(size_t idx, PathElem elem) { i_nodes[idx] = elem; }
-
- protected:
- std::deque<PathElem> i_nodes;
-};
-
-typedef Path<PathNode> SimplePath;
-
-#endif
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index eea0fd72e8b..58bc4915d3f 100644
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -29,21 +29,21 @@ Quest::Quest(Field* questRecord)
ZoneOrSort = questRecord[4].GetInt16();
Type = questRecord[5].GetUInt16();
SuggestedPlayers = questRecord[6].GetUInt8();
- LimitTime = questRecord[7].GetUInt32();
- RequiredRaces = questRecord[8].GetUInt16();
+ TimeAllowed = questRecord[7].GetUInt32();
+ AllowableRaces = questRecord[8].GetUInt16();
RequiredFactionId1 = questRecord[9].GetUInt16();
RequiredFactionId2 = questRecord[10].GetUInt16();
RequiredFactionValue1 = questRecord[11].GetInt32();
RequiredFactionValue2 = questRecord[12].GetInt32();
- NextQuestIdChain = questRecord[13].GetUInt32();
- RewardXPId = questRecord[14].GetUInt8();
- RewardOrRequiredMoney = questRecord[15].GetInt32();
- RewardMoneyMaxLevel = questRecord[16].GetUInt32();
- RewardSpell = questRecord[17].GetUInt32();
- RewardSpellCast = questRecord[18].GetInt32();
+ RewardNextQuest = questRecord[13].GetUInt32();
+ RewardXPDifficulty = questRecord[14].GetUInt8();
+ RewardMoney = questRecord[15].GetInt32();
+ RewardBonusMoney = questRecord[16].GetUInt32();
+ RewardDisplaySpell = questRecord[17].GetUInt32();
+ RewardSpell = questRecord[18].GetInt32();
RewardHonor = questRecord[19].GetUInt32();
- RewardHonorMultiplier = questRecord[20].GetFloat();
- SourceItemId = questRecord[21].GetUInt32();
+ RewardKillHonor = questRecord[20].GetFloat();
+ StartItem = questRecord[21].GetUInt32();
Flags = questRecord[22].GetUInt32();
RewardTitleId = questRecord[23].GetUInt8();
RequiredPlayerKills = questRecord[24].GetUInt8();
@@ -69,14 +69,14 @@ Quest::Quest(Field* questRecord)
RewardFactionValueIdOverride[i] = questRecord[49+i*3].GetInt32();
}
- PointMapId = questRecord[62].GetUInt16();
- PointX = questRecord[63].GetFloat();
- PointY = questRecord[64].GetFloat();
- PointOption = questRecord[65].GetUInt32();
+ POIContinent = questRecord[62].GetUInt16();
+ POIx = questRecord[63].GetFloat();
+ POIy = questRecord[64].GetFloat();
+ POIPriority = questRecord[65].GetUInt32();
Title = questRecord[66].GetString();
Objectives = questRecord[67].GetString();
Details = questRecord[68].GetString();
- EndText = questRecord[69].GetString();
+ AreaDescription = questRecord[69].GetString();
CompletedText = questRecord[70].GetString();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
@@ -86,10 +86,10 @@ Quest::Quest(Field* questRecord)
RequiredNpcOrGoCount[i] = questRecord[75+i].GetUInt16();
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
- RequiredSourceItemId[i] = questRecord[79+i].GetUInt32();
+ ItemDrop[i] = questRecord[79+i].GetUInt32();
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
- RequiredSourceItemCount[i] = questRecord[83+i].GetUInt16();
+ ItemDropQuantity[i] = questRecord[83+i].GetUInt16();
for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
RequiredItemId[i] = questRecord[87+i].GetUInt32();
@@ -102,6 +102,9 @@ Quest::Quest(Field* questRecord)
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
ObjectiveText[i] = questRecord[100+i].GetString();
+ EmoteOnIncomplete = 0;
+ EmoteOnComplete = 0;
+
//int32 VerifiedBuild = questRecord[104].GetInt32();
_reqItemsCount = 0;
@@ -169,7 +172,7 @@ void Quest::LoadQuestTemplateAddon(Field* fields)
RequiredMaxRepFaction = fields[12].GetUInt16();
RequiredMinRepValue = fields[13].GetInt32();
RequiredMaxRepValue = fields[14].GetInt32();
- SourceItemIdCount = fields[15].GetUInt8();
+ StartItemCount = fields[15].GetUInt8();
SpecialFlags = fields[16].GetUInt8();
if (SpecialFlags & QUEST_SPECIAL_FLAGS_AUTO_ACCEPT)
@@ -191,7 +194,7 @@ uint32 Quest::XPValue(Player* player) const
else if (diffFactor > 10)
diffFactor = 10;
- uint32 xp = diffFactor * xpentry->Exp[RewardXPId] / 10;
+ uint32 xp = diffFactor * xpentry->Exp[RewardXPDifficulty] / 10;
if (xp <= 100)
xp = 5 * ((xp + 2) / 5);
else if (xp <= 500)
@@ -210,11 +213,11 @@ uint32 Quest::XPValue(Player* player) const
int32 Quest::GetRewOrReqMoney() const
{
// RequiredMoney: the amount is the negative copper sum.
- if (RewardOrRequiredMoney <= 0)
- return RewardOrRequiredMoney;
+ if (RewardMoney <= 0)
+ return RewardMoney;
// RewardMoney: the positive amount
- return int32(RewardOrRequiredMoney * sWorld->getRate(RATE_MONEY_QUEST));
+ return int32(RewardMoney * sWorld->getRate(RATE_MONEY_QUEST));
}
uint32 Quest::GetRewMoneyMaxLevel() const
@@ -224,7 +227,7 @@ uint32 Quest::GetRewMoneyMaxLevel() const
return 0;
// Else, return the rewarded copper sum modified by the rate
- return uint32(RewardMoneyMaxLevel * sWorld->getRate(RATE_MONEY_MAX_LEVEL_QUEST));
+ return uint32(RewardBonusMoney * sWorld->getRate(RATE_MONEY_MAX_LEVEL_QUEST));
}
bool Quest::IsAutoAccept() const
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index 78fd065e9bd..91b4a3181f5 100644
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -182,7 +182,7 @@ struct QuestLocale
StringVector Objectives;
StringVector OfferRewardText;
StringVector RequestItemsText;
- StringVector EndText;
+ StringVector AreaDescription;
StringVector CompletedText;
std::vector< StringVector > ObjectiveText;
};
@@ -217,7 +217,7 @@ class Quest
int32 GetQuestLevel() const { return Level; }
uint32 GetType() const { return Type; }
uint32 GetRequiredClasses() const { return RequiredClasses; }
- uint32 GetRequiredRaces() const { return RequiredRaces; }
+ uint32 GetAllowableRaces() const { return AllowableRaces; }
uint32 GetRequiredSkill() const { return RequiredSkillId; }
uint32 GetRequiredSkillValue() const { return RequiredSkillPoints; }
uint32 GetRepObjectiveFaction() const { return RequiredFactionId1; }
@@ -229,38 +229,38 @@ class Quest
uint32 GetRequiredMaxRepFaction() const { return RequiredMaxRepFaction; }
int32 GetRequiredMaxRepValue() const { return RequiredMaxRepValue; }
uint32 GetSuggestedPlayers() const { return SuggestedPlayers; }
- uint32 GetLimitTime() const { return LimitTime; }
+ uint32 GetTimeAllowed() const { return TimeAllowed; }
int32 GetPrevQuestId() const { return PrevQuestId; }
int32 GetNextQuestId() const { return NextQuestId; }
int32 GetExclusiveGroup() const { return ExclusiveGroup; }
- uint32 GetNextQuestInChain() const { return NextQuestIdChain; }
+ uint32 GetNextQuestInChain() const { return RewardNextQuest; }
uint32 GetCharTitleId() const { return RewardTitleId; }
uint32 GetPlayersSlain() const { return RequiredPlayerKills; }
uint32 GetBonusTalents() const { return RewardTalents; }
int32 GetRewArenaPoints() const {return RewardArenaPoints; }
- uint32 GetXPId() const { return RewardXPId; }
- uint32 GetSrcItemId() const { return SourceItemId; }
- uint32 GetSrcItemCount() const { return SourceItemIdCount; }
+ uint32 GetXPId() const { return RewardXPDifficulty; }
+ uint32 GetSrcItemId() const { return StartItem; }
+ uint32 GetSrcItemCount() const { return StartItemCount; }
uint32 GetSrcSpell() const { return SourceSpellid; }
std::string const& GetTitle() const { return Title; }
std::string const& GetDetails() const { return Details; }
std::string const& GetObjectives() const { return Objectives; }
std::string const& GetOfferRewardText() const { return OfferRewardText; }
std::string const& GetRequestItemsText() const { return RequestItemsText; }
- std::string const& GetEndText() const { return EndText; }
+ std::string const& GetAreaDescription() const { return AreaDescription; }
std::string const& GetCompletedText() const { return CompletedText; }
int32 GetRewOrReqMoney() const;
uint32 GetRewHonorAddition() const { return RewardHonor; }
- float GetRewHonorMultiplier() const { return RewardHonorMultiplier; }
+ float GetRewHonorMultiplier() const { return RewardKillHonor; }
uint32 GetRewMoneyMaxLevel() const; // use in XP calculation at client
- uint32 GetRewSpell() const { return RewardSpell; }
- int32 GetRewSpellCast() const { return RewardSpellCast; }
+ uint32 GetRewSpell() const { return RewardDisplaySpell; }
+ int32 GetRewSpellCast() const { return RewardSpell; }
uint32 GetRewMailTemplateId() const { return RewardMailTemplateId; }
uint32 GetRewMailDelaySecs() const { return RewardMailDelay; }
- uint32 GetPointMapId() const { return PointMapId; }
- float GetPointX() const { return PointX; }
- float GetPointY() const { return PointY; }
- uint32 GetPointOpt() const { return PointOption; }
+ uint32 GetPOIContinent() const { return POIContinent; }
+ float GetPOIx() const { return POIx; }
+ float GetPOIy() const { return POIy; }
+ uint32 GetPointOpt() const { return POIPriority; }
uint32 GetIncompleteEmote() const { return EmoteOnIncomplete; }
uint32 GetCompleteEmote() const { return EmoteOnComplete; }
bool IsRepeatable() const { return SpecialFlags & QUEST_SPECIAL_FLAGS_REPEATABLE; }
@@ -281,8 +281,8 @@ class Quest
std::string ObjectiveText[QUEST_OBJECTIVES_COUNT];
uint32 RequiredItemId[QUEST_ITEM_OBJECTIVES_COUNT];
uint32 RequiredItemCount[QUEST_ITEM_OBJECTIVES_COUNT];
- uint32 RequiredSourceItemId[QUEST_SOURCE_ITEM_IDS_COUNT];
- uint32 RequiredSourceItemCount[QUEST_SOURCE_ITEM_IDS_COUNT];
+ uint32 ItemDrop[QUEST_SOURCE_ITEM_IDS_COUNT];
+ uint32 ItemDropQuantity[QUEST_SOURCE_ITEM_IDS_COUNT];
int32 RequiredNpcOrGo[QUEST_OBJECTIVES_COUNT]; // >0 Creature <0 Gameobject
uint32 RequiredNpcOrGoCount[QUEST_OBJECTIVES_COUNT];
uint32 RewardChoiceItemId[QUEST_REWARD_CHOICES_COUNT];
@@ -322,38 +322,38 @@ class Quest
uint32 MinLevel;
int32 Level;
uint32 Type;
- uint32 RequiredRaces;
+ uint32 AllowableRaces;
uint32 RequiredFactionId1;
int32 RequiredFactionValue1;
uint32 RequiredFactionId2;
int32 RequiredFactionValue2;
uint32 SuggestedPlayers;
- uint32 LimitTime;
+ uint32 TimeAllowed;
uint32 Flags;
uint32 RewardTitleId;
uint32 RequiredPlayerKills;
uint32 RewardTalents;
int32 RewardArenaPoints;
- uint32 NextQuestIdChain;
- uint32 RewardXPId;
- uint32 SourceItemId;
+ uint32 RewardNextQuest;
+ uint32 RewardXPDifficulty;
+ uint32 StartItem;
std::string Title;
std::string Details;
std::string Objectives;
std::string OfferRewardText;
std::string RequestItemsText;
- std::string EndText;
+ std::string AreaDescription;
std::string CompletedText;
uint32 RewardHonor;
- float RewardHonorMultiplier;
- int32 RewardOrRequiredMoney;
- uint32 RewardMoneyMaxLevel;
- uint32 RewardSpell;
- int32 RewardSpellCast;
- uint32 PointMapId;
- float PointX;
- float PointY;
- uint32 PointOption;
+ float RewardKillHonor;
+ int32 RewardMoney;
+ uint32 RewardBonusMoney;
+ uint32 RewardDisplaySpell;
+ int32 RewardSpell;
+ uint32 POIContinent;
+ float POIx;
+ float POIy;
+ uint32 POIPriority;
uint32 EmoteOnIncomplete;
uint32 EmoteOnComplete;
@@ -372,7 +372,7 @@ class Quest
int32 RequiredMinRepValue = 0;
uint32 RequiredMaxRepFaction = 0;
int32 RequiredMaxRepValue = 0;
- uint32 SourceItemIdCount = 0;
+ uint32 StartItemCount = 0;
uint32 SpecialFlags = 0; // custom flags, not sniffed/WDB
};
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index aed829a7b57..0ece05f1d93 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -108,7 +108,7 @@ class ScriptRegistry
TC_LOG_ERROR("scripts", "Script '%s' already assigned with the same script name, so the script can't work.",
script->GetName().c_str());
- ASSERT(false); // Error that should be fixed ASAP.
+ ABORT(); // Error that should be fixed ASAP.
}
}
else
@@ -960,7 +960,7 @@ bool ScriptMgr::OnAreaTrigger(Player* player, AreaTriggerEntry const* trigger)
Battleground* ScriptMgr::CreateBattleground(BattlegroundTypeId /*typeId*/)
{
/// @todo Implement script-side battlegrounds.
- ASSERT(false);
+ ABORT();
return NULL;
}
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 4eea5eed03d..e380373f4c4 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -323,7 +323,7 @@ Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owne
aura = new DynObjAura(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID);
break;
default:
- ASSERT(false);
+ ABORT();
return NULL;
}
// aura can be removed in Unit::_AddAura call
@@ -437,7 +437,7 @@ void Aura::_UnapplyForTarget(Unit* target, Unit* caster, AuraApplication * auraA
{
TC_LOG_ERROR("spells", "Aura::_UnapplyForTarget, target:%u, caster:%u, spell:%u was not found in owners application map!",
target->GetGUIDLow(), caster ? caster->GetGUIDLow() : 0, auraApp->GetBase()->GetSpellInfo()->Id);
- ASSERT(false);
+ ABORT();
}
// aura has to be already applied
@@ -528,7 +528,7 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply)
else
{
// ok, we have one unit twice in target map (impossible, but...)
- ASSERT(false);
+ ABORT();
}
}
@@ -586,7 +586,7 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply)
TC_LOG_FATAL("spells", "Aura %u: Owner %s (map %u) is not in the same map as target %s (map %u).", GetSpellInfo()->Id,
GetOwner()->GetName().c_str(), GetOwner()->IsInWorld() ? GetOwner()->GetMap()->GetId() : uint32(-1),
itr->first->GetName().c_str(), itr->first->IsInWorld() ? itr->first->GetMap()->GetId() : uint32(-1));
- ASSERT(false);
+ ABORT();
}
itr->first->_CreateAuraApplication(this, itr->second);
++itr;
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 03f14d1cdc8..ca6946554d4 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -6586,7 +6586,7 @@ SpellEvent::~SpellEvent()
{
TC_LOG_ERROR("spells", "~SpellEvent: %s %u tried to delete non-deletable spell %u. Was not deleted, causes memory leak.",
(m_Spell->GetCaster()->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), m_Spell->GetCaster()->GetGUIDLow(), m_Spell->m_spellInfo->Id);
- ASSERT(false);
+ ABORT();
}
}
@@ -7044,7 +7044,7 @@ bool Spell::CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMo
hookType = SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET;
break;
default:
- ASSERT(false);
+ ABORT();
return false;
}
(*scritr)->_PrepareScriptCall(hookType);
diff --git a/src/server/scripts/Commands/cs_lfg.cpp b/src/server/scripts/Commands/cs_lfg.cpp
index d1662f3a97c..8bb64a454d2 100644
--- a/src/server/scripts/Commands/cs_lfg.cpp
+++ b/src/server/scripts/Commands/cs_lfg.cpp
@@ -150,7 +150,7 @@ public:
static bool HandleLfgQueueInfoCommand(ChatHandler* handler, char const* args)
{
- handler->SendSysMessage(sLFGMgr->DumpQueueInfo(*args != '\0').c_str());
+ handler->SendSysMessage(sLFGMgr->DumpQueueInfo(*args != '\0').c_str(), true);
return true;
}
diff --git a/src/server/scripts/Commands/cs_ticket.cpp b/src/server/scripts/Commands/cs_ticket.cpp
index 5fc3cc618e5..b609dfe18dd 100644
--- a/src/server/scripts/Commands/cs_ticket.cpp
+++ b/src/server/scripts/Commands/cs_ticket.cpp
@@ -113,7 +113,7 @@ public:
// If assigned to different player other than current, leave
//! Console can override though
- Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : NULL;
+ Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : nullptr;
if (player && ticket->IsAssignedNotTo(player->GetGUID()))
{
handler->PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->GetId(), target.c_str());
@@ -146,7 +146,7 @@ public:
// Ticket should be assigned to the player who tries to close it.
// Console can override though
- Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : NULL;
+ Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : nullptr;
if (player && ticket->IsAssignedNotTo(player->GetGUID()))
{
handler->PSendSysMessage(LANG_COMMAND_TICKETCANNOTCLOSE, ticket->GetId());
@@ -190,7 +190,7 @@ public:
// Cannot comment ticket assigned to someone else
//! Console excluded
- Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : NULL;
+ Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : nullptr;
if (player && ticket->IsAssignedNotTo(player->GetGUID()))
{
handler->PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->GetId());
@@ -220,7 +220,9 @@ public:
if (!*args)
return false;
- uint32 ticketId = atoi(args);
+ char* ticketIdStr = strtok((char*)args, " ");
+ uint32 ticketId = atoi(ticketIdStr);
+
GmTicket* ticket = sTicketMgr->GetTicket(ticketId);
if (!ticket || ticket->IsClosed() || ticket->IsCompleted())
{
@@ -228,6 +230,21 @@ public:
return true;
}
+ char* response = strtok(NULL, "\n");
+ if (response)
+ {
+ // Cannot add response to ticket, assigned to someone else
+ //! Console excluded
+ Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : nullptr;
+ if (player && ticket->IsAssignedNotTo(player->GetGUID()))
+ {
+ handler->PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->GetId());
+ return true;
+ }
+
+ ticket->AppendResponse(response);
+ }
+
if (Player* player = ticket->GetPlayer())
ticket->SendResponse(player->GetSession());
@@ -476,7 +493,7 @@ public:
// Cannot add response to ticket, assigned to someone else
//! Console excluded
- Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : NULL;
+ Player* player = handler->GetSession() ? handler->GetSession()->GetPlayer() : nullptr;
if (player && ticket->IsAssignedNotTo(player->GetGUID()))
{
handler->PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->GetId());
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp b/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp
index f5842181358..7c85c5f73b9 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_patchwerk.cpp
@@ -21,7 +21,7 @@
enum Spells
{
- SPELL_HATEFUL_STRIKE = 41926,
+ SPELL_HATEFUL_STRIKE = 28308,
SPELL_FRENZY = 28131,
SPELL_BERSERK = 26662,
SPELL_SLIME_BOLT = 32309
@@ -33,7 +33,7 @@ enum Yells
SAY_SLAY = 1,
SAY_DEATH = 2,
EMOTE_BERSERK = 3,
- EMOTE_ENRAGE = 4
+ EMOTE_FRENZY = 4
};
enum Events
@@ -49,6 +49,11 @@ enum Misc
ACHIEV_MAKE_QUICK_WERK_OF_HIM_STARTING_EVENT = 10286
};
+enum HatefulThreatAmounts
+{
+ HATEFUL_THREAT_AMT = 1000,
+};
+
class boss_patchwerk : public CreatureScript
{
public:
@@ -92,8 +97,8 @@ public:
_EnterCombat();
Enraged = false;
Talk(SAY_AGGRO);
- events.ScheduleEvent(EVENT_HATEFUL, 1000);
- events.ScheduleEvent(EVENT_BERSERK, 360000);
+ events.ScheduleEvent(EVENT_HATEFUL, 1 * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_BERSERK, 6 * MINUTE * IN_MILLISECONDS);
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_MAKE_QUICK_WERK_OF_HIM_STARTING_EVENT);
}
@@ -111,37 +116,68 @@ public:
{
case EVENT_HATEFUL:
{
- //Cast Hateful strike on the player with the highest
- //amount of HP within melee distance
- uint32 MostHP = 0;
- Unit* pMostHPTarget = NULL;
+ // Hateful Strike targets the highest non-MT threat in melee range on 10man
+ // and the higher HP target out of the two highest non-MT threats in melee range on 25man
+ float MostThreat = 0.0f;
+ Unit* secondThreatTarget = NULL;
+ Unit* thirdThreatTarget = NULL;
+
std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin();
for (; i != me->getThreatManager().getThreatList().end(); ++i)
- {
+ { // find second highest
Unit* target = (*i)->getTarget();
- if (target->IsAlive() && target != me->GetVictim() && target->GetHealth() > MostHP && me->IsWithinMeleeRange(target))
+ if (target->IsAlive() && target != me->GetVictim() && (*i)->getThreat() >= MostThreat && me->IsWithinMeleeRange(target))
+ {
+ MostThreat = (*i)->getThreat();
+ secondThreatTarget = target;
+ }
+ }
+
+ if (secondThreatTarget && Is25ManRaid())
+ { // find third highest
+ MostThreat = 0.0f;
+ i = me->getThreatManager().getThreatList().begin();
+ for (; i != me->getThreatManager().getThreatList().end(); ++i)
{
- MostHP = target->GetHealth();
- pMostHPTarget = target;
+ Unit* target = (*i)->getTarget();
+ if (target->IsAlive() && target != me->GetVictim() && target != secondThreatTarget && (*i)->getThreat() >= MostThreat && me->IsWithinMeleeRange(target))
+ {
+ MostThreat = (*i)->getThreat();
+ thirdThreatTarget = target;
+ }
}
}
- if (!pMostHPTarget)
- pMostHPTarget = me->GetVictim();
+ Unit* pHatefulTarget = NULL;
+ if (!thirdThreatTarget)
+ pHatefulTarget = secondThreatTarget;
+ else if (secondThreatTarget)
+ pHatefulTarget = (secondThreatTarget->GetHealth() < thirdThreatTarget->GetHealth()) ? thirdThreatTarget : secondThreatTarget;
+
+ if (!pHatefulTarget)
+ pHatefulTarget = me->GetVictim();
+
+ DoCast(pHatefulTarget, SPELL_HATEFUL_STRIKE, true);
- DoCast(pMostHPTarget, SPELL_HATEFUL_STRIKE, true);
+ // add threat to highest threat targets
+ if (me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim()))
+ me->getThreatManager().addThreat(me->GetVictim(), HATEFUL_THREAT_AMT);
+ if (secondThreatTarget)
+ me->getThreatManager().addThreat(secondThreatTarget, HATEFUL_THREAT_AMT);
+ if (thirdThreatTarget)
+ me->getThreatManager().addThreat(thirdThreatTarget, HATEFUL_THREAT_AMT); // this will only ever be used in 25m
- events.ScheduleEvent(EVENT_HATEFUL, 1000);
+ events.ScheduleEvent(EVENT_HATEFUL, 1 * IN_MILLISECONDS);
break;
}
case EVENT_BERSERK:
DoCast(me, SPELL_BERSERK, true);
Talk(EMOTE_BERSERK);
- events.ScheduleEvent(EVENT_SLIME, 2000);
+ events.ScheduleEvent(EVENT_SLIME, 2 * IN_MILLISECONDS);
break;
case EVENT_SLIME:
DoCastVictim(SPELL_SLIME_BOLT, true);
- events.ScheduleEvent(EVENT_SLIME, 2000);
+ events.ScheduleEvent(EVENT_SLIME, 2 * IN_MILLISECONDS);
break;
}
}
@@ -149,7 +185,7 @@ public:
if (!Enraged && HealthBelowPct(5))
{
DoCast(me, SPELL_FRENZY, true);
- Talk(EMOTE_ENRAGE);
+ Talk(EMOTE_FRENZY);
Enraged = true;
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp
index ee482c23d1b..02a7aa570e5 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp
@@ -43,6 +43,7 @@ enum Spells
SPELL_BERSERK = 26662,
SPELL_DIES = 29357,
SPELL_CHILL = 28547,
+ SPELL_CHECK_RESISTS = 60539,
};
enum Phases
@@ -67,7 +68,8 @@ enum Events
EVENT_EXPLOSION,
EVENT_LAND,
EVENT_GROUND,
- EVENT_BIRTH
+ EVENT_BIRTH,
+ EVENT_CHECK_RESISTS
};
enum Misc
@@ -90,10 +92,9 @@ class boss_sapphiron : public CreatureScript
struct boss_sapphironAI : public BossAI
{
boss_sapphironAI(Creature* creature) :
- BossAI(creature, BOSS_SAPPHIRON), _map(me->GetMap())
+ BossAI(creature, BOSS_SAPPHIRON), _iceboltCount(0), _map(me->GetMap())
{
Initialize();
- _iceboltCount = 0;
}
void Initialize()
@@ -101,7 +102,6 @@ class boss_sapphiron : public CreatureScript
_phase = PHASE_NULL;
_canTheHundredClub = true;
- _checkFrostResistTimer = 5 * IN_MILLISECONDS;
}
void InitializeAI() override
@@ -123,7 +123,16 @@ class boss_sapphiron : public CreatureScript
_Reset();
if (_phase == PHASE_FLIGHT)
+ {
ClearIceBlock();
+ me->SetReactState(REACT_AGGRESSIVE);
+ if (me->IsHovering())
+ {
+ me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
+ me->SetHover(false);
+ }
+ me->SetDisableGravity(false);
+ }
Initialize();
}
@@ -134,22 +143,30 @@ class boss_sapphiron : public CreatureScript
me->CastSpell(me, SPELL_FROST_AURA, true);
+ DoCast(me, SPELL_CHECK_RESISTS);
+ events.ScheduleEvent(EVENT_CHECK_RESISTS, 30 * IN_MILLISECONDS);
events.ScheduleEvent(EVENT_BERSERK, 15 * MINUTE * IN_MILLISECONDS);
EnterPhaseGround();
-
- CheckPlayersFrostResist();
}
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
{
- if (spell->Id == SPELL_ICEBOLT)
+ switch(spell->Id)
{
- IceBlockMap::iterator itr = _iceblocks.find(target->GetGUID());
- if (itr != _iceblocks.end() && !itr->second)
+ case SPELL_ICEBOLT:
{
- if (GameObject* iceblock = me->SummonGameObject(GO_ICEBLOCK, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, 0, 0, 0, 0, 25))
- itr->second = iceblock->GetGUID();
+ IceBlockMap::iterator itr = _iceblocks.find(target->GetGUID());
+ if (itr != _iceblocks.end() && !itr->second)
+ {
+ if (GameObject* iceblock = me->SummonGameObject(GO_ICEBLOCK, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, 0, 0, 0, 0, 25))
+ itr->second = iceblock->GetGUID();
+ }
+ break;
}
+ case SPELL_CHECK_RESISTS:
+ if (target && target->GetResistance(SPELL_SCHOOL_FROST) > MAX_FROST_RESISTANCE)
+ _canTheHundredClub = false;
+ break;
}
}
@@ -157,8 +174,6 @@ class boss_sapphiron : public CreatureScript
{
_JustDied();
me->CastSpell(me, SPELL_DIES, true);
-
- CheckPlayersFrostResist();
}
void MovementInform(uint32 /*type*/, uint32 id) override
@@ -176,22 +191,6 @@ class boss_sapphiron : public CreatureScript
}
}
- void CheckPlayersFrostResist()
- {
- if (_canTheHundredClub && _map && _map->IsRaid())
- {
- Map::PlayerList const &players = _map->GetPlayers();
- for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
- {
- if (itr->GetSource()->GetResistance(SPELL_SCHOOL_FROST) > MAX_FROST_RESISTANCE)
- {
- _canTheHundredClub = false;
- break;
- }
- }
- }
- }
-
void EnterPhaseGround()
{
_phase = PHASE_GROUND;
@@ -235,23 +234,16 @@ class boss_sapphiron : public CreatureScript
if ((_phase != PHASE_BIRTH && !UpdateVictim()) || !CheckInRoom())
return;
- if (_canTheHundredClub)
- {
- if (_checkFrostResistTimer <= diff)
- {
- CheckPlayersFrostResist();
- _checkFrostResistTimer = 5 * IN_MILLISECONDS;
- }
- else
- _checkFrostResistTimer -= diff;
- }
-
if (_phase == PHASE_GROUND)
{
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
+ case EVENT_CHECK_RESISTS:
+ DoCast(me, SPELL_CHECK_RESISTS);
+ events.ScheduleEvent(EVENT_CHECK_RESISTS, 30 * IN_MILLISECONDS);
+ return;
case EVENT_BERSERK:
Talk(EMOTE_ENRAGE);
DoCast(me, SPELL_BERSERK);
@@ -270,7 +262,6 @@ class boss_sapphiron : public CreatureScript
return;
case EVENT_BLIZZARD:
{
- //DoCastAOE(SPELL_SUMMON_BLIZZARD);
if (Creature* summon = DoSummon(NPC_BLIZZARD, me, 0.0f, urand(25, 30) * IN_MILLISECONDS, TEMPSUMMON_TIMED_DESPAWN))
summon->GetMotionMaster()->MoveRandom(40);
events.ScheduleEvent(EVENT_BLIZZARD, RAID_MODE(20, 7) * IN_MILLISECONDS, 0, PHASE_GROUND);
@@ -300,9 +291,14 @@ class boss_sapphiron : public CreatureScript
{
switch (eventId)
{
+ case EVENT_CHECK_RESISTS:
+ DoCast(me, SPELL_CHECK_RESISTS);
+ events.ScheduleEvent(EVENT_CHECK_RESISTS, 30 * IN_MILLISECONDS);
+ return;
case EVENT_LIFTOFF:
Talk(EMOTE_AIR_PHASE);
me->SetDisableGravity(true);
+ me->SetHover(true);
events.ScheduleEvent(EVENT_ICEBOLT, 1500);
_iceboltCount = RAID_MODE(2, 3);
return;
@@ -346,6 +342,7 @@ class boss_sapphiron : public CreatureScript
case EVENT_LAND:
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
Talk(EMOTE_GROUND_PHASE);
+ me->SetHover(false);
me->SetDisableGravity(false);
events.ScheduleEvent(EVENT_GROUND, 1500);
return;
@@ -406,7 +403,6 @@ class boss_sapphiron : public CreatureScript
uint32 _iceboltCount;
IceBlockMap _iceblocks;
bool _canTheHundredClub;
- uint32 _checkFrostResistTimer;
Map* _map;
};
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
index 61d64413178..b31436f656a 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
@@ -97,9 +97,6 @@ enum Creatures
NPC_MIMIRON_TARGET_BEACON = 33369,
NPC_HODIR_TARGET_BEACON = 33108,
NPC_FREYA_TARGET_BEACON = 33366,
- NPC_LOREKEEPER = 33686, // Hard mode starter
- NPC_BRANZ_BRONZBEARD = 33579,
- NPC_DELORAH = 33701,
NPC_ULDUAR_GAUNTLET_GENERATOR = 33571, // Trigger tied to towers
};
@@ -1167,9 +1164,49 @@ class npc_freya_ward_summon : public CreatureScript
}
};
-//npc lore keeper
-#define GOSSIP_ITEM_1 "Activate secondary defensive systems"
-#define GOSSIP_ITEM_2 "Confirmed"
+enum BrannBronzebeardGossips
+{
+ GOSSIP_MENU_BRANN_BRONZEBEARD = 10355,
+ GOSSIP_OPTION_BRANN_BRONZEBEARD = 0
+};
+
+class npc_brann_bronzebeard_ulduar_intro : public CreatureScript
+{
+ public:
+ npc_brann_bronzebeard_ulduar_intro() : CreatureScript("npc_brann_bronzebeard_ulduar_intro") { }
+
+ struct npc_brann_bronzebeard_ulduar_introAI : public ScriptedAI
+ {
+ npc_brann_bronzebeard_ulduar_introAI(Creature* creature) : ScriptedAI(creature)
+ {
+ _instance = creature->GetInstanceScript();
+ }
+
+ void sGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
+ {
+ if (menuId == GOSSIP_MENU_BRANN_BRONZEBEARD && gossipListId == GOSSIP_OPTION_BRANN_BRONZEBEARD)
+ {
+ player->PlayerTalkClass->SendCloseGossip();
+ if (Creature* loreKeeper = _instance->GetCreature(DATA_LORE_KEEPER_OF_NORGANNON))
+ loreKeeper->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ }
+ }
+
+ private:
+ InstanceScript* _instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<npc_brann_bronzebeard_ulduar_introAI>(creature);
+ }
+};
+
+enum LoreKeeperGossips
+{
+ GOSSIP_MENU_LORE_KEEPER = 10477,
+ GOSSIP_OPTION_LORE_KEEPER = 0
+};
class npc_lorekeeper : public CreatureScript
{
@@ -1180,6 +1217,7 @@ class npc_lorekeeper : public CreatureScript
{
npc_lorekeeperAI(Creature* creature) : ScriptedAI(creature)
{
+ _instance = creature->GetInstanceScript();
}
void DoAction(int32 action) override
@@ -1187,66 +1225,42 @@ class npc_lorekeeper : public CreatureScript
// Start encounter
if (action == ACTION_SPAWN_VEHICLES)
{
- for (int32 i = 0; i < RAID_MODE(2, 5); ++i)
+ for (uint8 i = 0; i < RAID_MODE(2, 5); ++i)
DoSummon(VEHICLE_SIEGE, PosSiege[i], 3000, TEMPSUMMON_CORPSE_TIMED_DESPAWN);
- for (int32 i = 0; i < RAID_MODE(2, 5); ++i)
+ for (uint8 i = 0; i < RAID_MODE(2, 5); ++i)
DoSummon(VEHICLE_CHOPPER, PosChopper[i], 3000, TEMPSUMMON_CORPSE_TIMED_DESPAWN);
- for (int32 i = 0; i < RAID_MODE(2, 5); ++i)
+ for (uint8 i = 0; i < RAID_MODE(2, 5); ++i)
DoSummon(VEHICLE_DEMOLISHER, PosDemolisher[i], 3000, TEMPSUMMON_CORPSE_TIMED_DESPAWN);
- return;
}
}
- };
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- player->CLOSE_GOSSIP_MENU();
- InstanceScript* instance = creature->GetInstanceScript();
- if (!instance)
- return true;
- switch (action)
+ void sGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
{
- case GOSSIP_ACTION_INFO_DEF+1:
- player->PrepareGossipMenu(creature);
- instance->instance->LoadGrid(364, -16); //make sure leviathan is loaded
+ if (menuId == GOSSIP_MENU_LORE_KEEPER && gossipListId == GOSSIP_OPTION_LORE_KEEPER)
+ {
+ player->PlayerTalkClass->SendCloseGossip();
+ _instance->instance->LoadGrid(364, -16); // make sure leviathan is loaded
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- if (Creature* leviathan = instance->instance->GetCreature(instance->GetGuidData(BOSS_LEVIATHAN)))
+ if (Creature* leviathan = _instance->instance->GetCreature(_instance->GetGuidData(BOSS_LEVIATHAN)))
{
leviathan->AI()->DoAction(ACTION_START_HARD_MODE);
- creature->SetVisible(false);
- creature->AI()->DoAction(ACTION_SPAWN_VEHICLES); // spawn the vehicles
- if (Creature* Delorah = creature->FindNearestCreature(NPC_DELORAH, 1000, true))
+ me->SetVisible(false);
+ DoAction(ACTION_SPAWN_VEHICLES); // spawn the vehicles
+ if (Creature* delorah = _instance->GetCreature(DATA_DELLORAH))
{
- if (Creature* Branz = creature->FindNearestCreature(NPC_BRANZ_BRONZBEARD, 1000, true))
+ if (Creature* brann = _instance->GetCreature(DATA_BRANN_BRONZEBEARD_INTRO))
{
- Delorah->GetMotionMaster()->MovePoint(0, Branz->GetPositionX()-4, Branz->GetPositionY(), Branz->GetPositionZ());
- /// @todo Delorah->AI()->Talk(xxxx, Branz->GetGUID()); when reached at branz
+ delorah->GetMotionMaster()->MovePoint(0, brann->GetPositionX() - 4, brann->GetPositionY(), brann->GetPositionZ());
+ /// @todo delorah->AI()->Talk(xxxx, brann->GetGUID()); when reached at branz
}
}
}
- break;
+ }
}
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- InstanceScript* instance = creature->GetInstanceScript();
- if (instance && instance->GetData(BOSS_LEVIATHAN) != DONE && player)
- {
- player->PrepareGossipMenu(creature);
-
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
- }
- return true;
- }
+ private:
+ InstanceScript* _instance;
+ };
CreatureAI* GetAI(Creature* creature) const override
{
@@ -1254,56 +1268,6 @@ class npc_lorekeeper : public CreatureScript
}
};
-//enable hardmode
-////npc_brann_bronzebeard this requires more work involving area triggers. if reached this guy speaks through his radio..
-//#define GOSSIP_ITEM_1 "xxxxx"
-//#define GOSSIP_ITEM_2 "xxxxx"
-//
-/*
-class npc_brann_bronzebeard : public CreatureScript
-{
-public:
- npc_brann_bronzebeard() : CreatureScript("npc_brann_bronzebeard") { }
-
- //bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action) override
- //{
- // player->PlayerTalkClass->ClearMenus();
- // switch (action)
- // {
- // case GOSSIP_ACTION_INFO_DEF+1:
- // if (player)
- // {
- // player->PrepareGossipMenu(creature);
- //
- // player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
- // player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
- // }
- // break;
- // case GOSSIP_ACTION_INFO_DEF+2:
- // if (player)
- // player->CLOSE_GOSSIP_MENU();
- // if (Creature* Lorekeeper = creature->FindNearestCreature(NPC_LOREKEEPER, 1000, true)) //lore keeper of lorgannon
- // Lorekeeper->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- // break;
- // }
- // return true;
- //}
- //bool OnGossipHello(Player* player, Creature* creature) override
- //{
- // InstanceScript* instance = creature->GetInstanceScript();
- // if (instance && instance->GetData(BOSS_LEVIATHAN) !=DONE)
- // {
- // player->PrepareGossipMenu(creature);
- //
- // player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- // player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
- // }
- // return true;
- //}
- //
-}
-*/
-
class go_ulduar_tower : public GameObjectScript
{
public:
@@ -1836,8 +1800,8 @@ void AddSC_boss_flame_leviathan()
new npc_hodirs_fury();
new npc_freyas_ward();
new npc_freya_ward_summon();
+ new npc_brann_bronzebeard_ulduar_intro();
new npc_lorekeeper();
- // new npc_brann_bronzebeard();
new go_ulduar_tower();
new achievement_three_car_garage_demolisher();
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
index 818bb0041a9..6958b5d78a5 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
@@ -749,8 +749,8 @@ class boss_elder_brightleaf : public CreatureScript
case EVENT_SOLAR_FLARE:
{
uint8 stackAmount = 0;
- if (me->GetAura(SPELL_FLUX_AURA))
- stackAmount = me->GetAura(SPELL_FLUX_AURA)->GetStackAmount();
+ if (Aura* aura = me->GetAura(SPELL_FLUX_AURA))
+ stackAmount = aura->GetStackAmount();
me->CastCustomSpell(SPELL_SOLAR_FLARE, SPELLVALUE_MAX_TARGETS, stackAmount, me, false);
events.ScheduleEvent(EVENT_SOLAR_FLARE, urand(5000, 10000));
break;
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
index 0c7df100f60..f2edfa816a0 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
@@ -54,6 +54,15 @@ MinionData const minionData[] =
{ 0, 0, }
};
+ObjectData const creatureData[] =
+{
+ { NPC_BRANN_BRONZEBEARD_INTRO, DATA_BRANN_BRONZEBEARD_INTRO },
+ { NPC_LORE_KEEPER_OF_NORGANNON, DATA_LORE_KEEPER_OF_NORGANNON },
+ { NPC_HIGH_EXPLORER_DELLORAH, DATA_DELLORAH },
+ { NPC_BRONZEBEARD_RADIO, DATA_BRONZEBEARD_RADIO },
+ { 0, 0, }
+};
+
class instance_ulduar : public InstanceMapScript
{
public:
@@ -68,6 +77,7 @@ class instance_ulduar : public InstanceMapScript
LoadDoorData(doorData);
LoadMinionData(minionData);
+ LoadObjectData(creatureData, nullptr);
_algalonTimer = 61;
_maxArmorItemLevel = 0;
@@ -420,6 +430,8 @@ class instance_ulduar : public InstanceMapScript
algalon->AI()->JustSummoned(creature);
break;
}
+
+ InstanceScript::OnCreatureCreate(creature);
}
void OnCreatureRemove(Creature* creature) override
@@ -446,6 +458,8 @@ class instance_ulduar : public InstanceMapScript
default:
break;
}
+
+ InstanceScript::OnCreatureRemove(creature);
}
void OnGameObjectCreate(GameObject* gameObject) override
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
index 9f640c410ef..834ab32864f 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
@@ -80,6 +80,23 @@ enum UlduarNPCs
NPC_YOGG_SARON = 33288,
NPC_ALGALON = 32871,
+ // Flame Leviathan
+ NPC_ULDUAR_COLOSSUS = 33237,
+ NPC_BRANN_BRONZEBEARD_INTRO = 33579,
+ NPC_BRANN_BRONZEBEARD_FLYING_MACHINE = 34119,
+ NPC_BRANN_S_FLYING_MACHINE = 34120,
+ NPC_ARCHMAGE_PENTARUS = 33624,
+ NPC_ARCHMAGE_RHYDIAN = 33696,
+ NPC_LORE_KEEPER_OF_NORGANNON = 33686,
+ NPC_HIGH_EXPLORER_DELLORAH = 33701,
+ NPC_BRONZEBEARD_RADIO = 34054,
+ NPC_FLAME_LEVIATHAN = 33113,
+ NPC_FLAME_LEVIATHAN_SEAT = 33114,
+ NPC_FLAME_LEVIATHAN_TURRET = 33139,
+ NPC_LEVIATHAN_DEFENSE_TURRET = 33142,
+ NPC_OVERLOAD_CONTROL_DEVICE = 33143,
+ NPC_ORBITAL_SUPPORT = 34286,
+
// Mimiron
NPC_LEVIATHAN_MKII = 33432,
NPC_VX_001 = 33651,
@@ -382,6 +399,12 @@ enum UlduarData
DATA_UNIVERSE_GLOBE,
DATA_ALGALON_TRAPDOOR,
DATA_BRANN_BRONZEBEARD_ALG,
+
+ // Misc
+ DATA_BRANN_BRONZEBEARD_INTRO,
+ DATA_LORE_KEEPER_OF_NORGANNON,
+ DATA_DELLORAH,
+ DATA_BRONZEBEARD_RADIO
};
enum UlduarWorldStates
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 68c115f9faf..0ab7c2fcb54 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -614,6 +614,47 @@ class spell_gen_burn_brutallus : public SpellScriptLoader
}
};
+// 48750 - Burning Depths Necrolyte Image
+class spell_gen_burning_depths_necrolyte_image : public SpellScriptLoader
+{
+ public:
+ spell_gen_burning_depths_necrolyte_image() : SpellScriptLoader("spell_gen_burning_depths_necrolyte_image") { }
+
+ class spell_gen_burning_depths_necrolyte_image_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gen_burning_depths_necrolyte_image_AuraScript);
+
+ bool Validate(SpellInfo const* spellInfo) override
+ {
+ if (!sSpellMgr->GetSpellInfo(uint32(spellInfo->Effects[EFFECT_2].CalcValue())))
+ return false;
+ return true;
+ }
+
+ void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* caster = GetCaster())
+ caster->CastSpell(GetTarget(), uint32(GetSpellInfo()->Effects[EFFECT_2].CalcValue()));
+ }
+
+ void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->RemoveAurasDueToSpell(uint32(GetSpellInfo()->Effects[EFFECT_2].CalcValue()), GetCasterGUID());
+ }
+
+ void Register() override
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_gen_burning_depths_necrolyte_image_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_gen_burning_depths_necrolyte_image_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_gen_burning_depths_necrolyte_image_AuraScript();
+ }
+};
+
enum CannibalizeSpells
{
SPELL_CANNIBALIZE_TRIGGERED = 20578
@@ -4093,6 +4134,7 @@ void AddSC_generic_spell_scripts()
new spell_gen_break_shield("spell_gen_break_shield");
new spell_gen_break_shield("spell_gen_tournament_counterattack");
new spell_gen_burn_brutallus();
+ new spell_gen_burning_depths_necrolyte_image();
new spell_gen_cannibalize();
new spell_gen_chaos_blast();
new spell_gen_clone();
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index 57346443390..22eabd3dd65 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -57,6 +57,7 @@ EndContentData */
#include "SpellAuras.h"
#include "Pet.h"
#include "CreatureTextMgr.h"
+#include "SmartAI.h"
/*########
# npc_air_force_bots
@@ -2321,6 +2322,71 @@ public:
}
};
+enum StableMasters
+{
+ SPELL_MINIWING = 54573,
+ SPELL_JUBLING = 54611,
+ SPELL_DARTER = 54619,
+ SPELL_WORG = 54631,
+ SPELL_SMOLDERWEB = 54634,
+ SPELL_CHIKEN = 54677,
+ SPELL_WOLPERTINGER = 54688,
+
+ STABLE_MASTER_GOSSIP_SUB_MENU = 9820
+};
+
+class npc_stable_master : public CreatureScript
+{
+ public:
+ npc_stable_master() : CreatureScript("npc_stable_master") { }
+
+ struct npc_stable_masterAI : public SmartAI
+ {
+ npc_stable_masterAI(Creature* creature) : SmartAI(creature) { }
+
+ void sGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
+ {
+ SmartAI::sGossipSelect(player, menuId, gossipListId);
+ if (menuId != STABLE_MASTER_GOSSIP_SUB_MENU)
+ return;
+
+ switch (gossipListId)
+ {
+ case 0:
+ player->CastSpell(player, SPELL_MINIWING, false);
+ break;
+ case 1:
+ player->CastSpell(player, SPELL_JUBLING, false);
+ break;
+ case 2:
+ player->CastSpell(player, SPELL_DARTER, false);
+ break;
+ case 3:
+ player->CastSpell(player, SPELL_WORG, false);
+ break;
+ case 4:
+ player->CastSpell(player, SPELL_SMOLDERWEB, false);
+ break;
+ case 5:
+ player->CastSpell(player, SPELL_CHIKEN, false);
+ break;
+ case 6:
+ player->CastSpell(player, SPELL_WOLPERTINGER, false);
+ break;
+ default:
+ return;
+ }
+
+ player->PlayerTalkClass->SendCloseGossip();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_stable_masterAI(creature);
+ }
+};
+
void AddSC_npcs_special()
{
new npc_air_force_bots();
@@ -2343,4 +2409,5 @@ void AddSC_npcs_special()
new npc_firework();
new npc_spring_rabbit();
new npc_imp_in_a_ball();
+ new npc_stable_master();
}
diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp
index 10c41835a9f..387fb156dee 100644
--- a/src/server/worldserver/Main.cpp
+++ b/src/server/worldserver/Main.cpp
@@ -424,7 +424,7 @@ void FreezeDetectorHandler(const boost::system::error_code& error)
else if (getMSTimeDiff(_lastChangeMsTime, curtime) > _maxCoreStuckTimeInMs)
{
TC_LOG_ERROR("server.worldserver", "World Thread hangs, kicking out server!");
- ASSERT(false);
+ ABORT();
}
_freezeCheckTimer.expires_from_now(boost::posix_time::seconds(1));