generated from GarandPLG/rust-flake-template
Add ore level support and unify text rendering
Introduce a numeric `level` field for `BaseBuilding` and `Ore`, update their constructors and `get_level` implementations, and increase the default ore amount to the new maximum. Extend the `Structure` and `Unit` traits with `base_text` and `text` methods, add `is_unit` to `Units`, and adjust the `Structures` enum to delegate text rendering. Refactor `SidePanelWidget` to use the unified trait methods, removing duplicated rendering code. Update `BoardState` to create ore structures with an initial level of 1.
This commit is contained in:
@@ -81,9 +81,9 @@ impl BoardState {
|
|||||||
} else if enemy_base {
|
} else if enemy_base {
|
||||||
Structures::Base(BaseBuilding::new(Players::Enemy))
|
Structures::Base(BaseBuilding::new(Players::Enemy))
|
||||||
} else if player_ore {
|
} else if player_ore {
|
||||||
Structures::Ore(Ore::new(Players::Player))
|
Structures::Ore(Ore::new(Players::Player, 1))
|
||||||
} else if enemy_ore {
|
} else if enemy_ore {
|
||||||
Structures::Ore(Ore::new(Players::Enemy))
|
Structures::Ore(Ore::new(Players::Enemy, 1))
|
||||||
} else {
|
} else {
|
||||||
Structures::Stone(Stone::new())
|
Structures::Stone(Stone::new())
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ impl BaseBuilding {
|
|||||||
durability: 1500,
|
durability: 1500,
|
||||||
stress: 0,
|
stress: 0,
|
||||||
owner,
|
owner,
|
||||||
level: b'1',
|
level: 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@ impl Structure for BaseBuilding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_level(&self) -> char {
|
fn get_level(&self) -> char {
|
||||||
self.level as char
|
(self.level + b'0') as char
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_durability(&self) -> u16 {
|
fn get_durability(&self) -> u16 {
|
||||||
|
|||||||
@@ -1,22 +1,26 @@
|
|||||||
use crate::app::states::skirmish_states::{Players, structures::Structure};
|
use crate::app::states::skirmish_states::{Players, structures::Structure};
|
||||||
use ratatui::style::Color;
|
use ratatui::{
|
||||||
|
style::{Color, Stylize},
|
||||||
|
text::Line,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct Ore {
|
pub struct Ore {
|
||||||
owner: Players,
|
owner: Players,
|
||||||
ore_amount: u16,
|
ore_amount: u16,
|
||||||
// ore_max_amount: u16,
|
|
||||||
durability: u16,
|
durability: u16,
|
||||||
stress: u8,
|
stress: u8,
|
||||||
|
level: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ore {
|
impl Ore {
|
||||||
pub fn new(owner: Players) -> Self {
|
pub fn new(owner: Players, level: u8) -> Self {
|
||||||
Self {
|
Self {
|
||||||
owner,
|
owner,
|
||||||
ore_amount: 1000,
|
ore_amount: 5000,
|
||||||
durability: 1000,
|
durability: 1000,
|
||||||
stress: 0,
|
stress: 0,
|
||||||
|
level,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,7 +29,12 @@ impl Ore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_max_ore_amount(&self) -> u16 {
|
pub fn get_max_ore_amount(&self) -> u16 {
|
||||||
1000
|
5000
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_owner(&mut self, new_owner: Players) -> &mut Self {
|
||||||
|
self.owner = new_owner;
|
||||||
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +56,11 @@ impl Structure for Ore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_level(&self) -> char {
|
fn get_level(&self) -> char {
|
||||||
' '
|
if self.level != 0 {
|
||||||
|
(self.level + b'0') as char
|
||||||
|
} else {
|
||||||
|
' '
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_max_durability(&self) -> u16 {
|
fn get_max_durability(&self) -> u16 {
|
||||||
@@ -65,4 +78,17 @@ impl Structure for Ore {
|
|||||||
fn get_stress(&self) -> u8 {
|
fn get_stress(&self) -> u8 {
|
||||||
self.stress
|
self.stress
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn text(&self) -> Vec<Line<'_>> {
|
||||||
|
let mut lines: Vec<Line<'_>> = Structure::base_text(self);
|
||||||
|
|
||||||
|
lines.push(Line::from_iter([
|
||||||
|
"Ore: ".gray(),
|
||||||
|
self.get_ore_amount().to_string().cyan(),
|
||||||
|
"/".gray(),
|
||||||
|
self.get_max_ore_amount().to_string().cyan(),
|
||||||
|
]));
|
||||||
|
|
||||||
|
lines
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use crate::app::states::skirmish_states::{
|
|||||||
Players,
|
Players,
|
||||||
structures::{BaseBuilding, Ore, Stone, Structure, Tunnel},
|
structures::{BaseBuilding, Ore, Stone, Structure, Tunnel},
|
||||||
};
|
};
|
||||||
use ratatui::style::Color;
|
use ratatui::{style::Color, text::Line};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum Structures {
|
pub enum Structures {
|
||||||
@@ -56,4 +56,8 @@ impl Structure for Structures {
|
|||||||
fn get_owner(&self) -> Players {
|
fn get_owner(&self) -> Players {
|
||||||
self.structure().get_owner()
|
self.structure().get_owner()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn text(&self) -> Vec<Line<'_>> {
|
||||||
|
self.structure().text()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,57 @@
|
|||||||
use crate::app::states::skirmish_states::Players;
|
use crate::app::states::skirmish_states::Players;
|
||||||
use ratatui::style::Color;
|
use ratatui::{
|
||||||
|
style::{Color, Stylize},
|
||||||
|
text::Line,
|
||||||
|
};
|
||||||
|
|
||||||
pub trait Structure {
|
pub trait Structure {
|
||||||
fn get_tag(&self) -> char;
|
fn get_tag(&self) -> char;
|
||||||
|
|
||||||
fn get_color(&self) -> Color;
|
fn get_color(&self) -> Color;
|
||||||
|
|
||||||
fn get_level(&self) -> char;
|
fn get_level(&self) -> char;
|
||||||
|
|
||||||
fn get_stress(&self) -> u8;
|
fn get_stress(&self) -> u8;
|
||||||
|
|
||||||
fn get_durability(&self) -> u16;
|
fn get_durability(&self) -> u16;
|
||||||
|
|
||||||
fn get_max_durability(&self) -> u16;
|
fn get_max_durability(&self) -> u16;
|
||||||
|
|
||||||
fn get_name(&self) -> &'static str;
|
fn get_name(&self) -> &'static str;
|
||||||
|
|
||||||
fn get_owner(&self) -> Players;
|
fn get_owner(&self) -> Players;
|
||||||
|
|
||||||
|
fn base_text(&self) -> Vec<Line<'_>> {
|
||||||
|
let durability: u16 = self.get_durability();
|
||||||
|
let max_durability: u16 = self.get_max_durability();
|
||||||
|
let durability_percent: u32 = durability as u32 * 100 / max_durability as u32;
|
||||||
|
let stress: u8 = self.get_stress();
|
||||||
|
let level: char = self.get_level();
|
||||||
|
|
||||||
|
let mut lines: Vec<Line<'_>> = vec![
|
||||||
|
Line::from_iter([
|
||||||
|
"Durability: ".gray(),
|
||||||
|
durability.to_string().cyan(),
|
||||||
|
"/".gray(),
|
||||||
|
max_durability.to_string().cyan(),
|
||||||
|
" ( ".gray(),
|
||||||
|
durability_percent.to_string().cyan(),
|
||||||
|
"% )".gray(),
|
||||||
|
]),
|
||||||
|
Line::from_iter(["Stress: ".gray(), stress.to_string().cyan(), "%".gray()]),
|
||||||
|
];
|
||||||
|
|
||||||
|
if level != ' ' {
|
||||||
|
lines.push(Line::from_iter([
|
||||||
|
"Level: ".gray(),
|
||||||
|
level.to_string().cyan(),
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
lines
|
||||||
|
}
|
||||||
|
|
||||||
|
fn text(&self) -> Vec<Line<'_>> {
|
||||||
|
self.base_text()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,4 +42,8 @@ impl Unit for Option<Units> {
|
|||||||
fn get_owner(&self) -> Players {
|
fn get_owner(&self) -> Players {
|
||||||
self.map_or(Players::Unclaimed, |u| u.get_owner())
|
self.map_or(Players::Unclaimed, |u| u.get_owner())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_unit(&self) -> bool {
|
||||||
|
self.map_or(false, |u| u.is_unit())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,27 @@
|
|||||||
use crate::app::states::skirmish_states::Players;
|
use crate::app::states::skirmish_states::Players;
|
||||||
|
use ratatui::{
|
||||||
|
style::Stylize,
|
||||||
|
text::{Line, Span},
|
||||||
|
};
|
||||||
|
|
||||||
pub trait Unit {
|
pub trait Unit {
|
||||||
fn get_owner(&self) -> Players;
|
fn get_owner(&self) -> Players;
|
||||||
|
|
||||||
fn get_tag(&self) -> char;
|
fn get_tag(&self) -> char;
|
||||||
|
|
||||||
fn get_name(&self) -> &'static str;
|
fn get_name(&self) -> &'static str;
|
||||||
|
|
||||||
|
fn is_unit(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn base_text(&self) -> Vec<Line<'_>> {
|
||||||
|
let owner: Span<'_> = self.get_owner().get_span();
|
||||||
|
|
||||||
|
vec![Line::from_iter(vec!["Owner: ".gray(), owner])]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn text(&self) -> Vec<Line<'_>> {
|
||||||
|
self.base_text()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ use crate::app::{
|
|||||||
use ratatui::{
|
use ratatui::{
|
||||||
buffer::Buffer,
|
buffer::Buffer,
|
||||||
layout::{Alignment, Constraint, Layout, Margin, Rect},
|
layout::{Alignment, Constraint, Layout, Margin, Rect},
|
||||||
style::{Color, Stylize},
|
style::Color,
|
||||||
text::{Line, Span},
|
|
||||||
widgets::{Block, BorderType, Borders, Padding, Paragraph, Widget},
|
widgets::{Block, BorderType, Borders, Padding, Paragraph, Widget},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -61,52 +60,12 @@ impl<'a> SidePanelWidget<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_area_constraints(&self) -> [Constraint; 2] {
|
fn get_area_constraints(&self) -> [Constraint; 2] {
|
||||||
if !self.unit.get_name().is_empty() {
|
if self.unit.is_unit() {
|
||||||
[Constraint::Percentage(50), Constraint::Percentage(50)]
|
[Constraint::Percentage(50), Constraint::Percentage(50)]
|
||||||
} else {
|
} else {
|
||||||
[Constraint::Percentage(100), Constraint::Percentage(0)]
|
[Constraint::Percentage(100), Constraint::Percentage(0)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Relocate this to Structure trait implementations
|
|
||||||
fn structure_text(&self) -> Vec<Line<'_>> {
|
|
||||||
let s: &Structures = self.structure;
|
|
||||||
let durability: u16 = s.get_durability();
|
|
||||||
let max_durability: u16 = s.get_max_durability();
|
|
||||||
let durability_percent: u32 = durability as u32 * 100u32 / max_durability as u32;
|
|
||||||
let stress: u8 = s.get_stress();
|
|
||||||
let level: char = s.get_level();
|
|
||||||
|
|
||||||
let mut lines: Vec<Line<'_>> = vec![
|
|
||||||
Line::from_iter([
|
|
||||||
"Durability: ".gray(),
|
|
||||||
durability.to_string().cyan(),
|
|
||||||
"/".gray(),
|
|
||||||
max_durability.to_string().cyan(),
|
|
||||||
" ( ".gray(),
|
|
||||||
durability_percent.to_string().cyan(),
|
|
||||||
"% )".gray(),
|
|
||||||
]),
|
|
||||||
Line::from_iter(["Stress: ".gray(), stress.to_string().cyan(), "%".gray()]),
|
|
||||||
];
|
|
||||||
|
|
||||||
if level != ' ' {
|
|
||||||
lines.push(Line::from_iter([
|
|
||||||
"Level: ".gray(),
|
|
||||||
level.to_string().cyan(),
|
|
||||||
]));
|
|
||||||
}
|
|
||||||
|
|
||||||
lines
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Relocate this to Unit trait implementations
|
|
||||||
fn unit_text(&self) -> Vec<Line<'_>> {
|
|
||||||
let u: &Option<Units> = self.unit;
|
|
||||||
let owner: Span<'_> = u.get_owner().get_span();
|
|
||||||
|
|
||||||
vec![Line::from_iter(vec!["Owner: ".gray(), owner])]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widget for SidePanelWidget<'_> {
|
impl Widget for SidePanelWidget<'_> {
|
||||||
@@ -121,13 +80,13 @@ impl Widget for SidePanelWidget<'_> {
|
|||||||
let [structure_area, unit_area] =
|
let [structure_area, unit_area] =
|
||||||
Layout::vertical(self.get_area_constraints()).areas(inner_area);
|
Layout::vertical(self.get_area_constraints()).areas(inner_area);
|
||||||
|
|
||||||
Paragraph::new(self.structure_text())
|
Paragraph::new(self.structure.text())
|
||||||
.alignment(Alignment::Left)
|
.alignment(Alignment::Left)
|
||||||
.block(self.get_inner_block(self.structure.get_name().to_string(), Color::Cyan))
|
.block(self.get_inner_block(self.structure.get_name().to_string(), Color::Cyan))
|
||||||
.render(structure_area, buf);
|
.render(structure_area, buf);
|
||||||
|
|
||||||
if !self.unit.get_name().is_empty() {
|
if self.unit.is_unit() {
|
||||||
Paragraph::new(self.unit_text())
|
Paragraph::new(self.unit.text())
|
||||||
.alignment(Alignment::Left)
|
.alignment(Alignment::Left)
|
||||||
.block(self.get_inner_block(self.unit.get_name().to_string(), Color::Green))
|
.block(self.get_inner_block(self.unit.get_name().to_string(), Color::Green))
|
||||||
.render(unit_area, buf);
|
.render(unit_area, buf);
|
||||||
|
|||||||
Reference in New Issue
Block a user