// 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 "ResourceIDs.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"}); refreshValues(); _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() { if(!_profile.reloadData()) { _lastError = _profile.lastError(); _valid = false; return; } _name = _profile.at("CompanyName")->value; auto prop = _profile.at("ActiveFrameSlot"); _activeFrameSlot = prop ? prop->value : 0; prop = _profile.at("Credit"); _credits = prop ? prop->value : 0; prop = _profile.at("StoryProgress"); _storyProgress = prop ? prop->value : 0; prop = _profile.at("LastMissionID"); _lastMissionId = prop ? prop->value : 0; _verseSteel = getResource("ResourceMaterial", VerseSteel); _undinium = getResource("ResourceMaterial", Undinium); _necriumAlloy = getResource("ResourceMaterial", NecriumAlloy); _lunarite = getResource("ResourceMaterial", Lunarite); _asterite = getResource("ResourceMaterial", Asterite); _ednil = getResource("ResourceMaterial", Ednil); _nuflalt = getResource("ResourceMaterial", Nuflalt); _aurelene = getResource("ResourceMaterial", Aurelene); _soldus = getResource("ResourceMaterial", Soldus); _synthesisedN = getResource("ResourceMaterial", SynthesisedN); _alcarbonite = getResource("ResourceMaterial", Alcarbonite); _keriphene = getResource("ResourceMaterial", Keriphene); _nitinolCM = getResource("ResourceMaterial", NitinolCM); _quarkium = getResource("ResourceMaterial", Quarkium); _alterene = getResource("ResourceMaterial", Alterene); _mixedComposition = getResource("ResourceQuarkData", MixedComposition); _voidResidue = getResource("ResourceQuarkData", VoidResidue); _muscularConstruction = getResource("ResourceQuarkData", MuscularConstruction); _mineralExoskeletology = getResource("ResourceQuarkData", MineralExoskeletology); _carbonisedSkin = getResource("ResourceQuarkData", CarbonisedSkin); } auto Profile::companyName() const -> std::string const& { return _name; } 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() const -> Int { return _activeFrameSlot; } auto Profile::credits() const -> Int { return _credits; } 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() const -> Int { return _storyProgress; } 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() const -> Int { return _lastMissionId; } auto Profile::verseSteel() const -> Int { return _verseSteel; } auto Profile::setVerseSteel(Int amount) -> bool { return setResource("ResourceMaterial", VerseSteel, amount); } auto Profile::undinium() const -> Int { return _undinium; } auto Profile::setUndinium(Int amount) -> bool { return setResource("ResourceMaterial", Undinium, amount); } auto Profile::necriumAlloy() const -> Int { return _necriumAlloy; } auto Profile::setNecriumAlloy(Int amount) -> bool { return setResource("ResourceMaterial", NecriumAlloy, amount); } auto Profile::lunarite() const -> Int { return _lunarite; } auto Profile::setLunarite(Int amount) -> bool { return setResource("ResourceMaterial", Lunarite, amount); } auto Profile::asterite() const -> Int { return _asterite; } auto Profile::setAsterite(Int amount) -> bool { return setResource("ResourceMaterial", Asterite, amount); } auto Profile::ednil() const -> Int { return _ednil; } auto Profile::setEdnil(Int amount) -> bool { return setResource("ResourceMaterial", Ednil, amount); } auto Profile::nuflalt() const -> Int { return _nuflalt; } auto Profile::setNuflalt(Int amount) -> bool { return setResource("ResourceMaterial", Nuflalt, amount); } auto Profile::aurelene() const -> Int { return _aurelene; } auto Profile::setAurelene(Int amount) -> bool { return setResource("ResourceMaterial", Aurelene, amount); } auto Profile::soldus() const -> Int { return _soldus; } auto Profile::setSoldus(Int amount) -> bool { return setResource("ResourceMaterial", Soldus, amount); } auto Profile::synthesisedN() const -> Int { return _synthesisedN; } auto Profile::setSynthesisedN(Int amount) -> bool { return setResource("ResourceMaterial", SynthesisedN, amount); } auto Profile::alcarbonite() const -> Int { return _alcarbonite; } auto Profile::setAlcarbonite(Int amount) -> bool { return setResource("ResourceMaterial", Alcarbonite, amount); } auto Profile::keriphene() const -> Int { return _keriphene; } auto Profile::setKeriphene(Int amount) -> bool { return setResource("ResourceMaterial", Keriphene, amount); } auto Profile::nitinolCM() const -> Int { return _nitinolCM; } auto Profile::setNitinolCM(Int amount) -> bool { return setResource("ResourceMaterial", NitinolCM, amount); } auto Profile::quarkium() const -> Int { return _quarkium; } auto Profile::setQuarkium(Int amount) -> bool { return setResource("ResourceMaterial", Quarkium, amount); } auto Profile::alterene() const -> Int { return _alterene; } auto Profile::setAlterene(Int amount) -> bool { return setResource("ResourceMaterial", Alterene, amount); } auto Profile::mixedComposition() const -> Int { return _mixedComposition; } auto Profile::setMixedComposition(Int amount) -> bool { return setResource("ResourceQuarkData", MixedComposition, amount); } auto Profile::voidResidue() const -> Int { return _voidResidue; } auto Profile::setVoidResidue(Int amount) -> bool { return setResource("ResourceQuarkData", VoidResidue, amount); } auto Profile::muscularConstruction() const -> Int { return _muscularConstruction; } auto Profile::setMuscularConstruction(Int amount) -> bool { return setResource("ResourceQuarkData", MuscularConstruction, amount); } auto Profile::mineralExoskeletology() const -> Int { return _mineralExoskeletology; } auto Profile::setMineralExoskeletology(Int amount) -> bool { return setResource("ResourceQuarkData", MineralExoskeletology, amount); } auto Profile::carbonisedSkin() const -> Int { return _carbonisedSkin; } auto Profile::setCarbonisedSkin(Int amount) -> bool { return setResource("ResourceQuarkData", CarbonisedSkin, amount); } auto Profile::getResource(const char* container, Int id) -> Int { auto mats_prop = _profile.at(container); if(!mats_prop) { return 0; } 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); if(!mats_prop) { return false; } 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(); }