@adatechnology/game-items 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +83 -2
- package/dist/index.d.ts +755 -0
- package/dist/index.global.js +790 -0
- package/dist/index.global.js.map +1 -0
- package/dist/index.js +737 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -3
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,755 @@
|
|
|
1
|
+
import { BodySlot, DeepPartial } from '@adatechnology/game-contracts';
|
|
2
|
+
export { BodySlot } from '@adatechnology/game-contracts';
|
|
3
|
+
import { ItemDef as ItemDef$1, rng, ItemStack, SlotSpec, LootTables } from '@adatechnology/game-interactables';
|
|
4
|
+
export { ItemDef as BaseItemDef } from '@adatechnology/game-interactables';
|
|
5
|
+
|
|
6
|
+
/** Traits that pick any item of the catalog ("1 clothing" is any item of the category, "ingredients" is anything cookable). */
|
|
7
|
+
interface RecipeMatch {
|
|
8
|
+
readonly category?: string;
|
|
9
|
+
readonly cookable?: true;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* What a recipe consumes: one item, one of several (`any`), a fluid in `liters`, a thing of the world that is only near (`world`: furniture, ground) or any item
|
|
13
|
+
* with some traits (`match`). `qty` defaults to 1; `meters` marks a length taken from the item (the host measures it).
|
|
14
|
+
*/
|
|
15
|
+
interface RecipeInput {
|
|
16
|
+
item?: string;
|
|
17
|
+
any?: readonly string[];
|
|
18
|
+
fluid?: string;
|
|
19
|
+
world?: readonly string[];
|
|
20
|
+
match?: RecipeMatch;
|
|
21
|
+
qty?: number;
|
|
22
|
+
liters?: number;
|
|
23
|
+
meters?: number;
|
|
24
|
+
label?: string;
|
|
25
|
+
}
|
|
26
|
+
/** A tool requirement: one of `anyOf` must be in the inventory, and a station of `world` (a fire) must be near; both empty is bare hands. Tools are not consumed. */
|
|
27
|
+
interface RecipeTool {
|
|
28
|
+
anyOf: readonly string[];
|
|
29
|
+
world?: readonly string[];
|
|
30
|
+
label?: string;
|
|
31
|
+
}
|
|
32
|
+
type RecipeOutput = {
|
|
33
|
+
item: string;
|
|
34
|
+
qty: readonly [number, number];
|
|
35
|
+
label?: string;
|
|
36
|
+
note?: string;
|
|
37
|
+
} | {
|
|
38
|
+
effect: string;
|
|
39
|
+
params: Readonly<Record<string, unknown>>;
|
|
40
|
+
text?: string;
|
|
41
|
+
};
|
|
42
|
+
interface RecipeDef {
|
|
43
|
+
id: string;
|
|
44
|
+
inputs: readonly RecipeInput[];
|
|
45
|
+
tools: readonly RecipeTool[];
|
|
46
|
+
skill?: {
|
|
47
|
+
id: string;
|
|
48
|
+
level: number;
|
|
49
|
+
};
|
|
50
|
+
seconds: number;
|
|
51
|
+
/** Id of something the character must have unlocked first (a magazine read, a blueprint). Checked only when the host passes `unlocked`. */
|
|
52
|
+
unlockedBy?: string;
|
|
53
|
+
output: RecipeOutput;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** One way of using an item, read from the team's `useItem`: which items or categories trigger it and what it does. */
|
|
57
|
+
interface UseEffectDef {
|
|
58
|
+
id: string;
|
|
59
|
+
/** Id of the effect the host applies (`consume_nutrition`, `stop_bleeding`, `heal`, `calm`, `clean_wound`, `assemble_molotov`, `toggle_light`, `swap_bag`, `equip_melee`). */
|
|
60
|
+
effect: string;
|
|
61
|
+
params?: Readonly<Record<string, unknown>>;
|
|
62
|
+
/** The item is spent when used. */
|
|
63
|
+
consumes: boolean;
|
|
64
|
+
/** Items that trigger it, by id; wins over `category`. */
|
|
65
|
+
items?: readonly string[];
|
|
66
|
+
category?: readonly ItemCategory[];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Public types of @adatechnology/game-items.
|
|
71
|
+
*
|
|
72
|
+
* An `ItemDef` is a real-world thing (a can of beans, a hammer, a jacket) with its true size and weight; the rest of the fields are optional groups that
|
|
73
|
+
* only the categories that need them fill (nutrition for food, protection for clothing, carry for bags). Units: metres, kilograms, litres, days.
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
declare const RARITIES: readonly ["common", "uncommon", "rare", "very_rare", "legendary", "unique"];
|
|
77
|
+
type Rarity = (typeof RARITIES)[number];
|
|
78
|
+
|
|
79
|
+
declare const BODY_SLOTS: readonly BodySlot[];
|
|
80
|
+
declare const DURABILITY_KINDS: readonly ["uses", "portions", "doses", "hits", "cuts", "shots", "condition", "charges", "seconds", "days", "infinite", "container"];
|
|
81
|
+
type DurabilityKind = (typeof DURABILITY_KINDS)[number];
|
|
82
|
+
/** How long an item lasts, read from the source text ("10 uses", "4 portions", "300 hits", "infinite"). */
|
|
83
|
+
interface Durability {
|
|
84
|
+
kind: DurabilityKind;
|
|
85
|
+
amount?: number;
|
|
86
|
+
/** Source qualifier when the amount alone is not enough (for example the voltage of a battery). */
|
|
87
|
+
per?: string;
|
|
88
|
+
}
|
|
89
|
+
/** Id of a place where items turn up (house, hospital, farm...). Places are a registry: a pack or the game declares the ones it uses. */
|
|
90
|
+
type PlaceTag = string;
|
|
91
|
+
/** Id of an item category. The 14 of `ITEM_CATEGORIES` are always present; a game adds its own through `createItems({ categories })`. */
|
|
92
|
+
type ItemCategory = string;
|
|
93
|
+
interface CategoryDef {
|
|
94
|
+
id: ItemCategory;
|
|
95
|
+
/** Display name in English; games translate by id. */
|
|
96
|
+
name?: string;
|
|
97
|
+
}
|
|
98
|
+
interface PlaceDef {
|
|
99
|
+
id: PlaceTag;
|
|
100
|
+
name?: string;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Where items are found inside a place (a fridge, a drawer, a locker): which categories it draws from and how many stacks. The finds roll reads `count`,
|
|
104
|
+
* `categories` (or `categoriesByPlace`, with `*` for any other place) and `places`; other fields of a pack's container are kept and ignored.
|
|
105
|
+
*/
|
|
106
|
+
interface ContainerDef {
|
|
107
|
+
id: string;
|
|
108
|
+
name?: string;
|
|
109
|
+
/** Places the container turns up in (`toLootTables` only); empty or missing means any. */
|
|
110
|
+
places?: readonly PlaceTag[];
|
|
111
|
+
/** Weight of each category when a stack is drawn for this container. */
|
|
112
|
+
categories?: Readonly<Record<ItemCategory, number>>;
|
|
113
|
+
/** When `categories` is missing: the weights by place (a shop shelf stocks what the shop sells). */
|
|
114
|
+
categoriesByPlace?: Readonly<Record<PlaceTag, Readonly<Record<ItemCategory, number>>>>;
|
|
115
|
+
/** Range of stacks a container holds when it is filled. */
|
|
116
|
+
count?: readonly [number, number];
|
|
117
|
+
}
|
|
118
|
+
/** One thing an explicit pool can hold (a fridge: water bottle, milk, eggs...): `item` is the catalog id, `weight` the odds, `qty` the range. */
|
|
119
|
+
interface PoolEntry {
|
|
120
|
+
item: string;
|
|
121
|
+
weight: number;
|
|
122
|
+
qty: readonly [number, number];
|
|
123
|
+
/** Supplies (food, water, medicine, tools) are what a fortified house stocks up on. */
|
|
124
|
+
isSupply?: boolean;
|
|
125
|
+
}
|
|
126
|
+
interface ItemDef extends ItemDef$1 {
|
|
127
|
+
category: ItemCategory;
|
|
128
|
+
/** The old household category (`kitchen`, `hygiene`, `office`...), `perishable` or `craft_only`. */
|
|
129
|
+
tags?: readonly string[];
|
|
130
|
+
rarity: Rarity;
|
|
131
|
+
/** Litres. Derived from `size` when the pack does not give it. */
|
|
132
|
+
volume?: number;
|
|
133
|
+
durability?: Durability;
|
|
134
|
+
/** Days to spoil at room temperature. */
|
|
135
|
+
shelfLife?: number;
|
|
136
|
+
portions?: number;
|
|
137
|
+
cookable?: boolean;
|
|
138
|
+
nutrition?: {
|
|
139
|
+
satiety?: number;
|
|
140
|
+
hydration?: number;
|
|
141
|
+
};
|
|
142
|
+
/** Fractions 0..1 per attack, per body slot covered. */
|
|
143
|
+
protection?: {
|
|
144
|
+
slots: readonly BodySlot[];
|
|
145
|
+
bite?: number;
|
|
146
|
+
scratch?: number;
|
|
147
|
+
warmth?: number;
|
|
148
|
+
/** Against projectiles (read by game-characters): `resistance` in penetration units; a stopped projectile does `blunt` of its damage, one that goes through `pass`. */
|
|
149
|
+
ballistic?: {
|
|
150
|
+
resistance: number;
|
|
151
|
+
blunt?: number;
|
|
152
|
+
pass?: number;
|
|
153
|
+
consumable?: boolean;
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
carry?: {
|
|
157
|
+
capacityKg: number;
|
|
158
|
+
weightReduction: number;
|
|
159
|
+
quickSlots: number;
|
|
160
|
+
wheels?: boolean;
|
|
161
|
+
};
|
|
162
|
+
/** Id of the weapon in the arsenal when the item is also one. */
|
|
163
|
+
weapon?: string;
|
|
164
|
+
/** Id of the liquid (`game-fluids`) when the item holds one. */
|
|
165
|
+
fluid?: {
|
|
166
|
+
liquid: string;
|
|
167
|
+
liters: number;
|
|
168
|
+
};
|
|
169
|
+
uses?: readonly string[];
|
|
170
|
+
finds?: {
|
|
171
|
+
places: readonly PlaceTag[];
|
|
172
|
+
};
|
|
173
|
+
/** Battery-like items: share of the charge lost per month. */
|
|
174
|
+
charge?: {
|
|
175
|
+
lossPerMonth: number;
|
|
176
|
+
};
|
|
177
|
+
/** Fuel-like items: after `afterDays` each use fails with probability `chance`. */
|
|
178
|
+
agingFault?: {
|
|
179
|
+
afterDays: number;
|
|
180
|
+
chance: number;
|
|
181
|
+
};
|
|
182
|
+
/** Key of the 3D model in `game-items-three`; without it a simple shape from `shape` is drawn. */
|
|
183
|
+
model?: string;
|
|
184
|
+
}
|
|
185
|
+
/** A bundle of content: items plus the categories, places and containers they rely on. */
|
|
186
|
+
interface ItemPack {
|
|
187
|
+
id: string;
|
|
188
|
+
items: readonly ItemDef[];
|
|
189
|
+
categories?: readonly CategoryDef[];
|
|
190
|
+
places?: readonly PlaceDef[];
|
|
191
|
+
containers?: readonly ContainerDef[];
|
|
192
|
+
/** What using an item does, in priority order (`resolveUse`). */
|
|
193
|
+
useEffects?: readonly UseEffectDef[];
|
|
194
|
+
recipes?: readonly RecipeDef[];
|
|
195
|
+
/** Explicit pools of what a kind of furniture holds, by key (`fridge`, `sink`...); they win over the category roll of a container. */
|
|
196
|
+
pools?: Readonly<Record<string, readonly PoolEntry[]>>;
|
|
197
|
+
/** Keys that share another key's pool (`garage_wardrobe` -> `wardrobe`). */
|
|
198
|
+
poolAliases?: Readonly<Record<string, string>>;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** What a find is in: the plain world, a fortified house (stocked up) or an abandoned one (already picked over). */
|
|
202
|
+
type FindState = 'normal' | 'fortified' | 'abandoned';
|
|
203
|
+
/** Places whose stock falls with the days of the outbreak: `max(floor, 1 - perDay x days)` of the normal count, never below `floor`. */
|
|
204
|
+
interface DepletionRule {
|
|
205
|
+
places: readonly PlaceTag[];
|
|
206
|
+
perDay: number;
|
|
207
|
+
floor: number;
|
|
208
|
+
}
|
|
209
|
+
/** Where an item is stored; ids of `StorageRules`. A game adds its own. */
|
|
210
|
+
type StorageId = string;
|
|
211
|
+
interface StorageRule {
|
|
212
|
+
/** How much faster (above 1) or slower (below 1) the item ages there. */
|
|
213
|
+
multiplier: number;
|
|
214
|
+
/** The multiplier only holds while the place has power (fridge, freezer); without it the item ages at the ambient rate. */
|
|
215
|
+
needsPower?: boolean;
|
|
216
|
+
/** The multiplier holds for this many days only, then `afterLimit` applies (a cooler with ice). */
|
|
217
|
+
limitDays?: number;
|
|
218
|
+
afterLimit?: number;
|
|
219
|
+
}
|
|
220
|
+
type StorageRules = Readonly<Record<StorageId, StorageRule>>;
|
|
221
|
+
/** What eating food does once it is past its best; one entry per freshness state after `fresh`. */
|
|
222
|
+
interface FreshnessEffect {
|
|
223
|
+
/** Multiplies the satiety and hydration the food gives. */
|
|
224
|
+
satietyFactor: number;
|
|
225
|
+
/** Chance of food poisoning. */
|
|
226
|
+
poisonChance: number;
|
|
227
|
+
/** Morale change (negative hurts). */
|
|
228
|
+
morale: number;
|
|
229
|
+
/** False when the food cannot be eaten at all. */
|
|
230
|
+
isEdible: boolean;
|
|
231
|
+
}
|
|
232
|
+
interface ItemRules {
|
|
233
|
+
rarity: {
|
|
234
|
+
/** Draw weight of each rarity when a stack is rolled. */
|
|
235
|
+
weights: Readonly<Record<Rarity, number>>;
|
|
236
|
+
/** Rarities that only turn up at fixed spots, never in a roll. */
|
|
237
|
+
fixedOnly: readonly Rarity[];
|
|
238
|
+
};
|
|
239
|
+
/** Where `fresh` ends and `stale`, `spoiled` and `rotten` begin, as fractions of `shelfLife`. */
|
|
240
|
+
freshness: {
|
|
241
|
+
stale: number;
|
|
242
|
+
spoiled: number;
|
|
243
|
+
rotten: number;
|
|
244
|
+
};
|
|
245
|
+
storage: StorageRules;
|
|
246
|
+
carry: {
|
|
247
|
+
/** `(baseKg + perStrengthKg × strength) × factor`. */
|
|
248
|
+
baseKg: number;
|
|
249
|
+
perStrengthKg: number;
|
|
250
|
+
factor: number;
|
|
251
|
+
/** Fractions of the maximum load: above `encumbered` the carrier is slowed, above `overloaded` it cannot run. */
|
|
252
|
+
encumbered: number;
|
|
253
|
+
overloaded: number;
|
|
254
|
+
};
|
|
255
|
+
protection: {
|
|
256
|
+
/** Highest share of an attack clothing can block: there is always some risk. */
|
|
257
|
+
cap: number;
|
|
258
|
+
/** Condition a blocked attack costs the piece. */
|
|
259
|
+
wear: {
|
|
260
|
+
bite: number;
|
|
261
|
+
scratch: number;
|
|
262
|
+
};
|
|
263
|
+
/** Share of its value a torn piece (condition 0) still protects. */
|
|
264
|
+
tornShare: number;
|
|
265
|
+
/** A repair kit restores up to the maximum condition minus this. */
|
|
266
|
+
repairMargin: number;
|
|
267
|
+
};
|
|
268
|
+
aging: {
|
|
269
|
+
/** Storage with power -> days of shelf life a food keeps when the power fails (a thawed freezer counts as fresh with 2 days to go). */
|
|
270
|
+
thawShelfDays: Readonly<Record<StorageId, number>>;
|
|
271
|
+
};
|
|
272
|
+
inventory: {
|
|
273
|
+
/** Slots of a character's bag when no bag item says otherwise. */
|
|
274
|
+
defaultSlots: number;
|
|
275
|
+
/** Running speed and breath multiplier while carrying more than `carry.encumbered` of the maximum. */
|
|
276
|
+
encumberedRunFactor: number;
|
|
277
|
+
};
|
|
278
|
+
use: {
|
|
279
|
+
freshness: Readonly<Record<'stale' | 'spoiled' | 'rotten', FreshnessEffect>>;
|
|
280
|
+
/** Cooking the food leaves this share of its poison chance. */
|
|
281
|
+
cookedPoisonFactor: number;
|
|
282
|
+
};
|
|
283
|
+
spawn: {
|
|
284
|
+
/** On day 0 of the outbreak, stock on shelves in these places appears brand new (condition 100) instead of in the team's ranges. */
|
|
285
|
+
retailNew: boolean;
|
|
286
|
+
retailPlaces: readonly PlaceTag[];
|
|
287
|
+
/** Containers that count as shelf or stock room inside a retail place; empty means every container of the place. */
|
|
288
|
+
retailContainers: readonly string[];
|
|
289
|
+
/** Condition (0..100) of a found item with wear, by rarity: `[low, high]`. */
|
|
290
|
+
condition: Readonly<Record<Rarity, readonly [number, number]>>;
|
|
291
|
+
/** Found food is already old: the days since the outbreak plus this share of its shelf life, `[low, high]`. */
|
|
292
|
+
ageShare: readonly [number, number];
|
|
293
|
+
/** Charge (0..1) of found batteries. */
|
|
294
|
+
charge: readonly [number, number];
|
|
295
|
+
/** Items found partly filled (a jerrycan) and how full, 0..1. */
|
|
296
|
+
fillable: readonly string[];
|
|
297
|
+
fill: readonly [number, number];
|
|
298
|
+
};
|
|
299
|
+
finds: {
|
|
300
|
+
/** The container whose table a container unknown to the catalog uses (the team's game falls back to a corpse). */
|
|
301
|
+
fallbackContainer: string;
|
|
302
|
+
/** Ids left out of the roll by category (the game never rolls the 7.62x39 box). */
|
|
303
|
+
rollExcluded: readonly string[];
|
|
304
|
+
depletion: readonly DepletionRule[];
|
|
305
|
+
/** Multiplies the count of a place, by region id. */
|
|
306
|
+
regionMultiplier: Readonly<Record<string, number>>;
|
|
307
|
+
/** Maps the state a host passes to one of the three the finds know. */
|
|
308
|
+
states: Readonly<Record<string, FindState>>;
|
|
309
|
+
/** The numbers of the explicit house pools (the 3D viewer's `sorteiaConteudo`). */
|
|
310
|
+
pool: {
|
|
311
|
+
/** Footprint (m²) used when the query gives none. */
|
|
312
|
+
defaultFootprint: number;
|
|
313
|
+
/** Count of a normal container: `clamp(round(offset + footprint x perSquareMetre + random x jitter), min, max)`. */
|
|
314
|
+
offset: number;
|
|
315
|
+
perSquareMetre: number;
|
|
316
|
+
jitter: number;
|
|
317
|
+
min: number;
|
|
318
|
+
max: number;
|
|
319
|
+
/** Fortified: this many more entries (up to the pool size), supplies weigh `supplyWeight` times and give `supplyExtraQty` more. */
|
|
320
|
+
fortifiedExtra: number;
|
|
321
|
+
supplyWeight: number;
|
|
322
|
+
supplyExtraQty: number;
|
|
323
|
+
/** Abandoned: this chance of being empty, otherwise `abandonedKept` entries. */
|
|
324
|
+
abandonedEmptyChance: number;
|
|
325
|
+
abandonedKept: number;
|
|
326
|
+
/** Abandoned and empty: this chance of leaving a bit of junk. */
|
|
327
|
+
junkChance: number;
|
|
328
|
+
junkItem: string;
|
|
329
|
+
/** Abandoned fridges and freezers also hold this, gone bad. */
|
|
330
|
+
spoiledFoodItem: string;
|
|
331
|
+
coldContainers: readonly string[];
|
|
332
|
+
};
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
interface ItemsOptions {
|
|
337
|
+
/** Content bundles, merged in order (a later item replaces one with the same id). */
|
|
338
|
+
packs?: readonly ItemPack[];
|
|
339
|
+
/** Changes to items, by id, applied after the packs are merged; `size`, `nutrition`, `protection`... merge field by field, arrays replace. */
|
|
340
|
+
patch?: Readonly<Record<string, DeepPartial<Omit<ItemDef, 'id'>>>>;
|
|
341
|
+
/** Ids to take out after the patches. */
|
|
342
|
+
remove?: readonly string[];
|
|
343
|
+
/** Keeps only the items it returns true for, after `remove`. */
|
|
344
|
+
include?: (item: ItemDef) => boolean;
|
|
345
|
+
/** Extra categories, places and containers, added to those of the packs (by id). */
|
|
346
|
+
categories?: readonly CategoryDef[];
|
|
347
|
+
places?: readonly PlaceDef[];
|
|
348
|
+
containers?: readonly ContainerDef[];
|
|
349
|
+
useEffects?: readonly UseEffectDef[];
|
|
350
|
+
recipes?: readonly RecipeDef[];
|
|
351
|
+
pools?: ItemPack['pools'];
|
|
352
|
+
poolAliases?: ItemPack['poolAliases'];
|
|
353
|
+
rules?: DeepPartial<ItemRules>;
|
|
354
|
+
}
|
|
355
|
+
interface ItemsCatalog {
|
|
356
|
+
readonly items: ReadonlyMap<string, ItemDef>;
|
|
357
|
+
readonly categories: ReadonlyMap<ItemCategory, CategoryDef>;
|
|
358
|
+
readonly places: ReadonlyMap<PlaceTag, PlaceDef>;
|
|
359
|
+
readonly containers: ReadonlyMap<string, ContainerDef>;
|
|
360
|
+
/** Explicit pools by key, with the aliases already resolved. */
|
|
361
|
+
readonly pools: ReadonlyMap<string, readonly PoolEntry[]>;
|
|
362
|
+
readonly useEffects: readonly UseEffectDef[];
|
|
363
|
+
readonly recipes: ReadonlyMap<string, RecipeDef>;
|
|
364
|
+
readonly rules: ItemRules;
|
|
365
|
+
has(id: string): boolean;
|
|
366
|
+
/** Throws on an unknown id. */
|
|
367
|
+
get(id: string): ItemDef;
|
|
368
|
+
list(): ItemDef[];
|
|
369
|
+
byCategory(category: ItemCategory): ItemDef[];
|
|
370
|
+
/** Items that can be found in `place` (`finds.places`). */
|
|
371
|
+
byPlace(place: PlaceTag): ItemDef[];
|
|
372
|
+
byTag(tag: string): ItemDef[];
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Create the catalog. Order: the packs in order (added or replaced by id), then `patch`, then `remove`, then `include`; categories, places and
|
|
377
|
+
* containers are those of the packs plus the options, by id. Every inconsistency found is reported in one error.
|
|
378
|
+
*/
|
|
379
|
+
declare const createItems: (options?: ItemsOptions) => ItemsCatalog;
|
|
380
|
+
|
|
381
|
+
interface ItemsParts {
|
|
382
|
+
readonly items: ReadonlyMap<string, ItemDef>;
|
|
383
|
+
readonly categories: ReadonlyMap<string, CategoryDef>;
|
|
384
|
+
readonly places: ReadonlyMap<string, PlaceDef>;
|
|
385
|
+
readonly containers: ReadonlyMap<string, ContainerDef>;
|
|
386
|
+
readonly rules: ItemRules;
|
|
387
|
+
}
|
|
388
|
+
/** Every inconsistency of a catalog, one line each; empty when it is sound. */
|
|
389
|
+
declare const checkItems: (parts: ItemsParts) => string[];
|
|
390
|
+
|
|
391
|
+
/** The 14 categories of the team's catalog; always registered. */
|
|
392
|
+
declare const ITEM_CATEGORIES: readonly CategoryDef[];
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* The numbers of the rules, from the team's Vale Cinzento delivery. `storage` was read by hand from its table (Validade e apodrecimento) so the
|
|
396
|
+
* skeleton runs; the source test of the catalog tool proves it against the HTML (legendary and unique are never rolled: L276). Every field is an option of `createItems({ rules })`.
|
|
397
|
+
*/
|
|
398
|
+
declare const DEFAULT_RULES: ItemRules;
|
|
399
|
+
|
|
400
|
+
type Freshness = 'fresh' | 'stale' | 'spoiled' | 'rotten';
|
|
401
|
+
/**
|
|
402
|
+
* What an item remembers about its age. Nothing ticks: the account is closed lazily, when the item moves or someone looks at it.
|
|
403
|
+
* Times are in days on the host's clock.
|
|
404
|
+
*/
|
|
405
|
+
interface AgeState {
|
|
406
|
+
/** Effective age: days at room temperature. */
|
|
407
|
+
ageDays: number;
|
|
408
|
+
/** Time at which `ageDays` was last closed. */
|
|
409
|
+
since: number;
|
|
410
|
+
storage: StorageId;
|
|
411
|
+
/** Time at which the item entered `storage` (a cooler only helps for its first days). */
|
|
412
|
+
storedAt: number;
|
|
413
|
+
/** Replaces the item's shelf life (a thawed freezer leaves 2 days). */
|
|
414
|
+
shelfLife?: number;
|
|
415
|
+
}
|
|
416
|
+
interface AgeOptions {
|
|
417
|
+
/** Whether the storage has power right now (fridge, freezer). Default true. */
|
|
418
|
+
powered?: boolean;
|
|
419
|
+
rules?: ItemRules;
|
|
420
|
+
}
|
|
421
|
+
/** The multiplier of the age at one instant: `heldDays` is how long the item has been in `storage`. */
|
|
422
|
+
declare const storageMultiplier: (storage: StorageId, options?: AgeOptions & {
|
|
423
|
+
heldDays?: number;
|
|
424
|
+
}) => number;
|
|
425
|
+
/** Closes the account up to `now`: `ageDays += (now - since) x multiplier`. Pure: returns the new state. */
|
|
426
|
+
declare const advanceAge: (state: AgeState, now: number, options?: AgeOptions) => AgeState;
|
|
427
|
+
/** Moves the item to another storage: closes the account in the old one, then the new multiplier applies from `now`. */
|
|
428
|
+
declare const moveToStorage: (state: AgeState, now: number, storage: StorageId, options?: AgeOptions) => AgeState;
|
|
429
|
+
/** Age as a share of the shelf life; 0 for an item that does not spoil. */
|
|
430
|
+
declare const shelfRatio: (item: ItemDef, state: AgeState) => number;
|
|
431
|
+
/** `fresh`, `stale`, `spoiled` or `rotten` at 0.5, 1 and 1.5 of the shelf life (the rule's `freshness`). Closes the account up to `now` first. */
|
|
432
|
+
declare const freshness: (item: ItemDef, state: AgeState, now: number, options?: AgeOptions) => Freshness;
|
|
433
|
+
/** Charge left (0..1) of a battery-like item: it loses `charge.lossPerMonth` of the full charge per 30 days of effective age. */
|
|
434
|
+
declare const chargeLevel: (item: ItemDef, initialCharge: number, ageDays: number) => number;
|
|
435
|
+
/** True when one use of an old fuel-like item fails: past `agingFault.afterDays` each use fails with probability `chance`. Draws once, only when it can fail. */
|
|
436
|
+
declare const failsToStart: (item: ItemDef, ageDays: number, random: () => number) => boolean;
|
|
437
|
+
|
|
438
|
+
type AttackKind = 'bite' | 'scratch';
|
|
439
|
+
/** A piece of clothing on a body: the item and its condition, 0 (torn) to 100 (new). */
|
|
440
|
+
interface WornPiece {
|
|
441
|
+
item: ItemDef;
|
|
442
|
+
condition: number;
|
|
443
|
+
}
|
|
444
|
+
/** What one piece blocks of an attack: its value times its condition; a torn piece (condition 0) keeps `tornShare` of the value. */
|
|
445
|
+
declare const pieceBlock: (piece: WornPiece, attack: AttackKind, rules?: ItemRules) => number;
|
|
446
|
+
/** Share of an attack on `slot` that clothing blocks: `1 - PROD(1 - value x condition)`, never above the cap (there is always some risk). */
|
|
447
|
+
declare const blockChance: (pieces: readonly WornPiece[], slot: BodySlot, attack: AttackKind, rules?: ItemRules) => number;
|
|
448
|
+
/** A blocked attack wears every piece that covers the slot and blocks something: bite -8, scratch -3 (never below 0). */
|
|
449
|
+
declare const wearBlocked: (pieces: readonly WornPiece[], slot: BodySlot, attack: AttackKind, rules?: ItemRules) => WornPiece[];
|
|
450
|
+
/** A repair kit restores up to the maximum condition minus the margin (10); a piece already better is left alone. */
|
|
451
|
+
declare const repairPiece: (piece: WornPiece, rules?: ItemRules, maxCondition?: number) => WornPiece;
|
|
452
|
+
|
|
453
|
+
interface CarryEntry {
|
|
454
|
+
item: ItemDef;
|
|
455
|
+
count: number;
|
|
456
|
+
}
|
|
457
|
+
type LoadLevel = 'normal' | 'encumbered' | 'overloaded';
|
|
458
|
+
interface LoadState {
|
|
459
|
+
/** Load as a share of the maximum. */
|
|
460
|
+
ratio: number;
|
|
461
|
+
level: LoadLevel;
|
|
462
|
+
/** Multiplier of running speed and breath. */
|
|
463
|
+
runFactor: number;
|
|
464
|
+
canRun: boolean;
|
|
465
|
+
}
|
|
466
|
+
/** What a character can carry, kg: `(8 + 2.5 x strength) x 1.2` with the default rules. */
|
|
467
|
+
declare const maxLoadKg: (strength: number, rules?: ItemRules) => number;
|
|
468
|
+
/** Weight carried: what is outside the bag counts in full, what is inside counts times `(1 - weightReduction)`. */
|
|
469
|
+
declare const carriedKg: (parts: {
|
|
470
|
+
loose: readonly CarryEntry[];
|
|
471
|
+
packed?: readonly CarryEntry[];
|
|
472
|
+
weightReduction?: number;
|
|
473
|
+
}) => number;
|
|
474
|
+
/** Above 100% of the maximum, running and breath drop 25%; above 150% the character cannot run. */
|
|
475
|
+
declare const loadState: (loadKg: number, maxKg: number, rules?: ItemRules) => LoadState;
|
|
476
|
+
/** The bag of a character: how many item slots it has and how much it holds. */
|
|
477
|
+
interface BagOption {
|
|
478
|
+
slots: number;
|
|
479
|
+
capacityKg: number;
|
|
480
|
+
}
|
|
481
|
+
/** The bag a bag item gives: its `carry.capacityKg` is the slot count the team's game reads from `cap`; the weight limit is the character's. */
|
|
482
|
+
declare const bagOption: (bag: ItemDef | undefined, characterMaxKg: number, rules?: ItemRules) => BagOption;
|
|
483
|
+
type TakeResult = 'ok' | 'bag_full' | 'too_heavy';
|
|
484
|
+
/** Whether `item` can go into the bag now: first the slots, then the weight. */
|
|
485
|
+
declare const canTake: (item: ItemDef, bag: BagOption, used: {
|
|
486
|
+
slots: number;
|
|
487
|
+
loadKg: number;
|
|
488
|
+
}) => TakeResult;
|
|
489
|
+
|
|
490
|
+
interface UseContext {
|
|
491
|
+
/** State of the food, from `freshness()`. Default `fresh`. */
|
|
492
|
+
freshness?: Freshness;
|
|
493
|
+
/** The food was cooked: it keeps only `cookedPoisonFactor` of its poison chance. */
|
|
494
|
+
isCooked?: boolean;
|
|
495
|
+
}
|
|
496
|
+
interface NutritionResult {
|
|
497
|
+
satiety: number;
|
|
498
|
+
hydration: number;
|
|
499
|
+
morale: number;
|
|
500
|
+
poisonChance: number;
|
|
501
|
+
isEdible: boolean;
|
|
502
|
+
}
|
|
503
|
+
interface UseResult {
|
|
504
|
+
useId: string;
|
|
505
|
+
effect: string;
|
|
506
|
+
params: Readonly<Record<string, unknown>>;
|
|
507
|
+
/** The item is spent (false for food too rotten to eat). */
|
|
508
|
+
consumes: boolean;
|
|
509
|
+
/** Only for `consume_nutrition`. */
|
|
510
|
+
nutrition?: NutritionResult;
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* What using `item` does, as data: the host applies it (the player, the needs, the world). Pure. The first effect that lists the item wins, then the first
|
|
514
|
+
* that lists its category; `undefined` when nothing happens. Food past its best follows `rules.use.freshness`.
|
|
515
|
+
*/
|
|
516
|
+
declare const resolveUse: (item: ItemDef, effects: readonly UseEffectDef[], context?: UseContext, rules?: ItemRules) => UseResult | undefined;
|
|
517
|
+
|
|
518
|
+
interface CraftContext {
|
|
519
|
+
catalog: ItemsCatalog;
|
|
520
|
+
/** Count of each item the character has, by id. */
|
|
521
|
+
inventory: ReadonlyMap<string, number>;
|
|
522
|
+
/** Litres of each fluid at hand, by fluid id. */
|
|
523
|
+
fluids?: Readonly<Record<string, number>>;
|
|
524
|
+
/** Stations and things of the world that are near (`fire`, `table`, `soil`). */
|
|
525
|
+
world?: ReadonlySet<string>;
|
|
526
|
+
/** Skill levels by id. Without it the skill requirement is ignored. */
|
|
527
|
+
skills?: Readonly<Record<string, number>>;
|
|
528
|
+
/** Ids unlocked so far. Without it `unlockedBy` is ignored. */
|
|
529
|
+
unlocked?: ReadonlySet<string>;
|
|
530
|
+
}
|
|
531
|
+
interface CraftCheck {
|
|
532
|
+
isPossible: boolean;
|
|
533
|
+
/** One entry per unmet requirement: `item:nails`, `any:salt|sugar`, `match:cookable`, `fluid:water`, `world:fire`, `tool:hammer|axe`, `skill:carpentry:2`, `unlock:magazine`. */
|
|
534
|
+
missing: string[];
|
|
535
|
+
}
|
|
536
|
+
type Consumption = {
|
|
537
|
+
item: string;
|
|
538
|
+
count: number;
|
|
539
|
+
meters?: number;
|
|
540
|
+
} | {
|
|
541
|
+
fluid: string;
|
|
542
|
+
liters: number;
|
|
543
|
+
};
|
|
544
|
+
type CraftOutcome = {
|
|
545
|
+
item: string;
|
|
546
|
+
count: number;
|
|
547
|
+
} | {
|
|
548
|
+
effect: string;
|
|
549
|
+
params: Readonly<Record<string, unknown>>;
|
|
550
|
+
text?: string;
|
|
551
|
+
};
|
|
552
|
+
type CraftResult = {
|
|
553
|
+
isCrafted: true;
|
|
554
|
+
seconds: number;
|
|
555
|
+
consumed: Consumption[];
|
|
556
|
+
output: CraftOutcome;
|
|
557
|
+
} | {
|
|
558
|
+
isCrafted: false;
|
|
559
|
+
missing: string[];
|
|
560
|
+
};
|
|
561
|
+
/** Whether the character can make the recipe now, and what is missing when not. Skill and `unlockedBy` are ignored when the host does not pass `skills` or `unlocked`. */
|
|
562
|
+
declare const canCraft: (recipe: RecipeDef, context: CraftContext) => CraftCheck;
|
|
563
|
+
/**
|
|
564
|
+
* Makes the recipe: what is consumed and what comes out. Pure: the host takes the consumed things from its inventory and applies the output (an item is
|
|
565
|
+
* added, an effect such as "window with 200 life" is the host's to handle). Draws one number only when the output quantity is a range.
|
|
566
|
+
*/
|
|
567
|
+
declare const craft: (recipe: RecipeDef, context: CraftContext, random: () => number) => CraftResult;
|
|
568
|
+
|
|
569
|
+
/** The seeded generator of the SDK: a function returning floats in [0, 1). */
|
|
570
|
+
type Rng = ReturnType<typeof rng>;
|
|
571
|
+
/** Per-instance state of a found item. */
|
|
572
|
+
interface FindData {
|
|
573
|
+
/** Effective age in days (food). */
|
|
574
|
+
readonly ageDays?: number;
|
|
575
|
+
/** Condition 0..100 (clothing, weapons, tools). */
|
|
576
|
+
readonly condition?: number;
|
|
577
|
+
/** Charge 0..1 (batteries). */
|
|
578
|
+
readonly charge?: number;
|
|
579
|
+
/** How full 0..1 (a jerrycan). */
|
|
580
|
+
readonly fill?: number;
|
|
581
|
+
}
|
|
582
|
+
/** The shape of the floorplan's `FindStack`; structurally the same, so a provider plugs in without either package importing the other. */
|
|
583
|
+
interface FindStack {
|
|
584
|
+
readonly itemId: string;
|
|
585
|
+
readonly count: number;
|
|
586
|
+
readonly data?: FindData;
|
|
587
|
+
}
|
|
588
|
+
/** The shape of the floorplan's `FindsQuery`. */
|
|
589
|
+
interface FindsQuery {
|
|
590
|
+
/** Kind of place (`house`, `supermarket`...). */
|
|
591
|
+
place: string;
|
|
592
|
+
/** Kind of container (a catalog container id such as `fridge`, or a furniture category). */
|
|
593
|
+
container: string;
|
|
594
|
+
/** `normal`, `fortified` or `abandoned` (or a name the rules map to one of them). */
|
|
595
|
+
state: string;
|
|
596
|
+
rng: Rng;
|
|
597
|
+
/** Outbreak days; 0 is the normal world. */
|
|
598
|
+
day?: number;
|
|
599
|
+
region?: string;
|
|
600
|
+
/** Footprint of the furniture in m²: sets the count of an explicit pool. */
|
|
601
|
+
footprint?: number;
|
|
602
|
+
/** Key of the explicit pool when it differs from `container`. */
|
|
603
|
+
key?: string;
|
|
604
|
+
}
|
|
605
|
+
/** The shape of the floorplan's `FindsProvider`: answers what a container holds; `null` says it does not know the container. */
|
|
606
|
+
interface FindsProvider {
|
|
607
|
+
findsFor(query: FindsQuery): readonly FindStack[] | null;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* Port of the team game's `rollItems` (jogo.js L68796-68812) on the container table (`CONT_TAB`) and the rarity weights (`RAR_W`).
|
|
612
|
+
*
|
|
613
|
+
* Order of the random draws, the contract the golden test holds: one for the count; then for each stack one to pick the category, and (unless the category
|
|
614
|
+
* has nothing to draw) one to pick the item among those of the place, by rarity weight. Nothing else draws. The count is scaled by the day and the region
|
|
615
|
+
* after it is drawn, so day 0 gives exactly the game's rolls. Returns the item ids, one per stack.
|
|
616
|
+
*/
|
|
617
|
+
declare const rollByCategory: (catalog: ItemsCatalog, query: FindsQuery) => string[];
|
|
618
|
+
|
|
619
|
+
/** Share of the normal stock a place still has `day` days into the outbreak: `max(floor, 1 - perDay x day)`; 1 on day 0 and where no rule names the place. */
|
|
620
|
+
declare const depletionFactor: (place: PlaceTag, day: number, rules: ItemRules) => number;
|
|
621
|
+
/** The count of stacks after the days of the outbreak and the region: the roll is drawn first, so day 0 and an unknown region leave it as it was. */
|
|
622
|
+
declare const scaleCount: (count: number, scale: {
|
|
623
|
+
place: PlaceTag;
|
|
624
|
+
day: number;
|
|
625
|
+
region?: string;
|
|
626
|
+
}, rules: ItemRules) => number;
|
|
627
|
+
|
|
628
|
+
interface PoolPick {
|
|
629
|
+
itemId: string;
|
|
630
|
+
count: number;
|
|
631
|
+
/** The pool entry it came from; none for the junk an abandoned container leaves. */
|
|
632
|
+
entry?: PoolEntry;
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Port of the 3D house viewer's `sorteiaConteudo` (visor-casas-3d.js L10837-10863) over a pool of what a kind of furniture holds.
|
|
636
|
+
*
|
|
637
|
+
* Order of the random draws, the contract the golden test holds: one for the count (`base`); for an abandoned container one more (empty or not); then a full
|
|
638
|
+
* weighted order of the pool (one draw per entry, before the cut to the count); then one per kept entry for its quantity; and only for an abandoned and empty
|
|
639
|
+
* container one last draw for the junk. Fortified: more entries, supplies weigh x2.5 and give +1. Abandoned: 40% empty, otherwise one entry, plus junk and,
|
|
640
|
+
* in a fridge or freezer, spoiled food.
|
|
641
|
+
*/
|
|
642
|
+
declare const rollExplicitPool: (pool: readonly PoolEntry[], state: FindState, query: FindsQuery, rules: ItemRules) => PoolPick[];
|
|
643
|
+
|
|
644
|
+
interface FindsProviderOptions {
|
|
645
|
+
/** `team` (default): a container with an explicit pool in the catalog uses it; `none`: always the category roll. */
|
|
646
|
+
pools?: 'team' | 'none';
|
|
647
|
+
/** Changes to the `finds` and `spawn` rules for this provider. */
|
|
648
|
+
rules?: DeepPartial<Pick<ItemRules, 'finds' | 'spawn'>>;
|
|
649
|
+
/** Names a host uses for a place, mapped to the place tags of the catalog (a floorplan `cabin` is a `lodge`). */
|
|
650
|
+
placeAliases?: Readonly<Record<string, string>>;
|
|
651
|
+
/** Places where the explicit pools apply (the viewer's pools describe dwellings); the others use the category roll. Default: every place. */
|
|
652
|
+
poolPlaces?: readonly string[];
|
|
653
|
+
/** A container with neither a pool nor a table: `fallback` (default) uses the table of `rules.finds.fallbackContainer`, like the game; `pass` answers `null` so the host's own default applies. */
|
|
654
|
+
unknownContainers?: 'fallback' | 'pass';
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* What a container holds, as the floorplan's `FindsProvider` asks it. A container with an explicit pool (`query.key` or the container id) draws from it
|
|
658
|
+
* (port of the viewer); otherwise the category roll of the game draws on the container table. Every stack is chosen first, in the order of the sources, and
|
|
659
|
+
* only then each gets its state (age, condition, charge, fill) from the same generator. Items the catalog no longer has (removed by a game) are dropped
|
|
660
|
+
* after the draws, so the others do not change.
|
|
661
|
+
*/
|
|
662
|
+
declare function createFindsProvider(catalog: ItemsCatalog, options: FindsProviderOptions & {
|
|
663
|
+
unknownContainers: 'pass';
|
|
664
|
+
}): FindsProvider;
|
|
665
|
+
declare function createFindsProvider(catalog: ItemsCatalog, options?: FindsProviderOptions): {
|
|
666
|
+
findsFor(query: FindsQuery): readonly FindStack[];
|
|
667
|
+
};
|
|
668
|
+
|
|
669
|
+
interface PlacedFinds {
|
|
670
|
+
/** One entry per slot, in the order of `slots`; null is empty. */
|
|
671
|
+
contents: Array<ItemStack | null>;
|
|
672
|
+
/** Stacks that fit no free slot. */
|
|
673
|
+
leftover: FindStack[];
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Puts the stacks in the slots of a container: each in the first free slot its item fits (`fitsSize`, width and depth may swap), a stack larger than the
|
|
677
|
+
* item's `stack` splits over several slots. Pure and in order, so the same finds always land in the same slots. The result is the floorplan's `contents`.
|
|
678
|
+
*/
|
|
679
|
+
declare const placeFinds: (stacks: readonly FindStack[], slots: readonly SlotSpec[], catalog: ItemsCatalog) => PlacedFinds;
|
|
680
|
+
|
|
681
|
+
interface LootTablesQuery {
|
|
682
|
+
place: string;
|
|
683
|
+
/** Outbreak days; 0 is the normal world. */
|
|
684
|
+
day?: number;
|
|
685
|
+
region?: string;
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* The finds as the loot tables of `game-interactables`, for worlds that have no floorplan: one table per container of the place, named by the container id.
|
|
689
|
+
* A table has one entry per rollable item, weighted by the container's category weight and the rarity (60/28/9/2.5). A slot is filled with probability
|
|
690
|
+
* `fill` = expected count / most stacks, taking the container to have as many slots as its largest count; the day and the region scale the expected count.
|
|
691
|
+
*/
|
|
692
|
+
declare const toLootTables: (catalog: ItemsCatalog, query: LootTablesQuery) => LootTables;
|
|
693
|
+
|
|
694
|
+
/** Age of food when it turns up: the days since the outbreak plus 0 to 60% of the shelf life. On day 0 that is the normal turnover of the shelf. One draw. */
|
|
695
|
+
declare const spawnAgeDays: (item: ItemDef, outbreakDays: number, random: () => number, catalog: ItemsCatalog) => number | undefined;
|
|
696
|
+
/**
|
|
697
|
+
* The state an item has when it turns up, drawn after all the stacks of a container were chosen (so the choice itself matches the sources): food age, condition
|
|
698
|
+
* by rarity (100 for shop stock on day 0), battery charge and how full a jerrycan is. Draws in that order, only what applies.
|
|
699
|
+
*/
|
|
700
|
+
declare const spawnData: (item: ItemDef, query: FindsQuery, catalog: ItemsCatalog) => FindData | undefined;
|
|
701
|
+
|
|
702
|
+
/** The part of a weapon definition the bridge reads; `WeaponDef` of `@adatechnology/game-weapons` fits it without importing the package. */
|
|
703
|
+
interface ArsenalWeaponLike {
|
|
704
|
+
readonly id: string;
|
|
705
|
+
readonly mass: number;
|
|
706
|
+
readonly action: {
|
|
707
|
+
readonly kind: string;
|
|
708
|
+
readonly explosive?: string;
|
|
709
|
+
};
|
|
710
|
+
readonly dimensions?: {
|
|
711
|
+
readonly length: number;
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
/** The part of a calibre definition the bridge reads; `CaliberDef` fits it. */
|
|
715
|
+
interface ArsenalCaliberLike {
|
|
716
|
+
readonly id: string;
|
|
717
|
+
readonly bulletGrams: number;
|
|
718
|
+
readonly pellets?: number;
|
|
719
|
+
readonly caseType?: string;
|
|
720
|
+
readonly cartridge?: {
|
|
721
|
+
readonly caseDiameter: number;
|
|
722
|
+
readonly overallLength: number;
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
/** The part of an `Arsenal` the bridge reads. */
|
|
726
|
+
interface ArsenalLike {
|
|
727
|
+
readonly weapons: ReadonlyMap<string, ArsenalWeaponLike>;
|
|
728
|
+
readonly calibers: ReadonlyMap<string, ArsenalCaliberLike>;
|
|
729
|
+
}
|
|
730
|
+
/** What the team's game says of a box or an arsenal item (`ammo-boxes.json`, from its `EXTRA` table); it wins over the estimates below. */
|
|
731
|
+
interface ArsenalItemRecord {
|
|
732
|
+
/** Id of the item; without it the bridge uses `ammo_<caliber>`, `firearm_<weapon>` or `throwable_<weapon>`. */
|
|
733
|
+
id?: string;
|
|
734
|
+
kind: 'ammo_box' | 'firearm' | 'throwable';
|
|
735
|
+
/** Calibre id of a box. */
|
|
736
|
+
caliber?: string;
|
|
737
|
+
/** Weapon id of a firearm or throwable; for a throwable also the explosive it uses. */
|
|
738
|
+
weapon?: string;
|
|
739
|
+
rounds?: number;
|
|
740
|
+
weight: number;
|
|
741
|
+
rarity: Rarity;
|
|
742
|
+
}
|
|
743
|
+
interface ArsenalItemsOptions {
|
|
744
|
+
records?: readonly ArsenalItemRecord[];
|
|
745
|
+
}
|
|
746
|
+
declare const ARSENAL_CATEGORIES: readonly CategoryDef[];
|
|
747
|
+
/**
|
|
748
|
+
* The arsenal as items, so a bag can carry it: a box `ammo_<caliber>` for every calibre, `firearm_<id>` for every firearm and `throwable_<id>` for every
|
|
749
|
+
* throwable, with the mass and the real dimensions of the `WeaponDef` (`mass`, `dimensions.length`). A record from the team's game (`records`) gives the rounds
|
|
750
|
+
* per box, the weight and the rarity of what it listed (9x19: 20 rounds, 0.24 kg); the rest are estimated from the calibre (REF): rounds by case type,
|
|
751
|
+
* weight from the bullet. Returns a pack (with the `ammo`, `firearms` and `throwables` categories) for `createItems({ packs })`.
|
|
752
|
+
*/
|
|
753
|
+
declare const itemsFromArsenal: (arsenal: ArsenalLike, options?: ArsenalItemsOptions) => ItemPack;
|
|
754
|
+
|
|
755
|
+
export { ARSENAL_CATEGORIES, type AgeOptions, type AgeState, type ArsenalCaliberLike, type ArsenalItemRecord, type ArsenalItemsOptions, type ArsenalLike, type ArsenalWeaponLike, type AttackKind, BODY_SLOTS, type BagOption, type CarryEntry, type CategoryDef, type Consumption, type ContainerDef, type CraftCheck, type CraftContext, type CraftOutcome, type CraftResult, DEFAULT_RULES, DURABILITY_KINDS, type DepletionRule, type Durability, type DurabilityKind, type FindData, type FindStack, type FindState, type FindsProvider, type FindsProviderOptions, type FindsQuery, type Freshness, type FreshnessEffect, ITEM_CATEGORIES, type ItemCategory, type ItemDef, type ItemPack, type ItemRules, type ItemsCatalog, type ItemsOptions, type LoadLevel, type LoadState, type LootTablesQuery, type NutritionResult, type PlaceDef, type PlaceTag, type PlacedFinds, type PoolEntry, type PoolPick, RARITIES, type Rarity, type RecipeDef, type RecipeInput, type RecipeMatch, type RecipeOutput, type RecipeTool, type Rng, type StorageId, type StorageRule, type StorageRules, type TakeResult, type UseContext, type UseEffectDef, type UseResult, type WornPiece, advanceAge, bagOption, blockChance, canCraft, canTake, carriedKg, chargeLevel, checkItems, craft, createFindsProvider, createItems, depletionFactor, failsToStart, freshness, itemsFromArsenal, loadState, maxLoadKg, moveToStorage, pieceBlock, placeFinds, repairPiece, resolveUse, rollByCategory, rollExplicitPool, scaleCount, shelfRatio, spawnAgeDays, spawnData, storageMultiplier, toLootTables, wearBlocked };
|