fix: militia never being spent
This commit is contained in:
parent
8b894b4c8c
commit
fc4da3bcc5
|
|
@ -777,6 +777,28 @@ impl Character {
|
|||
}
|
||||
}
|
||||
|
||||
pub const fn militia<'a>(&'a self) -> Result<Militia<'a>> {
|
||||
let title = self.role.title();
|
||||
match &self.role {
|
||||
Role::Militia { targeted } => Ok(Militia(targeted)),
|
||||
_ => Err(GameError::InvalidRole {
|
||||
expected: RoleTitle::Militia,
|
||||
got: title,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn militia_mut<'a>(&'a mut self) -> Result<MilitiaMut<'a>> {
|
||||
let title = self.role.title();
|
||||
match &mut self.role {
|
||||
Role::Militia { targeted } => Ok(MilitiaMut(targeted)),
|
||||
_ => Err(GameError::InvalidRole {
|
||||
expected: RoleTitle::Militia,
|
||||
got: title,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn initial_shown_role(&self) -> RoleTitle {
|
||||
self.role.initial_shown_role()
|
||||
}
|
||||
|
|
@ -818,6 +840,7 @@ decl_ref_and_mut!(
|
|||
BlackKnight, BlackKnightMut: Option<DiedTo>;
|
||||
Guardian, GuardianMut: Option<PreviousGuardianAction>;
|
||||
Direwolf, DirewolfMut: Option<CharacterId>;
|
||||
Militia, MilitiaMut: Option<CharacterId>;
|
||||
);
|
||||
|
||||
pub struct BlackKnightKill<'a> {
|
||||
|
|
|
|||
|
|
@ -95,4 +95,6 @@ pub enum GameError {
|
|||
MissingTime(GameTime),
|
||||
#[error("no previous during day")]
|
||||
NoPreviousDuringDay,
|
||||
#[error("militia already spent")]
|
||||
MilitiaSpent,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,7 +39,19 @@ impl KillOutcome {
|
|||
pub fn apply_to_village(self, village: &mut Village) -> Result<()> {
|
||||
match self {
|
||||
KillOutcome::Single(character_id, died_to) => {
|
||||
village.character_by_id_mut(character_id)?.kill(died_to);
|
||||
village
|
||||
.character_by_id_mut(character_id)?
|
||||
.kill(died_to.clone());
|
||||
if let DiedTo::Militia { killer, .. } = died_to
|
||||
&& let Some(existing) = village
|
||||
.character_by_id_mut(killer)?
|
||||
.militia_mut()?
|
||||
.replace(character_id)
|
||||
{
|
||||
log::error!("militia kill after already recording a kill on {existing}");
|
||||
return Err(GameError::MilitiaSpent);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
KillOutcome::Guarding {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
// Copyright (C) 2025 Emilis Bliūdžius
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
use core::{num::NonZeroU8, ops::Deref};
|
||||
#[allow(unused)]
|
||||
use pretty_assertions::{assert_eq, assert_ne, assert_str_eq};
|
||||
|
||||
use crate::{
|
||||
diedto::DiedTo,
|
||||
game::{Game, GameSettings, SetupRole},
|
||||
game_test::{ActionPromptTitleExt, ActionResultExt, GameExt, SettingsExt, gen_players},
|
||||
message::night::ActionPromptTitle,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn spent_shot() {
|
||||
let players = gen_players(1..10);
|
||||
let militia = players[0].player_id;
|
||||
let target_wolf = players[1].player_id;
|
||||
let other_wolf = players[2].player_id;
|
||||
|
||||
let mut settings = GameSettings::empty();
|
||||
settings.add_and_assign(SetupRole::Militia, militia);
|
||||
settings.add_and_assign(SetupRole::Werewolf, target_wolf);
|
||||
settings.add_and_assign(SetupRole::Werewolf, other_wolf);
|
||||
|
||||
settings.fill_remaining_slots_with_villagers(9);
|
||||
let mut game = Game::new(&players, settings).unwrap();
|
||||
game.r#continue().r#continue();
|
||||
assert_eq!(game.next().title(), ActionPromptTitle::WolvesIntro);
|
||||
game.r#continue().sleep();
|
||||
|
||||
game.next_expect_day();
|
||||
game.execute().title().wolf_pack_kill();
|
||||
game.mark(game.living_villager().character_id());
|
||||
game.r#continue().sleep();
|
||||
|
||||
game.next().title().militia();
|
||||
game.mark(game.character_by_player_id(target_wolf).character_id());
|
||||
game.r#continue().sleep();
|
||||
|
||||
game.next_expect_day();
|
||||
|
||||
assert_eq!(
|
||||
game.character_by_player_id(militia)
|
||||
.militia()
|
||||
.unwrap()
|
||||
.deref()
|
||||
.clone(),
|
||||
Some(game.character_by_player_id(target_wolf).character_id())
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
game.character_by_player_id(target_wolf).died_to().cloned(),
|
||||
Some(DiedTo::Militia {
|
||||
killer: game.character_by_player_id(militia).character_id(),
|
||||
night: NonZeroU8::new(1).unwrap()
|
||||
})
|
||||
);
|
||||
|
||||
game.execute().title().wolf_pack_kill();
|
||||
game.mark(game.living_villager().character_id());
|
||||
game.r#continue().sleep();
|
||||
|
||||
game.next_expect_day();
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@ mod hunter;
|
|||
mod insomniac;
|
||||
mod lone_wolf;
|
||||
mod mason;
|
||||
mod militia;
|
||||
mod mortician;
|
||||
mod pyremaster;
|
||||
mod scapegoat;
|
||||
|
|
|
|||
Loading…
Reference in New Issue