Source code for tuxemon.config

# SPDX-License-Identifier: GPL-3.0
# Copyright (c) 2014-2023 William Edwards <shadowapex@gmail.com>, Benjamin Bean <superman2k5@gmail.com>
from __future__ import annotations

import configparser
from collections import OrderedDict
from typing import Any, Dict, Mapping, Optional

from tuxemon.animation import Animation
from tuxemon.platform.const import buttons, events

Animation.default_transition = "out_quint"


[docs]class TuxemonConfig: """ Handles loading of the config file for the primary game and map editor. Do not forget to edit the default configuration specified below! """ def __init__(self, config_path: Optional[str] = None) -> None: # load default config cfg = generate_default_config() self.cfg = cfg # update with customized values if config_path: cfg.read(config_path) # [display] resolution_x = cfg.getint("display", "resolution_x") resolution_y = cfg.getint("display", "resolution_y") self.resolution = resolution_x, resolution_y self.splash = cfg.getboolean("display", "splash") self.fullscreen = cfg.getboolean("display", "fullscreen") self.fps = cfg.getfloat("display", "fps") self.show_fps = cfg.getboolean("display", "show_fps") self.scaling = cfg.getboolean("display", "scaling") self.collision_map = cfg.getboolean("display", "collision_map") self.large_gui = cfg.getboolean("display", "large_gui") self.controller_overlay = cfg.getboolean( "display", "controller_overlay", ) self.controller_transparency = cfg.getint( "display", "controller_transparency", ) self.hide_mouse = cfg.getboolean("display", "hide_mouse") self.window_caption = cfg.get("display", "window_caption") # [game] self.data = cfg.get("game", "data") self.cli = cfg.getboolean("game", "cli_enabled") self.net_controller_enabled = cfg.getboolean( "game", "net_controller_enabled", ) self.locale = cfg.get("game", "locale") self.dev_tools = cfg.getboolean("game", "dev_tools") self.recompile_translations = cfg.getboolean( "game", "recompile_translations", ) self.skip_titlescreen = cfg.getboolean("game", "skip_titlescreen") self.compress_save: Optional[str] = cfg.get("game", "compress_save") if self.compress_save == "None": self.compress_save = None # [gameplay] self.items_consumed_on_failure = cfg.getboolean( "gameplay", "items_consumed_on_failure", ) self.encounter_rate_modifier = cfg.getfloat( "gameplay", "encounter_rate_modifier", ) self.default_monster_catch_rate = cfg.getfloat( "gameplay", "default_monster_catch_rate", ) self.default_upper_monster_catch_resistance = cfg.getfloat( "gameplay", "default_upper_monster_catch_resistance", ) self.default_lower_monster_catch_resistance = cfg.getfloat( "gameplay", "default_lower_monster_catch_resistance", ) self.dialog_speed = cfg.get( "gameplay", "dialog_speed", ) assert self.dialog_speed in ("slow", "max") # [player] self.player_animation_speed = cfg.getfloat("player", "animation_speed") self.player_npc = cfg.get("player", "player_npc") self.player_walkrate = cfg.getfloat("player", "player_walkrate") self.player_runrate = cfg.getfloat("player", "player_runrate") # [logging] # Log levels can be: debug, info, warning, error, or critical # Setting loggers to "all" will enable debug logging for all modules. # Some available loggers: # states.combat, states.world, event, # neteria.server, neteria.client, neteria.core # Comma-separated list of which modules to enable logging on loggers_str = cfg.get("logging", "loggers") self.loggers = loggers_str.replace(" ", "").split(",") self.debug_logging = cfg.getboolean("logging", "debug_logging") self.debug_level = cfg.get("logging", "debug_level") self.log_to_file = cfg.getboolean("logging", "dump_to_file") self.log_keep_max = cfg.getint("logging", "file_keep_max") # input config (None means use default for the platform) self.gamepad_deadzone = 0.25 self.gamepad_button_map = None self.keyboard_button_map = get_custom_pygame_keyboard_controls(cfg) # not configurable from the file yet self.mods = ["tuxemon"]
[docs]def get_custom_pygame_keyboard_controls( cfg: configparser.ConfigParser, ) -> Mapping[Optional[int], int]: """ Parameters: cfg: Config parser. """ import pygame.locals custom_controls: Dict[Optional[int], int] = {None: events.UNICODE} for key, values in cfg.items("controls"): key = key.upper() button_value: Optional[int] = getattr(buttons, key, None) event_value: Optional[int] = getattr(events, key, None) for each in values.split(", "): # used in case of multiple keys assigned to 1 method # pygame.locals uses all caps for constants except for letters each = each.lower() if len(each) == 1 else each.upper() pygame_value: Optional[int] = getattr( pygame.locals, "K_" + each, None ) if pygame_value is not None and button_value is not None: custom_controls[pygame_value] = button_value elif pygame_value is not None and event_value is not None: custom_controls[pygame_value] = event_value return custom_controls
[docs]def get_custom_pygame_keyboard_controls_names( cfg: configparser.ConfigParser, ) -> Mapping[Optional[str], int]: """ Basically the same thing as `get_custom_pygame_keyboard_controls()`, but returns with the key's string value instead of int Parameters: cfg: Config parser. """ custom_controls: Dict[Optional[str], int] = {None: events.UNICODE} for key, values in cfg.items("controls"): key = key.upper() button_value: Optional[int] = getattr(buttons, key, None) event_value: Optional[int] = getattr(events, key, None) # used incase of multiple keys assigned to 1 method # pygame.locals uses all caps for constants except for letters for each in values.split(", "): each = each.lower() if len(each) == 1 else each.upper() if each is not None and button_value is not None: custom_controls[each] = button_value elif each is not None and event_value is not None: custom_controls[each] = event_value return custom_controls
[docs]def get_defaults() -> Mapping[str, Any]: """ Generate a config from defaults. When making game changes, do not forget to edit this config! Returns: Mapping of default values. """ return OrderedDict( ( ( "display", OrderedDict( ( ("resolution_x", "1280"), ("resolution_y", "720"), ("splash", "True"), ("fullscreen", "False"), ("fps", "60"), ("show_fps", "False"), ("scaling", "True"), ("collision_map", "False"), ("large_gui", "False"), ("controller_overlay", "False"), ("controller_transparency", "45"), ("hide_mouse", "True"), ("window_caption", "Tuxemon"), ) ), ), ( "game", OrderedDict( ( ("data", "tuxemon"), ("skip_titlescreen", "False"), ("cli_enabled", "False"), ("net_controller_enabled", "False"), ("locale", "en_US"), ("dev_tools", "False"), ("recompile_translations", "True"), ("compress_save", "None"), ) ), ), ( "gameplay", OrderedDict( ( ("items_consumed_on_failure", "True"), ("encounter_rate_modifier", "1.0"), ("default_monster_catch_rate", "125"), ("default_upper_monster_catch_resistance", "1"), ("default_lower_monster_catch_resistance", "1"), ("dialog_speed", "slow"), ) ), ), ( "player", OrderedDict( ( ("animation_speed", "0.15"), ("player_npc", "npc_red"), ("player_walkrate", "3.75"), ("player_runrate", "7.35"), ) ), ), ( "logging", OrderedDict( ( ("loggers", "all"), ("debug_logging", "True"), ("debug_level", "error"), ("dump_to_file", "False"), ("file_keep_max", "5"), ) ), ), ( "controls", OrderedDict( ( ("up", "up"), ("down", "down"), ("left", "left"), ("right", "right"), ("a", "return"), ("b", "rshift, lshift"), ("back", "escape"), ("backspace", "backspace"), ) ), ), ) )
[docs]def generate_default_config() -> configparser.ConfigParser: """Get new config file from defaults.""" cfg = configparser.ConfigParser() cfg.read_dict(get_defaults()) return cfg