99 lines
3.0 KiB
TypeScript
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;
|
|
}
|
|
}
|