mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-02-04 03:23:48 +00:00
feat(Core/CreatureAddon): increased visibility for large creatures (#2304)
This commit is contained in:
1025
data/sql/updates/pending_db_world/rev_1569250786242020759.sql
Normal file
1025
data/sql/updates/pending_db_world/rev_1569250786242020759.sql
Normal file
File diff suppressed because it is too large
Load Diff
@@ -2208,6 +2208,10 @@ bool Creature::LoadCreaturesAddon(bool reload)
|
|||||||
SetByteValue(UNIT_FIELD_BYTES_2, 3, 0);
|
SetByteValue(UNIT_FIELD_BYTES_2, 3, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if Creature is Large
|
||||||
|
if (cainfo->isLarge)
|
||||||
|
SetVisibilityDistanceOverride(true);
|
||||||
|
|
||||||
if (cainfo->emote != 0)
|
if (cainfo->emote != 0)
|
||||||
SetUInt32Value(UNIT_NPC_EMOTESTATE, cainfo->emote);
|
SetUInt32Value(UNIT_NPC_EMOTESTATE, cainfo->emote);
|
||||||
|
|
||||||
|
|||||||
@@ -325,6 +325,7 @@ struct CreatureAddon
|
|||||||
uint32 bytes1;
|
uint32 bytes1;
|
||||||
uint32 bytes2;
|
uint32 bytes2;
|
||||||
uint32 emote;
|
uint32 emote;
|
||||||
|
bool isLarge;
|
||||||
std::vector<uint32> auras;
|
std::vector<uint32> auras;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1522,6 +1522,8 @@ float WorldObject::GetVisibilityRange() const
|
|||||||
{
|
{
|
||||||
if (isActiveObject() && !ToPlayer())
|
if (isActiveObject() && !ToPlayer())
|
||||||
return MAX_VISIBILITY_DISTANCE;
|
return MAX_VISIBILITY_DISTANCE;
|
||||||
|
else if (IsVisibilityOverridden() && GetTypeId() == TYPEID_UNIT)
|
||||||
|
return MAX_VISIBILITY_DISTANCE;
|
||||||
else if (GetTypeId() == TYPEID_GAMEOBJECT)
|
else if (GetTypeId() == TYPEID_GAMEOBJECT)
|
||||||
{
|
{
|
||||||
if (IsInWintergrasp())
|
if (IsInWintergrasp())
|
||||||
@@ -1545,6 +1547,8 @@ float WorldObject::GetSightRange(const WorldObject* target) const
|
|||||||
{
|
{
|
||||||
if (target->isActiveObject() && !target->ToPlayer())
|
if (target->isActiveObject() && !target->ToPlayer())
|
||||||
return MAX_VISIBILITY_DISTANCE;
|
return MAX_VISIBILITY_DISTANCE;
|
||||||
|
else if (target->IsVisibilityOverridden() && target->GetTypeId() == TYPEID_UNIT)
|
||||||
|
return MAX_VISIBILITY_DISTANCE;
|
||||||
else if (target->GetTypeId() == TYPEID_GAMEOBJECT)
|
else if (target->GetTypeId() == TYPEID_GAMEOBJECT)
|
||||||
{
|
{
|
||||||
if (IsInWintergrasp() && target->IsInWintergrasp())
|
if (IsInWintergrasp() && target->IsInWintergrasp())
|
||||||
|
|||||||
@@ -525,8 +525,8 @@ void ObjectMgr::LoadCreatureTemplateAddons()
|
|||||||
{
|
{
|
||||||
uint32 oldMSTime = getMSTime();
|
uint32 oldMSTime = getMSTime();
|
||||||
|
|
||||||
// 0 1 2 3 4 5 6
|
// 0 1 2 3 4 5 6 7
|
||||||
QueryResult result = WorldDatabase.Query("SELECT entry, path_id, mount, bytes1, bytes2, emote, auras FROM creature_template_addon");
|
QueryResult result = WorldDatabase.Query("SELECT entry, path_id, mount, bytes1, bytes2, emote, isLarge, auras FROM creature_template_addon");
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
@@ -555,8 +555,9 @@ void ObjectMgr::LoadCreatureTemplateAddons()
|
|||||||
creatureAddon.bytes1 = fields[3].GetUInt32();
|
creatureAddon.bytes1 = fields[3].GetUInt32();
|
||||||
creatureAddon.bytes2 = fields[4].GetUInt32();
|
creatureAddon.bytes2 = fields[4].GetUInt32();
|
||||||
creatureAddon.emote = fields[5].GetUInt32();
|
creatureAddon.emote = fields[5].GetUInt32();
|
||||||
|
creatureAddon.isLarge = fields[6].GetBool();
|
||||||
|
|
||||||
Tokenizer tokens(fields[6].GetString(), ' ');
|
Tokenizer tokens(fields[7].GetString(), ' ');
|
||||||
uint8 i = 0;
|
uint8 i = 0;
|
||||||
creatureAddon.auras.resize(tokens.size());
|
creatureAddon.auras.resize(tokens.size());
|
||||||
for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
|
for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
|
||||||
@@ -937,8 +938,8 @@ void ObjectMgr::LoadCreatureAddons()
|
|||||||
{
|
{
|
||||||
uint32 oldMSTime = getMSTime();
|
uint32 oldMSTime = getMSTime();
|
||||||
|
|
||||||
// 0 1 2 3 4 5 6
|
// 0 1 2 3 4 5 6 7
|
||||||
QueryResult result = WorldDatabase.Query("SELECT guid, path_id, mount, bytes1, bytes2, emote, auras FROM creature_addon");
|
QueryResult result = WorldDatabase.Query("SELECT guid, path_id, mount, bytes1, bytes2, emote, isLarge, auras FROM creature_addon");
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
@@ -974,8 +975,9 @@ void ObjectMgr::LoadCreatureAddons()
|
|||||||
creatureAddon.bytes1 = fields[3].GetUInt32();
|
creatureAddon.bytes1 = fields[3].GetUInt32();
|
||||||
creatureAddon.bytes2 = fields[4].GetUInt32();
|
creatureAddon.bytes2 = fields[4].GetUInt32();
|
||||||
creatureAddon.emote = fields[5].GetUInt32();
|
creatureAddon.emote = fields[5].GetUInt32();
|
||||||
|
creatureAddon.isLarge = fields[6].GetBool();
|
||||||
|
|
||||||
Tokenizer tokens(fields[6].GetString(), ' ');
|
Tokenizer tokens(fields[7].GetString(), ' ');
|
||||||
uint8 i = 0;
|
uint8 i = 0;
|
||||||
creatureAddon.auras.resize(tokens.size());
|
creatureAddon.auras.resize(tokens.size());
|
||||||
for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
|
for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
|
||||||
|
|||||||
@@ -325,6 +325,19 @@ void ObjectUpdater::Visit(GridRefManager<T> &m)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void LargeObjectUpdater::Visit(GridRefManager<T> &m)
|
||||||
|
{
|
||||||
|
T* obj;
|
||||||
|
for (typename GridRefManager<T>::iterator iter = m.begin(); iter != m.end(); )
|
||||||
|
{
|
||||||
|
obj = iter->GetSource();
|
||||||
|
++iter;
|
||||||
|
if (obj->IsInWorld() && obj->IsVisibilityOverridden())
|
||||||
|
obj->Update(i_timeDiff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool AnyDeadUnitObjectInRangeCheck::operator()(Player* u)
|
bool AnyDeadUnitObjectInRangeCheck::operator()(Player* u)
|
||||||
{
|
{
|
||||||
return !u->IsAlive() && !u->HasAuraType(SPELL_AURA_GHOST) && i_searchObj->IsWithinDistInMap(u, i_range);
|
return !u->IsAlive() && !u->HasAuraType(SPELL_AURA_GHOST) && i_searchObj->IsWithinDistInMap(u, i_range);
|
||||||
@@ -358,3 +371,4 @@ bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Creature* u)
|
|||||||
template void ObjectUpdater::Visit<Creature>(CreatureMapType&);
|
template void ObjectUpdater::Visit<Creature>(CreatureMapType&);
|
||||||
template void ObjectUpdater::Visit<GameObject>(GameObjectMapType&);
|
template void ObjectUpdater::Visit<GameObject>(GameObjectMapType&);
|
||||||
template void ObjectUpdater::Visit<DynamicObject>(DynamicObjectMapType&);
|
template void ObjectUpdater::Visit<DynamicObject>(DynamicObjectMapType&);
|
||||||
|
template void LargeObjectUpdater::Visit<Creature>(CreatureMapType&);
|
||||||
|
|||||||
@@ -146,6 +146,16 @@ namespace Trinity
|
|||||||
void Visit(CorpseMapType &) {}
|
void Visit(CorpseMapType &) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LargeObjectUpdater
|
||||||
|
{
|
||||||
|
uint32 i_timeDiff;
|
||||||
|
explicit LargeObjectUpdater(const uint32 diff) : i_timeDiff(diff) {}
|
||||||
|
template<class T> void Visit(GridRefManager<T> &m);
|
||||||
|
void Visit(GameObjectMapType &) {}
|
||||||
|
void Visit(DynamicObjectMapType &) {}
|
||||||
|
void Visit(CorpseMapType &) {}
|
||||||
|
};
|
||||||
|
|
||||||
// SEARCHERS & LIST SEARCHERS & WORKERS
|
// SEARCHERS & LIST SEARCHERS & WORKERS
|
||||||
|
|
||||||
// WorldObject searchers & workers
|
// WorldObject searchers & workers
|
||||||
|
|||||||
@@ -627,7 +627,41 @@ bool Map::IsGridLoaded(const GridCoord &p) const
|
|||||||
return (getNGrid(p.x_coord, p.y_coord) && isGridObjectDataLoaded(p.x_coord, p.y_coord));
|
return (getNGrid(p.x_coord, p.y_coord) && isGridObjectDataLoaded(p.x_coord, p.y_coord));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::VisitNearbyCellsOf(WorldObject* obj, TypeContainerVisitor<Trinity::ObjectUpdater, GridTypeMapContainer> &gridVisitor, TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer> &worldVisitor)
|
void Map::VisitNearbyCellsOfPlayer(Player* player, TypeContainerVisitor<Trinity::ObjectUpdater, GridTypeMapContainer> &gridVisitor,
|
||||||
|
TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer> &worldVisitor,
|
||||||
|
TypeContainerVisitor<Trinity::LargeObjectUpdater, GridTypeMapContainer> &largeObjectVisitor)
|
||||||
|
{
|
||||||
|
// check for valid position
|
||||||
|
if (!player->IsPositionValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// check normal grid activation range of the player
|
||||||
|
VisitNearbyCellsOf(player, gridVisitor, worldVisitor);
|
||||||
|
|
||||||
|
// check maximum visibility distance for large creatures (cells already visited by the normal check won't be visited again)
|
||||||
|
CellArea area = Cell::CalculateCellArea(player->GetPositionX(), player->GetPositionY(), MAX_VISIBILITY_DISTANCE);
|
||||||
|
|
||||||
|
for (uint32 x = area.low_bound.x_coord; x <= area.high_bound.x_coord; ++x)
|
||||||
|
{
|
||||||
|
for (uint32 y = area.low_bound.y_coord; y <= area.high_bound.y_coord; ++y)
|
||||||
|
{
|
||||||
|
// marked cells are those that have been visited
|
||||||
|
// don't visit the same cell twice
|
||||||
|
uint32 cell_id = (y * TOTAL_NUMBER_OF_CELLS_PER_MAP) + x;
|
||||||
|
if (isCellMarked(cell_id))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
markCell(cell_id);
|
||||||
|
CellCoord pair(x, y);
|
||||||
|
Cell cell(pair);
|
||||||
|
|
||||||
|
Visit(cell, largeObjectVisitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Map::VisitNearbyCellsOf(WorldObject* obj, TypeContainerVisitor<Trinity::ObjectUpdater, GridTypeMapContainer> &gridVisitor,
|
||||||
|
TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer> &worldVisitor)
|
||||||
{
|
{
|
||||||
// Check for valid position
|
// Check for valid position
|
||||||
if (!obj->IsPositionValid())
|
if (!obj->IsPositionValid())
|
||||||
@@ -706,9 +740,25 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/)
|
|||||||
// for pets
|
// for pets
|
||||||
TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater);
|
TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater);
|
||||||
|
|
||||||
|
// for large creatures
|
||||||
|
Trinity::LargeObjectUpdater largeObjectUpdater(t_diff);
|
||||||
|
TypeContainerVisitor<Trinity::LargeObjectUpdater, GridTypeMapContainer > grid_large_object_update(largeObjectUpdater);
|
||||||
|
|
||||||
// pussywizard: container for far creatures in combat with players
|
// pussywizard: container for far creatures in combat with players
|
||||||
std::vector<Creature*> updateList; updateList.reserve(10);
|
std::vector<Creature*> updateList; updateList.reserve(10);
|
||||||
|
|
||||||
|
// non-player active objects, increasing iterator in the loop in case of object removal
|
||||||
|
for (m_activeNonPlayersIter = m_activeNonPlayers.begin(); m_activeNonPlayersIter != m_activeNonPlayers.end();)
|
||||||
|
{
|
||||||
|
WorldObject* obj = *m_activeNonPlayersIter;
|
||||||
|
++m_activeNonPlayersIter;
|
||||||
|
|
||||||
|
if (!obj || !obj->IsInWorld())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
VisitNearbyCellsOf(obj, grid_object_update, world_object_update);
|
||||||
|
}
|
||||||
|
|
||||||
// the player iterator is stored in the map object
|
// the player iterator is stored in the map object
|
||||||
// to make sure calls to Map::Remove don't invalidate it
|
// to make sure calls to Map::Remove don't invalidate it
|
||||||
for (m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter)
|
for (m_mapRefIter = m_mapRefManager.begin(); m_mapRefIter != m_mapRefManager.end(); ++m_mapRefIter)
|
||||||
@@ -721,7 +771,7 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/)
|
|||||||
// update players at tick
|
// update players at tick
|
||||||
player->Update(s_diff);
|
player->Update(s_diff);
|
||||||
|
|
||||||
VisitNearbyCellsOf(player, grid_object_update, world_object_update);
|
VisitNearbyCellsOfPlayer(player, grid_object_update, world_object_update, grid_large_object_update);
|
||||||
|
|
||||||
// handle updates for creatures in combat with player and are more than X yards away
|
// handle updates for creatures in combat with player and are more than X yards away
|
||||||
if (player->IsInCombat())
|
if (player->IsInCombat())
|
||||||
@@ -742,18 +792,6 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// non-player active objects, increasing iterator in the loop in case of object removal
|
|
||||||
for (m_activeNonPlayersIter = m_activeNonPlayers.begin(); m_activeNonPlayersIter != m_activeNonPlayers.end();)
|
|
||||||
{
|
|
||||||
WorldObject* obj = *m_activeNonPlayersIter;
|
|
||||||
++m_activeNonPlayersIter;
|
|
||||||
|
|
||||||
if (!obj || !obj->IsInWorld())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
VisitNearbyCellsOf(obj, grid_object_update, world_object_update);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (_transportsUpdateIter = _transports.begin(); _transportsUpdateIter != _transports.end();) // pussywizard: transports updated after VisitNearbyCellsOf, grids around are loaded, everything ok
|
for (_transportsUpdateIter = _transports.begin(); _transportsUpdateIter != _transports.end();) // pussywizard: transports updated after VisitNearbyCellsOf, grids around are loaded, everything ok
|
||||||
{
|
{
|
||||||
MotionTransport* transport = *_transportsUpdateIter;
|
MotionTransport* transport = *_transportsUpdateIter;
|
||||||
|
|||||||
@@ -51,7 +51,11 @@ class BattlegroundMap;
|
|||||||
class Transport;
|
class Transport;
|
||||||
class StaticTransport;
|
class StaticTransport;
|
||||||
class MotionTransport;
|
class MotionTransport;
|
||||||
namespace Trinity { struct ObjectUpdater; }
|
namespace Trinity
|
||||||
|
{
|
||||||
|
struct ObjectUpdater;
|
||||||
|
struct LargeObjectUpdater;
|
||||||
|
}
|
||||||
|
|
||||||
struct ScriptAction
|
struct ScriptAction
|
||||||
{
|
{
|
||||||
@@ -292,7 +296,11 @@ class Map : public GridRefManager<NGridType>
|
|||||||
template<class T> bool AddToMap(T *, bool checkTransport = false);
|
template<class T> bool AddToMap(T *, bool checkTransport = false);
|
||||||
template<class T> void RemoveFromMap(T *, bool);
|
template<class T> void RemoveFromMap(T *, bool);
|
||||||
|
|
||||||
void VisitNearbyCellsOf(WorldObject* obj, TypeContainerVisitor<Trinity::ObjectUpdater, GridTypeMapContainer> &gridVisitor, TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer> &worldVisitor);
|
void VisitNearbyCellsOf(WorldObject* obj, TypeContainerVisitor<Trinity::ObjectUpdater, GridTypeMapContainer> &gridVisitor,
|
||||||
|
TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer> &worldVisitor);
|
||||||
|
void VisitNearbyCellsOfPlayer(Player* player, TypeContainerVisitor<Trinity::ObjectUpdater, GridTypeMapContainer> &gridVisitor,
|
||||||
|
TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer> &worldVisitor,
|
||||||
|
TypeContainerVisitor<Trinity::LargeObjectUpdater, GridTypeMapContainer> &largeObjectVisitor);
|
||||||
virtual void Update(const uint32, const uint32, bool thread = true);
|
virtual void Update(const uint32, const uint32, bool thread = true);
|
||||||
|
|
||||||
float GetVisibilityRange() const { return m_VisibleDistance; }
|
float GetVisibilityRange() const { return m_VisibleDistance; }
|
||||||
|
|||||||
Reference in New Issue
Block a user