Merge branch 'master' into Playerbot
This commit is contained in:
@@ -31,13 +31,13 @@
|
||||
#include "GroupMgr.h"
|
||||
#include "Log.h"
|
||||
#include "LootMgr.h"
|
||||
#include "MapMgr.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Opcodes.h"
|
||||
#include "OutdoorPvPMgr.h"
|
||||
#include "Pet.h"
|
||||
#include "Player.h"
|
||||
#include "PoolMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellMgr.h"
|
||||
@@ -301,6 +301,9 @@ void Creature::RemoveFromWorld()
|
||||
if (m_formation)
|
||||
sFormationMgr->RemoveCreatureFromGroup(m_formation, this);
|
||||
|
||||
if (Transport* transport = GetTransport())
|
||||
transport->RemovePassenger(this, true);
|
||||
|
||||
Unit::RemoveFromWorld();
|
||||
|
||||
if (m_spawnId)
|
||||
@@ -316,7 +319,7 @@ void Creature::DisappearAndDie()
|
||||
//SetVisibility(VISIBILITY_OFF);
|
||||
//ObjectAccessor::UpdateObjectVisibility(this);
|
||||
if (IsAlive())
|
||||
setDeathState(JUST_DIED, true);
|
||||
setDeathState(DeathState::JustDied, true);
|
||||
RemoveCorpse(false, true);
|
||||
}
|
||||
|
||||
@@ -342,11 +345,11 @@ void Creature::SearchFormation()
|
||||
|
||||
void Creature::RemoveCorpse(bool setSpawnTime, bool skipVisibility)
|
||||
{
|
||||
if (getDeathState() != CORPSE)
|
||||
if (getDeathState() != DeathState::Corpse)
|
||||
return;
|
||||
|
||||
m_corpseRemoveTime = GameTime::GetGameTime().count();
|
||||
setDeathState(DEAD);
|
||||
setDeathState(DeathState::Dead);
|
||||
RemoveAllAuras();
|
||||
if (!skipVisibility) // pussywizard
|
||||
DestroyForNearbyPlayers(); // pussywizard: previous UpdateObjectVisibility()
|
||||
@@ -362,15 +365,17 @@ void Creature::RemoveCorpse(bool setSpawnTime, bool skipVisibility)
|
||||
//SaveRespawnTime();
|
||||
}
|
||||
|
||||
float x, y, z, o;
|
||||
GetRespawnPosition(x, y, z, &o);
|
||||
SetHomePosition(x, y, z, o);
|
||||
SetPosition(x, y, z, o);
|
||||
|
||||
// xinef: relocate notifier
|
||||
m_last_notify_position.Relocate(-5000.0f, -5000.0f, -5000.0f, 0.0f);
|
||||
|
||||
// pussywizard: if corpse was removed during falling then the falling will continue after respawn, so stop falling is such case
|
||||
if (IsFalling())
|
||||
StopMoving();
|
||||
|
||||
float x, y, z, o;
|
||||
GetRespawnPosition(x, y, z, &o);
|
||||
UpdateAllowedPositionZ(x, y, z);
|
||||
SetHomePosition(x, y, z, o);
|
||||
GetMap()->CreatureRelocation(this, x, y, z, o);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -604,61 +609,28 @@ void Creature::Update(uint32 diff)
|
||||
|
||||
switch (m_deathState)
|
||||
{
|
||||
case JUST_RESPAWNED:
|
||||
case DeathState::JustRespawned:
|
||||
// Must not be called, see Creature::setDeathState JUST_RESPAWNED -> ALIVE promoting.
|
||||
LOG_ERROR("entities.unit", "Creature ({}) in wrong state: JUST_RESPAWNED (4)", GetGUID().ToString());
|
||||
LOG_ERROR("entities.unit", "Creature ({}) in wrong state: DeathState::JustRespawned (4)", GetGUID().ToString());
|
||||
break;
|
||||
case JUST_DIED:
|
||||
case DeathState::JustDied:
|
||||
// Must not be called, see Creature::setDeathState JUST_DIED -> CORPSE promoting.
|
||||
LOG_ERROR("entities.unit", "Creature ({}) in wrong state: JUST_DEAD (1)", GetGUID().ToString());
|
||||
LOG_ERROR("entities.unit", "Creature ({}) in wrong state: DeathState::JustDead (1)", GetGUID().ToString());
|
||||
break;
|
||||
case DEAD:
|
||||
case DeathState::Dead:
|
||||
{
|
||||
time_t now = GameTime::GetGameTime().count();
|
||||
if (m_respawnTime <= now)
|
||||
{
|
||||
|
||||
ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_CREATURE_RESPAWN, GetEntry());
|
||||
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(this, conditions))
|
||||
{
|
||||
// Creature should not respawn, reset respawn timer. Conditions will be checked again the next time it tries to respawn.
|
||||
m_respawnTime = GameTime::GetGameTime().count() + m_respawnDelay;
|
||||
break;
|
||||
}
|
||||
|
||||
bool allowed = !IsAIEnabled || AI()->CanRespawn(); // First check if there are any scripts that prevent us respawning
|
||||
if (!allowed) // Will be rechecked on next Update call
|
||||
break;
|
||||
|
||||
ObjectGuid dbtableHighGuid = ObjectGuid::Create<HighGuid::Unit>(m_creatureData ? m_creatureData->id1 : GetEntry(), m_spawnId);
|
||||
time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid);
|
||||
|
||||
CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(GetEntry());
|
||||
|
||||
if (!linkedRespawntime || (cInfo && cInfo->HasFlagsExtra(CREATURE_FLAG_EXTRA_HARD_RESET))) // Can respawn
|
||||
Respawn();
|
||||
else // the master is dead
|
||||
{
|
||||
ObjectGuid targetGuid = sObjectMgr->GetLinkedRespawnGuid(dbtableHighGuid);
|
||||
if (targetGuid == dbtableHighGuid) // if linking self, never respawn (check delayed to next day)
|
||||
{
|
||||
SetRespawnTime(DAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_respawnTime = (now > linkedRespawntime ? now : linkedRespawntime) + urand(5, MINUTE); // else copy time from master and add a little
|
||||
}
|
||||
SaveRespawnTime(); // also save to DB immediately
|
||||
}
|
||||
Respawn();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CORPSE:
|
||||
case DeathState::Corpse:
|
||||
{
|
||||
Unit::Update(diff);
|
||||
// deathstate changed on spells update, prevent problems
|
||||
if (m_deathState != CORPSE)
|
||||
if (m_deathState != DeathState::Corpse)
|
||||
break;
|
||||
|
||||
if (m_groupLootTimer && lootingGroupLowGUID)
|
||||
@@ -683,7 +655,7 @@ void Creature::Update(uint32 diff)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ALIVE:
|
||||
case DeathState::Alive:
|
||||
{
|
||||
Unit::Update(diff);
|
||||
|
||||
@@ -1721,12 +1693,12 @@ bool Creature::LoadCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool ad
|
||||
m_wanderDistance = data->wander_distance;
|
||||
|
||||
m_respawnDelay = data->spawntimesecs;
|
||||
m_deathState = ALIVE;
|
||||
m_deathState = DeathState::Alive;
|
||||
|
||||
m_respawnTime = GetMap()->GetCreatureRespawnTime(m_spawnId);
|
||||
if (m_respawnTime) // respawn on Update
|
||||
{
|
||||
m_deathState = DEAD;
|
||||
m_deathState = DeathState::Dead;
|
||||
if (CanFly())
|
||||
{
|
||||
float tz = map->GetHeight(GetPhaseMask(), data->posX, data->posY, data->posZ, true, MAX_FALL_DISTANCE);
|
||||
@@ -1756,7 +1728,7 @@ bool Creature::LoadCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool ad
|
||||
SetPower(POWER_MANA, GetMaxPower(POWER_MANA));
|
||||
}
|
||||
|
||||
SetHealth(m_deathState == ALIVE ? curhealth : 0);
|
||||
SetHealth(m_deathState == DeathState::Alive ? curhealth : 0);
|
||||
|
||||
// checked at creature_template loading
|
||||
m_defaultMovementType = MovementGeneratorType(data->movementType);
|
||||
@@ -1824,25 +1796,7 @@ void Creature::DeleteFromDB()
|
||||
return;
|
||||
}
|
||||
|
||||
CreatureData const* data = sObjectMgr->GetCreatureData(m_spawnId);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
CharacterDatabaseTransaction charTrans = CharacterDatabase.BeginTransaction();
|
||||
|
||||
sMapMgr->DoForAllMapsWithMapId(data->mapid,
|
||||
[this, charTrans](Map* map) -> void
|
||||
{
|
||||
// despawn all active creatures, and remove their respawns
|
||||
std::vector<Creature*> toUnload;
|
||||
for (auto const& pair : Acore::Containers::MapEqualRange(map->GetCreatureBySpawnIdStore(), m_spawnId))
|
||||
toUnload.push_back(pair.second);
|
||||
for (Creature* creature : toUnload)
|
||||
map->AddObjectToRemoveList(creature);
|
||||
map->RemoveCreatureRespawnTime(m_spawnId);
|
||||
}
|
||||
);
|
||||
|
||||
GetMap()->RemoveCreatureRespawnTime(m_spawnId);
|
||||
sObjectMgr->DeleteCreatureData(m_spawnId);
|
||||
|
||||
WorldDatabaseTransaction trans = WorldDatabase.BeginTransaction();
|
||||
@@ -1951,7 +1905,7 @@ void Creature::setDeathState(DeathState s, bool despawn)
|
||||
{
|
||||
Unit::setDeathState(s, despawn);
|
||||
|
||||
if (s == JUST_DIED)
|
||||
if (s == DeathState::JustDied)
|
||||
{
|
||||
_lastDamagedTime.reset();
|
||||
|
||||
@@ -1985,9 +1939,9 @@ void Creature::setDeathState(DeathState s, bool despawn)
|
||||
if (needsFalling)
|
||||
GetMotionMaster()->MoveFall(0, true);
|
||||
|
||||
Unit::setDeathState(CORPSE, despawn);
|
||||
Unit::setDeathState(DeathState::Corpse, despawn);
|
||||
}
|
||||
else if (s == JUST_RESPAWNED)
|
||||
else if (s == DeathState::JustRespawned)
|
||||
{
|
||||
//if (IsPet())
|
||||
// setActive(true);
|
||||
@@ -2009,7 +1963,7 @@ void Creature::setDeathState(DeathState s, bool despawn)
|
||||
ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_IGNORE_PATHFINDING | UNIT_STATE_NO_ENVIRONMENT_UPD)));
|
||||
SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool));
|
||||
|
||||
Unit::setDeathState(ALIVE, despawn);
|
||||
Unit::setDeathState(DeathState::Alive, despawn);
|
||||
|
||||
Motion_Initialize();
|
||||
LoadCreaturesAddon(true);
|
||||
@@ -2020,81 +1974,121 @@ void Creature::setDeathState(DeathState s, bool despawn)
|
||||
|
||||
void Creature::Respawn(bool force)
|
||||
{
|
||||
//DestroyForNearbyPlayers(); // pussywizard: not needed
|
||||
|
||||
if (force)
|
||||
{
|
||||
if (IsAlive())
|
||||
setDeathState(JUST_DIED);
|
||||
else if (getDeathState() != CORPSE)
|
||||
setDeathState(CORPSE);
|
||||
{
|
||||
setDeathState(DeathState::JustDied);
|
||||
}
|
||||
else if (getDeathState() != DeathState::Corpse)
|
||||
{
|
||||
setDeathState(DeathState::Corpse);
|
||||
}
|
||||
}
|
||||
|
||||
RemoveCorpse(false, false);
|
||||
ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_CREATURE_RESPAWN, GetEntry());
|
||||
|
||||
if (getDeathState() == DEAD)
|
||||
if (!sConditionMgr->IsObjectMeetToConditions(this, conditions) && !force)
|
||||
{
|
||||
if (m_spawnId)
|
||||
{
|
||||
GetMap()->RemoveCreatureRespawnTime(m_spawnId);
|
||||
CreatureData const* data = sObjectMgr->GetCreatureData(m_spawnId);
|
||||
// Respawn check if spawn has 2 entries
|
||||
if (data->id2)
|
||||
{
|
||||
uint32 entry = GetRandomId(data->id1, data->id2, data->id3);
|
||||
UpdateEntry(entry, data, true); // Select Random Entry
|
||||
m_defaultMovementType = MovementGeneratorType(data->movementType); // Reload Movement Type
|
||||
LoadEquipment(data->equipmentId); // Reload Equipment
|
||||
AIM_Initialize(); // Reload AI
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_originalEntry != GetEntry())
|
||||
UpdateEntry(m_originalEntry);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("entities.unit", "Respawning creature {} (SpawnId: {}, {})", GetName(), GetSpawnId(), GetGUID().ToString());
|
||||
m_respawnTime = 0;
|
||||
ResetPickPocketLootTime();
|
||||
loot.clear();
|
||||
SelectLevel();
|
||||
|
||||
setDeathState(JUST_RESPAWNED);
|
||||
|
||||
// MDic - Acidmanifesto
|
||||
// Do not override transform auras
|
||||
if (GetAuraEffectsByType(SPELL_AURA_TRANSFORM).empty())
|
||||
{
|
||||
uint32 displayID = GetNativeDisplayId();
|
||||
if (sObjectMgr->GetCreatureModelRandomGender(&displayID)) // Cancel load if no model defined
|
||||
{
|
||||
SetDisplayId(displayID);
|
||||
SetNativeDisplayId(displayID);
|
||||
}
|
||||
}
|
||||
|
||||
GetMotionMaster()->InitDefault();
|
||||
|
||||
//Call AI respawn virtual function
|
||||
if (IsAIEnabled)
|
||||
{
|
||||
//reset the AI to be sure no dirty or uninitialized values will be used till next tick
|
||||
AI()->Reset();
|
||||
TriggerJustRespawned = true;//delay event to next tick so all creatures are created on the map before processing
|
||||
}
|
||||
|
||||
uint32 poolid = m_spawnId ? sPoolMgr->IsPartOfAPool<Creature>(m_spawnId) : 0;
|
||||
if (poolid)
|
||||
sPoolMgr->UpdatePool<Creature>(poolid, m_spawnId);
|
||||
|
||||
//Re-initialize reactstate that could be altered by movementgenerators
|
||||
InitializeReactState();
|
||||
|
||||
m_respawnedTime = GameTime::GetGameTime().count();
|
||||
// Creature should not respawn, reset respawn timer. Conditions will be checked again the next time it tries to respawn.
|
||||
m_respawnTime = GameTime::GetGameTime().count() + m_respawnDelay;
|
||||
return;
|
||||
}
|
||||
|
||||
bool allowed = !IsAIEnabled || AI()->CanRespawn(); // First check if there are any scripts that prevent us respawning
|
||||
if (!allowed && !force) // Will be rechecked on next Update call
|
||||
return;
|
||||
|
||||
ObjectGuid dbtableHighGuid = ObjectGuid::Create<HighGuid::Unit>(m_creatureData ? m_creatureData->id1 : GetEntry(), m_spawnId);
|
||||
time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid);
|
||||
|
||||
CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(GetEntry());
|
||||
|
||||
if (!linkedRespawntime || (cInfo && cInfo->HasFlagsExtra(CREATURE_FLAG_EXTRA_HARD_RESET)) || force) // Should respawn
|
||||
{
|
||||
RemoveCorpse(false, false);
|
||||
|
||||
if (getDeathState() == DeathState::Dead)
|
||||
{
|
||||
if (m_spawnId)
|
||||
{
|
||||
GetMap()->RemoveCreatureRespawnTime(m_spawnId);
|
||||
CreatureData const* data = sObjectMgr->GetCreatureData(m_spawnId);
|
||||
// Respawn check if spawn has 2 entries
|
||||
if (data->id2)
|
||||
{
|
||||
uint32 entry = GetRandomId(data->id1, data->id2, data->id3);
|
||||
UpdateEntry(entry, data, true); // Select Random Entry
|
||||
m_defaultMovementType = MovementGeneratorType(data->movementType); // Reload Movement Type
|
||||
LoadEquipment(data->equipmentId); // Reload Equipment
|
||||
AIM_Initialize(); // Reload AI
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_originalEntry != GetEntry())
|
||||
UpdateEntry(m_originalEntry);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("entities.unit", "Respawning creature {} (SpawnId: {}, {})", GetName(), GetSpawnId(), GetGUID().ToString());
|
||||
m_respawnTime = 0;
|
||||
ResetPickPocketLootTime();
|
||||
loot.clear();
|
||||
SelectLevel();
|
||||
|
||||
setDeathState(DeathState::JustRespawned);
|
||||
|
||||
// MDic - Acidmanifesto
|
||||
// Do not override transform auras
|
||||
if (GetAuraEffectsByType(SPELL_AURA_TRANSFORM).empty())
|
||||
{
|
||||
uint32 displayID = GetNativeDisplayId();
|
||||
if (sObjectMgr->GetCreatureModelRandomGender(&displayID)) // Cancel load if no model defined
|
||||
{
|
||||
SetDisplayId(displayID);
|
||||
SetNativeDisplayId(displayID);
|
||||
}
|
||||
}
|
||||
|
||||
GetMotionMaster()->InitDefault();
|
||||
|
||||
//Call AI respawn virtual function
|
||||
if (IsAIEnabled)
|
||||
{
|
||||
//reset the AI to be sure no dirty or uninitialized values will be used till next tick
|
||||
AI()->Reset();
|
||||
TriggerJustRespawned = true;//delay event to next tick so all creatures are created on the map before processing
|
||||
}
|
||||
|
||||
uint32 poolid = m_spawnId ? sPoolMgr->IsPartOfAPool<Creature>(m_spawnId) : 0;
|
||||
if (poolid)
|
||||
sPoolMgr->UpdatePool<Creature>(poolid, m_spawnId);
|
||||
|
||||
//Re-initialize reactstate that could be altered by movementgenerators
|
||||
InitializeReactState();
|
||||
|
||||
m_respawnedTime = GameTime::GetGameTime().count();
|
||||
}
|
||||
m_respawnedTime = GameTime::GetGameTime().count();
|
||||
// xinef: relocate notifier, fixes npc appearing in corpse position after forced respawn (instead of spawn)
|
||||
m_last_notify_position.Relocate(-5000.0f, -5000.0f, -5000.0f, 0.0f);
|
||||
UpdateObjectVisibility(false);
|
||||
|
||||
}
|
||||
else // the master is dead
|
||||
{
|
||||
ObjectGuid targetGuid = sObjectMgr->GetLinkedRespawnGuid(dbtableHighGuid);
|
||||
if (targetGuid == dbtableHighGuid) // if linking self, never respawn (check delayed to next day)
|
||||
{
|
||||
SetRespawnTime(DAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t now = GameTime::GetGameTime().count();
|
||||
m_respawnTime = (now > linkedRespawntime ? now : linkedRespawntime) + urand(5, MINUTE); // else copy time from master and add a little
|
||||
}
|
||||
SaveRespawnTime(); // also save to DB immediately
|
||||
}
|
||||
m_respawnedTime = GameTime::GetGameTime().count();
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
void Creature::ForcedDespawn(uint32 timeMSToDespawn, Seconds forceRespawnTimer)
|
||||
@@ -2107,15 +2101,17 @@ void Creature::ForcedDespawn(uint32 timeMSToDespawn, Seconds forceRespawnTimer)
|
||||
}
|
||||
|
||||
if (IsAlive())
|
||||
setDeathState(JUST_DIED, true);
|
||||
setDeathState(DeathState::JustDied, true);
|
||||
|
||||
// Xinef: set new respawn time, ignore corpse decay time...
|
||||
RemoveCorpse(true);
|
||||
|
||||
if (forceRespawnTimer > Seconds::zero())
|
||||
{
|
||||
m_respawnTime = GameTime::GetGameTime().count() + forceRespawnTimer.count();
|
||||
m_respawnDelay = forceRespawnTimer.count();
|
||||
if (GetMap())
|
||||
{
|
||||
GetMap()->ScheduleCreatureRespawn(GetGUID(), forceRespawnTimer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3076,7 +3072,10 @@ std::string const& Creature::GetNameForLocaleIdx(LocaleConstant loc_idx) const
|
||||
|
||||
void Creature::SetPosition(float x, float y, float z, float o)
|
||||
{
|
||||
UpdatePosition(x, y, z, o, false);
|
||||
if (!Acore::IsValidMapCoord(x, y, z, o))
|
||||
return;
|
||||
|
||||
GetMap()->CreatureRelocation(this, x, y, z, o);
|
||||
}
|
||||
|
||||
bool Creature::IsDungeonBoss() const
|
||||
@@ -3745,6 +3744,15 @@ bool Creature::CanCastSpell(uint32 spellID) const
|
||||
return true;
|
||||
}
|
||||
|
||||
ObjectGuid Creature::GetSummonerGUID() const
|
||||
{
|
||||
if (TempSummon const* temp = ToTempSummon())
|
||||
return temp->GetSummonerGUID();
|
||||
|
||||
LOG_DEBUG("entities.unit", "Creature::GetSummonerGUID() called by creature that is not a summon. Creature: {} ({})", GetEntry(), GetName());
|
||||
return ObjectGuid::Empty;
|
||||
}
|
||||
|
||||
std::string Creature::GetDebugInfo() const
|
||||
{
|
||||
std::stringstream sstr;
|
||||
|
||||
@@ -68,7 +68,6 @@ public:
|
||||
|
||||
void Update(uint32 time) override; // overwrited Unit::Update
|
||||
void GetRespawnPosition(float& x, float& y, float& z, float* ori = nullptr, float* dist = nullptr) const;
|
||||
bool IsSpawnedOnTransport() const { return m_creatureData && m_creatureData->mapid != GetMapId(); }
|
||||
|
||||
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
|
||||
void SetCorpseRemoveTime(uint32 delay);
|
||||
@@ -408,6 +407,12 @@ public:
|
||||
* */
|
||||
bool CanCastSpell(uint32 spellID) const;
|
||||
|
||||
/**
|
||||
* @brief Helper to get the creature's summoner GUID, if it is a summon
|
||||
*
|
||||
* */
|
||||
[[nodiscard]] ObjectGuid GetSummonerGUID() const;
|
||||
|
||||
std::string GetDebugInfo() const override;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -17,11 +17,12 @@
|
||||
|
||||
#include "GossipDef.h"
|
||||
#include "Formulas.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Object.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Player.h"
|
||||
#include "QuestDef.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ void TempSummon::Update(uint32 diff)
|
||||
{
|
||||
Creature::Update(diff);
|
||||
|
||||
if (m_deathState == DEAD)
|
||||
if (m_deathState == DeathState::Dead)
|
||||
{
|
||||
UnSummon();
|
||||
return;
|
||||
@@ -107,7 +107,7 @@ void TempSummon::Update(uint32 diff)
|
||||
}
|
||||
case TEMPSUMMON_TIMED_DESPAWN_OOC_ALIVE:
|
||||
{
|
||||
if (!IsInCombat() && m_deathState != CORPSE)
|
||||
if (!IsInCombat() && m_deathState != DeathState::Corpse)
|
||||
{
|
||||
if (m_timer <= diff)
|
||||
{
|
||||
@@ -124,7 +124,7 @@ void TempSummon::Update(uint32 diff)
|
||||
}
|
||||
case TEMPSUMMON_CORPSE_TIMED_DESPAWN:
|
||||
{
|
||||
if (m_deathState == CORPSE)
|
||||
if (m_deathState == DeathState::Corpse)
|
||||
{
|
||||
if (m_timer <= diff)
|
||||
{
|
||||
@@ -139,7 +139,7 @@ void TempSummon::Update(uint32 diff)
|
||||
case TEMPSUMMON_CORPSE_DESPAWN:
|
||||
{
|
||||
// if m_deathState is DEAD, CORPSE was skipped
|
||||
if (m_deathState == CORPSE)
|
||||
if (m_deathState == DeathState::Corpse)
|
||||
{
|
||||
UnSummon();
|
||||
return;
|
||||
@@ -154,7 +154,7 @@ void TempSummon::Update(uint32 diff)
|
||||
case TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN:
|
||||
{
|
||||
// if m_deathState is DEAD, CORPSE was skipped
|
||||
if (m_deathState == CORPSE)
|
||||
if (m_deathState == DeathState::Corpse)
|
||||
{
|
||||
UnSummon();
|
||||
return;
|
||||
@@ -395,7 +395,7 @@ bool Minion::IsGuardianPet() const
|
||||
void Minion::setDeathState(DeathState s, bool despawn)
|
||||
{
|
||||
Creature::setDeathState(s, despawn);
|
||||
if (s == JUST_DIED && IsGuardianPet())
|
||||
if (s == DeathState::JustDied && IsGuardianPet())
|
||||
if (Unit* owner = GetOwner())
|
||||
if (owner->GetTypeId() == TYPEID_PLAYER && owner->GetMinionGUID() == GetGUID())
|
||||
for (Unit::ControlSet::const_iterator itr = owner->m_Controlled.begin(); itr != owner->m_Controlled.end(); ++itr)
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "GameTime.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Opcodes.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "Transport.h"
|
||||
#include "UpdateMask.h"
|
||||
#include "World.h"
|
||||
@@ -47,6 +47,14 @@ DynamicObject::~DynamicObject()
|
||||
|
||||
void DynamicObject::CleanupsBeforeDelete(bool finalCleanup /* = true */)
|
||||
{
|
||||
if (Transport* transport = GetTransport())
|
||||
{
|
||||
transport->RemovePassenger(this);
|
||||
SetTransport(nullptr);
|
||||
m_movementInfo.transport.Reset();
|
||||
m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
|
||||
}
|
||||
|
||||
WorldObject::CleanupsBeforeDelete(finalCleanup);
|
||||
}
|
||||
|
||||
@@ -80,6 +88,9 @@ void DynamicObject::RemoveFromWorld()
|
||||
|
||||
UnbindFromCaster();
|
||||
|
||||
if (Transport* transport = GetTransport())
|
||||
transport->RemovePassenger(this, true);
|
||||
|
||||
WorldObject::RemoveFromWorld();
|
||||
|
||||
GetMap()->GetObjectsStore().Remove<DynamicObject>(GetGUID());
|
||||
@@ -114,15 +125,17 @@ bool DynamicObject::CreateDynamicObject(ObjectGuid::LowType guidlow, Unit* caste
|
||||
SetFloatValue(DYNAMICOBJECT_RADIUS, radius);
|
||||
SetUInt32Value(DYNAMICOBJECT_CASTTIME, GameTime::GetGameTimeMS().count());
|
||||
|
||||
if (IsWorldObject())
|
||||
setActive(true); //must before add to map to be put in world container
|
||||
|
||||
if (!GetMap()->AddToMap(this, true))
|
||||
{
|
||||
// Returning false will cause the object to be deleted - remove from transport
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsWorldObject())
|
||||
{
|
||||
setActive(true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "GridNotifiersImpl.h"
|
||||
#include "Group.h"
|
||||
#include "GroupMgr.h"
|
||||
#include "MapMgr.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "OutdoorPvPMgr.h"
|
||||
#include "PoolMgr.h"
|
||||
@@ -103,9 +102,18 @@ std::string const& GameObject::GetAIName() const
|
||||
return sObjectMgr->GetGameObjectTemplate(GetEntry())->AIName;
|
||||
}
|
||||
|
||||
void GameObject::CleanupsBeforeDelete(bool finalCleanup)
|
||||
void GameObject::CleanupsBeforeDelete(bool /*finalCleanup*/)
|
||||
{
|
||||
WorldObject::CleanupsBeforeDelete(finalCleanup);
|
||||
if (GetTransport() && !ToTransport())
|
||||
{
|
||||
GetTransport()->RemovePassenger(this);
|
||||
SetTransport(nullptr);
|
||||
m_movementInfo.transport.Reset();
|
||||
m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
|
||||
}
|
||||
|
||||
if (IsInWorld())
|
||||
RemoveFromWorld();
|
||||
|
||||
if (m_uint32Values) // field array can be not exist if GameOBject not loaded
|
||||
RemoveFromOwner();
|
||||
@@ -174,6 +182,9 @@ void GameObject::RemoveFromWorld()
|
||||
if (GetMap()->ContainsGameObjectModel(*m_model))
|
||||
GetMap()->RemoveGameObjectModel(*m_model);
|
||||
|
||||
if (Transport* transport = GetTransport())
|
||||
transport->RemovePassenger(this, true);
|
||||
|
||||
// If linked trap exists, despawn it
|
||||
if (GameObject* linkedTrap = GetLinkedTrap())
|
||||
{
|
||||
@@ -877,11 +888,7 @@ void GameObject::Update(uint32 diff)
|
||||
if (!m_spawnedByDefault)
|
||||
{
|
||||
m_respawnTime = 0;
|
||||
if (m_spawnId)
|
||||
DestroyForNearbyPlayers(); // xinef: old UpdateObjectVisibility();
|
||||
else
|
||||
Delete();
|
||||
|
||||
DestroyForNearbyPlayers(); // xinef: old UpdateObjectVisibility();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1178,31 +1185,7 @@ bool GameObject::LoadGameObjectFromDB(ObjectGuid::LowType spawnId, Map* map, boo
|
||||
|
||||
void GameObject::DeleteFromDB()
|
||||
{
|
||||
if (!m_spawnId)
|
||||
{
|
||||
LOG_ERROR("entities.gameobject", "Trying to delete not saved gameobject: {}", GetGUID().ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
GameObjectData const* data = sObjectMgr->GetGameObjectData(m_spawnId);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
CharacterDatabaseTransaction charTrans = CharacterDatabase.BeginTransaction();
|
||||
|
||||
sMapMgr->DoForAllMapsWithMapId(data->mapid,
|
||||
[this, charTrans](Map* map) -> void
|
||||
{
|
||||
// despawn all active objects, and remove their respawns
|
||||
std::vector<GameObject*> toUnload;
|
||||
for (auto const& pair : Acore::Containers::MapEqualRange(map->GetGameObjectBySpawnIdStore(), m_spawnId))
|
||||
toUnload.push_back(pair.second);
|
||||
for (GameObject* obj : toUnload)
|
||||
map->AddObjectToRemoveList(obj);
|
||||
map->RemoveGORespawnTime(m_spawnId);
|
||||
}
|
||||
);
|
||||
|
||||
GetMap()->RemoveGORespawnTime(m_spawnId);
|
||||
sObjectMgr->DeleteGOData(m_spawnId);
|
||||
|
||||
WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAMEOBJECT);
|
||||
@@ -2191,6 +2174,15 @@ bool GameObject::IsInRange(float x, float y, float z, float radius) const
|
||||
&& dz < (info->maxZ * scale) + radius && dz > (info->minZ * scale) - radius;
|
||||
}
|
||||
|
||||
void GameObject::SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, bool includeMargin, Player const* skipped_rcvr) const
|
||||
{
|
||||
dist += GetObjectSize();
|
||||
if (includeMargin)
|
||||
dist += VISIBILITY_COMPENSATION * 2.0f; // pussywizard: to ensure everyone receives all important packets
|
||||
Acore::MessageDistDeliverer notifier(this, data, dist, false, skipped_rcvr);
|
||||
Cell::VisitWorldObjects(this, notifier, dist);
|
||||
}
|
||||
|
||||
void GameObject::EventInform(uint32 eventId)
|
||||
{
|
||||
if (!eventId)
|
||||
@@ -2807,7 +2799,7 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t
|
||||
return;
|
||||
|
||||
bool forcedFlags = GetGoType() == GAMEOBJECT_TYPE_CHEST && GetGOInfo()->chest.groupLootRules && HasLootRecipient();
|
||||
bool targetIsGM = target->IsGameMaster() && AccountMgr::IsGMAccount(target->GetSession()->GetSecurity());
|
||||
bool targetIsGM = target->IsGameMaster() && target->GetSession()->IsGMAccount();
|
||||
|
||||
ByteBuffer fieldBuffer;
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
#include "Common.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "G3D/Quat.h"
|
||||
#include "GameObjectData.h"
|
||||
#include "LootMgr.h"
|
||||
#include "Object.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "GameObjectData.h"
|
||||
#include "Unit.h"
|
||||
#include <array>
|
||||
|
||||
@@ -289,6 +289,8 @@ public:
|
||||
void SendCustomAnim(uint32 anim);
|
||||
[[nodiscard]] bool IsInRange(float x, float y, float z, float radius) const;
|
||||
|
||||
void SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, bool includeMargin = false, Player const* skipped_rcvr = nullptr) const override; // pussywizard!
|
||||
|
||||
void ModifyHealth(int32 change, Unit* attackerOrHealer = nullptr, uint32 spellId = 0);
|
||||
void SetDestructibleBuildingModifyState(bool allow) { m_allowModifyDestructibleBuilding = allow; }
|
||||
// sets GameObject type 33 destruction flags and optionally default health for that state
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Tokenize.h"
|
||||
#include "StringConvert.h"
|
||||
#include "Tokenize.h"
|
||||
#include "WorldPacket.h"
|
||||
|
||||
void AddItemsSetItem(Player* player, Item* item)
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ struct ItemSetEffect
|
||||
};
|
||||
|
||||
// EnumUtils: DESCRIBE THIS
|
||||
enum InventoryResult
|
||||
enum InventoryResult : uint8
|
||||
{
|
||||
EQUIP_ERR_OK = 0,
|
||||
EQUIP_ERR_CANT_EQUIP_LEVEL_I = 1,
|
||||
@@ -158,7 +158,7 @@ enum SellResult
|
||||
};
|
||||
|
||||
// -1 from client enchantment slot number
|
||||
enum EnchantmentSlot
|
||||
enum EnchantmentSlot : uint8
|
||||
{
|
||||
PERM_ENCHANTMENT_SLOT = 0,
|
||||
TEMP_ENCHANTMENT_SLOT = 1,
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Item.h"
|
||||
#include "Define.h"
|
||||
#include "Item.h"
|
||||
#include "SmartEnum.h"
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "CellImpl.h"
|
||||
#include "Chat.h"
|
||||
#include "Creature.h"
|
||||
#include "DynamicVisibility.h"
|
||||
#include "GameObjectAI.h"
|
||||
#include "GameTime.h"
|
||||
#include "GridNotifiers.h"
|
||||
@@ -37,8 +38,10 @@
|
||||
#include "ScriptMgr.h"
|
||||
#include "SharedDefines.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "StringConvert.h"
|
||||
#include "TargetedMovementGenerator.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "Tokenize.h"
|
||||
#include "Totem.h"
|
||||
#include "Transport.h"
|
||||
#include "UpdateData.h"
|
||||
@@ -48,8 +51,6 @@
|
||||
#include "Vehicle.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Tokenize.h"
|
||||
#include "StringConvert.h"
|
||||
|
||||
/// @todo: this import is not necessary for compilation and marked as unused by the IDE
|
||||
// however, for some reasons removing it would cause a damn linking issue
|
||||
@@ -64,7 +65,7 @@ constexpr float VisibilityDistances[AsUnderlyingType(VisibilityDistanceType::Max
|
||||
VISIBILITY_DISTANCE_SMALL,
|
||||
VISIBILITY_DISTANCE_LARGE,
|
||||
VISIBILITY_DISTANCE_GIGANTIC,
|
||||
MAX_VISIBILITY_DISTANCE
|
||||
VISIBILITY_DISTANCE_INFINITE
|
||||
};
|
||||
|
||||
Object::Object() : m_PackGUID(sizeof(uint64) + 1)
|
||||
@@ -248,10 +249,7 @@ void Object::SendUpdateToPlayer(Player* player)
|
||||
UpdateData upd;
|
||||
WorldPacket packet;
|
||||
|
||||
if (player->HaveAtClient(this))
|
||||
BuildValuesUpdateBlockForPlayer(&upd, player);
|
||||
else
|
||||
BuildCreateUpdateBlockForPlayer(&upd, player);
|
||||
BuildCreateUpdateBlockForPlayer(&upd, player);
|
||||
upd.BuildPacket(&packet);
|
||||
player->GetSession()->SendPacket(&packet);
|
||||
}
|
||||
@@ -1050,7 +1048,7 @@ void MovementInfo::OutDebug()
|
||||
}
|
||||
|
||||
WorldObject::WorldObject(bool isWorldObject) : WorldLocation(),
|
||||
LastUsedScriptID(0), m_name(""), m_isActive(false), m_isFarVisible(false), m_visibilityDistanceOverride(), m_isWorldObject(isWorldObject), m_zoneScript(nullptr),
|
||||
LastUsedScriptID(0), m_name(""), m_isActive(false), m_visibilityDistanceOverride(), m_isWorldObject(isWorldObject), m_zoneScript(nullptr),
|
||||
_zoneId(0), _areaId(0), _floorZ(INVALID_HEIGHT), _outdoors(false), _liquidData(), _updatePositionData(false), m_transport(nullptr),
|
||||
m_currMap(nullptr), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL), m_useCombinedPhases(true), m_notifyflags(0), m_executed_notifies(0)
|
||||
{
|
||||
@@ -1107,6 +1105,8 @@ void WorldObject::setActive(bool on)
|
||||
map->AddToActive(this->ToCreature());
|
||||
else if (GetTypeId() == TYPEID_DYNAMICOBJECT)
|
||||
map->AddToActive((DynamicObject*)this);
|
||||
else if (GetTypeId() == TYPEID_GAMEOBJECT)
|
||||
map->AddToActive((GameObject*)this);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1114,17 +1114,11 @@ void WorldObject::setActive(bool on)
|
||||
map->RemoveFromActive(this->ToCreature());
|
||||
else if (GetTypeId() == TYPEID_DYNAMICOBJECT)
|
||||
map->RemoveFromActive((DynamicObject*)this);
|
||||
else if (GetTypeId() == TYPEID_GAMEOBJECT)
|
||||
map->RemoveFromActive((GameObject*)this);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldObject::SetFarVisible(bool on)
|
||||
{
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
m_isFarVisible = on;
|
||||
}
|
||||
|
||||
void WorldObject::SetVisibilityDistanceOverride(VisibilityDistanceType type)
|
||||
{
|
||||
ASSERT(type < VisibilityDistanceType::Max);
|
||||
@@ -1140,9 +1134,6 @@ void WorldObject::CleanupsBeforeDelete(bool /*finalCleanup*/)
|
||||
{
|
||||
if (IsInWorld())
|
||||
RemoveFromWorld();
|
||||
|
||||
if (Transport* transport = GetTransport())
|
||||
transport->RemovePassenger(this, true);
|
||||
}
|
||||
|
||||
void WorldObject::_Create(ObjectGuid::LowType guidlow, HighGuid guidhigh, uint32 phaseMask)
|
||||
@@ -1635,9 +1626,9 @@ float WorldObject::GetGridActivationRange() const
|
||||
{
|
||||
if (ToPlayer()->GetCinematicMgr()->IsOnCinematic())
|
||||
{
|
||||
return std::max(DEFAULT_VISIBILITY_INSTANCE, GetMap()->GetVisibilityRange());
|
||||
return DEFAULT_VISIBILITY_INSTANCE;
|
||||
}
|
||||
return IsInWintergrasp() ? VISIBILITY_DISTANCE_LARGE : GetMap()->GetVisibilityRange();
|
||||
return IsInWintergrasp() ? VISIBILITY_DIST_WINTERGRASP : GetMap()->GetVisibilityRange();
|
||||
}
|
||||
else if (ToCreature())
|
||||
{
|
||||
@@ -1653,12 +1644,29 @@ float WorldObject::GetGridActivationRange() const
|
||||
|
||||
float WorldObject::GetVisibilityRange() const
|
||||
{
|
||||
if (IsVisibilityOverridden() && !ToPlayer())
|
||||
if (IsVisibilityOverridden() && GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
return *m_visibilityDistanceOverride;
|
||||
else if (IsFarVisible() && !ToPlayer())
|
||||
return MAX_VISIBILITY_DISTANCE;
|
||||
}
|
||||
else if (GetTypeId() == TYPEID_GAMEOBJECT)
|
||||
{
|
||||
{
|
||||
if (IsInWintergrasp())
|
||||
{
|
||||
return VISIBILITY_DIST_WINTERGRASP + VISIBILITY_INC_FOR_GOBJECTS;
|
||||
}
|
||||
else if (IsVisibilityOverridden())
|
||||
{
|
||||
return *m_visibilityDistanceOverride;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetMap()->GetVisibilityRange() + VISIBILITY_INC_FOR_GOBJECTS;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return IsInWintergrasp() ? VISIBILITY_DISTANCE_LARGE : GetMap()->GetVisibilityRange();
|
||||
return IsInWintergrasp() ? VISIBILITY_DIST_WINTERGRASP : GetMap()->GetVisibilityRange();
|
||||
}
|
||||
|
||||
float WorldObject::GetSightRange(WorldObject const* target) const
|
||||
@@ -1667,19 +1675,44 @@ float WorldObject::GetSightRange(WorldObject const* target) const
|
||||
{
|
||||
if (ToPlayer())
|
||||
{
|
||||
if (target && target->IsVisibilityOverridden() && !target->ToPlayer())
|
||||
return *target->m_visibilityDistanceOverride;
|
||||
else if (target && target->IsFarVisible() && !target->ToPlayer())
|
||||
return MAX_VISIBILITY_DISTANCE;
|
||||
else if (ToPlayer()->GetCinematicMgr()->IsOnCinematic())
|
||||
return DEFAULT_VISIBILITY_INSTANCE;
|
||||
else
|
||||
return IsInWintergrasp() ? VISIBILITY_DISTANCE_LARGE : GetMap()->GetVisibilityRange();
|
||||
if (target)
|
||||
{
|
||||
if (target->IsVisibilityOverridden() && target->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
return *target->m_visibilityDistanceOverride;
|
||||
}
|
||||
else if (target->GetTypeId() == TYPEID_GAMEOBJECT)
|
||||
{
|
||||
if (IsInWintergrasp() && target->IsInWintergrasp())
|
||||
{
|
||||
return VISIBILITY_DIST_WINTERGRASP + VISIBILITY_INC_FOR_GOBJECTS;
|
||||
}
|
||||
else if (target->IsVisibilityOverridden())
|
||||
{
|
||||
return *target->m_visibilityDistanceOverride;
|
||||
}
|
||||
else if (ToPlayer()->GetCinematicMgr()->IsOnCinematic())
|
||||
{
|
||||
return DEFAULT_VISIBILITY_INSTANCE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetMap()->GetVisibilityRange() + VISIBILITY_INC_FOR_GOBJECTS;
|
||||
}
|
||||
}
|
||||
|
||||
return IsInWintergrasp() && target->IsInWintergrasp() ? VISIBILITY_DIST_WINTERGRASP : GetMap()->GetVisibilityRange();
|
||||
}
|
||||
return IsInWintergrasp() ? VISIBILITY_DIST_WINTERGRASP : GetMap()->GetVisibilityRange();
|
||||
}
|
||||
else if (ToCreature())
|
||||
{
|
||||
return ToCreature()->m_SightDistance;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SIGHT_RANGE_UNIT;
|
||||
}
|
||||
}
|
||||
|
||||
if (ToDynObject() && isActiveObject())
|
||||
@@ -2044,8 +2077,11 @@ void Unit::BuildHeartBeatMsg(WorldPacket* data) const
|
||||
BuildMovementPacket(data);
|
||||
}
|
||||
|
||||
void WorldObject::SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, Player const* skipped_rcvr) const
|
||||
void WorldObject::SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, bool includeMargin, Player const* skipped_rcvr) const
|
||||
{
|
||||
dist += GetObjectSize();
|
||||
if (includeMargin)
|
||||
dist += VISIBILITY_COMPENSATION; // pussywizard: to ensure everyone receives all important packets
|
||||
Acore::MessageDistDeliverer notifier(this, data, dist, false, skipped_rcvr);
|
||||
Cell::VisitWorldObjects(this, notifier, dist);
|
||||
}
|
||||
@@ -2192,8 +2228,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!IsGridLoaded(pos.GetPositionX(), pos.GetPositionY()))
|
||||
EnsureGridLoaded(Cell(pos.GetPositionX(), pos.GetPositionY()));
|
||||
EnsureGridLoaded(Cell(pos.GetPositionX(), pos.GetPositionY()));
|
||||
if (!summon->Create(GenerateLowGuid<HighGuid::Unit>(), this, phase, entry, vehId, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation()))
|
||||
{
|
||||
delete summon;
|
||||
@@ -2866,8 +2901,8 @@ void WorldObject::DestroyForNearbyPlayers()
|
||||
return;
|
||||
|
||||
std::list<Player*> targets;
|
||||
Acore::AnyPlayerInObjectRangeCheck check(this, GetVisibilityRange(), false);
|
||||
Acore::PlayerListSearcher<Acore::AnyPlayerInObjectRangeCheck> searcher(this, targets, check);
|
||||
Acore::AnyPlayerInObjectRangeCheck check(this, GetVisibilityRange() + VISIBILITY_COMPENSATION, false);
|
||||
Acore::PlayerListSearcherWithSharedVision<Acore::AnyPlayerInObjectRangeCheck> searcher(this, targets, check);
|
||||
Cell::VisitWorldObjects(this, searcher, GetVisibilityRange());
|
||||
for (std::list<Player*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
|
||||
{
|
||||
@@ -2887,7 +2922,7 @@ void WorldObject::DestroyForNearbyPlayers()
|
||||
}
|
||||
}
|
||||
|
||||
void WorldObject::UpdateObjectVisibility(bool /*forced*/)
|
||||
void WorldObject::UpdateObjectVisibility(bool /*forced*/, bool /*fromUpdate*/)
|
||||
{
|
||||
//updates object's visibility for nearby players
|
||||
Acore::VisibleChangesNotifier notifier(*this);
|
||||
@@ -2896,7 +2931,28 @@ void WorldObject::UpdateObjectVisibility(bool /*forced*/)
|
||||
|
||||
void WorldObject::AddToNotify(uint16 f)
|
||||
{
|
||||
m_notifyflags |= f;
|
||||
if (!(m_notifyflags & f))
|
||||
if (Unit* u = ToUnit())
|
||||
{
|
||||
if (f & NOTIFY_VISIBILITY_CHANGED)
|
||||
{
|
||||
uint32 EVENT_VISIBILITY_DELAY = u->FindMap() ? DynamicVisibilityMgr::GetVisibilityNotifyDelay(u->FindMap()->GetEntry()->map_type) : 1000;
|
||||
|
||||
uint32 diff = getMSTimeDiff(u->m_last_notify_mstime, GameTime::GetGameTimeMS().count());
|
||||
if (diff >= EVENT_VISIBILITY_DELAY / 2)
|
||||
EVENT_VISIBILITY_DELAY /= 2;
|
||||
else
|
||||
EVENT_VISIBILITY_DELAY -= diff;
|
||||
u->m_delayed_unit_relocation_timer = EVENT_VISIBILITY_DELAY;
|
||||
u->m_last_notify_mstime = GameTime::GetGameTimeMS().count() + EVENT_VISIBILITY_DELAY - 1;
|
||||
}
|
||||
else if (f & NOTIFY_AI_RELOCATION)
|
||||
{
|
||||
u->m_delayed_unit_ai_notify_timer = u->FindMap() ? DynamicVisibilityMgr::GetAINotifyDelay(u->FindMap()->GetEntry()->map_type) : 500;
|
||||
}
|
||||
|
||||
m_notifyflags |= f;
|
||||
}
|
||||
}
|
||||
|
||||
struct WorldObjectChangeAccumulator
|
||||
@@ -2949,7 +3005,7 @@ struct WorldObjectChangeAccumulator
|
||||
source = iter->GetSource();
|
||||
ObjectGuid guid = source->GetCasterGUID();
|
||||
|
||||
if (guid.IsPlayer())
|
||||
if (guid)
|
||||
{
|
||||
//Caster may be nullptr if DynObj is in removelist
|
||||
if (Player* caster = ObjectAccessor::FindPlayer(guid))
|
||||
|
||||
@@ -379,23 +379,14 @@ class MovableMapObject
|
||||
template<class T> friend class RandomMovementGenerator;
|
||||
|
||||
protected:
|
||||
MovableMapObject() : _moveState(MAP_OBJECT_CELL_MOVE_NONE)
|
||||
{
|
||||
_newPosition.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
MovableMapObject() = default;
|
||||
|
||||
private:
|
||||
Cell _currentCell;
|
||||
[[nodiscard]] Cell const& GetCurrentCell() const { return _currentCell; }
|
||||
void SetCurrentCell(Cell const& cell) { _currentCell = cell; }
|
||||
|
||||
MapObjectCellMoveState _moveState;
|
||||
Position _newPosition;
|
||||
void SetNewCellPosition(float x, float y, float z, float o)
|
||||
{
|
||||
_moveState = MAP_OBJECT_CELL_MOVE_ACTIVE;
|
||||
_newPosition.Relocate(x, y, z, o);
|
||||
}
|
||||
Cell _currentCell;
|
||||
MapObjectCellMoveState _moveState{MAP_OBJECT_CELL_MOVE_NONE};
|
||||
};
|
||||
|
||||
class WorldObject : public Object, public WorldLocation
|
||||
@@ -488,9 +479,9 @@ public:
|
||||
|
||||
virtual void CleanupsBeforeDelete(bool finalCleanup = true); // used in destructor or explicitly before mass creature delete to remove cross-references to already deleted units
|
||||
|
||||
virtual void SendMessageToSet(WorldPacket const* data, bool self) const { if (IsInWorld()) SendMessageToSetInRange(data, GetVisibilityRange(), self); } // pussywizard!
|
||||
virtual void SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, Player const* skipped_rcvr = nullptr) const; // pussywizard!
|
||||
virtual void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const { if (IsInWorld()) SendMessageToSetInRange(data, GetVisibilityRange(), false, skipped_rcvr); } // pussywizard!
|
||||
virtual void SendMessageToSet(WorldPacket const* data, bool self) const { if (IsInWorld()) SendMessageToSetInRange(data, GetVisibilityRange(), self, true); } // pussywizard!
|
||||
virtual void SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/, bool includeMargin = false, Player const* skipped_rcvr = nullptr) const; // pussywizard!
|
||||
virtual void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const { if (IsInWorld()) SendMessageToSetInRange(data, GetVisibilityRange(), false, true, skipped_rcvr); } // pussywizard!
|
||||
|
||||
virtual uint8 getLevelForTarget(WorldObject const* /*target*/) const { return 1; }
|
||||
|
||||
@@ -547,7 +538,7 @@ public:
|
||||
void GetDeadCreatureListInGrid(std::list<Creature*>& lList, float maxSearchRange, bool alive = false) const;
|
||||
|
||||
void DestroyForNearbyPlayers();
|
||||
virtual void UpdateObjectVisibility(bool forced = true);
|
||||
virtual void UpdateObjectVisibility(bool forced = true, bool fromUpdate = false);
|
||||
void BuildUpdate(UpdateDataMapType& data_map, UpdatePlayerSet& player_set) override;
|
||||
void GetCreaturesWithEntryInRange(std::list<Creature*>& creatureList, float radius, uint32 entry);
|
||||
|
||||
@@ -569,7 +560,6 @@ public:
|
||||
[[nodiscard]] bool isActiveObject() const { return m_isActive; }
|
||||
void setActive(bool isActiveObject);
|
||||
[[nodiscard]] bool IsFarVisible() const { return m_isFarVisible; }
|
||||
void SetFarVisible(bool on);
|
||||
[[nodiscard]] bool IsVisibilityOverridden() const { return m_visibilityDistanceOverride.has_value(); }
|
||||
void SetVisibilityDistanceOverride(VisibilityDistanceType type);
|
||||
void SetWorldObject(bool apply);
|
||||
@@ -578,7 +568,7 @@ public:
|
||||
|
||||
[[nodiscard]] bool IsInWintergrasp() const
|
||||
{
|
||||
return GetMapId() == 571 && GetZoneId() == 4197;
|
||||
return GetMapId() == 571 && GetPositionX() > 3733.33331f && GetPositionX() < 5866.66663f && GetPositionY() > 1599.99999f && GetPositionY() < 4799.99997f;
|
||||
}
|
||||
|
||||
#ifdef MAP_BASED_RAND_GEN
|
||||
|
||||
@@ -23,18 +23,23 @@
|
||||
#define CONTACT_DISTANCE 0.5f
|
||||
#define INTERACTION_DISTANCE 5.5f
|
||||
#define ATTACK_DISTANCE 5.0f
|
||||
#define VISIBILITY_COMPENSATION 15.0f // increase searchers
|
||||
#define INSPECT_DISTANCE 28.0f
|
||||
#define VISIBILITY_INC_FOR_GOBJECTS 30.0f // pussywizard
|
||||
#define SPELL_SEARCHER_COMPENSATION 30.0f // increase searchers size in case we have large npc near cell border
|
||||
#define TRADE_DISTANCE 11.11f
|
||||
#define MAX_VISIBILITY_DISTANCE SIZE_OF_GRIDS // max distance for visible objects, experimental
|
||||
#define MAX_VISIBILITY_DISTANCE 250.0f // max distance for visible objects, experimental
|
||||
#define SIGHT_RANGE_UNIT 50.0f
|
||||
#define MAX_SEARCHER_DISTANCE 150.0f // pussywizard: replace the use of MAX_VISIBILITY_DISTANCE in searchers, because MAX_VISIBILITY_DISTANCE is quite too big for this purpose
|
||||
#define VISIBILITY_DISTANCE_INFINITE 533.0f
|
||||
#define VISIBILITY_DISTANCE_GIGANTIC 400.0f
|
||||
#define VISIBILITY_DISTANCE_LARGE 200.0f
|
||||
#define VISIBILITY_DISTANCE_NORMAL 100.0f
|
||||
#define VISIBILITY_DISTANCE_SMALL 50.0f
|
||||
#define VISIBILITY_DISTANCE_TINY 25.0f
|
||||
#define DEFAULT_VISIBILITY_DISTANCE VISIBILITY_DISTANCE_NORMAL // default visible distance, 100 yards on continents
|
||||
#define DEFAULT_VISIBILITY_DISTANCE 100.0f // default visible distance, 100 yards on continents
|
||||
#define DEFAULT_VISIBILITY_INSTANCE 170.0f // default visible distance in instances, 170 yards
|
||||
#define VISIBILITY_DIST_WINTERGRASP 175.0f
|
||||
#define DEFAULT_VISIBILITY_BGARENAS 533.0f // default visible distance in BG/Arenas, roughly 533 yards
|
||||
|
||||
#define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
|
||||
|
||||
@@ -134,7 +134,6 @@ class ObjectGuid
|
||||
ObjectGuid(HighGuid hi, uint32 entry, LowType counter) : _guid(counter ? uint64(counter) | (uint64(entry) << 24) | (uint64(hi) << 48) : 0) { }
|
||||
ObjectGuid(HighGuid hi, LowType counter) : _guid(counter ? uint64(counter) | (uint64(hi) << 48) : 0) { }
|
||||
|
||||
operator uint64() const { return _guid; }
|
||||
PackedGuidReader ReadAsPacked() { return PackedGuidReader(*this); }
|
||||
|
||||
void Set(uint64 guid) { _guid = guid; }
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "Define.h"
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <math.h>
|
||||
|
||||
enum UsedPosType { USED_POS_PLUS, USED_POS_MINUS };
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
#include "Position.h"
|
||||
#include "ByteBuffer.h"
|
||||
#include "GridDefines.h"
|
||||
#include "Geometry.h"
|
||||
#include "GridDefines.h"
|
||||
#include <G3D/g3dmath.h>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
#ifndef ACore_game_Position_h__
|
||||
#define ACore_game_Position_h__
|
||||
|
||||
#include <cmath>
|
||||
#include "Common.h"
|
||||
#include "G3D/Vector3.h"
|
||||
#include <cmath>
|
||||
|
||||
class ByteBuffer;
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "DatabaseEnv.h"
|
||||
#include "GameTime.h"
|
||||
#include "Group.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "Log.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "PetPackets.h"
|
||||
@@ -472,7 +473,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
|
||||
else
|
||||
{
|
||||
if (!curHealth && getPetType() == HUNTER_PET)
|
||||
setDeathState(JUST_DIED);
|
||||
setDeathState(DeathState::JustDied);
|
||||
else
|
||||
{
|
||||
SetHealth(curHealth > GetMaxHealth() ? GetMaxHealth() : curHealth);
|
||||
@@ -616,7 +617,7 @@ void Pet::DeleteFromDB(ObjectGuid::LowType guidlow)
|
||||
void Pet::setDeathState(DeathState s, bool /*despawn = false*/) // overwrite virtual Creature::setDeathState and Unit::setDeathState
|
||||
{
|
||||
Creature::setDeathState(s);
|
||||
if (getDeathState() == CORPSE)
|
||||
if (getDeathState() == DeathState::Corpse)
|
||||
{
|
||||
if (getPetType() == HUNTER_PET)
|
||||
{
|
||||
@@ -632,7 +633,7 @@ void Pet::setDeathState(DeathState s, bool /*despawn = false*/)
|
||||
//SetUnitFlag(UNIT_FLAG_STUNNED);
|
||||
}
|
||||
}
|
||||
else if (getDeathState() == ALIVE)
|
||||
else if (getDeathState() == DeathState::Alive)
|
||||
{
|
||||
//RemoveUnitFlag(UNIT_FLAG_STUNNED);
|
||||
CastPetAuras(true);
|
||||
@@ -651,7 +652,7 @@ void Pet::Update(uint32 diff)
|
||||
|
||||
switch (m_deathState)
|
||||
{
|
||||
case CORPSE:
|
||||
case DeathState::Corpse:
|
||||
{
|
||||
if (getPetType() != HUNTER_PET || m_corpseRemoveTime <= GameTime::GetGameTime().count())
|
||||
{
|
||||
@@ -660,7 +661,7 @@ void Pet::Update(uint32 diff)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ALIVE:
|
||||
case DeathState::Alive:
|
||||
{
|
||||
// unsummon pet that lost owner
|
||||
Player* owner = GetOwner();
|
||||
@@ -1941,16 +1942,16 @@ void Pet::InitLevelupSpellsForLevel()
|
||||
{
|
||||
for (uint32 spellId : defSpells->spellid)
|
||||
{
|
||||
SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(spellId);
|
||||
if (!spellEntry)
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
|
||||
if (!spellInfo)
|
||||
continue;
|
||||
|
||||
// will called first if level down
|
||||
if (spellEntry->SpellLevel > level && sScriptMgr->CanUnlearnSpellDefault(this, spellEntry))
|
||||
unlearnSpell(spellEntry->Id, true);
|
||||
if (spellInfo->SpellLevel > level && sScriptMgr->CanUnlearnSpellDefault(this, spellInfo))
|
||||
unlearnSpell(spellInfo->Id, true);
|
||||
// will called if level up
|
||||
else
|
||||
learnSpell(spellEntry->Id);
|
||||
learnSpell(spellInfo->Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2240,7 +2241,7 @@ uint8 Pet::GetMaxTalentPointsForLevel(uint8 level)
|
||||
|
||||
sScriptMgr->OnCalculateMaxTalentPointsForLevel(this, level, points);
|
||||
|
||||
return points;
|
||||
return uint8(points * sWorld->getRate(RATE_TALENT_PET));
|
||||
}
|
||||
|
||||
void Pet::ToggleAutocast(SpellInfo const* spellInfo, bool apply)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "Group.h"
|
||||
#include "Pet.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
|
||||
// KillRewarder incapsulates logic of rewarding player upon kill with:
|
||||
|
||||
@@ -53,14 +53,12 @@
|
||||
#include "InstanceSaveMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "LFGMgr.h"
|
||||
#include "Language.h"
|
||||
#include "Log.h"
|
||||
#include "LootItemStorage.h"
|
||||
#include "MapMgr.h"
|
||||
#include "MiscPackets.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Opcodes.h"
|
||||
#include "OutdoorPvP.h"
|
||||
#include "OutdoorPvPMgr.h"
|
||||
#include "Pet.h"
|
||||
@@ -75,18 +73,17 @@
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "StringConvert.h"
|
||||
#include "TicketMgr.h"
|
||||
#include "Tokenize.h"
|
||||
#include "Transport.h"
|
||||
#include "UpdateData.h"
|
||||
#include "UpdateFieldFlags.h"
|
||||
#include "Util.h"
|
||||
#include "Vehicle.h"
|
||||
#include "Weather.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "WorldSession.h"
|
||||
#include "Tokenize.h"
|
||||
#include "StringConvert.h"
|
||||
|
||||
/// @todo: this import is not necessary for compilation and marked as unused by the IDE
|
||||
// however, for some reasons removing it would cause a damn linking issue
|
||||
@@ -1010,7 +1007,7 @@ void Player::setDeathState(DeathState s, bool /*despawn = false*/)
|
||||
|
||||
bool cur = IsAlive();
|
||||
|
||||
if (s == JUST_DIED)
|
||||
if (s == DeathState::JustDied)
|
||||
{
|
||||
if (!cur)
|
||||
{
|
||||
@@ -1025,7 +1022,7 @@ void Player::setDeathState(DeathState s, bool /*despawn = false*/)
|
||||
|
||||
clearResurrectRequestData();
|
||||
|
||||
//FIXME: is pet dismissed at dying or releasing spirit? if second, add setDeathState(DEAD) to HandleRepopRequestOpcode and define pet unsummon here with (s == DEAD)
|
||||
//FIXME: is pet dismissed at dying or releasing spirit? if second, add setDeathState(DeathState::Dead) to HandleRepopRequestOpcode and define pet unsummon here with (s == DEAD)
|
||||
RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT, true);
|
||||
|
||||
// save value before aura remove in Unit::setDeathState
|
||||
@@ -1045,7 +1042,7 @@ void Player::setDeathState(DeathState s, bool /*despawn = false*/)
|
||||
ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH, 0);
|
||||
}
|
||||
// xinef: enable passive area auras!
|
||||
else if (s == ALIVE)
|
||||
else if (s == DeathState::Alive)
|
||||
ClearUnitState(UNIT_STATE_ISOLATED);
|
||||
|
||||
Unit::setDeathState(s);
|
||||
@@ -1054,7 +1051,7 @@ void Player::setDeathState(DeathState s, bool /*despawn = false*/)
|
||||
ArenaSpectator::SendCommand_UInt32Value(FindMap(), GetGUID(), "STA", IsAlive() ? 1 : 0);
|
||||
|
||||
// restore resurrection spell id for player after aura remove
|
||||
if (s == JUST_DIED && cur && ressSpellId)
|
||||
if (s == DeathState::JustDied && cur && ressSpellId)
|
||||
SetUInt32Value(PLAYER_SELF_RES_SPELL, ressSpellId);
|
||||
|
||||
if (IsAlive() && !cur)
|
||||
@@ -1313,9 +1310,6 @@ void Player::SendTeleportAckPacket()
|
||||
|
||||
bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options /*= 0*/, Unit* target /*= nullptr*/, bool newInstance /*= false*/)
|
||||
{
|
||||
// for except kick by antispeedhack
|
||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(this, true);
|
||||
|
||||
if (!MapMgr::IsValidMapCoord(mapid, x, y, z, orientation))
|
||||
{
|
||||
LOG_ERROR("entities.player", "TeleportTo: invalid map ({}) or invalid coordinates (X: {}, Y: {}, Z: {}, O: {}) given when teleporting player ({}, name: {}, map: {}, X: {}, Y: {}, Z: {}, O: {}).",
|
||||
@@ -1353,7 +1347,10 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||
|
||||
if (GetTransport())
|
||||
{
|
||||
m_transport->RemovePassenger(this, true);
|
||||
m_transport->RemovePassenger(this);
|
||||
m_transport = nullptr;
|
||||
m_movementInfo.transport.Reset();
|
||||
m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
|
||||
RepopAtGraveyard(); // teleport to near graveyard if on transport, looks blizz like :)
|
||||
}
|
||||
|
||||
@@ -1395,7 +1392,10 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
||||
AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
|
||||
else
|
||||
{
|
||||
m_transport->RemovePassenger(this, true);
|
||||
m_transport->RemovePassenger(this);
|
||||
m_transport = nullptr;
|
||||
m_movementInfo.transport.Reset();
|
||||
m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2186,14 +2186,14 @@ void Player::SetGameMaster(bool on)
|
||||
if (on)
|
||||
{
|
||||
m_ExtraFlags |= PLAYER_EXTRA_GM_ON;
|
||||
if (AccountMgr::IsGMAccount(GetSession()->GetSecurity()))
|
||||
if (GetSession()->IsGMAccount())
|
||||
SetFaction(FACTION_FRIENDLY);
|
||||
SetPlayerFlag(PLAYER_FLAGS_GM);
|
||||
SetUnitFlag2(UNIT_FLAG2_ALLOW_CHEAT_SPELLS);
|
||||
|
||||
if (Pet* pet = GetPet())
|
||||
{
|
||||
if (AccountMgr::IsGMAccount(GetSession()->GetSecurity()))
|
||||
if (GetSession()->IsGMAccount())
|
||||
pet->SetFaction(FACTION_FRIENDLY);
|
||||
pet->getHostileRefMgr().setOnlineOfflineState(false);
|
||||
}
|
||||
@@ -2292,7 +2292,6 @@ bool Player::IsInSameGroupWith(Player const* p) const
|
||||
}
|
||||
|
||||
///- If the player is invited, remove him. If the group if then only 1 person, disband the group.
|
||||
/// \todo Shouldn't we also check if there is no other invitees before disbanding the group?
|
||||
void Player::UninviteFromGroup()
|
||||
{
|
||||
Group* group = GetGroupInvite();
|
||||
@@ -2301,14 +2300,17 @@ void Player::UninviteFromGroup()
|
||||
|
||||
group->RemoveInvite(this);
|
||||
|
||||
if (group->GetMembersCount() <= 1) // group has just 1 member => disband
|
||||
if (group->IsCreated())
|
||||
{
|
||||
if (group->IsCreated())
|
||||
if (group->GetMembersCount() <= 1) // group has just 1 member => disband
|
||||
{
|
||||
group->Disband(true);
|
||||
group = nullptr; // gets deleted in disband
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
if (group->GetInviteeCount() <= 1)
|
||||
{
|
||||
group->RemoveAllInvites();
|
||||
delete group;
|
||||
@@ -4398,7 +4400,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
|
||||
if (GetSession()->IsARecruiter() || (GetSession()->GetRecruiterId() != 0))
|
||||
SetDynamicFlag(UNIT_DYNFLAG_REFER_A_FRIEND);
|
||||
|
||||
setDeathState(ALIVE);
|
||||
setDeathState(DeathState::Alive);
|
||||
SetMovement(MOVE_LAND_WALK);
|
||||
SetMovement(MOVE_UNROOT);
|
||||
SetWaterWalking(false);
|
||||
@@ -4465,7 +4467,7 @@ void Player::KillPlayer()
|
||||
|
||||
StopMirrorTimers(); //disable timers(bars)
|
||||
|
||||
setDeathState(CORPSE);
|
||||
setDeathState(DeathState::Corpse);
|
||||
//SetUnitFlag(UNIT_FLAG_NOT_IN_PVP);
|
||||
|
||||
ReplaceAllDynamicFlags(UNIT_DYNFLAG_NONE);
|
||||
@@ -4481,6 +4483,7 @@ void Player::KillPlayer()
|
||||
if (corpseReclaimDelay >= 0)
|
||||
SendCorpseReclaimDelay(corpseReclaimDelay);
|
||||
|
||||
sScriptMgr->OnPlayerJustDied(this);
|
||||
// don't create corpse at this moment, player might be falling
|
||||
|
||||
// update visibility
|
||||
@@ -5577,11 +5580,14 @@ void Player::SaveRecallPosition()
|
||||
m_recallO = GetOrientation();
|
||||
}
|
||||
|
||||
void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, Player const* skipped_rcvr) const
|
||||
void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool includeMargin, Player const* skipped_rcvr) const
|
||||
{
|
||||
if (self)
|
||||
GetSession()->SendPacket(data);
|
||||
|
||||
dist += GetObjectSize();
|
||||
if (includeMargin)
|
||||
dist += VISIBILITY_COMPENSATION; // pussywizard: to ensure everyone receives all important packets
|
||||
Acore::MessageDistDeliverer notifier(this, data, dist, false, skipped_rcvr);
|
||||
Cell::VisitWorldObjects(this, notifier, dist);
|
||||
}
|
||||
@@ -11315,7 +11321,7 @@ WorldLocation Player::GetStartPosition() const
|
||||
return WorldLocation(mapId, info->positionX, info->positionY, info->positionZ, 0);
|
||||
}
|
||||
|
||||
bool Player::HaveAtClient(Object const* u) const
|
||||
bool Player::HaveAtClient(WorldObject const* u) const
|
||||
{
|
||||
if (u == this)
|
||||
{
|
||||
@@ -13089,11 +13095,14 @@ void Player::SetViewpoint(WorldObject* target, bool apply)
|
||||
UpdateVisibilityOf(target);
|
||||
|
||||
if (target->isType(TYPEMASK_UNIT) && !GetVehicle())
|
||||
static_cast<Unit*>(target)->AddPlayerToVision(this);
|
||||
((Unit*)target)->AddPlayerToVision(this);
|
||||
SetSeer(target);
|
||||
}
|
||||
else
|
||||
{
|
||||
//must immediately set seer back otherwise may crash
|
||||
m_seer = this;
|
||||
|
||||
LOG_DEBUG("maps", "Player::CreateViewpoint: Player {} remove seer", GetName());
|
||||
|
||||
if (!RemoveGuidValue(PLAYER_FARSIGHT, target->GetGUID()))
|
||||
@@ -15173,6 +15182,8 @@ void Player::ActivateSpec(uint8 spec)
|
||||
else
|
||||
++iter;
|
||||
}
|
||||
|
||||
sScriptMgr->OnAfterSpecSlotChanged(this, GetActiveSpec());
|
||||
}
|
||||
|
||||
void Player::LoadActions(PreparedQueryResult result)
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
#include "PlayerTaxi.h"
|
||||
#include "QuestDef.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "TradeData.h"
|
||||
#include "Unit.h"
|
||||
#include "WorldSession.h"
|
||||
@@ -1986,10 +1986,10 @@ public:
|
||||
|
||||
void ProcessTerrainStatusUpdate() override;
|
||||
|
||||
void SendMessageToSet(WorldPacket const* data, bool self) const override { SendMessageToSetInRange(data, GetVisibilityRange(), self); } // pussywizard!
|
||||
void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, Player const* skipped_rcvr = nullptr) const override; // pussywizard!
|
||||
void SendMessageToSetInRange_OwnTeam(WorldPacket const* data, float dist, bool self) const; // pussywizard!
|
||||
void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const override { SendMessageToSetInRange(data, GetVisibilityRange(), skipped_rcvr != this, skipped_rcvr); } // pussywizard!
|
||||
void SendMessageToSet(WorldPacket const* data, bool self) const override { SendMessageToSetInRange(data, GetVisibilityRange(), self, true); } // pussywizard!
|
||||
void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool includeMargin = false, Player const* skipped_rcvr = nullptr) const override; // pussywizard!
|
||||
void SendMessageToSetInRange_OwnTeam(WorldPacket const* data, float dist, bool self) const; // pussywizard! param includeMargin not needed here
|
||||
void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const override { SendMessageToSetInRange(data, GetVisibilityRange(), skipped_rcvr != this, true, skipped_rcvr); } // pussywizard!
|
||||
|
||||
void SendTeleportAckPacket();
|
||||
|
||||
@@ -2342,8 +2342,9 @@ public:
|
||||
|
||||
// currently visible objects at player client
|
||||
GuidUnorderedSet m_clientGUIDs;
|
||||
std::vector<Unit*> m_newVisible; // pussywizard
|
||||
|
||||
[[nodiscard]] bool HaveAtClient(Object const* u) const;
|
||||
[[nodiscard]] bool HaveAtClient(WorldObject const* u) const;
|
||||
[[nodiscard]] bool HaveAtClient(ObjectGuid guid) const;
|
||||
|
||||
[[nodiscard]] bool IsNeverVisible() const override;
|
||||
@@ -2351,13 +2352,13 @@ public:
|
||||
bool IsVisibleGloballyFor(Player const* player) const;
|
||||
|
||||
void GetInitialVisiblePackets(Unit* target);
|
||||
void UpdateObjectVisibility(bool forced = true) override;
|
||||
void UpdateObjectVisibility(bool forced = true, bool fromUpdate = false) override;
|
||||
void UpdateVisibilityForPlayer(bool mapChange = false);
|
||||
void UpdateVisibilityOf(WorldObject* target);
|
||||
void UpdateTriggerVisibility();
|
||||
|
||||
template<class T>
|
||||
void UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
void UpdateVisibilityOf(T* target, UpdateData& data, std::vector<Unit*>& visibleNow);
|
||||
|
||||
uint8 m_forced_speed_changes[MAX_MOVE_TYPE];
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "CreatureAI.h"
|
||||
#include "DisableMgr.h"
|
||||
#include "GameEventMgr.h"
|
||||
#include "GameObjectAI.h"
|
||||
#include "GameTime.h"
|
||||
#include "GitRevision.h"
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "StringConvert.h"
|
||||
#include "Tokenize.h"
|
||||
#include "Transport.h"
|
||||
#include "UpdateData.h"
|
||||
#include "UpdateFieldFlags.h"
|
||||
@@ -70,8 +72,6 @@
|
||||
#include "Weather.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Tokenize.h"
|
||||
#include "StringConvert.h"
|
||||
|
||||
/// @todo: this import is not necessary for compilation and marked as unused by the IDE
|
||||
// however, for some reasons removing it would cause a damn linking issue
|
||||
@@ -5454,7 +5454,7 @@ bool Player::LoadFromDB(ObjectGuid playerGuid, CharacterDatabaseQueryHolder cons
|
||||
// add ghost flag (must be after aura load: PLAYER_FLAGS_GHOST set in aura)
|
||||
if (HasPlayerFlag(PLAYER_FLAGS_GHOST))
|
||||
{
|
||||
m_deathState = DEAD;
|
||||
m_deathState = DeathState::Dead;
|
||||
AddUnitState(UNIT_STATE_ISOLATED);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
#include "ObjectMgr.h"
|
||||
#include "Player.h"
|
||||
#include "Tokenize.h"
|
||||
#include "StringConvert.h"
|
||||
#include "Tokenize.h"
|
||||
|
||||
void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint8 level)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "AchievementMgr.h"
|
||||
#include "BattlefieldMgr.h"
|
||||
#include "CellImpl.h"
|
||||
#include "Channel.h"
|
||||
@@ -35,6 +36,7 @@
|
||||
#include "SpellMgr.h"
|
||||
#include "UpdateFieldFlags.h"
|
||||
#include "Vehicle.h"
|
||||
#include "Weather.h"
|
||||
#include "WeatherMgr.h"
|
||||
#include "WorldStatePackets.h"
|
||||
|
||||
@@ -311,7 +313,7 @@ void Player::Update(uint32 p_time)
|
||||
RegenerateAll();
|
||||
}
|
||||
|
||||
if (m_deathState == JUST_DIED)
|
||||
if (m_deathState == DeathState::JustDied)
|
||||
KillPlayer();
|
||||
|
||||
if (m_nextSave)
|
||||
@@ -413,6 +415,13 @@ void Player::Update(uint32 p_time)
|
||||
TeleportTo(teleportStore_dest, teleportStore_options);
|
||||
}
|
||||
|
||||
if (!IsBeingTeleported() && bRequestForcedVisibilityUpdate)
|
||||
{
|
||||
bRequestForcedVisibilityUpdate = false;
|
||||
UpdateObjectVisibility(true, true);
|
||||
m_delayed_unit_relocation_timer = 0;
|
||||
RemoveFromNotify(NOTIFY_VISIBILITY_CHANGED);
|
||||
}
|
||||
sScriptMgr->OnAfterPlayerUpdate(this, p_time);
|
||||
}
|
||||
|
||||
@@ -789,8 +798,8 @@ bool Player::UpdateCraftSkill(uint32 spellid)
|
||||
GetPureSkillValue(_spell_idx->second->SkillLine);
|
||||
|
||||
// Alchemy Discoveries here
|
||||
SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(spellid);
|
||||
if (spellEntry && spellEntry->Mechanic == MECHANIC_DISCOVERY)
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellid);
|
||||
if (spellInfo && spellInfo->Mechanic == MECHANIC_DISCOVERY)
|
||||
{
|
||||
if (uint32 discoveredSpell = GetSkillDiscoverySpell(
|
||||
_spell_idx->second->SkillLine, spellid, this))
|
||||
@@ -1523,11 +1532,17 @@ void Player::UpdatePotionCooldown(Spell* spell)
|
||||
SetLastPotionId(0);
|
||||
}
|
||||
|
||||
template void Player::UpdateVisibilityOf(Player* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(Creature* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(Corpse* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(GameObject* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(DynamicObject* target, UpdateData& data, std::set<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(Player* target, UpdateData& data,
|
||||
std::vector<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(Creature* target, UpdateData& data,
|
||||
std::vector<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(Corpse* target, UpdateData& data,
|
||||
std::vector<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(GameObject* target, UpdateData& data,
|
||||
std::vector<Unit*>& visibleNow);
|
||||
template void Player::UpdateVisibilityOf(DynamicObject* target,
|
||||
UpdateData& data,
|
||||
std::vector<Unit*>& visibleNow);
|
||||
|
||||
void Player::UpdateVisibilityForPlayer(bool mapChange)
|
||||
{
|
||||
@@ -1538,13 +1553,23 @@ void Player::UpdateVisibilityForPlayer(bool mapChange)
|
||||
m_seer = this;
|
||||
}
|
||||
|
||||
// updates visibility of all objects around point of view for current player
|
||||
Acore::VisibleNotifier notifier(*this);
|
||||
Cell::VisitAllObjects(m_seer, notifier, GetSightRange());
|
||||
notifier.SendToSelf(); // send gathered data
|
||||
Acore::VisibleNotifier notifierNoLarge(
|
||||
*this, mapChange,
|
||||
false); // visit only objects which are not large; default distance
|
||||
Cell::VisitAllObjects(m_seer, notifierNoLarge,
|
||||
GetSightRange() + VISIBILITY_INC_FOR_GOBJECTS);
|
||||
notifierNoLarge.SendToSelf();
|
||||
|
||||
Acore::VisibleNotifier notifierLarge(
|
||||
*this, mapChange, true); // visit only large objects; maximum distance
|
||||
Cell::VisitAllObjects(m_seer, notifierLarge, GetSightRange());
|
||||
notifierLarge.SendToSelf();
|
||||
|
||||
if (mapChange)
|
||||
m_last_notify_position.Relocate(-5000.0f, -5000.0f, -5000.0f, 0.0f);
|
||||
}
|
||||
|
||||
void Player::UpdateObjectVisibility(bool forced)
|
||||
void Player::UpdateObjectVisibility(bool forced, bool fromUpdate)
|
||||
{
|
||||
// Prevent updating visibility if player is not in world (example: LoadFromDB sets drunkstate which updates invisibility while player is not in map)
|
||||
if (!IsInWorld())
|
||||
@@ -1554,19 +1579,26 @@ void Player::UpdateObjectVisibility(bool forced)
|
||||
AddToNotify(NOTIFY_VISIBILITY_CHANGED);
|
||||
else if (!isBeingLoaded())
|
||||
{
|
||||
if (!fromUpdate) // pussywizard:
|
||||
{
|
||||
bRequestForcedVisibilityUpdate = true;
|
||||
return;
|
||||
}
|
||||
Unit::UpdateObjectVisibility(true);
|
||||
UpdateVisibilityForPlayer();
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, T* target, std::set<Unit*>& /*v*/)
|
||||
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, T* target,
|
||||
std::vector<Unit*>& /*v*/)
|
||||
{
|
||||
s64.insert(target->GetGUID());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, GameObject* target, std::set<Unit*>& /*v*/)
|
||||
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& 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
|
||||
@@ -1575,17 +1607,19 @@ inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, GameObject* target,
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, Creature* target, std::set<Unit*>& v)
|
||||
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, Creature* target,
|
||||
std::vector<Unit*>& v)
|
||||
{
|
||||
s64.insert(target->GetGUID());
|
||||
v.insert(target);
|
||||
v.push_back(target);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, Player* target, std::set<Unit*>& v)
|
||||
inline void UpdateVisibilityOf_helper(GuidUnorderedSet& s64, Player* target,
|
||||
std::vector<Unit*>& v)
|
||||
{
|
||||
s64.insert(target->GetGUID());
|
||||
v.insert(target);
|
||||
v.push_back(target);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -1601,7 +1635,8 @@ inline void BeforeVisibilityDestroy<Creature>(Creature* t, Player* p)
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& visibleNow)
|
||||
void Player::UpdateVisibilityOf(T* target, UpdateData& data,
|
||||
std::vector<Unit*>& visibleNow)
|
||||
{
|
||||
if (HaveAtClient(target))
|
||||
{
|
||||
|
||||
@@ -220,7 +220,7 @@ void SocialMgr::GetFriendInfo(Player* player, ObjectGuid friendGUID, FriendInfo&
|
||||
friendInfo.Class = 0;
|
||||
|
||||
Player* pFriend = ObjectAccessor::FindConnectedPlayer(friendGUID);
|
||||
if (!pFriend || AccountMgr::IsGMAccount(pFriend->GetSession()->GetSecurity()))
|
||||
if (!pFriend || pFriend->GetSession()->IsGMAccount())
|
||||
return;
|
||||
|
||||
TeamId teamId = player->GetTeamId();
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "World.h"
|
||||
#include "WorldModel.h"
|
||||
|
||||
MotionTransport::MotionTransport() : Transport(), _transportInfo(nullptr), _isMoving(true), _pendingStop(false), _triggeredArrivalEvent(false), _triggeredDepartureEvent(false), _delayedTeleport(false)
|
||||
MotionTransport::MotionTransport() : Transport(), _transportInfo(nullptr), _isMoving(true), _pendingStop(false), _triggeredArrivalEvent(false), _triggeredDepartureEvent(false), _passengersLoaded(false), _delayedTeleport(false)
|
||||
{
|
||||
m_updateFlag = UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_ROTATION;
|
||||
}
|
||||
@@ -230,14 +230,8 @@ void MotionTransport::Update(uint32 diff)
|
||||
3. transport moves from active to inactive grid
|
||||
4. the grid that transport is currently in unloads
|
||||
*/
|
||||
bool gridActive = GetMap()->IsGridLoaded(GetPositionX(), GetPositionY());
|
||||
|
||||
if (_staticPassengers.empty() && gridActive) // 2.
|
||||
if (_staticPassengers.empty() && GetMap()->IsGridLoaded(GetPositionX(), GetPositionY())) // 2.
|
||||
LoadStaticPassengers();
|
||||
else if (!_staticPassengers.empty() && !gridActive)
|
||||
// 4. - if transports stopped on grid edge, some passengers can remain in active grids
|
||||
// unload all static passengers otherwise passengers won't load correctly when the grid that transport is currently in becomes active
|
||||
UnloadStaticPassengers();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,27 +248,18 @@ void MotionTransport::DelayedUpdate(uint32 /*diff*/)
|
||||
|
||||
void MotionTransport::UpdatePosition(float x, float y, float z, float o)
|
||||
{
|
||||
bool newActive = GetMap()->IsGridLoaded(x, y);
|
||||
Cell oldCell(GetPositionX(), GetPositionY());
|
||||
if (!GetMap()->IsGridLoaded(x, y)) // pussywizard: should not happen, but just in case
|
||||
GetMap()->LoadGrid(x, y);
|
||||
|
||||
Relocate(x, y, z, o);
|
||||
UpdateModelPosition();
|
||||
|
||||
UpdatePassengerPositions(_passengers);
|
||||
|
||||
/* There are four possible scenarios that trigger loading/unloading passengers:
|
||||
1. transport moves from inactive to active grid
|
||||
2. the grid that transport is currently in becomes active
|
||||
3. transport moves from active to inactive grid
|
||||
4. the grid that transport is currently in unloads
|
||||
*/
|
||||
if (_staticPassengers.empty() && newActive) // 1.
|
||||
if (_staticPassengers.empty())
|
||||
LoadStaticPassengers();
|
||||
else if (!_staticPassengers.empty() && !newActive && oldCell.DiffGrid(Cell(GetPositionX(), GetPositionY()))) // 3.
|
||||
UnloadStaticPassengers();
|
||||
else
|
||||
UpdatePassengerPositions(_staticPassengers);
|
||||
// 4. is handed by grid unload
|
||||
}
|
||||
|
||||
void MotionTransport::AddPassenger(WorldObject* passenger, bool withAll)
|
||||
@@ -321,7 +306,8 @@ void MotionTransport::RemovePassenger(WorldObject* passenger, bool withAll)
|
||||
{
|
||||
passenger->SetTransport(nullptr);
|
||||
passenger->m_movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT;
|
||||
passenger->m_movementInfo.transport.Reset();
|
||||
passenger->m_movementInfo.transport.guid.Clear();
|
||||
passenger->m_movementInfo.transport.pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
if (passenger->ToUnit())
|
||||
{
|
||||
passenger->ToUnit()->ClearUnitState(UNIT_STATE_IGNORE_PATHFINDING);
|
||||
@@ -421,6 +407,9 @@ GameObject* MotionTransport::CreateGOPassenger(ObjectGuid::LowType guid, GameObj
|
||||
|
||||
void MotionTransport::LoadStaticPassengers()
|
||||
{
|
||||
if (PassengersLoaded())
|
||||
return;
|
||||
SetPassengersLoaded(true);
|
||||
if (uint32 mapId = GetGOInfo()->moTransport.mapID)
|
||||
{
|
||||
CellObjectGuidsMap const& cells = sObjectMgr->GetMapObjectGuids(mapId, GetMap()->GetSpawnMode());
|
||||
@@ -442,6 +431,7 @@ void MotionTransport::LoadStaticPassengers()
|
||||
|
||||
void MotionTransport::UnloadStaticPassengers()
|
||||
{
|
||||
SetPassengersLoaded(false);
|
||||
while (!_staticPassengers.empty())
|
||||
{
|
||||
WorldObject* obj = *_staticPassengers.begin();
|
||||
@@ -552,19 +542,11 @@ void MotionTransport::DelayedTeleportTransport()
|
||||
_delayedTeleport = false;
|
||||
|
||||
uint32 newMapId = _nextFrame->Node->mapid;
|
||||
Map* newMap = sMapMgr->CreateBaseMap(newMapId);
|
||||
GetMap()->RemoveFromMap<MotionTransport>(this, false);
|
||||
|
||||
float x = _nextFrame->Node->x,
|
||||
y = _nextFrame->Node->y,
|
||||
z = _nextFrame->Node->z,
|
||||
o = _nextFrame->InitialOrientation;
|
||||
|
||||
if (!newMap->IsGridLoaded(x, y) && !_passengers.empty())
|
||||
newMap->LoadGrid(x, y); // xinef: load before adding passengers to new map
|
||||
|
||||
SetMap(newMap);
|
||||
|
||||
PassengerSet _passengersCopy = _passengers;
|
||||
for (PassengerSet::iterator itr = _passengersCopy.begin(); itr != _passengersCopy.end(); )
|
||||
{
|
||||
@@ -610,8 +592,15 @@ void MotionTransport::DelayedTeleportTransport()
|
||||
}
|
||||
}
|
||||
|
||||
Map* newMap = sMapMgr->CreateBaseMap(newMapId);
|
||||
GetMap()->RemoveFromMap<MotionTransport>(this, false);
|
||||
newMap->LoadGrid(x, y); // xinef: load before adding passengers to new map
|
||||
SetMap(newMap);
|
||||
|
||||
Relocate(x, y, z, o);
|
||||
GetMap()->AddToMap<MotionTransport>(this);
|
||||
|
||||
LoadStaticPassengers();
|
||||
}
|
||||
|
||||
void MotionTransport::UpdatePassengerPositions(PassengerSet& passengers)
|
||||
@@ -642,7 +631,7 @@ void MotionTransport::UpdatePassengerPositions(PassengerSet& passengers)
|
||||
case TYPEID_UNIT:
|
||||
{
|
||||
Creature* creature = passenger->ToCreature();
|
||||
GetMap()->CreatureRelocation(creature, x, y, z, o, false);
|
||||
GetMap()->CreatureRelocation(creature, x, y, z, o);
|
||||
|
||||
creature->GetTransportHomePosition(x, y, z, o);
|
||||
CalculatePassengerPosition(x, y, z, &o);
|
||||
@@ -654,7 +643,7 @@ void MotionTransport::UpdatePassengerPositions(PassengerSet& passengers)
|
||||
GetMap()->PlayerRelocation(passenger->ToPlayer(), x, y, z, o);
|
||||
break;
|
||||
case TYPEID_GAMEOBJECT:
|
||||
GetMap()->GameObjectRelocation(passenger->ToGameObject(), x, y, z, o, false);
|
||||
GetMap()->GameObjectRelocation(passenger->ToGameObject(), x, y, z, o);
|
||||
break;
|
||||
case TYPEID_DYNAMICOBJECT:
|
||||
GetMap()->DynamicObjectRelocation(passenger->ToDynObject(), x, y, z, o);
|
||||
@@ -791,6 +780,7 @@ bool StaticTransport::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* m
|
||||
LastUsedScriptID = GetGOInfo()->ScriptId;
|
||||
AIM_Initialize();
|
||||
|
||||
this->setActive(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -925,8 +915,7 @@ void StaticTransport::UpdatePosition(float x, float y, float z, float o)
|
||||
if (!GetMap()->IsGridLoaded(x, y)) // pussywizard: should not happen, but just in case
|
||||
GetMap()->LoadGrid(x, y);
|
||||
|
||||
Relocate(x, y, z, o);
|
||||
UpdateModelPosition();
|
||||
GetMap()->GameObjectRelocation(this, x, y, z, o); // this also relocates the model
|
||||
UpdatePassengerPositions();
|
||||
}
|
||||
|
||||
@@ -953,14 +942,17 @@ void StaticTransport::UpdatePassengerPositions()
|
||||
switch (passenger->GetTypeId())
|
||||
{
|
||||
case TYPEID_UNIT:
|
||||
GetMap()->CreatureRelocation(passenger->ToCreature(), x, y, z, o, false);
|
||||
GetMap()->CreatureRelocation(passenger->ToCreature(), x, y, z, o);
|
||||
break;
|
||||
case TYPEID_PLAYER:
|
||||
if (passenger->IsInWorld())
|
||||
{
|
||||
GetMap()->PlayerRelocation(passenger->ToPlayer(), x, y, z, o);
|
||||
passenger->ToPlayer()->SetFallInformation(GameTime::GetGameTime().count(), z);
|
||||
}
|
||||
break;
|
||||
case TYPEID_GAMEOBJECT:
|
||||
GetMap()->GameObjectRelocation(passenger->ToGameObject(), x, y, z, o, false);
|
||||
GetMap()->GameObjectRelocation(passenger->ToGameObject(), x, y, z, o);
|
||||
break;
|
||||
case TYPEID_DYNAMICOBJECT:
|
||||
GetMap()->DynamicObjectRelocation(passenger->ToDynObject(), x, y, z, o);
|
||||
@@ -1009,7 +1001,8 @@ void StaticTransport::RemovePassenger(WorldObject* passenger, bool withAll)
|
||||
{
|
||||
passenger->SetTransport(nullptr);
|
||||
passenger->m_movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT;
|
||||
passenger->m_movementInfo.transport.Reset();
|
||||
passenger->m_movementInfo.transport.guid.Clear();
|
||||
passenger->m_movementInfo.transport.pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,8 @@ public:
|
||||
PassengerSet const& GetStaticPassengers() const { return _staticPassengers; }
|
||||
void UnloadStaticPassengers();
|
||||
void UnloadNonStaticPassengers();
|
||||
void SetPassengersLoaded(bool loaded) { _passengersLoaded = loaded; }
|
||||
bool PassengersLoaded() const { return _passengersLoaded; }
|
||||
|
||||
KeyFrameVec const& GetKeyFrames() const { return _transportInfo->keyFrames; }
|
||||
void EnableMovement(bool enabled);
|
||||
@@ -102,6 +104,7 @@ private:
|
||||
|
||||
PassengerSet _staticPassengers;
|
||||
mutable std::mutex Lock;
|
||||
bool _passengersLoaded;
|
||||
bool _delayedTeleport;
|
||||
};
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Creature.h"
|
||||
#include "Config.h"
|
||||
#include "Creature.h"
|
||||
#include "Pet.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptMgr.h"
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "CreatureAIImpl.h"
|
||||
#include "CreatureGroups.h"
|
||||
#include "DisableMgr.h"
|
||||
#include "DynamicVisibility.h"
|
||||
#include "Formulas.h"
|
||||
#include "GameObjectAI.h"
|
||||
#include "GameTime.h"
|
||||
@@ -43,23 +44,24 @@
|
||||
#include "MoveSpline.h"
|
||||
#include "MoveSplineInit.h"
|
||||
#include "MovementGenerator.h"
|
||||
#include "MovementPacketBuilder.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "Opcodes.h"
|
||||
#include "OutdoorPvP.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "Pet.h"
|
||||
#include "PetAI.h"
|
||||
#include "Player.h"
|
||||
#include "ReputationMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "Spell.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "StringConvert.h"
|
||||
#include "TargetedMovementGenerator.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "Tokenize.h"
|
||||
#include "Totem.h"
|
||||
#include "TotemAI.h"
|
||||
#include "Transport.h"
|
||||
@@ -68,8 +70,6 @@
|
||||
#include "Vehicle.h"
|
||||
#include "World.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Tokenize.h"
|
||||
#include "StringConvert.h"
|
||||
#include <math.h>
|
||||
|
||||
float baseMoveSpeed[MAX_MOVE_TYPE] =
|
||||
@@ -247,7 +247,7 @@ Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject),
|
||||
m_rootTimes = 0;
|
||||
|
||||
m_state = 0;
|
||||
m_deathState = ALIVE;
|
||||
m_deathState = DeathState::Alive;
|
||||
|
||||
for (uint8 i = 0; i < CURRENT_MAX_SPELL; ++i)
|
||||
m_currentSpells[i] = nullptr;
|
||||
@@ -317,6 +317,12 @@ Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject),
|
||||
|
||||
m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE);
|
||||
|
||||
m_last_notify_position.Relocate(-5000.0f, -5000.0f, -5000.0f, 0.0f);
|
||||
m_last_notify_mstime = 0;
|
||||
m_delayed_unit_relocation_timer = 0;
|
||||
m_delayed_unit_ai_notify_timer = 0;
|
||||
bRequestForcedVisibilityUpdate = false;
|
||||
|
||||
m_applyResilience = false;
|
||||
_instantCast = false;
|
||||
|
||||
@@ -405,6 +411,32 @@ void Unit::Update(uint32 p_time)
|
||||
if (!IsInWorld())
|
||||
return;
|
||||
|
||||
// pussywizard:
|
||||
if (GetTypeId() != TYPEID_PLAYER || (!ToPlayer()->IsBeingTeleported() && !bRequestForcedVisibilityUpdate))
|
||||
{
|
||||
if (m_delayed_unit_relocation_timer)
|
||||
{
|
||||
if (m_delayed_unit_relocation_timer <= p_time)
|
||||
{
|
||||
m_delayed_unit_relocation_timer = 0;
|
||||
//ExecuteDelayedUnitRelocationEvent();
|
||||
FindMap()->i_objectsForDelayedVisibility.insert(this);
|
||||
}
|
||||
else
|
||||
m_delayed_unit_relocation_timer -= p_time;
|
||||
}
|
||||
if (m_delayed_unit_ai_notify_timer)
|
||||
{
|
||||
if (m_delayed_unit_ai_notify_timer <= p_time)
|
||||
{
|
||||
m_delayed_unit_ai_notify_timer = 0;
|
||||
ExecuteDelayedUnitAINotifyEvent();
|
||||
}
|
||||
else
|
||||
m_delayed_unit_ai_notify_timer -= p_time;
|
||||
}
|
||||
}
|
||||
|
||||
_UpdateSpells( p_time );
|
||||
|
||||
if (CanHaveThreatList() && GetThreatMgr().isNeedUpdateToClient(p_time))
|
||||
@@ -568,27 +600,14 @@ void Unit::UpdateSplineMovement(uint32 t_diff)
|
||||
SplineHandler handler(this);
|
||||
movespline->updateState(t_diff, handler);
|
||||
// Xinef: Spline was cleared by StopMoving, return
|
||||
if (!movespline->Initialized()) {
|
||||
if (!movespline->Initialized())
|
||||
{
|
||||
DisableSpline();
|
||||
return;
|
||||
}
|
||||
|
||||
bool arrived = movespline->Finalized();
|
||||
|
||||
if (movespline->isCyclic())
|
||||
{
|
||||
m_splineSyncTimer.Update(t_diff);
|
||||
if (m_splineSyncTimer.Passed())
|
||||
{
|
||||
m_splineSyncTimer.Reset(5000); // Retail value, do not change
|
||||
|
||||
WorldPacket data(SMSG_FLIGHT_SPLINE_SYNC, 4 + GetPackGUID().size());
|
||||
Movement::PacketBuilder::WriteSplineSync(*movespline, data);
|
||||
data.appendPackGUID(GetGUID());
|
||||
SendMessageToSet(&data, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (arrived)
|
||||
{
|
||||
DisableSpline();
|
||||
@@ -597,11 +616,17 @@ void Unit::UpdateSplineMovement(uint32 t_diff)
|
||||
SetByteValue(UNIT_FIELD_BYTES_1, UNIT_BYTES_1_OFFSET_ANIM_TIER, movespline->GetAnimationType());
|
||||
}
|
||||
|
||||
// pussywizard: update always! not every 400ms, because movement generators need the actual position
|
||||
//m_movesplineTimer.Update(t_diff);
|
||||
//if (m_movesplineTimer.Passed() || arrived)
|
||||
UpdateSplinePosition();
|
||||
}
|
||||
|
||||
void Unit::UpdateSplinePosition()
|
||||
{
|
||||
//static uint32 const positionUpdateDelay = 400;
|
||||
|
||||
//m_movesplineTimer.Reset(positionUpdateDelay);
|
||||
Movement::Location loc = movespline->ComputePosition();
|
||||
|
||||
if (movespline->onTransport)
|
||||
@@ -614,14 +639,16 @@ void Unit::UpdateSplinePosition()
|
||||
|
||||
if (TransportBase* transport = GetDirectTransport())
|
||||
transport->CalculatePassengerPosition(loc.x, loc.y, loc.z, &loc.orientation);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasUnitState(UNIT_STATE_CANNOT_TURN))
|
||||
loc.orientation = GetOrientation();
|
||||
// Xinef: if we had spline running update orientation along with position
|
||||
//if (HasUnitState(UNIT_STATE_CANNOT_TURN))
|
||||
// loc.orientation = GetOrientation();
|
||||
|
||||
UpdatePosition(loc.x, loc.y, loc.z, loc.orientation);
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
UpdatePosition(loc.x, loc.y, loc.z, loc.orientation);
|
||||
else
|
||||
ToCreature()->SetPosition(loc.x, loc.y, loc.z, loc.orientation);
|
||||
}
|
||||
|
||||
void Unit::DisableSpline()
|
||||
@@ -1281,6 +1308,11 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
|
||||
// Script Hook For CalculateSpellDamageTaken -- Allow scripts to change the Damage post class mitigation calculations
|
||||
sScriptMgr->ModifySpellDamageTaken(damageInfo->target, damageInfo->attacker, damage, spellInfo);
|
||||
|
||||
if (victim->GetAI())
|
||||
{
|
||||
victim->GetAI()->OnCalculateSpellDamageReceived(damage, this);
|
||||
}
|
||||
|
||||
int32 cleanDamage = 0;
|
||||
if (Unit::IsDamageReducedByArmor(damageSchoolMask, spellInfo))
|
||||
{
|
||||
@@ -1531,6 +1563,11 @@ void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, Weapon
|
||||
// Script Hook For CalculateMeleeDamage -- Allow scripts to change the Damage pre class mitigation calculations
|
||||
sScriptMgr->ModifyMeleeDamage(damageInfo->target, damageInfo->attacker, damage);
|
||||
|
||||
if (victim->GetAI())
|
||||
{
|
||||
victim->GetAI()->OnCalculateMeleeDamageReceived(damage, this);
|
||||
}
|
||||
|
||||
// Calculate armor reduction
|
||||
if (IsDamageReducedByArmor((SpellSchoolMask)(damageInfo->damages[i].damageSchoolMask)))
|
||||
{
|
||||
@@ -4535,7 +4572,7 @@ void Unit::_UnapplyAura(AuraApplicationMap::iterator& i, AuraRemoveMode removeMo
|
||||
if (aurApp->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE && IsTotem() && GetGUID() == aura->GetCasterGUID())
|
||||
{
|
||||
if (ToTotem()->GetSpell() == aura->GetId() && ToTotem()->GetTotemType() == TOTEM_PASSIVE)
|
||||
ToTotem()->setDeathState(JUST_DIED);
|
||||
ToTotem()->setDeathState(DeathState::JustDied);
|
||||
}
|
||||
|
||||
// Remove aurastates only if were not found
|
||||
@@ -5502,7 +5539,7 @@ Aura* Unit::GetAuraOfRankedSpell(uint32 spellId, ObjectGuid casterGUID, ObjectGu
|
||||
return aurApp ? aurApp->GetBase() : nullptr;
|
||||
}
|
||||
|
||||
void Unit::GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelChargesList& dispelList)
|
||||
void Unit::GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelChargesList& dispelList, SpellInfo const* dispelSpell)
|
||||
{
|
||||
// we should not be able to dispel diseases if the target is affected by unholy blight
|
||||
if (dispelMask & (1 << DISPEL_DISEASE) && HasAura(50536))
|
||||
@@ -5548,6 +5585,12 @@ void Unit::GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelCharges
|
||||
continue;
|
||||
}
|
||||
|
||||
// Banish should only be dispelled by Mass Dispel
|
||||
if (aura->GetSpellInfo()->Mechanic == MECHANIC_BANISH && !dispelSpell->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// The charges / stack amounts don't count towards the total number of auras that can be dispelled.
|
||||
// Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
|
||||
// Polymorph instead of 1 / (5 + 1) -> 16%.
|
||||
@@ -9592,7 +9635,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
|
||||
// Cast positive spell on enemy target
|
||||
case 7099: // Curse of Mending
|
||||
case 39703: // Curse of Mending
|
||||
case 29494: // Temptation
|
||||
case 20233: // Improved Lay on Hands (cast on target)
|
||||
{
|
||||
target = victim;
|
||||
@@ -14514,7 +14556,7 @@ void Unit::setDeathState(DeathState s, bool despawn)
|
||||
// death state needs to be updated before RemoveAllAurasOnDeath() calls HandleChannelDeathItem(..) so that
|
||||
// it can be used to check creation of death items (such as soul shards).
|
||||
|
||||
if (s != ALIVE && s != JUST_RESPAWNED)
|
||||
if (s != DeathState::Alive && s != DeathState::JustRespawned)
|
||||
{
|
||||
CombatStop();
|
||||
GetThreatMgr().ClearAllThreat();
|
||||
@@ -14529,7 +14571,7 @@ void Unit::setDeathState(DeathState s, bool despawn)
|
||||
RemoveAllAurasOnDeath();
|
||||
}
|
||||
|
||||
if (s == JUST_DIED)
|
||||
if (s == DeathState::JustDied)
|
||||
{
|
||||
// remove aurastates allowing special moves
|
||||
ClearAllReactives();
|
||||
@@ -14558,7 +14600,7 @@ void Unit::setDeathState(DeathState s, bool despawn)
|
||||
if (ZoneScript* zoneScript = GetZoneScript() ? GetZoneScript() : (ZoneScript*)GetInstanceScript())
|
||||
zoneScript->OnUnitDeath(this);
|
||||
}
|
||||
else if (s == JUST_RESPAWNED)
|
||||
else if (s == DeathState::JustRespawned)
|
||||
{
|
||||
RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); // clear skinnable for creature and player (at battleground)
|
||||
}
|
||||
@@ -15437,9 +15479,9 @@ void Unit::SetLevel(uint8 lvl, bool showLevelChange)
|
||||
|
||||
void Unit::SetHealth(uint32 val)
|
||||
{
|
||||
if (getDeathState() == JUST_DIED)
|
||||
if (getDeathState() == DeathState::JustDied)
|
||||
val = 0;
|
||||
else if (GetTypeId() == TYPEID_PLAYER && getDeathState() == DEAD)
|
||||
else if (GetTypeId() == TYPEID_PLAYER && getDeathState() == DeathState::Dead)
|
||||
val = 1;
|
||||
else
|
||||
{
|
||||
@@ -15731,9 +15773,15 @@ void Unit::CleanupBeforeRemoveFromMap(bool finalCleanup)
|
||||
|
||||
void Unit::CleanupsBeforeDelete(bool finalCleanup)
|
||||
{
|
||||
CleanupBeforeRemoveFromMap(finalCleanup);
|
||||
if (GetTransport())
|
||||
{
|
||||
GetTransport()->RemovePassenger(this);
|
||||
SetTransport(nullptr);
|
||||
m_movementInfo.transport.Reset();
|
||||
m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
|
||||
}
|
||||
|
||||
WorldObject::CleanupsBeforeDelete(finalCleanup);
|
||||
CleanupBeforeRemoveFromMap(finalCleanup);
|
||||
}
|
||||
|
||||
void Unit::UpdateCharmAI()
|
||||
@@ -17506,17 +17554,13 @@ void Unit::SetContestedPvP(Player* attackedPlayer, bool lookForNearContestedGuar
|
||||
player->AddUnitState(UNIT_STATE_ATTACK_PLAYER);
|
||||
player->SetPlayerFlag(PLAYER_FLAGS_CONTESTED_PVP);
|
||||
// call MoveInLineOfSight for nearby contested guards
|
||||
Acore::AIRelocationNotifier notifier(*this);
|
||||
Cell::VisitWorldObjects(this, notifier, GetVisibilityRange());
|
||||
AddToNotify(NOTIFY_AI_RELOCATION);
|
||||
}
|
||||
for (Unit* unit : m_Controlled)
|
||||
if (!HasUnitState(UNIT_STATE_ATTACK_PLAYER))
|
||||
{
|
||||
if (!unit->HasUnitState(UNIT_STATE_ATTACK_PLAYER))
|
||||
{
|
||||
unit->AddUnitState(UNIT_STATE_ATTACK_PLAYER);
|
||||
Acore::AIRelocationNotifier notifier(*unit);
|
||||
Cell::VisitWorldObjects(this, notifier, GetVisibilityRange());
|
||||
}
|
||||
AddUnitState(UNIT_STATE_ATTACK_PLAYER);
|
||||
// call MoveInLineOfSight for nearby contested guards
|
||||
AddToNotify(NOTIFY_AI_RELOCATION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18103,12 +18147,12 @@ void Unit::Kill(Unit* killer, Unit* victim, bool durabilityLoss, WeaponAttackTyp
|
||||
|
||||
if (!spiritOfRedemption)
|
||||
{
|
||||
LOG_DEBUG("entities.unit", "SET JUST_DIED");
|
||||
victim->setDeathState(JUST_DIED);
|
||||
LOG_DEBUG("entities.unit", "SET DeathState::JustDied");
|
||||
victim->setDeathState(DeathState::JustDied);
|
||||
}
|
||||
|
||||
// Inform pets (if any) when player kills target)
|
||||
// MUST come after victim->setDeathState(JUST_DIED); or pet next target
|
||||
// MUST come after victim->setDeathState(DeathState::JustDied); or pet next target
|
||||
// selection will get stuck on same target and break pet react state
|
||||
if (player)
|
||||
{
|
||||
@@ -18517,11 +18561,6 @@ void Unit::SetFeared(bool apply, Unit* fearedBy /*= nullptr*/, bool isFear /*= f
|
||||
{
|
||||
SetTarget();
|
||||
GetMotionMaster()->MoveFleeing(fearedBy, isFear ? 0 : sWorld->getIntConfig(CONFIG_CREATURE_FAMILY_FLEE_DELAY));
|
||||
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(ToPlayer(), true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -18554,11 +18593,6 @@ void Unit::SetConfused(bool apply)
|
||||
{
|
||||
SetTarget();
|
||||
GetMotionMaster()->MoveConfused();
|
||||
|
||||
if (GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(ToPlayer(), true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -19377,7 +19411,7 @@ void Unit::SetPhaseMask(uint32 newPhaseMask, bool update)
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::UpdateObjectVisibility(bool forced)
|
||||
void Unit::UpdateObjectVisibility(bool forced, bool /*fromUpdate*/)
|
||||
{
|
||||
if (!forced)
|
||||
AddToNotify(NOTIFY_VISIBILITY_CHANGED);
|
||||
@@ -19385,7 +19419,8 @@ void Unit::UpdateObjectVisibility(bool forced)
|
||||
{
|
||||
WorldObject::UpdateObjectVisibility(true);
|
||||
Acore::AIRelocationNotifier notifier(*this);
|
||||
Cell::VisitAllObjects(this, notifier, GetVisibilityRange());
|
||||
float radius = 60.0f;
|
||||
Cell::VisitAllObjects(this, notifier, radius);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19424,7 +19459,6 @@ void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ)
|
||||
if (player->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) || player->HasAuraType(SPELL_AURA_FLY))
|
||||
player->SetCanFly(true, true);
|
||||
|
||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true);
|
||||
player->SetCanKnockback(true);
|
||||
}
|
||||
}
|
||||
@@ -19821,10 +19855,10 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
|
||||
Unit* target = (itr->second.castFlags & NPC_CLICK_CAST_TARGET_CLICKER) ? clicker : this;
|
||||
ObjectGuid origCasterGUID = (itr->second.castFlags & NPC_CLICK_CAST_ORIG_CASTER_OWNER) ? GetOwnerGUID() : clicker->GetGUID();
|
||||
|
||||
SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(itr->second.spellId);
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->second.spellId);
|
||||
|
||||
// xinef: dont allow players to enter vehicles on arena
|
||||
if (spellEntry->HasAura(SPELL_AURA_CONTROL_VEHICLE) && caster->GetTypeId() == TYPEID_PLAYER && caster->FindMap() && caster->FindMap()->IsBattleArena())
|
||||
if (spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE) && caster->GetTypeId() == TYPEID_PLAYER && caster->FindMap() && caster->FindMap()->IsBattleArena())
|
||||
continue;
|
||||
|
||||
if (seatId > -1)
|
||||
@@ -19833,7 +19867,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
|
||||
bool valid = false;
|
||||
while (i < MAX_SPELL_EFFECTS)
|
||||
{
|
||||
if (spellEntry->Effects[i].ApplyAuraName == SPELL_AURA_CONTROL_VEHICLE)
|
||||
if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_CONTROL_VEHICLE)
|
||||
{
|
||||
valid = true;
|
||||
break;
|
||||
@@ -19853,18 +19887,18 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
|
||||
{
|
||||
int32 bp0[MAX_SPELL_EFFECTS];
|
||||
for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
|
||||
bp0[j] = spellEntry->Effects[j].BasePoints;
|
||||
bp0[j] = spellInfo->Effects[j].BasePoints;
|
||||
|
||||
bp0[i] = seatId;
|
||||
Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, bp0, nullptr, origCasterGUID);
|
||||
Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, this, clicker, bp0, nullptr, origCasterGUID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsInMap(caster))
|
||||
caster->CastSpell(target, spellEntry, GetVehicleKit() ? TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE : TRIGGERED_NONE, nullptr, nullptr, origCasterGUID);
|
||||
caster->CastSpell(target, spellInfo, GetVehicleKit() ? TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE : TRIGGERED_NONE, nullptr, nullptr, origCasterGUID);
|
||||
else
|
||||
Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, nullptr, nullptr, origCasterGUID);
|
||||
Aura::TryRefreshStackOrCreate(spellInfo, MAX_EFFECT_MASK, this, clicker, nullptr, nullptr, origCasterGUID);
|
||||
}
|
||||
|
||||
result = true;
|
||||
@@ -19883,7 +19917,6 @@ void Unit::EnterVehicle(Unit* base, int8 seatId)
|
||||
if (Player* player = ToPlayer())
|
||||
{
|
||||
sScriptMgr->AnticheatSetUnderACKmount(player);
|
||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19926,7 +19959,6 @@ void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* a
|
||||
return;
|
||||
|
||||
sScriptMgr->AnticheatSetUnderACKmount(player);
|
||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true);
|
||||
|
||||
InterruptNonMeleeSpells(false);
|
||||
player->StopCastingCharm();
|
||||
@@ -19999,7 +20031,6 @@ void Unit::ExitVehicle(Position const* /*exitPosition*/)
|
||||
if (Player* player = ToPlayer())
|
||||
{
|
||||
sScriptMgr->AnticheatSetUnderACKmount(player);
|
||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20073,7 +20104,6 @@ void Unit::_ExitVehicle(Position const* exitPosition)
|
||||
player->SetFallInformation(GameTime::GetGameTime().count(), GetPositionZ());
|
||||
|
||||
sScriptMgr->AnticheatSetUnderACKmount(player);
|
||||
sScriptMgr->AnticheatSetSkipOnePacketForASH(player, true);
|
||||
}
|
||||
else if (HasUnitMovementFlag(MOVEMENTFLAG_ROOT))
|
||||
{
|
||||
@@ -20136,8 +20166,8 @@ void Unit::_ExitVehicle(Position const* exitPosition)
|
||||
if (HasUnitTypeMask(UNIT_MASK_ACCESSORY))
|
||||
{
|
||||
// Vehicle just died, we die too
|
||||
if (vehicleBase->getDeathState() == JUST_DIED)
|
||||
setDeathState(JUST_DIED);
|
||||
if (vehicleBase->getDeathState() == DeathState::JustDied)
|
||||
setDeathState(DeathState::JustDied);
|
||||
// If for other reason we as minion are exiting the vehicle (ejected, master dismounted) - unsummon
|
||||
else
|
||||
{
|
||||
@@ -20283,14 +20313,10 @@ bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool tel
|
||||
if (!Acore::IsValidMapCoord(x, y, z, orientation))
|
||||
return false;
|
||||
|
||||
// Check if angular distance changed
|
||||
bool const turn = G3D::fuzzyGt(M_PI - fabs(fabs(GetOrientation() - orientation) - M_PI), 0.0f);
|
||||
|
||||
// G3D::fuzzyEq won't help here, in some cases magnitudes differ by a little more than G3D::eps, but should be considered equal
|
||||
bool const relocated = (teleport ||
|
||||
std::fabs(GetPositionX() - x) > 0.001f ||
|
||||
std::fabs(GetPositionY() - y) > 0.001f ||
|
||||
std::fabs(GetPositionZ() - z) > 0.001f);
|
||||
float old_orientation = GetOrientation();
|
||||
float current_z = GetPositionZ();
|
||||
bool turn = (old_orientation != orientation);
|
||||
bool relocated = (teleport || GetPositionX() != x || GetPositionY() != y || current_z != z);
|
||||
|
||||
if (!GetVehicle())
|
||||
{
|
||||
@@ -20316,8 +20342,6 @@ bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool tel
|
||||
UpdateObjectVisibility(false);
|
||||
}
|
||||
|
||||
UpdatePositionData();
|
||||
|
||||
return (relocated || turn);
|
||||
}
|
||||
|
||||
@@ -20748,6 +20772,124 @@ bool ConflagrateAuraStateDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time
|
||||
return true;
|
||||
}
|
||||
|
||||
void Unit::ExecuteDelayedUnitRelocationEvent()
|
||||
{
|
||||
this->RemoveFromNotify(NOTIFY_VISIBILITY_CHANGED);
|
||||
if (!this->IsInWorld() || this->IsDuringRemoveFromWorld())
|
||||
return;
|
||||
|
||||
if (this->HasSharedVision())
|
||||
for (SharedVisionList::const_iterator itr = this->GetSharedVisionList().begin(); itr != this->GetSharedVisionList().end(); ++itr)
|
||||
if (Player* player = (*itr))
|
||||
{
|
||||
if (player->IsOnVehicle(this) || !player->IsInWorld() || player->IsDuringRemoveFromWorld()) // players on vehicles have their own event executed (due to passenger relocation)
|
||||
continue;
|
||||
WorldObject* viewPoint = player;
|
||||
if (player->m_seer && player->m_seer->IsInWorld())
|
||||
viewPoint = player->m_seer;
|
||||
if (!viewPoint->IsPositionValid() || !player->IsPositionValid())
|
||||
continue;
|
||||
|
||||
if (Unit* active = viewPoint->ToUnit())
|
||||
{
|
||||
//if (active->IsVehicle()) // always check original unit here, last notify position is not relocated
|
||||
// active = player;
|
||||
|
||||
float dx = active->m_last_notify_position.GetPositionX() - active->GetPositionX();
|
||||
float dy = active->m_last_notify_position.GetPositionY() - active->GetPositionY();
|
||||
float dz = active->m_last_notify_position.GetPositionZ() - active->GetPositionZ();
|
||||
float distsq = dx * dx + dy * dy + dz * dz;
|
||||
float mindistsq = DynamicVisibilityMgr::GetReqMoveDistSq(active->FindMap()->GetEntry()->map_type);
|
||||
if (distsq < mindistsq)
|
||||
continue;
|
||||
|
||||
// this will be relocated below sharedvision!
|
||||
//active->m_last_notify_position.Relocate(active->GetPositionX(), active->GetPositionY(), active->GetPositionZ());
|
||||
}
|
||||
|
||||
Acore::PlayerRelocationNotifier relocateNoLarge(*player, false); // visit only objects which are not large; default distance
|
||||
Cell::VisitAllObjects(viewPoint, relocateNoLarge, player->GetSightRange() + VISIBILITY_INC_FOR_GOBJECTS);
|
||||
relocateNoLarge.SendToSelf();
|
||||
Acore::PlayerRelocationNotifier relocateLarge(*player, true); // visit only large objects; maximum distance
|
||||
Cell::VisitAllObjects(viewPoint, relocateLarge, MAX_VISIBILITY_DISTANCE);
|
||||
relocateLarge.SendToSelf();
|
||||
}
|
||||
|
||||
if (Player* player = this->ToPlayer())
|
||||
{
|
||||
WorldObject* viewPoint = player;
|
||||
if (player->m_seer && player->m_seer->IsInWorld())
|
||||
viewPoint = player->m_seer;
|
||||
|
||||
if (viewPoint->GetMapId() != player->GetMapId() || !viewPoint->IsPositionValid() || !player->IsPositionValid())
|
||||
return;
|
||||
|
||||
if (Unit* active = viewPoint->ToUnit())
|
||||
{
|
||||
if (active->IsVehicle())
|
||||
active = player;
|
||||
|
||||
if (!player->GetFarSightDistance())
|
||||
{
|
||||
float dx = active->m_last_notify_position.GetPositionX() - active->GetPositionX();
|
||||
float dy = active->m_last_notify_position.GetPositionY() - active->GetPositionY();
|
||||
float dz = active->m_last_notify_position.GetPositionZ() - active->GetPositionZ();
|
||||
float distsq = dx * dx + dy * dy + dz * dz;
|
||||
|
||||
float mindistsq = DynamicVisibilityMgr::GetReqMoveDistSq(active->FindMap()->GetEntry()->map_type);
|
||||
if (distsq < mindistsq)
|
||||
return;
|
||||
|
||||
active->m_last_notify_position.Relocate(active->GetPositionX(), active->GetPositionY(), active->GetPositionZ());
|
||||
}
|
||||
}
|
||||
|
||||
Acore::PlayerRelocationNotifier relocateNoLarge(*player, false); // visit only objects which are not large; default distance
|
||||
Cell::VisitAllObjects(viewPoint, relocateNoLarge, player->GetSightRange() + VISIBILITY_INC_FOR_GOBJECTS);
|
||||
relocateNoLarge.SendToSelf();
|
||||
|
||||
if (!player->GetFarSightDistance())
|
||||
{
|
||||
Acore::PlayerRelocationNotifier relocateLarge(*player, true); // visit only large objects; maximum distance
|
||||
Cell::VisitAllObjects(viewPoint, relocateLarge, MAX_VISIBILITY_DISTANCE);
|
||||
relocateLarge.SendToSelf();
|
||||
}
|
||||
|
||||
this->AddToNotify(NOTIFY_AI_RELOCATION);
|
||||
}
|
||||
else if (Creature* unit = this->ToCreature())
|
||||
{
|
||||
if (!unit->IsPositionValid())
|
||||
return;
|
||||
|
||||
float dx = unit->m_last_notify_position.GetPositionX() - unit->GetPositionX();
|
||||
float dy = unit->m_last_notify_position.GetPositionY() - unit->GetPositionY();
|
||||
float dz = unit->m_last_notify_position.GetPositionZ() - unit->GetPositionZ();
|
||||
float distsq = dx * dx + dy * dy + dz * dz;
|
||||
float mindistsq = DynamicVisibilityMgr::GetReqMoveDistSq(unit->FindMap()->GetEntry()->map_type);
|
||||
if (distsq < mindistsq)
|
||||
return;
|
||||
|
||||
unit->m_last_notify_position.Relocate(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ());
|
||||
|
||||
Acore::CreatureRelocationNotifier relocate(*unit);
|
||||
Cell::VisitAllObjects(unit, relocate, unit->GetVisibilityRange() + VISIBILITY_COMPENSATION);
|
||||
|
||||
this->AddToNotify(NOTIFY_AI_RELOCATION);
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::ExecuteDelayedUnitAINotifyEvent()
|
||||
{
|
||||
this->RemoveFromNotify(NOTIFY_AI_RELOCATION);
|
||||
if (!this->IsInWorld() || this->IsDuringRemoveFromWorld())
|
||||
return;
|
||||
|
||||
Acore::AIRelocationNotifier notifier(*this);
|
||||
float radius = 60.0f;
|
||||
Cell::VisitAllObjects(this, notifier, radius);
|
||||
}
|
||||
|
||||
void Unit::SetInFront(WorldObject const* target)
|
||||
{
|
||||
if (!HasUnitState(UNIT_STATE_CANNOT_TURN))
|
||||
@@ -21016,7 +21158,7 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target)
|
||||
else if (index == UNIT_FIELD_FLAGS)
|
||||
{
|
||||
uint32 appendValue = m_uint32Values[UNIT_FIELD_FLAGS];
|
||||
if (target->IsGameMaster() && AccountMgr::IsGMAccount(target->GetSession()->GetSecurity()))
|
||||
if (target->IsGameMaster() && target->GetSession()->IsGMAccount())
|
||||
appendValue &= ~UNIT_FLAG_NOT_SELECTABLE;
|
||||
|
||||
fieldBuffer << uint32(appendValue);
|
||||
@@ -21041,7 +21183,7 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target)
|
||||
|
||||
if (cinfo->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER)
|
||||
{
|
||||
if (target->IsGameMaster() && AccountMgr::IsGMAccount(target->GetSession()->GetSecurity()))
|
||||
if (target->IsGameMaster() && target->GetSession()->IsGMAccount())
|
||||
{
|
||||
if (cinfo->Modelid1)
|
||||
displayId = cinfo->Modelid1; // Modelid1 is a visible model for gms
|
||||
@@ -21176,6 +21318,18 @@ void Unit::setRace(uint8 race)
|
||||
m_race = race;
|
||||
}
|
||||
|
||||
DisplayRace Unit::GetDisplayRaceFromModelId(uint32 modelId) const
|
||||
{
|
||||
if (CreatureDisplayInfoEntry const* display = sCreatureDisplayInfoStore.LookupEntry(modelId))
|
||||
{
|
||||
if (CreatureDisplayInfoExtraEntry const* displayExtra = sCreatureDisplayInfoExtraStore.LookupEntry(display->ExtendedDisplayInfoID))
|
||||
{
|
||||
return DisplayRace(displayExtra->DisplayRaceID);
|
||||
}
|
||||
}
|
||||
return DisplayRace::None;
|
||||
}
|
||||
|
||||
// Check if unit in combat with specific unit
|
||||
bool Unit::IsInCombatWith(Unit const* who) const
|
||||
{
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
#ifndef __UNIT_H
|
||||
#define __UNIT_H
|
||||
|
||||
#include "EventProcessor.h"
|
||||
#include "EnumFlag.h"
|
||||
#include "EventProcessor.h"
|
||||
#include "FollowerRefMgr.h"
|
||||
#include "FollowerReference.h"
|
||||
#include "HostileRefMgr.h"
|
||||
@@ -311,13 +311,13 @@ enum BaseModType
|
||||
|
||||
#define MOD_END (PCT_MOD+1)
|
||||
|
||||
enum DeathState
|
||||
enum class DeathState : uint8
|
||||
{
|
||||
ALIVE = 0,
|
||||
JUST_DIED = 1,
|
||||
CORPSE = 2,
|
||||
DEAD = 3,
|
||||
JUST_RESPAWNED = 4,
|
||||
Alive = 0,
|
||||
JustDied = 1,
|
||||
Corpse = 2,
|
||||
Dead = 3,
|
||||
JustRespawned = 4,
|
||||
};
|
||||
|
||||
enum UnitState
|
||||
@@ -391,7 +391,7 @@ enum UnitMoveType
|
||||
extern float baseMoveSpeed[MAX_MOVE_TYPE];
|
||||
extern float playerBaseMoveSpeed[MAX_MOVE_TYPE];
|
||||
|
||||
enum WeaponAttackType
|
||||
enum WeaponAttackType : uint8
|
||||
{
|
||||
BASE_ATTACK = 0,
|
||||
OFF_ATTACK = 1,
|
||||
@@ -430,7 +430,7 @@ enum CombatRating
|
||||
|
||||
#define MAX_COMBAT_RATING 25
|
||||
|
||||
enum DamageEffectType
|
||||
enum DamageEffectType : uint8
|
||||
{
|
||||
DIRECT_DAMAGE = 0, // used for normal weapon damage (not for class abilities or spells)
|
||||
SPELL_DIRECT_DAMAGE = 1, // spell/class abilities damage
|
||||
@@ -1438,6 +1438,8 @@ public:
|
||||
[[nodiscard]] uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, 1); }
|
||||
[[nodiscard]] uint32 getClassMask() const { return 1 << (getClass() - 1); }
|
||||
[[nodiscard]] uint8 getGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, 2); }
|
||||
[[nodiscard]] DisplayRace GetDisplayRaceFromModelId(uint32 modelId) const;
|
||||
[[nodiscard]] DisplayRace GetDisplayRace() const { return GetDisplayRaceFromModelId(GetDisplayId()); };
|
||||
|
||||
[[nodiscard]] float GetStat(Stats stat) const { return float(GetUInt32Value(static_cast<uint16>(UNIT_FIELD_STAT0) + stat)); }
|
||||
void SetStat(Stats stat, int32 val) { SetStatInt32Value(static_cast<uint16>(UNIT_FIELD_STAT0) + stat, val); }
|
||||
@@ -1819,9 +1821,9 @@ public:
|
||||
|
||||
void BuildHeartBeatMsg(WorldPacket* data) const;
|
||||
|
||||
[[nodiscard]] bool IsAlive() const { return (m_deathState == ALIVE); };
|
||||
[[nodiscard]] bool isDying() const { return (m_deathState == JUST_DIED); };
|
||||
[[nodiscard]] bool isDead() const { return (m_deathState == DEAD || m_deathState == CORPSE); };
|
||||
[[nodiscard]] bool IsAlive() const { return (m_deathState == DeathState::Alive); };
|
||||
[[nodiscard]] bool isDying() const { return (m_deathState == DeathState::JustDied); };
|
||||
[[nodiscard]] bool isDead() const { return (m_deathState == DeathState::Dead || m_deathState == DeathState::Corpse); };
|
||||
DeathState getDeathState() { return m_deathState; };
|
||||
virtual void setDeathState(DeathState s, bool despawn = false); // overwrited in Creature/Player/Pet
|
||||
|
||||
@@ -1995,7 +1997,7 @@ public:
|
||||
AuraApplication* GetAuraApplicationOfRankedSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0, AuraApplication* except = nullptr) const;
|
||||
[[nodiscard]] Aura* GetAuraOfRankedSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0) const;
|
||||
|
||||
void GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelChargesList& dispelList);
|
||||
void GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelChargesList& dispelList, SpellInfo const* dispelSpell);
|
||||
|
||||
[[nodiscard]] bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster = ObjectGuid::Empty) const;
|
||||
[[nodiscard]] uint32 GetAuraCount(uint32 spellId) const;
|
||||
@@ -2145,7 +2147,7 @@ public:
|
||||
// common function for visibility checks for player/creatures with detection code
|
||||
[[nodiscard]] uint32 GetPhaseByAuras() const;
|
||||
void SetPhaseMask(uint32 newPhaseMask, bool update) override;// overwrite WorldObject::SetPhaseMask
|
||||
void UpdateObjectVisibility(bool forced = true) override;
|
||||
void UpdateObjectVisibility(bool forced = true, bool fromUpdate = false) override;
|
||||
|
||||
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY];
|
||||
uint32 m_lastSanctuaryTime;
|
||||
@@ -2419,6 +2421,14 @@ public:
|
||||
void AddPointedBy(SafeUnitPointer* sup) { SafeUnitPointerSet.insert(sup); }
|
||||
void RemovePointedBy(SafeUnitPointer* sup) { SafeUnitPointerSet.erase(sup); }
|
||||
static void HandleSafeUnitPointersOnDelete(Unit* thisUnit);
|
||||
// Relocation Nofier optimization
|
||||
Position m_last_notify_position;
|
||||
uint32 m_last_notify_mstime;
|
||||
uint16 m_delayed_unit_relocation_timer;
|
||||
uint16 m_delayed_unit_ai_notify_timer;
|
||||
bool bRequestForcedVisibilityUpdate;
|
||||
void ExecuteDelayedUnitRelocationEvent();
|
||||
void ExecuteDelayedUnitAINotifyEvent();
|
||||
|
||||
// cooldowns
|
||||
[[nodiscard]] virtual bool HasSpellCooldown(uint32 /*spell_id*/) const { return false; }
|
||||
@@ -2581,7 +2591,7 @@ private:
|
||||
uint32 m_state; // Even derived shouldn't modify
|
||||
uint32 m_CombatTimer;
|
||||
uint32 m_lastManaUse; // msecs
|
||||
TimeTrackerSmall m_splineSyncTimer;
|
||||
//TimeTrackerSmall m_movesplineTimer;
|
||||
|
||||
Diminishing m_Diminishing;
|
||||
// Manage all Units that are threatened by us
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Unit.h"
|
||||
#include "Define.h"
|
||||
#include "SmartEnum.h"
|
||||
#include "Unit.h"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Acore::Impl::EnumUtilsImpl
|
||||
|
||||
@@ -545,8 +545,7 @@ bool Vehicle::IsVehicleInUse()
|
||||
|
||||
void Vehicle::TeleportVehicle(float x, float y, float z, float ang)
|
||||
{
|
||||
if (!_me->GetMap()->IsGridLoaded(x, y))
|
||||
_me->GetMap()->LoadGrid(x, y);
|
||||
_me->GetMap()->LoadGrid(x, y);
|
||||
_me->NearTeleportTo(x, y, z, ang, true);
|
||||
|
||||
for (SeatMap::const_iterator itr = Seats.begin(); itr != Seats.end(); ++itr)
|
||||
|
||||
Reference in New Issue
Block a user