Raise costs for skills prohibited by wish
This commit is contained in:
parent
1902f6e70b
commit
8c917df618
@ -34,8 +34,16 @@ export type Skill = {
|
|||||||
id: number
|
id: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type WishData = {
|
||||||
export type Wish = "celebritySocialite" | "nightswornAlchemist" | "batFreak";
|
profile: {name: string},
|
||||||
|
bannedSkills: () => Skill[],
|
||||||
|
discouragedSkills: () => Skill[],
|
||||||
|
encouragedSkills: () => Skill[],
|
||||||
|
requiredSkills: () => Skill[]
|
||||||
|
}
|
||||||
|
export type Wish = {
|
||||||
|
id: number
|
||||||
|
}
|
||||||
|
|
||||||
// endings
|
// endings
|
||||||
|
|
||||||
|
@ -4,8 +4,9 @@ import {BG_INSET, FG_BOLD, FG_TEXT} from "./colors.ts";
|
|||||||
import {AlignX, AlignY, Point, Rect, Size} from "./engine/datatypes.ts";
|
import {AlignX, AlignY, Point, Rect, Size} from "./engine/datatypes.ts";
|
||||||
import {DrawPile} from "./drawpile.ts";
|
import {DrawPile} from "./drawpile.ts";
|
||||||
import {addButton} from "./button.ts";
|
import {addButton} from "./button.ts";
|
||||||
import {ALL_STATS, Ending, Wish} from "./datatypes.ts";
|
import {ALL_STATS, Ending} from "./datatypes.ts";
|
||||||
import {getStateManager} from "./statemanager.ts";
|
import {getStateManager} from "./statemanager.ts";
|
||||||
|
import {getWishes} from "./wishes.ts";
|
||||||
|
|
||||||
const WIDTH = 384;
|
const WIDTH = 384;
|
||||||
const HEIGHT = 384;
|
const HEIGHT = 384;
|
||||||
@ -240,7 +241,7 @@ export class EndgameModal {
|
|||||||
let generalRect = new Rect(at, new Size(w, h));
|
let generalRect = new Rect(at, new Size(w, h));
|
||||||
let enabled = true;
|
let enabled = true;
|
||||||
|
|
||||||
let wishLabel = wishLabels[wishOption];
|
let wishData = getWishes().get(wishOption);
|
||||||
|
|
||||||
this.#drawpile.addClickable(
|
this.#drawpile.addClickable(
|
||||||
0,
|
0,
|
||||||
@ -256,7 +257,7 @@ export class EndgameModal {
|
|||||||
at.offset(new Point(2, 4)), new Size(w - 4, h - 8), fg,
|
at.offset(new Point(2, 4)), new Size(w - 4, h - 8), fg,
|
||||||
)
|
)
|
||||||
|
|
||||||
D.drawText(wishLabel, at.offset(new Point(w / 2,h / 2 )), fgBold, {
|
D.drawText(wishData.profile.name, at.offset(new Point(w / 2,h / 2 )), fgBold, {
|
||||||
forceWidth: w - 4,
|
forceWidth: w - 4,
|
||||||
alignX: AlignX.Center,
|
alignX: AlignX.Center,
|
||||||
alignY: AlignY.Middle,
|
alignY: AlignY.Middle,
|
||||||
@ -280,11 +281,6 @@ export class EndgameModal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const wishLabels: Record<Wish, string> = {
|
|
||||||
celebritySocialite: "Celebrity Socialite",
|
|
||||||
nightswornAlchemist: "Nightsworn Alchemist",
|
|
||||||
batFreak: "Bat Freak"
|
|
||||||
}
|
|
||||||
|
|
||||||
let active = new EndgameModal();
|
let active = new EndgameModal();
|
||||||
export function getEndgameModal() {
|
export function getEndgameModal() {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import {hostGame} from "./engine/internal/host.ts";
|
import {hostGame} from "./engine/internal/host.ts";
|
||||||
import {game} from "./game.ts";
|
import {game} from "./game.ts";
|
||||||
import {getStateManager} from "./statemanager.ts";
|
import {getStateManager} from "./statemanager.ts";
|
||||||
|
import {batFreak} from "./wishes.ts";
|
||||||
|
|
||||||
getStateManager().startGame({
|
getStateManager().startGame({
|
||||||
name: "Pyrex",
|
name: "Pyrex",
|
||||||
@ -8,5 +9,5 @@ getStateManager().startGame({
|
|||||||
note: null,
|
note: null,
|
||||||
stats: {AGI: 10, INT: 10, CHA: 10, PSI: 10},
|
stats: {AGI: 10, INT: 10, CHA: 10, PSI: 10},
|
||||||
talents: {AGI: 0, INT: 0, CHA: 0, PSI: 0},
|
talents: {AGI: 0, INT: 0, CHA: 0, PSI: 0},
|
||||||
}, null);
|
}, batFreak);
|
||||||
hostGame(game);
|
hostGame(game);
|
@ -141,6 +141,10 @@ export class PlayerProgress {
|
|||||||
this.#blood -= amt;
|
this.#blood -= amt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getWish(): Wish | null {
|
||||||
|
return this.#wish
|
||||||
|
}
|
||||||
|
|
||||||
getAvailableSkills(): Skill[] {
|
getAvailableSkills(): Skill[] {
|
||||||
// Sort by cost, then by name, then trim down to first 6
|
// Sort by cost, then by name, then trim down to first 6
|
||||||
let skillsAvailable = [...this.#untrimmedSkillsAvailable];
|
let skillsAvailable = [...this.#untrimmedSkillsAvailable];
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import {Skill, SkillData, SkillGoverning, SkillScoring, Stat} from "./datatypes.ts";
|
import {Skill, SkillData, SkillGoverning, SkillScoring, Stat} from "./datatypes.ts";
|
||||||
import {getPlayerProgress} from "./playerprogress.ts";
|
import {getPlayerProgress} from "./playerprogress.ts";
|
||||||
|
import {getCostMultiplier} from "./wishes.ts";
|
||||||
|
|
||||||
class SkillsTable {
|
class SkillsTable {
|
||||||
#skills: SkillData[]
|
#skills: SkillData[]
|
||||||
@ -34,9 +35,14 @@ class SkillsTable {
|
|||||||
governingStatValue += getPlayerProgress().getStat(stat) / data.governing.stats.length;
|
governingStatValue += getPlayerProgress().getStat(stat) / data.governing.stats.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mult = getCostMultiplier(getPlayerProgress().getWish(), skill);
|
||||||
|
let [underTarget, target] = [data.governing.underTarget, data.governing.target];
|
||||||
|
underTarget = mult * underTarget;
|
||||||
|
target = mult * target;
|
||||||
|
|
||||||
return Math.floor(geomInterpolate(
|
return Math.floor(geomInterpolate(
|
||||||
governingStatValue,
|
governingStatValue,
|
||||||
data.governing.underTarget, data.governing.target,
|
underTarget, target,
|
||||||
data.governing.cost, 999
|
data.governing.cost, 999
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
12
src/utils.ts
12
src/utils.ts
@ -4,3 +4,15 @@ export function choose<T>(array: Array<T>): T {
|
|||||||
}
|
}
|
||||||
return array[Math.floor(Math.random() * array.length)]
|
return array[Math.floor(Math.random() * array.length)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function shuffle<T>(array: Array<T>) {
|
||||||
|
// source: https://stackoverflow.com/posts/2450976/revisions
|
||||||
|
let currentIndex = array.length;
|
||||||
|
while (currentIndex != 0) {
|
||||||
|
let randomIndex = Math.floor(Math.random() * currentIndex);
|
||||||
|
currentIndex--;
|
||||||
|
|
||||||
|
[array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
105
src/wishes.ts
105
src/wishes.ts
@ -1,5 +1,106 @@
|
|||||||
import {Wish} from "./datatypes.ts";
|
import {Skill, Wish, WishData} from "./datatypes.ts";
|
||||||
|
import {shuffle} from "./utils.ts";
|
||||||
|
import {
|
||||||
|
bat0, bat1, bat2,
|
||||||
|
bat3,
|
||||||
|
charm0,
|
||||||
|
charm1,
|
||||||
|
charm2,
|
||||||
|
charm3,
|
||||||
|
lore0, lore1, lore2,
|
||||||
|
party0,
|
||||||
|
party1, party2, party3, stare0, stare1, stare2, stare3,
|
||||||
|
stealth0,
|
||||||
|
stealth1,
|
||||||
|
stealth2,
|
||||||
|
stealth3
|
||||||
|
} from "./skills.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];
|
||||||
|
}
|
||||||
|
|
||||||
|
getAllPossibleWishes(): Wish[] {
|
||||||
|
let wishes: Wish[] = [];
|
||||||
|
for (let i = 0; i < this.#wishes.length; i++) {
|
||||||
|
wishes.push({id: i});
|
||||||
|
}
|
||||||
|
return wishes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let table = new WishesTable();
|
||||||
|
export function getWishes(): WishesTable {
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const celebritySocialite = table.add({
|
||||||
|
profile: {name: "Celebrity Socialite"},
|
||||||
|
bannedSkills: () => [lore0],
|
||||||
|
discouragedSkills: () => [stealth0, stealth1, stealth2, stealth3],
|
||||||
|
encouragedSkills: () => [party0, party1, party2, party3],
|
||||||
|
requiredSkills: () => [charm0, charm1, charm2],
|
||||||
|
});
|
||||||
|
|
||||||
|
export const nightswornAlchemist = table.add({
|
||||||
|
profile: {name: "Nightsworn Alchemist"},
|
||||||
|
bannedSkills: () => [party0],
|
||||||
|
discouragedSkills: () => [charm0, charm1, charm2, charm3],
|
||||||
|
encouragedSkills: () => [stare0, stare1, stare2, stare3],
|
||||||
|
requiredSkills: () => [lore0, lore1, lore2]
|
||||||
|
});
|
||||||
|
|
||||||
|
export const batFreak = table.add({
|
||||||
|
profile: {name: "Bat Freak"},
|
||||||
|
bannedSkills: () => [charm0, stare0, party0, lore0],
|
||||||
|
discouragedSkills: () => [],
|
||||||
|
encouragedSkills: () => [stealth0, stealth1, stealth2, stealth3],
|
||||||
|
requiredSkills: () => [bat0, bat1, bat2, bat3]
|
||||||
|
});
|
||||||
|
|
||||||
export function generateWishes(): Wish[] {
|
export function generateWishes(): Wish[] {
|
||||||
return ["celebritySocialite", "nightswornAlchemist", "batFreak"];
|
let possibleWishes = table.getAllPossibleWishes();
|
||||||
|
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;
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user