maple wolf: show nights til starving
This commit is contained in:
parent
8e1d2e34d0
commit
9b19b51581
|
|
@ -482,7 +482,8 @@ impl Character {
|
|||
}),
|
||||
Role::MapleWolf { last_kill_on_night } => prompts.push(ActionPrompt::MapleWolf {
|
||||
character_id: self.identity(),
|
||||
kill_or_die: last_kill_on_night + MAPLE_WOLF_ABSTAIN_LIMIT.get() == night,
|
||||
nights_til_starvation: (last_kill_on_night + MAPLE_WOLF_ABSTAIN_LIMIT.get())
|
||||
- night,
|
||||
living_players: village.living_players_excluding(self.character_id()),
|
||||
marked: None,
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -108,13 +108,13 @@ impl Night {
|
|||
Some((
|
||||
ActionPrompt::MapleWolf {
|
||||
character_id,
|
||||
kill_or_die,
|
||||
nights_til_starvation,
|
||||
marked,
|
||||
..
|
||||
},
|
||||
_,
|
||||
)) => {
|
||||
if *kill_or_die {
|
||||
if *nights_til_starvation == 0 {
|
||||
(character_id.character_id, *marked)
|
||||
} else {
|
||||
return Ok(());
|
||||
|
|
|
|||
|
|
@ -238,8 +238,8 @@ impl Night {
|
|||
}
|
||||
ActionPrompt::MapleWolf {
|
||||
character_id,
|
||||
kill_or_die,
|
||||
marked: Some(marked),
|
||||
nights_til_starvation,
|
||||
..
|
||||
} => Ok(ResponseOutcome::ActionComplete(ActionComplete {
|
||||
result: ActionResult::GoBackToSleep,
|
||||
|
|
@ -248,7 +248,7 @@ impl Night {
|
|||
died_to: DiedTo::MapleWolf {
|
||||
night,
|
||||
source: character_id.character_id,
|
||||
starves_if_fails: *kill_or_die,
|
||||
starves_if_fails: *nights_til_starvation == 0,
|
||||
},
|
||||
}),
|
||||
})),
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ pub enum ActionPrompt {
|
|||
#[checks(ActionType::Other)]
|
||||
MapleWolf {
|
||||
character_id: CharacterIdentity,
|
||||
kill_or_die: bool,
|
||||
nights_til_starvation: u8,
|
||||
living_players: Box<[CharacterIdentity]>,
|
||||
marked: Option<CharacterId>,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2412,3 +2412,14 @@ li.choice {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.inc-dec {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
gap: 20px;
|
||||
|
||||
.inc-dec-content {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@ pub mod host {
|
|||
mod host;
|
||||
pub use host::*;
|
||||
}
|
||||
pub mod test_remote;
|
||||
// mod socket;
|
||||
|
||||
const DEBUG_URL: &str = "ws://192.168.1.162:8080/connect/";
|
||||
const LIVE_URL: &str = "wss://wolf.emilis.dev/connect/";
|
||||
|
|
|
|||
|
|
@ -1,70 +0,0 @@
|
|||
// 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 futures::{SinkExt, StreamExt, TryStreamExt, lock::Mutex};
|
||||
use gloo::net::websocket::{Message, futures::WebSocket};
|
||||
use werewolves_proto::message::host::{HostLobbyMessage, HostMessage, ServerToHostMessage};
|
||||
use yew::prelude::*;
|
||||
|
||||
use crate::test_util::TestScreens;
|
||||
|
||||
fn url() -> String {
|
||||
format!(
|
||||
"{}host",
|
||||
option_env!("LOCAL")
|
||||
.map(|_| crate::clients::DEBUG_URL)
|
||||
.unwrap_or(crate::clients::LIVE_URL)
|
||||
)
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
pub fn TestClientRemote() -> Html {
|
||||
gloo::utils::document().set_title("werewolves — remote test");
|
||||
let send = use_memo((), |_| Mutex::new(WebSocket::open(url().as_str()).unwrap()));
|
||||
let send_cb = {
|
||||
let send = send.clone();
|
||||
Callback::from(move |msg: ServerToHostMessage| {
|
||||
let send = send.clone();
|
||||
yew::platform::spawn_local(async move {
|
||||
send.lock()
|
||||
.await
|
||||
.send(gloo::net::websocket::Message::Bytes({
|
||||
let mut v = Vec::new();
|
||||
ciborium::into_writer(&HostMessage::Echo(msg.clone()), &mut v).unwrap();
|
||||
v
|
||||
}))
|
||||
.await
|
||||
.unwrap();
|
||||
loop {
|
||||
match send.lock().await.try_next().await {
|
||||
Ok(Some(Message::Bytes(b))) => {
|
||||
let recv: ServerToHostMessage =
|
||||
ciborium::from_reader(b.as_slice()).unwrap();
|
||||
if recv == msg {
|
||||
log::debug!("recv'd echo");
|
||||
return;
|
||||
}
|
||||
}
|
||||
Ok(_) => panic!("got text message"),
|
||||
Err(err) => panic!("{err}"),
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
};
|
||||
html! {
|
||||
<TestScreens send={send_cb} />
|
||||
}
|
||||
}
|
||||
|
|
@ -375,14 +375,14 @@ pub fn Prompt(props: &ActionPromptProps) -> Html {
|
|||
),
|
||||
ActionPrompt::MapleWolf {
|
||||
character_id,
|
||||
kill_or_die,
|
||||
nights_til_starvation,
|
||||
living_players,
|
||||
marked,
|
||||
} => (
|
||||
Some(character_id),
|
||||
living_players,
|
||||
marked.iter().cloned().collect(),
|
||||
html! {<>{"maple wolf"} {kill_or_die.then_some(" — starving")}</>},
|
||||
html! {<>{"maple wolf"} {(*nights_til_starvation == 0).then_some(" — starving")}</>},
|
||||
),
|
||||
ActionPrompt::WolfPackKill {
|
||||
living_villagers,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
use core::ops::Range;
|
||||
|
||||
// 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 yew::prelude::*;
|
||||
|
||||
use crate::components::Button;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||
pub struct IncDecU8Props {
|
||||
#[prop_or_default]
|
||||
pub children: Html,
|
||||
#[prop_or_default]
|
||||
pub class: yew::Classes,
|
||||
#[prop_or_default]
|
||||
pub button_class: yew::Classes,
|
||||
pub value: u8,
|
||||
pub value_range: Range<u8>,
|
||||
pub on_update: Callback<u8>,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
pub fn IncDecU8(
|
||||
IncDecU8Props {
|
||||
children,
|
||||
class,
|
||||
button_class,
|
||||
value,
|
||||
value_range,
|
||||
on_update,
|
||||
}: &IncDecU8Props,
|
||||
) -> Html {
|
||||
let value_state = use_state(|| *value);
|
||||
let dec_disabled = value_range
|
||||
.clone()
|
||||
.next()
|
||||
.and_then(|start| (start >= *value).then_some(String::from("already at minimum")));
|
||||
let dec = {
|
||||
let current = *value;
|
||||
let on_update = on_update.clone();
|
||||
let value_state = value_state.setter();
|
||||
Callback::from(move |_| {
|
||||
let new = current.saturating_sub(1);
|
||||
on_update.emit(new);
|
||||
value_state.set(new);
|
||||
})
|
||||
};
|
||||
let inc_disabled = value_range
|
||||
.clone()
|
||||
.last()
|
||||
.and_then(|end| (*value >= end).then_some(String::from("already at max value")));
|
||||
let inc = {
|
||||
let current = *value;
|
||||
let on_update = on_update.clone();
|
||||
let value_state = value_state.setter();
|
||||
Callback::from(move |_| {
|
||||
let new = current.saturating_add(1);
|
||||
on_update.emit(new);
|
||||
value_state.set(new);
|
||||
})
|
||||
};
|
||||
html! {
|
||||
<div class={classes!("inc-dec", class.clone())}>
|
||||
<Button
|
||||
on_click={dec}
|
||||
disabled_reason={dec_disabled}
|
||||
classes={button_class.clone()}
|
||||
>
|
||||
{"decrease"}
|
||||
</Button>
|
||||
<div class="inc-dec-content">
|
||||
<span class="inc-dec-count">{*value_state}</span>
|
||||
{children.clone()}
|
||||
</div>
|
||||
<Button
|
||||
on_click={inc}
|
||||
disabled_reason={inc_disabled}
|
||||
classes={button_class.clone()}
|
||||
>
|
||||
{"increase"}
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
|
@ -46,13 +46,9 @@ const BUILD_ID_LONG: &str = werewolves_macros::build_id_long!();
|
|||
const BUILD_DIRTY: bool = werewolves_macros::build_dirty!();
|
||||
const BUILD_TIME: &str = werewolves_macros::build_time!();
|
||||
|
||||
use crate::{
|
||||
clients::{
|
||||
client::{Client2, ClientContext},
|
||||
host::{Host, HostEvent},
|
||||
test_remote::TestClientRemote,
|
||||
},
|
||||
test_util::TestScreens,
|
||||
use crate::clients::{
|
||||
client::{Client2, ClientContext},
|
||||
host::{Host, HostEvent},
|
||||
};
|
||||
|
||||
fn main() {
|
||||
|
|
@ -70,9 +66,7 @@ fn main() {
|
|||
let error_callback =
|
||||
Callback::from(move |err: Option<WerewolfError>| cb_clone.send_message(err));
|
||||
|
||||
if path.starts_with("/host/test") {
|
||||
yew::Renderer::<TestClientRemote>::with_root(app_element).render();
|
||||
} else if path.starts_with("/host") {
|
||||
if path.starts_with("/host") {
|
||||
let host = yew::Renderer::<Host>::with_root(app_element).render();
|
||||
if path.starts_with("/host/big") {
|
||||
host.send_message(HostEvent::SetBigScreenState(true));
|
||||
|
|
|
|||
|
|
@ -109,14 +109,16 @@ impl RolePage for ActionPrompt {
|
|||
}]),
|
||||
ActionPrompt::MapleWolf {
|
||||
character_id,
|
||||
kill_or_die,
|
||||
nights_til_starvation,
|
||||
..
|
||||
} => Rc::new([html! {
|
||||
} => [html! {
|
||||
<>
|
||||
{ident(character_id)}
|
||||
<MapleWolfPage1 starving={*kill_or_die} />
|
||||
<MapleWolfPage1 nights_til_starvation={*nights_til_starvation} />
|
||||
</>
|
||||
}]),
|
||||
}]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
ActionPrompt::MasonLeaderRecruit {
|
||||
character_id,
|
||||
recruits_left,
|
||||
|
|
|
|||
|
|
@ -17,27 +17,45 @@ use yew::prelude::*;
|
|||
use crate::components::{Icon, IconSource, IconType};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
||||
pub struct MapleWolfPage1Props {
|
||||
pub starving: bool,
|
||||
pub struct MapleWolfPageProps {
|
||||
pub nights_til_starvation: u8,
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
pub fn MapleWolfPage1(MapleWolfPage1Props { starving }: &MapleWolfPage1Props) -> Html {
|
||||
let starving = starving
|
||||
.then_some(html! {
|
||||
pub fn MapleWolfPage1(
|
||||
MapleWolfPageProps {
|
||||
nights_til_starvation,
|
||||
}: &MapleWolfPageProps,
|
||||
) -> Html {
|
||||
let food_state = if *nights_til_starvation == 0 {
|
||||
html! {
|
||||
<div>
|
||||
<h3 class="red">{"YOU ARE STARVING"}</h3>
|
||||
<h3>{"IF YOU FAIL TO EAT TONIGHT, YOU WILL DIE"}</h3>
|
||||
</div>
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
}
|
||||
} else {
|
||||
let nights = if *nights_til_starvation == 1 {
|
||||
html! {
|
||||
<h3>
|
||||
{"IF YOU DON'T EAT FOR TOO LONG, YOU WILL "}
|
||||
<span class="red">{"STARVE"}</span>
|
||||
</h3>
|
||||
<>
|
||||
<span class="red">{"TOMORROW NIGHT "}</span>
|
||||
</>
|
||||
}
|
||||
});
|
||||
} else {
|
||||
html! {
|
||||
<>
|
||||
{"IN "}<span class="red">{*nights_til_starvation}</span>{" NIGHTS "}
|
||||
</>
|
||||
}
|
||||
};
|
||||
html! {
|
||||
<h3>
|
||||
{"IF YOU FAIL TO EAT "}
|
||||
{nights}
|
||||
{"YOU WILL "}<span class="yellow">{"STARVE"}</span>
|
||||
</h3>
|
||||
}
|
||||
};
|
||||
html! {
|
||||
<div class="role-page">
|
||||
<h1 class="offensive">{"MAPLE WOLF"}</h1>
|
||||
|
|
@ -48,7 +66,7 @@ pub fn MapleWolfPage1(MapleWolfPage1Props { starving }: &MapleWolfPage1Props) ->
|
|||
<div class="info-icon-grow">
|
||||
<Icon source={IconSource::MapleWolf} icon_type={IconType::Fit}/>
|
||||
</div>
|
||||
{starving}
|
||||
{food_state}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,10 +21,8 @@ use werewolves_proto::{
|
|||
diedto::DiedToTitle,
|
||||
message::{
|
||||
CharacterIdentity,
|
||||
host::{HostMessage, ServerToHostMessage},
|
||||
night::{
|
||||
ActionPrompt, ActionPromptTitle, ActionResult, ActionResultTitle, ActionType, Visits,
|
||||
},
|
||||
host::ServerToHostMessage,
|
||||
night::{ActionPrompt, ActionPromptTitle, ActionResult, ActionResultTitle, Visits},
|
||||
},
|
||||
role::{Alignment, AlignmentEq, Killer, Powerful, RoleTitle},
|
||||
};
|
||||
|
|
@ -304,7 +302,7 @@ impl From<ActionPromptTitle> for TestScreen {
|
|||
},
|
||||
ActionPromptTitle::MapleWolf => ActionPrompt::MapleWolf {
|
||||
character_id: identities(1).into_iter().next().unwrap(),
|
||||
kill_or_die: false,
|
||||
nights_til_starvation: 0,
|
||||
living_players: identities(20),
|
||||
marked: None,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -18,15 +18,15 @@ use core::num::NonZeroU8;
|
|||
|
||||
use web_sys::HtmlSelectElement;
|
||||
use werewolves_proto::{
|
||||
message::{
|
||||
host::{HostGameMessage, HostMessage, HostNightMessage, ServerToHostMessage},
|
||||
night::ActionPrompt,
|
||||
},
|
||||
player::RoleChange,
|
||||
message::{host::ServerToHostMessage, night::ActionPrompt},
|
||||
role::{PreviousGuardianAction, RoleTitle},
|
||||
};
|
||||
|
||||
use crate::{components::Button, pages::RolePage, test_util::identities};
|
||||
use crate::{
|
||||
components::{Button, IncDecU8},
|
||||
pages::RolePage,
|
||||
test_util::identities,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||
pub struct PromptScreenTestProps {
|
||||
|
|
@ -47,30 +47,11 @@ pub fn PromptScreenTest(
|
|||
) -> Html {
|
||||
let options = match prompt {
|
||||
ActionPrompt::WolvesIntro { wolves } => {
|
||||
let dec_disabled = wolves
|
||||
.is_empty()
|
||||
.then_some(String::from("already have zero wolves"));
|
||||
let dec = {
|
||||
let current = wolves.len();
|
||||
let on_update = {
|
||||
let send = send.clone();
|
||||
Callback::from(move |_| {
|
||||
Callback::from(move |new_count: u8| {
|
||||
let new_prompt = ActionPrompt::WolvesIntro {
|
||||
wolves: super::identities(current - 1)
|
||||
.into_iter()
|
||||
.zip(RoleTitle::ALL.into_iter().filter(|w| w.wolf()).cycle())
|
||||
.collect(),
|
||||
};
|
||||
send.emit(ServerToHostMessage::ActionPrompt(new_prompt.clone(), 0));
|
||||
})
|
||||
};
|
||||
let inc_disabled =
|
||||
(wolves.len() + 1 > 0xFF).then_some(String::from("already at max wolves"));
|
||||
let inc = {
|
||||
let current = wolves.len();
|
||||
let send = send.clone();
|
||||
Callback::from(move |_| {
|
||||
let new_prompt = ActionPrompt::WolvesIntro {
|
||||
wolves: super::identities(current + 1)
|
||||
wolves: super::identities(new_count as _)
|
||||
.into_iter()
|
||||
.zip(RoleTitle::ALL.into_iter().filter(|w| w.wolf()).cycle())
|
||||
.collect(),
|
||||
|
|
@ -79,21 +60,13 @@ pub fn PromptScreenTest(
|
|||
})
|
||||
};
|
||||
html! {
|
||||
<div class="prompt-number">
|
||||
<Button
|
||||
on_click={dec}
|
||||
disabled_reason={dec_disabled}
|
||||
>
|
||||
{"decrease"}
|
||||
</Button>
|
||||
<label>{wolves.len()}{" wolves"}</label>
|
||||
<Button
|
||||
on_click={inc}
|
||||
disabled_reason={inc_disabled}
|
||||
>
|
||||
{"increase"}
|
||||
</Button>
|
||||
</div>
|
||||
<IncDecU8
|
||||
value={wolves.len() as u8}
|
||||
value_range={1..0xFF}
|
||||
on_update={on_update}
|
||||
>
|
||||
{" wolves"}
|
||||
</IncDecU8>
|
||||
}
|
||||
}
|
||||
ActionPrompt::RoleChange { new_role, .. } => {
|
||||
|
|
@ -194,14 +167,16 @@ pub fn PromptScreenTest(
|
|||
</div>
|
||||
}
|
||||
}
|
||||
ActionPrompt::MapleWolf { kill_or_die, .. } => {
|
||||
let toggle = !*kill_or_die;
|
||||
let on_toggle = {
|
||||
ActionPrompt::MapleWolf {
|
||||
nights_til_starvation,
|
||||
..
|
||||
} => {
|
||||
let on_update = {
|
||||
let send = send.clone();
|
||||
Callback::from(move |_| {
|
||||
Callback::from(move |new_nights: u8| {
|
||||
let new_prompt = ActionPrompt::MapleWolf {
|
||||
character_id: super::identity(),
|
||||
kill_or_die: toggle,
|
||||
nights_til_starvation: new_nights,
|
||||
living_players: identities(20),
|
||||
marked: None,
|
||||
};
|
||||
|
|
@ -209,14 +184,15 @@ pub fn PromptScreenTest(
|
|||
})
|
||||
};
|
||||
|
||||
let button_text = if toggle {
|
||||
"turn starving"
|
||||
} else {
|
||||
"feed the poor boy"
|
||||
};
|
||||
html! {
|
||||
<div class="prompt-options">
|
||||
<Button on_click={on_toggle}>{button_text}</Button>
|
||||
<IncDecU8
|
||||
value={*nights_til_starvation}
|
||||
value_range={0..0xFF}
|
||||
on_update={on_update}
|
||||
>
|
||||
{" nights"}
|
||||
</IncDecU8>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
|
@ -284,75 +260,33 @@ pub fn PromptScreenTest(
|
|||
}
|
||||
}
|
||||
ActionPrompt::MasonsWake { masons, .. } => {
|
||||
let dec_disabled =
|
||||
(masons.len() == 1).then_some(String::from("already at min recruits"));
|
||||
let dec = {
|
||||
let current = masons.len();
|
||||
let on_update = {
|
||||
let send = send.clone();
|
||||
Callback::from(move |_| {
|
||||
Callback::from(move |new_count: u8| {
|
||||
let new_prompt = ActionPrompt::MasonsWake {
|
||||
leader: super::identity(),
|
||||
masons: super::identities(current.saturating_sub(1)),
|
||||
};
|
||||
send.emit(ServerToHostMessage::ActionPrompt(new_prompt.clone(), 0));
|
||||
})
|
||||
};
|
||||
let inc_disabled =
|
||||
(masons.len() > 0xFF).then_some(String::from("already at max wolves"));
|
||||
let inc = {
|
||||
let current = masons.len();
|
||||
let send = send.clone();
|
||||
Callback::from(move |_| {
|
||||
let new_prompt = ActionPrompt::MasonsWake {
|
||||
leader: super::identity(),
|
||||
masons: super::identities(current.saturating_add(1)),
|
||||
masons: super::identities(new_count as _),
|
||||
};
|
||||
send.emit(ServerToHostMessage::ActionPrompt(new_prompt.clone(), 0));
|
||||
})
|
||||
};
|
||||
html! {
|
||||
<div class="prompt-number">
|
||||
<Button
|
||||
on_click={dec}
|
||||
disabled_reason={dec_disabled}
|
||||
>
|
||||
{"decrease"}
|
||||
</Button>
|
||||
<label>{masons.len()}{" masons"}</label>
|
||||
<Button
|
||||
on_click={inc}
|
||||
disabled_reason={inc_disabled}
|
||||
>
|
||||
{"increase"}
|
||||
</Button>
|
||||
</div>
|
||||
<IncDecU8
|
||||
value={masons.len() as u8}
|
||||
value_range={1..0xFF}
|
||||
on_update={on_update}
|
||||
>
|
||||
{" masons"}
|
||||
</IncDecU8>
|
||||
}
|
||||
}
|
||||
ActionPrompt::MasonLeaderRecruit { recruits_left, .. } => {
|
||||
let dec_disabled =
|
||||
(recruits_left.get() == 1).then_some(String::from("already at min recruits"));
|
||||
let dec = {
|
||||
let current = recruits_left.get();
|
||||
let on_update = {
|
||||
let send = send.clone();
|
||||
Callback::from(move |_| {
|
||||
Callback::from(move |new_count: u8| {
|
||||
let new_prompt = ActionPrompt::MasonLeaderRecruit {
|
||||
character_id: super::identity(),
|
||||
recruits_left: NonZeroU8::new(current.saturating_sub(1)).unwrap(),
|
||||
potential_recruits: identities(20),
|
||||
marked: None,
|
||||
};
|
||||
send.emit(ServerToHostMessage::ActionPrompt(new_prompt.clone(), 0));
|
||||
})
|
||||
};
|
||||
let inc_disabled =
|
||||
(recruits_left.get() == 0xFF).then_some(String::from("already at max wolves"));
|
||||
let inc = {
|
||||
let current = recruits_left.get();
|
||||
let send = send.clone();
|
||||
Callback::from(move |_| {
|
||||
let new_prompt = ActionPrompt::MasonLeaderRecruit {
|
||||
character_id: super::identity(),
|
||||
recruits_left: NonZeroU8::new(current.saturating_add(1)).unwrap(),
|
||||
recruits_left: NonZeroU8::new(new_count).unwrap(),
|
||||
potential_recruits: identities(20),
|
||||
marked: None,
|
||||
};
|
||||
|
|
@ -360,21 +294,13 @@ pub fn PromptScreenTest(
|
|||
})
|
||||
};
|
||||
html! {
|
||||
<div class="prompt-number">
|
||||
<Button
|
||||
on_click={dec}
|
||||
disabled_reason={dec_disabled}
|
||||
>
|
||||
{"decrease"}
|
||||
</Button>
|
||||
<label>{recruits_left.get()}{" recruits"}</label>
|
||||
<Button
|
||||
on_click={inc}
|
||||
disabled_reason={inc_disabled}
|
||||
>
|
||||
{"increase"}
|
||||
</Button>
|
||||
</div>
|
||||
<IncDecU8
|
||||
value={recruits_left.get()}
|
||||
value_range={1..0xFF}
|
||||
on_update={on_update}
|
||||
>
|
||||
{" recruits"}
|
||||
</IncDecU8>
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue