Skip to content

Commit

Permalink
feat(interactable-players): interactable players with interactions fo…
Browse files Browse the repository at this point in the history
…r current game play (#644)

Closes #633
  • Loading branch information
antoinezanardi committed Nov 15, 2023
1 parent e230b3a commit 289b3f9
Show file tree
Hide file tree
Showing 8 changed files with 32,152 additions and 31,881 deletions.
30 changes: 1 addition & 29 deletions src/modules/game/helpers/game.helper.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import type { Types } from "mongoose";

import { VOTE_ACTIONS } from "@/modules/game/constants/game-play/game-play.constant";
import type { CreateGamePlayerDto } from "@/modules/game/dto/create-game/create-game-player/create-game-player.dto";
import type { CreateGameDto } from "@/modules/game/dto/create-game/create-game.dto";
import { GamePlayActions } from "@/modules/game/enums/game-play.enum";
import { PlayerAttributeNames, PlayerGroups } from "@/modules/game/enums/player.enum";
import { doesPlayerHaveActiveAttributeWithName } from "@/modules/game/helpers/player/player-attribute/player-attribute.helper";
import { createPlayer } from "@/modules/game/helpers/player/player.factory";
import type { GameAdditionalCard } from "@/modules/game/schemas/game-additional-card/game-additional-card.schema";
import type { Game } from "@/modules/game/schemas/game.schema";
import type { Player } from "@/modules/game/schemas/player/player.schema";
import type { GameSource, GetNearestPlayerOptions } from "@/modules/game/types/game.type";
import { RoleNames, RoleSides } from "@/modules/role/enums/role.enum";

import { createCantFindPlayerUnexpectedException, createNoCurrentGamePlayUnexpectedException } from "@/shared/exception/helpers/unexpected-exception.factory";
import { createCantFindPlayerUnexpectedException } from "@/shared/exception/helpers/unexpected-exception.factory";

function getPlayerDtoWithRole(game: CreateGameDto, role: RoleNames): CreateGamePlayerDto | undefined {
return game.players.find(player => player.role.name === role);
Expand Down Expand Up @@ -184,30 +181,6 @@ function getAllowedToVotePlayers(game: Game): Player[] {
return game.players.filter(player => player.isAlive && !doesPlayerHaveActiveAttributeWithName(player, PlayerAttributeNames.CANT_VOTE, game));
}

function getExpectedPlayersToPlay(game: Game): Player[] {
const { currentPlay } = game;
const mustIncludeDeadPlayersGamePlayActions = [GamePlayActions.SHOOT, GamePlayActions.BAN_VOTING, GamePlayActions.DELEGATE];
const voteActions: GamePlayActions[] = [...VOTE_ACTIONS];
let expectedPlayersToPlay: Player[] = [];
if (currentPlay === null) {
throw createNoCurrentGamePlayUnexpectedException("getExpectedPlayersToPlay", { gameId: game._id });
}
if (isGameSourceGroup(currentPlay.source.name)) {
expectedPlayersToPlay = getGroupOfPlayers(game, currentPlay.source.name);
} else if (isGameSourceRole(currentPlay.source.name)) {
expectedPlayersToPlay = getPlayersWithCurrentRole(game, currentPlay.source.name);
} else {
expectedPlayersToPlay = getPlayersWithActiveAttributeName(game, PlayerAttributeNames.SHERIFF);
}
if (!mustIncludeDeadPlayersGamePlayActions.includes(currentPlay.action)) {
expectedPlayersToPlay = expectedPlayersToPlay.filter(player => player.isAlive);
}
if (voteActions.includes(currentPlay.action)) {
expectedPlayersToPlay = expectedPlayersToPlay.filter(player => !doesPlayerHaveActiveAttributeWithName(player, PlayerAttributeNames.CANT_VOTE, game));
}
return expectedPlayersToPlay.map(player => createPlayer(player));
}

export {
getPlayerDtoWithRole,
getPlayerWithCurrentRole,
Expand Down Expand Up @@ -237,5 +210,4 @@ export {
getFoxSniffedPlayers,
getNearestAliveNeighbor,
getAllowedToVotePlayers,
getExpectedPlayersToPlay,
};
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { Injectable } from "@nestjs/common";

import { VOTE_ACTIONS } from "@/modules/game/constants/game-play/game-play.constant";
import { createPlayer } from "@/modules/game/helpers/player/player.factory";
import type { Player } from "@/modules/game/schemas/player/player.schema";
import { createGamePlayEligibleTargetsBoundaries } from "@/modules/game/helpers/game-play/game-play-eligible-targets/game-play-eligible-targets-boundaries/game-play-eligible-targets-boundaries.factory";
import { createInteractablePlayer } from "@/modules/game/helpers/game-play/game-play-eligible-targets/interactable-player/interactable-player.factory";
import { doesPlayerHaveActiveAttributeWithName } from "@/modules/game/helpers/player/player-attribute/player-attribute.helper";
import { GamePlayActions, GamePlayCauses, WitchPotions } from "@/modules/game/enums/game-play.enum";
import { PlayerAttributeNames, PlayerGroups, PlayerInteractionTypes } from "@/modules/game/enums/player.enum";
import { createGamePlayEligibleTargets } from "@/modules/game/helpers/game-play/game-play-eligible-targets/game-play-eligible-targets.factory";
import { createGamePlay } from "@/modules/game/helpers/game-play/game-play.factory";
import { getAlivePlayers, getAliveVillagerSidedPlayers, getAllowedToVotePlayers, getLeftToCharmByPiedPiperPlayers, getLeftToEatByWerewolvesPlayers, getLeftToEatByWhiteWerewolfPlayers } from "@/modules/game/helpers/game.helper";
import { getAlivePlayers, getAliveVillagerSidedPlayers, getAllowedToVotePlayers, getGroupOfPlayers, getLeftToCharmByPiedPiperPlayers, getLeftToEatByWerewolvesPlayers, getLeftToEatByWhiteWerewolfPlayers, getPlayersWithActiveAttributeName, getPlayersWithCurrentRole, isGameSourceGroup, isGameSourceRole } from "@/modules/game/helpers/game.helper";
import { GameHistoryRecordService } from "@/modules/game/providers/services/game-history/game-history-record.service";
import type { GamePlayEligibleTargetsBoundaries } from "@/modules/game/schemas/game-play/game-play-eligible-targets/game-play-eligible-targets-boundaries/game-play-eligible-targets-boundaries.schema";
import type { GamePlayEligibleTargets } from "@/modules/game/schemas/game-play/game-play-eligible-targets/game-play-eligible-targets.schema";
Expand All @@ -19,7 +22,7 @@ import type { GamePlaySourceName } from "@/modules/game/types/game-play.type";
import { WEREWOLF_ROLES } from "@/modules/role/constants/role.constant";
import { RoleNames } from "@/modules/role/enums/role.enum";

import { createCantFindLastNominatedPlayersUnexpectedException, createMalformedCurrentGamePlayUnexpectedException } from "@/shared/exception/helpers/unexpected-exception.factory";
import { createCantFindLastNominatedPlayersUnexpectedException, createMalformedCurrentGamePlayUnexpectedException, createNoCurrentGamePlayUnexpectedException } from "@/shared/exception/helpers/unexpected-exception.factory";

@Injectable()
export class GamePlayAugmenterService {
Expand Down Expand Up @@ -72,6 +75,12 @@ export class GamePlayAugmenterService {
return clonedGamePlay;
}

public setGamePlaySourcePlayers(gamePlay: GamePlay, game: Game): GamePlay {
const clonedGamePlay = createGamePlay(gamePlay);
clonedGamePlay.source.players = this.getExpectedPlayersToPlay(game);
return clonedGamePlay;
}

private async getSheriffSettlesVotesGamePlayEligibleTargets(game: Game): Promise<GamePlayEligibleTargets> {
const lastTieInVotesRecord = await this.gameHistoryRecordService.getLastGameHistoryTieInVotesRecord(game._id, GamePlayActions.VOTE);
if (lastTieInVotesRecord?.play.voting?.nominatedPlayers === undefined || lastTieInVotesRecord.play.voting.nominatedPlayers.length === 0) {
Expand Down Expand Up @@ -329,4 +338,28 @@ export class GamePlayAugmenterService {
}
return canBeSkippedGamePlayMethod(game, gamePlay);
}

private getExpectedPlayersToPlay(game: Game): Player[] {
const { currentPlay } = game;
const mustIncludeDeadPlayersGamePlayActions = [GamePlayActions.SHOOT, GamePlayActions.BAN_VOTING, GamePlayActions.DELEGATE];
const voteActions: GamePlayActions[] = [...VOTE_ACTIONS];
let expectedPlayersToPlay: Player[] = [];
if (currentPlay === null) {
throw createNoCurrentGamePlayUnexpectedException("getExpectedPlayersToPlay", { gameId: game._id });
}
if (isGameSourceGroup(currentPlay.source.name)) {
expectedPlayersToPlay = getGroupOfPlayers(game, currentPlay.source.name);
} else if (isGameSourceRole(currentPlay.source.name)) {
expectedPlayersToPlay = getPlayersWithCurrentRole(game, currentPlay.source.name);
} else {
expectedPlayersToPlay = getPlayersWithActiveAttributeName(game, PlayerAttributeNames.SHERIFF);
}
if (!mustIncludeDeadPlayersGamePlayActions.includes(currentPlay.action)) {
expectedPlayersToPlay = expectedPlayersToPlay.filter(player => player.isAlive);
}
if (voteActions.includes(currentPlay.action)) {
expectedPlayersToPlay = expectedPlayersToPlay.filter(player => !doesPlayerHaveActiveAttributeWithName(player, PlayerAttributeNames.CANT_VOTE, game));
}
return expectedPlayersToPlay.map(player => createPlayer(player));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { PlayerAttributeNames, PlayerGroups } from "@/modules/game/enums/player.
import { createGamePlay, createGamePlaySurvivorsElectSheriff, createGamePlaySurvivorsVote } from "@/modules/game/helpers/game-play/game-play.factory";
import { areGamePlaysEqual, canSurvivorsVote, findPlayPriorityIndex } from "@/modules/game/helpers/game-play/game-play.helper";
import { createGame, createGameWithCurrentGamePlay } from "@/modules/game/helpers/game.factory";
import { areAllWerewolvesAlive, getExpectedPlayersToPlay, getGroupOfPlayers, getLeftToEatByWerewolvesPlayers, getLeftToEatByWhiteWerewolfPlayers, getPlayerDtoWithRole, getPlayersWithActiveAttributeName, getPlayersWithCurrentRole, getPlayerWithActiveAttributeName, getPlayerWithCurrentRole, isGameSourceGroup, isGameSourceRole } from "@/modules/game/helpers/game.helper";
import { areAllWerewolvesAlive, getGroupOfPlayers, getLeftToEatByWerewolvesPlayers, getLeftToEatByWhiteWerewolfPlayers, getPlayerDtoWithRole, getPlayersWithActiveAttributeName, getPlayersWithCurrentRole, getPlayerWithActiveAttributeName, getPlayerWithCurrentRole, isGameSourceGroup, isGameSourceRole } from "@/modules/game/helpers/game.helper";
import { canPiedPiperCharm, isPlayerAliveAndPowerful, isPlayerPowerful } from "@/modules/game/helpers/player/player.helper";
import { GameHistoryRecordService } from "@/modules/game/providers/services/game-history/game-history-record.service";
import type { GameHistoryRecord } from "@/modules/game/schemas/game-history-record/game-history-record.schema";
Expand Down Expand Up @@ -53,7 +53,7 @@ export class GamePlayService {
const clonedGame = createGameWithCurrentGamePlay(game);
clonedGame.currentPlay = this.gamePlayAugmenterService.setGamePlayCanBeSkipped(clonedGame.currentPlay, clonedGame);
clonedGame.currentPlay = await this.gamePlayAugmenterService.setGamePlayEligibleTargets(clonedGame.currentPlay, clonedGame);
clonedGame.currentPlay.source.players = getExpectedPlayersToPlay(clonedGame);
clonedGame.currentPlay = this.gamePlayAugmenterService.setGamePlaySourcePlayers(clonedGame.currentPlay, clonedGame);
return clonedGame;
}

Expand Down

0 comments on commit 289b3f9

Please sign in to comment.