source410: engine COMPLETE (165/165) - link reaches PE emission; deep ledger cut
The tlink32 campaign after the checkpoint: eleven engine bodies back-dated from BT412 (rotation player team explode dropzone terrain cultural receiver subsystm app l4gauge - the Application core included), the WinTesla-ectomy handled by backdate.py's new unwrap rules (accessor-fn statics -> 1995 static objects, decl rewrites, pointer->reference Derivation ctor, 2007 windowed- gauge/console-marshal/idle-pump excisions), staged statics TUs opened for the game classes (MECH/BTPLAYER/BTDIRECT/PROJTILE/MISSILE/BTL4MPPR .CPP + L4APP/ NETWORK engine statics). State: every compiled symbol short of the shallow graph RESOLVED (the 52- and 17-symbol ledgers burned to zero); with 32stub.exe in place the linker reaches full vtable closure and emits the deep ledger (~210 symbols, UNRESOLVED- LEDGER.txt): remaining engine bodies (objstrm cstr gauge/gaugrend graphics pixelmap palette resfile ray scnrole explosion-table), the DOS driver extern layer (_SVGA*/_PCSerial*/_PCSPAK*/joystick/netnub/sosMIDI), the full L4App body, and the real game-TU frontier (Mech::Make et al.). Recipe proven for every category. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,29 @@
|
|||||||
|
//===========================================================================//
|
||||||
|
// Project: BattleTech //
|
||||||
|
//---------------------------------------------------------------------------//
|
||||||
|
// Copyright (C) 1995, Virtual World Entertainment, Inc. //
|
||||||
|
// All Rights reserved worldwide //
|
||||||
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
||||||
|
//===========================================================================//
|
||||||
|
|
||||||
|
#include <bt.hpp>
|
||||||
|
#pragma hdrstop
|
||||||
|
|
||||||
|
#if !defined(BTDIRECT_HPP)
|
||||||
|
# include <btdirect.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Derivation
|
||||||
|
BTCameraDirector::ClassDerivations(
|
||||||
|
CameraDirector::ClassDerivations,
|
||||||
|
"BTCameraDirector"
|
||||||
|
);
|
||||||
|
|
||||||
|
BTCameraDirector::SharedData
|
||||||
|
BTCameraDirector::DefaultData(
|
||||||
|
BTCameraDirector::ClassDerivations,
|
||||||
|
CameraDirector::MessageHandlers,
|
||||||
|
CameraDirector::AttributeIndex,
|
||||||
|
1,
|
||||||
|
(Entity::MakeHandler)BTCameraDirector::Make
|
||||||
|
);
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
//===========================================================================//
|
||||||
|
// Project: BattleTech //
|
||||||
|
//---------------------------------------------------------------------------//
|
||||||
|
// Copyright (C) 1995, Virtual World Entertainment, Inc. //
|
||||||
|
// All Rights reserved worldwide //
|
||||||
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
||||||
|
//===========================================================================//
|
||||||
|
|
||||||
|
#include <bt.hpp>
|
||||||
|
#pragma hdrstop
|
||||||
|
|
||||||
|
#if !defined(BTPLAYER_HPP)
|
||||||
|
# include <btplayer.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Derivation
|
||||||
|
BTPlayer::ClassDerivations(
|
||||||
|
Player::ClassDerivations,
|
||||||
|
"BTPlayer"
|
||||||
|
);
|
||||||
|
|
||||||
|
BTPlayer::SharedData
|
||||||
|
BTPlayer::DefaultData(
|
||||||
|
BTPlayer::ClassDerivations,
|
||||||
|
Player::MessageHandlers,
|
||||||
|
Player::AttributeIndex,
|
||||||
|
1,
|
||||||
|
(Entity::MakeHandler)BTPlayer::Make
|
||||||
|
);
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
//===========================================================================//
|
||||||
|
// File: mech.cpp //
|
||||||
|
// Project: BattleTech Brick: Entity Manager //
|
||||||
|
// Contents: Implementation details for the Mech entity //
|
||||||
|
//---------------------------------------------------------------------------//
|
||||||
|
// Date Who Modification //
|
||||||
|
// -------- --- ---------------------------------------------------------- //
|
||||||
|
// //
|
||||||
|
//---------------------------------------------------------------------------//
|
||||||
|
// Copyright (C) 1995, Virtual World Entertainment, Inc. //
|
||||||
|
// All Rights reserved worldwide //
|
||||||
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
||||||
|
//===========================================================================//
|
||||||
|
|
||||||
|
#include <bt.hpp>
|
||||||
|
#pragma hdrstop
|
||||||
|
|
||||||
|
#if !defined(MECH_HPP)
|
||||||
|
# include <mech.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
//#############################################################################
|
||||||
|
//#############################################################################
|
||||||
|
//
|
||||||
|
Derivation
|
||||||
|
Mech::ClassDerivations(
|
||||||
|
JointedMover::ClassDerivations,
|
||||||
|
"Mech"
|
||||||
|
);
|
||||||
|
|
||||||
|
Mech::SharedData
|
||||||
|
Mech::DefaultData(
|
||||||
|
Mech::ClassDerivations,
|
||||||
|
JointedMover::MessageHandlers,
|
||||||
|
JointedMover::AttributeIndex,
|
||||||
|
33,
|
||||||
|
(Entity::MakeHandler)Mech::Make
|
||||||
|
);
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
//===========================================================================//
|
||||||
|
// Project: BattleTech //
|
||||||
|
//---------------------------------------------------------------------------//
|
||||||
|
// Copyright (C) 1995, Virtual World Entertainment, Inc. //
|
||||||
|
// All Rights reserved worldwide //
|
||||||
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
||||||
|
//===========================================================================//
|
||||||
|
|
||||||
|
#include <bt.hpp>
|
||||||
|
#pragma hdrstop
|
||||||
|
|
||||||
|
#if !defined(MISSILE_HPP)
|
||||||
|
# include <missile.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Derivation
|
||||||
|
Missile::ClassDerivations(
|
||||||
|
Projectile::ClassDerivations,
|
||||||
|
"Missile"
|
||||||
|
);
|
||||||
|
|
||||||
|
Missile::SharedData
|
||||||
|
Missile::DefaultData(
|
||||||
|
Missile::ClassDerivations,
|
||||||
|
Mover::MessageHandlers,
|
||||||
|
Mover::AttributeIndex,
|
||||||
|
1,
|
||||||
|
(Entity::MakeHandler)Missile::Make
|
||||||
|
);
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
//===========================================================================//
|
||||||
|
// Project: BattleTech //
|
||||||
|
//---------------------------------------------------------------------------//
|
||||||
|
// Copyright (C) 1995, Virtual World Entertainment, Inc. //
|
||||||
|
// All Rights reserved worldwide //
|
||||||
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
||||||
|
//===========================================================================//
|
||||||
|
|
||||||
|
#include <bt.hpp>
|
||||||
|
#pragma hdrstop
|
||||||
|
|
||||||
|
#if !defined(PROJTILE_HPP)
|
||||||
|
# include <projtile.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Derivation
|
||||||
|
Projectile::ClassDerivations(
|
||||||
|
Mover::ClassDerivations,
|
||||||
|
"Projectile"
|
||||||
|
);
|
||||||
|
|
||||||
|
Projectile::SharedData
|
||||||
|
Projectile::DefaultData(
|
||||||
|
Projectile::ClassDerivations,
|
||||||
|
Mover::MessageHandlers,
|
||||||
|
Mover::AttributeIndex,
|
||||||
|
1,
|
||||||
|
(Entity::MakeHandler)Projectile::Make
|
||||||
|
);
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
//===========================================================================//
|
||||||
|
// Project: BattleTech //
|
||||||
|
//---------------------------------------------------------------------------//
|
||||||
|
// Copyright (C) 1995, Virtual World Entertainment, Inc. //
|
||||||
|
// All Rights reserved worldwide //
|
||||||
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
||||||
|
//===========================================================================//
|
||||||
|
|
||||||
|
#include <bt.hpp>
|
||||||
|
#pragma hdrstop
|
||||||
|
|
||||||
|
#if !defined(BTL4MPPR_HPP)
|
||||||
|
# include <btl4mppr.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Derivation
|
||||||
|
MechThrustmasterMapper::ClassDerivations(
|
||||||
|
Subsystem::ClassDerivations,
|
||||||
|
"MechThrustmasterMapper"
|
||||||
|
);
|
||||||
|
|
||||||
|
MechThrustmasterMapper::SharedData
|
||||||
|
MechThrustmasterMapper::DefaultData(
|
||||||
|
MechThrustmasterMapper::ClassDerivations,
|
||||||
|
Subsystem::MessageHandlers,
|
||||||
|
Subsystem::AttributeIndex,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
|
||||||
|
Derivation
|
||||||
|
MechRIOMapper::ClassDerivations(
|
||||||
|
Subsystem::ClassDerivations,
|
||||||
|
"MechRIOMapper"
|
||||||
|
);
|
||||||
|
|
||||||
|
MechRIOMapper::SharedData
|
||||||
|
MechRIOMapper::DefaultData(
|
||||||
|
MechRIOMapper::ClassDerivations,
|
||||||
|
Subsystem::MessageHandlers,
|
||||||
|
Subsystem::AttributeIndex,
|
||||||
|
1
|
||||||
|
);
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -409,7 +409,7 @@ public:
|
|||||||
static const HandlerEntry
|
static const HandlerEntry
|
||||||
MessageHandlerEntries[];
|
MessageHandlerEntries[];
|
||||||
//static MessageHandlerSet MessageHandlers;
|
//static MessageHandlerSet MessageHandlers;
|
||||||
static MessageHandlerSet& GetMessageHandlers();
|
static MessageHandlerSet MessageHandlers;
|
||||||
|
|
||||||
void
|
void
|
||||||
StateQueryMessageHandler(StateQueryMessage *message);
|
StateQueryMessageHandler(StateQueryMessage *message);
|
||||||
@@ -435,7 +435,7 @@ public:
|
|||||||
// Shared Data Support
|
// Shared Data Support
|
||||||
//
|
//
|
||||||
public:
|
public:
|
||||||
static Derivation *GetClassDerivations();
|
static Derivation ClassDerivations;
|
||||||
static SharedData DefaultData;
|
static SharedData DefaultData;
|
||||||
|
|
||||||
static Logical DoSuppressGauges() { return suppressGauges; }
|
static Logical DoSuppressGauges() { return suppressGauges; }
|
||||||
@@ -505,7 +505,7 @@ protected:
|
|||||||
MakeVideoRenderer();
|
MakeVideoRenderer();
|
||||||
|
|
||||||
virtual GaugeRenderer*
|
virtual GaugeRenderer*
|
||||||
MakeGaugeRenderer(int *secondaryIndex, int *aux1Index, int *aux2Index);
|
MakeGaugeRenderer();
|
||||||
|
|
||||||
virtual ModeManager*
|
virtual ModeManager*
|
||||||
MakeModeManager();
|
MakeModeManager();
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,459 @@
|
|||||||
|
# if !defined(MUNGA_HPP)
|
||||||
|
# include <munga.hpp>
|
||||||
|
# endif
|
||||||
|
#pragma hdrstop
|
||||||
|
|
||||||
|
# if !defined(DROPZONE_HPP)
|
||||||
|
# include <dropzone.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(RANDOM_HPP)
|
||||||
|
# include <random.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(APP_HPP)
|
||||||
|
# include <app.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(HOSTMGR_HPP)
|
||||||
|
# include <hostmgr.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(NTTMGR_HPP)
|
||||||
|
# include <nttmgr.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(NOTATION_HPP)
|
||||||
|
# include <notation.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(NAMELIST_HPP)
|
||||||
|
# include <namelist.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(PLAYER_HPP)
|
||||||
|
# include <player.hpp>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#define DOWN_TIME 5.0f
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
//############################### DropZone #################################
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
// Shared Data Support
|
||||||
|
//
|
||||||
|
Derivation
|
||||||
|
DropZone::ClassDerivations(Entity::ClassDerivations,"DropZone");
|
||||||
|
|
||||||
|
DropZone::SharedData
|
||||||
|
DropZone::DefaultData(
|
||||||
|
DropZone::ClassDerivations,
|
||||||
|
DropZone::MessageHandlers,
|
||||||
|
DropZone::AttributeIndex,
|
||||||
|
DropZone::StateCount,
|
||||||
|
(Entity::MakeHandler)DropZone::Make
|
||||||
|
);
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
// Message Support
|
||||||
|
//
|
||||||
|
const Receiver::HandlerEntry
|
||||||
|
DropZone::MessageHandlerEntries[]=
|
||||||
|
{
|
||||||
|
MESSAGE_ENTRY(DropZone, AssignDropZone)
|
||||||
|
};
|
||||||
|
|
||||||
|
DropZone::MessageHandlerSet
|
||||||
|
DropZone::MessageHandlers(ELEMENTS(DropZone::MessageHandlerEntries), DropZone::MessageHandlerEntries, Entity::MessageHandlers);
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
// Construction and Destruction
|
||||||
|
//
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
DropZone::DropZone(
|
||||||
|
DropZone::MakeMessage *creation_message,
|
||||||
|
DropZone::SharedData &virtual_data
|
||||||
|
):
|
||||||
|
Entity(creation_message, virtual_data)
|
||||||
|
{
|
||||||
|
Check_Pointer(this);
|
||||||
|
Check_Pointer(creation_message);
|
||||||
|
|
||||||
|
SetValidFlag();
|
||||||
|
dropZoneCount = 0;
|
||||||
|
dropZones = NULL;
|
||||||
|
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// Name the drop zone, and enter the zone in the drop zone group
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
//
|
||||||
|
Str_Copy(dropZoneName, creation_message->dropZoneName, sizeof(dropZoneName));
|
||||||
|
EntityManager *entity_manager = application->GetEntityManager();
|
||||||
|
Check(entity_manager);
|
||||||
|
EntityGroup* drop_zones = entity_manager->UseGroup("DropZones");
|
||||||
|
Check(drop_zones);
|
||||||
|
drop_zones->Add(this);
|
||||||
|
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// Now, interpret the data to create the appropriate number of drop zones
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
MemoryStream
|
||||||
|
stream(
|
||||||
|
creation_message,
|
||||||
|
creation_message->messageLength,
|
||||||
|
sizeof(*creation_message)
|
||||||
|
);
|
||||||
|
dropZoneCount = creation_message->dropZoneCount;
|
||||||
|
Verify(dropZoneCount > 0);
|
||||||
|
dropZones = new Origin[dropZoneCount];
|
||||||
|
Register_Pointer(dropZones);
|
||||||
|
lastUsageTime = new Time[dropZoneCount];
|
||||||
|
Register_Pointer(lastUsageTime);
|
||||||
|
lastUsedBy = new EntityID[dropZoneCount];
|
||||||
|
Register_Pointer(lastUsedBy);
|
||||||
|
lastDeathCount = new int[dropZoneCount];
|
||||||
|
Register_Pointer(lastDeathCount);
|
||||||
|
|
||||||
|
for (int i=0; i<dropZoneCount; ++i)
|
||||||
|
{
|
||||||
|
dropZones[i] = *(Origin*)stream.GetPointer();
|
||||||
|
lastUsageTime[i] = Time::Null;
|
||||||
|
lastUsedBy[i] = EntityID::Null;
|
||||||
|
lastDeathCount[i] = -3;
|
||||||
|
stream.AdvancePointer(sizeof(Origin));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
DropZone*
|
||||||
|
DropZone::Make(DropZone::MakeMessage *creation_message)
|
||||||
|
{
|
||||||
|
return new DropZone(creation_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
DropZone::~DropZone()
|
||||||
|
{
|
||||||
|
if (dropZones)
|
||||||
|
{
|
||||||
|
Unregister_Pointer(dropZones);
|
||||||
|
delete[] dropZones;
|
||||||
|
Unregister_Pointer(lastUsageTime);
|
||||||
|
delete[] lastUsageTime;
|
||||||
|
Unregister_Pointer(lastUsedBy);
|
||||||
|
delete[] lastUsedBy;
|
||||||
|
Unregister_Pointer(lastDeathCount);
|
||||||
|
delete[] lastDeathCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
// Dropzone assignment
|
||||||
|
//
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Logical
|
||||||
|
DropZone::IsAvailable(int index)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Verify(index >= 0 && index < dropZoneCount);
|
||||||
|
Check(application);
|
||||||
|
|
||||||
|
return
|
||||||
|
!lastUsageTime[index].ticks
|
||||||
|
|| Now() - lastUsageTime[index] > DOWN_TIME
|
||||||
|
&& application->GetApplicationState() == Application::RunningMission;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
DropZone::AssignDropZoneMessageHandler(AssignDropZoneMessage* message)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check_Pointer(message);
|
||||||
|
|
||||||
|
Check(application);
|
||||||
|
HostManager *host = application->GetHostManager();
|
||||||
|
Check(host);
|
||||||
|
Entity *entity = host->GetEntityPointer(message->requestingEntity);
|
||||||
|
Check(entity);
|
||||||
|
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// If we have allocated a dropzone within the last ten seconds for this
|
||||||
|
// player, resend the data
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
Origin *drop_zone = NULL;
|
||||||
|
int
|
||||||
|
lowest, highest, remaining, i;
|
||||||
|
for (i=0; i<dropZoneCount; ++i)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
!IsAvailable(i)
|
||||||
|
&& lastUsedBy[i] == message->requestingEntity
|
||||||
|
&& lastDeathCount[i] == message->deathCount
|
||||||
|
)
|
||||||
|
{
|
||||||
|
lastUsageTime[i] = Now();
|
||||||
|
drop_zone = &dropZones[i];
|
||||||
|
goto Found_One;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Figure out how many drop zones are available. If none are, repost this
|
||||||
|
// message to ourself
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
lowest = dropZoneCount;
|
||||||
|
highest = -1;
|
||||||
|
remaining = 0;
|
||||||
|
for (i=0; i<dropZoneCount; ++i)
|
||||||
|
{
|
||||||
|
if (IsAvailable(i))
|
||||||
|
{
|
||||||
|
++remaining;
|
||||||
|
if (i < lowest)
|
||||||
|
{
|
||||||
|
lowest = i;
|
||||||
|
}
|
||||||
|
if (i > highest)
|
||||||
|
{
|
||||||
|
highest = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// Now, randomly look about until we find one available
|
||||||
|
//-----------------------------------------------------
|
||||||
|
//
|
||||||
|
highest = highest - lowest + 1;
|
||||||
|
while (remaining)
|
||||||
|
{
|
||||||
|
i = lowest + Random(highest);
|
||||||
|
Verify(i < dropZoneCount && i >= 0);
|
||||||
|
if (IsAvailable(i))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Check to see if vehicle attached to a player is within 2 meters of
|
||||||
|
// this drop zone. If so, mark it unavailable for 3 seconds
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
EntityManager *entity_mgr = application->GetEntityManager();
|
||||||
|
Check(entity_mgr);
|
||||||
|
EntityGroup *player_group = entity_mgr->FindGroup("Players");
|
||||||
|
if (
|
||||||
|
player_group
|
||||||
|
&& application->GetApplicationState()
|
||||||
|
== Application::RunningMission
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Player *player;
|
||||||
|
ChainIteratorOf<Node*> iterator(player_group->groupMembers);
|
||||||
|
while ((player = (Player*)iterator.ReadAndNext()) != NULL)
|
||||||
|
{
|
||||||
|
Check(player);
|
||||||
|
Entity *vehicle = player->GetPlayerVehicle();
|
||||||
|
if (vehicle && player != entity)
|
||||||
|
{
|
||||||
|
Check(vehicle);
|
||||||
|
Vector3D distance;
|
||||||
|
distance.Subtract(
|
||||||
|
vehicle->localOrigin.linearPosition,
|
||||||
|
dropZones[i].linearPosition
|
||||||
|
);
|
||||||
|
if (distance.LengthSquared() <= 4.0f)
|
||||||
|
{
|
||||||
|
lastUsedBy[i] = NULL;
|
||||||
|
lastUsageTime[i] = Now();
|
||||||
|
lastUsageTime[i] -= DOWN_TIME - 1.0f;
|
||||||
|
--remaining;
|
||||||
|
if (i == lowest)
|
||||||
|
{
|
||||||
|
++lowest;
|
||||||
|
--highest;
|
||||||
|
}
|
||||||
|
else if (i == lowest + highest - 1)
|
||||||
|
{
|
||||||
|
--highest;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------
|
||||||
|
// If someone was in this spot, keep looking for another one
|
||||||
|
//----------------------------------------------------------
|
||||||
|
//
|
||||||
|
if (player)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastUsageTime[i] = Now();
|
||||||
|
drop_zone = &dropZones[i];
|
||||||
|
lastUsedBy[i] = message->requestingEntity;
|
||||||
|
lastDeathCount[i] = message->deathCount;
|
||||||
|
remaining = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
// If no drop_zone could be found, repost the message to ourselves
|
||||||
|
//----------------------------------------------------------------
|
||||||
|
//
|
||||||
|
if (!drop_zone)
|
||||||
|
{
|
||||||
|
Time when=Now();
|
||||||
|
when += 0.1f;
|
||||||
|
application->Post(MaxEventPriority, this, message, when);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// Send a message back to the requesting object what sent this message
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
Found_One:
|
||||||
|
ReplyMessage
|
||||||
|
reply(
|
||||||
|
message->replyMessageID,
|
||||||
|
sizeof(ReplyMessage),
|
||||||
|
*drop_zone,
|
||||||
|
message->deathCount
|
||||||
|
);
|
||||||
|
entity->Dispatch(&reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Logical
|
||||||
|
DropZone::CreateMakeMessage(
|
||||||
|
MakeMessage *creation_message,
|
||||||
|
const char* model_name,
|
||||||
|
const char* resource_name,
|
||||||
|
NotationFile *map_file
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Check(creation_message);
|
||||||
|
Check(map_file);
|
||||||
|
Check_Pointer(model_name);
|
||||||
|
Check_Pointer(resource_name);
|
||||||
|
|
||||||
|
if (!Entity::CreateMakeMessage(creation_message, map_file, NULL))
|
||||||
|
{
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
creation_message->classToCreate = RegisteredClass::DropZoneClassID;
|
||||||
|
creation_message->instanceFlags = MapFlag|TrappedFlag;
|
||||||
|
|
||||||
|
//
|
||||||
|
//-----------------------------------------------
|
||||||
|
// Count up the number of drop zones in our model
|
||||||
|
//-----------------------------------------------
|
||||||
|
//
|
||||||
|
Enumeration save_modes = map_file->GetModes();
|
||||||
|
map_file->SetMode(NotationFile::CleanListMode);
|
||||||
|
|
||||||
|
NameList *zone_list =
|
||||||
|
map_file->MakeEntryList(model_name, "dropzone");
|
||||||
|
Register_Object(zone_list);
|
||||||
|
creation_message->dropZoneCount = zone_list->EntryCount();
|
||||||
|
creation_message->messageLength =
|
||||||
|
sizeof(*creation_message)
|
||||||
|
+ creation_message->dropZoneCount*sizeof(Origin);
|
||||||
|
if (!creation_message->dropZoneCount)
|
||||||
|
{
|
||||||
|
cout << "Error: " << model_name << " hasn't specified any drop zones!\n";
|
||||||
|
Dump_And_Die:
|
||||||
|
Unregister_Object(zone_list);
|
||||||
|
delete zone_list;
|
||||||
|
map_file->PutModes(save_modes);
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//---------------------------------------------
|
||||||
|
// Allocate a buffer to hold the drop zone data
|
||||||
|
//---------------------------------------------
|
||||||
|
//
|
||||||
|
MemoryStream
|
||||||
|
stream(
|
||||||
|
creation_message,
|
||||||
|
creation_message->messageLength,
|
||||||
|
sizeof(*creation_message)
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
//----------------------------
|
||||||
|
// zero out the drop zone name
|
||||||
|
//----------------------------
|
||||||
|
//
|
||||||
|
for (int ii=0; ii<sizeof(creation_message->dropZoneName); ii++)
|
||||||
|
{
|
||||||
|
creation_message->dropZoneName[ii] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
Str_Copy(
|
||||||
|
creation_message->dropZoneName,
|
||||||
|
resource_name,
|
||||||
|
sizeof(creation_message->dropZoneName)
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
//-----------------
|
||||||
|
// Read in the data
|
||||||
|
//-----------------
|
||||||
|
//
|
||||||
|
NameList::Entry *drop_zone = zone_list->GetFirstEntry();
|
||||||
|
while (drop_zone)
|
||||||
|
{
|
||||||
|
Point3D translation;
|
||||||
|
EulerAngles tmp_rotation;
|
||||||
|
|
||||||
|
const char* zone_data = drop_zone->GetChar();
|
||||||
|
sscanf(
|
||||||
|
zone_data,
|
||||||
|
"%f %f %f %f %f %f",
|
||||||
|
&translation.x,
|
||||||
|
&translation.y,
|
||||||
|
&translation.z,
|
||||||
|
&tmp_rotation.pitch,
|
||||||
|
&tmp_rotation.yaw,
|
||||||
|
&tmp_rotation.roll
|
||||||
|
);
|
||||||
|
|
||||||
|
((Origin*)stream.GetPointer())->linearPosition = translation;
|
||||||
|
((Origin*)stream.GetPointer())->angularPosition = tmp_rotation;
|
||||||
|
stream.AdvancePointer(sizeof(Origin));
|
||||||
|
drop_zone = drop_zone->GetNextEntry();
|
||||||
|
}
|
||||||
|
|
||||||
|
Unregister_Object(zone_list);
|
||||||
|
delete zone_list;
|
||||||
|
map_file->PutModes(save_modes);
|
||||||
|
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logical
|
||||||
|
DropZone::TestInstance() const
|
||||||
|
{
|
||||||
|
return IsDerivedFrom(ClassDerivations);
|
||||||
|
}
|
||||||
@@ -0,0 +1,794 @@
|
|||||||
|
# if !defined(MUNGA_HPP)
|
||||||
|
# include <munga.hpp>
|
||||||
|
# endif
|
||||||
|
#pragma hdrstop
|
||||||
|
|
||||||
|
# if !defined(EXPLODE_HPP)
|
||||||
|
# include <explode.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(MOVER_HPP)
|
||||||
|
# include <mover.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(BOXSOLID_HPP)
|
||||||
|
# include <boxsolid.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(COLLASST_HPP)
|
||||||
|
# include <collasst.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(DAMAGE_HPP)
|
||||||
|
# include <damage.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(RANDOM_HPP)
|
||||||
|
# include <random.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(APP_HPP)
|
||||||
|
# include <app.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(OBJSTRM_HPP)
|
||||||
|
# include <objstrm.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(HOSTMGR_HPP)
|
||||||
|
# include <hostmgr.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(NOTATION_HPP)
|
||||||
|
# include <notation.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(NAMELIST_HPP)
|
||||||
|
# include <namelist.hpp>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
//############################ Explosion ################################
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
// Shared Data Support
|
||||||
|
//
|
||||||
|
Derivation
|
||||||
|
Explosion::ClassDerivations(Entity::ClassDerivations, "Explosion");
|
||||||
|
|
||||||
|
Explosion::SharedData
|
||||||
|
Explosion::DefaultData(
|
||||||
|
Explosion::ClassDerivations,
|
||||||
|
Explosion::MessageHandlers,
|
||||||
|
Explosion::AttributeIndex,
|
||||||
|
Explosion::StateCount,
|
||||||
|
(Entity::MakeHandler)Explosion::Make
|
||||||
|
);
|
||||||
|
|
||||||
|
void
|
||||||
|
Explosion::ExplosionSimulation(Scalar)
|
||||||
|
{
|
||||||
|
Check(application);
|
||||||
|
if ((Now() - creationTime) > explosionDuration)
|
||||||
|
{
|
||||||
|
CondemnToDeathRow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void Explosion::SplashDamage
|
||||||
|
( EntityID inflicting,
|
||||||
|
Damage &damage,
|
||||||
|
Scalar collisionRadius,
|
||||||
|
Vector3D offset,
|
||||||
|
Entity * excluded) // Excluded should really be a set of entities!
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check(entityHit);
|
||||||
|
if (excluded)
|
||||||
|
{
|
||||||
|
Check(excluded);
|
||||||
|
}
|
||||||
|
Check_Pointer(&damage);
|
||||||
|
Verify(0 < collisionRadius);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// The list of volumes we intersect
|
||||||
|
//
|
||||||
|
BoxedSolidCollisionList collision_list;
|
||||||
|
collision_list.Reset();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create the collision assistant to check movers against
|
||||||
|
//
|
||||||
|
CollisionAssistant *collision_assistant;
|
||||||
|
|
||||||
|
collision_assistant = new CollisionAssistant(entityHit->GetInterestZoneID());
|
||||||
|
Register_Object(collision_assistant);
|
||||||
|
Check(collision_assistant);
|
||||||
|
|
||||||
|
BoxedSolidResource box;
|
||||||
|
Check_Pointer(&box);
|
||||||
|
box.solidType = BoxedSolid::YAxisCylinderType;
|
||||||
|
box.materialType = BoxedSolid::ConcreteMaterial;
|
||||||
|
const Vector3D min = Vector3D(-collisionRadius,-collisionRadius,-collisionRadius);
|
||||||
|
const Vector3D max = Vector3D(collisionRadius,collisionRadius,collisionRadius);
|
||||||
|
ExtentBox ext_box = ExtentBox(min,max);
|
||||||
|
box.solidExtents = ext_box;
|
||||||
|
box.sliceExtents = ext_box;
|
||||||
|
|
||||||
|
BoxedSolidResource local_box;
|
||||||
|
local_box.Instance(box,localOrigin);
|
||||||
|
|
||||||
|
BoxedSolid *splash_volume = BoxedSolid::MakeBoxedSolid(&local_box, this, NULL);
|
||||||
|
Register_Object(splash_volume);
|
||||||
|
|
||||||
|
//
|
||||||
|
//---------------------------------
|
||||||
|
// Test against the tangible movers
|
||||||
|
//---------------------------------
|
||||||
|
//
|
||||||
|
Check(collision_assistant);
|
||||||
|
CollisionAssistant::MovingEntityIterator iterator(collision_assistant);
|
||||||
|
Entity *entity;
|
||||||
|
Mover *mover;
|
||||||
|
Check(splash_volume);
|
||||||
|
while ((entity = iterator.ReadAndNext()) != NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
// If we are checking against ourselves, skip it
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
Check(entity);
|
||||||
|
if (entity == this)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//--------------------------------------------------
|
||||||
|
// If we have a mover class object, check against it
|
||||||
|
//--------------------------------------------------
|
||||||
|
//
|
||||||
|
if (entity->IsDerivedFrom(Mover::ClassDerivations))
|
||||||
|
{
|
||||||
|
mover = Cast_Object(Mover *,entity);
|
||||||
|
Check(mover);
|
||||||
|
|
||||||
|
mover->CheckVolumeAgainstBoxedSolidChain(&collision_list, splash_volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// Test against the static world
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
InterestManager *interest_mgr = application->GetInterestManager();
|
||||||
|
Check(interest_mgr);
|
||||||
|
InterestZone *zone = interest_mgr->GetInterestZone(interestZoneID);
|
||||||
|
Check(zone);
|
||||||
|
BoxedSolidTree* tree = zone->GetCollisionRoot();
|
||||||
|
Check(tree);
|
||||||
|
tree->FindBoundingBoxesContaining(
|
||||||
|
splash_volume,
|
||||||
|
collision_list
|
||||||
|
);
|
||||||
|
|
||||||
|
Check_Fpu();
|
||||||
|
Unregister_Object(collision_assistant);
|
||||||
|
delete collision_assistant;
|
||||||
|
Unregister_Object(splash_volume);
|
||||||
|
delete splash_volume;
|
||||||
|
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// Make a sorted list of all the entities from the collision list,
|
||||||
|
// sorted by their distance from the explosion's origin.
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
VChainOf<Entity*,Vector3D> radius_chain(NULL,False);
|
||||||
|
VChainIteratorOf<Entity*,Vector3D> radius_chain_iterator(radius_chain);
|
||||||
|
|
||||||
|
Vector3D radius;
|
||||||
|
Entity *target_entity;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
for(int i = 0;i < collision_list.GetCollisionCount(); i++)
|
||||||
|
{
|
||||||
|
BoxedSolidCollision bsc = collision_list[i];
|
||||||
|
Check(&bsc);
|
||||||
|
target_entity = (Entity*) ((bsc.GetTreeVolume())->GetOwningSimulation());
|
||||||
|
Check(target_entity);
|
||||||
|
Verify(target_entity->IsDerivedFrom(Entity::ClassDerivations));
|
||||||
|
if ((target_entity != entityHit) && (target_entity != this) && (target_entity != excluded))
|
||||||
|
{
|
||||||
|
radius = Vector3D::Identity;
|
||||||
|
radius.Subtract(target_entity->localOrigin.linearPosition,localOrigin.linearPosition);
|
||||||
|
radius_chain.AddValue(target_entity, radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// While remaining_bursts > 0, advance through list, pick a number of bursts
|
||||||
|
// to inflict, and call SendDamage to the current entity.
|
||||||
|
|
||||||
|
Damage some_damage = damage;
|
||||||
|
int possible_targets = 0;
|
||||||
|
int damageable_targets = 0;
|
||||||
|
radius_chain_iterator.First();
|
||||||
|
while ((target_entity = (Entity*) radius_chain_iterator.GetCurrent()) != NULL)
|
||||||
|
{
|
||||||
|
Check(target_entity);
|
||||||
|
radius = radius_chain_iterator.GetValue();
|
||||||
|
radius_chain_iterator.Next();
|
||||||
|
possible_targets++;
|
||||||
|
if (target_entity->damageZones)
|
||||||
|
{
|
||||||
|
|
||||||
|
damageable_targets++;
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Set the damage data
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
some_damage.burstCount =damage.burstCount / (pow(radius.Length(), 1.2f));
|
||||||
|
Min_Clamp(some_damage.burstCount,1);
|
||||||
|
#if DEBUG_LEVEL > 0
|
||||||
|
DEBUG_STREAM << "At radius " << radius.Length() << ", applied burstCount is " << some_damage.burstCount << endl << flush;
|
||||||
|
DEBUG_STREAM << "Damage per burst is " << some_damage.damageAmount << endl << flush;
|
||||||
|
#endif
|
||||||
|
Vector3D force = Vector3D::Identity;
|
||||||
|
force.Multiply(radius,localToWorld);
|
||||||
|
some_damage.damageForce = force;
|
||||||
|
Point3D origin_point = Point3D::Identity;
|
||||||
|
origin_point.Add(localOrigin.linearPosition,offset);
|
||||||
|
some_damage.impactPoint = origin_point;
|
||||||
|
//some_damage.impactPoint.Add(origin_point,radius);
|
||||||
|
|
||||||
|
//
|
||||||
|
//------------------------------------------
|
||||||
|
// Send a damage message to the current target entity
|
||||||
|
//------------------------------------------
|
||||||
|
//
|
||||||
|
|
||||||
|
if (target_entity->GetEntityID() == inflicting)
|
||||||
|
{
|
||||||
|
DEBUG_STREAM << "Splash damage hurting inflicting entity." << endl << flush;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (excluded && target_entity->GetEntityID() == excluded->GetEntityID() )
|
||||||
|
{
|
||||||
|
DEBUG_STREAM << "Splash damage hurting excluded entity!" << endl << flush;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity::TakeDamageMessage take_damage(
|
||||||
|
Entity::TakeDamageMessageID,
|
||||||
|
sizeof(Entity::TakeDamageMessage),
|
||||||
|
inflicting,
|
||||||
|
-1, // We can't know what damage zone we hit
|
||||||
|
some_damage
|
||||||
|
);
|
||||||
|
target_entity->Dispatch(&take_damage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG_LEVEL >0
|
||||||
|
DEBUG_STREAM << "There were " << possible_targets << "entities within range, only " << damageable_targets << " had damage zones" << endl << flush;
|
||||||
|
#endif
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
// Construction and Destruction
|
||||||
|
//
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Explosion::Explosion(
|
||||||
|
Explosion::MakeMessage *creation_message,
|
||||||
|
Explosion::SharedData &virtual_data
|
||||||
|
):
|
||||||
|
Entity(creation_message, virtual_data)
|
||||||
|
{
|
||||||
|
Check_Pointer(this);
|
||||||
|
Check_Pointer(creation_message);
|
||||||
|
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// zero out any rotation
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
localOrigin.angularPosition = Quaternion::Identity;
|
||||||
|
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Get the explosion model resource
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
ResourceDescription *resource_description;
|
||||||
|
ModelResource *model_resource;
|
||||||
|
|
||||||
|
Check(application);
|
||||||
|
Check(application->GetResourceFile());
|
||||||
|
resource_description =
|
||||||
|
application->GetResourceFile()->SearchList(
|
||||||
|
resourceID,
|
||||||
|
ResourceDescription::GameModelResourceType
|
||||||
|
);
|
||||||
|
Check(resource_description);
|
||||||
|
resource_description->Lock();
|
||||||
|
model_resource = (ModelResource*)resource_description->resourceAddress;
|
||||||
|
Check_Pointer(model_resource);
|
||||||
|
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Get the creating entity and entity hit by explosion
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Check(application->GetHostManager());
|
||||||
|
entityHit =
|
||||||
|
application->GetHostManager()->GetEntityPointer(
|
||||||
|
creation_message->entityHitID
|
||||||
|
);
|
||||||
|
Check(entityHit);
|
||||||
|
|
||||||
|
if (creation_message->creatingEntityID != EntityID::Null)
|
||||||
|
{
|
||||||
|
creatingEntity =
|
||||||
|
application->GetHostManager()->GetEntityPointer(
|
||||||
|
creation_message->creatingEntityID
|
||||||
|
);
|
||||||
|
Check(creatingEntity);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
creatingEntity = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Calculate the localHitPosition in terms
|
||||||
|
// local coordinate system of the entityHit
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
localHitPosition.MultiplyByInverse(
|
||||||
|
localOrigin.linearPosition,
|
||||||
|
entityHit->localToWorld
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Get the explosion duration
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
explosionDuration = model_resource->explosionDuration;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// If an explosion resource table is being used then
|
||||||
|
// use it to set the resource
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
if (model_resource->resourceTableObjectID != NullObjectID)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// If the explosion hit us, set the material to our craft,
|
||||||
|
// If the explosion hit an opponent, set the material to other craft,
|
||||||
|
// If the explosion hit something else then get the material...
|
||||||
|
//
|
||||||
|
Enumeration material_type;
|
||||||
|
|
||||||
|
Check(application);
|
||||||
|
Entity *viewpoint_entity = application->GetViewpointEntity();
|
||||||
|
Check(viewpoint_entity);
|
||||||
|
Verify(creation_message->entityHitID != EntityID::Null);
|
||||||
|
|
||||||
|
// ECH 8/25/95 - Is this the best way to get our vehicle?
|
||||||
|
if (
|
||||||
|
creation_message->entityHitID ==
|
||||||
|
viewpoint_entity->GetEntityID()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
material_type = BoxedSolid::OurCraftMaterial;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ECH 8/25/95 - Is this the best way to identify other vehicles?
|
||||||
|
if (
|
||||||
|
entityHit != NULL &&
|
||||||
|
entityHit->GetPlayerLink() != NULL
|
||||||
|
)
|
||||||
|
{
|
||||||
|
material_type = BoxedSolid::OtherCraftMaterial;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ECH 8/25/95 - How to get material? Just use this for now.
|
||||||
|
material_type = BoxedSolid::ConcreteMaterial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get resource table pointer,
|
||||||
|
// Then set the appropriate resource ID
|
||||||
|
//
|
||||||
|
Plug *plug;
|
||||||
|
ExplosionResourceTable *resource_table;
|
||||||
|
ResourceDescription::ResourceID new_resource_ID;
|
||||||
|
|
||||||
|
plug = PlugStreamManager::FindPlug(model_resource->resourceTableObjectID);
|
||||||
|
resource_table = Cast_Object(ExplosionResourceTable*, plug);
|
||||||
|
Check(resource_table);
|
||||||
|
new_resource_ID = resource_table->FindResourceID(material_type);
|
||||||
|
if (new_resource_ID != ResourceDescription::NullResourceID)
|
||||||
|
{
|
||||||
|
resourceID = new_resource_ID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// If an explosion resource table is being used then
|
||||||
|
// use it to set the resource
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
if (model_resource->resourceTableObjectID != NullObjectID)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Get resource table pointer,
|
||||||
|
// Then set the appropriate resource ID
|
||||||
|
//
|
||||||
|
Plug *plug;
|
||||||
|
ExplosionResourceTable *resource_table;
|
||||||
|
ResourceDescription::ResourceID new_resource_ID;
|
||||||
|
|
||||||
|
plug = PlugStreamManager::FindPlug(model_resource->resourceTableObjectID);
|
||||||
|
resource_table = Cast_Object(ExplosionResourceTable*, plug);
|
||||||
|
Check(resource_table);
|
||||||
|
new_resource_ID = resource_table->FindResourceID(entityHit);
|
||||||
|
if (new_resource_ID != ResourceDescription::NullResourceID)
|
||||||
|
{
|
||||||
|
resourceID = new_resource_ID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Set performance and entity validity
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
resource_description->Unlock();
|
||||||
|
SetPerformance(&Explosion::ExplosionSimulation);
|
||||||
|
SetValidFlag();
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Explosion*
|
||||||
|
Explosion::Make(Explosion::MakeMessage *creation_message)
|
||||||
|
{
|
||||||
|
Check(application);
|
||||||
|
HostManager *host_mgr = application->GetHostManager();
|
||||||
|
Check(host_mgr);
|
||||||
|
Entity *entity = host_mgr->GetEntityPointer(creation_message->entityHitID);
|
||||||
|
if (entity)
|
||||||
|
{
|
||||||
|
return new Explosion(creation_message);
|
||||||
|
}
|
||||||
|
Tell(
|
||||||
|
"Warning: Explosion ignored - entity " << creation_message->entityHitID
|
||||||
|
<< " couldn't be found!\n"
|
||||||
|
);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Explosion::~Explosion()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Logical
|
||||||
|
Explosion::TestInstance() const
|
||||||
|
{
|
||||||
|
return IsDerivedFrom(ClassDerivations);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// CreateModelResource
|
||||||
|
//
|
||||||
|
ResourceDescription::ResourceID
|
||||||
|
Explosion::CreateModelResource(
|
||||||
|
ResourceFile *resource_file,
|
||||||
|
const char *model_name,
|
||||||
|
NotationFile *model_file,
|
||||||
|
const ResourceDirectories*
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Check(resource_file);
|
||||||
|
Check_Pointer(model_name);
|
||||||
|
Check(model_file);
|
||||||
|
|
||||||
|
ModelResource local_model;
|
||||||
|
if(
|
||||||
|
!model_file->GetEntry(
|
||||||
|
"gamedata",
|
||||||
|
"ExplosionDuration",
|
||||||
|
&local_model.explosionDuration
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
cerr<<model_file<<" missing ExplosionDuration"<<endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// If there exists the name of an explosion resource table then write
|
||||||
|
// its object ID
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
const char *resource_table_name;
|
||||||
|
|
||||||
|
if(
|
||||||
|
model_file->GetEntry(
|
||||||
|
"gamedata",
|
||||||
|
"ExplosionResourceTable",
|
||||||
|
&resource_table_name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Get the object ID and set it in the model resource
|
||||||
|
//
|
||||||
|
local_model.resourceTableObjectID =
|
||||||
|
PlugStreamManager::FindPlugName(resource_table_name);
|
||||||
|
if (local_model.resourceTableObjectID == NullObjectID)
|
||||||
|
{
|
||||||
|
cout << "resource_table_name == " << resource_table_name << "\n";
|
||||||
|
Fail("Explosion::CreateModelResource - ExplosionResourceTable not found");
|
||||||
|
}
|
||||||
|
Verify(local_model.resourceTableObjectID != NullObjectID);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
local_model.resourceTableObjectID = NullObjectID;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceDescription *resource_description =
|
||||||
|
resource_file->AddResource(
|
||||||
|
model_name,
|
||||||
|
ResourceDescription::GameModelResourceType,
|
||||||
|
1,
|
||||||
|
ResourceDescription::Preload,
|
||||||
|
&local_model,
|
||||||
|
sizeof(ModelResource)
|
||||||
|
);
|
||||||
|
Check(resource_description);
|
||||||
|
return resource_description->resourceID;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Enumeration
|
||||||
|
Explosion::GetInterestPriority(Entity *linked_entity)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check(linked_entity);
|
||||||
|
|
||||||
|
return
|
||||||
|
(
|
||||||
|
(linked_entity == creatingEntity) ?
|
||||||
|
HighInterestPriority :
|
||||||
|
LowInterestPriority
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
//###################### ExplosionResourceTable #########################
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
//
|
||||||
|
//#############################################################################
|
||||||
|
//#############################################################################
|
||||||
|
//
|
||||||
|
ExplosionResourceTable::ExplosionResourceTable(PlugStream *stream):
|
||||||
|
Plug(stream),
|
||||||
|
resourceIDSocket(NULL, True)
|
||||||
|
{
|
||||||
|
Check(stream);
|
||||||
|
Check(&resourceIDSocket);
|
||||||
|
|
||||||
|
CollectionSize table_size;
|
||||||
|
*stream >> table_size;
|
||||||
|
|
||||||
|
for (CollectionSize i = 0; i < table_size; i++)
|
||||||
|
{
|
||||||
|
Enumeration material_type;
|
||||||
|
ResourceDescription::ResourceID resource_ID;
|
||||||
|
ResourceIDPlug *resource_ID_Plug;
|
||||||
|
|
||||||
|
*stream >> material_type >> resource_ID;
|
||||||
|
|
||||||
|
resource_ID_Plug = new ResourceIDPlug(resource_ID);
|
||||||
|
Register_Object(resource_ID_Plug);
|
||||||
|
resourceIDSocket.AddValue(resource_ID_Plug, material_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//#############################################################################
|
||||||
|
//#############################################################################
|
||||||
|
//
|
||||||
|
ExplosionResourceTable::~ExplosionResourceTable()
|
||||||
|
{
|
||||||
|
TableIteratorOf<ResourceIDPlug*, Enumeration>
|
||||||
|
iterator(&resourceIDSocket);
|
||||||
|
|
||||||
|
Check(&iterator);
|
||||||
|
iterator.DeletePlugs();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//#############################################################################
|
||||||
|
//#############################################################################
|
||||||
|
//
|
||||||
|
void
|
||||||
|
ExplosionResourceTable::BuildFromPage(
|
||||||
|
ObjectStream *stream,
|
||||||
|
NameList *name_list,
|
||||||
|
ClassID class_ID,
|
||||||
|
ObjectID object_ID
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Check(stream);
|
||||||
|
Check(name_list);
|
||||||
|
|
||||||
|
Plug::BuildFromPage(stream, name_list, class_ID, object_ID);
|
||||||
|
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Write number of entries
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
CollectionSize table_size = 0;
|
||||||
|
NameList::Entry *entry;
|
||||||
|
|
||||||
|
Check(name_list);
|
||||||
|
entry = name_list->GetFirstEntry();
|
||||||
|
while (entry != NULL)
|
||||||
|
{
|
||||||
|
Check(entry);
|
||||||
|
if (entry->IsName("table_entry"))
|
||||||
|
table_size++;
|
||||||
|
entry = entry->GetNextEntry();
|
||||||
|
}
|
||||||
|
*stream << table_size;
|
||||||
|
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Write entries
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
#if DEBUG_LEVEL>0
|
||||||
|
CollectionSize i = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Check(name_list);
|
||||||
|
entry = name_list->GetFirstEntry();
|
||||||
|
while (entry != NULL)
|
||||||
|
{
|
||||||
|
Check(entry);
|
||||||
|
if (entry->IsName("table_entry"))
|
||||||
|
{
|
||||||
|
CString table_entry, token;
|
||||||
|
Enumeration material_type;
|
||||||
|
ResourceDescription *resource_description;
|
||||||
|
ResourceDescription::ResourceID resource_ID;
|
||||||
|
|
||||||
|
Check_Pointer(entry->GetChar());
|
||||||
|
table_entry = entry->GetChar();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Material
|
||||||
|
//
|
||||||
|
Check_Pointer(table_entry.GetNthToken(0));
|
||||||
|
material_type = atol(table_entry.GetNthToken(0));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Resource
|
||||||
|
//
|
||||||
|
Check_Pointer(table_entry.GetNthToken(1));
|
||||||
|
Check(stream->GetResourceFile());
|
||||||
|
resource_description =
|
||||||
|
stream->GetResourceFile()->FindResourceDescription(
|
||||||
|
table_entry.GetNthToken(1),
|
||||||
|
ResourceDescription::ModelListResourceType
|
||||||
|
);
|
||||||
|
Check(resource_description);
|
||||||
|
resource_ID = resource_description->resourceID;
|
||||||
|
|
||||||
|
*stream << material_type << resource_ID;
|
||||||
|
#if DEBUG_LEVEL>0
|
||||||
|
i++;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
entry = entry->GetNextEntry();
|
||||||
|
}
|
||||||
|
#if DEBUG_LEVEL>0
|
||||||
|
Verify(i == table_size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//#############################################################################
|
||||||
|
//#############################################################################
|
||||||
|
//
|
||||||
|
Logical
|
||||||
|
ExplosionResourceTable::TestInstance() const
|
||||||
|
{
|
||||||
|
Plug::TestInstance();
|
||||||
|
Check(&resourceIDSocket);
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//#############################################################################
|
||||||
|
//#############################################################################
|
||||||
|
//
|
||||||
|
ResourceDescription::ResourceID
|
||||||
|
ExplosionResourceTable::FindResourceID(Enumeration material_type)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
|
||||||
|
ResourceIDPlug *resource_ID_Plug;
|
||||||
|
if ((resource_ID_Plug = resourceIDSocket.Find(material_type)) != NULL)
|
||||||
|
{
|
||||||
|
Check(resource_ID_Plug);
|
||||||
|
return resource_ID_Plug->GetItem();
|
||||||
|
}
|
||||||
|
return ResourceDescription::NullResourceID;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//#############################################################################
|
||||||
|
//#############################################################################
|
||||||
|
//
|
||||||
|
ResourceDescription::ResourceID
|
||||||
|
ExplosionResourceTable::FindResourceID(Entity *entity_hit)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check(entity_hit);
|
||||||
|
|
||||||
|
//
|
||||||
|
// If the explosion hit us, set the material to our craft,
|
||||||
|
// If the explosion hit an opponent, set the material to other craft,
|
||||||
|
// If the explosion hit something else then get the material...
|
||||||
|
//
|
||||||
|
Enumeration material_type;
|
||||||
|
Entity *viewpoint_entity;
|
||||||
|
|
||||||
|
Check(application);
|
||||||
|
viewpoint_entity = application->GetViewpointEntity();
|
||||||
|
Check(viewpoint_entity);
|
||||||
|
|
||||||
|
// ECH 8/25/95 - Is this the best way to get our vehicle?
|
||||||
|
if (entity_hit->GetEntityID() == viewpoint_entity->GetEntityID())
|
||||||
|
{
|
||||||
|
material_type = BoxedSolid::OurCraftMaterial;
|
||||||
|
}
|
||||||
|
// ECH 8/25/95 - Is this the best way to identify other vehicles?
|
||||||
|
else if (entity_hit->GetPlayerLink() != NULL)
|
||||||
|
{
|
||||||
|
material_type = BoxedSolid::OtherCraftMaterial;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ECH 8/25/95 - How to get material? Just use this for now.
|
||||||
|
material_type = BoxedSolid::ConcreteMaterial;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the appropriate resource ID
|
||||||
|
//
|
||||||
|
return FindResourceID(material_type);
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
//===========================================================================//
|
||||||
|
// File: network.cpp //
|
||||||
|
// Project: MUNGA Brick: Network //
|
||||||
|
// Contents: Implementation details for network clients //
|
||||||
|
//---------------------------------------------------------------------------//
|
||||||
|
// Copyright (C) 1994-1995, Virtual World Entertainment, Inc. //
|
||||||
|
// All Rights reserved worldwide //
|
||||||
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
||||||
|
//===========================================================================//
|
||||||
|
|
||||||
|
#include <munga.hpp>
|
||||||
|
#pragma hdrstop
|
||||||
|
|
||||||
|
#if !defined(NETWORK_HPP)
|
||||||
|
# include <network.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
//#############################################################################
|
||||||
|
//#############################################################################
|
||||||
|
//
|
||||||
|
Derivation
|
||||||
|
NetworkClient::ClassDerivations(
|
||||||
|
Receiver::ClassDerivations,
|
||||||
|
"NetworkClient"
|
||||||
|
);
|
||||||
|
|
||||||
|
NetworkClient::SharedData
|
||||||
|
NetworkClient::DefaultData(
|
||||||
|
NetworkClient::ClassDerivations,
|
||||||
|
Receiver::MessageHandlers
|
||||||
|
);
|
||||||
|
|
||||||
|
Derivation
|
||||||
|
NetworkManager::ClassDerivations(
|
||||||
|
NetworkClient::ClassDerivations,
|
||||||
|
"NetworkManager"
|
||||||
|
);
|
||||||
|
|
||||||
|
NetworkManager::SharedData
|
||||||
|
NetworkManager::DefaultData(
|
||||||
|
NetworkManager::ClassDerivations,
|
||||||
|
Receiver::MessageHandlers
|
||||||
|
);
|
||||||
@@ -0,0 +1,893 @@
|
|||||||
|
# if !defined(MUNGA_HPP)
|
||||||
|
# include <munga.hpp>
|
||||||
|
# endif
|
||||||
|
#pragma hdrstop
|
||||||
|
|
||||||
|
# if !defined(PLAYER_HPP)
|
||||||
|
# include <player.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(ICOM_HPP)
|
||||||
|
# include <icom.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(CAMSHIP_HPP)
|
||||||
|
# include <camship.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(DROPZONE_HPP)
|
||||||
|
# include <dropzone.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(MISSION_HPP)
|
||||||
|
# include <mission.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(AUDIO_HPP)
|
||||||
|
# include <audio.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(DIRECTOR_HPP)
|
||||||
|
# include <director.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(APP_HPP)
|
||||||
|
# include <app.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(HOSTMGR_HPP)
|
||||||
|
# include <hostmgr.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(NTTMGR_HPP)
|
||||||
|
# include <nttmgr.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(CONSOLE_HPP)
|
||||||
|
# include <console.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(APPMSG_HPP)
|
||||||
|
# include <appmsg.hpp>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
//####################### Player::StatusMessage #########################
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
Player__StatusMessage::Player__StatusMessage(Player *player_involved, int message_type, Scalar display_time)
|
||||||
|
{
|
||||||
|
playerInvolved = player_involved;
|
||||||
|
messageType = message_type;
|
||||||
|
displayTime = display_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
//############################### Player ################################
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
// Shared Data Support
|
||||||
|
//
|
||||||
|
Derivation
|
||||||
|
Player::ClassDerivations(Entity::ClassDerivations, "Player");
|
||||||
|
|
||||||
|
Player::SharedData
|
||||||
|
Player::DefaultData(
|
||||||
|
Player::ClassDerivations,
|
||||||
|
Player::MessageHandlers,
|
||||||
|
Player::AttributeIndex,
|
||||||
|
Player::StateCount,
|
||||||
|
(Entity::MakeHandler)Player::Make
|
||||||
|
);
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
// Attribute Support
|
||||||
|
//
|
||||||
|
|
||||||
|
const Player::IndexEntry
|
||||||
|
Player::AttributePointers[]=
|
||||||
|
{
|
||||||
|
ATTRIBUTE_ENTRY(Player, CurrentScore, currentScore),
|
||||||
|
ATTRIBUTE_ENTRY(Player, PlayerRanking, playerRanking),
|
||||||
|
ATTRIBUTE_ENTRY(Player, DropZoneLocation, dropZoneLocation),
|
||||||
|
ATTRIBUTE_ENTRY(Player, StatusMessagePointer,statusMessagePointer),
|
||||||
|
ATTRIBUTE_ENTRY(Player, PlayerBitmapIndex, playerBitmapIndex),
|
||||||
|
ATTRIBUTE_ENTRY(Player, PlayerHighlighted, playerHighlighted)
|
||||||
|
};
|
||||||
|
|
||||||
|
Player::AttributeIndexSet
|
||||||
|
Player::AttributeIndex(ELEMENTS(Player::AttributePointers),
|
||||||
|
Player::AttributePointers,
|
||||||
|
Entity::AttributeIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
// Message Support
|
||||||
|
//
|
||||||
|
const Receiver::HandlerEntry
|
||||||
|
Player::MessageHandlerEntries[]=
|
||||||
|
{
|
||||||
|
MESSAGE_ENTRY(Player, DropZoneReply),
|
||||||
|
MESSAGE_ENTRY(Player, Score),
|
||||||
|
MESSAGE_ENTRY(Player, VehicleDead),
|
||||||
|
MESSAGE_ENTRY(Player, MissionStarting),
|
||||||
|
MESSAGE_ENTRY(Player, MissionEnding)
|
||||||
|
};
|
||||||
|
|
||||||
|
Player::MessageHandlerSet
|
||||||
|
Player::MessageHandlers(ELEMENTS(Player::MessageHandlerEntries), Player::MessageHandlerEntries, Entity::MessageHandlers);
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Player::MissionStartingMessageHandler(Message *)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Tell("Player::MissionStartingMessageHandler - starting fade in\n");
|
||||||
|
fadeTimeRemaining = 3.0f;
|
||||||
|
SetSimulationState(MissionStartingState);
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Player::MissionEndingMessageHandler(Message *)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
fadeTimeRemaining = 3.0f;
|
||||||
|
ForceUpdate();
|
||||||
|
SetSimulationState(MissionEndingState);
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Enumeration
|
||||||
|
Player::GetAudioRepresentation(
|
||||||
|
#if DEBUG_LEVEL>0
|
||||||
|
Entity *linked_entity
|
||||||
|
#else
|
||||||
|
Entity *
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check(linked_entity);
|
||||||
|
Check_Fpu();
|
||||||
|
|
||||||
|
return
|
||||||
|
(GetInstance() == MasterInstance) ?
|
||||||
|
InternalAudioRepresentation : ExternalAudioRepresentation;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Player::ScoreMessageHandler(ScoreMessage *message)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check(message);
|
||||||
|
|
||||||
|
currentScore += message->scoreAward;
|
||||||
|
|
||||||
|
//
|
||||||
|
// HACK - ECH 7/6/95 - Allow the player vehicle to respond to score
|
||||||
|
// messages, allows attribute system to be used for scoring
|
||||||
|
//
|
||||||
|
Check(playerVehicle);
|
||||||
|
playerVehicle->RespondToScoreMessage(message);
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Player::DropZoneReplyMessageHandler(
|
||||||
|
DropZone::ReplyMessage * //message
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Fail("Drop zone reply should not be handled by base player class!\n");
|
||||||
|
}
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Player::CreatePlayerVehicle(Origin camera_origin)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Create any MUNGA level vehicles
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
if (IsCameraShipPlayer())
|
||||||
|
{
|
||||||
|
Check(application);
|
||||||
|
ResourceFile *resources = application->GetResourceFile();
|
||||||
|
Check(resources);
|
||||||
|
Check_Pointer(playerMission->GetGameModel());
|
||||||
|
|
||||||
|
HostManager *host_manager = application->GetHostManager();
|
||||||
|
Check(host_manager);
|
||||||
|
ResourceDescription *camera_res =
|
||||||
|
resources->FindResourceDescription(
|
||||||
|
playerMission->GetGameModel(),
|
||||||
|
ResourceDescription::ModelListResourceType
|
||||||
|
);
|
||||||
|
Check(camera_res);
|
||||||
|
CameraShip::MakeMessage
|
||||||
|
create_camera(
|
||||||
|
CameraShip::MakeMessageID,
|
||||||
|
sizeof(CameraShip::MakeMessage),
|
||||||
|
EntityID(host_manager->GetLocalHostID()),
|
||||||
|
CameraShipClassID,
|
||||||
|
EntityID::Null,
|
||||||
|
camera_res->resourceID,
|
||||||
|
CameraShip::DefaultFlags,
|
||||||
|
camera_origin,
|
||||||
|
Motion::Identity,
|
||||||
|
Motion::Identity
|
||||||
|
);
|
||||||
|
CameraShip *camera =
|
||||||
|
(CameraShip*)application->MakeAndLinkViewpointEntity(&create_camera);
|
||||||
|
Register_Object(camera);
|
||||||
|
playerVehicle = camera;
|
||||||
|
}
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Player::VehicleDeadMessageHandler(VehicleDeadMessage *message)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check(message);
|
||||||
|
Check(application);
|
||||||
|
|
||||||
|
|
||||||
|
//DEBUG_STREAM << "VEHICLEDEAD : " << endl << flush;
|
||||||
|
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// If we have let the player fry, send a message to the dropzone to give us
|
||||||
|
// a new location to return to
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
if (
|
||||||
|
message->deathCount == deathCount
|
||||||
|
&& GetSimulationState() != DropZoneAcquiredState)
|
||||||
|
{
|
||||||
|
DropZone *dropzone;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// If no dropzone has been assigned to this death, find the closest one
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
if (message->dropZoneID == EntityID::Null)
|
||||||
|
{
|
||||||
|
|
||||||
|
//DEBUG_STREAM << " Find Closest" << endl << flush;
|
||||||
|
|
||||||
|
EntityManager *entity_manager = application->GetEntityManager();
|
||||||
|
Check(entity_manager);
|
||||||
|
EntityGroup *dropzones = entity_manager->FindGroup("DropZones");
|
||||||
|
Check(dropzones);
|
||||||
|
ChainIteratorOf<Node*> iterator(dropzones->groupMembers);
|
||||||
|
|
||||||
|
DropZone *closest_dropzone;
|
||||||
|
Vector3D range;
|
||||||
|
Scalar closest_range;
|
||||||
|
|
||||||
|
while ((dropzone = (DropZone*)iterator.ReadAndNext()) != NULL)
|
||||||
|
{
|
||||||
|
Check(dropzone);
|
||||||
|
|
||||||
|
if (!strnicmp(dropzone->GetDropZoneName(), "win", 3))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
closest_dropzone = dropzone;
|
||||||
|
range.Subtract(
|
||||||
|
localOrigin.linearPosition,
|
||||||
|
dropzone->localOrigin.linearPosition
|
||||||
|
);
|
||||||
|
closest_range = range.LengthSquared();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((dropzone = (DropZone*)iterator.ReadAndNext()) != NULL)
|
||||||
|
{
|
||||||
|
Check(dropzone);
|
||||||
|
if (!strnicmp(dropzone->GetDropZoneName(), "win", 3))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
range.Subtract(
|
||||||
|
localOrigin.linearPosition,
|
||||||
|
dropzone->localOrigin.linearPosition
|
||||||
|
);
|
||||||
|
Scalar len = range.LengthSquared();
|
||||||
|
if (len < closest_range)
|
||||||
|
{
|
||||||
|
closest_dropzone = dropzone;
|
||||||
|
closest_range = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
message->dropZoneID = closest_dropzone->GetEntityID();
|
||||||
|
dropzone = closest_dropzone;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//----------------------------------------------
|
||||||
|
// Otherwise, get this one from the host manager
|
||||||
|
//----------------------------------------------
|
||||||
|
//
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//DEBUG_STREAM << " Use Assigned" << endl << flush;
|
||||||
|
|
||||||
|
HostManager *host = application->GetHostManager();
|
||||||
|
Check(host);
|
||||||
|
dropzone =
|
||||||
|
Cast_Object(
|
||||||
|
DropZone*,
|
||||||
|
host->GetEntityPointer(message->dropZoneID)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Check(dropzone);
|
||||||
|
DropZone::AssignDropZoneMessage
|
||||||
|
request(
|
||||||
|
DropZone::AssignDropZoneMessageID,
|
||||||
|
sizeof(DropZone::AssignDropZoneMessage),
|
||||||
|
GetEntityID(),
|
||||||
|
DropZoneReplyMessageID,
|
||||||
|
deathCount
|
||||||
|
);
|
||||||
|
dropzone->Dispatch(&request);
|
||||||
|
Time when = Now();
|
||||||
|
when += 2.0f;
|
||||||
|
application->Post(HighEventPriority, this, message, when);
|
||||||
|
}
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Player::HuntForDropZone(Scalar)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check(playerMission);
|
||||||
|
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// See if our designated drop zone is around yet. If the dropzone group
|
||||||
|
// does not exist, then no dropzones at all are available
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
Check(application);
|
||||||
|
EntityManager *entity_manager = application->GetEntityManager();
|
||||||
|
Check(entity_manager);
|
||||||
|
EntityGroup *dropzones = entity_manager->FindGroup("DropZones");
|
||||||
|
if (!dropzones)
|
||||||
|
{
|
||||||
|
Check_Fpu();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Check(dropzones);
|
||||||
|
ChainIteratorOf<Node*> iterator(dropzones->groupMembers);
|
||||||
|
DropZone *dropzone;
|
||||||
|
const char* zone_name = playerMission->GetDropZoneName();
|
||||||
|
while ((dropzone = (DropZone*)iterator.ReadAndNext()) != NULL)
|
||||||
|
{
|
||||||
|
if (!strcmp(dropzone->GetDropZoneName(), zone_name))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// If it is, reset our performance, and send a message to the drop zone to
|
||||||
|
// give us a location
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
if (dropzone)
|
||||||
|
{
|
||||||
|
|
||||||
|
//DEBUG_STREAM << "FOUND DROPZONE" << endl << flush;
|
||||||
|
|
||||||
|
Check(dropzone);
|
||||||
|
SetPerformance(&Player::DoNothingOnce);
|
||||||
|
VehicleDeadMessage
|
||||||
|
dead(
|
||||||
|
VehicleDeadMessageID,
|
||||||
|
sizeof(VehicleDeadMessage),
|
||||||
|
dropzone->GetEntityID()
|
||||||
|
);
|
||||||
|
dead.deathCount = -2;
|
||||||
|
|
||||||
|
DropZone::AssignDropZoneMessage
|
||||||
|
request(
|
||||||
|
DropZone::AssignDropZoneMessageID,
|
||||||
|
sizeof(DropZone::AssignDropZoneMessage),
|
||||||
|
GetEntityID(),
|
||||||
|
DropZoneReplyMessageID,
|
||||||
|
deathCount
|
||||||
|
);
|
||||||
|
dropzone->Dispatch(&request);
|
||||||
|
Time when = Now();
|
||||||
|
when += 2.0f;
|
||||||
|
application->Post(HighEventPriority, this, &dead, when);
|
||||||
|
}
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Player::ManageApplicationStatus(Scalar time_slice)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// If we are in the game start/stop phase, count the timer down and send the
|
||||||
|
// appropriate message to the application when done
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
Check(this);
|
||||||
|
Check(application);
|
||||||
|
switch (GetSimulationState())
|
||||||
|
{
|
||||||
|
case MissionStartingState:
|
||||||
|
Verify(fadeTimeRemaining <= 3.0f);
|
||||||
|
fadeTimeRemaining -= time_slice;
|
||||||
|
if (fadeTimeRemaining <= 0.0f)
|
||||||
|
{
|
||||||
|
SetSimulationState(VehicleTranslocatedState);
|
||||||
|
Check(application);
|
||||||
|
switch (application->GetApplicationState())
|
||||||
|
{
|
||||||
|
case Application::LaunchingMission:
|
||||||
|
{
|
||||||
|
Application::RunMissionMessage message;
|
||||||
|
application->Dispatch(&message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Application::ResumingMission:
|
||||||
|
{
|
||||||
|
Application::ResumeMissionMessage message;
|
||||||
|
application->Dispatch(&message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MissionEndingState:
|
||||||
|
fadeTimeRemaining -= time_slice;
|
||||||
|
if (fadeTimeRemaining <= 0.0f)
|
||||||
|
{
|
||||||
|
Check(application);
|
||||||
|
switch (application->GetApplicationState())
|
||||||
|
{
|
||||||
|
case Application::EndingMission:
|
||||||
|
{
|
||||||
|
// Fill in appropriate exit code here. GAH
|
||||||
|
Application::StopMissionMessage message(NullExitCodeID);
|
||||||
|
application->Dispatch(&message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Application::AbortingMission:
|
||||||
|
{
|
||||||
|
// Fill in appropriate exit code here. GAH
|
||||||
|
Application::AbortMissionMessage message(NullExitCodeID);
|
||||||
|
application->Dispatch(&message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Application::SuspendingMission:
|
||||||
|
{
|
||||||
|
Application::SuspendMissionMessage message;
|
||||||
|
application->Dispatch(&message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Player::CameraShipSimulation(Scalar time_slice)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
CalcRanking();
|
||||||
|
|
||||||
|
ManageApplicationStatus(time_slice);
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Player::PlayerSimulation(Scalar time_slice)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
|
||||||
|
//-------------------------------
|
||||||
|
// Calculate the player's ranking
|
||||||
|
//-------------------------------
|
||||||
|
CalcRanking();
|
||||||
|
|
||||||
|
//----------------------------------
|
||||||
|
// ...manage the application status?
|
||||||
|
//----------------------------------
|
||||||
|
ManageApplicationStatus(time_slice);
|
||||||
|
|
||||||
|
//-------------------------------
|
||||||
|
// Copy vehicle position
|
||||||
|
//-------------------------------
|
||||||
|
if (playerVehicle)
|
||||||
|
{
|
||||||
|
Check(playerVehicle);
|
||||||
|
localOrigin = playerVehicle->localOrigin;
|
||||||
|
localToWorld = playerVehicle->localToWorld;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------
|
||||||
|
// Service the status message queue
|
||||||
|
//---------------------------------
|
||||||
|
StatusMessageUpdate(time_slice);
|
||||||
|
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Player::GoToVehicle(Scalar)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
if (playerVehicle)
|
||||||
|
{
|
||||||
|
Check(playerVehicle);
|
||||||
|
localOrigin = playerVehicle->localOrigin;
|
||||||
|
localToWorld = playerVehicle->localToWorld;
|
||||||
|
}
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
int
|
||||||
|
Player::CalcRanking()
|
||||||
|
{
|
||||||
|
|
||||||
|
//
|
||||||
|
//---------------------------------------
|
||||||
|
// Get all players from the entity group
|
||||||
|
//---------------------------------------
|
||||||
|
//
|
||||||
|
EntityGroup *player_group =
|
||||||
|
application->GetEntityManager()->FindGroup("Players");
|
||||||
|
if(player_group)
|
||||||
|
{
|
||||||
|
int num_players = 0;
|
||||||
|
Player *active_player;
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// Iterate through the players add to the sorted chain
|
||||||
|
//-----------------------------------------------------
|
||||||
|
//
|
||||||
|
ChainIteratorOf<Node*> iterator(player_group->groupMembers);
|
||||||
|
VChainOf<Player*, Scalar> player_rank(NULL, False);
|
||||||
|
while ((active_player = (Player*) iterator.ReadAndNext()) != NULL)
|
||||||
|
{
|
||||||
|
if(active_player->IsScoringPlayer())
|
||||||
|
{
|
||||||
|
player_rank.AddValue(active_player, active_player->currentScore);
|
||||||
|
++num_players;
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Reset Player Highlighted
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
active_player->playerHighlighted = False;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
active_player->playerRanking = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
--num_players;
|
||||||
|
//
|
||||||
|
//------------------------------------------------
|
||||||
|
// Iterate through the chain assigning the rank
|
||||||
|
//------------------------------------------------
|
||||||
|
//
|
||||||
|
VChainIteratorOf<Player*, Scalar> rank_iterator(player_rank);
|
||||||
|
|
||||||
|
|
||||||
|
while ((active_player = rank_iterator.ReadAndNext()) != NULL)
|
||||||
|
{
|
||||||
|
active_player->playerRanking = num_players;
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// If player in first place turn on player highlighted
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
if (!active_player->playerRanking)
|
||||||
|
{
|
||||||
|
active_player->playerHighlighted = True;
|
||||||
|
}
|
||||||
|
--num_players;
|
||||||
|
}
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
//#############################################################################
|
||||||
|
// Update Support
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Player::ReadUpdateRecord(Simulation::UpdateRecord *message)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check_Pointer(message);
|
||||||
|
Entity::ReadUpdateRecord(message);
|
||||||
|
UpdateRecord* record = (UpdateRecord*) message;
|
||||||
|
|
||||||
|
currentScore = record->currentScore;
|
||||||
|
dropZoneLocation = record->dropZoneLocation;
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Player::WriteUpdateRecord(
|
||||||
|
Simulation::UpdateRecord *record,
|
||||||
|
int update_model
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check_Pointer(record);
|
||||||
|
|
||||||
|
Entity::WriteUpdateRecord(record, update_model);
|
||||||
|
|
||||||
|
UpdateRecord* update = (UpdateRecord*) record;
|
||||||
|
|
||||||
|
update->recordLength = sizeof(*update);
|
||||||
|
update->currentScore = currentScore;
|
||||||
|
update->dropZoneLocation = dropZoneLocation;
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
// Construction and Destruction
|
||||||
|
//
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Player::Player(
|
||||||
|
Player::MakeMessage *creation_message,
|
||||||
|
Player::SharedData &virtual_data
|
||||||
|
):
|
||||||
|
Entity(creation_message, virtual_data),
|
||||||
|
statusMessageQueue(NULL)
|
||||||
|
{
|
||||||
|
Check_Pointer(this);
|
||||||
|
Check_Pointer(creation_message);
|
||||||
|
|
||||||
|
scenarioRole = NULL;
|
||||||
|
//---------------------------------
|
||||||
|
// Initialize data
|
||||||
|
//---------------------------------
|
||||||
|
statusMessagePointer = NULL;
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Initialize the playerMission
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
playerMission = application->GetCurrentMission();
|
||||||
|
Check(playerMission);
|
||||||
|
//
|
||||||
|
//---------------------------------
|
||||||
|
// Set the resource ID for a player
|
||||||
|
//---------------------------------
|
||||||
|
//
|
||||||
|
Check(application);
|
||||||
|
Check(application->GetResourceFile());
|
||||||
|
ResourceDescription *resource_description =
|
||||||
|
application->GetResourceFile()->FindResourceDescription(
|
||||||
|
"player",
|
||||||
|
ResourceDescription::ModelListResourceType
|
||||||
|
);
|
||||||
|
if (resource_description != NULL)
|
||||||
|
{
|
||||||
|
Verify(resourceID == ResourceDescription::NullResourceID);
|
||||||
|
resourceID = resource_description->resourceID;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Get the host type associated with the entity ID
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
HostType host_type;
|
||||||
|
|
||||||
|
HostID host_ID = entityID.GetHostID();
|
||||||
|
Check(application);
|
||||||
|
HostManager *host_mgr = application->GetHostManager();
|
||||||
|
Check(host_mgr);
|
||||||
|
Host *local_host = host_mgr->GetLocalHost();
|
||||||
|
Check(local_host);
|
||||||
|
if (host_ID == local_host->GetHostID())
|
||||||
|
{
|
||||||
|
host_type = local_host->GetHostType();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HostManager::RemoteHostIterator iterator(host_mgr);
|
||||||
|
local_host = iterator.Find(host_ID);
|
||||||
|
Check(local_host);
|
||||||
|
host_type = local_host->GetHostType();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsCameraShipPlayer())
|
||||||
|
{
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Make A CameraPlayers Entity Group
|
||||||
|
// since cameras are not involved in
|
||||||
|
// standard game play they need a
|
||||||
|
// separate Entity Group!
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
playerBitmapIndex = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Make A Regular Players Entity Group
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Check(application);
|
||||||
|
EntityManager *entity_manager = application->GetEntityManager();
|
||||||
|
Check(entity_manager);
|
||||||
|
EntityGroup *players = entity_manager->UseGroup("Players");
|
||||||
|
Check(players);
|
||||||
|
players->Add(this);
|
||||||
|
playerBitmapIndex = creation_message->playerBitmapIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetValidFlag();
|
||||||
|
playerVehicle = NULL;
|
||||||
|
if (GetInstance() != ReplicantInstance)
|
||||||
|
{
|
||||||
|
Check(application->GetCurrentMission());
|
||||||
|
playerMission = application->GetCurrentMission();
|
||||||
|
SetPerformance(&Player::HuntForDropZone);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetPerformance(&Player::GoToVehicle);
|
||||||
|
playerMission = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
playerRanking = 0;
|
||||||
|
deathCount = -2;
|
||||||
|
|
||||||
|
//-------------------------------------
|
||||||
|
// Clear score
|
||||||
|
//-------------------------------------
|
||||||
|
currentScore = 0.0f;
|
||||||
|
//-------------------------------------
|
||||||
|
// Create intercom object
|
||||||
|
//-------------------------------------
|
||||||
|
Check(application);
|
||||||
|
IcomManager
|
||||||
|
*intercom_manager = application->GetIntercomManager();
|
||||||
|
Check(intercom_manager);
|
||||||
|
|
||||||
|
intercomPointer = intercom_manager->MakeIcom(GetOwnerID());
|
||||||
|
Check(intercomPointer);
|
||||||
|
// registered in MakeIcom()
|
||||||
|
|
||||||
|
playerHighlighted = False;
|
||||||
|
fadeTimeRemaining = 0.0f;
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Player* Player::Make(Player::MakeMessage *creation_message)
|
||||||
|
{
|
||||||
|
Check_Fpu();
|
||||||
|
return new Player(creation_message, DefaultData);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Player::~Player()
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
|
||||||
|
//--------------------------------------------
|
||||||
|
// Delete intercom object
|
||||||
|
//--------------------------------------------
|
||||||
|
Check(intercomPointer);
|
||||||
|
Unregister_Object(intercomPointer);
|
||||||
|
delete intercomPointer;
|
||||||
|
intercomPointer = NULL;
|
||||||
|
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Player::AddStatusMessage(StatusMessage *status_message)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check_Pointer(status_message);
|
||||||
|
statusMessageQueue.Add(status_message);
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Player::StatusMessageUpdate(Scalar time_slice)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
//-------------------------------------
|
||||||
|
// We handle this queue as a STACK.
|
||||||
|
// The most recent message is presented
|
||||||
|
// first, causing older messages to
|
||||||
|
// wait "below" them on the stack.
|
||||||
|
// This allows a default message to
|
||||||
|
// sit at the "bottom" of the stack
|
||||||
|
// and allow others to override it
|
||||||
|
// temporarily.
|
||||||
|
//-------------------------------------
|
||||||
|
//
|
||||||
|
ChainIteratorOf<StatusMessage*>
|
||||||
|
iterator(statusMessageQueue);
|
||||||
|
//----------------------------------------
|
||||||
|
// ...we really want iterator.GetLast(),
|
||||||
|
// but since it doesn't exist we'll
|
||||||
|
// do it directly.
|
||||||
|
//----------------------------------------
|
||||||
|
statusMessagePointer = NULL;
|
||||||
|
{
|
||||||
|
StatusMessage
|
||||||
|
*the_message;
|
||||||
|
|
||||||
|
while ((the_message = iterator.ReadAndNext()) != NULL)
|
||||||
|
{
|
||||||
|
statusMessagePointer = the_message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//----------------------------------------
|
||||||
|
// If a message exists, decrement the
|
||||||
|
// timer: discard it if timed out.
|
||||||
|
//----------------------------------------
|
||||||
|
if (statusMessagePointer != NULL)
|
||||||
|
{
|
||||||
|
Check_Pointer(statusMessagePointer);
|
||||||
|
|
||||||
|
statusMessagePointer->displayTime -= time_slice;
|
||||||
|
if (statusMessagePointer->displayTime <= (Scalar) 0.0f)
|
||||||
|
{
|
||||||
|
Unregister_Object(statusMessagePointer);
|
||||||
|
delete statusMessagePointer;
|
||||||
|
statusMessagePointer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
Logical
|
||||||
|
Player::TestInstance() const
|
||||||
|
{
|
||||||
|
return IsDerivedFrom(ClassDerivations);
|
||||||
|
}
|
||||||
@@ -0,0 +1,180 @@
|
|||||||
|
# if !defined(MUNGA_HPP)
|
||||||
|
# include <munga.hpp>
|
||||||
|
# endif
|
||||||
|
#pragma hdrstop
|
||||||
|
|
||||||
|
# if !defined(RANDOM_HPP)
|
||||||
|
# include <random.hpp>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
int RandomGenerator::Numbers[250];
|
||||||
|
int RandomGenerator::Index = -1;
|
||||||
|
|
||||||
|
RandomGenerator Random;
|
||||||
|
|
||||||
|
//
|
||||||
|
//###########################################################################
|
||||||
|
//###########################################################################
|
||||||
|
//
|
||||||
|
void RandomGenerator::Init()
|
||||||
|
{
|
||||||
|
int i, msb, mask;
|
||||||
|
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// After making sure the table is built only once, initialize the
|
||||||
|
// Borland C++ random numbers with the low word of the current time in
|
||||||
|
// milliseconds, and initialize the index pointer
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
char *seed_spec = getenv("RANDOM");
|
||||||
|
unsigned seed;
|
||||||
|
if (seed_spec)
|
||||||
|
{
|
||||||
|
seed = (unsigned)atol(seed_spec);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
seed = (unsigned)time(NULL);
|
||||||
|
}
|
||||||
|
#if defined(TEST_CLASS)
|
||||||
|
cout << "Random Seed = " << seed << endl;
|
||||||
|
#endif
|
||||||
|
srand(seed);
|
||||||
|
Index = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
// Load the random number buffer, then go thru and set the sign bit
|
||||||
|
// randomly, increasing the range of random numbers from 0..32767 to
|
||||||
|
// 0..65535
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
for (i=0; i<250; i++)
|
||||||
|
{
|
||||||
|
Numbers[i] = rand();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// In order to preserve a good random number mix for the XOR function,
|
||||||
|
// mask and set the bits of 16 words in a descending manner as in
|
||||||
|
// 1xx..., 01xx..., 001xx..., 0001xx..., ...
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
mask = RAND_MAX >> 1;
|
||||||
|
msb = mask + 1;
|
||||||
|
int rand_size;
|
||||||
|
for (rand_size=0; !(msb&(1<<rand_size)); ++rand_size);
|
||||||
|
i = 14;
|
||||||
|
while (rand_size--)
|
||||||
|
{
|
||||||
|
Verify(i<ELEMENTS(Numbers));
|
||||||
|
Numbers[i] &= mask;
|
||||||
|
Numbers[i] |= msb;
|
||||||
|
mask >>= 1;
|
||||||
|
msb >>= 1;
|
||||||
|
i += 11;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//###########################################################################
|
||||||
|
//###########################################################################
|
||||||
|
//
|
||||||
|
int RandomGenerator::GetRandomInt()
|
||||||
|
{
|
||||||
|
int indent, result;
|
||||||
|
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
// The random number generated will be the result of an XOR with the
|
||||||
|
// element 103 positions further (wrapping around) in the table
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
indent = (Index>=147)?Index-147:Index+103;
|
||||||
|
result = Numbers[Index]^Numbers[indent];
|
||||||
|
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Replace the current random number with the new one generated, increment
|
||||||
|
// the buffer index pointer, and return the number
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
Numbers[Index] = result;
|
||||||
|
if (++Index == ELEMENTS(Numbers))
|
||||||
|
Index=0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//###########################################################################
|
||||||
|
//###########################################################################
|
||||||
|
//
|
||||||
|
RandomGenerator::operator Scalar()
|
||||||
|
{
|
||||||
|
Scalar result;
|
||||||
|
|
||||||
|
result = GetRandomInt();
|
||||||
|
result /= (float)(RAND_MAX + 1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//###########################################################################
|
||||||
|
//###########################################################################
|
||||||
|
//
|
||||||
|
int RandomGenerator::operator ()(int range)
|
||||||
|
{
|
||||||
|
int result, max;
|
||||||
|
|
||||||
|
max = RAND_MAX - ((RAND_MAX + 1)%range);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
result = GetRandomInt();
|
||||||
|
} while (result>max);
|
||||||
|
return result%range;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//###########################################################################
|
||||||
|
//###########################################################################
|
||||||
|
//
|
||||||
|
Die::Die(int n)
|
||||||
|
{
|
||||||
|
dieSides = (n>1)?n:2;
|
||||||
|
highestRandom = RAND_MAX - ((RAND_MAX+1)%dieSides);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//###########################################################################
|
||||||
|
//###########################################################################
|
||||||
|
//
|
||||||
|
Die::operator int()
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// In order to not skew the probabilities to the low numbers, make sure
|
||||||
|
// that the random # used is not greater than the limit determined for the
|
||||||
|
// number of sides.
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
do
|
||||||
|
{
|
||||||
|
result = Random.GetInt();
|
||||||
|
} while (result>highestRandom);
|
||||||
|
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Once the base random number is determined, do modulus division and
|
||||||
|
// increment by 1 to map into the die range.
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
return result % dieSides + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(TEST_CLASS)
|
||||||
|
#include "random.tcp"
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,641 @@
|
|||||||
|
# if !defined(MUNGA_HPP)
|
||||||
|
# include <munga.hpp>
|
||||||
|
# endif
|
||||||
|
#pragma hdrstop
|
||||||
|
|
||||||
|
# if !defined(RECEIVER_HPP)
|
||||||
|
# include <receiver.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(EVENT_HPP)
|
||||||
|
# include <event.hpp>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
//############################# Receiver ################################
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
const Receiver::Handler
|
||||||
|
Receiver::NullHandler=NULL;
|
||||||
|
|
||||||
|
Receiver::SharedData
|
||||||
|
Receiver::DefaultData(
|
||||||
|
Receiver::ClassDerivations,
|
||||||
|
Receiver::MessageHandlers
|
||||||
|
);
|
||||||
|
|
||||||
|
Derivation
|
||||||
|
Receiver::ClassDerivations("Receiver");
|
||||||
|
|
||||||
|
const Receiver::HandlerEntry
|
||||||
|
Receiver::MessageHandlerEntries[]=
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Receiver::WatcherChangedMessageID,
|
||||||
|
"WatcherChanged",
|
||||||
|
(Receiver::Handler)&Receiver::DefaultMessageHandler
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Receiver::LoadResourceFinishedMessageID,
|
||||||
|
"LoadResourceFinished",
|
||||||
|
(Receiver::Handler)&Receiver::DefaultMessageHandler
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Receiver::MessageHandlerSet
|
||||||
|
Receiver::MessageHandlers(ELEMENTS(Receiver::MessageHandlerEntries), Receiver::MessageHandlerEntries);
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
#if defined(USE_SIGNATURE)
|
||||||
|
int
|
||||||
|
Is_Signature_Bad(const volatile Receiver__Message *)
|
||||||
|
{
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
#if DEBUG_LEVEL>0
|
||||||
|
Receiver::DefaultMessageHandler(Message* message)
|
||||||
|
#else
|
||||||
|
Receiver::DefaultMessageHandler(Message*)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
Tell(
|
||||||
|
"Default Handler activated on message ID " << message->messageID << endl
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Receiver::Receive(Message *what)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// Service the message taps by creating an iterator to step through all the
|
||||||
|
// MessageTaps registered with the Derivation object for the receiver's
|
||||||
|
// class. Each tap will do whatever it thinks best about this receiver
|
||||||
|
// having received this message
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
Check(this);
|
||||||
|
Check_Pointer(what);
|
||||||
|
ChainIteratorOf<MessageTap*> i(GetDerivation()->activeTaps);
|
||||||
|
MessageTap *tap;
|
||||||
|
while ((tap = i.ReadAndNext()) != NULL)
|
||||||
|
{
|
||||||
|
tap->Scan(this,what);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Now, see if the receiver can handle this type of message, and if so, send
|
||||||
|
// the message to the returned method handler
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
Receiver::SharedData *sharedData = GetSharedData();
|
||||||
|
Handler handler = sharedData->activeMessageHandlers->Find(what->messageID);
|
||||||
|
if (handler != Receiver::NullHandler)
|
||||||
|
{
|
||||||
|
(this->*handler)(what);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Receiver::Receive(Event *event)
|
||||||
|
{
|
||||||
|
Receive(event->messageToSend);
|
||||||
|
Unregister_Object(event);
|
||||||
|
delete event;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Receiver::FlushEvents(int) // max_priority doesn't work yet!!!!
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
PlugIteratorOf<Event*> i(this);
|
||||||
|
Event *event;
|
||||||
|
while ((event = i.ReadAndNext()) != NULL)
|
||||||
|
{
|
||||||
|
if (event->GetClassID() == EventClassID)
|
||||||
|
{
|
||||||
|
Unregister_Object(event);
|
||||||
|
delete event;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Receiver::FlushMatchingEvents(
|
||||||
|
Receiver::MessageID target_message,
|
||||||
|
int // max_priority doesn't work yet!!!!
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
PlugIteratorOf<Event*>
|
||||||
|
i(this);
|
||||||
|
Event* event;
|
||||||
|
while ((event = i.ReadAndNext()) != NULL)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
event->GetClassID() == EventClassID && (
|
||||||
|
target_message == Receiver::AnyMessageID
|
||||||
|
|| event->messageToSend->messageID == target_message
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Unregister_Object(event);
|
||||||
|
delete event;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Receiver::ProcessDeferredQueue()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
//------------------------------------------------
|
||||||
|
// Find a delay queue, and return if there is none
|
||||||
|
//------------------------------------------------
|
||||||
|
//
|
||||||
|
Check(this);
|
||||||
|
PlugIteratorOf<DeferredEventQueue*> i(this);
|
||||||
|
DeferredEventQueue *deferred_queue;
|
||||||
|
while ((deferred_queue = i.ReadAndNext()) != NULL)
|
||||||
|
{
|
||||||
|
if (deferred_queue->GetClassID() == DeferredEventQueueClassID)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!deferred_queue)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
// Now, tell the queue to process all its events, then delete it
|
||||||
|
//--------------------------------------------------------------
|
||||||
|
//
|
||||||
|
deferred_queue->ProcessAllEvents();
|
||||||
|
Unregister_Object(deferred_queue);
|
||||||
|
delete deferred_queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Logical
|
||||||
|
Receiver::TestInstance() const
|
||||||
|
{
|
||||||
|
return IsDerivedFrom(ClassDerivations);
|
||||||
|
}
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
//######################### Receiver::Message ###########################
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Logical
|
||||||
|
Receiver::Message::TestInstance() const
|
||||||
|
{
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
//######################### Receiver::DynamicMessage ##########################
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Receiver__DynamicMessage::Receiver__DynamicMessage(
|
||||||
|
Receiver::MessageID message_ID,
|
||||||
|
size_t message_size
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Receiver::Message new_message(message_ID, message_size);
|
||||||
|
WriteBytes(&new_message, message_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
MemoryStream&
|
||||||
|
Receiver::DynamicMessage::WriteBytes(
|
||||||
|
const void *ptr,
|
||||||
|
size_t number_of_bytes
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DynamicMemoryStream::WriteBytes(ptr, number_of_bytes);
|
||||||
|
|
||||||
|
Receiver::Message *message = GetMessagePointer();
|
||||||
|
size_t new_size = GetBytesUsed();
|
||||||
|
message->messageLength = new_size;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
//############################ MessageTap ###############################
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
MemoryBlock
|
||||||
|
MessageTap::AllocatedMemory(sizeof(MessageTap), 30, 30, "Message Taps");
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
MessageTap::MessageTap(
|
||||||
|
Derivation *derivation,
|
||||||
|
Receiver *client,
|
||||||
|
Receiver::ScanCallback call_back
|
||||||
|
):
|
||||||
|
Plug(MessageTapClassID)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
//---------------------------
|
||||||
|
// Initialize the message tap
|
||||||
|
//---------------------------
|
||||||
|
//
|
||||||
|
Check(client);
|
||||||
|
clientReceiver = client;
|
||||||
|
scanCallback = call_back;
|
||||||
|
matchingReceiver = NULL;
|
||||||
|
matchingMessageID = Receiver::AnyMessageID;
|
||||||
|
|
||||||
|
//
|
||||||
|
//--------------------------------------------
|
||||||
|
// Hook the tap up to the specified derivation
|
||||||
|
//--------------------------------------------
|
||||||
|
//
|
||||||
|
Check(derivation);
|
||||||
|
derivation->AppendMessageTap(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
MessageTap::MessageTap(
|
||||||
|
Derivation *derivation,
|
||||||
|
Receiver *client,
|
||||||
|
Receiver::ScanCallback call_back,
|
||||||
|
Receiver::MessageID messageID,
|
||||||
|
Receiver *receiver
|
||||||
|
):
|
||||||
|
Plug(MessageTapClassID)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
//---------------------------
|
||||||
|
// Initialize the message tap
|
||||||
|
//---------------------------
|
||||||
|
//
|
||||||
|
Check(client);
|
||||||
|
clientReceiver = client;
|
||||||
|
scanCallback = call_back;
|
||||||
|
|
||||||
|
matchingReceiver = receiver;
|
||||||
|
matchingMessageID = messageID;
|
||||||
|
|
||||||
|
//
|
||||||
|
//--------------------------------------------
|
||||||
|
// Hook the tap up to the specified derivation
|
||||||
|
//--------------------------------------------
|
||||||
|
//
|
||||||
|
Check(derivation);
|
||||||
|
derivation->AppendMessageTap(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
MessageTap::Scan(
|
||||||
|
Receiver *receiver,
|
||||||
|
Receiver::Message *message
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check(message);
|
||||||
|
|
||||||
|
if (
|
||||||
|
(!matchingReceiver || matchingReceiver == receiver)
|
||||||
|
&& (
|
||||||
|
matchingMessageID == Receiver::AnyMessageID
|
||||||
|
|| matchingMessageID == message->messageID
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
(clientReceiver->*scanCallback)(message,receiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Logical
|
||||||
|
MessageTap::TestInstance() const
|
||||||
|
{
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
//##################### Receiver::InheritanceSet ########################
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Logical
|
||||||
|
Receiver::InheritanceSet::TestInstance() const
|
||||||
|
{
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
//#################### Receiver::MessageHandlerSet ######################
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
const Receiver::MessageHandlerSet
|
||||||
|
Receiver::MessageHandlerSet::NullSet;
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Receiver__MessageHandlerSet::~Receiver__MessageHandlerSet()
|
||||||
|
{
|
||||||
|
if (messageHandlers)
|
||||||
|
{
|
||||||
|
Unregister_Pointer(messageHandlers);
|
||||||
|
delete[] messageHandlers;
|
||||||
|
messageHandlers = NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Receiver::MessageHandlerSet::Build(
|
||||||
|
Receiver::MessageID count,
|
||||||
|
const Receiver::HandlerEntry handler_table[],
|
||||||
|
const Receiver::MessageHandlerSet *inheritance
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
//-------------------------------------------------------
|
||||||
|
// Find out the highest message type we have to deal with
|
||||||
|
//-------------------------------------------------------
|
||||||
|
//
|
||||||
|
Check(this);
|
||||||
|
Check_Pointer(handler_table);
|
||||||
|
entryCount = 0;
|
||||||
|
Receiver::MessageID i;
|
||||||
|
for (i=0; i<count; ++i)
|
||||||
|
{
|
||||||
|
if (handler_table[i].entryID > entryCount)
|
||||||
|
{
|
||||||
|
entryCount = handler_table[i].entryID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (inheritance)
|
||||||
|
{
|
||||||
|
Check(inheritance);
|
||||||
|
if (entryCount < inheritance->entryCount)
|
||||||
|
{
|
||||||
|
entryCount = inheritance->entryCount;
|
||||||
|
}
|
||||||
|
#if DEBUG_LEVEL>0
|
||||||
|
else if (entryCount > inheritance->entryCount)
|
||||||
|
{
|
||||||
|
i = inheritance->entryCount+1;
|
||||||
|
goto Check_Table;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Verify(entryCount == count);
|
||||||
|
#if DEBUG_LEVEL>0
|
||||||
|
i = 1;
|
||||||
|
Check_Table:
|
||||||
|
while (i <= entryCount)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
for (j=0; j<count; ++j)
|
||||||
|
{
|
||||||
|
if (handler_table[j].entryID == i)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j == count)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
Verify(i > count);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
// Allocate the memory for the new handler set, and copy the inherited
|
||||||
|
// handlers to the new table. We are guaranteed to have enough space for
|
||||||
|
// the inherited table
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
messageHandlers = new Receiver::HandlerEntry[entryCount];
|
||||||
|
Check_Pointer(messageHandlers);
|
||||||
|
Register_Pointer(messageHandlers);
|
||||||
|
i = 0;
|
||||||
|
if (inheritance)
|
||||||
|
{
|
||||||
|
for (; i<inheritance->entryCount; ++i)
|
||||||
|
{
|
||||||
|
messageHandlers[i] = inheritance->messageHandlers[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Step through the new table supplied, placing each handler in the slot
|
||||||
|
// determined by the message type
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
for (i=0; i<count; ++i)
|
||||||
|
{
|
||||||
|
Receiver::MessageID index = handler_table[i].entryID - 1;
|
||||||
|
Verify(index >= 0 && index < entryCount);
|
||||||
|
messageHandlers[index] = handler_table[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
const Receiver::HandlerEntry*
|
||||||
|
Receiver::MessageHandlerSet::Find(const char* name) const
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check_Pointer(name);
|
||||||
|
|
||||||
|
for (int i=0; i<entryCount; ++i)
|
||||||
|
{
|
||||||
|
if (!strcmp(name, messageHandlers[i].entryName))
|
||||||
|
{
|
||||||
|
return &messageHandlers[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
//############################# Derivation ##############################
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Derivation::Derivation(char *name):
|
||||||
|
Node(DerivationClassID),
|
||||||
|
classDerivations(this),
|
||||||
|
activeTaps(this)
|
||||||
|
{
|
||||||
|
Dump(name);
|
||||||
|
className = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Derivation::Derivation(
|
||||||
|
Derivation &derivation,
|
||||||
|
char *name
|
||||||
|
):
|
||||||
|
Node(DerivationClassID),
|
||||||
|
classDerivations(this),
|
||||||
|
activeTaps(this)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------
|
||||||
|
// Add this derivation as a child of the parent's derivation
|
||||||
|
//----------------------------------------------------------
|
||||||
|
//
|
||||||
|
Dump(name);
|
||||||
|
className = name;
|
||||||
|
Check(&derivation);
|
||||||
|
derivation.AppendDerivation(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Derivation::AppendMessageTap(MessageTap* tap)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check(tap);
|
||||||
|
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Add the tap to the taps chain, then step through all our derivations,
|
||||||
|
// sending each of them this same method
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
activeTaps.Add(tap);
|
||||||
|
ChainIteratorOf<Derivation*>
|
||||||
|
i(classDerivations);
|
||||||
|
Derivation *derivation;
|
||||||
|
while ((derivation = i.ReadAndNext()) != NULL)
|
||||||
|
{
|
||||||
|
derivation->AppendMessageTap(tap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Logical
|
||||||
|
Derivation::IsDescendedFrom(Derivation& parent)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check(&parent);
|
||||||
|
|
||||||
|
//
|
||||||
|
//------------------------------
|
||||||
|
// We are descended from ourself
|
||||||
|
//------------------------------
|
||||||
|
//
|
||||||
|
if (&parent == this)
|
||||||
|
{
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Find our parent derivation, and ask him
|
||||||
|
// sending each of them this same method
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
PlugIteratorOf<Derivation*> i(this);
|
||||||
|
Derivation *derivation;
|
||||||
|
while ((derivation = i.ReadAndNext()) != NULL)
|
||||||
|
{
|
||||||
|
if (derivation->GetClassID() == DerivationClassID)
|
||||||
|
{
|
||||||
|
return derivation->IsDescendedFrom(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Logical
|
||||||
|
Derivation::IsDescendedFrom(const char* parent)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check_Pointer(parent);
|
||||||
|
|
||||||
|
//
|
||||||
|
//------------------------------
|
||||||
|
// We are descended from ourself
|
||||||
|
//------------------------------
|
||||||
|
//
|
||||||
|
Check_Pointer(className);
|
||||||
|
if (!strcmp(className, parent))
|
||||||
|
{
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
// Find our parent derivation, and ask him
|
||||||
|
// sending each of them this same method
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
PlugIteratorOf<Derivation*> i(this);
|
||||||
|
Derivation *derivation;
|
||||||
|
while ((derivation = i.ReadAndNext()) != NULL)
|
||||||
|
{
|
||||||
|
Check(derivation);
|
||||||
|
if (derivation->GetClassID() == DerivationClassID)
|
||||||
|
{
|
||||||
|
return derivation->IsDescendedFrom(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
//###################### Receiver::SharedData ##########################
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
Logical
|
||||||
|
Receiver::SharedData::TestInstance() const
|
||||||
|
{
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(TEST_CLASS)
|
||||||
|
# include "receiver.tcp"
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,298 @@
|
|||||||
|
# if !defined(MUNGA_HPP)
|
||||||
|
# include <munga.hpp>
|
||||||
|
# endif
|
||||||
|
#pragma hdrstop
|
||||||
|
|
||||||
|
# if !defined(SUBSYSTM_HPP)
|
||||||
|
# include <subsystm.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(FILEUTIL_HPP)
|
||||||
|
# include <fileutil.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(NOTATION_HPP)
|
||||||
|
# include <notation.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(NAMELIST_HPP)
|
||||||
|
# include <namelist.hpp>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
Subsystem::SharedData
|
||||||
|
Subsystem::DefaultData(
|
||||||
|
Subsystem::ClassDerivations,
|
||||||
|
Subsystem::MessageHandlers,
|
||||||
|
Subsystem::AttributeIndex,
|
||||||
|
Subsystem::StateCount
|
||||||
|
);
|
||||||
|
|
||||||
|
Derivation
|
||||||
|
Subsystem::ClassDerivations(Simulation::ClassDerivations, "Subsystem");
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Subsystem::WriteUpdateRecord(
|
||||||
|
UpdateRecord *message,
|
||||||
|
int update_model
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check_Pointer(message);
|
||||||
|
|
||||||
|
Simulation::WriteUpdateRecord(message, update_model);
|
||||||
|
message->subsystemID = (Word)(subsystemID+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Subsystem::Subsystem(
|
||||||
|
Entity *entity,
|
||||||
|
int subsystem_ID,
|
||||||
|
SubsystemResource *model,
|
||||||
|
SharedData &shared_data
|
||||||
|
):
|
||||||
|
Simulation(model->classID, shared_data)
|
||||||
|
{
|
||||||
|
owningEntity = entity;
|
||||||
|
subsystemID = subsystem_ID;
|
||||||
|
size_t name_size = strlen(model->subsystemName)+1;
|
||||||
|
subsystemName = new char[name_size];
|
||||||
|
Register_Pointer(subsystemName);
|
||||||
|
Str_Copy(subsystemName, model->subsystemName, name_size);
|
||||||
|
segmentIndex = model->segmentIndex;
|
||||||
|
simulationFlags = model->subsystemFlags;
|
||||||
|
damageZone = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Subsystem::Subsystem(
|
||||||
|
Entity *entity,
|
||||||
|
int subsystem_id,
|
||||||
|
const char* subsystem_name,
|
||||||
|
RegisteredClass::ClassID class_id,
|
||||||
|
SharedData &shared_data
|
||||||
|
):
|
||||||
|
Simulation(class_id, shared_data)
|
||||||
|
{
|
||||||
|
owningEntity = entity;
|
||||||
|
subsystemID = subsystem_id;
|
||||||
|
size_t name_size = strlen(subsystem_name)+1;
|
||||||
|
subsystemName = new char[name_size];
|
||||||
|
Register_Pointer(subsystemName);
|
||||||
|
Str_Copy(subsystemName, subsystem_name, name_size);
|
||||||
|
segmentIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Subsystem::~Subsystem()
|
||||||
|
{
|
||||||
|
Unregister_Pointer(subsystemName);
|
||||||
|
delete[] subsystemName;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
ResourceDescription::ResourceID
|
||||||
|
Subsystem::CreateStreamedSubsystem(
|
||||||
|
NotationFile *model_file,
|
||||||
|
const char *model_name,
|
||||||
|
const char *subsystem_name,
|
||||||
|
SubsystemResource *subsystem_resource,
|
||||||
|
NotationFile *subsystem_file,
|
||||||
|
const ResourceDirectories *directories
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Check(model_file);
|
||||||
|
Check_Pointer(model_name);
|
||||||
|
Check_Pointer(subsystem_name);
|
||||||
|
Check_Pointer(subsystem_resource);
|
||||||
|
Check(subsystem_file);
|
||||||
|
Check_Pointer(directories);
|
||||||
|
|
||||||
|
for(int ii=0; ii<(sizeof(subsystem_resource->subsystemName));ii++)
|
||||||
|
{
|
||||||
|
subsystem_resource->subsystemName[ii] = '\0';
|
||||||
|
}
|
||||||
|
subsystem_resource->subsystemModelSize = sizeof(*subsystem_resource);
|
||||||
|
|
||||||
|
if (strlen(subsystem_name) > sizeof(subsystem_resource->subsystemName)-1)
|
||||||
|
{
|
||||||
|
DEBUG_STREAM << subsystem_name << " is too long. Maximum name size is "
|
||||||
|
<< (sizeof(subsystem_resource->subsystemName)-1) << " character!\n";
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
Str_Copy(
|
||||||
|
subsystem_resource->subsystemName,
|
||||||
|
subsystem_name,
|
||||||
|
sizeof(subsystem_resource->subsystemName)-1
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
//------------------------------------------
|
||||||
|
// If any flags were specified, read them in
|
||||||
|
//------------------------------------------
|
||||||
|
//
|
||||||
|
const char* flags;
|
||||||
|
subsystem_resource->subsystemFlags = 0;
|
||||||
|
if(
|
||||||
|
subsystem_file->GetEntry(
|
||||||
|
subsystem_name,
|
||||||
|
"SubsystemFlags",
|
||||||
|
&flags
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!strcmp(flags,"DontReplicateFlag"))
|
||||||
|
{
|
||||||
|
subsystem_resource->subsystemFlags |= Subsystem::DontReplicateFlag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_STREAM << subsystem_name << " has an unknown subsystem flag!\n" << flush;
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//--------------------------------------------------
|
||||||
|
// Get the Segment Name to locate in the .skl file
|
||||||
|
//--------------------------------------------------
|
||||||
|
//
|
||||||
|
const char* desired_page;
|
||||||
|
subsystem_resource->segmentIndex = -1;
|
||||||
|
if(
|
||||||
|
subsystem_file->GetEntry(
|
||||||
|
subsystem_name,
|
||||||
|
"SegmentPageName",
|
||||||
|
&desired_page
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
subsystem_resource->segmentIndex =
|
||||||
|
Get_Segment_Index(model_file, model_name, directories, desired_page);
|
||||||
|
}
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Logical
|
||||||
|
Subsystem::TestInstance() const
|
||||||
|
{
|
||||||
|
return IsDerivedFrom(ClassDerivations);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Logical
|
||||||
|
Subsystem::GenerateFault(int /*fault_index*/)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check_Fpu();
|
||||||
|
return False; // fault not generated
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
int
|
||||||
|
Get_Segment_Index(
|
||||||
|
NotationFile *model_file,
|
||||||
|
const char* model_name,
|
||||||
|
const ResourceDirectories *directories,
|
||||||
|
const char *desired_page
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//------------------------------------------
|
||||||
|
// Get the Segment Index from the .skl file
|
||||||
|
//------------------------------------------
|
||||||
|
//
|
||||||
|
const char* skl_entry;
|
||||||
|
if (
|
||||||
|
!model_file->GetEntry(
|
||||||
|
"video",
|
||||||
|
"skeleton",
|
||||||
|
&skl_entry
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
cerr << model_name << " is missing .skl file specification!\n";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *skl_filename =
|
||||||
|
MakePathedFilename(directories->videoDirectory, skl_entry);
|
||||||
|
Register_Pointer(skl_filename);
|
||||||
|
|
||||||
|
NotationFile *skl_file = new NotationFile(skl_filename);
|
||||||
|
Register_Object(skl_file);
|
||||||
|
if (!skl_file->PageCount())
|
||||||
|
{
|
||||||
|
cerr << skl_filename << " is empty or missing!\n";
|
||||||
|
Dump_And_Die:
|
||||||
|
Unregister_Pointer(skl_filename);
|
||||||
|
delete[] skl_filename;
|
||||||
|
Unregister_Object(skl_file);
|
||||||
|
delete skl_file;
|
||||||
|
return ResourceDescription::NullResourceID;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make a pagelist of all the segments
|
||||||
|
//
|
||||||
|
NameList *segment_pages = skl_file->MakePageList();
|
||||||
|
Register_Object(segment_pages);
|
||||||
|
|
||||||
|
NameList::Entry *segment_entry = segment_pages->GetFirstEntry();
|
||||||
|
char
|
||||||
|
segment_page_name[32];
|
||||||
|
int
|
||||||
|
segment_index = -1;
|
||||||
|
int
|
||||||
|
current_index = 0;
|
||||||
|
while(segment_entry)
|
||||||
|
{
|
||||||
|
Str_Copy(
|
||||||
|
segment_page_name,
|
||||||
|
segment_entry->GetName(),
|
||||||
|
sizeof(segment_page_name)
|
||||||
|
);
|
||||||
|
//
|
||||||
|
//---------------------------------------
|
||||||
|
// skip labonly and damagezones
|
||||||
|
//---------------------------------------
|
||||||
|
//
|
||||||
|
if(
|
||||||
|
(strcmp(segment_page_name, "LAB_ONLY") == 0) ||
|
||||||
|
(strcmp(segment_page_name,"DamageZones") ==0)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
segment_entry = segment_entry->GetNextEntry();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
//-------------------------------------
|
||||||
|
// if names match save the index
|
||||||
|
//-------------------------------------
|
||||||
|
//
|
||||||
|
else if(strcmp(segment_page_name,desired_page) ==0)
|
||||||
|
{
|
||||||
|
segment_index = current_index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++current_index;
|
||||||
|
segment_entry = segment_entry->GetNextEntry();
|
||||||
|
}
|
||||||
|
if(segment_index == -1)
|
||||||
|
{
|
||||||
|
cout<<desired_page <<" SegmentPageName Not in "<< skl_filename <<endl;
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
Unregister_Pointer(skl_filename);
|
||||||
|
delete[] skl_filename;
|
||||||
|
Unregister_Object(skl_file);
|
||||||
|
delete skl_file;
|
||||||
|
Unregister_Object(segment_pages);
|
||||||
|
delete segment_pages;
|
||||||
|
|
||||||
|
return segment_index;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,205 @@
|
|||||||
|
# if !defined(MUNGA_HPP)
|
||||||
|
# include <munga.hpp>
|
||||||
|
# endif
|
||||||
|
#pragma hdrstop
|
||||||
|
|
||||||
|
# if !defined(TEAM_HPP)
|
||||||
|
# include <team.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(APP_HPP)
|
||||||
|
# include <app.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(NTTMGR_HPP)
|
||||||
|
# include <nttmgr.hpp>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
//############################### Team #################################
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
// Shared Data Support
|
||||||
|
//
|
||||||
|
Derivation
|
||||||
|
Team::ClassDerivations(Entity::ClassDerivations, "Team");
|
||||||
|
|
||||||
|
Team::SharedData
|
||||||
|
Team::DefaultData(
|
||||||
|
Team::ClassDerivations,
|
||||||
|
Team::MessageHandlers,
|
||||||
|
Team::AttributeIndex,
|
||||||
|
Team::StateCount,
|
||||||
|
(Team::MakeHandler)Team::Make
|
||||||
|
);
|
||||||
|
//#############################################################################
|
||||||
|
// Attribute Support
|
||||||
|
//
|
||||||
|
|
||||||
|
const Team::IndexEntry
|
||||||
|
Team::AttributePointers[]=
|
||||||
|
{
|
||||||
|
ATTRIBUTE_ENTRY(Team, TeamName, teamName),
|
||||||
|
ATTRIBUTE_ENTRY(Team, TeamScore, teamScore)
|
||||||
|
};
|
||||||
|
|
||||||
|
Team::AttributeIndexSet
|
||||||
|
Team::AttributeIndex(ELEMENTS(Team::AttributePointers),
|
||||||
|
Team::AttributePointers,
|
||||||
|
Entity::AttributeIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
// Message Support
|
||||||
|
//
|
||||||
|
|
||||||
|
const Receiver::HandlerEntry
|
||||||
|
Team::MessageHandlerEntries[]=
|
||||||
|
{
|
||||||
|
MESSAGE_ENTRY(Team, Score)
|
||||||
|
};
|
||||||
|
|
||||||
|
Receiver::MessageHandlerSet
|
||||||
|
Team::MessageHandlers(
|
||||||
|
ELEMENTS(Team::MessageHandlerEntries),
|
||||||
|
Team::MessageHandlerEntries,
|
||||||
|
Entity::MessageHandlers
|
||||||
|
);
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Team::ScoreMessageHandler(ScoreMessage *score_message)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
Check(score_message);
|
||||||
|
|
||||||
|
teamScore += score_message->scoreAward;
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
void
|
||||||
|
Team::TeamSimulation(
|
||||||
|
Scalar // time_slice
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Check(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Team::Team(
|
||||||
|
MakeMessage *creation_message,
|
||||||
|
SharedData &shared_data
|
||||||
|
) :
|
||||||
|
Entity (creation_message, shared_data)
|
||||||
|
{
|
||||||
|
Str_Copy(teamName, creation_message->teamName, sizeof(teamName));
|
||||||
|
|
||||||
|
teamScore = creation_message->initialScore;
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Add this to the Entity Group of Teams
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Check(application);
|
||||||
|
EntityManager *entity_manager = application->GetEntityManager();
|
||||||
|
Check(entity_manager);
|
||||||
|
EntityGroup *team_group = entity_manager->UseGroup("Teams");
|
||||||
|
Check(team_group);
|
||||||
|
team_group->Add(this);
|
||||||
|
|
||||||
|
SetValidFlag();
|
||||||
|
|
||||||
|
Check_Fpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Team::~Team()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Team*
|
||||||
|
Team::Make(MakeMessage *creation_message)
|
||||||
|
{
|
||||||
|
Check_Fpu();
|
||||||
|
return new Team(creation_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Logical
|
||||||
|
Team::CreateMakeMessage(
|
||||||
|
MakeMessage *creation_message,
|
||||||
|
NotationFile *model_file,
|
||||||
|
const ResourceDirectories *directories
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Check(creation_message);
|
||||||
|
Check(model_file);
|
||||||
|
Check_Pointer(directories);
|
||||||
|
|
||||||
|
if (!Entity::CreateMakeMessage(creation_message, model_file, directories))
|
||||||
|
{
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
creation_message->messageLength = sizeof(Team::MakeMessage);
|
||||||
|
creation_message->classToCreate = TeamClassID;
|
||||||
|
creation_message->instanceFlags = MasterInstance | TrappedFlag | MapFlag;
|
||||||
|
Str_Copy(creation_message->teamName, "DEFUALT", sizeof(creation_message->teamName));
|
||||||
|
|
||||||
|
char *p;
|
||||||
|
#if 0
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~
|
||||||
|
// Get the TeamID
|
||||||
|
//~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
if ((p = strtok(NULL, " ")) == NULL)
|
||||||
|
{
|
||||||
|
cerr << "teamID missing!\n";
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
creation_message->teamID = atoi(p);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Get the Initial Score
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
if ((p = strtok(NULL, " ")) == NULL)
|
||||||
|
{
|
||||||
|
cerr << "InitialScore missing!\n";
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
creation_message->initialScore = atoi(p);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
//~~~~~~~~~~~~~~~
|
||||||
|
// Get the TeamName
|
||||||
|
//~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
if ((p = strtok(NULL, ",")) == NULL)
|
||||||
|
{
|
||||||
|
cerr << "teamName missing!\n";
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
Str_Copy(creation_message->teamName,p, sizeof(creation_message->teamName));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logical
|
||||||
|
Team::TestInstance() const
|
||||||
|
{
|
||||||
|
return IsDerivedFrom(ClassDerivations);
|
||||||
|
}
|
||||||
@@ -0,0 +1,305 @@
|
|||||||
|
# if !defined(MUNGA_HPP)
|
||||||
|
# include <munga.hpp>
|
||||||
|
# endif
|
||||||
|
#pragma hdrstop
|
||||||
|
|
||||||
|
# if !defined(TERRAIN_HPP)
|
||||||
|
# include <terrain.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(BOXSOLID_HPP)
|
||||||
|
# include <boxsolid.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(APP_HPP)
|
||||||
|
# include <app.hpp>
|
||||||
|
# endif
|
||||||
|
# if !defined(INTEREST_HPP)
|
||||||
|
# include <interest.hpp>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
//############################### Terrain #################################
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
// Shared Data Support
|
||||||
|
//
|
||||||
|
Derivation
|
||||||
|
Terrain::ClassDerivations(Entity::ClassDerivations, "Terrain");
|
||||||
|
|
||||||
|
Terrain::SharedData
|
||||||
|
Terrain::DefaultData(
|
||||||
|
Terrain::ClassDerivations,
|
||||||
|
Terrain::MessageHandlers,
|
||||||
|
Terrain::AttributeIndex,
|
||||||
|
Terrain::StateCount,
|
||||||
|
(Entity::MakeHandler)Terrain::Make
|
||||||
|
);
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
// Attribute Support
|
||||||
|
//
|
||||||
|
const Terrain::IndexEntry
|
||||||
|
Terrain::AttributePointers[]=
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Terrain::LocalScaleAttributeID,
|
||||||
|
"LocalScale",
|
||||||
|
(Entity::AttributePointer)&Terrain::localScale
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Terrain::AttributeIndexSet
|
||||||
|
Terrain::AttributeIndex(ELEMENTS(Terrain::AttributePointers),
|
||||||
|
Terrain::AttributePointers,
|
||||||
|
Entity::AttributeIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
// Construction and Destruction
|
||||||
|
//
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Terrain::Terrain(
|
||||||
|
Terrain::MakeMessage *creation_message,
|
||||||
|
Terrain::SharedData &virtual_data
|
||||||
|
):
|
||||||
|
Entity(creation_message, virtual_data)
|
||||||
|
{
|
||||||
|
localScale = creation_message->localScale;
|
||||||
|
SetValidFlag();
|
||||||
|
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// For now, load in the collision resources into the tree pointed to by
|
||||||
|
// this resource
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
ResourceFile *res_file = application->GetResourceFile();
|
||||||
|
Check(res_file);
|
||||||
|
ResourceDescription *res =
|
||||||
|
res_file->SearchList(
|
||||||
|
resourceID,
|
||||||
|
ResourceDescription::BoxedSolidStreamResourceType
|
||||||
|
);
|
||||||
|
|
||||||
|
collisionVolumes = NULL;
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
Check(res);
|
||||||
|
res->Lock();
|
||||||
|
InterestManager *interest_mgr =
|
||||||
|
application->GetInterestManager();
|
||||||
|
Check(interest_mgr);
|
||||||
|
InterestZone *zone =
|
||||||
|
interest_mgr->GetInterestZone(interestZoneID);
|
||||||
|
Check(zone);
|
||||||
|
BoxedSolidTree* tree = zone->GetCollisionRoot();
|
||||||
|
Check(tree);
|
||||||
|
BoxedSolidResource* solids =
|
||||||
|
(BoxedSolidResource*)res->resourceAddress;
|
||||||
|
int size = res->resourceSize / sizeof(BoxedSolidResource);
|
||||||
|
Dump(localOrigin);
|
||||||
|
while (size--)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Don't forget about scaling...
|
||||||
|
//
|
||||||
|
BoxedSolidResource rot_box;
|
||||||
|
rot_box.Instance(*solids,localOrigin);
|
||||||
|
collisionVolumes =
|
||||||
|
BoxedSolid::MakeBoxedSolid(&rot_box, this, collisionVolumes);
|
||||||
|
Register_Object(collisionVolumes);
|
||||||
|
tree->Add(collisionVolumes, rot_box.sliceExtents);
|
||||||
|
++solids;
|
||||||
|
}
|
||||||
|
res->Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Logical
|
||||||
|
Terrain::CreateMakeMessage(
|
||||||
|
MakeMessage *creation_message,
|
||||||
|
NotationFile *model_file,
|
||||||
|
const ResourceDirectories *directories
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Check(creation_message);
|
||||||
|
Check(model_file);
|
||||||
|
|
||||||
|
if (!Entity::CreateMakeMessage(creation_message, model_file, directories))
|
||||||
|
{
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
creation_message->messageLength = sizeof(MakeMessage);
|
||||||
|
creation_message->classToCreate = TerrainClassID;
|
||||||
|
creation_message->instanceFlags = HermitInstance|TrappedFlag;
|
||||||
|
|
||||||
|
char *p;
|
||||||
|
if ((p = strtok(NULL, " ")) == NULL)
|
||||||
|
{
|
||||||
|
cerr << "Scale missing!\n";
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
creation_message->localScale = atof(p);
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Terrain*
|
||||||
|
Terrain::Make(Terrain::MakeMessage *creation_message)
|
||||||
|
{
|
||||||
|
return new Terrain(creation_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Terrain::~Terrain()
|
||||||
|
{
|
||||||
|
BoxedSolid *box = collisionVolumes;
|
||||||
|
while (box)
|
||||||
|
{
|
||||||
|
BoxedSolid *next_box = box->GetNextSolid();
|
||||||
|
Unregister_Object(box);
|
||||||
|
delete box;
|
||||||
|
box = next_box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logical
|
||||||
|
Terrain::TestInstance() const
|
||||||
|
{
|
||||||
|
return IsDerivedFrom(ClassDerivations);
|
||||||
|
}
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
//######################### UnscalableTerrain ###########################
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
// Shared Data Support
|
||||||
|
//
|
||||||
|
Derivation
|
||||||
|
UnscalableTerrain::ClassDerivations(Terrain::ClassDerivations, "UnscalableTerrain");
|
||||||
|
|
||||||
|
|
||||||
|
UnscalableTerrain::SharedData
|
||||||
|
UnscalableTerrain::DefaultData(
|
||||||
|
UnscalableTerrain::ClassDerivations,
|
||||||
|
UnscalableTerrain::MessageHandlers,
|
||||||
|
UnscalableTerrain::AttributeIndex,
|
||||||
|
UnscalableTerrain::StateCount,
|
||||||
|
(Entity::MakeHandler)UnscalableTerrain::Make
|
||||||
|
);
|
||||||
|
|
||||||
|
//#############################################################################
|
||||||
|
// Construction and Destruction
|
||||||
|
//
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
UnscalableTerrain::UnscalableTerrain(
|
||||||
|
UnscalableTerrain::MakeMessage *creation_message,
|
||||||
|
UnscalableTerrain::SharedData &virtual_data
|
||||||
|
):
|
||||||
|
Entity(creation_message, virtual_data)
|
||||||
|
{
|
||||||
|
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// For now, load in the collision resources into the tree pointed to by
|
||||||
|
// this resource
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
SetValidFlag();
|
||||||
|
ResourceFile *res_file = application->GetResourceFile();
|
||||||
|
Check(res_file);
|
||||||
|
ResourceDescription *res =
|
||||||
|
res_file->SearchList(
|
||||||
|
resourceID,
|
||||||
|
ResourceDescription::BoxedSolidStreamResourceType
|
||||||
|
);
|
||||||
|
collisionVolumes = NULL;
|
||||||
|
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
Check(res);
|
||||||
|
res->Lock();
|
||||||
|
InterestManager *interest_mgr =
|
||||||
|
application->GetInterestManager();
|
||||||
|
Check(interest_mgr);
|
||||||
|
InterestZone *zone =
|
||||||
|
interest_mgr->GetInterestZone(interestZoneID);
|
||||||
|
Check(zone);
|
||||||
|
BoxedSolidTree* tree = zone->GetCollisionRoot();
|
||||||
|
Check(tree);
|
||||||
|
BoxedSolidResource* solids =
|
||||||
|
(BoxedSolidResource*)res->resourceAddress;
|
||||||
|
int size = res->resourceSize / sizeof(BoxedSolidResource);
|
||||||
|
while (size--)
|
||||||
|
{
|
||||||
|
BoxedSolidResource rot_box;
|
||||||
|
rot_box.Instance(*solids,localOrigin);
|
||||||
|
collisionVolumes =
|
||||||
|
BoxedSolid::MakeBoxedSolid(&rot_box, this, collisionVolumes);
|
||||||
|
Register_Object(collisionVolumes);
|
||||||
|
tree->Add(collisionVolumes, rot_box.sliceExtents);
|
||||||
|
++solids;
|
||||||
|
}
|
||||||
|
res->Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
Logical
|
||||||
|
UnscalableTerrain::CreateMakeMessage(
|
||||||
|
MakeMessage *creation_message,
|
||||||
|
NotationFile *model_file,
|
||||||
|
const ResourceDirectories *directories
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Check(creation_message);
|
||||||
|
Check(model_file);
|
||||||
|
|
||||||
|
if (!Entity::CreateMakeMessage(creation_message, model_file, directories))
|
||||||
|
{
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
creation_message->classToCreate = UnscalableTerrainClassID;
|
||||||
|
creation_message->instanceFlags = HermitInstance|TrappedFlag;
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
UnscalableTerrain*
|
||||||
|
UnscalableTerrain::Make(UnscalableTerrain::MakeMessage *creation_message)
|
||||||
|
{
|
||||||
|
return new UnscalableTerrain(creation_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
UnscalableTerrain::~UnscalableTerrain()
|
||||||
|
{
|
||||||
|
BoxedSolid *box = collisionVolumes;
|
||||||
|
while (box)
|
||||||
|
{
|
||||||
|
BoxedSolid *next_box = box->GetNextSolid();
|
||||||
|
Unregister_Object(box);
|
||||||
|
delete box;
|
||||||
|
box = next_box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logical
|
||||||
|
UnscalableTerrain::TestInstance() const
|
||||||
|
{
|
||||||
|
return IsDerivedFrom(ClassDerivations);
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
//===========================================================================//
|
||||||
|
// File: l4app.cpp //
|
||||||
|
// Project: MUNGA Brick: L4Application //
|
||||||
|
// Contents: Implementation details for L4Application //
|
||||||
|
//---------------------------------------------------------------------------//
|
||||||
|
// Date Who Modification //
|
||||||
|
// -------- --- ---------------------------------------------------------- //
|
||||||
|
// //
|
||||||
|
//---------------------------------------------------------------------------//
|
||||||
|
// Copyright (C) 1994, Virtual World Entertainment, Inc. //
|
||||||
|
// All Rights reserved worldwide. //
|
||||||
|
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
||||||
|
//===========================================================================//
|
||||||
|
|
||||||
|
#include <mungal4.hpp>
|
||||||
|
#pragma hdrstop
|
||||||
|
|
||||||
|
#if !defined(L4APP_HPP)
|
||||||
|
# include <l4app.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
//#############################################################################
|
||||||
|
//#############################################################################
|
||||||
|
//
|
||||||
|
const Receiver::HandlerEntry
|
||||||
|
L4Application::MessageHandlerEntries[]=
|
||||||
|
{
|
||||||
|
MESSAGE_ENTRY(L4Application, LightsOut),
|
||||||
|
MESSAGE_ENTRY(L4Application, RunMission),
|
||||||
|
MESSAGE_ENTRY(L4Application, StopMission),
|
||||||
|
MESSAGE_ENTRY(L4Application, KeyCommand)
|
||||||
|
};
|
||||||
|
|
||||||
|
L4Application::MessageHandlerSet
|
||||||
|
L4Application::MessageHandlers(
|
||||||
|
ELEMENTS(L4Application::MessageHandlerEntries),
|
||||||
|
L4Application::MessageHandlerEntries,
|
||||||
|
Application::MessageHandlers
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
//#############################################################################
|
||||||
|
//#############################################################################
|
||||||
|
//
|
||||||
|
Derivation
|
||||||
|
L4Application::ClassDerivations(
|
||||||
|
Application::ClassDerivations,
|
||||||
|
"L4Application"
|
||||||
|
);
|
||||||
|
|
||||||
|
L4Application::SharedData
|
||||||
|
L4Application::DefaultData(
|
||||||
|
L4Application::ClassDerivations,
|
||||||
|
L4Application::MessageHandlers
|
||||||
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
//#############################################################################
|
||||||
|
//#############################################################################
|
||||||
|
//
|
||||||
|
Logical
|
||||||
|
L4Application::seeSolids = False;
|
||||||
|
CString
|
||||||
|
L4Application::eggNotationFileName;
|
||||||
|
unsigned long
|
||||||
|
L4Application::networkCommonFlatAddress = 0;
|
||||||
|
int
|
||||||
|
L4Application::missionReviewMode = 0;
|
||||||
|
CString
|
||||||
|
L4Application::rioPlaybackFileName;
|
||||||
|
CString
|
||||||
|
L4Application::rioRecordingFileName;
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,52 +1,219 @@
|
|||||||
BTCameraDirector::DefaultData
|
AudioControlMixer::AudioControlMixer(PlugStream*,Entity*)
|
||||||
BTPlayer::DefaultData
|
AudioControlMixer::BuildFromPage(PlugStream*,NameList*,RegisteredClass::ClassID,long)
|
||||||
BackgroundBitmap::methodDescription
|
AudioControlMultiplier::AudioControlMultiplier(PlugStream*,Entity*)
|
||||||
BackgroundFilledRect::methodDescription
|
AudioControlMultiplier::BuildFromPage(PlugStream*,NameList*,RegisteredClass::ClassID,long)
|
||||||
BackgroundLine::methodDescription
|
AudioControlSend::AudioControlSend(PlugStream*,Entity*)
|
||||||
BackgroundPixelmap::methodDescription
|
AudioControlSend::BuildFromPage(PlugStream*,NameList*,RegisteredClass::ClassID,long)
|
||||||
BackgroundReconfig::methodDescription
|
AudioControlSmoother::AudioControlSmoother(PlugStream*,Entity*)
|
||||||
BackgroundRect::methodDescription
|
AudioControlSmoother::BuildFromPage(PlugStream*,NameList*,RegisteredClass::ClassID,long)
|
||||||
BarGraphPixelMapScalar::methodDescription
|
AudioControlSplitter::AudioControlSplitter(PlugStream*,Entity*)
|
||||||
BarGraphSolidScalar::methodDescription
|
AudioControlSplitter::BuildFromPage(PlugStream*,NameList*,RegisteredClass::ClassID,long)
|
||||||
ColorState::methodDescription
|
AudioControlsButtonMessageWatcher::AudioControlsButtonMessageWatcher(PlugStream*,Entity*)
|
||||||
CulturalIcon::DefaultData
|
AudioLFO::AudioLFO(PlugStream*,Entity*)
|
||||||
DigitalClock::methodDescription
|
AudioLFO::BuildFromPage(PlugStream*,NameList*,RegisteredClass::ClassID,long)
|
||||||
DropZone::DefaultData
|
AudioMessageWatcher::AudioMessageWatcher(PlugStream*,Entity*)
|
||||||
EulerAngles::Identity
|
AudioMessageWatcher::BuildFromPage(PlugStream*,NameList*,RegisteredClass::ClassID,long)
|
||||||
Explosion::DefaultData
|
AudioRenderer::AudioRenderer(float)
|
||||||
L4Application::ClassDerivations
|
AudioRenderer::ExecuteImplementation(float,RendererOrigin__InterestingEntityIterator*)
|
||||||
L4Application::MessageHandlers
|
AudioRenderer::FlushAudioMessages(AudioSource*)
|
||||||
L4Application::missionReviewMode
|
AudioRenderer::Initialize()
|
||||||
L4Application::rioPlaybackFileName
|
AudioRenderer::LinkToEntity(Entity*)
|
||||||
L4Application::rioRecordingFileName
|
AudioRenderer::MakeAudioHead()
|
||||||
Landmark::DefaultData
|
AudioRenderer::PostAudioRequestMessage(AudioSource*,AudioSource__RequestMessage*)
|
||||||
Mech::DefaultData
|
AudioRenderer::ProcessAudioRequestMessage()
|
||||||
MechRIOMapper::DefaultData
|
AudioRenderer::StartEntityEffectImplementation(Entity*,DamageZone*,int)
|
||||||
MechThrustmasterMapper::DefaultData
|
AudioRenderer::TestInstance() const
|
||||||
Missile::DefaultData
|
AudioRenderer::~AudioRenderer()
|
||||||
NetworkClient::ClassDerivations
|
AudioResourceSelector::AudioResourceSelector(PlugStream*,Entity*)
|
||||||
NumericDisplayInteger::methodDescription
|
AudioResourceSelector::BuildFromPage(PlugStream*,NameList*,RegisteredClass::ClassID,long)
|
||||||
NumericDisplayScalar::methodDescription
|
AudioSampleAndHold::AudioSampleAndHold(PlugStream*,Entity*)
|
||||||
NumericDisplaySpeed::methodDescription
|
AudioSampleAndHold::BuildFromPage(PlugStream*,NameList*,RegisteredClass::ClassID,long)
|
||||||
Player::AttributeIndex
|
BTCameraDirector::BTCameraDirector(Player__MakeMessage*,Entity__SharedData&)
|
||||||
Player::ClassDerivations
|
BTCameraDirector::Make(Player__MakeMessage*)
|
||||||
Player::DefaultData
|
BTL4GaugeRenderer::BTL4GaugeRenderer()
|
||||||
Player::MessageHandlers
|
BTL4Mission::BTL4Mission(NotationFile*,ResourceFile*)
|
||||||
Projectile::DefaultData
|
BTL4VideoRenderer::BTL4VideoRenderer(float,float,RendererPriority,InterestType,int)
|
||||||
Quaternion::Identity
|
BTPlayer::BTPlayer(BTPlayer__MakeMessage*,Entity__SharedData&)
|
||||||
RandomGenerator::Index
|
BTPlayer::Make(BTPlayer__MakeMessage*)
|
||||||
RankAndScore::methodDescription
|
BitMap::Make(const char*)
|
||||||
Receiver::ClassDerivations
|
BitMap::Make(int)
|
||||||
Receiver::DefaultData
|
BoundingBoxTreeNode::GetAllocatedMemory()
|
||||||
Receiver::MessageHandlers
|
CString::operator =(const CString&)
|
||||||
SegmentArcNormalized::methodDescription
|
CString::operator =(const char*)
|
||||||
Subsystem::ClassDerivations
|
CStringRepresentation::CStringRepresentation()
|
||||||
Team::AttributeIndex
|
CStringRepresentation::CStringRepresentation(const char*)
|
||||||
Team::ClassDerivations
|
CStringRepresentation::Compare(const CStringRepresentation&) const
|
||||||
Team::DefaultData
|
CStringRepresentation::GetNthToken(unsigned int,char*) const
|
||||||
Team::MessageHandlers
|
CStringRepresentation::~CStringRepresentation()
|
||||||
Terrain::DefaultData
|
Convert_From_Ascii(const char*,CString*)
|
||||||
TwoState::methodDescription
|
Exit(int)
|
||||||
UnscalableTerrain::ClassDerivations
|
ExplosionTable::CreateStreamedExplosionTable(ResourceFile*,CString,NotationFile*,CString,MemoryStream*)
|
||||||
UnscalableTerrain::DefaultData
|
ExplosionTable::ExplosionTable(MemoryStream*)
|
||||||
YawPitchRoll::Identity
|
Fail_To_Debugger(char*,char*,int)
|
||||||
|
Gauge::AddConnection(GaugeConnection*)
|
||||||
|
Gauge::DiscernTier()
|
||||||
|
Gauge::RemoveAllConnections()
|
||||||
|
Gauge::RemoveConnection(int)
|
||||||
|
Gauge::ReportProfile()
|
||||||
|
Gauge::ShowInstance(char*)
|
||||||
|
Gauge::Update(unsigned int)
|
||||||
|
Gauge::UpdateProfile(float)
|
||||||
|
GaugeBackground::GaugeBackground(unsigned long,GaugeRenderer*,unsigned int,const char*)
|
||||||
|
GaugeBase::BecameInactive()
|
||||||
|
GaugeBase::DiscernTier()
|
||||||
|
GaugeBase::Inactivate()
|
||||||
|
GaugeBase::LinkToEntity(Entity*)
|
||||||
|
GaugeBase::NotifyOfBecomingUninterestingEntity(Entity*)
|
||||||
|
GaugeBase::NotifyOfNewInterestingEntity(Entity*)
|
||||||
|
GaugeBase::ReportProfile()
|
||||||
|
GaugeBase::TestInstance() const
|
||||||
|
GaugeBase::Update(unsigned int)
|
||||||
|
GaugeBase::UpdateProfile(float)
|
||||||
|
GaugeBase::~GaugeBase()
|
||||||
|
GaugeConnection::GaugeConnection(int)
|
||||||
|
GaugeConnection::ShowInstance(char*)
|
||||||
|
GaugeConnection::~GaugeConnection()
|
||||||
|
GaugeRenderer::Configure(const char*,Entity*)
|
||||||
|
GaugeRenderer::ExecuteBackground()
|
||||||
|
GaugeRenderer::ExecuteForeground()
|
||||||
|
GaugeRenderer::ExecuteImplementation(float,RendererOrigin__InterestingEntityIterator*)
|
||||||
|
GaugeRenderer::GaugeRenderer()
|
||||||
|
GaugeRenderer::GetGraphicsPort(int)
|
||||||
|
GaugeRenderer::LinkToEntity(Entity*)
|
||||||
|
GaugeRenderer::LoadMissionImplementation(Mission*)
|
||||||
|
GaugeRenderer::LocalEmergencyShutdown()
|
||||||
|
GaugeRenderer::NotifyOfBecomingUninterestingEntity(Entity*)
|
||||||
|
GaugeRenderer::NotifyOfNewInterestingEntity(Entity*)
|
||||||
|
GaugeRenderer::Remove(unsigned int)
|
||||||
|
GaugeRenderer::ResumeImplementation()
|
||||||
|
GaugeRenderer::ShutdownImplementation()
|
||||||
|
GaugeRenderer::StartEntityAlarmImplementation(Entity*,Subsystem*,int,int)
|
||||||
|
GaugeRenderer::StopEntityAlarmImplementation(Entity*,Subsystem*,int)
|
||||||
|
GaugeRenderer::SuspendImplementation()
|
||||||
|
GaugeRenderer::TestInstance() const
|
||||||
|
GaugeRenderer::~GaugeRenderer()
|
||||||
|
GraphicGauge::GraphicGauge(unsigned int,unsigned long,GaugeRenderer*,unsigned int,int,const char*)
|
||||||
|
GraphicGauge::ShowInstance(char*)
|
||||||
|
GraphicGauge::TestInstance() const
|
||||||
|
GraphicGauge::~GraphicGauge()
|
||||||
|
GraphicGaugeBackground::GraphicGaugeBackground(unsigned long,GaugeRenderer*,unsigned int,int,const char*)
|
||||||
|
GraphicsDisplay::GraphicsDisplay(int,int)
|
||||||
|
GraphicsDisplay::ShowInstance(char*)
|
||||||
|
GraphicsDisplay::TextBounds(int,int,GraphicsDisplay::Justification,char)
|
||||||
|
GraphicsDisplay::Update(int)
|
||||||
|
GraphicsDisplay::WaitForUpdate()
|
||||||
|
GraphicsDisplay::~GraphicsDisplay()
|
||||||
|
GraphicsPort::GraphicsPort(GraphicsDisplay*,const char*)
|
||||||
|
GraphicsPort::SetColor(PaletteTriplet*,int)
|
||||||
|
GraphicsPort::ShowInstance(char*)
|
||||||
|
GraphicsPort::TextBounds(int,int,GraphicsDisplay::Justification,char)
|
||||||
|
GraphicsPort::~GraphicsPort()
|
||||||
|
GraphicsView::GraphicsView(GraphicsPort*)
|
||||||
|
GraphicsView::~GraphicsView()
|
||||||
|
L4Application::Initialize()
|
||||||
|
L4Application::KeyCommandMessageHandler(ReceiverDataMessageOf<int>*)
|
||||||
|
L4Application::L4Application(ResourceFile*,ApplicationID,RegisteredClass::ClassID,Receiver__SharedData)
|
||||||
|
L4Application::LightsOutMessageHandler(Receiver__Message*)
|
||||||
|
L4Application::MakeAndLinkViewpointEntity(Entity__MakeMessage*)
|
||||||
|
L4Application::MakeIntercomManager()
|
||||||
|
L4Application::MakeNetworkManager()
|
||||||
|
L4Application::RunMissionMessageHandler(Application__RunMissionMessage*)
|
||||||
|
L4Application::StopMissionMessageHandler(Application__StopMissionMessage*)
|
||||||
|
L4Application::Terminate()
|
||||||
|
L4Application::~L4Application()
|
||||||
|
LookupTable::Search(const char*)
|
||||||
|
MakePathedFilename(const char*,const char*)
|
||||||
|
Mech::Make(Mech__MakeMessage*)
|
||||||
|
Mech::SetMappingSubsystem(Subsystem*)
|
||||||
|
MechRIOMapper::MechRIOMapper(Mech*,int,CString,RegisteredClass::ClassID,Simulation__SharedData)
|
||||||
|
MechThrustmasterMapper::MechThrustmasterMapper(Mech*,int,CString,RegisteredClass::ClassID,Simulation__SharedData)
|
||||||
|
MemoryStream_Read(MemoryStream*,CString*)
|
||||||
|
MemoryStream_Write(MemoryStream*,const CStringRepresentation&)
|
||||||
|
Missile::Make(Mover__MakeMessage*)
|
||||||
|
NetNub::SendCommand()
|
||||||
|
NetworkClient::NetworkClient(RegisteredClass::ClassID,Receiver__SharedData,NetworkClient::ClientID)
|
||||||
|
NetworkClient::ReceiveNetworkPacket(NetworkPacket*,Receiver__Message*)
|
||||||
|
NetworkClient::~NetworkClient()
|
||||||
|
NetworkManager::Broadcast(Receiver__Message*,NetworkClient::ClientID)
|
||||||
|
NetworkManager::NetworkManager(Receiver__SharedData&)
|
||||||
|
NetworkManager::RoutePacket()
|
||||||
|
ObjectStream::BuildFromPageImplementation(NameList*,int,unsigned long)
|
||||||
|
ObjectStream::MakeObjectImplementation(int)
|
||||||
|
Palette8::BuildColorRange(int,int,PaletteTriplet,PaletteTriplet)
|
||||||
|
Palette8::Make(const char*)
|
||||||
|
Palette8::Make(int)
|
||||||
|
Palette8::Palette8()
|
||||||
|
Palette8::~Palette8()
|
||||||
|
ParameterDescription::~ParameterDescription()
|
||||||
|
PixelMap16::PixelMap16(int,int)
|
||||||
|
PixelMap16::ShowInstance(char*)
|
||||||
|
PixelMap16::~PixelMap16()
|
||||||
|
PixelMap8::Make(const char*)
|
||||||
|
PixelMap8::Make(int)
|
||||||
|
PixelMap8::PixelMap8(int,int)
|
||||||
|
PixelMap8::ShowInstance(char*)
|
||||||
|
PixelMap8::~PixelMap8()
|
||||||
|
PlugStream::AddGlobalObjectID(unsigned long,const CString&)
|
||||||
|
PlugStream::AddGlobalPlug(Plug*,unsigned long)
|
||||||
|
PlugStream::AddLocalObjectID(unsigned long,const CString&)
|
||||||
|
PlugStream::AddLocalPlug(Plug*,unsigned long)
|
||||||
|
PlugStream::BuildFromNotationFile(NotationFile*,ResourceFile*)
|
||||||
|
PlugStream::CreateObjects()
|
||||||
|
PlugStream::FindObjectID(const CString&)
|
||||||
|
PlugStream::FindPlug(unsigned long)
|
||||||
|
PlugStream::PlugStream()
|
||||||
|
PlugStream::PlugStream(ResourceDescription*)
|
||||||
|
PlugStream::TestInstance() const
|
||||||
|
PlugStream::~PlugStream()
|
||||||
|
PlugStreamManager::FindPlug(unsigned long)
|
||||||
|
PlugStreamManager::FindPlugName(const CString&)
|
||||||
|
PlugStream_FindEntryAndWriteObjectID(PlugStream*,NameList*,const CString&)
|
||||||
|
Projectile::Make(Mover__MakeMessage*)
|
||||||
|
Ray::LengthToClosestPointTo(const Point3D&)
|
||||||
|
Ray::Project(float,Point3D*)
|
||||||
|
ResourceDescription::LoadResource()
|
||||||
|
ResourceFile::AddResource(const char*,int,int,unsigned long,const void*,unsigned int,int)
|
||||||
|
ResourceFile::AddResourceList(const char*,int,int,unsigned long,const int*,int,int)
|
||||||
|
ResourceFile::AddResourceMemoryStream(const char*,int,int,unsigned long,MemoryStream*,int)
|
||||||
|
ResourceFile::FindResourceDescription(const char*,int,int)
|
||||||
|
ResourceFile::FindResourceDescription(int)
|
||||||
|
ResourceFile::ReleaseUnlockedResources()
|
||||||
|
ResourceFile::SearchList(int,const char*)
|
||||||
|
ResourceFile::SearchList(int,int)
|
||||||
|
ScenarioRole::ScenarioRole(const CString&,const CString&)
|
||||||
|
_Net_Common_Ptr
|
||||||
|
_PCSPAKActive
|
||||||
|
_PCSPAKErrors
|
||||||
|
_PCSPAKIRQState
|
||||||
|
_PCSPAKInit
|
||||||
|
_PCSPAKReceive
|
||||||
|
_PCSPAKSend
|
||||||
|
_PCSPAKSetDTR
|
||||||
|
_PCSPAKTerm
|
||||||
|
_PCSPAKTransmitCount
|
||||||
|
_PCSerialActive
|
||||||
|
_PCSerialFlowControl
|
||||||
|
_PCSerialInit
|
||||||
|
_PCSerialSend
|
||||||
|
_PCSerialTerm
|
||||||
|
_PCSerialTransmitCount
|
||||||
|
_PC_Joystick1_Raw_X
|
||||||
|
_PC_Joystick1_Raw_Y
|
||||||
|
_PC_Joystick2_Raw_Y
|
||||||
|
_PC_Joystick_Buttons
|
||||||
|
_PC_Joystick_Mask
|
||||||
|
_PC_Joystick_Update
|
||||||
|
_SVGAFunkyVideo
|
||||||
|
_SVGASetMode
|
||||||
|
_SVGASetPage
|
||||||
|
_SVGASetSplitterClock
|
||||||
|
_SVGATransfer32
|
||||||
|
_SVGATransfer32x
|
||||||
|
_SVGAWriteFullPalette
|
||||||
|
_SVGAWritePaletteMask
|
||||||
|
_SVGAZeroPalette
|
||||||
|
_iThinkIRQIsOn
|
||||||
|
_pcspakCharactersSent
|
||||||
|
_sosMIDIAWE32ReleaseSBKFiles
|
||||||
|
_sosMIDIAWE32SetSBKFile
|
||||||
|
operator +(const CStringRepresentation&,const CStringRepresentation&)
|
||||||
|
|||||||
@@ -19,7 +19,30 @@ def main():
|
|||||||
donor, out = sys.argv[1], sys.argv[2]
|
donor, out = sys.argv[1], sys.argv[2]
|
||||||
name = os.path.splitext(os.path.basename(out))[0].upper()
|
name = os.path.splitext(os.path.basename(out))[0].upper()
|
||||||
guard = "%s_HPP" % name
|
guard = "%s_HPP" % name
|
||||||
body = open(donor, "r", errors="replace").read().splitlines()
|
text = open(donor, "r", errors="replace").read()
|
||||||
|
# WinTesla wrapped the 1995 static objects in accessor functions (its
|
||||||
|
# static-init-order fix); unwrap them back to plain 1995 definitions.
|
||||||
|
text = re.sub(
|
||||||
|
r"Derivation\s*\*\s*(\w+)::GetClassDerivations\(\)\s*"
|
||||||
|
r"\{\s*static\s+Derivation\s+\w+\s*\(([^;]*?)\);\s*return\s*&\w+;\s*\}",
|
||||||
|
r"Derivation\n\t\1::ClassDerivations(\2);",
|
||||||
|
text, flags=re.S)
|
||||||
|
text = re.sub(
|
||||||
|
r"(?:Receiver::)?MessageHandlerSet\s*&?\s*(\w+)::GetMessageHandlers\(\)\s*"
|
||||||
|
r"\{\s*static\s+(?:\w+::)?MessageHandlerSet\s+\w+\s*\(([^;]*?)\);\s*return\s*\w+;\s*\}",
|
||||||
|
r"\1::MessageHandlerSet\n\t\1::MessageHandlers(\2);",
|
||||||
|
text, flags=re.S)
|
||||||
|
text = re.sub(
|
||||||
|
r"(?:\w+::)?AttributeIndexSet\s*&?\s*(\w+)::GetAttributeIndex\(\)\s*"
|
||||||
|
r"\{\s*static\s+(?:\w+::)?AttributeIndexSet\s+\w+\s*\(([^;]*?)\);\s*return\s*\w+;\s*\}",
|
||||||
|
r"\1::AttributeIndexSet\n\t\1::AttributeIndex(\2);",
|
||||||
|
text, flags=re.S)
|
||||||
|
text = re.sub(
|
||||||
|
r"MemoryBlock\s*\*\s*(\w+)::GetAllocatedMemory\(\)\s*"
|
||||||
|
r"\{\s*static\s+MemoryBlock\s+\w+\s*\(([^;]*?)\);\s*return\s*&\w+;\s*\}",
|
||||||
|
r"MemoryBlock\n\t\1::AllocatedMemory(\2);",
|
||||||
|
text, flags=re.S)
|
||||||
|
body = text.splitlines()
|
||||||
res = []
|
res = []
|
||||||
warned = set()
|
warned = set()
|
||||||
for line in body:
|
for line in body:
|
||||||
@@ -36,6 +59,26 @@ def main():
|
|||||||
res.append("#\tendif")
|
res.append("#\tendif")
|
||||||
continue
|
continue
|
||||||
# post-1994 C++ the 4.52 compiler rejects: de-modernize
|
# post-1994 C++ the 4.52 compiler rejects: de-modernize
|
||||||
|
line = re.sub(r"\b(\w+)::GetClassDerivations\(\)", r"\1::ClassDerivations", line)
|
||||||
|
line = re.sub(r"\b(\w+)::GetMessageHandlers\(\)", r"\1::MessageHandlers", line)
|
||||||
|
line = re.sub(r"\b(\w+)::GetAttributeIndex\(\)", r"\1::AttributeIndex", line)
|
||||||
|
line = re.sub(r"\b(\w+)::GetAllocatedMemory\(\)", r"\1::AllocatedMemory", line)
|
||||||
|
# header-side: 2007 accessor DECLARATIONS -> 1995 static objects
|
||||||
|
line = re.sub(r"static\s+Derivation\s*\*\s*GetClassDerivations\(\);",
|
||||||
|
"static Derivation ClassDerivations;", line)
|
||||||
|
line = re.sub(r"static\s+(?:\w+::)?MessageHandlerSet\s*&?\s*GetMessageHandlers\(\);",
|
||||||
|
"static MessageHandlerSet MessageHandlers;", line)
|
||||||
|
line = re.sub(r"static\s+(?:\w+::)?AttributeIndexSet\s*&?\s*GetAttributeIndex\(\);",
|
||||||
|
"static AttributeIndexSet AttributeIndex;", line)
|
||||||
|
line = line.replace("Shutdown(int remainingApps);", "Shutdown(int remainingApps = 0);")
|
||||||
|
line = re.sub(r"\*?\s*(?<![:\w])GetClassDerivations\(\)", "ClassDerivations", line)
|
||||||
|
line = re.sub(r"(?<![:\w])GetMessageHandlers\(\)", "MessageHandlers", line)
|
||||||
|
line = re.sub(r"(?<![:\w])GetAttributeIndex\(\)", "AttributeIndex", line)
|
||||||
|
line = line.replace("PostQuitMessage(AbortExitCodeID);", 'Fail("Exiting");')
|
||||||
|
for bad in ("atlbase.h", "windows.h", "winsock"):
|
||||||
|
if bad in line and "#include" in line:
|
||||||
|
line = ""
|
||||||
|
break
|
||||||
line = re.sub(r"\bstd::", "", line)
|
line = re.sub(r"\bstd::", "", line)
|
||||||
line = re.sub(r"\btrue\b", "True", line)
|
line = re.sub(r"\btrue\b", "True", line)
|
||||||
line = re.sub(r"\bfalse\b", "False", line)
|
line = re.sub(r"\bfalse\b", "False", line)
|
||||||
@@ -54,10 +97,20 @@ def main():
|
|||||||
# strip leading blank lines
|
# strip leading blank lines
|
||||||
while res and not res[0].strip():
|
while res and not res[0].strip():
|
||||||
res.pop(0)
|
res.pop(0)
|
||||||
|
out_text = "\n".join(res)
|
||||||
|
# cleanups after the accessor unwrap: a deref of the former pointer
|
||||||
|
# accessor, and doubled class prefixes from the static rename
|
||||||
|
out_text = re.sub(r"\*\s*(\w+)::ClassDerivations\b", r"\1::ClassDerivations", out_text)
|
||||||
|
out_text = re.sub(r"\b(\w+)::\1::", r"\1::", out_text)
|
||||||
|
is_header = out.upper().endswith((".HPP", ".H", ".THP"))
|
||||||
with open(out, "w", newline="\r\n") as f:
|
with open(out, "w", newline="\r\n") as f:
|
||||||
f.write("#if !defined(%s)\n#\tdefine %s\n\n" % (guard, guard))
|
if is_header:
|
||||||
f.write("\n".join(res))
|
f.write("#if !defined(%s)\n#\tdefine %s\n\n" % (guard, guard))
|
||||||
f.write("\n\n#endif\n")
|
f.write(out_text)
|
||||||
|
if is_header:
|
||||||
|
f.write("\n\n#endif\n")
|
||||||
|
else:
|
||||||
|
f.write("\n")
|
||||||
print("wrote %s (%d lines from %s)" % (out, len(res) + 5, donor))
|
print("wrote %s (%d lines from %s)" % (out, len(res) + 5, donor))
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ srcfor() { # srcfor <name.cpp> <BTdir> <RPdir> [S410dir]
|
|||||||
case "$1" in
|
case "$1" in
|
||||||
filestrm.cpp) echo "$3/FILESTRM.CPP"; return;; # BT pair = post-4.10 drift
|
filestrm.cpp) echo "$3/FILESTRM.CPP"; return;; # BT pair = post-4.10 drift
|
||||||
l4vidper.cpp|l4tsdpl.cpp) return;; # not in mungal4.lib
|
l4vidper.cpp|l4tsdpl.cpp) return;; # not in mungal4.lib
|
||||||
|
filestub.cpp) return;; # stub.lib member (prebuilt obj)
|
||||||
esac
|
esac
|
||||||
for d in "$2" "$4" "$3"; do # BT first, then source410, then RP
|
for d in "$2" "$4" "$3"; do # BT first, then source410, then RP
|
||||||
[ -z "$d" ] && continue
|
[ -z "$d" ] && continue
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public:
|
|||||||
|
|
||||||
Logical TestInstance() const;
|
Logical TestInstance() const;
|
||||||
|
|
||||||
protected:
|
public:
|
||||||
int fileHandle;
|
int fileHandle;
|
||||||
Logical readOnly;
|
Logical readOnly;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user