Skip to content

Commit

Permalink
[9405] Make all movements instant applied.
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
VladimirMangos committed Feb 17, 2010
1 parent 00cc0e3 commit 297025b
Show file tree
Hide file tree
Showing 12 changed files with 68 additions and 106 deletions.
31 changes: 30 additions & 1 deletion src/game/Creature.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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);
}
4 changes: 4 additions & 0 deletions src/game/Creature.h
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
96 changes: 25 additions & 71 deletions src/game/Map.cpp
Expand Up @@ -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";
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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);
}

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
float radius = MAX_CREATURE_ATTACK_RADIUS * sWorld.getConfig(CONFIG_FLOAT_RATE_CREATURE_AGGRO);

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 )
Expand Down Expand Up @@ -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());
Expand Down
18 changes: 1 addition & 17 deletions src/game/Map.h
Expand Up @@ -180,14 +180,6 @@ class GridMap
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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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&);
Expand Down
10 changes: 0 additions & 10 deletions src/game/MapInstanced.cpp
Expand Up @@ -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)
Expand Down
1 change: 0 additions & 1 deletion src/game/MapInstanced.h
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/game/MapManager.cpp
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/game/MapManager.h
Expand Up @@ -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();

Expand Down
3 changes: 2 additions & 1 deletion src/game/Unit.cpp
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/game/Unit.h
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/game/World.cpp
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion src/shared/revision_nr.h
@@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "9404"
#define REVISION_NR "9405"
#endif // __REVISION_NR_H__

7 comments on commit 297025b

@master257
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to be a problem with this commit (or a previous one) im getting a float point exception* error when "Cleaning up instances" starts to load :( (gets to 50%)

@kero99
Copy link

@kero99 kero99 commented on 297025b Feb 18, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not confirmed, my world run fine

@VladimirMangos
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe some strange case... " float point exception" something like operation with NaN possible... this commit ofc not related in any form to loading instances: all affected in commit code executed only after server startup and prev. commits also. Some modification has been in past from other side.
Maybe i look at related operations for something strange in code related to "Cleaning up instances"

@VladimirMangos
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see only single place where used float in "Cleaning up instances": Rate.InstanceResetTime value use. What value you have for it in config?

@master257
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yeah that was the problem.. floats are picking with decimals.. thanks for the help vladimir :) (it was set to 0.1 and i changed it to 1!)

@VladimirMangos
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, it also don't must be problems, so possible bug, thanks for info...

@VladimirMangos
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Must be fixed in [9407]

Please sign in to comment.