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>
2022-03-09 11:04:19 +01:00
# include <Corrade/Utility/Format.h>
# include <Corrade/Utility/Path.h>
2021-06-11 19:24:52 +02:00
2022-11-21 09:49:01 +01:00
# include <SDL_messagebox.h>
2021-06-11 19:24:52 +02:00
2022-12-01 23:42:39 +01:00
# include "../Configuration/Configuration.h"
2022-11-21 09:49:01 +01:00
# include "../FontAwesome/IconsFontAwesome5.h"
2021-06-11 19:24:52 +02:00
# include "../Maps/LastMissionId.h"
# include "../Maps/StoryProgress.h"
2022-11-21 09:49:01 +01:00
# include "SaveTool.h"
2022-12-03 16:49:39 +01:00
void
SaveTool : : drawManager ( ) {
2021-06-11 19:24:52 +02:00
ImGui : : SetNextWindowPos ( { 0.0f , ImGui : : GetItemRectSize ( ) . y } , ImGuiCond_Always ) ;
2022-12-05 11:32:18 +01:00
ImGui : : SetNextWindowSize ( { float ( windowSize ( ) . x ( ) ) , float ( windowSize ( ) . y ( ) ) - ImGui : : GetItemRectSize ( ) . y } ,
2021-06-11 19:24:52 +02:00
ImGuiCond_Always ) ;
if ( ! ImGui : : Begin ( " ##MainWindow " , nullptr ,
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoBringToFrontOnFocus ) )
{
ImGui : : End ( ) ;
return ;
}
2022-02-23 21:59:00 +01:00
drawAlignedText ( " Current profile: %s (%s) " ,
2022-03-09 11:04:19 +01:00
_currentProfile - > companyName ( ) . data ( ) ,
2022-03-09 13:27:21 +01:00
_currentProfile - > isDemo ( ) ? " demo " : " full game " ) ;
2021-07-23 14:17:42 +02:00
ImGui : : SameLine ( ) ;
2021-08-19 14:31:17 +02:00
if ( ImGui : : Button ( ICON_FA_ARROW_LEFT " Back to profile manager " ) ) {
2021-07-23 14:17:42 +02:00
_currentProfile = nullptr ;
_massManager . reset ( ) ;
_fileWatcher . reset ( ) ;
_uiState = UiState : : ProfileManager ;
2021-06-11 19:24:52 +02:00
}
2021-06-21 00:28:16 +02:00
if ( ImGui : : BeginChild ( " ##ProfileInfo " ,
2022-11-25 10:33:55 +01:00
{ ImGui : : GetContentRegionAvail ( ) . x * 0.60f , 0.0f } ,
2021-06-20 23:48:23 +02:00
true , ImGuiWindowFlags_MenuBar ) )
{
if ( ImGui : : BeginMenuBar ( ) ) {
2021-06-21 00:28:16 +02:00
ImGui : : TextUnformatted ( " Profile information " ) ;
2021-06-20 23:48:23 +02:00
ImGui : : EndMenuBar ( ) ;
}
2021-06-21 00:28:16 +02:00
if ( ImGui : : BeginTabBar ( " ##ProfileTabBar " ) ) {
if ( ImGui : : BeginTabItem ( " General info " ) ) {
drawGeneralInfo ( ) ;
ImGui : : EndTabItem ( ) ;
}
2021-06-11 19:24:52 +02:00
2021-06-21 00:28:16 +02:00
if ( ImGui : : BeginTabItem ( " Research inventory " ) ) {
drawResearchInventory ( ) ;
ImGui : : EndTabItem ( ) ;
}
2021-06-11 19:24:52 +02:00
2021-06-21 00:28:16 +02:00
ImGui : : EndTabBar ( ) ;
2021-06-20 23:48:23 +02:00
}
}
ImGui : : EndChild ( ) ;
2021-06-11 19:24:52 +02:00
ImGui : : SameLine ( ) ;
2021-06-20 23:48:23 +02:00
if ( ImGui : : BeginChild ( " ##MASSManager " , { 0.0f , 0.0f } ,
true , ImGuiWindowFlags_MenuBar ) )
{
if ( ImGui : : BeginMenuBar ( ) ) {
ImGui : : TextUnformatted ( " M.A.S.S. management " ) ;
drawHelpMarker ( " To move, import, or export builds, drag-and-drop them. " ) ;
ImGui : : EndMenuBar ( ) ;
}
drawMassManager ( ) ;
}
ImGui : : EndChild ( ) ;
2021-06-11 19:24:52 +02:00
ImGui : : End ( ) ;
}
2022-12-03 16:49:39 +01:00
bool
SaveTool : : drawIntEditPopup ( int * value_to_edit , int max ) {
2021-06-11 19:24:52 +02:00
bool apply = false ;
if ( ImGui : : BeginPopup ( " int_edit " ) ) {
ImGui : : Text ( " Please enter a value between 0 and %i: " , max ) ;
ImGui : : AlignTextToFramePadding ( ) ;
drawHelpMarker ( " You can either drag the widget left or right to change the value, \n "
" or click on it while holding Ctrl to edit the value directly. " ) ;
ImGui : : SameLine ( ) ;
2021-10-12 16:53:19 +02:00
drawUnsafeWidget ( [ ] ( auto . . . args ) { return ImGui : : SliderInt ( " " , args . . . ) ; } ,
value_to_edit , 0 , max , " %d " , ImGuiSliderFlags_AlwaysClamp ) ;
2021-06-11 19:24:52 +02:00
ImGui : : SameLine ( ) ;
if ( drawUnsafeWidget ( [ ] { return ImGui : : Button ( " Apply " ) ; } ) ) {
apply = true ;
ImGui : : CloseCurrentPopup ( ) ;
}
ImGui : : EndPopup ( ) ;
}
return apply ;
}
2022-12-03 16:49:39 +01:00
bool
SaveTool : : drawRenamePopup ( Containers : : ArrayView < char > name_view ) {
2021-06-11 19:24:52 +02:00
bool apply = false ;
if ( ImGui : : BeginPopup ( " name_edit " ) ) {
ImGui : : TextUnformatted ( " Please enter a new name. Conditions: " ) ;
std : : size_t len = std : : strlen ( name_view . data ( ) ) ;
ImGui : : BulletText ( " Length between 6 and 32 characters included. %s " ,
( len > = 6 & & len < = 32 ) ? ICON_FA_CHECK : ICON_FA_TIMES ) ;
ImGui : : BulletText ( " Only A-Z, a-z, 0-9, -, and whitespaces. " ICON_FA_CHECK ) ;
ImGui : : BulletText ( " No whitespace at the beginning or end. %s " ,
( name_view [ 0 ] ! = ' ' & & name_view [ len - 1 ] ! = ' ' ) ? ICON_FA_CHECK : ICON_FA_TIMES ) ;
static auto callback = [ ] ( ImGuiInputTextCallbackData * data ) - > int {
if ( data - > EventChar < 256 & & std : : strchr ( " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789- " , char ( data - > EventChar ) ) ) {
return 0 ;
}
return 1 ;
} ;
drawUnsafeWidget ( [ ] ( auto . . . args ) { return ImGui : : InputText ( " " , args . . . ) ; } ,
name_view . data ( ) , name_view . size ( ) ,
ImGuiInputTextFlags_CallbackCharFilter ,
callback , nullptr ) ;
ImGui : : SameLine ( ) ;
2021-07-21 14:36:49 +02:00
GameState game_state = _gameState ;
2022-11-21 09:19:48 +01:00
if ( game_state ! = GameState : : NotRunning | |
! ( len > = 6 & & len < = 32 ) | |
2021-07-10 16:46:45 +02:00
! ( name_view [ 0 ] ! = ' ' & & name_view [ len - 1 ] ! = ' ' ) )
2021-06-11 19:24:52 +02:00
{
2022-03-11 09:20:24 +01:00
ImGui : : BeginDisabled ( ) ;
2021-06-11 19:24:52 +02:00
}
if ( ImGui : : Button ( " Apply " ) ) {
apply = true ;
ImGui : : CloseCurrentPopup ( ) ;
}
2022-11-21 09:19:48 +01:00
if ( game_state ! = GameState : : NotRunning | |
! ( len > = 6 & & len < = 32 ) | |
2021-07-10 16:46:45 +02:00
! ( name_view [ 0 ] ! = ' ' & & name_view [ len - 1 ] ! = ' ' ) )
2021-06-11 19:24:52 +02:00
{
2022-03-11 09:20:24 +01:00
ImGui : : EndDisabled ( ) ;
2021-06-11 19:24:52 +02:00
}
ImGui : : EndPopup ( ) ;
}
return apply ;
}
2022-12-03 16:49:39 +01:00
void
SaveTool : : drawGeneralInfo ( ) {
2021-06-11 19:24:52 +02:00
if ( ! _currentProfile ) {
return ;
}
ImGui : : Text ( " Credits: %i " , _currentProfile - > credits ( ) ) ;
auto it = std : : find_if ( story_progress . begin ( ) , story_progress . end ( ) ,
[ this ] ( const StoryProgressPoint & p ) { return p . id = = _currentProfile - > storyProgress ( ) ; } ) ;
if ( it ! = story_progress . end ( ) )
{
ImGui : : TextUnformatted ( " Story progress: " ) ;
ImGui : : SameLine ( 0.0f , ImGui : : GetStyle ( ) . ItemSpacing . x / 4.0f ) ;
2022-01-15 10:48:49 +01:00
if ( ! it - > after ) {
2022-03-06 14:30:04 +01:00
ImGui : : TextWrapped ( " %s - %s " , it - > chapter . data ( ) , it - > point . data ( ) ) ;
2021-06-11 19:24:52 +02:00
}
else {
2022-03-06 14:30:04 +01:00
ImGui : : TextWrapped ( " %s - %s - %s " , it - > chapter . data ( ) , it - > after . data ( ) , it - > point . data ( ) ) ;
2021-06-11 19:24:52 +02:00
}
}
else {
ImGui : : Text ( " Story progress: 0x%x " , _currentProfile - > storyProgress ( ) ) ;
}
if ( mission_id_map . find ( _currentProfile - > lastMissionId ( ) ) ! = mission_id_map . cend ( ) ) {
2022-03-06 14:30:04 +01:00
ImGui : : Text ( " Last mission: %s " , mission_id_map . at ( _currentProfile - > lastMissionId ( ) ) . data ( ) ) ;
2021-06-11 19:24:52 +02:00
}
else if ( _currentProfile - > lastMissionId ( ) = = - 1 ) {
ImGui : : TextUnformatted ( " Last mission: none " ) ;
}
else {
ImGui : : Text ( " Last mission: 0x%x " , _currentProfile - > lastMissionId ( ) ) ;
}
drawTooltip ( " This is the last mission selected in the mission selection screen, not the last mission played. " ,
2022-11-21 20:47:09 +01:00
float ( windowSize ( ) . x ( ) ) * 0.35f ) ;
2021-06-11 19:24:52 +02:00
2022-12-05 11:32:18 +01:00
const float footer_height_to_reserve = ImGui : : GetStyle ( ) . ItemSpacing . y + ImGui : : GetFrameHeightWithSpacing ( ) ;
2021-06-11 19:24:52 +02:00
ImGui : : Dummy ( { ImGui : : GetContentRegionAvail ( ) . x , ImGui : : GetContentRegionAvail ( ) . y - footer_height_to_reserve } ) ;
ImGui : : Separator ( ) ;
static Containers : : StaticArray < 33 , char > name_buf { ValueInit } ;
if ( drawUnsafeWidget ( [ ] { return ImGui : : Button ( " Rename company " ) ; } ) ) {
for ( auto & c : name_buf ) {
c = ' \0 ' ;
}
2022-03-04 21:18:55 +01:00
std : : strncpy ( name_buf . data ( ) , _currentProfile - > companyName ( ) . data ( ) , 32 ) ;
2021-06-11 19:24:52 +02:00
ImGui : : OpenPopup ( " name_edit " ) ;
}
if ( drawRenamePopup ( name_buf ) ) {
if ( ! _currentProfile - > renameCompany ( name_buf . data ( ) ) ) {
2022-02-24 14:00:47 +01:00
_queue . addToast ( Toast : : Type : : Error , _currentProfile - > lastError ( ) ) ;
2021-06-11 19:24:52 +02:00
}
}
2022-12-01 23:42:39 +01:00
if ( ! conf ( ) . cheatMode ( ) ) {
2021-07-28 15:00:15 +02:00
return ;
}
2021-06-11 19:24:52 +02:00
ImGui : : SameLine ( ) ;
2022-12-05 11:32:18 +01:00
static std : : int32_t credits ;
2021-06-11 19:24:52 +02:00
if ( drawUnsafeWidget ( [ ] { return ImGui : : Button ( " Edit credits " ) ; } ) ) {
credits = _currentProfile - > credits ( ) ;
ImGui : : OpenPopup ( " int_edit " ) ;
}
2021-07-10 16:47:18 +02:00
if ( drawIntEditPopup ( & credits , 20000000 ) ) {
2021-06-11 19:24:52 +02:00
if ( ! _currentProfile - > setCredits ( credits ) ) {
2022-02-24 14:00:47 +01:00
_queue . addToast ( Toast : : Type : : Error , _currentProfile - > lastError ( ) ) ;
2021-06-11 19:24:52 +02:00
}
}
ImGui : : SameLine ( ) ;
if ( drawUnsafeWidget ( [ ] { return ImGui : : Button ( " Change story progression " ) ; } ) ) {
ImGui : : OpenPopup ( " StoryProgressMenu " ) ;
}
drawTooltip ( " Story progress directly affects unlocked levels. " ) ;
if ( ImGui : : BeginPopup ( " StoryProgressMenu " ) ) {
2022-11-21 09:19:48 +01:00
if ( _gameState ! = GameState : : NotRunning ) {
2021-06-11 19:24:52 +02:00
ImGui : : CloseCurrentPopup ( ) ;
}
for ( const auto & sp : story_progress ) {
2022-03-04 21:18:55 +01:00
if ( ImGui : : BeginMenu ( sp . chapter . data ( ) ) ) {
2022-01-15 10:48:49 +01:00
if ( ! sp . after ) {
2022-03-04 21:18:55 +01:00
if ( ImGui : : MenuItem ( sp . point . data ( ) ) ) {
2021-06-11 19:24:52 +02:00
if ( ! _currentProfile - > setStoryProgress ( sp . id ) ) {
2022-02-24 14:00:47 +01:00
_queue . addToast ( Toast : : Type : : Error , _currentProfile - > lastError ( ) ) ;
2021-06-11 19:24:52 +02:00
}
}
}
else {
2022-03-04 21:18:55 +01:00
if ( ImGui : : BeginMenu ( sp . after . data ( ) ) ) {
if ( ImGui : : MenuItem ( sp . point . data ( ) ) ) {
2021-06-11 19:24:52 +02:00
if ( ! _currentProfile - > setStoryProgress ( sp . id ) ) {
2022-02-24 14:00:47 +01:00
_queue . addToast ( Toast : : Type : : Error , _currentProfile - > lastError ( ) ) ;
2021-06-11 19:24:52 +02:00
}
}
ImGui : : EndMenu ( ) ;
}
}
ImGui : : EndMenu ( ) ;
}
}
ImGui : : EndPopup ( ) ;
}
}
2022-12-03 16:49:39 +01:00
void
SaveTool : : drawResearchInventory ( ) {
2021-06-11 19:24:52 +02:00
if ( ! _currentProfile ) {
return ;
}
2021-08-18 15:37:03 +02:00
if ( ImGui : : BeginTable ( " ##ResearchInventoryTable " , 4 ,
2021-08-19 14:02:21 +02:00
ImGuiTableFlags_BordersOuter | ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersInnerH ) )
2021-06-11 19:24:52 +02:00
{
2021-08-18 15:37:03 +02:00
ImGui : : TableSetupColumn ( " ##Tier " , ImGuiTableColumnFlags_WidthFixed ) ;
2021-06-11 19:24:52 +02:00
ImGui : : TableSetupColumn ( " ##Name " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " ##Value " , ImGuiTableColumnFlags_WidthStretch ) ;
ImGui : : TableSetupColumn ( " ##Edit " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableNextRow ( ImGuiTableRowFlags_Headers ) ;
2021-08-18 15:37:03 +02:00
ImGui : : TableSetColumnIndex ( 1 ) ;
2021-06-11 19:24:52 +02:00
ImGui : : Text ( " Engine materials " ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Verse steel " , 1 ,
[ this ] { return _currentProfile - > verseSteel ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setVerseSteel ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Undinium " , 2 ,
[ this ] { return _currentProfile - > undinium ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setUndinium ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Necrium alloy " , 3 ,
[ this ] { return _currentProfile - > necriumAlloy ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setNecriumAlloy ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Lunarite " , 4 ,
[ this ] { return _currentProfile - > lunarite ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setLunarite ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Asterite " , 5 ,
[ this ] { return _currentProfile - > asterite ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setAsterite ( amount ) ; } ) ;
2022-11-25 16:25:56 +01:00
drawMaterialRow ( " Hallite fragma " , 6 ,
[ this ] { return _currentProfile - > halliteFragma ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setHalliteFragma ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawUnavailableMaterialRow ( " Unnoctinium " , 7 ) ;
2021-06-11 19:24:52 +02:00
ImGui : : TableNextRow ( ImGuiTableRowFlags_Headers ) ;
2021-08-18 15:37:03 +02:00
ImGui : : TableSetColumnIndex ( 1 ) ;
2021-06-11 19:24:52 +02:00
ImGui : : Text ( " OS materials " ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Ednil " , 1 ,
[ this ] { return _currentProfile - > ednil ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setEdnil ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Nuflalt " , 2 ,
[ this ] { return _currentProfile - > nuflalt ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setNuflalt ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Aurelene " , 3 ,
[ this ] { return _currentProfile - > aurelene ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setAurelene ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Soldus " , 4 ,
[ this ] { return _currentProfile - > soldus ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setSoldus ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Synthesized N " , 5 ,
[ this ] { return _currentProfile - > synthesisedN ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setSynthesisedN ( amount ) ; } ) ;
2022-11-25 16:25:56 +01:00
drawMaterialRow ( " Nanoc " , 6 ,
[ this ] { return _currentProfile - > nanoc ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setNanoc ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawUnavailableMaterialRow ( " Abyssillite " , 7 ) ;
2021-06-11 19:24:52 +02:00
ImGui : : TableNextRow ( ImGuiTableRowFlags_Headers ) ;
2021-08-18 15:37:03 +02:00
ImGui : : TableSetColumnIndex ( 1 ) ;
2021-06-11 19:24:52 +02:00
ImGui : : Text ( " Architect materials " ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Alcarbonite " , 1 ,
[ this ] { return _currentProfile - > alcarbonite ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setAlcarbonite ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Keripehene " , 2 ,
[ this ] { return _currentProfile - > keriphene ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setKeriphene ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Nitinol-CM " , 3 ,
[ this ] { return _currentProfile - > nitinolCM ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setNitinolCM ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Quarkium " , 4 ,
[ this ] { return _currentProfile - > quarkium ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setQuarkium ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Alterene " , 5 ,
[ this ] { return _currentProfile - > alterene ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setAlterene ( amount ) ; } ) ;
2022-11-25 16:25:56 +01:00
drawMaterialRow ( " Cosmium " , 6 ,
[ this ] { return _currentProfile - > cosmium ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setCosmium ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawUnavailableMaterialRow ( " Purified quarkium " , 7 ) ;
2021-06-11 19:24:52 +02:00
ImGui : : TableNextRow ( ImGuiTableRowFlags_Headers ) ;
2021-08-18 15:37:03 +02:00
ImGui : : TableSetColumnIndex ( 1 ) ;
2021-06-11 19:24:52 +02:00
ImGui : : Text ( " Quark data " ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Mixed composition " , 1 ,
[ this ] { return _currentProfile - > mixedComposition ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setMixedComposition ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Void residue " , 2 ,
[ this ] { return _currentProfile - > voidResidue ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setVoidResidue ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Muscular construction " , 3 ,
[ this ] { return _currentProfile - > muscularConstruction ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setMuscularConstruction ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Mineral exoskeletology " , 4 ,
[ this ] { return _currentProfile - > mineralExoskeletology ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setMineralExoskeletology ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawMaterialRow ( " Carbonized skin " , 5 ,
[ this ] { return _currentProfile - > carbonisedSkin ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setCarbonisedSkin ( amount ) ; } ) ;
2022-11-25 16:25:56 +01:00
drawMaterialRow ( " Isolated void particle " , 6 ,
[ this ] { return _currentProfile - > isolatedVoidParticle ( ) ; } ,
2022-12-05 11:32:18 +01:00
[ this ] ( std : : int32_t amount ) { return _currentProfile - > setIsolatedVoidParticle ( amount ) ; } ) ;
2022-03-02 11:46:31 +01:00
drawUnavailableMaterialRow ( " Weaponised physiology " , 7 ) ;
2021-06-11 19:24:52 +02:00
ImGui : : EndTable ( ) ;
}
2022-03-02 11:46:31 +01:00
}
template < typename Getter , typename Setter >
2022-12-03 16:49:39 +01:00
void
2022-12-05 11:32:18 +01:00
SaveTool : : drawMaterialRow ( Containers : : StringView name , std : : int32_t tier , Getter getter , Setter setter ) {
static_assert ( std : : is_same < decltype ( getter ( ) ) , std : : int32_t > : : value , " getter doesn't return an std::int32_t, and/or doesn't take zero arguments. " ) ;
static_assert ( std : : is_same < decltype ( setter ( 0 ) ) , bool > : : value , " setter doesn't return a bool, and/or doesn't take a single std::int32_t as an argument. " ) ;
2022-03-02 11:46:31 +01:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableSetColumnIndex ( 0 ) ;
ImGui : : Text ( " T%i " , tier ) ;
ImGui : : TableSetColumnIndex ( 1 ) ;
2022-03-04 21:18:55 +01:00
ImGui : : TextUnformatted ( name . data ( ) ) ;
2022-03-02 11:46:31 +01:00
ImGui : : TableSetColumnIndex ( 2 ) ;
if ( getter ( ) ! = - 1 ) {
ImGui : : Text ( " %i " , getter ( ) ) ;
2022-12-01 23:42:39 +01:00
if ( conf ( ) . cheatMode ( ) ) {
2022-03-02 11:46:31 +01:00
ImGui : : TableSetColumnIndex ( 3 ) ;
2022-03-04 21:18:55 +01:00
ImGui : : PushID ( name . data ( ) ) ;
2022-12-05 11:32:18 +01:00
static std : : int32_t var = 0 ;
2022-03-02 11:46:31 +01:00
if ( drawUnsafeWidget ( ImGui : : SmallButton , ICON_FA_EDIT ) ) {
( var ) = getter ( ) ;
ImGui : : OpenPopup ( " int_edit " ) ;
}
2022-03-20 09:14:46 +01:00
drawTooltip ( " Edit " ) ;
2022-03-02 11:46:31 +01:00
if ( drawIntEditPopup ( & ( var ) , 9999 ) ) {
if ( ! setter ( var ) ) {
_queue . addToast ( Toast : : Type : : Error , _currentProfile - > lastError ( ) ) ;
}
}
ImGui : : PopID ( ) ;
}
}
else {
ImGui : : TextDisabled ( " Not found in the save file " ) ;
}
}
2021-06-11 19:24:52 +02:00
2022-12-03 16:49:39 +01:00
void
2022-12-05 11:32:18 +01:00
SaveTool : : drawUnavailableMaterialRow ( Containers : : StringView name , std : : int32_t tier ) {
2022-03-02 11:46:31 +01:00
ImGui : : TableNextRow ( ) ;
ImGui : : TableSetColumnIndex ( 0 ) ;
ImGui : : Text ( " T%i " , tier ) ;
ImGui : : TableSetColumnIndex ( 1 ) ;
2022-12-05 11:50:28 +01:00
ImGui : : TextUnformatted ( name . begin ( ) , name . end ( ) ) ;
2022-03-02 11:46:31 +01:00
ImGui : : TableSetColumnIndex ( 2 ) ;
ImGui : : TextDisabled ( " Unavailable as of game version " SUPPORTED_GAME_VERSION ) ;
2021-06-11 19:24:52 +02:00
}
2022-12-03 16:49:39 +01:00
void
SaveTool : : drawMassManager ( ) {
2021-06-11 19:24:52 +02:00
if ( ! _massManager ) {
return ;
}
static int mass_to_delete = 0 ;
static ImGuiID mass_deletion_popup_ID = drawDeleteMassPopup ( mass_to_delete ) ;
if ( ImGui : : BeginTable ( " ##HangarsTable " , 4 ,
ImGuiTableFlags_BordersOuter | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY ,
{ 0.0f , ImGui : : GetContentRegionAvail ( ) . y * 0.45f } ) )
{
ImGui : : TableSetupColumn ( " ##Hangar " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupColumn ( " ##MASSName " , ImGuiTableColumnFlags_WidthStretch ) ;
ImGui : : TableSetupColumn ( " ##Active " , ImGuiTableColumnFlags_WidthFixed ) ;
2022-01-14 13:42:09 +01:00
ImGui : : TableSetupColumn ( " ##Buttons " , ImGuiTableColumnFlags_WidthFixed ) ;
2021-06-11 19:24:52 +02:00
ImGui : : TableSetupScrollFreeze ( 0 , 1 ) ;
ImGui : : TableNextRow ( ImGuiTableRowFlags_Headers ) ;
ImGui : : TableSetColumnIndex ( 0 ) ;
ImGui : : TextUnformatted ( " # " ) ;
ImGui : : TableSetColumnIndex ( 1 ) ;
ImGui : : TextUnformatted ( " Name " ) ;
for ( int i = 0 ; i < 32 ; i + + ) {
ImGui : : TableNextRow ( ) ;
static int drag_drop_index = 0 ;
ImGui : : TableSetColumnIndex ( 0 ) ;
2022-03-09 11:04:19 +01:00
ImGui : : Selectable ( Utility : : format ( " {:.2d} " , i + 1 ) . data ( ) ,
2021-06-11 19:24:52 +02:00
false , ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap ) ;
2021-08-29 19:39:29 +02:00
if ( _massManager - > hangar ( i ) . state ( ) = = Mass : : State : : Valid & &
2021-06-11 19:24:52 +02:00
ImGui : : BeginDragDropSource ( ImGuiDragDropFlags_SourceNoHoldToOpenOthers ) )
{
drag_drop_index = i ;
ImGui : : SetDragDropPayload ( " Mass " , & drag_drop_index , sizeof ( int ) ) ;
2022-03-04 21:18:55 +01:00
ImGui : : Text ( " %s - Hangar %.2d " , _massManager - > hangar ( i ) . name ( ) . data ( ) , i + 1 ) ;
2021-06-11 19:24:52 +02:00
ImGui : : EndDragDropSource ( ) ;
}
2022-11-21 09:19:48 +01:00
if ( _gameState = = GameState : : NotRunning & & ImGui : : BeginDragDropTarget ( ) ) {
2021-06-11 19:24:52 +02:00
if ( const ImGuiPayload * payload = ImGui : : AcceptDragDropPayload ( " StagedMass " ) ) {
2022-03-21 16:31:29 +01:00
if ( payload - > DataSize ! = sizeof ( Containers : : String ) ) {
2021-06-11 19:24:52 +02:00
SDL_ShowSimpleMessageBox ( SDL_MESSAGEBOX_ERROR , " Fatal error " ,
2022-03-21 16:31:29 +01:00
" payload->DataSize != sizeof(Containers::String) in SaveTool::drawMassManager() " ,
2021-06-11 19:24:52 +02:00
window ( ) ) ;
exit ( EXIT_FAILURE ) ;
}
2022-03-21 16:31:29 +01:00
Containers : : StringView file = * static_cast < Containers : : String * > ( payload - > Data ) ;
2021-06-11 19:24:52 +02:00
if ( ! _massManager - > importMass ( file , i ) ) {
2022-02-26 14:48:45 +01:00
_queue . addToast ( Toast : : Type : : Error , _massManager - > lastError ( ) ) ;
2021-06-11 19:24:52 +02:00
}
}
2022-02-24 14:00:47 +01:00
else if ( ( payload = ImGui : : AcceptDragDropPayload ( " Mass " ) ) ) {
2021-06-11 19:24:52 +02:00
if ( payload - > DataSize ! = sizeof ( int ) ) {
SDL_ShowSimpleMessageBox ( SDL_MESSAGEBOX_ERROR , " Fatal error " ,
" payload->DataSize != sizeof(int) in SaveTool::drawMassManager() " ,
window ( ) ) ;
exit ( EXIT_FAILURE ) ;
}
int index = * ( static_cast < int * > ( payload - > Data ) ) ;
if ( ! _massManager - > moveMass ( index , i ) ) {
2022-02-26 14:48:45 +01:00
_queue . addToast ( Toast : : Type : : Error , _massManager - > lastError ( ) ) ;
2021-06-11 19:24:52 +02:00
}
}
ImGui : : EndDragDropTarget ( ) ;
}
ImGui : : TableSetColumnIndex ( 1 ) ;
2021-08-19 20:33:59 +02:00
switch ( _massManager - > hangar ( i ) . state ( ) ) {
2021-08-29 19:39:29 +02:00
case Mass : : State : : Empty :
2021-08-19 14:11:18 +02:00
ImGui : : TextDisabled ( " <empty> " ) ;
2021-06-11 19:24:52 +02:00
break ;
2021-08-29 19:39:29 +02:00
case Mass : : State : : Invalid :
2021-08-19 14:11:18 +02:00
ImGui : : TextDisabled ( " <invalid> " ) ;
2021-06-11 19:24:52 +02:00
break ;
2021-08-29 19:39:29 +02:00
case Mass : : State : : Valid :
2022-03-04 21:18:55 +01:00
ImGui : : TextUnformatted ( _massManager - > hangar ( i ) . name ( ) . data ( ) ) ;
2021-06-11 19:24:52 +02:00
break ;
}
if ( i = = _currentProfile - > activeFrameSlot ( ) ) {
ImGui : : TableSetColumnIndex ( 2 ) ;
ImGui : : TextUnformatted ( ICON_FA_CHECK ) ;
2021-08-19 14:11:18 +02:00
drawTooltip ( " This is the currently active frame slot. " ) ;
2021-06-11 19:24:52 +02:00
}
2021-08-29 19:39:29 +02:00
if ( _massManager - > hangar ( i ) . state ( ) ! = Mass : : State : : Empty ) {
2021-06-11 19:24:52 +02:00
ImGui : : TableSetColumnIndex ( 3 ) ;
ImGui : : PushID ( i ) ;
2021-08-29 19:39:29 +02:00
if ( _massManager - > hangar ( i ) . state ( ) = = Mass : : State : : Valid ) {
2021-08-19 20:35:00 +02:00
if ( ImGui : : SmallButton ( ICON_FA_SEARCH ) ) {
_currentMass = & _massManager - > hangar ( i ) ;
_uiState = UiState : : MassViewer ;
}
2022-03-20 09:14:46 +01:00
drawTooltip ( " Open in M.A.S.S. editor " ) ;
2021-08-19 20:35:00 +02:00
}
2022-01-14 13:42:09 +01:00
else {
ImGui : : PushStyleVar ( ImGuiStyleVar_Alpha , 0.0f ) ;
ImGui : : SmallButton ( ICON_FA_SEARCH ) ;
ImGui : : PopStyleVar ( ) ;
}
2022-03-20 09:14:46 +01:00
ImGui : : SameLine ( 0.0f , 2.0f ) ;
2021-06-11 19:24:52 +02:00
if ( drawUnsafeWidget ( ImGui : : SmallButton , ICON_FA_TRASH_ALT ) ) {
mass_to_delete = i ;
ImGui : : OpenPopup ( mass_deletion_popup_ID ) ;
}
2022-03-20 09:14:46 +01:00
drawTooltip ( " Delete " ) ;
2021-06-11 19:24:52 +02:00
ImGui : : PopID ( ) ;
}
}
ImGui : : EndTable ( ) ;
}
drawDeleteMassPopup ( mass_to_delete ) ;
static ImGuiID staged_mass_deletion_popup_ID = drawDeleteStagedMassPopup ( " " ) ;
2022-03-04 21:18:55 +01:00
static Containers : : StringView staged_mass_to_delete ;
2021-06-11 19:24:52 +02:00
if ( ImGui : : BeginTable ( " ##StagingArea " , 2 ,
ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_RowBg ) )
{
ImGui : : TableSetupColumn ( " ##NameColumn " , ImGuiTableColumnFlags_WidthStretch ) ;
ImGui : : TableSetupColumn ( " ##DeleteColumn " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableSetupScrollFreeze ( 0 , 1 ) ;
ImGui : : TableNextRow ( ImGuiTableRowFlags_Headers ) ;
ImGui : : TableSetColumnIndex ( 0 ) ;
ImGui : : TextUnformatted ( " Staging area " ) ;
ImGui : : SameLine ( ) ;
if ( ImGui : : SmallButton ( ICON_FA_FOLDER_OPEN " Open staging folder " ) ) {
2022-03-09 11:04:19 +01:00
openUri ( Utility : : Path : : toNativeSeparators ( _stagingDir ) ) ;
2021-06-11 19:24:52 +02:00
}
for ( const auto & pair : _massManager - > stagedMasses ( ) ) {
ImGui : : TableNextRow ( ) ;
ImGui : : TableSetColumnIndex ( 0 ) ;
2022-03-09 11:04:19 +01:00
Containers : : String staged_formatted = Utility : : format ( " {} ({}) " , pair . second , pair . first ) ;
ImGui : : Selectable ( staged_formatted . data ( ) ) ;
2022-11-25 10:33:55 +01:00
if ( ( ImGui : : CalcTextSize ( staged_formatted . data ( ) ) . x + ImGui : : GetStyle ( ) . FramePadding . x ) > ImGui : : GetContentRegionAvail ( ) . x ) {
2022-03-09 11:04:19 +01:00
drawTooltip ( staged_formatted . data ( ) ) ;
2021-06-11 19:24:52 +02:00
}
if ( ImGui : : BeginDragDropSource ( ImGuiDragDropFlags_SourceNoHoldToOpenOthers ) ) {
2022-03-21 16:31:29 +01:00
ImGui : : SetDragDropPayload ( " StagedMass " , & ( pair . first ) , sizeof ( Containers : : String ) ) ;
2021-06-11 19:24:52 +02:00
2022-03-04 21:18:55 +01:00
ImGui : : Text ( " %s - Staged " , pair . second . data ( ) ) ;
2021-06-11 19:24:52 +02:00
ImGui : : EndDragDropSource ( ) ;
}
ImGui : : TableSetColumnIndex ( 1 ) ;
2022-03-04 21:18:55 +01:00
ImGui : : PushID ( pair . first . data ( ) ) ;
2021-06-11 19:24:52 +02:00
if ( ImGui : : SmallButton ( ICON_FA_TRASH_ALT ) ) {
2022-03-04 21:18:55 +01:00
staged_mass_to_delete = pair . first ;
2021-06-11 19:24:52 +02:00
ImGui : : OpenPopup ( staged_mass_deletion_popup_ID ) ;
}
2022-03-20 09:14:46 +01:00
drawTooltip ( " Delete " ) ;
2021-06-11 19:24:52 +02:00
ImGui : : PopID ( ) ;
}
ImGui : : EndTable ( ) ;
}
if ( ImGui : : BeginDragDropTarget ( ) ) {
if ( const ImGuiPayload * payload = ImGui : : AcceptDragDropPayload ( " Mass " ) ) {
if ( payload - > DataSize ! = sizeof ( int ) ) {
SDL_ShowSimpleMessageBox ( SDL_MESSAGEBOX_ERROR , " Fatal error " ,
" payload->DataSize != sizeof(int) in SaveTool::drawMassManager() " ,
window ( ) ) ;
exit ( EXIT_FAILURE ) ;
}
int index = * ( static_cast < int * > ( payload - > Data ) ) ;
if ( ! _massManager - > exportMass ( index ) ) {
2022-02-26 14:48:45 +01:00
_queue . addToast ( Toast : : Type : : Error , _massManager - > lastError ( ) ) ;
2021-06-11 19:24:52 +02:00
}
}
ImGui : : EndDragDropTarget ( ) ;
}
2022-03-04 21:18:55 +01:00
drawDeleteStagedMassPopup ( staged_mass_to_delete ) ;
2021-06-11 19:24:52 +02:00
}
2022-12-03 16:49:39 +01:00
ImGuiID
SaveTool : : drawDeleteMassPopup ( int mass_index ) {
2021-06-11 19:24:52 +02:00
if ( ! ImGui : : BeginPopupModal ( " Confirmation##DeleteMassConfirmation " , nullptr ,
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove ) )
{
return ImGui : : GetID ( " Confirmation##DeleteMassConfirmation " ) ;
}
2021-08-29 19:39:29 +02:00
if ( _massManager - > hangar ( mass_index ) . state ( ) = = Mass : : State : : Empty ) {
2021-06-11 19:24:52 +02:00
ImGui : : CloseCurrentPopup ( ) ;
ImGui : : EndPopup ( ) ;
return 0 ;
}
2021-07-21 14:36:49 +02:00
if ( _gameState ! = GameState : : NotRunning ) {
2021-06-11 19:24:52 +02:00
ImGui : : CloseCurrentPopup ( ) ;
ImGui : : EndPopup ( ) ;
return 0 ;
}
2022-11-21 20:47:09 +01:00
ImGui : : PushTextWrapPos ( float ( windowSize ( ) . x ( ) ) * 0.40f ) ;
2021-08-29 19:39:29 +02:00
if ( _massManager - > hangar ( mass_index ) . state ( ) = = Mass : : State : : Invalid ) {
2021-06-11 19:24:52 +02:00
ImGui : : Text ( " Are you sure you want to delete the invalid M.A.S.S. data in hangar %.2i ? This operation is irreversible. " ,
mass_index + 1 ) ;
}
else {
ImGui : : Text ( " Are you sure you want to delete the M.A.S.S. named %s in hangar %.2i ? This operation is irreversible. " ,
2022-03-04 21:18:55 +01:00
_massManager - > hangar ( mass_index ) . name ( ) . data ( ) , mass_index + 1 ) ;
2021-06-11 19:24:52 +02:00
}
ImGui : : PopTextWrapPos ( ) ;
if ( ImGui : : BeginTable ( " ##DeleteMassLayout " , 2 ) ) {
ImGui : : TableSetupColumn ( " ##Dummy " , ImGuiTableColumnFlags_WidthStretch ) ;
ImGui : : TableSetupColumn ( " ##YesNo " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableSetColumnIndex ( 1 ) ;
if ( ImGui : : Button ( " Yes " ) ) {
if ( ! _massManager - > deleteMass ( mass_index ) ) {
2022-02-26 14:48:45 +01:00
_queue . addToast ( Toast : : Type : : Error , _massManager - > lastError ( ) ) ;
2021-06-11 19:24:52 +02:00
}
ImGui : : CloseCurrentPopup ( ) ;
}
ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( " No " , ImGui : : GetItemRectSize ( ) ) ) {
ImGui : : CloseCurrentPopup ( ) ;
}
ImGui : : EndTable ( ) ;
}
ImGui : : EndPopup ( ) ;
return 0 ;
}
2022-12-03 16:49:39 +01:00
ImGuiID
SaveTool : : drawDeleteStagedMassPopup ( Containers : : StringView filename ) {
2021-06-11 19:24:52 +02:00
if ( ! ImGui : : BeginPopupModal ( " Confirmation##DeleteStagedMassConfirmation " , nullptr ,
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove ) )
{
return ImGui : : GetID ( " Confirmation##DeleteStagedMassConfirmation " ) ;
}
2022-11-21 20:47:09 +01:00
ImGui : : PushTextWrapPos ( float ( windowSize ( ) . x ( ) ) * 0.40f ) ;
2021-06-11 19:24:52 +02:00
ImGui : : Text ( " Are you sure you want to delete the staged M.A.S.S. named %s ? This operation is irreversible. " ,
2022-03-04 21:18:55 +01:00
_massManager - > stagedMasses ( ) . at ( filename ) . data ( ) ) ;
2021-06-11 19:24:52 +02:00
ImGui : : PopTextWrapPos ( ) ;
if ( ImGui : : BeginTable ( " ##DeleteStagedMassLayout " , 2 ) ) {
ImGui : : TableSetupColumn ( " ##Dummy " , ImGuiTableColumnFlags_WidthStretch ) ;
ImGui : : TableSetupColumn ( " ##YesNo " , ImGuiTableColumnFlags_WidthFixed ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableSetColumnIndex ( 1 ) ;
if ( ImGui : : Button ( " Yes " ) ) {
if ( ! _massManager - > deleteStagedMass ( filename ) ) {
2022-02-26 14:48:45 +01:00
_queue . addToast ( Toast : : Type : : Error , _massManager - > lastError ( ) ) ;
2021-06-11 19:24:52 +02:00
}
ImGui : : CloseCurrentPopup ( ) ;
}
ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( " No " , ImGui : : GetItemRectSize ( ) ) ) {
ImGui : : CloseCurrentPopup ( ) ;
}
ImGui : : EndTable ( ) ;
}
ImGui : : EndPopup ( ) ;
return 0 ;
}