// MassBuilderSaveTool // Copyright (C) 2021 Guillaume Jacquemin // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include #include #include #include #include #include #include "../UESaveFile/Types/ArrayProperty.h" #include "../UESaveFile/Types/ResourceItemValue.h" #include "../UESaveFile/Types/IntProperty.h" #include "../UESaveFile/Types/StringProperty.h" #include "Profile.h" using namespace Corrade; Profile::Profile(const std::string& path): _profile(path) { _profileDirectory = Utility::Directory::path(path); _filename = Utility::Directory::filename(path); if(Utility::String::beginsWith(_filename, "Demo")) { _type = ProfileType::Demo; } else { _type = ProfileType::FullGame; } _steamId = Utility::String::ltrim(Utility::String::rtrim(_filename, ".sav"), (_type == ProfileType::Demo ? "Demo" : "") + std::string{"Profile"}); _valid = _profile.valid(); } auto Profile::valid() const -> bool { return _valid; } auto Profile::lastError() const -> std::string const& { return _lastError; } auto Profile::filename() const -> std::string const& { return _filename; } auto Profile::type() const -> ProfileType { return _type; } auto Profile::steamId() const -> std::string const& { return _steamId; } void Profile::refreshValues() { _profile.reloadData(); } auto Profile::companyName() -> std::string const& { return _profile.at("CompanyName")->value; } auto Profile::renameCompany(const std::string& new_name) -> bool { auto name_prop = _profile.at("CompanyName"); name_prop->value = new_name; if(!_profile.saveToFile()) { _lastError = "Couldn't save the profile."; return false; } return true; } auto Profile::activeFrameSlot() -> Int { auto active_frame_slot_prop = _profile.at("ActiveFrameSlot"); return active_frame_slot_prop ? active_frame_slot_prop->value : 0; } auto Profile::credits() -> Int { auto credits_prop = _profile.at("Credit"); return credits_prop ? credits_prop->value : 0; } auto Profile::setCredits(Int amount) -> bool { auto credits_prop = _profile.at("Credit"); if(!credits_prop) { credits_prop = new IntProperty; _profile.appendProperty(IntProperty::ptr{credits_prop}); } credits_prop->value = amount; if(!_profile.saveToFile()) { _lastError = "Couldn't save the profile."; return false; } return true; } auto Profile::storyProgress() -> Int { auto story_progress_prop = _profile.at("StoryProgress"); return story_progress_prop ? story_progress_prop->value : 0; } auto Profile::setStoryProgress(Int progress) -> bool { auto story_progress_prop = _profile.at("StoryProgress"); if(!story_progress_prop) { story_progress_prop = new IntProperty; _profile.appendProperty(IntProperty::ptr{story_progress_prop}); } story_progress_prop->value = progress; if(!_profile.saveToFile()) { _lastError = "Couldn't save the profile."; return false; } return true; } auto Profile::lastMissionId() -> Int { auto last_mission_id_prop = _profile.at("LastMissionID"); return last_mission_id_prop ? last_mission_id_prop->value : 0; } auto Profile::verseSteel() -> Int { return resource("ResourceMaterial", 0xC3500); } auto Profile::setVerseSteel(Int amount) -> bool { return setResource("ResourceMaterial", 0xC3500, amount); } auto Profile::undinium() -> Int { return resource("ResourceMaterial", 0xC3501); } auto Profile::setUndinium(Int amount) -> bool { return setResource("ResourceMaterial", 0xC3501, amount); } auto Profile::necriumAlloy() -> Int { return resource("ResourceMaterial", 0xC3502); } auto Profile::setNecriumAlloy(Int amount) -> bool { return setResource("ResourceMaterial", 0xC3502, amount); } auto Profile::lunarite() -> Int { return resource("ResourceMaterial", 0xC3503); } auto Profile::setLunarite(Int amount) -> bool { return setResource("ResourceMaterial", 0xC3503, amount); } auto Profile::asterite() -> Int { return resource("ResourceMaterial", 0xC3504); } auto Profile::setAsterite(Int amount) -> bool { return setResource("ResourceMaterial", 0xC3504, amount); } auto Profile::ednil() -> Int { return resource("ResourceMaterial", 0xC350A); } auto Profile::setEdnil(Int amount) -> bool { return setResource("ResourceMaterial", 0xC350A, amount); } auto Profile::nuflalt() -> Int { return resource("ResourceMaterial", 0xC350B); } auto Profile::setNuflalt(Int amount) -> bool { return setResource("ResourceMaterial", 0xC350B, amount); } auto Profile::aurelene() -> Int { return resource("ResourceMaterial", 0xC350C); } auto Profile::setAurelene(Int amount) -> bool { return setResource("ResourceMaterial", 0xC350C, amount); } auto Profile::soldus() -> Int { return resource("ResourceMaterial", 0xC350D); } auto Profile::setSoldus(Int amount) -> bool { return setResource("ResourceMaterial", 0xC350D, amount); } auto Profile::synthesizedN() -> Int { return resource("ResourceMaterial", 0xC350E); } auto Profile::setSynthesizedN(Int amount) -> bool { return setResource("ResourceMaterial", 0xC350E, amount); } auto Profile::alcarbonite() -> Int { return resource("ResourceMaterial", 0xC3514); } auto Profile::setAlcarbonite(Int amount) -> bool { return setResource("ResourceMaterial", 0xC3514, amount); } auto Profile::keriphene() -> Int { return resource("ResourceMaterial", 0xC3515); } auto Profile::setKeriphene(Int amount) -> bool { return setResource("ResourceMaterial", 0xC3515, amount); } auto Profile::nitinolCM() -> Int { return resource("ResourceMaterial", 0xC3516); } auto Profile::setNitinolCM(Int amount) -> bool { return setResource("ResourceMaterial", 0xC3516, amount); } auto Profile::quarkium() -> Int { return resource("ResourceMaterial", 0xC3517); } auto Profile::setQuarkium(Int amount) -> bool { return setResource("ResourceMaterial", 0xC3517, amount); } auto Profile::alterene() -> Int { return resource("ResourceMaterial", 0xC3518); } auto Profile::setAlterene(Int amount) -> bool { return setResource("ResourceMaterial", 0xC3518, amount); } auto Profile::mixedComposition() -> Int { return resource("ResourceQuarkData", 0xDBBA0); } auto Profile::setMixedComposition(Int amount) -> bool { return setResource("ResourceQuarkData", 0xDBBA0, amount); } auto Profile::voidResidue() -> Int { return resource("ResourceQuarkData", 0xDBBA1); } auto Profile::setVoidResidue(Int amount) -> bool { return setResource("ResourceQuarkData", 0xDBBA1, amount); } auto Profile::muscularConstruction() -> Int { return resource("ResourceQuarkData", 0xDBBA2); } auto Profile::setMuscularConstruction(Int amount) -> bool { return setResource("ResourceQuarkData", 0xDBBA2, amount); } auto Profile::mineralExoskeletology() -> Int { return resource("ResourceQuarkData", 0xDBBA3); } auto Profile::setMineralExoskeletology(Int amount) -> bool { return setResource("ResourceQuarkData", 0xDBBA3, amount); } auto Profile::carbonizedSkin() -> Int { return resource("ResourceQuarkData", 0xDBBA4); } auto Profile::setCarbonizedSkin(Int amount) -> bool { return setResource("ResourceQuarkData", 0xDBBA4, amount); } auto Profile::resource(const char* container, Int id) -> Int { auto mats_prop = _profile.at(container); static auto predicate = [&id](UnrealPropertyBase::ptr& prop){ auto res_prop = static_cast(prop.get()); return res_prop->id == id; }; auto it = std::find_if(mats_prop->items.begin(), mats_prop->items.end(), predicate); return it != mats_prop->items.end() ? static_cast(it->get())->quantity : 0; } auto Profile::setResource(const char* container, Int id, Int amount) -> bool { auto mats_prop = _profile.at(container); static auto predicate = [&id](UnrealPropertyBase::ptr& prop){ auto res_prop = static_cast(prop.get()); return res_prop->id == id; }; auto it = std::find_if(mats_prop->items.begin(), mats_prop->items.end(), predicate); ResourceItemValue* res_prop; if(it == mats_prop->items.end()) { res_prop = new ResourceItemValue; res_prop->id = id; ResourceItemValue::ptr prop{res_prop}; arrayAppend(mats_prop->items, std::move(prop)); } else { res_prop = static_cast(it->get()); } res_prop->quantity = amount; if(!_profile.saveToFile()) { _lastError = _profile.lastError(); return false; } return _profile.saveToFile(); }