generated from GarandPLG/rust-flake-template
Rename iron to metal, add mining and recruitment
- Updated CLI, README and documentation to use `--starting-metal` with `--starting-iron` retained as an alias. - Introduced `Resources` struct and constants for wood delivery and mine production. - Added new structures `Mine` and `MineConstruction` with cost, production and cancel logic. - Implemented building view for constructing mines and recruitment view for spawning miners. - Extended keybindings with `Building` and `Recruitment` actions and updated action availability logic. - Modified game state, board, units and UI widgets to handle metal resources and new construction mechanics. - Updated tests and increased total test count to 82, covering resources, construction, recruitment and context‑aware keybindings.
This commit is contained in:
1 parent
305cc2c4a2
commit
a981663152
35 files changed
+2160
-74
No files matched your search
+109
-2
@@ -1,4 +1,10 @@
|
||||
use crate::app::states::skirmish_states::BoardState;
|
||||
use crate::app::states::skirmish_states::{
|
||||
BoardState, Players, Resources,
|
||||
resources::{MINE_PRODUCTION_TICKS, WOOD_DELIVERY_AMOUNT, WOOD_DELIVERY_TICKS},
|
||||
structures::{BuildingTerrain, Mine, Structure, Structures},
|
||||
units::MinerUnit,
|
||||
};
|
||||
use crate::app::widgets::CellWidget;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct SkirmishState {
|
||||
@@ -7,14 +13,115 @@ pub struct SkirmishState {
|
||||
pub board: BoardState,
|
||||
pub side_panel: bool,
|
||||
pub turn_counter: u64,
|
||||
pub player_resources: Resources,
|
||||
pub enemy_resources: Resources,
|
||||
pub building_view: bool,
|
||||
pub recruitment_view: bool,
|
||||
}
|
||||
|
||||
impl SkirmishState {
|
||||
pub fn tick_update(&mut self) {
|
||||
pub fn can_recruit_miner(&self, (row, col): (usize, usize), owner: Players) -> bool {
|
||||
let resources: &Resources = match owner {
|
||||
Players::Player => &self.player_resources,
|
||||
Players::Enemy => &self.enemy_resources,
|
||||
Players::Unclaimed => return false,
|
||||
};
|
||||
if !resources.can_afford(MinerUnit::RECRUIT_COST) {
|
||||
return false;
|
||||
}
|
||||
self.board.cells.get(row).and_then(|cells: &Vec<CellWidget>| -> Option<&CellWidget> { cells.get(col) })
|
||||
.is_some_and(|cell: &CellWidget| -> bool {
|
||||
matches!(cell.get_structure(), Structures::Base(base) if base.get_owner() == owner && base.can_queue_miner())
|
||||
})
|
||||
}
|
||||
|
||||
pub fn recruit_miner(&mut self, coords: (usize, usize), owner: Players) -> bool {
|
||||
if !self.can_recruit_miner(coords, owner) {
|
||||
return false;
|
||||
}
|
||||
let cell: &mut CellWidget = &mut self.board.cells[coords.0][coords.1];
|
||||
let Structures::Base(mut base) = cell.get_structure() else {
|
||||
return false;
|
||||
};
|
||||
if !base.queue_miner() {
|
||||
return false;
|
||||
}
|
||||
cell.set_structure(Structures::Base(base));
|
||||
let resources: &mut Resources = if owner == Players::Player {
|
||||
&mut self.player_resources
|
||||
} else {
|
||||
&mut self.enemy_resources
|
||||
};
|
||||
resources.spend(MinerUnit::RECRUIT_COST)
|
||||
}
|
||||
|
||||
pub fn can_start_mine_construction(&self, coords: (usize, usize), owner: Players) -> bool {
|
||||
let resources: &Resources = match owner {
|
||||
Players::Player => &self.player_resources,
|
||||
Players::Enemy => &self.enemy_resources,
|
||||
Players::Unclaimed => return false,
|
||||
};
|
||||
resources.can_afford(Mine::COST) && self.board.can_build_at(coords, owner, BuildingTerrain::Ore)
|
||||
}
|
||||
|
||||
pub fn start_mine_construction(&mut self, coords: (usize, usize), owner: Players) -> bool {
|
||||
if !self.can_start_mine_construction(coords, owner)
|
||||
|| !self.board.start_mine_construction(coords, owner)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
let resources: &mut Resources = match owner {
|
||||
Players::Player => &mut self.player_resources,
|
||||
Players::Enemy => &mut self.enemy_resources,
|
||||
Players::Unclaimed => return false,
|
||||
};
|
||||
resources.spend(Mine::COST)
|
||||
}
|
||||
|
||||
pub fn cancel_mine_construction(&mut self, coords: (usize, usize), owner: Players) -> bool {
|
||||
if owner == Players::Unclaimed || !self.board.cancel_mine_construction(coords, owner) {
|
||||
return false;
|
||||
}
|
||||
let resources: &mut Resources = if owner == Players::Player {
|
||||
&mut self.player_resources
|
||||
} else {
|
||||
&mut self.enemy_resources
|
||||
};
|
||||
resources.add_wood(Mine::COST.wood);
|
||||
resources.add_metal(Mine::COST.metal);
|
||||
true
|
||||
}
|
||||
|
||||
pub fn tick_update(&mut self) -> () {
|
||||
self.board.advance_turn();
|
||||
self.board.advance_recruitment();
|
||||
self.board.advance_construction();
|
||||
|
||||
// if self.board.is_victory() {}
|
||||
|
||||
self.turn_counter += 1;
|
||||
if self.turn_counter.is_multiple_of(WOOD_DELIVERY_TICKS) {
|
||||
self.player_resources.add_wood(WOOD_DELIVERY_AMOUNT);
|
||||
}
|
||||
if self.turn_counter.is_multiple_of(MINE_PRODUCTION_TICKS) {
|
||||
for row in &mut self.board.cells {
|
||||
for cell in row {
|
||||
if let Structures::Mine(mut mine) = cell.get_structure() {
|
||||
let staffed: bool = cell.get_ref_option_unit().as_ref().is_some_and(
|
||||
|unit: &crate::app::states::skirmish_states::units::Units| -> bool {
|
||||
mine.accepts_unit(unit)
|
||||
},
|
||||
);
|
||||
let amount: u32 = u32::from(mine.produce_with_miner(staffed));
|
||||
match mine.get_owner() {
|
||||
Players::Player => self.player_resources.add_metal(amount),
|
||||
Players::Enemy => self.enemy_resources.add_metal(amount),
|
||||
Players::Unclaimed => (),
|
||||
}
|
||||
cell.set_structure(Structures::Mine(mine));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user