quake2ts 0.0.219 → 0.0.220
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/package.json +1 -1
- package/packages/client/dist/browser/index.global.js +13 -13
- package/packages/client/dist/browser/index.global.js.map +1 -1
- package/packages/client/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/game/dist/browser/index.global.js +2 -2
- package/packages/game/dist/browser/index.global.js.map +1 -1
- package/packages/game/dist/cjs/index.cjs +164 -32
- package/packages/game/dist/cjs/index.cjs.map +1 -1
- package/packages/game/dist/esm/index.js +163 -32
- package/packages/game/dist/esm/index.js.map +1 -1
- package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/game/dist/types/ai/constants.d.ts +8 -0
- package/packages/game/dist/types/ai/constants.d.ts.map +1 -1
- package/packages/game/dist/types/ai/movement.d.ts.map +1 -1
- package/packages/game/dist/types/entities/entity.d.ts +1 -0
- package/packages/game/dist/types/entities/entity.d.ts.map +1 -1
- package/packages/game/dist/types/entities/monsters/tank.d.ts.map +1 -1
|
@@ -27,6 +27,7 @@ __export(index_exports, {
|
|
|
27
27
|
AmmoItemId: () => AmmoItemId,
|
|
28
28
|
AmmoType: () => AmmoType,
|
|
29
29
|
ArmorType: () => ArmorType,
|
|
30
|
+
AttackState: () => AttackState,
|
|
30
31
|
CheckGround: () => CheckGround,
|
|
31
32
|
DamageFlags: () => DamageFlags,
|
|
32
33
|
DamageMod: () => DamageMod,
|
|
@@ -2111,9 +2112,18 @@ var AIFlags = /* @__PURE__ */ ((AIFlags2) => {
|
|
|
2111
2112
|
AIFlags2[AIFlags2["CombatPoint"] = 4096] = "CombatPoint";
|
|
2112
2113
|
AIFlags2[AIFlags2["Medic"] = 8192] = "Medic";
|
|
2113
2114
|
AIFlags2[AIFlags2["Resurrecting"] = 16384] = "Resurrecting";
|
|
2115
|
+
AIFlags2[AIFlags2["ManualSteering"] = 32768] = "ManualSteering";
|
|
2114
2116
|
AIFlags2[AIFlags2["Pathing"] = 1073741824] = "Pathing";
|
|
2115
2117
|
return AIFlags2;
|
|
2116
2118
|
})(AIFlags || {});
|
|
2119
|
+
var AttackState = /* @__PURE__ */ ((AttackState2) => {
|
|
2120
|
+
AttackState2[AttackState2["Straight"] = 0] = "Straight";
|
|
2121
|
+
AttackState2[AttackState2["Sliding"] = 1] = "Sliding";
|
|
2122
|
+
AttackState2[AttackState2["Melee"] = 2] = "Melee";
|
|
2123
|
+
AttackState2[AttackState2["Missile"] = 3] = "Missile";
|
|
2124
|
+
AttackState2[AttackState2["Blind"] = 4] = "Blind";
|
|
2125
|
+
return AttackState2;
|
|
2126
|
+
})(AttackState || {});
|
|
2117
2127
|
var TraceMask = /* @__PURE__ */ ((TraceMask2) => {
|
|
2118
2128
|
TraceMask2[TraceMask2["Opaque"] = 1] = "Opaque";
|
|
2119
2129
|
TraceMask2[TraceMask2["Window"] = 2] = "Window";
|
|
@@ -2407,7 +2417,9 @@ function ai_turn(self, distance2, deltaSeconds) {
|
|
|
2407
2417
|
if (distance2 !== 0) {
|
|
2408
2418
|
walkMove(self, self.angles.y, distance2);
|
|
2409
2419
|
}
|
|
2410
|
-
|
|
2420
|
+
if ((self.monsterinfo.aiflags & 32768 /* ManualSteering */) === 0) {
|
|
2421
|
+
changeYaw(self, deltaSeconds);
|
|
2422
|
+
}
|
|
2411
2423
|
}
|
|
2412
2424
|
function ai_run(self, distance2, deltaSeconds, context) {
|
|
2413
2425
|
if ((self.monsterinfo.aiflags & 1 /* StandGround */) !== 0) {
|
|
@@ -2416,7 +2428,9 @@ function ai_run(self, distance2, deltaSeconds, context) {
|
|
|
2416
2428
|
}
|
|
2417
2429
|
if (findTarget(self, context.targetAwareness, context, context.trace)) {
|
|
2418
2430
|
}
|
|
2419
|
-
|
|
2431
|
+
if ((self.monsterinfo.aiflags & 32768 /* ManualSteering */) === 0) {
|
|
2432
|
+
setIdealYawTowards2(self, self.enemy ?? self.goalentity);
|
|
2433
|
+
}
|
|
2420
2434
|
changeYaw(self, deltaSeconds);
|
|
2421
2435
|
if (self.monsterinfo.checkattack && self.monsterinfo.checkattack(self, context)) {
|
|
2422
2436
|
return;
|
|
@@ -2426,7 +2440,7 @@ function ai_run(self, distance2, deltaSeconds, context) {
|
|
|
2426
2440
|
}
|
|
2427
2441
|
}
|
|
2428
2442
|
function ai_face(self, enemy, distance2, deltaSeconds) {
|
|
2429
|
-
if (enemy) {
|
|
2443
|
+
if (enemy && (self.monsterinfo.aiflags & 32768 /* ManualSteering */) === 0) {
|
|
2430
2444
|
setIdealYawTowards2(self, enemy);
|
|
2431
2445
|
}
|
|
2432
2446
|
changeYaw(self, deltaSeconds);
|
|
@@ -2435,7 +2449,9 @@ function ai_face(self, enemy, distance2, deltaSeconds) {
|
|
|
2435
2449
|
}
|
|
2436
2450
|
}
|
|
2437
2451
|
function ai_charge(self, distance2, deltaSeconds, context) {
|
|
2438
|
-
|
|
2452
|
+
if ((self.monsterinfo.aiflags & 32768 /* ManualSteering */) === 0) {
|
|
2453
|
+
setIdealYawTowards2(self, self.enemy);
|
|
2454
|
+
}
|
|
2439
2455
|
changeYaw(self, deltaSeconds);
|
|
2440
2456
|
if (self.monsterinfo.checkattack && self.monsterinfo.checkattack(self, context)) {
|
|
2441
2457
|
return;
|
|
@@ -11247,6 +11263,31 @@ function registerSupertankSpawns(registry) {
|
|
|
11247
11263
|
|
|
11248
11264
|
// src/entities/monsters/tank.ts
|
|
11249
11265
|
var MONSTER_TICK20 = 0.1;
|
|
11266
|
+
function M_AdjustBlindfireTarget(self, start, target, right, context) {
|
|
11267
|
+
const tr = context.trace(start, target, ZERO_VEC3, ZERO_VEC3, self, MASK_SHOT);
|
|
11268
|
+
if (!tr.startsolid && !tr.allsolid && tr.fraction >= 0.5) {
|
|
11269
|
+
return normalizeVec3(subtractVec3(target, start));
|
|
11270
|
+
}
|
|
11271
|
+
const leftTarget = addVec3(target, scaleVec3(right, -20));
|
|
11272
|
+
const trLeft = context.trace(start, leftTarget, ZERO_VEC3, ZERO_VEC3, self, MASK_SHOT);
|
|
11273
|
+
if (!trLeft.startsolid && !trLeft.allsolid && trLeft.fraction >= 0.5) {
|
|
11274
|
+
return normalizeVec3(subtractVec3(leftTarget, start));
|
|
11275
|
+
}
|
|
11276
|
+
const rightTarget = addVec3(target, scaleVec3(right, 20));
|
|
11277
|
+
const trRight = context.trace(start, rightTarget, ZERO_VEC3, ZERO_VEC3, self, MASK_SHOT);
|
|
11278
|
+
if (!trRight.startsolid && !trRight.allsolid && trRight.fraction >= 0.5) {
|
|
11279
|
+
return normalizeVec3(subtractVec3(rightTarget, start));
|
|
11280
|
+
}
|
|
11281
|
+
return null;
|
|
11282
|
+
}
|
|
11283
|
+
function tank_blind_check(self, context) {
|
|
11284
|
+
if (self.monsterinfo.aiflags & 32768 /* ManualSteering */) {
|
|
11285
|
+
if (self.monsterinfo.blind_fire_target) {
|
|
11286
|
+
const aim = subtractVec3(self.monsterinfo.blind_fire_target, self.origin);
|
|
11287
|
+
self.ideal_yaw = vectorToYaw(aim);
|
|
11288
|
+
}
|
|
11289
|
+
}
|
|
11290
|
+
}
|
|
11250
11291
|
function monster_ai_stand20(self, dist, context) {
|
|
11251
11292
|
ai_stand(self, MONSTER_TICK20, context);
|
|
11252
11293
|
}
|
|
@@ -11293,8 +11334,60 @@ function classifyRange3(distance2) {
|
|
|
11293
11334
|
if (distance2 <= 1e3) return "mid" /* Mid */;
|
|
11294
11335
|
return "far" /* Far */;
|
|
11295
11336
|
}
|
|
11337
|
+
function tank_checkattack(self, context) {
|
|
11338
|
+
if (!self.enemy) return false;
|
|
11339
|
+
const visibleEnemy = rangeTo(self, self.enemy) <= 1e3 && context.trace(self.origin, ZERO_VEC3, ZERO_VEC3, self.enemy.origin, self, MASK_SHOT).fraction === 1;
|
|
11340
|
+
if (visibleEnemy) {
|
|
11341
|
+
self.monsterinfo.blind_fire_target = addVec3(self.enemy.origin, scaleVec3(self.enemy.velocity, -0.1));
|
|
11342
|
+
self.monsterinfo.blind_fire_delay = 0;
|
|
11343
|
+
} else {
|
|
11344
|
+
if (self.monsterinfo.blindfire && (self.monsterinfo.blind_fire_delay || 0) <= 20) {
|
|
11345
|
+
if (self.attack_finished_time > context.timeSeconds) return false;
|
|
11346
|
+
if (context.timeSeconds < self.monsterinfo.trail_time + (self.monsterinfo.blind_fire_delay || 0)) {
|
|
11347
|
+
return false;
|
|
11348
|
+
}
|
|
11349
|
+
if (self.monsterinfo.blind_fire_target) {
|
|
11350
|
+
const tr = context.trace(self.origin, ZERO_VEC3, ZERO_VEC3, self.monsterinfo.blind_fire_target, self, 0);
|
|
11351
|
+
self.monsterinfo.attack_state = 4 /* Blind */;
|
|
11352
|
+
return true;
|
|
11353
|
+
}
|
|
11354
|
+
}
|
|
11355
|
+
return false;
|
|
11356
|
+
}
|
|
11357
|
+
const dist = rangeTo(self, self.enemy);
|
|
11358
|
+
if (self.attack_finished_time > context.timeSeconds) return false;
|
|
11359
|
+
let chance = 0;
|
|
11360
|
+
if (dist <= 150) chance = 0.4;
|
|
11361
|
+
else if (dist <= 500) chance = 0.25;
|
|
11362
|
+
else if (dist <= 1e3) chance = 0.06;
|
|
11363
|
+
else chance = 0;
|
|
11364
|
+
if (Math.random() < chance) {
|
|
11365
|
+
self.monsterinfo.attack_state = 3 /* Missile */;
|
|
11366
|
+
self.attack_finished_time = context.timeSeconds;
|
|
11367
|
+
return true;
|
|
11368
|
+
}
|
|
11369
|
+
return false;
|
|
11370
|
+
}
|
|
11296
11371
|
function tank_attack(self) {
|
|
11297
11372
|
if (!self.enemy) return;
|
|
11373
|
+
if (self.monsterinfo.attack_state === 4 /* Blind */) {
|
|
11374
|
+
let chance = 1;
|
|
11375
|
+
if ((self.monsterinfo.blind_fire_delay || 0) < 1) chance = 1;
|
|
11376
|
+
else if ((self.monsterinfo.blind_fire_delay || 0) < 7.5) chance = 0.4;
|
|
11377
|
+
else chance = 0.1;
|
|
11378
|
+
if (Math.random() > chance) return;
|
|
11379
|
+
self.monsterinfo.blind_fire_delay = (self.monsterinfo.blind_fire_delay || 0) + 5.2 + Math.random() * 3;
|
|
11380
|
+
if (!self.monsterinfo.blind_fire_target) return;
|
|
11381
|
+
self.monsterinfo.aiflags |= 32768 /* ManualSteering */;
|
|
11382
|
+
if (Math.random() < 0.5) {
|
|
11383
|
+
self.monsterinfo.current_move = attack_rocket_move3;
|
|
11384
|
+
} else {
|
|
11385
|
+
self.monsterinfo.current_move = attack_blaster_move;
|
|
11386
|
+
self.monsterinfo.nextframe = 69;
|
|
11387
|
+
}
|
|
11388
|
+
self.pain_debounce_time = self.timestamp + 5;
|
|
11389
|
+
return;
|
|
11390
|
+
}
|
|
11298
11391
|
const dist = rangeTo(self, self.enemy);
|
|
11299
11392
|
const range = classifyRange3(dist);
|
|
11300
11393
|
if (range === "melee" /* Melee */ || range === "near" /* Near */) {
|
|
@@ -11320,7 +11413,18 @@ function tank_fire_blaster(self, context) {
|
|
|
11320
11413
|
y: self.origin.y,
|
|
11321
11414
|
z: self.origin.z + (self.viewheight || 0)
|
|
11322
11415
|
};
|
|
11323
|
-
|
|
11416
|
+
let dir;
|
|
11417
|
+
const blindfire = (self.monsterinfo.aiflags & 32768 /* ManualSteering */) !== 0;
|
|
11418
|
+
if (blindfire && self.monsterinfo.blind_fire_target) {
|
|
11419
|
+
const angles = self.angles;
|
|
11420
|
+
const { right } = angleVectors(angles);
|
|
11421
|
+
const target = self.monsterinfo.blind_fire_target;
|
|
11422
|
+
const adj = M_AdjustBlindfireTarget(self, start, target, right, context);
|
|
11423
|
+
if (!adj) return;
|
|
11424
|
+
dir = adj;
|
|
11425
|
+
} else {
|
|
11426
|
+
dir = normalizeVec3(subtractVec3(self.enemy.origin, start));
|
|
11427
|
+
}
|
|
11324
11428
|
const damage = 30;
|
|
11325
11429
|
const speed = 1e3;
|
|
11326
11430
|
monster_fire_blaster(self, start, dir, damage, speed, 0, 0, context, 1 /* BLASTER */);
|
|
@@ -11345,7 +11449,18 @@ function tank_fire_rocket(self, context) {
|
|
|
11345
11449
|
z: self.origin.z + (self.viewheight || 0)
|
|
11346
11450
|
// Firing from shoulder
|
|
11347
11451
|
};
|
|
11348
|
-
|
|
11452
|
+
let dir;
|
|
11453
|
+
const blindfire = (self.monsterinfo.aiflags & 32768 /* ManualSteering */) !== 0;
|
|
11454
|
+
if (blindfire && self.monsterinfo.blind_fire_target) {
|
|
11455
|
+
const angles = self.angles;
|
|
11456
|
+
const { right } = angleVectors(angles);
|
|
11457
|
+
const target = self.monsterinfo.blind_fire_target;
|
|
11458
|
+
const adj = M_AdjustBlindfireTarget(self, start, target, right, context);
|
|
11459
|
+
if (!adj) return;
|
|
11460
|
+
dir = adj;
|
|
11461
|
+
} else {
|
|
11462
|
+
dir = normalizeVec3(subtractVec3(self.enemy.origin, start));
|
|
11463
|
+
}
|
|
11349
11464
|
const damage = 50;
|
|
11350
11465
|
const speed = 650;
|
|
11351
11466
|
monster_fire_rocket(self, start, dir, damage, speed, 0, context);
|
|
@@ -11357,6 +11472,12 @@ function tank_dead(self) {
|
|
|
11357
11472
|
self.monsterinfo.nextframe = death_move17.lastframe;
|
|
11358
11473
|
self.nextthink = -1;
|
|
11359
11474
|
}
|
|
11475
|
+
function tank_refire_rocket(self, context) {
|
|
11476
|
+
if (self.monsterinfo.aiflags & 32768 /* ManualSteering */) {
|
|
11477
|
+
self.monsterinfo.aiflags &= ~32768 /* ManualSteering */;
|
|
11478
|
+
}
|
|
11479
|
+
tank_run(self);
|
|
11480
|
+
}
|
|
11360
11481
|
var stand_frames19 = Array.from({ length: 30 }, () => ({
|
|
11361
11482
|
ai: monster_ai_stand20,
|
|
11362
11483
|
dist: 0
|
|
@@ -11387,12 +11508,16 @@ run_move18 = {
|
|
|
11387
11508
|
frames: run_frames17,
|
|
11388
11509
|
endfunc: tank_run
|
|
11389
11510
|
};
|
|
11390
|
-
var attack_blaster_frames = Array.from({ length: 16 }, (_, i) =>
|
|
11391
|
-
|
|
11392
|
-
|
|
11393
|
-
|
|
11394
|
-
|
|
11395
|
-
|
|
11511
|
+
var attack_blaster_frames = Array.from({ length: 16 }, (_, i) => {
|
|
11512
|
+
let think = null;
|
|
11513
|
+
if (i === 7) think = tank_blind_check;
|
|
11514
|
+
else if (i > 5 && i < 12) think = tank_fire_blaster;
|
|
11515
|
+
return {
|
|
11516
|
+
ai: monster_ai_charge20,
|
|
11517
|
+
dist: 0,
|
|
11518
|
+
think
|
|
11519
|
+
};
|
|
11520
|
+
});
|
|
11396
11521
|
attack_blaster_move = {
|
|
11397
11522
|
firstframe: 62,
|
|
11398
11523
|
lastframe: 77,
|
|
@@ -11410,17 +11535,21 @@ attack_machinegun_move = {
|
|
|
11410
11535
|
frames: attack_machinegun_frames,
|
|
11411
11536
|
endfunc: tank_run
|
|
11412
11537
|
};
|
|
11413
|
-
var attack_rocket_frames3 = Array.from({ length: 18 }, (_, i) =>
|
|
11414
|
-
|
|
11415
|
-
|
|
11416
|
-
|
|
11417
|
-
|
|
11418
|
-
|
|
11538
|
+
var attack_rocket_frames3 = Array.from({ length: 18 }, (_, i) => {
|
|
11539
|
+
let think = null;
|
|
11540
|
+
if (i === 0) think = tank_blind_check;
|
|
11541
|
+
else if (i === 8 || i === 12 || i === 16) think = tank_fire_rocket;
|
|
11542
|
+
return {
|
|
11543
|
+
ai: monster_ai_charge20,
|
|
11544
|
+
dist: 0,
|
|
11545
|
+
think
|
|
11546
|
+
};
|
|
11547
|
+
});
|
|
11419
11548
|
attack_rocket_move3 = {
|
|
11420
11549
|
firstframe: 98,
|
|
11421
11550
|
lastframe: 115,
|
|
11422
11551
|
frames: attack_rocket_frames3,
|
|
11423
|
-
endfunc:
|
|
11552
|
+
endfunc: tank_refire_rocket
|
|
11424
11553
|
};
|
|
11425
11554
|
var pain_frames11 = Array.from({ length: 6 }, () => ({
|
|
11426
11555
|
ai: monster_ai_move20,
|
|
@@ -11480,6 +11609,8 @@ function SP_monster_tank(self, context) {
|
|
|
11480
11609
|
self.monsterinfo.run = tank_run;
|
|
11481
11610
|
self.monsterinfo.attack = tank_attack;
|
|
11482
11611
|
self.monsterinfo.attack_machinegun = attack_machinegun_move;
|
|
11612
|
+
self.monsterinfo.checkattack = tank_checkattack;
|
|
11613
|
+
self.monsterinfo.blindfire = true;
|
|
11483
11614
|
self.think = monster_think;
|
|
11484
11615
|
tank_stand(self);
|
|
11485
11616
|
self.nextthink = self.timestamp + MONSTER_TICK20;
|
|
@@ -13510,7 +13641,7 @@ var WEAPONS = {
|
|
|
13510
13641
|
};
|
|
13511
13642
|
|
|
13512
13643
|
// src/index.ts
|
|
13513
|
-
var
|
|
13644
|
+
var ZERO_VEC37 = { x: 0, y: 0, z: 0 };
|
|
13514
13645
|
function createGame(imports, engine, options) {
|
|
13515
13646
|
const gravity = options.gravity;
|
|
13516
13647
|
const deathmatch = options.deathmatch ?? false;
|
|
@@ -13577,8 +13708,8 @@ function createGame(imports, engine, options) {
|
|
|
13577
13708
|
};
|
|
13578
13709
|
entities.runFrame();
|
|
13579
13710
|
});
|
|
13580
|
-
let origin = { ...
|
|
13581
|
-
let velocity = { ...
|
|
13711
|
+
let origin = { ...ZERO_VEC37 };
|
|
13712
|
+
let velocity = { ...ZERO_VEC37 };
|
|
13582
13713
|
const calculateBlend = (player, time) => {
|
|
13583
13714
|
const blend = [0, 0, 0, 0];
|
|
13584
13715
|
if (!player || !player.client) return blend;
|
|
@@ -13661,9 +13792,9 @@ function createGame(imports, engine, options) {
|
|
|
13661
13792
|
damageIndicators: [],
|
|
13662
13793
|
// Stubs for new PlayerState fields
|
|
13663
13794
|
stats: player ? populatePlayerStats(player, levelClock.current.timeSeconds) : [],
|
|
13664
|
-
kick_angles:
|
|
13665
|
-
gunoffset:
|
|
13666
|
-
gunangles:
|
|
13795
|
+
kick_angles: ZERO_VEC37,
|
|
13796
|
+
gunoffset: ZERO_VEC37,
|
|
13797
|
+
gunangles: ZERO_VEC37,
|
|
13667
13798
|
gunindex: 0
|
|
13668
13799
|
}
|
|
13669
13800
|
};
|
|
@@ -13671,8 +13802,8 @@ function createGame(imports, engine, options) {
|
|
|
13671
13802
|
const resetState = (startTimeMs) => {
|
|
13672
13803
|
frameLoop.reset(startTimeMs);
|
|
13673
13804
|
levelClock.start(startTimeMs);
|
|
13674
|
-
origin = { ...
|
|
13675
|
-
velocity = { ...
|
|
13805
|
+
origin = { ...ZERO_VEC37 };
|
|
13806
|
+
velocity = { ...ZERO_VEC37 };
|
|
13676
13807
|
entities.beginFrame(startTimeMs / 1e3);
|
|
13677
13808
|
entities.runFrame();
|
|
13678
13809
|
};
|
|
@@ -13700,9 +13831,9 @@ function createGame(imports, engine, options) {
|
|
|
13700
13831
|
blend: [0, 0, 0, 0],
|
|
13701
13832
|
// Stubs
|
|
13702
13833
|
stats: populatePlayerStats(player, levelClock.current.timeSeconds),
|
|
13703
|
-
kick_angles:
|
|
13704
|
-
gunoffset:
|
|
13705
|
-
gunangles:
|
|
13834
|
+
kick_angles: ZERO_VEC37,
|
|
13835
|
+
gunoffset: ZERO_VEC37,
|
|
13836
|
+
gunangles: ZERO_VEC37,
|
|
13706
13837
|
gunindex: 0
|
|
13707
13838
|
};
|
|
13708
13839
|
const traceAdapter = (start, end) => {
|
|
@@ -13821,8 +13952,8 @@ function createGame(imports, engine, options) {
|
|
|
13821
13952
|
rng,
|
|
13822
13953
|
player: player?.client?.inventory
|
|
13823
13954
|
});
|
|
13824
|
-
origin = player ? { ...player.origin } : { ...
|
|
13825
|
-
velocity = player ? { ...player.velocity } : { ...
|
|
13955
|
+
origin = player ? { ...player.origin } : { ...ZERO_VEC37 };
|
|
13956
|
+
velocity = player ? { ...player.velocity } : { ...ZERO_VEC37 };
|
|
13826
13957
|
frameLoop.reset(save.level.timeSeconds * 1e3);
|
|
13827
13958
|
}
|
|
13828
13959
|
};
|
|
@@ -13839,6 +13970,7 @@ function createGame(imports, engine, options) {
|
|
|
13839
13970
|
AmmoItemId,
|
|
13840
13971
|
AmmoType,
|
|
13841
13972
|
ArmorType,
|
|
13973
|
+
AttackState,
|
|
13842
13974
|
CheckGround,
|
|
13843
13975
|
DamageFlags,
|
|
13844
13976
|
DamageMod,
|