diff --git a/lihzahrd/chests/__init__.py b/lihzahrd/chests/__init__.py index ad57620..f8bae14 100644 --- a/lihzahrd/chests/__init__.py +++ b/lihzahrd/chests/__init__.py @@ -1,7 +1,3 @@ -from .itemtype import ItemType -from .itemstack import ItemStack from .chest import Chest -from .clothingdisplay import ClothingDisplay, Mannequin, HatRack -from .singleitemdisplay import SingleItemDisplay -__all__ = ["ItemType", "ItemStack", "Chest", "ClothingDisplay", "SingleItemDisplay", "Mannequin", "HatRack"] +__all__ = ["Chest"] diff --git a/lihzahrd/chests/chest.py b/lihzahrd/chests/chest.py index 9de0f3f..a8827bd 100644 --- a/lihzahrd/chests/chest.py +++ b/lihzahrd/chests/chest.py @@ -1,5 +1,5 @@ import typing -from .itemstack import ItemStack +from ..items.itemstack import ItemStack from ..fileutils import Coordinates diff --git a/lihzahrd/chests/clothingdisplay.py b/lihzahrd/chests/clothingdisplay.py deleted file mode 100755 index d0ba61b..0000000 --- a/lihzahrd/chests/clothingdisplay.py +++ /dev/null @@ -1,50 +0,0 @@ -import typing -from .itemstack import ItemStack - - -class ClothingDisplay: - """Data pertaining to an item to display clothing.""" - - __slots__ = "wearing_items", "wearing_dyes" - - def __init__(self, - wearing_items: typing.List[ItemStack], - wearing_dyes: typing.List[ItemStack]): - - self.wearing_items: typing.List[ItemStack] = wearing_items - """What items is the mannequin wearing.""" - self.wearing_dyes: typing.List[ItemStack] = wearing_dyes - """What dyes is the mannequin wearing.""" - - def __repr__(self): - return f"<{self.__class__.__qualname__} with {self.total_count} items inside>" - - @property - def items_count(self): - return len(list(filter(lambda x: x is not None, self.wearing_items))) - - @property - def dyes_count(self): - return len(list(filter(lambda x: x is not None, self.wearing_dyes))) - - @property - def total_count(self): - return self.items_count + self.dyes_count - - -class Mannequin(ClothingDisplay): - """A `Mannequin `_ - / `Womannequin `_ containing up to 3 dyed armor pieces and up - to 5 dyed accessories.""" - def __init__(self, wearing_items: typing.List[ItemStack], wearing_dyes: typing.List[ItemStack]): - super().__init__(wearing_items, wearing_dyes) - assert len(wearing_items) == 8 - assert len(wearing_dyes) == 8 - - -class HatRack(ClothingDisplay): - """A `Hat Rack `_ containing up to 2 dyed helmets.""" - def __init__(self, wearing_items: typing.List[ItemStack], wearing_dyes: typing.List[ItemStack]): - super().__init__(wearing_items, wearing_dyes) - assert len(wearing_items) == 2 - assert len(wearing_dyes) == 2 diff --git a/lihzahrd/chests/singleitemdisplay.py b/lihzahrd/chests/singleitemdisplay.py deleted file mode 100755 index 6b851ac..0000000 --- a/lihzahrd/chests/singleitemdisplay.py +++ /dev/null @@ -1,23 +0,0 @@ -import typing -from .itemstack import ItemStack - -class SingleItemDisplay: - """Data pertaining to a single display item. - Currently weapon rack (https://terraria.gamepedia.com/Weapon_Rack) - and food plate (https://terraria.gamepedia.com/Plate). - """ - - __slots__ = "display_item", "display_type" - - def __init__(self, - display_item: typing.List[ItemStack], - display_type: str): - - self.display_item: typing.List[ItemStack] = display_item - """What item is on display.""" - - self.display_type: str = display_type - """What type of single item display this is.""" - - def __repr__(self): - return f"SingleItemDisplay(display_type={self.display_type}, display_item={self.display_item})" diff --git a/lihzahrd/items/__init__.py b/lihzahrd/items/__init__.py new file mode 100644 index 0000000..ec54bb8 --- /dev/null +++ b/lihzahrd/items/__init__.py @@ -0,0 +1,4 @@ +from .itemstack import ItemStack +from .itemtype import ItemType + +__all__ = ["ItemStack", "ItemType"] diff --git a/lihzahrd/chests/itemstack.py b/lihzahrd/items/itemstack.py similarity index 100% rename from lihzahrd/chests/itemstack.py rename to lihzahrd/items/itemstack.py diff --git a/lihzahrd/chests/itemtype.py b/lihzahrd/items/itemtype.py similarity index 100% rename from lihzahrd/chests/itemtype.py rename to lihzahrd/items/itemtype.py diff --git a/lihzahrd/tileentities/__init__.py b/lihzahrd/tileentities/__init__.py index 43e497c..fe72de9 100644 --- a/lihzahrd/tileentities/__init__.py +++ b/lihzahrd/tileentities/__init__.py @@ -2,6 +2,24 @@ from .tileentity import TileEntity from .itemframe import ItemFrame from .logicsensor import LogicSensor from .targetdummy import TargetDummy +from .clothingdisplay import ClothingDisplay +from .mannequin import Mannequin +from .hatrack import HatRack +from .singleitemdisplay import SingleItemDisplay +from .plate import Plate +from .weaponrack import WeaponRack from .pylon import Pylon -__all__ = ["TileEntity", "ItemFrame", "LogicSensor", "TargetDummy", "Pylon"] +__all__ = [ + "TileEntity", + "ItemFrame", + "LogicSensor", + "TargetDummy", + "ClothingDisplay", + "Mannequin", + "HatRack", + "SingleItemDisplay", + "Pylon", + "Plate", + "WeaponRack", +] diff --git a/lihzahrd/tileentities/clothingdisplay.py b/lihzahrd/tileentities/clothingdisplay.py new file mode 100644 index 0000000..ad06944 --- /dev/null +++ b/lihzahrd/tileentities/clothingdisplay.py @@ -0,0 +1,32 @@ +from typing import * +from ..items.itemstack import ItemStack + + +class ClothingDisplay: + """Data pertaining to an item to display clothing.""" + + __slots__ = "wearing_items", "wearing_dyes" + + def __init__(self, + wearing_items: List[ItemStack], + wearing_dyes: List[ItemStack]): + + self.wearing_items: List[ItemStack] = wearing_items + """What items is the mannequin wearing.""" + self.wearing_dyes: List[ItemStack] = wearing_dyes + """What dyes is the mannequin wearing.""" + + def __repr__(self): + return f"<{self.__class__.__qualname__} with {self.total_count} items inside>" + + @property + def items_count(self): + return len(list(filter(lambda x: x is not None, self.wearing_items))) + + @property + def dyes_count(self): + return len(list(filter(lambda x: x is not None, self.wearing_dyes))) + + @property + def total_count(self): + return self.items_count + self.dyes_count diff --git a/lihzahrd/tileentities/hatrack.py b/lihzahrd/tileentities/hatrack.py new file mode 100644 index 0000000..6d0cc5d --- /dev/null +++ b/lihzahrd/tileentities/hatrack.py @@ -0,0 +1,11 @@ +from typing import * +from ..items.itemstack import ItemStack +from .clothingdisplay import ClothingDisplay + + +class HatRack(ClothingDisplay): + """A `Hat Rack `_ containing up to 2 dyed helmets.""" + def __init__(self, wearing_items: List[ItemStack], wearing_dyes: List[ItemStack]): + super().__init__(wearing_items, wearing_dyes) + assert len(wearing_items) == 2 + assert len(wearing_dyes) == 2 diff --git a/lihzahrd/tileentities/itemframe.py b/lihzahrd/tileentities/itemframe.py index de290b7..62452ba 100644 --- a/lihzahrd/tileentities/itemframe.py +++ b/lihzahrd/tileentities/itemframe.py @@ -1,13 +1,5 @@ -from ..chests import ItemStack +from .singleitemdisplay import SingleItemDisplay -class ItemFrame: - """Data pertaining to an https://terraria.gamepedia.com/Item_Frame .""" - - __slots__ = ("item", ) - - def __init__(self, item: ItemStack): - self.item: ItemStack = item - - def __repr__(self): - return f"" +class ItemFrame(SingleItemDisplay): + """An `Item Frame `.""" diff --git a/lihzahrd/tileentities/mannequin.py b/lihzahrd/tileentities/mannequin.py new file mode 100644 index 0000000..630a6c8 --- /dev/null +++ b/lihzahrd/tileentities/mannequin.py @@ -0,0 +1,13 @@ +from typing import * +from ..items.itemstack import ItemStack +from .clothingdisplay import ClothingDisplay + + +class Mannequin(ClothingDisplay): + """A `Mannequin `_ + / `Womannequin `_ containing up to 3 dyed armor pieces and up + to 5 dyed accessories.""" + def __init__(self, wearing_items: List[ItemStack], wearing_dyes: List[ItemStack]): + super().__init__(wearing_items, wearing_dyes) + assert len(wearing_items) == 8 + assert len(wearing_dyes) == 8 diff --git a/lihzahrd/tileentities/plate.py b/lihzahrd/tileentities/plate.py new file mode 100644 index 0000000..1890a8b --- /dev/null +++ b/lihzahrd/tileentities/plate.py @@ -0,0 +1,5 @@ +from .singleitemdisplay import SingleItemDisplay + + +class Plate(SingleItemDisplay): + """A `Plate `_.""" diff --git a/lihzahrd/tileentities/singleitemdisplay.py b/lihzahrd/tileentities/singleitemdisplay.py new file mode 100644 index 0000000..834bf9c --- /dev/null +++ b/lihzahrd/tileentities/singleitemdisplay.py @@ -0,0 +1,15 @@ +from ..items.itemstack import ItemStack + + +class SingleItemDisplay: + """A display case for a single item, such as a `Weapon Rack `_, + a `Item Frame ` or a `Plate `_.""" + + __slots__ = "item", + + def __init__(self, item: ItemStack): + self.item: ItemStack = item + """The item which is on display.""" + + def __repr__(self): + return f"<{self.__class__.__qualname__} with {repr(self.item)} inside>" diff --git a/lihzahrd/tileentities/weaponrack.py b/lihzahrd/tileentities/weaponrack.py new file mode 100644 index 0000000..02a3889 --- /dev/null +++ b/lihzahrd/tileentities/weaponrack.py @@ -0,0 +1,5 @@ +from .singleitemdisplay import SingleItemDisplay + + +class WeaponRack(SingleItemDisplay): + """A `Weapon Rack `_.""" diff --git a/lihzahrd/world.py b/lihzahrd/world.py index 3e5f525..114a3cd 100644 --- a/lihzahrd/world.py +++ b/lihzahrd/world.py @@ -1,7 +1,8 @@ import uuid import math -import typing +from typing import * from .fileutils import * +from .items import * from .header import * from .tiles import * from .bestiary import * @@ -30,8 +31,8 @@ class World: bounds: Rect, size: Coordinates, difficulty: Difficulty, - drunk_world: bool, - get_good_world: bool, + is_drunk_world: bool, + is_for_the_worthy: bool, created_on, styles: Styles, backgrounds: Backgrounds, @@ -53,13 +54,13 @@ class World: tiles: TileMatrix, bestiary: Bestiary, journey_powers: JourneyPowers, - chests: typing.List[Chest], - signs: typing.List[Sign], - npcs: typing.List[NPC], - mobs: typing.List[Mob], - tile_entities: typing.List[TileEntity], - weighed_pressure_plates: typing.List[WeighedPressurePlate], - rooms: typing.List[Room], + chests: List[Chest], + signs: List[Sign], + npcs: List[NPC], + mobs: List[Mob], + tile_entities: List[TileEntity], + weighed_pressure_plates: List[WeighedPressurePlate], + rooms: List[Room], pets: Pets, halloween_today: bool, xmas_today: bool, @@ -110,11 +111,13 @@ class World: self.difficulty: Difficulty = difficulty """The `difficulty `_ the game is in.""" - self.drunk_world: bool = drunk_world - """Was this world created with the drunk worldgen seed.""" + self.is_drunk_world: bool = is_drunk_world + """If the world was created with the `5162020 ` + seed.""" - self.get_good_world: bool = get_good_world - """Was this world created with the get good worldgen seed.""" + self.is_for_the_worthy: bool = is_for_the_worthy + """Was this world created with the + `for the worthy ` seed.""" self.created_on = created_on """The date and time this world was created in.""" @@ -167,22 +170,22 @@ class World: self.tiles: TileMatrix = tiles """A matrix of all the tiles present in the world.""" - self.chests: typing.List[Chest] = chests + self.chests: List[Chest] = chests """A list of all the containers (chests, barrels) in the world.""" - self.signs: typing.List[Sign] = signs + self.signs: List[Sign] = signs """A list of all non-empty signs in the world.""" - self.npcs: typing.List[NPC] = npcs + self.npcs: List[NPC] = npcs """A list of all the NPCs currently living in the world, including the Old Man.""" - self.mobs: typing.List[Mob] = mobs + self.mobs: List[Mob] = mobs """A list of mobs in the world...?""" - self.tile_entities: typing.List[TileEntity] = tile_entities + self.tile_entities: List[TileEntity] = tile_entities """A list of tile entities in the world, such as Training Dummies, Item Frames and Logic Sensors.""" - self.weighed_pressure_plates: typing.List[WeighedPressurePlate] = weighed_pressure_plates + self.weighed_pressure_plates: List[WeighedPressurePlate] = weighed_pressure_plates """A list of all Weighed Pressure Plates in the world.""" self.pets: Pets = pets @@ -200,7 +203,7 @@ class World: self.saved_ore_tiers: SavedOreTiers = saved_ore_tiers """Probably related to drunk wordgen having both types of ores.""" - self.rooms: typing.List[Room] = rooms + self.rooms: List[Room] = rooms self.clouds: Clouds = clouds self.cultist_delay: int = cultist_delay self.unknown_file_format_data: bytes = unknown_file_format_data @@ -234,7 +237,7 @@ class World: self.shadow_orbs = value @staticmethod - def _read_tile_block(fr: FileReader, tileframeimportant) -> typing.List: + def _read_tile_block(fr: FileReader, tileframeimportant) -> List: # Once again, this code is a mess flags1 = fr.bits() has_block = flags1[1] @@ -316,15 +319,30 @@ class World: tile = Tile(block=block, wall=wall, liquid=liquid, wiring=wiring) return [tile] * multiply_by + @property + def is_classic(self): + """If the world is in classic difficulty or not.""" + return self.difficulty == 0 + @property def is_expert(self): - """If the world is in expert mode or not. + """If the world is in expert difficulty or not. Provided for compatibility purposes.""" return self.difficulty == 1 + @property + def is_master(self): + """If the world is in master difficulty or not.""" + return self.difficulty == 2 + + @property + def is_journey(self): + """If the world is in journey difficulty or not.""" + return self.difficulty == 3 + @classmethod - def _create_tilematrix(cls, f, world_size: Coordinates, tileframeimportant: typing.List[bool]): + def _create_tilematrix(cls, f, world_size: Coordinates, tileframeimportant: List[bool]): """Create a TileMatrix object from a file.""" tm = TileMatrix() while tm.size.x < world_size.x: @@ -377,8 +395,8 @@ class World: bounds = f.rect() world_size = Coordinates(y=f.int4(), x=f.int4()) difficulty = Difficulty(f.int4()) - drunk_world = f.bool() - get_good_world = f.bool() + is_drunk_world = f.bool() + is_for_the_worthy = f.bool() created_on = f.datetime() world_styles = Styles(moon=MoonStyle(f.uint1()), @@ -753,8 +771,8 @@ class World: elif te_type == 3: item_flags = f.bits() dye_flags = f.bits() - mannequin_items: typing.List[typing.Optional[ItemStack]] = [None for _ in range(len(item_flags))] - mannequin_dyes: typing.List[typing.Optional[ItemStack]] = [None for _ in range(len(dye_flags))] + mannequin_items: List[Optional[ItemStack]] = [None for _ in range(len(item_flags))] + mannequin_dyes: List[Optional[ItemStack]] = [None for _ in range(len(dye_flags))] for index, flag in enumerate(item_flags): if not flag: continue @@ -773,14 +791,14 @@ class World: # Weapon Rack elif te_type == 4: rack_item = ItemStack(ItemType(f.int2()), f.int1(), f.int2()) - te_extra = SingleItemDisplay(rack_item, "weapon_rack") + te_extra = WeaponRack(rack_item) # Hat Rack elif te_type == 5: # This isn't 100% tested, but the first two flags should be items, and the second two should be dyes. item_flags = f.bits() # Maximum of two items slots and two dye slots. - rack_items: typing.List[typing.Optional[ItemStack]] = [None for _ in range(2)] - rack_dyes: typing.List[typing.Optional[ItemStack]] = [None for _ in range(2)] + rack_items: List[Optional[ItemStack]] = [None for _ in range(2)] + rack_dyes: List[Optional[ItemStack]] = [None for _ in range(2)] for index, flag in enumerate(item_flags[0:2]): if not flag: continue @@ -799,7 +817,7 @@ class World: # Food Plate elif te_type == 6: plate_item = ItemStack(ItemType(f.int2()), f.int1(), f.int2()) - te_extra = SingleItemDisplay(plate_item, "food_plate") + te_extra = Plate(plate_item) # Teleport Pylon elif te_type == 7: te_extra = Pylon() @@ -880,7 +898,7 @@ class World: # Object creation world = cls(version=version, savefile_type=savefile_type, revision=revision, is_favorite=is_favorite, name=name, generator=generator, uuid_=uuid_, id_=id_, bounds=bounds, size=world_size, - difficulty=difficulty, drunk_world=drunk_world, get_good_world=get_good_world, + difficulty=difficulty, is_drunk_world=is_drunk_world, is_for_the_worthy=is_for_the_worthy, created_on=created_on, styles=world_styles, backgrounds=backgrounds, spawn_point=spawn_point, underground_level=underground_level, cavern_level=cavern_level, time=time, events=events, dungeon_point=dungeon_point, world_evil=world_evil,