beholder: only gets info on non-role blocked deaths

This commit is contained in:
emilis 2025-11-07 23:50:45 +00:00
parent ac864a5fa5
commit a2013adea9
No known key found for this signature in database
6 changed files with 50 additions and 16 deletions

View File

@ -19,7 +19,6 @@ use core::num::NonZeroU8;
use std::collections::VecDeque; use std::collections::VecDeque;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use werewolves_macros::Extract;
use super::Result; use super::Result;
use crate::{ use crate::{
@ -30,11 +29,9 @@ use crate::{
GameTime, Village, GameTime, Village,
kill::{self}, kill::{self},
night::changes::{ChangesLookup, NightChange}, night::changes::{ChangesLookup, NightChange},
story::NightChoice,
}, },
message::night::{ActionPrompt, ActionResponse, ActionResult, Visits}, message::night::{ActionPrompt, ActionResponse, ActionResult, Visits},
player::Protection, role::RoleTitle,
role::{PYREMASTER_VILLAGER_KILLS_TO_DIE, RoleBlock, RoleTitle},
}; };
enum BlockResolvedOutcome { enum BlockResolvedOutcome {
@ -1061,6 +1058,31 @@ impl Night {
Ok(()) Ok(())
} }
/// resolves whether the target [CharacterId] dies tonight with the current
/// state of the night
fn dies_tonight(&self, character_id: CharacterId) -> Result<bool> {
let ch = self
.changes_from_actions()
.into_iter()
.chain(self.automatic_changes())
.collect::<Box<[_]>>();
let mut changes = ChangesLookup::new(&ch);
if let Some(died_to) = changes.killed(character_id)
&& kill::resolve_kill(
&mut changes,
character_id,
died_to,
self.night,
&self.village,
)?
.is_some()
{
Ok(true)
} else {
Ok(false)
}
}
fn changes_from_actions(&self) -> Box<[NightChange]> { fn changes_from_actions(&self) -> Box<[NightChange]> {
self.used_actions self.used_actions
.iter() .iter()

View File

@ -394,7 +394,9 @@ impl Night {
} => { } => {
if let Some(result) = self.used_actions.iter().find_map(|(prompt, result, _)| { if let Some(result) = self.used_actions.iter().find_map(|(prompt, result, _)| {
prompt.matches_beholding(*marked).then_some(result) prompt.matches_beholding(*marked).then_some(result)
}) { }) && self.dies_tonight(*marked)?
&& !matches!(result, ActionResult::RoleBlocked)
{
Ok(ActionComplete { Ok(ActionComplete {
result: result.clone(), result: result.clone(),
change: None, change: None,

View File

@ -969,7 +969,6 @@ fn big_game_test_based_on_story_test() {
game.next().title().beholder(); game.next().title().beholder();
game.mark(game.character_by_player_id(power_seer).character_id()); game.mark(game.character_by_player_id(power_seer).character_id());
game.r#continue().power_seer();
game.r#continue().sleep(); game.r#continue().sleep();
game.next_expect_day(); game.next_expect_day();
@ -1050,7 +1049,6 @@ fn big_game_test_based_on_story_test() {
game.next().title().beholder(); game.next().title().beholder();
game.mark(game.character_by_player_id(power_seer).character_id()); game.mark(game.character_by_player_id(power_seer).character_id());
game.r#continue().power_seer();
game.r#continue().sleep(); game.r#continue().sleep();
game.next_expect_day(); game.next_expect_day();
@ -1127,13 +1125,12 @@ fn big_game_test_based_on_story_test() {
game.next().title().beholder(); game.next().title().beholder();
game.mark(game.character_by_player_id(gravedigger).character_id()); game.mark(game.character_by_player_id(gravedigger).character_id());
assert_eq!(game.r#continue().gravedigger(), Some(RoleTitle::Guardian));
game.r#continue().sleep(); game.r#continue().sleep();
game.next_expect_day(); game.next_expect_day();
game.mark_for_execution(game.character_by_player_id(vindicator).character_id()); game.mark_for_execution(game.character_by_player_id(vindicator).character_id());
game.execute().title().wolf_pack_kill(); game.execute().title().wolf_pack_kill();
game.mark(game.living_villager().character_id()); game.mark(game.character_by_player_id(mortician).character_id());
game.r#continue().sleep(); game.r#continue().sleep();
game.next().title().seer(); game.next().title().seer();

View File

@ -408,7 +408,6 @@ fn previous_prompt() {
game.next().title().beholder(); game.next().title().beholder();
game.mark(game.character_by_player_id(power_seer).character_id()); game.mark(game.character_by_player_id(power_seer).character_id());
game.r#continue().power_seer();
game.r#continue().sleep(); game.r#continue().sleep();
game.next_expect_day(); game.next_expect_day();

View File

@ -12,17 +12,16 @@
// //
// You should have received a copy of the GNU Affero General Public License // 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/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
use core::num::NonZeroU8;
#[allow(unused)] #[allow(unused)]
use pretty_assertions::{assert_eq, assert_ne, assert_str_eq}; use pretty_assertions::{assert_eq, assert_ne, assert_str_eq};
use crate::{ use crate::{
game::{Game, GameSettings, SetupRole}, game::{Game, GameSettings, SetupRole},
game_test::{ game_test::{
ActionPromptTitleExt, ActionResultExt, AlignmentExt, GameExt, SettingsExt, gen_players, ActionPromptTitleExt, ActionResultExt, GameExt, SettingsExt, gen_players, init_log,
init_log,
}, },
message::night::{ActionPrompt, ActionPromptTitle}, message::night::ActionPromptTitle,
role::Alignment,
}; };
#[test] #[test]
@ -59,7 +58,21 @@ fn beholding_seer() {
game.next().title().beholder(); game.next().title().beholder();
game.mark(game.character_by_player_id(seer_player_id).character_id()); game.mark(game.character_by_player_id(seer_player_id).character_id());
game.r#continue().seer().wolves(); game.r#continue().sleep();
game.next_expect_day();
game.execute().title().wolf_pack_kill();
game.mark(game.character_by_player_id(seer_player_id).character_id());
game.r#continue().sleep();
game.next().title().seer();
game.mark(game.character_by_player_id(wolf_player_id).character_id());
assert_eq!(game.r#continue().seer(), Alignment::Wolves);
game.r#continue().sleep();
game.next().title().beholder();
game.mark(game.character_by_player_id(seer_player_id).character_id());
assert_eq!(game.r#continue().seer(), Alignment::Wolves);
game.r#continue().sleep(); game.r#continue().sleep();
game.next_expect_day(); game.next_expect_day();

View File

@ -21,7 +21,8 @@ pub fn BeholderPage1() -> Html {
<h1 class="intel">{"BEHOLDER"}</h1> <h1 class="intel">{"BEHOLDER"}</h1>
<div class="information intel faint"> <div class="information intel faint">
<h2>{"PICK A PLAYER"}</h2> <h2>{"PICK A PLAYER"}</h2>
<h3 class="yellow">{"IF THEY ARE AN INTEL ROLE, YOU WILL SEE WHAT THEY SAW TONIGHT"}</h3> <h3>{"YOU WILL SEE WHAT INFORMATION THEY MAY HAVE GATHERED"}</h3>
<h2 class="yellow">{"SHOULD THEY DIE TONIGHT"}</h2>
</div> </div>
</div> </div>
} }