From 12ca8ea97f236a0027643ea2b6d0f43b4bc1f52f Mon Sep 17 00:00:00 2001 From: ryceg Date: Fri, 9 Apr 2021 21:44:09 +1000 Subject: [PATCH 1/4] Change pathing for both local and hosted --- lib/src/getIllustration.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/src/getIllustration.ts b/lib/src/getIllustration.ts index 70491f77f..4dce18e07 100644 --- a/lib/src/getIllustration.ts +++ b/lib/src/getIllustration.ts @@ -9,21 +9,31 @@ type Illustration = export const getIllustration = (illustration: Illustration, alt: string) => { let img = ' { + if (process.env.NODE_ENV === 'production' && location.origin !== 'file://') { + return './' + } + return '../' +} + // It would obviously be preferable to output actual s instead of having it render via SugarCube. // Unfortunately, I am not a clever man, and cannot figure it out. export const getImage = (illustration: Illustration) => { const img = document.createElement('img') + const path = getPath() img.id = 'illustration' - img.src = `../src/Resources/img/hero/${illustration}.jpg` - img.srcset = `../src/Resources/img/hero/${illustration}-x360.jpg 360w, ../src/Resources/img/hero/${illustration}-x411.jpg 411w, ../src/Resources/img/hero/${illustration}-x500.jpg 500w, ../src/Resources/img/hero/${illustration}-x576.jpg 576w, ../src/Resources/img/hero/${illustration}-x768.jpg 768w, ../src/Resources/img/hero/${illustration}-x992.jpg 992w, ../src/Resources/img/hero/${illustration}-x1200.jpg 1200w, ../src/Resources/img/hero/${illustration}.jpg` + img.src = `${path}src/Resources/img/hero/${illustration}.jpg` + img.srcset = `${path}src/Resources/img/hero/${illustration}-x360.jpg 360w, ${path}src/Resources/img/hero/${illustration}-x411.jpg 411w, ${path}src/Resources/img/hero/${illustration}-x500.jpg 500w, ${path}src/Resources/img/hero/${illustration}-x576.jpg 576w, ${path}src/Resources/img/hero/${illustration}-x768.jpg 768w, ${path}src/Resources/img/hero/${illustration}-x992.jpg 992w, ${path}src/Resources/img/hero/${illustration}-x1200.jpg 1200w, ${path}src/Resources/img/hero/${illustration}.jpg` img.alt = `An image depicting ${lib.articles.output(illustration)}, created by artist Juho Huttunen.` return img } From 687fabc6c6504b0ccdf6b7fca5c320061e95cab3 Mon Sep 17 00:00:00 2001 From: ryceg Date: Fri, 9 Apr 2021 22:17:22 +1000 Subject: [PATCH 2/4] Fix to github badge --- lib/src/badges.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/badges.ts b/lib/src/badges.ts index 9db1866a9..3308fdaf3 100644 --- a/lib/src/badges.ts +++ b/lib/src/badges.ts @@ -269,7 +269,7 @@ export const badges = { }, commitsSinceLastUpdate: { alt: 'Commits since last update', - source: '/github/commits-since/ryceg/Eigengrau-s-Essential-Establishment-Generator/2.7', + source: '/github/commits-since/ryceg/Eigengrau-s-Essential-Establishment-Generator/2.8', logo: 'github', color: '6cc644' }, From f76a5fbb71961a93467fef84d85363c197c3757e Mon Sep 17 00:00:00 2001 From: ryceg Date: Sat, 10 Apr 2021 15:21:25 +1000 Subject: [PATCH 3/4] Add preposition --- lib/src/terrain.ts | 66 ++++++++++++++++++++++++--------- src/Start/BriefDescription.twee | 2 +- 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/lib/src/terrain.ts b/lib/src/terrain.ts index fe8d722e7..6a5dc84f8 100644 --- a/lib/src/terrain.ts +++ b/lib/src/terrain.ts @@ -7,8 +7,7 @@ export type Seasons = 'spring' | 'summer' | 'autumn' | 'winter' export interface TerrainData { weather: WeatherData - start: string[] - location: Record + location: Record } interface WeatherData { @@ -26,6 +25,7 @@ interface TempVariation { temperatureTimer(): number } interface LocationData { + preposition: string precipitationIntensity: number origin: string[] vegetation: Record @@ -33,7 +33,8 @@ interface LocationData { possibleMaterials: string[] } -export const terrain: Record = { +// function makeTerrain () { +export const terrain = { temperate: { weather: { tempVariation: { @@ -89,10 +90,10 @@ export const terrain: Record = { } } }, - start: ['seashore', 'seashore', 'seashore', 'seashore', 'forest', 'forest', 'hills', 'plains', 'mountains', 'river coast', 'river coast'], location: { // town.Name is located in the _ 'seashore': { + preposition: 'on', precipitationIntensity: 3, // town.Name grew around _ origin: [ @@ -121,6 +122,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone'] }, 'forest': { + preposition: 'in', precipitationIntensity: 2, origin: [ 'a large freshwater lake', @@ -156,6 +158,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone', 'plaster', 'gypsum', 'adobe', 'daub', 'cob'] }, 'hills': { + preposition: 'in', precipitationIntensity: 2, origin: [ 'a large freshwater lake', @@ -180,6 +183,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone', 'plaster', 'gypsum', 'adobe', 'daub', 'cob'] }, 'plains': { + preposition: 'on', precipitationIntensity: 2, origin: [ 'a wide, navigable river', @@ -201,6 +205,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone', 'plaster', 'gypsum', 'adobe', 'daub', 'cob'] }, 'mountains': { + preposition: 'in', precipitationIntensity: 2, origin: [ 'a large freshwater lake', @@ -224,6 +229,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone', 'plaster', 'gypsum', 'adobe', 'daub', 'cob'] }, 'river coast': { + preposition: 'on', precipitationIntensity: 2, origin: [ 'a coastal harbor', @@ -291,9 +297,9 @@ export const terrain: Record = { } } }, - start: ['seacoast', 'forest', 'hills', 'plains', 'mountains', 'river coast', 'jungle', 'volcanic field'], location: { 'seacoast': { + preposition: 'on', precipitationIntensity: 3, origin: [ 'a coastal harbor', @@ -319,6 +325,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone', 'adobe', 'daub', 'cob', 'straw', 'terra cotta', 'clay'] }, 'forest': { + preposition: 'in', precipitationIntensity: 2, origin: [ 'a large freshwater lake', @@ -344,6 +351,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone', 'plaster', 'gypsum', 'adobe', 'daub', 'cob', 'straw', 'terra cotta', 'clay'] }, 'hills': { + preposition: 'in', precipitationIntensity: 2, origin: [ 'a large freshwater lake', @@ -366,6 +374,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone', 'plaster', 'gypsum', 'adobe', 'daub', 'cob', 'straw', 'terra cotta', 'clay'] }, 'plains': { + preposition: 'on', precipitationIntensity: 2, origin: [ 'a wide, navigable river', @@ -388,6 +397,7 @@ export const terrain: Record = { }, 'mountains': { + preposition: 'in', precipitationIntensity: 2, origin: [ 'a large freshwater lake', @@ -411,6 +421,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone', 'plaster', 'gypsum', 'adobe', 'daub', 'cob', 'straw', 'terra cotta', 'clay'] }, 'river coast': { + preposition: 'on', precipitationIntensity: 2, origin: [ 'a coastal harbor', @@ -430,6 +441,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone', 'plaster', 'gypsum', 'adobe', 'daub', 'cob', 'straw', 'terra cotta', 'clay'] }, 'jungle': { + preposition: 'in', precipitationIntensity: 2, origin: [ 'a river navigable by small craft', @@ -451,6 +463,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone', 'plaster', 'gypsum', 'adobe', 'daub', 'cob', 'straw', 'terra cotta', 'clay'] }, 'volcanic field': { + preposition: 'on', precipitationIntensity: 3, origin: [ 'a large freshwater lake', @@ -531,9 +544,9 @@ export const terrain: Record = { } } }, - start: ['desert', 'hills', 'plains', 'mountains', 'river coast', 'wasteland', 'oasis'], location: { 'desert': { + preposition: 'in', precipitationIntensity: 2, origin: [ 'a coastal harbor', @@ -547,10 +560,8 @@ export const terrain: Record = { 'a well-traveled crossroads', 'a water source and a well-traveled road'], vegetation: { - desolate: 3, - sparse: 1, - lush: 4, - thick: 3 + desolate: 5, + sparse: 4 }, plants: { shrubs: 1, @@ -560,6 +571,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'brick', 'limestone', 'plaster', 'gypsum', 'adobe', 'daub', 'cob', 'straw'] }, 'forest': { + preposition: 'in', precipitationIntensity: 2, origin: [ 'a large freshwater lake', @@ -575,7 +587,7 @@ export const terrain: Record = { vegetation: { desolate: 2, sparse: 1, - lush: 3, + lush: 2, thick: 6 }, plants: { @@ -586,6 +598,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone', 'plaster', 'gypsum', 'adobe', 'daub', 'cob', 'straw', 'terra cotta', 'clay'] }, 'hills': { + preposition: 'in', precipitationIntensity: 2, origin: [ 'a large freshwater lake', @@ -610,6 +623,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone', 'plaster', 'gypsum', 'adobe', 'daub', 'cob', 'straw', 'terra cotta', 'clay'] }, 'plains': { + preposition: 'on', precipitationIntensity: 2, origin: [ 'a wide, navigable river', @@ -619,10 +633,8 @@ export const terrain: Record = { 'a well-traveled crossroads', 'a water source and a well-traveled road'], vegetation: { - desolate: 5, - sparse: 5, - lush: 1, - thick: 1 + desolate: 3, + sparse: 5 }, plants: { shrubs: 1, @@ -632,6 +644,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone', 'plaster', 'gypsum', 'adobe', 'daub', 'cob', 'straw', 'terra cotta', 'clay'] }, 'mountains': { + preposition: 'in', precipitationIntensity: 2, origin: [ 'a large freshwater lake', @@ -645,8 +658,7 @@ export const terrain: Record = { vegetation: { desolate: 5, sparse: 5, - lush: 1, - thick: 1 + lush: 1 }, plants: { shrubs: 1, @@ -656,6 +668,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone', 'plaster', 'gypsum', 'adobe', 'daub', 'cob', 'straw', 'terra cotta', 'clay'] }, 'river coast': { + preposition: 'on', precipitationIntensity: 2, origin: [ 'a coastal harbor', @@ -676,6 +689,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone', 'plaster', 'gypsum', 'adobe', 'daub', 'cob', 'straw', 'terra cotta', 'clay'] }, 'wasteland': { + preposition: 'in', precipitationIntensity: 2, origin: [ 'a road traveled by merchants on the way to another, larger city', @@ -696,6 +710,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone', 'plaster', 'gypsum', 'adobe', 'daub', 'cob'] }, 'oasis': { + preposition: 'in', precipitationIntensity: 1, origin: [ 'a series of natural springs', @@ -774,9 +789,9 @@ export const terrain: Record = { } } }, - start: ['seacoast', 'forest', 'hills', 'plains', 'mountains', 'river coast', 'tundra', 'ice sheet', 'seacoast'], location: { 'seacoast': { + preposition: 'on', precipitationIntensity: 3, origin: [ 'a coastal harbor', @@ -803,6 +818,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone'] }, 'forest': { + preposition: 'in', precipitationIntensity: 2, origin: [ 'a large freshwater lake', @@ -829,6 +845,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone'] }, 'hills': { + preposition: 'in', precipitationIntensity: 2, origin: [ 'a large freshwater lake', @@ -853,6 +870,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone'] }, 'plains': { + preposition: 'on', precipitationIntensity: 2, origin: [ 'a wide, navigable river', @@ -875,6 +893,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone'] }, 'mountains': { + preposition: 'in', precipitationIntensity: 2, origin: [ 'a large freshwater lake', @@ -899,6 +918,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone'] }, 'river coast': { + preposition: 'on', precipitationIntensity: 2, origin: [ 'a coastal harbor', @@ -919,6 +939,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone'] }, 'tundra': { + preposition: 'on', precipitationIntensity: 2, origin: [ 'a wide, navigable river', @@ -940,6 +961,7 @@ export const terrain: Record = { possibleMaterials: ['hewn rock', 'stone', 'cobblestone', 'wood', 'brick', 'limestone'] }, 'ice sheet': { + preposition: 'on', precipitationIntensity: 3, origin: [ 'a wide, navigable river', @@ -963,3 +985,11 @@ export const terrain: Record = { } } } +// return terrain +// } + +// export const terrain = makeTerrain() + +type UnionKeys = T extends any ? keyof T : never +type Terrain = typeof terrain +export type Locations = UnionKeys diff --git a/src/Start/BriefDescription.twee b/src/Start/BriefDescription.twee index 8b92baf48..21f02936c 100644 --- a/src/Start/BriefDescription.twee +++ b/src/Start/BriefDescription.twee @@ -1,6 +1,6 @@ :: BriefDescription

The <> of $town.name

-\

$town.name is <> located in the $town.terrain $town.location, where the vegetation is $town.vegetation. $town.name grew around $town.origin, and is comprised <> +\

$town.name is <> located <> the $town.terrain $town.location, where the vegetation is $town.vegetation. $town.name grew around $town.origin, and is comprised <> <>. They are <><> <> <> From 4c17f9dc52e41a800304f4c4f139dca0d09018d8 Mon Sep 17 00:00:00 2001 From: ryceg Date: Sat, 10 Apr 2021 16:26:01 +1000 Subject: [PATCH 4/4] Initial commit (broken) --- src/Docks/docks.d.ts => lib/docks/_common.ts | 57 +- lib/docks/docksData.ts | 723 +++++++++++++++++++ lib/index.ts | 3 + src/Docks/DocksOutput.twee | 4 +- src/Docks/ShipProfile.twee | 2 +- src/Docks/createDocks.d.ts | 36 - src/Docks/createDocks.js | 47 -- src/Docks/createDocks.ts | 69 ++ src/Docks/docks.js | 700 ------------------ src/main.ts | 7 +- 10 files changed, 852 insertions(+), 796 deletions(-) rename src/Docks/docks.d.ts => lib/docks/_common.ts (52%) create mode 100644 lib/docks/docksData.ts delete mode 100644 src/Docks/createDocks.d.ts delete mode 100644 src/Docks/createDocks.js create mode 100644 src/Docks/createDocks.ts delete mode 100644 src/Docks/docks.js diff --git a/src/Docks/docks.d.ts b/lib/docks/_common.ts similarity index 52% rename from src/Docks/docks.d.ts rename to lib/docks/_common.ts index 8b6927930..d10558ee8 100644 --- a/src/Docks/docks.d.ts +++ b/lib/docks/_common.ts @@ -1,8 +1,8 @@ -import { Ship } from './createDocks' +import { Town, NPC } from '@lib' +import { Building } from 'lib/buildings/_common' -export interface Setup { - initDocks(): void - docks: { +// TODO DocksData is currently not being used. +export interface DocksData { rollData: { cleanliness: { description: string @@ -38,17 +38,15 @@ export interface Setup { hullDesc: string[] shipDetail: string[] eventDetail: string[] - type: Record + type: Record captain: Record> rollData: { cleanliness: [number, string][] size: [number, string][] } } - } } - -interface ShipType { +export interface ShipTypeData { masts: number, rigging: string, length: number, @@ -56,3 +54,46 @@ interface ShipType { hasOars: boolean, crewMen: number } + +export interface Docks extends Building { + notableFeature: string + notice: string + passageName: string + initPassage: string + buildingType: string + associatedNPC: NPC + wordNoun: string + ships: Record +} + +export interface Ship { + name: string + type: string + captainType: string + hull: string + detail: string + event: string + roll: { + size: number + cleanliness: number + } + captain: NPC + size: string + cleanliness: string +} + +interface Customer { + relationshipDescription: string + relationships: { + building?: { + relationship: string + reciprocalRelationship?: string + } + associatedNPC?: { + relationship: string + reciprocalRelationship: string + } + } + base?: Partial + description(docks: Docks, npc: NPC): string +} diff --git a/lib/docks/docksData.ts b/lib/docks/docksData.ts new file mode 100644 index 000000000..1bd037bce --- /dev/null +++ b/lib/docks/docksData.ts @@ -0,0 +1,723 @@ +import { Docks, NPC, Ship, Town } from '@lib' +import { random } from '../src/random' + +// function makeDocksData () { +export const docksData = { + rollData: { + cleanliness: { + description: 'How clean are the docks?', + preceding: 'Dock Cleanliness:', + rolls: [ + [80, 'quite clean', 'spotless, save for a couple splashes of sea water'], + [70, 'safe, if smelly', 'quite tidy, if you can stand the smell'], + [50, 'relatively tidy', 'reasonably clean, with the occasional rope laying about posing a tripping hazard'], + [40, 'crusty and dirty', 'crusted with sea water and barnacles cling to the supports'], + [30, 'seaweed infested', 'marred with seaweed and a slippery mess. It smells disgusting, too'], + [0, 'disgustingly slimy', 'disgusting. All types of moulds, algae, and other unspeakably slimy things are on display here.'] + ] + }, + size: { + description: 'How large are the docks?', + preceding: 'Dock Size:', + rolls: [ + [90, 'large and sprawling', 'huge; it sprawls across the body of water, as far as the eye can see'], + [80, 'large', 'large. It has the space and equipment to accommodate a fleet of ships'], + [60, 'big', 'big, with space to accommodate several galleons'], + [50, 'accommodating', 'average sized, with room enough for a fair few ships'], + [40, 'geared towards smaller vessels', 'on the small size; it is geared towards fishing vessels, but has the capacity for larger ships if needed'], + [30, 'small', 'small, and clearly geared towards smaller vessels such as fishing ships. You could probably fit a large ship in, if you were lucky'], + [20, 'pretty small', 'quite small, with room for fishing ships and little else'], + [0, 'glorified jetty', 'tiny; barely more than a glorified jetty'] + ] + }, + activity: { + description: 'How busy is the docks at the moment?', + preceding: 'Dock Activity:', + rolls: [ + [100, 'packed to the gills; you have trouble moving through some parts of the harbor due to the throngs of seafarers crowding the place'], + [90, [ + 'absolutely packed; the din of everyone shouting to one another to fetch another barrel and other such things makes the place feel alive', + 'absolutely packed; the din of everyone shouting to one another to haul in the fish off the boat and other such things makes the place feel alive', + 'absolutely packed; the din of everyone shouting to one another to get off their asses and shift this pile of rope and other such things makes the place feel alive' + ]], + [80, [ + 'bustling. There are all manners of folk walking around, all of whom have places to be', + 'bustling. Several ships seem to be currently unloading and crowds are beginning to fill the street' + ]], + [70, 'reasonably busy, with a couple folks milling about, waiting for a ship to dock'], + [60, [ + 'busy, with lots of deckhands running about, lugging things from point A to point B', + 'busy, with several large makeshift fish markets crowding the docks drawing in all kinds of crowds' + ]], + [50, 'reasonably busy, with a decent amount of activity'], + [40, 'relatively quiet, with some fishermen getting ready to head out on a trip'], + [30, 'pretty quiet, save for the gulls which are swooping around, eager to steal any unattended bread'], + [20, 'very quiet. There is next to nobody around'], + [10, 'rather peaceful, the silence only disturbed by the gentle lapping of water against rocks'], + [0, [ + 'deathly silent, save for the gentle sounds of the water lapping against the docks', + 'empty, save for a lone fisherman sitting and watching his lure bob up and down in the waves' + ]] + ] + } + }, + notableFeature: [ + // which are best known for _ + 'the foul smelling fish that fisherman haul in', + 'being a good place to get mugged', + 'a large lookout post that warns the shipmaster of approaching ships', + 'an impressive looking boat that has been moored for many years', + 'being the best place to go if you are looking to get into a fight', + 'single handedly keeping the brothels in business', + 'its ships that are all incredible smelly, but rather swift on the waters', + 'being a tourist attraction', + 'the Sea Priests and clergymen who roam the docks blessing ships before they set sail', + "it's shipwrights. The dry docks here have birthed a large portion of the local navy", + 'a fine dining restaurant that hangs suspended off the end of the pier', + "it's shady wharfmaster, who appears to be willing to turn a blind eye to just about anything for the right price", + "it's large ornate lighthouse, an ancient statue of a humanoid figure with all details eroded by time. It holds the lighthouse's beacon aloft in it's hand", + 'the waters around the docks being infested with predatory fish and poisonous snakes', + 'the exotic stone used to construct the docks', + "a peculiar ship docked here, constricted from living trees fed from it's soil filled hull", + 'the sun bleached wrecks littering the shore line', + 'local urban legends about ghosts ships and damned crew members', + 'the time the local the local militia and fishermen held back a pirate raid on the town here', + 'the large marble slabs that anchor the docks to the shore', + 'the thick oak timbers of the piers', + 'the enormous hand crafted ropes that tie down the ships', + 'a huge lighthouse that guides ships to the port', + 'being built inside an enormous cavern' + ], + notice: [ + 'a pair of beggars arguing over a dead fish', + 'some seagulls flying overhead', + 'an entrepreneurial fellow selling hot foods from a cart', + 'a sailor struggling to lift a coil of rope', + 'a pair of burly men shifting a barrel onto a ship', + 'a captain pointing at a map, arguing with another man', + 'there is a certain quietness to the air; nobody is shouting as is usual in dockyards', + 'the atmosphere is a little on edge; sailors are more curt than usual, and the dock hands are grimacing as they load the ships with goods', + 'there is a foul stench in the air; like a rotting fish, only much larger, with no escape from the stomach turning scent to be found in buildings, or behind a scented hankerchief', + 'a pair of sailors accidentally dropping one of their crates of cargo into the water', + 'a sailor in the water trying to rescue a dropped supply barrel', + 'a crew unfurling the sails of their ship as they head for open waters', + // a(n) enormous/large/moderately sized/regular/small/tiny/single stall fish market selling a large variety of fish/an inconceivable number of fish, crabs, shrimp, and other sea creatures/a small selection of fish/a pitiful variety fish + 'a small group of men posing for a portrait with the carcass of an enormous sea monster strung up from a tall wooden pole', + 'a person in dirty rags attempting to sell a single fish to passersby', + 'an incredibly large <> docked out in the water. It is ornately painted with the figurehead of a magical animal', + 'a large crowd gathered in front of an absolutely gargantuan severely damaged ship slowly drifting into port', + 'a lone fisherman sitting at the edge and waiting for his catch', + 'two men pulling up crab traps out of the water', + 'a haggard old woman weaving baskets out of seaweed' + ], + ships: { + create (town: Town, docks: Docks, opts: Partial) { + const ship = Object.assign({ + name: random(lib.docksData.ships.name), + // type: random(Object.keys(lib.docksData.ships.type)) as ShipTypes, + captainType: random(Object.keys(lib.docksData.ships.captain)), + hull: random(lib.docksData.ships.hullDesc), + detail: random(lib.docksData.ships.shipDetail), + event: random(lib.docksData.ships.eventDetail), + roll: { + size: random(1, 100), + cleanliness: random(1, 100) + } + }, opts) + + // Object.assign(ship, lib.docksData.ships.type[ship.type].hasOars, lib.docksData.ships.type[ship.type].rigging) + // Object.assign(ship, { + // crewMen: lib.docksData.ships.type[ship.type].crewMen(), + // masts: lib.docksData.ships.type[ship.type].masts(), + // length: lib.docksData.ships.type[ship.type].length(), + // purpose: random(lib.docksData.ships.type[ship.type].purpose) + // }) + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + ship.captain = setup.createNPC(town, lib.docksData.ships.captain[ship.captainType]) + + const rollDataVariables = ['size', 'cleanliness'] as const + for (const propName of rollDataVariables) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + lib.defineRollDataGetter(ship, lib.docksData.ships.rollData[propName].rolls, propName) + } + docks.ships[ship.name] = ship as Ship + return ship + }, + crew: { + create (town: Town) { + const crewType = random(lib.docksData.ships.crew.type) + + const readout = { + bodyFeature: random(lib.docksData.ships.crew.bodyFeature), + itemFeature: random(lib.docksData.ships.crew.itemFeature), + sailReason: random(lib.docksData.ships.crew.sailing) + } + const crewTraits = Object.assign({ + profession: 'sailor' + }, crewType) + const crew = setup.createNPC(town, crewTraits as Partial) + const heShe = crew.heshe + const hisHer = crew.hisher + return `Out of the crew steps ${crewType} named ${setup.profile(crew)}. ${heShe.toUpperFirst()} ${readout.bodyFeature} and ${readout.itemFeature}. When asked about why ${heShe} took to the sea, ${hisHer} reason is "${readout.sailReason}".` + }, + type: [ + { + type: 'a veteran of the sea who may have been beautiful at one point', + gender: 'woman', + note: 'A woman whose skin has been brined by the salt water.' + }, + { + type: 'a young sailor excited to take to the sea', + ageStage: 'young adult', + calmTrait: 'passionate' + }, + { + type: 'a wide eyed adventurer of the sea just getting a first true taste of sailing', + ageStage: 'young adult', + calmTrait: 'curious', + profession: 'wannabe pirate', + note: 'This person has great ambitions' + }, + { + type: 'an older, well-brined master of sailing', + ageStage: 'elderly' + }, + { type: 'an ordinary looking sailor' }, + { + type: 'a stoic looking veteran', + ageStage: 'settled adult', + calmTrait: 'quiet', + stressTrait: 'reliable' + }, + { + type: 'a rugged and battered looking bilge rat', + note: 'This person has extremely dirty clothing on.' + }, + { + type: 'a suspiciously regal and seasick looking sailor', + profession: 'sailor', + socialClass: 'nobility', + note: 'This character is a noble in hiding.' + } + ], + /** He/She (bodyFeature) and (itemFeature) . */ + bodyFeature: [ + 'has a bright pink scar running across the <> hand', + 'is missing the <> eye and instead has a glass one', + 'has long matted hair', 'has a thick layer of dirt covering the skin', + 'has a large number of sun spots', + 'is covered in freckles', + 'has a cleft chin', + 'has deep sunken eyes', + 'has leathery thick skin from the hot sun', + 'is missing several teeth', + 'is missing an ear', + 'has acne riddled skin', + 'has hawkish eyes the seem to catch every movement', + 'has rather pale skin for someone who works in the sun', + 'has course calloused hands from working with rope daily', + 'smells distinctly of the sea', + 'has a square jaw', + 'has a large bulbous nose', + 'has a crooked nose', + 'has a crooked smile', + 'has the eyes of a rat', + 'is hunched over all of the time', + 'suffers from a limp', + 'has a noticeable stutter', + 'has a large wart on the chin', + 'has incredibly long and nimble fingers', + 'has very expressive eyebrows', + 'has beautifully clean skin', + 'has short but unkempt hair', + 'is broad shouldered', + 'has a slender jaw', + 'has muscled arms from the hard work of the sea', + 'has a spoon lodged into the nub at the end of their arm where their hand should be', + 'has large cauliflower ears', + 'has rather pungent body odor' + ], + itemFeature: [ + 'is wearing a grungy looking sailors cap', + 'is wearing a cheap looking eyepatch', + 'has on clothes that are rugged and tattered from the storms', + 'is wearing clothes that are stiff from all the sea salt caked upon them', + 'always carries a fancy looking compass that only points <>', + 'has a crudely carved peg leg', + 'has a large hook for a hand', + 'has a very well crafted mahogany peg leg', + 'uses a crude walking stick', + 'uses a finely carved oak walking stick', + 'uses a walking cane with the head of a <> carved at the top', + 'is always wearing a backpack', + 'wears a thick seal leather coat to keep dry', + 'has a collapsible spyglass tied to their belt', + 'has a lucky accordion on hand at all times', + 'is wearing a tattered bandana', + 'is wearing a rather filthy looking cocked hat with a ragged feather poking out', + 'is wearing some thick leathery boots absolutely riddled with holes and rips', + 'has a large colorful parrot on one shoulder', + 'is wearing a large skull pendant', + 'is wearing a small jeweled pendant', + 'has some sort fo necklace tucked under their shirt' + + ], + /** When asked why he/she took to the sea, his/her reason is _ . */ + sailing: [ + 'the sea called to me and I answered her', + 'to try and find all the buried treasures that have been left behind', + 'for the riches that lie below', + 'adventure was calling me and the sea is where the greatest adventures happen', + 'I needed coin for a debt and I still need to pay it off', + 'I needed to get away from some trouble', + 'nobody cares about your past out at sea', + 'I just love the color blue', + 'the captain is a friend of mine and they asked me to come aboard', + 'the captain pays well', + "I don't know any other trade", + "all my family has sailed the sea. I'm just following in their footsteps", + 'it sounded like fun at the time', + 'I was sick of my town and wanted a change of scenery', + 'I lost my beloved and with it my only reason to stay on land', + 'to make enough money for my family to eat' + ] + }, + name: ['Lantheon', 'Starchaser', 'Dryad’s Fury', 'Black Trident', 'Corellon’s Arrow', 'Morkoth', 'Koalinthas', 'Sehanine’s Fool', 'Stormcrow', 'Vaazrus', 'Shield of Khahar', + 'Stingray', 'Sanaj-Rakal', 'Zhal-Vazir', 'Griffonwing', 'Blademark', 'Golden Libram', 'Hareth’s Barrel', 'Kasha’s Wake', 'Shining Flute', 'White Feather', 'Riventide', + 'Moonriser', 'Gem of Malfier', 'Dragon’s Glory', 'Menacer', 'Scarlet Dagger', 'Kral-Tajir', 'Ravager', 'Kerle’s Drum', 'Heart of Avandra', 'Goldraker', 'Sea Haunt', 'Storm Maven', + 'Grimbol’s Cutlass', 'Scimitar', 'Black Gauntlet', 'Iron Maiden', 'Wavecrusher', 'Hammer of Kavath', 'Waterblade', 'Arkhor’s Secret', 'Dire Gar', 'Prallmar’s Shadow', 'Piranha', + 'Devil’s Fork', 'Tuersyl’s Fist', 'Daraj-Vzan', 'Silver Chalice', 'Demonrudder', 'Turathi Flame', 'Storm’s Eye', 'Tanishar’s Fate', 'Shard of Night', 'Triton', 'Jarak’s Grasp', + 'Nightmare', 'Harpy’s Lure', 'Devious', 'Arazandro’s Bluff', 'Nbod’s Haul', 'Astaryntha', 'Expeditious', 'Curse of Thuban', 'Siren’s Kiss', 'Lonely Witch', 'Rat’s Nest', + 'Evader', 'Mistreaver', 'Ven’r', 'Vicious', 'Dream of Melora', 'Shensari', 'Damilor', 'Krimilvin’s Charm', 'Bloodmonger', 'Lucky Scrag', 'Windstriker', 'Grim Gale', 'Djinni’s Wish', + 'Flying Eel', 'Jewel of Irthos', 'Broken Keel', 'Javelin', 'Myrska’s Revenge', 'Fearsome', 'Archon’s Hammer', 'Vendetta', 'Thunderchaser', 'Heartless', 'Shrike', 'Morak’s Boat', + 'Mar-Turang', 'Will-o’-wisp', 'Asha-Naga', 'Dominant', 'Shoal Courser', 'Crescent Moon', 'Crystal Tear', 'Kara-Vaji', 'Shalastar', 'Roc’s Talon', 'Wavecarver', 'Graethan', + 'Rotten Apple', 'Bharzim’s Victory', 'Avarice', 'Farak-Changal', 'Falling Star', 'Crimson Knife', 'Yisek’s Ride', 'Shara-Vaja', 'Varalan’s Dweomer', 'Rangoth', 'Vostarika', + 'Mirasandra', 'Second Chance', 'Redfeather', 'Maal-Destir', 'Scorpion', 'Ghorzaar’s Bane', 'Moonwatcher', 'Dragon’s Crown', 'Dragonhawk', 'Dancing Sword', 'Kaveth’s Whisper', + 'Tirah', 'Phantom Shark', 'Hjeltia', 'Satyr', 'Breyten’s Thrill', 'Golden Coin', 'Pearl of Fire', 'Bhez-Rizma', 'Fireball', 'Color Spray', 'Sea Bear', 'Prosperous', 'Summer Rain', + 'Sundowner', 'Skulldark’s Ire', 'Skandalor', 'Zarkanan', 'Sana-Losi', 'Wolfshark', 'Song of Elyndri', 'Coral Rose', 'Rune of Halendros', 'Maelstrom', 'Shadow Mask', + 'Deep Heathen', 'Aurora', 'Rusted Cutlass', 'Thog’s Maul', 'Wooden Stake', 'Hellstrike', 'Scepter Queen', 'Prince of Lies', 'Fang of Tezmyr', 'White Hart', 'Floating Cask', + 'Sea Howler', 'Frostwind', 'Moonshadow', 'Melora’s Favor', 'Dark Queen’s Voice', 'Chethel’s Ghost', 'Mad Hag', 'Tamarion’s Grudge', 'Raven’s Gamble', 'Reckoner', 'Wraithwind', + 'Kalisa Tano', 'Beholder', 'Slippery Trickster', 'Retribution', 'Whirling Glyph', 'Lady Rose', 'Karthang’s Plunder', 'Good Fortune', 'Axe of Thard', 'Black Bow', 'Quickstrike', + 'Thelandira', 'Hammergust', 'Barracuda', 'Sahandrian’s Quarrel', 'Feral Knave', 'Wildwyrm', 'Shevaya’s Honor', 'Blackhelm’s Legacy', 'Wyvern’s Sting', 'Dragonroar', 'Kegstaff', + 'Oaken Ranger', 'Timber Serpent', 'Desperate Sorceress', 'Screaming Gull', 'Greedy Drake', 'Light of Pjaltr', 'Fate’s Blessing', 'Stardancer', 'Leering Skull', 'Ebon Moon', + 'Werewolf', 'Redemption', 'Zaetchan’s Privilege', 'Sea Skulk', 'Savage Swan', 'Bane’s Breath', 'Ghorok’s Grail', 'Emerald Eye', 'Remorseless', 'Skiprock', 'Zaetra', 'Silverfin', + 'Risen Ghost', 'Listless', 'Vortex', 'Advantage', 'Autumn Song', 'Trystan’s Delight', 'Soaring Manta', 'Calomaar’s Edge', 'Saerthzal', 'Iron Trumpet', 'Locathah', 'Demonskull', + 'Arrowhead', 'Frastain’s Bottle', 'The Saint Ive', 'Halygast', 'La Bon An', 'La Katerine', 'The Blythe', 'Rose', 'The Flying Squirrel', 'Golden Lion', 'Panther', 'Silent Night'], + /** The hull of the ship _ */ + hullDesc: [ + 'is encrusted with several very large and oddly colored barnacles', + 'is battered and old. The planks of the ship creak loudly in protest as it bobs through the water', + 'looks fresh and new as if it was built only yesterday', + 'looks to be damaged from a recent storm or perhaps a fight at sea', + 'has a great many number of nets hanging down it', + 'has several small portholes', + 'is grungy and dirty looking', + 'has a long gangplank hanging from the top of it', + 'appears to be wrapped with bands of iron', + 'has several boards nailed to the side in hasty repair', + 'has a long nasty gouge across it', + 'has a great number of pulleys affixed to it', + 'is decorated with many ornate brass fixtures', + 'has a few colorful banners hung across it, tattered by the sea' + // TODO: refactor these to not use either, as either breaks the seed + // 'has been painted to resemble <>', + // 'has been painted so the top half is <> and the bottom half is <>', + // 'is painted with small ornate <> patterns at the edges', + // 'has "$currentShip.name" painted on it in bold <> letters', + // 'is built out of bare <> ', + // 'has <> of <> colored paint going across it', + // 'is painted pure <>' + ], + // On board you notice _ + shipDetail: [ + 'all of the crew members are wearing matching uniforms', + 'the ship figurehead is a beautifully carved <>', + 'the ship seems to be barely held together with patchwork boards and makeshift nails', + "the captain's quarters has an expensive looking piano in it", + 'the rails of the ship are shaped like fish', + 'several large piles of tangled nets sitting around', + 'a large barrel full of poorly carved peglegs', + 'a small set of hooks with nameplates above them; one of them has an eyepatch hanging off of it', + 'several fishing rods bundled together', + 'a few small piles of unsorted fish and ocean debree sitting near the bow', + 'instead of a wheel there is a large lever jutting out in its place', + 'several hammocks have been set up for crew to be able to sleep under the night sky', + 'a few crew members are playing cards off in a corner', + 'all the ships rails are shaped like swords', + 'a large flag is hoisted high on top the mast', + 'a large locked chest off to one side of the deck', + "a large open chest off to one side of the deck, you can't quite see what's inside", + 'a small cage on deck with a few slaves inside', + 'a lusty looking harlot flirting with the captain', + 'a large barrel of oranges', + 'the body of a large sea creature strung up from the mast', + 'several different piles of potatoes in the cargo hold', + 'a large harpoon gun mounted near the front of the deck', + 'a small harpoon gun mounted at the side of the deck', + 'a few crates that seem to shake every once and a while', + "a bright red painted door that leads to the captain's quarters" + // 'a <> the crew keeps as a pet', + // 'the wheel of the ship appears to be made from <>' + ], + // The crew are currently _ + eventDetail: [ + 'prepping for a rather long journey far from mainland', + 'prepping the ship to set sail', + 'mulling about doing a whole lot of nothing', + 'on a mission to bring some secret cargo to a secret buyer', + 'just trying to get by until they get their next big break', + 'all partaking in a large open ring brawl on the deck of the ship', + 'partaking in an inner-crew fishing tournament', + 'trying to decipher a map one of them found in a bottle', + 'mostly relaxing on deck, eating, and laying about enjoying the sea breeze', + 'hauling goods and supplies up into cargo', + 'drinking deeply and laughing loudly', + 'seeking a great treasure that they heard about from a passing pirate', + 'planning to become pirates after a string of bad luck', + 'fitting the ship with cannons', + 'practicing tying different kinds of knots', + 'partaking in a safety class on the harpoon gun', + 'mostly asleep below deck or off in town', + 'gathered around the captain listening to an outrageously tall tale', + 'going about their normal day to day', + 'trying to patch up a considerably big leak in the hull', + 'crowded around a large chest that they seem to be trying to pry open', + 'trying to pry open an enormous clam they fished up on their last journey', + 'having a crew wide jig off by the stern', + 'planning a mutiny against the captain', + 'trying to pull up the anchor which appears to be stuck' + // 'singing a jaunty sea shanty about <> at the tops of their lungs' + ], + // type: { + // 'caravel': { + // masts: () => random(2, 3), + // rigging: 'lateen', + // length: () => random(468, 708), + // purpose: ['sailing', 'cargo', 'pirate'], + // hasOars: false, + // crewMen: () => random(20, 30) + // }, + // 'rowboat': { + // masts: () => 0, + // rigging: 'no', + // length: () => random(180, 240), + // purpose: ['fishing'], + // hasOars: true, + // crewMen: () => random(1, 3) + // }, + // 'dory': { + // masts: () => 0, + // rigging: 'no', + // length: () => random(180, 400), + // purpose: ['fishing'], + // hasOars: true, + // crewMen: () => random(1, 10) + // }, + // 'drifter': { + // masts: () => 0, + // rigging: 'no', + // length: () => random(180, 400), + // purpose: ['fishing'], + // hasOars: true, + // crewMen: () => random(1, 10) + // }, + // 'herring buss': { + // masts: () => random(2, 3), + // rigging: 'square', + // length: () => random(180, 400), + // purpose: ['fishing'], + // hasOars: false, + // crewMen: () => random(5, 25) + // }, + // 'carrack': { + // masts: () => random(3, 4), + // rigging: 'square', + // length: () => random(800, 920), + // purpose: ['sailing', 'cargo', 'navy', 'merchant'], + // hasOars: true, + // crewMen: () => random(30, 40) + // }, + // 'crayer': { + // masts: () => 3, + // rigging: 'square', + // length: () => random(468, 708), + // purpose: ['cargo', 'merchant'], + // hasOars: true, + // crewMen: () => random(30, 40) + // }, + // 'hoy': { + // masts: () => 1, + // rigging: 'square', + // length: () => random(400, 460), + // purpose: ['cargo'], + // hasOars: true, + // crewMen: () => random(30, 40) + // }, + // 'picard': { + // masts: () => 1, + // rigging: 'square', + // length: () => random(150, 240), + // purpose: ['cargo'], + // hasOars: true, + // crewMen: () => random(5, 20) + // }, + // 'galley': { + // masts: () => 3, + // rigging: 'lateen', + // length: () => random(3800, 4200), + // purpose: ['navy', "adventurer's", 'pirate'], + // hasOars: true, + // crewMen: () => random(80, 120) + // }, + // 'longship': { + // masts: () => 1, + // rigging: 'square', + // length: () => random(1600, 1800), + // purpose: ['navy', 'cargo', 'transport'], + // hasOars: true, + // crewMen: () => random(80, 120) + // }, + // 'balinger': { + // masts: () => 1, + // rigging: 'square', + // length: () => random(800, 1200), + // purpose: ['cargo', 'fishing', 'transport'], + // hasOars: true, + // crewMen: () => random(30, 80) + // }, + // 'frigate': { + // masts: () => 3, + // rigging: 'square', + // length: () => random(1500, 1700), + // purpose: ['navy', 'cargo', 'pirate', "adventurer's"], + // hasOars: true, + // crewMen: () => random(30, 40) + // }, + // 'galleon': { + // masts: () => 3, + // rigging: 'lateen', + // length: () => random(3800, 4200), + // purpose: ['navy', 'cargo', 'pirate', 'merchant', "adventurer's"], + // hasOars: true, + // crewMen: () => random(80, 120) + // }, + // 'galleass': { + // masts: () => 3, + // rigging: 'square', + // length: () => random(3800, 4200), + // purpose: ['cargo', 'transport', 'navy', 'pirate', "adventurer's"], + // hasOars: true, + // crewMen: () => random(80, 140) + // }, + // 'nef': { + // masts: () => 3, + // rigging: 'square', + // length: () => random(2400, 2800), + // purpose: ['cargo', 'exploration'], + // hasOars: true, + // crewMen: () => random(40, 120) + // }, + // 'barque': { + // masts: () => random(3, 5), + // rigging: 'square', + // length: () => random(3000, 5000), + // purpose: ['cargo', 'transport', "explorer's", 'pirate'], + // hasOars: true, + // crewMen: () => random(65, 120) + // } + // }, + captain: { + 'a seasoned veteran': { + profession: "ship's captain", + hasClass: false, + background: 'sailor' + }, + 'a reformed pirate': { + profession: "ship's captain", + hasClass: false, + background: 'sailor', + note: 'A reformed pirate.' + }, + 'a nobleman with more money than sense': { + profession: "ship's captain", + hasClass: false, + background: 'noble', + note: 'Inexperienced on the sea.', + gender: 'man' + }, + 'a relatively inexperienced, but gifted young lad': { + profession: "ship's captain", + background: 'sailor', + hasClass: false, + gender: 'man', + calmTrait: 'quick on his feet' + }, + 'a woman with a temper': { + profession: "ship's captain", + background: 'sailor', + hasClass: false, + gender: 'woman', + calmTrait: 'quick to anger', + stressTrait: 'extremely snappy' + }, + 'a stern man, with a long beard': { + profession: "ship's captain", + background: 'sailor', + hasClass: false, + gender: 'man', + beard: 'long and majestic', + calmTrait: 'stern', + stressTrait: 'shouty' + }, + 'a dwarf that wanted to see the seas': { + profession: "ship's captain", + background: 'sailor', + race: 'dwarf', + hasClass: false + }, + 'a man searching for his long lost lover': { + profession: "ship's captain", + background: 'sailor', + gender: 'man', + hasClass: false, + note: 'He is searching for his long lost lover.' + }, + 'an elf who has forsaken the earth': { + race: 'elf', + hasClass: false + }, + 'a half-orc with a passion for marine life': { + profession: "ship's captain", + background: 'sailor', + race: 'half-orc', + hasClass: false + }, + 'a stoic woman with a quiet voice': { + profession: "ship's captain", + background: 'sailor', + gender: 'woman', + vocalPattern: 'has a quiet voice', + hasClass: false + }, + 'an ex mercenary': { + profession: "ship's captain", + background: 'soldier' + }, + 'a retired merchant': { + profession: "ship's captain", + background: 'merchant', + ageStage: 'elderly', + hasClass: false + }, + 'a young boy who inherited the ship': { + profession: "ship's captain", + background: 'sailor', + ageStage: 'young adult', + note: 'Inherited the ship.', + hasClass: false + } + }, + rollData: { + size: { + rolls: [ + // it is a _______ $ship.type + [90, 'huge'], + [80, 'impressively sized'], + [60, 'somewhat impressive'], + [50, 'average sized'], + [30, 'somewhat unimpressive'], + [20, 'cluttered'], + [10, 'cluttered and cramped'] + ] + }, + cleanliness: { + rolls: [ + // ... that is + [80, 'absolutely spotless; it must have been cleaned recently, as no barnacles adorn the bottom of the ship'], + [80, 'spotless, save for a couple barnacles'], + [70, 'in quite good condition, with only a couple barnacles clinging on to the bottom'], + [50, 'in reasonable condition, with some barnacles hanging on, creating drag at speed'], + [40, 'in need of a good clean, with barnacles clinging to the bottom of the ship'], + [30, 'in desperate need of a thorough de-barnacleing, as well as a general clean'], + [20, 'filthy and laden with barnacles covering the bottom of the boat'] + ] + } + } + }, + get: { + customers: [ + { + relationshipDescription: 'regular', + relationships: { + building: { + relationship: 'regular', + reciprocalRelationship: 'place of work' + }, + associatedNPC: { + relationship: 'acquaintance' + } + }, + base: { + professionSector: 'naval' + }, + description (building: Docks, npc: NPC) { return `${npc.firstName} works with ships.` } + }, + { + relationshipDescription: 'shipwright', + relationships: { + building: { + relationship: 'shipwright', + reciprocalRelationship: 'place of work' + }, + associatedNPC: { + relationship: 'acquaintance' + } + }, + base: { + profession: 'shipwright' + }, + description (building: Docks, npc: NPC) { return `${npc.firstName} constructs and repairs ships in ${building.name}.` } + }, + { + relationshipDescription: 'bosun', + relationships: { + building: { + relationship: 'bosun', + reciprocalRelationship: 'place of work' + }, + associatedNPC: { + relationship: 'acquaintance' + } + }, + base: { + profession: 'bosun' + }, + description (building: Docks, npc: NPC) { return `${npc.firstName} works to organise equipment to be loaded off ${building.name} and onto ${npc.hisher} ship.` } + }, + { + relationshipDescription: 'stevedore', + relationships: { + building: { + relationship: 'stevedore', + reciprocalRelationship: 'place of work' + }, + associatedNPC: { + relationship: 'acquaintance' + } + }, + base: { + profession: 'stevedore' + }, + description (building: Docks, npc: NPC) { return `${npc.firstName} hauls stuff off ships and onto ${building.name}.` } + } + ] + } +} +// return docksData + +// export const docksData = makeDocksData() + +export type ShipTypes = keyof typeof docksData.ships.type +// export type Locations = UnionKeys diff --git a/lib/index.ts b/lib/index.ts index 02b55e1b0..32a930721 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -34,6 +34,9 @@ export * from './constructs/spider' export * from './constructs/tree' export * from './constructs/wolf' +export * from './docks/_common' +export * from './docks/docksData' + export * from './faction/_common' export * from './faction/createAllies' export * from './faction/createLeaderGroup' diff --git a/src/Docks/DocksOutput.twee b/src/Docks/DocksOutput.twee index 878001dcf..7d9cd63ce 100644 --- a/src/Docks/DocksOutput.twee +++ b/src/Docks/DocksOutput.twee @@ -1,9 +1,9 @@ :: DocksOutput \<> -\<> +\<> \

<>

\

You walk down to the docks, which are known best for $building.notableFeature. You notice $building.notice.

\

The docks are $building.sizeDescriptive, and is $building.cleanlinessDescriptive. It's currently $building.activity.

-<> +<> <> <
> \ No newline at end of file diff --git a/src/Docks/ShipProfile.twee b/src/Docks/ShipProfile.twee index 94d553fea..63a08f90f 100644 --- a/src/Docks/ShipProfile.twee +++ b/src/Docks/ShipProfile.twee @@ -12,5 +12,5 @@ \<>\ \<>\ <> It is <> <> ship $currentShip.cleanliness.
The hull of the ship $currentShip.hull. On board you notice $currentShip.detail. The crew are currently $currentShip.event. -
<><><><> +
<><><><> <>
<>$currentShip.crew<>
<
> diff --git a/src/Docks/createDocks.d.ts b/src/Docks/createDocks.d.ts deleted file mode 100644 index 0202126b3..000000000 --- a/src/Docks/createDocks.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -interface Setup { - createDocks(town: Town, opts?: Partial): Docks -} - -interface Options { - newBuilding(town: Town, type?: string): Building - npc: Partial -} - -export interface Docks { - notableFeature: string - notice: string - passageName: string - initPassage: string - buildingType: string - needsWordNoun: string - associatedNPC: NPC - wordNoun: string - ships: Record -} - -export interface Ship { - name: string - type: string - captainType: string - hull: string - detail: string - event: string - roll: { - size: number - cleanliness: number - } - captain: NPC - size: string - cleanliness: string -} diff --git a/src/Docks/createDocks.js b/src/Docks/createDocks.js deleted file mode 100644 index c63a18ff5..000000000 --- a/src/Docks/createDocks.js +++ /dev/null @@ -1,47 +0,0 @@ -// uses setup.createNPC -setup.createDocks = (town, opts = {}) => { - const createBuilding = opts.newBuilding || lib.createBuilding - - const docks = createBuilding(town, 'docks', opts) - Object.assign(docks, { - notableFeature: setup.docks.notableFeature.random(), - notice: setup.docks.notice.random(), - passageName: 'DocksOutput', - initPassage: 'DocksOutput', - buildingType: 'docks', - objectType: 'building', - needsWordNoun: false, - associatedNPC: setup.createNPC(town, Object.assign({ - isShallow: true, - profession: 'stevedore' - }, opts.npc)), - wordNoun: ['docks', 'pier', 'wharf', 'dockyard', 'shipyard', 'quay', 'staithe', 'marina', 'jetty', 'harbor', 'berth', 'port', 'seaport', 'dockyard'].random(), - ships: {} - }) - lib.createReciprocalRelationship(town, docks, docks.associatedNPC, { relationship: 'stevedore', reciprocalRelationship: 'place of employment' }) - - docks.name = lib.toTitleCase([ - `The ${['Old', 'New', '', ''].random()} ${[`${town.name}`, `${town.name}`, '', '', ''].random()} ${docks.wordNoun.toUpperFirst()}`, - `${[ - docks.associatedNPC.lastName, - `${docks.associatedNPC.firstName}'s`, - `${[ - docks.associatedNPC.firstName, - docks.associatedNPC.lastName - ].random()} Beach` - ].random()} ${docks.wordNoun}` - ].random()) - - const rollDataVariables = ['size', 'cleanliness', 'activity'] - for (const propName of rollDataVariables) { - lib.defineRollDataGetter(docks, setup.docks.rollData[propName].rolls, propName) - } - - lib.defineRollDataGetter(docks, setup.docks.rollData.size.rolls, 'sizeDescriptive', 'size', 2) - lib.defineRollDataGetter(docks, setup.docks.rollData.cleanliness.rolls, 'cleanlinessDescriptive', 'cleanliness', 2) - lib.defineRollDataGetter(docks, setup.docks.rollData.activity.rolls, 'activityDescriptive', 'activity') - docks.tippyDescription = `${lib.articles.output(docks.wordNoun).toUpperFirst()} that's ${docks.size || docks._size}. It is ${docks.cleanliness || docks._cleanliness}, and is known for ${docks.notableFeature}.` - setup.docks.ships.create(town, docks) - - return docks -} diff --git a/src/Docks/createDocks.ts b/src/Docks/createDocks.ts new file mode 100644 index 000000000..6b4873569 --- /dev/null +++ b/src/Docks/createDocks.ts @@ -0,0 +1,69 @@ +import { Docks, NPC, Town } from '@lib' + +interface Options { + newBuilding(town: Town, type?: string): Docks + npc: Partial +} + +// uses setup.createNPC +export const createDocks = (town: Town, opts: Options) => { + const createBuilding = opts.newBuilding || lib.createBuilding + + const docks = createBuilding(town, 'docks') + Object.assign(docks, { + notableFeature: lib.random(lib.docksData.notableFeature), + notice: lib.random(lib.docksData.notice), + passageName: 'DocksOutput', + initPassage: 'DocksOutput', + buildingType: 'docks', + objectType: 'building', + needsWordNoun: false, + associatedNPC: setup.createNPC(town, Object.assign({ + isShallow: true, + profession: 'stevedore' + }, opts.npc)), + wordNoun: lib.random(['docks', 'pier', 'wharf', 'dockyard', 'shipyard', 'quay', 'staithe', 'marina', 'jetty', 'harbor', 'berth', 'port', 'seaport', 'dockyard']), + ships: {} + }) + lib.createReciprocalRelationship(town, docks, docks.associatedNPC, { relationship: 'stevedore', reciprocalRelationship: 'place of employment' }) + + docks.name = lib.toTitleCase( + lib.random([ + `The ${lib.random( + ['Old', 'New', '', ''] + )} ${lib.random( + [`${town.name}`, `${town.name}`, '', '', ''] + )} ${docks.wordNoun.toUpperFirst()}`, + `${lib.random([ + docks.associatedNPC.lastName, + `${docks.associatedNPC.firstName}'s`, + `${lib.random([ + docks.associatedNPC.firstName, + docks.associatedNPC.lastName + ])} Beach` + ])} ${docks.wordNoun}` + ]) + ) + + const rollDataVariables = [ + ['size', 'size'], + ['cleanliness', 'cleanliness'], + ['activity', 'activity'], + ['size', 'sizeDescriptive', 2], + ['cleanliness', 'cleanlinessDescriptive', 2], + ['activity', 'activityDescriptive'] + ] as const + for (const [key, propName, rollLocation] of rollDataVariables) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + lib.defineRollDataGetter(docks, lib.docksData.rollData[key].rolls, propName, key, rollLocation) + } + + // lib.defineRollDataGetter(docks, lib.docksData.rollData.size.rolls, 'sizeDescriptive', 'size', 2) + // lib.defineRollDataGetter(docks, lib.docksData.rollData.cleanliness.rolls, 'cleanlinessDescriptive', 'cleanliness', 2) + // lib.defineRollDataGetter(docks, lib.docksData.rollData.activity.rolls, 'activityDescriptive', 'activity') + docks.tippyDescription = `${lib.articles.output(docks.wordNoun).toUpperFirst()} that's ${docks.size}. It is ${docks.cleanliness}, and is known for ${docks.notableFeature}.` + lib.docksData.ships.create(town, docks, {}) + + return docks +} diff --git a/src/Docks/docks.js b/src/Docks/docks.js deleted file mode 100644 index 8ae9bcbfb..000000000 --- a/src/Docks/docks.js +++ /dev/null @@ -1,700 +0,0 @@ -setup.initDocks = () => { - setup.docks = { - rollData: { - cleanliness: { - description: 'How clean are the docks?', - preceding: 'Dock Cleanliness:', - rolls: [ - [80, 'quite clean', 'spotless, save for a couple splashes of sea water'], - [70, 'safe, if smelly', 'quite tidy, if you can stand the smell'], - [50, 'relatively tidy', 'reasonably clean, with the occasional rope laying about posing a tripping hazard'], - [40, 'crusty and dirty', 'crusted with sea water and barnacles cling to the supports'], - [30, 'seaweed infested', 'marred with seaweed and a slippery mess. It smells disgusting, too'], - [0, 'disgustingly slimy', 'disgusting. All types of moulds, algae, and other unspeakably slimy things are on display here.'] - ] - }, - size: { - description: 'How large are the docks?', - preceding: 'Dock Size:', - rolls: [ - [90, 'large and sprawling', 'huge; it sprawls across the body of water, as far as the eye can see'], - [80, 'large', 'large. It has the space and equipment to accommodate a fleet of ships'], - [60, 'big', 'big, with space to accommodate several galleons'], - [50, 'accommodating', 'average sized, with room enough for a fair few ships'], - [40, 'geared towards smaller vessels', 'on the small size; it is geared towards fishing vessels, but has the capacity for larger ships if needed'], - [30, 'small', 'small, and clearly geared towards smaller vessels such as fishing ships. You could probably fit a large ship in, if you were lucky'], - [20, 'pretty small', 'quite small, with room for fishing ships and little else'], - [0, 'glorified jetty', 'tiny; barely more than a glorified jetty'] - ] - }, - activity: { - description: 'How busy is the docks at the moment?', - preceding: 'Dock Activity:', - rolls: [ - [100, 'packed to the gills; you have trouble moving through some parts of the harbor due to the throngs of seafarers crowding the place'], - [90, [ - 'absolutely packed; the din of everyone shouting to one another to fetch another barrel and other such things makes the place feel alive', - 'absolutely packed; the din of everyone shouting to one another to haul in the fish off the boat and other such things makes the place feel alive', - 'absolutely packed; the din of everyone shouting to one another to get off their asses and shift this pile of rope and other such things makes the place feel alive' - ]], - [80, [ - 'bustling. There are all manners of folk walking around, all of whom have places to be', - 'bustling. Several ships seem to be currently unloading and crowds are beginning to fill the street' - ]], - [70, 'reasonably busy, with a couple folks milling about, waiting for a ship to dock'], - [60, [ - 'busy, with lots of deckhands running about, lugging things from point A to point B', - 'busy, with several large makeshift fish markets crowding the docks drawing in all kinds of crowds' - ]], - [50, 'reasonably busy, with a decent amount of activity'], - [40, 'relatively quiet, with some fishermen getting ready to head out on a trip'], - [30, 'pretty quiet, save for the gulls which are swooping around, eager to steal any unattended bread'], - [20, 'very quiet. There is next to nobody around'], - [10, 'rather peaceful, the silence only disturbed by the gentle lapping of water against rocks'], - [0, [ - 'deathly silent, save for the gentle sounds of the water lapping against the docks', - 'empty, save for a lone fisherman sitting and watching his lure bob up and down in the waves' - ]] - ] - } - }, - notableFeature: [ - // which are best known for _ - 'the foul smelling fish that fisherman haul in', - 'being a good place to get mugged', - 'a large lookout post that warns the shipmaster of approaching ships', - 'an impressive looking boat that has been moored for many years', - 'being the best place to go if you are looking to get into a fight', - 'single handedly keeping the brothels in business', - 'its ships that are all incredible smelly, but rather swift on the waters', - 'being a tourist attraction', - 'the Sea Priests and clergymen who roam the docks blessing ships before they set sail', - "it's shipwrights. The dry docks here have birthed a large portion of the local navy", - 'a fine dining restaurant that hangs suspended off the end of the pier', - "it's shady wharfmaster, who appears to be willing to turn a blind eye to just about anything for the right price", - "it's large ornate lighthouse, an ancient statue of a humanoid figure with all details eroded by time. It holds the lighthouse's beacon aloft in it's hand", - 'the waters around the docks being infested with predatory fish and poisonous snakes', - 'the exotic stone used to construct the docks', - "a peculiar ship docked here, constricted from living trees fed from it's soil filled hull", - 'the sun bleached wrecks littering the shore line', - 'local urban legends about ghosts ships and damned crew members', - 'the time the local the local militia and fishermen held back a pirate raid on the town here', - 'the large marble slabs that anchor the docks to the shore', - 'the thick oak timbers of the piers', - 'the enormous hand crafted ropes that tie down the ships', - 'a huge lighthouse that guides ships to the port', - 'being built inside an enormous cavern' - ], - notice: [ - 'a pair of beggars arguing over a dead fish', - 'some seagulls flying overhead', - 'an entrepreneurial fellow selling hot foods from a cart', - 'a sailor struggling to lift a coil of rope', - 'a pair of burly men shifting a barrel onto a ship', - 'a captain pointing at a map, arguing with another man', - 'there is a certain quietness to the air; nobody is shouting as is usual in dockyards', - 'the atmosphere is a little on edge; sailors are more curt than usual, and the dock hands are grimacing as they load the ships with goods', - 'there is a foul stench in the air; like a rotting fish, only much larger, with no escape from the stomach turning scent to be found in buildings, or behind a scented hankerchief', - 'a pair of sailors accidentally dropping one of their crates of cargo into the water', - 'a sailor in the water trying to rescue a dropped supply barrel', - 'a crew unfurling the sails of their ship as they head for open waters', - // a(n) enormous/large/moderately sized/regular/small/tiny/single stall fish market selling a large variety of fish/an inconceivable number of fish, crabs, shrimp, and other sea creatures/a small selection of fish/a pitiful variety fish - 'a small group of men posing for a portrait with the carcass of an enormous sea monster strung up from a tall wooden pole', - 'a person in dirty rags attempting to sell a single fish to passersby', - 'an incredibly large <> docked out in the water. It is ornately painted with the figurehead of a magical animal', - 'a large crowd gathered in front of an absolutely gargantuan severely damaged ship slowly drifting into port', - 'a lone fisherman sitting at the edge and waiting for his catch', - 'two men pulling up crab traps out of the water', - 'a haggard old woman weaving baskets out of seaweed' - ], - ships: { - create (town, docks, opts) { - const ship = { - name: setup.docks.ships.name.random(), - type: Object.keys(setup.docks.ships.type).random(), - captainType: Object.keys(setup.docks.ships.captain).random(), - hull: setup.docks.ships.hullDesc.random(), - detail: setup.docks.ships.shipDetail.random(), - event: setup.docks.ships.eventDetail.random(), - roll: { - size: random(1, 100), - cleanliness: random(1, 100) - } - } - Object.assign(ship, setup.docks.ships.type[ship.type]) - ship.captain = setup.createNPC(town, setup.docks.ships.captain[ship.captainType]) - docks.ships[ship.name] = ship - - const rollDataVariables = ['size', 'cleanliness'] - rollDataVariables.forEach(function (propName) { - lib.defineRollDataGetter(ship, setup.docks.ships.rollData[propName].rolls, propName) - }) - return ship - }, - crew: { - create (town) { - const crewType = Object.keys(setup.docks.ships.crew.type).random() - - const readout = { - bodyFeature: setup.docks.ships.crew.bodyFeature.random(), - itemFeature: setup.docks.ships.crew.itemFeature.random(), - sailReason: setup.docks.ships.crew.sailing.random() - } - const crewTraits = Object.assign({ - isShallow: true, - hasClass: false, - profession: 'sailor' - }) - Object.assign(crewTraits, setup.docks.ships.crew.type[crewType]) - const crew = setup.createNPC(town, crewTraits) - const heShe = crew.heshe - const hisHer = crew.hisher - return `Out of the crew steps ${crewType} named ${setup.profile(crew)}. ${heShe.toUpperFirst()} ${readout.bodyFeature} and ${readout.itemFeature}. When asked about why ${heShe} took to the sea, ${hisHer} reason is "${readout.sailReason}".` - }, - type: { - 'a veteran of the sea who may have been beautiful at one point': { - gender: 'woman', - note: 'A woman whose skin has been brined by the salt water.' - }, - 'a young sailor excited to take to the sea': { - ageStage: 'young adult', - calmTrait: 'passionate' - }, - 'a wide eyed adventurer of the sea just getting a first true taste of sailing': { - ageStage: 'young adult', - calmTrait: 'curious', - profession: 'wannabe pirate', - note: 'This person has great ambitions' - }, - 'an older, well-brined master of sailing': { - ageStage: 'elderly' - }, - 'an ordinary looking sailor': {}, - 'a stoic looking veteran': { - ageStage: 'settled adult', - calmTrait: 'quiet', - stressTrait: 'reliable' - }, - 'a rugged and battered looking bilge rat': { - note: 'This person has extremely dirty clothing on.' - }, - 'a suspiciously regal and seasick looking sailor': { - profession: 'sailor', - socialClass: 'nobility', - note: 'This character is a noble in hiding.' - } - }, - // He/She (bodyFeature) and (itemFeature) . - bodyFeature: [ - 'has a bright pink scar running across the <> hand', - 'is missing the <> eye and instead has a glass one', - 'has long matted hair', 'has a thick layer of dirt covering the skin', - 'has a large number of sun spots', - 'is covered in freckles', - 'has a cleft chin', - 'has deep sunken eyes', - 'has leathery thick skin from the hot sun', - 'is missing several teeth', - 'is missing an ear', - 'has acne riddled skin', - 'has hawkish eyes the seem to catch every movement', - 'has rather pale skin for someone who works in the sun', - 'has course calloused hands from working with rope daily', - 'smells distinctly of the sea', - 'has a square jaw', - 'has a large bulbous nose', - 'has a crooked nose', - 'has a crooked smile', - 'has the eyes of a rat', - 'is hunched over all of the time', - 'suffers from a limp', - 'has a noticeable stutter', - 'has a large wart on the chin', - 'has incredibly long and nimble fingers', - 'has very expressive eyebrows', - 'has beautifully clean skin', - 'has short but unkempt hair', - 'is broad shouldered', - 'has a slender jaw', - 'has muscled arms from the hard work of the sea', - 'has a spoon lodged into the nub at the end of their arm where their hand should be', - 'has large cauliflower ears', - 'has rather pungent body odor' - ], - itemFeature: [ - 'is wearing a grungy looking sailors cap', - 'is wearing a cheap looking eyepatch', - 'has on clothes that are rugged and tattered from the storms', - 'is wearing clothes that are stiff from all the sea salt caked upon them', - 'always carries a fancy looking compass that only points <>', - 'has a crudely carved peg leg', - 'has a large hook for a hand', - 'has a very well crafted mahogany peg leg', - 'uses a crude walking stick', - 'uses a finely carved oak walking stick', - 'uses a walking cane with the head of a <> carved at the top', - 'is always wearing a backpack', - 'wears a thick seal leather coat to keep dry', - 'has a collapsible spyglass tied to their belt', - 'has a lucky accordion on hand at all times', - 'is wearing a tattered bandana', - 'is wearing a rather filthy looking cocked hat with a ragged feather poking out', - 'is wearing some thick leathery boots absolutely riddled with holes and rips', - 'has a large colorful parrot on one shoulder', - 'is wearing a large skull pendant', - 'is wearing a small jeweled pendant', - 'has some sort fo necklace tucked under their shirt' - - ], - // When asked why he/she took to the sea, his/her reason is _ . - sailing: [ - 'the sea called to me and I answered her', - 'to try and find all the buried treasures that have been left behind', - 'for the riches that lie below', - 'adventure was calling me and the sea is where the greatest adventures happen', - 'I needed coin for a debt and I still need to pay it off', - 'I needed to get away from some trouble', - 'nobody cares about your past out at sea', - 'I just love the color blue', - 'the captain is a friend of mine and they asked me to come aboard', - 'the captain pays well', - "I don't know any other trade", - "all my family has sailed the sea. I'm just following in their footsteps", - 'it sounded like fun at the time', - 'I was sick of my town and wanted a change of scenery', - 'I lost my beloved and with it my only reason to stay on land', - 'to make enough money for my family to eat' - ] - }, - name: ['Lantheon', 'Starchaser', 'Dryad’s Fury', 'Black Trident', 'Corellon’s Arrow', 'Morkoth', 'Koalinthas', 'Sehanine’s Fool', 'Stormcrow', 'Vaazrus', 'Shield of Khahar', - 'Stingray', 'Sanaj-Rakal', 'Zhal-Vazir', 'Griffonwing', 'Blademark', 'Golden Libram', 'Hareth’s Barrel', 'Kasha’s Wake', 'Shining Flute', 'White Feather', 'Riventide', - 'Moonriser', 'Gem of Malfier', 'Dragon’s Glory', 'Menacer', 'Scarlet Dagger', 'Kral-Tajir', 'Ravager', 'Kerle’s Drum', 'Heart of Avandra', 'Goldraker', 'Sea Haunt', 'Storm Maven', - 'Grimbol’s Cutlass', 'Scimitar', 'Black Gauntlet', 'Iron Maiden', 'Wavecrusher', 'Hammer of Kavath', 'Waterblade', 'Arkhor’s Secret', 'Dire Gar', 'Prallmar’s Shadow', 'Piranha', - 'Devil’s Fork', 'Tuersyl’s Fist', 'Daraj-Vzan', 'Silver Chalice', 'Demonrudder', 'Turathi Flame', 'Storm’s Eye', 'Tanishar’s Fate', 'Shard of Night', 'Triton', 'Jarak’s Grasp', - 'Nightmare', 'Harpy’s Lure', 'Devious', 'Arazandro’s Bluff', 'Nbod’s Haul', 'Astaryntha', 'Expeditious', 'Curse of Thuban', 'Siren’s Kiss', 'Lonely Witch', 'Rat’s Nest', - 'Evader', 'Mistreaver', 'Ven’r', 'Vicious', 'Dream of Melora', 'Shensari', 'Damilor', 'Krimilvin’s Charm', 'Bloodmonger', 'Lucky Scrag', 'Windstriker', 'Grim Gale', 'Djinni’s Wish', - 'Flying Eel', 'Jewel of Irthos', 'Broken Keel', 'Javelin', 'Myrska’s Revenge', 'Fearsome', 'Archon’s Hammer', 'Vendetta', 'Thunderchaser', 'Heartless', 'Shrike', 'Morak’s Boat', - 'Mar-Turang', 'Will-o’-wisp', 'Asha-Naga', 'Dominant', 'Shoal Courser', 'Crescent Moon', 'Crystal Tear', 'Kara-Vaji', 'Shalastar', 'Roc’s Talon', 'Wavecarver', 'Graethan', - 'Rotten Apple', 'Bharzim’s Victory', 'Avarice', 'Farak-Changal', 'Falling Star', 'Crimson Knife', 'Yisek’s Ride', 'Shara-Vaja', 'Varalan’s Dweomer', 'Rangoth', 'Vostarika', - 'Mirasandra', 'Second Chance', 'Redfeather', 'Maal-Destir', 'Scorpion', 'Ghorzaar’s Bane', 'Moonwatcher', 'Dragon’s Crown', 'Dragonhawk', 'Dancing Sword', 'Kaveth’s Whisper', - 'Tirah', 'Phantom Shark', 'Hjeltia', 'Satyr', 'Breyten’s Thrill', 'Golden Coin', 'Pearl of Fire', 'Bhez-Rizma', 'Fireball', 'Color Spray', 'Sea Bear', 'Prosperous', 'Summer Rain', - 'Sundowner', 'Skulldark’s Ire', 'Skandalor', 'Zarkanan', 'Sana-Losi', 'Wolfshark', 'Song of Elyndri', 'Coral Rose', 'Rune of Halendros', 'Maelstrom', 'Shadow Mask', - 'Deep Heathen', 'Aurora', 'Rusted Cutlass', 'Thog’s Maul', 'Wooden Stake', 'Hellstrike', 'Scepter Queen', 'Prince of Lies', 'Fang of Tezmyr', 'White Hart', 'Floating Cask', - 'Sea Howler', 'Frostwind', 'Moonshadow', 'Melora’s Favor', 'Dark Queen’s Voice', 'Chethel’s Ghost', 'Mad Hag', 'Tamarion’s Grudge', 'Raven’s Gamble', 'Reckoner', 'Wraithwind', - 'Kalisa Tano', 'Beholder', 'Slippery Trickster', 'Retribution', 'Whirling Glyph', 'Lady Rose', 'Karthang’s Plunder', 'Good Fortune', 'Axe of Thard', 'Black Bow', 'Quickstrike', - 'Thelandira', 'Hammergust', 'Barracuda', 'Sahandrian’s Quarrel', 'Feral Knave', 'Wildwyrm', 'Shevaya’s Honor', 'Blackhelm’s Legacy', 'Wyvern’s Sting', 'Dragonroar', 'Kegstaff', - 'Oaken Ranger', 'Timber Serpent', 'Desperate Sorceress', 'Screaming Gull', 'Greedy Drake', 'Light of Pjaltr', 'Fate’s Blessing', 'Stardancer', 'Leering Skull', 'Ebon Moon', - 'Werewolf', 'Redemption', 'Zaetchan’s Privilege', 'Sea Skulk', 'Savage Swan', 'Bane’s Breath', 'Ghorok’s Grail', 'Emerald Eye', 'Remorseless', 'Skiprock', 'Zaetra', 'Silverfin', - 'Risen Ghost', 'Listless', 'Vortex', 'Advantage', 'Autumn Song', 'Trystan’s Delight', 'Soaring Manta', 'Calomaar’s Edge', 'Saerthzal', 'Iron Trumpet', 'Locathah', 'Demonskull', - 'Arrowhead', 'Frastain’s Bottle', 'The Saint Ive', 'Halygast', 'La Bon An', 'La Katerine', 'The Blythe', 'Rose', 'The Flying Squirrel', 'Golden Lion', 'Panther', 'Silent Night'], - // The hull of the ship _ - hullDesc: [ - 'is encrusted with several very large and oddly colored barnacles', - 'is battered and old. The planks of the ship creak loudly in protest as it bobs through the water', - 'looks fresh and new as if it was built only yesterday', - 'looks to be damaged from a recent storm or perhaps a fight at sea', - 'has a great many number of nets hanging down it', - 'has several small portholes', - 'is grungy and dirty looking', - 'has a long gangplank hanging from the top of it', - 'appears to be wrapped with bands of iron', - 'has several boards nailed to the side in hasty repair', - 'has a long nasty gouge across it', - 'has a great number of pulleys affixed to it', - 'is decorated with many ornate brass fixtures', - 'has a few colorful banners hung across it, tattered by the sea' - // TODO: refactor these to not use either, as either breaks the seed - // 'has been painted to resemble <>', - // 'has been painted so the top half is <> and the bottom half is <>', - // 'is painted with small ornate <> patterns at the edges', - // 'has "$currentShip.name" painted on it in bold <> letters', - // 'is built out of bare <> ', - // 'has <> of <> colored paint going across it', - // 'is painted pure <>' - ], - // On board you notice _ - shipDetail: [ - 'all of the crew members are wearing matching uniforms', - 'the ship figurehead is a beautifully carved <>', - 'the ship seems to be barely held together with patchwork boards and makeshift nails', - "the captain's quarters has an expensive looking piano in it", - 'the rails of the ship are shaped like fish', - 'several large piles of tangled nets sitting around', - 'a large barrel full of poorly carved peglegs', - 'a small set of hooks with nameplates above them; one of them has an eyepatch hanging off of it', - 'several fishing rods bundled together', - 'a few small piles of unsorted fish and ocean debree sitting near the bow', - 'instead of a wheel there is a large lever jutting out in its place', - 'several hammocks have been set up for crew to be able to sleep under the night sky', - 'a few crew members are playing cards off in a corner', - 'all the ships rails are shaped like swords', - 'a large flag is hoisted high on top the mast', - 'a large locked chest off to one side of the deck', - "a large open chest off to one side of the deck, you can't quite see what's inside", - 'a small cage on deck with a few slaves inside', - 'a lusty looking harlot flirting with the captain', - 'a large barrel of oranges', - 'the body of a large sea creature strung up from the mast', - 'several different piles of potatoes in the cargo hold', - 'a large harpoon gun mounted near the front of the deck', - 'a small harpoon gun mounted at the side of the deck', - 'a few crates that seem to shake every once and a while', - "a bright red painted door that leads to the captain's quarters" - // 'a <> the crew keeps as a pet', - // 'the wheel of the ship appears to be made from <>' - ], - // The crew are currently _ - eventDetail: [ - 'prepping for a rather long journey far from mainland', - 'prepping the ship to set sail', - 'mulling about doing a whole lot of nothing', - 'on a mission to bring some secret cargo to a secret buyer', - 'just trying to get by until they get their next big break', - 'all partaking in a large open ring brawl on the deck of the ship', - 'partaking in an inner-crew fishing tournament', - 'trying to decipher a map one of them found in a bottle', - 'mostly relaxing on deck, eating, and laying about enjoying the sea breeze', - 'hauling goods and supplies up into cargo', - 'drinking deeply and laughing loudly', - 'seeking a great treasure that they heard about from a passing pirate', - 'planning to become pirates after a string of bad luck', - 'fitting the ship with cannons', - 'practicing tying different kinds of knots', - 'partaking in a safety class on the harpoon gun', - 'mostly asleep below deck or off in town', - 'gathered around the captain listening to an outrageously tall tale', - 'going about their normal day to day', - 'trying to patch up a considerably big leak in the hull', - 'crowded around a large chest that they seem to be trying to pry open', - 'trying to pry open an enormous clam they fished up on their last journey', - 'having a crew wide jig off by the stern', - 'planning a mutiny against the captain', - 'trying to pull up the anchor which appears to be stuck' - // 'singing a jaunty sea shanty about <> at the tops of their lungs' - ], - type: { - 'caravel': { - masts: random(2, 3), - rigging: 'lateen', - length: random(468, 708), - purpose: ['sailing', 'cargo', 'pirate'], - hasOars: false, - crewMen: random(20, 30) - }, - 'rowboat': { - masts: 0, - rigging: 'no', - length: random(180, 240), - purpose: ['fishing'], - hasOars: true, - crewMen: random(1, 3) - }, - 'dory': { - masts: 0, - rigging: 'no', - length: random(180, 400), - purpose: ['fishing'], - hasOars: true, - crewMen: random(1, 10) - }, - 'drifter': { - masts: 0, - rigging: 'no', - length: random(180, 400), - purpose: ['fishing'], - hasOars: true, - crewMen: random(1, 10) - }, - 'herring buss': { - masts: random(2, 3), - rigging: 'square', - length: random(180, 400), - purpose: ['fishing'], - hasOars: false, - crewMen: random(5, 25) - }, - 'carrack': { - masts: random(3, 4), - rigging: 'square', - length: random(800, 920), - purpose: ['sailing', 'cargo', 'navy', 'merchant'], - hasOars: true, - crewMen: random(30, 40) - }, - 'crayer': { - masts: 3, - rigging: 'square', - length: random(468, 708), - purpose: ['cargo', 'merchant'], - hasOars: true, - crewMen: random(30, 40) - }, - 'hoy': { - masts: 1, - rigging: 'square', - length: random(400, 460), - purpose: ['cargo'], - hasOars: true, - crewMen: random(30, 40) - }, - 'picard': { - masts: 1, - rigging: 'square', - length: random(150, 240), - purpose: ['cargo'], - hasOars: true, - crewMen: random(5, 20) - }, - 'galley': { - masts: 3, - rigging: 'lateen', - length: random(3800, 4200), - purpose: ['navy', "adventurer's", 'pirate'], - hasOars: true, - crewMen: random(80, 120) - }, - 'longship': { - masts: 1, - rigging: 'square', - length: random(1600, 1800), - purpose: ['navy', 'cargo', 'transport'], - hasOars: true, - crewMen: random(80, 120) - }, - 'balinger': { - masts: 1, - rigging: 'square', - length: random(800, 1200), - purpose: ['cargo', 'fishing', 'transport'], - hasOars: true, - crewMen: random(30, 80) - }, - 'frigate': { - masts: 3, - rigging: 'square', - length: random(1500, 1700), - purpose: ['navy', 'cargo', 'pirate', "adventurer's"], - hasOars: true, - crewMen: random(30, 40) - }, - 'galleon': { - masts: 3, - rigging: 'lateen', - length: random(3800, 4200), - purpose: ['navy', 'cargo', 'pirate', 'merchant', "adventurer's"], - hasOars: true, - crewMen: random(80, 120) - }, - 'galleass': { - masts: 3, - rigging: 'square', - length: random(3800, 4200), - purpose: ['cargo', 'transport', 'navy', 'pirate', "adventurer's"], - hasOars: true, - crewMen: random(80, 140) - }, - 'nef': { - masts: 3, - rigging: 'square', - length: random(2400, 2800), - purpose: ['cargo', 'exploration'], - hasOars: true, - crewMen: random(40, 120) - }, - 'barque': { - masts: random(3, 5), - rigging: 'square', - length: random(3000, 5000), - purpose: ['cargo', 'transport', "explorer's", 'pirate'], - hasOars: true, - crewMen: random(65, 120) - } - }, - captain: { - 'a seasoned veteran': { - profession: "ship's captain", - hasClass: false, - background: 'sailor' - }, - 'a reformed pirate': { - profession: "ship's captain", - hasClass: false, - background: 'sailor', - note: 'A reformed pirate.' - }, - 'a nobleman with more money than sense': { - profession: "ship's captain", - hasClass: false, - background: 'noble', - note: 'Inexperienced on the sea.', - gender: 'man' - }, - 'a relatively inexperienced, but gifted young lad': { - profession: "ship's captain", - background: 'sailor', - hasClass: false, - gender: 'man', - calmTrait: 'quick on his feet' - }, - 'a woman with a temper': { - profession: "ship's captain", - background: 'sailor', - hasClass: false, - gender: 'woman', - calmTrait: 'quick to anger', - stressTrait: 'extremely snappy' - }, - 'a stern man, with a long beard': { - profession: "ship's captain", - background: 'sailor', - hasClass: false, - gender: 'man', - beard: 'long and majestic', - calmTrait: 'stern', - stressTrait: 'shouty' - }, - 'a dwarf that wanted to see the seas': { - profession: "ship's captain", - background: 'sailor', - race: 'dwarf', - hasClass: false - }, - 'a man searching for his long lost lover': { - profession: "ship's captain", - background: 'sailor', - gender: 'man', - hasClass: false, - note: 'He is searching for his long lost lover.' - }, - 'an elf who has forsaken the earth': { - race: 'elf', - hasClass: false - }, - 'a half-orc with a passion for marine life': { - profession: "ship's captain", - background: 'sailor', - race: 'half-orc', - hasClass: false - }, - 'a stoic woman with a quiet voice': { - profession: "ship's captain", - background: 'sailor', - gender: 'woman', - vocalPattern: 'has a quiet voice', - hasClass: false - }, - 'an ex mercenary': { - profession: "ship's captain", - background: 'soldier' - }, - 'a retired merchant': { - profession: "ship's captain", - background: 'merchant', - ageStage: 'elderly', - hasClass: false - }, - 'a young boy who inherited the ship': { - profession: "ship's captain", - background: 'sailor', - ageStage: 'young adult', - note: 'Inherited the ship.', - hasClass: false - } - }, - rollData: { - size: { - rolls: [ - // it is a _______ $ship.type - [90, 'huge'], - [80, 'impressively sized'], - [60, 'somewhat impressive'], - [50, 'average sized'], - [30, 'somewhat unimpressive'], - [20, 'cluttered'], - [10, 'cluttered and cramped'] - ] - }, - cleanliness: { - rolls: [ - // ... that is - [80, 'absolutely spotless; it must have been cleaned recently, as no barnacles adorn the bottom of the ship'], - [80, 'spotless, save for a couple barnacles'], - [70, 'in quite good condition, with only a couple barnacles clinging on to the bottom'], - [50, 'in reasonable condition, with some barnacles hanging on, creating drag at speed'], - [40, 'in need of a good clean, with barnacles clinging to the bottom of the ship'], - [30, 'in desperate need of a thorough de-barnacleing, as well as a general clean'], - [20, 'filthy and laden with barnacles covering the bottom of the boat'] - ] - } - } - }, - get: { - customers: [ - { - relationshipDescription: 'regular', - relationships: { - building: { - relationship: 'regular', - reciprocalRelationship: 'place of work' - }, - associatedNPC: { - relationship: 'acquaintance' - } - }, - base: { - professionSector: 'naval' - }, - description (building, npc) { return `${npc.firstName} works with ships.` } - }, - { - relationshipDescription: 'shipwright', - relationships: { - building: { - relationship: 'shipwright', - reciprocalRelationship: 'place of work' - }, - associatedNPC: { - relationship: 'acquaintance' - } - }, - base: { - profession: 'shipwright' - }, - description (building, npc) { return `${npc.firstName} constructs and repairs ships in ${building.name}.` } - }, - { - relationshipDescription: 'bosun', - relationships: { - building: { - relationship: 'bosun', - reciprocalRelationship: 'place of work' - }, - associatedNPC: { - relationship: 'acquaintance' - } - }, - base: { - profession: 'bosun' - }, - description (building, npc) { return `${npc.firstName} works to organise equipment to be loaded off ${building.name} and onto ${npc.hisher} ship.` } - }, - { - relationshipDescription: 'stevedore', - relationships: { - building: { - relationship: 'stevedore', - reciprocalRelationship: 'place of work' - }, - associatedNPC: { - relationship: 'acquaintance' - } - }, - base: { - profession: 'stevedore' - }, - description (building, npc) { return `${npc.firstName} hauls stuff off ships and onto ${building.name}.` } - } - ] - } - } -} diff --git a/src/main.ts b/src/main.ts index 5bd261541..e3364269d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -43,6 +43,7 @@ import { createBlacksmithProject } from './Blacksmith/js/blacksmithProject' import { createSmithyName } from './Blacksmith/js/createSmithyName' import { createSmithy } from './Blacksmith/js/createSmithy' import { createReciprocalRelationshipNpc } from './Buildings/Components/buildingRelationshipNpc' +import { createDocks } from './Docks/createDocks' declare global { interface Setup { @@ -99,6 +100,7 @@ declare global { createSmithyName: typeof createSmithyName createSmithy: typeof createSmithy createReciprocalRelationshipNpc: typeof createReciprocalRelationshipNpc + createDocks: typeof createDocks } } @@ -155,7 +157,8 @@ Object.assign(setup, { createBlacksmithProject, createSmithyName, createSmithy, - createReciprocalRelationshipNpc + createReciprocalRelationshipNpc, + createDocks }) /** @@ -172,7 +175,7 @@ setup.init = (setup => () => { setup.initNpcData() setup.initTavernData() setup.initGoodsAndServices() - setup.initDocks() + // setup.initDocks() setup.initCastle() setup.initBuildingTypes() })(setup)