mod game_keybinds;
mod game_mode_settings;
mod gameplay_preferences;
mod graphics_settings;
pub use game_keybinds::GameKeybinds;
pub use game_mode_settings::{CustomModeConfig, GameModeSettings};
pub use gameplay_preferences::GameplayPreferences;
pub use graphics_settings::{
GraphicsSettings, MaybeOverride, TileTexture,
hard_drop_effect::HardDropEffect,
line_clear_effect::{LineClearEffect, LineClearInlineEffect, LineClearParticleEffect},
lock_effect::LockEffect,
mini_tetromino_symbols::MiniTetrominoSymbols,
small_tetromino_symbols::SmallTetrominoSymbols,
tile_coloring::{ColorID, TileColoring},
tile_symbols::TileSymbols,
tui_coloring::TuiColoring,
tui_symbols::TuiSymbols,
};
use crate::{
fmt_helpers::to_roman,
settings::{
game_keybinds::game_keybinds_presets,
gameplay_preferences::gameplay_settings_presets,
graphics_settings::{
graphics_settings_presets, hard_drop_effect::hard_drop_effect_presets,
line_clear_effect::line_clear_effect_presets, lock_effect::lock_effect_presets,
mini_tetromino_symbols::mini_tetromino_symbols_presets,
small_tetromino_symbols::small_tetromino_symbols_presets,
tile_coloring::tile_coloring_presets, tile_symbols::tile_symbols_presets,
tui_coloring::tui_coloring_presets, tui_symbols::tui_symbols_presets,
},
},
};
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct Settings {
pub graphics_selected: usize,
#[serde(rename = "GRAPHICS_SLOTS")]
pub graphics_slotmachine: SlotMachine<GraphicsSettings>,
#[serde(rename = "UI_COLORING_SLOTS")]
pub tui_coloring_slotmachine: SlotMachine<TuiColoring>,
#[serde(rename = "UI_SYMBOLS_SLOTS")]
pub tui_symbols_slotmachine: SlotMachine<TuiSymbols>,
#[serde(rename = "TILE_COLORING_SLOTS")]
pub tile_coloring_slotmachine: SlotMachine<TileColoring>,
#[serde(rename = "TILE_SYMBOLS_SLOTS")]
pub tile_symbols_slotmachine: SlotMachine<TileSymbols>,
#[serde(rename = "HARD_DROP_EFFECT_SLOTS")]
pub hard_drop_effect_slotmachine: SlotMachine<HardDropEffect>,
#[serde(rename = "LOCK_EFFECT_SLOTS")]
pub lock_effect_slotmachine: SlotMachine<LockEffect>,
#[serde(rename = "LINE_CLEAR_EFFECT_SLOTS")]
pub line_clear_effect_slotmachine: SlotMachine<LineClearEffect>,
#[serde(rename = "MINI_TETROMINO_SYMBOLS_SLOTS")]
pub mini_tetromino_symbols_slotmachine: SlotMachine<MiniTetrominoSymbols>,
#[serde(rename = "SMALL_TETROMINO_SYMBOLS_SLOTS")]
pub small_tetromino_symbols_slotmachine: SlotMachine<SmallTetrominoSymbols>,
pub keybinds_selected: usize,
#[serde(rename = "GAME_KEYBINDS_SLOTS")]
pub keybinds_slotmachine: SlotMachine<GameKeybinds>,
pub gameplay_selected: usize,
#[serde(rename = "GAMEPLAY_PREFERENCES_SLOTS")]
pub gameplay_slotmachine: SlotMachine<GameplayPreferences>,
#[serde(rename = "GAME_MODE_SETTINGS")]
pub game_mode_preferences: GameModeSettings,
}
impl Default for Settings {
fn default() -> Self {
Self {
graphics_selected: 0,
graphics_slotmachine: graphics_settings_presets(),
tui_coloring_slotmachine: tui_coloring_presets(),
tile_coloring_slotmachine: tile_coloring_presets(),
tui_symbols_slotmachine: tui_symbols_presets(),
tile_symbols_slotmachine: tile_symbols_presets(),
hard_drop_effect_slotmachine: hard_drop_effect_presets(),
lock_effect_slotmachine: lock_effect_presets(),
line_clear_effect_slotmachine: line_clear_effect_presets(),
mini_tetromino_symbols_slotmachine: mini_tetromino_symbols_presets(),
small_tetromino_symbols_slotmachine: small_tetromino_symbols_presets(),
keybinds_selected: 0,
keybinds_slotmachine: game_keybinds_presets(),
gameplay_selected: 0,
gameplay_slotmachine: gameplay_settings_presets(),
game_mode_preferences: GameModeSettings::default(),
}
}
}
impl Settings {
pub fn tui_coloring(&self) -> &TuiColoring {
&self
.tui_coloring_slotmachine
.grab(self.graphics().tui_coloring_selected)
.1
}
pub fn tile_coloring(&self) -> &TileColoring {
&self
.tile_coloring_slotmachine
.grab(self.graphics().tile_coloring_selected)
.1
}
pub fn tui_symbols(&self) -> &TuiSymbols {
&self
.tui_symbols_slotmachine
.grab(self.graphics().tui_symbols_selected)
.1
}
pub fn tile_symbols(&self) -> &TileSymbols {
&self
.tile_symbols_slotmachine
.grab(self.graphics().tile_symbols_selected)
.1
}
pub fn hard_drop_effect(&self) -> &HardDropEffect {
&self
.hard_drop_effect_slotmachine
.grab(self.graphics().hard_drop_selected)
.1
}
pub fn lock_effect(&self) -> &LockEffect {
&self
.lock_effect_slotmachine
.grab(self.graphics().lock_effect_selected)
.1
}
pub fn line_clear_effect(&self) -> &LineClearEffect {
&self
.line_clear_effect_slotmachine
.grab(self.graphics().line_clear_selected)
.1
}
pub fn mini_tetromino_symbols(&self) -> &MiniTetrominoSymbols {
&self
.mini_tetromino_symbols_slotmachine
.grab(self.graphics().mini_tetromino_symbols_selected)
.1
}
pub fn small_tetromino_symbols(&self) -> &SmallTetrominoSymbols {
&self
.small_tetromino_symbols_slotmachine
.grab(self.graphics().small_tetromino_symbols_selected)
.1
}
pub fn graphics(&self) -> &GraphicsSettings {
&self.graphics_slotmachine.grab(self.graphics_selected).1
}
pub fn keybinds(&self) -> &GameKeybinds {
&self.keybinds_slotmachine.grab(self.keybinds_selected).1
}
pub fn gameplay(&self) -> &GameplayPreferences {
&self.gameplay_slotmachine.grab(self.gameplay_selected).1
}
pub fn graphics_mut(&mut self) -> &mut GraphicsSettings {
&mut self.graphics_slotmachine.grab_mut(self.graphics_selected).1
}
pub fn keybinds_mut(&mut self) -> &mut GameKeybinds {
&mut self.keybinds_slotmachine.grab_mut(self.keybinds_selected).1
}
pub fn gameplay_mut(&mut self) -> &mut GameplayPreferences {
&mut self.gameplay_slotmachine.grab_mut(self.gameplay_selected).1
}
}
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct SlotMachine<T> {
pub unmodifiable_slots: usize,
pub name_template: String,
pub slots: Vec<(String, T)>,
}
impl<T: Clone> SlotMachine<T> {
pub fn with_unmodifiable_slots(
slots: Vec<(String, T)>,
cloned_slot_name_template: String,
) -> Self {
let num_unmodifiable_slots = slots.len();
Self {
slots,
unmodifiable_slots: num_unmodifiable_slots,
name_template: cloned_slot_name_template,
}
}
pub fn grab(&self, mut idx: usize) -> &(String, T) {
if idx >= self.slots.len() {
idx = 0;
}
&self.slots[idx]
}
pub fn grab_mut(&mut self, mut idx: usize) -> &mut (String, T) {
if idx >= self.slots.len() {
idx = 0;
}
&mut self.slots[idx]
}
pub fn clone_slot_if_unmodifiable(&mut self, slot_idx: usize) -> Option<usize> {
slot_idx.lt(&self.unmodifiable_slots).then(|| {
let cloned_slot_content = self.slots[slot_idx].1.clone();
let mut n = 1;
let cloned_slot_name = loop {
let name = format!("{} {}", self.name_template, to_roman(n));
if self.slots.iter().all(|s| s.0 != name) {
break name;
}
n += 1;
};
self.slots.push((cloned_slot_name, cloned_slot_content));
self.slots.len() - 1
})
}
}