generated from GarandPLG/rust-flake-template
Use b for building and r for recruitment
- Replace Ctrl+Space with `b` and Alt+Space with `r` in README and documentation. - Remove the old Alt+Space recruitment keybinding and adjust key handling code. - Revamp skirmish view to display colored lines and updated status messages. - Increase test suite to 83 tests and update test expectations for new shortcuts. - Update flake.lock with the latest revision and hash.
This commit is contained in:
1 parent
73f544d5d6
commit
6c1141a711
12 files changed
+169
-95
No files matched your search
@@ -112,15 +112,6 @@ pub struct KeyBinding {
|
||||
/// The slice is ordered primarily for readability; the runtime lookup scans
|
||||
/// this slice linearly, which is acceptable given the modest size of the list.
|
||||
static KEYBINDINGS: &[KeyBinding] = &[
|
||||
KeyBinding {
|
||||
action: Action::Recruitment,
|
||||
code: KeyCode::Char(' '),
|
||||
kind: KeyEventKind::Press,
|
||||
modifiers: KeyModifiers::ALT,
|
||||
group: Group::Opener,
|
||||
symbol: "Alt + Space / r",
|
||||
description: "Recruit",
|
||||
},
|
||||
KeyBinding {
|
||||
action: Action::Recruitment,
|
||||
code: KeyCode::Char('r'),
|
||||
@@ -132,11 +123,11 @@ static KEYBINDINGS: &[KeyBinding] = &[
|
||||
},
|
||||
KeyBinding {
|
||||
action: Action::Building,
|
||||
code: KeyCode::Char(' '),
|
||||
code: KeyCode::Char('b'),
|
||||
kind: KeyEventKind::Press,
|
||||
modifiers: KeyModifiers::CONTROL,
|
||||
modifiers: KeyModifiers::NONE,
|
||||
group: Group::Opener,
|
||||
symbol: "Ctrl + Space",
|
||||
symbol: "b",
|
||||
description: "Buildings",
|
||||
},
|
||||
KeyBinding {
|
||||
@@ -303,20 +294,20 @@ static KEYBINDINGS: &[KeyBinding] = &[
|
||||
},
|
||||
KeyBinding {
|
||||
action: Action::VolumeUp,
|
||||
code: KeyCode::Char('b'),
|
||||
code: KeyCode::Char('+'),
|
||||
kind: KeyEventKind::Press,
|
||||
modifiers: KeyModifiers::NONE,
|
||||
group: Group::Music,
|
||||
symbol: "b",
|
||||
symbol: "+",
|
||||
description: "🔊",
|
||||
},
|
||||
KeyBinding {
|
||||
action: Action::VolumeDown,
|
||||
code: KeyCode::Char('n'),
|
||||
code: KeyCode::Char('-'),
|
||||
kind: KeyEventKind::Press,
|
||||
modifiers: KeyModifiers::NONE,
|
||||
group: Group::Music,
|
||||
symbol: "n",
|
||||
symbol: "-",
|
||||
description: "🔉",
|
||||
},
|
||||
KeyBinding {
|
||||
@@ -361,13 +352,6 @@ pub fn binding_for(action: Action) -> Option<&'static KeyBinding> {
|
||||
/// was pressed. Returns `None` when the event does not correspond to any known
|
||||
/// action.
|
||||
pub fn event_to_action(event: &KeyEvent) -> Option<Action> {
|
||||
// Legacy terminals encode Ctrl+Space as NUL instead of a modified space.
|
||||
if event.code == KeyCode::Null
|
||||
&& event.kind == KeyEventKind::Press
|
||||
&& (event.modifiers == KeyModifiers::NONE || event.modifiers == KeyModifiers::CONTROL)
|
||||
{
|
||||
return Some(Action::Building);
|
||||
}
|
||||
if let Some(b) = KEYBINDINGS
|
||||
.iter()
|
||||
.find(|b| b.code == event.code && b.kind == event.kind && b.modifiers == event.modifiers)
|
||||
|
||||
+58
-29
@@ -203,65 +203,94 @@ pub fn skirmish_view(app: &App, area: Rect, buf: &mut Buffer) {
|
||||
let popup: Rect = main_area.centered(Constraint::Length(64), Constraint::Length(14));
|
||||
let coords: (usize, usize) = board.get_focused_cell().get_coords();
|
||||
let structure: Structures = board.get_ref_cell(coords.0, coords.1).get_structure();
|
||||
let status: String = if let Structures::MineConstruction(site) = structure
|
||||
let status: Vec<Line<'_>> = if let Structures::MineConstruction(site) = structure
|
||||
&& site.get_owner() == Players::Player
|
||||
{
|
||||
format!(
|
||||
"Construction: {}%\n{}\nDelete: cancel and refund full cost",
|
||||
site.progress_percent(),
|
||||
vec![
|
||||
Line::from(format!("Construction: {}%", site.progress_percent())).cyan(),
|
||||
if board.has_adjacent_builder(coords, Players::Player) {
|
||||
"Builder working"
|
||||
Line::from("Builder working").green()
|
||||
} else {
|
||||
"Paused: adjacent friendly builder required"
|
||||
}
|
||||
)
|
||||
Line::from("Paused: adjacent friendly builder required").yellow()
|
||||
},
|
||||
Line::from("Delete: cancel and refund full cost").yellow(),
|
||||
]
|
||||
} else if matches!(structure, Structures::Mine(_))
|
||||
&& structure.get_owner() == Players::Player
|
||||
{
|
||||
"Mine completed".to_string()
|
||||
vec![Line::from("Mine completed").green()]
|
||||
} else if states
|
||||
.skirmish
|
||||
.can_start_mine_construction(coords, Players::Player)
|
||||
{
|
||||
"Ready to build: Enter".to_string()
|
||||
vec![Line::from("Ready to build: Enter").green()]
|
||||
} else {
|
||||
"Construction unavailable: check site, builder and resources".to_string()
|
||||
vec![Line::from("Construction unavailable: check site, builder and resources").red()]
|
||||
};
|
||||
let mut lines: Vec<Line<'_>> = vec![
|
||||
Line::from("Mine").yellow().bold(),
|
||||
Line::from(format!(
|
||||
"Cost: {} Wood + {} Metal | Build time: 10s",
|
||||
Mine::COST.wood,
|
||||
Mine::COST.metal
|
||||
))
|
||||
.yellow(),
|
||||
Line::from("Requires: neutral Ore + adjacent friendly builder").gray(),
|
||||
Line::from("Produces: 1 Metal/s (2 with a Miner inside)").cyan(),
|
||||
];
|
||||
lines.extend(status);
|
||||
Clear.render(popup, buf);
|
||||
Paragraph::new(format!("Mine\nCost: {} Wood + {} Metal | Build time: 10s\nRequires: neutral Ore + adjacent friendly builder\nProduces: 1 Metal/s (2 with a Miner inside)\n{status}", Mine::COST.wood, Mine::COST.metal))
|
||||
.block(Block::bordered().title("Buildings").padding(Padding::uniform(1)))
|
||||
.render(popup, buf);
|
||||
Paragraph::new(lines)
|
||||
.block(
|
||||
Block::bordered()
|
||||
.title(Line::from("Buildings").magenta().bold())
|
||||
.padding(Padding::uniform(1)),
|
||||
)
|
||||
.render(popup, buf);
|
||||
}
|
||||
if states.skirmish.recruitment_view {
|
||||
let popup: Rect = main_area.centered(Constraint::Length(64), Constraint::Length(14));
|
||||
let coords: (usize, usize) = board.get_focused_cell().get_coords();
|
||||
let cell: &CellWidget = board.get_ref_cell(coords.0, coords.1);
|
||||
let text: String = if let Structures::Base(base) = cell.get_structure()
|
||||
let lines: Vec<Line<'_>> = if let Structures::Base(base) = cell.get_structure()
|
||||
&& base.get_owner() == Players::Player
|
||||
{
|
||||
let status: &'static str =
|
||||
base.recruitment_status(cell.get_ref_option_unit().is_some());
|
||||
let action: &'static str = if states.skirmish.can_recruit_miner(coords, Players::Player)
|
||||
{
|
||||
"Enter: queue Miner"
|
||||
let action: Line<'_> = if states.skirmish.can_recruit_miner(coords, Players::Player) {
|
||||
Line::from("Enter: queue Miner").green()
|
||||
} else {
|
||||
"Insufficient resources or queue full"
|
||||
Line::from("Insufficient resources or queue full").red()
|
||||
};
|
||||
format!(
|
||||
"Miner\nCost: {} Wood + {} Metal | Recruit time: 10s\nQueued Miners: {} (includes active)\nCurrent progress: {}%\n{status}\n{action}",
|
||||
MinerUnit::RECRUIT_COST.wood,
|
||||
MinerUnit::RECRUIT_COST.metal,
|
||||
base.queued_miners(),
|
||||
base.recruitment_progress()
|
||||
)
|
||||
vec![
|
||||
Line::from("Miner").yellow().bold(),
|
||||
Line::from(format!(
|
||||
"Cost: {} Wood + {} Metal | Recruit time: 10s",
|
||||
MinerUnit::RECRUIT_COST.wood,
|
||||
MinerUnit::RECRUIT_COST.metal
|
||||
))
|
||||
.yellow(),
|
||||
Line::from(format!(
|
||||
"Queued Miners: {} (includes active)",
|
||||
base.queued_miners()
|
||||
))
|
||||
.cyan(),
|
||||
Line::from(format!(
|
||||
"Current progress: {}%",
|
||||
base.recruitment_progress()
|
||||
))
|
||||
.cyan(),
|
||||
Line::from(status).yellow(),
|
||||
action,
|
||||
]
|
||||
} else {
|
||||
"Select your Base to recruit Miners".to_string()
|
||||
vec![Line::from("Select your Base to recruit Miners").red()]
|
||||
};
|
||||
Clear.render(popup, buf);
|
||||
Paragraph::new(text)
|
||||
Paragraph::new(lines)
|
||||
.block(
|
||||
Block::bordered()
|
||||
.title("Recruitment")
|
||||
.title(Line::from("Recruitment").magenta().bold())
|
||||
.padding(Padding::uniform(1)),
|
||||
)
|
||||
.render(popup, buf);
|
||||
|
||||
Reference in new issue
Block a user