diff options
author | Star Rauchenberger <fefferburbia@gmail.com> | 2023-12-09 13:14:25 -0500 |
---|---|---|
committer | Star Rauchenberger <fefferburbia@gmail.com> | 2023-12-09 13:14:25 -0500 |
commit | f0555579cd462b27c71c486bd7456265cc827937 (patch) | |
tree | 12dd8a500dd836f9466e534039fda46005547639 | |
parent | e72b3e5fae63db0f669155b7b965c2c5fc6f97e3 (diff) | |
download | lingo-randomizer-f0555579cd462b27c71c486bd7456265cc827937.tar.gz lingo-randomizer-f0555579cd462b27c71c486bd7456265cc827937.tar.bz2 lingo-randomizer-f0555579cd462b27c71c486bd7456265cc827937.zip |
Starting to work
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | randomizer.tscn | 102 | ||||
-rw-r--r-- | randomizer/generator.gd | 748 | ||||
-rw-r--r-- | randomizer/load.gd | 18 | ||||
-rw-r--r-- | randomizer/panelEnd.gd | 7 | ||||
-rw-r--r-- | randomizer/panelInput.gd | 5 | ||||
-rw-r--r-- | randomizer/panelLevelSwitch.gd | 7 | ||||
-rw-r--r-- | randomizer/randomizer.gd | 26 | ||||
-rw-r--r-- | randomizer/settings_buttons.gd | 16 | ||||
-rw-r--r-- | randomizer/settings_screen.gd | 78 | ||||
-rw-r--r-- | randomizer/worldTransporter.gd | 6 |
11 files changed, 1014 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore index d76b74e..306e0ff 100644 --- a/.gitignore +++ b/.gitignore | |||
@@ -1,2 +1,3 @@ | |||
1 | build | 1 | build |
2 | .DS_Store | 2 | .DS_Store |
3 | generated_puzzles.gd | ||
diff --git a/randomizer.tscn b/randomizer.tscn new file mode 100644 index 0000000..e4b96aa --- /dev/null +++ b/randomizer.tscn | |||
@@ -0,0 +1,102 @@ | |||
1 | [gd_scene load_steps=9 format=2] | ||
2 | |||
3 | [ext_resource path="res://nodes/label.tscn" type="PackedScene" id=1] | ||
4 | [ext_resource path="res://fonts/Lingo.tres" type="DynamicFont" id=2] | ||
5 | [ext_resource path="res://nodes/button.tscn" type="PackedScene" id=3] | ||
6 | [ext_resource path="user://maps/randomizer/settings_buttons.gd" type="Script" id=4] | ||
7 | [ext_resource path="user://maps/randomizer/settings_screen.gd" type="Script" id=5] | ||
8 | [ext_resource path="res://fonts/Lingo35.tres" type="DynamicFont" id=6] | ||
9 | |||
10 | [sub_resource type="StyleBoxFlat" id=1] | ||
11 | bg_color = Color( 0, 0, 0, 0 ) | ||
12 | |||
13 | [sub_resource type="StyleBoxFlat" id=2] | ||
14 | bg_color = Color( 1, 1, 1, 1 ) | ||
15 | border_width_left = 1 | ||
16 | border_width_top = 1 | ||
17 | border_width_right = 1 | ||
18 | border_width_bottom = 1 | ||
19 | border_color = Color( 1, 1, 0, 1 ) | ||
20 | border_blend = true | ||
21 | corner_radius_top_left = 3 | ||
22 | corner_radius_top_right = 3 | ||
23 | corner_radius_bottom_right = 3 | ||
24 | corner_radius_bottom_left = 3 | ||
25 | expand_margin_left = 5.0 | ||
26 | expand_margin_right = 5.0 | ||
27 | expand_margin_top = 5.0 | ||
28 | expand_margin_bottom = 5.0 | ||
29 | |||
30 | [node name="settings_screen" type="Spatial"] | ||
31 | script = ExtResource( 5 ) | ||
32 | |||
33 | [node name="Panel" type="Panel" parent="."] | ||
34 | margin_right = 1920.0 | ||
35 | margin_bottom = 1080.0 | ||
36 | |||
37 | [node name="title" parent="Panel" instance=ExtResource( 1 )] | ||
38 | margin_left = 0.0 | ||
39 | margin_top = 75.0 | ||
40 | margin_right = 1920.0 | ||
41 | margin_bottom = 225.0 | ||
42 | custom_fonts/font = ExtResource( 2 ) | ||
43 | text = "RANDOMIZER" | ||
44 | valign = 1 | ||
45 | |||
46 | [node name="credit" parent="Panel" instance=ExtResource( 1 )] | ||
47 | visible = false | ||
48 | margin_left = 1278.0 | ||
49 | margin_top = 974.0 | ||
50 | margin_right = 1868.0 | ||
51 | margin_bottom = 1034.0 | ||
52 | custom_fonts/font = ExtResource( 2 ) | ||
53 | text = "Brenton Wildes" | ||
54 | |||
55 | [node name="start_button" parent="Panel" instance=ExtResource( 3 )] | ||
56 | margin_left = 255.0 | ||
57 | margin_top = 875.0 | ||
58 | margin_right = 891.0 | ||
59 | margin_bottom = 1025.0 | ||
60 | custom_colors/font_color_hover = Color( 1, 0.501961, 0, 1 ) | ||
61 | custom_fonts/font = ExtResource( 2 ) | ||
62 | text = "START" | ||
63 | script = ExtResource( 4 ) | ||
64 | |||
65 | [node name="quit_button" parent="Panel" instance=ExtResource( 3 )] | ||
66 | margin_left = 1102.0 | ||
67 | margin_top = 875.0 | ||
68 | margin_right = 1738.0 | ||
69 | margin_bottom = 1025.0 | ||
70 | custom_colors/font_color_hover = Color( 1, 0, 0, 1 ) | ||
71 | custom_fonts/font = ExtResource( 2 ) | ||
72 | text = "BACK" | ||
73 | script = ExtResource( 4 ) | ||
74 | |||
75 | [node name="credit2" parent="Panel" instance=ExtResource( 1 )] | ||
76 | margin_left = -105.0 | ||
77 | margin_top = 346.0 | ||
78 | margin_right = 485.0 | ||
79 | margin_bottom = 410.0 | ||
80 | custom_fonts/font = ExtResource( 2 ) | ||
81 | custom_styles/normal = SubResource( 1 ) | ||
82 | text = "SEED" | ||
83 | align = 2 | ||
84 | |||
85 | [node name="seed_box" type="LineEdit" parent="Panel"] | ||
86 | margin_left = 502.0 | ||
87 | margin_top = 295.0 | ||
88 | margin_right = 1144.0 | ||
89 | margin_bottom = 445.0 | ||
90 | custom_colors/selection_color = Color( 0.482353, 0, 0, 1 ) | ||
91 | custom_colors/cursor_color = Color( 0, 0, 0, 1 ) | ||
92 | custom_colors/font_color = Color( 0, 0, 0, 1 ) | ||
93 | custom_styles/focus = SubResource( 2 ) | ||
94 | align = 1 | ||
95 | caret_blink = true | ||
96 | |||
97 | [node name="AcceptDialog" type="AcceptDialog" parent="Panel"] | ||
98 | margin_right = 83.0 | ||
99 | margin_bottom = 58.0 | ||
100 | |||
101 | [connection signal="pressed" from="Panel/start_button" to="Panel/start_button" method="_start_pressed"] | ||
102 | [connection signal="pressed" from="Panel/quit_button" to="Panel/quit_button" method="_back_pressed"] | ||
diff --git a/randomizer/generator.gd b/randomizer/generator.gd new file mode 100644 index 0000000..22ab178 --- /dev/null +++ b/randomizer/generator.gd | |||
@@ -0,0 +1,748 @@ | |||
1 | extends Node | ||
2 | |||
3 | var panel_mapping = [] | ||
4 | var gen_seed | ||
5 | |||
6 | var _generated_puzzles | ||
7 | var _answer_by_id | ||
8 | var _answers_by_type | ||
9 | var _answers_by_length | ||
10 | var _puzzle_by_id | ||
11 | var _rng | ||
12 | var _flags = 0 | ||
13 | var _total_generated = 0 | ||
14 | |||
15 | var _unique_pool = "" | ||
16 | var _answers_by_unique_pool = {} | ||
17 | var _needs_reuse = [] | ||
18 | var _possible_reuse = [] | ||
19 | |||
20 | const kWhiteMiddle = -1 | ||
21 | const kWhiteTop = 0 | ||
22 | const kWhiteBottom = 1 | ||
23 | const kYellowTop = 2 | ||
24 | const kYellowMiddle = 3 | ||
25 | const kBlackTop = 4 | ||
26 | const kBlackMiddle = 5 | ||
27 | const kBlackBottom = 6 | ||
28 | const kDoubleBlackBottom = 7 | ||
29 | const kRedTop = 8 | ||
30 | const kRedMiddle = 9 | ||
31 | const kRedBottom = 10 | ||
32 | const kBlueTop = 11 | ||
33 | const kBlueMiddle = 12 | ||
34 | const kBlueBottom = 13 | ||
35 | const kPurpleTop = 14 | ||
36 | const kPurpleMiddle = 15 | ||
37 | |||
38 | const kPuzzleTypes = [ | ||
39 | kWhiteMiddle, | ||
40 | kWhiteTop, | ||
41 | kWhiteBottom, | ||
42 | kYellowTop, | ||
43 | kYellowMiddle, | ||
44 | kBlackTop, | ||
45 | kBlackMiddle, | ||
46 | kBlackBottom, | ||
47 | kDoubleBlackBottom, | ||
48 | kRedTop, | ||
49 | kRedMiddle, | ||
50 | kRedBottom, | ||
51 | kBlueTop, | ||
52 | kBlueMiddle, | ||
53 | kBlueBottom, | ||
54 | kPurpleTop, | ||
55 | kPurpleMiddle | ||
56 | ] | ||
57 | |||
58 | const kMustReuseAnswer = 1 >> 0 | ||
59 | const kObscureHint = 1 >> 1 | ||
60 | const kShortAnswer = 1 >> 2 | ||
61 | |||
62 | signal generator_status | ||
63 | |||
64 | |||
65 | func _init(gen_puzzles): | ||
66 | _generated_puzzles = gen_puzzles | ||
67 | |||
68 | |||
69 | func generate(chosen_seed): | ||
70 | emit_signal("generator_status", "Generating puzzles...") | ||
71 | |||
72 | _flags = 0 | ||
73 | _total_generated = 0 | ||
74 | |||
75 | # Seed the random number generator. | ||
76 | if chosen_seed == "": | ||
77 | var seed_rng = RandomNumberGenerator.new() | ||
78 | seed_rng.randomize() | ||
79 | gen_seed = seed_rng.randi_range(0, 999999) | ||
80 | else: | ||
81 | gen_seed = int(chosen_seed) | ||
82 | |||
83 | _rng = RandomNumberGenerator.new() | ||
84 | _rng.seed = gen_seed | ||
85 | |||
86 | # Create some helpful indexes. | ||
87 | _answer_by_id = [] | ||
88 | _answers_by_type = {} | ||
89 | _answers_by_length = {} | ||
90 | _puzzle_by_id = [] | ||
91 | var openable_answers = [] | ||
92 | |||
93 | for puzzle_type in kPuzzleTypes: | ||
94 | _answers_by_type[puzzle_type] = [] | ||
95 | |||
96 | var puzzle_id = 0 | ||
97 | for puzzle in _generated_puzzles.forms: | ||
98 | _answers_by_type[kWhiteMiddle].append(puzzle_id) | ||
99 | |||
100 | match typeof(puzzle): | ||
101 | TYPE_ARRAY: | ||
102 | _answer_by_id.append(puzzle[0]) | ||
103 | if not _answers_by_length.has(puzzle[0].length()): | ||
104 | _answers_by_length[puzzle[0].length()] = [] | ||
105 | _answers_by_length[puzzle[0].length()].append(puzzle_id) | ||
106 | _puzzle_by_id.append(puzzle) | ||
107 | |||
108 | for puzzle_type in puzzle[1].keys(): | ||
109 | _answers_by_type[puzzle_type].append(puzzle_id) | ||
110 | |||
111 | if ( | ||
112 | puzzle[1].has(kYellowMiddle) | ||
113 | and puzzle[1].has(kBlackBottom) | ||
114 | and puzzle[1].has(kRedMiddle) | ||
115 | and puzzle[1].has(kBlueMiddle) | ||
116 | and puzzle[1].has(kPurpleMiddle) | ||
117 | ): | ||
118 | openable_answers.append(puzzle_id) | ||
119 | TYPE_STRING: | ||
120 | _answer_by_id.append(puzzle) | ||
121 | if not _answers_by_length.has(puzzle.length()): | ||
122 | _answers_by_length[puzzle.length()] = [] | ||
123 | _answers_by_length[puzzle.length()].append(puzzle_id) | ||
124 | _puzzle_by_id.append([puzzle, []]) | ||
125 | |||
126 | puzzle_id += 1 | ||
127 | |||
128 | # Choose the answer for the OPEN panels. | ||
129 | # There is a hedge maze OPEN but we can't randomize those yet. | ||
130 | var open_answer_id = _pickRandom(openable_answers) | ||
131 | |||
132 | _setUniquePool("agreeable") | ||
133 | _setPanel( | ||
134 | "Antonym Room/Panel_close_open", | ||
135 | _pickRandom(_puzzle_by_id[open_answer_id][1][kBlackBottom]), | ||
136 | open_answer_id | ||
137 | ) | ||
138 | |||
139 | _setUniquePool("seeker") | ||
140 | _setPanel("Heteronym Room/Panel_entrance_entrance", open_answer_id, open_answer_id) | ||
141 | |||
142 | _setUniquePool("traveled") | ||
143 | _setPanel("Synonym Room/Panel_open_open", open_answer_id, open_answer_id) | ||
144 | |||
145 | _setUniquePool("discerning") | ||
146 | _setPanel( | ||
147 | "Sun Room/Panel_nope_open", | ||
148 | _pickRandom(_puzzle_by_id[open_answer_id][1][kYellowMiddle]), | ||
149 | open_answer_id | ||
150 | ) | ||
151 | |||
152 | _setUniquePool("bold") | ||
153 | _setPanel( | ||
154 | "Truncate Room/Panel_unopened_open", | ||
155 | _pickRandom(_puzzle_by_id[open_answer_id][1][kRedMiddle]), | ||
156 | open_answer_id | ||
157 | ) | ||
158 | |||
159 | _setUniquePool("undeterred") | ||
160 | _setPanel( | ||
161 | "Blue Room/Panel_pen_open", | ||
162 | _pickRandom(_puzzle_by_id[open_answer_id][1][kBlueMiddle]), | ||
163 | open_answer_id | ||
164 | ) | ||
165 | |||
166 | _setUniquePool("initiated") | ||
167 | _setPanel( | ||
168 | "Rhyme Room/Panel_locked_knocked", | ||
169 | _pickRandom(_puzzle_by_id[open_answer_id][1][kPurpleMiddle]), | ||
170 | open_answer_id | ||
171 | ) | ||
172 | |||
173 | # Start generating puzzles that need to have reused solutions. | ||
174 | _setFlag(kMustReuseAnswer) | ||
175 | |||
176 | _setUniquePool("agreeable") | ||
177 | _gSingle("Antonym Room/Panel_read_write", kBlackBottom) | ||
178 | _gSingle("Antonym Room/Panel_different_same", kBlackBottom) | ||
179 | _gSingle("Antonym Room/Panel_bye_hi", kBlackBottom) | ||
180 | _gSingle("Antonym Room/Panel_low_high", kBlackBottom) | ||
181 | _gSingle("Antonym Room/Panel_alive_dead", kBlackBottom) | ||
182 | _gSingle("Antonym Room/Panel_that_this", kBlackBottom) | ||
183 | _gSingle("Doorways Room/Panel_found_lost", kBlackBottom) | ||
184 | |||
185 | _setUniquePool("bold") | ||
186 | _gDouble("Truncate Room/Panel_face_eye", "Truncate Room/Panel_needle_eye", kRedBottom) | ||
187 | _gDouble("Truncate Room/Panel_mouth_teeth", "Truncate Room/Panel_saw_teeth", kRedBottom) | ||
188 | _gSingle("Truncate Room/Panel_foot_toe", kRedBottom) | ||
189 | _gSingle("Truncate Room/Panel_hand_finger", kRedBottom) | ||
190 | _gSingle("Doorways Room/Panel_loaf_crust", kRedBottom) | ||
191 | |||
192 | _setUniquePool("undeterred") | ||
193 | _gSingle("Blue Room/Panel_two_toucan", kBlueTop) | ||
194 | _gDouble("Blue Room/Panel_ice_eyesight", "Blue Room/Panel_height_eyesight", kBlueTop) | ||
195 | _gSingle("Blue Room/Panel_eye_hi", kBlueTop) | ||
196 | _gSingle("Blue Room/Panel_not_notice", kBlueMiddle) | ||
197 | _gDouble("Blue Room/Panel_just_readjust", "Blue Room/Panel_read_readjust", kBlueMiddle) | ||
198 | _gSingle("Blue Room/Panel_ate_primate", kBlueMiddle) | ||
199 | _gSingle("Blue Room/Panel_bone_skeleton", kBlueBottom) | ||
200 | _gDouble("Blue Room/Panel_mouth_face", "Blue Room/Panel_eye_face", kBlueBottom) | ||
201 | _gSingle("Blue Room/Panel_toucan_bird", kBlueBottom) | ||
202 | _gSingle("Blue Room/Panel_primate_mammal", kBlueBottom) | ||
203 | _gDouble("Blue Room/Panel_continent_planet", "Blue Room/Panel_ocean_planet", kBlueBottom) | ||
204 | _gSingle("Blue Room/Panel_wall_room", kBlueBottom) | ||
205 | _gSingle("Doorways Room/Panel_sun_sky", kBlueBottom) | ||
206 | |||
207 | _setUniquePool("traveled") | ||
208 | _gSingle("Synonym Room/Panel_close_near", kWhiteBottom) | ||
209 | _gSingle("Synonym Room/Panel_category_type", kWhiteBottom) | ||
210 | _gSingle("Synonym Room/Panel_distant_far", kWhiteBottom) | ||
211 | _gSingle("Synonym Room/Panel_hay_straw", kWhiteBottom) | ||
212 | _gSingle("Synonym Room/Panel_snitch_rat", kWhiteBottom) | ||
213 | _gSingle("Synonym Room/Panel_concealed_hidden", kWhiteBottom) | ||
214 | _gSingle("Synonym Room/Panel_growths_warts", kWhiteBottom) | ||
215 | _gSingle("Synonym Room/Panel_hello_hi", kWhiteBottom) | ||
216 | _gDouble("Synonym Room/Panel_compose_write", "Synonym Room/Panel_record_write", kWhiteBottom) | ||
217 | _gDouble("Synonym Room/Panel_duplicate_same", "Synonym Room/Panel_identical_same", kWhiteBottom) | ||
218 | _gDouble("Synonym Room/Panel_giggle_laugh", "Synonym Room/Panel_chuckle_laugh", kWhiteBottom) | ||
219 | _gDouble("Synonym Room/Panel_plunge_fall", "Synonym Room/Panel_autumn_fall", kWhiteBottom) | ||
220 | _gSingle("Doorways Room/Panel_begin_start", kWhiteBottom) | ||
221 | |||
222 | _setUniquePool("initiated") | ||
223 | _gSingle("Rhyme Room/Panel_daughter_laughter", kPurpleMiddle) | ||
224 | _gSingle("Rhyme Room/Panel_scope_type", kPurpleMiddle) | ||
225 | _gSingle("Rhyme Room/Panel_abyss_this", kPurpleMiddle) | ||
226 | _gSingle("Rhyme Room/Panel_wrath_path", kPurpleMiddle) | ||
227 | _gSingle("Rhyme Room/Panel_bed_dead", kPurpleMiddle) | ||
228 | _gSingle("Rhyme Room/Panel_alumni_hi", kPurpleTop) | ||
229 | _gSingle("Rhyme Room/Panel_maim_same", kPurpleTop) | ||
230 | _gSingle("Rhyme Room/Panel_bare_bear", kPurpleTop) | ||
231 | _gDouble("Rhyme Room/Panel_move_love", "Rhyme Room/Panel_stove_love", kPurpleMiddle) | ||
232 | _gDouble("Rhyme Room/Panel_sweat_great", "Rhyme Room/Panel_beat_great", kPurpleMiddle) | ||
233 | _gDouble("Rhyme Room/Panel_knight_write", "Rhyme Room/Panel_byte_write", kPurpleTop) | ||
234 | # Panel_chair_bear, Panel_cost_most (cyborg) | ||
235 | |||
236 | _setUniquePool("fearless") | ||
237 | _gSingle("Naps Room/Panel_easy_soft", kDoubleBlackBottom) | ||
238 | _gSingle("Naps Room/Panel_sometimes_always", kDoubleBlackBottom) | ||
239 | _gSingle("Naps Room/Panel_dark_extinguish", kDoubleBlackBottom) | ||
240 | _gSingle("Naps Room/Panel_impatient_doctor", kDoubleBlackBottom) | ||
241 | _gSingle("Naps Room/Panel_even_ordinary", kDoubleBlackBottom) | ||
242 | |||
243 | _setUniquePool("unchallenged") | ||
244 | _gSingle("Challenge Room/Panel_nevertrusted_maladjusted", kPurpleMiddle) | ||
245 | _gSingle("Challenge Room/Panel_writer_songwriter", kBlueMiddle) | ||
246 | _gSingle("Challenge Room/Panel_lobs_lobster", kBlueMiddle) | ||
247 | |||
248 | _setUniquePool("red") | ||
249 | _gSingle("Hangry Room/Panel_red_bot_1", kRedBottom) | ||
250 | _gSingle("Hangry Room/Panel_red_bot_2", kRedBottom) | ||
251 | _gSingle("Hangry Room/Panel_red_bot_3", kRedBottom) | ||
252 | _gSingle("Hangry Room/Panel_red_bot_6", kRedBottom) | ||
253 | |||
254 | # Do must-reuse panels with no unique pool last so that we can reuse already chosen answers. | ||
255 | _clearUniquePool() | ||
256 | _gSingle("Symmetry Room/Panel_left_wrong", kDoubleBlackBottom) | ||
257 | _gSingle("Symmetry Room/Panel_black_white", kBlackBottom) | ||
258 | |||
259 | _gSingle("Shuffle Room/Panel_lost_found", kBlackBottom) | ||
260 | _gSingle("Shuffle Room/Panel_clockwise_counterclockwise", kBlackBottom) | ||
261 | _gSingle("Shuffle Room/Panel_order_chaos", kBlackBottom) | ||
262 | |||
263 | _gSingle("Maze Room/Panel_down_up", kBlackBottom) | ||
264 | _gSingle("Maze Room/Panel_strays_maze", kPurpleTop) | ||
265 | _gSingle("Maze Room/Panel_daze_maze", kPurpleMiddle) | ||
266 | _gSingle("Maze Room/Panel_hide_seek", kBlackBottom) | ||
267 | _gSingle("Maze Room/Panel_hide_seek_2", kBlackBottom) | ||
268 | _gSingle("Maze Room/Panel_hide_seek_3", kBlackBottom) | ||
269 | _gSingle("Maze Room/Panel_hide_seek_4", kBlackBottom) | ||
270 | _gSingle("Maze Room/Panel_leap_jump", kWhiteBottom) | ||
271 | _gSingle("Maze Room/Panel_look_look", kWhiteBottom) | ||
272 | |||
273 | _gSingle("Appendix Room/Panel_discover_recover", kPurpleMiddle) | ||
274 | _gSingle("Appendix Room/Panel_warner_corner", kPurpleTop) | ||
275 | _gSingle("Appendix Room/Panel_adjust_readjusted", kBlueMiddle) | ||
276 | _gSingle("Appendix Room/Panel_trust_crust", kPurpleMiddle) | ||
277 | _gCopy("Appendix Room/Panel_trust_crust", "Appendix Room/Panel_trust_crust_2") | ||
278 | _gSingle("Appendix Room/Panel_trusted_readjusted", kPurpleMiddle) | ||
279 | |||
280 | _gSingle("Painting Room/Panel_free_three", kPurpleMiddle) | ||
281 | _gSingle("Painting Room/Panel_our_four", kBlueMiddle) | ||
282 | _gSingle("Painting Room/Panel_house_neighborhood", kBlueBottom) | ||
283 | # Panel_path_road | ||
284 | _gSingle("Painting Room/Panel_park_drive", kBlackBottom) | ||
285 | _gSingle("Painting Room/Panel_carriage_horse", kRedBottom) | ||
286 | _gSingle("Painting Room/Panel_learns_turns", kPurpleMiddle) | ||
287 | _gSingle("Painting Room/Panel_urns_turns", kBlueMiddle) | ||
288 | |||
289 | _gSingle("Backside Room/Panel_ward_forward", kBlueMiddle) | ||
290 | _gSingle("Backside Room/Panel_hind_behind", kBlueMiddle) | ||
291 | _gSingle("Backside Room/Panel_rig_right", kBlueMiddle) | ||
292 | _gSingle("Backside Room/Panel_turn_return", kBlueMiddle) | ||
293 | _gSingle("Backside Room/Panel_windward_forward", kPurpleMiddle) | ||
294 | _gSingle("Backside Room/Panel_light_right", kPurpleMiddle) | ||
295 | _gSingle("Backside Room/Panel_rewind_behind", kPurpleMiddle) | ||
296 | _gSingle("Backside Room/Panel_learn_return", kPurpleMiddle) | ||
297 | |||
298 | _gSingle("Color Arrow Room/Panel_hues_colors", kWhiteBottom) | ||
299 | |||
300 | # Now we'll generate puzzles that don't need to be reused, and hopefully cover | ||
301 | # all previously generated answers. | ||
302 | _clearFlag(kMustReuseAnswer) | ||
303 | |||
304 | _setUniquePool("agreeable") | ||
305 | _gSingle("Antonym Room/Panel_retool_looter", kBlackMiddle) | ||
306 | _gSingle("Antonym Room/Panel_drawer_reward", kBlackMiddle) | ||
307 | _gSingle("Antonym Room/Panel_stressed_desserts", kBlackMiddle) | ||
308 | _gSingle("Antonym Room/Panel_star_rats", kBlackMiddle) | ||
309 | _gSingle("Antonym Room/Panel_tame_mate", kBlackTop) | ||
310 | _gSingle("Antonym Room/Panel_cat_tack", kBlackTop) | ||
311 | |||
312 | _setUniquePool("seeker") | ||
313 | _setFlag(kObscureHint) | ||
314 | _gSingle("Heteronym Room/Panel_bear_bear", kWhiteMiddle) | ||
315 | _gSingle("Heteronym Room/Panel_bow_bow", kWhiteMiddle) | ||
316 | _gSingle("Heteronym Room/Panel_does_does", kWhiteMiddle) | ||
317 | _gDouble("Heteronym Room/Panel_mine_mine", "Heteronym Room/Panel_mine_mine_2", kWhiteMiddle) | ||
318 | _gDouble( | ||
319 | "Heteronym Room/Panel_mobile_mobile", "Heteronym Room/Panel_mobile_mobile_2", kWhiteMiddle | ||
320 | ) | ||
321 | _gStack2( | ||
322 | "Heteronym Room/Panel_desert_dessert", | ||
323 | kWhiteTop, | ||
324 | "Heteronym Room/Panel_desert_desert", | ||
325 | kWhiteMiddle | ||
326 | ) | ||
327 | _gStack2("Heteronym Room/Panel_sow_so", kWhiteTop, "Heteronym Room/Panel_sow_sow", kWhiteMiddle) | ||
328 | _gDouble("Heteronym Room/Panel_two_to", "Heteronym Room/Panel_two_too", kWhiteTop) | ||
329 | _gDouble("Heteronym Room/Panel_not_knot", "Heteronym Room/Panel_not_naught", kWhiteTop) | ||
330 | _gSingle("Heteronym Room/Panel_write_right", kWhiteTop) | ||
331 | _gSingle("Heteronym Room/Panel_you_ewe", kWhiteTop) | ||
332 | _gSingle("Heteronym Room/Panel_bear_bare", kWhiteTop) | ||
333 | _clearFlag(kObscureHint) | ||
334 | |||
335 | _setUniquePool("tenacious") | ||
336 | _gSingle("Palindrome Room/Panel_slaughter_laughter", kRedMiddle) | ||
337 | _gSingle("Palindrome Room/Panel_dread_dead", kRedMiddle) | ||
338 | _gSingle("Palindrome Room/Panel_massacred_sacred", kRedMiddle) | ||
339 | _gSingle("Palindrome Room/Panel_decay_day", kRedMiddle) | ||
340 | # do palindromes | ||
341 | |||
342 | _setUniquePool("discerning") | ||
343 | _gSingle("Sun Room/Panel_hits_this", kYellowMiddle) | ||
344 | _gSingle("Sun Room/Panel_adder_dread", kYellowMiddle) | ||
345 | _gSingle("Sun Room/Panel_laughters_slaughter", kYellowMiddle) | ||
346 | _gSingle("Sun Room/Panel_rat_art", kYellowMiddle) | ||
347 | _gSingle("Sun Room/Panel_dusty_study", kYellowMiddle) | ||
348 | _gSingle("Sun Room/Panel_state_taste", kYellowMiddle) | ||
349 | _gSingle("Sun Room/Panel_react_trace", kYellowMiddle) | ||
350 | _gSingle("Sun Room/Panel_seam_same", kYellowMiddle) | ||
351 | _gDouble("Sun Room/Panel_warred_drawer", "Sun Room/Panel_redraw_drawer", kYellowMiddle) | ||
352 | _gDouble("Sun Room/Panel_stone_notes", "Sun Room/Panel_onset_notes", kYellowMiddle) | ||
353 | _gDouble("Sun Room/Panel_arts_star", "Sun Room/Panel_tsar_star", kYellowMiddle) | ||
354 | _gDouble("Sun Room/Panel_dear_read", "Sun Room/Panel_dare_read", kYellowMiddle) | ||
355 | |||
356 | _setUniquePool("bold") | ||
357 | _gSingle("Truncate Room/Panel_sushi_hi", kRedMiddle) | ||
358 | _gSingle("Truncate Room/Panel_thistle_this", kRedMiddle) | ||
359 | _gSingle("Truncate Room/Panel_heartbreak_brake", kRedTop) | ||
360 | _gSingle("Truncate Room/Panel_airplane_plain", kRedTop) | ||
361 | _gSingle("Truncate Room/Panel_nightmare_knight", kRedTop) | ||
362 | _gSingle("Truncate Room/Panel_sign_sigh", kRedTop) | ||
363 | _gDouble("Truncate Room/Panel_undead_dead", "Truncate Room/Panel_deadline_dead", kRedMiddle) | ||
364 | _gDouble("Truncate Room/Panel_landmass_mass", "Truncate Room/Panel_massacred_mass", kRedMiddle) | ||
365 | |||
366 | _setUniquePool("rhyme") | ||
367 | _gStack2( | ||
368 | "Double Room/Panel_ascend_rhyme", kPurpleTop, "Double Room/Panel_ascend_syn", kWhiteBottom | ||
369 | ) | ||
370 | _gStack2( | ||
371 | "Double Room/Panel_double_rhyme", kPurpleTop, "Double Room/Panel_double_syn", kWhiteBottom | ||
372 | ) | ||
373 | _gStack2( | ||
374 | "Double Room/Panel_blocked_rhyme", kPurpleTop, "Double Room/Panel_blocked_syn", kWhiteBottom | ||
375 | ) | ||
376 | _gStack2("Double Room/Panel_rise_rhyme", kPurpleTop, "Double Room/Panel_rise_syn", kWhiteBottom) | ||
377 | _gStack2( | ||
378 | "Double Room/Panel_crystal_rhyme", kPurpleTop, "Double Room/Panel_crystal_syn", kWhiteBottom | ||
379 | ) | ||
380 | _gStack2( | ||
381 | "Double Room/Panel_creative_rhyme", | ||
382 | kPurpleTop, | ||
383 | "Double Room/Panel_creative_syn", | ||
384 | kWhiteBottom | ||
385 | ) | ||
386 | _gStack2( | ||
387 | "Double Room/Panel_child_rhyme", kPurpleTop, "Double Room/Panel_child_syn", kWhiteBottom | ||
388 | ) | ||
389 | _gStack2( | ||
390 | "Double Room/Panel_hidden_rhyme", kPurpleTop, "Double Room/Panel_hidden_syn", kWhiteBottom | ||
391 | ) | ||
392 | _gStack2( | ||
393 | "Double Room/Panel_word_rhyme", kPurpleTop, "Double Room/Panel_word_whole", kBlueBottom | ||
394 | ) | ||
395 | _gStack2( | ||
396 | "Double Room/Panel_silent_rhyme", kPurpleTop, "Double Room/Panel_silent_syn", kWhiteBottom | ||
397 | ) | ||
398 | _gStack2( | ||
399 | "Double Room/Panel_bones_rhyme", kPurpleTop, "Double Room/Panel_bones_syn", kWhiteBottom | ||
400 | ) | ||
401 | _gStack2( | ||
402 | "Double Room/Panel_sentence_rhyme", | ||
403 | kPurpleTop, | ||
404 | "Double Room/Panel_sentence_whole", | ||
405 | kBlueBottom | ||
406 | ) | ||
407 | _gStack2( | ||
408 | "Double Room/Panel_dream_rhyme", kPurpleTop, "Double Room/Panel_dream_syn", kWhiteBottom | ||
409 | ) | ||
410 | _gStack2( | ||
411 | "Double Room/Panel_mystery_rhyme", kPurpleTop, "Double Room/Panel_mystery_syn", kWhiteBottom | ||
412 | ) | ||
413 | _gStack2("Double Room/Panel_jump_rhyme", kPurpleTop, "Double Room/Panel_jump_syn", kWhiteBottom) | ||
414 | _gStack2("Double Room/Panel_fall_rhyme", kPurpleTop, "Double Room/Panel_fall_syn", kWhiteBottom) | ||
415 | _gStack2( | ||
416 | "Double Room/Panel_return_rhyme", kPurpleTop, "Double Room/Panel_return_ant", kBlackBottom | ||
417 | ) | ||
418 | _gStack2( | ||
419 | "Double Room/Panel_descend_rhyme", kPurpleTop, "Double Room/Panel_descend_ant", kBlackBottom | ||
420 | ) | ||
421 | |||
422 | _clearUniquePool() | ||
423 | _gSingle("Entry Room/Panel_hidden_hidden", kWhiteMiddle) | ||
424 | |||
425 | _gPaired("Shuffle Room/Panel_sword_words", "Shuffle Room/Panel_words_sword", kYellowMiddle) | ||
426 | _gPaired("Shuffle Room/Panel_turn_runt", "Shuffle Room/Panel_turn_runt2", kYellowMiddle) | ||
427 | _gCohinted("Shuffle Room/Panel_lost_lots", "Shuffle Room/Panel_lost_slot", kYellowMiddle) | ||
428 | _gDouble("Shuffle Room/Panel_amen_mean", "Shuffle Room/Panel_name_mean", kYellowMiddle) | ||
429 | _gSingle("Shuffle Room/Panel_corner", kYellowTop) | ||
430 | _gSingle("Shuffle Room/Panel_gel", kYellowTop) | ||
431 | _gSingle("Shuffle Room/Panel_though", kYellowTop) | ||
432 | _gSingle("Shuffle Room/Panel_swap_wasp", kYellowMiddle) | ||
433 | _gSingle("Shuffle Room/Panel_eyes_see_shuffle", kYellowMiddle) | ||
434 | _gSingle("Shuffle Room/Panel_behind", kYellowMiddle) | ||
435 | _gPaired("Shuffle Room/Panel_left_left", "Shuffle Room/Panel_right_right", kWhiteMiddle) | ||
436 | _gSingle("Shuffle Room/Panel_middle_middle", kWhiteMiddle) | ||
437 | _gCopy("Shuffle Room/Panel_left_left", "Shuffle Room/Panel_left_left_2") | ||
438 | _gCopy("Shuffle Room/Panel_right_right", "Shuffle Room/Panel_right_right_2") | ||
439 | _gCopy("Shuffle Room/Panel_middle_middle", "Shuffle Room/Panel_middle_middle_2") | ||
440 | _gSingle("Shuffle Room/Panel_shortcuts", kWhiteMiddle) | ||
441 | _gSingle("Shuffle Room/Panel_tower", kWhiteMiddle) | ||
442 | |||
443 | _gSingle("Maze Room/Panel_reflow_flower", kYellowMiddle) | ||
444 | |||
445 | _gSingle("Appendix Room/Panel_rat_tar", kBlackMiddle) | ||
446 | _gSingle("Appendix Room/Panel_deadend_deadened", kWhiteTop) | ||
447 | _gPaired("Appendix Room/Panel_night_knight", "Appendix Room/Panel_knight_night", kBlueMiddle) | ||
448 | _gPaired("Appendix Room/Panel_bee_be", "Appendix Room/Panel_new_knew", kRedMiddle) | ||
449 | _gSingle("Appendix Room/Panel_fore_for", kRedMiddle) | ||
450 | _gCohinted( | ||
451 | "Appendix Room/Panel_trusted_trust", "Appendix Room/Panel_trusted_rusted", kRedMiddle | ||
452 | ) | ||
453 | _gCohinted("Appendix Room/Panel_rust_trust", "Appendix Room/Panel_rust_crust", kBlueMiddle) | ||
454 | _gSingle("Appendix Room/Panel_encrusted_rust", kRedMiddle) | ||
455 | _gCohinted( | ||
456 | "Appendix Room/Panel_adjust_readjust", "Appendix Room/Panel_adjust_adjusted", kBlueMiddle | ||
457 | ) | ||
458 | |||
459 | _gSingle("Painting Room/Panel_eon_one", kYellowMiddle) | ||
460 | _gSingle("Painting Room/Panel_to_two", kRedMiddle) | ||
461 | _setFlag(kShortAnswer) | ||
462 | _gSingle("Painting Room/Panel_an_many", kBlueMiddle) | ||
463 | _gSingle("Painting Room/Panel_may_many", kBlueMiddle) | ||
464 | _gSingle("Painting Room/Panel_any_many", kBlueMiddle) | ||
465 | _gSingle("Painting Room/Panel_man_many", kBlueMiddle) | ||
466 | _clearFlag(kShortAnswer) | ||
467 | |||
468 | _gExactLength("Backside Room/Panel_one_one", kWhiteMiddle, 1) | ||
469 | _gExactLength("Backside Room/Panel_two_two", kWhiteMiddle, 2) | ||
470 | _gExactLength("Backside Room/Panel_two_two_2", kWhiteMiddle, 2) | ||
471 | _gExactLength("Backside Room/Panel_three_three", kWhiteMiddle, 3) | ||
472 | _gExactLength("Backside Room/Panel_three_three_2", kWhiteMiddle, 3) | ||
473 | _gExactLength("Backside Room/Panel_three_three_3", kWhiteMiddle, 3) | ||
474 | |||
475 | _setFlag(kObscureHint) | ||
476 | _gSingle("Entry Room/Panel_forward_forward", kWhiteMiddle) | ||
477 | _gSingle("Entry Room/Panel_between_between", kWhiteMiddle) | ||
478 | _gSingle("Entry Room/Panel_backward_backward", kWhiteMiddle) | ||
479 | _gSingle("Entry Room/Panel_secret_secret", kWhiteMiddle) | ||
480 | |||
481 | _gPaired("Symmetry Room/Panel_leaf_feel", "Symmetry Room/Panel_feel_leaf", kBlackTop) | ||
482 | _gPaired("Symmetry Room/Panel_warts_straw", "Symmetry Room/Panel_straw_warts", kBlackMiddle) | ||
483 | _gPaired("Symmetry Room/Panel_near_far", "Symmetry Room/Panel_far_near", kBlackBottom) | ||
484 | _gPaired("Symmetry Room/Panel_left_right", "Symmetry Room/Panel_right_left", kBlackBottom) | ||
485 | |||
486 | _gSingle("Shuffle Room/Panel_theeyes_theeyes", kWhiteMiddle) | ||
487 | _gSingle("Shuffle Room/Panel_crossroads_crossroads", kWhiteMiddle) | ||
488 | _gSingle("Shuffle Room/Panel_corner_corner", kWhiteMiddle) | ||
489 | _gSingle("Shuffle Room/Panel_hollow_hollow", kWhiteMiddle) | ||
490 | _gPaired("Shuffle Room/Panel_far_far", "Shuffle Room/Panel_near_near", kWhiteMiddle) | ||
491 | |||
492 | _gSingle("Maze Room/Panel_trace_trace", kWhiteMiddle) | ||
493 | |||
494 | _gSingle("Appendix Room/Panel_deadend_deadend", kWhiteMiddle) | ||
495 | _gSingle("Appendix Room/Panel_lies_lies", kWhiteMiddle) | ||
496 | |||
497 | _gSingle("Cross Room/Panel_shortcut_shortcut", kWhiteMiddle) | ||
498 | |||
499 | _gSingle("Double Room/Panel_leap_leap", kWhiteMiddle) | ||
500 | |||
501 | _gSingle("Backside Room/Panel_backside_1", kWhiteMiddle) | ||
502 | _gSingle("Backside Room/Panel_backside_2", kWhiteMiddle) | ||
503 | _gSingle("Backside Room/Panel_backside_3", kWhiteMiddle) | ||
504 | _gSingle("Backside Room/Panel_backside_4", kWhiteMiddle) | ||
505 | _gSingle("Backside Room/Panel_backside_5", kWhiteMiddle) | ||
506 | _gSingle("Backside Room/Panel_farther_far", kRedMiddle) | ||
507 | _gSingle("Backside Room/Panel_first_first", kWhiteMiddle) | ||
508 | _gSingle("Backside Room/Panel_second_second", kWhiteMiddle) | ||
509 | _gSingle("Backside Room/Panel_third_third", kWhiteMiddle) | ||
510 | _gSingle("Backside Room/Panel_fourth_fourth", kWhiteMiddle) | ||
511 | |||
512 | _gExactLength("Backside Room/Panel_four_four", kWhiteMiddle, 4) | ||
513 | _gExactLength("Backside Room/Panel_four_four_2", kWhiteMiddle, 4) | ||
514 | _gExactLength("Backside Room/Panel_four_four_3", kWhiteMiddle, 4) | ||
515 | _gExactLength("Backside Room/Panel_four_four_4", kWhiteMiddle, 4) | ||
516 | _gExactLength("Backside Room/Panel_five_five", kWhiteMiddle, 5) | ||
517 | _gExactLength("Backside Room/Panel_five_five_2", kWhiteMiddle, 5) | ||
518 | _gExactLength("Backside Room/Panel_five_five_3", kWhiteMiddle, 5) | ||
519 | _gExactLength("Backside Room/Panel_five_five_4", kWhiteMiddle, 5) | ||
520 | _gExactLength("Backside Room/Panel_five_five_5", kWhiteMiddle, 5) | ||
521 | _gExactLength("Backside Room/Panel_six_six", kWhiteMiddle, 6) | ||
522 | _gExactLength("Backside Room/Panel_six_six_2", kWhiteMiddle, 6) | ||
523 | _gExactLength("Backside Room/Panel_six_six_3", kWhiteMiddle, 6) | ||
524 | _gExactLength("Backside Room/Panel_six_six_4", kWhiteMiddle, 6) | ||
525 | _gExactLength("Backside Room/Panel_six_six_5", kWhiteMiddle, 6) | ||
526 | _gExactLength("Backside Room/Panel_six_six_6", kWhiteMiddle, 6) | ||
527 | _gExactLength("Backside Room/Panel_seven_seven", kWhiteMiddle, 7) | ||
528 | _gExactLength("Backside Room/Panel_seven_seven_2", kWhiteMiddle, 7) | ||
529 | _gExactLength("Backside Room/Panel_seven_seven_3", kWhiteMiddle, 7) | ||
530 | _gExactLength("Backside Room/Panel_seven_seven_4", kWhiteMiddle, 7) | ||
531 | _gExactLength("Backside Room/Panel_seven_seven_5", kWhiteMiddle, 7) | ||
532 | _gExactLength("Backside Room/Panel_seven_seven_6", kWhiteMiddle, 7) | ||
533 | _gExactLength("Backside Room/Panel_seven_seven_7", kWhiteMiddle, 7) | ||
534 | _gExactLength("Backside Room/Panel_eight_eight", kWhiteMiddle, 8) | ||
535 | _gExactLength("Backside Room/Panel_eight_eight_2", kWhiteMiddle, 8) | ||
536 | _gExactLength("Backside Room/Panel_eight_eight_3", kWhiteMiddle, 8) | ||
537 | _gExactLength("Backside Room/Panel_eight_eight_4", kWhiteMiddle, 8) | ||
538 | _gExactLength("Backside Room/Panel_eight_eight_5", kWhiteMiddle, 8) | ||
539 | _gExactLength("Backside Room/Panel_eight_eight_6", kWhiteMiddle, 8) | ||
540 | _gExactLength("Backside Room/Panel_eight_eight_7", kWhiteMiddle, 8) | ||
541 | _gExactLength("Backside Room/Panel_eight_eight_8", kWhiteMiddle, 8) | ||
542 | _gExactLength("Backside Room/Panel_nine_nine", kWhiteMiddle, 9) | ||
543 | _gExactLength("Backside Room/Panel_nine_nine_2", kWhiteMiddle, 9) | ||
544 | _gExactLength("Backside Room/Panel_nine_nine_3", kWhiteMiddle, 9) | ||
545 | _gExactLength("Backside Room/Panel_nine_nine_4", kWhiteMiddle, 9) | ||
546 | _gExactLength("Backside Room/Panel_nine_nine_5", kWhiteMiddle, 9) | ||
547 | _gExactLength("Backside Room/Panel_nine_nine_6", kWhiteMiddle, 9) | ||
548 | _gExactLength("Backside Room/Panel_nine_nine_7", kWhiteMiddle, 9) | ||
549 | _gExactLength("Backside Room/Panel_nine_nine_8", kWhiteMiddle, 9) | ||
550 | _gExactLength("Backside Room/Panel_nine_nine_9", kWhiteMiddle, 9) | ||
551 | |||
552 | _clearFlag(kObscureHint) | ||
553 | |||
554 | if _needs_reuse.size() > 0: | ||
555 | print("Generation failed; the following words need to be reused:") | ||
556 | for word_id in _needs_reuse: | ||
557 | print(_answer_by_id[word_id]) | ||
558 | |||
559 | print("Generated!") | ||
560 | for puzzle in panel_mapping: | ||
561 | print("%s: %s? %s!" % puzzle) | ||
562 | |||
563 | |||
564 | func _pickRandom(set): | ||
565 | var id = _rng.randi_range(0, set.size() - 1) | ||
566 | return set[id] | ||
567 | |||
568 | |||
569 | func _setFlag(flag): | ||
570 | _flags |= flag | ||
571 | |||
572 | |||
573 | func _clearFlag(flag): | ||
574 | _flags &= ~flag | ||
575 | |||
576 | |||
577 | func _isFlag(flag): | ||
578 | return (_flags & flag) > 0 | ||
579 | |||
580 | |||
581 | func _setUniquePool(pool): | ||
582 | _unique_pool = pool | ||
583 | if not _answers_by_unique_pool.has(_unique_pool): | ||
584 | _answers_by_unique_pool[_unique_pool] = [] | ||
585 | |||
586 | |||
587 | func _clearUniquePool(): | ||
588 | _unique_pool = "" | ||
589 | |||
590 | |||
591 | func _gSingle(panel_path, puzzle_type): | ||
592 | if puzzle_type == kWhiteMiddle: | ||
593 | var word_choices = _filterBestPuzzles(_answers_by_type[kWhiteMiddle]) | ||
594 | var answer_id = _pickRandom(word_choices) | ||
595 | _setPanel(panel_path, answer_id, answer_id) | ||
596 | else: | ||
597 | var puzzle_choices = _filterBestPuzzles(_answers_by_type[puzzle_type]) | ||
598 | if puzzle_choices.empty(): | ||
599 | print("No possible puzzles for panel %s" % panel_path) | ||
600 | else: | ||
601 | var answer_id = _pickRandom(puzzle_choices) | ||
602 | var hint_choices = _puzzle_by_id[answer_id][1][puzzle_type] | ||
603 | var hint_id = _pickRandom(hint_choices) | ||
604 | _setPanel(panel_path, hint_id, answer_id) | ||
605 | |||
606 | |||
607 | func _gDouble(panel1_path, panel2_path, puzzle_type): | ||
608 | if puzzle_type == kWhiteMiddle: | ||
609 | var word_choices = _filterBestPuzzles(_answers_by_type[kWhiteMiddle]) | ||
610 | var answer_id = _pickRandom(word_choices) | ||
611 | _setPanel(panel1_path, answer_id, answer_id) | ||
612 | _setPanel(panel2_path, answer_id, answer_id) | ||
613 | else: | ||
614 | var pre_choices = _filterBestPuzzles(_answers_by_type[puzzle_type]) | ||
615 | var puzzle_choices = [] | ||
616 | for word_id in pre_choices: | ||
617 | if _puzzle_by_id[word_id][1][puzzle_type].size() > 1: | ||
618 | puzzle_choices.append(word_id) | ||
619 | if puzzle_choices.empty(): | ||
620 | print("No possible puzzles for panel %s" % panel1_path) | ||
621 | else: | ||
622 | var answer_id = _pickRandom(puzzle_choices) | ||
623 | var hint_choices = _puzzle_by_id[answer_id][1][puzzle_type].duplicate() | ||
624 | var hint1_id = _pickRandom(hint_choices) | ||
625 | hint_choices.erase(hint1_id) | ||
626 | var hint2_id = _pickRandom(hint_choices) | ||
627 | _setPanel(panel1_path, hint1_id, answer_id) | ||
628 | _setPanel(panel2_path, hint2_id, answer_id) | ||
629 | |||
630 | |||
631 | func _gPaired(panel1_path, panel2_path, puzzle_type): | ||
632 | var needed_type = puzzle_type | ||
633 | if puzzle_type == kWhiteMiddle: | ||
634 | needed_type = kBlackMiddle | ||
635 | var puzzle_choices = _filterBestPuzzles(_answers_by_type[needed_type]) | ||
636 | if puzzle_choices.empty(): | ||
637 | print("No possible puzzles for panel %s" % panel1_path) | ||
638 | else: | ||
639 | var answer_id = _pickRandom(puzzle_choices) | ||
640 | var hint_choices = _puzzle_by_id[answer_id][1][needed_type] | ||
641 | var hint_id = _pickRandom(hint_choices) | ||
642 | if puzzle_type == kWhiteMiddle: | ||
643 | _setPanel(panel1_path, hint_id, hint_id) | ||
644 | _setPanel(panel2_path, answer_id, answer_id) | ||
645 | else: | ||
646 | _setPanel(panel1_path, hint_id, answer_id) | ||
647 | _setPanel(panel2_path, answer_id, hint_id) | ||
648 | |||
649 | |||
650 | func _gCohinted(panel1_path, panel2_path, puzzle_type): | ||
651 | pass | ||
652 | |||
653 | |||
654 | func _gStack2(panel1_path, puzzle_type1, panel2_path, puzzle_type2): | ||
655 | if puzzle_type1 == kWhiteMiddle or puzzle_type2 == kWhiteMiddle: | ||
656 | if puzzle_type1 == kWhiteMiddle: | ||
657 | _gSingle(panel2_path, puzzle_type2) | ||
658 | _gCopyAnswer(panel2_path, panel1_path) | ||
659 | else: | ||
660 | _gSingle(panel1_path, puzzle_type1) | ||
661 | _gCopyAnswer(panel1_path, panel2_path) | ||
662 | else: | ||
663 | var pre_choices = _filterBestPuzzles(_answers_by_type[puzzle_type1]) | ||
664 | var puzzle_choices = [] | ||
665 | for word_id in pre_choices: | ||
666 | if _puzzle_by_id[word_id][1].has(puzzle_type2): | ||
667 | puzzle_choices.append(word_id) | ||
668 | if puzzle_choices.empty(): | ||
669 | print("No possible puzzles for panel %s" % panel1_path) | ||
670 | else: | ||
671 | var answer_id = _pickRandom(puzzle_choices) | ||
672 | var hint1_choices = _puzzle_by_id[answer_id][1][puzzle_type1] | ||
673 | var hint1_id = _pickRandom(hint1_choices) | ||
674 | var hint2_choices = _puzzle_by_id[answer_id][1][puzzle_type2] | ||
675 | var hint2_id = _pickRandom(hint2_choices) | ||
676 | _setPanel(panel1_path, hint1_id, answer_id) | ||
677 | _setPanel(panel2_path, hint2_id, answer_id) | ||
678 | |||
679 | |||
680 | func _gCopy(panel1_path, panel2_path): | ||
681 | for thing in panel_mapping: | ||
682 | if thing[0] == panel1_path: | ||
683 | panel_mapping.append([panel2_path, thing[1], thing[2]]) | ||
684 | return | ||
685 | |||
686 | |||
687 | func _gCopyAnswer(panel1_path, panel2_path): | ||
688 | for thing in panel_mapping: | ||
689 | if thing[0] == panel1_path: | ||
690 | panel_mapping.append([panel2_path, thing[2], thing[2]]) | ||
691 | return | ||
692 | |||
693 | |||
694 | func _gExactLength(panel_path, puzzle_type, answer_length): | ||
695 | var puzzle_choices = _filterBestPuzzles(_answers_by_length[answer_length]) | ||
696 | if puzzle_type != kWhiteMiddle: | ||
697 | # TODO: Do we even need this? | ||
698 | pass | ||
699 | if puzzle_choices.empty(): | ||
700 | print("No possible puzzles for panel %s" % panel_path) | ||
701 | else: | ||
702 | var answer_id = _pickRandom(puzzle_choices) | ||
703 | if puzzle_type == kWhiteMiddle: | ||
704 | _setPanel(panel_path, answer_id, answer_id) | ||
705 | else: | ||
706 | var hint_choices = _puzzle_by_id[answer_id][1][puzzle_type] | ||
707 | var hint_id = _pickRandom(hint_choices) | ||
708 | _setPanel(panel_path, hint_id, answer_id) | ||
709 | |||
710 | |||
711 | func _filterBestPuzzles(input): | ||
712 | var not_uniqued = [] | ||
713 | if _unique_pool == "": | ||
714 | not_uniqued = input | ||
715 | elif _answers_by_unique_pool.has(_unique_pool): | ||
716 | for word_id in input: | ||
717 | if not _answers_by_unique_pool[_unique_pool].has(word_id): | ||
718 | not_uniqued.append(word_id) | ||
719 | else: | ||
720 | not_uniqued = input | ||
721 | #if _isFlag(kMustReuseAnswer): | ||
722 | # var possible = [] | ||
723 | # for word_id in not_uniqued: | ||
724 | # if _puzzle_by_id[word_id][1].size() > 1: | ||
725 | # possible.append(word_id) | ||
726 | # not_uniqued = possible | ||
727 | var result = [] | ||
728 | for word_id in not_uniqued: | ||
729 | if _needs_reuse.has(word_id): | ||
730 | result.append(word_id) | ||
731 | if result.empty(): | ||
732 | for word_id in not_uniqued: | ||
733 | result.append(word_id) | ||
734 | if _possible_reuse.has(word_id): | ||
735 | result.append(word_id) | ||
736 | return result | ||
737 | |||
738 | |||
739 | func _setPanel(panel_path, hint_id, answer_id): | ||
740 | if _unique_pool != "": | ||
741 | _answers_by_unique_pool[_unique_pool].append(answer_id) | ||
742 | panel_mapping.append([panel_path, _answer_by_id[hint_id], _answer_by_id[answer_id]]) | ||
743 | if not _isFlag(kMustReuseAnswer): | ||
744 | if _needs_reuse.has(answer_id): | ||
745 | _needs_reuse.erase(answer_id) | ||
746 | _possible_reuse.append(answer_id) | ||
747 | _total_generated += 1 | ||
748 | emit_signal("generator_status", "Generating puzzles... (%d/?)" % _total_generated) | ||
diff --git a/randomizer/load.gd b/randomizer/load.gd new file mode 100644 index 0000000..727e368 --- /dev/null +++ b/randomizer/load.gd | |||
@@ -0,0 +1,18 @@ | |||
1 | extends "res://scripts/load.gd" | ||
2 | |||
3 | |||
4 | func _load(): | ||
5 | global._print("Hooked Load Start") | ||
6 | |||
7 | var randomizer = global.get_node("Randomizer") | ||
8 | |||
9 | # Apply the randomized panels. | ||
10 | var panels_parent = $Panels | ||
11 | for puzzle in randomizer.generator.panel_mapping: | ||
12 | var panel = panels_parent.get_node(puzzle[0]) | ||
13 | panel.text = puzzle[1] | ||
14 | panel.answer = puzzle[2] | ||
15 | |||
16 | # Proceed with the rest of the load. | ||
17 | global._print("Hooked Load End") | ||
18 | ._load() | ||
diff --git a/randomizer/panelEnd.gd b/randomizer/panelEnd.gd new file mode 100644 index 0000000..81f07d6 --- /dev/null +++ b/randomizer/panelEnd.gd | |||
@@ -0,0 +1,7 @@ | |||
1 | extends "res://scripts/panelEnd.gd" | ||
2 | |||
3 | |||
4 | func handle_correct(): | ||
5 | # We don't call the base method because we want to suppress the original | ||
6 | # behaviour. | ||
7 | global.solved -= 1 | ||
diff --git a/randomizer/panelInput.gd b/randomizer/panelInput.gd new file mode 100644 index 0000000..48d6324 --- /dev/null +++ b/randomizer/panelInput.gd | |||
@@ -0,0 +1,5 @@ | |||
1 | extends "res://scripts/panelInput.gd" | ||
2 | |||
3 | |||
4 | func uncomplete(): | ||
5 | global._print("Filtered out panel uncompletion") | ||
diff --git a/randomizer/panelLevelSwitch.gd b/randomizer/panelLevelSwitch.gd new file mode 100644 index 0000000..06df02b --- /dev/null +++ b/randomizer/panelLevelSwitch.gd | |||
@@ -0,0 +1,7 @@ | |||
1 | extends "res://scripts/panelLevelSwitch.gd" | ||
2 | |||
3 | |||
4 | func handle_correct(): | ||
5 | # We don't call the base method because we want to suppress the original | ||
6 | # behaviour. | ||
7 | global.solved -= 1 | ||
diff --git a/randomizer/randomizer.gd b/randomizer/randomizer.gd new file mode 100644 index 0000000..ff558a3 --- /dev/null +++ b/randomizer/randomizer.gd | |||
@@ -0,0 +1,26 @@ | |||
1 | extends Node | ||
2 | |||
3 | const my_version = "0.1.0" | ||
4 | |||
5 | var SCRIPT_generator | ||
6 | |||
7 | var generator | ||
8 | |||
9 | signal finished_randomizing | ||
10 | signal randomizer_status | ||
11 | |||
12 | |||
13 | func start(gen_seed = ""): | ||
14 | generator = SCRIPT_generator.new($GeneratedPuzzles) | ||
15 | generator.connect("generator_status", self, "statusUpdate") | ||
16 | generator.generate(gen_seed) | ||
17 | |||
18 | emit_signal("finished_randomizing") | ||
19 | |||
20 | |||
21 | func statusUpdate(text): | ||
22 | emit_signal("randomizer_status", text) | ||
23 | |||
24 | |||
25 | func getSaveFileName(): | ||
26 | return "zzRN_%d" % generator.gen_seed | ||
diff --git a/randomizer/settings_buttons.gd b/randomizer/settings_buttons.gd new file mode 100644 index 0000000..4e656b0 --- /dev/null +++ b/randomizer/settings_buttons.gd | |||
@@ -0,0 +1,16 @@ | |||
1 | extends Button | ||
2 | |||
3 | |||
4 | func _ready(): | ||
5 | pass | ||
6 | |||
7 | |||
8 | func _start_pressed(): | ||
9 | self.disabled = true | ||
10 | |||
11 | var randomizer = global.get_node("Randomizer") | ||
12 | randomizer.start(self.get_parent().get_node("seed_box").text) | ||
13 | |||
14 | |||
15 | func _back_pressed(): | ||
16 | fader._fade_start("main_menu") | ||
diff --git a/randomizer/settings_screen.gd b/randomizer/settings_screen.gd new file mode 100644 index 0000000..708b4ef --- /dev/null +++ b/randomizer/settings_screen.gd | |||
@@ -0,0 +1,78 @@ | |||
1 | extends Spatial | ||
2 | |||
3 | |||
4 | func _ready(): | ||
5 | # Undo the load screen removing our cursor | ||
6 | get_tree().get_root().set_disable_input(false) | ||
7 | Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) | ||
8 | |||
9 | # Create the global Randomizer node, if it doesn't already exist. | ||
10 | if not global.has_node("Randomizer"): | ||
11 | var randomizer_script = ResourceLoader.load("user://maps/randomizer/randomizer.gd") | ||
12 | var randomizer_instance = randomizer_script.new() | ||
13 | randomizer_instance.name = "Randomizer" | ||
14 | global.add_child(randomizer_instance) | ||
15 | |||
16 | randomizer_instance.SCRIPT_generator = load("user://maps/randomizer/generator.gd") | ||
17 | |||
18 | var generated_puzzles = ResourceLoader.load("user://maps/randomizer/generated_puzzles.gd") | ||
19 | var generated_puzzles_instance = generated_puzzles.new() | ||
20 | generated_puzzles_instance.name = "GeneratedPuzzles" | ||
21 | randomizer_instance.add_child(generated_puzzles_instance) | ||
22 | |||
23 | # Let's also inject any scripts we need to inject now. | ||
24 | installScriptExtension(ResourceLoader.load("user://maps/randomizer/load.gd")) | ||
25 | installScriptExtension(ResourceLoader.load("user://maps/randomizer/panelEnd.gd")) | ||
26 | installScriptExtension(ResourceLoader.load("user://maps/randomizer/panelInput.gd")) | ||
27 | installScriptExtension(ResourceLoader.load("user://maps/randomizer/panelLevelSwitch.gd")) | ||
28 | installScriptExtension(ResourceLoader.load("user://maps/randomizer/worldTransporter.gd")) | ||
29 | |||
30 | var randomizer = global.get_node("Randomizer") | ||
31 | randomizer.connect("finished_randomizing", self, "randomizationSuccessful") | ||
32 | randomizer.connect("randomizer_status", self, "randomizationStatus") | ||
33 | |||
34 | # Show client version. | ||
35 | self.get_node("Panel/title").text = "RANDOMIZER (%s)" % randomizer.my_version | ||
36 | |||
37 | # Increase font size in text boxes. | ||
38 | var field_font = DynamicFont.new() | ||
39 | field_font.font_data = load("res://fonts/CutiveMono_Regular.ttf") | ||
40 | field_font.size = 36 | ||
41 | |||
42 | self.get_node("Panel/seed_box").add_font_override("font", field_font) | ||
43 | |||
44 | |||
45 | # Adapted from https://gitlab.com/Delta-V-Modding/Mods/-/blob/main/game/ModLoader.gd | ||
46 | func installScriptExtension(childScript: Resource): | ||
47 | # Force Godot to compile the script now. | ||
48 | # We need to do this here to ensure that the inheritance chain is | ||
49 | # properly set up, and multiple mods can chain-extend the same | ||
50 | # class multiple times. | ||
51 | # This is also needed to make Godot instantiate the extended class | ||
52 | # when creating singletons. | ||
53 | # The actual instance is thrown away. | ||
54 | childScript.new() | ||
55 | |||
56 | var parentScript = childScript.get_base_script() | ||
57 | var parentScriptPath = parentScript.resource_path | ||
58 | global._print("ModLoader: Installing script extension over %s" % parentScriptPath) | ||
59 | childScript.take_over_path(parentScriptPath) | ||
60 | |||
61 | |||
62 | func randomizationStatus(message): | ||
63 | var popup = self.get_node("Panel/AcceptDialog") | ||
64 | popup.window_title = "Randomizing..." | ||
65 | popup.dialog_text = message | ||
66 | popup.popup_exclusive = true | ||
67 | popup.get_ok().visible = false | ||
68 | popup.popup_centered() | ||
69 | |||
70 | |||
71 | func randomizationSuccessful(): | ||
72 | var randomizer = global.get_node("Randomizer") | ||
73 | |||
74 | # Switch to LL1 | ||
75 | Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) | ||
76 | global.map = "level1" | ||
77 | global.save_file = randomizer.getSaveFileName() | ||
78 | var _discard = get_tree().change_scene("res://scenes/load_screen.tscn") | ||
diff --git a/randomizer/worldTransporter.gd b/randomizer/worldTransporter.gd new file mode 100644 index 0000000..1488907 --- /dev/null +++ b/randomizer/worldTransporter.gd | |||
@@ -0,0 +1,6 @@ | |||
1 | extends "res://scripts/worldTransporter.gd" | ||
2 | |||
3 | |||
4 | func _body_entered(_body): | ||
5 | # Do not transport the player. | ||
6 | pass | ||