diff --git a/README.md b/README.md
index afaa618..019947e 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@
- Resize 180px wide PNG card images to be 90px wide and create sprite from them:
```shell
- magick montage $(ls blue-*.png) $(ls brown-*.png) $(ls gray-*.png) $(ls green-*.png) $(ls pink-*.png) $(ls red-*.png) $(ls yellow-*.png) $(ls adventurer-*.png) back.png -geometry +0+0 -tile 7x8 -mode concatenate -background none -resize 90 montage.png
+ magick montage $(ls blue-*.png) $(ls brown-*.png) $(ls gray-*.png) $(ls green-*.png) $(ls pink-*.png) $(ls red-*.png) $(ls yellow-*.png) jersey.png $(ls adventurer-*.png) -geometry +0+0 -tile 7x8 -mode concatenate -background none -resize 90 montage.png
```
- Reduce generated sprite size by ~90% sending it to https://tinypng.com
diff --git a/img/cards.png b/img/cards.png
index f7e9a0f..c6dab14 100644
Binary files a/img/cards.png and b/img/cards.png differ
diff --git a/modules/constants.inc.php b/modules/constants.inc.php
index 78b520d..20cfe1b 100644
--- a/modules/constants.inc.php
+++ b/modules/constants.inc.php
@@ -28,6 +28,7 @@
define('COLOR_RED', 60);
define('COLOR_YELLOW', 70);
define('COLOR_ADVENTURER', 80);
+define('COLOR_JERSEY', 90);
// Cards value
define('VALUE_1', 1);
@@ -43,6 +44,4 @@
define('VALUE_40', 40);
define('VALUE_45', 45);
define('VALUE_50', 50);
-
-// Jersey value
-define('JERSEY_VALUE', 10);
+define('VALUE_JERSEY', 10);
diff --git a/velonimo.css b/velonimo.css
index 057a16d..9d35edc 100644
--- a/velonimo.css
+++ b/velonimo.css
@@ -132,7 +132,7 @@ Board
transition-duration: 0.4s;
}
.player-table.is-wearing-jersey .player-table-hand {
- margin: 5px 0 0 -5px;
+ margin: 5px 0 0 -6px;
}
.player-table-hand .number-of-cards {
position: absolute;
@@ -189,11 +189,11 @@ Board
}
.player-table.is-wearing-jersey .player-table-jersey {
position: absolute;
- bottom: 10px;
- right: 0;
- width: 60px;
- height: 83px;
- background-size: 60px 83px;
+ bottom: 7px;
+ right: -1px;
+ width: 65px;
+ height: 90px;
+ background-size: 65px 90px;
background-image: url('img/jersey.png');
background-repeat: no-repeat;
background-position: center center;
@@ -204,26 +204,6 @@ Board
.player-table.is-wearing-jersey.has-used-jersey .player-table-jersey {
opacity: 0.2;
}
-/* @TODO: try to only reduce opacity of jersey instead of using a cross overlay */
-.player-table.is-wearing-jersey.has-used-jersey .jersey-overlay {
- display: block;
- position: relative;
- top: 20px;
- height: 50px;
- width: 10px;
- margin: 0 auto;
- background: black;
- transform: rotate(45deg);
-}
-.player-table.is-wearing-jersey.has-used-jersey .jersey-overlay::after {
- content: "";
- position: absolute;
- left: -20px;
- top: 20px;
- width: 50px;
- height: 10px;
- background: black;
-}
/**
END Board
*/
@@ -341,9 +321,9 @@ Animations
*/
.moving-jersey {
position: absolute;
- width: 60px;
- height: 83px;
- background-size: 60px 83px;
+ width: 65px;
+ height: 90px;
+ background-size: 65px 90px;
background-image: url('img/jersey.png');
background-repeat: no-repeat;
z-index: 100;
diff --git a/velonimo.game.php b/velonimo.game.php
index da8a9bd..8f60075 100644
--- a/velonimo.game.php
+++ b/velonimo.game.php
@@ -29,6 +29,7 @@ class Velonimo extends Table
private const GAME_STATE_CURRENT_ROUND = 'currentRound';
private const GAME_STATE_JERSEY_HAS_BEEN_USED_IN_THE_CURRENT_ROUND = 'jerseyUsedInRound';
+ private const GAME_STATE_PREVIOUS_PLAYED_CARDS_VALUE = 'previousValueToBeat';
private const GAME_STATE_LAST_PLAYED_CARDS_VALUE = 'valueToBeat';
private const GAME_STATE_LAST_PLAYED_CARDS_PLAYER_ID = 'playerIdForValueToBeat';
private const GAME_STATE_LAST_SELECTED_NEXT_PLAYER_ID = 'selectedNextPlayerId';
@@ -65,6 +66,7 @@ function __construct() {
self::GAME_STATE_LAST_NUMBER_OF_CARDS_TO_PICK => 15,
self::GAME_STATE_LAST_NUMBER_OF_CARDS_TO_GIVE_BACK => 16,
self::GAME_STATE_LAST_PLAYER_ID_TO_GIVE_CARDS_BACK => 17,
+ self::GAME_STATE_PREVIOUS_PLAYED_CARDS_VALUE => 18,
self::GAME_OPTION_HOW_MANY_ROUNDS => 100,
]);
@@ -118,6 +120,7 @@ protected function setupNewGame($players, $options = []) {
// Init global values with their initial values
self::setGameStateValue(self::GAME_STATE_CURRENT_ROUND, 0);
+ self::setGameStateValue(self::GAME_STATE_PREVIOUS_PLAYED_CARDS_VALUE, 0);
self::setGameStateValue(self::GAME_STATE_LAST_PLAYED_CARDS_VALUE, 0);
self::setGameStateValue(self::GAME_STATE_LAST_PLAYED_CARDS_PLAYER_ID, 0);
self::setGameStateValue(self::GAME_STATE_LAST_SELECTED_NEXT_PLAYER_ID, 0);
@@ -217,6 +220,7 @@ protected function getAllDatas() {
$result['previousPlayedCards'] = $this->formatCardsForClient(
$this->fromBgaCardsToVelonimoCards($this->deck->getCardsInLocation(self::CARD_LOCATION_PREVIOUS_PLAYED))
);
+ $result['previousPlayedCardsValue'] = (int) self::getGameStateValue(self::GAME_STATE_PREVIOUS_PLAYED_CARDS_VALUE);
return $result;
}
@@ -334,6 +338,7 @@ function playCards(array $playedCardIds, bool $cardsPlayedWithJersey) {
self::setGameStateValue(self::GAME_STATE_JERSEY_HAS_BEEN_USED_IN_THE_CURRENT_ROUND, 1);
}
self::setGameStateValue(self::GAME_STATE_LAST_PLAYED_CARDS_PLAYER_ID, $currentPlayerId);
+ self::setGameStateValue(self::GAME_STATE_PREVIOUS_PLAYED_CARDS_VALUE, $lastPlayedCardsValue);
self::setGameStateValue(self::GAME_STATE_LAST_PLAYED_CARDS_VALUE, $playedCardsValue);
self::notifyAllPlayers('cardsPlayed', clienttranslate('${playerName} plays ${playedCardsValue}'), [
'playedCardsPlayerId' => $currentPlayerId,
@@ -681,7 +686,7 @@ function argPlayerGiveCardsBackAfterPicking() {
*/
function stStartRound() {
- $this->discardLastPlayedCards();
+ $this->discardPlayedCards();
// take back all cards and shuffle them
$this->deck->moveAllCardsInLocation(null, self::CARD_LOCATION_DECK);
$this->deck->shuffle(self::CARD_LOCATION_DECK);
@@ -733,7 +738,7 @@ function stActivateNextPlayer() {
$nextPlayerCanPlay = in_array($nextPlayerId, $playersWhoCanPlayIds, true);
// if the next player is the one who played the last played cards, remove the cards from the table
if ($nextPlayerId === $playerIdWhoPlayedTheLastCards) {
- $this->discardLastPlayedCards();
+ $this->discardPlayedCards();
self::giveExtraTime($nextPlayerId);
if ($nextPlayerCanPlay) {
$this->gamestate->nextState('firstPlayerTurn');
@@ -806,8 +811,8 @@ function stEndRound() {
// notify points earned by each player
foreach ($players as $player) {
$translatedMessage = ($numberOfPointsForRoundByPlayerId[$player->getId()] > 0)
- ? clienttranslate('${playerName} does not get any point')
- : clienttranslate('${playerName} wins ${points} points');
+ ? clienttranslate('${playerName} wins ${points} points')
+ : clienttranslate('${playerName} does not get any point');
self::notifyAllPlayers('pointsWon', $translatedMessage, [
'playerName' => $player->getName(),
'points' => $numberOfPointsForRoundByPlayerId[$player->getId()],
@@ -848,7 +853,7 @@ function stEndRound() {
$this->notifyAllPlayers( 'tableWindow', '', array(
'id' => 'finalScoring',
'title' => sprintf(
- clienttranslate('Result of round %s/%s'),
+ clienttranslate('Results of round %s/%s'),
$currentRound,
$howManyRounds
),
@@ -999,8 +1004,7 @@ private function getCardsValue(array $cards, bool $withJersey): int {
return 0;
}
- $addJerseyValueIfUsed = fn (int $value) => $value + ($withJersey ? JERSEY_VALUE : 0);
-
+ $addJerseyValueIfUsed = fn (int $value) => $value + ($withJersey ? VALUE_JERSEY : 0);
if (count($cards) === 1) {
return $addJerseyValueIfUsed($cards[0]->getValue());
@@ -1196,9 +1200,10 @@ private function getCurrentLoser(array $players): ?VelonimoPlayer {
return null;
}
- private function discardLastPlayedCards(): void {
+ private function discardPlayedCards(): void {
$this->deck->moveAllCardsInLocation(self::CARD_LOCATION_PREVIOUS_PLAYED, self::CARD_LOCATION_DISCARD);
$this->deck->moveAllCardsInLocation(self::CARD_LOCATION_PLAYED, self::CARD_LOCATION_DISCARD);
+ self::setGameStateValue(self::GAME_STATE_PREVIOUS_PLAYED_CARDS_VALUE, 0);
self::setGameStateValue(self::GAME_STATE_LAST_PLAYED_CARDS_VALUE, 0);
self::setGameStateValue(self::GAME_STATE_LAST_PLAYED_CARDS_PLAYER_ID, 0);
self::notifyAllPlayers('cardsDiscarded', '', []);
diff --git a/velonimo.js b/velonimo.js
index 61979ca..a4797ac 100644
--- a/velonimo.js
+++ b/velonimo.js
@@ -41,6 +41,7 @@ const COLOR_PINK = 50;
const COLOR_RED = 60;
const COLOR_YELLOW = 70;
const COLOR_ADVENTURER = 80;
+const COLOR_JERSEY = 90;
// Cards value
const VALUE_1 = 1;
@@ -56,9 +57,10 @@ const VALUE_35 = 35;
const VALUE_40 = 40;
const VALUE_45 = 45;
const VALUE_50 = 50;
+const VALUE_JERSEY = 10;
-// Jersey value
-const JERSEY_VALUE = 10;
+// Special cards ID
+const CARD_ID_JERSEY = 0;
// DOM IDs
const DOM_ID_APP = 'velonimo-game';
@@ -71,7 +73,6 @@ const DOM_ID_PLAYER_HAND_TOGGLE_SORT_BUTTON = 'toggle-sort-button';
const DOM_ID_PLAYER_HAND_TOGGLE_SORT_BUTTON_LABEL = 'toggle-sort-button-label';
const DOM_ID_CURRENT_ROUND = 'current-round';
const DOM_ID_ACTION_BUTTON_PLAY_CARDS = 'action-button-play-cards';
-const DOM_ID_ACTION_BUTTON_PLAY_CARDS_WITH_JERSEY = 'action-button-play-cards-with-jersey';
const DOM_ID_ACTION_BUTTON_PASS_TURN = 'action-button-pass-turn';
const DOM_ID_ACTION_BUTTON_SELECT_PLAYER = 'action-button-select-player';
const DOM_ID_ACTION_BUTTON_GIVE_CARDS = 'action-button-give-cards';
@@ -183,8 +184,6 @@ const PLAYERS_PLACES_BY_NUMBER_OF_PLAYERS = {
// @TODO: support 2 players game
// @TODO: ? game rounds topology instead of choosing number of rounds
// @TODO: ? be able to move cards individually in your hand
-// @TODO: ? be able to click on the jersey to play it instead of having a 2nd button
-// @TODO: ? improve the visibility of the jersey that has been played with the combination on the table
define([
'dojo','dojo/_base/declare',
'ebg/core/gamegui',
@@ -249,7 +248,7 @@ function (dojo, declare) {
`
${(player.name.length > 10 ? (player.name.substr(0,10) + '...') : player.name)}
${player.howManyCards}
-
+
`,
DOM_ID_BOARD_CARPET);
@@ -284,8 +283,17 @@ function (dojo, declare) {
// Setup cards played on table
this.playedCardsValue = gamedatas.playedCardsValue;
- this.setupPreviousPlayedCards(gamedatas.previousPlayedCards);
- this.moveCardsFromPlayerHandToTable(gamedatas.playedCardsPlayerId, gamedatas.playedCards);
+ this.setupPreviousPlayedCards(
+ (gamedatas.previousPlayedCardsValue === (this.getCardsValue(gamedatas.previousPlayedCards) + VALUE_JERSEY))
+ ? this.addJerseyToCards(gamedatas.previousPlayedCards)
+ : gamedatas.previousPlayedCards
+ );
+ this.moveCardsFromPlayerHandToTable(
+ gamedatas.playedCardsPlayerId,
+ (this.playedCardsValue === (this.getCardsValue(gamedatas.playedCards) + VALUE_JERSEY))
+ ? this.addJerseyToCards(gamedatas.playedCards)
+ : gamedatas.playedCards
+ );
// Setup jersey
if (gamedatas.jerseyHasBeenUsedInTheCurrentRound) {
@@ -294,6 +302,12 @@ function (dojo, declare) {
this.restoreJerseyForCurrentRound();
}
this.moveJerseyToCurrentWinner();
+ if (
+ this.currentPlayerHasJersey
+ && !this.jerseyHasBeenUsedInTheCurrentRound
+ ) {
+ this.addJerseyToPlayerHand();
+ }
// Setup extra info
this.setupPlayersScore();
@@ -515,9 +529,10 @@ function (dojo, declare) {
moveJerseyToCurrentWinner: function (currentJerseyWearerId) {
Object.entries(this.players).forEach((entry) => {
const player = entry[1];
+ const isCurrentPlayer = this.player_id === player.id;
if (player.isWearingJersey) {
- this.currentPlayerHasJersey = this.player_id === player.id;
+ this.currentPlayerHasJersey = isCurrentPlayer;
if (!dojo.hasClass(`player-table-${player.id}`, DOM_CLASS_PLAYER_IS_WEARING_JERSEY)) {
if (currentJerseyWearerId) {
@@ -539,6 +554,10 @@ function (dojo, declare) {
if (dojo.hasClass(`player-table-${player.id}`, DOM_CLASS_PLAYER_IS_WEARING_JERSEY)) {
dojo.removeClass(`player-table-${player.id}`, DOM_CLASS_PLAYER_IS_WEARING_JERSEY);
}
+
+ if (isCurrentPlayer) {
+ this.removeJerseyFromPlayerHand();
+ }
}
});
},
@@ -581,31 +600,16 @@ function (dojo, declare) {
},
setupPlayCardsActionButton: function () {
const selectedCards = this.getSelectedPlayerCards();
- const selectedCardsValue = this.getCardsValue(selectedCards, false);
+ const selectedCardsValue = this.getCardsValue(selectedCards);
- // setup play cards button without jersey
+ // setup play cards button
if (!$(DOM_ID_ACTION_BUTTON_PLAY_CARDS)) {
- this.addActionButton(DOM_ID_ACTION_BUTTON_PLAY_CARDS, _('Play selected cards'), () => this.onPlayCards(false));
+ this.addActionButton(DOM_ID_ACTION_BUTTON_PLAY_CARDS, _('Play selected cards'), 'onPlayCards');
dojo.place(` (${selectedCardsValue})`, DOM_ID_ACTION_BUTTON_PLAY_CARDS);
this.addTooltip(`${DOM_ID_ACTION_BUTTON_PLAY_CARDS}-value`, _('Total value of selected cards'), '');
}
dojo.toggleClass(DOM_ID_ACTION_BUTTON_PLAY_CARDS, DOM_CLASS_DISABLED_ACTION_BUTTON, selectedCardsValue <= this.playedCardsValue);
$(`${DOM_ID_ACTION_BUTTON_PLAY_CARDS}-value`).innerText = ` (${selectedCardsValue})`;
-
- // setup play cards button with jersey
- if (
- this.currentPlayerHasJersey
- && !this.jerseyHasBeenUsedInTheCurrentRound
- ) {
- const selectedCardsWithJerseyValue = this.getCardsValue(selectedCards, true);
- if (!$(DOM_ID_ACTION_BUTTON_PLAY_CARDS_WITH_JERSEY)) {
- this.addActionButton(DOM_ID_ACTION_BUTTON_PLAY_CARDS_WITH_JERSEY, _('Play jersey with selected cards'), () => this.onPlayCards(true));
- dojo.place(` (${selectedCardsWithJerseyValue})`, DOM_ID_ACTION_BUTTON_PLAY_CARDS_WITH_JERSEY);
- this.addTooltip(`${DOM_ID_ACTION_BUTTON_PLAY_CARDS_WITH_JERSEY}-value`, _(`Total value of selected cards + jersey (${JERSEY_VALUE})`), '');
- }
- dojo.toggleClass(DOM_ID_ACTION_BUTTON_PLAY_CARDS_WITH_JERSEY, DOM_CLASS_DISABLED_ACTION_BUTTON, selectedCardsWithJerseyValue <= this.playedCardsValue);
- $(`${DOM_ID_ACTION_BUTTON_PLAY_CARDS_WITH_JERSEY}-value`).innerText = ` (${selectedCardsWithJerseyValue})`;
- }
},
/**
*
@@ -675,6 +679,9 @@ function (dojo, declare) {
VALUE_45,
VALUE_50,
].forEach((value) => fn.bind(this)(COLOR_ADVENTURER, value));
+
+ // jersey card
+ fn.bind(this)(COLOR_JERSEY, VALUE_JERSEY);
},
/**
* This function gives the position of the card in the sprite "cards.png",
@@ -705,22 +712,23 @@ function (dojo, declare) {
case COLOR_ADVENTURER:
switch (value) {
case VALUE_25:
- return 49;
- case VALUE_30:
return 50;
- case VALUE_35:
+ case VALUE_30:
return 51;
- case VALUE_40:
+ case VALUE_35:
return 52;
- case VALUE_45:
+ case VALUE_40:
return 53;
- case VALUE_50:
+ case VALUE_45:
return 54;
- default:
+ case VALUE_50:
return 55;
+ default:
+ throw new Error('Unsupported');
}
default:
- return 55;
+ // Jersey
+ return 49;
}
},
sortPlayerCardsByColor: function () {
@@ -970,26 +978,30 @@ function (dojo, declare) {
value = VALUE_7;
break;
case 49:
+ color = COLOR_JERSEY;
+ value = VALUE_JERSEY;
+ break;
+ case 50:
color = COLOR_ADVENTURER;
value = VALUE_25;
break;
- case 50:
+ case 51:
color = COLOR_ADVENTURER;
value = VALUE_30;
break;
- case 51:
+ case 52:
color = COLOR_ADVENTURER;
value = VALUE_35;
break;
- case 52:
+ case 53:
color = COLOR_ADVENTURER;
value = VALUE_40;
break;
- case 53:
+ case 54:
color = COLOR_ADVENTURER;
value = VALUE_45;
break;
- case 54:
+ case 55:
color = COLOR_ADVENTURER;
value = VALUE_50;
break;
@@ -1011,6 +1023,13 @@ function (dojo, declare) {
*/
getCardsThatCanBePlayedWithCard: function (color, value, cards) {
return cards.filter((card) => {
+ if (color === COLOR_JERSEY) {
+ return card.color !== COLOR_ADVENTURER;
+ }
+ if (card.color === COLOR_JERSEY) {
+ return color !== COLOR_ADVENTURER;
+ }
+
if (color === COLOR_ADVENTURER && value !== card.value) {
return false;
}
@@ -1040,6 +1059,13 @@ function (dojo, declare) {
*/
getCardsThatCannotBePlayedWithCard: function (color, value, cards) {
return cards.filter((card) => {
+ if (color === COLOR_JERSEY) {
+ return card.color === COLOR_ADVENTURER;
+ }
+ if (card.color === COLOR_JERSEY) {
+ return color === COLOR_ADVENTURER;
+ }
+
if (color === COLOR_ADVENTURER && value !== card.value) {
return true;
}
@@ -1104,7 +1130,7 @@ function (dojo, declare) {
// format combinations
.map((cards) => ({
cards: cards,
- value: this.getCardsValue(cards, false),
+ value: this.getCardsValue(cards),
}))
// sort combinations by highest value
.sort((a, b) => {
@@ -1124,33 +1150,34 @@ function (dojo, declare) {
},
/**
* @param {Object[]} cards
- * @param {boolean} withJersey
* @returns {number}
*/
- getCardsValue: function (cards, withJersey) {
- if (!cards.length) {
+ getCardsValue: function (cards) {
+ const withJersey = cards.map((c) => c.id).includes(CARD_ID_JERSEY);
+ const cardsWithoutJersey = cards.filter((c) => c.id !== CARD_ID_JERSEY);
+ if (!cardsWithoutJersey.length) {
return 0;
}
// the jersey cannot be played with an adventurer
- if (withJersey && cards.map((c) => c.color).includes(COLOR_ADVENTURER)) {
+ if (withJersey && cardsWithoutJersey.map((c) => c.color).includes(COLOR_ADVENTURER)) {
return 0;
}
- const addJerseyValueIfUsed = (value) => value + (withJersey ? JERSEY_VALUE : 0);
+ const addJerseyValueIfUsed = (value) => value + (withJersey ? VALUE_JERSEY : 0);
- if (cards.length === 1) {
- return addJerseyValueIfUsed(cards[0].value);
+ if (cardsWithoutJersey.length === 1) {
+ return addJerseyValueIfUsed(cardsWithoutJersey[0].value);
}
let minCardValue = 1000;
- cards.forEach((card) => {
+ cardsWithoutJersey.forEach((card) => {
if (card.value < minCardValue) {
minCardValue = card.value;
}
});
- return addJerseyValueIfUsed((cards.length * 10) + minCardValue);
+ return addJerseyValueIfUsed((cardsWithoutJersey.length * 10) + minCardValue);
},
/**
* @returns {boolean}
@@ -1163,7 +1190,7 @@ function (dojo, declare) {
const playerCanPlayJersey = this.currentPlayerHasJersey && !this.jerseyHasBeenUsedInTheCurrentRound;
- return this.playedCardsValue < (playerCardsCombinations[0].value + (playerCanPlayJersey ? JERSEY_VALUE : 0));
+ return this.playedCardsValue < (playerCardsCombinations[0].value + (playerCanPlayJersey ? VALUE_JERSEY : 0));
},
/**
* @param {number} cardId
@@ -1386,6 +1413,33 @@ function (dojo, declare) {
this.playerHand.addToStockWithId(this.getCardPositionInSpriteByColorAndValue(card.color, card.value), card.id);
});
},
+ addJerseyToPlayerHand: function () {
+ const cards = this.getAllPlayerCards();
+ if (cards.map((c) => c.id).includes(CARD_ID_JERSEY)) {
+ return;
+ }
+
+ this.playerHand.addToStockWithId(this.getCardPositionInSpriteByColorAndValue(COLOR_JERSEY, VALUE_JERSEY), CARD_ID_JERSEY);
+ },
+ /**
+ * @param {Object[]} cards
+ */
+ addJerseyToCards: function (cards) {
+ return cards.concat(
+ this.getCardObjectFromPositionInSpriteAndId(
+ this.getCardPositionInSpriteByColorAndValue(COLOR_JERSEY, VALUE_JERSEY),
+ CARD_ID_JERSEY
+ )
+ );
+ },
+ removeJerseyFromPlayerHand: function () {
+ const cards = this.getAllPlayerCards();
+ if (!cards.map((c) => c.id).includes(CARD_ID_JERSEY)) {
+ return;
+ }
+
+ this.playerHand.removeFromStockById(CARD_ID_JERSEY);
+ },
movePlayedCardsToPreviousPlayedCards: function () {
dojo.query(`.${DOM_CLASS_CARDS_STACK_PREVIOUS_PLAYED}`).forEach(dojo.destroy);
dojo.query(`#${DOM_ID_LAST_PLAYED_CARDS} .${DOM_CLASS_CARDS_STACK}`).forEach((elementDomId) => {
@@ -1408,15 +1462,14 @@ function (dojo, declare) {
///////////////////////////////////////////////////
//// Player's action
///////////////////////////////////////////////////
- /**
- * @param {boolean} withJersey
- */
- onPlayCards: function (withJersey) {
+ onPlayCards: function () {
if (!this.checkAction('playCards')) {
return;
}
- const playedCards = this.getSelectedPlayerCards();
+ const cards = this.getSelectedPlayerCards();
+ const withJersey = cards.map((c) => c.id).includes(CARD_ID_JERSEY);
+ const playedCards = cards.filter((c) => c.id !== CARD_ID_JERSEY);
if (playedCards.length <= 0) {
return;
}
@@ -1465,7 +1518,7 @@ function (dojo, declare) {
return;
}
- const selectedCards = this.getSelectedPlayerCards();
+ const selectedCards = this.getSelectedPlayerCards().filter((c) => c.id !== CARD_ID_JERSEY);
if (selectedCards.length <= 0) {
return;
}
@@ -1519,6 +1572,12 @@ function (dojo, declare) {
notif_cardsDealt: function (data) {
this.playerHand.removeAll();
this.addCardsToPlayerHand(data.args.cards);
+ if (
+ this.currentPlayerHasJersey
+ && !this.jerseyHasBeenUsedInTheCurrentRound
+ ) {
+ this.addJerseyToPlayerHand();
+ }
},
notif_cardsPlayed: function (data) {
this.discardPlayerSpeechBubbles();
@@ -1526,7 +1585,10 @@ function (dojo, declare) {
// place new played cards
this.playedCardsValue = data.args.playedCardsValue;
- this.moveCardsFromPlayerHandToTable(data.args.playedCardsPlayerId, data.args.playedCards);
+ const playedCardsWithJersey = data.args.withJersey
+ ? this.addJerseyToCards(data.args.playedCards)
+ : data.args.playedCards;
+ this.moveCardsFromPlayerHandToTable(data.args.playedCardsPlayerId, playedCardsWithJersey);
// update number of cards in players hand
this.players[data.args.playedCardsPlayerId].howManyCards = this.players[data.args.playedCardsPlayerId].howManyCards - data.args.playedCards.length;