From ad29c3d59c0a5c9cce095e6264cbbb18ccbb37a2 Mon Sep 17 00:00:00 2001 From: emilis Date: Sat, 8 Nov 2025 00:44:55 +0000 Subject: [PATCH] beholder target roleblocked sees nothing slightly nicer game end screen --- werewolves-proto/src/game/mod.rs | 9 +++++ werewolves-proto/src/game/night.rs | 2 +- werewolves-proto/src/game/night/process.rs | 7 ++-- werewolves-proto/src/game/story.rs | 2 ++ werewolves-proto/src/message/night.rs | 1 + werewolves/index.scss | 27 ++++++++++++++ werewolves/src/clients/host/host.rs | 37 ++++++++++--------- werewolves/src/components/action/result.rs | 7 ++-- werewolves/src/components/story.rs | 3 ++ werewolves/src/components/victory.rs | 42 ++++++++++++++++++++++ werewolves/src/pages/role_page/beholder.rs | 16 +++++++++ 11 files changed, 131 insertions(+), 22 deletions(-) create mode 100644 werewolves/src/components/victory.rs diff --git a/werewolves-proto/src/game/mod.rs b/werewolves-proto/src/game/mod.rs index c5b32a2..db60be1 100644 --- a/werewolves-proto/src/game/mod.rs +++ b/werewolves-proto/src/game/mod.rs @@ -282,6 +282,15 @@ pub enum GameOver { WolvesWin, } +impl Display for GameOver { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + GameOver::VillageWins => f.write_str("village wins"), + GameOver::WolvesWin => f.write_str("wolves win"), + } + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Pool where diff --git a/werewolves-proto/src/game/night.rs b/werewolves-proto/src/game/night.rs index e398a1c..f0bc422 100644 --- a/werewolves-proto/src/game/night.rs +++ b/werewolves-proto/src/game/night.rs @@ -932,7 +932,7 @@ impl Night { NightState::Active { current_result: CurrentResult::Result(current_result), .. - } => Some(¤t_result), + } => Some(current_result), NightState::Active { current_result: CurrentResult::GoBackToSleepAfterShown { .. }, .. diff --git a/werewolves-proto/src/game/night/process.rs b/werewolves-proto/src/game/night/process.rs index 171d95d..d13dc7e 100644 --- a/werewolves-proto/src/game/night/process.rs +++ b/werewolves-proto/src/game/night/process.rs @@ -395,10 +395,13 @@ impl Night { if let Some(result) = self.used_actions.iter().find_map(|(prompt, result, _)| { prompt.matches_beholding(*marked).then_some(result) }) && self.dies_tonight(*marked)? - && !matches!(result, ActionResult::RoleBlocked) { Ok(ActionComplete { - result: result.clone(), + result: if matches!(result, ActionResult::RoleBlocked) { + ActionResult::BeholderSawNothing + } else { + result.clone() + }, change: None, } .into()) diff --git a/werewolves-proto/src/game/story.rs b/werewolves-proto/src/game/story.rs index 532fde8..de210d5 100644 --- a/werewolves-proto/src/game/story.rs +++ b/werewolves-proto/src/game/story.rs @@ -83,11 +83,13 @@ pub enum StoryActionResult { Mortician(DiedToTitle), Insomniac { visits: Box<[CharacterId]> }, Empath { scapegoat: bool }, + BeholderSawNothing, } impl StoryActionResult { pub fn new(result: ActionResult) -> Option { Some(match result { + ActionResult::BeholderSawNothing => Self::BeholderSawNothing, ActionResult::RoleBlocked => Self::RoleBlocked, ActionResult::Seer(alignment) => Self::Seer(alignment), ActionResult::PowerSeer { powerful } => Self::PowerSeer { powerful }, diff --git a/werewolves-proto/src/message/night.rs b/werewolves-proto/src/message/night.rs index 75a338c..1185c57 100644 --- a/werewolves-proto/src/message/night.rs +++ b/werewolves-proto/src/message/night.rs @@ -484,6 +484,7 @@ pub enum ActionResult { Mortician(DiedToTitle), Insomniac(Visits), Empath { scapegoat: bool }, + BeholderSawNothing, GoBackToSleep, Continue, } diff --git a/werewolves/index.scss b/werewolves/index.scss index 7d6c9a7..3583636 100644 --- a/werewolves/index.scss +++ b/werewolves/index.scss @@ -1306,7 +1306,10 @@ input { margin-top: 2%; font-size: 1.5vw; + height: 100vh; + .setup { + height: 85%; display: flex; flex-direction: row; flex-wrap: wrap; @@ -1322,6 +1325,7 @@ input { &.final { margin-top: 1cm; + margin-bottom: 1cm; } & .title { @@ -1870,3 +1874,26 @@ input { font-size: 3rem; text-align: center; } + +.victory { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: center; + align-items: center; + font-size: 3vw; + height: max-content; + gap: 1cm; + padding: 1cm; +} + + +.end-screen { + display: flex; + flex-direction: column; + flex-wrap: nowrap; + width: 100vw; + height: 100vh; + align-items: center; + justify-content: center; +} diff --git a/werewolves/src/clients/host/host.rs b/werewolves/src/clients/host/host.rs index ef2dd1c..393ce2c 100644 --- a/werewolves/src/clients/host/host.rs +++ b/werewolves/src/clients/host/host.rs @@ -41,7 +41,7 @@ use yew::{html::Scope, prelude::*}; use crate::{ callback, components::{ - Button, CoverOfDarkness, Lobby, LobbyPlayerAction, RoleReveal, Settings, Story, + Button, CoverOfDarkness, Lobby, LobbyPlayerAction, RoleReveal, Settings, Story, Victory, action::{ActionResultView, Prompt}, host::{DaytimePlayerList, Setup}, }, @@ -312,15 +312,26 @@ impl Component for Host { log::trace!("state: {:?}", self.state); let content = match self.state.clone() { HostState::Story { story, page } => { - let new_lobby_click = crate::callback::send_message( - HostMessage::PostGame(PostGameMessage::NewLobby), - self.send.clone(), - ); - html! { -
+ if let Some(outcome) = story + .final_village() + .ok() + .and_then(|village| village.is_game_over()) + && self.big_screen + { + html! { + + } + } else { + let new_lobby_click = crate::callback::send_message( + HostMessage::PostGame(PostGameMessage::NewLobby), + self.send.clone(), + ); + html! { +
-
+
+ } } } HostState::GameOver { result } => { @@ -332,15 +343,7 @@ impl Component for Host { }); html! { - "village wins", - GameOver::WolvesWin => "wolves win", - }} - next={cont} - > - {"continue"} - + } } HostState::Disconnected => html! { diff --git a/werewolves/src/components/action/result.rs b/werewolves/src/components/action/result.rs index 0f3b66e..7c58df5 100644 --- a/werewolves/src/components/action/result.rs +++ b/werewolves/src/components/action/result.rs @@ -25,8 +25,8 @@ use yew::prelude::*; use crate::{ components::{Button, CoverOfDarkness, Icon, IconSource, Identity}, pages::{ - AdjudicatorResult, ArcanistResult, EmpathResult, GravediggerResultPage, InsomniacResult, - MorticianResultPage, PowerSeerResult, RoleblockPage, SeerResult, + AdjudicatorResult, ArcanistResult, BeholderSawNothing, EmpathResult, GravediggerResultPage, + InsomniacResult, MorticianResultPage, PowerSeerResult, RoleblockPage, SeerResult, }, }; @@ -58,6 +58,9 @@ pub fn ActionResultView(props: &ActionResultProps) -> Html { .not() .then(|| html! {}); let body = match &props.result { + ActionResult::BeholderSawNothing => html! { + + }, ActionResult::PowerSeer { powerful } => { html! { diff --git a/werewolves/src/components/story.rs b/werewolves/src/components/story.rs index 54d1a89..c49f30e 100644 --- a/werewolves/src/components/story.rs +++ b/werewolves/src/components/story.rs @@ -274,6 +274,9 @@ struct StoryNightResultProps { #[function_component] fn StoryNightResult(StoryNightResultProps { result, characters }: &StoryNightResultProps) -> Html { match result { + StoryActionResult::BeholderSawNothing => html!{ + {"but saw nothing"} + }, StoryActionResult::RoleBlocked => html! { {"but was role blocked"} }, diff --git a/werewolves/src/components/victory.rs b/werewolves/src/components/victory.rs new file mode 100644 index 0000000..12f86fe --- /dev/null +++ b/werewolves/src/components/victory.rs @@ -0,0 +1,42 @@ +use werewolves_proto::game::GameOver; +use yew::prelude::*; + +use crate::components::{Button, Icon, IconSource, IconType}; + +#[derive(Debug, Clone, PartialEq, Properties)] +pub struct VictoryProps { + pub outcome: GameOver, + #[prop_or_default] + pub cont: Option>, +} + +#[function_component] +pub fn Victory(VictoryProps { outcome, cont }: &VictoryProps) -> Html { + let cont_btn = cont.clone().map(|cont| { + html! { + + } + }); + match outcome { + GameOver::WolvesWin => html! { +
+
+ +

{"Wolves Win"}

+ +
+ {cont_btn} +
+ }, + GameOver::VillageWins => html! { +
+
+ +

{"Village Wins"}

+ +
+ {cont_btn} +
+ }, + } +} diff --git a/werewolves/src/pages/role_page/beholder.rs b/werewolves/src/pages/role_page/beholder.rs index 3201097..b125657 100644 --- a/werewolves/src/pages/role_page/beholder.rs +++ b/werewolves/src/pages/role_page/beholder.rs @@ -14,6 +14,8 @@ // along with this program. If not, see . use yew::prelude::*; +use crate::components::{Icon, IconSource, IconType}; + #[function_component] pub fn BeholderPage1() -> Html { html! { @@ -27,3 +29,17 @@ pub fn BeholderPage1() -> Html { } } + +#[function_component] +pub fn BeholderSawNothing() -> Html { + html! { +
+

{"BEHOLDER"}

+
+

{"YOUR TARGET HAS DIED"}

+

+

{"BUT SAW NOTHING"}

+
+
+ } +}