Fix the numbers
This commit is contained in:
parent
5ab3778074
commit
81f498c804
@ -106,6 +106,7 @@ export type SuccessorOption = {
|
|||||||
name: string;
|
name: string;
|
||||||
title: string;
|
title: string;
|
||||||
template: Thrall;
|
template: Thrall;
|
||||||
|
nImprovements: number;
|
||||||
note: string | null; // ex "already a vampire"
|
note: string | null; // ex "already a vampire"
|
||||||
stats: Record<Stat, number>;
|
stats: Record<Stat, number>;
|
||||||
talents: Record<Stat, number>;
|
talents: Record<Stat, number>;
|
||||||
|
@ -206,7 +206,9 @@ export class HuntMode {
|
|||||||
this.floatingPlayer = this.floatingPlayer.offset(displacement);
|
this.floatingPlayer = this.floatingPlayer.offset(displacement);
|
||||||
this.velocity = dxy;
|
this.velocity = dxy;
|
||||||
// let friction do it
|
// let friction do it
|
||||||
getPlayerProgress().spendBlood(displacement.distance(new Point(0, 0)) * 10);
|
if (this.map.imposesBloodCosts) {
|
||||||
|
getPlayerProgress().spendBlood(displacement.distance(new Point(0, 0)) * 10 / 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#updateFov() {
|
#updateFov() {
|
||||||
|
@ -34,6 +34,7 @@ const BASIC_PLAN = Grid.createGridFromMultilineString(`
|
|||||||
|
|
||||||
export function generateManor(): LoadedNewMap {
|
export function generateManor(): LoadedNewMap {
|
||||||
let map = new LoadedNewMap("manor", BASIC_PLAN.size);
|
let map = new LoadedNewMap("manor", BASIC_PLAN.size);
|
||||||
|
map.imposesBloodCosts = false;
|
||||||
let thralls = getThralls().getAll();
|
let thralls = getThralls().getAll();
|
||||||
|
|
||||||
for (let y = 0; y < BASIC_PLAN.size.h; y++) {
|
for (let y = 0; y < BASIC_PLAN.size.h; y++) {
|
||||||
|
@ -15,8 +15,8 @@ import {
|
|||||||
import { getPlayerProgress } from "./playerprogress.ts";
|
import { getPlayerProgress } from "./playerprogress.ts";
|
||||||
import { ItemStage } from "./thralls.ts";
|
import { ItemStage } from "./thralls.ts";
|
||||||
|
|
||||||
const WIDTH = 21;
|
const WIDTH = 19;
|
||||||
const HEIGHT = 21;
|
const HEIGHT = 19;
|
||||||
|
|
||||||
const MIN_VAULTS = 1;
|
const MIN_VAULTS = 1;
|
||||||
const MAX_VAULTS = 2;
|
const MAX_VAULTS = 2;
|
||||||
@ -24,7 +24,7 @@ const NUM_VAULT_TRIES = 90;
|
|||||||
const NUM_ROOM_TRIES = 90;
|
const NUM_ROOM_TRIES = 90;
|
||||||
const NUM_STAIRCASE_TRIES = 90;
|
const NUM_STAIRCASE_TRIES = 90;
|
||||||
const NUM_STAIRCASES_DESIRED = 3;
|
const NUM_STAIRCASES_DESIRED = 3;
|
||||||
const NUM_ROOMS_DESIRED = 4;
|
const NUM_ROOMS_DESIRED = 1;
|
||||||
|
|
||||||
const EXTRA_CONNECTOR_CHANCE = 0.15;
|
const EXTRA_CONNECTOR_CHANCE = 0.15;
|
||||||
const WINDING_PERCENT = 50;
|
const WINDING_PERCENT = 50;
|
||||||
|
@ -30,6 +30,7 @@ export class LoadedNewMap {
|
|||||||
#id: string;
|
#id: string;
|
||||||
#size: Size;
|
#size: Size;
|
||||||
#entrance: Point | null;
|
#entrance: Point | null;
|
||||||
|
#imposesBloodCosts: boolean;
|
||||||
#architecture: Grid<Architecture>;
|
#architecture: Grid<Architecture>;
|
||||||
#pickups: Grid<Pickup | null>;
|
#pickups: Grid<Pickup | null>;
|
||||||
#provinces: Grid<string | null>; // TODO: Does this just duplicate zoneLabels
|
#provinces: Grid<string | null>; // TODO: Does this just duplicate zoneLabels
|
||||||
@ -40,6 +41,7 @@ export class LoadedNewMap {
|
|||||||
this.#id = id;
|
this.#id = id;
|
||||||
this.#size = size;
|
this.#size = size;
|
||||||
this.#entrance = null;
|
this.#entrance = null;
|
||||||
|
this.#imposesBloodCosts = true;
|
||||||
this.#architecture = new Grid<Architecture>(size, () => Architecture.Wall);
|
this.#architecture = new Grid<Architecture>(size, () => Architecture.Wall);
|
||||||
this.#pickups = new Grid<Pickup | null>(size, () => null);
|
this.#pickups = new Grid<Pickup | null>(size, () => null);
|
||||||
this.#provinces = new Grid<string | null>(size, () => null);
|
this.#provinces = new Grid<string | null>(size, () => null);
|
||||||
@ -58,6 +60,14 @@ export class LoadedNewMap {
|
|||||||
return this.#entrance;
|
return this.#entrance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set imposesBloodCosts(value: boolean) {
|
||||||
|
this.#imposesBloodCosts = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get imposesBloodCosts() {
|
||||||
|
return this.#imposesBloodCosts;
|
||||||
|
}
|
||||||
|
|
||||||
get size(): Size {
|
get size(): Size {
|
||||||
return this.#size;
|
return this.#size;
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,7 @@ export class StatPickupCallbacks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get cost(): number {
|
get cost(): number {
|
||||||
return 100;
|
return 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
obtain() {
|
obtain() {
|
||||||
@ -248,7 +248,7 @@ export class ExperiencePickupCallbacks {
|
|||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
get cost(): number {
|
get cost(): number {
|
||||||
return 100;
|
return 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
obtain() {
|
obtain() {
|
||||||
@ -319,7 +319,9 @@ export class LadderPickup {
|
|||||||
update() {}
|
update() {}
|
||||||
|
|
||||||
onClick(): boolean {
|
onClick(): boolean {
|
||||||
getPlayerProgress().addBlood(1000);
|
if (getHuntMode().map.imposesBloodCosts) {
|
||||||
|
getPlayerProgress().addBlood(100); // this used to award 1k; 100 now is equivalent to what 300 blood used to be
|
||||||
|
}
|
||||||
initHuntMode(new HuntMode(getHuntMode().depth + 1, generateMap()));
|
initHuntMode(new HuntMode(getHuntMode().depth + 1, generateMap()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import { getThralls, ItemStage, LifeStage, Thrall } from "./thralls.ts";
|
|||||||
export class PlayerProgress {
|
export class PlayerProgress {
|
||||||
#name: string;
|
#name: string;
|
||||||
#thrallTemplate: number;
|
#thrallTemplate: number;
|
||||||
|
#nImprovements: number;
|
||||||
#stats: Record<Stat, number>;
|
#stats: Record<Stat, number>;
|
||||||
#talents: Record<Stat, number>;
|
#talents: Record<Stat, number>;
|
||||||
#isInPenance: boolean;
|
#isInPenance: boolean;
|
||||||
@ -22,6 +23,7 @@ export class PlayerProgress {
|
|||||||
constructor(asSuccessor: SuccessorOption, withWish: Wish | null) {
|
constructor(asSuccessor: SuccessorOption, withWish: Wish | null) {
|
||||||
this.#name = asSuccessor.name;
|
this.#name = asSuccessor.name;
|
||||||
this.#thrallTemplate = asSuccessor.template.id;
|
this.#thrallTemplate = asSuccessor.template.id;
|
||||||
|
this.#nImprovements = asSuccessor.nImprovements;
|
||||||
this.#stats = { ...asSuccessor.stats };
|
this.#stats = { ...asSuccessor.stats };
|
||||||
this.#talents = { ...asSuccessor.talents };
|
this.#talents = { ...asSuccessor.talents };
|
||||||
this.#isInPenance = asSuccessor.inPenance;
|
this.#isInPenance = asSuccessor.inPenance;
|
||||||
@ -53,12 +55,16 @@ export class PlayerProgress {
|
|||||||
return { id: this.#thrallTemplate };
|
return { id: this.#thrallTemplate };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get nImprovements(): number {
|
||||||
|
return this.#nImprovements;
|
||||||
|
}
|
||||||
|
|
||||||
get isInPenance(): boolean {
|
get isInPenance(): boolean {
|
||||||
return this.#isInPenance;
|
return this.#isInPenance;
|
||||||
}
|
}
|
||||||
|
|
||||||
refill() {
|
refill() {
|
||||||
this.#blood = 2000;
|
this.#blood = 1000;
|
||||||
|
|
||||||
let learnableSkills = []; // TODO: Also include costing info
|
let learnableSkills = []; // TODO: Also include costing info
|
||||||
for (let skill of getSkills()
|
for (let skill of getSkills()
|
||||||
|
@ -122,7 +122,7 @@ class Scorer {
|
|||||||
vampiricSkills,
|
vampiricSkills,
|
||||||
mortalServants,
|
mortalServants,
|
||||||
};
|
};
|
||||||
let successorOptions = generateSuccessors(0, penance); // TODO: generate nImprovements from mortalServants and the player's bsae improvements
|
let successorOptions = generateSuccessors(getPlayerProgress().nImprovements + 2, penance); // TODO: generate nImprovements from mortalServants and the player's bsae improvements
|
||||||
let wishOptions = generateWishes(penance);
|
let wishOptions = generateWishes(penance);
|
||||||
|
|
||||||
let progenerateVerb = penance ? "Repent" : "Progenerate";
|
let progenerateVerb = penance ? "Repent" : "Progenerate";
|
||||||
|
@ -38,16 +38,22 @@ class SkillsTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
computeCost(skill: Skill) {
|
computeCost(skill: Skill) {
|
||||||
|
const _STAT_TO_TRIPS: Record<Stat, number> = {
|
||||||
|
"AGI": 1/7.2, // 8.4 is what I measured, but this seems very overpriced in practice
|
||||||
|
"INT": 1/5.4,
|
||||||
|
"CHA": 1/4.8,
|
||||||
|
"PSI": 1/7.0,
|
||||||
|
};
|
||||||
let data = this.get(skill);
|
let data = this.get(skill);
|
||||||
|
|
||||||
let governingStatValue = 0;
|
let governingStatValue = 0;
|
||||||
for (let stat of data.governing.stats.values()) {
|
for (let stat of data.governing.stats.values()) {
|
||||||
governingStatValue +=
|
governingStatValue +=
|
||||||
getPlayerProgress().getStat(stat) / data.governing.stats.length;
|
getPlayerProgress().getStat(stat) * _STAT_TO_TRIPS[stat] / data.governing.stats.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.governing.flipped) {
|
if (data.governing.flipped) {
|
||||||
governingStatValue = -governingStatValue + 10;
|
governingStatValue = -governingStatValue + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mult = getCostMultiplier(getPlayerProgress().getWish(), skill);
|
let mult = getCostMultiplier(getPlayerProgress().getWish(), skill);
|
||||||
@ -94,7 +100,7 @@ function geomInterpolate(
|
|||||||
return lowOut * Math.pow(highOut / lowOut, proportion);
|
return lowOut * Math.pow(highOut / lowOut, proportion);
|
||||||
}
|
}
|
||||||
|
|
||||||
type Difficulty = 0 | 1 | 1.25 | 2 | 3;
|
type Difficulty = -0.25 | -0.125 | 0 | 1 | 1.25 | 2 | 3;
|
||||||
type GoverningTemplate = {
|
type GoverningTemplate = {
|
||||||
stats: Stat[];
|
stats: Stat[];
|
||||||
note: string;
|
note: string;
|
||||||
@ -158,34 +164,46 @@ function governing(
|
|||||||
let cost: number;
|
let cost: number;
|
||||||
let mortalServantValue: number;
|
let mortalServantValue: number;
|
||||||
switch (difficulty) {
|
switch (difficulty) {
|
||||||
|
case -0.25:
|
||||||
|
underTarget = 0.0;
|
||||||
|
target = 3.9;
|
||||||
|
cost = 50;
|
||||||
|
mortalServantValue = 1;
|
||||||
|
break;
|
||||||
|
case -0.125:
|
||||||
|
underTarget = 0.25;
|
||||||
|
target = 4.25;
|
||||||
|
cost = 50;
|
||||||
|
mortalServantValue = 1;
|
||||||
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
underTarget = 5;
|
underTarget = 0.5;
|
||||||
target = 15;
|
target = 4.5;
|
||||||
cost = 50;
|
cost = 50;
|
||||||
mortalServantValue = 1;
|
mortalServantValue = 1;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
underTarget = 15;
|
underTarget = 4;
|
||||||
target = 40;
|
target = 10;
|
||||||
cost = 100;
|
cost = 50;
|
||||||
mortalServantValue = 2;
|
mortalServantValue = 2;
|
||||||
break;
|
break;
|
||||||
case 1.25:
|
case 1.25:
|
||||||
underTarget = 17;
|
underTarget = 5;
|
||||||
target = 42;
|
target = 12;
|
||||||
cost = 100;
|
cost = 50;
|
||||||
mortalServantValue = 2;
|
mortalServantValue = 2;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
underTarget = 30;
|
underTarget = 10;
|
||||||
target = 70;
|
target = 18;
|
||||||
cost = 125;
|
cost = 75;
|
||||||
mortalServantValue = 3;
|
mortalServantValue = 3;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
underTarget = 50;
|
underTarget = 14;
|
||||||
target = 100;
|
target = 23;
|
||||||
cost = 150;
|
cost = 100;
|
||||||
mortalServantValue = 10;
|
mortalServantValue = 10;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -247,7 +265,7 @@ export let bat3 = table.add({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export let stealth0 = table.add({
|
export let stealth0 = table.add({
|
||||||
governing: governing("stealth", 0),
|
governing: governing("stealth", -0.25),
|
||||||
profile: {
|
profile: {
|
||||||
name: "Be Quiet",
|
name: "Be Quiet",
|
||||||
description:
|
description:
|
||||||
@ -284,7 +302,7 @@ export let stealth3 = table.add({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export let charm0 = table.add({
|
export let charm0 = table.add({
|
||||||
governing: governing("charm", 0),
|
governing: governing("charm", -0.125),
|
||||||
profile: {
|
profile: {
|
||||||
name: "Flatter",
|
name: "Flatter",
|
||||||
description:
|
description:
|
||||||
|
@ -10,6 +10,7 @@ import { openingScene } from "./openingscene.ts";
|
|||||||
import { generateName } from "./namegen.ts";
|
import { generateName } from "./namegen.ts";
|
||||||
import { photogenicThralls } from "./thralls.ts";
|
import { photogenicThralls } from "./thralls.ts";
|
||||||
import { choose } from "./utils.ts";
|
import { choose } from "./utils.ts";
|
||||||
|
import {generateSuccessor} from "./successors.ts";
|
||||||
|
|
||||||
const N_TURNS: number = 9;
|
const N_TURNS: number = 9;
|
||||||
|
|
||||||
@ -34,6 +35,7 @@ export class StateManager {
|
|||||||
{
|
{
|
||||||
name: generateName(),
|
name: generateName(),
|
||||||
template: choose(photogenicThralls),
|
template: choose(photogenicThralls),
|
||||||
|
nImprovements: 0,
|
||||||
title: "",
|
title: "",
|
||||||
note: null,
|
note: null,
|
||||||
stats: { AGI: 10, INT: 10, CHA: 10, PSI: 10 },
|
stats: { AGI: 10, INT: 10, CHA: 10, PSI: 10 },
|
||||||
|
@ -37,6 +37,7 @@ export function generateSuccessorFromPlayer(): SuccessorOption {
|
|||||||
let successor = {
|
let successor = {
|
||||||
name: progress.name,
|
name: progress.name,
|
||||||
template: progress.template,
|
template: progress.template,
|
||||||
|
nImprovements: progress.nImprovements - 2,
|
||||||
title: "Penitent",
|
title: "Penitent",
|
||||||
note: "Failed at Master's bidding",
|
note: "Failed at Master's bidding",
|
||||||
stats: { ...progress.getStats() },
|
stats: { ...progress.getStats() },
|
||||||
@ -78,8 +79,9 @@ export function generateSuccessor(nImprovements: number): SuccessorOption {
|
|||||||
talents[choose(ALL_STATS)] += 1;
|
talents[choose(ALL_STATS)] += 1;
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
let nTotalImprovements = nImprovements + 5;
|
let nTotalImprovements = nImprovements;
|
||||||
for (let i = 0; i < nTotalImprovements; i++) {
|
let mult = 1;
|
||||||
|
for (let i = 0; i < nTotalImprovements * mult; i++) {
|
||||||
let improvement =
|
let improvement =
|
||||||
improvements[Math.floor(Math.random() * improvements.length)];
|
improvements[Math.floor(Math.random() * improvements.length)];
|
||||||
improvement();
|
improvement();
|
||||||
@ -91,6 +93,7 @@ export function generateSuccessor(nImprovements: number): SuccessorOption {
|
|||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
template,
|
template,
|
||||||
|
nImprovements,
|
||||||
title,
|
title,
|
||||||
note,
|
note,
|
||||||
stats,
|
stats,
|
||||||
|
@ -140,7 +140,7 @@ export let thrallParty = table.add({
|
|||||||
'"Oh, that? Yeah, I won it." And then lost it, apparently.\n\nHe\'s elated. He will never leave.',
|
'"Oh, that? Yeah, I won it." And then lost it, apparently.\n\nHe\'s elated. He will never leave.',
|
||||||
rewardMessage: "Garrett showers you with INT!",
|
rewardMessage: "Garrett showers you with INT!",
|
||||||
rewardCallback: (spawn) => {
|
rewardCallback: (spawn) => {
|
||||||
for (let i = 0; i < 30; i++) {
|
for (let i = 0; i < 12; i++) {
|
||||||
spawn("INT");
|
spawn("INT");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -216,7 +216,7 @@ export let thrallLore = table.add({
|
|||||||
"Lupin looks at his own reflection -- with interest, confusion, dismissal, and then deep satisfaction. He loves it. He will never leave.",
|
"Lupin looks at his own reflection -- with interest, confusion, dismissal, and then deep satisfaction. He loves it. He will never leave.",
|
||||||
rewardMessage: "Lupin showers you with AGI!",
|
rewardMessage: "Lupin showers you with AGI!",
|
||||||
rewardCallback: (spawn) => {
|
rewardCallback: (spawn) => {
|
||||||
for (let i = 0; i < 30; i++) {
|
for (let i = 0; i < 12; i++) {
|
||||||
spawn("AGI");
|
spawn("AGI");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -289,10 +289,10 @@ export let thrallBat = table.add({
|
|||||||
'Monica salivates. "This is... this is... simply exquisite!"\n\nShe is happy. She will never leave.',
|
'Monica salivates. "This is... this is... simply exquisite!"\n\nShe is happy. She will never leave.',
|
||||||
rewardMessage: "Monica showers you with CHA and INT!",
|
rewardMessage: "Monica showers you with CHA and INT!",
|
||||||
rewardCallback: (spawn) => {
|
rewardCallback: (spawn) => {
|
||||||
for (let i = 0; i < 15; i++) {
|
for (let i = 0; i < 8; i++) {
|
||||||
spawn("CHA");
|
spawn("CHA");
|
||||||
}
|
}
|
||||||
for (let i = 0; i < 15; i++) {
|
for (let i = 0; i < 4; i++) {
|
||||||
spawn("INT");
|
spawn("INT");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -365,7 +365,7 @@ export let thrallCharm = table.add({
|
|||||||
"Renfield inhales sharply and widens his stance, trying to hide his physical reaction to your face. He is elated and will never leave.",
|
"Renfield inhales sharply and widens his stance, trying to hide his physical reaction to your face. He is elated and will never leave.",
|
||||||
rewardMessage: "Renfield showers you with PSI!",
|
rewardMessage: "Renfield showers you with PSI!",
|
||||||
rewardCallback: (spawn) => {
|
rewardCallback: (spawn) => {
|
||||||
for (let i = 0; i < 24; i++) {
|
for (let i = 0; i < 12; i++) {
|
||||||
spawn("PSI");
|
spawn("PSI");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -439,10 +439,10 @@ export let thrallStealth = table.add({
|
|||||||
"\"That? That's not mine.\" But she wants it. Now it's hers. She will never leave.",
|
"\"That? That's not mine.\" But she wants it. Now it's hers. She will never leave.",
|
||||||
rewardMessage: "Narthyss showers you with CHA and AGI!",
|
rewardMessage: "Narthyss showers you with CHA and AGI!",
|
||||||
rewardCallback: (spawn) => {
|
rewardCallback: (spawn) => {
|
||||||
for (let i = 0; i < 15; i++) {
|
for (let i = 0; i < 8; i++) {
|
||||||
spawn("CHA");
|
spawn("CHA");
|
||||||
}
|
}
|
||||||
for (let i = 0; i < 15; i++) {
|
for (let i = 0; i < 4; i++) {
|
||||||
spawn("AGI");
|
spawn("AGI");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -516,7 +516,7 @@ export let thrallStare = table.add({
|
|||||||
"Ridley admires the gear but -- to your surprise -- refuses to jam it into its brain.\n\nThe pup is elated and will never leave.",
|
"Ridley admires the gear but -- to your surprise -- refuses to jam it into its brain.\n\nThe pup is elated and will never leave.",
|
||||||
rewardMessage: "Ridley showers you with EXP!",
|
rewardMessage: "Ridley showers you with EXP!",
|
||||||
rewardCallback: (spawn) => {
|
rewardCallback: (spawn) => {
|
||||||
for (let i = 0; i < 10; i++) {
|
for (let i = 0; i < 12; i++) {
|
||||||
spawn("EXP");
|
spawn("EXP");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user