yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
minecart_rail_tools.cc
Go to the documentation of this file.
2
3#include <algorithm>
4
6#include "imgui/imgui.h"
7
8namespace yaze::editor {
9
11 if (!ImGui::BeginTabBar("##RailTools")) {
12 return;
13 }
14 if (ImGui::BeginTabItem("Rails")) {
15 ImGui::Checkbox("Auto collision", &automatic_rail_collision_);
16 gui::AutoRegisterLastItem("checkbox", "Auto collision");
17 if (ImGui::IsItemHovered()) {
18 ImGui::SetTooltip(
19 "Straight rails set collision with placement and Undo. "
20 "Corners and crossings need explicit behavior until their "
21 "collision patterns are verified. Existing collision is preserved.");
22 }
24 set_canvas_editing(false);
26 placement_brush_.reset();
27 }
28 ImGui::EndTabItem();
29 }
30 if (ImGui::BeginTabItem("Nodes")) {
32 ImGui::EndTabItem();
33 }
34 if (!ImGui::BeginTabItem("Behavior")) {
35 ImGui::EndTabBar();
36 return;
37 }
38 bool stamping = collision_stamping_;
39 ImGui::BeginDisabled(!apply_collision_stamp_);
40 if (ImGui::Checkbox("Stamp rail behavior", &stamping)) {
41 set_collision_stamping(stamping);
42 }
43 gui::AutoRegisterLastItem("checkbox", "Stamp rail behavior");
44 ImGui::EndDisabled();
46 ImGui::EndTabItem();
47 ImGui::EndTabBar();
48 return;
49 }
50
51 struct Behavior {
52 uint8_t value;
53 const char* label;
54 };
55 static constexpr Behavior kBehaviors[] = {
56 {0xB0, "Straight: horizontal"},
57 {0xB1, "Straight: vertical"},
58 {0xB2, "Corner: right / down"},
59 {0xB3, "Corner: right / up"},
60 {0xB4, "Corner: left / down"},
61 {0xB5, "Corner: left / up"},
62 {0xB6, "Crossing"},
63 {0xB7, "Stop: depart south"},
64 {0xB8, "Stop: depart north"},
65 {0xB9, "Stop: depart east"},
66 {0xBA, "Stop: depart west"},
67 {0xBB, "Junction: south / east / west"},
68 {0xBC, "Junction: north / east / west"},
69 {0xBD, "Junction: north / south / west"},
70 {0xBE, "Junction: north / south / east"},
71 {0xD0, "Switch: right / down"},
72 {0xD1, "Switch: right / up"},
73 {0xD2, "Switch: left / down"},
74 {0xD3, "Switch: left / up"},
75 {0x00, "Erase rail behavior"}};
76 const char* selected = kBehaviors[1].label;
77 for (const auto& behavior : kBehaviors) {
78 if (behavior.value == collision_stamp_value_)
79 selected = behavior.label;
80 }
81 ImGui::SetNextItemWidth(-1);
82 const bool open = ImGui::BeginCombo("##RailBehavior", selected);
83 gui::AutoRegisterLastItem("combo", "RailBehavior");
84 if (open) {
85 for (const auto& behavior : kBehaviors) {
86 if (ImGui::Selectable(behavior.label,
87 behavior.value == collision_stamp_value_)) {
88 collision_stamp_value_ = behavior.value;
89 }
90 gui::AutoRegisterLastItem("selectable", behavior.label);
91 }
92 ImGui::EndCombo();
93 }
94 ImGui::Checkbox("2 x 2 cells (16 pixels)", &collision_stamp_large_);
95 ImGui::TextDisabled("Click to stamp. Drag a matching node to move it.");
96 ImGui::EndTabItem();
97 ImGui::EndTabBar();
98}
99
101 ImGui::SetNextItemWidth(ImGui::CalcTextSize("00000").x +
102 2 * ImGui::GetStyle().FramePadding.x);
103 ImGui::InputInt("ID", &node_id_, 0, 0);
104 node_id_ = std::clamp(node_id_, 0, 31);
105 gui::AutoRegisterLastItem("input", "Node ID");
106 if (ImGui::IsItemHovered()) {
107 ImGui::SetTooltip(
108 "Cart: unused route 0-31. Switches: shared channel 0-31. "
109 "Move an existing cart using its room marker.");
110 }
111 ImGui::SetNextItemWidth(-1);
112 ImGui::Combo("##Departure", &node_departure_,
113 "Depart south\0Depart north\0Depart east\0Depart west\0");
114 gui::AutoRegisterLastItem("combo", "Departure");
115 ImGui::SetNextItemWidth(-1);
116 ImGui::Combo("##SwitchOrientation", &node_switch_orientation_,
117 "Switch: right / down\0Switch: right / up\0"
118 "Switch: left / down\0Switch: left / up\0");
119 gui::AutoRegisterLastItem("combo", "Switch orientation");
120 ImGui::SetNextItemWidth(-1);
121 ImGui::Combo("##JunctionExits", &node_junction_,
122 "T: south / east / west\0T: north / east / west\0"
123 "T: north / south / west\0T: north / south / east\0");
124 gui::AutoRegisterLastItem("combo", "Junction exits");
125 auto row = [&](const char* label, const char* help,
126 MinecartToolPayload payload) {
127 ImGui::BeginDisabled(payload.collision_only ? !apply_collision_stamp_
128 : !place_node_);
129 if (ImGui::Selectable(label, false, 0,
130 ImVec2(0, ImGui::GetFrameHeight()))) {
131 SetPlacementBrush(payload);
132 }
133 gui::AutoRegisterLastItem("selectable", label);
134 if (ImGui::BeginDragDropSource()) {
135 payload.owner = this;
136 payload.revision = canvas_revision_;
137 payload.room_id = active_room_;
138 ImGui::SetDragDropPayload(kMinecartNodeDragPayload, &payload,
139 sizeof(payload), ImGuiCond_Once);
140 ImGui::TextUnformatted(label);
141 ImGui::EndDragDropSource();
142 }
143 if (ImGui::IsItemHovered()) {
144 ImGui::SetTooltip("%s\nDrag to the room, or click then place.", help);
145 }
146 ImGui::EndDisabled();
147 };
148 const auto stop = static_cast<uint8_t>(0xB7 + node_departure_);
149 const auto rotating = static_cast<uint8_t>(0xD0 + node_switch_orientation_);
150 row("Cart spawn", "Adds a cart, its route start and a stop.",
152 row("End stop", "Sets the cart's departure direction.", {{}, true, stop, 1});
153 row("Switch", "Links a lever to this channel.",
155 row("Switch track", "Places a rotating track and its collision.",
157 row("T junction", "Sets the three available exits. Artwork is separate.",
158 {{}, true, static_cast<uint8_t>(0xBB + node_junction_), 1});
159}
160
161} // namespace yaze::editor
std::optional< MinecartToolPayload > placement_brush_
void SetPlacementBrush(const MinecartToolPayload &brush)
Editors are the view controllers for the application.
constexpr const char * kMinecartNodeDragPayload
void AutoRegisterLastItem(const std::string &widget_type, const std::string &explicit_label, const std::string &description)
Automatically register the last ImGui item.
Automatic widget registration helpers for ImGui Test Engine integration.