diff --git a/img/game_banner.jpg b/img/game_banner.jpg index 0a5cd63..254da71 100644 Binary files a/img/game_banner.jpg and b/img/game_banner.jpg differ diff --git a/img/game_box.png b/img/game_box.png index 8cb409b..eb29ca0 100644 Binary files a/img/game_box.png and b/img/game_box.png differ diff --git a/img/game_box180.png b/img/game_box180.png index 074bda6..afde390 100644 Binary files a/img/game_box180.png and b/img/game_box180.png differ diff --git a/img/game_box75.png b/img/game_box75.png index a99d05b..b385bf3 100644 Binary files a/img/game_box75.png and b/img/game_box75.png differ diff --git a/img/publisher.png b/img/publisher.png index 52392b1..c86552e 100644 Binary files a/img/publisher.png and b/img/publisher.png differ diff --git a/states.inc.php b/states.inc.php index 3c1545d..22e6c2d 100644 --- a/states.inc.php +++ b/states.inc.php @@ -71,7 +71,7 @@ 'transitions' => ['firstPlayerTurn' => ST_FIRST_PLAYER_TURN], ], - // The first player of a round must play cards + // The first player must play cards ST_FIRST_PLAYER_TURN => [ 'name' => 'firstPlayerTurn', 'description' => clienttranslate('${actplayer} must play card(s)'), @@ -83,10 +83,11 @@ 'pickCardsFromAnotherPlayer' => ST_PLAYER_PICK_CARDS_FROM_PLAYER, 'nextPlayer' => ST_ACTIVATE_NEXT_PLAYER, 'endRound' => ST_END_ROUND, + 'zombiePass' => ST_ACTIVATE_NEXT_PLAYER, ], ], - // The next player must choose to play cards or pass + // The next players must choose to play cards or pass ST_PLAYER_TURN => [ 'name' => 'playerTurn', 'description' => clienttranslate('${actplayer} must play card(s) to beat ${playedCardsValue} or pass'), @@ -98,6 +99,7 @@ 'pickCardsFromAnotherPlayer' => ST_PLAYER_PICK_CARDS_FROM_PLAYER, 'nextPlayer' => ST_ACTIVATE_NEXT_PLAYER, 'endRound' => ST_END_ROUND, + 'zombiePass' => ST_ACTIVATE_NEXT_PLAYER, ], ], @@ -119,7 +121,10 @@ 'type' => 'activeplayer', 'args' => 'argPlayerSelectNextPlayer', 'possibleactions' => ['selectNextPlayer'], - 'transitions' => ['applySelectedNextPlayer' => ST_APPLY_SELECTED_NEXT_PLAYER], + 'transitions' => [ + 'applySelectedNextPlayer' => ST_APPLY_SELECTED_NEXT_PLAYER, + 'zombiePass' => ST_ACTIVATE_NEXT_PLAYER, + ], ], // Intermediate state to change the active player @@ -140,7 +145,10 @@ 'type' => 'activeplayer', 'args' => 'argPlayerSelectPlayerToPickCards', 'possibleactions' => ['selectPlayerToPickCards'], - 'transitions' => ['giveCardsBack' => ST_PLAYER_GIVE_CARDS_BACK_TO_PLAYER_AFTER_PICKING], + 'transitions' => [ + 'giveCardsBack' => ST_PLAYER_GIVE_CARDS_BACK_TO_PLAYER_AFTER_PICKING, + 'zombiePass' => ST_ACTIVATE_NEXT_PLAYER, + ], ], // After picking cards from another player's hand, @@ -152,7 +160,10 @@ 'type' => 'activeplayer', 'args' => 'argPlayerGiveCardsBackAfterPicking', 'possibleactions' => ['selectCardsToGiveBack'], - 'transitions' => ['nextPlayer' => ST_ACTIVATE_NEXT_PLAYER], + 'transitions' => [ + 'nextPlayer' => ST_ACTIVATE_NEXT_PLAYER, + 'zombiePass' => ST_ACTIVATE_NEXT_PLAYER, + ], ], // End round, count round points and give yellow jersey to the current winner diff --git a/velonimo.css b/velonimo.css index 9d35edc..dae2907 100644 --- a/velonimo.css +++ b/velonimo.css @@ -62,6 +62,7 @@ Board display: flex; align-items: center; justify-content: center; + min-width: 740px; } #game-info { diff --git a/velonimo.game.php b/velonimo.game.php index 4ff39d2..8325dab 100644 --- a/velonimo.game.php +++ b/velonimo.game.php @@ -245,11 +245,6 @@ function getGameProgression() { //////////// Player actions //////////////////////////////////////////////////////////////////////////// - /* - Each time a player is doing some game action, one of the methods below is called. - (note: each method below must match an input method in velonimo.action.php) - */ - /** * @param int[] $playedCardIds */ @@ -615,12 +610,6 @@ function selectCardsToGiveBack(array $selectedCardIds) { //////////// Game state arguments //////////////////////////////////////////////////////////////////////////// - /* - Here, you can create methods defined as "game state arguments" (see "args" property in states.inc.php). - These methods function is to return some additional information that is specific to the current - game state. - */ - function argFirstPlayerTurn() { return [ 'activePlayerId' => (int) self::getActivePlayerId(), @@ -680,11 +669,6 @@ function argPlayerGiveCardsBackAfterPicking() { //////////// Game state actions //////////////////////////////////////////////////////////////////////////// - /* - Here, you can create methods defined as "game state actions" (see "action" property in states.inc.php). - The action method of state X is called everytime the current game state is set to X. - */ - function stStartRound() { $this->discardPlayedCards(); // take back all cards and shuffle them @@ -891,33 +875,15 @@ function stEndRound() { //////////// Zombie //////////////////////////////////////////////////////////////////////////// - /* - zombieTurn: - - This method is called each time it is the turn of a player who has quit the game (= "zombie" player). - You can do whatever you want in order to make sure the turn of this player ends appropriately - (ex: pass). - - Important: your zombie code will be called when the player leaves the game. This action is triggered - from the main site and propagated to the gameserver from a server, not from a browser. - As a consequence, there is no current player associated to this action. In your zombieTurn function, - you must _never_ use getCurrentPlayerId() or getCurrentPlayerName(), otherwise it will fail with a "Not logged" error message. - */ - - function zombieTurn($state, $activePlayer) { - $statename = $state['name']; + function zombieTurn($state, $activePlayerId) { + $stateName = $state['name']; if ($state['type'] === 'activeplayer') { - switch ($statename) { - default: - $this->gamestate->nextState('zombiePass'); - break; - } - + $this->gamestate->nextState('zombiePass'); return; } - throw new feException('Zombie mode not supported at this game state: '.$statename); + throw new BgaVisibleSystemException('Zombie mode not supported at this game state: '.$stateName); } //////////////////////////////////////////////////////////////////////////// @@ -1055,7 +1021,7 @@ private function getPlayerById(int $playerId, array $players = null): VelonimoPl } } - throw new BgaVisibleSystemException(self::_('Player not found.')); + throw new BgaVisibleSystemException('Player not found.'); } /** diff --git a/velonimo.js b/velonimo.js index d253837..ac5f165 100644 --- a/velonimo.js +++ b/velonimo.js @@ -69,6 +69,7 @@ const DOM_ID_PLAYED_CARDS_WRAPPER = 'played-cards'; const DOM_ID_LAST_PLAYED_CARDS = 'last-played-cards'; const DOM_ID_PREVIOUS_LAST_PLAYED_CARDS = 'previous-last-played-cards'; const DOM_ID_PLAYER_HAND = 'my-hand'; +const DOM_ID_PLAYER_HAND_TITLE = 'my-hand-title'; 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'; @@ -107,8 +108,8 @@ 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 TABLE_STYLE_HORIZONTAL_CENTER = `left: ${(BOARD_CARPET_WIDTH / 2) - (PLAYER_TABLE_WIDTH / 2)}px;`; -const TABLE_STYLE_HORIZONTAL_MIDDLE_RIGHT = `right: ${BOARD_MARGIN + PLAYER_TABLE_WIDTH}px;`; -const TABLE_STYLE_HORIZONTAL_RIGHT = `right: ${BOARD_MARGIN}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;`; // 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 @@ -179,12 +180,10 @@ const PLAYERS_PLACES_BY_NUMBER_OF_PLAYERS = { }, }; -// @TODO: the cards picked/gave for the impacted players should be picked/gave consecutively (dojo.queue?) // @TODO: show cards in logs (especially the cards picked/gave for the impacted players) -// @TODO: update text when player cannot play (i.e. you have to pass) // @TODO: support 2 players game // @TODO: support "spectators" -// @TODO: support "zombie mode" +// @TODO: ? be more explicit when the player cannot beat the last played value (idea: disable its cards?) // @TODO: ? game rounds topology instead of choosing number of rounds define([ 'dojo','dojo/_base/declare', @@ -227,7 +226,7 @@ function (dojo, declare) {