Core/Entities: Phase Rework (main commit)
This commit is contained in:
commit
959dc25d10
79 files changed
+1738
-851
No files matched your search
@@ -0,0 +1,22 @@
|
||||
ALTER TABLE `creature`
|
||||
ADD `phaseUseFlags` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `spawnMask`,
|
||||
ADD `terrainSwapMap` int(11) NOT NULL DEFAULT '-1' AFTER `PhaseGroup`;
|
||||
|
||||
ALTER TABLE `gameobject`
|
||||
ADD `phaseUseFlags` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `spawnMask`,
|
||||
ADD `terrainSwapMap` int(11) NOT NULL DEFAULT '-1' AFTER `PhaseGroup`;
|
||||
|
||||
DROP TABLE `terrain_phase_info`;
|
||||
|
||||
ALTER TABLE `transports` ADD `phaseUseFlags` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `name`;
|
||||
|
||||
DELETE FROM `trinity_string` WHERE `entry` IN (101,178,179,180,181,182,183,184,185);
|
||||
INSERT INTO `trinity_string` (`entry`,`content_default`) VALUES
|
||||
(101,'Map: %u (%s) Zone: %u (%s) Area: %u (%s)\nX: %f Y: %f Z: %f Orientation: %f'),
|
||||
(178,'grid[%u,%u]cell[%u,%u] InstanceID: %u\n ZoneX: %f ZoneY: %f\nGroundZ: %f FloorZ: %f Have height data (Map: %u VMap: %u MMap: %u)'),
|
||||
(179,'PhaseShift:\n* Flags %u, PersonalGuid: %s'),
|
||||
(180,'* Phases: %s'),
|
||||
(181,'* VisibleMapIds: %s'),
|
||||
(182,'* UiWorldMapAreaSwaps: %s'),
|
||||
(183,'Cosmetic'),
|
||||
(184,'Personal');
|
||||
@@ -142,11 +142,11 @@ void DynamicMapTree::update(uint32 t_diff)
|
||||
|
||||
struct DynamicTreeIntersectionCallback
|
||||
{
|
||||
DynamicTreeIntersectionCallback(std::set<uint32> const& phases) : _didHit(false), _phases(phases) { }
|
||||
DynamicTreeIntersectionCallback(PhaseShift const& phaseShift) : _didHit(false), _phaseShift(phaseShift) { }
|
||||
|
||||
bool operator()(G3D::Ray const& r, GameObjectModel const& obj, float& distance)
|
||||
{
|
||||
_didHit = obj.intersectRay(r, distance, true, _phases, VMAP::ModelIgnoreFlags::Nothing);
|
||||
_didHit = obj.intersectRay(r, distance, true, _phaseShift, VMAP::ModelIgnoreFlags::Nothing);
|
||||
return _didHit;
|
||||
}
|
||||
|
||||
@@ -154,20 +154,20 @@ struct DynamicTreeIntersectionCallback
|
||||
|
||||
private:
|
||||
bool _didHit;
|
||||
std::set<uint32> _phases;
|
||||
PhaseShift const& _phaseShift;
|
||||
};
|
||||
|
||||
bool DynamicMapTree::getIntersectionTime(std::set<uint32> const& phases, G3D::Ray const& ray, G3D::Vector3 const& endPos, float& maxDist) const
|
||||
bool DynamicMapTree::getIntersectionTime(G3D::Ray const& ray, G3D::Vector3 const& endPos, PhaseShift const& phaseShift, float& maxDist) const
|
||||
{
|
||||
float distance = maxDist;
|
||||
DynamicTreeIntersectionCallback callback(phases);
|
||||
DynamicTreeIntersectionCallback callback(phaseShift);
|
||||
impl->intersectRay(ray, callback, distance, endPos);
|
||||
if (callback.didHit())
|
||||
maxDist = distance;
|
||||
return callback.didHit();
|
||||
}
|
||||
|
||||
bool DynamicMapTree::getObjectHitPos(std::set<uint32> const& phases, G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, G3D::Vector3& resultHitPos, float modifyDist) const
|
||||
bool DynamicMapTree::getObjectHitPos(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, G3D::Vector3& resultHitPos, float modifyDist, PhaseShift const& phaseShift) const
|
||||
{
|
||||
bool result = false;
|
||||
float maxDist = (endPos - startPos).magnitude();
|
||||
@@ -182,7 +182,7 @@ bool DynamicMapTree::getObjectHitPos(std::set<uint32> const& phases, G3D::Vector
|
||||
G3D::Vector3 dir = (endPos - startPos)/maxDist; // direction with length of 1
|
||||
G3D::Ray ray(startPos, dir);
|
||||
float dist = maxDist;
|
||||
if (getIntersectionTime(phases, ray, endPos, dist))
|
||||
if (getIntersectionTime(ray, endPos, phaseShift, dist))
|
||||
{
|
||||
resultHitPos = startPos + dir * dist;
|
||||
if (modifyDist < 0)
|
||||
@@ -205,7 +205,7 @@ bool DynamicMapTree::getObjectHitPos(std::set<uint32> const& phases, G3D::Vector
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DynamicMapTree::isInLineOfSight(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, std::set<uint32> const& phases) const
|
||||
bool DynamicMapTree::isInLineOfSight(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, PhaseShift const& phaseShift) const
|
||||
{
|
||||
float maxDist = (endPos - startPos).magnitude();
|
||||
|
||||
@@ -213,17 +213,17 @@ bool DynamicMapTree::isInLineOfSight(G3D::Vector3 const& startPos, G3D::Vector3
|
||||
return true;
|
||||
|
||||
G3D::Ray r(startPos, (endPos - startPos) / maxDist);
|
||||
DynamicTreeIntersectionCallback callback(phases);
|
||||
DynamicTreeIntersectionCallback callback(phaseShift);
|
||||
impl->intersectRay(r, callback, maxDist, endPos);
|
||||
|
||||
return !callback.didHit();
|
||||
}
|
||||
|
||||
float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist, std::set<uint32> const& phases) const
|
||||
float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist, PhaseShift const& phaseShift) const
|
||||
{
|
||||
G3D::Vector3 v(x, y, z + 0.5f);
|
||||
G3D::Ray r(v, G3D::Vector3(0, 0, -1));
|
||||
DynamicTreeIntersectionCallback callback(phases);
|
||||
DynamicTreeIntersectionCallback callback(phaseShift);
|
||||
impl->intersectZAllignedRay(r, callback, maxSearchDist);
|
||||
|
||||
if (callback.didHit())
|
||||
|
||||
@@ -29,6 +29,7 @@ namespace G3D
|
||||
}
|
||||
|
||||
class GameObjectModel;
|
||||
class PhaseShift;
|
||||
struct DynTreeImpl;
|
||||
|
||||
class TC_COMMON_API DynamicMapTree
|
||||
@@ -40,11 +41,11 @@ public:
|
||||
DynamicMapTree();
|
||||
~DynamicMapTree();
|
||||
|
||||
bool isInLineOfSight(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, std::set<uint32> const& phases) const;
|
||||
bool getIntersectionTime(std::set<uint32> const& phases, G3D::Ray const& ray, G3D::Vector3 const& endPos, float& maxDist) const;
|
||||
bool getObjectHitPos(std::set<uint32> const& phases, G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, G3D::Vector3& resultHitPos, float modifyDist) const;
|
||||
bool isInLineOfSight(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, PhaseShift const& phaseShift) const;
|
||||
bool getIntersectionTime(G3D::Ray const& ray, G3D::Vector3 const& endPos, PhaseShift const& phaseShift, float& maxDist) const;
|
||||
bool getObjectHitPos(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, G3D::Vector3& resultHitPos, float modifyDist, PhaseShift const& phaseShift) const;
|
||||
|
||||
float getHeight(float x, float y, float z, float maxSearchDist, std::set<uint32> const& phases) const;
|
||||
float getHeight(float x, float y, float z, float maxSearchDist, PhaseShift const& phaseShift) const;
|
||||
|
||||
void insert(const GameObjectModel&);
|
||||
void remove(const GameObjectModel&);
|
||||
|
||||
@@ -152,12 +152,12 @@ GameObjectModel* GameObjectModel::Create(std::unique_ptr<GameObjectModelOwnerBas
|
||||
return mdl;
|
||||
}
|
||||
|
||||
bool GameObjectModel::intersectRay(G3D::Ray const& ray, float& maxDist, bool stopAtFirstHit, std::set<uint32> const& phases, VMAP::ModelIgnoreFlags ignoreFlags) const
|
||||
bool GameObjectModel::intersectRay(G3D::Ray const& ray, float& maxDist, bool stopAtFirstHit, PhaseShift const& phaseShift, VMAP::ModelIgnoreFlags ignoreFlags) const
|
||||
{
|
||||
if (!isCollisionEnabled() || !owner->IsSpawned())
|
||||
return false;
|
||||
|
||||
if (!owner->IsInPhase(phases))
|
||||
if (!owner->IsInPhase(phaseShift))
|
||||
return false;
|
||||
|
||||
float time = ray.intersectionTime(iBound);
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#include "Define.h"
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
namespace VMAP
|
||||
{
|
||||
@@ -35,6 +34,7 @@ namespace VMAP
|
||||
}
|
||||
|
||||
class GameObject;
|
||||
class PhaseShift;
|
||||
struct GameObjectDisplayInfoEntry;
|
||||
|
||||
class TC_COMMON_API GameObjectModelOwnerBase
|
||||
@@ -42,7 +42,7 @@ class TC_COMMON_API GameObjectModelOwnerBase
|
||||
public:
|
||||
virtual bool IsSpawned() const { return false; }
|
||||
virtual uint32 GetDisplayId() const { return 0; }
|
||||
virtual bool IsInPhase(std::set<uint32> const& /*phases*/) const { return false; }
|
||||
virtual bool IsInPhase(PhaseShift const& /*phaseShift*/) const { return false; }
|
||||
virtual G3D::Vector3 GetPosition() const { return G3D::Vector3::zero(); }
|
||||
virtual float GetOrientation() const { return 0.0f; }
|
||||
virtual float GetScale() const { return 1.0f; }
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
void enableCollision(bool enable) { _collisionEnabled = enable; }
|
||||
bool isCollisionEnabled() const { return _collisionEnabled; }
|
||||
|
||||
bool intersectRay(G3D::Ray const& ray, float& maxDist, bool stopAtFirstHit, std::set<uint32> const& phases, VMAP::ModelIgnoreFlags ignoreFlags) const;
|
||||
bool intersectRay(G3D::Ray const& ray, float& maxDist, bool stopAtFirstHit, PhaseShift const& phaseShift, VMAP::ModelIgnoreFlags ignoreFlags) const;
|
||||
|
||||
static GameObjectModel* Create(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath);
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ namespace Trinity
|
||||
* Note: container cannot be empty
|
||||
*/
|
||||
template<class C, class Fn>
|
||||
auto SelectRandomWeightedContainerElement(C const& container, Fn weightExtractor) -> decltype(std::begin(container))
|
||||
inline auto SelectRandomWeightedContainerElement(C const& container, Fn weightExtractor) -> decltype(std::begin(container))
|
||||
{
|
||||
std::vector<double> weights;
|
||||
weights.reserve(Size(container));
|
||||
@@ -175,7 +175,7 @@ namespace Trinity
|
||||
* @return true if containers have a common element, false otherwise.
|
||||
*/
|
||||
template<class Iterator1, class Iterator2>
|
||||
bool Intersects(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
|
||||
inline bool Intersects(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
|
||||
{
|
||||
while (first1 != last1 && first2 != last2)
|
||||
{
|
||||
@@ -190,6 +190,37 @@ namespace Trinity
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn bool Trinity::Containers::Intersects(Iterator first1, Iterator last1, Iterator first2, Iterator last2, Predicate&& equalPred)
|
||||
*
|
||||
* @brief Checks if two SORTED containers have a common element
|
||||
*
|
||||
* @param first1 Iterator pointing to start of the first container
|
||||
* @param last1 Iterator pointing to end of the first container
|
||||
* @param first2 Iterator pointing to start of the second container
|
||||
* @param last2 Iterator pointing to end of the second container
|
||||
* @param equalPred Additional predicate to exclude elements
|
||||
*
|
||||
* @return true if containers have a common element, false otherwise.
|
||||
*/
|
||||
template<class Iterator1, class Iterator2, class Predicate>
|
||||
inline bool Intersects(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Predicate&& equalPred)
|
||||
{
|
||||
while (first1 != last1 && first2 != last2)
|
||||
{
|
||||
if (*first1 < *first2)
|
||||
++first1;
|
||||
else if (*first2 < *first1)
|
||||
++first2;
|
||||
else if (!equalPred(*first1, *first2))
|
||||
++first1, ++first2;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pointer to mapped value (or the value itself if map stores pointers)
|
||||
*/
|
||||
@@ -201,7 +232,7 @@ namespace Trinity
|
||||
}
|
||||
|
||||
template<class K, class V, template<class, class, class...> class M, class... Rest>
|
||||
void MultimapErasePair(M<K, V, Rest...>& multimap, K const& key, V const& value)
|
||||
inline void MultimapErasePair(M<K, V, Rest...>& multimap, K const& key, V const& value)
|
||||
{
|
||||
auto range = multimap.equal_range(key);
|
||||
for (auto itr = range.first; itr != range.second; )
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef EnumClassFlag_h__
|
||||
#define EnumClassFlag_h__
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
template<typename T>
|
||||
class EnumClassFlag
|
||||
{
|
||||
static_assert(std::is_enum<T>::value, "EnumClassFlag must be used only with enums");
|
||||
|
||||
public:
|
||||
/*implicit*/ EnumClassFlag(T value) : _value(value) { }
|
||||
|
||||
EnumClassFlag& operator&=(EnumClassFlag right)
|
||||
{
|
||||
_value = static_cast<T>(static_cast<std::underlying_type_t<T>>(_value) & static_cast<std::underlying_type_t<T>>(right._value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend EnumClassFlag operator&(EnumClassFlag left, EnumClassFlag right)
|
||||
{
|
||||
return left &= right;
|
||||
}
|
||||
|
||||
EnumClassFlag operator|=(EnumClassFlag right)
|
||||
{
|
||||
_value = static_cast<T>(static_cast<std::underlying_type_t<T>>(_value) | static_cast<std::underlying_type_t<T>>(right._value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend EnumClassFlag operator|(EnumClassFlag left, EnumClassFlag right)
|
||||
{
|
||||
return left |= right;
|
||||
}
|
||||
|
||||
EnumClassFlag operator~() const
|
||||
{
|
||||
return static_cast<T>(~static_cast<std::underlying_type_t<T>>(_value));
|
||||
}
|
||||
|
||||
void RemoveFlag(EnumClassFlag flag)
|
||||
{
|
||||
_value = static_cast<T>(static_cast<std::underlying_type_t<T>>(_value) & ~static_cast<std::underlying_type_t<T>>(flag._value));
|
||||
}
|
||||
|
||||
bool HasFlag(T flag) const
|
||||
{
|
||||
return (static_cast<std::underlying_type_t<T>>(_value) & static_cast<std::underlying_type_t<T>>(flag)) != 0;
|
||||
}
|
||||
|
||||
operator T() const
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
std::underlying_type_t<T> AsUnderlyingType() const
|
||||
{
|
||||
return static_cast<std::underlying_type_t<T>>(_value);
|
||||
}
|
||||
|
||||
private:
|
||||
T _value;
|
||||
};
|
||||
|
||||
#endif // EnumClassFlag_h__
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "Language.h"
|
||||
#include "ObjectDefines.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "SmartAI.h"
|
||||
@@ -1130,7 +1131,12 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
break;
|
||||
|
||||
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
|
||||
(*itr)->SetInPhase(e.action.ingamePhaseId.id, true, e.action.ingamePhaseId.apply == 1);
|
||||
{
|
||||
if (e.action.ingamePhaseId.apply == 1)
|
||||
PhasingHandler::AddPhase(*itr, e.action.ingamePhaseId.id, true);
|
||||
else
|
||||
PhasingHandler::RemovePhase(*itr, e.action.ingamePhaseId.id, true);
|
||||
}
|
||||
|
||||
delete targets;
|
||||
break;
|
||||
@@ -1142,11 +1148,13 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
if (!targets)
|
||||
break;
|
||||
|
||||
std::set<uint32> const& phases = GetPhasesForGroup(e.action.ingamePhaseGroup.groupId);
|
||||
|
||||
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
|
||||
for (auto phase : phases)
|
||||
(*itr)->SetInPhase(phase, true, e.action.ingamePhaseGroup.apply == 1);
|
||||
{
|
||||
if (e.action.ingamePhaseGroup.apply == 1)
|
||||
PhasingHandler::AddPhaseGroup(*itr, e.action.ingamePhaseGroup.groupId, true);
|
||||
else
|
||||
PhasingHandler::RemovePhaseGroup(*itr, e.action.ingamePhaseGroup.groupId, true);
|
||||
}
|
||||
|
||||
delete targets;
|
||||
break;
|
||||
|
||||
@@ -1337,7 +1337,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (phaseGroup && GetPhasesForGroup(phaseGroup).empty())
|
||||
if (phaseGroup && GetPhasesForGroup(phaseGroup))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_SET_INGAME_PHASE_GROUP uses invalid phase group id %u for creature %u, skipped", phaseGroup, e.entryOrGuid);
|
||||
return false;
|
||||
|
||||
@@ -1208,7 +1208,7 @@ LocaleConstant ChatHandler::GetSessionDbcLocale() const
|
||||
return m_session->GetSessionDbcLocale();
|
||||
}
|
||||
|
||||
int ChatHandler::GetSessionDbLocaleIndex() const
|
||||
LocaleConstant ChatHandler::GetSessionDbLocaleIndex() const
|
||||
{
|
||||
return m_session->GetSessionDbLocaleIndex();
|
||||
}
|
||||
@@ -1304,7 +1304,7 @@ LocaleConstant CliHandler::GetSessionDbcLocale() const
|
||||
return sWorld->GetDefaultDbcLocale();
|
||||
}
|
||||
|
||||
int CliHandler::GetSessionDbLocaleIndex() const
|
||||
LocaleConstant CliHandler::GetSessionDbLocaleIndex() const
|
||||
{
|
||||
return sObjectMgr->GetDBCLocaleIndex();
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ class TC_GAME_API ChatHandler
|
||||
virtual std::string GetNameLink() const { return GetNameLink(m_session->GetPlayer()); }
|
||||
virtual bool needReportToTarget(Player* chr) const;
|
||||
virtual LocaleConstant GetSessionDbcLocale() const;
|
||||
virtual int GetSessionDbLocaleIndex() const;
|
||||
virtual LocaleConstant GetSessionDbLocaleIndex() const;
|
||||
|
||||
bool HasLowerSecurity(Player* target, ObjectGuid guid, bool strong = false);
|
||||
bool HasLowerSecurityAccount(WorldSession* target, uint32 account, bool strong = false);
|
||||
@@ -178,7 +178,7 @@ class TC_GAME_API CliHandler : public ChatHandler
|
||||
std::string GetNameLink() const override;
|
||||
bool needReportToTarget(Player* chr) const override;
|
||||
LocaleConstant GetSessionDbcLocale() const override;
|
||||
int GetSessionDbLocaleIndex() const override;
|
||||
LocaleConstant GetSessionDbLocaleIndex() const override;
|
||||
|
||||
private:
|
||||
void* m_callbackArg;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "GameEventMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "Player.h"
|
||||
#include "Pet.h"
|
||||
#include "ReputationMgr.h"
|
||||
@@ -402,7 +403,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const
|
||||
}
|
||||
case CONDITION_PHASEID:
|
||||
{
|
||||
condMeets = object->IsInPhase(ConditionValue1);
|
||||
condMeets = object->GetPhaseShift().HasPhase(ConditionValue1);
|
||||
break;
|
||||
}
|
||||
case CONDITION_TITLE:
|
||||
@@ -430,7 +431,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const
|
||||
}
|
||||
case CONDITION_TERRAIN_SWAP:
|
||||
{
|
||||
condMeets = object->IsInTerrainSwap(ConditionValue1);
|
||||
condMeets = object->GetPhaseShift().HasVisibleMapId(ConditionValue1);
|
||||
break;
|
||||
}
|
||||
case CONDITION_REALM_ACHIEVEMENT:
|
||||
@@ -1040,17 +1041,7 @@ void ConditionMgr::LoadConditions(bool isReload)
|
||||
|
||||
sSpellMgr->UnloadSpellInfoImplicitTargetConditionLists();
|
||||
|
||||
TC_LOG_INFO("misc", "Re-Loading `terrain_phase_info` Table for Conditions!");
|
||||
sObjectMgr->LoadTerrainPhaseInfo();
|
||||
|
||||
TC_LOG_INFO("misc", "Re-Loading `terrain_swap_defaults` Table for Conditions!");
|
||||
sObjectMgr->LoadTerrainSwapDefaults();
|
||||
|
||||
TC_LOG_INFO("misc", "Re-Loading `terrain_worldmap` Table for Conditions!");
|
||||
sObjectMgr->LoadTerrainWorldMaps();
|
||||
|
||||
TC_LOG_INFO("misc", "Re-Loading `phase_area` Table for Conditions!");
|
||||
sObjectMgr->LoadAreaPhases();
|
||||
sObjectMgr->UnloadPhaseConditions();
|
||||
}
|
||||
|
||||
QueryResult result = WorldDatabase.Query("SELECT SourceTypeOrReferenceId, SourceGroup, SourceEntry, SourceId, ElseGroup, ConditionTypeOrReference, ConditionTarget, "
|
||||
@@ -1417,24 +1408,32 @@ bool ConditionMgr::addToPhases(Condition* cond) const
|
||||
{
|
||||
if (!cond->SourceEntry)
|
||||
{
|
||||
PhaseInfo& p = sObjectMgr->GetAreaPhasesForLoading();
|
||||
for (auto phaseItr = p.begin(); phaseItr != p.end(); ++phaseItr)
|
||||
if (PhaseInfoStruct const* phaseInfo = sObjectMgr->GetPhaseInfo(cond->SourceGroup))
|
||||
{
|
||||
for (PhaseInfoStruct& phase : phaseItr->second)
|
||||
bool found = false;
|
||||
for (uint32 areaId : phaseInfo->Areas)
|
||||
{
|
||||
if (phase.Id == cond->SourceGroup)
|
||||
if (std::vector<PhaseAreaInfo>* phases = const_cast<std::vector<PhaseAreaInfo>*>(sObjectMgr->GetPhasesForArea(areaId)))
|
||||
{
|
||||
phase.Conditions.push_back(cond);
|
||||
return true;
|
||||
for (PhaseAreaInfo& phase : *phases)
|
||||
{
|
||||
if (phase.PhaseInfo->Id == cond->SourceGroup)
|
||||
{
|
||||
phase.Conditions.push_back(cond);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (std::vector<PhaseInfoStruct>* phases = sObjectMgr->GetPhasesForAreaForLoading(cond->SourceEntry))
|
||||
else if (std::vector<PhaseAreaInfo>* phases = const_cast<std::vector<PhaseAreaInfo>*>(sObjectMgr->GetPhasesForArea(cond->SourceEntry)))
|
||||
{
|
||||
for (PhaseInfoStruct& phase : *phases)
|
||||
for (PhaseAreaInfo& phase : *phases)
|
||||
{
|
||||
if (phase.Id == cond->SourceGroup)
|
||||
if (phase.PhaseInfo->Id == cond->SourceGroup)
|
||||
{
|
||||
phase.Conditions.push_back(cond);
|
||||
return true;
|
||||
|
||||
@@ -466,6 +466,23 @@ enum MountCapabilityFlags
|
||||
MOUNT_CAPABIILTY_FLAG_IGNORE_RESTRICTIONS = 0x20,
|
||||
};
|
||||
|
||||
enum PhaseEntryFlags : uint16
|
||||
{
|
||||
PHASE_FLAG_NORMAL = 0x08,
|
||||
PHASE_FLAG_COSMETIC = 0x10,
|
||||
PHASE_FLAG_PERSONAL = 0x20
|
||||
};
|
||||
|
||||
// PhaseUseFlags fields in different DBCs
|
||||
enum PhaseUseFlagsValues : uint8
|
||||
{
|
||||
PHASE_USE_FLAGS_NONE = 0x0,
|
||||
PHASE_USE_FLAGS_ALWAYS_VISIBLE = 0x1,
|
||||
PHASE_USE_FLAGS_INVERSE = 0x2,
|
||||
|
||||
PHASE_USE_FLAGS_ALL = PHASE_USE_FLAGS_ALWAYS_VISIBLE | PHASE_USE_FLAGS_INVERSE
|
||||
};
|
||||
|
||||
enum SkillRaceClassInfoFlags
|
||||
{
|
||||
SKILL_FLAG_NO_SKILLUP_MESSAGE = 0x2,
|
||||
|
||||
@@ -558,7 +558,7 @@ void LoadDBCStores(const std::string& dataPath)
|
||||
for (uint32 i = 0; i < sPhaseGroupStore.GetNumRows(); ++i)
|
||||
if (PhaseGroupEntry const* group = sPhaseGroupStore.LookupEntry(i))
|
||||
if (PhaseEntry const* phase = sPhaseStore.LookupEntry(group->PhaseId))
|
||||
sPhasesByGroup[group->GroupId].insert(phase->ID);
|
||||
sPhasesByGroup[group->GroupId].push_back(phase->ID);
|
||||
|
||||
LoadDBC(availableDbcLocales, bad_dbc_files, sPowerDisplayStore, dbcPath, "PowerDisplay.dbc");
|
||||
|
||||
@@ -1360,9 +1360,9 @@ SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, u
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::set<uint32> const& GetPhasesForGroup(uint32 group)
|
||||
std::vector<uint32> const* GetPhasesForGroup(uint32 group)
|
||||
{
|
||||
return sPhasesByGroup[group];
|
||||
return &sPhasesByGroup[group];
|
||||
}
|
||||
|
||||
ResponseCodes ValidateName(std::wstring const& name, LocaleConstant locale)
|
||||
|
||||
@@ -81,7 +81,7 @@ TC_GAME_API LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty diffic
|
||||
|
||||
uint32 GetDefaultMapLight(uint32 mapId);
|
||||
|
||||
TC_GAME_API std::set<uint32> const& GetPhasesForGroup(uint32 group);
|
||||
TC_GAME_API std::vector<uint32> const* GetPhasesForGroup(uint32 group);
|
||||
|
||||
typedef std::unordered_multimap<uint32, SkillRaceClassInfoEntry const*> SkillRaceClassInfoMap;
|
||||
typedef std::pair<SkillRaceClassInfoMap::iterator, SkillRaceClassInfoMap::iterator> SkillRaceClassInfoBounds;
|
||||
@@ -254,7 +254,7 @@ TC_GAME_API extern DBCStorage <UnitPowerBarEntry> sUnitPowerBarStore;
|
||||
TC_GAME_API extern DBCStorage <VehicleEntry> sVehicleStore;
|
||||
TC_GAME_API extern DBCStorage <VehicleSeatEntry> sVehicleSeatStore;
|
||||
TC_GAME_API extern DBCStorage <WMOAreaTableEntry> sWMOAreaTableStore;
|
||||
//TC_GAME_API extern DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore; -- use Zone2MapCoordinates and Map2ZoneCoordinates
|
||||
TC_GAME_API extern DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore;
|
||||
TC_GAME_API extern DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore;
|
||||
TC_GAME_API extern DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore;
|
||||
|
||||
|
||||
@@ -1601,7 +1601,7 @@ struct PhaseEntry
|
||||
{
|
||||
uint32 ID; // 0
|
||||
char* Name; // 1
|
||||
uint32 flag; // 2
|
||||
uint32 Flags; // 2
|
||||
};
|
||||
|
||||
struct PhaseGroupEntry
|
||||
@@ -2734,5 +2734,5 @@ typedef std::vector<TaxiPathNodeList> TaxiPathNodesByPath;
|
||||
#define TaxiMaskSize 114
|
||||
typedef uint8 TaxiMask[TaxiMaskSize];
|
||||
|
||||
typedef std::unordered_map<uint32, std::set<uint32>> PhaseGroupContainer;
|
||||
typedef std::unordered_map<uint32, std::vector<uint32>> PhaseGroupContainer;
|
||||
#endif
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "ObjectAccessor.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "Unit.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "Log.h"
|
||||
@@ -78,7 +79,7 @@ bool AreaTrigger::CreateAreaTrigger(uint32 guidlow, uint32 triggerEntry, Unit* c
|
||||
SetFloatValue(AREATRIGGER_FINAL_POS + 1, pos.GetPositionY());
|
||||
SetFloatValue(AREATRIGGER_FINAL_POS + 2, pos.GetPositionZ());
|
||||
|
||||
CopyPhaseFrom(caster);
|
||||
PhasingHandler::InheritPhaseShift(this, caster);
|
||||
|
||||
if (!GetMap()->AddToMap(this))
|
||||
return false;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "Player.h"
|
||||
#include "UpdateMask.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "World.h"
|
||||
|
||||
@@ -86,7 +87,7 @@ bool Corpse::Create(ObjectGuid::LowType guidlow, Player* owner)
|
||||
|
||||
_cellCoord = Trinity::ComputeCellCoord(GetPositionX(), GetPositionY());
|
||||
|
||||
CopyPhaseFrom(owner);
|
||||
PhasingHandler::InheritPhaseShift(this, owner);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -116,12 +117,12 @@ void Corpse::SaveToDB()
|
||||
stmt->setUInt32(index++, GetInstanceId()); // instanceId
|
||||
trans->Append(stmt);
|
||||
|
||||
for (uint32 phaseId : GetPhases())
|
||||
for (PhaseShift::PhaseRef const& phase : GetPhaseShift().GetPhases())
|
||||
{
|
||||
index = 0;
|
||||
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CORPSE_PHASES);
|
||||
stmt->setUInt32(index++, GetOwnerGUID().GetCounter()); // OwnerGuid
|
||||
stmt->setUInt32(index++, phaseId); // PhaseId
|
||||
stmt->setUInt32(index++, phase.Id); // PhaseId
|
||||
trans->Append(stmt);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "LootMgr.h"
|
||||
#include "MoveSpline.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "Player.h"
|
||||
#include "PoolMgr.h"
|
||||
#include "QuestDef.h"
|
||||
@@ -888,12 +889,11 @@ bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 /*phaseMask*
|
||||
ASSERT(map);
|
||||
SetMap(map);
|
||||
|
||||
if (data && data->phaseid)
|
||||
SetInPhase(data->phaseid, false, true);
|
||||
|
||||
if (data && data->phaseGroup)
|
||||
for (auto ph : GetPhasesForGroup(data->phaseGroup))
|
||||
SetInPhase(ph, false, true);
|
||||
if (data)
|
||||
{
|
||||
PhasingHandler::InitDbPhaseShift(GetPhaseShift(), data->phaseUseFlags, data->phaseId, data->phaseGroup);
|
||||
PhasingHandler::InitDbVisibleMapId(GetPhaseShift(), data->terrainSwapMap);
|
||||
}
|
||||
|
||||
CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(entry);
|
||||
if (!cinfo)
|
||||
@@ -1157,7 +1157,7 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
|
||||
data.unit_flags = unit_flags;
|
||||
data.dynamicflags = dynamicflags;
|
||||
|
||||
data.phaseid = GetDBPhase() > 0 ? GetDBPhase() : 0;
|
||||
data.phaseId = GetDBPhase() > 0 ? GetDBPhase() : 0;
|
||||
data.phaseGroup = GetDBPhase() < 0 ? abs(GetDBPhase()) : 0;
|
||||
|
||||
// update in DB
|
||||
@@ -1176,7 +1176,7 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
|
||||
stmt->setUInt16(index++, uint16(mapid));
|
||||
stmt->setUInt8(index++, spawnMask);
|
||||
stmt->setUInt32(index++, GetPhaseMask());
|
||||
stmt->setUInt32(index++, data.phaseid);
|
||||
stmt->setUInt32(index++, data.phaseId);
|
||||
stmt->setUInt32(index++, data.phaseGroup);
|
||||
stmt->setUInt32(index++, displayId);
|
||||
stmt->setInt32(index++, int32(GetCurrentEquipmentId()));
|
||||
@@ -1437,7 +1437,7 @@ bool Creature::LoadCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool ad
|
||||
m_deathState = DEAD;
|
||||
if (CanFly())
|
||||
{
|
||||
float tz = map->GetHeight(GetPhases(), data->posX, data->posY, data->posZ, true, MAX_FALL_DISTANCE);
|
||||
float tz = map->GetHeight(GetPhaseShift(), data->posX, data->posY, data->posZ, true, MAX_FALL_DISTANCE);
|
||||
if (data->posZ - tz > 0.1f && Trinity::IsValidMapCoord(tz))
|
||||
Relocate(data->posX, data->posY, tz);
|
||||
}
|
||||
@@ -2701,7 +2701,7 @@ void Creature::UpdateMovementFlags()
|
||||
return;
|
||||
|
||||
// Set the movement flags if the creature is in that mode. (Only fly if actually in air, only swim if in water, etc)
|
||||
float ground = GetFloorZ();
|
||||
float ground = GetMap()->GetHeight(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZMinusOffset());
|
||||
|
||||
bool isInAir = (G3D::fuzzyGt(GetPositionZMinusOffset(), ground + 0.05f) || G3D::fuzzyLt(GetPositionZMinusOffset(), ground - 0.05f)); // Can be underground too, prevent the falling
|
||||
|
||||
|
||||
@@ -274,7 +274,8 @@ struct CreatureData
|
||||
CreatureData() : id(0), mapid(0), phaseMask(0), displayid(0), equipmentId(0),
|
||||
posX(0.0f), posY(0.0f), posZ(0.0f), orientation(0.0f), spawntimesecs(0),
|
||||
spawndist(0.0f), currentwaypoint(0), curhealth(0), curmana(0), movementType(0),
|
||||
spawnMask(0), npcflag(0), unit_flags(0), dynamicflags(0), phaseid(0), phaseGroup(0), ScriptId(0), dbData(true) { }
|
||||
spawnMask(0), npcflag(0), unit_flags(0), dynamicflags(0), phaseUseFlags(0),
|
||||
phaseId(0), phaseGroup(0), terrainSwapMap(-1), ScriptId(0), dbData(true) { }
|
||||
uint32 id; // entry in creature_template
|
||||
uint16 mapid;
|
||||
uint32 phaseMask;
|
||||
@@ -294,8 +295,10 @@ struct CreatureData
|
||||
uint32 npcflag;
|
||||
uint32 unit_flags; // enum UnitFlags mask values
|
||||
uint32 dynamicflags;
|
||||
uint32 phaseid;
|
||||
uint8 phaseUseFlags;
|
||||
uint32 phaseId;
|
||||
uint32 phaseGroup;
|
||||
int32 terrainSwapMap;
|
||||
uint32 ScriptId;
|
||||
bool dbData;
|
||||
};
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "GroupMgr.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "OutdoorPvPMgr.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "PoolMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellMgr.h"
|
||||
@@ -907,15 +908,8 @@ bool GameObject::LoadGameObjectFromDB(ObjectGuid::LowType spawnId, Map* map, boo
|
||||
if (!Create(map->GenerateLowGuid<HighGuid::GameObject>(), entry, map, phaseMask, pos, data->rotation, animprogress, go_state, artKit))
|
||||
return false;
|
||||
|
||||
if (data->phaseid)
|
||||
SetInPhase(data->phaseid, false, true);
|
||||
|
||||
if (data->phaseGroup)
|
||||
{
|
||||
// Set the gameobject in all the phases of the phasegroup
|
||||
for (auto ph : GetPhasesForGroup(data->phaseGroup))
|
||||
SetInPhase(ph, false, true);
|
||||
}
|
||||
PhasingHandler::InitDbPhaseShift(GetPhaseShift(), data->phaseUseFlags, data->phaseId, data->phaseGroup);
|
||||
PhasingHandler::InitDbVisibleMapId(GetPhaseShift(), data->terrainSwapMap);
|
||||
|
||||
if (data->spawntimesecs >= 0)
|
||||
{
|
||||
@@ -2476,7 +2470,6 @@ public:
|
||||
|
||||
virtual bool IsSpawned() const override { return _owner->isSpawned(); }
|
||||
virtual uint32 GetDisplayId() const override { return _owner->GetDisplayId(); }
|
||||
virtual bool IsInPhase(std::set<uint32> const& phases) const override { return _owner->IsInPhase(phases); }
|
||||
virtual G3D::Vector3 GetPosition() const override { return G3D::Vector3(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ()); }
|
||||
virtual float GetOrientation() const override { return _owner->GetOrientation(); }
|
||||
virtual float GetScale() const override { return _owner->GetObjectScale(); }
|
||||
|
||||
@@ -644,7 +644,8 @@ enum GOState
|
||||
struct GameObjectData
|
||||
{
|
||||
explicit GameObjectData() : id(0), mapid(0), phaseMask(0), posX(0.0f), posY(0.0f), posZ(0.0f), orientation(0.0f), spawntimesecs(0),
|
||||
animprogress(0), go_state(GO_STATE_ACTIVE), spawnMask(0), artKit(0), phaseid(0), phaseGroup(0), ScriptId(0), dbData(true) { }
|
||||
animprogress(0), go_state(GO_STATE_ACTIVE), spawnMask(0), artKit(0), phaseUseFlags(0), phaseId(0),
|
||||
phaseGroup(0), terrainSwapMap(-1), ScriptId(0), dbData(true) { }
|
||||
uint32 id; // entry in gamobject_template
|
||||
uint16 mapid;
|
||||
uint32 phaseMask;
|
||||
@@ -658,8 +659,10 @@ struct GameObjectData
|
||||
GOState go_state;
|
||||
uint8 spawnMask;
|
||||
uint8 artKit;
|
||||
uint32 phaseid;
|
||||
uint8 phaseUseFlags;
|
||||
uint32 phaseId;
|
||||
uint32 phaseGroup;
|
||||
int32 terrainSwapMap;
|
||||
uint32 ScriptId;
|
||||
bool dbData;
|
||||
};
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "TemporarySummon.h"
|
||||
#include "Totem.h"
|
||||
#include "OutdoorPvPMgr.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "MovementPacketBuilder.h"
|
||||
#include "DynamicTree.h"
|
||||
#include "Unit.h"
|
||||
@@ -1446,7 +1447,7 @@ bool WorldObject::IsWithinLOS(float ox, float oy, float oz, LineOfSightChecks ch
|
||||
else
|
||||
GetHitSpherePointFor({ ox, oy, oz }, x, y, z);
|
||||
|
||||
return GetMap()->isInLineOfSight(x, y, z + 2.0f, ox, oy, oz + 2.0f, GetPhases(), checks, ignoreFlags);
|
||||
return GetMap()->isInLineOfSight(GetPhaseShift(), x, y, z + 2.0f, ox, oy, oz + 2.0f, checks, ignoreFlags);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1621,7 +1622,7 @@ Position WorldObject::GetRandomPoint(const Position &srcPos, float distance) con
|
||||
|
||||
void WorldObject::UpdateGroundPositionZ(float x, float y, float &z) const
|
||||
{
|
||||
float new_z = GetMap()->GetHeight(GetPhases(), x, y, z + 2.0f, true);
|
||||
float new_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z + 2.0f, true);
|
||||
if (new_z > INVALID_HEIGHT)
|
||||
z = new_z + 0.05f; // just to be sure that we are not a few pixel under the surface
|
||||
}
|
||||
@@ -1643,8 +1644,8 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
|
||||
bool canSwim = ToCreature()->CanSwim();
|
||||
float ground_z = z;
|
||||
float max_z = canSwim
|
||||
? GetMap()->GetWaterOrGroundLevel(GetPhases(), x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK))
|
||||
: ((ground_z = GetMap()->GetHeight(GetPhases(), x, y, z, true)));
|
||||
? GetMap()->GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK))
|
||||
: ((ground_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z, true)));
|
||||
if (max_z > INVALID_HEIGHT)
|
||||
{
|
||||
if (z > max_z)
|
||||
@@ -1655,7 +1656,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
|
||||
}
|
||||
else
|
||||
{
|
||||
float ground_z = GetMap()->GetHeight(GetPhases(), x, y, z, true);
|
||||
float ground_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z, true);
|
||||
if (z < ground_z)
|
||||
z = ground_z;
|
||||
}
|
||||
@@ -1667,7 +1668,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
|
||||
if (!ToPlayer()->CanFly())
|
||||
{
|
||||
float ground_z = z;
|
||||
float max_z = GetMap()->GetWaterOrGroundLevel(GetPhases(), x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK));
|
||||
float max_z = GetMap()->GetWaterOrGroundLevel(GetPhaseShift(), x, y, z, &ground_z, !ToUnit()->HasAuraType(SPELL_AURA_WATER_WALK));
|
||||
if (max_z > INVALID_HEIGHT)
|
||||
{
|
||||
if (z > max_z)
|
||||
@@ -1678,7 +1679,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
|
||||
}
|
||||
else
|
||||
{
|
||||
float ground_z = GetMap()->GetHeight(GetPhases(), x, y, z, true);
|
||||
float ground_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z, true);
|
||||
if (z < ground_z)
|
||||
z = ground_z;
|
||||
}
|
||||
@@ -1686,7 +1687,7 @@ void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
|
||||
}
|
||||
default:
|
||||
{
|
||||
float ground_z = GetMap()->GetHeight(GetPhases(), x, y, z, true);
|
||||
float ground_z = GetMap()->GetHeight(GetPhaseShift(), x, y, z, true);
|
||||
if (ground_z > INVALID_HEIGHT)
|
||||
z = ground_z;
|
||||
break;
|
||||
@@ -2100,7 +2101,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
|
||||
}
|
||||
|
||||
// Set the summon to the summoner's phase
|
||||
summon->CopyPhaseFrom(summoner);
|
||||
PhasingHandler::InheritPhaseShift(summon, summoner);
|
||||
|
||||
summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId);
|
||||
|
||||
@@ -2204,7 +2205,7 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, Position const& pos, G3D
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
go->CopyPhaseFrom(this);
|
||||
PhasingHandler::InheritPhaseShift(go, this);
|
||||
|
||||
go->SetRespawnTime(respawnTime);
|
||||
if (GetTypeId() == TYPEID_PLAYER || (GetTypeId() == TYPEID_UNIT && summonType == GO_SUMMON_TIMED_OR_CORPSE_DESPAWN)) //not sure how to handle this
|
||||
@@ -2430,8 +2431,8 @@ void WorldObject::MovePosition(Position &pos, float dist, float angle)
|
||||
return;
|
||||
}
|
||||
|
||||
ground = GetMap()->GetHeight(GetPhases(), destx, desty, MAX_HEIGHT, true);
|
||||
floor = GetMap()->GetHeight(GetPhases(), destx, desty, pos.m_positionZ, true);
|
||||
ground = GetMap()->GetHeight(GetPhaseShift(), destx, desty, MAX_HEIGHT, true);
|
||||
floor = GetMap()->GetHeight(GetPhaseShift(), destx, desty, pos.m_positionZ, true);
|
||||
destz = std::fabs(ground - pos.m_positionZ) <= std::fabs(floor - pos.m_positionZ) ? ground : floor;
|
||||
|
||||
float step = dist/10.0f;
|
||||
@@ -2443,8 +2444,8 @@ void WorldObject::MovePosition(Position &pos, float dist, float angle)
|
||||
{
|
||||
destx -= step * std::cos(angle);
|
||||
desty -= step * std::sin(angle);
|
||||
ground = GetMap()->GetHeight(GetPhases(), destx, desty, MAX_HEIGHT, true);
|
||||
floor = GetMap()->GetHeight(GetPhases(), destx, desty, pos.m_positionZ, true);
|
||||
ground = GetMap()->GetHeight(GetPhaseShift(), destx, desty, MAX_HEIGHT, true);
|
||||
floor = GetMap()->GetHeight(GetPhaseShift(), destx, desty, pos.m_positionZ, true);
|
||||
destz = std::fabs(ground - pos.m_positionZ) <= std::fabs(floor - pos.m_positionZ) ? ground : floor;
|
||||
}
|
||||
// we have correct destz now
|
||||
@@ -2464,8 +2465,8 @@ void WorldObject::MovePosition(Position &pos, float dist, float angle)
|
||||
// @todo: replace with WorldObject::UpdateAllowedPositionZ
|
||||
float NormalizeZforCollision(WorldObject* obj, float x, float y, float z)
|
||||
{
|
||||
float ground = obj->GetMap()->GetHeight(obj->GetPhases(), x, y, MAX_HEIGHT, true);
|
||||
float floor = obj->GetMap()->GetHeight(obj->GetPhases(), x, y, z + 2.0f, true);
|
||||
float ground = obj->GetMap()->GetHeight(obj->GetPhaseShift(), x, y, MAX_HEIGHT, true);
|
||||
float floor = obj->GetMap()->GetHeight(obj->GetPhaseShift(), x, y, z + 2.0f, true);
|
||||
float helper = std::fabs(ground - z) <= std::fabs(floor - z) ? ground : floor;
|
||||
if (z > helper) // must be above ground
|
||||
{
|
||||
@@ -2514,7 +2515,7 @@ void WorldObject::MovePositionToFirstCollision(Position &pos, float dist, float
|
||||
}
|
||||
|
||||
// check dynamic collision
|
||||
col = GetMap()->getObjectHitPos(GetPhases(), pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f);
|
||||
col = GetMap()->getObjectHitPos(GetPhaseShift(), pos.m_positionX, pos.m_positionY, pos.m_positionZ + 0.5f, destx, desty, destz + 0.5f, destx, desty, destz, -0.5f);
|
||||
|
||||
// Collided with a gameobject
|
||||
if (col)
|
||||
@@ -2557,165 +2558,6 @@ void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update)
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
bool WorldObject::HasInPhaseList(uint32 phase)
|
||||
{
|
||||
return _phases.find(phase) != _phases.end();
|
||||
}
|
||||
|
||||
// Updates Area based phases, does not remove phases from auras
|
||||
// Phases from gm commands are not taken into calculations, they can be lost!!
|
||||
void WorldObject::UpdateAreaPhase()
|
||||
{
|
||||
bool updateNeeded = false;
|
||||
PhaseInfo const& phases = sObjectMgr->GetAreaPhases();
|
||||
for (PhaseInfo::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
|
||||
{
|
||||
uint32 areaId = itr->first;
|
||||
for (PhaseInfoStruct const& phase : itr->second)
|
||||
{
|
||||
if (areaId == GetAreaId())
|
||||
{
|
||||
if (sConditionMgr->IsObjectMeetToConditions(this, phase.Conditions))
|
||||
{
|
||||
// add new phase if condition passed, true if it wasnt added before
|
||||
bool up = SetInPhase(phase.Id, false, true);
|
||||
if (!updateNeeded && up)
|
||||
updateNeeded = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// condition failed, remove phase, true if there was something removed
|
||||
bool up = SetInPhase(phase.Id, false, false);
|
||||
if (!updateNeeded && up)
|
||||
updateNeeded = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// not in area, remove phase, true if there was something removed
|
||||
bool up = SetInPhase(phase.Id, false, false);
|
||||
if (!updateNeeded && up)
|
||||
updateNeeded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// do not remove a phase if it would be removed by an area but we have the same phase from an aura
|
||||
if (Unit* unit = ToUnit())
|
||||
{
|
||||
Unit::AuraEffectList const& auraPhaseList = unit->GetAuraEffectsByType(SPELL_AURA_PHASE);
|
||||
for (Unit::AuraEffectList::const_iterator itr = auraPhaseList.begin(); itr != auraPhaseList.end(); ++itr)
|
||||
{
|
||||
uint32 phase = uint32((*itr)->GetMiscValueB());
|
||||
bool up = SetInPhase(phase, false, true);
|
||||
if (!updateNeeded && up)
|
||||
updateNeeded = true;
|
||||
}
|
||||
Unit::AuraEffectList const& auraPhaseGroupList = unit->GetAuraEffectsByType(SPELL_AURA_PHASE_GROUP);
|
||||
for (Unit::AuraEffectList::const_iterator itr = auraPhaseGroupList.begin(); itr != auraPhaseGroupList.end(); ++itr)
|
||||
{
|
||||
bool up = false;
|
||||
uint32 phaseGroup = uint32((*itr)->GetMiscValueB());
|
||||
std::set<uint32> const& phases = GetPhasesForGroup(phaseGroup);
|
||||
for (uint32 phase : phases)
|
||||
up = SetInPhase(phase, false, true);
|
||||
if (!updateNeeded && up)
|
||||
updateNeeded = true;
|
||||
}
|
||||
}
|
||||
|
||||
// only update visibility and send packets if there was a change in the phase list
|
||||
if (updateNeeded && GetTypeId() == TYPEID_PLAYER && IsInWorld())
|
||||
ToPlayer()->GetSession()->SendSetPhaseShift(GetPhases(), GetTerrainSwaps(), GetWorldMapAreaSwaps());
|
||||
|
||||
// only update visibilty once, to prevent objects appearing for a moment while adding in multiple phases
|
||||
if (updateNeeded && IsInWorld())
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
bool WorldObject::SetInPhase(uint32 id, bool update, bool apply)
|
||||
{
|
||||
if (id)
|
||||
{
|
||||
if (apply)
|
||||
{
|
||||
if (HasInPhaseList(id)) // do not run the updates if we are already in this phase
|
||||
return false;
|
||||
|
||||
_phases.insert(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if area phase passes the condition we should not remove it (ie: if remove called from aura remove)
|
||||
// this however breaks the .mod phase command, you wont be able to remove any area based phases with it
|
||||
PhaseInfo const& phases = sObjectMgr->GetAreaPhases();
|
||||
for (PhaseInfo::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
|
||||
if (itr->first == GetAreaId() || itr->first == GetZoneId())
|
||||
for (PhaseInfoStruct const& phase : itr->second)
|
||||
if (id == phase.Id)
|
||||
if (sConditionMgr->IsObjectMeetToConditions(this, phase.Conditions))
|
||||
return false;
|
||||
|
||||
if (!HasInPhaseList(id)) // do not run the updates if we are not in this phase
|
||||
return false;
|
||||
|
||||
_phases.erase(id);
|
||||
}
|
||||
}
|
||||
|
||||
RebuildTerrainSwaps();
|
||||
|
||||
if (update && IsInWorld())
|
||||
UpdateObjectVisibility();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WorldObject::CopyPhaseFrom(WorldObject* obj, bool update)
|
||||
{
|
||||
if (!obj)
|
||||
return;
|
||||
|
||||
for (uint32 phase : obj->GetPhases())
|
||||
SetInPhase(phase, false, true);
|
||||
|
||||
if (update && IsInWorld())
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
void WorldObject::ClearPhases(bool update)
|
||||
{
|
||||
_phases.clear();
|
||||
|
||||
RebuildTerrainSwaps();
|
||||
|
||||
if (update && IsInWorld())
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
bool WorldObject::IsInPhase(std::set<uint32> const& phases) const
|
||||
{
|
||||
// PhaseId 169 is the default fallback phase
|
||||
if (_phases.empty() && phases.empty())
|
||||
return true;
|
||||
|
||||
if (_phases.empty() && phases.count(DEFAULT_PHASE) > 0)
|
||||
return true;
|
||||
|
||||
if (phases.empty() && _phases.count(DEFAULT_PHASE) > 0)
|
||||
return true;
|
||||
|
||||
return Trinity::Containers::Intersects(_phases.begin(), _phases.end(), phases.begin(), phases.end());
|
||||
}
|
||||
|
||||
bool WorldObject::IsInPhase(WorldObject const* obj) const
|
||||
{
|
||||
if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->IsGameMaster())
|
||||
return true;
|
||||
|
||||
return IsInPhase(obj->GetPhases());
|
||||
}
|
||||
|
||||
void WorldObject::PlayDistanceSound(uint32 sound_id, Player* target /*= NULL*/)
|
||||
{
|
||||
WorldPacket data(SMSG_PLAY_OBJECT_SOUND, 4 + 8);
|
||||
@@ -2882,7 +2724,7 @@ float WorldObject::GetFloorZ() const
|
||||
{
|
||||
if (!IsInWorld())
|
||||
return m_staticFloorZ;
|
||||
return std::max<float>(m_staticFloorZ, GetMap()->GetGameObjectFloor(GetPhases(), GetPositionX(), GetPositionY(), GetPositionZ()));
|
||||
return std::max<float>(m_staticFloorZ, GetMap()->GetGameObjectFloor(GetPhaseShift(), GetPositionX(), GetPositionY(), GetPositionZ()));
|
||||
}
|
||||
|
||||
template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::list<GameObject*>&, uint32, float) const;
|
||||
@@ -2944,63 +2786,3 @@ void WorldObject::SetMeleeAnimKitId(uint16 animKitId)
|
||||
data << uint16(animKitId);
|
||||
SendMessageToSet(&data, true);
|
||||
}
|
||||
|
||||
void WorldObject::RebuildTerrainSwaps()
|
||||
{
|
||||
// Clear all terrain swaps, will be rebuilt below
|
||||
// Reason for this is, multiple phases can have the same terrain swap, we should not remove the swap if another phase still use it
|
||||
_terrainSwaps.clear();
|
||||
|
||||
// Check all applied phases for terrain swap and add it only once
|
||||
for (uint32 phaseId : _phases)
|
||||
{
|
||||
if (std::vector<uint32> const* swaps = sObjectMgr->GetPhaseTerrainSwaps(phaseId))
|
||||
{
|
||||
for (uint32 const& swap : *swaps)
|
||||
{
|
||||
// only add terrain swaps for current map
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(swap);
|
||||
if (!mapEntry || mapEntry->rootPhaseMap != int32(GetMapId()))
|
||||
continue;
|
||||
|
||||
if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap, this))
|
||||
_terrainSwaps.insert(swap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get default terrain swaps, only for current map always
|
||||
if (std::vector<uint32> const* mapSwaps = sObjectMgr->GetDefaultTerrainSwaps(GetMapId()))
|
||||
for (uint32 const& swap : *mapSwaps)
|
||||
if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap, this))
|
||||
_terrainSwaps.insert(swap);
|
||||
|
||||
// online players have a game client with world map display
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
RebuildWorldMapAreaSwaps();
|
||||
}
|
||||
|
||||
void WorldObject::RebuildWorldMapAreaSwaps()
|
||||
{
|
||||
// Clear all world map area swaps, will be rebuilt below
|
||||
_worldMapAreaSwaps.clear();
|
||||
|
||||
// get ALL default terrain swaps, if we are using it (condition is true)
|
||||
// send the worldmaparea for it, to see swapped worldmaparea in client from other maps too, not just from our current
|
||||
TerrainPhaseInfo const& defaults = sObjectMgr->GetDefaultTerrainSwapStore();
|
||||
for (TerrainPhaseInfo::const_iterator itr = defaults.begin(); itr != defaults.end(); ++itr)
|
||||
for (uint32 const& swap : itr->second)
|
||||
if (std::vector<uint32> const* uiMapSwaps = sObjectMgr->GetTerrainWorldMaps(swap))
|
||||
if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap, this))
|
||||
for (uint32 worldMapAreaId : *uiMapSwaps)
|
||||
_worldMapAreaSwaps.insert(worldMapAreaId);
|
||||
|
||||
// Check all applied phases for world map area swaps
|
||||
for (uint32 phaseId : _phases)
|
||||
if (std::vector<uint32> const* swaps = sObjectMgr->GetPhaseTerrainSwaps(phaseId))
|
||||
for (uint32 const& swap : *swaps)
|
||||
if (std::vector<uint32> const* uiMapSwaps = sObjectMgr->GetTerrainWorldMaps(swap))
|
||||
if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap, this))
|
||||
for (uint32 worldMapAreaId : *uiMapSwaps)
|
||||
_worldMapAreaSwaps.insert(worldMapAreaId);
|
||||
}
|
||||
@@ -24,10 +24,10 @@
|
||||
#include "UpdateMask.h"
|
||||
#include "GridReference.h"
|
||||
#include "ObjectDefines.h"
|
||||
#include "PhaseShift.h"
|
||||
#include "Map.h"
|
||||
#include "ModelIgnoreFlags.h"
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
@@ -48,8 +48,6 @@
|
||||
#define NOMINAL_MELEE_RANGE 5.0f
|
||||
#define MELEE_RANGE (NOMINAL_MELEE_RANGE - MIN_MELEE_REACH * 2) //center to center for players
|
||||
|
||||
#define DEFAULT_PHASE 169
|
||||
|
||||
enum TempSummonType
|
||||
{
|
||||
TEMPSUMMON_TIMED_OR_DEAD_DESPAWN = 1, // despawns after a specified time OR when the creature disappears
|
||||
@@ -485,21 +483,16 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
|
||||
uint32 GetInstanceId() const { return m_InstanceId; }
|
||||
|
||||
virtual void SetPhaseMask(uint32 newPhaseMask, bool update);
|
||||
virtual bool SetInPhase(uint32 id, bool update, bool apply);
|
||||
void CopyPhaseFrom(WorldObject* obj, bool update = false);
|
||||
void UpdateAreaPhase();
|
||||
void ClearPhases(bool update = false);
|
||||
void RebuildTerrainSwaps();
|
||||
void RebuildWorldMapAreaSwaps();
|
||||
bool HasInPhaseList(uint32 phase);
|
||||
bool IsInPhase(WorldObject const* obj) const
|
||||
{
|
||||
return GetPhaseShift().CanSee(obj->GetPhaseShift());
|
||||
}
|
||||
|
||||
PhaseShift& GetPhaseShift() { return _phaseShift; }
|
||||
PhaseShift const& GetPhaseShift() const { return _phaseShift; }
|
||||
PhaseShift& GetSuppressedPhaseShift() { return _suppressedPhaseShift; }
|
||||
PhaseShift const& GetSuppressedPhaseShift() const { return _suppressedPhaseShift; }
|
||||
uint32 GetPhaseMask() const { return m_phaseMask; }
|
||||
bool IsInPhase(uint32 phase) const { return _phases.find(phase) != _phases.end(); }
|
||||
bool IsInPhase(std::set<uint32> const& phases) const;
|
||||
bool IsInPhase(WorldObject const* obj) const;
|
||||
bool IsInTerrainSwap(uint32 terrainSwap) const { return _terrainSwaps.find(terrainSwap) != _terrainSwaps.end(); }
|
||||
std::set<uint32> const& GetPhases() const { return _phases; }
|
||||
std::set<uint32> const& GetTerrainSwaps() const { return _terrainSwaps; }
|
||||
std::set<uint32> const& GetWorldMapAreaSwaps() const { return _worldMapAreaSwaps; }
|
||||
int32 GetDBPhase() { return _dbPhase; }
|
||||
|
||||
// if negative it is used as PhaseGroupId
|
||||
@@ -699,9 +692,8 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
|
||||
//uint32 m_mapId; // object at map with map_id
|
||||
uint32 m_InstanceId; // in map copy with instance id
|
||||
uint32 m_phaseMask; // in area phase state
|
||||
std::set<uint32> _phases;
|
||||
std::set<uint32> _terrainSwaps;
|
||||
std::set<uint32> _worldMapAreaSwaps;
|
||||
PhaseShift _phaseShift;
|
||||
PhaseShift _suppressedPhaseShift; // contains phases for current area but not applied due to conditions
|
||||
int32 _dbPhase;
|
||||
|
||||
uint16 m_notifyflags;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "Log.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "Pet.h"
|
||||
#include "Formulas.h"
|
||||
@@ -179,7 +180,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
|
||||
if (!Create(guid, map, petEntry, petId))
|
||||
return false;
|
||||
|
||||
CopyPhaseFrom(owner);
|
||||
PhasingHandler::InheritPhaseShift(this, owner);
|
||||
|
||||
setPetType(petType);
|
||||
SetFaction(owner->GetFaction());
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
#include "OutdoorPvP.h"
|
||||
#include "OutdoorPvPMgr.h"
|
||||
#include "Pet.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "QueryCallback.h"
|
||||
#include "QuestDef.h"
|
||||
#include "ReputationMgr.h"
|
||||
@@ -2624,10 +2625,13 @@ void Player::SetGameMaster(bool on)
|
||||
getHostileRefManager().setOnlineOfflineState(false);
|
||||
CombatStopWithPets();
|
||||
|
||||
PhasingHandler::SetAlwaysVisible(GetPhaseShift(), true);
|
||||
m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GM, GetSession()->GetSecurity());
|
||||
}
|
||||
else
|
||||
{
|
||||
PhasingHandler::SetAlwaysVisible(GetPhaseShift(), false);
|
||||
|
||||
m_ExtraFlags &= ~ PLAYER_EXTRA_GM_ON;
|
||||
SetFactionForRace(getRace());
|
||||
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM);
|
||||
@@ -7380,7 +7384,7 @@ void Player::UpdateArea(uint32 newArea)
|
||||
UpdatePvPState(true);
|
||||
|
||||
UpdateAreaDependentAuras(newArea);
|
||||
UpdateAreaPhase();
|
||||
PhasingHandler::OnAreaChange(this);
|
||||
|
||||
// previously this was in UpdateZone (but after UpdateArea) so nothing will break
|
||||
pvpInfo.IsInNoPvPArea = false;
|
||||
@@ -7485,8 +7489,6 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
|
||||
UpdateLocalChannels(newZone);
|
||||
|
||||
UpdateZoneDependentAuras(newZone);
|
||||
|
||||
UpdateAreaPhase();
|
||||
}
|
||||
|
||||
//If players are too far away from the duel flag... they lose the duel
|
||||
@@ -16040,7 +16042,7 @@ void Player::SendQuestUpdate(uint32 questId)
|
||||
}
|
||||
|
||||
UpdateForQuestWorldObjects();
|
||||
SendUpdatePhasing();
|
||||
PhasingHandler::OnConditionChange(this);
|
||||
}
|
||||
|
||||
QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver)
|
||||
@@ -23250,6 +23252,8 @@ void Player::SendInitialPacketsAfterAddToMap()
|
||||
else
|
||||
ClearQuestSharingInfo();
|
||||
}
|
||||
|
||||
PhasingHandler::OnMapChange(this);
|
||||
}
|
||||
|
||||
void Player::SendUpdateToOutOfRangeGroupMembers()
|
||||
@@ -27327,7 +27331,7 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
pet->CopyPhaseFrom(this);
|
||||
PhasingHandler::InheritPhaseShift(pet, this);
|
||||
|
||||
pet->SetCreatorGUID(GetGUID());
|
||||
pet->SetFaction(GetFaction());
|
||||
@@ -27699,16 +27703,6 @@ void Player::ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::Ext
|
||||
#undef REMOVE_VIOLATING_FLAGS
|
||||
}
|
||||
|
||||
void Player::SendUpdatePhasing()
|
||||
{
|
||||
if (!IsInWorld())
|
||||
return;
|
||||
|
||||
RebuildTerrainSwaps(); // to set default map swaps
|
||||
|
||||
GetSession()->SendSetPhaseShift(GetPhases(), GetTerrainSwaps(), GetWorldMapAreaSwaps());
|
||||
}
|
||||
|
||||
void Player::SendSupercededSpell(uint32 oldSpell, uint32 newSpell) const
|
||||
{
|
||||
WorldPacket data(SMSG_SUPERCEDED_SPELL, 8);
|
||||
|
||||
@@ -2347,6 +2347,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
|
||||
// currently visible objects at player client
|
||||
GuidUnorderedSet m_clientGUIDs;
|
||||
GuidUnorderedSet m_visibleTransports;
|
||||
|
||||
bool HaveAtClient(Object const* u) const;
|
||||
|
||||
@@ -2360,8 +2361,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
void UpdateVisibilityOf(WorldObject* target);
|
||||
void UpdateTriggerVisibility();
|
||||
|
||||
void SendUpdatePhasing();
|
||||
|
||||
template<class T>
|
||||
void UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "Transport.h"
|
||||
#include "MapManager.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "DBCStores.h"
|
||||
#include "GameObjectAI.h"
|
||||
@@ -326,13 +327,8 @@ Creature* Transport::CreateNPCPassenger(ObjectGuid::LowType guid, CreatureData c
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (data->phaseid)
|
||||
creature->SetInPhase(data->phaseid, false, true);
|
||||
else if (data->phaseGroup)
|
||||
for (auto phase : GetPhasesForGroup(data->phaseGroup))
|
||||
creature->SetInPhase(phase, false, true);
|
||||
else
|
||||
creature->CopyPhaseFrom(this);
|
||||
PhasingHandler::InitDbPhaseShift(creature->GetPhaseShift(), data->phaseUseFlags, data->phaseId, data->phaseGroup);
|
||||
PhasingHandler::InitDbVisibleMapId(creature->GetPhaseShift(), data->terrainSwapMap);
|
||||
|
||||
if (!map->AddToMap(creature))
|
||||
{
|
||||
@@ -377,6 +373,9 @@ GameObject* Transport::CreateGOPassenger(ObjectGuid::LowType guid, GameObjectDat
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PhasingHandler::InitDbPhaseShift(go->GetPhaseShift(), data->phaseUseFlags, data->phaseId, data->phaseGroup);
|
||||
PhasingHandler::InitDbVisibleMapId(go->GetPhaseShift(), data->terrainSwapMap);
|
||||
|
||||
if (!map->AddToMap(go))
|
||||
{
|
||||
delete go;
|
||||
@@ -441,12 +440,6 @@ TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSu
|
||||
}
|
||||
}
|
||||
|
||||
std::set<uint32> phases;
|
||||
if (summoner)
|
||||
phases = summoner->GetPhases();
|
||||
else
|
||||
phases = GetPhases(); // If there was no summoner, try to use the transport phases
|
||||
|
||||
TempSummon* summon = NULL;
|
||||
switch (mask)
|
||||
{
|
||||
@@ -477,8 +470,7 @@ TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSu
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (uint32 phase : phases)
|
||||
summon->SetInPhase(phase, false, true);
|
||||
PhasingHandler::InheritPhaseShift(summon, summoner ? static_cast<WorldObject*>(summoner) : static_cast<WorldObject*>(this));
|
||||
|
||||
summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId);
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ struct CreatureData;
|
||||
|
||||
class TC_GAME_API Transport : public GameObject, public TransportBase
|
||||
{
|
||||
friend Transport* TransportMgr::CreateTransport(uint32, ObjectGuid::LowType, Map*, uint32, uint32);
|
||||
friend Transport* TransportMgr::CreateTransport(uint32, ObjectGuid::LowType, Map*, uint8, uint32, uint32);
|
||||
|
||||
Transport();
|
||||
public:
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "PassiveAI.h"
|
||||
#include "PetAI.h"
|
||||
#include "Pet.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "Player.h"
|
||||
#include "PlayerAI.h"
|
||||
#include "QuestDef.h"
|
||||
@@ -3886,7 +3887,7 @@ void Unit::RemoveAurasWithAttribute(uint32 flags)
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase, bool phaseid)
|
||||
void Unit::RemoveNotOwnSingleTargetAuras(bool onPhaseChange /*= false*/)
|
||||
{
|
||||
// single target auras from other casters
|
||||
// Iterate m_ownedAuras - aura is marked as single target in Unit::AddAura (and pushed to m_ownedAuras).
|
||||
@@ -3903,12 +3904,12 @@ void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase, bool phaseid)
|
||||
|
||||
if (aura->GetCasterGUID() != GetGUID() && aura->IsSingleTarget())
|
||||
{
|
||||
if (!newPhase && !phaseid)
|
||||
if (!onPhaseChange)
|
||||
RemoveOwnedAura(iter);
|
||||
else
|
||||
{
|
||||
Unit* caster = aura->GetCaster();
|
||||
if (!caster || (newPhase && !caster->IsInPhase(newPhase)) || (!newPhase && !caster->IsInPhase(this)))
|
||||
if (!caster || !caster->IsInPhase(this))
|
||||
RemoveOwnedAura(iter);
|
||||
else
|
||||
++iter;
|
||||
@@ -3923,7 +3924,7 @@ void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase, bool phaseid)
|
||||
for (AuraList::iterator iter = scAuras.begin(); iter != scAuras.end();)
|
||||
{
|
||||
Aura* aura = *iter;
|
||||
if (aura->GetUnitOwner() != this && !aura->GetUnitOwner()->IsInPhase(newPhase))
|
||||
if (aura->GetUnitOwner() != this && !aura->GetUnitOwner()->IsInPhase(this))
|
||||
{
|
||||
aura->Remove();
|
||||
iter = scAuras.begin();
|
||||
@@ -10015,15 +10016,6 @@ int32 Unit::GetCreatePowers(Powers power) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Unit::AddToWorld()
|
||||
{
|
||||
if (!IsInWorld())
|
||||
{
|
||||
WorldObject::AddToWorld();
|
||||
}
|
||||
RebuildTerrainSwaps();
|
||||
}
|
||||
|
||||
void Unit::RemoveFromWorld()
|
||||
{
|
||||
// cleanup
|
||||
@@ -11343,7 +11335,7 @@ bool Unit::InitTamedPet(Pet* pet, uint8 level, uint32 spell_id)
|
||||
return false;
|
||||
}
|
||||
|
||||
pet->CopyPhaseFrom(this);
|
||||
PhasingHandler::InheritPhaseShift(pet, this);
|
||||
|
||||
pet->GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true);
|
||||
// this enables pet details window (Shift+P)
|
||||
@@ -12444,14 +12436,12 @@ float Unit::MeleeSpellMissChance(const Unit* victim, WeaponAttackType attType, u
|
||||
return missChance;
|
||||
}
|
||||
|
||||
bool Unit::SetInPhase(uint32 id, bool update, bool apply)
|
||||
void Unit::OnPhaseChange()
|
||||
{
|
||||
bool res = WorldObject::SetInPhase(id, update, apply);
|
||||
|
||||
if (!IsInWorld())
|
||||
return res;
|
||||
return;
|
||||
|
||||
if (GetTypeId() == TYPEID_UNIT || (!ToPlayer()->IsGameMaster() && !ToPlayer()->GetSession()->PlayerLogout()))
|
||||
if (GetTypeId() == TYPEID_UNIT || !ToPlayer()->GetSession()->PlayerLogout())
|
||||
{
|
||||
HostileRefManager& refManager = getHostileRefManager();
|
||||
HostileReference* ref = refManager.getFirst();
|
||||
@@ -12481,19 +12471,6 @@ bool Unit::SetInPhase(uint32 id, bool update, bool apply)
|
||||
unit->getHostileRefManager().setOnlineOfflineState(ToCreature(), unit->IsInPhase(this));
|
||||
}
|
||||
}
|
||||
|
||||
for (ControlList::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr)
|
||||
if ((*itr)->GetTypeId() == TYPEID_UNIT)
|
||||
(*itr)->SetInPhase(id, true, apply);
|
||||
|
||||
for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i)
|
||||
if (m_SummonSlot[i])
|
||||
if (Creature* summon = GetMap()->GetCreature(m_SummonSlot[i]))
|
||||
summon->SetInPhase(id, true, apply);
|
||||
|
||||
RemoveNotOwnSingleTargetAuras(0, true);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void Unit::UpdateObjectVisibility(bool forced)
|
||||
@@ -13274,7 +13251,7 @@ void Unit::_ExitVehicle(Position const* exitPosition)
|
||||
Movement::MoveSplineInit init(this);
|
||||
|
||||
// Creatures without inhabit type air should begin falling after exiting the vehicle
|
||||
if (GetTypeId() == TYPEID_UNIT && !CanFly() && height > GetMap()->GetWaterOrGroundLevel(GetPhases(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), &height) + 0.1f)
|
||||
if (GetTypeId() == TYPEID_UNIT && !CanFly() && height > GetMap()->GetWaterOrGroundLevel(GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), &height) + 0.1f)
|
||||
init.SetFall();
|
||||
|
||||
init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), height, false);
|
||||
|
||||
@@ -1309,7 +1309,6 @@ class TC_GAME_API Unit : public WorldObject
|
||||
UnitAI* GetAI() { return i_AI; }
|
||||
void SetAI(UnitAI* newAI) { i_AI = newAI; }
|
||||
|
||||
void AddToWorld() override;
|
||||
void RemoveFromWorld() override;
|
||||
|
||||
void CleanupBeforeRemoveFromMap(bool finalCleanup);
|
||||
@@ -1795,7 +1794,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, Unit* stealer);
|
||||
void RemoveAurasDueToItemSpell(uint32 spellId, ObjectGuid castItemGuid);
|
||||
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID = ObjectGuid::Empty, Aura* except = NULL, bool negative = true, bool positive = true);
|
||||
void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0, bool phaseid = false);
|
||||
void RemoveNotOwnSingleTargetAuras(bool onPhaseChange = false);
|
||||
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except = 0);
|
||||
void RemoveAurasWithAttribute(uint32 flags);
|
||||
void RemoveAurasWithFamily(SpellFamilyNames family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, ObjectGuid casterGUID);
|
||||
@@ -1977,7 +1976,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
void SetVisible(bool x);
|
||||
|
||||
// common function for visibility checks for player/creatures with detection code
|
||||
bool SetInPhase(uint32 id, bool update, bool apply) override;
|
||||
void OnPhaseChange();
|
||||
void UpdateObjectVisibility(bool forced = true) override;
|
||||
|
||||
SpellImmuneContainer m_spellImmune[MAX_SPELL_IMMUNITY];
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "Chat.h"
|
||||
#include "Common.h"
|
||||
#include "Containers.h"
|
||||
#include "CreatureAIFactory.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "DB2Structure.h"
|
||||
@@ -1828,9 +1829,9 @@ void ObjectMgr::LoadCreatures()
|
||||
// 0 1 2 3 4 5 6 7 8 9 10
|
||||
QueryResult result = WorldDatabase.Query("SELECT creature.guid, id, map, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, "
|
||||
// 11 12 13 14 15 16 17 18 19 20 21 22
|
||||
"currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags, creature.phaseid, "
|
||||
// 23 24
|
||||
"creature.phasegroup, creature.ScriptName "
|
||||
"currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags, creature.phaseUseFlags, "
|
||||
// 23 24 25 26
|
||||
"creature.phaseid, creature.phasegroup, creature.terrainSwapMap, creature.ScriptName "
|
||||
"FROM creature "
|
||||
"LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid "
|
||||
"LEFT OUTER JOIN pool_creature ON creature.guid = pool_creature.guid");
|
||||
@@ -1887,9 +1888,11 @@ void ObjectMgr::LoadCreatures()
|
||||
data.npcflag = fields[19].GetUInt32();
|
||||
data.unit_flags = fields[20].GetUInt32();
|
||||
data.dynamicflags = fields[21].GetUInt32();
|
||||
data.phaseid = fields[22].GetUInt32();
|
||||
data.phaseGroup = fields[23].GetUInt32();
|
||||
data.ScriptId = GetScriptId(fields[24].GetString());
|
||||
data.phaseUseFlags = fields[22].GetUInt8();
|
||||
data.phaseId = fields[23].GetUInt32();
|
||||
data.phaseGroup = fields[24].GetUInt32();
|
||||
data.terrainSwapMap = fields[25].GetInt32();
|
||||
data.ScriptId = GetScriptId(fields[26].GetString());
|
||||
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapid);
|
||||
if (!mapEntry)
|
||||
@@ -1971,18 +1974,46 @@ void ObjectMgr::LoadCreatures()
|
||||
data.phaseMask = 1;
|
||||
}
|
||||
|
||||
if (data.phaseGroup && GetPhasesForGroup(data.phaseGroup).empty())
|
||||
if (data.phaseUseFlags & ~PHASE_USE_FLAGS_ALL)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: " UI64FMTD " Entry: %u) has unknown `phaseUseFlags` set, removed unknown value.", guid, data.id);
|
||||
data.phaseUseFlags &= PHASE_USE_FLAGS_ALL;
|
||||
}
|
||||
|
||||
if (data.phaseUseFlags & PHASE_USE_FLAGS_ALWAYS_VISIBLE && data.phaseUseFlags & PHASE_USE_FLAGS_INVERSE)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: " UI64FMTD " Entry: %u) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE,"
|
||||
" removing PHASE_USE_FLAGS_INVERSE.", guid, data.id);
|
||||
data.phaseUseFlags &= ~PHASE_USE_FLAGS_INVERSE;
|
||||
}
|
||||
|
||||
if (data.phaseGroup && !GetPhasesForGroup(data.phaseGroup))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: %u Entry: %u) with non-existing `phasegroup` (%u) set, `phasegroup` set to 0", guid, data.id, data.phaseGroup);
|
||||
data.phaseGroup = 0;
|
||||
}
|
||||
|
||||
if (data.phaseGroup && data.phaseid)
|
||||
if (data.phaseGroup && data.phaseId)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: %u Entry: %u) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.id);
|
||||
data.phaseGroup = 0;
|
||||
}
|
||||
|
||||
if (data.terrainSwapMap != -1)
|
||||
{
|
||||
MapEntry const* terrainSwapEntry = sMapStore.LookupEntry(data.terrainSwapMap);
|
||||
if (!terrainSwapEntry)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: " UI64FMTD " Entry: %u) with `terrainSwapMap` %u does not exist, set to -1", guid, data.id, data.terrainSwapMap);
|
||||
data.terrainSwapMap = -1;
|
||||
}
|
||||
else if (terrainSwapEntry->rootPhaseMap != data.mapid)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: " UI64FMTD " Entry: %u) with `terrainSwapMap` %u which cannot be used on spawn map, set to -1", guid, data.id, data.terrainSwapMap);
|
||||
data.terrainSwapMap = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (sWorld->getBoolConfig(CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA))
|
||||
{
|
||||
uint32 zoneId = 0;
|
||||
@@ -2141,8 +2172,8 @@ void ObjectMgr::LoadGameobjects()
|
||||
QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, "
|
||||
// 7 8 9 10 11 12 13 14 15 16 17
|
||||
"rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, eventEntry, pool_entry, "
|
||||
// 18 19 20
|
||||
"phaseid, phasegroup, ScriptName "
|
||||
// 18 19 20 21 22
|
||||
"phaseUseFlags, phaseid, phasegroup, terrainSwapMap, ScriptName "
|
||||
"FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid "
|
||||
"LEFT OUTER JOIN pool_gameobject ON gameobject.guid = pool_gameobject.guid");
|
||||
|
||||
@@ -2243,22 +2274,52 @@ void ObjectMgr::LoadGameobjects()
|
||||
data.phaseMask = fields[15].GetUInt32();
|
||||
int16 gameEvent = fields[16].GetInt8();
|
||||
uint32 PoolId = fields[17].GetUInt32();
|
||||
data.phaseid = fields[18].GetUInt32();
|
||||
data.phaseGroup = fields[19].GetUInt32();
|
||||
data.phaseUseFlags = fields[18].GetUInt8();
|
||||
data.phaseId = fields[19].GetUInt32();
|
||||
data.phaseGroup = fields[20].GetUInt32();
|
||||
|
||||
if (data.phaseGroup && GetPhasesForGroup(data.phaseGroup).empty())
|
||||
if (data.phaseUseFlags & ~PHASE_USE_FLAGS_ALL)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: " UI64FMTD " Entry: %u) has unknown `phaseUseFlags` set, removed unknown value.", guid, data.id);
|
||||
data.phaseUseFlags &= PHASE_USE_FLAGS_ALL;
|
||||
}
|
||||
|
||||
if (data.phaseUseFlags & PHASE_USE_FLAGS_ALWAYS_VISIBLE && data.phaseUseFlags & PHASE_USE_FLAGS_INVERSE)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: " UI64FMTD " Entry: %u) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE,"
|
||||
" removing PHASE_USE_FLAGS_INVERSE.", guid, data.id);
|
||||
data.phaseUseFlags &= ~PHASE_USE_FLAGS_INVERSE;
|
||||
}
|
||||
|
||||
if (data.phaseGroup && !GetPhasesForGroup(data.phaseGroup))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: %u Entry: %u) with non-existing `phasegroup` (%u) set, `phasegroup` set to 0", guid, data.id, data.phaseGroup);
|
||||
data.phaseGroup = 0;
|
||||
}
|
||||
|
||||
if (data.phaseGroup && data.phaseid)
|
||||
if (data.phaseGroup && data.phaseId)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: %u Entry: %u) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.id);
|
||||
data.phaseGroup = 0;
|
||||
}
|
||||
|
||||
data.ScriptId = GetScriptId(fields[20].GetString());
|
||||
data.terrainSwapMap = fields[21].GetInt32();
|
||||
if (data.terrainSwapMap != -1)
|
||||
{
|
||||
MapEntry const* terrainSwapEntry = sMapStore.LookupEntry(data.terrainSwapMap);
|
||||
if (!terrainSwapEntry)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: " UI64FMTD " Entry: %u) with `terrainSwapMap` %u does not exist, set to -1", guid, data.id, data.terrainSwapMap);
|
||||
data.terrainSwapMap = -1;
|
||||
}
|
||||
else if (terrainSwapEntry->rootPhaseMap != data.mapid)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: " UI64FMTD " Entry: %u) with `terrainSwapMap` %u which cannot be used on spawn map, set to -1", guid, data.id, data.terrainSwapMap);
|
||||
data.terrainSwapMap = -1;
|
||||
}
|
||||
}
|
||||
|
||||
data.ScriptId = GetScriptId(fields[22].GetString());
|
||||
|
||||
if (std::abs(data.orientation) > 2 * float(M_PI))
|
||||
{
|
||||
@@ -9498,10 +9559,78 @@ void ObjectMgr::LoadFactionChangeTitles()
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u faction change title pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadPhases()
|
||||
{
|
||||
for (PhaseEntry const* phase : sPhaseStore)
|
||||
_phaseInfoById.emplace(std::make_pair(phase->ID, PhaseInfoStruct{ phase->ID, std::unordered_set<uint32>{} }));
|
||||
|
||||
for (MapEntry const* map : sMapStore)
|
||||
if (map->rootPhaseMap != -1)
|
||||
_terrainSwapInfoById.emplace(std::make_pair(map->MapID, TerrainSwapInfo{ map->MapID, std::vector<uint32>{} }));
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading Terrain World Map definitions...");
|
||||
LoadTerrainWorldMaps();
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading Terrain Swap Default definitions...");
|
||||
LoadTerrainSwapDefaults();
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading Phase Area definitions...");
|
||||
LoadAreaPhases();
|
||||
}
|
||||
|
||||
void ObjectMgr::UnloadPhaseConditions()
|
||||
{
|
||||
for (auto itr = _phaseInfoByArea.begin(); itr != _phaseInfoByArea.end(); ++itr)
|
||||
for (PhaseAreaInfo& phase : itr->second)
|
||||
phase.Conditions.clear();
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadTerrainWorldMaps()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
// 0 1
|
||||
QueryResult result = WorldDatabase.Query("SELECT TerrainSwapMap, WorldMapArea FROM `terrain_worldmap`");
|
||||
|
||||
|
||||
if (!result)
|
||||
{
|
||||
TC_LOG_INFO("server.loading", ">> Loaded 0 terrain world maps. DB table `terrain_worldmap` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 count = 0;
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
uint32 mapId = fields[0].GetUInt32();
|
||||
uint32 worldMapArea = fields[1].GetUInt32();
|
||||
|
||||
if (!sMapStore.LookupEntry(mapId))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "TerrainSwapMap %u defined in `terrain_worldmap` does not exist, skipped.", mapId);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!sWorldMapAreaStore.LookupEntry(worldMapArea))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "WorldMapArea %u defined in `terrain_worldmap` does not exist, skipped.", worldMapArea);
|
||||
continue;
|
||||
}
|
||||
|
||||
TerrainSwapInfo* terrainSwapInfo = &_terrainSwapInfoById[mapId];
|
||||
terrainSwapInfo->Id = mapId;
|
||||
terrainSwapInfo->UiWorldMapAreaIDSwaps.push_back(worldMapArea);
|
||||
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u terrain world maps in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadTerrainSwapDefaults()
|
||||
{
|
||||
_terrainMapDefaultStore.clear();
|
||||
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
// 0 1
|
||||
@@ -9534,7 +9663,9 @@ void ObjectMgr::LoadTerrainSwapDefaults()
|
||||
continue;
|
||||
}
|
||||
|
||||
_terrainMapDefaultStore[mapId].push_back(terrainSwap);
|
||||
TerrainSwapInfo* terrainSwapInfo = &_terrainSwapInfoById[terrainSwap];
|
||||
terrainSwapInfo->Id = terrainSwap;
|
||||
_terrainSwapInfoByMap[mapId].push_back(terrainSwapInfo);
|
||||
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
@@ -9542,88 +9673,8 @@ void ObjectMgr::LoadTerrainSwapDefaults()
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u terrain swap defaults in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadTerrainPhaseInfo()
|
||||
{
|
||||
_terrainPhaseInfoStore.clear();
|
||||
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
// 0 1
|
||||
QueryResult result = WorldDatabase.Query("SELECT Id, TerrainSwapMap FROM `terrain_phase_info`");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
TC_LOG_INFO("server.loading", ">> Loaded 0 terrain phase infos. DB table `terrain_phase_info` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 count = 0;
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
uint32 phaseId = fields[0].GetUInt32();
|
||||
|
||||
PhaseEntry const* phase = sPhaseStore.LookupEntry(phaseId);
|
||||
if (!phase)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Phase %u defined in `terrain_phase_info` does not exist, skipped.", phaseId);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32 terrainSwap = fields[1].GetUInt32();
|
||||
|
||||
_terrainPhaseInfoStore[phaseId].push_back(terrainSwap);
|
||||
|
||||
++count;
|
||||
}
|
||||
while (result->NextRow());
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u terrain phase infos in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadTerrainWorldMaps()
|
||||
{
|
||||
_terrainWorldMapStore.clear();
|
||||
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
// 0 1
|
||||
QueryResult result = WorldDatabase.Query("SELECT TerrainSwapMap, WorldMapArea FROM `terrain_worldmap`");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
TC_LOG_INFO("server.loading", ">> Loaded 0 terrain world maps. DB table `terrain_worldmap` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 count = 0;
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
uint32 mapId = fields[0].GetUInt32();
|
||||
|
||||
if (!sMapStore.LookupEntry(mapId))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "TerrainSwapMap %u defined in `terrain_worldmap` does not exist, skipped.", mapId);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32 worldMapArea = fields[1].GetUInt32();
|
||||
|
||||
_terrainWorldMapStore[mapId].push_back(worldMapArea);
|
||||
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u terrain world maps in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadAreaPhases()
|
||||
{
|
||||
_phases.clear();
|
||||
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
// 0 1
|
||||
@@ -9635,23 +9686,93 @@ void ObjectMgr::LoadAreaPhases()
|
||||
return;
|
||||
}
|
||||
|
||||
auto getOrCreatePhaseIfMissing = [this](uint32 phaseId)
|
||||
{
|
||||
PhaseInfoStruct* phaseInfo = &_phaseInfoById[phaseId];
|
||||
phaseInfo->Id = phaseId;
|
||||
return phaseInfo;
|
||||
};
|
||||
|
||||
uint32 count = 0;
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
PhaseInfoStruct phase;
|
||||
uint32 area = fields[0].GetUInt32();
|
||||
uint32 phaseId = fields[1].GetUInt32();
|
||||
if (!sAreaTableStore.LookupEntry(area))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Area %u defined in `phase_area` does not exist, skipped.", area);
|
||||
continue;
|
||||
}
|
||||
|
||||
phase.Id = fields[1].GetUInt32();
|
||||
_phases[area].push_back(phase);
|
||||
if (!sPhaseStore.LookupEntry(phaseId))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Phase %u defined in `phase_area` does not exist, skipped.", phaseId);
|
||||
continue;
|
||||
}
|
||||
|
||||
PhaseInfoStruct* phase = getOrCreatePhaseIfMissing(phaseId);
|
||||
phase->Areas.insert(area);
|
||||
_phaseInfoByArea[area].emplace_back(phase);
|
||||
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
|
||||
for (auto itr = _phaseInfoByArea.begin(); itr != _phaseInfoByArea.end(); ++itr)
|
||||
{
|
||||
for (PhaseAreaInfo& phase : itr->second)
|
||||
{
|
||||
uint32 parentAreaId = itr->first;
|
||||
do
|
||||
{
|
||||
AreaTableEntry const* area = sAreaTableStore.LookupEntry(parentAreaId);
|
||||
if (!area)
|
||||
break;
|
||||
|
||||
parentAreaId = area->zone;
|
||||
if (!parentAreaId)
|
||||
break;
|
||||
|
||||
if (std::vector<PhaseAreaInfo>* parentAreaPhases = Trinity::Containers::MapGetValuePtr(_phaseInfoByArea, parentAreaId))
|
||||
for (PhaseAreaInfo& parentAreaPhase : *parentAreaPhases)
|
||||
if (parentAreaPhase.PhaseInfo->Id == phase.PhaseInfo->Id)
|
||||
parentAreaPhase.SubAreaExclusions.insert(itr->first);
|
||||
|
||||
} while (true);
|
||||
}
|
||||
}
|
||||
|
||||
TC_LOG_INFO("server.loading", ">> Loaded %u phase areas in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
bool PhaseInfoStruct::IsAllowedInArea(uint32 areaId) const
|
||||
{
|
||||
return std::any_of(Areas.begin(), Areas.end(), [areaId](uint32 areaToCheck)
|
||||
{
|
||||
return IsInArea(areaId, areaToCheck);
|
||||
});
|
||||
}
|
||||
|
||||
PhaseInfoStruct const* ObjectMgr::GetPhaseInfo(uint32 phaseId) const
|
||||
{
|
||||
return Trinity::Containers::MapGetValuePtr(_phaseInfoById, phaseId);
|
||||
}
|
||||
|
||||
std::vector<PhaseAreaInfo> const* ObjectMgr::GetPhasesForArea(uint32 areaId) const
|
||||
{
|
||||
return Trinity::Containers::MapGetValuePtr(_phaseInfoByArea, areaId);
|
||||
}
|
||||
|
||||
TerrainSwapInfo const* ObjectMgr::GetTerrainSwapInfo(uint32 terrainSwapId) const
|
||||
{
|
||||
return Trinity::Containers::MapGetValuePtr(_terrainSwapInfoById, terrainSwapId);
|
||||
}
|
||||
|
||||
std::vector<TerrainSwapInfo*> const* ObjectMgr::GetTerrainSwapsForMap(uint32 mapId) const
|
||||
{
|
||||
return Trinity::Containers::MapGetValuePtr(_terrainSwapInfoByMap, mapId);
|
||||
}
|
||||
|
||||
GameObjectTemplate const* ObjectMgr::GetGameObjectTemplate(uint32 entry) const
|
||||
{
|
||||
GameObjectTemplateContainer::const_iterator itr = _gameObjectTemplateStore.find(entry);
|
||||
|
||||
@@ -710,15 +710,28 @@ struct HotfixInfo
|
||||
|
||||
typedef std::vector<HotfixInfo> HotfixData;
|
||||
|
||||
struct TerrainSwapInfo
|
||||
{
|
||||
uint32 Id;
|
||||
std::vector<uint32> UiWorldMapAreaIDSwaps;
|
||||
};
|
||||
|
||||
struct PhaseInfoStruct
|
||||
{
|
||||
uint32 Id;
|
||||
ConditionContainer Conditions;
|
||||
std::unordered_set<uint32> Areas;
|
||||
|
||||
bool IsAllowedInArea(uint32 areaId) const;
|
||||
};
|
||||
|
||||
typedef std::unordered_map<uint32, std::vector<uint32 /*id*/>> TerrainPhaseInfo; // terrain swap
|
||||
typedef std::unordered_map<uint32, std::vector<uint32>> TerrainUIPhaseInfo; // worldmaparea swap
|
||||
typedef std::unordered_map<uint32, std::vector<PhaseInfoStruct>> PhaseInfo; // phase
|
||||
struct PhaseAreaInfo
|
||||
{
|
||||
PhaseAreaInfo(PhaseInfoStruct const* phaseInfo) : PhaseInfo(phaseInfo) { }
|
||||
|
||||
PhaseInfoStruct const* PhaseInfo;
|
||||
std::unordered_set<uint32> SubAreaExclusions;
|
||||
ConditionContainer Conditions;
|
||||
};
|
||||
|
||||
class PlayerDumpReader;
|
||||
|
||||
@@ -1066,7 +1079,8 @@ class TC_GAME_API ObjectMgr
|
||||
void LoadTrainerSpell();
|
||||
void AddSpellToTrainer(uint32 ID, uint32 SpellID, uint32 MoneyCost, uint32 ReqSkillLine, uint32 ReqSkillRank, uint32 ReqLevel, uint32 Index);
|
||||
|
||||
void LoadTerrainPhaseInfo();
|
||||
void LoadPhases();
|
||||
void UnloadPhaseConditions();
|
||||
void LoadTerrainSwapDefaults();
|
||||
void LoadTerrainWorldMaps();
|
||||
void LoadAreaPhases();
|
||||
@@ -1338,36 +1352,6 @@ class TC_GAME_API ObjectMgr
|
||||
return _gossipMenuItemsStore.equal_range(uiMenuId);
|
||||
}
|
||||
|
||||
std::vector<uint32> const* GetPhaseTerrainSwaps(uint32 phaseid) const
|
||||
{
|
||||
auto itr = _terrainPhaseInfoStore.find(phaseid);
|
||||
return itr != _terrainPhaseInfoStore.end() ? &itr->second : nullptr;
|
||||
}
|
||||
std::vector<uint32> const* GetDefaultTerrainSwaps(uint32 mapid) const
|
||||
{
|
||||
auto itr = _terrainMapDefaultStore.find(mapid);
|
||||
return itr != _terrainMapDefaultStore.end() ? &itr->second : nullptr;
|
||||
}
|
||||
std::vector<uint32> const* GetTerrainWorldMaps(uint32 terrainId) const
|
||||
{
|
||||
auto itr = _terrainWorldMapStore.find(terrainId);
|
||||
return itr != _terrainWorldMapStore.end() ? &itr->second : nullptr;
|
||||
}
|
||||
std::vector<PhaseInfoStruct> const* GetPhasesForArea(uint32 area) const
|
||||
{
|
||||
auto itr = _phases.find(area);
|
||||
return itr != _phases.end() ? &itr->second : nullptr;
|
||||
}
|
||||
TerrainPhaseInfo const& GetDefaultTerrainSwapStore() const { return _terrainMapDefaultStore; }
|
||||
PhaseInfo const& GetAreaPhases() const { return _phases; }
|
||||
// condition loading helpers
|
||||
std::vector<PhaseInfoStruct>* GetPhasesForAreaForLoading(uint32 area)
|
||||
{
|
||||
auto itr = _phases.find(area);
|
||||
return itr != _phases.end() ? &itr->second : nullptr;
|
||||
}
|
||||
PhaseInfo& GetAreaPhasesForLoading() { return _phases; }
|
||||
|
||||
// for wintergrasp only
|
||||
GraveYardContainer GraveYardStore;
|
||||
|
||||
@@ -1486,10 +1470,18 @@ class TC_GAME_API ObjectMgr
|
||||
PageTextContainer _pageTextStore;
|
||||
InstanceTemplateContainer _instanceTemplateStore;
|
||||
|
||||
TerrainPhaseInfo _terrainPhaseInfoStore;
|
||||
TerrainPhaseInfo _terrainMapDefaultStore;
|
||||
TerrainUIPhaseInfo _terrainWorldMapStore;
|
||||
PhaseInfo _phases;
|
||||
public:
|
||||
PhaseInfoStruct const* GetPhaseInfo(uint32 phaseId) const;
|
||||
std::vector<PhaseAreaInfo> const* GetPhasesForArea(uint32 areaId) const;
|
||||
TerrainSwapInfo const* GetTerrainSwapInfo(uint32 terrainSwapId) const;
|
||||
std::vector<TerrainSwapInfo*> const* GetTerrainSwapsForMap(uint32 mapId) const;
|
||||
|
||||
private:
|
||||
std::unordered_map<uint32, PhaseInfoStruct> _phaseInfoById;
|
||||
std::unordered_map<uint32, TerrainSwapInfo> _terrainSwapInfoById;
|
||||
std::unordered_map<uint32, std::vector<PhaseAreaInfo>> _phaseInfoByArea;
|
||||
std::unordered_map<uint32, std::vector<TerrainSwapInfo*>> _terrainSwapInfoByMap;
|
||||
|
||||
|
||||
private:
|
||||
void LoadScripts(ScriptsType type);
|
||||
|
||||
@@ -324,7 +324,7 @@ void MessageDistDelivererToHostile::Visit(PlayerMapType &m)
|
||||
for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
Player* target = iter->GetSource();
|
||||
if (!target->IsInPhase(i_phaseMask))
|
||||
if (!target->IsInPhase(i_source))
|
||||
continue;
|
||||
|
||||
if (target->GetExactDist2dSq(i_source) > i_distSq)
|
||||
@@ -349,7 +349,7 @@ void MessageDistDelivererToHostile::Visit(CreatureMapType &m)
|
||||
for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
Creature* target = iter->GetSource();
|
||||
if (!target->IsInPhase(i_phaseMask))
|
||||
if (!target->IsInPhase(i_source))
|
||||
continue;
|
||||
|
||||
if (target->GetExactDist2dSq(i_source) > i_distSq)
|
||||
@@ -371,7 +371,7 @@ void MessageDistDelivererToHostile::Visit(DynamicObjectMapType &m)
|
||||
for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
DynamicObject* target = iter->GetSource();
|
||||
if (!target->IsInPhase(i_phaseMask))
|
||||
if (!target->IsInPhase(i_source))
|
||||
continue;
|
||||
|
||||
if (target->GetExactDist2dSq(i_source) > i_distSq)
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "Log.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Pet.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "Player.h"
|
||||
#include "SocialMgr.h"
|
||||
#include "SpellAuras.h"
|
||||
@@ -984,8 +985,6 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke
|
||||
if (mask == GROUP_UPDATE_FLAG_NONE)
|
||||
return;
|
||||
|
||||
std::set<uint32> const& phases = player->GetPhases();
|
||||
|
||||
if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also
|
||||
mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER);
|
||||
|
||||
@@ -1207,12 +1206,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke
|
||||
}
|
||||
|
||||
if (mask & GROUP_UPDATE_FLAG_PHASE)
|
||||
{
|
||||
*data << uint32(phases.empty() ? 8 : 0);
|
||||
*data << uint32(phases.size());
|
||||
for (std::set<uint32>::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
|
||||
*data << uint16(*itr);
|
||||
}
|
||||
PhasingHandler::FillPartyMemberPhase(data, player->GetPhaseShift());
|
||||
}
|
||||
|
||||
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
|
||||
@@ -1236,7 +1230,6 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData)
|
||||
|
||||
Pet* pet = player->GetPet();
|
||||
Powers powerType = player->getPowerType();
|
||||
std::set<uint32> const& phases = player->GetPhases();
|
||||
|
||||
WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
|
||||
data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
|
||||
@@ -1257,7 +1250,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData)
|
||||
if (player->GetVehicle())
|
||||
updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT;
|
||||
|
||||
if (!phases.empty())
|
||||
if (!player->GetPhaseShift().GetPhases().empty())
|
||||
updateFlags |= GROUP_UPDATE_FLAG_PHASE;
|
||||
|
||||
uint16 playerStatus = MEMBER_STATUS_ONLINE;
|
||||
@@ -1385,12 +1378,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData)
|
||||
data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]);
|
||||
|
||||
if (updateFlags & GROUP_UPDATE_FLAG_PHASE)
|
||||
{
|
||||
data << uint32(phases.empty() ? 8 : 0);
|
||||
data << uint32(phases.size());
|
||||
for (std::set<uint32>::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
|
||||
data << uint16(*itr);
|
||||
}
|
||||
PhasingHandler::FillPartyMemberPhase(&data, player->GetPhaseShift());
|
||||
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
@@ -1603,54 +1603,6 @@ void WorldSession::HandleReadyForAccountDataTimes(WorldPacket& /*recvData*/)
|
||||
SendAccountDataTimes(GLOBAL_CACHE_MASK);
|
||||
}
|
||||
|
||||
void WorldSession::SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set<uint32> const& terrainswaps, std::set<uint32> const& worldMapAreaSwaps)
|
||||
{
|
||||
ObjectGuid guid = _player->GetGUID();
|
||||
|
||||
WorldPacket data(SMSG_SET_PHASE_SHIFT, 1 + 8 + 4 + 4 + 4 + 4 + 2 * phaseIds.size() + 4 + terrainswaps.size() * 2);
|
||||
data.WriteBit(guid[2]);
|
||||
data.WriteBit(guid[3]);
|
||||
data.WriteBit(guid[1]);
|
||||
data.WriteBit(guid[6]);
|
||||
data.WriteBit(guid[4]);
|
||||
data.WriteBit(guid[5]);
|
||||
data.WriteBit(guid[0]);
|
||||
data.WriteBit(guid[7]);
|
||||
|
||||
data.WriteByteSeq(guid[7]);
|
||||
data.WriteByteSeq(guid[4]);
|
||||
|
||||
data << uint32(worldMapAreaSwaps.size()) * 2;
|
||||
for (auto mapSwap : worldMapAreaSwaps)
|
||||
data << uint16(mapSwap); // WorldMapArea.dbc id (controls map display)
|
||||
|
||||
data.WriteByteSeq(guid[1]);
|
||||
|
||||
data << uint32(phaseIds.size() ? 0 : 8); // flags (not phasemask)
|
||||
|
||||
data.WriteByteSeq(guid[2]);
|
||||
data.WriteByteSeq(guid[6]);
|
||||
|
||||
data << uint32(0); // Inactive terrain swaps
|
||||
//for (uint8 i = 0; i < inactiveSwapsCount; ++i)
|
||||
// data << uint16(0);
|
||||
|
||||
data << uint32(phaseIds.size()) * 2; // Phase.dbc ids
|
||||
for (std::set<uint32>::const_iterator itr = phaseIds.begin(); itr != phaseIds.end(); ++itr)
|
||||
data << uint16(*itr);
|
||||
|
||||
data.WriteByteSeq(guid[3]);
|
||||
data.WriteByteSeq(guid[0]);
|
||||
|
||||
data << uint32(terrainswaps.size()) * 2; // Active terrain swaps
|
||||
for (std::set<uint32>::const_iterator itr = terrainswaps.begin(); itr != terrainswaps.end(); ++itr)
|
||||
data << uint16(*itr);
|
||||
|
||||
data.WriteByteSeq(guid[5]);
|
||||
|
||||
SendPacket(&data);
|
||||
}
|
||||
|
||||
// Battlefield and Battleground
|
||||
void WorldSession::HandleAreaSpiritHealerQueryOpcode(WorldPacket& recvData)
|
||||
{
|
||||
|
||||
@@ -266,7 +266,7 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket& /*recvData*/)
|
||||
mapID = corpseMapEntry->entrance_map;
|
||||
x = corpseMapEntry->entrance_x;
|
||||
y = corpseMapEntry->entrance_y;
|
||||
z = entranceMap->GetHeight(GetPlayer()->GetPhases(), x, y, MAX_HEIGHT);
|
||||
z = entranceMap->GetHeight(GetPlayer()->GetPhaseShift(), x, y, MAX_HEIGHT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "Map.h"
|
||||
#include "Player.h"
|
||||
#include "Pet.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Opcodes.h"
|
||||
#include "ScriptReloadMgr.h"
|
||||
@@ -713,7 +714,7 @@ void InstanceScript::UpdatePhasing()
|
||||
Map::PlayerList const& players = instance->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
if (Player* player = itr->GetSource())
|
||||
player->SendUpdatePhasing();
|
||||
PhasingHandler::SendToPlayer(player);
|
||||
}
|
||||
|
||||
void InstanceScript::UpdateCombatResurrection(uint32 diff)
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Pet.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "Transport.h"
|
||||
#include "Vehicle.h"
|
||||
@@ -536,8 +537,7 @@ bool Map::AddPlayerToMap(Player* player)
|
||||
|
||||
player->m_clientGUIDs.clear();
|
||||
player->UpdateObjectVisibility(false);
|
||||
|
||||
player->SendUpdatePhasing();
|
||||
PhasingHandler::SendToPlayer(player);
|
||||
|
||||
if (player->IsAlive())
|
||||
ConvertCorpseToBones(player->GetGUID());
|
||||
@@ -600,8 +600,6 @@ bool Map::AddToMap(T* obj)
|
||||
if (obj->isActiveObject())
|
||||
AddToActive(obj);
|
||||
|
||||
obj->RebuildTerrainSwaps();
|
||||
|
||||
//something, such as vehicle, needs to be update immediately
|
||||
//also, trigger needs to cast spell, if not update, cannot see visual
|
||||
obj->UpdateObjectVisibilityOnCreate();
|
||||
@@ -2239,12 +2237,12 @@ inline GridMap* Map::GetGrid(float x, float y)
|
||||
return GridMaps[gx][gy];
|
||||
}
|
||||
|
||||
float Map::GetWaterOrGroundLevel(std::set<uint32> const& phases, float x, float y, float z, float* ground /*= nullptr*/, bool /*swim = false*/) const
|
||||
float Map::GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y, float z, float* ground /*= nullptr*/, bool /*swim = false*/) const
|
||||
{
|
||||
if (const_cast<Map*>(this)->GetGrid(x, y))
|
||||
{
|
||||
// we need ground level (including grid height version) for proper return water level in point
|
||||
float ground_z = GetHeight(phases, x, y, z, true, 50.0f);
|
||||
float ground_z = GetHeight(phaseShift, x, y, z, true, 50.0f);
|
||||
if (ground)
|
||||
*ground = ground_z;
|
||||
|
||||
@@ -2629,24 +2627,24 @@ float Map::GetWaterLevel(float x, float y) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Map::isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, std::set<uint32> const& phases, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const
|
||||
bool Map::isInLineOfSight(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const
|
||||
{
|
||||
if ((checks & LINEOFSIGHT_CHECK_VMAP)
|
||||
&& !VMAP::VMapFactory::createOrGetVMapManager()->isInLineOfSight(GetId(), x1, y1, z1, x2, y2, z2, ignoreFlags))
|
||||
return false;
|
||||
if (sWorld->getBoolConfig(CONFIG_CHECK_GOBJECT_LOS) && (checks & LINEOFSIGHT_CHECK_GOBJECT)
|
||||
&& !_dynamicTree.isInLineOfSight({x1, y1, z1}, {x2, y2, z2}, phases))
|
||||
&& !_dynamicTree.isInLineOfSight({x1, y1, z1}, {x2, y2, z2}, phaseShift))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Map::getObjectHitPos(std::set<uint32> const& phases, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist)
|
||||
bool Map::getObjectHitPos(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float& ry, float& rz, float modifyDist)
|
||||
{
|
||||
G3D::Vector3 startPos(x1, y1, z1);
|
||||
G3D::Vector3 dstPos(x2, y2, z2);
|
||||
|
||||
G3D::Vector3 resultPos;
|
||||
bool result = _dynamicTree.getObjectHitPos(phases, startPos, dstPos, resultPos, modifyDist);
|
||||
bool result = _dynamicTree.getObjectHitPos(startPos, dstPos, resultPos, modifyDist, phaseShift);
|
||||
|
||||
rx = resultPos.x;
|
||||
ry = resultPos.y;
|
||||
@@ -2654,9 +2652,9 @@ bool Map::getObjectHitPos(std::set<uint32> const& phases, float x1, float y1, fl
|
||||
return result;
|
||||
}
|
||||
|
||||
float Map::GetHeight(std::set<uint32> const& phases, float x, float y, float z, bool vmap /*= true*/, float maxSearchDist /*= DEFAULT_HEIGHT_SEARCH*/) const
|
||||
float Map::GetHeight(PhaseShift const& phaseShift, float x, float y, float z, bool vmap /*= true*/, float maxSearchDist /*= DEFAULT_HEIGHT_SEARCH*/) const
|
||||
{
|
||||
return std::max<float>(GetHeight(x, y, z, vmap, maxSearchDist), GetGameObjectFloor(phases, x, y, z, maxSearchDist));
|
||||
return std::max<float>(GetHeight(x, y, z, vmap, maxSearchDist), GetGameObjectFloor(phaseShift, x, y, z, maxSearchDist));
|
||||
}
|
||||
|
||||
bool Map::IsInWater(float x, float y, float pZ, LiquidData* data) const
|
||||
@@ -2703,6 +2701,7 @@ void Map::SendInitSelf(Player* player)
|
||||
if (Transport* transport = player->GetTransport())
|
||||
{
|
||||
transport->BuildCreateUpdateBlockForPlayer(&data, player);
|
||||
player->m_visibleTransports.insert(transport->GetGUID());
|
||||
}
|
||||
|
||||
// build data for self presence in world at own client (one time for map)
|
||||
@@ -2710,9 +2709,9 @@ void Map::SendInitSelf(Player* player)
|
||||
|
||||
// build other passengers at transport also (they always visible and marked as visible and will not send at visibility update at add to map
|
||||
if (Transport* transport = player->GetTransport())
|
||||
for (Transport::PassengerSet::const_iterator itr = transport->GetPassengers().begin(); itr != transport->GetPassengers().end(); ++itr)
|
||||
if (player != (*itr) && player->HaveAtClient(*itr))
|
||||
(*itr)->BuildCreateUpdateBlockForPlayer(&data, player);
|
||||
for (WorldObject* passenger : transport->GetPassengers())
|
||||
if (player != passenger && player->HaveAtClient(passenger))
|
||||
passenger->BuildCreateUpdateBlockForPlayer(&data, player);
|
||||
|
||||
WorldPacket packet;
|
||||
data.BuildPacket(&packet);
|
||||
@@ -2723,9 +2722,14 @@ void Map::SendInitTransports(Player* player)
|
||||
{
|
||||
// Hack to send out transports
|
||||
UpdateData transData(player->GetMapId());
|
||||
for (TransportsContainer::const_iterator i = _transports.begin(); i != _transports.end(); ++i)
|
||||
if (*i != player->GetTransport() && player->IsInPhase(*i))
|
||||
(*i)->BuildCreateUpdateBlockForPlayer(&transData, player);
|
||||
for (Transport* transport : _transports)
|
||||
{
|
||||
if (transport != player->GetTransport() && player->IsInPhase(transport))
|
||||
{
|
||||
transport->BuildCreateUpdateBlockForPlayer(&transData, player);
|
||||
player->m_visibleTransports.insert(transport->GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
WorldPacket packet;
|
||||
transData.BuildPacket(&packet);
|
||||
@@ -2736,28 +2740,33 @@ void Map::SendRemoveTransports(Player* player)
|
||||
{
|
||||
// Hack to send out transports
|
||||
UpdateData transData(player->GetMapId());
|
||||
for (TransportsContainer::const_iterator i = _transports.begin(); i != _transports.end(); ++i)
|
||||
if (*i != player->GetTransport())
|
||||
(*i)->BuildOutOfRangeUpdateBlock(&transData);
|
||||
for (Transport* transport : _transports)
|
||||
{
|
||||
if (transport != player->GetTransport())
|
||||
{
|
||||
transport->BuildOutOfRangeUpdateBlock(&transData);
|
||||
player->m_visibleTransports.erase(transport->GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
WorldPacket packet;
|
||||
transData.BuildPacket(&packet);
|
||||
player->GetSession()->SendPacket(&packet);
|
||||
}
|
||||
|
||||
void Map::SendUpdateTransportVisibility(Player* player, std::set<uint32> const& previousPhases)
|
||||
void Map::SendUpdateTransportVisibility(Player* player)
|
||||
{
|
||||
// Hack to send out transports
|
||||
UpdateData transData(player->GetMapId());
|
||||
for (TransportsContainer::const_iterator i = _transports.begin(); i != _transports.end(); ++i)
|
||||
for (Transport* transport : _transports)
|
||||
{
|
||||
if (*i == player->GetTransport())
|
||||
continue;
|
||||
|
||||
if (player->IsInPhase(*i) && !Trinity::Containers::Intersects(previousPhases.begin(), previousPhases.end(), (*i)->GetPhases().begin(), (*i)->GetPhases().end()))
|
||||
(*i)->BuildCreateUpdateBlockForPlayer(&transData, player);
|
||||
else if (!player->IsInPhase(*i))
|
||||
(*i)->BuildOutOfRangeUpdateBlock(&transData);
|
||||
if (player->IsInPhase(transport))
|
||||
{
|
||||
if (player->m_visibleTransports.find(transport->GetGUID()) == player->m_visibleTransports.end())
|
||||
transport->BuildCreateUpdateBlockForPlayer(&transData, player);
|
||||
}
|
||||
else if (player->m_visibleTransports.find(transport->GetGUID()) != player->m_visibleTransports.end())
|
||||
transport->BuildOutOfRangeUpdateBlock(&transData);
|
||||
}
|
||||
|
||||
WorldPacket packet;
|
||||
@@ -3775,8 +3784,8 @@ void Map::LoadCorpseData()
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto phaseId : phases[guid])
|
||||
corpse->SetInPhase(phaseId, false, true);
|
||||
for (uint32 phaseId : phases[guid])
|
||||
PhasingHandler::AddPhase(corpse, phaseId, false);
|
||||
|
||||
AddCorpse(corpse);
|
||||
} while (result->NextRow());
|
||||
@@ -3861,7 +3870,7 @@ Corpse* Map::ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia /*=
|
||||
if (corpse->GetUInt32Value(CORPSE_FIELD_ITEM + i))
|
||||
bones->SetUInt32Value(CORPSE_FIELD_ITEM + i, 0);
|
||||
|
||||
bones->CopyPhaseFrom(corpse);
|
||||
PhasingHandler::InheritPhaseShift(bones, corpse);
|
||||
|
||||
AddCorpse(bones);
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ class InstanceScript;
|
||||
class Group;
|
||||
class InstanceSave;
|
||||
class Object;
|
||||
class PhaseShift;
|
||||
class WorldObject;
|
||||
class TempSummon;
|
||||
class Player;
|
||||
@@ -514,18 +515,18 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
|
||||
BattlegroundMap* ToBattlegroundMap() { if (IsBattlegroundOrArena()) return reinterpret_cast<BattlegroundMap*>(this); else return NULL; }
|
||||
BattlegroundMap const* ToBattlegroundMap() const { if (IsBattlegroundOrArena()) return reinterpret_cast<BattlegroundMap const*>(this); return NULL; }
|
||||
|
||||
float GetWaterOrGroundLevel(std::set<uint32> const& phases, float x, float y, float z, float* ground = nullptr, bool swim = false) const;
|
||||
float GetHeight(std::set<uint32> const& phases, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
|
||||
bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, std::set<uint32> const& phases, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const;
|
||||
float GetWaterOrGroundLevel(PhaseShift const& phaseShift, float x, float y, float z, float* ground = nullptr, bool swim = false) const;
|
||||
float GetHeight(PhaseShift const& phaseShifts, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const;
|
||||
bool isInLineOfSight(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const;
|
||||
void Balance() { _dynamicTree.balance(); }
|
||||
void RemoveGameObjectModel(const GameObjectModel& model) { _dynamicTree.remove(model); }
|
||||
void InsertGameObjectModel(const GameObjectModel& model) { _dynamicTree.insert(model); }
|
||||
bool ContainsGameObjectModel(const GameObjectModel& model) const { return _dynamicTree.contains(model);}
|
||||
float GetGameObjectFloor(std::set<uint32> phases, float x, float y, float z, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const
|
||||
float GetGameObjectFloor(PhaseShift const& phaseShift, float x, float y, float z, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const
|
||||
{
|
||||
return _dynamicTree.getHeight(x, y, z, maxSearchDist, phases);
|
||||
return _dynamicTree.getHeight(x, y, z, maxSearchDist, phaseShift);
|
||||
}
|
||||
bool getObjectHitPos(std::set<uint32> const& phases, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist);
|
||||
bool getObjectHitPos(PhaseShift const& phaseShift, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist);
|
||||
|
||||
virtual uint32 GetOwnerGuildId(uint32 /*team*/ = TEAM_OTHER) const { return 0; }
|
||||
/*
|
||||
@@ -568,7 +569,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
|
||||
|
||||
void SendInitTransports(Player* player);
|
||||
void SendRemoveTransports(Player* player);
|
||||
void SendUpdateTransportVisibility(Player* player, std::set<uint32> const& previousPhases);
|
||||
void SendUpdateTransportVisibility(Player* player);
|
||||
void SendZoneDynamicInfo(Player* player);
|
||||
|
||||
void SetZoneMusic(uint32 zoneId, uint32 musicId);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "InstanceScript.h"
|
||||
#include "MoveSpline.h"
|
||||
#include "MapManager.h"
|
||||
#include "PhasingHandler.h"
|
||||
|
||||
TransportTemplate::~TransportTemplate()
|
||||
{
|
||||
@@ -354,7 +355,7 @@ void TransportMgr::AddPathNodeToTransport(uint32 transportEntry, uint32 timeSeg,
|
||||
animNode.Path[timeSeg] = node;
|
||||
}
|
||||
|
||||
Transport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid /*= 0*/, Map* map /*= NULL*/, uint32 phaseid /*= 0*/, uint32 phasegroup /*= 0*/)
|
||||
Transport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid /*= 0*/, Map* map /*= nullptr*/, uint8 phaseUseFlags /*= 0*/, uint32 phaseId /*= 0*/, uint32 phaseGroupId /*= 0*/)
|
||||
{
|
||||
// instance case, execute GetGameObjectEntry hook
|
||||
if (map)
|
||||
@@ -395,12 +396,7 @@ Transport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (phaseid)
|
||||
trans->SetInPhase(phaseid, false, true);
|
||||
|
||||
if (phasegroup)
|
||||
for (auto ph : GetPhasesForGroup(phasegroup))
|
||||
trans->SetInPhase(ph, false, true);
|
||||
PhasingHandler::InitDbPhaseShift(trans->GetPhaseShift(), phaseUseFlags, phaseId, phaseGroupId);
|
||||
|
||||
if (MapEntry const* mapEntry = sMapStore.LookupEntry(mapId))
|
||||
{
|
||||
@@ -431,7 +427,7 @@ void TransportMgr::SpawnContinentTransports()
|
||||
|
||||
uint32 oldMSTime = getMSTime();
|
||||
|
||||
QueryResult result = WorldDatabase.Query("SELECT guid, entry, phaseid, phasegroup FROM transports");
|
||||
QueryResult result = WorldDatabase.Query("SELECT guid, entry, phaseUseFlags, phaseid, phasegroup FROM transports");
|
||||
|
||||
uint32 count = 0;
|
||||
if (result)
|
||||
@@ -441,12 +437,50 @@ void TransportMgr::SpawnContinentTransports()
|
||||
Field* fields = result->Fetch();
|
||||
ObjectGuid::LowType guid = fields[0].GetUInt32();
|
||||
uint32 entry = fields[1].GetUInt32();
|
||||
uint32 phaseid = fields[2].GetUInt32();
|
||||
uint32 phasegroup = fields[3].GetUInt32();
|
||||
uint8 phaseUseFlags = fields[2].GetUInt8();
|
||||
uint32 phaseId = fields[3].GetUInt32();
|
||||
uint32 phaseGroupId = fields[4].GetUInt32();
|
||||
|
||||
if (phaseUseFlags & ~PHASE_USE_FLAGS_ALL)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table `transports` have transport (GUID: " UI64FMTD " Entry: %u) with unknown `phaseUseFlags` set, removed unknown value.", guid, entry);
|
||||
phaseUseFlags &= PHASE_USE_FLAGS_ALL;
|
||||
}
|
||||
|
||||
if (phaseUseFlags & PHASE_USE_FLAGS_ALWAYS_VISIBLE && phaseUseFlags & PHASE_USE_FLAGS_INVERSE)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table `transports` have transport (GUID: " UI64FMTD " Entry: %u) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE,"
|
||||
" removing PHASE_USE_FLAGS_INVERSE.", guid, entry);
|
||||
phaseUseFlags &= ~PHASE_USE_FLAGS_INVERSE;
|
||||
}
|
||||
|
||||
if (phaseGroupId && phaseId)
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table `transports` have transport (GUID: " UI64FMTD " Entry: %u) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, entry);
|
||||
phaseGroupId = 0;
|
||||
}
|
||||
|
||||
if (phaseId)
|
||||
{
|
||||
if (!sPhaseStore.LookupEntry(phaseId))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table `transports` have transport (GUID: " UI64FMTD " Entry: %u) with `phaseid` %u does not exist, set to 0", guid, entry, phaseId);
|
||||
phaseId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (phaseGroupId)
|
||||
{
|
||||
if (!GetPhasesForGroup(phaseGroupId))
|
||||
{
|
||||
TC_LOG_ERROR("sql.sql", "Table `transports` have transport (GUID: " UI64FMTD " Entry: %u) with `phaseGroup` %u does not exist, set to 0", guid, entry, phaseGroupId);
|
||||
phaseGroupId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (TransportTemplate const* tInfo = GetTransportTemplate(entry))
|
||||
if (!tInfo->inInstance)
|
||||
if (CreateTransport(entry, guid, nullptr, phaseid, phasegroup))
|
||||
if (CreateTransport(entry, guid, nullptr, phaseUseFlags, phaseId, phaseGroupId))
|
||||
++count;
|
||||
|
||||
} while (result->NextRow());
|
||||
|
||||
@@ -108,7 +108,7 @@ class TC_GAME_API TransportMgr
|
||||
void LoadTransportTemplates();
|
||||
|
||||
// Creates a transport using given GameObject template entry
|
||||
Transport* CreateTransport(uint32 entry, ObjectGuid::LowType guid = 0, Map* map = nullptr, uint32 phaseid = 0, uint32 phasegroup = 0);
|
||||
Transport* CreateTransport(uint32 entry, ObjectGuid::LowType guid = 0, Map* map = nullptr, uint8 phaseUseFlags = 0, uint32 phaseId = 0, uint32 phaseGroupId = 0);
|
||||
|
||||
// Spawns all continent transports, used at core startup
|
||||
void SpawnContinentTransports();
|
||||
|
||||
@@ -213,7 +213,13 @@ enum TrinityStrings
|
||||
LANG_INVALID_GAMEOBJECT_TYPE = 176,
|
||||
LANG_GAMEOBJECT_DAMAGED = 177,
|
||||
LANG_GRID_POSITION = 178,
|
||||
// 179-185 used in 6.x branch
|
||||
LANG_PHASESHIFT_STATUS = 179,
|
||||
LANG_PHASESHIFT_PHASES = 180,
|
||||
LANG_PHASESHIFT_VISIBLE_MAP_IDS = 181,
|
||||
LANG_PHASESHIFT_UI_WORLD_MAP_AREA_SWAPS = 182,
|
||||
LANG_PHASE_FLAG_COSMETIC = 183,
|
||||
LANG_PHASE_FLAG_PERSONAL = 184,
|
||||
// 185 not used
|
||||
LANG_TRANSPORT_POSITION = 186,
|
||||
LANG_PARTIAL_GROUP_SUMMON = 187,
|
||||
// Room for more level 1 188-199 not used
|
||||
|
||||
@@ -486,7 +486,7 @@ void MotionMaster::MoveCirclePath(float x, float y, float z, float radius, bool
|
||||
if (_owner->IsFlying())
|
||||
point.z = z;
|
||||
else
|
||||
point.z = _owner->GetMap()->GetHeight(_owner->GetPhases(), point.x, point.y, z);
|
||||
point.z = _owner->GetMap()->GetHeight(_owner->GetPhaseShift(), point.x, point.y, z);
|
||||
|
||||
init.Path().push_back(point);
|
||||
}
|
||||
@@ -569,7 +569,7 @@ void MotionMaster::ResumeSplineChain(SplineChainResumeInfo const& info)
|
||||
void MotionMaster::MoveFall(uint32 id /*=0*/)
|
||||
{
|
||||
// use larger distance for vmap height search than in most other cases
|
||||
float tz = _owner->GetMap()->GetHeight(_owner->GetPhases(), _owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ(), true, MAX_FALL_DISTANCE);
|
||||
float tz = _owner->GetMap()->GetHeight(_owner->GetPhaseShift(), _owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ(), true, MAX_FALL_DISTANCE);
|
||||
if (tz <= INVALID_HEIGHT)
|
||||
{
|
||||
TC_LOG_DEBUG("misc", "MotionMaster::MoveFall: unable to retrieve a proper height at map %u (x: %f, y: %f, z: %f).",
|
||||
|
||||
@@ -63,7 +63,7 @@ void RandomMovementGenerator<Creature>::_setRandomLocation(Creature* creature)
|
||||
// Limit height change
|
||||
const float distanceZ = float(rand_norm()) * travelDistZ/2.0f;
|
||||
destZ = respZ + distanceZ;
|
||||
float levelZ = map->GetWaterOrGroundLevel(creature->GetPhases(), destX, destY, destZ-2.5f);
|
||||
float levelZ = map->GetWaterOrGroundLevel(creature->GetPhaseShift(), destX, destY, destZ-2.5f);
|
||||
|
||||
// Problem here, we must fly above the ground and water, not under. Let's try on next tick
|
||||
if (levelZ >= destZ)
|
||||
@@ -77,17 +77,17 @@ void RandomMovementGenerator<Creature>::_setRandomLocation(Creature* creature)
|
||||
|
||||
// The fastest way to get an accurate result 90% of the time.
|
||||
// Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long.
|
||||
destZ = map->GetHeight(creature->GetPhases(), destX, destY, respZ+travelDistZ-2.0f, false);
|
||||
destZ = map->GetHeight(creature->GetPhaseShift(), destX, destY, respZ+travelDistZ-2.0f, false);
|
||||
|
||||
if (std::fabs(destZ - respZ) > travelDistZ) // Map check
|
||||
{
|
||||
// Vmap Horizontal or above
|
||||
destZ = map->GetHeight(creature->GetPhases(), destX, destY, respZ - 2.0f, true);
|
||||
destZ = map->GetHeight(creature->GetPhaseShift(), destX, destY, respZ - 2.0f, true);
|
||||
|
||||
if (std::fabs(destZ - respZ) > travelDistZ)
|
||||
{
|
||||
// Vmap Higher
|
||||
destZ = map->GetHeight(creature->GetPhases(), destX, destY, respZ+travelDistZ-2.0f, true);
|
||||
destZ = map->GetHeight(creature->GetPhaseShift(), destX, destY, respZ+travelDistZ-2.0f, true);
|
||||
|
||||
// let's forget this bad coords where a z cannot be find and retry at next tick
|
||||
if (std::fabs(destZ - respZ) > travelDistZ)
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PhaseShift.h"
|
||||
#include "Containers.h"
|
||||
|
||||
bool PhaseShift::AddPhase(uint32 phaseId, PhaseFlags flags, PhaseInfoStruct const* phase, std::vector<Condition*> const* areaConditions, int32 references /*= 1*/)
|
||||
{
|
||||
auto insertResult = Phases.emplace(phaseId, flags, phase, nullptr);
|
||||
ModifyPhasesReferences(insertResult.first, references);
|
||||
if (areaConditions)
|
||||
insertResult.first->AreaConditions = areaConditions;
|
||||
|
||||
return insertResult.second;
|
||||
}
|
||||
|
||||
PhaseShift::EraseResult<PhaseShift::PhaseContainer> PhaseShift::RemovePhase(uint32 phaseId)
|
||||
{
|
||||
auto itr = Phases.find(PhaseRef(phaseId, PhaseFlags::None, nullptr, nullptr));
|
||||
if (itr != Phases.end())
|
||||
{
|
||||
ModifyPhasesReferences(itr, -1);
|
||||
if (!itr->References)
|
||||
return { Phases.erase(itr), true };
|
||||
return { itr, false };
|
||||
}
|
||||
return { Phases.end(), false };
|
||||
}
|
||||
|
||||
bool PhaseShift::AddVisibleMapId(uint32 visibleMapId, TerrainSwapInfo const* visibleMapInfo, int32 references /*= 1*/)
|
||||
{
|
||||
auto insertResult = VisibleMapIds.emplace(visibleMapId, VisibleMapIdRef{ 0, visibleMapInfo });
|
||||
insertResult.first->second.References += references;
|
||||
return insertResult.second;
|
||||
}
|
||||
|
||||
PhaseShift::EraseResult<PhaseShift::VisibleMapIdContainer> PhaseShift::RemoveVisibleMapId(uint32 visibleMapId)
|
||||
{
|
||||
auto itr = VisibleMapIds.find(visibleMapId);
|
||||
if (itr != VisibleMapIds.end())
|
||||
{
|
||||
if (!--itr->second.References)
|
||||
return { VisibleMapIds.erase(itr), true };
|
||||
return { itr, false };
|
||||
}
|
||||
return { VisibleMapIds.end(), false };
|
||||
}
|
||||
|
||||
bool PhaseShift::AddUiWorldMapAreaIdSwap(uint32 uiWorldMapAreaId, int32 references /*= 1*/)
|
||||
{
|
||||
auto insertResult = UiWorldMapAreaIdSwaps.emplace(uiWorldMapAreaId, UiWorldMapAreaIdSwapRef{ 0 });
|
||||
insertResult.first->second.References += references;
|
||||
return insertResult.second;
|
||||
}
|
||||
|
||||
PhaseShift::EraseResult<PhaseShift::UiWorldMapAreaIdSwapContainer> PhaseShift::RemoveUiWorldMapAreaIdSwap(uint32 uiWorldMapAreaId)
|
||||
{
|
||||
auto itr = UiWorldMapAreaIdSwaps.find(uiWorldMapAreaId);
|
||||
if (itr != UiWorldMapAreaIdSwaps.end())
|
||||
{
|
||||
if (!--itr->second.References)
|
||||
return { UiWorldMapAreaIdSwaps.erase(itr), true };
|
||||
return { itr, false };
|
||||
}
|
||||
return { UiWorldMapAreaIdSwaps.end(), false };
|
||||
}
|
||||
|
||||
void PhaseShift::Clear()
|
||||
{
|
||||
ClearPhases();
|
||||
PersonalGuid.Clear();
|
||||
VisibleMapIds.clear();
|
||||
UiWorldMapAreaIdSwaps.clear();
|
||||
}
|
||||
|
||||
void PhaseShift::ClearPhases()
|
||||
{
|
||||
Flags &= EnumClassFlag<PhaseShiftFlags>(PhaseShiftFlags::AlwaysVisible) | PhaseShiftFlags::Inverse;
|
||||
Phases.clear();
|
||||
NonCosmeticReferences = 0;
|
||||
CosmeticReferences = 0;
|
||||
DefaultReferences = 0;
|
||||
UpdateUnphasedFlag();
|
||||
}
|
||||
|
||||
bool PhaseShift::CanSee(PhaseShift const& other) const
|
||||
{
|
||||
if (Flags.HasFlag(PhaseShiftFlags::Unphased) && other.Flags.HasFlag(PhaseShiftFlags::Unphased))
|
||||
return true;
|
||||
if (Flags.HasFlag(PhaseShiftFlags::AlwaysVisible) || other.Flags.HasFlag(PhaseShiftFlags::AlwaysVisible))
|
||||
return true;
|
||||
if (Flags.HasFlag(PhaseShiftFlags::Inverse) && other.Flags.HasFlag(PhaseShiftFlags::Inverse))
|
||||
return true;
|
||||
|
||||
PhaseFlags excludePhasesWithFlag = PhaseFlags::None;
|
||||
if (Flags.HasFlag(PhaseShiftFlags::NoCosmetic) && other.Flags.HasFlag(PhaseShiftFlags::NoCosmetic))
|
||||
excludePhasesWithFlag = PhaseFlags::Cosmetic;
|
||||
|
||||
if (!Flags.HasFlag(PhaseShiftFlags::Inverse) && !other.Flags.HasFlag(PhaseShiftFlags::Inverse))
|
||||
{
|
||||
ObjectGuid ownerGuid = PersonalGuid;
|
||||
ObjectGuid otherPersonalGuid = other.PersonalGuid;
|
||||
return Trinity::Containers::Intersects(Phases.begin(), Phases.end(), other.Phases.begin(), other.Phases.end(),
|
||||
[&ownerGuid, &otherPersonalGuid, excludePhasesWithFlag](PhaseRef const& myPhase, PhaseRef const& /*otherPhase*/)
|
||||
{
|
||||
return !myPhase.Flags.HasFlag(excludePhasesWithFlag) && (!myPhase.Flags.HasFlag(PhaseFlags::Personal) || ownerGuid == otherPersonalGuid);
|
||||
});
|
||||
}
|
||||
|
||||
auto checkInversePhaseShift = [excludePhasesWithFlag](PhaseShift const& phaseShift, PhaseShift const& excludedPhaseShift)
|
||||
{
|
||||
if (phaseShift.Flags.HasFlag(PhaseShiftFlags::Unphased) && !excludedPhaseShift.Flags.HasFlag(PhaseShiftFlags::InverseUnphased))
|
||||
return true;
|
||||
|
||||
for (auto itr = phaseShift.Phases.begin(); itr != phaseShift.Phases.end(); ++itr)
|
||||
{
|
||||
if (itr->Flags.HasFlag(excludePhasesWithFlag))
|
||||
continue;
|
||||
|
||||
auto itr2 = std::find(excludedPhaseShift.Phases.begin(), excludedPhaseShift.Phases.end(), *itr);
|
||||
if (itr2 == excludedPhaseShift.Phases.end() || itr2->Flags.HasFlag(excludePhasesWithFlag))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
if (other.Flags.HasFlag(PhaseShiftFlags::Inverse))
|
||||
return checkInversePhaseShift(*this, other);
|
||||
|
||||
return checkInversePhaseShift(other, *this);
|
||||
}
|
||||
|
||||
void PhaseShift::ModifyPhasesReferences(PhaseContainer::iterator itr, int32 references)
|
||||
{
|
||||
itr->References += references;
|
||||
|
||||
if (!IsDbPhaseShift)
|
||||
{
|
||||
if (itr->Flags.HasFlag(PhaseFlags::Cosmetic))
|
||||
CosmeticReferences += references;
|
||||
else if (itr->Id != DEFAULT_PHASE)
|
||||
NonCosmeticReferences += references;
|
||||
else
|
||||
DefaultReferences += references;
|
||||
|
||||
if (CosmeticReferences)
|
||||
Flags |= PhaseShiftFlags::NoCosmetic;
|
||||
else
|
||||
Flags &= ~EnumClassFlag<PhaseShiftFlags>(PhaseShiftFlags::NoCosmetic);
|
||||
|
||||
UpdateUnphasedFlag();
|
||||
}
|
||||
}
|
||||
|
||||
void PhaseShift::UpdateUnphasedFlag()
|
||||
{
|
||||
EnumClassFlag<PhaseShiftFlags> unphasedFlag = !Flags.HasFlag(PhaseShiftFlags::Inverse) ? PhaseShiftFlags::Unphased : PhaseShiftFlags::InverseUnphased;
|
||||
Flags &= ~EnumClassFlag<PhaseShiftFlags>(!Flags.HasFlag(PhaseShiftFlags::Inverse) ? PhaseShiftFlags::InverseUnphased : PhaseShiftFlags::Unphased);
|
||||
if (NonCosmeticReferences && !DefaultReferences)
|
||||
Flags &= ~unphasedFlag;
|
||||
else
|
||||
Flags |= unphasedFlag;
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PhaseShift_h__
|
||||
#define PhaseShift_h__
|
||||
|
||||
#include "Define.h"
|
||||
#include "EnumClassFlag.h"
|
||||
#include "ObjectGuid.h"
|
||||
#include <boost/container/flat_set.hpp>
|
||||
#include <map>
|
||||
|
||||
class PhasingHandler;
|
||||
struct Condition;
|
||||
struct PhaseInfoStruct;
|
||||
struct TerrainSwapInfo;
|
||||
|
||||
#define DEFAULT_PHASE 169
|
||||
|
||||
enum class PhaseShiftFlags : uint32
|
||||
{
|
||||
None = 0x00,
|
||||
AlwaysVisible = 0x01, // Ignores all phasing, can see everything and be seen by everything
|
||||
Inverse = 0x02, // By default having at least one shared phase for two objects means they can see each other
|
||||
// this flag makes objects see each other if they have at least one non-shared phase
|
||||
InverseUnphased = 0x04,
|
||||
Unphased = 0x08,
|
||||
NoCosmetic = 0x10 // This flag ignores shared cosmetic phases (two players that both have shared cosmetic phase but no other phase cannot see each other)
|
||||
};
|
||||
|
||||
enum class PhaseFlags : uint16
|
||||
{
|
||||
None = 0x0,
|
||||
Cosmetic = 0x1,
|
||||
Personal = 0x2
|
||||
};
|
||||
|
||||
class TC_GAME_API PhaseShift
|
||||
{
|
||||
public:
|
||||
struct PhaseRef
|
||||
{
|
||||
PhaseRef(uint32 id, PhaseFlags flags, PhaseInfoStruct const* phaseInfo, std::vector<Condition*> const* conditions)
|
||||
: Id(id), Flags(flags), References(0), PhaseInfo(phaseInfo), AreaConditions(conditions) { }
|
||||
|
||||
uint16 Id;
|
||||
EnumClassFlag<PhaseFlags> Flags;
|
||||
int32 References;
|
||||
PhaseInfoStruct const* PhaseInfo;
|
||||
std::vector<Condition*> const* AreaConditions;
|
||||
bool operator<(PhaseRef const& right) const { return Id < right.Id; }
|
||||
bool operator==(PhaseRef const& right) const { return Id == right.Id; }
|
||||
};
|
||||
struct VisibleMapIdRef
|
||||
{
|
||||
int32 References = 0;
|
||||
TerrainSwapInfo const* VisibleMapInfo = nullptr;
|
||||
};
|
||||
struct UiWorldMapAreaIdSwapRef
|
||||
{
|
||||
int32 References = 0;
|
||||
};
|
||||
template<typename Container>
|
||||
struct EraseResult
|
||||
{
|
||||
typename Container::iterator Iterator;
|
||||
bool Erased;
|
||||
};
|
||||
typedef boost::container::flat_set<PhaseRef> PhaseContainer;
|
||||
typedef std::map<uint32, VisibleMapIdRef> VisibleMapIdContainer;
|
||||
typedef std::map<uint32, UiWorldMapAreaIdSwapRef> UiWorldMapAreaIdSwapContainer;
|
||||
|
||||
bool AddPhase(uint32 phaseId, PhaseFlags flags, PhaseInfoStruct const* phase, std::vector<Condition*> const* areaConditions, int32 references = 1);
|
||||
EraseResult<PhaseContainer> RemovePhase(uint32 phaseId);
|
||||
bool HasPhase(uint32 phaseId) const { return Phases.find(PhaseRef(phaseId, PhaseFlags::None, nullptr, nullptr)) != Phases.end(); }
|
||||
PhaseContainer const& GetPhases() const { return Phases; }
|
||||
|
||||
bool AddVisibleMapId(uint32 visibleMapId, TerrainSwapInfo const* visibleMapInfo, int32 references = 1);
|
||||
EraseResult<VisibleMapIdContainer> RemoveVisibleMapId(uint32 visibleMapId);
|
||||
bool HasVisibleMapId(uint32 visibleMapId) const { return VisibleMapIds.find(visibleMapId) != VisibleMapIds.end(); }
|
||||
VisibleMapIdContainer const& GetVisibleMapIds() const { return VisibleMapIds; }
|
||||
|
||||
bool AddUiWorldMapAreaIdSwap(uint32 uiWorldMapAreaId, int32 references = 1);
|
||||
EraseResult<UiWorldMapAreaIdSwapContainer> RemoveUiWorldMapAreaIdSwap(uint32 uiWorldMapAreaId);
|
||||
bool HasUiWorldMapAreaIdSwap(uint32 uiWorldMapAreaId) const { return UiWorldMapAreaIdSwaps.find(uiWorldMapAreaId) != UiWorldMapAreaIdSwaps.end(); }
|
||||
UiWorldMapAreaIdSwapContainer const& GetUiWorldMapAreaIdSwaps() const { return UiWorldMapAreaIdSwaps; }
|
||||
|
||||
void Clear();
|
||||
void ClearPhases();
|
||||
|
||||
bool CanSee(PhaseShift const& other) const;
|
||||
|
||||
protected:
|
||||
friend class PhasingHandler;
|
||||
|
||||
EnumClassFlag<PhaseShiftFlags> Flags = PhaseShiftFlags::Unphased;
|
||||
ObjectGuid PersonalGuid;
|
||||
PhaseContainer Phases;
|
||||
VisibleMapIdContainer VisibleMapIds;
|
||||
UiWorldMapAreaIdSwapContainer UiWorldMapAreaIdSwaps;
|
||||
|
||||
void ModifyPhasesReferences(PhaseContainer::iterator itr, int32 references);
|
||||
void UpdateUnphasedFlag();
|
||||
int32 NonCosmeticReferences = 0;
|
||||
int32 CosmeticReferences = 0;
|
||||
int32 DefaultReferences = 0;
|
||||
bool IsDbPhaseShift = false;
|
||||
};
|
||||
|
||||
#endif // PhaseShift_h__
|
||||
@@ -0,0 +1,566 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PhasingHandler.h"
|
||||
#include "Chat.h"
|
||||
#include "ConditionMgr.h"
|
||||
#include "Creature.h"
|
||||
#include "DBCStores.h"
|
||||
#include "Language.h"
|
||||
#include "Map.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "PhaseShift.h"
|
||||
#include "Player.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
inline PhaseFlags GetPhaseFlags(uint32 phaseId)
|
||||
{
|
||||
if (PhaseEntry const* phase = sPhaseStore.LookupEntry(phaseId))
|
||||
{
|
||||
if (phase->Flags & PHASE_FLAG_COSMETIC)
|
||||
return PhaseFlags::Cosmetic;
|
||||
|
||||
if (phase->Flags & PHASE_FLAG_PERSONAL)
|
||||
return PhaseFlags::Personal;
|
||||
}
|
||||
|
||||
return PhaseFlags::None;
|
||||
}
|
||||
|
||||
template<typename Func>
|
||||
inline void ForAllControlled(Unit* unit, Func&& func)
|
||||
{
|
||||
for (Unit* controlled : unit->m_Controlled)
|
||||
if (controlled->GetTypeId() != TYPEID_PLAYER)
|
||||
func(controlled);
|
||||
|
||||
for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i)
|
||||
if (!unit->m_SummonSlot[i].IsEmpty())
|
||||
if (Creature* summon = unit->GetMap()->GetCreature(unit->m_SummonSlot[i]))
|
||||
func(summon);
|
||||
}
|
||||
}
|
||||
|
||||
void PhasingHandler::AddPhase(WorldObject* object, uint32 phaseId, bool updateVisibility)
|
||||
{
|
||||
bool changed = object->GetPhaseShift().AddPhase(phaseId, GetPhaseFlags(phaseId), sObjectMgr->GetPhaseInfo(phaseId), nullptr);
|
||||
|
||||
if (Unit* unit = object->ToUnit())
|
||||
{
|
||||
unit->OnPhaseChange();
|
||||
ForAllControlled(unit, [&](Unit* controlled)
|
||||
{
|
||||
AddPhase(controlled, phaseId, updateVisibility);
|
||||
});
|
||||
unit->RemoveNotOwnSingleTargetAuras(true);
|
||||
}
|
||||
|
||||
UpdateVisibilityIfNeeded(object, updateVisibility, changed);
|
||||
}
|
||||
|
||||
void PhasingHandler::RemovePhase(WorldObject* object, uint32 phaseId, bool updateVisibility)
|
||||
{
|
||||
bool changed = object->GetPhaseShift().RemovePhase(phaseId).Erased;
|
||||
|
||||
if (Unit* unit = object->ToUnit())
|
||||
{
|
||||
unit->OnPhaseChange();
|
||||
ForAllControlled(unit, [&](Unit* controlled)
|
||||
{
|
||||
RemovePhase(controlled, phaseId, updateVisibility);
|
||||
});
|
||||
unit->RemoveNotOwnSingleTargetAuras(true);
|
||||
}
|
||||
|
||||
UpdateVisibilityIfNeeded(object, updateVisibility, changed);
|
||||
}
|
||||
|
||||
void PhasingHandler::AddPhaseGroup(WorldObject* object, uint32 phaseGroupId, bool updateVisibility)
|
||||
{
|
||||
std::vector<uint32> const* phasesInGroup = GetPhasesForGroup(phaseGroupId);
|
||||
if (!phasesInGroup)
|
||||
return;
|
||||
|
||||
bool changed = false;
|
||||
for (uint32 phaseId : *phasesInGroup)
|
||||
changed = object->GetPhaseShift().AddPhase(phaseId, GetPhaseFlags(phaseId), sObjectMgr->GetPhaseInfo(phaseId), nullptr) || changed;
|
||||
|
||||
if (Unit* unit = object->ToUnit())
|
||||
{
|
||||
unit->OnPhaseChange();
|
||||
ForAllControlled(unit, [&](Unit* controlled)
|
||||
{
|
||||
AddPhaseGroup(controlled, phaseGroupId, updateVisibility);
|
||||
});
|
||||
unit->RemoveNotOwnSingleTargetAuras(true);
|
||||
}
|
||||
|
||||
UpdateVisibilityIfNeeded(object, updateVisibility, changed);
|
||||
}
|
||||
|
||||
void PhasingHandler::RemovePhaseGroup(WorldObject* object, uint32 phaseGroupId, bool updateVisibility)
|
||||
{
|
||||
std::vector<uint32> const* phasesInGroup = GetPhasesForGroup(phaseGroupId);
|
||||
if (!phasesInGroup)
|
||||
return;
|
||||
|
||||
bool changed = false;
|
||||
for (uint32 phaseId : *phasesInGroup)
|
||||
changed = object->GetPhaseShift().RemovePhase(phaseId).Erased || changed;
|
||||
|
||||
if (Unit* unit = object->ToUnit())
|
||||
{
|
||||
unit->OnPhaseChange();
|
||||
ForAllControlled(unit, [&](Unit* controlled)
|
||||
{
|
||||
RemovePhaseGroup(controlled, phaseGroupId, updateVisibility);
|
||||
});
|
||||
unit->RemoveNotOwnSingleTargetAuras(true);
|
||||
}
|
||||
|
||||
UpdateVisibilityIfNeeded(object, updateVisibility, changed);
|
||||
}
|
||||
|
||||
void PhasingHandler::AddVisibleMapId(WorldObject* object, uint32 visibleMapId)
|
||||
{
|
||||
TerrainSwapInfo const* terrainSwapInfo = sObjectMgr->GetTerrainSwapInfo(visibleMapId);
|
||||
bool changed = object->GetPhaseShift().AddVisibleMapId(visibleMapId, terrainSwapInfo);
|
||||
|
||||
for (uint32 uiWorldMapAreaIDSwap : terrainSwapInfo->UiWorldMapAreaIDSwaps)
|
||||
changed = object->GetPhaseShift().AddUiWorldMapAreaIdSwap(uiWorldMapAreaIDSwap) || changed;
|
||||
|
||||
if (Unit* unit = object->ToUnit())
|
||||
{
|
||||
ForAllControlled(unit, [&](Unit* controlled)
|
||||
{
|
||||
AddVisibleMapId(controlled, visibleMapId);
|
||||
});
|
||||
}
|
||||
|
||||
UpdateVisibilityIfNeeded(object, false, changed);
|
||||
}
|
||||
|
||||
void PhasingHandler::RemoveVisibleMapId(WorldObject* object, uint32 visibleMapId)
|
||||
{
|
||||
TerrainSwapInfo const* terrainSwapInfo = sObjectMgr->GetTerrainSwapInfo(visibleMapId);
|
||||
bool changed = object->GetPhaseShift().RemoveVisibleMapId(visibleMapId).Erased;
|
||||
|
||||
for (uint32 uiWorldMapAreaIDSwap : terrainSwapInfo->UiWorldMapAreaIDSwaps)
|
||||
changed = object->GetPhaseShift().RemoveUiWorldMapAreaIdSwap(uiWorldMapAreaIDSwap).Erased || changed;
|
||||
|
||||
if (Unit* unit = object->ToUnit())
|
||||
{
|
||||
ForAllControlled(unit, [&](Unit* controlled)
|
||||
{
|
||||
RemoveVisibleMapId(controlled, visibleMapId);
|
||||
});
|
||||
}
|
||||
|
||||
UpdateVisibilityIfNeeded(object, false, changed);
|
||||
}
|
||||
|
||||
void PhasingHandler::ResetPhaseShift(WorldObject* object)
|
||||
{
|
||||
object->GetPhaseShift().Clear();
|
||||
object->GetSuppressedPhaseShift().Clear();
|
||||
}
|
||||
|
||||
void PhasingHandler::InheritPhaseShift(WorldObject* target, WorldObject const* source)
|
||||
{
|
||||
target->GetPhaseShift() = source->GetPhaseShift();
|
||||
target->GetSuppressedPhaseShift() = source->GetSuppressedPhaseShift();
|
||||
}
|
||||
|
||||
void PhasingHandler::OnMapChange(WorldObject* object)
|
||||
{
|
||||
PhaseShift& phaseShift = object->GetPhaseShift();
|
||||
PhaseShift& suppressedPhaseShift = object->GetSuppressedPhaseShift();
|
||||
ConditionSourceInfo srcInfo = ConditionSourceInfo(object);
|
||||
|
||||
object->GetPhaseShift().VisibleMapIds.clear();
|
||||
object->GetPhaseShift().UiWorldMapAreaIdSwaps.clear();
|
||||
object->GetSuppressedPhaseShift().VisibleMapIds.clear();
|
||||
|
||||
if (std::vector<TerrainSwapInfo*> const* visibleMapIds = sObjectMgr->GetTerrainSwapsForMap(object->GetMapId()))
|
||||
{
|
||||
for (TerrainSwapInfo const* visibleMapInfo : *visibleMapIds)
|
||||
{
|
||||
if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, visibleMapInfo->Id, srcInfo))
|
||||
{
|
||||
phaseShift.AddVisibleMapId(visibleMapInfo->Id, visibleMapInfo);
|
||||
for (uint32 uiWorldMapAreaIdSwap : visibleMapInfo->UiWorldMapAreaIDSwaps)
|
||||
phaseShift.AddUiWorldMapAreaIdSwap(uiWorldMapAreaIdSwap);
|
||||
}
|
||||
else
|
||||
suppressedPhaseShift.AddVisibleMapId(visibleMapInfo->Id, visibleMapInfo);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateVisibilityIfNeeded(object, false, true);
|
||||
}
|
||||
|
||||
void PhasingHandler::OnAreaChange(WorldObject* object)
|
||||
{
|
||||
PhaseShift& phaseShift = object->GetPhaseShift();
|
||||
PhaseShift& suppressedPhaseShift = object->GetSuppressedPhaseShift();
|
||||
PhaseShift::PhaseContainer oldPhases = std::move(phaseShift.Phases); // for comparison
|
||||
ConditionSourceInfo srcInfo = ConditionSourceInfo(object);
|
||||
|
||||
object->GetPhaseShift().ClearPhases();
|
||||
object->GetSuppressedPhaseShift().ClearPhases();
|
||||
|
||||
AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(object->GetAreaId());
|
||||
while (areaEntry)
|
||||
{
|
||||
if (std::vector<PhaseAreaInfo> const* newAreaPhases = sObjectMgr->GetPhasesForArea(areaEntry->ID))
|
||||
{
|
||||
for (PhaseAreaInfo const& phaseArea : *newAreaPhases)
|
||||
{
|
||||
if (phaseArea.SubAreaExclusions.find(areaEntry->ID) != phaseArea.SubAreaExclusions.end())
|
||||
continue;
|
||||
|
||||
uint32 phaseId = phaseArea.PhaseInfo->Id;
|
||||
if (sConditionMgr->IsObjectMeetToConditions(srcInfo, phaseArea.Conditions))
|
||||
phaseShift.AddPhase(phaseArea.PhaseInfo->Id, GetPhaseFlags(phaseId), phaseArea.PhaseInfo, &phaseArea.Conditions);
|
||||
else
|
||||
suppressedPhaseShift.AddPhase(phaseArea.PhaseInfo->Id, GetPhaseFlags(phaseId), phaseArea.PhaseInfo, &phaseArea.Conditions);
|
||||
}
|
||||
}
|
||||
|
||||
areaEntry = sAreaTableStore.LookupEntry(areaEntry->zone);
|
||||
}
|
||||
|
||||
bool changed = phaseShift.Phases != oldPhases;
|
||||
if (Unit* unit = object->ToUnit())
|
||||
{
|
||||
for (AuraEffect const* aurEff : unit->GetAuraEffectsByType(SPELL_AURA_PHASE))
|
||||
{
|
||||
uint32 phaseId = uint32(aurEff->GetMiscValueB());
|
||||
changed = phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), sObjectMgr->GetPhaseInfo(phaseId), nullptr) || changed;
|
||||
}
|
||||
|
||||
for (AuraEffect const* aurEff : unit->GetAuraEffectsByType(SPELL_AURA_PHASE_GROUP))
|
||||
if (std::vector<uint32> const* phasesInGroup = GetPhasesForGroup(uint32(aurEff->GetMiscValueB())))
|
||||
for (uint32 phaseId : *phasesInGroup)
|
||||
changed = phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), sObjectMgr->GetPhaseInfo(phaseId), nullptr) || changed;
|
||||
|
||||
if (changed)
|
||||
unit->OnPhaseChange();
|
||||
|
||||
ForAllControlled(unit, [&](Unit* controlled)
|
||||
{
|
||||
InheritPhaseShift(controlled, unit);
|
||||
});
|
||||
|
||||
if (changed)
|
||||
unit->RemoveNotOwnSingleTargetAuras(true);
|
||||
}
|
||||
|
||||
UpdateVisibilityIfNeeded(object, true, changed);
|
||||
}
|
||||
|
||||
void PhasingHandler::OnConditionChange(WorldObject* object)
|
||||
{
|
||||
PhaseShift& phaseShift = object->GetPhaseShift();
|
||||
PhaseShift& suppressedPhaseShift = object->GetSuppressedPhaseShift();
|
||||
PhaseShift newSuppressions;
|
||||
ConditionSourceInfo srcInfo = ConditionSourceInfo(object);
|
||||
bool changed = false;
|
||||
|
||||
for (auto itr = phaseShift.Phases.begin(); itr != phaseShift.Phases.end();)
|
||||
{
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(srcInfo, *itr->AreaConditions))
|
||||
{
|
||||
newSuppressions.AddPhase(itr->Id, itr->Flags, itr->PhaseInfo, itr->AreaConditions, itr->References);
|
||||
itr = phaseShift.Phases.erase(itr);
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
|
||||
for (auto itr = suppressedPhaseShift.Phases.begin(); itr != suppressedPhaseShift.Phases.end();)
|
||||
{
|
||||
if (sConditionMgr->IsObjectMeetToConditions(srcInfo, *itr->AreaConditions))
|
||||
{
|
||||
changed = phaseShift.AddPhase(itr->Id, itr->Flags, itr->PhaseInfo, itr->AreaConditions, itr->References) || changed;
|
||||
itr = suppressedPhaseShift.Phases.erase(itr);
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
|
||||
for (auto itr = phaseShift.VisibleMapIds.begin(); itr != phaseShift.VisibleMapIds.end();)
|
||||
{
|
||||
if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, itr->first, srcInfo))
|
||||
{
|
||||
newSuppressions.AddVisibleMapId(itr->first, itr->second.VisibleMapInfo, itr->second.References);
|
||||
for (uint32 uiWorldMapAreaIdSwap : itr->second.VisibleMapInfo->UiWorldMapAreaIDSwaps)
|
||||
changed = phaseShift.RemoveUiWorldMapAreaIdSwap(uiWorldMapAreaIdSwap).Erased || changed;
|
||||
|
||||
itr = phaseShift.VisibleMapIds.erase(itr);
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
|
||||
for (auto itr = suppressedPhaseShift.VisibleMapIds.begin(); itr != suppressedPhaseShift.VisibleMapIds.end();)
|
||||
{
|
||||
if (sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, itr->first, srcInfo))
|
||||
{
|
||||
changed = phaseShift.AddVisibleMapId(itr->first, itr->second.VisibleMapInfo, itr->second.References) || changed;
|
||||
for (uint32 uiWorldMapAreaIdSwap : itr->second.VisibleMapInfo->UiWorldMapAreaIDSwaps)
|
||||
changed = phaseShift.AddUiWorldMapAreaIdSwap(uiWorldMapAreaIdSwap) || changed;
|
||||
|
||||
itr = suppressedPhaseShift.VisibleMapIds.erase(itr);
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
|
||||
Unit* unit = object->ToUnit();
|
||||
if (unit)
|
||||
{
|
||||
for (AuraEffect const* aurEff : unit->GetAuraEffectsByType(SPELL_AURA_PHASE))
|
||||
{
|
||||
uint32 phaseId = uint32(aurEff->GetMiscValueB());
|
||||
phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), sObjectMgr->GetPhaseInfo(phaseId), nullptr);
|
||||
newSuppressions.RemovePhase(phaseId);
|
||||
}
|
||||
|
||||
for (AuraEffect const* aurEff : unit->GetAuraEffectsByType(SPELL_AURA_PHASE_GROUP))
|
||||
{
|
||||
if (std::vector<uint32> const* phasesInGroup = GetPhasesForGroup(uint32(aurEff->GetMiscValueB())))
|
||||
{
|
||||
for (uint32 phaseId : *phasesInGroup)
|
||||
{
|
||||
phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), sObjectMgr->GetPhaseInfo(phaseId), nullptr);
|
||||
newSuppressions.RemovePhase(phaseId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
changed = changed || !newSuppressions.Phases.empty() || !newSuppressions.VisibleMapIds.empty();
|
||||
for (auto itr = newSuppressions.Phases.begin(); itr != newSuppressions.Phases.end(); ++itr)
|
||||
suppressedPhaseShift.AddPhase(itr->Id, itr->Flags, itr->PhaseInfo, itr->AreaConditions, itr->References);
|
||||
|
||||
for (auto itr = newSuppressions.VisibleMapIds.begin(); itr != newSuppressions.VisibleMapIds.end(); ++itr)
|
||||
suppressedPhaseShift.AddVisibleMapId(itr->first, itr->second.VisibleMapInfo, itr->second.References);
|
||||
|
||||
if (unit)
|
||||
{
|
||||
if (changed)
|
||||
unit->OnPhaseChange();
|
||||
|
||||
ForAllControlled(unit, [&](Unit* controlled)
|
||||
{
|
||||
InheritPhaseShift(controlled, unit);
|
||||
});
|
||||
|
||||
if (changed)
|
||||
unit->RemoveNotOwnSingleTargetAuras(true);
|
||||
}
|
||||
|
||||
UpdateVisibilityIfNeeded(object, true, changed);
|
||||
}
|
||||
|
||||
void PhasingHandler::SendToPlayer(Player const* player, PhaseShift const& phaseShift)
|
||||
{
|
||||
ObjectGuid guid = player->GetGUID();
|
||||
|
||||
WorldPacket data(SMSG_SET_PHASE_SHIFT, 1 + 8 + 4 + 4 + 4 + 4 + 2 * phaseShift.Phases.size() + 4 + phaseShift.VisibleMapIds.size() * 2);
|
||||
data.WriteBit(guid[2]);
|
||||
data.WriteBit(guid[3]);
|
||||
data.WriteBit(guid[1]);
|
||||
data.WriteBit(guid[6]);
|
||||
data.WriteBit(guid[4]);
|
||||
data.WriteBit(guid[5]);
|
||||
data.WriteBit(guid[0]);
|
||||
data.WriteBit(guid[7]);
|
||||
|
||||
data.WriteByteSeq(guid[7]);
|
||||
data.WriteByteSeq(guid[4]);
|
||||
|
||||
data << uint32(phaseShift.UiWorldMapAreaIdSwaps.size()) * 2;
|
||||
for (auto itr = phaseShift.UiWorldMapAreaIdSwaps.begin(); itr != phaseShift.UiWorldMapAreaIdSwaps.end(); ++itr)
|
||||
data << uint16(itr->first); // WorldMapArea.dbc id (controls map display)
|
||||
|
||||
data.WriteByteSeq(guid[1]);
|
||||
|
||||
data << uint32(phaseShift.Flags.AsUnderlyingType()); // flags
|
||||
|
||||
data.WriteByteSeq(guid[2]);
|
||||
data.WriteByteSeq(guid[6]);
|
||||
|
||||
data << uint32(0); // Inactive terrain swaps
|
||||
//for (uint8 i = 0; i < inactiveSwapsCount; ++i)
|
||||
// data << uint16(0);
|
||||
|
||||
data << uint32(phaseShift.Phases.size()) * 2; // Phase.dbc ids
|
||||
for (auto itr = phaseShift.Phases.begin(); itr != phaseShift.Phases.end(); ++itr)
|
||||
data << uint16(itr->Id);
|
||||
|
||||
data.WriteByteSeq(guid[3]);
|
||||
data.WriteByteSeq(guid[0]);
|
||||
|
||||
data << uint32(phaseShift.VisibleMapIds.size()) * 2; // Active terrain swaps
|
||||
for (auto itr = phaseShift.VisibleMapIds.begin(); itr != phaseShift.VisibleMapIds.end(); ++itr)
|
||||
data << uint16(itr->first);
|
||||
|
||||
data.WriteByteSeq(guid[5]);
|
||||
|
||||
player->SendDirectMessage(&data);
|
||||
}
|
||||
|
||||
void PhasingHandler::SendToPlayer(Player const* player)
|
||||
{
|
||||
SendToPlayer(player, player->GetPhaseShift());
|
||||
}
|
||||
|
||||
void PhasingHandler::FillPartyMemberPhase(WorldPacket* data, PhaseShift const& phaseShift)
|
||||
{
|
||||
*data << uint32(phaseShift.Flags.AsUnderlyingType());
|
||||
*data << uint32(phaseShift.Phases.size());
|
||||
for (auto itr = phaseShift.Phases.begin(); itr != phaseShift.Phases.end(); ++itr)
|
||||
*data << uint16(itr->Id);
|
||||
}
|
||||
|
||||
void PhasingHandler::InitDbPhaseShift(PhaseShift& phaseShift, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId)
|
||||
{
|
||||
phaseShift.IsDbPhaseShift = true;
|
||||
|
||||
EnumClassFlag<PhaseShiftFlags> flags = PhaseShiftFlags::None;
|
||||
if (phaseUseFlags & PHASE_USE_FLAGS_ALWAYS_VISIBLE)
|
||||
flags = flags | PhaseShiftFlags::AlwaysVisible | PhaseShiftFlags::Unphased;
|
||||
if (phaseUseFlags & PHASE_USE_FLAGS_INVERSE)
|
||||
flags |= PhaseShiftFlags::Inverse;
|
||||
|
||||
if (phaseId)
|
||||
phaseShift.AddPhase(phaseId, GetPhaseFlags(phaseId), sObjectMgr->GetPhaseInfo(phaseId), nullptr);
|
||||
else if (std::vector<uint32> const* phasesInGroup = GetPhasesForGroup(phaseGroupId))
|
||||
for (uint32 phaseInGroup : *phasesInGroup)
|
||||
phaseShift.AddPhase(phaseInGroup, GetPhaseFlags(phaseInGroup), sObjectMgr->GetPhaseInfo(phaseInGroup), nullptr);
|
||||
|
||||
if (phaseShift.Phases.empty() || phaseShift.HasPhase(DEFAULT_PHASE))
|
||||
{
|
||||
if (flags.HasFlag(PhaseShiftFlags::Inverse))
|
||||
flags |= PhaseShiftFlags::InverseUnphased;
|
||||
else
|
||||
flags |= PhaseShiftFlags::Unphased;
|
||||
}
|
||||
|
||||
phaseShift.Flags = flags;
|
||||
}
|
||||
|
||||
void PhasingHandler::InitDbVisibleMapId(PhaseShift& phaseShift, int32 visibleMapId)
|
||||
{
|
||||
if (visibleMapId != -1)
|
||||
phaseShift.AddVisibleMapId(visibleMapId, sObjectMgr->GetTerrainSwapInfo(visibleMapId));
|
||||
}
|
||||
|
||||
bool PhasingHandler::InDbPhaseShift(WorldObject const* object, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId)
|
||||
{
|
||||
PhaseShift phaseShift;
|
||||
InitDbPhaseShift(phaseShift, phaseUseFlags, phaseId, phaseGroupId);
|
||||
return object->GetPhaseShift().CanSee(phaseShift);
|
||||
}
|
||||
|
||||
void PhasingHandler::SetAlwaysVisible(PhaseShift& phaseShift, bool apply)
|
||||
{
|
||||
if (apply)
|
||||
phaseShift.Flags |= PhaseShiftFlags::AlwaysVisible;
|
||||
else
|
||||
phaseShift.Flags &= ~EnumClassFlag<PhaseShiftFlags>(PhaseShiftFlags::AlwaysVisible);
|
||||
}
|
||||
|
||||
void PhasingHandler::SetInversed(PhaseShift& phaseShift, bool apply)
|
||||
{
|
||||
if (apply)
|
||||
phaseShift.Flags |= PhaseShiftFlags::Inverse;
|
||||
else
|
||||
phaseShift.Flags &= ~EnumClassFlag<PhaseShiftFlags>(PhaseShiftFlags::Inverse);
|
||||
|
||||
phaseShift.UpdateUnphasedFlag();
|
||||
}
|
||||
|
||||
void PhasingHandler::PrintToChat(ChatHandler* chat, PhaseShift const& phaseShift)
|
||||
{
|
||||
chat->PSendSysMessage(LANG_PHASESHIFT_STATUS, phaseShift.Flags.AsUnderlyingType(), phaseShift.PersonalGuid.ToString().c_str());
|
||||
if (!phaseShift.Phases.empty())
|
||||
{
|
||||
std::ostringstream phases;
|
||||
std::string cosmetic = sObjectMgr->GetTrinityString(LANG_PHASE_FLAG_COSMETIC, chat->GetSessionDbLocaleIndex());
|
||||
std::string personal = sObjectMgr->GetTrinityString(LANG_PHASE_FLAG_PERSONAL, chat->GetSessionDbLocaleIndex());
|
||||
for (PhaseShift::PhaseRef const& phase : phaseShift.Phases)
|
||||
{
|
||||
phases << phase.Id;
|
||||
if (phase.Flags.HasFlag(PhaseFlags::Cosmetic))
|
||||
phases << ' ' << '(' << cosmetic << ')';
|
||||
if (phase.Flags.HasFlag(PhaseFlags::Personal))
|
||||
phases << ' ' << '(' << personal << ')';
|
||||
phases << ", ";
|
||||
}
|
||||
|
||||
chat->PSendSysMessage(LANG_PHASESHIFT_PHASES, phases.str().c_str());
|
||||
}
|
||||
|
||||
if (!phaseShift.VisibleMapIds.empty())
|
||||
{
|
||||
std::ostringstream visibleMapIds;
|
||||
for (PhaseShift::VisibleMapIdContainer::value_type const& visibleMapId : phaseShift.VisibleMapIds)
|
||||
visibleMapIds << visibleMapId.first << ',' << ' ';
|
||||
|
||||
chat->PSendSysMessage(LANG_PHASESHIFT_VISIBLE_MAP_IDS, visibleMapIds.str().c_str());
|
||||
}
|
||||
|
||||
if (!phaseShift.UiWorldMapAreaIdSwaps.empty())
|
||||
{
|
||||
std::ostringstream uiWorldMapAreaIdSwaps;
|
||||
for (PhaseShift::UiWorldMapAreaIdSwapContainer::value_type const& uiWorldMapAreaIdSwap : phaseShift.UiWorldMapAreaIdSwaps)
|
||||
uiWorldMapAreaIdSwaps << uiWorldMapAreaIdSwap.first << ',' << ' ';
|
||||
|
||||
chat->PSendSysMessage(LANG_PHASESHIFT_UI_WORLD_MAP_AREA_SWAPS, uiWorldMapAreaIdSwaps.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
std::string PhasingHandler::FormatPhases(PhaseShift const& phaseShift)
|
||||
{
|
||||
std::ostringstream phases;
|
||||
for (PhaseShift::PhaseRef const& phase : phaseShift.Phases)
|
||||
phases << phase.Id << ',';
|
||||
|
||||
return phases.str();
|
||||
}
|
||||
|
||||
void PhasingHandler::UpdateVisibilityIfNeeded(WorldObject* object, bool updateVisibility, bool changed)
|
||||
{
|
||||
if (changed && object->IsInWorld())
|
||||
{
|
||||
if (Player* player = object->ToPlayer())
|
||||
SendToPlayer(player);
|
||||
|
||||
if (updateVisibility)
|
||||
{
|
||||
if (Player* player = object->ToPlayer())
|
||||
player->GetMap()->SendUpdateTransportVisibility(player);
|
||||
|
||||
object->UpdateObjectVisibility();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PhasingHandler_h__
|
||||
#define PhasingHandler_h__
|
||||
|
||||
#include "Define.h"
|
||||
#include <string>
|
||||
|
||||
class ChatHandler;
|
||||
class PhaseShift;
|
||||
class Player;
|
||||
class WorldObject;
|
||||
|
||||
class TC_GAME_API PhasingHandler
|
||||
{
|
||||
public:
|
||||
static void AddPhase(WorldObject* object, uint32 phaseId, bool updateVisibility);
|
||||
static void RemovePhase(WorldObject* object, uint32 phaseId, bool updateVisibility);
|
||||
static void AddPhaseGroup(WorldObject* object, uint32 phaseGroupId, bool updateVisibility);
|
||||
static void RemovePhaseGroup(WorldObject* object, uint32 phaseGroupId, bool updateVisibility);
|
||||
|
||||
static void AddVisibleMapId(WorldObject* object, uint32 visibleMapId);
|
||||
static void RemoveVisibleMapId(WorldObject* object, uint32 visibleMapId);
|
||||
|
||||
static void ResetPhaseShift(WorldObject* object);
|
||||
static void InheritPhaseShift(WorldObject* target, WorldObject const* source);
|
||||
|
||||
static void OnMapChange(WorldObject* object);
|
||||
static void OnAreaChange(WorldObject* object);
|
||||
static void OnConditionChange(WorldObject* object);
|
||||
|
||||
static void SendToPlayer(Player const* player, PhaseShift const& phaseShift);
|
||||
static void SendToPlayer(Player const* player);
|
||||
static void FillPartyMemberPhase(WorldPacket* data, PhaseShift const& phaseShift);
|
||||
|
||||
static void InitDbPhaseShift(PhaseShift& phaseShift, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId);
|
||||
static void InitDbVisibleMapId(PhaseShift& phaseShift, int32 visibleMapId);
|
||||
static bool InDbPhaseShift(WorldObject const* object, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId);
|
||||
|
||||
static void SetAlwaysVisible(PhaseShift& phaseShift, bool apply);
|
||||
static void SetInversed(PhaseShift& phaseShift, bool apply);
|
||||
|
||||
static void PrintToChat(ChatHandler* chat, PhaseShift const& phaseShift);
|
||||
static std::string FormatPhases(PhaseShift const& phaseShift);
|
||||
|
||||
private:
|
||||
static void UpdateVisibilityIfNeeded(WorldObject* object, bool updateVisibility, bool changed);
|
||||
};
|
||||
|
||||
#endif // PhasingHandler_h__
|
||||
@@ -298,7 +298,6 @@ class TC_GAME_API WorldSession
|
||||
void SendPetNameInvalid(uint32 error, std::string const& name, DeclinedName *declinedName);
|
||||
void SendPartyResult(PartyOperation operation, std::string const& member, PartyResult res, uint32 val = 0);
|
||||
void SendAreaTriggerMessage(const char* Text, ...) ATTR_PRINTF(2, 3);
|
||||
void SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set<uint32> const& terrainswaps, std::set<uint32> const& worldMapAreaSwaps);
|
||||
void SendQueryTimeResponse();
|
||||
|
||||
void SendAuthResponse(uint8 code, bool queued, uint32 queuePos = 0);
|
||||
|
||||
@@ -119,7 +119,7 @@ void Archaeology::UseSite()
|
||||
float x = _player->GetPositionX() + cos(o) * 2.0f;
|
||||
float y = _player->GetPositionY() + sin(o) * 2.0f;
|
||||
float z = _player->GetPositionZ();
|
||||
float ground = _player->GetMap()->GetWaterOrGroundLevel(_player->GetPhases(), x, y, z, &ground, _player->IsInWater());
|
||||
float ground = _player->GetMap()->GetWaterOrGroundLevel(_player->GetPhaseShift(), x, y, z, &ground, _player->IsInWater());
|
||||
|
||||
G3D::Quat rot = G3D::Matrix3::fromEulerAnglesZYX(angle, 0.f, 0.f);
|
||||
if (std::abs(z - ground) < 1.5f)
|
||||
@@ -140,7 +140,7 @@ void Archaeology::UseSite()
|
||||
float x = _player->GetPositionX() + cos(o) * 2.0f;
|
||||
float y = _player->GetPositionY() + sin(o) * 2.0f;
|
||||
float z = _player->GetPositionZ();
|
||||
float ground = _player->GetMap()->GetWaterOrGroundLevel(_player->GetPhases(), x, y, z, &ground, _player->IsInWater());
|
||||
float ground = _player->GetMap()->GetWaterOrGroundLevel(_player->GetPhaseShift(), x, y, z, &ground, _player->IsInWater());
|
||||
|
||||
// Spawn object
|
||||
_player->SummonGameObject(goId, Position(x, y, ground, o), G3D::Quat(), 60);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "Log.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "Player.h"
|
||||
#include "Unit.h"
|
||||
#include "ObjectAccessor.h"
|
||||
@@ -1703,8 +1704,7 @@ void AuraEffect::HandlePhase(AuraApplication const* aurApp, uint8 mode, bool app
|
||||
|
||||
Unit* target = aurApp->GetTarget();
|
||||
|
||||
std::set<uint32> const& oldPhases = target->GetPhases();
|
||||
target->SetInPhase(GetMiscValueB(), false, apply);
|
||||
PhasingHandler::AddPhase(target, uint32(GetMiscValueB()), true);
|
||||
|
||||
// call functions which may have additional effects after chainging state of unit
|
||||
// phase auras normally not expected at BG but anyway better check
|
||||
@@ -1713,17 +1713,6 @@ void AuraEffect::HandlePhase(AuraApplication const* aurApp, uint8 mode, bool app
|
||||
// drop flag at invisibiliy in bg
|
||||
target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
|
||||
}
|
||||
|
||||
if (Player* player = target->ToPlayer())
|
||||
{
|
||||
if (player->IsInWorld())
|
||||
player->GetMap()->SendUpdateTransportVisibility(player, oldPhases);
|
||||
player->SendUpdatePhasing();
|
||||
}
|
||||
|
||||
// need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases)
|
||||
if (target->IsVisible())
|
||||
target->UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
void AuraEffect::HandlePhaseGroup(AuraApplication const* aurApp, uint8 mode, bool apply) const
|
||||
@@ -1733,10 +1722,7 @@ void AuraEffect::HandlePhaseGroup(AuraApplication const* aurApp, uint8 mode, boo
|
||||
|
||||
Unit* target = aurApp->GetTarget();
|
||||
|
||||
std::set<uint32> const& oldPhases = target->GetPhases();
|
||||
std::set<uint32> const& phases = GetPhasesForGroup(GetMiscValueB());
|
||||
for (auto phase : phases)
|
||||
target->SetInPhase(phase, false, apply);
|
||||
PhasingHandler::AddPhaseGroup(target, uint32(GetMiscValueB()), true);
|
||||
|
||||
// call functions which may have additional effects after chainging state of unit
|
||||
// phase auras normally not expected at BG but anyway better check
|
||||
@@ -1745,17 +1731,6 @@ void AuraEffect::HandlePhaseGroup(AuraApplication const* aurApp, uint8 mode, boo
|
||||
// drop flag at invisibiliy in bg
|
||||
target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
|
||||
}
|
||||
|
||||
if (Player* player = target->ToPlayer())
|
||||
{
|
||||
if (player->IsInWorld())
|
||||
player->GetMap()->SendUpdateTransportVisibility(player, oldPhases);
|
||||
player->SendUpdatePhasing();
|
||||
}
|
||||
|
||||
// need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases)
|
||||
if (target->IsVisible())
|
||||
target->UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
/**********************/
|
||||
|
||||
@@ -1303,7 +1303,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
|
||||
float angle = float(rand_norm()) * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
|
||||
m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dist, angle);
|
||||
|
||||
float ground = m_caster->GetMap()->GetHeight(m_caster->GetPhases(), x, y, z, true, 50.0f);
|
||||
float ground = m_caster->GetMap()->GetHeight(m_caster->GetPhaseShift(), x, y, z, true, 50.0f);
|
||||
float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
|
||||
LiquidData liquidData;
|
||||
if (m_caster->GetMap()->GetLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &liquidData))
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "World.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "Player.h"
|
||||
#include "SkillExtraItems.h"
|
||||
#include "Unit.h"
|
||||
@@ -3165,7 +3166,7 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex)
|
||||
return;
|
||||
}
|
||||
|
||||
pGameObj->CopyPhaseFrom(m_caster);
|
||||
PhasingHandler::InheritPhaseShift(pGameObj, m_caster);
|
||||
|
||||
int32 duration = m_spellInfo->GetDuration();
|
||||
|
||||
@@ -3184,6 +3185,8 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex)
|
||||
|
||||
if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
|
||||
{
|
||||
PhasingHandler::InheritPhaseShift(linkedTrap, m_caster);
|
||||
|
||||
linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
|
||||
linkedTrap->SetSpellId(m_spellInfo->Id);
|
||||
|
||||
@@ -3773,7 +3776,7 @@ void Spell::EffectDuel(SpellEffIndex effIndex)
|
||||
return;
|
||||
}
|
||||
|
||||
pGameObj->CopyPhaseFrom(m_caster);
|
||||
PhasingHandler::InheritPhaseShift(pGameObj, m_caster);
|
||||
|
||||
pGameObj->SetFaction(m_caster->GetFaction());
|
||||
pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()+1);
|
||||
@@ -4134,7 +4137,7 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex)
|
||||
return;
|
||||
}
|
||||
|
||||
go->CopyPhaseFrom(m_caster);
|
||||
PhasingHandler::InheritPhaseShift(go, m_caster);
|
||||
|
||||
//pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel());
|
||||
int32 duration = m_spellInfo->GetDuration();
|
||||
@@ -4848,7 +4851,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)
|
||||
return;
|
||||
}
|
||||
|
||||
pGameObj->CopyPhaseFrom(m_caster);
|
||||
PhasingHandler::InheritPhaseShift(pGameObj, m_caster);
|
||||
|
||||
int32 duration = m_spellInfo->GetDuration();
|
||||
|
||||
@@ -4908,6 +4911,8 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)
|
||||
|
||||
if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
|
||||
{
|
||||
PhasingHandler::InheritPhaseShift(linkedTrap, m_caster);
|
||||
|
||||
linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0);
|
||||
//linkedTrap->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel());
|
||||
linkedTrap->SetSpellId(m_spellInfo->Id);
|
||||
@@ -5742,7 +5747,7 @@ void Spell::EffectUpdatePlayerPhase(SpellEffIndex /*effIndex*/)
|
||||
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
unitTarget->UpdateAreaPhase();
|
||||
PhasingHandler::OnConditionChange(unitTarget);
|
||||
}
|
||||
|
||||
void Spell::EffectUpdateZoneAurasAndPhases(SpellEffIndex /*effIndex*/)
|
||||
|
||||
@@ -1885,17 +1885,7 @@ void World::SetInitialWorldSettings()
|
||||
TC_LOG_INFO("server.loading", "Loading World States..."); // must be loaded before battleground, outdoor PvP and conditions
|
||||
LoadWorldStates();
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading Terrain Phase definitions...");
|
||||
sObjectMgr->LoadTerrainPhaseInfo();
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading Terrain Swap Default definitions...");
|
||||
sObjectMgr->LoadTerrainSwapDefaults();
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading Terrain World Map definitions...");
|
||||
sObjectMgr->LoadTerrainWorldMaps();
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading Phase Area definitions...");
|
||||
sObjectMgr->LoadAreaPhases();
|
||||
sObjectMgr->LoadPhases();
|
||||
|
||||
TC_LOG_INFO("server.loading", "Loading Conditions...");
|
||||
sConditionMgr->LoadConditions();
|
||||
|
||||
@@ -24,6 +24,7 @@ EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "BattlefieldMgr.h"
|
||||
#include "BattlegroundMgr.h"
|
||||
#include "Chat.h"
|
||||
@@ -979,7 +980,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
v->CopyPhaseFrom(handler->GetSession()->GetPlayer());
|
||||
PhasingHandler::InheritPhaseShift(v, handler->GetSession()->GetPlayer());
|
||||
|
||||
map->AddToMap(v->ToCreature());
|
||||
|
||||
@@ -1008,22 +1009,20 @@ public:
|
||||
if (!t)
|
||||
return false;
|
||||
|
||||
std::set<uint32> terrainswap;
|
||||
std::set<uint32> phaseId;
|
||||
std::set<uint32> worldMapSwap;
|
||||
PhaseShift phaseShift;
|
||||
|
||||
if (uint32 ut = (uint32)atoi(t))
|
||||
terrainswap.insert(ut);
|
||||
phaseShift.AddVisibleMapId(ut, nullptr);
|
||||
|
||||
if (p)
|
||||
if (uint32 up = (uint32)atoi(p))
|
||||
phaseId.insert(up);
|
||||
phaseShift.AddPhase(up, PhaseFlags::None, nullptr, nullptr);
|
||||
|
||||
if (m)
|
||||
if (uint32 um = (uint32)atoi(m))
|
||||
worldMapSwap.insert(um);
|
||||
phaseShift.AddUiWorldMapAreaIdSwap(um);
|
||||
|
||||
handler->GetSession()->SendSetPhaseShift(phaseId, terrainswap, worldMapSwap);
|
||||
PhasingHandler::SendToPlayer(handler->GetSession()->GetPlayer(), phaseShift);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1462,15 +1461,8 @@ public:
|
||||
|
||||
std::stringstream phases;
|
||||
|
||||
for (uint32 phase : target->GetPhases())
|
||||
{
|
||||
phases << phase << " ";
|
||||
}
|
||||
PhasingHandler::PrintToChat(handler, target->GetPhaseShift());
|
||||
|
||||
if (!phases.str().empty())
|
||||
handler->PSendSysMessage("Target's current phases: %s", phases.str().c_str());
|
||||
else
|
||||
handler->SendSysMessage("Target is not phased");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ EndScriptData */
|
||||
#include "Language.h"
|
||||
#include "Player.h"
|
||||
#include "Opcodes.h"
|
||||
#include "PhasingHandler.h"
|
||||
|
||||
class gobject_commandscript : public CommandScript
|
||||
{
|
||||
@@ -147,7 +148,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
object->CopyPhaseFrom(player);
|
||||
PhasingHandler::InheritPhaseShift(object, player);
|
||||
|
||||
if (spawntimeSecs)
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "LFG.h"
|
||||
#include "Player.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "GroupMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
|
||||
@@ -331,7 +332,6 @@ public:
|
||||
{
|
||||
// Get ALL the variables!
|
||||
Player* playerTarget;
|
||||
uint32 phase = 0;
|
||||
ObjectGuid guidTarget;
|
||||
std::string nameTarget;
|
||||
std::string zoneName;
|
||||
@@ -412,11 +412,12 @@ public:
|
||||
|
||||
// Check if iterator is online. If is...
|
||||
Player* p = ObjectAccessor::FindPlayer((*itr).guid);
|
||||
std::string phases;
|
||||
if (p)
|
||||
{
|
||||
// ... than, it prints information like "is online", where he is, etc...
|
||||
onlineState = "online";
|
||||
phase = (!p->IsGameMaster() ? p->GetPhaseMask() : -1);
|
||||
phases = PhasingHandler::FormatPhases(p->GetPhaseShift());
|
||||
LocaleConstant localeConstant = handler->GetSessionDbcLocale();
|
||||
|
||||
AreaTableEntry const* area = sAreaTableStore.LookupEntry(p->GetAreaId());
|
||||
@@ -432,12 +433,11 @@ public:
|
||||
// ... else, everything is set to offline or neutral values.
|
||||
zoneName = "<ERROR>";
|
||||
onlineState = "Offline";
|
||||
phase = 0;
|
||||
}
|
||||
|
||||
// Now we can print those informations for every single member of each group!
|
||||
handler->PSendSysMessage(LANG_GROUP_PLAYER_NAME_GUID, slot.name.c_str(), onlineState,
|
||||
zoneName.c_str(), phase, slot.guid.GetCounter(), flags.c_str(),
|
||||
zoneName.c_str(), phases.c_str(), slot.guid.GetCounter(), flags.c_str(),
|
||||
lfg::GetRolesString(slot.roles).c_str());
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "WeatherMgr.h"
|
||||
#include "Player.h"
|
||||
#include "Pet.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "LFG.h"
|
||||
#include "GroupMgr.h"
|
||||
#include "MMapFactory.h"
|
||||
@@ -238,8 +239,8 @@ public:
|
||||
Map2ZoneCoordinates(zoneX, zoneY, zoneId);
|
||||
|
||||
Map const* map = object->GetMap();
|
||||
float groundZ = map->GetHeight(object->GetPhases(), object->GetPositionX(), object->GetPositionY(), MAX_HEIGHT);
|
||||
float floorZ = map->GetHeight(object->GetPhases(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ());
|
||||
float groundZ = map->GetHeight(object->GetPhaseShift(), object->GetPositionX(), object->GetPositionY(), MAX_HEIGHT);
|
||||
float floorZ = map->GetHeight(object->GetPhaseShift(), object->GetPositionX(), object->GetPositionY(), object->GetPositionZ());
|
||||
|
||||
GridCoord gridCoord = Trinity::ComputeGridCoord(object->GetPositionX(), object->GetPositionY());
|
||||
|
||||
@@ -266,7 +267,6 @@ public:
|
||||
mapId, (mapEntry ? mapEntry->name : unknown),
|
||||
zoneId, (zoneEntry ? zoneEntry->area_name : unknown),
|
||||
areaId, (areaEntry ? areaEntry->area_name : unknown),
|
||||
object->GetPhaseMask(), StringJoin(object->GetPhases(), ", ").c_str(),
|
||||
object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation());
|
||||
if (Transport* transport = object->GetTransport())
|
||||
handler->PSendSysMessage(LANG_TRANSPORT_POSITION,
|
||||
@@ -282,20 +282,7 @@ public:
|
||||
if (status)
|
||||
handler->PSendSysMessage(LANG_LIQUID_STATUS, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status);
|
||||
|
||||
if (!object->GetTerrainSwaps().empty())
|
||||
{
|
||||
std::stringstream ss;
|
||||
for (uint32 swap : object->GetTerrainSwaps())
|
||||
ss << swap << " ";
|
||||
handler->PSendSysMessage("Target's active terrain swaps: %s", ss.str().c_str());
|
||||
}
|
||||
if (!object->GetWorldMapAreaSwaps().empty())
|
||||
{
|
||||
std::stringstream ss;
|
||||
for (uint32 swap : object->GetWorldMapAreaSwaps())
|
||||
ss << swap << " ";
|
||||
handler->PSendSysMessage("Target's active world map area swaps: %s", ss.str().c_str());
|
||||
}
|
||||
PhasingHandler::PrintToChat(handler, object->GetPhaseShift());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -453,8 +440,8 @@ public:
|
||||
target->GetContactPoint(_player, x, y, z);
|
||||
|
||||
_player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE);
|
||||
|
||||
_player->CopyPhaseFrom(target, true);
|
||||
PhasingHandler::InheritPhaseShift(_player, target);
|
||||
_player->UpdateObjectVisibility();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -584,7 +571,8 @@ public:
|
||||
float x, y, z;
|
||||
_player->GetClosePoint(x, y, z, target->GetObjectSize());
|
||||
target->TeleportTo(_player->GetMapId(), x, y, z, target->GetOrientation());
|
||||
target->SetPhaseMask(_player->GetPhaseMask(), true);
|
||||
PhasingHandler::InheritPhaseShift(target, handler->GetSession()->GetPlayer());
|
||||
target->UpdateObjectVisibility();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1611,7 +1599,6 @@ public:
|
||||
// Position data print
|
||||
uint32 mapId;
|
||||
uint32 areaId;
|
||||
std::set<uint32> phases;
|
||||
std::string areaName = handler->GetTrinityString(LANG_UNKNOWN);
|
||||
std::string zoneName = handler->GetTrinityString(LANG_UNKNOWN);
|
||||
|
||||
@@ -1643,7 +1630,6 @@ public:
|
||||
areaId = target->GetAreaId();
|
||||
alive = target->IsAlive() ? handler->GetTrinityString(LANG_YES) : handler->GetTrinityString(LANG_NO);
|
||||
gender = target->getGender();
|
||||
phases = target->GetPhases();
|
||||
}
|
||||
// get additional information from DB
|
||||
else
|
||||
@@ -1830,9 +1816,9 @@ public:
|
||||
// Output XII. LANG_PINFO_CHR_ALIVE
|
||||
handler->PSendSysMessage(LANG_PINFO_CHR_ALIVE, alive.c_str());
|
||||
|
||||
// Output XIII. LANG_PINFO_CHR_PHASES
|
||||
if (target && !phases.empty())
|
||||
handler->PSendSysMessage(LANG_PINFO_CHR_PHASES, StringJoin(phases, ", ").c_str());
|
||||
// Output XIII. phases
|
||||
if (target)
|
||||
PhasingHandler::PrintToChat(handler, target->GetPhaseShift());
|
||||
|
||||
// Output XIV. LANG_PINFO_CHR_MONEY
|
||||
uint32 gold = money / GOLD;
|
||||
|
||||
@@ -27,6 +27,7 @@ EndScriptData */
|
||||
#include "ObjectMgr.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Pet.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "Player.h"
|
||||
#include "ReputationMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
@@ -828,9 +829,18 @@ public:
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
uint32 phaseId = uint32(atoul(args));
|
||||
char* phaseText = strtok((char*)args, " ");
|
||||
if (!phaseText)
|
||||
return false;
|
||||
|
||||
if (!sPhaseStore.LookupEntry(phaseId))
|
||||
uint32 phaseId = uint32(strtoul(phaseText, nullptr, 10));
|
||||
uint32 visibleMapId = 0;
|
||||
|
||||
char* visibleMapIdText = strtok(nullptr, " ");
|
||||
if (visibleMapIdText)
|
||||
visibleMapId = uint32(strtoul(visibleMapIdText, nullptr, 10));
|
||||
|
||||
if (phaseId && !sPhaseStore.LookupEntry(phaseId))
|
||||
{
|
||||
handler->SendSysMessage(LANG_PHASE_NOTFOUND);
|
||||
handler->SetSentErrorMessage(true);
|
||||
@@ -838,13 +848,29 @@ public:
|
||||
}
|
||||
|
||||
Unit* target = handler->getSelectedUnit();
|
||||
if (!target)
|
||||
target = handler->GetSession()->GetPlayer();
|
||||
if (visibleMapId)
|
||||
{
|
||||
MapEntry const* visibleMap = sMapStore.LookupEntry(visibleMapId);
|
||||
if (!visibleMap || visibleMap->rootPhaseMap != int32(target->GetMapId()))
|
||||
{
|
||||
handler->SendSysMessage(LANG_PHASE_NOTFOUND);
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
target->SetInPhase(phaseId, true, !target->IsInPhase(phaseId));
|
||||
if (!target->GetPhaseShift().HasVisibleMapId(visibleMapId))
|
||||
PhasingHandler::AddVisibleMapId(target, visibleMapId);
|
||||
else
|
||||
PhasingHandler::RemoveVisibleMapId(target, visibleMapId);
|
||||
}
|
||||
|
||||
if (target->GetTypeId() == TYPEID_PLAYER)
|
||||
target->ToPlayer()->SendUpdatePhasing();
|
||||
if (phaseId)
|
||||
{
|
||||
if (!target->GetPhaseShift().HasPhase(phaseId))
|
||||
PhasingHandler::AddPhase(target, phaseId, true);
|
||||
else
|
||||
PhasingHandler::RemovePhase(target, phaseId, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ EndScriptData */
|
||||
#include "CreatureAI.h"
|
||||
#include "Player.h"
|
||||
#include "Pet.h"
|
||||
#include "PhasingHandler.h"
|
||||
|
||||
template<typename E, typename T = char const*>
|
||||
struct EnumName
|
||||
@@ -287,8 +288,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
//creature->CopyPhaseFrom(chr); // creature is not directly added to world, only to db, so this is useless here
|
||||
|
||||
PhasingHandler::InheritPhaseShift(creature, chr);
|
||||
creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask());
|
||||
|
||||
ObjectGuid::LowType db_guid = creature->GetSpawnId();
|
||||
@@ -718,18 +718,8 @@ public:
|
||||
|
||||
if (CreatureData const* data = sObjectMgr->GetCreatureData(target->GetSpawnId()))
|
||||
{
|
||||
handler->PSendSysMessage(LANG_NPCINFO_PHASES, data->phaseid, data->phaseGroup);
|
||||
if (data->phaseGroup)
|
||||
{
|
||||
std::set<uint32> _phases = target->GetPhases();
|
||||
|
||||
if (!_phases.empty())
|
||||
{
|
||||
handler->PSendSysMessage(LANG_NPCINFO_PHASE_IDS);
|
||||
for (uint32 phaseId : _phases)
|
||||
handler->PSendSysMessage("%u", phaseId);
|
||||
}
|
||||
}
|
||||
handler->PSendSysMessage(LANG_NPCINFO_PHASES, data->phaseId, data->phaseGroup);
|
||||
PhasingHandler::PrintToChat(handler, target->GetPhaseShift());
|
||||
}
|
||||
|
||||
handler->PSendSysMessage(LANG_NPCINFO_ARMOR, target->GetArmor());
|
||||
@@ -1078,12 +1068,8 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
creature->ClearPhases();
|
||||
|
||||
for (uint32 id : GetPhasesForGroup(phaseGroupId))
|
||||
creature->SetInPhase(id, false, true); // don't send update here for multiple phases, only send it once after adding all phases
|
||||
|
||||
creature->UpdateObjectVisibility();
|
||||
PhasingHandler::ResetPhaseShift(creature);
|
||||
PhasingHandler::AddPhaseGroup(creature, phaseGroupId, true);
|
||||
creature->SetDBPhase(-int(phaseGroupId));
|
||||
|
||||
creature->SaveToDB();
|
||||
@@ -1114,8 +1100,8 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
creature->ClearPhases();
|
||||
creature->SetInPhase(phaseID, true, true);
|
||||
PhasingHandler::ResetPhaseShift(creature);
|
||||
PhasingHandler::AddPhase(creature, phaseID, true);
|
||||
creature->SetDBPhase(phaseID);
|
||||
|
||||
creature->SaveToDB();
|
||||
|
||||
@@ -1142,15 +1142,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool HandleReloadPhaseDefinitionsCommand(ChatHandler* handler, const char* /*args*/)
|
||||
{
|
||||
TC_LOG_INFO("misc", "Reloading terrain_phase_info table...");
|
||||
sObjectMgr->LoadTerrainPhaseInfo();
|
||||
handler->SendGlobalGMSysMessage("Terrain phase infos reloaded.");
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleReloadRBACCommand(ChatHandler* handler, const char* /*args*/)
|
||||
{
|
||||
TC_LOG_INFO("misc", "Reloading RBAC tables...");
|
||||
|
||||
@@ -25,6 +25,7 @@ EndScriptData */
|
||||
#include "Chat.h"
|
||||
#include "Language.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "WaypointManager.h"
|
||||
@@ -667,7 +668,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
wpCreature->CopyPhaseFrom(chr);
|
||||
PhasingHandler::InheritPhaseShift(wpCreature, chr);
|
||||
|
||||
wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask());
|
||||
// To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
|
||||
@@ -881,7 +882,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
wpCreature->CopyPhaseFrom(chr);
|
||||
PhasingHandler::InheritPhaseShift(wpCreature, chr);
|
||||
|
||||
// Set "wpguid" column to the visual waypoint
|
||||
stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_WPGUID);
|
||||
@@ -945,7 +946,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
creature->CopyPhaseFrom(chr);
|
||||
PhasingHandler::InheritPhaseShift(creature, chr);
|
||||
|
||||
creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask());
|
||||
if (!creature->LoadCreatureFromDB(creature->GetSpawnId(), map))
|
||||
@@ -996,7 +997,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
creature->CopyPhaseFrom(chr);
|
||||
PhasingHandler::InheritPhaseShift(creature, chr);
|
||||
|
||||
creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask());
|
||||
if (!creature->LoadCreatureFromDB(creature->GetSpawnId(), map))
|
||||
|
||||
@@ -1172,7 +1172,7 @@ public:
|
||||
|
||||
float x, y, z;
|
||||
me->GetPosition(x, y, z);
|
||||
z = me->GetMap()->GetHeight(me->GetPhases(), x, y, z);
|
||||
z = me->GetMap()->GetHeight(me->GetPhaseShift(), x, y, z);
|
||||
me->GetMotionMaster()->MovePoint(0, x, y, z);
|
||||
me->SetPosition(x, y, z, 0);
|
||||
}
|
||||
@@ -1290,7 +1290,7 @@ public:
|
||||
{
|
||||
float x, y, z;
|
||||
me->GetPosition(x, y, z);
|
||||
z = me->GetMap()->GetHeight(me->GetPhases(), x, y, z);
|
||||
z = me->GetMap()->GetHeight(me->GetPhaseShift(), x, y, z);
|
||||
me->GetMotionMaster()->MovePoint(0, x, y, z);
|
||||
me->SetPosition(x, y, z, 0);
|
||||
hyjal_trashAI::JustDied(killer);
|
||||
|
||||
@@ -543,7 +543,7 @@ public:
|
||||
|
||||
float x = caster->GetPositionX() + dist * std::cos(angle);
|
||||
float y = caster->GetPositionY() + dist * std::sin(angle);
|
||||
float z = caster->GetMap()->GetHeight(caster->GetPhases(), x, y, caster->GetPositionZ());
|
||||
float z = caster->GetMap()->GetHeight(caster->GetPhaseShift(), x, y, caster->GetPositionZ());
|
||||
|
||||
const_cast<WorldLocation*>(GetExplTargetDest())->Relocate(x, y, z);
|
||||
GetHitDest()->Relocate(x, y, z);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "ScriptMgr.h"
|
||||
#include "lost_city_of_the_tolvir.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
@@ -289,8 +290,7 @@ public:
|
||||
if (Creature* barim = _instance->GetCreature(DATA_HIGH_PROPHET_BARIM))
|
||||
barim->AI()->JustSummoned(me);
|
||||
|
||||
for (uint32 id : GetPhasesForGroup(PHASE_GROUP_ENCOUNTER_1))
|
||||
me->SetInPhase(id, false, true);
|
||||
PhasingHandler::AddPhaseGroup(me, PHASE_GROUP_ENCOUNTER_1, true);
|
||||
|
||||
DoCastSelf(SPELL_REPENTANCE_SCRIPT_1, true);
|
||||
_events.ScheduleEvent(EVENT_COPY_WEAPON, Seconds(2));
|
||||
@@ -439,7 +439,7 @@ public:
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
DoZoneInCombat();
|
||||
DoCastSelf(SPELL_BIRTH, true);
|
||||
me->SetInPhase(PHASE_ID_REPENTANCE, true, false);
|
||||
PhasingHandler::AddPhase(me, PHASE_ID_REPENTANCE, true);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
@@ -455,8 +455,7 @@ public:
|
||||
if (Creature* barim = _instance->GetCreature(DATA_HIGH_PROPHET_BARIM))
|
||||
barim->AI()->JustSummoned(summon);
|
||||
|
||||
for (uint32 id : GetPhasesForGroup(PHASE_GROUP_ENCOUNTER_1))
|
||||
summon->SetInPhase(id, false, true);
|
||||
PhasingHandler::AddPhaseGroup(summon, PHASE_GROUP_ENCOUNTER_1, true);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
|
||||
@@ -268,7 +268,7 @@ class boss_high_priestess_azil : public CreatureScript
|
||||
me->RemoveAurasDueToSpell(SPELL_EARTH_FURY_CASTING_VISUAL);
|
||||
me->RemoveAurasDueToSpell(SPELL_EARTH_FURY_ENERGY_SHIELD);
|
||||
Position pos = me->GetPosition();
|
||||
pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhases(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
|
||||
pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
|
||||
me->GetMotionMaster()->MovePoint(POINT_GROUND, pos);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ class boss_slabhide : public CreatureScript
|
||||
case EVENT_LAND:
|
||||
{
|
||||
Position pos = me->GetPosition();
|
||||
pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhases(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
|
||||
pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
|
||||
me->GetMotionMaster()->MoveLand(POINT_SLABHIDE_LAND, pos);
|
||||
break;
|
||||
}
|
||||
@@ -479,7 +479,7 @@ public:
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
Position pos = caster->GetPosition();
|
||||
pos.m_positionZ = caster->GetMap()->GetHeight(caster->GetPhases(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), true, 100.0f);
|
||||
pos.m_positionZ = caster->GetMap()->GetHeight(caster->GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), true, 100.0f);
|
||||
dest.Relocate(pos);
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ class boss_amanitar : public CreatureScript
|
||||
for (uint8 i = 0; i < 30; ++i)
|
||||
{
|
||||
Position pos = me->GetRandomNearPosition(30.0f);
|
||||
pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhases(), pos.GetPositionX(), pos.GetPositionY(), MAX_HEIGHT) + 2.0f;
|
||||
pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), MAX_HEIGHT) + 2.0f;
|
||||
|
||||
if (Creature* trigger = me->SummonCreature(NPC_TRIGGER, pos))
|
||||
{
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ahnkahet.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "Player.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
@@ -142,7 +143,7 @@ public:
|
||||
// clone
|
||||
player->CastSpell(summon, SPELL_CLONE_PLAYER, true);
|
||||
// phase the summon
|
||||
summon->SetInPhase(spellInfo->Effects[EFFECT_0].MiscValueB, true, true);
|
||||
PhasingHandler::AddPhase(summon, spellInfo->Effects[EFFECT_0].MiscValueB, true);
|
||||
}
|
||||
}
|
||||
++insanityHandled;
|
||||
@@ -168,9 +169,9 @@ public:
|
||||
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_QUICK_DEMISE_START_EVENT);
|
||||
|
||||
// Visible for all players in insanity
|
||||
me->SetInPhase(169, true, true);
|
||||
for (uint32 i = 173; i <= 177; ++i)
|
||||
me->SetInPhase(i, true, true);
|
||||
PhasingHandler::AddPhase(me, i, false);
|
||||
PhasingHandler::AddPhase(me, 169, true);
|
||||
|
||||
ResetPlayersPhase();
|
||||
|
||||
@@ -208,7 +209,7 @@ public:
|
||||
return;
|
||||
else
|
||||
{
|
||||
nextPhase = *visage->GetPhases().begin();
|
||||
nextPhase = visage->GetPhaseShift().GetPhases().begin()->Id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -627,7 +627,7 @@ class npc_frost_sphere : public CreatureScript
|
||||
if (me->GetHealth() <= damage)
|
||||
{
|
||||
damage = 0;
|
||||
float floorZ = me->GetMap()->GetHeight(me->GetPhases(), me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
|
||||
float floorZ = me->GetMap()->GetHeight(me->GetPhaseShift(), me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
|
||||
if (fabs(me->GetPositionZ() - floorZ) < 0.1f)
|
||||
{
|
||||
// we are close to the ground
|
||||
|
||||
@@ -804,7 +804,7 @@ class boss_prince_valanar_icc : public CreatureScript
|
||||
{
|
||||
float x, y, z;
|
||||
summon->GetPosition(x, y, z);
|
||||
float ground_Z = summon->GetMap()->GetHeight(summon->GetPhases(), x, y, z, true, 500.0f);
|
||||
float ground_Z = summon->GetMap()->GetHeight(summon->GetPhaseShift(), x, y, z, true, 500.0f);
|
||||
summon->GetMotionMaster()->MovePoint(POINT_KINETIC_BOMB_IMPACT, x, y, ground_Z);
|
||||
summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
break;
|
||||
@@ -1046,7 +1046,7 @@ class npc_kinetic_bomb : public CreatureScript
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->GetPosition(_x, _y, _groundZ);
|
||||
me->DespawnOrUnsummon(60000);
|
||||
_groundZ = me->GetMap()->GetHeight(me->GetPhases(), _x, _y, _groundZ, true, 500.0f);
|
||||
_groundZ = me->GetMap()->GetHeight(me->GetPhaseShift(), _x, _y, _groundZ, true, 500.0f);
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "ObjectMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "Cell.h"
|
||||
@@ -636,7 +637,7 @@ class npc_the_lich_king_controller : public CreatureScript
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
// must not be in dream phase
|
||||
summon->SetInPhase(173, true, false);
|
||||
PhasingHandler::RemovePhase(summon, 173, true);
|
||||
if (summon->GetEntry() != NPC_SUPPRESSER)
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
|
||||
summon->AI()->AttackStart(target);
|
||||
|
||||
@@ -778,7 +778,7 @@ class boss_flame_leviathan_safety_container : public CreatureScript
|
||||
{
|
||||
float x, y, z;
|
||||
me->GetPosition(x, y, z);
|
||||
z = me->GetMap()->GetHeight(me->GetPhases(), x, y, z);
|
||||
z = me->GetMap()->GetHeight(me->GetPhaseShift(), x, y, z);
|
||||
me->GetMotionMaster()->MovePoint(0, x, y, z);
|
||||
me->SetPosition(x, y, z, 0);
|
||||
}
|
||||
|
||||
@@ -872,7 +872,7 @@ class boss_sara : public CreatureScript
|
||||
float angle = frand(0.0f, 2.0f * float(M_PI));
|
||||
pos.m_positionX = YoggSaronSpawnPos.GetPositionX() + radius * cosf(angle);
|
||||
pos.m_positionY = YoggSaronSpawnPos.GetPositionY() + radius * sinf(angle);
|
||||
pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhases(), pos.GetPositionX(), pos.GetPositionY(), YoggSaronSpawnPos.GetPositionZ() + 5.0f);
|
||||
pos.m_positionZ = me->GetMap()->GetHeight(me->GetPhaseShift(), pos.GetPositionX(), pos.GetPositionY(), YoggSaronSpawnPos.GetPositionZ() + 5.0f);
|
||||
me->SummonCreature(NPC_DEATH_RAY, pos, TEMPSUMMON_TIMED_DESPAWN, 20000);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -38,6 +38,7 @@ EndContentData */
|
||||
#include "ScriptedGossip.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "ScriptedFollowerAI.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "Player.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "WorldSession.h"
|
||||
@@ -1689,7 +1690,7 @@ public:
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
|
||||
break;
|
||||
case 20:
|
||||
me->SetInPhase(170, true, false);
|
||||
PhasingHandler::RemovePhase(me, 170, true);
|
||||
Talk(SAY_5);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
|
||||
player->GroupEventHappens(QUEST_ESCAPING_THE_MIST, me);
|
||||
|
||||
@@ -529,7 +529,7 @@ public:
|
||||
|
||||
bird->KillSelf();
|
||||
crunchy->GetMotionMaster()->MovePoint(0, bird->GetPositionX(), bird->GetPositionY(),
|
||||
bird->GetMap()->GetWaterOrGroundLevel(bird->GetPhases(), bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ()));
|
||||
bird->GetMap()->GetWaterOrGroundLevel(bird->GetPhaseShift(), bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ()));
|
||||
/// @todo Make crunchy perform emote eat when he reaches the bird
|
||||
|
||||
break;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "ScriptMgr.h"
|
||||
#include "OutdoorPvPSI.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "PhasingHandler.h"
|
||||
#include "Player.h"
|
||||
#include "GameObject.h"
|
||||
#include "MapManager.h"
|
||||
@@ -182,8 +183,7 @@ bool OutdoorPvPSI::HandleDropFlag(Player* player, uint32 spellId)
|
||||
return true;
|
||||
}
|
||||
|
||||
go->CopyPhaseFrom(player);
|
||||
|
||||
PhasingHandler::InheritPhaseShift(go, player);
|
||||
go->SetRespawnTime(0);
|
||||
|
||||
if (!map->AddToMap(go))
|
||||
@@ -213,8 +213,7 @@ bool OutdoorPvPSI::HandleDropFlag(Player* player, uint32 spellId)
|
||||
return true;
|
||||
}
|
||||
|
||||
go->CopyPhaseFrom(player);
|
||||
|
||||
PhasingHandler::InheritPhaseShift(go, player);
|
||||
go->SetRespawnTime(0);
|
||||
|
||||
if (!map->AddToMap(go))
|
||||
|
||||
@@ -75,7 +75,7 @@ public:
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
ground = me->GetMap()->GetHeight(me->GetPhases(), me->GetPositionX(), me->GetPositionY(), me->GetPositionZMinusOffset());
|
||||
ground = me->GetMap()->GetHeight(me->GetPhaseShift(), me->GetPositionX(), me->GetPositionY(), me->GetPositionZMinusOffset());
|
||||
SummonInfernal();
|
||||
events.ScheduleEvent(EVENT_CAST_SUMMON_INFERNAL, urand(1000, 3000));
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user