// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include "stdpch.h" // include files #include "nel/misc/types_nl.h" #include "game_share/utils.h" #include "server_share/r2_variables.h" #include "game_share/r2_messages.h" #include "gpm_service.h" #include "messages.h" #include "world_position_manager.h" //#include "game_share/tick_event_handler.h" //#include "game_share/msg_client_server.h" //#include "game_share/mode_and_behaviour.h" //TEMP!!! //#include "game_share/news_types.h" //#include "game_share/bot_chat_types.h" //#include "game_share/brick_types.h" //#include "game_share/loot_harvest_state.h" //#include "game_share/ryzom_version.h" //#include "game_share/synchronised_message.h" using namespace std; using namespace NLMISC; using namespace NLNET; /****************************************************************\ cbAddEntity() \****************************************************************/ /* void cbAddEntity( CMessage& msgin, const string &serviceName, uint16 serviceId ) { // Only for invisible group entities (other entities use the mirror system) CEntityId id; msgin.serial( id ); // entity pos (x, y, z, theta) at tick sint32 x; msgin.serial( x ); sint32 y; msgin.serial( y ); sint32 z; msgin.serial( z ); float t; msgin.serial( t ); // the tick when this entity should be added //--------------------------------- DEBUG ONLY-------------------------------- NLMISC::TGameCycle tick; //msgin.serial( tick ); tick = CTickEventHandler::getGameCycle(); //--------------------------------- DEBUG ONLY-------------------------------- // entity sheet CSheetId sheet; msgin.serial( sheet ); uint8 continent = INVALID_CONTINENT_INDEX; if (msgin.getPos() != (sint32)msgin.length()) msgin.serial(continent); sint32 cell = 0; if (msgin.getPos() != (sint32)msgin.length()) msgin.serial(cell); nlinfo(" Add entity %s at pos (%d,%d,%d)", id.toString().c_str(), x,y,z ); CWorldPositionManager::addEntity( id, x, y, z, t, continent, cell, tick, sheet, id.getDynamicId() ); } // cbAddEntity // */ /****************************************************************\ cbAddIAObject() \****************************************************************/ /* void cbAddIAObject( CMessage& msgin, const string &serviceName, uint16 serviceId ) { nlerror( "TODO: process ADD_IA_OBJECT" ); } */ /****************************************************************\ cbAddEntities() \****************************************************************/ /*void cbAddEntities( CMessage& msgin, const string &serviceName, uint16 serviceId ) { //nlinfo("received ADD_ENTITIES request"); uint32 entitiesCount; msgin.serial( entitiesCount ); for( uint32 i = 0; i < entitiesCount; i++ ) { CEntityId id; msgin.serial( id ); // entity pos (x, y, z, theta) at tick sint32 x; msgin.serial( x ); sint32 y; msgin.serial( y ); sint32 z; msgin.serial( z ); float t; msgin.serial( t ); // the tick when this entity should be added //--------------------------------- DEBUG ONLY-------------------------------- NLMISC::TGameCycle tick; //msgin.serial( tick ); tick = CTickEventHandler::getGameCycle(); //--------------------------------- DEBUG ONLY-------------------------------- // entity sheet CSheetId sheet; msgin.serial( sheet ); nlinfo(" Add entity %s at pos (%d,%d,%d)", id.toString().c_str(), x,y,z ); CWorldPositionManager::addEntity(id, x, y, z, t, INVALID_CONTINENT_INDEX, 0, tick, sheet, id.getDynamicId() ); } } // cbAddEntities // /* /****************************************************************\ cbRemoveEntity() \****************************************************************/ /* void cbRemoveEntity( CMessage& msgin, const string &serviceName, uint16 serviceId ) { // Only for invisible group entities (other entities use the mirror system) CEntityId id; id.serial( msgin ); nlinfo("received REMOVE_ENTITY request for id %s", id.toString().c_str() ); CWorldPositionManager::onRemoveEntity( id ); } // cbRemoveEntity // */ /****************************************************************\ cbRemoveEntities() \****************************************************************/ /*void cbRemoveEntities( CMessage& msgin, const string &serviceName, uint16 serviceId ) { nlinfo("received REMOVE_ENTITIES request"); list ids; msgin.serialCont( ids ); list idsAgents; list::iterator it; for( it = ids.begin(); it!=ids.end(); ++it ) { CWorldPositionManager::removeEntity( *it ); nlinfo(" REMOVE_ENTITY id %s", (*it).toString().c_str() ); if( (*it).getType() == RYZOMID::npc ) { idsAgents.push_back( *it ); } } if( idsAgents.size() != 0 ) { CMessage msgout("REMOVE_ENTITY"); for ( it = idsAgents.begin() ; it != idsAgents.end() ; ++it) msgout.serial( const_cast (*it) ); sendMessageViaMirror( "AgS", msgout ); } }*/ // cbRemoveEntities // /****************************************************************\ CGPMPlayerPrivilegeInst::callback \****************************************************************/ void CGPMPlayerPrivilegeInst::callback (const std::string &name, NLNET::TServiceId id) { CWorldEntity* entity = CWorldPositionManager::getEntityPtr(PlayerIndex); if (entity == NULL || entity->PlayerInfos == NULL) { nlwarning("CGPMPlayerPrivilegeInst::callback(): entity '%d' is not a player", PlayerIndex.getIndex()); return; } // enable/disable speed checking, only enabled for basic players entity->PlayerInfos->CheckSpeed = (Type == CGPMPlayerPrivilege::Player); } /****************************************************************\ cbSetPlayerFlags() \****************************************************************/ void cbSetPlayerFlags( CMessage& msgin, const string &serviceName, NLNET::TServiceId serviceId ) { R2::CMessageSetGPMSPlayerFlags msgData; msgin.serial(msgData); CWorldEntity* entity = CWorldPositionManager::getEntityPtr(msgData.PlayerIndex); DROP_IF(entity == NULL || entity->PlayerInfos == NULL, NLMISC::toString("cbSetPlayerFlags(): entity '%d' is not a player", msgData.PlayerIndex.getIndex()), return); // enable/disable speed checking, only enabled for basic players entity->PlayerInfos->CheckSpeed = msgData.LimitSpeed; } /****************************************************************\ cbBag() \****************************************************************/ void cbBag( CMessage& msgin, const string &serviceName, NLNET::TServiceId serviceId ) { CEntityId id; vector content; msgin.serial(id); msgin.serialCont(content); TDataSetRow index = CWorldPositionManager::getEntityIndex(id); CWorldPositionManager::setContent(index, content); } // cbBag // /****************************************************************\ cbLoadContinent() \****************************************************************/ void cbLoadContinent( CMessage& msgin, const string &serviceName, NLNET::TServiceId serviceId ) { uint8 continent; string name; string file; // load continent index msgin.serial(continent); // load continent name msgin.serial(name); // load continent filename msgin.serial(file); // load continent in position manager CWorldPositionManager::loadContinent(name, file, continent); } /****************************************************************\ cbRemoveContinent() \****************************************************************/ void cbRemoveContinent( CMessage& msgin, const string &serviceName, NLNET::TServiceId serviceId ) { uint8 continent; // load continent index msgin.serial(continent); // remove continent from position manager CWorldPositionManager::removeContinent(continent); } /****************************************************************\ cbCreateIndoorUnit() \****************************************************************/ void cbCreateIndoorUnit( CMessage& msgin, const string &serviceName, NLNET::TServiceId serviceId ) { DROP_IF(IsRingShard,"Creating indoor units not supported on ring shards!",return); sint32 cell; // cell id (should be >= 2) msgin.serial(cell); if (cell < 2) { nlwarning("cbCreateIndoorUnit(): try to create unit using id < 2"); return; } CWorldPositionManager::createIndoorCell(cell); nlinfo("MSG: Creating indoor unit %d",cell); } /****************************************************************\ cbCreateBuilding() \****************************************************************/ void cbCreateBuilding( CMessage& msgin, const string &serviceName, NLNET::TServiceId serviceId ) { uint8 continent; string id; CVectorD position; msgin.serial(continent); msgin.serial(id); msgin.serial(position); CWorldPositionManager::createBuildingInstance(continent, id, position); } /****************************************************************\ cbCreateObstacle() \****************************************************************/ void cbCreateObstacle( CMessage& msgin, const string &serviceName, NLNET::TServiceId serviceId ) { string id, file; CVectorD position; float angle; while (msgin.getPos() < (sint32)msgin.length()) { msgin.serial(id, file, position, angle); CWorldPositionManager::instanciatePacsPrim(id, file, position, angle); } } /****************************************************************\ cbRemoveObstacle() \****************************************************************/ void cbRemoveObstacle( CMessage& msgin, const string &serviceName, NLNET::TServiceId serviceId ) { string id; while (msgin.getPos() < (sint32)msgin.length()) { msgin.serial(id); CWorldPositionManager::removePacsPrim(id); } } /****************************************************************\ cbSetObstacle() \****************************************************************/ void cbSetObstacle( CMessage& msgin, const string &serviceName, NLNET::TServiceId serviceId ) { string id; bool obstacle; while (msgin.getPos() < (sint32)msgin.length()) { msgin.serial(id, obstacle); CWorldPositionManager::setObstacle(id, obstacle); } } /****************************************************************\ cbUpdateEntityPosition() \****************************************************************/ /* void cbUpdateEntityPosition( CMessage& msgin, const string &serviceName, uint16 serviceId ) { H_BEFORE(cbUpdatePosition); //Use only for tp, update position and clear behaviours list //nlinfo("received UPDATE_ENTITY_POSITION request"); CEntityId id; id.serial( msgin ); // entity pos (x, y, z, theta) at tick sint32 x; msgin.serial( x ); sint32 y; msgin.serial( y ); sint32 z; msgin.serial( z ); float t; msgin.serial( t ); NLMISC::TGameCycle tick; msgin.serial( tick ); // nlwarning("GPMS Received Update Position, Pos(%.3f,%.3f,%.3f), theta = %.3f", x, y, z,t ); CWorldPositionManager::setEntityPosition(id, x, y, z, t, tick); H_AFTER(cbUpdatePosition); } // cbUpdateEntityPosition // */ /****************************************************************\ cbUpdateEntitiesPositions() \****************************************************************/ /* void cbUpdateEntitiesPositions( CMessage& msgin, const string &serviceName, uint16 serviceId ) { H_BEFORE(cbUpdatePositions); //Use only for tp, update position and clear behaviours list //nlinfo("received UPDATE_ENTITIES_POSITIONS request"); uint16 entitiesCount; msgin.serial( entitiesCount ); NLMISC::CEntityId sid; sint32 x, y, z; float t; NLMISC::TGameCycle tick; for (uint16 i = 0 ; i < entitiesCount ; ++i) { msgin.serial( sid ); msgin.serial( x ); msgin.serial( y ); msgin.serial( z ); msgin.serial( t ); msgin.serial( tick ); //nlinfo("Entity %s: received (%.3f,%.3f,%.3f), theta = %.3f", sid.toString().c_str(), x*0.001, y*0.001, z*0.001,t ); CWorldPositionManager::setEntityPosition(sid, x, y, z, t, tick); } H_AFTER(cbUpdatePositions); } // cbUpdateEntitiesPositions // */ /****************************************************************\ cbUpdateEntitiesPositions() \****************************************************************/ /* void cbUpdateEntitiesPositionsUsingSize( CMessage& msgin, const string &serviceName, uint16 serviceId ) { H_BEFORE(cbUpdatePositions); //nlinfo("received UPDATE_ENTITIES_POSITIONS request"); NLMISC::CEntityId sid; sint32 x, y, z; float t; NLMISC::TGameCycle tick; while (msgin.getPos() < (sint32)msgin.length()) { msgin.serial( sid ); msgin.serial( x ); msgin.serial( y ); msgin.serial( z ); msgin.serial( t ); msgin.serial( tick ); //nlinfo("Entity %s: received (%.3f,%.3f,%.3f), theta = %.3f", id.toString().c_str(), x*0.001, y*0.001, z*0.001,t ); CWorldPositionManager::setEntityPosition(sid, x, y, z, t, tick); } H_AFTER(cbUpdatePositions); } // cbUpdateEntitiesPositions // */ /* /// Update orientation of several entities void cbUpdateEntitiesOrientations( CMessage& msgin, const string &serviceName, uint16 serviceId ) /// Update position of several entities (for re-spawn, position correction, server resync...) void cbUpdateEntitiesPositionsUsingSize( CMessage& msgin, const string &serviceName, uint16 serviceId ) /// Update orientation of several entities void cbUpdateEntitiesOrientationsUsingSize( CMessage& msgin, const string &serviceName, uint16 serviceId ) */ /****************************************************************\ cbEntityTeleport() \****************************************************************/ void cbEntityTeleportation( CMessage& msgin, const string &serviceName, NLNET::TServiceId serviceId ) { CEntityId id; NLMISC::TGameCycle tick; id.serial( msgin ); TDataSetRow index = CWorldPositionManager::getEntityIndex(id); if (!index.isValid()) return; // if no position provided, teleport entity to nowhere if (msgin.getPos() == (sint32)msgin.length()) { if (IsRingShard) { // update the entity position in the ring vision universe pCGPMS->RingVisionUniverse->setEntityPosition(index,0,0); // update the player coordinates in the mirror CMirrorPropValue1DS( TheDataset, index, DSPropertyPOSX )= 0; CMirrorPropValue1DS( TheDataset, index, DSPropertyPOSY )= 0; CMirrorPropValue1DS( TheDataset, index, DSPropertyPOSZ )= 0; } else { CWorldPositionManager::teleport(index, 0, 0, 0, 0.0f, NO_CONTINENT_INDEX, 0, CTickEventHandler::getGameCycle()); } nlinfo("MSG: Teleporting entity %d to continent 0 (0, 0, 0)",index.getIndex()); return; } // entity pos (x, y, z, theta) at tick sint32 x; msgin.serial( x ); sint32 y; msgin.serial( y ); sint32 z; msgin.serial( z ); float t; msgin.serial( t ); msgin.serial( tick ); // use default continent 0 uint8 continent = INVALID_CONTINENT_INDEX; if (msgin.getPos() != (sint32)msgin.length()) msgin.serial(continent); sint32 cell = 0; if (msgin.getPos() != (sint32)msgin.length()) msgin.serial(cell); if (cell > 0) { nlwarning("cbEntityTeleportation(): cell=%d for %s should be zero or negative, forced to 0", cell, id.toString().c_str()); cell = 0; } uint8 move_to_new_cell = 0; if (msgin.getPos() != (sint32)msgin.length()) msgin.serial(move_to_new_cell); if (IsRingShard) { // update the ring vision universe position pCGPMS->RingVisionUniverse->setEntityPositionDelayed(index,x,y,tick); // tell the move checker to teleport the entity too pCGPMS->MoveChecker->teleport(index, x, y, tick); // update the player coordinates in the mirror CMirrorPropValue1DS( TheDataset, index, DSPropertyPOSX )= x; CMirrorPropValue1DS( TheDataset, index, DSPropertyPOSY )= y; CMirrorPropValue1DS( TheDataset, index, DSPropertyPOSZ )= z; CMirrorPropValue1DS( TheDataset, index, DSPropertyORIENTATION )= t; } else { if (move_to_new_cell == 1) { nlinfo("MSG: Sliding entity %d to cell %d) at tick: %d",index.getIndex(),cell,tick); CWorldPositionManager::updateEntityPosition(CWorldPositionManager::getEntityPtr(index), cell); } else { nlinfo("MSG: Teleporting entity %d to continent %d cell %d (%d, %d, %d) at tick: %d",index.getIndex(),continent,cell,x,y,z,tick); CWorldPositionManager::teleport(index, x, y, z, t, continent, cell, tick); } } // lock entity after a real teleport CWorldPositionManager::lock(index, 10); } // cbEntityTeleportation // /****************************************************************\ cbEntityPosition() \****************************************************************/ void cbEntityPosition( CMessage& msgin, const string &serviceName, NLNET::TServiceId serviceId ) { // CEntityId sender; // sender.serial( msgin ); CEntityId id; id.serial( msgin ); TDataSetRow index = CWorldPositionManager::getEntityIndex(id); const CWorldEntity *pEntity = CWorldPositionManager::getEntity( index ); if( pEntity ) { CMessage msgout( "ENTITY_POS" ); // msgout.serial( sender ); msgout.serial( id ); sint32 val; val = pEntity->X(); msgout.serial( val ); val = pEntity->Y(); msgout.serial( val ); val = pEntity->Z(); msgout.serial( val ); float t = pEntity->Theta(); msgout.serial( t ); sendMessageViaMirror (serviceId, msgout); } else { nlwarning("Entity position : entity %s is not in the GPMS", id.toString().c_str()); } } // cbEntityPosition // /****************************************************************\ Attach child entity to a father \****************************************************************/ void cbAttach( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) { CEntityId father, child; sint32 x, y, z; msgin.serial(father); msgin.serial(child); msgin.serial(x, y, z); TDataSetRow indexFather = CWorldPositionManager::getEntityIndex(father); TDataSetRow indexChild = CWorldPositionManager::getEntityIndex(child); CWorldPositionManager::attach(indexFather, indexChild, x, y, z); } /****************************************************************\ Detach child entity of its current father \****************************************************************/ void cbDetach( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) { CEntityId child; msgin.serial(child); TDataSetRow childIndex = CWorldPositionManager::getEntityIndex(child); CWorldPositionManager::detach(childIndex); } /****************************************************************\ acquire control \****************************************************************/ void cbAcquireControl( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) { CEntityId slave, master; sint32 x, y, z; msgin.serial(slave, master); msgin.serial(x, y, z); TDataSetRow indexSlave = CWorldPositionManager::getEntityIndex(slave); TDataSetRow indexMaster = CWorldPositionManager::getEntityIndex(master); CWorldPositionManager::acquireControl(indexSlave, indexMaster, x, y, z); if (IsRingShard) { pCGPMS->RingVisionUniverse->setEntityPosition(indexMaster,x,y); pCGPMS->RingVisionUniverse->setEntityPosition(indexSlave,x,y); } nlinfo("MSG: Master %s acquire control of slave %s at (%d, %d, %d)",master.toString().c_str(),slave.toString().c_str(),x,y,z); } /****************************************************************\ leave control \****************************************************************/ void cbLeaveControl( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) { CEntityId master; msgin.serial(master); TDataSetRow indexMaster = CWorldPositionManager::getEntityIndex(master); CWorldPositionManager::leaveControl(indexMaster); nlinfo("MSG: Master %s release control of slave",master.toString().c_str()); } /****************************************************************\ activate player self slot \****************************************************************/ void cbActivateSelf( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) { #ifdef HANDLE_SLOT0_SPECIAL CEntityId id; msgin.serial(id); TDataSetRow index = CWorldPositionManager::getEntityIndex(id); CWorldEntity *entity = CWorldPositionManager::getEntityPtr(index); CWorldPositionManager::activateSelfSlot(entity); #endif } /****************************************************************\ desactivate player self slot \****************************************************************/ void cbDesactivateSelf( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) { #ifdef HANDLE_SLOT0_SPECIAL CEntityId id; msgin.serial(id); TDataSetRow index = CWorldPositionManager::getEntityIndex(id); CWorldEntity *entity = CWorldPositionManager::getEntityPtr(index); CWorldPositionManager::desactivateSelfSlot(entity); #endif } // The following removed by Sadge because the entity has been removed from the mirror by the time the message arrives, // making it redundant ///****************************************************************\ // disable vision processing //\****************************************************************/ //void cbDisableVisionProcessing( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) //{ // CEntityId id; // // msgin.serial(id); // // TDataSetRow index = CWorldPositionManager::getEntityIndex(id); // CWorldPositionManager::setPlayerVisionProcessing(index, false); //} /****************************************************************\ Subscribe to a trigger \****************************************************************/ void cbTriggerSubscribe( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) { while ((uint32)msgin.getPos() < msgin.length()) { string name; uint16 id; msgin.serial(name, id); CWorldPositionManager::triggerSubscribe(serviceId, name, id); } } /****************************************************************\ Unsubscribe to a trigger \****************************************************************/ void cbTriggerUnsubscribe( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) { while ((uint32)msgin.getPos() < msgin.length()) { uint16 id; msgin.serial(id); CWorldPositionManager::triggerUnsubscribe(serviceId, id); } } /****************************************************************\ request all entities arround an entity \****************************************************************/ void cbEntitiesArroundEntity( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) { CEntityId id; // base entity for decide list of entities arround this list< string > propertySubscribe; // list of properties subscribe msgin.serial( id ); msgin.serialCont( propertySubscribe ); CWorldPositionManager::requestForEntityAround( serviceId, id, propertySubscribe ); nlinfo("Service %s asked for local mirror around entity %s",serviceName.c_str(), id.toString().c_str() ); } /****************************************************************\ end subscription for all entities arround an entity \****************************************************************/ void cbEndEntitiesArroundEntity( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) { CEntityId id; // base entity for decide list of entities arround this msgin.serial( id ); CWorldPositionManager::unrequestForEntityAround( serviceId, id ); nlinfo("Service %s unsubscribe for local mirror around entity %s",serviceName.c_str(), id.toString().c_str() ); } /****************************************************************\ ponctual vision request \****************************************************************/ void cbVisionRequest( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) { sint32 rid; sint32 x, y; sint32 range; msgin.serial(rid, x, y, range); static vector > entities; entities.clear(); // get vision CWorldPositionManager::visionRequest(x, y, range, entities); // build vision answer CMessage msgout("VISION_ANSWER"); msgout.serial(rid); uint i; const uint size = (uint)entities.size(); for ( i = 0 ; i < size ; ++i) msgout.serial(entities[i].first, entities[i].second); // send it to requester sendMessageViaMirror(serviceId, msgout); } /****************************************************************\ ponctual vision request \****************************************************************/ void cbR2ForceVisionReset( NLNET::CMessage& msgin, const std::string &serviceName, NLNET::TServiceId serviceId ) { CEntityId eid; msgin.serial(eid); TDataSetRow entityIndex = TheDataset.getDataSetRow( eid ); BOMB_IF(!entityIndex.isValid() , "Try to reset the vision of a invalid player "+eid.toString(), return); pCGPMS->RingVisionUniverse->forceResetVision(entityIndex); } //---------------------------- // CbArray //---------------------------- TUnifiedCallbackItem CbGPMSArray[]= { // Callbacks for all service use GPMS //{ "ADD_ENTITY", cbAddEntity }, // create a single entity //{ "ADD_ENTITIES", cbAddEntities }, // create a set of entities //{ "ADD_IA_OBJECT", cbAddIAObject }, // create an object only visible from ia agents //{ "REPLACE_ENTITY", cbReplaceEntity}, // replace an entity by another entity //{ "REMOVE_ENTITY", cbRemoveEntity }, // remove a single entity //{ "REMOVE_ENTITIES", cbRemoveEntities }, // removes a set of entities /*?DEAD?*/ { "BAG", cbBag }, // updates content of an entity (bag only ?) /*?DEAD?*/ { "LOAD_CONTINENT", cbLoadContinent }, // load a continent /*?DEAD?*/ { "REMOVE_CONTINENT", cbRemoveContinent }, // remove a continent { "CREATE_INDOOR_UNIT", cbCreateIndoorUnit }, // create an indoor unit, for latter teleport /*?DEAD?*/ { "CREATE_BUILDING", cbCreateBuilding }, // create a dynamic outdoor building /*?DEAD?*/ { "CREATE_OBSTACLE", cbCreateObstacle }, // create a dynamic obstacle from a pacs_prim file /*?DEAD?*/ { "REMOVE_OBSTACLE", cbRemoveObstacle }, // remove a dynamic obstacle /*?DEAD?*/ { "SET_OBSTACLE", cbSetObstacle }, // set dynamic obstacle state /*?DEAD?*/ { "TRIGGER_SUBSCRIBE", cbTriggerSubscribe }, /*?DEAD?*/ { "TRIGGER_UNSUBSCRIBE", cbTriggerUnsubscribe }, //{ "UPDATE_ENTITY_POS", cbUpdateEntityPosition}, // update a single entity position //{ "UPDATE_ENTITIES_POSITIONS", cbUpdateEntitiesPositions}, // update a set of entities positions //{ "UPDATE_ENTITIES_POS", cbUpdateEntitiesPositionsUsingSize }, // update a set of entities positions { "ENTITY_TELEPORTATION", cbEntityTeleportation}, // teleport a single entity (if no position, remove from cell map) /*?DEAD?*/ { "ATTACH", cbAttach }, // attach an entity (child) to an another (father) using direct local position /*?DEAD?*/ { "DETACH", cbDetach }, // detach an entity of its father { "ACQUIRE_CONTROL", cbAcquireControl }, // entity acquire control of another entity { "LEAVE_CONTROL", cbLeaveControl }, // entity leave control of another entity /*?DEAD?*/ { "ACTIV_SELF", cbActivateSelf }, /*?DEAD?*/ { "DESACTIV_SELF", cbDesactivateSelf }, // The following removed by Sadge because the entity has been removed from the mirror by the time the message arrives, // making it redundant // / *?DEAD?* / { "DISABLE_VISION_PROC", cbDisableVisionProcessing }, // ask for player vision not to be updated any longer /*?DEAD?*/ { "ENTITY_POS", cbEntityPosition }, // ask for position of an entity /*?DEAD?*/ { "ASK_VISION_ARROUND_ENTITY", cbEntitiesArroundEntity }, // ask for vision update around an entity /*?DEAD?*/ { "UNASK_VISION_ARROUND_ENTITY",cbEndEntitiesArroundEntity }, // remove vision update around an entity /*?DEAD?*/ { "VISION_REQUEST", cbVisionRequest }, { "SET_PLAYER_FLAGS", cbSetPlayerFlags }, // set flags for player (limit speed, etc) { "R2_VISION_REFRESH", cbR2ForceVisionReset }, // force the update of the vision (because some message must have been discared in Ring (in edition mode the network is not listen) }; //------------------------------------------------------------------------- // singleton initialisation and release void CMessages::init() { // setup the callback array CUnifiedNetwork::getInstance()->addCallbackArray( CbGPMSArray, sizeof(CbGPMSArray)/sizeof(CbGPMSArray[0]) ); } void CMessages::release() { }