103 lines
2.9 KiB
TypeScript
103 lines
2.9 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> = {};
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
// 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: 0,
|
|
vampiricSkills: 0,
|
|
mortalServants: 0,
|
|
}
|
|
let successorOptions = generateSuccessors(0); // TODO: generate nImprovements from score
|
|
let wishOptions = generateWishes();
|
|
|
|
return {
|
|
scene,
|
|
personal: {rank, domicile},
|
|
analytics,
|
|
successorOptions,
|
|
wishOptions,
|
|
}
|
|
}
|
|
}
|
|
|
|
let active = new Scorer();
|
|
export function getScorer(): Scorer {
|
|
return active;
|
|
}
|