TurnManager stateless avec sessions en mémoire (TTL 10min). SpellSystem : 15 sorts (5 par voie du Dao), mana, cooldowns, buffs/debuffs. CompanionAI : Mira (heal/support) et Vell (tank/dps) — IA contextuelle. Monster AI : 3 profils (agressif, défensif, chaotique). Nouvelles entités : Spell, PlayerSpell, PlayerDaoPath. Character +mana. Monster +aiProfile +isBoss. Migration : 1743004800000-TurnCombatSystem. Frontend : TurnCombatPage (select/combat/result), sélecteur compagnon, barres HP/MP, log scrollable, sous-menu sorts avec cooldowns. Endpoints : 8 routes sous /combat/turn/ (start, action, session, spells, unlocked, unlock, dao, dao/choose). Combat simple (POST /combat/start) et grind ×5/×10 inchangés.
118 lines
3.2 KiB
TypeScript
118 lines
3.2 KiB
TypeScript
import {
|
|
Controller,
|
|
Post,
|
|
Get,
|
|
Body,
|
|
Param,
|
|
UseGuards,
|
|
Req,
|
|
HttpCode,
|
|
HttpStatus,
|
|
} from '@nestjs/common';
|
|
import { Request } from 'express';
|
|
import { TurnCombatService } from './turn-combat.service';
|
|
import { SpellSystem } from './spell.system';
|
|
import { StartTurnCombatDto } from './dto/start-turn-combat.dto';
|
|
import { TurnActionDto } from './dto/turn-action.dto';
|
|
import { ChooseDaoPathDto } from './dto/choose-dao-path.dto';
|
|
import { UnlockSpellDto } from './dto/unlock-spell.dto';
|
|
import { AuthGuard } from '../../auth/guards/auth.guard';
|
|
import { User } from '../../user/user.entity';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
import { Repository } from 'typeorm';
|
|
import { Character } from '../../character/entities/character.entity';
|
|
|
|
@Controller('combat/turn')
|
|
@UseGuards(AuthGuard)
|
|
export class TurnCombatController {
|
|
constructor(
|
|
private readonly turnCombatService: TurnCombatService,
|
|
private readonly spellSystem: SpellSystem,
|
|
@InjectRepository(Character)
|
|
private readonly characterRepo: Repository<Character>,
|
|
) {}
|
|
|
|
// ---------- Combat tour par tour ----------
|
|
|
|
@Post('start')
|
|
@HttpCode(HttpStatus.OK)
|
|
startCombat(
|
|
@Body() dto: StartTurnCombatDto,
|
|
@Req() req: Request & { user: User },
|
|
) {
|
|
return this.turnCombatService.startSession(dto, req.user);
|
|
}
|
|
|
|
@Post('action')
|
|
@HttpCode(HttpStatus.OK)
|
|
submitAction(
|
|
@Body() dto: TurnActionDto,
|
|
@Req() req: Request & { user: User },
|
|
) {
|
|
return this.turnCombatService.submitAction(
|
|
dto.sessionId,
|
|
{ type: dto.type, spellId: dto.spellId, itemId: dto.itemId },
|
|
req.user.id,
|
|
);
|
|
}
|
|
|
|
@Get('session/:sessionId')
|
|
getSession(
|
|
@Param('sessionId') sessionId: string,
|
|
@Req() req: Request & { user: User },
|
|
) {
|
|
return this.turnCombatService.getSession(sessionId, req.user.id);
|
|
}
|
|
|
|
// ---------- Dao & Sorts ----------
|
|
|
|
@Get('spells')
|
|
getAllSpells() {
|
|
return this.spellSystem.getAllSpells();
|
|
}
|
|
|
|
@Get('spells/unlocked')
|
|
async getUnlockedSpells(@Req() req: Request & { user: User }) {
|
|
const character = await this.getCharacter(req.user.id);
|
|
return this.spellSystem.getUnlockedSpells(character.id);
|
|
}
|
|
|
|
@Post('spells/unlock')
|
|
@HttpCode(HttpStatus.OK)
|
|
async unlockSpell(
|
|
@Body() dto: UnlockSpellDto,
|
|
@Req() req: Request & { user: User },
|
|
) {
|
|
const character = await this.getCharacter(req.user.id);
|
|
return this.spellSystem.unlockSpell(character.id, dto.spellId);
|
|
}
|
|
|
|
@Get('dao')
|
|
async getDaoPaths(@Req() req: Request & { user: User }) {
|
|
const character = await this.getCharacter(req.user.id);
|
|
return this.spellSystem.getDaoPaths(character.id);
|
|
}
|
|
|
|
@Post('dao/choose')
|
|
@HttpCode(HttpStatus.OK)
|
|
async chooseDaoPath(
|
|
@Body() dto: ChooseDaoPathDto,
|
|
@Req() req: Request & { user: User },
|
|
) {
|
|
const character = await this.getCharacter(req.user.id);
|
|
return this.spellSystem.choosePrimaryPath(character.id, dto.path);
|
|
}
|
|
|
|
// ---------- Helper ----------
|
|
|
|
private async getCharacter(userId: string): Promise<Character> {
|
|
const character = await this.characterRepo.findOne({
|
|
where: { userId },
|
|
});
|
|
if (!character) {
|
|
throw new Error('Aucun personnage trouve');
|
|
}
|
|
return character;
|
|
}
|
|
}
|