@nxg-org/mineflayer-physics-util 1.8.14 → 1.8.15

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.
@@ -1,354 +1,354 @@
1
- import { describe, it, beforeEach } from "mocha";
2
- import expect from "expect";
3
- import { Vec3 } from "vec3";
4
- import md from "minecraft-data";
5
- import block, { Block as PBlock } from "prismarine-block";
6
- import { applyMdToNewEntity } from "../src/util/physicsUtils";
7
- import { EPhysicsCtx, PhysicsWorldSettings } from "../src/physics/settings";
8
- import { ControlStateHandler } from "../src/physics/player";
9
- import { BotcraftPhysics, EntityPhysics, IPhysics } from "../src/physics/engines";
10
- import { initSetup } from "../src/index";
11
- import { PlayerState } from "../src/physics/states";
12
- import { Bot, ControlState } from "mineflayer";
13
- import { AABB } from "@nxg-org/mineflayer-util-plugin";
14
-
15
- const version = "1.12.2";
16
- const mcData = md(version);
17
- const Engine = BotcraftPhysics;
18
- const Block = block(version) as typeof PBlock;
19
-
20
- const groundLevel = 67;
21
- const floatingOffset = 100 - groundLevel;
22
- const control: { [key: string]: boolean } = {};
23
-
24
- class FakeWorld {
25
- overrideBlocks: { [key: string]: PBlock } = {};
26
-
27
- setOverrideBlock(pos: Vec3, type: number) {
28
- pos = pos.floored();
29
- const block = new Block(type, 0, 0);
30
- block.position = pos;
31
- this.overrideBlocks[`${pos.x},${pos.y},${pos.z}`] = block;
32
- }
33
-
34
- clearOverrides() {
35
- this.overrideBlocks = {};
36
- }
37
-
38
- getBlock(pos: Vec3) {
39
- pos = pos.floored();
40
- const key = `${pos.x},${pos.y},${pos.z}`;
41
- if (this.overrideBlocks[key]) {
42
- return this.overrideBlocks[key];
43
- }
44
-
45
- const type = pos.y < groundLevel ? mcData.blocksByName.stone.id : mcData.blocksByName.air.id;
46
- const b = new Block(type, 0, 0);
47
- b.position = pos;
48
- return b;
49
- }
50
- }
51
-
52
- function createFakePlayer(pos: Vec3, tmpGroundLevel: number = groundLevel) {
53
- const onGround = pos.y === tmpGroundLevel
54
- return {
55
- entity: {
56
- position: pos,
57
- velocity: new Vec3(0, onGround ? -0.08 : 0, 0),
58
- onGround: onGround,
59
- isInWater: false,
60
- isInLava: false,
61
- isInWeb: false,
62
- isCollidedHorizontally: false,
63
- isCollidedVertically: false,
64
- yaw: 0,
65
- effects: [],
66
- attributes: {}
67
- },
68
- jumpTicks: 0,
69
- jumpQueued: false,
70
- version: version,
71
- inventory: { slots: [] },
72
- equipment: [],
73
- food: 20,
74
- game: { gameMode: "survival" },
75
- registry: mcData,
76
- setControlState: (name: ControlState, value: boolean) => {
77
- control[name] = value;
78
- },
79
- getControlState: (name: ControlState) => {
80
- return control?.[name] ?? false;
81
- },
82
- getEquipmentDestSlot: () => {},
83
- };
84
- }
85
-
86
- initSetup(mcData);
87
-
88
- const playerType = mcData.entitiesByName["player"];
89
-
90
- describe("Physics Simulation Tests", () => {
91
- let fakePlayer: ReturnType<typeof createFakePlayer> | any;
92
- let physics: IPhysics;
93
- let playerCtx: EPhysicsCtx;
94
- let playerState: PlayerState;
95
- const fakeWorld = new FakeWorld();
96
-
97
- const setupEntity = (yOffset: number) => {
98
- fakePlayer = createFakePlayer(new Vec3(0, groundLevel + yOffset, 0), groundLevel);
99
- fakePlayer.entity = applyMdToNewEntity(EPhysicsCtx, playerType, fakePlayer.entity);
100
- physics = new Engine(mcData);
101
- playerCtx = EPhysicsCtx.FROM_BOT(physics, fakePlayer);
102
- playerState = playerCtx.state as PlayerState;
103
- playerState.control = ControlStateHandler.DEFAULT();
104
- };
105
-
106
- afterEach(() => {
107
- fakeWorld.clearOverrides();
108
- });
109
-
110
- it("should maintain position when gravity is zero", () => {
111
- setupEntity(floatingOffset);
112
- fakePlayer.entity.velocity = new Vec3(0, 0, 0);
113
- playerState.vel.y = 0;
114
- playerCtx.gravity = 0;
115
-
116
- for (let i = 0; i < 2; i++) {
117
- // playerState.update(fakePlayer);
118
- physics.simulate(playerCtx, fakeWorld);
119
- playerState.apply(fakePlayer);
120
- }
121
-
122
- expect(fakePlayer.entity.position).toEqual(new Vec3(0, groundLevel + floatingOffset, 0));
123
- });
124
-
125
- it("should move forward correctly given proper gravity", () => {
126
- setupEntity(0);
127
- playerState.control.forward = true;
128
- playerState.control.sprint = true;
129
-
130
- for (let i = 0; i < 10; i++) {
131
- physics.simulate(playerCtx, fakeWorld);
132
- playerState.apply(fakePlayer);
133
- // console.log(fakePlayer.entity.position, playerState.pos, playerState.vel, playerState.age)
134
- }
135
-
136
- if (playerState.control.forward) {
137
- expect(fakePlayer.entity.position).toEqual(new Vec3(0, groundLevel, -2.4694812397932626));
138
- } else {
139
- expect(fakePlayer.entity.position).toEqual(new Vec3(0, groundLevel, 0));
140
- }
141
- });
142
-
143
- it("sprint-jumping", () => {
144
- setupEntity(0);
145
- playerState.control.forward = true;
146
- playerState.control.sprint = true;
147
-
148
- for (let i = 0; i < 4; i++) {
149
- physics.simulate(playerCtx, fakeWorld);
150
- playerState.apply(fakePlayer);
151
- // console.log(playerState.sprinting, playerState.onGround, playerState.pos)
152
- }
153
-
154
- playerState.control.jump = true;
155
-
156
- for (let i = 0; i < 12; i++) {
157
- physics.simulate(playerCtx, fakeWorld);
158
- playerState.apply(fakePlayer);
159
- // console.log(playerState.sprinting, playerState.onGround, playerState.pos)
160
- }
161
-
162
- expect(fakePlayer.entity.position.y).toEqual(groundLevel);
163
- expect(fakePlayer.entity.position.z).toEqual(-4.085029471928113);
164
- });
165
-
166
- it("walk_fallspeed", () => {
167
- setupEntity(floatingOffset);
168
- playerState.control.forward = true;
169
-
170
- while (!fakePlayer.entity.onGround && playerState.age < 100) {
171
- physics.simulate(playerCtx, fakeWorld);
172
- // console.log(fakePlayer.entity.position, playerState.pos, playerState.vel, playerState.age)
173
- playerState.apply(fakePlayer);
174
- }
175
-
176
- expect(fakePlayer.entity.position.z).toEqual(-5.082680598494437);
177
- expect(fakePlayer.entity.position.y).toEqual(groundLevel);
178
- });
179
-
180
- it ("sprint_fallspeed", () => {
181
- setupEntity(floatingOffset);
182
- playerState.control.forward = true;
183
- playerState.control.sprint = true;
184
-
185
- // console.log(playerState.vel)
186
- while (!fakePlayer.entity.onGround && playerState.age < 100) {
187
- physics.simulate(playerCtx, fakeWorld);
188
- playerState.apply(fakePlayer);
189
- }
190
-
191
- // console.log(fakePlayer.entity.position, landingPos, playerState.pos, playerState.control)
192
-
193
- expect(fakePlayer.entity.position.z).toEqual(-6.607484778042766);
194
- expect(fakePlayer.entity.position.y).toEqual(groundLevel);
195
- })
196
-
197
- it("should restore position after gravity toggle", () => {
198
- setupEntity(floatingOffset);
199
- const orgGravity = playerCtx.gravity;
200
- fakePlayer.entity.velocity = new Vec3(0, 0, 0);
201
- playerState.vel.y = 0;
202
- playerCtx.gravity = 0;
203
-
204
- for (let i = 0; i < 5; i++) {
205
- physics.simulate(playerCtx, fakeWorld);
206
- playerState.apply(fakePlayer);
207
- }
208
- expect(fakePlayer.entity.position).toEqual(new Vec3(0, groundLevel + floatingOffset, 0));
209
- playerCtx.gravity = orgGravity;
210
-
211
- while (!fakePlayer.entity.onGround && playerState.age < 100) {
212
- physics.simulate(playerCtx, fakeWorld);
213
- playerState.apply(fakePlayer);
214
- }
215
-
216
- expect(fakePlayer.entity.position.y).toEqual(groundLevel); // Verify movement in Z direction
217
- });
218
-
219
- it("should jump and fall correctly", () => {
220
- setupEntity(0);
221
- playerState.control.jump = true;
222
-
223
- for (let i = 0; i < 3; i++) {
224
- physics.simulate(playerCtx, fakeWorld);
225
- playerState.apply(fakePlayer);
226
- }
227
-
228
- expect(fakePlayer.entity.position.y).toEqual(groundLevel + 1.001335979112147);
229
-
230
- for (let i = 0; i < 9; i++) {
231
- physics.simulate(playerCtx, fakeWorld);
232
- playerState.apply(fakePlayer);
233
- }
234
-
235
- expect(fakePlayer.entity.position.y).toEqual(groundLevel);
236
- });
237
-
238
- it("hCol--z", () => {
239
- setupEntity(0);
240
- const blockPos = new Vec3(0, groundLevel + 1, -2);
241
- fakeWorld.setOverrideBlock(blockPos, mcData.blocksByName.dirt.id);
242
- playerState.look(0, 0);
243
- playerState.control.forward = true;
244
-
245
- for (let i = 0; i < 10; i++) {
246
- physics.simulate(playerCtx, fakeWorld);
247
- playerState.apply(fakePlayer);
248
- console.log(fakePlayer.entity.position, playerState.isCollidedHorizontally);
249
- }
250
-
251
- expect(playerState.pos.z).toEqual(-0.7);
252
- expect(playerState.isCollidedHorizontally).toEqual(true);
253
- });
254
-
255
- it("hCol-z", () => {
256
- setupEntity(0);
257
- const blockPos = new Vec3(0, groundLevel + 1, 1);
258
- fakeWorld.setOverrideBlock(blockPos, mcData.blocksByName.dirt.id);
259
- playerState.look(-359.9999 * (Math.PI / 360), 0);
260
- playerState.control.forward = true;
261
-
262
- for (let i = 0; i < 10; i++) {
263
- physics.simulate(playerCtx, fakeWorld);
264
- playerState.apply(fakePlayer);
265
- console.log(fakePlayer.entity.position, playerState.isCollidedHorizontally);
266
- }
267
-
268
- expect(playerState.pos.z).toEqual(0.7);
269
- expect(playerState.isCollidedHorizontally).toEqual(true);
270
- });
271
-
272
- it("hCol--x", () => {
273
- setupEntity(0);
274
- const blockPos = new Vec3(-2, groundLevel + 1, 0);
275
- fakeWorld.setOverrideBlock(blockPos, mcData.blocksByName.dirt.id);
276
- playerState.look(180 * (Math.PI / 360), 0)
277
- playerState.control.forward = true;
278
-
279
- for (let i = 0; i < 10; i++) {
280
- physics.simulate(playerCtx, fakeWorld);
281
- playerState.apply(fakePlayer);
282
- console.log(fakePlayer.entity.position, playerState.isCollidedHorizontally);
283
- }
284
-
285
- expect(playerState.pos.x).toEqual(-0.7);
286
- expect(playerState.isCollidedHorizontally).toEqual(true);
287
- });
288
-
289
- it("hCol-x", () => {
290
- setupEntity(0);
291
- const blockPos = new Vec3(1, groundLevel + 1, 0);
292
- fakeWorld.setOverrideBlock(blockPos, mcData.blocksByName.dirt.id);
293
- playerState.look(-180 * (Math.PI / 360), 0);
294
- playerState.control.forward = true;
295
-
296
- for (let i = 0; i < 10; i++) {
297
- physics.simulate(playerCtx, fakeWorld);
298
- playerState.apply(fakePlayer);
299
- console.log(fakePlayer.entity.position, playerState.isCollidedHorizontally);
300
- }
301
-
302
- expect(playerState.pos.x).toEqual(0.7);
303
- expect(playerState.isCollidedHorizontally).toEqual(true);
304
- });
305
-
306
- it("jumpIntoBlock", () => {
307
- setupEntity(0);
308
-
309
- const bl1 = new Vec3(0, groundLevel + 1, 1);
310
- fakeWorld.setOverrideBlock(bl1, mcData.blocksByName.dirt.id);
311
-
312
- fakePlayer.entity.position = new Vec3(0.5, groundLevel, 0.7); // right up against a block
313
- playerState.pos = fakePlayer.entity.position.clone();
314
- playerState.look(-359.9999 * (Math.PI / 360), 0);
315
-
316
- playerState.control.jump = true;
317
- playerState.control.forward = true;
318
- playerState.control.sprint = true;
319
-
320
- for (let i = 0; i < 12; i++) {
321
- physics.simulate(playerCtx, fakeWorld);
322
- playerState.apply(fakePlayer);
323
- // console.log(fakePlayer.entity.position, playerState.isCollidedHorizontally);
324
- }
325
-
326
- expect(playerState.pos.z).toEqual(0.7);
327
- expect(playerState.isCollidedHorizontally).toEqual(true);
328
- });
329
-
330
- it("walkUpStairs", () => {
331
- setupEntity(0);
332
-
333
- const bl1 = new Vec3(0, groundLevel, -1);
334
- fakeWorld.setOverrideBlock(bl1, mcData.blocksByName.stone_stairs.id);
335
-
336
- const shapes = fakeWorld.getBlock(bl1).shapes;
337
- const bbs = shapes.map((shape) => AABB.fromShape(shape, bl1));
338
-
339
- fakePlayer.entity.position = new Vec3(-0.3, groundLevel, -0.5); // right up against a block
340
- playerState.pos = fakePlayer.entity.position.clone();
341
- playerState.look(-180 * (Math.PI / 360), 0);
342
-
343
- playerState.control.forward = true;
344
- playerState.control.sprint = true;
345
-
346
- for (let i = 0; i < 4; i++) {
347
- // console.log(fakePlayer.entity.position, playerState.pos, playerState.isCollidedHorizontally);
348
- physics.simulate(playerCtx, fakeWorld);
349
- playerState.apply(fakePlayer);
350
- }
351
-
352
- expect(playerState.pos.y).toEqual(groundLevel + 1);
353
- });
354
- });
1
+ import { describe, it, beforeEach } from "mocha";
2
+ import expect from "expect";
3
+ import { Vec3 } from "vec3";
4
+ import md from "minecraft-data";
5
+ import block, { Block as PBlock } from "prismarine-block";
6
+ import { applyMdToNewEntity } from "../src/util/physicsUtils";
7
+ import { EPhysicsCtx, PhysicsWorldSettings } from "../src/physics/settings";
8
+ import { ControlStateHandler } from "../src/physics/player";
9
+ import { BotcraftPhysics, EntityPhysics, IPhysics } from "../src/physics/engines";
10
+ import { initSetup } from "../src/index";
11
+ import { PlayerState } from "../src/physics/states";
12
+ import { Bot, ControlState } from "mineflayer";
13
+ import { AABB } from "@nxg-org/mineflayer-util-plugin";
14
+
15
+ const version = "1.12.2";
16
+ const mcData = md(version);
17
+ const Engine = BotcraftPhysics;
18
+ const Block = block(version) as typeof PBlock;
19
+
20
+ const groundLevel = 67;
21
+ const floatingOffset = 100 - groundLevel;
22
+ const control: { [key: string]: boolean } = {};
23
+
24
+ class FakeWorld {
25
+ overrideBlocks: { [key: string]: PBlock } = {};
26
+
27
+ setOverrideBlock(pos: Vec3, type: number) {
28
+ pos = pos.floored();
29
+ const block = new Block(type, 0, 0);
30
+ block.position = pos;
31
+ this.overrideBlocks[`${pos.x},${pos.y},${pos.z}`] = block;
32
+ }
33
+
34
+ clearOverrides() {
35
+ this.overrideBlocks = {};
36
+ }
37
+
38
+ getBlock(pos: Vec3) {
39
+ pos = pos.floored();
40
+ const key = `${pos.x},${pos.y},${pos.z}`;
41
+ if (this.overrideBlocks[key]) {
42
+ return this.overrideBlocks[key];
43
+ }
44
+
45
+ const type = pos.y < groundLevel ? mcData.blocksByName.stone.id : mcData.blocksByName.air.id;
46
+ const b = new Block(type, 0, 0);
47
+ b.position = pos;
48
+ return b;
49
+ }
50
+ }
51
+
52
+ function createFakePlayer(pos: Vec3, tmpGroundLevel: number = groundLevel) {
53
+ const onGround = pos.y === tmpGroundLevel
54
+ return {
55
+ entity: {
56
+ position: pos,
57
+ velocity: new Vec3(0, onGround ? -0.08 : 0, 0),
58
+ onGround: onGround,
59
+ isInWater: false,
60
+ isInLava: false,
61
+ isInWeb: false,
62
+ isCollidedHorizontally: false,
63
+ isCollidedVertically: false,
64
+ yaw: 0,
65
+ effects: [],
66
+ attributes: {}
67
+ },
68
+ jumpTicks: 0,
69
+ jumpQueued: false,
70
+ version: version,
71
+ inventory: { slots: [] },
72
+ equipment: [],
73
+ food: 20,
74
+ game: { gameMode: "survival" },
75
+ registry: mcData,
76
+ setControlState: (name: ControlState, value: boolean) => {
77
+ control[name] = value;
78
+ },
79
+ getControlState: (name: ControlState) => {
80
+ return control?.[name] ?? false;
81
+ },
82
+ getEquipmentDestSlot: () => {},
83
+ };
84
+ }
85
+
86
+ initSetup(mcData);
87
+
88
+ const playerType = mcData.entitiesByName["player"];
89
+
90
+ describe("Physics Simulation Tests", () => {
91
+ let fakePlayer: ReturnType<typeof createFakePlayer> | any;
92
+ let physics: IPhysics;
93
+ let playerCtx: EPhysicsCtx;
94
+ let playerState: PlayerState;
95
+ const fakeWorld = new FakeWorld();
96
+
97
+ const setupEntity = (yOffset: number) => {
98
+ fakePlayer = createFakePlayer(new Vec3(0, groundLevel + yOffset, 0), groundLevel);
99
+ fakePlayer.entity = applyMdToNewEntity(EPhysicsCtx, playerType, fakePlayer.entity);
100
+ physics = new Engine(mcData);
101
+ playerCtx = EPhysicsCtx.FROM_BOT(physics, fakePlayer);
102
+ playerState = playerCtx.state as PlayerState;
103
+ playerState.control = ControlStateHandler.DEFAULT();
104
+ };
105
+
106
+ afterEach(() => {
107
+ fakeWorld.clearOverrides();
108
+ });
109
+
110
+ it("should maintain position when gravity is zero", () => {
111
+ setupEntity(floatingOffset);
112
+ fakePlayer.entity.velocity = new Vec3(0, 0, 0);
113
+ playerState.vel.y = 0;
114
+ playerCtx.gravity = 0;
115
+
116
+ for (let i = 0; i < 2; i++) {
117
+ // playerState.update(fakePlayer);
118
+ physics.simulate(playerCtx, fakeWorld);
119
+ playerState.apply(fakePlayer);
120
+ }
121
+
122
+ expect(fakePlayer.entity.position).toEqual(new Vec3(0, groundLevel + floatingOffset, 0));
123
+ });
124
+
125
+ it("should move forward correctly given proper gravity", () => {
126
+ setupEntity(0);
127
+ playerState.control.forward = true;
128
+ playerState.control.sprint = true;
129
+
130
+ for (let i = 0; i < 10; i++) {
131
+ physics.simulate(playerCtx, fakeWorld);
132
+ playerState.apply(fakePlayer);
133
+ // console.log(fakePlayer.entity.position, playerState.pos, playerState.vel, playerState.age)
134
+ }
135
+
136
+ if (playerState.control.forward) {
137
+ expect(fakePlayer.entity.position).toEqual(new Vec3(0, groundLevel, -2.4694812397932626));
138
+ } else {
139
+ expect(fakePlayer.entity.position).toEqual(new Vec3(0, groundLevel, 0));
140
+ }
141
+ });
142
+
143
+ it("sprint-jumping", () => {
144
+ setupEntity(0);
145
+ playerState.control.forward = true;
146
+ playerState.control.sprint = true;
147
+
148
+ for (let i = 0; i < 4; i++) {
149
+ physics.simulate(playerCtx, fakeWorld);
150
+ playerState.apply(fakePlayer);
151
+ // console.log(playerState.sprinting, playerState.onGround, playerState.pos)
152
+ }
153
+
154
+ playerState.control.jump = true;
155
+
156
+ for (let i = 0; i < 12; i++) {
157
+ physics.simulate(playerCtx, fakeWorld);
158
+ playerState.apply(fakePlayer);
159
+ // console.log(playerState.sprinting, playerState.onGround, playerState.pos)
160
+ }
161
+
162
+ expect(fakePlayer.entity.position.y).toEqual(groundLevel);
163
+ expect(fakePlayer.entity.position.z).toEqual(-4.085029471928113);
164
+ });
165
+
166
+ it("walk_fallspeed", () => {
167
+ setupEntity(floatingOffset);
168
+ playerState.control.forward = true;
169
+
170
+ while (!fakePlayer.entity.onGround && playerState.age < 100) {
171
+ physics.simulate(playerCtx, fakeWorld);
172
+ // console.log(fakePlayer.entity.position, playerState.pos, playerState.vel, playerState.age)
173
+ playerState.apply(fakePlayer);
174
+ }
175
+
176
+ expect(fakePlayer.entity.position.z).toEqual(-5.082680598494437);
177
+ expect(fakePlayer.entity.position.y).toEqual(groundLevel);
178
+ });
179
+
180
+ it ("sprint_fallspeed", () => {
181
+ setupEntity(floatingOffset);
182
+ playerState.control.forward = true;
183
+ playerState.control.sprint = true;
184
+
185
+ // console.log(playerState.vel)
186
+ while (!fakePlayer.entity.onGround && playerState.age < 100) {
187
+ physics.simulate(playerCtx, fakeWorld);
188
+ playerState.apply(fakePlayer);
189
+ }
190
+
191
+ // console.log(fakePlayer.entity.position, landingPos, playerState.pos, playerState.control)
192
+
193
+ expect(fakePlayer.entity.position.z).toEqual(-6.607484778042766);
194
+ expect(fakePlayer.entity.position.y).toEqual(groundLevel);
195
+ })
196
+
197
+ it("should restore position after gravity toggle", () => {
198
+ setupEntity(floatingOffset);
199
+ const orgGravity = playerCtx.gravity;
200
+ fakePlayer.entity.velocity = new Vec3(0, 0, 0);
201
+ playerState.vel.y = 0;
202
+ playerCtx.gravity = 0;
203
+
204
+ for (let i = 0; i < 5; i++) {
205
+ physics.simulate(playerCtx, fakeWorld);
206
+ playerState.apply(fakePlayer);
207
+ }
208
+ expect(fakePlayer.entity.position).toEqual(new Vec3(0, groundLevel + floatingOffset, 0));
209
+ playerCtx.gravity = orgGravity;
210
+
211
+ while (!fakePlayer.entity.onGround && playerState.age < 100) {
212
+ physics.simulate(playerCtx, fakeWorld);
213
+ playerState.apply(fakePlayer);
214
+ }
215
+
216
+ expect(fakePlayer.entity.position.y).toEqual(groundLevel); // Verify movement in Z direction
217
+ });
218
+
219
+ it("should jump and fall correctly", () => {
220
+ setupEntity(0);
221
+ playerState.control.jump = true;
222
+
223
+ for (let i = 0; i < 3; i++) {
224
+ physics.simulate(playerCtx, fakeWorld);
225
+ playerState.apply(fakePlayer);
226
+ }
227
+
228
+ expect(fakePlayer.entity.position.y).toEqual(groundLevel + 1.001335979112147);
229
+
230
+ for (let i = 0; i < 9; i++) {
231
+ physics.simulate(playerCtx, fakeWorld);
232
+ playerState.apply(fakePlayer);
233
+ }
234
+
235
+ expect(fakePlayer.entity.position.y).toEqual(groundLevel);
236
+ });
237
+
238
+ it("hCol--z", () => {
239
+ setupEntity(0);
240
+ const blockPos = new Vec3(0, groundLevel + 1, -2);
241
+ fakeWorld.setOverrideBlock(blockPos, mcData.blocksByName.dirt.id);
242
+ playerState.look(0, 0);
243
+ playerState.control.forward = true;
244
+
245
+ for (let i = 0; i < 10; i++) {
246
+ physics.simulate(playerCtx, fakeWorld);
247
+ playerState.apply(fakePlayer);
248
+ console.log(fakePlayer.entity.position, playerState.isCollidedHorizontally);
249
+ }
250
+
251
+ expect(playerState.pos.z).toEqual(-0.7);
252
+ expect(playerState.isCollidedHorizontally).toEqual(true);
253
+ });
254
+
255
+ it("hCol-z", () => {
256
+ setupEntity(0);
257
+ const blockPos = new Vec3(0, groundLevel + 1, 1);
258
+ fakeWorld.setOverrideBlock(blockPos, mcData.blocksByName.dirt.id);
259
+ playerState.look(-359.9999 * (Math.PI / 360), 0);
260
+ playerState.control.forward = true;
261
+
262
+ for (let i = 0; i < 10; i++) {
263
+ physics.simulate(playerCtx, fakeWorld);
264
+ playerState.apply(fakePlayer);
265
+ console.log(fakePlayer.entity.position, playerState.isCollidedHorizontally);
266
+ }
267
+
268
+ expect(playerState.pos.z).toEqual(0.7);
269
+ expect(playerState.isCollidedHorizontally).toEqual(true);
270
+ });
271
+
272
+ it("hCol--x", () => {
273
+ setupEntity(0);
274
+ const blockPos = new Vec3(-2, groundLevel + 1, 0);
275
+ fakeWorld.setOverrideBlock(blockPos, mcData.blocksByName.dirt.id);
276
+ playerState.look(180 * (Math.PI / 360), 0)
277
+ playerState.control.forward = true;
278
+
279
+ for (let i = 0; i < 10; i++) {
280
+ physics.simulate(playerCtx, fakeWorld);
281
+ playerState.apply(fakePlayer);
282
+ console.log(fakePlayer.entity.position, playerState.isCollidedHorizontally);
283
+ }
284
+
285
+ expect(playerState.pos.x).toEqual(-0.7);
286
+ expect(playerState.isCollidedHorizontally).toEqual(true);
287
+ });
288
+
289
+ it("hCol-x", () => {
290
+ setupEntity(0);
291
+ const blockPos = new Vec3(1, groundLevel + 1, 0);
292
+ fakeWorld.setOverrideBlock(blockPos, mcData.blocksByName.dirt.id);
293
+ playerState.look(-180 * (Math.PI / 360), 0);
294
+ playerState.control.forward = true;
295
+
296
+ for (let i = 0; i < 10; i++) {
297
+ physics.simulate(playerCtx, fakeWorld);
298
+ playerState.apply(fakePlayer);
299
+ console.log(fakePlayer.entity.position, playerState.isCollidedHorizontally);
300
+ }
301
+
302
+ expect(playerState.pos.x).toEqual(0.7);
303
+ expect(playerState.isCollidedHorizontally).toEqual(true);
304
+ });
305
+
306
+ it("jumpIntoBlock", () => {
307
+ setupEntity(0);
308
+
309
+ const bl1 = new Vec3(0, groundLevel + 1, 1);
310
+ fakeWorld.setOverrideBlock(bl1, mcData.blocksByName.dirt.id);
311
+
312
+ fakePlayer.entity.position = new Vec3(0.5, groundLevel, 0.7); // right up against a block
313
+ playerState.pos = fakePlayer.entity.position.clone();
314
+ playerState.look(-359.9999 * (Math.PI / 360), 0);
315
+
316
+ playerState.control.jump = true;
317
+ playerState.control.forward = true;
318
+ playerState.control.sprint = true;
319
+
320
+ for (let i = 0; i < 12; i++) {
321
+ physics.simulate(playerCtx, fakeWorld);
322
+ playerState.apply(fakePlayer);
323
+ // console.log(fakePlayer.entity.position, playerState.isCollidedHorizontally);
324
+ }
325
+
326
+ expect(playerState.pos.z).toEqual(0.7);
327
+ expect(playerState.isCollidedHorizontally).toEqual(true);
328
+ });
329
+
330
+ it("walkUpStairs", () => {
331
+ setupEntity(0);
332
+
333
+ const bl1 = new Vec3(0, groundLevel, -1);
334
+ fakeWorld.setOverrideBlock(bl1, mcData.blocksByName.stone_stairs.id);
335
+
336
+ const shapes = fakeWorld.getBlock(bl1).shapes;
337
+ const bbs = shapes.map((shape) => AABB.fromShape(shape, bl1));
338
+
339
+ fakePlayer.entity.position = new Vec3(-0.3, groundLevel, -0.5); // right up against a block
340
+ playerState.pos = fakePlayer.entity.position.clone();
341
+ playerState.look(-180 * (Math.PI / 360), 0);
342
+
343
+ playerState.control.forward = true;
344
+ playerState.control.sprint = true;
345
+
346
+ for (let i = 0; i < 4; i++) {
347
+ // console.log(fakePlayer.entity.position, playerState.pos, playerState.isCollidedHorizontally);
348
+ physics.simulate(playerCtx, fakeWorld);
349
+ playerState.apply(fakePlayer);
350
+ }
351
+
352
+ expect(playerState.pos.y).toEqual(groundLevel + 1);
353
+ });
354
+ });