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
-
-
+
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