Feat : allow buying cards
This commit is contained in:
@@ -79,7 +79,7 @@ export class CardsService {
|
|||||||
if (json.effects) {
|
if (json.effects) {
|
||||||
createdCard.effects = await this.createEffects(json.effects, createdCard);
|
createdCard.effects = await this.createEffects(json.effects, createdCard);
|
||||||
}
|
}
|
||||||
createdCard.save();
|
await createdCard.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async createEffects(
|
private async createEffects(
|
||||||
@@ -95,6 +95,7 @@ export class CardsService {
|
|||||||
times: e.times ?? 1,
|
times: e.times ?? 1,
|
||||||
per: e.per,
|
per: e.per,
|
||||||
faction: e.faction,
|
faction: e.faction,
|
||||||
|
mutex: e.mutex?.toString(),
|
||||||
} as Effect;
|
} as Effect;
|
||||||
if (e.sub_effects) {
|
if (e.sub_effects) {
|
||||||
createdEffect.subEffects = await this.createEffects(
|
createdEffect.subEffects = await this.createEffects(
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export class Effect extends Types.ObjectId {
|
|||||||
// },
|
// },
|
||||||
// ],
|
// ],
|
||||||
// })
|
// })
|
||||||
mutex?: Effect[];
|
mutex?: string;
|
||||||
|
|
||||||
// @Prop({
|
// @Prop({
|
||||||
// type: mongoose.Schema.Types.ObjectId,
|
// type: mongoose.Schema.Types.ObjectId,
|
||||||
@@ -77,15 +77,3 @@ EffectSchema.add({
|
|||||||
autopopulate: true,
|
autopopulate: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
EffectSchema.add({
|
|
||||||
mutex: {
|
|
||||||
type: [
|
|
||||||
{
|
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
|
||||||
ref: 'Effect',
|
|
||||||
autopopulate: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ export class TurnController {
|
|||||||
@UseGuards(AuthGuard)
|
@UseGuards(AuthGuard)
|
||||||
async lockCard(
|
async lockCard(
|
||||||
@Param('gameId') _gameId: string,
|
@Param('gameId') _gameId: string,
|
||||||
@Param('cardId') cardId: string,
|
@Param('cardId') _cardId: string,
|
||||||
@Param('gameId', GameStartedPipe) game: Document<Game> & Game,
|
@Param('gameId', GameStartedPipe) game: Document<Game> & Game,
|
||||||
@Param('gameId', CardPipe) card: Document<Card> & Card,
|
@Param('cardId', CardPipe) card: Document<Card> & Card,
|
||||||
@Session() session: Record<string, string>,
|
@Session() session: Record<string, string>,
|
||||||
) {
|
) {
|
||||||
const currentPlayer = getPlayer(session, game);
|
const currentPlayer = getPlayer(session, game);
|
||||||
@@ -45,10 +45,17 @@ export class TurnController {
|
|||||||
HttpStatus.FORBIDDEN,
|
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);
|
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')
|
@Post('buyCard/:cardId')
|
||||||
@@ -76,7 +83,8 @@ export class TurnController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (game.currentTurn.gold < card.cost) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,20 @@ import { EventEmitter2 } from '@nestjs/event-emitter';
|
|||||||
import { Game, Player } from '../schemas/game.schema';
|
import { Game, Player } from '../schemas/game.schema';
|
||||||
import { Document } from 'mongoose';
|
import { Document } from 'mongoose';
|
||||||
import { Card } from 'src/cards/schemas/cards.schema';
|
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';
|
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 = {
|
export const effectMappings = {
|
||||||
[CardEffects.GOLD]: (
|
[CardEffects.GOLD]: (
|
||||||
game: Document<Game> & Game,
|
game: Document<Game> & Game,
|
||||||
@@ -35,6 +46,25 @@ export const effectMappings = {
|
|||||||
operation: effect.amount,
|
operation: effect.amount,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[CardEffects.HEAL]: (
|
||||||
|
game: Document<Game> & 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<
|
} as Record<
|
||||||
CardEffects,
|
CardEffects,
|
||||||
(
|
(
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ export class GameService {
|
|||||||
game: Document<Game> & Game,
|
game: Document<Game> & Game,
|
||||||
session?: mongoose.mongo.ClientSession,
|
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(
|
throw new HttpException(
|
||||||
'Card not found in container',
|
'Card not found in container',
|
||||||
HttpStatus.NOT_FOUND,
|
HttpStatus.NOT_FOUND,
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ import { CardEffects, EffectType } from 'src/cards/schemas/cards.types';
|
|||||||
import { WithTransaction } from '../utils';
|
import { WithTransaction } from '../utils';
|
||||||
import { effectMappings } from './effect.functions';
|
import { effectMappings } from './effect.functions';
|
||||||
import { InjectConnection, InjectModel } from '@nestjs/mongoose';
|
import { InjectConnection, InjectModel } from '@nestjs/mongoose';
|
||||||
|
import { GameService } from './games.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TurnService {
|
export class TurnService {
|
||||||
constructor(
|
constructor(
|
||||||
private eventEmitter: EventEmitter2,
|
private eventEmitter: EventEmitter2,
|
||||||
|
private readonly gamesService: GameService,
|
||||||
@InjectModel(Game.name) private gameModel: Model<Game>,
|
@InjectModel(Game.name) private gameModel: Model<Game>,
|
||||||
@InjectConnection() private readonly connection: mongoose.Connection,
|
@InjectConnection() private readonly connection: mongoose.Connection,
|
||||||
) {}
|
) {}
|
||||||
@@ -21,16 +23,9 @@ export class TurnService {
|
|||||||
async lockCard(
|
async lockCard(
|
||||||
game: Document<Game> & Game,
|
game: Document<Game> & Game,
|
||||||
player: Player,
|
player: Player,
|
||||||
cardId: string,
|
card: Card,
|
||||||
session?: mongoose.mongo.ClientSession,
|
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);
|
game.currentTurn.cardsLocked.push(card);
|
||||||
this.eventEmitter.emit('sse.game.' + game._id.toHexString(), {
|
this.eventEmitter.emit('sse.game.' + game._id.toHexString(), {
|
||||||
type: 'lockCard',
|
type: 'lockCard',
|
||||||
@@ -38,7 +33,7 @@ export class TurnService {
|
|||||||
});
|
});
|
||||||
for (const effect of card.effects) {
|
for (const effect of card.effects) {
|
||||||
if (
|
if (
|
||||||
[, CardEffects.HEAL, CardEffects.GOLD, CardEffects.DAMAGE].includes(
|
[CardEffects.HEAL, CardEffects.GOLD, CardEffects.DAMAGE].includes(
|
||||||
effect.effect,
|
effect.effect,
|
||||||
) &&
|
) &&
|
||||||
!effect.mutex &&
|
!effect.mutex &&
|
||||||
@@ -93,6 +88,24 @@ export class TurnService {
|
|||||||
card: Card,
|
card: Card,
|
||||||
session?: mongoose.mongo.ClientSession,
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user