bool CMoveChecker::checkMove(TDataSetRow entityIndex, sint32& x, sint32& y, uint32 tick) { // setup a refference to the entity's position record, and bomb if it can't be found TPositions::iterator positionIt= _Positions.find(entityIndex); BOMB_IF(positionIt==_Positions.end(),"Ignoring call to 'checkMove' for an entity who doesn't exist in the move checker",return false); SPosition& thePosition= positionIt->second; // if the character hasn't moved then just return if ( (x==thePosition.X) && (y==thePosition.Y) ) { return true; } // nlinfo("Checking player move: %s from (%d,%d) @tick: %d to (%d,%d) @tick: %d", // entityIndex.toString().c_str(),thePosition.X,thePosition.Y,thePosition.Tick,x,y,tick); // if the tick value is out of order (for instance, after an advanced tp request) then ignore the move DROP_IF(sint32(tick-thePosition.Tick)<0,"Ignoring out of order move for character "+entityIndex.toString(),return false); // *** todo: perform a speed test here // *** todo: perform collision test here // *** NOTE: If move not legal then we need to change values of x and y and return false // record the new position thePosition.X= x; thePosition.Y= y; thePosition.Tick= tick; // generate a few stats addStats(entityIndex,x,y,tick); return true; }
//---------------------------------------------------------------------------- void CBuildingPhysicalGuild::dumpBuilding(NLMISC::CLog & log) const { log.displayNL("<BUILDING_DUMP> CBuildingPhysicalGuild"); log.displayNL("Name: %s, alias: %s", _Name.c_str(), CPrimitivesParser::aliasToString( _Alias ).c_str()); for (uint i = 0; i < _UsersInside.size(); i++) { const TDataSetRow rowId = _UsersInside[i]; CCharacter * c = PlayerManager.getChar( rowId ); if ( !c ) { log.displayNL("\tError: cannot find character with row id: %s", rowId.toString().c_str()); continue; } const string charName = c->getName().toUtf8(); const string charEId = c->getId().toString(); CMirrorPropValueRO<TYPE_CELL> mirrorCell(TheDataset, rowId, DSPropertyCELL); const sint32 cell = mirrorCell; IRoomInstance * room = CBuildingManager::getInstance()->getRoomInstanceFromCell( cell ); if ( !room ) { log.displayNL("\tError: character %s %s is in cell %d but no room was found", charName.c_str(), charEId.c_str(), cell); continue; } CRoomInstanceGuild * guildRoom = dynamic_cast<CRoomInstanceGuild *>(room); if ( !guildRoom ) { log.displayNL("\tError: character %s %s is in cell %d but room is not a guild room but a %s", charName.c_str(), charEId.c_str(), cell, room->getRoomDescription().c_str() ); continue; } const uint32 guildId = c->getGuildId(); string guildName; CGuild * guild = CGuildManager::getInstance()->getGuildFromId( guildId ); if (guild) guildName = guild->getName().toUtf8(); log.displayNL("\tCharacter %s %s [guild name='%s' id=%u] is in cell %d, room desc: %s", charName.c_str(), charEId.c_str(), guildName.c_str(), guildId, cell, room->getRoomDescription().c_str() ); } for (uint i = 0; i < _Guilds.size(); i++) { const uint32 guildId = _Guilds[i]; string guildName; CGuild * guild = CGuildManager::getInstance()->getGuildFromId( guildId ); if (guild) guildName = guild->getName().toUtf8(); log.displayNL("\t> Guild registered in building at index %u: %s", i, guildName.c_str()); } }
void CMoveChecker::teleport(TDataSetRow entityIndex, sint32 x, sint32 y, uint32 tick) { // get hold of the entity's record in the move checker (and creat a new entry if need be) SPosition& thePosition= _Positions[entityIndex]; nlinfo("Move checker teleporting player: %s from (%d,%d) @tick: %d to (%d,%d) @tick: %d", entityIndex.toString().c_str(),thePosition.X,thePosition.Y,thePosition.Tick,x,y,tick); // record the new position thePosition.X= x; thePosition.Y= y; thePosition.Tick= tick; // generate a few stats startStats(entityIndex,x,y,tick); }
void add(TDataSetRow entityIndex, sint32 x, sint32 y, uint32 tick) { // if we've just teleported then there's no point worrying about the time since last update... if (_Teleporting) { // flag teleporting as finished _Teleporting= false; } else { // check whether entity has been updated recently // if((tick-_LastTick)!=1) // { // nlwarning("Move Checker Stats: entity %s has only received position update after %d ticks",entityIndex.toString().c_str(),tick-_LastTick); // } } // calculate the distance moved and check whether its a new record uint32 squaredist= (_X-x)*(_X-x) + (_Y-y)*(_Y-y); if (squaredist>_MaxDist) { _MaxDist=squaredist; _MaxDistTime= std::max((uint32)_Counter,(uint32)_Distances.size()/2); } _Distances[_Counter%_Distances.size()]= squaredist; // store away basic info for next time round _X=x; _Y=y; _LastTick=tick; // increment our counter... ++_Counter; // if we've hit a new record recently then display a log message if ( (_Counter-_MaxDistTime) == (_Distances.size()/2) ) { std::string s; for (uint32 i=(uint32)_Distances.size();i!=0;--i) { s+=NLMISC::toString(" %d",_Distances[(_Counter-i)%_Distances.size()]); } nlinfo("SpeedStats record for %s: %d (%.2f m/s): %s",entityIndex.toString().c_str(),_MaxDist,sqrt((double)_MaxDist)/200,s.c_str()); } }
//---------------------------------------------------------------------------- void CBuildingPhysicalCommon::dumpBuilding(NLMISC::CLog & log) const { log.displayNL("<BUILDING_DUMP> CBuildingPhysicalCommon"); log.displayNL("Name: %s, alias: %s", _Name.c_str(), CPrimitivesParser::aliasToString( _Alias ).c_str()); for (uint i = 0; i < _UsersInside.size(); i++) { const TDataSetRow rowId = _UsersInside[i]; CCharacter * c = PlayerManager.getChar( rowId ); if ( !c ) { log.displayNL("\tError: cannot find character with row id: %s", rowId.toString().c_str()); continue; } const string charName = c->getName().toUtf8(); const string charEId = c->getId().toString(); CMirrorPropValueRO<TYPE_CELL> mirrorCell(TheDataset, rowId, DSPropertyCELL); const sint32 cell = mirrorCell; IRoomInstance * room = CBuildingManager::getInstance()->getRoomInstanceFromCell( cell ); if ( !room ) { log.displayNL("\tError: character %s %s is in cell %d but no room was found", charName.c_str(), charEId.c_str(), cell); continue; } CRoomInstanceCommon * commonRoom = dynamic_cast<CRoomInstanceCommon *>(room); if ( !commonRoom ) { log.displayNL("\tError: character %s %s is in cell %d but room is not a common room but a %s", charName.c_str(), charEId.c_str(), cell, room->getRoomDescription().c_str() ); continue; } log.displayNL("\tCharacter %s %s is in cell %d, room desc: %s", charName.c_str(), charEId.c_str(), cell, room->getRoomDescription().c_str() ); } }