2025-06-23 09:48:28 +01:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
use werewolves_macros::ChecksAs;
|
|
|
|
|
|
|
|
|
|
use crate::{
|
2025-09-28 02:13:34 +01:00
|
|
|
diedto::DiedTo,
|
|
|
|
|
message::PublicIdentity,
|
2025-06-23 09:48:28 +01:00
|
|
|
player::CharacterId,
|
|
|
|
|
role::{Alignment, PreviousGuardianAction, Role, RoleTitle},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
use super::Target;
|
|
|
|
|
|
2025-09-28 02:13:34 +01:00
|
|
|
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
|
|
|
|
|
pub enum ActionType {
|
|
|
|
|
Protect = 0,
|
|
|
|
|
WolfPackKill = 1,
|
|
|
|
|
Direwolf = 2,
|
|
|
|
|
Wolf = 3,
|
|
|
|
|
Block = 4,
|
|
|
|
|
Other = 5,
|
|
|
|
|
RoleChange = 6,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl PartialOrd for ActionType {
|
|
|
|
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
|
|
|
|
(*self as u8).partial_cmp(&(*other as u8))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, ChecksAs)]
|
2025-06-23 09:48:28 +01:00
|
|
|
pub enum ActionPrompt {
|
2025-09-28 02:13:34 +01:00
|
|
|
#[checks(ActionType::WolfPackKill)]
|
|
|
|
|
WolvesIntro { wolves: Box<[(Target, RoleTitle)]> },
|
|
|
|
|
#[checks(ActionType::RoleChange)]
|
|
|
|
|
RoleChange { new_role: RoleTitle },
|
|
|
|
|
#[checks(ActionType::Other)]
|
|
|
|
|
Seer { living_players: Box<[Target]> },
|
|
|
|
|
#[checks(ActionType::Protect)]
|
|
|
|
|
Protector { targets: Box<[Target]> },
|
|
|
|
|
#[checks(ActionType::Other)]
|
|
|
|
|
Arcanist { living_players: Box<[Target]> },
|
|
|
|
|
#[checks(ActionType::Other)]
|
|
|
|
|
Gravedigger { dead_players: Box<[Target]> },
|
|
|
|
|
#[checks(ActionType::Other)]
|
2025-06-23 09:48:28 +01:00
|
|
|
Hunter {
|
|
|
|
|
current_target: Option<Target>,
|
|
|
|
|
living_players: Box<[Target]>,
|
|
|
|
|
},
|
2025-09-28 02:13:34 +01:00
|
|
|
#[checks(ActionType::Other)]
|
|
|
|
|
Militia { living_players: Box<[Target]> },
|
|
|
|
|
#[checks(ActionType::Other)]
|
2025-06-23 09:48:28 +01:00
|
|
|
MapleWolf {
|
|
|
|
|
kill_or_die: bool,
|
|
|
|
|
living_players: Box<[Target]>,
|
|
|
|
|
},
|
2025-09-28 02:13:34 +01:00
|
|
|
#[checks(ActionType::Protect)]
|
2025-06-23 09:48:28 +01:00
|
|
|
Guardian {
|
|
|
|
|
previous: Option<PreviousGuardianAction>,
|
|
|
|
|
living_players: Box<[Target]>,
|
|
|
|
|
},
|
2025-09-28 02:13:34 +01:00
|
|
|
#[checks(ActionType::Wolf)]
|
|
|
|
|
WolfPackKill { living_villagers: Box<[Target]> },
|
|
|
|
|
#[checks(ActionType::Wolf)]
|
2025-06-23 09:48:28 +01:00
|
|
|
Shapeshifter,
|
2025-09-28 02:13:34 +01:00
|
|
|
#[checks(ActionType::Wolf)]
|
|
|
|
|
AlphaWolf { living_villagers: Box<[Target]> },
|
|
|
|
|
#[checks(ActionType::Direwolf)]
|
|
|
|
|
DireWolf { living_players: Box<[Target]> },
|
2025-06-23 09:48:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl PartialOrd for ActionPrompt {
|
|
|
|
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
2025-09-28 02:13:34 +01:00
|
|
|
// fn ordering_num(prompt: &ActionPrompt) -> u8 {
|
|
|
|
|
// match prompt {
|
|
|
|
|
// ActionPrompt::WolvesIntro { wolves: _ } => 0,
|
|
|
|
|
// ActionPrompt::Guardian {
|
|
|
|
|
// living_players: _,
|
|
|
|
|
// previous: _,
|
|
|
|
|
// }
|
|
|
|
|
// | ActionPrompt::Protector { targets: _ } => 1,
|
|
|
|
|
// ActionPrompt::WolfPackKill {
|
|
|
|
|
// living_villagers: _,
|
|
|
|
|
// } => 2,
|
|
|
|
|
// ActionPrompt::Shapeshifter => 3,
|
|
|
|
|
// ActionPrompt::AlphaWolf {
|
|
|
|
|
// living_villagers: _,
|
|
|
|
|
// } => 4,
|
|
|
|
|
// ActionPrompt::DireWolf { living_players: _ } => 5,
|
|
|
|
|
// ActionPrompt::Seer { living_players: _ }
|
|
|
|
|
// | ActionPrompt::Arcanist { living_players: _ }
|
|
|
|
|
// | ActionPrompt::Gravedigger { dead_players: _ }
|
|
|
|
|
// | ActionPrompt::Hunter {
|
|
|
|
|
// current_target: _,
|
|
|
|
|
// living_players: _,
|
|
|
|
|
// }
|
|
|
|
|
// | ActionPrompt::Militia { living_players: _ }
|
|
|
|
|
// | ActionPrompt::MapleWolf {
|
|
|
|
|
// kill_or_die: _,
|
|
|
|
|
// living_players: _,
|
|
|
|
|
// }
|
|
|
|
|
// | ActionPrompt::RoleChange { new_role: _ } => 0xFF,
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// ordering_num(self).partial_cmp(&ordering_num(other))
|
|
|
|
|
self.action_type().partial_cmp(&other.action_type())
|
2025-06-23 09:48:28 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Serialize, PartialEq, Deserialize, ChecksAs)]
|
|
|
|
|
pub enum ActionResponse {
|
|
|
|
|
Seer(CharacterId),
|
|
|
|
|
Arcanist(CharacterId, CharacterId),
|
|
|
|
|
Gravedigger(CharacterId),
|
|
|
|
|
Hunter(CharacterId),
|
|
|
|
|
Militia(Option<CharacterId>),
|
|
|
|
|
MapleWolf(Option<CharacterId>),
|
|
|
|
|
Guardian(CharacterId),
|
|
|
|
|
WolfPackKillVote(CharacterId),
|
|
|
|
|
#[checks]
|
|
|
|
|
Shapeshifter(bool),
|
|
|
|
|
AlphaWolf(Option<CharacterId>),
|
|
|
|
|
Direwolf(CharacterId),
|
|
|
|
|
Protector(CharacterId),
|
|
|
|
|
#[checks]
|
|
|
|
|
RoleChangeAck,
|
|
|
|
|
WolvesIntroAck,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
|
|
|
pub enum ActionResult {
|
|
|
|
|
RoleBlocked,
|
|
|
|
|
Seer(Alignment),
|
|
|
|
|
Arcanist { same: bool },
|
|
|
|
|
GraveDigger(Option<RoleTitle>),
|
|
|
|
|
GoBackToSleep,
|
|
|
|
|
WolvesIntroDone,
|
|
|
|
|
}
|