diff options
Diffstat (limited to 'src')
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(¶ms)) + if (dtStatusFailed(mesh->init(¶ms))) { 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 |