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; | ||||
| @@ -148,4 +149,31 @@ export class ThrallPickup { | ||||
|     getCheckModal().show(data.initialCheck, () => cell.pickup = null); | ||||
|     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: [ | ||||
|   | ||||