yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
entity_mutation_service.cc
Go to the documentation of this file.
2
3#include <algorithm>
4
7
8namespace yaze {
9namespace editor {
10
12 : overworld_(overworld) {}
13
15 const std::string& type, const OverworldContextTarget& target,
16 uint8_t item_id) {
17 MutationResult result;
18 const auto* map = overworld_.overworld_map(target.map_id);
19 const bool is_project_terrain = target.map_id >= 0xA0 && target.map_id < 0xC0;
21 (!map && !is_project_terrain) ||
22 (map && GetParentMapId(map, target.map_id) != target.parent_map_id)) {
23 result.status = absl::FailedPreconditionError(
24 "The insertion target is no longer available. Open the map menu "
25 "again.");
26 result.error_message = std::string(result.status.message());
27 return result;
28 }
29 return InsertEntity(type, target.world_position, target.map_id,
30 target.game_state, item_id);
31}
32
34 const std::string& type, ImVec2 pos, int map_id, int game_state,
35 uint8_t item_id) {
36 MutationResult result;
37
38 if (type == "entrance") {
39 auto res = editor::InsertEntrance(&overworld_, pos, map_id, false);
40 if (res.ok()) {
41 result.entity = *res;
42 } else {
43 result.status = res.status();
44 result.error_message =
45 "Cannot insert entrance: " + std::string(res.status().message());
46 }
47 } else if (type == "hole") {
48 auto res = editor::InsertEntrance(&overworld_, pos, map_id, true);
49 if (res.ok()) {
50 result.entity = *res;
51 } else {
52 result.status = res.status();
53 result.error_message =
54 "Cannot insert hole: " + std::string(res.status().message());
55 }
56 } else if (type == "exit") {
57 auto res = editor::InsertExit(&overworld_, pos, map_id);
58 if (res.ok()) {
59 result.entity = *res;
60 } else {
61 result.status = res.status();
62 result.error_message =
63 "Cannot insert exit: " + std::string(res.status().message());
64 }
65 } else if (type == "item") {
66 auto res = editor::InsertItem(&overworld_, pos, map_id, item_id);
67 if (res.ok()) {
68 result.entity = *res;
69 } else {
70 result.status = res.status();
71 result.error_message =
72 "Cannot insert item: " + std::string(res.status().message());
73 }
74 } else if (type == "sprite") {
75 auto res = editor::InsertSprite(&overworld_, pos, map_id, game_state, 0x00);
76 if (res.ok()) {
77 result.entity = *res;
78 } else {
79 result.status = res.status();
80 result.error_message =
81 "Cannot insert sprite: " + std::string(res.status().message());
82 }
83 } else {
84 result.status = absl::InvalidArgumentError("Unknown entity type: " + type);
85 }
86
87 return result;
88}
89
91 const zelda3::OverworldItem& source, int offset_x, int offset_y) {
92 MutationResult result;
93 auto res =
94 editor::DuplicateItemByIdentity(&overworld_, source, offset_x, offset_y);
95 if (res.ok()) {
96 result.entity = *res;
97 } else {
98 result.status = res.status();
99 result.error_message = "Failed to duplicate overworld item: " +
100 std::string(res.status().message());
101 }
102 return result;
103}
104
106 const zelda3::OverworldItem& item_identity) {
107 MutationResult result;
108 result.status = editor::RemoveItemByIdentity(&overworld_, item_identity);
109 if (!result.status.ok()) {
110 result.error_message = "Failed to delete selected item: " +
111 std::string(result.status.message());
112 }
113 return result;
114}
115
117 zelda3::Sprite* sprite, int game_state) {
118 MutationResult result;
119 if (!sprite) {
120 result.status = absl::InvalidArgumentError("Sprite is null");
121 return result;
122 }
123
124 auto& sprites = *overworld_.mutable_sprites(game_state);
125 auto it =
126 std::find_if(sprites.begin(), sprites.end(),
127 [sprite](const zelda3::Sprite& s) { return &s == sprite; });
128
129 if (it != sprites.end()) {
130 sprites.erase(it);
131 } else {
132 result.status =
133 absl::NotFoundError("Sprite not found in current game state");
134 }
135 return result;
136}
137
139 zelda3::OverworldEntrance* entrance) {
140 MutationResult result;
141 if (!entrance) {
142 result.status = absl::InvalidArgumentError("Entrance is null");
143 return result;
144 }
145 entrance->deleted = true;
146 return result;
147}
148
150 zelda3::OverworldExit* exit) {
151 MutationResult result;
152 if (!exit) {
153 result.status = absl::InvalidArgumentError("Exit is null");
154 return result;
155 }
156 exit->deleted_ = true;
157 return result;
158}
159
164
165} // namespace editor
166} // namespace yaze
EntityMutationService(zelda3::Overworld &overworld)
MutationResult DuplicateItem(const zelda3::OverworldItem &source, int offset_x, int offset_y)
MutationResult InsertEntity(const std::string &type, ImVec2 pos, int map_id, int game_state, uint8_t item_id=0)
Dispatches entity insertion based on type string.
MutationResult DeleteEntrance(zelda3::OverworldEntrance *entrance)
MutationResult DeleteItem(const zelda3::OverworldItem &item_identity)
zelda3::OverworldItem * ResolveNextSelection(const zelda3::OverworldItem &anchor_identity)
Resolves the best next item to select after a deletion.
MutationResult DeleteExit(zelda3::OverworldExit *exit)
MutationResult DeleteSprite(zelda3::Sprite *sprite, int game_state)
Represents an overworld exit that transitions from dungeon to overworld.
auto is_loaded() const
Definition overworld.h:836
auto overworld_map(int i) const
Definition overworld.h:770
auto mutable_sprites(int state)
Definition overworld.h:792
A class for managing sprites in the overworld and underworld.
Definition sprite.h:39
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::Status RemoveItemByIdentity(zelda3::Overworld *overworld, const zelda3::OverworldItem &item_identity)
Remove an item by value identity instead of pointer identity.
absl::StatusOr< zelda3::OverworldEntrance * > InsertEntrance(zelda3::Overworld *overworld, ImVec2 mouse_pos, int current_map, bool is_hole)
Flat helper functions for entity insertion/manipulation.
zelda3::OverworldItem * FindNearestItemForSelection(zelda3::Overworld *overworld, const zelda3::OverworldItem &anchor_identity)
Find the best next item to keep selection continuity after deletion.
absl::StatusOr< zelda3::OverworldExit * > InsertExit(zelda3::Overworld *overworld, ImVec2 mouse_pos, int current_map)
Insert a new exit at the specified position.
absl::StatusOr< zelda3::OverworldItem * > DuplicateItemByIdentity(zelda3::Overworld *overworld, const zelda3::OverworldItem &item_identity, int offset_x, int offset_y)
Duplicate an existing item by identity with a positional offset.
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.
uint8_t GetParentMapId(const zelda3::OverworldMap *map, int current_map)
Helper to get parent map ID for multi-area maps.
constexpr int kExpandedMapCount
Definition common.h:86
bool valid(int map_count=zelda3::kNumOverworldMaps) const