@dreadwood-types/types 0.1.139 → 0.1.141

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.
@@ -17,7 +17,10 @@
17
17
  */
18
18
  import { BRINE_TRICORN_KIND, MARIGOLD_STRONGBOX_KIND, SEA_CAVE_OUTSIDE, SMUGGLER_CAPTAIN_KIND, SMUGGLER_CAPTAIN_NAME, } from './smugglersStrand.js';
19
19
  import { CORVIN_SATCHEL_PROP, CORVINS_NOTES_KIND, PESTLE_AND_MORTAR_KIND, VIAL_OF_WATER_KIND, } from './potionMaking.js';
20
+ import { SUNDERED_SPAN_STAGES } from './southExpansion.js';
20
21
  import { FARMER_BRAMBLE_KIND, HOG_DAMAGE_PROP, MUD_WALLOW, OLD_HOGGER_KIND, ROTTEN_TURNIP_KIND, TURNIP_CRATE, WARTHOG_KIND, } from './hogWild.js';
22
+ import { FOLD_HOME, GOOSE_FEATHERS_NEEDED, GOOSE_FEATHER_KIND, HONEY_BREAD_KIND, HONEY_KIND, HONEYCOMB_KIND, SOUTH_FIELDS_HETTIE_NAME, SOUTH_FIELDS_NYE_NAME, SOUTH_FIELDS_WREN_NAME, SOUTH_PROP, southFieldsPersonAt, } from './southFieldsQuests.js';
23
+ import { SOUTH_FIELDS_CROP_FIELDS, SOUTH_FIELDS_FOLD, SOUTH_FIELDS_HIVES } from './southExpansion.js';
21
24
  export const STORY_SKILLS = [
22
25
  'strength',
23
26
  'archery',
@@ -48,6 +51,8 @@ export const STORY_SKILL_NAMES = {
48
51
  export function isStorySkill(value) {
49
52
  return typeof value === 'string' && STORY_SKILLS.includes(value);
50
53
  }
54
+ /** The kind whose people a story quest knows by name, not by kind (every villager is a `resident`). */
55
+ export const NAMED_STORY_NPC_KIND = 'resident';
51
56
  export const STORY_QUEST_IDS = [
52
57
  // The newcomer's first quest, from Guide Rowan by the starter notice board.
53
58
  'firstSteps',
@@ -79,6 +84,14 @@ export const STORY_QUEST_IDS = [
79
84
  'bountyHuntersBrew',
80
85
  'corvinsRecipes',
81
86
  'hogWild',
87
+ 'fiveArches',
88
+ // The South Fields' line (southFieldsQuests.ts), in order: each opens the next.
89
+ 'theNewGate',
90
+ 'hettiesSails',
91
+ 'geeseInTheWheat',
92
+ 'nyesStrays',
93
+ 'wrensHoney',
94
+ 'harvestSupper',
82
95
  ];
83
96
  /** The npc_action id for a story choice. */
84
97
  export const STORY_CHOICE_PREFIX = 'story:';
@@ -156,6 +169,19 @@ export function questPropModel(style) {
156
169
  return 'questhogtracks';
157
170
  if (prop === 'turnipcrate')
158
171
  return 'questturnipcrate';
172
+ // The South Fields (southFieldsQuests.ts): the two broken fences, Hettie's repair points (a stack of planks stands
173
+ // in for the fallen sail stock and canvas), Wren's smoker and hives as the layout's own models, and the supper
174
+ // hamper (the crate of produce stands in for a hamper).
175
+ if (prop === SOUTH_PROP.fieldBreach || prop === SOUTH_PROP.hurdleBreach)
176
+ return 'questbrokenfence';
177
+ if (prop === SOUTH_PROP.millRepair)
178
+ return 'plankstack';
179
+ if (prop === SOUTH_PROP.smoker)
180
+ return 'smoker';
181
+ if (prop === SOUTH_PROP.hive)
182
+ return 'beehive';
183
+ if (prop === SOUTH_PROP.hamper)
184
+ return 'questturnipcrate';
159
185
  return 'questdiarypage';
160
186
  }
161
187
  /**
@@ -209,6 +235,13 @@ export const BOB = { kind: 'bob', name: 'Bob' };
209
235
  /** Hog Wild (hogWild.ts): the farmer east of Calverton whose turnips the warthogs eat. */
210
236
  export const BRAMBLE = { kind: FARMER_BRAMBLE_KIND, name: 'Farmer Bramble' };
211
237
  export const OLD_HOGGER = { kind: OLD_HOGGER_KIND, name: 'Old Hogger' };
238
+ /** Five Arches: the King's last bridge keeper, at the bridgehead camp south of Base Camp (southExpansion.ts SUNDERED_SPAN.osmundSpot). */
239
+ export const BRIDGEWARDEN = { kind: 'bridgewarden', name: 'Bridgewarden Osmund' };
240
+ /** No Harm Farm's farmer (his son gives Clark's Chores), and the South Fields' people, residents known by name. */
241
+ export const CLARK = { kind: 'clark', name: 'Clark' };
242
+ export const HETTIE = { kind: NAMED_STORY_NPC_KIND, name: SOUTH_FIELDS_HETTIE_NAME };
243
+ export const NYE = { kind: NAMED_STORY_NPC_KIND, name: SOUTH_FIELDS_NYE_NAME };
244
+ export const WREN = { kind: NAMED_STORY_NPC_KIND, name: SOUTH_FIELDS_WREN_NAME };
212
245
  /** Every kind a story quest adds to the world, for the NpcKind union and the name table. */
213
246
  export const STORY_NPC_NAMES = {
214
247
  fred: FRED.name,
@@ -222,11 +255,14 @@ export const STORY_NPC_NAMES = {
222
255
  guide: ROWAN.name,
223
256
  farmerbramble: BRAMBLE.name,
224
257
  oldhogger: OLD_HOGGER.name,
258
+ bridgewarden: BRIDGEWARDEN.name,
225
259
  };
226
260
  const COOKED_FISH = ['cookedperch', 'cookedtench', 'cookedtrout', 'cookedbass', 'cookedfrostpike', 'cookedgrayling', 'cookedchar', 'cookedsalmon', 'cookedling', 'cookedhalibut', 'cookedanglerfish'];
227
261
  /** What Bernie will take for her birthday: any fish a starter can cook too, crab and frog legs included (Hope Beach has no perch). */
228
262
  const BIRTHDAY_TREATS = [...COOKED_FISH, 'grilledfish', 'cookedcrab', 'cookedfroglegs'];
229
263
  const ANY_LOG = ['birchwood', 'poplarwood', 'pinewood', 'sprucewood', 'ashwood'];
264
+ /** What Five Arches calls each log it asks for (spanStageStep). */
265
+ const SPAN_LOG_LABELS = { poplarwood: 'Poplar logs', birchwood: 'Birch logs', pinewood: 'Pine logs' };
230
266
  // ---- The quests -----------------------------------------------------------
231
267
  export const STORY_QUESTS = {
232
268
  fredsLetter: {
@@ -1376,7 +1412,351 @@ export const STORY_QUESTS = {
1376
1412
  perk: "Warthog Pet: it follows you, digs up finds, and eats Bramble's rotten turnips",
1377
1413
  },
1378
1414
  },
1415
+ /**
1416
+ * Five Arches (James, 2026-10-08: "a quest to repair the bridge ... a half concrete bridge with a wooden part over it
1417
+ * ... with woodwork (low level) ... remove the boat woman"). The Sundered Span's fallen arch is mended with a timber
1418
+ * trestle section, in the four hand-ins SUNDERED_SPAN_STAGES lists (one source for costs and levels), each a visible
1419
+ * stage of the player's own crossing. The ferry is gone: this is the only way over. Design sheets:
1420
+ * design-references/sunderedspan-repair-*.
1421
+ */
1422
+ fiveArches: {
1423
+ giver: BRIDGEWARDEN,
1424
+ requires: {
1425
+ skill: { skill: 'woodwork', level: SUNDERED_SPAN_STAGES[0].woodworkLevel },
1426
+ refuse: 'Four arches stand and the fifth is in the sea. I need someone who can handle timber: fell a few trees, learn the saw, and come back with Woodwork 5.',
1427
+ },
1428
+ offer: "Five arches, the old King's bridge, and four of them stand. The fifth went into the sea before I took this post. I have kept the toll house ever since, with nothing to toll. Timber, I say: a trestle bridge of poplar, birch and pine across the twelve tiles, bolted onto the stone. I can draw the plan and lash a post. I cannot fell the trees. Will you build it with me?",
1429
+ accept: 'Good. First look at what we are mending: walk out along the old deck to the broken edge, then come back and tell me what you saw.',
1430
+ decline: 'Then the sea keeps its arch, and I keep my toll house. Come back if you change your mind.',
1431
+ steps: [
1432
+ {
1433
+ kind: 'reach',
1434
+ area: { minX: 671, maxX: 680, minZ: 896, maxZ: 900 },
1435
+ at: { x: 676, z: 899, label: 'The broken edge of the Sundered Span' },
1436
+ label: 'Walk out to the broken edge of the Span',
1437
+ hint: 'Follow the old stone deck south from the bridgehead camp to where it breaks off: twelve tiles of open sea.',
1438
+ },
1439
+ {
1440
+ kind: 'talk',
1441
+ npc: BRIDGEWARDEN,
1442
+ label: 'Tell Osmund what you saw',
1443
+ hint: 'Bridgewarden Osmund keeps the bridgehead camp on the beach, south of Base Camp.',
1444
+ say: 'Twelve tiles of sea and a fallen arch at the bottom of it. Aye. Timber, then, in order: poplar for the trestle posts, birch for the beams, pine for the deck. Bring me the poplar first.',
1445
+ },
1446
+ spanStageStep(1, 'Bring Osmund twenty poplar logs', 'Fell poplar trees (Woodwork 5) and bring the logs to Bridgewarden Osmund. They are the trestle posts.', 'Sound timber, and straight. Watch the gap: the first trestles go in on the old footings. That is the posts standing.', 'Twenty poplar logs, and Woodwork 5 to work them.'),
1447
+ spanStageStep(2, 'Bring Osmund birch and poplar for the beams', 'Birch makes the cross-beams (Woodwork 8), with a little more poplar for the stringers. Bring them to Bridgewarden Osmund.', 'Now it is a frame, not a row of posts. You can see the way across it taking shape. Pine next, for the deck.', 'Twenty-five birch logs and ten poplar, and Woodwork 8.'),
1448
+ spanStageStep(3, 'Bring Osmund pine and poplar for the decking', 'Pine for the first run of deck boards (Woodwork 12), poplar for the nailing strips. Bring them to Bridgewarden Osmund.', 'Half the deck, laid from both ends towards the middle. Do not walk on it yet: I have seen men do worse things for less.', 'Fifteen pine logs and ten poplar, and Woodwork 12.'),
1449
+ spanStageStep(4, 'Bring Osmund pine and birch for the deck and rails', 'The last of the deck and the rails (Woodwork 12): pine and birch, to Bridgewarden Osmund.', 'Deck, rails, rope lashings, every bracket bolted to the old stone. That is the Span mended, timber and stone together.', 'Fifteen pine logs and fifteen birch, and Woodwork 12.'),
1450
+ {
1451
+ kind: 'reach',
1452
+ area: { minX: 671, maxX: 680, minZ: 913, maxZ: 920 },
1453
+ at: { x: 676, z: 910, label: 'The new timber section' },
1454
+ label: 'Cross the new timber section',
1455
+ hint: 'Walk out to the broken edge and click the new timber section in the gap: you cross to the far deck.',
1456
+ },
1457
+ {
1458
+ kind: 'talk',
1459
+ npc: BRIDGEWARDEN,
1460
+ label: 'Tell Osmund it holds',
1461
+ hint: 'Cross back the same way (click the timber section) and tell Bridgewarden Osmund at the bridgehead camp.',
1462
+ say: 'You crossed it and it held? Then four arches and a timber one it is. I never thought to see anyone on the far side.',
1463
+ },
1464
+ ],
1465
+ done: 'Five arches, near enough. The King would have hated it and I could not be prouder. Take this for the timber, and walk it whenever you like.',
1466
+ after: 'Timber and stone, and neither complains. The far side is yours, if you can stand what lives there.',
1467
+ rewards: { coins: 500, xp: { explorer: 1000 } },
1468
+ },
1469
+ // ---- The South Fields (southFieldsQuests.ts): six quests, each opening the next ----------------------------------
1470
+ theNewGate: {
1471
+ giver: CLARK,
1472
+ requires: {
1473
+ quest: 'clarksChores',
1474
+ refuse: "My lad's behind on the chores again. Give him a hand first, and then we'll talk about the new fields.",
1475
+ },
1476
+ offer: "We've cut a new gate through the crag south of the yard, and there's a whole headland of fields behind it. Hettie at the mill is short of wheat. Reap her three good sheaves, would you?",
1477
+ accept: "Through the new gate and the wheat's either side of the lane. Pull it by hand, then take it east along the track to Hettie's windmill.",
1478
+ decline: "No rush. The wheat's not going anywhere, more's the pity.",
1479
+ steps: [
1480
+ {
1481
+ kind: 'gather',
1482
+ items: ['wheat'],
1483
+ qty: 3,
1484
+ label: 'Reap three sheaves of wheat in the South Fields',
1485
+ hint: 'Go through the new gate in the crag south of the farmhouse. The ripe wheat stands in the plots either side of the lane: click a ripe stalk to reap it by hand.',
1486
+ at: { x: SOUTH_FIELDS_CROP_FIELDS[0].maxX - 2, z: SOUTH_FIELDS_CROP_FIELDS[0].minZ + 4, label: 'the wheat plots' },
1487
+ },
1488
+ {
1489
+ kind: 'deliver',
1490
+ npc: HETTIE,
1491
+ items: [{ kinds: ['wheat'], qty: 3, label: 'Wheat' }],
1492
+ label: 'Take the wheat to Miller Hettie at the windmill',
1493
+ hint: "Hettie's windmill stands on the east point of the South Fields: follow the track east past the orchard, the duck pond and the sheep fold.",
1494
+ say: "Clark's wheat, and good dry sheaves too. Thank you, love. I'd grind them now, but look at my sails: the storm tore them to rags, and the stones won't turn.",
1495
+ short: 'Three sheaves from the plots, love. Clark knows.',
1496
+ },
1497
+ ],
1498
+ done: "Hettie's got her wheat? Good. That mill's been our bread for forty years. If she's asking for help, help her.",
1499
+ after: 'The South Fields feed this farm. Go and see who needs a hand down there.',
1500
+ rewards: { coins: 60, xp: { foraging: 150, explorer: 300 } },
1501
+ },
1502
+ hettiesSails: {
1503
+ giver: HETTIE,
1504
+ requires: {
1505
+ quest: 'theNewGate',
1506
+ refuse: "Mind the flour dust. If you're after work, Clark up at the farm was looking for hands.",
1507
+ },
1508
+ offer: "The storm tore my sails clean off the stocks, and the stones won't turn on a breeze like this. I've two poplar planks and a bolt of linen put by. Help me fit them? Then I'll show you what a mill is for.",
1509
+ accept: "The planks are laid out on the east side of the mill, under the sails, and the linen beside them. Fit the stock first, then lace the canvas.",
1510
+ decline: 'The sails will wait. The wheat will not, but there we are.',
1511
+ steps: [
1512
+ {
1513
+ kind: 'touch',
1514
+ prop: SOUTH_PROP.millRepair,
1515
+ qty: 2,
1516
+ label: 'Fit the new sail stock and lace the canvas',
1517
+ hint: "Hettie's two poplar planks and her bolt of linen lie on the east side of the windmill, under the sails. Click each to fit it.",
1518
+ notices: {
1519
+ [`${SOUTH_PROP.millRepair}:stock`]: "You heave Hettie's two poplar planks up into the broken stock and peg them home. The frame is true again.",
1520
+ [`${SOUTH_PROP.millRepair}:canvas`]: 'You lace the new linen to the frame, tight as a drum. Above you, the sails creak and begin to turn.',
1521
+ },
1522
+ },
1523
+ {
1524
+ kind: 'gather',
1525
+ items: ['flour'],
1526
+ qty: 1,
1527
+ label: 'Have Hettie grind a sheaf into flour',
1528
+ hint: 'Reap a sheaf of wheat in the plots if you have none, then speak to Miller Hettie and choose Grind my wheat.',
1529
+ at: { ...southFieldsPersonAt(SOUTH_FIELDS_HETTIE_NAME), label: 'Miller Hettie' },
1530
+ },
1531
+ {
1532
+ kind: 'cook',
1533
+ dishes: ['bread'],
1534
+ qty: 1,
1535
+ label: 'Bake a loaf of bread',
1536
+ hint: "Bake the flour at the clay oven outside Nye's sheep fold, or at any fire (Cooking 2).",
1537
+ },
1538
+ {
1539
+ kind: 'talk',
1540
+ npc: HETTIE,
1541
+ label: 'Show Miller Hettie your loaf',
1542
+ hint: 'Miller Hettie stands at the door of her windmill, on the east point of the South Fields.',
1543
+ say: 'Wheat to the stones, flour to the fire. Now you know what this place is for. Every loaf on the headland starts here.',
1544
+ },
1545
+ ],
1546
+ done: 'The stones are turning and you can bake. Bring me wheat whenever you like: I grind it for nothing. Take this for your trouble.',
1547
+ after: 'Hear them turn? Bring me your wheat and I will grind it for you.',
1548
+ rewards: { coins: 120, xp: { cooking: 250, woodwork: 100, explorer: 400 } },
1549
+ },
1550
+ geeseInTheWheat: {
1551
+ giver: HETTIE,
1552
+ keepTouched: true,
1553
+ requires: {
1554
+ quest: 'hettiesSails',
1555
+ refuse: 'Help me get the sails up first, love. One job at a time.',
1556
+ },
1557
+ offer: 'Now the stones turn, the geese are at my wheat. They come up from the duck pond through a gap in the plot fence, bold as brass, and hiss at anyone who shoos them. See off a few and mend the gap?',
1558
+ accept: `Three should teach the rest. Bring me ${GOOSE_FEATHERS_NEEDED} of their feathers while you're at it: I'll cut a quill for the mill ledger. The gap is in the east fence of the south-east wheat plot, on the pond side.`,
1559
+ decline: 'Then I shall grow wheat for geese.',
1560
+ steps: [
1561
+ {
1562
+ kind: 'kill',
1563
+ npcKinds: ['goose'],
1564
+ qty: 3,
1565
+ npcLabel: 'Angry geese',
1566
+ label: 'See off three angry geese',
1567
+ hint: 'The angry geese keep the duck pond, south of the orchard (level 2). They bite back, so bring something to eat.',
1568
+ },
1569
+ {
1570
+ kind: 'touch',
1571
+ prop: SOUTH_PROP.fieldBreach,
1572
+ qty: 1,
1573
+ label: 'Mend the gap in the plot fence',
1574
+ hint: 'The broken fence is the east side of the south-east wheat plot, facing the duck pond.',
1575
+ notices: {
1576
+ [`${SOUTH_PROP.fieldBreach}:e`]: 'You stand the fallen rails back up and lash a hurdle across the gap. The geese will have to go the long way round.',
1577
+ },
1578
+ },
1579
+ {
1580
+ kind: 'deliver',
1581
+ npc: HETTIE,
1582
+ items: [{ kinds: [GOOSE_FEATHER_KIND], qty: GOOSE_FEATHERS_NEEDED, label: 'Goose feathers' }],
1583
+ label: `Bring Miller Hettie ${GOOSE_FEATHERS_NEEDED} goose feathers`,
1584
+ hint: 'A goose drops a feather when you see it off. Miller Hettie is at the windmill on the east point.',
1585
+ say: 'Two good flights. That will make a quill and a half. My wheat is safe for a season, thanks to you.',
1586
+ short: 'A couple of goose feathers for my quill, love. The pond geese have plenty.',
1587
+ },
1588
+ ],
1589
+ done: 'My ledger has a new quill and my wheat has a fence. Take this, and go and see Nye at the fold: he was asking after a steady pair of hands.',
1590
+ after: 'Not a goose in the wheat all week. The fence is holding.',
1591
+ rewards: { coins: 120, xp: { explorer: 400 }, choiceXp: { qty: 250, skills: STORY_COMBAT_SKILLS } },
1592
+ },
1593
+ nyesStrays: {
1594
+ giver: NYE,
1595
+ keepTouched: true,
1596
+ requires: {
1597
+ quest: 'geeseInTheWheat',
1598
+ skill: { skill: 'foraging', level: 5 },
1599
+ refuse: "I've a job, but it ends in shearing, and that wants a steady hand (Foraging 5). Reap the wheat and pick the orchard a while, then come and see me.",
1600
+ },
1601
+ offer: "Two of my ewes are out. They shoved through a rotten hurdle on the south side of the fold and they're grazing like they own the headland. Mend the hurdle, fetch them home, and then I've shearing for you.",
1602
+ accept: "Hurdle first, or they'll only wander straight back out. Here, take my spare shears if you've none of your own.",
1603
+ decline: "They'll come home when they're hungry. Or they won't.",
1604
+ onAccept: [{ kind: 'shears', qty: 1, ifMissing: true }],
1605
+ steps: [
1606
+ {
1607
+ kind: 'touch',
1608
+ prop: SOUTH_PROP.hurdleBreach,
1609
+ qty: 1,
1610
+ label: 'Mend the rotten hurdle in the fold',
1611
+ hint: "The rotten hurdle is in the fold's south fence, a little east of the dog's gap.",
1612
+ notices: {
1613
+ [`${SOUTH_PROP.hurdleBreach}:s`]: "You pull out the rotten hurdle and pin a new one in its place with Nye's stakes.",
1614
+ },
1615
+ },
1616
+ {
1617
+ kind: 'lead',
1618
+ pet: 'sheep',
1619
+ to: FOLD_HOME,
1620
+ label: 'Lead a stray ewe home to the fold',
1621
+ hint: "The strays graze west of the fold, by the pond track and on the duck pond's north bank. Click one, choose Lead home, then walk it in through the fold's west gate.",
1622
+ notice: 'The ewe trots in through the gate and makes straight for the trough, as if she had never been away.',
1623
+ },
1624
+ {
1625
+ kind: 'lead',
1626
+ pet: 'sheep',
1627
+ to: FOLD_HOME,
1628
+ label: 'Lead the other stray ewe home',
1629
+ hint: "The other stray is still out west of the fold. Click it, choose Lead home, and walk it in through the fold's west gate.",
1630
+ notice: 'The second ewe follows you in and the flock closes round her, bleating.',
1631
+ },
1632
+ {
1633
+ kind: 'gather',
1634
+ items: ['wool'],
1635
+ qty: 4,
1636
+ label: 'Shear four fleeces',
1637
+ hint: 'Shear the sheep in the fold (Foraging 5, shears). Walk up to one and choose Shear. A shorn sheep grows its coat back in a few minutes.',
1638
+ at: { x: SOUTH_FIELDS_FOLD.minX + 8, z: SOUTH_FIELDS_FOLD.minZ + 12, label: 'the sheep fold' },
1639
+ },
1640
+ {
1641
+ kind: 'talk',
1642
+ npc: NYE,
1643
+ label: 'Tell Shepherd Nye the flock is home and shorn',
1644
+ hint: "Shepherd Nye stands by the dog's gap on the south side of the fold.",
1645
+ say: 'Both ewes home, and four clean fleeces off. Keep the wool: Clark is talking about a harvest supper, and a good fleece is worth bringing to it.',
1646
+ },
1647
+ ],
1648
+ done: "There's not many I'd trust in with the flock. Take this. And Wren at the hives could use you next.",
1649
+ after: "The flock's all present. The dog's grateful, though he'd never say so.",
1650
+ rewards: { coins: 150, xp: { foraging: 300, explorer: 400 } },
1651
+ },
1652
+ wrensHoney: {
1653
+ giver: WREN,
1654
+ requires: {
1655
+ quest: 'nyesStrays',
1656
+ refuse: 'The bees are cross today. Help Nye with his flock first, and come back when they have calmed down.',
1657
+ },
1658
+ offer: "The orchard's in blossom and the hives are heavy. Help me take the comb? Smoke them first, mind, or they'll have the skin off you.",
1659
+ accept: "The smoker's beside the hives, warm already. A few puffs, then lift a comb from two of them. I'll spin it into honey for you, and Hettie's flour does the rest.",
1660
+ decline: 'The bees will keep. They always do.',
1661
+ steps: [
1662
+ {
1663
+ kind: 'touch',
1664
+ prop: SOUTH_PROP.smoker,
1665
+ qty: 1,
1666
+ label: 'Work the smoker over the hives',
1667
+ hint: "Wren's smoker stands just south of the three hives, in the orchard's meadow.",
1668
+ notices: {
1669
+ [`${SOUTH_PROP.smoker}:s`]: 'You work the bellows. Cool grey smoke drifts over the skeps and the hum drops to a drowsy murmur.',
1670
+ },
1671
+ },
1672
+ {
1673
+ kind: 'gather',
1674
+ items: [HONEYCOMB_KIND],
1675
+ qty: 2,
1676
+ label: 'Lift a comb from two of the hives',
1677
+ hint: 'Click a hive to lift a comb. Each hive gives one, then needs a few minutes to fill again.',
1678
+ at: { x: SOUTH_FIELDS_HIVES[1][0], z: SOUTH_FIELDS_HIVES[1][1] + 2, label: "Wren's hives" },
1679
+ },
1680
+ {
1681
+ kind: 'gather',
1682
+ items: [HONEY_KIND],
1683
+ qty: 2,
1684
+ label: 'Have Wren spin the comb into honey',
1685
+ hint: 'Speak to Beekeeper Wren beside the hives and choose Spin my honeycomb.',
1686
+ at: { ...southFieldsPersonAt(SOUTH_FIELDS_WREN_NAME), label: 'Beekeeper Wren' },
1687
+ },
1688
+ {
1689
+ kind: 'cook',
1690
+ dishes: [HONEY_BREAD_KIND],
1691
+ qty: 1,
1692
+ label: 'Bake a honey bread',
1693
+ hint: "A honey bread is a pot of honey and a sack of flour baked together (Cooking 4). Bake it at the clay oven outside Nye's fold, or any fire. Hettie grinds wheat into flour for nothing.",
1694
+ },
1695
+ {
1696
+ kind: 'talk',
1697
+ npc: WREN,
1698
+ label: 'Show Beekeeper Wren your honey bread',
1699
+ hint: "Beekeeper Wren stands by her hives in the orchard's meadow.",
1700
+ say: "Golden on top and sticky underneath. That's the South Fields in one loaf.",
1701
+ },
1702
+ ],
1703
+ done: "Take a couple of pots, and come back to the hives whenever you like: they fill again. Clark's laying a harvest supper, I hear. Bring him a loaf of that.",
1704
+ after: 'The bees are content. Smoke them first, and they will share.',
1705
+ rewards: { coins: 150, xp: { cooking: 250, foraging: 250, explorer: 400 }, items: [{ kind: HONEY_KIND, qty: 2 }] },
1706
+ },
1707
+ harvestSupper: {
1708
+ giver: CLARK,
1709
+ requires: {
1710
+ quest: 'wrensHoney',
1711
+ refuse: "There'll be a supper when the harvest's in. Hettie, Nye and Wren could all use a hand before then.",
1712
+ },
1713
+ offer: "Hettie's sails are turning, the geese are fenced out, Nye has his ewes and Wren's hives are full. That's a harvest worth a supper. Will you lay the long table in the South Fields for us all?",
1714
+ accept: 'Two loaves of bread, a honey bread, two fleeces for the raffle and four apples from the orchard. The hamper at the west end of the long table, west of the fold, takes the lot.',
1715
+ decline: "Then we'll eat standing up, like always.",
1716
+ steps: [
1717
+ {
1718
+ kind: 'touch',
1719
+ prop: SOUTH_PROP.hamper,
1720
+ qty: 1,
1721
+ label: 'Lay the supper at the long table',
1722
+ hint: 'Bring 2 bread, 1 honey bread, 2 wool and 4 apples to the hamper at the west end of the long table, west of the sheep fold, and click it.',
1723
+ notices: {
1724
+ [`${SOUTH_PROP.hamper}:s`]: 'You lay the loaves down the middle of the long table, the honey bread at the head, apples in a bowl and the fleeces rolled on the bench. The fields have never looked so fed.',
1725
+ },
1726
+ },
1727
+ {
1728
+ kind: 'talk',
1729
+ npc: CLARK,
1730
+ label: 'Tell Clark the table is laid',
1731
+ hint: 'Clark is at No Harm Farm by the farmhouse, north through the gate in the crag.',
1732
+ say: 'Laid already? Then we eat! Hettie will bring the cider and Nye will tell that story about the ram again.',
1733
+ },
1734
+ ],
1735
+ done: "Best supper this farm has had in years. Here, the farm's thanks. And Joss at the harvest cart will buy whatever the fields give you from now on: three orders a day, fair money.",
1736
+ after: "The fields are in good heart. Joss has the day's orders on the cart, if you've produce to sell.",
1737
+ rewards: {
1738
+ coins: 400,
1739
+ xp: { explorer: 800, cooking: 300, foraging: 300 },
1740
+ choiceXp: { qty: 500 },
1741
+ perk: "Joss's Harvest Cart: three produce orders a day for coins and XP, at the cart by the South Fields gate",
1742
+ },
1743
+ },
1379
1744
  };
1745
+ /** One hand-in of Five Arches: a `deliver` step to Osmund whose goods, Woodwork level and effect come from SUNDERED_SPAN_STAGES. */
1746
+ function spanStageStep(stage, label, hint, say, short) {
1747
+ const spec = SUNDERED_SPAN_STAGES[stage - 1];
1748
+ return {
1749
+ kind: 'deliver',
1750
+ npc: BRIDGEWARDEN,
1751
+ items: spec.cost.map((c) => ({ kinds: [c.kind], qty: c.qty, label: SPAN_LOG_LABELS[c.kind] ?? c.kind })),
1752
+ label,
1753
+ hint,
1754
+ say,
1755
+ short,
1756
+ skill: { skill: 'woodwork', level: spec.woodworkLevel },
1757
+ effect: `span-stage-${stage}`,
1758
+ };
1759
+ }
1380
1760
  /** Every skill level a quest's gate asks for (`requires.skill` and `requires.skills` together). */
1381
1761
  export function storySkillGates(def) {
1382
1762
  const req = def.requires;
@@ -1407,6 +1787,9 @@ export function storyStepTarget(step) {
1407
1787
  export function npcMatches(ref, npc) {
1408
1788
  if (ref.kind !== npc.kind)
1409
1789
  return false;
1790
+ // Residents are everyone's villagers: only the one with this name is the quest's.
1791
+ if (ref.kind === NAMED_STORY_NPC_KIND)
1792
+ return npc.name === ref.name;
1410
1793
  return ref.id ? ref.id === npc.id : true;
1411
1794
  }
1412
1795
  /** Reward lines for the offer card, as QuestReward rows. */