@adatechnology/game-characters-three 0.9.1 → 0.9.2

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.
@@ -1586,25 +1586,30 @@ var GameCharactersThree = (() => {
1586
1586
  };
1587
1587
 
1588
1588
  // ../game-contracts/dist/index.js
1589
- var DEFAULT_BLAST_SHOVE = { coupling: 0.02, maxSpeed: 20, lift: 0.3, minSpeed: 0.3, falloffPower: 2 };
1590
- function blastShove(blast2, target, options = {}) {
1591
- const o = { ...DEFAULT_BLAST_SHOVE, ...options };
1592
- const dx = target.position[0] - blast2.point[0];
1593
- const dy = target.position[1] - blast2.point[1];
1594
- const dz = target.position[2] - blast2.point[2];
1595
- const distance3 = Math.hypot(dx, dy, dz);
1596
- if (!(blast2.radius > 0) || distance3 > blast2.radius) return void 0;
1597
- const falloff = (1 - distance3 / blast2.radius) ** o.falloffPower;
1598
- const mass = Math.max(target.mass, 0.05);
1599
- const speed = Math.min(o.maxSpeed, Math.sqrt(2 * blast2.energy * (blast2.reach ?? 1) * o.coupling / mass)) * falloff;
1600
- if (!(speed >= o.minSpeed)) return void 0;
1601
- const direction = distance3 > 1e-4 ? [dx / distance3, dy / distance3 + o.lift, dz / distance3] : [0, 1, 0];
1602
- const length = Math.hypot(direction[0], direction[1], direction[2]);
1603
- return { speed, direction: [direction[0] / length, direction[1] / length, direction[2] / length], distance: distance3, falloff };
1589
+ var DEFAULT_BLAST_IMPULSE = { bodyArea: 0.7, lift: 0.15, minSpeed: 0.3, tntPerJoule: 0.24 / 2e5 };
1590
+ var NEAREST = 0.3;
1591
+ function sideOnImpulse(tnt, distance3) {
1592
+ if (!(tnt > 0)) return 0;
1593
+ const w3 = Math.cbrt(tnt);
1594
+ const z = Math.max(distance3, NEAREST) / w3;
1595
+ const scaled = 0.067 * Math.sqrt(1 + (z / 0.23) ** 4) / (z * z * Math.cbrt(1 + (z / 1.55) ** 3));
1596
+ return scaled * w3 * 100;
1597
+ }
1598
+ function bodyImpulse(tnt, distance3) {
1599
+ if (!(tnt > 0)) return 0;
1600
+ const z = Math.max(distance3, NEAREST) / Math.cbrt(tnt);
1601
+ return sideOnImpulse(tnt, distance3) * (2 + 4 / (1 + z * z));
1602
+ }
1603
+ function blastBodySpeed(tnt, distance3, mass, reach = 1, options = {}) {
1604
+ const area3 = options.bodyArea ?? DEFAULT_BLAST_IMPULSE.bodyArea;
1605
+ return bodyImpulse(tnt, distance3) * area3 * Math.max(0, reach) / Math.max(mass, 1);
1604
1606
  }
1605
1607
  var KNOCK_DOWN_SPEED = 2.5;
1606
1608
  var KNOCKED_DOWN_ANGLE = 1.35;
1607
1609
  var LIE_SECONDS = 1.6;
1610
+ var WOUNDED_LIE_SECONDS = 6;
1611
+ var FRAGMENT_COVER = 0.5;
1612
+ var STUN_SECONDS = 4;
1608
1613
  var STAND_UP_PER_SPEED = 0.25;
1609
1614
  var FALL_SECONDS = 0.25;
1610
1615
  var RISE_SECONDS = 0.6;
@@ -1613,11 +1618,38 @@ var GameCharactersThree = (() => {
1613
1618
  var KNOCK_CHEST = 1.1;
1614
1619
  var CHEST = KNOCK_CHEST;
1615
1620
  var bodyMass = (height, build = 1) => 70 * (height / 1.75) ** 2 * build;
1616
- function knockOf(blast2, feet, mass, options) {
1617
- const hit = blastShove(blast2, { position: [feet[0], feet[1] + CHEST, feet[2]], mass }, options);
1618
- if (!hit) return void 0;
1619
- const [dx, dy, dz] = hit.direction;
1620
- return { velocity: [dx * hit.speed, Math.max(0, dy * hit.speed), dz * hit.speed], airborne: dy > 0, lying: 0, lieLeft: 0, down: hit.speed >= KNOCK_DOWN_SPEED };
1621
+ function knockOf(blast2, feet, mass, options, impulse = {}) {
1622
+ const o = { ...DEFAULT_BLAST_IMPULSE, ...impulse };
1623
+ const chest = [feet[0], feet[1] + CHEST, feet[2]];
1624
+ const dx = chest[0] - blast2.point[0];
1625
+ const dy = chest[1] - blast2.point[1];
1626
+ const dz = chest[2] - blast2.point[2];
1627
+ const distance3 = Math.hypot(dx, dy, dz);
1628
+ if (!(blast2.radius > 0) || distance3 > blast2.radius) return void 0;
1629
+ const reach = Math.max(0, Math.min(1, blast2.reach ?? 1));
1630
+ const tnt = blast2.tnt ?? blast2.energy * o.tntPerJoule;
1631
+ let speed = blastBodySpeed(tnt, distance3, mass, reach, o);
1632
+ const minSpeed = impulse.minSpeed ?? options?.minSpeed ?? o.minSpeed;
1633
+ if (speed < minSpeed) speed = 0;
1634
+ const struck = reach >= FRAGMENT_COVER;
1635
+ const wounded = struck && blast2.lethalRadius !== void 0 && distance3 <= blast2.lethalRadius;
1636
+ const edge = 1 - distance3 / blast2.radius;
1637
+ const stunSeconds = struck ? STUN_SECONDS * edge * edge * reach : 0;
1638
+ if (speed === 0 && !wounded && stunSeconds < 0.25) return void 0;
1639
+ const horizontal = Math.hypot(dx, dz);
1640
+ const away = horizontal > 1e-4 ? [dx / horizontal, o.lift, dz / horizontal] : [0, 1, 0];
1641
+ const length = Math.hypot(away[0], away[1], away[2]);
1642
+ const velocity = [away[0] / length * speed, away[1] / length * speed, away[2] / length * speed];
1643
+ return {
1644
+ velocity,
1645
+ airborne: velocity[1] > 0.5,
1646
+ lying: 0,
1647
+ lieLeft: wounded ? WOUNDED_LIE_SECONDS : 0,
1648
+ away: horizontal > 1e-4 ? [dx / horizontal, 0, dz / horizontal] : [0, 0, 0],
1649
+ down: speed >= KNOCK_DOWN_SPEED || wounded,
1650
+ ...wounded ? { wounded } : {},
1651
+ ...stunSeconds >= 0.25 ? { stunSeconds } : {}
1652
+ };
1621
1653
  }
1622
1654
  function stepKnock(knock2, position, dt, groundAt, alive) {
1623
1655
  const v = knock2.velocity;
@@ -1641,14 +1673,11 @@ var GameCharactersThree = (() => {
1641
1673
  }
1642
1674
  const moving = horizontal > 0.05 || knock2.airborne;
1643
1675
  if (knock2.down) {
1644
- if (moving) knock2.lying = Math.min(1, knock2.lying + dt / FALL_SECONDS);
1645
- else {
1646
- knock2.lying = 1;
1647
- if (alive) {
1648
- knock2.lieLeft = knock2.lieLeft > 0 ? knock2.lieLeft : LIE_SECONDS + Math.hypot(v[0], v[2]) * STAND_UP_PER_SPEED;
1649
- knock2.lieLeft -= dt;
1650
- if (knock2.lieLeft <= 0) knock2.down = false;
1651
- }
1676
+ if (moving || knock2.lying < 1) knock2.lying = Math.min(1, knock2.lying + dt / FALL_SECONDS);
1677
+ else if (alive) {
1678
+ knock2.lieLeft = knock2.lieLeft > 0 ? knock2.lieLeft : LIE_SECONDS + Math.hypot(v[0], v[2]) * STAND_UP_PER_SPEED;
1679
+ knock2.lieLeft -= dt;
1680
+ if (knock2.lieLeft <= 0) knock2.down = false;
1652
1681
  }
1653
1682
  } else if (knock2.lying > 0) knock2.lying = Math.max(0, knock2.lying - dt / RISE_SECONDS);
1654
1683
  return !moving && !knock2.down && knock2.lying === 0;