Thrall item pickups
Before Width: | Height: | Size: 523 B After Width: | Height: | Size: 597 B |
Before Width: | Height: | Size: 601 B After Width: | Height: | Size: 660 B |
Before Width: | Height: | Size: 614 B After Width: | Height: | Size: 676 B |
Before Width: | Height: | Size: 559 B After Width: | Height: | Size: 630 B |
Before Width: | Height: | Size: 570 B After Width: | Height: | Size: 652 B |
Before Width: | Height: | Size: 572 B After Width: | Height: | Size: 647 B |
@ -107,13 +107,14 @@ export class CheckModal {
|
|||||||
let skill = option.skill();
|
let skill = option.skill();
|
||||||
let skillName = getSkills().get(skill).profile.name;
|
let skillName = getSkills().get(skill).profile.name;
|
||||||
let hasSkill = getPlayerProgress().hasLearned(skill);
|
let hasSkill = getPlayerProgress().hasLearned(skill);
|
||||||
// hasSkill ||= true;
|
hasSkill ||= true;
|
||||||
if (hasSkill) {
|
if (hasSkill) {
|
||||||
optionLabel = `[${skillName}] ${option.unlockable}`;
|
optionLabel = `[${skillName}] ${option.unlockable}`;
|
||||||
} else {
|
} else {
|
||||||
optionLabel = `[Needs ${skillName}] ${option.locked}`;
|
optionLabel = `[Needs ${skillName}] ${option.locked}`;
|
||||||
}
|
}
|
||||||
resultMessage = hasSkill ? option.success : option.failure;
|
resultMessage = hasSkill ? option.success : option.failure;
|
||||||
|
accomplished = hasSkill;
|
||||||
}
|
}
|
||||||
addButton(this.#drawpile, optionLabel, rect, true, () => {
|
addButton(this.#drawpile, optionLabel, rect, true, () => {
|
||||||
this.#success = resultMessage;
|
this.#success = resultMessage;
|
||||||
|
@ -3,6 +3,7 @@ import { Grid, Point } from "./engine/datatypes.ts";
|
|||||||
import { getThralls } from "./thralls.ts";
|
import { getThralls } from "./thralls.ts";
|
||||||
import {
|
import {
|
||||||
LadderPickup,
|
LadderPickup,
|
||||||
|
ThrallCollectionPlatePickup,
|
||||||
ThrallPosterPickup,
|
ThrallPosterPickup,
|
||||||
ThrallRecruitedPickup,
|
ThrallRecruitedPickup,
|
||||||
} from "./pickups.ts";
|
} from "./pickups.ts";
|
||||||
@ -11,15 +12,15 @@ import { getPlayerProgress } from "./playerprogress.ts";
|
|||||||
const BASIC_PLAN = Grid.createGridFromMultilineString(`
|
const BASIC_PLAN = Grid.createGridFromMultilineString(`
|
||||||
#####################
|
#####################
|
||||||
######### #########
|
######### #########
|
||||||
##### A # L # D #####
|
##### a # L # d #####
|
||||||
##### a # # d #####
|
##### A # # D #####
|
||||||
##### ## ## #####
|
##### ## ## #####
|
||||||
# ## ## ## ## #
|
# ## ## ## ## #
|
||||||
#Bb eE#
|
#bB Ee#
|
||||||
# ## ## ## ## #
|
# ## ## ## ## #
|
||||||
##### ## ## #####
|
##### ## ## #####
|
||||||
##### c # # f #####
|
##### C # # F #####
|
||||||
##### C # @ # F #####
|
##### c # @ # f #####
|
||||||
######### #########
|
######### #########
|
||||||
#####################
|
#####################
|
||||||
`);
|
`);
|
||||||
@ -32,16 +33,20 @@ export function generateManor(): LoadedNewMap {
|
|||||||
for (let x = 0; x < BASIC_PLAN.size.w; x++) {
|
for (let x = 0; x < BASIC_PLAN.size.w; x++) {
|
||||||
let xy = new Point(x, y);
|
let xy = new Point(x, y);
|
||||||
let cell = map.get(xy);
|
let cell = map.get(xy);
|
||||||
|
let unlocked = (ix: number) =>
|
||||||
|
getPlayerProgress().isThrallUnlocked(thralls[ix]);
|
||||||
|
|
||||||
let placeThrall = (ix: number) => {
|
let placeThrall = (ix: number) => {
|
||||||
cell.architecture = Architecture.Floor;
|
cell.architecture = Architecture.Floor;
|
||||||
if (true || getPlayerProgress().isThrallUnlocked(thralls[ix])) {
|
if (unlocked(ix)) {
|
||||||
cell.pickup = new ThrallRecruitedPickup(thralls[ix]);
|
cell.pickup = new ThrallRecruitedPickup(thralls[ix]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let placeThrallPoster = (ix: number) => {
|
let placeThrallPoster = (ix: number) => {
|
||||||
cell.architecture = Architecture.Floor;
|
cell.architecture = Architecture.Floor;
|
||||||
if (!getPlayerProgress().isThrallUnlocked(thralls[ix])) {
|
if (unlocked(ix)) {
|
||||||
|
cell.pickup = new ThrallCollectionPlatePickup(thralls[ix]);
|
||||||
|
} else {
|
||||||
cell.pickup = new ThrallPosterPickup(thralls[ix]);
|
cell.pickup = new ThrallPosterPickup(thralls[ix]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -8,9 +8,11 @@ import {
|
|||||||
LadderPickup,
|
LadderPickup,
|
||||||
LockPickup,
|
LockPickup,
|
||||||
StatPickup,
|
StatPickup,
|
||||||
|
ThrallItemPickup,
|
||||||
ThrallPickup,
|
ThrallPickup,
|
||||||
} from "./pickups.ts";
|
} from "./pickups.ts";
|
||||||
import { getPlayerProgress } from "./playerprogress.ts";
|
import { getPlayerProgress } from "./playerprogress.ts";
|
||||||
|
import { ItemStage } from "./thralls.ts";
|
||||||
|
|
||||||
const WIDTH = 19;
|
const WIDTH = 19;
|
||||||
const HEIGHT = 19;
|
const HEIGHT = 19;
|
||||||
@ -334,6 +336,7 @@ function carveVault(knife: Knife, room: Rect, vaultTemplate: VaultTemplate) {
|
|||||||
let cell = knife.map.get(goodie);
|
let cell = knife.map.get(goodie);
|
||||||
|
|
||||||
if (a.contains(goodie)) {
|
if (a.contains(goodie)) {
|
||||||
|
cell.pickup = new ExperiencePickup();
|
||||||
let thrall = vaultTemplate.thrall();
|
let thrall = vaultTemplate.thrall();
|
||||||
if (!getPlayerProgress().isThrallUnlocked(thrall)) {
|
if (!getPlayerProgress().isThrallUnlocked(thrall)) {
|
||||||
cell.pickup = new ThrallPickup(thrall);
|
cell.pickup = new ThrallPickup(thrall);
|
||||||
@ -350,7 +353,14 @@ function carveVault(knife: Knife, room: Rect, vaultTemplate: VaultTemplate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (d.contains(goodie)) {
|
if (d.contains(goodie)) {
|
||||||
// TOOD: Put a fancy item here
|
cell.pickup = new ExperiencePickup();
|
||||||
|
|
||||||
|
// replace with a fancy item if nothing is eligible
|
||||||
|
let thrallItem = vaultTemplate.thrallItem();
|
||||||
|
let stage = getPlayerProgress().getThrallItemStage(thrallItem);
|
||||||
|
if (stage == ItemStage.Untouched) {
|
||||||
|
cell.pickup = new ThrallItemPickup(thrallItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
141
src/pickups.ts
@ -1,4 +1,4 @@
|
|||||||
import { getThralls, LifeStage, Thrall } from "./thralls.ts";
|
import { getThralls, ItemStage, LifeStage, Thrall } from "./thralls.ts";
|
||||||
import { CellView, CheckData } from "./newmap.ts";
|
import { CellView, CheckData } from "./newmap.ts";
|
||||||
import { getPlayerProgress } from "./playerprogress.ts";
|
import { getPlayerProgress } from "./playerprogress.ts";
|
||||||
import { getHuntMode, HuntMode, initHuntMode } from "./huntmode.ts";
|
import { getHuntMode, HuntMode, initHuntMode } from "./huntmode.ts";
|
||||||
@ -13,8 +13,9 @@ import {
|
|||||||
} from "./sprites.ts";
|
} from "./sprites.ts";
|
||||||
import { GridArt } from "./gridart.ts";
|
import { GridArt } from "./gridart.ts";
|
||||||
import { getCheckModal } from "./checkmodal.ts";
|
import { getCheckModal } from "./checkmodal.ts";
|
||||||
import { Point } from "./engine/datatypes.ts";
|
import { Point, Size } from "./engine/datatypes.ts";
|
||||||
import { choose } from "./utils.ts";
|
import { choose } from "./utils.ts";
|
||||||
|
import { FG_TEXT } from "./colors.ts";
|
||||||
|
|
||||||
export type Pickup =
|
export type Pickup =
|
||||||
| LockPickup
|
| LockPickup
|
||||||
@ -293,3 +294,139 @@ export class ThrallRecruitedPickup {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ThrallCollectionPlatePickup {
|
||||||
|
thrall: Thrall;
|
||||||
|
rewarded: boolean;
|
||||||
|
|
||||||
|
constructor(thrall: Thrall) {
|
||||||
|
this.thrall = thrall;
|
||||||
|
this.rewarded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
computeCostToClick() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
isObstructive() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawFloor() {}
|
||||||
|
drawInAir(gridArt: GridArt) {
|
||||||
|
let itemStage = getPlayerProgress().getThrallItemStage(this.thrall);
|
||||||
|
let data = getThralls().get(this.thrall);
|
||||||
|
|
||||||
|
if (itemStage != ItemStage.Delivered) {
|
||||||
|
D.drawRect(
|
||||||
|
gridArt.project(0).offset(new Point(-18, -18)),
|
||||||
|
new Size(36, 36),
|
||||||
|
FG_TEXT,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
D.drawSprite(data.sprite, gridArt.project(2), 3, {
|
||||||
|
xScale: 2.0,
|
||||||
|
yScale: 2.0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClick(cell: CellView): boolean {
|
||||||
|
let lifeStage = getPlayerProgress().getThrallLifeStage(this.thrall);
|
||||||
|
let itemStage = getPlayerProgress().getThrallItemStage(this.thrall);
|
||||||
|
let data = getThralls().get(this.thrall);
|
||||||
|
|
||||||
|
// if (itemStage == ItemStage.Untouched) { itemStage = ItemStage.Obtained; }
|
||||||
|
|
||||||
|
if (itemStage == ItemStage.Untouched) {
|
||||||
|
if (lifeStage == LifeStage.Dead) {
|
||||||
|
getCheckModal().show(
|
||||||
|
{
|
||||||
|
label: "There's no point in delivering this now.",
|
||||||
|
options: [],
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
getCheckModal().show(
|
||||||
|
{
|
||||||
|
label: data.itemHint,
|
||||||
|
options: [],
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (itemStage == ItemStage.Obtained) {
|
||||||
|
getPlayerProgress().deliverThrallItem(this.thrall);
|
||||||
|
if (lifeStage != LifeStage.Dead) {
|
||||||
|
getCheckModal().show(
|
||||||
|
{
|
||||||
|
label: data.deliveryMessage,
|
||||||
|
options: [],
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (lifeStage == LifeStage.Dead) {
|
||||||
|
// nothing happens
|
||||||
|
} else if (this.rewarded) {
|
||||||
|
// nothing happens
|
||||||
|
} else {
|
||||||
|
this.rewarded = true;
|
||||||
|
getCheckModal().show(
|
||||||
|
{
|
||||||
|
label: data.rewardMessage,
|
||||||
|
options: [],
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
data.rewardCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getCheckModal().show(this.check, () => (cell.pickup = null));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ThrallItemPickup {
|
||||||
|
thrall: Thrall;
|
||||||
|
|
||||||
|
constructor(thrall: Thrall) {
|
||||||
|
this.thrall = thrall;
|
||||||
|
}
|
||||||
|
|
||||||
|
computeCostToClick() {
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
isObstructive() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawFloor() {}
|
||||||
|
drawInAir(gridArt: GridArt) {
|
||||||
|
let data = getThralls().get(this.thrall);
|
||||||
|
|
||||||
|
D.drawSprite(data.sprite, gridArt.project(2), 3, {
|
||||||
|
xScale: 2.0,
|
||||||
|
yScale: 2.0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onClick(cell: CellView): boolean {
|
||||||
|
let data = getThralls().get(this.thrall);
|
||||||
|
|
||||||
|
cell.pickup = null;
|
||||||
|
getCheckModal().show(
|
||||||
|
{
|
||||||
|
label: data.itemPickupMessage,
|
||||||
|
options: [],
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
getPlayerProgress().obtainThrallItem(this.thrall);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { ALL_STATS, Skill, Stat, SuccessorOption, Wish } from "./datatypes.ts";
|
import { ALL_STATS, Skill, Stat, SuccessorOption, Wish } from "./datatypes.ts";
|
||||||
import { getSkills } from "./skills.ts";
|
import { getSkills } from "./skills.ts";
|
||||||
import { getThralls, LifeStage, Thrall } from "./thralls.ts";
|
import { getThralls, ItemStage, LifeStage, Thrall } from "./thralls.ts";
|
||||||
|
|
||||||
export class PlayerProgress {
|
export class PlayerProgress {
|
||||||
#name: string;
|
#name: string;
|
||||||
@ -15,6 +15,8 @@ export class PlayerProgress {
|
|||||||
#untrimmedSkillsAvailable: Skill[];
|
#untrimmedSkillsAvailable: Skill[];
|
||||||
#thrallsUnlocked: number[];
|
#thrallsUnlocked: number[];
|
||||||
#thrallDamage: Record<number, number>;
|
#thrallDamage: Record<number, number>;
|
||||||
|
#thrallsObtainedItem: number[];
|
||||||
|
#thrallsDeliveredItem: number[];
|
||||||
|
|
||||||
constructor(asSuccessor: SuccessorOption, withWish: Wish | null) {
|
constructor(asSuccessor: SuccessorOption, withWish: Wish | null) {
|
||||||
this.#name = asSuccessor.name;
|
this.#name = asSuccessor.name;
|
||||||
@ -29,6 +31,8 @@ export class PlayerProgress {
|
|||||||
this.#untrimmedSkillsAvailable = [];
|
this.#untrimmedSkillsAvailable = [];
|
||||||
this.#thrallsUnlocked = [];
|
this.#thrallsUnlocked = [];
|
||||||
this.#thrallDamage = {};
|
this.#thrallDamage = {};
|
||||||
|
this.#thrallsObtainedItem = [];
|
||||||
|
this.#thrallsDeliveredItem = [];
|
||||||
|
|
||||||
this.refill();
|
this.refill();
|
||||||
}
|
}
|
||||||
@ -232,7 +236,6 @@ export class PlayerProgress {
|
|||||||
|
|
||||||
getThrallLifeStage(thrall: Thrall): LifeStage {
|
getThrallLifeStage(thrall: Thrall): LifeStage {
|
||||||
let damage = this.#thrallDamage[thrall.id] ?? 0;
|
let damage = this.#thrallDamage[thrall.id] ?? 0;
|
||||||
console.log(`damage: ${damage}`);
|
|
||||||
if (damage < 0.5) {
|
if (damage < 0.5) {
|
||||||
return LifeStage.Fresh;
|
return LifeStage.Fresh;
|
||||||
}
|
}
|
||||||
@ -247,6 +250,30 @@ export class PlayerProgress {
|
|||||||
}
|
}
|
||||||
return LifeStage.Dead;
|
return LifeStage.Dead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
obtainThrallItem(thrall: Thrall) {
|
||||||
|
if (this.#thrallsObtainedItem.indexOf(thrall.id) != -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.#thrallsObtainedItem.push(thrall.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
deliverThrallItem(thrall: Thrall) {
|
||||||
|
if (this.#thrallsDeliveredItem.indexOf(thrall.id) != -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.#thrallsDeliveredItem.push(thrall.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
getThrallItemStage(thrall: Thrall): ItemStage {
|
||||||
|
if (this.#thrallsDeliveredItem.indexOf(thrall.id) != -1) {
|
||||||
|
return ItemStage.Delivered;
|
||||||
|
}
|
||||||
|
if (this.#thrallsObtainedItem.indexOf(thrall.id) != -1) {
|
||||||
|
return ItemStage.Obtained;
|
||||||
|
}
|
||||||
|
return ItemStage.Untouched;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let active: PlayerProgress | null = null;
|
let active: PlayerProgress | null = null;
|
||||||
|
@ -57,41 +57,41 @@ export let sprThrallBat = new Sprite(
|
|||||||
imgThrallBat,
|
imgThrallBat,
|
||||||
new Size(24, 24),
|
new Size(24, 24),
|
||||||
new Point(12, 12),
|
new Point(12, 12),
|
||||||
new Size(3, 1),
|
new Size(4, 1),
|
||||||
3,
|
4,
|
||||||
);
|
);
|
||||||
export let sprThrallCharm = new Sprite(
|
export let sprThrallCharm = new Sprite(
|
||||||
imgThrallCharm,
|
imgThrallCharm,
|
||||||
new Size(24, 24),
|
new Size(24, 24),
|
||||||
new Point(12, 12),
|
new Point(12, 12),
|
||||||
new Size(3, 1),
|
new Size(4, 1),
|
||||||
3,
|
4,
|
||||||
);
|
);
|
||||||
export let sprThrallLore = new Sprite(
|
export let sprThrallLore = new Sprite(
|
||||||
imgThrallLore,
|
imgThrallLore,
|
||||||
new Size(24, 24),
|
new Size(24, 24),
|
||||||
new Point(12, 12),
|
new Point(12, 12),
|
||||||
new Size(3, 1),
|
new Size(4, 1),
|
||||||
3,
|
4,
|
||||||
);
|
);
|
||||||
export let sprThrallParty = new Sprite(
|
export let sprThrallParty = new Sprite(
|
||||||
imgThrallParty,
|
imgThrallParty,
|
||||||
new Size(24, 24),
|
new Size(24, 24),
|
||||||
new Point(12, 12),
|
new Point(12, 12),
|
||||||
new Size(3, 1),
|
new Size(4, 1),
|
||||||
3,
|
4,
|
||||||
);
|
);
|
||||||
export let sprThrallStare = new Sprite(
|
export let sprThrallStare = new Sprite(
|
||||||
imgThrallStare,
|
imgThrallStare,
|
||||||
new Size(24, 24),
|
new Size(24, 24),
|
||||||
new Point(12, 12),
|
new Point(12, 12),
|
||||||
new Size(3, 1),
|
new Size(4, 1),
|
||||||
3,
|
4,
|
||||||
);
|
);
|
||||||
export let sprThrallStealth = new Sprite(
|
export let sprThrallStealth = new Sprite(
|
||||||
imgThrallStealth,
|
imgThrallStealth,
|
||||||
new Size(24, 24),
|
new Size(24, 24),
|
||||||
new Point(12, 12),
|
new Point(12, 12),
|
||||||
new Size(3, 1),
|
new Size(4, 1),
|
||||||
3,
|
4,
|
||||||
);
|
);
|
||||||
|
@ -22,6 +22,7 @@ import {
|
|||||||
sprThrallStealth,
|
sprThrallStealth,
|
||||||
} from "./sprites.ts";
|
} from "./sprites.ts";
|
||||||
import { Sprite } from "./engine/internal/sprite.ts";
|
import { Sprite } from "./engine/internal/sprite.ts";
|
||||||
|
import { getPlayerProgress } from "./playerprogress.ts";
|
||||||
|
|
||||||
export type Thrall = {
|
export type Thrall = {
|
||||||
id: number;
|
id: number;
|
||||||
@ -57,6 +58,11 @@ export type ThrallData = {
|
|||||||
sprite: Sprite;
|
sprite: Sprite;
|
||||||
posterCheck: CheckData;
|
posterCheck: CheckData;
|
||||||
initialCheck: CheckData;
|
initialCheck: CheckData;
|
||||||
|
itemHint: string;
|
||||||
|
itemPickupMessage: string;
|
||||||
|
deliveryMessage: string;
|
||||||
|
rewardMessage: string;
|
||||||
|
rewardCallback: () => void;
|
||||||
|
|
||||||
lifeStageText: Record<LifeStage, LifeStageText>;
|
lifeStageText: Record<LifeStage, LifeStageText>;
|
||||||
};
|
};
|
||||||
@ -69,6 +75,12 @@ export enum LifeStage {
|
|||||||
Dead = "dead",
|
Dead = "dead",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum ItemStage {
|
||||||
|
Untouched = "untouched",
|
||||||
|
Obtained = "obtained",
|
||||||
|
Delivered = "delivered",
|
||||||
|
}
|
||||||
|
|
||||||
export type LifeStageText = {
|
export type LifeStageText = {
|
||||||
prebite: string;
|
prebite: string;
|
||||||
postbite: string;
|
postbite: string;
|
||||||
@ -113,6 +125,16 @@ export let thrallParty = table.add({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
itemHint:
|
||||||
|
'"Ah. I lost my wedding ring in a poker game.\n\nNot _my_ wedding ring, I won it from a lady."',
|
||||||
|
itemPickupMessage:
|
||||||
|
"This antique wedding ring looks like it was worth at least fifty big blinds.",
|
||||||
|
deliveryMessage:
|
||||||
|
'"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!",
|
||||||
|
rewardCallback: () => {
|
||||||
|
getPlayerProgress().add("INT", 10);
|
||||||
|
},
|
||||||
lifeStageText: {
|
lifeStageText: {
|
||||||
fresh: {
|
fresh: {
|
||||||
prebite: "Garrett flips a poker chip and mutters to himself.",
|
prebite: "Garrett flips a poker chip and mutters to himself.",
|
||||||
@ -175,6 +197,16 @@ export let thrallLore = table.add({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
itemHint:
|
||||||
|
"He sniffs his heels like a wolf.\nMaybe shattering his illusion would be good for him. Maybe it would be really bad...",
|
||||||
|
itemPickupMessage:
|
||||||
|
"You can't see yourself in this antique silver mirror. On the other hand, they say silver is effective against wolves.",
|
||||||
|
deliveryMessage:
|
||||||
|
"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!",
|
||||||
|
rewardCallback: () => {
|
||||||
|
getPlayerProgress().add("AGI", 10);
|
||||||
|
},
|
||||||
lifeStageText: {
|
lifeStageText: {
|
||||||
fresh: {
|
fresh: {
|
||||||
prebite: "Lupin awoos quietly to himself.",
|
prebite: "Lupin awoos quietly to himself.",
|
||||||
@ -234,6 +266,17 @@ export let thrallBat = table.add({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
itemHint:
|
||||||
|
"\"I'm from New Zealand, actually.\n\nThere's this regional dish -- I haven't had it in years...\"",
|
||||||
|
itemPickupMessage:
|
||||||
|
"This particular instance of gator food resembles an infamous Aotearoan entree: colonial goose.",
|
||||||
|
deliveryMessage:
|
||||||
|
'Monica salivates. "This is... this is... simply exquisite!"\n\nShe is happy. She will never leave.',
|
||||||
|
rewardMessage: "Monica showers you with CHA and INT!",
|
||||||
|
rewardCallback: () => {
|
||||||
|
getPlayerProgress().add("CHA", 5);
|
||||||
|
getPlayerProgress().add("INT", 5);
|
||||||
|
},
|
||||||
lifeStageText: {
|
lifeStageText: {
|
||||||
fresh: {
|
fresh: {
|
||||||
prebite: "Monica nibbles a pastry.",
|
prebite: "Monica nibbles a pastry.",
|
||||||
@ -294,6 +337,15 @@ export let thrallCharm = table.add({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
itemHint: '"I wish I had some way to look at you... when you\'re not here."',
|
||||||
|
itemPickupMessage:
|
||||||
|
"Your photo is going to be in a lot of places if it gets out, but you've got the original.",
|
||||||
|
deliveryMessage:
|
||||||
|
"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!",
|
||||||
|
rewardCallback: () => {
|
||||||
|
getPlayerProgress().add("PSI", 10);
|
||||||
|
},
|
||||||
lifeStageText: {
|
lifeStageText: {
|
||||||
fresh: {
|
fresh: {
|
||||||
prebite: "Renfield exposes the underside of his jaw.",
|
prebite: "Renfield exposes the underside of his jaw.",
|
||||||
@ -351,6 +403,17 @@ export let thrallStealth = table.add({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
itemHint:
|
||||||
|
'"Do you know what a kobold is? They\'re like me but much smaller."',
|
||||||
|
itemPickupMessage:
|
||||||
|
"The freezer is empty except for this frozen kobold, who mutters something about collecting blood for its master.",
|
||||||
|
deliveryMessage:
|
||||||
|
"\"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!",
|
||||||
|
rewardCallback: () => {
|
||||||
|
getPlayerProgress().add("CHA", 5);
|
||||||
|
getPlayerProgress().add("AGI", 5);
|
||||||
|
},
|
||||||
lifeStageText: {
|
lifeStageText: {
|
||||||
fresh: {
|
fresh: {
|
||||||
prebite: "Narthyss is producing a new track on her gamer PC.",
|
prebite: "Narthyss is producing a new track on her gamer PC.",
|
||||||
@ -409,6 +472,16 @@ export let thrallStare = table.add({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
itemHint:
|
||||||
|
"The slight syncopation of its beeping reminds you that it's missing a gear.",
|
||||||
|
itemPickupMessage:
|
||||||
|
"This glinting gear would be perfect for a malfunctioning robot.",
|
||||||
|
deliveryMessage:
|
||||||
|
"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!",
|
||||||
|
rewardCallback: () => {
|
||||||
|
getPlayerProgress().addExperience(100);
|
||||||
|
},
|
||||||
lifeStageText: {
|
lifeStageText: {
|
||||||
fresh: {
|
fresh: {
|
||||||
prebite: "Ridley is solving math problems.",
|
prebite: "Ridley is solving math problems.",
|
||||||
|
@ -33,6 +33,7 @@ import {
|
|||||||
export type VaultTemplate = {
|
export type VaultTemplate = {
|
||||||
stats: { primary: Stat; secondary: Stat };
|
stats: { primary: Stat; secondary: Stat };
|
||||||
thrall: () => Thrall;
|
thrall: () => Thrall;
|
||||||
|
thrallItem: () => Thrall;
|
||||||
checks: [CheckData, CheckData];
|
checks: [CheckData, CheckData];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -41,6 +42,7 @@ export const standardVaultTemplates: VaultTemplate[] = [
|
|||||||
// zoo
|
// zoo
|
||||||
stats: { primary: "AGI", secondary: "PSI" },
|
stats: { primary: "AGI", secondary: "PSI" },
|
||||||
thrall: () => thrallParty,
|
thrall: () => thrallParty,
|
||||||
|
thrallItem: () => thrallBat,
|
||||||
checks: [
|
checks: [
|
||||||
{
|
{
|
||||||
label:
|
label:
|
||||||
@ -87,6 +89,7 @@ export const standardVaultTemplates: VaultTemplate[] = [
|
|||||||
// blood bank
|
// blood bank
|
||||||
stats: { primary: "AGI", secondary: "INT" },
|
stats: { primary: "AGI", secondary: "INT" },
|
||||||
thrall: () => thrallLore,
|
thrall: () => thrallLore,
|
||||||
|
thrallItem: () => thrallStealth,
|
||||||
checks: [
|
checks: [
|
||||||
{
|
{
|
||||||
label:
|
label:
|
||||||
@ -132,6 +135,7 @@ export const standardVaultTemplates: VaultTemplate[] = [
|
|||||||
// coffee shop
|
// coffee shop
|
||||||
stats: { primary: "PSI", secondary: "CHA" },
|
stats: { primary: "PSI", secondary: "CHA" },
|
||||||
thrall: () => thrallBat,
|
thrall: () => thrallBat,
|
||||||
|
thrallItem: () => thrallCharm,
|
||||||
checks: [
|
checks: [
|
||||||
{
|
{
|
||||||
label:
|
label:
|
||||||
@ -178,6 +182,7 @@ export const standardVaultTemplates: VaultTemplate[] = [
|
|||||||
// optometrist
|
// optometrist
|
||||||
stats: { primary: "PSI", secondary: "PSI" },
|
stats: { primary: "PSI", secondary: "PSI" },
|
||||||
thrall: () => thrallCharm,
|
thrall: () => thrallCharm,
|
||||||
|
thrallItem: () => thrallStare,
|
||||||
checks: [
|
checks: [
|
||||||
{
|
{
|
||||||
label:
|
label:
|
||||||
@ -224,6 +229,7 @@ export const standardVaultTemplates: VaultTemplate[] = [
|
|||||||
// club,
|
// club,
|
||||||
stats: { primary: "CHA", secondary: "PSI" },
|
stats: { primary: "CHA", secondary: "PSI" },
|
||||||
thrall: () => thrallStealth,
|
thrall: () => thrallStealth,
|
||||||
|
thrallItem: () => thrallParty,
|
||||||
checks: [
|
checks: [
|
||||||
{
|
{
|
||||||
label:
|
label:
|
||||||
@ -270,6 +276,7 @@ export const standardVaultTemplates: VaultTemplate[] = [
|
|||||||
// library
|
// library
|
||||||
stats: { primary: "INT", secondary: "CHA" },
|
stats: { primary: "INT", secondary: "CHA" },
|
||||||
thrall: () => thrallStare,
|
thrall: () => thrallStare,
|
||||||
|
thrallItem: () => thrallLore,
|
||||||
checks: [
|
checks: [
|
||||||
{
|
{
|
||||||
label:
|
label:
|
||||||
|