class State: level: int = struct_field(0x0, sc_uint8) bool_tuple: Tuple[bool, ...] = struct_field(0x2, array(sc_bool, 3)) player_set: FrozenSet[Player] = struct_field(0x5, array(dc_struct, 2)) pointed_int: Optional[int] = struct_field(0xB, pointer(sc_uint16)) poly_player: PolyPointer[Player] = struct_field(0x13, poly_pointer(dc_struct))
class _RobinHoodTableEntry: hashed_key: int = struct_field(0x0, sc_uint32) # We intentionally don't use PolyPointer, to defer reading the Entity until # we know we have the right entry. entity_addr: int = struct_field(0x8, sc_void_p) SIZE: ClassVar[int] = 16
class _UnorderedMapMeta: _size_as_element_: ClassVar[int] = 64 end: int = struct_field(0x8, sc_uint64) size: int = struct_field(0x10, sc_uint64) # unused buckets_ptr: int = struct_field(0x18, sc_void_p) mask: int = struct_field(0x30, sc_uint64) bucket_size: int = struct_field(0x38, sc_uint64) # unused
class EntityReduced: type: Optional[EntityDBEntry] = struct_field(0x08, pointer(dc_struct), default=None) items: Optional[Tuple[int, ...]] = struct_field(0x18, vector(sc_uint32), default=None) position_x: float = struct_field(0x40, sc_float, default=0.0) position_y: float = struct_field(0x44, sc_float, default=0.0) layer: int = struct_field(0xA0, sc_uint8, default=Layer.FRONT)
class Inventory: # Amount of money collected in the current level money: int = struct_field(0x00, sc_uint32, default=0) bombs: int = struct_field(0x04, sc_uint8, default=4) ropes: int = struct_field(0x05, sc_uint8, default=4) poison_tick_timer: int = struct_field(0x06, sc_int16, default=-1) cursed: bool = struct_field(0x08, sc_bool, default=False) kills_level: int = struct_field(0x1424, sc_uint32, default=0) kills_total: int = struct_field(0x1428, sc_uint32, default=0) collected_money_total: int = struct_field(0x1520, sc_uint32, default=0)
class Movable(Entity): idle_counter: int = struct_field(0x100, sc_uint32, default=0) velocity_x: float = struct_field(0x108, sc_float, default=0.0) velocity_y: float = struct_field(0x10C, sc_float, default=0.0) holding_uid: int = struct_field(0x110, sc_int32, default=-1) state: CharState = struct_field(0x114, sc_uint8, default=CharState.STANDING) last_state: CharState = struct_field(0x115, sc_uint8, default=CharState.STANDING) health: int = struct_field(0x117, sc_int8, default=4)
class Items: players: Tuple[Optional[Player], ...] = struct_field(0x08, array(pointer(dc_struct), 4))
class Entity(EntityReduced): overlay: PolyPointer[EntityReduced] = struct_field( 0x10, poly_pointer(dc_struct), default_factory=PolyPointer.make_empty)
class ArenaState: format: ArenaFormat = struct_field( 0x964 - ARENA_STATE_BASE, sc_int8, default=ArenaFormat.DEATHMATCH ) ruleset: ArenaRuleset = struct_field( 0x965 - ARENA_STATE_BASE, sc_int8, default=ArenaRuleset.CUSTOM ) timer: ArenaTimer = struct_field( 0x978 - ARENA_STATE_BASE, sc_int8, default=ArenaTimer.TIME_02_00 ) timer_ending: ArenaTimerEnding = struct_field( 0x979 - ARENA_STATE_BASE, sc_int8, default=ArenaTimerEnding.ROUND_ENDS ) wins: int = struct_field(0x97A - ARENA_STATE_BASE, sc_uint8, default=5) lives: int = struct_field(0x97B - ARENA_STATE_BASE, sc_uint8, default=2) time_to_win: ArenaTimeToWin = struct_field( 0x97C - ARENA_STATE_BASE, sc_int8, default=ArenaTimeToWin.SECONDS_30 ) health: int = struct_field(0x986 - ARENA_STATE_BASE, sc_uint8, default=4) bombs: int = struct_field(0x987 - ARENA_STATE_BASE, sc_uint8, default=4) ropes: int = struct_field(0x988 - ARENA_STATE_BASE, sc_uint8, default=4) stun_time: ArenaStunTime = struct_field( 0x989 - ARENA_STATE_BASE, sc_int8, default=ArenaStunTime.X0_50 ) mount: ArenaMount = struct_field( 0x98A - ARENA_STATE_BASE, sc_int8, default=ArenaMount.NONE ) arena_select: ArenaSelect = struct_field( 0x98B - ARENA_STATE_BASE, sc_int8, default=ArenaSelect.RANDOM_LEVEL ) arenas: TupleBool40 = struct_field( 0x98C - ARENA_STATE_BASE, array(sc_bool, 40), default_factory=lambda: (False,) * 40, ) dark_level_chance: ArenaDarkLevelChance = struct_field( 0x9B4 - ARENA_STATE_BASE, sc_int8, default=ArenaDarkLevelChance.PERCENT_10 ) crate_frequency: ArenaCrateFrequency = struct_field( 0x9B5 - ARENA_STATE_BASE, sc_int8, default=ArenaCrateFrequency.MEDIUM ) items_enabled: TupleBool40 = struct_field( 0x9B6 - ARENA_STATE_BASE, array(sc_bool, 40), default_factory=lambda: (False,) * 40, ) items_in_crate: TupleBool40 = struct_field( 0x9DE - ARENA_STATE_BASE, array(sc_bool, 40), default_factory=lambda: (False,) * 40, ) held_item: ArenaItem = struct_field( 0xA06 - ARENA_STATE_BASE, sc_int8, default=ArenaItem.NOTHING ) equipped_backitem: ArenaItem = struct_field( 0xA07 - ARENA_STATE_BASE, sc_int8, default=ArenaItem.NOTHING ) equipped_items: TupleBool40 = struct_field( 0xA08 - ARENA_STATE_BASE, array(sc_bool, 40), default_factory=lambda: (False,) * 40, ) whip_damage: ArenaWhipDamage = struct_field( 0xA30 - ARENA_STATE_BASE, sc_int8, default=ArenaWhipDamage.HP_1 ) final_ghost: bool = struct_field(0xA31 - ARENA_STATE_BASE, sc_bool, default=True) breath_cooldown: ArenaBreathCooldown = struct_field( 0xA32 - ARENA_STATE_BASE, sc_int8, default=ArenaBreathCooldown.X0_50 ) punish_ball: bool = struct_field(0xA33 - ARENA_STATE_BASE, sc_bool, default=False) @staticmethod def get_enabled_items(items: Tuple[bool, ...]) -> FrozenSet[ArenaItem]: return frozenset(ArenaItem(idx) for idx, item in enumerate(items) if item) def get_enabled_levels(self) -> FrozenSet[ArenaLevel]: return frozenset( ArenaLevel(idx) for idx, level in enumerate(self.arenas) if level )
class _RobinHoodTableMeta: mask: int = struct_field(0x0, sc_uint64) table_ptr: int = struct_field(0x8, sc_void_p)
class Illumination: light_pos_x: float = struct_field(0x48, sc_float, default=0.0) light_pos_y: float = struct_field(0x4C, sc_float, default=0.0)
class LightEmitter(Movable): emitted_light: Optional[Illumination] = struct_field(0x130, pointer(dc_struct), default=None)
class State: screen_last: Screen = struct_field(0x08, sc_int32, default=Screen.LEVEL_TRANSITION) screen: Screen = struct_field(0x0C, sc_int32, default=Screen.LEVEL) screen_next: Screen = struct_field(0x10, sc_int32, default=Screen.LEVEL_TRANSITION) loading: LoadingState = struct_field(0x14, sc_int32, default=LoadingState.NOT_LOADING) quest_flags: QuestFlags = struct_field(0x38, sc_uint32, default=0) # The total amount spent at shops and stolen by leprechauns. This is non-positive during the run. # If the run ends in a victory, the bonus will be added to this during the score screen. money_shop_total: int = struct_field(0x58, sc_int32, default=0) world_start: int = struct_field(0x5C, sc_uint8, default=1) level_start: int = struct_field(0x5D, sc_uint8, default=1) theme_start: Theme = struct_field(0x5E, sc_uint8, default=Theme.DWELLING) time_total: int = struct_field(0x64, sc_uint32, default=1) world: int = struct_field(0x68, sc_uint8, default=1) world_next: int = struct_field(0x69, sc_uint8, default=1) level: int = struct_field(0x6A, sc_uint8, default=1) level_next: int = struct_field(0x6B, sc_uint8, default=2) theme: Theme = struct_field(0x74, sc_uint8, default=Theme.DWELLING) theme_next: Theme = struct_field(0x75, sc_uint8, default=Theme.DWELLING) win_state: WinState = struct_field(0x76, sc_int8, default=WinState.NO_WIN) waddler_storage: FrozenSet[EntityType] = struct_field(0x8C, array(sc_uint32, 99), default=frozenset()) arena_state: ArenaState = struct_field(0x95C, dc_struct, default_factory=ArenaState) run_recap_flags: RunRecapFlags = struct_field(0xA34, sc_uint32, default=0) hud_flags: HudFlags = struct_field(0xA50, sc_uint32, default=0) time_level: int = struct_field(0xA44, sc_uint32, default=0) presence_flags: PresenceFlags = struct_field(0xA54, sc_uint32, default=0) next_entity_uid: int = struct_field(0x12E0, sc_uint32, default=0) items: Optional[Items] = struct_field(0x12F0, pointer(dc_struct), default=None) instance_id_to_pointer: UidEntityMap = struct_field( 0x1348, uid_entity_map, default_factory=DictMap)
class Player(Movable): inventory: Optional[Inventory] = struct_field(0x140, pointer(dc_struct), default_factory=Inventory) linked_companion_child: int = struct_field(0x150, sc_int32, default=0) linked_companion_parent: int = struct_field(0x154, sc_int32, default=0)
class Supreme: num1: int = struct_field(0x0, sc_int8)
class Mount(Movable): is_tamed: bool = struct_field(0x151, sc_bool, default=False)
class _UnorderedMapBucket: _size_as_element_: ClassVar[int] = 16 first: int = struct_field(0x0, sc_void_p) last: int = struct_field(0x8, sc_void_p)
class EntityDBEntry: _size_as_element_: ClassVar[int] = 256 # Size of EntityDB struct id: EntityType = struct_field(0x14, sc_uint32) # pylint: disable=invalid-name
class Middle(Supreme): num2: int = struct_field(0x1, sc_int8)
class VecWrap: num_list: Optional[Tuple[int, ...]] = struct_field(0x1, vector(sc_uint16))
class Lowest(Middle): num3: int = struct_field(0x2, sc_int8)
class _VectorMeta: array_addr: int = struct_field(0x8, sc_void_p) size: int = struct_field(0x14, sc_uint32)
class Player: _size_as_element_: ClassVar[int] = 3 bombs: int = struct_field(0x0, sc_uint8) ropes: int = struct_field(0x1, sc_uint8)