@adatechnology/game-weapons-three 0.3.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.
Files changed (191) hide show
  1. package/README.md +14 -0
  2. package/assets/weapon-svg/CREDITS.md +25 -0
  3. package/assets/weapon-svg/LICENSE-NOTE.md +18 -0
  4. package/assets/weapon-svg/commons/ak_47.svg +1 -0
  5. package/assets/weapon-svg/commons/barrett_m82a1.svg +1 -0
  6. package/assets/weapon-svg/commons/benelli_m4.svg +1 -0
  7. package/assets/weapon-svg/commons/beretta_92fs.svg +1 -0
  8. package/assets/weapon-svg/commons/colt_m16a2.svg +1 -0
  9. package/assets/weapon-svg/commons/colt_m1911.svg +1 -0
  10. package/assets/weapon-svg/commons/colt_m4a1.svg +1 -0
  11. package/assets/weapon-svg/commons/desert_eagle_mark_xix.svg +1 -0
  12. package/assets/weapon-svg/commons/glock_19.svg +1 -0
  13. package/assets/weapon-svg/commons/hk_mp5a3.svg +1 -0
  14. package/assets/weapon-svg/commons/hk_mp5k.svg +1 -0
  15. package/assets/weapon-svg/commons/mac_10.svg +1 -0
  16. package/assets/weapon-svg/commons/sako_trg_42.svg +1 -0
  17. package/assets/weapon-svg/commons/steyr_aug_a1.svg +1 -0
  18. package/assets/weapon-svg/commons/svd_dragunov.svg +1 -0
  19. package/assets/weapon-svg/commons/utility_knife.svg +1 -0
  20. package/assets/weapon-svg/commons/uzi.svg +1 -0
  21. package/assets/weapon-svg/commons/vz61.svg +1 -0
  22. package/assets/weapon-svg/commons-sources.json +151 -0
  23. package/assets/weapon-svg/credits.html +36 -0
  24. package/assets/weapon-svg/generated/aa_12.svg +1 -0
  25. package/assets/weapon-svg/generated/accuracy_awm.svg +1 -0
  26. package/assets/weapon-svg/generated/ag36.svg +1 -0
  27. package/assets/weapon-svg/generated/ak_12.svg +1 -0
  28. package/assets/weapon-svg/generated/ak_47.svg +1 -0
  29. package/assets/weapon-svg/generated/ak_74.svg +1 -0
  30. package/assets/weapon-svg/generated/akm.svg +1 -0
  31. package/assets/weapon-svg/generated/anti_materiel_50.svg +1 -0
  32. package/assets/weapon-svg/generated/at4.svg +1 -0
  33. package/assets/weapon-svg/generated/axe.svg +1 -0
  34. package/assets/weapon-svg/generated/barrett_m82a1.svg +1 -0
  35. package/assets/weapon-svg/generated/barrett_mrad.svg +1 -0
  36. package/assets/weapon-svg/generated/baseball_bat.svg +1 -0
  37. package/assets/weapon-svg/generated/benelli_m4.svg +1 -0
  38. package/assets/weapon-svg/generated/beretta_92fs.svg +1 -0
  39. package/assets/weapon-svg/generated/blowtorch.svg +1 -0
  40. package/assets/weapon-svg/generated/boito_double_barrel.svg +1 -0
  41. package/assets/weapon-svg/generated/bow_compound.svg +1 -0
  42. package/assets/weapon-svg/generated/browning_m2.svg +1 -0
  43. package/assets/weapon-svg/generated/c4.svg +1 -0
  44. package/assets/weapon-svg/generated/car_fuel_tank.svg +1 -0
  45. package/assets/weapon-svg/generated/carbine_22.svg +1 -0
  46. package/assets/weapon-svg/generated/carl_gustaf_m4.svg +1 -0
  47. package/assets/weapon-svg/generated/cast_iron_skillet.svg +1 -0
  48. package/assets/weapon-svg/generated/cbc_122.svg +1 -0
  49. package/assets/weapon-svg/generated/cbc_7022.svg +1 -0
  50. package/assets/weapon-svg/generated/cbc_pump_military_3_0.svg +1 -0
  51. package/assets/weapon-svg/generated/chainsaw.svg +1 -0
  52. package/assets/weapon-svg/generated/cheytac_m200.svg +1 -0
  53. package/assets/weapon-svg/generated/claw_hammer.svg +1 -0
  54. package/assets/weapon-svg/generated/claymore.svg +1 -0
  55. package/assets/weapon-svg/generated/colt_m16a2.svg +1 -0
  56. package/assets/weapon-svg/generated/colt_m1911.svg +1 -0
  57. package/assets/weapon-svg/generated/colt_m4a1.svg +1 -0
  58. package/assets/weapon-svg/generated/crossbow.svg +1 -0
  59. package/assets/weapon-svg/generated/crowbar.svg +1 -0
  60. package/assets/weapon-svg/generated/cutting_torch.svg +1 -0
  61. package/assets/weapon-svg/generated/cz_75.svg +1 -0
  62. package/assets/weapon-svg/generated/cz_scorpion_evo_3.svg +1 -0
  63. package/assets/weapon-svg/generated/desert_eagle_mark_xix.svg +1 -0
  64. package/assets/weapon-svg/generated/dynamite.svg +1 -0
  65. package/assets/weapon-svg/generated/extinguisher.svg +1 -0
  66. package/assets/weapon-svg/generated/flamethrower.svg +1 -0
  67. package/assets/weapon-svg/generated/flashbang.svg +1 -0
  68. package/assets/weapon-svg/generated/fn_fal.svg +1 -0
  69. package/assets/weapon-svg/generated/fn_five_seven.svg +1 -0
  70. package/assets/weapon-svg/generated/fn_m249.svg +1 -0
  71. package/assets/weapon-svg/generated/fn_mag.svg +1 -0
  72. package/assets/weapon-svg/generated/fn_minimi.svg +1 -0
  73. package/assets/weapon-svg/generated/fn_minimi_para.svg +1 -0
  74. package/assets/weapon-svg/generated/fn_p90.svg +1 -0
  75. package/assets/weapon-svg/generated/fn_parafal.svg +1 -0
  76. package/assets/weapon-svg/generated/fn_scar_h.svg +1 -0
  77. package/assets/weapon-svg/generated/frag_grenade.svg +1 -0
  78. package/assets/weapon-svg/generated/franchi_spas_12.svg +1 -0
  79. package/assets/weapon-svg/generated/fuel_barrel.svg +1 -0
  80. package/assets/weapon-svg/generated/glock_17.svg +1 -0
  81. package/assets/weapon-svg/generated/glock_18.svg +1 -0
  82. package/assets/weapon-svg/generated/glock_19.svg +1 -0
  83. package/assets/weapon-svg/generated/gp_25.svg +1 -0
  84. package/assets/weapon-svg/generated/hacksaw.svg +1 -0
  85. package/assets/weapon-svg/generated/hammer.svg +1 -0
  86. package/assets/weapon-svg/generated/hatchet.svg +1 -0
  87. package/assets/weapon-svg/generated/hk416.svg +1 -0
  88. package/assets/weapon-svg/generated/hk_g36.svg +1 -0
  89. package/assets/weapon-svg/generated/hk_g36c.svg +1 -0
  90. package/assets/weapon-svg/generated/hk_g36k.svg +1 -0
  91. package/assets/weapon-svg/generated/hk_g3a3.svg +1 -0
  92. package/assets/weapon-svg/generated/hk_mp5a3.svg +1 -0
  93. package/assets/weapon-svg/generated/hk_mp5k.svg +1 -0
  94. package/assets/weapon-svg/generated/hk_mp5sd3.svg +1 -0
  95. package/assets/weapon-svg/generated/hk_mp7a1.svg +1 -0
  96. package/assets/weapon-svg/generated/hk_psg_1.svg +1 -0
  97. package/assets/weapon-svg/generated/hk_ump9.svg +1 -0
  98. package/assets/weapon-svg/generated/hk_ump_45.svg +1 -0
  99. package/assets/weapon-svg/generated/hunting_rifle_30_06.svg +1 -0
  100. package/assets/weapon-svg/generated/imbel_ia2.svg +1 -0
  101. package/assets/weapon-svg/generated/improvised_flamethrower.svg +1 -0
  102. package/assets/weapon-svg/generated/improvised_spear.svg +1 -0
  103. package/assets/weapon-svg/generated/iron_pipe.svg +1 -0
  104. package/assets/weapon-svg/generated/kel_tec_ksg.svg +1 -0
  105. package/assets/weapon-svg/generated/knife.svg +1 -0
  106. package/assets/weapon-svg/generated/knights_sr_25_mk11.svg +1 -0
  107. package/assets/weapon-svg/generated/kriss_vector.svg +1 -0
  108. package/assets/weapon-svg/generated/lighter.svg +1 -0
  109. package/assets/weapon-svg/generated/m134.svg +1 -0
  110. package/assets/weapon-svg/generated/m14_ebr.svg +1 -0
  111. package/assets/weapon-svg/generated/m203.svg +1 -0
  112. package/assets/weapon-svg/generated/m24_sws.svg +1 -0
  113. package/assets/weapon-svg/generated/m2_flamethrower.svg +1 -0
  114. package/assets/weapon-svg/generated/m60.svg +1 -0
  115. package/assets/weapon-svg/generated/m72_law.svg +1 -0
  116. package/assets/weapon-svg/generated/m79.svg +1 -0
  117. package/assets/weapon-svg/generated/mac_10.svg +1 -0
  118. package/assets/weapon-svg/generated/machete.svg +1 -0
  119. package/assets/weapon-svg/generated/makarov_pm.svg +1 -0
  120. package/assets/weapon-svg/generated/meat_cleaver.svg +1 -0
  121. package/assets/weapon-svg/generated/mg3.svg +1 -0
  122. package/assets/weapon-svg/generated/mini_uzi.svg +1 -0
  123. package/assets/weapon-svg/generated/molotov.svg +1 -0
  124. package/assets/weapon-svg/generated/mosin_nagant_91_30.svg +1 -0
  125. package/assets/weapon-svg/generated/mossberg_500.svg +1 -0
  126. package/assets/weapon-svg/generated/mossberg_500_cruiser.svg +1 -0
  127. package/assets/weapon-svg/generated/nail_bat.svg +1 -0
  128. package/assets/weapon-svg/generated/pickaxe.svg +1 -0
  129. package/assets/weapon-svg/generated/pipe_bomb.svg +1 -0
  130. package/assets/weapon-svg/generated/pistol_22.svg +1 -0
  131. package/assets/weapon-svg/generated/pistol_45.svg +1 -0
  132. package/assets/weapon-svg/generated/pistol_9mm.svg +1 -0
  133. package/assets/weapon-svg/generated/pkm.svg +1 -0
  134. package/assets/weapon-svg/generated/police_baton.svg +1 -0
  135. package/assets/weapon-svg/generated/pp19_bizon.svg +1 -0
  136. package/assets/weapon-svg/generated/propane_p13.svg +1 -0
  137. package/assets/weapon-svg/generated/pry_bar.svg +1 -0
  138. package/assets/weapon-svg/generated/recurve_bow.svg +1 -0
  139. package/assets/weapon-svg/generated/remington_700.svg +1 -0
  140. package/assets/weapon-svg/generated/remington_700_300wm.svg +1 -0
  141. package/assets/weapon-svg/generated/remington_870.svg +1 -0
  142. package/assets/weapon-svg/generated/revolver_357.svg +1 -0
  143. package/assets/weapon-svg/generated/revolver_38.svg +1 -0
  144. package/assets/weapon-svg/generated/rifle_5_56.svg +1 -0
  145. package/assets/weapon-svg/generated/rifle_7_62x39.svg +1 -0
  146. package/assets/weapon-svg/generated/rifle_bolt_308.svg +1 -0
  147. package/assets/weapon-svg/generated/rossi_puma.svg +1 -0
  148. package/assets/weapon-svg/generated/rpg_7.svg +1 -0
  149. package/assets/weapon-svg/generated/rpk.svg +1 -0
  150. package/assets/weapon-svg/generated/ruger_10_22.svg +1 -0
  151. package/assets/weapon-svg/generated/saiga_12.svg +1 -0
  152. package/assets/weapon-svg/generated/sako_trg_42.svg +1 -0
  153. package/assets/weapon-svg/generated/screwdriver.svg +1 -0
  154. package/assets/weapon-svg/generated/shotgun_double_12.svg +1 -0
  155. package/assets/weapon-svg/generated/shotgun_pump_12.svg +1 -0
  156. package/assets/weapon-svg/generated/shotgun_semi_12.svg +1 -0
  157. package/assets/weapon-svg/generated/sickle.svg +1 -0
  158. package/assets/weapon-svg/generated/sig_mpx.svg +1 -0
  159. package/assets/weapon-svg/generated/sig_sauer_p226.svg +1 -0
  160. package/assets/weapon-svg/generated/sks.svg +1 -0
  161. package/assets/weapon-svg/generated/sledgehammer.svg +1 -0
  162. package/assets/weapon-svg/generated/smg_9mm.svg +1 -0
  163. package/assets/weapon-svg/generated/sniper_338.svg +1 -0
  164. package/assets/weapon-svg/generated/steyr_aug_a1.svg +1 -0
  165. package/assets/weapon-svg/generated/steyr_ssg_69.svg +1 -0
  166. package/assets/weapon-svg/generated/svd_dragunov.svg +1 -0
  167. package/assets/weapon-svg/generated/sw_686.svg +1 -0
  168. package/assets/weapon-svg/generated/sw_model_29.svg +1 -0
  169. package/assets/weapon-svg/generated/tactical_knife.svg +1 -0
  170. package/assets/weapon-svg/generated/taurus_82.svg +1 -0
  171. package/assets/weapon-svg/generated/taurus_g2c.svg +1 -0
  172. package/assets/weapon-svg/generated/taurus_pt100.svg +1 -0
  173. package/assets/weapon-svg/generated/taurus_smt9.svg +1 -0
  174. package/assets/weapon-svg/generated/taurus_t4.svg +1 -0
  175. package/assets/weapon-svg/generated/taurus_t4_civil.svg +1 -0
  176. package/assets/weapon-svg/generated/taurus_th380.svg +1 -0
  177. package/assets/weapon-svg/generated/taurus_ts9.svg +1 -0
  178. package/assets/weapon-svg/generated/thompson_m1a1.svg +1 -0
  179. package/assets/weapon-svg/generated/utility_knife.svg +1 -0
  180. package/assets/weapon-svg/generated/uzi.svg +1 -0
  181. package/assets/weapon-svg/generated/vz61.svg +1 -0
  182. package/assets/weapon-svg/generated/winchester_1894.svg +1 -0
  183. package/assets/weapon-svg/generated/wrench.svg +1 -0
  184. package/assets/weapon-svg/manifest.json +717 -0
  185. package/dist/index.d.ts +22 -1
  186. package/dist/index.global.js +1266 -261
  187. package/dist/index.global.js.map +1 -1
  188. package/dist/index.js +747 -53
  189. package/dist/index.js.map +1 -1
  190. package/package.json +10 -8
  191. package/LICENSE +0 -21
@@ -27,12 +27,14 @@ var GameWeaponsThree = (() => {
27
27
  CLASS_REFERENCE_ENERGY: () => CLASS_REFERENCE_ENERGY,
28
28
  COUNTER_ITEM_ID: () => COUNTER_ITEM_ID,
29
29
  DEFAULT_ENERGY_CURVE: () => DEFAULT_ENERGY_CURVE,
30
+ DEFAULT_THUMBNAIL_BASE: () => DEFAULT_THUMBNAIL_BASE,
30
31
  GAME_DISTANCE_CURVE: () => GAME_DISTANCE_CURVE,
31
32
  GAME_SOUND_CLASSES: () => GAME_SOUND_CLASSES,
32
33
  MECHANICAL_SOUNDS: () => MECHANICAL_SOUNDS,
33
34
  MODEL_ENTRIES: () => MODEL_ENTRIES,
34
35
  MOUNTED_M134_ITEM_ID: () => MOUNTED_M134_ITEM_ID,
35
36
  WEAPON_ITEM_PREFIX: () => WEAPON_ITEM_PREFIX,
37
+ WEAPON_THUMBNAILS: () => WEAPON_THUMBNAILS,
36
38
  WORLD_EXPLOSIVE_IDS: () => WORLD_EXPLOSIVE_IDS,
37
39
  WORLD_EXPLOSIVE_PREFIX: () => WORLD_EXPLOSIVE_PREFIX,
38
40
  applyCondition: () => applyCondition,
@@ -58,10 +60,205 @@ var GameWeaponsThree = (() => {
58
60
  rigStock: () => rigStock,
59
61
  rigUnderbarrel: () => rigUnderbarrel,
60
62
  weaponProp: () => weaponProp,
63
+ weaponThumbnailCredit: () => weaponThumbnailCredit,
64
+ weaponThumbnailUrl: () => weaponThumbnailUrl,
61
65
  weaponsLayout: () => weaponsLayout,
62
66
  worldExplosiveItem: () => worldExplosiveItem
63
67
  });
64
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
+
65
262
  // ../game-weapons/dist/index.js
66
263
  var __defProp2 = Object.defineProperty;
67
264
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -11134,69 +11331,270 @@ var GameWeaponsThree = (() => {
11134
11331
  if (context.isCompatible && !context.isCompatible(def, attachment, fitted)) return { ok: false, reason: "rejected" };
11135
11332
  return { ok: true, mount: place.kind };
11136
11333
  };
11137
- var findDuplicateIds = (kind, entries) => {
11138
- const seen = /* @__PURE__ */ new Set();
11139
- const problems = [];
11140
- for (const { id } of entries ?? []) {
11141
- if (seen.has(id)) problems.push(`${kind} "${id}" is listed more than once`);
11142
- seen.add(id);
11143
- }
11144
- return problems;
11145
- };
11146
- var checkRotary = (id, action) => {
11147
- const problems = [];
11148
- const { rpm, rpmRange, spin } = action;
11149
- if (rpmRange && !(rpmRange[0] > 0 && rpmRange[0] <= rpmRange[1])) problems.push(`weapon "${id}" has an empty rate range ${rpmRange[0]}-${rpmRange[1]} rpm`);
11150
- if (rpmRange && (rpm < rpmRange[0] || rpm > rpmRange[1])) problems.push(`weapon "${id}" fires at ${rpm} rpm, outside its range ${rpmRange[0]}-${rpmRange[1]}`);
11151
- if (spin && !(spin.upSeconds >= 0 && spin.holdSeconds >= 0)) problems.push(`weapon "${id}" has a negative spin time`);
11152
- return problems;
11153
- };
11154
- var checkFirearm = (def, calibers) => {
11155
- if (def.action.kind !== "firearm") return [];
11156
- const problems = [];
11157
- for (const caliber of [def.action.caliber, ...def.action.acceptsCalibers ?? []]) {
11158
- if (!calibers.has(caliber)) problems.push(`weapon "${def.id}" uses unknown calibre "${caliber}"`);
11159
- }
11160
- if (def.action.modes.length === 0) problems.push(`weapon "${def.id}" has no fire modes`);
11161
- if (!(def.action.rpm > 0)) problems.push(`weapon "${def.id}" has a rate of fire of ${def.action.rpm} rpm`);
11162
- if (!(def.action.reload > 0)) problems.push(`weapon "${def.id}" has a reload time of ${def.action.reload} s`);
11163
- problems.push(...checkRotary(def.id, def.action));
11164
- return problems;
11165
- };
11166
- var checkTimings = (def) => {
11167
- const timings = "timings" in def.action ? def.action.timings : void 0;
11168
- return Object.entries(timings ?? {}).filter(([, seconds]) => typeof seconds === "number" && !(seconds > 0)).map(([name, seconds]) => `weapon "${def.id}" has a ${name} time of ${seconds} s`);
11169
- };
11170
- var checkExplosiveReference = (def, explosives) => {
11171
- const id = def.action.kind === "launcher" ? def.action.projectile : def.action.kind === "throwable" ? def.action.explosive : void 0;
11172
- return id !== void 0 && !explosives.has(id) ? [`weapon "${def.id}" uses unknown explosive "${id}"`] : [];
11173
- };
11174
- var checkExplosiveNumbers = (explosive) => {
11175
- const problems = [];
11176
- const [low, high] = explosive.fuseRange ?? [1, 1];
11177
- if (!(low > 0 && high >= low)) problems.push(`explosive "${explosive.id}" has a fuse range of ${low} to ${high} s`);
11178
- if (explosive.fuseLength !== void 0 && !(explosive.fuseLength > 0)) problems.push(`explosive "${explosive.id}" has a fuse length of ${explosive.fuseLength} m`);
11179
- if (explosive.burnRate !== void 0 && !(explosive.burnRate > 0)) problems.push(`explosive "${explosive.id}" has a burn rate of ${explosive.burnRate} s/m`);
11180
- if (explosive.burnTolerance !== void 0 && !(explosive.burnTolerance >= 0 && explosive.burnTolerance < 1)) problems.push(`explosive "${explosive.id}" has a burn tolerance of ${explosive.burnTolerance}`);
11181
- if (explosive.tripwire && !(explosive.tripwire.length > 0)) problems.push(`explosive "${explosive.id}" has a trip wire of ${explosive.tripwire.length} m`);
11182
- return problems;
11183
- };
11184
- var STATS = /* @__PURE__ */ new Set(["noise", "spread", "hipSpreadExcess", "recoilVertical", "recoilHorizontal", "range", "muzzleSpeed", "mass", "capacity", "reload", "reloadEmpty", "draw", "aim", "faultChance", "heatPerShot"]);
11185
- var INSTALLS = /* @__PURE__ */ new Set(["field", "tool", "bench"]);
11186
- var checkAttachment = (attachment, weapons) => {
11187
- const problems = [];
11188
- 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`);
11189
- const label = `attachment "${attachment.id}"`;
11190
- if (!INSTALLS.has(attachment.install)) problems.push(`${label} installs "${attachment.install}"`);
11191
- if (attachment.mounts.length === 0) problems.push(`${label} has no mount`);
11192
- if (attachment.interfaces.length === 0) problems.push(`${label} has no interface`);
11193
- for (const effect of attachment.effects) {
11194
- if (!STATS.has(effect.stat)) problems.push(`${label} changes the unknown stat "${effect.stat}"`);
11195
- if (effect.mul !== void 0 && !(effect.mul > 0)) problems.push(`${label} multiplies ${effect.stat} by ${effect.mul}`);
11196
- }
11197
- return problems;
11198
- };
11199
- 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) => {
11200
11598
  if (!attachments) return [];
11201
11599
  return (def.fitted ?? []).flatMap((part) => {
11202
11600
  const problems = [];
@@ -11218,18 +11616,6 @@ var GameWeaponsThree = (() => {
11218
11616
  ...[...explosives.values()].flatMap(checkExplosiveNumbers),
11219
11617
  ...checkRuleDefaults(rules)
11220
11618
  ];
11221
- var UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
11222
- var isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
11223
- var deepMerge = (base, patch) => {
11224
- if (!patch) return base;
11225
- const result2 = { ...base };
11226
- for (const [key, value] of Object.entries(patch)) {
11227
- if (value === void 0 || UNSAFE_KEYS.has(key)) continue;
11228
- const current = result2[key];
11229
- result2[key] = isPlainObject(current) && isPlainObject(value) ? deepMerge(current, value) : value;
11230
- }
11231
- return result2;
11232
- };
11233
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" };
11234
11620
  var categoriesEn = {
11235
11621
  pistol: "pistol",
@@ -11421,20 +11807,6 @@ var GameWeaponsThree = (() => {
11421
11807
  if (explosive.fuseRange) return explosive.fuseRange[0] + (explosive.fuseRange[1] - explosive.fuseRange[0]) * random();
11422
11808
  return explosive.fuse;
11423
11809
  };
11424
- var mergeById = (shipped, extra) => {
11425
- const entries = /* @__PURE__ */ new Map();
11426
- for (const entry of [...shipped, ...extra ?? []]) entries.set(entry.id, entry);
11427
- return entries;
11428
- };
11429
- var applyPatches = (entries, patches) => {
11430
- for (const [id, patch] of Object.entries(patches ?? {})) {
11431
- const entry = entries.get(id);
11432
- if (entry) entries.set(id, deepMerge(entry, patch));
11433
- }
11434
- };
11435
- var removeIds = (entries, ids) => {
11436
- for (const id of ids ?? []) entries.delete(id);
11437
- };
11438
11810
  var resolveThrowables = (weapons, explosives) => {
11439
11811
  for (const [id, def] of weapons) {
11440
11812
  if (def.action.kind !== "throwable" || def.action.explosive === void 0) continue;
@@ -12670,6 +13042,7 @@ var GameWeaponsThree = (() => {
12670
13042
  caliber: cal.diameter,
12671
13043
  caliberId: cal.id,
12672
13044
  speed,
13045
+ mass: cal.bulletGrams,
12673
13046
  energyAt,
12674
13047
  pellet: p,
12675
13048
  weapon: this.def.id
@@ -12855,7 +13228,7 @@ var GameWeaponsThree = (() => {
12855
13228
  var EXPLOSIVES = explosives_default;
12856
13229
  var ARCHETYPES = archetypes_default;
12857
13230
  var ARCHETYPE_IDS = ARCHETYPES.map((def) => def.id);
12858
- var WEAPONS = [...ARCHETYPES, ...firearms_default, ...launchers_default, ...explosive_weapons_default];
13231
+ var WEAPONS = [...ARCHETYPES, ...firearms_default, ...launchers_default, ...explosive_weapons_default, ...melee_weapons_default];
12859
13232
  var explosiveOf = (def, explosives) => {
12860
13233
  const id = def.action.kind === "launcher" ? def.action.projectile : def.action.kind === "throwable" ? def.action.explosive : void 0;
12861
13234
  return id === void 0 ? null : explosives.get(id) ?? null;
@@ -13601,7 +13974,68 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
13601
13974
  };
13602
13975
  };
13603
13976
 
13604
- // 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]));
13605
14039
  var ATTRIBUTES = ["position", "normal", "uv"];
13606
14040
  var isVisible = (object) => {
13607
14041
  for (let node = object; node; node = node.parent) if (!node.visible) return false;
@@ -17022,173 +17456,6 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
17022
17456
  };
17023
17457
  }
17024
17458
 
17025
- // ../game-contracts/dist/index.js
17026
- var TOOL_CLIP = {
17027
- DRAW: "draw",
17028
- SHOT: "shot",
17029
- MISFIRE: "misfire",
17030
- EMPTY: "empty",
17031
- CYCLE: "cycle",
17032
- RELOAD: "reload",
17033
- FEED: "feed",
17034
- FAULT: "fault",
17035
- CLEAR: "clear",
17036
- SAFETY_ON: "safety_on",
17037
- SAFETY_OFF: "safety_off",
17038
- MODE: "mode",
17039
- /** A throwable with the pin out, held until it is thrown. */
17040
- COOK: "cook",
17041
- /** The stock folds, unfolds, slides in or out (variants `fold`, `unfold`, `collapse`, `extend`). */
17042
- STOCK: "stock",
17043
- /** A light or a laser is switched (variants `on`, `off`). */
17044
- TOGGLE: "toggle"
17045
- };
17046
- var stockVariant = (event) => {
17047
- const isFolding = event.kind === void 0 ? false : event.kind.includes("fold");
17048
- if (event.state === "collapsed") return isFolding ? "fold" : "collapse";
17049
- return isFolding ? "unfold" : "extend";
17050
- };
17051
- var toolAnimationStep = (event) => {
17052
- switch (event.type) {
17053
- case "tool":
17054
- return { type: "play", clip: TOOL_CLIP.DRAW, ...event.duration === void 0 ? {} : { duration: event.duration } };
17055
- case "shot":
17056
- return { type: "play", clip: TOOL_CLIP.SHOT, repeat: Math.max(1, event.rounds ?? 1) };
17057
- case "misfire":
17058
- return { type: "play", clip: TOOL_CLIP.MISFIRE };
17059
- case "empty":
17060
- return { type: "play", clip: TOOL_CLIP.EMPTY };
17061
- case "mode":
17062
- return { type: "play", clip: TOOL_CLIP.MODE, variant: event.mode };
17063
- case "fault":
17064
- return { type: "play", clip: TOOL_CLIP.FAULT, variant: event.fault };
17065
- case "clear":
17066
- if (event.phase === "end") return { type: "finish", clip: TOOL_CLIP.CLEAR };
17067
- return { type: "play", clip: TOOL_CLIP.CLEAR, variant: event.fault, ...event.duration === void 0 ? {} : { duration: event.duration } };
17068
- case "safety":
17069
- return { type: "play", clip: event.on ? TOOL_CLIP.SAFETY_ON : TOOL_CLIP.SAFETY_OFF };
17070
- case "cycle":
17071
- if (event.phase === "end") return { type: "finish", clip: TOOL_CLIP.CYCLE };
17072
- return { type: "play", clip: TOOL_CLIP.CYCLE, ...event.duration === void 0 ? {} : { duration: event.duration } };
17073
- case "reload":
17074
- if (event.phase === "end") return { type: "finish", clip: TOOL_CLIP.RELOAD };
17075
- return { type: "play", clip: TOOL_CLIP.RELOAD, ...event.kind === void 0 ? {} : { variant: event.kind }, ...event.duration === void 0 ? {} : { duration: event.duration } };
17076
- case "stage":
17077
- return { type: "sync", stage: event.stage };
17078
- case "feed":
17079
- return { type: "play", clip: TOOL_CLIP.FEED };
17080
- case "cook":
17081
- if (event.phase === "start") return { type: "play", clip: TOOL_CLIP.COOK, duration: event.fuse };
17082
- return { type: "finish", clip: TOOL_CLIP.COOK };
17083
- case "stock":
17084
- return { type: "play", clip: TOOL_CLIP.STOCK, variant: stockVariant(event), ...event.duration === void 0 ? {} : { duration: event.duration } };
17085
- case "toggle":
17086
- return { type: "play", clip: TOOL_CLIP.TOGGLE, variant: event.on ? "on" : "off" };
17087
- default:
17088
- return null;
17089
- }
17090
- };
17091
- var STAGE_EVENT = "stage";
17092
- var scaleClip = (clip, duration) => {
17093
- const factor = clip.duration > 0 ? duration / clip.duration : 1;
17094
- return {
17095
- ...clip,
17096
- duration,
17097
- keys: clip.keys.map((key) => ({ ...key, t: key.t * factor })),
17098
- ...clip.events ? { events: clip.events.map((event) => ({ ...event, t: event.t * factor })) } : {}
17099
- };
17100
- };
17101
- var ZERO = [0, 0, 0];
17102
- var mix = (from, to, fraction) => [
17103
- (from[0] ?? 0) + ((to[0] ?? 0) - (from[0] ?? 0)) * fraction,
17104
- (from[1] ?? 0) + ((to[1] ?? 0) - (from[1] ?? 0)) * fraction,
17105
- (from[2] ?? 0) + ((to[2] ?? 0) - (from[2] ?? 0)) * fraction
17106
- ];
17107
- var sampleClip = (clip, partId, time) => {
17108
- const points = clip.keys.map((key) => {
17109
- const pose = partId === void 0 ? key : key.parts?.[partId];
17110
- return { t: key.t, position: pose?.position ?? ZERO, rotation: pose?.rotation ?? ZERO };
17111
- });
17112
- const first = points[0];
17113
- if (!first || first.t > 0) points.unshift({ t: 0, position: ZERO, rotation: ZERO });
17114
- const last = points[points.length - 1];
17115
- if (!last) return { position: ZERO, rotation: ZERO };
17116
- if (time >= last.t) return { position: mix(last.position, last.position, 0), rotation: mix(last.rotation, last.rotation, 0) };
17117
- const index = Math.max(0, points.findIndex((point, i) => time >= point.t && time < (points[i + 1]?.t ?? Infinity)));
17118
- const from = points[index];
17119
- const to = points[index + 1];
17120
- if (!from || !to) return { position: ZERO, rotation: ZERO };
17121
- const fraction = to.t > from.t ? (time - from.t) / (to.t - from.t) : 0;
17122
- return { position: mix(from.position, to.position, fraction), rotation: mix(from.rotation, to.rotation, fraction) };
17123
- };
17124
- var createToolClipPlayer = (options) => {
17125
- const { clips, rig, onEvent } = options;
17126
- let instances = [];
17127
- const find = (clip, variant) => {
17128
- const name = variant !== void 0 && clips[`${clip}_${variant}`] ? `${clip}_${variant}` : clip;
17129
- const found = clips[name];
17130
- return found ? { name, clip: found } : void 0;
17131
- };
17132
- const render = (instance) => {
17133
- const time = Math.min(instance.time, instance.clip.duration);
17134
- const root = sampleClip(instance.clip, void 0, time);
17135
- if (instance.clip.keys.some((key) => key.position || key.rotation)) rig.setRootPose?.(root);
17136
- const touched = new Set(instance.clip.keys.flatMap((key) => Object.keys(key.parts ?? {})));
17137
- for (const id of touched) rig.setPartPose(id, sampleClip(instance.clip, id, time));
17138
- };
17139
- const fireEvents = (instance, upTo) => {
17140
- const events = instance.clip.events ?? [];
17141
- while (instance.fired < events.length && (events[instance.fired]?.t ?? Infinity) <= upTo + 1e-9) {
17142
- const event = events[instance.fired];
17143
- instance.fired += 1;
17144
- if (event) onEvent?.(event, instance.name);
17145
- }
17146
- };
17147
- return {
17148
- apply(step) {
17149
- if (step.type === "sync") {
17150
- for (const instance of instances) {
17151
- const marker = (instance.clip.events ?? []).find((event) => event.type === STAGE_EVENT && event.data?.stage === step.stage);
17152
- if (marker && instance.time < marker.t) instance.time = marker.t;
17153
- }
17154
- return;
17155
- }
17156
- if (step.type === "finish") {
17157
- for (const instance of instances) {
17158
- if (instance.name !== step.clip && !instance.name.startsWith(`${step.clip}_`)) continue;
17159
- fireEvents(instance, instance.clip.duration);
17160
- instance.time = instance.clip.duration;
17161
- }
17162
- return;
17163
- }
17164
- const found = find(step.clip, step.variant);
17165
- if (!found) return;
17166
- const clip = step.duration && step.duration > 0 ? scaleClip(found.clip, step.duration) : found.clip;
17167
- const interval = options.repeatInterval?.() ?? 0.1;
17168
- instances = instances.filter((existing) => existing.name !== found.name || existing.delay > 0);
17169
- for (let round2 = 0; round2 < (step.repeat ?? 1); round2++) {
17170
- instances.push({ name: found.name, clip, time: 0, delay: round2 * interval, fired: 0 });
17171
- }
17172
- },
17173
- update(dt) {
17174
- for (const instance of instances) {
17175
- const carried = instance.delay > 0 ? dt - instance.delay : dt;
17176
- if (instance.delay > 0) {
17177
- instance.delay = Math.max(0, instance.delay - dt);
17178
- if (instance.delay > 0) continue;
17179
- }
17180
- instance.time += carried;
17181
- fireEvents(instance, instance.time);
17182
- render(instance);
17183
- }
17184
- instances = instances.filter((instance) => instance.delay > 0 || instance.time < instance.clip.duration);
17185
- },
17186
- get playing() {
17187
- return instances.map((instance) => instance.name);
17188
- }
17189
- };
17190
- };
17191
-
17192
17459
  // src/animation/clip-builder.ts
17193
17460
  var ROOT = "root";
17194
17461
  var AXIS_INDEX = { x: 0, y: 1, z: 2 };
@@ -18971,6 +19238,737 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
18971
19238
  };
18972
19239
  }
18973
19240
 
19241
+ // assets/weapon-svg/manifest.json
19242
+ var manifest_default = {
19243
+ version: 1,
19244
+ assets: {
19245
+ aa_12: {
19246
+ source: "generated",
19247
+ file: "generated/aa_12.svg"
19248
+ },
19249
+ accuracy_awm: {
19250
+ source: "generated",
19251
+ file: "generated/accuracy_awm.svg"
19252
+ },
19253
+ ag36: {
19254
+ source: "generated",
19255
+ file: "generated/ag36.svg"
19256
+ },
19257
+ ak_12: {
19258
+ source: "generated",
19259
+ file: "generated/ak_12.svg"
19260
+ },
19261
+ ak_47: {
19262
+ source: "commons",
19263
+ file: "commons/ak_47.svg",
19264
+ author: "Bes-ART",
19265
+ license: "CC BY-SA 4.0",
19266
+ licenseUrl: "https://creativecommons.org/licenses/by-sa/4.0",
19267
+ page: "https://commons.wikimedia.org/wiki/File:AK-47_silhouette.svg"
19268
+ },
19269
+ ak_74: {
19270
+ source: "generated",
19271
+ file: "generated/ak_74.svg"
19272
+ },
19273
+ akm: {
19274
+ source: "generated",
19275
+ file: "generated/akm.svg"
19276
+ },
19277
+ anti_materiel_50: {
19278
+ source: "generated",
19279
+ file: "generated/anti_materiel_50.svg"
19280
+ },
19281
+ at4: {
19282
+ source: "generated",
19283
+ file: "generated/at4.svg"
19284
+ },
19285
+ axe: {
19286
+ source: "generated",
19287
+ file: "generated/axe.svg"
19288
+ },
19289
+ barrett_m82a1: {
19290
+ source: "commons",
19291
+ file: "commons/barrett_m82a1.svg",
19292
+ author: "Bes-ART",
19293
+ license: "CC BY-SA 4.0",
19294
+ licenseUrl: "https://creativecommons.org/licenses/by-sa/4.0",
19295
+ page: "https://commons.wikimedia.org/wiki/File:Barret_M82_silhouette.svg"
19296
+ },
19297
+ barrett_mrad: {
19298
+ source: "generated",
19299
+ file: "generated/barrett_mrad.svg"
19300
+ },
19301
+ baseball_bat: {
19302
+ source: "generated",
19303
+ file: "generated/baseball_bat.svg"
19304
+ },
19305
+ benelli_m4: {
19306
+ source: "commons",
19307
+ file: "commons/benelli_m4.svg",
19308
+ author: "Bes-ART",
19309
+ license: "CC BY-SA 4.0",
19310
+ licenseUrl: "https://creativecommons.org/licenses/by-sa/4.0",
19311
+ page: "https://commons.wikimedia.org/wiki/File:Benelli_M4_Super_90_silhouette.svg"
19312
+ },
19313
+ beretta_92fs: {
19314
+ source: "commons",
19315
+ file: "commons/beretta_92fs.svg",
19316
+ author: "Bes-ART",
19317
+ license: "CC BY-SA 4.0",
19318
+ licenseUrl: "https://creativecommons.org/licenses/by-sa/4.0",
19319
+ page: "https://commons.wikimedia.org/wiki/File:Beretta_M9_silhouette.svg"
19320
+ },
19321
+ blowtorch: {
19322
+ source: "generated",
19323
+ file: "generated/blowtorch.svg"
19324
+ },
19325
+ boito_double_barrel: {
19326
+ source: "generated",
19327
+ file: "generated/boito_double_barrel.svg"
19328
+ },
19329
+ bow_compound: {
19330
+ source: "generated",
19331
+ file: "generated/bow_compound.svg"
19332
+ },
19333
+ browning_m2: {
19334
+ source: "generated",
19335
+ file: "generated/browning_m2.svg"
19336
+ },
19337
+ c4: {
19338
+ source: "generated",
19339
+ file: "generated/c4.svg"
19340
+ },
19341
+ car_fuel_tank: {
19342
+ source: "generated",
19343
+ file: "generated/car_fuel_tank.svg"
19344
+ },
19345
+ carbine_22: {
19346
+ source: "generated",
19347
+ file: "generated/carbine_22.svg"
19348
+ },
19349
+ carl_gustaf_m4: {
19350
+ source: "generated",
19351
+ file: "generated/carl_gustaf_m4.svg"
19352
+ },
19353
+ cast_iron_skillet: {
19354
+ source: "generated",
19355
+ file: "generated/cast_iron_skillet.svg"
19356
+ },
19357
+ cbc_122: {
19358
+ source: "generated",
19359
+ file: "generated/cbc_122.svg"
19360
+ },
19361
+ cbc_7022: {
19362
+ source: "generated",
19363
+ file: "generated/cbc_7022.svg"
19364
+ },
19365
+ cbc_pump_military_3_0: {
19366
+ source: "generated",
19367
+ file: "generated/cbc_pump_military_3_0.svg"
19368
+ },
19369
+ chainsaw: {
19370
+ source: "generated",
19371
+ file: "generated/chainsaw.svg"
19372
+ },
19373
+ cheytac_m200: {
19374
+ source: "generated",
19375
+ file: "generated/cheytac_m200.svg"
19376
+ },
19377
+ claw_hammer: {
19378
+ source: "generated",
19379
+ file: "generated/claw_hammer.svg"
19380
+ },
19381
+ claymore: {
19382
+ source: "generated",
19383
+ file: "generated/claymore.svg"
19384
+ },
19385
+ colt_m16a2: {
19386
+ source: "commons",
19387
+ file: "commons/colt_m16a2.svg",
19388
+ author: "Anonymous",
19389
+ license: "CC0",
19390
+ licenseUrl: "http://creativecommons.org/publicdomain/zero/1.0/deed.en",
19391
+ page: "https://commons.wikimedia.org/wiki/File:M16-Rifle.svg"
19392
+ },
19393
+ colt_m1911: {
19394
+ source: "commons",
19395
+ file: "commons/colt_m1911.svg",
19396
+ author: "Skoll",
19397
+ license: "CC BY 3.0",
19398
+ licenseUrl: "https://creativecommons.org/licenses/by/3.0",
19399
+ page: "https://commons.wikimedia.org/wiki/File:Colt-m1911_-_game-icons.svg"
19400
+ },
19401
+ colt_m4a1: {
19402
+ source: "commons",
19403
+ file: "commons/colt_m4a1.svg",
19404
+ author: "Bes-ART",
19405
+ license: "CC BY-SA 4.0",
19406
+ licenseUrl: "https://creativecommons.org/licenses/by-sa/4.0",
19407
+ page: "https://commons.wikimedia.org/wiki/File:Colt_M4A1_silhouette.svg"
19408
+ },
19409
+ crossbow: {
19410
+ source: "generated",
19411
+ file: "generated/crossbow.svg"
19412
+ },
19413
+ crowbar: {
19414
+ source: "generated",
19415
+ file: "generated/crowbar.svg"
19416
+ },
19417
+ cutting_torch: {
19418
+ source: "generated",
19419
+ file: "generated/cutting_torch.svg"
19420
+ },
19421
+ cz_75: {
19422
+ source: "generated",
19423
+ file: "generated/cz_75.svg"
19424
+ },
19425
+ cz_scorpion_evo_3: {
19426
+ source: "generated",
19427
+ file: "generated/cz_scorpion_evo_3.svg"
19428
+ },
19429
+ desert_eagle_mark_xix: {
19430
+ source: "commons",
19431
+ file: "commons/desert_eagle_mark_xix.svg",
19432
+ author: "Skoll",
19433
+ license: "CC BY 3.0",
19434
+ licenseUrl: "https://creativecommons.org/licenses/by/3.0",
19435
+ page: "https://commons.wikimedia.org/wiki/File:Desert-eagle_-_game-icons.svg"
19436
+ },
19437
+ dynamite: {
19438
+ source: "generated",
19439
+ file: "generated/dynamite.svg"
19440
+ },
19441
+ extinguisher: {
19442
+ source: "generated",
19443
+ file: "generated/extinguisher.svg"
19444
+ },
19445
+ flamethrower: {
19446
+ source: "generated",
19447
+ file: "generated/flamethrower.svg"
19448
+ },
19449
+ flashbang: {
19450
+ source: "generated",
19451
+ file: "generated/flashbang.svg"
19452
+ },
19453
+ fn_fal: {
19454
+ source: "generated",
19455
+ file: "generated/fn_fal.svg"
19456
+ },
19457
+ fn_five_seven: {
19458
+ source: "generated",
19459
+ file: "generated/fn_five_seven.svg"
19460
+ },
19461
+ fn_m249: {
19462
+ source: "generated",
19463
+ file: "generated/fn_m249.svg"
19464
+ },
19465
+ fn_mag: {
19466
+ source: "generated",
19467
+ file: "generated/fn_mag.svg"
19468
+ },
19469
+ fn_minimi: {
19470
+ source: "generated",
19471
+ file: "generated/fn_minimi.svg"
19472
+ },
19473
+ fn_minimi_para: {
19474
+ source: "generated",
19475
+ file: "generated/fn_minimi_para.svg"
19476
+ },
19477
+ fn_p90: {
19478
+ source: "generated",
19479
+ file: "generated/fn_p90.svg"
19480
+ },
19481
+ fn_parafal: {
19482
+ source: "generated",
19483
+ file: "generated/fn_parafal.svg"
19484
+ },
19485
+ fn_scar_h: {
19486
+ source: "generated",
19487
+ file: "generated/fn_scar_h.svg"
19488
+ },
19489
+ frag_grenade: {
19490
+ source: "generated",
19491
+ file: "generated/frag_grenade.svg"
19492
+ },
19493
+ franchi_spas_12: {
19494
+ source: "generated",
19495
+ file: "generated/franchi_spas_12.svg"
19496
+ },
19497
+ fuel_barrel: {
19498
+ source: "generated",
19499
+ file: "generated/fuel_barrel.svg"
19500
+ },
19501
+ glock_17: {
19502
+ source: "generated",
19503
+ file: "generated/glock_17.svg"
19504
+ },
19505
+ glock_18: {
19506
+ source: "generated",
19507
+ file: "generated/glock_18.svg"
19508
+ },
19509
+ glock_19: {
19510
+ source: "commons",
19511
+ file: "commons/glock_19.svg",
19512
+ author: "Bes-ART",
19513
+ license: "CC BY-SA 4.0",
19514
+ licenseUrl: "https://creativecommons.org/licenses/by-sa/4.0",
19515
+ page: "https://commons.wikimedia.org/wiki/File:Glock_19_silhouette.svg"
19516
+ },
19517
+ gp_25: {
19518
+ source: "generated",
19519
+ file: "generated/gp_25.svg"
19520
+ },
19521
+ hacksaw: {
19522
+ source: "generated",
19523
+ file: "generated/hacksaw.svg"
19524
+ },
19525
+ hammer: {
19526
+ source: "generated",
19527
+ file: "generated/hammer.svg"
19528
+ },
19529
+ hatchet: {
19530
+ source: "generated",
19531
+ file: "generated/hatchet.svg"
19532
+ },
19533
+ hk416: {
19534
+ source: "generated",
19535
+ file: "generated/hk416.svg"
19536
+ },
19537
+ hk_g36: {
19538
+ source: "generated",
19539
+ file: "generated/hk_g36.svg"
19540
+ },
19541
+ hk_g36c: {
19542
+ source: "generated",
19543
+ file: "generated/hk_g36c.svg"
19544
+ },
19545
+ hk_g36k: {
19546
+ source: "generated",
19547
+ file: "generated/hk_g36k.svg"
19548
+ },
19549
+ hk_g3a3: {
19550
+ source: "generated",
19551
+ file: "generated/hk_g3a3.svg"
19552
+ },
19553
+ hk_mp5a3: {
19554
+ source: "commons",
19555
+ file: "commons/hk_mp5a3.svg",
19556
+ author: "Bes-ART",
19557
+ license: "CC BY-SA 4.0",
19558
+ licenseUrl: "https://creativecommons.org/licenses/by-sa/4.0",
19559
+ page: "https://commons.wikimedia.org/wiki/File:H%26K_MP5_silhouette.svg"
19560
+ },
19561
+ hk_mp5k: {
19562
+ source: "commons",
19563
+ file: "commons/hk_mp5k.svg",
19564
+ author: "Skoll",
19565
+ license: "CC BY 3.0",
19566
+ licenseUrl: "https://creativecommons.org/licenses/by/3.0",
19567
+ page: "https://commons.wikimedia.org/wiki/File:Mp5k_-_game-icons.svg"
19568
+ },
19569
+ hk_mp5sd3: {
19570
+ source: "generated",
19571
+ file: "generated/hk_mp5sd3.svg"
19572
+ },
19573
+ hk_mp7a1: {
19574
+ source: "generated",
19575
+ file: "generated/hk_mp7a1.svg"
19576
+ },
19577
+ hk_psg_1: {
19578
+ source: "generated",
19579
+ file: "generated/hk_psg_1.svg"
19580
+ },
19581
+ hk_ump9: {
19582
+ source: "generated",
19583
+ file: "generated/hk_ump9.svg"
19584
+ },
19585
+ hk_ump_45: {
19586
+ source: "generated",
19587
+ file: "generated/hk_ump_45.svg"
19588
+ },
19589
+ hunting_rifle_30_06: {
19590
+ source: "generated",
19591
+ file: "generated/hunting_rifle_30_06.svg"
19592
+ },
19593
+ imbel_ia2: {
19594
+ source: "generated",
19595
+ file: "generated/imbel_ia2.svg"
19596
+ },
19597
+ improvised_flamethrower: {
19598
+ source: "generated",
19599
+ file: "generated/improvised_flamethrower.svg"
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
+ },
19609
+ kel_tec_ksg: {
19610
+ source: "generated",
19611
+ file: "generated/kel_tec_ksg.svg"
19612
+ },
19613
+ knife: {
19614
+ source: "generated",
19615
+ file: "generated/knife.svg"
19616
+ },
19617
+ knights_sr_25_mk11: {
19618
+ source: "generated",
19619
+ file: "generated/knights_sr_25_mk11.svg"
19620
+ },
19621
+ kriss_vector: {
19622
+ source: "generated",
19623
+ file: "generated/kriss_vector.svg"
19624
+ },
19625
+ lighter: {
19626
+ source: "generated",
19627
+ file: "generated/lighter.svg"
19628
+ },
19629
+ m134: {
19630
+ source: "generated",
19631
+ file: "generated/m134.svg"
19632
+ },
19633
+ m14_ebr: {
19634
+ source: "generated",
19635
+ file: "generated/m14_ebr.svg"
19636
+ },
19637
+ m203: {
19638
+ source: "generated",
19639
+ file: "generated/m203.svg"
19640
+ },
19641
+ m24_sws: {
19642
+ source: "generated",
19643
+ file: "generated/m24_sws.svg"
19644
+ },
19645
+ m2_flamethrower: {
19646
+ source: "generated",
19647
+ file: "generated/m2_flamethrower.svg"
19648
+ },
19649
+ m60: {
19650
+ source: "generated",
19651
+ file: "generated/m60.svg"
19652
+ },
19653
+ m72_law: {
19654
+ source: "generated",
19655
+ file: "generated/m72_law.svg"
19656
+ },
19657
+ m79: {
19658
+ source: "generated",
19659
+ file: "generated/m79.svg"
19660
+ },
19661
+ mac_10: {
19662
+ source: "commons",
19663
+ file: "commons/mac_10.svg",
19664
+ author: "Skoll",
19665
+ license: "CC BY 3.0",
19666
+ licenseUrl: "https://creativecommons.org/licenses/by/3.0",
19667
+ page: "https://commons.wikimedia.org/wiki/File:Mac-10_-_game-icons.svg"
19668
+ },
19669
+ machete: {
19670
+ source: "generated",
19671
+ file: "generated/machete.svg"
19672
+ },
19673
+ makarov_pm: {
19674
+ source: "generated",
19675
+ file: "generated/makarov_pm.svg"
19676
+ },
19677
+ meat_cleaver: {
19678
+ source: "generated",
19679
+ file: "generated/meat_cleaver.svg"
19680
+ },
19681
+ mg3: {
19682
+ source: "generated",
19683
+ file: "generated/mg3.svg"
19684
+ },
19685
+ mini_uzi: {
19686
+ source: "generated",
19687
+ file: "generated/mini_uzi.svg"
19688
+ },
19689
+ molotov: {
19690
+ source: "generated",
19691
+ file: "generated/molotov.svg"
19692
+ },
19693
+ mosin_nagant_91_30: {
19694
+ source: "generated",
19695
+ file: "generated/mosin_nagant_91_30.svg"
19696
+ },
19697
+ mossberg_500: {
19698
+ source: "generated",
19699
+ file: "generated/mossberg_500.svg"
19700
+ },
19701
+ mossberg_500_cruiser: {
19702
+ source: "generated",
19703
+ file: "generated/mossberg_500_cruiser.svg"
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
+ },
19713
+ pipe_bomb: {
19714
+ source: "generated",
19715
+ file: "generated/pipe_bomb.svg"
19716
+ },
19717
+ pistol_22: {
19718
+ source: "generated",
19719
+ file: "generated/pistol_22.svg"
19720
+ },
19721
+ pistol_45: {
19722
+ source: "generated",
19723
+ file: "generated/pistol_45.svg"
19724
+ },
19725
+ pistol_9mm: {
19726
+ source: "generated",
19727
+ file: "generated/pistol_9mm.svg"
19728
+ },
19729
+ pkm: {
19730
+ source: "generated",
19731
+ file: "generated/pkm.svg"
19732
+ },
19733
+ police_baton: {
19734
+ source: "generated",
19735
+ file: "generated/police_baton.svg"
19736
+ },
19737
+ pp19_bizon: {
19738
+ source: "generated",
19739
+ file: "generated/pp19_bizon.svg"
19740
+ },
19741
+ propane_p13: {
19742
+ source: "generated",
19743
+ file: "generated/propane_p13.svg"
19744
+ },
19745
+ pry_bar: {
19746
+ source: "generated",
19747
+ file: "generated/pry_bar.svg"
19748
+ },
19749
+ recurve_bow: {
19750
+ source: "generated",
19751
+ file: "generated/recurve_bow.svg"
19752
+ },
19753
+ remington_700: {
19754
+ source: "generated",
19755
+ file: "generated/remington_700.svg"
19756
+ },
19757
+ remington_700_300wm: {
19758
+ source: "generated",
19759
+ file: "generated/remington_700_300wm.svg"
19760
+ },
19761
+ remington_870: {
19762
+ source: "generated",
19763
+ file: "generated/remington_870.svg"
19764
+ },
19765
+ revolver_357: {
19766
+ source: "generated",
19767
+ file: "generated/revolver_357.svg"
19768
+ },
19769
+ revolver_38: {
19770
+ source: "generated",
19771
+ file: "generated/revolver_38.svg"
19772
+ },
19773
+ rifle_5_56: {
19774
+ source: "generated",
19775
+ file: "generated/rifle_5_56.svg"
19776
+ },
19777
+ rifle_7_62x39: {
19778
+ source: "generated",
19779
+ file: "generated/rifle_7_62x39.svg"
19780
+ },
19781
+ rifle_bolt_308: {
19782
+ source: "generated",
19783
+ file: "generated/rifle_bolt_308.svg"
19784
+ },
19785
+ rossi_puma: {
19786
+ source: "generated",
19787
+ file: "generated/rossi_puma.svg"
19788
+ },
19789
+ rpg_7: {
19790
+ source: "generated",
19791
+ file: "generated/rpg_7.svg"
19792
+ },
19793
+ rpk: {
19794
+ source: "generated",
19795
+ file: "generated/rpk.svg"
19796
+ },
19797
+ ruger_10_22: {
19798
+ source: "generated",
19799
+ file: "generated/ruger_10_22.svg"
19800
+ },
19801
+ saiga_12: {
19802
+ source: "generated",
19803
+ file: "generated/saiga_12.svg"
19804
+ },
19805
+ sako_trg_42: {
19806
+ source: "commons",
19807
+ file: "commons/sako_trg_42.svg",
19808
+ author: "Bes-ART",
19809
+ license: "CC BY-SA 4.0",
19810
+ licenseUrl: "https://creativecommons.org/licenses/by-sa/4.0",
19811
+ page: "https://commons.wikimedia.org/wiki/File:Sako_TRG_silhouette.svg"
19812
+ },
19813
+ screwdriver: {
19814
+ source: "generated",
19815
+ file: "generated/screwdriver.svg"
19816
+ },
19817
+ shotgun_double_12: {
19818
+ source: "generated",
19819
+ file: "generated/shotgun_double_12.svg"
19820
+ },
19821
+ shotgun_pump_12: {
19822
+ source: "generated",
19823
+ file: "generated/shotgun_pump_12.svg"
19824
+ },
19825
+ shotgun_semi_12: {
19826
+ source: "generated",
19827
+ file: "generated/shotgun_semi_12.svg"
19828
+ },
19829
+ sickle: {
19830
+ source: "generated",
19831
+ file: "generated/sickle.svg"
19832
+ },
19833
+ sig_mpx: {
19834
+ source: "generated",
19835
+ file: "generated/sig_mpx.svg"
19836
+ },
19837
+ sig_sauer_p226: {
19838
+ source: "generated",
19839
+ file: "generated/sig_sauer_p226.svg"
19840
+ },
19841
+ sks: {
19842
+ source: "generated",
19843
+ file: "generated/sks.svg"
19844
+ },
19845
+ sledgehammer: {
19846
+ source: "generated",
19847
+ file: "generated/sledgehammer.svg"
19848
+ },
19849
+ smg_9mm: {
19850
+ source: "generated",
19851
+ file: "generated/smg_9mm.svg"
19852
+ },
19853
+ sniper_338: {
19854
+ source: "generated",
19855
+ file: "generated/sniper_338.svg"
19856
+ },
19857
+ steyr_aug_a1: {
19858
+ source: "commons",
19859
+ file: "commons/steyr_aug_a1.svg",
19860
+ author: "Fleshgrinder",
19861
+ license: "Public domain",
19862
+ licenseUrl: "https://commons.wikimedia.org/wiki/File:Steyr_AUG_A1_407mm.svg",
19863
+ page: "https://commons.wikimedia.org/wiki/File:Steyr_AUG_A1_407mm.svg"
19864
+ },
19865
+ steyr_ssg_69: {
19866
+ source: "generated",
19867
+ file: "generated/steyr_ssg_69.svg"
19868
+ },
19869
+ svd_dragunov: {
19870
+ source: "commons",
19871
+ file: "commons/svd_dragunov.svg",
19872
+ author: "Bes-ART",
19873
+ license: "CC BY-SA 4.0",
19874
+ licenseUrl: "https://creativecommons.org/licenses/by-sa/4.0",
19875
+ page: "https://commons.wikimedia.org/wiki/File:Dragunov_silhouette.svg"
19876
+ },
19877
+ sw_686: {
19878
+ source: "generated",
19879
+ file: "generated/sw_686.svg"
19880
+ },
19881
+ sw_model_29: {
19882
+ source: "generated",
19883
+ file: "generated/sw_model_29.svg"
19884
+ },
19885
+ tactical_knife: {
19886
+ source: "generated",
19887
+ file: "generated/tactical_knife.svg"
19888
+ },
19889
+ taurus_82: {
19890
+ source: "generated",
19891
+ file: "generated/taurus_82.svg"
19892
+ },
19893
+ taurus_g2c: {
19894
+ source: "generated",
19895
+ file: "generated/taurus_g2c.svg"
19896
+ },
19897
+ taurus_pt100: {
19898
+ source: "generated",
19899
+ file: "generated/taurus_pt100.svg"
19900
+ },
19901
+ taurus_smt9: {
19902
+ source: "generated",
19903
+ file: "generated/taurus_smt9.svg"
19904
+ },
19905
+ taurus_t4: {
19906
+ source: "generated",
19907
+ file: "generated/taurus_t4.svg"
19908
+ },
19909
+ taurus_t4_civil: {
19910
+ source: "generated",
19911
+ file: "generated/taurus_t4_civil.svg"
19912
+ },
19913
+ taurus_th380: {
19914
+ source: "generated",
19915
+ file: "generated/taurus_th380.svg"
19916
+ },
19917
+ taurus_ts9: {
19918
+ source: "generated",
19919
+ file: "generated/taurus_ts9.svg"
19920
+ },
19921
+ thompson_m1a1: {
19922
+ source: "generated",
19923
+ file: "generated/thompson_m1a1.svg"
19924
+ },
19925
+ utility_knife: {
19926
+ source: "commons",
19927
+ file: "commons/utility_knife.svg",
19928
+ author: "Lucasbosch",
19929
+ license: "CC BY-SA 3.0",
19930
+ licenseUrl: "https://creativecommons.org/licenses/by-sa/3.0",
19931
+ page: "https://commons.wikimedia.org/wiki/File:OLFA_5019_SVR-2_9_mm_utility_knife_with_ABB_blade.svg"
19932
+ },
19933
+ uzi: {
19934
+ source: "commons",
19935
+ file: "commons/uzi.svg",
19936
+ author: "floatingbrainiac",
19937
+ license: "CC0",
19938
+ licenseUrl: "http://creativecommons.org/publicdomain/zero/1.0/deed.en",
19939
+ page: "https://commons.wikimedia.org/wiki/File:Uzi_silhouette.svg"
19940
+ },
19941
+ vz61: {
19942
+ source: "commons",
19943
+ file: "commons/vz61.svg",
19944
+ author: "Skoll",
19945
+ license: "CC BY 3.0",
19946
+ licenseUrl: "https://creativecommons.org/licenses/by/3.0",
19947
+ page: "https://commons.wikimedia.org/wiki/File:Cz-skorpion_-_game-icons.svg"
19948
+ },
19949
+ winchester_1894: {
19950
+ source: "generated",
19951
+ file: "generated/winchester_1894.svg"
19952
+ },
19953
+ wrench: {
19954
+ source: "generated",
19955
+ file: "generated/wrench.svg"
19956
+ }
19957
+ }
19958
+ };
19959
+
19960
+ // src/thumbnails.ts
19961
+ var WEAPON_THUMBNAILS = manifest_default.assets;
19962
+ function weaponThumbnailCredit(id) {
19963
+ const entry = WEAPON_THUMBNAILS[id];
19964
+ return entry?.source === "commons" && entry.author && entry.license ? `${entry.author}, ${entry.license}` : void 0;
19965
+ }
19966
+ var DEFAULT_THUMBNAIL_BASE = "weapon-svg/";
19967
+ function weaponThumbnailUrl(id, base = DEFAULT_THUMBNAIL_BASE) {
19968
+ const entry = WEAPON_THUMBNAILS[id];
19969
+ return entry ? `${base}${entry.file}` : void 0;
19970
+ }
19971
+
18974
19972
  // src/world-explosives.ts
18975
19973
  var WORLD_EXPLOSIVE_PREFIX = "world_";
18976
19974
  var SHAPES2 = {
@@ -19184,6 +20182,13 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
19184
20182
  const accessoryText = accessoryTextOf(locale);
19185
20183
  const audio = options.sound === false ? null : createWeaponAudio(void 0, options.seed === void 0 ? {} : { seed: options.seed });
19186
20184
  const weaponDefs = [...arsenal.weapons.values()].filter((def) => !BODY_ACTIONS.has(def.id));
20185
+ const thumbnailBase = options.thumbnailBase ?? DEFAULT_THUMBNAIL_BASE;
20186
+ const withThumbnail = (item, key) => {
20187
+ const thumbnail = thumbnailBase === false ? void 0 : weaponThumbnailUrl(key, thumbnailBase);
20188
+ if (!thumbnail) return item;
20189
+ const thumbnailCredit = weaponThumbnailCredit(key);
20190
+ return thumbnailCredit ? { ...item, thumbnail, thumbnailCredit } : { ...item, thumbnail };
20191
+ };
19187
20192
  const weaponIds = weaponDefs.filter((def) => !(def.id in ARCHETYPE_MODELS)).map((def) => `${WEAPON_ITEM_PREFIX}${def.id}`);
19188
20193
  const pitchOf = (itemId) => PITCH_BY_ID[itemId.slice(WEAPON_ITEM_PREFIX.length)] ?? DEFAULT_PITCH;
19189
20194
  const worldExplosives = WORLD_EXPLOSIVE_IDS.flatMap((id) => {
@@ -19207,11 +20212,11 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
19207
20212
  return fx;
19208
20213
  },
19209
20214
  items: () => [
19210
- ...weaponDefs.map((def) => weaponItem(def, arsenal.name(def.id))),
20215
+ ...weaponDefs.map((def) => withThumbnail(weaponItem(def, arsenal.name(def.id)), def.id)),
19211
20216
  asItem(COUNTER_ITEM_ID, text.counter, counterProp(text.counter), { movable: false }),
19212
20217
  ...TARGETS.map((target) => asItem(target.id, text.targets[target.id] ?? target.id, targetProp(target.id, text.targets[target.id] ?? target.id), { movable: false })),
19213
- ...worldExplosives,
19214
- ...mountedM134
20218
+ ...worldExplosives.map((item) => withThumbnail(item, item.id.slice(WORLD_EXPLOSIVE_PREFIX.length))),
20219
+ ...mountedM134.map((item) => withThumbnail(item, MOUNTED_M134.weaponId))
19215
20220
  ],
19216
20221
  area: () => ({
19217
20222
  placements: [