@dreadwood-types/types 0.1.278 → 0.1.280

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.
@@ -0,0 +1,166 @@
1
+ /**
2
+ * THE WANTED BOARD (A1, T84, 2026-10-14; AREA_PROPOSALS.md "The Wanted Board"): player bounties in the Dreadwoods. A board in
3
+ * Gallowmere's palisade (a safe pocket, nobody can be attacked there) where a player the woods' PvP has wronged can put coins on
4
+ * the head of the player who killed them. Hunters claim the pot by killing the target in the woods.
5
+ *
6
+ * The rules, all enforced by the server (backend wantedBoard.ts), all PLACEHOLDER numbers (balance is done last):
7
+ * - RIGHT TO POST: only after a real wilderness kill recorded by the server (not a duel, not a safe pocket). One kill = one bounty,
8
+ * posted within WANTED_KILL_WINDOW_MS, on the player who killed you, never on yourself, never on your own account's other character.
9
+ * - THE POT is taken out of the poster's bag when posted and held in escrow (it is nobody's until the bounty ends), plus a FEE that is
10
+ * not held: it is burned (a coin sink), so posting is never free. Pots are capped; so are open bounties per poster and per target.
11
+ * - EXPIRY: a bounty ends WANTED_EXPIRY_MS after posting and the pot goes back to the poster (the fee does not). The poster can also
12
+ * cancel at the board for the same refund. A refund or a payout to a player who is offline waits (saved) and is paid at their next join.
13
+ * - CLAIM: the hunter must kill the target in the woods (PvP zone, a wilderness fight, not a duel), within WANTED_MAX_LEVEL_GAP levels,
14
+ * and must not be the poster, the target, or on either's account. The same hunter claiming on the same target again within
15
+ * WANTED_CLAIM_PAIR_COOLDOWN_MS is paid nothing, and a hunter is paid at most WANTED_HUNTER_DAILY_CAP times a day.
16
+ * - A repeated kill by the same killer on the same victim inside WANTED_PAIR_KILL_COOLDOWN_MS gives no new right to post.
17
+ *
18
+ * Every number is a world tile or a placeholder. Backend wantedBoard.ts keeps the live board and world.ts wires it in.
19
+ */
20
+ export declare const WANTED_KEEPER: {
21
+ readonly id: "wanted-keeper";
22
+ readonly name: "Bailiff Wynn Ashby";
23
+ readonly x: 395;
24
+ readonly z: 610;
25
+ readonly faceX: 395;
26
+ readonly faceZ: 614;
27
+ readonly leash: 1;
28
+ };
29
+ export declare const WANTED_KEEPER_REACH = 3;
30
+ /** Where the board stands, for the guide and the verify links. */
31
+ export declare const WANTED_BOARD_PLACE = "Gallowmere's palisade";
32
+ /** The keeper's menu actions (npc_action ids). */
33
+ export declare const WANTED_READ_ACTION = "wanted-read";
34
+ export declare const WANTED_KILLERS_ACTION = "wanted-killers";
35
+ export declare const WANTED_MINE_ACTION = "wanted-mine";
36
+ export declare const WANTED_CANCEL_ACTION = "wanted-cancel";
37
+ export declare const WANTED_POST_ACTIONS: readonly string[];
38
+ export declare const WANTED_ACTIONS: readonly string[];
39
+ export declare function isWantedAction(action: string): boolean;
40
+ /** PLACEHOLDER pots for the three "post on my latest killer" buttons, and the bounds of a typed `/wanted post <name> <coins>`. */
41
+ export declare const WANTED_POT_TIERS: readonly number[];
42
+ export declare const WANTED_MIN_POT = 50;
43
+ export declare const WANTED_MAX_POT = 2000;
44
+ /** The fee on top of the pot: a percentage, at least the minimum. Burned, never held. */
45
+ export declare const WANTED_FEE_PERCENT = 10;
46
+ export declare const WANTED_FEE_MIN = 10;
47
+ export declare const WANTED_EXPIRY_MS: number;
48
+ /** A kill gives the right to post for this long. */
49
+ export declare const WANTED_KILL_WINDOW_MS: number;
50
+ /** A repeated kill by the same killer on the same victim inside this gives no new right to post. */
51
+ export declare const WANTED_PAIR_KILL_COOLDOWN_MS: number;
52
+ export declare const WANTED_CLAIM_PAIR_COOLDOWN_MS: number;
53
+ export declare const WANTED_HUNTER_DAILY_CAP = 3;
54
+ export declare const WANTED_HUNTER_WINDOW_MS: number;
55
+ export declare const WANTED_MAX_LEVEL_GAP = 10;
56
+ export declare const WANTED_MIN_COMBAT = 10;
57
+ export declare const WANTED_POSTS_PER_POSTER = 2;
58
+ export declare const WANTED_OPEN_PER_TARGET = 3;
59
+ export declare const WANTED_BOARD_MAX = 200;
60
+ export declare const WANTED_KILLS_MAX = 400;
61
+ export declare const WANTED_KILLS_PER_VICTIM = 5;
62
+ export declare const WANTED_OWED_PER_CHARACTER = 20;
63
+ export declare const WANTED_CLAIMS_MAX = 400;
64
+ /** Ids of settled payouts a character remembers, so a payout is never paid twice after a crash (Character.wantedSettled). */
65
+ export declare const WANTED_SETTLED_MAX = 60;
66
+ /** Ids of bounties a poster has funded, so a half-finished posting is told from a finished one after a crash (Character.wantedFunded). */
67
+ export declare const WANTED_FUNDED_MAX = 40;
68
+ /** Ledger lines (section `wanted`); the server writes each mark. */
69
+ export declare const LEDGER_WANTED_XP = 60;
70
+ export declare const LEDGER_WANTED_LINES: readonly {
71
+ id: string;
72
+ label: string;
73
+ }[];
74
+ export type WantedKill = {
75
+ id: string;
76
+ killerId: string;
77
+ killerAccount: string;
78
+ killerName: string;
79
+ victimId: string;
80
+ victimAccount: string;
81
+ victimName: string;
82
+ at: number;
83
+ used: boolean;
84
+ };
85
+ export type WantedBounty = {
86
+ id: string;
87
+ posterId: string;
88
+ posterAccount: string;
89
+ posterName: string;
90
+ targetId: string;
91
+ targetAccount: string;
92
+ targetName: string;
93
+ pot: number;
94
+ createdAt: number;
95
+ expiresAt: number;
96
+ /** False between "the board took the note" and "the poster's coins were saved as gone" (see backend wantedBoard.ts, reconcile). */
97
+ funded: boolean;
98
+ killId: string;
99
+ };
100
+ export type WantedOwedWhy = 'claim' | 'expired' | 'cancelled' | 'unfunded-cancelled';
101
+ /** Coins owed to a character who was not online when the bounty ended. Paid once at their next join. */
102
+ export type WantedOwed = {
103
+ id: string;
104
+ charId: string;
105
+ coins: number;
106
+ why: WantedOwedWhy;
107
+ at: number;
108
+ text: string;
109
+ };
110
+ export type WantedClaimRecord = {
111
+ hunterId: string;
112
+ targetId: string;
113
+ at: number;
114
+ };
115
+ export type WantedSave = {
116
+ v: 1;
117
+ seq: number;
118
+ bounties: WantedBounty[];
119
+ kills: WantedKill[];
120
+ owed: WantedOwed[];
121
+ claims: WantedClaimRecord[];
122
+ };
123
+ export declare function emptyWantedSave(): WantedSave;
124
+ export declare function wantedFee(pot: number): number;
125
+ /** What the poster pays out of the bag: the pot (held) plus the fee (burned). */
126
+ export declare function wantedCost(pot: number): number;
127
+ export declare function wantedPotValid(pot: unknown): pot is number;
128
+ export declare function wantedTimeLeft(ms: number): string;
129
+ /** The bounties still open (not past their end) on a target. */
130
+ export declare function wantedOpenOn(save: WantedSave, targetId: string, now: number): WantedBounty[];
131
+ /** The kills that gave `victimId` the right to post and have not been used or expired, newest first. */
132
+ export declare function wantedKillersOf(save: WantedSave, victimId: string, now: number): WantedKill[];
133
+ export type WantedCheck = {
134
+ ok: true;
135
+ } | {
136
+ ok: false;
137
+ reason: string;
138
+ };
139
+ /**
140
+ * Whether a kill may be written down as giving the victim the right to post. A repeated kill by the same killer on the same victim
141
+ * inside the cooldown is not (pairs trading kills cannot farm the right), nor is a kill of one of your own account's characters.
142
+ */
143
+ export declare function wantedKillRecordable(save: WantedSave, kill: Pick<WantedKill, 'killerId' | 'killerAccount' | 'victimId' | 'victimAccount' | 'at'>): WantedCheck;
144
+ export type WantedPoster = {
145
+ id: string;
146
+ account: string;
147
+ combat: number;
148
+ };
149
+ /** Whether a poster may put `pot` on the killer named by `kill` now. `coins` is what their bag holds. */
150
+ export declare function wantedPostCheck(save: WantedSave, poster: WantedPoster, kill: WantedKill | null, targetCombat: number, pot: number, coins: number, now: number): WantedCheck;
151
+ export type WantedHunter = {
152
+ id: string;
153
+ account: string;
154
+ combat: number;
155
+ };
156
+ /** Whether `hunter` felling `target` collects `bounty` now (the kill itself was already checked as a wilderness kill). */
157
+ export declare function wantedClaimCheck(save: WantedSave, bounty: WantedBounty, hunter: WantedHunter, target: {
158
+ id: string;
159
+ account: string;
160
+ combat: number;
161
+ }, now: number): WantedCheck;
162
+ /** The board as chat lines. `viewerId` marks your own postings and the ones on your head. */
163
+ export declare function wantedBoardLines(save: WantedSave, now: number, viewerId?: string): string[];
164
+ /** Whatever the database held, made safe: bounded lists, whole numbers, unknown shapes dropped. */
165
+ export declare function parseWantedSave(raw: unknown): WantedSave;
166
+ //# sourceMappingURL=wantedBoard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wantedBoard.d.ts","sourceRoot":"","sources":["../src/wantedBoard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,eAAO,MAAM,aAAa;;;;;;;;CAAiH,CAAC;AAC5I,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,kEAAkE;AAClE,eAAO,MAAM,kBAAkB,0BAA0B,CAAC;AAE1D,kDAAkD;AAClD,eAAO,MAAM,kBAAkB,gBAAgB,CAAC;AAChD,eAAO,MAAM,qBAAqB,mBAAmB,CAAC;AACtD,eAAO,MAAM,kBAAkB,gBAAgB,CAAC;AAChD,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AACpD,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAAwD,CAAC;AAC1G,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAAkH,CAAC;AAE/J,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,kIAAkI;AAClI,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAAqB,CAAC;AACpE,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,cAAc,OAAO,CAAC;AACnC,yFAAyF;AACzF,eAAO,MAAM,kBAAkB,KAAK,CAAC;AACrC,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC,eAAO,MAAM,gBAAgB,QAAgB,CAAC;AAC9C,oDAAoD;AACpD,eAAO,MAAM,qBAAqB,QAAgB,CAAC;AACnD,oGAAoG;AACpG,eAAO,MAAM,4BAA4B,QAAe,CAAC;AACzD,eAAO,MAAM,6BAA6B,QAAgB,CAAC;AAC3D,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,uBAAuB,QAAgB,CAAC;AACrD,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,sBAAsB,IAAI,CAAC;AACxC,eAAO,MAAM,gBAAgB,MAAM,CAAC;AACpC,eAAO,MAAM,gBAAgB,MAAM,CAAC;AACpC,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAC5C,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,6HAA6H;AAC7H,eAAO,MAAM,kBAAkB,KAAK,CAAC;AACrC,0IAA0I;AAC1I,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,oEAAoE;AACpE,eAAO,MAAM,gBAAgB,KAAK,CAAC;AACnC,eAAO,MAAM,mBAAmB,EAAE,SAAS;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAGvE,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,mIAAmI;IACnI,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,WAAW,GAAG,oBAAoB,CAAC;AAErF,wGAAwG;AACxG,MAAM,MAAM,UAAU,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,aAAa,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErH,MAAM,MAAM,iBAAiB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnF,MAAM,MAAM,UAAU,GAAG;IACvB,CAAC,EAAE,CAAC,CAAC;IACL,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,MAAM,EAAE,iBAAiB,EAAE,CAAC;CAC7B,CAAC;AAEF,wBAAgB,eAAe,IAAI,UAAU,CAE5C;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,CAE1D;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAIjD;AAED,gEAAgE;AAChE,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,YAAY,EAAE,CAE5F;AAED,wGAAwG;AACxG,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,EAAE,CAE7F;AAED,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvE;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,eAAe,GAAG,UAAU,GAAG,eAAe,GAAG,IAAI,CAAC,GACzF,WAAW,CAOb;AAED,MAAM,MAAM,YAAY,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,yGAAyG;AACzG,wBAAgB,eAAe,CAC7B,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,UAAU,GAAG,IAAI,EACvB,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,GACV,WAAW,CAcb;AAED,MAAM,MAAM,YAAY,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,0HAA0H;AAC1H,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EACvD,GAAG,EAAE,MAAM,GACV,WAAW,CAUb;AAED,6FAA6F;AAC7F,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,SAAK,GAAG,MAAM,EAAE,CAUvF;AAiDD,mGAAmG;AACnG,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAwBxD"}
@@ -0,0 +1,245 @@
1
+ /**
2
+ * THE WANTED BOARD (A1, T84, 2026-10-14; AREA_PROPOSALS.md "The Wanted Board"): player bounties in the Dreadwoods. A board in
3
+ * Gallowmere's palisade (a safe pocket, nobody can be attacked there) where a player the woods' PvP has wronged can put coins on
4
+ * the head of the player who killed them. Hunters claim the pot by killing the target in the woods.
5
+ *
6
+ * The rules, all enforced by the server (backend wantedBoard.ts), all PLACEHOLDER numbers (balance is done last):
7
+ * - RIGHT TO POST: only after a real wilderness kill recorded by the server (not a duel, not a safe pocket). One kill = one bounty,
8
+ * posted within WANTED_KILL_WINDOW_MS, on the player who killed you, never on yourself, never on your own account's other character.
9
+ * - THE POT is taken out of the poster's bag when posted and held in escrow (it is nobody's until the bounty ends), plus a FEE that is
10
+ * not held: it is burned (a coin sink), so posting is never free. Pots are capped; so are open bounties per poster and per target.
11
+ * - EXPIRY: a bounty ends WANTED_EXPIRY_MS after posting and the pot goes back to the poster (the fee does not). The poster can also
12
+ * cancel at the board for the same refund. A refund or a payout to a player who is offline waits (saved) and is paid at their next join.
13
+ * - CLAIM: the hunter must kill the target in the woods (PvP zone, a wilderness fight, not a duel), within WANTED_MAX_LEVEL_GAP levels,
14
+ * and must not be the poster, the target, or on either's account. The same hunter claiming on the same target again within
15
+ * WANTED_CLAIM_PAIR_COOLDOWN_MS is paid nothing, and a hunter is paid at most WANTED_HUNTER_DAILY_CAP times a day.
16
+ * - A repeated kill by the same killer on the same victim inside WANTED_PAIR_KILL_COOLDOWN_MS gives no new right to post.
17
+ *
18
+ * Every number is a world tile or a placeholder. Backend wantedBoard.ts keeps the live board and world.ts wires it in.
19
+ */
20
+ export const WANTED_KEEPER = { id: 'wanted-keeper', name: 'Bailiff Wynn Ashby', x: 395, z: 610, faceX: 395, faceZ: 614, leash: 1 };
21
+ export const WANTED_KEEPER_REACH = 3;
22
+ /** Where the board stands, for the guide and the verify links. */
23
+ export const WANTED_BOARD_PLACE = "Gallowmere's palisade";
24
+ /** The keeper's menu actions (npc_action ids). */
25
+ export const WANTED_READ_ACTION = 'wanted-read';
26
+ export const WANTED_KILLERS_ACTION = 'wanted-killers';
27
+ export const WANTED_MINE_ACTION = 'wanted-mine';
28
+ export const WANTED_CANCEL_ACTION = 'wanted-cancel';
29
+ export const WANTED_POST_ACTIONS = ['wanted-post-1', 'wanted-post-2', 'wanted-post-3'];
30
+ export const WANTED_ACTIONS = [WANTED_READ_ACTION, WANTED_KILLERS_ACTION, WANTED_MINE_ACTION, WANTED_CANCEL_ACTION, ...WANTED_POST_ACTIONS];
31
+ export function isWantedAction(action) {
32
+ return WANTED_ACTIONS.includes(action);
33
+ }
34
+ /** PLACEHOLDER pots for the three "post on my latest killer" buttons, and the bounds of a typed `/wanted post <name> <coins>`. */
35
+ export const WANTED_POT_TIERS = [100, 300, 1000];
36
+ export const WANTED_MIN_POT = 50;
37
+ export const WANTED_MAX_POT = 2000;
38
+ /** The fee on top of the pot: a percentage, at least the minimum. Burned, never held. */
39
+ export const WANTED_FEE_PERCENT = 10;
40
+ export const WANTED_FEE_MIN = 10;
41
+ export const WANTED_EXPIRY_MS = 24 * 3600_000;
42
+ /** A kill gives the right to post for this long. */
43
+ export const WANTED_KILL_WINDOW_MS = 48 * 3600_000;
44
+ /** A repeated kill by the same killer on the same victim inside this gives no new right to post. */
45
+ export const WANTED_PAIR_KILL_COOLDOWN_MS = 6 * 3600_000;
46
+ export const WANTED_CLAIM_PAIR_COOLDOWN_MS = 24 * 3600_000;
47
+ export const WANTED_HUNTER_DAILY_CAP = 3;
48
+ export const WANTED_HUNTER_WINDOW_MS = 24 * 3600_000;
49
+ export const WANTED_MAX_LEVEL_GAP = 10;
50
+ export const WANTED_MIN_COMBAT = 10;
51
+ export const WANTED_POSTS_PER_POSTER = 2;
52
+ export const WANTED_OPEN_PER_TARGET = 3;
53
+ export const WANTED_BOARD_MAX = 200;
54
+ export const WANTED_KILLS_MAX = 400;
55
+ export const WANTED_KILLS_PER_VICTIM = 5;
56
+ export const WANTED_OWED_PER_CHARACTER = 20;
57
+ export const WANTED_CLAIMS_MAX = 400;
58
+ /** Ids of settled payouts a character remembers, so a payout is never paid twice after a crash (Character.wantedSettled). */
59
+ export const WANTED_SETTLED_MAX = 60;
60
+ /** Ids of bounties a poster has funded, so a half-finished posting is told from a finished one after a crash (Character.wantedFunded). */
61
+ export const WANTED_FUNDED_MAX = 40;
62
+ /** Ledger lines (section `wanted`); the server writes each mark. */
63
+ export const LEDGER_WANTED_XP = 60;
64
+ export const LEDGER_WANTED_LINES = [
65
+ { id: 'wanted:posted', label: 'Put a bounty on the player who killed you in the woods' },
66
+ { id: 'wanted:claimed', label: 'Collected a bounty by felling its target in the woods' },
67
+ ];
68
+ export function emptyWantedSave() {
69
+ return { v: 1, seq: 0, bounties: [], kills: [], owed: [], claims: [] };
70
+ }
71
+ export function wantedFee(pot) {
72
+ return Math.max(WANTED_FEE_MIN, Math.ceil((pot * WANTED_FEE_PERCENT) / 100));
73
+ }
74
+ /** What the poster pays out of the bag: the pot (held) plus the fee (burned). */
75
+ export function wantedCost(pot) {
76
+ return pot + wantedFee(pot);
77
+ }
78
+ export function wantedPotValid(pot) {
79
+ return typeof pot === 'number' && Number.isInteger(pot) && pot >= WANTED_MIN_POT && pot <= WANTED_MAX_POT;
80
+ }
81
+ export function wantedTimeLeft(ms) {
82
+ const m = Math.max(0, Math.ceil(ms / 60_000));
83
+ if (m >= 120)
84
+ return `${Math.floor(m / 60)} h`;
85
+ return `${m} min`;
86
+ }
87
+ /** The bounties still open (not past their end) on a target. */
88
+ export function wantedOpenOn(save, targetId, now) {
89
+ return save.bounties.filter((b) => b.targetId === targetId && b.funded && b.expiresAt > now);
90
+ }
91
+ /** The kills that gave `victimId` the right to post and have not been used or expired, newest first. */
92
+ export function wantedKillersOf(save, victimId, now) {
93
+ return save.kills.filter((k) => k.victimId === victimId && !k.used && now - k.at <= WANTED_KILL_WINDOW_MS).sort((a, b) => b.at - a.at);
94
+ }
95
+ /**
96
+ * Whether a kill may be written down as giving the victim the right to post. A repeated kill by the same killer on the same victim
97
+ * inside the cooldown is not (pairs trading kills cannot farm the right), nor is a kill of one of your own account's characters.
98
+ */
99
+ export function wantedKillRecordable(save, kill) {
100
+ if (!kill.killerId || !kill.victimId || kill.killerId === kill.victimId)
101
+ return { ok: false, reason: 'self' };
102
+ if (kill.killerAccount && kill.killerAccount === kill.victimAccount)
103
+ return { ok: false, reason: 'same-account' };
104
+ for (const k of save.kills) {
105
+ if (k.killerId === kill.killerId && k.victimId === kill.victimId && kill.at - k.at < WANTED_PAIR_KILL_COOLDOWN_MS)
106
+ return { ok: false, reason: 'pair-cooldown' };
107
+ }
108
+ return { ok: true };
109
+ }
110
+ /** Whether a poster may put `pot` on the killer named by `kill` now. `coins` is what their bag holds. */
111
+ export function wantedPostCheck(save, poster, kill, targetCombat, pot, coins, now) {
112
+ if (!kill || kill.used || kill.victimId !== poster.id)
113
+ return { ok: false, reason: 'You have no recent kill against you to answer. The board takes a bounty only from someone a player killed in the woods.' };
114
+ if (now - kill.at > WANTED_KILL_WINDOW_MS)
115
+ return { ok: false, reason: 'That kill is too old: the board only takes a bounty within two days of it.' };
116
+ if (kill.killerId === poster.id || (kill.killerAccount && kill.killerAccount === poster.account))
117
+ return { ok: false, reason: 'You cannot put a bounty on yourself or on one of your own characters.' };
118
+ if (!wantedPotValid(pot))
119
+ return { ok: false, reason: `A pot is ${WANTED_MIN_POT} to ${WANTED_MAX_POT} coins, in whole coins.` };
120
+ if (poster.combat < WANTED_MIN_COMBAT)
121
+ return { ok: false, reason: `The board is for Combat ${WANTED_MIN_COMBAT} and over.` };
122
+ if (Math.abs(poster.combat - targetCombat) > WANTED_MAX_LEVEL_GAP)
123
+ return { ok: false, reason: `The board only posts players within ${WANTED_MAX_LEVEL_GAP} Combat levels of each other.` };
124
+ const mine = save.bounties.filter((b) => b.posterId === poster.id && b.expiresAt > now).length;
125
+ if (mine >= WANTED_POSTS_PER_POSTER)
126
+ return { ok: false, reason: `You already have ${WANTED_POSTS_PER_POSTER} bounties up. Wait for one to end or cancel it.` };
127
+ if (wantedOpenOn(save, kill.killerId, now).length >= WANTED_OPEN_PER_TARGET)
128
+ return { ok: false, reason: 'That player already has as many bounties on them as the board will hold.' };
129
+ if (save.bounties.length >= WANTED_BOARD_MAX)
130
+ return { ok: false, reason: 'The board is full. Try again later.' };
131
+ const cost = wantedCost(pot);
132
+ if (coins < cost)
133
+ return { ok: false, reason: `That needs ${cost} coins in your bag (${pot} for the pot and ${wantedFee(pot)} for the board's fee).` };
134
+ return { ok: true };
135
+ }
136
+ /** Whether `hunter` felling `target` collects `bounty` now (the kill itself was already checked as a wilderness kill). */
137
+ export function wantedClaimCheck(save, bounty, hunter, target, now) {
138
+ if (!bounty.funded || bounty.expiresAt <= now)
139
+ return { ok: false, reason: 'ended' };
140
+ if (bounty.targetId !== target.id)
141
+ return { ok: false, reason: 'not-target' };
142
+ if (hunter.id === bounty.posterId || hunter.id === target.id)
143
+ return { ok: false, reason: 'self' };
144
+ if (hunter.account && (hunter.account === bounty.posterAccount || hunter.account === target.account))
145
+ return { ok: false, reason: 'same-account' };
146
+ if (Math.abs(hunter.combat - target.combat) > WANTED_MAX_LEVEL_GAP)
147
+ return { ok: false, reason: 'level-gap' };
148
+ if (hunter.combat < WANTED_MIN_COMBAT)
149
+ return { ok: false, reason: 'too-low' };
150
+ if (save.claims.some((c) => c.hunterId === hunter.id && c.targetId === target.id && now - c.at < WANTED_CLAIM_PAIR_COOLDOWN_MS))
151
+ return { ok: false, reason: 'pair-cooldown' };
152
+ if (save.claims.filter((c) => c.hunterId === hunter.id && now - c.at < WANTED_HUNTER_WINDOW_MS).length >= WANTED_HUNTER_DAILY_CAP)
153
+ return { ok: false, reason: 'daily-cap' };
154
+ return { ok: true };
155
+ }
156
+ /** The board as chat lines. `viewerId` marks your own postings and the ones on your head. */
157
+ export function wantedBoardLines(save, now, viewerId = '') {
158
+ const open = save.bounties.filter((b) => b.funded && b.expiresAt > now).sort((a, b) => b.pot - a.pot);
159
+ if (open.length === 0)
160
+ return ['The Wanted Board is bare. Nobody has put a price on anyone in the woods.'];
161
+ const lines = [`The Wanted Board: ${open.length} ${open.length === 1 ? 'bounty' : 'bounties'}. Fell the target in the Dreadwoods to collect.`];
162
+ for (const b of open.slice(0, 12)) {
163
+ const tag = b.targetId === viewerId ? ' (ON YOUR HEAD)' : b.posterId === viewerId ? ' (yours)' : '';
164
+ lines.push(`${b.targetName}: ${b.pot} coins, ${wantedTimeLeft(b.expiresAt - now)} left${tag}`);
165
+ }
166
+ if (open.length > 12)
167
+ lines.push(`...and ${open.length - 12} more.`);
168
+ return lines;
169
+ }
170
+ // ---- Saving ---------------------------------------------------------------------------------------------------------
171
+ function num(v, min, max) {
172
+ return typeof v === 'number' && Number.isFinite(v) && v >= min && v <= max ? v : null;
173
+ }
174
+ function str(v, max = 60) {
175
+ return typeof v === 'string' && v.length > 0 ? v.slice(0, max) : null;
176
+ }
177
+ function text(v, max = 60) {
178
+ return typeof v === 'string' ? v.slice(0, max) : '';
179
+ }
180
+ function parseKill(raw) {
181
+ const r = raw;
182
+ if (!r || typeof r !== 'object')
183
+ return null;
184
+ const id = str(r.id), killerId = str(r.killerId), victimId = str(r.victimId), at = num(r.at, 0, 1e15);
185
+ if (!id || !killerId || !victimId || at === null)
186
+ return null;
187
+ return {
188
+ id, killerId, killerAccount: text(r.killerAccount), killerName: text(r.killerName, 40) || 'Someone',
189
+ victimId, victimAccount: text(r.victimAccount), victimName: text(r.victimName, 40) || 'Someone', at, used: r.used === true,
190
+ };
191
+ }
192
+ function parseBounty(raw) {
193
+ const r = raw;
194
+ if (!r || typeof r !== 'object')
195
+ return null;
196
+ const id = str(r.id), posterId = str(r.posterId), targetId = str(r.targetId);
197
+ const pot = num(r.pot, WANTED_MIN_POT, WANTED_MAX_POT), createdAt = num(r.createdAt, 0, 1e15), expiresAt = num(r.expiresAt, 0, 1e15);
198
+ if (!id || !posterId || !targetId || pot === null || !Number.isInteger(pot) || createdAt === null || expiresAt === null)
199
+ return null;
200
+ return {
201
+ id, posterId, posterAccount: text(r.posterAccount), posterName: text(r.posterName, 40) || 'Someone',
202
+ targetId, targetAccount: text(r.targetAccount), targetName: text(r.targetName, 40) || 'Someone',
203
+ pot, createdAt, expiresAt, funded: r.funded === true, killId: text(r.killId),
204
+ };
205
+ }
206
+ const OWED_WHY = ['claim', 'expired', 'cancelled', 'unfunded-cancelled'];
207
+ function parseOwed(raw) {
208
+ const r = raw;
209
+ if (!r || typeof r !== 'object')
210
+ return null;
211
+ const id = str(r.id), charId = str(r.charId), coins = num(r.coins, 1, WANTED_MAX_POT), at = num(r.at, 0, 1e15);
212
+ const why = OWED_WHY.find((w) => w === r.why);
213
+ if (!id || !charId || coins === null || !Number.isInteger(coins) || at === null || !why)
214
+ return null;
215
+ return { id, charId, coins, why, at, text: text(r.text, 160) };
216
+ }
217
+ /** Whatever the database held, made safe: bounded lists, whole numbers, unknown shapes dropped. */
218
+ export function parseWantedSave(raw) {
219
+ if (!raw || typeof raw !== 'object')
220
+ return emptyWantedSave();
221
+ const r = raw;
222
+ if (r.v !== 1)
223
+ return emptyWantedSave();
224
+ const list = (v, parse, max) => Array.isArray(v) ? v.slice(0, max).map(parse).filter((x) => x !== null) : [];
225
+ const dedupe = (items) => {
226
+ const seen = new Set();
227
+ return items.filter((i) => (seen.has(i.id) ? false : (seen.add(i.id), true)));
228
+ };
229
+ const claims = list(r.claims, (c) => {
230
+ const o = c;
231
+ if (!o || typeof o !== 'object')
232
+ return null;
233
+ const hunterId = str(o.hunterId), targetId = str(o.targetId), at = num(o.at, 0, 1e15);
234
+ return hunterId && targetId && at !== null ? { hunterId, targetId, at } : null;
235
+ }, WANTED_CLAIMS_MAX);
236
+ return {
237
+ v: 1,
238
+ seq: Math.floor(num(r.seq, 0, 1e12) ?? 0),
239
+ bounties: dedupe(list(r.bounties, parseBounty, WANTED_BOARD_MAX * 2)),
240
+ kills: dedupe(list(r.kills, parseKill, WANTED_KILLS_MAX)),
241
+ owed: dedupe(list(r.owed, parseOwed, 2000)),
242
+ claims,
243
+ };
244
+ }
245
+ //# sourceMappingURL=wantedBoard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wantedBoard.js","sourceRoot":"","sources":["../src/wantedBoard.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,43 +1,43 @@
1
- {
2
- "name": "@dreadwood-types/types",
3
- "version": "0.1.278",
4
- "description": "Public wire protocol and client-safe constants for Dreadwoods",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js",
12
- "default": "./dist/index.js"
13
- },
14
- "./legacy": {
15
- "types": "./dist/legacy.d.ts",
16
- "import": "./dist/legacy.js",
17
- "default": "./dist/legacy.js"
18
- }
19
- },
20
- "files": [
21
- "dist"
22
- ],
23
- "scripts": {
24
- "build": "tsc -p tsconfig.json",
25
- "test": "node --test scripts/animation-test.mjs scripts/starter-jobs-test.mjs scripts/cooking-nudge-test.mjs scripts/surface-chart-test.mjs scripts/south-expansion-test.mjs scripts/rudd-test.mjs scripts/cave-map-test.mjs scripts/birch-combat-test.mjs scripts/fort-rook-bosses-test.mjs scripts/bounty-first-test.mjs scripts/bounty-high-tiers-test.mjs scripts/running-test.mjs scripts/energy-test.mjs scripts/starter-town-test.mjs scripts/starter-expansion-test.mjs scripts/five-arches-test.mjs scripts/landing-test.mjs scripts/cove-ship-test.mjs scripts/south-fields-quests-test.mjs scripts/south-fields-errands-test.mjs scripts/arcane-lands-test.mjs scripts/fair-folk-test.mjs scripts/fair-contests-test.mjs scripts/missing-shipment-test.mjs scripts/world-boss-ring-test.mjs scripts/ringstone-fight-test.mjs scripts/highstone-test.mjs scripts/fenstone-test.mjs scripts/lair-awakening-test.mjs scripts/hopewood-wildlife-test.mjs scripts/hollin-wildlife-test.mjs scripts/hopewood-quests-test.mjs scripts/western-train-test.mjs scripts/moving-train-test.mjs scripts/train-circuit-test.mjs scripts/forge-halt-test.mjs scripts/forge-polish-test.mjs scripts/western-station-test.mjs scripts/hollin-quests-test.mjs scripts/western-lost-supplies-test.mjs scripts/western-herbal-remedies-test.mjs scripts/western-field-shrine-test.mjs scripts/western-kingdoms-test.mjs scripts/lantern-wake-test.mjs scripts/brindlecross-test.mjs scripts/brindlecross-quest-test.mjs scripts/greenwood-wilds-test.mjs scripts/greenwood-wildlife-test.mjs scripts/greenwood-quest-test.mjs scripts/dwarf-road-wildlife-test.mjs scripts/dwarf-road-test.mjs scripts/riversend-test.mjs scripts/riversend-content-test.mjs scripts/gatewarden-rounds-test.mjs scripts/boss-e8-test.mjs scripts/lantern-wake-town-test.mjs scripts/world-regions-test.mjs scripts/copse-wildlife-test.mjs scripts/copse-quests-test.mjs scripts/marches-wildlife-test.mjs scripts/marches-quests-test.mjs scripts/train-seats-test.mjs scripts/lantern-wake-gallery-test.mjs scripts/lantern-wake-wildlife-test.mjs scripts/lantern-wake-quest-test.mjs scripts/dwarf-hold-test.mjs scripts/western-line-texts-test.mjs scripts/xp-test.mjs scripts/bank-test.mjs scripts/timed-access-test.mjs scripts/ground-items-test.mjs scripts/name-filter-test.mjs scripts/woodwork-logs-test.mjs scripts/area-gates-test.mjs scripts/frozen-dungeons-test.mjs scripts/long-winter-test.mjs scripts/roster-delta-test.mjs scripts/bow-ladder-test.mjs scripts/lantern-wake-ledge-test.mjs scripts/explorer-ledger-test.mjs scripts/ore-smithing-test.mjs scripts/red-waste-test.mjs scripts/red-waste-folk-test.mjs scripts/daily-hooks-test.mjs scripts/sparring-yard-test.mjs scripts/t16-siege-floe-beach-test.mjs scripts/mammoth-road-test.mjs scripts/mammoth-road-test.mjs scripts/gulls-map-test.mjs scripts/gulls-rook-test.mjs scripts/ride-the-line-test.mjs scripts/gallowmere-test.mjs scripts/gallowmere-content-test.mjs scripts/fishing-derby-test.mjs scripts/sled-run-test.mjs scripts/eastern-marches-a-test.mjs scripts/windward-chalkshell-test.mjs scripts/gullhook-head-test.mjs scripts/webfen-test.mjs scripts/safe-pockets-test.mjs scripts/gallowmere-extras-test.mjs scripts/t53-high-ledge-skill-quests-test.mjs scripts/camp-traders-recommended-test.mjs scripts/west-coast-test.mjs scripts/heartwood-hunt-test.mjs scripts/calverton-extension-test.mjs scripts/gravewatch-test.mjs scripts/tide-of-blood-test.mjs scripts/north-wilds-test.mjs scripts/toll-road-test.mjs scripts/capital-quests-test.mjs",
26
- "dev": "tsc -p tsconfig.json --watch",
27
- "prepare": "npm run build",
28
- "prepublishOnly": "npm run build"
29
- },
30
- "devDependencies": {
31
- "typescript": "^5.9.2"
32
- },
33
- "repository": {
34
- "type": "git",
35
- "url": "https://github.com/JamesPhelps/dreadwoods-types.git"
36
- },
37
- "publishConfig": {
38
- "access": "public"
39
- },
40
- "engines": {
41
- "node": ">=22"
42
- }
43
- }
1
+ {
2
+ "name": "@dreadwood-types/types",
3
+ "version": "0.1.280",
4
+ "description": "Public wire protocol and client-safe constants for Dreadwoods",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "default": "./dist/index.js"
13
+ },
14
+ "./legacy": {
15
+ "types": "./dist/legacy.d.ts",
16
+ "import": "./dist/legacy.js",
17
+ "default": "./dist/legacy.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "scripts": {
24
+ "build": "tsc -p tsconfig.json",
25
+ "test": "node --test scripts/animation-test.mjs scripts/starter-jobs-test.mjs scripts/cooking-nudge-test.mjs scripts/surface-chart-test.mjs scripts/south-expansion-test.mjs scripts/rudd-test.mjs scripts/cave-map-test.mjs scripts/birch-combat-test.mjs scripts/fort-rook-bosses-test.mjs scripts/bounty-first-test.mjs scripts/bounty-high-tiers-test.mjs scripts/running-test.mjs scripts/energy-test.mjs scripts/starter-town-test.mjs scripts/starter-expansion-test.mjs scripts/five-arches-test.mjs scripts/landing-test.mjs scripts/cove-ship-test.mjs scripts/south-fields-quests-test.mjs scripts/south-fields-errands-test.mjs scripts/arcane-lands-test.mjs scripts/fair-folk-test.mjs scripts/fair-contests-test.mjs scripts/missing-shipment-test.mjs scripts/world-boss-ring-test.mjs scripts/ringstone-fight-test.mjs scripts/highstone-test.mjs scripts/fenstone-test.mjs scripts/lair-awakening-test.mjs scripts/hopewood-wildlife-test.mjs scripts/hollin-wildlife-test.mjs scripts/hopewood-quests-test.mjs scripts/western-train-test.mjs scripts/moving-train-test.mjs scripts/train-circuit-test.mjs scripts/forge-halt-test.mjs scripts/forge-polish-test.mjs scripts/western-station-test.mjs scripts/hollin-quests-test.mjs scripts/western-lost-supplies-test.mjs scripts/western-herbal-remedies-test.mjs scripts/western-field-shrine-test.mjs scripts/western-kingdoms-test.mjs scripts/lantern-wake-test.mjs scripts/brindlecross-test.mjs scripts/brindlecross-quest-test.mjs scripts/greenwood-wilds-test.mjs scripts/greenwood-wildlife-test.mjs scripts/greenwood-quest-test.mjs scripts/dwarf-road-wildlife-test.mjs scripts/dwarf-road-test.mjs scripts/riversend-test.mjs scripts/riversend-content-test.mjs scripts/gatewarden-rounds-test.mjs scripts/boss-e8-test.mjs scripts/lantern-wake-town-test.mjs scripts/world-regions-test.mjs scripts/copse-wildlife-test.mjs scripts/copse-quests-test.mjs scripts/marches-wildlife-test.mjs scripts/marches-quests-test.mjs scripts/train-seats-test.mjs scripts/lantern-wake-gallery-test.mjs scripts/lantern-wake-wildlife-test.mjs scripts/lantern-wake-quest-test.mjs scripts/dwarf-hold-test.mjs scripts/western-line-texts-test.mjs scripts/xp-test.mjs scripts/bank-test.mjs scripts/timed-access-test.mjs scripts/ground-items-test.mjs scripts/name-filter-test.mjs scripts/woodwork-logs-test.mjs scripts/area-gates-test.mjs scripts/frozen-dungeons-test.mjs scripts/long-winter-test.mjs scripts/roster-delta-test.mjs scripts/bow-ladder-test.mjs scripts/lantern-wake-ledge-test.mjs scripts/explorer-ledger-test.mjs scripts/ore-smithing-test.mjs scripts/red-waste-test.mjs scripts/red-waste-folk-test.mjs scripts/daily-hooks-test.mjs scripts/sparring-yard-test.mjs scripts/t16-siege-floe-beach-test.mjs scripts/mammoth-road-test.mjs scripts/mammoth-road-test.mjs scripts/gulls-map-test.mjs scripts/gulls-rook-test.mjs scripts/ride-the-line-test.mjs scripts/gallowmere-test.mjs scripts/gallowmere-content-test.mjs scripts/fishing-derby-test.mjs scripts/sled-run-test.mjs scripts/eastern-marches-a-test.mjs scripts/windward-chalkshell-test.mjs scripts/gullhook-head-test.mjs scripts/webfen-test.mjs scripts/safe-pockets-test.mjs scripts/gallowmere-extras-test.mjs scripts/t53-high-ledge-skill-quests-test.mjs scripts/camp-traders-recommended-test.mjs scripts/west-coast-test.mjs scripts/heartwood-hunt-test.mjs scripts/calverton-extension-test.mjs scripts/gravewatch-test.mjs scripts/tide-of-blood-test.mjs scripts/north-wilds-test.mjs scripts/toll-road-test.mjs scripts/capital-quests-test.mjs scripts/lean-wanted-test.mjs scripts/delvers-ladder-test.mjs",
26
+ "dev": "tsc -p tsconfig.json --watch",
27
+ "prepare": "npm run build",
28
+ "prepublishOnly": "npm run build"
29
+ },
30
+ "devDependencies": {
31
+ "typescript": "^5.9.2"
32
+ },
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "https://github.com/JamesPhelps/dreadwoods-types.git"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "engines": {
41
+ "node": ">=22"
42
+ }
43
+ }