about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2023-05-02 00:24:09 -0400
committerStar Rauchenberger <fefferburbia@gmail.com>2023-05-02 00:24:09 -0400
commit704c08bb439b9a90f7be2d26a0c8b01777e2cf2c (patch)
tree72b010a9e343ff69f549496de61f74356f2becb1
parentf7530492119f94a83bdb85bb3887b50ddb5a6ffd (diff)
downloadlingo-ap-tracker-704c08bb439b9a90f7be2d26a0c8b01777e2cf2c.tar.gz
lingo-ap-tracker-704c08bb439b9a90f7be2d26a0c8b01777e2cf2c.tar.bz2
lingo-ap-tracker-704c08bb439b9a90f7be2d26a0c8b01777e2cf2c.zip
Started reading in game data yaml
-rw-r--r--.gitignore1
-rw-r--r--.gitmodules3
-rw-r--r--CMakeLists.txt11
-rw-r--r--game_data.cpp255
-rw-r--r--game_data.h86
m---------vendor/hkutil0
6 files changed, 355 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore index 567609b..4a87eed 100644 --- a/.gitignore +++ b/.gitignore
@@ -1 +1,2 @@
1build/ 1build/
2assets/LL1.yaml
diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..5438989 --- /dev/null +++ b/.gitmodules
@@ -0,0 +1,3 @@
1[submodule "vendor/hkutil"]
2 path = vendor/hkutil
3 url = https://github.com/hatkirby/hkutil.git
diff --git a/CMakeLists.txt b/CMakeLists.txt index cb5cf25..2e4ece5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -6,11 +6,20 @@ set(CMAKE_BUILD_TYPE Debug)
6find_package(wxWidgets COMPONENTS core base) 6find_package(wxWidgets COMPONENTS core base)
7include(${wxWidgets_USE_FILE}) 7include(${wxWidgets_USE_FILE})
8 8
9find_package(PkgConfig)
10pkg_check_modules(yaml-cpp yaml-cpp REQUIRED)
11
12include_directories(
13 vendor/hkutil
14 ${yaml-cpp_INCLUDE_DIRS}
15)
16
9add_executable(lingo_ap_tracker 17add_executable(lingo_ap_tracker
10 main.cpp 18 main.cpp
11 tracker_frame.cpp 19 tracker_frame.cpp
12 tracker_panel.cpp 20 tracker_panel.cpp
21 game_data.cpp
13) 22)
14set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD 17) 23set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD 17)
15set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD_REQUIRED ON) 24set_property(TARGET lingo_ap_tracker PROPERTY CXX_STANDARD_REQUIRED ON)
16target_link_libraries(lingo_ap_tracker ${wxWidgets_LIBRARIES}) 25target_link_libraries(lingo_ap_tracker ${wxWidgets_LIBRARIES} ${yaml-cpp_LIBRARIES})
diff --git a/game_data.cpp b/game_data.cpp new file mode 100644 index 0000000..db574d3 --- /dev/null +++ b/game_data.cpp
@@ -0,0 +1,255 @@
1#include "game_data.h"
2
3#include <hkutil/string.h>
4#include <iostream>
5#include <yaml-cpp/yaml.h>
6
7LingoColor GetColorForString(const std::string &str) {
8 if (str == "black") {
9 return LingoColor::kBlack;
10 } else if (str == "red") {
11 return LingoColor::kRed;
12 } else if (str == "blue") {
13 return LingoColor::kBlue;
14 } else if (str == "yellow") {
15 return LingoColor::kYellow;
16 } else if (str == "orange") {
17 return LingoColor::kOrange;
18 } else if (str == "green") {
19 return LingoColor::kGreen;
20 } else if (str == "gray") {
21 return LingoColor::kGray;
22 } else if (str == "brown") {
23 return LingoColor::kBrown;
24 } else if (str == "purple") {
25 return LingoColor::kPurple;
26 } else {
27 std::cout << "Invalid color: " << str << std::endl;
28 return LingoColor::kNone;
29 }
30}
31
32GameData::GameData() {
33 YAML::Node lingo_config = YAML::LoadFile("assets/LL1.yaml");
34 YAML::Node areas_config = YAML::LoadFile("assets/areas.yaml");
35
36 rooms_.reserve(lingo_config.size() + 1); // The +1 is for Menu
37
38 for (const auto &room_it : lingo_config) {
39 int room_id = AddOrGetRoom(room_it.first.as<std::string>());
40 Room &room_obj = rooms_[room_id];
41
42 for (const auto &entrance_it : room_it.second["entrances"]) {
43 int from_room_id = AddOrGetRoom(entrance_it.first.as<std::string>());
44 Room &from_room_obj = rooms_[from_room_id];
45
46 switch (entrance_it.second.Type()) {
47 case YAML::NodeType::Scalar: {
48 // This is just "true".
49 from_room_obj.exits.push_back({.destination_room = room_id});
50 break;
51 }
52 case YAML::NodeType::Map: {
53 Exit exit_obj;
54 exit_obj.destination_room = room_id;
55
56 if (entrance_it.second["door"]) {
57 std::string door_room = room_obj.name;
58 if (entrance_it.second["room"]) {
59 door_room = entrance_it.second["room"].as<std::string>();
60 }
61 exit_obj.door = AddOrGetDoor(
62 door_room, entrance_it.second["door"].as<std::string>());
63 }
64
65 from_room_obj.exits.push_back(exit_obj);
66 break;
67 }
68 case YAML::NodeType::Sequence: {
69 for (const auto &option : entrance_it.second) {
70 Exit exit_obj;
71 exit_obj.destination_room = room_id;
72
73 std::string door_room = room_obj.name;
74 if (option["room"]) {
75 door_room = option["room"].as<std::string>();
76 }
77 exit_obj.door =
78 AddOrGetDoor(door_room, option["door"].as<std::string>());
79
80 from_room_obj.exits.push_back(exit_obj);
81 }
82
83 break;
84 }
85 default: {
86 // This shouldn't happen.
87 std::cout << "Error reading game data: " << entrance_it << std::endl;
88 break;
89 }
90 }
91 }
92
93 if (room_it.second["panels"]) {
94 for (const auto &panel_it : room_it.second["panels"]) {
95 int panel_id =
96 AddOrGetPanel(room_obj.name, panel_it.first.as<std::string>());
97 Panel &panel_obj = panels_[panel_id];
98
99 if (panel_it.second["colors"]) {
100 if (panel_it.second["colors"].IsScalar()) {
101 panel_obj.colors.push_back(
102 GetColorForString(panel_it.second["colors"].as<std::string>()));
103 } else {
104 for (const auto &color_node : panel_it.second["colors"]) {
105 panel_obj.colors.push_back(
106 GetColorForString(color_node.as<std::string>()));
107 }
108 }
109 }
110
111 if (panel_it.second["required_room"]) {
112 if (panel_it.second["required_room"].IsScalar()) {
113 panel_obj.required_rooms.push_back(AddOrGetRoom(
114 panel_it.second["required_room"].as<std::string>()));
115 } else {
116 for (const auto &rr_node : panel_it.second["required_room"]) {
117 panel_obj.required_rooms.push_back(
118 AddOrGetRoom(rr_node.as<std::string>()));
119 }
120 }
121 }
122
123 if (panel_it.second["required_door"]) {
124 if (panel_it.second["required_door"].IsMap()) {
125 std::string rd_room = room_obj.name;
126 if (panel_it.second["required_door"]["room"]) {
127 rd_room =
128 panel_it.second["required_door"]["room"].as<std::string>();
129 }
130
131 panel_obj.required_doors.push_back(AddOrGetDoor(
132 rd_room,
133 panel_it.second["required_door"]["door"].as<std::string>()));
134 } else {
135 for (const auto &rr_node : panel_it.second["required_door"]) {
136 std::string rd_room = room_obj.name;
137 if (rr_node["room"]) {
138 rd_room = rr_node["room"].as<std::string>();
139 }
140
141 panel_obj.required_doors.push_back(
142 AddOrGetDoor(rd_room, rr_node["door"].as<std::string>()));
143 }
144 }
145 }
146
147 if (panel_it.second["check"]) {
148 panel_obj.check = panel_it.second["check"].as<bool>();
149 }
150
151 if (panel_it.second["exclude_reduce"]) {
152 panel_obj.exclude_reduce =
153 panel_it.second["exclude_reduce"].as<bool>();
154 }
155 }
156 }
157
158 if (room_it.second["doors"]) {
159 for (const auto &door_it : room_it.second["doors"]) {
160 int door_id =
161 AddOrGetDoor(room_obj.name, door_it.first.as<std::string>());
162 Door &door_obj = doors_[door_id];
163
164 bool has_external_panels = false;
165 std::vector<std::string> panel_names;
166
167 for (const auto &panel_node : door_it.second["panels"]) {
168 if (panel_node.IsScalar()) {
169 panel_names.push_back(panel_node.as<std::string>());
170 door_obj.panels.push_back(
171 AddOrGetPanel(room_obj.name, panel_node.as<std::string>()));
172 } else {
173 has_external_panels = true;
174 panel_names.push_back(panel_node["panel"].as<std::string>());
175 door_obj.panels.push_back(
176 AddOrGetPanel(panel_node["room"].as<std::string>(),
177 panel_node["panel"].as<std::string>()));
178 }
179 }
180
181 if (door_it.second["skip_location"]) {
182 door_obj.skip_location = door_it.second["skip_location"].as<bool>();
183 }
184
185 if (door_it.second["item_name"]) {
186 door_obj.item_name = door_it.second["item_name"].as<std::string>();
187 } else if (!door_it.second["skip_item"] && !door_it.second["event"]) {
188 door_obj.item_name = room_obj.name + " - " + door_obj.name;
189 }
190
191 if (door_it.second["group"]) {
192 door_obj.group_name = door_it.second["group"].as<std::string>();
193 }
194
195 if (door_it.second["location_name"]) {
196 door_obj.location_name =
197 door_it.second["location_name"].as<std::string>();
198 } else if (!door_it.second["skip_location"] &&
199 !door_it.second["event"]) {
200 if (has_external_panels) {
201 std::cout
202 << room_obj.name << " - " << door_obj.name
203 << " has panels from other rooms but does not have an explicit "
204 "location name and is not marked skip_location or event"
205 << std::endl;
206 }
207
208 door_obj.location_name =
209 room_obj.name + " - " + hatkirby::implode(panel_names, ", ");
210 }
211
212 if (door_it.second["include_reduce"]) {
213 door_obj.exclude_reduce =
214 !door_it.second["include_reduce"].as<bool>();
215 }
216 }
217 }
218 }
219}
220
221int GameData::AddOrGetRoom(std::string room) {
222 if (!room_by_id_.count(room)) {
223 room_by_id_[room] = rooms_.size();
224 rooms_.push_back({.name = room});
225 }
226
227 return room_by_id_[room];
228}
229
230int GameData::AddOrGetDoor(std::string room, std::string door) {
231 std::string full_name = room + " - " + door;
232
233 if (!door_by_id_.count(full_name)) {
234 door_by_id_[full_name] = doors_.size();
235 doors_.push_back({.name = door, .room = AddOrGetRoom(room)});
236 }
237
238 return door_by_id_[full_name];
239}
240
241int GameData::AddOrGetPanel(std::string room, std::string panel) {
242 std::string full_name = room + " - " + panel;
243
244 if (!panel_by_id_.count(full_name)) {
245 panel_by_id_[full_name] = panels_.size();
246 panels_.push_back({.name = panel, .room = AddOrGetRoom(room)});
247 }
248
249 return panel_by_id_[full_name];
250}
251
252const GameData &GetGameData() {
253 static GameData *instance = new GameData();
254 return *instance;
255}
diff --git a/game_data.h b/game_data.h new file mode 100644 index 0000000..f74f033 --- /dev/null +++ b/game_data.h
@@ -0,0 +1,86 @@
1#ifndef GAME_DATA_H_9C42AC51
2#define GAME_DATA_H_9C42AC51
3
4#include <map>
5#include <string>
6#include <vector>
7
8enum class LingoColor {
9 kNone,
10 kBlack,
11 kRed,
12 kBlue,
13 kYellow,
14 kGreen,
15 kOrange,
16 kPurple,
17 kBrown,
18 kGray
19};
20
21struct Panel {
22 int room;
23 std::string name;
24 std::vector<LingoColor> colors;
25 std::vector<int> required_rooms;
26 std::vector<int> required_doors;
27 bool check = false;
28 bool exclude_reduce = false;
29};
30
31struct Door {
32 int room;
33 std::string name;
34 std::string location_name;
35 std::string item_name;
36 std::string group_name;
37 bool skip_location = false;
38 std::vector<int> panels;
39 bool exclude_reduce = true;
40};
41
42struct Exit {
43 int destination_room;
44 std::optional<int> door;
45};
46
47struct Room {
48 std::string name;
49 std::vector<Exit> exits;
50};
51
52struct Location {
53 std::string name;
54 int location_id;
55 int room;
56 std::vector<int> panels;
57};
58
59struct MapArea {
60 std::string name;
61 std::vector<Location> locations;
62 int map_x;
63 int map_y;
64};
65
66class GameData {
67public:
68 GameData();
69
70private:
71 int AddOrGetRoom(std::string room);
72 int AddOrGetDoor(std::string room, std::string door);
73 int AddOrGetPanel(std::string room, std::string panel);
74
75 std::vector<Room> rooms_;
76 std::vector<Door> doors_;
77 std::vector<Panel> panels_;
78
79 std::map<std::string, int> room_by_id_;
80 std::map<std::string, int> door_by_id_;
81 std::map<std::string, int> panel_by_id_;
82};
83
84const GameData &GetGameData();
85
86#endif /* end of include guard: GAME_DATA_H_9C42AC51 */
diff --git a/vendor/hkutil b/vendor/hkutil new file mode 160000
Subproject bfe86f537030739f2f82c3e2ddcbe97eff7ef0e