mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 12:11:33 -06:00

* Clean these functions up, get the hell out of here 5 parameter function * Clean up a bunch of rules that no longer need to be multi-lined since the functions are shorter * Clean up some range functions * Update to use world instead of player like Vi recommended * Fix merge conflict * Create new options * Slightly revise ls rule * Update options.py * Update options.py * Add tedious option for ls * Update laurels zips description * Create new options * Slightly revise ls rule * Update options.py * Update options.py * Add tedious option for ls * Update laurels zips description * Creating structures to redo ladder storage rules * Put together overworld ladder groups, remove tedious * Write up the rules for the regular rules * Update slot data and UT stuff * Put new ice grapple stuff in er rules * Ice grapple hard to get to fountain cross room * More ladder data * Wrote majority of overworld ladder rules * Finish the ladder storage rules * Update notes * Add note * Add well rail to the rules * More rules * Comment out logically irrelevant entrances * Update with laurels_zip helper * Add parameter to has_ice_grapple_logic for difficulty * Add new parameter to has_ice_grapple_logic * Move ice grapple chest to lower forest in ER/ladders * Fix rule * Finishing out hooking the new rules into the code * Fix bugs * Add more hard ice grapples * Fix more bugs * Shops my beloved * Change victory condition back * Remove debug stuff * Update plando connections description * Fix extremely rare bug * Add well front -> back hard ladder storages * Note in ls rules about knocking yourself down with bombs being out of logic * Add atoll fuse with wand + hard ls * Add some nonsense that boils down to activating the fuse in overworld * Further update LS description * Fix missing logic on bridge switch chest in upper zig * Revise upper zig rule change to account for ER * Fix merge conflict * Fix formatting, fix rule for heir access after merge * Add the shop sword logic stuff in * Remove todo that was already done * Fill out a to-do with some cursed nonsense * Fix event in wrong region * Fix missing cathedral -> elevator connection * Fix missing cathedral -> elevator connection * Add ER exception to cathedral -> elevator * Fix secret gathering place issue * Fix incorrect ls rule * Move 3 locations to Quarry Back since they're easily accessible from the back * Also update non-er region * Remove redundant parentheses * Add new test for a weird edge case in ER * Slight option description updates * Use has_ladder in spots where it wasn't used for some reason, add a comment * Fix unit test for ER * Update per exempt's suggestion * Add back LogicRules as an invisible option, to not break old yamls * Remove unused elevation from portal class * Update ladder storage without items description * Remove shop_scene stuff since it's no longer relevant in the mod by the time this version comes out * Remove shop scene stuff from game info since it's no longer relevant in the mod by the time this comes out * Update portal list to match main * god I love github merging things * Remove note * Add ice grapple hard path from upper overworld to temple rafters entrance * Actually that should be medium * Remove outdated note * Add ice grapple hard for swamp mid to the ledge * Add missing laurels zip in swamp * Some fixes to the ladder storage data while reviewing it * Add unit test for weird edge case * Backport outlet region system to fix ls bug * Fix incorrect ls, add todo * Add missing swamp ladder storage connections * Add swamp zip to er data * Add swamp zip to er rules * Add hard ice grapple for forest grave path main to upper * Add ice grapple logic for all bomb walls except the east quarry one * Add ice grapple logic for frog stairs eye to mouth without the ladder * Add hard ice grapple for overworld to the stairs to west garden * Add the ice grapple boss quick kills to medium ice grappling * Add the reverse connection for the ice grapple kill on Garden Knight * Add atoll house ice grapple push, and add west garden ice grapple entry to the regular rules
247 lines
15 KiB
Python
247 lines
15 KiB
Python
from itertools import groupby
|
|
from typing import Dict, List, Set, NamedTuple
|
|
from BaseClasses import ItemClassification
|
|
|
|
|
|
class TunicItemData(NamedTuple):
|
|
classification: ItemClassification
|
|
quantity_in_item_pool: int
|
|
item_id_offset: int
|
|
item_group: str = ""
|
|
|
|
|
|
item_base_id = 509342400
|
|
|
|
item_table: Dict[str, TunicItemData] = {
|
|
"Firecracker x2": TunicItemData(ItemClassification.filler, 3, 0, "Bombs"),
|
|
"Firecracker x3": TunicItemData(ItemClassification.filler, 3, 1, "Bombs"),
|
|
"Firecracker x4": TunicItemData(ItemClassification.filler, 3, 2, "Bombs"),
|
|
"Firecracker x5": TunicItemData(ItemClassification.filler, 1, 3, "Bombs"),
|
|
"Firecracker x6": TunicItemData(ItemClassification.filler, 2, 4, "Bombs"),
|
|
"Fire Bomb x2": TunicItemData(ItemClassification.filler, 2, 5, "Bombs"),
|
|
"Fire Bomb x3": TunicItemData(ItemClassification.filler, 1, 6, "Bombs"),
|
|
"Ice Bomb x2": TunicItemData(ItemClassification.filler, 2, 7, "Bombs"),
|
|
"Ice Bomb x3": TunicItemData(ItemClassification.filler, 2, 8, "Bombs"),
|
|
"Ice Bomb x5": TunicItemData(ItemClassification.filler, 1, 9, "Bombs"),
|
|
"Lure": TunicItemData(ItemClassification.filler, 4, 10, "Consumables"),
|
|
"Lure x2": TunicItemData(ItemClassification.filler, 1, 11, "Consumables"),
|
|
"Pepper x2": TunicItemData(ItemClassification.filler, 4, 12, "Consumables"),
|
|
"Ivy x3": TunicItemData(ItemClassification.filler, 2, 13, "Consumables"),
|
|
"Effigy": TunicItemData(ItemClassification.useful, 12, 14, "Money"),
|
|
"HP Berry": TunicItemData(ItemClassification.filler, 2, 15, "Consumables"),
|
|
"HP Berry x2": TunicItemData(ItemClassification.filler, 4, 16, "Consumables"),
|
|
"HP Berry x3": TunicItemData(ItemClassification.filler, 2, 17, "Consumables"),
|
|
"MP Berry": TunicItemData(ItemClassification.filler, 4, 18, "Consumables"),
|
|
"MP Berry x2": TunicItemData(ItemClassification.filler, 2, 19, "Consumables"),
|
|
"MP Berry x3": TunicItemData(ItemClassification.filler, 7, 20, "Consumables"),
|
|
"Fairy": TunicItemData(ItemClassification.progression, 20, 21),
|
|
"Stick": TunicItemData(ItemClassification.progression, 1, 22, "Weapons"),
|
|
"Sword": TunicItemData(ItemClassification.progression, 3, 23, "Weapons"),
|
|
"Sword Upgrade": TunicItemData(ItemClassification.progression, 4, 24, "Weapons"),
|
|
"Magic Wand": TunicItemData(ItemClassification.progression, 1, 25, "Weapons"),
|
|
"Magic Dagger": TunicItemData(ItemClassification.progression, 1, 26),
|
|
"Magic Orb": TunicItemData(ItemClassification.progression, 1, 27),
|
|
"Hero's Laurels": TunicItemData(ItemClassification.progression, 1, 28),
|
|
"Lantern": TunicItemData(ItemClassification.progression, 1, 29),
|
|
"Gun": TunicItemData(ItemClassification.progression, 1, 30, "Weapons"),
|
|
"Shield": TunicItemData(ItemClassification.useful, 1, 31),
|
|
"Dath Stone": TunicItemData(ItemClassification.useful, 1, 32),
|
|
"Hourglass": TunicItemData(ItemClassification.useful, 1, 33),
|
|
"Old House Key": TunicItemData(ItemClassification.progression, 1, 34, "Keys"),
|
|
"Key": TunicItemData(ItemClassification.progression, 2, 35, "Keys"),
|
|
"Fortress Vault Key": TunicItemData(ItemClassification.progression, 1, 36, "Keys"),
|
|
"Flask Shard": TunicItemData(ItemClassification.useful, 12, 37),
|
|
"Potion Flask": TunicItemData(ItemClassification.useful, 5, 38, "Flask"),
|
|
"Golden Coin": TunicItemData(ItemClassification.progression, 17, 39),
|
|
"Card Slot": TunicItemData(ItemClassification.useful, 4, 40),
|
|
"Red Questagon": TunicItemData(ItemClassification.progression_skip_balancing, 1, 41, "Hexagons"),
|
|
"Green Questagon": TunicItemData(ItemClassification.progression_skip_balancing, 1, 42, "Hexagons"),
|
|
"Blue Questagon": TunicItemData(ItemClassification.progression_skip_balancing, 1, 43, "Hexagons"),
|
|
"Gold Questagon": TunicItemData(ItemClassification.progression_skip_balancing, 0, 44, "Hexagons"),
|
|
"ATT Offering": TunicItemData(ItemClassification.useful, 4, 45, "Offerings"),
|
|
"DEF Offering": TunicItemData(ItemClassification.useful, 4, 46, "Offerings"),
|
|
"Potion Offering": TunicItemData(ItemClassification.useful, 3, 47, "Offerings"),
|
|
"HP Offering": TunicItemData(ItemClassification.useful, 6, 48, "Offerings"),
|
|
"MP Offering": TunicItemData(ItemClassification.useful, 3, 49, "Offerings"),
|
|
"SP Offering": TunicItemData(ItemClassification.useful, 2, 50, "Offerings"),
|
|
"Hero Relic - ATT": TunicItemData(ItemClassification.progression_skip_balancing, 1, 51, "Hero Relics"),
|
|
"Hero Relic - DEF": TunicItemData(ItemClassification.progression_skip_balancing, 1, 52, "Hero Relics"),
|
|
"Hero Relic - HP": TunicItemData(ItemClassification.progression_skip_balancing, 1, 53, "Hero Relics"),
|
|
"Hero Relic - MP": TunicItemData(ItemClassification.progression_skip_balancing, 1, 54, "Hero Relics"),
|
|
"Hero Relic - POTION": TunicItemData(ItemClassification.progression_skip_balancing, 1, 55, "Hero Relics"),
|
|
"Hero Relic - SP": TunicItemData(ItemClassification.progression_skip_balancing, 1, 56, "Hero Relics"),
|
|
"Orange Peril Ring": TunicItemData(ItemClassification.useful, 1, 57, "Cards"),
|
|
"Tincture": TunicItemData(ItemClassification.useful, 1, 58, "Cards"),
|
|
"Scavenger Mask": TunicItemData(ItemClassification.progression, 1, 59, "Cards"),
|
|
"Cyan Peril Ring": TunicItemData(ItemClassification.useful, 1, 60, "Cards"),
|
|
"Bracer": TunicItemData(ItemClassification.useful, 1, 61, "Cards"),
|
|
"Dagger Strap": TunicItemData(ItemClassification.useful, 1, 62, "Cards"),
|
|
"Inverted Ash": TunicItemData(ItemClassification.useful, 1, 63, "Cards"),
|
|
"Lucky Cup": TunicItemData(ItemClassification.useful, 1, 64, "Cards"),
|
|
"Magic Echo": TunicItemData(ItemClassification.useful, 1, 65, "Cards"),
|
|
"Anklet": TunicItemData(ItemClassification.useful, 1, 66, "Cards"),
|
|
"Muffling Bell": TunicItemData(ItemClassification.useful, 1, 67, "Cards"),
|
|
"Glass Cannon": TunicItemData(ItemClassification.useful, 1, 68, "Cards"),
|
|
"Perfume": TunicItemData(ItemClassification.useful, 1, 69, "Cards"),
|
|
"Louder Echo": TunicItemData(ItemClassification.useful, 1, 70, "Cards"),
|
|
"Aura's Gem": TunicItemData(ItemClassification.useful, 1, 71, "Cards"),
|
|
"Bone Card": TunicItemData(ItemClassification.useful, 1, 72, "Cards"),
|
|
"Mr Mayor": TunicItemData(ItemClassification.useful, 1, 73, "Golden Treasures"),
|
|
"Secret Legend": TunicItemData(ItemClassification.useful, 1, 74, "Golden Treasures"),
|
|
"Sacred Geometry": TunicItemData(ItemClassification.useful, 1, 75, "Golden Treasures"),
|
|
"Vintage": TunicItemData(ItemClassification.useful, 1, 76, "Golden Treasures"),
|
|
"Just Some Pals": TunicItemData(ItemClassification.useful, 1, 77, "Golden Treasures"),
|
|
"Regal Weasel": TunicItemData(ItemClassification.useful, 1, 78, "Golden Treasures"),
|
|
"Spring Falls": TunicItemData(ItemClassification.useful, 1, 79, "Golden Treasures"),
|
|
"Power Up": TunicItemData(ItemClassification.useful, 1, 80, "Golden Treasures"),
|
|
"Back To Work": TunicItemData(ItemClassification.useful, 1, 81, "Golden Treasures"),
|
|
"Phonomath": TunicItemData(ItemClassification.useful, 1, 82, "Golden Treasures"),
|
|
"Dusty": TunicItemData(ItemClassification.useful, 1, 83, "Golden Treasures"),
|
|
"Forever Friend": TunicItemData(ItemClassification.useful, 1, 84, "Golden Treasures"),
|
|
"Fool Trap": TunicItemData(ItemClassification.trap, 0, 85),
|
|
"Money x1": TunicItemData(ItemClassification.filler, 3, 86, "Money"),
|
|
"Money x10": TunicItemData(ItemClassification.filler, 1, 87, "Money"),
|
|
"Money x15": TunicItemData(ItemClassification.filler, 10, 88, "Money"),
|
|
"Money x16": TunicItemData(ItemClassification.filler, 1, 89, "Money"),
|
|
"Money x20": TunicItemData(ItemClassification.filler, 17, 90, "Money"),
|
|
"Money x25": TunicItemData(ItemClassification.filler, 14, 91, "Money"),
|
|
"Money x30": TunicItemData(ItemClassification.filler, 4, 92, "Money"),
|
|
"Money x32": TunicItemData(ItemClassification.filler, 4, 93, "Money"),
|
|
"Money x40": TunicItemData(ItemClassification.filler, 3, 94, "Money"),
|
|
"Money x48": TunicItemData(ItemClassification.filler, 1, 95, "Money"),
|
|
"Money x50": TunicItemData(ItemClassification.filler, 7, 96, "Money"),
|
|
"Money x64": TunicItemData(ItemClassification.filler, 1, 97, "Money"),
|
|
"Money x100": TunicItemData(ItemClassification.filler, 5, 98, "Money"),
|
|
"Money x128": TunicItemData(ItemClassification.useful, 3, 99, "Money"),
|
|
"Money x200": TunicItemData(ItemClassification.useful, 1, 100, "Money"),
|
|
"Money x255": TunicItemData(ItemClassification.useful, 1, 101, "Money"),
|
|
"Pages 0-1": TunicItemData(ItemClassification.useful, 1, 102, "Pages"),
|
|
"Pages 2-3": TunicItemData(ItemClassification.useful, 1, 103, "Pages"),
|
|
"Pages 4-5": TunicItemData(ItemClassification.useful, 1, 104, "Pages"),
|
|
"Pages 6-7": TunicItemData(ItemClassification.useful, 1, 105, "Pages"),
|
|
"Pages 8-9": TunicItemData(ItemClassification.useful, 1, 106, "Pages"),
|
|
"Pages 10-11": TunicItemData(ItemClassification.useful, 1, 107, "Pages"),
|
|
"Pages 12-13": TunicItemData(ItemClassification.useful, 1, 108, "Pages"),
|
|
"Pages 14-15": TunicItemData(ItemClassification.useful, 1, 109, "Pages"),
|
|
"Pages 16-17": TunicItemData(ItemClassification.useful, 1, 110, "Pages"),
|
|
"Pages 18-19": TunicItemData(ItemClassification.useful, 1, 111, "Pages"),
|
|
"Pages 20-21": TunicItemData(ItemClassification.useful, 1, 112, "Pages"),
|
|
"Pages 22-23": TunicItemData(ItemClassification.useful, 1, 113, "Pages"),
|
|
"Pages 24-25 (Prayer)": TunicItemData(ItemClassification.progression, 1, 114, "Pages"),
|
|
"Pages 26-27": TunicItemData(ItemClassification.useful, 1, 115, "Pages"),
|
|
"Pages 28-29": TunicItemData(ItemClassification.useful, 1, 116, "Pages"),
|
|
"Pages 30-31": TunicItemData(ItemClassification.useful, 1, 117, "Pages"),
|
|
"Pages 32-33": TunicItemData(ItemClassification.useful, 1, 118, "Pages"),
|
|
"Pages 34-35": TunicItemData(ItemClassification.useful, 1, 119, "Pages"),
|
|
"Pages 36-37": TunicItemData(ItemClassification.useful, 1, 120, "Pages"),
|
|
"Pages 38-39": TunicItemData(ItemClassification.useful, 1, 121, "Pages"),
|
|
"Pages 40-41": TunicItemData(ItemClassification.useful, 1, 122, "Pages"),
|
|
"Pages 42-43 (Holy Cross)": TunicItemData(ItemClassification.progression, 1, 123, "Pages"),
|
|
"Pages 44-45": TunicItemData(ItemClassification.useful, 1, 124, "Pages"),
|
|
"Pages 46-47": TunicItemData(ItemClassification.useful, 1, 125, "Pages"),
|
|
"Pages 48-49": TunicItemData(ItemClassification.useful, 1, 126, "Pages"),
|
|
"Pages 50-51": TunicItemData(ItemClassification.useful, 1, 127, "Pages"),
|
|
"Pages 52-53 (Icebolt)": TunicItemData(ItemClassification.progression, 1, 128, "Pages"),
|
|
"Pages 54-55": TunicItemData(ItemClassification.useful, 1, 129, "Pages"),
|
|
"Ladders near Weathervane": TunicItemData(ItemClassification.progression, 0, 130, "Ladders"),
|
|
"Ladders near Overworld Checkpoint": TunicItemData(ItemClassification.progression, 0, 131, "Ladders"),
|
|
"Ladders near Patrol Cave": TunicItemData(ItemClassification.progression, 0, 132, "Ladders"),
|
|
"Ladder near Temple Rafters": TunicItemData(ItemClassification.progression, 0, 133, "Ladders"),
|
|
"Ladders near Dark Tomb": TunicItemData(ItemClassification.progression, 0, 134, "Ladders"),
|
|
"Ladder to Quarry": TunicItemData(ItemClassification.progression, 0, 135, "Ladders"),
|
|
"Ladders to West Bell": TunicItemData(ItemClassification.progression, 0, 136, "Ladders"),
|
|
"Ladders in Overworld Town": TunicItemData(ItemClassification.progression, 0, 137, "Ladders"),
|
|
"Ladder to Ruined Atoll": TunicItemData(ItemClassification.progression, 0, 138, "Ladders"),
|
|
"Ladder to Swamp": TunicItemData(ItemClassification.progression, 0, 139, "Ladders"),
|
|
"Ladders in Well": TunicItemData(ItemClassification.progression, 0, 140, "Ladders"),
|
|
"Ladder in Dark Tomb": TunicItemData(ItemClassification.progression, 0, 141, "Ladders"),
|
|
"Ladder to East Forest": TunicItemData(ItemClassification.progression, 0, 142, "Ladders"),
|
|
"Ladders to Lower Forest": TunicItemData(ItemClassification.progression, 0, 143, "Ladders"),
|
|
"Ladder to Beneath the Vault": TunicItemData(ItemClassification.progression, 0, 144, "Ladders"),
|
|
"Ladders in Hourglass Cave": TunicItemData(ItemClassification.progression, 0, 145, "Ladders"),
|
|
"Ladders in South Atoll": TunicItemData(ItemClassification.progression, 0, 146, "Ladders"),
|
|
"Ladders to Frog's Domain": TunicItemData(ItemClassification.progression, 0, 147, "Ladders"),
|
|
"Ladders in Library": TunicItemData(ItemClassification.progression, 0, 148, "Ladders"),
|
|
"Ladders in Lower Quarry": TunicItemData(ItemClassification.progression, 0, 149, "Ladders"),
|
|
"Ladders in Swamp": TunicItemData(ItemClassification.progression, 0, 150, "Ladders"),
|
|
}
|
|
|
|
# items to be replaced by fool traps
|
|
fool_tiers: List[List[str]] = [
|
|
[],
|
|
["Money x1", "Money x10", "Money x15", "Money x16"],
|
|
["Money x1", "Money x10", "Money x15", "Money x16", "Money x20"],
|
|
["Money x1", "Money x10", "Money x15", "Money x16", "Money x20", "Money x25", "Money x30"],
|
|
]
|
|
|
|
# items we'll want the location of in slot data, for generating in-game hints
|
|
slot_data_item_names = [
|
|
"Stick",
|
|
"Sword",
|
|
"Sword Upgrade",
|
|
"Magic Dagger",
|
|
"Magic Wand",
|
|
"Magic Orb",
|
|
"Hero's Laurels",
|
|
"Lantern",
|
|
"Gun",
|
|
"Scavenger Mask",
|
|
"Shield",
|
|
"Dath Stone",
|
|
"Hourglass",
|
|
"Old House Key",
|
|
"Fortress Vault Key",
|
|
"Hero Relic - ATT",
|
|
"Hero Relic - DEF",
|
|
"Hero Relic - POTION",
|
|
"Hero Relic - HP",
|
|
"Hero Relic - SP",
|
|
"Hero Relic - MP",
|
|
"Pages 24-25 (Prayer)",
|
|
"Pages 42-43 (Holy Cross)",
|
|
"Pages 52-53 (Icebolt)",
|
|
"Red Questagon",
|
|
"Green Questagon",
|
|
"Blue Questagon",
|
|
"Gold Questagon",
|
|
]
|
|
|
|
item_name_to_id: Dict[str, int] = {name: item_base_id + data.item_id_offset for name, data in item_table.items()}
|
|
|
|
filler_items: List[str] = [name for name, data in item_table.items() if data.classification == ItemClassification.filler]
|
|
|
|
|
|
def get_item_group(item_name: str) -> str:
|
|
return item_table[item_name].item_group
|
|
|
|
|
|
item_name_groups: Dict[str, Set[str]] = {
|
|
group: set(item_names) for group, item_names in groupby(sorted(item_table, key=get_item_group), get_item_group) if group != ""
|
|
}
|
|
|
|
# extra groups for the purpose of aliasing items
|
|
extra_groups: Dict[str, Set[str]] = {
|
|
"Laurels": {"Hero's Laurels"},
|
|
"Orb": {"Magic Orb"},
|
|
"Dagger": {"Magic Dagger"},
|
|
"Wand": {"Magic Wand"},
|
|
"Magic Rod": {"Magic Wand"},
|
|
"Fire Rod": {"Magic Wand"},
|
|
"Holy Cross": {"Pages 42-43 (Holy Cross)"},
|
|
"Prayer": {"Pages 24-25 (Prayer)"},
|
|
"Icebolt": {"Pages 52-53 (Icebolt)"},
|
|
"Ice Rod": {"Pages 52-53 (Icebolt)"},
|
|
"Melee Weapons": {"Stick", "Sword", "Sword Upgrade"},
|
|
"Progressive Sword": {"Sword Upgrade"},
|
|
"Abilities": {"Pages 24-25 (Prayer)", "Pages 42-43 (Holy Cross)", "Pages 52-53 (Icebolt)"},
|
|
"Questagons": {"Red Questagon", "Green Questagon", "Blue Questagon", "Gold Questagon"},
|
|
"Ladder to Atoll": {"Ladder to Ruined Atoll"}, # fuzzy matching made it hint Ladders in Well, now it won't
|
|
"Ladders to Bell": {"Ladders to West Bell"},
|
|
"Ladders to Well": {"Ladders in Well"}, # fuzzy matching decided Ladders in Well was Ladders to West Bell
|
|
"Ladders in Atoll": {"Ladders in South Atoll"},
|
|
"Ladders in Ruined Atoll": {"Ladders in South Atoll"},
|
|
"Ladders in Town": {"Ladders in Overworld Town"}, # fuzzy matching decided this was Ladders in South Atoll
|
|
}
|
|
|
|
item_name_groups.update(extra_groups)
|