prismarine-physics 1.9.0 → 1.11.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/.github/workflows/ci.yml +1 -1
- package/.github/workflows/publish.yml +7 -5
- package/HISTORY.md +13 -0
- package/index.js +39 -5
- package/lib/features.json +7 -2
- package/package.json +2 -2
- package/test/elytra.test.js +2 -2
- package/test/scaffolding.test.js +152 -0
package/.github/workflows/ci.yml
CHANGED
|
@@ -3,6 +3,9 @@ on:
|
|
|
3
3
|
push:
|
|
4
4
|
branches:
|
|
5
5
|
- master # Change this to your default branch
|
|
6
|
+
permissions:
|
|
7
|
+
id-token: write
|
|
8
|
+
contents: write
|
|
6
9
|
jobs:
|
|
7
10
|
npm-publish:
|
|
8
11
|
name: npm-publish
|
|
@@ -13,13 +16,12 @@ jobs:
|
|
|
13
16
|
- name: Set up Node.js
|
|
14
17
|
uses: actions/setup-node@master
|
|
15
18
|
with:
|
|
16
|
-
node-version:
|
|
19
|
+
node-version: 24
|
|
20
|
+
registry-url: 'https://registry.npmjs.org'
|
|
17
21
|
- id: publish
|
|
18
|
-
uses: JS-DevTools/npm-publish@
|
|
19
|
-
with:
|
|
20
|
-
token: ${{ secrets.NPM_AUTH_TOKEN }}
|
|
22
|
+
uses: JS-DevTools/npm-publish@v4
|
|
21
23
|
- name: Create Release
|
|
22
|
-
if: steps.publish.outputs.type
|
|
24
|
+
if: ${{ steps.publish.outputs.type }}
|
|
23
25
|
id: create_release
|
|
24
26
|
uses: actions/create-release@v1
|
|
25
27
|
env:
|
package/HISTORY.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
## History
|
|
2
2
|
|
|
3
|
+
### 1.11.0
|
|
4
|
+
* [Update CI to Node 24 (#129)](https://github.com/PrismarineJS/prismarine-physics/commit/7be0b38f547f186d41fc9cda8841cacf8f2fd80a) (thanks @rom1504)
|
|
5
|
+
* [Fix incorrect elytra physics (#123)](https://github.com/PrismarineJS/prismarine-physics/commit/be7f91bb4ec85e1b1f4ccfa1a33607e9cdfdf92c) (thanks @BossFlea)
|
|
6
|
+
* [fix: add scaffolding to climbable blocks and 1.21 to climbUsingJump (#126)](https://github.com/PrismarineJS/prismarine-physics/commit/06543978564247457c6ac3255c666d64a99c4de4) (thanks @jerry1091)
|
|
7
|
+
* [Fix publish condition for npm-publish v4 (#128)](https://github.com/PrismarineJS/prismarine-physics/commit/45d7e992c58e0f60c18eee633adad783c3e64e0f) (thanks @rom1504)
|
|
8
|
+
* [Switch to trusted publishing via OIDC (#127)](https://github.com/PrismarineJS/prismarine-physics/commit/f34e1d48ece5329d443c58624e2fb55ba3d5cc03) (thanks @rom1504)
|
|
9
|
+
* [node 22 (#122)](https://github.com/PrismarineJS/prismarine-physics/commit/37d8d0b612de347b2e132e270642fec108d4f2ec) (thanks @rom1504)
|
|
10
|
+
|
|
11
|
+
### 1.10.0
|
|
12
|
+
* [Fix `.isOnLadder()` condition (#111)](https://github.com/PrismarineJS/prismarine-physics/commit/03b2e447b7f867257b8e50170439be8ca8e51743) (thanks @szdytom)
|
|
13
|
+
* [Bump mocha from 10.8.2 to 11.0.1 (#119)](https://github.com/PrismarineJS/prismarine-physics/commit/4a1d37c91915522d824b2d4170fce135926ce6e5) (thanks @dependabot[bot])
|
|
14
|
+
* [Use new block.isWaterlogged over reading block properties (#120)](https://github.com/PrismarineJS/prismarine-physics/commit/5cbba64ec457c6b5fa18002e57b87c8c584abb94) (thanks @extremeheat)
|
|
15
|
+
|
|
3
16
|
### 1.9.0
|
|
4
17
|
* [add 1.21 to proportionalliquidgravity setting (#117)](https://github.com/PrismarineJS/prismarine-physics/commit/4986c8e395773e770d461db06bce38f9faed0757) (thanks @Madlykeanu)
|
|
5
18
|
|
package/index.js
CHANGED
|
@@ -34,6 +34,22 @@ function Physics (mcData, world) {
|
|
|
34
34
|
const lavaIds = [blocksByName.lava.id, blocksByName.flowing_lava ? blocksByName.flowing_lava.id : -1]
|
|
35
35
|
const ladderId = blocksByName.ladder.id
|
|
36
36
|
const vineId = blocksByName.vine.id
|
|
37
|
+
const scaffoldingId = blocksByName.scaffolding ? blocksByName.scaffolding.id : -1 // 1.14+
|
|
38
|
+
|
|
39
|
+
// NOTE: Copper trapdoors is coming in 1.21.
|
|
40
|
+
const trapdoorIds = new Set()
|
|
41
|
+
if (blocksByName.iron_trapdoor) { trapdoorIds.add(blocksByName.iron_trapdoor.id) } // 1.8+
|
|
42
|
+
if (blocksByName.acacia_trapdoor) { trapdoorIds.add(blocksByName.acacia_trapdoor.id) } // 1.13+
|
|
43
|
+
if (blocksByName.birch_trapdoor) { trapdoorIds.add(blocksByName.birch_trapdoor.id) } // 1.13+
|
|
44
|
+
if (blocksByName.jungle_trapdoor) { trapdoorIds.add(blocksByName.jungle_trapdoor.id) } // 1.13+
|
|
45
|
+
if (blocksByName.oak_trapdoor) { trapdoorIds.add(blocksByName.oak_trapdoor.id) } // 1.13+
|
|
46
|
+
if (blocksByName.dark_oak_trapdoor) { trapdoorIds.add(blocksByName.dark_oak_trapdoor.id) } // 1.13+
|
|
47
|
+
if (blocksByName.spruce_trapdoor) { trapdoorIds.add(blocksByName.spruce_trapdoor.id) } // 1.13+
|
|
48
|
+
if (blocksByName.crimson_trapdoor) { trapdoorIds.add(blocksByName.crimson_trapdoor.id) } // 1.16+
|
|
49
|
+
if (blocksByName.warped_trapdoor) { trapdoorIds.add(blocksByName.warped_trapdoor.id) } // 1.16+
|
|
50
|
+
if (blocksByName.mangrove_trapdoor) { trapdoorIds.add(blocksByName.mangrove_trapdoor.id) } // 1.19+
|
|
51
|
+
if (blocksByName.cherry_trapdoor) { trapdoorIds.add(blocksByName.cherry_trapdoor.id) } // 1.20+
|
|
52
|
+
|
|
37
53
|
const waterLike = new Set()
|
|
38
54
|
if (blocksByName.seagrass) waterLike.add(blocksByName.seagrass.id) // 1.13+
|
|
39
55
|
if (blocksByName.tall_seagrass) waterLike.add(blocksByName.tall_seagrass.id) // 1.13+
|
|
@@ -419,9 +435,27 @@ function Physics (mcData, world) {
|
|
|
419
435
|
vel.z += forward * cos - strafe * sin
|
|
420
436
|
}
|
|
421
437
|
|
|
438
|
+
const climbableTrapdoorFeature = supportFeature('climbableTrapdoor')
|
|
422
439
|
function isOnLadder (world, pos) {
|
|
423
440
|
const block = world.getBlock(pos)
|
|
424
|
-
|
|
441
|
+
if (!block) { return false }
|
|
442
|
+
if (block.type === ladderId || block.type === vineId) { return true }
|
|
443
|
+
if (scaffoldingId !== -1 && block.type === scaffoldingId) { return true }
|
|
444
|
+
|
|
445
|
+
// Since 1.9, when a trapdoor satisfies the following conditions, it also becomes climbable:
|
|
446
|
+
// 1. The trapdoor is placed directly above a ladder.
|
|
447
|
+
// 2. The trapdoor is opened.
|
|
448
|
+
// 3. The trapdoor and the ladder directly below it face the same direction.
|
|
449
|
+
if (climbableTrapdoorFeature && trapdoorIds.has(block.type)) {
|
|
450
|
+
const blockBelow = world.getBlock(pos.offset(0, -1, 0))
|
|
451
|
+
if (blockBelow.type !== ladderId) { return false } // condition 1.
|
|
452
|
+
const blockProperties = block._properties
|
|
453
|
+
if (!blockProperties.open) { return false } // condition 2.
|
|
454
|
+
if (blockProperties.facing !== blockBelow.getProperties().facing) { return false } // condition 3
|
|
455
|
+
return true
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return false
|
|
425
459
|
}
|
|
426
460
|
|
|
427
461
|
function doesNotCollide (world, pos) {
|
|
@@ -484,8 +518,8 @@ function Physics (mcData, world) {
|
|
|
484
518
|
vel.z += lookDir.z * movingDownSpeedModifier / cosPitch
|
|
485
519
|
}
|
|
486
520
|
|
|
487
|
-
if (pitch
|
|
488
|
-
const lookDownSpeedModifier = horizontalSpeed *
|
|
521
|
+
if (pitch > 0.0 && cosPitch > 0.0) {
|
|
522
|
+
const lookDownSpeedModifier = horizontalSpeed * sinPitch * 0.04
|
|
489
523
|
vel.x += -lookDir.x * lookDownSpeedModifier / cosPitch
|
|
490
524
|
vel.y += lookDownSpeedModifier * 3.2
|
|
491
525
|
vel.z += -lookDir.z * lookDownSpeedModifier / cosPitch
|
|
@@ -592,7 +626,7 @@ function Physics (mcData, world) {
|
|
|
592
626
|
function getRenderedDepth (block) {
|
|
593
627
|
if (!block) return -1
|
|
594
628
|
if (waterLike.has(block.type)) return 0
|
|
595
|
-
if (block.
|
|
629
|
+
if (block.isWaterlogged) return 0
|
|
596
630
|
if (!waterIds.includes(block.type)) return -1
|
|
597
631
|
const meta = block.metadata
|
|
598
632
|
return meta >= 8 ? 0 : meta
|
|
@@ -640,7 +674,7 @@ function Physics (mcData, world) {
|
|
|
640
674
|
for (cursor.z = Math.floor(bb.minZ); cursor.z <= Math.floor(bb.maxZ); cursor.z++) {
|
|
641
675
|
for (cursor.x = Math.floor(bb.minX); cursor.x <= Math.floor(bb.maxX); cursor.x++) {
|
|
642
676
|
const block = world.getBlock(cursor)
|
|
643
|
-
if (block && (waterIds.includes(block.type) || waterLike.has(block.type) || block.
|
|
677
|
+
if (block && (waterIds.includes(block.type) || waterLike.has(block.type) || block.isWaterlogged)) {
|
|
644
678
|
const waterLevel = cursor.y + 1 - getLiquidHeightPcent(block)
|
|
645
679
|
if (Math.ceil(bb.maxY) >= waterLevel) waterBlocks.push(block)
|
|
646
680
|
}
|
package/lib/features.json
CHANGED
|
@@ -17,11 +17,16 @@
|
|
|
17
17
|
{
|
|
18
18
|
"name": "velocityBlocksOnTop",
|
|
19
19
|
"description": "Velocity changes are caused by the block the player is standing on",
|
|
20
|
-
"versions": ["1.15", "1.17", "1.18"]
|
|
20
|
+
"versions": ["1.15", "1.16", "1.17", "1.18", "1.19", "1.20"]
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
"name": "climbUsingJump",
|
|
24
24
|
"description": "Entity can climb ladders and vines by pressing jump",
|
|
25
|
-
"versions": ["1.14", "1.15", "1.17", "1.18"]
|
|
25
|
+
"versions": ["1.14", "1.15", "1.16", "1.17", "1.18", "1.19", "1.20", "1.21"]
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "climbableTrapdoor",
|
|
29
|
+
"description": "Trapdoors placed directly above ladders become climbable",
|
|
30
|
+
"versions": ["1.9", "1.10", "1.11", "1.12", "1.13", "1.14", "1.15", "1.16", "1.17", "1.18", "1.19", "1.20"]
|
|
26
31
|
}
|
|
27
32
|
]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prismarine-physics",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
4
4
|
"description": "Provide the physics engine for minecraft entities",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"directories": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"homepage": "https://github.com/PrismarineJS/prismarine-physics#readme",
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"expect": "^27.3.1",
|
|
32
|
-
"mocha": "^
|
|
32
|
+
"mocha": "^11.0.1",
|
|
33
33
|
"prismarine-block": "^1.7.3",
|
|
34
34
|
"prismarine-physics": "file:./",
|
|
35
35
|
"standard": "^17.0.0"
|
package/test/elytra.test.js
CHANGED
|
@@ -490,8 +490,8 @@ describe('Elytra tests', () => {
|
|
|
490
490
|
expect(webPlayer.entity.position.y).toBeGreaterThan(149)
|
|
491
491
|
|
|
492
492
|
// elytra player should be far away and much lower
|
|
493
|
-
expect(airPlayer.entity.position.x).toBeGreaterThan(
|
|
494
|
-
expect(airPlayer.entity.position.y).toBeLessThan(
|
|
493
|
+
expect(airPlayer.entity.position.x).toBeGreaterThan(60)
|
|
494
|
+
expect(airPlayer.entity.position.y).toBeLessThan(135)
|
|
495
495
|
})
|
|
496
496
|
|
|
497
497
|
it('can hit a wall', () => {
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/* eslint-env mocha */
|
|
2
|
+
|
|
3
|
+
const { Physics, PlayerState } = require('prismarine-physics')
|
|
4
|
+
const { Vec3 } = require('vec3')
|
|
5
|
+
const expect = require('expect')
|
|
6
|
+
const features = require('../lib/features.json')
|
|
7
|
+
|
|
8
|
+
describe('Scaffolding climbable and climbUsingJump feature', () => {
|
|
9
|
+
describe('features.json', () => {
|
|
10
|
+
it('climbUsingJump should include version 1.21', () => {
|
|
11
|
+
const climbUsingJump = features.find(f => f.name === 'climbUsingJump')
|
|
12
|
+
expect(climbUsingJump).toBeTruthy()
|
|
13
|
+
expect(climbUsingJump.versions).toContain('1.21')
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('climbUsingJump should include versions 1.14 through 1.21', () => {
|
|
17
|
+
const climbUsingJump = features.find(f => f.name === 'climbUsingJump')
|
|
18
|
+
for (const v of ['1.14', '1.15', '1.16', '1.17', '1.18', '1.19', '1.20', '1.21']) {
|
|
19
|
+
expect(climbUsingJump.versions).toContain(v)
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
describe('Scaffolding is climbable for versions >= 1.14', () => {
|
|
25
|
+
for (const version of ['1.14.4', '1.16.5', '1.21']) {
|
|
26
|
+
it(`should treat scaffolding as climbable in ${version}`, () => {
|
|
27
|
+
const mcData = require('minecraft-data')(version)
|
|
28
|
+
const Block = require('prismarine-block')(version)
|
|
29
|
+
|
|
30
|
+
const scaffoldingId = mcData.blocksByName.scaffolding.id
|
|
31
|
+
const stoneId = mcData.blocksByName.stone.id
|
|
32
|
+
const airId = mcData.blocksByName.air.id
|
|
33
|
+
|
|
34
|
+
// World: stone below y=60, scaffolding at y=61, air elsewhere
|
|
35
|
+
const fakeWorld = {
|
|
36
|
+
getBlock: (pos) => {
|
|
37
|
+
let type
|
|
38
|
+
if (pos.y < 60) {
|
|
39
|
+
type = stoneId
|
|
40
|
+
} else if (pos.y === 61 && pos.x === 0 && pos.z === 0) {
|
|
41
|
+
type = scaffoldingId
|
|
42
|
+
} else {
|
|
43
|
+
type = airId
|
|
44
|
+
}
|
|
45
|
+
const b = new Block(type, 0, 0)
|
|
46
|
+
b.position = pos
|
|
47
|
+
return b
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const physics = Physics(mcData, fakeWorld)
|
|
52
|
+
const controls = {
|
|
53
|
+
forward: false,
|
|
54
|
+
back: false,
|
|
55
|
+
left: false,
|
|
56
|
+
right: false,
|
|
57
|
+
jump: true,
|
|
58
|
+
sprint: false,
|
|
59
|
+
sneak: false
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const player = {
|
|
63
|
+
entity: {
|
|
64
|
+
position: new Vec3(0, 61, 0),
|
|
65
|
+
velocity: new Vec3(0, 0, 0),
|
|
66
|
+
onGround: false,
|
|
67
|
+
isInWater: false,
|
|
68
|
+
isInLava: false,
|
|
69
|
+
isInWeb: false,
|
|
70
|
+
isCollidedHorizontally: false,
|
|
71
|
+
isCollidedVertically: false,
|
|
72
|
+
elytraFlying: false,
|
|
73
|
+
yaw: 0,
|
|
74
|
+
pitch: 0,
|
|
75
|
+
effects: {}
|
|
76
|
+
},
|
|
77
|
+
jumpTicks: 0,
|
|
78
|
+
jumpQueued: false,
|
|
79
|
+
fireworkRocketDuration: 0,
|
|
80
|
+
version,
|
|
81
|
+
inventory: {
|
|
82
|
+
slots: []
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const playerState = new PlayerState(player, controls)
|
|
87
|
+
physics.simulatePlayer(playerState, fakeWorld).apply(player)
|
|
88
|
+
|
|
89
|
+
// When on scaffolding with jump pressed, the player should climb
|
|
90
|
+
// (velocity.y should be positive, equal to ladderClimbSpeed)
|
|
91
|
+
expect(player.entity.velocity.y).toBeGreaterThan(0)
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
describe('Scaffolding does not exist pre-1.14', () => {
|
|
97
|
+
it('should not crash when scaffolding block does not exist (1.13.2)', () => {
|
|
98
|
+
const mcData = require('minecraft-data')('1.13.2')
|
|
99
|
+
const Block = require('prismarine-block')('1.13.2')
|
|
100
|
+
|
|
101
|
+
expect(mcData.blocksByName.scaffolding).toBeFalsy()
|
|
102
|
+
|
|
103
|
+
const fakeWorld = {
|
|
104
|
+
getBlock: (pos) => {
|
|
105
|
+
const type = (pos.y < 60) ? mcData.blocksByName.stone.id : mcData.blocksByName.air.id
|
|
106
|
+
const b = new Block(type, 0, 0)
|
|
107
|
+
b.position = pos
|
|
108
|
+
return b
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Should not throw
|
|
113
|
+
const physics = Physics(mcData, fakeWorld)
|
|
114
|
+
const controls = {
|
|
115
|
+
forward: false,
|
|
116
|
+
back: false,
|
|
117
|
+
left: false,
|
|
118
|
+
right: false,
|
|
119
|
+
jump: false,
|
|
120
|
+
sprint: false,
|
|
121
|
+
sneak: false
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const player = {
|
|
125
|
+
entity: {
|
|
126
|
+
position: new Vec3(0, 80, 0),
|
|
127
|
+
velocity: new Vec3(0, 0, 0),
|
|
128
|
+
onGround: false,
|
|
129
|
+
isInWater: false,
|
|
130
|
+
isInLava: false,
|
|
131
|
+
isInWeb: false,
|
|
132
|
+
isCollidedHorizontally: false,
|
|
133
|
+
isCollidedVertically: false,
|
|
134
|
+
elytraFlying: false,
|
|
135
|
+
yaw: 0,
|
|
136
|
+
pitch: 0,
|
|
137
|
+
effects: {}
|
|
138
|
+
},
|
|
139
|
+
jumpTicks: 0,
|
|
140
|
+
jumpQueued: false,
|
|
141
|
+
fireworkRocketDuration: 0,
|
|
142
|
+
version: '1.13.2',
|
|
143
|
+
inventory: {
|
|
144
|
+
slots: []
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const playerState = new PlayerState(player, controls)
|
|
149
|
+
physics.simulatePlayer(playerState, fakeWorld).apply(player)
|
|
150
|
+
})
|
|
151
|
+
})
|
|
152
|
+
})
|