From 1873c52aa6f66fb79657555098d6c8e2efc9dada Mon Sep 17 00:00:00 2001 From: Seldom <38388947+Seldom-SE@users.noreply.github.com> Date: Tue, 15 Apr 2025 06:51:05 -0700 Subject: [PATCH] Terraria: 1.4.4 and Calamity support (#3847) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Terraria integration * Precollected items for debugging * Fix item classification * Golem requires Plantera's Bulb * Pumpkin Moon requires Dungeon * Progressive Dungeon * Reorg, Options.py work * Items are boss flags * Removed unused option * Removed nothing * Wall, Plantera, and Zenith goals * Achievements and items * Fixed The Cavalry and Completely Awesome achievements * Made "Dead Men Tell No Tales" a grindy achievement * Some docs, Python 3.8 compat * docs * Fix extra item and "Head in the Clouds" being included when achievements are disabled * Requested changes * Fix potential thread unsafety, replace Nothing with 50 Silver * Remove a log * Corrected heading * Added incompatible mods list * In-progress calamity integration * Terraria events progress * Rules use events * Removed an intentional crash I accidentally left in * Fixed infinite loop * Moved rules to data file * Moved item rewards to data file * Generating from data file * Fixed broken Mech Boss goal * Changes Calamity makes to vanilla rules, Calamity final bosses goal * Added Deerclops, fixed Zenith goal * Final detailed vanilla pass * Disable calamity goals * Typo * Fixed some reward items not adding to item pool * In-progress unit test fixes * Unit test fixes * `.apworld` compat * Organized rewards file, made Frog Leg and Fllpper available in vanilla * Water Walking Boots and Titan Glove rewards * Add goals to slot data * Fixed Hammush logic in Post-Mech goal * Fixed coin rewards * Updated Terraria docs * Formatted * Deathlink in-progress * Boots of the Hero is grindy * Fixed zenith goal not placing an item * Address review * Gelatin World Tour is grindy * Difficulty notice * Switched some achievements' grindiness * Added "Hey! Listen!" achievement * Terarria Python 3.8 compat * Fixed Terraria You and What Army logic * Calamity minion accessories * Typo * Calamity integration * `deathlink` -> `death_link` Co-authored-by: Zach Parks * Missing `.` Co-authored-by: Zach Parks * Incorrect type annotation Co-authored-by: Zach Parks * `deathlink` -> `death_link` 2 Co-authored-by: Zach Parks * Style Co-authored-by: Zach Parks * Markdown style Co-authored-by: Zach Parks * Markdown style 2 Co-authored-by: Zach Parks * Address review * Fix bad merge * Terraria utility mod recommendations * Calamity minion armor logic * ArmorMinions -> Armor Minions, boss rush goal, fixed unplaced item * Fixed unplaced item * Started on Terraria 1.4.4 * Crate logic * getfixedboi, 1.4.4 achievements, shimmer, town slimes, `Rule`, `Condition`, etc * More clam getfixedboi logic, bar decraft logic, `NotGetfixedboi` -> `Not Getfixedboi` * Calamity fixes * Calamity crate ore logic * Fixed item accessibility not generating in getfixedboi, fixed not generating with incompatible options, fixed grindy function * Early achievements, separate achievement category options * Infinity +1 Sword achievement can be location in later goals * The Frequent Flyer is impossible in Calamity getfixedboi * Add Enchanted Sword and Starfury for starting inventories * Don't Dread on Me is redundant in Calamity * In Calamity getfixedboi, Queen Bee summons enemies who drop Plague Cell Canisters * Can't use Gelatin Crystal outside Hallow * You can't get the Terminus without flags * Typo * Options difficult warnings * Robbing the Grave is Hardmode * Don't reserve an ID for unused Victory item * Plantera is accessible early in Calamity via Giant Plantera's Bulbs * Unshuffled Life Crystal and Defender Medal items * Comment about Midas' Blessing * Update worlds/terraria/Options.py Co-authored-by: Scipio Wright * Remove stray expression Co-authored-by: Scipio Wright * Review suggestions * Option naming caps consistency, add Laser Drill, Lunatic Cultist alt reqs, fix Eldritch Soul Artifact, Ceaseless Void reqs Dungeon * Cal Clone doesn't drop Broken Hero Sword anymore, Laser Drill is weaker in Calamity Co-authored-by: Seatori <92278897+Seatori@users.noreply.github.com> * Fix Acid Rain logic * Fix XB-∞ Hekate failing accessibility checks (by commenting it out bc it doesn't affect logic) * Hardmode ores being fishable early in Calamity is not a bug anymore * Mecha Mayhem is inaccessible in getfixedboi * Update worlds/terraria/Rules.dsv Co-authored-by: Seafo <92278897+Seatori@users.noreply.github.com> --------- Co-authored-by: Fabian Dill Co-authored-by: Zach Parks Co-authored-by: Scipio Wright Co-authored-by: Seatori <92278897+Seatori@users.noreply.github.com> --- worlds/terraria/Checks.py | 245 +++++++++++-------- worlds/terraria/Options.py | 73 ++++-- worlds/terraria/Rewards.dsv | 12 +- worlds/terraria/Rules.dsv | 465 ++++++++++++++++++++++++------------ worlds/terraria/__init__.py | 247 ++++++++++--------- 5 files changed, 661 insertions(+), 381 deletions(-) diff --git a/worlds/terraria/Checks.py b/worlds/terraria/Checks.py index 0630d629..53e66262 100644 --- a/worlds/terraria/Checks.py +++ b/worlds/terraria/Checks.py @@ -157,24 +157,57 @@ COND_FN = 2 COND_GROUP = 3 +class Condition: + def __init__( + self, + # True = positive, False = negative + sign: bool, + # See the `COND_*` constants + type: int, + # Condition name or list + condition: Union[str, Tuple[Union[bool, None], List["Condition"]]], + argument: Union[str, int, None], + ): + self.sign = sign + self.type = type + self.condition = condition + self.argument = argument + + +class Rule: + def __init__( + self, + name: str, + # Name to arg + flags: Dict[str, Union[str, int, None]], + # True = or, False = and, None = N/A + operator: Union[bool, None], + conditions: List[Condition], + ): + self.name = name + self.flags = flags + self.operator = operator + self.conditions = conditions + + def validate_conditions( rule: str, rule_indices: dict, - conditions: List[ - Tuple[ - bool, int, Union[str, Tuple[Union[bool, None], list]], Union[str, int, None] - ] - ], + conditions: List[Condition], ): - for _, type, condition, _ in conditions: - if type == COND_ITEM: - if condition not in rule_indices: - raise Exception(f"item `{condition}` in `{rule}` is not defined") - elif type == COND_LOC: - if condition not in rule_indices: - raise Exception(f"location `{condition}` in `{rule}` is not defined") - elif type == COND_FN: - if condition not in { + for condition in conditions: + if condition.type == COND_ITEM: + if condition.condition not in rule_indices: + raise Exception( + f"item `{condition.condition}` in `{rule}` is not defined" + ) + elif condition.type == COND_LOC: + if condition.condition not in rule_indices: + raise Exception( + f"location `{condition.condition}` in `{rule}` is not defined" + ) + elif condition.type == COND_FN: + if condition.condition not in { "npc", "calamity", "grindy", @@ -182,43 +215,48 @@ def validate_conditions( "hammer", "mech_boss", "minions", + "getfixedboi", }: - raise Exception(f"function `{condition}` in `{rule}` is not defined") - elif type == COND_GROUP: - _, conditions = condition + raise Exception( + f"function `{condition.condition}` in `{rule}` is not defined" + ) + elif condition.type == COND_GROUP: + _, conditions = condition.condition validate_conditions(rule, rule_indices, conditions) def mark_progression( - conditions: List[ - Tuple[ - bool, int, Union[str, Tuple[Union[bool, None], list]], Union[str, int, None] - ] - ], + conditions: List[Condition], progression: Set[str], rules: list, rule_indices: dict, loc_to_item: dict, ): - for _, type, condition, _ in conditions: - if type == COND_ITEM: - prog = condition in progression - progression.add(loc_to_item[condition]) - _, flags, _, conditions = rules[rule_indices[condition]] + for condition in conditions: + if condition.type == COND_ITEM: + prog = condition.condition in progression + progression.add(loc_to_item[condition.condition]) + rule = rules[rule_indices[condition.condition]] if ( not prog - and "Achievement" not in flags - and "Location" not in flags - and "Item" not in flags + and "Achievement" not in rule.flags + and "Location" not in rule.flags + and "Item" not in rule.flags ): mark_progression( - conditions, progression, rules, rule_indices, loc_to_item + rule.conditions, progression, rules, rule_indices, loc_to_item ) - elif type == COND_LOC: - _, _, _, conditions = rules[rule_indices[condition]] - mark_progression(conditions, progression, rules, rule_indices, loc_to_item) - elif type == COND_GROUP: - _, conditions = condition + elif condition.type == COND_LOC: + + mark_progression( + rules[rule_indices[condition.condition]].conditions, + progression, + rules, + rule_indices, + loc_to_item, + ) + elif condition.type == COND_GROUP: + _, conditions = condition.condition mark_progression(conditions, progression, rules, rule_indices, loc_to_item) @@ -226,29 +264,7 @@ def read_data() -> Tuple[ # Goal to rule index that ends that goal's range and the locations required List[Tuple[int, Set[str]]], # Rules - List[ - Tuple[ - # Rule - str, - # Flag to flag arg - Dict[str, Union[str, int, None]], - # True = or, False = and, None = N/A - Union[bool, None], - # Conditions - List[ - Tuple[ - # True = positive, False = negative - bool, - # Condition type - int, - # Condition name or list (True = or, False = and, None = N/A) (list shares type with outer) - Union[str, Tuple[Union[bool, None], List]], - # Condition arg - Union[str, int, None], - ] - ], - ] - ], + List[Rule], # Rule to rule index Dict[str, int], # Label to rewards @@ -379,7 +395,7 @@ def read_data() -> Tuple[ unexpected(line, char, id, token, pos, POS_FMT, "Rules.dsv") elif pos == COND_OR_SEMI: if id == IDENT: - conditions.append((sign, COND_ITEM, token, None)) + conditions.append(Condition(sign, COND_ITEM, token, None)) sign = True pos = POST_COND elif id == HASH: @@ -424,14 +440,14 @@ def read_data() -> Tuple[ ) condition = operator, conditions sign, operator, conditions = outer.pop() - conditions.append((sign, COND_GROUP, condition, None)) + conditions.append(Condition(sign, COND_GROUP, condition, None)) sign = True pos = POST_COND else: unexpected(line, char, id, token, pos, POS_FMT, "Rules.dsv") elif pos == COND: if id == IDENT: - conditions.append((sign, COND_ITEM, token, None)) + conditions.append(Condition(sign, COND_ITEM, token, None)) sign = True pos = POST_COND elif id == HASH: @@ -449,7 +465,7 @@ def read_data() -> Tuple[ unexpected(line, char, id, token, pos, POS_FMT, "Rules.dsv") elif pos == LOC: if id == IDENT: - conditions.append((sign, COND_LOC, token, None)) + conditions.append(Condition(sign, COND_LOC, token, None)) sign = True pos = POST_COND else: @@ -464,10 +480,10 @@ def read_data() -> Tuple[ if id == LPAREN: pos = FN_ARG elif id == SEMI: - conditions.append((sign, COND_FN, function, None)) + conditions.append(Condition(sign, COND_FN, function, None)) pos = END elif id == AND: - conditions.append((sign, COND_FN, function, None)) + conditions.append(Condition(sign, COND_FN, function, None)) sign = True if operator is True: raise Exception( @@ -476,7 +492,7 @@ def read_data() -> Tuple[ operator = False pos = COND elif id == OR: - conditions.append((sign, COND_FN, function, None)) + conditions.append(Condition(sign, COND_FN, function, None)) sign = True if operator is False: raise Exception( @@ -485,21 +501,21 @@ def read_data() -> Tuple[ operator = True pos = COND elif id == RPAREN: - conditions.append((sign, COND_FN, function, None)) + conditions.append(Condition(sign, COND_FN, function, None)) if not outer: raise Exception( f"found `)` at {line + 1}:{char + 1} without matching `(`" ) condition = operator, conditions sign, operator, conditions = outer.pop() - conditions.append((sign, COND_GROUP, condition, None)) + conditions.append(Condition(sign, COND_GROUP, condition, None)) sign = True pos = POST_COND else: unexpected(line, char, id, token, pos, POS_FMT, "Rules.dsv") elif pos == FN_ARG: if id == IDENT or id == NUM: - conditions.append((sign, COND_FN, function, token)) + conditions.append(Condition(sign, COND_FN, function, token)) sign = True pos = FN_ARG_END else: @@ -527,7 +543,33 @@ def read_data() -> Tuple[ f"rule `{name}` on line `{line + 1}` shadows a previous rule" ) rule_indices[name] = len(rules) - rules.append((name, flags, operator, conditions)) + rules.append(Rule(name, flags, operator, conditions)) + + for flag in flags: + if flag not in { + "Location", + "Item", + "Goal", + "Early", + "Achievement", + "Grindy", + "Fishing", + "Npc", + "Pickaxe", + "Hammer", + "Minions", + "Armor Minions", + "Mech Boss", + "Final Boss", + "Getfixedboi", + "Not Getfixedboi", + "Calamity", + "Not Calamity", + "Not Calamity Getfixedboi", + }: + raise Exception( + f"rule `{name}` on line `{line + 1}` has unrecognized flag `{flag}`" + ) if "Item" in flags: item_name = flags["Item"] or f"Post-{name}" @@ -558,7 +600,7 @@ def read_data() -> Tuple[ final_bosses.append(flags["Item"] or f"Post-{name}") final_boss_loc.append(name) - if (minions := flags.get("ArmorMinions")) is not None: + if (minions := flags.get("Armor Minions")) is not None: armor_minions[name] = minions if (minions := flags.get("Minions")) is not None: @@ -572,16 +614,19 @@ def read_data() -> Tuple[ goal_indices[goal] = len(goals) goals.append((len(rules), set())) - for name, flags, _, _ in rules: - if "Goal" in flags: - _, items = goals[ - goal_indices[ - name.translate(str.maketrans("", "", string.punctuation)) + for rule in rules: + if "Goal" in rule.flags: + if (name := rule.flags.get("Goal")) is not None: + goal_name = name + else: + goal_name = ( + rule.name.translate(str.maketrans("", "", string.punctuation)) .replace(" ", "_") .lower() - ] - ] - items.add(name) + ) + + _, items = goals[goal_indices[goal_name]] + items.add(rule.name) _, mech_boss_items = goals[goal_indices["mechanical_bosses"]] mech_boss_items.update(mech_boss_loc) @@ -589,24 +634,27 @@ def read_data() -> Tuple[ _, final_boss_items = goals[goal_indices["calamity_final_bosses"]] final_boss_items.update(final_boss_loc) - for name, _, _, conditions in rules: - validate_conditions(name, rule_indices, conditions) + for rule in rules: + validate_conditions(rule.name, rule_indices, rule.conditions) - for name, flags, _, conditions in rules: + for rule in rules: prog = False if ( - "Npc" in flags - or "Goal" in flags - or "Pickaxe" in flags - or "Hammer" in flags - or "Mech Boss" in flags - or "Minions" in flags - or "ArmorMinions" in flags + "Npc" in rule.flags + or "Goal" in rule.flags + or "Pickaxe" in rule.flags + or "Hammer" in rule.flags + or "Mech Boss" in rule.flags + or "Final Boss" in rule.flags + or "Minions" in rule.flags + or "Armor Minions" in rule.flags ): - progression.add(loc_to_item[name]) + progression.add(loc_to_item[rule.name]) prog = True - if prog or "Location" in flags or "Achievement" in flags: - mark_progression(conditions, progression, rules, rule_indices, loc_to_item) + if prog or "Location" in rule.flags or "Achievement" in rule.flags: + mark_progression( + rule.conditions, progression, rules, rule_indices, loc_to_item + ) # Will be randomized via `slot_randoms` / `self.multiworld.random` label = None @@ -685,16 +733,15 @@ def read_data() -> Tuple[ next_id += 1 item_name_to_id["Reward: Coins"] = next_id - item_name_to_id["Victory"] = next_id + 1 - next_id += 2 + next_id += 1 location_name_to_id = {} - for name, flags, _, _ in rules: - if "Location" in flags or "Achievement" in flags: - if name in location_name_to_id: - raise Exception(f"location `{name}` shadows a previous location") - location_name_to_id[name] = next_id + for rule in rules: + if "Location" in rule.flags or "Achievement" in rule.flags: + if rule.name in location_name_to_id: + raise Exception(f"location `{rule.name}` shadows a previous location") + location_name_to_id[rule.name] = next_id next_id += 1 return ( diff --git a/worlds/terraria/Options.py b/worlds/terraria/Options.py index 4c4b9605..f5056e4a 100644 --- a/worlds/terraria/Options.py +++ b/worlds/terraria/Options.py @@ -1,40 +1,70 @@ from dataclasses import dataclass -from Options import Choice, DeathLink, PerGameCommonOptions +from Options import Choice, DeathLink, PerGameCommonOptions, Toggle, DefaultOnToggle + + +class Calamity(Toggle): + """Calamity mod bosses and events are shuffled""" + + display_name = "Calamity Mod Integration" + + +class Getfixedboi(Toggle): + """Generation accomodates the secret, very difficult "getfixedboi" seed""" + + display_name = """"getfixedboi" Seed""" class Goal(Choice): - """The victory condition for your run. Stuff after the goal will not be shuffled.""" + """ + The victory condition for your run. Stuff after the goal will not be shuffled. + Primordial Wyrm and Boss Rush are accessible relatively early, so consider "Items" or + "Locations" accessibility to avoid getting stuck on the goal. + """ display_name = "Goal" option_mechanical_bosses = 0 - # option_calamitas_clone = 1 + option_calamitas_clone = 1 option_plantera = 2 option_golem = 3 option_empress_of_light = 4 option_lunatic_cultist = 5 - # option_astrum_deus = 6 + option_astrum_deus = 6 option_moon_lord = 7 - # option_providence_the_profaned_goddess = 8 - # option_devourer_of_gods = 9 - # option_yharon_dragon_of_rebirth = 10 + option_providence_the_profaned_goddess = 8 + option_devourer_of_gods = 9 + option_yharon_dragon_of_rebirth = 10 option_zenith = 11 - # option_calamity_final_bosses = 12 - # option_adult_eidolon_wyrm = 13 + option_calamity_final_bosses = 12 + option_primordial_wyrm = 13 + option_boss_rush = 14 default = 0 -class Achievements(Choice): +class EarlyAchievements(DefaultOnToggle): + """Adds checks upon collecting early Pre-Hardmode achievements. Adds many sphere 1 checks.""" + + display_name = "Early Pre-Hardmode Achievements" + + +class NormalAchievements(DefaultOnToggle): """ - Adds checks upon collecting achievements. Achievements for clearing bosses and events are excluded. - "Exclude Grindy" also excludes fishing achievements. + Adds checks upon collecting achivements not covered by the other options. Achievements for + clearing bosses and events are excluded. """ - display_name = "Achievements" - option_none = 0 - option_exclude_grindy = 1 - option_exclude_fishing = 2 - option_all = 3 - default = 1 + display_name = "Normal Achievements" + + +class GrindyAchievements(Toggle): + """Adds checks upon collecting grindy achievements""" + + display_name = "Grindy Achievements" + + +class FishingAchievements(Toggle): + """Adds checks upon collecting fishing quest achievements""" + + display_name = "Fishing Quest Achievements" class FillExtraChecksWith(Choice): @@ -51,7 +81,12 @@ class FillExtraChecksWith(Choice): @dataclass class TerrariaOptions(PerGameCommonOptions): + calamity: Calamity + getfixedboi: Getfixedboi goal: Goal - achievements: Achievements + early_achievements: EarlyAchievements + normal_achievements: NormalAchievements + grindy_achievements: GrindyAchievements + fishing_achievements: FishingAchievements fill_extra_checks_with: FillExtraChecksWith death_link: DeathLink diff --git a/worlds/terraria/Rewards.dsv b/worlds/terraria/Rewards.dsv index dbae37b4..c8fb9696 100644 --- a/worlds/terraria/Rewards.dsv +++ b/worlds/terraria/Rewards.dsv @@ -121,10 +121,9 @@ Corrupt Flask; Calamity; Crimson Flask; Calamity; Craw Carapace; Calamity; Giant Shell; Calamity; -Fungal Carapace; Calamity; Life Jelly; Calamity; Vital Jelly; Calamity; -Mana Jelly; Calamity; +Cleansing Jelly; Calamity; Giant Tortoise Shell; Calamity; Coin of Deceit; Calamity; Ink Bomb; Calamity; @@ -151,4 +150,11 @@ Depths Charm; Calamity; Anechoic Plating; Calamity; Iron Boots; Calamity; Sprit Glyph; Calamity; -Abyssal Amulet; Calamity; \ No newline at end of file +Abyssal Amulet; Calamity; + +# unshuffled + +Life Crystal; +Enchanted Sword; +Starfury; +Defender Medal; \ No newline at end of file diff --git a/worlds/terraria/Rules.dsv b/worlds/terraria/Rules.dsv index 322bf9c5..9ae82d74 100644 --- a/worlds/terraria/Rules.dsv +++ b/worlds/terraria/Rules.dsv @@ -1,43 +1,57 @@ -// TODO Calamity minion armor +// For the logic to account for all skips, these rules would need to be made much more comprehensive // Starting gear Copper Shortsword; Guide; Npc; // Immediately accessible -Timber!!; Achievement; -Benched; Achievement; -Stop! Hammer Time!; Achievement; -Matching Attire; Achievement; -Fashion Statement; Achievement; -Ooo! Shiny!; Achievement; -No Hobo; Achievement; +Squire Slime; Npc; +Traveling Merchant; ; @npc(2); +Lifeform Analyzer; ; Traveling Merchant; +DPS Meter; ; Traveling Merchant | (@calamity & Wire); +Stopwatch; ; Traveling Merchant; +Timber!!; Achievement | Early; +Benched; Achievement | Early; +Stop! Hammer Time!; Achievement | Early; +Matching Attire; Achievement | Early; +Fashion Statement; Achievement | Early; +Ooo! Shiny!; Achievement | Early; +No Hobo; Achievement | Early; // When NPC shuffling is added, this shouldn't be considered early Merchant; Npc; Bug Net; ; @calamity | Merchant; -Heavy Metal; Achievement; -Nurse; Npc; Merchant; -The Frequent Flyer; Achievement; Nurse; -Demolitionist; Npc; Merchant; +Heavy Metal; Achievement | Early; Dye Trader; Npc; @npc(4); Dye Hard; Achievement; Dye Trader; -Lucky Break; Achievement; -Star Power; Achievement; -You Can Do It!; Achievement; +Demolitionist; Npc; Merchant; +Lucky Break; Achievement | Early; +Star Power; Achievement | Early; +You Can Do It!; Achievement | Early; +Wulfrum Battery; Calamity; +Wulfrum Armor; Calamity | Armor Minions(1); // Surface exploration +Cactus; +Unusual Survival Strategies; Achievement | Early; Aglet; +Radar; +Wand of Sparking; Heliophobia; Achievement; Blighted Gel; Calamity; +Evil Powder; Archaeologist; Achievement | Grindy; Zoologist; Npc; Cat; Npc; Zoologist; Feeling Petty; Achievement; Cat | Dog; Dog; Npc; Zoologist; +Painter; Npc; @npc(8); A Rather Blustery Day; Achievement | Grindy; Enchanted Sword; Pretty in Pink; Achievement | Grindy; Marathon Medalist; Achievement | Grindy; Angler; Npc; +Fisherman's Pocket Guide; ; Angler | Weather Radio; +Weather Radio; ; Angler | Sextant; +Sextant; ; Angler | Fisherman's Pocket Guide; Servant-in-Training; Achievement | Fishing; Angler; \10 Fishing Quests; Achievement | Fishing; Angler; Trout Monkey; Achievement | Fishing; Angler; @@ -45,52 +59,69 @@ Glorious Golden Pole; Achievement | Fishing; Fast and Fishious; Achievement | Fishing; Angler; Supreme Helper Minion!; Achievement | Fishing; Angler; Water Walking Boots; -Painter; Npc; @npc(8); +Aquatic Heart; Calamity; // Sky exploration -Into Orbit; Achievement; +Into Orbit; Achievement | Early; Mysterious Circuitry; Calamity; Dubious Plating; Calamity; Charging Station; Calamity; Codebreaker Base; Calamity; Starfury; +Celestial Magnet; +Clumsy Slime; Npc; // Underground -Watch Your Step!; Achievement; -Throwing Lines; Achievement; +Watch Your Step!; Achievement | Early; +Throwing Lines; Achievement | Early; Torch God; Location | Item(Reward: Torch God's Favor); -Vehicular Manslaughter; Achievement; -Hey! Listen!; Achievement; +Vehicular Manslaughter; Achievement | Early; +Ancient Bone Dust; Calamity; +Depth Meter; +Compass; +Hey! Listen!; Achievement | Early; I Am Loot!; Achievement; +Magic Mirror; Heart Breaker; Achievement; -Hold on Tight!; Achievement; +Nurse; Npc; Merchant; +The Frequent Flyer; Not Calamity Getfixedboi | Achievement; Nurse; +Feast of Midas; Achievement; Bug Net; +Hold on Tight!; Achievement | Early; Feller of Evergreens; Calamity; Gold Hammer; Hammer(55); Gold Pickaxe; Pickaxe(55); +Gold Watch; Like a Boss; Achievement; Hermes Boots; Jeepers Creepers; Achievement; Stylist; Npc; Funkytown; Achievement; Deceiver of Fools; Achievement | Grindy; +Metal Detector; Dead Men Tell No Tales; Achievement; Bulldozer; Achievement | Grindy; // Cavern Obsidian; Obsidian Skull; ; Obsidian; +Raider's Talisman; Calamity; Obsidian; There are Some Who Call Him...; Achievement | Grindy; Lava Charm; Demonite Ore; -Demonite Bar; ; Demonite Ore | (@calamity & #Calamity Evil Boss); +Demonite Bar; ; Demonite Ore; Evil Sword; ; Demonite Bar; +Coin of Deceit; Calamity; Demonite Bar | Ruin Medallion; // Underground Ice Ice Skates; -Flinx Fur Coat; ArmorMinions(1); +Flinx Fur Coat; Armor Minions(1); // Underground Desert +Stormlion Mandible; Calamity; Golfer; Npc; +Party Girl; Npc; @npc(14); +Jolly Jamboree; Achievement | Grindy; Party Girl; +Cool Slime; Npc; Party Girl; // Sunken Sea Sea Prism; Calamity; @@ -98,37 +129,50 @@ Navyplate; Calamity; // Underground Jungle Anklet of the Wind; +Feral Claws; Stinger; Jungle Spores; Vine; Blade of Grass; ; Stinger & Jungle Spores & Vine; +Nature's Gift; +Bezoar; Summoning Potion; Minions(1); +// The Aether +A Shimmer In The Dark; Achievement; + // Underworld It's Getting Hot in Here; Achievement; Rock Bottom; Achievement; Obsidian Rose; Havocplate; Calamity; +Magma Stone; // Evil Smashing, Poppet!; Achievement; Arms Dealer; Npc; Leading Landlord; Achievement; Nurse & Arms Dealer; // The logic is way more complex, but that doesn't affect anything Completely Awesome; Achievement; Arms Dealer; +Illegal Gun Parts; ; Arms Dealer | Flamethrower; + +// Abyss +Ink Bomb; Calamity; // King Slime King Slime; Location | Item; -Sticky Situation; Achievement | Grindy; +Sticky Situation; Not Getfixedboi | Achievement | Grindy; The Cavalry; Achievement; Solidifier; ; #King Slime; +Nerdy Slime; Npc; #King Slime; // Desert Scourge Desert Scourge; Calamity | Location | Item; Pearl Shard; Calamity; #Desert Scourge; Sea Remains; Calamity; Pearl Shard; Reefclaw Hamaxe; Calamity | Hammer(60); Sea Remains; +Victide Armor; Calamity | Armor Minions(1); Sea Remains; Sandstorm; ; ~@calamity | Desert Scourge; -Voltaic Jelly; Calamity | Minions(1); Desert Scourge; // Jelly-Charged Battery doesn't stack. This is the case for all Calamity minion accessory upgrades. +Voltaic Jelly; Calamity | Minions(1); Desert Scourge | Jelly-Charged Battery; // Jelly-Charged Battery doesn't stack. This is the case for all Calamity minion accessory upgrades. // Giant Clam Giant Clam; Calamity | Location | Item; Desert Scourge; @@ -136,18 +180,21 @@ Amidias; Calamity; // Blood Moon Bloodbath; Achievement | Grindy; +Blood Orb; Calamity; +Shark Tooth Necklace; Til Death...; Achievement | Grindy; -Quiet Neighborhood; Achievement; +Quiet Neighborhood; Achievement | Early; +Surly Slime; Npc; // Eye of Cthulhu Eye of Cthulhu; Location | Item; Dryad; Npc; Eye of Cthulhu | Evil Boss | Skeletron; Pumpkin Seeds; ; Dryad; -Pumpkin; ; Pumpkin Seeds; -Purification Powder; ; Dryad; // Shimmered from Evil Powder in 1.4.4. Not bought from Dryad in get fixed boi. -Party Girl; Npc; @npc(14); -Jolly Jamboree; Achievement | Grindy; Party Girl; -Acid Rain Tier 1; Calamity | Location | Item; Eye of Cthulhu; +Pumpkin; ; Pumpkin Seeds | Cactus; +Purification Powder; ; (~@getfixedboi & Dryad) | Evil Powder; +Mystic Slime; Npc; Purification Powder; +And Good Riddance!; Achievement | Grindy; Dryad; +Acid Rain Tier 1; Calamity | Location | Item; Eye of Cthulhu | Wall of Flesh | Aquatic Scourge; // Crabulon Crabulon; Calamity | Location | Item; @@ -156,112 +203,160 @@ Crabulon; Calamity | Location | Item; Evil Boss; Location | Item; Evil Boss Part; ; #Evil Boss; Evil Pickaxe; Pickaxe(65); Evil Boss Part; -Obsidian Armor; ArmorMinions(1); Obsidian & Evil Boss Part; +Obsidian Armor; Armor Minions(1); Obsidian & Evil Boss Part; Tavernkeep; Npc; Evil Boss; Old One's Army Tier 1; Location | Item; Tavernkeep; -Meteorite; ; Evil Boss; -Meteorite Bar; ; Meteorite; +Meteorite; ; #Evil Boss | Evil Boss | Meteorite Bar | (@calamity & Astral Infection); +Meteorite Bar; ; Meteorite | (@calamity & Astral Infection) | Meteor Staff; Meteor Hamaxe; Hammer(60); Meteorite Bar; Hellforge; ; @pickaxe(60); -Hellstone; ; @pickaxe(65) | Wall of Flesh; +Hellstone; ; @pickaxe(65) | Wall of Flesh | Hellstone Bar; Hellstone Bar; ; Hellstone; Fiery Greatsword; ; Hellstone Bar; Molten Hamaxe; Hammer(70); Hellstone Bar; Molten Pickaxe; Pickaxe(100); Hellstone Bar; Miner for Fire; Achievement; Molten Pickaxe; -Hot Reels!; Achievement; Hellstone Bar & Bug Net; // TODO Calamity +Hot Reels!; Achievement; Hellstone Bar & (@calamity | Bug Net); Brimstone Slag; Calamity; @pickaxe(100); // Goblin Army Goblin Army; Location | Item; Goblin Tinkerer; Npc; Goblin Army; Tinkerer's Workshop; ; Goblin Tinkerer; +Mana Flower; ; (Tinkerer's Workshop & Nature's Gift) | (@calamity & Ethereal Talisman); +Silencing Sheath; Calamity; (Tinkerer's Workshop & Demonite Bar & Evil Boss Part) | Dark Matter Sheath; Rocket Boots; ; Goblin Tinkerer; Spectre Boots; ; Tinkerer's Workshop & Hermes Boots & Rocket Boots; Lightning Boots; ; Tinkerer's Workshop & Spectre Boots & Anklet of the Wind & Aglet; Frostspark Boots; ; Tinkerer's Workshop & Lightning Boots & Ice Skates; Lava Waders; ; Tinkerer's Workshop & Obsidian Skull & Lava Charm & Obsidian Rose & Water Walking Boots; Terraspark Boots; ; Tinkerer's Workshop & Frostspark Boots & Lava Waders; +GPS; ; Tinkerer's Workshop & Depth Meter & Gold Watch & Compass; +Goblin Tech; ; Tinkerer's Workshop & DPS Meter & Stopwatch & Metal Detector; +Fish Finder; ; Tinkerer's Workshop & Fisherman's Pocket Guide & Weather Radio & Sextant; Boots of the Hero; Achievement | Grindy; Terraspark Boots; +Diving Gear; ; Tinkerer's Workshop; // Queen Bee Where's My Honey?; Achievement; Queen Bee; Location | Item; Bee Keeper; ; #Queen Bee; Bee Wax; ; #Queen Bee; -Bee Armor; ArmorMinions(2); Bee Wax; +Bee Armor; Armor Minions(2); Bee Wax; Not the Bees!; Achievement; #Queen Bee & Bee Armor; Witch Doctor; Npc; Queen Bee; -Pygmy Necklace; Minions(1); Witch Doctor; +Pygmy Necklace; Minions(1); Witch Doctor | (@calamity & Statis' Blessing); // Calamity Evil Boss -Calamity Evil Boss; Calamity | Location | Item; -Aerialite Ore; Calamity; Calamity Evil Boss & @pickaxe(65); -Aerialite Bar; Calamity; Aerialite Ore; +The Hive Mind; Calamity | Location | Item; +The Perforators; Calamity | Location | Item; +Blood Sample; Calamity; #The Perforators; +Aerialite Ore; Calamity; The Hive Mind | The Perforators | Cobalt Ore | Aerialite Bar; // No pick needed; can be fished +Aerialite Bar; Calamity; Aerialite Ore | Feather Crown; Aerial Hamaxe; Calamity | Hammer(70); Aerialite Bar; Skyfringe Pickaxe; Calamity | Pickaxe(75); Aerialite Bar; +Aerospec Armor; Calamity | Armor Minions(1); Aerialite Bar; +Feather Crown; Calamity; Aerialite Bar | Moonstone Crown; // Skeletron Skeletron; Location | Item; Clothier; Npc; Skeletron; Dungeon; ; Skeletron; Dungeon Heist; Achievement; Dungeon; -Bone; ; Dungeon | (@calamity & #Skeletron); -Bewitching Table; Minions(1); Dungeon | (Witch Doctor & Wizard); +Bone; ; Dungeon | (@calamity & (#Skeletron | (@getfixedboi & #Ravager) | Mirage Mirror)); +Mirage Mirror; Calamity; (Tinkerer's Workshop & Bone) | Abyssal Mirror; +Tally Counter; ; Dungeon; +R.E.K. 3000; ; Tinkerer's Workshop & Radar & Tally Counter & Lifeform Analyzer; +PDA; ; Tinkerer's Workshop & GPS & R.E.K. 3000 & Goblin Tech & Fish Finder; +Cell Phone; ; (Tinkerer's Workshop & Magic Mirror & PDA) | (@getfixedboi & @calamity & #Polterghast); +Black Mirror; Achievement | Grindy; Cell Phone; +Bewitching Table; Minions(1); Dungeon | (Witch Doctor & Wizard) | Alchemy Table; +Alchemy Table; ; Dungeon | Bewitching Table; Mechanic; ; Dungeon; -Wire; ; Mechanic; +Wire; ; Mechanic | (@calamity & Electrician's Glove); Decryption Computer; Calamity; Mysterious Circuitry & Dubious Plating & Wire; Actuator; ; Mechanic; Muramasa; ; Dungeon; +Cobalt Shield; ; Dungeon | (@calamity & Cobalt Bar); +Obsidian Shield; ; Tinkerer's Workshop & Cobalt Shield & Obsidian Skull; +Elder Slime; Npc; Skeletron & Dungeon; // Deerclops Deerclops; Location | Item; // The Slime God The Slime God; Calamity | Location | Item; Blighted Gel; -Purified Gel; Calamity; #The Slime God; +Purified Gel; Calamity; #The Slime God | Jelly-Charged Battery; +Jelly-Charged Battery; Calamity; (Wulfrum Battery & Voltaic Jelly & Purified Gel & Stormlion Mandible) | Star-Tainted Generator; Static Refiner; Calamity; Purified Gel & Solidifier; Gelpick; Calamity | Pickaxe(100); Static Refiner & Purified Gel & Blighted Gel; +Statigel Armor; Calamity | Armor Minions(1); Static Refiner & Purified Gel & Blighted Gel; Night's Edge; ; Evil Sword & Muramasa & Blade of Grass & Fiery Greatsword & (~@calamity | Purified Gel); // Wall of Flesh Wall of Flesh; Location | Item(Hardmode); Guide; Pwnhammer; Hammer(80); #Wall of Flesh; +Emblem; ; #Wall of Flesh | Avenger Emblem | (@calamity & (Mechanical Glove | Celestial Emblem | Statis' Blessing)); +Fast Clock; ; Wall of Flesh | Trifold Map | (@calamity & Wire & Pixie Dust & Soul of Light); Wizard; Npc; Wall of Flesh; -Tax Collector; Npc; Purification Powder & Wall of Flesh; +Titan Glove; ; Wall of Flesh | Power Glove; +Power Glove; ; Tinkerer's Workshop & Titan Glove & Feral Claws; +Magic Quiver; ; Wall of Flesh | (@calamity & Elemental Quiver); +Hallowed Seeds; ; (Wall of Flesh & Dryad) | Holy Water; +Armor Polish; ; Wall of Flesh | Vitamins | (@calamity & Bone & Ancient Bone Dust); +Adhesive Bandage; ; @calamity | Wall of Flesh; +Medicated Bandage; ; Tinkerer's Workshop & Bezoar & Adhesive Bandage; +Megaphone; ; Wall of Flesh | Nazar | (@calamity & Wire & Cobalt Bar); +Pocket Mirror; ; Wall of Flesh | Blindfold | (@calamity & Crystal Shard & Soul of Night); +Trifold Map; ; Wall of Flesh | Fast Clock | (@calamity & Soul of Light & Soul of Night); +The Plan; ; Tinkerer's Workshop & Trifold Map & Fast Clock; +Tax Collector; Npc; (Purification Powder & Wall of Flesh) | @getfixedboi; Spider Fangs; ; Wall of Flesh; -Spider Armor; ArmorMinions(3); Spider Fangs; +Spider Armor; Armor Minions(3); Spider Fangs; Cross Necklace; ; Wall of Flesh; Altar; ; Wall of Flesh & @hammer(80); Begone, Evil!; Achievement; Altar; -Cobalt Ore; ; (((~@calamity & Altar) | (@calamity & Wall of Flesh)) & @pickaxe(100)) | Wall of Flesh; +Cobalt Ore; ; (((~@calamity & Altar) | (@calamity & Wall of Flesh)) & @pickaxe(100)) | Wall of Flesh | Mythril Ore | Cobalt Bar; Extra Shiny!; Achievement; Cobalt Ore | Mythril Ore | Adamantite Ore | Chlorophyte Ore; -Cobalt Bar; ; Cobalt Ore | Wall of Flesh; +Cobalt Bar; ; Cobalt Ore | (@calamity & Lunic Eye) | Wall of Flesh; Cobalt Pickaxe; Pickaxe(110); Cobalt Bar; -Soul of Night; ; Wall of Flesh | (@calamity & Altar); +Blindfold; ; @calamity | Wall of Flesh | Pocket Mirror; +Reflective Shades; ; Tinkerer's Workshop & Blindfold & Pocket Mirror; +Vitamins; ; Wall of Flesh | Armor Polish | (@calamity & Alchemy Table & Blood Orb); +Armor Bracing; ; Tinkerer's Workshop & Vitamins & Armor Polish; +Nazar; ; Wall of Flesh | Megaphone | (@calamity & Soul of Night); +Countercurse Mantra; ; Tinkerer's Workshop & Nazar & Megaphone; +Ankh Charm; ; Tinkerer's Workshop & Reflective Shades & Armor Bracing & Medicated Bandage & Countercurse Mantra & The Plan; +Ankh Shield; ; Tinkerer's Workshop & Obsidian Shield & Ankh Charm; +Ankhumulation Complete; Achievement | Grindy; Ankh Shield; +Soul of Night; ; Wall of Flesh | (@calamity & (Altar | (@getfixedboi & #Duke Fishron))); Hallow; ; Wall of Flesh; -Pixie Dust; ; Hallow; +Pixie Dust; ; Hallow | Meteor Staff | Holy Water; +Holy Water; ; (Pixie Dust & Hallowed Seeds) | (@calamity & Statis' Blessing); Unicorn Horn; ; Hallow; Crystal Shard; ; Hallow; Axe of Purity; Calamity; Feller of Evergreens & Purification Powder & Pixie Dust & Crystal Shard; -Soul of Light; ; Hallow | (@calamity & #Queen Slime); +Fabsol's Vodka; Calamity; (Pixie Dust & Crystal Shard & Unicorn Horn) | (@getfixedboi & #Empress of Light); +Soul of Light; ; Hallow | (@calamity & (#Queen Slime | (@getfixedboi & #Duke Fishron))) | Light Disc | Meteor Staff; +Meteor Staff; ; (Hardmode Anvil & Meteorite Bar & Pixie Dust & Soul of Light) | Asteroid Staff; Blessed Apple; ; Hallow; Rod of Discord; ; Hallow; Gelatin World Tour; Achievement | Grindy; Dungeon & Wall of Flesh & Hallow & #King Slime; Soul of Flight; ; Wall of Flesh; -Head in the Clouds; Achievement; @grindy | (Soul of Flight & ((Hardmode Anvil & (Soul of Light | Soul of Night | Pixie Dust | Wall of Flesh | Solar Eclipse | @mech_boss(1) | Plantera | Spectre Bar | #Golem)) | (Shroomite Bar & Autohammer) | #Mourning Wood | #Pumpking)) | Steampunker | (Wall of Flesh & Witch Doctor) | (Solar Eclipse & Plantera) | #Everscream | #Old One's Army Tier 3 | #Empress of Light | #Duke Fishron | (Fragment & Luminite Bar & Ancient Manipulator); // Leaf Wings are Post-Plantera in 1.4.4 +Head in the Clouds; Achievement; @grindy | (Soul of Flight & ((Hardmode Anvil & (Soul of Light | Soul of Night | Pixie Dust | Wall of Flesh | Solar Eclipse | @mech_boss(1) | Plantera | Spectre Bar | #Golem)) | (Shroomite Bar & Autohammer) | #Mourning Wood | #Pumpking)) | Steampunker | (Wall of Flesh & Plantera & Witch Doctor) | (Solar Eclipse & Plantera) | #Everscream | #Old One's Army Tier 3 | #Empress of Light | #Duke Fishron | (Fragment & Luminite Bar & Ancient Manipulator); Bunny; Npc; Zoologist & Wall of Flesh; // Extremely simplified Forbidden Fragment; ; Sandstorm & Wall of Flesh; -Astral Infection; Calamity; Wall of Flesh; -Stardust; Calamity; Astral Infection | #Astrum Aureus | #Astrum Deus; +Astral Infection; Calamity; Wall of Flesh | Astrum Aureus; +Stardust; Calamity; Astral Infection | #Astrum Aureus | #Astrum Deus | Eye of Magnus | Meld Construct; +Lunic Eye; Calamity; (Cobalt Bar & Stardust) | Eye of Magnus; Trapper Bulb; Calamity; Wall of Flesh; Titan Heart; Calamity; Astral Infection; Essence of Sunlight; Calamity; Wall of Flesh | Golem; -Essence of Eleum; Calamity; Wall of Flesh | Cryogen | #Cryogen; // TODO Check -Essence of Havoc; Calamity; Wall of Flesh | #Calamitas Clone | #Brimstone Elemental; -Don't Dread on Me; Achievement; Wall of Flesh; -Earth Elemental; Calamity | Location | Item; Wall of Flesh; -Cloud Elemental; Calamity | Location | Item; Wall of Flesh; +Essence of Eleum; Calamity; Wall of Flesh | Cryogen | #Cryogen | (@getfixedboi & #Duke Fishron); +Essence of Havoc; Calamity; Wall of Flesh | #Calamitas Clone | #Brimstone Elemental | Ruin Medallion; +Dreadnautilus; Calamity | Location | Item; Wall of Flesh; +Don't Dread on Me; Not Calamity | Achievement; Wall of Flesh; +Hardmode Giant Clam; Calamity | Location | Item; #Giant Clam & Wall of Flesh; Truffle; Npc; Wall of Flesh; It Can Talk?!; Achievement; Truffle; The First Shadowflame; Calamity | Minions(1); Goblin Army | Wall of Flesh; @@ -271,103 +366,125 @@ Pirate Invasion; Location | Item; Pirate; Npc; Pirate Invasion; // Queen Slime -Queen Slime; Location | Item; Hallow; +Queen Slime; Location | Item; Hallow | (@getfixedboi & @calamity & #Supreme Alchemist, Cirrus); +Sparkle Slime Balloon; ; #Queen Slime; +Diva Slime; Npc; Sparkle Slime Balloon; +The Great Slime Mitosis; Achievement; Nerdy Slime & Cool Slime & Elder Slime & Clumsy Slime & Diva Slime & Surly Slime & Mystic Slime & Squire Slime; // Aquatic Scourge -Mythril Ore; ; (((~@calamity & Altar) | (@calamity & @mech_boss(1))) & @pickaxe(110)) | (Wall of Flesh & (~@calamity | @mech_boss(1))); -Mythril Bar; ; Mythril Ore | (Wall of Flesh & (~@calamity | @mech_boss(1))); +Mythril Ore; ; (((~@calamity & Altar) | (@calamity & @mech_boss(1))) & @pickaxe(110)) | Wall of Flesh | Adamantite Ore | Mythril Bar; +Mythril Bar; ; Mythril Ore | Wall of Flesh | (@calamity & Electrician's Glove); Hardmode Anvil; ; Mythril Bar; Mythril Pickaxe; Pickaxe(150); Hardmode Anvil & Mythril Bar; -Adamantite Ore; ; (((~@calamity & Altar) | (@calamity & @mech_boss(2))) & @pickaxe(150)) | (Wall of Flesh & (~@calamity | @mech_boss(2))); +Electrician's Glove; Calamity; (Hardmode Anvil & Wire & Mythril Bar) | Nanotech; +Adamantite Ore; ; (((~@calamity & Altar) | (@calamity & @mech_boss(2))) & @pickaxe(150)) | Wall of Flesh | (~@calamity & Chlorophyte Ore) | Adamantite Bar | (@calamity & Hallowed Ore); Hardmode Forge; ; Hardmode Anvil & Adamantite Ore & Hellforge; -Adamantite Bar; ; (Hardmode Forge & Adamantite Ore) | (Wall of Flesh & (~@calamity | @mech_boss(2))); +Adamantite Bar; ; (Hardmode Forge & Adamantite Ore) | Wall of Flesh; Adamantite Pickaxe; Pickaxe(180); Hardmode Anvil & Adamantite Bar; -Forbidden Armor; ArmorMinions(2); Hardmode Anvil & Adamantite Bar & Forbidden Fragment; +Forbidden Armor; Armor Minions(2); Hardmode Anvil & Adamantite Bar & Forbidden Fragment; Aquatic Scourge; Calamity | Location | Item; -The Twins; Location | Item | Mech Boss; (@calamity | Hardmode Anvil) & Soul of Light; -Brimstone Elemental; Calamity | Location | Item; Soul of Night & Essence of Havoc & Unholy Core; -The Destroyer; Location | Item | Mech Boss; (@calamity | Hardmode Anvil) & Soul of Night; -Cryogen; Calamity | Location | Item; Soul of Night & Soul of Light & Essence of Eleum; -Skeletron Prime; Location | Item | Mech Boss; (@calamity | Hardmode Anvil) & Soul of Night & Soul of Light & Bone; -# mechanical_bosses Cragmaw Mire; Calamity | Location | Item; #Acid Rain Tier 2; -Nuclear Rod; Calamity | Minions(1); #Cragmaw Mire; -Acid Rain Tier 2; Calamity | Location | Item; #Acid Rain Tier 1 & Aquatic Scourge; +Nuclear Fuel Rod; Calamity | Minions(1); #Cragmaw Mire | Star-Tainted Generator; +Acid Rain Tier 2; Calamity | Location | Item; #Acid Rain Tier 1 & (Aquatic Scourge | Acid Rain Tier 3); +Mechanical Eye; ; (@calamity | Hardmode Anvil) & Soul of Light; +Mechanical Worm; ; (@calamity | Hardmode Anvil) & Soul of Night; +Mechanical Skull; ; (@calamity | Hardmode Anvil) & Soul of Night & Soul of Light & Bone; +Ocram's Razor; Getfixedboi; (@calamity | Hardmode Anvil) & Mechanical Eye & Mechanical Worm & Mechanical Skull; +The Twins; Location | Item | Mech Boss; (~@getfixedboi & Mechanical Eye) | (@getfixedboi & Ocram's Razor); +Brimstone Elemental; Calamity | Location | Item; Soul of Night & Essence of Havoc & Unholy Core; +The Destroyer; Location | Item | Mech Boss; (~@getfixedboi & Mechanical Worm) | (@getfixedboi & Ocram's Razor); +Cryogen; Calamity | Location | Item; Soul of Night & Soul of Light & Essence of Eleum; +Skeletron Prime; Location | Item | Mech Boss; (~@getfixedboi & Mechanical Skull) | (@getfixedboi & Ocram's Razor); +# mechanical_bosses // The Twins -Soul of Sight; ; #The Twins; +Soul of Sight; ; #The Twins | Avenger Emblem | (@calamity & (Mechanical Glove | Celestial Emblem)); Steampunker; Npc; @mech_boss(1); Hammush; ; Truffle & @mech_boss(1); Rainbow Rod; ; Hardmode Anvil & Crystal Shard & Unicorn Horn & Pixie Dust & Soul of Light & Soul of Sight; Prismancer; Achievement; Rainbow Rod; Long Ranged Sensor Array; Calamity; Hardmode Anvil & Mysterious Circuitry & Dubious Plating & Mythril Bar & Wire & Decryption Computer & Codebreaker Base; Hydraulic Volt Crusher; Calamity; Hardmode Anvil & Mysterious Circuitry & Dubious Plating & Mythril Bar & Soul of Sight; -Life Fruit; ; (@mech_boss(1) & Wall of Flesh) | (@calamity & (Living Shard | Wall of Flesh)); +Life Fruit; ; (@mech_boss(1) & Wall of Flesh) | (@calamity & (Living Shard | Wall of Flesh | (@getfixedboi & #Plantera))); Get a Life; Achievement; Life Fruit; Topped Off; Achievement; Life Fruit; Old One's Army Tier 2; Location | Item; #Old One's Army Tier 1 & ((Wall of Flesh & @mech_boss(1)) | #Old One's Army Tier 3); // Brimstone Elemental Infernal Suevite; Calamity; @pickaxe(150) | Brimstone Elemental; -Unholy Core; Calamity; Infernal Suevite & Hellstone; +Unholy Core; Calamity; (Infernal Suevite & Hellstone) | Brimstone Elemental; +Ruin Medallion; Calamity; (Hardmode Anvil & Coin of Deceit & Unholy Core & Essence of Havoc) | Dark Matter Sheath; // The Destroyer -Soul of Might; ; #The Destroyer; +Soul of Might; ; #The Destroyer | Avenger Emblem | Light Disc | (@calamity & (Mechanical Glove | Celestial Emblem)); // Cryogen -Cryonic Ore; Calamity; Cryogen & (@pickaxe(180) | @mech_boss(2)); -Cryonic Bar; Calamity; (Hardmode Forge & Cryonic Ore) | Fleshy Geode | Necromantic Geode; +Cryonic Ore; Calamity; (Cryogen & (@pickaxe(180) | @mech_boss(2))) | Cryonic Bar; +Cryonic Bar; Calamity; (Hardmode Forge & Cryonic Ore) | Fleshy Geode | Necromantic Geode | (Cryogen & @mech_boss(2)) | Life Alloy; Abyssal Warhammer; Calamity | Hammer(88); Hardmode Anvil & Cryonic Bar; Shardlight Pickaxe; Calamity | Pickaxe(180); Hardmode Anvil & Cryonic Bar; +Daedalus Armor; Calamity | Armor Minions(2); Hardmode Anvil & Cryonic Bar & Essence of Eleum; // Skeletron Prime -Soul of Fright; ; #Skeletron Prime; +Soul of Fright; ; #Skeletron Prime | Avenger Emblem | Flamethrower | (@calamity & (Mechanical Glove | Celestial Emblem)); Inferna Cutter; Calamity; Hardmode Anvil & Axe of Purity & Soul of Fright & Essence of Havoc; +Flamethrower; ; (Hardmode Anvil & Illegal Gun Parts & Soul of Fright) | (@getfixedboi & @calamity & #Skeletron); Buckets of Bolts; Achievement; #The Twins & #The Destroyer & #Skeletron Prime; -Mecha Mayhem; Achievement; #The Twins & #The Destroyer & #Skeletron Prime; -Hallowed Bar; ; (#The Twins | #The Destroyer | #Skeletron Prime) & (~@calamity | @mech_boss(3)); // Can't count on Hallowed Ore, since the player may be in prehardmode (TODO Check this) -Hallowed Armor; ArmorMinions(3); Hardmode Anvil & Hallowed Bar; +Mecha Mayhem; Achievement | Not Getfixedboi; #The Twins & #The Destroyer & #Skeletron Prime; +Hallowed Ore; Calamity; (@mech_boss(3) & @pickaxe(180)) | Chlorophyte Ore | Hallowed Bar; +Hallowed Bar; ; ((#The Twins | #The Destroyer | #Skeletron Prime) & (~@calamity | @mech_boss(3))) | (@calamity & Hardmode Forge & Hallowed Ore) | Light Disc; +Hallowed Armor; Armor Minions(3); Hardmode Anvil & Hallowed Bar; Excalibur; ; Hardmode Anvil & Hallowed Bar; Pickaxe Axe; Pickaxe(200); Hardmode Anvil & Hallowed Bar & Soul of Fright & Soul of Might & Soul of Sight; Drax Attax; Achievement; Pickaxe Axe; True Night's Edge; ; Hardmode Anvil & Night's Edge & Soul of Fright & Soul of Might & Soul of Sight; -Chlorophyte Ore; ; Wall of Flesh & @pickaxe(200); +Avenger Emblem; ; (Tinkerer's Workshop & Emblem & Soul of Might & Soul of Sight & Soul of Fright) | (@calamity & (Sand Shark Tooth Necklace | Sigil of Calamitas)) | (~@calamity & (Mechanical Glove | Celestial Emblem)); +Mechanical Glove; ; (Power Glove & ((~@calamity & Tinkerer's Workshop & Avenger Emblem) | (@calamity & Emblem & Soul of Fright & Soul of Might & Soul of Sight))) | Fire Gauntlet; +Celestial Emblem; ; (Celestial Magnet & ((~@calamity & Tinkerer's Workshop & Avenger Emblem) | (@calamity & Emblem & Soul of Fright & Soul of Might & Soul of Sight))) | Sigil of Calamitas; +Light Disc; ; (Hallowed Bar & Soul of Light & Soul of Might) | (@getfixedboi & @calamity & #Evil Boss); +Chlorophyte Ore; ; (Wall of Flesh & @pickaxe(200)) | (~@calamity & Luminite) | Chlorophyte Bar | (@calamity & Perennial Ore); Photosynthesis; Achievement; Chlorophyte Ore; -Chlorophyte Bar; ; Hardmode Forge & Chlorophyte Ore; +Chlorophyte Bar; ; (Hardmode Forge & Chlorophyte Ore) | Spectre Bar | Shroomite Bar; True Excalibur; ; Hardmode Anvil & Excalibur & Chlorophyte Bar; Chlorophyte Pickaxe; Pickaxe(200); Hardmode Anvil & Chlorophyte Bar; Chlorophyte Warhammer; Hammer(90); Hardmode Anvil & Chlorophyte Bar; // Calamitas Clone Calamitas Clone; Calamity | Location | Item | Goal; Hardmode Anvil & Hellstone Bar & Essence of Havoc; -Plantera; Location | Item | Goal; Wall of Flesh & (@mech_boss(3) | (@calamity & Hardmode Anvil & Trapper Bulb)); +Plantera; Location | Item | Goal; Wall of Flesh & (@mech_boss(3) | @calamity); # calamitas_clone # plantera -Ashes of Calamity; Calamity; #Calamitas Clone; +Ashes of Calamity; Calamity; #Calamitas Clone | Sigil of Calamitas; +Depth Cells; Calamity; Calamitas Clone | Abyssal Mirror; +Lumenyl; Calamity; Calamitas Clone | Abyssal Mirror; +Abyssal Mirror; Calamity; (Hardmode Anvil & Mirage Mirror & Ink Bomb & Depth Cells & Lumenyl) | Eclipse Mirror; +Fathom Swarmer Armor; Calamity | Armor Minions(2); Hardmode Anvil & Sea Remains & Depth Cells; // Plantera The Axe; Hammer(100); #Plantera; Seedler; ; #Plantera; Living Shard; Calamity; #Plantera; -Tiki Armor; ArmorMinions(4); Witch Doctor & Wall of Flesh & Plantera; +Tiki Armor; Armor Minions(4); Witch Doctor & Wall of Flesh & Plantera; Hercules Beetle; ; Witch Doctor & Wall of Flesh & Plantera; You and What Army?; Achievement; @minions(8); Cyborg; Npc; Plantera; +To Infinity... and Beyond!; Achievement; Cyborg & Wall of Flesh; Autohammer; ; Truffle & Plantera; Shroomite Bar; ; Autohammer & Chlorophyte Bar; Shroomite Digging Claw; Pickaxe(200); Hardmode Anvil & Shroomite Bar; Princess; Npc; Guide & Merchant & Nurse & Demolitionist & Dye Trader & Zoologist & Angler & Painter & Stylist & Golfer & Arms Dealer & Dryad & Party Girl & Tavernkeep & Goblin Tinkerer & Witch Doctor & Clothier & Wizard & Truffle & Tax Collector & Pirate & Steampunker & Cyborg; Real Estate Agent; Achievement; Princess; -Ectoplasm; ; ((Dungeon & Wall of Flesh) | @calamity) & Plantera; +Ectoplasm; ; (((Dungeon & Wall of Flesh) | @calamity) & Plantera) | Spectre Bar; Paladin's Shield; ; Dungeon & Wall of Flesh & Plantera; -Core of Sunlight; Calamity; (Hardmode Anvil & Essence of Sunlight & Ectoplasm) | Fleshy Geode | Necromantic Geode; -Core of Eleum; Calamity; (Hardmode Anvil & Essence of Eleum & Ectoplasm) | Fleshy Geode | Necromantic Geode; -Core of Havoc; Calamity; (Hardmode Anvil & Essence of Havoc & Ectoplasm) | Fleshy Geode | Necromantic Geode; -Core of Calamity; Calamity; (Hardmode Anvil & Core of Sunlight & Core of Eleum & Core of Havoc & Ashes of Calamity) | Necromantic Geode; +Core of Sunlight; Calamity; (Hardmode Anvil & Essence of Sunlight & Ectoplasm) | Fleshy Geode | Necromantic Geode | Core of Calamity | Statis' Blessing; +Core of Eleum; Calamity; (Hardmode Anvil & Essence of Eleum & Ectoplasm) | Fleshy Geode | Necromantic Geode | Core of Calamity; +Core of Havoc; Calamity; (Hardmode Anvil & Essence of Havoc & Ectoplasm) | Fleshy Geode | Necromantic Geode | Core of Calamity; +Core of Calamity; Calamity; (Hardmode Anvil & Core of Sunlight & Core of Eleum & Core of Havoc & Ashes of Calamity) | Necromantic Geode | Deadshot Brooch; +Deadshot Brooch; Calamity; (Hardmode Anvil & Emblem & Core of Calamity) | Elemental Quiver; Spectre Bar; ; Hardmode Forge & Chlorophyte Bar & Ectoplasm; Spectre Pickaxe; Pickaxe(200); Hardmode Anvil & Spectre Bar; Spectre Hamaxe; Hammer(90); Hardmode Anvil & Spectre Bar; -Robbing the Grave; Achievement; Dungeon & Plantera; +Robbing the Grave; Achievement; Dungeon & Wall of Flesh & Plantera; Evil Key; ; Plantera | (@calamity & #Wall of Flesh); Frozen Key; ; Plantera | (@calamity & #Cryogen); Jungle Key; ; Plantera | (@calamity & #Plantera); @@ -376,22 +493,25 @@ Desert Key; ; Big Booty; Achievement; Dungeon & Wall of Flesh & Plantera & (Evil Key | Frozen Key | Jungle Key | Hallowed Key | Desert Key); Rainbow Gun; ; Dungeon & Wall of Flesh & Plantera & Hallowed Key; Rainbows and Unicorns; Achievement; Blessed Apple & Rainbow Gun; -Perennial Ore; Calamity; Plantera; -Perennial Bar; Calamity; Hardmode Forge & Perennial Ore; +Perennial Ore; Calamity; Plantera | Perennial Bar; +Perennial Bar; Calamity; (Hardmode Forge & Perennial Ore) | Plantera | Life Alloy; Beastial Pickaxe; Calamity | Pickaxe(200); Hardmode Anvil & Perennial Bar; -Armored Digger; Calamity | Location | Item; Plantera; // TODO Check // Solar Eclipse Temple Raider; Achievement; #Plantera; Lihzahrd Temple; ; #Plantera | (Plantera & Actuator) | @pickaxe(210) | (@calamity & Hardmode Anvil & Soul of Light & Soul of Night); +Lihzahrd Furniture; ; Lihzahrd Temple; Solar Eclipse; ; Lihzahrd Temple & Wall of Flesh; -Broken Hero Sword; ; (Solar Eclipse & Plantera & @mech_boss(3)) | (@calamity & #Calamitas Clone); +Broken Hero Sword; ; Solar Eclipse & Plantera & @mech_boss(3); Terra Blade; ; Hardmode Anvil & True Night's Edge & True Excalibur & Broken Hero Sword & (~@calamity | Living Shard); Sword of the Hero; Achievement; Terra Blade; +Neptune's Shell; ; Solar Eclipse; Kill the Sun; Achievement; Solar Eclipse; // Great Sand Shark Great Sand Shark; Calamity | Location | Item; Hardmode Anvil & Forbidden Fragment & Core of Sunlight; +Grand Scale; Calamity; #Great Sand Shark | Sand Shark Tooth Necklace; +Sand Shark Tooth Necklace; Calamity; (Tinkerer's Workshop & Shark Tooth Necklace & Avenger Emblem & Grand Scale) | (@getfixedboi & #Desert Scourge); // Leviathan and Anahita Leviathan and Anahita; Calamity | Location | Item; @@ -404,32 +524,40 @@ Starbuster Core; Calamity | Minions(1); Golem; Location | Item | Goal; (Wall of Flesh & Plantera & Lihzahrd Temple) | (@calamity & Hardmode Anvil & Lihzahrd Temple & Essence of Sunlight); # golem Picksaw; Pickaxe(210); #Golem; -Lihzahrd Brick; ; @pickaxe(210); -Scoria Ore; Calamity; Golem | @pickaxe(210); -Scoria Bar; Calamity; Hardmode Forge & Scoria Ore; +Lihzahrd Brick; ; @pickaxe(210) | (Lihzahrd Furniture & Golem) | (@calamity & Lihzahrd Temple); +Scoria Ore; Calamity; Golem | @pickaxe(210) | Astral Ore | Luminite | Scoria Bar; +Scoria Bar; Calamity; (Hardmode Forge & Scoria Ore) | Golem | Life Alloy | Sigil of Calamitas | Fire Gauntlet; Seismic Hampick; Calamity | Pickaxe(210) | Hammer(95); Hardmode Anvil & Scoria Bar; -Life Alloy; Calamity; (Hardmode Anvil & Cryonic Bar & Perennial Bar & Scoria Bar) | Necromantic Geode; +Hydrothermic Armor; Calamity | Armor Minions(2); Hardmode Anvil & Scoria Bar & Core of Havoc; +Fire Gauntlet; ; (Tinkerer's Workshop & Magma Stone & Mechanical Glove & (~@calamity | Scoria Bar)) | (@calamity & Elemental Gauntlet); +Sigil of Calamitas; Calamity; (Hardmode Anvil & Celestial Emblem & Scoria Bar & Ashes of Calamity) | Ethereal Talisman; +Life Alloy; Calamity; (Hardmode Anvil & Cryonic Bar & Perennial Bar & Scoria Bar) | Necromantic Geode | Star-Tainted Generator | (@getfixedboi & #Yharon, Dragon of Rebirth); Advanced Display; Calamity; Hardmode Anvil & Mysterious Circuitry & Dubious Plating & Life Alloy & Long Ranged Sensor Array; +Star-Tainted Generator; Calamity; (Hardmode Anvil & Jelly-Charged Battery & Nuclear Fuel Rod & Starbuster Core & Life Alloy) | Nucleogenesis; Old One's Army Tier 3; Location | Item; #Old One's Army Tier 1 & Wall of Flesh & Golem; // Martian Madness Martian Madness; Location | Item; Wall of Flesh & Golem; +Laser Drill; Pickaxe(220); #Martian Madness; Influx Waver; ; #Martian Madness; // The Plaguebringer Goliath -Plague Cell Canister; Calamity; Golem; -Plaguebringer; Calamity | Location | Item; Golem; +Plague Cell Canister; Calamity; Golem | Alchemical Flask | (@getfixedboi & #Queen Bee); +Alchemical Flask; Calamity; (Hardmode Anvil & Bee Wax & Plague Cell Canister) | (@getfixedboi & #Queen Bee); The Plaguebringer Goliath; Calamity | Location | Item; Hardmode Anvil & Plague Cell Canister; +Infected Armor Plating; Calamity; #The Plaguebringer Goliath; +Plaguebringer Armor; Calamity | Armor Minions(3); Hardmode Anvil & Bee Armor & Alchemical Flask & Plague Cell Canister & Infected Armor Plating; // Duke Fishron -Duke Fishron; Location | Item; Bug Net & Wall of Flesh; +Duke Fishron; Location | Item; (Bug Net & Wall of Flesh) | (@getfixedboi & @calamity & #Astrum Deus); // Pumpkin Moon Pumpkin Moon; ; Hardmode Anvil & Pumpkin & Ectoplasm & (@calamity | Hallowed Bar); -Spooky Armor; ArmorMinions(4); Pumpkin Moon; +Spooky Armor; Armor Minions(4); Pumpkin Moon; Mourning Wood; Location | Item; Pumpkin Moon; Necromantic Scroll; Minions(1); #Mourning Wood; -Papyrus Scarab; Minions(1); Tinkerer's Workshop & Hercules Beetle & Necromantic Scroll; +Papyrus Scarab; Minions(1); (Tinkerer's Workshop & Hercules Beetle & Necromantic Scroll) | (@calamity & Statis' Blessing); +Statis' Blessing; Calamity; (Hardmode Anvil & Papyrus Scarab & Pygmy Necklace & Emblem & Holy Water & Core of Sunlight) | Statis' Curse; Pumpking; Location | Item; Pumpkin Moon; The Horseman's Blade; ; #Pumpking; Baleful Harvest; Achievement; Pumpkin Moon; @@ -451,11 +579,11 @@ Ravager; Calamity | Location | Item; Fleshy Geode; Calamity; #Ravager; // Empress of Light -Empress of Light; Location | Item | Goal; Wall of Flesh & Hallow & (@calamity | Plantera); +Empress of Light; Location | Item | Goal; (Wall of Flesh & Hallow & (@calamity | Plantera)) | (@getfixedboi & @calamity & #Supreme Alchemist, Cirrus); # empress_of_light // Lunatic Cultist -Lunatic Cultist; Location | Item | Goal; (@calamity | (Dungeon & Golem)) & Wall of Flesh; +Lunatic Cultist; Location | Item | Goal; ((@calamity | (Dungeon & Golem)) & Wall of Flesh) | (@calamity & Calamitas Clone); Astrum Deus; Calamity | Location | Item | Goal; Titan Heart; # lunatic_cultist # astrum_deus @@ -463,111 +591,142 @@ Ancient Manipulator; ; // Lunar Events Lunar Events; Location | Item; #Lunatic Cultist; -Fragment; ; #Lunar Events | #Astrum Deus; -Galactica Singularity; Calamity; Ancient Manipulator & Fragment; -Meld Blob; Calamity; #Lunar Events | #Astrum Deus; -Meld Construct; Calamity; Ancient Manipulator & Meld Blob & Stardust; +Fragment; ; #Lunar Events | #Astrum Deus | (Ancient Manipulator & (Nebula Fragment | Stardust Fragment)) | (@calamity & Galactica Singularity); +Nebula Fragment; ; Fragment | (@calamity & Eye of Magnus); +Eye of Magnus; Calamity; (Ancient Manipulator & Lunic Eye & Nebula Fragment) | (@getfixedboi & #Wall of Flesh); +Stardust Fragment; ; Fragment | (@calamity & Statis' Curse); +Statis' Curse; Calamity; (Ancient Manipulator & Statis' Blessing & The First Shadowflame & Stardust Fragment) | Nucleogenesis; +Galactica Singularity; Calamity; (Ancient Manipulator & Fragment) | Elemental Gauntlet | Elemental Quiver | Nucleogenesis | Moonstone Crown | Ethereal Talisman; +Meld Blob; Calamity; #Lunar Events | #Astrum Deus | (Astral Infection & Astrum Deus) | Meld Construct; +Meld Construct; Calamity; (Ancient Manipulator & Meld Blob & Stardust) | Dark Matter Sheath; +Dark Matter Sheath; Calamity; (Ancient Manipulator & Silencing Sheath & Ruin Medallion & Meld Construct) | Eclipse Mirror; // Astrum Deus -Astral Ore; Calamity; Wall of Flesh & Astrum Deus; -Astral Bar; Calamity; Ancient Manipulator & Stardust & Astral Ore; +Astral Ore; Calamity; (Astral Infection & Astrum Deus) | Astral Bar; // No pick needed; you can fish it +Astral Bar; Calamity; (Ancient Manipulator & Stardust & Astral Ore) | (Astral Infection & Astrum Deus); Astral Hamaxe; Calamity | Hammer(100); Ancient Manipulator & Astral Bar; Astral Pickaxe; Calamity | Pickaxe(220); Ancient Manipulator & Astral Bar; +Astral Armor; Calamity | Armor Minions(3); Ancient Manipulator & Astral Bar & Meteorite Bar; // Moon Lord Moon Lord; Location | Item | Goal; #Lunar Events; # moon_lord Slayer of Worlds; Achievement; #Evil Boss & #The Destroyer & #Duke Fishron & #Eye of Cthulhu & #Golem & #King Slime & #Lunatic Cultist & #Moon Lord & #Plantera & #Queen Bee & #Skeletron & #Skeletron Prime & #The Twins & #Wall of Flesh; -Luminite; ; #Moon Lord; -Luminite Bar; ; Ancient Manipulator & Luminite; +Luminite; ; #Moon Lord | (@calamity & (Exodium Cluster | Asteroid Staff)) | Luminite Bar; +Luminite Bar; ; (Ancient Manipulator & Luminite) | (@calamity & (Elemental Gauntlet | Elemental Quiver | Nucleogenesis | Moonstone Crown | Ethereal Talisman)); Luminite Hamaxe; Hammer(100); Ancient Manipulator & Fragment & Luminite Bar; Luminite Pickaxe; Pickaxe(225); Ancient Manipulator & Fragment & Luminite Bar; Genesis Pickaxe; Calamity | Pickaxe(225); Ancient Manipulator & Meld Construct & Luminite Bar; -Stardust Armor; ArmorMinions(5); Ancient Manipulator & Fragment & Luminite Bar; +Stardust Armor; Armor Minions(5); Ancient Manipulator & Fragment & Luminite Bar; +Asteroid Staff; Calamity; (Ancient Manipulator & Meteor Staff & Luminite Bar) | (@getfixedboi & #Astrum Aureus); +Moonstone Crown; Calamity; (Ancient Manipulator & Feather Crown & Luminite Bar & Galactica Singularity) | Nanotech; Terrarian; ; #Moon Lord; Sick Throw; Achievement; Terrarian; Meowmere; ; #Moon Lord; Star Wrath; ; #Moon Lord; -Exodium Cluster; Calamity; Moon Lord & @pickaxe(225); +Exodium Cluster; Calamity; Moon Lord | Uelibloom Ore; // No pick needed; can be fished Normality Relocator; Calamity; Ancient Manipulator & Rod of Discord & Exodium Cluster & Fragment; -Unholy Essence; Calamity; Moon Lord | #Providence, the Profaned Goddess; -Phantoplasm; Calamity; Moon Lord & (Wall of Flesh | Dungeon); // TODO Check -Eldritch Soul Artifact; Calamity; Exodium Cluster & Navyplate & Phantoplasm; +Unholy Essence; Calamity; Moon Lord | #Providence, the Profaned Goddess | (Hallow & Providence, the Profaned Goddess) | (@getfixedboi & Plantera); +Polterplasm; Calamity; (Moon Lord & Wall of Flesh) | (Dungeon & (Polterghast | Moon Lord)) | #Polterghast; +Eldritch Soul Artifact; Calamity | Minions(1); Exodium Cluster & Navyplate & Polterplasm; // Profaned Guardians Profaned Guardians; Calamity | Location | Item; Ancient Manipulator & Unholy Essence & Luminite Bar; // Dragonfolly -The Dragonfolly; Calamity | Location | Item; Ancient Manipulator & Unholy Essence & Luminite Bar; -Effulgent Feather; Calamity; Moon Lord | #The Dragonfolly; +The Dragonfolly; Calamity | Location | Item; (Ancient Manipulator & Unholy Essence & Luminite Bar) | (@getfixedboi & #Supreme Alchemist, Cirrus); +Effulgent Feather; Calamity; Moon Lord | #The Dragonfolly | (@getfixedboi & #Yharon, Dragon of Rebirth); // Providence, the Profaned Goddess -Providence, the Profaned Goddess; Calamity | Location | Item | Goal; #Profaned Guardians; +Providence, the Profaned Goddess; Calamity | Location | Item | Goal; #Profaned Guardians | (@getfixedboi & #Supreme Alchemist, Cirrus); # providence_the_profaned_goddess -Divine Geode; Calamity; #Providence, the Profaned Goddess; +Divine Geode; Calamity; #Providence, the Profaned Goddess | (@getfixedboi & #Profaned Guardians); Profaned Soul Artifact; Calamity | Minions(1); Exodium Cluster & Havocplate & Divine Geode; Rune of Kos; Calamity; #Providence, the Profaned Goddess; -Uelibloom Ore; Calamity; Providence, the Profaned Goddess; -Uelibloom Bar; Calamity; Hardmode Forge & Uelibloom Ore; +Uelibloom Ore; Calamity; Providence, the Profaned Goddess | Auric Ore | Uelibloom Bar; +Uelibloom Bar; Calamity; (Hardmode Forge & Uelibloom Ore) | Providence, the Profaned Goddess; Grax; Calamity | Hammer(110); Ancient Manipulator & Inferna Cutter & Luminite Hamaxe & Uelibloom Bar; Blossom Pickaxe; Calamity | Pickaxe(250); Ancient Manipulator & Uelibloom Bar; Voltage Regulation System; Calamity; Ancient Manipulator & Mysterious Circuitry & Dubious Plating & Uelibloom Bar & Luminite Bar & Advanced Display; +Tarragon Armor; Calamity | Armor Minions(3); Ancient Manipulator & Uelibloom Bar & Divine Geode; Necromantic Geode; Calamity; #Ravager & Providence, the Profaned Goddess; +Bloodstone; Calamity; Providence, the Profaned Goddess; +Bloodstone Core; Calamity; Hardmode Forge & Bloodstone & Polterplasm; // Sentinels of the Devourer Storm Weaver; Calamity | Location | Item; Rune of Kos; Armored Shell; Calamity; #Storm Weaver; -Ceaseless Void; Calamity | Location | Item; Rune of Kos; +Ceaseless Void; Calamity | Location | Item; Dungeon & Rune of Kos; Dark Plasma; Calamity; #Ceaseless Void; Signus, Envoy of the Devourer; Calamity | Location | Item; Rune of Kos; Twisting Nether; Calamity; #Signus, Envoy of the Devourer; // Polterghast -Polterghast; Calamity | Location | Item; Dungeon & ((Ancient Manipulator & Phantoplasm) | Moon Lord); -Colossal Squid; Calamity | Location | Item; -Reaper Shark; Calamity | Location | Item; -Eidolon Wyrm; Calamity | Location | Item; +Polterghast; Calamity | Location | Item; Dungeon & ((Ancient Manipulator & Polterplasm) | Moon Lord); +Ruinous Soul; Calamity; #Polterghast; +Bloodflare Armor; Calamity | Armor Minions(3); Ancient Manipulator & Bloodstone Core & Ruinous Soul; +Reaper Tooth; Calamity; Polterghast; +Omega Blue Armor; Calamity | Armor Minions(2); Ancient Manipulator & Reaper Tooth & Depth Cells & Ruinous Soul; // The Old Duke -Mauler; Calamity | Location | Item; #Acid Rain Tier 3; -Nuclear Terror; Calamity | Location | Item; #Acid Rain Tier 3; -Acid Rain Tier 3; Calamity | Location | Item; #Acid Rain Tier 1 & Polterghast; // TODO Check -The Old Duke; Calamity | Location | Item; #Acid Rain Tier 3 | (Bug Net & Moon Lord) | (Amidias & The Old Duke); +Mauler; Calamity | Location | Item; Acid Rain Tier 3; +Nuclear Terror; Calamity | Location | Item; Acid Rain Tier 3; +Acid Rain Tier 3; Calamity; #Acid Rain Tier 1 & Polterghast; +The Old Duke; Calamity | Location | Item; Acid Rain Tier 3 | (Bug Net & Moon Lord) | (Amidias & The Old Duke) | (@getfixedboi & #The Destroyer); // The Devourer of Gods -The Devourer of Gods; Calamity | Location | Item | Goal; Ancient Manipulator & ((Armored Shell & Twisting Nether & Dark Plasma) | (Luminite Bar & Galactica Singularity & Phantoplasm)); +The Devourer of Gods; Calamity | Location | Item | Goal; (Ancient Manipulator & ((Armored Shell & Twisting Nether & Dark Plasma) | (Luminite Bar & Galactica Singularity & Polterplasm))) | (@getfixedboi & #Supreme Alchemist, Cirrus); # the_devourer_of_gods Cosmilite Bar; Calamity; #The Devourer of Gods; Cosmic Anvil; Calamity; Ancient Manipulator & Hardmode Anvil & Cosmilite Bar & Luminite Bar & Galactica Singularity & Exodium Cluster; -Nightmare Fuel; Calamity; Pumpkin Moon & The Devourer of Gods; +Nightmare Fuel; Calamity; (Pumpkin Moon & The Devourer of Gods) | Occult Skull Crown; +Occult Skull Crown; Calamity | Getfixedboi; @getfixedboi & #Evil Boss; // Revengeance or getfixedboi Endothermic Energy; Calamity; Frost Moon & The Devourer of Gods; -Darksun Fragment; Calamity; Solar Eclipse & The Devourer of Gods; +Darksun Fragment; Calamity; (Solar Eclipse & The Devourer of Gods) | Eclipse Mirror; Dark Sun Ring; Calamity; Cosmic Anvil & Uelibloom Bar & Darksun Fragment; -Ascendant Spirit Essence; Calamity; Ancient Manipulator & Phantoplasm & Nightmare Fuel & Endothermic Energy & Darksun Fragment; +Eclipse Mirror; Calamity; (Cosmic Anvil & Abyssal Mirror & Dark Matter Sheath & Darksun Fragment) | (@getfixedboi & #Ceaseless Void); +Ascendant Spirit Essence; Calamity; (Ancient Manipulator & Polterplasm & Nightmare Fuel & Endothermic Energy & Darksun Fragment) | (@getfixedboi & #Providence, the Profaned Goddess) | Elemental Gauntlet | Elemental Quiver | Nucleogenesis | Nanotech | Ethereal Talisman; +Fearmonger Armor; Calamity | Armor Minions(2); Cosmic Anvil & Spooky Armor & Cosmilite Bar & Soul of Fright & Ascendant Spirit Essence; +Silva Armor; Calamity | Armor Minions(5); Cosmic Anvil & Effulgent Feather & Ascendant Spirit Essence; +Elemental Gauntlet; Calamity; (Cosmic Anvil & Fire Gauntlet & Luminite Bar & Galactica Singularity & Ascendant Spirit Essence) | (@getfixedboi & #Storm Weaver); +Elemental Quiver; Calamity; (Cosmic Anvil & Magic Quiver & Deadshot Brooch & Luminite Bar & Galactica Singularity & Ascendant Spirit Essence) | (@getfixedboi & #Storm Weaver); +Nucleogenesis; Calamity; (Cosmic Anvil & Star-Tainted Generator & Statis' Curse & Luminite Bar & Galactica Singularity & Ascendant Spirit Essence) | (@getfixedboi & #Ceaseless Void); +Nanotech; Calamity; (Emblem & Raider's Talisman & Moonstone Crown & Electrician's Glove & Luminite Bar & Galactica Singularity & Ascendant Spirit Essence) | (@getfixedboi & #Signus, Envoy of the Devourer); +Ethereal Talisman; Calamity; (Cosmic Anvil & Sigil of Calamitas & Mana Flower & Luminite Bar & Galactica Singularity & Ascendant Spirit Essence) | (@getfixedboi & #Signus, Envoy of the Devourer); // Yharon, Dragon of Rebirth Yharon, Dragon of Rebirth; Calamity | Location | Item | Goal; Ancient Manipulator & Effulgent Feather & Life Alloy; # yharon_dragon_of_rebirth -Yharon Soul Fragment; Calamity; #Yharon, Dragon of Rebirth; -Auric Ore; Calamity; Yharon, Dragon of Rebirth & @pickaxe(250); -Auric Bar; Calamity; Cosmic Anvil & Auric Ore & Yharon Soul Fragment; -Zenith; Location | Item(Has Zenith) | Goal; Hardmode Anvil & Terra Blade & Meowmere & Star Wrath & Influx Waver & The Horseman's Blade & Seedler & Starfury & Bee Keeper & Enchanted Sword & Copper Shortsword & (~@calamity | Auric Bar); +Yharon Soul Fragment; Calamity; #Yharon, Dragon of Rebirth | The Wand | Auric Bar; +The Wand; Calamity; (Cosmic Anvil & Wand of Sparking & Yharon Soul Fragment) | (@getfixedboi & #The Devourer of Gods); +Auric Ore; Calamity; (Yharon, Dragon of Rebirth & (@pickaxe(250) | Wall of Flesh)) | Auric Bar; +Auric Bar; Calamity; (Cosmic Anvil & Auric Ore & Yharon Soul Fragment) | Shadowspec Bar; +Auric Tesla Armor; Calamity | Armor Minions(6); Cosmic Anvil & Silva Armor & Bloodflare Armor & Tarragon Armor & Auric Bar; +Infinity +1 Sword; Achievement | Grindy | Item(Has Zenith) | Goal(zenith); Hardmode Anvil & Terra Blade & Meowmere & Star Wrath & Influx Waver & The Horseman's Blade & Seedler & Starfury & Bee Keeper & Enchanted Sword & Copper Shortsword & (~@calamity | Auric Bar); # zenith // Exo Mechs Auric Quantum Cooling Cell; Calamity; Cosmic Anvil & Auric Bar & Mysterious Circuitry & Dubious Plating & Endothermic Energy & Core of Eleum & Voltage Regulation System; Exo Mechs; Calamity | Location | Item | Final Boss; Codebreaker Base & Decryption Computer & Auric Quantum Cooling Cell; -Supreme Witch, Calamitas; Calamity | Location | Item | Final Boss; Cosmic Anvil & Brimstone Slag & Auric Bar & Core of Calamity & Ashes of Calamity; +// XB-Infinity Hekate; Getfixedboi | Calamity; Codebreaker Base & Decryption Computer & Auric Quantum Cooling Cell & Blood Sample; // Currently, this boss doesn't affect logic at all +Supreme Witch, Calamitas; Calamity | Location | Item | Final Boss; (Cosmic Anvil & Brimstone Slag & Auric Bar & Core of Calamity & Ashes of Calamity) | (@getfixedboi & #Supreme Alchemist, Cirrus); +Supreme Alchemist, Cirrus; Getfixedboi | Calamity; Cosmic Anvil & Brimstone Slag & Auric Bar & Core of Calamity & Fabsol's Vodka; +THE LORDE; Getfixedboi | Calamity; Lihzahrd Temple; # calamity_final_bosses -Exo Prism; Calamity; #Exo Mechs; +Exo Prism; Calamity; #Exo Mechs | Shadowspec Bar; Draedon's Forge; Calamity; Cosmic Anvil & Hardmode Forge & Tinkerer's Workshop & Ancient Manipulator & Auric Bar & Exo Prism & Ascendant Spirit Essence; // Supreme Witch, Calamitas -Ashes of Annihilation; Calamity; #Supreme Witch, Calamitas; +Ashes of Annihilation; Calamity; #Supreme Witch, Calamitas | (@getfixedboi & #Calamitas Clone) | Shadowspec Bar; Shadowspec Bar; Calamity; Draedon's Forge & Auric Bar & Exo Prism & Ashes of Annihilation; Crystyl Crusher; Calamity | Pickaxe(1000); Draedon's Forge & Luminite Pickaxe & Blossom Pickaxe & Shadowspec Bar; Angelic Alliance; Calamity | Minions(2); Draedon's Forge & Hallowed Armor & Paladin's Shield & True Excalibur & Cross Necklace & Shadowspec Bar; +Demonshade Armor; Calamity | Armor Minions(10); Draedon's Forge & Shadowspec Bar; -// Adult Eidolon Wyrm; -Adult Eidolon Wyrm; Calamity | Location | Item | Goal; Rod of Discord | Normality Relocator; -# adult_eidolon_wyrm +// Primordial Wyrm +Primordial Wyrm; Calamity | Location | Item | Goal; Rod of Discord | Normality Relocator; +# primordial_wyrm + +// Boss Rush +Boss Rush; Calamity | Location | Item | Goal; Diving Gear | Neptune's Shell | (Aquatic Heart & Skeletron); // Might be obtainable earlier with Midas' Blessing +# boss_rush diff --git a/worlds/terraria/__init__.py b/worlds/terraria/__init__.py index abc10a7b..20f56c8f 100644 --- a/worlds/terraria/__init__.py +++ b/worlds/terraria/__init__.py @@ -1,11 +1,13 @@ # Look at `Rules.dsv` first to get an idea for how this works +import logging from typing import Union, Tuple, List, Dict, Set from worlds.AutoWorld import WebWorld, World from BaseClasses import Region, ItemClassification, Tutorial, CollectionState from .Checks import ( TerrariaItem, TerrariaLocation, + Condition, goals, rules, rule_indices, @@ -25,7 +27,7 @@ from .Checks import ( armor_minions, accessory_minions, ) -from .Options import TerrariaOptions +from .Options import TerrariaOptions, Goal class TerrariaWeb(WebWorld): @@ -55,8 +57,8 @@ class TerrariaWorld(World): item_name_to_id = item_name_to_id location_name_to_id = location_name_to_id - # Turn into an option when calamity is supported in the mod calamity = False + getfixedboi = False ter_items: List[str] ter_locations: List[str] @@ -70,72 +72,100 @@ class TerrariaWorld(World): ter_goals = {} goal_items = set() for location in goal_locations: - _, flags, _, _ = rules[rule_indices[location]] + flags = rules[rule_indices[location]].flags + if not self.options.calamity.value and "Calamity" in flags: + logging.warning( + f"Terraria goal `{Goal.name_lookup[self.options.goal.value]}`, which requires Calamity, was selected with Calamity disabled; enabling Calamity" + ) + self.options.calamity.value = True + item = flags.get("Item") or f"Post-{location}" ter_goals[item] = location goal_items.add(item) - achievements = self.options.achievements.value location_count = 0 locations = [] - for rule, flags, _, _ in rules[:goal]: - if ( - (not self.calamity and "Calamity" in flags) - or (achievements < 1 and "Achievement" in flags) - or (achievements < 2 and "Grindy" in flags) - or (achievements < 3 and "Fishing" in flags) - or ( - rule == "Zenith" and self.options.goal.value != 11 - ) # Bad hardcoding - ): - continue - if "Location" in flags or ("Achievement" in flags and achievements >= 1): - # Location - location_count += 1 - locations.append(rule) - elif ( - "Achievement" not in flags - and "Location" not in flags - and "Item" not in flags - ): - # Event - locations.append(rule) - item_count = 0 items = [] - for rule, flags, _, _ in rules[:goal]: - if not self.calamity and "Calamity" in flags: + for rule in rules[:goal]: + early = "Early" in rule.flags + grindy = "Grindy" in rule.flags + fishing = "Fishing" in rule.flags + + if ( + (not self.options.getfixedboi.value and "Getfixedboi" in rule.flags) + or (self.options.getfixedboi.value and "Not Getfixedboi" in rule.flags) + or (not self.options.calamity.value and "Calamity" in rule.flags) + or (self.options.calamity.value and "Not Calamity" in rule.flags) + or ( + self.options.getfixedboi.value + and self.options.calamity.value + and "Not Calamity Getfixedboi" in rule.flags + ) + or (not self.options.early_achievements.value and early) + or ( + not self.options.normal_achievements.value + and "Achievement" in rule.flags + and not early + and not grindy + and not fishing + ) + or (not self.options.grindy_achievements.value and grindy) + or (not self.options.fishing_achievements.value and fishing) + ) and rule.name not in goal_locations: continue - if "Item" in flags: - # Item - item_count += 1 - if rule not in goal_locations: - items.append(rule) + + if "Location" in rule.flags or "Achievement" in rule.flags: + # Location + location_count += 1 + locations.append(rule.name) elif ( - "Achievement" not in flags - and "Location" not in flags - and "Item" not in flags + "Achievement" not in rule.flags + and "Location" not in rule.flags + and "Item" not in rule.flags ): # Event - items.append(rule) + locations.append(rule.name) + + if "Item" in rule.flags and not ( + "Achievement" in rule.flags and rule.name not in goal_locations + ): + # Item + item_count += 1 + if rule.name not in goal_locations: + items.append(rule.name) + elif ( + "Achievement" not in rule.flags + and "Location" not in rule.flags + and "Item" not in rule.flags + ): + # Event + items.append(rule.name) - extra_checks = self.options.fill_extra_checks_with.value ordered_rewards = [ reward for reward in labels["ordered"] - if self.calamity or "Calamity" not in rewards[reward] + if self.options.calamity.value or "Calamity" not in rewards[reward] ] - while extra_checks == 1 and item_count < location_count and ordered_rewards: + while ( + self.options.fill_extra_checks_with.value == 1 + and item_count < location_count + and ordered_rewards + ): items.append(ordered_rewards.pop(0)) item_count += 1 random_rewards = [ reward for reward in labels["random"] - if self.calamity or "Calamity" not in rewards[reward] + if self.options.calamity.value or "Calamity" not in rewards[reward] ] self.multiworld.random.shuffle(random_rewards) - while extra_checks == 1 and item_count < location_count and random_rewards: + while ( + self.options.fill_extra_checks_with.value == 1 + and item_count < location_count + and random_rewards + ): items.append(random_rewards.pop(0)) item_count += 1 @@ -173,9 +203,9 @@ class TerrariaWorld(World): def create_items(self) -> None: for item in self.ter_items: if (rule_index := rule_indices.get(item)) is not None: - _, flags, _, _ = rules[rule_index] - if "Item" in flags: - name = flags.get("Item") or f"Post-{item}" + rule = rules[rule_index] + if "Item" in rule.flags: + name = rule.flags.get("Item") or f"Post-{item}" else: continue else: @@ -186,8 +216,8 @@ class TerrariaWorld(World): locked_items = {} for location in self.ter_locations: - _, flags, _, _ = rules[rule_indices[location]] - if "Location" not in flags and "Achievement" not in flags: + rule = rules[rule_indices[location]] + if "Location" not in rule.flags and "Achievement" not in rule.flags: if location in progression: classification = ItemClassification.progression else: @@ -202,95 +232,92 @@ class TerrariaWorld(World): for location, item in locked_items.items(): self.multiworld.get_location(location, self.player).place_locked_item(item) - def check_condition( - self, - state, - sign: bool, - ty: int, - condition: Union[str, Tuple[Union[bool, None], list]], - arg: Union[str, int, None], - ) -> bool: - if ty == COND_ITEM: - _, flags, _, _ = rules[rule_indices[condition]] - if "Item" in flags: - name = flags.get("Item") or f"Post-{condition}" + def check_condition(self, state, condition: Condition) -> bool: + if condition.type == COND_ITEM: + rule = rules[rule_indices[condition.condition]] + if "Item" in rule.flags: + name = rule.flags.get("Item") or f"Post-{condition.condition}" else: - name = condition + name = condition.condition - return sign == state.has(name, self.player) - elif ty == COND_LOC: - _, _, operator, conditions = rules[rule_indices[condition]] - return sign == self.check_conditions(state, operator, conditions) - elif ty == COND_FN: - if condition == "npc": - if type(arg) is not int: + return condition.sign == state.has(name, self.player) + elif condition.type == COND_LOC: + rule = rules[rule_indices[condition.condition]] + return condition.sign == self.check_conditions( + state, rule.operator, rule.conditions + ) + elif condition.type == COND_FN: + if condition.condition == "npc": + if type(condition.argument) is not int: raise Exception("@npc requires an integer argument") npc_count = 0 for npc in npcs: if state.has(npc, self.player): npc_count += 1 - if npc_count >= arg: - return sign + if npc_count >= condition.argument: + return condition.sign - return not sign - elif condition == "calamity": - return sign == self.calamity - elif condition == "grindy": - return sign == (self.options.achievements.value >= 2) - elif condition == "pickaxe": - if type(arg) is not int: + return not condition.sign + elif condition.condition == "calamity": + return condition.sign == self.options.calamity.value + elif condition.condition == "grindy": + return condition.sign == self.options.grindy_achievements.value + elif condition.condition == "pickaxe": + if type(condition.argument) is not int: raise Exception("@pickaxe requires an integer argument") for pickaxe, power in pickaxes.items(): - if power >= arg and state.has(pickaxe, self.player): - return sign + if power >= condition.argument and state.has(pickaxe, self.player): + return condition.sign - return not sign - elif condition == "hammer": - if type(arg) is not int: + return not condition.sign + elif condition.condition == "hammer": + if type(condition.argument) is not int: raise Exception("@hammer requires an integer argument") for hammer, power in hammers.items(): - if power >= arg and state.has(hammer, self.player): - return sign + if power >= condition.argument and state.has(hammer, self.player): + return condition.sign - return not sign - elif condition == "mech_boss": - if type(arg) is not int: + return not condition.sign + elif condition.condition == "mech_boss": + if type(condition.argument) is not int: raise Exception("@mech_boss requires an integer argument") boss_count = 0 for boss in mech_bosses: if state.has(boss, self.player): boss_count += 1 - if boss_count >= arg: - return sign + if boss_count >= condition.argument: + return condition.sign - return not sign - elif condition == "minions": - if type(arg) is not int: + return not condition.sign + elif condition.condition == "minions": + if type(condition.argument) is not int: raise Exception("@minions requires an integer argument") minion_count = 1 for armor, minions in armor_minions.items(): if state.has(armor, self.player) and minions + 1 > minion_count: minion_count = minions + 1 - if minion_count >= arg: - return sign + if minion_count >= condition.argument: + return condition.sign for accessory, minions in accessory_minions.items(): if state.has(accessory, self.player): minion_count += minions - if minion_count >= arg: - return sign + if minion_count >= condition.argument: + return condition.sign - return not sign + return not condition.sign + elif condition.condition == "getfixedboi": + return condition.sign == self.options.getfixedboi.value else: - raise Exception(f"Unknown function {condition}") - elif ty == COND_GROUP: - operator, conditions = condition - return sign == self.check_conditions(state, operator, conditions) + raise Exception(f"Unknown function {condition.condition}") + elif condition.type == COND_GROUP: + operator, conditions = condition.condition + return condition.sign == self.check_conditions(state, operator, conditions) def check_conditions( self, @@ -310,22 +337,22 @@ class TerrariaWorld(World): return True if len(conditions) > 1: raise Exception("Found multiple conditions without an operator") - return self.check_condition(state, *conditions[0]) + return self.check_condition(state, conditions[0]) elif operator: return any( - self.check_condition(state, *condition) for condition in conditions + self.check_condition(state, condition) for condition in conditions ) else: return all( - self.check_condition(state, *condition) for condition in conditions + self.check_condition(state, condition) for condition in conditions ) def set_rules(self) -> None: for location in self.ter_locations: def check(state: CollectionState, location=location): - _, _, operator, conditions = rules[rule_indices[location]] - return self.check_conditions(state, operator, conditions) + rule = rules[rule_indices[location]] + return self.check_conditions(state, rule.operator, rule.conditions) self.multiworld.get_location(location, self.player).access_rule = check @@ -336,6 +363,12 @@ class TerrariaWorld(World): def fill_slot_data(self) -> Dict[str, object]: return { "goal": list(self.goal_locations), - "achievements": self.options.achievements.value, "deathlink": bool(self.options.death_link), + # The rest of these are included for trackers + "calamity": self.options.calamity.value, + "getfixedboi": self.options.getfixedboi.value, + "early_achievements": self.options.early_achievements.value, + "normal_achievements": self.options.normal_achievements.value, + "grindy_achievements": self.options.grindy_achievements.value, + "fishing_achievements": self.options.fishing_achievements.value, }