from __future__ import annotations
import json
import logging
import os
import time
from typing import TYPE_CHECKING
import pygame
from scripts.engine.internal.constant import DATA_PATH, InputIntent
from scripts.engine.internal.definition import (
ActorData,
AfflictionData,
GameConfigData,
GodData,
MapData,
RoomConceptData,
SecondaryStatModData,
SkillData,
TerrainData,
TraitData,
VideoConfigData,
)
from scripts.engine.internal.extend_json import deserialise_dataclasses
if TYPE_CHECKING:
from typing import Dict, List
__all__ = [
"TRAITS",
"AFFLICTIONS",
"TERRAIN",
"SECONDARY_STAT_MODS",
"GODS",
"SKILLS",
"MAPS",
"ACTORS",
"ROOMS",
"INPUT_CONFIG",
"VIDEO_CONFIG",
"GAME_CONFIG",
"refresh_library",
]
#################################################################
# This module is for loading external data that is offered to the
# rest of the engine as a reference.
#################################################################
####################### DATA DICTS ##############################
TRAITS: Dict[str, TraitData] = {}
AFFLICTIONS: Dict[str, AfflictionData] = {}
TERRAIN: Dict[str, TerrainData] = {}
SECONDARY_STAT_MODS: Dict[str, SecondaryStatModData] = {}
GODS: Dict[str, GodData] = {}
SKILLS: Dict[str, SkillData] = {}
BLESSINGS: Dict[str, Dict] = {}
MAPS: Dict[str, MapData] = {}
ROOMS: Dict[str, RoomConceptData] = {}
ACTORS: Dict[str, ActorData] = {}
INPUT_CONFIG: Dict[str, List[str]] = {}
# load with defaults, overidden by refresh
VIDEO_CONFIG: VideoConfigData = VideoConfigData()
GAME_CONFIG: GameConfigData = GameConfigData()
# build default list for input - needed in case json doesnt include all required values
for member in InputIntent.__dict__.keys():
if member[:2] != "__":
INPUT_CONFIG[member.lower()] = []
####################### REFRESH ##############################
[docs]def refresh_library():
"""
Load all json data into the library.
"""
if "GENERATING_SPHINX_DOCS" in os.environ: # when building in CI these fail
return
start_time = time.time()
_load_traits_data()
_load_affliction_data()
_load_terrain_data()
_load_secondary_stat_mod_data()
_load_gods_data()
_load_skills_data()
_load_blessings_data()
_load_map_data()
_load_room_data()
_load_npc_data()
_load_input_config()
_load_video_config()
_load_game_config()
logging.info(f"Library data refreshed...")
end_time = time.time()
logging.debug(f"-> loaded data in {format(end_time - start_time, '.5f')}")
####################### LOAD ##############################
def _load_affliction_data():
with open(str(DATA_PATH / "game/afflictions.json")) as file:
data = json.load(file, object_hook=deserialise_dataclasses)
global AFFLICTIONS
AFFLICTIONS = data
def _load_terrain_data():
global TERRAIN
TERRAIN = {}
with open("data/game/terrain.json") as file:
data = json.load(file, object_hook=deserialise_dataclasses)
TERRAIN = data
def _load_traits_data():
with open(str(DATA_PATH / "game/traits.json")) as file:
data = json.load(file, object_hook=deserialise_dataclasses)
global TRAITS
TRAITS = data
def _load_secondary_stat_mod_data():
with open(str(DATA_PATH / "game/secondary_stat_mods.json")) as file:
data = json.load(file, object_hook=deserialise_dataclasses)
global SECONDARY_STAT_MODS
SECONDARY_STAT_MODS = data
def _load_gods_data():
with open(str(DATA_PATH / "game/gods.json")) as file:
data = json.load(file, object_hook=deserialise_dataclasses)
global GODS
GODS = data
def _load_skills_data():
with open(str(DATA_PATH / "game/skills.json")) as file:
data = json.load(file, object_hook=deserialise_dataclasses)
global SKILLS
SKILLS = data
def _load_blessings_data():
with open(str(DATA_PATH / "game/blessings.json")) as file:
data = json.load(file, object_hook=deserialise_dataclasses)
global BLESSINGS
BLESSINGS = data
def _load_map_data():
with open(str(DATA_PATH / "game/maps.json")) as file:
data = json.load(file, object_hook=deserialise_dataclasses)
global MAPS
MAPS = data
def _load_room_data():
with open(str(DATA_PATH / "game/rooms.json")) as file:
data = json.load(file, object_hook=deserialise_dataclasses)
global ROOMS
ROOMS = data
def _load_npc_data():
with open(str(DATA_PATH / "game/actors.json")) as file:
data = json.load(file, object_hook=deserialise_dataclasses)
global ACTORS
ACTORS = data
def _load_input_config():
"""
Load the input config and map to pygame constants
"""
with open(str(DATA_PATH / "config/input.json")) as file:
data = json.load(file, object_hook=deserialise_dataclasses)
_input_list = {}
# unpack input config
for key, values in data.items():
inputs = []
for value in values:
try:
# try to map the string to a pygame constant
pygame_constant = getattr(pygame, value)
# is the input already mapped to another intent?
if not any(pygame_constant in sublist for sublist in _input_list.values()):
inputs.append(pygame_constant)
else:
logging.warning(f"{value} already mapped to another intent in input.json. Not added to {key}")
except AttributeError:
logging.warning(f"{value} specified in input.json not found in pygame constants.")
# add gathered values
_input_list[key] = inputs
# add mapped data
global INPUT_CONFIG
INPUT_CONFIG = _input_list
def _load_video_config():
"""
Load the _video config
"""
with open(str(DATA_PATH / "config/video.json")) as file:
data = json.load(file, object_hook=deserialise_dataclasses)
global VIDEO_CONFIG
VIDEO_CONFIG = data
def _load_game_config():
"""
Load the game config
"""
with open(str(DATA_PATH / "config/game.json")) as file:
data = json.load(file, object_hook=deserialise_dataclasses)
global GAME_CONFIG
GAME_CONFIG = data
####################### REFRESH ON INIT ##############################
if "GENERATING_SPHINX_DOCS" not in os.environ: # when building in CI these fail
# Refresh the library immediately on init. Need this to ensure everything here is init'd and updated.
refresh_library()