284 lines
6.5 KiB
TypeScript
284 lines
6.5 KiB
TypeScript
import { Skill, Wish, WishData } from "./datatypes.ts";
|
|
import { shuffle } from "./utils.ts";
|
|
import {
|
|
bat0,
|
|
bat1,
|
|
bat2,
|
|
bat3,
|
|
charm0,
|
|
charm1,
|
|
charm2,
|
|
charm3,
|
|
getSkills,
|
|
lore0,
|
|
lore1,
|
|
lore2,
|
|
party0,
|
|
party1,
|
|
party2,
|
|
party3,
|
|
sorry0,
|
|
sorry1,
|
|
sorry2,
|
|
stare0,
|
|
stare1,
|
|
stare2,
|
|
stare3,
|
|
stealth0,
|
|
stealth1,
|
|
stealth2,
|
|
stealth3,
|
|
} from "./skills.ts";
|
|
import { compile, VNSceneBasisPart } from "./vnscene.ts";
|
|
import { getPlayerProgress } from "./playerprogress.ts";
|
|
|
|
class WishesTable {
|
|
#wishes: WishData[];
|
|
|
|
constructor() {
|
|
this.#wishes = [];
|
|
}
|
|
|
|
add(data: WishData): Wish {
|
|
let id = this.#wishes.length;
|
|
this.#wishes.push(data);
|
|
return { id };
|
|
}
|
|
|
|
get(wish: Wish): WishData {
|
|
return this.#wishes[wish.id];
|
|
}
|
|
|
|
getAllRandomWishes(): Wish[] {
|
|
let wishes: Wish[] = [];
|
|
for (let i = 0; i < this.#wishes.length; i++) {
|
|
if (this.#wishes[i].isRandomlyAvailable) {
|
|
wishes.push({ id: i });
|
|
}
|
|
}
|
|
return wishes;
|
|
}
|
|
}
|
|
|
|
let table = new WishesTable();
|
|
export function getWishes(): WishesTable {
|
|
return table;
|
|
}
|
|
|
|
const whisper: VNSceneBasisPart = {
|
|
type: "message",
|
|
text: "...",
|
|
sfx: "whisper.mp3",
|
|
};
|
|
|
|
export const celebritySocialite = table.add({
|
|
profile: {
|
|
name: "Celebrity Socialite",
|
|
note: "+Charm -Lore",
|
|
domicile: "Party Mansion",
|
|
reignSentence: "A lot of people know who you are and like you.",
|
|
failureName: "Z-List Bloodstarver",
|
|
failureDomicile: "Obscure Soap Ad",
|
|
failureReignSentence: "Nobody really knows who you are.",
|
|
failureSuccessorVerb: "Apologize For Your Failure",
|
|
},
|
|
isRandomlyAvailable: true,
|
|
isCompulsory: false,
|
|
bannedSkills: () => [lore0],
|
|
discouragedSkills: () => [stealth0, stealth1, stealth2, stealth3],
|
|
encouragedSkills: () => [party0, party1, party2, party3],
|
|
requiredSkills: () => [charm0, charm1, charm2],
|
|
prologue: compile([
|
|
whisper,
|
|
"Master?",
|
|
whisper,
|
|
"I see.",
|
|
"You. I -- should I buy a guitar or something?",
|
|
whisper,
|
|
"My looks and my party skills...",
|
|
]),
|
|
onFailure: compile([
|
|
whisper,
|
|
"You're displeased...",
|
|
whisper,
|
|
"I'm not popular enough?",
|
|
"I see.",
|
|
]),
|
|
onVictory: compile([
|
|
whisper,
|
|
"I did as you commanded.",
|
|
"You're pleased?",
|
|
"... I'm free.",
|
|
]),
|
|
});
|
|
|
|
export const nightswornAlchemist = table.add({
|
|
profile: {
|
|
name: "Nightsworn Alchemist",
|
|
note: "+Lore -Party",
|
|
domicile: "Alchemical Lab",
|
|
reignSentence:
|
|
"You understand the fundamental connection between wine and blood.",
|
|
failureName: "Failure of Science",
|
|
failureDomicile: "Remedial College",
|
|
failureReignSentence: "You don't understand much of anything.",
|
|
failureSuccessorVerb: "Apologize For Your Failure",
|
|
},
|
|
isRandomlyAvailable: true,
|
|
isCompulsory: false,
|
|
bannedSkills: () => [party0],
|
|
discouragedSkills: () => [charm0, charm1, charm2, charm3],
|
|
encouragedSkills: () => [stare0, stare1, stare2, stare3],
|
|
requiredSkills: () => [lore0, lore1, lore2],
|
|
prologue: compile([
|
|
whisper,
|
|
"Master?",
|
|
whisper,
|
|
"I see.",
|
|
"You. I -- should dedicate my life to the vampiric sciences.",
|
|
whisper,
|
|
"My looks and my party skills...",
|
|
]),
|
|
onFailure: compile([
|
|
whisper,
|
|
"You're displeased...",
|
|
whisper,
|
|
"I should have learned more lore.",
|
|
]),
|
|
onVictory: compile([
|
|
whisper,
|
|
"I did as you commanded.",
|
|
"You're pleased?",
|
|
"... I'm free.",
|
|
]),
|
|
});
|
|
|
|
export const batFreak = table.add({
|
|
profile: {
|
|
name: "Bat Freak",
|
|
note: "++Bat -All",
|
|
domicile: "Master's Chiropteriary",
|
|
reignSentence: "You're an idol among bats.",
|
|
failureName: "Practically Mortal",
|
|
failureDomicile: "Right Side Up",
|
|
failureReignSentence: "Bats can tell you don't skreek correctly.",
|
|
failureSuccessorVerb: "Apologize -- SKREEK!",
|
|
},
|
|
isRandomlyAvailable: true,
|
|
isCompulsory: false,
|
|
bannedSkills: () => [charm0, stare0, party0, lore0],
|
|
discouragedSkills: () => [],
|
|
encouragedSkills: () => [stealth0, stealth1, stealth2, stealth3],
|
|
requiredSkills: () => [bat0, bat1, bat2, bat3],
|
|
prologue: compile([
|
|
whisper,
|
|
"Master?",
|
|
whisper,
|
|
"I see.",
|
|
"You -- SKKREEK -- want me to become a -- SKKREEK --",
|
|
]),
|
|
onFailure: compile([
|
|
whisper,
|
|
"You're displeased...",
|
|
whisper,
|
|
"I -- SKREEEEK -- should have spent more time becoming a bat...",
|
|
]),
|
|
onVictory: compile([whisper, "SKRSKRSKRSK.", "I'm FREEEEEEEEEE --"]),
|
|
});
|
|
|
|
export const repent = table.add({
|
|
profile: {
|
|
name: "Not Even Fit To Be Bat Food",
|
|
note: "--All",
|
|
domicile: "Master's Home",
|
|
reignSentence: "You are almost, but not quite loved.",
|
|
failureName: "Can't Even Repent Correctly",
|
|
failureDomicile: "Homeless",
|
|
failureReignSentence: "You are unloved and disrespected.",
|
|
failureSuccessorVerb: "Apologize Again",
|
|
},
|
|
isRandomlyAvailable: false,
|
|
isCompulsory: true,
|
|
bannedSkills: () => getSkills().getAvailableSkills(false),
|
|
discouragedSkills: () => [],
|
|
encouragedSkills: () => [],
|
|
requiredSkills: () => [sorry0, sorry1, sorry2],
|
|
prologue: compile([
|
|
whisper,
|
|
"I'm sorry.",
|
|
"Please...",
|
|
whisper,
|
|
"I must repent.",
|
|
]),
|
|
onFailure: compile([
|
|
whisper,
|
|
"I can't --",
|
|
"I must --",
|
|
whisper,
|
|
"Master -- please, no, I --",
|
|
]),
|
|
onVictory: compile([whisper, "Yes, I see.", "I'm free...?"]),
|
|
});
|
|
|
|
export function generateWishes(penance: boolean): Wish[] {
|
|
if (penance) {
|
|
return [repent];
|
|
}
|
|
|
|
let possibleWishes = table.getAllRandomWishes();
|
|
shuffle(possibleWishes);
|
|
|
|
let selectedWishes: Wish[] = [];
|
|
for (let i = 0; i < possibleWishes.length; i++) {
|
|
selectedWishes.push(possibleWishes[i]);
|
|
}
|
|
return selectedWishes;
|
|
}
|
|
|
|
export function getCostMultiplier(wish: Wish | null, skill: Skill): number {
|
|
if (wish == null) {
|
|
return 1.0;
|
|
}
|
|
|
|
let wishData = getWishes().get(wish);
|
|
|
|
for (let subj of wishData.requiredSkills()) {
|
|
if (subj.id == skill.id) {
|
|
return 0.75;
|
|
}
|
|
}
|
|
for (let subj of wishData.encouragedSkills()) {
|
|
if (subj.id == skill.id) {
|
|
return 0.875;
|
|
}
|
|
}
|
|
|
|
for (let subj of wishData.discouragedSkills()) {
|
|
if (subj.id == skill.id) {
|
|
return 1.25;
|
|
}
|
|
}
|
|
|
|
for (let subj of wishData.bannedSkills()) {
|
|
if (subj.id == skill.id) {
|
|
return 9999.0;
|
|
}
|
|
}
|
|
|
|
return 1.0;
|
|
}
|
|
|
|
export function isWishCompleted(wish: Wish): boolean {
|
|
let player = getPlayerProgress();
|
|
|
|
let wishData = getWishes().get(wish);
|
|
|
|
for (let subj of wishData.requiredSkills()) {
|
|
if (!player.hasLearned(subj)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|