about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Archipelago/client.gd118
-rw-r--r--Archipelago/load.gd87
-rw-r--r--Archipelago/mypainting.gd5
-rw-r--r--Archipelago/painting.gd10
-rw-r--r--Archipelago/painting_eye.gd16
-rw-r--r--Archipelago/painting_scenery.gd10
-rw-r--r--Archipelago/panel.gd2
-rw-r--r--Archipelago/pilgrimage_terminator.gd11
-rw-r--r--Archipelago/settings_screen.gd4
-rw-r--r--Archipelago/teleport.gd27
-rw-r--r--CHANGELOG.md30
-rw-r--r--README.md62
-rw-r--r--util/generate_gamedata.rb69
13 files changed, 368 insertions, 83 deletions
diff --git a/Archipelago/client.gd b/Archipelago/client.gd index 6f5fefe..c690986 100644 --- a/Archipelago/client.gd +++ b/Archipelago/client.gd
@@ -7,6 +7,7 @@ var SCRIPT_multiplayer
7var SCRIPT_mypainting 7var SCRIPT_mypainting
8var SCRIPT_notifier 8var SCRIPT_notifier
9var SCRIPT_panel 9var SCRIPT_panel
10var SCRIPT_pilgrimage_terminator
10var SCRIPT_uuid 11var SCRIPT_uuid
11 12
12var ap_server = "" 13var ap_server = ""
@@ -17,59 +18,28 @@ var enable_multiplayer = false
17var track_player = false 18var track_player = false
18var connection_history = [] 19var connection_history = []
19 20
20const my_version = "2.2.0" 21const my_version = "3.0.1"
21const ap_version = {"major": 0, "minor": 4, "build": 5, "class": "Version"} 22const ap_version = {"major": 0, "minor": 4, "build": 6, "class": "Version"}
22const color_items = [ 23const color_items = [
23 "White", "Black", "Red", "Blue", "Green", "Brown", "Gray", "Orange", "Purple", "Yellow" 24 "White", "Black", "Red", "Blue", "Green", "Brown", "Gray", "Orange", "Purple", "Yellow"
24] 25]
25const progressive_items = { 26const progressive_items = {
26 "Progressive Orange Tower": 27 "Progressive Orange Tower":
27 [ 28 ["Second Floor", "Third Floor", "Fourth Floor", "Fifth Floor", "Sixth Floor", "Seventh Floor"],
28 {"item": "Orange Tower - Second Floor", "display": "Second Floor"},
29 {"item": "Orange Tower - Third Floor", "display": "Third Floor"},
30 {"item": "Orange Tower - Fourth Floor", "display": "Fourth Floor"},
31 {"item": "Orange Tower - Fifth Floor", "display": "Fifth Floor"},
32 {"item": "Orange Tower - Sixth Floor", "display": "Sixth Floor"},
33 {"item": "Orange Tower - Seventh Floor", "display": "Seventh Floor"},
34 ],
35 "Progressive Art Gallery": 29 "Progressive Art Gallery":
36 [ 30 ["Second Floor", "Third Floor", "Fourth Floor", "Fifth Floor", "Exit"],
37 {"item": "Art Gallery - Second Floor", "display": "Second Floor"}, 31 "Progressive Hallway Room": ["First Door", "Second Door", "Third Door", "Fourth Door"],
38 {"item": "Art Gallery - Third Floor", "display": "Third Floor"}, 32 "Progressive Fearless": ["Second Floor", "Third Floor"],
39 {"item": "Art Gallery - Fourth Floor", "display": "Fourth Floor"},
40 {"item": "Art Gallery - Fifth Floor", "display": "Fifth Floor"},
41 {"item": "Art Gallery - Exit", "display": "Exit"},
42 ],
43 "Progressive Hallway Room":
44 [
45 {"item": "Outside The Agreeable - Hallway Door", "display": "First Door"},
46 {"item": "Hallway Room (2) - Exit", "display": "Second Door"},
47 {"item": "Hallway Room (3) - Exit", "display": "Third Door"},
48 {"item": "Hallway Room (4) - Exit", "display": "Fourth Door"},
49 ],
50 "Progressive Fearless":
51 [
52 {"item": "The Fearless (First Floor) - Second Floor", "display": "Second Floor"},
53 {"item": "The Fearless (Second Floor) - Third Floor", "display": "Third Floor"},
54 ],
55 "Progressive Colorful": 33 "Progressive Colorful":
56 [ 34 ["White", "Black", "Red", "Yellow", "Blue", "Purple", "Orange", "Green", "Brown", "Gray"],
57 {"item": "The Colorful - White Door", "display": "White"}, 35 "Progressive Pilgrimage":
58 {"item": "The Colorful - Black Door", "display": "Black"}, 36 ["1 Sunwarp", "2 Sunwarp", "3 Sunwarp", "4 Sunwarp", "5 Sunwarp", "6 Sunwarp"]
59 {"item": "The Colorful - Red Door", "display": "Red"},
60 {"item": "The Colorful - Yellow Door", "display": "Yellow"},
61 {"item": "The Colorful - Blue Door", "display": "Blue"},
62 {"item": "The Colorful - Purple Door", "display": "Purple"},
63 {"item": "The Colorful - Orange Door", "display": "Orange"},
64 {"item": "The Colorful - Green Door", "display": "Green"},
65 {"item": "The Colorful - Brown Door", "display": "Brown"},
66 {"item": "The Colorful - Gray Door", "display": "Gray"},
67 ]
68} 37}
69 38
70const kTHE_END = 0 39const kTHE_END = 0
71const kTHE_MASTER = 1 40const kTHE_MASTER = 1
72const kLEVEL_2 = 2 41const kLEVEL_2 = 2
42const kPILGRIMAGE = 3
73 43
74const kNO_PANEL_SHUFFLE = 0 44const kNO_PANEL_SHUFFLE = 0
75const kREARRANGE_PANELS = 1 45const kREARRANGE_PANELS = 1
@@ -83,6 +53,12 @@ const kCLASSIFICATION_REMOTE_NORMAL = 0
83const kCLASSIFICATION_REMOTE_REDUCED = 1 53const kCLASSIFICATION_REMOTE_REDUCED = 1
84const kCLASSIFICATION_REMOTE_INSANITY = 2 54const kCLASSIFICATION_REMOTE_INSANITY = 2
85 55
56const kSUNWARP_ACCESS_NORMAL = 0
57const kSUNWARP_ACCESS_DISABLED = 1
58const kSUNWARP_ACCESS_UNLOCK = 2
59const kSUNWARP_ACCESS_INDIVIDUAL = 3
60const kSUNWARP_ACCESS_PROGRESSIVE = 4
61
86var _client = WebSocketClient.new() 62var _client = WebSocketClient.new()
87var _should_process = false 63var _should_process = false
88var _initiated_disconnect = false 64var _initiated_disconnect = false
@@ -115,10 +91,17 @@ var _door_shuffle = false
115var _color_shuffle = false 91var _color_shuffle = false
116var _panel_shuffle = 0 # none, rearrange 92var _panel_shuffle = 0 # none, rearrange
117var _painting_shuffle = false 93var _painting_shuffle = false
94var _sunwarp_access = 0 # normal, disabled, unlock, progressive
118var _mastery_achievements = 21 95var _mastery_achievements = 21
119var _level_2_requirement = 223 96var _level_2_requirement = 223
120var _location_classification_bit = 0 97var _location_classification_bit = 0
121var _early_color_hallways = false 98var _early_color_hallways = false
99var _pilgrimage_compatibility = false # set to true for pre-0.4.6
100var _pilgrimage_enabled = false
101var _pilgrimage_allows_roof_access = false
102var _pilgrimage_allows_paintings = false
103var _sunwarp_shuffle = false
104var _sunwarp_mapping = []
122var _slot_seed = 0 105var _slot_seed = 0
123 106
124var _map_loaded = false 107var _map_loaded = false
@@ -293,6 +276,10 @@ func _on_data():
293 _painting_shuffle = _slot_data["shuffle_paintings"] 276 _painting_shuffle = _slot_data["shuffle_paintings"]
294 if _slot_data.has("shuffle_panels"): 277 if _slot_data.has("shuffle_panels"):
295 _panel_shuffle = _slot_data["shuffle_panels"] 278 _panel_shuffle = _slot_data["shuffle_panels"]
279 if _slot_data.has("sunwarp_access"):
280 _sunwarp_access = _slot_data["sunwarp_access"]
281 else:
282 _sunwarp_access = kSUNWARP_ACCESS_NORMAL
296 if _slot_data.has("seed"): 283 if _slot_data.has("seed"):
297 _slot_seed = _slot_data["seed"] 284 _slot_seed = _slot_data["seed"]
298 if _slot_data.has("painting_entrance_to_exit"): 285 if _slot_data.has("painting_entrance_to_exit"):
@@ -316,6 +303,25 @@ func _on_data():
316 _early_color_hallways = _slot_data["early_color_hallways"] 303 _early_color_hallways = _slot_data["early_color_hallways"]
317 else: 304 else:
318 _early_color_hallways = false 305 _early_color_hallways = false
306 if _slot_data.has("enable_pilgrimage"):
307 _pilgrimage_enabled = _slot_data["enable_pilgrimage"]
308 else:
309 _pilgrimage_compatibility = true
310 _pilgrimage_enabled = true
311 if _slot_data.has("pilgrimage_allows_roof_access"):
312 _pilgrimage_allows_roof_access = _slot_data["pilgrimage_allows_roof_access"]
313 else:
314 _pilgrimage_allows_roof_access = true
315 if _slot_data.has("pilgrimage_allows_paintings"):
316 _pilgrimage_allows_paintings = _slot_data["pilgrimage_allows_paintings"]
317 else:
318 _pilgrimage_allows_paintings = true
319 if _slot_data.has("shuffle_sunwarps"):
320 _sunwarp_shuffle = _slot_data["shuffle_sunwarps"]
321 else:
322 _sunwarp_shuffle = false
323 if _slot_data.has("sunwarp_permutation"):
324 _sunwarp_mapping = _slot_data["sunwarp_permutation"]
319 325
320 if _door_shuffle and not _early_color_hallways: 326 if _door_shuffle and not _early_color_hallways:
321 _location_classification_bit += kCLASSIFICATION_LOCAL_SMALL_SPHERE_ONE 327 _location_classification_bit += kCLASSIFICATION_LOCAL_SMALL_SPHERE_ONE
@@ -702,16 +708,22 @@ func processItem(item, index, from, flags):
702 if painting_node != null: 708 if painting_node != null:
703 painting_node.get_node("Script").movePainting() 709 painting_node.get_node("Script").movePainting()
704 710
711 if gamedata.warp_ids_by_item_id.has(int(item)):
712 var warpsNode = get_tree().get_root().get_node("Spatial/Warps")
713 for warp_id in gamedata.warp_ids_by_item_id[int(item)]:
714 warpsNode.get_node(warp_id).unlock_warp()
715
705 # Handle progressive items. 716 # Handle progressive items.
706 if item_name in progressive_items.keys(): 717 if int(item) in gamedata.items_by_progressive_id.keys():
707 if not item_name in _progressive_progress: 718 if not int(item) in _progressive_progress:
708 _progressive_progress[item_name] = 0 719 _progressive_progress[int(item)] = 0
709 720
710 if _progressive_progress[item_name] < progressive_items[item_name].size(): 721 if _progressive_progress[int(item)] < gamedata.items_by_progressive_id[int(item)].size():
711 var subitem_name = progressive_items[item_name][_progressive_progress[item_name]]["item"] 722 var subitems = gamedata.items_by_progressive_id[int(item)]
712 global._print(subitem_name) 723 var subitem_id = subitems[_progressive_progress[int(item)]]
713 processItem(_item_name_to_id[subitem_name], null, null, null) 724 global._print("Subitem: %d" % subitem_id)
714 _progressive_progress[item_name] += 1 725 processItem(subitem_id, null, null, null)
726 _progressive_progress[int(item)] += 1
715 727
716 if _color_shuffle and color_items.has(_item_id_to_name[item]): 728 if _color_shuffle and color_items.has(_item_id_to_name[item]):
717 var lcol = _item_id_to_name[item].to_lower() 729 var lcol = _item_id_to_name[item].to_lower()
@@ -725,8 +737,8 @@ func processItem(item, index, from, flags):
725 saveLocaldata() 737 saveLocaldata()
726 738
727 if item_name in progressive_items: 739 if item_name in progressive_items:
728 var subitem = progressive_items[item_name][_progressive_progress[item_name] - 1] 740 var subitem = progressive_items[item_name][_progressive_progress[int(item)] - 1]
729 item_name += " (%s)" % subitem["display"] 741 item_name += " (%s)" % subitem
730 742
731 var player_name = "Unknown" 743 var player_name = "Unknown"
732 if _player_name_by_slot.has(from): 744 if _player_name_by_slot.has(from):
@@ -762,6 +774,10 @@ func paintingIsVanilla(painting):
762 return !$Gamedata.mentioned_paintings.has(painting) 774 return !$Gamedata.mentioned_paintings.has(painting)
763 775
764 776
777func warpIsVanilla(warp):
778 return !$Gamedata.mentioned_warps.has(warp)
779
780
765func evaluateSolvability(): 781func evaluateSolvability():
766 emit_signal("evaluate_solvability") 782 emit_signal("evaluate_solvability")
767 783
diff --git a/Archipelago/load.gd b/Archipelago/load.gd index 27e70b7..0ed978a 100644 --- a/Archipelago/load.gd +++ b/Archipelago/load.gd
@@ -354,6 +354,8 @@ func _load():
354 victory_condition = "the master" 354 victory_condition = "the master"
355 elif apclient._victory_condition == apclient.kLEVEL_2: 355 elif apclient._victory_condition == apclient.kLEVEL_2:
356 victory_condition = "level 2" 356 victory_condition = "level 2"
357 elif apclient._victory_condition == apclient.kPILGRIMAGE:
358 victory_condition = "pilgrimage"
357 359
358 set_static_panel("Entry Room/Panel_this_this", victory_condition) 360 set_static_panel("Entry Room/Panel_this_this", victory_condition)
359 set_static_panel("Entry Room/Panel_hidden_hidden", "hewwo") 361 set_static_panel("Entry Room/Panel_hidden_hidden", "hewwo")
@@ -583,11 +585,84 @@ func _load():
583 level_2.get_node("Viewport/GUI/Panel/TextEdit").connect( 585 level_2.get_node("Viewport/GUI/Panel/TextEdit").connect(
584 "answer_correct", apclient, "completedGoal" 586 "answer_correct", apclient, "completedGoal"
585 ) 587 )
588 elif apclient._victory_condition == apclient.kPILGRIMAGE:
589 var pilgrim_panel = self.get_node("Panels/Lingo Room/Panel_pilgrim")
590 pilgrim_panel.get_node("Viewport/GUI/Panel/TextEdit").connect(
591 "answer_correct", apclient, "completedGoal"
592 )
586 else: 593 else:
587 var the_end = self.get_node("Decorations/EndPanel/Panel_end_end") 594 var the_end = self.get_node("Decorations/EndPanel/Panel_end_end")
588 the_end.get_node("Viewport/GUI/Panel/TextEdit").connect( 595 the_end.get_node("Viewport/GUI/Panel/TextEdit").connect(
589 "answer_correct", apclient, "completedGoal" 596 "answer_correct", apclient, "completedGoal"
590 ) 597 )
598
599 # If pilgrimage does not allow roof access, add a node on the Crossroads
600 # Roof Access stairs that disables it.
601 if !apclient._pilgrimage_allows_roof_access:
602 var terminator = apclient.SCRIPT_pilgrimage_terminator.new()
603 terminator.name = "RoofAccessPilgrimageTerminator"
604 terminator.translation.x = -36
605 terminator.translation.y = 3
606 terminator.translation.z = -35
607
608 var terminator_shape = CollisionShape.new()
609 terminator_shape.shape = BoxShape.new()
610 terminator_shape.shape.extents.x = 0.1
611
612 terminator.add_child(terminator_shape)
613 get_node("Decorations").add_child(terminator)
614
615 if apclient._sunwarp_shuffle:
616 # Sunwarps 1 and 6 are rotated differently from the rest, so we have to fix that.
617 get_node("Decorations/Teleporter Windows/localmap").rotation_degrees.y = 0
618 get_node("Decorations/Teleporter Windows/localmap2").rotation_degrees.y = 0
619 get_node("Decorations/Teleporter Windows/localmap11").rotation_degrees.y = 0
620 get_node("Decorations/Teleporter Windows/localmap12").rotation_degrees.y = 0
621 get_node("Decorations/Teleporter Windows/localmap13").rotation_degrees.y = -90
622
623 get_node("Warps/Teleporter Warps/Sunwarp_enter_1").translation.x = 19.5
624 get_node("Warps/Teleporter Warps/Sunwarp_exit_1").translation.x = -15.5
625 get_node("Warps/Teleporter Warps/Sunwarp_enter_6").translation.x = 4.5
626 get_node("Warps/Teleporter Warps/Sunwarp_exit_6").translation.x = -37.5
627 get_node("Warps/Teleporter Warps/Sunwarp_exit_7").translation.z = 23.5
628
629 # Change the sunwarps in accordance with the mapping.
630 var sw_orig_translations = []
631 var sw_text_translations = []
632 var sw_text_rotations = []
633 for i in range(1,7):
634 sw_orig_translations.append(get_node("Warps/Teleporter Warps/Sunwarp_enter_%d" % i).translation)
635 sw_text_translations.append(get_node("Decorations/Signs/Sunwarp Numbers/enter_%d" % i).translation)
636 sw_text_rotations.append(get_node("Decorations/Signs/Sunwarp Numbers/enter_%d" % i).rotation_degrees)
637 for i in range(1,7):
638 sw_orig_translations.append(get_node("Warps/Teleporter Warps/Sunwarp_exit_%d" % i).translation)
639 sw_text_translations.append(get_node("Decorations/Signs/Sunwarp Numbers/exit_%d" % i).translation)
640 sw_text_rotations.append(get_node("Decorations/Signs/Sunwarp Numbers/exit_%d" % i).rotation_degrees)
641
642 var sw_enter_indicators = [4, 5, 6, 12, 7, 10]
643 for i in range(1,7):
644 get_node("Warps/Teleporter Warps/Sunwarp_enter_%d" % i).translation = sw_orig_translations[apclient._sunwarp_mapping[i-1]]
645 get_node("Warps/Teleporter Warps/Sunwarp_exit_%d" % i).translation = sw_orig_translations[apclient._sunwarp_mapping[i+5]]
646
647 get_node("Decorations/Signs/Sunwarp Numbers/enter_%d" % i).translation = sw_text_translations[apclient._sunwarp_mapping[i-1]]
648 get_node("Decorations/Signs/Sunwarp Numbers/enter_%d" % i).rotation_degrees = sw_text_rotations[apclient._sunwarp_mapping[i-1]]
649
650 get_node("Decorations/Signs/Sunwarp Numbers/exit_%d" % i).translation = sw_text_translations[apclient._sunwarp_mapping[i+5]]
651 get_node("Decorations/Signs/Sunwarp Numbers/exit_%d" % i).rotation_degrees = sw_text_rotations[apclient._sunwarp_mapping[i+5]]
652
653 var enter_rot = _dir_to_int(gamedata.sunwarps[apclient._sunwarp_mapping[i-1]]["orientation"]) * 90
654 var exit_rot = _dir_to_int(gamedata.sunwarps[apclient._sunwarp_mapping[i+5]]["orientation"]) * 90
655 var final_rot = enter_rot - exit_rot
656 if final_rot < 0:
657 final_rot += 360
658 get_node("Warps/Teleporter Warps/Sunwarp_enter_%d" % i).rotate = str(final_rot)
659
660 var sw_enter_indicator_pos = gamedata.sunwarps[apclient._sunwarp_mapping[i-1]]["entrance_indicator_pos"]
661 var sw_enter_indicator = get_node("Decorations/Signs/Welcome Back Signs/Sign%d" % sw_enter_indicators[i-1])
662 sw_enter_indicator.translation.x = sw_enter_indicator_pos[0]
663 sw_enter_indicator.translation.y = sw_enter_indicator_pos[1]
664 sw_enter_indicator.translation.z = sw_enter_indicator_pos[2]
665 sw_enter_indicator.rotation_degrees.y = (enter_rot * -1) + 180
591 666
592 # Create the effects node. 667 # Create the effects node.
593 var effects_script = apclient.SCRIPT_effects 668 var effects_script = apclient.SCRIPT_effects
@@ -718,3 +793,15 @@ func set_small_gridmap_tile(x, y, z, tile):
718 793
719func archipelago_disconnected(reason): 794func archipelago_disconnected(reason):
720 messages.showMessage(reason) 795 messages.showMessage(reason)
796
797
798func _dir_to_int(dir):
799 if dir == "north":
800 return 0
801 elif dir == "west":
802 return 1
803 elif dir == "south":
804 return 2
805 elif dir == "east":
806 return 3
807 return 4
diff --git a/Archipelago/mypainting.gd b/Archipelago/mypainting.gd index 5e9c703..999b122 100644 --- a/Archipelago/mypainting.gd +++ b/Archipelago/mypainting.gd
@@ -86,6 +86,11 @@ func _looked_at(body, painting):
86 body.rotate_y(3 * PI / 2) 86 body.rotate_y(3 * PI / 2)
87 body.velocity = body.velocity.rotated(Vector3(0, 1, 0), 3 * PI / 2) 87 body.velocity = body.velocity.rotated(Vector3(0, 1, 0), 3 * PI / 2)
88 88
89 var apclient = global.get_node("Archipelago")
90 if !apclient._pilgrimage_allows_paintings:
91 global.sunwarp = 1
92 body.get_node("pivot/camera/sunwarp_background").visible = false
93
89 94
90func _dir_to_int(dir): 95func _dir_to_int(dir):
91 if dir == "north": 96 if dir == "north":
diff --git a/Archipelago/painting.gd b/Archipelago/painting.gd new file mode 100644 index 0000000..adc8337 --- /dev/null +++ b/Archipelago/painting.gd
@@ -0,0 +1,10 @@
1extends "res://scripts/painting.gd"
2
3func _looked_at(var body, var painting):
4 ._looked_at(body, painting)
5
6 if body.is_in_group("player") && (painting.get_name() == self.get_name()):
7 var apclient = global.get_node("Archipelago")
8 if !apclient._pilgrimage_allows_paintings:
9 global.sunwarp = 1
10 body.get_node("pivot/camera/sunwarp_background").visible = false
diff --git a/Archipelago/painting_eye.gd b/Archipelago/painting_eye.gd index 53d42b5..b2e6973 100644 --- a/Archipelago/painting_eye.gd +++ b/Archipelago/painting_eye.gd
@@ -3,9 +3,23 @@ extends "res://scripts/painting_eye.gd"
3 3
4func _answer_correct(): 4func _answer_correct():
5 var apclient = global.get_node("Archipelago") 5 var apclient = global.get_node("Archipelago")
6 if not apclient._door_shuffle or apclient.paintingIsVanilla(self.name): 6 if !apclient._pilgrimage_compatibility and get_name() == "pilgrim_painting2":
7 # When pilgrimage is enabled, the HOT CRUST panel should actually move the sun painting.
8 if apclient._pilgrimage_enabled:
9 movePainting()
10 elif not apclient._door_shuffle or apclient.paintingIsVanilla(self.name):
7 ._answer_correct() 11 ._answer_correct()
8 12
9 13
10func movePainting(): 14func movePainting():
11 ._answer_correct() 15 ._answer_correct()
16
17
18func _looked_at(var body, var painting):
19 ._looked_at(body, painting)
20
21 if body.is_in_group("player") && (painting.get_name() == self.get_name()):
22 var apclient = global.get_node("Archipelago")
23 if !apclient._pilgrimage_allows_paintings:
24 global.sunwarp = 1
25 body.get_node("pivot/camera/sunwarp_background").visible = false
diff --git a/Archipelago/painting_scenery.gd b/Archipelago/painting_scenery.gd index f49d602..1186e2f 100644 --- a/Archipelago/painting_scenery.gd +++ b/Archipelago/painting_scenery.gd
@@ -9,3 +9,13 @@ func _answer_correct():
9 9
10func movePainting(): 10func movePainting():
11 ._answer_correct() 11 ._answer_correct()
12
13
14func _looked_at(var body, var painting):
15 ._looked_at(body, painting)
16
17 if body.is_in_group("player") && (painting.get_name() == self.get_name()):
18 var apclient = global.get_node("Archipelago")
19 if !apclient._pilgrimage_allows_paintings:
20 global.sunwarp = 1
21 body.get_node("pivot/camera/sunwarp_background").visible = false
diff --git a/Archipelago/panel.gd b/Archipelago/panel.gd index aec18e8..fc5963a 100644 --- a/Archipelago/panel.gd +++ b/Archipelago/panel.gd
@@ -22,7 +22,7 @@ func _ready():
22 else: 22 else:
23 atbash_text += old_char 23 atbash_text += old_char
24 24
25 self.get_parent().get_node("Viewport/GUI/Panel/TextEdit").connect( 25 var _ignore = self.get_parent().get_node("Viewport/GUI/Panel/TextEdit").connect(
26 "answer_correct", self, "answer_correct" 26 "answer_correct", self, "answer_correct"
27 ) 27 )
28 28
diff --git a/Archipelago/pilgrimage_terminator.gd b/Archipelago/pilgrimage_terminator.gd new file mode 100644 index 0000000..29db2ee --- /dev/null +++ b/Archipelago/pilgrimage_terminator.gd
@@ -0,0 +1,11 @@
1extends Area
2
3
4func _ready():
5 var _connected = self.connect("body_entered", self, "_body_entered")
6
7
8func _body_entered(body):
9 if body.is_in_group("player"):
10 global.sunwarp = 1
11 body.get_node("pivot/camera/sunwarp_background").visible = false
diff --git a/Archipelago/settings_screen.gd b/Archipelago/settings_screen.gd index 453e3bf..79fdcc3 100644 --- a/Archipelago/settings_screen.gd +++ b/Archipelago/settings_screen.gd
@@ -30,6 +30,8 @@ func _ready():
30 apclient_instance.SCRIPT_mypainting = load("user://maps/Archipelago/mypainting.gd") 30 apclient_instance.SCRIPT_mypainting = load("user://maps/Archipelago/mypainting.gd")
31 apclient_instance.SCRIPT_notifier = load("user://maps/Archipelago/notifier.gd") 31 apclient_instance.SCRIPT_notifier = load("user://maps/Archipelago/notifier.gd")
32 apclient_instance.SCRIPT_panel = load("user://maps/Archipelago/panel.gd") 32 apclient_instance.SCRIPT_panel = load("user://maps/Archipelago/panel.gd")
33 var pilg_term = load("user://maps/Archipelago/pilgrimage_terminator.gd")
34 apclient_instance.SCRIPT_pilgrimage_terminator = pilg_term
33 apclient_instance.SCRIPT_uuid = load("user://maps/Archipelago/vendor/uuid.gd") 35 apclient_instance.SCRIPT_uuid = load("user://maps/Archipelago/vendor/uuid.gd")
34 36
35 var apdata = ResourceLoader.load("user://maps/Archipelago/gamedata.gd") 37 var apdata = ResourceLoader.load("user://maps/Archipelago/gamedata.gd")
@@ -45,6 +47,7 @@ func _ready():
45 # Let's also inject any scripts we need to inject now. 47 # Let's also inject any scripts we need to inject now.
46 installScriptExtension(apclient_instance.SCRIPT_doorControl) 48 installScriptExtension(apclient_instance.SCRIPT_doorControl)
47 installScriptExtension(ResourceLoader.load("user://maps/Archipelago/load.gd")) 49 installScriptExtension(ResourceLoader.load("user://maps/Archipelago/load.gd"))
50 installScriptExtension(ResourceLoader.load("user://maps/Archipelago/painting.gd"))
48 installScriptExtension(ResourceLoader.load("user://maps/Archipelago/painting_eye.gd")) 51 installScriptExtension(ResourceLoader.load("user://maps/Archipelago/painting_eye.gd"))
49 installScriptExtension(ResourceLoader.load("user://maps/Archipelago/painting_scenery.gd")) 52 installScriptExtension(ResourceLoader.load("user://maps/Archipelago/painting_scenery.gd"))
50 installScriptExtension(ResourceLoader.load("user://maps/Archipelago/panelLevelSwitch.gd")) 53 installScriptExtension(ResourceLoader.load("user://maps/Archipelago/panelLevelSwitch.gd"))
@@ -52,6 +55,7 @@ func _ready():
52 installScriptExtension(ResourceLoader.load("user://maps/Archipelago/panelInput.gd")) 55 installScriptExtension(ResourceLoader.load("user://maps/Archipelago/panelInput.gd"))
53 installScriptExtension(ResourceLoader.load("user://maps/Archipelago/pause_menu.gd")) 56 installScriptExtension(ResourceLoader.load("user://maps/Archipelago/pause_menu.gd"))
54 installScriptExtension(ResourceLoader.load("user://maps/Archipelago/player.gd")) 57 installScriptExtension(ResourceLoader.load("user://maps/Archipelago/player.gd"))
58 installScriptExtension(ResourceLoader.load("user://maps/Archipelago/teleport.gd"))
55 installScriptExtension(ResourceLoader.load("user://maps/Archipelago/worldTransporter.gd")) 59 installScriptExtension(ResourceLoader.load("user://maps/Archipelago/worldTransporter.gd"))
56 60
57 var apclient = global.get_node("Archipelago") 61 var apclient = global.get_node("Archipelago")
diff --git a/Archipelago/teleport.gd b/Archipelago/teleport.gd new file mode 100644 index 0000000..532f081 --- /dev/null +++ b/Archipelago/teleport.gd
@@ -0,0 +1,27 @@
1extends "res://scripts/teleport.gd"
2
3var _unlocked = true
4
5
6func _ready():
7 var apclient = global.get_node("Archipelago")
8 if self.get_parent().name == "Teleporter Warps":
9 if apclient._sunwarp_access != apclient.kSUNWARP_ACCESS_NORMAL:
10 _unlocked = false
11 elif apclient._door_shuffle and !apclient.warpIsVanilla(self.get_parent().name + "/" + self.name):
12 _unlocked = false
13
14
15func _body_entered(body):
16 if _unlocked:
17 ._body_entered(body)
18
19 if body.is_in_group("player"):
20 var apclient = global.get_node("Archipelago")
21 if !apclient._pilgrimage_enabled:
22 global.sunwarp = 1
23 body.get_node("pivot/camera/sunwarp_background").visible = false
24
25
26func unlock_warp():
27 _unlocked = true
diff --git a/CHANGELOG.md b/CHANGELOG.md index d5fc54d..de47cb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md
@@ -1,5 +1,35 @@
1# lingo-archipelago Releases 1# lingo-archipelago Releases
2 2
3## v3.0.1 - 2024-04-22
4
5- Fixed issue where Progressive Hallway Room did not work properly on worlds
6 generated on Archipelago 0.4.5 or earlier.
7
8Download:
9[lingo-archipelago-v3.0.1.zip](https://files.fourisland.com/releases/lingo-archipelago/lingo-archipelago-v3.0.1.zip)<br/>
10Source: [v3.0.1](https://code.fourisland.com/lingo-archipelago/tag/?h=v3.0.1)
11
12## v3.0.0 - 2024-04-22
13
14- [Archipelago 0.4.6](https://github.com/ArchipelagoMW/Archipelago/releases/tag/0.4.6)
15 has been released! This includes a major update for Lingo: The Pilgrim Update!
16 - The pilgrimage can now be disabled entirely.
17 - When enabled, the pilgrimage uses real logic to determine whether it is
18 possible, rather than a specific route.
19 - You can now specify whether paintings and/or roof access are allowed for the
20 pilgrimage.
21 - You can lock access to sunwarps behind item keys, like door shuffle.
22 - Sunwarps can be shuffled, similar to painting shuffle.
23 - Pilgrimage has been added as a win condition.
24- This update should retain backwards compatibility with Archipelago 0.4.5
25 worlds. World generated in Archipelago 0.4.4 will likely continue to have
26 minor problems, and it is best to downpatch to v1.2.1 if you need to play an
27 older world.
28
29Download:
30[lingo-archipelago-v3.0.0.zip](https://files.fourisland.com/releases/lingo-archipelago/lingo-archipelago-v3.0.0.zip)<br/>
31Source: [v3.0.0](https://code.fourisland.com/lingo-archipelago/tag/?h=v3.0.0)
32
3## v2.2.0 - 2024-04-17 33## v2.2.0 - 2024-04-17
4 34
5- The last ten connections are now saved in a list so that you can easily switch 35- The last ten connections are now saved in a list so that you can easily switch
diff --git a/README.md b/README.md index 68580e8..a242f95 100644 --- a/README.md +++ b/README.md
@@ -87,6 +87,10 @@ pick and choose which ones you would like to use.
87- **Painting shuffle**: This randomizes the appearance of the paintings in the 87- **Painting shuffle**: This randomizes the appearance of the paintings in the
88 game, as well as which of them are warps, and the locations that they warp you 88 game, as well as which of them are warps, and the locations that they warp you
89 to. It is the equivalent of an entrance randomizer in another game. 89 to. It is the equivalent of an entrance randomizer in another game.
90- **Sunwarp shuffle**: This randomizes the six pairs of sunwarps. The pairing of
91 the warps can change, whether a warp is an entrance or an exit can change, and
92 the numbering can change. You can also specify whether access to the sunwarps
93 should be locked behind receiving certain items.
90 94
91## Frequently Asked Questions 95## Frequently Asked Questions
92 96
@@ -155,33 +159,31 @@ to WELCOME BACK.
155 159
156### What about the pilgrimage? 160### What about the pilgrimage?
157 161
158The intended method of reaching the Pilgrim Room in the base game is known as 162You can enable or disable the pilgrimage in the world options. It defaults to
159"doing a pilgrimage". It involves entering each sunwarp in order without using 163disabled. When disabled, it is impossible to perform a pilgrimage (although the
160any non-painting warps in between. This is difficult to map out properly in AP 164sunwarps will still work, as long as you haven't disabled them too). The Sun
161logic, so we only consider one specific path through the map to be the canonical 165Painting will be added to the item pool, even if you do not have door shuffle
162pilgrimage route. Accessing the Pilgrim Room by pilgrimage is only in logic if 166on, so that you can still access the Pilgrim Antechamber.
163this specific route is available to you: 167
164 168When the pilgrimage is enabled, you are required to perform a pilgrimage in
165- From the Starting Room, proceed through the Second Room and into the Hub Room. 169order to access the Pilgrim Antechamber (although the Pilgrim Room itself may
166 Enter the first sunwarp. 170still be accessible through The Seeker if you have door shuffle on). The Sun
167- From the Crossroads, use the front tower entrance (the one nearest The 171Painting will not be added to the pool, and will behave as it does in vanilla
168 Discerning; not the one next to Sword/Words). Go through the Hot Crusts Door 172(in that it only moves when you solve HOT CRUST inside the Pilgrim Antechamber).
169 and enter the second sunwarp. 173It is non-trivial to determine whether you are able to perform a pilgrimage at
170- Enter the third sunwarp immediately after. 174any given state, but logic will expect you to be able to figure this out. There
171- Proceed past The Initiated and through the shortcut door back to the Hub Room. 175are options that let you determine whether or not paintings and/or the roof
172 Go through the shortcut door to the tower's first floor and enter the fourth 176access stairs in Crossroads will disable a pilgrimage. When sunwarps are
173 sunwarp. 177shuffled, your pilgrimage must take the new numbering of the warps into
174- Use the shortcut to the Directional Gallery (the one outside The Undeterred; 178consideration. The tracker is able to tell you whether or not the Pilgrim
175 not the one further down the hallway where the Number Hunt is), pass through 179Antechamber is accessible (as long as there is an otherwise accessible check
176 the Salt Pepper Door, and return to the Hub Room. Use the nearby entrance to 180inside it), but it can't tell you what your pilgrimage path should be. If you
177 the Crossroads and proceed to the fifth sunwarp. 181are lost, you can check your world's spoiler log for direction on the pilgrimage
178- Use the door that takes you to The Steady, and then the one that takes you to 182path to take.
179 The Bearer, and then the one that takes you to The Initiated. Return to the 183
180 Hub Room once more, and enter The Tenacious via the shortcut that opens upon 184In previous versions of the randomizer, there was a "canonical pilgrimage" that
181 solving the palindromes. Use the top-right door to access the area Outside the 185involved following a specific path in order to reach the Pilgrim Antechamber.
182 Agreeable, and enter the final sunwarp. 186This is no longer relevant, because all possible pilgrimage paths are now in
183 187logic, but you can still see the old route
184This route can be seen 188[starting at 2:47 in this video](https://youtu.be/8GfuDRRswdA?t=167) for
185[starting at 2:47 in this video](https://youtu.be/8GfuDRRswdA?t=167). Note that 189reference.
186this will almost never be required if door shuffle is enabled, as one of the
187other entrances to the room will usually be available sooner.
diff --git a/util/generate_gamedata.rb b/util/generate_gamedata.rb index 3f610b1..ce8df43 100644 --- a/util/generate_gamedata.rb +++ b/util/generate_gamedata.rb
@@ -12,15 +12,20 @@ CLASSIFICATION_SMALL_SPHERE_ONE = 8
12 12
13panel_to_id = {} 13panel_to_id = {}
14door_groups = {} 14door_groups = {}
15warp_groups = {}
15 16
16panel_output = [] 17panel_output = []
17door_ids_by_item_id = {} 18door_ids_by_item_id = {}
18painting_ids_by_item_id = {} 19painting_ids_by_item_id = {}
20warp_ids_by_item_id = {}
19panel_ids_by_location_id = {} 21panel_ids_by_location_id = {}
20classification_by_location_id = {} 22classification_by_location_id = {}
23sunwarps = Array.new(12) {Hash.new}
21mentioned_doors = Set[] 24mentioned_doors = Set[]
22mentioned_paintings = Set[] 25mentioned_paintings = Set[]
26mentioned_warps = Set[]
23painting_output = {} 27painting_output = {}
28items_by_progressive_id = {}
24 29
25ids_config = YAML.load_file(idspath) 30ids_config = YAML.load_file(idspath)
26 31
@@ -93,6 +98,30 @@ config.each do |room_name, room_data|
93 painting_output[painting["id"]] = painting 98 painting_output[painting["id"]] = painting
94 end 99 end
95 end 100 end
101
102 if room_data.include? "sunwarps"
103 room_data["sunwarps"].each do |sunwarp|
104 index = sunwarp["dots"] - 1
105 if sunwarp["direction"] == "exit" then
106 index += 6
107 end
108 sunwarps[index] = sunwarp
109 end
110 end
111
112 if room_data.include? "progression"
113 room_data["progression"].each do |progressive_item_name, progression|
114 progressive_id = ids_config["progression"][progressive_item_name]
115 items_by_progressive_id[progressive_id] = []
116
117 progression.each do |item|
118 item_room_name = (item.kind_of? Hash) ? item["room"] : room_name
119 item_item_name = (item.kind_of? Hash) ? item["door"] : item
120
121 items_by_progressive_id[progressive_id] << ids_config["doors"][item_room_name][item_item_name]["item"]
122 end
123 end
124 end
96end 125end
97 126
98config.each do |room_name, room_data| 127config.each do |room_name, room_data|
@@ -157,6 +186,23 @@ config.each do |room_name, room_data|
157 painting_ids_by_item_id[item_id] = internal_painting_ids 186 painting_ids_by_item_id[item_id] = internal_painting_ids
158 mentioned_paintings.merge(internal_painting_ids) 187 mentioned_paintings.merge(internal_painting_ids)
159 end 188 end
189
190 if door.include? "warp_id"
191 internal_warp_ids = []
192 if door["warp_id"].kind_of? String
193 internal_warp_ids = [door["warp_id"]]
194 else
195 internal_warp_ids = door["warp_id"]
196 end
197
198 if door.include? "door_group"
199 warp_groups[door["door_group"]] ||= Set[]
200 warp_groups[door["door_group"]].merge(internal_warp_ids)
201 end
202
203 warp_ids_by_item_id[item_id] = internal_warp_ids
204 mentioned_warps.merge(internal_warp_ids)
205 end
160 end 206 end
161 end 207 end
162 end 208 end
@@ -167,6 +213,11 @@ door_groups.each do |group_name, door_ids|
167 door_ids_by_item_id[item_id] = door_ids.to_a 213 door_ids_by_item_id[item_id] = door_ids.to_a
168end 214end
169 215
216warp_groups.each do |group_name, warp_ids|
217 item_id = ids_config["door_groups"][group_name]
218 warp_ids_by_item_id[item_id] = warp_ids.to_a
219end
220
170File.open(outputpath, "w") do |f| 221File.open(outputpath, "w") do |f|
171 f.write "extends Node\n\nvar panels = [" 222 f.write "extends Node\n\nvar panels = ["
172 f.write(panel_output.map do |panel| 223 f.write(panel_output.map do |panel|
@@ -186,6 +237,12 @@ File.open(outputpath, "w") do |f|
186 "\"#{painting_id}\"" 237 "\"#{painting_id}\""
187 end.join(",") + "]" 238 end.join(",") + "]"
188 end.join(",")) 239 end.join(","))
240 f.write "}\nvar warp_ids_by_item_id = {"
241 f.write(warp_ids_by_item_id.map do |item_id, warp_ids|
242 "#{item_id}:[" + warp_ids.map do |warp_id|
243 "\"#{warp_id}\""
244 end.join(",") + "]"
245 end.join(","))
189 f.write "}\nvar panel_ids_by_location_id = {" 246 f.write "}\nvar panel_ids_by_location_id = {"
190 f.write(panel_ids_by_location_id.map do |location_id, panel_ids| 247 f.write(panel_ids_by_location_id.map do |location_id, panel_ids|
191 "#{location_id}:[" + panel_ids.map do |panel_id| 248 "#{location_id}:[" + panel_ids.map do |panel_id|
@@ -200,6 +257,10 @@ File.open(outputpath, "w") do |f|
200 f.write(mentioned_paintings.map do |painting_id| 257 f.write(mentioned_paintings.map do |painting_id|
201 "\"#{painting_id}\"" 258 "\"#{painting_id}\""
202 end.join(",")) 259 end.join(","))
260 f.write "]\nvar mentioned_warps = ["
261 f.write(mentioned_warps.map do |warp_id|
262 "\"#{warp_id}\""
263 end.join(","))
203 f.write "]\nvar paintings = {" 264 f.write "]\nvar paintings = {"
204 f.write(painting_output.map do |painting_id, painting| 265 f.write(painting_output.map do |painting_id, painting|
205 "\"#{painting_id}\":{\"orientation\":\"#{painting["orientation"]}\",\"move\":#{painting.include? "move" and painting["move"]}}" 266 "\"#{painting_id}\":{\"orientation\":\"#{painting["orientation"]}\",\"move\":#{painting.include? "move" and painting["move"]}}"
@@ -208,5 +269,13 @@ File.open(outputpath, "w") do |f|
208 f.write(classification_by_location_id.map do |location_id, classification| 269 f.write(classification_by_location_id.map do |location_id, classification|
209 "#{location_id}:#{classification}" 270 "#{location_id}:#{classification}"
210 end.join(",")) 271 end.join(","))
272 f.write "}\nvar sunwarps = ["
273 f.write(sunwarps.map do |sunwarp|
274 "{\"orientation\":\"#{sunwarp["orientation"]}\",\"entrance_indicator_pos\":#{sunwarp["entrance_indicator_pos"].to_s}}"
275 end.join(","))
276 f.write "]\nvar items_by_progressive_id = {"
277 f.write(items_by_progressive_id.map do |item_id, progression_ids|
278 "#{item_id}:[" + progression_ids.map(&:to_s).join(",") + "]"
279 end.join(","))
211 f.write "}" 280 f.write "}"
212end 281end