@adatechnology/game-floorplan-structure 2.1.4 → 2.1.5

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.
@@ -2541,6 +2541,26 @@ var GameFloorplanStructure = (() => {
2541
2541
 
2542
2542
  // ../game-contracts/dist/index.js
2543
2543
  var DEFAULT_BLAST_IMPULSE = { bodyArea: 0.7, lift: 0.15, minSpeed: 0.3, tntPerJoule: 0.24 / 2e5 };
2544
+ var NEAREST = 0.3;
2545
+ function sideOnImpulse(tnt, distance2) {
2546
+ if (!(tnt > 0)) return 0;
2547
+ const w3 = Math.cbrt(tnt);
2548
+ const z = Math.max(distance2, NEAREST) / w3;
2549
+ const scaled = 0.067 * Math.sqrt(1 + (z / 0.23) ** 4) / (z * z * Math.cbrt(1 + (z / 1.55) ** 3));
2550
+ return scaled * w3 * 100;
2551
+ }
2552
+ var ATMOSPHERE = 101325;
2553
+ function sideOnOverpressure(tnt, distance2) {
2554
+ if (!(tnt > 0)) return 0;
2555
+ const z = Math.max(distance2, NEAREST) / Math.cbrt(tnt);
2556
+ const ratio = 808 * (1 + (z / 4.5) ** 2) / (Math.sqrt(1 + (z / 0.048) ** 2) * Math.sqrt(1 + (z / 0.32) ** 2) * Math.sqrt(1 + (z / 1.35) ** 2));
2557
+ return ratio * ATMOSPHERE;
2558
+ }
2559
+ function bodyImpulse(tnt, distance2) {
2560
+ if (!(tnt > 0)) return 0;
2561
+ const z = Math.max(distance2, NEAREST) / Math.cbrt(tnt);
2562
+ return sideOnImpulse(tnt, distance2) * (2 + 4 / (1 + z * z));
2563
+ }
2544
2564
  var DEFAULT_COST_ALLOCATION_BYTES = 1024 * 1024;
2545
2565
  var DEFAULT_IGNITION_RULES = {
2546
2566
  fillCurve: [
@@ -5545,9 +5565,15 @@ var GameFloorplanStructure = (() => {
5545
5565
  var BREACH_AREA = 0.25;
5546
5566
  var BREACH_BLAST_REACH = 0.12;
5547
5567
  var MEMBER_CUT_REACH = 0.5;
5568
+ var FAR_MEMBER_HP_FLOOR = 0.25;
5548
5569
  var BLAST_REFERENCE_RESISTANCE = 200 * 1900 * 0.13;
5549
5570
  var BLAST_EDGE_RAGGED = 0.3;
5550
5571
  var BLAST_EDGE_LOOSE = 1.35;
5572
+ var PANEL_PRESSURE = 7e4;
5573
+ var PANEL_IMPULSE = 150;
5574
+ var PANEL_PI = 6e6;
5575
+ var PANEL_POINTS = [[0, 0], [-0.3, 0], [0.3, 0], [0, -0.3], [0, 0.3]];
5576
+ var PANEL_POINTS_LOADED = 4;
5551
5577
  var BLAST_EDGE_WEAR = 0.6;
5552
5578
  var RESIDUAL_CAPACITY = 0.15;
5553
5579
  var SEVER_BAND = 0.1;
@@ -7141,7 +7167,7 @@ var GameFloorplanStructure = (() => {
7141
7167
  return BREACH_BLAST_REACH * Math.cbrt(Math.max(0, energy) / 1e3) * clamp22(Math.cbrt(BLAST_REFERENCE_RESISTANCE / resistance), 0.3, 2);
7142
7168
  };
7143
7169
  const blastUnits = (o, p, wp, energy, dist, src) => {
7144
- var _a, _b;
7170
+ var _a;
7145
7171
  if (!p.staged || p.st.stripped || isLost(p) || chipEnergy <= 0) return false;
7146
7172
  const reach = blastReachOf(p, energy);
7147
7173
  if (dist >= reach) return false;
@@ -7171,6 +7197,62 @@ var GameFloorplanStructure = (() => {
7171
7197
  }
7172
7198
  }
7173
7199
  if (out.length === 0) return false;
7200
+ return knockOutUnits(o, p, wp, energy, out, src);
7201
+ };
7202
+ const blastPanel = (o, p, point, energy, src) => {
7203
+ var _a;
7204
+ if (!p.staged || p.st.stripped || isLost(p) || !p.spec.units || p.spec.units.mortar === p.spec.material || p.spec.reinforcement) return false;
7205
+ const [u, v] = planeAxes(p.thin);
7206
+ const lp = toLocal(p.pos, p.q, objLocal(o, point));
7207
+ const half = p.dims[u] / 2;
7208
+ const posts = [];
7209
+ for (const m of o.parts) {
7210
+ if (m === p || !m.spec.reinforcement || isLost(m) || m.spec.shape.kind !== "box") continue;
7211
+ const mp = toLocal(p.pos, p.q, m.pos);
7212
+ if (Math.abs(mp[p.thin]) > p.dims[p.thin] + 0.15 || Math.abs(mp[u]) > half + 0.15 || m.dims[v] < p.dims[v] * 0.5) continue;
7213
+ posts.push(mp[u]);
7214
+ }
7215
+ let from = -half, to = half;
7216
+ for (const x of posts) {
7217
+ if (x <= lp[u] && x > from) from = x;
7218
+ if (x >= lp[u] && x < to) to = x;
7219
+ }
7220
+ if (to - from < 0.2) return false;
7221
+ const tnt = energy * DEFAULT_BLAST_IMPULSE.tntPerJoule;
7222
+ const centre2 = objLocal(o, point);
7223
+ const span = to - from, height = p.dims[v];
7224
+ let loaded = 0;
7225
+ for (const [fu, fv] of PANEL_POINTS) {
7226
+ const at2 = [0, 0, 0];
7227
+ at2[u] = (from + to) / 2 + fu * span;
7228
+ at2[v] = fv * height;
7229
+ at2[p.thin] = Math.sign(lp[p.thin]) * p.dims[p.thin] / 2;
7230
+ const r = vec.distance(toWorld(p.pos, p.q, at2), centre2);
7231
+ const side = sideOnOverpressure(tnt, r);
7232
+ const reflected = 2 * side + 6 * side * side / (side + 7 * 101325);
7233
+ const impulse = bodyImpulse(tnt, r);
7234
+ if (reflected > PANEL_PRESSURE && impulse > PANEL_IMPULSE && (reflected - PANEL_PRESSURE) * (impulse - PANEL_IMPULSE) >= PANEL_PI) loaded++;
7235
+ }
7236
+ if (loaded < PANEL_POINTS_LOADED) return false;
7237
+ const grid = gridOf(p);
7238
+ const worn = (_a = p.rt).chips ?? (_a.chips = {});
7239
+ const out = [];
7240
+ for (let i = 0; i < grid.length; i++) {
7241
+ const cell = grid[i];
7242
+ if (worn[i] === -1) continue;
7243
+ if (cell.center[u] - cell.size[u] / 2 >= from - 1e-6 && cell.center[u] + cell.size[u] / 2 <= to + 1e-6) out.push(i);
7244
+ }
7245
+ if (out.length === 0) return false;
7246
+ for (const i of out) worn[i] = -1;
7247
+ return knockOutUnits(o, p, point, energy, out, src);
7248
+ };
7249
+ const knockOutUnits = (o, p, wp, energy, out, src) => {
7250
+ var _a, _b;
7251
+ const [u, v] = planeAxes(p.thin);
7252
+ const op = p.st.opening ? toLocal(p.pos, p.q, p.st.opening.center) : null;
7253
+ const grid = gridOf(p);
7254
+ const worn = (_a = p.rt).chips ?? (_a.chips = {});
7255
+ for (const i of out) worn[i] = -1;
7174
7256
  const loose = unsupportedCells(grid, p.thin, p.dims, (i) => worn[i] !== -1 && !(op && p.st.opening && Math.hypot(grid[i].center[u] - op[u], grid[i].center[v] - op[v]) <= p.st.opening.radius));
7175
7257
  for (const i of loose) worn[i] = -1;
7176
7258
  const blown = out.map((i) => grid[i]), fallen = loose.map((i) => grid[i]);
@@ -7653,12 +7735,15 @@ var GameFloorplanStructure = (() => {
7653
7735
  return reach;
7654
7736
  }
7655
7737
  if (Ein > 20 && p.layers.length > 0) spallOuter(o, p, wp, faceOf(o, p, wn), wn, clamp22(0.05 + Math.sqrt(Ein) * 2e-3, 0.05, 0.4), src);
7656
- const dealt = applyDamage(o, p, amount, "explosive", point, null, Ein * 0.3, 40, src);
7738
+ const breachReach = BREACH_BLAST_REACH * Math.cbrt(Math.max(0, energy) / 1e3);
7739
+ const farMember = Boolean(p.spec.reinforcement && p.spec.units) && dist > MEMBER_CUT_REACH * breachReach;
7740
+ const dealt = farMember ? applyDamage(o, p, Math.min(amount, Math.max(0, p.st.hp - p.st.maxHp * FAR_MEMBER_HP_FLOOR)), "explosive", null, null, Ein * 0.3, 40, src) : applyDamage(o, p, amount, "explosive", point, null, Ein * 0.3, 40, src);
7657
7741
  res.damage += dealt;
7658
7742
  if (p.bend && flexure.enabled) bendByBlast(o, p, point, energy, radius, reach, src);
7659
- const breachReach = BREACH_BLAST_REACH * Math.cbrt(Math.max(0, energy) / 1e3);
7660
- if (p.spec.units && p.spec.units.mortar !== p.spec.material) blastUnits(o, p, wp, energy, dist, src);
7661
- else if (p.spec.reinforcement && p.spec.units && dist > MEMBER_CUT_REACH * breachReach) blastUnits(o, p, wp, energy, dist, src);
7743
+ if (p.spec.units && p.spec.units.mortar !== p.spec.material) {
7744
+ blastPanel(o, p, point, energy, src);
7745
+ if (!isLost(p)) blastUnits(o, p, wp, energy, dist, src);
7746
+ } else if (farMember) blastUnits(o, p, wp, energy, dist, src);
7662
7747
  else if (dist <= breachReach) addBreach(o, p, wp, breachAreaOf(p, dealt, true), Ein, null, src);
7663
7748
  return reach;
7664
7749
  };