@nxg-org/mineflayer-physics-util 1.8.18 → 1.9.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/.vscode/settings.json +4 -4
- package/README.md +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/physics/engines/botcraft.d.ts +9 -1
- package/dist/physics/engines/botcraft.js +119 -85
- package/dist/physics/engines/entityPhysics.js +5 -5
- package/dist/physics/engines/optimizedPhysics.js +4 -4
- package/dist/physics/settings/physicsSettings.js +1 -1
- package/dist/physics/states/entityState.d.ts +6 -1
- package/dist/physics/states/entityState.js +22 -12
- package/dist/physics/states/index.d.ts +1 -0
- package/dist/physics/states/playerState.d.ts +6 -1
- package/dist/physics/states/playerState.js +29 -19
- package/dist/physics/states/poses.js +4 -4
- package/dist/util/physicsUtils.d.ts +7 -0
- package/dist/util/physicsUtils.js +72 -16
- package/eslint.config.mjs +17 -17
- package/package.json +49 -47
- package/tests/actualBot.ts +0 -201
- package/tests/fakeWorld.test.ts +0 -354
- package/tests/predictBot.ts +0 -73
- package/tests/util/testUtils.ts +0 -68
package/.vscode/settings.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
{
|
|
2
|
-
"print.colourScheme": "GitHub",
|
|
3
|
-
"ecl.launchConfiguration": "not found",
|
|
4
|
-
"ecl.targetCluster": {}
|
|
1
|
+
{
|
|
2
|
+
"print.colourScheme": "GitHub",
|
|
3
|
+
"ecl.launchConfiguration": "not found",
|
|
4
|
+
"ecl.targetCluster": {}
|
|
5
5
|
}
|
package/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
# mineflayer-physics-utils
|
|
1
|
+
# mineflayer-physics-utils
|
package/dist/index.d.ts
CHANGED
|
@@ -14,4 +14,4 @@ export { EntityPhysics, BotcraftPhysics } from "./physics/engines";
|
|
|
14
14
|
export { EntityState, PlayerState, PlayerPoses, IEntityState } from "./physics/states";
|
|
15
15
|
export { ControlStateHandler } from "./physics/player";
|
|
16
16
|
export type { SimulationGoal, Controller, OnGoalReachFunction } from "./simulators";
|
|
17
|
-
export { convertPlayerState } from "./util/physicsUtils";
|
|
17
|
+
export { convertPlayerState, applyToPlayerState } from "./util/physicsUtils";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.convertPlayerState = exports.ControlStateHandler = exports.PlayerPoses = exports.PlayerState = exports.EntityState = exports.BotcraftPhysics = exports.EntityPhysics = exports.BaseSimulator = exports.PhysicsWorldSettings = exports.EPhysicsCtx = void 0;
|
|
3
|
+
exports.applyToPlayerState = exports.convertPlayerState = exports.ControlStateHandler = exports.PlayerPoses = exports.PlayerState = exports.EntityState = exports.BotcraftPhysics = exports.EntityPhysics = exports.BaseSimulator = exports.PhysicsWorldSettings = exports.EPhysicsCtx = void 0;
|
|
4
4
|
exports.default = loader;
|
|
5
5
|
exports.initSetup = initSetup;
|
|
6
6
|
const settings_1 = require("./physics/settings");
|
|
@@ -30,3 +30,4 @@ var player_1 = require("./physics/player");
|
|
|
30
30
|
Object.defineProperty(exports, "ControlStateHandler", { enumerable: true, get: function () { return player_1.ControlStateHandler; } });
|
|
31
31
|
var physicsUtils_1 = require("./util/physicsUtils");
|
|
32
32
|
Object.defineProperty(exports, "convertPlayerState", { enumerable: true, get: function () { return physicsUtils_1.convertPlayerState; } });
|
|
33
|
+
Object.defineProperty(exports, "applyToPlayerState", { enumerable: true, get: function () { return physicsUtils_1.applyToPlayerState; } });
|
|
@@ -9,7 +9,9 @@ import { IEntityState } from "../states";
|
|
|
9
9
|
import { IPhysics } from "./IPhysics";
|
|
10
10
|
import { PlayerState } from "../states";
|
|
11
11
|
import type { world } from "prismarine-world";
|
|
12
|
-
type World =
|
|
12
|
+
type World = {
|
|
13
|
+
getBlock: world.WorldSync["getBlock"];
|
|
14
|
+
};
|
|
13
15
|
/**
|
|
14
16
|
* Looking at this code, it's too specified towards players.
|
|
15
17
|
*
|
|
@@ -84,6 +86,7 @@ export declare class BotcraftPhysics implements IPhysics {
|
|
|
84
86
|
getLiquidHeightPcent(block: Block): number;
|
|
85
87
|
getRenderedDepth(block: Block): number;
|
|
86
88
|
private updateSwimming;
|
|
89
|
+
private isMovingSlowly;
|
|
87
90
|
private localPlayerAIStep;
|
|
88
91
|
private inputsToCrouch;
|
|
89
92
|
private isSwimmingAndNotFlying;
|
|
@@ -92,6 +95,8 @@ export declare class BotcraftPhysics implements IPhysics {
|
|
|
92
95
|
private hasEnoughFoodToSprint;
|
|
93
96
|
private vehicleCanSprint;
|
|
94
97
|
private isSwimming;
|
|
98
|
+
private handleFallFlyingCollisions;
|
|
99
|
+
private applyFireworkBoost;
|
|
95
100
|
private shouldStopRunSprinting;
|
|
96
101
|
private shouldStopSwimSprinting;
|
|
97
102
|
/**
|
|
@@ -102,6 +107,9 @@ export declare class BotcraftPhysics implements IPhysics {
|
|
|
102
107
|
setSprinting(ctx: EPhysicsCtx, value: boolean): void;
|
|
103
108
|
private inputsToFly;
|
|
104
109
|
private inputsToJump;
|
|
110
|
+
private getBlockJumpFactor;
|
|
111
|
+
private getKnownJumpFactor;
|
|
112
|
+
private getOffGroundSpeed;
|
|
105
113
|
private getBlockBelowAffectingMovement;
|
|
106
114
|
/**
|
|
107
115
|
* Taken from original physics impl.
|
|
@@ -451,8 +451,18 @@ class BotcraftPhysics {
|
|
|
451
451
|
!!(block.type === this.waterId || this.waterLike.has(block.type) || block.getProperties().waterlogged);
|
|
452
452
|
}
|
|
453
453
|
}
|
|
454
|
+
isMovingSlowly(ctx, world) {
|
|
455
|
+
const player = ctx.state;
|
|
456
|
+
if (this.verGreaterThan("1.13.2")) {
|
|
457
|
+
const visuallyCrawling = (player.pose === states_1.PlayerPoses.SWIMMING || (!player.fallFlying && player.pose === states_1.PlayerPoses.FALL_FLYING)) &&
|
|
458
|
+
!player.isInWater;
|
|
459
|
+
return player.crouching || visuallyCrawling;
|
|
460
|
+
}
|
|
461
|
+
return player.crouching;
|
|
462
|
+
}
|
|
454
463
|
localPlayerAIStep(ctx, world) {
|
|
455
464
|
const player = ctx.state;
|
|
465
|
+
const tickStartedOnGround = player.onGround;
|
|
456
466
|
const heading = (0, states_1.convInpToAxes)(player);
|
|
457
467
|
player.heading = heading;
|
|
458
468
|
// moved into AiStep since it's tied to player behavior. Strictly, is Player::updateSwimming.
|
|
@@ -472,11 +482,6 @@ class BotcraftPhysics {
|
|
|
472
482
|
{
|
|
473
483
|
player.flyJumpTriggerTime = Math.max(0, player.flyJumpTriggerTime - 1);
|
|
474
484
|
}
|
|
475
|
-
// TODO: find a good way to implement this.
|
|
476
|
-
player.prevHeading.forward = heading.forward;
|
|
477
|
-
player.prevHeading.strafe = heading.strafe;
|
|
478
|
-
player.prevControl.jump = player.control.jump;
|
|
479
|
-
player.prevControl.sneak = player.control.sneak;
|
|
480
485
|
// livingEntity::AiStep
|
|
481
486
|
{
|
|
482
487
|
player.jumpTicks = Math.max(0, player.jumpTicks - 1);
|
|
@@ -509,6 +514,11 @@ class BotcraftPhysics {
|
|
|
509
514
|
player.vel.y += (mSinPitch - player.vel.y) * (mSinPitch < -0.2 ? 0.085 : 0.06);
|
|
510
515
|
}
|
|
511
516
|
}
|
|
517
|
+
// Refresh pose before movement so the first fall-flying tick uses the
|
|
518
|
+
// correct collider instead of the standing bounding box.
|
|
519
|
+
if (this.verGreaterThan("1.13.2")) {
|
|
520
|
+
this.updatePoses(ctx, world);
|
|
521
|
+
}
|
|
512
522
|
const velY = player.vel.y;
|
|
513
523
|
this.movePlayer(ctx, world); // TODO: should be in player-specific logic??
|
|
514
524
|
if (player.flying) {
|
|
@@ -527,6 +537,13 @@ class BotcraftPhysics {
|
|
|
527
537
|
if (this.verGreaterThan("1.13.2")) {
|
|
528
538
|
this.updatePoses(ctx, world);
|
|
529
539
|
}
|
|
540
|
+
// Preserve the current inputs for the next tick after all previous-state
|
|
541
|
+
// consumers in this tick have already read the prior values.
|
|
542
|
+
player.lastOnGround = player.onGround;
|
|
543
|
+
player.prevHeading.forward = heading.forward;
|
|
544
|
+
player.prevHeading.strafe = heading.strafe;
|
|
545
|
+
player.prevControl.jump = player.control.jump;
|
|
546
|
+
player.prevControl.sneak = player.control.sneak;
|
|
530
547
|
}
|
|
531
548
|
inputsToCrouch(ctx, heading, world) {
|
|
532
549
|
var _a, _b, _c;
|
|
@@ -545,19 +562,13 @@ class BotcraftPhysics {
|
|
|
545
562
|
player.crouching = !this.isSwimmingAndNotFlying(ctx, world) && player.prevControl.sneak;
|
|
546
563
|
}
|
|
547
564
|
// Determine if moving slowly
|
|
548
|
-
|
|
549
|
-
if (this.verGreaterThan("1.13.2")) {
|
|
550
|
-
isMovingSlowly = player.crouching || (player.pose === states_1.PlayerPoses.SWIMMING && !player.isInWater);
|
|
551
|
-
}
|
|
552
|
-
else {
|
|
553
|
-
isMovingSlowly = player.crouching;
|
|
554
|
-
}
|
|
565
|
+
const isMovingSlowly = this.isMovingSlowly(ctx, world);
|
|
555
566
|
// Handle post-1.21.3 sprinting conditions
|
|
556
567
|
if (this.verGreaterThan("1.21.3")) {
|
|
557
568
|
// TODO: just use stored blindness effect.
|
|
558
569
|
const hasBlindness = this.getEffectLevel(physicsUtils_1.CheapEffects.BLINDNESS, player.effects) > 0;
|
|
559
570
|
// Stop sprinting when crouching fix in 1.21.4+
|
|
560
|
-
if (
|
|
571
|
+
if (hasBlindness || isMovingSlowly) {
|
|
561
572
|
this.setSprinting(ctx, false);
|
|
562
573
|
}
|
|
563
574
|
}
|
|
@@ -640,6 +651,30 @@ class BotcraftPhysics {
|
|
|
640
651
|
const player = ctx.state;
|
|
641
652
|
return player.isInWater && player.isUnderWater;
|
|
642
653
|
}
|
|
654
|
+
handleFallFlyingCollisions(player, previousHorizontalSpeed) {
|
|
655
|
+
if (!player.isCollidedHorizontally)
|
|
656
|
+
return;
|
|
657
|
+
const currentHorizontalSpeed = Math.sqrt(player.vel.x * player.vel.x + player.vel.z * player.vel.z);
|
|
658
|
+
const deltaSpeed = previousHorizontalSpeed - currentHorizontalSpeed;
|
|
659
|
+
const collisionDamage = deltaSpeed * 10.0 - 3.0;
|
|
660
|
+
if (collisionDamage > 0.0) {
|
|
661
|
+
// Vanilla applies fly-into-wall damage and sound here.
|
|
662
|
+
// BotcraftPhysics currently does not model those side effects.
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
applyFireworkBoost(player) {
|
|
666
|
+
if (player.fireworkRocketDuration <= 0)
|
|
667
|
+
return;
|
|
668
|
+
if (!player.fallFlying) {
|
|
669
|
+
player.fireworkRocketDuration = 0;
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
const { lookDir } = (0, physicsUtils_1.getLookingVector)(player);
|
|
673
|
+
player.vel.x += lookDir.x * 0.1 + (lookDir.x * 1.5 - player.vel.x) * 0.5;
|
|
674
|
+
player.vel.y += lookDir.y * 0.1 + (lookDir.y * 1.5 - player.vel.y) * 0.5;
|
|
675
|
+
player.vel.z += lookDir.z * 0.1 + (lookDir.z * 1.5 - player.vel.z) * 0.5;
|
|
676
|
+
--player.fireworkRocketDuration;
|
|
677
|
+
}
|
|
643
678
|
shouldStopRunSprinting(ctx, heading) {
|
|
644
679
|
const player = ctx.state;
|
|
645
680
|
return player.blindness > 0 ||
|
|
@@ -730,57 +765,68 @@ class BotcraftPhysics {
|
|
|
730
765
|
var _a, _b;
|
|
731
766
|
if (entity instanceof states_1.PlayerState) {
|
|
732
767
|
const player = entity;
|
|
733
|
-
if (player.control.jump
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
768
|
+
if (!player.control.jump) {
|
|
769
|
+
player.jumpTicks = 0;
|
|
770
|
+
return;
|
|
771
|
+
}
|
|
772
|
+
if (player.flying) {
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
if (player.isInWater || player.isInLava) {
|
|
776
|
+
player.vel.y += 0.03999999910593033; // magic number
|
|
777
|
+
}
|
|
778
|
+
else if (player.onGround && player.jumpTicks === 0) {
|
|
779
|
+
const blockJumpFactor = this.getBlockJumpFactor(player, world, worldSettings);
|
|
780
|
+
const jumpBoost = Math.fround(0.1 * player.jumpBoost); // in mineflayer, level 1 is 1, not 0.
|
|
781
|
+
if (this.verLessThan("1.20.5")) {
|
|
782
|
+
const jumpPower = Math.fround(Math.fround(0.42) * Math.fround(blockJumpFactor) + jumpBoost);
|
|
783
|
+
player.vel.y = Math.max(jumpPower, player.vel.y);
|
|
784
|
+
if (player.sprinting) {
|
|
785
|
+
const yawRad = Math.PI - player.yaw; // should already be in yaw. MINEFLAYER SPECIFC CHANGE, MATH.PI -
|
|
786
|
+
// potential inconsistency here. This may not be accurate.
|
|
787
|
+
const offsetX = Math.fround(Math.sin(yawRad)) * 0.2;
|
|
788
|
+
const offsetZ = Math.fround(Math.cos(yawRad)) * 0.2;
|
|
789
|
+
player.vel.x -= offsetX;
|
|
790
|
+
player.vel.z += offsetZ;
|
|
750
791
|
}
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
792
|
+
}
|
|
793
|
+
else {
|
|
794
|
+
const value = Math.fround((_b = (_a = entity.attributes[this.jumpStrengthAttribute]) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : Math.fround(0.42));
|
|
795
|
+
const jumpPower = Math.fround(value * Math.fround(blockJumpFactor) + jumpBoost);
|
|
796
|
+
if (jumpPower > 1e-5) {
|
|
797
|
+
player.vel.y = Math.max(jumpPower, player.vel.y);
|
|
754
798
|
if (player.sprinting) {
|
|
755
799
|
const yawRad = Math.PI - player.yaw; // should already be in yaw. MINEFLAYER SPECIFC CHANGE, MATH.PI -
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
const offsetZ = Math.fround(Math.cos(yawRad)) * 0.2;
|
|
759
|
-
player.vel.x -= offsetX;
|
|
760
|
-
player.vel.z += offsetZ;
|
|
800
|
+
player.vel.x -= Math.sin(yawRad) * 0.2;
|
|
801
|
+
player.vel.z += Math.cos(yawRad) * 0.2;
|
|
761
802
|
}
|
|
762
803
|
}
|
|
763
|
-
else {
|
|
764
|
-
// something about getting an attribute for jump strength?
|
|
765
|
-
const value = (_b = (_a = entity.attributes[this.jumpStrengthAttribute]) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : Math.fround(0.42); // default value from previous versions
|
|
766
|
-
const jumpPower = value * blockJumpFactor + jumpBoost;
|
|
767
|
-
if (jumpPower > 1e-5) {
|
|
768
|
-
player.vel.y = jumpPower;
|
|
769
|
-
if (player.sprinting) {
|
|
770
|
-
const yawRad = Math.PI - player.yaw; // should already be in yaw. MINEFLAYER SPECIFC CHANGE, MATH.PI -
|
|
771
|
-
player.vel.x -= Math.sin(yawRad) * 0.2;
|
|
772
|
-
player.vel.z += Math.cos(yawRad) * 0.2;
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
player.jumpTicks = worldSettings.autojumpCooldown;
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
else {
|
|
779
|
-
player.jumpTicks = 0;
|
|
780
804
|
}
|
|
805
|
+
player.jumpTicks = worldSettings.autojumpCooldown;
|
|
781
806
|
}
|
|
782
807
|
}
|
|
783
808
|
}
|
|
809
|
+
getBlockJumpFactor(entity, world, worldSettings) {
|
|
810
|
+
const feetBlock = world.getBlock(new vec3_1.Vec3(entity.pos.x, entity.pos.y, entity.pos.z));
|
|
811
|
+
const feetJumpFactor = this.getKnownJumpFactor(feetBlock === null || feetBlock === void 0 ? void 0 : feetBlock.type, worldSettings);
|
|
812
|
+
if (feetJumpFactor !== 1.0)
|
|
813
|
+
return feetJumpFactor;
|
|
814
|
+
const supportBlock = world.getBlock(this.getBlockBelowAffectingMovement(entity, world));
|
|
815
|
+
return this.getKnownJumpFactor(supportBlock === null || supportBlock === void 0 ? void 0 : supportBlock.type, worldSettings);
|
|
816
|
+
}
|
|
817
|
+
getKnownJumpFactor(blockType, worldSettings) {
|
|
818
|
+
if (blockType == null)
|
|
819
|
+
return 1.0;
|
|
820
|
+
if (blockType === this.honeyblockId)
|
|
821
|
+
return worldSettings.honeyblockJumpSpeed;
|
|
822
|
+
return 1.0;
|
|
823
|
+
}
|
|
824
|
+
getOffGroundSpeed(player) {
|
|
825
|
+
if (player.flying) {
|
|
826
|
+
return player.sprinting ? player.flySpeed * 2.0 : player.flySpeed;
|
|
827
|
+
}
|
|
828
|
+
return player.sprinting ? Math.fround(0.025999999) : Math.fround(0.02);
|
|
829
|
+
}
|
|
784
830
|
getBlockBelowAffectingMovement(entity, world) {
|
|
785
831
|
if (entity.supportingBlockPos != null) {
|
|
786
832
|
return entity.supportingBlockPos; //.offset(0, -0.500001, 0);
|
|
@@ -929,6 +975,7 @@ class BotcraftPhysics {
|
|
|
929
975
|
}
|
|
930
976
|
// elytra flying.
|
|
931
977
|
else if (player.fallFlying) {
|
|
978
|
+
const previousHorizontalSpeed = Math.sqrt(player.vel.x * player.vel.x + player.vel.z * player.vel.z);
|
|
932
979
|
// slight deviation
|
|
933
980
|
// sqrt(front_vector.x² + front_vector.z²) to follow vanilla code
|
|
934
981
|
const { pitch, sinPitch, cosPitch, lookDir } = (0, physicsUtils_1.getLookingVector)(player);
|
|
@@ -942,10 +989,10 @@ class BotcraftPhysics {
|
|
|
942
989
|
player.vel.z += (lookDir.z * deltaSpeed) / cosPitchFromLength;
|
|
943
990
|
player.vel.y += deltaSpeed;
|
|
944
991
|
}
|
|
945
|
-
if (player.pitch
|
|
946
|
-
const deltaSpeed = hVel *
|
|
947
|
-
player.vel.x += (lookDir.x * deltaSpeed) / cosPitchFromLength;
|
|
948
|
-
player.vel.z += (lookDir.z * deltaSpeed) / cosPitchFromLength;
|
|
992
|
+
if (player.pitch > 0.0 && cosPitchFromLength > 0.0) {
|
|
993
|
+
const deltaSpeed = hVel * lookDir.y * 0.04;
|
|
994
|
+
player.vel.x += (-lookDir.x * deltaSpeed) / cosPitchFromLength;
|
|
995
|
+
player.vel.z += (-lookDir.z * deltaSpeed) / cosPitchFromLength;
|
|
949
996
|
player.vel.y += deltaSpeed * 3.2; // magic number
|
|
950
997
|
}
|
|
951
998
|
if (cosPitchFromLength > 0.0) {
|
|
@@ -956,44 +1003,24 @@ class BotcraftPhysics {
|
|
|
956
1003
|
player.vel.z *= Math.fround(0.99); // magic number, this DEFINITELY should be replaced by a drag value.
|
|
957
1004
|
player.vel.y *= Math.fround(0.98); // magic number, this DEFINITELY should be replaced by a drag value.
|
|
958
1005
|
this.applyMovement(ctx, world);
|
|
959
|
-
|
|
960
|
-
player.fallFlying = false;
|
|
961
|
-
}
|
|
962
|
-
// Potentially not the correct place for this logic, but it is easier to implement here for now. This is the firework boost from elytra flying.
|
|
963
|
-
if (player.fireworkRocketDuration > 0) {
|
|
964
|
-
const { lookDir } = (0, physicsUtils_1.getLookingVector)(player);
|
|
965
|
-
player.vel.x += lookDir.x * 0.1 + (lookDir.x * 1.5 - player.vel.x) * 0.5;
|
|
966
|
-
player.vel.y += lookDir.y * 0.1 + (lookDir.y * 1.5 - player.vel.y) * 0.5;
|
|
967
|
-
player.vel.z += lookDir.z * 0.1 + (lookDir.z * 1.5 - player.vel.z) * 0.5;
|
|
968
|
-
--player.fireworkRocketDuration;
|
|
969
|
-
}
|
|
970
|
-
// we're on ground or in air, not flying.
|
|
1006
|
+
this.handleFallFlyingCollisions(player, previousHorizontalSpeed);
|
|
971
1007
|
}
|
|
972
1008
|
else {
|
|
973
|
-
// clear firework boost if on ground or in air without flying, otherwise it can cause issues with movement.
|
|
974
|
-
if (player.fireworkRocketDuration > 0) {
|
|
975
|
-
player.fireworkRocketDuration = 0;
|
|
976
|
-
}
|
|
977
1009
|
const blockBelow = world.getBlock(this.getBlockBelowAffectingMovement(player, world));
|
|
978
1010
|
// deviation. using our stores slipperiness values.
|
|
979
1011
|
const friction = blockBelow
|
|
980
1012
|
? (_c = this.blockSlipperiness[blockBelow.type]) !== null && _c !== void 0 ? _c : ctx.worldSettings.defaultSlipperiness
|
|
981
1013
|
: ctx.worldSettings.defaultSlipperiness;
|
|
982
1014
|
// console.log(blockBelow.name, blockBelow.position, player.supportingBlockPos, friction)
|
|
983
|
-
const inertia = player.
|
|
1015
|
+
const inertia = player.lastOnGround ? friction * ctx.airborneInertia : ctx.airborneInertia;
|
|
984
1016
|
// deviation, adding additional logic for changing attribute values.
|
|
985
1017
|
const movementSpeedAttr = this.getMovementSpeedAttribute(ctx);
|
|
986
1018
|
let inputStrength;
|
|
987
|
-
if (player.
|
|
1019
|
+
if (player.lastOnGround) {
|
|
988
1020
|
inputStrength = movementSpeedAttr * (0.21600002 / (friction * friction * friction));
|
|
989
1021
|
}
|
|
990
1022
|
else {
|
|
991
|
-
inputStrength =
|
|
992
|
-
// DEVIATION: taken from p-physics, fixes motion!
|
|
993
|
-
if (player.sprinting) {
|
|
994
|
-
const airSprintFactor = ctx.airborneAccel * 0.3;
|
|
995
|
-
inputStrength += airSprintFactor;
|
|
996
|
-
}
|
|
1023
|
+
inputStrength = this.getOffGroundSpeed(player);
|
|
997
1024
|
}
|
|
998
1025
|
this.applyInputs(inputStrength, player);
|
|
999
1026
|
if (player.onClimbable) {
|
|
@@ -1024,6 +1051,7 @@ class BotcraftPhysics {
|
|
|
1024
1051
|
// this can be generalized.
|
|
1025
1052
|
player.vel.y *= 0.9800000190734863;
|
|
1026
1053
|
}
|
|
1054
|
+
this.applyFireworkBoost(player);
|
|
1027
1055
|
}
|
|
1028
1056
|
}
|
|
1029
1057
|
applyMovement(ctx, world) {
|
|
@@ -1120,8 +1148,11 @@ class BotcraftPhysics {
|
|
|
1120
1148
|
// TODO: add minor horizontal collision check
|
|
1121
1149
|
{
|
|
1122
1150
|
// Entity::setOnGroundWithKnownMovement
|
|
1123
|
-
|
|
1124
|
-
|
|
1151
|
+
const wasOnGround = player.onGround;
|
|
1152
|
+
const groundedByCollision = movementBeforeCollisions.y < 0.0 && collisionY;
|
|
1153
|
+
const shouldCheckStandingSupport = wasOnGround && Math.abs(movementBeforeCollisions.y) <= 1e-7;
|
|
1154
|
+
player.onGround = groundedByCollision;
|
|
1155
|
+
if (player.onGround || shouldCheckStandingSupport) {
|
|
1125
1156
|
const halfWidth = player.halfWidth;
|
|
1126
1157
|
const feetSliceAABB = new mineflayer_util_plugin_1.AABB(player.pos.x - halfWidth, player.pos.y, player.pos.z - halfWidth, player.pos.x + halfWidth, player.pos.y + 1, player.pos.z + halfWidth);
|
|
1127
1158
|
const supportingBlockPos = this.getSupportingBlockPos(world, feetSliceAABB);
|
|
@@ -1132,6 +1163,9 @@ class BotcraftPhysics {
|
|
|
1132
1163
|
else {
|
|
1133
1164
|
player.supportingBlockPos = this.getSupportingBlockPos(world, feetSliceAABB.translate(-movement.x, 0.0, -movement.z));
|
|
1134
1165
|
}
|
|
1166
|
+
if (!player.onGround && player.supportingBlockPos != null) {
|
|
1167
|
+
player.onGround = true;
|
|
1168
|
+
}
|
|
1135
1169
|
// unnecessary due to it being a getter.
|
|
1136
1170
|
// player->on_ground_without_supporting_block = !player->supporting_block_pos.has_value();
|
|
1137
1171
|
}
|
|
@@ -533,7 +533,7 @@ class EntityPhysics {
|
|
|
533
533
|
const gravityMultiplier = vel.y <= 0 && entity.state.slowFalling > 0 ? entity.worldSettings.slowFalling : 1;
|
|
534
534
|
// Unsure how to handle this w/ other entities.
|
|
535
535
|
// this is player-only.
|
|
536
|
-
if (entity.state.
|
|
536
|
+
if (entity.state.fallFlying) {
|
|
537
537
|
const { pitch, sinPitch, cosPitch, lookDir } = (0, physicsUtils_1.getLookingVector)(entity.state);
|
|
538
538
|
const horizontalSpeed = Math.sqrt(vel.x * vel.x + vel.z * vel.z);
|
|
539
539
|
const cosPitchSquared = cosPitch * cosPitch;
|
|
@@ -561,7 +561,7 @@ class EntityPhysics {
|
|
|
561
561
|
vel.z *= 0.99;
|
|
562
562
|
this.moveEntity(entity, vel.x, vel.y, vel.z, world);
|
|
563
563
|
if (entity.state.onGround) {
|
|
564
|
-
entity.state.
|
|
564
|
+
entity.state.fallFlying = false;
|
|
565
565
|
}
|
|
566
566
|
}
|
|
567
567
|
else if (!entity.state.isInWater && !entity.state.isInLava) {
|
|
@@ -732,12 +732,12 @@ class EntityPhysics {
|
|
|
732
732
|
forward *= entity.worldSettings.usingItemSpeed;
|
|
733
733
|
entity.state.control.sprint = false;
|
|
734
734
|
}
|
|
735
|
-
entity.state.
|
|
736
|
-
entity.state.
|
|
735
|
+
entity.state.fallFlying =
|
|
736
|
+
entity.state.fallFlying && entity.state.elytraEquipped && !entity.state.onGround && !entity.state.levitation;
|
|
737
737
|
// for now, only check if this is a player.
|
|
738
738
|
if (entity.state instanceof states_1.PlayerState) {
|
|
739
739
|
if (entity.state.fireworkRocketDuration > 0) {
|
|
740
|
-
if (!entity.state.
|
|
740
|
+
if (!entity.state.fallFlying) {
|
|
741
741
|
entity.state.fireworkRocketDuration = 0;
|
|
742
742
|
}
|
|
743
743
|
else {
|
|
@@ -601,7 +601,7 @@ class EntityPhysics {
|
|
|
601
601
|
vel.x *= inertia;
|
|
602
602
|
vel.z *= inertia;
|
|
603
603
|
}
|
|
604
|
-
else if (entity.state.
|
|
604
|
+
else if (entity.state.fallFlying) {
|
|
605
605
|
const { pitch, sinPitch, cosPitch, lookDir } = (0, physicsUtils_1.getLookingVector)(entity.state);
|
|
606
606
|
const horizontalSpeed = Math.sqrt(vel.x * vel.x + vel.z * vel.z);
|
|
607
607
|
const cosPitchSquared = cosPitch * cosPitch;
|
|
@@ -629,7 +629,7 @@ class EntityPhysics {
|
|
|
629
629
|
vel.z *= 0.99;
|
|
630
630
|
this.moveEntity(entity, world, vel.x, vel.y, vel.z);
|
|
631
631
|
if (entity.state.onGround) {
|
|
632
|
-
entity.state.
|
|
632
|
+
entity.state.fallFlying = false;
|
|
633
633
|
}
|
|
634
634
|
}
|
|
635
635
|
else {
|
|
@@ -731,9 +731,9 @@ class EntityPhysics {
|
|
|
731
731
|
entity.state.control.sprint = false;
|
|
732
732
|
}
|
|
733
733
|
}
|
|
734
|
-
entity.state.
|
|
734
|
+
entity.state.fallFlying = entity.state.fallFlying && entity.state.elytraEquipped && !entity.state.onGround && !entity.state.levitation;
|
|
735
735
|
if (entity.state.fireworkRocketDuration > 0) {
|
|
736
|
-
if (!entity.state.
|
|
736
|
+
if (!entity.state.fallFlying) {
|
|
737
737
|
entity.state.fireworkRocketDuration = 0;
|
|
738
738
|
}
|
|
739
739
|
else {
|
|
@@ -9,7 +9,7 @@ class PhysicsWorldSettings {
|
|
|
9
9
|
this.negligeableVelocity = 0.003; // actually 0.005 for 1.8; but seems fine
|
|
10
10
|
this.soulsandSpeed = 0.4;
|
|
11
11
|
this.honeyblockSpeed = 0.4;
|
|
12
|
-
this.honeyblockJumpSpeed = 0.
|
|
12
|
+
this.honeyblockJumpSpeed = 0.5;
|
|
13
13
|
this.ladderMaxSpeed = 0.15;
|
|
14
14
|
this.ladderClimbSpeed = 0.2;
|
|
15
15
|
// public gravity: number = 0.08;
|
|
@@ -21,7 +21,7 @@ export declare class EntityState implements IEntityState {
|
|
|
21
21
|
isInWater: boolean;
|
|
22
22
|
isInLava: boolean;
|
|
23
23
|
isInWeb: boolean;
|
|
24
|
-
|
|
24
|
+
fallFlying: boolean;
|
|
25
25
|
elytraEquipped: boolean;
|
|
26
26
|
isCollidedHorizontally: boolean;
|
|
27
27
|
isCollidedVertically: boolean;
|
|
@@ -44,6 +44,11 @@ export declare class EntityState implements IEntityState {
|
|
|
44
44
|
pose: PlayerPoses;
|
|
45
45
|
fireworkRocketDuration: number;
|
|
46
46
|
supportingBlockPos: Vec3 | null;
|
|
47
|
+
/**
|
|
48
|
+
* Deprecated compatibility alias for fallFlying.
|
|
49
|
+
*/
|
|
50
|
+
get elytraFlying(): boolean;
|
|
51
|
+
set elytraFlying(value: boolean);
|
|
47
52
|
constructor(ctx: IPhysics, height: number, halfWidth: number, pos: Vec3, vel: Vec3, onGround: boolean, yaw: number, pitch: number, control?: ControlStateHandler);
|
|
48
53
|
static CREATE_FROM_BOT(ctx: IPhysics, bot: Bot): EntityState;
|
|
49
54
|
static CREATE_FROM_ENTITY(ctx: IPhysics, entity: Entity): EntityState;
|
|
@@ -12,6 +12,15 @@ const poses_1 = require("./poses");
|
|
|
12
12
|
const prismarine_nbt_1 = __importDefault(require("prismarine-nbt"));
|
|
13
13
|
const emptyVec = new vec3_1.Vec3(0, 0, 0);
|
|
14
14
|
class EntityState {
|
|
15
|
+
/**
|
|
16
|
+
* Deprecated compatibility alias for fallFlying.
|
|
17
|
+
*/
|
|
18
|
+
get elytraFlying() {
|
|
19
|
+
return this.fallFlying;
|
|
20
|
+
}
|
|
21
|
+
set elytraFlying(value) {
|
|
22
|
+
this.fallFlying = value;
|
|
23
|
+
}
|
|
15
24
|
// public effects: Effect[];
|
|
16
25
|
// public statusEffectNames;
|
|
17
26
|
constructor(ctx, height, halfWidth, pos, vel, onGround, yaw, pitch, control = playerControls_1.ControlStateHandler.DEFAULT()) {
|
|
@@ -30,7 +39,7 @@ class EntityState {
|
|
|
30
39
|
this.isInWater = false;
|
|
31
40
|
this.isInLava = false;
|
|
32
41
|
this.isInWeb = false;
|
|
33
|
-
this.
|
|
42
|
+
this.fallFlying = false;
|
|
34
43
|
this.elytraEquipped = false;
|
|
35
44
|
this.isCollidedHorizontally = false;
|
|
36
45
|
this.isCollidedVertically = false;
|
|
@@ -83,7 +92,7 @@ class EntityState {
|
|
|
83
92
|
return this;
|
|
84
93
|
}
|
|
85
94
|
updateFromEntity(entity, all = false) {
|
|
86
|
-
var _a, _b, _c;
|
|
95
|
+
var _a, _b, _c, _d, _e;
|
|
87
96
|
if (all) {
|
|
88
97
|
// most mobs don't have this defined, so ignore it (only self does).
|
|
89
98
|
this.vel = entity.velocity.clone();
|
|
@@ -92,13 +101,13 @@ class EntityState {
|
|
|
92
101
|
this.isInWater = entity.isInWater;
|
|
93
102
|
this.isInLava = entity.isInLava;
|
|
94
103
|
this.isInWeb = entity.isInWeb;
|
|
95
|
-
this.
|
|
104
|
+
this.fallFlying = (_b = (_a = entity.fallFlying) !== null && _a !== void 0 ? _a : entity.elytraFlying) !== null && _b !== void 0 ? _b : false;
|
|
96
105
|
this.isCollidedHorizontally = entity.isCollidedHorizontally;
|
|
97
106
|
this.isCollidedVertically = entity.isCollidedVertically;
|
|
98
107
|
this.sneakCollision = false; //TODO
|
|
99
108
|
this.attributes || (this.attributes = entity.attributes);
|
|
100
|
-
this.elytraEquipped = entity.equipment[4] && ((
|
|
101
|
-
this.
|
|
109
|
+
this.elytraEquipped = entity.equipment[4] && ((_c = entity.equipment[4]) === null || _c === void 0 ? void 0 : _c.name.includes("elytra"));
|
|
110
|
+
this.fallFlying = this.elytraEquipped && this.fallFlying;
|
|
102
111
|
}
|
|
103
112
|
this.pos = entity.position.clone();
|
|
104
113
|
//not sure what to do here, ngl.
|
|
@@ -124,7 +133,7 @@ class EntityState {
|
|
|
124
133
|
const boots = entity.equipment[5];
|
|
125
134
|
if (boots && boots.nbt) {
|
|
126
135
|
const simplifiedNbt = prismarine_nbt_1.default.simplify(boots.nbt);
|
|
127
|
-
const enchantments = (
|
|
136
|
+
const enchantments = (_e = (_d = simplifiedNbt.Enchantments) !== null && _d !== void 0 ? _d : simplifiedNbt.ench) !== null && _e !== void 0 ? _e : [];
|
|
128
137
|
this.depthStrider = this.ctx.getEnchantmentLevel(physicsUtils_1.CheapEnchantments.DEPTH_STRIDER, enchantments);
|
|
129
138
|
}
|
|
130
139
|
else {
|
|
@@ -134,7 +143,7 @@ class EntityState {
|
|
|
134
143
|
return this;
|
|
135
144
|
}
|
|
136
145
|
updateFromRaw(other) {
|
|
137
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
|
146
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
138
147
|
this.onGround = (_a = other.onGround) !== null && _a !== void 0 ? _a : this.onGround;
|
|
139
148
|
this.onClimbable = (_b = other.onClimbable) !== null && _b !== void 0 ? _b : this.onClimbable;
|
|
140
149
|
this.sneakCollision = (_c = other.sneakCollision) !== null && _c !== void 0 ? _c : this.sneakCollision;
|
|
@@ -152,8 +161,8 @@ class EntityState {
|
|
|
152
161
|
this.isInWater = (_q = other.isInWater) !== null && _q !== void 0 ? _q : this.isInWater;
|
|
153
162
|
this.isInLava = (_r = other.isInLava) !== null && _r !== void 0 ? _r : this.isInLava;
|
|
154
163
|
this.isInWeb = (_s = other.isInWeb) !== null && _s !== void 0 ? _s : this.isInWeb;
|
|
155
|
-
this.
|
|
156
|
-
this.elytraEquipped = (
|
|
164
|
+
this.fallFlying = (_u = (_t = other.fallFlying) !== null && _t !== void 0 ? _t : other.elytraFlying) !== null && _u !== void 0 ? _u : this.fallFlying;
|
|
165
|
+
this.elytraEquipped = (_v = other.elytraEquipped) !== null && _v !== void 0 ? _v : this.elytraEquipped;
|
|
157
166
|
return this;
|
|
158
167
|
}
|
|
159
168
|
applyToBot(bot) {
|
|
@@ -170,7 +179,8 @@ class EntityState {
|
|
|
170
179
|
bot.entity.isInWater = this.isInWater;
|
|
171
180
|
bot.entity.isInLava = this.isInLava;
|
|
172
181
|
bot.entity.isInWeb = this.isInWeb;
|
|
173
|
-
bot.entity.
|
|
182
|
+
bot.entity.fallFlying = this.fallFlying;
|
|
183
|
+
bot.entity.elytraFlying = this.fallFlying;
|
|
174
184
|
bot.entity.elytraEquipped = this.elytraEquipped;
|
|
175
185
|
bot.entity.isCollidedHorizontally = this.isCollidedHorizontally;
|
|
176
186
|
bot.entity.isCollidedVertically = this.isCollidedVertically;
|
|
@@ -202,7 +212,7 @@ class EntityState {
|
|
|
202
212
|
other.isInWater = this.isInWater;
|
|
203
213
|
other.isInLava = this.isInLava;
|
|
204
214
|
other.isInWeb = this.isInWeb;
|
|
205
|
-
other.
|
|
215
|
+
other.fallFlying = this.fallFlying;
|
|
206
216
|
other.elytraEquipped = this.elytraEquipped;
|
|
207
217
|
other.fireworkRocketDuration = this.fireworkRocketDuration;
|
|
208
218
|
other.jumpTicks = this.jumpTicks;
|
|
@@ -234,7 +244,7 @@ class EntityState {
|
|
|
234
244
|
this.isInWater = other.isInWater;
|
|
235
245
|
this.isInLava = other.isInLava;
|
|
236
246
|
this.isInWeb = other.isInWeb;
|
|
237
|
-
this.
|
|
247
|
+
this.fallFlying = other.fallFlying;
|
|
238
248
|
this.elytraEquipped = other.elytraEquipped;
|
|
239
249
|
this.fireworkRocketDuration = other.fireworkRocketDuration;
|
|
240
250
|
this.jumpTicks = other.jumpTicks;
|
|
@@ -33,13 +33,13 @@ export declare class PlayerState implements IEntityState {
|
|
|
33
33
|
pos: Vec3;
|
|
34
34
|
vel: Vec3;
|
|
35
35
|
onGround: boolean;
|
|
36
|
+
lastOnGround: boolean;
|
|
36
37
|
onClimbable: boolean;
|
|
37
38
|
isInWater: boolean;
|
|
38
39
|
isUnderWater: boolean;
|
|
39
40
|
isInLava: boolean;
|
|
40
41
|
isUnderLava: boolean;
|
|
41
42
|
isInWeb: boolean;
|
|
42
|
-
elytraFlying: boolean;
|
|
43
43
|
elytraEquipped: boolean;
|
|
44
44
|
fireworkRocketDuration: number;
|
|
45
45
|
isCollidedHorizontally: boolean;
|
|
@@ -103,6 +103,11 @@ export declare class PlayerState implements IEntityState {
|
|
|
103
103
|
* TODO: proper impl.
|
|
104
104
|
*/
|
|
105
105
|
fallFlying: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Deprecated compatibility alias for fallFlying.
|
|
108
|
+
*/
|
|
109
|
+
get elytraFlying(): boolean;
|
|
110
|
+
set elytraFlying(value: boolean);
|
|
106
111
|
/**
|
|
107
112
|
* TODO: proper impl.
|
|
108
113
|
*/
|