Compare commits
2 Commits
9f00d2b912
...
00617afe7b
| Author | SHA1 | Date |
|---|---|---|
|
|
00617afe7b | |
|
|
2075f07bb7 |
|
|
@ -250,7 +250,7 @@ impl Character {
|
||||||
.is_empty()
|
.is_empty()
|
||||||
.not()
|
.not()
|
||||||
.then_some(ActionPrompt::MasonsWake {
|
.then_some(ActionPrompt::MasonsWake {
|
||||||
leader: self.character_id(),
|
leader: self.identity(),
|
||||||
masons: recruits.clone(),
|
masons: recruits.clone(),
|
||||||
})
|
})
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
@ -396,9 +396,20 @@ impl Character {
|
||||||
living_villagers: village.living_players_excluding(self.character_id()),
|
living_villagers: village.living_players_excluding(self.character_id()),
|
||||||
marked: None,
|
marked: None,
|
||||||
},
|
},
|
||||||
Role::DireWolf => ActionPrompt::DireWolf {
|
Role::DireWolf {
|
||||||
|
last_blocked: Some(last_blocked),
|
||||||
|
} => ActionPrompt::DireWolf {
|
||||||
character_id: self.identity(),
|
character_id: self.identity(),
|
||||||
living_players: village.living_players(),
|
living_players: village
|
||||||
|
.living_players_excluding(self.character_id())
|
||||||
|
.into_iter()
|
||||||
|
.filter(|c| c.character_id != *last_blocked)
|
||||||
|
.collect(),
|
||||||
|
marked: None,
|
||||||
|
},
|
||||||
|
Role::DireWolf { .. } => ActionPrompt::DireWolf {
|
||||||
|
character_id: self.identity(),
|
||||||
|
living_players: village.living_players_excluding(self.character_id()),
|
||||||
marked: None,
|
marked: None,
|
||||||
},
|
},
|
||||||
Role::Shapeshifter { shifted_into: None } => ActionPrompt::Shapeshifter {
|
Role::Shapeshifter { shifted_into: None } => ActionPrompt::Shapeshifter {
|
||||||
|
|
@ -718,6 +729,28 @@ impl Character {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const fn direwolf<'a>(&'a self) -> Result<Direwolf<'a>> {
|
||||||
|
let title = self.role.title();
|
||||||
|
match &self.role {
|
||||||
|
Role::DireWolf { last_blocked } => Ok(Direwolf(last_blocked)),
|
||||||
|
_ => Err(GameError::InvalidRole {
|
||||||
|
expected: RoleTitle::DireWolf,
|
||||||
|
got: title,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn direwolf_mut<'a>(&'a mut self) -> Result<DirewolfMut<'a>> {
|
||||||
|
let title = self.role.title();
|
||||||
|
match &mut self.role {
|
||||||
|
Role::DireWolf { last_blocked } => Ok(DirewolfMut(last_blocked)),
|
||||||
|
_ => Err(GameError::InvalidRole {
|
||||||
|
expected: RoleTitle::DireWolf,
|
||||||
|
got: title,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub const fn initial_shown_role(&self) -> RoleTitle {
|
pub const fn initial_shown_role(&self) -> RoleTitle {
|
||||||
self.role.initial_shown_role()
|
self.role.initial_shown_role()
|
||||||
}
|
}
|
||||||
|
|
@ -758,6 +791,7 @@ decl_ref_and_mut!(
|
||||||
Empath, EmpathMut: bool;
|
Empath, EmpathMut: bool;
|
||||||
BlackKnight, BlackKnightMut: Option<DiedTo>;
|
BlackKnight, BlackKnightMut: Option<DiedTo>;
|
||||||
Guardian, GuardianMut: Option<PreviousGuardianAction>;
|
Guardian, GuardianMut: Option<PreviousGuardianAction>;
|
||||||
|
Direwolf, DirewolfMut: Option<CharacterId>;
|
||||||
);
|
);
|
||||||
|
|
||||||
pub struct BlackKnightKill<'a> {
|
pub struct BlackKnightKill<'a> {
|
||||||
|
|
|
||||||
|
|
@ -319,7 +319,7 @@ impl Night {
|
||||||
}
|
}
|
||||||
NightState::Complete => return Err(GameError::NightOver),
|
NightState::Complete => return Err(GameError::NightOver),
|
||||||
};
|
};
|
||||||
if let Some((prompt, _, changes)) = self.used_actions.pop() {
|
if let Some((mut prompt, _, changes)) = self.used_actions.pop() {
|
||||||
// Remove the shapeshifter role change from the queue
|
// Remove the shapeshifter role change from the queue
|
||||||
if let ActionPrompt::Shapeshifter {
|
if let ActionPrompt::Shapeshifter {
|
||||||
character_id: ss_char,
|
character_id: ss_char,
|
||||||
|
|
@ -337,8 +337,9 @@ impl Night {
|
||||||
// put it back in
|
// put it back in
|
||||||
self.action_queue.push_front(next);
|
self.action_queue.push_front(next);
|
||||||
}
|
}
|
||||||
// panic!("{:#?}", self.action_queue.pop_front());
|
core::mem::swap(&mut prompt, current_prompt);
|
||||||
*current_prompt = prompt;
|
let last_prompt = prompt;
|
||||||
|
self.action_queue.push_front(last_prompt);
|
||||||
*current_result = None;
|
*current_result = None;
|
||||||
*current_changes = Vec::new();
|
*current_changes = Vec::new();
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -369,7 +370,7 @@ impl Night {
|
||||||
if self.village.character_by_id(recruiting)?.is_village() {
|
if self.village.character_by_id(recruiting)?.is_village() {
|
||||||
if let Some(masons) = self.action_queue.iter_mut().find_map(|a| match a {
|
if let Some(masons) = self.action_queue.iter_mut().find_map(|a| match a {
|
||||||
ActionPrompt::MasonsWake { leader, masons, .. } => {
|
ActionPrompt::MasonsWake { leader, masons, .. } => {
|
||||||
(*leader == mason_leader).then_some(masons)
|
(leader.character_id == mason_leader).then_some(masons)
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}) {
|
}) {
|
||||||
|
|
@ -378,7 +379,7 @@ impl Night {
|
||||||
*masons = ext_masons.into_boxed_slice();
|
*masons = ext_masons.into_boxed_slice();
|
||||||
} else {
|
} else {
|
||||||
self.action_queue.push_front(ActionPrompt::MasonsWake {
|
self.action_queue.push_front(ActionPrompt::MasonsWake {
|
||||||
leader: self.village.character_by_id(mason_leader)?.character_id(),
|
leader: self.village.character_by_id(mason_leader)?.identity(),
|
||||||
masons: Box::new([self.village.character_by_id(recruiting)?.identity()]),
|
masons: Box::new([self.village.character_by_id(recruiting)?.identity()]),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,7 @@ impl SetupRoleTitle {
|
||||||
},
|
},
|
||||||
SetupRoleTitle::Werewolf => Role::Werewolf,
|
SetupRoleTitle::Werewolf => Role::Werewolf,
|
||||||
SetupRoleTitle::AlphaWolf => Role::AlphaWolf { killed: None },
|
SetupRoleTitle::AlphaWolf => Role::AlphaWolf { killed: None },
|
||||||
SetupRoleTitle::DireWolf => Role::DireWolf,
|
SetupRoleTitle::DireWolf => Role::DireWolf { last_blocked: None },
|
||||||
SetupRoleTitle::Shapeshifter => Role::Shapeshifter { shifted_into: None },
|
SetupRoleTitle::Shapeshifter => Role::Shapeshifter { shifted_into: None },
|
||||||
SetupRoleTitle::Adjudicator => Role::Adjudicator,
|
SetupRoleTitle::Adjudicator => Role::Adjudicator,
|
||||||
SetupRoleTitle::PowerSeer => Role::PowerSeer,
|
SetupRoleTitle::PowerSeer => Role::PowerSeer,
|
||||||
|
|
@ -269,7 +269,7 @@ impl SetupRole {
|
||||||
},
|
},
|
||||||
SetupRole::Werewolf => Role::Werewolf,
|
SetupRole::Werewolf => Role::Werewolf,
|
||||||
SetupRole::AlphaWolf => Role::AlphaWolf { killed: None },
|
SetupRole::AlphaWolf => Role::AlphaWolf { killed: None },
|
||||||
SetupRole::DireWolf => Role::DireWolf,
|
SetupRole::DireWolf => Role::DireWolf { last_blocked: None },
|
||||||
SetupRole::Shapeshifter => Role::Shapeshifter { shifted_into: None },
|
SetupRole::Shapeshifter => Role::Shapeshifter { shifted_into: None },
|
||||||
SetupRole::MasonLeader { recruits_available } => Role::MasonLeader {
|
SetupRole::MasonLeader { recruits_available } => Role::MasonLeader {
|
||||||
recruits_available: recruits_available.get(),
|
recruits_available: recruits_available.get(),
|
||||||
|
|
|
||||||
|
|
@ -292,7 +292,7 @@ impl StoryActionPrompt {
|
||||||
chosen: marked,
|
chosen: marked,
|
||||||
},
|
},
|
||||||
ActionPrompt::MasonsWake { leader, masons } => Self::MasonsWake {
|
ActionPrompt::MasonsWake { leader, masons } => Self::MasonsWake {
|
||||||
leader,
|
leader: leader.character_id,
|
||||||
masons: masons.into_iter().map(|c| c.character_id).collect(),
|
masons: masons.into_iter().map(|c| c.character_id).collect(),
|
||||||
},
|
},
|
||||||
ActionPrompt::MasonLeaderRecruit {
|
ActionPrompt::MasonLeaderRecruit {
|
||||||
|
|
@ -413,6 +413,19 @@ impl GameStory {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn final_village(&self) -> Result<Village> {
|
||||||
|
let mut village = self.starting_village.clone();
|
||||||
|
for (_, actions) in self.iter() {
|
||||||
|
village = match actions {
|
||||||
|
GameActions::DayDetails(day_details) => village.with_day_changes(day_details)?,
|
||||||
|
GameActions::NightDetails(night_details) => {
|
||||||
|
village.with_night_changes(&night_details.changes)?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Ok(village)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn village_at(&self, at_time: GameTime) -> Result<Option<Village>> {
|
pub fn village_at(&self, at_time: GameTime) -> Result<Option<Village>> {
|
||||||
let mut village = self.starting_village.clone();
|
let mut village = self.starting_village.clone();
|
||||||
for (time, actions) in self.iter() {
|
for (time, actions) in self.iter() {
|
||||||
|
|
|
||||||
|
|
@ -299,7 +299,7 @@ impl RoleTitle {
|
||||||
},
|
},
|
||||||
RoleTitle::Werewolf => Role::Werewolf,
|
RoleTitle::Werewolf => Role::Werewolf,
|
||||||
RoleTitle::AlphaWolf => Role::AlphaWolf { killed: None },
|
RoleTitle::AlphaWolf => Role::AlphaWolf { killed: None },
|
||||||
RoleTitle::DireWolf => Role::DireWolf,
|
RoleTitle::DireWolf => Role::DireWolf { last_blocked: None },
|
||||||
RoleTitle::Shapeshifter => Role::Shapeshifter { shifted_into: None },
|
RoleTitle::Shapeshifter => Role::Shapeshifter { shifted_into: None },
|
||||||
RoleTitle::Protector => Role::Protector {
|
RoleTitle::Protector => Role::Protector {
|
||||||
last_protected: None,
|
last_protected: None,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use crate::{
|
||||||
story::DayDetail,
|
story::DayDetail,
|
||||||
},
|
},
|
||||||
player::Protection,
|
player::Protection,
|
||||||
role::{PYREMASTER_VILLAGER_KILLS_TO_DIE, PreviousGuardianAction, RoleTitle},
|
role::{PYREMASTER_VILLAGER_KILLS_TO_DIE, PreviousGuardianAction, RoleBlock, RoleTitle},
|
||||||
};
|
};
|
||||||
|
|
||||||
type Result<T> = core::result::Result<T, GameError>;
|
type Result<T> = core::result::Result<T, GameError>;
|
||||||
|
|
@ -100,7 +100,18 @@ impl Village {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
NightChange::RoleBlock { .. } | NightChange::Protection { .. } => {}
|
NightChange::RoleBlock {
|
||||||
|
source,
|
||||||
|
target,
|
||||||
|
block_type: RoleBlock::Direwolf,
|
||||||
|
} => {
|
||||||
|
new_village
|
||||||
|
.character_by_id_mut(*source)?
|
||||||
|
.direwolf_mut()?
|
||||||
|
.replace(*target);
|
||||||
|
}
|
||||||
|
|
||||||
|
NightChange::Protection { .. } => {}
|
||||||
NightChange::MasonRecruit {
|
NightChange::MasonRecruit {
|
||||||
mason_leader,
|
mason_leader,
|
||||||
recruiting,
|
recruiting,
|
||||||
|
|
|
||||||
|
|
@ -217,14 +217,14 @@ impl ActionResultExt for ActionResult {
|
||||||
fn arcanist(&self) -> bool {
|
fn arcanist(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
ActionResult::Arcanist(same) => same.same(),
|
ActionResult::Arcanist(same) => same.same(),
|
||||||
_ => panic!("expected an arcanist result"),
|
resp => panic!("expected an arcanist result, got {resp:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insomniac(&self) -> Visits {
|
fn insomniac(&self) -> Visits {
|
||||||
match self {
|
match self {
|
||||||
ActionResult::Insomniac(v) => v.clone(),
|
ActionResult::Insomniac(v) => v.clone(),
|
||||||
_ => panic!("expected an insomniac result"),
|
resp => panic!("expected an insomniac result, got {resp:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -298,9 +298,13 @@ pub trait GameExt {
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
fn get_state(&mut self) -> ServerToHostMessage;
|
fn get_state(&mut self) -> ServerToHostMessage;
|
||||||
fn next_expect_game_over(&mut self) -> GameOver;
|
fn next_expect_game_over(&mut self) -> GameOver;
|
||||||
|
fn prev(&mut self) -> ServerToHostMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameExt for Game {
|
impl GameExt for Game {
|
||||||
|
fn prev(&mut self) -> ServerToHostMessage {
|
||||||
|
self.process(HostGameMessage::PreviousState).unwrap()
|
||||||
|
}
|
||||||
fn next_expect_game_over(&mut self) -> GameOver {
|
fn next_expect_game_over(&mut self) -> GameOver {
|
||||||
match self
|
match self
|
||||||
.process(HostGameMessage::Night(
|
.process(HostGameMessage::Night(
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,20 @@
|
||||||
|
use core::num::NonZeroU8;
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
use pretty_assertions::{assert_eq, assert_ne, assert_str_eq};
|
use pretty_assertions::{assert_eq, assert_ne, assert_str_eq};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
game::{Game, GameSettings, GameState, SetupRole},
|
diedto::DiedToTitle,
|
||||||
game_test::{ActionPromptTitleExt, ActionResultExt, GameExt, SettingsExt, gen_players},
|
game::{Game, GameSettings, GameState, OrRandom, SetupRole},
|
||||||
|
game_test::{
|
||||||
|
ActionPromptTitleExt, ActionResultExt, GameExt, SettingsExt, gen_players, init_log,
|
||||||
|
},
|
||||||
message::{
|
message::{
|
||||||
|
Identification, PublicIdentity,
|
||||||
host::ServerToHostMessage,
|
host::ServerToHostMessage,
|
||||||
night::{ActionPrompt, ActionPromptTitle, ActionResponse},
|
night::{ActionPrompt, ActionPromptTitle, ActionResponse},
|
||||||
},
|
},
|
||||||
|
player::PlayerId,
|
||||||
role::RoleTitle,
|
role::RoleTitle,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -125,3 +132,258 @@ fn previous_shapeshifter_undone_and_changed_to_no() {
|
||||||
&[]
|
&[]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn previous_prompt() {
|
||||||
|
init_log();
|
||||||
|
let players = (1..32u8)
|
||||||
|
.filter_map(NonZeroU8::new)
|
||||||
|
.map(|n| Identification {
|
||||||
|
player_id: PlayerId::from_u128(n.get() as _),
|
||||||
|
public: PublicIdentity {
|
||||||
|
name: format!("Player {n}"),
|
||||||
|
pronouns: Some("he/him".into()),
|
||||||
|
number: Some(n),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.collect::<Box<[_]>>();
|
||||||
|
let mut players_iter = players.iter().map(|p| p.player_id);
|
||||||
|
let (
|
||||||
|
werewolf,
|
||||||
|
dire_wolf,
|
||||||
|
shapeshifter,
|
||||||
|
alpha_wolf,
|
||||||
|
seer,
|
||||||
|
arcanist,
|
||||||
|
maple_wolf,
|
||||||
|
guardian,
|
||||||
|
vindicator,
|
||||||
|
adjudicator,
|
||||||
|
power_seer,
|
||||||
|
beholder,
|
||||||
|
gravedigger,
|
||||||
|
mortician,
|
||||||
|
insomniac,
|
||||||
|
empath,
|
||||||
|
scapegoat,
|
||||||
|
hunter,
|
||||||
|
) = (
|
||||||
|
(SetupRole::Werewolf, players_iter.next().unwrap()),
|
||||||
|
(SetupRole::DireWolf, players_iter.next().unwrap()),
|
||||||
|
(SetupRole::Shapeshifter, players_iter.next().unwrap()),
|
||||||
|
(SetupRole::AlphaWolf, players_iter.next().unwrap()),
|
||||||
|
(SetupRole::Seer, players_iter.next().unwrap()),
|
||||||
|
(SetupRole::Arcanist, players_iter.next().unwrap()),
|
||||||
|
(SetupRole::MapleWolf, players_iter.next().unwrap()),
|
||||||
|
(SetupRole::Guardian, players_iter.next().unwrap()),
|
||||||
|
(SetupRole::Vindicator, players_iter.next().unwrap()),
|
||||||
|
(SetupRole::Adjudicator, players_iter.next().unwrap()),
|
||||||
|
(SetupRole::PowerSeer, players_iter.next().unwrap()),
|
||||||
|
(SetupRole::Beholder, players_iter.next().unwrap()),
|
||||||
|
(SetupRole::Gravedigger, players_iter.next().unwrap()),
|
||||||
|
(SetupRole::Mortician, players_iter.next().unwrap()),
|
||||||
|
(SetupRole::Insomniac, players_iter.next().unwrap()),
|
||||||
|
(SetupRole::Empath, players_iter.next().unwrap()),
|
||||||
|
(
|
||||||
|
SetupRole::Scapegoat {
|
||||||
|
redeemed: OrRandom::Determined(false),
|
||||||
|
},
|
||||||
|
players_iter.next().unwrap(),
|
||||||
|
),
|
||||||
|
(SetupRole::Hunter, players_iter.next().unwrap()),
|
||||||
|
);
|
||||||
|
let mut settings = GameSettings::empty();
|
||||||
|
settings.add_and_assign(werewolf.0, werewolf.1);
|
||||||
|
settings.add_and_assign(dire_wolf.0, dire_wolf.1);
|
||||||
|
settings.add_and_assign(shapeshifter.0, shapeshifter.1);
|
||||||
|
settings.add_and_assign(alpha_wolf.0, alpha_wolf.1);
|
||||||
|
settings.add_and_assign(seer.0, seer.1);
|
||||||
|
settings.add_and_assign(arcanist.0, arcanist.1);
|
||||||
|
settings.add_and_assign(maple_wolf.0, maple_wolf.1);
|
||||||
|
settings.add_and_assign(guardian.0, guardian.1);
|
||||||
|
settings.add_and_assign(vindicator.0, vindicator.1);
|
||||||
|
settings.add_and_assign(adjudicator.0, adjudicator.1);
|
||||||
|
settings.add_and_assign(power_seer.0, power_seer.1);
|
||||||
|
settings.add_and_assign(beholder.0, beholder.1);
|
||||||
|
settings.add_and_assign(gravedigger.0, gravedigger.1);
|
||||||
|
settings.add_and_assign(mortician.0, mortician.1);
|
||||||
|
settings.add_and_assign(insomniac.0, insomniac.1);
|
||||||
|
settings.add_and_assign(empath.0, empath.1);
|
||||||
|
settings.add_and_assign(scapegoat.0, scapegoat.1);
|
||||||
|
settings.add_and_assign(hunter.0, hunter.1);
|
||||||
|
settings.fill_remaining_slots_with_villagers(players.len());
|
||||||
|
|
||||||
|
let (
|
||||||
|
werewolf,
|
||||||
|
dire_wolf,
|
||||||
|
shapeshifter,
|
||||||
|
alpha_wolf,
|
||||||
|
seer,
|
||||||
|
arcanist,
|
||||||
|
maple_wolf,
|
||||||
|
guardian,
|
||||||
|
vindicator,
|
||||||
|
adjudicator,
|
||||||
|
power_seer,
|
||||||
|
beholder,
|
||||||
|
gravedigger,
|
||||||
|
mortician,
|
||||||
|
insomniac,
|
||||||
|
empath,
|
||||||
|
scapegoat,
|
||||||
|
hunter,
|
||||||
|
) = (
|
||||||
|
werewolf.1,
|
||||||
|
dire_wolf.1,
|
||||||
|
shapeshifter.1,
|
||||||
|
alpha_wolf.1,
|
||||||
|
seer.1,
|
||||||
|
arcanist.1,
|
||||||
|
maple_wolf.1,
|
||||||
|
guardian.1,
|
||||||
|
vindicator.1,
|
||||||
|
adjudicator.1,
|
||||||
|
power_seer.1,
|
||||||
|
beholder.1,
|
||||||
|
gravedigger.1,
|
||||||
|
mortician.1,
|
||||||
|
insomniac.1,
|
||||||
|
empath.1,
|
||||||
|
scapegoat.1,
|
||||||
|
hunter.1,
|
||||||
|
);
|
||||||
|
let mut game = Game::new(&players, settings).unwrap();
|
||||||
|
game.r#continue().r#continue();
|
||||||
|
game.next().title().wolves_intro();
|
||||||
|
game.r#continue().r#continue();
|
||||||
|
|
||||||
|
game.next().title().direwolf();
|
||||||
|
game.mark(game.character_by_player_id(seer).character_id());
|
||||||
|
game.r#continue().sleep();
|
||||||
|
|
||||||
|
game.next().title().seer();
|
||||||
|
game.mark(game.character_by_player_id(werewolf).character_id());
|
||||||
|
game.r#continue().seer();
|
||||||
|
|
||||||
|
game.next().title().arcanist();
|
||||||
|
game.mark(game.character_by_player_id(seer).character_id());
|
||||||
|
game.mark(game.character_by_player_id(werewolf).character_id());
|
||||||
|
game.r#continue().role_blocked();
|
||||||
|
|
||||||
|
game.next().title().adjudicator();
|
||||||
|
game.mark(game.character_by_player_id(werewolf).character_id());
|
||||||
|
game.r#continue().adjudicator();
|
||||||
|
|
||||||
|
game.next().title().power_seer();
|
||||||
|
match game.prev() {
|
||||||
|
ServerToHostMessage::ActionPrompt(
|
||||||
|
ActionPrompt::Adjudicator {
|
||||||
|
character_id,
|
||||||
|
marked: Some(mark),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
_,
|
||||||
|
) => {
|
||||||
|
assert_eq!(
|
||||||
|
character_id,
|
||||||
|
game.character_by_player_id(adjudicator).identity()
|
||||||
|
);
|
||||||
|
assert_eq!(mark, game.character_by_player_id(werewolf).character_id());
|
||||||
|
}
|
||||||
|
resp => panic!("expected adjudicator prompt, got {resp:?}"),
|
||||||
|
}
|
||||||
|
match game.prev() {
|
||||||
|
ServerToHostMessage::ActionPrompt(
|
||||||
|
ActionPrompt::Arcanist {
|
||||||
|
character_id,
|
||||||
|
marked: (Some(mark1), Some(mark2)),
|
||||||
|
..
|
||||||
|
},
|
||||||
|
_,
|
||||||
|
) => {
|
||||||
|
assert_eq!(
|
||||||
|
character_id,
|
||||||
|
game.character_by_player_id(arcanist).identity()
|
||||||
|
);
|
||||||
|
assert_eq!(mark1, game.character_by_player_id(seer).character_id());
|
||||||
|
assert_eq!(mark2, game.character_by_player_id(werewolf).character_id());
|
||||||
|
}
|
||||||
|
resp => panic!("expected arcanist prompt, got {resp:?}"),
|
||||||
|
}
|
||||||
|
game.r#continue().role_blocked();
|
||||||
|
game.next().title().adjudicator();
|
||||||
|
game.r#continue().adjudicator();
|
||||||
|
|
||||||
|
game.next().title().power_seer();
|
||||||
|
game.mark(game.character_by_player_id(werewolf).character_id());
|
||||||
|
game.r#continue().power_seer();
|
||||||
|
|
||||||
|
game.next().title().beholder();
|
||||||
|
game.mark(game.character_by_player_id(arcanist).character_id());
|
||||||
|
game.r#continue().role_blocked();
|
||||||
|
|
||||||
|
game.next_expect_day();
|
||||||
|
game.mark_for_execution(game.character_by_player_id(dire_wolf).character_id());
|
||||||
|
game.mark_for_execution(game.character_by_player_id(alpha_wolf).character_id());
|
||||||
|
|
||||||
|
game.execute().title().guardian();
|
||||||
|
let protect = game.living_villager();
|
||||||
|
game.mark(protect.character_id());
|
||||||
|
game.r#continue().sleep();
|
||||||
|
|
||||||
|
game.next().title().wolf_pack_kill();
|
||||||
|
game.mark(protect.character_id());
|
||||||
|
game.r#continue().r#continue();
|
||||||
|
|
||||||
|
game.next().title().shapeshifter();
|
||||||
|
game.response(ActionResponse::Shapeshift).sleep();
|
||||||
|
|
||||||
|
game.next().title().seer();
|
||||||
|
game.mark(game.character_by_player_id(werewolf).character_id());
|
||||||
|
game.r#continue().seer();
|
||||||
|
|
||||||
|
game.next().title().arcanist();
|
||||||
|
game.mark(game.character_by_player_id(seer).character_id());
|
||||||
|
game.mark(game.character_by_player_id(werewolf).character_id());
|
||||||
|
game.r#continue().arcanist();
|
||||||
|
|
||||||
|
game.next().title().adjudicator();
|
||||||
|
game.mark(game.character_by_player_id(seer).character_id());
|
||||||
|
game.r#continue().adjudicator();
|
||||||
|
|
||||||
|
game.next().title().power_seer();
|
||||||
|
game.mark(game.living_villager().character_id());
|
||||||
|
game.r#continue().power_seer();
|
||||||
|
|
||||||
|
game.next().title().gravedigger();
|
||||||
|
game.mark(game.character_by_player_id(dire_wolf).character_id());
|
||||||
|
assert_eq!(game.r#continue().gravedigger(), Some(RoleTitle::DireWolf));
|
||||||
|
|
||||||
|
game.next().title().mortician();
|
||||||
|
game.mark(game.character_by_player_id(dire_wolf).character_id());
|
||||||
|
assert_eq!(game.r#continue().mortician(), DiedToTitle::Execution);
|
||||||
|
|
||||||
|
game.next().title().empath();
|
||||||
|
game.mark(game.living_villager().character_id());
|
||||||
|
assert!(!game.r#continue().empath());
|
||||||
|
|
||||||
|
game.next().title().maple_wolf();
|
||||||
|
game.mark(
|
||||||
|
game.living_villager_excl(protect.player_id())
|
||||||
|
.character_id(),
|
||||||
|
);
|
||||||
|
game.r#continue().sleep();
|
||||||
|
|
||||||
|
game.next().title().hunter();
|
||||||
|
game.mark(game.character_by_player_id(insomniac).character_id());
|
||||||
|
game.r#continue().sleep();
|
||||||
|
|
||||||
|
game.next().title().insomniac();
|
||||||
|
game.r#continue().insomniac();
|
||||||
|
|
||||||
|
game.next().title().beholder();
|
||||||
|
game.mark(game.character_by_player_id(power_seer).character_id());
|
||||||
|
game.r#continue().power_seer();
|
||||||
|
|
||||||
|
game.next_expect_day();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ fn recruits_decrement() {
|
||||||
ActionPrompt::MasonsWake {
|
ActionPrompt::MasonsWake {
|
||||||
leader: game
|
leader: game
|
||||||
.character_by_player_id(mason_leader_player_id)
|
.character_by_player_id(mason_leader_player_id)
|
||||||
.character_id(),
|
.identity(),
|
||||||
masons: Box::new([
|
masons: Box::new([
|
||||||
game.character_by_player_id(mason_leader_player_id)
|
game.character_by_player_id(mason_leader_player_id)
|
||||||
.identity(),
|
.identity(),
|
||||||
|
|
@ -105,7 +105,7 @@ fn dies_recruiting_wolf() {
|
||||||
ActionPrompt::MasonsWake {
|
ActionPrompt::MasonsWake {
|
||||||
leader: game
|
leader: game
|
||||||
.character_by_player_id(mason_leader_player_id)
|
.character_by_player_id(mason_leader_player_id)
|
||||||
.character_id(),
|
.identity(),
|
||||||
masons: Box::new([game
|
masons: Box::new([game
|
||||||
.character_by_player_id(mason_leader_player_id)
|
.character_by_player_id(mason_leader_player_id)
|
||||||
.identity()])
|
.identity()])
|
||||||
|
|
@ -165,7 +165,7 @@ fn masons_wake_even_if_leader_died() {
|
||||||
ActionPrompt::MasonsWake {
|
ActionPrompt::MasonsWake {
|
||||||
leader: game
|
leader: game
|
||||||
.character_by_player_id(mason_leader_player_id)
|
.character_by_player_id(mason_leader_player_id)
|
||||||
.character_id(),
|
.identity(),
|
||||||
masons: Box::new([
|
masons: Box::new([
|
||||||
game.character_by_player_id(mason_leader_player_id)
|
game.character_by_player_id(mason_leader_player_id)
|
||||||
.identity(),
|
.identity(),
|
||||||
|
|
@ -192,7 +192,7 @@ fn masons_wake_even_if_leader_died() {
|
||||||
ActionPrompt::MasonsWake {
|
ActionPrompt::MasonsWake {
|
||||||
leader: game
|
leader: game
|
||||||
.character_by_player_id(mason_leader_player_id)
|
.character_by_player_id(mason_leader_player_id)
|
||||||
.character_id(),
|
.identity(),
|
||||||
masons: Box::new([
|
masons: Box::new([
|
||||||
game.character_by_player_id(black_knight_player_id)
|
game.character_by_player_id(black_knight_player_id)
|
||||||
.identity(),
|
.identity(),
|
||||||
|
|
@ -220,7 +220,7 @@ fn masons_wake_even_if_leader_died() {
|
||||||
ActionPrompt::MasonsWake {
|
ActionPrompt::MasonsWake {
|
||||||
leader: game
|
leader: game
|
||||||
.character_by_player_id(mason_leader_player_id)
|
.character_by_player_id(mason_leader_player_id)
|
||||||
.character_id(),
|
.identity(),
|
||||||
masons: Box::new([
|
masons: Box::new([
|
||||||
game.character_by_player_id(black_knight_player_id)
|
game.character_by_player_id(black_knight_player_id)
|
||||||
.identity(),
|
.identity(),
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ pub enum ActionPrompt {
|
||||||
},
|
},
|
||||||
#[checks(ActionType::MasonsWake)]
|
#[checks(ActionType::MasonsWake)]
|
||||||
MasonsWake {
|
MasonsWake {
|
||||||
leader: CharacterId,
|
leader: CharacterIdentity,
|
||||||
masons: Box<[CharacterIdentity]>,
|
masons: Box<[CharacterIdentity]>,
|
||||||
},
|
},
|
||||||
#[checks(ActionType::MasonRecruit)]
|
#[checks(ActionType::MasonRecruit)]
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ pub enum Role {
|
||||||
#[checks(Killer::Killer)]
|
#[checks(Killer::Killer)]
|
||||||
#[checks(Powerful::Powerful)]
|
#[checks(Powerful::Powerful)]
|
||||||
#[checks("wolf")]
|
#[checks("wolf")]
|
||||||
DireWolf,
|
DireWolf { last_blocked: Option<CharacterId> },
|
||||||
#[checks(Alignment::Wolves)]
|
#[checks(Alignment::Wolves)]
|
||||||
#[checks(Killer::Killer)]
|
#[checks(Killer::Killer)]
|
||||||
#[checks(Powerful::Powerful)]
|
#[checks(Powerful::Powerful)]
|
||||||
|
|
@ -299,7 +299,7 @@ impl Role {
|
||||||
|
|
||||||
Role::Werewolf => KillingWolfOrder::Werewolf,
|
Role::Werewolf => KillingWolfOrder::Werewolf,
|
||||||
Role::AlphaWolf { .. } => KillingWolfOrder::AlphaWolf,
|
Role::AlphaWolf { .. } => KillingWolfOrder::AlphaWolf,
|
||||||
Role::DireWolf => KillingWolfOrder::DireWolf,
|
Role::DireWolf { .. } => KillingWolfOrder::DireWolf,
|
||||||
Role::Shapeshifter { .. } => KillingWolfOrder::Shapeshifter,
|
Role::Shapeshifter { .. } => KillingWolfOrder::Shapeshifter,
|
||||||
Role::LoneWolf => KillingWolfOrder::LoneWolf,
|
Role::LoneWolf => KillingWolfOrder::LoneWolf,
|
||||||
})
|
})
|
||||||
|
|
@ -311,7 +311,7 @@ impl Role {
|
||||||
| Role::PowerSeer
|
| Role::PowerSeer
|
||||||
| Role::Beholder
|
| Role::Beholder
|
||||||
| Role::Adjudicator
|
| Role::Adjudicator
|
||||||
| Role::DireWolf
|
| Role::DireWolf { .. }
|
||||||
| Role::Arcanist
|
| Role::Arcanist
|
||||||
| Role::Seer => true,
|
| Role::Seer => true,
|
||||||
|
|
||||||
|
|
@ -377,7 +377,7 @@ impl Role {
|
||||||
| Role::Adjudicator
|
| Role::Adjudicator
|
||||||
| Role::Scapegoat { redeemed: true }
|
| Role::Scapegoat { redeemed: true }
|
||||||
| Role::Shapeshifter { .. }
|
| Role::Shapeshifter { .. }
|
||||||
| Role::DireWolf
|
| Role::DireWolf { .. }
|
||||||
| Role::AlphaWolf { killed: None }
|
| Role::AlphaWolf { killed: None }
|
||||||
| Role::Arcanist
|
| Role::Arcanist
|
||||||
| Role::Protector { .. }
|
| Role::Protector { .. }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="18.946421mm"
|
||||||
|
height="18.95406mm"
|
||||||
|
viewBox="0 0 18.946421 18.95406"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
sodipodi:docname="icons.svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="true"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.4142136"
|
||||||
|
inkscape:cx="233.34524"
|
||||||
|
inkscape:cy="503.81359"
|
||||||
|
inkscape:window-width="1918"
|
||||||
|
inkscape:window-height="1042"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="17"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="layer4"><inkscape:grid
|
||||||
|
id="grid1"
|
||||||
|
units="mm"
|
||||||
|
originx="-81.683493"
|
||||||
|
originy="-164.22112"
|
||||||
|
spacingx="0.26458333"
|
||||||
|
spacingy="0.26458334"
|
||||||
|
empcolor="#0099e5"
|
||||||
|
empopacity="0.30196078"
|
||||||
|
color="#0099e5"
|
||||||
|
opacity="0.14901961"
|
||||||
|
empspacing="5"
|
||||||
|
enabled="true"
|
||||||
|
visible="false" /><inkscape:page
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="18.946421"
|
||||||
|
height="18.95406"
|
||||||
|
id="page2"
|
||||||
|
margin="0"
|
||||||
|
bleed="0" /></sodipodi:namedview><defs
|
||||||
|
id="defs1" /><g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer4"
|
||||||
|
inkscape:label="Layer 4"
|
||||||
|
transform="translate(-81.683494,-164.22111)"><path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="fill:#8cff91;fill-opacity:0.697629;stroke:#ccffcc;stroke-width:0.548;stroke-dasharray:none;stroke-opacity:0.698625"
|
||||||
|
id="path3"
|
||||||
|
inkscape:flatsided="false"
|
||||||
|
sodipodi:sides="6"
|
||||||
|
sodipodi:cx="109.63396"
|
||||||
|
sodipodi:cy="232.73831"
|
||||||
|
sodipodi:r1="8.0361061"
|
||||||
|
sodipodi:r2="7.7416453"
|
||||||
|
sodipodi:arg1="-2.0943951"
|
||||||
|
sodipodi:arg2="-2.9866062"
|
||||||
|
inkscape:rounded="0.5"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 105.6159,225.77884 c -1.22761,-3.17739 -7.037083,5.76416 -3.63079,5.76442 6.50663,5e-4 7.58314,-0.69893 11.6669,-5.76442 2.13789,-2.65184 -8.51045,-3.21222 -6.80753,-0.26215 3.25288,5.63516 4.39686,6.21772 10.82558,7.22162 3.36551,0.52555 -1.47336,-8.97637 -3.17673,-6.02657 -3.25375,5.63466 -3.18628,6.91666 -0.84132,12.98604 1.22761,3.17739 7.03709,-5.76416 3.6308,-5.76442 -6.50664,-4.9e-4 -7.58314,0.69893 -11.66691,5.76442 -2.13789,2.65184 8.51046,3.21222 6.80754,0.26216 -3.25289,-5.63516 -4.39687,-6.21773 -10.82559,-7.22163 -3.365501,-0.52555 1.47337,8.97638 3.17674,6.02657 3.25374,-5.63466 3.18627,-6.91665 0.84131,-12.98604 z"
|
||||||
|
inkscape:transform-center-x="-0.32847244"
|
||||||
|
inkscape:transform-center-y="-0.29842497"
|
||||||
|
transform="translate(-18.477247,-59.040163)"
|
||||||
|
inkscape:export-filename="diseased.svg"
|
||||||
|
inkscape:export-xdpi="900.08"
|
||||||
|
inkscape:export-ydpi="900.08" /></g></svg>
|
||||||
|
After Width: | Height: | Size: 3.2 KiB |
|
|
@ -2,9 +2,9 @@
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
<svg
|
<svg
|
||||||
width="14.519332mm"
|
width="20.907848mm"
|
||||||
height="14.518607mm"
|
height="24.813328mm"
|
||||||
viewBox="0 0 14.519332 14.518607"
|
viewBox="0 0 20.907848 24.813328"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
id="svg1"
|
id="svg1"
|
||||||
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
|
@ -23,20 +23,33 @@
|
||||||
inkscape:pagecheckerboard="true"
|
inkscape:pagecheckerboard="true"
|
||||||
inkscape:deskcolor="#d1d1d1"
|
inkscape:deskcolor="#d1d1d1"
|
||||||
inkscape:document-units="mm"
|
inkscape:document-units="mm"
|
||||||
showgrid="true"
|
showgrid="false"
|
||||||
inkscape:zoom="2"
|
inkscape:zoom="1.4142136"
|
||||||
inkscape:cx="92.75"
|
inkscape:cx="233.34524"
|
||||||
inkscape:cy="546.5"
|
inkscape:cy="503.81359"
|
||||||
inkscape:window-width="1918"
|
inkscape:window-width="1918"
|
||||||
inkscape:window-height="1061"
|
inkscape:window-height="1042"
|
||||||
inkscape:window-x="0"
|
inkscape:window-x="0"
|
||||||
inkscape:window-y="17"
|
inkscape:window-y="17"
|
||||||
inkscape:window-maximized="0"
|
inkscape:window-maximized="0"
|
||||||
inkscape:current-layer="layer4"><inkscape:page
|
inkscape:current-layer="layer4"><inkscape:grid
|
||||||
x="-3.6500685e-13"
|
id="grid1"
|
||||||
|
units="mm"
|
||||||
|
originx="-94.492683"
|
||||||
|
originy="-224.65327"
|
||||||
|
spacingx="0.26458333"
|
||||||
|
spacingy="0.26458334"
|
||||||
|
empcolor="#0099e5"
|
||||||
|
empopacity="0.30196078"
|
||||||
|
color="#0099e5"
|
||||||
|
opacity="0.14901961"
|
||||||
|
empspacing="5"
|
||||||
|
enabled="true"
|
||||||
|
visible="false" /><inkscape:page
|
||||||
|
x="0"
|
||||||
y="0"
|
y="0"
|
||||||
width="14.519333"
|
width="20.907848"
|
||||||
height="14.518607"
|
height="24.813328"
|
||||||
id="page2"
|
id="page2"
|
||||||
margin="0"
|
margin="0"
|
||||||
bleed="0" /></sodipodi:namedview><defs
|
bleed="0" /></sodipodi:namedview><defs
|
||||||
|
|
@ -44,10 +57,25 @@
|
||||||
inkscape:groupmode="layer"
|
inkscape:groupmode="layer"
|
||||||
id="layer4"
|
id="layer4"
|
||||||
inkscape:label="Layer 4"
|
inkscape:label="Layer 4"
|
||||||
transform="translate(-81.081288,-167.88827)"><path
|
transform="translate(-94.492686,-224.65327)"><g
|
||||||
id="rect172"
|
id="g10-3"
|
||||||
style="fill:#7f7f7f;fill-opacity:1;stroke:#000000;stroke-width:0.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
inkscape:export-filename="../../src/werewolves/werewolves/img/gravedigger.svg"
|
||||||
d="m 94.511966,168.08826 -8.159189,8.15918 -1.539827,-1.53983 -3.324114,3.32339 -0.207549,4.17587 4.176605,-0.20681 3.32375,-3.32376 -1.540192,-1.54019 8.159186,-8.15919 z" /><path
|
inkscape:export-xdpi="900.08"
|
||||||
id="path145-7"
|
inkscape:export-ydpi="900.08"
|
||||||
style="fill:#a0a0a0;fill-opacity:0.5;stroke:#545454;stroke-width:0.232;stroke-dasharray:none;stroke-opacity:0.7"
|
transform="translate(-23.17051,-0.63943083)"><path
|
||||||
d="m 88.300286,169.67427 c -0.48287,0.009 -0.965274,0.0916 -1.420584,0.25373 -1.738714,0.59694 -3.342068,0.9627 -3.03444,4.1274 -0.06576,0.94137 -0.0783,1.89737 0.06408,2.83239 0.07766,0.53633 0.382678,1.09991 0.888836,1.32446 0.446178,0.0891 0.985208,-0.0139 1.31258,0.39223 0.88847,0.68196 0.349966,2.06997 1.028362,1.973 0.4264,-0.0609 0.136174,-0.73886 0.260966,-0.80202 0.192692,-0.0975 0.181336,-0.0608 0.241846,0.18087 0.03243,0.38247 -0.05245,0.69761 0.28112,0.66198 0.550572,-0.0588 0.28691,-0.48129 0.328144,-0.95808 0.0732,-0.0163 0.08707,-0.0125 0.0894,-0.0114 h 5.18e-4 c 0.0023,-0.001 0.01617,-0.005 0.0894,0.0114 0.04123,0.47679 -0.222428,0.89925 0.328144,0.95808 0.333568,0.0356 0.248694,-0.27951 0.28112,-0.66198 0.06051,-0.2417 0.04915,-0.27839 0.241846,-0.18087 0.124792,0.0632 -0.165434,0.74107 0.260966,0.80202 0.678396,0.097 0.139892,-1.29104 1.028362,-1.973 0.327372,-0.40615 0.866402,-0.30311 1.31258,-0.39223 0.506158,-0.22455 0.81169,-0.78813 0.889352,-1.32446 0.14238,-0.93502 0.129318,-1.89102 0.06356,-2.83239 0.307628,-3.1647 -1.295726,-3.53046 -3.03444,-4.1274 -0.45531,-0.16216 -0.937716,-0.24475 -1.420586,-0.25373 -0.0135,0 -0.02664,-1e-4 -0.04031,0 -0.01367,-1e-4 -0.02733,0 -0.04083,0 z m -2.07274,4.18424 c 0.703538,-0.004 1.021816,0.49934 1.094506,0.7059 0.462654,1.11185 -0.373098,1.45665 -1.174088,1.42576 -0.699984,0.0989 -1.258414,0.0508 -1.342554,-1.01286 -0.01001,-0.33209 0.308906,-0.96177 1.096574,-1.08366 0.116648,-0.0235 0.225056,-0.0346 0.325562,-0.0351 z m 4.226614,0 c 0.100506,5.1e-4 0.208914,0.0116 0.325562,0.0351 0.787668,0.12189 1.106584,0.75157 1.096574,1.08366 -0.08414,1.06367 -0.64257,1.11173 -1.342554,1.01286 -0.80099,0.0309 -1.636742,-0.31391 -1.174088,-1.42576 0.07269,-0.20656 0.390968,-0.70943 1.094506,-0.7059 z m -2.113048,2.94194 c 0.215198,0.0216 0.284064,0.38489 0.583426,0.77618 0.276858,0.50031 -0.16476,0.69652 -0.409794,0.48318 -0.146516,-0.11734 -0.171114,-0.12967 -0.173632,-0.13074 -0.0025,0.001 -0.02763,0.0134 -0.17415,0.13074 -0.245034,0.21334 -0.686652,0.0171 -0.409794,-0.48318 0.299362,-0.39129 0.368746,-0.75459 0.583944,-0.77618 z" /></g></svg>
|
id="rect1-3-9-6"
|
||||||
|
style="fill:#803300;fill-opacity:1;stroke:#441b00;stroke-width:0.860999;stroke-opacity:1"
|
||||||
|
d="m 124.55133,225.72321 -4,4.95837 v 4.079 l 4,14.53587 h 4.347 l 4,-14.53587 v -4.079 l -4,-4.95837 z"
|
||||||
|
sodipodi:nodetypes="ccccccccc"
|
||||||
|
inkscape:export-filename="mortician.svg"
|
||||||
|
inkscape:export-xdpi="900.08"
|
||||||
|
inkscape:export-ydpi="900.08" /><path
|
||||||
|
id="path145-7-2-2-1"
|
||||||
|
style="fill:#ffffff;fill-opacity:0.5;stroke:#441b00;stroke-width:0.232;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 126.68415,227.8032 c -0.48287,0.009 -0.96527,0.0916 -1.42058,0.25373 -1.73872,0.59694 -3.34207,0.9627 -3.03444,4.1274 -0.0658,0.94137 -0.0783,1.89737 0.0641,2.83239 0.0777,0.53633 0.38267,1.09991 0.88883,1.32446 0.44618,0.0891 0.98521,-0.0139 1.31258,0.39223 0.88847,0.68196 0.34997,2.06997 1.02836,1.973 0.4264,-0.0609 0.13618,-0.73886 0.26097,-0.80202 0.19269,-0.0975 0.18134,-0.0608 0.24185,0.18087 0.0324,0.38247 -0.0524,0.69761 0.28112,0.66198 0.55057,-0.0588 0.28691,-0.48129 0.32814,-0.95808 0.0732,-0.0163 0.0871,-0.0125 0.0894,-0.0114 h 5.2e-4 c 0.002,-0.001 0.0162,-0.005 0.0894,0.0114 0.0412,0.47679 -0.22243,0.89925 0.32814,0.95808 0.33357,0.0356 0.24869,-0.27951 0.28112,-0.66198 0.0605,-0.2417 0.0491,-0.27839 0.24185,-0.18087 0.12479,0.0632 -0.16544,0.74107 0.26096,0.80202 0.6784,0.097 0.13989,-1.29104 1.02836,-1.973 0.32738,-0.40615 0.86641,-0.30311 1.31258,-0.39223 0.50616,-0.22455 0.81169,-0.78813 0.88936,-1.32446 0.14238,-0.93502 0.12931,-1.89102 0.0636,-2.83239 0.30762,-3.1647 -1.29573,-3.53046 -3.03444,-4.1274 -0.45531,-0.16216 -0.93772,-0.24475 -1.42059,-0.25373 -0.0135,0 -0.0266,-1e-4 -0.0403,0 -0.0137,-1e-4 -0.0273,0 -0.0408,0 z m -2.07274,4.18424 c 0.70354,-0.004 1.02182,0.49934 1.09451,0.7059 0.46265,1.11185 -0.3731,1.45665 -1.17409,1.42576 -0.69999,0.0989 -1.25842,0.0508 -1.34256,-1.01286 -0.01,-0.33209 0.30891,-0.96177 1.09658,-1.08366 0.11665,-0.0235 0.22505,-0.0346 0.32556,-0.0351 z m 4.22661,0 c 0.10051,5.1e-4 0.20892,0.0116 0.32556,0.0351 0.78767,0.12189 1.10659,0.75157 1.09658,1.08366 -0.0841,1.06367 -0.64257,1.11173 -1.34256,1.01286 -0.80099,0.0309 -1.63674,-0.31391 -1.17408,-1.42576 0.0727,-0.20656 0.39096,-0.70943 1.0945,-0.7059 z m -2.11305,2.94194 c 0.2152,0.0216 0.28407,0.38489 0.58343,0.77618 0.27686,0.50031 -0.16476,0.69652 -0.40979,0.48318 -0.14652,-0.11734 -0.17112,-0.12967 -0.17364,-0.13074 -0.002,0.001 -0.0276,0.0134 -0.17414,0.13074 -0.24504,0.21334 -0.68666,0.0171 -0.4098,-0.48318 0.29936,-0.39129 0.36875,-0.75459 0.58394,-0.77618 z" /></g><path
|
||||||
|
id="rect172-2"
|
||||||
|
style="fill:#7f7f7f;fill-opacity:1;stroke:#000000;stroke-width:0.576;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||||
|
d="m 113.83285,228.84782 -11.74921,11.74921 -2.217361,-2.21735 -4.786727,4.78568 -0.298871,6.01325 6.014309,-0.2978 4.7862,-4.78621 -2.21787,-2.21788 11.74922,-11.74924 z"
|
||||||
|
inkscape:export-filename="../../src/werewolves/werewolves/img/gravedigger.svg"
|
||||||
|
inkscape:export-xdpi="900.08"
|
||||||
|
inkscape:export-ydpi="900.08" /></g></svg>
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 5.1 KiB |
|
|
@ -2,9 +2,9 @@
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
<svg
|
<svg
|
||||||
width="49.5746mm"
|
width="49.480812mm"
|
||||||
height="46.331978mm"
|
height="46.331978mm"
|
||||||
viewBox="0 0 49.5746 46.331978"
|
viewBox="0 0 49.480812 46.331978"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
id="svg1"
|
id="svg1"
|
||||||
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
|
@ -23,35 +23,48 @@
|
||||||
inkscape:pagecheckerboard="true"
|
inkscape:pagecheckerboard="true"
|
||||||
inkscape:deskcolor="#d1d1d1"
|
inkscape:deskcolor="#d1d1d1"
|
||||||
inkscape:document-units="mm"
|
inkscape:document-units="mm"
|
||||||
showgrid="true"
|
showgrid="false"
|
||||||
inkscape:zoom="1.4142136"
|
inkscape:zoom="0.99999999"
|
||||||
inkscape:cx="290.26733"
|
inkscape:cx="147"
|
||||||
inkscape:cy="686.60068"
|
inkscape:cy="885.50001"
|
||||||
inkscape:window-width="1918"
|
inkscape:window-width="1918"
|
||||||
inkscape:window-height="1061"
|
inkscape:window-height="1042"
|
||||||
inkscape:window-x="0"
|
inkscape:window-x="0"
|
||||||
inkscape:window-y="17"
|
inkscape:window-y="17"
|
||||||
inkscape:window-maximized="0"
|
inkscape:window-maximized="0"
|
||||||
inkscape:current-layer="layer4"><inkscape:page
|
inkscape:current-layer="layer4"><inkscape:grid
|
||||||
x="-1.2367246e-13"
|
id="grid1"
|
||||||
|
units="mm"
|
||||||
|
originx="-111.78369"
|
||||||
|
originy="-150.9173"
|
||||||
|
spacingx="0.26458333"
|
||||||
|
spacingy="0.26458334"
|
||||||
|
empcolor="#0099e5"
|
||||||
|
empopacity="0.30196078"
|
||||||
|
color="#0099e5"
|
||||||
|
opacity="0.14901961"
|
||||||
|
empspacing="5"
|
||||||
|
enabled="true"
|
||||||
|
visible="false" /><inkscape:page
|
||||||
|
x="0"
|
||||||
y="0"
|
y="0"
|
||||||
width="49.574596"
|
width="49.480812"
|
||||||
height="46.331978"
|
height="46.331978"
|
||||||
id="page2"
|
id="page2"
|
||||||
margin="0"
|
margin="0"
|
||||||
bleed="0" /></sodipodi:namedview><defs
|
bleed="0" /></sodipodi:namedview><defs
|
||||||
id="defs1"><inkscape:path-effect
|
id="defs1"><inkscape:path-effect
|
||||||
effect="mirror_symmetry"
|
effect="mirror_symmetry"
|
||||||
start_point="86.254165,185.51628"
|
start_point="86.207393,185.56305"
|
||||||
end_point="86.385181,235.08332"
|
end_point="86.338409,235.13009"
|
||||||
center_point="86.319673,210.2998"
|
center_point="86.272901,210.34657"
|
||||||
id="path-effect149"
|
id="path-effect149"
|
||||||
is_visible="true"
|
is_visible="true"
|
||||||
lpeversion="1.2"
|
lpeversion="1.2"
|
||||||
lpesatellites=""
|
lpesatellites=""
|
||||||
mode="free"
|
mode="free"
|
||||||
discard_orig_path="false"
|
discard_orig_path="false"
|
||||||
fuse_paths="false"
|
fuse_paths="true"
|
||||||
oposite_fuse="false"
|
oposite_fuse="false"
|
||||||
split_items="false"
|
split_items="false"
|
||||||
split_open="false"
|
split_open="false"
|
||||||
|
|
@ -59,14 +72,18 @@
|
||||||
inkscape:groupmode="layer"
|
inkscape:groupmode="layer"
|
||||||
id="layer4"
|
id="layer4"
|
||||||
inkscape:label="Layer 4"
|
inkscape:label="Layer 4"
|
||||||
transform="translate(-61.512867,-189.01705)"><g
|
transform="translate(-111.78369,-150.9173)"><g
|
||||||
id="g151"><path
|
id="g151"
|
||||||
|
inkscape:export-filename="../../src/werewolves/werewolves/dist/img/heart.svg"
|
||||||
|
inkscape:export-xdpi="900.08"
|
||||||
|
inkscape:export-ydpi="900.08"
|
||||||
|
transform="translate(50.270833,-38.1)"><path
|
||||||
style="fill:#ff2424;fill-opacity:1;stroke:#ff2424;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
style="fill:#ff2424;fill-opacity:1;stroke:#ff2424;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
d="m 86.254166,235.08229 c 0,0 -24.302335,-18.46127 -24.606251,-31.8823 -0.126849,-5.60168 4.153389,-12.70855 9.657292,-13.75832 5.852331,-1.11623 14.123929,1.87077 14.932422,9.82265 z m 0.262022,-6.9e-4 c 0,0 24.204402,-18.58949 24.437362,-32.01193 0.0972,-5.60228 -4.22051,-12.68642 -9.72988,-13.70708 -5.858155,-1.08528 -14.113847,1.94541 -14.880292,9.90145 z"
|
d="m 86.254166,235.08229 c 0,0 -24.302335,-18.46127 -24.606251,-31.8823 -0.126849,-5.60168 4.153389,-12.70855 9.657292,-13.75832 5.852331,-1.11623 14.123929,1.87077 14.932422,9.82265 z m 0.168232,-4.4e-4 c 0,0 24.204402,-18.58949 24.437362,-32.01194 0.0972,-5.60227 -4.22051,-12.68641 -9.72989,-13.70707 -5.858145,-1.08528 -14.113837,1.94541 -14.880282,9.90145 z"
|
||||||
id="path148"
|
id="path148"
|
||||||
sodipodi:nodetypes="caacc"
|
sodipodi:nodetypes="caacc"
|
||||||
inkscape:path-effect="#path-effect149"
|
inkscape:original-d="m 86.254166,235.08229 c 0,0 -24.302335,-18.46127 -24.606251,-31.8823 -0.126849,-5.60168 4.153389,-12.70855 9.657292,-13.75832 5.852331,-1.11623 14.123929,1.87077 14.932422,9.82265 z"
|
||||||
inkscape:original-d="m 86.254166,235.08229 c 0,0 -24.302335,-18.46127 -24.606251,-31.8823 -0.126849,-5.60168 4.153389,-12.70855 9.657292,-13.75832 5.852331,-1.11623 14.123929,1.87077 14.932422,9.82265 z" /><path
|
inkscape:path-effect="#path-effect149" /><path
|
||||||
sodipodi:type="star"
|
sodipodi:type="star"
|
||||||
style="fill:#fff001;fill-opacity:1;stroke:#ff2424;stroke-width:0.15;stroke-dasharray:none;stroke-opacity:1"
|
style="fill:#fff001;fill-opacity:1;stroke:#ff2424;stroke-width:0.15;stroke-dasharray:none;stroke-opacity:1"
|
||||||
id="path150"
|
id="path150"
|
||||||
|
|
@ -95,4 +112,19 @@
|
||||||
sodipodi:arg2="1.5925996"
|
sodipodi:arg2="1.5925996"
|
||||||
inkscape:rounded="0.5"
|
inkscape:rounded="0.5"
|
||||||
inkscape:randomized="0"
|
inkscape:randomized="0"
|
||||||
d="m 73.525842,205.79755 c -1.802133,1.72521 -2.255654,-1.4788 -4.749977,-1.5277 -2.4873,-0.0488 -3.071191,3.13767 -4.791545,1.34061 -1.725212,-1.80213 1.478793,-2.25565 1.527701,-4.74998 0.04877,-2.4873 -3.137671,-3.07119 -1.340613,-4.79154 1.802133,-1.72521 2.255655,1.47879 4.749978,1.5277 2.487299,0.0488 3.07119,-3.13767 4.791545,-1.34061 1.725212,1.80213 -1.478794,2.25565 -1.527702,4.74997 -0.04877,2.4873 3.137671,3.07119 1.340613,4.79155 z" /></g></g></svg>
|
d="m 73.525842,205.79755 c -1.802133,1.72521 -2.255654,-1.4788 -4.749977,-1.5277 -2.4873,-0.0488 -3.071191,3.13767 -4.791545,1.34061 -1.725212,-1.80213 1.478793,-2.25565 1.527701,-4.74998 0.04877,-2.4873 -3.137671,-3.07119 -1.340613,-4.79154 1.802133,-1.72521 2.255655,1.47879 4.749978,1.5277 2.487299,0.0488 3.07119,-3.13767 4.791545,-1.34061 1.725212,1.80213 -1.478794,2.25565 -1.527702,4.74997 -0.04877,2.4873 3.137671,3.07119 1.340613,4.79155 z" /></g><path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="fill:#7f6500;fill-opacity:1;stroke:#daaf00;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||||
|
id="path155-0"
|
||||||
|
inkscape:flatsided="false"
|
||||||
|
sodipodi:sides="6"
|
||||||
|
sodipodi:cx="99.020317"
|
||||||
|
sodipodi:cy="191.42604"
|
||||||
|
sodipodi:r1="7.1881213"
|
||||||
|
sodipodi:r2="4.5083508"
|
||||||
|
sodipodi:arg1="1.906205"
|
||||||
|
sodipodi:arg2="1.8672678"
|
||||||
|
inkscape:rounded="0.5"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 96.65431,198.21361 c -1.309919,0.3028 1.927067,-1.45786 1.048904,-2.4759 -2.111403,-2.44772 -3.538875,-0.60338 -5.744108,-2.96691 -0.917188,-0.98302 2.22608,0.93996 2.668647,-0.32957 1.064081,-3.05239 -1.2469,-3.36644 -0.30264,-6.458 0.392731,-1.28582 0.299014,2.39782 1.619743,2.14633 3.175484,-0.60467 2.291975,-2.76307 5.441464,-3.49109 1.30992,-0.30279 -1.927062,1.45787 -1.0489,2.4759 2.1114,2.44772 3.53888,0.60338 5.74411,2.96691 0.91719,0.98302 -2.22608,-0.93996 -2.66865,0.32957 -1.06408,3.05239 1.2469,3.36645 0.30264,6.458 -0.39273,1.28582 -0.29901,-2.39782 -1.61974,-2.14633 -3.175485,0.60467 -2.291977,2.76307 -5.44147,3.49109 z"
|
||||||
|
transform="translate(6.9985536,-38.801292)" /></g></svg>
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 6.5 KiB |
|
|
@ -23,16 +23,29 @@
|
||||||
inkscape:pagecheckerboard="true"
|
inkscape:pagecheckerboard="true"
|
||||||
inkscape:deskcolor="#d1d1d1"
|
inkscape:deskcolor="#d1d1d1"
|
||||||
inkscape:document-units="mm"
|
inkscape:document-units="mm"
|
||||||
showgrid="true"
|
showgrid="false"
|
||||||
inkscape:zoom="0.5"
|
inkscape:zoom="2.8284272"
|
||||||
inkscape:cx="-77"
|
inkscape:cx="35.885668"
|
||||||
inkscape:cy="466"
|
inkscape:cy="411.71291"
|
||||||
inkscape:window-width="1918"
|
inkscape:window-width="1918"
|
||||||
inkscape:window-height="1061"
|
inkscape:window-height="1042"
|
||||||
inkscape:window-x="0"
|
inkscape:window-x="0"
|
||||||
inkscape:window-y="17"
|
inkscape:window-y="17"
|
||||||
inkscape:window-maximized="0"
|
inkscape:window-maximized="0"
|
||||||
inkscape:current-layer="layer4"><inkscape:page
|
inkscape:current-layer="layer4"><inkscape:grid
|
||||||
|
id="grid1"
|
||||||
|
units="mm"
|
||||||
|
originx="-1.6153444"
|
||||||
|
originy="-96.526486"
|
||||||
|
spacingx="0.26458333"
|
||||||
|
spacingy="0.26458334"
|
||||||
|
empcolor="#0099e5"
|
||||||
|
empopacity="0.30196078"
|
||||||
|
color="#0099e5"
|
||||||
|
opacity="0.14901961"
|
||||||
|
empspacing="5"
|
||||||
|
enabled="true"
|
||||||
|
visible="false" /><inkscape:page
|
||||||
x="0"
|
x="0"
|
||||||
y="0"
|
y="0"
|
||||||
width="24.399992"
|
width="24.399992"
|
||||||
|
|
@ -60,85 +73,87 @@
|
||||||
id="layer4"
|
id="layer4"
|
||||||
inkscape:label="Layer 4"
|
inkscape:label="Layer 4"
|
||||||
transform="translate(-1.6153444,-96.526492)"><g
|
transform="translate(-1.6153444,-96.526492)"><g
|
||||||
id="g179"><g
|
id="g166-2"
|
||||||
id="g166-2"
|
inkscape:path-effect="#path-effect166-2"
|
||||||
inkscape:path-effect="#path-effect166-2"
|
style="fill:#ff0707;fill-opacity:0.697154;stroke:#c10000;stroke-width:0.4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
style="fill:#ff0505;fill-opacity:0.7;stroke:#c20000;stroke-width:0.4;stroke-dasharray:none;stroke-opacity:0.5"
|
transform="matrix(1.728,0,0,1.728,-72.928813,-210.62831)"
|
||||||
transform="translate(-36.557573,-76.085222)"
|
inkscape:export-filename="hunter.svg"
|
||||||
inkscape:export-filename="../../src/werewolves/werewolves/img/hunter.svg"
|
inkscape:export-xdpi="900.08"
|
||||||
inkscape:export-xdpi="900.08"
|
inkscape:export-ydpi="900.08"><path
|
||||||
inkscape:export-ydpi="900.08"><path
|
id="path164-8"
|
||||||
id="path164-8"
|
style="fill:#ff0707;fill-opacity:0.697154;stroke:#c10000;stroke-width:0.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||||
style="fill:#ff0505;fill-opacity:0.7;stroke:#c20000;stroke-width:0.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:0.5;paint-order:normal"
|
d="m 50.373047,183.43359 c -1.534096,0.26874 -1.029204,1.24619 -1.832031,2.63672 -0.65564,1.13559 -1.854319,1.39291 -1.029297,2.41211 0.94012,1.1614 1.512735,0.45231 2.861328,0.33008 1.348593,0.12223 1.921208,0.83132 2.861328,-0.33008 0.825022,-1.0192 -0.373657,-1.27652 -1.029297,-2.41211 -0.802827,-1.39053 -0.297935,-2.36798 -1.832031,-2.63672 z"
|
||||||
d="m 50.373047,183.43359 c -1.534096,0.26874 -1.029204,1.24619 -1.832031,2.63672 -0.65564,1.13559 -1.854319,1.39291 -1.029297,2.41211 0.94012,1.1614 1.512735,0.45231 2.861328,0.33008 1.348593,0.12223 1.921208,0.83132 2.861328,-0.33008 0.825022,-1.0192 -0.373657,-1.27652 -1.029297,-2.41211 -0.802827,-1.39053 -0.297935,-2.36798 -1.832031,-2.63672 z"
|
inkscape:original-d="m 50.372741,183.43371 c -1.534096,0.26874 -1.028586,1.24549 -1.831413,2.63602 -0.65564,1.13559 -1.854933,1.39253 -1.029911,2.41173 0.94012,1.1614 1.512731,0.45348 2.861324,0.33125 z" /><path
|
||||||
inkscape:original-d="m 50.372741,183.43371 c -1.534096,0.26874 -1.028586,1.24549 -1.831413,2.63602 -0.65564,1.13559 -1.854933,1.39253 -1.029911,2.41173 0.94012,1.1614 1.512731,0.45348 2.861324,0.33125 z" /><path
|
sodipodi:type="star"
|
||||||
sodipodi:type="star"
|
style="fill:#ff0707;fill-opacity:0.697154;stroke:#c10000;stroke-width:0.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||||
style="fill:#ff0505;fill-opacity:0.7;stroke:#c20000;stroke-width:0.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:0.5;paint-order:normal"
|
id="path165-3"
|
||||||
id="path165-3"
|
inkscape:flatsided="false"
|
||||||
inkscape:flatsided="false"
|
sodipodi:sides="2"
|
||||||
sodipodi:sides="2"
|
sodipodi:cx="51.634216"
|
||||||
sodipodi:cx="51.634216"
|
sodipodi:cy="182.45293"
|
||||||
sodipodi:cy="182.45293"
|
sodipodi:r1="1.3725731"
|
||||||
sodipodi:r1="1.3725731"
|
sodipodi:r2="0.82291079"
|
||||||
sodipodi:r2="0.82291079"
|
sodipodi:arg1="1.1071487"
|
||||||
sodipodi:arg1="1.1071487"
|
sodipodi:arg2="2.677945"
|
||||||
sodipodi:arg2="2.677945"
|
inkscape:rounded="0.5"
|
||||||
inkscape:rounded="0.5"
|
inkscape:randomized="0"
|
||||||
inkscape:randomized="0"
|
d="m 52.24805,183.68059 c -0.715701,0.35785 -0.992017,-0.14395 -1.349867,-0.85965 -0.357851,-0.7157 -0.593501,-1.23783 0.1222,-1.59568 0.715701,-0.35785 0.992017,0.14395 1.349867,0.85965 0.357851,0.7157 0.593501,1.23783 -0.1222,1.59568 z m 5.18186,0 c 0.7157,0.35785 0.992016,-0.14395 1.349867,-0.85965 0.35785,-0.7157 0.5935,-1.23783 -0.122201,-1.59568 -0.715701,-0.35785 -0.992016,0.14395 -1.349867,0.85965 -0.35785,0.7157 -0.5935,1.23783 0.122201,1.59568 z"
|
||||||
d="m 52.24805,183.68059 c -0.715701,0.35785 -0.992017,-0.14395 -1.349867,-0.85965 -0.357851,-0.7157 -0.593501,-1.23783 0.1222,-1.59568 0.715701,-0.35785 0.992017,0.14395 1.349867,0.85965 0.357851,0.7157 0.593501,1.23783 -0.1222,1.59568 z m 5.18186,0 c 0.7157,0.35785 0.992016,-0.14395 1.349867,-0.85965 0.35785,-0.7157 0.5935,-1.23783 -0.122201,-1.59568 -0.715701,-0.35785 -0.992016,0.14395 -1.349867,0.85965 -0.35785,0.7157 -0.5935,1.23783 0.122201,1.59568 z"
|
inkscape:transform-center-x="0.12681959"
|
||||||
inkscape:transform-center-x="0.12681959"
|
inkscape:transform-center-y="0.079724714"
|
||||||
inkscape:transform-center-y="0.079724714"
|
transform="translate(-4.4662386,1.8414355)" /><path
|
||||||
transform="translate(-4.4662386,1.8414355)" /><path
|
sodipodi:type="star"
|
||||||
sodipodi:type="star"
|
style="fill:#ff0707;fill-opacity:0.697154;stroke:#c10000;stroke-width:0.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||||
style="fill:#ff0505;fill-opacity:0.7;stroke:#c20000;stroke-width:0.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:0.5;paint-order:normal"
|
id="path165-6-8"
|
||||||
id="path165-6-8"
|
inkscape:flatsided="false"
|
||||||
inkscape:flatsided="false"
|
sodipodi:sides="2"
|
||||||
sodipodi:sides="2"
|
sodipodi:cx="51.634216"
|
||||||
sodipodi:cx="51.634216"
|
sodipodi:cy="182.45293"
|
||||||
sodipodi:cy="182.45293"
|
sodipodi:r1="1.3725731"
|
||||||
sodipodi:r1="1.3725731"
|
sodipodi:r2="0.82291079"
|
||||||
sodipodi:r2="0.82291079"
|
sodipodi:arg1="1.1071487"
|
||||||
sodipodi:arg1="1.1071487"
|
sodipodi:arg2="2.677945"
|
||||||
sodipodi:arg2="2.677945"
|
inkscape:rounded="0.5"
|
||||||
inkscape:rounded="0.5"
|
inkscape:randomized="0"
|
||||||
inkscape:randomized="0"
|
d="m 52.24805,183.68059 c -0.715701,0.35785 -0.992017,-0.14395 -1.349867,-0.85965 -0.357851,-0.7157 -0.593501,-1.23783 0.1222,-1.59568 0.715701,-0.35785 0.992017,0.14395 1.349867,0.85965 0.357851,0.7157 0.593501,1.23783 -0.1222,1.59568 z m 2.374602,-1.10775 c 0.734072,-0.31847 0.527114,-0.85263 0.208644,-1.5867 -0.31847,-0.73407 -0.567138,-1.25013 -1.30121,-0.93166 -0.734072,0.31847 -0.527114,0.85263 -0.208644,1.5867 0.31847,0.73407 0.567138,1.25013 1.30121,0.93166 z"
|
||||||
d="m 52.24805,183.68059 c -0.715701,0.35785 -0.992017,-0.14395 -1.349867,-0.85965 -0.357851,-0.7157 -0.593501,-1.23783 0.1222,-1.59568 0.715701,-0.35785 0.992017,0.14395 1.349867,0.85965 0.357851,0.7157 0.593501,1.23783 -0.1222,1.59568 z m 2.374602,-1.10775 c 0.734072,-0.31847 0.527114,-0.85263 0.208644,-1.5867 -0.31847,-0.73407 -0.567138,-1.25013 -1.30121,-0.93166 -0.734072,0.31847 -0.527114,0.85263 -0.208644,1.5867 0.31847,0.73407 0.567138,1.25013 1.30121,0.93166 z"
|
inkscape:transform-center-x="0.14863452"
|
||||||
inkscape:transform-center-x="0.14863452"
|
inkscape:transform-center-y="0.01863483"
|
||||||
inkscape:transform-center-y="0.01863483"
|
transform="rotate(25.009099,51.670619,176.27381)" /></g><g
|
||||||
transform="rotate(25.009099,51.670619,176.27381)" /></g><g
|
id="g6"
|
||||||
id="g178"><path
|
inkscape:export-filename="../../src/werewolves/werewolves/img/hunter.svg"
|
||||||
id="path166-0"
|
inkscape:export-xdpi="900.08"
|
||||||
style="fill:#0f07ff;fill-opacity:1;stroke:#05009e;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
inkscape:export-ydpi="900.08"><path
|
||||||
d="m 13.815426,98.72668 c -5.522776,5e-5 -10.000374,4.47713 -10.000423,9.99991 4.9e-5,5.52277 4.477647,9.99985 10.000423,9.9999 5.522777,-5e-5 9.999857,-4.47713 9.999907,-9.9999 -5e-5,-5.52278 -4.47713,-9.99986 -9.999907,-9.99991 z m 0,1.99988 c 4.418297,-2e-5 8.000047,3.58172 8.000027,8.00003 2e-5,4.4183 -3.58173,8.00004 -8.000027,8.00002 -4.418301,2e-5 -8.000045,-3.58172 -8.000029,-8.00002 -1.6e-5,-4.41831 3.581728,-8.00005 8.000029,-8.00003 z" /><rect
|
id="path166-0"
|
||||||
style="fill:#0f07ff;fill-opacity:1;stroke:#05009e;stroke-width:0.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
style="fill:#0f07ff;fill-opacity:0.496669;stroke:#05009e;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||||
id="rect167-8-0-4"
|
d="m 13.815426,98.72668 c -5.522776,5e-5 -10.000374,4.47713 -10.000423,9.99991 4.9e-5,5.52277 4.477647,9.99985 10.000423,9.9999 5.522777,-5e-5 9.999857,-4.47713 9.999907,-9.9999 -5e-5,-5.52278 -4.47713,-9.99986 -9.999907,-9.99991 z m 0,1.99988 c 4.418297,-2e-5 8.000047,3.58172 8.000027,8.00003 2e-5,4.4183 -3.58173,8.00004 -8.000027,8.00002 -4.418301,2e-5 -8.000045,-3.58172 -8.000029,-8.00002 -1.6e-5,-4.41831 3.581728,-8.00005 8.000029,-8.00003 z" /><rect
|
||||||
width="1.5"
|
style="fill:#0f07ff;fill-opacity:1;stroke:#05009e;stroke-width:0.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||||
height="6"
|
id="rect167-8-0-4"
|
||||||
x="-109.47657"
|
width="1.5"
|
||||||
y="19.815336"
|
height="6"
|
||||||
transform="rotate(-90)"
|
x="-109.47657"
|
||||||
ry="0" /><rect
|
y="19.815336"
|
||||||
style="fill:#0f07ff;fill-opacity:1;stroke:#05009e;stroke-width:0.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
transform="rotate(-90)"
|
||||||
id="rect167-8-0-9-2"
|
ry="0" /><rect
|
||||||
width="1.5"
|
style="fill:#0f07ff;fill-opacity:1;stroke:#05009e;stroke-width:0.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||||
height="6"
|
id="rect167-8-0-9-2"
|
||||||
x="-109.47657"
|
width="1.5"
|
||||||
y="1.8153445"
|
height="6"
|
||||||
transform="rotate(-90)"
|
x="-109.47657"
|
||||||
ry="0" /><rect
|
y="1.8153445"
|
||||||
style="fill:#0f07ff;fill-opacity:1;stroke:#05009e;stroke-width:0.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
transform="rotate(-90)"
|
||||||
id="rect167-8-0-1-2"
|
ry="0" /><rect
|
||||||
width="1.5"
|
style="fill:#0f07ff;fill-opacity:1;stroke:#05009e;stroke-width:0.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||||
height="6"
|
id="rect167-8-0-1-2"
|
||||||
x="-14.56517"
|
width="1.5"
|
||||||
y="-120.72649"
|
height="6"
|
||||||
transform="scale(-1)"
|
x="-14.56517"
|
||||||
ry="0" /><rect
|
y="-120.72649"
|
||||||
style="fill:#0f07ff;fill-opacity:1;stroke:#05009e;stroke-width:0.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
transform="scale(-1)"
|
||||||
id="rect167-8-0-1-7-2"
|
ry="0" /><rect
|
||||||
width="1.5"
|
style="fill:#0f07ff;fill-opacity:1;stroke:#05009e;stroke-width:0.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||||
height="6"
|
id="rect167-8-0-1-7-2"
|
||||||
x="-14.56517"
|
width="1.5"
|
||||||
y="-102.72649"
|
height="6"
|
||||||
transform="scale(-1)"
|
x="-14.56517"
|
||||||
ry="0" /></g></g></g></svg>
|
y="-102.72649"
|
||||||
|
transform="scale(-1)"
|
||||||
|
ry="0" /></g></g></svg>
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 127 KiB |
|
|
@ -0,0 +1,87 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="23.228039mm"
|
||||||
|
height="25.150064mm"
|
||||||
|
viewBox="0 0 23.228039 25.150064"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
sodipodi:docname="icons.svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="true"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.4142136"
|
||||||
|
inkscape:cx="233.34524"
|
||||||
|
inkscape:cy="503.81359"
|
||||||
|
inkscape:window-width="1918"
|
||||||
|
inkscape:window-height="1042"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="17"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="layer4"><inkscape:grid
|
||||||
|
id="grid1"
|
||||||
|
units="mm"
|
||||||
|
originx="-138.94072"
|
||||||
|
originy="-238.20293"
|
||||||
|
spacingx="0.26458333"
|
||||||
|
spacingy="0.26458334"
|
||||||
|
empcolor="#0099e5"
|
||||||
|
empopacity="0.30196078"
|
||||||
|
color="#0099e5"
|
||||||
|
opacity="0.14901961"
|
||||||
|
empspacing="5"
|
||||||
|
enabled="true"
|
||||||
|
visible="false" /><inkscape:page
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="23.228039"
|
||||||
|
height="25.150064"
|
||||||
|
id="page2"
|
||||||
|
margin="0"
|
||||||
|
bleed="0" /></sodipodi:namedview><defs
|
||||||
|
id="defs1" /><g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer4"
|
||||||
|
inkscape:label="Layer 4"
|
||||||
|
transform="translate(-138.94072,-238.20292)"><g
|
||||||
|
id="g10-8"
|
||||||
|
inkscape:export-filename="mortician.svg"
|
||||||
|
inkscape:export-xdpi="900.08"
|
||||||
|
inkscape:export-ydpi="900.08"
|
||||||
|
transform="translate(21.695837,13.62604)"><path
|
||||||
|
id="rect1-3-9-4"
|
||||||
|
style="fill:#803300;fill-opacity:1;stroke:#441b00;stroke-width:0.860999;stroke-opacity:1"
|
||||||
|
d="m 124.55133,225.72321 -4,4.95837 v 4.079 l 4,14.53587 h 4.347 l 4,-14.53587 v -4.079 l -4,-4.95837 z"
|
||||||
|
sodipodi:nodetypes="ccccccccc"
|
||||||
|
inkscape:export-filename="mortician.svg"
|
||||||
|
inkscape:export-xdpi="900.08"
|
||||||
|
inkscape:export-ydpi="900.08" /><path
|
||||||
|
id="path145-7-2-2-5"
|
||||||
|
style="fill:#ffffff;fill-opacity:0.5;stroke:#441b00;stroke-width:0.232;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 126.68415,227.8032 c -0.48287,0.009 -0.96527,0.0916 -1.42058,0.25373 -1.73872,0.59694 -3.34207,0.9627 -3.03444,4.1274 -0.0658,0.94137 -0.0783,1.89737 0.0641,2.83239 0.0777,0.53633 0.38267,1.09991 0.88883,1.32446 0.44618,0.0891 0.98521,-0.0139 1.31258,0.39223 0.88847,0.68196 0.34997,2.06997 1.02836,1.973 0.4264,-0.0609 0.13618,-0.73886 0.26097,-0.80202 0.19269,-0.0975 0.18134,-0.0608 0.24185,0.18087 0.0324,0.38247 -0.0524,0.69761 0.28112,0.66198 0.55057,-0.0588 0.28691,-0.48129 0.32814,-0.95808 0.0732,-0.0163 0.0871,-0.0125 0.0894,-0.0114 h 5.2e-4 c 0.002,-0.001 0.0162,-0.005 0.0894,0.0114 0.0412,0.47679 -0.22243,0.89925 0.32814,0.95808 0.33357,0.0356 0.24869,-0.27951 0.28112,-0.66198 0.0605,-0.2417 0.0491,-0.27839 0.24185,-0.18087 0.12479,0.0632 -0.16544,0.74107 0.26096,0.80202 0.6784,0.097 0.13989,-1.29104 1.02836,-1.973 0.32738,-0.40615 0.86641,-0.30311 1.31258,-0.39223 0.50616,-0.22455 0.81169,-0.78813 0.88936,-1.32446 0.14238,-0.93502 0.12931,-1.89102 0.0636,-2.83239 0.30762,-3.1647 -1.29573,-3.53046 -3.03444,-4.1274 -0.45531,-0.16216 -0.93772,-0.24475 -1.42059,-0.25373 -0.0135,0 -0.0266,-1e-4 -0.0403,0 -0.0137,-1e-4 -0.0273,0 -0.0408,0 z m -2.07274,4.18424 c 0.70354,-0.004 1.02182,0.49934 1.09451,0.7059 0.46265,1.11185 -0.3731,1.45665 -1.17409,1.42576 -0.69999,0.0989 -1.25842,0.0508 -1.34256,-1.01286 -0.01,-0.33209 0.30891,-0.96177 1.09658,-1.08366 0.11665,-0.0235 0.22505,-0.0346 0.32556,-0.0351 z m 4.22661,0 c 0.10051,5.1e-4 0.20892,0.0116 0.32556,0.0351 0.78767,0.12189 1.10659,0.75157 1.09658,1.08366 -0.0841,1.06367 -0.64257,1.11173 -1.34256,1.01286 -0.80099,0.0309 -1.63674,-0.31391 -1.17408,-1.42576 0.0727,-0.20656 0.39096,-0.70943 1.0945,-0.7059 z m -2.11305,2.94194 c 0.2152,0.0216 0.28407,0.38489 0.58343,0.77618 0.27686,0.50031 -0.16476,0.69652 -0.40979,0.48318 -0.14652,-0.11734 -0.17112,-0.12967 -0.17364,-0.13074 -0.002,0.001 -0.0276,0.0134 -0.17414,0.13074 -0.24504,0.21334 -0.68666,0.0171 -0.4098,-0.48318 0.29936,-0.39129 0.36875,-0.75459 0.58394,-0.77618 z" /></g><g
|
||||||
|
id="g9-5-0"
|
||||||
|
transform="matrix(1.4662567,-1.4662567,1.4662567,1.4662567,-373.25727,72.676841)"
|
||||||
|
style="stroke:#231f7b;stroke-opacity:1"><circle
|
||||||
|
style="fill:#1bd9ff;fill-opacity:0.394368;stroke:#231f7b;stroke-width:0.860999;stroke-opacity:1"
|
||||||
|
id="path2-9-3"
|
||||||
|
cx="118.21665"
|
||||||
|
cy="237.36874"
|
||||||
|
r="4" /><path
|
||||||
|
style="fill:none;stroke:#231f7b;stroke-width:1.15033;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 118.21665,241.199 -0.15789,5.31553"
|
||||||
|
id="path6-2-6"
|
||||||
|
sodipodi:nodetypes="cc" /></g></g></svg>
|
||||||
|
After Width: | Height: | Size: 5.1 KiB |
|
|
@ -0,0 +1,95 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="22.945572mm"
|
||||||
|
height="28.24629mm"
|
||||||
|
viewBox="0 0 22.945572 28.24629"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
sodipodi:docname="icons.svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="true"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="2.8284272"
|
||||||
|
inkscape:cx="329.68853"
|
||||||
|
inkscape:cy="1037.856"
|
||||||
|
inkscape:window-width="1918"
|
||||||
|
inkscape:window-height="1042"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="17"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="layer4"><inkscape:grid
|
||||||
|
id="grid1"
|
||||||
|
units="mm"
|
||||||
|
originx="-84.294216"
|
||||||
|
originy="-256.51758"
|
||||||
|
spacingx="0.26458333"
|
||||||
|
spacingy="0.26458334"
|
||||||
|
empcolor="#0099e5"
|
||||||
|
empopacity="0.30196078"
|
||||||
|
color="#0099e5"
|
||||||
|
opacity="0.14901961"
|
||||||
|
empspacing="5"
|
||||||
|
enabled="true"
|
||||||
|
visible="false" /><inkscape:page
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="22.945572"
|
||||||
|
height="28.24629"
|
||||||
|
id="page2"
|
||||||
|
margin="0"
|
||||||
|
bleed="0" /></sodipodi:namedview><defs
|
||||||
|
id="defs1" /><g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer4"
|
||||||
|
inkscape:label="Layer 4"
|
||||||
|
transform="translate(-84.29421,-256.51757)"><g
|
||||||
|
id="g17"><path
|
||||||
|
id="path13-2"
|
||||||
|
style="fill:#ff0707;fill-opacity:0.796663;stroke:#ffbb33;stroke-width:0.665;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 102.26758,259.22827 -4.652431,14.9748 c 0,0 -3.853406,-2.83967 -6.441467,-7.23625 -0.281201,4.36457 0.45945,18.75999 11.093898,19.05465 10.63444,-0.29466 11.37665,-14.69008 11.09545,-19.05465 -2.58806,4.39658 -6.44097,7.23625 -6.44096,7.23625 z m -6.895188,20.4246 h 4.976438 a 2.48832,2.48832 0 0 1 -2.488217,2.48822 2.48832,2.48832 0 0 1 -2.488221,-2.48822 z m 8.815478,0 h 4.97645 a 2.48832,2.48832 0 0 1 -2.48822,2.48822 2.48832,2.48832 0 0 1 -2.48823,-2.48822 z"
|
||||||
|
transform="translate(-6.5013311,-1.5902536)" /><path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="fill:#ff0707;fill-opacity:0.796663;stroke:#ffbb33;stroke-width:0.665001;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path14"
|
||||||
|
inkscape:flatsided="false"
|
||||||
|
sodipodi:sides="3"
|
||||||
|
sodipodi:cx="63.610146"
|
||||||
|
sodipodi:cy="259.77261"
|
||||||
|
sodipodi:r1="2.4050174"
|
||||||
|
sodipodi:r2="0.8495208"
|
||||||
|
sodipodi:arg1="1.3352513"
|
||||||
|
sodipodi:arg2="2.2426747"
|
||||||
|
inkscape:rounded="0.2"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 64.171412,262.11122 c -0.371671,0.14644 -0.815095,-1.38393 -1.090057,-1.67373 -0.307066,-0.32362 -1.843044,-0.90688 -1.777137,-1.34811 0.05902,-0.3951 1.606071,-0.0139 1.994519,-0.10715 0.433804,-0.10412 1.706909,-1.14268 2.05607,-0.86499 0.312654,0.24866 -0.790976,1.39786 -0.904463,1.78088 -0.126738,0.42774 0.136135,2.04957 -0.278932,2.2131 z"
|
||||||
|
transform="translate(25.967913,5.8850319)" /><path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="fill:#ff0707;fill-opacity:0.796663;stroke:#ffbb33;stroke-width:0.665001;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path15"
|
||||||
|
inkscape:flatsided="false"
|
||||||
|
sodipodi:sides="4"
|
||||||
|
sodipodi:cx="73.712936"
|
||||||
|
sodipodi:cy="258.36945"
|
||||||
|
sodipodi:r1="1.9284658"
|
||||||
|
sodipodi:r2="1.1014973"
|
||||||
|
sodipodi:arg1="1.3258177"
|
||||||
|
sodipodi:arg2="2.1112159"
|
||||||
|
inkscape:rounded="0.2"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 74.180658,260.24033 c -0.269428,0.0674 -0.796295,-0.78347 -1.034437,-0.92636 -0.238143,-0.14288 -1.236814,-0.20738 -1.304171,-0.4768 -0.06736,-0.26943 0.783475,-0.7963 0.92636,-1.03444 0.142886,-0.23814 0.207377,-1.23681 0.476805,-1.30417 0.269427,-0.0674 0.796295,0.78347 1.034437,0.92636 0.238143,0.14289 1.236814,0.20738 1.304171,0.4768 0.06736,0.26943 -0.783475,0.7963 -0.926361,1.03444 -0.142885,0.23814 -0.207376,1.23682 -0.476804,1.30417 z"
|
||||||
|
transform="translate(28.887732,7.0275078)" /></g></g></svg>
|
||||||
|
After Width: | Height: | Size: 4.4 KiB |
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="53.178997mm"
|
||||||
|
height="53.178989mm"
|
||||||
|
viewBox="0 0 53.178997 53.178989"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
sodipodi:docname="icons.svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="true"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.7071068"
|
||||||
|
inkscape:cx="-43.133512"
|
||||||
|
inkscape:cy="1034.4972"
|
||||||
|
inkscape:window-width="1918"
|
||||||
|
inkscape:window-height="1042"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="17"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="layer4"><inkscape:grid
|
||||||
|
id="grid1"
|
||||||
|
units="mm"
|
||||||
|
originx="-22.053554"
|
||||||
|
originy="-242.63108"
|
||||||
|
spacingx="0.26458333"
|
||||||
|
spacingy="0.26458334"
|
||||||
|
empcolor="#0099e5"
|
||||||
|
empopacity="0.30196078"
|
||||||
|
color="#0099e5"
|
||||||
|
opacity="0.14901961"
|
||||||
|
empspacing="5"
|
||||||
|
enabled="true"
|
||||||
|
visible="false" /><inkscape:page
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="53.178997"
|
||||||
|
height="53.178989"
|
||||||
|
id="page2"
|
||||||
|
margin="0"
|
||||||
|
bleed="0" /></sodipodi:namedview><defs
|
||||||
|
id="defs1" /><g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer4"
|
||||||
|
inkscape:label="Layer 4"
|
||||||
|
transform="translate(-22.053555,-242.63109)"><g
|
||||||
|
id="g19"><circle
|
||||||
|
style="fill:#ff2424;fill-opacity:1;stroke:#c10000;stroke-width:3.179;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path18"
|
||||||
|
cx="48.643055"
|
||||||
|
cy="269.22058"
|
||||||
|
r="25" /><rect
|
||||||
|
style="fill:#ffffff;fill-opacity:0.902751;stroke:none;stroke-width:7.48793;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="rect19"
|
||||||
|
width="30"
|
||||||
|
height="10"
|
||||||
|
x="33.643055"
|
||||||
|
y="264.22058" /><circle
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:0.5;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path19"
|
||||||
|
cx="48.643055"
|
||||||
|
cy="269.22058"
|
||||||
|
r="25" /></g></g></svg>
|
||||||
|
After Width: | Height: | Size: 2.5 KiB |
|
|
@ -0,0 +1,68 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="61.086262mm"
|
||||||
|
height="70.948692mm"
|
||||||
|
viewBox="0 0 61.086262 70.948692"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
sodipodi:docname="icons.svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="true"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.99999999"
|
||||||
|
inkscape:cx="147"
|
||||||
|
inkscape:cy="885.50001"
|
||||||
|
inkscape:window-width="1918"
|
||||||
|
inkscape:window-height="1042"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="17"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="layer4"><inkscape:grid
|
||||||
|
id="grid1"
|
||||||
|
units="mm"
|
||||||
|
originx="-14.168536"
|
||||||
|
originy="-171.71318"
|
||||||
|
spacingx="0.26458333"
|
||||||
|
spacingy="0.26458334"
|
||||||
|
empcolor="#0099e5"
|
||||||
|
empopacity="0.30196078"
|
||||||
|
color="#0099e5"
|
||||||
|
opacity="0.14901961"
|
||||||
|
empspacing="5"
|
||||||
|
enabled="true"
|
||||||
|
visible="false" /><inkscape:page
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="61.086262"
|
||||||
|
height="70.948692"
|
||||||
|
id="page2"
|
||||||
|
margin="0"
|
||||||
|
bleed="0" /></sodipodi:namedview><defs
|
||||||
|
id="defs1" /><g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer4"
|
||||||
|
inkscape:label="Layer 4"
|
||||||
|
transform="translate(-14.168537,-171.71318)"><path
|
||||||
|
id="rect55"
|
||||||
|
style="display:none;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.7;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 54.680079,205.91192 0.0075,3.95139 h -0.02186 v 1.21435 h 2.712393 v 25.2552 l 0.5302,0.68461 0.58136,-0.68461 v -25.2552 h 2.712392 v -1.21435 h -0.02232 l -0.007,-3.95139 -0.404006,-1.44994 -0.408967,1.44994 0.007,3.95139 h -1.877095 -0.149294 l -0.0075,-3.95139 -0.440632,-1.43824 -0.372342,1.43824 0.007,3.95139 H 57.37808 55.50052 l -0.007,-3.95139 -0.442679,-1.43824 z"
|
||||||
|
sodipodi:nodetypes="ccccccccccccccccccccccccccc" /><path
|
||||||
|
id="path145-5"
|
||||||
|
style="fill:#0f07ff;fill-opacity:0.698287;stroke:#05009e;stroke-width:0.661;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 15.328263,172.81891 c -0.006,0.0619 -1.574466,16.33979 -0.360701,22.78207 1.118918,5.93888 7.519695,11.32363 7.269324,13.90044 -1.315571,12.29009 4.666937,14.58151 11.327474,22.74745 4.44235,3.40984 1.748274,10.34937 5.140254,9.86452 2.132,-0.30475 0.68242,-3.69534 1.30638,-4.01113 0.96346,-0.48761 0.906162,-0.30316 1.208712,0.90537 0.16213,1.91232 -0.261724,3.48859 1.406116,3.3104 2.75286,-0.29411 1.433523,-2.40746 1.639693,-4.79144 0.380196,-0.0845 0.440732,-0.0612 0.448552,-0.0563 h 5.16e-4 5.17e-4 l 5.17e-4,-5.2e-4 c 0.011,-0.006 0.07972,-0.025 0.448035,0.0568 0.20617,2.38398 -1.113167,4.49733 1.639693,4.79144 1.66784,0.17819 1.243985,-1.39808 1.406115,-3.3104 0.30255,-1.20853 0.245252,-1.39298 1.208712,-0.90537 0.62396,0.31579 -0.82562,3.70638 1.30638,4.01113 3.39198,0.48485 0.697905,-6.45468 5.140255,-9.86452 6.660537,-8.16594 12.643045,-10.45736 11.327474,-22.74745 -0.250371,-2.57681 6.150409,-7.96156 7.269324,-13.90044 1.21447,-6.44598 -0.357038,-22.73876 -0.361218,-22.78207 -1.22374,2.2493 -4.89321,20.52768 -12.072649,25.27649 -5.697887,4.31136 -17.377299,5.29548 -17.377299,5.29548 -6.311171,0.0296 -12.005471,-1.80477 -17.250039,-5.29548 -7.179344,-4.74875 -10.848343,-23.02679 -12.072132,-25.27649 z m 18.820557,35.70015 c 3.51769,-0.0177 5.108051,2.49515 5.471501,3.52795 2.31327,5.55922 -1.864976,7.28272 -5.869926,7.12824 -3.49992,0.49438 -6.292069,0.25355 -6.712769,-5.0648 -0.05005,-1.66043 1.545046,-4.80782 5.483386,-5.41725 0.58324,-0.11752 1.125278,-0.17162 1.627808,-0.17414 z m 21.131527,0 c 0.50253,0.003 1.044567,0.0566 1.627807,0.17414 3.93834,0.60943 5.533437,3.75682 5.483387,5.41725 -0.4207,5.31835 -3.212849,5.55918 -6.712769,5.0648 -4.00495,0.15448 -8.183196,-1.56902 -5.869926,-7.12824 0.36345,-1.0328 1.953811,-3.54565 5.471501,-3.52795 z m -10.661365,14.72313 h 0.190686 c 1.002355,0.2034 1.370965,1.9696 2.822567,3.86694 1.38429,2.50156 -0.823801,3.48209 -2.048971,2.41536 -0.781777,-0.62611 -0.869157,-0.65369 -0.869197,-0.65371 -4e-5,2e-5 -0.08742,0.0276 -0.869198,0.65371 -1.22517,1.06673 -3.433261,0.0862 -2.048971,-2.41536 1.451602,-1.89734 1.820729,-3.66354 2.823084,-3.86694 z"
|
||||||
|
sodipodi:nodetypes="csccsscsccccccscssccscccccccccccccccccccccscccc" /></g></svg>
|
||||||
|
After Width: | Height: | Size: 4.7 KiB |
|
|
@ -2,9 +2,9 @@
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
<svg
|
<svg
|
||||||
width="45.428978mm"
|
width="46.290329mm"
|
||||||
height="54.734951mm"
|
height="55.595428mm"
|
||||||
viewBox="0 0 45.428978 54.734951"
|
viewBox="0 0 46.290329 55.595428"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
id="svg1"
|
id="svg1"
|
||||||
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
|
@ -23,35 +23,48 @@
|
||||||
inkscape:pagecheckerboard="true"
|
inkscape:pagecheckerboard="true"
|
||||||
inkscape:deskcolor="#d1d1d1"
|
inkscape:deskcolor="#d1d1d1"
|
||||||
inkscape:document-units="mm"
|
inkscape:document-units="mm"
|
||||||
showgrid="true"
|
showgrid="false"
|
||||||
inkscape:zoom="1.4142136"
|
inkscape:zoom="1.4142136"
|
||||||
inkscape:cx="204.00031"
|
inkscape:cx="558.61436"
|
||||||
inkscape:cy="749.53319"
|
inkscape:cy="667.15525"
|
||||||
inkscape:window-width="1918"
|
inkscape:window-width="1918"
|
||||||
inkscape:window-height="1061"
|
inkscape:window-height="1042"
|
||||||
inkscape:window-x="0"
|
inkscape:window-x="0"
|
||||||
inkscape:window-y="17"
|
inkscape:window-y="17"
|
||||||
inkscape:window-maximized="0"
|
inkscape:window-maximized="0"
|
||||||
inkscape:current-layer="layer4"><inkscape:page
|
inkscape:current-layer="layer4"><inkscape:grid
|
||||||
x="0"
|
id="grid1"
|
||||||
|
units="mm"
|
||||||
|
originx="-160.58582"
|
||||||
|
originy="-190.77645"
|
||||||
|
spacingx="0.26458333"
|
||||||
|
spacingy="0.26458334"
|
||||||
|
empcolor="#0099e5"
|
||||||
|
empopacity="0.30196078"
|
||||||
|
color="#0099e5"
|
||||||
|
opacity="0.14901961"
|
||||||
|
empspacing="5"
|
||||||
|
enabled="true"
|
||||||
|
visible="false" /><inkscape:page
|
||||||
|
x="2.454365e-15"
|
||||||
y="0"
|
y="0"
|
||||||
width="45.428978"
|
width="46.290325"
|
||||||
height="54.734951"
|
height="55.595428"
|
||||||
id="page2"
|
id="page2"
|
||||||
margin="0"
|
margin="0"
|
||||||
bleed="0" /></sodipodi:namedview><defs
|
bleed="0" /></sodipodi:namedview><defs
|
||||||
id="defs1"><inkscape:path-effect
|
id="defs1"><inkscape:path-effect
|
||||||
effect="mirror_symmetry"
|
effect="mirror_symmetry"
|
||||||
start_point="145.93901,200.00018"
|
start_point="86.207393,185.56305"
|
||||||
end_point="145.93901,257.23118"
|
end_point="86.338409,235.13009"
|
||||||
center_point="145.93901,228.61568"
|
center_point="86.272901,210.34657"
|
||||||
id="path-effect146"
|
id="path-effect149"
|
||||||
is_visible="true"
|
is_visible="true"
|
||||||
lpeversion="1.2"
|
lpeversion="1.2"
|
||||||
lpesatellites=""
|
lpesatellites=""
|
||||||
mode="free"
|
mode="free"
|
||||||
discard_orig_path="false"
|
discard_orig_path="false"
|
||||||
fuse_paths="false"
|
fuse_paths="true"
|
||||||
oposite_fuse="false"
|
oposite_fuse="false"
|
||||||
split_items="false"
|
split_items="false"
|
||||||
split_open="false"
|
split_open="false"
|
||||||
|
|
@ -59,14 +72,53 @@
|
||||||
inkscape:groupmode="layer"
|
inkscape:groupmode="layer"
|
||||||
id="layer4"
|
id="layer4"
|
||||||
inkscape:label="Layer 4"
|
inkscape:label="Layer 4"
|
||||||
transform="translate(-102.64477,-201.30981)"><path
|
transform="translate(-160.58582,-190.77645)"><path
|
||||||
d="m 145.93901,249.87364 c 0,0 -0.0303,-0.0367 -0.44909,0.0563 -0.20617,2.38398 1.11335,4.49732 -1.63951,4.79143 -1.66784,0.17819 -1.24406,-1.39832 -1.40619,-3.31064 -0.30255,-1.20853 -0.24531,-1.39312 -1.20877,-0.90551 -0.62396,0.31579 0.82573,3.70676 -1.30627,4.01151 -3.39198,0.48485 -0.69804,-6.45466 -5.14039,-9.8645 -1.63686,-2.03072 -4.33202,-1.51761 -6.56291,-1.96319 -2.53079,-1.12277 -4.05741,-3.94017 -4.44572,-6.62182 -0.7119,-4.67507 -0.64763,-9.45558 -0.31885,-14.16244 -1.53814,-15.82349 6.47812,-17.65127 15.17169,-20.63595 2.27655,-0.8108 4.68806,-1.22375 7.10241,-1.26865 0.0675,0 0.13527,2e-5 0.2036,5.1e-4 v 35.63039 c -1.07599,0.10793 -1.42136,1.92498 -2.91817,3.88142 -1.38429,2.50152 0.8238,3.48208 2.04897,2.41535 0.78196,-0.62623 0.8692,-0.65371 0.8692,-0.65371 z m -17.67696,-23.3593 c 0.4207,5.31835 3.21309,5.55909 6.71301,5.06471 4.00495,0.15448 8.18296,-1.56893 5.86969,-7.12815 -0.41537,-1.18035 -2.43304,-4.29435 -7.09899,-3.3542 -3.93834,0.60943 -5.53376,3.75721 -5.48371,5.41764 z m 17.67696,23.3593 c 0,0 0.0303,-0.0367 0.44909,0.0563 0.20617,2.38398 -1.11335,4.49732 1.63951,4.79143 1.66784,0.17819 1.24406,-1.39832 1.40619,-3.31064 0.30255,-1.20853 0.24531,-1.39312 1.20877,-0.90551 0.62396,0.31579 -0.82573,3.70676 1.30627,4.01151 3.39198,0.48485 0.69804,-6.45466 5.14039,-9.8645 1.63686,-2.03072 4.33202,-1.51761 6.56291,-1.96319 2.53079,-1.12277 4.05741,-3.94017 4.44572,-6.62182 0.7119,-4.67507 0.64763,-9.45558 0.31885,-14.16244 1.53814,-15.82349 -6.47812,-17.65127 -15.17169,-20.63595 -2.27655,-0.8108 -4.68806,-1.22375 -7.10241,-1.26865 -0.0675,0 -0.13527,2e-5 -0.2036,5.1e-4 v 35.63039 c 1.07599,0.10793 1.42136,1.92498 2.91817,3.88142 1.38429,2.50152 -0.8238,3.48208 -2.04897,2.41535 -0.78196,-0.62623 -0.8692,-0.65371 -0.8692,-0.65371 z m 17.67696,-23.3593 c -0.4207,5.31835 -3.21309,5.55909 -6.71301,5.06471 -4.00495,0.15448 -8.18296,-1.56893 -5.86969,-7.12815 0.41537,-1.18035 2.43304,-4.29435 7.09899,-3.3542 3.93834,0.60943 5.53376,3.75721 5.48371,5.41764 z"
|
|
||||||
style="fill:#a0a0a0;fill-opacity:1;stroke-width:0.161404"
|
|
||||||
id="path145"
|
id="path145"
|
||||||
inkscape:original-d="m 145.93901,249.87364 c 0,0 -0.0303,-0.0367 -0.44909,0.0563 -0.20617,2.38398 1.11335,4.49732 -1.63951,4.79143 -1.66784,0.17819 -1.24406,-1.39832 -1.40619,-3.31064 -0.30255,-1.20853 -0.24531,-1.39312 -1.20877,-0.90551 -0.62396,0.31579 0.82573,3.70676 -1.30627,4.01151 -3.39198,0.48485 -0.69804,-6.45466 -5.14039,-9.8645 -1.63686,-2.03072 -4.33202,-1.51761 -6.56291,-1.96319 -2.53079,-1.12277 -4.05741,-3.94017 -4.44572,-6.62182 -0.7119,-4.67507 -0.64763,-9.45558 -0.31885,-14.16244 -1.53814,-15.82349 6.47812,-17.65127 15.17169,-20.63595 2.27655,-0.8108 4.68806,-1.22375 7.10241,-1.26865 0.0675,0 0.13527,2e-5 0.2036,5.1e-4 v 35.63039 c -1.07599,0.10793 -1.42136,1.92498 -2.91817,3.88142 -1.38429,2.50152 0.8238,3.48208 2.04897,2.41535 0.78196,-0.62623 0.8692,-0.65371 0.8692,-0.65371 z m -17.67696,-23.3593 c 0.4207,5.31835 3.21309,5.55909 6.71301,5.06471 4.00495,0.15448 8.18296,-1.56893 5.86969,-7.12815 -0.41537,-1.18035 -2.43304,-4.29435 -7.09899,-3.3542 -3.93834,0.60943 -5.53376,3.75721 -5.48371,5.41764 z"
|
style="fill:#878787;fill-opacity:0.8;stroke:#4c4c4c;stroke-width:0.861;stroke-dasharray:none;stroke-opacity:1"
|
||||||
inkscape:path-effect="#path-effect146"
|
d="m 183.52738,191.20695 c -2.41435,0.0449 -4.82586,0.45785 -7.10241,1.26865 -8.69357,2.98468 -16.70982,4.81246 -15.17168,20.63595 -0.32878,4.70686 -0.39306,9.48738 0.31884,14.16245 0.38831,2.68165 1.91493,5.49905 4.44572,6.62182 2.23089,0.44558 4.92605,-0.0675 6.56291,1.96318 4.44235,3.40984 1.74827,10.34937 5.14025,9.86452 2.132,-0.30475 0.68242,-3.69585 1.30638,-4.01164 0.96346,-0.48761 0.90617,-0.30265 1.20872,0.90588 0.16213,1.91232 -0.26173,3.48859 1.40611,3.3104 2.75286,-0.29411 1.43353,-2.40746 1.6397,-4.79144 0.37937,-0.0842 0.43999,-0.0618 0.44803,-0.0568 h 5.2e-4 l 5.1e-4,5.2e-4 5.2e-4,-5.2e-4 h 5.2e-4 c 0.008,-0.005 0.0686,-0.0274 0.44803,0.0568 0.20617,2.38398 -1.11317,4.49733 1.63969,4.79144 1.66784,0.17819 1.24399,-1.39808 1.40612,-3.3104 0.30255,-1.20853 0.24525,-1.39349 1.20871,-0.90588 0.62396,0.31579 -0.82562,3.70689 1.30638,4.01164 3.39198,0.48485 0.69791,-6.45468 5.14026,-9.86452 1.63686,-2.03072 4.33201,-1.5176 6.5629,-1.96318 2.53079,-1.12277 4.05742,-3.94017 4.44573,-6.62182 0.7119,-4.67507 0.64762,-9.45559 0.31884,-14.16245 1.53814,-15.82349 -6.47811,-17.65127 -15.17168,-20.63595 -2.27655,-0.8108 -4.68806,-1.22375 -7.10241,-1.26865 -0.0675,0 -0.13528,3e-5 -0.20361,5.2e-4 -0.0683,-4.9e-4 -0.1361,-5.2e-4 -0.2036,-5.2e-4 z m -10.36216,20.92224 c 3.5177,-0.0177 5.10805,2.49566 5.4715,3.52846 2.31327,5.55922 -1.86498,7.28273 -5.86993,7.12825 -3.49992,0.49438 -6.29206,0.25354 -6.71276,-5.06481 -0.05,-1.66043 1.54504,-4.80832 5.48338,-5.41775 0.58325,-0.11752 1.12528,-0.17163 1.62781,-0.17415 z m 21.13153,0 c 0.50252,0.003 1.04404,0.0566 1.62729,0.17415 3.93834,0.60943 5.53395,3.75732 5.4839,5.41775 -0.4207,5.31835 -3.21336,5.55919 -6.71328,5.06481 -4.00495,0.15448 -8.18268,-1.56903 -5.86941,-7.12825 0.36344,-1.0328 1.9538,-3.54611 5.4715,-3.52846 z m -10.56577,14.70866 c 1.07599,0.10793 1.42136,1.92498 2.91817,3.88142 1.38429,2.50152 -0.8238,3.48208 -2.04897,2.41535 -0.78178,-0.62609 -0.86916,-0.65369 -0.8692,-0.65371 -4e-5,2e-5 -0.0874,0.0276 -0.86919,0.65371 -1.22517,1.06673 -3.43326,0.0862 -2.04897,-2.41535 1.49681,-1.95644 1.84217,-3.77349 2.91816,-3.88142 z"
|
||||||
transform="translate(-20.579754,1.3096207)"
|
inkscape:export-filename="../../src/werewolves/src/werewolves/werewolves/img/skull.svg"
|
||||||
sodipodi:nodetypes="ccscssccccccccccccccccc"
|
|
||||||
inkscape:export-filename="../../src/werewolves/werewolves/img/skull;.svg"
|
|
||||||
inkscape:export-xdpi="900.08"
|
inkscape:export-xdpi="900.08"
|
||||||
inkscape:export-ydpi="900.08" /></g></svg>
|
inkscape:export-ydpi="900.08" /><g
|
||||||
|
id="g151"
|
||||||
|
inkscape:export-filename="../../src/werewolves/werewolves/dist/img/heart.svg"
|
||||||
|
inkscape:export-xdpi="900.08"
|
||||||
|
inkscape:export-ydpi="900.08"
|
||||||
|
transform="translate(50.270833,-38.1)"><path
|
||||||
|
style="fill:#ff2424;fill-opacity:1;stroke:#ff2424;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 86.254166,235.08229 c 0,0 -24.302335,-18.46127 -24.606251,-31.8823 -0.126849,-5.60168 4.153389,-12.70855 9.657292,-13.75832 5.852331,-1.11623 14.123929,1.87077 14.932422,9.82265 z m 0.168232,-4.4e-4 c 0,0 24.204402,-18.58949 24.437362,-32.01194 0.0972,-5.60227 -4.22051,-12.68641 -9.72989,-13.70707 -5.858145,-1.08528 -14.113837,1.94541 -14.880282,9.90145 z"
|
||||||
|
id="path148"
|
||||||
|
sodipodi:nodetypes="caacc"
|
||||||
|
inkscape:original-d="m 86.254166,235.08229 c 0,0 -24.302335,-18.46127 -24.606251,-31.8823 -0.126849,-5.60168 4.153389,-12.70855 9.657292,-13.75832 5.852331,-1.11623 14.123929,1.87077 14.932422,9.82265 z"
|
||||||
|
inkscape:path-effect="#path-effect149"
|
||||||
|
inkscape:export-filename="../../src/werewolves/werewolves/img/heart.svg"
|
||||||
|
inkscape:export-xdpi="900.08"
|
||||||
|
inkscape:export-ydpi="900.08" /><path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="fill:#fff001;fill-opacity:1;stroke:#ff2424;stroke-width:0.15;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path150"
|
||||||
|
inkscape:flatsided="false"
|
||||||
|
sodipodi:sides="4"
|
||||||
|
sodipodi:cx="79.886864"
|
||||||
|
sodipodi:cy="208.97804"
|
||||||
|
sodipodi:r1="5.2418227"
|
||||||
|
sodipodi:r2="2.8830025"
|
||||||
|
sodipodi:arg1="0.607802"
|
||||||
|
sodipodi:arg2="1.3932002"
|
||||||
|
inkscape:rounded="0.5"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 84.189903,211.97146 c -1.084141,1.55845 -1.92512,-0.49115 -3.793716,-0.15576 -1.868596,0.33539 -1.944289,2.54952 -3.502742,1.46538 -1.558453,-1.08414 0.491151,-1.92512 0.155762,-3.79371 -0.335389,-1.8686 -2.549524,-1.94429 -1.465383,-3.50275 1.084141,-1.55845 1.925121,0.49116 3.793717,0.15577 1.868596,-0.33539 1.944289,-2.54953 3.502742,-1.46539 1.558452,1.08414 -0.491152,1.92512 -0.155763,3.79372 0.335389,1.8686 2.549524,1.94429 1.465383,3.50274 z"
|
||||||
|
transform="rotate(28.628814,62.558026,193.09515)" /><path
|
||||||
|
sodipodi:type="star"
|
||||||
|
style="fill:#fff001;fill-opacity:1;stroke:#ff2424;stroke-width:0.15;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
id="path151"
|
||||||
|
inkscape:flatsided="false"
|
||||||
|
sodipodi:sides="4"
|
||||||
|
sodipodi:cx="68.848625"
|
||||||
|
sodipodi:cy="200.93324"
|
||||||
|
sodipodi:r1="6.7481718"
|
||||||
|
sodipodi:r2="3.3373971"
|
||||||
|
sodipodi:arg1="0.80500349"
|
||||||
|
sodipodi:arg2="1.5925996"
|
||||||
|
inkscape:rounded="0.5"
|
||||||
|
inkscape:randomized="0"
|
||||||
|
d="m 73.525842,205.79755 c -1.802133,1.72521 -2.255654,-1.4788 -4.749977,-1.5277 -2.4873,-0.0488 -3.071191,3.13767 -4.791545,1.34061 -1.725212,-1.80213 1.478793,-2.25565 1.527701,-4.74998 0.04877,-2.4873 -3.137671,-3.07119 -1.340613,-4.79154 1.802133,-1.72521 2.255655,1.47879 4.749978,1.5277 2.487299,0.0488 3.07119,-3.13767 4.791545,-1.34061 1.725212,1.80213 -1.478794,2.25565 -1.527702,4.74997 -0.04877,2.4873 3.137671,3.07119 1.340613,4.79155 z" /></g></g></svg>
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 7.8 KiB |
|
|
@ -0,0 +1,80 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="22.314859mm"
|
||||||
|
height="22.297653mm"
|
||||||
|
viewBox="0 0 22.314859 22.297653"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
||||||
|
sodipodi:docname="icons.svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="true"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="2.8284272"
|
||||||
|
inkscape:cx="329.68853"
|
||||||
|
inkscape:cy="1037.856"
|
||||||
|
inkscape:window-width="1918"
|
||||||
|
inkscape:window-height="1042"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="17"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="layer4"><inkscape:grid
|
||||||
|
id="grid1"
|
||||||
|
units="mm"
|
||||||
|
originx="-56.082429"
|
||||||
|
originy="-239.74316"
|
||||||
|
spacingx="0.26458333"
|
||||||
|
spacingy="0.26458334"
|
||||||
|
empcolor="#0099e5"
|
||||||
|
empopacity="0.30196078"
|
||||||
|
color="#0099e5"
|
||||||
|
opacity="0.14901961"
|
||||||
|
empspacing="5"
|
||||||
|
enabled="true"
|
||||||
|
visible="false" /><inkscape:page
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
width="22.314859"
|
||||||
|
height="22.297653"
|
||||||
|
id="page2"
|
||||||
|
margin="0"
|
||||||
|
bleed="0" /></sodipodi:namedview><defs
|
||||||
|
id="defs1" /><g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer4"
|
||||||
|
inkscape:label="Layer 4"
|
||||||
|
transform="translate(-56.082426,-239.74318)"><path
|
||||||
|
id="path4-9-8-6"
|
||||||
|
style="fill:#ffa606;fill-opacity:1;stroke-width:0.679;stroke-dasharray:none"
|
||||||
|
inkscape:transform-center-x="-0.11920648"
|
||||||
|
inkscape:transform-center-y="-9.0503731"
|
||||||
|
d="m 75.968916,255.39833 -14.375127,-14.37513 -5.51136,-1.28003 1.279797,5.51159 14.375127,14.37513 z"
|
||||||
|
sodipodi:nodetypes="cccccc" /><path
|
||||||
|
id="path4-1-2-1-9"
|
||||||
|
style="fill:#000000;fill-opacity:0.504713;stroke-width:0.339521"
|
||||||
|
inkscape:transform-center-x="-0.11920648"
|
||||||
|
inkscape:transform-center-y="-9.0503731"
|
||||||
|
d="m 72.46276,258.16133 2.037184,-2.03718 -16.922161,-14.88563 z" /><path
|
||||||
|
id="path159-3"
|
||||||
|
style="fill:#ffffff;fill-opacity:0.696867;stroke-width:0.339521"
|
||||||
|
inkscape:transform-center-x="-0.11920648"
|
||||||
|
inkscape:transform-center-y="-9.0503731"
|
||||||
|
d="m 78.294558,260.62268 -3.768526,-3.76853 2.07583,-2.07583 c 0.126016,-0.12601 -0.252031,-0.50406 -0.378048,-0.37805 -0.0188,0.0188 -5.484278,5.48428 -5.484278,5.48428 -0.188161,0.18816 0.177445,0.57865 0.378048,0.37805 l 2.075593,-2.07559 3.768526,3.76852 c 0.423571,0.42357 1.82288,-0.84283 1.332855,-1.33285 z"
|
||||||
|
sodipodi:nodetypes="zcsssscsz"
|
||||||
|
inkscape:export-filename="sword.svg"
|
||||||
|
inkscape:export-xdpi="900.08"
|
||||||
|
inkscape:export-ydpi="900.08" /></g></svg>
|
||||||
|
After Width: | Height: | Size: 3.1 KiB |
|
|
@ -25,6 +25,13 @@ $defensive_border_faint: color.change($defensive_border, $alpha: 0.3);
|
||||||
$intel_border_faint: color.change($intel_border, $alpha: 0.3);
|
$intel_border_faint: color.change($intel_border, $alpha: 0.3);
|
||||||
$starts_as_villager_border_faint: color.change($starts_as_villager_border, $alpha: 0.3);
|
$starts_as_villager_border_faint: color.change($starts_as_villager_border, $alpha: 0.3);
|
||||||
|
|
||||||
|
$wolves_color_faint: color.change($wolves_color, $alpha: 0.1);
|
||||||
|
$village_color_faint: color.change($village_color, $alpha: 0.1);
|
||||||
|
$offensive_color_faint: color.change($offensive_color, $alpha: 0.1);
|
||||||
|
$defensive_color_faint: color.change($defensive_color, $alpha: 0.1);
|
||||||
|
$intel_color_faint: color.change($intel_color, $alpha: 0.1);
|
||||||
|
$starts_as_villager_color_faint: color.change($starts_as_villager_color, $alpha: 0.1);
|
||||||
|
|
||||||
|
|
||||||
@mixin flexbox() {
|
@mixin flexbox() {
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
|
|
@ -353,9 +360,26 @@ button {
|
||||||
.character {
|
.character {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border: 3px solid rgba(0, 0, 0, 0.4);
|
border: 3px solid rgba(0, 0, 0, 0.4);
|
||||||
|
// min-width: 20%;
|
||||||
|
flex-shrink: 1;
|
||||||
|
|
||||||
.role {
|
.role {
|
||||||
font-size: 2rem;
|
font-size: 1.5rem;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
&.wolves {
|
||||||
|
padding-top: 20px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
|
||||||
|
&>.role {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 15vw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -805,16 +829,23 @@ error {
|
||||||
}
|
}
|
||||||
|
|
||||||
.binary {
|
.binary {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
.button-container {
|
.button-container {
|
||||||
background-color: $village_color;
|
|
||||||
border: 3px solid darken($village_color, 20%);
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1 1 0;
|
flex: 1 1 0;
|
||||||
|
gap: 20px;
|
||||||
|
margin-top: 20px;
|
||||||
|
justify-content: space-around;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
button {
|
button {
|
||||||
|
background-color: $wolves_color_faint;
|
||||||
|
border: 3px solid $wolves_border_faint;
|
||||||
font-size: 3rem;
|
font-size: 3rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
|
|
@ -822,8 +853,14 @@ error {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $wolves_border_faint;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
|
|
@ -911,6 +948,7 @@ input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: white;
|
color: white;
|
||||||
|
height: 90vh;
|
||||||
$marked_bg: color.change($wolves_color, $alpha: 0.3);
|
$marked_bg: color.change($wolves_color, $alpha: 0.3);
|
||||||
$marked_border: color.change($wolves_color, $alpha: 1.0);
|
$marked_border: color.change($wolves_color, $alpha: 1.0);
|
||||||
$village_bg: color.change($village_color, $alpha: 0.3);
|
$village_bg: color.change($village_color, $alpha: 0.3);
|
||||||
|
|
@ -921,6 +959,9 @@ input {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: space-evenly;
|
justify-content: space-evenly;
|
||||||
|
align-items: center;
|
||||||
|
flex-grow: 1;
|
||||||
|
align-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.character {
|
.character {
|
||||||
|
|
@ -1037,6 +1078,11 @@ input {
|
||||||
color: white;
|
color: white;
|
||||||
background-color: $village_border;
|
background-color: $village_border;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.faint {
|
||||||
|
border: 1px solid $village_border_faint;
|
||||||
|
background-color: $village_color_faint;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.wolves {
|
.wolves {
|
||||||
|
|
@ -1050,6 +1096,7 @@ input {
|
||||||
|
|
||||||
&.faint {
|
&.faint {
|
||||||
border: 1px solid $wolves_border_faint;
|
border: 1px solid $wolves_border_faint;
|
||||||
|
background-color: $wolves_color_faint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1064,6 +1111,7 @@ input {
|
||||||
|
|
||||||
&.faint {
|
&.faint {
|
||||||
border: 1px solid $intel_border_faint;
|
border: 1px solid $intel_border_faint;
|
||||||
|
background-color: $intel_color_faint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1078,6 +1126,7 @@ input {
|
||||||
|
|
||||||
&.faint {
|
&.faint {
|
||||||
border: 1px solid $defensive_border_faint;
|
border: 1px solid $defensive_border_faint;
|
||||||
|
background-color: $defensive_color_faint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1092,6 +1141,7 @@ input {
|
||||||
|
|
||||||
&.faint {
|
&.faint {
|
||||||
border: 1px solid $offensive_border_faint;
|
border: 1px solid $offensive_border_faint;
|
||||||
|
background-color: $offensive_color_faint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1106,6 +1156,7 @@ input {
|
||||||
|
|
||||||
&.faint {
|
&.faint {
|
||||||
border: 1px solid $starts_as_villager_border_faint;
|
border: 1px solid $starts_as_villager_border_faint;
|
||||||
|
background-color: $starts_as_villager_color_faint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1330,6 +1381,8 @@ input {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
|
|
@ -1339,9 +1392,6 @@ input {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
// width: ;
|
|
||||||
|
|
||||||
& .next {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.signin {
|
.signin {
|
||||||
|
|
@ -1374,9 +1424,17 @@ input {
|
||||||
|
|
||||||
|
|
||||||
.story {
|
.story {
|
||||||
user-select: text;
|
.cast {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
.time-period {
|
.time-period {
|
||||||
|
user-select: text;
|
||||||
|
|
||||||
.day {
|
.day {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
@ -1462,30 +1520,6 @@ input {
|
||||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.wolves {
|
|
||||||
background-color: color.change($wolves_color, $alpha: 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.intel {
|
|
||||||
background-color: color.change($intel_color, $alpha: 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.defensive {
|
|
||||||
background-color: color.change($defensive_color, $alpha: 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.offensive {
|
|
||||||
background-color: color.change($offensive_color, $alpha: 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.village {
|
|
||||||
background-color: color.change($village_color, $alpha: 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.starts-as-villager {
|
|
||||||
background-color: color.change($starts_as_villager_color, $alpha: 0.1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.alignment-eq {
|
.alignment-eq {
|
||||||
|
|
@ -1513,6 +1547,10 @@ input {
|
||||||
justify-items: baseline;
|
justify-items: baseline;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
|
|
||||||
|
.number {
|
||||||
|
color: rgba(255, 255, 0, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
.role {
|
.role {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
@ -1595,3 +1633,58 @@ input {
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.role-page {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
// align-self: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.information {
|
||||||
|
font-size: 1.2em;
|
||||||
|
padding-left: 5%;
|
||||||
|
padding-right: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.yellow {
|
||||||
|
color: yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icons {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-info {
|
||||||
|
flex-shrink: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-player-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
&.masons {
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ pub fn test_story() -> GameStory {
|
||||||
empath,
|
empath,
|
||||||
scapegoat,
|
scapegoat,
|
||||||
hunter,
|
hunter,
|
||||||
|
diseased,
|
||||||
) = (
|
) = (
|
||||||
(SetupRole::Werewolf, players_iter.next().unwrap()),
|
(SetupRole::Werewolf, players_iter.next().unwrap()),
|
||||||
(SetupRole::DireWolf, players_iter.next().unwrap()),
|
(SetupRole::DireWolf, players_iter.next().unwrap()),
|
||||||
|
|
@ -83,6 +84,7 @@ pub fn test_story() -> GameStory {
|
||||||
players_iter.next().unwrap(),
|
players_iter.next().unwrap(),
|
||||||
),
|
),
|
||||||
(SetupRole::Hunter, players_iter.next().unwrap()),
|
(SetupRole::Hunter, players_iter.next().unwrap()),
|
||||||
|
(SetupRole::Diseased, players_iter.next().unwrap()),
|
||||||
);
|
);
|
||||||
let mut settings = GameSettings::empty();
|
let mut settings = GameSettings::empty();
|
||||||
settings.add_and_assign(werewolf.0, werewolf.1);
|
settings.add_and_assign(werewolf.0, werewolf.1);
|
||||||
|
|
@ -103,6 +105,7 @@ pub fn test_story() -> GameStory {
|
||||||
settings.add_and_assign(empath.0, empath.1);
|
settings.add_and_assign(empath.0, empath.1);
|
||||||
settings.add_and_assign(scapegoat.0, scapegoat.1);
|
settings.add_and_assign(scapegoat.0, scapegoat.1);
|
||||||
settings.add_and_assign(hunter.0, hunter.1);
|
settings.add_and_assign(hunter.0, hunter.1);
|
||||||
|
settings.add_and_assign(diseased.0, diseased.1);
|
||||||
settings.fill_remaining_slots_with_villagers(players.len());
|
settings.fill_remaining_slots_with_villagers(players.len());
|
||||||
|
|
||||||
let (
|
let (
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ pub fn BinaryChoice(
|
||||||
html! {
|
html! {
|
||||||
<div class="column-list binary">
|
<div class="column-list binary">
|
||||||
{children.clone()}
|
{children.clone()}
|
||||||
<div class="row-list gap">
|
<div class="button-container">
|
||||||
<Button on_click={yes}>{"Yes"}</Button>
|
<Button on_click={yes}>{"Yes"}</Button>
|
||||||
<Button on_click={no}>{"No"}</Button>
|
<Button on_click={no}>{"No"}</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
use werewolves_proto::{
|
use werewolves_proto::{character::CharacterId, message::CharacterIdentity};
|
||||||
character::CharacterId,
|
|
||||||
message::{CharacterIdentity, PublicIdentity},
|
|
||||||
};
|
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Button, Identity};
|
use crate::components::{Button, CharacterTargetCard};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Properties)]
|
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||||
pub struct TargetPickerProps {
|
pub struct TargetPickerProps {
|
||||||
|
|
@ -72,10 +69,9 @@ pub fn TargetCard(
|
||||||
.map(|cb| Callback::from(move |_| cb.emit(click_target)))
|
.map(|cb| Callback::from(move |_| cb.emit(click_target)))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let marked = marked.then_some("marked");
|
let marked = marked.then_some("marked");
|
||||||
let ident: PublicIdentity = target.into();
|
|
||||||
html! {
|
html! {
|
||||||
<Button on_click={on_click} classes={classes!(marked, "character")}>
|
<Button on_click={on_click} classes={classes!(marked, "character")}>
|
||||||
<Identity ident={ident}/>
|
<CharacterTargetCard ident={target.clone()}/>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,12 @@ use werewolves_proto::{
|
||||||
};
|
};
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{
|
use crate::{
|
||||||
Button, CoverOfDarkness, Identity,
|
components::{
|
||||||
action::{BinaryChoice, TargetPicker, WolvesIntro},
|
Button, CoverOfDarkness, Identity,
|
||||||
|
action::{BinaryChoice, TargetPicker, WolvesIntro},
|
||||||
|
},
|
||||||
|
pages::MasonsWake,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Properties)]
|
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||||
|
|
@ -109,58 +112,27 @@ pub fn Prompt(props: &ActionPromptProps) -> Html {
|
||||||
/>
|
/>
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
ActionPrompt::ElderReveal { character_id } => {
|
ActionPrompt::MasonsWake { .. } => {
|
||||||
return html! {
|
props
|
||||||
<div class="role-change">
|
.on_complete
|
||||||
{identity_html(props, Some(character_id))}
|
.emit(HostMessage::InGame(HostGameMessage::Night(
|
||||||
<h1>{"you are the elder"}</h1>
|
HostNightMessage::ActionResponse(ActionResponse::Continue),
|
||||||
{cont}
|
)));
|
||||||
</div>
|
props
|
||||||
};
|
.on_complete
|
||||||
|
.emit(HostMessage::InGame(HostGameMessage::Night(
|
||||||
|
HostNightMessage::Next,
|
||||||
|
)));
|
||||||
|
props.on_complete.emit(HostMessage::GetState);
|
||||||
|
return html! {};
|
||||||
}
|
}
|
||||||
ActionPrompt::Insomniac { character_id } => {
|
ActionPrompt::RoleChange { .. }
|
||||||
return html! {
|
| ActionPrompt::ElderReveal { .. }
|
||||||
<div class="insomniac prompt">
|
| ActionPrompt::Insomniac { .. } => {
|
||||||
{identity_html(props, Some(character_id))}
|
if let Some(cb) = continue_callback {
|
||||||
<h2>{"you are the insomniac"}</h2>
|
cb.emit(());
|
||||||
{cont}
|
}
|
||||||
</div>
|
return html! {};
|
||||||
};
|
|
||||||
}
|
|
||||||
ActionPrompt::RoleChange {
|
|
||||||
character_id,
|
|
||||||
new_role,
|
|
||||||
} => {
|
|
||||||
return html! {
|
|
||||||
<div class="role-change">
|
|
||||||
{identity_html(props, Some(character_id))}
|
|
||||||
<h2>{"your role has changed"}</h2>
|
|
||||||
<h1>{new_role.to_string()}</h1>
|
|
||||||
{cont}
|
|
||||||
</div>
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionPrompt::MasonsWake { leader, masons } => {
|
|
||||||
let masons = masons
|
|
||||||
.into_iter()
|
|
||||||
.map(|c| {
|
|
||||||
let leader = (c.character_id == *leader).then_some("leader");
|
|
||||||
let ident: PublicIdentity = c.into();
|
|
||||||
html! {
|
|
||||||
<Identity class={classes!(leader)} ident={ident}/>
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Html>();
|
|
||||||
return html! {
|
|
||||||
<div class="masons">
|
|
||||||
<h2>{"these are the masons"}</h2>
|
|
||||||
<div class="mason-list">
|
|
||||||
{masons}
|
|
||||||
</div>
|
|
||||||
{cont}
|
|
||||||
</div>
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionPrompt::Guardian {
|
ActionPrompt::Guardian {
|
||||||
|
|
@ -408,10 +380,22 @@ pub fn Prompt(props: &ActionPromptProps) -> Html {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return html! {
|
return html! {
|
||||||
<div>
|
<div class="role-page">
|
||||||
{identity_html(props, Some(character_id))}
|
{identity_html(props, Some(character_id))}
|
||||||
|
<h1 class="wolves">{"SHAPESHIFTER"}</h1>
|
||||||
|
<div class="information wolves faint">
|
||||||
|
<h3>
|
||||||
|
{"WOULD YOU LIKE TO USE YOUR "}
|
||||||
|
<span class="yellow">{"ONCE PER GAME"}</span>
|
||||||
|
{" SHAPESHIFT ABILITY?"}
|
||||||
|
</h3>
|
||||||
|
<h4>
|
||||||
|
<span class="yellow">{"YOU WILL DIE"}</span>{", AND THE "}
|
||||||
|
{"TARGET OF THE WOLFPACK KILL"}
|
||||||
|
{" SHALL INSTEAD BECOME A WOLF"}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
<BinaryChoice on_chosen={on_select}>
|
<BinaryChoice on_chosen={on_select}>
|
||||||
<h2>{"shapeshift?"}</h2>
|
|
||||||
</BinaryChoice>
|
</BinaryChoice>
|
||||||
</div>
|
</div>
|
||||||
};
|
};
|
||||||
|
|
@ -434,14 +418,16 @@ pub fn Prompt(props: &ActionPromptProps) -> Html {
|
||||||
Some(character_id),
|
Some(character_id),
|
||||||
living_players,
|
living_players,
|
||||||
marked.iter().cloned().collect(),
|
marked.iter().cloned().collect(),
|
||||||
html! {{"dire wolf"}},
|
html! {{"direwolf"}},
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
let role_info = props.big_screen.not().then_some(html! {
|
||||||
|
<h2>{role_info}</h2>
|
||||||
|
});
|
||||||
html! {
|
html! {
|
||||||
<div class="prompt">
|
<div class="prompt">
|
||||||
{identity_html(props, character_id)}
|
{identity_html(props, character_id)}
|
||||||
<h2>{role_info}</h2>
|
{role_info}
|
||||||
<TargetPicker
|
<TargetPicker
|
||||||
targets={targets.clone()}
|
targets={targets.clone()}
|
||||||
marked={marked}
|
marked={marked}
|
||||||
|
|
@ -450,343 +436,4 @@ pub fn Prompt(props: &ActionPromptProps) -> Html {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
// match &props.prompt {
|
|
||||||
// ActionPrompt::CoverOfDarkness => {
|
|
||||||
// let on_complete = props.on_complete.clone();
|
|
||||||
// let next = props.big_screen.not().then(|| {
|
|
||||||
// Callback::from(move |_| {
|
|
||||||
// on_complete.emit(HostMessage::InGame(HostGameMessage::Night(
|
|
||||||
// HostNightMessage::ActionResponse(ActionResponse::ClearCoverOfDarkness),
|
|
||||||
// )))
|
|
||||||
// })
|
|
||||||
// });
|
|
||||||
// return html! {
|
|
||||||
// <CoverOfDarkness next={next} />
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// ActionPrompt::WolvesIntro { wolves } => {
|
|
||||||
// let on_complete = props.on_complete.clone();
|
|
||||||
// let on_complete = Callback::from(move |_| {
|
|
||||||
// on_complete.emit(HostMessage::InGame(HostGameMessage::Night(
|
|
||||||
// HostNightMessage::ActionResponse(
|
|
||||||
// werewolves_proto::message::night::ActionResponse::WolvesIntroAck,
|
|
||||||
// ),
|
|
||||||
// )))
|
|
||||||
// });
|
|
||||||
// html! {
|
|
||||||
// <WolvesIntro
|
|
||||||
// big_screen={props.big_screen}
|
|
||||||
// on_complete={on_complete}
|
|
||||||
// wolves={wolves.clone()}
|
|
||||||
// />
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ActionPrompt::Seer {
|
|
||||||
// character_id,
|
|
||||||
// living_players,
|
|
||||||
// } => {
|
|
||||||
// let on_complete = props.on_complete.clone();
|
|
||||||
// let on_select = props.big_screen.not().then(|| {
|
|
||||||
// Callback::from(move |target: CharacterId| {
|
|
||||||
// on_complete.emit(HostMessage::InGame(HostGameMessage::Night(
|
|
||||||
// HostNightMessage::ActionResponse(ActionResponse::Seer(target)),
|
|
||||||
// )));
|
|
||||||
// })
|
|
||||||
// });
|
|
||||||
// html! {
|
|
||||||
// <div>
|
|
||||||
// {identity_html(props, Some(&character_id))}
|
|
||||||
// <SingleTarget
|
|
||||||
// targets={living_players.clone()}
|
|
||||||
// target_selection={on_select}
|
|
||||||
// headline={"check alignment"}
|
|
||||||
// />
|
|
||||||
// </div>
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ActionPrompt::RoleChange {
|
|
||||||
// character_id,
|
|
||||||
// new_role,
|
|
||||||
// } => {
|
|
||||||
// let on_complete = props.on_complete.clone();
|
|
||||||
// let on_click = Callback::from(move |_| {
|
|
||||||
// on_complete.emit(HostMessage::InGame(HostGameMessage::Night(
|
|
||||||
// HostNightMessage::ActionResponse(ActionResponse::RoleChangeAck),
|
|
||||||
// )))
|
|
||||||
// });
|
|
||||||
// let cont = props.big_screen.not().then(|| {
|
|
||||||
// html! {
|
|
||||||
// <Button on_click={on_click}>{"continue"}</Button>
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// html! {
|
|
||||||
// <div>
|
|
||||||
// {identity_html(props, Some(&character_id))}
|
|
||||||
// <h2>{"your role has changed"}</h2>
|
|
||||||
// <p>{new_role.to_string()}</p>
|
|
||||||
// {cont}
|
|
||||||
// </div>
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ActionPrompt::Protector {
|
|
||||||
// character_id,
|
|
||||||
// targets,
|
|
||||||
// } => {
|
|
||||||
// let on_complete = props.on_complete.clone();
|
|
||||||
// let on_select = props.big_screen.not().then(|| {
|
|
||||||
// Callback::from(move |target: CharacterId| {
|
|
||||||
// on_complete.emit(HostMessage::InGame(HostGameMessage::Night(
|
|
||||||
// HostNightMessage::ActionResponse(ActionResponse::Protector(target)),
|
|
||||||
// )));
|
|
||||||
// })
|
|
||||||
// });
|
|
||||||
// html! {
|
|
||||||
// <div>
|
|
||||||
// {identity_html(props, Some(&character_id))}
|
|
||||||
// <SingleTarget
|
|
||||||
// targets={targets.clone()}
|
|
||||||
// target_selection={on_select}
|
|
||||||
// headline={"protector"}
|
|
||||||
// />
|
|
||||||
// </div>
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ActionPrompt::Arcanist {
|
|
||||||
// character_id,
|
|
||||||
// living_players,
|
|
||||||
// } => {
|
|
||||||
// let on_complete = props.on_complete.clone();
|
|
||||||
// let on_select = props.big_screen.not().then(|| {
|
|
||||||
// Callback::from(move |(t1, t2): (CharacterId, CharacterId)| {
|
|
||||||
// on_complete.emit(HostMessage::InGame(HostGameMessage::Night(
|
|
||||||
// HostNightMessage::ActionResponse(ActionResponse::Arcanist(t1, t2)),
|
|
||||||
// )));
|
|
||||||
// })
|
|
||||||
// });
|
|
||||||
// html! {
|
|
||||||
// <div>
|
|
||||||
// {identity_html(props, Some(&character_id))}
|
|
||||||
// <TwoTarget
|
|
||||||
// targets={living_players.clone()}
|
|
||||||
// target_selection={on_select}
|
|
||||||
// headline={"arcanist"}
|
|
||||||
// />
|
|
||||||
// </div>
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ActionPrompt::Gravedigger {
|
|
||||||
// character_id,
|
|
||||||
// dead_players,
|
|
||||||
// } => {
|
|
||||||
// let on_complete = props.on_complete.clone();
|
|
||||||
// let on_select = props.big_screen.not().then(|| {
|
|
||||||
// Callback::from(move |target: CharacterId| {
|
|
||||||
// on_complete.emit(HostMessage::InGame(HostGameMessage::Night(
|
|
||||||
// HostNightMessage::ActionResponse(ActionResponse::Gravedigger(target)),
|
|
||||||
// )));
|
|
||||||
// })
|
|
||||||
// });
|
|
||||||
// html! {
|
|
||||||
// <div>
|
|
||||||
// {identity_html(props, Some(&character_id))}
|
|
||||||
// <SingleTarget
|
|
||||||
// targets={dead_players.clone()}
|
|
||||||
// target_selection={on_select}
|
|
||||||
// headline={"gravedigger"}
|
|
||||||
// />
|
|
||||||
// </div>
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ActionPrompt::Hunter {
|
|
||||||
// character_id,
|
|
||||||
// current_target,
|
|
||||||
// living_players,
|
|
||||||
// } => {
|
|
||||||
// let on_complete = props.on_complete.clone();
|
|
||||||
// let on_select = props.big_screen.not().then(|| {
|
|
||||||
// Callback::from(move |target: CharacterId| {
|
|
||||||
// on_complete.emit(HostMessage::InGame(HostGameMessage::Night(
|
|
||||||
// HostNightMessage::ActionResponse(ActionResponse::Hunter(target)),
|
|
||||||
// )));
|
|
||||||
// })
|
|
||||||
// });
|
|
||||||
// html! {
|
|
||||||
// <div>
|
|
||||||
// {identity_html(props, Some(&character_id))}
|
|
||||||
// <SingleTarget
|
|
||||||
// targets={living_players.clone()}
|
|
||||||
// target_selection={on_select}
|
|
||||||
// headline={"hunter"}
|
|
||||||
// >
|
|
||||||
// <h3>
|
|
||||||
// <b>{"current target: "}</b>{current_target.clone().map(|t| html!{
|
|
||||||
// <Identity ident={Into::<PublicIdentity>::into(t)} />
|
|
||||||
// }).unwrap_or_else(|| html!{<i>{"none"}</i>})}
|
|
||||||
// </h3>
|
|
||||||
// </SingleTarget>
|
|
||||||
// </div>
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ActionPrompt::Militia {
|
|
||||||
// character_id,
|
|
||||||
// living_players,
|
|
||||||
// } => {
|
|
||||||
// let on_complete = props.on_complete.clone();
|
|
||||||
// let on_select = props.big_screen.not().then(|| {
|
|
||||||
// Callback::from(move |target: Option<CharacterId>| {
|
|
||||||
// on_complete.emit(HostMessage::InGame(HostGameMessage::Night(
|
|
||||||
// HostNightMessage::ActionResponse(ActionResponse::Militia(target)),
|
|
||||||
// )));
|
|
||||||
// })
|
|
||||||
// });
|
|
||||||
// html! {
|
|
||||||
// <div>
|
|
||||||
// {identity_html(props, Some(&character_id))}
|
|
||||||
// <OptionalSingleTarget
|
|
||||||
// targets={living_players.clone()}
|
|
||||||
// target_selection={on_select}
|
|
||||||
// headline={"pew pew?"}
|
|
||||||
// />
|
|
||||||
// </div>
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ActionPrompt::MapleWolf {
|
|
||||||
// character_id,
|
|
||||||
// kill_or_die,
|
|
||||||
// living_players,
|
|
||||||
// marked,
|
|
||||||
// } => {
|
|
||||||
// let kill_or_die = kill_or_die.then(|| {
|
|
||||||
// html! {
|
|
||||||
// <em>{"if you fail to eat tonight, you will starve"}</em>
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// html! {
|
|
||||||
// <div>
|
|
||||||
// {identity_html(props, Some(&character_id))}
|
|
||||||
// <OptionalSingleTarget
|
|
||||||
// targets={living_players.clone()}
|
|
||||||
// target_selection={on_select}
|
|
||||||
// headline={"nom nom?"}
|
|
||||||
// >
|
|
||||||
// {kill_or_die}
|
|
||||||
// </OptionalSingleTarget>
|
|
||||||
// </div>
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ActionPrompt::Guardian {
|
|
||||||
// character_id,
|
|
||||||
// previous,
|
|
||||||
// living_players,
|
|
||||||
// marked,
|
|
||||||
// } => {
|
|
||||||
// let last_protect = previous.as_ref().map(|prev| match prev {
|
|
||||||
// PreviousGuardianAction::Protect(target) => {
|
|
||||||
// html! {
|
|
||||||
// <>
|
|
||||||
// <b>{"last night you protected: "}</b>
|
|
||||||
// <Identity ident={Into::<PublicIdentity>::into(target)}/>
|
|
||||||
// </>
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// PreviousGuardianAction::Guard(target) => html! {
|
|
||||||
// <>
|
|
||||||
// <b>{"last night you guarded: "}</b>
|
|
||||||
// <Identity ident={Into::<PublicIdentity>::into(target)}/>
|
|
||||||
// </>
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
// let marked = marked.iter().cloned().collect();
|
|
||||||
|
|
||||||
// html! {
|
|
||||||
// <div>
|
|
||||||
// {identity_html(props, Some(&character_id))}
|
|
||||||
// <h2>{"guardian"}</h2>
|
|
||||||
// {last_protect}
|
|
||||||
// <TargetPicker
|
|
||||||
// targets={living_players.clone()}
|
|
||||||
// marked={marked}
|
|
||||||
// mark_callback={mark_callback}
|
|
||||||
// continue_callback={continue_callback}
|
|
||||||
// />
|
|
||||||
// </div>
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ActionPrompt::WolfPackKill { living_villagers } => {
|
|
||||||
// let on_complete = props.on_complete.clone();
|
|
||||||
|
|
||||||
// html! {
|
|
||||||
// <SingleTarget
|
|
||||||
// targets={living_villagers.clone()}
|
|
||||||
// target_selection={on_select}
|
|
||||||
// headline={"wolf pack kill"}
|
|
||||||
// />
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ActionPrompt::Shapeshifter { character_id } => {
|
|
||||||
// let on_complete = props.on_complete.clone();
|
|
||||||
// let on_select = props.big_screen.not().then_some({
|
|
||||||
// move |shift| {
|
|
||||||
// on_complete.emit(HostMessage::InGame(HostGameMessage::Night(
|
|
||||||
// HostNightMessage::ActionResponse(ActionResponse::Shapeshifter(shift)),
|
|
||||||
// )));
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// html! {
|
|
||||||
// <div>
|
|
||||||
// {identity_html(props, Some(&character_id))}
|
|
||||||
// <BinaryChoice on_chosen={on_select}>
|
|
||||||
// <h2>{"shapeshift?"}</h2>
|
|
||||||
// </BinaryChoice>
|
|
||||||
// </div>
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ActionPrompt::AlphaWolf {
|
|
||||||
// character_id,
|
|
||||||
// living_villagers,
|
|
||||||
// } => {
|
|
||||||
// let on_complete = props.on_complete.clone();
|
|
||||||
// let on_select = props.big_screen.not().then(|| {
|
|
||||||
// Callback::from(move |target: Option<CharacterId>| {
|
|
||||||
// on_complete.emit(HostMessage::InGame(HostGameMessage::Night(
|
|
||||||
// HostNightMessage::ActionResponse(ActionResponse::AlphaWolf(target)),
|
|
||||||
// )));
|
|
||||||
// })
|
|
||||||
// });
|
|
||||||
// html! {
|
|
||||||
// <div>
|
|
||||||
// {identity_html(props, Some(&character_id))}
|
|
||||||
// <OptionalSingleTarget
|
|
||||||
// targets={living_villagers.clone()}
|
|
||||||
// target_selection={on_select}
|
|
||||||
// headline={"alpha wolf target"}
|
|
||||||
// />
|
|
||||||
// </div>
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ActionPrompt::DireWolf {
|
|
||||||
// character_id,
|
|
||||||
// living_players,
|
|
||||||
// } => {
|
|
||||||
// let on_complete = props.on_complete.clone();
|
|
||||||
// let on_select = props.big_screen.not().then(|| {
|
|
||||||
// Callback::from(move |target: CharacterId| {
|
|
||||||
// on_complete.emit(HostMessage::InGame(HostGameMessage::Night(
|
|
||||||
// HostNightMessage::ActionResponse(ActionResponse::Direwolf(target)),
|
|
||||||
// )));
|
|
||||||
// })
|
|
||||||
// });
|
|
||||||
// html! {
|
|
||||||
// <div>
|
|
||||||
// {identity_html(props, Some(&character_id))}
|
|
||||||
// <SingleTarget
|
|
||||||
// targets={living_players.clone()}
|
|
||||||
// target_selection={on_select}
|
|
||||||
// headline={"direwolf block target"}
|
|
||||||
// />
|
|
||||||
// </div>
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,20 @@
|
||||||
use core::ops::Not;
|
use core::ops::Not;
|
||||||
|
|
||||||
use convert_case::{Case, Casing};
|
use convert_case::{Case, Casing};
|
||||||
use werewolves_proto::{
|
use werewolves_proto::message::{
|
||||||
message::{
|
PublicIdentity,
|
||||||
PublicIdentity,
|
host::{HostGameMessage, HostMessage, HostNightMessage},
|
||||||
host::{HostGameMessage, HostMessage, HostNightMessage},
|
night::ActionResult,
|
||||||
night::ActionResult,
|
|
||||||
},
|
|
||||||
role::Alignment,
|
|
||||||
};
|
};
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Button, CoverOfDarkness, Icon, IconSource, Identity};
|
use crate::{
|
||||||
|
components::{Button, CoverOfDarkness, Icon, IconSource, Identity},
|
||||||
|
pages::{
|
||||||
|
AdjudicatorResult, ArcanistResult, EmpathResult, GravediggerResultPage, InsomniacResult,
|
||||||
|
MorticianResultPage, PowerSeerResult, RoleblockPage, SeerResult,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Properties)]
|
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||||
pub struct ActionResultProps {
|
pub struct ActionResultProps {
|
||||||
|
|
@ -42,128 +45,42 @@ pub fn ActionResultView(props: &ActionResultProps) -> Html {
|
||||||
.then(|| html! {<Button on_click={on_complete}>{"continue"}</Button>});
|
.then(|| html! {<Button on_click={on_complete}>{"continue"}</Button>});
|
||||||
let body = match &props.result {
|
let body = match &props.result {
|
||||||
ActionResult::PowerSeer { powerful } => {
|
ActionResult::PowerSeer { powerful } => {
|
||||||
let inactive = powerful.powerful().not().then_some("inactive");
|
|
||||||
let text = if powerful.powerful() {
|
|
||||||
"powerful"
|
|
||||||
} else {
|
|
||||||
"not powerful"
|
|
||||||
};
|
|
||||||
html! {
|
html! {
|
||||||
<>
|
<PowerSeerResult powerful={*powerful}/>
|
||||||
<img src="/img/powerful.svg" class={classes!(inactive)}/>
|
|
||||||
<h3>{text}</h3>
|
|
||||||
</>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionResult::Adjudicator { killer } => {
|
ActionResult::Adjudicator { killer } => {
|
||||||
let text = if killer.killer() {
|
|
||||||
"is a killer"
|
|
||||||
} else {
|
|
||||||
"is NOT a killer"
|
|
||||||
};
|
|
||||||
html! {
|
html! {
|
||||||
<>
|
<AdjudicatorResult killer={*killer}/>
|
||||||
<h1>{"your target..."}</h1>
|
|
||||||
<Icon source={IconSource::Killer} inactive={killer.killer().not()}/>
|
|
||||||
<h2>{text}</h2>
|
|
||||||
</>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionResult::Mortician(died_to) => html! {
|
ActionResult::Mortician(died_to) => html! {
|
||||||
<h2>{"cause of death: "}{died_to.to_string().to_case(Case::Title)}</h2>
|
<MorticianResultPage died_to={*died_to}/>
|
||||||
},
|
},
|
||||||
ActionResult::Empath { scapegoat: true } => html! {
|
ActionResult::Empath { scapegoat } => html! {
|
||||||
<>
|
<EmpathResult scapegoat={*scapegoat}/>
|
||||||
<h2>{"was the scapegoat!"}</h2>
|
|
||||||
<h3>{"tag! you're it!"}</h3>
|
|
||||||
</>
|
|
||||||
},
|
|
||||||
ActionResult::Empath { scapegoat: false } => html! {
|
|
||||||
<h2>{"not the scapegoat"}</h2>
|
|
||||||
},
|
},
|
||||||
ActionResult::Insomniac(visits) => {
|
ActionResult::Insomniac(visits) => {
|
||||||
let visits = visits
|
|
||||||
.iter()
|
|
||||||
.map(|v| {
|
|
||||||
let ident: PublicIdentity = v.clone().into();
|
|
||||||
html! {
|
|
||||||
<Identity ident={ident}/>
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Html>();
|
|
||||||
html! {
|
html! {
|
||||||
<>
|
<InsomniacResult visits={visits.clone()}/>
|
||||||
<h1>{"tonight you were visited by..."}</h1>
|
|
||||||
<div class="result-list">
|
|
||||||
{visits}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionResult::RoleBlocked => {
|
ActionResult::RoleBlocked => {
|
||||||
html! {
|
html! {
|
||||||
<h2>{"you were role blocked"}</h2>
|
<RoleblockPage />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionResult::Seer(alignment) => html! {
|
ActionResult::Seer(alignment) => html! {
|
||||||
<>
|
<SeerResult alignment={*alignment}/>
|
||||||
<h2>{"the alignment was"}</h2>
|
|
||||||
{match alignment {
|
|
||||||
Alignment::Village => html!{
|
|
||||||
<>
|
|
||||||
<Icon source={IconSource::Village}/>
|
|
||||||
<h3>{"village"}</h3>
|
|
||||||
</>
|
|
||||||
},
|
|
||||||
Alignment::Wolves => html!{
|
|
||||||
<>
|
|
||||||
<Icon source={IconSource::Wolves}/>
|
|
||||||
<h3>{"wolves"}</h3>
|
|
||||||
</>
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
</>
|
|
||||||
},
|
},
|
||||||
ActionResult::Arcanist(same) => {
|
ActionResult::Arcanist(same) => {
|
||||||
let outcome = if same.same() {
|
|
||||||
html! {
|
|
||||||
<>
|
|
||||||
<div class="arcanist-result">
|
|
||||||
<Icon source={IconSource::Village}/>
|
|
||||||
<Icon source={IconSource::Village}/>
|
|
||||||
<Icon source={IconSource::Wolves}/>
|
|
||||||
<Icon source={IconSource::Wolves}/>
|
|
||||||
</div>
|
|
||||||
<h2>{"the same"}</h2>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
html! {
|
|
||||||
<>
|
|
||||||
<div class="arcanist-result">
|
|
||||||
<Icon source={IconSource::Village}/>
|
|
||||||
<Icon source={IconSource::Wolves}/>
|
|
||||||
</div>
|
|
||||||
<h2>{"different"}</h2>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
};
|
|
||||||
html! {
|
html! {
|
||||||
<>
|
<ArcanistResult alignment_eq={*same}/>
|
||||||
<h1>{"the alignments are:"}</h1>
|
|
||||||
<p>{outcome}</p>
|
|
||||||
</>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionResult::GraveDigger(role_title) => {
|
ActionResult::GraveDigger(role_title) => {
|
||||||
let dig = role_title
|
|
||||||
.map(|r| r.to_string().to_case(Case::Title))
|
|
||||||
.unwrap_or_else(|| String::from("an empty grave"));
|
|
||||||
html! {
|
html! {
|
||||||
<>
|
<GravediggerResultPage role={*role_title}/>
|
||||||
<h2>{"you see:"}</h2>
|
|
||||||
<p>{dig}</p>
|
|
||||||
</>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ActionResult::GoBackToSleep => {
|
ActionResult::GoBackToSleep => {
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ pub fn WolvesIntro(props: &WolvesIntroProps) -> Html {
|
||||||
<div class="row-list wolves-list">
|
<div class="row-list wolves-list">
|
||||||
{
|
{
|
||||||
props.wolves.iter().map(|w| html!{
|
props.wolves.iter().map(|w| html!{
|
||||||
<div class="character wolves">
|
<div class="character wolves faint">
|
||||||
<p class="role">{w.1.to_string()}</p>
|
<p class="role">{w.1.to_string()}</p>
|
||||||
<Identity ident={Into::<PublicIdentity>::into(&w.0)} />
|
<Identity ident={Into::<PublicIdentity>::into(&w.0)} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use convert_case::{Case, Casing};
|
use convert_case::{Case, Casing};
|
||||||
use werewolves_proto::{character::Character, game::SetupRole};
|
use werewolves_proto::{character::Character, game::SetupRole, message::CharacterIdentity};
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::{Icon, IconSource, IconType, PartialAssociatedIcon};
|
use crate::components::{Icon, IconSource, IconType, PartialAssociatedIcon};
|
||||||
|
|
@ -7,10 +7,14 @@ use crate::components::{Icon, IconSource, IconType, PartialAssociatedIcon};
|
||||||
#[derive(Debug, Clone, PartialEq, Properties)]
|
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||||
pub struct CharacterCardProps {
|
pub struct CharacterCardProps {
|
||||||
pub char: Character,
|
pub char: Character,
|
||||||
|
#[prop_or_default]
|
||||||
|
pub dead: bool,
|
||||||
|
#[prop_or_default]
|
||||||
|
pub faint: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn CharacterCard(CharacterCardProps { char }: &CharacterCardProps) -> Html {
|
pub fn CharacterCard(CharacterCardProps { faint, char, dead }: &CharacterCardProps) -> Html {
|
||||||
let class = Into::<SetupRole>::into(char.role_title())
|
let class = Into::<SetupRole>::into(char.role_title())
|
||||||
.category()
|
.category()
|
||||||
.class();
|
.class();
|
||||||
|
|
@ -28,10 +32,18 @@ pub fn CharacterCard(CharacterCardProps { char }: &CharacterCardProps) -> Html {
|
||||||
IconSource::Wolves
|
IconSource::Wolves
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let dead = dead.then(|| {
|
||||||
|
html! {
|
||||||
|
<Icon source={IconSource::Skull} icon_type={IconType::Small}/>
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let faint = faint.then_some("faint");
|
||||||
|
|
||||||
html! {
|
html! {
|
||||||
<span class={classes!("character-span", class)}>
|
<span class={classes!("character-span", class, faint)}>
|
||||||
<span class={classes!("role", class)}>
|
<span class={classes!("role", class, faint)}>
|
||||||
<div>
|
<div>
|
||||||
|
{dead}
|
||||||
<Icon source={source} icon_type={IconType::Small}/>
|
<Icon source={source} icon_type={IconType::Small}/>
|
||||||
</div>
|
</div>
|
||||||
{role}
|
{role}
|
||||||
|
|
@ -42,3 +54,20 @@ pub fn CharacterCard(CharacterCardProps { char }: &CharacterCardProps) -> Html {
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||||
|
pub struct CharacterTargetCardProps {
|
||||||
|
pub ident: CharacterIdentity,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn CharacterTargetCard(CharacterTargetCardProps { ident }: &CharacterTargetCardProps) -> Html {
|
||||||
|
let name = ident.name.clone();
|
||||||
|
|
||||||
|
html! {
|
||||||
|
<span class={classes!("character-span")}>
|
||||||
|
<span class={classes!("number")}><b>{ident.number.get()}</b></span>
|
||||||
|
<span class="name">{name}</span>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,43 +4,51 @@ use werewolves_proto::{
|
||||||
};
|
};
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
macro_rules! decl_icon {
|
||||||
pub enum IconSource {
|
($($name:ident: $path:literal,)*) => {
|
||||||
Village,
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
Wolves,
|
pub enum IconSource {
|
||||||
Killer,
|
$(
|
||||||
Powerful,
|
$name,
|
||||||
ListItem,
|
)*
|
||||||
Skull,
|
}
|
||||||
Heart,
|
|
||||||
Shield,
|
impl IconSource {
|
||||||
ShieldAndSword,
|
pub const fn source(&self) -> &'static str {
|
||||||
Seer,
|
match self {
|
||||||
Hunter,
|
$(
|
||||||
MapleWolf,
|
Self::$name => $path,
|
||||||
Gravedigger,
|
)*
|
||||||
PowerSeer,
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
decl_icon!(
|
||||||
|
Village: "/img/village.svg",
|
||||||
|
Wolves: "/img/wolf.svg",
|
||||||
|
Killer: "/img/killer.svg",
|
||||||
|
Powerful: "/img/powerful.svg",
|
||||||
|
ListItem: "/img/li.svg",
|
||||||
|
Skull: "/img/skull.svg",
|
||||||
|
Heart: "/img/heart.svg",
|
||||||
|
Shield: "/img/shield.svg",
|
||||||
|
ShieldAndSword: "/img/shield-and-sword.svg",
|
||||||
|
Seer: "/img/seer.svg",
|
||||||
|
Hunter: "/img/hunter.svg",
|
||||||
|
MapleWolf: "/img/maple-wolf.svg",
|
||||||
|
Gravedigger: "/img/gravedigger.svg",
|
||||||
|
PowerSeer: "/img/power-seer.svg",
|
||||||
|
Scapegoat: "/img/scapegoat.svg",
|
||||||
|
Diseased: "/img/diseased.svg",
|
||||||
|
Mortician: "/img/mortician.svg",
|
||||||
|
Pyremaster: "/img/pyremaster.svg",
|
||||||
|
Sword: "/img/sword.svg",
|
||||||
|
Roleblock: "/img/roleblock.svg",
|
||||||
|
);
|
||||||
|
|
||||||
impl IconSource {
|
impl IconSource {
|
||||||
pub const fn source(&self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
IconSource::Village => "/img/village.svg",
|
|
||||||
IconSource::Wolves => "/img/wolf.svg",
|
|
||||||
IconSource::Killer => "/img/killer.svg",
|
|
||||||
IconSource::Powerful => "/img/powerful.svg",
|
|
||||||
IconSource::ListItem => "/img/li.svg",
|
|
||||||
IconSource::Skull => "/img/skull.svg",
|
|
||||||
IconSource::Heart => "/img/heart.svg",
|
|
||||||
IconSource::Shield => "/img/shield.svg",
|
|
||||||
IconSource::ShieldAndSword => "/img/shield-and-sword.svg",
|
|
||||||
IconSource::Seer => "/img/seer.svg",
|
|
||||||
IconSource::Hunter => "/img/hunter.svg",
|
|
||||||
IconSource::MapleWolf => "/img/maple-wolf.svg",
|
|
||||||
IconSource::Gravedigger => "/img/gravedigger.svg",
|
|
||||||
IconSource::PowerSeer => "/img/power-seer.svg",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub const fn class(&self) -> Option<&'static str> {
|
pub const fn class(&self) -> Option<&'static str> {
|
||||||
match self {
|
match self {
|
||||||
IconSource::Killer => Some("killer"),
|
IconSource::Killer => Some("killer"),
|
||||||
|
|
@ -53,6 +61,7 @@ impl IconSource {
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||||
pub enum IconType {
|
pub enum IconType {
|
||||||
Small,
|
Small,
|
||||||
|
Informational,
|
||||||
#[default]
|
#[default]
|
||||||
RoleCheck,
|
RoleCheck,
|
||||||
}
|
}
|
||||||
|
|
@ -61,6 +70,7 @@ impl IconType {
|
||||||
pub const fn class(&self) -> &'static str {
|
pub const fn class(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
IconType::Small => "icon",
|
IconType::Small => "icon",
|
||||||
|
IconType::Informational => "icon-info",
|
||||||
IconType::RoleCheck => "check-icon",
|
IconType::RoleCheck => "check-icon",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -122,27 +132,27 @@ impl AssociatedIcon for Powerful {
|
||||||
impl PartialAssociatedIcon for RoleTitle {
|
impl PartialAssociatedIcon for RoleTitle {
|
||||||
fn icon(&self) -> Option<IconSource> {
|
fn icon(&self) -> Option<IconSource> {
|
||||||
Some(match self {
|
Some(match self {
|
||||||
RoleTitle::Scapegoat
|
RoleTitle::Arcanist
|
||||||
| RoleTitle::Arcanist
|
|
||||||
| RoleTitle::Adjudicator
|
| RoleTitle::Adjudicator
|
||||||
| RoleTitle::Mortician
|
|
||||||
| RoleTitle::Beholder
|
| RoleTitle::Beholder
|
||||||
| RoleTitle::MasonLeader
|
| RoleTitle::MasonLeader
|
||||||
| RoleTitle::Diseased
|
|
||||||
| RoleTitle::BlackKnight
|
| RoleTitle::BlackKnight
|
||||||
| RoleTitle::Weightlifter
|
| RoleTitle::Weightlifter
|
||||||
| RoleTitle::PyreMaster
|
|
||||||
| RoleTitle::Militia
|
|
||||||
| RoleTitle::Apprentice
|
| RoleTitle::Apprentice
|
||||||
| RoleTitle::Elder
|
| RoleTitle::Elder
|
||||||
| RoleTitle::Insomniac
|
| RoleTitle::Insomniac
|
||||||
| RoleTitle::Werewolf
|
|
||||||
| RoleTitle::AlphaWolf
|
| RoleTitle::AlphaWolf
|
||||||
| RoleTitle::DireWolf
|
| RoleTitle::DireWolf
|
||||||
| RoleTitle::Shapeshifter
|
| RoleTitle::Shapeshifter
|
||||||
| RoleTitle::LoneWolf
|
| RoleTitle::LoneWolf
|
||||||
| RoleTitle::Villager => return None,
|
| RoleTitle::Villager => return None,
|
||||||
|
|
||||||
|
RoleTitle::Werewolf => IconSource::Wolves,
|
||||||
|
RoleTitle::Militia => IconSource::Sword,
|
||||||
|
RoleTitle::PyreMaster => IconSource::Pyremaster,
|
||||||
|
RoleTitle::Mortician => IconSource::Mortician,
|
||||||
|
RoleTitle::Diseased => IconSource::Diseased,
|
||||||
|
RoleTitle::Scapegoat => IconSource::Scapegoat,
|
||||||
RoleTitle::PowerSeer => IconSource::PowerSeer,
|
RoleTitle::PowerSeer => IconSource::PowerSeer,
|
||||||
RoleTitle::Gravedigger => IconSource::Gravedigger,
|
RoleTitle::Gravedigger => IconSource::Gravedigger,
|
||||||
RoleTitle::MapleWolf => IconSource::MapleWolf,
|
RoleTitle::MapleWolf => IconSource::MapleWolf,
|
||||||
|
|
@ -160,13 +170,13 @@ impl PartialAssociatedIcon for DiedToTitle {
|
||||||
match self {
|
match self {
|
||||||
DiedToTitle::Execution => Some(IconSource::Skull),
|
DiedToTitle::Execution => Some(IconSource::Skull),
|
||||||
DiedToTitle::MapleWolf | DiedToTitle::MapleWolfStarved => Some(IconSource::MapleWolf),
|
DiedToTitle::MapleWolf | DiedToTitle::MapleWolfStarved => Some(IconSource::MapleWolf),
|
||||||
DiedToTitle::Militia => Some(IconSource::Killer),
|
DiedToTitle::Militia => Some(IconSource::Sword),
|
||||||
DiedToTitle::Wolfpack => None,
|
DiedToTitle::Wolfpack => None,
|
||||||
DiedToTitle::AlphaWolf => None,
|
DiedToTitle::AlphaWolf => None,
|
||||||
DiedToTitle::Shapeshift => None,
|
DiedToTitle::Shapeshift => None,
|
||||||
DiedToTitle::Hunter => Some(IconSource::Hunter),
|
DiedToTitle::Hunter => Some(IconSource::Hunter),
|
||||||
DiedToTitle::GuardianProtecting => Some(IconSource::ShieldAndSword),
|
DiedToTitle::GuardianProtecting => Some(IconSource::ShieldAndSword),
|
||||||
DiedToTitle::PyreMaster => None,
|
DiedToTitle::PyreMaster => Some(IconSource::Pyremaster),
|
||||||
DiedToTitle::PyreMasterLynchMob => None,
|
DiedToTitle::PyreMasterLynchMob => None,
|
||||||
DiedToTitle::MasonLeaderRecruitFail => None,
|
DiedToTitle::MasonLeaderRecruitFail => None,
|
||||||
DiedToTitle::LoneWolf => None,
|
DiedToTitle::LoneWolf => None,
|
||||||
|
|
|
||||||
|
|
@ -29,14 +29,21 @@ pub struct StoryProps {
|
||||||
|
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn Story(StoryProps { story }: &StoryProps) -> Html {
|
pub fn Story(StoryProps { story }: &StoryProps) -> Html {
|
||||||
let characters = Rc::new(
|
let final_characters =
|
||||||
story
|
story
|
||||||
.starting_village
|
.final_village()
|
||||||
|
.unwrap_or_else(|_| story.starting_village.clone())
|
||||||
.characters()
|
.characters()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|c| (c.character_id(), c))
|
.map(|c| {
|
||||||
.collect::<HashMap<CharacterId, Character>>(),
|
let dead =c.alive().not();
|
||||||
);
|
html! {
|
||||||
|
<>
|
||||||
|
<CharacterCard faint=true char={c} dead={dead}/>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Html>();
|
||||||
let bits = story
|
let bits = story
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(time, changes)| {
|
.map(|(time, changes)| {
|
||||||
|
|
@ -51,7 +58,12 @@ pub fn Story(StoryProps { story }: &StoryProps) -> Html {
|
||||||
}).ok().flatten()
|
}).ok().flatten()
|
||||||
.map(|v| Rc::new(v.characters().into_iter()
|
.map(|v| Rc::new(v.characters().into_iter()
|
||||||
.map(|c| (c.character_id(), c))
|
.map(|c| (c.character_id(), c))
|
||||||
.collect::<HashMap<CharacterId, Character>>())).unwrap_or_else(|| characters.clone());
|
.collect::<HashMap<CharacterId, Character>>()))
|
||||||
|
.unwrap_or_else(||
|
||||||
|
Rc::new(story.starting_village
|
||||||
|
.characters().into_iter()
|
||||||
|
.map(|c| (c.character_id(), c))
|
||||||
|
.collect::<HashMap<_, _>>()));
|
||||||
let changes = match changes {
|
let changes = match changes {
|
||||||
GameActions::DayDetails(day_changes) => {
|
GameActions::DayDetails(day_changes) => {
|
||||||
let execute_list = if day_changes.is_empty() {
|
let execute_list = if day_changes.is_empty() {
|
||||||
|
|
@ -66,7 +78,7 @@ pub fn Story(StoryProps { story }: &StoryProps) -> Html {
|
||||||
.map(|c| {
|
.map(|c| {
|
||||||
html! {
|
html! {
|
||||||
// <span>
|
// <span>
|
||||||
<CharacterCard char={c.clone()}/>
|
<CharacterCard faint=true char={c.clone()}/>
|
||||||
// </span>
|
// </span>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -134,6 +146,9 @@ pub fn Story(StoryProps { story }: &StoryProps) -> Html {
|
||||||
.collect::<Html>();
|
.collect::<Html>();
|
||||||
html! {
|
html! {
|
||||||
<div class="story">
|
<div class="story">
|
||||||
|
<div class="cast">
|
||||||
|
{final_characters}
|
||||||
|
</div>
|
||||||
{bits}
|
{bits}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
@ -156,9 +171,9 @@ fn StoryNightChange(StoryNightChangeProps { change, characters }: &StoryNightCha
|
||||||
|
|
||||||
html! {
|
html! {
|
||||||
<>
|
<>
|
||||||
<CharacterCard char={char.clone()}/>
|
<CharacterCard faint=true char={char.clone()}/>
|
||||||
{"is now"}
|
{"is now"}
|
||||||
<CharacterCard char={new_char.clone()}/>
|
<CharacterCard faint=true char={new_char.clone()}/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -170,7 +185,7 @@ fn StoryNightChange(StoryNightChangeProps { change, characters }: &StoryNightCha
|
||||||
html! {
|
html! {
|
||||||
<>
|
<>
|
||||||
<Icon source={IconSource::Skull} icon_type={IconType::Small}/>
|
<Icon source={IconSource::Skull} icon_type={IconType::Small}/>
|
||||||
<CharacterCard char={target.clone()}/>
|
<CharacterCard faint=true char={target.clone()}/>
|
||||||
{"died to"}
|
{"died to"}
|
||||||
<DiedToSpan died_to={died_to.title()}/>
|
<DiedToSpan died_to={died_to.title()}/>
|
||||||
</>
|
</>
|
||||||
|
|
@ -183,9 +198,9 @@ fn StoryNightChange(StoryNightChangeProps { change, characters }: &StoryNightCha
|
||||||
.map(|(source, target)| {
|
.map(|(source, target)| {
|
||||||
html! {
|
html! {
|
||||||
<>
|
<>
|
||||||
<CharacterCard char={source.clone()}/>
|
<CharacterCard faint=true char={source.clone()}/>
|
||||||
{"role blocked"}
|
{"role blocked"}
|
||||||
<CharacterCard char={target.clone()}/>
|
<CharacterCard faint=true char={target.clone()}/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -196,9 +211,9 @@ fn StoryNightChange(StoryNightChangeProps { change, characters }: &StoryNightCha
|
||||||
.map(|(source, into)| {
|
.map(|(source, into)| {
|
||||||
html! {
|
html! {
|
||||||
<>
|
<>
|
||||||
<CharacterCard char={source.clone()}/>
|
<CharacterCard faint=true char={source.clone()}/>
|
||||||
{"shapeshifted into"}
|
{"shapeshifted into"}
|
||||||
<CharacterCard char={into.clone()}/>
|
<CharacterCard faint=true char={into.clone()}/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -209,7 +224,7 @@ fn StoryNightChange(StoryNightChangeProps { change, characters }: &StoryNightCha
|
||||||
.map(|elder| {
|
.map(|elder| {
|
||||||
html! {
|
html! {
|
||||||
<>
|
<>
|
||||||
<CharacterCard char={elder.clone()}/>
|
<CharacterCard faint=true char={elder.clone()}/>
|
||||||
{"learned they are the Elder"}
|
{"learned they are the Elder"}
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
@ -221,9 +236,9 @@ fn StoryNightChange(StoryNightChangeProps { change, characters }: &StoryNightCha
|
||||||
.map(|(empath, scapegoat)| {
|
.map(|(empath, scapegoat)| {
|
||||||
html! {
|
html! {
|
||||||
<>
|
<>
|
||||||
<CharacterCard char={empath.clone()}/>
|
<CharacterCard faint=true char={empath.clone()}/>
|
||||||
{"found the scapegoat in"}
|
{"found the scapegoat in"}
|
||||||
<CharacterCard char={scapegoat.clone()}/>
|
<CharacterCard faint=true char={scapegoat.clone()}/>
|
||||||
{"and took on their curse"}
|
{"and took on their curse"}
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
@ -304,7 +319,7 @@ fn StoryNightResult(StoryNightResultProps { result, characters }: &StoryNightRes
|
||||||
.filter_map(|c| characters.get(c))
|
.filter_map(|c| characters.get(c))
|
||||||
.map(|c| {
|
.map(|c| {
|
||||||
html! {
|
html! {
|
||||||
<CharacterCard char={c.clone()}/>
|
<CharacterCard faint=true char={c.clone()}/>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Html>();
|
.collect::<Html>();
|
||||||
|
|
@ -353,9 +368,9 @@ fn StoryNightChoice(StoryNightChoiceProps { choice, characters }: &StoryNightCho
|
||||||
.map(|(char, chosen)| {
|
.map(|(char, chosen)| {
|
||||||
html! {
|
html! {
|
||||||
<>
|
<>
|
||||||
<CharacterCard char={char.clone()}/>
|
<CharacterCard faint=true char={char.clone()}/>
|
||||||
<span>{action}</span>
|
<span>{action}</span>
|
||||||
<CharacterCard char={chosen.clone()}/>
|
<CharacterCard faint=true char={chosen.clone()}/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -375,11 +390,11 @@ fn StoryNightChoice(StoryNightChoiceProps { choice, characters }: &StoryNightCho
|
||||||
.map(|(arcanist, chosen1, chosen2)| {
|
.map(|(arcanist, chosen1, chosen2)| {
|
||||||
html! {
|
html! {
|
||||||
<>
|
<>
|
||||||
<CharacterCard char={arcanist.clone()}/>
|
<CharacterCard faint=true char={arcanist.clone()}/>
|
||||||
<span>{"compared"}</span>
|
<span>{"compared"}</span>
|
||||||
<CharacterCard char={chosen1.clone()}/>
|
<CharacterCard faint=true char={chosen1.clone()}/>
|
||||||
<span>{"and"}</span>
|
<span>{"and"}</span>
|
||||||
<CharacterCard char={chosen2.clone()}/>
|
<CharacterCard faint=true char={chosen2.clone()}/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
@ -389,13 +404,13 @@ fn StoryNightChoice(StoryNightChoiceProps { choice, characters }: &StoryNightCho
|
||||||
.filter_map(|m| characters.get(m))
|
.filter_map(|m| characters.get(m))
|
||||||
.map(|c| {
|
.map(|c| {
|
||||||
html! {
|
html! {
|
||||||
<CharacterCard char={c.clone()}/>
|
<CharacterCard faint=true char={c.clone()}/>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Html>();
|
.collect::<Html>();
|
||||||
html! {
|
html! {
|
||||||
<>
|
<>
|
||||||
<CharacterCard char={leader.clone()}/>
|
<CharacterCard faint=true char={leader.clone()}/>
|
||||||
<span>{"'s masons"}</span>
|
<span>{"'s masons"}</span>
|
||||||
{masons}
|
{masons}
|
||||||
<span>{"convened in secret"}</span>
|
<span>{"convened in secret"}</span>
|
||||||
|
|
@ -447,9 +462,9 @@ fn StoryNightChoice(StoryNightChoiceProps { choice, characters }: &StoryNightCho
|
||||||
.map(|(char, chosen)| {
|
.map(|(char, chosen)| {
|
||||||
html! {
|
html! {
|
||||||
<>
|
<>
|
||||||
<CharacterCard char={char.clone()}/>
|
<CharacterCard faint=true char={char.clone()}/>
|
||||||
<span>{"invited"}</span>
|
<span>{"invited"}</span>
|
||||||
<CharacterCard char={chosen.clone()}/>
|
<CharacterCard faint=true char={chosen.clone()}/>
|
||||||
<span>{"for dinner"}</span>
|
<span>{"for dinner"}</span>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
@ -486,7 +501,7 @@ fn StoryNightChoice(StoryNightChoiceProps { choice, characters }: &StoryNightCho
|
||||||
<>
|
<>
|
||||||
<AlignmentSpan alignment={Alignment::Wolves}/>
|
<AlignmentSpan alignment={Alignment::Wolves}/>
|
||||||
<span>{"attempted a kill on"}</span>
|
<span>{"attempted a kill on"}</span>
|
||||||
<CharacterCard char={chosen.clone()} />
|
<CharacterCard faint=true char={chosen.clone()} />
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -495,7 +510,7 @@ fn StoryNightChoice(StoryNightChoiceProps { choice, characters }: &StoryNightCho
|
||||||
characters.get(character_id).map(|shifter| {
|
characters.get(character_id).map(|shifter| {
|
||||||
html! {
|
html! {
|
||||||
<>
|
<>
|
||||||
<CharacterCard char={shifter.clone()} />
|
<CharacterCard faint=true char={shifter.clone()} />
|
||||||
<span>{"decided to shapeshift into the wolf kill target"}</span>
|
<span>{"decided to shapeshift into the wolf kill target"}</span>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
@ -517,7 +532,7 @@ fn StoryNightChoice(StoryNightChoiceProps { choice, characters }: &StoryNightCho
|
||||||
characters.get(character_id).map(|insomniac| {
|
characters.get(character_id).map(|insomniac| {
|
||||||
html! {
|
html! {
|
||||||
<>
|
<>
|
||||||
<CharacterCard char={insomniac.clone()} />
|
<CharacterCard faint=true char={insomniac.clone()} />
|
||||||
<span>{"witnessed visits from"}</span>
|
<span>{"witnessed visits from"}</span>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
use convert_case::{Case, Casing};
|
||||||
|
use werewolves_proto::{
|
||||||
|
game::SetupRole,
|
||||||
|
role::{Alignment, RoleTitle},
|
||||||
|
};
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::{AssociatedIcon, Icon, IconSource, IconType, PartialAssociatedIcon};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
||||||
|
pub struct RoleChangePageProps {
|
||||||
|
pub role: RoleTitle,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn RoleChangePage(RoleChangePageProps { role }: &RoleChangePageProps) -> Html {
|
||||||
|
let class = Into::<SetupRole>::into(*role).category().class();
|
||||||
|
let icon = role.icon().map(|icon| {
|
||||||
|
html! {
|
||||||
|
<h4 class="icons">
|
||||||
|
<Icon source={icon} icon_type={IconType::Informational}/>
|
||||||
|
</h4>
|
||||||
|
}
|
||||||
|
});
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="intel">{"ROLE CHANGE"}</h1>
|
||||||
|
<div class={classes!("information", class, "faint")}>
|
||||||
|
<h2>{"YOUR ROLE HAS CHANGED"}</h2>
|
||||||
|
{icon}
|
||||||
|
<h3 class="yellow">{"YOUR NEW ROLE IS"}</h3>
|
||||||
|
<h3>{role.to_string().to_case(Case::Upper)}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,16 @@
|
||||||
use core::ops::Not;
|
use core::ops::Not;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use werewolves_proto::message::{PublicIdentity, night::ActionPrompt};
|
use werewolves_proto::{
|
||||||
|
message::{CharacterIdentity, PublicIdentity, night::ActionPrompt},
|
||||||
|
role::PreviousGuardianAction,
|
||||||
|
};
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::components::Identity;
|
use crate::{
|
||||||
|
components::Identity,
|
||||||
|
pages::{RoleChangePage, WolfpackKillPage},
|
||||||
|
};
|
||||||
|
|
||||||
werewolves_macros::include_path!("werewolves/src/pages/role_page");
|
werewolves_macros::include_path!("werewolves/src/pages/role_page");
|
||||||
pub trait RolePage {
|
pub trait RolePage {
|
||||||
|
|
@ -13,28 +19,194 @@ pub trait RolePage {
|
||||||
|
|
||||||
impl RolePage for ActionPrompt {
|
impl RolePage for ActionPrompt {
|
||||||
fn role_pages(&self, big_screen: bool) -> Rc<[yew::Html]> {
|
fn role_pages(&self, big_screen: bool) -> Rc<[yew::Html]> {
|
||||||
|
let ident = |character_id: &CharacterIdentity| {
|
||||||
|
big_screen.not().then(|| {
|
||||||
|
html! {
|
||||||
|
<Identity ident={Into::<PublicIdentity>::into(character_id)} />
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
match self {
|
match self {
|
||||||
ActionPrompt::Beholder { character_id, .. } => {
|
ActionPrompt::Beholder { character_id, .. } => Rc::new([html! {
|
||||||
let ident = big_screen.not().then(|| {
|
<>
|
||||||
html! {
|
{ident(character_id)}
|
||||||
<Identity ident={Into::<PublicIdentity>::into(character_id)} />
|
<BeholderPage1 />
|
||||||
}
|
</>
|
||||||
});
|
}]),
|
||||||
Rc::new([
|
ActionPrompt::DireWolf { character_id, .. } => Rc::new([html! {
|
||||||
html! {
|
<>
|
||||||
<>
|
{ident(character_id)}
|
||||||
{ident.clone()}
|
<DirewolfPage1 />
|
||||||
<BeholderPage1 />
|
</>
|
||||||
</>
|
}]),
|
||||||
},
|
ActionPrompt::Adjudicator { character_id, .. } => Rc::new([html! {
|
||||||
html! {
|
<>
|
||||||
<>
|
{ident(character_id)}
|
||||||
{ident}
|
<AdjudicatorPage1 />
|
||||||
<BeholderPage2 />
|
</>
|
||||||
</>
|
}]),
|
||||||
},
|
ActionPrompt::Seer { character_id, .. } => Rc::new([html! {
|
||||||
])
|
<>
|
||||||
}
|
{ident(character_id)}
|
||||||
|
<SeerPage1 />
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::PowerSeer { character_id, .. } => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<PowerSeerPage1 />
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::Arcanist { character_id, .. } => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<ArcanistPage1 />
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::Protector { character_id, .. } => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<ProtectorPage1 />
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::Empath { character_id, .. } => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<EmpathPage1 />
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::Hunter { character_id, .. } => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<HunterPage1 />
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::PyreMaster { character_id, .. } => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<PyremasterPage1 />
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::Militia { character_id, .. } => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<MilitiaPage1 />
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::MapleWolf {
|
||||||
|
character_id,
|
||||||
|
kill_or_die,
|
||||||
|
..
|
||||||
|
} => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<MapleWolfPage1 starving={*kill_or_die} />
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::MasonLeaderRecruit {
|
||||||
|
character_id,
|
||||||
|
recruits_left,
|
||||||
|
..
|
||||||
|
} => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<MasonRecruitPage1 recruits_left={*recruits_left} />
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::MasonsWake { leader, masons } => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(leader)}
|
||||||
|
<MasonsWake leader={leader.clone()} masons={masons.clone()}/>
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::AlphaWolf { character_id, .. } => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<AlphaWolfPage1 />
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::Insomniac { character_id, .. } => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<InsomniacPage1 />
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::ElderReveal { character_id, .. } => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<ElderPage1 />
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::Guardian {
|
||||||
|
character_id,
|
||||||
|
previous: None,
|
||||||
|
..
|
||||||
|
} => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<GuardianPageNoPrevProtect/>
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::Guardian {
|
||||||
|
character_id,
|
||||||
|
previous: Some(PreviousGuardianAction::Protect(target)),
|
||||||
|
..
|
||||||
|
} => Rc::new([
|
||||||
|
html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<GuardianPagePreviousProtect1 previous={target.clone()}/>
|
||||||
|
</>
|
||||||
|
},
|
||||||
|
html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<GuardianPagePreviousProtect2 previous={target.clone()}/>
|
||||||
|
</>
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
ActionPrompt::Guardian {
|
||||||
|
character_id,
|
||||||
|
previous: Some(PreviousGuardianAction::Guard(target)),
|
||||||
|
..
|
||||||
|
} => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<GuardianPagePreviousGuard previous={target.clone()}/>
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::Mortician { character_id, .. } => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<MorticianPage1 />
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::RoleChange {
|
||||||
|
character_id,
|
||||||
|
new_role,
|
||||||
|
} => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<RoleChangePage role={*new_role}/>
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::WolfPackKill { .. } => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
<WolfpackKillPage />
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::Gravedigger { character_id, .. } => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<GravediggerPage1 />
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
|
ActionPrompt::Vindicator { character_id, .. } => Rc::new([html! {
|
||||||
|
<>
|
||||||
|
{ident(character_id)}
|
||||||
|
<VindicatorPage1 />
|
||||||
|
</>
|
||||||
|
}]),
|
||||||
_ => Rc::new([]),
|
_ => Rc::new([]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
use core::ops::Not;
|
||||||
|
|
||||||
|
use werewolves_proto::role::Killer;
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn AdjudicatorPage1() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="defensive">{"ADJUDICATOR"}</h1>
|
||||||
|
<div class="information defensive faint">
|
||||||
|
<h2>{"PICK A PLAYER"}</h2>
|
||||||
|
<h4 class="icons">
|
||||||
|
<Icon source={IconSource::Killer} icon_type={IconType::Informational}/>
|
||||||
|
<Icon source={IconSource::Killer} icon_type={IconType::Informational} inactive={true}/>
|
||||||
|
</h4>
|
||||||
|
<h3 class="yellow">{"YOU WILL CHECK IF THEY APPEAR AS A KILLER"}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
||||||
|
pub struct AdjudicatorResultProps {
|
||||||
|
pub killer: Killer,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn AdjudicatorResult(AdjudicatorResultProps { killer }: &AdjudicatorResultProps) -> Html {
|
||||||
|
let text = match killer {
|
||||||
|
Killer::Killer => "IS A KILLER",
|
||||||
|
Killer::NotKiller => "IS NOT A KILLER",
|
||||||
|
};
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="defensive">{"ADJUDICATOR"}</h1>
|
||||||
|
<div class="information defensive faint">
|
||||||
|
<h2>{"YOUR TARGET"}</h2>
|
||||||
|
<h4><Icon
|
||||||
|
source={IconSource::Killer}
|
||||||
|
icon_type={IconType::Informational}
|
||||||
|
inactive={killer.killer().not()}
|
||||||
|
/></h4>
|
||||||
|
<h3 class="yellow">{text}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn AlphaWolfPage1() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="wolves">{"ALPHA WOLF"}</h1>
|
||||||
|
<div class="information wolves faint">
|
||||||
|
<h2>
|
||||||
|
{"IF YOU WISH TO USE YOUR "}
|
||||||
|
<span class="yellow">{"ONCE PER GAME"}</span>
|
||||||
|
{" KILL ABILITY"}
|
||||||
|
</h2>
|
||||||
|
<h3 class="yellow">
|
||||||
|
{"POINT AT YOUR TARGET "}
|
||||||
|
{"OR GO BACK TO SLEEP"}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
use werewolves_proto::role::AlignmentEq;
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn ArcanistPage1() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="intel">{"ARCANIST"}</h1>
|
||||||
|
<div class="information intel faint">
|
||||||
|
<h2>{"PICK TWO PLAYERS"}</h2>
|
||||||
|
<h4 class="icons">
|
||||||
|
<Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
||||||
|
<Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
||||||
|
<Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
||||||
|
<Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
||||||
|
</h4>
|
||||||
|
<h3 class="yellow">{"YOU WILL CHECK IF THEIR ALIGNMENTS ARE THE SAME OR DIFFERENT"}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
||||||
|
pub struct ArcanistResultProps {
|
||||||
|
pub alignment_eq: AlignmentEq,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn ArcanistResult(ArcanistResultProps { alignment_eq }: &ArcanistResultProps) -> Html {
|
||||||
|
let text = match alignment_eq {
|
||||||
|
AlignmentEq::Same => "THE SAME",
|
||||||
|
AlignmentEq::Different => "DIFFERENT",
|
||||||
|
};
|
||||||
|
let icons = match alignment_eq {
|
||||||
|
AlignmentEq::Same => html! {
|
||||||
|
<>
|
||||||
|
<Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
||||||
|
<Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
||||||
|
<span>{"OR"}</span>
|
||||||
|
<Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
||||||
|
<Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
||||||
|
</>
|
||||||
|
},
|
||||||
|
AlignmentEq::Different => html! {
|
||||||
|
<>
|
||||||
|
<Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
||||||
|
<Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
||||||
|
{"OR"}
|
||||||
|
<Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
||||||
|
<Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
||||||
|
</>
|
||||||
|
},
|
||||||
|
};
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="intel">{"ARCANIST"}</h1>
|
||||||
|
<div class="information intel faint">
|
||||||
|
<h2>{"YOUR TARGETS APPEAR AS"}</h2>
|
||||||
|
<h4 class="icons">
|
||||||
|
{icons}
|
||||||
|
</h4>
|
||||||
|
<h3 class="yellow">{text}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,19 +3,12 @@ use yew::prelude::*;
|
||||||
#[function_component]
|
#[function_component]
|
||||||
pub fn BeholderPage1() -> Html {
|
pub fn BeholderPage1() -> Html {
|
||||||
html! {
|
html! {
|
||||||
<div>
|
<div class="role-page">
|
||||||
<h1>{"this is a beholder"}</h1>
|
<h1 class="intel">{"BEHOLDER"}</h1>
|
||||||
<h2>{"there's information on this page"}</h2>
|
<div class="information intel faint">
|
||||||
</div>
|
<h2>{"PICK A PLAYER"}</h2>
|
||||||
}
|
<h3 class="yellow">{"IF THEY ARE AN INTEL ROLE, YOU WILL SEE WHAT THEY SAW TONIGHT"}</h3>
|
||||||
}
|
</div>
|
||||||
|
|
||||||
#[function_component]
|
|
||||||
pub fn BeholderPage2() -> Html {
|
|
||||||
html! {
|
|
||||||
<div>
|
|
||||||
<h1>{"more information on beholder"}</h1>
|
|
||||||
<h2>{"idk, hi?"}</h2>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn DirewolfPage1() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="wolves">{"DIREWOLF"}</h1>
|
||||||
|
<div class="information wolves faint">
|
||||||
|
<h2>{"CHOOSE A TARGET"}</h2>
|
||||||
|
<h3 class="yellow">{"ANY VISITORS TO THIS TARGET WILL BE ROLE BLOCKED"}</h3>
|
||||||
|
<h4>{"YOU CANNOT CHOOSE YOURSELF OR THE SAME TARGET AS LAST NIGHT"}</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn ElderPage1() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="starts-as-villager">{"ELDER"}</h1>
|
||||||
|
<div class="information starts-as-villager faint">
|
||||||
|
<h2>{"YOU ARE THE ELDER"}</h2>
|
||||||
|
<h4 class="yellow">
|
||||||
|
{"IF YOU ARE EXECUTED BY THE VILLAGE FROM NOW ON "}
|
||||||
|
{"ALL POWER ROLES WILL BE LOST"}
|
||||||
|
</h4>
|
||||||
|
<h4>
|
||||||
|
{"YOU STARTED THE GAME WITH PROTECTION FROM A NIGHT "}
|
||||||
|
{"DEATH — THIS MAY OR MAY NOT STILL BE INTACT"}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
use core::ops::Not;
|
||||||
|
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn EmpathPage1() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="intel">{"EMPATH"}</h1>
|
||||||
|
<div class="information intel faint">
|
||||||
|
<h2>{"PICK A PLAYER"}</h2>
|
||||||
|
<h3 class="yellow">{"YOU WILL CHECK IF THEY ARE THE SCAPEGOAT"}</h3>
|
||||||
|
<h3>{"AND IF THEY ARE, TAKE ON THEIR CURSE"}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
||||||
|
pub struct EmpathResultProps {
|
||||||
|
pub scapegoat: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn EmpathResult(EmpathResultProps { scapegoat }: &EmpathResultProps) -> Html {
|
||||||
|
let text = match scapegoat {
|
||||||
|
true => "THE SCAPEGOAT",
|
||||||
|
false => "NOT THE SCAPEGOAT",
|
||||||
|
};
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="intel">{"EMPATH"}</h1>
|
||||||
|
<div class="information intel faint">
|
||||||
|
<h2>{"YOUR TARGET IS"}</h2>
|
||||||
|
<h4>
|
||||||
|
<Icon
|
||||||
|
source={IconSource::Scapegoat}
|
||||||
|
icon_type={IconType::Informational}
|
||||||
|
inactive={scapegoat.not()}
|
||||||
|
/>
|
||||||
|
</h4>
|
||||||
|
<h3 class="yellow">{text}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
use convert_case::{Case, Casing};
|
||||||
|
use werewolves_proto::role::RoleTitle;
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::{Icon, IconSource, IconType, PartialAssociatedIcon};
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn GravediggerPage1() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="intel">{"GRAVEDIGGER"}</h1>
|
||||||
|
<div class="information intel faint">
|
||||||
|
<h2>
|
||||||
|
{"PICK A "}
|
||||||
|
<span class="yellow">{"DEAD"}</span>
|
||||||
|
{" PLAYER"}
|
||||||
|
</h2>
|
||||||
|
<div class="icons">
|
||||||
|
<Icon source={IconSource::Gravedigger} icon_type={IconType::Informational}/>
|
||||||
|
</div>
|
||||||
|
<h3 class="yellow">
|
||||||
|
{"YOU WILL LEARN THEIR ROLE"}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
||||||
|
pub struct GravediggerResultPageProps {
|
||||||
|
pub role: Option<RoleTitle>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn GravediggerResultPage(
|
||||||
|
GravediggerResultPageProps { role }: &GravediggerResultPageProps,
|
||||||
|
) -> Html {
|
||||||
|
let text = role
|
||||||
|
.as_ref()
|
||||||
|
.map(|r| {
|
||||||
|
html! {
|
||||||
|
<h4>
|
||||||
|
{"YOU DIG UP THE BODY OF A "}
|
||||||
|
<span class="yellow">
|
||||||
|
{r.to_string().to_case(Case::Upper)}
|
||||||
|
</span>
|
||||||
|
</h4>
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
html! {
|
||||||
|
<h4>{"BUT INSTEAD YOU FIND AN EMPTY GRAVE"}</h4>
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let icon = role
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|i| i.icon())
|
||||||
|
.unwrap_or(IconSource::Gravedigger);
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="intel">{"GRAVEDIGGER"}</h1>
|
||||||
|
<div class="information intel faint">
|
||||||
|
<h2>{"YOU CHECK THE ROLE OF YOUR TARGET"}</h2>
|
||||||
|
<h4>
|
||||||
|
<Icon
|
||||||
|
source={icon}
|
||||||
|
icon_type={IconType::Informational}
|
||||||
|
/>
|
||||||
|
</h4>
|
||||||
|
{text}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
use werewolves_proto::message::CharacterIdentity;
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::{CharacterTargetCard, Icon, IconSource, IconType};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||||
|
pub struct GuardianPageProps {
|
||||||
|
pub previous: CharacterIdentity,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn GuardianPageNoPrevProtect() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="defensive">{"GUARDIAN"}</h1>
|
||||||
|
<div class="information defensive faint">
|
||||||
|
<h2>{"PICK A PLAYER"}</h2>
|
||||||
|
<h4 class="icons">
|
||||||
|
<Icon source={IconSource::ShieldAndSword} icon_type={IconType::Informational}/>
|
||||||
|
</h4>
|
||||||
|
<h3 class="yellow">{"CHOOSE SOMEONE TO PROTECT FROM DEATH"}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn GuardianPagePreviousProtect1(GuardianPageProps { previous }: &GuardianPageProps) -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="defensive">{"GUARDIAN"}</h1>
|
||||||
|
<div class="information defensive faint">
|
||||||
|
<h2>{"LAST TIME YOU PROTECTED"}</h2>
|
||||||
|
<div class="info-player-list">
|
||||||
|
<CharacterTargetCard ident={previous.clone()} />
|
||||||
|
</div>
|
||||||
|
<h3 class="yellow">{"IF YOU PROTECT THEM AGAIN, YOU WILL INSTEAD GUARD THEM"}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn GuardianPagePreviousProtect2(GuardianPageProps { previous }: &GuardianPageProps) -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="defensive">{"GUARDIAN"}</h1>
|
||||||
|
<div class="information defensive faint">
|
||||||
|
<h2>{"LAST TIME YOU PROTECTED"}</h2>
|
||||||
|
<div class="info-player-list">
|
||||||
|
<CharacterTargetCard ident={previous.clone()} />
|
||||||
|
</div>
|
||||||
|
<h3 class="yellow">{"IF ATTACKED WHILE GUARDED, YOU AND THEIR ATTACKER WILL INSTEAD DIE"}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn GuardianPagePreviousGuard(GuardianPageProps { previous }: &GuardianPageProps) -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="defensive">{"GUARDIAN"}</h1>
|
||||||
|
<div class="information defensive faint">
|
||||||
|
<h2>{"LAST TIME YOU GUARDED"}</h2>
|
||||||
|
<div class="info-player-list">
|
||||||
|
<CharacterTargetCard ident={previous.clone()} />
|
||||||
|
</div>
|
||||||
|
<h4 class="icons">
|
||||||
|
<Icon source={IconSource::ShieldAndSword} icon_type={IconType::Informational}/>
|
||||||
|
</h4>
|
||||||
|
<h3 class="yellow">{"YOU CANNOT PROTECT THEM TONIGHT"}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn HunterPage1() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="offensive">{"HUNTER"}</h1>
|
||||||
|
<div class="information offensive faint">
|
||||||
|
<h2>{"SET A HUNTER'S TRAP ON A PLAYER"}</h2>
|
||||||
|
<div class="icons">
|
||||||
|
<Icon source={IconSource::Hunter} icon_type={IconType::Informational}/>
|
||||||
|
</div>
|
||||||
|
<h3 class="yellow">
|
||||||
|
{"IF YOU DIE TONIGHT, OR ARE EXECUTED TOMORROW"}
|
||||||
|
{"THIS PLAYER WILL DIE AT NIGHT AS WELL"}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
use werewolves_proto::message::night::Visits;
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::CharacterTargetCard;
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn InsomniacPage1() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="intel">{"INSOMNIAC"}</h1>
|
||||||
|
<div class="information intel faint">
|
||||||
|
<h2>{"YOUR POOR SLEEP RESULTS IN BEING WOKEN BY VISITORS IN THE NIGHT"}</h2>
|
||||||
|
<h3 class="yellow">
|
||||||
|
{"YOU WILL REMEMBER WHO VISITED YOU TONIGHT"}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||||
|
pub struct InsomniacResultProps {
|
||||||
|
pub visits: Visits,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn InsomniacResult(InsomniacResultProps { visits }: &InsomniacResultProps) -> Html {
|
||||||
|
let visitors = visits
|
||||||
|
.iter()
|
||||||
|
.map(|visitor| {
|
||||||
|
html! {
|
||||||
|
<CharacterTargetCard ident={visitor.clone()}/>
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Html>();
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="intel">{"INSOMNIAC"}</h1>
|
||||||
|
<div class="information intel faint">
|
||||||
|
<h2>{"YOU WERE VISITED IN THE NIGHT BY:"}</h2>
|
||||||
|
<div class="info-player-list">
|
||||||
|
{visitors}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
||||||
|
pub struct MapleWolfPage1Props {
|
||||||
|
pub starving: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn MapleWolfPage1(MapleWolfPage1Props { starving }: &MapleWolfPage1Props) -> Html {
|
||||||
|
let starving = starving
|
||||||
|
.then_some(html! {
|
||||||
|
<>
|
||||||
|
<h3 class="red">{"YOU ARE STARVING"}</h3>
|
||||||
|
<h3>{"IF YOU FAIL TO EAT TONIGHT, YOU WILL DIE"}</h3>
|
||||||
|
</>
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
html! {
|
||||||
|
<h3>
|
||||||
|
{"IF YOU DON'T EAT FOR TOO LONG, YOU WILL "}
|
||||||
|
<span class="red">{"STARVE"}</span>
|
||||||
|
</h3>
|
||||||
|
}
|
||||||
|
});
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="offensive">{"MAPLE WOLF"}</h1>
|
||||||
|
<div class="information offensive faint">
|
||||||
|
<h2>
|
||||||
|
{"YOU CAN CHOOSE TO EAT A PLAYER TONIGHT"}
|
||||||
|
</h2>
|
||||||
|
<div class="icons">
|
||||||
|
<Icon source={IconSource::MapleWolf} icon_type={IconType::Informational}/>
|
||||||
|
</div>
|
||||||
|
{starving}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
use core::num::NonZeroU8;
|
||||||
|
|
||||||
|
use werewolves_proto::message::CharacterIdentity;
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::CharacterTargetCard;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
||||||
|
pub struct MasonRecruitPage1Props {
|
||||||
|
pub recruits_left: NonZeroU8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn MasonRecruitPage1(
|
||||||
|
MasonRecruitPage1Props { recruits_left }: &MasonRecruitPage1Props,
|
||||||
|
) -> Html {
|
||||||
|
let recruitments = match recruits_left.get() {
|
||||||
|
0 => unreachable!(),
|
||||||
|
1 => html! {
|
||||||
|
<>
|
||||||
|
<span class="yellow">{1}</span>
|
||||||
|
{" RECRUITMENT"}
|
||||||
|
</>
|
||||||
|
},
|
||||||
|
num => html! {
|
||||||
|
<>
|
||||||
|
<span class="yellow">{num}</span>
|
||||||
|
{" RECRUITMENTS"}
|
||||||
|
</>
|
||||||
|
},
|
||||||
|
};
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="intel">{"MASON LEADER"}</h1>
|
||||||
|
<div class="information intel faint">
|
||||||
|
<h2>{"YOU HAVE "}{recruitments}{" LEFT"}</h2>
|
||||||
|
<h4>
|
||||||
|
{"ANYONE YOU RECRUIT INTO THE MASONS WILL WAKE WITH YOU "}
|
||||||
|
<span class="yellow">{"EVERY NIGHT"}</span>
|
||||||
|
{", AS LONG AS THEY ARE ALIVE AND REMAIN VILLAGE ALIGNED"}
|
||||||
|
</h4>
|
||||||
|
<h3 class="yellow">{"WOULD YOU LIKE TO RECRUIT TONIGHT?"}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Properties)]
|
||||||
|
pub struct MasonsWakeProps {
|
||||||
|
pub leader: CharacterIdentity,
|
||||||
|
pub masons: Box<[CharacterIdentity]>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn MasonsWake(MasonsWakeProps { leader, masons }: &MasonsWakeProps) -> Html {
|
||||||
|
let title = html! {
|
||||||
|
<>
|
||||||
|
{"MASONS OF "}
|
||||||
|
<span class="yellow">{leader.name.clone()}</span>
|
||||||
|
</>
|
||||||
|
};
|
||||||
|
let masons = masons
|
||||||
|
.iter()
|
||||||
|
.map(|mason| {
|
||||||
|
html! {
|
||||||
|
<CharacterTargetCard ident={mason.clone()}/>
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Html>();
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="intel">{title}</h1>
|
||||||
|
<div class="information intel faint">
|
||||||
|
<h2>{"YOU ARE ALL MEMBERS "}</h2>
|
||||||
|
<div class="info-player-list masons">
|
||||||
|
{masons}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn MilitiaPage1() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="offensive">{"MILITIA"}</h1>
|
||||||
|
<div class="information offensive faint">
|
||||||
|
<h2>
|
||||||
|
{"IF YOU WISH TO USE YOUR "}
|
||||||
|
<span class="yellow">{"ONCE PER GAME"}</span>
|
||||||
|
{" KILL ABILITY"}
|
||||||
|
</h2>
|
||||||
|
<div class="icons">
|
||||||
|
<Icon source={IconSource::Sword} icon_type={IconType::Informational}/>
|
||||||
|
</div>
|
||||||
|
<h3 class="yellow">
|
||||||
|
{"POINT AT YOUR TARGET "}
|
||||||
|
{"OR GO BACK TO SLEEP"}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
use werewolves_proto::diedto::DiedToTitle;
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::{Icon, IconSource, IconType, PartialAssociatedIcon};
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn MorticianPage1() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="intel">{"MORTICIAN"}</h1>
|
||||||
|
<div class="information intel faint">
|
||||||
|
<h2>
|
||||||
|
{"PICK A "}
|
||||||
|
<span class="yellow">{"DEAD"}</span>
|
||||||
|
{" PLAYER"}
|
||||||
|
</h2>
|
||||||
|
<div class="icons">
|
||||||
|
<Icon source={IconSource::Mortician} icon_type={IconType::Informational}/>
|
||||||
|
</div>
|
||||||
|
<h3 class="yellow">
|
||||||
|
{"YOU WILL LEARN THE CAUSE "}
|
||||||
|
{"OF THEIR DEATH"}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
||||||
|
pub struct MorticianResultPageProps {
|
||||||
|
pub died_to: DiedToTitle,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn MorticianResultPage(
|
||||||
|
MorticianResultPageProps { died_to }: &MorticianResultPageProps,
|
||||||
|
) -> Html {
|
||||||
|
let text = match died_to {
|
||||||
|
DiedToTitle::Execution => "Execution",
|
||||||
|
DiedToTitle::MapleWolf => "Maple Wolf",
|
||||||
|
DiedToTitle::MapleWolfStarved => "Starvation",
|
||||||
|
DiedToTitle::Militia => "Militia Shot",
|
||||||
|
DiedToTitle::Wolfpack => "Wolfpack",
|
||||||
|
DiedToTitle::AlphaWolf => "Alpha Wolf",
|
||||||
|
DiedToTitle::Shapeshift => "Shapeshifting",
|
||||||
|
DiedToTitle::Hunter => "Hunter Trap",
|
||||||
|
DiedToTitle::GuardianProtecting => "Guardian",
|
||||||
|
DiedToTitle::PyreMaster => "Pyre Master",
|
||||||
|
DiedToTitle::PyreMasterLynchMob => "An Angry Mob of Villagers Against Fire",
|
||||||
|
DiedToTitle::MasonLeaderRecruitFail => "Occupational Hazard (Mason Recruit Fail)",
|
||||||
|
DiedToTitle::LoneWolf => "Lone Wolf",
|
||||||
|
};
|
||||||
|
let icon = died_to.icon().unwrap_or(IconSource::Mortician);
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="intel">{"MORTICIAN"}</h1>
|
||||||
|
<div class="information intel faint">
|
||||||
|
<h2>{"YOUR TARGET DIED TO"}</h2>
|
||||||
|
<h4>
|
||||||
|
<Icon
|
||||||
|
source={icon}
|
||||||
|
icon_type={IconType::Informational}
|
||||||
|
/>
|
||||||
|
</h4>
|
||||||
|
<h3 class="yellow">{text}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
use core::ops::Not;
|
||||||
|
|
||||||
|
use werewolves_proto::role::Powerful;
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::{AssociatedIcon, Icon, IconSource, IconType};
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn PowerSeerPage1() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="intel">{"POWER SEER"}</h1>
|
||||||
|
<div class="information intel faint">
|
||||||
|
<h2>{"PICK A PLAYER"}</h2>
|
||||||
|
<h4 class="icons">
|
||||||
|
<Icon source={IconSource::Powerful} icon_type={IconType::Informational}/>
|
||||||
|
<Icon source={IconSource::Powerful} icon_type={IconType::Informational} inactive={true}/>
|
||||||
|
</h4>
|
||||||
|
<h3 class="yellow">{"YOU WILL CHECK IF THEY ARE POWERFUL"}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
||||||
|
pub struct PowerSeerResultProps {
|
||||||
|
pub powerful: Powerful,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn PowerSeerResult(PowerSeerResultProps { powerful }: &PowerSeerResultProps) -> Html {
|
||||||
|
let text = match powerful {
|
||||||
|
Powerful::Powerful => "POWERFUL",
|
||||||
|
Powerful::NotPowerful => "NOT POWERFUL",
|
||||||
|
};
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="intel">{"POWER SEER"}</h1>
|
||||||
|
<div class="information intel faint">
|
||||||
|
<h2>{"YOUR TARGET APPEARS AS"}</h2>
|
||||||
|
<h4>
|
||||||
|
<Icon
|
||||||
|
source={powerful.icon()}
|
||||||
|
icon_type={IconType::Informational}
|
||||||
|
inactive={powerful.powerful().not()}
|
||||||
|
/>
|
||||||
|
</h4>
|
||||||
|
<h3 class="yellow">{text}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn ProtectorPage1() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="defensive">{"PROTECTOR"}</h1>
|
||||||
|
<div class="information defensive faint">
|
||||||
|
<h2>{"PICK A PLAYER"}</h2>
|
||||||
|
<h4 class="icons">
|
||||||
|
<Icon source={IconSource::Shield} icon_type={IconType::Informational}/>
|
||||||
|
</h4>
|
||||||
|
<h3 class="yellow">{"YOU WILL PROTECT THEM FROM A DEATH TONIGHT"}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn PyremasterPage1() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="offensive">{"PYREMASTER"}</h1>
|
||||||
|
<div class="information offensive faint">
|
||||||
|
<h2>{"IF YOU WISH TO THROW A PLAYER ON THE PYRE"}</h2>
|
||||||
|
<div class="icons">
|
||||||
|
<Icon source={IconSource::Pyremaster} icon_type={IconType::Informational}/>
|
||||||
|
</div>
|
||||||
|
<h3 class="yellow">
|
||||||
|
{"IF YOU KILL TWO GOOD VILLAGERS LIKE THIS "}
|
||||||
|
{"YOU WILL DIE AS WELL"}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
use werewolves_proto::role::Alignment;
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::{AssociatedIcon, Icon, IconSource, IconType};
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn SeerPage1() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="intel">{"SEER"}</h1>
|
||||||
|
<div class="information intel faint">
|
||||||
|
<h2>{"PICK A PLAYER"}</h2>
|
||||||
|
<h4 class="icons">
|
||||||
|
<Icon source={IconSource::Village} icon_type={IconType::Informational}/>
|
||||||
|
<Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
||||||
|
</h4>
|
||||||
|
<h3 class="yellow">{"YOU WILL CHECK IF THEY APPEAR AS A VILLAGER OR PART OF THE WOLFPACK"}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Properties)]
|
||||||
|
pub struct SeerResultProps {
|
||||||
|
pub alignment: Alignment,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn SeerResult(SeerResultProps { alignment }: &SeerResultProps) -> Html {
|
||||||
|
let text = match alignment {
|
||||||
|
Alignment::Village => "VILLAGE",
|
||||||
|
Alignment::Wolves => "WOLFPACK",
|
||||||
|
};
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="intel">{"SEER"}</h1>
|
||||||
|
<div class="information intel faint">
|
||||||
|
<h2>{"YOUR TARGET APPEARS AS"}</h2>
|
||||||
|
<h4>
|
||||||
|
<Icon
|
||||||
|
source={alignment.icon()}
|
||||||
|
icon_type={IconType::Informational}
|
||||||
|
/>
|
||||||
|
</h4>
|
||||||
|
<h3 class="yellow">{text}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn VindicatorPage1() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="defensive">{"VINDICATOR"}</h1>
|
||||||
|
<div class="information defensive faint">
|
||||||
|
<h3>{"A VILLAGER WAS EXECUTED"}</h3>
|
||||||
|
<h2>{"PICK A PLAYER"}</h2>
|
||||||
|
<h4 class="icons">
|
||||||
|
<Icon source={IconSource::Shield} icon_type={IconType::Informational}/>
|
||||||
|
</h4>
|
||||||
|
<h3 class="yellow">{"YOU WILL PROTECT THEM FROM A DEATH TONIGHT"}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::{Icon, IconSource, IconType};
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn RoleblockPage() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="wolves">{"ROLE BLOCKED"}</h1>
|
||||||
|
<div class="information wolves faint">
|
||||||
|
<h2>{"YOU WERE ROLE BLOCKED"}</h2>
|
||||||
|
<h4 class="icons">
|
||||||
|
<Icon source={IconSource::Roleblock} icon_type={IconType::Informational}/>
|
||||||
|
</h4>
|
||||||
|
<h3 class="yellow">{"YOUR NIGHT ACTION DID NOT TAKE PLACE"}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
use core::ops::Not;
|
||||||
|
|
||||||
|
use werewolves_proto::role::Powerful;
|
||||||
|
use yew::prelude::*;
|
||||||
|
|
||||||
|
use crate::components::{AssociatedIcon, Icon, IconSource, IconType};
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
pub fn WolfpackKillPage() -> Html {
|
||||||
|
html! {
|
||||||
|
<div class="role-page">
|
||||||
|
<h1 class="wolves">{"WOLF PACK KILL"}</h1>
|
||||||
|
<div class="information wolves faint">
|
||||||
|
<h2>{"CHOOSE A TARGET TO EAT TONIGHT"}</h2>
|
||||||
|
<h4 class="icons">
|
||||||
|
<Icon source={IconSource::Wolves} icon_type={IconType::Informational}/>
|
||||||
|
</h4>
|
||||||
|
<h3 class="yellow">{"WOLVES MUST BE UNANIMOUS"}</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||