generated from GarandPLG/rust-flake-template
Add base tags, adjust margins, update CLI defaults
Introduce `CellTag` and `Players` enums and extend `CellWidget` to carry a tag. Store player and enemy base coordinates in `BoardState` and tag those cells. Reduce horizontal margin from 3 to 1 in board layout helpers. Change CLI defaults: map width default 42, map height min 11 and default 11. Adjust offset calculation and render constraints to match the new layout.
This commit is contained in:
@@ -9,7 +9,7 @@ pub fn cells_area_helper(area: &Rect) -> Rect {
|
|||||||
.borders(Borders::LEFT | Borders::TOP | Borders::RIGHT)
|
.borders(Borders::LEFT | Borders::TOP | Borders::RIGHT)
|
||||||
.inner(skirmish_layout(*area)[1])
|
.inner(skirmish_layout(*area)[1])
|
||||||
.inner(Margin {
|
.inner(Margin {
|
||||||
horizontal: 3,
|
horizontal: 1,
|
||||||
vertical: 1,
|
vertical: 1,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::app::{
|
use crate::app::{
|
||||||
helpers::{CellSizes, cell_size_helper, cells_area_helper},
|
helpers::{CellSizes, cell_size_helper, cells_area_helper},
|
||||||
states::{FocusedCell, Offset, ZoomLevel, skirmish_states::MoveFocusedCell},
|
states::{FocusedCell, Offset, ZoomLevel, skirmish_states::MoveFocusedCell},
|
||||||
widgets::CellWidget,
|
widgets::{CellTag, CellWidget, Players},
|
||||||
};
|
};
|
||||||
use ratatui::layout::Rect;
|
use ratatui::layout::Rect;
|
||||||
|
|
||||||
@@ -19,6 +19,8 @@ pub struct BoardState {
|
|||||||
pub cells: Vec<Vec<CellWidget>>,
|
pub cells: Vec<Vec<CellWidget>>,
|
||||||
pub zoom_level: ZoomLevel,
|
pub zoom_level: ZoomLevel,
|
||||||
focused_cell: FocusedCell,
|
focused_cell: FocusedCell,
|
||||||
|
player_base_coords: (usize, usize),
|
||||||
|
enemy_base_coords: (usize, usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BoardState {
|
impl BoardState {
|
||||||
@@ -35,25 +37,34 @@ impl BoardState {
|
|||||||
let h_max_offset: usize = Self::max_offset(map_width, cols);
|
let h_max_offset: usize = Self::max_offset(map_width, cols);
|
||||||
|
|
||||||
let vertical_offset: Offset = Offset::new(
|
let vertical_offset: Offset = Offset::new(
|
||||||
Some((map_height - rows as usize) / 2 + 1),
|
Some((map_height - rows as usize + 1) / 2),
|
||||||
Some(v_max_offset),
|
Some(v_max_offset),
|
||||||
);
|
);
|
||||||
let horizontal_offset: Offset = Offset::new(None, Some(h_max_offset));
|
let horizontal_offset: Offset = Offset::new(None, Some(h_max_offset));
|
||||||
|
|
||||||
let focused_cell: FocusedCell = FocusedCell::new(map_height / 2, 2, map_height, map_width);
|
let focused_cell: FocusedCell =
|
||||||
|
FocusedCell::new((map_height) / 2, 2, map_height, map_width);
|
||||||
|
|
||||||
let mut cells: Vec<Vec<CellWidget>> = Vec::new();
|
let mut cells: Vec<Vec<CellWidget>> = Vec::new();
|
||||||
|
|
||||||
|
let player_base_coords: (usize, usize) = ((map_height) / 2, 1);
|
||||||
|
let enemy_base_coords: (usize, usize) = ((map_height) / 2, map_width - 2);
|
||||||
|
|
||||||
for row in 0..map_height {
|
for row in 0..map_height {
|
||||||
let mut rows: Vec<CellWidget> = Vec::new();
|
let mut rows: Vec<CellWidget> = Vec::new();
|
||||||
|
|
||||||
for col in 0..map_width {
|
for col in 0..map_width {
|
||||||
rows.push(CellWidget::new(
|
let selected: bool = row == focused_cell.get_row() && col == focused_cell.get_col();
|
||||||
row,
|
|
||||||
col,
|
let tag: CellTag = if row == player_base_coords.0 && col == player_base_coords.1 {
|
||||||
row == focused_cell.get_row() && col == focused_cell.get_col(),
|
CellTag::Base(Players::Player)
|
||||||
zoom_level,
|
} else if row == enemy_base_coords.0 && col == enemy_base_coords.1 {
|
||||||
));
|
CellTag::Base(Players::Enemy)
|
||||||
|
} else {
|
||||||
|
CellTag::Stone
|
||||||
|
};
|
||||||
|
|
||||||
|
rows.push(CellWidget::new(row, col, zoom_level, selected, tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
cells.push(rows);
|
cells.push(rows);
|
||||||
@@ -72,6 +83,8 @@ impl BoardState {
|
|||||||
cells,
|
cells,
|
||||||
zoom_level,
|
zoom_level,
|
||||||
focused_cell,
|
focused_cell,
|
||||||
|
player_base_coords,
|
||||||
|
enemy_base_coords,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,11 +89,22 @@ pub fn skirmish_view(app: &App, area: Rect, buf: &mut Buffer) {
|
|||||||
board_block.render(main_area, buf);
|
board_block.render(main_area, buf);
|
||||||
|
|
||||||
let cells_area: Rect = board_area.inner(Margin {
|
let cells_area: Rect = board_area.inner(Margin {
|
||||||
horizontal: 3,
|
horizontal: 1,
|
||||||
vertical: 1,
|
vertical: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
BoardWidget::new(&states.skirmish.board).render(cells_area, buf);
|
// TODO: add actual (effective) board sizes as Constraints
|
||||||
|
BoardWidget::new(&states.skirmish.board).render(
|
||||||
|
cells_area.centered(
|
||||||
|
Constraint::Length(
|
||||||
|
(states.skirmish.board.cell_width * states.skirmish.board.cols) as u16,
|
||||||
|
),
|
||||||
|
Constraint::Length(
|
||||||
|
(states.skirmish.board.cell_height * states.skirmish.board.rows) as u16,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
buf,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
+55
-26
@@ -3,17 +3,22 @@ use ratatui::{
|
|||||||
buffer::Buffer,
|
buffer::Buffer,
|
||||||
layout::{Alignment, Rect},
|
layout::{Alignment, Rect},
|
||||||
style::{Color, Style, Stylize},
|
style::{Color, Style, Stylize},
|
||||||
text::Line,
|
text::{Line, Span, ToSpan},
|
||||||
widgets::{Block, Borders, Paragraph, Widget},
|
widgets::{Block, Borders, Paragraph, Widget},
|
||||||
};
|
};
|
||||||
|
|
||||||
// pub enum CellTags {
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
// Player,
|
pub enum CellTag {
|
||||||
// Enemy,
|
Base(Players),
|
||||||
// Dirt,
|
Tunel,
|
||||||
// Tunnel,
|
Stone,
|
||||||
// Base,
|
}
|
||||||
// }
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum Players {
|
||||||
|
Player,
|
||||||
|
Enemy,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct CellWidget {
|
pub struct CellWidget {
|
||||||
@@ -21,16 +26,23 @@ pub struct CellWidget {
|
|||||||
col: usize,
|
col: usize,
|
||||||
selected: bool,
|
selected: bool,
|
||||||
zoom_level: ZoomLevel,
|
zoom_level: ZoomLevel,
|
||||||
// pub tags: Vec<CellTags>,
|
tag: CellTag,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CellWidget {
|
impl CellWidget {
|
||||||
pub fn new(row: usize, col: usize, selected: bool, zoom_level: ZoomLevel) -> Self {
|
pub fn new(
|
||||||
|
row: usize,
|
||||||
|
col: usize,
|
||||||
|
zoom_level: ZoomLevel,
|
||||||
|
selected: bool,
|
||||||
|
tag: CellTag,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
row,
|
row,
|
||||||
col,
|
col,
|
||||||
selected,
|
selected,
|
||||||
zoom_level,
|
zoom_level,
|
||||||
|
tag,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,6 +54,10 @@ impl CellWidget {
|
|||||||
self.zoom_level = zoom_level;
|
self.zoom_level = zoom_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_tag(&mut self, tag: CellTag) {
|
||||||
|
self.tag = tag;
|
||||||
|
}
|
||||||
|
|
||||||
fn col_to_letters(&self) -> String {
|
fn col_to_letters(&self) -> String {
|
||||||
let mut col: usize = self.col + 1;
|
let mut col: usize = self.col + 1;
|
||||||
let mut letters: Vec<char> = Vec::new();
|
let mut letters: Vec<char> = Vec::new();
|
||||||
@@ -54,36 +70,49 @@ impl CellWidget {
|
|||||||
letters.iter().rev().collect()
|
letters.iter().rev().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn display_coords(&self) -> String {
|
fn display_coords(&self) -> Span<'_> {
|
||||||
format!("{}{}", self.col_to_letters(), self.row)
|
if self.selected || self.tag != CellTag::Stone {
|
||||||
|
format!("{}{}", self.col_to_letters(), self.row).green()
|
||||||
|
} else {
|
||||||
|
"".to_span()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fg_color(&self) -> Color {
|
fn fg_color(&self) -> Color {
|
||||||
if self.selected {
|
match self.tag {
|
||||||
Color::Red
|
_ if self.selected => Color::LightYellow,
|
||||||
} else {
|
CellTag::Base(Players::Player) if !self.selected => Color::LightBlue,
|
||||||
Color::White
|
CellTag::Base(Players::Enemy) if !self.selected => Color::LightRed,
|
||||||
|
CellTag::Tunel if !self.selected => Color::Gray,
|
||||||
|
_ => Color::White,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_text_area(&self) -> Vec<Line<'_>> {
|
fn get_text_area(&self) -> Vec<Line<'_>> {
|
||||||
|
let tag: &str = match self.tag {
|
||||||
|
CellTag::Base(_) => "B",
|
||||||
|
CellTag::Tunel => "T",
|
||||||
|
CellTag::Stone => " ",
|
||||||
|
};
|
||||||
|
let units: &str = " "; // TODO: units count on that cell
|
||||||
|
|
||||||
let mut text_area: Vec<Line<'_>> = Vec::new();
|
let mut text_area: Vec<Line<'_>> = Vec::new();
|
||||||
|
|
||||||
match self.zoom_level {
|
match self.zoom_level {
|
||||||
ZoomLevel::ZoomedIn => {
|
ZoomLevel::ZoomedIn => {
|
||||||
text_area.push(Line::from(" "));
|
text_area.push(Line::from(format!(" {}", units)));
|
||||||
text_area.push(Line::from(" "));
|
text_area.push(Line::from(format!(" ")));
|
||||||
text_area.push(Line::from(" "));
|
text_area.push(Line::from(format!(" {} ", tag)));
|
||||||
text_area.push(Line::from(" "));
|
text_area.push(Line::from(format!(" ")));
|
||||||
text_area.push(Line::from(" "));
|
text_area.push(Line::from(format!(" ")));
|
||||||
}
|
}
|
||||||
ZoomLevel::Default => {
|
ZoomLevel::Default => {
|
||||||
text_area.push(Line::from(" "));
|
text_area.push(Line::from(format!(" {}", units)));
|
||||||
text_area.push(Line::from(" "));
|
text_area.push(Line::from(format!(" {} ", tag)));
|
||||||
text_area.push(Line::from(" "));
|
text_area.push(Line::from(format!(" ")));
|
||||||
}
|
}
|
||||||
ZoomLevel::ZoomedOut => {
|
ZoomLevel::ZoomedOut => {
|
||||||
text_area.push(Line::from(" "));
|
text_area.push(Line::from(format!(" {} ", tag)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +123,7 @@ impl CellWidget {
|
|||||||
Block::default()
|
Block::default()
|
||||||
.borders(Borders::ALL)
|
.borders(Borders::ALL)
|
||||||
.style(Style::default().fg(self.fg_color()))
|
.style(Style::default().fg(self.fg_color()))
|
||||||
.title(self.display_coords().green())
|
.title(self.display_coords())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,5 +3,5 @@ pub mod cell;
|
|||||||
pub mod keybindings;
|
pub mod keybindings;
|
||||||
|
|
||||||
pub use board::BoardWidget;
|
pub use board::BoardWidget;
|
||||||
pub use cell::CellWidget;
|
pub use cell::{CellTag, CellWidget, Players};
|
||||||
pub use keybindings::KeybindingsWidget;
|
pub use keybindings::KeybindingsWidget;
|
||||||
|
|||||||
+5
-5
@@ -49,18 +49,18 @@ pub struct Cli {
|
|||||||
long,
|
long,
|
||||||
help = "Map width",
|
help = "Map width",
|
||||||
value_name = "Positive integer [36; 108]",
|
value_name = "Positive integer [36; 108]",
|
||||||
default_value = "36",
|
default_value = "42",
|
||||||
value_parser = value_parser!(u8).range(36..=108)
|
value_parser = value_parser!(u8).range(36..=108)
|
||||||
)]
|
)]
|
||||||
pub map_width: u8,
|
pub map_width: u8,
|
||||||
|
|
||||||
/// Height of the generated map (13–50 tiles).
|
/// Height of the generated map (11–50 tiles).
|
||||||
#[arg(
|
#[arg(
|
||||||
long,
|
long,
|
||||||
help = "Map height",
|
help = "Map height",
|
||||||
value_name = "Positive integer [13; 39]",
|
value_name = "Positive integer [11; 39]",
|
||||||
default_value = "13",
|
default_value = "11",
|
||||||
value_parser = value_parser!(u8).range(13..=39)
|
value_parser = value_parser!(u8).range(11..=39)
|
||||||
)]
|
)]
|
||||||
pub map_height: u8,
|
pub map_height: u8,
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user