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>
774 lines
20 KiB
C++
774 lines
20 KiB
C++
#include "munga.h"
|
|
#pragma hdrstop
|
|
|
|
#include "explode.h"
|
|
#include "mover.h"
|
|
#include "boxsolid.h"
|
|
#include "collasst.h"
|
|
#include "damage.h"
|
|
#include "random.h"
|
|
#include "app.h"
|
|
#include "objstrm.h"
|
|
#include "hostmgr.h"
|
|
#include "notation.h"
|
|
#include "namelist.h"
|
|
|
|
//#############################################################################
|
|
//############################ Explosion ################################
|
|
//#############################################################################
|
|
|
|
//#############################################################################
|
|
// Shared Data Support
|
|
//
|
|
Derivation* Explosion::GetClassDerivations()
|
|
{
|
|
static Derivation classDerivations(Entity::GetClassDerivations(), "Explosion");
|
|
return &classDerivations;
|
|
}
|
|
|
|
Explosion::SharedData
|
|
Explosion::DefaultData(
|
|
Explosion::GetClassDerivations(),
|
|
Explosion::GetMessageHandlers(),
|
|
Explosion::GetAttributeIndex(),
|
|
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::GetClassDerivations()))
|
|
{
|
|
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::GetClassDerivations()));
|
|
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 << std::endl << std::flush;
|
|
DEBUG_STREAM << "Damage per burst is " << some_damage.damageAmount << std::endl << std::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." << std::endl << std::flush;
|
|
}
|
|
|
|
if (excluded && target_entity->GetEntityID() == excluded->GetEntityID() )
|
|
{
|
|
DEBUG_STREAM << "Splash damage hurting excluded entity!" << std::endl << std::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" << std::endl << std::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(*GetClassDerivations());
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
// 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
|
|
)
|
|
)
|
|
{
|
|
std::cerr<<model_file<<" missing ExplosionDuration"<<std::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)
|
|
{
|
|
std::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);
|
|
}
|