@adatechnology/game-weapons-three 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/index.global.js +209 -6
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +183 -3
- package/dist/index.js.map +1 -1
- package/package.json +12 -12
package/README.md
CHANGED
|
@@ -6,6 +6,8 @@ The muzzle flash, the smoke, the backblast of a launched rocket and the flame je
|
|
|
6
6
|
|
|
7
7
|
**Hands.** The weapon in the hands tells the host where the hands go (`host.setHandTargets`, `HandTargets` of `game-contracts`): the right on the pistol grip (the `grip` pivot of the model, else under the receiver), the left on the handguard, on the pump of a pump gun (it moves with the pump), under the right on a handgun, and to the magazine while it is changed; the generic props take the right hand on the `handle` and the left under the `head` of a long gun. Sizes come from the model, the hands shrink with a model drawn small.
|
|
8
8
|
|
|
9
|
+
**Safety (destravar).** Turning the safety on or off (the `safety` event, B in the test room) plays `safety_on` / `safety_off` on every model: the weapon cants to the right and rises a little toward the eye, the shooting hand slides up its grip so the thumb reaches the lever (`thumb_safety` in `src/data/hand-work.json`; an AK-style rifle's support hand goes over to the big lever on the right, `lever_right`), the lever flicks (when the model draws one, the `safety` part) and the weapon settles. The seconds and radians are `SAFETY_MOTION` of `src/animation/shot-clips.ts`.
|
|
10
|
+
|
|
9
11
|
**Weapons the gallery did not model.** The melee weapons and tools with no gallery model (the bat, the axe, the machete, the knife, the hammer, the crowbar, the crossbow, the wrench, the extinguisher, the blowtorch...) are drawn with the team's item model of `@adatechnology/game-items-three` (Itens do Vale Cinzento), on the counters and in the hands: `buildItemWeaponModel` lays it along +x, flat, the head at +x, with an empty `handle` where the hand closes. The item is the one with the weapon's id, or the one `registerWeaponItemModel(weaponId, { item, turn, flip })` names (`wrench` → `adjustable_wrench`); `registerWeaponItemModel(id, null)` keeps the low-poly prop. Only a weapon with neither model falls back to the low-poly boxes of its category (`weaponProp`), and the kit's scene check (`tools/kit-audit/scene.mjs`) lists those as pending.
|
|
10
12
|
|
|
11
13
|
**Reload sounds.** Each step of a reload makes its noise where the clip says: the clips carry `sound` cues (`cue(t, 'sound', { id })`), so the sound follows the animation and scales with the weapon's reload time (`mag_release`, `mag_out`, `mag_insert`, `mag_seat`, `slide_release`, `charging_handle_pull/release`, `bolt_lift/pull/push/lock`, `shell_insert` once per round, `pump_back/forward`, `lever_open/close`, `cylinder_open/eject/close`, `speedloader`, `barrels_open/close`, `belt_cover_open/close`, `belt_insert`, `rocket_load/seat`, `grenade_load`, `breech_open/close`, `tube_drop/seat`). The recipes are data (`src/data/reload-sounds.json`: layers of the game-audio primitives); a profile (`soundProfileOf`: weight light/medium/heavy from the model family, steel or polymer from a list in the data) changes their pitch and level, and `createWeaponAudio(volume, { reloadCues })` replaces or adds recipes. `createWeaponFx({ onSound })` is told at each cue (the test area logs it as a `sound` entry); `WeaponFx.clips` says which reload variant is playing. `tests/reload-sounds.test.ts` checks the cue order of every weapon and kind, one recipe per cue, and the per-round sounds.
|
package/dist/index.global.js
CHANGED
|
@@ -19681,6 +19681,23 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
19681
19681
|
return angle === 0 ? q : quat.mul(q, quat.fromAxisAngle([0, 0, 1], angle));
|
|
19682
19682
|
};
|
|
19683
19683
|
var clamp = (v, a, b) => Math.max(a, Math.min(b, v));
|
|
19684
|
+
var tearStack = (inp, root, t, u, v, n, sheet) => {
|
|
19685
|
+
const { dims, rnd: rnd2, maxFragments } = inp;
|
|
19686
|
+
const layers = clamp(Math.ceil(dims[t] / STACK_LAYER), 2, 4);
|
|
19687
|
+
const per = clamp(n, 3, Math.max(3, Math.floor(maxFragments / layers)));
|
|
19688
|
+
const out = [];
|
|
19689
|
+
for (let k = 0; k < layers; k++) {
|
|
19690
|
+
const off = -dims[t] / 2 + (k + 0.5) * dims[t] / layers;
|
|
19691
|
+
for (const b of bsp(root, per, [u, v], rnd2)) {
|
|
19692
|
+
if (out.length >= maxFragments) return out;
|
|
19693
|
+
const c = [b.c[0], b.c[1], b.c[2]];
|
|
19694
|
+
c[t] = off;
|
|
19695
|
+
out.push({ center: c, size: [b.s[u], b.s[v], sheet], q: frame(u, v, t, (rnd2() - 0.5) * 0.8), shape: "scrap", weight: b.s[u] * b.s[v], inner: out.length % 4 !== 0 });
|
|
19696
|
+
}
|
|
19697
|
+
}
|
|
19698
|
+
return out;
|
|
19699
|
+
};
|
|
19700
|
+
var STACK_LAYER = 0.012;
|
|
19684
19701
|
var planFragments = (inp) => {
|
|
19685
19702
|
const { style, dims, rnd: rnd2, maxFragments } = inp;
|
|
19686
19703
|
const [fmin, fmax] = inp.fragmentSize;
|
|
@@ -19723,6 +19740,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
19723
19740
|
}
|
|
19724
19741
|
if (style === "tear") {
|
|
19725
19742
|
const n2 = clamp(Math.round(dims[u] * dims[v] / (mean * mean)), 3, maxFragments);
|
|
19743
|
+
const sheet = inp.sheet ?? 0;
|
|
19744
|
+
if (sheet > 0 && dims[t] > sheet * 4) return tearStack(inp, root, t, u, v, n2, sheet);
|
|
19726
19745
|
const th2 = Math.min(inp.thickness, dims[t]);
|
|
19727
19746
|
for (const b of bsp(root, n2, [u, v], rnd2)) {
|
|
19728
19747
|
out.push({ center: [b.c[0], b.c[1], b.c[2]], size: [b.s[u], b.s[v], th2], q: frame(u, v, t), shape: "scrap", weight: b.s[u] * b.s[v] });
|
|
@@ -21305,6 +21324,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21305
21324
|
0.03,
|
|
21306
21325
|
0.15
|
|
21307
21326
|
],
|
|
21327
|
+
sheet: 1e-3,
|
|
21308
21328
|
damageScale: {
|
|
21309
21329
|
slash: 3
|
|
21310
21330
|
},
|
|
@@ -21320,7 +21340,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
21320
21340
|
smoke: "grey"
|
|
21321
21341
|
},
|
|
21322
21342
|
visual: {
|
|
21323
|
-
charColor: 1709072
|
|
21343
|
+
charColor: 1709072,
|
|
21344
|
+
innerColor: 15524048
|
|
21324
21345
|
},
|
|
21325
21346
|
tags: [
|
|
21326
21347
|
"fabric",
|
|
@@ -23033,7 +23054,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
23033
23054
|
hit: hitLocal,
|
|
23034
23055
|
fragmentSize: p.mat.fragmentSize ?? [0.04, 0.2],
|
|
23035
23056
|
maxFragments,
|
|
23036
|
-
rnd: rnd2
|
|
23057
|
+
rnd: rnd2,
|
|
23058
|
+
sheet: p.mat.sheet
|
|
23037
23059
|
});
|
|
23038
23060
|
const holes = p.st.holes.length > 0 ? localHolesOf(p) : [];
|
|
23039
23061
|
const mass = p.st.mass;
|
|
@@ -23057,7 +23079,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
23057
23079
|
velocity: [dv[0] * k, dv[1] * k + 0.5 * rnd2(), dv[2] * k],
|
|
23058
23080
|
angularVelocity: [(rnd2() - 0.5) * 12, (rnd2() - 0.5) * 12, (rnd2() - 0.5) * 12],
|
|
23059
23081
|
mass: mass * f.weight / totW,
|
|
23060
|
-
...marks.length > 0 ? { marks } : {}
|
|
23082
|
+
...marks.length > 0 ? { marks } : {},
|
|
23083
|
+
...f.inner ? { inner: true } : {}
|
|
23061
23084
|
};
|
|
23062
23085
|
});
|
|
23063
23086
|
const reinforcement = p.spec.reinforcement;
|
|
@@ -37811,6 +37834,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
37811
37834
|
/** Closure of the fingers on a grip and on a forend (0 open, 1 closed). */
|
|
37812
37835
|
closed: 0.9,
|
|
37813
37836
|
forend: 0.6,
|
|
37837
|
+
/** How far the shooting hand slides on its grip so the thumb reaches the safety lever. */
|
|
37838
|
+
thumbReach: 0.02,
|
|
37814
37839
|
/** How fast the supporting hand goes to the magazine and back, per second. */
|
|
37815
37840
|
magRate: 7,
|
|
37816
37841
|
/** The hands shrink with the tool: a tool drawn at scale `s` takes hands at `s ** handScaleExponent`. */
|
|
@@ -48497,9 +48522,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
|
|
|
48497
48522
|
);
|
|
48498
48523
|
return [misfire, ...stopped];
|
|
48499
48524
|
}
|
|
48525
|
+
var SAFETY_MOTION = { cant: 0.22, lift: 0.012, in: 0.14, flickAt: 0.16, flick: 0.1, outAt: 0.32, out: 0.16, lever: 0.6 };
|
|
48500
48526
|
function safetyClips(context) {
|
|
48501
|
-
|
|
48502
|
-
|
|
48527
|
+
const { cant, lift, in: rise, flickAt, flick, outAt, out, lever } = SAFETY_MOTION;
|
|
48528
|
+
const carry = () => [turn(ROOT, "x", 0, rise, 0, cant), move(ROOT, "y", 0, rise, 0, lift), turn(ROOT, "x", outAt, out, cant, 0), move(ROOT, "y", outAt, out, lift, 0)];
|
|
48529
|
+
const flickTo = (from, to) => context.parts.safety ? [turn("safety", "z", flickAt, flick, from, to)] : [];
|
|
48530
|
+
const clips = [composeClip("safety_on", [...carry(), ...flickTo(0, -lever)]), composeClip("safety_off", [...carry(), ...flickTo(-lever, 0)])];
|
|
48531
|
+
if (context.parts.safety) clips.push(composeClip("mode", [turn("safety", "z", 0, 0.07, 0, 0.4), turn("safety", "z", 0.07, 0.07, 0.4, 0)]));
|
|
48532
|
+
return clips;
|
|
48503
48533
|
}
|
|
48504
48534
|
var drawClip = () => composeClip("draw", [move(ROOT, "y", 0, 0.35, -0.1, 0), turn(ROOT, "z", 0, 0.35, -0.6, 0)]);
|
|
48505
48535
|
|
|
@@ -58270,8 +58300,169 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
58270
58300
|
hand: "L",
|
|
58271
58301
|
anchor: "cylinder_side",
|
|
58272
58302
|
merge: 1
|
|
58303
|
+
},
|
|
58304
|
+
{
|
|
58305
|
+
family: "pistol",
|
|
58306
|
+
clips: [
|
|
58307
|
+
"safety_on",
|
|
58308
|
+
"safety_off"
|
|
58309
|
+
],
|
|
58310
|
+
hand: "R",
|
|
58311
|
+
anchor: "thumb_safety",
|
|
58312
|
+
whole: true,
|
|
58313
|
+
lead: 0.3,
|
|
58314
|
+
tail: 0.3
|
|
58315
|
+
},
|
|
58316
|
+
{
|
|
58317
|
+
family: "revolver",
|
|
58318
|
+
clips: [
|
|
58319
|
+
"safety_on",
|
|
58320
|
+
"safety_off"
|
|
58321
|
+
],
|
|
58322
|
+
hand: "R",
|
|
58323
|
+
anchor: "thumb_safety",
|
|
58324
|
+
whole: true,
|
|
58325
|
+
lead: 0.3,
|
|
58326
|
+
tail: 0.3
|
|
58327
|
+
},
|
|
58328
|
+
{
|
|
58329
|
+
family: "rifle",
|
|
58330
|
+
clips: [
|
|
58331
|
+
"safety_on",
|
|
58332
|
+
"safety_off"
|
|
58333
|
+
],
|
|
58334
|
+
hand: "R",
|
|
58335
|
+
anchor: "thumb_safety",
|
|
58336
|
+
whole: true,
|
|
58337
|
+
lead: 0.3,
|
|
58338
|
+
tail: 0.3,
|
|
58339
|
+
style: "ar"
|
|
58340
|
+
},
|
|
58341
|
+
{
|
|
58342
|
+
family: "p90",
|
|
58343
|
+
clips: [
|
|
58344
|
+
"safety_on",
|
|
58345
|
+
"safety_off"
|
|
58346
|
+
],
|
|
58347
|
+
hand: "R",
|
|
58348
|
+
anchor: "thumb_safety",
|
|
58349
|
+
whole: true,
|
|
58350
|
+
lead: 0.3,
|
|
58351
|
+
tail: 0.3
|
|
58352
|
+
},
|
|
58353
|
+
{
|
|
58354
|
+
family: "pump",
|
|
58355
|
+
clips: [
|
|
58356
|
+
"safety_on",
|
|
58357
|
+
"safety_off"
|
|
58358
|
+
],
|
|
58359
|
+
hand: "R",
|
|
58360
|
+
anchor: "thumb_safety",
|
|
58361
|
+
whole: true,
|
|
58362
|
+
lead: 0.3,
|
|
58363
|
+
tail: 0.3
|
|
58364
|
+
},
|
|
58365
|
+
{
|
|
58366
|
+
family: "semi12",
|
|
58367
|
+
clips: [
|
|
58368
|
+
"safety_on",
|
|
58369
|
+
"safety_off"
|
|
58370
|
+
],
|
|
58371
|
+
hand: "R",
|
|
58372
|
+
anchor: "thumb_safety",
|
|
58373
|
+
whole: true,
|
|
58374
|
+
lead: 0.3,
|
|
58375
|
+
tail: 0.3
|
|
58376
|
+
},
|
|
58377
|
+
{
|
|
58378
|
+
family: "semiint",
|
|
58379
|
+
clips: [
|
|
58380
|
+
"safety_on",
|
|
58381
|
+
"safety_off"
|
|
58382
|
+
],
|
|
58383
|
+
hand: "R",
|
|
58384
|
+
anchor: "thumb_safety",
|
|
58385
|
+
whole: true,
|
|
58386
|
+
lead: 0.3,
|
|
58387
|
+
tail: 0.3
|
|
58388
|
+
},
|
|
58389
|
+
{
|
|
58390
|
+
family: "break",
|
|
58391
|
+
clips: [
|
|
58392
|
+
"safety_on",
|
|
58393
|
+
"safety_off"
|
|
58394
|
+
],
|
|
58395
|
+
hand: "R",
|
|
58396
|
+
anchor: "thumb_safety",
|
|
58397
|
+
whole: true,
|
|
58398
|
+
lead: 0.3,
|
|
58399
|
+
tail: 0.3
|
|
58400
|
+
},
|
|
58401
|
+
{
|
|
58402
|
+
family: "bolt",
|
|
58403
|
+
clips: [
|
|
58404
|
+
"safety_on",
|
|
58405
|
+
"safety_off"
|
|
58406
|
+
],
|
|
58407
|
+
hand: "R",
|
|
58408
|
+
anchor: "thumb_safety",
|
|
58409
|
+
whole: true,
|
|
58410
|
+
lead: 0.3,
|
|
58411
|
+
tail: 0.3
|
|
58412
|
+
},
|
|
58413
|
+
{
|
|
58414
|
+
family: "boltmag",
|
|
58415
|
+
clips: [
|
|
58416
|
+
"safety_on",
|
|
58417
|
+
"safety_off"
|
|
58418
|
+
],
|
|
58419
|
+
hand: "R",
|
|
58420
|
+
anchor: "thumb_safety",
|
|
58421
|
+
whole: true,
|
|
58422
|
+
lead: 0.3,
|
|
58423
|
+
tail: 0.3
|
|
58424
|
+
},
|
|
58425
|
+
{
|
|
58426
|
+
family: "lever",
|
|
58427
|
+
clips: [
|
|
58428
|
+
"safety_on",
|
|
58429
|
+
"safety_off"
|
|
58430
|
+
],
|
|
58431
|
+
hand: "R",
|
|
58432
|
+
anchor: "thumb_safety",
|
|
58433
|
+
whole: true,
|
|
58434
|
+
lead: 0.3,
|
|
58435
|
+
tail: 0.3
|
|
58436
|
+
},
|
|
58437
|
+
{
|
|
58438
|
+
family: "belt",
|
|
58439
|
+
clips: [
|
|
58440
|
+
"safety_on",
|
|
58441
|
+
"safety_off"
|
|
58442
|
+
],
|
|
58443
|
+
hand: "R",
|
|
58444
|
+
anchor: "thumb_safety",
|
|
58445
|
+
whole: true,
|
|
58446
|
+
lead: 0.3,
|
|
58447
|
+
tail: 0.3
|
|
58448
|
+
},
|
|
58449
|
+
{
|
|
58450
|
+
family: "rifle",
|
|
58451
|
+
clips: [
|
|
58452
|
+
"safety_on",
|
|
58453
|
+
"safety_off"
|
|
58454
|
+
],
|
|
58455
|
+
hand: "L",
|
|
58456
|
+
anchor: "lever_right",
|
|
58457
|
+
style: "ak",
|
|
58458
|
+
whole: true,
|
|
58459
|
+
lead: 0.3,
|
|
58460
|
+
tail: 0.3
|
|
58273
58461
|
}
|
|
58274
|
-
]
|
|
58462
|
+
],
|
|
58463
|
+
safety: {
|
|
58464
|
+
comment: "Safety on and off (B): the shooting hand slides up its grip so the thumb flicks the lever while the clip cants the weapon; an AK-style rifle (akCharge) has its big lever on the right, pushed by the support hand over the top."
|
|
58465
|
+
}
|
|
58275
58466
|
};
|
|
58276
58467
|
|
|
58277
58468
|
// src/fx/hand-work.ts
|
|
@@ -58299,6 +58490,18 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
58299
58490
|
if (!right || !parts.slide) return null;
|
|
58300
58491
|
return { part: right.part, offset: right.offset.clone().add(V2(THREE, 0, 0.012, 0)), quaternion: right.quaternion };
|
|
58301
58492
|
}
|
|
58493
|
+
if (kind === "thumb_safety") {
|
|
58494
|
+
if (!right) return null;
|
|
58495
|
+
const toward2 = parts.safety ? right.part.worldToLocal(parts.safety.getWorldPosition(V2(THREE, 0, 0, 0))).sub(right.offset) : V2(THREE, 0, HAND_HOLD.thumbReach, 0);
|
|
58496
|
+
return { part: right.part, offset: right.offset.clone().add(toward2.clampLength(0, HAND_HOLD.thumbReach)), quaternion: right.quaternion };
|
|
58497
|
+
}
|
|
58498
|
+
if (kind === "lever_right") {
|
|
58499
|
+
const receiver = parts.bolt ?? parts.boltHandle;
|
|
58500
|
+
if (!receiver) return null;
|
|
58501
|
+
const b2 = boxIn(THREE, root, receiver);
|
|
58502
|
+
const x = parts.trigger ? root.worldToLocal(parts.trigger.getWorldPosition(V2(THREE, 0, 0, 0))).x : b2.min.x;
|
|
58503
|
+
return anchorAt(receiver, V2(THREE, x, b2.getCenter(V2(THREE, 0, 0, 0)).y, b2.max.z + palm), handFrame(THREE, V2(THREE, 1, 0, 0), V2(THREE, 0, 0, 1)));
|
|
58504
|
+
}
|
|
58302
58505
|
if (!part) return null;
|
|
58303
58506
|
const b = boxIn(THREE, root, part);
|
|
58304
58507
|
const c = b.getCenter(V2(THREE, 0, 0, 0));
|