Feat : add tokens, handle mutex effects
This commit is contained in:
Vendored
+22
-25
@@ -1,27 +1,24 @@
|
|||||||
{
|
{
|
||||||
// Use IntelliSense to learn about possible attributes.
|
// Use IntelliSense to learn about possible attributes.
|
||||||
// Hover to view descriptions of existing attributes.
|
// Hover to view descriptions of existing attributes.
|
||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "Launch via NPM",
|
"name": "Launch via NPM",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"runtimeArgs": [
|
"runtimeArgs": ["run", "start:dev", "-b", "swc"],
|
||||||
"run",
|
"runtimeExecutable": "npm",
|
||||||
"start:dev",
|
"skipFiles": [
|
||||||
"-b",
|
"<node_internals>/**",
|
||||||
"swc"
|
"${workspaceFolder}/node_modules/**/*.js",
|
||||||
],
|
"${workspaceFolder}/lib/**/*.js"
|
||||||
"runtimeExecutable": "npm",
|
],
|
||||||
"skipFiles": [
|
"type": "node",
|
||||||
"<node_internals>/**"
|
"console": "internalConsole",
|
||||||
],
|
"outputCapture": "std",
|
||||||
"type": "node",
|
"internalConsoleOptions": "openOnSessionStart",
|
||||||
"console": "internalConsole",
|
"envFile": "${workspaceFolder}/.env"
|
||||||
"outputCapture": "std",
|
}
|
||||||
"internalConsoleOptions": "openOnSessionStart",
|
]
|
||||||
"envFile": "${workspaceFolder}/.env"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ import { Module } from '@nestjs/common';
|
|||||||
import { MongooseModule } from '@nestjs/mongoose';
|
import { MongooseModule } from '@nestjs/mongoose';
|
||||||
import { Card, CardSchema } from './schemas/cards.schema';
|
import { Card, CardSchema } from './schemas/cards.schema';
|
||||||
import { CardsService } from './cards.service';
|
import { CardsService } from './cards.service';
|
||||||
|
import { Effect, EffectSchema } from './schemas/effect.schema';
|
||||||
// import {
|
// import {
|
||||||
// Effect,
|
// Effect,
|
||||||
// EffectCondition,
|
// EffectCondition,
|
||||||
@@ -12,7 +13,7 @@ import { CardsService } from './cards.service';
|
|||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
MongooseModule.forFeature([
|
MongooseModule.forFeature([
|
||||||
// { name: Effect.name, schema: EffectSchema },
|
{ name: Effect.name, schema: EffectSchema },
|
||||||
// { name: EffectCondition.name, schema: EffectConditionSchema },
|
// { name: EffectCondition.name, schema: EffectConditionSchema },
|
||||||
{ name: Card.name, schema: CardSchema },
|
{ name: Card.name, schema: CardSchema },
|
||||||
]),
|
]),
|
||||||
|
|||||||
@@ -17,7 +17,10 @@ import { EffectCondition } from './schemas/effect.schema';
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CardsService {
|
export class CardsService {
|
||||||
constructor(@InjectModel(Card.name) private cardModel: Model<Card>) {}
|
constructor(
|
||||||
|
@InjectModel(Card.name) private cardModel: Model<Card>,
|
||||||
|
@InjectModel(Effect.name) private effectModel: Model<Effect>,
|
||||||
|
) {}
|
||||||
|
|
||||||
async loadCards(): Promise<void> {
|
async loadCards(): Promise<void> {
|
||||||
const cardPath = path.join(path.resolve(), 'src', 'json');
|
const cardPath = path.join(path.resolve(), 'src', 'json');
|
||||||
@@ -88,6 +91,9 @@ export class CardsService {
|
|||||||
): Promise<Effect[]> {
|
): Promise<Effect[]> {
|
||||||
return await Promise.all(
|
return await Promise.all(
|
||||||
json.map(async (e) => {
|
json.map(async (e) => {
|
||||||
|
if (e.mutex) {
|
||||||
|
console.log(e.mutex);
|
||||||
|
}
|
||||||
const createdEffect = {
|
const createdEffect = {
|
||||||
card: card,
|
card: card,
|
||||||
effect: e.effect,
|
effect: e.effect,
|
||||||
@@ -112,7 +118,7 @@ export class CardsService {
|
|||||||
card,
|
card,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return createdEffect;
|
return await this.effectModel.create(createdEffect);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
|
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
|
||||||
import { CardFaction, CardRole, CardType } from './cards.types';
|
import { CardFaction, CardRole, CardType } from './cards.types';
|
||||||
import { Types } from 'mongoose';
|
import mongoose, { Types } from 'mongoose';
|
||||||
import { Effect } from './effect.schema';
|
import { Effect } from './effect.schema';
|
||||||
|
|
||||||
@Schema()
|
@Schema()
|
||||||
@@ -32,7 +32,11 @@ export class Card extends Types.ObjectId {
|
|||||||
@Prop()
|
@Prop()
|
||||||
guard?: boolean;
|
guard?: boolean;
|
||||||
|
|
||||||
@Prop({ type: [Effect], default: [], autopopulate: true })
|
@Prop({
|
||||||
|
type: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Effect' }],
|
||||||
|
autopopulate: true,
|
||||||
|
default: [],
|
||||||
|
})
|
||||||
effects: Effect[];
|
effects: Effect[];
|
||||||
|
|
||||||
@Prop()
|
@Prop()
|
||||||
|
|||||||
@@ -38,7 +38,11 @@ export class Effect extends Types.ObjectId {
|
|||||||
@Prop({ type: Number, default: 1 })
|
@Prop({ type: Number, default: 1 })
|
||||||
times!: number;
|
times!: number;
|
||||||
|
|
||||||
// @Prop({ type: [Effect], default: [], autopopulate: true })
|
@Prop({
|
||||||
|
type: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Effect' }],
|
||||||
|
autopopulate: true,
|
||||||
|
default: [],
|
||||||
|
})
|
||||||
subEffects: Effect[];
|
subEffects: Effect[];
|
||||||
|
|
||||||
@Prop({ type: EffectCondition, autopopulate: true })
|
@Prop({ type: EffectCondition, autopopulate: true })
|
||||||
@@ -56,6 +60,7 @@ export class Effect extends Types.ObjectId {
|
|||||||
// },
|
// },
|
||||||
// ],
|
// ],
|
||||||
// })
|
// })
|
||||||
|
@Prop({ type: String })
|
||||||
mutex?: string;
|
mutex?: string;
|
||||||
|
|
||||||
// @Prop({
|
// @Prop({
|
||||||
@@ -74,6 +79,6 @@ EffectSchema.add({
|
|||||||
card: {
|
card: {
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
ref: 'Card',
|
ref: 'Card',
|
||||||
autopopulate: true,
|
autopopulate: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ import { TurnService } from '../services/turn.service';
|
|||||||
import { getPlayer, getCurrentTeam, isInTeam } from '../utils';
|
import { getPlayer, getCurrentTeam, isInTeam } from '../utils';
|
||||||
import { CardPipe } from '../pipe/card.pipe';
|
import { CardPipe } from '../pipe/card.pipe';
|
||||||
import { Card } from 'src/cards/schemas/cards.schema';
|
import { Card } from 'src/cards/schemas/cards.schema';
|
||||||
|
import { EffectPipe } from '../pipe/effect.pipe';
|
||||||
|
import { Effect } from 'src/cards/schemas/effect.schema';
|
||||||
|
|
||||||
@ApiTags('turn')
|
@ApiTags('turn')
|
||||||
@Controller('games/:gameId/turn')
|
@Controller('games/:gameId/turn')
|
||||||
@@ -87,4 +89,39 @@ export class TurnController {
|
|||||||
}
|
}
|
||||||
await this.turnService.buyCard(game, currentPlayer, card);
|
await this.turnService.buyCard(game, currentPlayer, card);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Post('lockEffect/:effectId')
|
||||||
|
@ApiOperation({ summary: 'Lock an effect' })
|
||||||
|
@UseGuards(AuthGuard)
|
||||||
|
async lockEffect(
|
||||||
|
@Param('gameId') _gameId: string,
|
||||||
|
@Param('effectId') _effectId: string,
|
||||||
|
@Param('gameId', GameStartedPipe) game: Document<Game> & Game,
|
||||||
|
@Param('effectId', EffectPipe) effect: Document<Effect> & Effect,
|
||||||
|
@Session() session: Record<string, string>,
|
||||||
|
) {
|
||||||
|
const currentPlayer = getPlayer(session, game);
|
||||||
|
const currentTeam = getCurrentTeam(game);
|
||||||
|
if (!isInTeam(currentTeam, currentPlayer)) {
|
||||||
|
throw new HttpException(
|
||||||
|
'It is not your turn to play',
|
||||||
|
HttpStatus.FORBIDDEN,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (game.currentTurn.lockedEffects.some((e) => e._id.equals(effect._id))) {
|
||||||
|
throw new HttpException('Effect already locked', HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
const card = (await effect.populate('card')).card;
|
||||||
|
if (!currentPlayer.board.cards.some((c) => c._id.equals(card._id))) {
|
||||||
|
throw new HttpException(
|
||||||
|
'Card not found in player board',
|
||||||
|
HttpStatus.NOT_FOUND,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!game.currentTurn.cardsLocked.some((c) => c._id.equals(card._id))) {
|
||||||
|
throw new HttpException('Card not locked', HttpStatus.BAD_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.turnService.lockEffect(game, currentPlayer, effect, card);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { ApiProperty } from '@nestjs/swagger';
|
|||||||
import { DatabaseObjectDto } from './database-object.dto';
|
import { DatabaseObjectDto } from './database-object.dto';
|
||||||
import { Game, Player, PlayingTurn, Team } from '../schemas/game.schema';
|
import { Game, Player, PlayingTurn, Team } from '../schemas/game.schema';
|
||||||
import { Card } from 'src/cards/schemas/cards.schema';
|
import { Card } from 'src/cards/schemas/cards.schema';
|
||||||
|
import { Effect } from 'src/cards/schemas/effect.schema';
|
||||||
|
|
||||||
export class ReadPlayerDto extends DatabaseObjectDto {
|
export class ReadPlayerDto extends DatabaseObjectDto {
|
||||||
constructor(
|
constructor(
|
||||||
@@ -53,14 +54,14 @@ export class ReadContainerDto extends DatabaseObjectDto {
|
|||||||
typeof DatabaseObjectDto
|
typeof DatabaseObjectDto
|
||||||
>[0],
|
>[0],
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
_hidden = false,
|
hidden = false,
|
||||||
) {
|
) {
|
||||||
super(data);
|
super(data);
|
||||||
// if (hidden) {
|
if (hidden) {
|
||||||
// this.cards = data.cards.map(() => null);
|
this.cards = data.cards.map(() => null);
|
||||||
// } else {
|
} else {
|
||||||
this.cards = data.cards;
|
this.cards = data.cards;
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cards: Card[];
|
cards: Card[];
|
||||||
@@ -95,9 +96,12 @@ class ReadPlayingTeamDto {
|
|||||||
constructor(currentTurn: PlayingTurn) {
|
constructor(currentTurn: PlayingTurn) {
|
||||||
this.currentTeam = currentTurn.currentTeam;
|
this.currentTeam = currentTurn.currentTeam;
|
||||||
this.cardsLocked = currentTurn.cardsLocked.map((c) => c._id.toHexString());
|
this.cardsLocked = currentTurn.cardsLocked.map((c) => c._id.toHexString());
|
||||||
this.effectsUsed = currentTurn.effectsUsed;
|
this.lockedEffects = currentTurn.lockedEffects.map((e) =>
|
||||||
|
e._id.toHexString(),
|
||||||
|
);
|
||||||
this.damage = currentTurn.damage;
|
this.damage = currentTurn.damage;
|
||||||
this.gold = currentTurn.gold;
|
this.gold = currentTurn.gold;
|
||||||
|
this.tokens = currentTurn.tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
@@ -107,7 +111,10 @@ class ReadPlayingTeamDto {
|
|||||||
cardsLocked: string[];
|
cardsLocked: string[];
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
effectsUsed: string[];
|
lockedEffects: string[];
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
tokens: Effect[];
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
damage: number;
|
damage: number;
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import {
|
||||||
|
PipeTransform,
|
||||||
|
Injectable,
|
||||||
|
HttpException,
|
||||||
|
HttpStatus,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { InjectModel } from '@nestjs/mongoose';
|
||||||
|
import { Model } from 'mongoose';
|
||||||
|
import { Effect } from 'src/cards/schemas/effect.schema';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class EffectPipe implements PipeTransform {
|
||||||
|
constructor(@InjectModel(Effect.name) private effectmodel: Model<Effect>) {}
|
||||||
|
|
||||||
|
async transform(value: any) {
|
||||||
|
const effect = await this.effectmodel.findById(value);
|
||||||
|
if (!effect) {
|
||||||
|
throw new HttpException('Effect not found', HttpStatus.NOT_FOUND);
|
||||||
|
}
|
||||||
|
return effect;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
|
|||||||
import mongoose, { HydratedDocument, Types } from 'mongoose';
|
import mongoose, { HydratedDocument, Types } from 'mongoose';
|
||||||
import { Card } from 'src/cards/schemas/cards.schema';
|
import { Card } from 'src/cards/schemas/cards.schema';
|
||||||
import { CardRole } from 'src/cards/schemas/cards.types';
|
import { CardRole } from 'src/cards/schemas/cards.types';
|
||||||
|
import { Effect } from 'src/cards/schemas/effect.schema';
|
||||||
import { User } from 'src/users/schemas/user.entity';
|
import { User } from 'src/users/schemas/user.entity';
|
||||||
|
|
||||||
export type GameDocument = HydratedDocument<Game>;
|
export type GameDocument = HydratedDocument<Game>;
|
||||||
@@ -29,8 +30,19 @@ export class PlayingTurn extends Types.ObjectId {
|
|||||||
})
|
})
|
||||||
cardsLocked: Card[];
|
cardsLocked: Card[];
|
||||||
|
|
||||||
@Prop({ type: [String], default: [] })
|
@Prop({
|
||||||
effectsUsed: string[];
|
type: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Effect' }],
|
||||||
|
autopopulate: false,
|
||||||
|
default: [],
|
||||||
|
})
|
||||||
|
lockedEffects: Effect[];
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
type: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Effect' }],
|
||||||
|
autopopulate: true,
|
||||||
|
default: [],
|
||||||
|
})
|
||||||
|
tokens: Effect[];
|
||||||
|
|
||||||
@Prop({ default: 0 })
|
@Prop({ default: 0 })
|
||||||
damage: number;
|
damage: number;
|
||||||
|
|||||||
@@ -18,6 +18,22 @@ export function isAutoActivable(effect: Effect) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function addToken(
|
||||||
|
game: Document<Game> & Game,
|
||||||
|
effect: Effect,
|
||||||
|
_player: Player,
|
||||||
|
_card: Card,
|
||||||
|
_gameService: GameService,
|
||||||
|
eventEmitter: EventEmitter2,
|
||||||
|
_session: mongoose.mongo.ClientSession,
|
||||||
|
) {
|
||||||
|
game.currentTurn.tokens.push(effect);
|
||||||
|
eventEmitter.emit('sse.game.' + game._id.toHexString(), {
|
||||||
|
type: 'currentTurn.addToken',
|
||||||
|
token: effect,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export const effectMappings = {
|
export const effectMappings = {
|
||||||
[CardEffects.GOLD]: async (
|
[CardEffects.GOLD]: async (
|
||||||
game: Document<Game> & Game,
|
game: Document<Game> & Game,
|
||||||
@@ -29,6 +45,10 @@ export const effectMappings = {
|
|||||||
_session: mongoose.mongo.ClientSession,
|
_session: mongoose.mongo.ClientSession,
|
||||||
) => {
|
) => {
|
||||||
game.currentTurn.gold += effect.amount;
|
game.currentTurn.gold += effect.amount;
|
||||||
|
eventEmitter.emit('sse.game.' + game._id.toHexString(), {
|
||||||
|
type: 'consumeEffect',
|
||||||
|
effect: effect._id.toHexString(),
|
||||||
|
});
|
||||||
eventEmitter.emit('sse.game.' + game._id.toHexString(), {
|
eventEmitter.emit('sse.game.' + game._id.toHexString(), {
|
||||||
type: 'currentTurn.updateGold',
|
type: 'currentTurn.updateGold',
|
||||||
gold: game.currentTurn.gold,
|
gold: game.currentTurn.gold,
|
||||||
@@ -46,6 +66,10 @@ export const effectMappings = {
|
|||||||
_session: mongoose.mongo.ClientSession,
|
_session: mongoose.mongo.ClientSession,
|
||||||
) => {
|
) => {
|
||||||
game.currentTurn.damage += effect.amount;
|
game.currentTurn.damage += effect.amount;
|
||||||
|
eventEmitter.emit('sse.game.' + game._id.toHexString(), {
|
||||||
|
type: 'consumeEffect',
|
||||||
|
effect: effect._id.toHexString(),
|
||||||
|
});
|
||||||
eventEmitter.emit('sse.game.' + game._id.toHexString(), {
|
eventEmitter.emit('sse.game.' + game._id.toHexString(), {
|
||||||
type: 'currentTurn.updateDamage',
|
type: 'currentTurn.updateDamage',
|
||||||
damage: game.currentTurn.damage,
|
damage: game.currentTurn.damage,
|
||||||
@@ -66,6 +90,10 @@ export const effectMappings = {
|
|||||||
t.players.some((p) => p._id.equals(player._id)),
|
t.players.some((p) => p._id.equals(player._id)),
|
||||||
);
|
);
|
||||||
team.health += effect.amount;
|
team.health += effect.amount;
|
||||||
|
eventEmitter.emit('sse.game.' + game._id.toHexString(), {
|
||||||
|
type: 'consumeEffect',
|
||||||
|
effect: effect._id.toHexString(),
|
||||||
|
});
|
||||||
eventEmitter.emit('sse.game.' + game._id.toHexString(), {
|
eventEmitter.emit('sse.game.' + game._id.toHexString(), {
|
||||||
type: 'team.updateHealth',
|
type: 'team.updateHealth',
|
||||||
team: team._id,
|
team: team._id,
|
||||||
@@ -85,6 +113,32 @@ export const effectMappings = {
|
|||||||
) => {
|
) => {
|
||||||
await gameService.drawToBoard(effect.amount, player, game, session);
|
await gameService.drawToBoard(effect.amount, player, game, session);
|
||||||
},
|
},
|
||||||
|
[CardEffects.PREPARE]: addToken,
|
||||||
|
[CardEffects.STUN]: addToken,
|
||||||
|
[CardEffects.SACRIFICE]: addToken,
|
||||||
|
[CardEffects.DRAW_AND_DISCARD]: addToken,
|
||||||
|
[CardEffects.MAKE_DISCARD]: addToken,
|
||||||
|
[CardEffects.RESTACK_DISCARDED_CHAMPION]: addToken,
|
||||||
|
[CardEffects.RESTACK_DISCARDED_CARD]: addToken,
|
||||||
|
[CardEffects.STACK_NEXT_ACTION_BOUGHT]: addToken,
|
||||||
|
[CardEffects.STACK_NEXT_CARD_BOUGHT]: addToken,
|
||||||
|
[CardEffects.PLAY_NEXT_CARD_BOUGHT]: addToken,
|
||||||
|
|
||||||
|
// [CardEffects.BUY_FOR_FREE]: addToken,
|
||||||
|
// [CardEffects.DISCARD_X_AND_DRAW_X]: addToken,
|
||||||
|
// [CardEffects.PREPARE_ANOTHER_CHAMPION]: addToken,
|
||||||
|
// [CardEffects.CHEAPER_CHAMPION]: addToken,
|
||||||
|
// [CardEffects.CHEAPER_CHAMPIONS_PASSIVE]: addToken,
|
||||||
|
// [CardEffects.CHEAPER_ACTION]: addToken,
|
||||||
|
// [CardEffects.CONTROL_OPPOSING_CHAMPION_PASSIVE]: addToken,
|
||||||
|
|
||||||
|
// [CardEffects.RESTACK_DISCARDED_ACTION]: addToken,
|
||||||
|
|
||||||
|
// [CardEffects.KEEP_IN_HAND]: addToken,
|
||||||
|
// [CardEffects.BUY_GEM_FOR_FREE]: addToken,
|
||||||
|
// [CardEffects.CHEAPER_SKILLS_PASSIVE]: addToken,
|
||||||
|
// [CardEffects.CHEAPER_CARD_IF_HIGHER_PRICE]: addToken,
|
||||||
|
// [CardEffects.PICK_FACTION]: addToken,
|
||||||
} as Record<
|
} as Record<
|
||||||
CardEffects,
|
CardEffects,
|
||||||
(
|
(
|
||||||
|
|||||||
@@ -48,7 +48,8 @@ export class GameService {
|
|||||||
game.teams[(index + 1) % game.teams.length]._id.toHexString();
|
game.teams[(index + 1) % game.teams.length]._id.toHexString();
|
||||||
|
|
||||||
game.currentTurn.cardsLocked = [];
|
game.currentTurn.cardsLocked = [];
|
||||||
game.currentTurn.effectsUsed = [];
|
game.currentTurn.lockedEffects = [];
|
||||||
|
game.currentTurn.tokens = [];
|
||||||
game.currentTurn.damage = 0;
|
game.currentTurn.damage = 0;
|
||||||
game.currentTurn.gold = 0;
|
game.currentTurn.gold = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -40,14 +40,14 @@ export class TurnService {
|
|||||||
});
|
});
|
||||||
for (const effect of card.effects) {
|
for (const effect of card.effects) {
|
||||||
if (isAutoActivable(effect)) {
|
if (isAutoActivable(effect)) {
|
||||||
await this.useEffect(game, player, effect, card, session);
|
await this.lockEffect(game, player, effect, card, session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await game.save({ session });
|
await game.save({ session });
|
||||||
}
|
}
|
||||||
|
|
||||||
@WithTransaction
|
@WithTransaction
|
||||||
async useEffect(
|
async lockEffect(
|
||||||
game: Document<Game> & Game,
|
game: Document<Game> & Game,
|
||||||
player: Player,
|
player: Player,
|
||||||
effect: Effect,
|
effect: Effect,
|
||||||
@@ -64,7 +64,7 @@ export class TurnService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
const effectUUID = effect._id.toHexString();
|
const effectUUID = effect._id.toHexString();
|
||||||
if (game.currentTurn.effectsUsed.includes(effectUUID)) {
|
if (game.currentTurn.lockedEffects.some((e) => e._id.equals(effectUUID))) {
|
||||||
console.error(`Effect ${effectUUID} already used this turn`);
|
console.error(`Effect ${effectUUID} already used this turn`);
|
||||||
throw new HttpException(
|
throw new HttpException(
|
||||||
`Effect ${effectUUID} already used this turn`,
|
`Effect ${effectUUID} already used this turn`,
|
||||||
@@ -72,10 +72,21 @@ export class TurnService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.eventEmitter.emit('sse.game.' + game._id.toHexString(), {
|
this.eventEmitter.emit('sse.game.' + game._id.toHexString(), {
|
||||||
type: 'useEffect',
|
type: 'lockEffect',
|
||||||
effect: effectUUID,
|
effect: effectUUID,
|
||||||
});
|
});
|
||||||
game.currentTurn.effectsUsed.push(effectUUID);
|
if (effect.mutex) {
|
||||||
|
for (const e of card.effects) {
|
||||||
|
if (e.mutex == effect.mutex) {
|
||||||
|
this.eventEmitter.emit('sse.game.' + game._id.toHexString(), {
|
||||||
|
type: 'lockEffect',
|
||||||
|
effect: e._id.toHexString(),
|
||||||
|
});
|
||||||
|
game.currentTurn.lockedEffects.push(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
game.currentTurn.lockedEffects.push(effect);
|
||||||
await effectRunner(
|
await effectRunner(
|
||||||
game,
|
game,
|
||||||
effect,
|
effect,
|
||||||
|
|||||||
Reference in New Issue
Block a user