Merge branch 'master' of https://github.com/azerothcore/azerothcore-wotlk into dir-restructure

This commit is contained in:
Yehonal
2017-12-21 11:26:43 +01:00
445 changed files with 49192 additions and 15431 deletions
@@ -353,7 +353,7 @@ bool Creature::InitEntry(uint32 Entry, const CreatureData* data)
// Load creature equipment
if (!data || data->equipmentId == 0) // use default from the template
LoadEquipment(GetCreatureData() ? GetOriginalEquipmentId() : 1);
LoadEquipment();
else if (data && data->equipmentId != 0) // override, 0 means no equipment
{
m_originalEquipmentId = data->equipmentId;
+46 -107
View File
@@ -1095,9 +1095,13 @@ bool WorldObject::IsWithinLOSInMap(const WorldObject* obj) const
if (!IsInMap(obj))
return false;
float ox, oy, oz;
obj->GetPosition(ox, oy, oz);
return IsWithinLOS(ox, oy, oz);
float x, y, z;
if (obj->GetTypeId() == TYPEID_PLAYER)
obj->GetPosition(x, y, z);
else
obj->GetHitSpherePointFor(GetPosition(), x, y, z);
return IsWithinLOS(x, y, z);
}
bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const
@@ -1107,11 +1111,36 @@ bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const
VMAP::IVMapManager* vMapManager = VMAP::VMapFactory::createOrGetVMapManager();
return vMapManager->isInLineOfSight(GetMapId(), x, y, z+2.0f, ox, oy, oz+2.0f);*/
if (IsInWorld())
return GetMap()->isInLineOfSight(GetPositionX(), GetPositionY(), GetPositionZ()+2.f, ox, oy, oz+2.f, GetPhaseMask());
{
float x, y, z;
if (GetTypeId() == TYPEID_PLAYER)
GetPosition(x, y, z);
else
GetHitSpherePointFor({ ox, oy, oz }, x, y, z);
return GetMap()->isInLineOfSight(x, y, z + 2.0f, ox, oy, oz + 2.0f, GetPhaseMask());
}
return true;
}
Position WorldObject::GetHitSpherePointFor(Position const& dest) const
{
G3D::Vector3 vThis(GetPositionX(), GetPositionY(), GetPositionZ());
G3D::Vector3 vObj(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ());
G3D::Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * std::min(dest.GetExactDist(this), GetObjectSize());
return Position(contactPoint.x, contactPoint.y, contactPoint.z, GetAngle(contactPoint.x, contactPoint.y));
}
void WorldObject::GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z) const
{
Position pos = GetHitSpherePointFor(dest);
x = pos.GetPositionX();
y = pos.GetPositionY();
z = pos.GetPositionZ();
}
bool WorldObject::GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D /* = true */) const
{
float dx1 = GetPositionX() - obj1->GetPositionX();
@@ -2402,123 +2431,33 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y,
else
UpdateAllowedPositionZ(x, y, z);
/*
// if detection disabled, return first point
if (!sWorld->getIntConfig(CONFIG_DETECT_POS_COLLISION))
{
UpdateGroundPositionZ(x, y, z); // update to LOS height if available
if (!sWorld->getBoolConfig(CONFIG_DETECT_POS_COLLISION))
return;
}
// or remember first point
// return if the point is already in LoS
if (IsWithinLOS(x, y, z))
return;
// remember first point
float first_x = x;
float first_y = y;
bool first_los_conflict = false; // first point LOS problems
float first_z = z;
// prepare selector for work
ObjectPosSelector selector(GetPositionX(), GetPositionY(), GetObjectSize(), distance2d+searcher_size);
// adding used positions around object
// loop in a circle to look for a point in LoS using small steps
for (float angle = float(M_PI) / 8; angle < float(M_PI) * 2; angle += float(M_PI) / 8)
{
CellCoord p(Trinity::ComputeCellCoord(GetPositionX(), GetPositionY()));
Cell cell(p);
cell.SetNoCreate();
Trinity::NearUsedPosDo u_do(*this, searcher, absAngle, selector);
Trinity::WorldObjectWorker<Trinity::NearUsedPosDo> worker(this, u_do);
TypeContainerVisitor<Trinity::WorldObjectWorker<Trinity::NearUsedPosDo>, GridTypeMapContainer > grid_obj_worker(worker);
TypeContainerVisitor<Trinity::WorldObjectWorker<Trinity::NearUsedPosDo>, WorldTypeMapContainer > world_obj_worker(worker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, grid_obj_worker, *GetMap(), *this, distance2d);
cell_lock->Visit(cell_lock, world_obj_worker, *GetMap(), *this, distance2d);
}
// maybe can just place in primary position
if (selector.CheckOriginal())
{
UpdateGroundPositionZ(x, y, z); // update to LOS height if available
if (IsWithinLOS(x, y, z))
return;
first_los_conflict = true; // first point have LOS problems
}
float angle; // candidate of angle for free pos
// special case when one from list empty and then empty side preferred
if (selector.FirstAngle(angle))
{
GetNearPoint2D(x, y, distance2d, absAngle+angle);
GetNearPoint2D(x, y, distance2d + searcher_size, absAngle + angle);
z = GetPositionZ();
UpdateGroundPositionZ(x, y, z); // update to LOS height if available
UpdateAllowedPositionZ(x, y, z);
if (IsWithinLOS(x, y, z))
return;
}
// set first used pos in lists
selector.InitializeAngle();
// select in positions after current nodes (selection one by one)
while (selector.NextAngle(angle)) // angle for free pos
{
GetNearPoint2D(x, y, distance2d, absAngle+angle);
z = GetPositionZ();
UpdateGroundPositionZ(x, y, z); // update to LOS height if available
if (IsWithinLOS(x, y, z))
return;
}
// BAD NEWS: not free pos (or used or have LOS problems)
// Attempt find _used_ pos without LOS problem
if (!first_los_conflict)
{
x = first_x;
y = first_y;
UpdateGroundPositionZ(x, y, z); // update to LOS height if available
return;
}
// special case when one from list empty and then empty side preferred
if (selector.IsNonBalanced())
{
if (!selector.FirstAngle(angle)) // _used_ pos
{
GetNearPoint2D(x, y, distance2d, absAngle+angle);
z = GetPositionZ();
UpdateGroundPositionZ(x, y, z); // update to LOS height if available
if (IsWithinLOS(x, y, z))
return;
}
}
// set first used pos in lists
selector.InitializeAngle();
// select in positions after current nodes (selection one by one)
while (selector.NextUsedAngle(angle)) // angle for used pos but maybe without LOS problem
{
GetNearPoint2D(x, y, distance2d, absAngle+angle);
z = GetPositionZ();
UpdateGroundPositionZ(x, y, z); // update to LOS height if available
if (IsWithinLOS(x, y, z))
return;
}
// BAD BAD NEWS: all found pos (free and used) have LOS problem :(
// still not in LoS, give up and return first position found
x = first_x;
y = first_y;
UpdateGroundPositionZ(x, y, z); // update to LOS height if available
*/
z = first_z;
}
bool WorldObject::GetClosePoint(float &x, float &y, float &z, float size, float distance2d, float angle, const WorldObject* forWho, bool force) const
+94 -24
View File
@@ -365,6 +365,17 @@ class Object
struct Position
{
Position(float x = 0, float y = 0, float z = 0, float o = 0)
: m_positionX(x), m_positionY(y), m_positionZ(z), m_orientation(NormalizeOrientation(o)) { }
Position(Position const& loc) { Relocate(loc); }
struct PositionXYStreamer
{
explicit PositionXYStreamer(Position& pos) : Pos(&pos) { }
Position* Pos;
};
struct PositionXYZStreamer
{
explicit PositionXYZStreamer(Position& pos) : m_pos(&pos) {}
@@ -382,19 +393,38 @@ struct Position
float m_positionZ;
float m_orientation;
bool operator==(Position const &a);
inline bool operator!=(Position const &a)
{
return !(operator==(a));
}
void Relocate(float x, float y)
{ m_positionX = x; m_positionY = y;}
{
m_positionX = x; m_positionY = y;
}
void Relocate(float x, float y, float z)
{ m_positionX = x; m_positionY = y; m_positionZ = z; }
{
m_positionX = x; m_positionY = y; m_positionZ = z;
}
void Relocate(float x, float y, float z, float orientation)
{ m_positionX = x; m_positionY = y; m_positionZ = z; m_orientation = orientation; }
{
m_positionX = x; m_positionY = y; m_positionZ = z; m_orientation = orientation;
}
void Relocate(const Position &pos)
{ m_positionX = pos.m_positionX; m_positionY = pos.m_positionY; m_positionZ = pos.m_positionZ; m_orientation = pos.m_orientation; }
{
m_positionX = pos.m_positionX; m_positionY = pos.m_positionY; m_positionZ = pos.m_positionZ; m_orientation = pos.m_orientation;
}
void Relocate(const Position* pos)
{ m_positionX = pos->m_positionX; m_positionY = pos->m_positionY; m_positionZ = pos->m_positionZ; m_orientation = pos->m_orientation; }
{
m_positionX = pos->m_positionX; m_positionY = pos->m_positionY; m_positionZ = pos->m_positionZ; m_orientation = pos->m_orientation;
}
void RelocateOffset(const Position &offset);
void SetOrientation(float orientation)
{ m_orientation = orientation; }
{
m_orientation = orientation;
}
float GetPositionX() const { return m_positionX; }
float GetPositionY() const { return m_positionY; }
@@ -402,17 +432,26 @@ struct Position
float GetOrientation() const { return m_orientation; }
void GetPosition(float &x, float &y) const
{ x = m_positionX; y = m_positionY; }
{
x = m_positionX; y = m_positionY;
}
void GetPosition(float &x, float &y, float &z) const
{ x = m_positionX; y = m_positionY; z = m_positionZ; }
{
x = m_positionX; y = m_positionY; z = m_positionZ;
}
void GetPosition(float &x, float &y, float &z, float &o) const
{ x = m_positionX; y = m_positionY; z = m_positionZ; o = m_orientation; }
{
x = m_positionX; y = m_positionY; z = m_positionZ; o = m_orientation;
}
void GetPosition(Position* pos) const
{
if (pos)
pos->Relocate(m_positionX, m_positionY, m_positionZ, m_orientation);
}
Position GetPosition() const { return *this; }
Position::PositionXYZStreamer PositionXYZStream()
{
return PositionXYZStreamer(*this);
@@ -425,39 +464,65 @@ struct Position
bool IsPositionValid() const;
float GetExactDist2dSq(float x, float y) const
{ float dx = m_positionX - x; float dy = m_positionY - y; return dx*dx + dy*dy; }
{
float dx = m_positionX - x; float dy = m_positionY - y; return dx*dx + dy*dy;
}
float GetExactDist2d(const float x, const float y) const
{ return sqrt(GetExactDist2dSq(x, y)); }
{
return sqrt(GetExactDist2dSq(x, y));
}
float GetExactDist2dSq(const Position* pos) const
{ float dx = m_positionX - pos->m_positionX; float dy = m_positionY - pos->m_positionY; return dx*dx + dy*dy; }
{
float dx = m_positionX - pos->m_positionX; float dy = m_positionY - pos->m_positionY; return dx*dx + dy*dy;
}
float GetExactDist2d(const Position* pos) const
{ return sqrt(GetExactDist2dSq(pos)); }
{
return sqrt(GetExactDist2dSq(pos));
}
float GetExactDistSq(float x, float y, float z) const
{ float dz = m_positionZ - z; return GetExactDist2dSq(x, y) + dz*dz; }
{
float dz = m_positionZ - z; return GetExactDist2dSq(x, y) + dz*dz;
}
float GetExactDist(float x, float y, float z) const
{ return sqrt(GetExactDistSq(x, y, z)); }
{
return sqrt(GetExactDistSq(x, y, z));
}
float GetExactDistSq(const Position* pos) const
{ float dx = m_positionX - pos->m_positionX; float dy = m_positionY - pos->m_positionY; float dz = m_positionZ - pos->m_positionZ; return dx*dx + dy*dy + dz*dz; }
{
float dx = m_positionX - pos->m_positionX; float dy = m_positionY - pos->m_positionY; float dz = m_positionZ - pos->m_positionZ; return dx*dx + dy*dy + dz*dz;
}
float GetExactDist(const Position* pos) const
{ return sqrt(GetExactDistSq(pos)); }
{
return sqrt(GetExactDistSq(pos));
}
void GetPositionOffsetTo(const Position & endPos, Position & retOffset) const;
float GetAngle(const Position* pos) const;
float GetAngle(float x, float y) const;
float GetRelativeAngle(const Position* pos) const
{ return GetAngle(pos) - m_orientation; }
{
return GetAngle(pos) - m_orientation;
}
float GetRelativeAngle(float x, float y) const { return GetAngle(x, y) - m_orientation; }
void GetSinCos(float x, float y, float &vsin, float &vcos) const;
bool IsInDist2d(float x, float y, float dist) const
{ return GetExactDist2dSq(x, y) < dist * dist; }
{
return GetExactDist2dSq(x, y) < dist * dist;
}
bool IsInDist2d(const Position* pos, float dist) const
{ return GetExactDist2dSq(pos) < dist * dist; }
{
return GetExactDist2dSq(pos) < dist * dist;
}
bool IsInDist(float x, float y, float z, float dist) const
{ return GetExactDistSq(x, y, z) < dist * dist; }
{
return GetExactDistSq(x, y, z) < dist * dist;
}
bool IsInDist(const Position* pos, float dist) const
{ return GetExactDistSq(pos) < dist * dist; }
{
return GetExactDistSq(pos) < dist * dist;
}
bool IsWithinBox(const Position& center, float xradius, float yradius, float zradius) const;
bool HasInArc(float arcangle, const Position* pos, float targetRadius = 0.0f) const;
@@ -479,10 +544,13 @@ struct Position
return fmod(o, 2.0f * static_cast<float>(M_PI));
}
};
ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer);
ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYStreamer const& streamer);
ByteBuffer& operator >> (ByteBuffer& buf, Position::PositionXYStreamer const& streamer);
ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer);
ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer);
ByteBuffer& operator >> (ByteBuffer& buf, Position::PositionXYZStreamer const& streamer);
ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer);
ByteBuffer& operator >> (ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer);
struct MovementInfo
{
@@ -785,6 +853,8 @@ class WorldObject : public Object, public WorldLocation
}
bool IsWithinLOS(float x, float y, float z) const;
bool IsWithinLOSInMap(const WorldObject* obj) const;
Position GetHitSpherePointFor(Position const& dest) const;
void GetHitSpherePointFor(Position const& dest, float& x, float& y, float& z) const;
bool GetDistanceOrder(WorldObject const* obj1, WorldObject const* obj2, bool is3D = true) const;
bool IsInRange(WorldObject const* obj, float minRange, float maxRange, bool is3D = true) const;
bool IsInRange2d(float x, float y, float minRange, float maxRange) const;
+1
View File
@@ -960,6 +960,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
SetCreateHealth(4 * petlevel);
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - 30 - (petlevel / 4) + m_owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.006f));
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel - 30 + (petlevel / 4) + m_owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.006f));
SetReactState(REACT_DEFENSIVE);
break;
}
case NPC_ARMY_OF_THE_DEAD:
+83 -60
View File
@@ -2189,8 +2189,8 @@ void Player::SendTeleportAckPacket()
GetSession()->SendPacket(&data);
}
bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options)
{
bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options /*= 0*/, Unit *target /*= nullptr*/)
{
if (!MapManager::IsValidMapCoord(mapid, x, y, z, orientation))
{
sLog->outError("TeleportTo: invalid map (%d) or invalid coordinates (X: %f, Y: %f, Z: %f, O: %f) given when teleporting player (GUID: %u, name: %s, map: %d, X: %f, Y: %f, Z: %f, O: %f).",
@@ -2288,6 +2288,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
if (duel && GetMapId() != mapid && GetMap()->GetGameObject(GetUInt64Value(PLAYER_DUEL_ARBITER)))
DuelComplete(DUEL_FLED);
if (!sScriptMgr->OnBeforePlayerTeleport(this, mapid, x, y, z, orientation, options, target))
return false;
if (GetMapId() == mapid)
{
//lets reset far teleport flag if it wasn't reset during chained teleports
@@ -3026,11 +3029,7 @@ void Player::SetGameMaster(bool on)
else
{
// restore phase
uint32 newPhase = 0;
AuraEffectList const& phases = GetAuraEffectsByType(SPELL_AURA_PHASE);
if (!phases.empty())
for (AuraEffectList::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
newPhase |= (*itr)->GetMiscValue();
uint32 newPhase = GetPhaseByAuras();
if (!newPhase)
newPhase = PHASEMASK_NORMAL;
@@ -3063,14 +3062,21 @@ void Player::SetGameMaster(bool on)
}
void Player::SetGMVisible(bool on)
{
{
const uint32 VISUAL_AURA = 37800;
if (on)
{
if (HasAura(VISUAL_AURA, 0))
RemoveAurasDueToSpell(VISUAL_AURA);
m_ExtraFlags &= ~PLAYER_EXTRA_GM_INVISIBLE; //remove flag
m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GM, SEC_PLAYER);
}
else
{
AddAura(VISUAL_AURA, this);
m_ExtraFlags |= PLAYER_EXTRA_GM_INVISIBLE; //add flag
SetAcceptWhispers(false);
@@ -5286,7 +5292,7 @@ void Player::CreateCorpse()
return;
}
_uf = GetUInt32Value(UNIT_FIELD_BYTES_0);
_uf = getRace();
_pb = GetUInt32Value(PLAYER_BYTES);
_pb2 = GetUInt32Value(PLAYER_BYTES_2);
@@ -5577,11 +5583,11 @@ void Player::RepopAtGraveyard()
// note: this can be called also when the player is alive
// for example from WorldSession::HandleMovementOpcodes
AreaTableEntry const* zone = GetAreaEntryByAreaID(GetAreaId());
AreaTableEntry const* zone = sAreaTableStore.LookupEntry(GetAreaId());
// Such zones are considered unreachable as a ghost and the player must be automatically revived
// Xinef: Get Transport Check is not needed
if ((!IsAlive() && zone && zone->flags & AREA_FLAG_NEED_FLY) /*|| GetTransport()*/ || GetPositionZ() < -500.0f)
if ((!IsAlive() && zone && zone->flags & AREA_FLAG_NEED_FLY) /*|| GetTransport()*/ || GetPositionZ() < GetMap()->GetMinHeight(GetPositionX(), GetPositionY()))
{
ResurrectPlayer(0.5f);
SpawnCorpseBones();
@@ -5618,8 +5624,10 @@ void Player::RepopAtGraveyard()
GetSession()->SendPacket(&data);
}
}
else if (GetPositionZ() < -500.0f)
else if (GetPositionZ() < GetMap()->GetMinHeight(GetPositionX(), GetPositionY()))
TeleportTo(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, GetOrientation());
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_IS_OUT_OF_BOUNDS);
}
bool Player::CanJoinConstantChannelInZone(ChatChannelsEntry const* channel, AreaTableEntry const* zone)
@@ -5671,7 +5679,7 @@ void Player::UpdateLocalChannels(uint32 newZone)
if (GetSession()->PlayerLoading() && !IsBeingTeleportedFar())
return; // The client handles it automatically after loading, but not after teleporting
AreaTableEntry const* current_zone = GetAreaEntryByAreaID(newZone);
AreaTableEntry const* current_zone = sAreaTableStore.LookupEntry(newZone);
if (!current_zone)
return;
@@ -6894,45 +6902,46 @@ void Player::CheckAreaExploreAndOutdoor()
return;
bool isOutdoor = IsOutdoors();
uint32 areaFlag = GetAreaFlagByAreaID(GetAreaId());
uint32 areaId = GetBaseMap()->GetAreaId(GetPositionX(), GetPositionY(), GetPositionZ(), &isOutdoor);
AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(areaId);
if (sWorld->getBoolConfig(CONFIG_VMAP_INDOOR_CHECK) && !isOutdoor)
RemoveAurasWithAttribute(SPELL_ATTR0_OUTDOORS_ONLY);
if (areaFlag == 0xffff)
if (!areaId)
return;
int offset = areaFlag / 32;
if (!areaEntry)
{
sLog->outError("Player '%s' (%u) discovered unknown area (x: %f y: %f z: %f map: %u)",
GetName().c_str(), GetGUIDLow(), GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId());
return;
}
uint32 offset = areaEntry->exploreFlag / 32;
if (offset >= PLAYER_EXPLORED_ZONES_SIZE)
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
sLog->outError("Wrong area flag %u in map data for (X: %f Y: %f) point to field PLAYER_EXPLORED_ZONES_1 + %u ( %u must be < %u ).", areaFlag, GetPositionX(), GetPositionY(), offset, offset, PLAYER_EXPLORED_ZONES_SIZE);
sLog->outError("Wrong area flag %u in map data for (X: %f Y: %f) point to field PLAYER_EXPLORED_ZONES_1 + %u ( %u must be < %u ).", areaEntry->flags, GetPositionX(), GetPositionY(), offset, offset, PLAYER_EXPLORED_ZONES_SIZE);
#endif
return;
}
uint32 val = (uint32)(1 << (areaFlag % 32));
uint32 val = (uint32)(1 << (areaEntry->exploreFlag % 32));
uint32 currFields = GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset);
if (!(currFields & val))
{
SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val));
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA, GetAreaId());
AreaTableEntry const* areaEntry = GetAreaEntryByAreaFlagAndMap(areaFlag, GetMapId());
if (!areaEntry)
{
sLog->outError("Player %u discovered unknown area (x: %f y: %f z: %f map: %u", GetGUIDLow(), GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId());
return;
}
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA, areaId);
if (areaEntry->area_level > 0)
{
uint32 area = areaEntry->ID;
if (getLevel() >= sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
{
SendExplorationExperience(area, 0);
SendExplorationExperience(areaId, 0);
}
else
{
@@ -6958,10 +6967,10 @@ void Player::CheckAreaExploreAndOutdoor()
}
GiveXP(XP, NULL);
SendExplorationExperience(area, XP);
SendExplorationExperience(areaId, XP);
}
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
sLog->outDetail("Player %u discovered a new area: %u", GetGUIDLow(), area);
sLog->outDetail("Player %u discovered a new area: %u", GetGUIDLow(), areaId);
#endif
}
}
@@ -7528,12 +7537,14 @@ void Player::UpdateArea(uint32 newArea)
// pussywizard: inform instance, needed for Icecrown Citadel
if (InstanceScript* instance = GetInstanceScript())
instance->OnPlayerAreaUpdate(this, m_areaUpdateId, newArea);
sScriptMgr->OnPlayerUpdateArea(this, m_areaUpdateId, newArea);
// FFA_PVP flags are area and not zone id dependent
// so apply them accordingly
m_areaUpdateId = newArea;
AreaTableEntry const* area = GetAreaEntryByAreaID(newArea);
AreaTableEntry const* area = sAreaTableStore.LookupEntry(newArea);
bool oldFFAPvPArea = pvpInfo.IsInFFAPvPArea;
pvpInfo.IsInFFAPvPArea = area && (area->flags & AREA_FLAG_ARENA);
UpdatePvPState(true);
@@ -7568,7 +7579,7 @@ void Player::UpdateArea(uint32 newArea)
}
// Xinef: area should inherit zone flags
AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone);
AreaTableEntry const* zone = sAreaTableStore.LookupEntry(area->zone);
uint32 areaFlags = area->flags;
bool isSanctuary = area->IsSanctuary();
bool isInn = area->IsInn(GetTeamId(true));
@@ -7656,7 +7667,7 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
// zone changed, so area changed as well, update it
UpdateArea(newArea);
AreaTableEntry const* zone = GetAreaEntryByAreaID(newZone);
AreaTableEntry const* zone = sAreaTableStore.LookupEntry(newZone);
if (!zone)
return;
@@ -9258,6 +9269,12 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
loot->FillLoot(creature->GetCreatureTemplate()->SkinLootId, LootTemplates_Skinning, this, true);
permission = OWNER_PERMISSION;
//Inform instance if creature is skinned.
if (InstanceScript* mapInstance = creature->GetInstanceScript())
{
mapInstance->CreatureLooted(creature, LOOT_SKINNING);
}
// Xinef: Set new loot recipient
creature->SetLootRecipient(this, false);
}
@@ -20736,7 +20753,7 @@ void Player::Say(const std::string& text, const uint32 language)
sScriptMgr->OnPlayerChat(this, CHAT_MSG_SAY, language, _text);
WorldPacket data;
ChatHandler::BuildChatPacket(data, CHAT_MSG_SAY, Language(language), this, this, text);
ChatHandler::BuildChatPacket(data, CHAT_MSG_SAY, Language(language), this, this, _text);
SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true);
}
@@ -20746,7 +20763,7 @@ void Player::Yell(const std::string& text, const uint32 language)
sScriptMgr->OnPlayerChat(this, CHAT_MSG_YELL, language, _text);
WorldPacket data;
ChatHandler::BuildChatPacket(data, CHAT_MSG_YELL, Language(language), this, this, text);
ChatHandler::BuildChatPacket(data, CHAT_MSG_YELL, Language(language), this, this, _text);
SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), true);
}
@@ -20756,7 +20773,7 @@ void Player::TextEmote(const std::string& text)
sScriptMgr->OnPlayerChat(this, CHAT_MSG_EMOTE, LANG_UNIVERSAL, _text);
WorldPacket data;
ChatHandler::BuildChatPacket(data, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, text);
ChatHandler::BuildChatPacket(data, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text);
SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT));
}
@@ -20773,14 +20790,14 @@ void Player::Whisper(const std::string& text, uint32 language, uint64 receiver)
sScriptMgr->OnPlayerChat(this, CHAT_MSG_WHISPER, language, _text, rPlayer);
WorldPacket data;
ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, Language(language), this, this, text);
ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, Language(language), this, this, _text);
rPlayer->GetSession()->SendPacket(&data);
// rest stuff shouldn't happen in case of addon message
if (isAddonMessage)
return;
ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER_INFORM, Language(language), rPlayer, rPlayer, text);
ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER_INFORM, Language(language), rPlayer, rPlayer, _text);
GetSession()->SendPacket(&data);
if (!isAcceptWhispers() && !IsGameMaster() && !rPlayer->IsGameMaster())
@@ -22658,19 +22675,30 @@ bool Player::IsVisibleGloballyFor(Player const* u) const
}
template<class T>
inline void UpdateVisibilityOf_helper(T* /*target*/, std::vector<Unit*>& /*v*/)
inline void UpdateVisibilityOf_helper(Player::ClientGUIDs& s64, T* target, std::vector<Unit*>& /*v*/)
{
s64.insert(target->GetGUID());
}
template<>
inline void UpdateVisibilityOf_helper(Creature* target, std::vector<Unit*>& v)
inline void UpdateVisibilityOf_helper(Player::ClientGUIDs& s64, GameObject* target, std::vector<Unit*>& /*v*/)
{
// @HACK: This is to prevent objects like deeprun tram from disappearing when player moves far from its spawn point while riding it
if ((target->GetGOInfo()->type != GAMEOBJECT_TYPE_TRANSPORT))
s64.insert(target->GetGUID());
}
template<>
inline void UpdateVisibilityOf_helper(Player::ClientGUIDs& s64, Creature* target, std::vector<Unit*>& v)
{
s64.insert(target->GetGUID());
v.push_back(target);
}
template<>
inline void UpdateVisibilityOf_helper(Player* target, std::vector<Unit*>& v)
inline void UpdateVisibilityOf_helper(Player::ClientGUIDs& s64, Player* target, std::vector<Unit*>& v)
{
s64.insert(target->GetGUID());
v.push_back(target);
}
@@ -22784,9 +22812,7 @@ void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::vector<Unit*>&
if (CanSeeOrDetect(target, false, true))
{
target->BuildCreateUpdateBlockForPlayer(&data, this);
m_clientGUIDs.insert(target->GetGUID());
UpdateVisibilityOf_helper(target, visibleNow);
UpdateVisibilityOf_helper(m_clientGUIDs, target, visibleNow);
}
}
}
@@ -23610,8 +23636,8 @@ void Player::UpdateForQuestWorldObjects()
GetSession()->SendPacket(&packet);
}
void Player::SummonIfPossible(bool agree)
{
void Player::SummonIfPossible(bool agree, uint32 summoner_guid)
{
if (!agree)
{
m_summon_expire = 0;
@@ -23631,7 +23657,7 @@ void Player::SummonIfPossible(bool agree)
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS, 1);
TeleportTo(m_summon_mapid, m_summon_x, m_summon_y, m_summon_z, GetOrientation());
TeleportTo(m_summon_mapid, m_summon_x, m_summon_y, m_summon_z, GetOrientation(), 0, ObjectAccessor::FindPlayer(summoner_guid));
}
void Player::RemoveItemDurations(Item* item)
@@ -25226,22 +25252,19 @@ void Player::_LoadSkills(PreparedQueryResult result)
}
uint32 Player::GetPhaseMaskForSpawn() const
{
uint32 phase = PHASEMASK_NORMAL;
if (!IsGameMaster())
phase = GetPhaseMask();
else
{
AuraEffectList const& phases = GetAuraEffectsByType(SPELL_AURA_PHASE);
if (!phases.empty())
phase = phases.front()->GetMiscValue();
}
{
uint32 phase = IsGameMaster() ? GetPhaseByAuras() : GetPhaseMask();
if (!phase)
phase = PHASEMASK_NORMAL;
// some aura phases include 1 normal map in addition to phase itself
if (uint32 n_phase = phase & ~PHASEMASK_NORMAL)
uint32 n_phase = phase & ~PHASEMASK_NORMAL;
if (n_phase > 0)
return n_phase;
return PHASEMASK_NORMAL;
return phase;
}
InventoryResult Player::CanEquipUniqueItem(Item* pItem, uint8 eslot, uint32 limit_count) const
+4 -4
View File
@@ -1096,10 +1096,10 @@ class Player : public Unit, public GridObject<Player>
SetFloatValue(UNIT_FIELD_COMBATREACH, scale * DEFAULT_COMBAT_REACH);
}
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0);
bool TeleportTo(WorldLocation const &loc, uint32 options = 0)
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0, Unit *target = nullptr);
bool TeleportTo(WorldLocation const &loc, uint32 options = 0, Unit *target = nullptr)
{
return TeleportTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation(), options);
return TeleportTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation(), options, target);
}
bool TeleportToEntryPoint();
@@ -1114,7 +1114,7 @@ class Player : public Unit, public GridObject<Player>
}
bool IsSummonAsSpectator() const { return m_summon_asSpectator && m_summon_expire >= time(NULL); }
void SetSummonAsSpectator(bool on) { m_summon_asSpectator = on; }
void SummonIfPossible(bool agree);
void SummonIfPossible(bool agree, uint32 summoner_guid);
time_t GetSummonExpireTimer() const { return m_summon_expire; }
bool Create(uint32 guidlow, CharacterCreateInfo* createInfo);
+23 -3
View File
@@ -3395,6 +3395,15 @@ int32 Unit::GetCurrentSpellCastTime(uint32 spell_id) const
return 0;
}
bool Unit::CanMoveDuringChannel() const
{
if (Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL])
if (spell->getState() != SPELL_STATE_FINISHED)
return spell->GetSpellInfo()->HasAttribute(SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING) && spell->IsChannelActive();
return false;
}
bool Unit::isInFrontInMap(Unit const* target, float distance, float arc) const
{
return IsWithinDistInMap(target, distance) && HasInArc(arc, target);
@@ -13690,7 +13699,7 @@ void Unit::ModSpellCastTime(SpellInfo const* spellInfo, int32 & castTime, Spell*
if (!spellInfo || castTime < 0)
return;
if (spellInfo->IsChanneled() && !(spellInfo->AttributesEx5 & SPELL_ATTR5_HASTE_AFFECT_DURATION))
if (spellInfo->IsChanneled() && spellInfo->HasAura(SPELL_AURA_MOUNTED))
return;
// called from caster
@@ -14493,7 +14502,7 @@ void CharmInfo::InitPossessCreateSpells()
{
uint32 spellId = _unit->ToCreature()->m_spells[i];
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (spellInfo && !spellInfo->HasAttribute(SPELL_ATTR0_CASTABLE_WHILE_DEAD))
if (spellInfo)
{
if (spellInfo->IsPassive())
_unit->CastSpell(_unit, spellInfo, true);
@@ -14523,7 +14532,7 @@ void CharmInfo::InitCharmCreateSpells()
uint32 spellId = _unit->ToCreature()->m_spells[x];
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo || spellInfo->HasAttribute(SPELL_ATTR0_CASTABLE_WHILE_DEAD))
if (!spellInfo)
{
_charmspells[x].SetActionAndType(spellId, ACT_DISABLED);
continue;
@@ -17547,6 +17556,17 @@ float Unit::MeleeSpellMissChance(const Unit* victim, WeaponAttackType attType, i
return missChance;
}
uint32 Unit::GetPhaseByAuras() const
{
uint32 currentPhase = 0;
AuraEffectList const& phases = GetAuraEffectsByType(SPELL_AURA_PHASE);
if (!phases.empty())
for (AuraEffectList::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
currentPhase |= (*itr)->GetMiscValue();
return currentPhase;
}
void Unit::SetPhaseMask(uint32 newPhaseMask, bool update)
{
if (newPhaseMask == GetPhaseMask())
+4
View File
@@ -2048,6 +2048,9 @@ class Unit : public WorldObject
// delayed+channeled spells are always interrupted
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid = 0, bool withInstant = true, bool bySelf = false);
// Check if our current channel spell has attribute SPELL_ATTR5_CAN_CHANNEL_WHEN_MOVING
bool CanMoveDuringChannel() const;
Spell* GetCurrentSpell(CurrentSpellTypes spellType) const { return m_currentSpells[spellType]; }
Spell* GetCurrentSpell(uint32 spellType) const { return m_currentSpells[spellType]; }
Spell* FindCurrentSpellBySpellId(uint32 spell_id) const;
@@ -2122,6 +2125,7 @@ class Unit : public WorldObject
void SetModelVisible(bool on);
// common function for visibility checks for player/creatures with detection code
uint32 GetPhaseByAuras() const;
void SetPhaseMask(uint32 newPhaseMask, bool update);// overwrite WorldObject::SetPhaseMask
void UpdateObjectVisibility(bool forced = true, bool fromUpdate = false);