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.
1399 lines
34 KiB
C++
1399 lines
34 KiB
C++
//===========================================================================//
|
|
// File: Entity.hpp //
|
|
//---------------------------------------------------------------------------//
|
|
// Date Who Modification //
|
|
// -------- --- ---------------------------------------------------------- //
|
|
// 11/29/94 JMA Initial coding. //
|
|
// 08/25/97 JMA Infrastructure changes //
|
|
// 08/25/97 ECH Infrastructure changes //
|
|
//---------------------------------------------------------------------------//
|
|
// Copyright (C) 1994-97, Virtual World Entertainment, Inc. //
|
|
// All Rights reserved worldwide //
|
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
|
//===========================================================================//
|
|
|
|
#pragma once
|
|
|
|
#include "Adept.hpp"
|
|
#include "Replicator.hpp"
|
|
#include "ExecutionState.hpp"
|
|
#include "Event.hpp"
|
|
#include "NameTable.hpp"
|
|
#include "RendererManager.hpp"
|
|
#include <ElementRenderer\Element.hpp>
|
|
|
|
namespace Adept {
|
|
|
|
class RendererComponentWeb;
|
|
class Renderer;
|
|
class AttributeEntry;
|
|
class AttributeTable;
|
|
class ModelAttributeEntry;
|
|
class CollisionVolume;
|
|
class DamageObject;
|
|
|
|
class Entity;
|
|
class Entity__ClassData;
|
|
class Entity__GameModel;
|
|
class Entity__BecomeInterestingMessage;
|
|
class Entity__CreateMessage;
|
|
class Entity__TakeDamageMessage;
|
|
class Entity__UpdateMessage;
|
|
|
|
//##########################################################################
|
|
//################## Entity::CreateMessage ###########################
|
|
//##########################################################################
|
|
|
|
class Entity__CreateMessage:
|
|
public Replicator__CreateMessage
|
|
{
|
|
public:
|
|
|
|
#if NSWIZZLE
|
|
ResourceID
|
|
dataListID;
|
|
Stuff::LinearMatrix4D
|
|
localToParent;
|
|
Entity__ExecutionStateEngine::FactoryRequest
|
|
executionState;
|
|
ObjectID
|
|
nameID;
|
|
Stuff::Scalar
|
|
initialAge;
|
|
int
|
|
alignment;
|
|
#else
|
|
Stuff::LinearMatrix4D
|
|
localToParent;
|
|
Entity__ExecutionStateEngine::FactoryRequest
|
|
executionState;
|
|
Stuff::Scalar
|
|
initialAge;
|
|
ResourceID
|
|
dataListID;
|
|
int
|
|
alignment;
|
|
ObjectID
|
|
nameID;
|
|
#endif
|
|
|
|
Entity__CreateMessage(
|
|
size_t length,
|
|
int priority,
|
|
int message_flags,
|
|
Stuff::RegisteredClass::ClassID class_id,
|
|
int replicator_flags,
|
|
const ResourceID& data_list_id,
|
|
const Stuff::LinearMatrix4D &local_to_parent,
|
|
Stuff::Scalar age,
|
|
int execution_state,
|
|
ObjectID name_id,
|
|
int entity_alignment
|
|
):
|
|
Replicator__CreateMessage(
|
|
length,
|
|
priority,
|
|
message_flags,
|
|
class_id,
|
|
replicator_flags
|
|
),
|
|
dataListID(data_list_id),
|
|
localToParent(local_to_parent),
|
|
initialAge(age),
|
|
executionState(execution_state),
|
|
nameID(name_id),
|
|
alignment(entity_alignment)
|
|
{}
|
|
|
|
static void
|
|
ConstructCreateMessage(Script *script);
|
|
};
|
|
|
|
//##########################################################################
|
|
//###################### Entity::GameModel ###########################
|
|
//##########################################################################
|
|
|
|
class Entity__GameModel
|
|
{
|
|
public:
|
|
|
|
#if NSWIZZLE
|
|
Stuff::RegisteredClass::ClassID
|
|
classID;
|
|
|
|
ResourceID
|
|
elementResourceID,
|
|
obbStreamResourceID;
|
|
unsigned
|
|
defaultFlags;
|
|
|
|
static void
|
|
GetEffectResourceID(ResourceID *return_id, const ResourceID& effect_stream, BYTE index);
|
|
void
|
|
TestInstance() const
|
|
{}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Attribute Support
|
|
//
|
|
public:
|
|
typedef int
|
|
AttributeID;
|
|
typedef int
|
|
Entity__GameModel::*AttributePointer;
|
|
bool
|
|
collider,
|
|
canBeWalkedOn,
|
|
canBeShot,
|
|
waterSurface,
|
|
OBBCollides;
|
|
int
|
|
walkThru;
|
|
#else
|
|
bool
|
|
collider,
|
|
canBeWalkedOn,
|
|
canBeShot,
|
|
waterSurface,
|
|
OBBCollides;
|
|
int
|
|
walkThru;
|
|
Stuff::RegisteredClass::ClassID
|
|
classID;
|
|
|
|
ResourceID
|
|
obbStreamResourceID,
|
|
elementResourceID;
|
|
unsigned
|
|
defaultFlags;
|
|
|
|
static void
|
|
GetEffectResourceID(ResourceID *return_id, const ResourceID& effect_stream, BYTE index);
|
|
void
|
|
TestInstance() const
|
|
{}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Attribute Support
|
|
//
|
|
public:
|
|
typedef int
|
|
AttributeID;
|
|
typedef int
|
|
Entity__GameModel::*AttributePointer;
|
|
#endif
|
|
|
|
enum
|
|
{
|
|
AnyAttributeID = 0,
|
|
ColliderAttributeID,
|
|
CanBeWalkedOnAttributeID,
|
|
CanBeShotAttributeID,
|
|
WaterSurfaceAttributeID,
|
|
OBBCollidesAttributeID,
|
|
NextAttributeID
|
|
};
|
|
|
|
enum
|
|
{
|
|
MaxStringLength = 256
|
|
};
|
|
|
|
// enum
|
|
// {
|
|
// NothingCanWalkThru =0,
|
|
// HeavyCanWalkThru,
|
|
// MediumCanWalkThru,
|
|
// AnythingCanWalkThru
|
|
// }
|
|
|
|
static int
|
|
WalkThruTextToAscii(const char *string);
|
|
|
|
ModelAttributeEntry*
|
|
GetAttributeEntry(AttributeID attribute_ID);
|
|
ModelAttributeEntry*
|
|
GetAttributeEntry(const char *attribute_name);
|
|
|
|
static bool
|
|
ReadAndVerify(
|
|
Entity__GameModel *model,
|
|
ModelAttributeEntry *attribute_entry,
|
|
const char *data,
|
|
char **error,
|
|
int error_buffer = 128
|
|
);
|
|
|
|
static void
|
|
WriteToText(
|
|
Entity__GameModel *model,
|
|
ModelAttributeEntry *attribute_entry,
|
|
char **text_string
|
|
);
|
|
|
|
static void
|
|
SaveGameModel(
|
|
Entity__GameModel *model,
|
|
Stuff::NotationFile *data_file
|
|
);
|
|
|
|
typedef bool
|
|
(*ReadAndVerifier)(
|
|
Entity__GameModel *model,
|
|
ModelAttributeEntry *attribute_entry,
|
|
const char *data,
|
|
char **error,
|
|
int error_buffer = 128
|
|
);
|
|
typedef void
|
|
(*ModelWrite)(
|
|
Entity__GameModel *model,
|
|
ModelAttributeEntry *attribute_entry,
|
|
char **text_string
|
|
);
|
|
typedef void
|
|
(*ModelSave)(
|
|
Entity__GameModel *model,
|
|
Stuff::NotationFile *data_file
|
|
);
|
|
|
|
|
|
class Script
|
|
{
|
|
public:
|
|
Script(
|
|
Stuff::MemoryStream *model_stream,
|
|
Stuff::NotationFile *model_file,
|
|
Entity__ClassData *model_class_data
|
|
):
|
|
modelStream(model_stream),
|
|
modelFile(model_file),
|
|
modelClassData(model_class_data)
|
|
{}
|
|
|
|
void
|
|
TestInstance() const
|
|
{}
|
|
|
|
Stuff::MemoryStream
|
|
*modelStream;
|
|
Stuff::NotationFile
|
|
*modelFile;
|
|
Entity__ClassData
|
|
*modelClassData;
|
|
};
|
|
|
|
typedef void
|
|
(*Factory)(Script *script);
|
|
static void
|
|
ConstructGameModel(Script *script);
|
|
static void
|
|
ConstructOBBStream(Script *script);
|
|
};
|
|
|
|
//##########################################################################
|
|
//########################### Entity #################################
|
|
//##########################################################################
|
|
|
|
typedef Replicator__Message Entity__Message;
|
|
typedef Replicator__DestroyMessage Entity__DestroyMessage;
|
|
class Entity__CollisionQuery;
|
|
class Entity__CollisionData;
|
|
|
|
class Entity:
|
|
public Replicator
|
|
{
|
|
friend class Entity__ExecutionStateEngine;
|
|
friend class Entity__ExecutingChildEntityIterator;
|
|
friend class EntityManager;
|
|
friend class Map;
|
|
friend class CollisionGrid;
|
|
friend class Zone;
|
|
friend class CollisionVolume;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Inheritance support
|
|
//
|
|
public:
|
|
typedef Entity__ClassData ClassData;
|
|
typedef Entity__GameModel GameModel;
|
|
typedef Entity__CreateMessage CreateMessage;
|
|
typedef Entity__Message Message;
|
|
typedef Entity__DestroyMessage DestroyMessage;
|
|
typedef Entity__UpdateMessage UpdateMessage;
|
|
typedef Entity__ExecutionStateEngine ExecutionStateEngine;
|
|
typedef Entity__CollisionQuery CollisionQuery;
|
|
typedef Entity__CollisionData CollisionData;
|
|
typedef Entity__TakeDamageMessage TakeDamageMessage;
|
|
typedef Entity__BecomeInterestingMessage BecomeInterestingMessage;
|
|
typedef Replicator BaseClass;
|
|
|
|
public:
|
|
static void
|
|
InitializeClass();
|
|
static void
|
|
TerminateClass();
|
|
ClassData*
|
|
GetClassData();
|
|
static ClassData
|
|
*DefaultData;
|
|
|
|
static HGOSHEAP
|
|
s_Heap,
|
|
s_CollisionHeap;
|
|
static int
|
|
s_EntitiesSynced;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Run-time Construction and Destruction Support
|
|
//
|
|
public:
|
|
typedef Entity*
|
|
(*Factory)(
|
|
const CreateMessage *message,
|
|
ReplicatorID *base_id
|
|
);
|
|
|
|
static Entity*
|
|
Make(
|
|
const CreateMessage *message,
|
|
ReplicatorID *base_id
|
|
);
|
|
|
|
Replicator::CreateMessage*
|
|
SaveMakeMessage(Stuff::MemoryStream *stream, ResourceFile *res_file);
|
|
|
|
virtual void
|
|
SaveInstanceText(Stuff::Page *page);
|
|
|
|
void
|
|
Reuse(
|
|
const CreateMessage *message,
|
|
ReplicatorID *base_id
|
|
);
|
|
virtual void
|
|
Respawn(CreateMessage *message);
|
|
|
|
virtual void
|
|
SentenceToDeathRow();
|
|
|
|
static Entity*
|
|
CreateEntity(
|
|
Stuff::MemoryStream *stream,
|
|
ReplicatorID *base_id,
|
|
bool use_armory=true
|
|
);
|
|
|
|
void
|
|
Destroy() //Never Call this unless you really need to
|
|
{Check_Object(this); delete this;}
|
|
|
|
|
|
protected:
|
|
Entity(
|
|
ClassData *class_data,
|
|
const CreateMessage *message,
|
|
ReplicatorID *base_id,
|
|
ElementRenderer::Element *element
|
|
);
|
|
~Entity();
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Message Support
|
|
//
|
|
public:
|
|
enum {
|
|
UpdateMessageID = Replicator::NextMessageID,
|
|
TakeDamageMessageID,
|
|
BecomeInterestingMessageID,
|
|
NextMessageID
|
|
};
|
|
|
|
void
|
|
DestroyMessageHandler(const DestroyMessage *message);
|
|
void
|
|
UpdateMessageHandler(const UpdateMessage *message);
|
|
void
|
|
TakeDamageMessageHandler(const TakeDamageMessage *message);
|
|
void
|
|
BecomeInterestingMessageHandler(const BecomeInterestingMessage *message);
|
|
|
|
void
|
|
RequestUpdate(int update_flags);
|
|
virtual UpdateMessage*
|
|
ConstructUpdate(Stuff::MemoryStream *stream);
|
|
|
|
protected:
|
|
static const MessageEntry
|
|
MessageEntries[];
|
|
int
|
|
updateFlags;
|
|
Stuff::SlotOf<AbstractEvent*>
|
|
m_pendingInterestMessage;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Flag Support
|
|
//
|
|
public:
|
|
enum
|
|
{
|
|
PropTypeFlagBit = Replicator::NextFlagBit,
|
|
DirtyMatrixFlagBit = PropTypeFlagBit+2,
|
|
PostCollisionFlagBit,
|
|
InterestLevelFlagBit,
|
|
DirtyZoneFlagBit = InterestLevelFlagBit+2,
|
|
TileBoundFlagBit,
|
|
ColliderFlagBit,
|
|
CanBeWalkedOnFlagBit,
|
|
CanBeShotFlagBit,
|
|
WaterSurfaceFlagBit,
|
|
OBBCollidesFlagBit,
|
|
EditorIsMovingFlagBit,
|
|
WalkThruBit,
|
|
DestroyedFlagBit = WalkThruBit+2,
|
|
ReusableFlagBit,
|
|
DamageDecalFlagBit,
|
|
TriedToMoveOffMapThisFrameFlagBit,
|
|
NextFlagBit
|
|
};
|
|
|
|
enum InterestLevel
|
|
{
|
|
DormantInterestLevel = 0,
|
|
SimulationInterestLevel = 1<<InterestLevelFlagBit,
|
|
RenderingInterestLevel = 2<<InterestLevelFlagBit
|
|
};
|
|
|
|
enum PropType {
|
|
PlayerPropType = 0,
|
|
MissionPropType = 1<<PropTypeFlagBit,
|
|
ArmoryPropType = 2<<PropTypeFlagBit,
|
|
MapPropType = 3<<PropTypeFlagBit
|
|
};
|
|
|
|
enum WalkThruType {
|
|
NothingCanWalkThruType = 0,
|
|
HeavyCanWalkThruType = 1<<WalkThruBit,
|
|
MediumCanWalkThruType = 2<<WalkThruBit,
|
|
AnythingCanWalkThruType = 3<<WalkThruBit
|
|
};
|
|
|
|
enum CollisionMask
|
|
{
|
|
CanBeWalkedOnFlag = 1<<CanBeWalkedOnFlagBit,
|
|
CanBeShotFlag = 1<<CanBeShotFlagBit,
|
|
WaterSurfaceFlag = 1<<WaterSurfaceFlagBit,
|
|
EditorIsMovingFlag = 1<<EditorIsMovingFlagBit,
|
|
OBBCollidesFlag = 1<<OBBCollidesFlagBit,
|
|
|
|
NeverCollidesMask = 0,
|
|
WalkerMask = CanBeWalkedOnFlag|CanBeShotFlag,
|
|
FloaterMask = CanBeWalkedOnFlag|WaterSurfaceFlag,
|
|
AlwaysCollidesMask = FloaterMask|WalkerMask|OBBCollidesFlag,
|
|
AllCollisionsMask = AlwaysCollidesMask|EditorIsMovingFlag
|
|
};
|
|
|
|
enum
|
|
{
|
|
PropTypeMask = 3<<PropTypeFlagBit,
|
|
DirtyMatrixFlag = 1<<DirtyMatrixFlagBit,
|
|
PostCollisionFlag = 1<<PostCollisionFlagBit,
|
|
InterestLevelMask = 3<<InterestLevelFlagBit,
|
|
DirtyZoneFlag = 1<<DirtyZoneFlagBit,
|
|
ColliderFlag = 1<<ColliderFlagBit,
|
|
TileBoundFlag = 1<<TileBoundFlagBit,
|
|
|
|
WalkThruMask = 3<<WalkThruBit,
|
|
GameModelMask = ColliderFlag|AlwaysCollidesMask|WalkThruMask,
|
|
DestroyedFlag = 1<<DestroyedFlagBit,
|
|
|
|
ReusableFlag = 1<<ReusableFlagBit,
|
|
DamageDecalFlag = 1<<DamageDecalFlagBit,
|
|
|
|
TriedToMoveOffMapThisFrameFlag = 1 <<TriedToMoveOffMapThisFrameFlagBit,
|
|
DefaultFlags = 0
|
|
};
|
|
|
|
void
|
|
SetPropType(PropType type)
|
|
{Check_Object(this); replicatorFlags &= ~PropTypeMask; replicatorFlags |= type;}
|
|
PropType
|
|
GetPropType()
|
|
{Check_Object(this); return static_cast<PropType>(replicatorFlags&PropTypeMask);}
|
|
|
|
void
|
|
NeedMatrixSync()
|
|
{Check_Object(this); replicatorFlags |= DirtyMatrixFlag;}
|
|
void
|
|
ClearNeedMatrixSync()
|
|
{
|
|
Check_Object(this); Check_Object(entityElement);
|
|
replicatorFlags &= ~DirtyMatrixFlag;
|
|
}
|
|
bool
|
|
IsMatrixDirty()
|
|
{Check_Object(this); return (replicatorFlags&DirtyMatrixFlag) != 0;}
|
|
|
|
void
|
|
UsePostCollision()
|
|
{Check_Object(this); replicatorFlags |= PostCollisionFlag;}
|
|
void
|
|
IgnorePostCollision()
|
|
{Check_Object(this); Verify(!newCollisions); replicatorFlags &= ~PostCollisionFlag;}
|
|
bool
|
|
IsUsingPostCollision()
|
|
{Check_Object(this); return (replicatorFlags&PostCollisionFlag) != 0;}
|
|
|
|
InterestLevel
|
|
GetInterestLevel()
|
|
{Check_Object(this); return static_cast<InterestLevel>(replicatorFlags&InterestLevelMask);}
|
|
void
|
|
SetInterestMask(InterestLevel type)
|
|
{Check_Object(this); replicatorFlags &= ~InterestLevelMask; replicatorFlags |= type;}
|
|
void
|
|
SetInterestLevel(InterestLevel type);
|
|
|
|
bool
|
|
IsACollider()
|
|
{Check_Object(this); return (replicatorFlags & ColliderFlag) != 0;}
|
|
|
|
bool
|
|
IsZoneDirty()
|
|
{Check_Object(this); return (replicatorFlags&DirtyZoneFlag) != 0;}
|
|
|
|
void
|
|
BindToZone();
|
|
void
|
|
BindToTile();
|
|
bool
|
|
IsTileBound()
|
|
{Check_Object(this); return (replicatorFlags & TileBoundFlag) != 0;}
|
|
|
|
CollisionMask
|
|
GetCollisionMask()
|
|
{Check_Object(this); return static_cast<CollisionMask>(replicatorFlags & AllCollisionsMask);}
|
|
virtual void
|
|
SetCollisionMask(CollisionMask mask);
|
|
bool
|
|
CouldCollideWith(int mask)
|
|
{Check_Object(this); return (replicatorFlags & mask & AllCollisionsMask) != 0;}
|
|
bool
|
|
CanBeWalkedOn()
|
|
{Check_Object(this); return (replicatorFlags & CanBeWalkedOnFlag) != 0;}
|
|
bool
|
|
CanBeShot()
|
|
{Check_Object(this); return (replicatorFlags & CanBeShotFlag) != 0;}
|
|
bool
|
|
IsWaterSurface()
|
|
{Check_Object(this); return (replicatorFlags & WaterSurfaceFlag) != 0;}
|
|
bool
|
|
CanOBBCollide()
|
|
{Check_Object(this); return (replicatorFlags & OBBCollidesFlag) != 0;}
|
|
|
|
void
|
|
SetWalkThruType(WalkThruType type)
|
|
{Check_Object(this); replicatorFlags &= ~WalkThruMask; replicatorFlags |= type;}
|
|
WalkThruType
|
|
GetWalkThruType()
|
|
{Check_Object(this); return static_cast<WalkThruType>(replicatorFlags&WalkThruMask);}
|
|
|
|
|
|
bool
|
|
IsDestroyed()
|
|
{Check_Object(this); return (replicatorFlags & DestroyedFlag) !=0;}
|
|
void
|
|
SetDestroyedFlag(int damage_mode);
|
|
void
|
|
ClearDestroyedFlag();
|
|
bool
|
|
HasTriedToMoveOffMapThisFrameFlag()
|
|
{Check_Object(this); return (replicatorFlags & TriedToMoveOffMapThisFrameFlag) != 0;}
|
|
void
|
|
SetTriedToMoveOffMapThisFrameFlag();
|
|
void
|
|
ClearTriedToMoveOffMapThisFrameFlag();
|
|
|
|
bool
|
|
HasPlacedDamageDecal()
|
|
{Check_Object(this); return (replicatorFlags & DamageDecalFlag) !=0;}
|
|
void
|
|
SetDamageDecalFlag()
|
|
{Check_Object(this); replicatorFlags |= DamageDecalFlag;}
|
|
void
|
|
ClearDamageDecalFlag()
|
|
{Check_Object(this); replicatorFlags &= ~DamageDecalFlag;}
|
|
|
|
bool
|
|
IsReusable()
|
|
{Check_Object(this); return (replicatorFlags & ReusableFlag) != 0;}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Attribute Support
|
|
//
|
|
public:
|
|
typedef int
|
|
AttributeID;
|
|
typedef int
|
|
Entity::*AttributePointer;
|
|
|
|
Stuff::Scalar
|
|
lightIntensity;
|
|
|
|
enum
|
|
{
|
|
AnyAttributeID = 0,
|
|
ExecutionStateAttributeID,
|
|
LocalToWorldAttributeID,
|
|
IsDestroyedAttributeID,
|
|
VisualRepresentationAttributeID,
|
|
LightIntensityAttributeID,
|
|
NextAttributeID
|
|
};
|
|
|
|
AttributeEntry*
|
|
GetAttributeEntry(AttributeID attribute_ID);
|
|
AttributeEntry*
|
|
GetAttributeEntry(const char *attribute_name);
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Resource Support
|
|
//
|
|
public:
|
|
const GameModel*
|
|
GetGameModel()
|
|
{Check_Object(this); return Cast_Pointer(GameModel*, gameModelResource.GetPointer());}
|
|
static void
|
|
GetGameModelResourceFromDataListID(
|
|
Resource *resource,
|
|
const ResourceID &data_list
|
|
);
|
|
static ClassID
|
|
GetClassIDFromDataListID(const ResourceID &data_list);
|
|
|
|
const ResourceID&
|
|
GetDataListResourceID()
|
|
{Check_Object(this); return dataListResource.GetResourceID();}
|
|
|
|
const char*
|
|
GetModelName()
|
|
{Check_Object(this); return dataListResource.GetName();}
|
|
|
|
const char*
|
|
GetGameModelResourceName()
|
|
{Check_Object(this); return (gameModelResource.GetName());}
|
|
|
|
Resource*
|
|
GetDataListResource()
|
|
{Check_Object(this); return (&dataListResource);}
|
|
|
|
Resource*
|
|
GetGameModelResource()
|
|
{Check_Object(this); return (&gameModelResource);}
|
|
|
|
const ResourceID&
|
|
GetGameModelResourceID()
|
|
{Check_Object(this); return gameModelResource.GetResourceID();}
|
|
|
|
virtual char *
|
|
GetObjectName()
|
|
{Check_Object(this); return (char *)" ";}
|
|
|
|
Stuff::MString
|
|
instanceName;
|
|
ObjectID
|
|
objectID;
|
|
|
|
protected:
|
|
Resource
|
|
dataListResource,
|
|
gameModelResource;
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Ownership
|
|
//
|
|
public:
|
|
Entity*
|
|
GetParentEntity()
|
|
{Check_Object(this); return parentEntity;}
|
|
|
|
virtual void
|
|
AddChild(Entity *entity);
|
|
virtual void
|
|
RemoveChild(Entity *entity);
|
|
|
|
const Stuff::LinearMatrix4D&
|
|
GetLocalToWorld()
|
|
{
|
|
Check_Object(this); Check_Object(entityElement);
|
|
return entityElement->GetLocalToWorld();
|
|
}
|
|
const Stuff::LinearMatrix4D&
|
|
GetLocalToParent()
|
|
{
|
|
Check_Object(this); Check_Object(entityElement);
|
|
return entityElement->GetLocalToParent();
|
|
}
|
|
|
|
void
|
|
SetNewLocalToParent(const Stuff::LinearMatrix4D &new_local_to_world);
|
|
|
|
//
|
|
// Only use this member for creating iterators in editors, etc.
|
|
// DO NOT use this directly in the game
|
|
//
|
|
Stuff::ChainOf<Entity*>
|
|
childEntityChain;
|
|
|
|
protected:
|
|
void
|
|
DeleteChildEntities();
|
|
|
|
virtual void
|
|
ChildPreCollisionChanged(Entity *entity);
|
|
|
|
Entity
|
|
*parentEntity;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Renderer Support
|
|
//
|
|
public:
|
|
RendererComponentWeb*
|
|
GetComponentWeb(unsigned renderer_id)
|
|
{
|
|
Check_Object(this);
|
|
return componentWebs[renderer_id];
|
|
}
|
|
void
|
|
SetComponentWeb(
|
|
unsigned renderer_id,
|
|
RendererComponentWeb *web
|
|
);
|
|
|
|
bool
|
|
m_doesNeedToUpdateWebs;
|
|
void
|
|
ExecuteComponentWebs();
|
|
void
|
|
ExecuteChildComponentWebs();
|
|
|
|
virtual void
|
|
BecomeInteresting(bool render_me);
|
|
virtual void
|
|
BecomeUninteresting();
|
|
|
|
const ResourceID&
|
|
GetRendererDataResourceID(int renderer_type);
|
|
|
|
ElementRenderer::Element*
|
|
GetElement()
|
|
{Check_Object(this); return entityElement;}
|
|
|
|
protected:
|
|
RendererComponentWeb*
|
|
componentWebs[RendererManager::RendererTypeCount];
|
|
ElementRenderer::Element
|
|
*entityElement;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Execution Support
|
|
//
|
|
public:
|
|
bool isPlayerVehicle;
|
|
|
|
virtual int
|
|
GetExecutionSlot();
|
|
|
|
virtual void
|
|
PreCollisionExecute(Stuff::Time till);
|
|
virtual bool
|
|
CollisionHandler(
|
|
Stuff::LinearMatrix4D *new_position,
|
|
Stuff::DynamicArrayOf<CollisionData> *collisions
|
|
);
|
|
virtual void
|
|
SyncMatrices(bool update_matrix);
|
|
virtual void
|
|
SyncMatricesFirstLevelOnly(bool update_matrix);
|
|
|
|
virtual void
|
|
PostCollisionExecute(Stuff::Time till);
|
|
|
|
virtual int
|
|
GetTableArray()
|
|
{Check_Object(this); return NameTable::CulturalArray;}
|
|
|
|
ExecutionStateEngine
|
|
*executionState;
|
|
|
|
virtual void
|
|
PlaceOnEntity(
|
|
Stuff::LinearMatrix4D *position,
|
|
Stuff::Motion3D *velocity,
|
|
const Stuff::LinearMatrix4D &initial_offset,
|
|
const Stuff::Motion3D &initial_velocity
|
|
);
|
|
|
|
void
|
|
FollowAndBillBoard(
|
|
Stuff::LinearMatrix4D *position,
|
|
Stuff::UnitVector3D *direction
|
|
);
|
|
|
|
Stuff::Scalar
|
|
GetTimeParameter(Stuff::Time till)
|
|
{
|
|
Stuff::Scalar slice = static_cast<Stuff::Scalar>(till - lastParameterization);
|
|
return slice;
|
|
}
|
|
|
|
Stuff::Scalar
|
|
GetTimeSlice(Stuff::Time till)
|
|
{
|
|
Stuff::Scalar slice = static_cast<Stuff::Scalar>(till - lastExecuted);
|
|
return slice;
|
|
}
|
|
|
|
CollisionVolume*
|
|
GetSolidVolume()
|
|
{Check_Object(this); return solidVolume;}
|
|
CollisionVolume*
|
|
GetHierarchicalVolume()
|
|
{Check_Object(this); return hierarchicalVolume;}
|
|
|
|
Entity*
|
|
ProjectLine(
|
|
Stuff::Line3D *line,
|
|
CollisionMask mask,
|
|
Stuff::Point3D *target_offset,
|
|
Stuff::Normal3D *normal
|
|
);
|
|
|
|
virtual bool
|
|
IsWithin(
|
|
Entity *target,
|
|
Stuff::Scalar distance,
|
|
bool ignorey = false
|
|
);
|
|
|
|
Stuff::Scalar
|
|
GetDistanceFrom(Entity *target);
|
|
|
|
Stuff::Scalar
|
|
GetDistanceSquaredFrom(Entity *target, bool ignore_y = false);
|
|
|
|
|
|
Stuff::Time
|
|
lastExecuted,
|
|
lastParameterization;
|
|
|
|
Stuff::LinearMatrix4D
|
|
initialLocalToParent;
|
|
|
|
enum{
|
|
DefaultAlignment = 0,
|
|
Player,
|
|
Enemy,
|
|
Team1,
|
|
Team2,
|
|
Team3,
|
|
Team4,
|
|
LastAlignment
|
|
};
|
|
|
|
virtual int
|
|
GetAlignment() const
|
|
{ return (alignment); }
|
|
|
|
void
|
|
SetAlignment(int _alignment)
|
|
{ alignment = _alignment; }
|
|
|
|
int
|
|
GetRelativeAlignment(int object_alignment) const
|
|
{
|
|
if (object_alignment == DefaultAlignment)
|
|
{
|
|
return (DefaultAlignment);
|
|
}
|
|
|
|
int align = GetAlignment();
|
|
|
|
if (align == DefaultAlignment)
|
|
{
|
|
return (DefaultAlignment);
|
|
}
|
|
|
|
if (align != object_alignment)
|
|
{
|
|
return (Enemy);
|
|
}
|
|
|
|
return (Player);
|
|
}
|
|
|
|
static const char *
|
|
AlignmentAsciiToText(int alignment);
|
|
static int
|
|
AlignmentTextToAscii(const char *alignment);
|
|
|
|
void SetPlayerVehicle()
|
|
{
|
|
isPlayerVehicle = true;
|
|
}
|
|
|
|
bool IsPlayerVehicle()
|
|
{
|
|
return isPlayerVehicle;
|
|
}
|
|
|
|
//These are for sensor speed in lookups. I makes us not have
|
|
//to drill down into entity class structure to check if they can
|
|
//be sensed by sensors. This is not good practice. I suck.
|
|
virtual int
|
|
GetSensorMode()
|
|
{return -1;}
|
|
virtual bool
|
|
DoesHaveECM()
|
|
{return false;}
|
|
//
|
|
// NOTE! DO NOT CALL THESE DIRECTLY. THEY ARE FOR STATE ENGINES!
|
|
//
|
|
|
|
virtual void
|
|
EnterNeverExecuteState();
|
|
virtual void
|
|
LeaveNeverExecuteState();
|
|
|
|
bool IsMultiTile()
|
|
{Check_Object(this); return minTileRow!=maxTileRow || minTileColumn!=maxTileColumn;}
|
|
bool IsMultiZone()
|
|
{Check_Object(this); return (minTileRow&~7)!=(maxTileRow&~7) || (minTileColumn&~7)!=(maxTileColumn&~7);}
|
|
|
|
BYTE GetMinTileRow()
|
|
{Check_Object(this); return minTileRow;}
|
|
BYTE GetMinTileCol()
|
|
{Check_Object(this); return minTileColumn;}
|
|
BYTE GetMaxTileRow()
|
|
{Check_Object(this); return maxTileRow;}
|
|
BYTE GetMaxTileCol()
|
|
{Check_Object(this); return maxTileColumn;}
|
|
|
|
void
|
|
RemoveCollision();
|
|
|
|
virtual bool IsNeverExecuteState();
|
|
|
|
virtual bool // TEMPORARY until Fang fixes the SlidingShapeComponent NonCom bug -- PAULTOZ
|
|
IsNonCom() const
|
|
{ return (false); }
|
|
|
|
protected:
|
|
CollisionVolume
|
|
*solidVolume,
|
|
*hierarchicalVolume;
|
|
Stuff::DynamicArrayOf<CollisionData>
|
|
*oldCollisions,
|
|
*newCollisions;
|
|
Entity
|
|
*nextPreExecution;
|
|
|
|
BYTE
|
|
minTileRow,
|
|
maxTileRow,
|
|
minTileColumn,
|
|
maxTileColumn;
|
|
|
|
Entity
|
|
*dontHit;
|
|
|
|
int
|
|
alignment;
|
|
bool
|
|
collisionAllowed;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Damage support
|
|
//
|
|
public:
|
|
|
|
enum{
|
|
PrestineState = 0,
|
|
DestroyedState,
|
|
PrestineInternalState,
|
|
DestroyedInternalState,
|
|
PrestineNoneState=0xe,
|
|
DestroyedNoneState=0xf,
|
|
PrestineBothState=0x20,
|
|
DestroyedBothState=0x31
|
|
};
|
|
|
|
virtual void
|
|
SetDamageObject(DamageObject *damage_object);
|
|
virtual void
|
|
ReactToHit(const TakeDamageMessage *message,DamageObject *partHit)
|
|
{};
|
|
virtual void
|
|
ReactToInternalDamage(int damage_mode)
|
|
{};
|
|
virtual void
|
|
ReactToDestruction(int damage_mode,int damage_type);
|
|
virtual void
|
|
ReactToDamageTaken(Stuff::Scalar damage_taken, const Adept::ReplicatorID& inflicting_entity, int weaponID, int damageType)
|
|
{};
|
|
virtual bool
|
|
FriendlyFire(const TakeDamageMessage *message);
|
|
|
|
void
|
|
NotifyWhoHitMe(const ReplicatorID& inflicting_id, int weap_id)
|
|
{Check_Object(this); m_whoShotMeLast = inflicting_id; m_weaponShotMeLast = weap_id;}
|
|
|
|
virtual void
|
|
TakeSplashDamage(Adept::Entity__TakeDamageMessage *message){};
|
|
|
|
void
|
|
SetDestroyedRepresentation();
|
|
void
|
|
SetInternalRepresentation();
|
|
void
|
|
SetBothRepresentation();
|
|
void
|
|
SetExternalRepresentation();
|
|
void
|
|
SetNoneRepresentation();
|
|
|
|
void
|
|
DestroyChildren(int damage_mode);
|
|
virtual void
|
|
DestroyDamageObjects(){};
|
|
|
|
//This is used to have a pointer to the death entity of the object if it is destroyed.
|
|
Stuff::SlotOf<Entity *>
|
|
m_deathEntity;
|
|
|
|
void
|
|
ApplyVisualDamage(const TakeDamageMessage *message, int armor_zone);
|
|
|
|
virtual bool
|
|
IsDestroyable();
|
|
|
|
DamageObject
|
|
*damageObject;
|
|
int
|
|
isDestroyed;
|
|
int
|
|
visualRepresentation;
|
|
ReplicatorID
|
|
m_whoShotMeLast;
|
|
int
|
|
m_weaponShotMeLast;
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Network Damage support
|
|
//
|
|
int
|
|
damageBit;
|
|
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// Test support
|
|
//
|
|
public:
|
|
void
|
|
TestInstance();
|
|
};
|
|
|
|
//##########################################################################
|
|
//############ Entity::TakeDamageMessage ############################
|
|
//##########################################################################
|
|
|
|
class Entity__TakeDamageMessage:
|
|
public Entity__Message
|
|
{
|
|
public:
|
|
Stuff::Scalar amountOfDamage;
|
|
int amountOfModifier;
|
|
ReplicatorID inflictingEntityID;
|
|
char typeOfDamage;
|
|
Stuff::Normal3D normal;
|
|
Stuff::Point3D hitOffset;
|
|
Stuff::Scalar amountOfHeat;
|
|
bool quickDamage;
|
|
int weaponID;
|
|
|
|
public:
|
|
enum {DefaultWeaponType=-1};
|
|
|
|
Entity__TakeDamageMessage(
|
|
const ReplicatorID &receiving_entity_id,
|
|
const ReplicatorID &inflicting_entity_id,
|
|
Stuff::Scalar damage_amount,
|
|
int damage_modifier,
|
|
char type_of_damage,
|
|
const Stuff::Normal3D& hit_normal,
|
|
const Stuff::Point3D& hit_offset,
|
|
Stuff::Scalar heat_amount,
|
|
bool quick_damage,
|
|
int weapon_id
|
|
):
|
|
Entity__Message(
|
|
Entity::TakeDamageMessageID,
|
|
sizeof(*this),
|
|
Adept::DefaultEventPriority,
|
|
DefaultFlags,
|
|
receiving_entity_id
|
|
)
|
|
, normal(hit_normal)
|
|
, hitOffset(hit_offset)
|
|
{
|
|
inflictingEntityID = inflicting_entity_id;
|
|
amountOfDamage = damage_amount;
|
|
amountOfModifier = damage_modifier;
|
|
typeOfDamage = type_of_damage;
|
|
amountOfHeat = heat_amount;
|
|
quickDamage = quick_damage;
|
|
weaponID = weapon_id;
|
|
}
|
|
};
|
|
|
|
//##########################################################################
|
|
//############ Entity::UpdateMessage ################################
|
|
//##########################################################################
|
|
|
|
class Entity__UpdateMessage:
|
|
public Entity__Message
|
|
{
|
|
public:
|
|
Stuff::LinearMatrix4D
|
|
localToParent;
|
|
|
|
Entity__UpdateMessage(
|
|
const ReplicatorID &replicator_id,
|
|
const Stuff::LinearMatrix4D& local_to_parent
|
|
):
|
|
Entity__Message(
|
|
Entity::UpdateMessageID,
|
|
sizeof(*this),
|
|
Adept::DefaultEventPriority,
|
|
DefaultFlags,
|
|
replicator_id
|
|
),
|
|
localToParent(local_to_parent)
|
|
{}
|
|
};
|
|
|
|
//##########################################################################
|
|
//######## Entity::BecomeInterestingMessage #########################
|
|
//##########################################################################
|
|
|
|
class Entity__BecomeInterestingMessage:
|
|
public Entity__Message
|
|
{
|
|
public:
|
|
bool m_render;
|
|
|
|
Entity__BecomeInterestingMessage(
|
|
const ReplicatorID &replicator_id,
|
|
bool render
|
|
):
|
|
Entity__Message(
|
|
Entity::BecomeInterestingMessageID,
|
|
sizeof(*this),
|
|
Adept::DefaultEventPriority,
|
|
DefaultFlags,
|
|
replicator_id
|
|
),
|
|
m_render(render)
|
|
{}
|
|
};
|
|
|
|
//##########################################################################
|
|
//####################### Attribute Macros ##########################
|
|
//##########################################################################
|
|
|
|
//
|
|
// class name, attribute name, attribute, type
|
|
//
|
|
#define DIRECT_ATTRIBUTE(c,n,a,t)\
|
|
{\
|
|
AttributeEntry *attribute_entry;\
|
|
attribute_entry = new DirectAttributeEntryOf<t, t##ClassID>(\
|
|
c::n##AttributeID,\
|
|
#n,\
|
|
reinterpret_cast<Entity::AttributePointer>(\
|
|
reinterpret_cast<int c::*>(&c::a)\
|
|
)\
|
|
);\
|
|
Register_Object(attribute_entry);\
|
|
Check_Object(DefaultData);\
|
|
DefaultData->attributeTable.AddAttributeEntry(attribute_entry);\
|
|
}
|
|
|
|
//
|
|
// class name, attribute name, attribute, type, class id
|
|
//
|
|
#define CUSTOM_DIRECT_ATTRIBUTE(c,n,a,t,id)\
|
|
{\
|
|
AttributeEntry *attribute_entry;\
|
|
attribute_entry = new DirectAttributeEntryOf<t, id>(\
|
|
c::n##AttributeID,\
|
|
#n,\
|
|
reinterpret_cast<Entity::AttributePointer>(\
|
|
reinterpret_cast<int c::*>(&c::a)\
|
|
)\
|
|
);\
|
|
Register_Object(attribute_entry);\
|
|
Check_Object(DefaultData);\
|
|
DefaultData->attributeTable.AddAttributeEntry(attribute_entry);\
|
|
}
|
|
|
|
//
|
|
// class name, attribute name, attribute, type
|
|
//
|
|
#define INDIRECT_ATTRIBUTE(c,n,a,t)\
|
|
{\
|
|
AttributeEntry *attribute_entry;\
|
|
attribute_entry = new IndirectAttributeEntryOf<t, t##ClassID>(\
|
|
c::n##AttributeID,\
|
|
#n,\
|
|
reinterpret_cast<Entity::AttributePointer>(\
|
|
reinterpret_cast<int c::*>(&c::a)\
|
|
)\
|
|
);\
|
|
Register_Object(attribute_entry);\
|
|
Check_Object(DefaultData);\
|
|
DefaultData->attributeTable.AddAttributeEntry(attribute_entry);\
|
|
}
|
|
|
|
//
|
|
// class name, attribute name, attribute, type
|
|
//
|
|
#define DIRECT_STATE_ATTRIBUTE(c,n,a,t)\
|
|
{\
|
|
AttributeEntry *attribute_entry;\
|
|
attribute_entry = new DirectStateAttributeEntry(\
|
|
c::n##AttributeID,\
|
|
#n,\
|
|
t##ClassID,\
|
|
reinterpret_cast<Entity::AttributePointer>(\
|
|
reinterpret_cast<int c::*>(&c::a)\
|
|
)\
|
|
);\
|
|
Register_Object(attribute_entry);\
|
|
Check_Object(DefaultData);\
|
|
DefaultData->attributeTable.AddAttributeEntry(attribute_entry);\
|
|
}
|
|
|
|
//
|
|
// class name, attribute name, attribute, type
|
|
//
|
|
#define INDIRECT_STATE_ATTRIBUTE(c,n,a,t)\
|
|
{\
|
|
AttributeEntry *attribute_entry;\
|
|
attribute_entry = new IndirectStateAttributeEntry(\
|
|
c::n##AttributeID,\
|
|
#n,\
|
|
t##ClassID,\
|
|
reinterpret_cast<Entity::AttributePointer>(\
|
|
reinterpret_cast<int c::*>(&c::a)\
|
|
)\
|
|
);\
|
|
Register_Object(attribute_entry);\
|
|
Check_Object(DefaultData);\
|
|
DefaultData->attributeTable.AddAttributeEntry(attribute_entry);\
|
|
}
|
|
|
|
//##########################################################################
|
|
//################## Game Model Attribute Macros ####################
|
|
//##########################################################################
|
|
|
|
//
|
|
// class name, attribute name, attribute, type
|
|
//
|
|
#define DIRECT_GAME_MODEL_ATTRIBUTE(c,n,a,t)\
|
|
{\
|
|
ModelAttributeEntry *attribute_entry;\
|
|
attribute_entry = new DirectModelAttributeEntryOf<t, t##ClassID>(\
|
|
c::n##AttributeID,\
|
|
#n,\
|
|
reinterpret_cast<Entity__GameModel::AttributePointer>(\
|
|
reinterpret_cast<int c::*>(&c::a)\
|
|
)\
|
|
);\
|
|
Register_Object(attribute_entry);\
|
|
Check_Object(DefaultData);\
|
|
DefaultData->gameModelAttributeTable.AddAttributeEntry(attribute_entry);\
|
|
}
|
|
|
|
//
|
|
// class name, attribute name, attribute, type, class id
|
|
//
|
|
#define CUSTOM_DIRECT_GAME_MODEL_ATTRIBUTE(c,n,a,t,id)\
|
|
{\
|
|
ModelAttributeEntry *attribute_entry;\
|
|
attribute_entry = new DirectModelAttributeEntryOf<t, id>(\
|
|
c::n##AttributeID,\
|
|
#n,\
|
|
reinterpret_cast<Entity__GameModel::AttributePointer>(\
|
|
reinterpret_cast<int c::*>(&c::a)\
|
|
)\
|
|
);\
|
|
Register_Object(attribute_entry);\
|
|
Check_Object(DefaultData);\
|
|
DefaultData->gameModelAttributeTable.AddAttributeEntry(attribute_entry);\
|
|
}
|
|
|
|
//##########################################################################
|
|
//########################### Entity #################################
|
|
//##########################################################################
|
|
|
|
class Entity__CollisionQuery:
|
|
public ElementRenderer::CollisionQuery
|
|
{
|
|
public:
|
|
Entity
|
|
*m_raySource;
|
|
Entity::CollisionMask
|
|
m_collisionMask;
|
|
|
|
Entity__CollisionQuery(
|
|
Stuff::Line3D *l,
|
|
Stuff::Normal3D *n,
|
|
Entity::CollisionMask m,
|
|
Entity *source
|
|
):
|
|
ElementRenderer::CollisionQuery(l, n),
|
|
m_raySource(source),
|
|
m_collisionMask(m)
|
|
{}
|
|
};
|
|
|
|
class Entity__CollisionData
|
|
#if defined(_ARMOR)
|
|
: public Stuff::Signature
|
|
#endif
|
|
{
|
|
public:
|
|
CollisionVolume
|
|
*m_volume,
|
|
*m_otherVolume;
|
|
Entity
|
|
*m_otherEntity;
|
|
Stuff::Point3D m_worldIntersectionPoint;
|
|
Stuff::Normal3D m_normal;
|
|
Stuff::Normal3D m_otherNormal;
|
|
Stuff::Scalar m_timeSlice;
|
|
BYTE
|
|
m_material;
|
|
|
|
void
|
|
TestInstance() const
|
|
{}
|
|
};
|
|
|
|
}
|
|
|
|
|