@nxg-org/mineflayer-physics-util 1.5.5 → 1.5.7

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.
@@ -294,10 +294,7 @@ class EntityPhysics {
294
294
  if (dz !== oldVelZ)
295
295
  vel.z = 0;
296
296
  if (dy !== oldVelY) {
297
- if (entity.collisionBehavior.blockEffects &&
298
- blockAtFeet &&
299
- blockAtFeet.type === this.slimeBlockId &&
300
- !entity.state.control.sneak) {
297
+ if (entity.collisionBehavior.blockEffects && blockAtFeet && blockAtFeet.type === this.slimeBlockId && !entity.state.control.sneak) {
301
298
  vel.y = -vel.y;
302
299
  }
303
300
  else {
@@ -329,9 +326,7 @@ class EntityPhysics {
329
326
  else if (block.type === this.bubblecolumnId) {
330
327
  const down = !block.metadata;
331
328
  const aboveBlock = world.getBlock(cursor.offset(0, 1, 0));
332
- const bubbleDrag = aboveBlock && aboveBlock.type === 0 /* air */
333
- ? physicsSettings_1.PhysicsSettings.bubbleColumnSurfaceDrag
334
- : physicsSettings_1.PhysicsSettings.bubbleColumnDrag;
329
+ const bubbleDrag = aboveBlock && aboveBlock.type === 0 /* air */ ? physicsSettings_1.PhysicsSettings.bubbleColumnSurfaceDrag : physicsSettings_1.PhysicsSettings.bubbleColumnDrag;
335
330
  if (down) {
336
331
  vel.y = Math.max(bubbleDrag.maxDown, vel.y - bubbleDrag.down);
337
332
  }
@@ -592,6 +587,7 @@ class EntityPhysics {
592
587
  vel.x *= inertia;
593
588
  vel.z *= inertia;
594
589
  }
590
+ // this is player-only.
595
591
  else if (entity.state.elytraFlying) {
596
592
  const { pitch, sinPitch, cosPitch, lookDir } = (0, physicsUtils_1.getLookingVector)(entity.state);
597
593
  const horizontalSpeed = Math.sqrt(vel.x * vel.x + vel.z * vel.z);
@@ -600,20 +596,20 @@ class EntityPhysics {
600
596
  // cosPitch is in [0, 1], so cosPitch > 0.0 is just to protect against
601
597
  // divide by zero errors
602
598
  if (vel.y < 0.0 && cosPitch > 0.0) {
603
- const movingDownSpeedModifier = vel.y * (-0.1) * cosPitchSquared;
604
- vel.x += lookDir.x * movingDownSpeedModifier / cosPitch;
599
+ const movingDownSpeedModifier = vel.y * -0.1 * cosPitchSquared;
600
+ vel.x += (lookDir.x * movingDownSpeedModifier) / cosPitch;
605
601
  vel.y += movingDownSpeedModifier;
606
- vel.z += lookDir.z * movingDownSpeedModifier / cosPitch;
602
+ vel.z += (lookDir.z * movingDownSpeedModifier) / cosPitch;
607
603
  }
608
604
  if (pitch < 0.0 && cosPitch > 0.0) {
609
- const lookDownSpeedModifier = horizontalSpeed * (-sinPitch) * 0.04;
610
- vel.x += -lookDir.x * lookDownSpeedModifier / cosPitch;
605
+ const lookDownSpeedModifier = horizontalSpeed * -sinPitch * 0.04;
606
+ vel.x += (-lookDir.x * lookDownSpeedModifier) / cosPitch;
611
607
  vel.y += lookDownSpeedModifier * 3.2;
612
- vel.z += -lookDir.z * lookDownSpeedModifier / cosPitch;
608
+ vel.z += (-lookDir.z * lookDownSpeedModifier) / cosPitch;
613
609
  }
614
610
  if (cosPitch > 0.0) {
615
- vel.x += (lookDir.x / cosPitch * horizontalSpeed - vel.x) * 0.1;
616
- vel.z += (lookDir.z / cosPitch * horizontalSpeed - vel.z) * 0.1;
611
+ vel.x += ((lookDir.x / cosPitch) * horizontalSpeed - vel.x) * 0.1;
612
+ vel.z += ((lookDir.z / cosPitch) * horizontalSpeed - vel.z) * 0.1;
617
613
  }
618
614
  vel.x *= 0.99;
619
615
  vel.y *= 0.98;
@@ -686,12 +682,11 @@ class EntityPhysics {
686
682
  if (entity.state.jumpTicks > 0)
687
683
  entity.state.jumpTicks--;
688
684
  if (entity.state.isInWater || entity.state.isInLava) {
689
- vel.y += Math.fround(0.4);
685
+ vel.y += 0.04;
690
686
  }
691
687
  else if (entity.state.onGround && entity.state.jumpTicks === 0) {
692
688
  const blockBelow = world.getBlock(entity.position.floored().offset(0, -0.5, 0));
693
- vel.y =
694
- Math.fround(0.42) * (blockBelow && blockBelow.type === this.honeyblockId ? physicsSettings_1.PhysicsSettings.honeyblockJumpSpeed : 1);
689
+ vel.y = Math.fround(0.42) * (blockBelow && blockBelow.type === this.honeyblockId ? physicsSettings_1.PhysicsSettings.honeyblockJumpSpeed : 1);
695
690
  if (entity.state.jumpBoost > 0) {
696
691
  vel.y += 0.1 * entity.state.jumpBoost;
697
692
  }
@@ -707,10 +702,8 @@ class EntityPhysics {
707
702
  entity.state.jumpTicks = 0; // reset autojump cooldown
708
703
  }
709
704
  entity.state.jumpQueued = false;
710
- strafe =
711
- (entity.state.control.left - entity.state.control.right) * 0.98;
712
- forward =
713
- (entity.state.control.forward - entity.state.control.back) * 0.98;
705
+ strafe = (entity.state.control.left - entity.state.control.right) * 0.98;
706
+ forward = (entity.state.control.forward - entity.state.control.back) * 0.98;
714
707
  if (entity.state.control.sneak) {
715
708
  strafe *= physicsSettings_1.PhysicsSettings.sneakSpeed;
716
709
  forward *= physicsSettings_1.PhysicsSettings.sneakSpeed;
@@ -722,7 +715,8 @@ class EntityPhysics {
722
715
  entity.state.control.sprint = false;
723
716
  }
724
717
  }
725
- entity.state.elytraFlying = entity.state.elytraFlying && entity.state.elytraEquipped && !entity.state.onGround && !entity.state.levitation;
718
+ entity.state.elytraFlying =
719
+ entity.state.elytraFlying && entity.state.elytraEquipped && !entity.state.onGround && !entity.state.levitation;
726
720
  if (entity.state.fireworkRocketDuration > 0) {
727
721
  if (!entity.state.elytraFlying) {
728
722
  entity.state.fireworkRocketDuration = 0;
@@ -0,0 +1,79 @@
1
+ import { AABB } from "@nxg-org/mineflayer-util-plugin";
2
+ import md from "minecraft-data";
3
+ import { Block } from "prismarine-block";
4
+ import { Effect } from "prismarine-entity";
5
+ import { Vec3 } from "vec3";
6
+ import { CheapEffects, CheapEnchantments, makeSupportFeature } from "../../util/physicsUtils";
7
+ import { EPhysicsCtx } from "../settings/entityPhysicsCtx";
8
+ import { EntityState } from "../states/entityState";
9
+ import { IPhysics } from "./IPhysics";
10
+ /**
11
+ * Looking at this code, it's too specified towards players.
12
+ *
13
+ * I will eventually split this code into PlayerState and bot.entityState, where bot.entityState contains fewer controls.
14
+ */
15
+ export declare class EntityPhysics implements IPhysics {
16
+ data: md.IndexedData;
17
+ movementSpeedAttribute: any;
18
+ supportFeature: ReturnType<typeof makeSupportFeature>;
19
+ blockSlipperiness: {
20
+ [name: string]: number;
21
+ };
22
+ protected slimeBlockId: number;
23
+ protected soulsandId: number;
24
+ protected honeyblockId: number;
25
+ protected webId: number;
26
+ protected waterId: number;
27
+ protected lavaId: number;
28
+ protected ladderId: number;
29
+ protected vineId: number;
30
+ protected bubblecolumnId: number;
31
+ protected waterLike: Set<number>;
32
+ readonly statusEffectNames: {
33
+ [type in CheapEffects]: string;
34
+ };
35
+ readonly enchantmentNames: {
36
+ [type in CheapEnchantments]: string;
37
+ };
38
+ constructor(mcData: md.IndexedData);
39
+ getEntityBB(entity: EPhysicsCtx, pos: {
40
+ x: number;
41
+ y: number;
42
+ z: number;
43
+ }): AABB;
44
+ setPositionToBB(entity: EPhysicsCtx, bb: AABB, pos: {
45
+ x: number;
46
+ y: number;
47
+ z: number;
48
+ }): void;
49
+ shouldMoveEntity(entity: EPhysicsCtx): boolean;
50
+ getUnderlyingBlockBBs(queryBB: AABB, world: any): AABB[];
51
+ getSurroundingBBs(queryBB: AABB, world: any): AABB[];
52
+ adjustPositionHeight(entity: EPhysicsCtx, pos: Vec3, world: any): void;
53
+ moveEntity(entity: EPhysicsCtx, dx: number, dy: number, dz: number, world: any): void;
54
+ applyHeading(entity: EPhysicsCtx, strafe: number, forward: number, multiplier: number): void;
55
+ getEffectLevel(wantedEffect: CheapEffects, effects: Effect[]): number;
56
+ getEnchantmentLevel(wantedEnchantment: CheapEnchantments, enchantments: any[]): any;
57
+ isOnLadder(pos: {
58
+ x: number;
59
+ y: number;
60
+ z: number;
61
+ }, world: any): any;
62
+ doesNotCollide(entity: EPhysicsCtx, pos: {
63
+ x: number;
64
+ y: number;
65
+ z: number;
66
+ }, world: any): boolean;
67
+ isMaterialInBB(queryBB: AABB, type: number, world: any): boolean;
68
+ getWaterInBB(bb: AABB, world: any): any[];
69
+ getLiquidHeightPcent(block: Block): number;
70
+ getRenderedDepth(block: Block): number;
71
+ getFlow(block: Block, world: any): Vec3;
72
+ isInWaterApplyCurrent(bb: AABB, vel: {
73
+ x: number;
74
+ y: number;
75
+ z: number;
76
+ }, world: any): boolean;
77
+ moveEntityWithHeading(entity: EPhysicsCtx, strafe: number, forward: number, world: any): void;
78
+ simulate(entity: EPhysicsCtx, world: any): EntityState;
79
+ }
@@ -0,0 +1,742 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.EntityPhysics = void 0;
27
+ const mineflayer_util_plugin_1 = require("@nxg-org/mineflayer-util-plugin");
28
+ const vec3_1 = require("vec3");
29
+ const physicsUtils_1 = require("../../util/physicsUtils");
30
+ const attributes = __importStar(require("../info/attributes"));
31
+ const math = __importStar(require("../info/math"));
32
+ const physicsSettings_1 = require("../settings/physicsSettings");
33
+ /**
34
+ * Looking at this code, it's too specified towards players.
35
+ *
36
+ * I will eventually split this code into PlayerState and bot.entityState, where bot.entityState contains fewer controls.
37
+ */
38
+ class EntityPhysics {
39
+ constructor(mcData) {
40
+ this.data = mcData;
41
+ const blocksByName = mcData.blocksByName;
42
+ this.supportFeature = (0, physicsUtils_1.makeSupportFeature)(mcData);
43
+ this.movementSpeedAttribute = this.data.attributesByName.movementSpeed.resource;
44
+ this.blockSlipperiness = {};
45
+ this.slimeBlockId = blocksByName.slime_block ? blocksByName.slime_block.id : blocksByName.slime.id;
46
+ this.blockSlipperiness[this.slimeBlockId] = 0.8;
47
+ this.blockSlipperiness[blocksByName.ice.id] = 0.98;
48
+ this.blockSlipperiness[blocksByName.packed_ice.id] = 0.98;
49
+ // 1.9+
50
+ if (blocksByName.frosted_ice)
51
+ this.blockSlipperiness[blocksByName.frosted_ice.id] = 0.98;
52
+ // 1.13+
53
+ if (blocksByName.blue_ice)
54
+ this.blockSlipperiness[blocksByName.blue_ice.id] = 0.989;
55
+ this.soulsandId = blocksByName.soul_sand.id;
56
+ this.honeyblockId = blocksByName.honey_block ? blocksByName.honey_block.id : -1; // 1.15+
57
+ this.webId = blocksByName.cobweb ? blocksByName.cobweb.id : blocksByName.web.id;
58
+ this.waterId = blocksByName.water.id;
59
+ this.lavaId = blocksByName.lava.id;
60
+ this.ladderId = blocksByName.ladder.id;
61
+ this.vineId = blocksByName.vine.id;
62
+ this.waterLike = new Set();
63
+ if (blocksByName.seagrass)
64
+ this.waterLike.add(blocksByName.seagrass.id); // 1.13+
65
+ if (blocksByName.tall_seagrass)
66
+ this.waterLike.add(blocksByName.tall_seagrass.id); // 1.13+
67
+ if (blocksByName.kelp)
68
+ this.waterLike.add(blocksByName.kelp.id); // 1.13+
69
+ this.bubblecolumnId = blocksByName.bubble_column ? blocksByName.bubble_column.id : -1; // 1.13+
70
+ if (blocksByName.bubble_column)
71
+ this.waterLike.add(this.bubblecolumnId);
72
+ this.statusEffectNames = {}; // mmm, speed.
73
+ this.enchantmentNames = {}; //mmm, double speed.
74
+ let ind = 0;
75
+ const tmp = (0, physicsUtils_1.getStatusEffectNamesForVersion)(this.supportFeature);
76
+ for (const key in tmp) {
77
+ this.statusEffectNames[ind] = tmp[key];
78
+ ind++;
79
+ }
80
+ Object.freeze(this.statusEffectNames);
81
+ ind = 0;
82
+ const tmp1 = (0, physicsUtils_1.getEnchantmentNamesForVersion)(this.supportFeature);
83
+ for (const key in tmp1) {
84
+ this.enchantmentNames[ind] = tmp1[key];
85
+ }
86
+ Object.freeze(this.enchantmentNames);
87
+ }
88
+ getEntityBB(entity, pos) {
89
+ const w = entity.getHalfWidth();
90
+ return new mineflayer_util_plugin_1.AABB(-w, 0, -w, w, entity.height, w).translate(pos.x, pos.y, pos.z);
91
+ }
92
+ setPositionToBB(entity, bb, pos) {
93
+ const halfWidth = entity.getHalfWidth();
94
+ pos.x = bb.minX + halfWidth;
95
+ pos.y = bb.minY;
96
+ pos.z = bb.minZ + halfWidth;
97
+ }
98
+ shouldMoveEntity(entity) {
99
+ return !((entity.state.isCollidedHorizontally || entity.state.isCollidedVertically) &&
100
+ !entity.collisionBehavior.affectedAfterCollision);
101
+ }
102
+ getUnderlyingBlockBBs(queryBB, world /*prismarine-world*/) {
103
+ const surroundingBBs = [];
104
+ const cursor = new vec3_1.Vec3(0, Math.floor(queryBB.minY) - 0.251, 0);
105
+ for (cursor.z = Math.floor(queryBB.minZ); cursor.z <= Math.floor(queryBB.maxZ); cursor.z++) {
106
+ for (cursor.x = Math.floor(queryBB.minX); cursor.x <= Math.floor(queryBB.maxX); cursor.x++) {
107
+ const block = world.getBlock(cursor);
108
+ if (block) {
109
+ const blockPos = block.position;
110
+ for (const shape of block.shapes) {
111
+ const blockBB = new mineflayer_util_plugin_1.AABB(shape[0], shape[1], shape[2], shape[3], shape[4], shape[5]);
112
+ blockBB.translate(blockPos.x, blockPos.y, blockPos.z);
113
+ surroundingBBs.push(blockBB);
114
+ }
115
+ }
116
+ }
117
+ }
118
+ return surroundingBBs;
119
+ }
120
+ getSurroundingBBs(queryBB, world /*prismarine-world*/) {
121
+ const surroundingBBs = [];
122
+ const cursor = new vec3_1.Vec3(0, 0, 0);
123
+ for (cursor.y = Math.floor(queryBB.minY) - 1; cursor.y <= Math.floor(queryBB.maxY); cursor.y++) {
124
+ for (cursor.z = Math.floor(queryBB.minZ); cursor.z <= Math.floor(queryBB.maxZ); cursor.z++) {
125
+ for (cursor.x = Math.floor(queryBB.minX); cursor.x <= Math.floor(queryBB.maxX); cursor.x++) {
126
+ const block = world.getBlock(cursor);
127
+ if (block) {
128
+ const blockPos = block.position;
129
+ for (const shape of block.shapes) {
130
+ const blockBB = new mineflayer_util_plugin_1.AABB(shape[0], shape[1], shape[2], shape[3], shape[4], shape[5]);
131
+ blockBB.translate(blockPos.x, blockPos.y, blockPos.z);
132
+ surroundingBBs.push(blockBB);
133
+ }
134
+ }
135
+ }
136
+ }
137
+ }
138
+ return surroundingBBs;
139
+ }
140
+ adjustPositionHeight(entity, pos, world /*prismarine-world*/) {
141
+ const playerBB = this.getEntityBB(entity, pos);
142
+ const queryBB = playerBB.clone().extend(0, -1, 0);
143
+ const surroundingBBs = this.getSurroundingBBs(queryBB, world);
144
+ let dy = -1;
145
+ for (const blockBB of surroundingBBs) {
146
+ dy = blockBB.computeOffsetY(playerBB, dy);
147
+ }
148
+ pos.y += dy;
149
+ }
150
+ moveEntity(entity, dx, dy, dz, world /*prismarine-world*/) {
151
+ var _a;
152
+ if (!this.shouldMoveEntity(entity)) {
153
+ entity.velocity.set(0, 0, 0);
154
+ return;
155
+ }
156
+ const vel = entity.velocity;
157
+ const pos = entity.position;
158
+ if (entity.state.isInWeb && !((_a = entity.entityType) === null || _a === void 0 ? void 0 : _a.name.includes("arrow"))) {
159
+ dx *= 0.25;
160
+ dy *= 0.05;
161
+ dz *= 0.25;
162
+ vel.x = 0;
163
+ vel.y = 0;
164
+ vel.z = 0;
165
+ entity.state.isInWeb = false;
166
+ }
167
+ const oldOldVelX = dx;
168
+ let oldVelX = dx;
169
+ const oldVelY = dy;
170
+ let oldVelZ = dz;
171
+ const oldOldVelZ = dz;
172
+ if (entity.useControls && entity.state.control.sneak && entity.state.onGround) {
173
+ const step = 0.05;
174
+ // In the 3 loops bellow, y offset should be -1, but that doesnt reproduce vanilla behavior.
175
+ for (; dx !== 0 && this.getSurroundingBBs(this.getEntityBB(entity, pos).translate(dx, 0, 0), world).length === 0; oldVelX = dx) {
176
+ if (dx < step && dx >= -step)
177
+ dx = 0;
178
+ else if (dx > 0)
179
+ dx -= step;
180
+ else
181
+ dx += step;
182
+ }
183
+ for (; dz !== 0 && this.getSurroundingBBs(this.getEntityBB(entity, pos).translate(0, 0, dz), world).length === 0; oldVelZ = dz) {
184
+ if (dz < step && dz >= -step)
185
+ dz = 0;
186
+ else if (dz > 0)
187
+ dz -= step;
188
+ else
189
+ dz += step;
190
+ }
191
+ while (dx !== 0 && dz !== 0 && this.getSurroundingBBs(this.getEntityBB(entity, pos).translate(dx, 0, dz), world).length === 0) {
192
+ if (dx < step && dx >= -step)
193
+ dx = 0;
194
+ else if (dx > 0)
195
+ dx -= step;
196
+ else
197
+ dx += step;
198
+ if (dz < step && dz >= -step)
199
+ dz = 0;
200
+ else if (dz > 0)
201
+ dz -= step;
202
+ else
203
+ dz += step;
204
+ oldVelX = dx;
205
+ oldVelZ = dz;
206
+ }
207
+ }
208
+ let playerBB = this.getEntityBB(entity, pos);
209
+ const queryBB = playerBB.clone().extend(dx, dy, dz);
210
+ const surroundingBBs = this.getSurroundingBBs(queryBB, world);
211
+ const oldBB = playerBB.clone();
212
+ for (const blockBB of surroundingBBs) {
213
+ dy = blockBB.computeOffsetY(playerBB, dy);
214
+ }
215
+ playerBB.translate(0, dy, 0);
216
+ for (const blockBB of surroundingBBs) {
217
+ dx = blockBB.computeOffsetX(playerBB, dx);
218
+ }
219
+ playerBB.translate(dx, 0, 0);
220
+ for (const blockBB of surroundingBBs) {
221
+ dz = blockBB.computeOffsetZ(playerBB, dz);
222
+ }
223
+ playerBB.translate(0, 0, dz);
224
+ // Step on block if height < stepHeight
225
+ if (entity.stepHeight > 0 && (entity.state.onGround || (dy !== oldVelY && oldVelY < 0)) && (dx !== oldVelX || dz !== oldVelZ)) {
226
+ const oldVelXCol = dx;
227
+ const oldVelYCol = dy;
228
+ const oldVelZCol = dz;
229
+ const oldBBCol = playerBB.clone();
230
+ dy = entity.stepHeight;
231
+ const queryBB = oldBB.clone().extend(oldVelX, dy, oldVelZ);
232
+ const surroundingBBs = this.getSurroundingBBs(queryBB, world);
233
+ const BB1 = oldBB.clone();
234
+ const BB2 = oldBB.clone();
235
+ const BB_XZ = BB1.clone().extend(dx, 0, dz);
236
+ let dy1 = dy;
237
+ let dy2 = dy;
238
+ for (const blockBB of surroundingBBs) {
239
+ dy1 = blockBB.computeOffsetY(BB_XZ, dy1);
240
+ dy2 = blockBB.computeOffsetY(BB2, dy2);
241
+ }
242
+ BB1.translate(0, dy1, 0);
243
+ BB2.translate(0, dy2, 0);
244
+ let dx1 = oldVelX;
245
+ let dx2 = oldVelX;
246
+ for (const blockBB of surroundingBBs) {
247
+ dx1 = blockBB.computeOffsetX(BB1, dx1);
248
+ dx2 = blockBB.computeOffsetX(BB2, dx2);
249
+ }
250
+ BB1.translate(dx1, 0, 0);
251
+ BB2.translate(dx2, 0, 0);
252
+ let dz1 = oldVelZ;
253
+ let dz2 = oldVelZ;
254
+ for (const blockBB of surroundingBBs) {
255
+ dz1 = blockBB.computeOffsetZ(BB1, dz1);
256
+ dz2 = blockBB.computeOffsetZ(BB2, dz2);
257
+ }
258
+ BB1.translate(0, 0, dz1);
259
+ BB2.translate(0, 0, dz2);
260
+ const norm1 = dx1 * dx1 + dz1 * dz1;
261
+ const norm2 = dx2 * dx2 + dz2 * dz2;
262
+ if (norm1 > norm2) {
263
+ dx = dx1;
264
+ dy = -dy1;
265
+ dz = dz1;
266
+ playerBB = BB1;
267
+ }
268
+ else {
269
+ dx = dx2;
270
+ dy = -dy2;
271
+ dz = dz2;
272
+ playerBB = BB2;
273
+ }
274
+ for (const blockBB of surroundingBBs) {
275
+ dy = blockBB.computeOffsetY(playerBB, dy);
276
+ }
277
+ playerBB.translate(0, dy, 0);
278
+ if (oldVelXCol * oldVelXCol + oldVelZCol * oldVelZCol >= dx * dx + dz * dz) {
279
+ dx = oldVelXCol;
280
+ dy = oldVelYCol;
281
+ dz = oldVelZCol;
282
+ playerBB = oldBBCol;
283
+ }
284
+ }
285
+ // Update flags
286
+ this.setPositionToBB(entity, playerBB, pos);
287
+ entity.state.sneakCollision = dx !== oldOldVelX || dz !== oldOldVelZ;
288
+ entity.state.isCollidedHorizontally = dx !== oldVelX || dz !== oldVelZ;
289
+ entity.state.isCollidedVertically = dy !== oldVelY;
290
+ entity.state.onGround = entity.state.isCollidedVertically && oldVelY < 0;
291
+ const blockAtFeet = world.getBlock(pos.offset(0, -0.2, 0));
292
+ if (dx !== oldVelX)
293
+ vel.x = 0;
294
+ if (dz !== oldVelZ)
295
+ vel.z = 0;
296
+ if (dy !== oldVelY) {
297
+ if (entity.collisionBehavior.blockEffects &&
298
+ blockAtFeet &&
299
+ blockAtFeet.type === this.slimeBlockId &&
300
+ !entity.state.control.sneak) {
301
+ vel.y = -vel.y;
302
+ }
303
+ else {
304
+ vel.y = 0;
305
+ }
306
+ }
307
+ // Finally, apply block collisions (web, soulsand...)
308
+ playerBB.contract(0.001, 0.001, 0.001);
309
+ const cursor = new vec3_1.Vec3(0, 0, 0);
310
+ for (cursor.y = Math.floor(playerBB.minY); cursor.y <= Math.floor(playerBB.maxY); cursor.y++) {
311
+ for (cursor.z = Math.floor(playerBB.minZ); cursor.z <= Math.floor(playerBB.maxZ); cursor.z++) {
312
+ for (cursor.x = Math.floor(playerBB.minX); cursor.x <= Math.floor(playerBB.maxX); cursor.x++) {
313
+ const block = world.getBlock(cursor);
314
+ if (block) {
315
+ if (entity.collisionBehavior.blockEffects && this.supportFeature("velocityBlocksOnCollision")) {
316
+ if (block.type === this.soulsandId) {
317
+ vel.x *= physicsSettings_1.PhysicsSettings.soulsandSpeed;
318
+ vel.z *= physicsSettings_1.PhysicsSettings.soulsandSpeed;
319
+ }
320
+ else if (block.type === this.honeyblockId) {
321
+ vel.x *= physicsSettings_1.PhysicsSettings.honeyblockSpeed;
322
+ vel.z *= physicsSettings_1.PhysicsSettings.honeyblockSpeed;
323
+ }
324
+ }
325
+ if (block.type === this.webId) {
326
+ entity.state.isInWeb = true;
327
+ }
328
+ // no blockEffects check here, apparently all entities are affected by this.
329
+ else if (block.type === this.bubblecolumnId) {
330
+ const down = !block.metadata;
331
+ const aboveBlock = world.getBlock(cursor.offset(0, 1, 0));
332
+ const bubbleDrag = aboveBlock && aboveBlock.type === 0 /* air */
333
+ ? physicsSettings_1.PhysicsSettings.bubbleColumnSurfaceDrag
334
+ : physicsSettings_1.PhysicsSettings.bubbleColumnDrag;
335
+ if (down) {
336
+ vel.y = Math.max(bubbleDrag.maxDown, vel.y - bubbleDrag.down);
337
+ }
338
+ else {
339
+ vel.y = Math.min(bubbleDrag.maxUp, vel.y + bubbleDrag.up);
340
+ }
341
+ }
342
+ }
343
+ }
344
+ }
345
+ }
346
+ if (entity.collisionBehavior.blockEffects && this.supportFeature("velocityBlocksOnTop")) {
347
+ const blockBelow = world.getBlock(entity.position.floored().offset(0, -0.5, 0));
348
+ if (blockBelow) {
349
+ if (blockBelow.type === this.soulsandId) {
350
+ vel.x *= physicsSettings_1.PhysicsSettings.soulsandSpeed;
351
+ vel.z *= physicsSettings_1.PhysicsSettings.soulsandSpeed;
352
+ }
353
+ else if (blockBelow.type === this.honeyblockId) {
354
+ vel.x *= physicsSettings_1.PhysicsSettings.honeyblockSpeed;
355
+ vel.z *= physicsSettings_1.PhysicsSettings.honeyblockSpeed;
356
+ }
357
+ }
358
+ }
359
+ }
360
+ applyHeading(entity, strafe, forward, multiplier) {
361
+ if (!this.shouldMoveEntity(entity)) {
362
+ entity.velocity.set(0, 0, 0);
363
+ return;
364
+ }
365
+ let speed = Math.sqrt(strafe * strafe + forward * forward);
366
+ if (speed < 0.01)
367
+ return;
368
+ speed = multiplier / Math.max(speed, 1);
369
+ strafe *= speed;
370
+ forward *= speed;
371
+ const yaw = Math.PI - entity.state.yaw;
372
+ const sin = Math.sin(yaw);
373
+ const cos = Math.cos(yaw);
374
+ const vel = entity.velocity;
375
+ vel.x += strafe * cos - forward * sin;
376
+ vel.z += forward * cos + strafe * sin;
377
+ }
378
+ getEffectLevel(wantedEffect, effects) {
379
+ const effectDescriptor = this.data.effectsByName[this.statusEffectNames[wantedEffect]];
380
+ if (!effectDescriptor) {
381
+ return 0;
382
+ }
383
+ const effectInfo = effects[effectDescriptor.id];
384
+ if (!effectInfo) {
385
+ return 0;
386
+ }
387
+ return effectInfo.amplifier + 1;
388
+ }
389
+ getEnchantmentLevel(wantedEnchantment, enchantments) {
390
+ const enchantmentName = this.enchantmentNames[wantedEnchantment];
391
+ const enchantmentDescriptor = this.data.enchantmentsByName[enchantmentName];
392
+ if (!enchantmentDescriptor) {
393
+ return 0;
394
+ }
395
+ for (const enchInfo of enchantments) {
396
+ if (typeof enchInfo.id === "string") {
397
+ if (enchInfo.id.includes(enchantmentName)) {
398
+ return enchInfo.lvl;
399
+ }
400
+ }
401
+ else if (enchInfo.id === enchantmentDescriptor.id) {
402
+ return enchInfo.lvl;
403
+ }
404
+ }
405
+ return 0;
406
+ }
407
+ isOnLadder(pos, world /*prismarine-world*/) {
408
+ const block = world.getBlock(pos);
409
+ return block && (block.type === this.ladderId || block.type === this.vineId);
410
+ }
411
+ doesNotCollide(entity, pos, world /*prismarine-world*/) {
412
+ const pBB = this.getEntityBB(entity, pos);
413
+ return !this.getSurroundingBBs(pBB, world).some((x) => pBB.intersects(x)) && this.getWaterInBB(pBB, world).length === 0;
414
+ }
415
+ isMaterialInBB(queryBB, type, world /*prismarine-world*/) {
416
+ const cursor = new vec3_1.Vec3(0, 0, 0);
417
+ for (cursor.y = Math.floor(queryBB.minY); cursor.y <= Math.floor(queryBB.maxY); cursor.y++) {
418
+ for (cursor.z = Math.floor(queryBB.minZ); cursor.z <= Math.floor(queryBB.maxZ); cursor.z++) {
419
+ for (cursor.x = Math.floor(queryBB.minX); cursor.x <= Math.floor(queryBB.maxX); cursor.x++) {
420
+ const block = world.getBlock(cursor);
421
+ if (block && block.type === type)
422
+ return true;
423
+ }
424
+ }
425
+ }
426
+ return false;
427
+ }
428
+ getWaterInBB(bb, world /*prismarine-world*/) {
429
+ const waterBlocks = [];
430
+ const cursor = new vec3_1.Vec3(0, 0, 0);
431
+ for (cursor.y = Math.floor(bb.minY); cursor.y <= Math.floor(bb.maxY); cursor.y++) {
432
+ for (cursor.z = Math.floor(bb.minZ); cursor.z <= Math.floor(bb.maxZ); cursor.z++) {
433
+ for (cursor.x = Math.floor(bb.minX); cursor.x <= Math.floor(bb.maxX); cursor.x++) {
434
+ const block = world.getBlock(cursor);
435
+ if (block && (block.type === this.waterId || this.waterLike.has(block.type) || block.getProperties().waterlogged)) {
436
+ const waterLevel = cursor.y + 1 - this.getLiquidHeightPcent(block);
437
+ if (Math.ceil(bb.maxY) >= waterLevel)
438
+ waterBlocks.push(block);
439
+ }
440
+ }
441
+ }
442
+ }
443
+ return waterBlocks;
444
+ }
445
+ getLiquidHeightPcent(block) {
446
+ return (this.getRenderedDepth(block) + 1) / 9;
447
+ }
448
+ getRenderedDepth(block) {
449
+ if (!block)
450
+ return -1;
451
+ if (this.waterLike.has(block.type))
452
+ return 0;
453
+ if (block.getProperties().waterlogged)
454
+ return 0;
455
+ if (block.type !== this.waterId)
456
+ return -1;
457
+ const meta = block.metadata;
458
+ return meta >= 8 ? 0 : meta;
459
+ }
460
+ getFlow(block, world /*prismarine-world*/) {
461
+ const curlevel = this.getRenderedDepth(block);
462
+ const flow = new vec3_1.Vec3(0, 0, 0);
463
+ for (const [dx, dz] of [
464
+ [0, 1],
465
+ [-1, 0],
466
+ [0, -1],
467
+ [1, 0],
468
+ ]) {
469
+ const adjBlock = world.getBlock(block.position.offset(dx, 0, dz));
470
+ const adjLevel = this.getRenderedDepth(adjBlock);
471
+ if (adjLevel < 0) {
472
+ if (adjBlock && adjBlock.boundingBox !== "empty") {
473
+ const adjLevel = this.getRenderedDepth(world.getBlock(block.position.offset(dx, -1, dz)));
474
+ if (adjLevel >= 0) {
475
+ const f = adjLevel - (curlevel - 8);
476
+ flow.x += dx * f;
477
+ flow.z += dz * f;
478
+ }
479
+ }
480
+ }
481
+ else {
482
+ const f = adjLevel - curlevel;
483
+ flow.x += dx * f;
484
+ flow.z += dz * f;
485
+ }
486
+ }
487
+ if (block.metadata >= 8) {
488
+ for (const [dx, dz] of [
489
+ [0, 1],
490
+ [-1, 0],
491
+ [0, -1],
492
+ [1, 0],
493
+ ]) {
494
+ const adjBlock = world.getBlock(block.position.offset(dx, 0, dz));
495
+ const adjUpBlock = world.getBlock(block.position.offset(dx, 1, dz));
496
+ if ((adjBlock && adjBlock.boundingBox !== "empty") || (adjUpBlock && adjUpBlock.boundingBox !== "empty")) {
497
+ flow.normalize().translate(0, -6, 0);
498
+ }
499
+ }
500
+ }
501
+ return flow.normalize();
502
+ }
503
+ isInWaterApplyCurrent(bb, vel, world /*prismarine-world*/) {
504
+ const acceleration = new vec3_1.Vec3(0, 0, 0);
505
+ const waterBlocks = this.getWaterInBB(bb, world);
506
+ const isInWater = waterBlocks.length > 0;
507
+ for (const block of waterBlocks) {
508
+ const flow = this.getFlow(block, world);
509
+ acceleration.add(flow);
510
+ }
511
+ const len = acceleration.norm();
512
+ if (len > 0) {
513
+ vel.x += (acceleration.x / len) * 0.014;
514
+ vel.y += (acceleration.y / len) * 0.014;
515
+ vel.z += (acceleration.z / len) * 0.014;
516
+ }
517
+ return isInWater;
518
+ }
519
+ moveEntityWithHeading(entity, strafe, forward, world /*prismarine-world*/) {
520
+ if (!this.shouldMoveEntity(entity)) {
521
+ entity.velocity.set(0, 0, 0);
522
+ return;
523
+ }
524
+ const vel = entity.velocity;
525
+ const pos = entity.position;
526
+ const gravityMultiplier = vel.y <= 0 && entity.state.slowFalling > 0 ? physicsSettings_1.PhysicsSettings.slowFalling : 1;
527
+ // Unsure how to handle this w/ other entities.
528
+ if (!entity.state.isInWater && !entity.state.isInLava) {
529
+ let acceleration = entity.airborneAccel;
530
+ let inertia = entity.airborneInertia;
531
+ const blockUnder = world.getBlock(pos.offset(0, -1, 0));
532
+ if (entity.state.onGround && blockUnder) {
533
+ let playerSpeedAttribute;
534
+ if (entity.state.attributes && entity.state.attributes[this.movementSpeedAttribute]) {
535
+ // Use server-side player attributes
536
+ playerSpeedAttribute = entity.state.attributes[this.movementSpeedAttribute];
537
+ }
538
+ else {
539
+ // Create an attribute if the player does not have it
540
+ //TODO: Generalize to all entities.
541
+ playerSpeedAttribute = attributes.createAttributeValue(physicsSettings_1.PhysicsSettings.playerSpeed);
542
+ }
543
+ // Client-side sprinting (don't rely on server-side sprinting)
544
+ // setSprinting in LivingEntity.java
545
+ //TODO: Generalize to all entities.
546
+ playerSpeedAttribute = attributes.deleteAttributeModifier(playerSpeedAttribute, physicsSettings_1.PhysicsSettings.sprintingUUID); // always delete sprinting (if it exists)
547
+ if (entity.state.control.sprint) {
548
+ if (!attributes.checkAttributeModifier(playerSpeedAttribute, physicsSettings_1.PhysicsSettings.sprintingUUID)) {
549
+ playerSpeedAttribute = attributes.addAttributeModifier(playerSpeedAttribute, {
550
+ uuid: physicsSettings_1.PhysicsSettings.sprintingUUID,
551
+ amount: physicsSettings_1.PhysicsSettings.sprintSpeed,
552
+ operation: 2,
553
+ });
554
+ }
555
+ }
556
+ // Calculate what the speed is (0.1 if no modification)
557
+ const attributeSpeed = attributes.getAttributeValue(playerSpeedAttribute);
558
+ inertia = (this.blockSlipperiness[blockUnder.type] || physicsSettings_1.PhysicsSettings.defaultSlipperiness) * 0.91;
559
+ acceleration = attributeSpeed * (0.1627714 / (inertia * inertia * inertia));
560
+ if (acceleration < 0)
561
+ acceleration = 0; // acceleration should not be negative
562
+ }
563
+ this.applyHeading(entity, strafe, forward, acceleration);
564
+ if (entity.collisionBehavior.blockEffects && this.isOnLadder(pos, world)) {
565
+ vel.x = math.clamp(-physicsSettings_1.PhysicsSettings.ladderMaxSpeed, vel.x, physicsSettings_1.PhysicsSettings.ladderMaxSpeed);
566
+ vel.z = math.clamp(-physicsSettings_1.PhysicsSettings.ladderMaxSpeed, vel.z, physicsSettings_1.PhysicsSettings.ladderMaxSpeed);
567
+ vel.y = Math.max(vel.y, entity.state.control.sneak ? 0 : -physicsSettings_1.PhysicsSettings.ladderMaxSpeed);
568
+ }
569
+ this.moveEntity(entity, vel.x, vel.y, vel.z, world);
570
+ if (entity.collisionBehavior.blockEffects &&
571
+ this.isOnLadder(pos, world) &&
572
+ (entity.state.isCollidedHorizontally || (this.supportFeature("climbUsingJump") && entity.state.control.jump))) {
573
+ vel.y = physicsSettings_1.PhysicsSettings.ladderClimbSpeed; // climb ladder
574
+ }
575
+ // Not adding an additional function call. No point.
576
+ if (entity.gravityThenDrag) {
577
+ // Apply gravity, then air drag.
578
+ if (entity.state.levitation > 0)
579
+ vel.y += (0.05 * entity.state.levitation - vel.y) * 0.2;
580
+ else
581
+ vel.y -= entity.gravity * gravityMultiplier;
582
+ vel.y *= entity.airdrag;
583
+ }
584
+ else {
585
+ // Apply airdrag, then gravity.
586
+ vel.y *= entity.airdrag;
587
+ if (entity.state.levitation > 0)
588
+ vel.y += (0.05 * entity.state.levitation - vel.y) * 0.2;
589
+ else
590
+ vel.y -= entity.gravity * gravityMultiplier;
591
+ }
592
+ vel.x *= inertia;
593
+ vel.z *= inertia;
594
+ }
595
+ else if (entity.state.elytraFlying) {
596
+ const { pitch, sinPitch, cosPitch, lookDir } = (0, physicsUtils_1.getLookingVector)(entity.state);
597
+ const horizontalSpeed = Math.sqrt(vel.x * vel.x + vel.z * vel.z);
598
+ const cosPitchSquared = cosPitch * cosPitch;
599
+ vel.y += entity.gravity * gravityMultiplier * (-1.0 + cosPitchSquared * 0.75);
600
+ // cosPitch is in [0, 1], so cosPitch > 0.0 is just to protect against
601
+ // divide by zero errors
602
+ if (vel.y < 0.0 && cosPitch > 0.0) {
603
+ const movingDownSpeedModifier = vel.y * (-0.1) * cosPitchSquared;
604
+ vel.x += lookDir.x * movingDownSpeedModifier / cosPitch;
605
+ vel.y += movingDownSpeedModifier;
606
+ vel.z += lookDir.z * movingDownSpeedModifier / cosPitch;
607
+ }
608
+ if (pitch < 0.0 && cosPitch > 0.0) {
609
+ const lookDownSpeedModifier = horizontalSpeed * (-sinPitch) * 0.04;
610
+ vel.x += -lookDir.x * lookDownSpeedModifier / cosPitch;
611
+ vel.y += lookDownSpeedModifier * 3.2;
612
+ vel.z += -lookDir.z * lookDownSpeedModifier / cosPitch;
613
+ }
614
+ if (cosPitch > 0.0) {
615
+ vel.x += (lookDir.x / cosPitch * horizontalSpeed - vel.x) * 0.1;
616
+ vel.z += (lookDir.z / cosPitch * horizontalSpeed - vel.z) * 0.1;
617
+ }
618
+ vel.x *= 0.99;
619
+ vel.y *= 0.98;
620
+ vel.z *= 0.99;
621
+ this.moveEntity(entity, world, vel.x, vel.y, vel.z);
622
+ if (entity.state.onGround) {
623
+ entity.state.elytraFlying = false;
624
+ }
625
+ }
626
+ else {
627
+ // Water / Lava movement
628
+ const lastY = pos.y;
629
+ let acceleration = entity.liquidAccel;
630
+ const inertia = entity.state.isInWater ? entity.waterInertia : entity.lavaInertia;
631
+ let horizontalInertia = inertia;
632
+ if (entity.state.isInWater) {
633
+ let strider = Math.min(entity.state.depthStrider, 3);
634
+ if (!entity.state.onGround) {
635
+ strider *= 0.5;
636
+ }
637
+ if (strider > 0) {
638
+ horizontalInertia += ((0.546 - horizontalInertia) * strider) / 3;
639
+ acceleration += ((0.7 - acceleration) * strider) / 3;
640
+ }
641
+ if (entity.state.dolphinsGrace > 0)
642
+ horizontalInertia = 0.96;
643
+ }
644
+ this.applyHeading(entity, strafe, forward, acceleration);
645
+ this.moveEntity(entity, vel.x, vel.y, vel.z, world);
646
+ if (entity.gravityThenDrag) {
647
+ vel.y -= (entity.state.isInWater ? entity.waterGravity : entity.lavaGravity) * gravityMultiplier;
648
+ vel.y *= inertia;
649
+ }
650
+ else {
651
+ vel.y *= inertia;
652
+ vel.y -= (entity.state.isInWater ? entity.waterGravity : entity.lavaGravity) * gravityMultiplier;
653
+ }
654
+ vel.x *= horizontalInertia;
655
+ vel.z *= horizontalInertia;
656
+ if (entity.state.isCollidedHorizontally &&
657
+ this.doesNotCollide(entity, pos.offset(vel.x, vel.y + 0.6 - pos.y + lastY, vel.z), world)) {
658
+ vel.y = physicsSettings_1.PhysicsSettings.outOfLiquidImpulse; // jump out of liquid
659
+ }
660
+ }
661
+ }
662
+ simulate(entity, world /*prismarine-world*/) {
663
+ if (!this.shouldMoveEntity(entity)) {
664
+ entity.velocity.set(0, 0, 0);
665
+ return entity.state;
666
+ }
667
+ const vel = entity.velocity;
668
+ const pos = entity.position;
669
+ const waterBB = this.getEntityBB(entity, pos).contract(0.001, 0.401, 0.001);
670
+ const lavaBB = this.getEntityBB(entity, pos).contract(0.1, 0.4, 0.1);
671
+ // assume that if we shouldn't move entity, isInWater and isInLava are already properly set.
672
+ entity.state.isInWater = this.isInWaterApplyCurrent(waterBB, vel, world);
673
+ entity.state.isInLava = this.isMaterialInBB(lavaBB, this.lavaId, world);
674
+ // Reset velocity component if it falls under the threshold
675
+ if (Math.abs(vel.x) < physicsSettings_1.PhysicsSettings.negligeableVelocity)
676
+ vel.x = 0;
677
+ if (Math.abs(vel.y) < physicsSettings_1.PhysicsSettings.negligeableVelocity)
678
+ vel.y = 0;
679
+ if (Math.abs(vel.z) < physicsSettings_1.PhysicsSettings.negligeableVelocity)
680
+ vel.z = 0;
681
+ let strafe = 0;
682
+ let forward = 0;
683
+ // Handle inputs
684
+ if (entity.useControls) {
685
+ if (entity.state.control.jump || entity.state.jumpQueued) {
686
+ if (entity.state.jumpTicks > 0)
687
+ entity.state.jumpTicks--;
688
+ if (entity.state.isInWater || entity.state.isInLava) {
689
+ vel.y += 0.04; // according to prismarine-physics
690
+ }
691
+ else if (entity.state.onGround && entity.state.jumpTicks === 0) {
692
+ const blockBelow = world.getBlock(entity.position.floored().offset(0, -0.5, 0));
693
+ vel.y =
694
+ Math.fround(0.42) * (blockBelow && blockBelow.type === this.honeyblockId ? physicsSettings_1.PhysicsSettings.honeyblockJumpSpeed : 1);
695
+ if (entity.state.jumpBoost > 0) {
696
+ vel.y += 0.1 * entity.state.jumpBoost;
697
+ }
698
+ if (entity.state.control.sprint) {
699
+ const yaw = Math.PI - entity.state.yaw;
700
+ vel.x -= Math.sin(yaw) * 0.2;
701
+ vel.z += Math.cos(yaw) * 0.2;
702
+ }
703
+ entity.state.jumpTicks = physicsSettings_1.PhysicsSettings.autojumpCooldown;
704
+ }
705
+ }
706
+ else {
707
+ entity.state.jumpTicks = 0; // reset autojump cooldown
708
+ }
709
+ entity.state.jumpQueued = false;
710
+ strafe =
711
+ (entity.state.control.left - entity.state.control.right) * 0.98;
712
+ forward =
713
+ (entity.state.control.forward - entity.state.control.back) * 0.98;
714
+ if (entity.state.control.sneak) {
715
+ strafe *= physicsSettings_1.PhysicsSettings.sneakSpeed;
716
+ forward *= physicsSettings_1.PhysicsSettings.sneakSpeed;
717
+ entity.state.control.sprint = false;
718
+ }
719
+ if (entity.state.isUsingItem) {
720
+ strafe *= physicsSettings_1.PhysicsSettings.usingItemSpeed;
721
+ forward *= physicsSettings_1.PhysicsSettings.usingItemSpeed;
722
+ entity.state.control.sprint = false;
723
+ }
724
+ }
725
+ entity.state.elytraFlying = entity.state.elytraFlying && entity.state.elytraEquipped && !entity.state.onGround && !entity.state.levitation;
726
+ if (entity.state.fireworkRocketDuration > 0) {
727
+ if (!entity.state.elytraFlying) {
728
+ entity.state.fireworkRocketDuration = 0;
729
+ }
730
+ else {
731
+ const { lookDir } = (0, physicsUtils_1.getLookingVector)(entity.state);
732
+ vel.x += lookDir.x * 0.1 + (lookDir.x * 1.5 - vel.x) * 0.5;
733
+ vel.y += lookDir.y * 0.1 + (lookDir.y * 1.5 - vel.y) * 0.5;
734
+ vel.z += lookDir.z * 0.1 + (lookDir.z * 1.5 - vel.z) * 0.5;
735
+ --entity.state.fireworkRocketDuration;
736
+ }
737
+ }
738
+ this.moveEntityWithHeading(entity, strafe, forward, world);
739
+ return entity.state;
740
+ }
741
+ }
742
+ exports.EntityPhysics = EntityPhysics;
@@ -96,6 +96,8 @@ export declare class EntityState implements EntityStateBuilder {
96
96
  * @returns AABB
97
97
  */
98
98
  getAABB(): AABB;
99
+ lookAt(vec3: Vec3): void;
100
+ look(yaw: number, pitch: number): void;
99
101
  getUnderlyingBlockBBs(world: any): AABB[];
100
102
  getSurroundingBBs(world: any): AABB[];
101
103
  }
@@ -258,6 +258,17 @@ class EntityState {
258
258
  const w = this.halfWidth;
259
259
  return new mineflayer_util_plugin_1.AABB(this.pos.x - w, this.pos.y, this.pos.z - w, this.pos.x + w, this.pos.y + this.height, this.pos.z + w);
260
260
  }
261
+ lookAt(vec3) {
262
+ const dx = vec3.x - this.pos.x;
263
+ const dy = vec3.y - this.pos.y;
264
+ const dz = vec3.z - this.pos.z;
265
+ this.yaw = Math.atan2(dz, dx) * 180 / Math.PI - 90;
266
+ this.pitch = -Math.atan2(dy, Math.sqrt(dx * dx + dz * dz)) * 180 / Math.PI;
267
+ }
268
+ look(yaw, pitch) {
269
+ this.yaw = yaw;
270
+ this.pitch = pitch;
271
+ }
261
272
  getUnderlyingBlockBBs(world /*prismarine-world*/) {
262
273
  const queryBB = this.getAABB();
263
274
  return this.ctx.getUnderlyingBlockBBs(queryBB, world);
@@ -26,6 +26,7 @@ export declare class EntityDimensions {
26
26
  export declare class PlayerState implements EntityStateBuilder {
27
27
  readonly bot: Bot;
28
28
  height: number;
29
+ eyeHeight: number;
29
30
  halfWidth: number;
30
31
  pos: Vec3;
31
32
  vel: Vec3;
@@ -72,7 +72,8 @@ exports.EntityDimensions = EntityDimensions;
72
72
  class PlayerState {
73
73
  constructor(ctx, bot, control) {
74
74
  var _a, _b, _c, _d, _e;
75
- this.height = 1.62;
75
+ this.height = 1.8;
76
+ this.eyeHeight = 1.62;
76
77
  this.halfWidth = 0.3;
77
78
  this.supportFeature = (0, physicsUtils_1.makeSupportFeature)(ctx.data);
78
79
  this.ctx = ctx;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nxg-org/mineflayer-physics-util",
3
- "version": "1.5.5",
3
+ "version": "1.5.7",
4
4
  "description": "Provides functionality for more accurate entity and projectile tracking.",
5
5
  "keywords": [
6
6
  "mineflayer",
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "devDependencies": {
27
27
  "expect": "^29.5.0",
28
- "mineflayer": "^4.17.0",
28
+ "mineflayer": "^4.18.0",
29
29
  "mineflayer-pathfinder": "^2.4.4",
30
30
  "prismarine-entity": "^2.4.0",
31
31
  "typescript": "^4.5.5"
@@ -11,12 +11,22 @@ const bot: Bot = createBot({
11
11
  username: "testingbot"
12
12
  })
13
13
 
14
- bot.once('spawn', () => {
14
+ bot.once('spawn', async () => {
15
15
  bot.loadPlugin(loader)
16
16
  bot.loadPlugin(pathfinder)
17
+ await bot.waitForTicks(20)
18
+ bot.chat('rocky1928')
17
19
  })
18
20
 
19
21
 
22
+ const rl = require('readline').createInterface({
23
+ input: process.stdin,
24
+ output: process.stdout
25
+
26
+ })
27
+
28
+ rl.on('line', (line: any) => bot.chat(line))
29
+
20
30
  bot.on("chat", (user, message) => {
21
31
  const [cmd, ...args] = message.split(' ')
22
32
  const author = bot.nearestEntity(e=>e.username===user);
@@ -28,14 +38,24 @@ bot.on("chat", (user, message) => {
28
38
  bot.physics = new Physics(bot.registry, bot.world);
29
39
  break;
30
40
  case "new":
31
- // rough patching in custom physics for the time being.
32
- const fuck0 = new EntityPhysics(bot.registry)
33
- bot.physics = fuck0 as any;
34
- (bot.physics as any).simulatePlayer = (state: EntityState, world: any /* prismarine-world*/) => {
35
- const entity = EPhysicsCtx.FROM_ENTITY_STATE(fuck0, state)
36
- return fuck0.simulate(entity, world);
37
- }
41
+ const val = new EntityPhysics(bot.registry)
42
+ const oldSim = (bot.physics as any).simulatePlayer;
43
+
44
+ (EntityState.prototype as any).apply = function (bot: Bot) {
45
+ this.applyToBot(bot);
46
+ };
47
+ (bot.physics as any).simulatePlayer = (...args: any[]) => {
48
+ // bot.jumpTicks = 0
49
+ const ctx = EPhysicsCtx.FROM_BOT(val, bot)
50
+ ctx.state.jumpTicks = 0; // allow immediate jumping
51
+ // ctx.state.control.set('sneak', true)
52
+ return val.simulate(ctx, bot.world);
53
+ return oldSim(...args);
54
+ };
38
55
  break;
56
+ case "jump":
57
+ bot.setControlState('jump', true)
58
+ break
39
59
  case "come":
40
60
  if (!author) return bot.chat(`Cannot see ${user}!`);
41
61
  const goal0 = new goals.GoalNear(author.position.x, author.position.y, author.position.z, 3);
@@ -48,6 +68,7 @@ bot.on("chat", (user, message) => {
48
68
  break;
49
69
  case "stop":
50
70
  bot.pathfinder.stop();
71
+ bot.clearControlStates();
51
72
  bot.chat('Stopped!')
52
73
  break;
53
74