apprentice gets power same night
also various cosmetic changes
This commit is contained in:
parent
15a6454ae2
commit
79c8c464b6
|
|
@ -1,4 +1,8 @@
|
|||
use core::{fmt::Display, num::NonZeroU8, ops::Not};
|
||||
use core::{
|
||||
fmt::Display,
|
||||
num::NonZeroU8,
|
||||
ops::{Deref, Not},
|
||||
};
|
||||
|
||||
use rand::seq::SliceRandom;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
@ -272,6 +276,14 @@ impl Character {
|
|||
.collect())
|
||||
}
|
||||
|
||||
/// Returns a copy of this character with their role replaced
|
||||
/// in a read-only type
|
||||
pub fn as_role(&self, role: Role) -> AsCharacter {
|
||||
let mut char = self.clone();
|
||||
char.role = role;
|
||||
AsCharacter(char)
|
||||
}
|
||||
|
||||
pub fn night_action_prompts(&self, village: &Village) -> Result<Box<[ActionPrompt]>> {
|
||||
if self.mason_leader().is_ok() {
|
||||
return self.mason_prompts(village);
|
||||
|
|
@ -834,3 +846,13 @@ impl MasonLeaderMut<'_> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AsCharacter(Character);
|
||||
|
||||
impl Deref for AsCharacter {
|
||||
type Target = Character;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -270,7 +270,31 @@ impl Night {
|
|||
.partial_cmp(right_prompt)
|
||||
.unwrap_or(core::cmp::Ordering::Equal)
|
||||
});
|
||||
let mut action_queue = VecDeque::from(action_queue);
|
||||
|
||||
let mut action_queue = VecDeque::from({
|
||||
// insert actions for role-changed roles
|
||||
let mut expanded_queue = Vec::new();
|
||||
for action in action_queue {
|
||||
match &action {
|
||||
ActionPrompt::RoleChange {
|
||||
character_id,
|
||||
new_role,
|
||||
} => {
|
||||
let char = village.character_by_id(character_id.character_id)?;
|
||||
let as_role = char.as_role(new_role.title_to_role_excl_apprentice());
|
||||
expanded_queue.push(action);
|
||||
for prompt in as_role.night_action_prompts(&village)? {
|
||||
expanded_queue.push(prompt);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
expanded_queue.push(action);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
expanded_queue
|
||||
});
|
||||
|
||||
if night == 0 {
|
||||
action_queue.push_front(ActionPrompt::WolvesIntro {
|
||||
|
|
@ -716,6 +740,39 @@ impl Night {
|
|||
}
|
||||
}
|
||||
|
||||
fn received_response_consecutive_same_player_no_sleep(
|
||||
&self,
|
||||
resp: ActionResponse,
|
||||
) -> Result<ResponseOutcome> {
|
||||
let same_char = self
|
||||
.current_character_id()
|
||||
.and_then(|curr| {
|
||||
self.action_queue
|
||||
.iter()
|
||||
.next()
|
||||
.map(|n| n.character_id() == Some(curr))
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
match (
|
||||
self.received_response_consecutive_wolves_dont_sleep(resp)?,
|
||||
same_char,
|
||||
) {
|
||||
(ResponseOutcome::PromptUpdate(p), _) => Ok(ResponseOutcome::PromptUpdate(p)),
|
||||
(
|
||||
ResponseOutcome::ActionComplete(ActionComplete {
|
||||
result: ActionResult::GoBackToSleep,
|
||||
change,
|
||||
}),
|
||||
true,
|
||||
) => Ok(ResponseOutcome::ActionComplete(ActionComplete {
|
||||
result: ActionResult::Continue,
|
||||
change,
|
||||
})),
|
||||
(act, _) => Ok(act),
|
||||
}
|
||||
}
|
||||
|
||||
fn received_response_consecutive_wolves_dont_sleep(
|
||||
&self,
|
||||
resp: ActionResponse,
|
||||
|
|
@ -775,7 +832,7 @@ impl Night {
|
|||
&self,
|
||||
resp: ActionResponse,
|
||||
) -> Result<BlockResolvedOutcome> {
|
||||
match self.received_response_consecutive_wolves_dont_sleep(resp)? {
|
||||
match self.received_response_consecutive_same_player_no_sleep(resp)? {
|
||||
ResponseOutcome::PromptUpdate(update) => Ok(BlockResolvedOutcome::PromptUpdate(update)),
|
||||
ResponseOutcome::ActionComplete(ActionComplete { result, change }) => {
|
||||
match self
|
||||
|
|
@ -864,36 +921,7 @@ impl Night {
|
|||
current_prompt,
|
||||
current_result: _,
|
||||
..
|
||||
} => match current_prompt {
|
||||
ActionPrompt::Insomniac { character_id, .. }
|
||||
| ActionPrompt::LoneWolfKill { character_id, .. }
|
||||
| ActionPrompt::ElderReveal { character_id }
|
||||
| ActionPrompt::RoleChange { character_id, .. }
|
||||
| ActionPrompt::Seer { character_id, .. }
|
||||
| ActionPrompt::Protector { character_id, .. }
|
||||
| ActionPrompt::Arcanist { character_id, .. }
|
||||
| ActionPrompt::Gravedigger { character_id, .. }
|
||||
| ActionPrompt::Hunter { character_id, .. }
|
||||
| ActionPrompt::Militia { character_id, .. }
|
||||
| ActionPrompt::MapleWolf { character_id, .. }
|
||||
| ActionPrompt::Guardian { character_id, .. }
|
||||
| ActionPrompt::Shapeshifter { character_id }
|
||||
| ActionPrompt::AlphaWolf { character_id, .. }
|
||||
| ActionPrompt::Adjudicator { character_id, .. }
|
||||
| ActionPrompt::PowerSeer { character_id, .. }
|
||||
| ActionPrompt::Mortician { character_id, .. }
|
||||
| ActionPrompt::Beholder { character_id, .. }
|
||||
| ActionPrompt::MasonLeaderRecruit { character_id, .. }
|
||||
| ActionPrompt::Empath { character_id, .. }
|
||||
| ActionPrompt::Vindicator { character_id, .. }
|
||||
| ActionPrompt::PyreMaster { character_id, .. }
|
||||
| ActionPrompt::DireWolf { character_id, .. } => Some(character_id.character_id),
|
||||
|
||||
ActionPrompt::WolvesIntro { wolves: _ }
|
||||
| ActionPrompt::MasonsWake { .. }
|
||||
| ActionPrompt::WolfPackKill { .. }
|
||||
| ActionPrompt::CoverOfDarkness => None,
|
||||
},
|
||||
} => current_prompt.character_id(),
|
||||
NightState::Complete => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,36 +13,32 @@ use crate::{
|
|||
|
||||
type Result<T> = core::result::Result<T, GameError>;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, PartialOrd)]
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, PartialOrd, ChecksAs)]
|
||||
pub enum ActionType {
|
||||
Cover,
|
||||
#[checks("is_wolfy")]
|
||||
WolvesIntro,
|
||||
RoleChange,
|
||||
Protect,
|
||||
#[checks("is_wolfy")]
|
||||
WolfPackKill,
|
||||
Direwolf,
|
||||
#[checks("is_wolfy")]
|
||||
Shapeshifter,
|
||||
#[checks("is_wolfy")]
|
||||
AlphaWolfKill,
|
||||
#[checks("is_wolfy")]
|
||||
OtherWolf,
|
||||
#[checks("is_wolfy")]
|
||||
Direwolf,
|
||||
LoneWolfKill,
|
||||
Block,
|
||||
VillageKill,
|
||||
Intel,
|
||||
Other,
|
||||
MasonRecruit,
|
||||
MasonsWake,
|
||||
Insomniac,
|
||||
Beholder,
|
||||
RoleChange,
|
||||
}
|
||||
|
||||
impl ActionType {
|
||||
const fn is_wolfy(&self) -> bool {
|
||||
// note: Lone Wolf isn't wolfy, as they don't wake with wolves
|
||||
matches!(
|
||||
self,
|
||||
ActionType::Direwolf
|
||||
| ActionType::OtherWolf
|
||||
| ActionType::WolfPackKill
|
||||
| ActionType::WolvesIntro
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, ChecksAs, Titles)]
|
||||
|
|
@ -91,7 +87,7 @@ pub enum ActionPrompt {
|
|||
living_players: Box<[CharacterIdentity]>,
|
||||
marked: Option<CharacterId>,
|
||||
},
|
||||
#[checks(ActionType::Other)]
|
||||
#[checks(ActionType::VillageKill)]
|
||||
Militia {
|
||||
character_id: CharacterIdentity,
|
||||
living_players: Box<[CharacterIdentity]>,
|
||||
|
|
@ -159,7 +155,7 @@ pub enum ActionPrompt {
|
|||
living_players: Box<[CharacterIdentity]>,
|
||||
marked: Option<CharacterId>,
|
||||
},
|
||||
#[checks(ActionType::Other)]
|
||||
#[checks(ActionType::VillageKill)]
|
||||
PyreMaster {
|
||||
character_id: CharacterIdentity,
|
||||
living_players: Box<[CharacterIdentity]>,
|
||||
|
|
@ -171,9 +167,9 @@ pub enum ActionPrompt {
|
|||
living_villagers: Box<[CharacterIdentity]>,
|
||||
marked: Option<CharacterId>,
|
||||
},
|
||||
#[checks(ActionType::OtherWolf)]
|
||||
#[checks(ActionType::Shapeshifter)]
|
||||
Shapeshifter { character_id: CharacterIdentity },
|
||||
#[checks(ActionType::OtherWolf)]
|
||||
#[checks(ActionType::AlphaWolfKill)]
|
||||
AlphaWolf {
|
||||
character_id: CharacterIdentity,
|
||||
living_villagers: Box<[CharacterIdentity]>,
|
||||
|
|
@ -196,6 +192,38 @@ pub enum ActionPrompt {
|
|||
}
|
||||
|
||||
impl ActionPrompt {
|
||||
pub(crate) const fn character_id(&self) -> Option<CharacterId> {
|
||||
match self {
|
||||
ActionPrompt::Insomniac { character_id, .. }
|
||||
| ActionPrompt::LoneWolfKill { character_id, .. }
|
||||
| ActionPrompt::ElderReveal { character_id }
|
||||
| ActionPrompt::RoleChange { character_id, .. }
|
||||
| ActionPrompt::Seer { character_id, .. }
|
||||
| ActionPrompt::Protector { character_id, .. }
|
||||
| ActionPrompt::Arcanist { character_id, .. }
|
||||
| ActionPrompt::Gravedigger { character_id, .. }
|
||||
| ActionPrompt::Hunter { character_id, .. }
|
||||
| ActionPrompt::Militia { character_id, .. }
|
||||
| ActionPrompt::MapleWolf { character_id, .. }
|
||||
| ActionPrompt::Guardian { character_id, .. }
|
||||
| ActionPrompt::Shapeshifter { character_id }
|
||||
| ActionPrompt::AlphaWolf { character_id, .. }
|
||||
| ActionPrompt::Adjudicator { character_id, .. }
|
||||
| ActionPrompt::PowerSeer { character_id, .. }
|
||||
| ActionPrompt::Mortician { character_id, .. }
|
||||
| ActionPrompt::Beholder { character_id, .. }
|
||||
| ActionPrompt::MasonLeaderRecruit { character_id, .. }
|
||||
| ActionPrompt::Empath { character_id, .. }
|
||||
| ActionPrompt::Vindicator { character_id, .. }
|
||||
| ActionPrompt::PyreMaster { character_id, .. }
|
||||
| ActionPrompt::DireWolf { character_id, .. } => Some(character_id.character_id),
|
||||
|
||||
ActionPrompt::WolvesIntro { .. }
|
||||
| ActionPrompt::MasonsWake { .. }
|
||||
| ActionPrompt::WolfPackKill { .. }
|
||||
| ActionPrompt::CoverOfDarkness => None,
|
||||
}
|
||||
}
|
||||
pub(crate) fn matches_beholding(&self, target: CharacterId) -> bool {
|
||||
match self {
|
||||
ActionPrompt::Insomniac { character_id, .. }
|
||||
|
|
|
|||
|
|
@ -219,7 +219,6 @@ pub enum Role {
|
|||
#[checks(Alignment::Village)]
|
||||
#[checks(Powerful::Powerful)]
|
||||
#[checks(Killer::NotKiller)]
|
||||
#[checks("is_mentor")]
|
||||
Elder {
|
||||
knows_on_night: NonZeroU8,
|
||||
woken_for_reveal: bool,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="81.560997mm"
|
||||
height="48.303188mm"
|
||||
viewBox="0 0 81.560997 48.303188"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1" /><g
|
||||
id="layer4"
|
||||
transform="translate(-50.121599,-612.75354)"><g
|
||||
id="g9"><rect
|
||||
style="fill:#3c34ff;fill-opacity:1;stroke:#0f07ff;stroke-width:1.561;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect6"
|
||||
width="80"
|
||||
height="20"
|
||||
x="50.902103"
|
||||
y="613.53406" /><rect
|
||||
style="fill:#3c34ff;fill-opacity:1;stroke:#0f07ff;stroke-width:1.561;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect6-1"
|
||||
width="80"
|
||||
height="20"
|
||||
x="50.902103"
|
||||
y="640.27625" /></g></g></svg>
|
||||
|
After Width: | Height: | Size: 932 B |
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="81.560997mm"
|
||||
height="79.98938mm"
|
||||
viewBox="0 0 81.560997 79.98938"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1" /><g
|
||||
id="layer4"
|
||||
transform="translate(-50.121599,-596.91049)"><g
|
||||
id="g9"><rect
|
||||
style="fill:#3c34ff;fill-opacity:1;stroke:#0f07ff;stroke-width:1.561;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect6"
|
||||
width="80"
|
||||
height="20"
|
||||
x="50.902103"
|
||||
y="613.53406" /><rect
|
||||
style="fill:#3c34ff;fill-opacity:1;stroke:#0f07ff;stroke-width:1.561;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect6-1"
|
||||
width="80"
|
||||
height="20"
|
||||
x="50.902103"
|
||||
y="640.27625" /></g><rect
|
||||
style="fill:#ff0707;fill-opacity:1;stroke:#c10000;stroke-width:1.561;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect6-3"
|
||||
width="100"
|
||||
height="10"
|
||||
x="-436.08246"
|
||||
y="509.63745"
|
||||
transform="rotate(-45)" /></g></svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="87.060303mm"
|
||||
height="87.060318mm"
|
||||
viewBox="0 0 87.060303 87.060318"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1" /><g
|
||||
id="layer4"
|
||||
transform="translate(-207.43333,-614.36255)"><path
|
||||
id="rect6-3-3"
|
||||
style="fill:#ff0707;fill-opacity:1;stroke:#c10000;stroke-width:1.561;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m -277.74226,592.65854 h -20.00022 v 39.9997 h -39.99971 v 20.00022 h 39.99971 v 39.9997 h 20.00022 v -39.9997 h 39.9997 v -20.00022 h -39.9997 z"
|
||||
transform="rotate(-45)" /></g></svg>
|
||||
|
After Width: | Height: | Size: 776 B |
|
|
@ -102,7 +102,7 @@ app {
|
|||
left: 0;
|
||||
top: 0;
|
||||
margin: 0;
|
||||
font-size: 2rem;
|
||||
font-size: 2.7vw;
|
||||
}
|
||||
|
||||
$link_color: #432054;
|
||||
|
|
@ -383,16 +383,38 @@ button {
|
|||
}
|
||||
|
||||
.identity {
|
||||
font-size: 1.5em;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.day-char {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
// min-width: 1vw;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.red {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.character {
|
||||
text-align: center;
|
||||
border: 3px solid rgba(0, 0, 0, 0.4);
|
||||
// min-width: 20%;
|
||||
flex-shrink: 1;
|
||||
|
||||
.headline {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
overflow: hidden;
|
||||
gap: 5px;
|
||||
|
||||
}
|
||||
|
||||
.role {
|
||||
font-size: 1.5rem;
|
||||
|
||||
|
|
@ -881,6 +903,7 @@ error {
|
|||
.binary {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 1.5vw;
|
||||
|
||||
.button-container {
|
||||
text-align: center;
|
||||
|
|
@ -1281,7 +1304,7 @@ input {
|
|||
|
||||
.setup-screen {
|
||||
margin-top: 2%;
|
||||
font-size: 1rem;
|
||||
font-size: 1.5vw;
|
||||
|
||||
.setup {
|
||||
display: flex;
|
||||
|
|
@ -1341,6 +1364,7 @@ input {
|
|||
filter: saturate(40%);
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
font-weight: bolder;
|
||||
|
||||
&.wakes {
|
||||
border: 2px solid yellow;
|
||||
|
|
@ -1361,7 +1385,8 @@ input {
|
|||
}
|
||||
|
||||
.inactive {
|
||||
filter: grayscale(100%) brightness(30%);
|
||||
// filter: grayscale(100%) brightness(30%);
|
||||
filter: brightness(0%);
|
||||
}
|
||||
|
||||
.qrcode {
|
||||
|
|
@ -1383,6 +1408,7 @@ input {
|
|||
}
|
||||
|
||||
.details {
|
||||
font-size: 5vw;
|
||||
// height: 100%;
|
||||
// width: 100%;
|
||||
border: 1px solid $village_border;
|
||||
|
|
@ -1485,12 +1511,17 @@ input {
|
|||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
&.full-height {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
& input {
|
||||
height: 2rem;
|
||||
text-align: center;
|
||||
|
||||
&#number {
|
||||
#number {
|
||||
font-size: 2rem;
|
||||
max-width: 50vw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1724,10 +1755,11 @@ input {
|
|||
h1 {
|
||||
text-align: center;
|
||||
// align-self: flex-start;
|
||||
font-size: 4vw;
|
||||
}
|
||||
|
||||
.information {
|
||||
font-size: 1.2em;
|
||||
font-size: 1.2rem;
|
||||
padding-left: 5%;
|
||||
padding-right: 5%;
|
||||
}
|
||||
|
|
@ -1764,7 +1796,7 @@ input {
|
|||
gap: 10px;
|
||||
|
||||
&.masons {
|
||||
font-size: 2em;
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -459,13 +459,17 @@ impl Component for Host {
|
|||
<Button on_click={to_normal}>{"small screen"}</Button>
|
||||
}
|
||||
} else {
|
||||
let to_big = Callback::from(|_| {
|
||||
if let Some(loc) = gloo::utils::document().location() {
|
||||
let _ = loc.replace("/host/big");
|
||||
}
|
||||
});
|
||||
// let to_big = Callback::from(|_| {
|
||||
// if let Some(loc) = gloo::utils::document().location() {
|
||||
// let _ = loc.replace("/host/big");
|
||||
// }
|
||||
// });
|
||||
html! {
|
||||
<Button on_click={to_big}>{"big screen 📺"}</Button>
|
||||
<a href="/host/big">
|
||||
<Button on_click={Callback::default()}>
|
||||
{"big screen 📺"}
|
||||
</Button>
|
||||
</a>
|
||||
}
|
||||
};
|
||||
let story_on_click = if let HostState::Story { .. } = &self.state {
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ pub fn Signin(props: &SigninProps) -> Html {
|
|||
|
||||
let on_change = crate::components::input_element_number_oninput(num_value);
|
||||
html! {
|
||||
<div class="signin">
|
||||
<div class="signin full-height">
|
||||
<div class="column-list">
|
||||
<label for="name">{"Name"}</label>
|
||||
<input oninput={name_on_input} name="name" id="name" type="text"/>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use core::{num::NonZeroU8, ops::Not};
|
||||
|
||||
use convert_case::{Case, Casing};
|
||||
use werewolves_proto::{
|
||||
character::CharacterId,
|
||||
game::GameTime,
|
||||
|
|
@ -7,7 +8,10 @@ use werewolves_proto::{
|
|||
};
|
||||
use yew::prelude::*;
|
||||
|
||||
use crate::components::{Button, Identity};
|
||||
use crate::components::{
|
||||
AssociatedIcon, Button, Icon, IconType, Identity, PartialAssociatedIcon,
|
||||
attributes::RoleTitleSpan,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||
pub struct DaytimePlayerListProps {
|
||||
|
|
@ -115,7 +119,7 @@ pub fn DaytimePlayer(
|
|||
character:
|
||||
CharacterState {
|
||||
player_id: _,
|
||||
role: _,
|
||||
role,
|
||||
died_to,
|
||||
identity,
|
||||
},
|
||||
|
|
@ -133,9 +137,18 @@ pub fn DaytimePlayer(
|
|||
)
|
||||
.unwrap_or_default();
|
||||
let identity: PublicIdentity = identity.into();
|
||||
let icon = role.icon().unwrap_or_else(|| role.alignment().icon());
|
||||
let text = role.to_string().to_case(Case::Title);
|
||||
let align_class = role.wolf().then_some("red");
|
||||
html! {
|
||||
<Button on_click={on_click} classes={classes!(class, "character")}>
|
||||
<Identity ident={identity}/>
|
||||
<div class="day-char">
|
||||
<span class={classes!("headline")}>
|
||||
<Icon source={icon} icon_type={IconType::Small}/>
|
||||
<span class={classes!(align_class)}>{text}</span>
|
||||
</span>
|
||||
<Identity ident={identity}/>
|
||||
</div>
|
||||
</Button>
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use yew::prelude::*;
|
|||
|
||||
macro_rules! decl_icon {
|
||||
($($name:ident: $path:literal,)*) => {
|
||||
#[allow(unused)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum IconSource {
|
||||
$(
|
||||
|
|
@ -58,6 +59,9 @@ decl_icon!(
|
|||
Insomniac: "/img/insomniac.svg",
|
||||
BlackKnight: "/img/black-knight.svg",
|
||||
Mason: "/img/mason.svg",
|
||||
NotEqual: "/img/not-equal.svg",
|
||||
Equal: "/img/equal.svg",
|
||||
RedX: "/img/red-x.svg",
|
||||
);
|
||||
|
||||
impl IconSource {
|
||||
|
|
|
|||
|
|
@ -33,16 +33,26 @@ pub fn AdjudicatorResult(AdjudicatorResultProps { killer }: &AdjudicatorResultPr
|
|||
Killer::Killer => "IS A KILLER",
|
||||
Killer::NotKiller => "IS NOT A KILLER",
|
||||
};
|
||||
let icon = match killer {
|
||||
Killer::Killer => html! {
|
||||
<Icon
|
||||
source={IconSource::Killer}
|
||||
icon_type={IconType::Informational}
|
||||
/>
|
||||
},
|
||||
Killer::NotKiller => html! {
|
||||
<Icon
|
||||
source={IconSource::RedX}
|
||||
icon_type={IconType::Informational}
|
||||
/>
|
||||
},
|
||||
};
|
||||
html! {
|
||||
<div class="role-page">
|
||||
<h1 class="defensive">{"ADJUDICATOR"}</h1>
|
||||
<div class="information defensive faint">
|
||||
<h2>{"YOUR TARGET"}</h2>
|
||||
<h4><Icon
|
||||
source={IconSource::Killer}
|
||||
icon_type={IconType::Informational}
|
||||
inactive={killer.killer().not()}
|
||||
/></h4>
|
||||
<h4>{icon}</h4>
|
||||
<h3 class="yellow">{text}</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ pub fn ArcanistPage1() -> Html {
|
|||
<h2>{"PICK TWO PLAYERS"}</h2>
|
||||
<h4 class="icons">
|
||||
<Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
||||
<Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
||||
<Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
||||
// <Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
||||
// <Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
||||
<Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
||||
</h4>
|
||||
<h3 class="yellow">{"YOU WILL CHECK IF THEIR ALIGNMENTS ARE THE SAME OR DIFFERENT"}</h3>
|
||||
|
|
@ -36,20 +36,21 @@ pub fn ArcanistResult(ArcanistResultProps { alignment_eq }: &ArcanistResultProps
|
|||
let icons = match alignment_eq {
|
||||
AlignmentEq::Same => html! {
|
||||
<>
|
||||
<Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
||||
<Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
||||
<span>{"OR"}</span>
|
||||
<Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
||||
<Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
||||
// <Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
||||
// <Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
||||
// <span>{"OR"}</span>
|
||||
// <Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
||||
// <Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
||||
<Icon source={IconSource::Equal} icon_type={IconType::Informational} />
|
||||
</>
|
||||
},
|
||||
AlignmentEq::Different => html! {
|
||||
<>
|
||||
<Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
||||
<Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
||||
{"OR"}
|
||||
<Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
||||
<Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
||||
// {"OR"}
|
||||
// <Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
||||
// <Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
||||
</>
|
||||
},
|
||||
};
|
||||
|
|
@ -61,7 +62,7 @@ pub fn ArcanistResult(ArcanistResultProps { alignment_eq }: &ArcanistResultProps
|
|||
<h4 class="icons">
|
||||
{icons}
|
||||
</h4>
|
||||
<h3 class="yellow">{text}</h3>
|
||||
<h1 class="yellow">{text}</h1>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,18 +33,26 @@ pub fn PowerSeerResult(PowerSeerResultProps { powerful }: &PowerSeerResultProps)
|
|||
Powerful::Powerful => "POWERFUL",
|
||||
Powerful::NotPowerful => "NOT POWERFUL",
|
||||
};
|
||||
let icon = match powerful {
|
||||
Powerful::Powerful => html! {
|
||||
<Icon
|
||||
source={IconSource::Powerful}
|
||||
icon_type={IconType::Informational}
|
||||
/>
|
||||
},
|
||||
Powerful::NotPowerful => html! {
|
||||
<Icon
|
||||
source={IconSource::RedX}
|
||||
icon_type={IconType::Informational}
|
||||
/>
|
||||
},
|
||||
};
|
||||
html! {
|
||||
<div class="role-page">
|
||||
<h1 class="intel">{"POWER SEER"}</h1>
|
||||
<div class="information intel faint">
|
||||
<h2>{"YOUR TARGET APPEARS AS"}</h2>
|
||||
<h4>
|
||||
<Icon
|
||||
source={powerful.icon()}
|
||||
icon_type={IconType::Informational}
|
||||
inactive={powerful.powerful().not()}
|
||||
/>
|
||||
</h4>
|
||||
<h4>{icon}</h4>
|
||||
<h3 class="yellow">{text}</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue