import {VNScene} from "./vnscene.ts"; import {getPlayerProgress} from "./playerprogress.ts"; import {getSkills} from "./skills.ts"; import {Ending, SCORING_CATEGORIES, ScoringCategory} from "./datatypes.ts"; import {sceneBat, sceneCharm, sceneLore, sceneParty, sceneStare, sceneStealth} from "./endings.ts"; import {generateWishes} from "./wishes.ts"; import {generateSuccessors} from "./successors.ts"; class Scorer { constructor() { } pickEnding(): Ending { let learnedSkills = getPlayerProgress().getLearnedSkills(); let scores: Record = {}; let itemsPurloined = getPlayerProgress().getItemsPurloined(); let vampiricSkills = 0; let mortalServants = itemsPurloined / 10; for (const skill of learnedSkills.values()) { let data = getSkills().get(skill); for (let [category, number] of Object.entries(data.governing.scoring)) { scores[category] = (scores[category] ?? 0) + number; } mortalServants += data.governing.mortalServantValue; vampiricSkills += 1; } mortalServants = Math.floor(mortalServants); // NOTE: This approach isn't efficient but it's easy to understand // and it allows me to arbitrate ties however I want let runningScores: Record = {...scores}; const isMax = (cat: ScoringCategory, min: number) => { let score = runningScores[cat] ?? 0; runningScores[cat] = 0; // each category, once checked, can't disqualify any other category if (score < min) { return false; } for (let cat of SCORING_CATEGORIES.values()) { if (runningScores[cat] > score) { return false; } } return true; } let scene: VNScene; let rank: string; let domicile: string; // TODO: Award different ranks depending on second-to-top skill // TODO: Award different domiciles based on overall score // TODO: Force the rank to match the wish if one existed if (isMax("stare", 3)) { scene = sceneStare; rank = "Hypno-Chiropteran"; domicile = "Village of Brainwashed Mortals"; } else if (isMax("lore", 3)) { scene = sceneLore; rank = "Loremaster"; domicile = "Vineyard"; } else if (isMax("charm", 2)) { scene = sceneCharm; rank = "Seducer"; domicile = "Guest House"; } else if (isMax("party", 1)) { scene = sceneParty; rank = "Party Animal"; domicile = "Nightclub"; } else if (isMax("stealth", 0)) { scene = sceneStealth; rank = "Invisible"; domicile = "Townhouse"; } // if (isMax("bat")) { else { scene = sceneBat; rank = "Bat"; domicile = "Cave"; } // TODO: Analytics tracker let analytics = { itemsPurloined, vampiricSkills, mortalServants, } let successorOptions = generateSuccessors(0); // TODO: generate nImprovements from mortalServants and the player's bsae improvements let wishOptions = generateWishes(); return { scene, personal: {rank, domicile}, analytics, successorOptions, wishOptions, } } } let active = new Scorer(); export function getScorer(): Scorer { return active; }