import { Column, CreateDateColumn, Entity, Index, JoinColumn, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn, } from 'typeorm'; import { ItemDefinition } from '../../items/entities/item-definition.entity'; import { LootTable } from './loot-table.entity'; /** * One independently rolled drop (spec §17). * * `position` fixes the roll order so injected randoms are predictable in tests; * it is content ordering, not priority. A guaranteed drop is simply * `dropChance = 1.0000` — no extra mechanism needed (spec §14). */ @Entity({ name: 'loot_table_entries' }) @Index('IDX_loot_table_entries_table_position', ['lootTableId', 'position'], { unique: true }) @Index('IDX_loot_table_entries_table_item', ['lootTableId', 'itemDefinitionId'], { unique: true }) export class LootTableEntry { @PrimaryGeneratedColumn('uuid', { name: 'id' }) id!: string; @Column({ name: 'loot_table_id', type: 'uuid' }) lootTableId!: string; @Column({ name: 'item_definition_id', type: 'uuid' }) itemDefinitionId!: string; @Column({ name: 'position', type: 'integer' }) position!: number; // PostgreSQL numeric arrives as a string, like LocationConnection.ambushChance. @Column({ name: 'drop_chance', type: 'numeric', precision: 5, scale: 4 }) dropChance!: string; @Column({ name: 'min_quantity', type: 'integer' }) minQuantity!: number; @Column({ name: 'max_quantity', type: 'integer' }) maxQuantity!: number; @Column({ name: 'enabled', type: 'boolean' }) enabled!: boolean; @CreateDateColumn({ name: 'created_at', type: 'timestamptz' }) createdAt!: Date; @UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' }) updatedAt!: Date; @ManyToOne(() => LootTable, { onDelete: 'CASCADE' }) @JoinColumn({ name: 'loot_table_id' }) lootTable!: LootTable; @ManyToOne(() => ItemDefinition, { onDelete: 'RESTRICT' }) @JoinColumn({ name: 'item_definition_id' }) itemDefinition!: ItemDefinition; }