@adatechnology/game-contracts 0.23.0 → 0.25.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
@@ -1,5 +1,6 @@
1
1
  // src/blast-shove.ts
2
2
  var DEFAULT_BLAST_SHOVE = { coupling: 0.02, maxSpeed: 20, lift: 0.3, minSpeed: 0.3, falloffPower: 2 };
3
+ var clampShare = (share) => Math.min(1, Math.max(0, share));
3
4
  function blastShove(blast, target, options = {}) {
4
5
  const o = { ...DEFAULT_BLAST_SHOVE, ...options };
5
6
  const dx = target.position[0] - blast.point[0];
@@ -9,17 +10,41 @@ function blastShove(blast, target, options = {}) {
9
10
  if (!(blast.radius > 0) || distance > blast.radius) return void 0;
10
11
  const falloff = (1 - distance / blast.radius) ** o.falloffPower;
11
12
  const mass = Math.max(target.mass, 0.05);
12
- const speed = Math.min(o.maxSpeed, Math.sqrt(2 * blast.energy * (blast.reach ?? 1) * o.coupling / mass)) * falloff;
13
+ const reach = clampShare(blast.reach ?? 1);
14
+ const speed = Math.sqrt(reach) * Math.min(o.maxSpeed, Math.sqrt(2 * blast.energy * o.coupling / mass)) * falloff;
13
15
  if (!(speed >= o.minSpeed)) return void 0;
14
16
  const direction = distance > 1e-4 ? [dx / distance, dy / distance + o.lift, dz / distance] : [0, 1, 0];
15
17
  const length = Math.hypot(direction[0], direction[1], direction[2]);
16
18
  return { speed, direction: [direction[0] / length, direction[1] / length, direction[2] / length], distance, falloff };
17
19
  }
18
20
 
21
+ // src/blast-impulse.ts
22
+ var DEFAULT_BLAST_IMPULSE = { bodyArea: 0.7, lift: 0.15, minSpeed: 0.3, tntPerJoule: 0.24 / 2e5 };
23
+ var NEAREST = 0.3;
24
+ function sideOnImpulse(tnt, distance) {
25
+ if (!(tnt > 0)) return 0;
26
+ const w3 = Math.cbrt(tnt);
27
+ const z = Math.max(distance, NEAREST) / w3;
28
+ const scaled = 0.067 * Math.sqrt(1 + (z / 0.23) ** 4) / (z * z * Math.cbrt(1 + (z / 1.55) ** 3));
29
+ return scaled * w3 * 100;
30
+ }
31
+ function bodyImpulse(tnt, distance) {
32
+ if (!(tnt > 0)) return 0;
33
+ const z = Math.max(distance, NEAREST) / Math.cbrt(tnt);
34
+ return sideOnImpulse(tnt, distance) * (2 + 4 / (1 + z * z));
35
+ }
36
+ function blastBodySpeed(tnt, distance, mass, reach = 1, options = {}) {
37
+ const area = options.bodyArea ?? DEFAULT_BLAST_IMPULSE.bodyArea;
38
+ return bodyImpulse(tnt, distance) * area * Math.max(0, reach) / Math.max(mass, 1);
39
+ }
40
+
19
41
  // src/blast-knock.ts
20
42
  var KNOCK_DOWN_SPEED = 2.5;
21
43
  var KNOCKED_DOWN_ANGLE = 1.35;
22
44
  var LIE_SECONDS = 1.6;
45
+ var WOUNDED_LIE_SECONDS = 6;
46
+ var FRAGMENT_COVER = 0.5;
47
+ var STUN_SECONDS = 4;
23
48
  var STAND_UP_PER_SPEED = 0.25;
24
49
  var FALL_SECONDS = 0.25;
25
50
  var RISE_SECONDS = 0.6;
@@ -28,11 +53,38 @@ var GRAVITY = 9.81;
28
53
  var KNOCK_CHEST = 1.1;
29
54
  var CHEST = KNOCK_CHEST;
30
55
  var bodyMass = (height, build = 1) => 70 * (height / 1.75) ** 2 * build;
31
- function knockOf(blast, feet, mass, options) {
32
- const hit = blastShove(blast, { position: [feet[0], feet[1] + CHEST, feet[2]], mass }, options);
33
- if (!hit) return void 0;
34
- const [dx, dy, dz] = hit.direction;
35
- 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 };
56
+ function knockOf(blast, feet, mass, options, impulse = {}) {
57
+ const o = { ...DEFAULT_BLAST_IMPULSE, ...impulse };
58
+ const chest = [feet[0], feet[1] + CHEST, feet[2]];
59
+ const dx = chest[0] - blast.point[0];
60
+ const dy = chest[1] - blast.point[1];
61
+ const dz = chest[2] - blast.point[2];
62
+ const distance = Math.hypot(dx, dy, dz);
63
+ if (!(blast.radius > 0) || distance > blast.radius) return void 0;
64
+ const reach = Math.max(0, Math.min(1, blast.reach ?? 1));
65
+ const tnt = blast.tnt ?? blast.energy * o.tntPerJoule;
66
+ let speed = blastBodySpeed(tnt, distance, mass, reach, o);
67
+ const minSpeed = impulse.minSpeed ?? options?.minSpeed ?? o.minSpeed;
68
+ if (speed < minSpeed) speed = 0;
69
+ const struck = reach >= FRAGMENT_COVER;
70
+ const wounded = struck && blast.lethalRadius !== void 0 && distance <= blast.lethalRadius;
71
+ const edge = 1 - distance / blast.radius;
72
+ const stunSeconds = struck ? STUN_SECONDS * edge * edge * reach : 0;
73
+ if (speed === 0 && !wounded && stunSeconds < 0.25) return void 0;
74
+ const horizontal = Math.hypot(dx, dz);
75
+ const away = horizontal > 1e-4 ? [dx / horizontal, o.lift, dz / horizontal] : [0, 1, 0];
76
+ const length = Math.hypot(away[0], away[1], away[2]);
77
+ const velocity = [away[0] / length * speed, away[1] / length * speed, away[2] / length * speed];
78
+ return {
79
+ velocity,
80
+ airborne: velocity[1] > 0.5,
81
+ lying: 0,
82
+ lieLeft: wounded ? WOUNDED_LIE_SECONDS : 0,
83
+ away: horizontal > 1e-4 ? [dx / horizontal, 0, dz / horizontal] : [0, 0, 0],
84
+ down: speed >= KNOCK_DOWN_SPEED || wounded,
85
+ ...wounded ? { wounded } : {},
86
+ ...stunSeconds >= 0.25 ? { stunSeconds } : {}
87
+ };
36
88
  }
37
89
  function stepKnock(knock, position, dt, groundAt, alive) {
38
90
  const v = knock.velocity;
@@ -56,18 +108,25 @@ function stepKnock(knock, position, dt, groundAt, alive) {
56
108
  }
57
109
  const moving = horizontal > 0.05 || knock.airborne;
58
110
  if (knock.down) {
59
- if (moving) knock.lying = Math.min(1, knock.lying + dt / FALL_SECONDS);
60
- else {
61
- knock.lying = 1;
62
- if (alive) {
63
- knock.lieLeft = knock.lieLeft > 0 ? knock.lieLeft : LIE_SECONDS + Math.hypot(v[0], v[2]) * STAND_UP_PER_SPEED;
64
- knock.lieLeft -= dt;
65
- if (knock.lieLeft <= 0) knock.down = false;
66
- }
111
+ if (moving || knock.lying < 1) knock.lying = Math.min(1, knock.lying + dt / FALL_SECONDS);
112
+ else if (alive) {
113
+ knock.lieLeft = knock.lieLeft > 0 ? knock.lieLeft : LIE_SECONDS + Math.hypot(v[0], v[2]) * STAND_UP_PER_SPEED;
114
+ knock.lieLeft -= dt;
115
+ if (knock.lieLeft <= 0) knock.down = false;
67
116
  }
68
117
  } else if (knock.lying > 0) knock.lying = Math.max(0, knock.lying - dt / RISE_SECONDS);
69
118
  return !moving && !knock.down && knock.lying === 0;
70
119
  }
120
+ var LAUNCHED = "launched";
121
+ function launchBody(root, velocity) {
122
+ root.userData[LAUNCHED] = [velocity[0], velocity[1], velocity[2]];
123
+ }
124
+ function takeLaunch(root) {
125
+ const velocity = root.userData[LAUNCHED];
126
+ if (!velocity) return void 0;
127
+ delete root.userData[LAUNCHED];
128
+ return { velocity: [velocity[0], velocity[1], velocity[2]], airborne: true, lying: 0, lieLeft: 0, down: true };
129
+ }
71
130
 
72
131
  // src/impact-cost.ts
73
132
  var DEFAULT_COST_READS = 1e4;
@@ -1092,6 +1151,8 @@ var MATERIAL_SURFACES = {
1092
1151
  mortar: "concrete",
1093
1152
  stone: "concrete",
1094
1153
  brick: "concrete",
1154
+ cobble: "concrete",
1155
+ paver: "concrete",
1095
1156
  plaster: "concrete",
1096
1157
  asphalt: "asphalt",
1097
1158
  wood_soft: "wood",
@@ -1102,6 +1163,8 @@ var MATERIAL_SURFACES = {
1102
1163
  ceramic: "tile",
1103
1164
  plastic: "tile",
1104
1165
  soil: "dirt",
1166
+ mud: "dirt",
1167
+ clay: "dirt",
1105
1168
  wax: "dirt",
1106
1169
  flesh_fruit: "dirt",
1107
1170
  turf: "grass",
@@ -1109,6 +1172,8 @@ var MATERIAL_SURFACES = {
1109
1172
  cactus: "grass",
1110
1173
  gravel: "gravel",
1111
1174
  sand: "sand",
1175
+ // no snow surface yet: packed snow crunches closest to sand underfoot
1176
+ snow: "sand",
1112
1177
  steel: "metal",
1113
1178
  cast_iron: "metal",
1114
1179
  aluminium: "metal",
@@ -1135,6 +1200,7 @@ export {
1135
1200
  BLOW_IDS,
1136
1201
  BODY_FOLEY_IDS,
1137
1202
  BODY_SOUND_IDS,
1203
+ DEFAULT_BLAST_IMPULSE,
1138
1204
  DEFAULT_BLAST_SHOVE,
1139
1205
  DEFAULT_ENVIRONMENT,
1140
1206
  DEFAULT_IGNITION_RULES,
@@ -1142,6 +1208,7 @@ export {
1142
1208
  DEFERRED_PRIORITY,
1143
1209
  DEFERRED_QUEUE_ID,
1144
1210
  FOOTSTEP_SOUND_IDS,
1211
+ FRAGMENT_COVER,
1145
1212
  FRAME_PHASES,
1146
1213
  GAIT_IDS,
1147
1214
  HEAVY_LANDING_SPEED,
@@ -1160,7 +1227,9 @@ export {
1160
1227
  TOOL_CLIP,
1161
1228
  TWIST_LIFT,
1162
1229
  applyPatches,
1230
+ blastBodySpeed,
1163
1231
  blastShove,
1232
+ bodyImpulse,
1164
1233
  bodyMass,
1165
1234
  checkAnimation,
1166
1235
  checkBench,
@@ -1183,6 +1252,7 @@ export {
1183
1252
  kitOriginOf,
1184
1253
  knockOf,
1185
1254
  landSoundId,
1255
+ launchBody,
1186
1256
  leadClipEvents,
1187
1257
  markKitOrigin,
1188
1258
  mergeById,
@@ -1196,10 +1266,12 @@ export {
1196
1266
  sealOpener,
1197
1267
  shotExtras,
1198
1268
  shotToHit,
1269
+ sideOnImpulse,
1199
1270
  sparkTargetFactor,
1200
1271
  stepKnock,
1201
1272
  surfaceOfMaterial,
1202
1273
  swingSoundId,
1274
+ takeLaunch,
1203
1275
  toolAnimationStep,
1204
1276
  twistStroke,
1205
1277
  unmarkedDrawings,