about summary refs log tree commit diff stats
path: root/apworld/client/gamedata.gd
diff options
context:
space:
mode:
Diffstat (limited to 'apworld/client/gamedata.gd')
-rw-r--r--apworld/client/gamedata.gd310
1 files changed, 310 insertions, 0 deletions
diff --git a/apworld/client/gamedata.gd b/apworld/client/gamedata.gd new file mode 100644 index 0000000..373f981 --- /dev/null +++ b/apworld/client/gamedata.gd
@@ -0,0 +1,310 @@
1extends Node
2
3var SCRIPT_proto
4
5var objects
6var door_id_by_map_node_path = {}
7var painting_id_by_map_node_path = {}
8var panel_id_by_map_node_path = {}
9var port_id_by_map_node_path = {}
10var door_id_by_ap_id = {}
11var map_id_by_name = {}
12var progressive_id_by_ap_id = {}
13var letter_id_by_ap_id = {}
14var symbol_item_ids = []
15var anti_trap_ids = {}
16var location_name_by_id = {}
17var ending_display_name_by_name = {}
18var port_id_by_ap_id = {}
19var map_id_by_rte_ap_id = {}
20
21var kSYMBOL_ITEMS
22
23
24func _init(proto_script):
25 SCRIPT_proto = proto_script
26
27 kSYMBOL_ITEMS = {
28 SCRIPT_proto.PuzzleSymbol.SUN: "Sun Symbol",
29 SCRIPT_proto.PuzzleSymbol.SPARKLES: "Sparkles Symbol",
30 SCRIPT_proto.PuzzleSymbol.ZERO: "Zero Symbol",
31 SCRIPT_proto.PuzzleSymbol.EXAMPLE: "Example Symbol",
32 SCRIPT_proto.PuzzleSymbol.BOXES: "Boxes Symbol",
33 SCRIPT_proto.PuzzleSymbol.PLANET: "Planet Symbol",
34 SCRIPT_proto.PuzzleSymbol.PYRAMID: "Pyramid Symbol",
35 SCRIPT_proto.PuzzleSymbol.CROSS: "Cross Symbol",
36 SCRIPT_proto.PuzzleSymbol.SWEET: "Sweet Symbol",
37 SCRIPT_proto.PuzzleSymbol.GENDER: "Gender Symbol",
38 SCRIPT_proto.PuzzleSymbol.AGE: "Age Symbol",
39 SCRIPT_proto.PuzzleSymbol.SOUND: "Sound Symbol",
40 SCRIPT_proto.PuzzleSymbol.ANAGRAM: "Anagram Symbol",
41 SCRIPT_proto.PuzzleSymbol.JOB: "Job Symbol",
42 SCRIPT_proto.PuzzleSymbol.STARS: "Stars Symbol",
43 SCRIPT_proto.PuzzleSymbol.NULL: "Null Symbol",
44 SCRIPT_proto.PuzzleSymbol.EVAL: "Eval Symbol",
45 SCRIPT_proto.PuzzleSymbol.LINGO: "Lingo Symbol",
46 SCRIPT_proto.PuzzleSymbol.QUESTION: "Question Symbol",
47 }
48
49
50func load(data_bytes):
51 objects = SCRIPT_proto.AllObjects.new()
52
53 var result_code = objects.from_bytes(data_bytes)
54 if result_code != SCRIPT_proto.PB_ERR.NO_ERRORS:
55 print("Could not load generated data: %d" % result_code)
56 return
57
58 for map in objects.get_maps():
59 map_id_by_name[map.get_name()] = map.get_id()
60
61 if map.has_rte_ap_id():
62 map_id_by_rte_ap_id[map.get_rte_ap_id()] = map.get_id()
63
64 for door in objects.get_doors():
65 var map = objects.get_maps()[door.get_map_id()]
66
67 if not map.get_name() in door_id_by_map_node_path:
68 door_id_by_map_node_path[map.get_name()] = {}
69
70 var map_data = door_id_by_map_node_path[map.get_name()]
71 for receiver in door.get_receivers():
72 map_data[receiver] = door.get_id()
73
74 for painting_id in door.get_move_paintings():
75 var painting = objects.get_paintings()[painting_id]
76 map_data[painting.get_path()] = door.get_id()
77
78 if door.has_ap_id():
79 door_id_by_ap_id[door.get_ap_id()] = door.get_id()
80
81 if (
82 door.get_type() == SCRIPT_proto.DoorType.STANDARD
83 or door.get_type() == SCRIPT_proto.DoorType.LOCATION_ONLY
84 or door.get_type() == SCRIPT_proto.DoorType.GRAVESTONE
85 ):
86 location_name_by_id[door.get_ap_id()] = _get_door_location_name(door)
87
88 for painting in objects.get_paintings():
89 var room = objects.get_rooms()[painting.get_room_id()]
90 var map = objects.get_maps()[room.get_map_id()]
91
92 if not map.get_name() in painting_id_by_map_node_path:
93 painting_id_by_map_node_path[map.get_name()] = {}
94
95 var _map_data = painting_id_by_map_node_path[map.get_name()]
96
97 for port in objects.get_ports():
98 var room = objects.get_rooms()[port.get_room_id()]
99 var map = objects.get_maps()[room.get_map_id()]
100
101 if not map.get_name() in port_id_by_map_node_path:
102 port_id_by_map_node_path[map.get_name()] = {}
103
104 var map_data = port_id_by_map_node_path[map.get_name()]
105 map_data[port.get_path()] = port.get_id()
106
107 if port.has_ap_id():
108 port_id_by_ap_id[port.get_ap_id()] = port.get_id()
109
110 for progressive in objects.get_progressives():
111 progressive_id_by_ap_id[progressive.get_ap_id()] = progressive.get_id()
112
113 for letter in objects.get_letters():
114 letter_id_by_ap_id[letter.get_ap_id()] = letter.get_id()
115 location_name_by_id[letter.get_ap_id()] = _get_letter_location_name(letter)
116
117 for mastery in objects.get_masteries():
118 location_name_by_id[mastery.get_ap_id()] = _get_mastery_location_name(mastery)
119
120 for ending in objects.get_endings():
121 var location_name = _get_ending_location_name(ending)
122 location_name_by_id[ending.get_ap_id()] = location_name
123 ending_display_name_by_name[ending.get_name()] = location_name
124
125 for keyholder in objects.get_keyholders():
126 if keyholder.has_key():
127 location_name_by_id[keyholder.get_ap_id()] = _get_keyholder_location_name(keyholder)
128
129 for panel in objects.get_panels():
130 var room = objects.get_rooms()[panel.get_room_id()]
131 var map = objects.get_maps()[room.get_map_id()]
132
133 if not map.get_name() in panel_id_by_map_node_path:
134 panel_id_by_map_node_path[map.get_name()] = {}
135
136 var map_data = panel_id_by_map_node_path[map.get_name()]
137 map_data[panel.get_path()] = panel.get_id()
138
139 for symbol_name in kSYMBOL_ITEMS.values():
140 symbol_item_ids.append(objects.get_special_ids()[symbol_name])
141
142 for special_name in objects.get_special_ids().keys():
143 if special_name.begins_with("Anti "):
144 anti_trap_ids[objects.get_special_ids()[special_name]] = (
145 special_name.substr(5).to_lower()
146 )
147
148
149func get_door_for_map_node_path(map_name, node_path):
150 if not door_id_by_map_node_path.has(map_name):
151 return null
152
153 var map_data = door_id_by_map_node_path[map_name]
154 return map_data.get(node_path, null)
155
156
157func get_panel_for_map_node_path(map_name, node_path):
158 if not panel_id_by_map_node_path.has(map_name):
159 return null
160
161 var map_data = panel_id_by_map_node_path[map_name]
162 return map_data.get(node_path, null)
163
164
165func get_port_for_map_node_path(map_name, node_path):
166 if not port_id_by_map_node_path.has(map_name):
167 return null
168
169 var map_data = port_id_by_map_node_path[map_name]
170 return map_data.get(node_path, null)
171
172
173func get_door_ap_id(door_id):
174 var door = objects.get_doors()[door_id]
175 if door.has_ap_id():
176 return door.get_ap_id()
177 else:
178 return null
179
180
181func get_door_map_name(door_id):
182 var door = objects.get_doors()[door_id]
183 var map = objects.get_maps()[door.get_map_id()]
184 return map.get_name()
185
186
187func get_door_receivers(door_id):
188 var door = objects.get_doors()[door_id]
189 return door.get_receivers()
190
191
192func get_worldport_display_name(port_id):
193 var port = objects.get_ports()[port_id]
194 return "%s - %s" % [_get_room_object_map_name(port), port.get_display_name()]
195
196
197func _get_map_object_map_name(obj):
198 return objects.get_maps()[obj.get_map_id()].get_display_name()
199
200
201func _get_room_object_map_name(obj):
202 return _get_map_object_map_name(objects.get_rooms()[obj.get_room_id()])
203
204
205func _get_room_object_location_prefix(obj):
206 var room = objects.get_rooms()[obj.get_room_id()]
207 var game_map = objects.get_maps()[room.get_map_id()]
208
209 if room.has_panel_display_name():
210 return "%s (%s)" % [game_map.get_display_name(), room.get_panel_display_name()]
211 else:
212 return game_map.get_display_name()
213
214
215func _get_door_location_name(door):
216 var map_part = _get_room_object_location_prefix(door)
217
218 if door.has_location_name():
219 return "%s - %s" % [map_part, door.get_location_name()]
220
221 var generated_location_name = _get_generated_door_location_name(door)
222 if generated_location_name != null:
223 return generated_location_name
224
225 return "%s - %s" % [map_part, door.get_name()]
226
227
228func _get_generated_door_location_name(door):
229 if door.get_type() != SCRIPT_proto.DoorType.STANDARD:
230 return null
231
232 if (
233 door.get_keyholders().size() > 0
234 or (door.has_white_ending() and door.get_white_ending())
235 or door.has_complete_at()
236 ):
237 return null
238
239 if door.get_panels().size() > 4:
240 return null
241
242 var map_areas = []
243 for panel_id in door.get_panels():
244 var panel = objects.get_panels()[panel_id.get_panel()]
245 var panel_room = objects.get_rooms()[panel.get_room_id()]
246 # It's okay if panel_display_name is not present because then it's coalesced with other unnamed areas.
247 var panel_display_name = ""
248 if panel_room.has_panel_display_name():
249 panel_display_name = panel_room.get_panel_display_name()
250 if not map_areas.has(panel_display_name):
251 map_areas.append(panel_display_name)
252
253 if map_areas.size() > 1:
254 return null
255
256 var game_map = objects.get_maps()[door.get_map_id()]
257 var map_area = map_areas[0]
258 var map_part
259 if map_area == "":
260 map_part = game_map.get_display_name()
261 else:
262 map_part = "%s (%s)" % [game_map.get_display_name(), map_area]
263
264 var panel_names = []
265 for panel_id in door.get_panels():
266 var panel_data = objects.get_panels()[panel_id.get_panel()]
267 var panel_name
268 if panel_data.has_display_name():
269 panel_name = panel_data.get_display_name()
270 else:
271 panel_name = panel_data.get_name()
272
273 var location_part
274 if panel_id.has_answer():
275 location_part = "%s/%s" % [panel_name, panel_id.get_answer().to_upper()]
276 else:
277 location_part = panel_name
278
279 panel_names.append(location_part)
280
281 panel_names.sort()
282
283 return map_part + " - " + ", ".join(panel_names)
284
285
286func _get_letter_location_name(letter):
287 var letter_level = 2 if (letter.has_level2() and letter.get_level2()) else 1
288 var letter_name = "%s%d" % [letter.get_key().to_upper(), letter_level]
289 return "%s - %s" % [_get_room_object_map_name(letter), letter_name]
290
291
292func _get_mastery_location_name(mastery):
293 return "%s - Mastery" % _get_room_object_map_name(mastery)
294
295
296func _get_ending_location_name(ending):
297 return (
298 "%s - %s Ending" % [_get_room_object_map_name(ending), ending.get_name().to_pascal_case()]
299 )
300
301
302func _get_keyholder_location_name(keyholder):
303 return (
304 "%s - %s Keyholder"
305 % [_get_room_object_location_prefix(keyholder), keyholder.get_key().to_upper()]
306 )
307
308
309func vec3d_to_vector3(input) -> Vector3:
310 return Vector3(input.get_x(), input.get_y(), input.get_z())