seer false positives, player list styling
This commit is contained in:
parent
cb69649fe4
commit
eaaf0ab2b7
|
|
@ -404,12 +404,40 @@ impl Role {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl RoleTitle {
|
||||||
|
pub fn falsely_appear_village() -> Box<[RoleTitle]> {
|
||||||
|
Self::ALL
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.filter(|r| r.wolf() && r.alignment().village())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn falsely_appear_wolf() -> Box<[RoleTitle]> {
|
||||||
|
Self::ALL
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.filter(|r| !r.wolf() && r.alignment().wolves())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
|
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
|
||||||
pub enum Alignment {
|
pub enum Alignment {
|
||||||
Village,
|
Village,
|
||||||
Wolves,
|
Wolves,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Alignment {
|
||||||
|
pub const fn village(&self) -> bool {
|
||||||
|
matches!(self, Alignment::Village)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn wolves(&self) -> bool {
|
||||||
|
matches!(self, Alignment::Wolves)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for Alignment {
|
impl Display for Alignment {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,32 @@ nav.debug-nav {
|
||||||
}
|
}
|
||||||
|
|
||||||
.player-list {
|
.player-list {
|
||||||
|
padding-bottom: 20px;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
gap: 10px;
|
||||||
|
justify-items: center;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
|
||||||
|
.targets {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
align-content: center;
|
||||||
|
gap: 10px;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
|
||||||
|
&>* {
|
||||||
|
// min-width: 15vw;
|
||||||
|
// min-height: 12vh;
|
||||||
|
// font-size: 3em;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.lobby-player-list {
|
||||||
padding-bottom: 80px;
|
padding-bottom: 80px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
@ -341,22 +367,28 @@ button {
|
||||||
}
|
}
|
||||||
|
|
||||||
.wolves-intro {
|
.wolves-intro {
|
||||||
@extend .column-list;
|
|
||||||
align-content: center;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.wolves-list {
|
|
||||||
flex-wrap: wrap;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: space-evenly;
|
|
||||||
flex: 1 1 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
& button {
|
& button {
|
||||||
align-self: center;
|
align-self: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wolves-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
min-height: 70vh;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&>* {
|
||||||
|
height: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.identity {
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.character {
|
.character {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border: 3px solid rgba(0, 0, 0, 0.4);
|
border: 3px solid rgba(0, 0, 0, 0.4);
|
||||||
|
|
@ -386,7 +418,8 @@ button {
|
||||||
h1,
|
h1,
|
||||||
h2,
|
h2,
|
||||||
h3,
|
h3,
|
||||||
h4 {
|
h4,
|
||||||
|
h5 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -702,18 +735,25 @@ clients {
|
||||||
padding-bottom: 5px;
|
padding-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.box {
|
@media only screen and (max-width : 1899px) {
|
||||||
border: solid 3px;
|
|
||||||
border-color: #432054;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
margin-left: 5vw;
|
margin-left: 5vw;
|
||||||
margin-right: 5vw;
|
margin-right: 5vw;
|
||||||
margin-top: 30px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-basis: content;
|
flex-basis: content;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width : 1900px) {
|
||||||
|
.content {
|
||||||
|
margin-left: 5vw;
|
||||||
|
margin-right: 5vw;
|
||||||
|
display: flex;
|
||||||
|
flex-basis: content;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.sp-ace {
|
.sp-ace {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
|
|
@ -948,22 +988,13 @@ input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: white;
|
color: white;
|
||||||
height: 90vh;
|
height: 100%;
|
||||||
|
justify-content: center;
|
||||||
$marked_bg: color.change($wolves_color, $alpha: 0.3);
|
$marked_bg: color.change($wolves_color, $alpha: 0.3);
|
||||||
$marked_border: color.change($wolves_color, $alpha: 1.0);
|
$marked_border: color.change($wolves_color, $alpha: 1.0);
|
||||||
$village_bg: color.change($village_color, $alpha: 0.3);
|
$village_bg: color.change($village_color, $alpha: 0.3);
|
||||||
$village_border: color.change($village_color, $alpha: 1.0);
|
$village_border: color.change($village_color, $alpha: 1.0);
|
||||||
|
|
||||||
.targets {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: space-evenly;
|
|
||||||
align-items: center;
|
|
||||||
flex-grow: 1;
|
|
||||||
align-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.character {
|
.character {
|
||||||
padding: 0.5cm;
|
padding: 0.5cm;
|
||||||
|
|
||||||
|
|
@ -1688,3 +1719,43 @@ input {
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.two-column {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 3fr 2fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.role-title-span {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 100fr;
|
||||||
|
max-height: 2rem;
|
||||||
|
width: fit-content;
|
||||||
|
|
||||||
|
|
||||||
|
padding-top: 5px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 10px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
max-height: 2rem;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.false-positives {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-bound {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -472,13 +472,17 @@ impl Component for Host {
|
||||||
<Button on_click={to_big}>{"big screen 📺"}</Button>
|
<Button on_click={to_big}>{"big screen 📺"}</Button>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let story_on_click = if let HostState::Story { .. } = &self.state {
|
||||||
|
crate::callback::send_message(HostMessage::GetState, self.send.clone())
|
||||||
|
} else {
|
||||||
let s = _ctx.link().clone();
|
let s = _ctx.link().clone();
|
||||||
let story_on_click = Callback::from(move |_| {
|
Callback::from(move |_| {
|
||||||
s.send_message(HostEvent::SetState(HostState::Story {
|
s.send_message(HostEvent::SetState(HostState::Story {
|
||||||
story: crate::clients::host::story_test::test_story(),
|
story: crate::clients::host::story_test::test_story(),
|
||||||
page: 0,
|
page: 0,
|
||||||
}));
|
}));
|
||||||
});
|
})
|
||||||
|
};
|
||||||
html! {
|
html! {
|
||||||
<nav class="debug-nav" style="z-index: 3;">
|
<nav class="debug-nav" style="z-index: 3;">
|
||||||
<Button on_click={on_error_click}>{"error"}</Button>
|
<Button on_click={on_error_click}>{"error"}</Button>
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@ pub fn WolvesIntro(props: &WolvesIntroProps) -> Html {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
html! {
|
html! {
|
||||||
<div class="wolves-intro">
|
<div class="role-page wolves-intro">
|
||||||
<h2>{"these are the wolves:"}</h2>
|
<h1 class="wolves">{"THESE ARE THE WOLVES"}</h1>
|
||||||
<div class="row-list wolves-list">
|
<div class="wolves-list">
|
||||||
{
|
{
|
||||||
props.wolves.iter().map(|w| html!{
|
props.wolves.iter().map(|w| html!{
|
||||||
<div class="character wolves faint">
|
<div class="character wolves faint">
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
use werewolves_proto::{game::Category, role};
|
use convert_case::{Case, Casing};
|
||||||
|
use werewolves_proto::{
|
||||||
|
game::{Category, SetupRole},
|
||||||
|
role::{self, RoleTitle},
|
||||||
|
};
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{AssociatedIcon, Icon, IconSource, IconType};
|
use crate::components::{AssociatedIcon, Icon, IconSource, IconType, PartialAssociatedIcon};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
||||||
pub struct AlignmentSpanProps {
|
pub struct AlignmentSpanProps {
|
||||||
|
|
@ -59,3 +63,21 @@ pub fn CategorySpan(
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
||||||
|
pub struct RoleTitleSpanProps {
|
||||||
|
pub role: RoleTitle,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn RoleTitleSpan(RoleTitleSpanProps { role }: &RoleTitleSpanProps) -> Html {
|
||||||
|
let class = Into::<SetupRole>::into(*role).category().class();
|
||||||
|
let icon = role.icon().unwrap_or(role.alignment().icon());
|
||||||
|
let text = role.to_string().to_case(Case::Title);
|
||||||
|
html! {
|
||||||
|
<span class={classes!("role-title-span", "faint", class)}>
|
||||||
|
<Icon source={icon} icon_type={IconType::List}/>
|
||||||
|
<span>{text}</span>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ impl IconSource {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||||
pub enum IconType {
|
pub enum IconType {
|
||||||
|
List,
|
||||||
Small,
|
Small,
|
||||||
Informational,
|
Informational,
|
||||||
#[default]
|
#[default]
|
||||||
|
|
@ -69,6 +70,7 @@ pub enum IconType {
|
||||||
impl IconType {
|
impl IconType {
|
||||||
pub const fn class(&self) -> &'static str {
|
pub const fn class(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
|
IconType::List => "icon-in-list",
|
||||||
IconType::Small => "icon",
|
IconType::Small => "icon",
|
||||||
IconType::Informational => "icon-info",
|
IconType::Informational => "icon-info",
|
||||||
IconType::RoleCheck => "check-icon",
|
IconType::RoleCheck => "check-icon",
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ pub fn Lobby(LobbyProps { players, on_action }: &LobbyProps) -> Html {
|
||||||
html! {
|
html! {
|
||||||
<div class="column-list">
|
<div class="column-list">
|
||||||
<p style="text-align: center;">{format!("Players in lobby: {}", players.len())}</p>
|
<p style="text-align: center;">{format!("Players in lobby: {}", players.len())}</p>
|
||||||
<div class="player-list">
|
<div class="lobby-player-list">
|
||||||
{
|
{
|
||||||
players
|
players
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
use werewolves_proto::role::Alignment;
|
use werewolves_proto::role::{Alignment, RoleTitle};
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{AssociatedIcon, Icon, IconSource, IconType};
|
use crate::components::{
|
||||||
|
AssociatedIcon, Icon, IconSource, IconType, PartialAssociatedIcon, attributes::RoleTitleSpan,
|
||||||
|
};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn SeerPage1() -> Html {
|
pub fn SeerPage1() -> Html {
|
||||||
|
|
@ -31,10 +33,23 @@ pub fn SeerResult(SeerResultProps { alignment }: &SeerResultProps) -> Html {
|
||||||
Alignment::Village => "VILLAGE",
|
Alignment::Village => "VILLAGE",
|
||||||
Alignment::Wolves => "WOLFPACK",
|
Alignment::Wolves => "WOLFPACK",
|
||||||
};
|
};
|
||||||
|
let false_positives = match alignment {
|
||||||
|
Alignment::Village => RoleTitle::falsely_appear_village(),
|
||||||
|
Alignment::Wolves => RoleTitle::falsely_appear_wolf(),
|
||||||
|
}
|
||||||
|
.into_iter()
|
||||||
|
.map(|role| {
|
||||||
|
html! {
|
||||||
|
<RoleTitleSpan role={role}/>
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Html>();
|
||||||
html! {
|
html! {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="intel">{"SEER"}</h1>
|
<h1 class="intel">{"SEER"}</h1>
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
|
<div class="two-column">
|
||||||
|
<div>
|
||||||
<h2>{"YOUR TARGET APPEARS AS"}</h2>
|
<h2>{"YOUR TARGET APPEARS AS"}</h2>
|
||||||
<h4>
|
<h4>
|
||||||
<Icon
|
<Icon
|
||||||
|
|
@ -44,6 +59,17 @@ pub fn SeerResult(SeerResultProps { alignment }: &SeerResultProps) -> Html {
|
||||||
</h4>
|
</h4>
|
||||||
<h3 class="yellow">{text}</h3>
|
<h3 class="yellow">{text}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="bottom-bound">
|
||||||
|
<h5>
|
||||||
|
{"ROLES THAT FALSELY APPEAR AS "}
|
||||||
|
<span class="yellow">{text}</span>
|
||||||
|
</h5>
|
||||||
|
<div class="false-positives yellow">
|
||||||
|
{false_positives}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue