From 067d8e707bfa7a445da37190c24f7654dd738121 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Sat, 6 Sep 2025 16:09:10 -0400 Subject: [Client] Location scouting for letters --- client/Archipelago/client.gd | 15 +++++++++++ client/Archipelago/collectable.gd | 4 +++ client/Archipelago/gamedata.gd | 5 ++-- client/Archipelago/manager.gd | 56 +++++++++++++++++++++++++++++++++++---- client/Archipelago/player.gd | 17 ++++++++++++ 5 files changed, 89 insertions(+), 8 deletions(-) (limited to 'client/Archipelago') diff --git a/client/Archipelago/client.gd b/client/Archipelago/client.gd index 428560e..2e080fd 100644 --- a/client/Archipelago/client.gd +++ b/client/Archipelago/client.gd @@ -41,6 +41,7 @@ signal connect_status signal client_connected(slot_data) signal item_received(item_id, index, player, flags, amount) signal message_received(message) +signal location_scout_received(item_id, location_id, player, flags) func _init(): @@ -257,6 +258,16 @@ func _process(_delta): elif cmd == "PrintJSON": emit_signal("message_received", message) + elif cmd == "LocationInfo": + for loc in message["locations"]: + emit_signal( + "location_scout_received", + int(loc["item"]), + int(loc["location"]), + int(loc["player"]), + int(loc["flags"]) + ) + elif state == WebSocketPeer.STATE_CLOSED: if _has_connected: _closed() @@ -392,6 +403,10 @@ func completedGoal(): sendMessage([{"cmd": "StatusUpdate", "status": 30}]) # CLIENT_GOAL +func scoutLocations(loc_ids): + sendMessage([{"cmd": "LocationScouts", "locations": loc_ids}]) + + func hasItem(item_id): return _received_items.has(item_id) diff --git a/client/Archipelago/collectable.gd b/client/Archipelago/collectable.gd index 7bbdd8b..4a17a2a 100644 --- a/client/Archipelago/collectable.gd +++ b/client/Archipelago/collectable.gd @@ -10,3 +10,7 @@ func pickedUp(): ap.keyboard.update_unlocks() super.pickedUp() + + +func setScoutedText(text): + get_node("MeshInstance3D").mesh.text = text.replace(" ", "\n") diff --git a/client/Archipelago/gamedata.gd b/client/Archipelago/gamedata.gd index 11f4981..f7a5d90 100644 --- a/client/Archipelago/gamedata.gd +++ b/client/Archipelago/gamedata.gd @@ -8,7 +8,7 @@ var painting_id_by_map_node_path = {} var door_id_by_ap_id = {} var map_id_by_name = {} var progressive_id_by_ap_id = {} -var letter_key_by_ap_id = {} +var letter_id_by_ap_id = {} func _init(proto_script): @@ -56,8 +56,7 @@ func load(data_bytes): progressive_id_by_ap_id[progressive.get_ap_id()] = progressive.get_id() for letter in objects.get_letters(): - if not letter.has_level2() or not letter.get_level2(): - letter_key_by_ap_id[letter.get_ap_id()] = letter.get_key() + letter_id_by_ap_id[letter.get_ap_id()] = letter.get_id() func get_door_for_map_node_path(map_name, node_path): diff --git a/client/Archipelago/manager.gd b/client/Archipelago/manager.gd index 07d28a4..bcb21e7 100644 --- a/client/Archipelago/manager.gd +++ b/client/Archipelago/manager.gd @@ -20,6 +20,8 @@ var _localdata_file = "" var _last_new_item = -1 var _batch_locations = false var _held_locations = [] +var _held_location_scouts = [] +var _location_scouts = {} var _item_locks = {} var _held_letters = {} var _letters_setup = false @@ -75,6 +77,7 @@ func _ready(): client.connect("item_received", _process_item) client.connect("message_received", _process_message) + client.connect("location_scout_received", _process_location_scout) client.connect("could_not_connect", _client_could_not_connect) client.connect("connect_status", _client_connect_status) client.connect("client_connected", _client_connected) @@ -161,9 +164,11 @@ func _process_item(item, index, from, flags, amount): if rnode != null: rnode.handleTriggered() - var letter_key = gamedata.letter_key_by_ap_id.get(item, null) - if letter_key != null: - _process_key_item(letter_key, amount) + var letter_id = gamedata.letter_id_by_ap_id.get(item, null) + if letter_id != null: + var letter = gamedata.objects.get_letters()[letter_id] + if not letter.has_level2() or not letter.get_level2(): + _process_key_item(letter.get_key(), amount) # Show a message about the item if it's new. if index != null and index > _last_new_item: @@ -280,6 +285,29 @@ func parse_printjson_for_textclient(message): textclient_node.parse_printjson("".join(parts)) +func _process_location_scout(item_id, location_id, player, flags): + _location_scouts[location_id] = {"item": item_id, "player": player, "flags": flags} + + var gamedata = global.get_node("Gamedata") + var map_id = gamedata.map_id_by_name.get(global.map) + + var item_name = "Unknown" + var item_player_game = client._game_by_player[float(player)] + if client._item_id_to_name[item_player_game].has(item_id): + item_name = client._item_id_to_name[item_player_game][item_id] + + var letter_id = gamedata.letter_id_by_ap_id.get(location_id, null) + if letter_id != null: + var letter = gamedata.objects.get_letters()[letter_id] + var room = gamedata.objects.get_rooms()[letter.get_room_id()] + if room.get_map_id() == map_id: + var collectable = get_tree().get_root().get_node("scene").get_node_or_null( + letter.get_path() + ) + if collectable != null: + collectable.setScoutedText(item_name) + + func _client_could_not_connect(): emit_signal("could_not_connect") @@ -345,10 +373,28 @@ func send_location(loc_id): client.sendLocation(loc_id) +func scout_location(loc_id): + if _location_scouts.has(loc_id): + return _location_scouts.get(loc_id) + + if _batch_locations: + _held_location_scouts.append(loc_id) + else: + client.scoutLocation(loc_id) + + return null + + func stop_batching_locations(): _batch_locations = false - client.sendLocations(_held_locations) - _held_locations.clear() + + if not _held_locations.is_empty(): + client.sendLocations(_held_locations) + _held_locations.clear() + + if not _held_location_scouts.is_empty(): + client.scoutLocations(_held_location_scouts) + _held_location_scouts.clear() func colorForItemType(flags): diff --git a/client/Archipelago/player.gd b/client/Archipelago/player.gd index 4569af5..dd6aa2b 100644 --- a/client/Archipelago/player.gd +++ b/client/Archipelago/player.gd @@ -81,6 +81,23 @@ func _ready(): get_parent().add_child.call_deferred(locationListener) + if ( + ap.get_letter_behavior(letter.get_key(), letter.has_level2() and letter.get_level2()) + != ap.kLETTER_BEHAVIOR_VANILLA + ): + var scout = ap.scout_location(letter.get_ap_id()) + if scout != null: + var item_name = "Unknown" + var item_player_game = ap.client._game_by_player[float(scout["player"])] + if ap.client._item_id_to_name[item_player_game].has(scout["item"]): + item_name = ap.client._item_id_to_name[item_player_game][scout["item"]] + + var collectable = get_tree().get_root().get_node("scene").get_node_or_null( + letter.get_path() + ) + if collectable != null: + collectable.setScoutedText.call_deferred(item_name) + # Set up mastery locations. for mastery in gamedata.objects.get_masteries(): var room = gamedata.objects.get_rooms()[mastery.get_room_id()] -- cgit 1.4.1