// :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;
}
Exemplo n.º 2
0
/****************************************************************\
					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 //