fix: picking dead players in daytime view

This commit is contained in:
emilis 2026-02-22 23:43:09 +00:00
parent 5a452b220c
commit 567e023a73
No known key found for this signature in database
10 changed files with 54 additions and 12 deletions

View File

@ -1051,6 +1051,11 @@ form {
background-color: color.change($red2, $alpha: 0.3);
border: 1px solid color.change($red2, $alpha: 0.8);
}
&.dead {
filter: grayscale(100%);
cursor: default;
}
}
}

View File

@ -213,9 +213,12 @@ impl Game {
self.process(HostGameMessage::GetState)
}
(
GameState::Day { village: _, marked },
GameState::Day { village, marked },
HostGameMessage::Day(HostDayMessage::MarkForExecution(target)),
) => {
if village.character_by_id(target)?.died_to().is_some() {
return Err(GameError::CharacterAlreadyDead);
}
match marked
.iter()
.enumerate()

View File

@ -10,6 +10,8 @@ use leptos_use::{
use_websocket_with_options,
};
use reactive_stores::Store;
use sorted_vec::SortedSet;
use werewolves_proto::message::dead::DeadChatMessage;
use werewolves_proto::message::host::ServerToHostMessage;
use werewolves_proto::message::{ClientMessage, host::HostMessage};
use werewolves_proto::message::{IntoClientResponse, WrappedServerMessage};
@ -28,6 +30,7 @@ use crate::{
#[component]
pub fn GamePage(error: WriteSignal<Option<WolfError>>) -> impl IntoView {
let dead_chat_messages: RwSignal<SortedSet<DeadChatMessage>> = RwSignal::new(SortedSet::new());
move || {
let params = hooks::use_params_map();
let auth = expect_context::<Store<AuthContext>>();
@ -197,12 +200,18 @@ pub fn GamePage(error: WriteSignal<Option<WolfError>>) -> impl IntoView {
view! {
{status}
<HostGamePage error=error message=host_message.into() reply=host_reply.write_only() />
<HostGamePage
error=error
message=host_message.into()
reply=host_reply.write_only()
dead_chat_messages=dead_chat_messages
/>
<PlayerGamePage
error=error
message=player_message.into()
reply=player_reply.write_only()
disconnect=disconnect
dead_chat_messages=dead_chat_messages
/>
}
}

View File

@ -1,5 +1,5 @@
werewolves_macros::include_path!("werewolves/src/app/pages/game/big");
use core::str::FromStr;
use core::{ops::DerefMut, str::FromStr};
use crate::{
ConsoleLogError,
@ -14,6 +14,7 @@ use crate::{
},
};
use codee::binary::MsgpackSerdeCodec;
use gloo::history::History;
use leptos::prelude::*;
use leptos_router::hooks;
use leptos_use::{
@ -21,10 +22,12 @@ use leptos_use::{
use_websocket_with_options,
};
use reactive_stores::Store;
use sorted_vec::SortedSet;
use werewolves_proto::{
game::GameId,
message::{
CharacterIdentity, IntoClientResponse, WrappedServerMessage,
dead::DeadChatMessage,
host::ServerToHostMessage,
night::{ActionPrompt, ActionResult},
},
@ -51,6 +54,7 @@ enum BigScreenPage {
#[component]
pub fn BigScreen() -> impl IntoView {
let dead_chat_messages: RwSignal<SortedSet<DeadChatMessage>> = RwSignal::new(SortedSet::new());
move || {
let params = hooks::use_params_map();
let auth = expect_context::<Store<AuthContext>>();
@ -210,8 +214,15 @@ pub fn BigScreen() -> impl IntoView {
page.set(BigScreenPage::RoleReveal);
}
ServerToHostMessage::Story { story, page } => todo!(),
ServerToHostMessage::DeadChat(dead_chat_messages) => todo!(),
ServerToHostMessage::DeadChatMessage(dead_chat_message) => todo!(),
ServerToHostMessage::DeadChat(m) => {
let mut dcm = dead_chat_messages.write();
for msg in m {
dcm.push(msg);
}
}
ServerToHostMessage::DeadChatMessage(msg) => {
dead_chat_messages.write().push(msg);
}
}
});

View File

@ -7,11 +7,13 @@ use core::{num::NonZeroU8, ops::Not};
use std::collections::HashMap;
use leptos::prelude::*;
use sorted_vec::SortedSet;
use werewolves_proto::{
character::CharacterId,
game::{Category, GameSettings},
message::{
CharacterIdentity, CharacterState, PlayerState,
dead::DeadChatMessage,
host::{HostGameMessage, HostLobbyMessage, HostMessage, ServerToHostMessage as Srv2Host},
night::{ActionPrompt, ActionResult},
},
@ -55,6 +57,7 @@ pub fn HostGamePage(
error: WriteSignal<Option<WolfError>>,
message: Signal<Option<Srv2Host>>,
reply: WriteSignal<Option<HostMessage>>,
dead_chat_messages: RwSignal<SortedSet<DeadChatMessage>>,
) -> impl IntoView {
let prefs = expect_context::<(Signal<Preferences>, WriteSignal<Preferences>)>().0;
let page = RwSignal::new(HostPage::default());

View File

@ -161,10 +161,13 @@ fn DaytimePlayer(
..
} = character;
let character_id = identity.character_id;
let dead = died_to.is_some();
let select = move |_| {
if !dead {
reply.set(Some(HostMessage::InGame(HostGameMessage::Day(
HostDayMessage::MarkForExecution(character_id),
))))
}
};
let icon = role.icon().unwrap_or_else(|| role.alignment().icon());

View File

@ -39,6 +39,7 @@ pub fn PlayerGamePage(
message: Signal<Option<Srv2Client>>,
reply: WriteSignal<Option<ClientMessage>>,
disconnect: RwSignal<bool>,
dead_chat_messages: RwSignal<SortedSet<DeadChatMessage>>,
) -> impl IntoView {
let dead_chat: RwSignal<Option<SortedSet<DeadChatMessage>>> = RwSignal::new(None);
let page: RwSignal<Option<Page>> = RwSignal::new(None);

View File

@ -360,7 +360,11 @@ pub fn TargetPicker(
})
.collect_view();
view! { <div class="target-picker" class:allow-scroll=pick.is_some()>{targets}</div> }
view! {
<div class="target-picker" class:allow-scroll=pick.is_some()>
{targets}
</div>
}
}
#[component]

View File

@ -41,7 +41,10 @@ pub fn ArcanistResult(
let text = match value {
AlignmentEq::Same => view! { "ARE THE SAME" }.into_any(),
AlignmentEq::Different => {
view! {"ARE "<span class="wolves underline">"DIFFERENT"</span>}.into_any()
view! {
"ARE "
<span class="wolves underline">"DIFFERENT"</span>
}.into_any()
}
};
let icons = match value {