@adatechnology/game-destruction 0.2.0 → 0.3.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/dist/index.js CHANGED
@@ -1413,6 +1413,7 @@ var cutFactorOf = (shape) => clamp2(Math.max(...shapeDims(shape)) / CUT_SLICE, 1
1413
1413
  var clamp2 = (v, a, b) => Math.max(a, Math.min(b, v));
1414
1414
  var isLost = (p) => p.st.status === "broken" || p.st.status === "melted" || p.st.status === "ashes";
1415
1415
  var clone = (v) => structuredClone(v);
1416
+ var overloadRate = (stress) => Math.min(0.6, 0.12 + 0.8 * (stress - 1));
1416
1417
  var updateBound = (o) => {
1417
1418
  if (!o.parts.length) return;
1418
1419
  const c = [0, 0, 0];
@@ -1723,7 +1724,10 @@ var createDestruction = (options = {}) => {
1723
1724
  for (const g of o.st.groups) {
1724
1725
  const ps = g.map((id) => o.byId.get(id)).filter((p) => !isLost(p) && !o.collapsed.has(p.spec.id));
1725
1726
  if (ps.length === 0 || g.some((id) => o.byId.get(id).anchored) || !ps.some((p) => p.structural)) continue;
1726
- for (const p of ps) o.collapsed.add(p.spec.id);
1727
+ for (const p of ps) {
1728
+ o.collapsed.add(p.spec.id);
1729
+ p.st.status = "collapsed";
1730
+ }
1727
1731
  emit({ ...base(o, src), type: "collapse", parts: ps.map((p) => p.spec.id), mass: ps.reduce((sum, p) => sum + p.st.mass, 0) });
1728
1732
  }
1729
1733
  }
@@ -2023,7 +2027,7 @@ var createDestruction = (options = {}) => {
2023
2027
  const effM = p.thickness / Math.max(sin, 0.3);
2024
2028
  const thr = mat.penetration * effM * 1e3;
2025
2029
  const penetrated = E > thr;
2026
- const scale = mat.damageScale?.ballistic ?? 1;
2030
+ const scale = (mat.damageScale?.ballistic ?? 1) * (mat.fracture === "shatter" ? fragility(mat.ductility, p.thickness) : 1);
2027
2031
  const id = p.spec.id;
2028
2032
  if (!penetrated && mat.ricochetDeg && angle < mat.ricochetDeg) {
2029
2033
  const r = vec.sub(d, vec.scale(n, 2 * vec.dot(d, n)));
@@ -2373,7 +2377,7 @@ var createDestruction = (options = {}) => {
2373
2377
  p.rt.stressT = 0.5;
2374
2378
  emit({ ...base(o), type: "stress", part: p.spec.id, stress, load: p.st.load ?? 0 });
2375
2379
  }
2376
- applyDamage(o, p, (stress - 1) * p.st.maxHp * 0.5 * dt, "blunt", null, null, 5, 3);
2380
+ applyDamage(o, p, overloadRate(stress) * p.st.maxHp * dt, "blunt", null, null, 5, 3);
2377
2381
  } else if (stress > 0.8 && p.mat.ductility < 0.3 && p.rt.stressT <= 0 && p.st.cracks.length < 6) {
2378
2382
  p.rt.stressT = 0.5;
2379
2383
  const { c, q } = partXf(o, p);
@@ -2835,6 +2839,47 @@ var buildFrame = (o = {}) => {
2835
2839
  return { name: "frame", parts, joints, tags: ["structure"] };
2836
2840
  };
2837
2841
 
2842
+ // src/size.ts
2843
+ var sizeStructure = (spec, options = {}) => {
2844
+ const safety = options.safety ?? 0.65;
2845
+ const redundancy = options.redundancy;
2846
+ const loads = (s) => {
2847
+ const w = createDestruction(options.materials ? { materials: options.materials } : {});
2848
+ const id = w.add(s);
2849
+ return new Map(w.state(id).parts.map((p) => [p.id, { load: p.load ?? 0, stress: p.stress ?? 0 }]));
2850
+ };
2851
+ const out = structuredClone(spec);
2852
+ const base = loads(out);
2853
+ const need = /* @__PURE__ */ new Map();
2854
+ for (const p of out.parts) {
2855
+ if (!p.structure || p.structure.role === "none") continue;
2856
+ const b = base.get(p.id);
2857
+ if (!b || b.stress <= 0) continue;
2858
+ need.set(p.id, b.load / safety);
2859
+ }
2860
+ if (redundancy !== void 0) {
2861
+ for (const col of out.parts) {
2862
+ if (col.structure?.role !== "column") continue;
2863
+ const reduced = {
2864
+ ...out,
2865
+ parts: out.parts.filter((p) => p.id !== col.id),
2866
+ joints: (out.joints ?? []).filter((j) => j.a !== col.id && j.b !== col.id)
2867
+ };
2868
+ if (!out.joints) delete reduced.joints;
2869
+ const l = loads(reduced);
2870
+ for (const [id, n] of need) {
2871
+ const r = l.get(id);
2872
+ if (r && r.stress > 0) need.set(id, Math.max(n, r.load / redundancy));
2873
+ }
2874
+ }
2875
+ }
2876
+ for (const p of out.parts) {
2877
+ const n = need.get(p.id);
2878
+ if (n !== void 0) p.structure = { ...p.structure, capacity: n };
2879
+ }
2880
+ return out;
2881
+ };
2882
+
2838
2883
  // src/locale.ts
2839
2884
  var locales = {
2840
2885
  en: {
@@ -2867,7 +2912,7 @@ var locales = {
2867
2912
  wax: "wax",
2868
2913
  soil: "soil"
2869
2914
  },
2870
- partStatus: { intact: "intact", damaged: "damaged", broken: "broken", melted: "melted", ashes: "ashes" },
2915
+ partStatus: { intact: "intact", damaged: "damaged", collapsed: "collapsed", broken: "broken", melted: "melted", ashes: "ashes" },
2871
2916
  jointKinds: {
2872
2917
  screw: "screw",
2873
2918
  bolt: "nut and bolt",
@@ -2948,7 +2993,7 @@ var locales = {
2948
2993
  wax: "cera",
2949
2994
  soil: "terra"
2950
2995
  },
2951
- partStatus: { intact: "intacto", damaged: "danificado", broken: "quebrado", melted: "derretido", ashes: "cinzas" },
2996
+ partStatus: { intact: "intacto", damaged: "danificado", collapsed: "desabado", broken: "quebrado", melted: "derretido", ashes: "cinzas" },
2952
2997
  jointKinds: {
2953
2998
  screw: "parafuso",
2954
2999
  bolt: "porca e parafuso",
@@ -3030,6 +3075,7 @@ export {
3030
3075
  quatFromEuler,
3031
3076
  resolveStrings,
3032
3077
  rotateVec,
3078
+ sizeStructure,
3033
3079
  toLocal,
3034
3080
  toWorld,
3035
3081
  vec