diff --git a/CMakeLists.txt b/CMakeLists.txt index a69436f..f6a73cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,6 +73,7 @@ target_link_options(wxMASSManager PRIVATE -static -static-libgcc -static-libstdc target_link_libraries(wxMASSManager PRIVATE Corrade::Containers Corrade::Utility + wx_mswu_propgrid-3.0 wx_mswu_adv-3.0 wx_mswu_core-3.0 wx_baseu-3.0 diff --git a/GUI/EvtMainFrame.cpp b/GUI/EvtMainFrame.cpp index 732d76c..9855124 100644 --- a/GUI/EvtMainFrame.cpp +++ b/GUI/EvtMainFrame.cpp @@ -241,6 +241,59 @@ void EvtMainFrame::openStoryProgressMenuEvent(wxCommandEvent&) { PopupMenu(_storyProgressSelectionMenu.get()); } +void EvtMainFrame::inventoryChangeEvent(wxPropertyGridEvent& event) { + const static std::string error_prefix = "Inventory change failed:\n\n"; + + std::int32_t value = event.GetPropertyValue().GetInteger(); + Profile* profile = _profileManager.currentProfile(); + + if(value > 1000000 || value < 0) { + event.SetValidationFailureMessage(error_prefix + "The value must not be higher than 1 million or lower than 0"); + event.Veto(); + return; + } + + if(_unsafeMode == true || _mbManager.gameState() == GameState::NotRunning) { + wxPGProperty* prop = event.GetProperty(); + bool success = false; + + if(prop == _verseSteel) { success = profile->setVerseSteel(value); } + else if(prop == _undinium) { success = profile->setUndinium(value); } + else if(prop == _necriumAlloy) { success = profile->setNecriumAlloy(value); } + else if(prop == _lunarite) { success = profile->setLunarite(value); } + else if(prop == _asterite) { success = profile->setAsterite(value); } + else if(prop == _ednil) { success = profile->setEdnil(value); } + else if(prop == _nuflalt) { success = profile->setNuflalt(value); } + else if(prop == _aurelene) { success = profile->setAurelene(value); } + else if(prop == _soldus) { success = profile->setSoldus(value); } + else if(prop == _synthesizedN) { success = profile->setSynthesizedN(value); } + else if(prop == _alcarbonite) { success = profile->setAlcarbonite(value); } + else if(prop == _keriphene) { success = profile->setKeriphene(value); } + else if(prop == _nitinolCM) { success = profile->setNitinolCM(value); } + else if(prop == _quarkium) { success = profile->setQuarkium(value); } + else if(prop == _alterene) { success = profile->setAlterene(value); } + + else if(prop == _mixedComposition) { success = profile->setMixedComposition(value); } + else if(prop == _voidResidue) { success = profile->setVoidResidue(value); } + else if(prop == _muscularConstruction) { success = profile->setMuscularConstruction(value); } + else if(prop == _mineralExoskeletology) { success = profile->setMineralExoskeletology(value); } + else if(prop == _carbonizedSkin) { success = profile->setCarbonizedSkin(value); } + + if(!success) { + event.SetValidationFailureMessage(error_prefix + profile->lastError()); + event.Veto(); + } + } + else if(_mbManager.gameState() == GameState::Unknown) { + event.SetValidationFailureMessage(error_prefix + "For security reasons, changing the inventory is disabled if the game's status is unknown."); + event.Veto(); + } + else if(_mbManager.gameState() == GameState::Running) { + event.SetValidationFailureMessage(error_prefix + "For security reasons, changing the inventory is disabled if the game is running."); + event.Veto(); + } +} + void EvtMainFrame::importMassEvent(wxCommandEvent&) { const static std::string error_prefix = "Importing failed:\n\n"; @@ -592,6 +645,28 @@ void EvtMainFrame::updateProfileStats() { else { _lastMissionId->SetLabel(wxString::Format("0x%X", current_profile->lastMissionId())); } + + _verseSteel->SetValueFromInt(current_profile->getVerseSteel()); + _undinium->SetValueFromInt(current_profile->getUndinium()); + _necriumAlloy->SetValueFromInt(current_profile->getNecriumAlloy()); + _lunarite->SetValueFromInt(current_profile->getLunarite()); + _asterite->SetValueFromInt(current_profile->getAsterite()); + _ednil->SetValueFromInt(current_profile->getEdnil()); + _nuflalt->SetValueFromInt(current_profile->getNuflalt()); + _aurelene->SetValueFromInt(current_profile->getAurelene()); + _soldus->SetValueFromInt(current_profile->getSoldus()); + _synthesizedN->SetValueFromInt(current_profile->getSynthesizedN()); + _alcarbonite->SetValueFromInt(current_profile->getAlcarbonite()); + _keriphene->SetValueFromInt(current_profile->getKeriphene()); + _nitinolCM->SetValueFromInt(current_profile->getNitinolCM()); + _quarkium->SetValueFromInt(current_profile->getQuarkium()); + _alterene->SetValueFromInt(current_profile->getAlterene()); + + _mixedComposition->SetValueFromInt(current_profile->getMixedComposition()); + _voidResidue->SetValueFromInt(current_profile->getVoidResidue()); + _muscularConstruction->SetValueFromInt(current_profile->getMuscularConstruction()); + _mineralExoskeletology->SetValueFromInt(current_profile->getMineralExoskeletology()); + _carbonizedSkin->SetValueFromInt(current_profile->getCarbonizedSkin()); } void EvtMainFrame::initStoryProgressMenu() { @@ -714,6 +789,14 @@ void EvtMainFrame::updateCommandsState() { _companyRenameButton->Enable(_unsafeMode == true || game_state == GameState::NotRunning); _storyProgressChangeButton->Enable(_unsafeMode == true || game_state == GameState::NotRunning); + wxPropertyGridConstIterator it = _researchInventoryPropGrid->GetIterator(wxPG_ITERATE_NORMAL); + while(!it.AtEnd()) { + if(it.GetProperty()->IsCategory() == false) { + it.GetProperty()->Enable(_unsafeMode == true || game_state == GameState::NotRunning); + } + it.Next(); + } + _importButton->Enable(selection != -1 && staged_selection != -1 && (_unsafeMode == true || game_state == GameState::NotRunning)); _exportButton->Enable(selection != -1); _moveButton->Enable(selection != -1 && (_unsafeMode == true || game_state == GameState::NotRunning) && mass_state == MassState::Valid); diff --git a/GUI/EvtMainFrame.h b/GUI/EvtMainFrame.h index 0cd96ef..4b32f16 100644 --- a/GUI/EvtMainFrame.h +++ b/GUI/EvtMainFrame.h @@ -47,6 +47,7 @@ class EvtMainFrame: public MainFrame { void companyRenameEvent(wxMouseEvent&); void storyProgressSelectionEvent(wxCommandEvent& event); void openStoryProgressMenuEvent(wxCommandEvent&); + void inventoryChangeEvent(wxPropertyGridEvent& event); // M.A.S.S.-related events void importMassEvent(wxCommandEvent&); diff --git a/GUI/MainFrame.cpp b/GUI/MainFrame.cpp index 25ead3c..7958b73 100644 --- a/GUI/MainFrame.cpp +++ b/GUI/MainFrame.cpp @@ -121,7 +121,47 @@ MainFrame::MainFrame( wxWindow* parent, wxWindowID id, const wxString& title, co sbSizerGeneralInfo->Add( bSizerProfileCommands, 0, wxEXPAND, 5 ); - bSizerProfilePanel->Add( sbSizerGeneralInfo, 1, wxEXPAND|wxALL, 5 ); + bSizerProfilePanel->Add( sbSizerGeneralInfo, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSizerBottomHalf; + bSizerBottomHalf = new wxBoxSizer( wxHORIZONTAL ); + + wxStaticBoxSizer* sbSizerResearchInv; + sbSizerResearchInv = new wxStaticBoxSizer( new wxStaticBox( _profilePanel, wxID_ANY, wxT("Research inventory") ), wxVERTICAL ); + + _researchInventoryPropGrid = new wxPropertyGrid(sbSizerResearchInv->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxPG_HIDE_MARGIN|wxPG_SPLITTER_AUTO_CENTER|wxPG_STATIC_LAYOUT|wxPG_STATIC_SPLITTER); + _materialsCategory = _researchInventoryPropGrid->Append( new wxPropertyCategory( wxT("Materials"), wxT("Materials") ) ); + _verseSteel = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Verse Steel"), wxT("Verse Steel") ) ); + _undinium = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Undinium"), wxT("Undinium") ) ); + _necriumAlloy = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Necrium Alloy"), wxT("Necrium Alloy") ) ); + _lunarite = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Lunarite"), wxT("Lunarite") ) ); + _asterite = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Asterite"), wxT("Asterite") ) ); + _ednil = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Ednil"), wxT("Ednil") ) ); + _nuflalt = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Nuflalt"), wxT("Nuflalt") ) ); + _aurelene = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Aurelene"), wxT("Aurelene") ) ); + _soldus = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Soldus"), wxT("Soldus") ) ); + _synthesizedN = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Synthesized N."), wxT("Synthesized N.") ) ); + _alcarbonite = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Alcarbonite"), wxT("Alcarbonite") ) ); + _keriphene = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Keriphene"), wxT("Keriphene") ) ); + _nitinolCM = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Nitinol-CM"), wxT("Nitinol-CM") ) ); + _quarkium = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Quarkium"), wxT("Quarkium") ) ); + _alterene = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Alterene"), wxT("Alterene") ) ); + _quarkDataCategory = _researchInventoryPropGrid->Append( new wxPropertyCategory( wxT("Quark Data"), wxT("Quark Data") ) ); + _mixedComposition = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Mixed Composition"), wxT("Mixed Composition") ) ); + _voidResidue = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Void Residue"), wxT("Void Residue") ) ); + _muscularConstruction = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Muscular Construction"), wxT("Muscular Construction") ) ); + _mineralExoskeletology = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Mineral Exoskeletology"), wxT("Mineral Exoskeletology") ) ); + _carbonizedSkin = _researchInventoryPropGrid->Append( new wxIntProperty( wxT("Carbonized Skin"), wxT("Carbonized Skin") ) ); + sbSizerResearchInv->Add( _researchInventoryPropGrid, 1, wxALL|wxEXPAND, 5 ); + + + bSizerBottomHalf->Add( sbSizerResearchInv, 1, wxEXPAND|wxALL, 5 ); + + + bSizerBottomHalf->Add( 0, 0, 1, wxEXPAND, 5 ); + + + bSizerProfilePanel->Add( bSizerBottomHalf, 1, wxEXPAND, 5 ); _profilePanel->SetSizer( bSizerProfilePanel ); @@ -259,6 +299,7 @@ MainFrame::MainFrame( wxWindow* parent, wxWindowID id, const wxString& title, co _unsafeCheckbox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MainFrame::unsafeCheckboxEvent ), NULL, this ); _companyRenameButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::companyRenameEvent ), NULL, this ); _storyProgressChangeButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::openStoryProgressMenuEvent ), NULL, this ); + _researchInventoryPropGrid->Connect( wxEVT_PG_CHANGING, wxPropertyGridEventHandler( MainFrame::inventoryChangeEvent ), NULL, this ); _moveButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::moveMassEvent ), NULL, this ); _deleteButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::deleteMassEvent ), NULL, this ); _renameButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::renameMassEvent ), NULL, this ); @@ -280,6 +321,7 @@ MainFrame::~MainFrame() _unsafeCheckbox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( MainFrame::unsafeCheckboxEvent ), NULL, this ); _companyRenameButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::companyRenameEvent ), NULL, this ); _storyProgressChangeButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::openStoryProgressMenuEvent ), NULL, this ); + _researchInventoryPropGrid->Disconnect( wxEVT_PG_CHANGING, wxPropertyGridEventHandler( MainFrame::inventoryChangeEvent ), NULL, this ); _moveButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::moveMassEvent ), NULL, this ); _deleteButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::deleteMassEvent ), NULL, this ); _renameButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::renameMassEvent ), NULL, this ); diff --git a/GUI/MainFrame.fbp b/GUI/MainFrame.fbp index 3a762d7..4a5b187 100644 --- a/GUI/MainFrame.fbp +++ b/GUI/MainFrame.fbp @@ -123,7 +123,7 @@ 5 wxEXPAND 0 - + bSizerProfile wxHORIZONTAL @@ -327,11 +327,11 @@ backupSelectedProfileEvent - + 5 wxALL 0 - + 1 1 1 @@ -400,21 +400,21 @@ openScreenshotDirEvent - + 5 wxEXPAND 1 - + 0 protected 0 - + 5 wxALL|wxALIGN_CENTER_VERTICAL 0 - + 1 1 1 @@ -596,7 +596,7 @@ none 5 - wxEXPAND|wxALL + wxEXPAND|wxTOP|wxRIGHT|wxLEFT 1 wxID_ANY @@ -610,7 +610,7 @@ 5 wxEXPAND 1 - + 2 wxBOTH 1 @@ -622,11 +622,11 @@ none 0 0 - + 5 wxALL 0 - + 1 1 1 @@ -683,11 +683,11 @@ -1 - + 5 wxALL|wxEXPAND 0 - + 1 1 1 @@ -744,11 +744,11 @@ -1 - + 5 wxALL 0 - + 1 1 1 @@ -805,11 +805,11 @@ -1 - + 5 wxALL|wxEXPAND 0 - + 1 1 1 @@ -866,11 +866,11 @@ -1 - + 5 wxALL 0 - + 1 1 1 @@ -927,11 +927,11 @@ -1 - + 5 wxALL|wxEXPAND 0 - + 1 1 1 @@ -988,11 +988,11 @@ -1 - + 5 wxALL 0 - + 1 1 1 @@ -1049,11 +1049,11 @@ -1 - + 5 wxALL|wxEXPAND 0 - + 1 1 1 @@ -1271,6 +1271,257 @@ + + 5 + wxEXPAND + 1 + + + bSizerBottomHalf + wxHORIZONTAL + none + + 5 + wxEXPAND|wxALL + 1 + + wxID_ANY + Research inventory + + sbSizerResearchInv + wxVERTICAL + 1 + none + + 5 + wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + + 1 + + 0 + 0 + wxID_ANY + 1 + + 0 + + + 0 + + 1 + _researchInventoryPropGrid + 1 + + + protected + 1 + + Resizable + 1 + + wxPG_HIDE_MARGIN|wxPG_SPLITTER_AUTO_CENTER|wxPG_STATIC_LAYOUT|wxPG_STATIC_SPLITTER + ; ; forward_declare + 0 + + + + + inventoryChangeEvent + + + Materials + _materialsCategory + protected + Category + + + + Verse Steel + _verseSteel + protected + Int + + + + Undinium + _undinium + protected + Int + + + + Necrium Alloy + _necriumAlloy + protected + Int + + + + Lunarite + _lunarite + protected + Int + + + + Asterite + _asterite + protected + Int + + + + Ednil + _ednil + protected + Int + + + + Nuflalt + _nuflalt + protected + Int + + + + Aurelene + _aurelene + protected + Int + + + + Soldus + _soldus + protected + Int + + + + Synthesized N. + _synthesizedN + protected + Int + + + + Alcarbonite + _alcarbonite + protected + Int + + + + Keriphene + _keriphene + protected + Int + + + + Nitinol-CM + _nitinolCM + protected + Int + + + + Quarkium + _quarkium + protected + Int + + + + Alterene + _alterene + protected + Int + + + + Quark Data + _quarkDataCategory + protected + Category + + + + Mixed Composition + _mixedComposition + protected + Int + + + + Void Residue + _voidResidue + protected + Int + + + + Muscular Construction + _muscularConstruction + protected + Int + + + + Mineral Exoskeletology + _mineralExoskeletology + protected + Int + + + + Carbonized Skin + _carbonizedSkin + protected + Int + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + @@ -1278,7 +1529,7 @@ M.A.S.S.es 0 - + 1 1 1 @@ -1329,16 +1580,16 @@ wxTAB_TRAVERSAL - + bSizerMassPanel wxHORIZONTAL none - + 5 wxEXPAND|wxALL 1 - + wxID_ANY Installed M.A.S.S.es @@ -1641,11 +1892,11 @@ - + 5 wxEXPAND|wxRIGHT|wxLEFT 0 - + bSizerSecondRow wxHORIZONTAL diff --git a/GUI/MainFrame.h b/GUI/MainFrame.h index ce52e01..f3791f8 100644 --- a/GUI/MainFrame.h +++ b/GUI/MainFrame.h @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include #include @@ -60,6 +62,29 @@ class MainFrame : public wxFrame wxStaticText* _lastMissionId; wxButton* _companyRenameButton; wxButton* _storyProgressChangeButton; + wxPropertyGrid* _researchInventoryPropGrid; + wxPGProperty* _materialsCategory; + wxPGProperty* _verseSteel; + wxPGProperty* _undinium; + wxPGProperty* _necriumAlloy; + wxPGProperty* _lunarite; + wxPGProperty* _asterite; + wxPGProperty* _ednil; + wxPGProperty* _nuflalt; + wxPGProperty* _aurelene; + wxPGProperty* _soldus; + wxPGProperty* _synthesizedN; + wxPGProperty* _alcarbonite; + wxPGProperty* _keriphene; + wxPGProperty* _nitinolCM; + wxPGProperty* _quarkium; + wxPGProperty* _alterene; + wxPGProperty* _quarkDataCategory; + wxPGProperty* _mixedComposition; + wxPGProperty* _voidResidue; + wxPGProperty* _muscularConstruction; + wxPGProperty* _mineralExoskeletology; + wxPGProperty* _carbonizedSkin; wxPanel* _massPanel; wxListView* _installedListView; wxButton* _moveButton; @@ -85,6 +110,7 @@ class MainFrame : public wxFrame virtual void unsafeCheckboxEvent( wxCommandEvent& event ) { event.Skip(); } virtual void companyRenameEvent( wxCommandEvent& event ) { event.Skip(); } virtual void openStoryProgressMenuEvent( wxCommandEvent& event ) { event.Skip(); } + virtual void inventoryChangeEvent( wxPropertyGridEvent& event ) { event.Skip(); } virtual void moveMassEvent( wxCommandEvent& event ) { event.Skip(); } virtual void deleteMassEvent( wxCommandEvent& event ) { event.Skip(); } virtual void renameMassEvent( wxCommandEvent& event ) { event.Skip(); } diff --git a/Profile/Locators.h b/Profile/Locators.h index 06579c4..01aa486 100644 --- a/Profile/Locators.h +++ b/Profile/Locators.h @@ -21,3 +21,65 @@ constexpr char active_slot_locator[] = "ActiveFrameSlot\0\x0c\0\0\0IntProperty"; constexpr char credits_locator[] = "Credit\0\x0c\0\0\0IntProperty"; constexpr char story_progress_locator[] = "StoryProgress\0\x0c\0\0\0IntProperty"; constexpr char last_mission_id_locator[] = "LastMissionID\0\x0c\0\0\0IntProperty"; + +constexpr char verse_steel_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\x00\x35\x0c\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; +constexpr char undinium_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\x01\x35\x0c\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; +constexpr char necrium_alloy_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\x02\x35\x0c\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; +constexpr char lunarite_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\x03\x35\x0c\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; +constexpr char asterite_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\x04\x35\x0c\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; +constexpr char ednil_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\x0a\x35\x0c\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; +constexpr char nuflalt_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\x0b\x35\x0c\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; +constexpr char aurelene_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\x0c\x35\x0c\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; +constexpr char soldus_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\x0d\x35\x0c\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; +constexpr char synthesized_n_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\x0e\x35\x0c\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; +constexpr char alcarbonite_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\x14\x35\x0c\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; +constexpr char keriphene_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\x15\x35\x0c\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; +constexpr char nitinol_cm_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\x16\x35\x0c\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; +constexpr char quarkium_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\x17\x35\x0c\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; +constexpr char alterene_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\x18\x35\x0c\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; + +constexpr char mixed_composition_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\xa0\xbb\x0d\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; +constexpr char void_residue_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\xa1\xbb\x0d\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; +constexpr char muscular_construction_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\xa2\xbb\x0d\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; +constexpr char mineral_exoskeletology_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\xa3\xbb\x0d\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; +constexpr char carbonized_skin_locator[] = + "ID_4_AAE08F17428E229EC7A2209F51081A21\0\x0c\0\0\0IntProperty\0\x04\0\0\0\0\0\0\0\0\xa4\xbb\x0d\0,\0\0\0" + "Quantity_3_560F09B5485C365D3041888910019CE3\0\x0c\0\0\0IntProperty"; diff --git a/Profile/Profile.cpp b/Profile/Profile.cpp index 0e78630..4958cfb 100644 --- a/Profile/Profile.cpp +++ b/Profile/Profile.cpp @@ -179,7 +179,7 @@ auto Profile::getCredits() -> std::int32_t { if(iter != mmap.end()) { _credits = *reinterpret_cast(iter + 0x20); } - else{ + else { _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; _credits = -1; } @@ -199,7 +199,7 @@ auto Profile::getStoryProgress() -> std::int32_t { if(iter != mmap.end()) { _storyProgress = *reinterpret_cast(iter + 0x27); } - else{ + else { _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; _storyProgress = -1; } @@ -214,9 +214,10 @@ auto Profile::setStoryProgress(std::int32_t progress) -> bool { if(iter != mmap.end()) { *reinterpret_cast(iter + 0x27) = progress; + _storyProgress = progress; return true; } - else{ + else { _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; return false; } @@ -234,7 +235,7 @@ auto Profile::getLastMissionId() -> std::int32_t { if(iter != mmap.end()) { _lastMissionId = *reinterpret_cast(iter + 0x27); } - else{ + else { _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; _lastMissionId = -1; } @@ -242,6 +243,726 @@ auto Profile::getLastMissionId() -> std::int32_t { return _lastMissionId; } +auto Profile::verseSteel() const -> std::int32_t { + return _verseSteel; +} + +auto Profile::getVerseSteel() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &verse_steel_locator[0], &verse_steel_locator[129]); + + if(iter != mmap.end()) { + _verseSteel = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _verseSteel = -1; + } + + return _verseSteel; +} + +auto Profile::setVerseSteel(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &verse_steel_locator[0], &verse_steel_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _verseSteel = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::undinium() const -> std::int32_t { + return _undinium; +} + +auto Profile::getUndinium() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &undinium_locator[0], &undinium_locator[129]); + + if(iter != mmap.end()) { + _undinium = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _undinium = -1; + } + + return _undinium; +} + +auto Profile::setUndinium(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &undinium_locator[0], &undinium_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _undinium = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::necriumAlloy() const -> std::int32_t { + return _necriumAlloy; +} + +auto Profile::getNecriumAlloy() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &necrium_alloy_locator[0], &necrium_alloy_locator[129]); + + if(iter != mmap.end()) { + _necriumAlloy = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _necriumAlloy = -1; + } + + return _necriumAlloy; +} + +auto Profile::setNecriumAlloy(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &necrium_alloy_locator[0], &necrium_alloy_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _necriumAlloy = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::lunarite() const -> std::int32_t { + return _lunarite; +} + +auto Profile::getLunarite() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &lunarite_locator[0], &lunarite_locator[129]); + + if(iter != mmap.end()) { + _lunarite = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _lunarite = -1; + } + + return _lunarite; +} + +auto Profile::setLunarite(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &lunarite_locator[0], &lunarite_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _lunarite = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::asterite() const -> std::int32_t { + return _asterite; +} + +auto Profile::getAsterite() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &asterite_locator[0], &asterite_locator[129]); + + if(iter != mmap.end()) { + _asterite = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _asterite = -1; + } + + return _asterite; +} + +auto Profile::setAsterite(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &asterite_locator[0], &asterite_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _asterite = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::ednil() const -> std::int32_t { + return _ednil; +} + +auto Profile::getEdnil() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &ednil_locator[0], &ednil_locator[129]); + + if(iter != mmap.end()) { + _ednil = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _ednil = -1; + } + + return _ednil; +} + +auto Profile::setEdnil(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &ednil_locator[0], &ednil_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _ednil = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::nuflalt() const -> std::int32_t { + return _nuflalt; +} + +auto Profile::getNuflalt() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &nuflalt_locator[0], &nuflalt_locator[129]); + + if(iter != mmap.end()) { + _nuflalt = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _nuflalt = -1; + } + + return _nuflalt; +} + +auto Profile::setNuflalt(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &nuflalt_locator[0], &nuflalt_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _nuflalt = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::aurelene() const -> std::int32_t { + return _aurelene; +} + +auto Profile::getAurelene() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &aurelene_locator[0], &aurelene_locator[129]); + + if(iter != mmap.end()) { + _aurelene = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _aurelene = -1; + } + + return _aurelene; +} + +auto Profile::setAurelene(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &aurelene_locator[0], &aurelene_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _aurelene = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::soldus() const -> std::int32_t { + return _soldus; +} + +auto Profile::getSoldus() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &soldus_locator[0], &soldus_locator[129]); + + if(iter != mmap.end()) { + _soldus = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _soldus = -1; + } + + return _soldus; +} + +auto Profile::setSoldus(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &soldus_locator[0], &soldus_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _soldus = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::synthesizedN() const -> std::int32_t { + return _synthesizedN; +} + +auto Profile::getSynthesizedN() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &synthesized_n_locator[0], &synthesized_n_locator[129]); + + if(iter != mmap.end()) { + _synthesizedN = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _synthesizedN = -1; + } + + return _synthesizedN; +} + +auto Profile::setSynthesizedN(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &synthesized_n_locator[0], &synthesized_n_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _synthesizedN = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::alcarbonite() const -> std::int32_t { + return _alcarbonite; +} + +auto Profile::getAlcarbonite() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &alcarbonite_locator[0], &alcarbonite_locator[129]); + + if(iter != mmap.end()) { + _alcarbonite = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _alcarbonite = -1; + } + + return _alcarbonite; +} + +auto Profile::setAlcarbonite(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &alcarbonite_locator[0], &alcarbonite_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _alcarbonite = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::keriphene() const -> std::int32_t { + return _keriphene; +} + +auto Profile::getKeriphene() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &keriphene_locator[0], &keriphene_locator[129]); + + if(iter != mmap.end()) { + _keriphene = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _keriphene= -1; + } + + return _keriphene; +} + +auto Profile::setKeriphene(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &keriphene_locator[0], &keriphene_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _keriphene = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::nitinolCM() const -> std::int32_t { + return _nitinolCM; +} + +auto Profile::getNitinolCM() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &nitinol_cm_locator[0], &nitinol_cm_locator[129]); + + if(iter != mmap.end()) { + _nitinolCM = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _nitinolCM = -1; + } + + return _nitinolCM; +} + +auto Profile::setNitinolCM(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &nitinol_cm_locator[0], &nitinol_cm_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _nitinolCM = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::quarkium() const -> std::int32_t { + return _quarkium; +} + +auto Profile::getQuarkium() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &quarkium_locator[0], &quarkium_locator[129]); + + if(iter != mmap.end()) { + _quarkium = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _quarkium = -1; + } + + return _quarkium; +} + +auto Profile::setQuarkium(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &quarkium_locator[0], &quarkium_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _quarkium = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::alterene() const -> std::int32_t { + return _alterene; +} + +auto Profile::getAlterene() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &alterene_locator[0], &alterene_locator[129]); + + if(iter != mmap.end()) { + _alterene = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _alterene = -1; + } + + return _alterene; +} + +auto Profile::setAlterene(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &alterene_locator[0], &alterene_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _alterene = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::mixedComposition() const -> std::int32_t { + return _mixedComposition; +} + +auto Profile::getMixedComposition() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &mixed_composition_locator[0], &mixed_composition_locator[129]); + + if(iter != mmap.end()) { + _mixedComposition = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _mixedComposition = -1; + } + + return _mixedComposition; +} + +auto Profile::setMixedComposition(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &mixed_composition_locator[0], &mixed_composition_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _mixedComposition = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::voidResidue() const -> std::int32_t { + return _voidResidue; +} + +auto Profile::getVoidResidue() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &void_residue_locator[0], &void_residue_locator[129]); + + if(iter != mmap.end()) { + _voidResidue = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _voidResidue = -1; + } + + return _voidResidue; +} + +auto Profile::setVoidResidue(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &void_residue_locator[0], &void_residue_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _voidResidue = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::muscularConstruction() const -> std::int32_t { + return _muscularConstruction; +} + +auto Profile::getMuscularConstruction() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &muscular_construction_locator[0], &muscular_construction_locator[129]); + + if(iter != mmap.end()) { + _muscularConstruction = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _muscularConstruction = -1; + } + + return _muscularConstruction; +} + +auto Profile::setMuscularConstruction(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &muscular_construction_locator[0], &muscular_construction_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _muscularConstruction = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::mineralExoskeletology() const -> std::int32_t { + return _mineralExoskeletology; +} + +auto Profile::getMineralExoskeletology() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &mineral_exoskeletology_locator[0], &mineral_exoskeletology_locator[129]); + + if(iter != mmap.end()) { + _mineralExoskeletology = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _mineralExoskeletology = -1; + } + + return _mineralExoskeletology; +} + +auto Profile::setMineralExoskeletology(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &mineral_exoskeletology_locator[0], &mineral_exoskeletology_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _mineralExoskeletology = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + +auto Profile::carbonizedSkin() const -> std::int32_t { + return _carbonizedSkin; +} + +auto Profile::getCarbonizedSkin() -> std::int32_t { + auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &carbonized_skin_locator[0], &carbonized_skin_locator[129]); + + if(iter != mmap.end()) { + _carbonizedSkin = *reinterpret_cast(iter + 0x8C); + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + _carbonizedSkin = -1; + } + + return _carbonizedSkin; +} + +auto Profile::setCarbonizedSkin(std::int32_t amount) -> bool { + auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename)); + + auto iter = std::search(mmap.begin(), mmap.end(), &carbonized_skin_locator[0], &carbonized_skin_locator[129]); + + if(iter != mmap.end()) { + *reinterpret_cast(iter + 0x8C) = amount; + _carbonizedSkin = amount; + return true; + } + else { + _lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file."; + return false; + } +} + auto Profile::backup(const std::string& filename) -> bool { if(filename.empty() || (filename.length() < 5 && !Utility::String::endsWith(filename, ".zip"))) { _lastError = "Invalid filename " + filename + " in Profile::backup()"; diff --git a/Profile/Profile.h b/Profile/Profile.h index fa98a5d..3781e73 100644 --- a/Profile/Profile.h +++ b/Profile/Profile.h @@ -41,6 +41,86 @@ class Profile { auto lastMissionId() const -> std::int32_t; auto getLastMissionId() -> std::int32_t; + auto verseSteel() const -> std::int32_t; + auto getVerseSteel() -> std::int32_t; + auto setVerseSteel(std::int32_t amount) -> bool; + + auto undinium() const -> std::int32_t; + auto getUndinium() -> std::int32_t; + auto setUndinium(std::int32_t amount) -> bool; + + auto necriumAlloy() const -> std::int32_t; + auto getNecriumAlloy() -> std::int32_t; + auto setNecriumAlloy(std::int32_t amount) -> bool; + + auto lunarite() const -> std::int32_t; + auto getLunarite() -> std::int32_t; + auto setLunarite(std::int32_t amount) -> bool; + + auto asterite() const -> std::int32_t; + auto getAsterite() -> std::int32_t; + auto setAsterite(std::int32_t amount) -> bool; + + auto ednil() const -> std::int32_t; + auto getEdnil() -> std::int32_t; + auto setEdnil(std::int32_t amount) -> bool; + + auto nuflalt() const -> std::int32_t; + auto getNuflalt() -> std::int32_t; + auto setNuflalt(std::int32_t amount) -> bool; + + auto aurelene() const -> std::int32_t; + auto getAurelene() -> std::int32_t; + auto setAurelene(std::int32_t amount) -> bool; + + auto soldus() const -> std::int32_t; + auto getSoldus() -> std::int32_t; + auto setSoldus(std::int32_t amount) -> bool; + + auto synthesizedN() const -> std::int32_t; + auto getSynthesizedN() -> std::int32_t; + auto setSynthesizedN(std::int32_t amount) -> bool; + + auto alcarbonite() const -> std::int32_t; + auto getAlcarbonite() -> std::int32_t; + auto setAlcarbonite(std::int32_t amount) -> bool; + + auto keriphene() const -> std::int32_t; + auto getKeriphene() -> std::int32_t; + auto setKeriphene(std::int32_t amount) -> bool; + + auto nitinolCM() const -> std::int32_t; + auto getNitinolCM() -> std::int32_t; + auto setNitinolCM(std::int32_t amount) -> bool; + + auto quarkium() const -> std::int32_t; + auto getQuarkium() -> std::int32_t; + auto setQuarkium(std::int32_t amount) -> bool; + + auto alterene() const -> std::int32_t; + auto getAlterene() -> std::int32_t; + auto setAlterene(std::int32_t amount) -> bool; + + auto mixedComposition() const -> std::int32_t; + auto getMixedComposition() -> std::int32_t; + auto setMixedComposition(std::int32_t amount) -> bool; + + auto voidResidue() const -> std::int32_t; + auto getVoidResidue() -> std::int32_t; + auto setVoidResidue(std::int32_t amount) -> bool; + + auto muscularConstruction() const -> std::int32_t; + auto getMuscularConstruction() -> std::int32_t; + auto setMuscularConstruction(std::int32_t amount) -> bool; + + auto mineralExoskeletology() const -> std::int32_t; + auto getMineralExoskeletology() -> std::int32_t; + auto setMineralExoskeletology(std::int32_t amount) -> bool; + + auto carbonizedSkin() const -> std::int32_t; + auto getCarbonizedSkin() -> std::int32_t; + auto setCarbonizedSkin(std::int32_t amount) -> bool; + auto backup(const std::string& filename) -> bool; private: @@ -63,6 +143,28 @@ class Profile { std::int32_t _storyProgress; std::int32_t _lastMissionId; + + std::int32_t _verseSteel; + std::int32_t _undinium; + std::int32_t _necriumAlloy; + std::int32_t _lunarite; + std::int32_t _asterite; + std::int32_t _ednil; + std::int32_t _nuflalt; + std::int32_t _aurelene; + std::int32_t _soldus; + std::int32_t _synthesizedN; + std::int32_t _alcarbonite; + std::int32_t _keriphene; + std::int32_t _nitinolCM; + std::int32_t _quarkium; + std::int32_t _alterene; + + std::int32_t _mixedComposition; + std::int32_t _voidResidue; + std::int32_t _muscularConstruction; + std::int32_t _mineralExoskeletology; + std::int32_t _carbonizedSkin; }; #endif //PROFILE_H