mirror of
https://github.com/Steffo99/lihzahrd.git
synced 2024-11-21 15:44:24 +00:00
Added parsing for bestiary and journey mode powers.
Journey mode powers could use some convenience functions to map and from the values shown in the game.
This commit is contained in:
parent
76944e5c63
commit
a7827e2e8e
9 changed files with 162 additions and 12 deletions
|
@ -1,5 +1,5 @@
|
|||
import lihzahrd
|
||||
|
||||
world = lihzahrd.World.create_from_file("test-1404.wld")
|
||||
world = lihzahrd.World.create_from_file("test-1404j.wld")
|
||||
|
||||
breakpoint()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from .world import World
|
||||
from . import chests, fileutils, header, npcs, pressureplates, signs, tileentities, tiles, townmanager
|
||||
from . import bestiary, chests, fileutils, header, journeypowers, npcs, pressureplates, signs, tileentities, tiles, townmanager
|
||||
|
||||
__all__ = ["World", "chests", "fileutils", "header", "npcs", "pressureplates", "signs", "tileentities", "tiles",
|
||||
__all__ = ["World", "bestiary", "chests", "fileutils", "header", "journeypowers", "npcs", "pressureplates", "signs", "tileentities", "tiles",
|
||||
"townmanager"]
|
||||
|
|
3
lihzahrd/bestiary/__init__.py
Executable file
3
lihzahrd/bestiary/__init__.py
Executable file
|
@ -0,0 +1,3 @@
|
|||
from .bestiary import Bestiary
|
||||
|
||||
__all__ = ["Bestiary"]
|
23
lihzahrd/bestiary/bestiary.py
Executable file
23
lihzahrd/bestiary/bestiary.py
Executable file
|
@ -0,0 +1,23 @@
|
|||
import typing
|
||||
|
||||
class Bestiary:
|
||||
"""A bestiary entry."""
|
||||
|
||||
__slots__ = "npc_chats_count", "npc_chats_data", "npc_kill_count","npc_kill_data", "npc_sighting_count", "npc_sighting_data"
|
||||
|
||||
def __init__(self,
|
||||
npc_chats_count: int,
|
||||
npc_chats_data: typing.Dict[str, int],
|
||||
npc_kill_count: int,
|
||||
npc_kill_data: typing.List[str],
|
||||
npc_sighting_count: int,
|
||||
npc_sighting_data: typing.List[str],):
|
||||
self.npc_chats_count: int = npc_chats_count
|
||||
self.npc_chats_data: typing.Dict[str, int] = npc_chats_data
|
||||
self.npc_kill_count: int = npc_kill_count
|
||||
self.npc_kill_data: typing.List[str] = npc_kill_data
|
||||
self.npc_sighting_count: int = npc_sighting_count
|
||||
self.npc_sighting_data: typing.List[str] = npc_sighting_data
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Bestiary entry: chats={self.npc_chats_count}: {self.npc_chats_data}, kills={self.npc_kill_count}: {self.npc_kill_data}, sightings={self.npc_sighting_count}: {self.npc_sighting_data}>"
|
|
@ -11,6 +11,8 @@ class Pointers:
|
|||
tile_entities: int,
|
||||
pressure_plates: int,
|
||||
town_manager: int,
|
||||
bestiary: int,
|
||||
journey_powers: int,
|
||||
footer: int,
|
||||
*unknown):
|
||||
self.file_format: int = 0
|
||||
|
@ -22,5 +24,7 @@ class Pointers:
|
|||
self.tile_entities: int = tile_entities
|
||||
self.pressure_plates: int = pressure_plates
|
||||
self.town_manager: int = town_manager
|
||||
self.bestiary: int = bestiary
|
||||
self.journey_powers: int = journey_powers
|
||||
self.footer: int = footer
|
||||
self.unknown: typing.List[int] = list(unknown)
|
||||
|
|
3
lihzahrd/journeypowers/__init__.py
Executable file
3
lihzahrd/journeypowers/__init__.py
Executable file
|
@ -0,0 +1,3 @@
|
|||
from .journeypowers import JourneyPowers
|
||||
|
||||
__all__ = ["JourneyPowers"]
|
45
lihzahrd/journeypowers/journeypowers.py
Executable file
45
lihzahrd/journeypowers/journeypowers.py
Executable file
|
@ -0,0 +1,45 @@
|
|||
import typing
|
||||
|
||||
class JourneyPowers:
|
||||
"""Journey mode powers settings. Spawn rate does not appear to be stored in the world."""
|
||||
|
||||
__slots__ = "freeze_time", "god_mode", "time_rate", "freeze_rain", "freeze_wind", "far_placement_range", "difficulty", "freeze_biome_spread", "spawn_rate"
|
||||
|
||||
def __init__(self,
|
||||
freeze_time: typing.Optional[bool] = None,
|
||||
god_mode: typing.Optional[bool] = None,
|
||||
time_rate: typing.Optional[float] = None,
|
||||
freeze_rain: typing.Optional[bool] = None,
|
||||
freeze_wind: typing.Optional[bool] = None,
|
||||
far_placement_range: typing.Optional[bool] = None,
|
||||
difficulty: typing.Optional[float] = None,
|
||||
freeze_biome_spread: typing.Optional[bool] = None,):
|
||||
|
||||
self.freeze_time: bool = freeze_time
|
||||
"""Can time be frozen."""
|
||||
|
||||
self.god_mode: bool = god_mode
|
||||
"""Can god mode be enabled."""
|
||||
|
||||
self.time_rate: float = time_rate
|
||||
"""How fast does time go, 1x to 24x. Value ranges from 0.0 to 1.0."""
|
||||
|
||||
self.freeze_rain: bool = freeze_rain
|
||||
"""Can the rain change."""
|
||||
|
||||
self.freeze_wind: bool = freeze_wind
|
||||
"""Can the wind speed and direction change."""
|
||||
|
||||
self.far_placement_range: bool = far_placement_range
|
||||
"""Can players place blocks further than normal."""
|
||||
|
||||
self.difficulty: float = difficulty
|
||||
"""Enemy difficulty scaling, 0.5x to 3x. Value ranges from 0.0 to 1.0."""
|
||||
|
||||
self.freeze_biome_spread: bool = freeze_biome_spread
|
||||
"""Can evil biomes & the hallow spread."""
|
||||
|
||||
def __repr__(self):
|
||||
return f"<JourneyPowers: freeze_time={self.freeze_time}, god_mode={self.god_mode}, freeze_rain={self.freeze_rain}," \
|
||||
f"freeze_wind={self.freeze_wind}, far_placement={self.far_placement_range}, biome_spread={self.freeze_biome_spread}," \
|
||||
f"time_rate={self.time_rate}, difficulty={self.difficulty}>"
|
|
@ -6,13 +6,14 @@ from ..fileutils import Coordinates
|
|||
class NPC:
|
||||
"""A NPC somewhere in the world."""
|
||||
|
||||
__slots__ = "type", "name", "position", "home"
|
||||
__slots__ = "type", "name", "position", "home", "variation_index"
|
||||
|
||||
def __init__(self,
|
||||
type_: EntityType,
|
||||
name: str,
|
||||
position: Coordinates,
|
||||
home: typing.Optional[Coordinates] = None):
|
||||
type_: EntityType,
|
||||
name: str,
|
||||
position: Coordinates,
|
||||
variation_index: int,
|
||||
home: typing.Optional[Coordinates] = None,):
|
||||
self.type: EntityType = type_
|
||||
"""The NPC this object represents."""
|
||||
|
||||
|
@ -25,5 +26,8 @@ class NPC:
|
|||
self.home: typing.Optional[Coordinates] = home
|
||||
"""The coordinates of the home of this NPC, or None if the NPC is homeless."""
|
||||
|
||||
self.variation_index: int = variation_index
|
||||
"""Unsure, but seems to be an index to different possible NPC variations."""
|
||||
|
||||
def __repr__(self):
|
||||
return f"<NPC {repr(self.type)} at {self.position}>"
|
||||
|
|
|
@ -4,6 +4,8 @@ import typing
|
|||
from .fileutils import *
|
||||
from .header import *
|
||||
from .tiles import *
|
||||
from .bestiary import *
|
||||
from .journeypowers import *
|
||||
from .chests import *
|
||||
from .signs import *
|
||||
from .npcs import *
|
||||
|
@ -49,6 +51,8 @@ class World:
|
|||
clouds: Clouds,
|
||||
cultist_delay: int,
|
||||
tiles: TileMatrix,
|
||||
bestiary: Bestiary,
|
||||
journey_powers: JourneyPowers,
|
||||
chests: typing.List[Chest],
|
||||
signs: typing.List[Sign],
|
||||
npcs: typing.List[NPC],
|
||||
|
@ -69,7 +73,9 @@ class World:
|
|||
unknown_npcs_data: bytes = b"",
|
||||
unknown_tile_entities_data: bytes = b"",
|
||||
unknown_pressure_plates_data: bytes = b"",
|
||||
unknown_town_manager_data: bytes = b""):
|
||||
unknown_town_manager_data: bytes = b"",
|
||||
unknown_bestiary_data: bytes = b"",
|
||||
unknown_journey_powers_data: bytes = b""):
|
||||
|
||||
self.version: Version = version
|
||||
"""The game version when this savefile was last saved."""
|
||||
|
@ -210,6 +216,12 @@ class World:
|
|||
self.unknown_pressure_plates_data: bytes = unknown_pressure_plates_data
|
||||
self.unknown_town_manager_data: bytes = unknown_town_manager_data
|
||||
|
||||
self.bestiary: Bestiary = bestiary
|
||||
"""Information about the bestiary, including sightings, kills and takling to NPCs."""
|
||||
|
||||
self.journey_powers: JourneyPowers= journey_powers
|
||||
"""Status of powers available in Journey mode."""
|
||||
|
||||
def __repr__(self):
|
||||
return f'<World "{self.name}">'
|
||||
|
||||
|
@ -676,10 +688,14 @@ class World:
|
|||
if is_homeless:
|
||||
npc_home = None
|
||||
|
||||
npc_flags = f.bits()
|
||||
npc_variation_index = 0 if npc_flags[0] else f.int4()
|
||||
|
||||
npc = NPC(type_=npc_type,
|
||||
name=npc_name,
|
||||
position=npc_position,
|
||||
home=npc_home)
|
||||
home=npc_home,
|
||||
variation_index=npc_variation_index)
|
||||
npcs.append(npc)
|
||||
|
||||
while f.bool():
|
||||
|
@ -735,7 +751,56 @@ class World:
|
|||
room = Room(npc=EntityType(f.int4()), position=Coordinates(f.int4(), f.int4()))
|
||||
rooms.append(room)
|
||||
|
||||
unknown_town_manager_data = f.read_until(pointers.footer)
|
||||
unknown_town_manager_data = f.read_until(pointers.bestiary)
|
||||
|
||||
bestiary_kill_count = f.int4()
|
||||
bestiary_kill_data = {f.string(): f.int4() for _ in range(bestiary_kill_count)}
|
||||
bestiary_sighting_count = f.int4()
|
||||
bestiary_sighting_data = [f.string() for _ in range(bestiary_sighting_count)]
|
||||
bestiary_chat_count = f.int4()
|
||||
bestiary_chat_data = [f.string() for _ in range(bestiary_chat_count)]
|
||||
bestiary = Bestiary(bestiary_chat_count,
|
||||
bestiary_chat_data,
|
||||
bestiary_kill_count,
|
||||
bestiary_kill_data,
|
||||
bestiary_sighting_count,
|
||||
bestiary_sighting_data)
|
||||
unknown_bestiary_data = f.read_until(pointers.journey_powers)
|
||||
|
||||
while f.bool():
|
||||
journey_powers = JourneyPowers()
|
||||
power_id = f.int2()
|
||||
if power_id == 0:
|
||||
freeze_time = f.bool()
|
||||
journey_powers.freeze_time = freeze_time
|
||||
elif power_id == 5:
|
||||
god_mode = f.bool()
|
||||
journey_powers.god_mode = god_mode
|
||||
elif power_id == 8:
|
||||
time_rate = f.single()
|
||||
journey_powers.time_rate = time_rate
|
||||
elif power_id == 9:
|
||||
freeze_rain = f.bool()
|
||||
journey_powers.freeze_rain = freeze_rain
|
||||
elif power_id == 10:
|
||||
freeze_wind = f.bool()
|
||||
journey_powers.freeze_wind = freeze_wind
|
||||
elif power_id == 11:
|
||||
far_placement_range = f.bool()
|
||||
journey_powers.far_placement_range = far_placement_range
|
||||
elif power_id == 12:
|
||||
difficulty = f.single()
|
||||
journey_powers.difficulty = difficulty
|
||||
elif power_id == 13:
|
||||
freeze_biome_spread = f.bool()
|
||||
journey_powers.freeze_biome_spread = freeze_biome_spread
|
||||
elif power_id == -1:
|
||||
spawn_rate: f.single()
|
||||
journey_powers.spawn_rate = spawn_rate
|
||||
else:
|
||||
print(f"Unknown id: {power_id}")
|
||||
|
||||
unknown_journey_powers_data = f.read_until(pointers.footer)
|
||||
|
||||
# Object creation
|
||||
world = cls(version=version, savefile_type=savefile_type, revision=revision, is_favorite=is_favorite,
|
||||
|
@ -751,6 +816,7 @@ class World:
|
|||
weighed_pressure_plates=weighed_pressure_plates, rooms=rooms,
|
||||
halloween_today=halloween_today, xmas_today=xmas_today,
|
||||
treetop_variants=treetop_variants, saved_ore_tiers=saved_ore_tiers, pets=pets,
|
||||
bestiary=bestiary, journey_powers=journey_powers,
|
||||
unknown_file_format_data=unknown_file_format_data,
|
||||
unknown_world_header_data=unknown_world_header_data,
|
||||
unknown_world_tiles_data=unknown_world_tiles_data,
|
||||
|
@ -759,7 +825,9 @@ class World:
|
|||
unknown_npcs_data=unknown_npcs_data,
|
||||
unknown_tile_entities_data=unknown_tile_entities_data,
|
||||
unknown_pressure_plates_data=unknown_pressure_plates_data,
|
||||
unknown_town_manager_data=unknown_town_manager_data)
|
||||
unknown_town_manager_data=unknown_town_manager_data,
|
||||
unknown_bestiary_data=unknown_bestiary_data,
|
||||
unknown_journey_powers_data=unknown_journey_powers_data)
|
||||
|
||||
# Footer
|
||||
if not f.bool():
|
||||
|
|
Loading…
Reference in a new issue