show targets for intel results
This commit is contained in:
parent
251d72e2a0
commit
e536edfc28
|
|
@ -192,9 +192,10 @@ impl Night {
|
||||||
marked: Some(marked),
|
marked: Some(marked),
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let alignment = self.character_with_current_auras(*marked)?.alignment();
|
let target = self.character_with_current_auras(*marked)?;
|
||||||
|
let alignment = target.alignment();
|
||||||
Ok(ResponseOutcome::ActionComplete(ActionComplete {
|
Ok(ResponseOutcome::ActionComplete(ActionComplete {
|
||||||
result: ActionResult::Seer(alignment),
|
result: ActionResult::Seer(target.identity(), alignment),
|
||||||
change: None,
|
change: None,
|
||||||
secondary_changes: vec![],
|
secondary_changes: vec![],
|
||||||
}))
|
}))
|
||||||
|
|
@ -217,11 +218,15 @@ impl Night {
|
||||||
marked: (Some(marked1), Some(marked2)),
|
marked: (Some(marked1), Some(marked2)),
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let same = self.character_with_current_auras(*marked1)?.alignment()
|
let target1 = self.character_with_current_auras(*marked1)?;
|
||||||
== self.character_with_current_auras(*marked2)?.alignment();
|
let target2 = self.character_with_current_auras(*marked2)?;
|
||||||
|
let same = target1.alignment() == target2.alignment();
|
||||||
|
|
||||||
Ok(ResponseOutcome::ActionComplete(ActionComplete {
|
Ok(ResponseOutcome::ActionComplete(ActionComplete {
|
||||||
result: ActionResult::Arcanist(AlignmentEq::new(same)),
|
result: ActionResult::Arcanist(
|
||||||
|
(target1.identity(), target2.identity()),
|
||||||
|
AlignmentEq::new(same),
|
||||||
|
),
|
||||||
change: None,
|
change: None,
|
||||||
secondary_changes: vec![],
|
secondary_changes: vec![],
|
||||||
}))
|
}))
|
||||||
|
|
@ -234,7 +239,10 @@ impl Night {
|
||||||
.character_with_current_auras(*marked)?
|
.character_with_current_auras(*marked)?
|
||||||
.gravedigger_dig();
|
.gravedigger_dig();
|
||||||
Ok(ResponseOutcome::ActionComplete(ActionComplete {
|
Ok(ResponseOutcome::ActionComplete(ActionComplete {
|
||||||
result: ActionResult::GraveDigger(dig_role),
|
result: ActionResult::GraveDigger(
|
||||||
|
self.village.character_by_id(*marked)?.identity(),
|
||||||
|
dig_role,
|
||||||
|
),
|
||||||
change: None,
|
change: None,
|
||||||
secondary_changes: vec![],
|
secondary_changes: vec![],
|
||||||
}))
|
}))
|
||||||
|
|
@ -423,6 +431,7 @@ impl Night {
|
||||||
..
|
..
|
||||||
} => Ok(ActionComplete {
|
} => Ok(ActionComplete {
|
||||||
result: ActionResult::Adjudicator {
|
result: ActionResult::Adjudicator {
|
||||||
|
target: self.village.character_by_id(*marked)?.identity(),
|
||||||
killer: self.character_with_current_auras(*marked)?.killer(),
|
killer: self.character_with_current_auras(*marked)?.killer(),
|
||||||
},
|
},
|
||||||
change: None,
|
change: None,
|
||||||
|
|
@ -434,6 +443,7 @@ impl Night {
|
||||||
..
|
..
|
||||||
} => Ok(ActionComplete {
|
} => Ok(ActionComplete {
|
||||||
result: ActionResult::PowerSeer {
|
result: ActionResult::PowerSeer {
|
||||||
|
target: self.village.character_by_id(*marked)?.identity(),
|
||||||
powerful: self.character_with_current_auras(*marked)?.powerful(),
|
powerful: self.character_with_current_auras(*marked)?.powerful(),
|
||||||
},
|
},
|
||||||
change: None,
|
change: None,
|
||||||
|
|
@ -445,6 +455,7 @@ impl Night {
|
||||||
..
|
..
|
||||||
} => Ok(ActionComplete {
|
} => Ok(ActionComplete {
|
||||||
result: ActionResult::Mortician(
|
result: ActionResult::Mortician(
|
||||||
|
self.village.character_by_id(*marked)?.identity(),
|
||||||
self.village
|
self.village
|
||||||
.character_by_id(*marked)?
|
.character_by_id(*marked)?
|
||||||
.died_to()
|
.died_to()
|
||||||
|
|
@ -507,7 +518,10 @@ impl Night {
|
||||||
let scapegoat = marked.role_title() == RoleTitle::Scapegoat || is_scapegoat_aura;
|
let scapegoat = marked.role_title() == RoleTitle::Scapegoat || is_scapegoat_aura;
|
||||||
|
|
||||||
Ok(ActionComplete {
|
Ok(ActionComplete {
|
||||||
result: ActionResult::Empath { scapegoat },
|
result: ActionResult::Empath {
|
||||||
|
target: marked.identity(),
|
||||||
|
scapegoat,
|
||||||
|
},
|
||||||
change: scapegoat.then(|| NightChange::EmpathFoundScapegoat {
|
change: scapegoat.then(|| NightChange::EmpathFoundScapegoat {
|
||||||
empath: character_id.character_id,
|
empath: character_id.character_id,
|
||||||
scapegoat: marked.character_id(),
|
scapegoat: marked.character_id(),
|
||||||
|
|
@ -658,36 +672,35 @@ impl Night {
|
||||||
}
|
}
|
||||||
Aura::InevitableScapegoat => {
|
Aura::InevitableScapegoat => {
|
||||||
match &act.result {
|
match &act.result {
|
||||||
ActionResult::Adjudicator { .. } => {
|
ActionResult::Adjudicator { target, .. } => {
|
||||||
act.result = ActionResult::Adjudicator {
|
act.result = ActionResult::Adjudicator {
|
||||||
|
target: target.clone(),
|
||||||
killer: Killer::Killer,
|
killer: Killer::Killer,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
ActionResult::PowerSeer { .. } => {
|
ActionResult::PowerSeer { target, .. } => {
|
||||||
act.result = ActionResult::PowerSeer {
|
act.result = ActionResult::PowerSeer {
|
||||||
|
target: target.clone(),
|
||||||
powerful: Powerful::Powerful,
|
powerful: Powerful::Powerful,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionResult::Arcanist(_) => {
|
ActionResult::Arcanist((t1, t2), _) => {
|
||||||
let (_, target2) = self
|
let target2 = self.village.character_by_id(t2.character_id)?;
|
||||||
.current_prompt()
|
|
||||||
.ok_or(GameError::NoCurrentPromptForAura)?
|
let target2_align = target2.alignment();
|
||||||
.0
|
|
||||||
.marked()
|
|
||||||
.ok_or(GameError::MustSelectTarget)?;
|
|
||||||
let target2_align = self
|
|
||||||
.village
|
|
||||||
.character_by_id(target2.ok_or(GameError::MustSelectTarget)?)?
|
|
||||||
.alignment();
|
|
||||||
let target1_align = Alignment::Wolves;
|
let target1_align = Alignment::Wolves;
|
||||||
act.result =
|
act.result = ActionResult::Arcanist(
|
||||||
ActionResult::Arcanist(if target1_align == target2_align {
|
(t1.clone(), t2.clone()),
|
||||||
|
if target1_align == target2_align {
|
||||||
AlignmentEq::Same
|
AlignmentEq::Same
|
||||||
} else {
|
} else {
|
||||||
AlignmentEq::Different
|
AlignmentEq::Different
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ActionResult::Seer(target, _) => {
|
||||||
|
act.result = ActionResult::Seer(target.clone(), Alignment::Wolves)
|
||||||
}
|
}
|
||||||
ActionResult::Seer(_) => act.result = ActionResult::Seer(Alignment::Wolves),
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
if let Some((marked, _)) = self
|
if let Some((marked, _)) = self
|
||||||
|
|
|
||||||
|
|
@ -79,14 +79,25 @@ impl NightChoice {
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum StoryActionResult {
|
pub enum StoryActionResult {
|
||||||
RoleBlocked,
|
RoleBlocked,
|
||||||
Seer(Alignment),
|
Seer(CharacterId, Alignment),
|
||||||
PowerSeer { powerful: Powerful },
|
PowerSeer {
|
||||||
Adjudicator { killer: Killer },
|
target: CharacterId,
|
||||||
Arcanist(AlignmentEq),
|
powerful: Powerful,
|
||||||
GraveDigger(Option<RoleTitle>),
|
},
|
||||||
Mortician(DiedToTitle),
|
Adjudicator {
|
||||||
Insomniac { visits: Box<[CharacterId]> },
|
target: CharacterId,
|
||||||
Empath { scapegoat: bool },
|
killer: Killer,
|
||||||
|
},
|
||||||
|
Arcanist((CharacterId, CharacterId), AlignmentEq),
|
||||||
|
GraveDigger(CharacterId, Option<RoleTitle>),
|
||||||
|
Mortician(CharacterId, DiedToTitle),
|
||||||
|
Insomniac {
|
||||||
|
visits: Box<[CharacterId]>,
|
||||||
|
},
|
||||||
|
Empath {
|
||||||
|
target: CharacterId,
|
||||||
|
scapegoat: bool,
|
||||||
|
},
|
||||||
BeholderSawNothing,
|
BeholderSawNothing,
|
||||||
BeholderSawEverything,
|
BeholderSawEverything,
|
||||||
Drunk,
|
Drunk,
|
||||||
|
|
@ -101,16 +112,31 @@ impl StoryActionResult {
|
||||||
ActionResult::BeholderSawEverything => Self::BeholderSawEverything,
|
ActionResult::BeholderSawEverything => Self::BeholderSawEverything,
|
||||||
ActionResult::Drunk => Self::Drunk,
|
ActionResult::Drunk => Self::Drunk,
|
||||||
ActionResult::RoleBlocked => Self::RoleBlocked,
|
ActionResult::RoleBlocked => Self::RoleBlocked,
|
||||||
ActionResult::Seer(alignment) => Self::Seer(alignment),
|
ActionResult::Seer(target, alignment) => Self::Seer(target.character_id, alignment),
|
||||||
ActionResult::PowerSeer { powerful } => Self::PowerSeer { powerful },
|
ActionResult::PowerSeer { target, powerful } => Self::PowerSeer {
|
||||||
ActionResult::Adjudicator { killer } => Self::Adjudicator { killer },
|
powerful,
|
||||||
ActionResult::Arcanist(same) => Self::Arcanist(same),
|
target: target.character_id,
|
||||||
ActionResult::GraveDigger(role_title) => Self::GraveDigger(role_title),
|
},
|
||||||
ActionResult::Mortician(died_to) => Self::Mortician(died_to),
|
ActionResult::Adjudicator { target, killer } => Self::Adjudicator {
|
||||||
|
killer,
|
||||||
|
target: target.character_id,
|
||||||
|
},
|
||||||
|
ActionResult::Arcanist((target1, target2), same) => {
|
||||||
|
Self::Arcanist((target1.character_id, target2.character_id), same)
|
||||||
|
}
|
||||||
|
ActionResult::GraveDigger(target, role_title) => {
|
||||||
|
Self::GraveDigger(target.character_id, role_title)
|
||||||
|
}
|
||||||
|
ActionResult::Mortician(target, died_to) => {
|
||||||
|
Self::Mortician(target.character_id, died_to)
|
||||||
|
}
|
||||||
ActionResult::Insomniac(visits) => Self::Insomniac {
|
ActionResult::Insomniac(visits) => Self::Insomniac {
|
||||||
visits: visits.iter().map(|c| c.character_id).collect(),
|
visits: visits.iter().map(|c| c.character_id).collect(),
|
||||||
},
|
},
|
||||||
ActionResult::Empath { scapegoat } => Self::Empath { scapegoat },
|
ActionResult::Empath { target, scapegoat } => Self::Empath {
|
||||||
|
scapegoat,
|
||||||
|
target: target.character_id,
|
||||||
|
},
|
||||||
|
|
||||||
ActionResult::GoBackToSleep | ActionResult::Continue => return None,
|
ActionResult::GoBackToSleep | ActionResult::Continue => return None,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -206,19 +206,19 @@ impl ActionResultExt for ActionResult {
|
||||||
}
|
}
|
||||||
fn empath(&self) -> bool {
|
fn empath(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Empath { scapegoat } => *scapegoat,
|
Self::Empath { scapegoat, .. } => *scapegoat,
|
||||||
resp => panic!("expected empath, got {resp:?}"),
|
resp => panic!("expected empath, got {resp:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn mortician(&self) -> DiedToTitle {
|
fn mortician(&self) -> DiedToTitle {
|
||||||
match self {
|
match self {
|
||||||
Self::Mortician(role) => *role,
|
Self::Mortician(_, role) => *role,
|
||||||
resp => panic!("expected mortician, got {resp:?}"),
|
resp => panic!("expected mortician, got {resp:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn gravedigger(&self) -> Option<RoleTitle> {
|
fn gravedigger(&self) -> Option<RoleTitle> {
|
||||||
match self {
|
match self {
|
||||||
Self::GraveDigger(role) => *role,
|
Self::GraveDigger(_, role) => *role,
|
||||||
resp => panic!("expected gravedigger, got {resp:?}"),
|
resp => panic!("expected gravedigger, got {resp:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -227,13 +227,13 @@ impl ActionResultExt for ActionResult {
|
||||||
}
|
}
|
||||||
fn adjudicator(&self) -> Killer {
|
fn adjudicator(&self) -> Killer {
|
||||||
match self {
|
match self {
|
||||||
Self::Adjudicator { killer } => *killer,
|
Self::Adjudicator { killer, .. } => *killer,
|
||||||
resp => panic!("expected adjudicator, got {resp:?}"),
|
resp => panic!("expected adjudicator, got {resp:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn power_seer(&self) -> Powerful {
|
fn power_seer(&self) -> Powerful {
|
||||||
match self {
|
match self {
|
||||||
Self::PowerSeer { powerful } => *powerful,
|
Self::PowerSeer { powerful, .. } => *powerful,
|
||||||
resp => panic!("expected power seer, got {resp:?}"),
|
resp => panic!("expected power seer, got {resp:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -247,14 +247,14 @@ impl ActionResultExt for ActionResult {
|
||||||
|
|
||||||
fn seer(&self) -> Alignment {
|
fn seer(&self) -> Alignment {
|
||||||
match self {
|
match self {
|
||||||
ActionResult::Seer(a) => a.clone(),
|
ActionResult::Seer(_, a) => a.clone(),
|
||||||
_ => panic!("expected a seer result"),
|
_ => panic!("expected a seer result"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arcanist(&self) -> AlignmentEq {
|
fn arcanist(&self) -> AlignmentEq {
|
||||||
match self {
|
match self {
|
||||||
ActionResult::Arcanist(same) => same.clone(),
|
ActionResult::Arcanist(_, same) => same.clone(),
|
||||||
resp => panic!("expected an arcanist result, got {resp:?}"),
|
resp => panic!("expected an arcanist result, got {resp:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,13 @@ fn nothing_on_wolf() {
|
||||||
|
|
||||||
game.next().title().empath();
|
game.next().title().empath();
|
||||||
game.mark(game.character_by_player_id(wolf_player_id).character_id());
|
game.mark(game.character_by_player_id(wolf_player_id).character_id());
|
||||||
assert_eq!(game.r#continue(), ActionResult::Empath { scapegoat: false });
|
assert_eq!(
|
||||||
|
game.r#continue(),
|
||||||
|
ActionResult::Empath {
|
||||||
|
scapegoat: false,
|
||||||
|
target: game.character_by_player_id(wolf_player_id).identity()
|
||||||
|
}
|
||||||
|
);
|
||||||
game.r#continue().sleep();
|
game.r#continue().sleep();
|
||||||
|
|
||||||
game.next_expect_day();
|
game.next_expect_day();
|
||||||
|
|
@ -105,7 +111,13 @@ fn takes_on_scapegoats_curse() {
|
||||||
game.character_by_player_id(scapegoat_player_id)
|
game.character_by_player_id(scapegoat_player_id)
|
||||||
.character_id(),
|
.character_id(),
|
||||||
);
|
);
|
||||||
assert_eq!(game.r#continue(), ActionResult::Empath { scapegoat: true });
|
assert_eq!(
|
||||||
|
game.r#continue(),
|
||||||
|
ActionResult::Empath {
|
||||||
|
scapegoat: true,
|
||||||
|
target: game.character_by_player_id(scapegoat_player_id).identity()
|
||||||
|
}
|
||||||
|
);
|
||||||
game.r#continue().sleep();
|
game.r#continue().sleep();
|
||||||
|
|
||||||
game.next().title().seer();
|
game.next().title().seer();
|
||||||
|
|
@ -181,7 +193,13 @@ fn takes_on_scapegoat_aura_curse() {
|
||||||
|
|
||||||
game.next().title().empath();
|
game.next().title().empath();
|
||||||
game.mark(game.character_by_player_id(scapegoat).character_id());
|
game.mark(game.character_by_player_id(scapegoat).character_id());
|
||||||
assert_eq!(game.r#continue(), ActionResult::Empath { scapegoat: true });
|
assert_eq!(
|
||||||
|
game.r#continue(),
|
||||||
|
ActionResult::Empath {
|
||||||
|
scapegoat: true,
|
||||||
|
target: game.character_by_player_id(scapegoat).identity()
|
||||||
|
}
|
||||||
|
);
|
||||||
game.r#continue().sleep();
|
game.r#continue().sleep();
|
||||||
|
|
||||||
game.next_expect_day();
|
game.next_expect_day();
|
||||||
|
|
@ -222,7 +240,13 @@ fn takes_on_scapegoat_aura_curse_no_role_change() {
|
||||||
|
|
||||||
game.next().title().empath();
|
game.next().title().empath();
|
||||||
game.mark(game.character_by_player_id(scapegoat).character_id());
|
game.mark(game.character_by_player_id(scapegoat).character_id());
|
||||||
assert_eq!(game.r#continue(), ActionResult::Empath { scapegoat: true });
|
assert_eq!(
|
||||||
|
game.r#continue(),
|
||||||
|
ActionResult::Empath {
|
||||||
|
scapegoat: true,
|
||||||
|
target: game.character_by_player_id(scapegoat).identity()
|
||||||
|
}
|
||||||
|
);
|
||||||
game.r#continue().sleep();
|
game.r#continue().sleep();
|
||||||
|
|
||||||
game.next_expect_day();
|
game.next_expect_day();
|
||||||
|
|
|
||||||
|
|
@ -601,14 +601,23 @@ pub enum ActionResponse {
|
||||||
pub enum ActionResult {
|
pub enum ActionResult {
|
||||||
RoleBlocked,
|
RoleBlocked,
|
||||||
Drunk,
|
Drunk,
|
||||||
Seer(Alignment),
|
Seer(CharacterIdentity, Alignment),
|
||||||
PowerSeer { powerful: Powerful },
|
PowerSeer {
|
||||||
Adjudicator { killer: Killer },
|
target: CharacterIdentity,
|
||||||
Arcanist(AlignmentEq),
|
powerful: Powerful,
|
||||||
GraveDigger(Option<RoleTitle>),
|
},
|
||||||
Mortician(DiedToTitle),
|
Adjudicator {
|
||||||
|
target: CharacterIdentity,
|
||||||
|
killer: Killer,
|
||||||
|
},
|
||||||
|
Arcanist((CharacterIdentity, CharacterIdentity), AlignmentEq),
|
||||||
|
GraveDigger(CharacterIdentity, Option<RoleTitle>),
|
||||||
|
Mortician(CharacterIdentity, DiedToTitle),
|
||||||
Insomniac(Visits),
|
Insomniac(Visits),
|
||||||
Empath { scapegoat: bool },
|
Empath {
|
||||||
|
target: CharacterIdentity,
|
||||||
|
scapegoat: bool,
|
||||||
|
},
|
||||||
BeholderSawNothing,
|
BeholderSawNothing,
|
||||||
BeholderSawEverything,
|
BeholderSawEverything,
|
||||||
GoBackToSleep,
|
GoBackToSleep,
|
||||||
|
|
@ -619,16 +628,26 @@ pub enum ActionResult {
|
||||||
impl ActionResult {
|
impl ActionResult {
|
||||||
pub fn insane(&self) -> Option<Self> {
|
pub fn insane(&self) -> Option<Self> {
|
||||||
Some(match self {
|
Some(match self {
|
||||||
ActionResult::Seer(Alignment::Village) => ActionResult::Seer(Alignment::Wolves),
|
ActionResult::Seer(c, Alignment::Village) => {
|
||||||
ActionResult::Seer(Alignment::Traitor) | ActionResult::Seer(Alignment::Wolves) => {
|
ActionResult::Seer(c.clone(), Alignment::Wolves)
|
||||||
ActionResult::Seer(Alignment::Village)
|
|
||||||
}
|
}
|
||||||
ActionResult::PowerSeer { powerful } => ActionResult::PowerSeer {
|
ActionResult::Seer(c, Alignment::Traitor)
|
||||||
|
| ActionResult::Seer(c, Alignment::Wolves) => {
|
||||||
|
ActionResult::Seer(c.clone(), Alignment::Village)
|
||||||
|
}
|
||||||
|
ActionResult::PowerSeer { target, powerful } => ActionResult::PowerSeer {
|
||||||
|
target: target.clone(),
|
||||||
powerful: !*powerful,
|
powerful: !*powerful,
|
||||||
},
|
},
|
||||||
ActionResult::Adjudicator { killer } => ActionResult::Adjudicator { killer: !*killer },
|
ActionResult::Adjudicator { target, killer } => ActionResult::Adjudicator {
|
||||||
ActionResult::Arcanist(alignment_eq) => ActionResult::Arcanist(!*alignment_eq),
|
target: target.clone(),
|
||||||
ActionResult::Empath { scapegoat } => ActionResult::Empath {
|
killer: !*killer,
|
||||||
|
},
|
||||||
|
ActionResult::Arcanist(targets, alignment_eq) => {
|
||||||
|
ActionResult::Arcanist(targets.clone(), !*alignment_eq)
|
||||||
|
}
|
||||||
|
ActionResult::Empath { target, scapegoat } => ActionResult::Empath {
|
||||||
|
target: target.clone(),
|
||||||
scapegoat: !*scapegoat,
|
scapegoat: !*scapegoat,
|
||||||
},
|
},
|
||||||
ActionResult::BeholderSawNothing => ActionResult::BeholderSawEverything,
|
ActionResult::BeholderSawNothing => ActionResult::BeholderSawEverything,
|
||||||
|
|
@ -637,8 +656,8 @@ impl ActionResult {
|
||||||
ActionResult::ShiftFailed
|
ActionResult::ShiftFailed
|
||||||
| ActionResult::RoleBlocked
|
| ActionResult::RoleBlocked
|
||||||
| ActionResult::Drunk
|
| ActionResult::Drunk
|
||||||
| ActionResult::GraveDigger(_)
|
| ActionResult::GraveDigger(_, _)
|
||||||
| ActionResult::Mortician(_)
|
| ActionResult::Mortician(_, _)
|
||||||
| ActionResult::Insomniac(_)
|
| ActionResult::Insomniac(_)
|
||||||
| ActionResult::GoBackToSleep
|
| ActionResult::GoBackToSleep
|
||||||
| ActionResult::Continue => return None,
|
| ActionResult::Continue => return None,
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,7 @@ nav.host-nav {
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
color: invert(#cccccc);
|
color: color.invert(#cccccc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -952,7 +952,7 @@ error {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 2px;
|
gap: 2px;
|
||||||
font-size: 1rem;
|
font-size: 1em;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
@ -2159,6 +2159,18 @@ li.choice {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 30px;
|
gap: 30px;
|
||||||
|
max-height: 40%;
|
||||||
|
|
||||||
|
@media only screen and (min-width : 1600px) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
flex-shrink: 1;
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-height: 100%;
|
||||||
|
flex-shrink: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-info {
|
.icon-info {
|
||||||
|
|
@ -2248,6 +2260,7 @@ li.choice {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
align-items: center;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2287,6 +2300,7 @@ li.choice {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
font-size: 0.5em;
|
||||||
|
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
@ -2368,9 +2382,13 @@ li.choice {
|
||||||
}
|
}
|
||||||
|
|
||||||
.information {
|
.information {
|
||||||
font-size: 1.0rem;
|
font-size: 2.0rem;
|
||||||
|
font-stretch: condensed;
|
||||||
padding-left: 5%;
|
padding-left: 5%;
|
||||||
padding-right: 5%;
|
padding-right: 5%;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
@ -2397,6 +2415,30 @@ li.choice {
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
flex-shrink: 1;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subtext {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arcanist-targets {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 1ch;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.and {
|
||||||
|
font-style: italic;
|
||||||
|
opacity: 50%;
|
||||||
|
font-size: 0.7em;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.setup-aura {
|
.setup-aura {
|
||||||
|
|
@ -2594,7 +2636,7 @@ dialog::backdrop {
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button:not(:hover) {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,9 @@ use werewolves_proto::{
|
||||||
};
|
};
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::components::{
|
||||||
components::{
|
|
||||||
Button, CoverOfDarkness, Identity,
|
Button, CoverOfDarkness, Identity,
|
||||||
action::{BinaryChoice, TargetPicker, WolvesIntro},
|
action::{BinaryChoice, TargetPicker, WolvesIntro},
|
||||||
},
|
|
||||||
pages::TraitorIntroPage,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Properties)]
|
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||||
|
|
@ -111,24 +108,8 @@ pub fn Prompt(props: &ActionPromptProps) -> Html {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
let cont = continue_callback.clone().map(|continue_callback| {
|
|
||||||
html! {
|
|
||||||
<Button on_click={continue_callback}>
|
|
||||||
{"continue"}
|
|
||||||
</Button>
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let (character_id, targets, marked, role_info) = match &props.prompt {
|
let (character_id, targets, marked, role_info) = match &props.prompt {
|
||||||
ActionPrompt::BeholderWakes { .. } => return html! {},
|
ActionPrompt::BeholderWakes { .. } | ActionPrompt::TraitorIntro { .. } => return html! {},
|
||||||
ActionPrompt::TraitorIntro { character_id } => {
|
|
||||||
return html! {
|
|
||||||
<div class="prompt">
|
|
||||||
{identity_html(props, Some(character_id))}
|
|
||||||
<TraitorIntroPage />
|
|
||||||
{cont}
|
|
||||||
</div>
|
|
||||||
};
|
|
||||||
}
|
|
||||||
ActionPrompt::CoverOfDarkness => {
|
ActionPrompt::CoverOfDarkness => {
|
||||||
return html! {
|
return html! {
|
||||||
<CoverOfDarkness next={continue_callback}/>
|
<CoverOfDarkness next={continue_callback}/>
|
||||||
|
|
@ -415,16 +396,15 @@ pub fn Prompt(props: &ActionPromptProps) -> Html {
|
||||||
{identity_html(props, Some(character_id))}
|
{identity_html(props, Some(character_id))}
|
||||||
<h1 class="wolves">{"SHAPESHIFTER"}</h1>
|
<h1 class="wolves">{"SHAPESHIFTER"}</h1>
|
||||||
<div class="information wolves faint">
|
<div class="information wolves faint">
|
||||||
<h2>
|
<span>
|
||||||
{"WOULD YOU LIKE TO USE YOUR "}
|
{"WOULD YOU LIKE TO USE YOUR "}
|
||||||
<span class="yellow">{"ONCE PER GAME"}</span>
|
<span class="yellow">{"ONCE PER GAME"}</span>
|
||||||
{" SHAPESHIFT ABILITY?"}
|
{" SHAPESHIFT ABILITY?"}
|
||||||
</h2>
|
</span>
|
||||||
<h2>
|
<span class="subtext">
|
||||||
<span class="yellow">{"YOU WILL DIE"}</span>{", AND THE "}
|
<span class="yellow">{"YOU WILL DIE"}</span>
|
||||||
{"TARGET OF THE WOLFPACK KILL"}
|
{", BUT THE TARGET OF THE WOLFPACK KILL SHALL INSTEAD BECOME A WOLF"}
|
||||||
{" SHALL INSTEAD BECOME A WOLF"}
|
</span>
|
||||||
</h2>
|
|
||||||
</div>
|
</div>
|
||||||
{choice}
|
{choice}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -70,21 +70,21 @@ pub fn ActionResultView(props: &ActionResultProps) -> Html {
|
||||||
ActionResult::BeholderSawNothing => html! {
|
ActionResult::BeholderSawNothing => html! {
|
||||||
<BeholderSawNothing />
|
<BeholderSawNothing />
|
||||||
},
|
},
|
||||||
ActionResult::PowerSeer { powerful } => {
|
ActionResult::PowerSeer { target, powerful } => {
|
||||||
html! {
|
html! {
|
||||||
<PowerSeerResult powerful={*powerful}/>
|
<PowerSeerResult powerful={*powerful} target={target.clone().into_public()}/>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionResult::Adjudicator { killer } => {
|
ActionResult::Adjudicator { killer, target } => {
|
||||||
html! {
|
html! {
|
||||||
<AdjudicatorResult killer={*killer}/>
|
<AdjudicatorResult killer={*killer} target={target.clone().into_public()}/>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionResult::Mortician(died_to) => html! {
|
ActionResult::Mortician(target, died_to) => html! {
|
||||||
<MorticianResultPage died_to={*died_to}/>
|
<MorticianResultPage died_to={*died_to} target={target.clone().into_public()}/>
|
||||||
},
|
},
|
||||||
ActionResult::Empath { scapegoat } => html! {
|
ActionResult::Empath { target, scapegoat } => html! {
|
||||||
<EmpathResult scapegoat={*scapegoat}/>
|
<EmpathResult scapegoat={*scapegoat} target={target.clone().into_public()}/>
|
||||||
},
|
},
|
||||||
ActionResult::Insomniac(visits) => {
|
ActionResult::Insomniac(visits) => {
|
||||||
html! {
|
html! {
|
||||||
|
|
@ -96,17 +96,17 @@ pub fn ActionResultView(props: &ActionResultProps) -> Html {
|
||||||
<RoleblockPage />
|
<RoleblockPage />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionResult::Seer(alignment) => html! {
|
ActionResult::Seer(target, alignment) => html! {
|
||||||
<SeerResult alignment={*alignment}/>
|
<SeerResult alignment={*alignment} target={target.clone().into_public()}/>
|
||||||
},
|
},
|
||||||
ActionResult::Arcanist(same) => {
|
ActionResult::Arcanist((t1, t2), same) => {
|
||||||
html! {
|
html! {
|
||||||
<ArcanistResult alignment_eq={*same}/>
|
<ArcanistResult alignment_eq={*same} targets={(t1.clone().into_public(), t2.clone().into_public())}/>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionResult::GraveDigger(role_title) => {
|
ActionResult::GraveDigger(target, role_title) => {
|
||||||
html! {
|
html! {
|
||||||
<GravediggerResultPage role={*role_title}/>
|
<GravediggerResultPage role={*role_title} target={target.clone().into_public()}/>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionResult::GoBackToSleep => {
|
ActionResult::GoBackToSleep => {
|
||||||
|
|
|
||||||
|
|
@ -327,40 +327,40 @@ fn Choice(
|
||||||
<Roleblock>{"Roleblocked"}</Roleblock>
|
<Roleblock>{"Roleblocked"}</Roleblock>
|
||||||
</>
|
</>
|
||||||
},
|
},
|
||||||
StoryActionResult::Seer(alignment) => html! {
|
StoryActionResult::Seer(_, alignment) => html! {
|
||||||
<>
|
<>
|
||||||
<span>{"and saw"}</span>
|
<span>{"and saw"}</span>
|
||||||
<AlignmentSpan alignment={*alignment}/>
|
<AlignmentSpan alignment={*alignment}/>
|
||||||
</>
|
</>
|
||||||
},
|
},
|
||||||
StoryActionResult::PowerSeer { powerful } => html! {
|
StoryActionResult::PowerSeer { powerful, .. } => html! {
|
||||||
<>
|
<>
|
||||||
<span>{"and saw"}</span>
|
<span>{"and saw"}</span>
|
||||||
<PowerfulSpan powerful={*powerful}/>
|
<PowerfulSpan powerful={*powerful}/>
|
||||||
</>
|
</>
|
||||||
},
|
},
|
||||||
StoryActionResult::Adjudicator { killer } => html! {
|
StoryActionResult::Adjudicator { killer, .. } => html! {
|
||||||
<>
|
<>
|
||||||
<span>{"and saw"}</span>
|
<span>{"and saw"}</span>
|
||||||
<KillerSpan killer={*killer}/>
|
<KillerSpan killer={*killer}/>
|
||||||
</>
|
</>
|
||||||
},
|
},
|
||||||
StoryActionResult::Arcanist(alignment_eq) => html! {
|
StoryActionResult::Arcanist(_, alignment_eq) => html! {
|
||||||
<>
|
<>
|
||||||
<span>{"and saw them as"}</span>
|
<span>{"and saw them as"}</span>
|
||||||
<AlignmentComparisonSpan comparison={*alignment_eq}/>
|
<AlignmentComparisonSpan comparison={*alignment_eq}/>
|
||||||
</>
|
</>
|
||||||
},
|
},
|
||||||
StoryActionResult::GraveDigger(None) => html! {
|
StoryActionResult::GraveDigger(_, None) => html! {
|
||||||
<span>{"but found an empty grave"}</span>
|
<span>{"but found an empty grave"}</span>
|
||||||
},
|
},
|
||||||
StoryActionResult::GraveDigger(Some(role_title)) => html! {
|
StoryActionResult::GraveDigger(_, Some(role_title)) => html! {
|
||||||
<>
|
<>
|
||||||
<span>{"as"}</span>
|
<span>{"as"}</span>
|
||||||
<RoleSpan role={*role_title}/>
|
<RoleSpan role={*role_title}/>
|
||||||
</>
|
</>
|
||||||
},
|
},
|
||||||
StoryActionResult::Mortician(died_to_title) => html! {
|
StoryActionResult::Mortician(_, died_to_title) => html! {
|
||||||
<>
|
<>
|
||||||
<span>{"and found"}</span>
|
<span>{"and found"}</span>
|
||||||
<DiedToSpan died_to={*died_to_title}/>
|
<DiedToSpan died_to={*died_to_title}/>
|
||||||
|
|
@ -390,10 +390,14 @@ fn Choice(
|
||||||
})
|
})
|
||||||
.collect::<Html>()
|
.collect::<Html>()
|
||||||
}
|
}
|
||||||
StoryActionResult::Empath { scapegoat: true } => {
|
StoryActionResult::Empath {
|
||||||
|
scapegoat: true, ..
|
||||||
|
} => {
|
||||||
html! {<span>{"and found their scapegoat"}</span>}
|
html! {<span>{"and found their scapegoat"}</span>}
|
||||||
}
|
}
|
||||||
StoryActionResult::Empath { scapegoat: false } => {
|
StoryActionResult::Empath {
|
||||||
|
scapegoat: false, ..
|
||||||
|
} => {
|
||||||
html! {<span>{"who was not a scapegoat"}</span>}
|
html! {<span>{"who was not a scapegoat"}</span>}
|
||||||
}
|
}
|
||||||
StoryActionResult::BeholderSawNothing => html! {
|
StoryActionResult::BeholderSawNothing => html! {
|
||||||
|
|
|
||||||
|
|
@ -652,19 +652,19 @@ impl ActionResultExt for ActionResult {
|
||||||
}
|
}
|
||||||
fn empath(&self) -> bool {
|
fn empath(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Self::Empath { scapegoat } => *scapegoat,
|
Self::Empath { scapegoat, .. } => *scapegoat,
|
||||||
resp => panic!("expected empath, got {resp:?}"),
|
resp => panic!("expected empath, got {resp:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn mortician(&self) -> DiedToTitle {
|
fn mortician(&self) -> DiedToTitle {
|
||||||
match self {
|
match self {
|
||||||
Self::Mortician(role) => *role,
|
Self::Mortician(_, role) => *role,
|
||||||
resp => panic!("expected mortician, got {resp:?}"),
|
resp => panic!("expected mortician, got {resp:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn gravedigger(&self) -> Option<RoleTitle> {
|
fn gravedigger(&self) -> Option<RoleTitle> {
|
||||||
match self {
|
match self {
|
||||||
Self::GraveDigger(role) => *role,
|
Self::GraveDigger(_, role) => *role,
|
||||||
resp => panic!("expected gravedigger, got {resp:?}"),
|
resp => panic!("expected gravedigger, got {resp:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -673,13 +673,13 @@ impl ActionResultExt for ActionResult {
|
||||||
}
|
}
|
||||||
fn adjudicator(&self) -> Killer {
|
fn adjudicator(&self) -> Killer {
|
||||||
match self {
|
match self {
|
||||||
Self::Adjudicator { killer } => *killer,
|
Self::Adjudicator { killer, .. } => *killer,
|
||||||
resp => panic!("expected adjudicator, got {resp:?}"),
|
resp => panic!("expected adjudicator, got {resp:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn power_seer(&self) -> Powerful {
|
fn power_seer(&self) -> Powerful {
|
||||||
match self {
|
match self {
|
||||||
Self::PowerSeer { powerful } => *powerful,
|
Self::PowerSeer { powerful, .. } => *powerful,
|
||||||
resp => panic!("expected power seer, got {resp:?}"),
|
resp => panic!("expected power seer, got {resp:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -693,14 +693,14 @@ impl ActionResultExt for ActionResult {
|
||||||
|
|
||||||
fn seer(&self) -> Alignment {
|
fn seer(&self) -> Alignment {
|
||||||
match self {
|
match self {
|
||||||
ActionResult::Seer(a) => a.clone(),
|
ActionResult::Seer(_, a) => a.clone(),
|
||||||
_ => panic!("expected a seer result"),
|
_ => panic!("expected a seer result"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arcanist(&self) -> AlignmentEq {
|
fn arcanist(&self) -> AlignmentEq {
|
||||||
match self {
|
match self {
|
||||||
ActionResult::Arcanist(same) => same.clone(),
|
ActionResult::Arcanist(_, same) => same.clone(),
|
||||||
resp => panic!("expected an arcanist result, got {resp:?}"),
|
resp => panic!("expected an arcanist result, got {resp:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use werewolves_proto::aura::AuraTitle;
|
use werewolves_proto::aura::AuraTitle;
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Icon, IconSource, PartialAssociatedIcon};
|
use crate::components::{Icon, IconSource, IconType, PartialAssociatedIcon};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn DrunkPage() -> Html {
|
pub fn DrunkPage() -> Html {
|
||||||
|
|
@ -10,11 +10,9 @@ pub fn DrunkPage() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="drunk">{"DRUNK"}</h1>
|
<h1 class="drunk">{"DRUNK"}</h1>
|
||||||
<div class="information drunk faint">
|
<div class="information drunk faint">
|
||||||
<h2>{"YOU GOT DRUNK INSTEAD"}</h2>
|
{"YOU GOT DRUNK INSTEAD"}
|
||||||
<div class="info-icon-grow">
|
<Icon source={icon} icon_type={IconType::Informational}/>
|
||||||
<Icon source={icon}/>
|
<span class="yellow">{"YOUR NIGHT ACTION DID NOT TAKE PLACE"}</span>
|
||||||
</div>
|
|
||||||
<h3 class="yellow">{"YOUR NIGHT ACTION DID NOT TAKE PLACE"}</h3>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ use convert_case::{Case, Casing};
|
||||||
use werewolves_proto::{game::SetupRole, role::RoleTitle};
|
use werewolves_proto::{game::SetupRole, role::RoleTitle};
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Icon, PartialAssociatedIcon};
|
use crate::components::{Icon, IconType, PartialAssociatedIcon};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
||||||
pub struct RoleChangePageProps {
|
pub struct RoleChangePageProps {
|
||||||
|
|
@ -28,21 +28,19 @@ pub fn RoleChangePage(RoleChangePageProps { role }: &RoleChangePageProps) -> Htm
|
||||||
let class = Into::<SetupRole>::into(*role).category().class();
|
let class = Into::<SetupRole>::into(*role).category().class();
|
||||||
let icon = role.icon().map(|icon| {
|
let icon = role.icon().map(|icon| {
|
||||||
html! {
|
html! {
|
||||||
<div class="info-icon-grow">
|
<Icon source={icon} icon_type={IconType::Fit}/>
|
||||||
<Icon source={icon}/>
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
html! {
|
html! {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class={classes!(class)}>{"ROLE CHANGE"}</h1>
|
<h1 class={classes!(class)}>{"ROLE CHANGE"}</h1>
|
||||||
<div class={classes!("information", class, "faint")}>
|
<div class={classes!("information", class, "faint")}>
|
||||||
<h2>{"YOUR ROLE HAS CHANGED"}</h2>
|
{"YOUR ROLE HAS CHANGED"}
|
||||||
{icon}
|
{icon}
|
||||||
<h3>
|
<span>
|
||||||
<span>{"YOUR NEW ROLE IS "}</span>
|
{"YOUR NEW ROLE IS "}
|
||||||
<span class="yellow">{role.to_string().to_case(Case::Upper)}</span>
|
<span class="yellow">{role.to_string().to_case(Case::Upper)}</span>
|
||||||
</h3>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ use yew::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
components::Identity,
|
components::Identity,
|
||||||
pages::{RoleChangePage, WolfpackKillPage},
|
pages::{RoleChangePage, TraitorIntroPage1, TraitorIntroPage2, WolfpackKillPage},
|
||||||
};
|
};
|
||||||
|
|
||||||
werewolves_macros::include_path!("werewolves/src/pages/role_page");
|
werewolves_macros::include_path!("werewolves/src/pages/role_page");
|
||||||
|
|
@ -123,12 +123,20 @@ impl RolePage for ActionPrompt {
|
||||||
character_id,
|
character_id,
|
||||||
recruits_left,
|
recruits_left,
|
||||||
..
|
..
|
||||||
} => Rc::new([html! {
|
} => Rc::new([
|
||||||
|
html! {
|
||||||
<>
|
<>
|
||||||
{ident(character_id)}
|
{ident(character_id)}
|
||||||
<MasonRecruitPage1 recruits_left={*recruits_left} />
|
<MasonRecruitPage1 recruits_left={*recruits_left} />
|
||||||
</>
|
</>
|
||||||
}]),
|
},
|
||||||
|
html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<MasonRecruitPage2 />
|
||||||
|
</>
|
||||||
|
},
|
||||||
|
]),
|
||||||
ActionPrompt::MasonsWake { leader, masons } => Rc::new([html! {
|
ActionPrompt::MasonsWake { leader, masons } => Rc::new([html! {
|
||||||
<>
|
<>
|
||||||
{ident(leader)}
|
{ident(leader)}
|
||||||
|
|
@ -147,12 +155,20 @@ impl RolePage for ActionPrompt {
|
||||||
<InsomniacPage1 />
|
<InsomniacPage1 />
|
||||||
</>
|
</>
|
||||||
}]),
|
}]),
|
||||||
ActionPrompt::ElderReveal { character_id, .. } => Rc::new([html! {
|
ActionPrompt::ElderReveal { character_id, .. } => Rc::new([
|
||||||
|
html! {
|
||||||
<>
|
<>
|
||||||
{ident(character_id)}
|
{ident(character_id)}
|
||||||
<ElderPage1 />
|
<ElderPage1 />
|
||||||
</>
|
</>
|
||||||
}]),
|
},
|
||||||
|
html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<ElderPage2 />
|
||||||
|
</>
|
||||||
|
},
|
||||||
|
]),
|
||||||
ActionPrompt::Guardian {
|
ActionPrompt::Guardian {
|
||||||
character_id,
|
character_id,
|
||||||
previous: None,
|
previous: None,
|
||||||
|
|
@ -253,6 +269,20 @@ impl RolePage for ActionPrompt {
|
||||||
<BeholderWakePage1 />
|
<BeholderWakePage1 />
|
||||||
</>
|
</>
|
||||||
}]),
|
}]),
|
||||||
|
ActionPrompt::TraitorIntro { character_id } => Rc::new([
|
||||||
|
html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<TraitorIntroPage1 />
|
||||||
|
</>
|
||||||
|
},
|
||||||
|
html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<TraitorIntroPage2 />
|
||||||
|
</>
|
||||||
|
},
|
||||||
|
]),
|
||||||
_ => Rc::new([]),
|
_ => Rc::new([]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
use werewolves_proto::role::Killer;
|
use werewolves_proto::{message::PublicIdentity, role::Killer};
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Icon, IconSource};
|
use crate::components::{Icon, IconSource, IdentitySpan};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn AdjudicatorPage1() -> Html {
|
pub fn AdjudicatorPage1() -> Html {
|
||||||
|
|
@ -23,23 +23,24 @@ pub fn AdjudicatorPage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="defensive">{"ADJUDICATOR"}</h1>
|
<h1 class="defensive">{"ADJUDICATOR"}</h1>
|
||||||
<div class="information defensive faint">
|
<div class="information defensive faint">
|
||||||
<h2>{"PICK A PLAYER"}</h2>
|
<h4>{"PICK A PLAYER"}</h4>
|
||||||
<div class="info-icon-grow">
|
|
||||||
<Icon source={IconSource::Killer}/>
|
<Icon source={IconSource::Killer}/>
|
||||||
</div>
|
<h4 class="yellow">{"YOU WILL CHECK IF THEY APPEAR AS A KILLER"}</h4>
|
||||||
<h3 class="yellow">{"YOU WILL CHECK IF THEY APPEAR AS A KILLER"}</h3>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||||
pub struct AdjudicatorResultProps {
|
pub struct AdjudicatorResultProps {
|
||||||
pub killer: Killer,
|
pub killer: Killer,
|
||||||
|
pub target: PublicIdentity,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn AdjudicatorResult(AdjudicatorResultProps { killer }: &AdjudicatorResultProps) -> Html {
|
pub fn AdjudicatorResult(
|
||||||
|
AdjudicatorResultProps { killer, target }: &AdjudicatorResultProps,
|
||||||
|
) -> Html {
|
||||||
let text = match killer {
|
let text = match killer {
|
||||||
Killer::Killer => "IS A KILLER",
|
Killer::Killer => "IS A KILLER",
|
||||||
Killer::NotKiller => "IS NOT A KILLER",
|
Killer::NotKiller => "IS NOT A KILLER",
|
||||||
|
|
@ -60,8 +61,8 @@ pub fn AdjudicatorResult(AdjudicatorResultProps { killer }: &AdjudicatorResultPr
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="defensive">{"ADJUDICATOR"}</h1>
|
<h1 class="defensive">{"ADJUDICATOR"}</h1>
|
||||||
<div class="information defensive faint">
|
<div class="information defensive faint">
|
||||||
<h2>{"YOUR TARGET"}</h2>
|
<IdentitySpan ident={target.clone()}/>
|
||||||
<div class="info-icon-grow">{icon}</div>
|
{icon}
|
||||||
<h3 class="yellow">{text}</h3>
|
<h3 class="yellow">{text}</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -20,15 +20,12 @@ pub fn AlphaWolfPage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="wolves">{"ALPHA WOLF"}</h1>
|
<h1 class="wolves">{"ALPHA WOLF"}</h1>
|
||||||
<div class="information wolves faint">
|
<div class="information wolves faint">
|
||||||
<h2>
|
<span>
|
||||||
{"IF YOU WISH TO USE YOUR "}
|
{"IF YOU WISH TO USE YOUR "}
|
||||||
<span class="yellow">{"ONCE PER GAME"}</span>
|
<span class="yellow">{"ONCE PER GAME"}</span>
|
||||||
{" KILL ABILITY"}
|
{" KILL ABILITY"}
|
||||||
</h2>
|
</span>
|
||||||
<h2>
|
{"POINT AT YOUR TARGET OR GO BACK TO SLEEP"}
|
||||||
{"POINT AT YOUR TARGET "}
|
|
||||||
{"OR GO BACK TO SLEEP"}
|
|
||||||
</h2>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
use werewolves_proto::role::AlignmentEq;
|
use werewolves_proto::{message::PublicIdentity, role::AlignmentEq};
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Icon, IconSource, IconType};
|
use crate::components::{Icon, IconSource, IconType, IdentitySpan};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn ArcanistPage1() -> Html {
|
pub fn ArcanistPage1() -> Html {
|
||||||
|
|
@ -23,50 +23,59 @@ pub fn ArcanistPage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="intel">{"ARCANIST"}</h1>
|
<h1 class="intel">{"ARCANIST"}</h1>
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
<h2>{"PICK TWO PLAYERS"}</h2>
|
{"PICK TWO PLAYERS"}
|
||||||
<h4 class="icons">
|
<div class="icons">
|
||||||
<Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
<Icon source={IconSource::Village}
|
||||||
// <Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
icon_type={IconType::Informational}
|
||||||
// <Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
/>
|
||||||
<Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
<Icon source={IconSource::Wolves}
|
||||||
</h4>
|
icon_type={IconType::Informational}
|
||||||
<h3 class="yellow">{"YOU WILL CHECK IF THEIR ALIGNMENTS ARE THE SAME OR DIFFERENT"}</h3>
|
/>
|
||||||
|
</div>
|
||||||
|
<span class="yellow">{"YOU WILL COMPARE THEIR ALIGNMENTS"}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||||
pub struct ArcanistResultProps {
|
pub struct ArcanistResultProps {
|
||||||
pub alignment_eq: AlignmentEq,
|
pub alignment_eq: AlignmentEq,
|
||||||
|
pub targets: (PublicIdentity, PublicIdentity),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn ArcanistResult(ArcanistResultProps { alignment_eq }: &ArcanistResultProps) -> Html {
|
pub fn ArcanistResult(
|
||||||
|
ArcanistResultProps {
|
||||||
|
alignment_eq,
|
||||||
|
targets: (t1, t2),
|
||||||
|
}: &ArcanistResultProps,
|
||||||
|
) -> Html {
|
||||||
let text = match alignment_eq {
|
let text = match alignment_eq {
|
||||||
AlignmentEq::Same => "THE SAME",
|
AlignmentEq::Same => "ARE THE SAME",
|
||||||
AlignmentEq::Different => "DIFFERENT",
|
AlignmentEq::Different => "ARE DIFFERENT",
|
||||||
};
|
};
|
||||||
let icons = match alignment_eq {
|
let icons = match alignment_eq {
|
||||||
AlignmentEq::Same => html! {
|
AlignmentEq::Same => html! {
|
||||||
<Icon source={IconSource::Equal} />
|
<Icon source={IconSource::Equal} icon_type={IconType::Informational} />
|
||||||
},
|
},
|
||||||
AlignmentEq::Different => html! {
|
AlignmentEq::Different => html! {
|
||||||
<>
|
<Icon source={IconSource::NotEqual} icon_type={IconType::Informational} />
|
||||||
<Icon source={IconSource::Village} />
|
|
||||||
<Icon source={IconSource::Wolves} />
|
|
||||||
</>
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
html! {
|
html! {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="intel">{"ARCANIST"}</h1>
|
<h1 class="intel">{"ARCANIST"}</h1>
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
<h2>{"YOUR TARGETS APPEAR AS"}</h2>
|
<div class="arcanist-targets">
|
||||||
<div class="info-icon-list-grow">
|
<IdentitySpan ident={t1.clone()}/>
|
||||||
|
<span class="and">{"AND"}</span>
|
||||||
|
<IdentitySpan ident={t2.clone()}/>
|
||||||
|
</div>
|
||||||
|
<div class="icons">
|
||||||
{icons}
|
{icons}
|
||||||
</div>
|
</div>
|
||||||
<h1 class="yellow">{text}</h1>
|
<span class="yellow">{text}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Icon, IconSource};
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn BeholderPage1() -> Html {
|
pub fn BeholderPage1() -> Html {
|
||||||
|
|
@ -22,9 +22,10 @@ pub fn BeholderPage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="intel">{"BEHOLDER"}</h1>
|
<h1 class="intel">{"BEHOLDER"}</h1>
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
<h2>{"PICK A PLAYER"}</h2>
|
{"PICK A PLAYER"}
|
||||||
<h3>{"YOU WILL SEE WHAT INFORMATION THEY MAY HAVE GATHERED"}</h3>
|
<Icon source={IconSource::Beholder} icon_type={IconType::Informational}/>
|
||||||
<h2 class="yellow">{"SHOULD THEY DIE TONIGHT"}</h2>
|
{"YOU WILL SEE WHAT INFORMATION THEY MAY HAVE GATHERED"}
|
||||||
|
<span class="yellow">{"SHOULD THEY DIE TONIGHT"}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
@ -36,11 +37,9 @@ pub fn BeholderWakePage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="intel">{"BEHOLDER"}</h1>
|
<h1 class="intel">{"BEHOLDER"}</h1>
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
<h2>{"YOUR TARGET HAS DIED"}</h2>
|
{"YOUR TARGET HAS DIED"}
|
||||||
<div class="info-icon-grow">
|
<Icon source={IconSource::Beholder} icon_type={IconType::Informational}/>
|
||||||
<Icon source={IconSource::Beholder}/>
|
<span class="yellow">{"THIS IS THE LAST PIECE OF INFORMATION THEY SAW"}</span>
|
||||||
</div>
|
|
||||||
<h2 class="yellow">{"THIS IS THE LAST PIECE OF INFORMATION THEY SAW"}</h2>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
@ -68,16 +67,14 @@ pub fn BeholderSawEverything() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="intel">{"BEHOLDER"}</h1>
|
<h1 class="intel">{"BEHOLDER"}</h1>
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
<h1>{"YOUR TARGET HAS DIED"}</h1>
|
{"YOUR TARGET HAS DIED"}
|
||||||
<div class="info-icon-grow">
|
<Icon source={IconSource::Beholder} icon_type={IconType::Informational}/>
|
||||||
<Icon source={IconSource::Beholder}/>
|
<span>
|
||||||
</div>
|
|
||||||
<h1>
|
|
||||||
{"BUT SAW "}
|
{"BUT SAW "}
|
||||||
<em class="red">
|
<em class="red">
|
||||||
<strong>{"EVERYTHING"}</strong>
|
<strong>{"EVERYTHING"}</strong>
|
||||||
</em>
|
</em>
|
||||||
</h1>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,17 +22,16 @@ pub fn BloodletterPage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="wolves">{"BLOODLETTER"}</h1>
|
<h1 class="wolves">{"BLOODLETTER"}</h1>
|
||||||
<div class="information wolves faint">
|
<div class="information wolves faint">
|
||||||
<h2>{"PICK A PLAYER"}</h2>
|
<span>{"PICK A PLAYER"}</span>
|
||||||
<h3>{"THEY WILL BE COVERED IN WOLF BLOOD"}</h3>
|
<span class="inline-icons">
|
||||||
<h2 class="yellow inline-icons">
|
{"THEY'LL APPEAR AS A WOLF "}
|
||||||
{"AND APPEAR AS A WOLF "}
|
|
||||||
<Icon source={IconSource::Wolves} icon_type={IconType::Fit}/>
|
<Icon source={IconSource::Wolves} icon_type={IconType::Fit}/>
|
||||||
{" KILLER "}
|
{"KILLER"}
|
||||||
<Icon source={IconSource::Killer} icon_type={IconType::Fit}/>
|
<Icon source={IconSource::Killer} icon_type={IconType::Fit}/>
|
||||||
{" AND POWERFUL "}
|
{"AND POWERFUL"}
|
||||||
<Icon source={IconSource::Powerful} icon_type={IconType::Fit}/>
|
<Icon source={IconSource::Powerful} icon_type={IconType::Fit}/>
|
||||||
{" IN CHECKS"}
|
{"IN CHECKS FOR 2 NIGHTS"}
|
||||||
</h2>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,9 @@ pub fn DirewolfPage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="wolves">{"DIREWOLF"}</h1>
|
<h1 class="wolves">{"DIREWOLF"}</h1>
|
||||||
<div class="information wolves faint">
|
<div class="information wolves faint">
|
||||||
<h2>{"CHOOSE A TARGET"}</h2>
|
{"CHOOSE A TARGET"}
|
||||||
<h3 class="yellow">{"ANY VISITORS TO THIS TARGET WILL BE ROLE BLOCKED"}</h3>
|
<span class="yellow">{"ANY VISITORS TO THIS TARGET WILL BE ROLE BLOCKED"}</span>
|
||||||
<h4>{"YOU CANNOT CHOOSE YOURSELF OR THE SAME TARGET AS LAST NIGHT"}</h4>
|
{"YOU CANNOT CHOOSE YOURSELF OR THE SAME TARGET AS LAST NIGHT"}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,15 +20,24 @@ pub fn ElderPage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="starts-as-villager">{"ELDER"}</h1>
|
<h1 class="starts-as-villager">{"ELDER"}</h1>
|
||||||
<div class="information starts-as-villager faint">
|
<div class="information starts-as-villager faint">
|
||||||
<h2>{"YOU ARE THE ELDER"}</h2>
|
{"YOU ARE THE ELDER"}
|
||||||
<h4 class="yellow">
|
<span class="yellow">
|
||||||
{"IF YOU ARE EXECUTED BY THE VILLAGE FROM NOW ON "}
|
{"IF YOU ARE EXECUTED BY THE VILLAGE FROM NOW ON "}
|
||||||
{"ALL POWER ROLES WILL BE LOST"}
|
{"ALL POWER ROLES WILL BE LOST"}
|
||||||
</h4>
|
</span>
|
||||||
<h4>
|
</div>
|
||||||
{"YOU STARTED THE GAME WITH PROTECTION FROM A NIGHT "}
|
</div>
|
||||||
{"DEATH — THIS MAY OR MAY NOT STILL BE INTACT"}
|
}
|
||||||
</h4>
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn ElderPage2() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="starts-as-villager">{"ELDER"}</h1>
|
||||||
|
<div class="information starts-as-villager faint">
|
||||||
|
{"YOU STARTED THE GAME WITH PROTECTION FROM A NIGHT "}
|
||||||
|
{"DEATH — THIS MAY OR MAY NOT STILL BE INTACT"}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,10 @@
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use werewolves_proto::message::PublicIdentity;
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Icon, IconSource};
|
use crate::components::{Icon, IconSource, IconType, IdentitySpan};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn EmpathPage1() -> Html {
|
pub fn EmpathPage1() -> Html {
|
||||||
|
|
@ -23,34 +24,35 @@ pub fn EmpathPage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="intel">{"EMPATH"}</h1>
|
<h1 class="intel">{"EMPATH"}</h1>
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
<h2>{"PICK A PLAYER"}</h2>
|
{"PICK A PLAYER"}
|
||||||
<h3 class="yellow">{"YOU WILL CHECK IF THEY ARE THE SCAPEGOAT"}</h3>
|
<span class="yellow">{"YOU WILL CHECK IF THEY ARE THE SCAPEGOAT"}</span>
|
||||||
<h3>{"IF THEY ARE, YOU WILL TAKE ON THEIR CURSE"}</h3>
|
{"IF THEY ARE, YOU WILL TAKE ON THEIR CURSE"}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||||
pub struct EmpathResultProps {
|
pub struct EmpathResultProps {
|
||||||
pub scapegoat: bool,
|
pub scapegoat: bool,
|
||||||
|
pub target: PublicIdentity,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn EmpathResult(EmpathResultProps { scapegoat }: &EmpathResultProps) -> Html {
|
pub fn EmpathResult(EmpathResultProps { scapegoat, target }: &EmpathResultProps) -> Html {
|
||||||
let text = match scapegoat {
|
let text = match scapegoat {
|
||||||
true => "THE SCAPEGOAT",
|
true => "IS THE SCAPEGOAT",
|
||||||
false => "NOT THE SCAPEGOAT",
|
false => "IS NOT THE SCAPEGOAT",
|
||||||
};
|
};
|
||||||
let icon = match scapegoat {
|
let icon = match scapegoat {
|
||||||
true => html! {
|
true => html! {
|
||||||
<Icon
|
<Icon
|
||||||
source={IconSource::Scapegoat}
|
source={IconSource::Scapegoat} icon_type={IconType::Informational}
|
||||||
/>
|
/>
|
||||||
},
|
},
|
||||||
false => html! {
|
false => html! {
|
||||||
<Icon
|
<Icon
|
||||||
source={IconSource::RedX}
|
source={IconSource::RedX} icon_type={IconType::Informational}
|
||||||
/>
|
/>
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -58,11 +60,9 @@ pub fn EmpathResult(EmpathResultProps { scapegoat }: &EmpathResultProps) -> Html
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="intel">{"EMPATH"}</h1>
|
<h1 class="intel">{"EMPATH"}</h1>
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
<h2>{"YOUR TARGET IS"}</h2>
|
<IdentitySpan ident={target.clone()}/>
|
||||||
<div class="info-icon-grow">
|
|
||||||
{icon}
|
{icon}
|
||||||
</div>
|
<span class="yellow">{text}</span>
|
||||||
<h3 class="yellow">{text}</h3>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
use convert_case::{Case, Casing};
|
use convert_case::{Case, Casing};
|
||||||
use werewolves_proto::role::RoleTitle;
|
use werewolves_proto::{message::PublicIdentity, role::RoleTitle};
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Icon, IconSource, PartialAssociatedIcon};
|
use crate::components::{Icon, IconSource, IconType, IdentitySpan, PartialAssociatedIcon};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn GravediggerPage1() -> Html {
|
pub fn GravediggerPage1() -> Html {
|
||||||
|
|
@ -24,46 +24,45 @@ pub fn GravediggerPage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="intel">{"GRAVEDIGGER"}</h1>
|
<h1 class="intel">{"GRAVEDIGGER"}</h1>
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
<h2>
|
<span>
|
||||||
{"PICK A "}
|
{"PICK A "}
|
||||||
<span class="yellow">{"DEAD"}</span>
|
<span class="yellow">{"DEAD"}</span>
|
||||||
{" PLAYER"}
|
{" PLAYER"}
|
||||||
</h2>
|
</span>
|
||||||
<div class="info-icon-grow">
|
<Icon source={IconSource::Gravedigger} icon_type={IconType::Informational}/>
|
||||||
<Icon source={IconSource::Gravedigger}/>
|
<span class="yellow">
|
||||||
</div>
|
|
||||||
<h3 class="yellow">
|
|
||||||
{"YOU WILL LEARN THEIR ROLE"}
|
{"YOU WILL LEARN THEIR ROLE"}
|
||||||
</h3>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||||
pub struct GravediggerResultPageProps {
|
pub struct GravediggerResultPageProps {
|
||||||
pub role: Option<RoleTitle>,
|
pub role: Option<RoleTitle>,
|
||||||
|
pub target: PublicIdentity,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn GravediggerResultPage(
|
pub fn GravediggerResultPage(
|
||||||
GravediggerResultPageProps { role }: &GravediggerResultPageProps,
|
GravediggerResultPageProps { role, target }: &GravediggerResultPageProps,
|
||||||
) -> Html {
|
) -> Html {
|
||||||
let text = role
|
let text = role
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|r| {
|
.map(|r| {
|
||||||
html! {
|
html! {
|
||||||
<h4>
|
<>
|
||||||
{"AND FIND A "}
|
{"WAS A "}
|
||||||
<span class="yellow">
|
<span class="yellow">
|
||||||
{r.to_string().to_case(Case::Upper)}
|
{r.to_string().to_case(Case::Upper)}
|
||||||
</span>
|
</span>
|
||||||
</h4>
|
</>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
html! {
|
html! {
|
||||||
<h4>{"BUT INSTEAD YOU FIND AN EMPTY GRAVE"}</h4>
|
{"YOU FIND AN EMPTY GRAVE"}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let icon = role
|
let icon = role
|
||||||
|
|
@ -74,10 +73,8 @@ pub fn GravediggerResultPage(
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="intel">{"GRAVEDIGGER"}</h1>
|
<h1 class="intel">{"GRAVEDIGGER"}</h1>
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
<h2>{"YOU CHECK THE ROLE OF YOUR TARGET"}</h2>
|
<IdentitySpan ident={target.clone()}/>
|
||||||
<div class="info-icon-grow">
|
<Icon source={icon} icon_type={IconType::Informational}/>
|
||||||
<Icon source={icon} />
|
|
||||||
</div>
|
|
||||||
{text}
|
{text}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
use werewolves_proto::message::CharacterIdentity;
|
use werewolves_proto::message::CharacterIdentity;
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{CharacterTargetCard, Icon, IconSource};
|
use crate::components::{CharacterTargetCard, Icon, IconSource, IconType};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Properties)]
|
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||||
pub struct GuardianPageProps {
|
pub struct GuardianPageProps {
|
||||||
|
|
@ -28,11 +28,9 @@ pub fn GuardianPageNoPrevProtect() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="defensive">{"GUARDIAN"}</h1>
|
<h1 class="defensive">{"GUARDIAN"}</h1>
|
||||||
<div class="information defensive faint">
|
<div class="information defensive faint">
|
||||||
<h2>{"PICK A PLAYER"}</h2>
|
{"PICK A PLAYER"}
|
||||||
<div class="info-icon-grow">
|
<Icon source={IconSource::ShieldAndSword} icon_type={IconType::Informational}/>
|
||||||
<Icon source={IconSource::ShieldAndSword}/>
|
<span class="yellow">{"CHOOSE SOMEONE TO PROTECT FROM DEATH"}</span>
|
||||||
</div>
|
|
||||||
<h3 class="yellow">{"CHOOSE SOMEONE TO PROTECT FROM DEATH"}</h3>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
@ -44,8 +42,8 @@ pub fn GuardianPagePreviousProtectSelf() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="defensive">{"GUARDIAN"}</h1>
|
<h1 class="defensive">{"GUARDIAN"}</h1>
|
||||||
<div class="information defensive faint">
|
<div class="information defensive faint">
|
||||||
<h2>{"LAST TIME YOU PROTECTED YOURSELF"}</h2>
|
{"LAST TIME YOU PROTECTED YOURSELF"}
|
||||||
<h3 class="yellow">{"YOU CANNOT PROTECT YOURSELF AGAIN TONIGHT"}</h3>
|
<span class="yellow">{"YOU CANNOT PROTECT YOURSELF AGAIN TONIGHT"}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
@ -57,14 +55,12 @@ pub fn GuardianPagePreviousProtect1(GuardianPageProps { previous }: &GuardianPag
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="defensive">{"GUARDIAN"}</h1>
|
<h1 class="defensive">{"GUARDIAN"}</h1>
|
||||||
<div class="information defensive faint">
|
<div class="information defensive faint">
|
||||||
<h2>{"LAST TIME YOU PROTECTED"}</h2>
|
{"LAST TIME YOU PROTECTED"}
|
||||||
<div class="info-icon-grow">
|
<Icon source={IconSource::ShieldAndSword} icon_type={IconType::Informational}/>
|
||||||
<Icon source={IconSource::ShieldAndSword} />
|
|
||||||
</div>
|
|
||||||
<div class="info-player-list">
|
<div class="info-player-list">
|
||||||
<CharacterTargetCard ident={previous.clone()} />
|
<CharacterTargetCard ident={previous.clone()} />
|
||||||
</div>
|
</div>
|
||||||
<h3 class="yellow">{"IF YOU PROTECT THEM AGAIN, YOU WILL INSTEAD GUARD THEM"}</h3>
|
<span class="yellow">{"IF YOU PROTECT THEM AGAIN, YOU WILL INSTEAD GUARD THEM"}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
@ -76,14 +72,12 @@ pub fn GuardianPagePreviousProtect2(GuardianPageProps { previous }: &GuardianPag
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="defensive">{"GUARDIAN"}</h1>
|
<h1 class="defensive">{"GUARDIAN"}</h1>
|
||||||
<div class="information defensive faint">
|
<div class="information defensive faint">
|
||||||
<h2>{"LAST TIME YOU PROTECTED"}</h2>
|
{"LAST TIME YOU PROTECTED"}
|
||||||
<div class="info-icon-grow">
|
<Icon source={IconSource::ShieldAndSword} icon_type={IconType::Informational}/>
|
||||||
<Icon source={IconSource::ShieldAndSword} />
|
|
||||||
</div>
|
|
||||||
<div class="info-player-list">
|
<div class="info-player-list">
|
||||||
<CharacterTargetCard ident={previous.clone()} />
|
<CharacterTargetCard ident={previous.clone()} />
|
||||||
</div>
|
</div>
|
||||||
<h3 class="yellow">{"IF ATTACKED WHILE GUARDED, YOU AND THEIR ATTACKER WILL INSTEAD DIE"}</h3>
|
<span class="yellow">{"IF ATTACKED WHILE GUARDED, YOU AND THEIR ATTACKER WILL INSTEAD DIE"}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
@ -95,14 +89,12 @@ pub fn GuardianPagePreviousGuard(GuardianPageProps { previous }: &GuardianPagePr
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="defensive">{"GUARDIAN"}</h1>
|
<h1 class="defensive">{"GUARDIAN"}</h1>
|
||||||
<div class="information defensive faint">
|
<div class="information defensive faint">
|
||||||
<h2>{"LAST TIME YOU GUARDED"}</h2>
|
{"LAST TIME YOU GUARDED"}
|
||||||
<div class="info-icon-grow">
|
<Icon source={IconSource::ShieldAndSword} icon_type={IconType::Informational}/>
|
||||||
<Icon source={IconSource::ShieldAndSword} />
|
|
||||||
</div>
|
|
||||||
<div class="info-player-list">
|
<div class="info-player-list">
|
||||||
<CharacterTargetCard ident={previous.clone()} />
|
<CharacterTargetCard ident={previous.clone()} />
|
||||||
</div>
|
</div>
|
||||||
<h3 class="yellow">{"YOU CANNOT PROTECT THEM TONIGHT"}</h3>
|
<span class="yellow">{"YOU CANNOT PROTECT THEM TONIGHT"}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Icon, IconSource};
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn HunterPage1() -> Html {
|
pub fn HunterPage1() -> Html {
|
||||||
|
|
@ -22,14 +22,12 @@ pub fn HunterPage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="offensive">{"HUNTER"}</h1>
|
<h1 class="offensive">{"HUNTER"}</h1>
|
||||||
<div class="information offensive faint">
|
<div class="information offensive faint">
|
||||||
<h2>{"SET A HUNTER'S TRAP ON A PLAYER"}</h2>
|
{"SET A HUNTER'S TRAP ON A PLAYER"}
|
||||||
<div class="info-icon-grow">
|
<Icon source={IconSource::Hunter} icon_type={IconType::Informational}/>
|
||||||
<Icon source={IconSource::Hunter}/>
|
<span class="yellow">
|
||||||
</div>
|
|
||||||
<h3 class="yellow">
|
|
||||||
{"IF YOU DIE TONIGHT, OR ARE EXECUTED TOMORROW "}
|
{"IF YOU DIE TONIGHT, OR ARE EXECUTED TOMORROW "}
|
||||||
{"THIS PLAYER WILL DIE AT NIGHT"}
|
{"THIS PLAYER WILL DIE AT NIGHT"}
|
||||||
</h3>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
use werewolves_proto::message::night::Visits;
|
use werewolves_proto::message::night::Visits;
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{CharacterTargetCard, Icon, IconSource, Identity};
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn InsomniacPage1() -> Html {
|
pub fn InsomniacPage1() -> Html {
|
||||||
|
|
@ -23,13 +23,9 @@ pub fn InsomniacPage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="intel">{"INSOMNIAC"}</h1>
|
<h1 class="intel">{"INSOMNIAC"}</h1>
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
<h2>{"YOUR SLEEP IS INTERRUPTED"}</h2>
|
{"YOUR SLEEP IS INTERRUPTED"}
|
||||||
<div class="info-icon-grow">
|
<Icon source={IconSource::Insomniac} icon_type={IconType::Informational}/>
|
||||||
<Icon source={IconSource::Insomniac}/>
|
{"YOU'VE NOTICED VISITORS IN THE NIGHT"}
|
||||||
</div>
|
|
||||||
<h3 class="yellow">
|
|
||||||
{"THE FOLLOWING PEOPLE VISITED YOU TONIGHT"}
|
|
||||||
</h3>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
@ -57,7 +53,7 @@ pub fn InsomniacResult(InsomniacResultProps { visits }: &InsomniacResultProps) -
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="intel">{"INSOMNIAC"}</h1>
|
<h1 class="intel">{"INSOMNIAC"}</h1>
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
<h2>{"YOU WERE VISITED IN THE NIGHT BY:"}</h2>
|
{"YOU WERE VISITED IN THE NIGHT BY:"}
|
||||||
<div class="info-player-boxes">
|
<div class="info-player-boxes">
|
||||||
{visitors}
|
{visitors}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,13 @@ pub fn LoneWolfPage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="wolves">{"LONE WOLF"}</h1>
|
<h1 class="wolves">{"LONE WOLF"}</h1>
|
||||||
<div class="information wolves faint">
|
<div class="information wolves faint">
|
||||||
<h2>
|
<span>
|
||||||
{"YOU MUST KILL TONIGHT IN ANGER OVER A FELLOW "}
|
{"YOU MUST KILL TONIGHT IN ANGER OVER A FELLOW "}
|
||||||
{"WOLF HAVING BEEN SLAIN"}
|
{"WOLF HAVING BEEN SLAIN"}
|
||||||
</h2>
|
</span>
|
||||||
<h3 class="yellow">
|
<span class="yellow">
|
||||||
{"POINT AT YOUR TARGET "}
|
{"PICK A PLAYER"}
|
||||||
</h3>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,10 @@ pub fn MapleWolfPage1(
|
||||||
) -> Html {
|
) -> Html {
|
||||||
let food_state = if *nights_til_starvation == 0 {
|
let food_state = if *nights_til_starvation == 0 {
|
||||||
html! {
|
html! {
|
||||||
<div>
|
<>
|
||||||
<h3 class="red">{"YOU ARE STARVING"}</h3>
|
<span class="red">{"YOU ARE STARVING"}</span>
|
||||||
<h3>{"IF YOU FAIL TO EAT TONIGHT, YOU WILL DIE"}</h3>
|
{"IF YOU FAIL TO EAT TONIGHT, YOU WILL DIE"}
|
||||||
</div>
|
</>
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let nights = if *nights_til_starvation == 1 {
|
let nights = if *nights_til_starvation == 1 {
|
||||||
|
|
@ -49,23 +49,19 @@ pub fn MapleWolfPage1(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
html! {
|
html! {
|
||||||
<h3>
|
<span>
|
||||||
{"IF YOU FAIL TO EAT "}
|
{"IF YOU FAIL TO EAT "}
|
||||||
{nights}
|
{nights}
|
||||||
{"YOU WILL "}<span class="yellow">{"STARVE"}</span>
|
{"YOU WILL "}<span class="yellow">{"STARVE"}</span>
|
||||||
</h3>
|
</span>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
html! {
|
html! {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="offensive">{"MAPLE WOLF"}</h1>
|
<h1 class="offensive">{"MAPLE WOLF"}</h1>
|
||||||
<div class="information offensive faint">
|
<div class="information offensive faint">
|
||||||
<h2>
|
|
||||||
{"YOU CAN CHOOSE TO EAT A PLAYER TONIGHT"}
|
{"YOU CAN CHOOSE TO EAT A PLAYER TONIGHT"}
|
||||||
</h2>
|
|
||||||
<div class="info-icon-grow">
|
|
||||||
<Icon source={IconSource::MapleWolf} icon_type={IconType::Fit}/>
|
<Icon source={IconSource::MapleWolf} icon_type={IconType::Fit}/>
|
||||||
</div>
|
|
||||||
{food_state}
|
{food_state}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -47,13 +47,23 @@ pub fn MasonRecruitPage1(
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="intel">{"MASON LEADER"}</h1>
|
<h1 class="intel">{"MASON LEADER"}</h1>
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
<h2>{"YOU HAVE "}{recruitments}{" LEFT"}</h2>
|
<span>{"YOU HAVE "}{recruitments}{" LEFT"}</span>
|
||||||
<h4>
|
<span>
|
||||||
{"ANYONE YOU RECRUIT INTO THE MASONS WILL WAKE WITH YOU "}
|
{"RECRUITS WILL WAKE WITH YOU EVERY NIGHT"}
|
||||||
<span class="yellow">{"EVERY NIGHT"}</span>
|
{" WHILE THEY ARE ALIVE AND REMAIN VILLAGE ALIGNED"}
|
||||||
{", AS LONG AS THEY ARE ALIVE AND REMAIN VILLAGE ALIGNED"}
|
</span>
|
||||||
</h4>
|
</div>
|
||||||
<h2 class="yellow">{"WOULD YOU LIKE TO RECRUIT TONIGHT?"}</h2>
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn MasonRecruitPage2() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="intel">{"MASON LEADER"}</h1>
|
||||||
|
<div class="information intel faint">
|
||||||
|
<span class="yellow">{"WOULD YOU LIKE TO RECRUIT TONIGHT?"}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
@ -85,7 +95,7 @@ pub fn MasonsWake(MasonsWakeProps { leader, masons }: &MasonsWakeProps) -> Html
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="intel">{title}</h1>
|
<h1 class="intel">{title}</h1>
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
<h2>{"YOU ARE ALL MEMBERS "}</h2>
|
{"THE MASONS CONVENE AT NIGHT"}
|
||||||
<div class="info-player-list masons">
|
<div class="info-player-list masons">
|
||||||
{masons}
|
{masons}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Icon, IconSource};
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn MilitiaPage1() -> Html {
|
pub fn MilitiaPage1() -> Html {
|
||||||
|
|
@ -22,18 +22,16 @@ pub fn MilitiaPage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="offensive">{"MILITIA"}</h1>
|
<h1 class="offensive">{"MILITIA"}</h1>
|
||||||
<div class="information offensive faint">
|
<div class="information offensive faint">
|
||||||
<h2>
|
<span>
|
||||||
{"IF YOU WISH TO USE YOUR "}
|
{"IF YOU WISH TO USE YOUR "}
|
||||||
<span class="yellow">{"ONCE PER GAME"}</span>
|
<span class="yellow">{"ONCE PER GAME"}</span>
|
||||||
{" KILL ABILITY"}
|
{" KILL ABILITY"}
|
||||||
</h2>
|
</span>
|
||||||
<div class="info-icon-grow">
|
<Icon source={IconSource::Sword} icon_type={IconType::Informational}/>
|
||||||
<Icon source={IconSource::Sword}/>
|
<span class="yellow">
|
||||||
</div>
|
{"PICK A PLAYER "}
|
||||||
<h3 class="yellow">
|
|
||||||
{"POINT AT YOUR TARGET "}
|
|
||||||
{"OR GO BACK TO SLEEP"}
|
{"OR GO BACK TO SLEEP"}
|
||||||
</h3>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
use werewolves_proto::diedto::DiedToTitle;
|
use werewolves_proto::{diedto::DiedToTitle, message::PublicIdentity};
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Icon, IconSource, IconType, PartialAssociatedIcon};
|
use crate::components::{Icon, IconSource, IconType, IdentitySpan, PartialAssociatedIcon};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn MorticianPage1() -> Html {
|
pub fn MorticianPage1() -> Html {
|
||||||
|
|
@ -23,31 +23,26 @@ pub fn MorticianPage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="intel">{"MORTICIAN"}</h1>
|
<h1 class="intel">{"MORTICIAN"}</h1>
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
<h2>
|
<span>{"PICK A "}<span class="yellow">{"DEAD"}</span>{" PLAYER"}</span>
|
||||||
{"PICK A "}
|
<Icon source={IconSource::Mortician} icon_type={IconType::Informational}/>
|
||||||
<span class="yellow">{"DEAD"}</span>
|
<span class="yellow">
|
||||||
{" PLAYER"}
|
|
||||||
</h2>
|
|
||||||
<div class="info-icon-grow">
|
|
||||||
<Icon source={IconSource::Mortician}/>
|
|
||||||
</div>
|
|
||||||
<h3 class="yellow">
|
|
||||||
{"YOU WILL LEARN THE CAUSE "}
|
{"YOU WILL LEARN THE CAUSE "}
|
||||||
{"OF THEIR DEATH"}
|
{"OF THEIR DEATH"}
|
||||||
</h3>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||||
pub struct MorticianResultPageProps {
|
pub struct MorticianResultPageProps {
|
||||||
pub died_to: DiedToTitle,
|
pub died_to: DiedToTitle,
|
||||||
|
pub target: PublicIdentity,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn MorticianResultPage(
|
pub fn MorticianResultPage(
|
||||||
MorticianResultPageProps { died_to }: &MorticianResultPageProps,
|
MorticianResultPageProps { died_to, target }: &MorticianResultPageProps,
|
||||||
) -> Html {
|
) -> Html {
|
||||||
let text = match died_to {
|
let text = match died_to {
|
||||||
DiedToTitle::Execution => "Execution",
|
DiedToTitle::Execution => "Execution",
|
||||||
|
|
@ -69,11 +64,10 @@ pub fn MorticianResultPage(
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="intel">{"MORTICIAN"}</h1>
|
<h1 class="intel">{"MORTICIAN"}</h1>
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
<h2>{"YOUR TARGET DIED TO"}</h2>
|
<IdentitySpan ident={target.clone()}/>
|
||||||
<div class="info-icon-grow">
|
{"DIED TO"}
|
||||||
<Icon source={icon}/>
|
<Icon source={icon} icon_type={IconType::Informational}/>
|
||||||
</div>
|
<span class="yellow">{text}</span>
|
||||||
<h3 class="yellow">{text}</h3>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use werewolves_proto::role::Powerful;
|
use werewolves_proto::{message::PublicIdentity, role::Powerful};
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Icon, IconSource};
|
use crate::components::{Icon, IconSource, IdentitySpan};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn PowerSeerPage1() -> Html {
|
pub fn PowerSeerPage1() -> Html {
|
||||||
|
|
@ -24,38 +24,37 @@ pub fn PowerSeerPage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="intel">{"POWER SEER"}</h1>
|
<h1 class="intel">{"POWER SEER"}</h1>
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
<h2>{"PICK A PLAYER"}</h2>
|
{"PICK A PLAYER"}
|
||||||
<div class="info-icon-grow">
|
<div class="info-icon-grow">
|
||||||
<Icon source={IconSource::Powerful} />
|
<Icon source={IconSource::Powerful} />
|
||||||
</div>
|
</div>
|
||||||
<h3 class="yellow">{"YOU WILL CHECK IF THEY ARE POWERFUL"}</h3>
|
<span class="yellow">{"YOU WILL CHECK IF THEY ARE POWERFUL"}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||||
pub struct PowerSeerResultProps {
|
pub struct PowerSeerResultProps {
|
||||||
pub powerful: Powerful,
|
pub powerful: Powerful,
|
||||||
|
pub target: PublicIdentity,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn PowerSeerResult(PowerSeerResultProps { powerful }: &PowerSeerResultProps) -> Html {
|
pub fn PowerSeerResult(PowerSeerResultProps { powerful, target }: &PowerSeerResultProps) -> Html {
|
||||||
let text = match powerful {
|
let text = match powerful {
|
||||||
Powerful::Powerful => "POWERFUL",
|
Powerful::Powerful => "IS POWERFUL",
|
||||||
Powerful::NotPowerful => "NOT POWERFUL",
|
Powerful::NotPowerful => "IS NOT POWERFUL",
|
||||||
};
|
};
|
||||||
let icon = match powerful {
|
let icon = match powerful {
|
||||||
Powerful::Powerful => html! {
|
Powerful::Powerful => html! {
|
||||||
<Icon
|
<Icon
|
||||||
source={IconSource::Powerful}
|
source={IconSource::Powerful}
|
||||||
// icon_type={IconType::Informational}
|
|
||||||
/>
|
/>
|
||||||
},
|
},
|
||||||
Powerful::NotPowerful => html! {
|
Powerful::NotPowerful => html! {
|
||||||
<Icon
|
<Icon
|
||||||
source={IconSource::RedX}
|
source={IconSource::RedX}
|
||||||
// icon_type={IconType::Informational}
|
|
||||||
/>
|
/>
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -63,7 +62,7 @@ pub fn PowerSeerResult(PowerSeerResultProps { powerful }: &PowerSeerResultProps)
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="intel">{"POWER SEER"}</h1>
|
<h1 class="intel">{"POWER SEER"}</h1>
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
<h2>{"YOUR TARGET APPEARS AS"}</h2>
|
<IdentitySpan ident={target.clone()}/>
|
||||||
<div class="info-icon-grow">{icon}</div>
|
<div class="info-icon-grow">{icon}</div>
|
||||||
<h3 class="yellow">{text}</h3>
|
<h3 class="yellow">{text}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Icon, IconSource};
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn ProtectorPage1() -> Html {
|
pub fn ProtectorPage1() -> Html {
|
||||||
|
|
@ -22,11 +22,9 @@ pub fn ProtectorPage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="defensive">{"PROTECTOR"}</h1>
|
<h1 class="defensive">{"PROTECTOR"}</h1>
|
||||||
<div class="information defensive faint">
|
<div class="information defensive faint">
|
||||||
<h2>{"PICK A PLAYER"}</h2>
|
{"PICK A PLAYER"}
|
||||||
<div class="info-icon-grow">
|
<Icon source={IconSource::Shield} icon_type={IconType::Informational}/>
|
||||||
<Icon source={IconSource::Shield} />
|
<span class="yellow">{"YOU WILL PROTECT THEM FROM A DEATH TONIGHT"}</span>
|
||||||
</div>
|
|
||||||
<h3 class="yellow">{"YOU WILL PROTECT THEM FROM A DEATH TONIGHT"}</h3>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Icon, IconSource};
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn PyremasterPage1() -> Html {
|
pub fn PyremasterPage1() -> Html {
|
||||||
|
|
@ -22,16 +22,14 @@ pub fn PyremasterPage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="offensive">{"PYREMASTER"}</h1>
|
<h1 class="offensive">{"PYREMASTER"}</h1>
|
||||||
<div class="information offensive faint">
|
<div class="information offensive faint">
|
||||||
<h3>{"YOU CAN CHOOSE TO THROW A PLAYER ON THE PYRE"}</h3>
|
{"YOU CAN CHOOSE TO THROW A PLAYER ON THE PYRE"}
|
||||||
<div class="info-icon-grow">
|
<Icon source={IconSource::Pyremaster} icon_type={IconType::Informational}/>
|
||||||
<Icon source={IconSource::Pyremaster}/>
|
<span>
|
||||||
</div>
|
|
||||||
<h3>
|
|
||||||
{"IF YOU KILL "}
|
{"IF YOU KILL "}
|
||||||
<span class="yellow">{"TWO"}</span>
|
<span class="yellow">{"TWO"}</span>
|
||||||
{" GOOD VILLAGERS LIKE THIS "}
|
{" GOOD VILLAGERS LIKE THIS "}
|
||||||
{"YOU WILL DIE AS WELL"}
|
{"YOU WILL DIE AS WELL"}
|
||||||
</h3>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,15 @@
|
||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
use werewolves_proto::role::{Alignment, RoleTitle};
|
use werewolves_proto::{
|
||||||
|
message::PublicIdentity,
|
||||||
|
role::{Alignment, RoleTitle},
|
||||||
|
};
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{AssociatedIcon, Icon, IconSource, IconType, attributes::RoleTitleSpan};
|
use crate::components::{
|
||||||
|
AssociatedIcon, Icon, IconSource, IconType, IdentitySpan, attributes::RoleTitleSpan,
|
||||||
|
};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn SeerPage1() -> Html {
|
pub fn SeerPage1() -> Html {
|
||||||
|
|
@ -23,24 +28,25 @@ pub fn SeerPage1() -> 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">
|
||||||
<h2>{"PICK A PLAYER"}</h2>
|
{"PICK A PLAYER"}
|
||||||
<div class="info-icon-list-grow">
|
<div class="icons">
|
||||||
<Icon source={IconSource::Village} />
|
<Icon source={IconSource::Village} icon_type={IconType::Informational} />
|
||||||
<Icon source={IconSource::Wolves} />
|
<Icon source={IconSource::Wolves} icon_type={IconType::Informational} />
|
||||||
</div>
|
</div>
|
||||||
<h3 class="yellow">{"YOU WILL CHECK IF THEY APPEAR AS A VILLAGER OR PART OF THE WOLFPACK"}</h3>
|
<span class="yellow">{"YOU WILL CHECK THEIR ALIGNMENT"}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||||
pub struct SeerResultProps {
|
pub struct SeerResultProps {
|
||||||
pub alignment: Alignment,
|
pub alignment: Alignment,
|
||||||
|
pub target: PublicIdentity,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn SeerResult(SeerResultProps { alignment }: &SeerResultProps) -> Html {
|
pub fn SeerResult(SeerResultProps { alignment, target }: &SeerResultProps) -> Html {
|
||||||
let text = match alignment {
|
let text = match alignment {
|
||||||
Alignment::Village => "VILLAGE",
|
Alignment::Village => "VILLAGE",
|
||||||
Alignment::Wolves => "WOLFPACK",
|
Alignment::Wolves => "WOLFPACK",
|
||||||
|
|
@ -61,11 +67,9 @@ pub fn SeerResult(SeerResultProps { alignment }: &SeerResultProps) -> Html {
|
||||||
},
|
},
|
||||||
Alignment::Traitor => html! {
|
Alignment::Traitor => html! {
|
||||||
<div class="bottom-bound">
|
<div class="bottom-bound">
|
||||||
<h1>
|
|
||||||
{"THIS PERSON IS A "}
|
{"THIS PERSON IS A "}
|
||||||
<span class="yellow">{"TRAITOR"}</span>
|
<span class="yellow">{"TRAITOR"}</span>
|
||||||
</h1>
|
{"THEY WIN ALONGSIDE EVIL"}
|
||||||
<h3>{"THEY WIN ALONGSIDE EVIL"}</h3>
|
|
||||||
</div>
|
</div>
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -75,11 +79,9 @@ pub fn SeerResult(SeerResultProps { alignment }: &SeerResultProps) -> Html {
|
||||||
<div class="information intel faint">
|
<div class="information intel faint">
|
||||||
<div class="two-column">
|
<div class="two-column">
|
||||||
<div class="seer-check">
|
<div class="seer-check">
|
||||||
<h2>{"YOUR TARGET APPEARS AS"}</h2>
|
<IdentitySpan ident={target.clone()}/>
|
||||||
<Icon
|
<Icon source={alignment.icon()}/>
|
||||||
source={alignment.icon()}
|
<span class="yellow">{text}</span>
|
||||||
/>
|
|
||||||
<h3 class="yellow">{text}</h3>
|
|
||||||
</div>
|
</div>
|
||||||
{additional_info}
|
{additional_info}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -106,16 +108,15 @@ fn FalselyAppearsAs(
|
||||||
.copied()
|
.copied()
|
||||||
.map(|role| {
|
.map(|role| {
|
||||||
html! {
|
html! {
|
||||||
<RoleTitleSpan role={role} icon_type={IconType::Icon15Pct}/>
|
<RoleTitleSpan role={role} //icon_type={IconType::Icon15Pct}
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Html>();
|
.collect::<Html>();
|
||||||
html! {
|
html! {
|
||||||
<div class="bottom-bound">
|
<div class="bottom-bound">
|
||||||
<h5>
|
|
||||||
{"ROLES THAT FALSELY APPEAR AS "}
|
{"ROLES THAT FALSELY APPEAR AS "}
|
||||||
<span class="yellow">{*alignment_text}</span>
|
<span class="yellow">{*alignment_text}</span>
|
||||||
</h5>
|
|
||||||
<div class="false-positives yellow">
|
<div class="false-positives yellow">
|
||||||
{false_positives}
|
{false_positives}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Icon, IconSource};
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn VindicatorPage1() -> Html {
|
pub fn VindicatorPage1() -> Html {
|
||||||
|
|
@ -22,12 +22,9 @@ pub fn VindicatorPage1() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="defensive">{"VINDICATOR"}</h1>
|
<h1 class="defensive">{"VINDICATOR"}</h1>
|
||||||
<div class="information defensive faint">
|
<div class="information defensive faint">
|
||||||
<h3>{"A VILLAGER WAS EXECUTED"}</h3>
|
<span>{"A VILLAGER WAS EXECUTED"}</span>
|
||||||
<h2>{"PICK A PLAYER"}</h2>
|
<Icon source={IconSource::Vindicator} icon_type={IconType::Fit}/>
|
||||||
<div class="info-icon-grow">
|
<span class="yellow">{"PICK A PLAYER TO PROTECT FROM A DEATH TONIGHT"}</span>
|
||||||
<Icon source={IconSource::Vindicator} />
|
|
||||||
</div>
|
|
||||||
<h3 class="yellow">{"YOU WILL PROTECT THEM FROM A DEATH TONIGHT"}</h3>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Icon, IconSource};
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn RoleblockPage() -> Html {
|
pub fn RoleblockPage() -> Html {
|
||||||
|
|
@ -22,11 +22,9 @@ pub fn RoleblockPage() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="wolves">{"ROLE BLOCKED"}</h1>
|
<h1 class="wolves">{"ROLE BLOCKED"}</h1>
|
||||||
<div class="information wolves faint">
|
<div class="information wolves faint">
|
||||||
<h2>{"YOU WERE ROLE BLOCKED"}</h2>
|
{"YOU WERE ROLE BLOCKED"}
|
||||||
<div class="info-icon-grow">
|
<Icon source={IconSource::Roleblock} icon_type={IconType::Informational}/>
|
||||||
<Icon source={IconSource::Roleblock} />
|
<span class="yellow">{"YOUR NIGHT ACTION DID NOT TAKE PLACE"}</span>
|
||||||
</div>
|
|
||||||
<h3 class="yellow">{"YOUR NIGHT ACTION DID NOT TAKE PLACE"}</h3>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Icon, IconSource};
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn ShiftFailed() -> Html {
|
pub fn ShiftFailed() -> Html {
|
||||||
|
|
@ -22,13 +22,9 @@ pub fn ShiftFailed() -> Html {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="wolves">{"SHIFT FAILED"}</h1>
|
<h1 class="wolves">{"SHIFT FAILED"}</h1>
|
||||||
<div class={classes!("information", "wolves", "faint")}>
|
<div class={classes!("information", "wolves", "faint")}>
|
||||||
<h2>{"YOUR SHIFT HAS FAILED"}</h2>
|
{"YOUR SHIFT HAS FAILED"}
|
||||||
<div class="info-icon-grow">
|
<Icon source={IconSource::RedX} icon_type={IconType::Informational}/>
|
||||||
<Icon source={IconSource::RedX}/>
|
|
||||||
</div>
|
|
||||||
<h3>
|
|
||||||
{"YOU RETAIN YOUR SHAPESHIFT ABILITY"}
|
{"YOU RETAIN YOUR SHAPESHIFT ABILITY"}
|
||||||
</h3>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,30 @@
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Icon, IconSource};
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn TraitorIntroPage() -> Html {
|
pub fn TraitorIntroPage1() -> Html {
|
||||||
html! {
|
html! {
|
||||||
<div class="role-page">
|
<div class="role-page">
|
||||||
<h1 class="traitor">{"TRAITOR"}</h1>
|
<h1 class="traitor">{"DAMNED"}</h1>
|
||||||
<div class="information traitor faint">
|
<div class="information traitor faint">
|
||||||
<h2>{"YOU ARE A TRAITOR"}</h2>
|
<span class="yellow">{"YOU ARE DAMNED"}</span>
|
||||||
<h3>{"YOU RETAIN YOUR ROLE AND WIN IF EVIL WINS"}</h3>
|
<Icon source={IconSource::Traitor} icon_type={IconType::Informational}/>
|
||||||
<div class="info-icon-grow">
|
</div>
|
||||||
<Icon source={IconSource::Traitor}/>
|
</div>
|
||||||
</div>
|
}
|
||||||
<h4>{"HOWEVER"}</h4>
|
}
|
||||||
<h2 class="yellow">
|
|
||||||
{"YOU CONTRIBUTE TO VILLAGE PARITY"}
|
#[function_component]
|
||||||
</h2>
|
pub fn TraitorIntroPage2() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="traitor">{"DAMNED"}</h1>
|
||||||
|
<div class="information traitor faint">
|
||||||
|
{"YOU RETAIN YOUR ROLE AND WIN IF EVIL WINS"}
|
||||||
|
<span class="yellow">
|
||||||
|
{"HOWEVER, YOU CONTRIBUTE TO VILLAGE PARITY"}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ pub fn TestScreenSelector(
|
||||||
let class = prompt_class(&prompt);
|
let class = prompt_class(&prompt);
|
||||||
html! {
|
html! {
|
||||||
<li>
|
<li>
|
||||||
<Button on_click={callback} classes={classes!(class, picked_class)}>
|
<Button on_click={callback} classes={classes!(class, picked_class, "hover")}>
|
||||||
{format!("{title:?}")}
|
{format!("{title:?}")}
|
||||||
</Button>
|
</Button>
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -172,7 +172,7 @@ pub fn TestScreenSelector(
|
||||||
let class = result_class(&result);
|
let class = result_class(&result);
|
||||||
html! {
|
html! {
|
||||||
<li>
|
<li>
|
||||||
<Button on_click={callback} classes={classes!(picked_class, class)}>
|
<Button on_click={callback} classes={classes!(picked_class, class, "hover")}>
|
||||||
{format!("{title:?}")}
|
{format!("{title:?}")}
|
||||||
</Button>
|
</Button>
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -225,18 +225,28 @@ impl From<ActionResultTitle> for TestScreen {
|
||||||
TestScreen::Result(match value {
|
TestScreen::Result(match value {
|
||||||
ActionResultTitle::RoleBlocked => ActionResult::RoleBlocked,
|
ActionResultTitle::RoleBlocked => ActionResult::RoleBlocked,
|
||||||
ActionResultTitle::Drunk => ActionResult::Drunk,
|
ActionResultTitle::Drunk => ActionResult::Drunk,
|
||||||
ActionResultTitle::Seer => ActionResult::Seer(Alignment::Village),
|
ActionResultTitle::Seer => ActionResult::Seer(identity(), Alignment::Village),
|
||||||
ActionResultTitle::PowerSeer => ActionResult::PowerSeer {
|
ActionResultTitle::PowerSeer => ActionResult::PowerSeer {
|
||||||
|
target: identity(),
|
||||||
powerful: Powerful::Powerful,
|
powerful: Powerful::Powerful,
|
||||||
},
|
},
|
||||||
ActionResultTitle::Adjudicator => ActionResult::Adjudicator {
|
ActionResultTitle::Adjudicator => ActionResult::Adjudicator {
|
||||||
|
target: identity(),
|
||||||
killer: Killer::Killer,
|
killer: Killer::Killer,
|
||||||
},
|
},
|
||||||
ActionResultTitle::Arcanist => ActionResult::Arcanist(AlignmentEq::Same),
|
ActionResultTitle::Arcanist => ActionResult::Arcanist(
|
||||||
ActionResultTitle::GraveDigger => ActionResult::GraveDigger(None),
|
(identity(), identities(2).last().cloned().unwrap()),
|
||||||
ActionResultTitle::Mortician => ActionResult::Mortician(DiedToTitle::Execution),
|
AlignmentEq::Same,
|
||||||
|
),
|
||||||
|
ActionResultTitle::GraveDigger => ActionResult::GraveDigger(identity(), None),
|
||||||
|
ActionResultTitle::Mortician => {
|
||||||
|
ActionResult::Mortician(identity(), DiedToTitle::Execution)
|
||||||
|
}
|
||||||
ActionResultTitle::Insomniac => ActionResult::Insomniac(Visits::new(identities(2))),
|
ActionResultTitle::Insomniac => ActionResult::Insomniac(Visits::new(identities(2))),
|
||||||
ActionResultTitle::Empath => ActionResult::Empath { scapegoat: true },
|
ActionResultTitle::Empath => ActionResult::Empath {
|
||||||
|
target: identity(),
|
||||||
|
scapegoat: true,
|
||||||
|
},
|
||||||
ActionResultTitle::BeholderSawNothing => ActionResult::BeholderSawNothing,
|
ActionResultTitle::BeholderSawNothing => ActionResult::BeholderSawNothing,
|
||||||
ActionResultTitle::BeholderSawEverything => ActionResult::BeholderSawEverything,
|
ActionResultTitle::BeholderSawEverything => ActionResult::BeholderSawEverything,
|
||||||
ActionResultTitle::GoBackToSleep => ActionResult::GoBackToSleep,
|
ActionResultTitle::GoBackToSleep => ActionResult::GoBackToSleep,
|
||||||
|
|
|
||||||
|
|
@ -49,16 +49,17 @@ pub fn ResultScreenTest(
|
||||||
| ActionResult::Continue
|
| ActionResult::Continue
|
||||||
| ActionResult::Drunk
|
| ActionResult::Drunk
|
||||||
| ActionResult::RoleBlocked => html! {},
|
| ActionResult::RoleBlocked => html! {},
|
||||||
ActionResult::Seer(alignment) => {
|
ActionResult::Seer(target, alignment) => {
|
||||||
let all = Alignment::ALL
|
let all = Alignment::ALL
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|align| {
|
.map(|align| {
|
||||||
let on_click = {
|
let on_click = {
|
||||||
|
let target= target.clone();
|
||||||
let send = send.clone();
|
let send = send.clone();
|
||||||
Callback::from(move |_| {
|
Callback::from(move |_| {
|
||||||
send.emit(ServerToHostMessage::ActionResult(
|
send.emit(ServerToHostMessage::ActionResult(
|
||||||
None,
|
None,
|
||||||
ActionResult::Seer(align),
|
ActionResult::Seer(target.clone(), align),
|
||||||
));
|
));
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
@ -76,14 +77,18 @@ pub fn ResultScreenTest(
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionResult::PowerSeer { powerful } => {
|
ActionResult::PowerSeer { target, powerful } => {
|
||||||
let on_toggle = {
|
let on_toggle = {
|
||||||
let set = !*powerful;
|
let set = !*powerful;
|
||||||
let send = send.clone();
|
let send = send.clone();
|
||||||
|
let target = target.clone();
|
||||||
Callback::from(move |_| {
|
Callback::from(move |_| {
|
||||||
send.emit(ServerToHostMessage::ActionResult(
|
send.emit(ServerToHostMessage::ActionResult(
|
||||||
None,
|
None,
|
||||||
ActionResult::PowerSeer { powerful: set },
|
ActionResult::PowerSeer {
|
||||||
|
target: target.clone(),
|
||||||
|
powerful: set,
|
||||||
|
},
|
||||||
));
|
));
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
@ -98,14 +103,18 @@ pub fn ResultScreenTest(
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionResult::Adjudicator { killer } => {
|
ActionResult::Adjudicator { target, killer } => {
|
||||||
let on_toggle = {
|
let on_toggle = {
|
||||||
let set = !*killer;
|
let set = !*killer;
|
||||||
let send = send.clone();
|
let send = send.clone();
|
||||||
|
let target = target.clone();
|
||||||
Callback::from(move |_| {
|
Callback::from(move |_| {
|
||||||
send.emit(ServerToHostMessage::ActionResult(
|
send.emit(ServerToHostMessage::ActionResult(
|
||||||
None,
|
None,
|
||||||
ActionResult::Adjudicator { killer: set },
|
ActionResult::Adjudicator {
|
||||||
|
target: target.clone(),
|
||||||
|
killer: set,
|
||||||
|
},
|
||||||
));
|
));
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
@ -120,14 +129,15 @@ pub fn ResultScreenTest(
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionResult::Arcanist(alignment_eq) => {
|
ActionResult::Arcanist(targets, alignment_eq) => {
|
||||||
let on_toggle = {
|
let on_toggle = {
|
||||||
let set = !*alignment_eq;
|
let set = !*alignment_eq;
|
||||||
let send = send.clone();
|
let send = send.clone();
|
||||||
|
let targets = targets.clone();
|
||||||
Callback::from(move |_| {
|
Callback::from(move |_| {
|
||||||
send.emit(ServerToHostMessage::ActionResult(
|
send.emit(ServerToHostMessage::ActionResult(
|
||||||
None,
|
None,
|
||||||
ActionResult::Arcanist(set),
|
ActionResult::Arcanist(targets.clone(), set),
|
||||||
));
|
));
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
@ -142,7 +152,7 @@ pub fn ResultScreenTest(
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionResult::GraveDigger(role_title) => {
|
ActionResult::GraveDigger(target, role_title) => {
|
||||||
let possibilities = [None]
|
let possibilities = [None]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(RoleTitle::ALL.into_iter().map(Some))
|
.chain(RoleTitle::ALL.into_iter().map(Some))
|
||||||
|
|
@ -162,6 +172,7 @@ pub fn ResultScreenTest(
|
||||||
let on_change_cb = {
|
let on_change_cb = {
|
||||||
let send = send.clone();
|
let send = send.clone();
|
||||||
let possibilities = possibilities.clone();
|
let possibilities = possibilities.clone();
|
||||||
|
let target = target.clone();
|
||||||
Callback::from(move |ev: Event| {
|
Callback::from(move |ev: Event| {
|
||||||
if let Some(select) = ev.target_dyn_into::<HtmlSelectElement>() {
|
if let Some(select) = ev.target_dyn_into::<HtmlSelectElement>() {
|
||||||
let selected = select.selected_index();
|
let selected = select.selected_index();
|
||||||
|
|
@ -171,7 +182,7 @@ pub fn ResultScreenTest(
|
||||||
if let Some(new_role) = possibilities.get(selected as usize) {
|
if let Some(new_role) = possibilities.get(selected as usize) {
|
||||||
send.emit(ServerToHostMessage::ActionResult(
|
send.emit(ServerToHostMessage::ActionResult(
|
||||||
None,
|
None,
|
||||||
ActionResult::GraveDigger(*new_role),
|
ActionResult::GraveDigger(target.clone(), *new_role),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -179,6 +190,7 @@ pub fn ResultScreenTest(
|
||||||
};
|
};
|
||||||
let on_wheel = {
|
let on_wheel = {
|
||||||
let send = send.clone();
|
let send = send.clone();
|
||||||
|
let res_target = target.clone();
|
||||||
let possibilities = possibilities.clone();
|
let possibilities = possibilities.clone();
|
||||||
Callback::from(move |ev: WheelEvent| {
|
Callback::from(move |ev: WheelEvent| {
|
||||||
let Some(target) = ev.target_dyn_into::<HtmlSelectElement>() else {
|
let Some(target) = ev.target_dyn_into::<HtmlSelectElement>() else {
|
||||||
|
|
@ -206,7 +218,7 @@ pub fn ResultScreenTest(
|
||||||
if let Some(new_role) = possibilities.get(new_index as usize) {
|
if let Some(new_role) = possibilities.get(new_index as usize) {
|
||||||
send.emit(ServerToHostMessage::ActionResult(
|
send.emit(ServerToHostMessage::ActionResult(
|
||||||
None,
|
None,
|
||||||
ActionResult::GraveDigger(*new_role),
|
ActionResult::GraveDigger(res_target.clone(), *new_role),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -220,7 +232,7 @@ pub fn ResultScreenTest(
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionResult::Mortician(died_to_title) => {
|
ActionResult::Mortician(target, died_to_title) => {
|
||||||
let roles = DiedToTitle::ALL
|
let roles = DiedToTitle::ALL
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|died_to| {
|
.map(|died_to| {
|
||||||
|
|
@ -231,6 +243,7 @@ pub fn ResultScreenTest(
|
||||||
.collect::<Html>();
|
.collect::<Html>();
|
||||||
let on_change_cb = {
|
let on_change_cb = {
|
||||||
let send = send.clone();
|
let send = send.clone();
|
||||||
|
let target = target.clone();
|
||||||
Callback::from(move |ev: Event| {
|
Callback::from(move |ev: Event| {
|
||||||
if let Some(select) = ev.target_dyn_into::<HtmlSelectElement>() {
|
if let Some(select) = ev.target_dyn_into::<HtmlSelectElement>() {
|
||||||
let selected = select.selected_index();
|
let selected = select.selected_index();
|
||||||
|
|
@ -240,7 +253,7 @@ pub fn ResultScreenTest(
|
||||||
if let Some(died_to) = DiedToTitle::ALL.into_iter().nth(selected as _) {
|
if let Some(died_to) = DiedToTitle::ALL.into_iter().nth(selected as _) {
|
||||||
send.emit(ServerToHostMessage::ActionResult(
|
send.emit(ServerToHostMessage::ActionResult(
|
||||||
None,
|
None,
|
||||||
ActionResult::Mortician(died_to),
|
ActionResult::Mortician(target.clone(), died_to),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -248,6 +261,7 @@ pub fn ResultScreenTest(
|
||||||
};
|
};
|
||||||
let on_wheel = {
|
let on_wheel = {
|
||||||
let send = send.clone();
|
let send = send.clone();
|
||||||
|
let res_target = target.clone();
|
||||||
Callback::from(move |ev: WheelEvent| {
|
Callback::from(move |ev: WheelEvent| {
|
||||||
let Some(target) = ev.target_dyn_into::<HtmlSelectElement>() else {
|
let Some(target) = ev.target_dyn_into::<HtmlSelectElement>() else {
|
||||||
return;
|
return;
|
||||||
|
|
@ -274,7 +288,7 @@ pub fn ResultScreenTest(
|
||||||
if let Some(died_to) = DiedToTitle::ALL.into_iter().nth(new_index as _) {
|
if let Some(died_to) = DiedToTitle::ALL.into_iter().nth(new_index as _) {
|
||||||
send.emit(ServerToHostMessage::ActionResult(
|
send.emit(ServerToHostMessage::ActionResult(
|
||||||
None,
|
None,
|
||||||
ActionResult::Mortician(died_to),
|
ActionResult::Mortician(res_target.clone(), died_to),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -335,14 +349,18 @@ pub fn ResultScreenTest(
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionResult::Empath { scapegoat } => {
|
ActionResult::Empath { target, scapegoat } => {
|
||||||
let on_toggle = {
|
let on_toggle = {
|
||||||
let set = !*scapegoat;
|
let set = !*scapegoat;
|
||||||
let send = send.clone();
|
let send = send.clone();
|
||||||
|
let target = target.clone();
|
||||||
Callback::from(move |_| {
|
Callback::from(move |_| {
|
||||||
send.emit(ServerToHostMessage::ActionResult(
|
send.emit(ServerToHostMessage::ActionResult(
|
||||||
None,
|
None,
|
||||||
ActionResult::Empath { scapegoat: set },
|
ActionResult::Empath {
|
||||||
|
scapegoat: set,
|
||||||
|
target: target.clone(),
|
||||||
|
},
|
||||||
));
|
));
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue