Files
CydandClaude Opus 4.8 4abbf8879f Initial import of Red Planet v4.10 Win32 source
Imports the current Win32 source for the pod-racing game 'Red Planet',
built on the MUNGA engine and its L4 (Win32/DirectX) platform layer:

- MUNGA / MUNGA_L4: cross-platform engine core and Win32 backend
- RP / RP_L4: Red Planet game logic and Win32 application
- DivLoader, Setup1: asset loader and installer project
- lib, MUNGA_L4/openal, MUNGA_L4/sos: third-party audio dependencies

Removed stale Subversion metadata and added .gitignore/.gitattributes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 07:59:51 -05:00

1074 lines
24 KiB
C++

#include "munga.h"
#pragma hdrstop
#include "cultural.h"
#include "terrain.h"
#include "fileutil.h"
#include "boxtree.h"
#include "boxsolid.h"
#include "scnrole.h"
#include "mission.h"
#include "explode.h"
#include "app.h"
#include "interest.h"
#include "hostmgr.h"
#include "nttmgr.h"
#include "namelist.h"
#include "console.h"
//##########################################################################
//##################### Class CulturalIcon ##########################
//##########################################################################
//#############################################################################
// Shared Data Support
//
Derivation* CulturalIcon::GetClassDerivations()
{ static Derivation classDerivations(UnscalableTerrain::GetClassDerivations(), "CulturalIcon");
return &classDerivations;
}
CulturalIcon::SharedData
CulturalIcon::DefaultData(
CulturalIcon::GetClassDerivations(),
CulturalIcon::GetMessageHandlers(),
CulturalIcon::GetAttributeIndex(),
CulturalIcon::StateCount,
(UnscalableTerrain::MakeHandler)CulturalIcon::Make
);
//#############################################################################
// Message Support
//
const Receiver::HandlerEntry
CulturalIcon::MessageHandlerEntries[]=
{
MESSAGE_ENTRY(CulturalIcon, TakeDamage),
MESSAGE_ENTRY(CulturalIcon, SetBurningState)
};
CulturalIcon::MessageHandlerSet& CulturalIcon::GetMessageHandlers()
{
static CulturalIcon::MessageHandlerSet messageHandlers(ELEMENTS(CulturalIcon::MessageHandlerEntries), CulturalIcon::MessageHandlerEntries, UnscalableTerrain::GetMessageHandlers());
return messageHandlers;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
CulturalIcon::SetBurningStateMessageHandler(Message * /*burning_message*/)
{
SetSimulationState(CulturalIcon::BurningState);
ForceUpdate(DefaultUpdateModelFlag);
AlwaysExecute();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
CulturalIcon::TakeDamageMessageHandler(TakeDamageMessage *damage_message)
{
Check(damage_message);
if (damage_message->damageZone == -1 )
{
damage_message->damageZone = 0;
}
if (GetSimulationState() == CulturalIcon::DefaultState)
{
//
//~~~~~~~~~~~~~~~~~~
// Update Replicants
//~~~~~~~~~~~~~~~~~~
//
if (GetInstance() != ReplicantInstance)
{
ForceUpdate(DamageZoneUpdateModelFlag | DefaultUpdateModelFlag);
AlwaysExecute();
}
//
//~~~~~~~~~~~~~~~~~~~~~
// Call Derived Classes
//~~~~~~~~~~~~~~~~~~~~~
//
UnscalableTerrain::TakeDamageMessageHandler(damage_message);
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Update Collision Volumes if we died
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
for(int ii=0;ii<damageZoneCount;++ii)
{
if(damageZones[ii]->GetDamageZoneState() == DamageZone::BurningState)
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Create the explosion
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Origin explode_origin = localOrigin;
ResourceDescription::ResourceID explosion_ID;
if ((damage_message->damageData.damageType == Damage::CollisionDamageType )&&
(crunchExplosionResourceID != -1))
{
explosion_ID = crunchExplosionResourceID;
}
else
{
explosion_ID = explosionResourceID;
}
Explosion::MakeMessage exp_message(
Explosion::MakeMessageID,
sizeof(Explosion::MakeMessage),
RegisteredClass::ExplosionClassID,
EntityID::Null,
explosion_ID,
Explosion::DefaultFlags,
explode_origin,
GetEntityID(),
GetEntityID()
);
#if (DEBUG_LEVEL > 0)
Explosion *new_exp =
#endif
Explosion::Make(&exp_message);
Register_Object(new_exp);
Message dummy_message(SetBurningStateMessageID, sizeof(Message));
Check(application);
Time now = Now();
now += timeDelay;
application->Post(CreationEventPriority, this, &dummy_message, now);
SetSimulationState(WaitingToBurn);
UpdateCollisionVolumes();
break;
}
}
}
Check_Fpu();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
CulturalIcon::UpdateCollisionVolumes()
{
Check(this);
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Get the Tree for these Collision Volumes
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
InterestManager *interest_mgr =
application->GetInterestManager();
Check(interest_mgr);
InterestZone *zone =
interest_mgr->GetInterestZone(interestZoneID);
Check(zone);
BoxedSolidTree* tree = zone->GetCollisionRoot();
Check(tree);
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Update Volumes based on RemoveVolume Flag
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
BoxedSolid *box = collisionVolumes;
while (box)
{
BoxedSolid *next_box = box->GetNextSolid();
if (RemoveCollisionVolumeOnDeath())
{
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Delete the Collision Volume
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
tree->Remove(box);
Unregister_Object(box);
delete box;
}
else
{
//
//~~~~~~~~~~~~~~~~~~~~~~
// Move Collision Volume
//~~~~~~~~~~~~~~~~~~~~~~
//
box->minY += destroyedYTranslation;
box->maxY += destroyedYTranslation;
}
box = next_box;
}
collisionVolumes = NULL;
Check_Fpu();
}
//#############################################################################
// Attribute Support
//
const CulturalIcon::IndexEntry
CulturalIcon::AttributePointers[]=
{
ATTRIBUTE_ENTRY(CulturalIcon, TeamName, teamName)
};
CulturalIcon::AttributeIndexSet& CulturalIcon::GetAttributeIndex()
{
static CulturalIcon::AttributeIndexSet attributeIndex(ELEMENTS(CulturalIcon::AttributePointers),
CulturalIcon::AttributePointers,
UnscalableTerrain::GetAttributeIndex()
);
return attributeIndex;
}
//#############################################################################
// Construction and Destruction
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
CulturalIcon::CulturalIcon(
MakeMessage *creation_message,
SharedData &shared_data
) :
UnscalableTerrain(creation_message, shared_data)
{
Str_Copy(teamName, "Defualt", sizeof(teamName));
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Read in the ModelResource Information
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ResourceDescription *res =
application->GetResourceFile()->SearchList(
resourceID,
ResourceDescription::GameModelResourceType
);
Check(res);
res->Lock();
ModelResource* model_resource = (ModelResource*)res->resourceAddress;
Check_Pointer(model_resource);
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Determine if we move or Destroy the
// Collision volume in Death of the map entity
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
if (model_resource->sinkCollisionVolume)
{
destroyedYTranslation = model_resource->destroyedYTranslation;
}
else
{
destroyedYTranslation = 0.0f;
SetRemoveCollisionVolumeFlag();
}
timeDelay = model_resource->timeDelay;
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Is Stopping Collision Volume ?
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
if (model_resource->stoppingCollisionVolume)
{
SetStoppingCollisionVolumeFlag();
}
explosionResourceID = model_resource->explosionResourceID;
crunchExplosionResourceID = model_resource->crunchExplosionResourceID;
res->Unlock();
//DEBUG_STREAM << model_resource->crunchExplosionResourceID << std::endl << std::flush;
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Read in DamageZone Information from the Resource
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ResourceDescription *dmg_res =
application->GetResourceFile()->SearchList(
resourceID,
ResourceDescription::DamageZoneStreamResourceType
);
Check(dmg_res);
dmg_res->Lock();
DynamicMemoryStream damage_stream (
dmg_res->resourceAddress,
dmg_res->resourceSize
);
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~
// skip over DamageZoneCount
//~~~~~~~~~~~~~~~~~~~~~~~~~~
//
damage_stream.AdvancePointer(sizeof(damageZoneCount));
//
//~~~~~~~~~~~~~~~~~~~~~~~
// Create the DamageZones
//~~~~~~~~~~~~~~~~~~~~~~~
//
for(int ii=0;ii<damageZoneCount;++ii)
{
damageZones[ii] = new DamageZone(
this,
ii,
&damage_stream
);
Register_Object(damageZones[ii]);
}
SetValidFlag();
dmg_res->Unlock();
Check_Fpu();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
CulturalIcon::ReadUpdateRecord(Simulation::UpdateRecord *message)
{
Check(this);
Check_Pointer(message);
UnscalableTerrain::ReadUpdateRecord(message);
if (simulationState.GetOldState() != GetSimulationState() && (GetSimulationState() == BurningState))
{
UpdateCollisionVolumes();
}
Check_Fpu();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Logical
CulturalIcon::CreateMakeMessage(
MakeMessage *creation_message,
NotationFile *model_file,
const ResourceDirectories *directories
)
{
Check(creation_message);
Check(model_file);
if (!UnscalableTerrain::CreateMakeMessage(creation_message, model_file, directories))
{
return False;
}
creation_message->messageLength = sizeof(MakeMessage);
creation_message->classToCreate = CulturalIconClassID;
creation_message->instanceFlags = MasterInstance|DynamicFlag|MapFlag|TrappedFlag;
return True;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
CulturalIcon*
CulturalIcon::Make(MakeMessage *creation_message)
{
Check_Fpu();
return new CulturalIcon(creation_message);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
CulturalIcon::~CulturalIcon()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
CulturalIcon::CreateModelResource(
#if DEBUG_LEVEL>0
ResourceFile *resource_file,
const char *model_name,
NotationFile *model_file,
const ResourceDirectories *directories,
ModelResource* model
#else
ResourceFile *resource_file,
const char *model_name,
NotationFile *model_file,
const ResourceDirectories *,
ModelResource* model
#endif
)
{
Check(resource_file);
Check_Pointer(model_name);
Check(model_file);
Check_Pointer(directories);
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Allocate memory for the resource
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ModelResource *local_model = model;
if (!local_model)
{
local_model = new ModelResource;
Register_Pointer(local_model);
}
if (
!model_file->GetEntry(
"gamedata",
"DestroyedYTranslation",
&local_model->destroyedYTranslation
)
)
{
local_model->sinkCollisionVolume = False;
local_model->destroyedYTranslation = 0.0f;
}
else
{
local_model->sinkCollisionVolume = True;
}
if (!model_file->GetLogicalEntry(
"gamedata",
"StoppingCollisionVolume",
&local_model->stoppingCollisionVolume
)
)
{
local_model->stoppingCollisionVolume = False;
}
if (
!model_file->GetEntry(
"gamedata",
"TimeDelay",
&local_model->timeDelay
)
)
{
DEBUG_STREAM << model_name << " TimeDelay is missing " << std::endl << std::flush;
PostQuitMessage(AbortExitCodeID);
}
//
//----------------------------------------------------------------------
// Read in the Model Filename of the Explosion renderable, then find its
// resource ID in the resource file
//----------------------------------------------------------------------
//
const char *explosion = "Unspecified";
if (
!model_file->GetEntry(
"gamedata",
"ExplosionModelFile",
&explosion
)
)
{
std::cout << model_name << " missing ExplosionModelFile!\n";
Check_Fpu();
return False;
}
ResourceDescription *res = NULL;
if (strcmp(explosion,"Unspecified"))
{
res = resource_file->FindResourceDescription(
explosion,
ResourceDescription::ModelListResourceType
);
}
if (!res)
{
std::cout << model_name << " cannot find " << explosion
<< " in resource file!\n";
Check_Fpu();
return False;
}
if (res)
{
local_model->explosionResourceID = res->resourceID;
}
const char *crunch_explosion = "Unspecified";
model_file->GetEntry(
"gamedata",
"CrunchExplosionModelFile",
&crunch_explosion
);
local_model->crunchExplosionResourceID = -1;
if (strcmp(crunch_explosion,"Unspecified"))
{
//res = NULL;
res = resource_file->FindResourceDescription(
crunch_explosion,
ResourceDescription::ModelListResourceType
);
if (!res)
{
std::cout << model_name << " cannot find " << crunch_explosion
<< " in resource file!\n";
Check_Fpu();
return False;
}
else
{
local_model->crunchExplosionResourceID = res->resourceID;
}
}
//DEBUG_STREAM << ":" << local_model->crunchExplosionResourceID << std::endl << std::flush;
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Write the model to the resource
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
if (!model)
{
ResourceDescription *new_res =
resource_file->AddResource(
model_name,
ResourceDescription::GameModelResourceType,
1,
ResourceDescription::Preload,
local_model,
sizeof(*local_model)
);
Unregister_Pointer(local_model);
delete local_model;
Check(new_res);
Check_Fpu();
return new_res->resourceID;
}
else
{
Check_Fpu();
return 0;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
CulturalIcon::CreateDamageZoneStream(
ResourceFile *resource_file,
const char *model_name,
NotationFile *model_file,
const ResourceDirectories *directories
)
{
Check(resource_file);
Check_Pointer(model_name);
Check(model_file);
Check_Pointer(directories);
//
//-------------------
// Find the .dmg file
//-------------------
//
const char* dmg_file_cname;
if (
!model_file->GetEntry(
"gamedata",
"DamageZones",
&dmg_file_cname
)
)
{
std::cerr << model_name << " is missing .dmg file specification!\n";
return -1;
}
CString dmg_filename =
MakePathedFilename(directories->modelDirectory, dmg_file_cname);
NotationFile *dmg_file = new NotationFile(dmg_filename);
Register_Object(dmg_file);
int page_count = dmg_file->PageCount();
if (!page_count)
{
std::cerr << dmg_filename << " is empty or missing!\n";
Unregister_Object(dmg_file);
delete dmg_file;
return -1;
}
DynamicMemoryStream damage_stream;
damage_stream << page_count;
NameList *dmg_namelist = dmg_file->MakePageList();
Register_Object(dmg_namelist);
NameList::Entry *dmg_entry = dmg_namelist->GetFirstEntry();
CString dmg_page_name;
while(dmg_entry)
{
dmg_page_name = dmg_entry->GetName();
DamageZone::CreateStreamedDamageZone(
model_file,
model_name,
NULL,
dmg_page_name,
&damage_stream,
dmg_file,
directories
);
dmg_entry = dmg_entry->GetNextEntry();
}
//
//~~~~~~~~~~~~~~~~~~~~~~~
// Add Stream to Resource
//~~~~~~~~~~~~~~~~~~~~~~~
//
ResourceDescription *new_res =
resource_file->AddResourceMemoryStream(
model_name,
ResourceDescription::DamageZoneStreamResourceType,
1,
ResourceDescription::Preload,
&damage_stream
);
Check(new_res);
Unregister_Object(dmg_file);
delete dmg_file;
Unregister_Object(dmg_namelist);
delete dmg_namelist;
return new_res->resourceID;
}
//##########################################################################
//#################### Class Landmark ##########################
//##########################################################################
//#############################################################################
// Shared Data Support
//
Derivation* Landmark::GetClassDerivations()
{ static Derivation classDerivations(CulturalIcon::GetClassDerivations(), "Landmark");
return &classDerivations;
}
Landmark::SharedData
Landmark::DefaultData(
Landmark::GetClassDerivations(),
Landmark::MessageHandlers,
Landmark::GetAttributeIndex(),
Landmark::StateCount,
(Landmark::MakeHandler)Landmark::Make
);
//#############################################################################
// Message Support
//
const Receiver::HandlerEntry
Landmark::MessageHandlerEntries[]=
{
MESSAGE_ENTRY(Landmark, TakeDamage)
};
Landmark::MessageHandlerSet
Landmark::MessageHandlers(
ELEMENTS(Landmark::MessageHandlerEntries),
Landmark::MessageHandlerEntries,
CulturalIcon::GetMessageHandlers()
);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
Landmark::TakeDamageMessageHandler(TakeDamageMessage *damage_message)
{
Check(damage_message);
if (owningTeam == NULL)
{
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialize the owning team pointer
// with the Teams entity Group
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Check(application);
EntityManager *entity_manager = application->GetEntityManager();
Check(entity_manager);
EntityGroup *team_group = entity_manager->UseGroup("Teams");
if (team_group)
{
ChainIteratorOf<Node*> team_iterator(team_group->groupMembers);
Team *current_team;
while((current_team = (Team*) team_iterator.ReadAndNext() ) != NULL)
{
if (!strcmp(current_team->teamName, teamName))
{
owningTeam = current_team;
break;
}
}
}
}
if (owningTeam == NULL)
{
DEBUG_STREAM << "TEAM : '" << teamName << "' was never found! " << std::endl << std::flush;
exit (-1);
}
if (GetSimulationState() != BurningState)
{
CulturalIcon::TakeDamageMessageHandler(damage_message);
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Calculate the Score Loss based
// on the Scenario Data
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Check(scenarioRole);
#if 0
Logical landmark_destroyed = GetSimulationState() == BurningState;
Scalar score_loss = scenarioRole->CalcDamageReceivedScore(
damage_message->damageData.damageAmount
);
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Tell the Console about the Damage
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Check(application);
HostManager *host_manager = application->GetHostManager();
Check(host_manager);
Host *console_host = host_manager->GetConsoleHost();
if (console_host)
{
Check(console_host);
ConsoleLandmarkDamagedMessage landmark_damaged_message(
damage_message->inflictingEntity.GetHostID(),
landmarkID,
damage_message->damageData.damageAmount,
landmark_destroyed,
score_loss
);
application->SendMessage(
console_host->GetHostID(),
NetworkClient::ConsoleClientID,
&landmark_damaged_message
);
}
#endif
}
}
Logical
CulturalIcon::TestInstance() const
{
return IsDerivedFrom(*GetClassDerivations());
}
//#############################################################################
// Construction and Destruction
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Landmark::Landmark(
MakeMessage *creation_message,
SharedData &shared_data
) :
CulturalIcon ( creation_message, shared_data)
{
scenarioRole = NULL;
owningTeam = NULL;
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initialize the owning team pointer
// with the Teams entity Group
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Check(application);
EntityManager *entity_manager = application->GetEntityManager();
Check(entity_manager);
EntityGroup *team_group = entity_manager->UseGroup("Teams");
if (team_group)
{
ChainIteratorOf<Node*> team_iterator(team_group->groupMembers);
Team *current_team;
while((current_team = (Team*) team_iterator.ReadAndNext() ) != NULL)
{
if (!strcmp(current_team->teamName, creation_message->teamName))
{
owningTeam = current_team;
break;
}
}
}
//
// If the team is null, that's ok. It will either show up over the network
// or be a free for all
//
Str_Copy(teamName, creation_message->teamName, sizeof(teamName));
Check(application->GetCurrentMission());
scenarioRole =
application->GetCurrentMission()->GetScenarioRole(creation_message->roleName);
if (!scenarioRole)
{
scenarioRole = new ScenarioRole("Role::MapAssigned",creation_message->roleName);
Register_Object(scenarioRole);
application->GetCurrentMission()->AddScenarioRole(scenarioRole);
}
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Add this landmark to the Landmark Entity Group
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
EntityGroup *landmark_group = entity_manager->UseGroup("Landmarks");
Check(landmark_group);
landmark_group->Add(this);
Check_Fpu();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Landmark::~Landmark()
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Logical
Landmark::CreateMakeMessage(
MakeMessage *creation_message,
NotationFile *model_file,
const ResourceDirectories *directories
)
{
Check(creation_message);
Check(model_file);
if (!CulturalIcon::CreateMakeMessage(creation_message, model_file, directories))
{
return False;
}
creation_message->messageLength = sizeof(MakeMessage);
creation_message->classToCreate = LandmarkClassID;
char *p;
//
//----------------------------
// landmarkID allocated
// by map stream creation
//----------------------------
//
//
//~~~~~~~~~~~~~~~
// Get the teamName
//~~~~~~~~~~~~~~~
//
if ((p = strtok(NULL, ",")) == NULL)
{
std::cerr << "teamName missing!\n";
return False;
}
Str_Copy(creation_message->teamName,p, sizeof(creation_message->teamName));
//
//~~~~~~~~~~~~~~~~~
// Get the roleName
//~~~~~~~~~~~~~~~~~
//
if ((p = strtok(NULL, ",")) == NULL)
{
std::cerr << "roleName missing!\n";
return False;
}
Str_Copy(creation_message->roleName,p, sizeof(creation_message->roleName));
//
//~~~~~~~~~~~~~~~~~~~~~~
// Get the Landmark Name
//~~~~~~~~~~~~~~~~~~~~~~
//
if ((p = strtok(NULL, ",")) == NULL)
{
std::cerr << "Landmark Name missing!\n";
return False;
}
Str_Copy(creation_message->landmarkName,p, sizeof(creation_message->landmarkName));
return True;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Landmark*
Landmark::Make(MakeMessage *creation_message)
{
Check_Fpu();
return new Landmark(creation_message);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
Landmark::CreateModelResource(
ResourceFile *resource_file,
const char *model_name,
NotationFile *model_file,
const ResourceDirectories *directories,
ModelResource* model
)
{
Check(resource_file);
Check_Pointer(model_name);
Check(model_file);
Check_Pointer(directories);
CulturalIcon::CreateModelResource(resource_file, model_name, model_file, directories, model);
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Allocate memory for the resource
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ModelResource *local_model = model;
if (!local_model)
{
local_model = new ModelResource;
Register_Pointer(local_model);
}
#if 0
const char *role_model_file;
if (!model_file->GetEntry(
"gamedata",
"RoleModelFile",
&role_model_file
)
)
{
std::cerr<<model_name<<" missing RoleModelFile ! \n"<<std::endl;
Dump_And_Die:
if (local_model)
{
Unregister_Pointer(local_model);
delete local_model;
}
return -1;
}
else
{
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Hunt for Model file in ResourceFile
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ResourceDescription *res;
res = resource_file->FindResourceDescription(
role_model_file,
ResourceDescription::ModelListResourceType
);
if (!res)
{
std::cout << model_name << " cannot find " << role_model_file
<< " in resource file!\n";
goto Dump_And_Die;
}
local_model->roleResourceID = res->resourceID;
}
#endif
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Write the model to the resource
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
if (!model)
{
ResourceDescription *new_res =
resource_file->AddResource(
model_name,
ResourceDescription::GameModelResourceType,
1,
ResourceDescription::Preload,
local_model,
sizeof(*local_model)
);
Unregister_Pointer(local_model);
delete local_model;
Check(new_res);
Check_Fpu();
return new_res->resourceID;
}
else
{
Check_Fpu();
return 0;
}
}
Logical
Landmark::TestInstance() const
{
return IsDerivedFrom(*GetClassDerivations());
}