diff --git a/worlds/tunic/combat_logic.py b/worlds/tunic/combat_logic.py index e7409e212a..721d58deac 100644 --- a/worlds/tunic/combat_logic.py +++ b/worlds/tunic/combat_logic.py @@ -54,7 +54,7 @@ enemy_encounters: Dict[str, EncounterData] = { "Garden Knight": EncounterData(12, [[sword]], False), "Siege Engine": EncounterData(16), "Librarian": EncounterData(16, [[fire_wand], [gun]]), - "Boss Scavenger": EncounterData(24), + "Boss Scavenger": EncounterData(24, [[sword]], False), "Gauntlet": EncounterData(10, [[sword, fire_wand], [sword, gun]]), # the other heir requirements are included in the entrance rule for the heir fight "The Heir": EncounterData(28), @@ -98,24 +98,29 @@ def has_required_items(required_items: List[List[str]], stick_req: bool, state: def sum_power(state: CollectionState, player: int) -> int: return (get_att_power(state, player) + get_def_power(state, player) + get_potion_power(state, player) - + get_hp_power(state, player) + get_mp_power(state, player) + get_other_power(state, player)) + + get_hp_power(state, player) + get_mp_power(state, player) + get_sp_power(state, player) + + get_other_power(state, player)) def get_att_power(state: CollectionState, player: int) -> int: # no stick, no power if not has_melee(state, player): - return False - power = state.count_from_list({"ATT Offering", "Hero Relic - ATT"}, player) + return 0 + power = state.count_from_list({"ATT Offering", "Hero Relic - ATT"}, player) * 4 // 3 sword_upgrades = state.count("Sword Upgrade", player) - # +4 power from sword, +2 power for the next two sword (includes the attack buff from getting it) + # longer swords are effectively an extra attack upgrade in terms of how much better you do with range if sword_upgrades >= 2: - power += max(8, sword_upgrades * 2) + power += min(10, sword_upgrades * 8 // 3) + # stick doesn't scale super well in terms of damage, cap it at 4 power + if not has_sword(state, player): + power = min(4, power) return power # defense helps a lot when you're trying not to die, as it turns out def get_def_power(state: CollectionState, player: int) -> int: - return min(4, state.count_from_list({"DEF Offering", "Hero Relic - DEF", "Secret Legend", "Phonomath"}, player)) + def_upgrades = state.count_from_list({"DEF Offering", "Hero Relic - DEF", "Secret Legend", "Phonomath"}, player) + return min(4, def_upgrades * 2 // 3) # healing is kinda power, right? @@ -123,11 +128,11 @@ def get_potion_power(state: CollectionState, player: int) -> int: potion_count = state.count("Potion Flask", player) + state.count("Flask Shard", player) // 3 if potion_count == 0: return 0 - power = min(3, potion_count // 2) - # get potion upgrades - power += min(3, state.count_from_list({"Potion Offering", "Hero Relic - POTION", - "Just Some Pals", "Spring Falls", "Back To Work"}, player)) - return power + potion_upgrade_count = state.count_from_list({"Potion Offering", "Hero Relic - POTION", + "Just Some Pals", "Spring Falls", "Back To Work"}, player) + total_healing = potion_count * (30 + 10 * potion_upgrade_count) + # effectively .5 power per unupgraded flask + return min(6, total_healing // 60) def get_hp_power(state: CollectionState, player: int) -> int: @@ -139,12 +144,17 @@ def get_mp_power(state: CollectionState, player: int) -> int: return 0 # default 2 power for having a wand or gun. Having both doesn't increase it since they do basically the same thing power = 2 - # max of 3 power from mp gains + # max of 3 power from mp gains, get +.5 power per mp offering (since each is half a tick) power += min(3, state.count_from_list({"MP Offering", "Hero Relic - MP", - "Sacred Geometry", "Vintage", "Dusty"}, player)) + "Sacred Geometry", "Vintage", "Dusty"}, player) // 2) return power +def get_sp_power(state: CollectionState, player: int) -> int: + return min(2, state.count_from_list({"SP Offering", "Hero Relic - SP", + "Mr Mayor", "Power Up", "Regal Weasel", "Forever Friend"}, player) // 4) + + def get_other_power(state: CollectionState, player: int) -> int: power = 0 if state.has("Shield", player): diff --git a/worlds/tunic/items.py b/worlds/tunic/items.py index 6d73494d2b..0847324d77 100644 --- a/worlds/tunic/items.py +++ b/worlds/tunic/items.py @@ -52,8 +52,8 @@ item_table: Dict[str, TunicItemData] = { "Old House Key": TunicItemData(IC.progression, 1, 34, "Keys"), "Key": TunicItemData(IC.progression, 2, 35, "Keys"), "Fortress Vault Key": TunicItemData(IC.progression, 1, 36, "Keys"), - "Flask Shard": TunicItemData(IC.useful, 12, 37), - "Potion Flask": TunicItemData(IC.useful, 5, 38, "Flask"), + "Flask Shard": TunicItemData(IC.useful, 12, 37, combat_ic=IC.progression), + "Potion Flask": TunicItemData(IC.useful, 5, 38, "Flask", combat_ic=IC.progression), "Golden Coin": TunicItemData(IC.progression, 17, 39), "Card Slot": TunicItemData(IC.useful, 4, 40), "Red Questagon": TunicItemData(IC.progression_skip_balancing, 1, 41, "Hexagons"), @@ -65,13 +65,13 @@ item_table: Dict[str, TunicItemData] = { "Potion Offering": TunicItemData(IC.useful, 3, 47, "Offerings", combat_ic=IC.progression), "HP Offering": TunicItemData(IC.useful, 6, 48, "Offerings", combat_ic=IC.progression), "MP Offering": TunicItemData(IC.useful, 3, 49, "Offerings", combat_ic=IC.progression), - "SP Offering": TunicItemData(IC.useful, 2, 50, "Offerings"), + "SP Offering": TunicItemData(IC.useful, 2, 50, "Offerings", combat_ic=IC.progression), "Hero Relic - ATT": TunicItemData(IC.progression_skip_balancing, 1, 51, "Hero Relics", combat_ic=IC.progression), "Hero Relic - DEF": TunicItemData(IC.progression_skip_balancing, 1, 52, "Hero Relics", combat_ic=IC.progression), "Hero Relic - HP": TunicItemData(IC.progression_skip_balancing, 1, 53, "Hero Relics", combat_ic=IC.progression), "Hero Relic - MP": TunicItemData(IC.progression_skip_balancing, 1, 54, "Hero Relics", combat_ic=IC.progression), "Hero Relic - POTION": TunicItemData(IC.progression_skip_balancing, 1, 55, "Hero Relics", combat_ic=IC.progression), - "Hero Relic - SP": TunicItemData(IC.progression_skip_balancing, 1, 56, "Hero Relics"), + "Hero Relic - SP": TunicItemData(IC.progression_skip_balancing, 1, 56, "Hero Relics", combat_ic=IC.progression), "Orange Peril Ring": TunicItemData(IC.useful, 1, 57, "Cards"), "Tincture": TunicItemData(IC.useful, 1, 58, "Cards"), "Scavenger Mask": TunicItemData(IC.progression, 1, 59, "Cards"), @@ -88,18 +88,18 @@ item_table: Dict[str, TunicItemData] = { "Louder Echo": TunicItemData(IC.useful, 1, 70, "Cards"), "Aura's Gem": TunicItemData(IC.useful, 1, 71, "Cards"), "Bone Card": TunicItemData(IC.useful, 1, 72, "Cards"), - "Mr Mayor": TunicItemData(IC.useful, 1, 73, "Golden Treasures"), + "Mr Mayor": TunicItemData(IC.useful, 1, 73, "Golden Treasures", combat_ic=IC.progression), "Secret Legend": TunicItemData(IC.useful, 1, 74, "Golden Treasures", combat_ic=IC.progression), "Sacred Geometry": TunicItemData(IC.useful, 1, 75, "Golden Treasures", combat_ic=IC.progression), "Vintage": TunicItemData(IC.useful, 1, 76, "Golden Treasures", combat_ic=IC.progression), "Just Some Pals": TunicItemData(IC.useful, 1, 77, "Golden Treasures", combat_ic=IC.progression), - "Regal Weasel": TunicItemData(IC.useful, 1, 78, "Golden Treasures"), + "Regal Weasel": TunicItemData(IC.useful, 1, 78, "Golden Treasures", combat_ic=IC.progression), "Spring Falls": TunicItemData(IC.useful, 1, 79, "Golden Treasures", combat_ic=IC.progression), - "Power Up": TunicItemData(IC.useful, 1, 80, "Golden Treasures"), + "Power Up": TunicItemData(IC.useful, 1, 80, "Golden Treasures", combat_ic=IC.progression), "Back To Work": TunicItemData(IC.useful, 1, 81, "Golden Treasures", combat_ic=IC.progression), "Phonomath": TunicItemData(IC.useful, 1, 82, "Golden Treasures", combat_ic=IC.progression), "Dusty": TunicItemData(IC.useful, 1, 83, "Golden Treasures", combat_ic=IC.progression), - "Forever Friend": TunicItemData(IC.useful, 1, 84, "Golden Treasures"), + "Forever Friend": TunicItemData(IC.useful, 1, 84, "Golden Treasures", combat_ic=IC.progression), "Fool Trap": TunicItemData(IC.trap, 0, 85), "Money x1": TunicItemData(IC.filler, 3, 86, "Money"), "Money x10": TunicItemData(IC.filler, 1, 87, "Money"),