@dreadwood-types/types 0.1.286 → 0.1.288
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/arcaneRealms.d.ts +18 -0
- package/dist/arcaneRealms.d.ts.map +1 -0
- package/dist/arcaneRealms.js +25 -0
- package/dist/arcaneRealms.js.map +1 -0
- package/dist/arcaneRealmsContent.d.ts +144 -0
- package/dist/arcaneRealmsContent.d.ts.map +1 -0
- package/dist/arcaneRealmsContent.js +199 -0
- package/dist/arcaneRealmsContent.js.map +1 -0
- package/dist/arcaneRealmsQuestDef.d.ts +38 -0
- package/dist/arcaneRealmsQuestDef.d.ts.map +1 -0
- package/dist/arcaneRealmsQuestDef.js +191 -0
- package/dist/arcaneRealmsQuestDef.js.map +1 -0
- package/dist/areaGates.d.ts.map +1 -1
- package/dist/areaGates.js +12 -0
- package/dist/areaGates.js.map +1 -1
- package/dist/attackableNpcs.d.ts.map +1 -1
- package/dist/attackableNpcs.js +5 -0
- package/dist/attackableNpcs.js.map +1 -1
- package/dist/bossSignatures.d.ts +1 -1
- package/dist/bossSignatures.d.ts.map +1 -1
- package/dist/bossSignatures.js +6 -0
- package/dist/bossSignatures.js.map +1 -1
- package/dist/capitalQuests.js +1 -1
- package/dist/capitalQuests.js.map +1 -1
- package/dist/capitalShops.d.ts +160 -0
- package/dist/capitalShops.d.ts.map +1 -0
- package/dist/capitalShops.js +363 -0
- package/dist/capitalShops.js.map +1 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js.map +1 -1
- package/dist/explorerLedger.d.ts +2 -1
- package/dist/explorerLedger.d.ts.map +1 -1
- package/dist/explorerLedger.js +6 -0
- package/dist/explorerLedger.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/quests.d.ts.map +1 -1
- package/dist/quests.js +30 -1
- package/dist/quests.js.map +1 -1
- package/dist/storyQuests.d.ts +2 -1
- package/dist/storyQuests.d.ts.map +1 -1
- package/dist/storyQuests.js +17 -0
- package/dist/storyQuests.js.map +1 -1
- package/package.json +43 -43
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE CAPITAL'S SHOPS AND SET PIECES (track T90, 2026-10-14; plan `.cursor/task-plans/2026-10-14-t90-capital-shops.md`), the follow-on to
|
|
3
|
+
* T77's quests (capitalQuests.ts). After T77 the Capital had thirteen quests and no shops: the planned market and district NPC spots
|
|
4
|
+
* (CAPITAL_NPC_SPOTS) were empty tiles. This file puts eight shopkeepers on them, and adds the two set pieces T77 left:
|
|
5
|
+
*
|
|
6
|
+
* - EIGHT SHOPKEEPERS, named residents on the city-folk look (the client dresses a Capital person by its id; the chandler is a docker),
|
|
7
|
+
* each with a counter of EXISTING goods. Every counter is a world.ts NAMED_SHOPKEEPERS entry keyed by name. The profit-loop rule holds
|
|
8
|
+
* across all counters (no counter buys a line for more than any counter sells it for): buy-backs are the universal rates already in the game
|
|
9
|
+
* (Trader Joe's table, the Northern Gate Stores' silver and gold, Saul's fish) or a tenth of the counter price (bows).
|
|
10
|
+
* Armour and weapon prices are a placeholder formula (bars x a per-metal unit) for the balance pass; nobody buys that gear back.
|
|
11
|
+
* - A HARBOUR FISHING ERRAND, A Catch for the Galley (the Ship's Chandler Jory Tolliver, Fishing 14): three fixed tide snapper spots off the
|
|
12
|
+
* east end of the Royal Pier (the existing fish, the small rod and crab meat the chandler sells or hands over).
|
|
13
|
+
* - THE WALL ALARM: a night set piece on the north ring road. A clock-read window (UTC night hours, ten minutes in every thirty) in which a
|
|
14
|
+
* small scaled stream of prowlers climbs the wall. Nothing is rolled or stored: the window is read off the clock, so a restart or a second
|
|
15
|
+
* server agrees. Every number is a PLACEHOLDER for the balance pass.
|
|
16
|
+
*
|
|
17
|
+
* Imports only erased types from storyQuests.ts, so storyQuests.ts can spread CAPITAL_SHOP_QUESTS with no cycle.
|
|
18
|
+
*/
|
|
19
|
+
import type { StoryQuestDef } from './storyQuests.js';
|
|
20
|
+
/** What one bar of each metal counts for at the armourer's and the weaponsmith's counters (PLACEHOLDER, balance pass). John's Armoury sells poplar at 1200-2200. */
|
|
21
|
+
export declare const CAPITAL_BAR_UNIT_PRICE: Readonly<Record<'bronzebar' | 'ironbar' | 'steelbar', number>>;
|
|
22
|
+
/** The counter price of a forged piece: the bars it takes times the metal's unit price (wood is not counted), or 0 for a piece with no such recipe. */
|
|
23
|
+
export declare function capitalForgedPrice(output: string): number;
|
|
24
|
+
/** The role the client dresses a Capital person by (the id prefix `capital-<role>-`). The chandler is a docker; everyone else is city folk. */
|
|
25
|
+
export type CapitalShopRole = 'folk' | 'docker';
|
|
26
|
+
export type CapitalShopLine = {
|
|
27
|
+
readonly kind: string;
|
|
28
|
+
readonly price: number;
|
|
29
|
+
};
|
|
30
|
+
export type CapitalShopFolk = {
|
|
31
|
+
readonly key: string;
|
|
32
|
+
readonly name: string;
|
|
33
|
+
readonly role: CapitalShopRole;
|
|
34
|
+
/** Where they stand (world tiles) and what they face. */
|
|
35
|
+
readonly x: number;
|
|
36
|
+
readonly z: number;
|
|
37
|
+
readonly faceX: number;
|
|
38
|
+
readonly faceZ: number;
|
|
39
|
+
/** The plan's NPC spot id they stand on, or '' for the chandler (the harbour has none). */
|
|
40
|
+
readonly spotId: string;
|
|
41
|
+
/** For the guide: where the counter is. */
|
|
42
|
+
readonly place: string;
|
|
43
|
+
readonly shopTitle: string;
|
|
44
|
+
readonly stock: ReadonlyArray<CapitalShopLine>;
|
|
45
|
+
/** What the counter buys back. */
|
|
46
|
+
readonly buys: Readonly<Record<string, number>>;
|
|
47
|
+
/** The general store buys what Trader Joe buys, at his rates (the backend spreads its own table in: the types do not hold it). */
|
|
48
|
+
readonly buysLikeTrader?: true;
|
|
49
|
+
/** The Speak line, and the line for the Trade option (the client's menu). */
|
|
50
|
+
readonly speak: string;
|
|
51
|
+
readonly trade: string;
|
|
52
|
+
};
|
|
53
|
+
export declare const CAPITAL_SHOP_NAMES: {
|
|
54
|
+
readonly store: "Storekeeper Wilm Ardent";
|
|
55
|
+
readonly armourer: "Armourer Berta Stonewell";
|
|
56
|
+
readonly weaponsmith: "Weaponsmith Ivo Draymark";
|
|
57
|
+
readonly fletcher: "Fletcher Linnet Swift";
|
|
58
|
+
readonly apothecary: "Apothecary Sorrel Quince";
|
|
59
|
+
readonly baker: "Baker Maud Pennick";
|
|
60
|
+
readonly assayer: "Assayer Joren Marchant";
|
|
61
|
+
readonly chandler: "Ship's Chandler Jory Tolliver";
|
|
62
|
+
};
|
|
63
|
+
/** The Ship's Chandler stands inside the chandler's shop on the Harbour Road (types harbour.ts `chandler`, door at 784,168), two tiles in from the door. */
|
|
64
|
+
export declare const CAPITAL_CHANDLER_AT: {
|
|
65
|
+
readonly x: 786;
|
|
66
|
+
readonly z: 170;
|
|
67
|
+
};
|
|
68
|
+
/** The mini potions the apothecary keeps (a stat boost for a quarter of an hour; the full ones are for the brewer). PLACEHOLDER price. */
|
|
69
|
+
export declare const CAPITAL_MINI_POTION_KINDS: readonly string[];
|
|
70
|
+
export declare const CAPITAL_MINI_POTION_PRICE = 350;
|
|
71
|
+
export declare const CAPITAL_SHOP_FOLK: ReadonlyArray<CapitalShopFolk>;
|
|
72
|
+
export declare function capitalShopFolkByName(name: string | undefined): CapitalShopFolk | null;
|
|
73
|
+
/** Fixed tide snapper spots: three water tiles two north of the Royal Pier's boards, east of the royal-north ship's hull (x 830-846). */
|
|
74
|
+
export declare const CAPITAL_HARBOUR_FISH_SPOTS: ReadonlyArray<{
|
|
75
|
+
x: number;
|
|
76
|
+
z: number;
|
|
77
|
+
}>;
|
|
78
|
+
export declare const CAPITAL_SHOP_QUEST_IDS: readonly ["catchForTheGalley"];
|
|
79
|
+
export type CapitalShopQuestId = (typeof CAPITAL_SHOP_QUEST_IDS)[number];
|
|
80
|
+
export declare const CATCH_FOR_GALLEY_FISHING = 14;
|
|
81
|
+
export declare const CATCH_FOR_GALLEY_FISH = 5;
|
|
82
|
+
export declare const CATCH_FOR_GALLEY_QUEST: StoryQuestDef;
|
|
83
|
+
export declare const CAPITAL_SHOP_QUESTS: Readonly<Record<CapitalShopQuestId, StoryQuestDef>>;
|
|
84
|
+
export declare const CAPITAL_SHOP_QUEST_META: Readonly<Record<CapitalShopQuestId, {
|
|
85
|
+
title: string;
|
|
86
|
+
description: string;
|
|
87
|
+
category: 'combat' | 'side' | 'skilling' | 'exploration';
|
|
88
|
+
art: {
|
|
89
|
+
item: string;
|
|
90
|
+
} | {
|
|
91
|
+
npc: string;
|
|
92
|
+
};
|
|
93
|
+
}>>;
|
|
94
|
+
export declare const CAPITAL_SHOP_QUEST_GIVER_PLACES: Readonly<Record<CapitalShopQuestId, string>>;
|
|
95
|
+
export declare const WALL_ALARM_NAME = "The Wall Alarm";
|
|
96
|
+
/** UTC hours in which the alarm may sound (the night watch's hours). */
|
|
97
|
+
export declare const WALL_ALARM_HOURS_UTC: readonly number[];
|
|
98
|
+
/** A slot is thirty minutes; the alarm sounds for the first ten of a night slot. */
|
|
99
|
+
export declare const WALL_ALARM_SLOT_MS: number;
|
|
100
|
+
export declare const WALL_ALARM_LENGTH_MS: number;
|
|
101
|
+
/** Where it happens: the north stretch of the ring road, inside the wall (the Wall Walk's north-west and north-east corner posts bound it). */
|
|
102
|
+
export declare const WALL_ALARM_AREA: {
|
|
103
|
+
readonly minX: 489;
|
|
104
|
+
readonly maxX: 751;
|
|
105
|
+
readonly minZ: 85;
|
|
106
|
+
readonly maxZ: 91;
|
|
107
|
+
};
|
|
108
|
+
export declare function inWallAlarmArea(x: number, z: number): boolean;
|
|
109
|
+
/** The prowlers: cutthroats (the Lost Seal's own thieves), scaled to whoever stands on the wall. */
|
|
110
|
+
export declare const WALL_ALARM_STREAM: {
|
|
111
|
+
readonly kind: "cutthroat";
|
|
112
|
+
readonly name: "Wall prowler";
|
|
113
|
+
readonly levels: [number, number];
|
|
114
|
+
readonly cap: 3;
|
|
115
|
+
readonly perExtraPlayer: 1;
|
|
116
|
+
readonly everyMs: 10000;
|
|
117
|
+
readonly firstWave: 2;
|
|
118
|
+
/** Prowlers ignore anyone below this Combat. */
|
|
119
|
+
readonly aggroCombat: 10;
|
|
120
|
+
readonly aggroRadius: 6;
|
|
121
|
+
readonly leashRadius: 30;
|
|
122
|
+
readonly aggroText: "A prowler drops over the parapet and comes at you!";
|
|
123
|
+
};
|
|
124
|
+
export declare const WALL_ALARM_DIFFICULTY = 1;
|
|
125
|
+
/** Where they come over the wall: three points on the ring road's north side, clear of the corner posts (standable, checked by the backend smoke). */
|
|
126
|
+
export declare const WALL_ALARM_NESTS: ReadonlyArray<{
|
|
127
|
+
x: number;
|
|
128
|
+
z: number;
|
|
129
|
+
}>;
|
|
130
|
+
/** Prowlers felled, in one alarm, that earn the watch's pay; paid when the window closes to those still standing. */
|
|
131
|
+
export declare const WALL_ALARM_KILLS_TO_PAY = 3;
|
|
132
|
+
export declare const WALL_ALARM_REWARD: {
|
|
133
|
+
readonly coins: 150;
|
|
134
|
+
readonly explorerXp: 250;
|
|
135
|
+
};
|
|
136
|
+
/** At most this many paid alarms per account per UTC day (kept in memory: a restart resets it). */
|
|
137
|
+
export declare const WALL_ALARM_PAID_PER_DAY = 6;
|
|
138
|
+
export declare const WALL_ALARM_DIFFICULTY_NOTE = "placeholder numbers for the balance pass";
|
|
139
|
+
export declare const WALL_ALARM_TEXTS: {
|
|
140
|
+
readonly start: "The alarm bell rings from the Great Gate: prowlers are coming over the north wall! Hold the ring road until the bell stops.";
|
|
141
|
+
readonly quiet: "The alarm bell rings, but the prowlers have no interest in someone so green. Keep to the middle of the road.";
|
|
142
|
+
readonly endPaid: "The bell stops and the watch clears the last prowlers. The Guard thanks you for standing your ground.";
|
|
143
|
+
readonly endPlain: "The bell stops and the watch clears the last prowlers.";
|
|
144
|
+
/** To a player on the wall just before a window opens. */
|
|
145
|
+
readonly warn: "The watch is mustering: the alarm bell will ring on the north wall within the minute.";
|
|
146
|
+
};
|
|
147
|
+
export type WallAlarmWindow = {
|
|
148
|
+
/** Which half hour this is (counted from the Unix epoch). */
|
|
149
|
+
slot: number;
|
|
150
|
+
startMs: number;
|
|
151
|
+
/** When the alarm ends (startMs + the length) if it sounds in this slot. */
|
|
152
|
+
endMs: number;
|
|
153
|
+
/** True when the alarm is sounding at `nowMs`. */
|
|
154
|
+
active: boolean;
|
|
155
|
+
/** The start of the next alarm at or after `nowMs` (this one's when it is sounding). */
|
|
156
|
+
nextStartMs: number;
|
|
157
|
+
};
|
|
158
|
+
/** The alarm window at `nowMs`: read off the clock, never rolled or stored, so a restart or a second server agrees. */
|
|
159
|
+
export declare function wallAlarmWindow(nowMs: number): WallAlarmWindow;
|
|
160
|
+
//# sourceMappingURL=capitalShops.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capitalShops.d.ts","sourceRoot":"","sources":["../src/capitalShops.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import { CAPITAL_NPC_SPOTS } from './capital.js';
|
|
2
|
+
import { BLACKSMITH_RECIPES } from './blacksmithing.js';
|
|
3
|
+
import { INN_BREAD_PRICE } from './tavern.js';
|
|
4
|
+
import { TIDE_SNAPPER_PRICES } from './tideSnapper.js';
|
|
5
|
+
import { EMPTY_VIAL_BUY_PRICE, PESTLE_AND_MORTAR_PRICE, VIAL_OF_WATER_PRICE } from './potionMaking.js';
|
|
6
|
+
// ---- Prices ----------------------------------------------------------------------------------------------------------------------------
|
|
7
|
+
/** What one bar of each metal counts for at the armourer's and the weaponsmith's counters (PLACEHOLDER, balance pass). John's Armoury sells poplar at 1200-2200. */
|
|
8
|
+
export const CAPITAL_BAR_UNIT_PRICE = {
|
|
9
|
+
bronzebar: 600,
|
|
10
|
+
ironbar: 1500,
|
|
11
|
+
steelbar: 3200,
|
|
12
|
+
};
|
|
13
|
+
/** The counter price of a forged piece: the bars it takes times the metal's unit price (wood is not counted), or 0 for a piece with no such recipe. */
|
|
14
|
+
export function capitalForgedPrice(output) {
|
|
15
|
+
const recipe = BLACKSMITH_RECIPES.find((r) => r.output === output && r.station === 'anvil');
|
|
16
|
+
if (!recipe)
|
|
17
|
+
return 0;
|
|
18
|
+
let total = 0;
|
|
19
|
+
for (const m of recipe.materials) {
|
|
20
|
+
const unit = CAPITAL_BAR_UNIT_PRICE[m.kind];
|
|
21
|
+
if (unit)
|
|
22
|
+
total += unit * m.qty;
|
|
23
|
+
}
|
|
24
|
+
return total;
|
|
25
|
+
}
|
|
26
|
+
const ARMOUR_PIECES = ['shield', 'helmet', 'gauntlets', 'boots', 'legs', 'body'];
|
|
27
|
+
const WEAPON_PIECES = ['dagger', 'sword'];
|
|
28
|
+
function spot(id) {
|
|
29
|
+
const s = CAPITAL_NPC_SPOTS.find((row) => row.id === id);
|
|
30
|
+
if (!s)
|
|
31
|
+
throw new Error(`capitalShops: no NPC spot ${id}`);
|
|
32
|
+
return { x: s.x, z: s.z };
|
|
33
|
+
}
|
|
34
|
+
const on = (id) => ({ ...spot(id), spotId: id });
|
|
35
|
+
export const CAPITAL_SHOP_NAMES = {
|
|
36
|
+
store: 'Storekeeper Wilm Ardent',
|
|
37
|
+
armourer: 'Armourer Berta Stonewell',
|
|
38
|
+
weaponsmith: 'Weaponsmith Ivo Draymark',
|
|
39
|
+
fletcher: 'Fletcher Linnet Swift',
|
|
40
|
+
apothecary: 'Apothecary Sorrel Quince',
|
|
41
|
+
baker: 'Baker Maud Pennick',
|
|
42
|
+
assayer: 'Assayer Joren Marchant',
|
|
43
|
+
chandler: 'Ship\'s Chandler Jory Tolliver',
|
|
44
|
+
};
|
|
45
|
+
/** The Ship's Chandler stands inside the chandler's shop on the Harbour Road (types harbour.ts `chandler`, door at 784,168), two tiles in from the door. */
|
|
46
|
+
export const CAPITAL_CHANDLER_AT = { x: 786, z: 170 };
|
|
47
|
+
const forged = (prefix, pieces) => pieces.map((p) => ({ kind: `${prefix}${p}`, price: capitalForgedPrice(`${prefix}${p}`) }));
|
|
48
|
+
const BOWS = [
|
|
49
|
+
{ kind: 'birchshortbow', price: 150 },
|
|
50
|
+
{ kind: 'pinebow', price: 750 },
|
|
51
|
+
{ kind: 'sprucebow', price: 1800 },
|
|
52
|
+
{ kind: 'ashbow', price: 3600 },
|
|
53
|
+
{ kind: 'oakbow', price: 7000 },
|
|
54
|
+
];
|
|
55
|
+
const ARROWS = [
|
|
56
|
+
{ kind: 'bircharrow', price: 20 },
|
|
57
|
+
{ kind: 'sprucearrow', price: 45 },
|
|
58
|
+
];
|
|
59
|
+
/** The mini potions the apothecary keeps (a stat boost for a quarter of an hour; the full ones are for the brewer). PLACEHOLDER price. */
|
|
60
|
+
export const CAPITAL_MINI_POTION_KINDS = [
|
|
61
|
+
'ministrengthpotion',
|
|
62
|
+
'miniarcherypotion',
|
|
63
|
+
'miniweaponmasterypotion',
|
|
64
|
+
'minifishingpotion',
|
|
65
|
+
'minicookingpotion',
|
|
66
|
+
'miniforagingpotion',
|
|
67
|
+
'miniwoodworkpotion',
|
|
68
|
+
'miniexplorerpotion',
|
|
69
|
+
];
|
|
70
|
+
export const CAPITAL_MINI_POTION_PRICE = 350;
|
|
71
|
+
export const CAPITAL_SHOP_FOLK = [
|
|
72
|
+
{
|
|
73
|
+
key: 'store',
|
|
74
|
+
name: CAPITAL_SHOP_NAMES.store,
|
|
75
|
+
role: 'folk',
|
|
76
|
+
...on('storekeeper'),
|
|
77
|
+
faceX: spot('storekeeper').x,
|
|
78
|
+
faceZ: spot('storekeeper').z + 3,
|
|
79
|
+
place: 'the general store on the Royal Way\'s west side, near the Gate Square',
|
|
80
|
+
shopTitle: "Ardent's General Store",
|
|
81
|
+
stock: [
|
|
82
|
+
{ kind: 'cookedchicken', price: 50 },
|
|
83
|
+
{ kind: 'apple', price: 5 },
|
|
84
|
+
{ kind: 'wheat', price: 5 },
|
|
85
|
+
{ kind: 'grapes', price: 5 },
|
|
86
|
+
{ kind: 'orange', price: 5 },
|
|
87
|
+
{ kind: 'copperpickaxe', price: 60 },
|
|
88
|
+
{ kind: 'bucket', price: 10 },
|
|
89
|
+
{ kind: 'foldingsaw', price: 30 },
|
|
90
|
+
{ kind: 'carvingknife', price: 50 },
|
|
91
|
+
{ kind: 'unlitbirchtorch', price: 12 },
|
|
92
|
+
],
|
|
93
|
+
buys: {},
|
|
94
|
+
buysLikeTrader: true,
|
|
95
|
+
speak: "Wilm Ardent. Rope, rations and the odd thing you did not know you needed. I buy what the roads give you, at Trader Joe's rates, so you need not walk home to sell it.",
|
|
96
|
+
trade: "Rations, tools and a torch for the dark. I pay the same for your finds as Trader Joe does on the coast, no more and no less, and I do not haggle.",
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
key: 'armourer',
|
|
100
|
+
name: CAPITAL_SHOP_NAMES.armourer,
|
|
101
|
+
role: 'folk',
|
|
102
|
+
...on('armourer'),
|
|
103
|
+
faceX: spot('armourer').x,
|
|
104
|
+
faceZ: spot('armourer').z + 3,
|
|
105
|
+
place: 'the Armourer\'s in the Forge and Artisan Quarter',
|
|
106
|
+
shopTitle: "Stonewell's Armoury",
|
|
107
|
+
stock: [...forged('bronze', ARMOUR_PIECES), ...forged('iron', ARMOUR_PIECES), ...forged('steel', ARMOUR_PIECES), { kind: 'steeltowershield', price: capitalForgedPrice('steeltowershield') }],
|
|
108
|
+
buys: {},
|
|
109
|
+
speak: "Berta Stonewell, armourer. Bronze for beginners, iron for people who have been hit, steel for people who mean to go on being hit. Every piece is forged here, the slow way.",
|
|
110
|
+
trade: "Bronze, iron and steel, finished and fitted. If you would rather make your own, the anvils on Anvil Square are free. I charge for my time, and for the bars.",
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
key: 'weaponsmith',
|
|
114
|
+
name: CAPITAL_SHOP_NAMES.weaponsmith,
|
|
115
|
+
role: 'folk',
|
|
116
|
+
...on('forge-master'),
|
|
117
|
+
faceX: spot('forge-master').x,
|
|
118
|
+
faceZ: spot('forge-master').z + 3,
|
|
119
|
+
place: 'the weaponsmith\'s stall in the Forge and Artisan Quarter',
|
|
120
|
+
shopTitle: "Draymark's Blades",
|
|
121
|
+
stock: [
|
|
122
|
+
...forged('bronze', WEAPON_PIECES),
|
|
123
|
+
...forged('iron', [...WEAPON_PIECES, 'longsword']),
|
|
124
|
+
...forged('steel', [...WEAPON_PIECES, 'longsword', 'mace', 'battleaxe']),
|
|
125
|
+
],
|
|
126
|
+
buys: {},
|
|
127
|
+
speak: "Ivo Draymark. Daggers for the quick, swords for the sensible, and a battleaxe for anyone who has stopped being either. Mind the edge.",
|
|
128
|
+
trade: "Bronze to steel, every blade balanced on my own bench. Silver I leave to the Forge Master, who has opinions about the dead.",
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
key: 'fletcher',
|
|
132
|
+
name: CAPITAL_SHOP_NAMES.fletcher,
|
|
133
|
+
role: 'folk',
|
|
134
|
+
...on('ranger'),
|
|
135
|
+
faceX: spot('ranger').x,
|
|
136
|
+
faceZ: spot('ranger').z + 3,
|
|
137
|
+
place: 'the fletcher\'s on the Royal Way, south-west of the Westgate Outpost',
|
|
138
|
+
shopTitle: "Swift's Bows and Arrows",
|
|
139
|
+
stock: [...BOWS, ...ARROWS],
|
|
140
|
+
buys: Object.fromEntries([...BOWS, ...ARROWS].map((l) => [l.kind, Math.round(l.price / 10)]).concat([['feather', 1]])),
|
|
141
|
+
speak: "Linnet Swift. Birch to start, pine to learn on, then spruce, ash and oak when your arm has earned them. I buy a bow back at a tenth, because I have to eat too.",
|
|
142
|
+
trade: "Every bow from birch to oak, and arrows by the dozen. Bring your own bows and I will give you a tenth for them, which is more than the crows will.",
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
key: 'apothecary',
|
|
146
|
+
name: CAPITAL_SHOP_NAMES.apothecary,
|
|
147
|
+
role: 'folk',
|
|
148
|
+
...on('alchemist'),
|
|
149
|
+
faceX: spot('alchemist').x,
|
|
150
|
+
faceZ: spot('alchemist').z + 3,
|
|
151
|
+
place: 'the Alchemy Hut in the Forge and Artisan Quarter',
|
|
152
|
+
shopTitle: "Quince's Apothecary",
|
|
153
|
+
stock: [
|
|
154
|
+
{ kind: 'vialofwater', price: VIAL_OF_WATER_PRICE },
|
|
155
|
+
{ kind: 'pestleandmortar', price: PESTLE_AND_MORTAR_PRICE },
|
|
156
|
+
...CAPITAL_MINI_POTION_KINDS.map((kind) => ({ kind, price: CAPITAL_MINI_POTION_PRICE })),
|
|
157
|
+
],
|
|
158
|
+
buys: { emptyvial: EMPTY_VIAL_BUY_PRICE },
|
|
159
|
+
speak: "Sorrel Quince. The cauldron in the corner is free to anyone with the herbs and the patience. If you have neither, I sell the small brews ready made.",
|
|
160
|
+
trade: "Vials for your own brewing, and the small potions ready made for those who would rather not wait. The big ones I leave to the people who make them.",
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
key: 'baker',
|
|
164
|
+
name: CAPITAL_SHOP_NAMES.baker,
|
|
165
|
+
role: 'folk',
|
|
166
|
+
...on('cloth-keeper'),
|
|
167
|
+
faceX: spot('cloth-keeper').x,
|
|
168
|
+
faceZ: spot('cloth-keeper').z + 3,
|
|
169
|
+
place: 'the baker\'s stall in Market Square',
|
|
170
|
+
shopTitle: "Pennick's Bakehouse",
|
|
171
|
+
stock: [
|
|
172
|
+
{ kind: 'bread', price: INN_BREAD_PRICE },
|
|
173
|
+
{ kind: 'flour', price: 6 },
|
|
174
|
+
{ kind: 'cookedrabbit', price: 30 },
|
|
175
|
+
{ kind: 'cookedtrout', price: 40 },
|
|
176
|
+
{ kind: 'cookedchar', price: 46 },
|
|
177
|
+
{ kind: 'cookedchicken', price: 50 },
|
|
178
|
+
{ kind: 'cookedsalmon', price: 65 },
|
|
179
|
+
],
|
|
180
|
+
buys: { wheat: 3, flour: 3, bread: 8 },
|
|
181
|
+
speak: "Maud Pennick. Bread at dawn, pies when I can spare the flour, and the cook-off judges leave me their crusts. Warm hands, honest weight.",
|
|
182
|
+
trade: "Bread and flour from my own oven, and cooked fish and fowl for the road. Wheat and flour I take at the miller's rate, and the day-old loaves too.",
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
key: 'assayer',
|
|
186
|
+
name: CAPITAL_SHOP_NAMES.assayer,
|
|
187
|
+
role: 'folk',
|
|
188
|
+
...on('exchange-clerk'),
|
|
189
|
+
faceX: spot('exchange-clerk').x,
|
|
190
|
+
faceZ: spot('exchange-clerk').z + 3,
|
|
191
|
+
place: 'the counting house of the Trade District, beside Coin Square',
|
|
192
|
+
shopTitle: "Marchant's Assay Counter",
|
|
193
|
+
stock: [],
|
|
194
|
+
buys: { silver: 30, silverbar: 75, gold: 45, goldbar: 110, coal: 12, gem: 2500 },
|
|
195
|
+
speak: "Joren Marchant, assayer to the Trade District's counting house. I weigh metal, I do not sell it. Bring gold and silver, ore or bar, and I will pay the counting house's honest rate.",
|
|
196
|
+
trade: "Silver and gold, ore and bars, coal for the furnaces and the rare gem. The rates are the counting house's, the same at every counter in the kingdom, and I will not move them for a smile.",
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
key: 'chandler',
|
|
200
|
+
name: CAPITAL_SHOP_NAMES.chandler,
|
|
201
|
+
role: 'docker',
|
|
202
|
+
x: CAPITAL_CHANDLER_AT.x,
|
|
203
|
+
z: CAPITAL_CHANDLER_AT.z,
|
|
204
|
+
spotId: '',
|
|
205
|
+
faceX: 784,
|
|
206
|
+
faceZ: 168,
|
|
207
|
+
place: 'the Chandler\'s on the Harbour Road, south of the road in the King\'s Harbour',
|
|
208
|
+
shopTitle: "Tolliver's Ship Chandlery",
|
|
209
|
+
stock: [
|
|
210
|
+
{ kind: 'smallfishingrod', price: 200 },
|
|
211
|
+
{ kind: 'fishingline', price: 15 },
|
|
212
|
+
{ kind: 'fishinghook', price: 10 },
|
|
213
|
+
{ kind: 'fishingfloat', price: 8 },
|
|
214
|
+
{ kind: 'crabcage', price: 20 },
|
|
215
|
+
],
|
|
216
|
+
buys: {
|
|
217
|
+
rawtidesnapper: TIDE_SNAPPER_PRICES.rawtidesnapper,
|
|
218
|
+
cookedtidesnapper: TIDE_SNAPPER_PRICES.cookedtidesnapper,
|
|
219
|
+
rawconger: 22,
|
|
220
|
+
cookedconger: 40,
|
|
221
|
+
rawbass: 30,
|
|
222
|
+
cookedbass: 55,
|
|
223
|
+
crabmeat: 5,
|
|
224
|
+
cookedcrab: 8,
|
|
225
|
+
},
|
|
226
|
+
speak: "Jory Tolliver. Rope, hooks, floats and a bit of everything a hull might want. The tide snapper run off the east end of the Royal Pier, if you have a rod and the patience.",
|
|
227
|
+
trade: "Tackle for the pier, and I buy the catch: snapper, conger, bass and crab, at the prices the harbour has always paid.",
|
|
228
|
+
},
|
|
229
|
+
];
|
|
230
|
+
export function capitalShopFolkByName(name) {
|
|
231
|
+
return name ? CAPITAL_SHOP_FOLK.find((f) => f.name === name) ?? null : null;
|
|
232
|
+
}
|
|
233
|
+
// ---- The harbour fishing errand -----------------------------------------------------------------------------------------------------------
|
|
234
|
+
/** Fixed tide snapper spots: three water tiles two north of the Royal Pier's boards, east of the royal-north ship's hull (x 830-846). */
|
|
235
|
+
export const CAPITAL_HARBOUR_FISH_SPOTS = [
|
|
236
|
+
{ x: 849, z: 155 },
|
|
237
|
+
{ x: 851, z: 155 },
|
|
238
|
+
{ x: 853, z: 155 },
|
|
239
|
+
];
|
|
240
|
+
export const CAPITAL_SHOP_QUEST_IDS = ['catchForTheGalley'];
|
|
241
|
+
export const CATCH_FOR_GALLEY_FISHING = 14;
|
|
242
|
+
export const CATCH_FOR_GALLEY_FISH = 5;
|
|
243
|
+
const CHANDLER = { kind: 'resident', name: CAPITAL_SHOP_NAMES.chandler };
|
|
244
|
+
export const CATCH_FOR_GALLEY_QUEST = {
|
|
245
|
+
giver: CHANDLER,
|
|
246
|
+
requires: {
|
|
247
|
+
skill: { skill: 'fishing', level: CATCH_FOR_GALLEY_FISHING },
|
|
248
|
+
refuse: `The pier's snapper want a steady hand (Fishing ${CATCH_FOR_GALLEY_FISHING}). Come back when you can land one.`,
|
|
249
|
+
},
|
|
250
|
+
offer: "The galley of the royal ship has no fresh fish and the cook has threatened to quit. Five tide snapper off the east end of the Royal Pier would settle him. I will lend you a rod and crab meat for bait, and pay for the catch.",
|
|
251
|
+
accept: "Walk out along the Royal Pier to its east end. The snapper rise in the water just north of the boards. Cast, wait, and bring me five.",
|
|
252
|
+
decline: 'Then the cook will keep shouting, and I shall keep ducking.',
|
|
253
|
+
onAccept: [
|
|
254
|
+
{ kind: 'smallfishingrod', qty: 1, ifMissing: true },
|
|
255
|
+
{ kind: 'crabmeat', qty: 8 },
|
|
256
|
+
],
|
|
257
|
+
steps: [
|
|
258
|
+
{
|
|
259
|
+
kind: 'catch',
|
|
260
|
+
fish: ['rawtidesnapper'],
|
|
261
|
+
qty: CATCH_FOR_GALLEY_FISH,
|
|
262
|
+
label: `Catch ${CATCH_FOR_GALLEY_FISH} tide snapper off the Royal Pier`,
|
|
263
|
+
hint: 'Walk out along the Royal Pier to its east end and cast into the water north of the boards, with the small rod and a piece of crab meat.',
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
kind: 'deliver',
|
|
267
|
+
npc: CHANDLER,
|
|
268
|
+
items: [{ kinds: ['rawtidesnapper'], qty: CATCH_FOR_GALLEY_FISH, label: 'Tide snapper' }],
|
|
269
|
+
label: "Bring the catch to Ship's Chandler Jory Tolliver",
|
|
270
|
+
hint: "The Chandler's shop is on the Harbour Road, south of the road; he stands inside, two tiles in from the door.",
|
|
271
|
+
say: "Five good snapper, and still wriggling in my mind's eye. The galley eats well tonight. Take this, and the pier is yours whenever you like.",
|
|
272
|
+
short: 'Five tide snapper, and no fewer. The pier has plenty.',
|
|
273
|
+
},
|
|
274
|
+
],
|
|
275
|
+
done: "The cook is quiet and the captain is pleased, and between them that is a miracle. Here, for the catch.",
|
|
276
|
+
after: 'The pier is yours whenever the tide is kind. Mind the gulls.',
|
|
277
|
+
rewards: { coins: 400, xp: { fishing: 1500, explorer: 500 } },
|
|
278
|
+
};
|
|
279
|
+
export const CAPITAL_SHOP_QUESTS = {
|
|
280
|
+
catchForTheGalley: CATCH_FOR_GALLEY_QUEST,
|
|
281
|
+
};
|
|
282
|
+
export const CAPITAL_SHOP_QUEST_META = {
|
|
283
|
+
catchForTheGalley: {
|
|
284
|
+
title: 'A Catch for the Galley',
|
|
285
|
+
description: `Land ${CATCH_FOR_GALLEY_FISH} tide snapper from the east end of the Royal Pier for Ship's Chandler Jory Tolliver. He lends the rod and the bait. Needs Fishing ${CATCH_FOR_GALLEY_FISHING}.`,
|
|
286
|
+
category: 'skilling',
|
|
287
|
+
art: { item: 'rawtidesnapper' },
|
|
288
|
+
},
|
|
289
|
+
};
|
|
290
|
+
export const CAPITAL_SHOP_QUEST_GIVER_PLACES = {
|
|
291
|
+
catchForTheGalley: "Ship's Chandler Jory Tolliver keeps the Chandler's on the Harbour Road of the King's Harbour, outside the Capital's East Gate.",
|
|
292
|
+
};
|
|
293
|
+
// ---- The Wall Alarm (night set piece) ----------------------------------------------------------------------------------------------------
|
|
294
|
+
export const WALL_ALARM_NAME = 'The Wall Alarm';
|
|
295
|
+
/** UTC hours in which the alarm may sound (the night watch's hours). */
|
|
296
|
+
export const WALL_ALARM_HOURS_UTC = [20, 21, 22, 23, 0, 1, 2, 3];
|
|
297
|
+
/** A slot is thirty minutes; the alarm sounds for the first ten of a night slot. */
|
|
298
|
+
export const WALL_ALARM_SLOT_MS = 30 * 60_000;
|
|
299
|
+
export const WALL_ALARM_LENGTH_MS = 10 * 60_000;
|
|
300
|
+
/** Where it happens: the north stretch of the ring road, inside the wall (the Wall Walk's north-west and north-east corner posts bound it). */
|
|
301
|
+
export const WALL_ALARM_AREA = { minX: 489, maxX: 751, minZ: 85, maxZ: 91 };
|
|
302
|
+
export function inWallAlarmArea(x, z) {
|
|
303
|
+
return x >= WALL_ALARM_AREA.minX && x <= WALL_ALARM_AREA.maxX && z >= WALL_ALARM_AREA.minZ && z <= WALL_ALARM_AREA.maxZ;
|
|
304
|
+
}
|
|
305
|
+
/** The prowlers: cutthroats (the Lost Seal's own thieves), scaled to whoever stands on the wall. */
|
|
306
|
+
export const WALL_ALARM_STREAM = {
|
|
307
|
+
kind: 'cutthroat',
|
|
308
|
+
name: 'Wall prowler',
|
|
309
|
+
levels: [15, 35],
|
|
310
|
+
cap: 3,
|
|
311
|
+
perExtraPlayer: 1,
|
|
312
|
+
everyMs: 10_000,
|
|
313
|
+
firstWave: 2,
|
|
314
|
+
/** Prowlers ignore anyone below this Combat. */
|
|
315
|
+
aggroCombat: 10,
|
|
316
|
+
aggroRadius: 6,
|
|
317
|
+
leashRadius: 30,
|
|
318
|
+
aggroText: 'A prowler drops over the parapet and comes at you!',
|
|
319
|
+
};
|
|
320
|
+
export const WALL_ALARM_DIFFICULTY = 1;
|
|
321
|
+
/** Where they come over the wall: three points on the ring road's north side, clear of the corner posts (standable, checked by the backend smoke). */
|
|
322
|
+
export const WALL_ALARM_NESTS = [
|
|
323
|
+
{ x: 560, z: 88 },
|
|
324
|
+
{ x: 620, z: 88 },
|
|
325
|
+
{ x: 680, z: 88 },
|
|
326
|
+
];
|
|
327
|
+
/** Prowlers felled, in one alarm, that earn the watch's pay; paid when the window closes to those still standing. */
|
|
328
|
+
export const WALL_ALARM_KILLS_TO_PAY = 3;
|
|
329
|
+
export const WALL_ALARM_REWARD = { coins: 150, explorerXp: 250 };
|
|
330
|
+
/** At most this many paid alarms per account per UTC day (kept in memory: a restart resets it). */
|
|
331
|
+
export const WALL_ALARM_PAID_PER_DAY = 6;
|
|
332
|
+
export const WALL_ALARM_DIFFICULTY_NOTE = 'placeholder numbers for the balance pass';
|
|
333
|
+
export const WALL_ALARM_TEXTS = {
|
|
334
|
+
start: 'The alarm bell rings from the Great Gate: prowlers are coming over the north wall! Hold the ring road until the bell stops.',
|
|
335
|
+
quiet: 'The alarm bell rings, but the prowlers have no interest in someone so green. Keep to the middle of the road.',
|
|
336
|
+
endPaid: 'The bell stops and the watch clears the last prowlers. The Guard thanks you for standing your ground.',
|
|
337
|
+
endPlain: 'The bell stops and the watch clears the last prowlers.',
|
|
338
|
+
/** To a player on the wall just before a window opens. */
|
|
339
|
+
warn: 'The watch is mustering: the alarm bell will ring on the north wall within the minute.',
|
|
340
|
+
};
|
|
341
|
+
function slotSounds(slot) {
|
|
342
|
+
const hour = new Date(slot * WALL_ALARM_SLOT_MS).getUTCHours();
|
|
343
|
+
return WALL_ALARM_HOURS_UTC.includes(hour);
|
|
344
|
+
}
|
|
345
|
+
/** The alarm window at `nowMs`: read off the clock, never rolled or stored, so a restart or a second server agrees. */
|
|
346
|
+
export function wallAlarmWindow(nowMs) {
|
|
347
|
+
const slot = Math.floor(nowMs / WALL_ALARM_SLOT_MS);
|
|
348
|
+
const startMs = slot * WALL_ALARM_SLOT_MS;
|
|
349
|
+
const endMs = startMs + WALL_ALARM_LENGTH_MS;
|
|
350
|
+
const active = slotSounds(slot) && nowMs < endMs;
|
|
351
|
+
let nextStartMs = startMs;
|
|
352
|
+
if (!active) {
|
|
353
|
+
let next = slot;
|
|
354
|
+
// A slot that has begun (and whose ten minutes are over) is behind us; look from the next one on.
|
|
355
|
+
if (startMs < nowMs || !slotSounds(next))
|
|
356
|
+
next = slot + 1;
|
|
357
|
+
while (!slotSounds(next))
|
|
358
|
+
next++;
|
|
359
|
+
nextStartMs = next * WALL_ALARM_SLOT_MS;
|
|
360
|
+
}
|
|
361
|
+
return { slot, startMs, endMs, active, nextStartMs };
|
|
362
|
+
}
|
|
363
|
+
//# sourceMappingURL=capitalShops.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capitalShops.js","sourceRoot":"","sources":["../src/capitalShops.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAEvG,2IAA2I;AAE3I,oKAAoK;AACpK,MAAM,CAAC,MAAM,sBAAsB,GAAmE;IACpG,SAAS,EAAE,GAAG;IACd,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,IAAI;CACf,CAAC;AAEF,uJAAuJ;AACvJ,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;IAC5F,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC;IACtB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACjC,MAAM,IAAI,GAAI,sBAA6D,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACpF,IAAI,IAAI;YAAE,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC;IAClC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,aAAa,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAU,CAAC;AAC1F,MAAM,aAAa,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAU,CAAC;AAiCnD,SAAS,IAAI,CAAC,EAAU;IACtB,MAAM,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACzD,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,EAAE,EAAE,CAAC,CAAC;IAC3D,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5B,CAAC;AACD,MAAM,EAAE,GAAG,CAAC,EAAU,EAA4C,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;AAEnG,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,KAAK,EAAE,yBAAyB;IAChC,QAAQ,EAAE,0BAA0B;IACpC,WAAW,EAAE,0BAA0B;IACvC,QAAQ,EAAE,uBAAuB;IACjC,UAAU,EAAE,0BAA0B;IACtC,KAAK,EAAE,oBAAoB;IAC3B,OAAO,EAAE,wBAAwB;IACjC,QAAQ,EAAE,gCAAgC;CAClC,CAAC;AAEX,4JAA4J;AAC5J,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAW,CAAC;AAE/D,MAAM,MAAM,GAAG,CAAC,MAAc,EAAE,MAAyB,EAAqB,EAAE,CAC9E,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,MAAM,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,kBAAkB,CAAC,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAE7F,MAAM,IAAI,GAAmC;IAC3C,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,GAAG,EAAE;IACrC,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE;IAC/B,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE;IAClC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE;IAC/B,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE;CAChC,CAAC;AACF,MAAM,MAAM,GAAmC;IAC7C,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,EAAE;IACjC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,EAAE;CACnC,CAAC;AAEF,0IAA0I;AAC1I,MAAM,CAAC,MAAM,yBAAyB,GAAsB;IAC1D,oBAAoB;IACpB,mBAAmB;IACnB,yBAAyB;IACzB,mBAAmB;IACnB,mBAAmB;IACnB,oBAAoB;IACpB,oBAAoB;IACpB,oBAAoB;CACrB,CAAC;AACF,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAE7C,MAAM,CAAC,MAAM,iBAAiB,GAAmC;IAC/D;QACE,GAAG,EAAE,OAAO;QACZ,IAAI,EAAE,kBAAkB,CAAC,KAAK;QAC9B,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,CAAC,aAAa,CAAC;QACpB,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;QAC5B,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC;QAChC,KAAK,EAAE,uEAAuE;QAC9E,SAAS,EAAE,wBAAwB;QACnC,KAAK,EAAE;YACL,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,EAAE;YACpC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE;YAC3B,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE;YAC3B,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE;YAC5B,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE;YAC5B,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,EAAE;YACpC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE;YAC7B,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,EAAE;YACjC,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE,EAAE;YACnC,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,EAAE,EAAE;SACvC;QACD,IAAI,EAAE,EAAE;QACR,cAAc,EAAE,IAAI;QACpB,KAAK,EAAE,uKAAuK;QAC9K,KAAK,EAAE,mJAAmJ;KAC3J;IACD;QACE,GAAG,EAAE,UAAU;QACf,IAAI,EAAE,kBAAkB,CAAC,QAAQ;QACjC,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,CAAC,UAAU,CAAC;QACjB,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QACzB,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;QAC7B,KAAK,EAAE,kDAAkD;QACzD,SAAS,EAAE,qBAAqB;QAChC,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,kBAAkB,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC7L,IAAI,EAAE,EAAE;QACR,KAAK,EAAE,6KAA6K;QACpL,KAAK,EAAE,8JAA8J;KACtK;IACD;QACE,GAAG,EAAE,aAAa;QAClB,IAAI,EAAE,kBAAkB,CAAC,WAAW;QACpC,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,CAAC,cAAc,CAAC;QACrB,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;QAC7B,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC;QACjC,KAAK,EAAE,2DAA2D;QAClE,SAAS,EAAE,mBAAmB;QAC9B,KAAK,EAAE;YACL,GAAG,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC;YAClC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,aAAa,EAAE,WAAW,CAAC,CAAC;YAClD,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,GAAG,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;SACzE;QACD,IAAI,EAAE,EAAE;QACR,KAAK,EAAE,uIAAuI;QAC9I,KAAK,EAAE,6HAA6H;KACrI;IACD;QACE,GAAG,EAAE,UAAU;QACf,IAAI,EAAE,kBAAkB,CAAC,QAAQ;QACjC,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,CAAC,QAAQ,CAAC;QACf,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QACvB,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC;QAC3B,KAAK,EAAE,sEAAsE;QAC7E,SAAS,EAAE,yBAAyB;QACpC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;QAC3B,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACtH,KAAK,EAAE,iKAAiK;QACxK,KAAK,EAAE,oJAAoJ;KAC5J;IACD;QACE,GAAG,EAAE,YAAY;QACjB,IAAI,EAAE,kBAAkB,CAAC,UAAU;QACnC,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,CAAC,WAAW,CAAC;QAClB,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;QAC1B,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC;QAC9B,KAAK,EAAE,kDAAkD;QACzD,SAAS,EAAE,qBAAqB;QAChC,KAAK,EAAE;YACL,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,mBAAmB,EAAE;YACnD,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,uBAAuB,EAAE;YAC3D,GAAG,yBAAyB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC,CAAC;SACzF;QACD,IAAI,EAAE,EAAE,SAAS,EAAE,oBAAoB,EAAE;QACzC,KAAK,EAAE,sJAAsJ;QAC7J,KAAK,EAAE,qJAAqJ;KAC7J;IACD;QACE,GAAG,EAAE,OAAO;QACZ,IAAI,EAAE,kBAAkB,CAAC,KAAK;QAC9B,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,CAAC,cAAc,CAAC;QACrB,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;QAC7B,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC;QACjC,KAAK,EAAE,qCAAqC;QAC5C,SAAS,EAAE,qBAAqB;QAChC,KAAK,EAAE;YACL,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE;YACzC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE;YAC3B,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE,EAAE;YACnC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,EAAE;YAClC,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,EAAE;YACjC,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,EAAE;YACpC,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE,EAAE;SACpC;QACD,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;QACtC,KAAK,EAAE,yIAAyI;QAChJ,KAAK,EAAE,mJAAmJ;KAC3J;IACD;QACE,GAAG,EAAE,SAAS;QACd,IAAI,EAAE,kBAAkB,CAAC,OAAO;QAChC,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,CAAC,gBAAgB,CAAC;QACvB,KAAK,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAC/B,KAAK,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC;QACnC,KAAK,EAAE,8DAA8D;QACrE,SAAS,EAAE,0BAA0B;QACrC,KAAK,EAAE,EAAE;QACT,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE;QAChF,KAAK,EAAE,sLAAsL;QAC7L,KAAK,EAAE,4LAA4L;KACpM;IACD;QACE,GAAG,EAAE,UAAU;QACf,IAAI,EAAE,kBAAkB,CAAC,QAAQ;QACjC,IAAI,EAAE,QAAQ;QACd,CAAC,EAAE,mBAAmB,CAAC,CAAC;QACxB,CAAC,EAAE,mBAAmB,CAAC,CAAC;QACxB,MAAM,EAAE,EAAE;QACV,KAAK,EAAE,GAAG;QACV,KAAK,EAAE,GAAG;QACV,KAAK,EAAE,+EAA+E;QACtF,SAAS,EAAE,2BAA2B;QACtC,KAAK,EAAE;YACL,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,GAAG,EAAE;YACvC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,EAAE;YAClC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,EAAE;YAClC,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE;YAClC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE;SAChC;QACD,IAAI,EAAE;YACJ,cAAc,EAAE,mBAAmB,CAAC,cAAc;YAClD,iBAAiB,EAAE,mBAAmB,CAAC,iBAAiB;YACxD,SAAS,EAAE,EAAE;YACb,YAAY,EAAE,EAAE;YAChB,OAAO,EAAE,EAAE;YACX,UAAU,EAAE,EAAE;YACd,QAAQ,EAAE,CAAC;YACX,UAAU,EAAE,CAAC;SACd;QACD,KAAK,EAAE,4KAA4K;QACnL,KAAK,EAAE,sHAAsH;KAC9H;CACF,CAAC;AAEF,MAAM,UAAU,qBAAqB,CAAC,IAAwB;IAC5D,OAAO,IAAI,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9E,CAAC;AAED,8IAA8I;AAE9I,yIAAyI;AACzI,MAAM,CAAC,MAAM,0BAA0B,GAA4C;IACjF,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE;IAClB,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE;IAClB,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE;CACnB,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,mBAAmB,CAAU,CAAC;AAGrE,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAC3C,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAEvC,MAAM,QAAQ,GAAgB,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,kBAAkB,CAAC,QAAQ,EAAE,CAAC;AAEtF,MAAM,CAAC,MAAM,sBAAsB,GAAkB;IACnD,KAAK,EAAE,QAAQ;IACf,QAAQ,EAAE;QACR,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,wBAAwB,EAAE;QAC5D,MAAM,EAAE,kDAAkD,wBAAwB,qCAAqC;KACxH;IACD,KAAK,EACH,iOAAiO;IACnO,MAAM,EACJ,uIAAuI;IACzI,OAAO,EAAE,6DAA6D;IACtE,QAAQ,EAAE;QACR,EAAE,IAAI,EAAE,iBAAiB,EAAE,GAAG,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE;QACpD,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,EAAE;KAC7B;IACD,KAAK,EAAE;QACL;YACE,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,CAAC,gBAAgB,CAAC;YACxB,GAAG,EAAE,qBAAqB;YAC1B,KAAK,EAAE,SAAS,qBAAqB,kCAAkC;YACvE,IAAI,EAAE,yIAAyI;SAChJ;QACD;YACE,IAAI,EAAE,SAAS;YACf,GAAG,EAAE,QAAQ;YACb,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,gBAAgB,CAAC,EAAE,GAAG,EAAE,qBAAqB,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;YACzF,KAAK,EAAE,kDAAkD;YACzD,IAAI,EAAE,8GAA8G;YACpH,GAAG,EAAE,4IAA4I;YACjJ,KAAK,EAAE,uDAAuD;SAC/D;KACF;IACD,IAAI,EAAE,wGAAwG;IAC9G,KAAK,EAAE,8DAA8D;IACrE,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE;CAC9D,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAwD;IACtF,iBAAiB,EAAE,sBAAsB;CAC1C,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAoL;IACtN,iBAAiB,EAAE;QACjB,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EAAE,QAAQ,qBAAqB,qIAAqI,wBAAwB,GAAG;QAC1M,QAAQ,EAAE,UAAU;QACpB,GAAG,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;KAChC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,+BAA+B,GAAiD;IAC3F,iBAAiB,EAAE,gIAAgI;CACpJ,CAAC;AAEF,6IAA6I;AAE7I,MAAM,CAAC,MAAM,eAAe,GAAG,gBAAgB,CAAC;AAChD,wEAAwE;AACxE,MAAM,CAAC,MAAM,oBAAoB,GAAsB,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACpF,oFAAoF;AACpF,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,GAAG,MAAM,CAAC;AAC9C,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,GAAG,MAAM,CAAC;AAChD,+IAA+I;AAC/I,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAW,CAAC;AACrF,MAAM,UAAU,eAAe,CAAC,CAAS,EAAE,CAAS;IAClD,OAAO,CAAC,IAAI,eAAe,CAAC,IAAI,IAAI,CAAC,IAAI,eAAe,CAAC,IAAI,IAAI,CAAC,IAAI,eAAe,CAAC,IAAI,IAAI,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC;AAC1H,CAAC;AACD,oGAAoG;AACpG,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,cAAc;IACpB,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAqB;IACpC,GAAG,EAAE,CAAC;IACN,cAAc,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM;IACf,SAAS,EAAE,CAAC;IACZ,gDAAgD;IAChD,WAAW,EAAE,EAAE;IACf,WAAW,EAAE,CAAC;IACd,WAAW,EAAE,EAAE;IACf,SAAS,EAAE,oDAAoD;CACvD,CAAC;AACX,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AACvC,sJAAsJ;AACtJ,MAAM,CAAC,MAAM,gBAAgB,GAA4C;IACvE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE;IACjB,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE;IACjB,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,EAAE;CAClB,CAAC;AACF,qHAAqH;AACrH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AACzC,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAW,CAAC;AAC1E,mGAAmG;AACnG,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AACzC,MAAM,CAAC,MAAM,0BAA0B,GAAG,0CAA0C,CAAC;AAErF,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,KAAK,EAAE,6HAA6H;IACpI,KAAK,EAAE,8GAA8G;IACrH,OAAO,EAAE,uGAAuG;IAChH,QAAQ,EAAE,wDAAwD;IAClE,0DAA0D;IAC1D,IAAI,EAAE,uFAAuF;CACrF,CAAC;AAcX,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/D,OAAO,oBAAoB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED,uHAAuH;AACvH,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,kBAAkB,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,IAAI,GAAG,kBAAkB,CAAC;IAC1C,MAAM,KAAK,GAAG,OAAO,GAAG,oBAAoB,CAAC;IAC7C,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK,GAAG,KAAK,CAAC;IACjD,IAAI,WAAW,GAAG,OAAO,CAAC;IAC1B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAI,IAAI,GAAG,IAAI,CAAC;QAChB,kGAAkG;QAClG,IAAI,OAAO,GAAG,KAAK,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC;QAC1D,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,IAAI,EAAE,CAAC;QACjC,WAAW,GAAG,IAAI,GAAG,kBAAkB,CAAC;IAC1C,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;AACvD,CAAC"}
|
package/dist/constants.d.ts
CHANGED
|
@@ -660,6 +660,8 @@ export type NpcKind = 'seagull' | 'crab'
|
|
|
660
660
|
| 'mudtoad' | 'reedspinner' | 'fenheron' | 'reedmatriarch'
|
|
661
661
|
/** Gullhook Head's wrecker chief (gullhookHead.ts, T70 2026-10-14): Skerrow the Lamp-Snuffer, level 30, with the Gaff Haul. */
|
|
662
662
|
| 'skerrow'
|
|
663
|
+
/** The Arcane Realms' creatures and mini-boss (arcaneRealmsContent.ts, T86 2026-10-14): wisp, sentinel, hawk and the Runebound Warden. */
|
|
664
|
+
| 'manawisp' | 'runesentinel' | 'zephyrhawk' | 'runewarden'
|
|
663
665
|
/** Saltmere Crescent's salt crab, wreck rat and shore reaver (saltmereWildlife.ts, T68 2026-10-14). */
|
|
664
666
|
| 'saltcrab' | 'bayrat' | 'shorereaver'
|
|
665
667
|
/** The Redclay Hook's clay crab, mud goat and kiln raider (redclayWildlife.ts, T68 2026-10-14). */
|