From 646bf58941444789f00b6554a6526256b585d4c1 Mon Sep 17 00:00:00 2001 From: Oliboy50 Date: Sat, 6 Aug 2022 12:34:32 +0200 Subject: [PATCH] feat(logs): add cards image in log --- modules/constants.inc.php | 3 ++ velonimo.css | 12 +++++++ velonimo.game.php | 57 ++++++++++++++++++++----------- velonimo.js | 72 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 123 insertions(+), 21 deletions(-) diff --git a/modules/constants.inc.php b/modules/constants.inc.php index 2e6e1e6..6da2e2c 100644 --- a/modules/constants.inc.php +++ b/modules/constants.inc.php @@ -46,3 +46,6 @@ define('VALUE_45', 45); define('VALUE_50', 50); define('VALUE_JERSEY', 10); + +// Special cards ID +define('CARD_ID_JERSEY', 0); diff --git a/velonimo.css b/velonimo.css index 1eaf69c..c5a46b9 100644 --- a/velonimo.css +++ b/velonimo.css @@ -419,3 +419,15 @@ Animations /** END Animations */ + +/** +Log HTML + */ +.log .velonimo-card { + display: inline-block; + vertical-align: bottom; + border-radius: 0; +} +/** +END Log HTML + */ diff --git a/velonimo.game.php b/velonimo.game.php index f640265..3541cf2 100644 --- a/velonimo.game.php +++ b/velonimo.game.php @@ -348,9 +348,12 @@ function playCards(array $playedCardIds, bool $cardsPlayedWithJersey) { 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('${player_name} plays ${playedCardsValue}'), [ + self::notifyAllPlayers('cardsPlayed', clienttranslate('${player_name} attacks with ${cardsImage}'), [ 'playedCardsPlayerId' => $currentPlayerId, - 'playedCards' => $this->formatCardsForClient($playedCards), + 'playedCards' => $formattedCards = $this->formatCardsForClient($playedCards), + 'cardsImage' => $cardsPlayedWithJersey + ? array_merge([$this->formatJerseyForClient()], $formattedCards) + : $formattedCards, 'player_name' => self::getCurrentPlayerName(), 'playedCardsValue' => $playedCardsValue, 'withJersey' => $cardsPlayedWithJersey, @@ -384,16 +387,17 @@ function playCards(array $playedCardIds, bool $cardsPlayedWithJersey) { $this->deck->pickCards($numberOfPlayedCardsOfValueTwo, self::CARD_LOCATION_DECK, $currentPlayer->getId()) ); $numberOfCurrentPlayerCards = $numberOfCurrentPlayerCards + $numberOfCardsToPickFromDeck; - $translatedMessage = clienttranslate('${player_name} picks ${numberOfCards} card(s) from the top of the deck'); - self::notifyAllPlayers('cardsMovedFromDeckToAnotherPlayer', $translatedMessage, [ + self::notifyAllPlayers('cardsMovedFromDeckToAnotherPlayer', clienttranslate('${player_name} picks ${numberOfCards} card(s) from the deck'), [ 'receiverPlayerId' => $currentPlayer->getId(), 'numberOfCards' => $numberOfCardsToPickFromDeck, 'player_name' => $currentPlayer->getName(), ]); + $translatedMessage = clienttranslate('${player_name} picks ${cardsImage} from the deck'); foreach ($players as $player) { if ($player->getId() === $currentPlayer->getId()) { self::notifyPlayer($currentPlayer->getId(), 'cardsReceivedFromDeck', $translatedMessage, [ - 'cards' => $this->formatCardsForClient($cardsPickedFromDeck), + 'cards' => $formattedCards = $this->formatCardsForClient($cardsPickedFromDeck), + 'cardsImage' => $formattedCards, 'numberOfCards' => $numberOfCardsToPickFromDeck, 'player_name' => $currentPlayer->getName(), ]); @@ -527,12 +531,13 @@ function selectWhoTakeAttackReward(int $selectedPlayerId) { // notify players if ($currentPlayer->getId() === $selectedPlayer->getId()) { - $translatedMessage = clienttranslate('${player_name} takes the attacker reward'); + $translatedMessage = clienttranslate('${player_name} takes the attacker reward ${cardsImage}'); } else { - $translatedMessage = clienttranslate('${player_name} gives the attacker reward to ${player_name2}'); + $translatedMessage = clienttranslate('${player_name} gives the attacker reward ${cardsImage} to ${player_name2}'); } self::notifyAllPlayers('attackRewardCardsMovedToPlayer', $translatedMessage, [ - 'cards' => $this->formatCardsForClient($rewardCards), + 'cards' => $formattedCards = $this->formatCardsForClient($rewardCards), + 'cardsImage' => $formattedCards, 'receiverPlayerId' => $selectedPlayer->getId(), 'player_name' => $currentPlayer->getName(), 'player_name2' => $selectedPlayer->getName(), @@ -590,18 +595,19 @@ function selectPlayerToPickCards(int $selectedPlayerId) { // notify players $formattedPickedCards = $this->formatCardsForClient($pickedCards); - $translatedMessage = clienttranslate('${player_name} picks ${numberOfCards} card(s) from ${player_name2} hand'); - self::notifyAllPlayers('cardsMovedBetweenTwoOtherPlayers', $translatedMessage, [ + self::notifyAllPlayers('cardsMovedBetweenTwoOtherPlayers', clienttranslate('${player_name} picks ${numberOfCards} card(s) from ${player_name2} hand'), [ 'receiverPlayerId' => $currentPlayer->getId(), 'senderPlayerId' => $selectedPlayer->getId(), 'numberOfCards' => $numberOfCardsToPick, 'player_name' => $currentPlayer->getName(), 'player_name2' => $selectedPlayer->getName(), ]); + $translatedMessage = clienttranslate('${player_name} picks ${cardsImage} from ${player_name2} hand'); foreach ($players as $player) { if ($player->getId() === $currentPlayer->getId()) { self::notifyPlayer($currentPlayer->getId(), 'cardsReceivedFromAnotherPlayer', $translatedMessage, [ 'cards' => $formattedPickedCards, + 'cardsImage' => $formattedPickedCards, 'senderPlayerId' => $selectedPlayer->getId(), 'numberOfCards' => $numberOfCardsToPick, 'player_name' => $currentPlayer->getName(), @@ -610,6 +616,7 @@ function selectPlayerToPickCards(int $selectedPlayerId) { } elseif ($player->getId() === $selectedPlayer->getId()) { self::notifyPlayer($selectedPlayer->getId(), 'cardsSentToAnotherPlayer', $translatedMessage, [ 'cards' => $formattedPickedCards, + 'cardsImage' => $formattedPickedCards, 'receiverPlayerId' => $currentPlayer->getId(), 'numberOfCards' => $numberOfCardsToPick, 'player_name' => $currentPlayer->getName(), @@ -674,18 +681,19 @@ function selectCardsToGiveBack(array $selectedCardIds) { // notify players $formattedSelectedCards = $this->formatCardsForClient($selectedCards); - $translatedMessage = clienttranslate('${player_name} gives back ${numberOfCards} card(s) to ${player_name2}'); - self::notifyAllPlayers('cardsMovedBetweenTwoOtherPlayers', $translatedMessage, [ + self::notifyAllPlayers('cardsMovedBetweenTwoOtherPlayers', clienttranslate('${player_name} gives back ${numberOfCards} card(s) to ${player_name2}'), [ 'receiverPlayerId' => $receiverPlayer->getId(), 'senderPlayerId' => $currentPlayer->getId(), 'numberOfCards' => $numberOfCardsToGiveBack, 'player_name2' => $receiverPlayer->getName(), 'player_name' => $currentPlayer->getName(), ]); + $translatedMessage = clienttranslate('${player_name} gives back ${cardsImage} to ${player_name2}'); foreach ($players as $player) { if ($player->getId() === $currentPlayer->getId()) { self::notifyPlayer($currentPlayer->getId(), 'cardsSentToAnotherPlayer', $translatedMessage, [ 'cards' => $formattedSelectedCards, + 'cardsImage' => $formattedSelectedCards, 'receiverPlayerId' => $receiverPlayer->getId(), 'numberOfCards' => $numberOfCardsToGiveBack, 'player_name2' => $receiverPlayer->getName(), @@ -694,6 +702,7 @@ function selectCardsToGiveBack(array $selectedCardIds) { } elseif ($player->getId() === $receiverPlayer->getId()) { self::notifyPlayer($receiverPlayer->getId(), 'cardsReceivedFromAnotherPlayer', $translatedMessage, [ 'cards' => $formattedSelectedCards, + 'cardsImage' => $formattedSelectedCards, 'senderPlayerId' => $currentPlayer->getId(), 'numberOfCards' => $numberOfCardsToGiveBack, 'player_name2' => $receiverPlayer->getName(), @@ -817,7 +826,7 @@ function stStartRound() { self::activeNextPlayer(); } - self::notifyAllPlayers('roundStarted', 'Round #${currentRound} starts', [ + self::notifyAllPlayers('roundStarted', clienttranslate('Round #${currentRound} starts'), [ 'currentRound' => $newRound, 'players' => $this->formatPlayersForClient($players), 'numberOfCardsInDeck' => $this->getNumberOfCardsInDeck(), @@ -919,18 +928,17 @@ 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', 'Round #${currentRound} has been won by ${player_name}', [ + self::notifyAllPlayers('roundEnded', clienttranslate('Round #${currentRound} has been won by ${player_name}'), [ 'currentRound' => $currentRound, 'player_name' => $winnerOfCurrentRound ? $winnerOfCurrentRound->getName() : 'N/A', 'players' => $this->formatPlayersForClient($players), ]); // notify points earned by each player + $translatedMessageForPoints = clienttranslate('${player_name} wins ${points} point(s)'); + $translatedMessageForNoPoints = clienttranslate('${player_name} does not get any point'); foreach ($players as $player) { - $translatedMessage = ($numberOfPointsForRoundByPlayerId[$player->getId()] > 0) - ? clienttranslate('${player_name} wins ${points} point(s)') - : clienttranslate('${player_name} does not get any point'); - self::notifyAllPlayers('pointsWon', $translatedMessage, [ + self::notifyAllPlayers('pointsWon', ($numberOfPointsForRoundByPlayerId[$player->getId()] > 0) ? $translatedMessageForPoints : $translatedMessageForNoPoints, [ 'player_name' => $player->getName(), 'points' => $numberOfPointsForRoundByPlayerId[$player->getId()], ]); @@ -1089,6 +1097,14 @@ private function formatCardsForClient(array $cards): array { ); } + private function formatJerseyForClient(): array { + return [ + 'id' => CARD_ID_JERSEY, + 'color' => COLOR_JERSEY, + 'value' => VALUE_JERSEY, + ]; + } + /** * @param VelonimoCard[] $cards */ @@ -1359,12 +1375,13 @@ private function revealNewAttackRewardCardsIfEnoughCardsInDeck(): void { $this->deck->pickCardForLocation(self::CARD_LOCATION_DECK, self::CARD_LOCATION_ATTACK_REWARD); - self::notifyAllPlayers('attackRewardCardsRevealed', 'A new attack reward card is revealed', [ - 'cards' => $this->formatCardsForClient( + self::notifyAllPlayers('attackRewardCardsRevealed', clienttranslate('The best attacker reward is ${cardsImage}'), [ + 'cards' => $formattedCards = $this->formatCardsForClient( $this->fromBgaCardsToVelonimoCards( $this->deck->getCardsInLocation(self::CARD_LOCATION_ATTACK_REWARD) ) ), + 'cardsImage' => $formattedCards, ]); } } diff --git a/velonimo.js b/velonimo.js index afdfd2e..8e14960 100644 --- a/velonimo.js +++ b/velonimo.js @@ -429,6 +429,75 @@ function (dojo, declare) { /////////////////////////////////////////////////// //// Utility methods /////////////////////////////////////////////////// + /** + * @Override format_string_recursive BGA framework function + * @see https://en.doc.boardgamearena.com/BGA_Studio_Cookbook#Inject_images_and_styled_html_in_the_log + */ + format_string_recursive: function (log, args) { + try { + if (log && args && !args.processed) { + args.processed = true; + + for (let key in args) { + switch (key) { + case 'cardsImage': + args[key] = this.getLogHtmlForCards(args[key]); + break; + } + } + } + } catch (e) { + console.error("Custom format_string_recursive thrown", log, args, e.stack); + } + return this.inherited(arguments); // equivalent to "super()" + }, + /** + * @param {Object[]} cards + * @returns string + */ + getLogHtmlForCards: function (cards) { + const getWidthForCard = (card) => { + if (card.color === COLOR_ADVENTURER) { + return 32; + } + if (card.color === COLOR_JERSEY) { + return 25; + } + return 17; + }; + const getBackgroundOffsetXForCard = (card) => { + if (card.color === COLOR_ADVENTURER) { + return 6; + } + if (card.value === VALUE_1) { + return 12; + } + if (card.value === VALUE_2) { + return 63; + } + if (card.value === VALUE_7) { + return 10; + } + if (card.color === COLOR_JERSEY) { + return 6; + } + return 11; + }; + const getBackgroundOffsetYForCard = (card) => { + if (card.color === COLOR_ADVENTURER) { + return 8; + } + return 7; + }; + + return this.sortPlayedCards(cards).map((card) => { + const position = this.getCardPositionInSpriteByColorAndValue(card.color, card.value); + const backgroundX = this.getAbsoluteCardBackgroundPositionXFromCardPosition(position) + getBackgroundOffsetXForCard(card); + const backgroundY = this.getAbsoluteCardBackgroundPositionYFromCardPosition(position) + getBackgroundOffsetYForCard(card); + + return `
`; + }).join(' '); + }, /** * @param {string} action * @param {Object} data @@ -1310,7 +1379,8 @@ function (dojo, declare) { cards.length <= 0 || !placeDomId ) { - return; + console.error(cards, placeDomId); + throw new Error(`buildAndPlacePlayedStackOfCards`); } const stackedCards = this.sortPlayedCards(cards);