@adatechnology/game-test-room 0.24.0 → 0.25.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/index.d.ts +3 -1
- package/dist/index.global.js +188 -25
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +73 -11
- package/dist/index.js.map +1 -1
- package/package.json +14 -14
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { AudioEngine } from '@adatechnology/game-audio';
|
|
|
4
4
|
import { Vec3 as Vec3$1, DestructionWorld, BlastOptions, DestructibleSpec, DestructionOptions, DestructionEvent } from '@adatechnology/game-destruction';
|
|
5
5
|
export { DestructionEvent, Vec3 } from '@adatechnology/game-destruction';
|
|
6
6
|
import { DoorUsePhase, FurniturePushPhase, FurniturePushBlock, FurniturePushRules, DoorUseRules } from '@adatechnology/game-player';
|
|
7
|
-
import { BusySink, ItemSeat, Vec3, HandTargets, ModuleControl, ControlValue, ModuleLayer, EnvironmentBus, Knock, BusyTask, BusyOptions, TestableModule, ModuleItemSeal, DestructibleImpl, AnimationClipSpec, ItemSounds, GroundLayout, BlastShoveOptions } from '@adatechnology/game-contracts';
|
|
7
|
+
import { BusySink, ItemSeat, Vec3, HandTargets, ModuleControl, ControlValue, ModuleLayer, EnvironmentBus, Knock, BusyTask, BusyOptions, TestableModule, ModuleItemSeal, DestructibleImpl, AnimationClipSpec, ItemSounds, GroundLayout, BlastImpulseOptions, BlastShoveOptions } from '@adatechnology/game-contracts';
|
|
8
8
|
export { AnimationClipSpec, DestructibleImpl, ItemAnimationContract, ModuleScenario, TestableItem, TestableModule } from '@adatechnology/game-contracts';
|
|
9
9
|
import { DestructionRenderer, SpecFromObjectOptions, Quality, SoundDetail, FragmentLifeRule } from '@adatechnology/game-destruction-three';
|
|
10
10
|
import { StorageLike, GraphicsController } from '@adatechnology/game-graphics';
|
|
@@ -831,6 +831,8 @@ interface TestRoomOptions {
|
|
|
831
831
|
* The numbers of the shove an explosion gives to what is around it: loose items, furniture, and the bodies of the modules (people), which read them from `ModuleHost.blastShove`.
|
|
832
832
|
* Default: the SDK's (`DEFAULT_BLAST_SHOVE` of game-contracts: 2 % of the energy becomes speed, 20 m/s at most, falloff `(1 - d / r)^2`).
|
|
833
833
|
*/
|
|
834
|
+
/** The body the blast wave pushes (the player's area, the charge read from a blast without one): `knockOf` of `game-contracts`. Default `DEFAULT_BLAST_IMPULSE`. */
|
|
835
|
+
blastImpulse?: BlastImpulseOptions;
|
|
834
836
|
blastShove?: BlastShoveOptions;
|
|
835
837
|
/** Mass of the player's body in kg: how far a blast throws it and whether it knocks it down (default 70, the `bodyMass` of 1.75 m). */
|
|
836
838
|
playerMass?: number;
|
package/dist/index.global.js
CHANGED
|
@@ -62,8 +62,29 @@ var GameTestRoom = (() => {
|
|
|
62
62
|
const length3 = Math.hypot(direction[0], direction[1], direction[2]);
|
|
63
63
|
return { speed, direction: [direction[0] / length3, direction[1] / length3, direction[2] / length3], distance: distance4, falloff };
|
|
64
64
|
}
|
|
65
|
+
var DEFAULT_BLAST_IMPULSE = { bodyArea: 0.7, lift: 0.15, minSpeed: 0.3, tntPerJoule: 0.24 / 2e5 };
|
|
66
|
+
var NEAREST = 0.3;
|
|
67
|
+
function sideOnImpulse(tnt, distance4) {
|
|
68
|
+
if (!(tnt > 0)) return 0;
|
|
69
|
+
const w3 = Math.cbrt(tnt);
|
|
70
|
+
const z = Math.max(distance4, NEAREST) / w3;
|
|
71
|
+
const scaled2 = 0.067 * Math.sqrt(1 + (z / 0.23) ** 4) / (z * z * Math.cbrt(1 + (z / 1.55) ** 3));
|
|
72
|
+
return scaled2 * w3 * 100;
|
|
73
|
+
}
|
|
74
|
+
function bodyImpulse(tnt, distance4) {
|
|
75
|
+
if (!(tnt > 0)) return 0;
|
|
76
|
+
const z = Math.max(distance4, NEAREST) / Math.cbrt(tnt);
|
|
77
|
+
return sideOnImpulse(tnt, distance4) * (2 + 4 / (1 + z * z));
|
|
78
|
+
}
|
|
79
|
+
function blastBodySpeed(tnt, distance4, mass, reach = 1, options = {}) {
|
|
80
|
+
const area = options.bodyArea ?? DEFAULT_BLAST_IMPULSE.bodyArea;
|
|
81
|
+
return bodyImpulse(tnt, distance4) * area * Math.max(0, reach) / Math.max(mass, 1);
|
|
82
|
+
}
|
|
65
83
|
var KNOCK_DOWN_SPEED = 2.5;
|
|
66
84
|
var LIE_SECONDS = 1.6;
|
|
85
|
+
var WOUNDED_LIE_SECONDS = 6;
|
|
86
|
+
var FRAGMENT_COVER = 0.5;
|
|
87
|
+
var STUN_SECONDS = 4;
|
|
67
88
|
var STAND_UP_PER_SPEED = 0.25;
|
|
68
89
|
var FALL_SECONDS = 0.25;
|
|
69
90
|
var RISE_SECONDS = 0.6;
|
|
@@ -72,11 +93,38 @@ var GameTestRoom = (() => {
|
|
|
72
93
|
var KNOCK_CHEST = 1.1;
|
|
73
94
|
var CHEST = KNOCK_CHEST;
|
|
74
95
|
var bodyMass = (height, build = 1) => 70 * (height / 1.75) ** 2 * build;
|
|
75
|
-
function knockOf(blast3, feet, mass, options) {
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
|
|
96
|
+
function knockOf(blast3, feet, mass, options, impulse = {}) {
|
|
97
|
+
const o = { ...DEFAULT_BLAST_IMPULSE, ...impulse };
|
|
98
|
+
const chest = [feet[0], feet[1] + CHEST, feet[2]];
|
|
99
|
+
const dx = chest[0] - blast3.point[0];
|
|
100
|
+
const dy = chest[1] - blast3.point[1];
|
|
101
|
+
const dz = chest[2] - blast3.point[2];
|
|
102
|
+
const distance4 = Math.hypot(dx, dy, dz);
|
|
103
|
+
if (!(blast3.radius > 0) || distance4 > blast3.radius) return void 0;
|
|
104
|
+
const reach = Math.max(0, Math.min(1, blast3.reach ?? 1));
|
|
105
|
+
const tnt = blast3.tnt ?? blast3.energy * o.tntPerJoule;
|
|
106
|
+
let speed = blastBodySpeed(tnt, distance4, mass, reach, o);
|
|
107
|
+
const minSpeed = impulse.minSpeed ?? options?.minSpeed ?? o.minSpeed;
|
|
108
|
+
if (speed < minSpeed) speed = 0;
|
|
109
|
+
const struck = reach >= FRAGMENT_COVER;
|
|
110
|
+
const wounded = struck && blast3.lethalRadius !== void 0 && distance4 <= blast3.lethalRadius;
|
|
111
|
+
const edge = 1 - distance4 / blast3.radius;
|
|
112
|
+
const stunSeconds = struck ? STUN_SECONDS * edge * edge * reach : 0;
|
|
113
|
+
if (speed === 0 && !wounded && stunSeconds < 0.25) return void 0;
|
|
114
|
+
const horizontal = Math.hypot(dx, dz);
|
|
115
|
+
const away = horizontal > 1e-4 ? [dx / horizontal, o.lift, dz / horizontal] : [0, 1, 0];
|
|
116
|
+
const length3 = Math.hypot(away[0], away[1], away[2]);
|
|
117
|
+
const velocity = [away[0] / length3 * speed, away[1] / length3 * speed, away[2] / length3 * speed];
|
|
118
|
+
return {
|
|
119
|
+
velocity,
|
|
120
|
+
airborne: velocity[1] > 0.5,
|
|
121
|
+
lying: 0,
|
|
122
|
+
lieLeft: wounded ? WOUNDED_LIE_SECONDS : 0,
|
|
123
|
+
away: horizontal > 1e-4 ? [dx / horizontal, 0, dz / horizontal] : [0, 0, 0],
|
|
124
|
+
down: speed >= KNOCK_DOWN_SPEED || wounded,
|
|
125
|
+
...wounded ? { wounded } : {},
|
|
126
|
+
...stunSeconds >= 0.25 ? { stunSeconds } : {}
|
|
127
|
+
};
|
|
80
128
|
}
|
|
81
129
|
function stepKnock(knock2, position, dt, groundAt, alive) {
|
|
82
130
|
const v = knock2.velocity;
|
|
@@ -100,14 +148,11 @@ var GameTestRoom = (() => {
|
|
|
100
148
|
}
|
|
101
149
|
const moving = horizontal > 0.05 || knock2.airborne;
|
|
102
150
|
if (knock2.down) {
|
|
103
|
-
if (moving) knock2.lying = Math.min(1, knock2.lying + dt / FALL_SECONDS);
|
|
104
|
-
else {
|
|
105
|
-
knock2.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
knock2.lieLeft -= dt;
|
|
109
|
-
if (knock2.lieLeft <= 0) knock2.down = false;
|
|
110
|
-
}
|
|
151
|
+
if (moving || knock2.lying < 1) knock2.lying = Math.min(1, knock2.lying + dt / FALL_SECONDS);
|
|
152
|
+
else if (alive) {
|
|
153
|
+
knock2.lieLeft = knock2.lieLeft > 0 ? knock2.lieLeft : LIE_SECONDS + Math.hypot(v[0], v[2]) * STAND_UP_PER_SPEED;
|
|
154
|
+
knock2.lieLeft -= dt;
|
|
155
|
+
if (knock2.lieLeft <= 0) knock2.down = false;
|
|
111
156
|
}
|
|
112
157
|
} else if (knock2.lying > 0) knock2.lying = Math.max(0, knock2.lying - dt / RISE_SECONDS);
|
|
113
158
|
return !moving && !knock2.down && knock2.lying === 0;
|
|
@@ -5020,7 +5065,7 @@ var GameTestRoom = (() => {
|
|
|
5020
5065
|
return;
|
|
5021
5066
|
}
|
|
5022
5067
|
if (ex) {
|
|
5023
|
-
emit2({ ...base(o, src), type: "explode", part: p.spec.id, point: c, energy: ex.energy, radius: ex.radius, ...ex.lethalRadius !== void 0 ? { lethalRadius: ex.lethalRadius } : {}, ...ex.effect !== void 0 ? { effect: ex.effect } : {} });
|
|
5068
|
+
emit2({ ...base(o, src), type: "explode", part: p.spec.id, point: c, energy: ex.energy, radius: ex.radius, ...ex.lethalRadius !== void 0 ? { lethalRadius: ex.lethalRadius } : {}, ...ex.tnt !== void 0 ? { tnt: ex.tnt } : {}, ...ex.effect !== void 0 ? { effect: ex.effect } : {} });
|
|
5024
5069
|
blasts.push({ point: c, energy: ex.energy, radius: ex.radius, ...ex.lethalRadius !== void 0 ? { lethalRadius: ex.lethalRadius } : {}, source: src });
|
|
5025
5070
|
}
|
|
5026
5071
|
partLost(o, p, src);
|
|
@@ -18506,7 +18551,44 @@ var GameTestRoom = (() => {
|
|
|
18506
18551
|
renderer.compile(scene2, camera2);
|
|
18507
18552
|
renderer.render(scene2, camera2);
|
|
18508
18553
|
}
|
|
18554
|
+
function drawOnly(scene2, root) {
|
|
18555
|
+
const hidden = [];
|
|
18556
|
+
const visit = (object) => {
|
|
18557
|
+
if (object === root || !object.visible) return;
|
|
18558
|
+
const drawable = object;
|
|
18559
|
+
if (drawable.isMesh === true || drawable.isPoints === true || drawable.isLine === true || drawable.isSprite === true) {
|
|
18560
|
+
if (!holdsLight(object) && !holdsObject(object, root)) {
|
|
18561
|
+
object.visible = false;
|
|
18562
|
+
hidden.push(object);
|
|
18563
|
+
return;
|
|
18564
|
+
}
|
|
18565
|
+
}
|
|
18566
|
+
for (const child of object.children) visit(child);
|
|
18567
|
+
};
|
|
18568
|
+
for (const child of scene2.children) visit(child);
|
|
18569
|
+
return () => hidden.forEach((object) => object.visible = true);
|
|
18570
|
+
}
|
|
18571
|
+
function holdsLight(object) {
|
|
18572
|
+
let found = false;
|
|
18573
|
+
object.traverse((each) => {
|
|
18574
|
+
if (each.isLight === true) found = true;
|
|
18575
|
+
});
|
|
18576
|
+
return found;
|
|
18577
|
+
}
|
|
18578
|
+
function holdsObject(object, target) {
|
|
18579
|
+
for (let at3 = target; at3 !== null; at3 = at3.parent) if (at3 === object) return true;
|
|
18580
|
+
return false;
|
|
18581
|
+
}
|
|
18509
18582
|
function playEffect(renderer, scene2, camera2, effect, target) {
|
|
18583
|
+
const root = effect.root?.();
|
|
18584
|
+
const restore = root === null || root === void 0 ? () => void 0 : drawOnly(scene2, root);
|
|
18585
|
+
try {
|
|
18586
|
+
playFrames(renderer, scene2, camera2, effect, target);
|
|
18587
|
+
} finally {
|
|
18588
|
+
restore();
|
|
18589
|
+
}
|
|
18590
|
+
}
|
|
18591
|
+
function playFrames(renderer, scene2, camera2, effect, target) {
|
|
18510
18592
|
effect.play();
|
|
18511
18593
|
try {
|
|
18512
18594
|
for (let frame2 = 0; frame2 < (effect.frames ?? DEFAULT_EFFECT_FRAMES); frame2++) {
|
|
@@ -19013,7 +19095,7 @@ var GameTestRoom = (() => {
|
|
|
19013
19095
|
return sources;
|
|
19014
19096
|
}
|
|
19015
19097
|
|
|
19016
|
-
// ../game-vfx-three/dist/chunk-
|
|
19098
|
+
// ../game-vfx-three/dist/chunk-2MZDWTHX.js
|
|
19017
19099
|
var GLOW_VERTEX = `attribute vec4 aP;attribute vec4 aC;varying vec2 vU;varying vec4 vC;
|
|
19018
19100
|
void main(){vec3 R=vec3(viewMatrix[0][0],viewMatrix[1][0],viewMatrix[2][0]);vec3 Up=vec3(viewMatrix[0][1],viewMatrix[1][1],viewMatrix[2][1]);
|
|
19019
19101
|
vec3 wp=aP.xyz+(R*position.x+Up*position.y)*aP.w;vU=position.xy;vC=aC;gl_Position=projectionMatrix*viewMatrix*vec4(wp,1.);}`;
|
|
@@ -20393,6 +20475,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
20393
20475
|
drawCalls = Number(lastDrawn.puffs > 0) + Number(lastDrawn.sparks > 0) + Number(lastDrawn.glows > 0) + Number(chunks.rocks.count > 0) + Number(chunks.plates.count > 0) + Number(sprites.additive.geometry.drawRange.count > 0) + Number(sprites.normal.geometry.drawRange.count > 0) + lastDrawn.shocks * 2 + marks.count() + workshopCalls;
|
|
20394
20476
|
}
|
|
20395
20477
|
return {
|
|
20478
|
+
root,
|
|
20396
20479
|
world,
|
|
20397
20480
|
play(request) {
|
|
20398
20481
|
followCamera();
|
|
@@ -28830,6 +28913,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
28830
28913
|
lethalRadius: 5,
|
|
28831
28914
|
injuryRadius: 15,
|
|
28832
28915
|
energy: 2e5,
|
|
28916
|
+
tnt: 0.24,
|
|
28833
28917
|
destructionLevel: 2,
|
|
28834
28918
|
noise: 500,
|
|
28835
28919
|
fuse: 4,
|
|
@@ -28875,6 +28959,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
28875
28959
|
lethalRadius: 3,
|
|
28876
28960
|
injuryRadius: 10,
|
|
28877
28961
|
energy: 43200,
|
|
28962
|
+
tnt: 0.15,
|
|
28878
28963
|
destructionLevel: 2,
|
|
28879
28964
|
noise: 450,
|
|
28880
28965
|
fuse: 3,
|
|
@@ -28894,6 +28979,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
28894
28979
|
lethalRadius: 5,
|
|
28895
28980
|
injuryRadius: 14,
|
|
28896
28981
|
energy: 2e5,
|
|
28982
|
+
tnt: 1.5,
|
|
28897
28983
|
destructionLevel: 2,
|
|
28898
28984
|
noise: 550,
|
|
28899
28985
|
fire: {
|
|
@@ -28940,6 +29026,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
28940
29026
|
lethalRadius: 4,
|
|
28941
29027
|
injuryRadius: 12,
|
|
28942
29028
|
energy: 102400,
|
|
29029
|
+
tnt: 0.25,
|
|
28943
29030
|
destructionLevel: 3,
|
|
28944
29031
|
noise: 600,
|
|
28945
29032
|
fuseLength: 0.03,
|
|
@@ -28962,6 +29049,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
28962
29049
|
lethalRadius: 6,
|
|
28963
29050
|
injuryRadius: 18,
|
|
28964
29051
|
energy: 345600,
|
|
29052
|
+
tnt: 0.76,
|
|
28965
29053
|
destructionLevel: 3,
|
|
28966
29054
|
noise: 700,
|
|
28967
29055
|
triggers: [
|
|
@@ -28985,6 +29073,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
28985
29073
|
length: 50
|
|
28986
29074
|
},
|
|
28987
29075
|
energy: 102400,
|
|
29076
|
+
tnt: 0.9,
|
|
28988
29077
|
destructionLevel: 1,
|
|
28989
29078
|
noise: 500,
|
|
28990
29079
|
triggers: [
|
|
@@ -29008,6 +29097,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
29008
29097
|
lethalRadius: 0,
|
|
29009
29098
|
injuryRadius: 10,
|
|
29010
29099
|
energy: 0,
|
|
29100
|
+
tnt: 0.01,
|
|
29011
29101
|
destructionLevel: 0,
|
|
29012
29102
|
noise: 400,
|
|
29013
29103
|
fuseRange: [
|
|
@@ -29032,6 +29122,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
29032
29122
|
lethalRadius: 4,
|
|
29033
29123
|
injuryRadius: 12,
|
|
29034
29124
|
energy: 102400,
|
|
29125
|
+
tnt: 0.045,
|
|
29035
29126
|
destructionLevel: 2,
|
|
29036
29127
|
noise: 450,
|
|
29037
29128
|
triggers: [
|
|
@@ -29050,6 +29141,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
29050
29141
|
lethalRadius: 5,
|
|
29051
29142
|
injuryRadius: 15,
|
|
29052
29143
|
energy: 2e5,
|
|
29144
|
+
tnt: 0.45,
|
|
29053
29145
|
destructionLevel: 3,
|
|
29054
29146
|
noise: 700,
|
|
29055
29147
|
triggers: [
|
|
@@ -29068,6 +29160,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
29068
29160
|
lethalRadius: 5,
|
|
29069
29161
|
injuryRadius: 16,
|
|
29070
29162
|
energy: 2e5,
|
|
29163
|
+
tnt: 0.7,
|
|
29071
29164
|
destructionLevel: 3,
|
|
29072
29165
|
noise: 750,
|
|
29073
29166
|
triggers: [
|
|
@@ -29086,6 +29179,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
29086
29179
|
lethalRadius: 5,
|
|
29087
29180
|
injuryRadius: 16,
|
|
29088
29181
|
energy: 2e5,
|
|
29182
|
+
tnt: 0.45,
|
|
29089
29183
|
destructionLevel: 3,
|
|
29090
29184
|
noise: 750,
|
|
29091
29185
|
triggers: [
|
|
@@ -29104,6 +29198,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
29104
29198
|
lethalRadius: 5,
|
|
29105
29199
|
injuryRadius: 16,
|
|
29106
29200
|
energy: 2e5,
|
|
29201
|
+
tnt: 0.7,
|
|
29107
29202
|
destructionLevel: 3,
|
|
29108
29203
|
noise: 750,
|
|
29109
29204
|
triggers: [
|
|
@@ -29122,6 +29217,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
29122
29217
|
lethalRadius: 4,
|
|
29123
29218
|
injuryRadius: 12,
|
|
29124
29219
|
energy: 102400,
|
|
29220
|
+
tnt: 1,
|
|
29125
29221
|
destructionLevel: 2,
|
|
29126
29222
|
noise: 550,
|
|
29127
29223
|
fire: {
|
|
@@ -29155,6 +29251,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
29155
29251
|
lethalRadius: 5,
|
|
29156
29252
|
injuryRadius: 14,
|
|
29157
29253
|
energy: 2e5,
|
|
29254
|
+
tnt: 0.5,
|
|
29158
29255
|
destructionLevel: 2,
|
|
29159
29256
|
noise: 550,
|
|
29160
29257
|
fire: {
|
|
@@ -29192,6 +29289,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
29192
29289
|
lethalRadius: 4,
|
|
29193
29290
|
injuryRadius: 12,
|
|
29194
29291
|
energy: 102400,
|
|
29292
|
+
tnt: 0.5,
|
|
29195
29293
|
destructionLevel: 3,
|
|
29196
29294
|
noise: 700,
|
|
29197
29295
|
fire: {
|
|
@@ -29221,6 +29319,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
29221
29319
|
lethalRadius: 12,
|
|
29222
29320
|
injuryRadius: 30,
|
|
29223
29321
|
energy: 2764800,
|
|
29322
|
+
tnt: 20,
|
|
29224
29323
|
destructionLevel: 3,
|
|
29225
29324
|
noise: 700,
|
|
29226
29325
|
fire: {
|
|
@@ -29248,6 +29347,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
29248
29347
|
lethalRadius: 4,
|
|
29249
29348
|
injuryRadius: 12,
|
|
29250
29349
|
energy: 102400,
|
|
29350
|
+
tnt: 0.045,
|
|
29251
29351
|
destructionLevel: 2,
|
|
29252
29352
|
noise: 450,
|
|
29253
29353
|
triggers: [
|
|
@@ -37966,6 +38066,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
37966
38066
|
direction: this.facing,
|
|
37967
38067
|
at: at3,
|
|
37968
38068
|
energy: def.energy,
|
|
38069
|
+
...def.tnt !== void 0 ? { tnt: def.tnt } : {},
|
|
37969
38070
|
lethalRadius: def.lethalRadius,
|
|
37970
38071
|
injuryRadius: def.injuryRadius,
|
|
37971
38072
|
noise: def.noise,
|
|
@@ -45768,7 +45869,17 @@ void main(){
|
|
|
45768
45869
|
if (onPlayer.zone !== "none") {
|
|
45769
45870
|
action("blast_player", translate("act.blast_player", { weapon: weaponName, zone: translate(`blast.zone.${onPlayer.zone}`), distance: format(onPlayer.distance, 1), stun: format(onPlayer.stunSeconds, 1) }), { data: { ...onPlayer } });
|
|
45770
45871
|
}
|
|
45771
|
-
context.emitHost({
|
|
45872
|
+
context.emitHost({
|
|
45873
|
+
type: "explosion",
|
|
45874
|
+
source: projectile.weapon,
|
|
45875
|
+
point: detonation.point,
|
|
45876
|
+
energy: detonation.energy,
|
|
45877
|
+
radius: reach,
|
|
45878
|
+
cause: detonation.cause,
|
|
45879
|
+
explosive: detonation.explosive,
|
|
45880
|
+
lethalRadius: detonation.lethalRadius,
|
|
45881
|
+
...detonation.tnt !== void 0 ? { tnt: detonation.tnt } : {}
|
|
45882
|
+
});
|
|
45772
45883
|
if (detonation.fire) context.startFire(projectile.weapon, detonation.point, detonation.fire, detonation.cause === "impact");
|
|
45773
45884
|
};
|
|
45774
45885
|
const detonateBare = (projectile, isImpact) => {
|
|
@@ -47937,6 +48048,9 @@ void main(){
|
|
|
47937
48048
|
var LYING_PITCH = 1.05;
|
|
47938
48049
|
var LYING_ROLL = 0.35;
|
|
47939
48050
|
var LYING_PITCH_FACE_DOWN = -1.05;
|
|
48051
|
+
var STUN_PITCH = 0.05;
|
|
48052
|
+
var STUN_ROLL = 0.08;
|
|
48053
|
+
var STUN_FULL = 2;
|
|
47940
48054
|
function createPlayer(THREE, o) {
|
|
47941
48055
|
const cam = o.camera;
|
|
47942
48056
|
let yaw = 0;
|
|
@@ -47976,11 +48090,16 @@ void main(){
|
|
|
47976
48090
|
};
|
|
47977
48091
|
let knocked = null;
|
|
47978
48092
|
let knockedForward = false;
|
|
48093
|
+
let stunLeft = 0;
|
|
48094
|
+
let stunPhase = 0;
|
|
47979
48095
|
let rollSide = 1;
|
|
47980
48096
|
const apply = () => {
|
|
47981
48097
|
const lying = knocked?.lying ?? 0;
|
|
47982
48098
|
const fallen = lying * lying * (3 - 2 * lying);
|
|
47983
|
-
|
|
48099
|
+
const sway = Math.min(1, stunLeft / STUN_FULL);
|
|
48100
|
+
const swayPitch = STUN_PITCH * sway * Math.sin(stunPhase * 1.3);
|
|
48101
|
+
const swayRoll = STUN_ROLL * sway * Math.sin(stunPhase * 0.9 + 1);
|
|
48102
|
+
euler.set(pitch + ((knockedForward ? LYING_PITCH_FACE_DOWN : LYING_PITCH) - pitch) * fallen + swayPitch, yaw, LYING_ROLL * rollSide * fallen + swayRoll, "YXZ");
|
|
47984
48103
|
cam.quaternion.setFromEuler(euler);
|
|
47985
48104
|
const standing = eye - CROUCH_DROP * crouch - bend;
|
|
47986
48105
|
cam.position.set(px.x, floorLevel + y + standing + (LYING_EYE - standing) * fallen, px.z);
|
|
@@ -48254,11 +48373,15 @@ void main(){
|
|
|
48254
48373
|
knocked.velocity = [knocked.velocity[0] + next.velocity[0], knocked.velocity[1] + next.velocity[1], knocked.velocity[2] + next.velocity[2]];
|
|
48255
48374
|
knocked.airborne || (knocked.airborne = next.airborne);
|
|
48256
48375
|
knocked.down || (knocked.down = next.down);
|
|
48376
|
+
knocked.wounded || (knocked.wounded = next.wounded);
|
|
48377
|
+
knocked.lieLeft = Math.max(knocked.lieLeft, next.lieLeft);
|
|
48257
48378
|
} else knocked = { ...next, velocity: [...next.velocity] };
|
|
48379
|
+
stunLeft = Math.max(stunLeft, next.stunSeconds ?? 0);
|
|
48258
48380
|
if (next.down) {
|
|
48259
|
-
const
|
|
48381
|
+
const away = next.away && (next.away[0] !== 0 || next.away[2] !== 0) ? next.away : next.velocity;
|
|
48382
|
+
const right = Math.cos(yaw) * away[0] - Math.sin(yaw) * away[2];
|
|
48260
48383
|
rollSide = right >= 0 ? -1 : 1;
|
|
48261
|
-
knockedForward = -Math.sin(yaw) *
|
|
48384
|
+
knockedForward = -Math.sin(yaw) * away[0] - Math.cos(yaw) * away[2] > 0;
|
|
48262
48385
|
crouchLatched = false;
|
|
48263
48386
|
}
|
|
48264
48387
|
if (knocked.airborne) vy2 = Math.max(vy2, knocked.velocity[1]);
|
|
@@ -48269,7 +48392,14 @@ void main(){
|
|
|
48269
48392
|
get knockedForward() {
|
|
48270
48393
|
return knockedForward;
|
|
48271
48394
|
},
|
|
48395
|
+
get stunned() {
|
|
48396
|
+
return stunLeft;
|
|
48397
|
+
},
|
|
48272
48398
|
update(dt) {
|
|
48399
|
+
if (stunLeft > 0) {
|
|
48400
|
+
stunLeft = Math.max(0, stunLeft - dt);
|
|
48401
|
+
stunPhase += dt * 2.4;
|
|
48402
|
+
}
|
|
48273
48403
|
if (knocked) {
|
|
48274
48404
|
stepKnocked(dt);
|
|
48275
48405
|
return;
|
|
@@ -51418,6 +51548,9 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
|
|
|
51418
51548
|
"act.player_slammed": "The player was thrown into {what} at {speed} m/s",
|
|
51419
51549
|
"act.player_fell": "The player hit the floor at {speed} m/s",
|
|
51420
51550
|
"act.player_shoved": "The blast pushed the player at {speed} m/s ({reach}% got through the cover)",
|
|
51551
|
+
"act.player_wounded": "The blast felled the player where they stood, {distance} m from it: badly wounded, stunned for {stun} s ({reach}% got through the cover)",
|
|
51552
|
+
"act.player_thrown_wounded": "The blast threw the player at {speed} m/s, {distance} m from it: badly wounded, stunned for {stun} s ({reach}% got through the cover)",
|
|
51553
|
+
"act.player_stunned": "The blast stunned the player for {stun} s, {distance} m from it: dizzy, ears ringing",
|
|
51421
51554
|
"act.came_apart": "{name} came apart: what stayed is loose and falls",
|
|
51422
51555
|
"act.shoved": "{name} stands free: the shots moved it",
|
|
51423
51556
|
"act.impact": "{name} hit {where} at {speed} m/s: {energy} J of blunt damage",
|
|
@@ -51780,6 +51913,9 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
|
|
|
51780
51913
|
"act.player_slammed": "O jogador foi arremessado contra {what} a {speed} m/s",
|
|
51781
51914
|
"act.player_fell": "O jogador bateu no ch\xE3o a {speed} m/s",
|
|
51782
51915
|
"act.player_shoved": "A explos\xE3o empurrou o jogador a {speed} m/s ({reach}% passou pela cobertura)",
|
|
51916
|
+
"act.player_wounded": "A explos\xE3o derrubou o jogador onde estava, a {distance} m dela: ferido gravemente, atordoado por {stun} s ({reach}% passou pela cobertura)",
|
|
51917
|
+
"act.player_thrown_wounded": "A explos\xE3o arremessou o jogador a {speed} m/s, a {distance} m dela: ferido gravemente, atordoado por {stun} s ({reach}% passou pela cobertura)",
|
|
51918
|
+
"act.player_stunned": "A explos\xE3o atordoou o jogador por {stun} s, a {distance} m dela: tonto, com os ouvidos zumbindo",
|
|
51783
51919
|
"act.came_apart": "{name} se desmontou: o que ficou est\xE1 solto e cai",
|
|
51784
51920
|
"act.shoved": "{name} estava solto no ch\xE3o: os tiros o moveram",
|
|
51785
51921
|
"act.impact": "{name} bateu em {where} a {speed} m/s: {energy} J de dano de impacto",
|
|
@@ -53509,7 +53645,19 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
|
|
|
53509
53645
|
for (const ev of batch) {
|
|
53510
53646
|
if (ev.type === "leak") puncture(ev);
|
|
53511
53647
|
else if (ev.type === "ignite") igniteNear(ev.point, 0.9);
|
|
53512
|
-
else if (ev.type === "explode")
|
|
53648
|
+
else if (ev.type === "explode") {
|
|
53649
|
+
emitHost({
|
|
53650
|
+
type: "explosion",
|
|
53651
|
+
source: ev.object,
|
|
53652
|
+
point: ev.point,
|
|
53653
|
+
energy: ev.energy,
|
|
53654
|
+
radius: ev.radius,
|
|
53655
|
+
cause: "part",
|
|
53656
|
+
...ev.effect !== void 0 ? { explosive: ev.effect } : {},
|
|
53657
|
+
...ev.tnt !== void 0 ? { tnt: ev.tnt } : {},
|
|
53658
|
+
...ev.lethalRadius !== void 0 ? { lethalRadius: ev.lethalRadius } : {}
|
|
53659
|
+
});
|
|
53660
|
+
}
|
|
53513
53661
|
fire2("event", ev);
|
|
53514
53662
|
options.onEvent?.(ev);
|
|
53515
53663
|
}
|
|
@@ -54205,14 +54353,27 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
|
|
|
54205
54353
|
const knockPlayer = (event) => {
|
|
54206
54354
|
if (seating.seat) return;
|
|
54207
54355
|
const feet = [player.x, player.feet, player.z];
|
|
54208
|
-
const
|
|
54209
|
-
const
|
|
54356
|
+
const chest = [feet[0], feet[1] + KNOCK_CHEST, feet[2]];
|
|
54357
|
+
const reach = world.blastReach(event.point, chest, event.source ? { ignore: [event.source] } : {});
|
|
54358
|
+
const blast3 = {
|
|
54359
|
+
point: event.point,
|
|
54360
|
+
energy: event.energy,
|
|
54361
|
+
radius: event.radius,
|
|
54362
|
+
reach,
|
|
54363
|
+
...event.tnt !== void 0 ? { tnt: event.tnt } : {},
|
|
54364
|
+
...event.lethalRadius !== void 0 ? { lethalRadius: event.lethalRadius } : {}
|
|
54365
|
+
};
|
|
54366
|
+
const knock2 = knockOf(blast3, feet, playerMass, options.blastShove, options.blastImpulse);
|
|
54210
54367
|
if (!knock2) return;
|
|
54211
54368
|
player.knock(knock2);
|
|
54212
54369
|
const speed = Math.hypot(knock2.velocity[0], knock2.velocity[1], knock2.velocity[2]);
|
|
54213
|
-
|
|
54214
|
-
|
|
54215
|
-
}
|
|
54370
|
+
const distance4 = Math.hypot(chest[0] - event.point[0], chest[1] - event.point[1], chest[2] - event.point[2]);
|
|
54371
|
+
const data = { speed, reach, distance: distance4, down: knock2.down, wounded: Boolean(knock2.wounded), stunSeconds: knock2.stunSeconds ?? 0, source: event.source };
|
|
54372
|
+
const values = { speed: num(speed, 1), reach: num(reach * 100, 0), distance: num(distance4, 1), stun: num(knock2.stunSeconds ?? 0, 1) };
|
|
54373
|
+
if (knock2.wounded) action("player_wounded", t(speed >= KNOCK_DOWN_SPEED ? "act.player_thrown_wounded" : "act.player_wounded", values), { data });
|
|
54374
|
+
else if (knock2.down) action("player_knocked_down", t("act.knocked_down", values), { data });
|
|
54375
|
+
else if (speed > 0) action("player_shoved", t("act.player_shoved", values), { data });
|
|
54376
|
+
else action("player_stunned", t("act.player_stunned", values), { data });
|
|
54216
54377
|
};
|
|
54217
54378
|
const avatarState = { speed: 0, running: false, crouch: false, down: false, armed: false, pitch: 0 };
|
|
54218
54379
|
let feetPrev = null;
|
|
@@ -56172,6 +56333,8 @@ ${SURFACE_GLSL}`).replace("#include <color_fragment>", "#include <color_fragment
|
|
|
56172
56333
|
let handle = null;
|
|
56173
56334
|
return {
|
|
56174
56335
|
id: `vfx:${id}`,
|
|
56336
|
+
// the room was drawn in every fog state just before: each frame of a blast draws the effects alone
|
|
56337
|
+
root: () => vfx.root,
|
|
56175
56338
|
play() {
|
|
56176
56339
|
handle = vfx.play({ effect: id, point: [0, 0.1, -4], direction: [0, 1, 0], normal: [0, 1, 0] });
|
|
56177
56340
|
},
|