From ab98318a653160f5014e97473e4a1b9b8fa97639 Mon Sep 17 00:00:00 2001 From: Sam Maselli Date: Fri, 3 Jan 2025 15:47:35 -0500 Subject: [PATCH] puppeteer rework, no poison --- client/src/resources/lang/en_us.json | 10 +++---- client/src/resources/roles.json | 2 +- server/src/game/role/apostle.rs | 2 +- server/src/game/role/puppeteer.rs | 42 +++++++++++----------------- 4 files changed, 24 insertions(+), 32 deletions(-) diff --git a/client/src/resources/lang/en_us.json b/client/src/resources/lang/en_us.json index f1af72b89..c5a1dc7f2 100644 --- a/client/src/resources/lang/en_us.json +++ b/client/src/resources/lang/en_us.json @@ -499,7 +499,7 @@ "role.puppeteer.smallRoleMenu.marionettesRemaining": "\\0 marionettes remaining.", "role.puppeteer.smallRoleMenu": "Tonight you will \\0.", "controllerId.role.puppeteer.1.name": "Choose Ability", - "controllerId.role.puppeteer.1.integer.0": "Poison", + "controllerId.role.puppeteer.1.integer.0": "Kill", "controllerId.role.puppeteer.1.integer.1": "Marionette", "role.kira.name": "Kira", @@ -1786,10 +1786,10 @@ "wiki.article.role.ojo.attributes":"- If you are dead, you cant select to use your ability\n* If you are blocked, you have no ability\n* Your attack is an armor-piercing attack\n* You can't attack anybody on night 1", "wiki.article.role.ojo.extra":"- Your attack ability works on the person you actually visited, so if a transporter transports a player you visit with someone else, you attack the other player, this only applies to the attack ability, not any other ability of yours\n- You wont visit dead players using your attack ability\n- You are immune to possession, but not wardblocks or roleblocks", - "wiki.article.role.puppeteer.reminder": "Each night, select a player to either poison them or recruit them.", - "wiki.article.role.puppeteer.guide":"- You may choose to do one of the following\n - Select and poison a player\n - They are told they are poisoned, and then they are attacked the next night\n\n - Select a player to string up into a marionette\n - They are told they are strung up, and that they will win with fiends, regardless of their role\n - They attacked the following night, and every night until they die\n - They should try their hardest to help you and should NOT say they were strung up\n - At night all puppeteers and marionettes can chat in the puppeteer chat, even if dead\n - The players in the puppeteer chat that are dead can chat during the day or night", - "wiki.article.role.puppeteer.abilities":"- You may choose to do one of the following\n - Visit a player to poison them\n - They are told they are poisoned\n - They are indirectly hit with an armor-piercing attack on the following night\n\n - Visit a player to string up into a marionette\n - They are told they are strung up, and they now win with fiends, regardless of their role\n - They will be indirectly hit with a protection-piercing attack every night by all puppeteers until they die, if there are no puppeteers they are still attacked\n - You can only use this X times (X = Total players ÷ 5 (round up))", - "wiki.article.role.puppeteer.attributes":"- You and the marionettes are all puppeteer insiders\n- Stringing someone up is armor-piercing, if a player has higher defense than armor when you attempt to string them up, they are instead poisoned\n - At night all puppeteers and marionettes can chat in the puppeteer chat, even if dead\n - The players in the puppeteer chat that are dead can chat during the day or night", + "wiki.article.role.puppeteer.reminder": "Each night, select a player to either kill them or recruit them.", + "wiki.article.role.puppeteer.guide":"- You may choose to do one of the following\n - Select and attack a player\n - Select a player to string up into a marionette\n - They are told they are strung up, and are now a fiends loyalist\n - They are attacked the following night, and every night until they die\n - At night all puppeteers and marionettes can chat in the puppeteer chat, even if dead\n - The players in the puppeteer chat that are dead can chat during the day or night\n- Your attack and convert are both armor-piercing", + "wiki.article.role.puppeteer.abilities":"- You may choose to do one of the following\n - Visit a player to attack them\n - Visit a player to string up into a marionette\n - They are told they are strung up, and are now a fiends loyalist\n - They are indirectly attacked (protection-piercing) every night by all puppeteers until they die, if there are no puppeteers they are still attacked\n - You can only use this X times (X = Total players ÷ 5 (round up))\n- Your attack and convert are both armor-piercing", + "wiki.article.role.puppeteer.attributes":"- You and the marionettes are all puppeteer insiders\n- Stringing someone up is armor-piercing\n - At night all puppeteers and marionettes can chat in the puppeteer chat, even if dead\n - The players in the puppeteer chat that are dead can chat during the day or night", "wiki.article.role.puppeteer.extra":"- You can't select anybody who is a puppeteer, marionette, or is being strung into a marionette\n- A puppeteer can't be stringed into a marionette\n- A marionette can't be stringed into a marionette twice, if 2 puppeteers choose a player to be turned into a marionette on the same night, they get the message only once", "wiki.article.role.kira.reminder": "Each night, guess players roles, if all your guesses are correct, you attack all of the players you guessed.", diff --git a/client/src/resources/roles.json b/client/src/resources/roles.json index 04b990a4b..f0eaf6bf3 100644 --- a/client/src/resources/roles.json +++ b/client/src/resources/roles.json @@ -1090,7 +1090,7 @@ "canBeConvertedTo": [], "chatMessages":[ {"type": "puppeteerPlayerIsNowMarionette","player": 32}, - {"type": "youArePoisoned"}, + {"type": "yourConvertFailed"}, { "type": "normal", "messageSender": { diff --git a/server/src/game/role/apostle.rs b/server/src/game/role/apostle.rs index ef792f879..84e8fd289 100644 --- a/server/src/game/role/apostle.rs +++ b/server/src/game/role/apostle.rs @@ -64,7 +64,7 @@ impl RoleStateImpl for Apostle { game, actor_ref, ControllerID::role(actor_ref, Role::Apostle, 0), - Cult::next_ability(game) == CultAbility::Kill + true ) } fn controller_parameters_map(self, game: &Game, actor_ref: PlayerReference) -> super::ControllerParametersMap { diff --git a/server/src/game/role/puppeteer.rs b/server/src/game/role/puppeteer.rs index 31b4658c0..4eb78d3ef 100644 --- a/server/src/game/role/puppeteer.rs +++ b/server/src/game/role/puppeteer.rs @@ -2,8 +2,10 @@ use serde::Serialize; use crate::game::attack_power::AttackPower; use crate::game::components::detained::Detained; -use crate::game::components::poison::{Poison, PoisonAlert}; -use crate::game::{attack_power::DefensePower, components::puppeteer_marionette::PuppeteerMarionette}; +use crate::game::{ + attack_power::DefensePower, + components::puppeteer_marionette::PuppeteerMarionette +}; use crate::game::player::PlayerReference; use crate::game::visit::Visit; @@ -20,13 +22,10 @@ pub struct Puppeteer{ impl Default for Puppeteer{ fn default() -> Self { - Self { - marionettes_remaining: 3, - } + Self {marionettes_remaining: 3,} } } - pub(super) const MAXIMUM_COUNT: Option = None; pub(super) const DEFENSE: DefensePower = DefensePower::Armor; @@ -39,8 +38,7 @@ impl RoleStateImpl for Puppeteer { } } fn do_night_action(mut self, game: &mut Game, actor_ref: PlayerReference, priority: Priority) { - if priority != Priority::Poison {return;} - + if priority != Priority::Kill {return;} let actor_visits = actor_ref.untagged_night_visits_cloned(game); if let Some(visit) = actor_visits.first(){ @@ -49,30 +47,24 @@ impl RoleStateImpl for Puppeteer { if game.saved_controllers.get_controller_current_selection_integer( ControllerID::role(actor_ref, Role::Puppeteer, 1) ).unwrap_or(IntegerSelection(0)).0 == 1 { - if AttackPower::ArmorPiercing.can_pierce(target.defense(game)) { + if !AttackPower::ArmorPiercing.can_pierce(target.defense(game)) { + actor_ref.push_night_message(game, crate::game::chat::ChatMessageVariant::YourConvertFailed); + }else{ if PuppeteerMarionette::string(game, target){ - self.marionettes_remaining -= 1; + self.marionettes_remaining = self.marionettes_remaining.saturating_sub(1); } actor_ref.set_role_state(game, RoleState::Puppeteer(self)); - }else{ - Poison::poison_player(game, - target, AttackPower::ArmorPiercing, - crate::game::grave::GraveKiller::Role(Role::Puppeteer), - vec![actor_ref].into_iter().collect(), true, - PoisonAlert::Alert, - ); } }else{ - Poison::poison_player(game, - target, AttackPower::ArmorPiercing, - crate::game::grave::GraveKiller::Role(Role::Puppeteer), - vec![actor_ref].into_iter().collect(), true, - PoisonAlert::Alert, + actor_ref.try_night_kill_single_attacker( + actor_ref, + game, + crate::game::grave::GraveKiller::Role(Role::Puppeteer), + AttackPower::ArmorPiercing, + true ); } } - - } fn controller_parameters_map(self, game: &Game, actor_ref: PlayerReference) -> super::ControllerParametersMap { ControllerParametersMap::new_controller_fast( @@ -114,7 +106,7 @@ impl RoleStateImpl for Puppeteer { game, actor_ref, ControllerID::role(actor_ref, Role::Puppeteer, 0), - false, + true, ) } fn default_revealed_groups(self) -> crate::vec_set::VecSet {