Add manor skeleton
@@ -1,61 +0,0 @@
 | 
			
		||||
architecture:
 | 
			
		||||
 | 
			
		||||
--------------
 | 
			
		||||
provinces:
 | 
			
		||||
 | 
			
		||||
--------------
 | 
			
		||||
{
 | 
			
		||||
    "provinces": {
 | 
			
		||||
        "a": "Zoo",
 | 
			
		||||
        "b": "Gator Pen",
 | 
			
		||||
        "c": "Food Storage"
 | 
			
		||||
    },
 | 
			
		||||
    "architecture": {
 | 
			
		||||
        "@": "entrance",
 | 
			
		||||
        "#": "wall",
 | 
			
		||||
        " ": "floor",
 | 
			
		||||
        "*": { "item": "gecko" },
 | 
			
		||||
        ".": {
 | 
			
		||||
            "pickup": [
 | 
			
		||||
                "AGI", "AGI", "AGI", "AGI",
 | 
			
		||||
                "PSI", "PSI",
 | 
			
		||||
                "EXP"
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
        "!": { "item": "colonialGoose" },
 | 
			
		||||
        "1": {
 | 
			
		||||
            "label": "The gator pen appears to be locked. Some bats behind the barred gate are amusing themselves by swooping and darting just out of the alligators' reach.",
 | 
			
		||||
            "checks": [
 | 
			
		||||
                {
 | 
			
		||||
                    "skills": ["lore1"],
 | 
			
		||||
                    "locked": "That wall sure does look impenetrable.",
 | 
			
		||||
                    "unlockable": "Notice a failure in the construction.",
 | 
			
		||||
                    "unlockScene": [
 | 
			
		||||
                        "I dig my clawed fingers into a crack between the bricks and feel the concrete give way.",
 | 
			
		||||
                        "This structure, built by mortals, is impermanent. Soon none of it will exist.",
 | 
			
		||||
                        "I rip another clump of brittle earth from the crack, no longer invisible.",
 | 
			
		||||
                        "And another. When the gap's wide enough to crawl through, I climb in."
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "skills": ["stare0"],
 | 
			
		||||
                    "locked": "The bats are happy by themselves.",
 | 
			
		||||
                    "unlockable": "These bats could be enjoying themselves so much more.",
 | 
			
		||||
                    "unlockScene": [
 | 
			
		||||
                        "I hold my face to the bars. One bat looks at me.",
 | 
			
		||||
                        "\"Here, little bat\" -- I think before I say it. No, relate to it as an equal.",
 | 
			
		||||
                        "What does it really want?",
 | 
			
		||||
                        "What does any mortal want? It wants to feel good --"",
 | 
			
		||||
                        "So stare --",
 | 
			
		||||
                        "...",
 | 
			
		||||
                        "... Now it breaks. Like any mortal.",
 | 
			
		||||
                        "Still dripping, it flaps unsurely to the door and -- with only a little coaxing -- it opens the lock."
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
        },
 | 
			
		||||
        "2": {
 | 
			
		||||
            "label":
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 468 B After Width: | Height: | Size: 523 B  | 
| 
		 Before Width: | Height: | Size: 535 B After Width: | Height: | Size: 601 B  | 
| 
		 Before Width: | Height: | Size: 536 B After Width: | Height: | Size: 614 B  | 
| 
		 Before Width: | Height: | Size: 503 B After Width: | Height: | Size: 559 B  | 
| 
		 Before Width: | Height: | Size: 523 B After Width: | Height: | Size: 570 B  | 
| 
		 Before Width: | Height: | Size: 503 B After Width: | Height: | Size: 572 B  | 
@@ -102,7 +102,16 @@ export class CheckModal {
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (options.length == 1) {
 | 
			
		||||
    if (options.length == 0) {
 | 
			
		||||
      addButton(
 | 
			
		||||
        this.#drawpile,
 | 
			
		||||
        "OK!",
 | 
			
		||||
        new Rect(new Point(0, size.h - 64), new Size(size.w, 64)),
 | 
			
		||||
        true,
 | 
			
		||||
        () => { this.show(null, null) }
 | 
			
		||||
      )
 | 
			
		||||
    }
 | 
			
		||||
    else if (options.length == 1) {
 | 
			
		||||
      addOptionButton(options[0], new Rect(new Point(0, size.h - 64), new Size(size.w, 64)));
 | 
			
		||||
    }
 | 
			
		||||
    else if (options.length == 2) {
 | 
			
		||||
 
 | 
			
		||||
@@ -132,11 +132,11 @@ export class HuntMode {
 | 
			
		||||
    offsetInCells: Point,
 | 
			
		||||
    mapPosition: Point,
 | 
			
		||||
  ) {
 | 
			
		||||
    const OFFSET_UNDER_FLOOR = -512;
 | 
			
		||||
    const OFFSET_FLOOR = -256;
 | 
			
		||||
    const OFFSET_AIR = 0;
 | 
			
		||||
    const OFFSET_TOP = 256;
 | 
			
		||||
    const OFFSET_TOP_OF_TOP = 512;
 | 
			
		||||
    const OFFSET_UNDER_FLOOR = -512 + mapPosition.y;
 | 
			
		||||
    const OFFSET_FLOOR = -256 + mapPosition.y;
 | 
			
		||||
    const OFFSET_AIR = 0 + mapPosition.y;
 | 
			
		||||
    const OFFSET_TOP = 256 + mapPosition.y;
 | 
			
		||||
    const OFFSET_TOP_OF_TOP = 512 + mapPosition.y;
 | 
			
		||||
 | 
			
		||||
    const gridArt = new GridArt(offsetInCells);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										62
									
								
								src/manormap.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,62 @@
 | 
			
		||||
import {Architecture, LoadedNewMap} from "./newmap.ts";
 | 
			
		||||
import {Grid, Point} from "./engine/datatypes.ts";
 | 
			
		||||
import {getThralls} from "./thralls.ts";
 | 
			
		||||
import {LadderPickup, ThrallPosterPickup} from "./pickups.ts";
 | 
			
		||||
 | 
			
		||||
const BASIC_PLAN = Grid.createGridFromMultilineString(`
 | 
			
		||||
#####################
 | 
			
		||||
#########   #########
 | 
			
		||||
##### A # L # D #####
 | 
			
		||||
##### a #   # d #####
 | 
			
		||||
#####   ## ##   #####
 | 
			
		||||
#   ## ##   ## ##   #
 | 
			
		||||
#Bb               eE#
 | 
			
		||||
#   ## ##   ## ##   #
 | 
			
		||||
#####   ## ##   #####
 | 
			
		||||
##### c #   # f #####
 | 
			
		||||
##### C # @ # F #####
 | 
			
		||||
#########   #########
 | 
			
		||||
#####################
 | 
			
		||||
`);
 | 
			
		||||
 | 
			
		||||
export function generateManor(): LoadedNewMap {
 | 
			
		||||
  let map = new LoadedNewMap("manor", BASIC_PLAN.size);
 | 
			
		||||
  let thralls = getThralls().getAll();
 | 
			
		||||
 | 
			
		||||
  for (let y = 0; y < BASIC_PLAN.size.h; y++) {
 | 
			
		||||
    for (let x = 0; x < BASIC_PLAN.size.w; x++) {
 | 
			
		||||
      let xy = new Point(x, y);
 | 
			
		||||
      let cell = map.get(xy);
 | 
			
		||||
 | 
			
		||||
      let placeThrall = (ix: number) => {
 | 
			
		||||
        // TODO
 | 
			
		||||
        cell.architecture = Architecture.Floor;
 | 
			
		||||
      };
 | 
			
		||||
      let placeThrallPoster = (ix: number) => {
 | 
			
		||||
        cell.architecture = Architecture.Floor;
 | 
			
		||||
        cell.pickup = new ThrallPosterPickup(thralls[ix]);
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      switch (BASIC_PLAN.get(xy)) {
 | 
			
		||||
        case '#': break
 | 
			
		||||
        case '@': cell.architecture = Architecture.Floor; map.entrance = xy; break;
 | 
			
		||||
        case 'L': cell.architecture = Architecture.Floor; cell.pickup = new LadderPickup(); break;
 | 
			
		||||
        case ' ': cell.architecture = Architecture.Floor; break;
 | 
			
		||||
        case 'a': placeThrall(0); break;
 | 
			
		||||
        case 'b': placeThrall(1); break;
 | 
			
		||||
        case 'c': placeThrall(2); break;
 | 
			
		||||
        case 'd': placeThrall(3); break;
 | 
			
		||||
        case 'e': placeThrall(4); break;
 | 
			
		||||
        case 'f': placeThrall(5); break;
 | 
			
		||||
        case 'A': placeThrallPoster(0); break;
 | 
			
		||||
        case 'B': placeThrallPoster(1); break;
 | 
			
		||||
        case 'C': placeThrallPoster(2); break;
 | 
			
		||||
        case 'D': placeThrallPoster(3); break;
 | 
			
		||||
        case 'E': placeThrallPoster(4); break;
 | 
			
		||||
        case 'F': placeThrallPoster(5); break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return map;
 | 
			
		||||
}
 | 
			
		||||
@@ -16,6 +16,7 @@ export type Pickup
 | 
			
		||||
  | ExperiencePickup
 | 
			
		||||
  | LadderPickup
 | 
			
		||||
  | ThrallPickup
 | 
			
		||||
  | ThrallPosterPickup
 | 
			
		||||
 | 
			
		||||
export class LockPickup {
 | 
			
		||||
  check: CheckData;
 | 
			
		||||
@@ -149,3 +150,30 @@ export class ThrallPickup {
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class ThrallPosterPickup {
 | 
			
		||||
  thrall: Thrall;
 | 
			
		||||
 | 
			
		||||
  constructor(thrall: Thrall) {
 | 
			
		||||
    this.thrall = thrall;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  computeCostToClick() { return 0; }
 | 
			
		||||
 | 
			
		||||
  isObstructive() { return false; }
 | 
			
		||||
 | 
			
		||||
  drawFloor() { }
 | 
			
		||||
  drawInAir(gridArt: GridArt) {
 | 
			
		||||
    let data = getThralls().get(this.thrall);
 | 
			
		||||
    D.drawSprite(data.sprite, gridArt.project(0.0), 2, {
 | 
			
		||||
      xScale: 2.0,
 | 
			
		||||
      yScale: 2.0,
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  onClick(cell: CellView): boolean {
 | 
			
		||||
    let data = getThralls().get(this.thrall);
 | 
			
		||||
    getCheckModal().show(data.posterCheck, () => cell.pickup = null);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -41,9 +41,9 @@ export let sprLock = new Sprite(
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export let sprThrallBat = new Sprite(imgThrallBat, new Size(24, 24), new Point(12, 12), new Size(2, 1), 2);
 | 
			
		||||
export let sprThrallCharm = new Sprite(imgThrallCharm, new Size(24, 24), new Point(12, 12), new Size(2, 1), 2);
 | 
			
		||||
export let sprThrallLore = new Sprite(imgThrallLore, new Size(24, 24), new Point(12, 12), new Size(2, 1), 2);
 | 
			
		||||
export let sprThrallParty = new Sprite(imgThrallParty, new Size(24, 24), new Point(12, 12), new Size(2, 1), 2);
 | 
			
		||||
export let sprThrallStare = new Sprite(imgThrallStare, new Size(24, 24), new Point(12, 12), new Size(2, 1), 2);
 | 
			
		||||
export let sprThrallStealth = new Sprite(imgThrallStealth, new Size(24, 24), new Point(12, 12), new Size(2, 1), 2);
 | 
			
		||||
export let sprThrallBat = new Sprite(imgThrallBat, new Size(24, 24), new Point(12, 12), new Size(3, 1), 3);
 | 
			
		||||
export let sprThrallCharm = new Sprite(imgThrallCharm, new Size(24, 24), new Point(12, 12), new Size(3, 1), 3);
 | 
			
		||||
export let sprThrallLore = new Sprite(imgThrallLore, new Size(24, 24), new Point(12, 12), new Size(3, 1), 3);
 | 
			
		||||
export let sprThrallParty = new Sprite(imgThrallParty, new Size(24, 24), new Point(12, 12), new Size(3, 1), 3);
 | 
			
		||||
export let sprThrallStare = new Sprite(imgThrallStare, new Size(24, 24), new Point(12, 12), new Size(3, 1), 3);
 | 
			
		||||
export let sprThrallStealth = new Sprite(imgThrallStealth, new Size(24, 24), new Point(12, 12), new Size(3, 1), 3);
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ import {getVNModal} from "./vnmodal.ts";
 | 
			
		||||
import {getScorer} from "./scorer.ts";
 | 
			
		||||
import {getEndgameModal} from "./endgamemodal.ts";
 | 
			
		||||
import {SuccessorOption, Wish} from "./datatypes.ts";
 | 
			
		||||
import {generateMap} from "./mapgen.ts";
 | 
			
		||||
import {generateManor} from "./manormap.ts";
 | 
			
		||||
 | 
			
		||||
const N_TURNS: number = 9;
 | 
			
		||||
 | 
			
		||||
@@ -22,7 +22,7 @@ export class StateManager {
 | 
			
		||||
 | 
			
		||||
  startGame(asSuccessor: SuccessorOption, withWish: Wish | null) {
 | 
			
		||||
    this.#turn = 1;
 | 
			
		||||
    initHuntMode(new HuntMode(1, generateMap()));
 | 
			
		||||
    initHuntMode(new HuntMode(1, generateManor()));
 | 
			
		||||
    initPlayerProgress(asSuccessor, withWish);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -33,7 +33,7 @@ export class StateManager {
 | 
			
		||||
      this.#turn += 1;
 | 
			
		||||
      getPlayerProgress().applyEndOfTurn();
 | 
			
		||||
      getPlayerProgress().refill();
 | 
			
		||||
      initHuntMode(new HuntMode(getHuntMode().depth, generateMap()));
 | 
			
		||||
      initHuntMode(new HuntMode(getHuntMode().depth, generateManor()));
 | 
			
		||||
    } else {
 | 
			
		||||
      // TODO: Play a specific scene
 | 
			
		||||
      let ending = getScorer().pickEnding();
 | 
			
		||||
 
 | 
			
		||||
@@ -43,10 +43,19 @@ class ThrallsTable {
 | 
			
		||||
  get(thrall: Thrall): ThrallData {
 | 
			
		||||
    return this.#thralls[thrall.id]
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getAll(): Thrall[] {
 | 
			
		||||
    let thralls = [];
 | 
			
		||||
    for (let id = 0; id < this.#thralls.length; id++) {
 | 
			
		||||
      thralls.push({id})
 | 
			
		||||
    }
 | 
			
		||||
    return thralls;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
export type ThrallData = {
 | 
			
		||||
  label: string,
 | 
			
		||||
  sprite: Sprite,
 | 
			
		||||
  posterCheck: CheckData,
 | 
			
		||||
  initialCheck: CheckData,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -63,6 +72,10 @@ export function getThralls() {
 | 
			
		||||
export let thrallParty = table.add({
 | 
			
		||||
  label: "Garrett",
 | 
			
		||||
  sprite: sprThrallParty,
 | 
			
		||||
  posterCheck: {
 | 
			
		||||
    label: "This room would be perfect for someone with an ostensibly managed gambling addiction.",
 | 
			
		||||
    options: [],
 | 
			
		||||
  },
 | 
			
		||||
  initialCheck: {
 | 
			
		||||
    label: "That's Garrett. He plays poker, but he goes to the zoo to cool down after he's lost a lot of chips. His ice cream cone has melted.",
 | 
			
		||||
    options: [
 | 
			
		||||
@@ -87,6 +100,10 @@ export let thrallParty = table.add({
 | 
			
		||||
export let thrallLore = table.add({
 | 
			
		||||
  label: "Lupin",
 | 
			
		||||
  sprite: sprThrallLore,
 | 
			
		||||
  posterCheck: {
 | 
			
		||||
    label: "This room would be perfect for someone with a love of nature and screaming.",
 | 
			
		||||
    options: [],
 | 
			
		||||
  },
 | 
			
		||||
  initialCheck: {
 | 
			
		||||
    label: "That's Lupin. He's a Wolf Scout, but hardcore about it. I'm not sure he knows he's a raccoon.",
 | 
			
		||||
    options: [
 | 
			
		||||
@@ -111,6 +128,10 @@ export let thrallLore = table.add({
 | 
			
		||||
export let thrallBat = table.add({
 | 
			
		||||
  label: "Monica",
 | 
			
		||||
  sprite: sprThrallBat,
 | 
			
		||||
  posterCheck: {
 | 
			
		||||
    label: "This room would be perfect for some kind of television chef.",
 | 
			
		||||
    options: [],
 | 
			
		||||
  },
 | 
			
		||||
  initialCheck: {
 | 
			
		||||
    label: "That's Monica. You've seen her cook on TV! Looks like she's enjoying a kiwi flan.",
 | 
			
		||||
    options: [
 | 
			
		||||
@@ -135,6 +156,10 @@ export let thrallBat = table.add({
 | 
			
		||||
export let thrallCharm = table.add({
 | 
			
		||||
  label: "Renfield",
 | 
			
		||||
  sprite: sprThrallCharm,
 | 
			
		||||
  posterCheck: {
 | 
			
		||||
    label: "This room would be perfect for someone who likes vampires even more than you enjoy being a vampire.",
 | 
			
		||||
    options: [],
 | 
			
		||||
  },
 | 
			
		||||
  initialCheck: {
 | 
			
		||||
    label: "Doesn't this guy seem a little creepy? His nametag says Renfield. Not sure you should trust him...",
 | 
			
		||||
    options: [
 | 
			
		||||
@@ -159,6 +184,10 @@ export let thrallCharm = table.add({
 | 
			
		||||
export let thrallStealth = table.add({
 | 
			
		||||
  label: "Narthyss",
 | 
			
		||||
  sprite: sprThrallStealth,
 | 
			
		||||
  posterCheck: {
 | 
			
		||||
    label: "This room would be perfect for someone who can breathe fire.",
 | 
			
		||||
    options: [],
 | 
			
		||||
  },
 | 
			
		||||
  initialCheck: {
 | 
			
		||||
    label: "Narthyss (dragon, heiress) actually owns the club, so she probably wouldn't talk to you... Would she?",
 | 
			
		||||
    options: [
 | 
			
		||||
@@ -183,6 +212,10 @@ export let thrallStealth = table.add({
 | 
			
		||||
export let thrallStare = table.add({
 | 
			
		||||
  label: "Ridley",
 | 
			
		||||
  sprite: sprThrallStare,
 | 
			
		||||
  posterCheck: {
 | 
			
		||||
    label: "This room would be perfect for a soulless robot.",
 | 
			
		||||
    options: [],
 | 
			
		||||
  },
 | 
			
		||||
  initialCheck: {
 | 
			
		||||
    label: "Ridley is the library's catalogue system. It can give you an incorrect answer to any question. (It has a couple gears loose.)",
 | 
			
		||||
    options: [
 | 
			
		||||
 
 | 
			
		||||