Compare commits

...

2 commits

Author SHA1 Message Date
04beebbc1c SaveTool: implement the UI for BL placement editing. 2022-03-20 10:17:14 +01:00
47520b89e3 Mass: implement BL attachment writing.
Needs testing, though.
2022-03-20 10:16:39 +01:00
4 changed files with 212 additions and 1 deletions

View file

@ -237,7 +237,95 @@ void Mass::getBulletLauncherAttachments() {
} }
auto Mass::writeBulletLauncherAttachments() -> bool { auto Mass::writeBulletLauncherAttachments() -> bool {
auto unit_data = _mass->at<GenericStructProperty>("UnitData"_s);
if(!unit_data) {
_state = State::Invalid;
_lastError = "No unit data in " + _filename;
return false; return false;
}
auto attach_style_prop = unit_data->at<ByteProperty>("WeaponBLAttachmentStyle_65_5943FCE8406F18D2C3F69285EB23A699"_s);
auto attach_array = unit_data->at<ArrayProperty>("WeaponBLAttachment_61_442D08F547510A4CEE1501BBAF297BA0"_s);
if(!attach_style_prop && !attach_array) {
_armour.blAttachmentStyle = BulletLauncherAttachmentStyle::NotFound;
_lastError = "No attachment properties to write to in " + _filename;
return false;
}
if(attach_style_prop && !attach_array) {
_armour.blAttachmentStyle = BulletLauncherAttachmentStyle::NotFound;
_state = State::Invalid;
_lastError = "Couldn't find the attachments in " + _filename;
return false;
}
if(attach_array->items.size() == _weapons.bulletLaunchers.size() &&
attach_array->items.size() == _armour.blAttachment.size())
{
for(UnsignedInt i = 0; i < attach_array->items.size(); i++) {
auto attachment_prop = attach_array->at<GenericStructProperty>(i);
auto& attachment = _armour.blAttachment[i];
auto& socket = attachment_prop->at<StringProperty>("Socket_9_B9DBF30D4A1F0032A2BE2F8B342B35A9"_s)->value;
switch(attachment.socket) {
#define c(enumerator, strenum, name) case BulletLauncherSocket::enumerator: socket = strenum; break;
#include "../Maps/BulletLauncherSockets.hpp"
#undef c
default:
_lastError = "Invalid socket type."_s;
return false;
}
auto rel_loc_prop = attachment_prop->at<VectorStructProperty>("RelativeLocation_10_2F6E75DF4C40622658340E9A22D38B02"_s);
rel_loc_prop->x = attachment.relativeLocation.x();
rel_loc_prop->y = attachment.relativeLocation.y();
rel_loc_prop->z = attachment.relativeLocation.z();
auto off_loc_prop = attachment_prop->at<VectorStructProperty>("OffsetLocation_11_F42B3DA3436948FF85752DB33722382F"_s);
off_loc_prop->x = attachment.offsetLocation.x();
off_loc_prop->y = attachment.offsetLocation.y();
off_loc_prop->z = attachment.offsetLocation.z();
auto rel_rot_prop = attachment_prop->at<VectorStructProperty>("RelativeRotation_12_578140464621245132CFF2A2AD85E735"_s);
rel_rot_prop->x = attachment.relativeRotation.x();
rel_rot_prop->y = attachment.relativeRotation.y();
rel_rot_prop->z = attachment.relativeRotation.z();
auto off_rot_prop = attachment_prop->at<VectorStructProperty>("OffsetRotation_13_B5980BCD47905D842D1490A1A520B064"_s);
off_rot_prop->x = attachment.offsetRotation.x();
off_rot_prop->y = attachment.offsetRotation.y();
off_rot_prop->z = attachment.offsetRotation.z();
auto rel_scale_prop = attachment_prop->at<VectorStructProperty>("RelativeScale_16_37BC80EF42699F79533F7AA7B3094E38"_s);
rel_scale_prop->x = attachment.relativeScale.x();
rel_scale_prop->y = attachment.relativeScale.y();
rel_scale_prop->z = attachment.relativeScale.z();
}
}
if(!attach_style_prop) {
attach_style_prop = new ByteProperty;
attach_style_prop->name.emplace("WeaponBLAttachmentStyle_65_5943FCE8406F18D2C3F69285EB23A699"_s);
attach_style_prop->enumType = "enuBLAttachmentStyle"_s;
ByteProperty::ptr prop{attach_style_prop};
arrayAppend(unit_data->properties, std::move(prop));
}
auto& attach_style = attach_style_prop->enumValue;
switch(_armour.blAttachmentStyle) {
#define c(enumerator, strenum) case BulletLauncherAttachmentStyle::enumerator: \
attach_style = strenum; \
break;
#include "../Maps/BulletLauncherAttachmentStyles.hpp"
#undef c
default:
_lastError = "Unknown BL attachment style.";
return false;
}
if(!_mass->saveToFile()) {
_lastError = _mass->lastError();
return false;
}
return true;
} }
auto Mass::armourCustomStyles() -> Containers::ArrayView<CustomStyle> { auto Mass::armourCustomStyles() -> Containers::ArrayView<CustomStyle> {

View file

@ -282,6 +282,7 @@ class SaveTool: public Platform::Sdl2Application, public efsw::FileWatchListener
bool _eyeFlareDirty{false}; bool _eyeFlareDirty{false};
Containers::StaticArray<38, Int> _selectedArmourDecals{ValueInit}; Containers::StaticArray<38, Int> _selectedArmourDecals{ValueInit};
Containers::StaticArray<38, Int> _selectedArmourAccessories{ValueInit}; Containers::StaticArray<38, Int> _selectedArmourAccessories{ValueInit};
Int _selectedBLPlacement{0};
Int _selectedWeaponPart{0}; Int _selectedWeaponPart{0};
Int _selectedWeaponDecal{0}; Int _selectedWeaponDecal{0};
Int _selectedWeaponAccessory{0}; Int _selectedWeaponAccessory{0};

View file

@ -87,6 +87,7 @@ void SaveTool::drawMassViewer() {
_eyeFlareDirty = false; _eyeFlareDirty = false;
_selectedArmourDecals = Containers::StaticArray<38, Int>{ValueInit}; _selectedArmourDecals = Containers::StaticArray<38, Int>{ValueInit};
_selectedArmourAccessories = Containers::StaticArray<38, Int>{ValueInit}; _selectedArmourAccessories = Containers::StaticArray<38, Int>{ValueInit};
_selectedBLPlacement = 0;
_selectedWeaponPart = 0; _selectedWeaponPart = 0;
_selectedWeaponDecal = 0; _selectedWeaponDecal = 0;
_selectedWeaponAccessory = 0; _selectedWeaponAccessory = 0;

View file

@ -28,6 +28,7 @@ void SaveTool::drawArmour() {
if(ImGui::Button(ICON_FA_UNDO_ALT " Reset all")) { if(ImGui::Button(ICON_FA_UNDO_ALT " Reset all")) {
_currentMass->getArmourParts(); _currentMass->getArmourParts();
_currentMass->getBulletLauncherAttachments();
} }
if(!ImGui::BeginChild("##ArmourParts", {0.0f, 0.0f}, true)) { if(!ImGui::BeginChild("##ArmourParts", {0.0f, 0.0f}, true)) {
@ -160,6 +161,126 @@ void SaveTool::drawArmour() {
ImGui::PopID(); ImGui::PopID();
} }
if(_currentMass->bulletLauncherAttachmentStyle() != BulletLauncherAttachmentStyle::NotFound &&
ImGui::CollapsingHeader("Bullet launcher placement"))
{
drawAlignedText("Attachment style:"_s);
ImGui::SameLine();
ImGui::RadioButton("Active one",
_currentMass->bulletLauncherAttachmentStyle() == BulletLauncherAttachmentStyle::ActiveOne);
ImGui::SameLine();
ImGui::RadioButton("Active one per slot",
_currentMass->bulletLauncherAttachmentStyle() == BulletLauncherAttachmentStyle::ActiveOnePerSlot);
ImGui::SameLine();
ImGui::RadioButton("All equipped",
_currentMass->bulletLauncherAttachmentStyle() == 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[UnsignedInt(placement.socket)].data())) {
for(UnsignedInt i = 0; i < (sizeof(socket_labels) / sizeof(socket_labels[0])); i++) {
if(ImGui::Selectable(socket_labels[i].data(), i == UnsignedInt(placement.socket), ImGuiSelectableFlags_SpanAvailWidth)) {
placement.socket = static_cast<BulletLauncherSocket>(i);
}
}
ImGui::EndCombo();
}
if(placement.socket != BulletLauncherSocket::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"); }) &&
!_currentMass->writeBulletLauncherAttachments())
{
_queue.addToast(Toast::Type::Error, _currentMass->lastError());
}
}
ImGui::EndChild(); ImGui::EndChild();
} }