Compare commits

...

29 Commits

Author SHA1 Message Date
prisixia 7f2dbf80fb
Remove unused function 2023-05-08 10:02:40 +02:00
prisixia 170278fbec
Cleanup CMakeLists
There were a few things such as a no longer required component and
mistakenly adding a not existing directory into the include directories.
2023-05-08 09:57:01 +02:00
prisixia e27e16d083
Get string from path in some functions
Some variables were missing that
2023-05-07 20:42:55 +02:00
prisixia 7380c8a7a0
clang-tidy: readability-qualified-auto 2023-05-07 11:04:10 +02:00
prisixia 06a472a358
Disable cppcoreguidelines-owning-memory
Due to how wxWidgets works, certain parts of it don't require owning the
memory and it's just recommend to use raw pointers instead.
2023-05-06 15:33:40 +02:00
prisixia 505e4ac4d1
clang-tidy: readability-braces-around-statements 2023-05-06 13:08:18 +02:00
prisixia aa6267c242
clang-tidy: performance-for-range-copy 2023-05-06 09:44:23 +02:00
prisixia bdcb18ad8e
Remove modernize-use-trailing-return-type 2023-05-05 20:37:58 +02:00
prisixia fdf1c4a9ee
clang-tidy: modernize-pass-by-value 2023-05-05 20:29:32 +02:00
prisixia a58c313bc9
Rephrase entry in file menu
"Import and append" can just be renamed to "Append" while still
conveying the same meaning.
2023-05-05 15:46:12 +02:00
prisixia 7d897c6081
clang-tidy: modernize-use-nodiscard 2023-05-05 15:43:14 +02:00
prisixia e50bb2bd80
clang-tidy: performance-unnecessary-value-param 2023-05-05 14:10:52 +02:00
prisixia 3324118cea
Add default constructor to Frames
Might be removed again at some point, but for now it's back so that the
program can compile again.
2023-05-04 20:36:16 +02:00
prisixia 8c7f47a3f9
Add cereal header to patch.h 2023-05-04 20:04:05 +02:00
prisixia a693430acb
Make CheckForErrors() clear log
It'd make sense for CheckForErrors() to clear the log itself to prevent
filling up the log with the same errors over and over again.
2023-05-04 19:29:13 +02:00
prisixia 48ab92ea6f
Adjust constructors a little 2023-05-04 15:34:47 +02:00
prisixia a112f790b3
Combine namespaces 2023-05-04 10:54:08 +02:00
prisixia 6a7d8c91cf
Add language to clang-format 2023-05-04 10:18:10 +02:00
prisixia b5ed32e7d5
Add clang-tidy 2023-05-04 10:17:31 +02:00
prisixia fa33186a37
Replace RapidJSON with cereal
This is a rather big change to pretty much everything here, including
some minor changes that were just required along the way. It's probably
by no means perfect, but this should work more or less for now, but
should be taken with a grain of salt.
2023-05-04 09:05:16 +02:00
prisixia 42c977b300
Update Metadata
It should match with its original structure.
2023-04-29 21:28:05 +02:00
prisixia c574e46a96
Remove cereal from thirdparty
On second thought;
Nevermind, the way it handles std::optional is just a big "No, thanks"
and was the reason why this program directly uses RapidJSON.
2023-04-29 20:46:10 +02:00
prisixia 535b074c96
Rename `requires` to `_requires`
`requires` is a keyword in C++20.
Despite this written in C++17 as of now, some editors and
linters may handle it like a keyword.

This adds to the commit from before.
2023-04-29 15:38:37 +02:00
prisixia 0e8e5294f4
Rename `requires` to `_requires`
`requires` is a keyword in C++20.
Despite this written in C++17 as of now, some editors and linters may handle it like a keyword.
2023-04-29 15:33:48 +02:00
prisixia d2e9bac40c
Add cereal to thirdparty 2023-04-29 13:54:51 +02:00
prisixia 3bf7f58e4e
Split up the GUI a little
Panels now have their own files for hopefully better readability.
2023-04-27 21:20:23 +02:00
prisixia b139b9e37a
Make list of source files a variable
Should make the CMakeLists file a bit more readable and maintainable.
2023-04-27 11:16:37 +02:00
prisixia 164f49c017
Update README
Development has been seemingly picked up again.
2023-04-26 14:47:34 +02:00
prisixia 9b143f99db
Copyright update 2023-04-26 14:42:24 +02:00
31 changed files with 2222 additions and 1775 deletions

View File

@ -1,4 +1,5 @@
---
Language: Cpp
BasedOnStyle: LLVM
IndentWidth: 4
TabWidth: 4

10
.clang-tidy Normal file
View File

@ -0,0 +1,10 @@
Checks: "bugprone-*,\
cert-*,\
clang-analyzer-*,\
cppcoreguidelines-*,\
llvm-*,\
misc-*,\
modernize-*,\
performance-*,\
readability-*,\
-modernize-use-trailing-return-type"

6
.gitmodules vendored
View File

@ -1,6 +1,6 @@
[submodule "thirdparty/magic_enum"]
path = thirdparty/magic_enum
url = https://github.com/Neargye/magic_enum
[submodule "thirdparty/rapidjson"]
path = thirdparty/rapidjson
url = https://github.com/Tencent/rapidjson
[submodule "thirdparty/cereal"]
path = thirdparty/cereal
url = https://github.com/USCiLab/cereal

View File

@ -9,41 +9,46 @@ if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
# For clang-tidy
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(SOURCE_LIST
"src/speciesgen.cpp"
"src/error.cpp"
"src/gui/main_panel.cpp"
"src/gui/stages_panel.cpp"
"src/starbound/metadata.cpp"
"src/starbound/item.cpp"
"src/starbound/frames.cpp"
"src/starpounds/weightstage.cpp"
"src/starpounds/species.cpp"
"src/starpounds/types.cpp"
)
if (NOT MSVC AND NOT WIN32)
add_executable(speciesgen
"src/speciesgen.cpp"
"src/error.cpp"
"src/starbound/metadata.cpp"
"src/starbound/item.cpp"
"src/starbound/patch.cpp"
"src/starbound/frames.cpp"
"src/starpounds/weightstage.cpp"
"src/starpounds/types.cpp"
${SOURCE_LIST}
)
else()
add_executable(speciesgen WIN32
"src/speciesgen.cpp"
"src/error.cpp"
"src/starbound/metadata.cpp"
"src/starbound/item.cpp"
"src/starbound/patch.cpp"
"src/starbound/frames.cpp"
"src/starpounds/weightstage.cpp"
"src/starpounds/types.cpp"
${SOURCE_LIST}
#"resources/resource.rc"
)
endif()
find_package(wxWidgets 3.1.5 REQUIRED COMPONENTS propgrid core base)
find_package(wxWidgets 3.1.5 REQUIRED COMPONENTS core base)
include(${wxWidgets_USE_FILE})
include_directories(speciesgen "include" "thirdparty/rapidjson/include" "thirdparty/magic_enum/include")
include_directories("include" "thirdparty/magic_enum/include" "thirdparty/cereal/include")
target_link_libraries(speciesgen PRIVATE ${wxWidgets_LIBRARIES})
add_definitions(-DSPECIESGEN_VERSION="${CMAKE_PROJECT_VERSION}")
if (NOT CMAKE_BUILD_TYPE EQUAL "DEBUG")
if (NOT CMAKE_BUILD_TYPE STREQUAL "DEBUG")
message(STATUS "Build type is RELEASE")
add_definitions(-DwxDEBUG_LEVEL=0 -D_ITERATOR_DEBUG_LEVEL=0)
else()
message(STATUS "Build type is DEBUG")
add_compile_options(-g -O0 -gdwarf-2)
endif()
if (CMAKE_VERSION VERSION_GREATER 3.12)

24
LICENSE.cereal Normal file
View File

@ -0,0 +1,24 @@
Copyright (c) 2013-2022, Randolph Voorhies, Shane Grant
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,57 +0,0 @@
Tencent is pleased to support the open source community by making RapidJSON available.
Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
If you have downloaded a copy of the RapidJSON binary from Tencent, please note that the RapidJSON binary is licensed under the MIT License.
If you have downloaded a copy of the RapidJSON source code from Tencent, please note that RapidJSON source code is licensed under the MIT License, except for the third-party components listed below which are subject to different license terms. Your integration of RapidJSON into your own projects may require compliance with the MIT License, as well as the other licenses applicable to the third-party components included within RapidJSON. To avoid the problematic JSON license in your own projects, it's sufficient to exclude the bin/jsonchecker/ directory, as it's the only code under the JSON license.
A copy of the MIT License is included in this file.
Other dependencies and licenses:
Open Source Software Licensed Under the BSD License:
--------------------------------------------------------------------
The msinttypes r29
Copyright (c) 2006-2013 Alexander Chemeris
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Open Source Software Licensed Under the JSON License:
--------------------------------------------------------------------
json.org
Copyright (c) 2002 JSON.org
All Rights Reserved.
JSON_checker
Copyright (c) 2002 JSON.org
All Rights Reserved.
Terms of the JSON License:
---------------------------------------------------
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Terms of the MIT License:
--------------------------------------------------------------------
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,10 +1,8 @@
<h1 align="center">speciesgen</h1>
# This version has been indefinitely put on hold in favor of the [Rust version](http://git.vern.cc/prisixia/speciesgen.rs).
## About
speciesgen is a tool to aid in the creation of mods to support modded species in the Starpounds mod for the game Starbound.
speciesgen is a tool to aid in the creation of mods to support modded species in the StarPounds mod for the game Starbound.
## Installation

View File

@ -1,6 +1,6 @@
/*
speciesgen
Copyright (C) 2022 prisixia
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
@ -23,8 +23,8 @@ along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
// Purpose: Implementation of ErrorHandler
// Author: prisixia
// Created: 2022-10-13
// Copyright: (c) 2022 prisixia
// License: GNU General Public License version 3
// Copyright: (C) 2022-2023 prisixia
// Licence: GNU General Public License version 3
/////////////////////////////////////////////////////////////////////////////
#ifndef SPECIESGEN_ERROR_H
@ -37,7 +37,7 @@ along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
namespace SpeciesGen {
class ErrorHandler {
public:
ErrorHandler(const std::string = "ErrorHandler");
ErrorHandler(std::string = "ErrorHandler");
virtual size_t CheckForErrors() = 0;
virtual std::string GetError(const size_t);
virtual void ClearErrors();

92
include/gui/main_panel.h Normal file
View File

@ -0,0 +1,92 @@
/*
speciesgen
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
speciesgen 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.
speciesgen 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 speciesgen. If not, see <https://www.gnu.org/licenses/>.
*/
/////////////////////////////////////////////////////////////////////////////
// Name: main_panel.cpp
// Purpose: Main panel, part of the GUI
// Author: prisixia
// Created: 2023-04-27
// Copyright: (C) 2022-2023 prisixia
// Licence: GNU General Public License version 3
/////////////////////////////////////////////////////////////////////////////
#ifndef SPECIESGEN_PANEL_MAIN_H
#define SPECIESGEN_PANEL_MAIN_H
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif // WX_PRECOMP
#if wxUSE_CLIPBOARD
#include <wx/clipbrd.h>
#include <wx/dataobj.h>
#endif // wxUSE_CLIPBOARD
#include <wx/dir.h>
#include <wx/stdpaths.h>
#include "error.h"
namespace SpeciesGen {
enum {
MOD_GENERATE,
DIR_CHOOSE
};
class MainPanel : public wxPanel, public ErrorHandler {
public:
MainPanel(wxWindow *, int, int, int, int, const std::string &);
#if wxUSE_CLIPBOARD
// bool HasSelection() const;
// void DoPasteFromClipboard();
// void DoCopyToClipboard();
#endif // wxUSE_CLIPBOARD
#if wxUSE_DIRDLG
void DoChooseDir(wxCommandEvent &WXUNUSED(event));
#endif // wxUSE_DIRDLG
virtual size_t CheckForErrors();
wxTextCtrl *m_author;
wxTextCtrl *m_name;
wxTextCtrl *m_friendlyName;
wxTextCtrl *m_modDestination;
wxButton *m_generate;
private:
#if wxUSE_CLIPBOARD
// wxTextCtrl *GetFocusedText() const;
#endif // wxUSE_CLIPBOARD
wxButton *m_browse;
wxStaticText *m_modDestinationText;
wxStaticText *m_authorText;
wxStaticText *m_nameText;
wxStaticText *m_friendlyNameText;
wxDECLARE_EVENT_TABLE();
};
} // namespace SpeciesGen
#endif // SPECIESGEN_PANEL_MAIN_H

143
include/gui/stages_panel.h Normal file
View File

@ -0,0 +1,143 @@
/*
speciesgen
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
speciesgen 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.
speciesgen 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 speciesgen. If not, see <https://www.gnu.org/licenses/>.
*/
/////////////////////////////////////////////////////////////////////////////
// Name: stages_panel.cpp
// Purpose: Stages panel, part of the GUI
// Author: prisixia
// Created: 2023-04-27
// Copyright: (C) 2022-2023 prisixia
// Licence: GNU General Public License version 3
/////////////////////////////////////////////////////////////////////////////
#ifndef SPECIESGEN_PANEL_STAGES_H
#define SPECIESGEN_PANEL_STAGES_H
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif // WX_PRECOMP
#if wxUSE_CLIPBOARD
#include <wx/clipbrd.h>
#include <wx/dataobj.h>
#endif // wxUSE_CLIPBOARD
#include "error.h"
#include "starpounds/types.h"
#include "starpounds/weightstage.h"
namespace SpeciesGen {
enum {
STAGES_ADD,
STAGES_REMOVE,
STAGES_SUB_ADD,
STAGES_SUB_REMOVE,
STAGES_SET_DEFAULT,
STAGES_ID,
STAGES_LIST,
STAGES_SUB_LIST,
STAGES_FRAMES,
STAGES_TYPE_CHEST,
STAGES_TYPE_LEG,
STAGES_TEXT_NAME,
STAGES_TEXT_FRIENDLYNAME,
STAGES_TEXT_DESCRIPTION_CHEST,
STAGES_TEXT_DESCRIPTION_LEG
};
class StagesPanel : public wxPanel, public ErrorHandler {
public:
StagesPanel(wxWindow *, int, int, int, int, const std::string &);
void DoAddWeightStage(Starpounds::WeightStage = Starpounds::WeightStage(
"new", "New", "Chest description.",
Starpounds::Types::Chests::Belly,
"Leg description.", Starpounds::Types::Legs::Legs,
false, true, {}));
void DoRemoveWeightStage();
void DoAddWeightStageSub(
Starpounds::WeightStageSub =
Starpounds::WeightStageSub("new", "New", "Chest description.",
Starpounds::Types::Chests::Belly));
void DoRemoveWeightStageSub();
void DoClickCheckboxID(const bool);
[[nodiscard]] std::vector<Starpounds::WeightStage> GetWeightStages() const;
void ClearWeightStages();
virtual size_t CheckForErrors();
void ClearForm();
wxButton *m_add;
wxButton *m_remove;
wxButton *m_subAdd;
wxButton *m_subRemove;
wxCheckBox *m_id;
private:
void EnableForm(const bool, const bool = true, const bool = false);
void PopulateForm(const Starpounds::WeightStage &);
void PopulateForm(const Starpounds::WeightStageSub &);
void DoResetWeightStages();
std::string GetInternalNameReplacement(const Starpounds::WeightStage &);
std::string GetInternalNameReplacement(const Starpounds::WeightStageSub &);
bool HasDuplicateInternalName(const std::string &, const bool);
bool HasDuplicateNoID();
void OnClickWeightStage(wxCommandEvent &);
void OnClickWeightStageSub(wxCommandEvent &);
void OnClickCheckboxFrames(wxCommandEvent &);
void OnSelectComboBoxChest(wxCommandEvent &);
void OnSelectComboBoxLeg(wxCommandEvent &);
void OnInternalNameEdit(wxCommandEvent &WXUNUSED(event));
void OnFriendlyNameEdit(wxCommandEvent &WXUNUSED(event));
void OnDescriptionChestEdit(wxCommandEvent &WXUNUSED(event));
void OnDescriptionLegEdit(wxCommandEvent &WXUNUSED(event));
void OnResetWeightStages(wxCommandEvent &WXUNUSED(event));
wxTextCtrl *m_name;
wxTextCtrl *m_friendlyName;
wxTextCtrl *m_descriptionChest;
wxTextCtrl *m_descriptionLeg;
wxChoice *m_typeChest;
wxChoice *m_typeLeg;
wxCheckBox *m_frames;
wxListBox *m_stagesList;
wxListBox *m_subStagesList;
wxButton *m_default;
wxStaticText *m_nameText;
wxStaticText *m_friendlyNameText;
wxStaticText *m_descriptionChestText;
wxStaticText *m_descriptionLegText;
wxStaticText *m_typeChestText;
wxStaticText *m_typeLegText;
wxStaticText *m_stagesListText;
wxStaticText *m_subStagesListText;
std::vector<Starpounds::WeightStage> m_stages;
wxDECLARE_EVENT_TABLE();
};
} // namespace SpeciesGen
#endif // SPECIESGEN_PANEL_STAGES_H

View File

@ -1,6 +1,6 @@
/*
speciesgen
Copyright (C) 2022 prisixia
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
@ -20,16 +20,22 @@ along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
/////////////////////////////////////////////////////////////////////////////
// Name: speciesgen.cpp
// Purpose: Generating species support mods for Starpounds
// Purpose: Generating species support mods for StarPounds
// Author: prisixia
// Created: 2022-02-13
// Copyright: (c) 2022 prisixia
// License: GNU General Public License version 3
// Copyright: (C) 2022-2023 prisixia
// Licence: GNU General Public License version 3
/////////////////////////////////////////////////////////////////////////////
#ifndef SPECIESGEN_H
#define SPECIESGEN_H
#define CEREAL_SERIALIZE_FUNCTION_NAME Serialise
#define CEREAL_LOAD_FUNCTION_NAME Load
#define CEREAL_SAVE_FUNCTION_NAME Save
#define CEREAL_LOAD_MINIMAL_FUNCTION_NAME LoadMinimal
#define CEREAL_SAVE_MINIMAL_FUNCTION_NAME SaveMinimal
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
@ -49,31 +55,31 @@ along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
#define wxUSE_CLIPBOARD 0
#endif // wxUSE_DRAG_AND_DROP
#include <wx/dir.h>
#include <wx/notebook.h>
#include <wx/propgrid/propgrid.h>
#include <wx/stdpaths.h>
#include <filesystem>
#include <fstream>
#include <optional>
#include "error.h"
#include "gui/main_panel.h"
#include "gui/stages_panel.h"
#include "starbound/frames.h"
#include "starbound/item.h"
#include "starbound/metadata.h"
#include "starbound/patch.h"
#include "starpounds/species.h"
#include "starpounds/weightstage.h"
#include "cereal/archives/json.hpp"
#include "magic_enum.hpp"
#include "rapidjson/istreamwrapper.h"
#include "rapidjson/ostreamwrapper.h"
#include "rapidjson/prettywriter.h"
#define SPECIESGEN_ABOUT_PAGE \
"This program generates mods to add support for\n" \
"modded species in Starpounds.\n\n" \
"Version " SPECIESGEN_VERSION "\n" \
"Copyright (c) 2022, prisixia" \
"Copyright (C) 2022-2023 prisixia" \
"\n" \
"GNU General Public License version 3" \
"\n" \
@ -86,10 +92,10 @@ along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
"\n" \
"wxWindows Library Licence, Version 3.1" \
"\n\n" \
"RapidJSON:\n" \
"Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip" \
"cereal:\n" \
"Copyright (c) 2013-2022, Randolph Voorhies, Shane Grant" \
"\n" \
"MIT License" \
"BSD 3-Clause License" \
"\n" \
"All rights reserved." \
"\n\n" \
@ -116,26 +122,6 @@ enum {
// TEXT_CLIPBOARD_PASTE,
// TEXT_CLIPBOARD_VETO,
MOD_GENERATE,
DIR_CHOOSE,
STAGES_ADD,
STAGES_REMOVE,
STAGES_SUB_ADD,
STAGES_SUB_REMOVE,
STAGES_SET_DEFAULT,
STAGES_ID,
STAGES_LIST,
STAGES_SUB_LIST,
STAGES_FRAMES,
STAGES_TYPE_CHEST,
STAGES_TYPE_LEG,
STAGES_TEXT_NAME,
STAGES_TEXT_FRIENDLYNAME,
STAGES_TEXT_DESCRIPTION_CHEST,
STAGES_TEXT_DESCRIPTION_LEG,
CONFIG_IMPORT = (1 << 0),
CONFIG_IMPORT_APPEND = (1 << 1),
CONFIG_EXPORT = (1 << 2)
@ -146,115 +132,6 @@ public:
bool OnInit() wxOVERRIDE;
};
class MainPanel : public wxPanel, public ErrorHandler {
public:
MainPanel(wxWindow *, int, int, int, int, const std::string);
#if wxUSE_CLIPBOARD
// bool HasSelection() const;
// void DoPasteFromClipboard();
// void DoCopyToClipboard();
#endif // wxUSE_CLIPBOARD
#if wxUSE_DIRDLG
void DoChooseDir(wxCommandEvent &WXUNUSED(event));
#endif // wxUSE_DIRDLG
virtual size_t CheckForErrors();
wxTextCtrl *m_author;
wxTextCtrl *m_name;
wxTextCtrl *m_friendlyName;
wxTextCtrl *m_modDestination;
wxButton *m_generate;
private:
#if wxUSE_CLIPBOARD
// wxTextCtrl *GetFocusedText() const;
#endif // wxUSE_CLIPBOARD
wxButton *m_browse;
wxStaticText *m_modDestinationText;
wxStaticText *m_authorText;
wxStaticText *m_nameText;
wxStaticText *m_friendlyNameText;
wxDECLARE_EVENT_TABLE();
};
class StagesPanel : public wxPanel, public ErrorHandler {
public:
StagesPanel(wxWindow *, int, int, int, int, const std::string);
void DoAddWeightStage(Starpounds::WeightStage = Starpounds::WeightStage(
"new", "New", "Chest description.",
Starpounds::Types::Chests::Belly,
"Leg description.", Starpounds::Types::Legs::Legs,
false, true, {}));
void DoRemoveWeightStage();
void DoAddWeightStageSub(
Starpounds::WeightStageSub =
Starpounds::WeightStageSub("new", "New", "Chest description.",
Starpounds::Types::Chests::Belly));
void DoRemoveWeightStageSub();
void DoClickCheckboxID(const bool);
std::vector<Starpounds::WeightStage> GetWeightStages() const;
virtual size_t CheckForErrors();
void ClearForm();
wxButton *m_add;
wxButton *m_remove;
wxButton *m_subAdd;
wxButton *m_subRemove;
wxCheckBox *m_id;
private:
void EnableForm(const bool, const bool = true, const bool = false);
void PopulateForm(const Starpounds::WeightStage &);
void PopulateForm(const Starpounds::WeightStageSub &);
void DoResetWeightStages();
std::string GetInternalNameReplacement(const Starpounds::WeightStage &);
std::string GetInternalNameReplacement(const Starpounds::WeightStageSub &);
bool HasDuplicateInternalName(const std::string &, const bool);
bool HasDuplicateNoID();
void OnClickWeightStage(wxCommandEvent &);
void OnClickWeightStageSub(wxCommandEvent &);
void OnClickCheckboxFrames(wxCommandEvent &);
void OnSelectComboBoxChest(wxCommandEvent &);
void OnSelectComboBoxLeg(wxCommandEvent &);
void OnInternalNameEdit(wxCommandEvent &WXUNUSED(event));
void OnFriendlyNameEdit(wxCommandEvent &WXUNUSED(event));
void OnDescriptionChestEdit(wxCommandEvent &WXUNUSED(event));
void OnDescriptionLegEdit(wxCommandEvent &WXUNUSED(event));
void OnResetWeightStages(wxCommandEvent &WXUNUSED(event));
wxTextCtrl *m_name;
wxTextCtrl *m_friendlyName;
wxTextCtrl *m_descriptionChest;
wxTextCtrl *m_descriptionLeg;
wxChoice *m_typeChest;
wxChoice *m_typeLeg;
wxCheckBox *m_frames;
wxListBox *m_stagesList;
wxListBox *m_subStagesList;
wxButton *m_default;
wxStaticText *m_nameText;
wxStaticText *m_friendlyNameText;
wxStaticText *m_descriptionChestText;
wxStaticText *m_descriptionLegText;
wxStaticText *m_typeChestText;
wxStaticText *m_typeLegText;
wxStaticText *m_stagesListText;
wxStaticText *m_subStagesListText;
std::vector<Starpounds::WeightStage> m_stages;
wxDECLARE_EVENT_TABLE();
};
/*
class SpritesPanel: public wxPanel, public ErrorHandler
{
@ -297,7 +174,6 @@ private:
void OnRemoveWeightStage(wxCommandEvent &WXUNUSED(event));
void OnAddWeightStageSub(wxCommandEvent &WXUNUSED(event));
void OnRemoveWeightStageSub(wxCommandEvent &WXUNUSED(event));
void OnChangedValue(wxPropertyGridEvent &WXUNUSED(event));
void OnClickCheckboxID(wxCommandEvent &);
MainPanel *m_panel_main;
@ -307,7 +183,6 @@ private:
wxDECLARE_EVENT_TABLE();
};
} // namespace SpeciesGen
#endif // SPECIESGEN_H

View File

@ -1,6 +1,6 @@
/*
speciesgen
Copyright (C) 2022 prisixia
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
@ -23,41 +23,39 @@ along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
// Purpose: Implementation of Frames and related
// Author: prisixia
// Created: 2022-10-03
// Copyright: (c) 2022 prisixia
// License: GNU General Public License version 3
// Copyright: (C) 2022-2023 prisixia
// Licence: GNU General Public License version 3
/////////////////////////////////////////////////////////////////////////////
#ifndef SPECIESGEN_STARBOUND_FRAMES_H
#define SPECIESGEN_STARBOUND_FRAMES_H
#include <filesystem>
#include <fstream>
#include <optional>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>
#include "rapidjson/ostreamwrapper.h"
#include "rapidjson/prettywriter.h"
#include "cereal/types/string.hpp"
#include "cereal/types/vector.hpp"
namespace Starbound {
namespace Frames {
namespace Starbound::Frames {
class Grid {
public:
Grid(const std::vector<std::vector<std::optional<std::string>>>,
Grid() = delete;
Grid(std::vector<std::vector<std::optional<std::string>>>,
const std::tuple<uint32_t, uint32_t> = {129, 129},
const std::tuple<uint32_t, uint32_t> = {9, 6});
std::tuple<uint32_t, uint32_t> GetSize() const;
std::tuple<uint32_t, uint32_t> GetDimensions() const;
std::vector<std::vector<std::optional<std::string>>> GetNames() const;
[[nodiscard]] std::tuple<uint32_t, uint32_t> GetSize() const;
[[nodiscard]] std::tuple<uint32_t, uint32_t> GetDimensions() const;
[[nodiscard]] std::vector<std::vector<std::optional<std::string>>>
GetNames() const;
void SetSize(const std::tuple<uint32_t, uint32_t>);
void SetDimensions(const std::tuple<uint32_t, uint32_t>);
void SetNames(const std::vector<std::vector<std::optional<std::string>>>);
void Serialize(const std::filesystem::path) const;
template <typename Writer> void Serialize(Writer &) const;
void SetNames(const std::vector<std::vector<std::optional<std::string>>> &);
private:
std::tuple<uint32_t, uint32_t> m_size;
@ -67,21 +65,97 @@ private:
class Frames {
public:
Frames(const std::unordered_map<std::string, std::string>, const Grid);
std::unordered_map<std::string, std::string> GetAliases() const;
Grid GetGrid() const;
Frames() = delete;
Frames(std::unordered_map<std::string, std::string>, Grid);
void SetAliases(const std::unordered_map<std::string, std::string>);
void SetGrid(const Grid);
[[nodiscard]] std::unordered_map<std::string, std::string>
GetAliases() const;
void Serialize(const std::filesystem::path) const;
template <typename Writer> void Serialize(Writer &) const;
[[nodiscard]] Grid GetGrid() const;
void SetAliases(const std::unordered_map<std::string, std::string> &);
void SetGrid(const Grid &);
private:
std::unordered_map<std::string, std::string> m_aliases;
Grid m_grid;
};
} // namespace Frames
} // namespace Starbound
} // namespace Starbound::Frames
//----------------------------------------------------------------------
// Serialisation
//----------------------------------------------------------------------
namespace cereal {
template <class Archive>
void Save(Archive &archive,
std::unordered_map<std::string, std::string> const &m) {
for (const std::pair<const std::string, std::string> &pair : m) {
archive(CEREAL_NVP_(pair.first.c_str(), pair.second));
}
}
template <class Archive>
void Save(Archive &archive, std::tuple<uint32_t, uint32_t> const &m) {
archive(make_size_tag(static_cast<size_type>(
std::tuple_size_v<std::tuple<uint32_t, uint32_t>>)));
archive(std::get<0>(m), std::get<1>(m));
}
template <class Archive>
void Save(Archive &archive, std::vector<std::optional<std::string>> const &m) {
archive(make_size_tag(static_cast<size_type>(m.size())));
for (const auto &opt : m) {
if (opt.has_value()) {
archive(opt.value());
} else {
archive(nullptr);
}
}
}
template <class Archive>
static void load_and_construct(Archive &archive,
construct<Starbound::Frames::Grid> &construct) {
std::tuple<uint32_t, uint32_t> size;
std::tuple<uint32_t, uint32_t> dimensions;
std::vector<std::vector<std::optional<std::string>>> names;
archive(CEREAL_NVP(size), CEREAL_NVP(dimensions), CEREAL_NVP(names));
construct(names, size, dimensions);
}
template <class Archive>
void Save(Archive &archive, Starbound::Frames::Grid const &m) {
const std::tuple<uint32_t, uint32_t> size = m.GetSize();
const std::tuple<uint32_t, uint32_t> dimensions = m.GetDimensions();
const std::vector<std::vector<std::optional<std::string>>> names =
m.GetNames();
archive(CEREAL_NVP(size), CEREAL_NVP(dimensions), CEREAL_NVP(names));
}
template <class Archive>
static void
load_and_construct(Archive &archive,
construct<Starbound::Frames::Frames> &construct) {
std::unordered_map<std::string, std::string> aliases;
Starbound::Frames::Grid grid;
archive(CEREAL_NVP(aliases), CEREAL_NVP(grid));
construct(aliases, grid);
}
template <class Archive>
void Save(Archive &archive, Starbound::Frames::Frames const &m) {
const std::unordered_map<std::string, std::string> aliases = m.GetAliases();
const Starbound::Frames::Grid grid = m.GetGrid();
archive(CEREAL_NVP(aliases), CEREAL_NVP(grid));
}
} // namespace cereal
#endif // SPECIESGEN_STARBOUND_FRAMES_H

View File

@ -1,6 +1,6 @@
/*
speciesgen
Copyright (C) 2022 prisixia
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
@ -23,24 +23,22 @@ along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
// Purpose: Implementation of Item and related
// Author: prisixia
// Created: 2022-10-02
// Copyright: (c) 2022 prisixia
// License: GNU General Public License version 3
// Copyright: (C) 2022-2023 prisixia
// Licence: GNU General Public License version 3
/////////////////////////////////////////////////////////////////////////////
#ifndef SPECIESGEN_STARBOUND_ITEM_H
#define SPECIESGEN_STARBOUND_ITEM_H
#include <algorithm>
#include <cctype>
#include <filesystem>
#include <fstream>
#include <string>
#include "cereal/types/string.hpp"
#include "magic_enum.hpp"
#include "rapidjson/ostreamwrapper.h"
#include "rapidjson/prettywriter.h"
namespace Starbound {
namespace Item {
namespace Starbound::Item {
enum class Rarity {
Common = 0,
Uncommon = 1,
@ -55,18 +53,17 @@ enum class TooltipKind { Armor = 0 };
class Frames {
public:
Frames(const std::filesystem::path, const std::filesystem::path = "",
const std::filesystem::path = "");
std::filesystem::path GetBody() const;
std::filesystem::path GetBackSleeve() const;
std::filesystem::path GetFrontSleeve() const;
Frames() = default;
Frames(std::filesystem::path);
Frames(std::filesystem::path, std::filesystem::path, std::filesystem::path);
void SetBody(const std::filesystem::path);
void SetBackSleeve(const std::filesystem::path);
void SetFrontSleeve(const std::filesystem::path);
[[nodiscard]] std::filesystem::path GetBody() const;
[[nodiscard]] std::filesystem::path GetBackSleeve() const;
[[nodiscard]] std::filesystem::path GetFrontSleeve() const;
void Serialize(const std::filesystem::path) const;
template <typename Writer> void Serialize(Writer &) const;
void SetBody(const std::filesystem::path &);
void SetBackSleeve(const std::filesystem::path &);
void SetFrontSleeve(const std::filesystem::path &);
private:
std::filesystem::path m_body;
@ -76,34 +73,34 @@ private:
class Item {
public:
Item(const std::string, const std::filesystem::path, const Category,
const std::string, const std::string, const Frames, const Frames);
std::string GetItemName() const;
uint32_t GetPrice() const;
std::filesystem::path GetInventoryIcon() const;
uint16_t GetMaxStack() const;
Rarity GetRarity() const;
Category GetCategory() const;
std::string GetDescription() const;
std::string GetShortDescription() const;
TooltipKind GetTooltipKind() const;
Frames GetMaleFrames() const;
Frames GetFemaleFrames() const;
Item() = default;
Item(std::string, const Rarity);
Item(std::string, std::filesystem::path, const Category, std::string,
std::string, Frames, Frames);
void SetItemName(const std::string);
[[nodiscard]] std::string GetItemName() const;
[[nodiscard]] uint32_t GetPrice() const;
[[nodiscard]] std::filesystem::path GetInventoryIcon() const;
[[nodiscard]] uint16_t GetMaxStack() const;
[[nodiscard]] Rarity GetRarity() const;
[[nodiscard]] Category GetCategory() const;
[[nodiscard]] std::string GetDescription() const;
[[nodiscard]] std::string GetShortDescription() const;
[[nodiscard]] TooltipKind GetTooltipKind() const;
[[nodiscard]] Frames GetMaleFrames() const;
[[nodiscard]] Frames GetFemaleFrames() const;
void SetItemName(const std::string &);
void SetPrice(const uint32_t);
void SetInventoryIcon(const std::filesystem::path);
void SetInventoryIcon(const std::filesystem::path &);
void SetMaxStack(const uint16_t);
void SetRarity(const Rarity);
void SetCategory(const Category);
void SetDescription(const std::string);
void SetShortDescription(const std::string);
void SetDescription(const std::string &);
void SetShortDescription(const std::string &);
void SetTooltipKind(const TooltipKind);
void SetMaleFrames(const Frames);
void SetFemaleFrames(const Frames);
void Serialize(const std::filesystem::path) const;
template <typename Writer> void Serialize(Writer &) const;
void SetMaleFrames(const Frames &);
void SetFemaleFrames(const Frames &);
private:
std::string m_itemName;
@ -118,7 +115,158 @@ private:
Frames m_maleFrames;
Frames m_femaleFrames;
};
} // namespace Item
} // namespace Starbound
} // namespace Starbound::Item
//----------------------------------------------------------------------
// Serialisation
//----------------------------------------------------------------------
namespace cereal {
template <class Archive>
static void load_and_construct(Archive &archive,
construct<Starbound::Item::Frames> &construct) {
std::filesystem::path body;
std::filesystem::path backSleeve;
std::filesystem::path frontSleeve;
archive(CEREAL_NVP(body), CEREAL_NVP(backSleeve), CEREAL_NVP(frontSleeve));
construct(body, backSleeve, frontSleeve);
}
template <class Archive>
void Save(Archive &archive, Starbound::Item::Frames const &m) {
const std::string body = m.GetBody().string();
const std::string backSleeve = m.GetBackSleeve().string();
const std::string frontSleeve = m.GetFrontSleeve().string();
archive(CEREAL_NVP(body), CEREAL_NVP(backSleeve), CEREAL_NVP(frontSleeve));
}
template <class Archive> void Load(Archive &archive, Starbound::Item::Item &m) {
std::string itemName;
uint32_t price;
std::string inventoryIcon;
uint16_t maxStack;
std::string _rarity;
std::string _category;
std::string description;
std::string shortdescription;
std::string _tooltipKind;
Starbound::Item::Frames maleFrames;
Starbound::Item::Frames femaleFrames;
archive(CEREAL_NVP(itemName), CEREAL_NVP(price), CEREAL_NVP(inventoryIcon),
CEREAL_NVP(maxStack), CEREAL_NVP_("rarity", _rarity),
CEREAL_NVP_("category", _category), CEREAL_NVP(description),
CEREAL_NVP(shortdescription),
CEREAL_NVP_("tooltipKind", _tooltipKind), CEREAL_NVP(maleFrames),
CEREAL_NVP(femaleFrames));
const auto rarity = magic_enum::enum_cast<Starbound::Item::Rarity>(_rarity);
const auto category =
magic_enum::enum_cast<Starbound::Item::Category>(_category);
const auto tooltipKind =
magic_enum::enum_cast<Starbound::Item::TooltipKind>(_tooltipKind);
m.SetItemName(itemName);
m.SetPrice(price);
m.SetInventoryIcon(inventoryIcon);
m.SetMaxStack(maxStack);
if (rarity.has_value()) {
m.SetRarity(rarity.value());
}
if (category.has_value()) {
m.SetCategory(category.value());
}
m.SetDescription(description);
m.SetShortDescription(shortdescription);
if (tooltipKind.has_value()) {
m.SetTooltipKind(tooltipKind.value());
}
m.SetMaleFrames(maleFrames);
m.SetFemaleFrames(femaleFrames);
}
template <class Archive>
void Save(Archive &archive, Starbound::Item::Item const &m) {
const std::string itemName = m.GetItemName();
const uint32_t price = m.GetPrice();
const std::string inventoryIcon = m.GetInventoryIcon().string();
const uint16_t maxStack = m.GetMaxStack();
const std::string rarity =
static_cast<std::string>(magic_enum::enum_name(m.GetRarity()));
std::string category =
static_cast<std::string>(magic_enum::enum_name(m.GetCategory()));
const std::string description = m.GetDescription();
const std::string shortdescription = m.GetShortDescription();
const std::string tooltipKind =
static_cast<std::string>(magic_enum::enum_name(m.GetTooltipKind()));
const Starbound::Item::Frames maleFrames = m.GetMaleFrames();
const Starbound::Item::Frames femaleFrames = m.GetFemaleFrames();
category[0] = tolower(category[0]);
archive(CEREAL_NVP(itemName), CEREAL_NVP(price), CEREAL_NVP(inventoryIcon),
CEREAL_NVP(maxStack), CEREAL_NVP(rarity), CEREAL_NVP(category),
CEREAL_NVP(description), CEREAL_NVP(shortdescription),
CEREAL_NVP(tooltipKind));
if (maleFrames.GetBackSleeve().empty() &&
maleFrames.GetFrontSleeve().empty() &&
femaleFrames.GetBackSleeve().empty() &&
femaleFrames.GetFrontSleeve().empty()) {
archive(CEREAL_NVP_("maleFrames", maleFrames.GetBody()),
CEREAL_NVP_("femaleFrames", femaleFrames.GetBody()));
} else {
archive(CEREAL_NVP(maleFrames), CEREAL_NVP(femaleFrames));
}
/*
* At the moment, cereal doesn't really support optional values
* for deserialisation, meaning that we have to serialise all fields
* even if they're eventually unneeded.
*/
/*
archive(CEREAL_NVP(itemName), CEREAL_NVP(rarity), CEREAL_NVP(maleFrames),
CEREAL_NVP(femaleFrames));
if (price > 0) {
archive(CEREAL_NVP(price));
}
if (!inventoryIcon.empty()) {
archive(CEREAL_NVP(inventoryIcon));
}
if (maxStack > 1) {
archive(CEREAL_NVP(maxStack));
}
if (!category.empty()) {
category[0] = tolower(category[0]);
archive(CEREAL_NVP(category));
}
if (!description.empty()) {
archive(CEREAL_NVP(description));
}
if (!shortdescription.empty()) {
archive(CEREAL_NVP(shortdescription));
}
if (!tooltipKind.empty()) {
archive(CEREAL_NVP(tooltipKind));
}
*/
}
} // namespace cereal
#endif // SPECIESGEN_STARBOUND_ITEM_H

View File

@ -1,6 +1,6 @@
/*
speciesgen
Copyright (C) 2022 prisixia
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
@ -23,48 +23,54 @@ along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
// Purpose: Implementation of Metadata
// Author: prisixia
// Created: 2022-10-02
// Copyright: (c) 2022 prisixia
// License: GNU General Public License version 3
// Copyright: (C) 2022-2023 prisixia
// Licence: GNU General Public License version 3
/////////////////////////////////////////////////////////////////////////////
#ifndef SPECIESGEN_STARBOUND_METADATA_H
#define SPECIESGEN_STARBOUND_METADATA_H
#include <filesystem>
#include <fstream>
#include <string>
#include <vector>
#include "rapidjson/ostreamwrapper.h"
#include "rapidjson/prettywriter.h"
#include "cereal/types/string.hpp"
#include "cereal/types/vector.hpp"
namespace Starbound {
class Metadata {
public:
Metadata(const std::string, const std::string, const std::string,
const std::string =
Metadata() = default;
Metadata(std::string, std::string, std::string,
std::string =
"This mod has been generated via speciesgen made by prisixia.",
const std::string = "1.0.0_gen" SPECIESGEN_VERSION,
const std::string = "http://git.vern.cc/prisixia/speciesgen",
const std::vector<std::string> = {"starpounds"});
std::string GetName() const;
std::string GetFriendlyName() const;
std::string GetDescription() const;
std::string GetAuthor() const;
std::string GetVersion() const;
std::string GetLink() const;
std::vector<std::string> GetRequires() const;
std::string = "1.0.0_gen" SPECIESGEN_VERSION,
std::string = "http://git.vern.cc/prisixia/speciesgen",
std::vector<std::string> = {"starpounds"});
void SetName(const std::string);
void SetFriendlyName(const std::string);
void SetDescription(const std::string);
void SetAuthor(const std::string);
void SetVersion(const std::string);
void SetLink(const std::string);
void SetRequires(const std::vector<std::string>);
[[nodiscard]] std::string GetName() const;
[[nodiscard]] std::string GetFriendlyName() const;
[[nodiscard]] std::string GetDescription() const;
[[nodiscard]] std::string GetAuthor() const;
[[nodiscard]] std::string GetVersion() const;
[[nodiscard]] std::string GetLink() const;
[[nodiscard]] std::string GetSteamContentID() const;
[[nodiscard]] std::string GetTags() const;
[[nodiscard]] std::vector<std::string> GetIncludes() const;
[[nodiscard]] std::vector<std::string> GetRequires() const;
[[nodiscard]] uint32_t GetPriority() const;
void Serialize(const std::filesystem::path) const;
template <typename Writer> void Serialize(Writer &) const;
void SetName(const std::string &);
void SetFriendlyName(const std::string &);
void SetDescription(const std::string &);
void SetAuthor(const std::string &);
void SetVersion(const std::string &);
void SetLink(const std::string &);
void SetSteamContentID(const std::string &);
void SetTags(const std::string &);
void SetIncludes(const std::vector<std::string> &);
void SetRequires(const std::vector<std::string> &);
void SetPriority(const uint32_t);
private:
std::string m_name;
@ -73,8 +79,121 @@ private:
std::string m_author;
std::string m_version;
std::string m_link;
std::string m_steamContentId;
std::string m_tags;
std::vector<std::string> m_includes;
std::vector<std::string> m_requires;
uint32_t m_priority;
};
} // namespace Starbound
//----------------------------------------------------------------------
// Serialisation
//----------------------------------------------------------------------
namespace cereal {
template <class Archive> void Load(Archive &archive, Starbound::Metadata &m) {
std::string name;
std::string friendlyName;
std::string description;
std::string author;
std::string version;
std::string link;
std::string steamContentId;
std::string tags;
std::vector<std::string> includes;
std::vector<std::string> _requires;
uint32_t priority;
archive(CEREAL_NVP(name), CEREAL_NVP(friendlyName), CEREAL_NVP(description),
CEREAL_NVP(author), CEREAL_NVP(version), CEREAL_NVP(link),
CEREAL_NVP(steamContentId), CEREAL_NVP(tags), CEREAL_NVP(includes),
CEREAL_NVP_("requires", _requires), CEREAL_NVP(priority));
m.SetName(name);
m.SetFriendlyName(friendlyName);
m.SetDescription(description);
m.SetAuthor(author);
m.SetVersion(version);
m.SetLink(link);
m.SetSteamContentID(steamContentId);
m.SetTags(tags);
m.SetIncludes(includes);
m.SetRequires(_requires);
m.SetPriority(priority);
}
template <class Archive>
void Save(Archive &archive, Starbound::Metadata const &m) {
const std::string name = m.GetName();
const std::string friendlyName = m.GetFriendlyName();
const std::string description = m.GetDescription();
const std::string author = m.GetAuthor();
const std::string version = m.GetVersion();
const std::string link = m.GetLink();
const std::string steamContentId = m.GetSteamContentID();
const std::string tags = m.GetTags();
const std::vector<std::string> includes = m.GetIncludes();
const std::vector<std::string> _requires = m.GetRequires();
const uint32_t priority = m.GetPriority();
archive(CEREAL_NVP(name), CEREAL_NVP(friendlyName), CEREAL_NVP(description),
CEREAL_NVP(author), CEREAL_NVP(version), CEREAL_NVP(link),
CEREAL_NVP(steamContentId), CEREAL_NVP(tags), CEREAL_NVP(includes),
CEREAL_NVP_("requires", _requires), CEREAL_NVP(priority));
/*
* At the moment, cereal doesn't really support optional values
* for deserialisation, meaning that we have to serialise all fields
* even if they're eventually unneeded.
*/
/*
if (!name.empty()) {
archive(CEREAL_NVP(name));
}
if (!friendlyName.empty()) {
archive(CEREAL_NVP(friendlyName));
}
if (!description.empty()) {
archive(CEREAL_NVP(description));
}
if (!author.empty()) {
archive(CEREAL_NVP(author));
}
if (!version.empty()) {
archive(CEREAL_NVP(version));
}
if (!link.empty()) {
archive(CEREAL_NVP(link));
}
if (!steamContentId.empty()) {
archive(CEREAL_NVP(steamContentId));
}
if (!tags.empty()) {
archive(CEREAL_NVP(tags));
}
if (!includes.empty()) {
archive(CEREAL_NVP(includes));
}
if (!_requires.empty()) {
archive(CEREAL_NVP_("requires", _requires));
}
if (priority > 0) {
archive(CEREAL_NVP(priority));
}
*/
}
} // namespace cereal
#endif // SPECIESGEN_STARBOUND_METADATA_H

View File

@ -1,6 +1,6 @@
/*
speciesgen
Copyright (C) 2022 prisixia
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
@ -23,8 +23,8 @@ along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
// Purpose: Implementation of Patch and related
// Author: prisixia
// Created: 2022-10-02
// Copyright: (c) 2022 prisixia
// License: GNU General Public License version 3
// Copyright: (C) 2022-2023 prisixia
// Licence: GNU General Public License version 3
/////////////////////////////////////////////////////////////////////////////
#ifndef SPECIESGEN_STARBOUND_PATCH_H
@ -32,15 +32,12 @@ along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
#include <algorithm>
#include <filesystem>
#include <fstream>
#include <string>
#include "cereal/cereal.hpp"
#include "magic_enum.hpp"
#include "rapidjson/ostreamwrapper.h"
#include "rapidjson/prettywriter.h"
namespace Starbound {
namespace Patch {
namespace Starbound::Patch {
enum class Operation {
Test = 0,
Add = 1,
@ -50,29 +47,64 @@ enum class Operation {
Replace = 5
};
class Patch {
template <typename Value = std::string> class Patch {
public:
Patch(std::string, Operation = Operation::Add);
Operation GetOperation() const;
std::string GetPath() const;
std::string GetOverride() const;
std::string GetOverrideDirectives() const;
Patch() = delete;
Patch(std::filesystem::path path, Operation op = Operation::Add)
: m_op(op), m_path(std::move(path)) {}
Patch(std::filesystem::path path, Value value,
Operation op = Operation::Add)
: m_op(op), m_path(std::move(path)), m_value(value) {}
void SetOperation(const Operation);
void SetPath(const std::string);
void SetOverride(const std::string);
void SetOverrideDirectives(const std::string);
[[nodiscard]] Operation GetOperation() const { return m_op; }
[[nodiscard]] std::filesystem::path GetPath() const { return m_path; }
[[nodiscard]] Value GetValue() const { return m_value; }
void Serialize(const std::filesystem::path) const;
template <typename Writer> void Serialize(Writer &) const;
void SetOperation(const Operation op) { m_op = op; }
void SetPath(const std::filesystem::path &path) { m_path = path; }
void SetValue(const Value value) { m_value = value; }
private:
Operation m_op;
std::string m_path;
std::string m_override;
std::string m_overrideDirectives;
std::filesystem::path m_path;
Value m_value;
};
} // namespace Patch
} // namespace Starbound
} // namespace Starbound::Patch
//----------------------------------------------------------------------
// Serialisation
//----------------------------------------------------------------------
namespace cereal {
template <class Archive, typename Value>
static void
load_and_construct(Archive &archive,
construct<Starbound::Patch::Patch<Value>> &construct) {
std::string _op;
std::filesystem::path path;
Value value;
archive(CEREAL_NVP_("op", _op), CEREAL_NVP(path), CEREAL_NVP(value));
const auto op =
magic_enum::enum_cast<Starbound::Patch::Operation>(_op).value_or(
Starbound::Patch::Operation::Add);
construct(path, value, op);
}
template <class Archive, typename Value>
void Save(Archive &archive, Starbound::Patch::Patch<Value> const &m) {
std::string op =
static_cast<std::string>(magic_enum::enum_name(m.GetOperation()))
.c_str();
const std::string path = m.GetPath().string();
const Value value = m.GetValue();
std::for_each(op.begin(), op.end(), [](char &c) { c = ::tolower(c); });
archive(CEREAL_NVP(op), CEREAL_NVP(path), CEREAL_NVP(value));
}
} // namespace cereal
#endif // SPECIESGEN_STARBOUND_PATCH_HPP

View File

@ -0,0 +1,108 @@
/*
speciesgen
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
speciesgen 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.
speciesgen 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 speciesgen. If not, see <https://www.gnu.org/licenses/>.
*/
/////////////////////////////////////////////////////////////////////////////
// Name: species.cpp
// Purpose: Implementation of SpeciesConfig for patching
// Author: prisixia
// Created: 2022-10-03
// Copyright: (C) 2022-2023 prisixia
// Licence: GNU General Public License version 3
/////////////////////////////////////////////////////////////////////////////
#ifndef SPECIESGEN_STARPOUNDS_SPECIES_H
#define SPECIESGEN_STARPOUNDS_SPECIES_H
#include <filesystem>
#include <string>
#include "cereal/types/string.hpp"
namespace Starpounds {
class SpeciesConfig {
public:
SpeciesConfig(const bool = false);
SpeciesConfig(std::string, const bool = false);
SpeciesConfig(std::string, std::string, const bool = false);
[[nodiscard]] bool GetFullbright() const;
[[nodiscard]] std::string GetOverride() const;
[[nodiscard]] std::string GetOverrideDirectives() const;
void SetFullbright(const bool);
void SetOverride(const std::string &);
void SetOverrideDirectives(const std::string &);
private:
bool m_fullbright;
std::string m_override;
std::string m_overrideDirectives;
};
} // namespace Starpounds
//----------------------------------------------------------------------
// Serialisation
//----------------------------------------------------------------------
namespace cereal {
template <class Archive>
void Load(Archive &archive, Starpounds::SpeciesConfig &m) {
bool fullbright;
std::string _override;
std::string overrideDirectives;
/*
* It'd throw an exception here eventually, since this
* patch may not include unnecesseary data, while cereal
* currently has no option to deserialise with optional
* values.
*
* But since we don't load this and just have this function
* because we can, we don't have to worry about this for now.
*/
archive(CEREAL_NVP(fullbright), CEREAL_NVP_("override", _override),
CEREAL_NVP(overrideDirectives));
m.SetFullbright(fullbright);
m.SetOverride(_override);
m.SetOverrideDirectives(overrideDirectives);
}
template <class Archive>
void Save(Archive &archive, Starpounds::SpeciesConfig const &m) {
const bool fullbright = m.GetFullbright();
const std::string _override = m.GetOverride();
const std::string overrideDirectives = m.GetOverrideDirectives();
if (fullbright) {
archive(CEREAL_NVP(fullbright));
}
if (!_override.empty()) {
archive(CEREAL_NVP_("override", _override));
}
if (!overrideDirectives.empty()) {
archive(CEREAL_NVP(overrideDirectives));
}
}
} // namespace cereal
#endif // SPECIESGEN_STARPOUNDS_SPECIES_H

View File

@ -1,6 +1,6 @@
/*
speciesgen
Copyright (C) 2022 prisixia
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
@ -23,8 +23,8 @@ along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
// Purpose: Implementation of Types
// Author: prisixia
// Created: 2022-10-09
// Copyright: (c) 2022 prisixia
// License: GNU General Public License version 3
// Copyright: (C) 2022-2023 prisixia
// Licence: GNU General Public License version 3
/////////////////////////////////////////////////////////////////////////////
#ifndef SPECIESGEN_STARPOUNDS_SUBS_H
@ -35,8 +35,7 @@ along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
#include "magic_enum.hpp"
namespace Starpounds {
namespace Types {
namespace Starpounds::Types {
enum class Chests { Chest = 0, Bust = 1, Belly = 2, Arms = 3 };
enum class Legs { Legs = 0, Body = 1 };
@ -56,7 +55,6 @@ enum class Subs {
std::string AsString(const Subs);
std::string AsFriendly(const Subs);
Chests AsChest(const Subs);
} // namespace Types
} // namespace Starpounds
} // namespace Starpounds::Types
#endif // SPECIESGEN_STARPOUNDS_SUBS_H

View File

@ -1,6 +1,6 @@
/*
speciesgen
Copyright (C) 2022 prisixia
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
@ -23,45 +23,40 @@ along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
// Purpose: Implementation of WeightStage and related
// Author: prisixia
// Created: 2022-10-03
// Copyright: (c) 2022 prisixia
// License: GNU General Public License version 3
// Copyright: (C) 2022-2023 prisixia
// Licence: GNU General Public License version 3
/////////////////////////////////////////////////////////////////////////////
#ifndef SPECIESGEN_STARPOUNDS_WEIGHTSTAGE_H
#define SPECIESGEN_STARPOUNDS_WEIGHTSTAGE_H
#include <filesystem>
#include <fstream>
#include <string>
#include <vector>
#include "starpounds/types.h"
// #include "rapidjson/document.h"
#include "rapidjson/istreamwrapper.h"
#include "rapidjson/ostreamwrapper.h"
#include "rapidjson/prettywriter.h"
#include "cereal/types/string.hpp"
#include "cereal/types/vector.hpp"
namespace Starpounds {
class WeightStageSub {
public:
WeightStageSub(const std::string, const std::string, const std::string,
const Types::Chests);
WeightStageSub(const std::string);
WeightStageSub(const Types::Subs, const std::string);
std::string GetName() const;
std::string GetFriendlyName() const;
std::string GetChestDescription() const;
Types::Chests GetChestType() const;
WeightStageSub() = default;
WeightStageSub(std::string, std::string, std::string, const Types::Chests);
WeightStageSub(std::string);
WeightStageSub(const Types::Subs, std::string);
void SetName(const std::string);
void SetFriendlyName(const std::string);
void SetChestDescription(const std::string);
[[nodiscard]] std::string GetName() const;
[[nodiscard]] std::string GetFriendlyName() const;
[[nodiscard]] std::string GetChestDescription() const;
[[nodiscard]] Types::Chests GetChestType() const;
void SetName(const std::string &);
void SetFriendlyName(const std::string &);
void SetChestDescription(const std::string &);
void SetChestType(const Types::Chests);
void Serialize(const std::filesystem::path) const;
template <typename Writer> void Serialize(Writer &) const;
protected:
std::string m_name;
std::string m_friendlyName;
@ -71,27 +66,24 @@ protected:
class WeightStage : public WeightStageSub {
public:
WeightStage(const std::string, const std::string, const std::string,
const Types::Chests, const std::string, const Types::Legs,
const bool, const bool, const std::vector<WeightStageSub> = {});
WeightStage(const std::string, const bool, const bool,
const std::vector<WeightStageSub> = {});
std::string GetLegDescription() const;
Types::Legs GetLegType() const;
bool HasFrames() const;
bool HasID() const;
std::vector<WeightStageSub> GetSubs() const;
WeightStage() = default;
WeightStage(const std::string &, const std::string &, const std::string &,
const Types::Chests, std::string, const Types::Legs, const bool,
const bool, std::vector<WeightStageSub> = {});
WeightStage(const std::string &, const bool, const bool,
std::vector<WeightStageSub> = {});
void SetLegDescription(const std::string);
[[nodiscard]] std::string GetLegDescription() const;
[[nodiscard]] Types::Legs GetLegType() const;
[[nodiscard]] bool HasFrames() const;
[[nodiscard]] bool HasID() const;
[[nodiscard]] std::vector<WeightStageSub> GetSubs() const;
void SetLegDescription(const std::string &);
void SetLegType(const Types::Legs);
void SetFrames(const bool);
void SetID(const bool);
void SetSubs(const std::vector<WeightStageSub>);
void Serialize(const std::filesystem::path) const;
template <typename Writer> void Serialize(Writer &) const;
// void Deserialize(const std::filesystem::path);
// void Deserialize(const rapidjson::Value &);
void SetSubs(const std::vector<WeightStageSub> &);
private:
std::string m_descriptionLeg;
@ -102,4 +94,150 @@ private:
};
} // namespace Starpounds
//----------------------------------------------------------------------
// Serialisation
//----------------------------------------------------------------------
namespace cereal {
template <class Archive>
void Load(Archive &archive, Starpounds::WeightStageSub &m) {
std::string name;
std::string friendlyName;
std::string descriptionChest;
std::string typeChest;
archive(CEREAL_NVP(name), CEREAL_NVP_("friendly_name", friendlyName),
CEREAL_NVP_("desc_chest", descriptionChest),
CEREAL_NVP_("type_chest", typeChest));
m.SetName(name);
m.SetFriendlyName(friendlyName);
m.SetChestDescription(descriptionChest);
m.SetChestType(
magic_enum::enum_cast<Starpounds::Types::Chests>(typeChest).value_or(
Starpounds::Types::Chests::Chest));
}
template <class Archive>
void Save(Archive &archive, Starpounds::WeightStageSub const &m) {
const std::string name = m.GetName();
const std::string friendlyName = m.GetFriendlyName();
const std::string descriptionChest = m.GetChestDescription();
const std::string typeChest =
static_cast<std::string>(magic_enum::enum_name(m.GetChestType()));
archive(CEREAL_NVP(name), CEREAL_NVP_("friendly_name", friendlyName),
CEREAL_NVP_("desc_chest", descriptionChest),
CEREAL_NVP_("type_chest", typeChest));
/*
* At the moment, cereal doesn't really support optional values
* for deserialisation, meaning that we have to serialise all fields
* even if they're eventually unneeded.
*/
/*
archive(CEREAL_NVP(name));
if (!friendlyName.empty()) {
archive(CEREAL_NVP_("friendly_name", friendlyName));
}
if (!descriptionChest.empty()) {
archive(CEREAL_NVP_("desc_chest", descriptionChest));
}
archive(CEREAL_NVP_("type_chest", typeChest));
*/
}
template <class Archive>
void Load(Archive &archive, Starpounds::WeightStage &m) {
std::string name;
std::string friendlyName;
std::string descriptionChest;
std::string descriptionLeg;
std::string typeChest;
std::string typeLeg;
bool frames;
bool id;
std::vector<Starpounds::WeightStageSub> subs;
archive(CEREAL_NVP(name), CEREAL_NVP_("friendly_name", friendlyName),
CEREAL_NVP_("desc_chest", descriptionChest),
CEREAL_NVP_("desc_leg", descriptionLeg),
CEREAL_NVP_("type_chest", typeChest),
CEREAL_NVP_("type_leg", typeLeg),
CEREAL_NVP_("need_frames", frames), CEREAL_NVP_("need_id", id),
CEREAL_NVP(subs));
m.SetName(name);
m.SetFriendlyName(friendlyName);
m.SetChestDescription(descriptionChest);
m.SetLegDescription(descriptionLeg);
m.SetChestType(
magic_enum::enum_cast<Starpounds::Types::Chests>(typeChest).value_or(
Starpounds::Types::Chests::Chest));
m.SetLegType(
magic_enum::enum_cast<Starpounds::Types::Legs>(typeLeg).value_or(
Starpounds::Types::Legs::Legs));
m.SetFrames(frames);
m.SetID(id);
m.SetSubs(subs);
}
template <class Archive>
void Save(Archive &archive, Starpounds::WeightStage const &m) {
const std::string name = m.GetName();
const std::string friendlyName = m.GetFriendlyName();
const std::string descriptionChest = m.GetChestDescription();
const std::string descriptionLeg = m.GetLegDescription();
const std::string typeChest =
static_cast<std::string>(magic_enum::enum_name(m.GetChestType()));
const std::string typeLeg =
static_cast<std::string>(magic_enum::enum_name(m.GetLegType()));
const bool frames = m.HasFrames();
const bool id = m.HasID();
const std::vector<Starpounds::WeightStageSub> subs = m.GetSubs();
archive(CEREAL_NVP(name), CEREAL_NVP_("friendly_name", friendlyName),
CEREAL_NVP_("desc_chest", descriptionChest),
CEREAL_NVP_("desc_leg", descriptionLeg),
CEREAL_NVP_("type_chest", typeChest),
CEREAL_NVP_("type_leg", typeLeg),
CEREAL_NVP_("need_frames", frames), CEREAL_NVP_("need_id", id),
CEREAL_NVP(subs));
/*
* At the moment, cereal doesn't really support optional values
* for deserialisation, meaning that we have to serialise all fields
* even if they're eventually unneeded.
*/
/*
archive(CEREAL_NVP(name));
if (!friendlyName.empty()) {
archive(CEREAL_NVP_("friendly_name", friendlyName));
}
if (!descriptionChest.empty()) {
archive(CEREAL_NVP_("desc_chest", descriptionChest));
}
if (!descriptionLeg.empty()) {
archive(CEREAL_NVP_("desc_leg", descriptionLeg));
}
archive(CEREAL_NVP_("type_chest", typeChest),
CEREAL_NVP_("type_leg", typeLeg),
CEREAL_NVP_("need_frames", frames), CEREAL_NVP_("need_id", id));
if (!subs.empty()) {
archive(CEREAL_NVP(subs));
}
*/
}
} // namespace cereal
#endif // SPECIESGEN_STARPOUNDS_WEIGHTSTAGE_H

View File

@ -1,6 +1,6 @@
/*
speciesgen
Copyright (C) 2022 prisixia
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
@ -26,8 +26,8 @@ namespace SpeciesGen {
// ErrorHandler
//----------------------------------------------------------------------
ErrorHandler::ErrorHandler(const std::string handlerName)
: m_handlerName(handlerName) {}
ErrorHandler::ErrorHandler(std::string handlerName)
: m_handlerName(std::move(handlerName)) {}
std::string ErrorHandler::GetError(const size_t index) {
const std::string handlerName = m_handlerName;

209
src/gui/main_panel.cpp Normal file
View File

@ -0,0 +1,209 @@
/*
speciesgen
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
speciesgen 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.
speciesgen 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 speciesgen. If not, see <https://www.gnu.org/licenses/>.
*/
#include "gui/main_panel.h"
namespace SpeciesGen {
wxBEGIN_EVENT_TABLE(MainPanel, wxPanel)
#if wxUSE_DIRDLG
EVT_BUTTON(DIR_CHOOSE, MainPanel::DoChooseDir)
#endif // wxUSE_DIRDLG
wxEND_EVENT_TABLE()
// NOLINTBEGIN(cppcoreguidelines-owning-memory): wxWidgets already manages its
// memory more or less so that there's no need for owning the memory
MainPanel::MainPanel(wxWindow *window, int x, int y, int w, int h,
const std::string &handlerName)
: wxPanel(window, wxID_ANY, wxPoint(x, y), wxSize(w, h)),
ErrorHandler(handlerName) {
wxBoxSizer *column1 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *column2 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *row = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
m_authorText = new wxStaticText(this, wxID_ANY, "Author");
m_nameText = new wxStaticText(this, wxID_ANY, "Species (Internal)");
m_friendlyNameText = new wxStaticText(this, wxID_ANY, "Species (In-Game)");
m_modDestinationText = new wxStaticText(this, wxID_ANY, "Output directory");
m_author = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
wxSize(150, wxDefaultSize.GetHeight()));
m_author->SetHint("Author's name");
m_author->SetMaxLength(128);
#ifdef _WIN32
m_author->SetValue(wxGetUserName());
#else
m_author->SetValue(getenv("USER"));
#endif // _WIN32
m_name = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
wxSize(150, wxDefaultSize.GetHeight()));
m_name->SetHint("Internal species name");
m_name->SetMaxLength(128);
m_friendlyName =
new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition,
wxSize(150, wxDefaultSize.GetHeight()));
m_friendlyName->SetHint("In-Game species name");
m_friendlyName->SetMaxLength(128);
#ifdef _WIN32
m_modDestination = new wxTextCtrl(
this, wxID_ANY,
"C:\\Program Files (x86)\\Steam\\steamapps\\common\\Starbound\\mods",
wxDefaultPosition, wxSize(400, wxDefaultSize.GetHeight()));
#else
m_modDestination = new wxTextCtrl(
this, wxID_ANY,
wxString::Format("%s/.steam/steam/steamapps/common/Starbound/mods",
wxGetUserHome(wxGetUserName())));
#endif // _WIN32
m_generate = new wxButton(this, MOD_GENERATE, "Generate mod",
wxDefaultPosition, wxSize(280, 80));
column1->Add(m_authorText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column1->Add(m_author, 0, wxEXPAND | wxALL, 10);
column1->Add(m_nameText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column1->Add(m_name, 0, wxEXPAND | wxALL, 10);
column1->Add(m_friendlyNameText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column1->Add(m_friendlyName, 0, wxEXPAND | wxALL, 10);
column2->Add(m_modDestinationText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column2->Add(m_modDestination, 0, wxEXPAND | wxLEFT | wxUP, 10);
#if wxUSE_DIRDLG
m_browse = new wxButton(this, DIR_CHOOSE, "Browse...");
column2->Add(m_browse, 0, wxALL, 10);
#endif // wxUSE_DIRDLG
column2->AddSpacer(20);
column2->Add(m_generate, 0, wxALIGN_CENTER, 0);
row->Add(column1, 0, wxALL | wxALIGN_CENTER, 10);
row->Add(column2, 0, wxALL | wxALIGN_CENTER, 10);
topSizer->Add(row, 0, wxALL | wxALIGN_CENTER, 10);
SetSizer(topSizer);
}
// NOLINTEND(cppcoreguidelines-owning-memory)
#if wxUSE_CLIPBOARD
/*
wxTextCtrl *MainPanel::GetFocusedText() const
{
wxWindow *win = FindFocus();
wxTextCtrl *text = win ? wxDynamicCast(win, wxTextCtrl) : NULL;
return text;
}
bool MainPanel::HasSelection() const
{
long from;
long to;
GetFocusedText()->GetSelection(&from, &to);
return from != to;
}
void MainPanel::DoPasteFromClipboard()
{
// On X11, we want to get the data from the primary selection instead
// of the normal clipboard (which isn't normal under X11 at all). This
// call has no effect under MSW.
wxTheClipboard->UsePrimarySelection();
if (!wxTheClipboard->Open())
return;
wxTextDataObject data;
if (wxTheClipboard->IsSupported(data.GetFormat())) {
if (wxTheClipboard->GetData(data))
GetFocusedText()->AppendText(data.GetText());
}
wxTheClipboard->Close();
}
void MainPanel::DoCopyToClipboard()
{
// On X11, we want to get the data from the primary selection instead
// of the normal clipboard (which isn't normal under X11 at all). This
// call has no effect under MSW.
wxTheClipboard->UsePrimarySelection();
wxString text(GetFocusedText()->GetStringSelection());
if (text.IsEmpty())
return;
if (!wxTheClipboard->Open())
return;
wxTextDataObject *data = new wxTextDataObject(text);
wxTheClipboard->SetData(data);
wxTheClipboard->Close();
}
*/
#endif // wxUSE_CLIPBOARD
#if wxUSE_DIRDLG
void MainPanel::DoChooseDir(wxCommandEvent &WXUNUSED(event)) {
wxString dirHome =
wxStandardPaths::Get().GetUserDir(wxStandardPaths::Dir_Desktop);
wxDirDialog dialog(this, "Select a directory", dirHome,
wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
if (dialog.ShowModal() == wxID_OK) {
m_modDestination->SetValue(dialog.GetPath());
}
}
#endif // wxUSE_DIRDLG
size_t MainPanel::CheckForErrors() {
m_errorLog.clear();
size_t errorCount = 0;
if (m_author->IsEmpty()) {
m_errorLog.push_back("Empty author field, please fill it out.");
errorCount++;
}
if (m_name->IsEmpty()) {
m_errorLog.push_back("Empty internal name field, please fill it out.");
errorCount++;
}
if (m_friendlyName->IsEmpty()) {
m_errorLog.push_back("Empty in-game name field, please fill it out.");
errorCount++;
}
if (m_modDestination->IsEmpty()) {
m_errorLog.push_back("Empty path field, please fill it out.");
errorCount++;
}
if (!wxDir::Exists(m_modDestination->GetValue())) {
m_errorLog.push_back(
"Invalid directory, please check your entered path.");
errorCount++;
}
return errorCount;
}
} // namespace SpeciesGen

678
src/gui/stages_panel.cpp Normal file
View File

@ -0,0 +1,678 @@
/*
speciesgen
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
speciesgen 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.
speciesgen 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 speciesgen. If not, see <https://www.gnu.org/licenses/>.
*/
#include "gui/stages_panel.h"
namespace SpeciesGen {
wxBEGIN_EVENT_TABLE(StagesPanel, wxPanel)
EVT_LISTBOX(STAGES_LIST, StagesPanel::OnClickWeightStage)
EVT_LISTBOX(STAGES_SUB_LIST, StagesPanel::OnClickWeightStageSub)
EVT_CHECKBOX(STAGES_FRAMES, StagesPanel::OnClickCheckboxFrames)
EVT_COMBOBOX(STAGES_TYPE_CHEST, StagesPanel::OnSelectComboBoxChest)
EVT_COMBOBOX(STAGES_TYPE_LEG, StagesPanel::OnSelectComboBoxLeg)
EVT_TEXT(STAGES_TEXT_NAME, StagesPanel::OnInternalNameEdit)
EVT_TEXT(STAGES_TEXT_FRIENDLYNAME, StagesPanel::OnFriendlyNameEdit)
EVT_TEXT(STAGES_TEXT_DESCRIPTION_CHEST, StagesPanel::OnDescriptionChestEdit)
EVT_TEXT(STAGES_TEXT_DESCRIPTION_LEG, StagesPanel::OnDescriptionLegEdit)
EVT_BUTTON(STAGES_SET_DEFAULT, StagesPanel::OnResetWeightStages)
wxEND_EVENT_TABLE()
// NOLINTBEGIN(cppcoreguidelines-owning-memory): wxWidgets already manages its
// memory more or less so that there's no need for owning the memory
StagesPanel::StagesPanel(wxWindow *window, int x, int y, int w, int h,
const std::string &handlerName)
: wxPanel(window, wxID_ANY, wxPoint(x, y), wxSize(w, h)),
ErrorHandler(handlerName) {
wxBoxSizer *row1 = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *row2 = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *column1 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *column2 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *column3 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *column4 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
wxArrayString choicesChest;
wxArrayString choicesLeg;
constexpr auto enumsChest =
magic_enum::enum_values<Starpounds::Types::Chests>();
constexpr auto enumsLeg =
magic_enum::enum_values<Starpounds::Types::Legs>();
for (auto enumChest : enumsChest) {
choicesChest.Add(
static_cast<std::string>(magic_enum::enum_name(enumChest)));
}
for (auto enumLeg : enumsLeg) {
choicesLeg.Add(
static_cast<std::string>(magic_enum::enum_name(enumLeg)));
}
m_add = new wxButton(this, STAGES_ADD, "Add");
m_remove = new wxButton(this, STAGES_REMOVE, "Remove");
m_default = new wxButton(this, STAGES_SET_DEFAULT, "Restore default");
m_subAdd = new wxButton(this, STAGES_SUB_ADD, "Add sub-stage");
m_subRemove = new wxButton(this, STAGES_SUB_ADD, "Remove sub-stage");
m_subAdd->Disable();
m_subRemove->Disable();
m_nameText = new wxStaticText(this, wxID_ANY, "Internal name");
m_friendlyNameText = new wxStaticText(this, wxID_ANY, "In-Game name");
m_descriptionChestText =
new wxStaticText(this, wxID_ANY, "Chest description");
m_descriptionLegText = new wxStaticText(this, wxID_ANY, "Leg description");
m_typeChestText = new wxStaticText(this, wxID_ANY, "Chest type");
m_typeLegText = new wxStaticText(this, wxID_ANY, "Leg type");
m_stagesListText = new wxStaticText(this, wxID_ANY, "Stages");
m_subStagesListText = new wxStaticText(this, wxID_ANY, "Sub-Stages");
m_frames = new wxCheckBox(this, STAGES_FRAMES, "Has frames");
m_id = new wxCheckBox(this, STAGES_ID, "Has ID");
m_name = new wxTextCtrl(this, STAGES_TEXT_NAME);
m_friendlyName = new wxTextCtrl(this, STAGES_TEXT_FRIENDLYNAME);
m_descriptionChest = new wxTextCtrl(this, STAGES_TEXT_DESCRIPTION_CHEST,
wxEmptyString, wxDefaultPosition,
wxSize(240, wxDefaultSize.GetHeight()));
m_descriptionLeg = new wxTextCtrl(this, STAGES_TEXT_DESCRIPTION_LEG,
wxEmptyString, wxDefaultPosition,
wxSize(240, wxDefaultSize.GetHeight()));
m_stagesList =
new wxListBox(this, STAGES_LIST, wxDefaultPosition, wxSize(105, 220));
m_subStagesList = new wxListBox(this, STAGES_SUB_LIST, wxDefaultPosition,
wxSize(105, 220));
m_typeChest = new wxComboBox(
this, STAGES_TYPE_CHEST, choicesChest.Item(2), wxDefaultPosition,
wxSize(74, wxDefaultSize.GetHeight()), choicesChest, wxCB_READONLY);
m_typeLeg = new wxComboBox(
this, STAGES_TYPE_LEG, choicesLeg.Item(0), wxDefaultPosition,
wxSize(74, wxDefaultSize.GetHeight()), choicesLeg, wxCB_READONLY);
row1->Add(m_add, 0, wxALL, 10);
row1->Add(m_remove, 0, wxALL, 10);
row1->Add(m_default, 0, wxALL, 10);
row1->Add(m_subAdd, 0, wxALL, 10);
row1->Add(m_subRemove, 0, wxALL, 10);
column1->Add(m_stagesListText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column1->Add(m_stagesList, 0, wxALL, 10);
column2->Add(m_subStagesListText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column2->Add(m_subStagesList, 0, wxALL, 10);
column3->Add(m_nameText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column3->Add(m_name, 0, wxEXPAND | wxALL, 10);
column3->Add(m_friendlyNameText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column3->Add(m_friendlyName, 0, wxEXPAND | wxALL, 10);
column3->Add(m_typeChestText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column3->Add(m_typeChest, 0, wxALL, 10);
column4->Add(m_descriptionChestText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column4->Add(m_descriptionChest, 0, wxEXPAND | wxALL, 10);
column4->Add(m_descriptionLegText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column4->Add(m_descriptionLeg, 0, wxEXPAND | wxALL, 10);
column4->Add(m_typeLegText, 0, wxEXPAND | wxLEFT | wxUP, 10);
column4->Add(m_typeLeg, 0, wxALL, 10);
column3->Add(m_frames, 0, wxEXPAND | wxLEFT | wxUP, 10);
column3->Add(m_id, 0, wxEXPAND | wxLEFT | wxUP, 10);
row2->Add(column1, 0, 0, 0);
row2->Add(column2, 0, 0, 0);
row2->Add(column3, 0, 0, 0);
row2->Add(column4, 0, 0, 0);
topSizer->Add(row1, 0, wxLEFT | wxUP, 10);
topSizer->Add(row2, 0, wxALL | wxEXPAND, 10);
EnableForm(false);
DoResetWeightStages();
SetSizer(topSizer);
}
// NOLINTEND(cppcoreguidelines-owning-memory)
void StagesPanel::DoAddWeightStage(Starpounds::WeightStage stage) {
stage.SetName(GetInternalNameReplacement(stage));
m_stages.push_back(stage);
wxArrayString name;
name.Add(stage.GetName());
m_stagesList->InsertItems(name, m_stagesList->GetCount());
}
void StagesPanel::DoRemoveWeightStage() {
if (m_stagesList->GetCount() == 0) {
return;
}
int selection = m_stagesList->GetSelection();
if (selection == wxNOT_FOUND) {
selection = 0;
}
m_stagesList->Delete(selection);
m_subStagesList->Clear();
m_subAdd->Disable();
m_subRemove->Disable();
m_stages.erase(m_stages.begin() + selection);
EnableForm(false);
ClearForm();
}
void StagesPanel::DoAddWeightStageSub(Starpounds::WeightStageSub sub) {
int selection = m_stagesList->GetSelection();
if (selection == wxNOT_FOUND) {
selection = 0;
}
Starpounds::WeightStage &stage = m_stages.at(selection);
std::vector<Starpounds::WeightStageSub> subs = stage.GetSubs();
sub.SetName(GetInternalNameReplacement(sub));
subs.push_back(sub);
stage.SetSubs(subs);
wxArrayString name;
name.Add(sub.GetName());
m_subStagesList->InsertItems(name, m_subStagesList->GetCount());
}
void StagesPanel::DoRemoveWeightStageSub() {
if (m_subStagesList->GetCount() == 0) {
return;
}
int selection = m_subStagesList->GetSelection();
int stageSelection = m_stagesList->GetSelection();
if (selection == wxNOT_FOUND) {
selection = 0;
}
if (stageSelection == wxNOT_FOUND) {
stageSelection = 0;
}
Starpounds::WeightStage &stage = m_stages.at(stageSelection);
std::vector<Starpounds::WeightStageSub> subs = stage.GetSubs();
m_subStagesList->Delete(selection);
subs.erase(subs.begin() + selection);
stage.SetSubs(subs);
EnableForm(false);
ClearForm();
}
void StagesPanel::DoClickCheckboxID(const bool isChecked) {
Starpounds::WeightStage &stage = m_stages.at(m_stagesList->GetSelection());
stage.SetID(isChecked);
EnableForm(true, isChecked);
}
std::vector<Starpounds::WeightStage> StagesPanel::GetWeightStages() const {
return m_stages;
}
void StagesPanel::ClearWeightStages() {
m_stages.clear();
m_stagesList->Clear();
m_subStagesList->Clear();
this->ClearForm();
}
size_t StagesPanel::CheckForErrors() {
m_errorLog.clear();
size_t errorCount = 0;
if (m_stagesList->GetCount() == 0) {
m_errorLog.push_back("No available weightstages, please fill it or"
" restore the defaults.");
errorCount++;
}
if (HasDuplicateNoID()) {
m_errorLog.push_back("More than one weightstages have \"Has ID\""
" unchecked.");
errorCount++;
}
return errorCount;
}
void StagesPanel::EnableForm(const bool enable, const bool id, const bool sub) {
m_name->Enable(enable);
m_friendlyName->Enable(enable && id);
m_descriptionChest->Enable(enable && id);
m_descriptionLeg->Enable(enable && id && !sub);
m_typeChest->Enable(enable && id);
m_typeLeg->Enable(enable && id && !sub);
m_frames->Enable(enable && !sub);
m_id->Enable(enable && !sub);
m_nameText->Enable(enable);
m_friendlyNameText->Enable(enable && id);
m_descriptionChestText->Enable(enable && id);
m_descriptionLegText->Enable(enable && id && !sub);
m_typeChestText->Enable(enable && id);
m_typeLegText->Enable(enable && id && !sub);
}
void StagesPanel::ClearForm() {
m_name->ChangeValue(wxEmptyString);
m_friendlyName->ChangeValue(wxEmptyString);
m_descriptionChest->ChangeValue(wxEmptyString);
m_descriptionLeg->ChangeValue(wxEmptyString);
m_typeChest->SetSelection(2);
m_typeLeg->SetSelection(0);
m_frames->SetValue(false);
m_id->SetValue(false);
}
void StagesPanel::PopulateForm(const Starpounds::WeightStage &stage) {
m_name->ChangeValue(stage.GetName());
m_friendlyName->ChangeValue(stage.GetFriendlyName());
m_descriptionChest->ChangeValue(stage.GetChestDescription());
m_descriptionLeg->ChangeValue(stage.GetLegDescription());
m_typeChest->SetSelection(magic_enum::enum_integer(stage.GetChestType()));
m_typeLeg->SetSelection(magic_enum::enum_integer(stage.GetLegType()));
m_frames->SetValue(stage.HasFrames());
m_id->SetValue(stage.HasID());
EnableForm(true, stage.HasID());
}
void StagesPanel::PopulateForm(const Starpounds::WeightStageSub &sub) {
m_name->ChangeValue(sub.GetName());
m_friendlyName->ChangeValue(sub.GetFriendlyName());
m_descriptionChest->ChangeValue(sub.GetChestDescription());
m_typeChest->SetSelection(magic_enum::enum_integer(sub.GetChestType()));
EnableForm(true, true, true);
}
void StagesPanel::DoResetWeightStages() {
m_stages.clear();
m_stagesList->Clear();
m_subStagesList->Clear();
DoAddWeightStage(Starpounds::WeightStage(
"skinny", false, false,
{Starpounds::WeightStageSub(Starpounds::Types::Subs::Busty,
"Someone is a bit well developed."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Milky,
"You can hear the sloshing with every bounce."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Hyper,
"Someone is a bit well developed."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Saturated,
"Got a nice small gut from that meal you just had."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Stuffed,
"Quite a large meal you had with that big gut."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Packed,
"You've since past the point you could "
"try sucking in this gut."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Glutted,
"Either you're just that gluttonous or "
"your stomach is quite elastic."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Filled,
"You can start visualizing how much "
"padding you're gonna get from all this food."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Gorged,
"Every pound in your stomach you can feel "
"turning into fat right now.")}));
DoAddWeightStage(Starpounds::WeightStage(
"soft", "Soft", "Your stomach is looking a little less flat nowadays.",
Starpounds::Types::Chests::Belly,
"Your hips are a bit flared. No stick legs for you.",
Starpounds::Types::Legs::Legs, false, true,
{Starpounds::WeightStageSub(Starpounds::Types::Subs::Busty,
"You might be a bit out of shape but at "
"least you got some boob to balance it."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Milky,
"It's okay that you got a bit of a belly. "
"Those sloshing milkers are hiding it."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Hyper,
"Got some real nice melons there."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Stuffed,
"A bit out of shape and having a big meal, huh?"),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Packed,
"You certainly ain't gonna lose that "
"chub with a meal like this."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Glutted,
"Either you're just that gluttonous or "
"your stomach is quite elastic."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Filled,
"No wonder you've packed on weight with meals like this."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Gorged,
"You won't be just thick with meals like this.")}));
DoAddWeightStage(Starpounds::WeightStage(
"thick", "Thick",
"First sign of being out of shape is a soft gut that can't be sucked "
"in.",
Starpounds::Types::Chests::Belly,
"Thighs touching one another? Seems like someone is a bit thicker than "
"the most.",
Starpounds::Types::Legs::Legs, false, true,
{Starpounds::WeightStageSub(Starpounds::Types::Subs::Busty,
"You might be a bit out of shape but at "
"least you got some boob to balance it."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Milky,
"It's okay that you got a bit of a belly. "
"Those sloshing milkers are hiding it."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Hyper,
"Got some real nice melons there."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Stuffed,
"A bit out of shape and having a big meal, huh?"),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Packed,
"You certainly ain't gonna lose that "
"chub with a meal like this."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Filled,
"No wonder you've packed on weight with meals like this."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Gorged,
"You won't be just thick with meals like this.")}));
DoAddWeightStage(Starpounds::WeightStage(
"chubster", "Chubby",
"So wide, so chubby. Someone's been eating too many sweets.",
Starpounds::Types::Chests::Belly,
"Log sized legs, door jamming hips, ultra soft rear. You've been "
"snacking heavily.",
Starpounds::Types::Legs::Legs, false, true,
{Starpounds::WeightStageSub(Starpounds::Types::Subs::Busty,
"It's hard to tell your boobs are that big "
"with a gut that still dwarfs them."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Milky,
"Those sloshing milk tanks help to obscure "
"that chubby belly of yours."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Hyper,
"My, my. Your breasts are bigger than your own head."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Stuffed,
"It's okay. It's hard to tell you've eaten "
"with that much padding."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Filled,
"No wonder you've been packing on the "
"pounds with that much food eaten."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Gorged,
"Is this a sign you've given up on losing "
"weight? Or can you not stop yourself?")}));
DoAddWeightStage(Starpounds::WeightStage(
"plump", "Plump",
"When your gut is resting on a table, it's pretty fat porky.",
Starpounds::Types::Chests::Belly,
"A rear the size of a couch? You're really out of shape.",
Starpounds::Types::Legs::Legs, false, true,
{Starpounds::WeightStageSub(
Starpounds::Types::Subs::Busty,
"When your gut is resting on a table, it's pretty fat porky."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Milky,
"When your gut is resting on a table, it's pretty fat porky."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Hyper,
"Tables must fear a rack of that size."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Stuffed,
"It's hard to even tell you've just eaten."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Filled,
"A meal like this must just be an appetizer for you."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Gorged,
"The food in your stomach weighs more than a person, tubs.")}));
DoAddWeightStage(Starpounds::WeightStage(
"fatty", "Fatty",
"Your gut is the size of a person, you're just a hopeless, fat "
"glutton.",
Starpounds::Types::Chests::Belly,
"That butt is an absolute dumptruck. Only good for sitting down every "
"single day.",
Starpounds::Types::Legs::Legs, false, true,
{Starpounds::WeightStageSub(Starpounds::Types::Subs::Busty,
"Such impressive boobs you have. If they "
"weren't dwarfed by a big fat gut."),
Starpounds::WeightStageSub(
Starpounds::Types::Subs::Milky,
"From a certain angle. Your chest can give "
"the illusion your stomach isn't as big as it is."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Hyper,
"Those boobs are as wide as you are tall."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Stuffed,
"Your gut is the size of a person, you're "
"just a hopeless, fat glutton."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Filled,
"Your gut is the size of a person, you're "
"just a hopeless, fat glutton."),
Starpounds::WeightStageSub(Starpounds::Types::Subs::Gorged,
"Your gut is the size of a person, you're "
"just a hopeless, fat glutton.")}));
DoAddWeightStage(Starpounds::WeightStage(
"blob", "Blobby", "A bit of arm fat that can't be missed.",
Starpounds::Types::Chests::Arms,
"It'd be amazing if you can fit into a house since you're now a whale.",
Starpounds::Types::Legs::Body, true, true));
DoAddWeightStage(Starpounds::WeightStage(
"immobile", "Blobby", "A bit of arm fat that can't be missed.",
Starpounds::Types::Chests::Arms,
"Now you can't even move fatty. Your gluttony knows no bounds.",
Starpounds::Types::Legs::Body, true, true));
}
std::string
StagesPanel::GetInternalNameReplacement(const Starpounds::WeightStage &stage) {
size_t i = 0;
const std::string name = stage.GetName();
std::string newName = name;
while (HasDuplicateInternalName(newName, false)) {
newName = wxString::Format("%s%d", name, ++i);
}
return newName;
}
std::string
StagesPanel::GetInternalNameReplacement(const Starpounds::WeightStageSub &sub) {
size_t i = 0;
const std::string name = sub.GetName();
std::string newName = name;
while (HasDuplicateInternalName(newName, true)) {
newName = wxString::Format("%s%d", name, ++i);
}
return newName;
}
bool StagesPanel::HasDuplicateInternalName(const std::string &name,
const bool subs) {
if (subs) {
int selection = m_stagesList->GetSelection();
if (selection == wxNOT_FOUND) {
selection = 0;
}
const Starpounds::WeightStage &stage = m_stages.at(selection);
for (const Starpounds::WeightStageSub &sub : stage.GetSubs()) {
if (sub.GetName() == name) {
return true;
}
}
} else {
for (const Starpounds::WeightStage &stage : m_stages) {
if (stage.GetName() == name) {
return true;
}
}
}
return false;
}
bool StagesPanel::HasDuplicateNoID() {
bool hasNoID = false;
for (const Starpounds::WeightStage &stage : m_stages) {
if (!stage.HasID()) {
if (hasNoID) {
return true;
} else {
hasNoID = true;
}
}
}
return false;
}
void StagesPanel::OnClickWeightStage(wxCommandEvent &event) {
if (event.IsSelection()) {
ClearForm();
const int selection = event.GetSelection();
const Starpounds::WeightStage &stage = m_stages.at(selection);
wxArrayString names;
for (const Starpounds::WeightStageSub &sub : stage.GetSubs()) {
names.Add(sub.GetName());
}
m_subStagesList->Clear();
m_subStagesList->InsertItems(names, 0);
m_subAdd->Enable();
m_subRemove->Enable();
PopulateForm(stage);
} else {
m_subAdd->Disable();
m_subRemove->Disable();
EnableForm(false);
ClearForm();
}
}
void StagesPanel::OnClickWeightStageSub(wxCommandEvent &event) {
if (event.IsSelection()) {
ClearForm();
const int selection = event.GetSelection();
int stageSelection = m_stagesList->GetSelection();
if (stageSelection == wxNOT_FOUND) {
stageSelection = 0;
}
const Starpounds::WeightStage &stage = m_stages.at(stageSelection);
const Starpounds::WeightStageSub sub = stage.GetSubs().at(selection);
PopulateForm(sub);
} else {
EnableForm(false);
ClearForm();
}
}
void StagesPanel::OnClickCheckboxFrames(wxCommandEvent &event) {
const bool isChecked = event.IsChecked();
Starpounds::WeightStage &stage = m_stages.at(m_stagesList->GetSelection());
stage.SetFrames(isChecked);
}
void StagesPanel::OnSelectComboBoxChest(wxCommandEvent &event) {
const int selection = event.GetSelection();
int stageSelection = m_stagesList->GetSelection();
if (stageSelection == wxNOT_FOUND) {
stageSelection = 0;
}
Starpounds::WeightStage &stage = m_stages.at(stageSelection);
stage.SetChestType(
magic_enum::enum_value<Starpounds::Types::Chests>(selection));
}
void StagesPanel::OnSelectComboBoxLeg(wxCommandEvent &event) {
const int selection = event.GetSelection();
int parentSelection = m_stagesList->GetSelection();
if (parentSelection == wxNOT_FOUND) {
parentSelection = 0;
}
Starpounds::WeightStage &stage = m_stages.at(parentSelection);
stage.SetLegType(
magic_enum::enum_value<Starpounds::Types::Legs>(selection));
}
void StagesPanel::OnInternalNameEdit(wxCommandEvent &WXUNUSED(event)) {
int selection = m_stagesList->GetSelection();
int subSelection = m_subStagesList->GetSelection();
if (selection == wxNOT_FOUND) {
selection = 0;
}
Starpounds::WeightStage &stage = m_stages.at(selection);
if (subSelection != wxNOT_FOUND) {
std::vector<Starpounds::WeightStageSub> subs = stage.GetSubs();
Starpounds::WeightStageSub &sub = subs.at(subSelection);
sub.SetName(m_name->GetValue().ToStdString());
stage.SetSubs(subs);
m_subStagesList->SetString(subSelection, m_name->GetValue());
} else {
stage.SetName(m_name->GetValue().ToStdString());
m_stagesList->SetString(selection, m_name->GetValue());
}
}
void StagesPanel::OnFriendlyNameEdit(wxCommandEvent &WXUNUSED(event)) {
int selection = m_stagesList->GetSelection();
int subSelection = m_subStagesList->GetSelection();
if (selection == wxNOT_FOUND) {
selection = 0;
}
Starpounds::WeightStage &stage = m_stages.at(selection);
if (subSelection != wxNOT_FOUND) {
std::vector<Starpounds::WeightStageSub> subs = stage.GetSubs();
Starpounds::WeightStageSub &sub = subs.at(subSelection);
sub.SetFriendlyName(m_friendlyName->GetValue().ToStdString());
stage.SetSubs(subs);
} else {
Starpounds::WeightStage &stage = m_stages.at(selection);
stage.SetFriendlyName(m_friendlyName->GetValue().ToStdString());
}
}
void StagesPanel::OnDescriptionChestEdit(wxCommandEvent &WXUNUSED(event)) {
int selection = m_stagesList->GetSelection();
if (selection == wxNOT_FOUND) {
selection = 0;
}
Starpounds::WeightStage &stage = m_stages.at(selection);
stage.SetChestDescription(m_descriptionChest->GetValue().ToStdString());
}
void StagesPanel::OnDescriptionLegEdit(wxCommandEvent &WXUNUSED(event)) {
int selection = m_stagesList->GetSelection();
if (selection == wxNOT_FOUND) {
selection = 0;
}
Starpounds::WeightStage &stage = m_stages.at(selection);
stage.SetLegDescription(m_descriptionLeg->GetValue().ToStdString());
}
void StagesPanel::OnResetWeightStages(wxCommandEvent &WXUNUSED(event)) {
DoResetWeightStages();
}
} // namespace SpeciesGen

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*
speciesgen
Copyright (C) 2022 prisixia
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
@ -20,17 +20,16 @@ along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
#include "starbound/frames.h"
namespace Starbound {
namespace Frames {
namespace Starbound::Frames {
//----------------------------------------------------------------------
// Grid
//----------------------------------------------------------------------
Grid::Grid(const std::vector<std::vector<std::optional<std::string>>> names,
Grid::Grid(std::vector<std::vector<std::optional<std::string>>> names,
const std::tuple<uint32_t, uint32_t> size,
const std::tuple<uint32_t, uint32_t> dimensions)
: m_size(size), m_dimensions(dimensions), m_names(names) {}
: m_size(size), m_dimensions(dimensions), m_names(std::move(names)) {}
std::tuple<uint32_t, uint32_t> Grid::GetSize() const { return m_size; }
@ -49,57 +48,16 @@ void Grid::SetDimensions(const std::tuple<uint32_t, uint32_t> dimensions) {
}
void Grid::SetNames(
const std::vector<std::vector<std::optional<std::string>>> names) {
const std::vector<std::vector<std::optional<std::string>>> &names) {
m_names = names;
}
void Grid::Serialize(const std::filesystem::path path) const {
std::ofstream file(path);
rapidjson::BasicOStreamWrapper wrapper(file);
rapidjson::PrettyWriter writer(wrapper);
writer.StartObject();
this->Serialize(writer);
writer.EndObject();
}
template <typename Writer> void Grid::Serialize(Writer &writer) const {
const std::tuple<uint32_t, uint32_t> size = m_size;
const std::tuple<uint32_t, uint32_t> dimensions = m_dimensions;
const std::vector<std::vector<std::optional<std::string>>> names = m_names;
writer.Key(RAPIDJSON_STRINGIFY(size));
writer.StartArray();
writer.Uint(std::get<0>(size));
writer.Uint(std::get<1>(size));
writer.EndArray();
writer.Key(RAPIDJSON_STRINGIFY(dimensions));
writer.StartArray();
writer.Uint(std::get<0>(dimensions));
writer.Uint(std::get<1>(dimensions));
writer.EndArray();
writer.Key(RAPIDJSON_STRINGIFY(names));
writer.StartArray();
for (auto &vec : names) {
writer.StartArray();
for (auto &name : vec) {
if (name.has_value())
writer.String(name.value().c_str());
else
writer.Null();
}
writer.EndArray();
}
writer.EndArray();
}
//----------------------------------------------------------------------
// Frames
//----------------------------------------------------------------------
Frames::Frames(const std::unordered_map<std::string, std::string> aliases,
const Grid grid)
: m_aliases(aliases), m_grid(grid) {}
Frames::Frames(std::unordered_map<std::string, std::string> aliases, Grid grid)
: m_aliases(std::move(aliases)), m_grid(std::move(grid)) {}
std::unordered_map<std::string, std::string> Frames::GetAliases() const {
return m_aliases;
@ -108,37 +66,9 @@ std::unordered_map<std::string, std::string> Frames::GetAliases() const {
Grid Frames::GetGrid() const { return m_grid; }
void Frames::SetAliases(
const std::unordered_map<std::string, std::string> aliases) {
const std::unordered_map<std::string, std::string> &aliases) {
m_aliases = aliases;
}
void Frames::SetGrid(const Grid grid) { m_grid = grid; }
void Frames::Serialize(const std::filesystem::path path) const {
std::ofstream file(path);
rapidjson::BasicOStreamWrapper wrapper(file);
rapidjson::PrettyWriter writer(wrapper);
writer.StartObject();
this->Serialize(writer);
writer.EndObject();
}
template <typename Writer> void Frames::Serialize(Writer &writer) const {
const std::unordered_map<std::string, std::string> aliases = m_aliases;
const Grid grid = m_grid;
writer.Key(RAPIDJSON_STRINGIFY(aliases));
writer.StartObject();
for (auto &it : aliases) {
writer.Key(it.first.c_str());
writer.String(it.second.c_str());
}
writer.EndObject();
writer.Key(RAPIDJSON_STRINGIFY(grid));
writer.StartObject();
grid.Serialize(writer);
writer.EndObject();
}
} // namespace Frames
} // namespace Starbound
void Frames::SetGrid(const Grid &grid) { m_grid = grid; }
} // namespace Starbound::Frames

View File

@ -1,6 +1,6 @@
/*
speciesgen
Copyright (C) 2022 prisixia
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
@ -20,17 +20,18 @@ along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
#include "starbound/item.h"
namespace Starbound {
namespace Item {
namespace Starbound::Item {
//----------------------------------------------------------------------
// Frames
//----------------------------------------------------------------------
Frames::Frames(const std::filesystem::path body,
const std::filesystem::path backSleeve,
const std::filesystem::path frontSleeve)
: m_body(body), m_backSleeve(backSleeve), m_frontSleeve(frontSleeve) {}
Frames::Frames(std::filesystem::path body) : m_body(std::move(body)) {}
Frames::Frames(std::filesystem::path body, std::filesystem::path backSleeve,
std::filesystem::path frontSleeve)
: m_body(std::move(body)), m_backSleeve(std::move(backSleeve)),
m_frontSleeve(std::move(frontSleeve)) {}
std::filesystem::path Frames::GetBody() const { return m_body; }
@ -38,55 +39,33 @@ std::filesystem::path Frames::GetBackSleeve() const { return m_backSleeve; }
std::filesystem::path Frames::GetFrontSleeve() const { return m_frontSleeve; }
void Frames::SetBody(const std::filesystem::path body) { m_body = body; }
void Frames::SetBody(const std::filesystem::path &body) { m_body = body; }
void Frames::SetBackSleeve(const std::filesystem::path backSleeve) {
void Frames::SetBackSleeve(const std::filesystem::path &backSleeve) {
m_backSleeve = backSleeve;
}
void Frames::SetFrontSleeve(const std::filesystem::path frontSleeve) {
void Frames::SetFrontSleeve(const std::filesystem::path &frontSleeve) {
m_frontSleeve = frontSleeve;
}
void Frames::Serialize(const std::filesystem::path path) const {
std::ofstream file(path);
rapidjson::BasicOStreamWrapper wrapper(file);
rapidjson::PrettyWriter writer(wrapper);
writer.StartObject();
this->Serialize(writer);
writer.EndObject();
}
template <typename Writer> void Frames::Serialize(Writer &writer) const {
const std::string body = m_body.string();
const std::string backSleeve = m_backSleeve.string();
const std::string frontSleeve = m_frontSleeve.string();
writer.Key(RAPIDJSON_STRINGIFY(body));
writer.String(body.c_str(),
static_cast<rapidjson::SizeType>(body.length()));
writer.Key(RAPIDJSON_STRINGIFY(backSleeve));
writer.String(backSleeve.c_str(),
static_cast<rapidjson::SizeType>(backSleeve.length()));
writer.Key(RAPIDJSON_STRINGIFY(frontSleeve));
writer.String(frontSleeve.c_str(),
static_cast<rapidjson::SizeType>(frontSleeve.length()));
}
//----------------------------------------------------------------------
// Item
//----------------------------------------------------------------------
Item::Item(const std::string itemName,
const std::filesystem::path inventoryIcon, const Category category,
const std::string description, const std::string shortDescription,
const Frames maleFrames, const Frames femaleFrames)
: m_itemName(itemName), m_price(0), m_inventoryIcon(inventoryIcon),
m_maxStack(0), m_rarity(Rarity::Essential), m_category(category),
m_description(description), m_shortDescription(shortDescription),
m_tooltipKind(TooltipKind::Armor), m_maleFrames(maleFrames),
m_femaleFrames(femaleFrames) {}
Item::Item(std::string itemName, const Rarity rarity)
: m_itemName(std::move(itemName)), m_price(0), m_maxStack(1), m_rarity(rarity) {}
Item::Item(std::string itemName, std::filesystem::path inventoryIcon,
const Category category, std::string description,
std::string shortDescription, Frames maleFrames, Frames femaleFrames)
: m_itemName(std::move(itemName)), m_price(0),
m_inventoryIcon(std::move(inventoryIcon)), m_maxStack(1),
m_rarity(Rarity::Essential), m_category(category),
m_description(std::move(description)),
m_shortDescription(std::move(shortDescription)),
m_tooltipKind(TooltipKind::Armor), m_maleFrames(std::move(maleFrames)),
m_femaleFrames(std::move(femaleFrames)) {}
std::string Item::GetItemName() const { return m_itemName; }
@ -110,11 +89,11 @@ Frames Item::GetMaleFrames() const { return m_maleFrames; }
Frames Item::GetFemaleFrames() const { return m_femaleFrames; }
void Item::SetItemName(const std::string itemName) { m_itemName = itemName; }
void Item::SetItemName(const std::string &itemName) { m_itemName = itemName; }
void Item::SetPrice(const uint32_t price) { m_price = price; }
void Item::SetInventoryIcon(const std::filesystem::path inventoryIcon) {
void Item::SetInventoryIcon(const std::filesystem::path &inventoryIcon) {
m_inventoryIcon = inventoryIcon;
}
@ -124,11 +103,11 @@ void Item::SetRarity(const Rarity rarity) { m_rarity = rarity; }
void Item::SetCategory(const Category category) { m_category = category; }
void Item::SetDescription(const std::string description) {
void Item::SetDescription(const std::string &description) {
m_description = description;
}
void Item::SetShortDescription(const std::string shortDescription) {
void Item::SetShortDescription(const std::string &shortDescription) {
m_shortDescription = shortDescription;
}
@ -136,91 +115,11 @@ void Item::SetTooltipKind(const TooltipKind tooltipKind) {
m_tooltipKind = tooltipKind;
}
void Item::SetMaleFrames(const Frames maleFrames) { m_maleFrames = maleFrames; }
void Item::SetMaleFrames(const Frames &maleFrames) {
m_maleFrames = maleFrames;
}
void Item::SetFemaleFrames(const Frames femaleFrames) {
void Item::SetFemaleFrames(const Frames &femaleFrames) {
m_femaleFrames = femaleFrames;
}
void Item::Serialize(const std::filesystem::path path) const {
std::ofstream file(path);
rapidjson::BasicOStreamWrapper wrapper(file);
rapidjson::PrettyWriter writer(wrapper);
writer.StartObject();
this->Serialize(writer);
writer.EndObject();
}
template <typename Writer> void Item::Serialize(Writer &writer) const {
const std::string itemName = m_itemName;
const uint32_t price = m_price;
const std::string inventoryIcon = m_inventoryIcon.string();
const uint16_t maxStack = m_maxStack;
std::string rarity =
static_cast<std::string>(magic_enum::enum_name(m_rarity));
std::string category =
static_cast<std::string>(magic_enum::enum_name(m_category));
const std::string description = m_description;
const std::string shortdescription = m_shortDescription;
std::string tooltipKind =
static_cast<std::string>(magic_enum::enum_name(m_tooltipKind));
const Starbound::Item::Frames maleFrames = m_maleFrames;
const Starbound::Item::Frames femaleFrames = m_femaleFrames;
std::for_each(rarity.begin(), rarity.end(),
[](char &c) { c = ::tolower(c); });
std::for_each(category.begin(), category.end(),
[](char &c) { c = ::tolower(c); });
std::for_each(tooltipKind.begin(), tooltipKind.end(),
[](char &c) { c = ::tolower(c); });
writer.Key(RAPIDJSON_STRINGIFY(itemName));
writer.String(itemName.c_str(),
static_cast<rapidjson::SizeType>(itemName.length()));
writer.Key(RAPIDJSON_STRINGIFY(price));
writer.Uint(price);
writer.Key(RAPIDJSON_STRINGIFY(inventoryIcon));
writer.String(inventoryIcon.c_str(),
static_cast<rapidjson::SizeType>(inventoryIcon.length()));
writer.Key(RAPIDJSON_STRINGIFY(maxStack));
writer.Uint(price);
writer.Key(RAPIDJSON_STRINGIFY(rarity));
writer.String(rarity.c_str(),
static_cast<rapidjson::SizeType>(rarity.length()));
writer.Key(RAPIDJSON_STRINGIFY(category));
writer.String(category.c_str(),
static_cast<rapidjson::SizeType>(category.length()));
writer.Key(RAPIDJSON_STRINGIFY(description));
writer.String(description.c_str(),
static_cast<rapidjson::SizeType>(description.length()));
writer.Key(RAPIDJSON_STRINGIFY(shortdescription));
writer.String(shortdescription.c_str(),
static_cast<rapidjson::SizeType>(shortdescription.length()));
writer.Key(RAPIDJSON_STRINGIFY(tooltipKind));
writer.String(tooltipKind.c_str(),
static_cast<rapidjson::SizeType>(tooltipKind.length()));
writer.Key(RAPIDJSON_STRINGIFY(maleFrames));
// TODO: Make that better, idk, at least it works for now
if (m_category == Category::Chestwear) {
writer.StartObject();
maleFrames.Serialize(writer);
writer.EndObject();
} else {
const std::string body = maleFrames.GetBody().string();
writer.String(body.c_str(),
static_cast<rapidjson::SizeType>(body.length()));
}
writer.Key(RAPIDJSON_STRINGIFY(femaleFrames));
if (m_category == Category::Chestwear) {
writer.StartObject();
femaleFrames.Serialize(writer);
writer.EndObject();
} else {
const std::string body = femaleFrames.GetBody().string();
writer.String(body.c_str(),
static_cast<rapidjson::SizeType>(body.length()));
}
}
} // namespace Item
} // namespace Starbound
} // namespace Starbound::Item

View File

@ -1,6 +1,6 @@
/*
speciesgen
Copyright (C) 2022 prisixia
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
@ -26,13 +26,14 @@ namespace Starbound {
// Metadata
//----------------------------------------------------------------------
Metadata::Metadata(const std::string name, const std::string friendlyName,
const std::string author, const std::string description,
const std::string version, const std::string link,
const std::vector<std::string> requires)
: m_name(name), m_friendlyName(friendlyName), m_author(author),
m_description(description), m_version(version), m_link(link),
m_requires(requires) {}
Metadata::Metadata(std::string name, std::string friendlyName,
std::string author, std::string description,
std::string version, std::string link,
std::vector<std::string> _requires)
: m_name(std::move(name)), m_friendlyName(std::move(friendlyName)),
m_author(std::move(author)), m_description(std::move(description)),
m_version(std::move(version)), m_link(std::move(link)),
m_requires(std::move(_requires)), m_priority(0) {}
std::string Metadata::GetName() const { return m_name; }
@ -46,71 +47,45 @@ std::string Metadata::GetVersion() const { return m_version; }
std::string Metadata::GetLink() const { return m_link; }
std::string Metadata::GetSteamContentID() const { return m_steamContentId; }
std::string Metadata::GetTags() const { return m_tags; }
std::vector<std::string> Metadata::GetIncludes() const { return m_includes; }
std::vector<std::string> Metadata::GetRequires() const { return m_requires; }
void Metadata::SetName(const std::string name) { m_name = name; }
uint32_t Metadata::GetPriority() const { return m_priority; }
void Metadata::SetFriendlyName(const std::string friendlyName) {
void Metadata::SetName(const std::string &name) { m_name = name; }
void Metadata::SetFriendlyName(const std::string &friendlyName) {
m_friendlyName = friendlyName;
}
void Metadata::SetDescription(const std::string description) {
void Metadata::SetDescription(const std::string &description) {
m_description = description;
}
void Metadata::SetAuthor(const std::string author) { m_author = author; }
void Metadata::SetAuthor(const std::string &author) { m_author = author; }
void Metadata::SetVersion(const std::string version) { m_version = version; }
void Metadata::SetVersion(const std::string &version) { m_version = version; }
void Metadata::SetLink(const std::string link) { m_link = link; }
void Metadata::SetLink(const std::string &link) { m_link = link; }
void Metadata::SetRequires(const std::vector<std::string> requires) {
m_requires = requires;
void Metadata::SetSteamContentID(const std::string &steamContentId) {
m_steamContentId = steamContentId;
}
void Metadata::Serialize(const std::filesystem::path path) const {
std::ofstream file(path);
rapidjson::BasicOStreamWrapper wrapper(file);
rapidjson::PrettyWriter writer(wrapper);
void Metadata::SetTags(const std::string &tags) { m_tags = tags; }
writer.StartObject();
this->Serialize(writer);
writer.EndObject();
void Metadata::SetIncludes(const std::vector<std::string> &includes) {
m_includes = includes;
}
template <typename Writer> void Metadata::Serialize(Writer &writer) const {
const std::string name = m_name;
const std::string friendlyName = m_friendlyName;
const std::string description = m_description;
const std::string author = m_author;
const std::string version = m_version;
const std::string link = m_link;
const std::vector<std::string>
requires = m_requires;
writer.Key(RAPIDJSON_STRINGIFY(name));
writer.String(name.c_str(),
static_cast<rapidjson::SizeType>(name.length()));
writer.Key(RAPIDJSON_STRINGIFY(friendlyName));
writer.String(friendlyName.c_str(),
static_cast<rapidjson::SizeType>(friendlyName.length()));
writer.Key(RAPIDJSON_STRINGIFY(description));
writer.String(description.c_str(),
static_cast<rapidjson::SizeType>(description.length()));
writer.Key(RAPIDJSON_STRINGIFY(author));
writer.String(author.c_str(),
static_cast<rapidjson::SizeType>(author.length()));
writer.Key(RAPIDJSON_STRINGIFY(version));
writer.String(version.c_str(),
static_cast<rapidjson::SizeType>(version.length()));
writer.Key(RAPIDJSON_STRINGIFY(link));
writer.String(link.c_str(),
static_cast<rapidjson::SizeType>(link.length()));
writer.Key(RAPIDJSON_STRINGIFY(requires));
writer.StartArray();
for (auto &require : requires)
writer.String(require.c_str(),
static_cast<rapidjson::SizeType>(require.length()));
writer.EndArray();
void Metadata::SetRequires(const std::vector<std::string> &_requires) {
m_requires = _requires;
}
void Metadata::SetPriority(const uint32_t priority) { m_priority = priority; }
} // namespace Starbound

View File

@ -1,90 +0,0 @@
/*
speciesgen
Copyright (C) 2022 prisixia
This file is part of speciesgen.
speciesgen 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.
speciesgen 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 speciesgen. If not, see <https://www.gnu.org/licenses/>.
*/
#include "starbound/patch.h"
namespace Starbound {
namespace Patch {
//----------------------------------------------------------------------
// Patch
//----------------------------------------------------------------------
Patch::Patch(std::string path, Operation op) : m_op(op), m_path(path) {}
Operation Patch::GetOperation() const { return m_op; }
std::string Patch::GetPath() const { return m_path; }
std::string Patch::GetOverride() const { return m_override; }
std::string Patch::GetOverrideDirectives() const {
return m_overrideDirectives;
}
void Patch::SetOperation(const Operation op) { m_op = op; }
void Patch::SetPath(const std::string path) { m_path = path; }
void Patch::SetOverride(const std::string override) { m_override = override; }
void Patch::SetOverrideDirectives(const std::string overrideDirectives) {
m_overrideDirectives = overrideDirectives;
}
void Patch::Serialize(const std::filesystem::path path) const {
std::ofstream file(path);
rapidjson::BasicOStreamWrapper wrapper(file);
rapidjson::PrettyWriter writer(wrapper);
writer.StartObject();
this->Serialize(writer);
writer.EndObject();
}
template <typename Writer> void Patch::Serialize(Writer &writer) const {
std::string op =
static_cast<std::string>(magic_enum::enum_name(m_op)).c_str();
const std::string path = m_path;
const std::string override = m_override;
const std::string overrideDirectives = m_overrideDirectives;
std::for_each(op.begin(), op.end(), [](char &c) { c = ::tolower(c); });
writer.Key(RAPIDJSON_STRINGIFY(op));
writer.String(op.c_str(), static_cast<rapidjson::SizeType>(op.length()));
writer.Key(RAPIDJSON_STRINGIFY(path));
writer.String(path.c_str(),
static_cast<rapidjson::SizeType>(path.length()));
writer.Key(RAPIDJSON_STRINGIFY(value));
writer.StartObject();
if (!m_override.empty()) {
writer.Key(RAPIDJSON_STRINGIFY(override));
writer.String(override.c_str(),
static_cast<rapidjson::SizeType>(override.length()));
writer.Key(RAPIDJSON_STRINGIFY(overrideDirectives));
writer.String(
overrideDirectives.c_str(),
static_cast<rapidjson::SizeType>(overrideDirectives.length()));
}
writer.EndObject();
}
} // namespace Patch
} // namespace Starbound

View File

@ -0,0 +1,50 @@
/*
speciesgen
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
speciesgen 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.
speciesgen 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 speciesgen. If not, see <https://www.gnu.org/licenses/>.
*/
#include "starpounds/species.h"
namespace Starpounds {
SpeciesConfig::SpeciesConfig(const bool fullbright)
: m_fullbright(fullbright) {}
SpeciesConfig::SpeciesConfig(std::string _override, const bool fullbright)
: m_fullbright(fullbright), m_override(std::move(_override)) {}
SpeciesConfig::SpeciesConfig(std::string _override,
std::string overrideDirectives,
const bool fullbright)
: m_fullbright(fullbright), m_override(std::move(_override)),
m_overrideDirectives(std::move(overrideDirectives)) {}
bool SpeciesConfig::GetFullbright() const { return m_fullbright; }
std::string SpeciesConfig::GetOverride() const { return m_override; }
std::string SpeciesConfig::GetOverrideDirectives() const {
return m_overrideDirectives;
}
void SpeciesConfig::SetFullbright(const bool fullbright) {
m_fullbright = fullbright;
}
void SpeciesConfig::SetOverride(const std::string &_override) {
m_override = _override;
}
void SpeciesConfig::SetOverrideDirectives(
const std::string &overrideDirectives) {
m_overrideDirectives = overrideDirectives;
}
} // namespace Starpounds

View File

@ -1,6 +1,6 @@
/*
speciesgen
Copyright (C) 2022 prisixia
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
@ -20,8 +20,7 @@ along with speciesgen. If not, see <https://www.gnu.org/licenses/>.
#include "starpounds/types.h"
namespace Starpounds {
namespace Types {
namespace Starpounds::Types {
std::string AsString(const Subs type) {
std::string type_str =
static_cast<std::string>(magic_enum::enum_name(type));
@ -51,5 +50,4 @@ Chests AsChest(const Subs type) {
return Chests::Belly;
}
}
} // namespace Types
} // namespace Starpounds
} // namespace Starpounds::Types

View File

@ -1,6 +1,6 @@
/*
speciesgen
Copyright (C) 2022 prisixia
Copyright (C) 2022-2023 prisixia
This file is part of speciesgen.
@ -26,21 +26,20 @@ namespace Starpounds {
// WeightStageSub
//----------------------------------------------------------------------
WeightStageSub::WeightStageSub(const std::string name,
const std::string friendlyName,
const std::string descriptionChest,
WeightStageSub::WeightStageSub(std::string name, std::string friendlyName,
std::string descriptionChest,
const Types::Chests typeChest)
: m_name(name), m_friendlyName(friendlyName),
m_descriptionChest(descriptionChest), m_typeChest(typeChest) {}
: m_name(std::move(name)), m_friendlyName(std::move(friendlyName)),
m_descriptionChest(std::move(descriptionChest)), m_typeChest(typeChest) {}
WeightStageSub::WeightStageSub(const std::string name)
: m_name(name), m_friendlyName(""), m_descriptionChest(""),
m_typeChest(Types::Chests::Chest) {}
WeightStageSub::WeightStageSub(std::string name)
: m_name(std::move(name)), m_typeChest(Types::Chests::Chest) {}
WeightStageSub::WeightStageSub(const Types::Subs type,
const std::string descriptionChest)
std::string descriptionChest)
: m_name(Types::AsString(type)), m_friendlyName(Types::AsFriendly(type)),
m_descriptionChest(descriptionChest), m_typeChest(Types::AsChest(type)) {}
m_descriptionChest(std::move(descriptionChest)),
m_typeChest(Types::AsChest(type)) {}
std::string WeightStageSub::GetName() const { return m_name; }
@ -52,13 +51,13 @@ std::string WeightStageSub::GetChestDescription() const {
Types::Chests WeightStageSub::GetChestType() const { return m_typeChest; }
void WeightStageSub::SetName(const std::string name) { m_name = name; }
void WeightStageSub::SetName(const std::string &name) { m_name = name; }
void WeightStageSub::SetFriendlyName(const std::string friendlyName) {
void WeightStageSub::SetFriendlyName(const std::string &friendlyName) {
m_friendlyName = friendlyName;
}
void WeightStageSub::SetChestDescription(const std::string descriptionChest) {
void WeightStageSub::SetChestDescription(const std::string &descriptionChest) {
m_descriptionChest = descriptionChest;
}
@ -66,56 +65,25 @@ void WeightStageSub::SetChestType(const Types::Chests typeChest) {
m_typeChest = typeChest;
}
void WeightStageSub::Serialize(const std::filesystem::path path) const {
std::ofstream file(path);
rapidjson::BasicOStreamWrapper wrapper(file);
rapidjson::PrettyWriter writer(wrapper);
writer.StartObject();
this->Serialize(writer);
writer.EndObject();
}
template <typename Writer>
void WeightStageSub::Serialize(Writer &writer) const {
const std::string name = m_name;
const std::string friendly_name = m_friendlyName;
const std::string desc_chest = m_descriptionChest;
const std::string type_chest =
static_cast<std::string>(magic_enum::enum_name(m_typeChest));
writer.Key(RAPIDJSON_STRINGIFY(name));
writer.String(name.c_str(),
static_cast<rapidjson::SizeType>(name.length()));
writer.Key(RAPIDJSON_STRINGIFY(friendly_name));
writer.String(friendly_name.c_str(),
static_cast<rapidjson::SizeType>(friendly_name.length()));
writer.Key(RAPIDJSON_STRINGIFY(desc_chest));
writer.String(desc_chest.c_str(),
static_cast<rapidjson::SizeType>(desc_chest.length()));
writer.Key(RAPIDJSON_STRINGIFY(type_chest));
writer.String(type_chest.c_str(),
static_cast<rapidjson::SizeType>(type_chest.length()));
}
//----------------------------------------------------------------------
// WeightStage
//----------------------------------------------------------------------
WeightStage::WeightStage(const std::string name, const std::string friendlyName,
const std::string descriptionChest,
WeightStage::WeightStage(const std::string &name,
const std::string &friendlyName,
const std::string &descriptionChest,
const Types::Chests typeChest,
const std::string descriptionLeg,
const Types::Legs typeLeg, const bool frames,
const bool id, const std::vector<WeightStageSub> subs)
std::string descriptionLeg, const Types::Legs typeLeg,
const bool frames, const bool id,
std::vector<WeightStageSub> subs)
: WeightStageSub(name, friendlyName, descriptionChest, typeChest),
m_descriptionLeg(descriptionLeg), m_typeLeg(typeLeg), m_frames(frames),
m_id(id), m_subs(subs) {}
m_descriptionLeg(std::move(descriptionLeg)), m_typeLeg(typeLeg),
m_frames(frames), m_id(id), m_subs(std::move(subs)) {}
WeightStage::WeightStage(const std::string name, const bool frames,
const bool id, const std::vector<WeightStageSub> subs)
: WeightStageSub(name), m_descriptionLeg(""), m_typeLeg(Types::Legs::Legs),
m_frames(frames), m_id(id), m_subs(subs) {}
WeightStage::WeightStage(const std::string &name, const bool frames,
const bool id, std::vector<WeightStageSub> subs)
: WeightStageSub(name), m_typeLeg(Types::Legs::Legs), m_frames(frames),
m_id(id), m_subs(std::move(subs)) {}
std::string WeightStage::GetLegDescription() const { return m_descriptionLeg; }
@ -127,7 +95,7 @@ bool WeightStage::HasID() const { return m_id; }
std::vector<WeightStageSub> WeightStage::GetSubs() const { return m_subs; }
void WeightStage::SetLegDescription(const std::string descriptionLeg) {
void WeightStage::SetLegDescription(const std::string &descriptionLeg) {
m_descriptionLeg = descriptionLeg;
}
@ -137,94 +105,7 @@ void WeightStage::SetFrames(const bool frames) { m_frames = frames; }
void WeightStage::SetID(const bool id) { m_id = id; }
void WeightStage::SetSubs(const std::vector<WeightStageSub> subs) {
void WeightStage::SetSubs(const std::vector<WeightStageSub> &subs) {
m_subs = subs;
}
void WeightStage::Serialize(const std::filesystem::path path) const {
std::ofstream file(path);
rapidjson::BasicOStreamWrapper wrapper(file);
rapidjson::PrettyWriter writer(wrapper);
writer.StartObject();
this->Serialize(writer);
writer.EndObject();
}
template <typename Writer> void WeightStage::Serialize(Writer &writer) const {
const std::string name = m_name;
const std::string friendly_name = m_friendlyName;
const std::string desc_chest = m_descriptionChest;
const std::string desc_leg = m_descriptionLeg;
const std::string type_chest =
static_cast<std::string>(magic_enum::enum_name(m_typeChest));
const std::string type_leg =
static_cast<std::string>(magic_enum::enum_name(m_typeLeg));
const bool frames = m_frames;
const bool id = m_id;
const std::vector<WeightStageSub> subs = m_subs;
writer.Key(RAPIDJSON_STRINGIFY(name));
writer.String(name.c_str(),
static_cast<rapidjson::SizeType>(name.length()));
if (id) {
writer.Key(RAPIDJSON_STRINGIFY(friendly_name));
writer.String(friendly_name.c_str(),
static_cast<rapidjson::SizeType>(friendly_name.length()));
writer.Key(RAPIDJSON_STRINGIFY(desc_chest));
writer.String(desc_chest.c_str(),
static_cast<rapidjson::SizeType>(desc_chest.length()));
writer.Key(RAPIDJSON_STRINGIFY(desc_leg));
writer.String(desc_leg.c_str(),
static_cast<rapidjson::SizeType>(desc_leg.length()));
writer.Key(RAPIDJSON_STRINGIFY(type_chest));
writer.String(type_chest.c_str(),
static_cast<rapidjson::SizeType>(type_chest.length()));
writer.Key(RAPIDJSON_STRINGIFY(type_leg));
writer.String(type_leg.c_str(),
static_cast<rapidjson::SizeType>(type_leg.length()));
}
writer.Key(RAPIDJSON_STRINGIFY(frames));
writer.Bool(frames);
writer.Key(RAPIDJSON_STRINGIFY(id));
writer.Bool(id);
if (!subs.empty()) {
writer.Key(RAPIDJSON_STRINGIFY(subs));
writer.StartArray();
for (const WeightStageSub &sub : subs) {
writer.StartObject();
sub.Serialize(writer);
writer.EndObject();
}
writer.EndArray();
}
}
// TODO: Get proper deserialization to work
/*
void WeightStage::Deserialize(const std::filesystem::path path)
{
std::ifstream file(path);
std::stringstream buffer;
buffer << file.rdbuf();
file.close();
rapidjson::Document doc;
doc.Parse(buffer.str().c_str());
Deserialize(doc);
}
void WeightStage::Deserialize(const rapidjson::Value &value)
{
m_name = value["name"].GetString();
m_friendlyName = value["friendly_name"].GetString();
m_descriptionChest = value["desc_chest"].GetString();
m_descriptionLeg = value["desc_leg"].GetString();
m_frames = value["frames"].GetBool();
m_id = value["id"].GetBool();
}
*/
} // namespace Starpounds

1
thirdparty/cereal vendored Submodule

@ -0,0 +1 @@
Subproject commit ebef1e929807629befafbb2918ea1a08c7194554

@ -1 +0,0 @@
Subproject commit f54b0e47a08782a6131cc3d60f94d038fa6e0a51