From e62361e3c4b0411b63de18bf9da3e7d6934d7b55 Mon Sep 17 00:00:00 2001 From: Oliboy50 Date: Sat, 13 Aug 2022 14:31:14 +0200 Subject: [PATCH] feat(style): show player hidden cards as fan + add medals when players finish round --- img/finish.png | Bin 0 -> 67670 bytes velonimo.css | 245 +++++++++++++++++----- velonimo.game.php | 17 +- velonimo.js | 523 +++++++++++++++++++++++++++------------------- 4 files changed, 507 insertions(+), 278 deletions(-) create mode 100644 img/finish.png diff --git a/img/finish.png b/img/finish.png new file mode 100644 index 0000000000000000000000000000000000000000..73c6fa7b524e95c2d647782aa0f49a7dfd6c5eb6 GIT binary patch literal 67670 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 $cardsPlayedWithJersey ? array_merge([$this->formatJerseyForClient()], $formattedCards) : $formattedCards, - 'player_name' => self::getCurrentPlayerName(), + 'player_name' => $currentPlayerName = self::getCurrentPlayerName(), 'playedCardsValue' => $playedCardsValue, 'withJersey' => $cardsPlayedWithJersey, ]); @@ -398,7 +398,6 @@ function playCards(array $playedCardIds, bool $cardsPlayedWithJersey) { self::notifyPlayer($currentPlayer->getId(), 'cardsReceivedFromDeck', $translatedMessage, [ 'cards' => $formattedCards = $this->formatCardsForClient($cardsPickedFromDeck), 'cardsImage' => $formattedCards, - 'numberOfCards' => $numberOfCardsToPickFromDeck, 'player_name' => $currentPlayer->getName(), ]); } @@ -416,6 +415,12 @@ function playCards(array $playedCardIds, bool $cardsPlayedWithJersey) { if ($nextRankForRound === 1) { $this->incStat(1, 'numberOfRoundsWon', $currentPlayerId); } + self::notifyAllPlayers('playerHasFinishedRound', clienttranslate('${player_name} finished in position ${rank}'), [ + 'playerId' => $currentPlayer->getId(), + 'roundsRanking' => $currentPlayer->getRoundsRanking(), + 'player_name' => $currentPlayerName, + 'rank' => $nextRankForRound, + ]); $playersWhoCanPlay = array_filter( $this->getPlayersWhoCanPlayDuringRound($currentRound, $players), @@ -896,12 +901,8 @@ function stEndRound() { $numberOfPlayers = count($players); $currentRound = (int) self::getGameStateValue(self::GAME_STATE_CURRENT_ROUND); $numberOfPointsForRoundByPlayerId = []; - $winnerOfCurrentRound = null; foreach ($players as $k => $player) { $playerCurrentRoundRank = $player->getLastRoundRank(); - if ($playerCurrentRoundRank === 1) { - $winnerOfCurrentRound = $player; - } $numberOfPointsForRoundByPlayerId[$player->getId()] = $this->getNumberOfPointsAtRankForRound( $playerCurrentRoundRank, $currentRound, @@ -928,9 +929,8 @@ function stEndRound() { // re-allow the jersey to be used self::setGameStateValue(self::GAME_STATE_JERSEY_HAS_BEEN_USED_IN_THE_CURRENT_ROUND, 0); - self::notifyAllPlayers('roundEnded', clienttranslate('Round #${currentRound} has been won by ${player_name}'), [ + self::notifyAllPlayers('roundEnded', clienttranslate('Round #${currentRound} ends'), [ 'currentRound' => $currentRound, - 'player_name' => $winnerOfCurrentRound ? $winnerOfCurrentRound->getName() : 'N/A', 'players' => $this->formatPlayersForClient($players), ]); @@ -1216,6 +1216,7 @@ private function formatPlayersForClient(array $players): array { 'name' => $player->getName(), 'color' => $player->getColor(), 'score' => $player->getScore(), + 'roundsRanking' => $player->getRoundsRanking(), 'isWearingJersey' => $player->isWearingJersey(), 'howManyCards' => count($this->deck->getCardsInLocation(self::CARD_LOCATION_PLAYER_HAND, $player->getId())), ]; diff --git a/velonimo.js b/velonimo.js index 8e14960..fa2f33f 100644 --- a/velonimo.js +++ b/velonimo.js @@ -89,13 +89,13 @@ const DOM_CLASS_PLAYER_TABLE = 'player-table'; const DOM_CLASS_PLAYER_IS_WEARING_JERSEY = 'is-wearing-jersey'; const DOM_CLASS_PLAYER_HAS_USED_JERSEY = 'has-used-jersey'; const DOM_CLASS_CARDS_STACK = 'cards-stack'; -const DOM_CLASS_TEXT_ON_CARDS = 'text-on-cards'; const DOM_CLASS_CARDS_STACK_PREVIOUS_PLAYED = 'previous-last-played-cards'; const DOM_CLASS_DISABLED_ACTION_BUTTON = 'disabled'; const DOM_CLASS_ACTIVE_PLAYER = 'active'; const DOM_CLASS_SELECTABLE_PLAYER = 'selectable'; const DOM_CLASS_NON_SELECTABLE_CARD = 'non-selectable-player-card'; const DOM_CLASS_PLAYER_SPEECH_BUBBLE_SHOW = 'show-bubble'; +const DOM_CLASS_SPEECH_BUBBLE = 'player-table-speech-bubble'; const DOM_CLASS_SPEECH_BUBBLE_LEFT = 'speech-bubble-on-left'; const DOM_CLASS_SPEECH_BUBBLE_RIGHT = 'speech-bubble-on-right'; const DOM_CLASS_CARDS_GROUP_CARD = 'cards-group-card'; @@ -108,20 +108,18 @@ const PLAYER_HAND_SORT_BY_VALUE = 'value'; // Style const BOARD_CARPET_WIDTH = 740; -const BOARD_CARPET_HEIGHT = 450; const CARD_WIDTH = 90; const CARD_HEIGHT = 126; -const PLAYER_TABLE_WIDTH = 130; -const PLAYER_TABLE_HEIGHT = 130; -const PLAYER_TABLE_BORDER_SIZE = 2; -const BOARD_MARGIN = 10; -const TABLE_STYLE_HORIZONTAL_LEFT = `left: ${BOARD_MARGIN}px;`; -const TABLE_STYLE_HORIZONTAL_MIDDLE_LEFT = `left: ${BOARD_MARGIN + PLAYER_TABLE_WIDTH}px;`; +const PLAYER_TABLE_WIDTH = 200; +const PLAYER_TABLE_HEIGHT = CARD_HEIGHT; +const PLAYER_TABLE_HORIZONTAL_MIDDLE_MARGIN = 100; +const TABLE_STYLE_HORIZONTAL_LEFT = `left: 0;`; +const TABLE_STYLE_HORIZONTAL_MIDDLE_LEFT = `left: ${PLAYER_TABLE_HORIZONTAL_MIDDLE_MARGIN}px;`; const TABLE_STYLE_HORIZONTAL_CENTER = `left: ${(BOARD_CARPET_WIDTH / 2) - (PLAYER_TABLE_WIDTH / 2)}px;`; -const TABLE_STYLE_HORIZONTAL_MIDDLE_RIGHT = `left: ${BOARD_CARPET_WIDTH - (BOARD_MARGIN + (PLAYER_TABLE_WIDTH * 2))}px;`; -const TABLE_STYLE_HORIZONTAL_RIGHT = `left: ${BOARD_CARPET_WIDTH - (BOARD_MARGIN + PLAYER_TABLE_WIDTH)}px;`; -const TABLE_STYLE_VERTICAL_TOP = `top: ${BOARD_MARGIN}px;`; -const TABLE_STYLE_VERTICAL_BOTTOM = `bottom: ${BOARD_MARGIN}px;`; +const TABLE_STYLE_HORIZONTAL_MIDDLE_RIGHT = `left: ${BOARD_CARPET_WIDTH - (PLAYER_TABLE_WIDTH + PLAYER_TABLE_HORIZONTAL_MIDDLE_MARGIN)}px;`; +const TABLE_STYLE_HORIZONTAL_RIGHT = `left: ${BOARD_CARPET_WIDTH - PLAYER_TABLE_WIDTH}px;`; +const TABLE_STYLE_VERTICAL_TOP = `top: 0;`; +const TABLE_STYLE_VERTICAL_BOTTOM = `bottom: 0;`; // the current player (index 0 == current player) place is always at the bottom of the board, in a way that players always stay closed to their hand const PLAYERS_PLACES_BY_NUMBER_OF_PLAYERS = { 2: { @@ -218,7 +216,7 @@ function (dojo, declare) { this.jerseyHasBeenUsedInTheCurrentRound = gamedatas.jerseyHasBeenUsedInTheCurrentRound; this.howManyRounds = gamedatas.howManyRounds; - // Setup board + // setup board dojo.place( `
@@ -242,7 +240,7 @@ function (dojo, declare) { DOM_ID_APP ); - // Setup players + // setup players this.players = gamedatas.players; const howManyPlayers = Object.keys(this.players).length; const playersPlace = PLAYERS_PLACES_BY_NUMBER_OF_PLAYERS[howManyPlayers]; @@ -252,17 +250,30 @@ function (dojo, declare) { ).forEach((player, index) => { const playerPosition = playersPlace[index]; const playerColorRGB = `#${player.color}`; + const isPositionTop = playerPosition.tableStyle.indexOf('top') !== -1; + const hasJerseyOnLeft = playerPosition.bubbleClass.indexOf('left') !== -1; dojo.place( - `
-
${(player.name.length > 10 ? (player.name.substr(0,10) + '...') : player.name)}
-
+ `
+
${(player.name.length > 10 ? (player.name.substr(0,10) + '...') : player.name)}
+
-
+
+
`, DOM_ID_BOARD_CARPET); }); + console.log(this.players); this.setupNumberOfCardsInPlayersHand(); + this.setupPlayersFinishPosition(); + + // setup jersey + if (gamedatas.jerseyHasBeenUsedInTheCurrentRound) { + this.useJerseyForCurrentRound(); + } else { + this.restoreJerseyForCurrentRound(); + } + this.moveJerseyToCurrentWinner(); // show 2P mode items if (this.is2PlayersMode()) { @@ -277,7 +288,7 @@ function (dojo, declare) { this.setupAttackRewardCards(gamedatas.attackRewardCards); } - // Init playerHand "ebg.stock" component + // init playerHand "ebg.stock" component this.playerHand = new ebg.stock(); this.playerHand.create(this, $(DOM_ID_PLAYER_HAND), CARD_WIDTH, CARD_HEIGHT); this.playerHand.setSelectionAppearance('class'); @@ -293,12 +304,6 @@ function (dojo, declare) { cardPositionInSprite // position in sprite ); }); - // sort cards - this.onClickOnTogglePlayerHandSortButton(); - dojo.connect($(DOM_ID_PLAYER_HAND_TOGGLE_SORT_BUTTON), 'onclick', this, 'onClickOnTogglePlayerHandSortButton'); - - - // Setup currentPlayer cards dojo.connect(this.playerHand, 'onChangeSelection', this, (_, itemId) => { if (typeof itemId === 'undefined') { return; @@ -311,9 +316,18 @@ function (dojo, declare) { this.onPlayerCardUnselected(cardId); } }); - this.addCardsToPlayerHand(gamedatas.currentPlayerCards); + // sort cards + this.onClickOnTogglePlayerHandSortButton(); + dojo.connect($(DOM_ID_PLAYER_HAND_TOGGLE_SORT_BUTTON), 'onclick', this, 'onClickOnTogglePlayerHandSortButton'); + // setup currentPlayer cards + this.players[this.player_id].howManyCards = 0; + this.addCardsToPlayerHand( + (this.currentPlayerHasJersey && !this.jerseyHasBeenUsedInTheCurrentRound) + ? this.addJerseyToCards(gamedatas.currentPlayerCards) + : gamedatas.currentPlayerCards + ); - // Setup cards played on table + // setup cards played on table this.playedCardsValue = gamedatas.playedCardsValue; this.setupPreviousPlayedCards( (gamedatas.previousPlayedCardsValue === (this.getCardsValue(gamedatas.previousPlayedCards) + VALUE_JERSEY)) @@ -327,25 +341,13 @@ function (dojo, declare) { : gamedatas.playedCards ); - // Setup jersey - if (gamedatas.jerseyHasBeenUsedInTheCurrentRound) { - this.useJerseyForCurrentRound(); - } else { - this.restoreJerseyForCurrentRound(); - } - this.moveJerseyToCurrentWinner(); - if ( - this.currentPlayerHasJersey - && !this.jerseyHasBeenUsedInTheCurrentRound - ) { - this.addJerseyToPlayerHand(); - } - - // Setup extra info + // setup players score this.setupPlayersScore(); + + // setup rounds info this.setupRoundsInfo(); - // Setup game notifications to handle + // handle game notifications this.setupNotifications(); }, @@ -357,20 +359,24 @@ function (dojo, declare) { switch (state) { case 'firstPlayerTurn': case 'playerTurn': - // show active player dojo.addClass(`player-table-${data.args.activePlayerId}`, DOM_CLASS_ACTIVE_PLAYER); break; case 'playerSelectNextPlayer': + dojo.addClass(`player-table-${data.args.activePlayerId}`, DOM_CLASS_ACTIVE_PLAYER); + this.setupSelectPlayerAction(data.args.activePlayerId, data.args.selectablePlayers, this.onSelectNextPlayer); break; case 'playerSelectWhoTakeAttackReward': + dojo.addClass(`player-table-${data.args.activePlayerId}`, DOM_CLASS_ACTIVE_PLAYER); + this.setupSelectPlayerAction(data.args.activePlayerId, data.args.selectablePlayers, this.onSelectWhoTakeAttackReward); break; case 'playerSelectPlayerToPickCards': + dojo.addClass(`player-table-${data.args.activePlayerId}`, DOM_CLASS_ACTIVE_PLAYER); + this.setupSelectPlayerAction(data.args.activePlayerId, data.args.selectablePlayers, this.onSelectPlayerToPickCards); break; case 'playerGiveCardsBackAfterPicking': - // show active player dojo.addClass(`player-table-${data.args.activePlayerId}`, DOM_CLASS_ACTIVE_PLAYER); this.howManyCardsToGiveBack = data.args.numberOfCards; @@ -378,10 +384,8 @@ function (dojo, declare) { } }, onLeavingState: function (state) { - // hide active player dojo.query(`.${DOM_CLASS_PLAYER_TABLE}`).removeClass(DOM_CLASS_ACTIVE_PLAYER); - // do special things for state switch (state) { case 'playerSelectNextPlayer': case 'playerSelectWhoTakeAttackReward': @@ -406,6 +410,7 @@ function (dojo, declare) { return; } + this.currentState = state; switch (state) { case 'firstPlayerTurn': this.setupPlayCardsActionButton(); @@ -543,10 +548,23 @@ function (dojo, declare) { $(DOM_ID_CURRENT_ROUND).innerHTML = `${this.currentRound} / ${this.howManyRounds}`; }, setupNumberOfCardsInPlayersHand: function () { + const getCardRotateDeg = (numberOfCards, i) => { + if (numberOfCards === 1) { + return 0; + } + + const offset = numberOfCards * 2; + + return offset + ((i * -1) * 5); + }; Object.entries(this.players).forEach((entry) => { const player = entry[1]; - $(`player-table-${player.id}-number-of-cards`).innerHTML = player.howManyCards; + const playerCardsHtml = []; + for (let i = 0; i < player.howManyCards; i++) { + playerCardsHtml.push(`
`); + } + $(`player-table-${player.id}-hand-cards`).innerHTML = playerCardsHtml.join(''); }); }, setupPlayersScore: function () { @@ -558,10 +576,78 @@ function (dojo, declare) { } }); }, + setupPlayersFinishPosition: function () { + Object.entries(this.players).forEach((entry) => { + const player = entry[1]; + + const playerCurrentRoundRank = this.getCurrentRoundRankFromPlayerRoundsRanking(player.roundsRanking || {}); + dojo.removeClass(`player-table-${player.id}`, `has-finished-1`); + dojo.removeClass(`player-table-${player.id}`, `has-finished-2`); + dojo.removeClass(`player-table-${player.id}`, `has-finished-3`); + if (playerCurrentRoundRank) { + dojo.addClass(`player-table-${player.id}`, `has-finished-${playerCurrentRoundRank}`); + } + }); + }, + setupPlayCardsActionButtonIfNeeded: function () { + if ( + this.isCurrentPlayerActive() + && ( + this.currentState === 'firstPlayerTurn' + || this.currentState === 'playerTurn' + ) + && this.currentPlayerCanPlayCards() + ) { + this.setupPlayCardsActionButton(); + } + }, + setupPlayCardsActionButton: function () { + const selectedCards = this.getSelectedPlayerCards(); + const selectedCardsValue = this.getCardsValue(selectedCards); + + // setup play cards button + if (!$(DOM_ID_ACTION_BUTTON_PLAY_CARDS)) { + 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})`; + }, /** - * @param {number?} currentJerseyWearerId + * + * @param {number} activePlayerId + * @param {Object[]} selectablePlayers Indexed by playerId. + * @param {function(number)} onClickOnActionButton The function arg is the selected playerId. */ - moveJerseyToCurrentWinner: function (currentJerseyWearerId) { + setupSelectPlayerAction: function (activePlayerId, selectablePlayers, onClickOnActionButton) { + if (this.isCurrentPlayerActive()) { + Object.entries(selectablePlayers).forEach((entry) => { + const player = entry[1]; + + // setup click on player tables + dojo.addClass(`player-table-${player.id}`, DOM_CLASS_SELECTABLE_PLAYER); + this.connect($(`player-table-${player.id}`), 'onclick', () => onClickOnActionButton.bind(this)(player.id)); + + // setup click on action buttons + this.addActionButton(`${DOM_ID_ACTION_BUTTON_SELECT_PLAYER}-${player.id}`, player.name, () => onClickOnActionButton.bind(this)(player.id), null, false, 'gray'); + dojo.style(`${DOM_ID_ACTION_BUTTON_SELECT_PLAYER}-${player.id}`, 'color', `#${player.color}`); + }); + } + }, + setupGiveCardsBackAfterPickingActionButton: function () { + this.setupPlayerHandSelectableCards(); + + const selectedCards = this.getSelectedPlayerCards(); + if (!$(DOM_ID_ACTION_BUTTON_GIVE_CARDS)) { + this.addActionButton(DOM_ID_ACTION_BUTTON_GIVE_CARDS, _('Give selected cards'), 'onSelectCardsToGiveBack'); + } + dojo.toggleClass(DOM_ID_ACTION_BUTTON_GIVE_CARDS, DOM_CLASS_DISABLED_ACTION_BUTTON, (selectedCards.length === 0) || (selectedCards.length !== this.howManyCardsToGiveBack)); + }, + /** + * @param {number|undefined} [previousJerseyWearerId] + */ + moveJerseyToCurrentWinner: function (previousJerseyWearerId) { Object.entries(this.players).forEach((entry) => { const player = entry[1]; const isCurrentPlayer = this.player_id === player.id; @@ -570,13 +656,13 @@ function (dojo, declare) { this.currentPlayerHasJersey = isCurrentPlayer; if (!dojo.hasClass(`player-table-${player.id}`, DOM_CLASS_PLAYER_IS_WEARING_JERSEY)) { - if (currentJerseyWearerId) { + if (previousJerseyWearerId) { // move jersey from player A to player B, // then add isWearingJersey class to player B at the end of the animation const animation = this.slideTemporaryObject( `
`, - `player-table-${currentJerseyWearerId}-jersey`, - `player-table-${currentJerseyWearerId}-jersey`, + `player-table-${previousJerseyWearerId}-jersey`, + `player-table-${previousJerseyWearerId}-jersey`, `player-table-${player.id}-jersey` ); dojo.connect(animation, 'onEnd', () => dojo.addClass(`player-table-${player.id}`, DOM_CLASS_PLAYER_IS_WEARING_JERSEY)); @@ -589,10 +675,6 @@ 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(); - } } }); }, @@ -633,66 +715,16 @@ function (dojo, declare) { } }); }, - setupPlayCardsActionButtonIfNeeded: function () { - if ( - this.isCurrentPlayerActive() - && ( - this.currentState === 'firstPlayerTurn' - || this.currentState === 'playerTurn' - ) - && this.currentPlayerCanPlayCards() - ) { - this.setupPlayCardsActionButton(); - } - }, - setupPlayCardsActionButton: function () { - const selectedCards = this.getSelectedPlayerCards(); - const selectedCardsValue = this.getCardsValue(selectedCards); - - // setup play cards button - if (!$(DOM_ID_ACTION_BUTTON_PLAY_CARDS)) { - 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})`; - }, /** - * - * @param {number} activePlayerId - * @param {Object[]} selectablePlayers Indexed by playerId. - * @param {function(number)} onClickOnActionButton The function arg is the selected playerId. + * @param {Object} roundsRanking + * @returns {number|undefined} */ - setupSelectPlayerAction: function (activePlayerId, selectablePlayers, onClickOnActionButton) { - if (this.isCurrentPlayerActive()) { - // hide active player state for active player - dojo.removeClass(`player-table-${activePlayerId}`, DOM_CLASS_ACTIVE_PLAYER); - - Object.entries(selectablePlayers).forEach((entry) => { - const player = entry[1]; - - // setup click on player tables - dojo.addClass(`player-table-${player.id}`, DOM_CLASS_SELECTABLE_PLAYER); - this.connect($(`player-table-${player.id}`), 'onclick', () => onClickOnActionButton.bind(this)(player.id)); - - // setup click on action buttons - this.addActionButton(`${DOM_ID_ACTION_BUTTON_SELECT_PLAYER}-${player.id}`, player.name, () => onClickOnActionButton.bind(this)(player.id), null, false, 'gray'); - dojo.style(`${DOM_ID_ACTION_BUTTON_SELECT_PLAYER}-${player.id}`, 'color', `#${player.color}`); - }); - } else { - // show active player for other players - dojo.addClass(`player-table-${activePlayerId}`, DOM_CLASS_ACTIVE_PLAYER); + getCurrentRoundRankFromPlayerRoundsRanking: function (roundsRanking) { + if (!roundsRanking[this.currentRound]) { + return undefined; } - }, - setupGiveCardsBackAfterPickingActionButton: function () { - this.setupPlayerHandSelectableCards(); - const selectedCards = this.getSelectedPlayerCards(); - if (!$(DOM_ID_ACTION_BUTTON_GIVE_CARDS)) { - this.addActionButton(DOM_ID_ACTION_BUTTON_GIVE_CARDS, _('Give selected cards'), 'onSelectCardsToGiveBack'); - } - dojo.toggleClass(DOM_ID_ACTION_BUTTON_GIVE_CARDS, DOM_CLASS_DISABLED_ACTION_BUTTON, (selectedCards.length === 0) || (selectedCards.length !== this.howManyCardsToGiveBack)); + return roundsRanking[this.currentRound]; }, /** * @param {function (number, number)} fn such as (color, value) => {...} @@ -1204,9 +1236,9 @@ function (dojo, declare) { return [ ...acc, // add highest color combination - [card, ...cardsThatCanBePlayedWithCard].filter((c) => c.color === card.color).sort(sortCardsById), + [card, ...cardsThatCanBePlayedWithCard].filter((c) => c.color === card.color || c.id === CARD_ID_JERSEY).sort(sortCardsById), // add highest value combination - [card, ...cardsThatCanBePlayedWithCard].filter((c) => c.value === card.value).sort(sortCardsById), + [card, ...cardsThatCanBePlayedWithCard].filter((c) => c.value === card.value || c.id === CARD_ID_JERSEY).sort(sortCardsById), ]; }, []); @@ -1244,9 +1276,10 @@ function (dojo, declare) { return 0; } - // the jersey cannot be played with an adventurer - if (withJersey && cardsWithoutJersey.map((c) => c.color).includes(COLOR_ADVENTURER)) { - return 0; + // an adventurer is only playable solo (and without jersey) + const adventurer = cardsWithoutJersey.find((c) => c.color === COLOR_ADVENTURER); + if (adventurer) { + return adventurer.value; } const addJerseyValueIfUsed = (value) => value + (withJersey ? VALUE_JERSEY : 0); @@ -1273,9 +1306,7 @@ function (dojo, declare) { return false; } - const playerCanPlayJersey = this.currentPlayerHasJersey && !this.jerseyHasBeenUsedInTheCurrentRound; - - return this.playedCardsValue < (playerCardsCombinations[0].value + (playerCanPlayJersey ? VALUE_JERSEY : 0)); + return this.playedCardsValue < playerCardsCombinations[0].value; }, setupPlayerHandSelectableCards: function () { const selectedCards = this.getSelectedPlayerCards(); @@ -1407,12 +1438,18 @@ function (dojo, declare) { /** * @param {Object[]} cards * @param {string} domId + * @param {function(number)} [onBeforeFirstAnimation] + * @param {function(number)} [onAfterEachAnimation] */ - moveTemporaryCardsFromDomIdToPlayerHand: function (cards, domId) { + moveTemporaryCardsFromDomIdToPlayerHand: function (cards, domId, onBeforeFirstAnimation, onAfterEachAnimation) { if (cards.length <= 0) { return; } + if (typeof onBeforeFirstAnimation === 'function') { + onBeforeFirstAnimation.bind(this)(0); + } + let animations = []; for (let i = 0; i < cards.length; i++) { const position = this.getCardPositionInSpriteByColorAndValue(cards[i].color, cards[i].value); @@ -1426,10 +1463,9 @@ function (dojo, declare) { 1000, i * 1000 ); - dojo.connect(animations[i], 'onEnd', () => { - this.playerHand.addToStockWithId(position, cards[i].id); - this.setupPlayerHandSelectableCards(); - }); + if (typeof onAfterEachAnimation === 'function') { + dojo.connect(animations[i], 'onEnd', () => onAfterEachAnimation.bind(this)(i)); + } animations[i].play(); } }, @@ -1437,17 +1473,32 @@ function (dojo, declare) { * @param {string} fromDomId * @param {string} toDomId * @param {number} numberOfCards + * @param {function(number)} [onBeforeFirstAnimation] + * @param {function(number)} [onAfterEachAnimation] */ - moveHiddenTemporaryCardsFromDomIdToDomId: function (fromDomId, toDomId, numberOfCards) { + moveHiddenTemporaryCardsFromDomIdToDomId: function (fromDomId, toDomId, numberOfCards, onBeforeFirstAnimation, onAfterEachAnimation) { + if (numberOfCards <= 0) { + return; + } + + if (typeof onBeforeFirstAnimation === 'function') { + onBeforeFirstAnimation.bind(this)(0); + } + + let animations = []; for (let i = 0; i < numberOfCards; i++) { - this.slideTemporaryObject( + animations[i] = this.slideTemporaryObject( `
`, fromDomId, fromDomId, toDomId, 1000, i * 1000 - ).play(); + ); + if (typeof onAfterEachAnimation === 'function') { + dojo.connect(animations[i], 'onEnd', () => onAfterEachAnimation.bind(this)(i)); + } + animations[i].play(); } }, /** @@ -1456,7 +1507,20 @@ function (dojo, declare) { * @param {Object[]} cards */ moveCardsFromDeckToPlayerHand: function (cards) { - this.moveTemporaryCardsFromDomIdToPlayerHand(cards, DOM_ID_CARDS_DECK); + this.moveTemporaryCardsFromDomIdToPlayerHand( + cards, + DOM_ID_CARDS_DECK, + () => { + this.decreaseNumberOfCardsInDeck(1); + }, + (animationIndex) => { + if ((animationIndex + 1) < cards.length) { + this.decreaseNumberOfCardsInDeck(1); + } + + this.addCardsToPlayerHand([cards[animationIndex]]); + } + ); }, /** * /!\ 2P mode only @@ -1465,7 +1529,21 @@ function (dojo, declare) { * @param {number} numberOfCards */ moveCardsFromDeckToAnotherPlayer: function (receiverId, numberOfCards) { - this.moveHiddenTemporaryCardsFromDomIdToDomId(DOM_ID_CARDS_DECK, `player-table-${receiverId}-hand`, numberOfCards); + this.moveHiddenTemporaryCardsFromDomIdToDomId( + DOM_ID_CARDS_DECK, + `player-table-${receiverId}-hand`, + numberOfCards, + () => { + this.decreaseNumberOfCardsInDeck(1); + }, + (animationIndex) => { + if ((animationIndex + 1) < numberOfCards) { + this.decreaseNumberOfCardsInDeck(1); + } + + this.increaseNumberOfCardsOfPlayer(receiverId, 1); + } + ); }, /** * /!\ 2P mode only @@ -1536,7 +1614,8 @@ function (dojo, declare) { dojo.connect(animation, 'onEnd', () => { if (receiverPlayerId === this.player_id) { this.addCardsToPlayerHand(cards); - this.setupPlayerHandSelectableCards(); + } else { + this.increaseNumberOfCardsOfPlayer(receiverPlayerId, cards.length); } this.fadeOutAndDestroy(rewardCardDomId); }); @@ -1573,6 +1652,11 @@ function (dojo, declare) { // place cards from where the animation will start if (playerId !== this.player_id) { this.placeOnObject(`cards-stack-${topOfStackCardId}`, `player-table-${playerId}-hand`); + cards.forEach((card) => { + if (card.id !== CARD_ID_JERSEY) { + this.decreaseNumberOfCardsOfPlayer(playerId, 1); + } + }); } else if ($(`${DOM_ID_PLAYER_HAND}_item_${topOfStackCardId}`)) { this.placeOnObject(`cards-stack-${topOfStackCardId}`, `${DOM_ID_PLAYER_HAND}_item_${topOfStackCardId}`); cards.forEach((card) => { @@ -1592,7 +1676,20 @@ function (dojo, declare) { * @param {Object[]} cards */ receiveCardsFromAnotherPlayer: function (senderId, cards) { - this.moveTemporaryCardsFromDomIdToPlayerHand(cards, `player-table-${senderId}-hand`); + this.moveTemporaryCardsFromDomIdToPlayerHand( + cards, + `player-table-${senderId}-hand`, + () => { + this.decreaseNumberOfCardsOfPlayer(senderId, 1); + }, + (animationIndex) => { + if ((animationIndex + 1) < cards.length) { + this.decreaseNumberOfCardsOfPlayer(senderId, 1); + } + + this.addCardsToPlayerHand([cards[animationIndex]]); + } + ); }, /** * @param {number} receiverId @@ -1616,6 +1713,8 @@ function (dojo, declare) { } }); + this.removeCardFromPlayerHand(sortedCards[0].id); + let animations = []; for (let i = 0; i < sortedCards.length; i++) { const position = this.getCardPositionInSpriteByColorAndValue(sortedCards[i].color, sortedCards[i].value); @@ -1638,10 +1737,11 @@ function (dojo, declare) { if (i + 1 === sortedCards.length) { this.sortPlayerCardsByCurrentSortingMode(); } + + this.increaseNumberOfCardsOfPlayer(receiverId, 1); }); animations[i].play(); } - this.removeCardFromPlayerHand(sortedCards[0].id); }, /** * @param {number} senderId @@ -1649,7 +1749,21 @@ function (dojo, declare) { * @param {number} numberOfCards */ moveCardsBetweenTwoOtherPlayers: function (senderId, receiverId, numberOfCards) { - this.moveHiddenTemporaryCardsFromDomIdToDomId(`player-table-${senderId}-hand`, `player-table-${receiverId}-hand`, numberOfCards); + this.moveHiddenTemporaryCardsFromDomIdToDomId( + `player-table-${senderId}-hand`, + `player-table-${receiverId}-hand`, + numberOfCards, + () => { + this.decreaseNumberOfCardsOfPlayer(senderId, 1); + }, + (animationIndex) => { + if ((animationIndex + 1) < numberOfCards) { + this.decreaseNumberOfCardsOfPlayer(senderId, 1); + } + + this.increaseNumberOfCardsOfPlayer(receiverId, 1); + } + ); }, /** * @param {number} playerId @@ -1665,7 +1779,9 @@ function (dojo, declare) { * @param {number} numberOfCards */ decreaseNumberOfCardsOfPlayer: function (playerId, numberOfCards) { - this.players[playerId].howManyCards = this.players[playerId].howManyCards - numberOfCards; + if (this.players[playerId].howManyCards > 0) { + this.players[playerId].howManyCards = this.players[playerId].howManyCards - numberOfCards; + } this.setupNumberOfCardsInPlayersHand(); }, @@ -1674,16 +1790,29 @@ function (dojo, declare) { */ addCardsToPlayerHand: function (cards) { cards.forEach((card) => { + if (card.id !== CARD_ID_JERSEY) { + this.increaseNumberOfCardsOfPlayer(this.player_id, 1); + } this.playerHand.addToStockWithId(this.getCardPositionInSpriteByColorAndValue(card.color, card.value), card.id); + this.setupPlayerHandSelectableCards(); }); }, - addJerseyToPlayerHand: function () { - const cards = this.getAllPlayerCards(); - if (cards.map((c) => c.id).includes(CARD_ID_JERSEY)) { - return; - } + /** + * @param {number} cardId + */ + removeCardFromPlayerHand: function (cardId) { + this.cardsGroups.forEach((group) => { + if (group.cards.map((c) => c.id).includes(cardId)) { + this.removeCardsGroup(group.id); + } + }); + this.setupGroupCardsButton(); - this.playerHand.addToStockWithId(this.getCardPositionInSpriteByColorAndValue(COLOR_JERSEY, VALUE_JERSEY), CARD_ID_JERSEY); + this.playerHand.removeFromStockById(cardId); + if (cardId !== CARD_ID_JERSEY) { + this.decreaseNumberOfCardsOfPlayer(this.player_id, 1); + } + this.setupPlayerHandSelectableCards(); }, /** * @param {Object[]} cards @@ -1696,14 +1825,6 @@ function (dojo, declare) { ) ); }, - removeJerseyFromPlayerHand: function () { - const cards = this.getAllPlayerCards(); - if (!cards.map((c) => c.id).includes(CARD_ID_JERSEY)) { - return; - } - - this.removeCardFromPlayerHand(CARD_ID_JERSEY); - }, movePlayedCardsToPreviousPlayedCards: function () { dojo.query(`.${DOM_CLASS_CARDS_STACK_PREVIOUS_PLAYED}`).forEach(this.fadeOutAndDestroy); dojo.query(`#${DOM_ID_LAST_PLAYED_CARDS} .${DOM_CLASS_CARDS_STACK}`).forEach((elementDomId) => { @@ -1878,24 +1999,6 @@ function (dojo, declare) { resetCurrentState: function () { this.currentState = null; }, - removeAllCardsFromPlayerHand: function () { - this.playerHand.removeAll(); - this.resetCardsGroups(); - }, - /** - * @param {number} cardId - */ - removeCardFromPlayerHand: function (cardId) { - this.cardsGroups.forEach((group) => { - if (group.cards.map((c) => c.id).includes(cardId)) { - this.removeCardsGroup(group.id); - } - }); - this.setupGroupCardsButton(); - - this.playerHand.removeFromStockById(cardId); - this.setupPlayerHandSelectableCards(); - }, /** * @param {Object[]} cardsA * @param {Object[]} cardsB @@ -2101,14 +2204,15 @@ function (dojo, declare) { /////////////////////////////////////////////////// setupNotifications: function () { [ - ['cardsDealt', 1], ['roundStarted', 1], + ['roundEnded', 1], + ['cardsDealt', 1], ['cardsPlayed', 1000], + ['playerHasFinishedRound', 1], ['playedCardsDiscarded', 1], - ['cardsReceivedFromAnotherPlayer', 1000], - ['cardsSentToAnotherPlayer', 1000], - ['cardsMovedBetweenTwoOtherPlayers', 1000, (notif) => (notif.args.receiverPlayerId === this.player_id || notif.args.senderPlayerId === this.player_id)], - ['roundEnded', 1], + ['cardsReceivedFromAnotherPlayer', this.isReadOnly() ? 3000 : 1500], + ['cardsSentToAnotherPlayer', this.isReadOnly() ? 3000 : 1500], + ['cardsMovedBetweenTwoOtherPlayers', this.isReadOnly() ? 2000 : 1500, (notif) => (notif.args.receiverPlayerId === this.player_id || notif.args.senderPlayerId === this.player_id)], // /!\ 2P mode only ['attackRewardCardsDiscarded', 1], // /!\ 2P mode only @@ -2116,9 +2220,9 @@ function (dojo, declare) { // /!\ 2P mode only ['attackRewardCardsRevealed', 1000], // /!\ 2P mode only - ['cardsReceivedFromDeck', 1000], + ['cardsReceivedFromDeck', this.isReadOnly() ? 2000 : 1000], // /!\ 2P mode only - ['cardsMovedFromDeckToAnotherPlayer', 1000, (notif) => notif.args.receiverPlayerId === this.player_id], + ['cardsMovedFromDeckToAnotherPlayer', this.isReadOnly() ? 2000 : 1500, (notif) => notif.args.receiverPlayerId === this.player_id], ].forEach((notif) => { const name = notif[0]; const lockDurationInMs = notif[1]; @@ -2133,15 +2237,13 @@ function (dojo, declare) { }); }, notif_cardsDealt: function (data) { - this.removeAllCardsFromPlayerHand(); - this.addCardsToPlayerHand(data.args.cards); - if ( - this.currentPlayerHasJersey - && !this.jerseyHasBeenUsedInTheCurrentRound - ) { - this.addJerseyToPlayerHand(); - } - this.setupPlayerHandSelectableCards(); + this.playerHand.removeAll(); + this.resetCardsGroups(); + this.players[this.player_id].howManyCards = 0; + this.addCardsToPlayerHand((this.currentPlayerHasJersey && !this.jerseyHasBeenUsedInTheCurrentRound) + ? this.addJerseyToCards(data.args.cards) + : data.args.cards + ); }, notif_roundStarted: function (data) { this.currentRound = data.args.currentRound; @@ -2149,9 +2251,12 @@ function (dojo, declare) { this.players = data.args.players; this.setupNumberOfCardsInPlayersHand(); + this.setupPlayersFinishPosition(); - this.howManyCardsInDeck = data.args.numberOfCardsInDeck; - this.setupDeckOfCards(); + if (this.is2PlayersMode()) { + this.howManyCardsInDeck = data.args.numberOfCardsInDeck; + this.setupDeckOfCards(); + } }, notif_cardsPlayed: function (data) { this.discardPlayerSpeechBubbles(); @@ -2164,49 +2269,43 @@ function (dojo, declare) { : data.args.playedCards; this.moveCardsFromPlayerHandToTable(data.args.playedCardsPlayerId, playedCardsWithJersey); - // update number of cards in players hand - this.decreaseNumberOfCardsOfPlayer(data.args.playedCardsPlayerId, data.args.playedCards.length) - // update jersey state if it has been used if (data.args.withJersey) { this.useJerseyForCurrentRound(); } }, + notif_playerHasFinishedRound: function (data) { + this.players[data.args.playerId].roundsRanking = data.args.roundsRanking; + this.setupPlayersFinishPosition(); + }, notif_playedCardsDiscarded: function (data) { this.discardPlayerSpeechBubbles(); this.discardPlayedCards(); }, notif_cardsReceivedFromAnotherPlayer: function (data) { - this.decreaseNumberOfCardsOfPlayer(data.args.senderPlayerId, data.args.cards.length); - this.receiveCardsFromAnotherPlayer(data.args.senderPlayerId, data.args.cards); - - this.increaseNumberOfCardsOfPlayer(this.player_id, data.args.cards.length); }, notif_cardsSentToAnotherPlayer: function (data) { - this.decreaseNumberOfCardsOfPlayer(this.player_id, data.args.cards.length); - this.sendCardsToAnotherPlayer(data.args.receiverPlayerId, data.args.cards); - - this.increaseNumberOfCardsOfPlayer(data.args.receiverPlayerId, data.args.cards.length); }, notif_cardsMovedBetweenTwoOtherPlayers: function (data) { - this.decreaseNumberOfCardsOfPlayer(data.args.senderPlayerId, data.args.numberOfCards); - this.moveCardsBetweenTwoOtherPlayers(data.args.senderPlayerId, data.args.receiverPlayerId, data.args.numberOfCards); - - this.increaseNumberOfCardsOfPlayer(data.args.receiverPlayerId, data.args.numberOfCards); }, notif_roundEnded: function (data) { - const currentJerseyWearerId = this.getCurrentJerseyWearerIdIfExists(); - this.players = data.args.players; - - this.setupPlayersScore(); - // restore and move jersey before the next round begin, // in order to have a beautiful jersey for the winner of the game (at the very end) + if ( + this.currentPlayerHasJersey + && !this.jerseyHasBeenUsedInTheCurrentRound + ) { + this.removeCardFromPlayerHand(CARD_ID_JERSEY); + } + const previousJerseyWearerId = this.getCurrentJerseyWearerIdIfExists(); + this.players = data.args.players; this.restoreJerseyForCurrentRound(); - this.moveJerseyToCurrentWinner(currentJerseyWearerId); + this.moveJerseyToCurrentWinner(previousJerseyWearerId); + + this.setupPlayersScore(); }, /** * /!\ 2P mode only @@ -2219,33 +2318,25 @@ function (dojo, declare) { */ notif_attackRewardCardsMovedToPlayer: function (data) { this.moveAttackRewardCardsToPlayer(data.args.receiverPlayerId, data.args.cards); - - this.increaseNumberOfCardsOfPlayer(data.args.receiverPlayerId, data.args.cards.length); }, /** * /!\ 2P mode only */ notif_attackRewardCardsRevealed: function (data) { - this.decreaseNumberOfCardsInDeck(data.args.cards.length); this.setupAttackRewardCards(data.args.cards); + this.decreaseNumberOfCardsInDeck(data.args.cards.length); }, /** * /!\ 2P mode only */ notif_cardsReceivedFromDeck: function (data) { this.moveCardsFromDeckToPlayerHand(data.args.cards); - - this.decreaseNumberOfCardsInDeck(data.args.numberOfCards); - this.increaseNumberOfCardsOfPlayer(this.player_id, data.args.numberOfCards); }, /** * /!\ 2P mode only */ notif_cardsMovedFromDeckToAnotherPlayer: function (data) { this.moveCardsFromDeckToAnotherPlayer(data.args.receiverPlayerId, data.args.numberOfCards); - - this.decreaseNumberOfCardsInDeck(data.args.numberOfCards); - this.increaseNumberOfCardsOfPlayer(data.args.receiverPlayerId, data.args.numberOfCards); }, }); });