@adatechnology/game-player 0.4.1 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-RUFQCNZH.js +1068 -0
- package/dist/chunk-RUFQCNZH.js.map +1 -0
- package/dist/index.d.ts +4 -410
- package/dist/index.global.js +172 -18
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +12 -1016
- package/dist/index.js.map +1 -1
- package/dist/testing-CD4p4NR5.d.ts +430 -0
- package/dist/testing.d.ts +2 -0
- package/dist/testing.js +7 -0
- package/dist/testing.js.map +1 -0
- package/package.json +6 -2
package/dist/index.global.js
CHANGED
|
@@ -39,6 +39,121 @@ var GamePlayer = (() => {
|
|
|
39
39
|
swingSecondsFor: () => swingSecondsFor
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
+
// ../game-contracts/dist/index.js
|
|
43
|
+
var DEFAULT_COST_ALLOCATION_BYTES = 1024 * 1024;
|
|
44
|
+
var DEFERRED_QUEUE_ID = {
|
|
45
|
+
DESTRUCTION_EVENTS: "destruction.events",
|
|
46
|
+
BREACH_PAINT: "floorplan.breach-paint",
|
|
47
|
+
AUDIO_VOICES: "audio.voices",
|
|
48
|
+
VEHICLE_CREASE: "vehicles.crease"
|
|
49
|
+
};
|
|
50
|
+
var DEFERRED_PRIORITY = {
|
|
51
|
+
[DEFERRED_QUEUE_ID.DESTRUCTION_EVENTS]: { priority: 300, phase: "present" },
|
|
52
|
+
[DEFERRED_QUEUE_ID.BREACH_PAINT]: { priority: 250, phase: "present" },
|
|
53
|
+
[DEFERRED_QUEUE_ID.AUDIO_VOICES]: { priority: 200, phase: "idle", reserveMs: 1 },
|
|
54
|
+
[DEFERRED_QUEUE_ID.VEHICLE_CREASE]: { priority: 100, phase: "idle" }
|
|
55
|
+
};
|
|
56
|
+
var SURFACE_IDS = ["concrete", "asphalt", "wood", "tile", "dirt", "grass", "gravel", "sand", "metal", "water", "glass", "carpet"];
|
|
57
|
+
var DEFAULT_SURFACE = "concrete";
|
|
58
|
+
var GAIT_IDS = ["walk", "run"];
|
|
59
|
+
var LANDING_IDS = ["light", "heavy"];
|
|
60
|
+
var HEAVY_LANDING_SPEED = 5.5;
|
|
61
|
+
var BODY_SOUND_IDS = [
|
|
62
|
+
"jump",
|
|
63
|
+
"cloth_rustle",
|
|
64
|
+
"body_fall",
|
|
65
|
+
"fall_damage",
|
|
66
|
+
"player_hurt",
|
|
67
|
+
"player_breath_run",
|
|
68
|
+
"player_death",
|
|
69
|
+
"bite",
|
|
70
|
+
"grab",
|
|
71
|
+
"punch_swing",
|
|
72
|
+
"punch_hit_body",
|
|
73
|
+
"punch_hit_face",
|
|
74
|
+
"punch_hit_object",
|
|
75
|
+
"kick_swing",
|
|
76
|
+
"kick_hit",
|
|
77
|
+
"kick_hit_object",
|
|
78
|
+
"shove_two_hands",
|
|
79
|
+
"knife_swing",
|
|
80
|
+
"knife_stab",
|
|
81
|
+
"knife_slash",
|
|
82
|
+
"knife_hit_object",
|
|
83
|
+
"blunt_swing",
|
|
84
|
+
"blunt_hit",
|
|
85
|
+
"blunt_hit_object",
|
|
86
|
+
"axe_swing",
|
|
87
|
+
"axe_chop",
|
|
88
|
+
"axe_hit_object"
|
|
89
|
+
];
|
|
90
|
+
var footstepSoundId = (surface, gait) => `footstep_${surface}_${gait}`;
|
|
91
|
+
var landSoundId = (surface, fallSpeed) => `land_${surface}_${fallSpeed >= HEAVY_LANDING_SPEED ? "heavy" : "light"}`;
|
|
92
|
+
var FOOTSTEP_SOUND_IDS = SURFACE_IDS.flatMap((surface) => GAIT_IDS.map((gait) => footstepSoundId(surface, gait)));
|
|
93
|
+
var LAND_SOUND_IDS = SURFACE_IDS.flatMap((surface) => LANDING_IDS.map((landing) => `land_${surface}_${landing}`));
|
|
94
|
+
var BODY_FOLEY_IDS = [...FOOTSTEP_SOUND_IDS, ...LAND_SOUND_IDS, ...BODY_SOUND_IDS];
|
|
95
|
+
var SWING = {
|
|
96
|
+
punch: "punch_swing",
|
|
97
|
+
kick: "kick_swing",
|
|
98
|
+
// two hands pushed out do not whistle: the shove is one sound, at the contact
|
|
99
|
+
shove: null,
|
|
100
|
+
blade: "knife_swing",
|
|
101
|
+
blunt: "blunt_swing",
|
|
102
|
+
chop: "axe_swing"
|
|
103
|
+
};
|
|
104
|
+
var SWING_LEAD_SECONDS = { punch: 0.07, kick: 0.09, shove: 0, blade: 0.05, blunt: 0.1, chop: 0.11 };
|
|
105
|
+
var swingSoundId = (blow) => SWING[blow];
|
|
106
|
+
var HIT = {
|
|
107
|
+
punch: { body: "punch_hit_body", head: "punch_hit_face", object: "punch_hit_object" },
|
|
108
|
+
kick: { body: "kick_hit", head: "kick_hit", object: "kick_hit_object" },
|
|
109
|
+
shove: { body: "shove_two_hands", head: "shove_two_hands", object: "shove_two_hands" },
|
|
110
|
+
blade: { body: "knife_stab", head: "knife_stab", object: "knife_hit_object" },
|
|
111
|
+
blunt: { body: "blunt_hit", head: "blunt_hit", object: "blunt_hit_object" },
|
|
112
|
+
chop: { body: "axe_chop", head: "axe_chop", object: "axe_hit_object" }
|
|
113
|
+
};
|
|
114
|
+
var hitSoundId = (blow, target) => HIT[blow][target];
|
|
115
|
+
var MATERIAL_SURFACES = {
|
|
116
|
+
concrete: "concrete",
|
|
117
|
+
mortar: "concrete",
|
|
118
|
+
stone: "concrete",
|
|
119
|
+
brick: "concrete",
|
|
120
|
+
plaster: "concrete",
|
|
121
|
+
asphalt: "asphalt",
|
|
122
|
+
wood_soft: "wood",
|
|
123
|
+
wood_hard: "wood",
|
|
124
|
+
green_wood: "wood",
|
|
125
|
+
plywood: "wood",
|
|
126
|
+
mdf: "wood",
|
|
127
|
+
ceramic: "tile",
|
|
128
|
+
plastic: "tile",
|
|
129
|
+
soil: "dirt",
|
|
130
|
+
wax: "dirt",
|
|
131
|
+
flesh_fruit: "dirt",
|
|
132
|
+
turf: "grass",
|
|
133
|
+
foliage: "grass",
|
|
134
|
+
cactus: "grass",
|
|
135
|
+
gravel: "gravel",
|
|
136
|
+
sand: "sand",
|
|
137
|
+
steel: "metal",
|
|
138
|
+
cast_iron: "metal",
|
|
139
|
+
aluminium: "metal",
|
|
140
|
+
copper: "metal",
|
|
141
|
+
water: "water",
|
|
142
|
+
glass: "glass",
|
|
143
|
+
tempered_glass: "glass",
|
|
144
|
+
fabric: "carpet",
|
|
145
|
+
foam: "carpet",
|
|
146
|
+
leather: "carpet",
|
|
147
|
+
rubber: "carpet",
|
|
148
|
+
paper: "carpet"
|
|
149
|
+
};
|
|
150
|
+
var isSurfaceId = (value) => typeof value === "string" && SURFACE_IDS.includes(value);
|
|
151
|
+
function surfaceOfMaterial(material, table = MATERIAL_SURFACES, fallback = DEFAULT_SURFACE) {
|
|
152
|
+
if (material === void 0) return fallback;
|
|
153
|
+
if (isSurfaceId(material)) return material;
|
|
154
|
+
return table[material] ?? fallback;
|
|
155
|
+
}
|
|
156
|
+
|
|
42
157
|
// src/data/defaults.json
|
|
43
158
|
var defaults_default = {
|
|
44
159
|
sources: {
|
|
@@ -264,7 +379,11 @@ var GamePlayer = (() => {
|
|
|
264
379
|
const set = listeners.get(event);
|
|
265
380
|
if (set) for (const listener of set) listener(payload);
|
|
266
381
|
};
|
|
267
|
-
const sound = (id, volume) => emit("sound", { sound: id, volume, position: [P.x, P.y, P.z] });
|
|
382
|
+
const sound = (id, volume, ids, surface, at) => emit("sound", { sound: id, ids, volume, position: [P.x, P.y, P.z], ...surface ? { surface } : {}, ...at ? { at } : {} });
|
|
383
|
+
let surfaceHint;
|
|
384
|
+
const surfaceHere = () => inWater(P.x, P.z) ? "water" : surfaceOfMaterial(surfaceHint ?? world.surfaceAt?.(P.x, P.z));
|
|
385
|
+
let hostFeet = false;
|
|
386
|
+
const blowOf = (item) => item.blow ?? (item === fist ? "punch" : (item.crit ?? 0) > 0 ? "blade" : "blunt");
|
|
268
387
|
const noise = (x, z, radius) => emit("noise", { x, z, radius });
|
|
269
388
|
const message = (id, seconds) => emit("message", { id, seconds });
|
|
270
389
|
const inWater = (x, z) => world.inWater?.(x, z) ?? false;
|
|
@@ -297,7 +416,7 @@ var GamePlayer = (() => {
|
|
|
297
416
|
if (!P.alive) return;
|
|
298
417
|
P.health -= amount;
|
|
299
418
|
P.hurtFlash = numbers.hurtFlash;
|
|
300
|
-
sound("flesh", numbers.hurtVolume);
|
|
419
|
+
sound("flesh", numbers.hurtVolume, ["player_hurt"]);
|
|
301
420
|
const kind = drawWound(wounds, random);
|
|
302
421
|
P.wounds.push(kind);
|
|
303
422
|
if (wounds[kind]?.bleeds) P.bleeding = 1;
|
|
@@ -310,7 +429,7 @@ var GamePlayer = (() => {
|
|
|
310
429
|
P.hurtFlash = numbers.biteFlash;
|
|
311
430
|
P.bleeding = 1;
|
|
312
431
|
P.wounds.push("bite");
|
|
313
|
-
sound("flesh", numbers.biteVolume);
|
|
432
|
+
sound("flesh", numbers.biteVolume, ["bite", "player_hurt"]);
|
|
314
433
|
emit("hurt", { amount: numbers.biteDamage, wound: "bite" });
|
|
315
434
|
infect("bite");
|
|
316
435
|
message("bitten", 5);
|
|
@@ -323,7 +442,7 @@ var GamePlayer = (() => {
|
|
|
323
442
|
P.grabNoJaw = noJaw;
|
|
324
443
|
P.grabDrown = drown;
|
|
325
444
|
message(drown ? "grabbed_drown" : "grabbed", 3);
|
|
326
|
-
sound("flesh", numbers.grabVolume);
|
|
445
|
+
sound("flesh", numbers.grabVolume, ["grab"]);
|
|
327
446
|
emit("grabbed", { by, noJaw, drown });
|
|
328
447
|
};
|
|
329
448
|
const front = (range, cosMin, yaw, crowd = world.crowd) => {
|
|
@@ -342,7 +461,7 @@ var GamePlayer = (() => {
|
|
|
342
461
|
return out.sort((a, b) => a[0] - b[0]);
|
|
343
462
|
};
|
|
344
463
|
const shove = (yaw) => {
|
|
345
|
-
sound("step", numbers.shoveVolume);
|
|
464
|
+
sound("step", numbers.shoveVolume, ["shove_two_hands"]);
|
|
346
465
|
const crowd = world.crowd;
|
|
347
466
|
const targets = [];
|
|
348
467
|
for (const [d, i] of front(numbers.shoveRange, numbers.shoveCone, yaw)) {
|
|
@@ -353,12 +472,20 @@ var GamePlayer = (() => {
|
|
|
353
472
|
};
|
|
354
473
|
const melee = (item, yaw) => {
|
|
355
474
|
const t = front(numbers.meleeRangeBase + (item.reach ?? 0), numbers.meleeCone, yaw)[0];
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
if (!t)
|
|
475
|
+
const blow = blowOf(item);
|
|
476
|
+
const swing = swingSoundId(blow);
|
|
477
|
+
if (!t) {
|
|
478
|
+
sound("flesh", numbers.meleeVolume, swing ? [swing] : []);
|
|
479
|
+
noise(P.x, P.z, item.noise || 1);
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
359
482
|
const crowd = world.crowd;
|
|
360
483
|
const i = t[1];
|
|
361
484
|
const region = crowd.down(i) ? 0 : random() < numbers.meleeHeadChance ? 0 : random() < numbers.meleeArmChance ? 1 : 2 + Math.floor(random() * 2);
|
|
485
|
+
const hit = hitSoundId(blow, region === 0 ? "head" : "body");
|
|
486
|
+
if (swing) sound("flesh", numbers.meleeVolume, [swing, hit], void 0, [0, SWING_LEAD_SECONDS[blow]]);
|
|
487
|
+
else sound("flesh", numbers.meleeVolume, [hit]);
|
|
488
|
+
noise(P.x, P.z, item.noise || 1);
|
|
362
489
|
const damage = item.damage * (1 + (attributes.strength - numbers.meleeStrengthBase) * numbers.meleeStrengthPerPoint);
|
|
363
490
|
const cut = Math.min(1, (item.crit || 0) / numbers.meleeCritToCut);
|
|
364
491
|
crowd.damage(i, { region, amount: damage, distance: t[0], cut });
|
|
@@ -366,6 +493,7 @@ var GamePlayer = (() => {
|
|
|
366
493
|
};
|
|
367
494
|
const update = (dt, input = {}, frameWorld) => {
|
|
368
495
|
world = frameWorld ?? defaultWorld;
|
|
496
|
+
surfaceHint = input.surface;
|
|
369
497
|
if (!P.alive) {
|
|
370
498
|
P.deathTime += dt;
|
|
371
499
|
if (P.infected && infection && !P.turned && P.deathTime >= infection.reanimateSeconds) {
|
|
@@ -393,7 +521,7 @@ var GamePlayer = (() => {
|
|
|
393
521
|
const every = 1 / infection.feverNoiseEvery;
|
|
394
522
|
if (P.infectionTime > infection.feverSeconds && Math.floor(P.infectionTime * every) !== Math.floor((P.infectionTime - dt) * every) && random() < infection.feverNoiseChance) {
|
|
395
523
|
noise(P.x, P.z, infection.feverNoiseRadius);
|
|
396
|
-
sound("step", infection.feverNoiseVolume);
|
|
524
|
+
sound("step", infection.feverNoiseVolume, ["cloth_rustle"]);
|
|
397
525
|
}
|
|
398
526
|
if (P.infectionTime > infection.deathSeconds) {
|
|
399
527
|
P.health = 0;
|
|
@@ -428,7 +556,7 @@ var GamePlayer = (() => {
|
|
|
428
556
|
if (wasPressed("push") && P.stamina > numbers.grabPushMinStamina) {
|
|
429
557
|
P.grabPushes++;
|
|
430
558
|
P.stamina -= numbers.grabPushCost;
|
|
431
|
-
sound("step", numbers.grabPushVolume);
|
|
559
|
+
sound("step", numbers.grabPushVolume, ["shove_two_hands"]);
|
|
432
560
|
}
|
|
433
561
|
if (wasPressed("knife")) {
|
|
434
562
|
if (random() < numbers.grabKnifeChance) {
|
|
@@ -482,7 +610,8 @@ var GamePlayer = (() => {
|
|
|
482
610
|
if (P.vaultTimer <= 0) {
|
|
483
611
|
P.y = 0;
|
|
484
612
|
noise(P.x, P.z, numbers.vaultNoise);
|
|
485
|
-
|
|
613
|
+
const surface = surfaceHere();
|
|
614
|
+
sound("step", numbers.vaultLandVolume, [landSoundId(surface, 0)], surface);
|
|
486
615
|
}
|
|
487
616
|
return;
|
|
488
617
|
}
|
|
@@ -499,7 +628,7 @@ var GamePlayer = (() => {
|
|
|
499
628
|
P.vault = [P.x, P.z, ex, ez];
|
|
500
629
|
P.vaultTimer = numbers.vaultSeconds;
|
|
501
630
|
P.stamina -= numbers.vaultCost;
|
|
502
|
-
sound("step", numbers.vaultStartVolume);
|
|
631
|
+
sound("step", numbers.vaultStartVolume, ["jump"]);
|
|
503
632
|
emit("vault", { from: [P.x, P.z], to: [ex, ez] });
|
|
504
633
|
return;
|
|
505
634
|
}
|
|
@@ -572,11 +701,14 @@ var GamePlayer = (() => {
|
|
|
572
701
|
dy -= Math.round(dy / TAU_APPROX) * TAU_APPROX;
|
|
573
702
|
P.yaw += input.aim || input.firing ? dy : dy * Math.min(1, dt * numbers.turnFollow);
|
|
574
703
|
}
|
|
704
|
+
if (input.footfall) hostFeet = true;
|
|
575
705
|
P.stepTimer -= dt * spd;
|
|
576
|
-
|
|
706
|
+
const stepNow = hostFeet ? input.footfall === true : P.stepTimer <= 0 && spd > numbers.stepMinSpeed;
|
|
707
|
+
if (stepNow) {
|
|
577
708
|
P.stepTimer = numbers.stepEvery;
|
|
578
709
|
noise(P.x, P.z, (P.running ? numbers.stepNoiseRun : P.crouch ? numbers.stepNoiseCrouch : numbers.stepNoiseWalk) * derived.footstepNoise * (wet ? numbers.stepNoiseWater : 1));
|
|
579
|
-
|
|
710
|
+
const surface = surfaceHere();
|
|
711
|
+
sound("step", P.running ? numbers.stepVolumeRun : numbers.stepVolumeWalk, [footstepSoundId(surface, P.running ? "run" : "walk")], surface);
|
|
580
712
|
emit("step", { x: P.x, z: P.z, yaw: P.yaw });
|
|
581
713
|
}
|
|
582
714
|
if (wasPressed("push") && P.stamina > numbers.shoveCost) {
|
|
@@ -904,6 +1036,7 @@ var GamePlayer = (() => {
|
|
|
904
1036
|
|
|
905
1037
|
// src/bench/module.ts
|
|
906
1038
|
var MOVING_SPEED = 0.2;
|
|
1039
|
+
var TELEPORT_SPEED = 10;
|
|
907
1040
|
var SPRINT_SPEED = 3.4;
|
|
908
1041
|
var FRAME = 1 / 30;
|
|
909
1042
|
var createGrabber = () => {
|
|
@@ -948,6 +1081,9 @@ var GamePlayer = (() => {
|
|
|
948
1081
|
let lastMessage = "";
|
|
949
1082
|
let pending = {};
|
|
950
1083
|
let bandage = false;
|
|
1084
|
+
let footfall = false;
|
|
1085
|
+
let surface;
|
|
1086
|
+
let gait;
|
|
951
1087
|
let last = null;
|
|
952
1088
|
const offs = [];
|
|
953
1089
|
const build = () => {
|
|
@@ -956,7 +1092,15 @@ var GamePlayer = (() => {
|
|
|
956
1092
|
offs.push(made.on("noise", (e) => void (lastNoise = e.radius)));
|
|
957
1093
|
offs.push(made.on("step", () => void (steps += 1)));
|
|
958
1094
|
offs.push(made.on("message", (e) => void (lastMessage = playerTextOf(e.id, locale))));
|
|
959
|
-
offs.push(
|
|
1095
|
+
offs.push(
|
|
1096
|
+
made.on("sound", (e) => {
|
|
1097
|
+
if (e.ids.length === 0) return;
|
|
1098
|
+
e.ids.forEach((id, index) => {
|
|
1099
|
+
const delay = e.at?.[index] ?? 0;
|
|
1100
|
+
host?.audio?.play({ sound: id, volume: e.volume, position: e.position, urgent: true, ...delay > 0 ? { delay } : {} });
|
|
1101
|
+
});
|
|
1102
|
+
})
|
|
1103
|
+
);
|
|
960
1104
|
offs.push(made.on("died", (e) => host?.log(`player died: ${e.cause}`, { cause: e.cause })));
|
|
961
1105
|
lastNoise = 0;
|
|
962
1106
|
steps = 0;
|
|
@@ -976,13 +1120,15 @@ var GamePlayer = (() => {
|
|
|
976
1120
|
};
|
|
977
1121
|
const frame = (dt) => {
|
|
978
1122
|
const here = view();
|
|
979
|
-
const
|
|
1123
|
+
const raw = here && last && dt > 0 ? Math.hypot(here.x - last.x, here.z - last.z) / dt : 0;
|
|
1124
|
+
const speed = raw > TELEPORT_SPEED ? 0 : raw;
|
|
980
1125
|
if (here) {
|
|
981
1126
|
player.state.x = here.x;
|
|
982
1127
|
player.state.z = here.z;
|
|
983
1128
|
}
|
|
984
|
-
const input = { forward: speed > MOVING_SPEED ? 1 : 0, run: speed > SPRINT_SPEED, yaw: here?.yaw ?? 0, bandage, pressed: pending };
|
|
1129
|
+
const input = { forward: speed > MOVING_SPEED ? 1 : 0, run: gait ? gait === "run" : speed > SPRINT_SPEED, yaw: here?.yaw ?? 0, bandage, pressed: pending, footfall, ...surface ? { surface } : {} };
|
|
985
1130
|
pending = {};
|
|
1131
|
+
footfall = false;
|
|
986
1132
|
bandage = false;
|
|
987
1133
|
player.update(dt, input, { crowd: grabber.crowd });
|
|
988
1134
|
if (here) {
|
|
@@ -1150,9 +1296,16 @@ var GamePlayer = (() => {
|
|
|
1150
1296
|
last = null;
|
|
1151
1297
|
const off = lent.bench?.onChange(onChange);
|
|
1152
1298
|
const offFrame = lent.onFrame(frame);
|
|
1299
|
+
const offFeet = lent.on((event) => {
|
|
1300
|
+
if (event.type !== "footfall") return;
|
|
1301
|
+
footfall = true;
|
|
1302
|
+
surface = event.surface;
|
|
1303
|
+
gait = event.gait;
|
|
1304
|
+
});
|
|
1153
1305
|
return () => {
|
|
1154
1306
|
off?.();
|
|
1155
1307
|
offFrame();
|
|
1308
|
+
offFeet();
|
|
1156
1309
|
host = null;
|
|
1157
1310
|
};
|
|
1158
1311
|
}
|
|
@@ -1165,7 +1318,8 @@ var GamePlayer = (() => {
|
|
|
1165
1318
|
reachSeconds: 0.3,
|
|
1166
1319
|
swingSeconds: { base: 0.45, perKg: 0.02, min: 0.45, max: 1.6 },
|
|
1167
1320
|
releaseSeconds: 0.22,
|
|
1168
|
-
|
|
1321
|
+
// the length of the recorded handle shaken (game-audio door_locked_rattle, 0.6 to 0.83 s): the hand lets go as the sound ends
|
|
1322
|
+
rattleSeconds: 0.75,
|
|
1169
1323
|
stepFraction: 0.04,
|
|
1170
1324
|
endTolerance: 0.02
|
|
1171
1325
|
};
|