@adatechnology/game-test-room 0.17.0 → 0.17.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.global.js +69 -13
- package/dist/index.global.js.map +1 -1
- package/package.json +13 -13
package/dist/index.global.js
CHANGED
|
@@ -2270,6 +2270,7 @@ var GameTestRoom = (() => {
|
|
|
2270
2270
|
},
|
|
2271
2271
|
hitDebris: "chips",
|
|
2272
2272
|
breakDebris: "dust",
|
|
2273
|
+
visual: { innerColor: 10197652 },
|
|
2273
2274
|
thermal: {
|
|
2274
2275
|
conductivity: 0.15,
|
|
2275
2276
|
heatCapacity: 2.5
|
|
@@ -2300,6 +2301,7 @@ var GameTestRoom = (() => {
|
|
|
2300
2301
|
],
|
|
2301
2302
|
hitDebris: "chips",
|
|
2302
2303
|
breakDebris: "dust",
|
|
2304
|
+
visual: { innerColor: 12085567 },
|
|
2303
2305
|
thermal: {
|
|
2304
2306
|
conductivity: 0.15,
|
|
2305
2307
|
heatCapacity: 2.5
|
|
@@ -2330,6 +2332,7 @@ var GameTestRoom = (() => {
|
|
|
2330
2332
|
],
|
|
2331
2333
|
hitDebris: "dust",
|
|
2332
2334
|
breakDebris: "dust",
|
|
2335
|
+
visual: { innerColor: 14999507 },
|
|
2333
2336
|
thermal: {
|
|
2334
2337
|
conductivity: 0.1,
|
|
2335
2338
|
heatCapacity: 1.5
|
|
@@ -2355,6 +2358,7 @@ var GameTestRoom = (() => {
|
|
|
2355
2358
|
],
|
|
2356
2359
|
hitDebris: "chips",
|
|
2357
2360
|
breakDebris: "dust",
|
|
2361
|
+
visual: { innerColor: 9407364 },
|
|
2358
2362
|
thermal: {
|
|
2359
2363
|
conductivity: 0.2,
|
|
2360
2364
|
heatCapacity: 2.5
|
|
@@ -3117,6 +3121,7 @@ var GameTestRoom = (() => {
|
|
|
3117
3121
|
var CHIP_ENERGY = 200;
|
|
3118
3122
|
var CHIP_SPLASH = 0.5;
|
|
3119
3123
|
var BAR_BOW = 0.08;
|
|
3124
|
+
var BULLET_JOINT_SPAN = 0.3;
|
|
3120
3125
|
var CUT_SLICE = 1;
|
|
3121
3126
|
var cutFactorOf = (shape) => clamp2(Math.max(...shapeDims(shape)) / CUT_SLICE, 1, 50);
|
|
3122
3127
|
var clamp2 = (v, a, b) => Math.max(a, Math.min(b, v));
|
|
@@ -4243,7 +4248,7 @@ var GameTestRoom = (() => {
|
|
|
4243
4248
|
emit2({ ...base(o, src), type: "crack", part: p.spec.id, crack, worldPoint: wp });
|
|
4244
4249
|
setStage(o, p, 1, {}, src);
|
|
4245
4250
|
};
|
|
4246
|
-
const debris2 = (o, p, kind, point, normal, count, speed, src) => emit2({ ...base(o, src), type: "debris", part: p.spec.id, kind, point, normal, count, speed });
|
|
4251
|
+
const debris2 = (o, p, kind, point, normal, count, speed, src, material) => emit2({ ...base(o, src), type: "debris", part: p.spec.id, kind, point, normal, count, speed, ...material && material !== p.spec.material ? { material } : {} });
|
|
4247
4252
|
const holeRate = (hole, pressurized) => (pressurized ? 0.5 : 0.1) * (hole.diameter / 9e-3);
|
|
4248
4253
|
const detachEvents = (o, opened, by, src) => {
|
|
4249
4254
|
for (const j of opened) emit2({ ...base(o, src), type: "detach", joint: j.spec.id, parts: [j.spec.a, j.spec.b], by, groups: o.st.groups.map((g) => [...g]) });
|
|
@@ -4284,7 +4289,13 @@ var GameTestRoom = (() => {
|
|
|
4284
4289
|
const small = pa.dims[0] * pa.dims[1] * pa.dims[2] <= pb.dims[0] * pb.dims[1] * pb.dims[2] ? pa : pb;
|
|
4285
4290
|
return Math.max(0.06, 0.5 * Math.min(small.dims[0], small.dims[1], small.dims[2]));
|
|
4286
4291
|
};
|
|
4287
|
-
const
|
|
4292
|
+
const jointLength = (o, j) => {
|
|
4293
|
+
const A = partWorldAabb(o, o.parts[j.ia]), B = partWorldAabb(o, o.parts[j.ib]);
|
|
4294
|
+
let len = 0;
|
|
4295
|
+
for (let k = 0; k < 3; k++) len = Math.max(len, Math.min(A.max[k], B.max[k]) - Math.max(A.min[k], B.min[k]));
|
|
4296
|
+
return len;
|
|
4297
|
+
};
|
|
4298
|
+
const wearJoints = (o, p, amount, near, radius = 0.06, src, split = false, span) => {
|
|
4288
4299
|
if (amount <= 0) return;
|
|
4289
4300
|
const mine = (o.byPart.get(p.spec.id) ?? []).filter((j) => !j.st.open);
|
|
4290
4301
|
if (split && mine.length) amount /= mine.length;
|
|
@@ -4292,7 +4303,7 @@ var GameTestRoom = (() => {
|
|
|
4292
4303
|
if (j.st.open) continue;
|
|
4293
4304
|
if (j.spec.kind === "rebar" && (isReinforced(o.parts[j.ia].spec) || isReinforced(o.parts[j.ib].spec))) continue;
|
|
4294
4305
|
if (near && jointReach(o, j, near) > Math.max(radius, jointReachLimit(o, j))) continue;
|
|
4295
|
-
j.st.hp -= amount;
|
|
4306
|
+
j.st.hp -= span === void 0 ? amount : amount * Math.min(1, span / Math.max(jointLength(o, j), 1e-6));
|
|
4296
4307
|
if (j.st.hp <= 0) {
|
|
4297
4308
|
j.st.hp = 0;
|
|
4298
4309
|
j.st.open = true;
|
|
@@ -4321,7 +4332,7 @@ var GameTestRoom = (() => {
|
|
|
4321
4332
|
if (spalls.length > MAX_SPALLS) spalls.shift();
|
|
4322
4333
|
markDamaged(p);
|
|
4323
4334
|
emit2({ ...base(o, src), type: "spall", part: p.spec.id, layer: layer2.index, point: wp, area: Math.PI * radius * radius });
|
|
4324
|
-
debris2(o, p, layer2.mat.hitDebris, wp, normal, 5, 2, src);
|
|
4335
|
+
debris2(o, p, layer2.mat.hitDebris, wp, normal, 5, 2, src, layer2.mat.id);
|
|
4325
4336
|
setStage(o, p, 1, {}, src);
|
|
4326
4337
|
};
|
|
4327
4338
|
const crater = (o, p, wp, normal, radius, src) => {
|
|
@@ -4808,7 +4819,7 @@ var GameTestRoom = (() => {
|
|
|
4808
4819
|
if (mat.fracture !== "shatter") addHole(o, p, entry, n, caliber / 1e3, false, void 0, src);
|
|
4809
4820
|
} else addHole(o, p, entry, n, caliber / 1e3, false, void 0, src);
|
|
4810
4821
|
debris2(o, p, mat.hitDebris, entry, n, clamp2(Math.round(E / 60) + 2, 2, 14), clamp2(Math.sqrt(E) / 6, 1, 8), src);
|
|
4811
|
-
wearJoints(o, p, (penetrated ? thr : E) * 0.02, void 0, 0, src, true);
|
|
4822
|
+
wearJoints(o, p, (penetrated ? thr : E) * 0.02, void 0, 0, src, true, BULLET_JOINT_SPAN);
|
|
4812
4823
|
const absorbed = penetrated && mat.ductility >= 0.5 && mat.fracture !== "tear" ? Math.min(E, thr) : E;
|
|
4813
4824
|
const dmg = applyDamage(o, p, absorbed * DMG_PER_J * scale2, "ballistic", entry, d, absorbed * 0.1, 12, src);
|
|
4814
4825
|
if (!isLost(p)) tearAt(o, p, "ballistic", entry, penetrated ? exitPoint : void 0, d, E, caliber / 1e3, src);
|
|
@@ -13935,6 +13946,24 @@ var GameTestRoom = (() => {
|
|
|
13935
13946
|
for (const decal2 of this.decals) decal2.on = false;
|
|
13936
13947
|
this.count = 0;
|
|
13937
13948
|
}
|
|
13949
|
+
/**
|
|
13950
|
+
* Takes away the marks inside a box: world `center`, `half` extents along the axes of the world `rotation` (a quaternion, x y z w; none means the
|
|
13951
|
+
* world axes). The surface they were on is gone (a brick came out of a wall with its bullet holes). Returns how many went.
|
|
13952
|
+
*/
|
|
13953
|
+
clearInside(center, half, rotation = [0, 0, 0, 1]) {
|
|
13954
|
+
const qx = -rotation[0], qy = -rotation[1], qz = -rotation[2], qw = rotation[3];
|
|
13955
|
+
let gone = 0;
|
|
13956
|
+
for (const decal2 of this.decals) {
|
|
13957
|
+
if (!decal2.on) continue;
|
|
13958
|
+
const vx2 = decal2.x - center[0], vy2 = decal2.y - center[1], vz2 = decal2.z - center[2];
|
|
13959
|
+
const tx = 2 * (qy * vz2 - qz * vy2), ty = 2 * (qz * vx2 - qx * vz2), tz = 2 * (qx * vy2 - qy * vx2);
|
|
13960
|
+
const lx = vx2 + qw * tx + (qy * tz - qz * ty), ly = vy2 + qw * ty + (qz * tx - qx * tz), lz = vz2 + qw * tz + (qx * ty - qy * tx);
|
|
13961
|
+
if (Math.abs(lx) > half[0] || Math.abs(ly) > half[1] || Math.abs(lz) > half[2]) continue;
|
|
13962
|
+
decal2.on = false;
|
|
13963
|
+
gone++;
|
|
13964
|
+
}
|
|
13965
|
+
return gone;
|
|
13966
|
+
}
|
|
13938
13967
|
update(dt) {
|
|
13939
13968
|
this.count = 0;
|
|
13940
13969
|
for (const decal2 of this.decals) {
|
|
@@ -17759,6 +17788,21 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
17759
17788
|
d.geometry?.dispose();
|
|
17760
17789
|
this.decalCount = Math.max(0, this.decalCount - 1);
|
|
17761
17790
|
}
|
|
17791
|
+
/**
|
|
17792
|
+
* Takes away the decals of a mesh that sit inside a box (world `center`, `half` extents along the axes of the world `rotation`): the surface they
|
|
17793
|
+
* marked is gone (a unit came out of the wall with its bullet holes and spalls).
|
|
17794
|
+
*/
|
|
17795
|
+
clearDecals(mv, center, half, rotation) {
|
|
17796
|
+
const inv = rotation.clone().invert();
|
|
17797
|
+
const p = new this.THREE.Vector3();
|
|
17798
|
+
for (let i = mv.decals.length - 1; i >= 0; i--) {
|
|
17799
|
+
const d = mv.decals[i];
|
|
17800
|
+
d.obj.getWorldPosition(p).sub(center).applyQuaternion(inv);
|
|
17801
|
+
if (Math.abs(p.x) > half.x || Math.abs(p.y) > half.y || Math.abs(p.z) > half.z) continue;
|
|
17802
|
+
this.disposeDecal(d);
|
|
17803
|
+
mv.decals.splice(i, 1);
|
|
17804
|
+
}
|
|
17805
|
+
}
|
|
17762
17806
|
addHole(mv, worldPoint, worldNormal, diameter) {
|
|
17763
17807
|
const { s, pos, quat: quat2 } = this.decalPose(mv.mesh, worldPoint, worldNormal, 25e-4);
|
|
17764
17808
|
const work = mv.host ? mv.host.work : mv.work;
|
|
@@ -18239,6 +18283,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
18239
18283
|
};
|
|
18240
18284
|
var rendererCount = 0;
|
|
18241
18285
|
var COLLAPSE_CLOUD_KG = 1e3;
|
|
18286
|
+
var CHIP_DECAL_EDGE = 0.05;
|
|
18242
18287
|
var IMPACT_TAGS = ["metal", "glass", "wood"];
|
|
18243
18288
|
var GLOW_FROM_C = 430;
|
|
18244
18289
|
var QUEUE_CAP = 4e3;
|
|
@@ -18795,7 +18840,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
18795
18840
|
break;
|
|
18796
18841
|
}
|
|
18797
18842
|
case "debris":
|
|
18798
|
-
this.vfx.burst(ev.kind, ev.point, ev.normal, ev.count, ev.speed > 0 ? ev.speed : DEFAULT_SPEED[ev.kind] ?? 1, this.debrisOptions(ev.kind, ev.object, ev.part));
|
|
18843
|
+
this.vfx.burst(ev.kind, ev.point, ev.normal, ev.count, ev.speed > 0 ? ev.speed : DEFAULT_SPEED[ev.kind] ?? 1, this.debrisOptions(ev.kind, ev.object, ev.part, ev.material));
|
|
18799
18844
|
break;
|
|
18800
18845
|
case "fracture":
|
|
18801
18846
|
this.onFracture(ev);
|
|
@@ -18968,10 +19013,11 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
18968
19013
|
}
|
|
18969
19014
|
return def ? fallbackColor(def.id, def) : null;
|
|
18970
19015
|
}
|
|
18971
|
-
debrisOptions(kind, objectId, partId) {
|
|
19016
|
+
debrisOptions(kind, objectId, partId, material) {
|
|
18972
19017
|
const pv = this.partVis(objectId, partId);
|
|
18973
|
-
const def =
|
|
19018
|
+
const def = this.world.materials.get(material ?? pv?.material ?? "");
|
|
18974
19019
|
if (kind === "smoke") return { color: SMOKE_TONES[def?.thermal.smoke ?? "grey"] };
|
|
19020
|
+
if ((kind === "dust" || kind === "chips") && def?.visual?.innerColor !== void 0) return { color: def.visual.innerColor };
|
|
18975
19021
|
if (kind === "fibers" || kind === "leaves") {
|
|
18976
19022
|
if (def?.visual?.innerColor !== void 0) return { color: def.visual.innerColor };
|
|
18977
19023
|
const c = pv ? this.visuals.baseColorHex(pv.meshes[0] ?? {}) : -1;
|
|
@@ -19079,8 +19125,11 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
19079
19125
|
const mv = this.nearestMesh(pv, wp);
|
|
19080
19126
|
if (!mv) return;
|
|
19081
19127
|
const def = this.world.materials.get(pv.material);
|
|
19082
|
-
|
|
19083
|
-
|
|
19128
|
+
const normal = this.faceNormal(mv, wp);
|
|
19129
|
+
const core = def?.visual?.innerColor;
|
|
19130
|
+
if (core !== void 0) this.vfx.burst("chips", ev.point, [normal.x, normal.y, normal.z], 5, 2.5, { color: core });
|
|
19131
|
+
else this.playEvent({ kind: "spall", material: this.impactMaterial(def) }, ev.point);
|
|
19132
|
+
this.visuals.addSpall(mv, wp, normal, Math.sqrt(ev.area / Math.PI), core ?? fallbackColor(pv.material, def));
|
|
19084
19133
|
}
|
|
19085
19134
|
/**
|
|
19086
19135
|
* Stage 2 of a staged part: the unit-sized fragments come out and the part stays drawn (hiding it is what `fracture` does). The opening itself
|
|
@@ -19103,8 +19152,9 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
19103
19152
|
this.sound(impactKey(def), ev.opening.center, 0.8);
|
|
19104
19153
|
}
|
|
19105
19154
|
/**
|
|
19106
|
-
* A unit came out of a wall of units: the unit flies as a fragment with a puff of its dust
|
|
19107
|
-
* the
|
|
19155
|
+
* A unit came out of a wall of units: the unit flies as a fragment with a puff of its dust, and the marks drawn on it (bullet holes, spalls, the impact
|
|
19156
|
+
* marks of the effects) go with it. The gap itself is the drawing's (the house renderer cuts the wall where the unit was); a part drawn as one box
|
|
19157
|
+
* keeps its box.
|
|
19108
19158
|
*/
|
|
19109
19159
|
onChip(ev) {
|
|
19110
19160
|
const pv = this.partVis(ev.object, ev.part);
|
|
@@ -19116,7 +19166,13 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
|
|
|
19116
19166
|
const tone2 = fr.inner && fdef?.visual?.innerColor !== void 0 ? fdef.visual.innerColor : fdef === def ? color : fallbackColor(fr.material, fdef);
|
|
19117
19167
|
this.fragments.spawn(fr, this.fragments.materialFor(fr.material, tone2, false), ev.object, maxAlive);
|
|
19118
19168
|
}
|
|
19119
|
-
|
|
19169
|
+
const T = this.THREE;
|
|
19170
|
+
const center = new T.Vector3(ev.center[0], ev.center[1], ev.center[2]);
|
|
19171
|
+
const half = new T.Vector3(ev.size[0] / 2 + CHIP_DECAL_EDGE, ev.size[1] / 2 + CHIP_DECAL_EDGE, ev.size[2] / 2 + CHIP_DECAL_EDGE);
|
|
19172
|
+
const rotation = new T.Quaternion(ev.rotation[0], ev.rotation[1], ev.rotation[2], ev.rotation[3]);
|
|
19173
|
+
for (const part of this.bounds.get(ev.object)?.parts.values() ?? []) for (const mv of part.meshes) this.visuals.clearDecals(mv, center, half, rotation);
|
|
19174
|
+
this.vfx.peekWorkshop()?.decals.clearInside(ev.center, [half.x, half.y, half.z], ev.rotation);
|
|
19175
|
+
this.vfx.burst("dust", ev.center, [0, 1, 0], 8, 0.8, { color });
|
|
19120
19176
|
this.sound(impactKey(def), ev.center, 0.7);
|
|
19121
19177
|
}
|
|
19122
19178
|
onFracture(ev) {
|