#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;iiGetDamageZoneState() == 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;iiUnlock(); 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 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 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<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()); }