diff --git a/src/cards/cards.service.ts b/src/cards/cards.service.ts index a6d5a9a..1abd6d4 100644 --- a/src/cards/cards.service.ts +++ b/src/cards/cards.service.ts @@ -79,7 +79,7 @@ export class CardsService { if (json.effects) { createdCard.effects = await this.createEffects(json.effects, createdCard); } - createdCard.save(); + await createdCard.save(); } private async createEffects( @@ -95,6 +95,7 @@ export class CardsService { times: e.times ?? 1, per: e.per, faction: e.faction, + mutex: e.mutex?.toString(), } as Effect; if (e.sub_effects) { createdEffect.subEffects = await this.createEffects( diff --git a/src/cards/schemas/effect.schema.ts b/src/cards/schemas/effect.schema.ts index a29e1bc..1a6faa3 100644 --- a/src/cards/schemas/effect.schema.ts +++ b/src/cards/schemas/effect.schema.ts @@ -56,7 +56,7 @@ export class Effect extends Types.ObjectId { // }, // ], // }) - mutex?: Effect[]; + mutex?: string; // @Prop({ // type: mongoose.Schema.Types.ObjectId, @@ -77,15 +77,3 @@ EffectSchema.add({ autopopulate: true, }, }); - -EffectSchema.add({ - mutex: { - type: [ - { - type: mongoose.Schema.Types.ObjectId, - ref: 'Effect', - autopopulate: true, - }, - ], - }, -}); diff --git a/src/games/controllers/turn.controller.ts b/src/games/controllers/turn.controller.ts index b498528..681c476 100644 --- a/src/games/controllers/turn.controller.ts +++ b/src/games/controllers/turn.controller.ts @@ -32,9 +32,9 @@ export class TurnController { @UseGuards(AuthGuard) async lockCard( @Param('gameId') _gameId: string, - @Param('cardId') cardId: string, + @Param('cardId') _cardId: string, @Param('gameId', GameStartedPipe) game: Document & Game, - @Param('gameId', CardPipe) card: Document & Card, + @Param('cardId', CardPipe) card: Document & Card, @Session() session: Record, ) { const currentPlayer = getPlayer(session, game); @@ -45,10 +45,17 @@ export class TurnController { HttpStatus.FORBIDDEN, ); } - if (game.currentTurn.cardsLocked.some((c) => c._id.equals(cardId))) { + if (game.currentTurn.cardsLocked.some((c) => c._id.equals(card._id))) { throw new HttpException('Card already locked', HttpStatus.BAD_REQUEST); } - this.turnService.lockCard(game, currentPlayer, cardId); + if (!currentPlayer.board.cards.some((c) => c._id.equals(card._id))) { + throw new HttpException( + 'Card not found in player board', + HttpStatus.NOT_FOUND, + ); + } + + await this.turnService.lockCard(game, currentPlayer, card); } @Post('buyCard/:cardId') @@ -76,7 +83,8 @@ export class TurnController { ); } if (game.currentTurn.gold < card.cost) { - this.turnService.buyCard(game, currentPlayer, card); + throw new HttpException('Not enough gold', HttpStatus.BAD_REQUEST); } + await this.turnService.buyCard(game, currentPlayer, card); } } diff --git a/src/games/services/effect.functions.ts b/src/games/services/effect.functions.ts index b70cd20..a5b4243 100644 --- a/src/games/services/effect.functions.ts +++ b/src/games/services/effect.functions.ts @@ -2,9 +2,20 @@ import { EventEmitter2 } from '@nestjs/event-emitter'; import { Game, Player } from '../schemas/game.schema'; import { Document } from 'mongoose'; import { Card } from 'src/cards/schemas/cards.schema'; -import { CardEffects } from 'src/cards/schemas/cards.types'; +import { CardEffects, EffectType } from 'src/cards/schemas/cards.types'; import { Effect } from 'src/cards/schemas/effect.schema'; +export function isAutoActivable(effect: Effect) { + if ( + !effect.mutex && + (!effect.condition || + effect.condition.effectId == EffectType.CHAMPION_ACTION) + ) { + return true; + } + return false; +} + export const effectMappings = { [CardEffects.GOLD]: ( game: Document & Game, @@ -35,6 +46,25 @@ export const effectMappings = { operation: effect.amount, }); }, + + [CardEffects.HEAL]: ( + game: Document & Game, + effect: Effect, + player: Player, + _card: Card, + eventEmitter: EventEmitter2, + ) => { + const team = game.teams.find((t) => + t.players.some((p) => p._id.equals(player._id)), + ); + team.health += effect.amount; + eventEmitter.emit('sse.game.' + game._id.toHexString(), { + type: 'team.updateHealth', + team: team._id, + health: team.health, + operation: effect.amount, + }); + }, } as Record< CardEffects, ( diff --git a/src/games/services/games.service.ts b/src/games/services/games.service.ts index 280cf44..6f66392 100644 --- a/src/games/services/games.service.ts +++ b/src/games/services/games.service.ts @@ -185,7 +185,7 @@ export class GameService { game: Document & Game, session?: mongoose.mongo.ClientSession, ) { - if (cards.some((c) => !from.cards.includes(c))) { + if (cards.some((c) => !from.cards.some((cc) => cc._id.equals(c._id)))) { throw new HttpException( 'Card not found in container', HttpStatus.NOT_FOUND, diff --git a/src/games/services/turn.service.ts b/src/games/services/turn.service.ts index 0fc58c1..a51e75d 100644 --- a/src/games/services/turn.service.ts +++ b/src/games/services/turn.service.ts @@ -8,11 +8,13 @@ import { CardEffects, EffectType } from 'src/cards/schemas/cards.types'; import { WithTransaction } from '../utils'; import { effectMappings } from './effect.functions'; import { InjectConnection, InjectModel } from '@nestjs/mongoose'; +import { GameService } from './games.service'; @Injectable() export class TurnService { constructor( private eventEmitter: EventEmitter2, + private readonly gamesService: GameService, @InjectModel(Game.name) private gameModel: Model, @InjectConnection() private readonly connection: mongoose.Connection, ) {} @@ -21,16 +23,9 @@ export class TurnService { async lockCard( game: Document & Game, player: Player, - cardId: string, + card: Card, session?: mongoose.mongo.ClientSession, ) { - const card = player.board.cards.find((c) => c._id.equals(cardId)); - if (!card) { - throw new HttpException( - 'Card not found in player board', - HttpStatus.NOT_FOUND, - ); - } game.currentTurn.cardsLocked.push(card); this.eventEmitter.emit('sse.game.' + game._id.toHexString(), { type: 'lockCard', @@ -38,7 +33,7 @@ export class TurnService { }); for (const effect of card.effects) { if ( - [, CardEffects.HEAL, CardEffects.GOLD, CardEffects.DAMAGE].includes( + [CardEffects.HEAL, CardEffects.GOLD, CardEffects.DAMAGE].includes( effect.effect, ) && !effect.mutex && @@ -93,6 +88,24 @@ export class TurnService { card: Card, session?: mongoose.mongo.ClientSession, ) { + if (!card.cost) { + throw new TypeError('Card cost is null or undefined'); + } + game.currentTurn.gold -= card.cost; + this.eventEmitter.emit('sse.game.' + game._id.toHexString(), { + type: 'currentTurn.updateGold', + gold: game.currentTurn.gold, + operation: -card.cost, + }); + await this.gamesService.distributeCards( + [card], + game.market, + player.discard, + game, + session, + ); + await this.gamesService.fillMarket(game, session); + await game.save({ session }); return; } }