fledgling/src/scorer.ts

111 lines
3.2 KiB
TypeScript

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<string, number> = {};
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<string, number> = {...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;
}