556 lines
24 KiB
C++
556 lines
24 KiB
C++
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
|
// 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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
#include "stdpch.h"
|
|
#include "entity_container.h"
|
|
#include "frontend_service.h"
|
|
#include <vector>
|
|
|
|
using namespace std;
|
|
using namespace NLMISC;
|
|
using namespace CLFECOMMON;
|
|
|
|
const TDataSetIndex LAST_VISION_CHANGE = LAST_CHANGED;
|
|
|
|
|
|
CMirroredDataSet *CEntity::DataSet = NULL;
|
|
|
|
CEntityContainer *CEntityContainer::I = NULL;
|
|
|
|
TPropertyIndex CEntityContainer::_VisualPropIndexToDataSet[CLFECOMMON::NB_VISUAL_PROPERTIES];
|
|
|
|
// Property indices that are not in game_share/ryzom_mirror_properties.h
|
|
TPropertyIndex DSPropertyTickPos;
|
|
TPropertyIndex DSPropertyLocalX;
|
|
TPropertyIndex DSPropertyLocalY;
|
|
TPropertyIndex DSPropertyLocalZ;
|
|
//TPropertyIndex DSPropertyStunned;
|
|
TPropertyIndex DSFirstPropertyAvailableImpulseBitSize;
|
|
|
|
|
|
// Use the callbacks in game_share/ryzom_mirror_properties.cpp
|
|
extern std::string BehaviourToStringCb( void *value );
|
|
extern std::string ModeToStringCb( void *value );
|
|
|
|
|
|
/*
|
|
* Constructor
|
|
*/
|
|
CEntityContainer::CEntityContainer() : EntityToClient(NULL), _DataSet(NULL)
|
|
{
|
|
nlassert( !I );
|
|
I = this;
|
|
}
|
|
|
|
|
|
/*
|
|
* Initialisation 2
|
|
*/
|
|
void cbMirrorIsReady( CMirror *mirror )
|
|
{
|
|
CFrontEndService::instance()->postInit();
|
|
}
|
|
|
|
|
|
/*
|
|
* Fast check if an addition has been notified
|
|
*/
|
|
bool cbAdditionNotifiedCallback( const TDataSetRow& entityIndex )
|
|
{
|
|
return CEntityContainer::I->getEntity(entityIndex)->TickPosition.isReadable();
|
|
}
|
|
|
|
|
|
void cbNotificationCallback()
|
|
{
|
|
CEntityContainer::I->updateMirror();
|
|
}
|
|
|
|
|
|
/*
|
|
* Initialisation
|
|
*/
|
|
void CEntityContainer::init( CClientIdLookup *cl, void (*cbUpdate)(), void (*cbSync)() )
|
|
{
|
|
EntityToClient = cl;
|
|
|
|
// Init the mirror system
|
|
vector<string> datasetNames;
|
|
datasetNames.push_back( "fe_temp" );
|
|
_Mirror.init( datasetNames, cbMirrorIsReady, cbUpdate, cbSync );
|
|
}
|
|
|
|
|
|
/*
|
|
* Initialisation of the properties
|
|
*/
|
|
void CEntityContainer::initMirror()
|
|
{
|
|
// Declare the property needed as readOnly, not notifying the changes
|
|
_DataSet = &(_Mirror.getDataSet("fe_temp"));
|
|
_DataSet->declareProperty( "X", PSOReadOnly | PSONotifyChanges ); // for mileage calculation
|
|
_DataSet->declareProperty( "Y", PSOReadOnly | PSONotifyChanges ); // for mileage calculation
|
|
_DataSet->declareProperty( "Z", PSOReadOnly );
|
|
_DataSet->declareProperty( "Theta", PSOReadOnly );
|
|
_DataSet->declareProperty( "Sheet", PSOReadOnly );
|
|
_DataSet->declareProperty( "NPCAlias", PSOReadOnly );
|
|
_DataSet->declareProperty( "Behaviour", PSOReadOnly );
|
|
_DataSet->declareProperty( "NameIndex", PSOReadOnly );
|
|
_DataSet->declareProperty( "Target", PSOReadOnly );
|
|
_DataSet->declareProperty( "Mode", PSOReadOnly );
|
|
_DataSet->declareProperty( "VisualPropertyA", PSOReadOnly );
|
|
_DataSet->declareProperty( "VisualPropertyB", PSOReadOnly );
|
|
_DataSet->declareProperty( "VisualPropertyC", PSOReadOnly );
|
|
_DataSet->declareProperty( "EntityMounted", PSOReadOnly );
|
|
_DataSet->declareProperty( "RiderEntity", PSOReadOnly );
|
|
_DataSet->declareProperty( "ContextualProperty", PSOReadOnly );
|
|
_DataSet->declareProperty( "TickPos", PSOReadOnly );
|
|
_DataSet->declareProperty( "LocalX", PSOReadOnly );
|
|
_DataSet->declareProperty( "LocalY", PSOReadOnly );
|
|
_DataSet->declareProperty( "LocalZ", PSOReadOnly );
|
|
_DataSet->declareProperty( "Bars", PSOReadOnly );
|
|
//_DataSet->declareProperty( "Stunned", PSOReadOnly ); // to block or not incoming messages from the client
|
|
_DataSet->declareProperty( "AvailableImpulseBitSize", PSOWriteOnly ); // to avoid other FS to receive changes
|
|
_DataSet->declareProperty( "TargetList", PSOReadOnly );
|
|
_DataSet->declareProperty( "VisualFX", PSOReadOnly );
|
|
_DataSet->declareProperty( "GuildSymbol", PSOReadOnly );
|
|
_DataSet->declareProperty( "GuildNameId", PSOReadOnly );
|
|
_DataSet->declareProperty( "EventFactionId", PSOReadOnly );
|
|
_DataSet->declareProperty( "PvpMode", PSOReadOnly );
|
|
_DataSet->declareProperty( "PvpClan", PSOReadOnly );
|
|
_DataSet->declareProperty( "OwnerPeople", PSOReadOnly );
|
|
_DataSet->declareProperty( "OutpostInfos", PSOReadOnly );
|
|
|
|
|
|
// All will be ready when _Mirror.mirrorIsReady()
|
|
// and _Mirror.propIsAllocated("_EId_fe_temp")
|
|
// and _Mirror.propIsAllocated(all the properties above)
|
|
|
|
// Set the dataset
|
|
CEntity::DataSet = _DataSet;
|
|
|
|
// Map the property indices
|
|
//_VisualPropIndexToDataSet.resize( _DataSet->nbProperties() );
|
|
DSPropertyPOSX = mapVisualPropIndex( "X", PROPERTY_POSX );
|
|
DSPropertyPOSY = mapVisualPropIndex( "Y", PROPERTY_POSY );
|
|
DSPropertyPOSZ = mapVisualPropIndex( "Z", PROPERTY_POSZ );
|
|
DSPropertyORIENTATION = mapVisualPropIndex( "Theta", PROPERTY_ORIENTATION );
|
|
DSPropertySHEET = mapVisualPropIndex( "Sheet", PROPERTY_SHEET );
|
|
DSPropertyBEHAVIOUR = mapVisualPropIndex( "Behaviour", PROPERTY_BEHAVIOUR );
|
|
DSPropertyNAME_STRING_ID = mapVisualPropIndex( "NameIndex", PROPERTY_NAME_STRING_ID );
|
|
DSPropertyTARGET_ID = mapVisualPropIndex( "Target", PROPERTY_TARGET_ID );
|
|
DSPropertyMODE = mapVisualPropIndex( "Mode", PROPERTY_MODE );
|
|
DSPropertyVPA = mapVisualPropIndex( "VisualPropertyA", PROPERTY_VPA );
|
|
DSPropertyVPB = mapVisualPropIndex( "VisualPropertyB", PROPERTY_VPB );
|
|
DSPropertyVPC = mapVisualPropIndex( "VisualPropertyC", PROPERTY_VPC );
|
|
DSPropertyENTITY_MOUNTED_ID = mapVisualPropIndex( "EntityMounted", PROPERTY_ENTITY_MOUNTED_ID );
|
|
DSPropertyRIDER_ENTITY_ID = mapVisualPropIndex( "RiderEntity", PROPERTY_RIDER_ENTITY_ID );
|
|
DSPropertyCONTEXTUAL = mapVisualPropIndex( "ContextualProperty", PROPERTY_CONTEXTUAL );
|
|
DSPropertyBARS = mapVisualPropIndex( "Bars", PROPERTY_BARS );
|
|
DSPropertyTickPos = getPropertyIndex( "TickPos" );
|
|
DSPropertyLocalX = getPropertyIndex( "LocalX" );
|
|
DSPropertyLocalY = getPropertyIndex( "LocalY" );
|
|
DSPropertyLocalZ = getPropertyIndex( "LocalZ" );
|
|
//DSPropertyStunned = getPropertyIndex( "Stunned" );
|
|
DSFirstPropertyAvailableImpulseBitSize = getPropertyIndex( "AvailableImpulseBitSize" );
|
|
DSPropertyTARGET_LIST = mapVisualPropIndex( "TargetList", PROPERTY_TARGET_LIST );
|
|
DSPropertyVISUAL_FX = mapVisualPropIndex( "VisualFX", PROPERTY_VISUAL_FX );
|
|
DSPropertyGUILD_SYMBOL = mapVisualPropIndex( "GuildSymbol", PROPERTY_GUILD_SYMBOL );
|
|
DSPropertyGUILD_NAME_ID = mapVisualPropIndex( "GuildNameId", PROPERTY_GUILD_NAME_ID );
|
|
DSPropertyEVENT_FACTION_ID = mapVisualPropIndex( "EventFactionId", PROPERTY_EVENT_FACTION_ID );
|
|
DSPropertyPVP_MODE = mapVisualPropIndex( "PvpMode", PROPERTY_PVP_MODE );
|
|
DSPropertyPVP_CLAN = mapVisualPropIndex( "PvpClan", PROPERTY_PVP_CLAN );
|
|
DSPropertyOWNER_PEOPLE = mapVisualPropIndex( "OwnerPeople", PROPERTY_OWNER_PEOPLE );
|
|
DSPropertyOUTPOST_INFOS = mapVisualPropIndex( "OutpostInfos", PROPERTY_OUTPOST_INFOS );
|
|
DSPropertyNPC_ALIAS = getPropertyIndex( "NPCAlias" );
|
|
|
|
// Resize the entity container
|
|
_Entities.resize( _DataSet->maxNbRows() );
|
|
EntityToClient->init( _DataSet->maxNbRows() );
|
|
|
|
// Set the display callbacks (because not using initRyzomVisualPropertyIndices())
|
|
_DataSet->setDisplayCallback( DSPropertyBEHAVIOUR, BehaviourToStringCb );
|
|
_DataSet->setDisplayCallback( DSPropertyMODE, ModeToStringCb );
|
|
|
|
_Mirror.setNotificationCallback( cbNotificationCallback );
|
|
}
|
|
|
|
|
|
/*
|
|
* Set the mapping and return the dataset property index
|
|
*/
|
|
TPropertyIndex CEntityContainer::mapVisualPropIndex( const std::string& propName, TPropIndex vPropIndex )
|
|
{
|
|
nlassert ( vPropIndex < CLFECOMMON::NB_VISUAL_PROPERTIES );
|
|
_VisualPropIndexToDataSet[vPropIndex] = _DataSet->getPropertyIndex( propName );
|
|
if ( _VisualPropIndexToDataSet[vPropIndex] == INVALID_PROPERTY_INDEX )
|
|
nlerror( "ERROR: Property %s not found in dataset", propName.c_str() );
|
|
return _VisualPropIndexToDataSet[vPropIndex];
|
|
}
|
|
|
|
|
|
/*
|
|
* Return the property index at startup
|
|
*/
|
|
TPropertyIndex CEntityContainer::getPropertyIndex( const std::string& propName ) const
|
|
{
|
|
TPropertyIndex propertyIndex = _DataSet->getPropertyIndex( propName );
|
|
if ( propertyIndex == INVALID_PROPERTY_INDEX )
|
|
nlerror( "ERROR: Property %s not found in dataset", propName.c_str() );
|
|
return propertyIndex;
|
|
}
|
|
|
|
|
|
/*uint32 NbcX, NbcY;
|
|
NLMISC_VARIABLE( uint32, NbcX, "" );
|
|
NLMISC_VARIABLE( uint32, NbcY, "" );
|
|
CValueSmootherTemplate<uint32> Nbcx(20);
|
|
CValueSmootherTemplate<uint32> Nbcy(20);
|
|
|
|
NLMISC_DYNVARIABLE( uint32, NbcX, "" )
|
|
{
|
|
if ( get )
|
|
{
|
|
*pointer = Nbcx.getSmoothValue();
|
|
}
|
|
}
|
|
|
|
NLMISC_DYNVARIABLE( uint32, NbcY, "" )
|
|
{
|
|
if ( get )
|
|
{
|
|
*pointer = Nbcy.getSmoothValue();
|
|
}
|
|
}*/
|
|
|
|
|
|
/*
|
|
* Update (called every cycle by the mirror system)
|
|
*/
|
|
void CEntityContainer::updateMirror()
|
|
{
|
|
//nldebug( "%u: updateMirror", CTickEventHandler::getGameCycle() );
|
|
H_AUTO(UpdateEntities)
|
|
|
|
// Process added entities
|
|
_DataSet->beginAddedEntities();
|
|
TDataSetRow entityIndex = _DataSet->getNextAddedEntity();
|
|
while ( entityIndex != LAST_CHANGED )
|
|
{
|
|
// The front-end is not aware of the entity index. Use the CEntityId to map it.
|
|
// This is done here because the vision provider needs it when scanning the changed properties
|
|
// of a client to send the discrete ones to himself. Note: MapSidToUid for this client
|
|
// must be called before (receiving CL_ID from the EGS)
|
|
const CEntityId& entityId = _DataSet->getEntityId( entityIndex );
|
|
TClientId clientid = EntityToClient->getClientId( entityId );
|
|
if ( clientid != INVALID_CLIENT )
|
|
{
|
|
CClientHost *clienthost = CFrontEndService::instance()->sendSub()->clientIdCont()[clientid];
|
|
//#ifdef NL_DEBUG
|
|
if ( clienthost )
|
|
{
|
|
//#endif
|
|
clienthost->setEntityIndex( entityIndex );
|
|
EntityToClient->addEntityIndex( entityIndex, clientid );
|
|
nlinfo( "%u: Setting mirror row to C%hu uid %u E%u", CTickEventHandler::getGameCycle(), clientid, clienthost->Uid, entityIndex.getIndex() );
|
|
CFrontEndService::instance()->receiveSub()->ConnectionStatLog->displayNL( "Setting mirror row to C%hu uid %u E%u", clientid, clienthost->Uid, entityIndex.getIndex() );
|
|
//nldebug( "dataset %s, maxNbRows %d", _DataSet->name().c_str(), _DataSet->maxNbRows() );
|
|
//#ifdef NL_DEBUG
|
|
}
|
|
else
|
|
{
|
|
// Should not occur
|
|
nlwarning( "No client corresponding to C%hu E%u", clientid, entityIndex.getIndex() );
|
|
}
|
|
//#endif
|
|
}
|
|
|
|
// Init entity structure
|
|
_Entities[entityIndex.getIndex()].initFields( entityIndex, entityId );
|
|
|
|
/*
|
|
// TEMP workaround for vision with entityIds (not entityIndices)
|
|
pair<TMapOfEarlyVisionAssociations::iterator, TMapOfEarlyVisionAssociations::iterator> range = EarlyVisionIns.equal_range( entityId );
|
|
if ( range.first != EarlyVisionIns.end() )
|
|
{
|
|
TMapOfEarlyVisionAssociations::iterator ite;
|
|
for ( ite=range.first; ite!=range.second; ++ite )
|
|
{
|
|
// Reinsert in vision now we know the entityIndex (works because VisionIn not cleared before next processVision)
|
|
nldebug( "Reinserting %s into vision of E%u", entityId.toString().c_str(), (*ite).second.first.getIndex() );
|
|
_Entities[(*ite).second.first.getIndex()].insertIntoVisionIn( (*ite).second.first, entityId, (*ite).second.second.first, (*ite).second.second.second );
|
|
}
|
|
EarlyVisionIns.erase( range.first, range.second );
|
|
}
|
|
*/
|
|
|
|
// Get next
|
|
entityIndex = _DataSet->getNextAddedEntity();
|
|
}
|
|
_DataSet->endAddedEntities();
|
|
|
|
// Process removed entities
|
|
_DataSet->beginRemovedEntities();
|
|
CEntityId *entityId;
|
|
entityIndex = _DataSet->getNextRemovedEntity( &entityId );
|
|
while ( entityIndex != LAST_CHANGED )
|
|
{
|
|
// Check if the entity is a client on this FE (unspawning)
|
|
TClientId clientid = EntityToClient->getClientId( entityIndex );
|
|
if ( clientid != INVALID_CLIENT )
|
|
{
|
|
// Unset the entity index
|
|
LOG_VISION( "FEVIS:%u: Removing entity index %u for client %hu (%s)", CTickEventHandler::getGameCycle(), entityIndex.getIndex(), clientid, entityId->toString().c_str() );
|
|
EntityToClient->removeEntityIndex( entityIndex );
|
|
CClientHost *clienthost = CFrontEndService::instance()->sendSub()->clientIdCont()[clientid];
|
|
if ( clienthost )
|
|
{
|
|
clienthost->setEntityIndex( TEntityIndex() );
|
|
|
|
// Reset the vision of the client
|
|
CFrontEndService::instance()->PrioSub.VisionProvider.resetVision( clienthost );
|
|
}
|
|
|
|
// Set properties to uninitialized state
|
|
_Entities[entityIndex.getIndex()].invalidateProperties();
|
|
}
|
|
entityIndex = _DataSet->getNextRemovedEntity( &entityId );
|
|
}
|
|
_DataSet->endRemovedEntities();
|
|
|
|
//uint nbx, nby = 0;
|
|
//H_BEFORE(ScanPosXY);
|
|
// Compute mileages with X and Y TODO: mileage computation may be useless now
|
|
//H_BEFORE(beginChangeX)
|
|
_DataSet->beginChangedValuesForProp( DSPropertyPOSX );
|
|
//H_AFTER(beginChangeX)
|
|
while( (entityIndex = _DataSet->getNextChangedValueForProp()) != LAST_CHANGED )
|
|
{
|
|
//H_BEFORE(InsideWhileX)
|
|
_Entities[entityIndex.getIndex()].updateMileageX( entityIndex );
|
|
//++nbx;
|
|
//H_AFTER(InsideWhileX)
|
|
}
|
|
//H_BEFORE(endChangeX)
|
|
_DataSet->endChangedValuesForProp();
|
|
//H_AFTER(endChangeX)
|
|
//H_BEFORE(beginChangeY)
|
|
_DataSet->beginChangedValuesForProp( DSPropertyPOSY );
|
|
//H_AFTER(beginChangeY)
|
|
while( (entityIndex = _DataSet->getNextChangedValueForProp()) != LAST_CHANGED )
|
|
{
|
|
//H_BEFORE(InsideWhileY)
|
|
_Entities[entityIndex.getIndex()].updateMileageY( entityIndex );
|
|
//++nby;
|
|
//H_AFTER(InsideWhileY)
|
|
}
|
|
//H_BEFORE(endChangeY)
|
|
_DataSet->endChangedValuesForProp();
|
|
//H_AFTER(endChangeY)
|
|
//H_AFTER(ScanPosXY);
|
|
//Nbcx.addValue( nbx );
|
|
//Nbcy.addValue( nby );
|
|
}
|
|
|
|
|
|
/*
|
|
* Insert entityId, slot into VisionIn
|
|
*/
|
|
//void CEntity::insertIntoVisionIn( TEntityIndex iviewer, const NLMISC::CEntityId& entityId, CLFECOMMON::TCLEntityId slot, bool replace )
|
|
void CEntity::insertIntoVisionIn( const TEntityIndex& iviewer, const TDataSetRow& entityIndex, CLFECOMMON::TCLEntityId slot, bool replace )
|
|
{
|
|
// Find the index of the id
|
|
//TEntityIndex iviewed = TheEntityContainer->entityIdToIndex( entityId );
|
|
const TEntityIndex& iviewed = entityIndex;
|
|
|
|
if ( !iviewed.isValid() )
|
|
{
|
|
//nldebug( "New viewed entity id %s not in mirror yet, storing for viewer E%u", entityId.toString().c_str(), iviewer.getIndex() );
|
|
nlwarning( "Received invalid entity index for vision of E%u", iviewed.getIndex() );
|
|
// TEMP Workaround (until GPMS vision uses entityindices)
|
|
// removed, entityIndex will always be valid (according to Olivier)
|
|
//CEntityContainer::I->EarlyVisionIns.insert( std::make_pair( entityId, std::make_pair( iviewer, std::make_pair( slot, replace ) ) ) );
|
|
return;
|
|
}
|
|
//nlinfo( "* Add E%u to VisionIn", iviewed );
|
|
VisionIn.insert( std::make_pair( iviewed, std::make_pair( slot, replace ) ) );
|
|
}
|
|
|
|
|
|
// Property value
|
|
#define PV(propIndex) properties[propIndex]
|
|
|
|
#define dispDist(s,t) s += string(" \t - ") + ((dist<t) ? string("IN") : string("OUT")) + string(" RADIUS ") + toString( "(%g m)", t/1000.0f )
|
|
|
|
|
|
/*
|
|
*
|
|
*/
|
|
void CEntity::displayProperties( const TEntityIndex& entityIndex, NLMISC::CLog *log, TClientId optClientId, CLFECOMMON::TCLEntityId optSlot ) const
|
|
{
|
|
CMirrorPropValueRO<float> mmm( TheDataset, entityIndex, DSPropertyORIENTATION );
|
|
|
|
uint64 properties[NB_VISUAL_PROPERTIES];
|
|
fillVisualPropertiesFromMirror( properties, entityIndex );
|
|
|
|
string lsTheta, lsSheet, lsBehav, lsName, lsTarget, lsMode, lsVPA, lsVPB, lsVPC, lsMount, lsRider, lsContextual, lsBars, lsEventFactionId, lsPvpMode, lsPvpClan, lsOwnerPeople, lsOutpostInfos;
|
|
string sdist;
|
|
if ( (optClientId != INVALID_CLIENT) && (optSlot != INVALID_SLOT) )
|
|
{
|
|
TPairState& pairState = CFrontEndService::instance()->PrioSub.VisionArray.getPairState( optClientId, optSlot );
|
|
TCoord dist = pairState.DistanceCE;
|
|
sdist = toString( " Dist %g m", ((float)dist)/1000.0f );
|
|
|
|
CHistory *history = CFrontEndService::instance()->history();
|
|
bool histohasvalue;
|
|
TPropertiesValue lastsent_value = history->getPropertyEntry( optClientId, optSlot, PROPERTY_ORIENTATION, histohasvalue ).LastSent;
|
|
lsTheta = histohasvalue ? toString( "%.2f", *(float*)&lastsent_value ) : "NOT SENT YET";
|
|
dispDist(lsTheta,THRESHOLD_ORIENTATION);
|
|
lastsent_value = history->getPropertyEntry( optClientId, optSlot, PROPERTY_SHEET, histohasvalue ).LastSent;
|
|
lsSheet = histohasvalue ? toString( "%u", (uint32)lastsent_value ) : "NOT SENT YET";
|
|
dispDist(lsSheet,THRESHOLD_SHEET);
|
|
lastsent_value = history->getPropertyEntry( optClientId, optSlot, PROPERTY_BEHAVIOUR, histohasvalue ).LastSent;
|
|
lsBehav = histohasvalue ? toString( "%"NL_I64"u", (uint64)lastsent_value ) : "NOT SENT YET";
|
|
dispDist(lsBehav,THRESHOLD_BEHAVIOUR);
|
|
lastsent_value = history->getPropertyEntry( optClientId, optSlot, PROPERTY_NAME_STRING_ID, histohasvalue ).LastSent;
|
|
lsName = histohasvalue ? toString( "%u", (uint32)lastsent_value ) : "NOT SENT YET";
|
|
dispDist(lsName,THRESHOLD_NAME_STRING_ID);
|
|
lastsent_value = history->getPropertyEntry( optClientId, optSlot, PROPERTY_TARGET_ID, histohasvalue ).LastSent;
|
|
lsTarget = histohasvalue ? toString( "%u", (uint32)lastsent_value ) : "NOT SENT YET";
|
|
dispDist(lsTarget,THRESHOLD_TARGET_ID);
|
|
lastsent_value = history->getPropertyEntry( optClientId, optSlot, PROPERTY_MODE, histohasvalue ).LastSent;
|
|
lsMode = histohasvalue ? toString( "%hu", (uint32)lastsent_value ) : "NOT SENT YET";
|
|
dispDist(lsMode,THRESHOLD_MODE);
|
|
lastsent_value = history->getPropertyEntry( optClientId, optSlot, PROPERTY_VPA, histohasvalue ).LastSent;
|
|
lsVPA = histohasvalue ? toString( "%"NL_I64"u", lastsent_value ) : "NOT SENT YET";
|
|
dispDist(lsVPA,THRESHOLD_VPA);
|
|
lastsent_value = history->getPropertyEntry( optClientId, optSlot, PROPERTY_VPB, histohasvalue ).LastSent;
|
|
lsVPB = histohasvalue ? toString( "%"NL_I64"u", lastsent_value ) : "NOT SENT YET";
|
|
dispDist(lsVPB,THRESHOLD_VPB);
|
|
lastsent_value = history->getPropertyEntry( optClientId, optSlot, PROPERTY_VPC, histohasvalue ).LastSent;
|
|
lsVPC = histohasvalue ? toString( "%"NL_I64"u", lastsent_value ) : "NOT SENT YET";
|
|
dispDist(lsVPC,THRESHOLD_VPC);
|
|
lastsent_value = history->getPropertyEntry( optClientId, optSlot, PROPERTY_ENTITY_MOUNTED_ID, histohasvalue ).LastSent;
|
|
lsMount = histohasvalue ? toString( "%d", (uint32)lastsent_value ) : "NOT SENT YET";
|
|
dispDist(lsMount,THRESHOLD_ENTITY_MOUNTED_ID);
|
|
lastsent_value = history->getPropertyEntry( optClientId, optSlot, PROPERTY_RIDER_ENTITY_ID, histohasvalue ).LastSent;
|
|
lsRider = histohasvalue ? toString( "%d", (uint32)lastsent_value ) : "NOT SENT YET";
|
|
dispDist(lsRider,THRESHOLD_RIDER_ENTITY_ID);
|
|
lastsent_value = history->getPropertyEntry( optClientId, optSlot, PROPERTY_CONTEXTUAL, histohasvalue ).LastSent;
|
|
lsContextual = histohasvalue ? toString( "%u", (uint32)lastsent_value ) : "NOT SENT YET";
|
|
dispDist(lsContextual,THRESHOLD_CONTEXTUAL);
|
|
lsBars = histohasvalue ? toString( "%u", (uint32)lastsent_value ) : "NOT SENT YET";
|
|
dispDist(lsBars,THRESHOLD_BARS);
|
|
lastsent_value = history->getPropertyEntry( optClientId, optSlot, PROPERTY_EVENT_FACTION_ID, histohasvalue ).LastSent;
|
|
lsEventFactionId = histohasvalue ? toString( "%u", (uint32)lastsent_value ) : "NOT SENT YET";
|
|
dispDist(lsEventFactionId,THRESHOLD_EVENT_FACTION_ID);
|
|
lastsent_value = history->getPropertyEntry( optClientId, optSlot, PROPERTY_PVP_MODE, histohasvalue ).LastSent;
|
|
lsEventFactionId = histohasvalue ? toString( "%u", (uint32)lastsent_value ) : "NOT SENT YET";
|
|
dispDist(lsPvpMode,THRESHOLD_PVP_MODE);
|
|
lastsent_value = history->getPropertyEntry( optClientId, optSlot, PROPERTY_PVP_CLAN, histohasvalue ).LastSent;
|
|
lsPvpClan = histohasvalue ? toString( "%u", (uint32)lastsent_value ) : "NOT SENT YET";
|
|
dispDist(lsPvpClan,THRESHOLD_PVP_CLAN);
|
|
lastsent_value = history->getPropertyEntry( optClientId, optSlot, PROPERTY_OWNER_PEOPLE, histohasvalue ).LastSent;
|
|
lsOwnerPeople = histohasvalue ? toString( "%u", (uint32)lastsent_value ) : "NOT SENT YET";
|
|
dispDist(lsOwnerPeople,PROPERTY_OWNER_PEOPLE);
|
|
lastsent_value = history->getPropertyEntry( optClientId, optSlot, PROPERTY_OUTPOST_INFOS, histohasvalue ).LastSent;
|
|
lsOutpostInfos = histohasvalue ? toString( "%u", (uint32)lastsent_value ) : "NOT SENT YET";
|
|
dispDist(lsOutpostInfos,PROPERTY_OUTPOST_INFOS);
|
|
}
|
|
|
|
CMirrorPropValue<TYPE_SHEET> sheetValue( TheDataset, entityIndex, DSPropertySHEET );
|
|
TGameCycle sheetTimestamp = sheetValue.getTimestamp(), deltaTSheet = CTickEventHandler::getGameCycle()-sheetTimestamp;
|
|
string sheetSet = (sheetTimestamp!=0) ? toString( "set %u ticks (%.3f hours) ago", deltaTSheet, ((float)deltaTSheet)/36000.0f ) : "not set yet";
|
|
|
|
log->displayNL( "| E%u: TickPos %u Mileage %u %s", entityIndex.getIndex(), TickPosition(), Mileage, sdist.c_str() );
|
|
log->displayNL( "| Sheet %u \t %s (sheet %s)", (uint32)PV(PROPERTY_SHEET), lsSheet.c_str(), sheetSet.c_str() );
|
|
log->displayNL( "| AbsPos: %d %d %d", (sint32)PV(PROPERTY_POSX), (sint32)PV(PROPERTY_POSY), (sint32)PV(PROPERTY_POSZ) );;
|
|
log->displayNL( "| Theta %.2f \t %s", *(float*)(&PV(PROPERTY_ORIENTATION)), lsTheta.c_str() );
|
|
log->displayNL( "| Behav %u \t %s", (uint32)PV(PROPERTY_BEHAVIOUR), lsBehav.c_str() );
|
|
log->displayNL( "| Name %u \t %s", (uint32)PV(PROPERTY_NAME_STRING_ID), lsName.c_str() );
|
|
TDataSetIndex target = (TDataSetIndex)PV(PROPERTY_TARGET_ID), mount = (TDataSetIndex)PV(PROPERTY_ENTITY_MOUNTED_ID), rider = (TDataSetIndex)PV(PROPERTY_RIDER_ENTITY_ID);
|
|
log->displayNL( "| Target %d \t %s", target, lsTarget.c_str() );
|
|
log->displayNL( "| Mode %hu \t %s", (uint8)PV(PROPERTY_MODE), lsMode.c_str() );
|
|
log->displayNL( "| VPA %"NL_I64"u \t %s", PV(PROPERTY_VPA), lsVPA.c_str() );
|
|
log->displayNL( "| VPB %"NL_I64"u \t %s", PV(PROPERTY_VPB), lsVPB.c_str() );
|
|
log->displayNL( "| VPC %"NL_I64"u \t %s", PV(PROPERTY_VPC), lsVPC.c_str() );
|
|
log->displayNL( "| Mount %d \t %s", mount, lsMount.c_str() );
|
|
log->displayNL( "| Rider %d \t \t %s", rider, lsRider.c_str() );
|
|
log->displayNL( "| Contextual %hu \t %s", (uint16)PV(PROPERTY_CONTEXTUAL), lsContextual.c_str() );
|
|
log->displayNL( "| EventFactionId %u \t %s", (uint32)PV(PROPERTY_EVENT_FACTION_ID), lsEventFactionId.c_str() );
|
|
log->displayNL( "| PvpMode %u \t %s", (uint32)PV(PROPERTY_PVP_MODE), lsPvpMode.c_str() );
|
|
log->displayNL( "| PvpClan %u \t %s", (uint32)PV(PROPERTY_PVP_CLAN), lsPvpClan.c_str() );
|
|
log->displayNL( "| OwnerPeople %u \t %s", (uint32)PV(PROPERTY_OWNER_PEOPLE), lsOwnerPeople.c_str() );
|
|
log->displayNL( "| OutpostInfos %u \t %s", (uint32)PV(PROPERTY_OUTPOST_INFOS), lsOutpostInfos.c_str() );
|
|
}
|
|
|
|
|
|
#define FILL_PROP( name ) \
|
|
{ \
|
|
CMirrorPropValueRO<TYPE_##name> prop( TheDataset, entityIndex, DSProperty##name ); \
|
|
TYPE_##name *pt = (TYPE_##name*)&(properties[PROPERTY_##name]); \
|
|
*pt = prop(); \
|
|
}
|
|
|
|
void CEntity::fillVisualPropertiesFromMirror( uint64 properties[], const TEntityIndex& entityIndex )
|
|
{
|
|
for ( sint i=0; i!=NB_VISUAL_PROPERTIES; ++i )
|
|
properties[i] = 0;
|
|
|
|
FILL_PROP( POSX );
|
|
FILL_PROP( POSY );
|
|
FILL_PROP( POSZ );
|
|
FILL_PROP( ORIENTATION );
|
|
FILL_PROP( SHEET );
|
|
FILL_PROP( BEHAVIOUR );
|
|
FILL_PROP( NAME_STRING_ID );
|
|
FILL_PROP( TARGET_ID );
|
|
FILL_PROP( MODE );
|
|
FILL_PROP( VPA );
|
|
FILL_PROP( VPB );
|
|
FILL_PROP( VPC );
|
|
FILL_PROP( ENTITY_MOUNTED_ID );
|
|
FILL_PROP( RIDER_ENTITY_ID );
|
|
FILL_PROP( CONTEXTUAL );
|
|
FILL_PROP( GUILD_SYMBOL );
|
|
FILL_PROP( GUILD_NAME_ID );
|
|
FILL_PROP( EVENT_FACTION_ID );
|
|
FILL_PROP( PVP_MODE );
|
|
FILL_PROP( PVP_CLAN );
|
|
}
|
|
|
|
|
|
/*
|
|
* Helper for positionIsInitialized()
|
|
*/
|
|
/*
|
|
bool CEntity::checkPositionInitialized( const TEntityIndex& entityIndex )
|
|
{
|
|
if ( ! ((X() == 0) && (Y() == 0)) ) // not local pos because can be 0 0
|
|
{
|
|
PropInitialized[PROPERTY_POSITION] = true;
|
|
#ifdef NL_DEBUG
|
|
nldebug( "%u: E%u: Position initialized to %d %d", CTickEventHandler::getGameCycle(), entityIndex.getIndex(), X(), Y() );
|
|
#endif
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
*/
|
|
|