121 lines
3.4 KiB
Python
121 lines
3.4 KiB
Python
"""Handle the loading and initialization of game sessions."""
|
|
from __future__ import annotations
|
|
|
|
import copy
|
|
import lzma
|
|
import pickle
|
|
import traceback
|
|
from typing import Optional
|
|
|
|
import tcod
|
|
|
|
import color
|
|
from engine import Engine
|
|
import entity_factories
|
|
from game_map import GameWorld
|
|
import input_handlers
|
|
|
|
# Load the background image and remove the alpha channel.
|
|
background_image = tcod.image.load("menu_background.png")[:, :, :3]
|
|
|
|
|
|
def new_game() -> Engine:
|
|
"""Return a brand new game session as an Engine instance."""
|
|
map_width = 80
|
|
map_height = 43
|
|
|
|
room_max_size = 10
|
|
room_min_size = 6
|
|
max_rooms = 30
|
|
|
|
max_monsters_per_room = 2
|
|
max_items_per_room = 2
|
|
|
|
player = copy.deepcopy(entity_factories.player)
|
|
|
|
engine = Engine(player)
|
|
|
|
engine.game_world = GameWorld(
|
|
engine=engine,
|
|
max_rooms=max_rooms,
|
|
room_min_size=room_min_size,
|
|
room_max_size=room_max_size,
|
|
map_width=map_width,
|
|
map_height=map_height,
|
|
max_monsters_per_room=max_monsters_per_room,
|
|
max_items_per_room=max_items_per_room,
|
|
)
|
|
engine.game_world.generate_floor()
|
|
engine.update_fov()
|
|
|
|
engine.message_log.add_message(
|
|
"Hello and welcome, adventurer, to yet another dungeon!",
|
|
color.welcome_text
|
|
)
|
|
|
|
return engine
|
|
|
|
|
|
def load_game(filename: str) -> Engine:
|
|
"""Load an engine instance from a file."""
|
|
with open(filename, "rb") as f:
|
|
engine = pickle.loads(lzma.decompress(f.read()))
|
|
assert isinstance(engine, Engine)
|
|
|
|
return engine
|
|
|
|
|
|
class MainMenu(input_handlers.BaseEventHandler):
|
|
"""Handle the main menu rendering and input."""
|
|
|
|
def on_render(self, console: tcod.Console) -> None:
|
|
"""Render the main menu on a background image."""
|
|
console.draw_semigraphics(background_image, 0, 0)
|
|
|
|
console.print(
|
|
console.width // 2,
|
|
console.height // 2 - 4,
|
|
"TOMBS OF THE ANCIENT KINGS",
|
|
fg=color.menu_title,
|
|
alignment=tcod.CENTER,
|
|
)
|
|
console.print(
|
|
console.width // 2,
|
|
console.height - 2,
|
|
"By Timothy J. Warren",
|
|
fg=color.menu_title,
|
|
alignment=tcod.CENTER,
|
|
)
|
|
|
|
menu_width = 24
|
|
for i, text in enumerate([
|
|
"[N] Play a new game",
|
|
"[C] Continue last game",
|
|
"[Q] Quit"
|
|
]):
|
|
console.print(
|
|
console.width // 2,
|
|
console.height // 2 - 2 + i,
|
|
text.ljust(menu_width),
|
|
fg=color.menu_text,
|
|
bg=color.black,
|
|
alignment=tcod.CENTER,
|
|
bg_blend=tcod.BKGND_ALPHA(64),
|
|
)
|
|
|
|
def ev_keydown(self, event: tcod.event.KeyDown) -> Optional[input_handlers.BaseEventHandler]:
|
|
if event.sym in (tcod.event.K_q, tcod.event.K_ESCAPE):
|
|
raise SystemExit()
|
|
elif event.sym == tcod.event.K_c:
|
|
try:
|
|
return input_handlers.MainGameEventHandler(load_game("savegame.sav"))
|
|
except FileNotFoundError:
|
|
return input_handlers.PopupMessage(self, "No saved game to load.")
|
|
except Exception as exc:
|
|
traceback.print_exc() # Print to stderr.
|
|
return input_handlers.PopupMessage(self, f"Failed to load save:\n{exc}")
|
|
elif event.sym == tcod.event.K_n:
|
|
return input_handlers.MainGameEventHandler(new_game())
|
|
|
|
return None
|