#include "MW4Headers.hpp" #pragma warning(disable:4100) // unreferenced formal parameter #include "CampaignMechLab.hpp" #include #include "Mech.hpp" #include "MWDamageObject.hpp" #include "Subsystem.hpp" #include "Weapon.hpp" #include "MWMover.hpp" #include "Armor.hpp" #include "SubsystemClassData.hpp" #include "Salvage.hpp" #include "MWGame.hpp" #include "MWApplication.hpp" #include "MWTable.hpp" #include #include #include #include #include #include #include #include "..\buildnum\buildnum.h" // jcem begin #if 1 // jcem for MechView, CampaignMechLab.cpp too #define CONN4ML (Connection::Hermit) #else #define CONN4ML (Connection::Local) #endif // jcem end //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CampaignMechLab::CampaignMechLab() : MechLab() { // m_chassisCount = GetChassisCount(); m_isCampaign = 1; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void CampaignMechLab::ReInitialize() { m_mechIDs = NULL; m_chassisIDs = NULL; DestroyWorkingEntity(); if(m_mechResourceFile.GetCurrent()) delete m_mechResourceFile.GetCurrent(); m_mechResourceFile.Remove(); m_mode = ChassisTabMode; m_mechLabCount = GetMechCount(); m_chassisCount = GetChassisCount(); //Need to somehow make this a paramter so we can start with the current //mech if there was one in the pilot place. } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void CampaignMechLab::InitializeSubsystemsAvailable() { Check_Object(MWGame::GetInstance()); Check_Object(MWGame::GetInstance()->m_salvageManager); SortedChainIteratorOf iterator(&MWGame::GetInstance()->m_salvageManager->m_salvageList); SalvagePlug *salvage_plug; while((salvage_plug = iterator.ReadAndNext()) != NULL) { Check_Object(salvage_plug); Resource model_resource(salvage_plug->m_salvageID); Verify(model_resource.DoesResourceExist()); Subsystem::GameModel *sub_model = Cast_Pointer( Subsystem::GameModel *, model_resource.GetPointer()); //We are a Generic Sub and should be unlimmited if((sub_model->itemID >= FirstGenericSubsystemID) && (sub_model->itemID <= LastGenericSubsystemID)) { SubsystemResource *sub_resource; sub_resource = AddAvailableSubsystem( salvage_plug->m_dataListID, salvage_plug->m_salvageID, sub_model->itemID ); Check_Object(sub_resource); sub_resource->SetUnlimited(); } else { //We need to check in with the salvage manager to get what is available! for(int i=0; im_count; i++) { AddAvailableSubsystem( salvage_plug->m_dataListID, salvage_plug->m_salvageID, sub_model->itemID ); } } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int CampaignMechLab::GetChassis(void* data[], int count) { Check_Pointer(this); return 1; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int CampaignMechLab::GetChassisCount() { Check_Pointer(this); Check_Object(MWGame::GetInstance()); Check_Object(MWGame::GetInstance()->m_salvageManager); return 0; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int CampaignMechLab::GetMechCount() { Check_Pointer(this); Check_Object(MWGame::GetInstance()); int count = 0; SortedChainIteratorOf iterator(&MWGame::GetInstance()->m_mechTable); MechTablePlug *mech_plug; while((mech_plug = iterator.ReadAndNext()) != NULL) { if(mech_plug->GetStatus() != MechTablePlug::DestroyedStatus) { count ++; } } return count; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int CampaignMechLab::GetMechs(void* data[], int count) { Check_Pointer(this); Check_Object(MWGame::GetInstance()); char **name_array = STRARRAYPARAM(1); int *selected_mech = INTARRAYPARAM(2); *selected_mech = 0; // jcem if(m_mechLabCount > 0) { if(m_mechIDs) { gos_Free(m_mechIDs); m_mechIDs = NULL; } m_mechIDs = (ResourceID *)gos_Malloc(m_mechLabCount * sizeof(ResourceID)); } int i = 0; SortedChainIteratorOf iterator(&MWGame::GetInstance()->m_mechTable); MechTablePlug *mech_plug; while((mech_plug = iterator.ReadAndNext()) != NULL) { if(mech_plug->GetStatus() != MechTablePlug::DestroyedStatus) { FREEANDNULL(name_array[i]); name_array[i] = (char *)gos_Malloc(128); Str_Copy( name_array[i], (const char *)mech_plug->GetMechName(), mech_plug->GetMechName().GetLength() + 1 ); m_mechIDs[i] = mech_plug->GetMechResourceID(); i++; } } return 1; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int CampaignMechLab::SelectMech(void *data[], int count, const char *path) { Check_Pointer(this); const char *mech_name = STRPARM(2); MWGame::GetInstance()->ResetSalvageManager(); m_subsystemsAvailable.DeletePlugs(); InitializeSubsystemsAvailable(); int return_value = MechLab::SelectMech(data, count, ""); Check_Object(GetWorkingMech()); MechTablePlug *mech_plug = MWGame::GetInstance()->m_mechTable.Find(mech_name); MWGame::GetInstance()->SetCurrentMechPlug(mech_plug); m_workingMech->instanceName = mech_plug->GetOriginalName(); return return_value; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int CampaignMechLab::SaveMech() { //This needs to be done totally diferntly than that other one if(GetWorkingMech()) { Check_Object(MWGame::GetInstance()); DynamicMemoryStream stream; m_workingMech->SaveMakeMessage(&stream, MWGame::GetInstance()->GetGameResourceFile()); stream.Rewind(); // Stuff::FileDependencies dependancies; // dependancies.AddDependency(""); MechTablePlug *mech_plug = MWGame::GetInstance()->GetCurrentMechPlug(); Check_Object(mech_plug); Resource mech_resource(mech_plug->GetMechResourceID()); mech_resource.Save(&stream, NULL); } MWGame::GetInstance()->SaveMWGame(MWGame::GetInstance()->GetGameName(), false); MWGame::GetInstance()->ResetSalvageManager(); m_subsystemsAvailable.DeletePlugs(); InitializeSubsystemsAvailable(); //MWGame::GetInstance()->GetGameResourceFile()->Save(); return 1; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int CampaignMechLab::Exit() { // SaveMech(); Check_Object(MWGame::GetInstance()); MWGame::GetInstance()->ResetSalvageManager(); MWGame::GetInstance()->SaveMWGame(MWGame::GetInstance()->GetGameName(), false); return MechLab::Exit(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int CampaignMechLab::CreateNewMech(void *data[], int count, const char *path) { Check_Pointer(this); STOP(("SHOULD NEVER GET HERE!")); return -1; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int CampaignMechLab::RemoveEquipmentFromList(Mech *mech) { Check_Pointer(this); Check_Object(mech); int return_value = 1; ChainIteratorOf sub_iterator(&mech->subsystemsInVehicle); Subsystem *subsystem; while((subsystem = sub_iterator.ReadAndNext()) != NULL) { Check_Object(subsystem); const Subsystem::GameModel *sub_model = subsystem->GetGameModel(); Check_Object(sub_model); if(sub_model->itemID > -1) { if(DoesHaveAvailableSubsystem(sub_model->itemID)) { //We have it in stock...now subtract it from stock RemoveAvailableSubsystem(sub_model->itemID); } else { subsystem->DisconnectSubsystem(); subsystem->Destroy(); return_value = -1; } } } return return_value; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void CampaignMechLab::AddEquipmentToList(Mech *mech) { Check_Pointer(this); Check_Object(mech); //Here we need to run through the mech equipment and re add it to our //list of available stuff. ChainIteratorOf sub_iterator(&mech->subsystemsInVehicle); Subsystem *subsystem; while((subsystem = sub_iterator.ReadAndNext()) != NULL) { Check_Object(subsystem); const Subsystem::GameModel *sub_model = subsystem->GetGameModel(); Check_Object(sub_model); if(sub_model->itemID > -1) { AddAvailableSubsystem(subsystem->GetDataListResourceID(), subsystem->GetGameModelResourceID(), sub_model->itemID ); } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void CampaignMechLab::SetUpWorkingMech(Entity *entity) { Check_Pointer(this); Check_Object(entity); MechLab::SetUpWorkingMech(entity); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void CampaignMechLab::AddSubsystemToMech(int *sub_type, int *zone, int *error) { MechLab::AddSubsystemToMech(sub_type, zone, error); //Make sure that we added the subsystem! if(GetWorkingMech() && (*error == 1)) { Check_Object(m_workingMech); MWInternalDamageObject *internal_zone; internal_zone = m_workingMech->internalDamageObjects.Find(*zone); Check_Object(internal_zone); Subsystem *subsystem = internal_zone->GetSubsystem(*sub_type); if((subsystem) && (*sub_type != Sub_HeatSink)) { MWGame::GetInstance()->m_salvageManager->RemoveSalvage(subsystem); } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int CampaignMechLab::AutoAddSubsystem(void *data[], int count) { int *sub_type = INTARRAYPARAM(1); int *error = INTARRAYPARAM(2); *error = 1; if(GetWorkingMech()) { Check_Object(m_workingMech); SubsystemResource *sub_resource = m_subsystemsAvailable.Find(*sub_type); if(sub_resource) { Check_Object(sub_resource); RegisteredClass::ClassID class_id = Entity::GetClassIDFromDataListID(sub_resource->GetDataListID()); Subsystem::ClassData *class_data = Cast_Pointer(Subsystem::ClassData*, RegisteredClass::FindClassData(class_id)); Check_Object(class_data); DynamicMemoryStream stream; (*class_data->streamCreate)(sub_resource->GetDataListID(), &stream); ReplicatorID base_id = Connection::Local->GetNextReplicatorID(); Subsystem__CreateMessage *create_message = Cast_Pointer(Subsystem__CreateMessage *, stream.GetPointer()); //Ok now we have the subsystem stream...before we create we need to know where //we want to put the thing. Resource sub_model_resource(sub_resource->GetGameModelID()); Verify(sub_model_resource.DoesResourceExist()); Subsystem::GameModel *sub_model = Cast_Pointer( Subsystem::GameModel *, sub_model_resource.GetPointer()); int slots_needed = sub_model->totalSlotsTaken; int slot_type = sub_model->slotType; //First check for a slot with the correct type, starting with the arms int location = FindInternalLocation(slot_type, slots_needed); //Next check for an omni slot starting with the arms if(location == -1) location = FindInternalLocation(MWInternalDamageObject::OmniSlotType, slots_needed); if(location == -1) { *error = 0; return 0; } //if no zone then exit! create_message->locationID = (char)location; Subsystem *subsystem = Cast_Object(Subsystem *, Entity::CreateEntity(&stream, &base_id)); Check_Object(subsystem); if(subsystem->IsDerivedFrom(Weapon::DefaultData)) { Weapon *weapon = Cast_Object(Weapon *, subsystem); MWInternalDamageObject *zone_object = m_workingMech->internalDamageObjects.Find(location); Check_Object(zone_object); Site *site = zone_object->GetNextWeaponSite(); if(!site) { *error = 0; subsystem->Destroy(); return 0; } weapon->siteName = site->GetName(); } m_workingMech->AddChild(subsystem); m_workingMech->SyncMatrices(true); if(subsystem->ConnectSubsystem()) { m_workingMech->AddSubsystem(subsystem); RemoveAvailableSubsystem(*sub_type); MWGame::GetInstance()->m_salvageManager->RemoveSalvage(subsystem); } else { subsystem->Destroy(); *error = 0; return 0; } } else { *error = 0; return 0; } } MWApplication *app = MWApplication::GetInstance(); app->memoryDiffKiller.Init(); return 1; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void CampaignMechLab::RemoveWeaponFromMech(int *sub_id, int *zone) { if(GetWorkingMech()) { Check_Object(m_workingMech); MWInternalDamageObject *internal_zone; internal_zone = m_workingMech->internalDamageObjects.Find(*zone); Check_Object(internal_zone); // Subsystem *subsystem = internal_zone->subsystemChain.GetNth(*sub_id); Subsystem *subsystem; int weapon_count = 0; ChainIteratorOf iterator(&internal_zone->subsystemChain); while((subsystem = iterator.ReadAndNext()) != NULL) { Check_Object(subsystem); if(subsystem->IsDerivedFrom(Weapon::DefaultData)) { if(*sub_id == weapon_count) { //we need to get the subsystem name from the table using the model resource name Check_Object(MWApplication::GetInstance()); MString sub_name = subsystem->GetModelName(); MWTableEntry *sub_entry = MWApplication::GetInstance()->m_weaponsTable->FindEntryFromDataString(sub_name); Check_Object(sub_entry); MWGame::GetInstance()->m_salvageManager->AddSalvage(subsystem, sub_entry->GetEntryName()); } else { weapon_count ++; } } } } MechLab::RemoveWeaponFromMech(sub_id, zone); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void CampaignMechLab::RemoveSubsystemFromMech(int *sub_type, int *zone) { if(GetWorkingMech()) { Check_Object(m_workingMech); MWInternalDamageObject *internal_zone; internal_zone = m_workingMech->internalDamageObjects.Find(*zone); Check_Object(internal_zone); Subsystem *subsystem = internal_zone->GetSubsystem(*sub_type); //Subsystem *subsystem = internal_zone->subsystemChain.GetNth(*sub_type); if((subsystem)&& (*sub_type != Sub_HeatSink)) { //we need to get the subsystem name from the table using the model resource name Check_Object(MWApplication::GetInstance()); MString sub_name = subsystem->GetModelName(); MWTableEntry *sub_entry = MWApplication::GetInstance()->m_subsystemTable->FindEntryFromDataString(sub_name); Check_Object(sub_entry); MWGame::GetInstance()->m_salvageManager->AddSalvage(subsystem, sub_entry->GetEntryName()); } } MechLab::RemoveSubsystemFromMech(sub_type, zone); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int CampaignMechLab::RemoveAllSubsystems() { if(GetWorkingMech()) { Check_Object(m_workingMech); ChainIteratorOf iterator(&m_workingMech->subsystemsInVehicle); Subsystem *subsystem; while((subsystem = iterator.ReadAndNext()) != NULL) { Check_Object(subsystem); if(subsystem->IsDerivedFrom(Weapon::DefaultData)) { //Disconnect, add to our reserves, and delete Check_Object(MWApplication::GetInstance()); MString sub_name = subsystem->GetModelName(); MWTableEntry *sub_entry = MWApplication::GetInstance()->m_weaponsTable->FindEntryFromDataString(sub_name); if(!sub_entry) { //Check the subsystem one sub_entry = MWApplication::GetInstance()->m_subsystemTable->FindEntryFromDataString(sub_name); } Check_Object(sub_entry); MWGame::GetInstance()->m_salvageManager->AddSalvage(subsystem, sub_entry->GetEntryName()); subsystem->DisconnectSubsystem(); m_workingMech->RemoveSubsystem(subsystem); AddAvailableSubsystem(subsystem); subsystem->Destroy(); } } //SaveMech(); return 1; } return 0; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int CampaignMechLab::Rename(void *data[], int count, const char *) { const char *chassis_name = STRPARM(1); const char *mech_name = STRPARM(2); MString new_name = MString(chassis_name)+" "+mech_name; //new_name.ToLower(); MechTablePlug *mech_plug = MWGame::GetInstance()->GetCurrentMechPlug(); Check_Object(mech_plug); MString old_name = mech_plug->GetMechName(); //old_name.ToLower(); if (new_name == old_name) return 1; if (MWGame::GetInstance()->m_mechTable.Find(new_name)) return E_MechAlreadyExists; MWGame::GetInstance()->m_mechTable.Remove(mech_plug); mech_plug->SetMechName(MString(chassis_name)+" "+mech_name); MWGame::GetInstance()->m_mechTable.AddValue(mech_plug, new_name); return 1; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // int CampaignMechLab::Restore() { Check_Object(MWGame::GetInstance()); MWGame::GetInstance()->ResetSalvageManager(); m_subsystemsAvailable.DeletePlugs(); InitializeSubsystemsAvailable(); MechTablePlug *mech_plug = MWGame::GetInstance()->GetCurrentMechPlug(); DestroyWorkingEntity(); Resource mech_resource(mech_plug->GetMechResourceID()); Verify(mech_resource.DoesResourceExist()); ReplicatorID base_id = Connection::Local->GetNextReplicatorID(); Entity *entity; entity = Entity::CreateEntity(&mech_resource, &base_id); Check_Object(entity); SetUpWorkingMech(entity); m_workingMech->instanceName = mech_plug->GetOriginalName(); return 1; }