Compare commits
No commits in common. "f522d20dd40df9db44fc52770cae2ec0a2723ecf" and "de2ba9ce7ffb2e5fe32d88d86e3a7c8865ebbec9" have entirely different histories.
f522d20dd4
...
de2ba9ce7f
9 changed files with 987 additions and 1110 deletions
|
@ -116,9 +116,6 @@ add_executable(MassBuilderSaveTool WIN32
|
|||
SaveTool/SaveTool_drawMainMenu.cpp
|
||||
SaveTool/SaveTool_MainManager.cpp
|
||||
SaveTool/SaveTool_MassViewer.cpp
|
||||
SaveTool/SaveTool_MassViewer_Frame.cpp
|
||||
SaveTool/SaveTool_MassViewer_Armour.cpp
|
||||
SaveTool/SaveTool_MassViewer_Weapons.cpp
|
||||
SaveTool/SaveTool_ProfileManager.cpp
|
||||
ProfileManager/ProfileManager.h
|
||||
ProfileManager/ProfileManager.cpp
|
||||
|
|
|
@ -22,9 +22,7 @@
|
|||
|
||||
using namespace Magnum;
|
||||
|
||||
extern const std::map<Int, const char*> style_names
|
||||
#ifdef STYLENAMES_DEFINITION
|
||||
{
|
||||
static const std::map<Int, const char*> style_names {
|
||||
{0, "Custom Style 1"},
|
||||
{1, "Custom Style 2"},
|
||||
{2, "Custom Style 3"},
|
||||
|
@ -187,6 +185,4 @@ extern const std::map<Int, const char*> style_names
|
|||
{225, "Dark Brown Camo"},
|
||||
{226, "Blue Camo"},
|
||||
{227, "Dark Blue Camo"},
|
||||
}
|
||||
#endif
|
||||
;
|
||||
};
|
||||
|
|
|
@ -832,6 +832,7 @@ void Mass::getGlobalStyles() {
|
|||
|
||||
if(global_styles->items.size() != _globalStyles.size()) {
|
||||
_globalStyles = Containers::Array<CustomStyle>{global_styles->items.size()};
|
||||
return;
|
||||
}
|
||||
|
||||
getCustomStyles(_globalStyles, global_styles);
|
||||
|
|
|
@ -105,9 +105,6 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
|
|||
auto drawRenamePopup(Containers::ArrayView<char> name_view) -> bool;
|
||||
void drawGeneralInfo();
|
||||
void drawResearchInventory();
|
||||
template<typename Getter, typename Setter>
|
||||
void drawMaterialRow(const char* name, Int tier, Getter getter, Setter setter);
|
||||
void drawUnavailableMaterialRow(const char* name, Int tier);
|
||||
void drawMassManager();
|
||||
auto drawDeleteMassPopup(int mass_index) -> ImGuiID;
|
||||
auto drawDeleteStagedMassPopup(const std::string& filename) -> ImGuiID;
|
||||
|
@ -121,7 +118,6 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
|
|||
void drawArmour();
|
||||
void drawCustomArmourStyles();
|
||||
void drawWeapons();
|
||||
void drawWeaponCategory(const char* name, Containers::ArrayView<Weapon> weapons_view, bool& dirty, const char* payload_type, const char* payload_tooltip);
|
||||
void drawWeaponEditor(Weapon& weapon);
|
||||
void drawGlobalStyles();
|
||||
void drawTuning();
|
||||
|
@ -239,8 +235,6 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
|
|||
Containers::Pointer<MassManager> _massManager;
|
||||
Mass* _currentMass{nullptr};
|
||||
|
||||
Weapon* _currentWeapon = nullptr;
|
||||
|
||||
Containers::Pointer<efsw::FileWatcher> _fileWatcher;
|
||||
enum watchID {
|
||||
SaveDir = 0,
|
||||
|
|
|
@ -287,6 +287,44 @@ void SaveTool::drawResearchInventory() {
|
|||
return;
|
||||
}
|
||||
|
||||
#define unavRow(name, tier) \
|
||||
ImGui::TableNextRow(); \
|
||||
ImGui::TableSetColumnIndex(0); \
|
||||
ImGui::TextUnformatted("T" #tier); \
|
||||
ImGui::TableSetColumnIndex(1); \
|
||||
ImGui::TextUnformatted(name); \
|
||||
ImGui::TableSetColumnIndex(2); \
|
||||
ImGui::TextDisabled("Unavailable as of game version " SUPPORTED_GAME_VERSION);
|
||||
|
||||
#define matRow(name, tier, var, getter, setter) \
|
||||
ImGui::TableNextRow(); \
|
||||
ImGui::TableSetColumnIndex(0); \
|
||||
ImGui::TextUnformatted("T" #tier); \
|
||||
ImGui::TableSetColumnIndex(1); \
|
||||
ImGui::TextUnformatted(name); \
|
||||
ImGui::TableSetColumnIndex(2); \
|
||||
if(_currentProfile->getter() != -1) { \
|
||||
ImGui::Text("%i", _currentProfile->getter()); \
|
||||
if(_cheatMode) { \
|
||||
ImGui::TableSetColumnIndex(3); \
|
||||
ImGui::PushID(#setter); \
|
||||
static Int var = _currentProfile->getter(); \
|
||||
if(drawUnsafeWidget(ImGui::SmallButton, ICON_FA_EDIT)) { \
|
||||
(var) = _currentProfile->getter(); \
|
||||
ImGui::OpenPopup("int_edit"); \
|
||||
} \
|
||||
if(drawIntEditPopup(&(var), 9999)) { \
|
||||
if(!_currentProfile->set##setter((var))) { \
|
||||
_queue.addToast(Toast::Type::Error, _currentProfile->lastError()); \
|
||||
} \
|
||||
} \
|
||||
ImGui::PopID(); \
|
||||
} \
|
||||
} \
|
||||
else { \
|
||||
ImGui::TextDisabled("Not found in the save file"); \
|
||||
}
|
||||
|
||||
if(ImGui::BeginTable("##ResearchInventoryTable", 4,
|
||||
ImGuiTableFlags_BordersOuter|ImGuiTableFlags_ScrollY|ImGuiTableFlags_BordersInnerH))
|
||||
{
|
||||
|
@ -299,136 +337,55 @@ void SaveTool::drawResearchInventory() {
|
|||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("Engine materials");
|
||||
|
||||
drawMaterialRow("Verse steel", 1,
|
||||
[this]{ return _currentProfile->verseSteel(); },
|
||||
[this](Int amount){ return _currentProfile->setVerseSteel(amount); });
|
||||
drawMaterialRow("Undinium", 2,
|
||||
[this]{ return _currentProfile->undinium(); },
|
||||
[this](Int amount){ return _currentProfile->setUndinium(amount); });
|
||||
drawMaterialRow("Necrium alloy", 3,
|
||||
[this]{ return _currentProfile->necriumAlloy(); },
|
||||
[this](Int amount){ return _currentProfile->setNecriumAlloy(amount); });
|
||||
drawMaterialRow("Lunarite", 4,
|
||||
[this]{ return _currentProfile->lunarite(); },
|
||||
[this](Int amount){ return _currentProfile->setLunarite(amount); });
|
||||
drawMaterialRow("Asterite", 5,
|
||||
[this]{ return _currentProfile->asterite(); },
|
||||
[this](Int amount){ return _currentProfile->setAsterite(amount); });
|
||||
drawUnavailableMaterialRow("Hallite fragma", 6);
|
||||
drawUnavailableMaterialRow("Unnoctinium", 7);
|
||||
matRow("Verse steel", 1, verse_steel, verseSteel, VerseSteel)
|
||||
matRow("Undinium", 2, undinium, undinium, Undinium)
|
||||
matRow("Necrium alloy", 3, necrium_alloy, necriumAlloy, NecriumAlloy)
|
||||
matRow("Lunarite", 4, lunarite, lunarite, Lunarite)
|
||||
matRow("Asterite", 5, asterite, asterite, Asterite)
|
||||
unavRow("Hallite fragma", 6)
|
||||
unavRow("Unnoctinium", 7)
|
||||
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("OS materials");
|
||||
|
||||
drawMaterialRow("Ednil", 1,
|
||||
[this]{ return _currentProfile->ednil(); },
|
||||
[this](Int amount){ return _currentProfile->setEdnil(amount); });
|
||||
drawMaterialRow("Nuflalt", 2,
|
||||
[this]{ return _currentProfile->nuflalt(); },
|
||||
[this](Int amount){ return _currentProfile->setNuflalt(amount); });
|
||||
drawMaterialRow("Aurelene", 3,
|
||||
[this]{ return _currentProfile->aurelene(); },
|
||||
[this](Int amount){ return _currentProfile->setAurelene(amount); });
|
||||
drawMaterialRow("Soldus", 4,
|
||||
[this]{ return _currentProfile->soldus(); },
|
||||
[this](Int amount){ return _currentProfile->setSoldus(amount); });
|
||||
drawMaterialRow("Synthesized N", 5,
|
||||
[this]{ return _currentProfile->synthesisedN(); },
|
||||
[this](Int amount){ return _currentProfile->setSynthesisedN(amount); });
|
||||
drawUnavailableMaterialRow("Nanoc", 6);
|
||||
drawUnavailableMaterialRow("Abyssillite", 7);
|
||||
matRow("Ednil", 1, ednil, ednil, Ednil)
|
||||
matRow("Nuflalt", 2, nuflalt, nuflalt, Nuflalt)
|
||||
matRow("Aurelene", 3, aurelene, aurelene, Aurelene)
|
||||
matRow("Soldus", 4, soldus, soldus, Soldus)
|
||||
matRow("Synthesized N", 5, synthesised_n, synthesisedN, SynthesisedN)
|
||||
unavRow("Nanoc", 6)
|
||||
unavRow("Abyssillite", 7)
|
||||
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("Architect materials");
|
||||
|
||||
drawMaterialRow("Alcarbonite", 1,
|
||||
[this]{ return _currentProfile->alcarbonite(); },
|
||||
[this](Int amount){ return _currentProfile->setAlcarbonite(amount); });
|
||||
drawMaterialRow("Keripehene", 2,
|
||||
[this]{ return _currentProfile->keriphene(); },
|
||||
[this](Int amount){ return _currentProfile->setKeriphene(amount); });
|
||||
drawMaterialRow("Nitinol-CM", 3,
|
||||
[this]{ return _currentProfile->nitinolCM(); },
|
||||
[this](Int amount){ return _currentProfile->setNitinolCM(amount); });
|
||||
drawMaterialRow("Quarkium", 4,
|
||||
[this]{ return _currentProfile->quarkium(); },
|
||||
[this](Int amount){ return _currentProfile->setQuarkium(amount); });
|
||||
drawMaterialRow("Alterene", 5,
|
||||
[this]{ return _currentProfile->alterene(); },
|
||||
[this](Int amount){ return _currentProfile->setAlterene(amount); });
|
||||
drawUnavailableMaterialRow("Cosmium", 6);
|
||||
drawUnavailableMaterialRow("Purified quarkium", 7);
|
||||
matRow("Alcarbonite", 1, alcarbonite, alcarbonite, Alcarbonite)
|
||||
matRow("Keriphene", 2, keriphene, keriphene, Keriphene)
|
||||
matRow("Nitinol-CM", 3, nitinol_cm, nitinolCM, NitinolCM)
|
||||
matRow("Quarkium", 4, quarkium, quarkium, Quarkium)
|
||||
matRow("Alterene", 5, alterene, alterene, Alterene)
|
||||
unavRow("Cosmium", 6)
|
||||
unavRow("Purified quarkium", 7)
|
||||
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("Quark data");
|
||||
|
||||
drawMaterialRow("Mixed composition", 1,
|
||||
[this]{ return _currentProfile->mixedComposition(); },
|
||||
[this](Int amount){ return _currentProfile->setMixedComposition(amount); });
|
||||
drawMaterialRow("Void residue", 2,
|
||||
[this]{ return _currentProfile->voidResidue(); },
|
||||
[this](Int amount){ return _currentProfile->setVoidResidue(amount); });
|
||||
drawMaterialRow("Muscular construction", 3,
|
||||
[this]{ return _currentProfile->muscularConstruction(); },
|
||||
[this](Int amount){ return _currentProfile->setMuscularConstruction(amount); });
|
||||
drawMaterialRow("Mineral exoskeletology", 4,
|
||||
[this]{ return _currentProfile->mineralExoskeletology(); },
|
||||
[this](Int amount){ return _currentProfile->setMineralExoskeletology(amount); });
|
||||
drawMaterialRow("Carbonized skin", 5,
|
||||
[this]{ return _currentProfile->carbonisedSkin(); },
|
||||
[this](Int amount){ return _currentProfile->setCarbonisedSkin(amount); });
|
||||
drawUnavailableMaterialRow("Isolated void particle", 6);
|
||||
drawUnavailableMaterialRow("Weaponised physiology", 7);
|
||||
matRow("Mixed composition", 1, mixed_composition, mixedComposition, MixedComposition)
|
||||
matRow("Void residue", 2, void_residue, voidResidue, VoidResidue)
|
||||
matRow("Muscular construction", 3, muscular_construction, muscularConstruction, MuscularConstruction)
|
||||
matRow("Mineral exoskeletology", 4, mineral_exoskeletology, mineralExoskeletology, MineralExoskeletology)
|
||||
matRow("Carbonized skin", 5, carbonised_skin, carbonisedSkin, CarbonisedSkin)
|
||||
unavRow("Isolated void particle", 6)
|
||||
unavRow("Weaponised physiology", 7)
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Getter, typename Setter>
|
||||
void SaveTool::drawMaterialRow(const char* name, Int tier, Getter getter, Setter setter) {
|
||||
static_assert(std::is_same<decltype(getter()), Int>::value, "getter doesn't return an Int, and/or doesn't take zero arguments.");
|
||||
static_assert(std::is_same<decltype(setter(0)), bool>::value, "setter doesn't return a bool, and/or doesn't take a single Int as an argument.");
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Text("T%i", tier);
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::TextUnformatted(name);
|
||||
ImGui::TableSetColumnIndex(2);
|
||||
if(getter() != -1) {
|
||||
ImGui::Text("%i", getter());
|
||||
if(_cheatMode) {
|
||||
ImGui::TableSetColumnIndex(3);
|
||||
ImGui::PushID(name);
|
||||
static Int var = 0;
|
||||
if(drawUnsafeWidget(ImGui::SmallButton, ICON_FA_EDIT)) {
|
||||
(var) = getter();
|
||||
ImGui::OpenPopup("int_edit");
|
||||
}
|
||||
if(drawIntEditPopup(&(var), 9999)) {
|
||||
if(!setter(var)) {
|
||||
_queue.addToast(Toast::Type::Error, _currentProfile->lastError());
|
||||
}
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
else {
|
||||
ImGui::TextDisabled("Not found in the save file");
|
||||
}
|
||||
}
|
||||
|
||||
void SaveTool::drawUnavailableMaterialRow(const char* name, Int tier) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Text("T%i", tier);
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::TextUnformatted(name);
|
||||
ImGui::TableSetColumnIndex(2);
|
||||
ImGui::TextDisabled("Unavailable as of game version " SUPPORTED_GAME_VERSION);
|
||||
#undef unavRow
|
||||
#undef matRow
|
||||
}
|
||||
|
||||
void SaveTool::drawMassManager() {
|
||||
|
|
|
@ -19,18 +19,19 @@
|
|||
#include <Magnum/ImGuiIntegration/Integration.h>
|
||||
|
||||
#include "../Maps/Accessories.h"
|
||||
|
||||
#define STYLENAMES_DEFINITION
|
||||
#include "../Maps/ArmourSets.h"
|
||||
#include "../Maps/StyleNames.h"
|
||||
|
||||
#include "../FontAwesome/IconsFontAwesome5.h"
|
||||
|
||||
#include "SaveTool.h"
|
||||
|
||||
static Weapon* current_weapon = nullptr;
|
||||
|
||||
void SaveTool::drawMassViewer() {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
|
||||
_currentMass = nullptr;
|
||||
_currentWeapon = nullptr;
|
||||
current_weapon = nullptr;
|
||||
_uiState = UiState::MainManager;
|
||||
_queue.addToast(Toast::Type::Error, "The selected M.A.S.S. isn't valid anymore.");
|
||||
return;
|
||||
|
@ -79,7 +80,7 @@ void SaveTool::drawMassViewer() {
|
|||
|
||||
ImGui::TableSetColumnIndex(3);
|
||||
if(ImGui::SmallButton(ICON_FA_TIMES)) {
|
||||
_currentWeapon = nullptr;
|
||||
current_weapon = nullptr;
|
||||
_currentMass = nullptr;
|
||||
_uiState = UiState::MainManager;
|
||||
_jointsDirty = false;
|
||||
|
@ -151,6 +152,917 @@ void SaveTool::drawMassViewer() {
|
|||
ImGui::End();
|
||||
}
|
||||
|
||||
void SaveTool::drawFrameInfo() {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ImGui::BeginChild("##FrameInfo")) {
|
||||
ImGui::EndChild();
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::BeginGroup();
|
||||
|
||||
if(ImGui::BeginChild("##JointSliders", {(ImGui::GetContentRegionAvailWidth() / 2.0f) - (ImGui::GetStyle().WindowPadding.x / 2.0f), 300.0f}, true, ImGuiWindowFlags_MenuBar)) {
|
||||
if(ImGui::BeginMenuBar()) {
|
||||
ImGui::TextUnformatted("Joint sliders");
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
drawJointSliders();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
if(ImGui::BeginChild("##FrameStyles", {(ImGui::GetContentRegionAvailWidth() / 2.0f) - (ImGui::GetStyle().WindowPadding.x / 2.0f), 0.0f}, true, ImGuiWindowFlags_MenuBar)) {
|
||||
if(ImGui::BeginMenuBar()) {
|
||||
ImGui::TextUnformatted("Frame styles");
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
drawFrameStyles();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if(ImGui::BeginChild("##EyeFlare", {0.0f, 0.0f}, true, ImGuiWindowFlags_MenuBar)) {
|
||||
if(ImGui::BeginMenuBar()) {
|
||||
ImGui::TextUnformatted("Eye flare colour");
|
||||
drawHelpMarker("Right-click the picker for more options.", 250.0f);
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
drawEyeColourPicker();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
void SaveTool::drawJointSliders() {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::TextWrapped("In-game values are multiplied by 100.\nFor example, 0.500 here is equal to 50 in-game.");
|
||||
|
||||
if(ImGui::BeginTable("##JointSliderTable", 2, ImGuiTableFlags_Borders)) {
|
||||
ImGui::TableSetupColumn("##SliderLabel", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("##Sliders", ImGuiTableColumnFlags_WidthStretch);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
drawAlignedText("Neck");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::SetNextItemWidth(-1.0f);
|
||||
if(ImGui::SliderFloat("##NeckSlider", &_currentMass->jointSliders().neck, 0.0f, 1.0f)) {
|
||||
_jointsDirty = true;
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
drawAlignedText("Body");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::SetNextItemWidth(-1.0f);
|
||||
if(ImGui::SliderFloat("##BodySlider", &_currentMass->jointSliders().body, 0.0f, 1.0f)) {
|
||||
_jointsDirty = true;
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
drawAlignedText("Shoulders");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::SetNextItemWidth(-1.0f);
|
||||
if(ImGui::SliderFloat("##ShouldersSlider", &_currentMass->jointSliders().shoulders, 0.0f, 1.0f)) {
|
||||
_jointsDirty = true;
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
drawAlignedText("Hips");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::SetNextItemWidth(-1.0f);
|
||||
if(ImGui::SliderFloat("##HipsSlider", &_currentMass->jointSliders().hips, 0.0f, 1.0f)) {
|
||||
_jointsDirty = true;
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
drawAlignedText("Arms");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{2.0f, 1.0f});
|
||||
if(ImGui::BeginTable("##UpperLowerArmsLayoutTable", 2)) {
|
||||
ImGui::TableSetupColumn("##UpperArms", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("##LowerArms", ImGuiTableColumnFlags_WidthStretch);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(-1.0f);
|
||||
if(ImGui::SliderFloat("##UpperArmsSlider", &_currentMass->jointSliders().upperArms, 0.0f, 1.0f, "Upper: %.3f")) {
|
||||
_jointsDirty = true;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(-1.0f);
|
||||
if(ImGui::SliderFloat("##LowerArmsSlider", &_currentMass->jointSliders().lowerArms, 0.0f, 1.0f, "Lower: %.3f")) {
|
||||
_jointsDirty = true;
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
drawAlignedText("Legs");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{2.0f, 1.0f});
|
||||
if(ImGui::BeginTable("##UpperLowerLegsLayoutTable", 2)) {
|
||||
ImGui::TableSetupColumn("##UpperLegs", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("##LowerLegs", ImGuiTableColumnFlags_WidthStretch);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(-1.0f);
|
||||
if(ImGui::SliderFloat("##UpperLegsSlider", &_currentMass->jointSliders().upperLegs, 0.0f, 1.0f, "Upper: %.3f")) {
|
||||
_jointsDirty = true;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(-1.0f);
|
||||
if(ImGui::SliderFloat("##LowerLegsSlider", &_currentMass->jointSliders().lowerLegs, 0.0f, 1.0f, "Lower: %.3f")) {
|
||||
_jointsDirty = true;
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if(!_jointsDirty) {
|
||||
ImGui::BeginDisabled();
|
||||
ImGui::Button(ICON_FA_SAVE " Save");
|
||||
ImGui::SameLine();
|
||||
ImGui::Button(ICON_FA_UNDO " Reset");
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
else {
|
||||
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
||||
if(!_currentMass->writeJointSliders()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
_jointsDirty = false;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if(ImGui::Button(ICON_FA_UNDO " Reset")) {
|
||||
_currentMass->getJointSliders();
|
||||
_jointsDirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SaveTool::drawFrameStyles() {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(Int i = 0; i < 4; i++) {
|
||||
drawAlignedText("Slot %d:", i + 1);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::PushID(i);
|
||||
|
||||
if(ImGui::BeginCombo("##Style", getStyleName(_currentMass->frameStyles()[i], _currentMass->frameCustomStyles()))) {
|
||||
for(const auto& style : style_names) {
|
||||
if(ImGui::Selectable(getStyleName(style.first, _currentMass->frameCustomStyles()), _currentMass->frameStyles()[i] == style.first)) {
|
||||
_currentMass->frameStyles()[i] = style.first;
|
||||
_stylesDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
if(!_stylesDirty) {
|
||||
ImGui::BeginDisabled();
|
||||
ImGui::Button(ICON_FA_SAVE " Save");
|
||||
ImGui::SameLine();
|
||||
ImGui::Button(ICON_FA_UNDO " Reset");
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
else {
|
||||
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
||||
if(!_currentMass->writeFrameStyles()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
_stylesDirty = false;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if(ImGui::Button(ICON_FA_UNDO " Reset")) {
|
||||
_currentMass->getFrameStyles();
|
||||
_stylesDirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SaveTool::drawEyeColourPicker() {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(ImGui::ColorPicker3("##EyeFlarePicker", &_currentMass->eyeFlareColour().x())) {
|
||||
_eyeFlareDirty = true;
|
||||
}
|
||||
|
||||
if(!_eyeFlareDirty) {
|
||||
ImGui::BeginDisabled();
|
||||
ImGui::Button(ICON_FA_SAVE " Save");
|
||||
ImGui::SameLine();
|
||||
ImGui::Button(ICON_FA_UNDO " Reset");
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
else {
|
||||
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
||||
if(!_currentMass->writeEyeFlareColour()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
_eyeFlareDirty = false;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if(ImGui::Button(ICON_FA_UNDO " Reset")) {
|
||||
_currentMass->getEyeFlareColour();
|
||||
_eyeFlareDirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SaveTool::drawCustomFrameStyles() {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ImGui::BeginChild("##FrameStyles")) {
|
||||
ImGui::EndChild();
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::TextWrapped("In-game values are multiplied by 100. For example, 0.500 here is equal to 50 in-game.");
|
||||
|
||||
for(UnsignedInt i = 0; i < _currentMass->frameCustomStyles().size(); i++) {
|
||||
ImGui::PushID(i);
|
||||
DCSResult result;
|
||||
result = drawCustomStyle(_currentMass->frameCustomStyles()[i]);
|
||||
switch(result) {
|
||||
case DCS_ResetStyle:
|
||||
_currentMass->getFrameCustomStyles();
|
||||
break;
|
||||
case DCS_Save:
|
||||
if(!_currentMass->writeFrameCustomStyle(i)) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
void SaveTool::drawArmour() {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(ImGui::Button(ICON_FA_UNDO_ALT " Reset all")) {
|
||||
_currentMass->getArmourParts();
|
||||
}
|
||||
|
||||
if(!ImGui::BeginChild("##ArmourParts")) {
|
||||
ImGui::EndChild();
|
||||
return;
|
||||
}
|
||||
|
||||
static const char* slot_labels[] = {
|
||||
#define c(enumerator, strenum, name) name,
|
||||
#include "../Maps/ArmourSlots.hpp"
|
||||
#undef c
|
||||
};
|
||||
|
||||
for(UnsignedInt i = 0; i < _currentMass->armourParts().size(); i++) {
|
||||
ImGui::PushID(i);
|
||||
|
||||
auto& part = _currentMass->armourParts()[i];
|
||||
|
||||
static char header[129] = {'\0'};
|
||||
|
||||
std::memset(header, '\0', 129);
|
||||
|
||||
if(armour_sets.find(part.id) != armour_sets.cend()) {
|
||||
std::snprintf(header, 128, "%s: %s###%u", slot_labels[UnsignedInt(part.slot)], armour_sets.at(part.id).name, UnsignedInt(part.slot));
|
||||
}
|
||||
else {
|
||||
std::snprintf(header, 128, "%s: %i###%u", slot_labels[UnsignedInt(part.slot)], part.id, UnsignedInt(part.slot));
|
||||
}
|
||||
|
||||
if(ImGui::CollapsingHeader(header)) {
|
||||
ImGui::BeginGroup();
|
||||
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth() * 0.491f);
|
||||
if(ImGui::BeginListBox("##ChangePart")) {
|
||||
if(std::strncmp("Neck", slot_labels[UnsignedInt(part.slot)], 4) != 0) {
|
||||
for(auto& set : armour_sets) {
|
||||
if(ImGui::Selectable(set.second.name, set.first == part.id, ImGuiSelectableFlags_SpanAvailWidth)) {
|
||||
part.id = set.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(auto& set : armour_sets) {
|
||||
if(!set.second.neck_compatible) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(ImGui::Selectable(set.second.name, set.first == part.id, ImGuiSelectableFlags_SpanAvailWidth)) {
|
||||
part.id = set.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndListBox();
|
||||
}
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginGroup();
|
||||
|
||||
ImGui::TextUnformatted("Styles:");
|
||||
|
||||
for(Int j = 0; j < 4; j++) {
|
||||
drawAlignedText("Slot %d:", j + 1);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::PushID(j);
|
||||
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth() - 2.0f);
|
||||
if(ImGui::BeginCombo("##Style", getStyleName(part.styles[j], _currentMass->armourCustomStyles()))) {
|
||||
for(const auto& style : style_names) {
|
||||
if(ImGui::Selectable(getStyleName(style.first, _currentMass->armourCustomStyles()), part.styles[j] == style.first)) {
|
||||
part.styles[j] = style.first;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::PushID("Decal");
|
||||
|
||||
drawAlignedText("Showing/editing decal");
|
||||
for(UnsignedLong j = 0; j < part.decals.size(); j++) {
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton(std::to_string(j + 1).c_str(), &_selectedArmourDecals[i], j);
|
||||
}
|
||||
|
||||
drawDecalEditor(part.decals[_selectedArmourDecals[i]]);
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
if(!part.accessories.size()) {
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::PushID("Accessory");
|
||||
|
||||
drawAlignedText("Showing/editing accessory");
|
||||
for(UnsignedInt j = 0; j < part.accessories.size(); j++) {
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton(std::string{char(65 + j)}.c_str(), &_selectedArmourAccessories[i], j);
|
||||
}
|
||||
|
||||
drawAccessoryEditor(part.accessories[_selectedArmourAccessories[i]], _currentMass->armourCustomStyles());
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
||||
if(!_currentMass->writeArmourPart(part.slot)) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
void SaveTool::drawCustomArmourStyles() {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ImGui::BeginChild("##ArmourStyles")) {
|
||||
ImGui::EndChild();
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::TextWrapped("In-game values are multiplied by 100. For example, 0.500 here is equal to 50 in-game.");
|
||||
|
||||
for(UnsignedInt i = 0; i < _currentMass->armourCustomStyles().size(); i++) {
|
||||
ImGui::PushID(i);
|
||||
DCSResult result;
|
||||
result = drawCustomStyle(_currentMass->armourCustomStyles()[i]);
|
||||
switch(result) {
|
||||
case DCS_ResetStyle:
|
||||
_currentMass->getArmourCustomStyles();
|
||||
break;
|
||||
case DCS_Save:
|
||||
if(_currentMass->writeArmourCustomStyle(i)) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
void SaveTool::drawWeapons() {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
|
||||
current_weapon = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
const Float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
|
||||
|
||||
ImGui::BeginGroup();
|
||||
|
||||
if(!ImGui::BeginTable("##WeaponsList", 1,
|
||||
ImGuiTableFlags_ScrollY|ImGuiTableFlags_BordersOuter|ImGuiTableFlags_BordersInnerH,
|
||||
{ImGui::GetContentRegionAvailWidth() * 0.2f, -footer_height_to_reserve}))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::TableSetupColumn("Weapon");
|
||||
|
||||
int id = 0;
|
||||
|
||||
#define weapcat(header, array, dirty, payload_type, payload_tooltip) \
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers); \
|
||||
ImGui::TableNextColumn(); \
|
||||
ImGui::TextUnformatted(header); \
|
||||
\
|
||||
for(UnsignedInt i = 0; i < _currentMass->array().size(); i++) { \
|
||||
auto& weapon = _currentMass->array()[i]; \
|
||||
\
|
||||
ImGui::TableNextRow(); \
|
||||
ImGui::TableNextColumn(); \
|
||||
ImGui::PushID(id); \
|
||||
if(ImGui::Selectable(weapon.name.c_str(), current_weapon == &weapon)) { \
|
||||
current_weapon = &weapon; \
|
||||
} \
|
||||
if(ImGui::BeginDragDropSource()) { \
|
||||
ImGui::SetDragDropPayload(payload_type, &i, sizeof(UnsignedInt)); \
|
||||
if(ImGui::GetIO().KeyCtrl) { \
|
||||
ImGui::Text(payload_tooltip " %i - %s (copy)", i + 1, weapon.name.c_str()); \
|
||||
} \
|
||||
else { \
|
||||
ImGui::Text(payload_tooltip " %i - %s", i + 1, weapon.name.c_str()); \
|
||||
} \
|
||||
ImGui::EndDragDropSource(); \
|
||||
} \
|
||||
if(ImGui::BeginDragDropTarget()) { \
|
||||
if(const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(payload_type)) { \
|
||||
int index = *static_cast<int*>(payload->Data); \
|
||||
\
|
||||
if(!ImGui::GetIO().KeyCtrl) { \
|
||||
if(current_weapon == &_currentMass->array()[index]) { \
|
||||
current_weapon = &_currentMass->array()[i]; \
|
||||
} \
|
||||
else if (current_weapon == &_currentMass->array()[i]) { \
|
||||
current_weapon = &_currentMass->array()[index]; \
|
||||
} \
|
||||
\
|
||||
std::swap(_currentMass->array()[index], _currentMass->array()[i]); \
|
||||
} \
|
||||
else { \
|
||||
_currentMass->array()[i] = _currentMass->array()[index]; \
|
||||
} \
|
||||
(dirty) = true; \
|
||||
} \
|
||||
\
|
||||
ImGui::EndDragDropTarget(); \
|
||||
} \
|
||||
\
|
||||
ImGui::PopID(); \
|
||||
id++; \
|
||||
\
|
||||
if(weapon.attached == true) { \
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, 0x1F008CFFu); \
|
||||
} \
|
||||
}
|
||||
|
||||
weapcat("Melee weapons", meleeWeapons, _meleeDirty, "MeleeWeapon", "Melee weapon")
|
||||
weapcat("Shield", shields, _shieldsDirty, "Shield", "Shield")
|
||||
weapcat("Bullet shooters", bulletShooters, _bShootersDirty, "BShooter", "Bullet shooter")
|
||||
weapcat("Energy shooters", energyShooters, _eShootersDirty, "EShooter", "Energy shooter")
|
||||
weapcat("Bullet launchers", bulletLaunchers, _bLaunchersDirty, "BLauncher", "Bullet launcher")
|
||||
weapcat("Energy launchers", energyLaunchers, _eLaunchersDirty, "ELauncher", "Energy launcher")
|
||||
|
||||
#undef weapcat
|
||||
|
||||
ImGui::EndTable();
|
||||
|
||||
bool dirty = _meleeDirty || _shieldsDirty || _bShootersDirty || _eShootersDirty || _bLaunchersDirty || _eLaunchersDirty;
|
||||
|
||||
if(!dirty) {
|
||||
ImGui::BeginDisabled();
|
||||
}
|
||||
|
||||
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
||||
if(_meleeDirty) {
|
||||
if(!_currentMass->writeMeleeWeapons()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
else {
|
||||
_meleeDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(_shieldsDirty) {
|
||||
if(!_currentMass->writeShields()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
else {
|
||||
_shieldsDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(_bShootersDirty) {
|
||||
if(!_currentMass->writeBulletShooters()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
else {
|
||||
_bShootersDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(_eShootersDirty) {
|
||||
if(_currentMass->writeEnergyShooters()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
else {
|
||||
_eShootersDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(_bLaunchersDirty) {
|
||||
if(_currentMass->writeBulletLaunchers()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
else {
|
||||
_bLaunchersDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(_eLaunchersDirty) {
|
||||
if(_currentMass->writeEnergyLaunchers()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
else {
|
||||
_eLaunchersDirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if(ImGui::Button(ICON_FA_UNDO_ALT " Reset")) {
|
||||
if(_meleeDirty) {
|
||||
_currentMass->getMeleeWeapons();
|
||||
_meleeDirty = false;
|
||||
}
|
||||
if(_shieldsDirty) {
|
||||
_currentMass->getShields();
|
||||
_shieldsDirty = false;
|
||||
}
|
||||
if(_bShootersDirty) {
|
||||
_currentMass->getBulletShooters();
|
||||
_bShootersDirty = false;
|
||||
}
|
||||
if(_eShootersDirty) {
|
||||
_currentMass->getEnergyShooters();
|
||||
_eShootersDirty = false;
|
||||
}
|
||||
if(_bLaunchersDirty) {
|
||||
_currentMass->getBulletLaunchers();
|
||||
_bLaunchersDirty = false;
|
||||
}
|
||||
if(_eLaunchersDirty) {
|
||||
_currentMass->getEnergyLaunchers();
|
||||
_eLaunchersDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!dirty) {
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if(!current_weapon) {
|
||||
ImGui::TextUnformatted("No weapon selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::BeginGroup();
|
||||
|
||||
if(!ImGui::BeginChild("##WeaponChild", {0.0f, -footer_height_to_reserve})) {
|
||||
ImGui::EndChild();
|
||||
return;
|
||||
}
|
||||
|
||||
drawWeaponEditor(*current_weapon);
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if(drawUnsafeWidget([](){ return ImGui::Button(ICON_FA_SAVE " Save changes to weapon category"); })) {
|
||||
switch(current_weapon->type) {
|
||||
case WeaponType::Melee:
|
||||
if(!_currentMass->writeMeleeWeapons()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
break;
|
||||
case WeaponType::Shield:
|
||||
if(!_currentMass->writeShields()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
break;
|
||||
case WeaponType::BulletShooter:
|
||||
if(!_currentMass->writeBulletShooters()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
break;
|
||||
case WeaponType::EnergyShooter:
|
||||
if(!_currentMass->writeEnergyShooters()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
break;
|
||||
case WeaponType::BulletLauncher:
|
||||
if(!_currentMass->writeBulletLaunchers()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
break;
|
||||
case WeaponType::EnergyLauncher:
|
||||
if(!_currentMass->writeEnergyLaunchers()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_queue.addToast(Toast::Type::Error, "Unknown weapon type");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if(ImGui::Button(ICON_FA_UNDO_ALT " Reset weapon category")) {
|
||||
switch(current_weapon->type) {
|
||||
case WeaponType::Melee:
|
||||
_currentMass->getMeleeWeapons();
|
||||
break;
|
||||
case WeaponType::Shield:
|
||||
_currentMass->getShields();
|
||||
break;
|
||||
case WeaponType::BulletShooter:
|
||||
_currentMass->getBulletShooters();
|
||||
break;
|
||||
case WeaponType::EnergyShooter:
|
||||
_currentMass->getEnergyShooters();
|
||||
break;
|
||||
case WeaponType::BulletLauncher:
|
||||
_currentMass->getBulletLaunchers();
|
||||
break;
|
||||
case WeaponType::EnergyLauncher:
|
||||
_currentMass->getEnergyLaunchers();
|
||||
break;
|
||||
default:
|
||||
_queue.addToast(Toast::Type::Error, "Unknown weapon type");
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndGroup();
|
||||
}
|
||||
|
||||
void SaveTool::drawWeaponEditor(Weapon& weapon) {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid || !current_weapon) {
|
||||
return;
|
||||
}
|
||||
|
||||
static const char* labels[] {
|
||||
#define c(enumerator, strenum, name) name,
|
||||
#include "../Maps/WeaponTypes.hpp"
|
||||
#undef c
|
||||
};
|
||||
|
||||
drawAlignedText("%s: %s", labels[UnsignedInt(weapon.type)], weapon.name.c_str());
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
static Containers::StaticArray<33, char> name_buf{ValueInit};
|
||||
if(ImGui::Button(ICON_FA_EDIT " Rename")) {
|
||||
for(auto& c : name_buf) {
|
||||
c = '\0';
|
||||
}
|
||||
std::strncpy(name_buf.data(), weapon.name.c_str(), 32);
|
||||
ImGui::OpenPopup("name_edit");
|
||||
}
|
||||
if(drawRenamePopup(name_buf)) {
|
||||
weapon.name = name_buf.data();
|
||||
}
|
||||
|
||||
ImGui::BeginGroup();
|
||||
drawAlignedText("Equipped:");
|
||||
|
||||
if(weapon.type != WeaponType::Shield) {
|
||||
drawAlignedText("Damage type:");
|
||||
}
|
||||
|
||||
if(weapon.type == WeaponType::Melee) {
|
||||
drawAlignedText("Dual-wield:");
|
||||
|
||||
drawAlignedText("Custom effect mode:");
|
||||
|
||||
drawAlignedText("Custom effect colour:");
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginGroup();
|
||||
ImGui::Checkbox("##EquippedCheckbox", &weapon.attached);
|
||||
|
||||
if(weapon.type != WeaponType::Shield) {
|
||||
if(weapon.type == WeaponType::Melee &&
|
||||
ImGui::RadioButton("Physical##NoElement", weapon.damageType == DamageType::Physical))
|
||||
{
|
||||
weapon.damageType = DamageType::Physical;
|
||||
}
|
||||
else if((weapon.type == WeaponType::BulletShooter || weapon.type == WeaponType::BulletLauncher) &&
|
||||
ImGui::RadioButton("Piercing##NoElement", weapon.damageType == DamageType::Piercing))
|
||||
{
|
||||
weapon.damageType = DamageType::Piercing;
|
||||
}
|
||||
else if((weapon.type == WeaponType::EnergyShooter || weapon.type == WeaponType::EnergyLauncher) &&
|
||||
ImGui::RadioButton("Plasma##NoElement", weapon.damageType == DamageType::Plasma))
|
||||
{
|
||||
weapon.damageType = DamageType::Plasma;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if(ImGui::RadioButton("Heat##Heat", weapon.damageType == DamageType::Heat)) {
|
||||
weapon.damageType = DamageType::Heat;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if(ImGui::RadioButton("Freeze##Freeze", weapon.damageType == DamageType::Freeze)) {
|
||||
weapon.damageType = DamageType::Freeze;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if(ImGui::RadioButton("Shock##Shock", weapon.damageType == DamageType::Freeze)) {
|
||||
weapon.damageType = DamageType::Freeze;
|
||||
}
|
||||
}
|
||||
|
||||
if(weapon.type == WeaponType::Melee) {
|
||||
ImGui::Checkbox("##DualWield", &weapon.dualWield);
|
||||
|
||||
if(ImGui::RadioButton("Default##Default", weapon.effectColourMode == EffectColourMode::Default)) {
|
||||
weapon.effectColourMode = EffectColourMode::Default;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if(ImGui::RadioButton("Custom##Custom", weapon.effectColourMode == EffectColourMode::Custom)) {
|
||||
weapon.effectColourMode = EffectColourMode::Custom;
|
||||
}
|
||||
|
||||
bool custom_effect = (weapon.effectColourMode == EffectColourMode::Custom);
|
||||
if(!custom_effect) {
|
||||
ImGui::BeginDisabled();
|
||||
}
|
||||
|
||||
ImGui::ColorEdit3("##CustomEffectColourPicker", &weapon.effectColour.x(), ImGuiColorEditFlags_HDR|ImGuiColorEditFlags_Float);
|
||||
|
||||
if(!custom_effect) {
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if(ImGui::CollapsingHeader("Weapon parts")) {
|
||||
drawAlignedText("Viewing/editing part:");
|
||||
for(Int i = 0; UnsignedLong(i) < weapon.parts.size(); i++) {
|
||||
if(UnsignedLong(_selectedWeaponPart) >= weapon.parts.size()) {
|
||||
_selectedWeaponPart = 0;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton(std::to_string(i + 1).c_str(), &_selectedWeaponPart, i);
|
||||
}
|
||||
|
||||
auto& part = weapon.parts[_selectedWeaponPart];
|
||||
|
||||
ImGui::Text("ID: %i", part.id);
|
||||
|
||||
if(ImGui::BeginChild("##PartDetails", {0.0f, 0.0f}, true)) {
|
||||
ImGui::TextUnformatted("Styles:");
|
||||
|
||||
for(Int i = 0; i < 4; i++) {
|
||||
drawAlignedText("Slot %d:", i + 1);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::PushID(i);
|
||||
|
||||
if(ImGui::BeginCombo("##Style", getStyleName(part.styles[i], weapon.customStyles))) {
|
||||
for(const auto& style: style_names) {
|
||||
if(ImGui::Selectable(getStyleName(style.first, weapon.customStyles),
|
||||
part.styles[i] == style.first)) {
|
||||
part.styles[i] = style.first;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::PushID("Decal");
|
||||
|
||||
drawAlignedText("Showing/editing decal");
|
||||
for(UnsignedLong i = 0; i < part.decals.size(); i++) {
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton(std::to_string(i + 1).c_str(), &_selectedWeaponDecal, i);
|
||||
}
|
||||
|
||||
drawDecalEditor(part.decals[_selectedWeaponDecal]);
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
if(part.accessories.size() != 0) {
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::PushID("Accessory");
|
||||
|
||||
drawAlignedText("Showing/editing accessory");
|
||||
for(UnsignedLong i = 0; i < part.accessories.size(); i++) {
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton(std::string{char(65 + i)}.c_str(), &_selectedWeaponAccessory, i);
|
||||
}
|
||||
|
||||
drawAccessoryEditor(part.accessories[_selectedWeaponAccessory], weapon.customStyles);
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
}
|
||||
}
|
||||
|
||||
void SaveTool::drawGlobalStyles() {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
|
||||
return;
|
||||
|
|
|
@ -1,198 +0,0 @@
|
|||
// MassBuilderSaveTool
|
||||
// Copyright (C) 2021-2022 Guillaume Jacquemin
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "../FontAwesome/IconsFontAwesome5.h"
|
||||
|
||||
#include "../Maps/ArmourSets.h"
|
||||
#include "../Maps/StyleNames.h"
|
||||
|
||||
#include "SaveTool.h"
|
||||
|
||||
void SaveTool::drawArmour() {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(ImGui::Button(ICON_FA_UNDO_ALT " Reset all")) {
|
||||
_currentMass->getArmourParts();
|
||||
}
|
||||
|
||||
if(!ImGui::BeginChild("##ArmourParts")) {
|
||||
ImGui::EndChild();
|
||||
return;
|
||||
}
|
||||
|
||||
static const char* slot_labels[] = {
|
||||
#define c(enumerator, strenum, name) name,
|
||||
#include "../Maps/ArmourSlots.hpp"
|
||||
#undef c
|
||||
};
|
||||
|
||||
for(UnsignedInt i = 0; i < _currentMass->armourParts().size(); i++) {
|
||||
ImGui::PushID(i);
|
||||
|
||||
auto& part = _currentMass->armourParts()[i];
|
||||
|
||||
static char header[129] = {'\0'};
|
||||
|
||||
std::memset(header, '\0', 129);
|
||||
|
||||
if(armour_sets.find(part.id) != armour_sets.cend()) {
|
||||
std::snprintf(header, 128, "%s: %s###%u", slot_labels[UnsignedInt(part.slot)], armour_sets.at(part.id).name, UnsignedInt(part.slot));
|
||||
}
|
||||
else {
|
||||
std::snprintf(header, 128, "%s: %i###%u", slot_labels[UnsignedInt(part.slot)], part.id, UnsignedInt(part.slot));
|
||||
}
|
||||
|
||||
if(ImGui::CollapsingHeader(header)) {
|
||||
ImGui::BeginGroup();
|
||||
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth() * 0.491f);
|
||||
if(ImGui::BeginListBox("##ChangePart")) {
|
||||
if(std::strncmp("Neck", slot_labels[UnsignedInt(part.slot)], 4) != 0) {
|
||||
for(auto& set : armour_sets) {
|
||||
if(ImGui::Selectable(set.second.name, set.first == part.id, ImGuiSelectableFlags_SpanAvailWidth)) {
|
||||
part.id = set.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(auto& set : armour_sets) {
|
||||
if(!set.second.neck_compatible) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(ImGui::Selectable(set.second.name, set.first == part.id, ImGuiSelectableFlags_SpanAvailWidth)) {
|
||||
part.id = set.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::EndListBox();
|
||||
}
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginGroup();
|
||||
|
||||
ImGui::TextUnformatted("Styles:");
|
||||
|
||||
for(Int j = 0; j < 4; j++) {
|
||||
drawAlignedText("Slot %d:", j + 1);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::PushID(j);
|
||||
|
||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth() - 2.0f);
|
||||
if(ImGui::BeginCombo("##Style", getStyleName(part.styles[j], _currentMass->armourCustomStyles()))) {
|
||||
for(const auto& style : style_names) {
|
||||
if(ImGui::Selectable(getStyleName(style.first, _currentMass->armourCustomStyles()), part.styles[j] == style.first)) {
|
||||
part.styles[j] = style.first;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::PushID("Decal");
|
||||
|
||||
drawAlignedText("Showing/editing decal");
|
||||
for(UnsignedInt j = 0; j < part.decals.size(); j++) {
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton(std::to_string(j + 1).c_str(), &_selectedArmourDecals[i], j);
|
||||
}
|
||||
|
||||
drawDecalEditor(part.decals[_selectedArmourDecals[i]]);
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
if(!part.accessories.size()) {
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::PushID("Accessory");
|
||||
|
||||
drawAlignedText("Showing/editing accessory");
|
||||
for(UnsignedInt j = 0; j < part.accessories.size(); j++) {
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton(std::string{char(65 + j)}.c_str(), &_selectedArmourAccessories[i], j);
|
||||
}
|
||||
|
||||
drawAccessoryEditor(part.accessories[_selectedArmourAccessories[i]], _currentMass->armourCustomStyles());
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
||||
if(!_currentMass->writeArmourPart(part.slot)) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
void SaveTool::drawCustomArmourStyles() {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ImGui::BeginChild("##ArmourStyles")) {
|
||||
ImGui::EndChild();
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::TextWrapped("In-game values are multiplied by 100. For example, 0.500 here is equal to 50 in-game.");
|
||||
|
||||
for(UnsignedInt i = 0; i < _currentMass->armourCustomStyles().size(); i++) {
|
||||
ImGui::PushID(i);
|
||||
DCSResult result;
|
||||
result = drawCustomStyle(_currentMass->armourCustomStyles()[i]);
|
||||
switch(result) {
|
||||
case DCS_ResetStyle:
|
||||
_currentMass->getArmourCustomStyles();
|
||||
break;
|
||||
case DCS_Save:
|
||||
if(_currentMass->writeArmourCustomStyle(i)) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
}
|
|
@ -1,307 +0,0 @@
|
|||
// MassBuilderSaveTool
|
||||
// Copyright (C) 2021-2022 Guillaume Jacquemin
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "../FontAwesome/IconsFontAwesome5.h"
|
||||
|
||||
#include "../Maps/StyleNames.h"
|
||||
|
||||
#include "SaveTool.h"
|
||||
|
||||
void SaveTool::drawFrameInfo() {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ImGui::BeginChild("##FrameInfo")) {
|
||||
ImGui::EndChild();
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::BeginGroup();
|
||||
|
||||
if(ImGui::BeginChild("##JointSliders", {(ImGui::GetContentRegionAvailWidth() / 2.0f) - (ImGui::GetStyle().WindowPadding.x / 2.0f), 300.0f}, true, ImGuiWindowFlags_MenuBar)) {
|
||||
if(ImGui::BeginMenuBar()) {
|
||||
ImGui::TextUnformatted("Joint sliders");
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
drawJointSliders();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
if(ImGui::BeginChild("##FrameStyles", {(ImGui::GetContentRegionAvailWidth() / 2.0f) - (ImGui::GetStyle().WindowPadding.x / 2.0f), 0.0f}, true, ImGuiWindowFlags_MenuBar)) {
|
||||
if(ImGui::BeginMenuBar()) {
|
||||
ImGui::TextUnformatted("Frame styles");
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
drawFrameStyles();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if(ImGui::BeginChild("##EyeFlare", {0.0f, 0.0f}, true, ImGuiWindowFlags_MenuBar)) {
|
||||
if(ImGui::BeginMenuBar()) {
|
||||
ImGui::TextUnformatted("Eye flare colour");
|
||||
drawHelpMarker("Right-click the picker for more options.", 250.0f);
|
||||
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
drawEyeColourPicker();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
void SaveTool::drawJointSliders() {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::TextWrapped("In-game values are multiplied by 100.\nFor example, 0.500 here is equal to 50 in-game.");
|
||||
|
||||
if(ImGui::BeginTable("##JointSliderTable", 2, ImGuiTableFlags_Borders)) {
|
||||
ImGui::TableSetupColumn("##SliderLabel", ImGuiTableColumnFlags_WidthFixed);
|
||||
ImGui::TableSetupColumn("##Sliders", ImGuiTableColumnFlags_WidthStretch);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
drawAlignedText("Neck");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::SetNextItemWidth(-1.0f);
|
||||
if(ImGui::SliderFloat("##NeckSlider", &_currentMass->jointSliders().neck, 0.0f, 1.0f)) {
|
||||
_jointsDirty = true;
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
drawAlignedText("Body");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::SetNextItemWidth(-1.0f);
|
||||
if(ImGui::SliderFloat("##BodySlider", &_currentMass->jointSliders().body, 0.0f, 1.0f)) {
|
||||
_jointsDirty = true;
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
drawAlignedText("Shoulders");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::SetNextItemWidth(-1.0f);
|
||||
if(ImGui::SliderFloat("##ShouldersSlider", &_currentMass->jointSliders().shoulders, 0.0f, 1.0f)) {
|
||||
_jointsDirty = true;
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
drawAlignedText("Hips");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::SetNextItemWidth(-1.0f);
|
||||
if(ImGui::SliderFloat("##HipsSlider", &_currentMass->jointSliders().hips, 0.0f, 1.0f)) {
|
||||
_jointsDirty = true;
|
||||
}
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
drawAlignedText("Arms");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{2.0f, 1.0f});
|
||||
if(ImGui::BeginTable("##UpperLowerArmsLayoutTable", 2)) {
|
||||
ImGui::TableSetupColumn("##UpperArms", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("##LowerArms", ImGuiTableColumnFlags_WidthStretch);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(-1.0f);
|
||||
if(ImGui::SliderFloat("##UpperArmsSlider", &_currentMass->jointSliders().upperArms, 0.0f, 1.0f, "Upper: %.3f")) {
|
||||
_jointsDirty = true;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(-1.0f);
|
||||
if(ImGui::SliderFloat("##LowerArmsSlider", &_currentMass->jointSliders().lowerArms, 0.0f, 1.0f, "Lower: %.3f")) {
|
||||
_jointsDirty = true;
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
drawAlignedText("Legs");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2{2.0f, 1.0f});
|
||||
if(ImGui::BeginTable("##UpperLowerLegsLayoutTable", 2)) {
|
||||
ImGui::TableSetupColumn("##UpperLegs", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("##LowerLegs", ImGuiTableColumnFlags_WidthStretch);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(-1.0f);
|
||||
if(ImGui::SliderFloat("##UpperLegsSlider", &_currentMass->jointSliders().upperLegs, 0.0f, 1.0f, "Upper: %.3f")) {
|
||||
_jointsDirty = true;
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(-1.0f);
|
||||
if(ImGui::SliderFloat("##LowerLegsSlider", &_currentMass->jointSliders().lowerLegs, 0.0f, 1.0f, "Lower: %.3f")) {
|
||||
_jointsDirty = true;
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if(!_jointsDirty) {
|
||||
ImGui::BeginDisabled();
|
||||
ImGui::Button(ICON_FA_SAVE " Save");
|
||||
ImGui::SameLine();
|
||||
ImGui::Button(ICON_FA_UNDO " Reset");
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
else {
|
||||
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
||||
if(!_currentMass->writeJointSliders()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
_jointsDirty = false;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if(ImGui::Button(ICON_FA_UNDO " Reset")) {
|
||||
_currentMass->getJointSliders();
|
||||
_jointsDirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SaveTool::drawFrameStyles() {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(Int i = 0; i < 4; i++) {
|
||||
drawAlignedText("Slot %d:", i + 1);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::PushID(i);
|
||||
|
||||
if(ImGui::BeginCombo("##Style", getStyleName(_currentMass->frameStyles()[i], _currentMass->frameCustomStyles()))) {
|
||||
for(const auto& style : style_names) {
|
||||
if(ImGui::Selectable(getStyleName(style.first, _currentMass->frameCustomStyles()), _currentMass->frameStyles()[i] == style.first)) {
|
||||
_currentMass->frameStyles()[i] = style.first;
|
||||
_stylesDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
if(!_stylesDirty) {
|
||||
ImGui::BeginDisabled();
|
||||
ImGui::Button(ICON_FA_SAVE " Save");
|
||||
ImGui::SameLine();
|
||||
ImGui::Button(ICON_FA_UNDO " Reset");
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
else {
|
||||
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
||||
if(!_currentMass->writeFrameStyles()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
_stylesDirty = false;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if(ImGui::Button(ICON_FA_UNDO " Reset")) {
|
||||
_currentMass->getFrameStyles();
|
||||
_stylesDirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SaveTool::drawEyeColourPicker() {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(ImGui::ColorPicker3("##EyeFlarePicker", &_currentMass->eyeFlareColour().x())) {
|
||||
_eyeFlareDirty = true;
|
||||
}
|
||||
|
||||
if(!_eyeFlareDirty) {
|
||||
ImGui::BeginDisabled();
|
||||
ImGui::Button(ICON_FA_SAVE " Save");
|
||||
ImGui::SameLine();
|
||||
ImGui::Button(ICON_FA_UNDO " Reset");
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
else {
|
||||
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
||||
if(!_currentMass->writeEyeFlareColour()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
_eyeFlareDirty = false;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if(ImGui::Button(ICON_FA_UNDO " Reset")) {
|
||||
_currentMass->getEyeFlareColour();
|
||||
_eyeFlareDirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SaveTool::drawCustomFrameStyles() {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ImGui::BeginChild("##FrameStyles")) {
|
||||
ImGui::EndChild();
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::TextWrapped("In-game values are multiplied by 100. For example, 0.500 here is equal to 50 in-game.");
|
||||
|
||||
for(UnsignedInt i = 0; i < _currentMass->frameCustomStyles().size(); i++) {
|
||||
ImGui::PushID(i);
|
||||
DCSResult result;
|
||||
result = drawCustomStyle(_currentMass->frameCustomStyles()[i]);
|
||||
switch(result) {
|
||||
case DCS_ResetStyle:
|
||||
_currentMass->getFrameCustomStyles();
|
||||
break;
|
||||
case DCS_Save:
|
||||
if(!_currentMass->writeFrameCustomStyle(i)) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
}
|
|
@ -1,475 +0,0 @@
|
|||
// MassBuilderSaveTool
|
||||
// Copyright (C) 2021-2022 Guillaume Jacquemin
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "../FontAwesome/IconsFontAwesome5.h"
|
||||
|
||||
#include "../Maps/StyleNames.h"
|
||||
|
||||
#include "SaveTool.h"
|
||||
|
||||
void SaveTool::drawWeapons() {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid) {
|
||||
_currentWeapon = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
const Float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
|
||||
|
||||
ImGui::BeginGroup();
|
||||
|
||||
if(!ImGui::BeginTable("##WeaponsList", 1,
|
||||
ImGuiTableFlags_ScrollY|ImGuiTableFlags_BordersOuter|ImGuiTableFlags_BordersInnerH,
|
||||
{ImGui::GetContentRegionAvailWidth() * 0.2f, -footer_height_to_reserve}))
|
||||
{
|
||||
ImGui::EndGroup();
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::TableSetupColumn("Weapon");
|
||||
|
||||
drawWeaponCategory("Melee weapons", _currentMass->meleeWeapons(), _meleeDirty, "MeleeWeapon", "Melee weapon");
|
||||
drawWeaponCategory("Shield", _currentMass->shields(), _shieldsDirty, "Shield", "Shield");
|
||||
drawWeaponCategory("Bullet shooters", _currentMass->bulletShooters(), _bShootersDirty, "BShooter", "Bullet shooter");
|
||||
drawWeaponCategory("Energy shooters", _currentMass->energyShooters(), _eShootersDirty, "EShooter", "Energy shooter");
|
||||
drawWeaponCategory("Bullet launchers", _currentMass->bulletLaunchers(), _bLaunchersDirty, "BLauncher", "Bullet launcher");
|
||||
drawWeaponCategory("Energy launchers", _currentMass->energyLaunchers(), _eLaunchersDirty, "ELauncher", "Energy launcher");
|
||||
|
||||
ImGui::EndTable();
|
||||
|
||||
bool dirty = _meleeDirty || _shieldsDirty || _bShootersDirty || _eShootersDirty || _bLaunchersDirty || _eLaunchersDirty;
|
||||
|
||||
if(!dirty) {
|
||||
ImGui::BeginDisabled();
|
||||
}
|
||||
|
||||
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
||||
if(_meleeDirty) {
|
||||
if(!_currentMass->writeMeleeWeapons()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
else {
|
||||
_meleeDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(_shieldsDirty) {
|
||||
if(!_currentMass->writeShields()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
else {
|
||||
_shieldsDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(_bShootersDirty) {
|
||||
if(!_currentMass->writeBulletShooters()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
else {
|
||||
_bShootersDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(_eShootersDirty) {
|
||||
if(_currentMass->writeEnergyShooters()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
else {
|
||||
_eShootersDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(_bLaunchersDirty) {
|
||||
if(_currentMass->writeBulletLaunchers()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
else {
|
||||
_bLaunchersDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(_eLaunchersDirty) {
|
||||
if(_currentMass->writeEnergyLaunchers()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
else {
|
||||
_eLaunchersDirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if(ImGui::Button(ICON_FA_UNDO_ALT " Reset")) {
|
||||
if(_meleeDirty) {
|
||||
_currentMass->getMeleeWeapons();
|
||||
_meleeDirty = false;
|
||||
}
|
||||
if(_shieldsDirty) {
|
||||
_currentMass->getShields();
|
||||
_shieldsDirty = false;
|
||||
}
|
||||
if(_bShootersDirty) {
|
||||
_currentMass->getBulletShooters();
|
||||
_bShootersDirty = false;
|
||||
}
|
||||
if(_eShootersDirty) {
|
||||
_currentMass->getEnergyShooters();
|
||||
_eShootersDirty = false;
|
||||
}
|
||||
if(_bLaunchersDirty) {
|
||||
_currentMass->getBulletLaunchers();
|
||||
_bLaunchersDirty = false;
|
||||
}
|
||||
if(_eLaunchersDirty) {
|
||||
_currentMass->getEnergyLaunchers();
|
||||
_eLaunchersDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!dirty) {
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if(!_currentWeapon) {
|
||||
ImGui::TextUnformatted("No weapon selected.");
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::BeginGroup();
|
||||
|
||||
if(!ImGui::BeginChild("##WeaponChild", {0.0f, -footer_height_to_reserve})) {
|
||||
ImGui::EndChild();
|
||||
return;
|
||||
}
|
||||
|
||||
drawWeaponEditor(*_currentWeapon);
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if(drawUnsafeWidget([](){ return ImGui::Button(ICON_FA_SAVE " Save changes to weapon category"); })) {
|
||||
switch(_currentWeapon->type) {
|
||||
case WeaponType::Melee:
|
||||
if(!_currentMass->writeMeleeWeapons()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
break;
|
||||
case WeaponType::Shield:
|
||||
if(!_currentMass->writeShields()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
break;
|
||||
case WeaponType::BulletShooter:
|
||||
if(!_currentMass->writeBulletShooters()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
break;
|
||||
case WeaponType::EnergyShooter:
|
||||
if(!_currentMass->writeEnergyShooters()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
break;
|
||||
case WeaponType::BulletLauncher:
|
||||
if(!_currentMass->writeBulletLaunchers()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
break;
|
||||
case WeaponType::EnergyLauncher:
|
||||
if(!_currentMass->writeEnergyLaunchers()) {
|
||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_queue.addToast(Toast::Type::Error, "Unknown weapon type");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if(ImGui::Button(ICON_FA_UNDO_ALT " Reset weapon category")) {
|
||||
switch(_currentWeapon->type) {
|
||||
case WeaponType::Melee:
|
||||
_currentMass->getMeleeWeapons();
|
||||
break;
|
||||
case WeaponType::Shield:
|
||||
_currentMass->getShields();
|
||||
break;
|
||||
case WeaponType::BulletShooter:
|
||||
_currentMass->getBulletShooters();
|
||||
break;
|
||||
case WeaponType::EnergyShooter:
|
||||
_currentMass->getEnergyShooters();
|
||||
break;
|
||||
case WeaponType::BulletLauncher:
|
||||
_currentMass->getBulletLaunchers();
|
||||
break;
|
||||
case WeaponType::EnergyLauncher:
|
||||
_currentMass->getEnergyLaunchers();
|
||||
break;
|
||||
default:
|
||||
_queue.addToast(Toast::Type::Error, "Unknown weapon type");
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndGroup();
|
||||
}
|
||||
|
||||
void SaveTool::drawWeaponCategory(const char* name, Containers::ArrayView<Weapon> weapons_view, bool& dirty,
|
||||
const char* payload_type, const char* payload_tooltip)
|
||||
{
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TextUnformatted(name);
|
||||
|
||||
ImGui::PushID(payload_type);
|
||||
|
||||
for(UnsignedInt i = 0; i < weapons_view.size(); i++) {
|
||||
auto& weapon = weapons_view[i];
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::PushID(i);
|
||||
|
||||
if(ImGui::Selectable(weapon.name.c_str(), _currentWeapon == &weapon)) {
|
||||
_currentWeapon = &weapon;
|
||||
}
|
||||
if(ImGui::BeginDragDropSource()) {
|
||||
ImGui::SetDragDropPayload(payload_type, &i, sizeof(UnsignedInt));
|
||||
if(ImGui::GetIO().KeyCtrl) {
|
||||
ImGui::Text("%s %i - %s (copy)", payload_tooltip, i + 1, weapon.name.c_str());
|
||||
}
|
||||
else {
|
||||
ImGui::Text("%s %i - %s", payload_tooltip, i + 1, weapon.name.c_str());
|
||||
}
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
if(ImGui::BeginDragDropTarget()) {
|
||||
if(const ImGuiPayload* payload = ImGui::AcceptDragDropPayload(payload_type)) {
|
||||
int index = *static_cast<int*>(payload->Data);
|
||||
|
||||
if(!ImGui::GetIO().KeyCtrl) {
|
||||
if(_currentWeapon == &weapons_view[index]) {
|
||||
_currentWeapon = &weapons_view[i];
|
||||
}
|
||||
else if (_currentWeapon == &weapons_view[i]) {
|
||||
_currentWeapon = &weapons_view[index];
|
||||
}
|
||||
|
||||
std::swap(weapons_view[index], weapons_view[i]);
|
||||
}
|
||||
else {
|
||||
weapons_view[i] = weapons_view[index];
|
||||
}
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
if(weapon.attached == true) {
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, 0x1F008CFFu);
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
void SaveTool::drawWeaponEditor(Weapon& weapon) {
|
||||
if(!_currentMass || _currentMass->state() != Mass::State::Valid || !_currentWeapon) {
|
||||
return;
|
||||
}
|
||||
|
||||
static const char* labels[] {
|
||||
#define c(enumerator, strenum, name) name,
|
||||
#include "../Maps/WeaponTypes.hpp"
|
||||
#undef c
|
||||
};
|
||||
|
||||
drawAlignedText("%s: %s", labels[UnsignedInt(weapon.type)], weapon.name.c_str());
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
static Containers::StaticArray<33, char> name_buf{ValueInit};
|
||||
if(ImGui::Button(ICON_FA_EDIT " Rename")) {
|
||||
for(auto& c : name_buf) {
|
||||
c = '\0';
|
||||
}
|
||||
std::strncpy(name_buf.data(), weapon.name.c_str(), 32);
|
||||
ImGui::OpenPopup("name_edit");
|
||||
}
|
||||
if(drawRenamePopup(name_buf)) {
|
||||
weapon.name = name_buf.data();
|
||||
}
|
||||
|
||||
ImGui::BeginGroup();
|
||||
drawAlignedText("Equipped:");
|
||||
|
||||
if(weapon.type != WeaponType::Shield) {
|
||||
drawAlignedText("Damage type:");
|
||||
}
|
||||
|
||||
if(weapon.type == WeaponType::Melee) {
|
||||
drawAlignedText("Dual-wield:");
|
||||
|
||||
drawAlignedText("Custom effect mode:");
|
||||
|
||||
drawAlignedText("Custom effect colour:");
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginGroup();
|
||||
ImGui::Checkbox("##EquippedCheckbox", &weapon.attached);
|
||||
|
||||
if(weapon.type != WeaponType::Shield) {
|
||||
if(weapon.type == WeaponType::Melee &&
|
||||
ImGui::RadioButton("Physical##NoElement", weapon.damageType == DamageType::Physical))
|
||||
{
|
||||
weapon.damageType = DamageType::Physical;
|
||||
}
|
||||
else if((weapon.type == WeaponType::BulletShooter || weapon.type == WeaponType::BulletLauncher) &&
|
||||
ImGui::RadioButton("Piercing##NoElement", weapon.damageType == DamageType::Piercing))
|
||||
{
|
||||
weapon.damageType = DamageType::Piercing;
|
||||
}
|
||||
else if((weapon.type == WeaponType::EnergyShooter || weapon.type == WeaponType::EnergyLauncher) &&
|
||||
ImGui::RadioButton("Plasma##NoElement", weapon.damageType == DamageType::Plasma))
|
||||
{
|
||||
weapon.damageType = DamageType::Plasma;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if(ImGui::RadioButton("Heat##Heat", weapon.damageType == DamageType::Heat)) {
|
||||
weapon.damageType = DamageType::Heat;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if(ImGui::RadioButton("Freeze##Freeze", weapon.damageType == DamageType::Freeze)) {
|
||||
weapon.damageType = DamageType::Freeze;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if(ImGui::RadioButton("Shock##Shock", weapon.damageType == DamageType::Freeze)) {
|
||||
weapon.damageType = DamageType::Freeze;
|
||||
}
|
||||
}
|
||||
|
||||
if(weapon.type == WeaponType::Melee) {
|
||||
ImGui::Checkbox("##DualWield", &weapon.dualWield);
|
||||
|
||||
if(ImGui::RadioButton("Default##Default", weapon.effectColourMode == EffectColourMode::Default)) {
|
||||
weapon.effectColourMode = EffectColourMode::Default;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if(ImGui::RadioButton("Custom##Custom", weapon.effectColourMode == EffectColourMode::Custom)) {
|
||||
weapon.effectColourMode = EffectColourMode::Custom;
|
||||
}
|
||||
|
||||
bool custom_effect = (weapon.effectColourMode == EffectColourMode::Custom);
|
||||
if(!custom_effect) {
|
||||
ImGui::BeginDisabled();
|
||||
}
|
||||
|
||||
ImGui::ColorEdit3("##CustomEffectColourPicker", &weapon.effectColour.x(), ImGuiColorEditFlags_HDR|ImGuiColorEditFlags_Float);
|
||||
|
||||
if(!custom_effect) {
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if(ImGui::CollapsingHeader("Weapon parts")) {
|
||||
drawAlignedText("Viewing/editing part:");
|
||||
for(Int i = 0; UnsignedLong(i) < weapon.parts.size(); i++) {
|
||||
if(UnsignedLong(_selectedWeaponPart) >= weapon.parts.size()) {
|
||||
_selectedWeaponPart = 0;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton(std::to_string(i + 1).c_str(), &_selectedWeaponPart, i);
|
||||
}
|
||||
|
||||
auto& part = weapon.parts[_selectedWeaponPart];
|
||||
|
||||
ImGui::Text("ID: %i", part.id);
|
||||
|
||||
if(ImGui::BeginChild("##PartDetails", {0.0f, 0.0f}, true)) {
|
||||
ImGui::TextUnformatted("Styles:");
|
||||
|
||||
for(Int i = 0; i < 4; i++) {
|
||||
drawAlignedText("Slot %d:", i + 1);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::PushID(i);
|
||||
|
||||
if(ImGui::BeginCombo("##Style", getStyleName(part.styles[i], weapon.customStyles))) {
|
||||
for(const auto& style: style_names) {
|
||||
if(ImGui::Selectable(getStyleName(style.first, weapon.customStyles),
|
||||
part.styles[i] == style.first)) {
|
||||
part.styles[i] = style.first;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::PushID("Decal");
|
||||
|
||||
drawAlignedText("Showing/editing decal");
|
||||
for(UnsignedLong i = 0; i < part.decals.size(); i++) {
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton(std::to_string(i + 1).c_str(), &_selectedWeaponDecal, i);
|
||||
}
|
||||
|
||||
drawDecalEditor(part.decals[_selectedWeaponDecal]);
|
||||
|
||||
ImGui::PopID();
|
||||
|
||||
if(part.accessories.size() != 0) {
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::PushID("Accessory");
|
||||
|
||||
drawAlignedText("Showing/editing accessory");
|
||||
for(UnsignedLong i = 0; i < part.accessories.size(); i++) {
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton(std::string{char(65 + i)}.c_str(), &_selectedWeaponAccessory, i);
|
||||
}
|
||||
|
||||
drawAccessoryEditor(part.accessories[_selectedWeaponAccessory], weapon.customStyles);
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue