Some checks failed
Deploy Dimension47 / deploy (push) Failing after 23s
- Add battle module with sessions, maps, tokens, and combatants - Implement WebSocket gateway for real-time battle updates - Add map upload with configurable grid system - Create battle canvas with token rendering and drag support - Support PC tokens from characters and NPC tokens from templates - Add initiative tracking and round management - GM-only controls for token manipulation Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
101 lines
2.4 KiB
TypeScript
101 lines
2.4 KiB
TypeScript
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
|
import { IsString, IsInt, IsOptional, IsEnum, Min, Max, IsArray, ValidateNested } from 'class-validator';
|
|
import { Type } from 'class-transformer';
|
|
import { CombatantType, ActionType } from '../../../generated/prisma/client.js';
|
|
|
|
export class CreateCombatantAbilityDto {
|
|
@ApiProperty({ description: 'Ability name' })
|
|
@IsString()
|
|
name: string;
|
|
|
|
@ApiProperty({ description: 'Action cost (0 for free/reaction, 1-3 for actions)' })
|
|
@IsInt()
|
|
@Min(0)
|
|
@Max(3)
|
|
actionCost: number;
|
|
|
|
@ApiProperty({ enum: ['ACTION', 'REACTION', 'FREE'] })
|
|
@IsEnum(ActionType)
|
|
actionType: ActionType;
|
|
|
|
@ApiProperty({ description: 'Ability description' })
|
|
@IsString()
|
|
description: string;
|
|
|
|
@ApiPropertyOptional({ description: 'Damage dice (e.g. "2d6+4 slashing")' })
|
|
@IsOptional()
|
|
@IsString()
|
|
damage?: string;
|
|
|
|
@ApiPropertyOptional({ description: 'Ability traits', type: [String] })
|
|
@IsOptional()
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
traits?: string[] = [];
|
|
}
|
|
|
|
export class CreateCombatantDto {
|
|
@ApiProperty({ description: 'Combatant name' })
|
|
@IsString()
|
|
name: string;
|
|
|
|
@ApiProperty({ enum: ['PC', 'NPC', 'MONSTER'] })
|
|
@IsEnum(CombatantType)
|
|
type: CombatantType;
|
|
|
|
@ApiProperty({ description: 'Combatant level' })
|
|
@IsInt()
|
|
@Min(-1)
|
|
@Max(30)
|
|
level: number;
|
|
|
|
@ApiProperty({ description: 'Maximum HP' })
|
|
@IsInt()
|
|
@Min(1)
|
|
hpMax: number;
|
|
|
|
@ApiProperty({ description: 'Armor Class' })
|
|
@IsInt()
|
|
@Min(0)
|
|
ac: number;
|
|
|
|
@ApiProperty({ description: 'Fortitude save modifier' })
|
|
@IsInt()
|
|
fortitude: number;
|
|
|
|
@ApiProperty({ description: 'Reflex save modifier' })
|
|
@IsInt()
|
|
reflex: number;
|
|
|
|
@ApiProperty({ description: 'Will save modifier' })
|
|
@IsInt()
|
|
will: number;
|
|
|
|
@ApiProperty({ description: 'Perception modifier' })
|
|
@IsInt()
|
|
perception: number;
|
|
|
|
@ApiPropertyOptional({ description: 'Movement speed in feet', default: 25 })
|
|
@IsOptional()
|
|
@IsInt()
|
|
@Min(0)
|
|
speed?: number = 25;
|
|
|
|
@ApiPropertyOptional({ description: 'Avatar image URL' })
|
|
@IsOptional()
|
|
@IsString()
|
|
avatarUrl?: string;
|
|
|
|
@ApiPropertyOptional({ description: 'Description/notes' })
|
|
@IsOptional()
|
|
@IsString()
|
|
description?: string;
|
|
|
|
@ApiPropertyOptional({ description: 'Combat abilities', type: [CreateCombatantAbilityDto] })
|
|
@IsOptional()
|
|
@IsArray()
|
|
@ValidateNested({ each: true })
|
|
@Type(() => CreateCombatantAbilityDto)
|
|
abilities?: CreateCombatantAbilityDto[] = [];
|
|
}
|