@adatechnology/game-weapons-three 0.4.0 → 0.4.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.
@@ -66,6 +66,199 @@ var GameWeaponsThree = (() => {
66
66
  worldExplosiveItem: () => worldExplosiveItem
67
67
  });
68
68
 
69
+ // ../game-contracts/dist/index.js
70
+ var TOOL_CLIP = {
71
+ DRAW: "draw",
72
+ SHOT: "shot",
73
+ MISFIRE: "misfire",
74
+ EMPTY: "empty",
75
+ CYCLE: "cycle",
76
+ RELOAD: "reload",
77
+ FEED: "feed",
78
+ FAULT: "fault",
79
+ CLEAR: "clear",
80
+ SAFETY_ON: "safety_on",
81
+ SAFETY_OFF: "safety_off",
82
+ MODE: "mode",
83
+ /** A throwable with the pin out, held until it is thrown. */
84
+ COOK: "cook",
85
+ /** The stock folds, unfolds, slides in or out (variants `fold`, `unfold`, `collapse`, `extend`). */
86
+ STOCK: "stock",
87
+ /** A light or a laser is switched (variants `on`, `off`). */
88
+ TOGGLE: "toggle"
89
+ };
90
+ var stockVariant = (event) => {
91
+ const isFolding = event.kind === void 0 ? false : event.kind.includes("fold");
92
+ if (event.state === "collapsed") return isFolding ? "fold" : "collapse";
93
+ return isFolding ? "unfold" : "extend";
94
+ };
95
+ var toolAnimationStep = (event) => {
96
+ switch (event.type) {
97
+ case "tool":
98
+ return { type: "play", clip: TOOL_CLIP.DRAW, ...event.duration === void 0 ? {} : { duration: event.duration } };
99
+ case "shot":
100
+ return { type: "play", clip: TOOL_CLIP.SHOT, repeat: Math.max(1, event.rounds ?? 1) };
101
+ case "misfire":
102
+ return { type: "play", clip: TOOL_CLIP.MISFIRE };
103
+ case "empty":
104
+ return { type: "play", clip: TOOL_CLIP.EMPTY };
105
+ case "mode":
106
+ return { type: "play", clip: TOOL_CLIP.MODE, variant: event.mode };
107
+ case "fault":
108
+ return { type: "play", clip: TOOL_CLIP.FAULT, variant: event.fault };
109
+ case "clear":
110
+ if (event.phase === "end") return { type: "finish", clip: TOOL_CLIP.CLEAR };
111
+ return { type: "play", clip: TOOL_CLIP.CLEAR, variant: event.fault, ...event.duration === void 0 ? {} : { duration: event.duration } };
112
+ case "safety":
113
+ return { type: "play", clip: event.on ? TOOL_CLIP.SAFETY_ON : TOOL_CLIP.SAFETY_OFF };
114
+ case "cycle":
115
+ if (event.phase === "end") return { type: "finish", clip: TOOL_CLIP.CYCLE };
116
+ return { type: "play", clip: TOOL_CLIP.CYCLE, ...event.duration === void 0 ? {} : { duration: event.duration } };
117
+ case "reload":
118
+ if (event.phase === "end") return { type: "finish", clip: TOOL_CLIP.RELOAD };
119
+ return { type: "play", clip: TOOL_CLIP.RELOAD, ...event.kind === void 0 ? {} : { variant: event.kind }, ...event.duration === void 0 ? {} : { duration: event.duration } };
120
+ case "stage":
121
+ return { type: "sync", stage: event.stage };
122
+ case "feed":
123
+ return { type: "play", clip: TOOL_CLIP.FEED };
124
+ case "cook":
125
+ if (event.phase === "start") return { type: "play", clip: TOOL_CLIP.COOK, duration: event.fuse };
126
+ return { type: "finish", clip: TOOL_CLIP.COOK };
127
+ case "stock":
128
+ return { type: "play", clip: TOOL_CLIP.STOCK, variant: stockVariant(event), ...event.duration === void 0 ? {} : { duration: event.duration } };
129
+ case "toggle":
130
+ return { type: "play", clip: TOOL_CLIP.TOGGLE, variant: event.on ? "on" : "off" };
131
+ default:
132
+ return null;
133
+ }
134
+ };
135
+ var STAGE_EVENT = "stage";
136
+ var scaleClip = (clip, duration) => {
137
+ const factor = clip.duration > 0 ? duration / clip.duration : 1;
138
+ return {
139
+ ...clip,
140
+ duration,
141
+ keys: clip.keys.map((key) => ({ ...key, t: key.t * factor })),
142
+ ...clip.events ? { events: clip.events.map((event) => ({ ...event, t: event.t * factor })) } : {}
143
+ };
144
+ };
145
+ var ZERO = [0, 0, 0];
146
+ var mix = (from, to, fraction) => [
147
+ (from[0] ?? 0) + ((to[0] ?? 0) - (from[0] ?? 0)) * fraction,
148
+ (from[1] ?? 0) + ((to[1] ?? 0) - (from[1] ?? 0)) * fraction,
149
+ (from[2] ?? 0) + ((to[2] ?? 0) - (from[2] ?? 0)) * fraction
150
+ ];
151
+ var sampleClip = (clip, partId, time) => {
152
+ const points = clip.keys.map((key) => {
153
+ const pose = partId === void 0 ? key : key.parts?.[partId];
154
+ return { t: key.t, position: pose?.position ?? ZERO, rotation: pose?.rotation ?? ZERO };
155
+ });
156
+ const first = points[0];
157
+ if (!first || first.t > 0) points.unshift({ t: 0, position: ZERO, rotation: ZERO });
158
+ const last = points[points.length - 1];
159
+ if (!last) return { position: ZERO, rotation: ZERO };
160
+ if (time >= last.t) return { position: mix(last.position, last.position, 0), rotation: mix(last.rotation, last.rotation, 0) };
161
+ const index = Math.max(0, points.findIndex((point, i) => time >= point.t && time < (points[i + 1]?.t ?? Infinity)));
162
+ const from = points[index];
163
+ const to = points[index + 1];
164
+ if (!from || !to) return { position: ZERO, rotation: ZERO };
165
+ const fraction = to.t > from.t ? (time - from.t) / (to.t - from.t) : 0;
166
+ return { position: mix(from.position, to.position, fraction), rotation: mix(from.rotation, to.rotation, fraction) };
167
+ };
168
+ var createToolClipPlayer = (options) => {
169
+ const { clips, rig, onEvent } = options;
170
+ let instances = [];
171
+ const find = (clip, variant) => {
172
+ const name = variant !== void 0 && clips[`${clip}_${variant}`] ? `${clip}_${variant}` : clip;
173
+ const found = clips[name];
174
+ return found ? { name, clip: found } : void 0;
175
+ };
176
+ const render = (instance) => {
177
+ const time = Math.min(instance.time, instance.clip.duration);
178
+ const root = sampleClip(instance.clip, void 0, time);
179
+ if (instance.clip.keys.some((key) => key.position || key.rotation)) rig.setRootPose?.(root);
180
+ const touched = new Set(instance.clip.keys.flatMap((key) => Object.keys(key.parts ?? {})));
181
+ for (const id of touched) rig.setPartPose(id, sampleClip(instance.clip, id, time));
182
+ };
183
+ const fireEvents = (instance, upTo) => {
184
+ const events = instance.clip.events ?? [];
185
+ while (instance.fired < events.length && (events[instance.fired]?.t ?? Infinity) <= upTo + 1e-9) {
186
+ const event = events[instance.fired];
187
+ instance.fired += 1;
188
+ if (event) onEvent?.(event, instance.name);
189
+ }
190
+ };
191
+ return {
192
+ apply(step) {
193
+ if (step.type === "sync") {
194
+ for (const instance of instances) {
195
+ const marker = (instance.clip.events ?? []).find((event) => event.type === STAGE_EVENT && event.data?.stage === step.stage);
196
+ if (marker && instance.time < marker.t) instance.time = marker.t;
197
+ }
198
+ return;
199
+ }
200
+ if (step.type === "finish") {
201
+ for (const instance of instances) {
202
+ if (instance.name !== step.clip && !instance.name.startsWith(`${step.clip}_`)) continue;
203
+ fireEvents(instance, instance.clip.duration);
204
+ instance.time = instance.clip.duration;
205
+ }
206
+ return;
207
+ }
208
+ const found = find(step.clip, step.variant);
209
+ if (!found) return;
210
+ const clip = step.duration && step.duration > 0 ? scaleClip(found.clip, step.duration) : found.clip;
211
+ const interval = options.repeatInterval?.() ?? 0.1;
212
+ instances = instances.filter((existing) => existing.name !== found.name || existing.delay > 0);
213
+ for (let round2 = 0; round2 < (step.repeat ?? 1); round2++) {
214
+ instances.push({ name: found.name, clip, time: 0, delay: round2 * interval, fired: 0 });
215
+ }
216
+ },
217
+ update(dt) {
218
+ for (const instance of instances) {
219
+ const carried = instance.delay > 0 ? dt - instance.delay : dt;
220
+ if (instance.delay > 0) {
221
+ instance.delay = Math.max(0, instance.delay - dt);
222
+ if (instance.delay > 0) continue;
223
+ }
224
+ instance.time += carried;
225
+ fireEvents(instance, instance.time);
226
+ render(instance);
227
+ }
228
+ instances = instances.filter((instance) => instance.delay > 0 || instance.time < instance.clip.duration);
229
+ },
230
+ get playing() {
231
+ return instances.map((instance) => instance.name);
232
+ }
233
+ };
234
+ };
235
+ var UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
236
+ var isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
237
+ var deepMerge = (base, patch) => {
238
+ if (!patch) return base;
239
+ const result2 = { ...base };
240
+ for (const [key, value] of Object.entries(patch)) {
241
+ if (value === void 0 || UNSAFE_KEYS.has(key)) continue;
242
+ const current = result2[key];
243
+ result2[key] = isPlainObject(current) && isPlainObject(value) ? deepMerge(current, value) : value;
244
+ }
245
+ return result2;
246
+ };
247
+ var mergeById = (shipped, extra) => {
248
+ const entries = /* @__PURE__ */ new Map();
249
+ for (const entry of [...shipped, ...extra ?? []]) entries.set(entry.id, entry);
250
+ return entries;
251
+ };
252
+ var applyPatches = (entries, patches) => {
253
+ for (const [id, patch] of Object.entries(patches ?? {})) {
254
+ const entry = entries.get(id);
255
+ if (entry) entries.set(id, deepMerge(entry, patch));
256
+ }
257
+ };
258
+ var removeIds = (entries, ids) => {
259
+ for (const id of ids ?? []) entries.delete(id);
260
+ };
261
+
69
262
  // ../game-weapons/dist/index.js
70
263
  var __defProp2 = Object.defineProperty;
71
264
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -11138,69 +11331,270 @@ var GameWeaponsThree = (() => {
11138
11331
  if (context.isCompatible && !context.isCompatible(def, attachment, fitted)) return { ok: false, reason: "rejected" };
11139
11332
  return { ok: true, mount: place.kind };
11140
11333
  };
11141
- var findDuplicateIds = (kind, entries) => {
11142
- const seen = /* @__PURE__ */ new Set();
11143
- const problems = [];
11144
- for (const { id } of entries ?? []) {
11145
- if (seen.has(id)) problems.push(`${kind} "${id}" is listed more than once`);
11146
- seen.add(id);
11147
- }
11148
- return problems;
11149
- };
11150
- var checkRotary = (id, action) => {
11151
- const problems = [];
11152
- const { rpm, rpmRange, spin } = action;
11153
- if (rpmRange && !(rpmRange[0] > 0 && rpmRange[0] <= rpmRange[1])) problems.push(`weapon "${id}" has an empty rate range ${rpmRange[0]}-${rpmRange[1]} rpm`);
11154
- if (rpmRange && (rpm < rpmRange[0] || rpm > rpmRange[1])) problems.push(`weapon "${id}" fires at ${rpm} rpm, outside its range ${rpmRange[0]}-${rpmRange[1]}`);
11155
- if (spin && !(spin.upSeconds >= 0 && spin.holdSeconds >= 0)) problems.push(`weapon "${id}" has a negative spin time`);
11156
- return problems;
11157
- };
11158
- var checkFirearm = (def, calibers) => {
11159
- if (def.action.kind !== "firearm") return [];
11160
- const problems = [];
11161
- for (const caliber of [def.action.caliber, ...def.action.acceptsCalibers ?? []]) {
11162
- if (!calibers.has(caliber)) problems.push(`weapon "${def.id}" uses unknown calibre "${caliber}"`);
11163
- }
11164
- if (def.action.modes.length === 0) problems.push(`weapon "${def.id}" has no fire modes`);
11165
- if (!(def.action.rpm > 0)) problems.push(`weapon "${def.id}" has a rate of fire of ${def.action.rpm} rpm`);
11166
- if (!(def.action.reload > 0)) problems.push(`weapon "${def.id}" has a reload time of ${def.action.reload} s`);
11167
- problems.push(...checkRotary(def.id, def.action));
11168
- return problems;
11169
- };
11170
- var checkTimings = (def) => {
11171
- const timings = "timings" in def.action ? def.action.timings : void 0;
11172
- return Object.entries(timings ?? {}).filter(([, seconds]) => typeof seconds === "number" && !(seconds > 0)).map(([name, seconds]) => `weapon "${def.id}" has a ${name} time of ${seconds} s`);
11173
- };
11174
- var checkExplosiveReference = (def, explosives) => {
11175
- const id = def.action.kind === "launcher" ? def.action.projectile : def.action.kind === "throwable" ? def.action.explosive : void 0;
11176
- return id !== void 0 && !explosives.has(id) ? [`weapon "${def.id}" uses unknown explosive "${id}"`] : [];
11177
- };
11178
- var checkExplosiveNumbers = (explosive) => {
11179
- const problems = [];
11180
- const [low, high] = explosive.fuseRange ?? [1, 1];
11181
- if (!(low > 0 && high >= low)) problems.push(`explosive "${explosive.id}" has a fuse range of ${low} to ${high} s`);
11182
- if (explosive.fuseLength !== void 0 && !(explosive.fuseLength > 0)) problems.push(`explosive "${explosive.id}" has a fuse length of ${explosive.fuseLength} m`);
11183
- if (explosive.burnRate !== void 0 && !(explosive.burnRate > 0)) problems.push(`explosive "${explosive.id}" has a burn rate of ${explosive.burnRate} s/m`);
11184
- if (explosive.burnTolerance !== void 0 && !(explosive.burnTolerance >= 0 && explosive.burnTolerance < 1)) problems.push(`explosive "${explosive.id}" has a burn tolerance of ${explosive.burnTolerance}`);
11185
- if (explosive.tripwire && !(explosive.tripwire.length > 0)) problems.push(`explosive "${explosive.id}" has a trip wire of ${explosive.tripwire.length} m`);
11186
- return problems;
11187
- };
11188
- var STATS = /* @__PURE__ */ new Set(["noise", "spread", "hipSpreadExcess", "recoilVertical", "recoilHorizontal", "range", "muzzleSpeed", "mass", "capacity", "reload", "reloadEmpty", "draw", "aim", "faultChance", "heatPerShot"]);
11189
- var INSTALLS = /* @__PURE__ */ new Set(["field", "tool", "bench"]);
11190
- var checkAttachment = (attachment, weapons) => {
11191
- const problems = [];
11192
- if (attachment.launcher !== void 0 && weapons.get(attachment.launcher)?.action.kind !== "launcher") problems.push(`attachment "${attachment.id}" names "${attachment.launcher}" as its launcher, which is not a launcher weapon`);
11193
- const label = `attachment "${attachment.id}"`;
11194
- if (!INSTALLS.has(attachment.install)) problems.push(`${label} installs "${attachment.install}"`);
11195
- if (attachment.mounts.length === 0) problems.push(`${label} has no mount`);
11196
- if (attachment.interfaces.length === 0) problems.push(`${label} has no interface`);
11197
- for (const effect of attachment.effects) {
11198
- if (!STATS.has(effect.stat)) problems.push(`${label} changes the unknown stat "${effect.stat}"`);
11199
- if (effect.mul !== void 0 && !(effect.mul > 0)) problems.push(`${label} multiplies ${effect.stat} by ${effect.mul}`);
11200
- }
11201
- return problems;
11202
- };
11203
- var checkFitted = (def, attachments) => {
11334
+ var melee_weapons_default = [
11335
+ {
11336
+ id: "tactical_knife",
11337
+ name: "Tactical knife",
11338
+ category: "melee_blade",
11339
+ action: {
11340
+ kind: "melee",
11341
+ damage: "slash",
11342
+ energy: 45,
11343
+ radius: 0.03,
11344
+ reach: 0.6,
11345
+ rpm: 100,
11346
+ noise: 1
11347
+ },
11348
+ mass: 0.3
11349
+ },
11350
+ {
11351
+ id: "meat_cleaver",
11352
+ name: "Meat cleaver",
11353
+ category: "melee_blade",
11354
+ action: {
11355
+ kind: "melee",
11356
+ damage: "slash",
11357
+ energy: 120,
11358
+ radius: 0.05,
11359
+ reach: 0.6,
11360
+ rpm: 70,
11361
+ noise: 2
11362
+ },
11363
+ mass: 0.6
11364
+ },
11365
+ {
11366
+ id: "hatchet",
11367
+ name: "Hatchet",
11368
+ category: "melee_blade",
11369
+ action: {
11370
+ kind: "melee",
11371
+ damage: "slash",
11372
+ energy: 180,
11373
+ radius: 0.06,
11374
+ reach: 0.7,
11375
+ rpm: 55,
11376
+ noise: 2
11377
+ },
11378
+ mass: 0.8
11379
+ },
11380
+ {
11381
+ id: "nail_bat",
11382
+ name: "Nail bat",
11383
+ category: "melee_blunt",
11384
+ action: {
11385
+ kind: "melee",
11386
+ damage: "blunt",
11387
+ energy: 170,
11388
+ radius: 0.1,
11389
+ reach: 1,
11390
+ rpm: 60,
11391
+ noise: 3
11392
+ },
11393
+ mass: 1.2
11394
+ },
11395
+ {
11396
+ id: "iron_pipe",
11397
+ name: "Iron pipe",
11398
+ category: "melee_blunt",
11399
+ action: {
11400
+ kind: "melee",
11401
+ damage: "blunt",
11402
+ energy: 140,
11403
+ radius: 0.06,
11404
+ reach: 1,
11405
+ rpm: 60,
11406
+ noise: 4
11407
+ },
11408
+ mass: 1.2
11409
+ },
11410
+ {
11411
+ id: "pickaxe",
11412
+ name: "Pickaxe",
11413
+ category: "melee_blade",
11414
+ action: {
11415
+ kind: "melee",
11416
+ damage: "slash",
11417
+ energy: 260,
11418
+ radius: 0.05,
11419
+ reach: 1,
11420
+ rpm: 40,
11421
+ noise: 4
11422
+ },
11423
+ mass: 2.8,
11424
+ tags: [
11425
+ "heavy"
11426
+ ]
11427
+ },
11428
+ {
11429
+ id: "sickle",
11430
+ name: "Sickle",
11431
+ category: "melee_blade",
11432
+ action: {
11433
+ kind: "melee",
11434
+ damage: "slash",
11435
+ energy: 70,
11436
+ radius: 0.05,
11437
+ reach: 1.1,
11438
+ rpm: 70,
11439
+ noise: 2
11440
+ },
11441
+ mass: 1.2
11442
+ },
11443
+ {
11444
+ id: "police_baton",
11445
+ name: "Police baton",
11446
+ category: "melee_blunt",
11447
+ action: {
11448
+ kind: "melee",
11449
+ damage: "blunt",
11450
+ energy: 70,
11451
+ radius: 0.04,
11452
+ reach: 0.7,
11453
+ rpm: 90,
11454
+ noise: 3
11455
+ },
11456
+ mass: 0.6
11457
+ },
11458
+ {
11459
+ id: "cast_iron_skillet",
11460
+ name: "Cast iron skillet",
11461
+ category: "melee_blunt",
11462
+ action: {
11463
+ kind: "melee",
11464
+ damage: "blunt",
11465
+ energy: 110,
11466
+ radius: 0.12,
11467
+ reach: 0.6,
11468
+ rpm: 60,
11469
+ noise: 8
11470
+ },
11471
+ mass: 1.2
11472
+ },
11473
+ {
11474
+ id: "improvised_spear",
11475
+ name: "Improvised spear",
11476
+ category: "melee_blade",
11477
+ action: {
11478
+ kind: "melee",
11479
+ damage: "slash",
11480
+ energy: 90,
11481
+ radius: 0.02,
11482
+ reach: 1.6,
11483
+ rpm: 50,
11484
+ noise: 1
11485
+ },
11486
+ mass: 1.1
11487
+ },
11488
+ {
11489
+ id: "chainsaw",
11490
+ name: "Chainsaw",
11491
+ category: "melee_blade",
11492
+ action: {
11493
+ kind: "melee",
11494
+ damage: "slash",
11495
+ energy: 400,
11496
+ radius: 0.1,
11497
+ reach: 0.9,
11498
+ rpm: 300,
11499
+ noise: 120
11500
+ },
11501
+ mass: 6,
11502
+ tags: [
11503
+ "heavy"
11504
+ ]
11505
+ },
11506
+ {
11507
+ id: "recurve_bow",
11508
+ name: "Recurve bow",
11509
+ category: "bow",
11510
+ action: {
11511
+ kind: "firearm",
11512
+ caliber: "arrow",
11513
+ rpm: 20,
11514
+ modes: [
11515
+ "single"
11516
+ ],
11517
+ magazine: 1,
11518
+ reload: 1.5,
11519
+ barrel: 1,
11520
+ spreadDeg: 0.4,
11521
+ bloomDeg: 0.4,
11522
+ recoveryDegPerS: 2,
11523
+ recoil: [
11524
+ 0.3,
11525
+ 0.1
11526
+ ],
11527
+ range: 40
11528
+ },
11529
+ mass: 1.2,
11530
+ tags: [
11531
+ "silent"
11532
+ ]
11533
+ }
11534
+ ];
11535
+ var findDuplicateIds = (kind, entries) => {
11536
+ const seen = /* @__PURE__ */ new Set();
11537
+ const problems = [];
11538
+ for (const { id } of entries ?? []) {
11539
+ if (seen.has(id)) problems.push(`${kind} "${id}" is listed more than once`);
11540
+ seen.add(id);
11541
+ }
11542
+ return problems;
11543
+ };
11544
+ var checkRotary = (id, action) => {
11545
+ const problems = [];
11546
+ const { rpm, rpmRange, spin } = action;
11547
+ if (rpmRange && !(rpmRange[0] > 0 && rpmRange[0] <= rpmRange[1])) problems.push(`weapon "${id}" has an empty rate range ${rpmRange[0]}-${rpmRange[1]} rpm`);
11548
+ if (rpmRange && (rpm < rpmRange[0] || rpm > rpmRange[1])) problems.push(`weapon "${id}" fires at ${rpm} rpm, outside its range ${rpmRange[0]}-${rpmRange[1]}`);
11549
+ if (spin && !(spin.upSeconds >= 0 && spin.holdSeconds >= 0)) problems.push(`weapon "${id}" has a negative spin time`);
11550
+ return problems;
11551
+ };
11552
+ var checkFirearm = (def, calibers) => {
11553
+ if (def.action.kind !== "firearm") return [];
11554
+ const problems = [];
11555
+ for (const caliber of [def.action.caliber, ...def.action.acceptsCalibers ?? []]) {
11556
+ if (!calibers.has(caliber)) problems.push(`weapon "${def.id}" uses unknown calibre "${caliber}"`);
11557
+ }
11558
+ if (def.action.modes.length === 0) problems.push(`weapon "${def.id}" has no fire modes`);
11559
+ if (!(def.action.rpm > 0)) problems.push(`weapon "${def.id}" has a rate of fire of ${def.action.rpm} rpm`);
11560
+ if (!(def.action.reload > 0)) problems.push(`weapon "${def.id}" has a reload time of ${def.action.reload} s`);
11561
+ problems.push(...checkRotary(def.id, def.action));
11562
+ return problems;
11563
+ };
11564
+ var checkTimings = (def) => {
11565
+ const timings = "timings" in def.action ? def.action.timings : void 0;
11566
+ return Object.entries(timings ?? {}).filter(([, seconds]) => typeof seconds === "number" && !(seconds > 0)).map(([name, seconds]) => `weapon "${def.id}" has a ${name} time of ${seconds} s`);
11567
+ };
11568
+ var checkExplosiveReference = (def, explosives) => {
11569
+ const id = def.action.kind === "launcher" ? def.action.projectile : def.action.kind === "throwable" ? def.action.explosive : void 0;
11570
+ return id !== void 0 && !explosives.has(id) ? [`weapon "${def.id}" uses unknown explosive "${id}"`] : [];
11571
+ };
11572
+ var checkExplosiveNumbers = (explosive) => {
11573
+ const problems = [];
11574
+ const [low, high] = explosive.fuseRange ?? [1, 1];
11575
+ if (!(low > 0 && high >= low)) problems.push(`explosive "${explosive.id}" has a fuse range of ${low} to ${high} s`);
11576
+ if (explosive.fuseLength !== void 0 && !(explosive.fuseLength > 0)) problems.push(`explosive "${explosive.id}" has a fuse length of ${explosive.fuseLength} m`);
11577
+ if (explosive.burnRate !== void 0 && !(explosive.burnRate > 0)) problems.push(`explosive "${explosive.id}" has a burn rate of ${explosive.burnRate} s/m`);
11578
+ if (explosive.burnTolerance !== void 0 && !(explosive.burnTolerance >= 0 && explosive.burnTolerance < 1)) problems.push(`explosive "${explosive.id}" has a burn tolerance of ${explosive.burnTolerance}`);
11579
+ if (explosive.tripwire && !(explosive.tripwire.length > 0)) problems.push(`explosive "${explosive.id}" has a trip wire of ${explosive.tripwire.length} m`);
11580
+ return problems;
11581
+ };
11582
+ var STATS = /* @__PURE__ */ new Set(["noise", "spread", "hipSpreadExcess", "recoilVertical", "recoilHorizontal", "range", "muzzleSpeed", "mass", "capacity", "reload", "reloadEmpty", "draw", "aim", "faultChance", "heatPerShot"]);
11583
+ var INSTALLS = /* @__PURE__ */ new Set(["field", "tool", "bench"]);
11584
+ var checkAttachment = (attachment, weapons) => {
11585
+ const problems = [];
11586
+ if (attachment.launcher !== void 0 && weapons.get(attachment.launcher)?.action.kind !== "launcher") problems.push(`attachment "${attachment.id}" names "${attachment.launcher}" as its launcher, which is not a launcher weapon`);
11587
+ const label = `attachment "${attachment.id}"`;
11588
+ if (!INSTALLS.has(attachment.install)) problems.push(`${label} installs "${attachment.install}"`);
11589
+ if (attachment.mounts.length === 0) problems.push(`${label} has no mount`);
11590
+ if (attachment.interfaces.length === 0) problems.push(`${label} has no interface`);
11591
+ for (const effect of attachment.effects) {
11592
+ if (!STATS.has(effect.stat)) problems.push(`${label} changes the unknown stat "${effect.stat}"`);
11593
+ if (effect.mul !== void 0 && !(effect.mul > 0)) problems.push(`${label} multiplies ${effect.stat} by ${effect.mul}`);
11594
+ }
11595
+ return problems;
11596
+ };
11597
+ var checkFitted = (def, attachments) => {
11204
11598
  if (!attachments) return [];
11205
11599
  return (def.fitted ?? []).flatMap((part) => {
11206
11600
  const problems = [];
@@ -11222,18 +11616,6 @@ var GameWeaponsThree = (() => {
11222
11616
  ...[...explosives.values()].flatMap(checkExplosiveNumbers),
11223
11617
  ...checkRuleDefaults(rules)
11224
11618
  ];
11225
- var UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
11226
- var isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
11227
- var deepMerge = (base, patch) => {
11228
- if (!patch) return base;
11229
- const result2 = { ...base };
11230
- for (const [key, value] of Object.entries(patch)) {
11231
- if (value === void 0 || UNSAFE_KEYS.has(key)) continue;
11232
- const current = result2[key];
11233
- result2[key] = isPlainObject(current) && isPlainObject(value) ? deepMerge(current, value) : value;
11234
- }
11235
- return result2;
11236
- };
11237
11619
  var modesEn = { single: "single action", semi: "semi-automatic", burst: "burst", auto: "automatic", pump: "pump action", bolt: "bolt action", lever: "lever action", break: "break action", volley: "volley" };
11238
11620
  var categoriesEn = {
11239
11621
  pistol: "pistol",
@@ -11425,20 +11807,6 @@ var GameWeaponsThree = (() => {
11425
11807
  if (explosive.fuseRange) return explosive.fuseRange[0] + (explosive.fuseRange[1] - explosive.fuseRange[0]) * random();
11426
11808
  return explosive.fuse;
11427
11809
  };
11428
- var mergeById = (shipped, extra) => {
11429
- const entries = /* @__PURE__ */ new Map();
11430
- for (const entry of [...shipped, ...extra ?? []]) entries.set(entry.id, entry);
11431
- return entries;
11432
- };
11433
- var applyPatches = (entries, patches) => {
11434
- for (const [id, patch] of Object.entries(patches ?? {})) {
11435
- const entry = entries.get(id);
11436
- if (entry) entries.set(id, deepMerge(entry, patch));
11437
- }
11438
- };
11439
- var removeIds = (entries, ids) => {
11440
- for (const id of ids ?? []) entries.delete(id);
11441
- };
11442
11810
  var resolveThrowables = (weapons, explosives) => {
11443
11811
  for (const [id, def] of weapons) {
11444
11812
  if (def.action.kind !== "throwable" || def.action.explosive === void 0) continue;
@@ -12674,6 +13042,7 @@ var GameWeaponsThree = (() => {
12674
13042
  caliber: cal.diameter,
12675
13043
  caliberId: cal.id,
12676
13044
  speed,
13045
+ mass: cal.bulletGrams,
12677
13046
  energyAt,
12678
13047
  pellet: p,
12679
13048
  weapon: this.def.id
@@ -12859,7 +13228,7 @@ var GameWeaponsThree = (() => {
12859
13228
  var EXPLOSIVES = explosives_default;
12860
13229
  var ARCHETYPES = archetypes_default;
12861
13230
  var ARCHETYPE_IDS = ARCHETYPES.map((def) => def.id);
12862
- var WEAPONS = [...ARCHETYPES, ...firearms_default, ...launchers_default, ...explosive_weapons_default];
13231
+ var WEAPONS = [...ARCHETYPES, ...firearms_default, ...launchers_default, ...explosive_weapons_default, ...melee_weapons_default];
12863
13232
  var explosiveOf = (def, explosives) => {
12864
13233
  const id = def.action.kind === "launcher" ? def.action.projectile : def.action.kind === "throwable" ? def.action.explosive : void 0;
12865
13234
  return id === void 0 ? null : explosives.get(id) ?? null;
@@ -13605,7 +13974,68 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
13605
13974
  };
13606
13975
  };
13607
13976
 
13608
- // src/merge-by-material.ts
13977
+ // ../game-props3d/dist/index.js
13978
+ var T = (id, interior, w, d, h, y, solid2, group) => ({ id, interior, w, d, h, y, solid: solid2, group });
13979
+ var TYPE_DEFS = [
13980
+ T("ceiling_light", true, 0.4, 0.4, 0.07, 0, false, "ceiling"),
13981
+ T("pendant", true, 0.34, 0.34, 1, 0, false, "ceiling"),
13982
+ T("track_spot", true, 1.2, 0.1, 0.2, 0, false, "ceiling"),
13983
+ T("chandelier", true, 0.7, 0.7, 0.7, 0, false, "ceiling"),
13984
+ T("wall_ac", true, 0.9, 0.2, 0.28, 2.15, false, "wall"),
13985
+ T("picture_small", true, 0.35, 0.03, 0.45, 1.3, false, "wall"),
13986
+ T("picture_large", true, 1, 0.04, 0.7, 1.2, false, "wall"),
13987
+ T("mirror", true, 0.6, 0.03, 1.2, 0.9, false, "wall"),
13988
+ T("curtain", true, 1.6, 0.12, 2.3, 0.1, false, "wall"),
13989
+ T("blinds", true, 1.2, 0.08, 1.3, 1, false, "wall"),
13990
+ T("flat_tv", true, 1.2, 0.06, 0.7, 1, false, "wall"),
13991
+ T("floor_plant", true, 0.5, 0.5, 1.1, 0, true, "plants"),
13992
+ T("table_plant", true, 0.2, 0.2, 0.3, 0, false, "plants"),
13993
+ T("hanging_plant", true, 0.5, 0.5, 1, 0, false, "plants"),
13994
+ T("tv_stand", true, 1.6, 0.42, 1.05, 0, true, "furniture"),
13995
+ T("breakfast_bar", true, 2, 1.6, 0.95, 0, true, "furniture"),
13996
+ T("sofa_l", true, 2.8, 1.7, 0.85, 0, true, "furniture"),
13997
+ T("double_bed_modern", true, 1.6, 2.1, 1.2, 0, true, "furniture"),
13998
+ T("home_office", true, 1.4, 0.75, 1.2, 0, true, "furniture"),
13999
+ T("closet", true, 2.2, 0.6, 2.3, 0, true, "furniture"),
14000
+ T("vanity", true, 0.6, 0.45, 1.5, 0, true, "furniture"),
14001
+ T("ac_condenser", false, 0.8, 0.3, 0.55, 0.5, true, "yard"),
14002
+ T("lawn", false, 4, 4, 0.02, 0, false, "floor"),
14003
+ T("tile_floor", false, 4, 3, 0.03, 0, false, "floor"),
14004
+ T("concrete", false, 4, 4, 0.03, 0, false, "floor"),
14005
+ T("deck_floor", false, 4, 3, 0.04, 0, false, "floor"),
14006
+ T("dirt", false, 4, 4, 0.02, 0, false, "floor"),
14007
+ T("gourmet_counter", false, 4.2, 3, 2.9, 0, true, "yard"),
14008
+ T("sauna", false, 2, 1.8, 2.1, 0, true, "yard"),
14009
+ T("soaking_tub", false, 1.3, 1.3, 0.8, 0, true, "yard"),
14010
+ T("pool", false, 4.5, 2.8, 0.1, 0, true, "yard"),
14011
+ T("deck", false, 3.5, 3, 0.22, 0, true, "yard"),
14012
+ T("sun_lounger", false, 0.62, 1.9, 0.5, 0, true, "yard"),
14013
+ T("garden_bed", false, 2, 1, 0.9, 0, true, "yard"),
14014
+ T("fruit_tree", false, 2.4, 2.4, 3.2, 0, true, "yard"),
14015
+ T("palm_tree", false, 2, 2, 4.5, 0, true, "yard"),
14016
+ T("pergola", false, 3.5, 3, 2.4, 0, true, "yard"),
14017
+ T("slide", false, 0.8, 2.6, 1.5, 0, true, "yard"),
14018
+ T("swing", false, 2.2, 1.7, 2.2, 0, true, "yard"),
14019
+ T("bbq_simple", false, 0.9, 0.6, 1, 0, true, "yard"),
14020
+ T("garage_car", false, 1.8, 4.2, 1.45, 0, true, "yard"),
14021
+ T("window_boards", true, 1.2, 0.06, 1.15, 1, false, "house_state"),
14022
+ T("barricade", true, 1.5, 0.7, 1.8, 0, true, "house_state"),
14023
+ T("sandbags", false, 1.6, 0.5, 0.6, 0, true, "house_state"),
14024
+ T("barbed_wire", false, 4, 0.2, 0.6, 0, false, "house_state"),
14025
+ T("razor_wire", false, 4, 0.6, 0.6, 0, false, "house_state"),
14026
+ T("water_bottle_crates", true, 0.9, 0.6, 0.65, 0, true, "house_state"),
14027
+ T("canned_food", true, 0.4, 0.3, 0.3, 0, false, "house_state"),
14028
+ T("water_jug", true, 0.3, 0.3, 0.5, 0, true, "house_state"),
14029
+ T("floor_mattress", true, 0.9, 1.9, 0.3, 0, false, "house_state"),
14030
+ T("lantern", true, 0.16, 0.16, 0.3, 0, false, "house_state"),
14031
+ T("candles", true, 0.25, 0.25, 0.2, 0, false, "house_state"),
14032
+ T("open_suitcases", true, 1.5, 0.7, 0.6, 0, false, "house_state"),
14033
+ T("clothes_on_floor", true, 1.2, 1, 0.05, 0, false, "house_state"),
14034
+ T("fallen_chair", true, 0.5, 0.5, 0.5, 0, false, "house_state"),
14035
+ T("blood_stains", true, 1.2, 1.2, 0.01, 0, false, "house_state"),
14036
+ T("open_door", true, 0.9, 0.15, 2.15, 0, false, "house_state")
14037
+ ];
14038
+ var DEFS = Object.fromEntries(TYPE_DEFS.map((t) => [t.id, t]));
13609
14039
  var ATTRIBUTES = ["position", "normal", "uv"];
13610
14040
  var isVisible = (object) => {
13611
14041
  for (let node = object; node; node = node.parent) if (!node.visible) return false;
@@ -17026,173 +17456,6 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
17026
17456
  };
17027
17457
  }
17028
17458
 
17029
- // ../game-contracts/dist/index.js
17030
- var TOOL_CLIP = {
17031
- DRAW: "draw",
17032
- SHOT: "shot",
17033
- MISFIRE: "misfire",
17034
- EMPTY: "empty",
17035
- CYCLE: "cycle",
17036
- RELOAD: "reload",
17037
- FEED: "feed",
17038
- FAULT: "fault",
17039
- CLEAR: "clear",
17040
- SAFETY_ON: "safety_on",
17041
- SAFETY_OFF: "safety_off",
17042
- MODE: "mode",
17043
- /** A throwable with the pin out, held until it is thrown. */
17044
- COOK: "cook",
17045
- /** The stock folds, unfolds, slides in or out (variants `fold`, `unfold`, `collapse`, `extend`). */
17046
- STOCK: "stock",
17047
- /** A light or a laser is switched (variants `on`, `off`). */
17048
- TOGGLE: "toggle"
17049
- };
17050
- var stockVariant = (event) => {
17051
- const isFolding = event.kind === void 0 ? false : event.kind.includes("fold");
17052
- if (event.state === "collapsed") return isFolding ? "fold" : "collapse";
17053
- return isFolding ? "unfold" : "extend";
17054
- };
17055
- var toolAnimationStep = (event) => {
17056
- switch (event.type) {
17057
- case "tool":
17058
- return { type: "play", clip: TOOL_CLIP.DRAW, ...event.duration === void 0 ? {} : { duration: event.duration } };
17059
- case "shot":
17060
- return { type: "play", clip: TOOL_CLIP.SHOT, repeat: Math.max(1, event.rounds ?? 1) };
17061
- case "misfire":
17062
- return { type: "play", clip: TOOL_CLIP.MISFIRE };
17063
- case "empty":
17064
- return { type: "play", clip: TOOL_CLIP.EMPTY };
17065
- case "mode":
17066
- return { type: "play", clip: TOOL_CLIP.MODE, variant: event.mode };
17067
- case "fault":
17068
- return { type: "play", clip: TOOL_CLIP.FAULT, variant: event.fault };
17069
- case "clear":
17070
- if (event.phase === "end") return { type: "finish", clip: TOOL_CLIP.CLEAR };
17071
- return { type: "play", clip: TOOL_CLIP.CLEAR, variant: event.fault, ...event.duration === void 0 ? {} : { duration: event.duration } };
17072
- case "safety":
17073
- return { type: "play", clip: event.on ? TOOL_CLIP.SAFETY_ON : TOOL_CLIP.SAFETY_OFF };
17074
- case "cycle":
17075
- if (event.phase === "end") return { type: "finish", clip: TOOL_CLIP.CYCLE };
17076
- return { type: "play", clip: TOOL_CLIP.CYCLE, ...event.duration === void 0 ? {} : { duration: event.duration } };
17077
- case "reload":
17078
- if (event.phase === "end") return { type: "finish", clip: TOOL_CLIP.RELOAD };
17079
- return { type: "play", clip: TOOL_CLIP.RELOAD, ...event.kind === void 0 ? {} : { variant: event.kind }, ...event.duration === void 0 ? {} : { duration: event.duration } };
17080
- case "stage":
17081
- return { type: "sync", stage: event.stage };
17082
- case "feed":
17083
- return { type: "play", clip: TOOL_CLIP.FEED };
17084
- case "cook":
17085
- if (event.phase === "start") return { type: "play", clip: TOOL_CLIP.COOK, duration: event.fuse };
17086
- return { type: "finish", clip: TOOL_CLIP.COOK };
17087
- case "stock":
17088
- return { type: "play", clip: TOOL_CLIP.STOCK, variant: stockVariant(event), ...event.duration === void 0 ? {} : { duration: event.duration } };
17089
- case "toggle":
17090
- return { type: "play", clip: TOOL_CLIP.TOGGLE, variant: event.on ? "on" : "off" };
17091
- default:
17092
- return null;
17093
- }
17094
- };
17095
- var STAGE_EVENT = "stage";
17096
- var scaleClip = (clip, duration) => {
17097
- const factor = clip.duration > 0 ? duration / clip.duration : 1;
17098
- return {
17099
- ...clip,
17100
- duration,
17101
- keys: clip.keys.map((key) => ({ ...key, t: key.t * factor })),
17102
- ...clip.events ? { events: clip.events.map((event) => ({ ...event, t: event.t * factor })) } : {}
17103
- };
17104
- };
17105
- var ZERO = [0, 0, 0];
17106
- var mix = (from, to, fraction) => [
17107
- (from[0] ?? 0) + ((to[0] ?? 0) - (from[0] ?? 0)) * fraction,
17108
- (from[1] ?? 0) + ((to[1] ?? 0) - (from[1] ?? 0)) * fraction,
17109
- (from[2] ?? 0) + ((to[2] ?? 0) - (from[2] ?? 0)) * fraction
17110
- ];
17111
- var sampleClip = (clip, partId, time) => {
17112
- const points = clip.keys.map((key) => {
17113
- const pose = partId === void 0 ? key : key.parts?.[partId];
17114
- return { t: key.t, position: pose?.position ?? ZERO, rotation: pose?.rotation ?? ZERO };
17115
- });
17116
- const first = points[0];
17117
- if (!first || first.t > 0) points.unshift({ t: 0, position: ZERO, rotation: ZERO });
17118
- const last = points[points.length - 1];
17119
- if (!last) return { position: ZERO, rotation: ZERO };
17120
- if (time >= last.t) return { position: mix(last.position, last.position, 0), rotation: mix(last.rotation, last.rotation, 0) };
17121
- const index = Math.max(0, points.findIndex((point, i) => time >= point.t && time < (points[i + 1]?.t ?? Infinity)));
17122
- const from = points[index];
17123
- const to = points[index + 1];
17124
- if (!from || !to) return { position: ZERO, rotation: ZERO };
17125
- const fraction = to.t > from.t ? (time - from.t) / (to.t - from.t) : 0;
17126
- return { position: mix(from.position, to.position, fraction), rotation: mix(from.rotation, to.rotation, fraction) };
17127
- };
17128
- var createToolClipPlayer = (options) => {
17129
- const { clips, rig, onEvent } = options;
17130
- let instances = [];
17131
- const find = (clip, variant) => {
17132
- const name = variant !== void 0 && clips[`${clip}_${variant}`] ? `${clip}_${variant}` : clip;
17133
- const found = clips[name];
17134
- return found ? { name, clip: found } : void 0;
17135
- };
17136
- const render = (instance) => {
17137
- const time = Math.min(instance.time, instance.clip.duration);
17138
- const root = sampleClip(instance.clip, void 0, time);
17139
- if (instance.clip.keys.some((key) => key.position || key.rotation)) rig.setRootPose?.(root);
17140
- const touched = new Set(instance.clip.keys.flatMap((key) => Object.keys(key.parts ?? {})));
17141
- for (const id of touched) rig.setPartPose(id, sampleClip(instance.clip, id, time));
17142
- };
17143
- const fireEvents = (instance, upTo) => {
17144
- const events = instance.clip.events ?? [];
17145
- while (instance.fired < events.length && (events[instance.fired]?.t ?? Infinity) <= upTo + 1e-9) {
17146
- const event = events[instance.fired];
17147
- instance.fired += 1;
17148
- if (event) onEvent?.(event, instance.name);
17149
- }
17150
- };
17151
- return {
17152
- apply(step) {
17153
- if (step.type === "sync") {
17154
- for (const instance of instances) {
17155
- const marker = (instance.clip.events ?? []).find((event) => event.type === STAGE_EVENT && event.data?.stage === step.stage);
17156
- if (marker && instance.time < marker.t) instance.time = marker.t;
17157
- }
17158
- return;
17159
- }
17160
- if (step.type === "finish") {
17161
- for (const instance of instances) {
17162
- if (instance.name !== step.clip && !instance.name.startsWith(`${step.clip}_`)) continue;
17163
- fireEvents(instance, instance.clip.duration);
17164
- instance.time = instance.clip.duration;
17165
- }
17166
- return;
17167
- }
17168
- const found = find(step.clip, step.variant);
17169
- if (!found) return;
17170
- const clip = step.duration && step.duration > 0 ? scaleClip(found.clip, step.duration) : found.clip;
17171
- const interval = options.repeatInterval?.() ?? 0.1;
17172
- instances = instances.filter((existing) => existing.name !== found.name || existing.delay > 0);
17173
- for (let round2 = 0; round2 < (step.repeat ?? 1); round2++) {
17174
- instances.push({ name: found.name, clip, time: 0, delay: round2 * interval, fired: 0 });
17175
- }
17176
- },
17177
- update(dt) {
17178
- for (const instance of instances) {
17179
- const carried = instance.delay > 0 ? dt - instance.delay : dt;
17180
- if (instance.delay > 0) {
17181
- instance.delay = Math.max(0, instance.delay - dt);
17182
- if (instance.delay > 0) continue;
17183
- }
17184
- instance.time += carried;
17185
- fireEvents(instance, instance.time);
17186
- render(instance);
17187
- }
17188
- instances = instances.filter((instance) => instance.delay > 0 || instance.time < instance.clip.duration);
17189
- },
17190
- get playing() {
17191
- return instances.map((instance) => instance.name);
17192
- }
17193
- };
17194
- };
17195
-
17196
17459
  // src/animation/clip-builder.ts
17197
17460
  var ROOT = "root";
17198
17461
  var AXIS_INDEX = { x: 0, y: 1, z: 2 };
@@ -19087,6 +19350,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
19087
19350
  source: "generated",
19088
19351
  file: "generated/carl_gustaf_m4.svg"
19089
19352
  },
19353
+ cast_iron_skillet: {
19354
+ source: "generated",
19355
+ file: "generated/cast_iron_skillet.svg"
19356
+ },
19090
19357
  cbc_122: {
19091
19358
  source: "generated",
19092
19359
  file: "generated/cbc_122.svg"
@@ -19099,6 +19366,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
19099
19366
  source: "generated",
19100
19367
  file: "generated/cbc_pump_military_3_0.svg"
19101
19368
  },
19369
+ chainsaw: {
19370
+ source: "generated",
19371
+ file: "generated/chainsaw.svg"
19372
+ },
19102
19373
  cheytac_m200: {
19103
19374
  source: "generated",
19104
19375
  file: "generated/cheytac_m200.svg"
@@ -19255,6 +19526,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
19255
19526
  source: "generated",
19256
19527
  file: "generated/hammer.svg"
19257
19528
  },
19529
+ hatchet: {
19530
+ source: "generated",
19531
+ file: "generated/hatchet.svg"
19532
+ },
19258
19533
  hk416: {
19259
19534
  source: "generated",
19260
19535
  file: "generated/hk416.svg"
@@ -19323,6 +19598,14 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
19323
19598
  source: "generated",
19324
19599
  file: "generated/improvised_flamethrower.svg"
19325
19600
  },
19601
+ improvised_spear: {
19602
+ source: "generated",
19603
+ file: "generated/improvised_spear.svg"
19604
+ },
19605
+ iron_pipe: {
19606
+ source: "generated",
19607
+ file: "generated/iron_pipe.svg"
19608
+ },
19326
19609
  kel_tec_ksg: {
19327
19610
  source: "generated",
19328
19611
  file: "generated/kel_tec_ksg.svg"
@@ -19391,6 +19674,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
19391
19674
  source: "generated",
19392
19675
  file: "generated/makarov_pm.svg"
19393
19676
  },
19677
+ meat_cleaver: {
19678
+ source: "generated",
19679
+ file: "generated/meat_cleaver.svg"
19680
+ },
19394
19681
  mg3: {
19395
19682
  source: "generated",
19396
19683
  file: "generated/mg3.svg"
@@ -19415,6 +19702,14 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
19415
19702
  source: "generated",
19416
19703
  file: "generated/mossberg_500_cruiser.svg"
19417
19704
  },
19705
+ nail_bat: {
19706
+ source: "generated",
19707
+ file: "generated/nail_bat.svg"
19708
+ },
19709
+ pickaxe: {
19710
+ source: "generated",
19711
+ file: "generated/pickaxe.svg"
19712
+ },
19418
19713
  pipe_bomb: {
19419
19714
  source: "generated",
19420
19715
  file: "generated/pipe_bomb.svg"
@@ -19435,6 +19730,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
19435
19730
  source: "generated",
19436
19731
  file: "generated/pkm.svg"
19437
19732
  },
19733
+ police_baton: {
19734
+ source: "generated",
19735
+ file: "generated/police_baton.svg"
19736
+ },
19438
19737
  pp19_bizon: {
19439
19738
  source: "generated",
19440
19739
  file: "generated/pp19_bizon.svg"
@@ -19447,6 +19746,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
19447
19746
  source: "generated",
19448
19747
  file: "generated/pry_bar.svg"
19449
19748
  },
19749
+ recurve_bow: {
19750
+ source: "generated",
19751
+ file: "generated/recurve_bow.svg"
19752
+ },
19450
19753
  remington_700: {
19451
19754
  source: "generated",
19452
19755
  file: "generated/remington_700.svg"
@@ -19523,6 +19826,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
19523
19826
  source: "generated",
19524
19827
  file: "generated/shotgun_semi_12.svg"
19525
19828
  },
19829
+ sickle: {
19830
+ source: "generated",
19831
+ file: "generated/sickle.svg"
19832
+ },
19526
19833
  sig_mpx: {
19527
19834
  source: "generated",
19528
19835
  file: "generated/sig_mpx.svg"
@@ -19575,6 +19882,10 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
19575
19882
  source: "generated",
19576
19883
  file: "generated/sw_model_29.svg"
19577
19884
  },
19885
+ tactical_knife: {
19886
+ source: "generated",
19887
+ file: "generated/tactical_knife.svg"
19888
+ },
19578
19889
  taurus_82: {
19579
19890
  source: "generated",
19580
19891
  file: "generated/taurus_82.svg"