use strum::IntoEnumIterator;
use crate::prelude::*;
pub fn game_plugin(game: &mut Game) {
game.systems.add_startup_system(load_settings);
}
fn load_settings(game: &mut Game) {
let default_settings = {
let assets = game.shared_resource::<AssetServer>().unwrap();
let settings = &assets.root::<GameMeta>().default_settings;
settings.clone()
};
let mut storage = game.shared_resource_mut::<Storage>().unwrap();
if storage.get::<Settings>().is_none() {
storage.insert(default_settings);
}
}
#[derive(HasSchema, Debug, Clone)]
#[repr(C)]
pub struct Settings {
pub main_volume: f32,
pub music_volume: f32,
pub effects_volume: f32,
pub fullscreen: bool,
pub player_controls: PlayerControlMapping,
pub matchmaking_server: String,
}
impl Default for Settings {
fn default() -> Self {
Self {
main_volume: 1.0,
music_volume: 1.0,
effects_volume: 1.0,
fullscreen: true,
player_controls: default(),
matchmaking_server: default(),
}
}
}
#[derive(HasSchema, Clone, Debug, Default)]
#[repr(C)]
pub struct PlayerControlMapping {
pub gamepad: PlayerControlSetting,
pub keyboard1: PlayerControlSetting,
pub keyboard2: PlayerControlSetting,
}
impl PlayerControlMapping {
pub fn map_control_source(&self, source: ControlSource) -> &PlayerControlSetting {
match source {
ControlSource::Keyboard1 => &self.keyboard1,
ControlSource::Keyboard2 => &self.keyboard2,
ControlSource::Gamepad(_) => &self.gamepad,
}
}
pub fn all_settings(&self) -> impl Iterator<Item = &PlayerControlSetting> {
ControlSource::iter().map(|s| self.map_control_source(s))
}
}
#[derive(HasSchema, Clone, Debug, Default)]
#[repr(C)]
pub struct PlayerControlSetting {
pub movement: VirtualDPad,
pub movement_alt: VirtualDPad,
pub pause: InputKind,
pub jump: InputKind,
pub grab: InputKind,
pub shoot: InputKind,
pub slide: InputKind,
pub ragdoll: InputKind,
pub menu_back: InputKind,
pub menu_start: InputKind,
pub menu_confirm: InputKind,
}
#[derive(HasSchema, Clone, Debug, Default)]
#[repr(C)]
pub struct VirtualDPad {
pub up: InputKind,
pub down: InputKind,
pub left: InputKind,
pub right: InputKind,
}
#[derive(HasSchema, Clone, Debug, Default)]
#[repr(C, u8)]
pub enum InputKind {
#[default]
None,
Button(GamepadButton),
AxisPositive(GamepadAxis),
AxisNegative(GamepadAxis),
Keyboard(KeyCode),
}
impl std::fmt::Display for InputKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
InputKind::None => write!(f, "[None]"),
InputKind::Button(btn) => write!(f, "{btn}"),
InputKind::AxisPositive(axis) => write!(f, "{axis} +"),
InputKind::AxisNegative(axis) => write!(f, "{axis} -"),
InputKind::Keyboard(key) => write!(f, "{key:?}"),
}
}
}