//---------------------------------------------------------------------------- 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()); } }
/* * Return the number of changes (slow) */ sint32 CChangeTrackerBase::nbChanges() const { sint32 nb = 0; TDataSetRow entityIndex (getFirstChanged()); while ( entityIndex.getIndex() != LAST_CHANGED ) { ++nb; entityIndex = getNextChanged( entityIndex ); } return nb; }
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 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() ); } }
// :KLUDGE: This method is was created to avoid duplication of code. It // results that it doesn't have a meaning without prior code to be executed // (see sheetChanged and spawn). It's a trick that should be removed since // there is code duplication anyway in sheetChanged method and its overrides. /// @TODO Clean that mess bool CBot::finalizeSpawn(RYAI_MAP_CRUNCH::CWorldPosition const& botWPos, CAngle const& spawnTheta, float botMeterSize) { // Create eid NLMISC::CEntityId eid = createEntityId(); // Create row TDataSetRow const row = CMirrors::createEntity(eid); if (!row.isValid()) { nlwarning("***> Not Enough Mirror Space for Type: %s", RYZOMID::toString(getRyzomType()).c_str()); return false; } if (_ClientSheet!=NLMISC::CSheetId::Unknown) CMirrors::initSheet(row, _ClientSheet); else CMirrors::initSheet(row, getSheet()->SheetId()); // get the spawn of this persistent objet. setSpawn(getSpawnBot(row, eid, botMeterSize)); CSpawnBot* spawnBot = getSpawnObj(); nlassert(spawnBot); spawnBot->setVisualPropertiesName(); CAIPos botPos; if (!isStuck() && !IsRingShard) botPos = CAIPos(botWPos.toAIVector(),0,0); else botPos = CAIPos(lastTriedPos, 0, 0); spawnBot->setPos(botPos, botWPos); // Use base class method to avoid overload in spawnBot->CModEntityPhysical::setTheta(spawnTheta); this->initAdditionalMirrorValues(); // let derived class do its additional inits before declaring the entity CMirrors::declareEntity(row); linkToWorldMap(this, spawnBot->pos(), getAIInstance()->botMatrix()); return true; }
void CMissionParser::solvePlayerName( TVectorParamCheck & params , const TDataSetRow & playerRow ) { CCharacter * user = PlayerManager.getChar(playerRow); if( !user ) { nlwarning("<CMissionParser solvePlayerName>Invalid user %u",playerRow.getIndex()); return; } for ( uint i = 0; i< params.size(); i++) { if ( params[i].Type == STRING_MANAGER::player ) { params[i].setEIdAIAlias( user->getId(), CAIAliasTranslator::getInstance()->getAIAlias(user->getId()) ); } } }
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 CMissionParser::solveEntitiesNames( TVectorParamCheck & params , const TDataSetRow & playerRow,const NLMISC::CEntityId& giver ) { CCharacter * user = PlayerManager.getChar(playerRow); if( !user ) { nlwarning("<CMissionParser solveEntitiesNames>Invalid user %u",playerRow.getIndex()); return; } for ( uint i = 0; i< params.size(); i++) { if ( params[i].Type == STRING_MANAGER::player ) { params[i].setEIdAIAlias( user->getId(), CAIAliasTranslator::getInstance()->getAIAlias(user->getId()) ); } else if ( params[i].Type == STRING_MANAGER::bot ) { if ( params[i].getEId() == NLMISC::CEntityId::Unknown ) { if ( params[i].Identifier == "giver" ) { params[i].setEIdAIAlias( giver, CAIAliasTranslator::getInstance()->getAIAlias(giver) ); } else { params[i].setEIdAIAlias( CAIAliasTranslator::getInstance()->getEntityId( params[i].Int ), params[i].Int ); } } } else if ( params[i].Type == STRING_MANAGER::string_id && params[i].Identifier == "$guild_name$" ) { // resolve the player guild name /// todo guild mission /* CGuild *g = user->getGuild(); if (g == NULL) { nlwarning("<CMissionParser solveEntitiesNames>No guild for user %u",playerRow.getIndex()); return; } params[i].StringId = g->getNameId(); */ } } }
/****************************************************************\ cbUpdateEntityPosition() \****************************************************************/ void cbClientPosition( CMessage& msgin, const string &serviceName, NLNET::TServiceId serviceId ) { H_AUTO(cbClientPosition); CEntityId id; NLMISC::TGameCycle tick; msgin.serial(id, tick); TDataSetRow entityIndex = TheDataset.getDataSetRow( id ); if ( !entityIndex.isValid() ) { // client may send position even before it is added in system //nldebug( "%u: Receiving a position from client %s which is not in mirror yet", CTickEventHandler::getGameCycle(), id.toString().c_str() ); return; } // entity pos (x, y, z, theta) sint32 x, y, z; float heading; msgin.serial(x, y, z, heading); if (IsRingShard) { // make sure the move that the player is trying to make is legal // if the move wasn't legal then the values of 'x' and 'y' will be changed to make them legal bool moveWasLegal= pCGPMS->MoveChecker->checkMove(entityIndex, x, y, tick); // if the move wasn't legal then dispatch a message to the player if (!moveWasLegal) { // ***TODO *** // // Teleport the player back to a previous valid location // CMessage msgout( "IMPULSION_ID" ); // msgout.serial( master->Id ); // CBitMemStream bms; // GenericXmlMsgManager.pushNameToStream( "TP:CORRECT", bms ); // bms.serial( x ); // bms.serial( y ); // bms.serial( z ); // msgout.serialMemStream( bms ); // CUnifiedNetwork::getInstance()->send( master->Id.getDynamicId(), msgout ); // ***TODO *** } // set the player coordinates in the ring vision universe pCGPMS->RingVisionUniverse->setEntityPosition(entityIndex,x,y); // todo: determine whether player is in water etc for real; bool local= false; bool interior= false; bool water= false; // update the player coordinates in the mirror CMirrorPropValue1DS<sint32>( TheDataset, entityIndex, DSPropertyPOSX )= x; CMirrorPropValue1DS<sint32>( TheDataset, entityIndex, DSPropertyPOSY )= y; CMirrorPropValue1DS<sint32>( TheDataset, entityIndex, DSPropertyPOSZ )= (z&~7) + (local ? 1 : 0) + (interior ? 2 : 0) + (water ? 4 : 0); CMirrorPropValue1DS<float>( TheDataset, entityIndex, DSPropertyORIENTATION )= heading; CMirrorPropValue1DS<NLMISC::TGameCycle>( TheDataset, entityIndex, DSPropertyTICK_POS )= tick; CMirrorPropValue1DS<TYPE_CELL> cell ( TheDataset, entityIndex, DSPropertyCELL ); uint32 cx = (uint16) ( + x/CWorldPositionManager::getCellSize() ); uint32 cy = (uint16) ( - y/CWorldPositionManager::getCellSize() ); cell = (cx<<16) + cy; // update the player position in the ring vision grid pCGPMS->RingVisionUniverse->setEntityPosition(entityIndex,x,y); } else { /* // check player mode and behaviour CMirrorPropValueRO<MBEHAV::TMode> propMode( TheDataset, entityIndex, DSPropertyMODE ); MBEHAV::EMode mode = (MBEHAV::EMode)(propMode().Mode); CMirrorPropValueRO<MBEHAV::CBehaviour> propBehaviour( TheDataset, entityIndex, DSPropertyBEHAVIOUR ); MBEHAV::EBehaviour behaviour = (MBEHAV::EBehaviour)(propBehaviour().Behaviour); if ( (mode == MBEHAV::COMBAT) || (mode == MBEHAV::COMBAT_FLOAT) || (mode == MBEHAV::DEATH) ) { H_AFTER(cbClientPosition); return; } */ CWorldEntity *player = CWorldPositionManager::getEntityPtr(entityIndex); if (player == NULL) { return; } if (player->X() == 0 && player->Y() == 0 && player->Z() == 0) { return; } //CWorldPositionManager::setEntityPosition(id, x, y, z, heading, tick); if (player->getType() == CWorldEntity::Player && player->CheckMotion && player->PosInitialised) { CWorldPositionManager::movePlayer(player, x, y, z, heading, tick); } } } // cbClientPosition //