From 6aaf7acc1c8481087c89a3580ac0aadfb6b2fb33 Mon Sep 17 00:00:00 2001 From: sybaik1 Date: Mon, 5 May 2025 01:39:27 +0900 Subject: [PATCH 1/2] feat: added Korea strategy for p2_lr, p3_ur, p3_apoc, p4_dd, p4_ct --- scenes/p2/p2_lr_main.tscn | 4 +- scenes/p2/sequences/light_ramp_seq.gd | 38 +++--- scenes/p3/p3_apoc_main.tscn | 4 +- scenes/p3/p3_ur_main.tscn | 4 +- scenes/p3/sequences/apoc_seq.gd | 83 ++++++++++--- scenes/p3/sequences/ult_relativity_seq.gd | 13 +- scenes/p4/p4_ct_main.tscn | 11 +- scenes/p4/p4_dd_main.tscn | 4 +- scenes/p4/sequences/crystal_time_seq.gd | 91 +++++++++++--- scenes/p4/sequences/ct_positions.gd | 21 ++++ scenes/p4/sequences/darklit_seq.gd | 143 +++++++++++++++++++++- scenes/p4/sequences/dd_positions.gd | 11 ++ 12 files changed, 357 insertions(+), 70 deletions(-) diff --git a/scenes/p2/p2_lr_main.tscn b/scenes/p2/p2_lr_main.tscn index e78bcc8..882d1d5 100644 --- a/scenes/p2/p2_lr_main.tscn +++ b/scenes/p2/p2_lr_main.tscn @@ -438,7 +438,7 @@ action_mode = 1 button_mask = 3 selected = 0 fit_to_longest_item = false -item_count = 4 +item_count = 5 popup/item_0/text = "NAUR (E/W Puddles)" popup/item_1/text = "LPDU (N/S Puddles)" popup/item_1/id = 1 @@ -446,6 +446,8 @@ popup/item_2/text = "Elemental (E/W)" popup/item_2/id = 2 popup/item_3/text = "Mana (NE/SW)" popup/item_3/id = 3 +popup/item_4/text = "KOR (NE/SW)" +popup/item_4/id = 4 script = ExtResource("28_lb327") [node name="PuddlesSelectButton" type="CheckButton" parent="Buttons"] diff --git a/scenes/p2/sequences/light_ramp_seq.gd b/scenes/p2/sequences/light_ramp_seq.gd index b2f481e..d6ca95f 100644 --- a/scenes/p2/sequences/light_ramp_seq.gd +++ b/scenes/p2/sequences/light_ramp_seq.gd @@ -5,7 +5,7 @@ extends Node -enum Strat {NA, EU, ELE, MANA} +enum Strat {NA, EU, ELE, MANA, KOR} # Debuff Icon Scenes const CHAINS_LOCKED = preload("res://scenes/ui/auras/debuff_icons/p2/chains_locked.tscn") @@ -70,6 +70,7 @@ var orb_keys := [] var spread_keys := [] var na_we_spread_prio := [4, 3, 5, 2, 6, 1, 7, 0] # W > E Prio [r1, h1, r2, h2, m1, t1, m2, t2] var eu_ns_spread_prio := [3, 2, 1, 0, 4, 5, 6, 7] # N > S Prio [h1, h2, t1, t2, r1, r2, m1, m2] +var kor_we_spread_prio := [5, 4, 6, 3, 7, 2, 0, 1] # W > E Prio [m2, m1, r1, h1, r2, h2, t2, t1] #var ele_we_spread_prio := [6, 3, 7, 2, 4, 1, 5, 0] # W > E Prio [m1, h1, m2, h2, r1, t1, r2, t2] # Will be randomized. First 4 get 1 stacks of debuff, last 4 are quad tower soakers. var lightsteeped_keys := ["t2", "t1", "h2", "h1", "r1", "r2", "m1", "m2"] @@ -109,7 +110,7 @@ func cast_lr() -> void: func move_pre_pos() -> void: - if strat in [Strat.ELE, Strat.MANA]: + if strat in [Strat.ELE, Strat.MANA, Strat.KOR]: move_party(party, LRPosNA.pre_pos_44_ele) else: move_party(party, LRPosNA.pre_pos_44) @@ -154,7 +155,7 @@ func move_puddles_tower_lineup() -> void: elif strat == Strat.ELE: party[lr_party["n_puddle"]].move_to(LRPosEU.tower_lineup["n_puddle"]) party[lr_party["s_puddle"]].move_to(LRPosEU.tower_lineup["s_puddle"]) - elif strat == Strat.MANA: + elif strat in [Strat.MANA, Strat.KOR]: party[lr_party["n_puddle"]].move_to(LRPosJP.tower_lineup["n_puddle"]) party[lr_party["s_puddle"]].move_to(LRPosJP.tower_lineup["s_puddle"]) @@ -165,7 +166,7 @@ func move_tower_lineup() -> void: move_lr_party(LRPosNA.tower_lineup) elif strat == Strat.EU: move_lr_party(LRPosEU.tower_lineup) - elif strat == Strat.MANA: + elif strat in [Strat.MANA, Strat.KOR]: move_lr_party(LRPosJP.tower_lineup) ## 11.00 @@ -185,7 +186,7 @@ func move_tower_soak(): move_lr_party(LRPosNA.tower_soak) elif strat == Strat.EU: move_lr_party(LRPosEU.tower_soak) - elif strat == Strat.MANA: + elif strat in [Strat.MANA, Strat.KOR]: move_lr_party(LRPosJP.tower_soak) ## 15.60 @@ -206,7 +207,7 @@ func first_puddle_snapshot() -> void: move_lr_party(LRPosNA.puddle_dodge_1) elif strat == Strat.EU: move_lr_party(LRPosEU.puddle_dodge_1) - elif strat == Strat.MANA: + elif strat in [Strat.MANA, Strat.KOR]: move_lr_party(LRPosJP.puddle_dodge_1) @@ -218,7 +219,7 @@ func second_puddle_snapshot() -> void: move_lr_party(LRPosNA.puddle_dodge_2) elif strat == Strat.EU: move_lr_party(LRPosEU.puddle_dodge_2) - elif strat == Strat.MANA: + elif strat in [Strat.MANA, Strat.KOR]: move_lr_party(LRPosJP.puddle_dodge_2) @@ -230,7 +231,7 @@ func third_puddle_snapshot() -> void: move_lr_party(LRPosNA.puddle_dodge_3) elif strat == Strat.EU: move_lr_party(LRPosEU.puddle_dodge_3) - elif strat == Strat.MANA: + elif strat in [Strat.MANA, Strat.KOR]: move_lr_party(LRPosJP.puddle_dodge_3) @@ -283,7 +284,7 @@ func forth_puddle_snapshot() -> void: move_lr_party(LRPosNA.puddle_dodge_4) elif strat == Strat.EU: move_lr_party(LRPosEU.puddle_dodge_4) - elif strat == Strat.MANA: + elif strat in [Strat.MANA, Strat.KOR]: move_lr_party(LRPosJP.puddle_dodge_4) @@ -296,7 +297,7 @@ func fifth_puddle_snapshot() -> void: move_lr_party(LRPosNA.puddle_dodge_5) elif strat == Strat.EU: move_lr_party(LRPosEU.puddle_dodge_5) - elif strat == Strat.MANA: + elif strat in [Strat.MANA, Strat.KOR]: move_lr_party(LRPosJP.puddle_dodge_5) first_orbs_telegraph() @@ -323,7 +324,7 @@ func second_orbs_spawn () -> void: # Intermediate dodge to simulate slower movement leading up to shared hit func move_to_intermediate_spot() -> void: - if strat in [Strat.NA, Strat.ELE, Strat.MANA]: + if strat in [Strat.NA, Strat.ELE, Strat.MANA, Strat.KOR]: move_lr_party(LRPosNA.inter_dodge) elif strat == Strat.EU: move_lr_party(LRPosEU.inter_dodge) @@ -332,7 +333,7 @@ func move_to_intermediate_spot() -> void: ## 24.50 # Move groups to first safe spot func move_safe_spot_1() -> void: - if strat in [Strat.NA, Strat.ELE, Strat.MANA]: + if strat in [Strat.NA, Strat.ELE, Strat.MANA, Strat.KOR]: if n_orb_pattern: move_lr_party(LRPosNA.north_orb_first_dodge) else: @@ -391,7 +392,7 @@ func first_orbs_hit() -> void: # Move group to second safe spot # Remove chains func move_safe_spot_2() -> void: - if strat in [Strat.NA, Strat.ELE, Strat.MANA]: + if strat in [Strat.NA, Strat.ELE, Strat.MANA, Strat.KOR]: if n_orb_pattern: move_lr_party(LRPosNA.north_orb_second_dodge) else: @@ -420,7 +421,7 @@ func second_orbs_hit() -> void: func move_middle_safe_spot() -> void: - if strat in [Strat.NA, Strat.ELE, Strat.MANA]: + if strat in [Strat.NA, Strat.ELE, Strat.MANA, Strat.KOR]: if n_orb_pattern: move_lr_party(LRPosNA.n_pattern_middle_dodge) else: @@ -465,12 +466,12 @@ func middle_tower_snapshot() -> void: # Move to spread/pair spots func move_spread_pairs() -> void: if halo_spread_pattern: - if strat == Strat.MANA: + if strat in [Strat.MANA, Strat.KOR]: move_party(party, LRPosJP.spread_clocks) else: move_party(party, LRPosNA.spread_clocks) else: - if strat == Strat.MANA: + if strat in [Strat.MANA, Strat.KOR]: move_party(party, LRPosJP.pairs) else: move_party(party, LRPosNA.pairs) @@ -495,7 +496,7 @@ func spread_pairs_hit() -> void: ## 38.0 # Move to clock pos func move_to_clock_pos() -> void: - if strat == Strat.MANA: + if strat in [Strat.MANA, Strat.KOR]: move_party(party, LRPosJP.spread_clocks) else: move_party(party, LRPosNA.spread_clocks) @@ -540,6 +541,9 @@ func four_four_party_setup() -> void: elif strat in [Strat.ELE, Strat.MANA]: spread_prio = na_we_spread_prio lr_south_lineup = lr_south_lineup_ele + elif strat == Strat.KOR: + spread_prio = kor_we_spread_prio + lr_south_lineup = lr_south_lineup_ele # LR assigments: 2 puddles, 6 chains, 2 chained orbs # Get 2 unique random keys var spread_keys_index := [] diff --git a/scenes/p3/p3_apoc_main.tscn b/scenes/p3/p3_apoc_main.tscn index 9ce7637..993a929 100644 --- a/scenes/p3/p3_apoc_main.tscn +++ b/scenes/p3/p3_apoc_main.tscn @@ -738,7 +738,7 @@ action_mode = 1 button_mask = 3 selected = 0 fit_to_longest_item = false -item_count = 4 +item_count = 5 popup/item_0/text = "NAUR (E/W)" popup/item_1/text = "LPDU (NW/SE)" popup/item_1/id = 1 @@ -746,6 +746,8 @@ popup/item_2/text = "MUR (LP)" popup/item_2/id = 2 popup/item_3/text = "Mana" popup/item_3/id = 3 +popup/item_4/text = "KOR" +popup/item_4/id = 4 script = ExtResource("27_eht14") [node name="Label" type="Label" parent="Buttons/StratSelectButton"] diff --git a/scenes/p3/p3_ur_main.tscn b/scenes/p3/p3_ur_main.tscn index a03447d..0e95af2 100644 --- a/scenes/p3/p3_ur_main.tscn +++ b/scenes/p3/p3_ur_main.tscn @@ -426,12 +426,14 @@ action_mode = 1 button_mask = 3 selected = 0 fit_to_longest_item = false -item_count = 3 +item_count = 4 popup/item_0/text = "NAUR Lineup" popup/item_1/text = "LPDU Lineup" popup/item_1/id = 1 popup/item_2/text = "Grey-9 Lineup" popup/item_2/id = 2 +popup/item_3/text = "KOR" +popup/item_3/id = 3 script = ExtResource("25_wp03d") [node name="SequenceSelectButton2" parent="Buttons" instance=ExtResource("26_js0i3")] diff --git a/scenes/p3/sequences/apoc_seq.gd b/scenes/p3/sequences/apoc_seq.gd index 1021943..5fee4bc 100644 --- a/scenes/p3/sequences/apoc_seq.gd +++ b/scenes/p3/sequences/apoc_seq.gd @@ -6,7 +6,7 @@ extends Node enum {NONE, SHORT, MED, LONG} # Water debuff durations. -enum Strat {NAUR, LPDU, MUR, MANA} +enum Strat {NAUR, LPDU, MUR, MANA, KOR} enum Spread {STATIC, PERMA} # Freepoc, Permaswap const DARK_WATER_ICON = preload("res://scenes/ui/auras/debuff_icons/p3/dark_water_icon.tscn") @@ -38,9 +38,16 @@ const CCW_ROTATION_MAP := {0: -135, 45: -90, 90: -45, 135: 0} const MANA_CW_ROTATION_MAP := {0: -45, 45: 0, 90: -135, 135: -90} const MANA_CCW_ROTATION_MAP := {0: 45, 45: 90, 90: -45, 135: 0} const MANA_ROTATION_OFFSET = 22.5 +# KOR rotations: party anchor points are -45 ~ 90 +# const KOR_ROTATION_OFFSET = 67.5 +const KOR_CW_ROTATION_MAP := {0: -45, 45: 0, 90: 45, 135: 90} +const KOR_CCW_ROTATION_MAP := {0: 45, 45: 90, 90: -45, 135: 0} # Determines where T2 goes for bait (assuming no swap) const T2_ROTATION_CW := {0: -45, 45: 0, 90: -135, 135: -90} const T2_ROTATION_CCW := {0: -45, 45: 0, 90: 45, 135: 90} +# KOR strat: Determines where T2 goes for bait (assuming no swap) +const KOR_T2_ROTATION_CW := {0: -45, 45: 0, 90: 45, 135: 90} +const KOR_T2_ROTATION_CCW := {0: 135, 45: 180, 90: 45, 135: 90} # Base positions for NA and EU setups const PARTY_SA_STATIC := { @@ -137,8 +144,9 @@ func cast_refrain(): func move_to_setup(): if strat in [Strat.NAUR, Strat.MUR]: move_party_sa_static(ApocPos.ROLE_SETUP_NA) - elif strat == Strat.MANA: - move_party_sa_static_rotated(ApocPos.ROLE_SETUP_EU, MANA_ROTATION_OFFSET) + # MANA start is NNW, KOR start is NNE, so add 45 degree when strat is KOR + elif strat == Strat.MANA or strat == Strat.KOR: + move_party_sa_static_rotated(ApocPos.ROLE_SETUP_EU, MANA_ROTATION_OFFSET + 45*int(strat==Strat.KOR)) else: move_party_sa_static(ApocPos.ROLE_SETUP_EU) @@ -195,8 +203,8 @@ func cast_apoc(): func move_to_swap_pos(): if strat in [Strat.NAUR, Strat.MUR]: move_party_sa(ApocPos.SWAP_SETUP_NA) - elif strat == Strat.MANA: - move_party_sa_rotated(ApocPos.SWAP_SETUP_EU, MANA_ROTATION_OFFSET) + elif strat in [Strat.MANA, Strat.KOR]: + move_party_sa_rotated(ApocPos.SWAP_SETUP_EU, MANA_ROTATION_OFFSET + 45*int(strat==Strat.KOR)) else: move_party_sa(ApocPos.SWAP_SETUP_EU) @@ -221,8 +229,8 @@ func start_lock_cd(duration): func move_stack_1(): if strat in [Strat.NAUR, Strat.MUR]: move_party_sa(ApocPos.STACK_1_NA) - elif strat == Strat.MANA: - move_party_sa_rotated(ApocPos.STACK_1_EU, MANA_ROTATION_OFFSET) + elif strat in [Strat.MANA, Strat.KOR]: + move_party_sa_rotated(ApocPos.STACK_1_EU, MANA_ROTATION_OFFSET + 45*int(strat==Strat.KOR)) else: move_party_sa(ApocPos.STACK_1_EU) @@ -257,8 +265,8 @@ func water_hit(duration: int): func move_to_spread_pos(): if strat in [Strat.NAUR, Strat.MUR]: move_party_sa(ApocPos.SPREAD_NA) - elif strat == Strat.MANA: - move_party_sa_rotated(ApocPos.SPREAD_EU, MANA_ROTATION_OFFSET) + elif strat in [Strat.MANA, Strat.KOR]: + move_party_sa_rotated(ApocPos.SPREAD_EU, MANA_ROTATION_OFFSET + 45*int(strat==Strat.KOR)) else: move_party_sa(ApocPos.SPREAD_EU) @@ -288,9 +296,9 @@ func pre_move_swaps(): # Move to Apoc Spread pos (move bots as late as possible). func move_apoc_spread(): # This works fine for all strats, I'm just being overly cautious. - if strat == Strat.MANA: + if strat in [Strat.MANA, Strat.KOR]: var check_cw = "CW" if cw_light else "CCW" - var check_map = "MANA_%s_ROTATION_MAP" if strat == Strat.MANA else "%s_ROTATION_MAP" + var check_map = "MANA_%s_ROTATION_MAP" if strat == Strat.MANA else "KOR_%s_ROTATION_MAP" var ROTATION_MAP = get(check_map % check_cw) var APOC_SPREAD = ApocPos.APOC_SPREAD_CW if cw_light else ApocPos.APOC_SPREAD_CCW if apoc_spread == Spread.STATIC: @@ -338,9 +346,9 @@ func eruption_hit(): ## 36.2 # Move to post eruption pos func move_post_erupt(): - if strat == Strat.MANA: + if strat in [Strat.MANA, Strat.KOR]: var check_cw = "CW" if cw_light else "CCW" - var check_map = "MANA_%s_ROTATION_MAP" if strat == Strat.MANA else "%s_ROTATION_MAP" + var check_map = "MANA_%s_ROTATION_MAP" if strat == Strat.MANA else "KOR_%s_ROTATION_MAP" var ROTATION_MAP = get(check_map % check_cw) var APOC_SPREAD = ApocPos.POST_ERUPTION if apoc_spread == Spread.STATIC: @@ -364,10 +372,15 @@ func move_post_erupt(): ## 37.0 # Move to water stack 2 func move_stack_2(): - if cw_light: - move_party_sa_rotated(ApocPos.STACK_2, CW_ROTATION_MAP[arena_rotation_deg]) + var check_cw = "CW" if cw_light else "CCW" + if strat in [Strat.MANA, Strat.KOR]: + var check_map = "MANA_%s_ROTATION_MAP" if strat == Strat.MANA else "KOR_%s_ROTATION_MAP" + var ROTATION_MAP = get(check_map % check_cw) + move_party_sa_rotated(ApocPos.STACK_2, ROTATION_MAP[arena_rotation_deg]) else: - move_party_sa_rotated(ApocPos.STACK_2, CCW_ROTATION_MAP[arena_rotation_deg]) + var check_map = "%s_ROTATION_MAP" + var ROTATION_MAP = get(check_map % check_cw) + move_party_sa_rotated(ApocPos.STACK_2, ROTATION_MAP[arena_rotation_deg]) ## 36.8 @@ -398,7 +411,11 @@ func med_water_hit(): ## 41.8 func move_t2_short(): bait_tank_key = "t2" if !Global.p3_t1_bait else "t1" - bait_rotation_dict = T2_ROTATION_CW if cw_light else T2_ROTATION_CCW + var check_cw = "CW" if cw_light else "CCW" + var bait_map = "T2_ROTATION_%s" + if strat == Strat.KOR: + bait_map = "KOR_T2_ROTATION_%s" + bait_rotation_dict = get(bait_map % check_cw) bait_rotation_offset = 0 # If tank swapped, send them to opposite side. if (!Global.p3_t1_bait and t2_swapped) or (Global.p3_t1_bait and t1_swapped): @@ -473,6 +490,14 @@ func long_lock_cd(): # Move to pre-kb position func move_pre_kb(): var flank_positions := get_oracle_flank_pos() + # KOR strat: move to nearest flank positions + if strat == Strat.KOR: + var bait_swapped = false + if (!Global.p3_t1_bait and t2_swapped) or (Global.p3_t1_bait and t1_swapped): + bait_swapped = true + # sup group go right + if cw_light != bait_swapped: + flank_positions = [flank_positions[1], flank_positions[0]] for key: String in party_keys_sa: if key.contains("sup"): get_char_sa(key).move_to(flank_positions[0]) @@ -530,7 +555,7 @@ func party_setup() -> void: var dps_keys: Array # LP1 keys for MUR #var sup_keys: Array # LP2 keys for MUR # Handle strat specific variables. - if strat in [Strat.NAUR, Strat.LPDU, Strat.MANA]: + if strat in [Strat.NAUR, Strat.LPDU, Strat.MANA, Strat.KOR]: party_keys_sa = PARTY_SA_STATIC.duplicate() dps_adjust_prio = DPS_ADJUST_PRIO_NA.duplicate() sup_adjust_prio = SUP_ADJUST_PRIO_NA.duplicate() @@ -546,7 +571,7 @@ func party_setup() -> void: assert(shuffle_list.size() == debuff_lengths.size(), "Array size mismatch.") shuffle_list.shuffle() - # User option to force swap. + # User option to force swap. if Global.p3_apoc_force_swap: var player_key = get_tree().get_first_node_in_group("player").get_role() # We can ignore this if player is lowest swap prio. @@ -602,12 +627,32 @@ func party_setup() -> void: t1_swapped = true if adjusters["dps"].has("t2") or adjusters["sup"].has("t2"): t2_swapped = true + # Sort adjusting groups by adjusting priority. + var sorted_adjusters := {"dps": [], "sup": []} + for dps in dps_adjust_prio: + if dps in adjusters["dps"]: + sorted_adjusters["dps"].append(dps) + for sup in sup_adjust_prio: + if sup in adjusters["sup"]: + sorted_adjusters["sup"].append(sup) + adjusters = sorted_adjusters + # Handle swaps. while adjusters["dps"].size() > 0: var dps_swap = adjusters["dps"].pop_front() var sup_swap = adjusters["sup"].pop_front() var sup_key = party_keys_sa.find_key(sup_swap) party_keys_sa[party_keys_sa.find_key(dps_swap)] = sup_swap party_keys_sa[sup_key] = dps_swap + # KOR strat! Handle swaps for melee dps going to the back. tank adjust to the back. + if strat == Strat.KOR: + if party_keys_sa.find_key("m1") == "fl_sup": # only when m1 and h1 swap + party_keys_sa["nl_sup"] = "m1" + party_keys_sa["fl_sup"] = "t1" + if party_keys_sa.find_key("m2") == "fl_sup": # t1 could have swaped with m1 + var sup_swap = "t1" if party_keys_sa["fl_sup"] == "t1" else "t2" + var sup_key = party_keys_sa.find_key(sup_swap) + party_keys_sa["fl_sup"] = sup_swap + party_keys_sa[sup_key] = "m2" # Return CharacterBody given its Apoc position key. diff --git a/scenes/p3/sequences/ult_relativity_seq.gd b/scenes/p3/sequences/ult_relativity_seq.gd index 6b5ef5e..bcb169c 100644 --- a/scenes/p3/sequences/ult_relativity_seq.gd +++ b/scenes/p3/sequences/ult_relativity_seq.gd @@ -5,7 +5,7 @@ extends Node -enum Strat {NA, EU, GREY} +enum Strat {NA, EU, GREY, KOR} # Debuff Icon Scenes const STUN_ICON = preload("res://scenes/ui/auras/debuff_icons/common/stun_icon.tscn") @@ -58,6 +58,8 @@ var eu_dps_prio := ["r1", "m1", "m2", "r2"] var eu_sup_prio := ["h1", "t1", "t2", "h2"] var grey_dps_prio := ["r2", "m2", "m1", "r1"] var grey_sup_prio := ["h2", "t2", "t1", "h1"] +var kor_dps_prio := ["r2", "r1", "m2", "m1"] +var kor_sup_prio := ["h2", "t2", "t1", "h1"] var party_keys_ur := { "f1_dps_sw": "", "f1_dps_se": "", "f1_sup": "", "f2_dps": "", "f2_sup": "", @@ -373,7 +375,7 @@ func move_third_bait() -> void: var pc: PlayableCharacter = get_ur_player(hourglass_soakers[key]) var pos_key = hourglass_soakers[key] # Need to swap E/W soaker keys if Grey-9 - if selected_strat == Strat.GREY and pos_key in ["f2_dps", "f2_sup"]: + if selected_strat in [Strat.GREY, Strat.KOR] and pos_key in ["f2_dps", "f2_sup"]: if pos_key == "f2_dps": pc = get_ur_player("f2_sup") pos_key = "f2_sup_g9" @@ -400,7 +402,7 @@ func move_final() -> void: func look_out() -> void: for key in party_keys_ur: var pos_key = String(key) - if selected_strat == Strat.GREY and pos_key in ["f2_dps", "f2_sup"]: + if selected_strat in [Strat.GREY, Strat.KOR] and pos_key in ["f2_dps", "f2_sup"]: pos_key = str(pos_key + "_g9") get_ur_player(key).look_at_direction(v3(UltRelativityPcPos.look_direction[pos_key].rotated(deg_to_rad(arena_rotation_deg)))) @@ -530,6 +532,9 @@ func party_setup() -> void: elif selected_strat == Strat.GREY: dps_prio = grey_dps_prio.duplicate() sup_prio = grey_sup_prio.duplicate() + elif selected_strat == Strat.KOR: + dps_prio = kor_dps_prio.duplicate() + sup_prio = kor_sup_prio.duplicate() else: # If user changes saved_variable to something invalid, reset it. GameEvents.emit_variable_saved("settings", "p3_ur_strat", 0) @@ -598,7 +603,7 @@ func move_party(party_dict: Dictionary, pos: Dictionary) -> void: func move_party_ur_rotated(pos: Dictionary) -> void: for key: String in party_keys_ur: var pos_key = String(key) - if selected_strat == Strat.GREY and key in ["f2_dps", "f2_sup"]: + if selected_strat in [Strat.GREY, Strat.KOR] and key in ["f2_dps", "f2_sup"]: pos_key = str(pos_key + "_g9") var pc: PlayableCharacter = get_ur_player(key) if pc.is_player() and !Global.spectate_mode: diff --git a/scenes/p4/p4_ct_main.tscn b/scenes/p4/p4_ct_main.tscn index 2bfb913..3a1680b 100644 --- a/scenes/p4/p4_ct_main.tscn +++ b/scenes/p4/p4_ct_main.tscn @@ -153,8 +153,8 @@ tracks/1/path = NodePath(".") tracks/1/interp = 1 tracks/1/loop_wrap = true tracks/1/keys = { -"times": PackedFloat32Array(13.4, 18, 20.9, 21.4, 23.2, 24.2, 26.2, 28.3, 29.3, 31.2, 33.6, 35.8, 40.6, 56.4), -"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), +"times": PackedFloat32Array(13.4, 18, 20.9, 21.4, 23.2, 24.2, 26.2, 28.3, 29.3, 31.2, 33.6, 35.8, 40.6, 45.6, 56.4), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), "values": [{ "args": [], "method": &"move_pre_hg" @@ -196,6 +196,9 @@ tracks/1/keys = { "method": &"move_jump_spread" }, { "args": [], +"method": &"cast_kb_resist" +}, { +"args": [], "method": &"move_akh_morn" }] } @@ -742,10 +745,12 @@ action_mode = 1 button_mask = 3 selected = 0 fit_to_longest_item = false -item_count = 2 +item_count = 3 popup/item_0/text = "NAUR" popup/item_1/text = "MUR" popup/item_1/id = 1 +popup/item_2/text = "KOR" +popup/item_2/id = 2 script = ExtResource("35_k1mu3") [node name="Label" type="Label" parent="Buttons/StratSelectButton"] diff --git a/scenes/p4/p4_dd_main.tscn b/scenes/p4/p4_dd_main.tscn index c5cfdae..7a83357 100644 --- a/scenes/p4/p4_dd_main.tscn +++ b/scenes/p4/p4_dd_main.tscn @@ -639,7 +639,7 @@ action_mode = 1 button_mask = 3 selected = 0 fit_to_longest_item = false -item_count = 5 +item_count = 6 popup/item_0/text = "NAUR" popup/item_1/text = "Mami (EU)" popup/item_1/id = 1 @@ -649,6 +649,8 @@ popup/item_3/text = "Mana" popup/item_3/id = 3 popup/item_4/text = "MUR" popup/item_4/id = 4 +popup/item_5/text = "KOR" +popup/item_5/id = 5 script = ExtResource("34_c6fxa") [node name="Label" type="Label" parent="Buttons/StratSelectButton"] diff --git a/scenes/p4/sequences/crystal_time_seq.gd b/scenes/p4/sequences/crystal_time_seq.gd index ca8167c..ce8716d 100644 --- a/scenes/p4/sequences/crystal_time_seq.gd +++ b/scenes/p4/sequences/crystal_time_seq.gd @@ -6,7 +6,7 @@ extends Node enum Intercards {NW, NE, SE, SW} -enum Strat {NA, MUR} +enum Strat {NA, MUR, KOR} # Debuff Icon Scenes const AERO_ICON = preload("res://scenes/ui/auras/debuff_icons/p4/aero.tscn") @@ -70,6 +70,7 @@ const AKH_MORN_DARK_COLOR := Color.DARK_VIOLET const NA_WE_PRIO := ["h2", "h1", "t2", "t1", "m1", "m2", "r1", "r2"] const MUR_WE_PRIO := ["h1", "r1", "m1", "t1", "t2", "m2", "r2", "h2"] +const KOR_WE_PRIO := ["h1", "t1", "t2", "m1", "m2", "r1", "r2", "h2"] const DEBUFF_ASSIGNMENTS := { "r_aero_sw": {AERO_ICON: 14, WYRMCLAW_ICON: 40, RETURN_ICON: 33}, "r_aero_se": {AERO_ICON: 14, WYRMCLAW_ICON: 40, RETURN_ICON: 33}, @@ -512,7 +513,10 @@ func move_post_exa_4(): ## 35.8 # Move to Rewind posistions. func move_rewind(): - move_party(party, CTPos.REWIND_REF[exaline_spawns]) + if strat in [Strat.NA, Strat.MUR]: + move_party(party, CTPos.REWIND_REF[exaline_spawns]) + elif strat == Strat.KOR: # Only care about North(0,1) and South(2,3) + move_party(party, CTPos.KOR_REWIND_REF[exaline_spawns]) ## 39.6 @@ -542,23 +546,36 @@ func snapshot_rewinds(): # We do this now to give the scanner enough frames to cross the entire arena. func clone_cast_spirit(): clone_cast_bar.cast_clone("Spirit Taker", 2.7, 1) - - # E/W Scan - if east_exa: - line_scanner.scan_line(v2(USURPER_POS["e"]), v2(USURPER_POS["w"]), 1.5) + if strat == Strat.KOR: + var target_keys = rewind_positions.keys() + if east_exa: + target_keys.sort_custom(func(a, b): + return rewind_positions[a].y > rewind_positions[b].y) + else: + target_keys.sort_custom(func(a, b): + return rewind_positions[a].y < rewind_positions[b].y) + ew_kb_targets = target_keys.slice(0, 4) else: - line_scanner.scan_line(v2(USURPER_POS["w"]), v2(USURPER_POS["e"]), 1.5) + # E/W Scan + if east_exa: + line_scanner.scan_line(v2(USURPER_POS["e"]), v2(USURPER_POS["w"]), 1.5) + else: + line_scanner.scan_line(v2(USURPER_POS["w"]), v2(USURPER_POS["e"]), 1.5) ## 40.6 # Move to post-rewind spread. func move_jump_spread(): - if exaline_spawns == Intercards.NW: - for key: String in CTPos.JUMP_SPREAD_NW: - party[key].move_to(CTPos.JUMP_SPREAD_NW[key]) - else: - for key: String in CTPos.JUMP_SPREAD_NE: - party[key].move_to(CTPos.JUMP_SPREAD_NE[key].rotated(arena_rotation[exaline_spawns])) + if strat == Strat.KOR: + for key: String in CTPos.KOR_JUMP_SPREAD: + party[key].move_to(CTPos.KOR_JUMP_SPREAD[key]) + elif strat in [Strat.NA, Strat.MUR]: + if exaline_spawns == Intercards.NW: + for key: String in CTPos.JUMP_SPREAD_NW: + party[key].move_to(CTPos.JUMP_SPREAD_NW[key]) + else: + for key: String in CTPos.JUMP_SPREAD_NE: + party[key].move_to(CTPos.JUMP_SPREAD_NE[key].rotated(arena_rotation[exaline_spawns])) ## 41.0 @@ -575,11 +592,21 @@ func tele_usurper_mid(): ## 42 # Run N/S scan func scan_rewind_ns(): - # First kb will come East to West - if north_exa: - line_scanner.scan_line(v2(USURPER_POS["n"]), v2(USURPER_POS["s"]), 1.5) + if strat == Strat.KOR: + var target_keys = rewind_positions.keys() + if north_exa: + target_keys.sort_custom(func(a, b): + return rewind_positions[a].x > rewind_positions[b].x) + else: + target_keys.sort_custom(func(a, b): + return rewind_positions[a].x < rewind_positions[b].x) + ns_kb_targets = target_keys.slice(0, 4) else: - line_scanner.scan_line(v2(USURPER_POS["s"]), v2(USURPER_POS["n"]), 1.5) + # First kb will come East to West + if north_exa: + line_scanner.scan_line(v2(USURPER_POS["n"]), v2(USURPER_POS["s"]), 1.5) + else: + line_scanner.scan_line(v2(USURPER_POS["s"]), v2(USURPER_POS["n"]), 1.5) func on_scan_finished(areas: Array): if areas.size() < 4: @@ -634,6 +661,17 @@ func jump_hit(): JUMP_LIFETIME, JUMP_COLOR, [1, 1, "Spirit Taker (Oracle Jump)", [pc]]) +## 45.6 +# Cast Arm's Length/Surecast for KOR strat +func cast_kb_resist(): + for key in party: + var pc: PlayableCharacter = party[key] + if pc.is_player() and !pc.spectate_mode: + continue + # TODO: connect to PlayerMovementController arms_length + arms_length(pc) + + ## 46.6 # Freeze players. # Assign stun debuffs (9s) @@ -706,7 +744,8 @@ func knockback_2_hit(): for key in ns_kb_targets: var pc: PlayableCharacter = get_char(key) if pc.has_debuff("magic_vuln"): - fail_list.add_fail(str(pc.get_name(), " failed Hallowed Wings (2 stacks of Magic Vuln)")) + if strat != Strat.KOR: + fail_list.add_fail(str(pc.get_name(), " failed Hallowed Wings (2 stacks of Magic Vuln)")) else: pc.add_debuff(MAGIC_VULN_ICON, MAGIC_VULN_DURATION) @@ -811,7 +850,7 @@ func instantiate_party(new_party: Dictionary) -> void: # Standard role keys party = new_party # NA/MUR Party setup - na_mur_party_setup() + na_mur_kor_party_setup() # Randomize Tether spawn nw_tether = randi() % 2 == 0 # Pick 3 Quietus targets @@ -829,12 +868,14 @@ func instantiate_party(new_party: Dictionary) -> void: north_exa = (exaline_spawns == Intercards.NE or exaline_spawns == Intercards.NW) -func na_mur_party_setup() -> void: +func na_mur_kor_party_setup() -> void: var we_prio if strat == Strat.NA: we_prio = NA_WE_PRIO elif strat == Strat.MUR: we_prio = MUR_WE_PRIO + elif strat == Strat.KOR: + we_prio = KOR_WE_PRIO # Shuffle dps/sup roles var shuffle_list := party.keys() @@ -919,6 +960,16 @@ func on_toggle_bots_visible() -> void: pc.visible = bots_visible +func arms_length(pc: PlayableCharacter) -> void: + var arms_length_duration := 6.0 + pc.kb_resist = true + var timer: Timer = Timer.new() + timer.wait_time = arms_length_duration + add_child(timer) + timer.timeout.connect(func() -> void: pc.kb_resist = false) + timer.start() + + func v2(vec3: Vector3) -> Vector2: return Vector2(vec3.x, vec3.z) diff --git a/scenes/p4/sequences/ct_positions.gd b/scenes/p4/sequences/ct_positions.gd index ba547e2..e7ce507 100644 --- a/scenes/p4/sequences/ct_positions.gd +++ b/scenes/p4/sequences/ct_positions.gd @@ -73,6 +73,8 @@ const M2_SPREAD_NW := Vector2(0, 14) const R1_SPREAD_NW := Vector2(-29, -29) const R2_SPREAD_NW := Vector2(29, 29) +const KOR_SPREAD := Vector2(20.5, 20.5) + # Akh Morn const AM_STACK_LEFT := Vector2(8, 0) const AM_STACK_RIGHT := Vector2(-8, 0) @@ -314,6 +316,20 @@ const REWIND_SW := { "r1": G1_PARTY_SW + RS1, "r2": G2_PARTY_SW + RS1, "h1": G1_PARTY_SW + RS2, "h2": G2_PARTY_SW + RS2 } +# KOR Rewind Positions +const KOR_REWIND_REF := [KOR_REWIND_N, KOR_REWIND_N, KOR_REWIND_S, KOR_REWIND_S] +const KOR_REWIND_N := { + "t1": FIRST_HG_DODGE * NW, "t2": FIRST_HG_DODGE * NE, + "m1": Vector2(5, 0) + RS1, "m2": Vector2(5, 0) + RS2, + "r1": Vector2(5, 0) + RS3, "r2": Vector2(5, 0) - RS1, + "h1": Vector2(5, 0) - RS2, "h2": Vector2(5, 0) - RS3 +} +const KOR_REWIND_S := { + "t1": FIRST_HG_DODGE * SW, "t2": FIRST_HG_DODGE * SE, + "m1": Vector2(-5, 0) + RS1, "m2": Vector2(-5, 0) + RS2, + "r1": Vector2(-5, 0) + RS3, "r2": Vector2(-5, 0) - RS1, + "h1": Vector2(-5, 0) - RS2, "h2": Vector2(-5, 0) - RS3 +} const JUMP_SPREAD_NE := { "t1": T1_SPREAD_NE, "t2": T2_SPREAD_NE, @@ -327,6 +343,11 @@ const JUMP_SPREAD_NW := { "r1": R1_SPREAD_NW, "r2": R2_SPREAD_NW, "h1": H1_SPREAD_NW, "h2": H2_SPREAD_NW } +const KOR_JUMP_SPREAD := { + "m1": KOR_SPREAD * SW, "m2": KOR_SPREAD * SE, + "r1": KOR_SPREAD * NW, "r2": KOR_SPREAD * NE, + "h1": Vector2(-29.0, 0), "h2": MID +} const AKH_MORN := { "t1": AM_STACK_LEFT, "t2": AM_STACK_RIGHT, diff --git a/scenes/p4/sequences/darklit_seq.gd b/scenes/p4/sequences/darklit_seq.gd index 6d3773b..078fd9e 100644 --- a/scenes/p4/sequences/darklit_seq.gd +++ b/scenes/p4/sequences/darklit_seq.gd @@ -5,7 +5,7 @@ extends Node -enum Strat {NA, EU, JP, MANA, MUR} +enum Strat {NA, EU, JP, MANA, MUR, KOR} enum DanceStrat {SHARED, T1SOLO, T2SOLO} # Debuff Icon Scenes @@ -66,6 +66,8 @@ const EU_JP_DPS_LINEUP := ["m1", "m2", "r1", "r2"] # W>E or S>N const EU_JP_WE_PRIO := ["t1", "t2", "h1", "h2", "m1", "m2", "r1", "r2"] # Mana Prio, matches lineup. const MANA_WE_PRIO := ["h1", "h2", "t1", "t2", "m1", "m2", "r1", "r2"] +# KOR Prio. +const KOR_SN_PRIO := ["t1", "t2", "h1", "h2", "m1", "m2", "r1", "r2"] # Entity Positions const USURPER_POS := {"final": Vector3(0, 0, -6), "final_rota": 135.0} @@ -152,7 +154,7 @@ func start_sequence(new_party: Dictionary) -> void: ## 2.0 # Move part mid func move_mid(): - if strat == Strat.MANA: + if strat in [Strat.MANA, Strat.KOR]: move_party(DDPos.MANA_STACK_PARTY) else: move_party(DDPos.MID_STACK_PARTY) @@ -181,6 +183,8 @@ func move_first_spread() -> void: move_party(DDPos.POST_AA_PARTY_JP) elif strat == Strat.MANA: move_party(DDPos.POST_AA_PARTY_MANA) + elif strat == Strat.KOR: + move_party(DDPos.POST_AA_PARTY_KOR) ## 9.3 # First AoE's hit on snapshot positions @@ -208,6 +212,8 @@ func move_lr_pre_pos(): move_party(DDPos.LR_PARTY_JP) elif strat == Strat.MANA: move_party(DDPos.LR_PARTY_MANA) + elif strat == Strat.KOR: + move_party(DDPos.LR_PARTY_KOR) ## 14.7 @@ -348,7 +354,7 @@ func move_spirit_spread(): pc.move_to(DDPos.SPIRIT_DD_SP_NA[key]) elif strat == Strat.EU: move_party_dd(DDPos.SPIRIT_DD_EU) - elif strat in [Strat.JP, Strat.MANA]: + elif strat in [Strat.JP, Strat.MANA, Strat.KOR]: move_party_dd(DDPos.SPIRIT_DD_JP) ## 35.5 @@ -628,6 +634,8 @@ func instantiate_party(new_party: Dictionary) -> void: # Vetical/EU setup elif strat in [Strat.EU, Strat.JP]: eu_jp_party_setup() + elif strat == Strat.KOR: + kor_party_setup() else: assert(false, "Error. Invalid Strat selection in party setup.") # Pick Usurper Jump target @@ -900,6 +908,135 @@ func eu_jp_party_setup() -> void: spirit_spread_dd["e_sup"] = party_dd["se_bait"] spirit_spread_dd["e_dps"] = party_dd["ne_bait"] + +func kor_party_setup() -> void: + # Shuffle tank, healers and dps (tank/healer/dps[0] + dps[1] will be LR tethers) + var tanks = Global.TANK_ROLE_KEYS.duplicate() + var healers = Global.HEALER_ROLE_KEYS.duplicate() + var dps = Global.DPS_ROLE_KEYS.duplicate() + tanks.shuffle() + healers.shuffle() + dps.shuffle() + + # If user is forcing tethers, swap player to tether index. + if Global.p4_dd_force_tether: + var player_key: String = get_tree().get_first_node_in_group("player").get_role() + if Global.TANK_ROLE_KEYS.has(player_key) and tanks[0] != player_key: + tanks[1] = tanks[0] + tanks[0] = player_key + elif Global.HEALER_ROLE_KEYS.has(player_key) and healers[0] != player_key: + healers[1] = healers[0] + healers[0] = player_key + elif Global.DPS_ROLE_KEYS.has(player_key) and (dps[0] != player_key and dps[1] != player_key): + var player_index = dps.find(player_key) + var swap_index = randi_range(0, 1) + dps[player_index] = dps[swap_index] + dps[swap_index] = player_key + + # Build shuffled tether link list (0 linked to 1 and 3, etc.) + tether_links.append(tanks[0]) + tether_links.append(dps[0]) + tether_links.append(dps[1]) + tether_links.shuffle() + # Add healer at index 0 (Healer always NW anchor) + tether_links.push_front(healers[0]) + + # Handle tether swap to make bowtie shape + # Use lineup to determine which dps is South/North + var lineup + if strat == Strat.KOR: + lineup = KOR_SN_PRIO + else: + assert(false, "Invalid Strat selection in KOR party setup.") + + var south_dps + var north_dps + if lineup.find(dps[0]) < lineup.find(dps[1]): + south_dps = dps[0] + north_dps = dps[1] + else: + north_dps = dps[0] + south_dps = dps[1] + # Default bowtie shape (no swaps needed) + var bowtie_tethers := [healers[0], north_dps, south_dps, tanks[0]] # [nw, ne, se, sw] + # Get the pair of keys linked to the healer + var linked_to_nw := [tether_links[1], tether_links[3]] + # If box shape, swap dps + if linked_to_nw.has(tanks[0]) and linked_to_nw.has(north_dps): + bowtie_tethers[1] = south_dps # ne + bowtie_tethers[2] = north_dps # se + # If hourglass shape, swap tank with west dps + elif linked_to_nw.has(north_dps) and linked_to_nw.has(south_dps): + bowtie_tethers[1] = tanks[0] # ne + bowtie_tethers[3] = north_dps # sw + + # Handle water debuffs and potential swap + var non_tethers := [healers[1], dps[2], dps[3], tanks[1]] # [nw, ne, se, sw] + # Store pre-swap positions, to be used for bot movement. + var pre_water_swap_non_tethers = non_tethers.duplicate() + # Pick Waters, swap non-tethers if they are on same N/S side. + var tether_water = bowtie_tethers.pick_random() + var non_tether_water = non_tethers.pick_random() + var west_swapped := false + var east_swapped := false + # Check if both waters are North + if (tether_water == bowtie_tethers[0] or tether_water == bowtie_tethers[1]) and\ + (non_tether_water == non_tethers[0] or non_tether_water == non_tethers[1]): + # 0 swaps with 3, 1 swaps with 2 + if non_tether_water == non_tethers[0]: + var temp = non_tethers[0] + non_tethers[0] = non_tethers[3] + non_tethers[3] = temp + west_swapped = true + elif non_tether_water == non_tethers[1]: + var temp = non_tethers[1] + non_tethers[1] = non_tethers[2] + non_tethers[2] = temp + east_swapped = true + # Check if both waters are South + elif (tether_water == bowtie_tethers[2] or tether_water == bowtie_tethers[3]) and\ + (non_tether_water == non_tethers[2] or non_tether_water == non_tethers[3]): + # 0 swaps with 3, 1 swaps with 2 + if non_tether_water == non_tethers[3]: + var temp = non_tethers[0] + non_tethers[0] = non_tethers[3] + non_tethers[3] = temp + west_swapped = true + elif non_tether_water == non_tethers[2]: + var temp = non_tethers[1] + non_tethers[1] = non_tethers[2] + non_tethers[2] = temp + east_swapped = true + assert(!(west_swapped and east_swapped), "Error in E/W swap logic.") + # Build party_dd Dictionary + party_dd = { + "nw_tether": bowtie_tethers[0], "ne_tether": bowtie_tethers[1], + "se_tether": bowtie_tethers[2], "sw_tether": bowtie_tethers[3], + "nw_bait": non_tethers[0], "ne_bait": non_tethers[1], + "se_bait": non_tethers[2], "sw_bait": non_tethers[3] + } + # Build pre-swap Dictionary (for positioning before waters swap) + pre_swap_party_dd = party_dd.duplicate() + pre_swap_party_dd["nw_bait"] = pre_water_swap_non_tethers[0] + pre_swap_party_dd["ne_bait"] = pre_water_swap_non_tethers[1] + pre_swap_party_dd["se_bait"] = pre_water_swap_non_tethers[2] + pre_swap_party_dd["sw_bait"] = pre_water_swap_non_tethers[3] + water_keys = [tether_water, non_tether_water] + # Build Spirit Spread Dictionary (need to distinguish Supp from DPS for spread positions). + spirit_spread_dd = { + "nw_tether": party_dd["nw_tether"], "ne_tether": party_dd["ne_tether"], + "se_tether": party_dd["se_tether"], "sw_tether": party_dd["sw_tether"], + "w_sup": party_dd["nw_bait"], "w_dps": party_dd["sw_bait"], + "e_sup": party_dd["ne_bait"], "e_dps": party_dd["se_bait"] + } + if west_swapped: + spirit_spread_dd["w_sup"] = party_dd["sw_bait"] + spirit_spread_dd["w_dps"] = party_dd["nw_bait"] + elif east_swapped: + spirit_spread_dd["e_sup"] = party_dd["se_bait"] + spirit_spread_dd["e_dps"] = party_dd["ne_bait"] + + # Returns the PlayableCharacter for the assigned key. func get_char(dd_key) -> PlayableCharacter: return party[party_dd[dd_key]] diff --git a/scenes/p4/sequences/dd_positions.gd b/scenes/p4/sequences/dd_positions.gd index 0fdbced..b904a36 100644 --- a/scenes/p4/sequences/dd_positions.gd +++ b/scenes/p4/sequences/dd_positions.gd @@ -104,6 +104,11 @@ const POST_AA_PARTY_MANA := { "t1": MID, "t2": MID + RS1, "h1": MID + RS2, "h2": MID + RS3, "m1": MID - RS1, "m2": MID - RS2, "r1": MID - RS3, "r2": MID } +# KOR +const POST_AA_PARTY_KOR := { + "t1": MID, "t2": MID + RS1, "h1": MID + RS2, "h2": MID + RS3, + "m1": MID - RS1, "m2": MID - RS2, "r1": MID - RS3, "r2": MID + } # Move to LR pre-pos, NA const LR_PARTY_NA := { @@ -133,6 +138,12 @@ const LR_PARTY_MANA := { "m1": LR_EW * SW + S_OFFSET, "m2": LR_NS * SW + S_OFFSET, "r1": LR_NS * SE + S_OFFSET, "r2": LR_EW * SE + S_OFFSET } +const LR_PARTY_KOR := { + "t1": LR_JP * NW + (S_OFFSET * 3), "t2": LR_JP * NW + (S_OFFSET * 2), + "h1": LR_JP * NW + S_OFFSET, "h2": LR_JP * NW, + "m1": LR_JP * NE + (S_OFFSET * 3), "m2": LR_JP * NE + (S_OFFSET * 2), + "r1": LR_JP * NE + S_OFFSET, "r2": LR_JP * NE + } # Bowtie positions const BOWTIE_DD := { From ab632d445faa2d77124c7d7d4acd8c94cf1ad26e Mon Sep 17 00:00:00 2001 From: sybaik1 Date: Mon, 5 May 2025 20:19:20 +0900 Subject: [PATCH 2/2] fix: p4_dd KOR strategy non tethers dps priority fix --- scenes/p4/sequences/darklit_seq.gd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scenes/p4/sequences/darklit_seq.gd b/scenes/p4/sequences/darklit_seq.gd index 078fd9e..31a0582 100644 --- a/scenes/p4/sequences/darklit_seq.gd +++ b/scenes/p4/sequences/darklit_seq.gd @@ -971,7 +971,7 @@ func kor_party_setup() -> void: bowtie_tethers[3] = north_dps # sw # Handle water debuffs and potential swap - var non_tethers := [healers[1], dps[2], dps[3], tanks[1]] # [nw, ne, se, sw] + var non_tethers := [healers[1], dps[3], dps[2], tanks[1]] # [nw, ne, se, sw] # Store pre-swap positions, to be used for bot movement. var pre_water_swap_non_tethers = non_tethers.duplicate() # Pick Waters, swap non-tethers if they are on same N/S side.