2021-06-11 19:24:52 +02:00
// MassBuilderSaveTool
2022-01-30 11:36:56 +01:00
// Copyright (C) 2021-2022 Guillaume Jacquemin
2021-06-11 19:24:52 +02:00
//
// 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 <https://www.gnu.org/licenses/>.
# include <algorithm>
# include <Corrade/Containers/Array.h>
2022-03-09 11:04:19 +01:00
# include <Corrade/Containers/Pair.h>
2022-03-30 19:51:00 +02:00
# include <Corrade/Containers/ScopeGuard.h>
2022-03-09 11:04:19 +01:00
# include <Corrade/Utility/Path.h>
2021-06-11 19:24:52 +02:00
2021-09-27 17:52:47 +02:00
# include "../UESaveFile/Types/ArrayProperty.h"
2021-10-03 16:32:47 +02:00
# include "../UESaveFile/Types/BoolProperty.h"
2021-09-27 17:52:47 +02:00
# include "../UESaveFile/Types/ColourStructProperty.h"
# include "../UESaveFile/Types/GenericStructProperty.h"
# include "../UESaveFile/Types/IntProperty.h"
# include "../UESaveFile/Types/StringProperty.h"
2021-08-19 20:33:59 +02:00
2021-06-11 19:24:52 +02:00
# include "Mass.h"
2022-03-04 21:18:55 +01:00
using namespace Containers : : Literals ;
2022-03-09 11:04:19 +01:00
Mass : : Mass ( Containers : : StringView path ) {
auto split = Utility : : Path : : split ( path ) ;
_folder = split . first ( ) ;
_filename = split . second ( ) ;
2021-06-11 19:24:52 +02:00
2021-08-28 20:20:09 +02:00
refreshValues ( ) ;
2021-06-11 19:24:52 +02:00
}
2022-03-04 21:18:55 +01:00
auto Mass : : lastError ( ) - > Containers : : StringView {
2021-06-11 19:24:52 +02:00
return _lastError ;
}
2022-03-04 21:18:55 +01:00
auto Mass : : getNameFromFile ( Containers : : StringView path ) - > Containers : : Optional < Containers : : String > {
2022-03-09 11:04:19 +01:00
if ( ! Utility : : Path : : exists ( path ) ) {
2022-03-04 21:18:55 +01:00
Utility : : Error { } < < path < < " couldn't be found. " _s ;
2021-09-27 17:52:47 +02:00
return Containers : : NullOpt ;
2021-06-11 19:24:52 +02:00
}
2021-09-27 17:52:47 +02:00
UESaveFile mass { path } ;
2021-06-11 19:24:52 +02:00
2021-09-27 17:52:47 +02:00
if ( ! mass . valid ( ) ) {
2022-03-04 21:18:55 +01:00
Utility : : Error { } < < " The unit file seems to be corrupt. " _s ;
2021-09-27 17:52:47 +02:00
return Containers : : NullOpt ;
}
2021-06-11 19:24:52 +02:00
2022-03-04 21:18:55 +01:00
auto unit_data = mass . at < GenericStructProperty > ( " UnitData " _s ) ;
2021-06-11 19:24:52 +02:00
2021-09-27 17:52:47 +02:00
if ( ! unit_data ) {
2022-03-04 21:18:55 +01:00
Utility : : Error { } < < " Couldn't find unit data in the file. " _s ;
2021-09-27 17:52:47 +02:00
return Containers : : NullOpt ;
2021-06-11 19:24:52 +02:00
}
2021-09-27 17:52:47 +02:00
2022-03-04 21:18:55 +01:00
auto name_prop = unit_data - > at < StringProperty > ( " Name_45_A037C5D54E53456407BDF091344529BB " _s ) ;
2021-09-27 17:52:47 +02:00
if ( ! name_prop ) {
2022-03-04 21:18:55 +01:00
Utility : : Error { } < < " Couldn't find the name in the file. " _s ;
2021-09-27 17:52:47 +02:00
return Containers : : NullOpt ;
2021-06-11 19:24:52 +02:00
}
2022-03-04 21:18:55 +01:00
return { name_prop - > value } ;
2021-06-11 19:24:52 +02:00
}
2021-08-28 20:20:09 +02:00
void Mass : : refreshValues ( ) {
2022-03-30 19:51:00 +02:00
Utility : : Debug { } < < " =Refreshing values for " < < _filename < < Utility : : Debug : : nospace < < " = " ;
Containers : : ScopeGuard guard { [ ] { Utility : : Error { } < < " Refresh failed. " ; } } ;
2022-03-09 11:04:19 +01:00
if ( ! Utility : : Path : : exists ( Utility : : Path : : join ( _folder , _filename ) ) ) {
2022-03-30 19:51:00 +02:00
Utility : : Warning { } < < _filename < < " does not exist in " < < _folder ;
2021-09-27 17:52:47 +02:00
_state = State : : Empty ;
2021-08-28 20:21:13 +02:00
return ;
}
2021-09-27 17:52:47 +02:00
if ( ! _mass ) {
2022-03-09 11:04:19 +01:00
_mass . emplace ( Utility : : Path : : join ( _folder , _filename ) ) ;
2021-09-27 17:52:47 +02:00
if ( ! _mass - > valid ( ) ) {
2022-03-30 19:51:00 +02:00
Utility : : Error { } < < _mass - > lastError ( ) ;
2021-09-27 17:52:47 +02:00
_state = State : : Invalid ;
return ;
}
2021-08-28 20:21:13 +02:00
}
2021-09-27 17:52:47 +02:00
else {
if ( ! _mass - > reloadData ( ) ) {
2022-03-30 19:51:00 +02:00
Utility : : Error { } < < _mass - > lastError ( ) ;
2021-09-27 17:52:47 +02:00
_state = State : : Invalid ;
return ;
}
2021-08-28 20:21:13 +02:00
}
2022-04-02 19:54:32 +02:00
if ( _mass - > saveType ( ) ! = " /Game/Core/Save/bpSaveGameUnit.bpSaveGameUnit_C " _s ) {
Utility : : Error { } < < _filename < < " is not a valid unit save. " ;
}
2022-03-11 10:57:16 +01:00
auto unit_data = _mass - > at < GenericStructProperty > ( " UnitData " _s ) ;
2021-09-27 17:52:47 +02:00
if ( ! unit_data ) {
2022-03-30 19:51:00 +02:00
Utility : : Error { } < < " Couldn't find unit data in " < < _filename ;
2021-08-28 20:21:13 +02:00
_state = State : : Invalid ;
2021-09-27 17:52:47 +02:00
return ;
2021-08-28 20:21:13 +02:00
}
2022-03-11 10:57:16 +01:00
auto name_prop = unit_data - > at < StringProperty > ( " Name_45_A037C5D54E53456407BDF091344529BB " _s ) ;
2021-06-11 19:24:52 +02:00
2021-10-04 18:18:53 +02:00
if ( ! name_prop ) {
2022-03-30 19:51:00 +02:00
Utility : : Error { } < < " Couldn't find a M.A.S.S. name in " < < _filename ;
2021-10-04 18:18:53 +02:00
_name = Containers : : NullOpt ;
_state = State : : Invalid ;
return ;
2021-10-02 14:52:48 +02:00
}
2021-06-11 19:24:52 +02:00
2022-03-04 21:18:55 +01:00
_name = { name_prop - > value } ;
2021-10-02 19:23:35 +02:00
2021-10-04 18:18:53 +02:00
getJointSliders ( ) ;
if ( _state = = State : : Invalid ) {
return ;
2021-06-11 19:24:52 +02:00
}
2021-10-02 14:52:48 +02:00
2021-10-04 18:18:53 +02:00
getFrameStyles ( ) ;
if ( _state = = State : : Invalid ) {
return ;
2021-10-02 14:52:48 +02:00
}
2021-10-03 16:32:47 +02:00
2021-10-04 18:18:53 +02:00
getEyeFlareColour ( ) ;
if ( _state = = State : : Invalid ) {
return ;
2021-10-03 16:32:47 +02:00
}
2021-10-02 19:23:35 +02:00
2021-10-04 18:18:53 +02:00
getFrameCustomStyles ( ) ;
if ( _state = = State : : Invalid ) {
return ;
}
2021-10-02 14:52:48 +02:00
2021-10-04 18:18:53 +02:00
getArmourParts ( ) ;
if ( _state = = State : : Invalid ) {
return ;
}
2021-10-02 14:52:48 +02:00
2022-03-12 09:34:19 +01:00
getBulletLauncherAttachments ( ) ;
if ( _state = = State : : Invalid ) {
return ;
}
2021-10-04 18:18:53 +02:00
getArmourCustomStyles ( ) ;
if ( _state = = State : : Invalid ) {
return ;
2021-10-02 14:52:48 +02:00
}
2021-10-17 08:37:12 +02:00
getMeleeWeapons ( ) ;
if ( _state = = State : : Invalid ) {
return ;
}
getShields ( ) ;
if ( _state = = State : : Invalid ) {
return ;
}
getBulletShooters ( ) ;
if ( _state = = State : : Invalid ) {
return ;
}
getEnergyShooters ( ) ;
if ( _state = = State : : Invalid ) {
return ;
}
getBulletLaunchers ( ) ;
if ( _state = = State : : Invalid ) {
return ;
}
getEnergyLaunchers ( ) ;
if ( _state = = State : : Invalid ) {
return ;
}
2021-10-02 14:52:48 +02:00
2022-02-17 20:01:59 +01:00
getGlobalStyles ( ) ;
if ( _state = = State : : Invalid ) {
return ;
2021-10-02 14:52:48 +02:00
}
2021-12-02 15:27:00 +01:00
getTuning ( ) ;
if ( _state = = State : : Invalid ) {
return ;
}
2021-06-11 19:24:52 +02:00
2022-03-11 10:57:16 +01:00
auto account_prop = _mass - > at < StringProperty > ( " Account " _s ) ;
2021-09-27 17:52:47 +02:00
if ( ! account_prop ) {
2022-03-30 19:51:00 +02:00
Utility : : Error { } < < " Couldn't find an account ID in " < < _filename ;
2021-09-27 17:52:47 +02:00
_state = State : : Invalid ;
return ;
2021-06-11 19:24:52 +02:00
}
2022-02-09 20:16:14 +01:00
_account = account_prop - > value ;
2021-06-11 19:24:52 +02:00
2022-03-30 19:51:00 +02:00
guard . release ( ) ;
guard = Containers : : ScopeGuard { [ ] { Utility : : Debug { } < < " Refresh successful. " ; } } ;
2021-09-27 17:52:47 +02:00
_state = State : : Valid ;
2021-06-11 19:24:52 +02:00
}
2021-08-28 20:20:09 +02:00
2022-03-04 21:18:55 +01:00
auto Mass : : filename ( ) - > Containers : : StringView {
2021-09-27 17:52:47 +02:00
return _filename ;
}
2021-08-28 20:20:09 +02:00
2022-03-04 21:18:55 +01:00
auto Mass : : name ( ) - > Containers : : StringView {
return * _name ;
2021-09-27 17:52:47 +02:00
}
2021-08-28 20:20:09 +02:00
2022-03-04 21:18:55 +01:00
auto Mass : : setName ( Containers : : StringView new_name ) - > bool {
_name = { new_name } ;
2021-08-28 20:20:09 +02:00
2022-03-04 21:18:55 +01:00
auto unit_data = _mass - > at < GenericStructProperty > ( " UnitData " _s ) ;
2021-08-28 20:20:09 +02:00
2021-09-27 17:52:47 +02:00
if ( ! unit_data ) {
_state = State : : Invalid ;
return false ;
2021-08-28 20:20:09 +02:00
}
2021-09-27 17:52:47 +02:00
2022-03-04 21:18:55 +01:00
auto name_prop = unit_data - > at < StringProperty > ( " Name_45_A037C5D54E53456407BDF091344529BB " _s ) ;
2021-09-27 17:52:47 +02:00
if ( ! name_prop ) {
2021-08-28 20:20:09 +02:00
_state = State : : Invalid ;
2021-09-27 17:52:47 +02:00
return false ;
2021-08-28 20:20:09 +02:00
}
2021-09-27 17:52:47 +02:00
2022-03-04 21:18:55 +01:00
name_prop - > value = new_name ;
2021-09-27 17:52:47 +02:00
2022-03-04 21:18:55 +01:00
if ( ! _mass - > saveToFile ( ) ) {
_lastError = _mass - > lastError ( ) ;
return false ;
}
return true ;
2021-09-27 17:52:47 +02:00
}
auto Mass : : state ( ) - > State {
return _state ;
2021-08-28 20:20:09 +02:00
}
2021-09-27 17:52:47 +02:00
auto Mass : : dirty ( ) const - > bool {
return _dirty ;
}
2021-09-10 16:13:29 +02:00
2021-09-27 17:52:47 +02:00
void Mass : : setDirty ( bool dirty ) {
_dirty = dirty ;
}
2021-09-10 16:13:29 +02:00
2021-12-02 15:27:00 +01:00
void Mass : : getTuning ( ) {
2022-03-04 21:18:55 +01:00
getTuningCategory ( " Engine " _s , _tuning . engineId , " Gears " _s , _tuning . gearIds ) ;
2021-12-02 15:27:00 +01:00
if ( _state = = State : : Invalid ) {
return ;
}
2022-03-04 21:18:55 +01:00
getTuningCategory ( " OS " _s , _tuning . osId , " Modules " _s , _tuning . moduleIds ) ;
2021-12-02 15:27:00 +01:00
if ( _state = = State : : Invalid ) {
return ;
}
2022-03-04 21:18:55 +01:00
getTuningCategory ( " Architect " _s , _tuning . archId , " Techs " _s , _tuning . techIds ) ;
2021-12-02 15:27:00 +01:00
if ( _state = = State : : Invalid ) {
return ;
}
}
auto Mass : : engine ( ) - > Int & {
return _tuning . engineId ;
}
auto Mass : : gears ( ) - > Containers : : ArrayView < Int > {
return _tuning . gearIds ;
}
auto Mass : : os ( ) - > Int & {
return _tuning . osId ;
}
auto Mass : : modules ( ) - > Containers : : ArrayView < Int > {
return _tuning . moduleIds ;
}
auto Mass : : architecture ( ) - > Int & {
return _tuning . archId ;
}
auto Mass : : techs ( ) - > Containers : : ArrayView < Int > {
return _tuning . techIds ;
}
2022-03-04 21:18:55 +01:00
auto Mass : : account ( ) - > Containers : : StringView {
2022-02-17 20:01:59 +01:00
return _account ;
}
2022-03-04 21:18:55 +01:00
auto Mass : : updateAccount ( Containers : : StringView new_account ) - > bool {
2022-02-09 20:16:14 +01:00
_account = new_account ;
2021-08-28 20:20:09 +02:00
2022-03-04 21:18:55 +01:00
auto account = _mass - > at < StringProperty > ( " Account " _s ) ;
2021-10-14 15:06:03 +02:00
if ( ! account ) {
2021-08-28 20:20:09 +02:00
_state = State : : Invalid ;
2022-03-04 21:18:55 +01:00
_lastError = " Couldn't find the account property. " _s ;
2021-09-27 17:52:47 +02:00
return false ;
2021-08-28 20:20:09 +02:00
}
2021-09-27 17:52:47 +02:00
2022-02-09 20:16:14 +01:00
account - > value = new_account ;
2021-09-27 17:52:47 +02:00
2022-02-26 14:48:45 +01:00
if ( ! _mass - > saveToFile ( ) ) {
_lastError = _mass - > lastError ( ) ;
return false ;
}
return true ;
2021-08-28 20:20:09 +02:00
}
2021-10-02 14:52:48 +02:00
2022-03-04 21:18:55 +01:00
void Mass : : getTuningCategory ( Containers : : StringView big_node_prop_name , Int & big_node_id ,
Containers : : StringView small_nodes_prop_name , Containers : : ArrayView < Int > small_nodes_ids )
2021-12-02 15:27:00 +01:00
{
auto node_id = _mass - > at < IntProperty > ( big_node_prop_name ) ;
if ( ! node_id ) {
2022-03-30 19:51:00 +02:00
Utility : : Error { } < < " Couldn't find " < < big_node_prop_name < < " in " < < _filename ;
2021-12-02 15:27:00 +01:00
_state = State : : Invalid ;
return ;
}
big_node_id = node_id - > value ;
auto node_ids = _mass - > at < ArrayProperty > ( small_nodes_prop_name ) ;
if ( ! node_ids ) {
2022-03-30 19:51:00 +02:00
Utility : : Error { } < < " Couldn't find " < < small_nodes_prop_name < < " in " < < _filename ;
2021-12-02 15:27:00 +01:00
_state = State : : Invalid ;
return ;
}
if ( node_ids - > items . size ( ) ! = small_nodes_ids . size ( ) ) {
2022-03-30 19:51:00 +02:00
Utility : : Error { } < < " Node ID arrays are not of the same size. Expected " < < small_nodes_ids . size ( ) < < Utility : : Debug : : nospace < < " , got " < < node_ids - > items . size ( ) < < " instead. " ;
2021-12-02 15:27:00 +01:00
_state = State : : Invalid ;
return ;
}
for ( UnsignedInt i = 0 ; i < small_nodes_ids . size ( ) ; i + + ) {
auto small_node_id = node_ids - > at < IntProperty > ( i ) ;
CORRADE_INTERNAL_ASSERT ( small_node_id ) ;
small_nodes_ids [ i ] = small_node_id - > value ;
}
}