// 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 "ResearchTree.h" #include "NodeIDs.h" //region Node Node::Node(Node::Type type, const char* name, UnsignedByte tier, UnsignedByte slots, const char* description, const char* active_effect, const char* passive_effect): _type{type}, _state{State::Unavailable}, _name{name}, _tier{tier}, _slots{slots}, _description{description}, _activeEffect{active_effect}, _passiveEffect{passive_effect} { //ctor } auto Node::type() const -> Node::Type { return _type; } auto Node::state() const -> Node::State { return _state; } void Node::setState(Node::State state) { if(_state == state) { return; } _state = state; if(_state == State::Available) { for(Node* n : _children) { n->setState(State::Unavailable, NotClicked); } } else if(_state == State::Unlocked) { for(Node* n : _children) { n->setState(State::Available, NotClicked); } } } auto Node::name() const -> const char* { return _name; } auto Node::tier() const -> UnsignedByte { return _tier; } auto Node::slots() const -> UnsignedByte { return _slots; } auto Node::description() const -> const char* { return _description; } auto Node::activeEffect() const -> const char* { return _activeEffect; } auto Node::passiveEffect() const -> const char* { return _passiveEffect; } auto Node::children() -> Containers::ArrayView { return _children; } void Node::addChild(Node& child) { arrayAppend(_children, &child); child.addParent(*this); } void Node::addParent(Node& parent) { arrayAppend(_parents, &parent); } void Node::setState(State state, NotClickedT) { if(_state == state) { return; } if(state == State::Unavailable) { for(Node* node : _parents) { if(node->state() == State::Unlocked) { return; } } } else if(state == State::Available && _state == State::Unlocked) { return; } _state = state; if(_state != State::Unlocked) { for(Node* node : _children) { node->setState(State::Unavailable, NotClicked); } } else { for(Node* node : _children) { node->setState(State::Available, NotClicked); } } } //endregion void ResearchTree::generateEngineTree() { if(!_engineNodes.empty()) { return; } // T1 _engineNodes.emplace(VerseEngine, Node{Node::Type::Engine, "Verse Engine", 1, 3, "A basic low-speed engine with great durability.", "Durability +346, Power +60, Armour +22, Acceleration +75, Magazine load +35, Energy capacity +35", "Durability +3%"}); _engineNodes.emplace(LoadedEngine, Node{Node::Type::Engine, "Loaded Engine", 1, 3, "An alternate heavier model of engine used to operate a M.A.S.S.", "Durability +288, Power +84, Armour +14, Acceleration +75, Magazine load +35, Energy capacity +35", "Power +3%"}); _engineNodes.emplace(MetalPlatings1, Node{Node::Type::Gear, "Metal Platings 1", 1, 0, "Level 1 metal plating that adds durability and armour to your engine.", "Durability +60, Armour +5, Acceleration -15", ""}); _engineNodes.emplace(HeatTurbines1, Node{Node::Type::Gear, "Heat Turbines 1", 1, 0, "Modified heat turbines to increase speed for a M.A.S.S.", "Acceleration +75, Fuel capacity +5", ""}); _engineNodes.emplace(Microcontroller1, Node{Node::Type::Gear, "Microcontroller 1", 1, 0, "A microchip that enhances various aspects of a M.A.S.S.", "Durability +36, Power +1, Armour +11, Magazine load +5, Energy capacity +5, Fuel capacity +3", ""}); _engineNodes.emplace(CombustionController1, Node{Node::Type::Gear, "Combustion Controller 1", 1, 0, "Controlled combustion allows increased power generation through specific ignition.", "Power +2, Magazine load +10, Energy capacity +10, Acceleration -25", ""}); // T2 _engineNodes.emplace(ModAlloyEngine, Node{Node::Type::Engine, "Mod. Alloy Engine", 2, 3, "Built with a modified alloy and able to sustain greater attacks from any enemy.", "Durability +1152, Power +75, Armour +194, Acceleration +75, Magazine load +40, Energy capacity +40", "Durability +3%"}); _engineNodes.emplace(ChargedEngine, Node{Node::Type::Engine, "Charged Engine", 2, 3, "Remove most armours to attain more speed and power, and fuel.", "Durability +960, Power +75, Acceleration +300, Magazine load +40, Energy capacity +40, Fuel capacity +52", "Acceleration +5"}); _engineNodes.emplace(ReinforcedLoadedEngine, Node{Node::Type::Engine, "Reinforced Loaded Engine", 2, 3, "An upgraded build of the basic model, with reinforced Verse Steel for more strength.", "Durability +960, Power +105, Armour +130, Acceleration +75, Magazine load +40, Energy capacity +40", "Power +3%"}); _engineNodes.emplace(HeavyImpactsEnabler, Node{Node::Type::Engine, "Heavy Impacts Enabler", 2, 0, "Enable the usage of Heavy Combos in close combat attacks.", "", ""}); _engineNodes.emplace(MetalPlatings2, Node{Node::Type::Gear, "Metal Platings 2", 2, 0, "Level 2 Metal plating that adds durability and armour to your engine.", "Durability +180, Armour +41, Acceleration -15", ""}); _engineNodes.emplace(HeatTurbines2, Node{Node::Type::Gear, "Heat Turbines 2", 2, 0, "Level 2 Modified heat turbines to increase speed for a M.A.S.S.", "Acceleration +75, Fuel capacity +16", ""}); _engineNodes.emplace(Microcontroller2, Node{Node::Type::Gear, "Microcontroller 2", 2, 0, "Level 2 Microchip that enhances various aspects of a M.A.S.S.", "Durability +108, Power +3, Armour +17, Magazine load +6, Energy capacity +6, Fuel capacity +8", ""}); _engineNodes.emplace(WeaponsCargo1, Node{Node::Type::Gear, "Weapons Cargo 1", 2, 0, "Added another cargo hold for ammo and energy recharger.", "Magazine load +24, Energy capacity +24, Acceleration -40", ""}); _engineNodes.emplace(CombustionController2, Node{Node::Type::Gear, "Combustion Controller 2", 2, 0, "Level 2 Controlled combustion allows increased power generation through specific ignition.", "Power +5, Magazine load +12, Energy capacity +12, Acceleration -25", ""}); _engineNodes.emplace(PoweredRewiring1, Node{Node::Type::Gear, "Powered Rewiring 1", 2, 0, "Rewiring that efficiently improves power and engine durability.", "Durability +180, Power +5", ""}); // T3 _engineNodes.emplace(ModSteelEngine, Node{Node::Type::Engine, "Mod. Steel Engine", 3, 3, "Low-speed engine that uses heavy materials for high durability.", "Durability +2352, Power +90, Armour +311, Acceleration +75, Magazine load +47, Energy capacity +47", "Durability +3%"}); _engineNodes.emplace(SuperchargedEngine, Node{Node::Type::Engine, "Supercharged Engine", 3, 3, "An engine with more thermal efficiency that does not sacrifice much performance for speed.", "Durability +1960, Power +90, Acceleration +300, Magazine load +47, Energy capacity +47, Fuel capacity +104", "Acceleration +5"}); _engineNodes.emplace(NecriumAlloyEngine, Node{Node::Type::Engine, "Necrium Alloy Engine", 3, 3, "Engine constructed of Necrium Alloy. Costly but with better performance.", "Durability +1960, Power +126, Armour +207, Acceleration +75, Magazine load +47, Energy capacity +47", "Power +3%"}); _engineNodes.emplace(MetalPlatings3, Node{Node::Type::Gear, "Metal Platings 3", 3, 0, "Level 3 Metal plating that adds durability and armour to your engine.", "Durability +360, Armour +57, Acceleration -15", ""}); _engineNodes.emplace(HeatTurbines3, Node{Node::Type::Gear, "Heat Turbines 3", 3, 0, "Level 3 Modified heat turbines to increase speed for a M.A.S.S.", "Acceleration +75, Fuel capacity +32", ""}); _engineNodes.emplace(Microcontroller3, Node{Node::Type::Gear, "Microcontroller 3", 3, 0, "Level 3 Microchip that enhances various aspects of a M.A.S.S.", "Durability +216, Power +5, Armour +24, Magazine load +7, Energy capacity +7, Fuel capacity +16", ""}); _engineNodes.emplace(WeaponsCargo2, Node{Node::Type::Gear, "Weapons Cargo 2", 3, 0, "Level 2 Added another cargo hold for ammo and energy recharger.", "Magazine load +28, Energy capacity +28, Acceleration -40", ""}); _engineNodes.emplace(CombustionController3, Node{Node::Type::Gear, "Combustion Controller 3", 3, 0, "Level 3 Controlled combustion allows increased power generation through specific ignition.", "Power +11, Magazine load +14, Energy capacity +14, Acceleration -25", ""}); _engineNodes.emplace(PoweredRewiring2, Node{Node::Type::Gear, "Powered Rewiring 2", 3, 0, "Level 2 Rewiring that efficiently improves power and engine durability.", "Durability +360, Power +11", ""}); _engineNodes.at(VerseEngine).addChild(_engineNodes.at(MetalPlatings1)); _engineNodes.at(VerseEngine).addChild(_engineNodes.at(HeatTurbines1)); _engineNodes.at(VerseEngine).addChild(_engineNodes.at(LoadedEngine)); _engineNodes.at(LoadedEngine).addChild(_engineNodes.at(Microcontroller1)); _engineNodes.at(LoadedEngine).addChild(_engineNodes.at(CombustionController1)); _engineNodes.at(MetalPlatings1).addChild(_engineNodes.at(ModAlloyEngine)); _engineNodes.at(HeatTurbines1).addChild(_engineNodes.at(ChargedEngine)); _engineNodes.at(Microcontroller1).addChild(_engineNodes.at(ChargedEngine)); _engineNodes.at(CombustionController1).addChild(_engineNodes.at(ReinforcedLoadedEngine)); _engineNodes.at(ModAlloyEngine).addChild(_engineNodes.at(MetalPlatings2)); _engineNodes.at(ModAlloyEngine).addChild(_engineNodes.at(HeatTurbines2)); _engineNodes.at(ChargedEngine).addChild(_engineNodes.at(HeatTurbines2)); _engineNodes.at(ChargedEngine).addChild(_engineNodes.at(Microcontroller2)); _engineNodes.at(ChargedEngine).addChild(_engineNodes.at(WeaponsCargo1)); _engineNodes.at(ReinforcedLoadedEngine).addChild(_engineNodes.at(CombustionController2)); _engineNodes.at(ReinforcedLoadedEngine).addChild(_engineNodes.at(PoweredRewiring1)); _engineNodes.at(ReinforcedLoadedEngine).addChild(_engineNodes.at(HeavyImpactsEnabler)); _engineNodes.at(MetalPlatings2).addChild(_engineNodes.at(ModSteelEngine)); _engineNodes.at(HeatTurbines2).addChild(_engineNodes.at(SuperchargedEngine)); _engineNodes.at(Microcontroller2).addChild(_engineNodes.at(SuperchargedEngine)); _engineNodes.at(WeaponsCargo1).addChild(_engineNodes.at(SuperchargedEngine)); _engineNodes.at(CombustionController2).addChild(_engineNodes.at(NecriumAlloyEngine)); _engineNodes.at(PoweredRewiring1).addChild(_engineNodes.at(NecriumAlloyEngine)); _engineNodes.at(ModSteelEngine).addChild(_engineNodes.at(MetalPlatings3)); _engineNodes.at(ModSteelEngine).addChild(_engineNodes.at(HeatTurbines3)); _engineNodes.at(SuperchargedEngine).addChild(_engineNodes.at(HeatTurbines3)); _engineNodes.at(SuperchargedEngine).addChild(_engineNodes.at(Microcontroller3)); _engineNodes.at(SuperchargedEngine).addChild(_engineNodes.at(WeaponsCargo2)); _engineNodes.at(NecriumAlloyEngine).addChild(_engineNodes.at(WeaponsCargo2)); _engineNodes.at(NecriumAlloyEngine).addChild(_engineNodes.at(CombustionController3)); _engineNodes.at(NecriumAlloyEngine).addChild(_engineNodes.at(PoweredRewiring2)); _engineNodes.at(VerseEngine).setState(Node::State::Unlocked); } void ResearchTree::generateOSTree() { if(!_osNodes.empty()) { return; } _osNodes.emplace(NeuralOS, Node{Node::Type::OS, "Neural OS", 1, 3, "Synchronise the links between your nervous system and the M.A.S.S. perfectly.", "Accuracy +24, Shield +624, Fuel burn rate +200, Magazine reload +24, Energy recharge +66, Shield recover +1620", "Shield +3%"}); _osNodes.at(NeuralOS).setState(Node::State::Unlocked); } void ResearchTree::generateArchTree() { if(!_archNodes.empty()) { return; } _archNodes.emplace(StandardFrame, Node{Node::Type::Architect, "Standard Frame", 1, 2, "The standard frame architecture for mass-produced humanoid robots. It uses the most common technologies and materials.", "Durability +300, Shield +200, Physical damage +600, Piercing damage +300, Plasma damage +300", ""}); _archNodes.at(StandardFrame).setState(Node::State::Unlocked); } void ResearchTree::readEngineUnlocks(Containers::ArrayView engines, Containers::ArrayView gears) { if(engines == nullptr || engines.size() == 0) { Utility::Error{} << "Engines can't be empty"; } for(Int& engine : engines) { if(_engineNodes.find(engine) != _engineNodes.end()) { _engineNodes.at(engine).setState(Node::State::Unlocked); } } if(gears == nullptr || engines.size() == 0) { return; } for(Int& gear : gears) { if(_engineNodes.find(gear) != _engineNodes.end()) { _engineNodes.at(gear).setState(Node::State::Unlocked); } } } auto ResearchTree::getEngineRootNode() -> Node& { return _engineNodes.at(VerseEngine); } auto ResearchTree::getOSRootNode() -> Node& { return _osNodes.at(NeuralOS); } auto ResearchTree::getArchRootNode() -> Node& { return _archNodes.at(StandardFrame); }