Files
back-ts/src/games/services/turn.service.ts
T
2024-07-05 09:56:09 +02:00

99 lines
3.0 KiB
TypeScript

import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { Game, Player } from '../schemas/game.schema';
import mongoose, { Document, Model } from 'mongoose';
import { Card } from 'src/cards/schemas/cards.schema';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { Effect } from 'src/cards/schemas/effect.schema';
import { CardEffects, EffectType } from 'src/cards/schemas/cards.types';
import { WithTransaction } from '../utils';
import { effectMappings } from './effect.functions';
import { InjectConnection, InjectModel } from '@nestjs/mongoose';
@Injectable()
export class TurnService {
constructor(
private eventEmitter: EventEmitter2,
@InjectModel(Game.name) private gameModel: Model<Game>,
@InjectConnection() private readonly connection: mongoose.Connection,
) {}
@WithTransaction
async lockCard(
game: Document<Game> & Game,
player: Player,
cardId: string,
session?: mongoose.mongo.ClientSession,
) {
const card = player.board.cards.find((c) => c._id.toHexString() == 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',
card: card._id.toHexString(),
});
for (const effect of card.effects) {
if (
[, CardEffects.HEAL, CardEffects.GOLD, CardEffects.DAMAGE].includes(
effect.effect,
) &&
!effect.mutex &&
!effect.per &&
(!effect.condition ||
effect.condition.effectId == EffectType.CHAMPION_ACTION)
) {
await this.useEffect(game, player, effect, card, session);
}
}
await game.save({ session });
}
@WithTransaction
async useEffect(
game: Document<Game> & Game,
player: Player,
effect: Effect,
card: Card,
session?: mongoose.mongo.ClientSession,
) {
const effectRunner = effectMappings[effect.effect];
if (!effectMappings[effect.effect]) {
console.warn(`Effect ${effect.effect} not implemented`);
return;
throw new HttpException(
`Effect ${effect.effect} not implemented`,
HttpStatus.NOT_IMPLEMENTED,
);
}
const effectUUID = effect._id.toHexString();
if (game.currentTurn.effectsUsed.includes(effectUUID)) {
console.error(`Effect ${effectUUID} already used this turn`);
throw new HttpException(
`Effect ${effectUUID} already used this turn`,
HttpStatus.CONFLICT,
);
}
this.eventEmitter.emit('sse.game.' + game._id.toHexString(), {
type: 'useEffect',
effect: effectUUID,
});
game.currentTurn.effectsUsed.push(effectUUID);
await effectRunner(game, effect, player, card, this.eventEmitter);
await game.save({ session });
}
@WithTransaction
async buyCard(
game: Document<Game> & Game,
player: Player,
card: Card,
session?: mongoose.mongo.ClientSession,
) {
return;
}
}