From 66d0e221e1bc480ab309b0aa4df9b4d51dfa1a24 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Mon, 6 Mar 2023 01:44:30 +0100 Subject: [PATCH] Update world parsing with new flags --- lihzahrd/header/backgrounds.py | 69 ++++++------ lihzahrd/header/bossesdefeated.py | 2 + lihzahrd/header/party.py | 7 +- lihzahrd/header/savednpcs.py | 69 +++++++++++- lihzahrd/world.py | 167 ++++++++++++++++++++++-------- 5 files changed, 227 insertions(+), 87 deletions(-) diff --git a/lihzahrd/header/backgrounds.py b/lihzahrd/header/backgrounds.py index 4de6100..9c291c0 100644 --- a/lihzahrd/header/backgrounds.py +++ b/lihzahrd/header/backgrounds.py @@ -1,46 +1,43 @@ +from .fourpartsplit import FourPartSplit + + class Backgrounds: """The backgrounds of various world biomes.""" def __init__( self, - bg_underground_snow: int, - bg_underground_jungle: int, - bg_hell: int, - bg_forest: int, - bg_corruption: int, - bg_jungle: int, - bg_snow: int, - bg_hallow: int, - bg_crimson: int, - bg_desert: int, - bg_ocean: int, - new_bg_1: int, - new_bg_2: int, - new_bg_3: int, - new_bg_4: int, - new_bg_5: int, + underground_snow: int, + underground_jungle: int, + hell: int, + forest: FourPartSplit, + corruption: int, + jungle: int, + snow: int, + hallow: int, + crimson: int, + desert: int, + ocean: int, + mushroom: int, + underworld: int, ): - self.bg_underground_snow: int = bg_underground_snow - self.bg_underground_jungle: int = bg_underground_jungle - self.bg_hell: int = bg_hell - self.bg_forest: int = bg_forest - self.bg_corruption: int = bg_corruption - self.bg_jungle: int = bg_jungle - self.bg_snow: int = bg_snow - self.bg_hallow: int = bg_hallow - self.bg_crimson: int = bg_crimson - self.bg_desert: int = bg_desert - self.bg_ocean: int = bg_ocean - self.new_bg_1: int = new_bg_1 - self.new_bg_2: int = new_bg_2 - self.new_bg_3: int = new_bg_3 - self.new_bg_4: int = new_bg_4 - self.new_bg_5: int = new_bg_5 + self.underground_snow: int = underground_snow + self.underground_jungle: int = underground_jungle + self.hell: int = hell + self.forest: FourPartSplit = forest + self.corruption: int = corruption + self.jungle: int = jungle + self.snow: int = snow + self.hallow: int = hallow + self.crimson: int = crimson + self.desert: int = desert + self.ocean: int = ocean + self.mushroom: int = mushroom + self.underworld: int = underworld def __repr__(self): return ( - f"WorldBackgrounds({self.bg_underground_snow}, {self.bg_underground_jungle}, {self.bg_hell}," - f" {self.bg_forest}, {self.bg_corruption}, {self.bg_jungle}, {self.bg_snow}, {self.bg_hallow}," - f" {self.bg_crimson}, {self.bg_desert}, {self.bg_ocean}," - f" {self.new_bg_1}, {self.new_bg_2}, {self.new_bg_3}, {self.new_bg_4}, {self.new_bg_5})" + f"WorldBackgrounds({self.underground_snow}, {self.underground_jungle}, {self.hell}," + f" {self.forest}, {self.corruption}, {self.jungle}, {self.snow}, {self.hallow}," + f" {self.crimson}, {self.desert}, {self.ocean}," + f" {self.mushroom}, {self.underworld})" ) diff --git a/lihzahrd/header/bossesdefeated.py b/lihzahrd/header/bossesdefeated.py index f394882..a8144a0 100644 --- a/lihzahrd/header/bossesdefeated.py +++ b/lihzahrd/header/bossesdefeated.py @@ -33,6 +33,7 @@ class BossesDefeated: old_ones_army: OldOnesArmyTiers, empress_of_light: bool, queen_slime: bool, + deerclops: bool, ): self.eye_of_cthulhu: bool = eye_of_cthulhu self.eater_of_worlds: bool = eater_of_worlds @@ -65,6 +66,7 @@ class BossesDefeated: self.old_ones_army: OldOnesArmyTiers = old_ones_army self.empress_of_light: bool = empress_of_light self.queen_slime: bool = queen_slime + self.deerclops: bool = deerclops def __repr__(self): return f"" diff --git a/lihzahrd/header/party.py b/lihzahrd/header/party.py index 0465417..560210a 100644 --- a/lihzahrd/header/party.py +++ b/lihzahrd/header/party.py @@ -5,8 +5,11 @@ class Party: """NPC Party related information.""" def __init__( - self, thrown_by_party_center: bool, thrown_by_npcs: bool, cooldown: int, partying_npcs: typing.List[int] + self, is_doomed: bool, thrown_by_party_center: bool, thrown_by_npcs: bool, cooldown: int, partying_npcs: typing.List[int] ): + self.is_doomed: bool = is_doomed + """If all NPCs will die after this party ends.""" + self.thrown_by_party_center: bool = thrown_by_party_center """If the party was started by right-clicking a Party Center.""" @@ -21,7 +24,7 @@ class Party: def __repr__(self): return ( - f"WorldParty(thrown_by_party_center={self.thrown_by_party_center}," + f"WorldParty(is_doomed={self.is_doomed}, thrown_by_party_center={self.thrown_by_party_center}," f" thrown_by_npcs={self.thrown_by_npcs}, cooldown={self.cooldown}, partying_npcs={self.partying_npcs})" ) diff --git a/lihzahrd/header/savednpcs.py b/lihzahrd/header/savednpcs.py index 5dad45d..1ccd734 100644 --- a/lihzahrd/header/savednpcs.py +++ b/lihzahrd/header/savednpcs.py @@ -10,6 +10,24 @@ class SavedNPCs: bartender: bool, golfer: bool, advanced_combat: bool, + slime_nerdy: bool, + merchant: bool, + demolitionist: bool, + party_girl: bool, + dye_trader: bool, + truffle: bool, + arms_dealer: bool, + nurse: bool, + princess: bool, + advanced_combat_2: bool, + peddlers_satchel: bool, + slime_cool: bool, + slime_elder: bool, + slime_clumsy: bool, + slime_diva: bool, + slime_surly: bool, + slime_mystic: bool, + slime_squire: bool, ): self.goblin_tinkerer: bool = goblin_tinkerer self.wizard: bool = wizard @@ -20,11 +38,54 @@ class SavedNPCs: self.bartender: bool = bartender self.golfer: bool = golfer self.advanced_combat: bool = advanced_combat - """Was the Advanced Combat Technique Book used.""" + self.slime_nerdy: bool = slime_nerdy + self.merchant: bool = merchant + self.demolitionist: bool = demolitionist + self.party_girl: bool = party_girl + self.dye_trader: bool = dye_trader + self.truffle: bool = truffle + self.arms_dealer: bool = arms_dealer + self.nurse: bool = nurse + self.princess: bool = princess + self.advanced_combat_2: bool = advanced_combat_2 + self.peddlers_satchel: bool = peddlers_satchel + self.slime_cool: bool = slime_cool + self.slime_elder: bool = slime_elder + self.slime_clumsy: bool = slime_clumsy + self.slime_diva: bool = slime_diva + self.slime_surly: bool = slime_surly + self.slime_mystic: bool = slime_mystic + self.slime_squire: bool = slime_squire def __repr__(self): return ( - f"SavedNPCs(goblin_tinkerer={self.goblin_tinkerer}, wizard={self.wizard}, mechanic={self.mechanic}," - f" angler={self.angler}, stylist={self.stylist}, tax_collector={self.tax_collector}," - f" bartender={self.bartender}, golfer={self.golfer}, advanced_combat={self.advanced_combat}" + f"SavedNPCs(" + f"goblin_tinkerer={self.goblin_tinkerer}, " + f"wizard={self.wizard}, " + f"mechanic={self.mechanic}, " + f"angler={self.angler}, " + f"stylist={self.stylist}, " + f"tax_collector={self.tax_collector}, " + f"bartender={self.bartender}, " + f"golfer={self.golfer}, " + f"advanced_combat={self.advanced_combat}, " + f"slime_nerdy={self.slime_nerdy}, " + f"merchant={self.merchant}, " + f"demolitionist={self.demolitionist}, " + f"party_girl={self.party_girl}, " + f"dye_trader={self.dye_trader}, " + f"truffle={self.truffle}, " + f"arms_dealer={self.arms_dealer}, " + f"nurse={self.nurse}, " + f"princess={self.princess}, " + f"advanced_combat_2={self.advanced_combat_2}, " + f"peddlers_satchel={self.peddlers_satchel}, " + f"slime_cool={self.slime_cool}, " + f"slime_elder={self.slime_elder}, " + f"slime_clumsy={self.slime_clumsy}, " + f"slime_diva={self.slime_diva}, " + f"slime_surly={self.slime_surly}, " + f"slime_mystic={self.slime_mystic}, " + f"slime_squire={self.slime_squire}" + f")" ) diff --git a/lihzahrd/world.py b/lihzahrd/world.py index 35e2488..736aa70 100644 --- a/lihzahrd/world.py +++ b/lihzahrd/world.py @@ -36,6 +36,11 @@ class World: is_drunk_world: bool, is_for_the_worthy: bool, is_tenth_anniversary: bool, + is_the_constant: bool, + is_bee_world: bool, + is_upside_down: bool, + is_trap_world: bool, + is_zenith_world: bool, created_on, styles: Styles, backgrounds: Backgrounds, @@ -116,16 +121,28 @@ class World: """The difficulty (https://terraria.gamepedia.com/Difficulty) the game is in.""" self.is_drunk_world: bool = is_drunk_world - """If the world was created with the 5162020 (https://terraria.gamepedia.com/Secret_world_seeds#Drunk_World) - seed.""" + """If the world was created with the `Drunk world `_ seed.""" self.is_for_the_worthy: bool = is_for_the_worthy - """If the world was created with the - for the worthy (https://terraria.gamepedia.com/Secret_world_seeds#For_the_worthy) seed.""" + """If the world was created with the `For the worthy `_ seed.""" self.is_tenth_anniversary: bool = is_tenth_anniversary - """If the world was created with the - celebrationmk10 (https://terraria.fandom.com/wiki/Secret_world_seeds#Celebrationmk10) seed.""" + """If the world was created with the `Celebrationmk10 ` seed.""" + + self.is_the_constant: bool = is_the_constant + """If the world was created with `The Constant `_ seed.""" + + self.is_bee_world: bool = is_bee_world + """If the world was created with the `Not the bees `_ seed.""" + + self.is_upside_down: bool = is_upside_down + """If the world was created with the `Don't dig up `_ seed.""" + + self.is_trap_world: bool = is_trap_world + """If the world was created with the `No traps `_ seed.""" + + self.is_zenith_world: bool = is_zenith_world + """If the world was created with the `Get fixed boi `_ seed.""" self.created_on = created_on """The date and time this world was created in.""" @@ -345,15 +362,18 @@ class World: @property def is_expert(self): - """If the world is in expert difficulty or not. - - Provided for compatibility purposes.""" - return self.difficulty == 1 + """If the world is in expert difficulty or not.""" + return self.difficulty == 1 or self.difficulty == 0 and (self.is_for_the_worthy or self.is_zenith_world) @property def is_master(self): """If the world is in master difficulty or not.""" - return self.difficulty == 2 + return self.difficulty == 2 or self.difficulty == 1 and (self.is_for_the_worthy or self.is_zenith_world) + + @property + def is_legendary(self): + """If the world is in legendary difficulty or not.""" + return self.difficulty == 2 and (self.is_for_the_worthy or self.is_zenith_world) @property def is_journey(self): @@ -390,7 +410,7 @@ class World: # File header version = Version(f.int4()) - relogic = f.string(7) + relogic = f.string(7) # TODO: this can appearently be "xindong"? savefile_type = f.uint1() supported_versions = (Version("1.4.4.9"), Version("1.4.4.9")) if version not in supported_versions or relogic != "relogic" or savefile_type != 2: @@ -420,6 +440,12 @@ class World: is_drunk_world = f.bool() is_for_the_worthy = f.bool() is_tenth_anniversary = f.bool() + is_the_constant = f.bool() + is_bee_world = f.bool() + is_upside_down = f.bool() + is_trap_world = f.bool() + is_zenith_world = f.bool() + created_on = f.datetime() world_styles = Styles( @@ -479,6 +505,8 @@ class World: is_hardmode = f.bool() + party_is_doomed = not f.bool() + invasion_delay = f.int4() invasion_size = f.int4() invasion_type = InvasionType(f.int4()) @@ -578,6 +606,7 @@ class World: for _ in range(partying_npcs_count): partying_npcs.append(f.int4()) party = Party( + is_doomed=party_is_doomed, thrown_by_party_center=party_center_active, thrown_by_npcs=party_natural_active, cooldown=party_cooldown, @@ -592,47 +621,37 @@ class World: # ToDo: Figure out which biomes got new BGs. # Oasis and Graveyard probably got new backgrounds. - new_bg_1 = f.int1() - new_bg_2 = f.int1() - new_bg_3 = f.int1() # Maybe oasis. - new_bg_4 = f.int1() - new_bg_5 = f.int1() + bg_mushroom = f.int1() + bg_underworld = f.int1() + bg_forest_2 = f.int1() # Maybe oasis. + bg_forest_3 = f.int1() + bg_forest_4 = f.int1() backgrounds = Backgrounds( - bg_underground_snow=bg_underground_snow, - bg_underground_jungle=bg_underground_jungle, - bg_hell=bg_hell, - bg_forest=bg_forest, - bg_corruption=bg_corruption, - bg_jungle=bg_jungle, - bg_snow=bg_snow, - bg_hallow=bg_hallow, - bg_crimson=bg_crimson, - bg_desert=bg_desert, - bg_ocean=bg_ocean, - new_bg_1=new_bg_1, - new_bg_2=new_bg_2, - new_bg_3=new_bg_3, - new_bg_4=new_bg_4, - new_bg_5=new_bg_5, + underground_snow=bg_underground_snow, + underground_jungle=bg_underground_jungle, + hell=bg_hell, + forest=FourPartSplit(world_styles.trees.separators, [bg_forest, bg_forest_2, bg_forest_3, bg_forest_4]), + corruption=bg_corruption, + jungle=bg_jungle, + snow=bg_snow, + hallow=bg_hallow, + crimson=bg_crimson, + desert=bg_desert, + ocean=bg_ocean, + mushroom=bg_mushroom, + underworld=bg_underworld, ) combat_book_used = f.bool() - saved_npcs = SavedNPCs( - goblin_tinkerer=saved_goblin_tinkerer, - wizard=saved_wizard, - mechanic=saved_mechanic, - angler=saved_angler, - stylist=saved_stylist, - tax_collector=saved_tax_collector, - bartender=saved_bartender, - golfer=saved_golfer, - advanced_combat=combat_book_used, + lantern_night = LanternNight( + nights_on_cooldown=f.int4(), + genuine=f.bool(), + manual=f.bool(), + next_night_is_lantern_night=f.bool() ) - lantern_night = LanternNight(f.int4(), f.bool(), f.bool(), f.bool()) - events = Events( blood_moon=blood_moon, solar_eclipse=eclipse, @@ -661,6 +680,7 @@ class World: defeated_empress_of_light = f.bool() defeated_queen_slime = f.bool() + defeated_deerclops = f.bool() bosses_defeated = BossesDefeated( eye_of_cthulhu=defeated_eye_of_cthulhu, @@ -691,6 +711,58 @@ class World: lunatic_cultist=defeated_lunatic_cultist, empress_of_light=defeated_empress_of_light, queen_slime=defeated_queen_slime, + deerclops=defeated_deerclops, + ) + + defeated_deerclops = f.bool() + + saved_slime_nerdy = f.bool() + saved_merchant = f.bool() + saved_demolitionist = f.bool() + saved_party_girl = f.bool() + saved_dye_trader = f.bool() + saved_truffle = f.bool() + saved_arms_dealer = f.bool() + saved_nurse = f.bool() + saved_princess = f.bool() + combat_book_2_used = f.bool() + peddler_satchel_used = f.bool() + saved_slime_cool = f.bool() + saved_slime_elder = f.bool() + saved_slime_clumsy = f.bool() + saved_slime_diva = f.bool() + saved_slime_surly = f.bool() + saved_slime_mystic = f.bool() + saved_slime_squire = f.bool() + + saved_npcs = SavedNPCs( + goblin_tinkerer=saved_goblin_tinkerer, + wizard=saved_wizard, + mechanic=saved_mechanic, + angler=saved_angler, + stylist=saved_stylist, + tax_collector=saved_tax_collector, + bartender=saved_bartender, + golfer=saved_golfer, + advanced_combat=combat_book_used, + slime_nerdy=saved_slime_nerdy, + merchant=saved_merchant, + demolitionist=saved_demolitionist, + party_girl=saved_party_girl, + dye_trader=saved_dye_trader, + truffle=saved_truffle, + arms_dealer=saved_arms_dealer, + nurse=saved_nurse, + princess=saved_princess, + advanced_combat_2=combat_book_2_used, + peddlers_satchel=peddler_satchel_used, + slime_cool=saved_slime_cool, + slime_elder=saved_slime_elder, + slime_clumsy=saved_slime_clumsy, + slime_diva=saved_slime_diva, + slime_surly=saved_slime_surly, + slime_mystic=saved_slime_mystic, + slime_squire=saved_slime_squire, ) unknown_world_header_data = f.read_until(pointers.world_tiles) @@ -915,6 +987,11 @@ class World: is_drunk_world=is_drunk_world, is_for_the_worthy=is_for_the_worthy, is_tenth_anniversary=is_tenth_anniversary, + is_the_constant=is_the_constant, + is_bee_world=is_bee_world, + is_upside_down=is_upside_down, + is_trap_world=is_trap_world, + is_zenith_world=is_zenith_world, created_on=created_on, styles=world_styles, backgrounds=backgrounds,