12 if (!overworld || !overworld->
is_loaded()) {
13 return absl::FailedPreconditionError(
"Overworld not loaded");
25 auto& holes = overworld->
holes();
26 for (
size_t i = 0; i < holes.size(); ++i) {
27 if (holes[i].deleted) {
29 holes[i].deleted =
false;
30 holes[i].map_id_ = map_id;
31 holes[i].x_ =
static_cast<int>(snapped_pos.x);
32 holes[i].y_ =
static_cast<int>(snapped_pos.y);
33 holes[i].entrance_id_ = 0;
34 holes[i].is_hole_ =
true;
37 holes[i].UpdateMapProperties(map_id, overworld);
40 "Inserted hole at slot %zu: pos=(%d,%d) map=0x%02X", i,
41 holes[i].x_, holes[i].y_, map_id);
46 return absl::ResourceExhaustedError(
47 "No space available for new hole. Delete one first.");
52 for (
size_t i = 0; i < entrances->size(); ++i) {
53 if (entrances->at(i).deleted) {
55 entrances->at(i).deleted =
false;
56 entrances->at(i).map_id_ = map_id;
57 entrances->at(i).x_ =
static_cast<int>(snapped_pos.x);
58 entrances->at(i).y_ =
static_cast<int>(snapped_pos.y);
59 entrances->at(i).entrance_id_ = 0;
60 entrances->at(i).is_hole_ =
false;
63 entrances->at(i).UpdateMapProperties(map_id, overworld);
66 "Inserted entrance at slot %zu: pos=(%d,%d) map=0x%02X", i,
67 entrances->at(i).x_, entrances->at(i).y_, map_id);
69 return &entrances->at(i);
72 return absl::ResourceExhaustedError(
73 "No space available for new entrance. Delete one first.");
80 if (!overworld || !overworld->
is_loaded()) {
81 return absl::FailedPreconditionError(
"Overworld not loaded");
93 for (
size_t i = 0; i < exits.size(); ++i) {
94 if (exits[i].deleted_) {
96 exits[i].deleted_ =
false;
97 exits[i].map_id_ = map_id;
98 exits[i].x_ =
static_cast<int>(snapped_pos.x);
99 exits[i].y_ =
static_cast<int>(snapped_pos.y);
103 exits[i].room_id_ = 0;
104 exits[i].x_scroll_ = 0;
105 exits[i].y_scroll_ = 0;
106 exits[i].x_camera_ = 0;
107 exits[i].y_camera_ = 0;
108 exits[i].x_player_ =
static_cast<uint16_t
>(snapped_pos.x);
109 exits[i].y_player_ =
static_cast<uint16_t
>(snapped_pos.y);
110 exits[i].scroll_mod_x_ = 0;
111 exits[i].scroll_mod_y_ = 0;
112 exits[i].door_type_1_ = 0;
113 exits[i].door_type_2_ = 0;
116 exits[i].UpdateMapProperties(map_id, overworld);
119 "Inserted exit at slot %zu: pos=(%d,%d) map=0x%02X", i,
120 exits[i].x_, exits[i].y_, map_id);
126 return absl::ResourceExhaustedError(
127 "No space available for new exit. Delete one first.");
131 ImVec2 mouse_pos,
int current_map,
134 if (!overworld || !overworld->
is_loaded()) {
135 return absl::FailedPreconditionError(
"Overworld not loaded");
138 if (game_state < 0 || game_state > 2) {
139 return absl::InvalidArgumentError(
"Invalid game state (must be 0-2)");
147 auto* current_ow_map = overworld->
overworld_map(current_map);
152 int map_local_x =
static_cast<int>(snapped_pos.x) % 512;
153 int map_local_y =
static_cast<int>(snapped_pos.y) % 512;
156 uint8_t game_x =
static_cast<uint8_t
>(map_local_x / 16);
157 uint8_t game_y =
static_cast<uint8_t
>(map_local_y / 16);
164 current_ow_map->current_graphics(),
static_cast<uint8_t
>(map_id),
168 static_cast<int>(snapped_pos.x),
169 static_cast<int>(snapped_pos.y)
172 sprites.push_back(new_sprite);
179 "Inserted sprite at game_state=%d: pos=(%d,%d) map=0x%02X id=0x%02X",
180 game_state, inserted_sprite->
x_, inserted_sprite->
y_, map_id, sprite_id);
182 return inserted_sprite;
189 if (!overworld || !overworld->
is_loaded()) {
190 return absl::FailedPreconditionError(
"Overworld not loaded");
197 auto* current_ow_map = overworld->
overworld_map(current_map);
202 int fake_id = current_map % 0x40;
203 int sy = fake_id / 8;
204 int sx = fake_id - (sy * 8);
207 int map_local_x =
static_cast<int>(snapped_pos.x) % 512;
208 int map_local_y =
static_cast<int>(snapped_pos.y) % 512;
211 uint8_t game_x =
static_cast<uint8_t
>(map_local_x / 16);
212 uint8_t game_y =
static_cast<uint8_t
>(map_local_y / 16);
218 items.emplace_back(item_id,
219 static_cast<uint16_t
>(map_id),
220 static_cast<int>(snapped_pos.x),
221 static_cast<int>(snapped_pos.y),
227 inserted_item->
game_x_ = game_x;
228 inserted_item->
game_y_ = game_y;
231 "Inserted item: pos=(%d,%d) game=(%d,%d) map=0x%02X id=0x%02X",
232 inserted_item->
x_, inserted_item->
y_, game_x, game_y, map_id,
235 return inserted_item;
absl::StatusOr< zelda3::OverworldItem * > InsertItem(zelda3::Overworld *overworld, ImVec2 mouse_pos, int current_map, uint8_t item_id)
Insert a new item at the specified position.
absl::StatusOr< zelda3::OverworldEntrance * > InsertEntrance(zelda3::Overworld *overworld, ImVec2 mouse_pos, int current_map, bool is_hole)
Flat helper functions for entity insertion/manipulation.
absl::StatusOr< zelda3::Sprite * > InsertSprite(zelda3::Overworld *overworld, ImVec2 mouse_pos, int current_map, int game_state, uint8_t sprite_id)
Insert a new sprite at the specified position.