Application: redo the whole armour tab.
This commit is contained in:
parent
570134ced0
commit
7ce726f933
3 changed files with 280 additions and 233 deletions
|
@ -137,6 +137,7 @@ class Application: public Platform::Sdl2Application, public efsw::FileWatchListe
|
||||||
void drawEyeColourPicker();
|
void drawEyeColourPicker();
|
||||||
void drawCustomFrameStyles();
|
void drawCustomFrameStyles();
|
||||||
void drawArmour();
|
void drawArmour();
|
||||||
|
void drawBLAttachment();
|
||||||
void drawCustomArmourStyles();
|
void drawCustomArmourStyles();
|
||||||
void drawWeapons();
|
void drawWeapons();
|
||||||
void drawWeaponCategory(Containers::StringView name, Containers::ArrayView<GameObjects::Weapon> weapons_view,
|
void drawWeaponCategory(Containers::StringView name, Containers::ArrayView<GameObjects::Weapon> weapons_view,
|
||||||
|
@ -276,9 +277,10 @@ class Application: public Platform::Sdl2Application, public efsw::FileWatchListe
|
||||||
bool _bLaunchersDirty = false;
|
bool _bLaunchersDirty = false;
|
||||||
bool _eLaunchersDirty = false;
|
bool _eLaunchersDirty = false;
|
||||||
|
|
||||||
|
Containers::Optional<std::size_t> _selectedArmourSlot{Containers::NullOpt};
|
||||||
Containers::StaticArray<38, std::int32_t> _selectedArmourDecals{ValueInit};
|
Containers::StaticArray<38, std::int32_t> _selectedArmourDecals{ValueInit};
|
||||||
Containers::StaticArray<38, std::int32_t> _selectedArmourAccessories{ValueInit};
|
Containers::StaticArray<38, std::int32_t> _selectedArmourAccessories{ValueInit};
|
||||||
std::int32_t _selectedBLPlacement = 0;
|
std::uint32_t _selectedBLPlacement = 0;
|
||||||
std::int32_t _selectedWeaponPart = 0;
|
std::int32_t _selectedWeaponPart = 0;
|
||||||
std::int32_t _selectedWeaponDecal = 0;
|
std::int32_t _selectedWeaponDecal = 0;
|
||||||
std::int32_t _selectedWeaponAccessory = 0;
|
std::int32_t _selectedWeaponAccessory = 0;
|
||||||
|
|
|
@ -88,6 +88,7 @@ Application::drawMassViewer() {
|
||||||
_jointsDirty = false;
|
_jointsDirty = false;
|
||||||
_stylesDirty = false;
|
_stylesDirty = false;
|
||||||
_eyeFlareDirty = false;
|
_eyeFlareDirty = false;
|
||||||
|
_selectedArmourSlot = Containers::NullOpt;
|
||||||
_selectedArmourDecals = Containers::StaticArray<38, std::int32_t>{ValueInit};
|
_selectedArmourDecals = Containers::StaticArray<38, std::int32_t>{ValueInit};
|
||||||
_selectedArmourAccessories = Containers::StaticArray<38, std::int32_t>{ValueInit};
|
_selectedArmourAccessories = Containers::StaticArray<38, std::int32_t>{ValueInit};
|
||||||
_selectedBLPlacement = 0;
|
_selectedBLPlacement = 0;
|
||||||
|
@ -126,6 +127,13 @@ Application::drawMassViewer() {
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(_currentMass->bulletLauncherAttachmentStyle() != GameObjects::BulletLauncherAttachmentStyle::NotFound &&
|
||||||
|
ImGui::BeginTabItem("Bullet launcher attachment"))
|
||||||
|
{
|
||||||
|
drawBLAttachment();
|
||||||
|
ImGui::EndTabItem();
|
||||||
|
}
|
||||||
|
|
||||||
if(ImGui::BeginTabItem("Custom armour styles")) {
|
if(ImGui::BeginTabItem("Custom armour styles")) {
|
||||||
drawCustomArmourStyles();
|
drawCustomArmourStyles();
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
|
|
|
@ -29,63 +29,77 @@ Application::drawArmour() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ImGui::Button(ICON_FA_UNDO_ALT " Reset all")) {
|
constexpr static Containers::StringView slot_labels[] = {
|
||||||
_currentMass->getArmourParts();
|
|
||||||
_currentMass->getBulletLauncherAttachments();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!ImGui::BeginChild("##ArmourParts", {}, ImGuiChildFlags_Border)) {
|
|
||||||
ImGui::EndChild();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Containers::StringView slot_labels[] = {
|
|
||||||
#define c(enumerator, strenum, name) name,
|
#define c(enumerator, strenum, name) name,
|
||||||
#include "../Maps/ArmourSlots.hpp"
|
#include "../Maps/ArmourSlots.hpp"
|
||||||
#undef c
|
#undef c
|
||||||
};
|
};
|
||||||
|
|
||||||
for(std::uint32_t i = 0; i < _currentMass->armourParts().size(); i++) {
|
auto labels_view = arrayView(slot_labels);
|
||||||
ImGui::PushID(int(i));
|
|
||||||
|
|
||||||
auto& part = _currentMass->armourParts()[i];
|
const static float footer_height_to_reserve = ImGui::GetFrameHeightWithSpacing();
|
||||||
|
|
||||||
static char header[129] = {'\0'};
|
ImGui::BeginGroup();
|
||||||
|
|
||||||
std::memset(header, '\0', 129);
|
if(ImGui::BeginTable("##SlotsTable", 1,
|
||||||
|
ImGuiTableFlags_ScrollY|ImGuiTableFlags_BordersOuter|ImGuiTableFlags_BordersInnerH,
|
||||||
|
{ImGui::GetContentRegionAvail().x * 0.15f, -footer_height_to_reserve}))
|
||||||
|
{
|
||||||
|
ImGui::TableSetupColumn("##Slots", ImGuiTableColumnFlags_WidthStretch);
|
||||||
|
|
||||||
|
for(std::size_t i = 0; i < labels_view.size(); i++) {
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if(ImGui::Selectable(labels_view[i].data(), _selectedArmourSlot && (*_selectedArmourSlot) == i,
|
||||||
|
ImGuiSelectableFlags_SpanAvailWidth))
|
||||||
|
{
|
||||||
|
_selectedArmourSlot = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ImGui::Button(ICON_FA_UNDO_ALT " Reset all")) {
|
||||||
|
_currentMass->getArmourParts();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndGroup();
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
if(!_selectedArmourSlot) {
|
||||||
|
ImGui::TextUnformatted("No selected armour slot.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& part = _currentMass->armourParts()[*_selectedArmourSlot];
|
||||||
|
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
|
||||||
|
if(ImGui::BeginChild("##ArmourEditor", {0.0f, -footer_height_to_reserve})) {
|
||||||
|
|
||||||
|
ImGui::SeparatorText("Part");
|
||||||
|
|
||||||
if(GameData::armour_sets.find(part.id) != GameData::armour_sets.cend()) {
|
if(GameData::armour_sets.find(part.id) != GameData::armour_sets.cend()) {
|
||||||
std::snprintf(header, 128, "%s: %s###%u",
|
ImGui::Text("Set name: %s", GameData::armour_sets.at(part.id).name.data());
|
||||||
slot_labels[std::uint32_t(part.slot)].data(),
|
|
||||||
GameData::armour_sets.at(part.id).name.data(),
|
|
||||||
std::uint32_t(part.slot));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::snprintf(header, 128, "%s: %i###%u",
|
ImGui::Text("Set ID: %u", part.id);
|
||||||
slot_labels[std::uint32_t(part.slot)].data(),
|
|
||||||
part.id,
|
|
||||||
std::uint32_t(part.slot));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ImGui::CollapsingHeader(header)) {
|
ImGui::SameLine();
|
||||||
ImGui::BeginGroup();
|
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x * 0.491f);
|
if(ImGui::SmallButton("Change")) {
|
||||||
|
ImGui::OpenPopup("##ArmourPartPopup");
|
||||||
|
}
|
||||||
|
if(ImGui::BeginPopup("##ArmourPartPopup")) {
|
||||||
if(ImGui::BeginListBox("##ChangePart")) {
|
if(ImGui::BeginListBox("##ChangePart")) {
|
||||||
if(std::strncmp("Neck", slot_labels[std::uint32_t(part.slot)].data(), 4) != 0) {
|
for(auto& set : GameData::armour_sets) {
|
||||||
for(auto& set : GameData::armour_sets) {
|
if(part.slot != GameObjects::ArmourPart::Slot::Neck || set.second.neck_compatible) {
|
||||||
if(ImGui::Selectable(set.second.name.data(), set.first == part.id, ImGuiSelectableFlags_SpanAvailWidth)) {
|
if(ImGui::Selectable(set.second.name.data(), set.first == part.id,
|
||||||
part.id = set.first;
|
ImGuiSelectableFlags_SpanAvailWidth))
|
||||||
}
|
{
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for(auto& set : GameData::armour_sets) {
|
|
||||||
if(!set.second.neck_compatible) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ImGui::Selectable(set.second.name.data(), set.first == part.id, ImGuiSelectableFlags_SpanAvailWidth)) {
|
|
||||||
part.id = set.first;
|
part.id = set.first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,208 +107,231 @@ Application::drawArmour() {
|
||||||
ImGui::EndListBox();
|
ImGui::EndListBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndGroup();
|
ImGui::EndPopup();
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
|
|
||||||
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
|
||||||
|
|
||||||
ImGui::TextUnformatted("Styles:");
|
|
||||||
|
|
||||||
for(std::int32_t j = 0; j < 4; j++) {
|
|
||||||
drawAlignedText("Slot %d:", j + 1);
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
|
|
||||||
ImGui::PushID(j);
|
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - 2.0f);
|
|
||||||
if(ImGui::BeginCombo("##Style", getStyleName(part.styles[j], _currentMass->armourCustomStyles()).data())) {
|
|
||||||
for(const auto& style : GameData::style_names) {
|
|
||||||
if(ImGui::Selectable(getStyleName(style.first, _currentMass->armourCustomStyles()).data(), 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(std::uint32_t j = 0; j < part.decals.size(); j++) {
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::RadioButton(std::to_string(j + 1).c_str(), &_selectedArmourDecals[i], int(j));
|
|
||||||
}
|
|
||||||
|
|
||||||
drawDecalEditor(part.decals[_selectedArmourDecals[i]]);
|
|
||||||
|
|
||||||
ImGui::PopID();
|
|
||||||
|
|
||||||
if(!part.accessories.isEmpty()) {
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
ImGui::PushID("Accessory");
|
|
||||||
|
|
||||||
drawAlignedText("Showing/editing accessory");
|
|
||||||
for(std::uint32_t j = 0; j < part.accessories.size(); j++) {
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::RadioButton(std::string{char(65 + j)}.c_str(), &_selectedArmourAccessories[i], int(j));
|
|
||||||
}
|
|
||||||
|
|
||||||
drawAccessoryEditor(part.accessories[_selectedArmourAccessories[i]], _currentMass->armourCustomStyles());
|
|
||||||
|
|
||||||
ImGui::PopID();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
|
||||||
_modifiedBySaveTool = true;
|
|
||||||
if(!_currentMass->writeArmourPart(part.slot)) {
|
|
||||||
_modifiedBySaveTool = false;
|
|
||||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::PopID();
|
ImGui::SeparatorText("Styles");
|
||||||
|
|
||||||
|
for(std::int32_t i = 0; i < 4; i++) {
|
||||||
|
drawAlignedText("Slot %d:", i + 1);
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
ImGui::PushID(i);
|
||||||
|
if(ImGui::BeginCombo("##Style",
|
||||||
|
getStyleName(part.styles[i], _currentMass->armourCustomStyles()).data()))
|
||||||
|
{
|
||||||
|
for(const auto& style : GameData::style_names) {
|
||||||
|
if(ImGui::Selectable(getStyleName(style.first, _currentMass->armourCustomStyles()).data(),
|
||||||
|
part.styles[i] == style.first))
|
||||||
|
{
|
||||||
|
part.styles[i] = style.first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SeparatorText("Decals");
|
||||||
|
|
||||||
|
constexpr static float selectable_width = 25.0f;
|
||||||
|
|
||||||
|
drawAlignedText("Showing/editing decal:");
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, {0.5f, 0.0f});
|
||||||
|
for(std::uint32_t i = 0; i < part.decals.size(); i++) {
|
||||||
|
ImGui::SameLine();
|
||||||
|
if(ImGui::Selectable(std::to_string(i + 1).c_str(), _selectedArmourDecals[*_selectedArmourSlot] == int(i),
|
||||||
|
ImGuiSelectableFlags_None, {selectable_width, 0.0f}))
|
||||||
|
{
|
||||||
|
_selectedArmourDecals[*_selectedArmourSlot] = int(i);
|
||||||
|
}
|
||||||
|
if(i != part.decals.size() - 1) {
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
drawDecalEditor(part.decals[_selectedArmourDecals[*_selectedArmourSlot]]);
|
||||||
|
|
||||||
|
if(!part.accessories.isEmpty()) {
|
||||||
|
ImGui::SeparatorText("Accessories");
|
||||||
|
|
||||||
|
drawAlignedText("Showing/editing accessory:");
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, {0.5f, 0.0f});
|
||||||
|
for(std::uint32_t i = 0; i < part.accessories.size(); i++) {
|
||||||
|
ImGui::SameLine();
|
||||||
|
if(ImGui::Selectable((std::string{} + char(i + 65)).c_str(),
|
||||||
|
_selectedArmourAccessories[*_selectedArmourSlot] == int(i),
|
||||||
|
ImGuiSelectableFlags_None, {selectable_width, 0.0f}))
|
||||||
|
{
|
||||||
|
_selectedArmourAccessories[*_selectedArmourSlot] = int(i);
|
||||||
|
}
|
||||||
|
if(i != part.accessories.size() - 1) {
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
drawAccessoryEditor(part.accessories[_selectedArmourAccessories[*_selectedArmourSlot]],
|
||||||
|
_currentMass->armourCustomStyles());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_currentMass->bulletLauncherAttachmentStyle() != GameObjects::BulletLauncherAttachmentStyle::NotFound &&
|
ImGui::EndChild();
|
||||||
ImGui::CollapsingHeader("Bullet launcher placement"))
|
|
||||||
{
|
|
||||||
drawAlignedText("Attachment style:"_s);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::RadioButton("Active one",
|
|
||||||
_currentMass->bulletLauncherAttachmentStyle() == GameObjects::BulletLauncherAttachmentStyle::ActiveOne);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::RadioButton("Active one per slot",
|
|
||||||
_currentMass->bulletLauncherAttachmentStyle() == GameObjects::BulletLauncherAttachmentStyle::ActiveOnePerSlot);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::RadioButton("All equipped",
|
|
||||||
_currentMass->bulletLauncherAttachmentStyle() == GameObjects::BulletLauncherAttachmentStyle::AllEquipped);
|
|
||||||
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
drawAlignedText("Launcher slot:");
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::RadioButton("1", &_selectedBLPlacement, 0);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::RadioButton("2", &_selectedBLPlacement, 1);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::RadioButton("3", &_selectedBLPlacement, 2);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::RadioButton("4", &_selectedBLPlacement, 3);
|
|
||||||
|
|
||||||
auto& placement = _currentMass->bulletLauncherAttachments()[_selectedBLPlacement];
|
|
||||||
|
|
||||||
static const Containers::StringView socket_labels[] = {
|
|
||||||
#define c(enumerator, enumstr, name) name,
|
|
||||||
#include "../Maps/BulletLauncherSockets.hpp"
|
|
||||||
#undef c
|
|
||||||
};
|
|
||||||
|
|
||||||
drawAlignedText("Socket:");
|
|
||||||
ImGui::SameLine();
|
|
||||||
if(ImGui::BeginCombo("##Socket", socket_labels[std::uint32_t(placement.socket)].data())) {
|
|
||||||
for(std::uint32_t i = 0; i < (sizeof(socket_labels) / sizeof(socket_labels[0])); i++) {
|
|
||||||
if(ImGui::Selectable(socket_labels[i].data(), i == std::uint32_t(placement.socket), ImGuiSelectableFlags_SpanAvailWidth)) {
|
|
||||||
placement.socket = static_cast<GameObjects::BulletLauncherAttachment::Socket>(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::EndCombo();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(placement.socket != GameObjects::BulletLauncherAttachment::Socket::Auto) {
|
|
||||||
ImGui::BeginGroup();
|
|
||||||
drawAlignedText("Relative position:");
|
|
||||||
drawAlignedText("Offset position:");
|
|
||||||
drawAlignedText("Relative rotation:");
|
|
||||||
drawAlignedText("Offset rotation:");
|
|
||||||
drawAlignedText("Scale:");
|
|
||||||
ImGui::EndGroup();
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
|
||||||
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth());
|
|
||||||
ImGui::DragFloat("##RelPosX", &placement.relativeLocation.x(), 1.0f, -FLT_MAX, +FLT_MAX, "X: %.3f");
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
|
||||||
ImGui::DragFloat("##RelPosY", &placement.relativeLocation.y(), 1.0f, -FLT_MAX, +FLT_MAX, "Y: %.3f");
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
|
||||||
ImGui::DragFloat("##RelPosZ", &placement.relativeLocation.z(), 1.0f, -FLT_MAX, +FLT_MAX, "Z: %.3f");
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
|
|
||||||
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth());
|
|
||||||
ImGui::SliderFloat("##OffPosX", &placement.offsetLocation.x(), -500.0f, +500.0f, "X: %.3f");
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
|
||||||
ImGui::SliderFloat("##OffPosY", &placement.offsetLocation.y(), -500.0f, +500.0f, "Y: %.3f");
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
|
||||||
ImGui::SliderFloat("##OffPosZ", &placement.offsetLocation.z(), -500.0f, +500.0f, "Z: %.3f");
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
ImGui::SameLine();
|
|
||||||
drawHelpMarker("+/-500.0 = +/-250 in-game");
|
|
||||||
|
|
||||||
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth());
|
|
||||||
ImGui::DragFloat("##RotX", &placement.relativeRotation.x(), 1.0f, -FLT_MAX, +FLT_MAX, "Roll: %.3f");
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
|
||||||
ImGui::DragFloat("##RotY", &placement.relativeRotation.y(), 1.0f, -FLT_MAX, +FLT_MAX, "Yaw: %.3f");
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
|
||||||
ImGui::DragFloat("##RotZ", &placement.relativeRotation.z(), 1.0f, -FLT_MAX, +FLT_MAX, "Pitch: %.3f");
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
|
|
||||||
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth());
|
|
||||||
ImGui::SliderFloat("##RotOffsetZ", &placement.offsetRotation.z(), -180.0f, +180.0f, "Roll: %.3f");
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
|
||||||
ImGui::SliderFloat("##RotOffsetX", &placement.offsetRotation.x(), -30.0f, +30.0f, "Pitch: %.3f");
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
|
||||||
ImGui::SliderFloat("##RotOffsetY", &placement.offsetRotation.y(), -30.0f, +30.0f, "Yaw: %.3f");
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
|
|
||||||
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth());
|
|
||||||
ImGui::SliderFloat("##ScaleX", &placement.relativeScale.x(), 0.5f, 1.5f, "X: %.3f");
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
|
||||||
ImGui::SliderFloat("##ScaleY", &placement.relativeScale.y(), 0.5f, 1.5f, "Y: %.3f");
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
|
||||||
ImGui::SliderFloat("##ScaleZ", &placement.relativeScale.z(), 0.5f, 1.5f, "Z: %.3f");
|
|
||||||
ImGui::PopItemWidth();
|
|
||||||
ImGui::SameLine();
|
|
||||||
drawHelpMarker("0.5 = 50 in-game\n1.5 = 150 in-game");
|
|
||||||
ImGui::EndGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
||||||
_modifiedBySaveTool = true;
|
_modifiedBySaveTool = true;
|
||||||
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); }) &&
|
if(!_currentMass->writeArmourPart(part.slot)) {
|
||||||
!_currentMass->writeBulletLauncherAttachments())
|
|
||||||
{
|
|
||||||
_modifiedBySaveTool = false;
|
_modifiedBySaveTool = false;
|
||||||
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndChild();
|
ImGui::EndGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Application::drawBLAttachment() {
|
||||||
|
if(!_currentMass || _currentMass->state() != GameObjects::Mass::State::Valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawAlignedText("Attachment style:"_s);
|
||||||
|
ImGui::SameLine();
|
||||||
|
if(ImGui::RadioButton("Active one",
|
||||||
|
_currentMass->bulletLauncherAttachmentStyle() == GameObjects::BulletLauncherAttachmentStyle::ActiveOne))
|
||||||
|
{
|
||||||
|
_currentMass->bulletLauncherAttachmentStyle() = GameObjects::BulletLauncherAttachmentStyle::ActiveOne;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if(ImGui::RadioButton("Active one per slot",
|
||||||
|
_currentMass->bulletLauncherAttachmentStyle() == GameObjects::BulletLauncherAttachmentStyle::ActiveOnePerSlot))
|
||||||
|
{
|
||||||
|
_currentMass->bulletLauncherAttachmentStyle() = GameObjects::BulletLauncherAttachmentStyle::ActiveOnePerSlot;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if(ImGui::RadioButton("All equipped",
|
||||||
|
_currentMass->bulletLauncherAttachmentStyle() == GameObjects::BulletLauncherAttachmentStyle::AllEquipped))
|
||||||
|
{
|
||||||
|
_currentMass->bulletLauncherAttachmentStyle() = GameObjects::BulletLauncherAttachmentStyle::ActiveOnePerSlot;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
constexpr static float selectable_width = 25.0f;
|
||||||
|
drawAlignedText("Launcher slot:");
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, {0.5f, 0.0f});
|
||||||
|
for(auto i = 0u; i < _currentMass->bulletLauncherAttachments().size(); i++) {
|
||||||
|
ImGui::SameLine();
|
||||||
|
if(ImGui::Selectable(std::to_string(i).c_str(), _selectedBLPlacement == i, ImGuiSelectableFlags_None,
|
||||||
|
{selectable_width, 0.0f}))
|
||||||
|
{
|
||||||
|
_selectedBLPlacement = i;
|
||||||
|
}
|
||||||
|
if(i != _currentMass->bulletLauncherAttachments().size() - 1) {
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::PopStyleVar();
|
||||||
|
|
||||||
|
auto& placement = _currentMass->bulletLauncherAttachments()[_selectedBLPlacement];
|
||||||
|
|
||||||
|
static const Containers::StringView socket_labels[] = {
|
||||||
|
#define c(enumerator, enumstr, name) name,
|
||||||
|
#include "../Maps/BulletLauncherSockets.hpp"
|
||||||
|
#undef c
|
||||||
|
};
|
||||||
|
|
||||||
|
drawAlignedText("Socket:");
|
||||||
|
ImGui::SameLine();
|
||||||
|
if(ImGui::BeginCombo("##Socket", socket_labels[std::uint32_t(placement.socket)].data())) {
|
||||||
|
for(std::uint32_t i = 0; i < (sizeof(socket_labels) / sizeof(socket_labels[0])); i++) {
|
||||||
|
if(ImGui::Selectable(socket_labels[i].data(), i == std::uint32_t(placement.socket), ImGuiSelectableFlags_SpanAvailWidth)) {
|
||||||
|
placement.socket = static_cast<GameObjects::BulletLauncherAttachment::Socket>(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(placement.socket != GameObjects::BulletLauncherAttachment::Socket::Auto) {
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
drawAlignedText("Relative position:");
|
||||||
|
drawAlignedText("Offset position:");
|
||||||
|
drawAlignedText("Relative rotation:");
|
||||||
|
drawAlignedText("Offset rotation:");
|
||||||
|
drawAlignedText("Scale:");
|
||||||
|
ImGui::EndGroup();
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
ImGui::BeginGroup();
|
||||||
|
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth());
|
||||||
|
ImGui::DragFloat("##RelPosX", &placement.relativeLocation.x(), 1.0f, -FLT_MAX, +FLT_MAX, "X: %.3f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||||
|
ImGui::DragFloat("##RelPosY", &placement.relativeLocation.y(), 1.0f, -FLT_MAX, +FLT_MAX, "Y: %.3f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||||
|
ImGui::DragFloat("##RelPosZ", &placement.relativeLocation.z(), 1.0f, -FLT_MAX, +FLT_MAX, "Z: %.3f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
|
||||||
|
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth());
|
||||||
|
ImGui::SliderFloat("##OffPosX", &placement.offsetLocation.x(), -500.0f, +500.0f, "X: %.3f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||||
|
ImGui::SliderFloat("##OffPosY", &placement.offsetLocation.y(), -500.0f, +500.0f, "Y: %.3f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||||
|
ImGui::SliderFloat("##OffPosZ", &placement.offsetLocation.z(), -500.0f, +500.0f, "Z: %.3f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::SameLine();
|
||||||
|
drawHelpMarker("+/-500.0 = +/-250 in-game");
|
||||||
|
|
||||||
|
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth());
|
||||||
|
ImGui::DragFloat("##RotX", &placement.relativeRotation.x(), 1.0f, -FLT_MAX, +FLT_MAX, "Roll: %.3f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||||
|
ImGui::DragFloat("##RotY", &placement.relativeRotation.y(), 1.0f, -FLT_MAX, +FLT_MAX, "Yaw: %.3f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||||
|
ImGui::DragFloat("##RotZ", &placement.relativeRotation.z(), 1.0f, -FLT_MAX, +FLT_MAX, "Pitch: %.3f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
|
||||||
|
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth());
|
||||||
|
ImGui::SliderFloat("##RotOffsetZ", &placement.offsetRotation.z(), -180.0f, +180.0f, "Roll: %.3f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||||
|
ImGui::SliderFloat("##RotOffsetX", &placement.offsetRotation.x(), -30.0f, +30.0f, "Pitch: %.3f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||||
|
ImGui::SliderFloat("##RotOffsetY", &placement.offsetRotation.y(), -30.0f, +30.0f, "Yaw: %.3f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
|
||||||
|
ImGui::PushMultiItemsWidths(3, ImGui::CalcItemWidth());
|
||||||
|
ImGui::SliderFloat("##ScaleX", &placement.relativeScale.x(), 0.5f, 1.5f, "X: %.3f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||||
|
ImGui::SliderFloat("##ScaleY", &placement.relativeScale.y(), 0.5f, 1.5f, "Y: %.3f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
|
||||||
|
ImGui::SliderFloat("##ScaleZ", &placement.relativeScale.z(), 0.5f, 1.5f, "Z: %.3f");
|
||||||
|
ImGui::PopItemWidth();
|
||||||
|
ImGui::SameLine();
|
||||||
|
drawHelpMarker("0.5 = 50 in-game\n1.5 = 150 in-game");
|
||||||
|
ImGui::EndGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
_modifiedBySaveTool = true;
|
||||||
|
if(drawUnsafeWidget([]{ return ImGui::Button(ICON_FA_SAVE " Save"); })) {
|
||||||
|
_modifiedBySaveTool = true;
|
||||||
|
if(!_currentMass->writeBulletLauncherAttachments()) {
|
||||||
|
_modifiedBySaveTool = false;
|
||||||
|
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in a new issue