first commit
This commit is contained in:
24
libs/encounter-library/project.json
Normal file
24
libs/encounter-library/project.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "encounter-library",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "libs/encounter-library/src",
|
||||
"projectType": "library",
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/js:tsc",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"options": {
|
||||
"outputPath": "dist/libs/encounter-library",
|
||||
"main": "libs/encounter-library/src/index.ts",
|
||||
"tsConfig": "libs/encounter-library/tsconfig.lib.json"
|
||||
}
|
||||
},
|
||||
"validate": {
|
||||
"executor": "@nx/workspace:run-commands",
|
||||
"options": {
|
||||
"command": "ts-node libs/encounter-library/src/lib/validate-encounters.ts"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": ["scope:content"]
|
||||
}
|
||||
1
libs/encounter-library/src/index.ts
Normal file
1
libs/encounter-library/src/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './lib/encounter-library';
|
||||
42
libs/encounter-library/src/lib/encounter-library.ts
Normal file
42
libs/encounter-library/src/lib/encounter-library.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import encountersData from './encounters.json';
|
||||
|
||||
export interface EncounterRecord {
|
||||
id: string;
|
||||
tier: string;
|
||||
baseSuccessChance: number;
|
||||
difficultyTags: string[];
|
||||
perkTags: string[];
|
||||
flavor: string[];
|
||||
}
|
||||
|
||||
interface EncounterDocument {
|
||||
schemaVersion: number;
|
||||
records: EncounterRecord[];
|
||||
}
|
||||
|
||||
const doc = encountersData as EncounterDocument;
|
||||
|
||||
export function listEncounters(): EncounterRecord[] {
|
||||
return doc.records;
|
||||
}
|
||||
|
||||
export function getEncounterById(id: string): EncounterRecord | undefined {
|
||||
return doc.records.find((record) => record.id === id);
|
||||
}
|
||||
|
||||
export function getRandomEncounterByTier(tier: string, seed = Date.now()): EncounterRecord {
|
||||
const matching = doc.records.filter((record) => record.tier === tier);
|
||||
const pool = matching.length > 0 ? matching : doc.records;
|
||||
const index = Math.abs(seed) % pool.length;
|
||||
return pool[index];
|
||||
}
|
||||
|
||||
export function migrateEncounterDocument(document: EncounterDocument): EncounterDocument {
|
||||
if (document.schemaVersion === 1) {
|
||||
return document;
|
||||
}
|
||||
return {
|
||||
schemaVersion: 1,
|
||||
records: document.records
|
||||
};
|
||||
}
|
||||
45
libs/encounter-library/src/lib/encounter.schema.json
Normal file
45
libs/encounter-library/src/lib/encounter.schema.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"required": ["schemaVersion", "records"],
|
||||
"properties": {
|
||||
"schemaVersion": {
|
||||
"type": "integer",
|
||||
"minimum": 1
|
||||
},
|
||||
"records": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"tier",
|
||||
"baseSuccessChance",
|
||||
"difficultyTags",
|
||||
"perkTags",
|
||||
"flavor"
|
||||
],
|
||||
"properties": {
|
||||
"id": { "type": "string", "minLength": 1 },
|
||||
"tier": { "type": "string" },
|
||||
"baseSuccessChance": { "type": "number", "minimum": 0, "maximum": 1 },
|
||||
"difficultyTags": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" }
|
||||
},
|
||||
"perkTags": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" }
|
||||
},
|
||||
"flavor": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
27
libs/encounter-library/src/lib/encounters.json
Normal file
27
libs/encounter-library/src/lib/encounters.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"records": [
|
||||
{
|
||||
"id": "cleanse_hex",
|
||||
"tier": "common",
|
||||
"baseSuccessChance": 0.62,
|
||||
"difficultyTags": ["normal", "hard"],
|
||||
"perkTags": ["totem", "support"],
|
||||
"flavor": [
|
||||
"The bones glow with cursed light.",
|
||||
"You cleanse the totem before the killer returns."
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "escape_hatch",
|
||||
"tier": "rare",
|
||||
"baseSuccessChance": 0.41,
|
||||
"difficultyTags": ["hard", "nightmare"],
|
||||
"perkTags": ["mobility", "luck"],
|
||||
"flavor": [
|
||||
"A rusted hatch creaks in the distance.",
|
||||
"One wrong step and the fog closes in."
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
27
libs/encounter-library/src/lib/validate-encounters.ts
Normal file
27
libs/encounter-library/src/lib/validate-encounters.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
import { z } from 'zod';
|
||||
|
||||
const encounterRecord = z.object({
|
||||
id: z.string().min(1),
|
||||
tier: z.string(),
|
||||
baseSuccessChance: z.number().min(0).max(1),
|
||||
difficultyTags: z.array(z.string()),
|
||||
perkTags: z.array(z.string()),
|
||||
flavor: z.array(z.string()).min(1)
|
||||
});
|
||||
|
||||
const encounterDocument = z.object({
|
||||
schemaVersion: z.number().int().min(1),
|
||||
records: z.array(encounterRecord)
|
||||
});
|
||||
|
||||
function main(): void {
|
||||
const file = resolve(process.cwd(), 'libs/encounter-library/src/lib/encounters.json');
|
||||
const raw = readFileSync(file, 'utf-8');
|
||||
const parsed = JSON.parse(raw) as unknown;
|
||||
encounterDocument.parse(parsed);
|
||||
process.stdout.write('Encounter library validation passed.\n');
|
||||
}
|
||||
|
||||
main();
|
||||
9
libs/encounter-library/tsconfig.lib.json
Normal file
9
libs/encounter-library/tsconfig.lib.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"declaration": true,
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.json"]
|
||||
}
|
||||
Reference in New Issue
Block a user