mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 04:37:00 +00:00
[9405] Make all movements instant applied.
* Drop delayed moves list in Map code * Apply movement coords update always at call including movement to different cell/grid. * Instead removed functionality mark creature as need move notify broadcast at next tick, do it. This must resolve porblesm with CreatureRelocation in past not always update position to new expected at call And in resul next code fail or work in strange way. Mark creature for notifier call at next Update let safe main part remopved functionality implemented in another way: prevent cascade (or infinity chain) in move updates. In fiture possible implement move notify call not at each tick for save time.
This commit is contained in:
parent
e74f62ea31
commit
5af05a314e
12 changed files with 68 additions and 106 deletions
|
|
@ -118,7 +118,8 @@ m_lootMoney(0), m_lootRecipient(0),
|
|||
m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f),
|
||||
m_subtype(subtype), m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0),
|
||||
m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false),
|
||||
m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
|
||||
m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_needNotify(false),
|
||||
m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
|
||||
m_creatureInfo(NULL), m_isActiveObject(false), m_splineFlags(SPLINEFLAG_WALKMODE)
|
||||
{
|
||||
m_regenTimer = 200;
|
||||
|
|
@ -334,6 +335,15 @@ void Creature::Update(uint32 diff)
|
|||
else
|
||||
m_GlobalCooldown -= diff;
|
||||
|
||||
if (m_needNotify)
|
||||
{
|
||||
m_needNotify = false;
|
||||
RelocationNotify();
|
||||
|
||||
if (!IsInWorld())
|
||||
return;
|
||||
}
|
||||
|
||||
switch( m_deathState )
|
||||
{
|
||||
case JUST_ALIVED:
|
||||
|
|
@ -2066,3 +2076,22 @@ void Creature::SendAreaSpiritHealerQueryOpcode(Player *pl)
|
|||
data << GetGUID() << next_resurrect;
|
||||
pl->SendDirectMessage(&data);
|
||||
}
|
||||
|
||||
void Creature::RelocationNotify()
|
||||
{
|
||||
CellPair new_val = MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY());
|
||||
Cell cell(new_val);
|
||||
CellPair cellpair = cell.cellPair();
|
||||
|
||||
MaNGOS::CreatureRelocationNotifier relocationNotifier(*this);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate(); // not trigger load unloaded grids at notifier call
|
||||
|
||||
TypeContainerVisitor<MaNGOS::CreatureRelocationNotifier, WorldTypeMapContainer > c2world_relocation(relocationNotifier);
|
||||
TypeContainerVisitor<MaNGOS::CreatureRelocationNotifier, GridTypeMapContainer > c2grid_relocation(relocationNotifier);
|
||||
|
||||
float radius = MAX_CREATURE_ATTACK_RADIUS * sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_AGGRO);
|
||||
|
||||
cell.Visit(cellpair, c2world_relocation, *GetMap(), *this, radius);
|
||||
cell.Visit(cellpair, c2grid_relocation, *GetMap(), *this, radius);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -615,11 +615,14 @@ class MANGOS_DLL_SPEC Creature : public Unit
|
|||
bool isActiveObject() const { return m_isActiveObject || HasAuraType(SPELL_AURA_BIND_SIGHT) || HasAuraType(SPELL_AURA_FAR_SIGHT); }
|
||||
void SetActiveObjectState(bool on);
|
||||
|
||||
void SetNeedNotify() { m_needNotify = true; }
|
||||
|
||||
void SendAreaSpiritHealerQueryOpcode(Player *pl);
|
||||
|
||||
protected:
|
||||
bool CreateFromProto(uint32 guidlow,uint32 Entry,uint32 team, const CreatureData *data = NULL);
|
||||
bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL);
|
||||
void RelocationNotify();
|
||||
|
||||
// vendor items
|
||||
VendorItemCounts m_vendorItemCounts;
|
||||
|
|
@ -652,6 +655,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
|
|||
bool m_regenHealth;
|
||||
bool m_AI_locked;
|
||||
bool m_isDeadByDefault;
|
||||
bool m_needNotify;
|
||||
|
||||
SpellSchoolMask m_meleeDamageSchoolMask;
|
||||
uint32 m_originalEntry;
|
||||
|
|
|
|||
|
|
@ -40,8 +40,6 @@
|
|||
#include "InstanceSaveMgr.h"
|
||||
#include "VMapFactory.h"
|
||||
|
||||
#define MAX_CREATURE_ATTACK_RADIUS (45.0f * sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_AGGRO))
|
||||
|
||||
GridState* si_GridStates[MAX_GRID_STATE];
|
||||
|
||||
static char const* MAP_MAGIC = "MAPS";
|
||||
|
|
@ -344,9 +342,9 @@ void Map::AddNotifier(Player* obj, Cell const& cell, CellPair const& cellpair)
|
|||
}
|
||||
|
||||
template<>
|
||||
void Map::AddNotifier(Creature* obj, Cell const& cell, CellPair const& cellpair)
|
||||
void Map::AddNotifier(Creature* obj, Cell const&, CellPair const&)
|
||||
{
|
||||
CreatureRelocationNotify(obj,cell,cellpair);
|
||||
obj->SetNeedNotify();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -904,62 +902,38 @@ Map::CreatureRelocation(Creature *creature, float x, float y, float z, float ang
|
|||
if ((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES) == 0)
|
||||
sLog.outDebug("Creature (GUID: %u Entry: %u) added to moving list from grid[%u,%u]cell[%u,%u] to grid[%u,%u]cell[%u,%u].", creature->GetGUIDLow(), creature->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY());
|
||||
#endif
|
||||
AddCreatureToMoveList(creature, x, y, z, ang);
|
||||
// in diffcell/diffgrid case notifiers called at finishing move creature in Map::MoveAllCreaturesInMoveList
|
||||
}
|
||||
else
|
||||
{
|
||||
creature->Relocate(x, y, z, ang);
|
||||
CreatureRelocationNotify(creature, new_cell, new_val);
|
||||
}
|
||||
|
||||
assert(CheckGridIntegrity(creature,true));
|
||||
}
|
||||
|
||||
void Map::AddCreatureToMoveList(Creature *c, float x, float y, float z, float ang)
|
||||
{
|
||||
if(!c)
|
||||
return;
|
||||
|
||||
i_creaturesToMove[c] = CreatureMover(x, y, z, ang);
|
||||
}
|
||||
|
||||
void Map::MoveAllCreaturesInMoveList()
|
||||
{
|
||||
while(!i_creaturesToMove.empty())
|
||||
{
|
||||
// get data and remove element;
|
||||
CreatureMoveList::iterator iter = i_creaturesToMove.begin();
|
||||
Creature* c = iter->first;
|
||||
CreatureMover cm = iter->second;
|
||||
i_creaturesToMove.erase(iter);
|
||||
|
||||
// calculate cells
|
||||
CellPair new_val = MaNGOS::ComputeCellPair(cm.x, cm.y);
|
||||
Cell new_cell(new_val);
|
||||
|
||||
// do move or do move to respawn or remove creature if previous all fail
|
||||
if(CreatureCellRelocation(c,new_cell))
|
||||
if(CreatureCellRelocation(creature,new_cell))
|
||||
{
|
||||
// update pos
|
||||
c->Relocate(cm.x, cm.y, cm.z, cm.ang);
|
||||
CreatureRelocationNotify(c, new_cell, new_cell.cellPair());
|
||||
creature->Relocate(x, y, z, ang);
|
||||
|
||||
// in diffcell/diffgrid case notifiers called in Creature::Update
|
||||
creature->SetNeedNotify();
|
||||
}
|
||||
else
|
||||
{
|
||||
// if creature can't be move in new cell/grid (not loaded) move it to repawn cell/grid
|
||||
// creature coordinates will be updated and notifiers send
|
||||
if(!CreatureRespawnRelocation(c))
|
||||
if(!CreatureRespawnRelocation(creature))
|
||||
{
|
||||
// ... or unload (if respawn grid also not loaded)
|
||||
#ifdef MANGOS_DEBUG
|
||||
if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0)
|
||||
sLog.outDebug("Creature (GUID: %u Entry: %u ) can't be move to unloaded respawn grid.",c->GetGUIDLow(),c->GetEntry());
|
||||
sLog.outDebug("Creature (GUID: %u Entry: %u ) can't be move to unloaded respawn grid.",creature->GetGUIDLow(),creature->GetEntry());
|
||||
#endif
|
||||
AddObjectToRemoveList(c);
|
||||
creature->SetNeedNotify();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
creature->Relocate(x, y, z, ang);
|
||||
creature->SetNeedNotify();
|
||||
}
|
||||
|
||||
assert(CheckGridIntegrity(creature,true));
|
||||
}
|
||||
|
||||
bool Map::CreatureCellRelocation(Creature *c, Cell new_cell)
|
||||
|
|
@ -1055,7 +1029,7 @@ bool Map::CreatureRespawnRelocation(Creature *c)
|
|||
{
|
||||
c->Relocate(resp_x, resp_y, resp_z, resp_o);
|
||||
c->GetMotionMaster()->Initialize(); // prevent possible problems with default move generators
|
||||
CreatureRelocationNotify(c,resp_cell,resp_cell.cellPair());
|
||||
c->SetNeedNotify();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
@ -1074,15 +1048,15 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce)
|
|||
DEBUG_LOG("Unloading grid[%u,%u] for map %u", x,y, i_id);
|
||||
ObjectGridUnloader unloader(*grid);
|
||||
|
||||
// Finish creature moves, remove and delete all creatures with delayed remove before moving to respawn grids
|
||||
// Finish remove and delete all creatures with delayed remove before moving to respawn grids
|
||||
// Must know real mob position before move
|
||||
DoDelayedMovesAndRemoves();
|
||||
RemoveAllObjectsInRemoveList();
|
||||
|
||||
// move creatures to respawn grids if this is diff.grid or to remove list
|
||||
unloader.MoveToRespawnN();
|
||||
|
||||
// Finish creature moves, remove and delete all creatures with delayed remove before unload
|
||||
DoDelayedMovesAndRemoves();
|
||||
// Finish remove and delete all creatures with delayed remove before unload
|
||||
RemoveAllObjectsInRemoveList();
|
||||
|
||||
unloader.UnloadN();
|
||||
delete getNGrid(x, y);
|
||||
|
|
@ -1115,9 +1089,6 @@ bool Map::UnloadGrid(const uint32 &x, const uint32 &y, bool pForce)
|
|||
|
||||
void Map::UnloadAll(bool pForce)
|
||||
{
|
||||
// clear all delayed moves, useless anyway do this moves before map unload.
|
||||
i_creaturesToMove.clear();
|
||||
|
||||
for (GridRefManager<NGridType>::iterator i = GridRefManager<NGridType>::begin(); i != GridRefManager<NGridType>::end(); )
|
||||
{
|
||||
NGridType &grid(*i->getSource());
|
||||
|
|
@ -2066,21 +2037,10 @@ void Map::PlayerRelocationNotify( Player* player, Cell cell, CellPair cellpair )
|
|||
TypeContainerVisitor<MaNGOS::PlayerRelocationNotifier, GridTypeMapContainer > p2grid_relocation(relocationNotifier);
|
||||
TypeContainerVisitor<MaNGOS::PlayerRelocationNotifier, WorldTypeMapContainer > p2world_relocation(relocationNotifier);
|
||||
|
||||
cell.Visit(cellpair, p2grid_relocation, *this, *player, MAX_CREATURE_ATTACK_RADIUS);
|
||||
cell.Visit(cellpair, p2world_relocation, *this, *player, MAX_CREATURE_ATTACK_RADIUS);
|
||||
}
|
||||
float radius = MAX_CREATURE_ATTACK_RADIUS * sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_AGGRO);
|
||||
|
||||
void Map::CreatureRelocationNotify(Creature *creature, Cell cell, CellPair cellpair)
|
||||
{
|
||||
MaNGOS::CreatureRelocationNotifier relocationNotifier(*creature);
|
||||
cell.data.Part.reserved = ALL_DISTRICT;
|
||||
cell.SetNoCreate(); // not trigger load unloaded grids at notifier call
|
||||
|
||||
TypeContainerVisitor<MaNGOS::CreatureRelocationNotifier, WorldTypeMapContainer > c2world_relocation(relocationNotifier);
|
||||
TypeContainerVisitor<MaNGOS::CreatureRelocationNotifier, GridTypeMapContainer > c2grid_relocation(relocationNotifier);
|
||||
|
||||
cell.Visit(cellpair, c2world_relocation, *this, *creature, MAX_CREATURE_ATTACK_RADIUS);
|
||||
cell.Visit(cellpair, c2grid_relocation, *this, *creature, MAX_CREATURE_ATTACK_RADIUS);
|
||||
cell.Visit(cellpair, p2grid_relocation, *this, *player, radius);
|
||||
cell.Visit(cellpair, p2world_relocation, *this, *player, radius);
|
||||
}
|
||||
|
||||
void Map::SendInitSelf( Player * player )
|
||||
|
|
@ -2175,12 +2135,6 @@ inline void Map::setNGrid(NGridType *grid, uint32 x, uint32 y)
|
|||
i_grids[x][y] = grid;
|
||||
}
|
||||
|
||||
void Map::DoDelayedMovesAndRemoves()
|
||||
{
|
||||
MoveAllCreaturesInMoveList();
|
||||
RemoveAllObjectsInRemoveList();
|
||||
}
|
||||
|
||||
void Map::AddObjectToRemoveList(WorldObject *obj)
|
||||
{
|
||||
assert(obj->GetMapId()==GetId() && obj->GetInstanceId()==GetInstanceId());
|
||||
|
|
|
|||
|
|
@ -180,14 +180,6 @@ public:
|
|||
ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data = 0);
|
||||
};
|
||||
|
||||
struct CreatureMover
|
||||
{
|
||||
CreatureMover() : x(0), y(0), z(0), ang(0) {}
|
||||
CreatureMover(float _x, float _y, float _z, float _ang) : x(_x), y(_y), z(_z), ang(_ang) {}
|
||||
|
||||
float x, y, z, ang;
|
||||
};
|
||||
|
||||
// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform
|
||||
#if defined( __GNUC__ )
|
||||
#pragma pack(1)
|
||||
|
|
@ -219,8 +211,6 @@ enum LevelRequirementVsMode
|
|||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
typedef UNORDERED_MAP<Creature*, CreatureMover> CreatureMoveList;
|
||||
|
||||
#define MAX_HEIGHT 100000.0f // can be use for find ground height at surface
|
||||
#define INVALID_HEIGHT -100000.0f // for check, must be equal to VMAP_INVALID_HEIGHT, real value for unknown height is VMAP_INVALID_HEIGHT_VALUE
|
||||
#define MIN_UNLOAD_DELAY 1 // immediate unload
|
||||
|
|
@ -327,10 +317,9 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
|||
GetZoneAndAreaIdByAreaFlag(zoneid,areaid,GetAreaFlag(x,y,z),i_id);
|
||||
}
|
||||
|
||||
virtual void MoveAllCreaturesInMoveList();
|
||||
virtual void RemoveAllObjectsInRemoveList();
|
||||
|
||||
bool CreatureRespawnRelocation(Creature *c); // used only in MoveAllCreaturesInMoveList and ObjectGridUnloader
|
||||
bool CreatureRespawnRelocation(Creature *c); // used only in CreatureRelocation and ObjectGridUnloader
|
||||
|
||||
// assert print helper
|
||||
bool CheckGridIntegrity(Creature* c, bool moved) const;
|
||||
|
|
@ -371,7 +360,6 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
|||
}
|
||||
|
||||
void AddObjectToRemoveList(WorldObject *obj);
|
||||
void DoDelayedMovesAndRemoves();
|
||||
|
||||
virtual bool RemoveBones(uint64 guid, float x, float y);
|
||||
|
||||
|
|
@ -445,13 +433,9 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
|
|||
void SendRemoveTransports( Player * player );
|
||||
|
||||
void PlayerRelocationNotify(Player* player, Cell cell, CellPair cellpair);
|
||||
void CreatureRelocationNotify(Creature *creature, Cell newcell, CellPair newval);
|
||||
|
||||
bool CreatureCellRelocation(Creature *creature, Cell new_cell);
|
||||
|
||||
void AddCreatureToMoveList(Creature *c, float x, float y, float z, float ang);
|
||||
CreatureMoveList i_creaturesToMove;
|
||||
|
||||
bool loaded(const GridPair &) const;
|
||||
void EnsureGridCreated(const GridPair &);
|
||||
bool EnsureGridLoaded(Cell const&);
|
||||
|
|
|
|||
|
|
@ -66,16 +66,6 @@ void MapInstanced::Update(const uint32& t)
|
|||
}
|
||||
}
|
||||
|
||||
void MapInstanced::MoveAllCreaturesInMoveList()
|
||||
{
|
||||
for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i)
|
||||
{
|
||||
i->second->MoveAllCreaturesInMoveList();
|
||||
}
|
||||
|
||||
Map::MoveAllCreaturesInMoveList();
|
||||
}
|
||||
|
||||
void MapInstanced::RemoveAllObjectsInRemoveList()
|
||||
{
|
||||
for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ class MANGOS_DLL_DECL MapInstanced : public Map
|
|||
|
||||
// functions overwrite Map versions
|
||||
void Update(const uint32&);
|
||||
void MoveAllCreaturesInMoveList();
|
||||
void RemoveAllObjectsInRemoveList();
|
||||
bool RemoveBones(uint64 guid, float x, float y);
|
||||
void UnloadAll(bool pForce);
|
||||
|
|
|
|||
|
|
@ -271,10 +271,10 @@ MapManager::Update(uint32 diff)
|
|||
i_timer.SetCurrent(0);
|
||||
}
|
||||
|
||||
void MapManager::DoDelayedMovesAndRemoves()
|
||||
void MapManager::RemoveAllObjectsInRemoveList()
|
||||
{
|
||||
for(MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter)
|
||||
iter->second->DoDelayedMovesAndRemoves();
|
||||
iter->second->RemoveAllObjectsInRemoveList();
|
||||
}
|
||||
|
||||
bool MapManager::ExistMapAndVMap(uint32 mapid, float x,float y)
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ class MANGOS_DLL_DECL MapManager : public MaNGOS::Singleton<MapManager, MaNGOS::
|
|||
return IsValidMapCoord(loc.mapid,loc.coord_x,loc.coord_y,loc.coord_z,loc.orientation);
|
||||
}
|
||||
|
||||
void DoDelayedMovesAndRemoves();
|
||||
void RemoveAllObjectsInRemoveList();
|
||||
|
||||
void LoadTransports();
|
||||
|
||||
|
|
|
|||
|
|
@ -13382,9 +13382,10 @@ void Unit::KnockBackFrom(Unit* target, float horizintalSpeed, float verticalSpee
|
|||
fx = fx2;
|
||||
fy = fy2;
|
||||
fz = fz2;
|
||||
UpdateGroundPositionZ(fx, fy, fz);
|
||||
}
|
||||
|
||||
UpdateGroundPositionZ(fx, fy, fz);
|
||||
|
||||
//FIXME: this mostly hack, must exist some packet for proper creature move at client side
|
||||
// with CreatureRelocation at server side
|
||||
NearTeleportTo(fx, fy, fz, GetOrientation(), this == target);
|
||||
|
|
|
|||
|
|
@ -1056,6 +1056,7 @@ typedef std::set<uint64> GuardianPetList;
|
|||
// delay time next attack to prevent client attack animation problems
|
||||
#define ATTACK_DISPLAY_DELAY 200
|
||||
#define MAX_PLAYER_STEALTH_DETECT_RANGE 45.0f // max distance for detection targets by player
|
||||
#define MAX_CREATURE_ATTACK_RADIUS 45.0f // max distance for creature aggro (use with CONFIG_FLOAT_RATE_CREATURE_AGGRO)
|
||||
|
||||
// Regeneration defines
|
||||
#define REGEN_TIME_FULL 2000 // For this time difference is computed regen value
|
||||
|
|
|
|||
|
|
@ -1429,7 +1429,7 @@ void World::Update(uint32 diff)
|
|||
|
||||
/// </ul>
|
||||
///- Move all creatures with "delayed move" and remove and delete all objects with "delayed remove"
|
||||
sMapMgr.DoDelayedMovesAndRemoves();
|
||||
sMapMgr.RemoveAllObjectsInRemoveList();
|
||||
|
||||
// update the instance reset times
|
||||
sInstanceSaveMgr.Update();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "9404"
|
||||
#define REVISION_NR "9405"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue