Add Stone and Tunnel, refactor CellStructure

Introduce new building types Stone and Tunnel with their own tag, color,
and
properties. CellStructure now holds these structs (Tunnel, Stone)
instead of
simple variants. BaseBuilding is simplified to return a char tag and a
color
based on owner. BoardState creation and CellWidget rendering are updated
to
use the new building structs and their methods.
This commit is contained in:
2026-04-19 20:00:59 +02:00
parent 54e86b2688
commit 33088dc29d
8 changed files with 119 additions and 46 deletions
+7 -3
View File
@@ -1,4 +1,8 @@
use crate::app::states::skirmish_states::{BoardState, buildings::BaseBuilding, units::MinerUnit};
use crate::app::states::skirmish_states::{
BoardState,
buildings::{BaseBuilding, Stone, Tunnel},
units::MinerUnit,
};
use clap::ValueEnum;
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -30,8 +34,8 @@ pub enum Players {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CellStructure {
Base(BaseBuilding),
Tunel,
Stone,
Tunnel(Tunnel),
Stone(Stone),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+6 -2
View File
@@ -2,7 +2,11 @@ use crate::app::{
helpers::{CellSizes, cell_size_helper, cells_area_helper},
states::{
CellStructure, FocusedCell, Offset, Players, Units, ZoomLevel,
skirmish_states::{MoveFocusedCell, buildings::BaseBuilding, units::MinerUnit},
skirmish_states::{
MoveFocusedCell,
buildings::{BaseBuilding, Stone},
units::MinerUnit,
},
},
widgets::CellWidget,
};
@@ -68,7 +72,7 @@ impl BoardState {
} else if enemy_base {
CellStructure::Base(BaseBuilding::new(Players::Enemy))
} else {
CellStructure::Stone
CellStructure::Stone(Stone::new())
};
let unit: Option<Units> = if player_base {
@@ -1,18 +1,26 @@
use ratatui::style::Color;
use crate::app::states::Players;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BaseBuilding {
owner: Players,
level: u8,
tag: &'static str,
}
impl BaseBuilding {
pub fn new(owner: Players) -> Self {
Self {
owner,
level: 1,
tag: "B",
Self { owner, level: b'1' }
}
pub fn get_tag(&self) -> char {
'B'
}
pub fn get_color(&self) -> Color {
match self.owner {
Players::Player => Color::LightBlue,
Players::Enemy => Color::LightRed,
}
}
@@ -20,16 +28,7 @@ impl BaseBuilding {
self.owner
}
pub fn get_tag(&self) -> &'static str {
self.tag
}
pub fn get_level(&self) -> &'static str {
match self.level {
1 => "1",
2 => "2",
3 => "3",
_ => " ",
}
pub fn get_level(&self) -> char {
self.level as char
}
}
@@ -1,3 +1,7 @@
mod base;
mod stone;
mod tunnel;
pub use base::BaseBuilding;
pub use stone::Stone;
pub use tunnel::Tunnel;
@@ -0,0 +1,20 @@
use ratatui::style::Color;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Stone {
durability: u16,
}
impl Stone {
pub fn new() -> Self {
Self { durability: 1000 }
}
pub fn get_tag(&self) -> char {
' '
}
pub fn get_color(&self) -> Color {
Color::White
}
}
@@ -0,0 +1,38 @@
use ratatui::style::Color;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Tunnel {
durability: u16,
stress: u8,
roof_support: bool,
rail: bool,
lamp: bool,
}
impl Tunnel {
pub fn new() -> Self {
Self {
durability: 500,
stress: 25,
roof_support: false,
rail: false,
lamp: false,
}
}
pub fn get_tag(&self) -> char {
'T'
}
pub fn get_color(&self) -> Color {
Color::Gray
}
pub fn get_durability(&self) -> u16 {
self.durability
}
pub fn get_stress(&self) -> u8 {
self.stress
}
}
@@ -3,15 +3,14 @@ use crate::app::states::Players;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct MinerUnit {
owner: Players,
tag: &'static str,
}
impl MinerUnit {
pub fn new(owner: Players) -> Self {
Self { owner, tag: "M" }
Self { owner }
}
pub fn get_tag(self) -> &'static str {
self.tag
pub fn get_tag(self) -> char {
'M'
}
}
+26 -21
View File
@@ -1,4 +1,4 @@
use crate::app::states::{CellStructure, Players, Units, ZoomLevel};
use crate::app::states::{CellStructure, Units, ZoomLevel, skirmish_states::buildings::Stone};
use ratatui::{
buffer::Buffer,
layout::{Alignment, Rect},
@@ -75,7 +75,7 @@ impl CellWidget {
}
fn display_coords(&self) -> Span<'_> {
if self.selected || self.structure != CellStructure::Stone || self.marked {
if self.selected || self.structure != CellStructure::Stone(Stone::new()) || self.marked {
format!("{}{}", self.col_to_letters(), self.row).green()
} else {
"".to_span()
@@ -83,38 +83,43 @@ impl CellWidget {
}
fn fg_color(&self) -> Color {
match self.structure {
_ if self.marked && self.selected => Color::Magenta,
_ if self.marked && !self.selected => Color::LightMagenta,
_ if self.selected && !self.marked => Color::LightYellow,
CellStructure::Base(base) if !self.selected => match base.get_owner() {
Players::Player => Color::LightBlue,
Players::Enemy => Color::LightRed,
},
CellStructure::Tunel if !self.selected => Color::Gray,
_ => Color::White,
if self.marked && self.selected {
return Color::Magenta;
} else if self.marked && !self.selected {
return Color::LightMagenta;
} else if self.selected && !self.marked {
return Color::LightYellow;
}
if !self.selected {
return match self.structure {
CellStructure::Base(base) => base.get_color(),
CellStructure::Tunnel(tunnel) => tunnel.get_color(),
CellStructure::Stone(stone) => stone.get_color(),
};
}
Color::White
}
fn get_text_area(&self) -> Vec<Line<'_>> {
let tag: &str = match self.structure {
let tag: char = match self.structure {
CellStructure::Base(base) => base.get_tag(),
CellStructure::Tunel => "T",
CellStructure::Stone => " ",
// _ => " ",
CellStructure::Tunnel(tunnel) => tunnel.get_tag(),
CellStructure::Stone(stone) => stone.get_tag(),
};
let b_level: &str = match self.structure {
let b_level: char = match self.structure {
CellStructure::Base(base) => base.get_level(),
_ => " ",
_ => ' ',
};
let unit: &str = match self.unit {
let unit: char = match self.unit {
Some(unit) => match unit {
Units::Miner(miner) => miner.get_tag(),
// _ => " ",
// _ => ' ',
},
None => " ",
None => ' ',
};
let mut text_area: Vec<Line<'_>> = Vec::new();