Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
675 lines
16 KiB
C++
675 lines
16 KiB
C++
//===========================================================================//
|
|
// File: EntityManager.cpp //
|
|
//---------------------------------------------------------------------------//
|
|
// Date Who Modification //
|
|
// -------- --- ---------------------------------------------------------- //
|
|
// 11/29/94 JMA Initial coding. //
|
|
// 08/25/97 JMA Infrastructure changes //
|
|
// 08/25/97 ECH Infrastructure changes //
|
|
//---------------------------------------------------------------------------//
|
|
// Copyright (C) 1994, Virtual World Entertainment, Inc. //
|
|
// All Rights reserved worldwide //
|
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
|
//===========================================================================//
|
|
|
|
#include "AdeptHeaders.hpp"
|
|
|
|
#include "EntityManager.hpp"
|
|
#include "Application.hpp"
|
|
#include "Map.hpp"
|
|
#include "DropZone.hpp"
|
|
#include "Mission.hpp"
|
|
#include "Mover.hpp"
|
|
#include "CollisionGrid.hpp"
|
|
#include "Tile.hpp"
|
|
#include "DamageObject.hpp"
|
|
#include "Player.hpp"
|
|
|
|
|
|
//#############################################################################
|
|
//########################## EntityStockpile ############################
|
|
//#############################################################################
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
EntityStockpile::EntityStockpile():
|
|
Plug(DefaultData),
|
|
availableEntities(NULL)
|
|
{
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
EntityStockpile::~EntityStockpile()
|
|
{
|
|
availableEntities.DeletePlugs();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
EntityStockpile::TestInstance()
|
|
{
|
|
}
|
|
|
|
//#############################################################################
|
|
//########################### EntityManager #############################
|
|
//#############################################################################
|
|
|
|
EntityManager::ClassData*
|
|
EntityManager::DefaultData = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
EntityManager::InitializeClass()
|
|
{
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
EntityManagerClassID,
|
|
"Adept::EntityManager",
|
|
Plug::DefaultData
|
|
);
|
|
Register_Object(DefaultData);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
EntityManager::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
EntityManager::EntityManager(ClassData *data):
|
|
Plug(data),
|
|
armory(53, NULL, true),
|
|
deathRow(NULL),
|
|
nameSocket(NULL, true),
|
|
resourceIDSocket(2003, NULL, true),
|
|
postCollisionExecutors(NULL),
|
|
updateEntities(NULL),
|
|
tileBoundDamage(3000>>3)
|
|
{
|
|
Check_Pointer(this);
|
|
isExecutionSuspended = false;
|
|
|
|
playerReady = false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
EntityManager::~EntityManager()
|
|
{
|
|
//
|
|
//------------------
|
|
// Delete stockpiles
|
|
//------------------
|
|
//
|
|
armory.DeletePlugs();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void EntityManager::SetPlayerReady(Entity *entity)
|
|
{
|
|
playerReady = true;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
EntityManager::StoreInArmory(Entity *entity)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(entity);
|
|
const ResourceID &data_id = entity->GetDataListResourceID();
|
|
Verify(data_id != ResourceID::Null);
|
|
|
|
//
|
|
//-----------------------------------
|
|
// Verify that the entity is reusable
|
|
//-----------------------------------
|
|
//
|
|
Verify(entity->IsReusable());
|
|
Map::GetInstance()->RemoveChild(entity);
|
|
entity->BecomeUninteresting();
|
|
entity->owningConnection->RemoveReplicator(entity);
|
|
|
|
//
|
|
//--------------------------------------
|
|
// Get the stockpile for its resource ID
|
|
//--------------------------------------
|
|
//
|
|
EntityStockpile *stockpile;
|
|
if ((stockpile = armory.Find(data_id)) == NULL)
|
|
{
|
|
gos_PushCurrentHeap(g_Heap);
|
|
stockpile = new EntityStockpile;
|
|
gos_PopCurrentHeap();
|
|
Register_Object(stockpile);
|
|
armory.AddValue(stockpile, data_id);
|
|
}
|
|
Check_Object(stockpile);
|
|
|
|
//
|
|
//--------------------------------------------
|
|
// If it has already been entered, then return
|
|
//--------------------------------------------
|
|
//
|
|
Verify(!stockpile->availableEntities.IsPlugMember(entity));
|
|
stockpile->availableEntities.Add(entity);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Entity*
|
|
EntityManager::RequestFromArmory(const ResourceID &instance_resource_ID)
|
|
{
|
|
Check_Object(this);
|
|
|
|
//
|
|
//------------------------------------------------
|
|
// Get the stockpile for this entity, if it exists
|
|
//------------------------------------------------
|
|
//
|
|
EntityStockpile *stockpile;
|
|
|
|
if ((stockpile = armory.Find(instance_resource_ID)) == NULL)
|
|
return NULL;
|
|
Check_Object(stockpile);
|
|
if (stockpile->availableEntities.IsEmpty())
|
|
return NULL;
|
|
|
|
//
|
|
//-----------------------------------------
|
|
// Verify that an entity can be created now
|
|
//-----------------------------------------
|
|
//
|
|
Check_Object(Application::GetInstance());
|
|
Verify(!Application::GetInstance()->InPreCollisionPhase());
|
|
|
|
//
|
|
//-------------------------------------------
|
|
// Grab an entity from the available entities
|
|
//-------------------------------------------
|
|
//
|
|
Entity *entity;
|
|
ChainIteratorOf<Entity*> iterator(&stockpile->availableEntities);
|
|
entity = iterator.GetCurrent();
|
|
Check_Object(entity);
|
|
iterator.Remove();
|
|
|
|
//
|
|
//----------------------------------------------------------------
|
|
// Otherwise, grab the oldest in use, and update position in chain
|
|
//----------------------------------------------------------------
|
|
//
|
|
Verify(entity->GetDataListResourceID() == instance_resource_ID);
|
|
Verify(entity->IsReusable());
|
|
return entity;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
EntityManager::EntityCreated(Entity *entity)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(entity);
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
EntityManager::FryDeathRow()
|
|
{
|
|
Check_Object(this);
|
|
|
|
if (!deathRow.IsEmpty())
|
|
{
|
|
ChainIteratorOf<Entity*> iterator(&deathRow);
|
|
Entity *entity;
|
|
|
|
while ((entity = iterator.GetCurrent()) != NULL)
|
|
{
|
|
Check_Object(entity);
|
|
|
|
//
|
|
// If the entity is reusable,
|
|
// it needs to be entered into the armory
|
|
//
|
|
//This is armory stuff that is going to be rewritten
|
|
if (entity->IsReusable())
|
|
{
|
|
{
|
|
// LOGIC("Background Tasks::Fry Death Row::REMOVE");
|
|
iterator.Remove();
|
|
}
|
|
{
|
|
// LOGIC("Background Tasks::Fry Death Row::STORE");
|
|
StoreInArmory(entity);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
{
|
|
// LOGIC("Background Tasks::Fry Death Row::REMOVE");
|
|
iterator.Remove();
|
|
}
|
|
{
|
|
// LOGIC("Background Tasks::Fry Death Row::DELETE");
|
|
Unregister_Object(entity);
|
|
delete entity;
|
|
}
|
|
}
|
|
iterator.First();
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
EntityManager::PrefixParentToName(
|
|
const Stuff::MString& parent_name,
|
|
Entity *entity
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(entity);
|
|
|
|
MString new_name;
|
|
new_name = parent_name;
|
|
new_name += "::";
|
|
new_name += entity->instanceName;
|
|
|
|
#if defined(_ARMOR)
|
|
nameSocket.Remove(entity);
|
|
#endif
|
|
entity->instanceName = new_name;
|
|
#if defined(_ARMOR)
|
|
nameSocket.AddValue(entity, entity->instanceName);
|
|
#endif
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
DropZone*
|
|
EntityManager::GetDropZone(ObjectID zone_id)
|
|
{
|
|
Check_Object(this);
|
|
|
|
Entity *entity = NameTable::GetInstance()->FindData(zone_id);
|
|
if((entity) && (entity != (Entity *)-1))
|
|
{
|
|
Check_Object(entity);
|
|
Verify(entity->IsDerivedFrom(DropZone::DefaultData));
|
|
DropZone *zone;
|
|
zone = Cast_Object(DropZone *, entity);
|
|
|
|
return zone;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
EntityManager::AddPlayerVehicle(Mover *mover)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(mover);
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void
|
|
EntityManager::SetNetworkDamageBit(bool bit_value, int bit_number)
|
|
{
|
|
|
|
int byte = bit_number >> 3;
|
|
BYTE bit = (BYTE)(bit_number & 0x7);
|
|
|
|
|
|
// no allocations are allowed now. They are only allowed at start up inside
|
|
// of BuildTileBoundDamageList
|
|
|
|
Verify(byte+1 < tileBoundDamage.GetSize());
|
|
|
|
BYTE *memory = (BYTE*)tileBoundDamage.GetPointer();
|
|
|
|
if (bit_value)
|
|
{
|
|
memory[byte] |= 0x1<<bit;
|
|
}
|
|
else
|
|
{
|
|
// if bit is 3 than the third bit should be zeroed
|
|
// 11111011
|
|
memory[byte] &= ~(0x1<<bit);
|
|
}
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
bool
|
|
EntityManager::GetNetworkDamageBit(int bit_number)
|
|
{
|
|
|
|
int byte = bit_number >> 3;
|
|
BYTE bit = (BYTE)(bit_number & 0x7);
|
|
|
|
Verify(byte+1 < tileBoundDamage.GetSize());
|
|
|
|
BYTE *memory = (BYTE*)tileBoundDamage.GetPointer();
|
|
|
|
|
|
return (memory[byte] & (0x1<<bit))?true:false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void
|
|
EntityManager::BuildTileBoundDamageList()
|
|
{
|
|
|
|
Check_Object(CollisionGrid::Instance);
|
|
|
|
BYTE row_size;
|
|
BYTE column_size;
|
|
CollisionGrid::Instance->GetSize(&row_size, &column_size);
|
|
|
|
|
|
int current_byte = 0;
|
|
|
|
|
|
for (WORD index = 0; index < (row_size * column_size); ++index)
|
|
{
|
|
|
|
Tile *tile = CollisionGrid::Instance->GetTile(index);
|
|
Check_Object(tile);
|
|
|
|
// go thru the children...
|
|
|
|
int current_bit = current_byte<<3;
|
|
int tile_entity_count = 0;
|
|
|
|
tile->SetDamageBitStart(current_bit);
|
|
|
|
|
|
Entity *entity;
|
|
for (int i = 0; i < tile->GetDamagableEntityCount(); ++i)
|
|
{
|
|
|
|
entity = tile->GetDamagableEntity(i);
|
|
Check_Object(entity);
|
|
|
|
Verify(entity->IsDestroyable());
|
|
|
|
entity->damageBit = current_bit;
|
|
|
|
tileBoundDamage.WriteBit(entity->IsDestroyed());
|
|
++current_bit;
|
|
++tile_entity_count;
|
|
|
|
if (tileBoundDamage.GetBytesRemaining() < 2)
|
|
{
|
|
tileBoundDamage.AllocateBytes(1000>>3);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
tileBoundDamage.WriteByteAlign();
|
|
current_byte = tileBoundDamage.GetBytesUsed();
|
|
|
|
|
|
}
|
|
tileBoundDamage.Rewind();
|
|
|
|
|
|
}
|
|
|
|
void
|
|
EntityManager::ResetTileBoundDamageList()
|
|
{
|
|
|
|
Check_Object(CollisionGrid::Instance);
|
|
|
|
BYTE row_size;
|
|
BYTE column_size;
|
|
CollisionGrid::Instance->GetSize(&row_size, &column_size);
|
|
|
|
|
|
int current_byte = 0;
|
|
|
|
|
|
tileBoundDamage.Rewind();
|
|
|
|
for (WORD index = 0; index < (row_size * column_size); ++index)
|
|
{
|
|
|
|
Tile *tile = CollisionGrid::Instance->GetTile(index);
|
|
Check_Object(tile);
|
|
|
|
// go thru the children...
|
|
|
|
int current_bit = current_byte<<3;
|
|
int tile_entity_count = 0;
|
|
|
|
tile->SetDamageBitStart(current_bit);
|
|
|
|
|
|
Entity *entity;
|
|
for (int i = 0; i < tile->GetDamagableEntityCount(); ++i)
|
|
{
|
|
|
|
entity = tile->GetDamagableEntity(i);
|
|
Check_Object(entity);
|
|
|
|
Verify(entity->IsDestroyable());
|
|
|
|
tileBoundDamage.WriteBit(entity->IsDestroyed());
|
|
++current_bit;
|
|
++tile_entity_count;
|
|
|
|
}
|
|
|
|
|
|
tileBoundDamage.WriteByteAlign();
|
|
current_byte = tileBoundDamage.GetBytesUsed();
|
|
|
|
|
|
}
|
|
tileBoundDamage.Rewind();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
EntityManager::PreCollisionExecute(Time till)
|
|
{
|
|
Check_Object(this);
|
|
PRECOLLISION_LOGIC("Entity Manager");
|
|
|
|
//
|
|
//--------------------------------------------
|
|
// Execute the mission if we are not suspended
|
|
//--------------------------------------------
|
|
//
|
|
Check_Object(Mission::GetInstance());
|
|
if (!isExecutionSuspended)
|
|
{
|
|
Mission::GetInstance()->PreCollisionExecute(till);
|
|
PreCollisionNetworkEvents();
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
EntityManager::PostCollisionExecute(Time till)
|
|
{
|
|
Check_Object(this);
|
|
POSTCOLLISION_LOGIC("Entity Manager");
|
|
|
|
//
|
|
//-------------------------------------------------
|
|
// Execute all callback entities in insertion order
|
|
//-------------------------------------------------
|
|
//
|
|
while (!postCollisionExecutors.IsEmpty())
|
|
{
|
|
ChainIteratorOf<Entity*> entities(&postCollisionExecutors);
|
|
Entity *entity = entities.GetCurrent();
|
|
Check_Object(entity);
|
|
Verify(!entity->GetElement()->IsMatrixDirty());
|
|
entity->PostCollisionExecute(till);
|
|
Verify(!entity->newCollisions);
|
|
Verify(!entity->GetElement()->IsMatrixDirty());
|
|
postCollisionExecutors.RemovePlug(entity);
|
|
}
|
|
Verify(postCollisionExecutors.IsEmpty());
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
EntityManager::UpdateEntities()
|
|
{
|
|
Check_Object(this);
|
|
|
|
return;
|
|
|
|
// WE NO LONGER DO THIS FOR NETWORK UPDATES
|
|
// EVERYTHING IS CLIENT SERVER BASED NOW
|
|
|
|
#if 0
|
|
//
|
|
//-------------------------------------------------
|
|
// Execute all callback entities in insertion order
|
|
//-------------------------------------------------
|
|
//
|
|
ChainIteratorOf<Entity*> entities(&updateEntities);
|
|
Entity *entity;
|
|
while ((entity = entities.GetCurrent()) != NULL)
|
|
{
|
|
Check_Object(entity);
|
|
Verify(entity->GetReplicatorMode() == Replicator::MasterMode);
|
|
|
|
//
|
|
//---------------------------------------------------------------------
|
|
// For each one, we need to make a stream for the message to write into
|
|
// and then broadcast the message to the entities replicants
|
|
//---------------------------------------------------------------------
|
|
//
|
|
DynamicMemoryStream stream;
|
|
Entity::UpdateMessage *message = entity->ConstructUpdate(&stream);
|
|
Check_Object(message);
|
|
entity->DispatchToReplicants(message);
|
|
|
|
//
|
|
//---------------------------------------------------
|
|
// Clean out each entry in the chain as it's executed
|
|
//---------------------------------------------------
|
|
//
|
|
entity->updateFlags = 0;
|
|
entities.Remove();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
EntityManager::RequestPostCollisionExecution(Entity *entity)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(entity);
|
|
|
|
Verify(!postCollisionExecutors.IsPlugMember(entity));
|
|
postCollisionExecutors.Add(entity);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
EntityManager::RemovePostCollisionExecution(Entity *entity)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(entity);
|
|
Verify(!entity->newCollisions);
|
|
|
|
if (entity->IsUsingPostCollision())
|
|
{
|
|
postCollisionExecutors.Remove(entity);
|
|
entity->IgnorePostCollision();
|
|
}
|
|
Verify(!postCollisionExecutors.IsPlugMember(entity));
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
EntityManager::RequestUpdate(Entity *entity)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(entity);
|
|
|
|
updateEntities.Add(entity);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
EntityManager::IsInPostCollisionExecution(Entity *entity)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(entity);
|
|
|
|
return postCollisionExecutors.IsPlugMember(entity);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
void EntityManager::ServeLocalEntities(Time till)
|
|
{
|
|
STOP(("That's a bad little monkey!!!: EntityManager::ServeLocalEntities - VIRTUAL NOT IMPLEMENTED"));
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
void EntityManager::UpdateClientEntites(int connection, int message_type, Stuff::MemoryStream *message)
|
|
{
|
|
STOP(("That's a bad little monkey!!!: EntityManager::UpdateLocalEntites - VIRTUAL NOT IMPLEMENTED"));
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void
|
|
EntityManager::TestInstance()
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|