diff options
Diffstat (limited to 'apworld')
| -rw-r--r-- | apworld/__init__.py | 4 | ||||
| -rw-r--r-- | apworld/client/gamedata.gd | 8 | ||||
| -rw-r--r-- | apworld/client/manager.gd | 18 | ||||
| -rw-r--r-- | apworld/client/maps/control_center.gd | 22 | ||||
| -rw-r--r-- | apworld/client/player.gd | 29 | ||||
| -rw-r--r-- | apworld/client/rteMenu.gd | 55 | ||||
| -rw-r--r-- | apworld/tracker.py | 4 |
7 files changed, 139 insertions, 1 deletions
| diff --git a/apworld/__init__.py b/apworld/__init__.py index ff1da66..42350bc 100644 --- a/apworld/__init__.py +++ b/apworld/__init__.py | |||
| @@ -71,6 +71,10 @@ class Lingo2World(World): | |||
| 71 | self.port_pairings = {} | 71 | self.port_pairings = {} |
| 72 | 72 | ||
| 73 | def create_regions(self): | 73 | def create_regions(self): |
| 74 | if hasattr(self.multiworld, "re_gen_passthrough") and "Lingo 2" in self.multiworld.re_gen_passthrough: | ||
| 75 | self.player_logic.rte_mapping = [self.world.static_logic.map_id_by_name[map_name] | ||
| 76 | for map_name in self.multiworld.re_gen_passthrough["Lingo 2"]["rte"]] | ||
| 77 | |||
| 74 | create_regions(self) | 78 | create_regions(self) |
| 75 | 79 | ||
| 76 | def connect_entrances(self): | 80 | def connect_entrances(self): |
| diff --git a/apworld/client/gamedata.gd b/apworld/client/gamedata.gd index d7e3136..373f981 100644 --- a/apworld/client/gamedata.gd +++ b/apworld/client/gamedata.gd | |||
| @@ -16,6 +16,7 @@ var anti_trap_ids = {} | |||
| 16 | var location_name_by_id = {} | 16 | var location_name_by_id = {} |
| 17 | var ending_display_name_by_name = {} | 17 | var ending_display_name_by_name = {} |
| 18 | var port_id_by_ap_id = {} | 18 | var port_id_by_ap_id = {} |
| 19 | var map_id_by_rte_ap_id = {} | ||
| 19 | 20 | ||
| 20 | var kSYMBOL_ITEMS | 21 | var kSYMBOL_ITEMS |
| 21 | 22 | ||
| @@ -57,6 +58,9 @@ func load(data_bytes): | |||
| 57 | for map in objects.get_maps(): | 58 | for map in objects.get_maps(): |
| 58 | map_id_by_name[map.get_name()] = map.get_id() | 59 | map_id_by_name[map.get_name()] = map.get_id() |
| 59 | 60 | ||
| 61 | if map.has_rte_ap_id(): | ||
| 62 | map_id_by_rte_ap_id[map.get_rte_ap_id()] = map.get_id() | ||
| 63 | |||
| 60 | for door in objects.get_doors(): | 64 | for door in objects.get_doors(): |
| 61 | var map = objects.get_maps()[door.get_map_id()] | 65 | var map = objects.get_maps()[door.get_map_id()] |
| 62 | 66 | ||
| @@ -300,3 +304,7 @@ func _get_keyholder_location_name(keyholder): | |||
| 300 | "%s - %s Keyholder" | 304 | "%s - %s Keyholder" |
| 301 | % [_get_room_object_location_prefix(keyholder), keyholder.get_key().to_upper()] | 305 | % [_get_room_object_location_prefix(keyholder), keyholder.get_key().to_upper()] |
| 302 | ) | 306 | ) |
| 307 | |||
| 308 | |||
| 309 | func vec3d_to_vector3(input) -> Vector3: | ||
| 310 | return Vector3(input.get_x(), input.get_y(), input.get_z()) | ||
| diff --git a/apworld/client/manager.gd b/apworld/client/manager.gd index 1e0b549..00f03ea 100644 --- a/apworld/client/manager.gd +++ b/apworld/client/manager.gd | |||
| @@ -46,6 +46,10 @@ const kCYAN_DOOR_BEHAVIOR_H2 = 0 | |||
| 46 | const kCYAN_DOOR_BEHAVIOR_DOUBLE_LETTER = 1 | 46 | const kCYAN_DOOR_BEHAVIOR_DOUBLE_LETTER = 1 |
| 47 | const kCYAN_DOOR_BEHAVIOR_ITEM = 2 | 47 | const kCYAN_DOOR_BEHAVIOR_ITEM = 2 |
| 48 | 48 | ||
| 49 | const kFAST_TRAVEL_ACCESS_VANILLA = 0 | ||
| 50 | const kFAST_TRAVEL_ACCESS_UNLOCKED = 1 | ||
| 51 | const kFAST_TRAVEL_ACCESS_ITEMS = 2 | ||
| 52 | |||
| 49 | const kEndingNameByVictoryValue = { | 53 | const kEndingNameByVictoryValue = { |
| 50 | 0: "GRAY", | 54 | 0: "GRAY", |
| 51 | 1: "PURPLE", | 55 | 1: "PURPLE", |
| @@ -69,9 +73,11 @@ var daedalus_roof_access = false | |||
| 69 | var enable_gift_maps = [] | 73 | var enable_gift_maps = [] |
| 70 | var enable_icarus = false | 74 | var enable_icarus = false |
| 71 | var endings_requirement = 0 | 75 | var endings_requirement = 0 |
| 76 | var fast_travel_access = 0 | ||
| 72 | var keyholder_sanity = false | 77 | var keyholder_sanity = false |
| 73 | var masteries_requirement = 0 | 78 | var masteries_requirement = 0 |
| 74 | var port_pairings = {} | 79 | var port_pairings = {} |
| 80 | var rte_mapping = [] | ||
| 75 | var shuffle_control_center_colors = false | 81 | var shuffle_control_center_colors = false |
| 76 | var shuffle_doors = false | 82 | var shuffle_doors = false |
| 77 | var shuffle_gallery_paintings = false | 83 | var shuffle_gallery_paintings = false |
| @@ -269,6 +275,13 @@ func _process_item(item, amount): | |||
| 269 | if item_id == gamedata.objects.get_special_ids()["Numbers"] and global.map == "the_fuzzy": | 275 | if item_id == gamedata.objects.get_special_ids()["Numbers"] and global.map == "the_fuzzy": |
| 270 | global.allow_numbers = true | 276 | global.allow_numbers = true |
| 271 | 277 | ||
| 278 | if gamedata.map_id_by_rte_ap_id.has(item_id): | ||
| 279 | var rteInner = get_tree().get_root().get_node_or_null( | ||
| 280 | "scene/player/pause_menu/menu/return/rteInner" | ||
| 281 | ) | ||
| 282 | if rteInner != null: | ||
| 283 | rteInner.refreshButtons() | ||
| 284 | |||
| 272 | # Show a message about the item if it's new. | 285 | # Show a message about the item if it's new. |
| 273 | if int(item["index"]) > _last_new_item: | 286 | if int(item["index"]) > _last_new_item: |
| 274 | _last_new_item = int(item["index"]) | 287 | _last_new_item = int(item["index"]) |
| @@ -469,6 +482,7 @@ func _client_connected(slot_data): | |||
| 469 | enable_gift_maps = slot_data.get("enable_gift_maps", []) | 482 | enable_gift_maps = slot_data.get("enable_gift_maps", []) |
| 470 | enable_icarus = bool(slot_data.get("enable_icarus", false)) | 483 | enable_icarus = bool(slot_data.get("enable_icarus", false)) |
| 471 | endings_requirement = int(slot_data.get("endings_requirement", 0)) | 484 | endings_requirement = int(slot_data.get("endings_requirement", 0)) |
| 485 | fast_travel_access = int(slot_data.get("fast_travel_access", 0)) | ||
| 472 | keyholder_sanity = bool(slot_data.get("keyholder_sanity", false)) | 486 | keyholder_sanity = bool(slot_data.get("keyholder_sanity", false)) |
| 473 | masteries_requirement = int(slot_data.get("masteries_requirement", 0)) | 487 | masteries_requirement = int(slot_data.get("masteries_requirement", 0)) |
| 474 | shuffle_control_center_colors = bool(slot_data.get("shuffle_control_center_colors", false)) | 488 | shuffle_control_center_colors = bool(slot_data.get("shuffle_control_center_colors", false)) |
| @@ -496,6 +510,10 @@ func _client_connected(slot_data): | |||
| 496 | raw_pp[p1] | 510 | raw_pp[p1] |
| 497 | )] | 511 | )] |
| 498 | 512 | ||
| 513 | rte_mapping.clear() | ||
| 514 | if slot_data.has("rte"): | ||
| 515 | rte_mapping = slot_data.get("rte") | ||
| 516 | |||
| 499 | # Set up item locks. | 517 | # Set up item locks. |
| 500 | _item_locks = {} | 518 | _item_locks = {} |
| 501 | 519 | ||
| diff --git a/apworld/client/maps/control_center.gd b/apworld/client/maps/control_center.gd index fadfed9..92999d3 100644 --- a/apworld/client/maps/control_center.gd +++ b/apworld/client/maps/control_center.gd | |||
| @@ -74,6 +74,28 @@ func on_map_load(root): | |||
| 74 | old_door.queue_free() | 74 | old_door.queue_free() |
| 75 | root.get_node("/root/scene/Components/Doors").add_child.call_deferred(new_door) | 75 | root.get_node("/root/scene/Components/Doors").add_child.call_deferred(new_door) |
| 76 | 76 | ||
| 77 | # Display White Ending requirements. | ||
| 78 | var ending_count = 0 | ||
| 79 | var mastery_count = 0 | ||
| 80 | for key in unlocks.data: | ||
| 81 | if unlocks.data[key] == "unlocked": | ||
| 82 | if key.ends_with("_ending"): | ||
| 83 | ending_count += 1 | ||
| 84 | elif key.ends_with("_mastery"): | ||
| 85 | mastery_count += 1 | ||
| 86 | |||
| 87 | var sign_prefab = preload("res://objects/nodes/sign.tscn") | ||
| 88 | var sign1 = sign_prefab.instantiate() | ||
| 89 | sign1.position = Vector3(87.5, 5, -42.01) | ||
| 90 | sign1.text = "Endings: %d/%d" % [ending_count, ap.endings_requirement] | ||
| 91 | root.get_node("/root/scene").add_child.call_deferred(sign1) | ||
| 92 | |||
| 93 | var sign2 = sign_prefab.instantiate() | ||
| 94 | sign2.position = Vector3(87.5, 5, -15.99) | ||
| 95 | sign2.rotation_degrees.y = 180 | ||
| 96 | sign2.text = "Masteries: %d/%d" % [mastery_count, ap.masteries_requirement] | ||
| 97 | root.get_node("/root/scene").add_child.call_deferred(sign2) | ||
| 98 | |||
| 77 | 99 | ||
| 78 | func _set_up_mastery_listener(root, name): | 100 | func _set_up_mastery_listener(root, name): |
| 79 | var prefab = preload("res://objects/nodes/listeners/unlockReaderListener.tscn") | 101 | var prefab = preload("res://objects/nodes/listeners/unlockReaderListener.tscn") |
| diff --git a/apworld/client/player.gd b/apworld/client/player.gd index 5fac9fd..95c05d7 100644 --- a/apworld/client/player.gd +++ b/apworld/client/player.gd | |||
| @@ -13,6 +13,8 @@ func _ready(): | |||
| 13 | 13 | ||
| 14 | var ap = global.get_node("Archipelago") | 14 | var ap = global.get_node("Archipelago") |
| 15 | var gamedata = global.get_node("Gamedata") | 15 | var gamedata = global.get_node("Gamedata") |
| 16 | var map_id = gamedata.map_id_by_name.get(global.map) | ||
| 17 | var map_data = gamedata.objects.get_maps()[map_id] | ||
| 16 | 18 | ||
| 17 | compass = global.get_node("Compass") | 19 | compass = global.get_node("Compass") |
| 18 | compass.visible = ap.show_compass | 20 | compass.visible = ap.show_compass |
| @@ -26,8 +28,33 @@ func _ready(): | |||
| 26 | 28 | ||
| 27 | ap.update_job_well_done_sign() | 29 | ap.update_job_well_done_sign() |
| 28 | 30 | ||
| 31 | # Set up the RTE trigger, if there is one. | ||
| 32 | if map_data.has_rte_trigger_pos(): | ||
| 33 | var oneShotListener_prefab = preload("res://objects/nodes/listeners/oneShotListener.tscn") | ||
| 34 | var triggerArea_prefab = preload("res://objects/nodes/triggerArea.tscn") | ||
| 35 | var unlockSetterListener_prefab = preload( | ||
| 36 | "res://objects/nodes/listeners/unlockSetterListener.tscn" | ||
| 37 | ) | ||
| 38 | |||
| 39 | var triggerArea = triggerArea_prefab.instantiate() | ||
| 40 | triggerArea.name = "rte_triggerArea" | ||
| 41 | triggerArea.position = gamedata.vec3d_to_vector3(map_data.get_rte_trigger_pos()) | ||
| 42 | triggerArea.scale = gamedata.vec3d_to_vector3(map_data.get_rte_trigger_scale()) | ||
| 43 | get_parent().add_child.call_deferred(triggerArea) | ||
| 44 | |||
| 45 | var osl = oneShotListener_prefab.instantiate() | ||
| 46 | osl.name = "rte_osl" | ||
| 47 | osl.senders.append(NodePath("/root/scene/rte_triggerArea")) | ||
| 48 | get_parent().add_child.call_deferred(osl) | ||
| 49 | |||
| 50 | var usl = unlockSetterListener_prefab.instantiate() | ||
| 51 | usl.name = "rte_usl" | ||
| 52 | usl.key = "rte_%s" % global.map | ||
| 53 | usl.value = "unlocked" | ||
| 54 | usl.senders.append(NodePath("/root/scene/rte_osl")) | ||
| 55 | get_parent().add_child.call_deferred(usl) | ||
| 56 | |||
| 29 | # Set up door locations. | 57 | # Set up door locations. |
| 30 | var map_id = gamedata.map_id_by_name.get(global.map) | ||
| 31 | for door in gamedata.objects.get_doors(): | 58 | for door in gamedata.objects.get_doors(): |
| 32 | if door.get_map_id() != map_id: | 59 | if door.get_map_id() != map_id: |
| 33 | continue | 60 | continue |
| diff --git a/apworld/client/rteMenu.gd b/apworld/client/rteMenu.gd index 5882d77..519f09f 100644 --- a/apworld/client/rteMenu.gd +++ b/apworld/client/rteMenu.gd | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | extends "res://scripts/ui/rteMenu.gd" | 1 | extends "res://scripts/ui/rteMenu.gd" |
| 2 | 2 | ||
| 3 | var buttons = [] | ||
| 4 | |||
| 3 | 5 | ||
| 4 | func _readier(): | 6 | func _readier(): |
| 5 | var ap = global.get_node("Archipelago") | 7 | var ap = global.get_node("Archipelago") |
| @@ -8,5 +10,58 @@ func _readier(): | |||
| 8 | get_node("rte_daedalus").show() | 10 | get_node("rte_daedalus").show() |
| 9 | 11 | ||
| 10 | switcher.preload_map("res://objects/scenes/daedalus.tscn") | 12 | switcher.preload_map("res://objects/scenes/daedalus.tscn") |
| 13 | elif !ap.rte_mapping.is_empty(): | ||
| 14 | buttons = [$rte_the_plaza, $rte_the_gallery, $rte_daedalus, $rte_control_center] | ||
| 15 | for i in range(4): | ||
| 16 | buttons[i].name = "button_%d" % i | ||
| 17 | for i in range(4): | ||
| 18 | _setupButton(buttons[i], ap.rte_mapping[i]) | ||
| 19 | |||
| 20 | refreshButtons() | ||
| 11 | else: | 21 | else: |
| 12 | super()._readier() | 22 | super()._readier() |
| 23 | |||
| 24 | |||
| 25 | func _setupButton(button, map_name): | ||
| 26 | switcher.preload_map("res://objects/scenes/%s.tscn" % map_name) | ||
| 27 | |||
| 28 | button.hide() | ||
| 29 | button.text = map_name.replace("_", " ") | ||
| 30 | button.name = "rte_%s" % map_name | ||
| 31 | button.autowrap_mode = TextServer.AUTOWRAP_WORD | ||
| 32 | |||
| 33 | var ap = global.get_node("Archipelago") | ||
| 34 | if ( | ||
| 35 | ap.fast_travel_access == ap.kFAST_TRAVEL_ACCESS_VANILLA | ||
| 36 | and !unlocks.data.has("rte_%s" % map_name) | ||
| 37 | ): | ||
| 38 | unlocks.data["rte_%s" % map_name] = "" | ||
| 39 | |||
| 40 | |||
| 41 | func refreshButtons(): | ||
| 42 | var ap = global.get_node("Archipelago") | ||
| 43 | if ap.rte_mapping.is_empty(): | ||
| 44 | return | ||
| 45 | |||
| 46 | for i in range(4): | ||
| 47 | if _shouldShowButton(ap.rte_mapping[i]): | ||
| 48 | buttons[i].show() | ||
| 49 | else: | ||
| 50 | buttons[i].hide() | ||
| 51 | |||
| 52 | |||
| 53 | func _shouldShowButton(map_name): | ||
| 54 | var ap = global.get_node("Archipelago") | ||
| 55 | |||
| 56 | if ap.fast_travel_access == ap.kFAST_TRAVEL_ACCESS_VANILLA: | ||
| 57 | return unlocks.data["rte_%s" % map_name] == "unlocked" | ||
| 58 | elif ap.fast_travel_access == ap.kFAST_TRAVEL_ACCESS_UNLOCKED: | ||
| 59 | return true | ||
| 60 | elif ap.fast_travel_access == ap.kFAST_TRAVEL_ACCESS_ITEMS: | ||
| 61 | var gamedata = global.get_node("Gamedata") | ||
| 62 | var map_id = gamedata.map_id_by_name[map_name] | ||
| 63 | var rte_ap_id = gamedata.objects.get_maps()[map_id].get_rte_ap_id() | ||
| 64 | |||
| 65 | return ap.client.hasItem(rte_ap_id) | ||
| 66 | |||
| 67 | return false | ||
| diff --git a/apworld/tracker.py b/apworld/tracker.py index a84c3f8..3e1cafb 100644 --- a/apworld/tracker.py +++ b/apworld/tracker.py | |||
| @@ -44,6 +44,10 @@ class Tracker: | |||
| 44 | for k, t in Lingo2Options.type_hints.items()}) | 44 | for k, t in Lingo2Options.type_hints.items()}) |
| 45 | 45 | ||
| 46 | self.world.generate_early() | 46 | self.world.generate_early() |
| 47 | |||
| 48 | self.world.player_logic.rte_mapping = [self.world.static_logic.map_id_by_name[map_name] | ||
| 49 | for map_name in slot_data.get("rte", [])] | ||
| 50 | |||
| 47 | self.world.create_regions() | 51 | self.world.create_regions() |
| 48 | 52 | ||
| 49 | if self.world.options.shuffle_worldports: | 53 | if self.world.options.shuffle_worldports: |
