Skip to content

Fix Santa #750

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Dec 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions client/src/resources/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -1581,14 +1581,14 @@
"wiki.article.role.mafioso.extra":"* You can't target other syndicate members",

"wiki.article.role.santaClaus.reminder": "Add players to the nice and naughty lists. You win when only nice players remain alive.",
"wiki.article.role.santaClaus.guide": "On odd nights: Select up to two people to add to the nice list\n* This player retains their original win condition and gains the Nice List win condition.\n* Players on the nice list cannot be put on the naughty list.\n\nOn even nights: Select two players to add to the naughty list\n* These players retain their original win conditions, and gain the Naughty List win condition.\n* Players on the Naughty list cannot be put on the nice list.",
"wiki.article.role.santaClaus.abilities":"On odd nights: Select up to two people to add to the nice list\n* This player retains their original win condition and gains the Nice List win condition.\n* Players on the nice list cannot be put on the naughty list.\n\nOn even nights: Select two players to add to the naughty list\n* These players retain their original win conditions, and gain the Naughty List win condition.\n* Players on the Naughty list cannot be put on the nice list.",
"wiki.article.role.santaClaus.attributes":"* You are a nice list loyalist\n* You are roleblock immune.\n* You are wardblock immune.\n* You have innocent aura.\n* You are not told whether you were successful in adding your target to the list.",
"wiki.article.role.santaClaus.guide": "On odd nights: Select zero or one players to add to the nice list\n* This player retains their original win condition and gains the Nice List win condition.\n* Players on the nice list cannot be put on the naughty list.\n\nOn even nights: Select one player to add to the naughty list\n* This player retains their original win condition, and gains the Naughty List win condition.\n* Players on the Naughty list cannot be put on the nice list.",
"wiki.article.role.santaClaus.abilities":"- None",
"wiki.article.role.santaClaus.attributes":"* If you don't select a player to put on the naughty list, you visit a random player to be put on the naughty list.\n* You are a nice list loyalist\n* You are roleblock immune.\n* You are wardblock immune.\n* You have innocent aura.\n* You are not told whether you were successful in adding your target to the list.\n- You can't visit due to your own ability while dead, even if possessed.",
"wiki.article.role.santaClaus.extra":"* You can't add a player to both lists.\n* Visiting a player with independent win condition does nothing.",

"wiki.article.role.krampus.reminder": "Each night, investigate a player's role and win condition. Every odd night, select a player to attack them.",
"wiki.article.role.krampus.guide": "- At night select a player to investigate them. You learn the role and win condition of your target.\n- On odd nights, you attack your target.",
"wiki.article.role.krampus.abilities": "- At night select a player to investigate them. You learn the role and win condition of your target.\n- On odd nights, you attack your target.",
"wiki.article.role.krampus.abilities": "- None",
"wiki.article.role.krampus.attributes":"* You are a naughty list loyalist\n* You have a basic attack",
"wiki.article.role.krampus.extra":"* You can leave a death note. This is a good way to communicate with your fellow naughty-listers.\n* If Krampus and Santa Claus are the only remaining roles, they both die and the game ends in a draw.\n* Visiting a player with independent win condition does nothing.",

Expand Down
1 change: 1 addition & 0 deletions server/src/game/role/jester.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ impl RoleStateImpl for Jester {
Detained::is_detained(game, actor_ref) ||
!self.lynched_yesterday;

// Note: Sam, when you fix this, don't forget to fix Santa Claus in the same manner
ControllerParametersMap::new_controller_fast(
game,
ControllerID::role(actor_ref, Role::Jester, 0),
Expand Down
4 changes: 2 additions & 2 deletions server/src/game/role/krampus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ pub struct Krampus {
#[derive(Debug, Clone, Copy, Serialize, Default, PartialEq, Eq, PartialOrd, Ord)]
#[serde(rename_all = "camelCase")]
pub enum KrampusAbility {
DoNothing,
#[default] Kill
#[default] DoNothing,
Kill
}

pub(super) const MAXIMUM_COUNT: Option<u8> = None;
Expand Down
11 changes: 8 additions & 3 deletions server/src/game/role/santa_claus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ impl RoleStateImpl for SantaClaus {
super::AvailableAbilitySelection::new_player_list(
get_selectable_players(game, actor_ref),
false,
Some(2)
Some(1)
),
AbilitySelection::new_player_list(vec![]),
Detained::is_detained(game, actor_ref) || !actor_ref.alive(game),
Expand All @@ -122,7 +122,7 @@ impl RoleStateImpl for SantaClaus {
super::AvailableAbilitySelection::new_player_list(
get_selectable_players(game, actor_ref),
false,
Some(2)
Some(1)
),
AbilitySelection::new_player_list(vec![]),
Detained::is_detained(game, actor_ref) || !actor_ref.alive(game),
Expand All @@ -134,6 +134,11 @@ impl RoleStateImpl for SantaClaus {
}
}
fn convert_selection_to_visits(self, game: &Game, actor_ref: PlayerReference) -> Vec<Visit> {
// Note: Sam, fix this when you fix jester
if !actor_ref.alive(game) {
return vec![];
}

match self.next_ability {
SantaListKind::Nice => {
crate::game::role::common_role::convert_controller_selection_to_visits(
Expand Down Expand Up @@ -164,7 +169,7 @@ impl RoleStateImpl for SantaClaus {

let mut targets: Vec<PlayerReference> = eligible_targets.into_iter().chain(eligible_options).collect();

targets.truncate(2);
targets.truncate(1);

targets.into_iter()
.map(|target| Visit::new(actor_ref, target, false, VisitTag::Role))
Expand Down
46 changes: 22 additions & 24 deletions server/tests/role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2470,9 +2470,7 @@ fn santa_cannot_convert_naughty_player() {
kit::scenario!(game in Night 1 where
santa: SantaClaus,
nice: Villager,
nice2: Villager,
naughty: Villager,
naughty2: Villager
naughty: Villager
);
santa.send_ability_input_player_list_typical(nice);

Expand All @@ -2486,7 +2484,7 @@ fn santa_cannot_convert_naughty_player() {
assert_contains!(santa.get_messages_after_night(2),
ChatMessageVariant::NextSantaAbility { ability: mafia_server::game::role::santa_claus::SantaListKind::Naughty }
);
santa.send_ability_input_player_list([naughty, naughty2], 1);
santa.send_ability_input_player_list(naughty, 1);

game.skip_to(Night, 3);

Expand All @@ -2495,15 +2493,10 @@ fn santa_cannot_convert_naughty_player() {
GameConclusion::NaughtyList
);

santa.send_ability_input_player_list_typical([naughty, nice2]);
santa.send_ability_input_player_list_typical(naughty);

game.skip_to(Obituary, 4);

assert_contains!(
nice2.player_ref().win_condition(&*game).required_resolution_states_for_win().unwrap(),
GameConclusion::NiceList
);

assert_contains!(
naughty.player_ref().win_condition(&*game).required_resolution_states_for_win().unwrap(),
GameConclusion::NaughtyList
Expand All @@ -2530,35 +2523,40 @@ fn krampus_obeys_ability_order() {
assert_contains!(krampus.get_messages_after_night(night), ChatMessageVariant::NextKrampusAbility { ability });
};

expect_ability(1, KrampusAbility::Kill);
expect_ability(1, KrampusAbility::DoNothing);
krampus.send_ability_input_player_list_typical(town2);

game.skip_to(Night, 2);

expect_ability(2, KrampusAbility::Kill);
krampus.send_ability_input_player_list_typical(town1);

assert_not_contains!(town2.get_messages_after_night(2), ChatMessageVariant::YouDied);
game.skip_to(Obituary, 2);
assert_not_contains!(town2.get_messages_after_night(3), ChatMessageVariant::YouDied);
game.skip_to(Obituary, 3);
assert!(!town1.alive());

game.skip_to(Night, 2);
expect_ability(2, KrampusAbility::DoNothing);
game.skip_to(Night, 3);
expect_ability(3, KrampusAbility::DoNothing);
krampus.send_ability_input_player_list_typical(town2);

game.skip_to(Obituary, 3);
game.skip_to(Obituary, 4);
assert!(town2.alive());

game.skip_to(Night, 3);
expect_ability(3, KrampusAbility::Kill);

game.skip_to(Night, 4);
expect_ability(4, KrampusAbility::Kill);

game.skip_to(Night, 5);
expect_ability(5, KrampusAbility::Kill);
krampus.send_ability_input_player_list_typical(town3);

game.skip_to(Obituary, 5);
game.skip_to(Obituary, 6);
assert!(!town3.alive());

game.skip_to(Night, 5);
expect_ability(5, KrampusAbility::DoNothing);

game.skip_to(Night, 6);
expect_ability(6, KrampusAbility::Kill);
expect_ability(6, KrampusAbility::DoNothing);

game.skip_to(Night, 7);
expect_ability(7, KrampusAbility::Kill);
}

#[test]
Expand Down
Loading