aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/CMakeLists.txt2
-rw-r--r--src/server/authserver/CMakeLists.txt12
-rw-r--r--src/server/collision/Management/MMapManager.cpp10
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp13
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp8
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp52
-rw-r--r--src/server/game/Entities/Creature/Creature.h4
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp90
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h2
-rw-r--r--src/server/game/Entities/Object/Object.cpp386
-rw-r--r--src/server/game/Entities/Object/Object.h82
-rw-r--r--src/server/game/Entities/Pet/Pet.cpp4
-rw-r--r--src/server/game/Entities/Player/Player.cpp109
-rw-r--r--src/server/game/Entities/Transport/Transport.cpp16
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp359
-rw-r--r--src/server/game/Entities/Unit/Unit.h59
-rw-r--r--src/server/game/Entities/Vehicle/Vehicle.cpp12
-rw-r--r--src/server/game/Grids/GridDefines.h2
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp3
-rw-r--r--src/server/game/Handlers/GroupHandler.cpp4
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp24
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h2
-rw-r--r--src/server/game/Movement/PathGenerator.cpp34
-rw-r--r--src/server/game/Movement/Spline/MoveSpline.cpp17
-rw-r--r--src/server/game/Movement/Spline/MoveSpline.h19
-rw-r--r--src/server/game/Movement/Spline/MoveSplineFlag.h3
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.cpp2
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.h2
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInitArgs.h9
-rw-r--r--src/server/game/Movement/Spline/MovementTypedefs.h4
-rw-r--r--src/server/game/Movement/Spline/MovementUtil.cpp33
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp1
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h2
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp49
-rw-r--r--src/server/scripts/Commands/cs_cheat.cpp6
-rw-r--r--src/server/scripts/Commands/cs_gm.cpp10
-rw-r--r--src/server/scripts/Commands/cs_mmaps.cpp21
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/Uldaman/uldaman.cpp1
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp3
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp16
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp6
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp2
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp6
-rw-r--r--src/server/scripts/Northrend/zone_borean_tundra.cpp5
-rw-r--r--src/server/scripts/Northrend/zone_grizzly_hills.cpp525
-rw-r--r--src/server/scripts/Northrend/zone_howling_fjord.cpp2
-rw-r--r--src/server/scripts/Northrend/zone_sholazar_basin.cpp7
-rw-r--r--src/server/scripts/Northrend/zone_zuldrak.cpp543
-rw-r--r--src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp129
-rw-r--r--src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp172
-rw-r--r--src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp173
-rw-r--r--src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp11
-rw-r--r--src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h24
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_illidan.cpp2
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp3
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp3
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp6
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp2
-rw-r--r--src/server/scripts/Spells/spell_quest.cpp32
-rw-r--r--src/server/scripts/World/npcs_special.cpp2
-rw-r--r--src/server/shared/CMakeLists.txt6
-rw-r--r--src/server/worldserver/CMakeLists.txt12
-rw-r--r--src/tools/mmaps_generator/Info/readme.txt4
-rw-r--r--src/tools/mmaps_generator/MapBuilder.cpp179
-rw-r--r--src/tools/mmaps_generator/MapBuilder.h2
-rw-r--r--src/tools/mmaps_generator/PathGenerator.cpp2
-rw-r--r--src/tools/mmaps_generator/TerrainBuilder.h2
70 files changed, 1912 insertions, 1449 deletions
diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt
index 02fca56340f..646b89b6f80 100644
--- a/src/server/CMakeLists.txt
+++ b/src/server/CMakeLists.txt
@@ -17,7 +17,7 @@ if(CMAKE_COMPILER_IS_GNUCXX AND NOT MINGW)
endif()
if( SERVERS )
- set(sources_Debugging
+ set(sources_windows_Debugging
${CMAKE_SOURCE_DIR}/src/server/shared/Debugging/WheatyExceptionReport.cpp
${CMAKE_SOURCE_DIR}/src/server/shared/Debugging/WheatyExceptionReport.h
)
diff --git a/src/server/authserver/CMakeLists.txt b/src/server/authserver/CMakeLists.txt
index 6d756434a20..ff3a4cdd67c 100644
--- a/src/server/authserver/CMakeLists.txt
+++ b/src/server/authserver/CMakeLists.txt
@@ -29,16 +29,14 @@ set(authserver_SRCS
)
if( WIN32 )
+ set(authserver_SRCS
+ ${authserver_SRCS}
+ ${sources_windows_Debugging}
+ )
if ( MSVC )
set(authserver_SRCS
${authserver_SRCS}
- ${sources_Debugging}
- authserver.rc
- )
- else ( )
- set(authserver_SRCS
- ${authserver_SRCS}
- ${sources_Debugging}
+ authserver.rc
)
endif ()
endif()
diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp
index a3f89f42443..65c13c07e66 100644
--- a/src/server/collision/Management/MMapManager.cpp
+++ b/src/server/collision/Management/MMapManager.cpp
@@ -63,7 +63,7 @@ namespace MMAP
dtNavMesh* mesh = dtAllocNavMesh();
ASSERT(mesh);
- if (DT_SUCCESS != mesh->init(&params))
+ if (dtStatusFailed(mesh->init(&params)))
{
dtFreeNavMesh(mesh);
TC_LOG_ERROR(LOG_FILTER_MAPS, "MMAP:loadMapData: Failed to initialize dtNavMesh for mmap %03u from file %s", mapId, fileName);
@@ -152,7 +152,7 @@ namespace MMAP
dtTileRef tileRef = 0;
// memory allocated for data is now managed by detour, and will be deallocated when the tile is removed
- if (DT_SUCCESS == mmap->navMesh->addTile(data, fileHeader.size, DT_TILE_FREE_DATA, 0, &tileRef))
+ if (dtStatusSucceed(mmap->navMesh->addTile(data, fileHeader.size, DT_TILE_FREE_DATA, 0, &tileRef)))
{
mmap->mmapLoadedTiles.insert(std::pair<uint32, dtTileRef>(packedGridPos, tileRef));
++loadedTiles;
@@ -193,7 +193,7 @@ namespace MMAP
dtTileRef tileRef = mmap->mmapLoadedTiles[packedGridPos];
// unload, and mark as non loaded
- if (DT_SUCCESS != mmap->navMesh->removeTile(tileRef, NULL, NULL))
+ if (dtStatusFailed(mmap->navMesh->removeTile(tileRef, NULL, NULL)))
{
// this is technically a memory leak
// if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used
@@ -227,7 +227,7 @@ namespace MMAP
{
uint32 x = (i->first >> 16);
uint32 y = (i->first & 0x0000FFFF);
- if (DT_SUCCESS != mmap->navMesh->removeTile(i->second, NULL, NULL))
+ if (dtStatusFailed(mmap->navMesh->removeTile(i->second, NULL, NULL)))
TC_LOG_ERROR(LOG_FILTER_MAPS, "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, x, y);
else
{
@@ -288,7 +288,7 @@ namespace MMAP
// allocate mesh query
dtNavMeshQuery* query = dtAllocNavMeshQuery();
ASSERT(query);
- if (DT_SUCCESS != query->init(mmap->navMesh, 1024))
+ if (dtStatusFailed(query->init(mmap->navMesh, 1024)))
{
dtFreeNavMeshQuery(query);
TC_LOG_ERROR(LOG_FILTER_MAPS, "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId);
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index 4d2b5f88376..f43a7f91f32 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -724,27 +724,18 @@ uint64 SmartAI::GetGUID(int32 /*id*/) const
void SmartAI::SetRun(bool run)
{
- if (run)
- me->SetWalk(false);
- else
- me->SetWalk(true);
-
+ me->SetWalk(!run);
mRun = run;
}
void SmartAI::SetFly(bool fly)
{
me->SetDisableGravity(fly);
- me->SendMovementDisableGravity();
}
void SmartAI::SetSwim(bool swim)
{
- if (swim)
- me->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
- else
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
- me->SendMovementSwimming();
+ me->SetSwim(swim);
}
void SmartAI::sGossipHello(Player* player)
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp
index 7b4f323ac31..b5b8a7ce7e2 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp
@@ -101,10 +101,10 @@ void BattlegroundIC::DoAction(uint32 action, uint64 var)
player->SetTransport(player->GetTeamId() == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde);
- player->m_movementInfo.t_pos.m_positionX = TransportMovementInfo.GetPositionX();
- player->m_movementInfo.t_pos.m_positionY = TransportMovementInfo.GetPositionY();
- player->m_movementInfo.t_pos.m_positionZ = TransportMovementInfo.GetPositionZ();
- player->m_movementInfo.t_guid = (player->GetTeamId() == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)->GetGUID();
+ player->m_movementInfo.transport.pos.m_positionX = TransportMovementInfo.GetPositionX();
+ player->m_movementInfo.transport.pos.m_positionY = TransportMovementInfo.GetPositionY();
+ player->m_movementInfo.transport.pos.m_positionZ = TransportMovementInfo.GetPositionZ();
+ player->m_movementInfo.transport.guid = (player->GetTeamId() == TEAM_ALLIANCE ? gunshipAlliance : gunshipHorde)->GetGUID();
if (player->TeleportTo(GetMapId(), TeleportToTransportPosition.GetPositionX(),
TeleportToTransportPosition.GetPositionY(),
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index ebbf11be586..d8da1e5e286 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -2416,53 +2416,6 @@ bool Creature::IsDungeonBoss() const
return cinfo && (cinfo->flags_extra & CREATURE_FLAG_EXTRA_DUNGEON_BOSS);
}
-bool Creature::SetWalk(bool enable)
-{
- if (!Unit::SetWalk(enable))
- return false;
-
- if (!movespline->Initialized())
- return true;
-
- SendMovementWalkMode();
- return true;
-}
-
-bool Creature::SetDisableGravity(bool disable, bool packetOnly/*=false*/)
-{
- //! It's possible only a packet is sent but moveflags are not updated
- //! Need more research on this
- if (!packetOnly && !Unit::SetDisableGravity(disable))
- return false;
-
- if (!movespline->Initialized())
- return true;
-
- SendMovementDisableGravity();
- return true;
-}
-
-bool Creature::SetHover(bool enable)
-{
- if (!Unit::SetHover(enable))
- return false;
-
- //! Unconfirmed for players:
- if (enable)
- SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER);
- else
- RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER);
-
- if (!movespline->Initialized())
- return true;
-
- // If creature hovers using aura, the hover movement opcode is sent from aura handler
- if (!HasAuraType(SPELL_AURA_HOVER))
- SendMovementHover();
-
- return true;
-}
-
float Creature::GetAggroRange(Unit const* target) const
{
// Determines the aggro range for creatures (usually pets), used mainly for aggressive pet target selection.
@@ -2549,10 +2502,7 @@ void Creature::UpdateMovementFlags()
SetDisableGravity(false);
}
- if (GetCreatureTemplate()->InhabitType & INHABIT_WATER && IsInWater())
- AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
- else
- RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
+ SetSwim(GetCreatureTemplate()->InhabitType & INHABIT_WATER && IsInWater());
}
void Creature::SetObjectScale(float scale)
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index d70a4268235..de826d3f310 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -503,10 +503,6 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
CreatureAI* AI() const { return (CreatureAI*)i_AI; }
- bool SetWalk(bool enable);
- bool SetDisableGravity(bool disable, bool packetOnly = false);
- bool SetHover(bool enable);
-
SpellSchoolMask GetMeleeDamageSchoolMask() const { return m_meleeDamageSchoolMask; }
void SetMeleeDamageSchool(SpellSchools school) { m_meleeDamageSchoolMask = SpellSchoolMask(1 << school); }
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 07a3c0412d2..62426e95987 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -17,22 +17,22 @@
*/
#include "GameObjectAI.h"
-#include "ObjectMgr.h"
+#include "BattlegroundAV.h"
+#include "CellImpl.h"
+#include "CreatureAISelector.h"
+#include "DynamicTree.h"
+#include "GameObjectModel.h"
+#include "GridNotifiersImpl.h"
+#include "Group.h"
#include "GroupMgr.h"
+#include "ObjectMgr.h"
+#include "OutdoorPvPMgr.h"
#include "PoolMgr.h"
+#include "ScriptMgr.h"
#include "SpellMgr.h"
+#include "UpdateFieldFlags.h"
#include "World.h"
-#include "GridNotifiersImpl.h"
-#include "CellImpl.h"
-#include "OutdoorPvPMgr.h"
-#include "BattlegroundAV.h"
-#include "ScriptMgr.h"
-#include "CreatureAISelector.h"
-#include "Group.h"
#include "MapManager.h"
-#include "GameObjectModel.h"
-#include "DynamicTree.h"
-
GameObject::GameObject(): WorldObject(false), m_model(NULL), m_goValue(), m_AI(NULL)
{
m_objectType |= TYPEMASK_GAMEOBJECT;
@@ -2084,3 +2084,71 @@ bool GameObject::IsLootAllowedFor(Player const* player) const
return true;
}
+
+void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const
+{
+ if (!target)
+ return;
+
+ bool forcedFlags = GetGoType() == GAMEOBJECT_TYPE_CHEST && GetGOInfo()->chest.groupLootRules && HasLootRecipient();
+ bool targetIsGM = target->IsGameMaster();
+
+ ByteBuffer fieldBuffer;
+
+ UpdateMask updateMask;
+ updateMask.SetCount(m_valuesCount);
+
+ uint32* flags = GameObjectUpdateFieldFlags;
+ uint32 visibleFlag = UF_FLAG_PUBLIC;
+ if (GetOwnerGUID() == target->GetGUID())
+ visibleFlag |= UF_FLAG_OWNER;
+
+ for (uint16 index = 0; index < m_valuesCount; ++index)
+ {
+ if (_fieldNotifyFlags & flags[index] ||
+ ((updateType == UPDATETYPE_VALUES ? _changesMask.GetBit(index) : m_uint32Values[index]) && (flags[index] & visibleFlag)) ||
+ (index == GAMEOBJECT_FLAGS && forcedFlags))
+ {
+ updateMask.SetBit(index);
+
+ if (index == GAMEOBJECT_DYNAMIC)
+ {
+ uint16 dynFlags = 0;
+ switch (GetGoType())
+ {
+ case GAMEOBJECT_TYPE_CHEST:
+ case GAMEOBJECT_TYPE_GOOBER:
+ if (ActivateToQuest(target))
+ dynFlags |= GO_DYNFLAG_LO_ACTIVATE | GO_DYNFLAG_LO_SPARKLE;
+ else if (targetIsGM)
+ dynFlags |= GO_DYNFLAG_LO_ACTIVATE;
+ break;
+ case GAMEOBJECT_TYPE_GENERIC:
+ if (ActivateToQuest(target))
+ dynFlags |= GO_DYNFLAG_LO_SPARKLE;
+ break;
+ default:
+ break;
+ }
+
+ fieldBuffer << uint16(dynFlags);
+ fieldBuffer << uint16(-1);
+ }
+ else if (index == GAMEOBJECT_FLAGS)
+ {
+ uint32 flags = m_uint32Values[GAMEOBJECT_FLAGS];
+ if (GetGoType() == GAMEOBJECT_TYPE_CHEST)
+ if (GetGOInfo()->chest.groupLootRules && !IsLootAllowedFor(target))
+ flags |= GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE;
+
+ fieldBuffer << flags;
+ }
+ else
+ fieldBuffer << m_uint32Values[index]; // other cases
+ }
+ }
+
+ *data << uint8(updateMask.GetBlockCount());
+ updateMask.AppendToPacket(data);
+ data->append(fieldBuffer);
+}
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index b1d55a6b200..97c9f4a4650 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -624,6 +624,8 @@ class GameObject : public WorldObject, public GridObject<GameObject>
explicit GameObject();
~GameObject();
+ void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const;
+
void AddToWorld();
void RemoveFromWorld();
void CleanupsBeforeDelete(bool finalCleanup = true);
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index eae333bc4c8..9ee58d62194 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -251,12 +251,8 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c
buf.append(GetPackGUID());
buf << uint8(m_objectTypeId);
- _BuildMovementUpdate(&buf, flags);
-
- UpdateMask updateMask;
- updateMask.SetCount(valCount);
- _SetCreateBits(&updateMask, target);
- _BuildValuesUpdate(updateType, &buf, &updateMask, target);
+ BuildMovementUpdate(&buf, flags);
+ BuildValuesUpdate(updateType, &buf, target);
data->AddUpdateBlock(buf);
}
@@ -278,15 +274,7 @@ void Object::BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target) c
buf << uint8(UPDATETYPE_VALUES);
buf.append(GetPackGUID());
- UpdateMask updateMask;
- uint32 valCount = m_valuesCount;
- if (GetTypeId() == TYPEID_PLAYER && target != this)
- valCount = PLAYER_END_NOT_SELF;
-
- updateMask.SetCount(valCount);
-
- _SetUpdateBits(&updateMask, target);
- _BuildValuesUpdate(UPDATETYPE_VALUES, &buf, &updateMask, target);
+ BuildValuesUpdate(UPDATETYPE_VALUES, &buf, target);
data->AddUpdateBlock(buf);
}
@@ -359,7 +347,7 @@ uint16 Object::GetUInt16Value(uint16 index, uint8 offset) const
return *(((uint16*)&m_uint32Values[index])+offset);
}
-void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
+void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
{
Unit const* self = NULL;
ObjectGuid guid = GetGUID();
@@ -434,12 +422,12 @@ void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
data->WriteBit(hasFallData); // Has fall data
data->WriteBit(!hasSplineElevation); // Has spline elevation
data->WriteBit(guid[5]);
- data->WriteBit(self->m_movementInfo.t_guid); // Has transport data
+ data->WriteBit(self->m_movementInfo.transport.guid); // Has transport data
data->WriteBit(0); // Is missing time
- if (self->m_movementInfo.t_guid)
+ if (self->m_movementInfo.transport.guid)
{
- ObjectGuid transGuid = self->m_movementInfo.t_guid;
+ ObjectGuid transGuid = self->m_movementInfo.transport.guid;
data->WriteBit(transGuid[1]);
data->WriteBit(hasTransportTime2); // Has transport time 2
@@ -473,7 +461,7 @@ void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
if (flags & UPDATEFLAG_GO_TRANSPORT_POSITION)
{
WorldObject const* self = static_cast<WorldObject const*>(this);
- ObjectGuid transGuid = self->m_movementInfo.t_guid;
+ ObjectGuid transGuid = self->m_movementInfo.transport.guid;
data->WriteBit(transGuid[5]);
data->WriteBit(0); // Has GO transport time 3
data->WriteBit(transGuid[0]);
@@ -521,13 +509,13 @@ void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
{
if (hasFallDirection)
{
- *data << float(self->m_movementInfo.j_cosAngle);
- *data << float(self->m_movementInfo.j_xyspeed);
- *data << float(self->m_movementInfo.j_sinAngle);
+ *data << float(self->m_movementInfo.jump.cosAngle);
+ *data << float(self->m_movementInfo.jump.xyspeed);
+ *data << float(self->m_movementInfo.jump.sinAngle);
}
- *data << uint32(self->m_movementInfo.fallTime);
- *data << float(self->m_movementInfo.j_zspeed);
+ *data << uint32(self->m_movementInfo.jump.fallTime);
+ *data << float(self->m_movementInfo.jump.zspeed);
}
*data << self->GetSpeed(MOVE_SWIM_BACK);
@@ -540,16 +528,16 @@ void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
*data << float(self->GetPositionZMinusOffset());
data->WriteByteSeq(guid[5]);
- if (self->m_movementInfo.t_guid)
+ if (self->m_movementInfo.transport.guid)
{
- ObjectGuid transGuid = self->m_movementInfo.t_guid;
+ ObjectGuid transGuid = self->m_movementInfo.transport.guid;
data->WriteByteSeq(transGuid[5]);
data->WriteByteSeq(transGuid[7]);
*data << uint32(self->GetTransTime());
*data << float(self->GetTransOffsetO());
if (hasTransportTime2)
- *data << uint32(self->m_movementInfo.t_time2);
+ *data << uint32(self->m_movementInfo.transport.time2);
*data << float(self->GetTransOffsetY());
*data << float(self->GetTransOffsetX());
@@ -557,7 +545,7 @@ void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
*data << float(self->GetTransOffsetZ());
data->WriteByteSeq(transGuid[0]);
if (hasTransportTime3)
- *data << uint32(self->m_movementInfo.t_time3);
+ *data << uint32(self->m_movementInfo.transport.time3);
*data << int8(self->GetTransSeat());
data->WriteByteSeq(transGuid[1]);
@@ -602,12 +590,12 @@ void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
if (flags & UPDATEFLAG_GO_TRANSPORT_POSITION)
{
WorldObject const* self = static_cast<WorldObject const*>(this);
- ObjectGuid transGuid = self->m_movementInfo.t_guid;
+ ObjectGuid transGuid = self->m_movementInfo.transport.guid;
data->WriteBit(transGuid[0]);
data->WriteBit(transGuid[5]);
if (hasTransportTime3)
- *data << uint32(self->m_movementInfo.t_time3);
+ *data << uint32(self->m_movementInfo.transport.time3);
data->WriteBit(transGuid[3]);
*data << float(self->GetTransOffsetX());
@@ -622,7 +610,7 @@ void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
*data << int8(self->GetTransSeat());
*data << float(self->GetTransOffsetO());
if (hasTransportTime2)
- *data << uint32(self->m_movementInfo.t_time2);
+ *data << uint32(self->m_movementInfo.transport.time2);
}
if (flags & UPDATEFLAG_ROTATION)
@@ -688,286 +676,31 @@ void Object::_BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
*data << uint32(getMSTime()); // Unknown - getMSTime is wrong.
}
-void Object::_BuildValuesUpdate(uint8 updateType, ByteBuffer* data, UpdateMask* updateMask, Player* target) const
+void Object::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const
{
if (!target)
return;
- bool IsActivateToQuest = false;
+ ByteBuffer fieldBuffer;
+ UpdateMask updateMask;
+ updateMask.SetCount(m_valuesCount);
- // Before trying to convert to each type there is a check, so safe
- Unit const* unit = ToUnit();
- GameObject const* go = ToGameObject();
+ uint32* flags = NULL;
+ uint32 visibleFlag = GetUpdateFieldData(target, flags);
- if (unit)
- {
- if (unit->HasFlag(UNIT_FIELD_AURASTATE, PER_CASTER_AURA_STATE_MASK))
- updateMask->SetBit(UNIT_FIELD_AURASTATE);
- }
- else if (go)
+ for (uint16 index = 0; index < m_valuesCount; ++index)
{
- if (updateType == UPDATETYPE_CREATE_OBJECT || updateType == UPDATETYPE_CREATE_OBJECT2)
+ if (_fieldNotifyFlags & flags[index] ||
+ ((updateType == UPDATETYPE_VALUES ? _changesMask.GetBit(index) : m_uint32Values[index]) && (flags[index] & visibleFlag)))
{
- if (!go->IsDynTransport())
- {
- if (go->ActivateToQuest(target) || target->IsGameMaster())
- IsActivateToQuest = true;
-
- if (go->GetGoArtKit())
- updateMask->SetBit(GAMEOBJECT_BYTES_1);
- }
- }
- else
- {
- if (!go->IsTransport())
- {
- if (go->ActivateToQuest(target) || target->IsGameMaster())
- IsActivateToQuest = true;
-
- updateMask->SetBit(GAMEOBJECT_BYTES_1);
-
- if (go->GetGoType() == GAMEOBJECT_TYPE_CHEST && go->GetGOInfo()->chest.groupLootRules &&
- go->HasLootRecipient())
- {
- updateMask->SetBit(GAMEOBJECT_FLAGS);
- }
- }
+ updateMask.SetBit(index);
+ fieldBuffer << m_uint32Values[index];
}
}
- uint32 valCount = m_valuesCount;
- if (GetTypeId() == TYPEID_PLAYER && target != this)
- valCount = PLAYER_END_NOT_SELF;
-
- ASSERT(updateMask && updateMask->GetCount() == valCount);
-
- *data << uint8(updateMask->GetBlockCount());
- updateMask->AppendToPacket(data);
-
- // 2 specialized loops for speed optimization in non-unit case
- if (unit) // unit (creature/player) case
- {
- Creature const* creature = ToCreature();
- for (uint16 index = 0; index < valCount; ++index)
- {
- if (updateMask->GetBit(index))
- {
- if (index == UNIT_NPC_FLAGS)
- {
- // remove custom flag before sending
- uint32 appendValue = m_uint32Values[index];
-
- if (GetTypeId() == TYPEID_UNIT)
- {
- if (!target->CanSeeSpellClickOn(this->ToCreature()))
- appendValue &= ~UNIT_NPC_FLAG_SPELLCLICK;
- }
-
- *data << uint32(appendValue);
- }
- else if (index == UNIT_FIELD_AURASTATE)
- {
- // Check per caster aura states to not enable using a spell in client if specified aura is not by target
- *data << unit->BuildAuraStateUpdateForTarget(target);
- }
- // FIXME: Some values at server stored in float format but must be sent to client in uint32 format
- else if (index >= UNIT_FIELD_BASEATTACKTIME && index <= UNIT_FIELD_RANGEDATTACKTIME)
- {
- // convert from float to uint32 and send
- *data << uint32(m_floatValues[index] < 0 ? 0 : m_floatValues[index]);
- }
- // there are some float values which may be negative or can't get negative due to other checks
- else if ((index >= UNIT_FIELD_NEGSTAT0 && index <= UNIT_FIELD_NEGSTAT4) ||
- (index >= UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE && index <= (UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE + 6)) ||
- (index >= UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE && index <= (UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE + 6)) ||
- (index >= UNIT_FIELD_POSSTAT0 && index <= UNIT_FIELD_POSSTAT4))
- {
- *data << uint32(m_floatValues[index]);
- }
- // Gamemasters should be always able to select units - remove not selectable flag
- else if (index == UNIT_FIELD_FLAGS)
- {
- if (target->IsGameMaster())
- *data << (m_uint32Values[index] & ~UNIT_FLAG_NOT_SELECTABLE);
- else
- *data << m_uint32Values[index];
- }
- // use modelid_a if not gm, _h if gm for CREATURE_FLAG_EXTRA_TRIGGER creatures
- else if (index == UNIT_FIELD_DISPLAYID)
- {
- if (GetTypeId() == TYPEID_UNIT)
- {
- CreatureTemplate const* cinfo = creature->GetCreatureTemplate();
-
- // this also applies for transform auras
- if (SpellInfo const* transform = sSpellMgr->GetSpellInfo(ToUnit()->getTransForm()))
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (transform->Effects[i].IsAura(SPELL_AURA_TRANSFORM))
- if (CreatureTemplate const* transformInfo = sObjectMgr->GetCreatureTemplate(transform->Effects[i].MiscValue))
- {
- cinfo = transformInfo;
- break;
- }
-
- if (cinfo->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER)
- {
- if (target->IsGameMaster())
- {
- if (cinfo->Modelid1)
- *data << cinfo->Modelid1;//Modelid1 is a visible model for gms
- else
- *data << 17519; // world invisible trigger's model
- }
- else
- {
- if (cinfo->Modelid2)
- *data << cinfo->Modelid2;//Modelid2 is an invisible model for players
- else
- *data << 11686; // world invisible trigger's model
- }
- }
- else
- *data << m_uint32Values[index];
- }
- else
- *data << m_uint32Values[index];
- }
- // hide lootable animation for unallowed players
- else if (index == UNIT_DYNAMIC_FLAGS)
- {
- uint32 dynamicFlags = m_uint32Values[index];
-
- if (creature)
- {
- if (creature->hasLootRecipient())
- {
- if (creature->isTappedBy(target))
- {
- dynamicFlags |= (UNIT_DYNFLAG_TAPPED | UNIT_DYNFLAG_TAPPED_BY_PLAYER);
- }
- else
- {
- dynamicFlags |= UNIT_DYNFLAG_TAPPED;
- dynamicFlags &= ~UNIT_DYNFLAG_TAPPED_BY_PLAYER;
- }
- }
- else
- {
- dynamicFlags &= ~UNIT_DYNFLAG_TAPPED;
- dynamicFlags &= ~UNIT_DYNFLAG_TAPPED_BY_PLAYER;
- }
-
- if (!target->isAllowedToLoot(creature))
- dynamicFlags &= ~UNIT_DYNFLAG_LOOTABLE;
- }
-
- // unit UNIT_DYNFLAG_TRACK_UNIT should only be sent to caster of SPELL_AURA_MOD_STALKED auras
- if (dynamicFlags & UNIT_DYNFLAG_TRACK_UNIT)
- if (!unit->HasAuraTypeWithCaster(SPELL_AURA_MOD_STALKED, target->GetGUID()))
- dynamicFlags &= ~UNIT_DYNFLAG_TRACK_UNIT;
- *data << dynamicFlags;
- }
- // FG: pretend that OTHER players in own group are friendly ("blue")
- else if (index == UNIT_FIELD_BYTES_2 || index == UNIT_FIELD_FACTIONTEMPLATE)
- {
- if (unit->IsControlledByPlayer() && target != this && sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && unit->IsInRaidWith(target))
- {
- FactionTemplateEntry const* ft1 = unit->GetFactionTemplateEntry();
- FactionTemplateEntry const* ft2 = target->GetFactionTemplateEntry();
- if (ft1 && ft2 && !ft1->IsFriendlyTo(*ft2))
- {
- if (index == UNIT_FIELD_BYTES_2)
- {
- // Allow targetting opposite faction in party when enabled in config
- *data << (m_uint32Values[index] & ((UNIT_BYTE2_FLAG_SANCTUARY /*| UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5*/) << 8)); // this flag is at uint8 offset 1 !!
- }
- else
- {
- // pretend that all other HOSTILE players have own faction, to allow follow, heal, rezz (trade wont work)
- uint32 faction = target->getFaction();
- *data << uint32(faction);
- }
- }
- else
- *data << m_uint32Values[index];
- }
- else
- *data << m_uint32Values[index];
- }
- else
- {
- // send in current format (float as float, uint32 as uint32)
- *data << m_uint32Values[index];
- }
- }
- }
- }
- else if (go) // gameobject case
- {
- for (uint16 index = 0; index < valCount; ++index)
- {
- if (updateMask->GetBit(index))
- {
- // send in current format (float as float, uint32 as uint32)
- if (index == GAMEOBJECT_DYNAMIC)
- {
- if (IsActivateToQuest)
- {
- switch (go->GetGoType())
- {
- case GAMEOBJECT_TYPE_CHEST:
- if (target->IsGameMaster())
- *data << uint16(GO_DYNFLAG_LO_ACTIVATE);
- else
- *data << uint16(GO_DYNFLAG_LO_ACTIVATE | GO_DYNFLAG_LO_SPARKLE);
- break;
- case GAMEOBJECT_TYPE_GENERIC:
- if (target->IsGameMaster())
- *data << uint16(0);
- else
- *data << uint16(GO_DYNFLAG_LO_SPARKLE);
- break;
- case GAMEOBJECT_TYPE_GOOBER:
- if (target->IsGameMaster())
- *data << uint16(GO_DYNFLAG_LO_ACTIVATE);
- else
- *data << uint16(GO_DYNFLAG_LO_ACTIVATE | GO_DYNFLAG_LO_SPARKLE);
- break;
- default:
- *data << uint16(0); // unknown, not happen.
- break;
- }
- }
- else
- *data << uint16(0); // disable quest object
-
- *data << uint16(-1);
- }
- else if (index == GAMEOBJECT_FLAGS)
- {
- uint32 flags = m_uint32Values[index];
- if (go->GetGoType() == GAMEOBJECT_TYPE_CHEST)
- if (go->GetGOInfo()->chest.groupLootRules && !go->IsLootAllowedFor(target))
- flags |= GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE;
-
- *data << flags;
- }
- else
- *data << m_uint32Values[index]; // other cases
- }
- }
- }
- else // other objects case (no special index checks)
- {
- for (uint16 index = 0; index < valCount; ++index)
- {
- if (updateMask->GetBit(index))
- {
- // send in current format (float as float, uint32 as uint32)
- *data << m_uint32Values[index];
- }
- }
- }
+ *data << uint8(updateMask.GetBlockCount());
+ updateMask.AppendToPacket(data);
+ data->append(fieldBuffer);
}
void Object::ClearUpdateMask(bool remove)
@@ -1069,33 +802,6 @@ void Object::_LoadIntoDataField(std::string const& data, uint32 startOffset, uin
}
}
-void Object::_SetUpdateBits(UpdateMask* updateMask, Player* target) const
-{
- uint32* flags = NULL;
- uint32 visibleFlag = GetUpdateFieldData(target, flags);
- uint32 valCount = m_valuesCount;
- if (GetTypeId() == TYPEID_PLAYER && target != this)
- valCount = PLAYER_END_NOT_SELF;
-
- for (uint16 index = 0; index < valCount; ++index)
- if (_fieldNotifyFlags & flags[index] || ((flags[index] & visibleFlag) & UF_FLAG_SPECIAL_INFO) || (_changesMask.GetBit(index) && (flags[index] & visibleFlag)))
- updateMask->SetBit(index);
-}
-
-void Object::_SetCreateBits(UpdateMask* updateMask, Player* target) const
-{
- uint32* value = m_uint32Values;
- uint32* flags = NULL;
- uint32 visibleFlag = GetUpdateFieldData(target, flags);
- uint32 valCount = m_valuesCount;
- if (GetTypeId() == TYPEID_PLAYER && target != this)
- valCount = PLAYER_END_NOT_SELF;
-
- for (uint16 index = 0; index < valCount; ++index, ++value)
- if (_fieldNotifyFlags & flags[index] || ((flags[index] & visibleFlag) & UF_FLAG_SPECIAL_INFO) || (*value && (flags[index] & visibleFlag)))
- updateMask->SetBit(index);
-}
-
void Object::SetInt32Value(uint16 index, int32 value)
{
ASSERT(index < m_valuesCount || PrintIndexError(index, true));
@@ -1546,17 +1252,17 @@ void MovementInfo::OutDebug()
TC_LOG_INFO(LOG_FILTER_GENERAL, "flags2 %s (%u)", Movement::MovementFlagsExtra_ToString(flags2).c_str(), flags2);
TC_LOG_INFO(LOG_FILTER_GENERAL, "time %u current time %u", time, getMSTime());
TC_LOG_INFO(LOG_FILTER_GENERAL, "position: `%s`", pos.ToString().c_str());
- if (t_guid)
+ if (transport.guid)
{
TC_LOG_INFO(LOG_FILTER_GENERAL, "TRANSPORT:");
- TC_LOG_INFO(LOG_FILTER_GENERAL, "guid: " UI64FMTD, t_guid);
- TC_LOG_INFO(LOG_FILTER_GENERAL, "position: `%s`", t_pos.ToString().c_str());
- TC_LOG_INFO(LOG_FILTER_GENERAL, "seat: %i", t_seat);
- TC_LOG_INFO(LOG_FILTER_GENERAL, "time: %u", t_time);
+ TC_LOG_INFO(LOG_FILTER_GENERAL, "guid: " UI64FMTD, transport.guid);
+ TC_LOG_INFO(LOG_FILTER_GENERAL, "position: `%s`", transport.pos.ToString().c_str());
+ TC_LOG_INFO(LOG_FILTER_GENERAL, "seat: %i", transport.seat);
+ TC_LOG_INFO(LOG_FILTER_GENERAL, "time: %u", transport.time);
if (flags2 & MOVEMENTFLAG2_INTERPOLATED_MOVEMENT)
- TC_LOG_INFO(LOG_FILTER_GENERAL, "time2: %u", t_time2);
+ TC_LOG_INFO(LOG_FILTER_GENERAL, "time2: %u", transport.time2);
if (bits.hasTransportTime3)
- TC_LOG_INFO(LOG_FILTER_GENERAL, "time3: %u", t_time3);
+ TC_LOG_INFO(LOG_FILTER_GENERAL, "time3: %u", transport.time3);
}
if ((flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (flags2 & MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING))
@@ -1564,9 +1270,9 @@ void MovementInfo::OutDebug()
if (flags & MOVEMENTFLAG_FALLING || bits.hasFallData)
{
- TC_LOG_INFO(LOG_FILTER_GENERAL, "fallTime: %u j_zspeed: %f", fallTime, j_zspeed);
+ TC_LOG_INFO(LOG_FILTER_GENERAL, "fallTime: %u j_zspeed: %f", jump.fallTime, jump.zspeed);
if (flags & MOVEMENTFLAG_FALLING)
- TC_LOG_INFO(LOG_FILTER_GENERAL, "j_sinAngle: %f j_cosAngle: %f j_xyspeed: %f", j_sinAngle, j_cosAngle, j_xyspeed);
+ TC_LOG_INFO(LOG_FILTER_GENERAL, "j_sinAngle: %f j_cosAngle: %f j_xyspeed: %f", jump.sinAngle, jump.cosAngle, jump.xyspeed);
}
if (flags & MOVEMENTFLAG_SPLINE_ELEVATION)
@@ -1692,12 +1398,12 @@ bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool
if (m_transport && obj->GetTransport() && obj->GetTransport()->GetGUIDLow() == m_transport->GetGUIDLow())
{
- float dtx = m_movementInfo.t_pos.m_positionX - obj->m_movementInfo.t_pos.m_positionX;
- float dty = m_movementInfo.t_pos.m_positionY - obj->m_movementInfo.t_pos.m_positionY;
+ float dtx = m_movementInfo.transport.pos.m_positionX - obj->m_movementInfo.transport.pos.m_positionX;
+ float dty = m_movementInfo.transport.pos.m_positionY - obj->m_movementInfo.transport.pos.m_positionY;
float disttsq = dtx * dtx + dty * dty;
if (is3D)
{
- float dtz = m_movementInfo.t_pos.m_positionZ - obj->m_movementInfo.t_pos.m_positionZ;
+ float dtz = m_movementInfo.transport.pos.m_positionZ - obj->m_movementInfo.transport.pos.m_positionZ;
disttsq += dtz * dtz;
}
return disttsq < (maxdist * maxdist);
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 427d5a91afd..08bc0ae88ae 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -192,7 +192,7 @@ class Object
uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); }
void SetEntry(uint32 entry) { SetUInt32Value(OBJECT_FIELD_ENTRY, entry); }
- void SetObjectScale(float scale) { SetFloatValue(OBJECT_FIELD_SCALE_X, scale); }
+ virtual void SetObjectScale(float scale) { SetFloatValue(OBJECT_FIELD_SCALE_X, scale); }
TypeID GetTypeId() const { return m_objectTypeId; }
bool isType(uint16 mask) const { return (mask & m_objectType); }
@@ -296,10 +296,8 @@ class Object
uint32 GetUpdateFieldData(Player const* target, uint32*& flags) const;
- void _SetUpdateBits(UpdateMask* updateMask, Player* target) const;
- void _SetCreateBits(UpdateMask* updateMask, Player* target) const;
- void _BuildMovementUpdate(ByteBuffer * data, uint16 flags) const;
- void _BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, UpdateMask* updateMask, Player* target) const;
+ void BuildMovementUpdate(ByteBuffer* data, uint16 flags) const;
+ virtual void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const;
uint16 m_objectType;
@@ -469,19 +467,47 @@ struct MovementInfo
uint16 flags2;
Position pos;
uint32 time;
+
// transport
- uint64 t_guid;
- Position t_pos;
- int8 t_seat;
- uint32 t_time;
- uint32 t_time2;
- uint32 t_time3;
+ struct TransportInfo
+ {
+ void Reset()
+ {
+ guid = 0;
+ pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
+ seat = -1;
+ time = 0;
+ time2 = 0;
+ time3 = 0;
+ }
+
+ uint64 guid;
+ Position pos;
+ int8 seat;
+ uint32 time;
+ uint32 time2;
+ uint32 time3;
+ } transport;
+
// swimming/flying
float pitch;
- // falling
- uint32 fallTime;
+
+
// jumping
- float j_zspeed, j_sinAngle, j_cosAngle, j_xyspeed;
+ struct JumpInfo
+ {
+ void Reset()
+ {
+ fallTime = 0;
+ zspeed = sinAngle = cosAngle = xyspeed = 0.0f;
+ }
+
+ uint32 fallTime;
+
+ float zspeed, sinAngle, cosAngle, xyspeed;
+
+ } jump;
+
// spline
float splineElevation;
@@ -497,12 +523,11 @@ struct MovementInfo
} bits;
MovementInfo() :
- guid(0), flags(0), flags2(0), time(0), t_guid(0),
- t_seat(-1), t_time(0), t_time2(0), t_time3(0), pitch(0.0f), fallTime(0),
- j_zspeed(0.0f), j_sinAngle(0.0f), j_cosAngle(0.0f), j_xyspeed(0.0f)
+ guid(0), flags(0), flags2(0), time(0), pitch(0.0f)
{
pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
- t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
+ transport.Reset();
+ jump.Reset();
memset(&bits, 0, sizeof(bits));
}
@@ -513,18 +538,25 @@ struct MovementInfo
bool HasMovementFlag(uint32 flag) const { return flags & flag; }
uint16 GetExtraMovementFlags() const { return flags2; }
+ void SetExtraMovementFlags(uint16 flag) { flags2 = flag; }
void AddExtraMovementFlag(uint16 flag) { flags2 |= flag; }
+ void RemoveExtraMovementFlag(uint16 flag) { flags2 &= ~flag; }
bool HasExtraMovementFlag(uint16 flag) const { return flags2 & flag; }
- void SetFallTime(uint32 time) { fallTime = time; }
+ void SetFallTime(uint32 time) { jump.fallTime = time; }
+
+ void ResetTransport()
+ {
+ transport.Reset();
+ bits.hasTransportTime2 = false;
+ bits.hasTransportTime3 = false;
+ }
- void ClearTransport()
+ void ResetJump()
{
- t_guid = 0;
- t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
- t_seat = -1;
- t_time = 0;
- t_time2 = 0;
+ jump.Reset();
+ bits.hasFallData = false;
+ bits.hasFallDirection = false;
}
void OutDebug();
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index 55043537daa..687f1ab40b5 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -2048,6 +2048,6 @@ void Pet::SetDisplayId(uint32 modelId)
if (Unit* owner = GetOwner())
if (Player* player = owner->ToPlayer())
- if (owner->ToPlayer()->GetGroup())
- owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MODEL_ID);
+ if (player->GetGroup())
+ player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_MODEL_ID);
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 0fb67ea7d07..bc326d7c232 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -24,15 +24,14 @@
#include "Battlefield.h"
#include "BattlefieldMgr.h"
#include "BattlefieldWG.h"
-#include "BattlegroundAV.h"
#include "Battleground.h"
+#include "BattlegroundAV.h"
#include "BattlegroundMgr.h"
#include "CellImpl.h"
#include "Channel.h"
#include "ChannelMgr.h"
#include "CharacterDatabaseCleaner.h"
#include "Chat.h"
-#include <cmath>
#include "Common.h"
#include "ConditionMgr.h"
#include "CreatureAI.h"
@@ -50,8 +49,8 @@
#include "GuildMgr.h"
#include "InstanceSaveMgr.h"
#include "InstanceScript.h"
-#include "Language.h"
#include "LFGMgr.h"
+#include "Language.h"
#include "Log.h"
#include "MapInstanced.h"
#include "MapManager.h"
@@ -60,17 +59,18 @@
#include "Opcodes.h"
#include "OutdoorPvP.h"
#include "OutdoorPvPMgr.h"
-#include "ReputationMgr.h"
#include "Pet.h"
#include "QuestDef.h"
+#include "ReputationMgr.h"
#include "SkillDiscovery.h"
#include "SocialMgr.h"
+#include "Spell.h"
#include "SpellAuraEffects.h"
#include "SpellAuras.h"
-#include "Spell.h"
#include "SpellMgr.h"
#include "Transport.h"
#include "UpdateData.h"
+#include "UpdateFieldFlags.h"
#include "UpdateMask.h"
#include "Util.h"
#include "Vehicle.h"
@@ -2135,7 +2135,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
{
m_transport->RemovePassenger(this);
m_transport = NULL;
- m_movementInfo.ClearTransport();
+ m_movementInfo.ResetTransport();
RepopAtGraveyard(); // teleport to near graveyard if on transport, looks blizz like :)
}
@@ -2159,7 +2159,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
{
m_transport->RemovePassenger(this);
m_transport = NULL;
- m_movementInfo.ClearTransport();
+ m_movementInfo.ResetTransport();
}
}
@@ -2317,10 +2317,10 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
if (m_transport)
{
- final_x += m_movementInfo.t_pos.GetPositionX();
- final_y += m_movementInfo.t_pos.GetPositionY();
- final_z += m_movementInfo.t_pos.GetPositionZ();
- final_o += m_movementInfo.t_pos.GetOrientation();
+ final_x += m_movementInfo.transport.pos.GetPositionX();
+ final_y += m_movementInfo.transport.pos.GetPositionY();
+ final_z += m_movementInfo.transport.pos.GetPositionZ();
+ final_o += m_movementInfo.transport.pos.GetOrientation();
}
m_teleport_dest = WorldLocation(mapid, final_x, final_y, final_z, final_o);
@@ -5137,8 +5137,7 @@ void Player::BuildPlayerRepop()
// convert player body to ghost
SetHealth(1);
- AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
- SendMovementWaterWalking();
+ SetWaterWalking(true);
if (!GetSession()->isLogingOut())
SetRooted(false);
@@ -5178,8 +5177,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
setDeathState(ALIVE);
- RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
- SendMovementWaterWalking();
+ SetWaterWalking(false);
SetRooted(false);
m_deathTimer = 0;
@@ -17244,18 +17242,18 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
// currently we do not support transport in bg
else if (transGUID)
{
- m_movementInfo.t_guid = MAKE_NEW_GUID(transGUID, 0, HIGHGUID_MO_TRANSPORT);
- m_movementInfo.t_pos.Relocate(fields[27].GetFloat(), fields[28].GetFloat(), fields[29].GetFloat(), fields[30].GetFloat());
+ m_movementInfo.transport.guid = MAKE_NEW_GUID(transGUID, 0, HIGHGUID_MO_TRANSPORT);
+ m_movementInfo.transport.pos.Relocate(fields[27].GetFloat(), fields[28].GetFloat(), fields[29].GetFloat(), fields[30].GetFloat());
if (!Trinity::IsValidMapCoord(
- GetPositionX()+m_movementInfo.t_pos.m_positionX, GetPositionY()+m_movementInfo.t_pos.m_positionY,
- GetPositionZ()+m_movementInfo.t_pos.m_positionZ, GetOrientation()+m_movementInfo.t_pos.GetOrientation()) ||
+ GetPositionX()+m_movementInfo.transport.pos.GetPositionX(), GetPositionY()+m_movementInfo.transport.pos.GetPositionY(),
+ GetPositionZ()+m_movementInfo.transport.pos.GetPositionZ(), GetOrientation()+m_movementInfo.transport.pos.GetOrientation()) ||
// transport size limited
- m_movementInfo.t_pos.m_positionX > 250 || m_movementInfo.t_pos.m_positionY > 250 || m_movementInfo.t_pos.m_positionZ > 250)
+ m_movementInfo.transport.pos.m_positionX > 250 || m_movementInfo.transport.pos.m_positionY > 250 || m_movementInfo.transport.pos.m_positionZ > 250)
{
TC_LOG_ERROR(LOG_FILTER_PLAYER, "Player (guidlow %d) have invalid transport coordinates (X: %f Y: %f Z: %f O: %f). Teleport to bind location.",
- guid, GetPositionX()+m_movementInfo.t_pos.m_positionX, GetPositionY()+m_movementInfo.t_pos.m_positionY,
- GetPositionZ()+m_movementInfo.t_pos.m_positionZ, GetOrientation()+m_movementInfo.t_pos.GetOrientation());
+ guid, GetPositionX()+m_movementInfo.transport.pos.GetPositionX(), GetPositionY()+m_movementInfo.transport.pos.GetPositionY(),
+ GetPositionZ()+m_movementInfo.transport.pos.GetPositionZ(), GetOrientation()+m_movementInfo.transport.pos.GetOrientation());
RelocateToHomebind();
}
@@ -22760,14 +22758,30 @@ void Player::UpdateTriggerVisibility()
{
if (IS_CREATURE_GUID(*itr))
{
- Creature* obj = GetMap()->GetCreature(*itr);
- if (!obj || !(obj->IsTrigger() || obj->HasAuraType(SPELL_AURA_TRANSFORM))) // can transform into triggers
+ Creature* creature = GetMap()->GetCreature(*itr);
+ // Update fields of triggers, transformed units or unselectable units (values dependent on GM state)
+ if (!creature || (!creature->IsTrigger() && !creature->HasAuraType(SPELL_AURA_TRANSFORM) && !creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE)))
continue;
- obj->BuildValuesUpdateBlockForPlayer(&udata, this);
+ creature->SetFieldNotifyFlag(UF_FLAG_PUBLIC);
+ creature->BuildValuesUpdateBlockForPlayer(&udata, this);
+ creature->RemoveFieldNotifyFlag(UF_FLAG_PUBLIC);
+ }
+ else if (IS_GAMEOBJECT_GUID((*itr)))
+ {
+ GameObject* go = GetMap()->GetGameObject(*itr);
+ if (!go)
+ continue;
+
+ go->SetFieldNotifyFlag(UF_FLAG_PUBLIC);
+ go->BuildValuesUpdateBlockForPlayer(&udata, this);
+ go->RemoveFieldNotifyFlag(UF_FLAG_PUBLIC);
}
}
+ if (!udata.HasData())
+ return;
+
udata.BuildPacket(&packet);
GetSession()->SendPacket(&packet);
}
@@ -23387,13 +23401,13 @@ void Player::SendAurasForTarget(Unit* target)
These movement packets are usually found in SMSG_COMPRESSED_MOVES
*/
if (target->HasAuraType(SPELL_AURA_FEATHER_FALL))
- target->SendMovementFeatherFall();
+ target->SetFeatherFall(true, true);
if (target->HasAuraType(SPELL_AURA_WATER_WALK))
- target->SendMovementWaterWalking();
+ target->SetWaterWalking(true, true);
if (target->HasAuraType(SPELL_AURA_HOVER))
- target->SendMovementHover();
+ target->SetHover(true, true);
WorldPacket data(SMSG_AURA_UPDATE_ALL);
data.append(target->GetPackGUID());
@@ -25319,7 +25333,7 @@ void Player::HandleFall(MovementInfo const& movementInfo)
}
//Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction
- TC_LOG_DEBUG(LOG_FILTER_PLAYER, "FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d", movementInfo.pos.GetPositionZ(), height, GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall);
+ TC_LOG_DEBUG(LOG_FILTER_PLAYER, "FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d", movementInfo.pos.GetPositionZ(), height, GetPositionZ(), movementInfo.jump.fallTime, height, damage, safe_fall);
}
}
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_LANDING); // No fly zone - Parachute
@@ -25659,8 +25673,8 @@ void Player::AddKnownCurrency(uint32 itemId)
void Player::UpdateFallInformationIfNeed(MovementInfo const& minfo, uint16 opcode)
{
- if (m_lastFallTime >= minfo.fallTime || m_lastFallZ <= minfo.pos.GetPositionZ() || opcode == MSG_MOVE_FALL_LAND)
- SetFallInformation(minfo.fallTime, minfo.pos.GetPositionZ());
+ if (m_lastFallTime >= minfo.jump.fallTime || m_lastFallZ <= minfo.pos.GetPositionZ() || opcode == MSG_MOVE_FALL_LAND)
+ SetFallInformation(minfo.jump.fallTime, minfo.pos.GetPositionZ());
}
void Player::UnsummonPetTemporaryIfAny()
@@ -26829,10 +26843,9 @@ void Player::_SaveInstanceTimeRestrictions(SQLTransaction& trans)
bool Player::IsInWhisperWhiteList(uint64 guid)
{
for (WhisperListContainer::const_iterator itr = WhisperList.begin(); itr != WhisperList.end(); ++itr)
- {
if (*itr == guid)
return true;
- }
+
return false;
}
@@ -27240,35 +27253,35 @@ void Player::ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::Ext
break;
case MSETransportPositionX:
if (hasTransportData)
- data >> mi->t_pos.m_positionX;
+ data >> mi->transport.pos.m_positionX;
break;
case MSETransportPositionY:
if (hasTransportData)
- data >> mi->t_pos.m_positionY;
+ data >> mi->transport.pos.m_positionY;
break;
case MSETransportPositionZ:
if (hasTransportData)
- data >> mi->t_pos.m_positionZ;
+ data >> mi->transport.pos.m_positionZ;
break;
case MSETransportOrientation:
if (hasTransportData)
- mi->t_pos.SetOrientation(data.read<float>());
+ mi->transport.pos.SetOrientation(data.read<float>());
break;
case MSETransportSeat:
if (hasTransportData)
- data >> mi->t_seat;
+ data >> mi->transport.seat;
break;
case MSETransportTime:
if (hasTransportData)
- data >> mi->t_time;
+ data >> mi->transport.time;
break;
case MSETransportTime2:
if (hasTransportData && mi->bits.hasTransportTime2)
- data >> mi->t_time2;
+ data >> mi->transport.time2;
break;
case MSETransportTime3:
if (hasTransportData && mi->bits.hasTransportTime3)
- data >> mi->t_time3;
+ data >> mi->transport.time3;
break;
case MSEPitch:
if (mi->bits.hasPitch)
@@ -27276,23 +27289,23 @@ void Player::ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::Ext
break;
case MSEFallTime:
if (mi->bits.hasFallData)
- data >> mi->fallTime;
+ data >> mi->jump.fallTime;
break;
case MSEFallVerticalSpeed:
if (mi->bits.hasFallData)
- data >> mi->j_zspeed;
+ data >> mi->jump.zspeed;
break;
case MSEFallCosAngle:
if (mi->bits.hasFallData && mi->bits.hasFallDirection)
- data >> mi->j_cosAngle;
+ data >> mi->jump.cosAngle;
break;
case MSEFallSinAngle:
if (mi->bits.hasFallData && mi->bits.hasFallDirection)
- data >> mi->j_sinAngle;
+ data >> mi->jump.sinAngle;
break;
case MSEFallHorizontalSpeed:
if (mi->bits.hasFallData && mi->bits.hasFallDirection)
- data >> mi->j_xyspeed;
+ data >> mi->jump.xyspeed;
break;
case MSESplineElevation:
if (mi->bits.hasSplineElevation)
@@ -27315,9 +27328,9 @@ void Player::ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::Ext
}
mi->guid = guid;
- mi->t_guid = tguid;
+ mi->transport.guid = tguid;
- if (hasTransportData && mi->pos.m_positionX != mi->t_pos.m_positionX)
+ if (hasTransportData && mi->pos.m_positionX != mi->transport.pos.m_positionX)
if (GetTransport())
GetTransport()->UpdatePosition(mi);
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index 5361eaff8a2..3b1e031dbb6 100644
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -634,8 +634,8 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y,
}
creature->SetTransport(this);
- creature->m_movementInfo.t_guid = GetGUID();
- creature->m_movementInfo.t_pos.Relocate(x, y, z, o);
+ creature->m_movementInfo.transport.guid = GetGUID();
+ creature->m_movementInfo.transport.pos.Relocate(x, y, z, o);
if (anim)
creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, anim);
@@ -647,7 +647,7 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y,
o + GetOrientation());
creature->SetHomePosition(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation());
- creature->SetTransportHomePosition(creature->m_movementInfo.t_pos);
+ creature->SetTransportHomePosition(creature->m_movementInfo.transport.pos);
if (!creature->IsPositionValid())
{
@@ -674,10 +674,10 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y,
void Transport::UpdatePosition(MovementInfo* mi)
{
- float transport_o = mi->pos.GetOrientation() - mi->t_pos.GetOrientation();
- float transport_x = mi->pos.m_positionX - (mi->t_pos.m_positionX * std::cos(transport_o) - mi->t_pos.m_positionY * std::sin(transport_o));
- float transport_y = mi->pos.m_positionY - (mi->t_pos.m_positionY * std::cos(transport_o) + mi->t_pos.m_positionX * std::sin(transport_o));
- float transport_z = mi->pos.m_positionZ - mi->t_pos.m_positionZ;
+ float transport_o = mi->pos.GetOrientation() - mi->transport.pos.GetOrientation();
+ float transport_x = mi->pos.m_positionX - (mi->transport.pos.m_positionX * std::cos(transport_o) - mi->transport.pos.m_positionY * std::sin(transport_o));
+ float transport_y = mi->pos.m_positionY - (mi->transport.pos.m_positionY * std::cos(transport_o) + mi->transport.pos.m_positionX * std::sin(transport_o));
+ float transport_z = mi->pos.m_positionZ - mi->transport.pos.m_positionZ;
Relocate(transport_x, transport_y, transport_z, transport_o);
UpdatePassengerPositions();
@@ -690,7 +690,7 @@ void Transport::UpdatePassengerPositions()
Creature* npc = *itr;
float x, y, z, o;
- npc->m_movementInfo.t_pos.GetPosition(x, y, z, o);
+ npc->m_movementInfo.transport.pos.GetPosition(x, y, z, o);
CalculatePassengerPosition(x, y, z, &o);
GetMap()->CreatureRelocation(npc, x, y, z, o, false);
npc->GetTransportHomePosition(x, y, z, o);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index a6084a62fdb..9ca21adb157 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -409,7 +409,7 @@ void Unit::UpdateSplinePosition()
Movement::Location loc = movespline->ComputePosition();
if (GetTransGUID())
{
- Position& pos = m_movementInfo.t_pos;
+ Position& pos = m_movementInfo.transport.pos;
pos.m_positionX = loc.x;
pos.m_positionY = loc.y;
pos.m_positionZ = loc.z;
@@ -8594,10 +8594,7 @@ void Unit::SetCharm(Unit* charm, bool apply)
_isWalkingBeforeCharm = charm->IsWalking();
if (_isWalkingBeforeCharm)
- {
charm->SetWalk(false);
- charm->SendMovementWalkMode();
- }
m_Controlled.insert(charm);
}
@@ -8632,10 +8629,7 @@ void Unit::SetCharm(Unit* charm, bool apply)
}
if (charm->IsWalking() != _isWalkingBeforeCharm)
- {
charm->SetWalk(_isWalkingBeforeCharm);
- charm->SendMovementWalkMode();
- }
if (charm->GetTypeId() == TYPEID_PLAYER
|| !charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_MINION)
@@ -16008,14 +16002,6 @@ bool Unit::IsFalling() const
return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR) || movespline->isFalling();
}
-void Unit::SetCanFly(bool apply)
-{
- if (apply)
- AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
- else
- RemoveUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
-}
-
void Unit::NearTeleportTo(float x, float y, float z, float orientation, bool casting /*= false*/)
{
DisableSpline();
@@ -16218,11 +16204,11 @@ void Unit::WriteMovementInfo(WorldPacket& data, Movement::ExtraMovementStatusEle
break;
case MSETransportTime2:
if (hasTransportData && hasTransportTime2)
- data << mi.t_time2;
+ data << mi.transport.time2;
break;
case MSETransportTime3:
if (hasTransportData && hasTransportTime3)
- data << mi.t_time3;
+ data << mi.transport.time3;
break;
case MSEPitch:
if (hasPitch)
@@ -16230,23 +16216,23 @@ void Unit::WriteMovementInfo(WorldPacket& data, Movement::ExtraMovementStatusEle
break;
case MSEFallTime:
if (hasFallData)
- data << mi.fallTime;
+ data << mi.jump.fallTime;
break;
case MSEFallVerticalSpeed:
if (hasFallData)
- data << mi.j_zspeed;
+ data << mi.jump.zspeed;
break;
case MSEFallCosAngle:
if (hasFallData && hasFallDirection)
- data << mi.j_cosAngle;
+ data << mi.jump.cosAngle;
break;
case MSEFallSinAngle:
if (hasFallData && hasFallDirection)
- data << mi.j_sinAngle;
+ data << mi.jump.sinAngle;
break;
case MSEFallHorizontalSpeed:
if (hasFallData && hasFallDirection)
- data << mi.j_xyspeed;
+ data << mi.jump.xyspeed;
break;
case MSESplineElevation:
if (hasSplineElevation)
@@ -16700,103 +16686,146 @@ bool Unit::SetWalk(bool enable)
else
RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ ///@ TODO: Find proper opcode for walk mode setting in player mind controlling a player case
+ if (enable)
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_WALK_MODE, SMSG_SPLINE_MOVE_SET_WALK_MODE).Send();
+ else
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_RUN_MODE, SMSG_SPLINE_MOVE_SET_WALK_MODE).Send();
+
return true;
}
-bool Unit::SetDisableGravity(bool disable, bool /*packetOnly = false*/)
+bool Unit::SetDisableGravity(bool disable, bool packetOnly /*= false*/)
{
- if (disable == IsLevitating())
- return false;
+ if (!packetOnly)
+ {
+ if (disable == IsLevitating())
+ return false;
+
+ if (disable)
+ AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
+ else
+ RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
+ }
if (disable)
- AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_GRAVITY_DISABLE, SMSG_MOVE_GRAVITY_DISABLE).Send();
else
- RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_GRAVITY_ENABLE, SMSG_MOVE_GRAVITY_ENABLE).Send();
return true;
}
-bool Unit::SetHover(bool enable)
+bool Unit::SetSwim(bool enable)
{
- if (enable == HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
+ if (enable == HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING))
return false;
if (enable)
- {
- //! No need to check height on ascent
- AddUnitMovementFlag(MOVEMENTFLAG_HOVER);
- if (float hh = GetFloatValue(UNIT_FIELD_HOVERHEIGHT))
- UpdateHeight(GetPositionZ() + hh);
- }
+ AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
else
- {
- RemoveUnitMovementFlag(MOVEMENTFLAG_HOVER);
- if (float hh = GetFloatValue(UNIT_FIELD_HOVERHEIGHT))
- {
- float newZ = GetPositionZ() - hh;
- UpdateAllowedPositionZ(GetPositionX(), GetPositionY(), newZ);
- UpdateHeight(newZ);
- }
- }
+ RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
+
+ if (enable)
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_START_SWIM, NULL_OPCODE).Send();
+ else
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_STOP_SWIM, NULL_OPCODE).Send();
return true;
}
-void Unit::SendMovementHover()
+bool Unit::SetCanFly(bool enable)
{
- if (HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_HOVER, SMSG_MOVE_SET_HOVER).Send();
+ if (enable == HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY))
+ return false;
+
+ if (enable)
+ AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
else
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_UNSET_HOVER, SMSG_MOVE_UNSET_HOVER).Send();
+ RemoveUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
+
+ if (enable)
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_FLYING, SMSG_MOVE_SET_CAN_FLY).Send();
+ else
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_UNSET_FLYING, SMSG_MOVE_UNSET_CAN_FLY).Send();
+
+ return true;
}
-void Unit::SendMovementWaterWalking()
+bool Unit::SetWaterWalking(bool enable, bool packetOnly /*= false */)
{
- if (HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING))
+ if (!packetOnly)
+ {
+ if (enable == HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING))
+ return false;
+
+ if (enable)
+ AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
+ else
+ RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
+ }
+
+ if (enable)
Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_WATER_WALK, SMSG_MOVE_WATER_WALK).Send();
else
Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_LAND_WALK, SMSG_MOVE_LAND_WALK).Send();
+
+ return true;
}
-void Unit::SendMovementFeatherFall()
+bool Unit::SetFeatherFall(bool enable, bool packetOnly /*= false */)
{
- if (HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW))
+ if (!packetOnly)
+ {
+ if (enable == HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW))
+ return false;
+
+ if (enable)
+ AddUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
+ else
+ RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
+ }
+
+ if (enable)
Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_FEATHER_FALL, SMSG_MOVE_FEATHER_FALL).Send();
else
Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_NORMAL_FALL, SMSG_MOVE_NORMAL_FALL).Send();
-}
-void Unit::SendMovementCanFlyChange()
-{
- if (HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY))
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_FLYING, SMSG_MOVE_SET_CAN_FLY).Send();
- else
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_UNSET_FLYING, SMSG_MOVE_UNSET_CAN_FLY).Send();
+ return true;
}
-void Unit::SendMovementDisableGravity()
+bool Unit::SetHover(bool enable, bool packetOnly /*= false*/)
{
- if (HasUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY))
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_GRAVITY_DISABLE, SMSG_MOVE_GRAVITY_DISABLE).Send();
- else
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_GRAVITY_ENABLE, SMSG_MOVE_GRAVITY_ENABLE).Send();
-}
+ if (!packetOnly)
+ {
+ if (enable == HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
+ return false;
-void Unit::SendMovementWalkMode()
-{
- ///@ TODO: Find proper opcode for walk mode setting in player mind controlling a player case
- if (HasUnitMovementFlag(MOVEMENTFLAG_WALKING))
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_WALK_MODE, SMSG_SPLINE_MOVE_SET_WALK_MODE).Send();
- else
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_RUN_MODE, SMSG_SPLINE_MOVE_SET_WALK_MODE).Send();
-}
+ if (enable)
+ {
+ //! No need to check height on ascent
+ AddUnitMovementFlag(MOVEMENTFLAG_HOVER);
+ if (float hh = GetFloatValue(UNIT_FIELD_HOVERHEIGHT))
+ UpdateHeight(GetPositionZ() + hh);
+ }
+ else
+ {
+ RemoveUnitMovementFlag(MOVEMENTFLAG_HOVER);
+ if (float hh = GetFloatValue(UNIT_FIELD_HOVERHEIGHT))
+ {
+ float newZ = GetPositionZ() - hh;
+ UpdateAllowedPositionZ(GetPositionX(), GetPositionY(), newZ);
+ UpdateHeight(newZ);
+ }
+ }
+ }
-void Unit::SendMovementSwimming()
-{
- if (HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING))
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_START_SWIM, NULL_OPCODE).Send();
+ if (enable)
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_HOVER, SMSG_MOVE_SET_HOVER).Send();
else
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_STOP_SWIM, NULL_OPCODE).Send();
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_UNSET_HOVER, SMSG_MOVE_UNSET_HOVER).Send();
+
+ return true;
}
void Unit::SendSetPlayHoverAnim(bool enable)
@@ -16874,3 +16903,177 @@ void Unit::ReleaseFocus(Spell const* focusSpell)
if (focusSpell->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_DONT_TURN_DURING_CAST)
ClearUnitState(UNIT_STATE_ROTATING);
}
+
+void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const
+{
+ if (!target)
+ return;
+
+ ByteBuffer fieldBuffer;
+
+ UpdateMask updateMask;
+ updateMask.SetCount(m_valuesCount);
+
+ uint32* flags = UnitUpdateFieldFlags;
+ uint32 visibleFlag = UF_FLAG_PUBLIC;
+
+ if (target == this)
+ visibleFlag |= UF_FLAG_PRIVATE;
+
+ Player* plr = GetCharmerOrOwnerPlayerOrPlayerItself();
+ if (GetOwnerGUID() == target->GetGUID())
+ visibleFlag |= UF_FLAG_OWNER;
+
+ if (HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_SPECIALINFO))
+ if (HasAuraTypeWithCaster(SPELL_AURA_EMPATHY, target->GetGUID()))
+ visibleFlag |= UF_FLAG_SPECIAL_INFO;
+
+ if (plr && plr->IsInSameRaidWith(target))
+ visibleFlag |= UF_FLAG_PARTY_MEMBER;
+
+ Creature const* creature = ToCreature();
+ for (uint16 index = 0; index < m_valuesCount; ++index)
+ {
+ if (_fieldNotifyFlags & flags[index] ||
+ ((flags[index] & visibleFlag) & UF_FLAG_SPECIAL_INFO) ||
+ ((updateType == UPDATETYPE_VALUES ? _changesMask.GetBit(index) : m_uint32Values[index]) && (flags[index] & visibleFlag)) ||
+ (index == UNIT_FIELD_AURASTATE && HasFlag(UNIT_FIELD_AURASTATE, PER_CASTER_AURA_STATE_MASK)))
+ {
+ updateMask.SetBit(index);
+
+ if (index == UNIT_NPC_FLAGS)
+ {
+ uint32 appendValue = m_uint32Values[UNIT_NPC_FLAGS];
+
+ if (creature)
+ if (!target->CanSeeSpellClickOn(creature))
+ appendValue &= ~UNIT_NPC_FLAG_SPELLCLICK;
+
+ fieldBuffer << uint32(appendValue);
+ }
+ else if (index == UNIT_FIELD_AURASTATE)
+ {
+ // Check per caster aura states to not enable using a spell in client if specified aura is not by target
+ fieldBuffer << BuildAuraStateUpdateForTarget(target);
+ }
+ // FIXME: Some values at server stored in float format but must be sent to client in uint32 format
+ else if (index >= UNIT_FIELD_BASEATTACKTIME && index <= UNIT_FIELD_RANGEDATTACKTIME)
+ {
+ // convert from float to uint32 and send
+ fieldBuffer << uint32(m_floatValues[index] < 0 ? 0 : m_floatValues[index]);
+ }
+ // there are some float values which may be negative or can't get negative due to other checks
+ else if ((index >= UNIT_FIELD_NEGSTAT0 && index <= UNIT_FIELD_NEGSTAT4) ||
+ (index >= UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE && index <= (UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE + 6)) ||
+ (index >= UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE && index <= (UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE + 6)) ||
+ (index >= UNIT_FIELD_POSSTAT0 && index <= UNIT_FIELD_POSSTAT4))
+ {
+ fieldBuffer << uint32(m_floatValues[index]);
+ }
+ // Gamemasters should be always able to select units - remove not selectable flag
+ else if (index == UNIT_FIELD_FLAGS)
+ {
+ uint32 appendValue = m_uint32Values[UNIT_FIELD_FLAGS];
+ if (target->IsGameMaster())
+ appendValue &= ~UNIT_FLAG_NOT_SELECTABLE;
+
+ fieldBuffer << uint32(appendValue);
+ }
+ // use modelid_a if not gm, _h if gm for CREATURE_FLAG_EXTRA_TRIGGER creatures
+ else if (index == UNIT_FIELD_DISPLAYID)
+ {
+ uint32 displayId = m_uint32Values[UNIT_FIELD_DISPLAYID];
+ if (creature)
+ {
+ CreatureTemplate const* cinfo = creature->GetCreatureTemplate();
+
+ // this also applies for transform auras
+ if (SpellInfo const* transform = sSpellMgr->GetSpellInfo(getTransForm()))
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ if (transform->Effects[i].IsAura(SPELL_AURA_TRANSFORM))
+ if (CreatureTemplate const* transformInfo = sObjectMgr->GetCreatureTemplate(transform->Effects[i].MiscValue))
+ {
+ cinfo = transformInfo;
+ break;
+ }
+
+ if (cinfo->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER)
+ {
+ if (target->IsGameMaster())
+ {
+ if (cinfo->Modelid1)
+ displayId = cinfo->Modelid1; // Modelid1 is a visible model for gms
+ else
+ displayId = 17519; // world visible trigger's model
+ }
+ else
+ {
+ if (cinfo->Modelid2)
+ displayId = cinfo->Modelid2; // Modelid2 is an invisible model for players
+ else
+ displayId = 11686; // world invisible trigger's model
+ }
+ }
+ }
+
+ fieldBuffer << uint32(displayId);
+ }
+ // hide lootable animation for unallowed players
+ else if (index == UNIT_DYNAMIC_FLAGS)
+ {
+ uint32 dynamicFlags = m_uint32Values[UNIT_DYNAMIC_FLAGS] & ~(UNIT_DYNFLAG_TAPPED | UNIT_DYNFLAG_TAPPED_BY_PLAYER);
+
+ if (creature)
+ {
+ if (creature->hasLootRecipient())
+ {
+ dynamicFlags |= UNIT_DYNFLAG_TAPPED;
+ if (creature->isTappedBy(target))
+ dynamicFlags |= UNIT_DYNFLAG_TAPPED_BY_PLAYER;
+ }
+
+ if (!target->isAllowedToLoot(creature))
+ dynamicFlags &= ~UNIT_DYNFLAG_LOOTABLE;
+ }
+
+ // unit UNIT_DYNFLAG_TRACK_UNIT should only be sent to caster of SPELL_AURA_MOD_STALKED auras
+ if (dynamicFlags & UNIT_DYNFLAG_TRACK_UNIT)
+ if (!HasAuraTypeWithCaster(SPELL_AURA_MOD_STALKED, target->GetGUID()))
+ dynamicFlags &= ~UNIT_DYNFLAG_TRACK_UNIT;
+
+ fieldBuffer << dynamicFlags;
+ }
+ // FG: pretend that OTHER players in own group are friendly ("blue")
+ else if (index == UNIT_FIELD_BYTES_2 || index == UNIT_FIELD_FACTIONTEMPLATE)
+ {
+ if (IsControlledByPlayer() && target != this && sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && IsInRaidWith(target))
+ {
+ FactionTemplateEntry const* ft1 = GetFactionTemplateEntry();
+ FactionTemplateEntry const* ft2 = target->GetFactionTemplateEntry();
+ if (ft1 && ft2 && !ft1->IsFriendlyTo(*ft2))
+ {
+ if (index == UNIT_FIELD_BYTES_2)
+ // Allow targetting opposite faction in party when enabled in config
+ fieldBuffer << (m_uint32Values[UNIT_FIELD_BYTES_2] & ((UNIT_BYTE2_FLAG_SANCTUARY /*| UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5*/) << 8)); // this flag is at uint8 offset 1 !!
+ else
+ // pretend that all other HOSTILE players have own faction, to allow follow, heal, rezz (trade wont work)
+ fieldBuffer << uint32(target->getFaction());
+ }
+ else
+ fieldBuffer << m_uint32Values[index];
+ }
+ else
+ fieldBuffer << m_uint32Values[index];
+ }
+ else
+ {
+ // send in current format (float as float, uint32 as uint32)
+ fieldBuffer << m_uint32Values[index];
+ }
+ }
+ }
+
+ *data << uint8(updateMask.GetBlockCount());
+ updateMask.AppendToPacket(data);
+ data->append(fieldBuffer);
+}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 3e8abdd404b..95aaf57a84f 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1597,27 +1597,19 @@ class Unit : public WorldObject
void MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath = false, bool forceDestination = false);
- /*! These methods send the same packet to the client in apply and unapply case.
- The client-side interpretation of this packet depends on the presence of relevant movementflags
- which are sent with movementinfo. Furthermore, these packets are broadcast to nearby players as well
- as the current unit.
- */
- void SendMovementHover();
- void SendMovementFeatherFall();
- void SendMovementWaterWalking();
- void SendMovementCanFlyChange();
- void SendMovementDisableGravity();
- void SendMovementWalkMode();
- void SendMovementSwimming();
void SendSetPlayHoverAnim(bool enable);
void SendMovementSetSplineAnim(Movement::AnimType anim);
- bool IsLevitating() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);}
- bool IsWalking() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING);}
+ bool IsLevitating() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); }
+ bool IsWalking() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING); }
virtual bool SetWalk(bool enable);
virtual bool SetDisableGravity(bool disable, bool packetOnly = false);
- virtual bool SetHover(bool enable);
+ virtual bool SetSwim(bool enable);
+ virtual bool SetCanFly(bool enable);
+ virtual bool SetWaterWalking(bool enable, bool packetOnly = false);
+ virtual bool SetFeatherFall(bool enable, bool packetOnly = false);
+ virtual bool SetHover(bool enable, bool packetOnly = false);
void SetInFront(WorldObject const* target);
void SetFacingTo(float ori);
@@ -2026,17 +2018,17 @@ class Unit : public WorldObject
bool IsStopped() const { return !(HasUnitState(UNIT_STATE_MOVING)); }
void StopMoving();
- void AddUnitMovementFlag(uint32 f) { m_movementInfo.flags |= f; }
- void RemoveUnitMovementFlag(uint32 f) { m_movementInfo.flags &= ~f; }
- bool HasUnitMovementFlag(uint32 f) const { return (m_movementInfo.flags & f) == f; }
- uint32 GetUnitMovementFlags() const { return m_movementInfo.flags; }
- void SetUnitMovementFlags(uint32 f) { m_movementInfo.flags = f; }
-
- void AddExtraUnitMovementFlag(uint16 f) { m_movementInfo.flags2 |= f; }
- void RemoveExtraUnitMovementFlag(uint16 f) { m_movementInfo.flags2 &= ~f; }
- uint16 HasExtraUnitMovementFlag(uint16 f) const { return m_movementInfo.flags2 & f; }
- uint16 GetExtraUnitMovementFlags() const { return m_movementInfo.flags2; }
- void SetExtraUnitMovementFlags(uint16 f) { m_movementInfo.flags2 = f; }
+ void AddUnitMovementFlag(uint32 f) { m_movementInfo.AddMovementFlag(f); }
+ void RemoveUnitMovementFlag(uint32 f) { m_movementInfo.RemoveMovementFlag(f); }
+ bool HasUnitMovementFlag(uint32 f) const { return m_movementInfo.HasMovementFlag(f); }
+ uint32 GetUnitMovementFlags() const { return m_movementInfo.GetMovementFlags(); }
+ void SetUnitMovementFlags(uint32 f) { m_movementInfo.SetMovementFlags(f); }
+
+ void AddExtraUnitMovementFlag(uint16 f) { m_movementInfo.AddExtraMovementFlag(f); }
+ void RemoveExtraUnitMovementFlag(uint16 f) { m_movementInfo.RemoveExtraMovementFlag(f); }
+ uint16 HasExtraUnitMovementFlag(uint16 f) const { return m_movementInfo.HasExtraMovementFlag(f); }
+ uint16 GetExtraUnitMovementFlags() const { return m_movementInfo.GetExtraMovementFlags(); }
+ void SetExtraUnitMovementFlags(uint16 f) { m_movementInfo.SetExtraMovementFlags(f); }
bool IsSplineEnabled() const;
float GetPositionZMinusOffset() const;
@@ -2094,12 +2086,12 @@ class Unit : public WorldObject
bool IsOnVehicle(const Unit* vehicle) const;
Unit* GetVehicleBase() const;
Creature* GetVehicleCreatureBase() const;
- float GetTransOffsetX() const { return m_movementInfo.t_pos.GetPositionX(); }
- float GetTransOffsetY() const { return m_movementInfo.t_pos.GetPositionY(); }
- float GetTransOffsetZ() const { return m_movementInfo.t_pos.GetPositionZ(); }
- float GetTransOffsetO() const { return m_movementInfo.t_pos.GetOrientation(); }
- uint32 GetTransTime() const { return m_movementInfo.t_time; }
- int8 GetTransSeat() const { return m_movementInfo.t_seat; }
+ float GetTransOffsetX() const { return m_movementInfo.transport.pos.GetPositionX(); }
+ float GetTransOffsetY() const { return m_movementInfo.transport.pos.GetPositionY(); }
+ float GetTransOffsetZ() const { return m_movementInfo.transport.pos.GetPositionZ(); }
+ float GetTransOffsetO() const { return m_movementInfo.transport.pos.GetOrientation(); }
+ uint32 GetTransTime() const { return m_movementInfo.transport.time; }
+ int8 GetTransSeat() const { return m_movementInfo.transport.seat; }
uint64 GetTransGUID() const;
/// Returns the transport this unit is on directly (if on vehicle and transport, return vehicle)
TransportBase* GetDirectTransport() const;
@@ -2122,7 +2114,6 @@ class Unit : public WorldObject
virtual bool CanFly() const = 0;
bool IsFlying() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_DISABLE_GRAVITY); }
bool IsFalling() const;
- void SetCanFly(bool apply);
void RewardRage(uint32 baseRage, bool attacker);
@@ -2157,6 +2148,8 @@ class Unit : public WorldObject
protected:
explicit Unit (bool isWorldObject);
+ void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const;
+
UnitAI* i_AI, *i_disabledAI;
void _UpdateSpells(uint32 time);
diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp
index 797430683f4..28429387400 100644
--- a/src/server/game/Entities/Vehicle/Vehicle.cpp
+++ b/src/server/game/Entities/Vehicle/Vehicle.cpp
@@ -517,7 +517,7 @@ Vehicle* Vehicle::RemovePassenger(Unit* unit)
_me->RemoveCharmedBy(unit);
if (_me->IsInWorld())
- unit->m_movementInfo.ClearTransport();
+ unit->m_movementInfo.ResetTransport();
// only for flyable vehicles
if (unit->IsFlying())
@@ -554,7 +554,7 @@ void Vehicle::RelocatePassengers()
ASSERT(passenger->IsInWorld());
float px, py, pz, po;
- passenger->m_movementInfo.t_pos.GetPosition(px, py, pz, po);
+ passenger->m_movementInfo.transport.pos.GetPosition(px, py, pz, po);
CalculatePassengerPosition(px, py, pz, &po);
passenger->UpdatePosition(px, py, pz, po);
@@ -837,10 +837,10 @@ bool VehicleJoinEvent::Execute(uint64, uint32)
Passenger->AddUnitState(UNIT_STATE_ONVEHICLE);
VehicleSeatEntry const* veSeat = Seat->second.SeatInfo;
- Passenger->m_movementInfo.t_pos.Relocate(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ);
- Passenger->m_movementInfo.t_time = 0; // 1 for player
- Passenger->m_movementInfo.t_seat = Seat->first;
- Passenger->m_movementInfo.t_guid = Target->GetBase()->GetGUID();
+ Passenger->m_movementInfo.transport.pos.Relocate(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ);
+ Passenger->m_movementInfo.transport.time = 0;
+ Passenger->m_movementInfo.transport.seat = Seat->first;
+ Passenger->m_movementInfo.transport.guid = Target->GetBase()->GetGUID();
if (Target->GetBase()->GetTypeId() == TYPEID_UNIT && Passenger->GetTypeId() == TYPEID_PLAYER &&
Seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_CAN_CONTROL)
diff --git a/src/server/game/Grids/GridDefines.h b/src/server/game/Grids/GridDefines.h
index 0cb2f32f621..1e4a9ca83b4 100644
--- a/src/server/game/Grids/GridDefines.h
+++ b/src/server/game/Grids/GridDefines.h
@@ -36,7 +36,7 @@ class AreaTrigger;
#define MAX_NUMBER_OF_GRIDS 64
-#define SIZE_OF_GRIDS 533.33333f
+#define SIZE_OF_GRIDS 533.3333f
#define CENTER_GRID_ID (MAX_NUMBER_OF_GRIDS/2)
#define CENTER_GRID_OFFSET (SIZE_OF_GRIDS/2)
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index bb7d4b1052f..6bd325f9114 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -1053,8 +1053,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form)
pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
- pCurrChar->AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
- pCurrChar->SendMovementWaterWalking();
+ pCurrChar->SetWaterWalking(true);
}
pCurrChar->ContinueTaxiFlight();
diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp
index d4bfc235595..79cb03c0ab3 100644
--- a/src/server/game/Handlers/GroupHandler.cpp
+++ b/src/server/game/Handlers/GroupHandler.cpp
@@ -1154,7 +1154,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke
if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
{
if (Vehicle* veh = player->GetVehicle())
- *data << uint32(veh->GetVehicleInfo()->m_seatID[player->m_movementInfo.t_seat]);
+ *data << uint32(veh->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]);
else
*data << uint32(0);
@@ -1335,7 +1335,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData)
data.put<uint64>(maskPos, petAuraMask); // GROUP_UPDATE_FLAG_PET_AURAS
if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
- data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.t_seat]);
+ data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]);
SendPacket(&data);
}
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index f45efe0b47e..cad1ef77daa 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -292,18 +292,18 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvPacket)
}
/* handle special cases */
- if (movementInfo.t_guid)
+ if (movementInfo.transport.guid)
{
// transports size limited
// (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
- if (movementInfo.t_pos.GetPositionX() > 50 || movementInfo.t_pos.GetPositionY() > 50 || movementInfo.t_pos.GetPositionZ() > 50)
+ if (movementInfo.transport.pos.GetPositionX() > 50 || movementInfo.transport.pos.GetPositionY() > 50 || movementInfo.transport.pos.GetPositionZ() > 50)
{
recvPacket.rfinish(); // prevent warnings spam
return;
}
- if (!Trinity::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.t_pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.t_pos.GetPositionY(),
- movementInfo.pos.GetPositionZ() + movementInfo.t_pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.t_pos.GetOrientation()))
+ if (!Trinity::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.transport.pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.transport.pos.GetPositionY(),
+ movementInfo.pos.GetPositionZ() + movementInfo.transport.pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.transport.pos.GetOrientation()))
{
recvPacket.rfinish(); // prevent warnings spam
return;
@@ -317,7 +317,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvPacket)
// elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just dismount if the guid can be found in the transport list
for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
{
- if ((*iter)->GetGUID() == movementInfo.t_guid)
+ if ((*iter)->GetGUID() == movementInfo.transport.guid)
{
plrMover->m_transport = *iter;
(*iter)->AddPassenger(plrMover);
@@ -325,13 +325,13 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvPacket)
}
}
}
- else if (plrMover->GetTransport()->GetGUID() != movementInfo.t_guid)
+ else if (plrMover->GetTransport()->GetGUID() != movementInfo.transport.guid)
{
bool foundNewTransport = false;
plrMover->m_transport->RemovePassenger(plrMover);
for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
{
- if ((*iter)->GetGUID() == movementInfo.t_guid)
+ if ((*iter)->GetGUID() == movementInfo.transport.guid)
{
foundNewTransport = true;
plrMover->m_transport = *iter;
@@ -343,25 +343,23 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvPacket)
if (!foundNewTransport)
{
plrMover->m_transport = NULL;
- movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
- movementInfo.t_time = 0;
- movementInfo.t_seat = -1;
+ movementInfo.ResetTransport();
}
}
}
if (!mover->GetTransport() && !mover->GetVehicle())
{
- GameObject* go = mover->GetMap()->GetGameObject(movementInfo.t_guid);
+ GameObject* go = mover->GetMap()->GetGameObject(movementInfo.transport.guid);
if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT)
- movementInfo.t_guid = 0;
+ movementInfo.transport.guid = 0;
}
}
else if (plrMover && plrMover->GetTransport()) // if we were on a transport, leave
{
plrMover->m_transport->RemovePassenger(plrMover);
plrMover->m_transport = NULL;
- movementInfo.ClearTransport();
+ movementInfo.ResetTransport();
}
// fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index 57faa5f3ebc..5ca07c095aa 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -4047,7 +4047,7 @@ enum PartyResult
};
const uint32 MMAP_MAGIC = 0x4d4d4150; // 'MMAP'
-#define MMAP_VERSION 3
+#define MMAP_VERSION 4
struct MmapTileHeader
{
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index 6ef93402606..ed30b59f0ec 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -97,7 +97,7 @@ dtPolyRef PathGenerator::GetPathPolyByPosition(dtPolyRef const* polyPath, uint32
for (uint32 i = 0; i < polyPathSize; ++i)
{
float closestPoint[VERTEX_SIZE];
- if (DT_SUCCESS != _navMeshQuery->closestPointOnPoly(polyPath[i], point, closestPoint))
+ if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(polyPath[i], point, closestPoint)))
continue;
float d = dtVdist2DSqr(point, closestPoint);
@@ -132,8 +132,7 @@ dtPolyRef PathGenerator::GetPolyByLocation(float const* point, float* distance)
// first try with low search box
float extents[VERTEX_SIZE] = {3.0f, 5.0f, 3.0f}; // bounds of poly search area
float closestPoint[VERTEX_SIZE] = {0.0f, 0.0f, 0.0f};
- dtStatus result = _navMeshQuery->findNearestPoly(point, extents, &_filter, &polyRef, closestPoint);
- if (DT_SUCCESS == result && polyRef != INVALID_POLYREF)
+ if (dtStatusSucceed(_navMeshQuery->findNearestPoly(point, extents, &_filter, &polyRef, closestPoint)) && polyRef != INVALID_POLYREF)
{
*distance = dtVdist(closestPoint, point);
return polyRef;
@@ -141,9 +140,10 @@ dtPolyRef PathGenerator::GetPolyByLocation(float const* point, float* distance)
// still nothing ..
// try with bigger search box
- extents[1] = 200.0f;
- result = _navMeshQuery->findNearestPoly(point, extents, &_filter, &polyRef, closestPoint);
- if (DT_SUCCESS == result && polyRef != INVALID_POLYREF)
+ // Note that the extent should not overlap more than 128 polygons in the navmesh (see dtNavMeshQuery::findNearestPoly)
+ extents[1] = 50.0f;
+
+ if (dtStatusSucceed(_navMeshQuery->findNearestPoly(point, extents, &_filter, &polyRef, closestPoint)) && polyRef != INVALID_POLYREF)
{
*distance = dtVdist(closestPoint, point);
return polyRef;
@@ -228,7 +228,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
{
float closestPoint[VERTEX_SIZE];
// we may want to use closestPointOnPolyBoundary instead
- if (DT_SUCCESS == _navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint))
+ if (dtStatusSucceed(_navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint)))
{
dtVcopy(endPoint, closestPoint);
SetActualEndPosition(G3D::Vector3(endPoint[2], endPoint[0], endPoint[1]));
@@ -319,13 +319,13 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
// we need any point on our suffix start poly to generate poly-path, so we need last poly in prefix data
float suffixEndPoint[VERTEX_SIZE];
- if (DT_SUCCESS != _navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint))
+ if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint)))
{
// we can hit offmesh connection as last poly - closestPointOnPoly() don't like that
// try to recover by using prev polyref
--prefixPolyLength;
suffixStartPoly = _pathPolyRefs[prefixPolyLength-1];
- if (DT_SUCCESS != _navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint))
+ if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint)))
{
// suffixStartPoly is still invalid, error state
BuildShortcut();
@@ -346,7 +346,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
(int*)&suffixPolyLength,
MAX_PATH_LENGTH-prefixPolyLength); // max number of polygons in output path
- if (!suffixPolyLength || dtResult != DT_SUCCESS)
+ if (!suffixPolyLength || dtStatusFailed(dtResult))
{
// this is probably an error state, but we'll leave it
// and hopefully recover on the next Update
@@ -380,7 +380,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con
(int*)&_polyLength,
MAX_PATH_LENGTH); // max number of polygons in output path
- if (!_polyLength || dtResult != DT_SUCCESS)
+ if (!_polyLength || dtStatusFailed(dtResult))
{
// only happens if we passed bad data to findPath(), or navmesh is messed up
TC_LOG_ERROR(LOG_FILTER_MAPS, "%u's Path Build failed: 0 length path", _sourceUnit->GetGUIDLow());
@@ -430,7 +430,7 @@ void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoin
_pointPathLimit); // maximum number of points
}
- if (pointCount < 2 || dtResult != DT_SUCCESS)
+ if (pointCount < 2 || dtStatusFailed(dtResult))
{
// only happens if pass bad data to findStraightPath or navmesh is broken
// single point paths can be generated here
@@ -577,7 +577,7 @@ bool PathGenerator::HaveTile(const G3D::Vector3& p) const
if (tx < 0 || ty < 0)
return false;
- return (_navMesh->getTileAt(tx, ty) != NULL);
+ return (_navMesh->getTileAt(tx, ty, 0) != NULL);
}
uint32 PathGenerator::FixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, dtPolyRef const* visited, uint32 nvisited)
@@ -637,7 +637,7 @@ bool PathGenerator::GetSteerTarget(float const* startPos, float const* endPos,
uint32 nsteerPath = 0;
dtStatus dtResult = _navMeshQuery->findStraightPath(startPos, endPos, path, pathSize,
steerPath, steerPathFlags, steerPathPolys, (int*)&nsteerPath, MAX_STEER_POINTS);
- if (!nsteerPath || DT_SUCCESS != dtResult)
+ if (!nsteerPath || dtStatusFailed(dtResult))
return false;
// Find vertex far enough to steer to.
@@ -674,10 +674,10 @@ dtStatus PathGenerator::FindSmoothPath(float const* startPos, float const* endPo
uint32 npolys = polyPathSize;
float iterPos[VERTEX_SIZE], targetPos[VERTEX_SIZE];
- if (DT_SUCCESS != _navMeshQuery->closestPointOnPolyBoundary(polys[0], startPos, iterPos))
+ if (dtStatusFailed(_navMeshQuery->closestPointOnPolyBoundary(polys[0], startPos, iterPos)))
return DT_FAILURE;
- if (DT_SUCCESS != _navMeshQuery->closestPointOnPolyBoundary(polys[npolys-1], endPos, targetPos))
+ if (dtStatusFailed(_navMeshQuery->closestPointOnPolyBoundary(polys[npolys-1], endPos, targetPos)))
return DT_FAILURE;
dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos);
@@ -756,7 +756,7 @@ dtStatus PathGenerator::FindSmoothPath(float const* startPos, float const* endPo
// Handle the connection.
float startPos[VERTEX_SIZE], endPos[VERTEX_SIZE];
- if (DT_SUCCESS == _navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos))
+ if (dtStatusSucceed(_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos)))
{
if (nsmoothPath < maxSmoothPathSize)
{
diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp
index 02be702d3c2..1a35271c8c6 100644
--- a/src/server/game/Movement/Spline/MoveSpline.cpp
+++ b/src/server/game/Movement/Spline/MoveSpline.cpp
@@ -23,10 +23,6 @@
namespace Movement{
-extern float computeFallTime(float path_length, bool isSafeFall);
-extern float computeFallElevation(float time_passed, bool isSafeFall, float start_velocy);
-extern float computeFallElevation(float time_passed);
-
Location MoveSpline::ComputePosition() const
{
ASSERT(Initialized());
@@ -84,12 +80,9 @@ void MoveSpline::computeParabolicElevation(float& el) const
void MoveSpline::computeFallElevation(float& el) const
{
- float z_now = spline.getPoint(spline.first()).z - Movement::computeFallElevation(MSToSec(time_passed));
+ float z_now = spline.getPoint(spline.first()).z - Movement::computeFallElevation(MSToSec(time_passed), false);
float final_z = FinalDestination().z;
- if (z_now < final_z)
- el = final_z;
- else
- el = z_now;
+ el = std::max(z_now, final_z);
}
inline uint32 computeDuration(float length, float velocity)
@@ -160,7 +153,7 @@ void MoveSpline::init_spline(const MoveSplineInitArgs& args)
point_Idx = spline.first();
}
-void MoveSpline::Initialize(const MoveSplineInitArgs& args)
+void MoveSpline::Initialize(MoveSplineInitArgs const& args)
{
splineflags = args.flags;
facing = args.facing;
@@ -168,7 +161,6 @@ void MoveSpline::Initialize(const MoveSplineInitArgs& args)
point_Idx_offset = args.path_Idx_offset;
initialOrientation = args.initialOrientation;
- onTransport = false;
time_passed = 0;
vertical_acceleration = 0.f;
effect_start_time = 0;
@@ -196,7 +188,8 @@ void MoveSpline::Initialize(const MoveSplineInitArgs& args)
}
MoveSpline::MoveSpline() : m_Id(0), time_passed(0),
- vertical_acceleration(0.f), initialOrientation(0.f), effect_start_time(0), point_Idx(0), point_Idx_offset(0)
+ vertical_acceleration(0.f), initialOrientation(0.f), effect_start_time(0), point_Idx(0), point_Idx_offset(0),
+ onTransport(false)
{
splineflags.done = true;
}
diff --git a/src/server/game/Movement/Spline/MoveSpline.h b/src/server/game/Movement/Spline/MoveSpline.h
index a76c552079b..75ea89bee81 100644
--- a/src/server/game/Movement/Spline/MoveSpline.h
+++ b/src/server/game/Movement/Spline/MoveSpline.h
@@ -49,6 +49,7 @@ namespace Movement
Result_NextSegment = 0x08
};
friend class PacketBuilder;
+
protected:
MySpline spline;
@@ -69,30 +70,30 @@ namespace Movement
int32 point_Idx_offset;
void init_spline(const MoveSplineInitArgs& args);
- protected:
- const MySpline::ControlArray& getPath() const { return spline.getPoints(); }
+ protected:
+ MySpline::ControlArray const& getPath() const { return spline.getPoints(); }
void computeParabolicElevation(float& el) const;
void computeFallElevation(float& el) const;
UpdateResult _updateState(int32& ms_time_diff);
- int32 next_timestamp() const { return spline.length(point_Idx+1); }
- int32 segment_time_elapsed() const { return next_timestamp()-time_passed; }
+ int32 next_timestamp() const { return spline.length(point_Idx + 1); }
+ int32 segment_time_elapsed() const { return next_timestamp() - time_passed; }
int32 timeElapsed() const { return Duration() - time_passed; }
int32 timePassed() const { return time_passed; }
public:
int32 Duration() const { return spline.length(); }
- const MySpline& _Spline() const { return spline; }
+ MySpline const& _Spline() const { return spline; }
int32 _currentSplineIdx() const { return point_Idx; }
void _Finalize();
- void _Interrupt() { splineflags.done = true;}
+ void _Interrupt() { splineflags.done = true; }
public:
void Initialize(const MoveSplineInitArgs&);
bool Initialized() const { return !spline.empty(); }
- explicit MoveSpline();
+ MoveSpline();
template<class UpdateHandler>
void updateState(int32 difftime, UpdateHandler& handler)
@@ -116,8 +117,8 @@ namespace Movement
bool Finalized() const { return splineflags.done; }
bool isCyclic() const { return splineflags.cyclic; }
bool isFalling() const { return splineflags.falling; }
- const Vector3 FinalDestination() const { return Initialized() ? spline.getPoint(spline.last()) : Vector3(); }
- const Vector3 CurrentDestination() const { return Initialized() ? spline.getPoint(point_Idx+1) : Vector3(); }
+ Vector3 FinalDestination() const { return Initialized() ? spline.getPoint(spline.last()) : Vector3(); }
+ Vector3 CurrentDestination() const { return Initialized() ? spline.getPoint(point_Idx + 1) : Vector3(); }
int32 currentPathIdx() const;
bool onTransport;
diff --git a/src/server/game/Movement/Spline/MoveSplineFlag.h b/src/server/game/Movement/Spline/MoveSplineFlag.h
index 08e73c0344b..f86ce6431ed 100644
--- a/src/server/game/Movement/Spline/MoveSplineFlag.h
+++ b/src/server/game/Movement/Spline/MoveSplineFlag.h
@@ -104,7 +104,8 @@ namespace Movement
void EnableAnimation(uint8 anim) { raw() = (raw() & ~(Mask_Animations | Falling | Parabolic | FallingSlow)) | Animation | (anim & Mask_Animations); }
void EnableParabolic() { raw() = (raw() & ~(Mask_Animations | Falling | Animation | FallingSlow)) | Parabolic; }
- void EnableFalling() { raw() = (raw() & ~(Mask_Animations | Parabolic | Animation)) | Falling; }
+ void EnableFlying() { raw() = (raw() & ~(Falling)) | Flying; }
+ void EnableFalling() { raw() = (raw() & ~(Mask_Animations | Parabolic | Animation | Flying)) | Falling; }
void EnableCatmullRom() { raw() = (raw() & ~SmoothGroundPath) | Catmullrom; }
void EnableFacingPoint() { raw() = (raw() & ~Mask_Final_Facing) | Final_Point; }
void EnableFacingAngle() { raw() = (raw() & ~Mask_Final_Facing) | Final_Angle; }
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp
index 9cc1dbb3f43..65af02360e6 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.cpp
+++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp
@@ -98,6 +98,8 @@ namespace Movement
uint32 moveFlagsForSpeed = moveFlags;
if (args.flags.walkmode)
moveFlagsForSpeed |= MOVEMENTFLAG_WALKING;
+ else
+ moveFlagsForSpeed &= ~MOVEMENTFLAG_WALKING;
args.velocity = unit->GetSpeed(SelectSpeedType(moveFlagsForSpeed));
}
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h
index 1eaf1011a2c..c968f660f58 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.h
+++ b/src/server/game/Movement/Spline/MoveSplineInit.h
@@ -157,7 +157,7 @@ namespace Movement
Unit* unit;
};
- inline void MoveSplineInit::SetFly() { args.flags.flying = true; }
+ inline void MoveSplineInit::SetFly() { args.flags.EnableFlying(); }
inline void MoveSplineInit::SetWalk(bool enable) { args.flags.walkmode = enable; }
inline void MoveSplineInit::SetSmooth() { args.flags.EnableCatmullRom(); }
inline void MoveSplineInit::SetUncompressed() { args.flags.uncompressedPath = true; }
diff --git a/src/server/game/Movement/Spline/MoveSplineInitArgs.h b/src/server/game/Movement/Spline/MoveSplineInitArgs.h
index 4a086094c3f..474541cbf15 100644
--- a/src/server/game/Movement/Spline/MoveSplineInitArgs.h
+++ b/src/server/game/Movement/Spline/MoveSplineInitArgs.h
@@ -30,9 +30,9 @@ namespace Movement
union FacingInfo
{
- struct{
+ struct {
float x, y, z;
- }f;
+ } f;
uint64 target;
float angle;
@@ -43,8 +43,8 @@ namespace Movement
struct MoveSplineInitArgs
{
- MoveSplineInitArgs(size_t path_capacity = 16) : path_Idx_offset(0),
- velocity(0.f), parabolic_amplitude(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f),
+ MoveSplineInitArgs(size_t path_capacity = 16) : path_Idx_offset(0), velocity(0.f),
+ parabolic_amplitude(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f),
HasVelocity(false), TransformForTransport(true)
{
path.reserve(path_capacity);
@@ -64,6 +64,7 @@ namespace Movement
/** Returns true to show that the arguments were configured correctly and MoveSpline initialization will succeed. */
bool Validate(Unit* unit) const;
+
private:
bool _checkPathBounds() const;
};
diff --git a/src/server/game/Movement/Spline/MovementTypedefs.h b/src/server/game/Movement/Spline/MovementTypedefs.h
index f044d249fcb..1a0f3d54d27 100644
--- a/src/server/game/Movement/Spline/MovementTypedefs.h
+++ b/src/server/game/Movement/Spline/MovementTypedefs.h
@@ -44,6 +44,9 @@ namespace Movement
return ms / 1000.f;
}
+ float computeFallTime(float path_length, bool isSafeFall);
+ float computeFallElevation(float t_passed, bool isSafeFall, float start_velocity = 0.0f);
+
#ifndef static_assert
#define CONCAT(x, y) CONCAT1 (x, y)
#define CONCAT1(x, y) x##y
@@ -75,7 +78,6 @@ namespace Movement
typedef counter<uint32, 0xFFFFFFFF> UInt32Counter;
extern double gravity;
- extern float computeFallElevation(float t_passed, bool isSafeFall, float start_velocity);
extern UInt32Counter splineIdGen;
extern std::string MovementFlags_ToString(uint32 flags);
extern std::string MovementFlagsExtra_ToString(uint32 flags);
diff --git a/src/server/game/Movement/Spline/MovementUtil.cpp b/src/server/game/Movement/Spline/MovementUtil.cpp
index aaa575c752f..ee47a5ebedc 100644
--- a/src/server/game/Movement/Spline/MovementUtil.cpp
+++ b/src/server/game/Movement/Spline/MovementUtil.cpp
@@ -30,8 +30,9 @@ namespace Movement
float terminalSafefallVelocity = 7.0f;
const float terminal_length = float(terminalVelocity * terminalVelocity) / (2.0f * gravity);
- const float terminal_safefall_length = (terminalSafefallVelocity * terminalSafefallVelocity) / (2.0f * gravity);
- const float terminalFallTime = float(terminalVelocity / gravity); // the time that needed to reach terminalVelocity
+ const float terminal_safeFall_length = (terminalSafefallVelocity * terminalSafefallVelocity) / (2.0f * gravity);
+ const float terminal_fallTime = float(terminalVelocity / gravity); // the time that needed to reach terminalVelocity
+ const float terminal_safeFall_fallTime = float(terminalSafefallVelocity / gravity); // the time that needed to reach terminalVelocity with safefall
float computeFallTime(float path_length, bool isSafeFall)
{
@@ -41,15 +42,15 @@ namespace Movement
float time;
if (isSafeFall)
{
- if (path_length >= terminal_safefall_length)
- time = (path_length - terminal_safefall_length) / terminalSafefallVelocity + terminalSafefallVelocity / gravity;
+ if (path_length >= terminal_safeFall_length)
+ time = (path_length - terminal_safeFall_length) / terminalSafefallVelocity + terminal_safeFall_fallTime;
else
time = sqrtf(2.0f * path_length / gravity);
}
else
{
if (path_length >= terminal_length)
- time = (path_length - terminal_length) / terminalVelocity + terminalFallTime;
+ time = (path_length - terminal_length) / terminalVelocity + terminal_fallTime;
else
time = sqrtf(2.0f * path_length / gravity);
}
@@ -57,7 +58,7 @@ namespace Movement
return time;
}
- float computeFallElevation(float t_passed, bool isSafeFall, float start_velocity)
+ float computeFallElevation(float t_passed, bool isSafeFall, float start_velocity /*= 0.0f*/)
{
float termVel;
float result;
@@ -70,11 +71,11 @@ namespace Movement
if (start_velocity > termVel)
start_velocity = termVel;
- float terminal_time = terminalFallTime - start_velocity / gravity; // the time that needed to reach terminalVelocity
+ float terminal_time = (isSafeFall ? terminal_safeFall_fallTime : terminal_fallTime) - start_velocity / gravity; // the time that needed to reach terminalVelocity
if (t_passed > terminal_time)
{
- result = terminalVelocity * (t_passed - terminal_time) +
+ result = termVel * (t_passed - terminal_time) +
start_velocity * terminal_time +
gravity * terminal_time * terminal_time*0.5f;
}
@@ -84,22 +85,6 @@ namespace Movement
return result;
}
- float computeFallElevation(float t_passed)
- {
- float result;
-
- if (t_passed > terminalFallTime)
- {
- //result = terminalVelocity * (t_passed - terminal_time) + gravity*terminal_time*terminal_time*0.5f;
- // simplified view:
- result = terminalVelocity * (t_passed - terminalFallTime) + terminal_length;
- }
- else
- result = t_passed * t_passed * gravity * 0.5f;
-
- return result;
- }
-
#define STR(x) #x
char const* g_MovementFlag_names[] =
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 9acc4a15dc4..e6e5386626d 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -1216,7 +1216,6 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_FLYING, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_WATER_WALK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_STABLE_RESULT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_STANDSTATE_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_START_MIRROR_TIMER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index cd72faf5740..0c6d7c82c06 100644
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -1295,7 +1295,7 @@ enum Opcodes
SMSG_SPLINE_MOVE_SET_TURN_RATE = 0x78B5,
SMSG_SPLINE_MOVE_SET_WALK_MODE = 0x54B6,
SMSG_SPLINE_MOVE_SET_WALK_SPEED = 0x34A5,
- SMSG_SPLINE_MOVE_SET_WATER_WALK = 0x0000,
+ SMSG_SPLINE_MOVE_SET_WATER_WALK = 0x50A2,
SMSG_SPLINE_MOVE_START_SWIM = 0x31A5,
SMSG_SPLINE_MOVE_STOP_SWIM = 0x1DA2,
SMSG_SPLINE_MOVE_UNROOT = 0x75B6,
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index faaedf42b74..58f49f72cfd 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -2650,23 +2650,17 @@ void AuraEffect::HandleAuraAllowFlight(AuraApplication const* aurApp, uint8 mode
}
//! Not entirely sure if this should be sent for creatures as well, but I don't think so.
- target->SetCanFly(apply);
if (!apply)
{
- target->RemoveUnitMovementFlag(MOVEMENTFLAG_MASK_MOVING_FLY);
- target->GetMotionMaster()->MoveFall();
target->m_movementInfo.SetFallTime(0);
+ target->RemoveUnitMovementFlag(MOVEMENTFLAG_MASK_MOVING_FLY);
+ target->AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
}
- Player* player = target->ToPlayer();
- if (!player)
- player = target->m_movedPlayer;
-
- if (player)
- player->SendMovementCanFlyChange();
+ target->SetCanFly(apply);
- //! We still need to initiate a server-side MoveFall here,
- //! which requires MSG_MOVE_FALL_LAND on landing.
+ if (target->GetTypeId() == TYPEID_UNIT)
+ target->GetMotionMaster()->MoveFall();
}
void AuraEffect::HandleAuraWaterWalk(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -2683,12 +2677,7 @@ void AuraEffect::HandleAuraWaterWalk(AuraApplication const* aurApp, uint8 mode,
return;
}
- if (apply)
- target->AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
- else
- target->RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
-
- target->SendMovementWaterWalking();
+ target->SetWaterWalking(apply);
}
void AuraEffect::HandleAuraFeatherFall(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -2705,12 +2694,7 @@ void AuraEffect::HandleAuraFeatherFall(AuraApplication const* aurApp, uint8 mode
return;
}
- if (apply)
- target->AddUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
- else
- target->RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
-
- target->SendMovementFeatherFall();
+ target->SetFeatherFall(apply);
// start fall from current height
if (!apply && target->GetTypeId() == TYPEID_PLAYER)
@@ -2732,7 +2716,6 @@ void AuraEffect::HandleAuraHover(AuraApplication const* aurApp, uint8 mode, bool
}
target->SetHover(apply); //! Sets movementflags
- target->SendMovementHover();
}
void AuraEffect::HandleWaterBreathing(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
@@ -3054,6 +3037,8 @@ void AuraEffect::HandleAuraModIncreaseFlightSpeed(AuraApplication const* aurApp,
return;
Unit* target = aurApp->GetTarget();
+ if (mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK)
+ target->UpdateSpeed(MOVE_FLIGHT, true);
//! Update ability to fly
if (GetAuraType() == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED)
@@ -3061,22 +3046,17 @@ void AuraEffect::HandleAuraModIncreaseFlightSpeed(AuraApplication const* aurApp,
// do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
if (mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK && (apply || (!target->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !target->HasAuraType(SPELL_AURA_FLY))))
{
- target->SetCanFly(apply);
if (!apply)
{
target->m_movementInfo.SetFallTime(0);
target->RemoveUnitMovementFlag(MOVEMENTFLAG_MASK_MOVING_FLY);
+ target->AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
}
- Player* player = target->ToPlayer();
- if (!player)
- player = target->m_movedPlayer;
-
- if (player)
- player->SendMovementCanFlyChange();
+ target->SetCanFly(apply);
- //! We still need to initiate a server-side MoveFall here,
- //! which requires MSG_MOVE_FALL_LAND on landing.
+ if (target->GetTypeId() == TYPEID_UNIT)
+ target->GetMotionMaster()->MoveFall();
}
//! Someone should clean up these hacks and remove it from this function. It doesn't even belong here.
@@ -3091,9 +3071,6 @@ void AuraEffect::HandleAuraModIncreaseFlightSpeed(AuraApplication const* aurApp,
target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 16314);
}
}
-
- if (mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK)
- target->UpdateSpeed(MOVE_FLIGHT, true);
}
void AuraEffect::HandleAuraModIncreaseSwimSpeed(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
diff --git a/src/server/scripts/Commands/cs_cheat.cpp b/src/server/scripts/Commands/cs_cheat.cpp
index aeac475fdb1..a5199ce75b4 100644
--- a/src/server/scripts/Commands/cs_cheat.cpp
+++ b/src/server/scripts/Commands/cs_cheat.cpp
@@ -198,16 +198,14 @@ public:
if (argstr == "off")
{
target->SetCommandStatusOff(CHEAT_WATERWALK);
- target->RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
- target->SendMovementWaterWalking(); // OFF
+ target->SetWaterWalking(false);
handler->SendSysMessage("Waterwalking is OFF. You can't walk on water.");
return true;
}
else if (argstr == "on")
{
target->SetCommandStatusOn(CHEAT_WATERWALK);
- target->AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
- target->SendMovementWaterWalking(); // ON
+ target->SetWaterWalking(true);
handler->SendSysMessage("Waterwalking is ON. You can walk on water.");
return true;
}
diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp
index c484f7ef753..f837680d570 100644
--- a/src/server/scripts/Commands/cs_gm.cpp
+++ b/src/server/scripts/Commands/cs_gm.cpp
@@ -103,15 +103,9 @@ public:
WorldPacket data;
if (strncmp(args, "on", 3) == 0)
- {
- target->AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
- target->SendMovementCanFlyChange();
- }
+ target->SetCanFly(true);
else if (strncmp(args, "off", 4) == 0)
- {
- target->RemoveUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
- target->SendMovementCanFlyChange();
- }
+ target->SetCanFly(false);
else
{
handler->SendSysMessage(LANG_USE_BOL);
diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp
index 49fa87b5d68..2428cb0a239 100644
--- a/src/server/scripts/Commands/cs_mmaps.cpp
+++ b/src/server/scripts/Commands/cs_mmaps.cpp
@@ -153,7 +153,11 @@ public:
// navmesh poly -> navmesh tile location
dtQueryFilter filter = dtQueryFilter();
dtPolyRef polyRef = INVALID_POLYREF;
- navmeshquery->findNearestPoly(location, extents, &filter, &polyRef, NULL);
+ if (dtStatusFailed(navmeshquery->findNearestPoly(location, extents, &filter, &polyRef, NULL)))
+ {
+ handler->PSendSysMessage("Dt [??,??] (invalid poly, probably no tile loaded)");
+ return true;
+ }
if (polyRef == INVALID_POLYREF)
handler->PSendSysMessage("Dt [??, ??] (invalid poly, probably no tile loaded)");
@@ -161,11 +165,16 @@ public:
{
dtMeshTile const* tile;
dtPoly const* poly;
- navmesh->getTileAndPolyByRef(polyRef, &tile, &poly);
- if (tile)
- handler->PSendSysMessage("Dt [%02i, %02i]", tile->header->x, tile->header->y);
- else
- handler->PSendSysMessage("Dt [??, ??] (no tile loaded)");
+ if (dtStatusSucceed(navmesh->getTileAndPolyByRef(polyRef, &tile, &poly)))
+ {
+ if (tile)
+ {
+ handler->PSendSysMessage("Dt [%02i,%02i]", tile->header->x, tile->header->y);
+ return false;
+ }
+ }
+
+ handler->PSendSysMessage("Dt [??,??] (no tile loaded)");
}
return true;
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp
index da2dadc656a..7b833b07abb 100644
--- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp
@@ -443,7 +443,7 @@ public:
{
me->SetVisible(false);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
+ me->SetDisableGravity(true);
me->SetSpeed(MOVE_WALK, 5.0f, true);
wp_reached = false;
count = 0;
@@ -476,7 +476,7 @@ public:
instance->SetData(GAMEOBJECT_PUMPKIN_SHRINE, 0); //hide gameobject
break;
case 19:
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
+ me->SetDisableGravity(false);
break;
case 20:
{
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp
index ea8509ffc7c..6af7634a90a 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_felmyst.cpp
@@ -248,7 +248,7 @@ public:
case PHASE_GROUND:
me->CastStop(SPELL_FOG_BREATH);
me->RemoveAurasDueToSpell(SPELL_FOG_BREATH);
- me->SetUnitMovementFlags(MOVEMENTFLAG_NONE);
+ me->StopMoving();
me->SetSpeed(MOVE_RUN, 2.0f);
events.ScheduleEvent(EVENT_CLEAVE, urand(5000, 10000));
@@ -258,7 +258,7 @@ public:
events.ScheduleEvent(EVENT_FLIGHT, 60000);
break;
case PHASE_FLIGHT:
- me->SetUnitMovementFlags(MOVEMENTFLAG_DISABLE_GRAVITY);
+ me->SetDisableGravity(true);
events.ScheduleEvent(EVENT_FLIGHT_SEQUENCE, 1000);
uiFlightCount = 0;
uiBreathCount = 0;
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
index e493abf936d..a051274d1b1 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_kiljaeden.cpp
@@ -254,7 +254,7 @@ public:
{
OrbsEmpowered = 0;
EmpowerCount = 0;
- me->AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
+ me->SetDisableGravity(true);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->setActive(true);
@@ -442,7 +442,7 @@ public:
summoned->CastSpell(summoned, SPELL_SHADOW_CHANNELING, false);
break;
case CREATURE_ANVEENA:
- summoned->AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
+ summoned->SetDisableGravity(true);
summoned->CastSpell(summoned, SPELL_ANVEENA_PRISON, true);
summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
break;
diff --git a/src/server/scripts/EasternKingdoms/Uldaman/uldaman.cpp b/src/server/scripts/EasternKingdoms/Uldaman/uldaman.cpp
index 250e41aebd3..3a84c79afdc 100644
--- a/src/server/scripts/EasternKingdoms/Uldaman/uldaman.cpp
+++ b/src/server/scripts/EasternKingdoms/Uldaman/uldaman.cpp
@@ -25,7 +25,6 @@ EndScriptData */
/* ContentData
mob_jadespine_basilisk
-npc_lore_keeper_of_norgannon
go_keystone_chamber
at_map_chamber
EndContentData */
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp
index 2b1cc2590ca..a4749d63cb2 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/ObsidianSanctum/boss_sartharion.cpp
@@ -479,8 +479,7 @@ public:
{
if (temp->IsAlive() && !temp->GetVictim())
{
- if (temp->HasUnitMovementFlag(MOVEMENTFLAG_WALKING))
- temp->SetWalk(false);
+ temp->SetWalk(false);
if (temp->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
temp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
index e74d420a741..b2b629dd510 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
@@ -132,9 +132,9 @@ bool GrandChampionsOutVehicle(Creature* me)
if (pGrandChampion1 && pGrandChampion2 && pGrandChampion3)
{
- if (!pGrandChampion1->m_movementInfo.t_guid &&
- !pGrandChampion2->m_movementInfo.t_guid &&
- !pGrandChampion3->m_movementInfo.t_guid)
+ if (!pGrandChampion1->m_movementInfo.transport.guid &&
+ !pGrandChampion2->m_movementInfo.transport.guid &&
+ !pGrandChampion3->m_movementInfo.transport.guid)
return true;
}
@@ -386,7 +386,7 @@ public:
}
}else uiPhaseTimer -= uiDiff;
- if (!UpdateVictim() || me->m_movementInfo.t_guid)
+ if (!UpdateVictim() || me->m_movementInfo.transport.guid)
return;
if (uiInterceptTimer <= uiDiff)
@@ -530,7 +530,7 @@ public:
uiFireBallTimer = 5000;
} else uiFireBallTimer -= uiDiff;
- if (!UpdateVictim() || me->m_movementInfo.t_guid)
+ if (!UpdateVictim() || me->m_movementInfo.transport.guid)
return;
if (uiFireBallTimer <= uiDiff)
@@ -668,7 +668,7 @@ public:
}
}else uiPhaseTimer -= uiDiff;
- if (!UpdateVictim() || me->m_movementInfo.t_guid)
+ if (!UpdateVictim() || me->m_movementInfo.transport.guid)
return;
if (uiChainLightningTimer <= uiDiff)
@@ -814,7 +814,7 @@ public:
}
}else uiPhaseTimer -= uiDiff;
- if (!UpdateVictim() || me->m_movementInfo.t_guid)
+ if (!UpdateVictim() || me->m_movementInfo.transport.guid)
return;
if (uiLightningArrowsTimer <= uiDiff)
@@ -962,7 +962,7 @@ public:
}
} else uiPhaseTimer -= uiDiff;
- if (!UpdateVictim() || me->m_movementInfo.t_guid)
+ if (!UpdateVictim() || me->m_movementInfo.transport.guid)
return;
if (uiEviscerateTimer <= uiDiff)
diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
index abdd5db9d6f..efe9697a358 100644
--- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
@@ -431,7 +431,7 @@ class npc_jaina_or_sylvanas_hor : public CreatureScript
// Spawn LK in front of door, and make him move to the sword.
if (Creature* lichking = me->SummonCreature(NPC_LICH_KING_PART1, LichKingSpawnPos, TEMPSUMMON_MANUAL_DESPAWN))
{
- lichking->SetUnitMovementFlags(MOVEMENTFLAG_WALKING);
+ lichking->SetWalk(true);
lichking->GetMotionMaster()->MovePoint(0, LichKingMoveThronePos);
//lichking->SetReactState(REACT_PASSIVE);
lichkingGUID = lichking->GetGUID();
@@ -494,7 +494,7 @@ class npc_jaina_or_sylvanas_hor : public CreatureScript
if (Creature* lichking = me->GetCreature(*me, lichkingGUID))
{
lichking->AI()->Talk(SAY_LK_INTRO_3);
- lichking->SetUnitMovementFlags(MOVEMENTFLAG_WALKING);
+ lichking->SetWalk(true);
lichking->GetMotionMaster()->MovePoint(0, LichKingMoveAwayPos);
}
events.ScheduleEvent(EVENT_INTRO_LK_7, 10000);
@@ -554,7 +554,7 @@ class npc_jaina_or_sylvanas_hor : public CreatureScript
/// @todo Loralen/Koreln shall run also
if (Creature* lichking = me->SummonCreature(NPC_LICH_KING_PART1, LichKingSpawnPos, TEMPSUMMON_MANUAL_DESPAWN))
{
- lichking->SetUnitMovementFlags(MOVEMENTFLAG_WALKING);
+ lichking->SetWalk(true);
lichking->GetMotionMaster()->MovePoint(0, LichKingMoveThronePos);
lichking->SetReactState(REACT_PASSIVE);
lichkingGUID = lichking->GetGUID();
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp b/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp
index bf513b51855..1f1954cb00c 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/boss_urom.cpp
@@ -277,7 +277,7 @@ public:
me->NearTeleportTo(pPos.GetPositionX(), pPos.GetPositionY(), pPos.GetPositionZ(), pPos.GetOrientation());
me->GetMotionMaster()->MoveChase(me->GetVictim(), 0, 0);
- me->SetUnitMovementFlags(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
Talk(EMOTE_ARCANE_EXPLOSION);
Talk(SAY_ARCANE_EXPLOSION);
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
index 023ef126dd3..51d3913a084 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
@@ -311,11 +311,7 @@ public:
void Reset()
{
//! HACK: Creature's can't have MOVEMENTFLAG_FLYING
- me->AddUnitMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_HOVER);
- me->SetSpeed(MOVE_SWIM, 1.0f);
- me->SetSpeed(MOVE_RUN, 1.0f);
- me->SetSpeed(MOVE_WALK, 1.0f);
- //me->SetSpeed(MOVE_FLIGHT, 1.0f);
+ me->SetHover(true);
me->GetPosition(x, y, z);
DoTeleportTo(x+1, y, z+30);
diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp
index fc9d79296cb..fffb87ed022 100644
--- a/src/server/scripts/Northrend/zone_borean_tundra.cpp
+++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp
@@ -812,7 +812,10 @@ public:
struct npc_nexus_drake_hatchlingAI : public FollowerAI //The spell who makes the npc follow the player is missing, also we can use FollowerAI!
{
- npc_nexus_drake_hatchlingAI(Creature* creature) : FollowerAI(creature) {}
+ npc_nexus_drake_hatchlingAI(Creature* creature) : FollowerAI(creature)
+ {
+ HarpoonerGUID = 0;
+ }
uint64 HarpoonerGUID;
bool WithRedDragonBlood;
diff --git a/src/server/scripts/Northrend/zone_grizzly_hills.cpp b/src/server/scripts/Northrend/zone_grizzly_hills.cpp
index 0f3a312c1bc..560ab86e3e4 100644
--- a/src/server/scripts/Northrend/zone_grizzly_hills.cpp
+++ b/src/server/scripts/Northrend/zone_grizzly_hills.cpp
@@ -27,33 +27,34 @@
## Quest 12027: Mr. Floppy's Perilous Adventure
######*/
-enum eFloppy
+enum Floppy
{
+ // Creature
NPC_MRFLOPPY = 26589,
NPC_HUNGRY_WORG = 26586,
- NPC_RAVENOUS_WORG = 26590, //RWORG
+ NPC_RAVENOUS_WORG = 26590, // RWORG
NPC_EMILY = 26588,
-
+ // Quest
QUEST_PERILOUS_ADVENTURE = 12027,
-
- SPELL_MRFLOPPY = 47184, //vehicle aura
-
- SAY_WORGHAGGRO1 = 0, //Um... I think one of those wolves is back...
- SAY_WORGHAGGRO2 = 1, //He's going for Mr. Floppy!
- SAY_WORGRAGGRO3 = 2, //Oh, no! Look, it's another wolf, and it's a biiiiiig one!
- SAY_WORGRAGGRO4 = 3, //He's gonna eat Mr. Floppy! You gotta help Mr. Floppy! You just gotta!
- SAY_RANDOMAGGRO = 4, //There's a big meanie attacking Mr. Floppy! Help!
- SAY_VICTORY1 = 5, //Let's get out of here before more wolves find us!
- SAY_VICTORY2 = 6, //Don't go toward the light, Mr. Floppy!
- SAY_VICTORY3 = 7, //Mr. Floppy, you're ok! Thank you so much for saving Mr. Floppy!
- SAY_VICTORY4 = 8, //I think I see the camp! We're almost home, Mr. Floppy! Let's go!
- TEXT_EMOTE_WP1 = 9, //Mr. Floppy revives
- TEXT_EMOTE_AGGRO = 10, //The Ravenous Worg chomps down on Mr. Floppy
- SAY_QUEST_ACCEPT = 11, //Are you ready, Mr. Floppy? Stay close to me and watch out for those wolves!
- SAY_QUEST_COMPLETE = 12 //Thank you for helping me get back to the camp. Go tell Walter that I'm safe now!
+ // Spell
+ SPELL_MRFLOPPY = 47184, // vehicle aura
+ // Text
+ SAY_WORGHAGGRO1 = 0, // Um... I think one of those wolves is back...
+ SAY_WORGHAGGRO2 = 1, // He's going for Mr. Floppy!
+ SAY_WORGRAGGRO3 = 2, // Oh, no! Look, it's another wolf, and it's a biiiiiig one!
+ SAY_WORGRAGGRO4 = 3, // He's gonna eat Mr. Floppy! You gotta help Mr. Floppy! You just gotta!
+ SAY_RANDOMAGGRO = 4, // There's a big meanie attacking Mr. Floppy! Help!
+ SAY_VICTORY1 = 5, // Let's get out of here before more wolves find us!
+ SAY_VICTORY2 = 6, // Don't go toward the light, Mr. Floppy!
+ SAY_VICTORY3 = 7, // Mr. Floppy, you're ok! Thank you so much for saving Mr. Floppy!
+ SAY_VICTORY4 = 8, // I think I see the camp! We're almost home, Mr. Floppy! Let's go!
+ TEXT_EMOTE_WP1 = 9, // Mr. Floppy revives
+ TEXT_EMOTE_AGGRO = 10, // The Ravenous Worg chomps down on Mr. Floppy
+ SAY_QUEST_ACCEPT = 11, // Are you ready, Mr. Floppy? Stay close to me and watch out for those wolves!
+ SAY_QUEST_COMPLETE = 12 // Thank you for helping me get back to the camp. Go tell Walter that I'm safe now!
};
-//emily
+// emily
class npc_emily : public CreatureScript
{
public:
@@ -63,13 +64,6 @@ public:
{
npc_emilyAI(Creature* creature) : npc_escortAI(creature) { }
- uint32 m_uiChatTimer;
-
- uint64 RWORGGUID;
- uint64 MrfloppyGUID;
-
- bool Completed;
-
void JustSummoned(Creature* summoned)
{
if (Creature* Mrfloppy = GetClosestCreatureWithEntry(me, NPC_MRFLOPPY, 50.0f))
@@ -88,55 +82,55 @@ public:
{
case 9:
if (Creature* Mrfloppy = GetClosestCreatureWithEntry(me, NPC_MRFLOPPY, 100.0f))
- MrfloppyGUID = Mrfloppy->GetGUID();
+ _mrfloppyGUID = Mrfloppy->GetGUID();
break;
case 10:
- if (Unit::GetCreature(*me, MrfloppyGUID))
+ if (Unit::GetCreature(*me, _mrfloppyGUID))
{
Talk(SAY_WORGHAGGRO1);
me->SummonCreature(NPC_HUNGRY_WORG, me->GetPositionX()+5, me->GetPositionY()+2, me->GetPositionZ()+1, 3.229f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000);
}
break;
case 11:
- if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID))
+ if (Creature* Mrfloppy = Unit::GetCreature(*me, _mrfloppyGUID))
Mrfloppy->GetMotionMaster()->MoveFollow(me, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
break;
case 17:
- if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID))
+ if (Creature* Mrfloppy = Unit::GetCreature(*me, _mrfloppyGUID))
Mrfloppy->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
Talk(SAY_WORGRAGGRO3);
if (Creature* RWORG = me->SummonCreature(NPC_RAVENOUS_WORG, me->GetPositionX()+10, me->GetPositionY()+8, me->GetPositionZ()+2, 3.229f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000))
{
RWORG->setFaction(35);
- RWORGGUID = RWORG->GetGUID();
+ _RavenousworgGUID = RWORG->GetGUID();
}
break;
case 18:
- if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID))
+ if (Creature* Mrfloppy = Unit::GetCreature(*me, _mrfloppyGUID))
{
- if (Creature* RWORG = Unit::GetCreature(*me, RWORGGUID))
+ if (Creature* RWORG = Unit::GetCreature(*me, _RavenousworgGUID))
RWORG->GetMotionMaster()->MovePoint(0, Mrfloppy->GetPositionX(), Mrfloppy->GetPositionY(), Mrfloppy->GetPositionZ());
DoCast(Mrfloppy, SPELL_MRFLOPPY);
}
break;
case 19:
- if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID))
+ if (Creature* Mrfloppy = Unit::GetCreature(*me, _mrfloppyGUID))
{
if (Mrfloppy->HasAura(SPELL_MRFLOPPY, 0))
{
- if (Creature* RWORG = Unit::GetCreature(*me, RWORGGUID))
+ if (Creature* RWORG = Unit::GetCreature(*me, _RavenousworgGUID))
Mrfloppy->EnterVehicle(RWORG);
}
}
break;
case 20:
- if (Creature* RWORG = Unit::GetCreature(*me, RWORGGUID))
+ if (Creature* RWORG = Unit::GetCreature(*me, _RavenousworgGUID))
RWORG->HandleEmoteCommand(34);
break;
case 21:
- if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID))
+ if (Creature* Mrfloppy = Unit::GetCreature(*me, _mrfloppyGUID))
{
- if (Creature* RWORG = Unit::GetCreature(*me, RWORGGUID))
+ if (Creature* RWORG = Unit::GetCreature(*me, _RavenousworgGUID))
{
RWORG->Kill(Mrfloppy);
Mrfloppy->ExitVehicle();
@@ -147,11 +141,11 @@ public:
}
break;
case 22:
- if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID))
+ if (Creature* Mrfloppy = Unit::GetCreature(*me, _mrfloppyGUID))
{
if (Mrfloppy->isDead())
{
- if (Creature* RWORG = Unit::GetCreature(*me, RWORGGUID))
+ if (Creature* RWORG = Unit::GetCreature(*me, _RavenousworgGUID))
RWORG->DisappearAndDie();
me->GetMotionMaster()->MovePoint(0, Mrfloppy->GetPositionX(), Mrfloppy->GetPositionY(), Mrfloppy->GetPositionZ());
Mrfloppy->setDeathState(ALIVE);
@@ -163,7 +157,6 @@ public:
case 24:
if (player)
{
- Completed = true;
player->GroupEventHappens(QUEST_PERILOUS_ADVENTURE, me);
Talk(SAY_QUEST_COMPLETE, player->GetGUID());
}
@@ -174,7 +167,7 @@ public:
break;
case 27:
me->DisappearAndDie();
- if (Creature* Mrfloppy = Unit::GetCreature(*me, MrfloppyGUID))
+ if (Creature* Mrfloppy = Unit::GetCreature(*me, _mrfloppyGUID))
Mrfloppy->DisappearAndDie();
break;
}
@@ -187,23 +180,13 @@ public:
void Reset()
{
- m_uiChatTimer = 4000;
- MrfloppyGUID = 0;
- RWORGGUID = 0;
+ _mrfloppyGUID = 0;
+ _RavenousworgGUID = 0;
}
- void UpdateAI(uint32 uiDiff)
- {
- npc_escortAI::UpdateAI(uiDiff);
-
- if (HasEscortState(STATE_ESCORT_ESCORTING))
- {
- if (m_uiChatTimer <= uiDiff)
- m_uiChatTimer = 12000;
- else
- m_uiChatTimer -= uiDiff;
- }
- }
+ private:
+ uint64 _RavenousworgGUID;
+ uint64 _mrfloppyGUID;
};
bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest)
@@ -226,7 +209,7 @@ public:
}
};
-//mrfloppy
+// mrfloppy
class npc_mrfloppy : public CreatureScript
{
public:
@@ -236,10 +219,6 @@ public:
{
npc_mrfloppyAI(Creature* creature) : ScriptedAI(creature) {}
- uint64 EmilyGUID;
- uint64 RWORGGUID;
- uint64 HWORGGUID;
-
void Reset() {}
void EnterCombat(Unit* Who)
@@ -277,21 +256,21 @@ public:
}
};
-// Outhouse Bunny
+/*######
+## Quest 12227: Doing Your Duty
+######*/
-enum eOuthouseBunny
+enum Outhouse
{
+ // Sound
+ SOUND_FEMALE = 12671,
+ SOUND_MALE = 12670,
+ // Spell
SPELL_OUTHOUSE_GROANS = 48382,
SPELL_CAMERA_SHAKE = 47533,
SPELL_DUST_FIELD = 48329
};
-enum eSounds
-{
- SOUND_FEMALE = 12671,
- SOUND_MALE = 12670
-};
-
class npc_outhouse_bunny : public CreatureScript
{
public:
@@ -301,32 +280,29 @@ public:
{
npc_outhouse_bunnyAI(Creature* creature) : ScriptedAI(creature) {}
- uint8 m_counter;
- uint8 m_gender;
-
void Reset()
{
- m_counter = 0;
- m_gender = 0;
+ _counter = 0;
+ _gender = 0;
}
- void SetData(uint32 uiType, uint32 uiData)
+ void SetData(uint32 Type, uint32 Data)
{
- if (uiType == 1)
- m_gender = uiData;
+ if (Type == 1)
+ _gender = Data;
}
- void SpellHit(Unit* pCaster, const SpellInfo* pSpell)
+ void SpellHit(Unit* Caster, const SpellInfo* Spell)
{
- if (pSpell->Id == SPELL_OUTHOUSE_GROANS)
+ if (Spell->Id == SPELL_OUTHOUSE_GROANS)
{
- ++m_counter;
- if (m_counter < 5)
- DoCast(pCaster, SPELL_CAMERA_SHAKE, true);
+ ++_counter;
+ if (_counter < 5)
+ DoCast(Caster, SPELL_CAMERA_SHAKE, true);
else
- m_counter = 0;
+ _counter = 0;
DoCast(me, SPELL_DUST_FIELD, true);
- switch (m_gender)
+ switch (_gender)
{
case GENDER_FEMALE:
DoPlaySoundToSet(me, SOUND_FEMALE);
@@ -338,6 +314,9 @@ public:
}
}
}
+ private:
+ uint8 _counter;
+ uint8 _gender;
};
CreatureAI* GetAI(Creature* creature) const
@@ -348,8 +327,9 @@ public:
// Tallhorn Stage
-enum etallhornstage
+enum TallhornStage
{
+ //Gameobject
OBJECT_HAUNCH = 188665
};
@@ -362,16 +342,14 @@ public:
{
npc_tallhorn_stagAI(Creature* creature) : ScriptedAI(creature) {}
- uint8 m_uiPhase;
-
void Reset()
{
- m_uiPhase = 1;
+ _phase = 1;
}
- void UpdateAI(uint32 /*uiDiff*/)
+ void UpdateAI(uint32 /*diff*/)
{
- if (m_uiPhase == 1)
+ if (_phase == 1)
{
if (me->FindNearestGameObject(OBJECT_HAUNCH, 2.0f))
{
@@ -379,10 +357,12 @@ public:
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
me->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
}
- m_uiPhase = 0;
+ _phase = 0;
}
DoMeleeAttackIfReady();
}
+ private:
+ uint8 _phase;
};
CreatureAI* GetAI(Creature* creature) const
@@ -393,9 +373,16 @@ public:
// Amberpine Woodsman
-enum eamberpinewoodsman
+enum AmberpineWoodsman
{
- TALLHORN_STAG = 26363
+ // Creature
+ NPC_TALLHORN_STAG = 26363
+};
+
+enum AmberpineWoodsmanEvents
+{
+ EVENT_WOODSMAN_1 = 1,
+ EVENT_WOODSMAN_2 = 2
};
class npc_amberpine_woodsman : public CreatureScript
@@ -407,48 +394,40 @@ public:
{
npc_amberpine_woodsmanAI(Creature* creature) : ScriptedAI(creature) {}
- uint8 m_uiPhase;
- uint32 m_uiTimer;
-
void Reset()
{
- m_uiTimer = 0;
- m_uiPhase = 1;
- }
-
- void UpdateAI(uint32 uiDiff)
- {
- // call this each update tick?
- if (me->FindNearestCreature(TALLHORN_STAG, 0.2f))
+ if (me->FindNearestCreature(NPC_TALLHORN_STAG, 0.2f))
{
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING);
}
else
- if (m_uiPhase)
+ _events.ScheduleEvent(EVENT_WOODSMAN_1, 0);
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
{
- if (m_uiTimer <= uiDiff)
- {
- switch (m_uiPhase)
- {
- case 1:
- me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_LOOT);
- m_uiTimer = 3000;
- m_uiPhase = 2;
- break;
- case 2:
- me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_ATTACK1H);
- m_uiTimer = 4000;
- m_uiPhase = 1;
- break;
- }
- }
- else
- m_uiTimer -= uiDiff;
+ case EVENT_WOODSMAN_1:
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_LOOT);
+ _events.ScheduleEvent(EVENT_WOODSMAN_2, 3000);
+ break;
+ case EVENT_WOODSMAN_2:
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_ATTACK1H);
+ _events.ScheduleEvent(EVENT_WOODSMAN_1, 4000);
+ break;
+ default:
+ break;
}
- ScriptedAI::UpdateAI(uiDiff);
-
+ }
UpdateVictim();
}
+ private:
+ EventMap _events;
};
CreatureAI* GetAI(Creature* creature) const
@@ -456,16 +435,20 @@ public:
return new npc_amberpine_woodsmanAI(creature);
}
};
+
/*######
## Quest 12288: Overwhelmed!
######*/
-enum eSkirmisher
+enum Skirmisher
{
+ // Quest
+ QUEST_OVERWHELMED = 12288,
+ // Spell
SPELL_RENEW_SKIRMISHER = 48812,
- CREDIT_NPC = 27466,
-
- RANDOM_SAY = 0,
+ SPELL_KILL_CREDIT = 48813,
+ // Text
+ SAY_RANDOM = 0
};
class npc_wounded_skirmisher : public CreatureScript
@@ -477,35 +460,31 @@ public:
{
npc_wounded_skirmisherAI(Creature* creature) : ScriptedAI(creature) {}
- uint64 uiPlayerGUID;
-
- uint32 DespawnTimer;
-
void Reset()
{
- DespawnTimer = 5000;
- uiPlayerGUID = 0;
+ _despawnTimer = 5000;
+ _playerGUID = 0;
}
void MovementInform(uint32, uint32 id)
{
if (id == 1)
- me->DespawnOrUnsummon(DespawnTimer);
+ me->DespawnOrUnsummon(_despawnTimer);
}
void SpellHit(Unit* caster, const SpellInfo* spell)
{
if (spell->Id == SPELL_RENEW_SKIRMISHER && caster->GetTypeId() == TYPEID_PLAYER
- && caster->ToPlayer()->GetQuestStatus(12288) == QUEST_STATUS_INCOMPLETE)
+ && caster->ToPlayer()->GetQuestStatus(QUEST_OVERWHELMED) == QUEST_STATUS_INCOMPLETE)
{
- caster->ToPlayer()->KilledMonsterCredit(CREDIT_NPC, 0);
- sCreatureTextMgr->SendChat(me, RANDOM_SAY, 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, caster->ToPlayer());
+ DoCast(caster, SPELL_KILL_CREDIT);
+ Talk(SAY_RANDOM);
if (me->IsStandState())
me->GetMotionMaster()->MovePoint(1, me->GetPositionX()+7, me->GetPositionY()+7, me->GetPositionZ());
else
{
me->SetStandState(UNIT_STAND_STATE_STAND);
- me->DespawnOrUnsummon(DespawnTimer);
+ me->DespawnOrUnsummon(_despawnTimer);
}
}
}
@@ -517,6 +496,9 @@ public:
DoMeleeAttackIfReady();
}
+ private:
+ uint64 _playerGUID;
+ uint32 _despawnTimer;
};
CreatureAI* GetAI(Creature* creature) const
@@ -526,15 +508,22 @@ public:
};
/*Lightning Sentry - if you kill it when you have your Minion with you, you will get a quest credit*/
-enum eSentry
+enum Sentry
{
- QUEST_OR_MAYBE_WE_DONT_A = 12138,
- QUEST_OR_MAYBE_WE_DONT_H = 12198,
-
- NPC_LIGHTNING_SENTRY = 26407,
- NPC_WAR_GOLEM = 27017,
+ //Creature
+ NPC_LIGHTNING_SENTRY = 26407,
+ NPC_WAR_GOLEM = 27017,
+ // Quest
+ QUEST_OR_MAYBE_WE_DONT_A = 12138,
+ QUEST_OR_MAYBE_WE_DONT_H = 12198,
+ // Spell
+ SPELL_CHARGED_SENTRY_TOTEM = 52703,
+ SPELL_WAR_GOLEM_CHARGE_CREDIT = 47797,
+};
- SPELL_CHARGED_SENTRY_TOTEM = 52703,
+enum SentryEvents
+{
+ EVENT_SENTRY = 1
};
class npc_lightning_sentry : public CreatureScript
@@ -542,34 +531,37 @@ class npc_lightning_sentry : public CreatureScript
public:
npc_lightning_sentry() : CreatureScript("npc_lightning_sentry") { }
- CreatureAI* GetAI(Creature* creature) const
- {
- return new npc_lightning_sentryAI(creature);
- }
-
struct npc_lightning_sentryAI : public ScriptedAI
{
npc_lightning_sentryAI(Creature* creature) : ScriptedAI(creature) { }
- uint32 uiChargedSentryTotem;
-
void Reset()
{
- uiChargedSentryTotem = urand(10000, 12000);
+ _events.ScheduleEvent(EVENT_SENTRY, urand(10000, 12000));
}
- void UpdateAI(uint32 uiDiff)
+ void UpdateAI(uint32 diff)
{
if (!UpdateVictim())
return;
- if (uiChargedSentryTotem <= uiDiff)
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
{
- DoCast(SPELL_CHARGED_SENTRY_TOTEM);
- uiChargedSentryTotem = urand(10000, 12000);
+ switch (eventId)
+ {
+ case EVENT_SENTRY:
+ DoCast(SPELL_CHARGED_SENTRY_TOTEM);
+ _events.ScheduleEvent(EVENT_SENTRY, urand(10000, 12000));
+ break;
+ default:
+ break;
+ }
}
- else
- uiChargedSentryTotem -= uiDiff;
+
+ if (!UpdateVictim())
+ return;
DoMeleeAttackIfReady();
}
@@ -582,108 +574,117 @@ public:
{
if (killer->ToPlayer()->GetQuestStatus(QUEST_OR_MAYBE_WE_DONT_A) == QUEST_STATUS_INCOMPLETE ||
killer->ToPlayer()->GetQuestStatus(QUEST_OR_MAYBE_WE_DONT_H) == QUEST_STATUS_INCOMPLETE)
- killer->ToPlayer()->KilledMonsterCredit(NPC_WAR_GOLEM, 0);
+ DoCast(killer, SPELL_WAR_GOLEM_CHARGE_CREDIT);
}
}
}
+ private:
+ EventMap _events;
};
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_lightning_sentryAI(creature);
+ }
};
/*Venture co. Straggler - when you cast Smoke Bomb, he will yell and run away*/
-enum eSmokeEmOut
+enum SmokeEmOut
{
- SAY_SEO = 0,
+ // Quest
QUEST_SMOKE_EM_OUT_A = 12323,
QUEST_SMOKE_EM_OUT_H = 12324,
+ // Spell
SPELL_SMOKE_BOMB = 49075,
SPELL_CHOP = 43410,
SPELL_VENTURE_STRAGGLER_CREDIT = 49093,
+ // Text
+ SAY_SEO = 0
+};
+
+enum StragglerEvents
+{
+ EVENT_STRAGGLER_1 = 1,
+ EVENT_STRAGGLER_2 = 2,
+ EVENT_STRAGGLER_3 = 3,
+ EVENT_STRAGGLER_4 = 4,
+ EVENT_CHOP = 5
};
class npc_venture_co_straggler : public CreatureScript
{
- public:
- npc_venture_co_straggler() : CreatureScript("npc_venture_co_straggler") { }
+public:
+ npc_venture_co_straggler() : CreatureScript("npc_venture_co_straggler") { }
- struct npc_venture_co_stragglerAI : public ScriptedAI
+ struct npc_venture_co_stragglerAI : public ScriptedAI
+ {
+ npc_venture_co_stragglerAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset()
{
- npc_venture_co_stragglerAI(Creature* creature) : ScriptedAI(creature) { }
+ _playerGUID = 0;
- uint64 uiPlayerGUID;
- uint32 uiRunAwayTimer;
- uint32 uiTimer;
- uint32 uiChopTimer;
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
+ me->SetReactState(REACT_AGGRESSIVE);
+ }
- void Reset()
- {
- uiPlayerGUID = 0;
- uiTimer = 0;
- uiRunAwayTimer = 0;
- uiChopTimer = urand(10000, 12500);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
- me->SetReactState(REACT_AGGRESSIVE);
- }
+ void UpdateAI(uint32 diff)
+ {
+ _events.Update(diff);
- void UpdateAI(uint32 uiDiff)
+ while (uint32 eventId = _events.ExecuteEvent())
{
- if (uiPlayerGUID && uiRunAwayTimer <= uiDiff)
+ switch (eventId)
{
- if (Player* player = Unit::GetPlayer(*me, uiPlayerGUID))
- {
- switch (uiTimer)
- {
- case 0:
- DoCast(player, SPELL_VENTURE_STRAGGLER_CREDIT);
- me->GetMotionMaster()->MovePoint(0, me->GetPositionX()-7, me->GetPositionY()+7, me->GetPositionZ());
- uiRunAwayTimer = 2500;
- ++uiTimer;
- break;
- case 1:
- Talk(SAY_SEO);
- me->GetMotionMaster()->MovePoint(0, me->GetPositionX()-7, me->GetPositionY()-5, me->GetPositionZ());
- uiRunAwayTimer = 2500;
- ++uiTimer;
- break;
- case 2:
- me->GetMotionMaster()->MovePoint(0, me->GetPositionX()-5, me->GetPositionY()-5, me->GetPositionZ());
- uiRunAwayTimer = 2500;
- ++uiTimer;
- break;
- case 3:
- me->DisappearAndDie();
- uiTimer = 0;
- break;
- }
- }
+ case EVENT_STRAGGLER_1:
+ if (Player* player = Unit::GetPlayer(*me, _playerGUID))
+ DoCast(player, SPELL_VENTURE_STRAGGLER_CREDIT);
+ me->GetMotionMaster()->MovePoint(0, me->GetPositionX()-7, me->GetPositionY()+7, me->GetPositionZ());
+ _events.ScheduleEvent(EVENT_STRAGGLER_2, 2500);
+ break;
+ case EVENT_STRAGGLER_2:
+ Talk(SAY_SEO);
+ me->GetMotionMaster()->MovePoint(0, me->GetPositionX()-7, me->GetPositionY()-5, me->GetPositionZ());
+ _events.ScheduleEvent(EVENT_STRAGGLER_3, 2500);
+ break;
+ case EVENT_STRAGGLER_3:
+ me->GetMotionMaster()->MovePoint(0, me->GetPositionX()-5, me->GetPositionY()-5, me->GetPositionZ());
+ _events.ScheduleEvent(EVENT_STRAGGLER_4, 2500);
+ break;
+ case EVENT_STRAGGLER_4:
+ me->DisappearAndDie();
+ break;
+ case EVENT_CHOP:
+ if (UpdateVictim())
+ DoCast(me->GetVictim(), SPELL_CHOP);
+ _events.ScheduleEvent(EVENT_CHOP, 10000, 12000);
+ break;
+ default:
+ break;
}
- else if (uiRunAwayTimer)
- uiRunAwayTimer -= uiDiff;
-
- if (!UpdateVictim())
- return;
+ }
- if (uiChopTimer <= uiDiff)
- {
- DoCast(me->GetVictim(), SPELL_CHOP);
- uiChopTimer = urand(10000, 12000);
- }
- else
- uiChopTimer -= uiDiff;
+ if (!UpdateVictim())
+ return;
- DoMeleeAttackIfReady();
- }
+ DoMeleeAttackIfReady();
+ }
- void SpellHit(Unit* caster, SpellInfo const* spell)
+ void SpellHit(Unit* caster, SpellInfo const* spell)
+ {
+ if (spell->Id == SPELL_SMOKE_BOMB && caster->GetTypeId() == TYPEID_PLAYER)
{
- if (spell->Id == SPELL_SMOKE_BOMB && caster->GetTypeId() == TYPEID_PLAYER)
- {
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
- me->SetReactState(REACT_PASSIVE);
- me->CombatStop(false);
- uiPlayerGUID = caster->GetGUID();
- uiRunAwayTimer = 3500;
- }
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC);
+ me->SetReactState(REACT_PASSIVE);
+ me->CombatStop(false);
+ _playerGUID = caster->GetGUID();
+ _events.ScheduleEvent(EVENT_STRAGGLER_1, 3500);
}
+ }
+
+ private:
+ EventMap _events;
+ uint64 _playerGUID;
};
CreatureAI* GetAI(Creature* creature) const
@@ -693,26 +694,24 @@ class npc_venture_co_straggler : public CreatureScript
};
/*######
-## Quest A Blade Fit For A Champion
+## Quest: A Blade Fit For A Champion
######*/
enum LakeFrog
{
+ // Creature
+ NPC_LAKE_FROG = 33211,
+ NPC_LAKE_FROG_QUEST = 33224,
+ NPC_MAIDEN_OF_ASHWOOD_LAKE = 33220,
+ // Items
+ ITEM_WARTS_B_GONE_LIP_BALM = 44986,
// Spells
SPELL_WARTSBGONE_LIP_BALM = 62574,
SPELL_FROG_LOVE = 62537, // for 1 minute !
SPELL_WARTS = 62581,
SPELL_MAIDEN_OF_ASHWOOD_LAKE_TRANSFORM = 62550,
SPELL_SUMMON_ASHWOOD_BRAND = 62554,
-
- // Items
- ITEM_WARTS_B_GONE_LIP_BALM = 44986,
-
- // Creature
- NPC_LAKE_FROG = 33211,
- NPC_LAKE_FROG_QUEST = 33224,
- NPC_MAIDEN_OF_ASHWOOD_LAKE = 33220,
-
+ SPELL_FROG_KISS = 62536,
// Text
SAY_MAIDEN_0 = 0,
SAY_MAIDEN_1 = 1
@@ -720,17 +719,17 @@ enum LakeFrog
enum LakeFrogEvents
{
- EVENT_SCRIPT_1 = 1,
- EVENT_SCRIPT_2 = 2,
- EVENT_SCRIPT_3 = 3,
- EVENT_SCRIPT_4 = 4,
- EVENT_SCRIPT_5 = 5
+ EVENT_LAKEFROG_1 = 1,
+ EVENT_LAKEFROG_2 = 2,
+ EVENT_LAKEFROG_3 = 3,
+ EVENT_LAKEFROG_4 = 4,
+ EVENT_LAKEFROG_5 = 5
};
class npc_lake_frog : public CreatureScript
{
- public:
- npc_lake_frog() : CreatureScript("npc_lake_frog") { }
+public:
+ npc_lake_frog() : CreatureScript("npc_lake_frog") { }
struct npc_lake_frogAI : public ScriptedAI
{
@@ -756,24 +755,24 @@ class npc_lake_frog : public CreatureScript
{
switch (eventId)
{
- case EVENT_SCRIPT_1:
+ case EVENT_LAKEFROG_1:
DoCast(me, SPELL_MAIDEN_OF_ASHWOOD_LAKE_TRANSFORM);
me->SetEntry(NPC_MAIDEN_OF_ASHWOOD_LAKE);
- _events.ScheduleEvent(EVENT_SCRIPT_2, 2000);
+ _events.ScheduleEvent(EVENT_LAKEFROG_2, 2000);
break;
- case EVENT_SCRIPT_2:
+ case EVENT_LAKEFROG_2:
Talk(SAY_MAIDEN_0);
- _events.ScheduleEvent(EVENT_SCRIPT_3, 3000);
+ _events.ScheduleEvent(EVENT_LAKEFROG_3, 3000);
break;
- case EVENT_SCRIPT_3:
+ case EVENT_LAKEFROG_3:
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- _events.ScheduleEvent(EVENT_SCRIPT_4, 25000);
+ _events.ScheduleEvent(EVENT_LAKEFROG_4, 25000);
break;
- case EVENT_SCRIPT_4:
+ case EVENT_LAKEFROG_4:
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- _events.ScheduleEvent(EVENT_SCRIPT_5, 2000);
+ _events.ScheduleEvent(EVENT_LAKEFROG_5, 2000);
break;
- case EVENT_SCRIPT_5:
+ case EVENT_LAKEFROG_5:
Talk(SAY_MAIDEN_1);
me->DespawnOrUnsummon(4000);
break;
@@ -794,7 +793,7 @@ class npc_lake_frog : public CreatureScript
player->AddAura(SPELL_WARTS, player);
else
{
- player->RemoveAura(SPELL_WARTSBGONE_LIP_BALM);
+ DoCast(player, SPELL_FROG_KISS); // Removes SPELL_WARTSBGONE_LIP_BALM
if (me->GetEntry() == NPC_LAKE_FROG)
{
@@ -807,7 +806,7 @@ class npc_lake_frog : public CreatureScript
me->GetMotionMaster()->MoveIdle();
me->SetFacingToObject(player);
_runningScript = true;
- _events.ScheduleEvent(EVENT_SCRIPT_1, 2000);
+ _events.ScheduleEvent(EVENT_LAKEFROG_1, 2000);
}
}
}
diff --git a/src/server/scripts/Northrend/zone_howling_fjord.cpp b/src/server/scripts/Northrend/zone_howling_fjord.cpp
index 32bc2f6e424..4cb52f6360f 100644
--- a/src/server/scripts/Northrend/zone_howling_fjord.cpp
+++ b/src/server/scripts/Northrend/zone_howling_fjord.cpp
@@ -186,7 +186,7 @@ public:
if (!summonerGUID)
return;
- me->SetUnitMovementFlags(MOVEMENTFLAG_WALKING);
+ me->SetWalk(true);
Start(false, false, summonerGUID);
}
diff --git a/src/server/scripts/Northrend/zone_sholazar_basin.cpp b/src/server/scripts/Northrend/zone_sholazar_basin.cpp
index adf709ee304..2c0a98ab0ad 100644
--- a/src/server/scripts/Northrend/zone_sholazar_basin.cpp
+++ b/src/server/scripts/Northrend/zone_sholazar_basin.cpp
@@ -98,13 +98,13 @@ public:
case 16:
case 17:
case 18:
- me->RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
me->RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING);
me->SetSpeed(MOVE_SWIM, 0.85f, true);
- me->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_DISABLE_GRAVITY);
+ me->SetSwim(true);
+ me->SetDisableGravity(true);
break;
case 19:
- me->SetUnitMovementFlags(MOVEMENTFLAG_FALLING);
+ me->GetMotionMaster()->MoveFall();
break;
case 28:
player->GroupEventHappens(QUEST_FORTUNATE_MISUNDERSTANDINGS, me);
@@ -148,7 +148,6 @@ public:
{
CAST_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID());
CAST_AI(npc_escortAI, (creature->AI()))->SetMaxPlayerDistance(35.0f);
- creature->SetUnitMovementFlags(MOVEMENTFLAG_FALLING);
creature->AI()->Talk(SAY_START_IRO);
switch (player->GetTeam()){
diff --git a/src/server/scripts/Northrend/zone_zuldrak.cpp b/src/server/scripts/Northrend/zone_zuldrak.cpp
index 825f1804e3c..329759ab439 100644
--- a/src/server/scripts/Northrend/zone_zuldrak.cpp
+++ b/src/server/scripts/Northrend/zone_zuldrak.cpp
@@ -21,12 +21,15 @@
#include "ScriptedEscortAI.h"
#include "Player.h"
#include "SpellInfo.h"
+#include "SpellScript.h"
+#include "SpellAuras.h"
+#include "SpellAuraEffects.h"
/*####
## npc_drakuru_shackles
####*/
-enum eDrakuruShackles
+enum DrakuruShackles
{
SPELL_LEFT_CHAIN = 59951,
SPELL_RIGHT_CHAIN = 59952,
@@ -34,7 +37,7 @@ enum eDrakuruShackles
SPELL_FREE_RAGECLAW = 55223,
NPC_RAGECLAW = 29686,
- QUEST_TROLLS_IS_GONE_CRAZY = 12861,
+ QUEST_TROLLS_IS_GONE_CRAZY = 12861
};
class npc_drakuru_shackles : public CreatureScript
@@ -115,7 +118,7 @@ public:
## npc_captured_rageclaw
####*/
-enum eRageclaw
+enum Rageclaw
{
SPELL_UNSHACKLED = 55085,
SPELL_KNEEL = 39656
@@ -1384,7 +1387,7 @@ public:
## go_scourge_enclosure
######*/
-enum eScourgeEnclosure
+enum ScourgeEnclosure
{
QUEST_OUR_ONLY_HOPE = 12916,
NPC_GYMER_DUMMY = 29928 //from quest template
@@ -1412,6 +1415,532 @@ public:
}
};
+/*######
+## Quest: Troll Patrol: The Alchemist's Apprentice
+######*/
+
+enum Finklestein
+{
+ // Creature
+ NPC_FINKLESTEIN = 28205,
+ // Item
+ ITEM_KNOTROOT = 38338,
+ ITEM_PICKLED_EAGLE_EGG = 38341,
+ ITEM_SPECKLED_GUANO = 38337,
+ ITEM_WITHERED_BATWING = 38339,
+ ITEM_SEASONED_SLIDER_CIDER = 38381,
+ ITEM_PULVERIZED_GARGOYLE_TEETH = 38384,
+ ITEM_MUDDY_MIRE_MAGGOT = 38386,
+ ITEM_SPIKY_SPIDER_EGG = 38393,
+ ITEM_HAIRY_HERRING_HEAD = 38396,
+ ITEM_PUTRID_PIRATE_PERSPIRATION = 38397,
+ ITEM_ICECROWN_BOTTLED_WATER = 38398,
+ ITEM_WASPS_WINGS = 38369,
+ ITEM_PRISMATIC_MOJO = 38343,
+ ITEM_RAPTOR_CLAW = 38370,
+ ITEM_AMBERSEED = 38340,
+ ITEM_SHRUNKEN_DRAGONS_CLAW = 38344,
+ ITEM_CHILLED_SERPENT_MUCUS = 38346,
+ ITEM_CRYSTALLIZED_HOGSNOT = 38336,
+ ITEM_CRUSHED_BASILISK_CRYSTALS = 38379,
+ ITEM_TROLLBANE = 38342,
+ ITEM_FROZEN_SPIDER_ICHOR = 38345,
+ // Quest
+ QUEST_THE_ALCHEMIST_APPRENTICE_DAILY = 12541,
+ // Spells
+ SPELL_ALCHEMIST_APPRENTICE_INVISBUFF = 51216,
+ SPELL_RANDOM_INGREDIENT_EASY_AURA = 51015,
+ SPELL_RANDOM_INGREDIENT_MEDIUM_AURA = 51154,
+ SPELL_RANDOM_INGREDIENT_HARD_AURA = 51157,
+ SPELL_RANDOM_INGREDIENT_EASY = 51134,
+ SPELL_RANDOM_INGREDIENT_MEDIUM = 51105,
+ SPELL_RANDOM_INGREDIENT_HARD = 51107,
+ SPELL_NEXT_INGREDIENT = 51049,
+ SPELL_POT_CHECK = 51046,
+ SPELL_THROW_INGREDIENT = 51025,
+ SPELL_KILL_CREDIT = 51111,
+ // Spell Fetch Easy
+ SPELL_FETCH_KNOTROOT = 51018,
+ SPELL_FETCH_PICKLED_EAGLE_EGG = 51055,
+ SPELL_FETCH_SPECKLED_GUANO = 51057,
+ SPELL_FETCH_WITHERED_BATWING = 51059,
+ SPELL_FETCH_SEASONED_SLIDER_CIDER = 51062,
+ SPELL_FETCH_PULVERIZED_GARGOYLE_TEETH = 51064,
+ SPELL_FETCH_MUDDY_MIRE_MAGGOT = 51067,
+ SPELL_FETCH_SPIKY_SPIDER_EGG = 51069,
+ SPELL_FETCH_HAIRY_HERRING_HEAD = 51072,
+ SPELL_FETCH_PUTRID_PIRATE_PERSPIRATION = 51077,
+ SPELL_FETCH_ICECROWN_BOTTLED_WATER = 51079,
+ // Spell Have Easy
+ SPELL_HAVE_KNOTROOT = 51047,
+ SPELL_HAVE_PICKLED_EAGLE_EGG = 51056,
+ SPELL_HAVE_SPECKLED_GUANO = 51058,
+ SPELL_HAVE_WITHERED_BATWING = 51060,
+ SPELL_HAVE_SEASONED_SLIDER_CIDER = 51063,
+ SPELL_HAVE_PULVERIZED_GARGOYLE_TEETH = 51065,
+ SPELL_HAVE_MUDDY_MIRE_MAGGOT = 51068,
+ SPELL_HAVE_SPIKY_SPIDER_EGG = 51070,
+ SPELL_HAVE_HAIRY_HERRING_HEAD = 51075,
+ SPELL_HAVE_PUTRID_PIRATE_PERSPIRATION = 51078,
+ SPELL_HAVE_ICECROWN_BOTTLED_WATER = 51080,
+ // Spell Fetch Medium
+ SPELL_FETCH_WASPS_WINGS = 51081,
+ SPELL_FETCH_PRISMATIC_MOJO = 51083,
+ SPELL_FETCH_RAPTOR_CLAW = 51085,
+ SPELL_FETCH_AMBERSEED = 51087,
+ SPELL_FETCH_SHRUNKEN_DRAGONS_CLAW = 51091,
+ // Spell Have Medium
+ SPELL_HAVE_WASPS_WINGS = 51082,
+ SPELL_HAVE_PRISMATIC_MOJO = 51084,
+ SPELL_HAVE_RAPTOR_CLAW = 51086,
+ SPELL_HAVE_AMBERSEED = 51088,
+ SPELL_HAVE_SHRUNKEN_DRAGONS_CLAW = 51092,
+ // Spell Fetch Hard
+ SPELL_FETCH_CHILLED_SERPENT_MUCUS = 51093,
+ SPELL_FETCH_CRYSTALLIZED_HOGSNOT = 51095,
+ SPELL_FETCH_CRUSHED_BASILISK_CRYSTALS = 51097,
+ SPELL_FETCH_TROLLBANE = 51100,
+ SPELL_FETCH_FROZEN_SPIDER_ICHOR = 51102,
+ // Spell Have Hard
+ SPELL_HAVE_CHILLED_SERPENT_MUCUS = 51094,
+ SPELL_HAVE_CRYSTALLIZED_HOGSNOT = 51096,
+ SPELL_HAVE_CRUSHED_BASILISK_CRYSTALS = 51098,
+ SPELL_HAVE_TROLLBANE = 51101,
+ SPELL_HAVE_FROZEN_SPIDER_ICHOR = 51104,
+ // Text
+ SAY_EASY_123 = 0,
+ SAY_MEDIUM_4 = 1,
+ SAY_MEDIUM_5 = 2,
+ SAY_HARD_6 = 3,
+ SAY_RUINED = 4,
+ // Text Easy
+ SAY_KNOTROOT = 5,
+ SAY_PICKLED_EAGLE_EGG = 6,
+ SAY_SPECKLED_GUANO = 7,
+ SAY_WITHERED_BATWING = 8,
+ SAY_SEASONED_SLIDER_CIDER = 9,
+ SAY_PULVERIZED_GARGOYLE_TEETH = 10,
+ SAY_MUDDY_MIRE_MAGGOT = 11,
+ SAY_SPIKY_SPIDER_EGG = 12,
+ SAY_HAIRY_HERRING_HEAD = 13,
+ SAY_PUTRID_PIRATE_PERSPIRATION = 14,
+ SAY_ICECROWN_BOTTLED_WATER = 15,
+ // Text Medium
+ SAY_WASPS_WINGS = 16,
+ SAY_PRISMATIC_MOJO = 17,
+ SAY_RAPTOR_CLAW = 18,
+ SAY_AMBERSEED = 19,
+ SAY_SHRUNKEN_DRAGONS_CLAW = 20,
+ // Text Hard
+ SAY_CHILLED_SERPENT_MUCUS = 21,
+ SAY_CRYSTALLIZED_HOGSNOT = 22,
+ SAY_CRUSHED_BASILISK_CRYSTALS = 23,
+ SAY_TROLLBANE = 24,
+ SAY_FROZEN_SPIDER_ICHOR = 25
+};
+
+enum FinklesteinEvents
+{
+ EVENT_TURN_TO_POT = 1,
+ EVENT_TURN_BACK = 2,
+ EVENT_EASY_123 = 3,
+ EVENT_MEDIUM_4 = 4,
+ EVENT_MEDIUM_5 = 5,
+ EVENT_HARD_6 = 6
+};
+
+class npc_alchemist_finklestein : public CreatureScript
+{
+public:
+ npc_alchemist_finklestein() : CreatureScript("npc_alchemist_finklestein") { }
+
+ struct npc_alchemist_finklesteinAI : public ScriptedAI
+ {
+ npc_alchemist_finklesteinAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset()
+ {
+ _events.ScheduleEvent(EVENT_TURN_TO_POT, urand(15000, 26000));
+ }
+
+ void SetData(uint32 Type, uint32 Data)
+ {
+ if (Type == 1 && Data == 1)
+ switch (_getingredienttry)
+ {
+ case 2:
+ case 3:
+ _events.ScheduleEvent(EVENT_EASY_123, 100);
+ break;
+ case 4:
+ _events.ScheduleEvent(EVENT_MEDIUM_4, 100);
+ break;
+ case 5:
+ _events.ScheduleEvent(EVENT_MEDIUM_5, 100);
+ break;
+ case 6:
+ _events.ScheduleEvent(EVENT_HARD_6, 100);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_TURN_TO_POT:
+ me->SetFacingTo(6.230825f);
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING_NO_SHEATHE);
+ _events.ScheduleEvent(EVENT_TURN_BACK, 11000);
+ break;
+ case EVENT_TURN_BACK:
+ me->SetFacingTo(4.886922f);
+ me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
+ _events.ScheduleEvent(EVENT_TURN_TO_POT, urand(25000, 41000));
+ break;
+ case EVENT_EASY_123:
+ if (Player* player = Unit::GetPlayer(*me, _playerGUID))
+ {
+ Talk(SAY_EASY_123, _playerGUID);
+ DoCast(player, SPELL_RANDOM_INGREDIENT_EASY_AURA);
+ ++_getingredienttry;
+ }
+ break;
+ case EVENT_MEDIUM_4:
+ if (Player* player = Unit::GetPlayer(*me, _playerGUID))
+ {
+ Talk(SAY_MEDIUM_4, _playerGUID);
+ DoCast(player, SPELL_RANDOM_INGREDIENT_MEDIUM_AURA);
+ ++_getingredienttry;
+ }
+ break;
+ case EVENT_MEDIUM_5:
+ if (Player* player = Unit::GetPlayer(*me, _playerGUID))
+ {
+ Talk(SAY_MEDIUM_5, _playerGUID);
+ DoCast(player, SPELL_RANDOM_INGREDIENT_MEDIUM_AURA);
+ ++_getingredienttry;
+ }
+ break;
+ case EVENT_HARD_6:
+ if (Player* player = Unit::GetPlayer(*me, _playerGUID))
+ {
+ Talk(SAY_HARD_6, _playerGUID);
+ DoCast(player, SPELL_RANDOM_INGREDIENT_HARD_AURA);
+ ++_getingredienttry;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ void sGossipSelect(Player* player, uint32 /*sender*/, uint32 /*action*/)
+ {
+ player->CLOSE_GOSSIP_MENU();
+ DoCast(player, SPELL_ALCHEMIST_APPRENTICE_INVISBUFF);
+ _playerGUID = player->GetGUID();
+ _getingredienttry = 1;
+ _events.ScheduleEvent(EVENT_EASY_123, 100);
+ }
+
+ private:
+ EventMap _events;
+ uint64 _playerGUID;
+ uint8 _getingredienttry;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_alchemist_finklesteinAI(creature);
+ }
+};
+
+class go_finklesteins_cauldron : public GameObjectScript
+{
+public:
+ go_finklesteins_cauldron() : GameObjectScript("go_finklesteins_cauldron") { }
+
+ bool OnGossipHello(Player* player, GameObject* /*go*/)
+ {
+ player->CastSpell(player, SPELL_POT_CHECK);
+ return true;
+ }
+};
+
+uint32 const FetchIngredients[21] [4] =
+{
+ { SPELL_FETCH_KNOTROOT, SPELL_HAVE_KNOTROOT, ITEM_KNOTROOT, SAY_KNOTROOT },
+ { SPELL_FETCH_PICKLED_EAGLE_EGG, SPELL_HAVE_PICKLED_EAGLE_EGG, ITEM_PICKLED_EAGLE_EGG, SAY_PICKLED_EAGLE_EGG },
+ { SPELL_FETCH_SPECKLED_GUANO, SPELL_HAVE_SPECKLED_GUANO, ITEM_SPECKLED_GUANO, SAY_SPECKLED_GUANO },
+ { SPELL_FETCH_WITHERED_BATWING, SPELL_HAVE_WITHERED_BATWING, ITEM_WITHERED_BATWING, SAY_WITHERED_BATWING },
+ { SPELL_FETCH_SEASONED_SLIDER_CIDER, SPELL_HAVE_SEASONED_SLIDER_CIDER, ITEM_SEASONED_SLIDER_CIDER, SAY_SEASONED_SLIDER_CIDER },
+ { SPELL_FETCH_PULVERIZED_GARGOYLE_TEETH, SPELL_HAVE_PULVERIZED_GARGOYLE_TEETH, ITEM_PULVERIZED_GARGOYLE_TEETH, SAY_PULVERIZED_GARGOYLE_TEETH },
+ { SPELL_FETCH_MUDDY_MIRE_MAGGOT, SPELL_HAVE_MUDDY_MIRE_MAGGOT, ITEM_MUDDY_MIRE_MAGGOT, SAY_MUDDY_MIRE_MAGGOT },
+ { SPELL_FETCH_SPIKY_SPIDER_EGG, SPELL_HAVE_SPIKY_SPIDER_EGG, ITEM_SPIKY_SPIDER_EGG, SAY_SPIKY_SPIDER_EGG },
+ { SPELL_FETCH_HAIRY_HERRING_HEAD, SPELL_HAVE_HAIRY_HERRING_HEAD, ITEM_HAIRY_HERRING_HEAD, SAY_HAIRY_HERRING_HEAD },
+ { SPELL_FETCH_PUTRID_PIRATE_PERSPIRATION, SPELL_HAVE_PUTRID_PIRATE_PERSPIRATION, ITEM_PUTRID_PIRATE_PERSPIRATION, SAY_PUTRID_PIRATE_PERSPIRATION },
+ { SPELL_FETCH_ICECROWN_BOTTLED_WATER, SPELL_HAVE_ICECROWN_BOTTLED_WATER, ITEM_ICECROWN_BOTTLED_WATER, SAY_ICECROWN_BOTTLED_WATER },
+ { SPELL_FETCH_WASPS_WINGS, SPELL_HAVE_WASPS_WINGS, ITEM_WASPS_WINGS, SAY_WASPS_WINGS },
+ { SPELL_FETCH_PRISMATIC_MOJO, SPELL_HAVE_PRISMATIC_MOJO, ITEM_PRISMATIC_MOJO, SAY_PRISMATIC_MOJO },
+ { SPELL_FETCH_RAPTOR_CLAW, SPELL_HAVE_RAPTOR_CLAW, ITEM_RAPTOR_CLAW, SAY_RAPTOR_CLAW },
+ { SPELL_FETCH_AMBERSEED, SPELL_HAVE_AMBERSEED, ITEM_AMBERSEED, SAY_AMBERSEED },
+ { SPELL_FETCH_SHRUNKEN_DRAGONS_CLAW, SPELL_HAVE_SHRUNKEN_DRAGONS_CLAW, ITEM_SHRUNKEN_DRAGONS_CLAW, SAY_SHRUNKEN_DRAGONS_CLAW },
+ { SPELL_FETCH_CHILLED_SERPENT_MUCUS, SPELL_HAVE_CHILLED_SERPENT_MUCUS, ITEM_CHILLED_SERPENT_MUCUS, SAY_CHILLED_SERPENT_MUCUS },
+ { SPELL_FETCH_CRYSTALLIZED_HOGSNOT, SPELL_HAVE_CRYSTALLIZED_HOGSNOT, ITEM_CRYSTALLIZED_HOGSNOT, SAY_CRYSTALLIZED_HOGSNOT },
+ { SPELL_FETCH_CRUSHED_BASILISK_CRYSTALS, SPELL_HAVE_CRUSHED_BASILISK_CRYSTALS, ITEM_CRUSHED_BASILISK_CRYSTALS, SAY_CRUSHED_BASILISK_CRYSTALS },
+ { SPELL_FETCH_TROLLBANE, SPELL_HAVE_TROLLBANE, ITEM_TROLLBANE, SAY_TROLLBANE },
+ { SPELL_FETCH_FROZEN_SPIDER_ICHOR, SPELL_HAVE_FROZEN_SPIDER_ICHOR, ITEM_FROZEN_SPIDER_ICHOR, SAY_FROZEN_SPIDER_ICHOR }
+};
+
+/*#####
+# spell_random_ingredient_aura
+#####*/
+
+class spell_random_ingredient_aura : public SpellScriptLoader
+{
+ public: spell_random_ingredient_aura() : SpellScriptLoader("spell_random_ingredient_aura") { }
+
+ class spell_random_ingredient_aura_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_random_ingredient_aura_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellEntry*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_RANDOM_INGREDIENT_EASY) || !sSpellMgr->GetSpellInfo(SPELL_RANDOM_INGREDIENT_MEDIUM) || !sSpellMgr->GetSpellInfo(SPELL_RANDOM_INGREDIENT_HARD))
+ return false;
+ return true;
+ }
+
+ void PeriodicTick(AuraEffect const* /*aurEff*/)
+ {
+ switch (GetSpellInfo()->Id)
+ {
+ case SPELL_RANDOM_INGREDIENT_EASY_AURA:
+ GetTarget()->CastSpell(GetTarget(), SPELL_RANDOM_INGREDIENT_EASY);
+ break;
+ case SPELL_RANDOM_INGREDIENT_MEDIUM_AURA:
+ GetTarget()->CastSpell(GetTarget(), SPELL_RANDOM_INGREDIENT_MEDIUM);
+ break;
+ case SPELL_RANDOM_INGREDIENT_HARD_AURA:
+ GetTarget()->CastSpell(GetTarget(), SPELL_RANDOM_INGREDIENT_HARD);
+ break;
+ }
+ }
+
+ void Register()
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_random_ingredient_aura_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_random_ingredient_aura_AuraScript();
+ }
+};
+
+/*#####
+# spell_random_ingredient
+#####*/
+
+class spell_random_ingredient : public SpellScriptLoader
+{
+ public: spell_random_ingredient() : SpellScriptLoader("spell_random_ingredient") { }
+
+ class spell_random_ingredient_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_random_ingredient_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellEntry*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_FETCH_KNOTROOT) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_PICKLED_EAGLE_EGG) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_SPECKLED_GUANO) ||
+ !sSpellMgr->GetSpellInfo(SPELL_FETCH_WITHERED_BATWING) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_SEASONED_SLIDER_CIDER) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_PULVERIZED_GARGOYLE_TEETH) ||
+ !sSpellMgr->GetSpellInfo(SPELL_FETCH_MUDDY_MIRE_MAGGOT) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_SPIKY_SPIDER_EGG) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_HAIRY_HERRING_HEAD) ||
+ !sSpellMgr->GetSpellInfo(SPELL_FETCH_PUTRID_PIRATE_PERSPIRATION) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_ICECROWN_BOTTLED_WATER) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_WASPS_WINGS) ||
+ !sSpellMgr->GetSpellInfo(SPELL_FETCH_PRISMATIC_MOJO) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_RAPTOR_CLAW) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_AMBERSEED) ||
+ !sSpellMgr->GetSpellInfo(SPELL_FETCH_SHRUNKEN_DRAGONS_CLAW) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_CHILLED_SERPENT_MUCUS) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_CRYSTALLIZED_HOGSNOT) ||
+ !sSpellMgr->GetSpellInfo(SPELL_FETCH_CRUSHED_BASILISK_CRYSTALS) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_TROLLBANE) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_FROZEN_SPIDER_ICHOR))
+ return false;
+ return true;
+ }
+
+ void HandleScriptEffect(SpellEffIndex /* effIndex */)
+ {
+ if (Player* player = GetHitPlayer())
+ {
+
+ uint8 ingredient = 0;
+
+ switch (GetSpellInfo()->Id)
+ {
+ case SPELL_RANDOM_INGREDIENT_EASY:
+ ingredient = urand(0, 10);
+ break;
+ case SPELL_RANDOM_INGREDIENT_MEDIUM:
+ ingredient = urand(11, 15);
+ break;
+ case SPELL_RANDOM_INGREDIENT_HARD:
+ ingredient = urand(16, 20);
+ break;
+ }
+
+ if (Creature* finklestein = GetClosestCreatureWithEntry(player, NPC_FINKLESTEIN, 25.0f))
+ {
+ finklestein->CastSpell(player, FetchIngredients[ingredient] [0], true, NULL);
+ finklestein->AI()->Talk(FetchIngredients[ingredient] [3], player->GetGUID());
+ }
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_random_ingredient_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_random_ingredient_SpellScript();
+ }
+};
+
+/*#####
+# spell_pot_check
+#####*/
+
+class spell_pot_check : public SpellScriptLoader
+{
+ public: spell_pot_check() : SpellScriptLoader("spell_pot_check") { }
+
+ class spell_pot_check_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_pot_check_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellEntry*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_FETCH_KNOTROOT) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_PICKLED_EAGLE_EGG) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_SPECKLED_GUANO) ||
+ !sSpellMgr->GetSpellInfo(SPELL_FETCH_WITHERED_BATWING) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_SEASONED_SLIDER_CIDER) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_PULVERIZED_GARGOYLE_TEETH) ||
+ !sSpellMgr->GetSpellInfo(SPELL_FETCH_MUDDY_MIRE_MAGGOT) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_SPIKY_SPIDER_EGG) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_HAIRY_HERRING_HEAD) ||
+ !sSpellMgr->GetSpellInfo(SPELL_FETCH_PUTRID_PIRATE_PERSPIRATION) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_ICECROWN_BOTTLED_WATER) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_WASPS_WINGS) ||
+ !sSpellMgr->GetSpellInfo(SPELL_FETCH_PRISMATIC_MOJO) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_RAPTOR_CLAW) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_AMBERSEED) ||
+ !sSpellMgr->GetSpellInfo(SPELL_FETCH_SHRUNKEN_DRAGONS_CLAW) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_CHILLED_SERPENT_MUCUS) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_CRYSTALLIZED_HOGSNOT) ||
+ !sSpellMgr->GetSpellInfo(SPELL_FETCH_CRUSHED_BASILISK_CRYSTALS) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_TROLLBANE) || !sSpellMgr->GetSpellInfo(SPELL_FETCH_FROZEN_SPIDER_ICHOR) ||
+ !sSpellMgr->GetSpellInfo(SPELL_HAVE_KNOTROOT) || !sSpellMgr->GetSpellInfo(SPELL_HAVE_PICKLED_EAGLE_EGG) || !sSpellMgr->GetSpellInfo(SPELL_HAVE_SPECKLED_GUANO) ||
+ !sSpellMgr->GetSpellInfo(SPELL_HAVE_WITHERED_BATWING) || !sSpellMgr->GetSpellInfo(SPELL_HAVE_SEASONED_SLIDER_CIDER) || !sSpellMgr->GetSpellInfo(SPELL_HAVE_PULVERIZED_GARGOYLE_TEETH) ||
+ !sSpellMgr->GetSpellInfo(SPELL_HAVE_MUDDY_MIRE_MAGGOT) || !sSpellMgr->GetSpellInfo(SPELL_HAVE_SPIKY_SPIDER_EGG) || !sSpellMgr->GetSpellInfo(SPELL_HAVE_HAIRY_HERRING_HEAD) ||
+ !sSpellMgr->GetSpellInfo(SPELL_HAVE_PUTRID_PIRATE_PERSPIRATION) || !sSpellMgr->GetSpellInfo(SPELL_HAVE_ICECROWN_BOTTLED_WATER) || !sSpellMgr->GetSpellInfo(SPELL_HAVE_WASPS_WINGS) ||
+ !sSpellMgr->GetSpellInfo(SPELL_HAVE_PRISMATIC_MOJO) || !sSpellMgr->GetSpellInfo(SPELL_HAVE_RAPTOR_CLAW) || !sSpellMgr->GetSpellInfo(SPELL_HAVE_AMBERSEED) ||
+ !sSpellMgr->GetSpellInfo(SPELL_HAVE_SHRUNKEN_DRAGONS_CLAW) || !sSpellMgr->GetSpellInfo(SPELL_HAVE_CHILLED_SERPENT_MUCUS) || !sSpellMgr->GetSpellInfo(SPELL_HAVE_CRYSTALLIZED_HOGSNOT) ||
+ !sSpellMgr->GetSpellInfo(SPELL_HAVE_CRUSHED_BASILISK_CRYSTALS) || !sSpellMgr->GetSpellInfo(SPELL_HAVE_TROLLBANE) || !sSpellMgr->GetSpellInfo(SPELL_HAVE_FROZEN_SPIDER_ICHOR))
+ return false;
+ return true;
+ }
+
+ void HandleScriptEffect(SpellEffIndex /* effIndex */)
+ {
+ if (Player* player = GetHitPlayer())
+ {
+ for (uint8 i = 0; i < 21; ++i)
+ {
+ if(player->HasAura(FetchIngredients[i] [0]))
+ {
+ player->CastSpell(player, SPELL_THROW_INGREDIENT);
+ player->RemoveAura(FetchIngredients[i] [0]);
+ if(player->HasAura(FetchIngredients[i] [1]))
+ {
+ player->RemoveAura(FetchIngredients[i] [1]);
+ player->DestroyItemCount(FetchIngredients[i] [2], 1, true);
+ if (i < 15)
+ {
+ if (Creature* finklestein = GetClosestCreatureWithEntry(player, NPC_FINKLESTEIN, 25.0f))
+ finklestein->AI()->SetData(1, 1);
+ return;
+ }
+ else
+ {
+ if (player->GetQuestStatus(QUEST_THE_ALCHEMIST_APPRENTICE_DAILY) == QUEST_STATUS_INCOMPLETE)
+ {
+ player->RemoveAura(SPELL_ALCHEMIST_APPRENTICE_INVISBUFF);
+ player->CastSpell(player, SPELL_KILL_CREDIT);
+ }
+ }
+ }
+ else
+ {
+ RemoveItems(player);
+ player->RemoveAura(SPELL_ALCHEMIST_APPRENTICE_INVISBUFF);
+ if (Creature* finklestein = GetClosestCreatureWithEntry(player, NPC_FINKLESTEIN, 25.0f))
+ finklestein->AI()->Talk(SAY_RUINED, player->GetGUID());
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ void RemoveItems(Player* player)
+ {
+ for (uint8 i = 0; i < 21; ++i)
+ if (player->HasItemCount(FetchIngredients[i] [2], 1, true))
+ player->DestroyItemCount(FetchIngredients[i] [2], 1, true);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_pot_check_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_pot_check_SpellScript();
+ }
+};
+
+/*#####
+# spell_fetch_ingredient_aura
+#####*/
+
+class spell_fetch_ingredient_aura : public SpellScriptLoader
+{
+ public: spell_fetch_ingredient_aura() : SpellScriptLoader("spell_fetch_ingredient_aura") { }
+
+ class spell_fetch_ingredient_aura_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_fetch_ingredient_aura_AuraScript);
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
+ if (Unit* target = GetTarget())
+ if (target->HasAura(SPELL_ALCHEMIST_APPRENTICE_INVISBUFF))
+ if (Creature* finklestein = GetClosestCreatureWithEntry(target, NPC_FINKLESTEIN, 100.0f))
+ {
+ target->RemoveAura(SPELL_ALCHEMIST_APPRENTICE_INVISBUFF);
+ finklestein->AI()->Talk(SAY_RUINED, target->GetGUID());
+ }
+ }
+
+ void Register()
+ {
+ OnEffectRemove += AuraEffectRemoveFn(spell_fetch_ingredient_aura_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_fetch_ingredient_aura_AuraScript();
+ }
+};
+
void AddSC_zuldrak()
{
new npc_drakuru_shackles;
@@ -1427,4 +1956,10 @@ void AddSC_zuldrak()
new npc_elemental_lord;
new npc_fiend_elemental;
new go_scourge_enclosure;
+ new npc_alchemist_finklestein;
+ new go_finklesteins_cauldron;
+ new spell_random_ingredient_aura;
+ new spell_random_ingredient;
+ new spell_pot_check;
+ new spell_fetch_ingredient_aura;
}
diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp
index 0c0bae17c5d..307e8c8a2c6 100644
--- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp
+++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_blackheart_the_inciter.cpp
@@ -16,12 +16,12 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Boss_Blackheart_the_Inciter
-SD%Complete: 75
-SDComment: Incite Chaos not functional since core lacks Mind Control support
-SDCategory: Auchindoun, Shadow Labyrinth
-EndScriptData */
+/*
+Name: Boss_Blackheart_the_Inciter
+%Complete: 75
+Comment: Incite Chaos not functional since core lacks Mind Control support
+Category: Auchindoun, Shadow Labyrinth
+*/
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
@@ -48,38 +48,26 @@ enum BlackheartTheInciter
SAY2_DEATH = 9
};
+enum Events
+{
+ EVENT_INCITE_CHAOS_WAIT = 1,
+ EVENT_INCITE_CHAOS = 2,
+ EVENT_CHARGE_ATTACK = 3,
+ EVENT_WAR_STOMP = 4
+};
+
class boss_blackheart_the_inciter : public CreatureScript
{
public:
boss_blackheart_the_inciter() : CreatureScript("boss_blackheart_the_inciter") { }
- CreatureAI* GetAI(Creature* creature) const
+ struct boss_blackheart_the_inciterAI : public BossAI
{
- return new boss_blackheart_the_inciterAI (creature);
- }
-
- struct boss_blackheart_the_inciterAI : public ScriptedAI
- {
- boss_blackheart_the_inciterAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
-
- InstanceScript* instance;
-
- bool InciteChaos;
- uint32 InciteChaos_Timer;
- uint32 InciteChaosWait_Timer;
- uint32 Charge_Timer;
- uint32 Knockback_Timer;
+ boss_blackheart_the_inciterAI(Creature* creature) : BossAI(creature, DATA_BLACKHEARTTHEINCITEREVENT) { }
void Reset()
{
InciteChaos = false;
- InciteChaos_Timer = 20000;
- InciteChaosWait_Timer = 15000;
- Charge_Timer = 5000;
- Knockback_Timer = 15000;
if (instance)
instance->SetData(DATA_BLACKHEARTTHEINCITEREVENT, NOT_STARTED);
@@ -100,6 +88,11 @@ public:
void EnterCombat(Unit* /*who*/)
{
+ events.ScheduleEvent(EVENT_INCITE_CHAOS_WAIT, 15000);
+ events.ScheduleEvent(EVENT_INCITE_CHAOS, 20000);
+ events.ScheduleEvent(EVENT_CHARGE_ATTACK, 5000);
+ events.ScheduleEvent(EVENT_WAR_STOMP, 15000);
+
Talk(SAY_AGGRO);
if (instance)
@@ -108,55 +101,59 @@ public:
void UpdateAI(uint32 diff)
{
- //Return since we have no target
if (!UpdateVictim())
return;
- if (InciteChaos)
- {
- if (InciteChaosWait_Timer <= diff)
- {
- InciteChaos = false;
- InciteChaosWait_Timer = 15000;
- } else InciteChaosWait_Timer -= diff;
+ events.Update(diff);
+ if (me->HasUnitState(UNIT_STATE_CASTING))
return;
- }
- if (InciteChaos_Timer <= diff)
+ while (uint32 eventId = events.ExecuteEvent())
{
- DoCast(me, SPELL_INCITE_CHAOS);
-
- std::list<HostileReference*> t_list = me->getThreatManager().getThreatList();
- for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
+ switch (eventId)
{
- Unit* target = Unit::GetUnit(*me, (*itr)->getUnitGuid());
- if (target && target->GetTypeId() == TYPEID_PLAYER)
- me->CastSpell(target, SPELL_INCITE_CHAOS_B, true);
+ case EVENT_INCITE_CHAOS_WAIT:
+ InciteChaos = false;
+ events.ScheduleEvent(EVENT_INCITE_CHAOS_WAIT, 15000);
+ break;
+ case EVENT_INCITE_CHAOS:
+ {
+ DoCast(me, SPELL_INCITE_CHAOS);
+
+ std::list<HostileReference*> t_list = me->getThreatManager().getThreatList();
+ for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
+ {
+ Unit* target = Unit::GetUnit(*me, (*itr)->getUnitGuid());
+ if (target && target->GetTypeId() == TYPEID_PLAYER)
+ me->CastSpell(target, SPELL_INCITE_CHAOS_B, true);
+ }
+
+ DoResetThreat();
+ InciteChaos = true;
+ events.ScheduleEvent(EVENT_INCITE_CHAOS, 40000);
+ break;
+ }
+ case EVENT_CHARGE_ATTACK:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_CHARGE);
+ events.ScheduleEvent(EVENT_CHARGE, urand(15000, 25000));
+ break;
+ case EVENT_WAR_STOMP:
+ DoCast(me, SPELL_WAR_STOMP);
+ events.ScheduleEvent(EVENT_WAR_STOMP, urand(18000, 24000));
+ break;
}
+ }
+ DoMeleeAttackIfReady();
+ }
- DoResetThreat();
- InciteChaos = true;
- InciteChaos_Timer = 40000;
- return;
- } else InciteChaos_Timer -= diff;
-
- //Charge_Timer
- if (Charge_Timer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_CHARGE);
- Charge_Timer = urand(15000, 25000);
- } else Charge_Timer -= diff;
-
- //Knockback_Timer
- if (Knockback_Timer <= diff)
- {
- DoCast(me, SPELL_WAR_STOMP);
- Knockback_Timer = urand(18000, 24000);
- } else Knockback_Timer -= diff;
+ private:
+ bool InciteChaos;
- DoMeleeAttackIfReady();
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new boss_blackheart_the_inciterAI (creature);
}
};
diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp
index a424de35e51..115c75c2f17 100644
--- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp
+++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_grandmaster_vorpil.cpp
@@ -16,12 +16,11 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Boss_Grandmaster_Vorpil
-SD%Complete: 100
-SDComment:
-SDCategory: Auchindoun, Shadow Labyrinth
-EndScriptData */
+/*
+Name: Boss_Grandmaster_Vorpil
+%Complete: 100
+Category: Auchindoun, Shadow Labyrinth
+*/
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
@@ -43,13 +42,13 @@ enum GrandmasterVorpil
SPELL_SHADOWBOLT_VOLLEY = 33841,
SPELL_BANISH = 38791,
- MOB_VOID_TRAVELER = 19226,
+ NPC_VOID_TRAVELER = 19226,
SPELL_SACRIFICE = 33587,
SPELL_SHADOW_NOVA = 33846,
SPELL_EMPOWERING_SHADOWS = 33783,
H_SPELL_EMPOWERING_SHADOWS = 39364,
- MOB_VOID_PORTAL = 19224,
+ NPC_VOID_PORTAL = 19224,
SPELL_VOID_PORTAL_VISUAL = 33569
};
@@ -64,21 +63,22 @@ float VoidPortalCoords[5][3] =
{-261.4533f, -297.3298f, 17.1f}
};
-class mob_voidtraveler : public CreatureScript
+enum Events
{
-public:
- mob_voidtraveler() : CreatureScript("mob_voidtraveler") { }
+ EVENT_SHADOWBOLT_VOLLEY = 1,
+ EVENT_BANISH = 2,
+ EVENT_DRAW_SHADOWS = 3,
+ EVENT_SUMMON_TRAVELER = 4
+};
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_voidtravelerAI (creature);
- }
+class npc_voidtraveler : public CreatureScript
+{
+public:
+ npc_voidtraveler() : CreatureScript("npc_voidtraveler") { }
- struct mob_voidtravelerAI : public ScriptedAI
+ struct npc_voidtravelerAI : public ScriptedAI
{
- mob_voidtravelerAI(Creature* creature) : ScriptedAI(creature)
- {
- }
+ npc_voidtravelerAI(Creature* creature) : ScriptedAI(creature) {}
uint64 VorpilGUID;
uint32 move;
@@ -133,6 +133,11 @@ public:
move = 1000;
} else move -= diff;
}
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_voidtravelerAI (creature);
+ }
};
};
@@ -142,35 +147,15 @@ class boss_grandmaster_vorpil : public CreatureScript
public:
boss_grandmaster_vorpil() : CreatureScript("boss_grandmaster_vorpil") { }
- CreatureAI* GetAI(Creature* creature) const
+ struct boss_grandmaster_vorpilAI : public BossAI
{
- return new boss_grandmaster_vorpilAI (creature);
- }
-
- struct boss_grandmaster_vorpilAI : public ScriptedAI
- {
- boss_grandmaster_vorpilAI(Creature* creature) : ScriptedAI(creature)
+ boss_grandmaster_vorpilAI(Creature* creature) : BossAI(creature, DATA_GRANDMASTERVORPIL)
{
- instance = creature->GetInstanceScript();
Intro = false;
}
- InstanceScript* instance;
- bool Intro, HelpYell;
- bool sumportals;
-
- uint32 ShadowBoltVolley_Timer;
- uint32 DrawShadows_Timer;
- uint32 summonTraveler_Timer;
- uint32 banish_Timer;
- uint64 PortalsGuid[5];
-
void Reset()
{
- ShadowBoltVolley_Timer = urand(7000, 14000);
- DrawShadows_Timer = 45000;
- summonTraveler_Timer = 90000;
- banish_Timer = 17000;
HelpYell = false;
sumportals = false;
destroyPortals();
@@ -186,7 +171,7 @@ public:
for (uint8 i = 0; i < 5; ++i)
{
Creature* Portal = NULL;
- Portal = me->SummonCreature(MOB_VOID_PORTAL, VoidPortalCoords[i][0], VoidPortalCoords[i][1], VoidPortalCoords[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 3000000);
+ Portal = me->SummonCreature(NPC_VOID_PORTAL, VoidPortalCoords[i][0], VoidPortalCoords[i][1], VoidPortalCoords[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 3000000);
if (Portal)
{
PortalsGuid[i] = Portal->GetGUID();
@@ -194,7 +179,7 @@ public:
}
}
sumportals = true;
- summonTraveler_Timer = 5000;
+ events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 5000);
}
}
@@ -216,7 +201,7 @@ public:
void spawnVoidTraveler()
{
int pos = urand(0, 4);
- me->SummonCreature(MOB_VOID_TRAVELER, VoidPortalCoords[pos][0], VoidPortalCoords[pos][1], VoidPortalCoords[pos][2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000);
+ me->SummonCreature(NPC_VOID_TRAVELER, VoidPortalCoords[pos][0], VoidPortalCoords[pos][1], VoidPortalCoords[pos][2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000);
if (!HelpYell)
{
Talk(SAY_HELP);
@@ -226,8 +211,8 @@ public:
void JustSummoned(Creature* summoned)
{
- if (summoned && summoned->GetEntry() == MOB_VOID_TRAVELER)
- CAST_AI(mob_voidtraveler::mob_voidtravelerAI, summoned->AI())->VorpilGUID = me->GetGUID();
+ if (summoned && summoned->GetEntry() == NPC_VOID_TRAVELER)
+ CAST_AI(npc_voidtraveler::npc_voidtravelerAI, summoned->AI())->VorpilGUID = me->GetGUID();
}
void KilledUnit(Unit* /*victim*/)
@@ -246,11 +231,18 @@ public:
void EnterCombat(Unit* /*who*/)
{
+ events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, urand(7000, 14000));
+ if (IsHeroic())
+ events.ScheduleEvent(EVENT_BANISH, 17000);
+ events.ScheduleEvent(EVENT_DRAW_SHADOWS, 45000);
+ events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 90000);
+
Talk(SAY_AGGRO);
summonPortals();
if (instance)
instance->SetData(DATA_GRANDMASTERVORPILEVENT, IN_PROGRESS);
+ _EnterCombat();
}
void MoveInLineOfSight(Unit* who)
@@ -269,50 +261,60 @@ public:
if (!UpdateVictim())
return;
- if (ShadowBoltVolley_Timer <= diff)
- {
- DoCast(me, SPELL_SHADOWBOLT_VOLLEY);
- ShadowBoltVolley_Timer = urand(15000, 30000);
- } else ShadowBoltVolley_Timer -= diff;
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (IsHeroic() && banish_Timer <= diff)
+ while (uint32 eventId = events.ExecuteEvent())
{
- Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30, false);
- if (target)
+ switch (eventId)
{
- DoCast(target, SPELL_BANISH);
- banish_Timer = 16000;
+ case EVENT_SHADOWBOLT_VOLLEY:
+ DoCast(me, SPELL_SHADOWBOLT_VOLLEY);
+ events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, urand(15000, 30000));
+ break;
+ case EVENT_BANISH:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30, false))
+ DoCast(target, SPELL_BANISH);
+ events.ScheduleEvent(EVENT_BANISH, 16000);
+ break;
+ case EVENT_DRAW_SHADOWS:
+ {
+ Map* map = me->GetMap();
+ Map::PlayerList const &PlayerList = map->GetPlayers();
+ for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
+ if (Player* i_pl = i->GetSource())
+ if (i_pl->IsAlive() && !i_pl->HasAura(SPELL_BANISH))
+ i_pl->TeleportTo(me->GetMapId(), VorpilPosition[0], VorpilPosition[1], VorpilPosition[2], 0, TELE_TO_NOT_LEAVE_COMBAT);
+
+ me->SetPosition(VorpilPosition[0], VorpilPosition[1], VorpilPosition[2], 0.0f);
+ DoCast(me, SPELL_DRAW_SHADOWS, true);
+ DoCast(me, SPELL_RAIN_OF_FIRE);
+ events.ScheduleEvent(EVENT_SHADOWBOLT_VOLLEY, 6000);
+ events.ScheduleEvent(EVENT_DRAW_SHADOWS, 30000);
+ break;
+ }
+ case EVENT_SUMMON_TRAVELER:
+ spawnVoidTraveler();
+ events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 10000);
+ //enrage at 20%
+ if (HealthBelowPct(20))
+ events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 5000);
+ break;
}
- } else banish_Timer -= diff;
-
- if (DrawShadows_Timer <= diff)
- {
- Map* map = me->GetMap();
- Map::PlayerList const &PlayerList = map->GetPlayers();
- for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- if (Player* i_pl = i->GetSource())
- if (i_pl->IsAlive() && !i_pl->HasAura(SPELL_BANISH))
- i_pl->TeleportTo(me->GetMapId(), VorpilPosition[0], VorpilPosition[1], VorpilPosition[2], 0, TELE_TO_NOT_LEAVE_COMBAT);
-
- me->SetPosition(VorpilPosition[0], VorpilPosition[1], VorpilPosition[2], 0.0f);
- DoCast(me, SPELL_DRAW_SHADOWS, true);
-
- DoCast(me, SPELL_RAIN_OF_FIRE);
+ }
+ DoMeleeAttackIfReady();
+ }
- ShadowBoltVolley_Timer = 6000;
- DrawShadows_Timer = 30000;
- } else DrawShadows_Timer -= diff;
+ private:
+ bool Intro, HelpYell;
+ bool sumportals;
+ uint64 PortalsGuid[5];
- if (summonTraveler_Timer <= diff)
- {
- spawnVoidTraveler();
- summonTraveler_Timer = 10000;
- //enrage at 20%
- if (HealthBelowPct(20))
- summonTraveler_Timer = 5000;
- } else summonTraveler_Timer -=diff;
-
- DoMeleeAttackIfReady();
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new boss_grandmaster_vorpilAI (creature);
}
};
@@ -321,5 +323,5 @@ public:
void AddSC_boss_grandmaster_vorpil()
{
new boss_grandmaster_vorpil();
- new mob_voidtraveler();
+ new npc_voidtraveler();
}
diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp
index 786eb662a57..b96418097f3 100644
--- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp
+++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_murmur.cpp
@@ -30,53 +30,51 @@ EndScriptData */
enum Murmur
{
+ // Spell
SPELL_RESONANCE = 33657,
SPELL_MAGNETIC_PULL = 33689,
SPELL_SONIC_SHOCK = 38797,
SPELL_THUNDERING_STORM = 39365,
+ SPELL_SONIC_BOOM_CAST = 33923,
+ SPELL_SONIC_BOOM_EFFECT = 33666,
+ SPELL_MURMURS_TOUCH = 33711,
+ // Text
EMOTE_SONIC_BOOM = 0
};
-#define SPELL_SONIC_BOOM_CAST DUNGEON_MODE(33923, 38796)
-#define SPELL_SONIC_BOOM_EFFECT DUNGEON_MODE(33666, 38795)
-
-#define SPELL_MURMURS_TOUCH DUNGEON_MODE(33711, 38794)
-
+enum Events
+{
+ EVENT_SONIC_BOOM = 1,
+ EVENT_MURMURS_TOUCH = 2,
+ EVENT_RESONANCE = 3,
+ EVENT_MAGNETIC_PULL = 4,
+ EVENT_THUNDERING_STORM = 5,
+ EVENT_SONIC_SHOCK = 6
+};
class boss_murmur : public CreatureScript
{
public:
boss_murmur() : CreatureScript("boss_murmur") { }
- CreatureAI* GetAI(Creature* creature) const
+ struct boss_murmurAI : public BossAI
{
- return new boss_murmurAI (creature);
- }
-
- struct boss_murmurAI : public ScriptedAI
- {
- boss_murmurAI(Creature* creature) : ScriptedAI(creature)
+ boss_murmurAI(Creature* creature) : BossAI(creature, DATA_MURMUREVENT)
{
SetCombatMovement(false);
}
- uint32 SonicBoom_Timer;
- uint32 MurmursTouch_Timer;
- uint32 Resonance_Timer;
- uint32 MagneticPull_Timer;
- uint32 SonicShock_Timer;
- uint32 ThunderingStorm_Timer;
- bool SonicBoom;
-
void Reset()
{
- SonicBoom_Timer = 30000;
- MurmursTouch_Timer = urand(8000, 20000);
- Resonance_Timer = 5000;
- MagneticPull_Timer = urand(15000, 30000);
- ThunderingStorm_Timer = 15000;
- SonicShock_Timer = 10000;
- SonicBoom = false;
+ events.ScheduleEvent(EVENT_SONIC_BOOM, 30000);
+ events.ScheduleEvent(EVENT_MURMURS_TOUCH, urand(8000, 20000));
+ events.ScheduleEvent(EVENT_RESONANCE, 5000);
+ events.ScheduleEvent(EVENT_MAGNETIC_PULL, urand(15000, 30000));
+ if (IsHeroic())
+ {
+ events.ScheduleEvent(EVENT_THUNDERING_STORM, 15000);
+ events.ScheduleEvent(EVENT_SONIC_SHOCK, 10000);
+ }
//database should have `RegenHealth`=0 to prevent regen
uint32 hp = me->CountPctFromMaxHealth(40);
@@ -117,81 +115,65 @@ public:
if (!UpdateVictim() || me->IsNonMeleeSpellCasted(false))
return;
- // Sonic Boom
- if (SonicBoom)
- {
- DoCast(me, SPELL_SONIC_BOOM_EFFECT, true);
- SonicBoomEffect();
-
- SonicBoom = false;
- Resonance_Timer = 1500;
- }
- if (SonicBoom_Timer <= diff)
- {
- Talk(EMOTE_SONIC_BOOM);
- DoCast(me, SPELL_SONIC_BOOM_CAST);
- SonicBoom_Timer = 30000;
- SonicBoom = true;
- return;
- } else SonicBoom_Timer -= diff;
-
- // Murmur's Touch
- if (MurmursTouch_Timer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 80, true))
- DoCast(target, SPELL_MURMURS_TOUCH);
- MurmursTouch_Timer = urand(25000, 35000);
- } else MurmursTouch_Timer -= diff;
+ events.Update(diff);
- // Resonance
- if (!SonicBoom && !(me->IsWithinMeleeRange(me->GetVictim())))
+ while (uint32 eventId = events.ExecuteEvent())
{
- if (Resonance_Timer <= diff)
+ switch (eventId)
{
- DoCast(me, SPELL_RESONANCE);
- Resonance_Timer = 5000;
- } else Resonance_Timer -= diff;
- }
-
- // Magnetic Pull
- if (MagneticPull_Timer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- if (target->GetTypeId() == TYPEID_PLAYER && target->IsAlive())
+ case EVENT_SONIC_BOOM:
+ Talk(EMOTE_SONIC_BOOM);
+ DoCast(me, SPELL_SONIC_BOOM_CAST);
+ DoCast(me, SPELL_SONIC_BOOM_EFFECT, true);
+ SonicBoomEffect();
+ events.ScheduleEvent(EVENT_SONIC_BOOM, 30000);
+ events.ScheduleEvent(EVENT_RESONANCE, 1500);
+ break;
+ case EVENT_MURMURS_TOUCH:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 80, true))
+ DoCast(target, SPELL_MURMURS_TOUCH);
+ events.ScheduleEvent(EVENT_MURMURS_TOUCH, urand(25000, 35000));
+ break;
+ case EVENT_RESONANCE:
+ if (!(me->IsWithinMeleeRange(me->GetVictim())))
+ {
+ DoCast(me, SPELL_RESONANCE);
+ events.ScheduleEvent(EVENT_RESONANCE, 5000);
+ }
+ break;
+ case EVENT_MAGNETIC_PULL:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ if (target->GetTypeId() == TYPEID_PLAYER && target->IsAlive())
+ {
+ DoCast(target, SPELL_MAGNETIC_PULL);
+ events.ScheduleEvent(EVENT_MAGNETIC_PULL, 15000+rand()%15000);
+ break;
+ }
+ events.ScheduleEvent(EVENT_MAGNETIC_PULL, 500);
+ break;
+ case EVENT_THUNDERING_STORM:
{
- DoCast(target, SPELL_MAGNETIC_PULL);
- MagneticPull_Timer = 15000+rand()%15000;
- return;
- }
- MagneticPull_Timer = 500;
- } else MagneticPull_Timer -= diff;
-
- if (IsHeroic())
- {
- // Thundering Storm
- if (ThunderingStorm_Timer <= diff)
- {
- ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
- for (ThreatContainer::StorageType::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i)
- if (Unit* target = Unit::GetUnit(*me, (*i)->getUnitGuid()))
- if (target->IsAlive() && !me->IsWithinDist(target, 35, false))
- DoCast(target, SPELL_THUNDERING_STORM, true);
- ThunderingStorm_Timer = 15000;
- } else ThunderingStorm_Timer -= diff;
-
- // Sonic Shock
- if (SonicShock_Timer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 20, false))
- if (target->IsAlive())
- DoCast(target, SPELL_SONIC_SHOCK);
- SonicShock_Timer = 10000+rand()%10000;
- } else SonicShock_Timer -= diff;
+ ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
+ for (ThreatContainer::StorageType::const_iterator i = threatlist.begin(); i != threatlist.end(); ++i)
+ if (Unit* target = Unit::GetUnit(*me, (*i)->getUnitGuid()))
+ if (target->IsAlive() && !me->IsWithinDist(target, 35, false))
+ DoCast(target, SPELL_THUNDERING_STORM, true);
+ events.ScheduleEvent(EVENT_THUNDERING_STORM, 15000);
+ break;
+ }
+ case EVENT_SONIC_SHOCK:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 20, false))
+ if (target->IsAlive())
+ DoCast(target, SPELL_SONIC_SHOCK);
+ events.ScheduleEvent(EVENT_SONIC_SHOCK, 10000+rand()%10000);
+ break;
+ }
}
// Select nearest most aggro target if top aggro too far
if (!me->isAttackReady())
return;
+
if (!me->IsWithinMeleeRange(me->GetVictim()))
{
ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
@@ -206,6 +188,11 @@ public:
DoMeleeAttackIfReady();
}
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new boss_murmurAI (creature);
+ }
};
};
diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp
index 970b78a2cea..e3dec9c0a45 100644
--- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp
+++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/instance_shadow_labyrinth.cpp
@@ -27,11 +27,6 @@ EndScriptData */
#include "InstanceScript.h"
#include "shadow_labyrinth.h"
-#define MAX_ENCOUNTER 5
-
-#define REFECTORY_DOOR 183296 //door opened when blackheart the inciter dies
-#define SCREAMING_HALL_DOOR 183295 //door opened when grandmaster vorpil dies
-
/* Shadow Labyrinth encounters:
1 - Ambassador Hellmaw event
2 - Blackheart the Inciter event
@@ -53,7 +48,7 @@ public:
{
instance_shadow_labyrinth_InstanceMapScript(Map* map) : InstanceScript(map) {}
- uint32 m_auiEncounter[MAX_ENCOUNTER];
+ uint32 m_auiEncounter[EncounterCount];
std::string str_data;
uint64 m_uiRefectoryDoorGUID;
@@ -75,7 +70,7 @@ public:
bool IsEncounterInProgress() const
{
- for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ for (uint8 i = 0; i < EncounterCount; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
return true;
@@ -217,7 +212,7 @@ public:
std::istringstream loadStream(in);
loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3] >> m_auiEncounter[4];
- for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
+ for (uint8 i = 0; i < EncounterCount; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
m_auiEncounter[i] = NOT_STARTED;
diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h
index 9c6ca776dea..8fdb60b32a6 100644
--- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h
+++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/shadow_labyrinth.h
@@ -19,11 +19,23 @@
#ifndef DEF_SHADOW_LABYRINTH_H
#define DEF_SHADOW_LABYRINTH_H
-#define TYPE_HELLMAW 1
-#define TYPE_OVERSEER 2
-#define DATA_BLACKHEARTTHEINCITEREVENT 3
-#define DATA_GRANDMASTERVORPILEVENT 4
-#define DATA_MURMUREVENT 5
-#define DATA_GRANDMASTERVORPIL 6
+uint32 const EncounterCount = 5;
+
+enum DataTypes
+{
+ TYPE_HELLMAW = 1,
+ TYPE_OVERSEER = 2,
+ DATA_BLACKHEARTTHEINCITEREVENT = 3,
+ DATA_GRANDMASTERVORPILEVENT = 4,
+ DATA_MURMUREVENT = 5,
+ DATA_GRANDMASTERVORPIL = 6
+};
+
+enum Objects
+{
+ REFECTORY_DOOR = 183296, // door opened when blackheart the inciter dies
+ SCREAMING_HALL_DOOR = 183295 // door opened when grandmaster vorpil dies
+};
+
#endif
diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
index 59419f6dcbd..7cac1128815 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
@@ -810,7 +810,7 @@ public:
{
case 1: // lift off
me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
- me->SetUnitMovementFlags(MOVEMENTFLAG_DISABLE_GRAVITY);
+ me->SetDisableGravity(true);
me->StopMoving();
me->MonsterYell(SAY_TAKEOFF, LANG_UNIVERSAL, 0);
DoPlaySoundToSet(me, SOUND_TAKEOFF);
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp
index 8ca61395f3a..13e6a1abd05 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/boss_lurker_below.cpp
@@ -112,7 +112,8 @@ public:
}
void Reset()
{
- me->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_DISABLE_GRAVITY);
+ me->SetSwim(true);
+ me->SetDisableGravity(true);
SpoutAnimTimer = 1000;
RotTimer = 0;
WaterboltTimer = 15000; // give time to get in range when fight starts
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp
index 439edefae8c..27134a3a740 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp
@@ -156,7 +156,8 @@ class instance_serpent_shrine : public InstanceMapScript
if (Creature* frenzy = player->SummonCreature(MOB_COILFANG_FRENZY, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 2000))
{
frenzy->Attack(player, false);
- frenzy->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_DISABLE_GRAVITY);
+ frenzy->SetSwim(true);
+ frenzy->SetDisableGravity(true);
}
DoSpawnFrenzy = false;
}
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
index 530e811f8cd..61cccc7ae24 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_alar.cpp
@@ -132,7 +132,7 @@ class boss_alar : public CreatureScript
//me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 10);
//me->SetFloatValue(UNIT_FIELD_COMBATREACH, 10);
me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true);
- me->SetUnitMovementFlags(MOVEMENTFLAG_DISABLE_GRAVITY);
+ me->SetDisableGravity(true);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->setActive(false);
}
@@ -142,7 +142,7 @@ class boss_alar : public CreatureScript
if (instance)
instance->SetData(DATA_ALAREVENT, IN_PROGRESS);
- me->SetUnitMovementFlags(MOVEMENTFLAG_DISABLE_GRAVITY); // after enterevademode will be set walk movement
+ me->SetDisableGravity(true); // after enterevademode will be set walk movement
DoZoneInCombat();
me->setActive(true);
}
@@ -472,7 +472,7 @@ class mob_ember_of_alar : public CreatureScript
mob_ember_of_alarAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
- creature->SetUnitMovementFlags(MOVEMENTFLAG_DISABLE_GRAVITY);
+ creature->SetDisableGravity(true);
creature->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true);
}
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index b727aa6f0e6..a99c02a60c0 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -986,7 +986,7 @@ class spell_gen_parachute_ic : public SpellScriptLoader
void HandleTriggerSpell(AuraEffect const* /*aurEff*/)
{
if (Player* target = GetTarget()->ToPlayer())
- if (target->m_movementInfo.fallTime > 2000)
+ if (target->m_movementInfo.jump.fallTime > 2000)
target->CastSpell(target, SPELL_PARACHUTE_IC, true);
}
diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp
index 013dfda809d..5b55b532566 100644
--- a/src/server/scripts/Spells/spell_quest.cpp
+++ b/src/server/scripts/Spells/spell_quest.cpp
@@ -1602,6 +1602,37 @@ class spell_q12527_zuldrak_rat : public SpellScriptLoader
}
};
+class spell_q12661_q12669_q12676_q12677_q12713_summon_stefan : public SpellScriptLoader
+{
+ public:
+ spell_q12661_q12669_q12676_q12677_q12713_summon_stefan() : SpellScriptLoader("spell_q12661_q12669_q12676_q12677_q12713_summon_stefan") { }
+
+ class spell_q12661_q12669_q12676_q12677_q12713_summon_stefan_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q12661_q12669_q12676_q12677_q12713_summon_stefan_SpellScript);
+
+ void ChangeSummonPos(SpellEffIndex /*effIndex*/)
+ {
+ // Adjust effect summon position
+ WorldLocation summonPos = *GetExplTargetDest();
+ Position offset = { 0.0f, 0.0f, 20.0f, 0.0f };
+ summonPos.RelocateOffset(offset);
+ SetExplTargetDest(summonPos);
+ GetHitDest()->RelocateOffset(offset);
+ }
+
+ void Register()
+ {
+ OnEffectHit += SpellEffectFn(spell_q12661_q12669_q12676_q12677_q12713_summon_stefan_SpellScript::ChangeSummonPos, EFFECT_0, SPELL_EFFECT_SUMMON);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_q12661_q12669_q12676_q12677_q12713_summon_stefan_SpellScript();
+ }
+};
+
enum QuenchingMist
{
SPELL_FLICKERING_FLAMES = 53504
@@ -1789,6 +1820,7 @@ void AddSC_quest_spell_scripts()
new spell_q11010_q11102_q11023_q11008_check_fly_mount();
new spell_q12372_azure_on_death_force_whisper();
new spell_q12527_zuldrak_rat();
+ new spell_q12661_q12669_q12676_q12677_q12713_summon_stefan();
new spell_q12730_quenching_mist();
new spell_q13291_q13292_q13239_q13261_frostbrood_skytalon_grab_decoy();
new spell_q13291_q13292_q13239_q13261_armored_decoy_summon_skytalon();
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index 868531c6ad4..e810e6f39bf 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -1904,7 +1904,7 @@ public:
//! HACK: Creature's can't have MOVEMENTFLAG_FLYING
// Fly Away
- me->AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY|MOVEMENTFLAG_ASCENDING|MOVEMENTFLAG_FLYING);
+ me->SetCanFly(true);
me->SetSpeed(MOVE_FLIGHT, 0.75f, true);
me->SetSpeed(MOVE_RUN, 0.75f, true);
float x = me->GetPositionX() + 20 * std::cos(me->GetOrientation());
diff --git a/src/server/shared/CMakeLists.txt b/src/server/shared/CMakeLists.txt
index 447819b0431..4fc318f57eb 100644
--- a/src/server/shared/CMakeLists.txt
+++ b/src/server/shared/CMakeLists.txt
@@ -16,7 +16,6 @@ file(GLOB_RECURSE sources_Configuration Configuration/*.cpp Configuration/*.h)
file(GLOB_RECURSE sources_Cryptography Cryptography/*.cpp Cryptography/*.h)
file(GLOB_RECURSE sources_Database Database/*.cpp Database/*.h)
file(GLOB_RECURSE sources_DataStores DataStores/*.cpp DataStores/*.h)
-file(GLOB_RECURSE sources_Debugging Debugging/*.cpp Debugging/*.h)
file(GLOB_RECURSE sources_Dynamic Dynamic/*.cpp Dynamic/*.h)
file(GLOB_RECURSE sources_Logging Logging/*.cpp Logging/*.h)
file(GLOB_RECURSE sources_Packets Packets/*.cpp Packets/*.h)
@@ -25,6 +24,11 @@ file(GLOB_RECURSE sources_Utilities Utilities/*.cpp Utilities/*.h)
file(GLOB sources_localdir *.cpp *.h)
+# Manually set sources for Debugging directory as we don't want to include WheatyExceptionReport in shared project
+# It needs to be included both in authserver and worldserver for the static global variable to be properly initialized
+# and to handle crash logs on windows
+set(sources_Debugging Debugging/Errors.cpp Debugging/Errors.h)
+
#
# Build shared sourcelist
#
diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt
index e461a019af5..b63340a690c 100644
--- a/src/server/worldserver/CMakeLists.txt
+++ b/src/server/worldserver/CMakeLists.txt
@@ -29,18 +29,16 @@ set(worldserver_SRCS
)
if( WIN32 )
+ set(worldserver_SRCS
+ ${worldserver_SRCS}
+ ${sources_windows_Debugging}
+ )
if ( MSVC )
set(worldserver_SRCS
${worldserver_SRCS}
- ${sources_Debugging}
worldserver.rc
)
- else ( )
- set(worldserver_SRCS
- ${worldserver_SRCS}
- ${sources_Debugging}
- )
- endif ()
+ endif()
endif()
include_directories(
diff --git a/src/tools/mmaps_generator/Info/readme.txt b/src/tools/mmaps_generator/Info/readme.txt
index ff3f2f43526..bde8e61b080 100644
--- a/src/tools/mmaps_generator/Info/readme.txt
+++ b/src/tools/mmaps_generator/Info/readme.txt
@@ -8,7 +8,7 @@ Generator command line args
"map_id tile_x,tile_y (start_x start_y start_z) (end_x end_y end_z) size //optional comments"
Single mesh connection per line.
---silent Make us script friendly. Do not wait for user input
+--silent [] Make us script friendly. Do not wait for user input
on error or completion.
--bigBaseUnit [true|false] Generate tile/map using bigger basic unit.
@@ -20,7 +20,7 @@ Generator command line args
float between 45 and 90 degrees (default 60)
---skipLiquid liquid data for maps
+--skipLiquid [true|false] extract liquid data for maps
false: include liquid data (default)
diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp
index cd85d926125..d4192571454 100644
--- a/src/tools/mmaps_generator/MapBuilder.cpp
+++ b/src/tools/mmaps_generator/MapBuilder.cpp
@@ -36,7 +36,7 @@ namespace DisableMgr
}
#define MMAP_MAGIC 0x4d4d4150 // 'MMAP'
-#define MMAP_VERSION 3
+#define MMAP_VERSION 4
struct MmapTileHeader
{
@@ -332,12 +332,12 @@ namespace MMAP
buildNavMesh(mapID, navMesh);
if (!navMesh)
{
- printf("[Map %i] Failed creating navmesh!\n", mapID);
+ printf("[Map %03i] Failed creating navmesh!\n", mapID);
return;
}
// now start building mmtiles for each tile
- printf("[Map %i] We have %u tiles. \n", mapID, (unsigned int)tiles->size());
+ printf("[Map %03i] We have %u tiles. \n", mapID, (unsigned int)tiles->size());
for (std::set<uint32>::iterator it = tiles->begin(); it != tiles->end(); ++it)
{
uint32 tileX, tileY;
@@ -354,13 +354,13 @@ namespace MMAP
dtFreeNavMesh(navMesh);
}
- printf("[Map %i] Complete!\n", mapID);
+ printf("[Map %03i] Complete!\n", mapID);
}
/**************************************************************************/
void MapBuilder::buildTile(uint32 mapID, uint32 tileX, uint32 tileY, dtNavMesh* navMesh)
{
- printf("[Map %i] Building tile [%02u,%02u]\n", mapID, tileX, tileY);
+ printf("[Map %03i] Building tile [%02u,%02u]\n", mapID, tileX, tileY);
MeshData meshData;
@@ -446,10 +446,10 @@ namespace MMAP
navMeshParams.maxPolys = maxPolysPerTile;
navMesh = dtAllocNavMesh();
- printf("[Map %i] Creating navMesh...\n", mapID);
+ printf("[Map %03i] Creating navMesh...\n", mapID);
if (!navMesh->init(&navMeshParams))
{
- printf("[Map %i] Failed creating navmesh! \n", mapID);
+ printf("[Map %03i] Failed creating navmesh! \n", mapID);
return;
}
@@ -461,7 +461,7 @@ namespace MMAP
{
dtFreeNavMesh(navMesh);
char message[1024];
- sprintf(message, "[Map %i] Failed to open %s for writing!\n", mapID, fileName);
+ sprintf(message, "[Map %03i] Failed to open %s for writing!\n", mapID, fileName);
perror(message);
return;
}
@@ -496,8 +496,8 @@ namespace MMAP
// these are WORLD UNIT based metrics
// this are basic unit dimentions
- // value have to divide GRID_SIZE(533.33333f) ( aka: 0.5333, 0.2666, 0.3333, 0.1333, etc )
- const static float BASE_UNIT_DIM = m_bigBaseUnit ? 0.533333f : 0.266666f;
+ // value have to divide GRID_SIZE(533.3333f) ( aka: 0.5333, 0.2666, 0.3333, 0.1333, etc )
+ const static float BASE_UNIT_DIM = m_bigBaseUnit ? 0.5333333f : 0.2666666f;
// All are in UNIT metrics!
const static int VERTEX_PER_MAP = int(GRID_SIZE/BASE_UNIT_DIM + 0.5f);
@@ -517,12 +517,12 @@ namespace MMAP
config.tileSize = VERTEX_PER_TILE;
config.walkableRadius = m_bigBaseUnit ? 1 : 2;
config.borderSize = config.walkableRadius + 3;
- config.maxEdgeLen = VERTEX_PER_TILE + 1; //anything bigger than tileSize
- config.walkableHeight = m_bigBaseUnit ? 3 : 6;
- config.walkableClimb = m_bigBaseUnit ? 2 : 4; // keep less than walkableHeight
+ config.maxEdgeLen = VERTEX_PER_TILE + 1; // anything bigger than tileSize
+ config.walkableHeight = m_bigBaseUnit ? 2 : 4;
+ config.walkableClimb = m_bigBaseUnit ? 1 : 2; // keep less than walkableHeight
config.minRegionArea = rcSqr(60);
config.mergeRegionArea = rcSqr(50);
- config.maxSimplificationError = 2.0f; // eliminates most jagged edges (tinny polygons)
+ config.maxSimplificationError = 1.8f; // eliminates most jagged edges (tiny polygons)
config.detailSampleDist = config.cs * 64;
config.detailSampleMaxError = config.ch * 2;
@@ -677,14 +677,6 @@ namespace MMAP
delete[] tiles;
- // remove padding for extraction
- for (int i = 0; i < iv.polyMesh->nverts; ++i)
- {
- unsigned short* v = &iv.polyMesh->verts[i*3];
- v[0] -= (unsigned short)config.borderSize;
- v[2] -= (unsigned short)config.borderSize;
- }
-
// set polygons as walkable
// TODO: special flags for DYNAMIC polygons, ie surfaces that can be turned on and off
for (int i = 0; i < iv.polyMesh->npolys; ++i)
@@ -723,8 +715,9 @@ namespace MMAP
rcVcopy(params.bmax, bmax);
params.cs = config.cs;
params.ch = config.ch;
- params.tileSize = VERTEX_PER_MAP;
-
+ params.tileLayer = 0;
+ params.buildBvTree = true;
+
// will hold final navmesh
unsigned char* navData = NULL;
int navDataSize = 0;
@@ -792,7 +785,7 @@ namespace MMAP
if (!file)
{
char message[1024];
- sprintf(message, "[Map %i] Failed to open %s for writing!\n", mapID, fileName);
+ sprintf(message, "[Map %03i] Failed to open %s for writing!\n", mapID, fileName);
perror(message);
navMesh->removeTile(tileRef, NULL, NULL);
continue;
@@ -854,50 +847,50 @@ namespace MMAP
{
if (m_skipContinents)
switch (mapID)
- {
- case 0:
- case 1:
- case 530:
- case 571:
- return true;
- default:
- break;
- }
+ {
+ case 0:
+ case 1:
+ case 530:
+ case 571:
+ return true;
+ default:
+ break;
+ }
if (m_skipJunkMaps)
switch (mapID)
- {
- case 13: // test.wdt
- case 25: // ScottTest.wdt
- case 29: // Test.wdt
- case 42: // Colin.wdt
- case 169: // EmeraldDream.wdt (unused, and very large)
- case 451: // development.wdt
- case 573: // ExteriorTest.wdt
- case 597: // CraigTest.wdt
- case 605: // development_nonweighted.wdt
- case 606: // QA_DVD.wdt
- return true;
- default:
- if (isTransportMap(mapID))
+ {
+ case 13: // test.wdt
+ case 25: // ScottTest.wdt
+ case 29: // Test.wdt
+ case 42: // Colin.wdt
+ case 169: // EmeraldDream.wdt (unused, and very large)
+ case 451: // development.wdt
+ case 573: // ExteriorTest.wdt
+ case 597: // CraigTest.wdt
+ case 605: // development_nonweighted.wdt
+ case 606: // QA_DVD.wdt
return true;
- break;
- }
+ default:
+ if (isTransportMap(mapID))
+ return true;
+ break;
+ }
if (m_skipBattlegrounds)
switch (mapID)
- {
- case 30: // AV
- case 37: // ?
- case 489: // WSG
- case 529: // AB
- case 566: // EotS
- case 607: // SotA
- case 628: // IoC
- return true;
- default:
- break;
- }
+ {
+ case 30: // AV
+ case 37: // ?
+ case 489: // WSG
+ case 529: // AB
+ case 566: // EotS
+ case 607: // SotA
+ case 628: // IoC
+ return true;
+ default:
+ break;
+ }
return false;
}
@@ -908,37 +901,37 @@ namespace MMAP
switch (mapID)
{
// transport maps
- case 582:
- case 584:
- case 586:
- case 587:
- case 588:
- case 589:
- case 590:
- case 591:
- case 592:
- case 593:
- case 594:
- case 596:
- case 610:
- case 612:
- case 613:
- case 614:
- case 620:
- case 621:
- case 622:
- case 623:
- case 641:
- case 642:
- case 647:
- case 672:
- case 673:
- case 712:
- case 713:
- case 718:
- return true;
- default:
- return false;
+ case 582:
+ case 584:
+ case 586:
+ case 587:
+ case 588:
+ case 589:
+ case 590:
+ case 591:
+ case 592:
+ case 593:
+ case 594:
+ case 596:
+ case 610:
+ case 612:
+ case 613:
+ case 614:
+ case 620:
+ case 621:
+ case 622:
+ case 623:
+ case 641:
+ case 642:
+ case 647:
+ case 672:
+ case 673:
+ case 712:
+ case 713:
+ case 718:
+ return true;
+ default:
+ return false;
}
}
diff --git a/src/tools/mmaps_generator/MapBuilder.h b/src/tools/mmaps_generator/MapBuilder.h
index 3ffaea0ab66..6ab0b312af8 100644
--- a/src/tools/mmaps_generator/MapBuilder.h
+++ b/src/tools/mmaps_generator/MapBuilder.h
@@ -61,7 +61,7 @@ namespace MMAP
class MapBuilder
{
public:
- MapBuilder(float maxWalkableAngle = 60.f,
+ MapBuilder(float maxWalkableAngle = 55.f,
bool skipLiquid = false,
bool skipContinents = false,
bool skipJunkMaps = true,
diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp
index 47d35b517d5..ed114491b27 100644
--- a/src/tools/mmaps_generator/PathGenerator.cpp
+++ b/src/tools/mmaps_generator/PathGenerator.cpp
@@ -242,7 +242,7 @@ int finish(const char* message, int returnValue)
int main(int argc, char** argv)
{
int threads = 3, mapnum = -1;
- float maxAngle = 60.0f;
+ float maxAngle = 55.0f;
int tileX = -1, tileY = -1;
bool skipLiquid = false,
skipContinents = false,
diff --git a/src/tools/mmaps_generator/TerrainBuilder.h b/src/tools/mmaps_generator/TerrainBuilder.h
index 069a5a94c84..e9ff2a3c175 100644
--- a/src/tools/mmaps_generator/TerrainBuilder.h
+++ b/src/tools/mmaps_generator/TerrainBuilder.h
@@ -47,7 +47,7 @@ namespace MMAP
static const int V9_SIZE_SQ = V9_SIZE*V9_SIZE;
static const int V8_SIZE = 128;
static const int V8_SIZE_SQ = V8_SIZE*V8_SIZE;
- static const float GRID_SIZE = 533.33333f;
+ static const float GRID_SIZE = 533.3333f;
static const float GRID_PART_SIZE = GRID_SIZE/V8_SIZE;
// see contrib/extractor/system.cpp, CONF_use_minHeight