Skip to content

Commit

Permalink
feat(GameOptions): Number of charmed people per night by Pied Piper o…
Browse files Browse the repository at this point in the history
…ption. Closes #174
  • Loading branch information
antoinezanardi committed Apr 27, 2021
1 parent 282498d commit 7961220
Show file tree
Hide file tree
Showing 11 changed files with 36 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* [#170](https://github.com/antoinezanardi/werewolves-assistant-web/issues/170) - Dog Wolf chosen side is revealed option.
* [#171](https://github.com/antoinezanardi/werewolves-assistant-web/issues/171) - Big Bad Wolf not powerless if one werewolf dies option.
* [#173](https://github.com/antoinezanardi/werewolves-assistant-web/issues/173) - White Werewolf waking up interval option.
* [#174](https://github.com/antoinezanardi/werewolves-assistant-web/issues/174) - Number of charmed people per night by Pied Piper option.
* [#183](https://github.com/antoinezanardi/werewolves-assistant-web/issues/183) - Audio options in parameters modal.
* [#188](https://github.com/antoinezanardi/werewolves-assistant-web/issues/188) - Modal for helping players with roles.

Expand Down
7 changes: 5 additions & 2 deletions src/classes/Game.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,11 +277,14 @@ class Game {
}

get expectedTargetsLength() {
const { to } = this.firstWaiting;
const { to, for: source } = this.firstWaiting;
const oneTargetActions = ["look", "eat", "protect", "shoot", "settle-votes", "delegate", "choose-model", "use-potion", "sniff"];
const twoTargetsActions = ["charm"];
const noLimitActions = ["ban-voting"];
if (oneTargetActions.includes(to) || to === "charm" && this.piedPiperTargets.length === 1) {
if (source === "pied-piper") {
const { charmedPeopleCountPerNight } = this.options.roles.piedPiper;
return this.piedPiperTargets.length < charmedPeopleCountPerNight ? this.piedPiperTargets.length : charmedPeopleCountPerNight;
} else if (oneTargetActions.includes(to)) {
return 1;
} else if (twoTargetsActions.includes(to)) {
return 2;
Expand Down
2 changes: 1 addition & 1 deletion src/components/Game/GameContent/GameContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export default {
} else if (target.attribute === "drank-death-potion") {
target.hasDrankDeathPotion = true;
}
const maxTargetLength = maxTargetLengthForPlayerAttribute(payload.attribute);
const maxTargetLength = maxTargetLengthForPlayerAttribute(payload.attribute, this.game);
const targetIdx = this.play.targets.findIndex(({ player }) => player === target.player);
if (!payload.selected) {
if (targetIdx !== -1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,8 +424,9 @@ export default {
charm: [
{ header, target: "#game-waiting-label", content: this.$t(`${actionStepsTextPath}.piedPiperCharmsWhen`) },
{ header, target: "#player-targets", content: this.$t(`${actionStepsTextPath}.piedPiperCanCharm`) },
{ header, target: "#player-targets", content: this.$t(`${actionStepsTextPath}.gameMasterTouchBackToCharmedPeople`) },
{ header, target: "#player-targets", content: this.$t(`${actionStepsTextPath}.ifAllAreCharmed`) },
...insertIf(!!game.vileFatherOfWolvesPlayer, {
...insertIf(!!game.vileFatherOfWolvesPlayer && game.options.roles.piedPiper.isPowerlessIfInfected, {
header, target: "#pied-piper-player",
content: this.$t(`${actionStepsTextPath}.ifPiedPiperIsInfected`),
}),
Expand Down
8 changes: 5 additions & 3 deletions src/components/Game/GameEventMonitor/GameEvent/GameEvent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -371,16 +371,18 @@ export default {
};
},
gameEventPiedPiperTurnMetadata() {
const { charmedPeopleCountPerNight } = this.gameOptions.roles.piedPiper;
return {
messages: [i18n.t("GameEvent.messages.piedPiperStarts")],
messages: [i18n.tc("GameEvent.messages.piedPiperStarts", charmedPeopleCountPerNight, { charmedPeopleCountPerNight })],
soundEffect: "pied-piper-plays",
};
},
gameEventPiedPiperCharmsMetadata() {
const { charmedPeopleCountPerNight } = this.gameOptions.roles.piedPiper;
return {
messages: [
i18n.t("GameEvent.messages.piedPiperCharmedTwoPlayers"),
i18n.t("GameEvent.messages.gameMasterWillTouchCharmed"),
i18n.tc("GameEvent.messages.piedPiperCharmedTwoPlayers", charmedPeopleCountPerNight, { charmedPeopleCountPerNight }),
i18n.tc("GameEvent.messages.gameMasterWillTouchCharmed", charmedPeopleCountPerNight, { charmedPeopleCountPerNight }),
],
soundEffect: "pied-piper-plays",
};
Expand Down
6 changes: 3 additions & 3 deletions src/components/shared/Game/GamePlayAlerts/GamePlayAlerts.vue
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export default {
return !!angelPlayer && angelPlayer.isAliveAndPowerful && doesAngelWinIfHeDiesNow ? ["angel-will-win-if-he-dies"] : [];
},
eatAlerts() {
const { firstWaiting, guardPlayer, ancientPlayer, witchPlayer, vileFatherOfWolvesPlayer, piedPiperPlayer } = this.game;
const { firstWaiting, guardPlayer, ancientPlayer, witchPlayer, vileFatherOfWolvesPlayer, piedPiperPlayer, options } = this.game;
const { to: action, for: source } = firstWaiting;
if (action !== "eat") {
return [];
Expand All @@ -92,8 +92,8 @@ export default {
...insertIf(source !== "white-werewolf" && !!witchPlayer && witchPlayer.isAliveAndPowerful, "witch-can-protect-target"),
...insertIf(source === "werewolves" && !!vileFatherOfWolvesPlayer && vileFatherOfWolvesPlayer.isAlive,
"vile-father-of-wolves-can-infect"),
...insertIf(source === "werewolves" && !!vileFatherOfWolvesPlayer && vileFatherOfWolvesPlayer.isAlive &&
!!piedPiperPlayer && piedPiperPlayer.isAliveAndPowerful, "pied-piper-will-loose-powers-if-infected"),
...insertIf(source === "werewolves" && !!vileFatherOfWolvesPlayer && vileFatherOfWolvesPlayer.isAlive && !!piedPiperPlayer &&
piedPiperPlayer.isAliveAndPowerful && options.roles.piedPiper.isPowerlessIfInfected, "pied-piper-will-loose-powers-if-infected"),
];
},
protectAlerts() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export default {
},
firstDeadWerewolfNotBigBadWolfPlayer: {
type: Player,
required: true,
default: undefined,
},
isBigBadWolfFirstWerewolfToDie: {
type: Boolean,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ export default {
const { options, thiefAdditionalCards } = this.game;
const { action, source, targets, votesResult, doesJudgeRequestAnotherVote } = this.gameHistoryEntry.play;
const { isPowerlessIfMissesWerewolf } = this.gameOptions.roles.fox;
const { isPowerlessIfInfected } = this.gameOptions.roles.piedPiper;
const consequencesText = "GameSummaryHistoryPlayLine.consequences";
return [
...insertIf(action === "protect" && targets[0].player.currentRole === "little-girl" && !options.roles.littleGirl.isProtectedByGuard,
Expand All @@ -177,7 +178,7 @@ export default {
...insertIf(action === "vote" && votesResult === "no-death", this.$t(`${consequencesText}.votesNoDeath`)),
...insertIf(action === "vote" && doesJudgeRequestAnotherVote, this.$t(`${consequencesText}.stutteringJudgeRequestedVote`)),
...insertIf(action === "eat" && source.name === "werewolves" && targets[0].isInfected &&
targets[0].isInfected.role.current === "pied-piper", this.$t(`${consequencesText}.piedPiperIsInfected`)),
targets[0].player.role.current === "pied-piper" && isPowerlessIfInfected, this.$t(`${consequencesText}.piedPiperIsInfected`)),
...insertIf(action === "mark" && targets.length,
this.$t(`${consequencesText}.ravenMarked`, { markPenalty: options.roles.raven.markPenalty })),
...insertIf(action === "choose-card" && options.roles.thief.mustChooseBetweenWerewolves &&
Expand Down
4 changes: 3 additions & 1 deletion src/components/shared/Game/PlayField/CancelActionButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

<script>
import { mapGetters } from "vuex";
import { maxTargetLengthForPlayerAttribute } from "@/helpers/functions/Player";
export default {
name: "CancelActionButton",
Expand Down Expand Up @@ -42,6 +43,7 @@ export default {
return "";
},
noTargetSelectedText() {
const targetsCount = maxTargetLengthForPlayerAttribute(this.attribute, this.game);
if (this.game.isFirstWaitingChooseSideAction) {
return this.$t("CancelActionButton.pleaseChooseSide");
} else if (this.game.isFirstWaitingChooseCardAction) {
Expand All @@ -52,7 +54,7 @@ export default {
} else if (this.game.isFirstWaitingSkippableAction) {
return this.$t("CancelActionButton.chooseTargetIfNot");
}
return this.$t("CancelActionButton.pleaseChooseTarget");
return this.$tc("CancelActionButton.pleaseChooseTarget", targetsCount, { targetsCount });
},
},
methods: {
Expand Down
8 changes: 6 additions & 2 deletions src/helpers/functions/Player.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ export function getNominatedPlayers(votes, game, action) {
return votedPlayers.filter(player => player.vote === maxVotes);
}

export function maxTargetLengthForPlayerAttribute(attribute) {
export function maxTargetLengthForPlayerAttribute(attribute, game) {
const { firstWaiting, options, piedPiperTargets } = game;
const oneTargetAttributes = [
"seen",
"eaten",
Expand All @@ -50,7 +51,10 @@ export function maxTargetLengthForPlayerAttribute(attribute) {
"sniff",
];
const twoTargetsAttributes = ["in-love", "charmed"];
if (oneTargetAttributes.includes(attribute)) {
if (attribute === "charmed" && firstWaiting.for === "pied-piper") {
const { charmedPeopleCountPerNight } = options.roles.piedPiper;
return piedPiperTargets.length < charmedPeopleCountPerNight ? piedPiperTargets.length : charmedPeopleCountPerNight;
} else if (oneTargetAttributes.includes(attribute)) {
return 1;
} else if (twoTargetsAttributes.includes(attribute)) {
return 2;
Expand Down
13 changes: 7 additions & 6 deletions src/plugins/vue-i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,8 @@
"charm": {
"howToPlay": "Comment jouer le Joueur de Flûte ?",
"piedPiperCharmsWhen": "Chaque nuit, s'il est vivant, le Joueur de Flûte se réveille.",
"piedPiperCanCharm": "Le Joueur de Flûte peut charmer deux joueurs grâce son talent de musicien hors pair. Le maître du jeu devra, en silence et le plus discrètement possible, tapoter le dos des joueurs charmés une fois le choix du Joueur de Flûte fait.",
"piedPiperCanCharm": "Le Joueur de Flûte peut charmer deux joueurs grâce son talent de musicien hors pair. Le nombre de joueurs charmés par nuit peut être modifié dans les options de la partie.",
"gameMasterTouchBackToCharmedPeople": "Le maître du jeu devra, en silence et le plus discrètement possible, tapoter le dos des joueurs charmés une fois le choix du Joueur de Flûte fait.",
"ifAllAreCharmed": "Si tous les joueurs vivants sont charmés par le Joueur de Flûte, ce dernier gagne la partie seul !",
"ifPiedPiperIsInfected": "Si l'Infect Père des Loups choisit d'infecter le Joueur de Flûte, ce dernier perd son pouvoir de charme et ne peut plus gagner seul mais avec les Loups-Garous.",
"toValidateCharm": "Pour passer à la suite, le Joueur de Flûte doit obligatoirement choisir deux cibles."
Expand All @@ -883,7 +884,7 @@
"charmed": {
"meet-each-other": {
"howToPlay": "Comment jouer le joueur charmés ?",
"charmedMeetEachOtherWhen": "Chaque fois que le Joueur de Flûte utilise son talent de musicien, tous les joueurs charmés se réveillent et se recontrent.",
"charmedMeetEachOtherWhen": "Chaque fois que le Joueur de Flûte utilise son talent de musicien, tous les joueurs charmés se réveillent et se rencontrent.",
"ifAllAreCharmed": "Les joueurs charmés doivent se dépécher de trouver qui est le Joueur de Flûte, car si tous les joueurs vivants sont charmés, le musicien gagnera la partie à lui tout seul !",
"charmedHave20s": "Les joueurs charmés ont environ 20 secondes pendant leur tour, ce qui est suffisant pour se découvrir et déduire qui pourrait être le Joueur de Flûte.",
"noActionRequiredToValidate": "Aucune action n'est requise pour passer à la suite."
Expand Down Expand Up @@ -1303,7 +1304,7 @@
"cancelTarget": "Annuler cette cible",
"cancelSide": "Annuler le choix du camp",
"chooseTargetIfNot": "Choisissez une cible dans le cas contraire",
"pleaseChooseTarget": "Veuillez choisir une cible",
"pleaseChooseTarget": "Veuillez choisir une cible | Veuillez choisir {targetsCount} cibles",
"pleaseChooseSide": "Veuillez choisir un camp",
"pleaseChooseCard": "Veuillez choisir une carte",
"chooseCardIfNot": "Choisissez une carte dans le cas contraire"
Expand Down Expand Up @@ -1397,11 +1398,11 @@
"threeBrothersWakeUpToTalk": "Les Trois Frères se réveillent et vont se concerter discrètement.",
"wildChildStarts": "L'Enfant Sauvage se réveille pour choisir son modèle parmi les habitants.",
"bigBadWolfStarts": "Le Grand-Méchant-Loup se réveille pour choisir la seconde victime des Loups-Garous.",
"piedPiperStarts": "Le Joueur de flûte se réveille pour choisir deux victimes qui seront sous l'emprise de son charme.",
"piedPiperStarts": "Le Joueur de flûte se réveille pour choisir une victime qui sera sous l'emprise de son charme. | Le Joueur de flûte se réveille pour choisir {charmedPeopleCountPerNight} victimes qui seront sous l'emprise de son charme.",
"sheriffSettlesVote": "Le maire va départager pour régler l'égalité des votes sur la pendaison.",
"sheriffDelegates": "Dans son dernier souffle, le maire va déléguer son rôle à l'un des survivants.",
"piedPiperCharmedTwoPlayers": "Le Joueur de Flûte a charmé deux personnes de plus, il se rapproche de son but ultime de vengeance.",
"gameMasterWillTouchCharmed": "Le maître du jeu va faire le tour des habitants et toucher dans le dos les deux nouveaux charmés.",
"piedPiperCharmedTwoPlayers": "Le Joueur de Flûte a charmé une personne de plus, il se rapproche de son but ultime de vengeance. | Le Joueur de Flûte a charmé {charmedPeopleCountPerNight} personnes de plus, il se rapproche de son but ultime de vengeance.",
"gameMasterWillTouchCharmed": "Le maître du jeu va faire le tour des habitants et toucher dans le dos le nouveau charmé. | Le maître du jeu va faire le tour des habitants et toucher dans le dos les {charmedPeopleCountPerNight} nouveaux charmés.",
"charmedWakeUp": "Les tout juste charmés par le Joueur de Flûte se réveillent pour se reconnaître.",
"charmedWakeUpWithOldOnes": "Les tout juste charmés par le Joueur de Flûte se réveillent avec les anciens charmés pour se reconnaître.",
"scapegoatStarts": "Face à l'injustice de sa mort, le Bouc-Émissaire va choisir qui n'aura pas le droit de vote au jour suivant dans son dernier souffle.",
Expand Down

0 comments on commit 7961220

Please sign in to comment.