From c068e66ec9c085d0d897095e6248f70308046de1 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Tue, 18 Apr 2023 14:11:17 -0400 Subject: Added painting shuffling --- Archipelago/client.gd | 22 +++++++++- Archipelago/load.gd | 76 ++++++++++++++++++++++++++++++++++ Archipelago/mypainting.gd | 99 +++++++++++++++++++++++++++++++++++++++++++++ Archipelago/paintingdata.gd | 88 ++++++++++++++++++++++++++++++++++++++++ data/LL1.yaml | 2 +- 5 files changed, 284 insertions(+), 3 deletions(-) create mode 100644 Archipelago/mypainting.gd create mode 100644 Archipelago/paintingdata.gd diff --git a/Archipelago/client.gd b/Archipelago/client.gd index c5f1488..79313b2 100644 --- a/Archipelago/client.gd +++ b/Archipelago/client.gd @@ -42,12 +42,15 @@ var _mentioned_doors = [] var _painting_ids_by_item = {} var _mentioned_paintings = [] var _panel_ids_by_location = {} +var _paintings = {} +var _paintings_mapping = {} var _localdata_file = "" var _death_link = false var _victory_condition = 0 # THE END, THE MASTER var _door_shuffle = false var _color_shuffle = false var _panel_shuffle = 0 # none, rearrange +var _painting_shuffle = false var _slot_seed = 0 var _map_loaded = false @@ -162,6 +165,8 @@ func _on_data(): _mentioned_paintings.append(painting) if _slot_data.has("panel_ids_by_location_id"): _panel_ids_by_location = _slot_data["panel_ids_by_location_id"] + if _slot_data.has("paintings"): + _paintings = _slot_data["paintings"] _death_link = _slot_data.has("death_link") and _slot_data["death_link"] if _death_link: @@ -173,10 +178,14 @@ func _on_data(): _color_shuffle = _slot_data["shuffle_colors"] if _slot_data.has("shuffle_doors"): _door_shuffle = (_slot_data["shuffle_doors"] > 0) + if _slot_data.has("shuffle_paintings"): + _painting_shuffle = (_slot_data["shuffle_paintings"] > 0) if _slot_data.has("shuffle_panels"): _panel_shuffle = _slot_data["shuffle_panels"] if _slot_data.has("seed"): _slot_seed = _slot_data["seed"] + if _slot_data.has("painting_entrance_to_exit"): + _paintings_mapping = _slot_data["painting_entrance_to_exit"] _localdata_file = "user://archipelago/%s_%d" % [_seed, _slot] var ap_file = File.new() @@ -411,9 +420,18 @@ func processItem(item, index, from): doorsNode.get_node(door_id).openDoor() if _painting_ids_by_item.has(stringified): - var paintingsNode = get_tree().get_root().get_node("Spatial/Decorations/Paintings") + var real_parent_node = get_tree().get_root().get_node("Spatial/Decorations/Paintings") + var fake_parent_node = get_tree().get_root().get_node("Spatial/AP_Paintings") + for painting_id in _painting_ids_by_item[stringified]: - paintingsNode.get_node(painting_id).movePainting() + var painting_node = real_parent_node.get_node_or_null(painting_id) + if painting_node != null: + painting_node.movePainting() + + if _painting_shuffle: + painting_node = fake_parent_node.get_node_or_null(painting_id) + if painting_node != null: + painting_node.get_node("Script").movePainting() # Handle progressively opening up the tower. if _item_name_to_id["Progressive Orange Tower"] == item and _tower_floors < orange_tower.size(): diff --git a/Archipelago/load.gd b/Archipelago/load.gd index 47f51a6..3c6b31c 100644 --- a/Archipelago/load.gd +++ b/Archipelago/load.gd @@ -90,6 +90,52 @@ func _load(): target_panel_node.text = source["hint"] target_panel_node.answer = source["answer"] + # Randomize the paintings, if necessary. + if apclient._painting_shuffle: + var pd_script = ResourceLoader.load("user://maps/Archipelago/paintingdata.gd") + var pd = pd_script.new() + pd.set_name("AP_Paintings") + self.add_child(pd) + + var all_paintings = pd.kALL_PAINTINGS + + var classes = {} + for painting in apclient._paintings_mapping.values(): + if not classes.has(painting): + var i = rng.randi_range(0, all_paintings.size() - 1) + var chosen = all_paintings[i] + classes[painting] = chosen + all_paintings.remove(i) + + var randomized = [] + for painting in apclient._paintings_mapping.values(): + var painting_class = classes[painting] + instantiate_painting(painting, painting_class) + randomized.append(painting) + + for source_painting in apclient._paintings_mapping.keys(): + var target_painting = apclient._paintings_mapping[source_painting] + var painting_class = classes[target_painting] + var new_source = instantiate_painting(source_painting, painting_class) + new_source.target = pd.get_node(target_painting).get_node("Script") + randomized.append(source_painting) + + var remaining_size = classes.size() / 2 + if remaining_size >= all_paintings.size(): + remaining_size = all_paintings.size() + var remaining = [] + for i in range(0, remaining_size): + var j = rng.randi_range(0, all_paintings.size() - 1) + remaining.append(all_paintings[j]) + all_paintings.remove(j) + + for painting in apclient._paintings.keys(): + if randomized.has(painting): + continue + + var chosen_painting = remaining[rng.randi_range(0, remaining.size() - 1)] + instantiate_painting(painting, chosen_painting) + # Attach a script to every panel so that we can do things like conditionally # disable them. var panel_script = ResourceLoader.load("user://maps/Archipelago/panel.gd") @@ -130,3 +176,33 @@ func _load(): func sort_by_link(a, b): return a["link"] < b["link"] + + +func instantiate_painting(name, scene): + var apclient = global.get_node("Archipelago") + + var scene_path = "res://nodes/paintings/%s.tscn" % scene + var painting_scene = load(scene_path) + var new_painting = painting_scene.instance() + new_painting.set_name(name) + + var old_painting = self.get_node("Decorations/Paintings").get_node(name) + new_painting.translation = old_painting.translation + new_painting.rotation = old_painting.rotation + + var mypainting_script = ResourceLoader.load("user://maps/Archipelago/mypainting.gd") + var mps_inst = mypainting_script.new() + mps_inst.set_name("Script") + + var pconfig = apclient._paintings[name] + mps_inst.orientation = pconfig["orientation"] + if pconfig["move"]: + mps_inst.move = true + mps_inst.move_to_x = old_painting.move_to_x + mps_inst.move_to_z = old_painting.move_to_z + mps_inst.key = old_painting.key + + self.get_node("AP_Paintings").add_child(new_painting) + new_painting.add_child(mps_inst) + old_painting.queue_free() + return mps_inst diff --git a/Archipelago/mypainting.gd b/Archipelago/mypainting.gd new file mode 100644 index 0000000..5e9c703 --- /dev/null +++ b/Archipelago/mypainting.gd @@ -0,0 +1,99 @@ +extends Spatial + +var orientation = "" # north, south, east, west +var move = false +var move_to_x +var move_to_z +var target = null +var key + + +func _ready(): + var _connected = get_tree().get_root().get_node("Spatial/player").connect( + "looked_at", self, "_looked_at" + ) + if move: + key.get_node("Viewport/GUI/Panel/TextEdit").connect( + "answer_correct", self, "_answer_correct" + ) + + +func _answer_correct(): + var apclient = global.get_node("Archipelago") + if not apclient._door_shuffle or apclient.paintingIsVanilla(self.get_parent().name): + movePainting() + + +func movePainting(): + self.get_parent().translation.x = move_to_x + self.get_parent().translation.z = move_to_z + + +func _looked_at(body, painting): + if ( + target != null + and body.is_in_group("player") + and (painting.get_name() == self.get_parent().get_name()) + ): + var target_dir = _dir_to_int(target.orientation) + var source_dir = _dir_to_int(orientation) + var rotate = target_dir - source_dir + if rotate < 0: + rotate += 4 + rotate *= 90 + + var target_painting = target.get_parent() + + # this is ACW + if rotate == 0: + body.translation.x = ( + target_painting.translation.x + (body.translation.x - painting.translation.x) + ) + body.translation.y = ( + target_painting.translation.y + (body.translation.y - painting.translation.y) + ) + body.translation.z = ( + target_painting.translation.z + (body.translation.z - painting.translation.z) + ) + elif rotate == 180: + body.translation.x = ( + target_painting.translation.x - (body.translation.x - painting.translation.x) + ) + body.translation.y = ( + target_painting.translation.y + (body.translation.y - painting.translation.y) + ) + body.translation.z = ( + target_painting.translation.z - (body.translation.z - painting.translation.z) + ) + body.rotate_y(PI) + body.velocity = body.velocity.rotated(Vector3(0, 1, 0), PI) + elif rotate == 90: + var diff_x = body.translation.x - painting.translation.x + var diff_y = body.translation.y - painting.translation.y + var diff_z = body.translation.z - painting.translation.z + body.translation.x = target_painting.translation.x + diff_z + body.translation.y = target_painting.translation.y + diff_y + body.translation.z = target_painting.translation.z - diff_x + body.rotate_y(PI / 2) + body.velocity = body.velocity.rotated(Vector3(0, 1, 0), PI / 2) + elif rotate == 270: + var diff_x = body.translation.x - painting.translation.x + var diff_y = body.translation.y - painting.translation.y + var diff_z = body.translation.z - painting.translation.z + body.translation.x = target_painting.translation.x - diff_z + body.translation.y = target_painting.translation.y + diff_y + body.translation.z = target_painting.translation.z + diff_x + body.rotate_y(3 * PI / 2) + body.velocity = body.velocity.rotated(Vector3(0, 1, 0), 3 * PI / 2) + + +func _dir_to_int(dir): + if dir == "north": + return 0 + elif dir == "west": + return 1 + elif dir == "south": + return 2 + elif dir == "east": + return 3 + return 4 diff --git a/Archipelago/paintingdata.gd b/Archipelago/paintingdata.gd new file mode 100644 index 0000000..0cbeac2 --- /dev/null +++ b/Archipelago/paintingdata.gd @@ -0,0 +1,88 @@ +extends Node + +const kALL_PAINTINGS = [ + "arrows", + "beach", + "bg_bg1", + "bg_bg2", + "bg_bg3", + "bg_bg4", + "bg_bg5", + "bg_bg6", + "bg_bg7", + "bg_bg8", + "bg_bookshelf", + "bg_candle", + "bg_colin", + "bg_cooking", + "bg_egg", + "bg_fish", + "bg_fourth", + "bg_gene", + "bg_knight", + "bg_margret", + "bg_nose", + "bg_pearson", + "bg_scorpion", + "bg_stakeout", + "bg_waves", + "blueman", + "boxes", + "catlike", + "cherry", + "clock", + "colors", + "crep", + "crown", + "egg", + "eight", + "electrons", + "emmy", + "ether", + "eyes", + "eyesyellow", + "flower", + "fruitbowl", + "garden", + "gardenexploded", + "hatkirby", + "hatman", + "hi", + "hi_solved", + "icy", + "ig_note", + "ig_rose", + "kiwi", + "knot", + "map", + "maze", + "mittens", + "ninjonicx", + "ninjonicx_square", + "noka", + "ntwiles", + "owl", + "panda", + "pattern_gold", + "pattern_gray", + "pattern_icely", + "pattern_purple", + "pattern_solar", + "pencil", + "rainbow", + "redman", + "rever", + "rm_tower", + "rubrica", + "samswine", + "smile", + "smile_red", + "snowman", + "symmetry", + "symmetry_2", + "taiji", + "tree", + "undalevein", + "yinyang", + "zombie" +] diff --git a/data/LL1.yaml b/data/LL1.yaml index 8c9bea2..88eb3f6 100644 --- a/data/LL1.yaml +++ b/data/LL1.yaml @@ -2294,7 +2294,7 @@ tag: topyellow # Forbid these three for now because one is hidden - id: Chemistry Room/Panel_open - color: black + color: white tag: forbid - id: Chemistry Room/Panel_close color: black -- cgit 1.4.1