spectra-physics 1.0.0 → 1.1.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/README.md +31 -22
- package/index.js +2 -2
- package/lib/client/connection.js +83 -0
- package/lib/client/controls.js +78 -0
- package/lib/client/environment.js +125 -0
- package/lib/client/index.js +72 -0
- package/lib/client/reporter.js +91 -0
- package/lib/client/riding.js +65 -0
- package/lib/client/server.js +90 -0
- package/lib/client/teleport.js +108 -0
- package/lib/client/ticker.js +144 -0
- package/lib/engine/player/blocks.js +134 -0
- package/lib/engine/player/effects.js +152 -0
- package/lib/engine/player/fluids.js +141 -0
- package/lib/engine/player/index.js +202 -0
- package/lib/engine/player/input.js +86 -0
- package/lib/engine/player/move.js +135 -0
- package/lib/engine/player/pose.js +95 -0
- package/lib/engine/player/push.js +27 -0
- package/lib/engine/player/travel.js +203 -0
- package/lib/engine/version.js +49 -26
- package/lib/engine/world.js +3 -0
- package/package.json +1 -1
- package/lib/engine/physics.js +0 -780
- package/lib/plugin.js +0 -574
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { f32, sin, cos, degToRadF, clamp } = require('../mth')
|
|
4
|
+
const { moveRelative } = require('./input')
|
|
5
|
+
const { move } = require('./move')
|
|
6
|
+
const { fluidFallingAdjusted } = require('./fluids')
|
|
7
|
+
const blocks = require('./blocks')
|
|
8
|
+
|
|
9
|
+
const F_098 = f32(0.98)
|
|
10
|
+
const F_091 = f32(0.91)
|
|
11
|
+
const F_08 = f32(0.8)
|
|
12
|
+
const F_09 = f32(0.9)
|
|
13
|
+
const F_096 = f32(0.96)
|
|
14
|
+
const F_002 = f32(0.02)
|
|
15
|
+
const F_0026 = f32(0.025999999)
|
|
16
|
+
const F_0216 = f32(0.21600002)
|
|
17
|
+
const F_0546 = f32(0.54600006)
|
|
18
|
+
const F_015 = f32(0.15)
|
|
19
|
+
const F_042 = f32(0.42)
|
|
20
|
+
const F_01 = f32(0.1)
|
|
21
|
+
const F_02 = f32(0.2)
|
|
22
|
+
const F_004 = f32(0.04)
|
|
23
|
+
const F_06 = 0.6000000238418579
|
|
24
|
+
const F_03 = 0.30000001192092896
|
|
25
|
+
|
|
26
|
+
function flyingSpeed (player) {
|
|
27
|
+
if (!player.V.flyingSpeedLive) return player.legacyFlyingSpeed
|
|
28
|
+
if (player.abilities.flying) return player.sprinting ? f32(player.abilities.flyingSpeed * 2) : player.abilities.flyingSpeed
|
|
29
|
+
return player.sprinting ? F_0026 : F_002
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function frictionInfluencedSpeed (player, friction) {
|
|
33
|
+
if (player.onGround) return f32(player.movementSpeed() * f32(F_0216 / f32(f32(friction * friction) * friction)))
|
|
34
|
+
return flyingSpeed(player)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function handleOnClimbable (player) {
|
|
38
|
+
if (!blocks.onClimbable(player)) return
|
|
39
|
+
player.fallDistance = 0
|
|
40
|
+
player.vel.x = clamp(player.vel.x, -F_015, F_015)
|
|
41
|
+
player.vel.z = clamp(player.vel.z, -F_015, F_015)
|
|
42
|
+
let vy = Math.max(player.vel.y, -F_015)
|
|
43
|
+
if (vy < 0 && !blocks.feetBlock(player).isScaffolding && player.input.shift) vy = 0
|
|
44
|
+
player.vel.y = vy
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function isFree (player, dx, dy, dz) {
|
|
48
|
+
const box = player.bb().move(dx, dy, dz)
|
|
49
|
+
return player.world.noCollision(box) && !player.world.containsAnyLiquid(box)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// LivingEntity#jumpFromGround
|
|
53
|
+
function jumpFromGround (player) {
|
|
54
|
+
const V = player.V
|
|
55
|
+
const strength = V.attributes2005 ? f32(player.env.attribute('jump_strength', 0.42)) : F_042
|
|
56
|
+
let power = f32(strength * blocks.jumpFactor(player))
|
|
57
|
+
const boost = player.env.effect('jump_boost')
|
|
58
|
+
if (boost != null) power = f32(power + f32(F_01 * (boost + 1)))
|
|
59
|
+
if (V.attributes2005 && power <= 1.0e-5) return
|
|
60
|
+
player.vel.y = V.jumpKeepsHigherY ? Math.max(power, player.vel.y) : power
|
|
61
|
+
if (!player.sprinting) return
|
|
62
|
+
const r = degToRadF(player.yRot)
|
|
63
|
+
if (V.jumpDoubleSprintBoost) {
|
|
64
|
+
player.vel.x += -sin(r) * 0.2
|
|
65
|
+
player.vel.z += cos(r) * 0.2
|
|
66
|
+
} else {
|
|
67
|
+
player.vel.x += f32(-sin(r) * F_02)
|
|
68
|
+
player.vel.z += f32(cos(r) * F_02)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// jump handling in LivingEntity#aiStep
|
|
73
|
+
function handleJump (player) {
|
|
74
|
+
if (!player.input.jumping || player.abilities.flying) {
|
|
75
|
+
player.noJumpDelay = 0
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
const inLava = player.isInLava()
|
|
79
|
+
const height = inLava ? player.fluidHeight.lava : player.fluidHeight.water
|
|
80
|
+
const inWater = player.isInWater() && height > 0
|
|
81
|
+
const threshold = player.eyeHeight() < 0.4 ? 0 : 0.4
|
|
82
|
+
if (inWater && !(player.onGround && !(height > threshold))) {
|
|
83
|
+
player.vel.y += F_004
|
|
84
|
+
} else if (inLava && !(player.onGround && !(height > threshold))) {
|
|
85
|
+
player.vel.y += F_004
|
|
86
|
+
} else if ((player.onGround || (inWater && height <= threshold)) && player.noJumpDelay === 0) {
|
|
87
|
+
jumpFromGround(player)
|
|
88
|
+
player.noJumpDelay = 10
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function travelInWater (player, ix, iy, iz, gravity, falling) {
|
|
93
|
+
const V = player.V
|
|
94
|
+
const startY = player.pos.y
|
|
95
|
+
let friction = player.sprinting ? F_09 : F_08
|
|
96
|
+
let speed = F_002
|
|
97
|
+
let strider = V.efficiencyAttributes
|
|
98
|
+
? f32(player.env.attribute('water_movement_efficiency', 0))
|
|
99
|
+
: Math.min(3, player.env.bootsEnchant('depth_strider'))
|
|
100
|
+
if (!player.onGround) strider = f32(strider * 0.5)
|
|
101
|
+
if (strider > 0) {
|
|
102
|
+
const divisor = V.efficiencyAttributes ? 1 : 3
|
|
103
|
+
friction = f32(friction + f32(f32(f32(F_0546 - friction) * strider) / divisor))
|
|
104
|
+
speed = f32(speed + f32(f32(f32(player.movementSpeed() - speed) * strider) / divisor))
|
|
105
|
+
}
|
|
106
|
+
if (player.env.effect('dolphins_grace') != null) friction = F_096
|
|
107
|
+
moveRelative(player, speed, ix, iy, iz)
|
|
108
|
+
move(player, player.vel.x, player.vel.y, player.vel.z)
|
|
109
|
+
if (player.horizontalCollision && blocks.onClimbable(player)) player.vel.y = 0.2
|
|
110
|
+
player.vel.x *= friction
|
|
111
|
+
player.vel.y *= F_08
|
|
112
|
+
player.vel.z *= friction
|
|
113
|
+
fluidFallingAdjusted(player, gravity, falling)
|
|
114
|
+
if (player.horizontalCollision && isFree(player, player.vel.x, player.vel.y + F_06 - player.pos.y + startY, player.vel.z)) {
|
|
115
|
+
player.vel.y = F_03
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function travelInLava (player, ix, iy, iz, gravity, falling) {
|
|
120
|
+
const startY = player.pos.y
|
|
121
|
+
moveRelative(player, F_002, ix, iy, iz)
|
|
122
|
+
move(player, player.vel.x, player.vel.y, player.vel.z)
|
|
123
|
+
if (player.fluidHeight.lava <= 0.4) {
|
|
124
|
+
player.vel.x *= 0.5
|
|
125
|
+
player.vel.y *= F_08
|
|
126
|
+
player.vel.z *= 0.5
|
|
127
|
+
fluidFallingAdjusted(player, gravity, falling)
|
|
128
|
+
} else {
|
|
129
|
+
player.vel.x *= 0.5
|
|
130
|
+
player.vel.y *= 0.5
|
|
131
|
+
player.vel.z *= 0.5
|
|
132
|
+
}
|
|
133
|
+
player.vel.y += -gravity / 4
|
|
134
|
+
if (player.horizontalCollision && isFree(player, player.vel.x, player.vel.y + F_06 - player.pos.y + startY, player.vel.z)) {
|
|
135
|
+
player.vel.y = F_03
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function travelInAir (player, ix, iy, iz, gravity) {
|
|
140
|
+
const below = blocks.belowPos(player)
|
|
141
|
+
const friction = player.world.blockAt(below.x, below.y, below.z).friction
|
|
142
|
+
const drag = player.onGround ? f32(friction * F_091) : F_091
|
|
143
|
+
moveRelative(player, frictionInfluencedSpeed(player, friction), ix, iy, iz)
|
|
144
|
+
handleOnClimbable(player)
|
|
145
|
+
move(player, player.vel.x, player.vel.y, player.vel.z)
|
|
146
|
+
if ((player.horizontalCollision || player.input.jumping) && (blocks.onClimbable(player) || blocks.onPowderSnowWithBoots(player))) {
|
|
147
|
+
player.vel.y = 0.2
|
|
148
|
+
}
|
|
149
|
+
let vy = player.vel.y
|
|
150
|
+
const levitation = player.env.effect('levitation')
|
|
151
|
+
if (levitation != null) {
|
|
152
|
+
vy += (0.05 * (levitation + 1) - player.vel.y) * 0.2
|
|
153
|
+
player.fallDistance = 0
|
|
154
|
+
} else if (!player.world.hasChunk(below.x, below.z)) {
|
|
155
|
+
vy = player.pos.y > player.world.minY ? -0.1 : 0
|
|
156
|
+
} else {
|
|
157
|
+
vy -= gravity
|
|
158
|
+
}
|
|
159
|
+
player.vel.x *= drag
|
|
160
|
+
player.vel.y = vy * F_098
|
|
161
|
+
player.vel.z *= drag
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// LivingEntity#travel
|
|
165
|
+
function livingTravel (player, ix, iy, iz) {
|
|
166
|
+
const falling = player.vel.y <= 0
|
|
167
|
+
let gravity = player.V.attributes2005 ? player.env.attribute('gravity', 0.08) : 0.08
|
|
168
|
+
if (falling && player.env.effect('slow_falling') != null) {
|
|
169
|
+
gravity = player.V.attributes2005 ? Math.min(gravity, 0.01) : 0.01
|
|
170
|
+
player.fallDistance = 0
|
|
171
|
+
}
|
|
172
|
+
const affected = !player.abilities.flying
|
|
173
|
+
if (player.isInWater() && affected) travelInWater(player, ix, iy, iz, gravity, falling)
|
|
174
|
+
else if (player.isInLava() && affected) travelInLava(player, ix, iy, iz, gravity, falling)
|
|
175
|
+
else travelInAir(player, ix, iy, iz, gravity)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function swimTowardsLook (player) {
|
|
179
|
+
const lookY = -sin(degToRadF(player.xRot))
|
|
180
|
+
const k = lookY < -0.2 ? 0.085 : 0.06
|
|
181
|
+
const above = player.world.fluidAt(Math.floor(player.pos.x), Math.floor(player.pos.y + 1 - 0.1), Math.floor(player.pos.z))
|
|
182
|
+
if (lookY <= 0 || player.input.jumping || above) player.vel.y += (lookY - player.vel.y) * k
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Player#travel
|
|
186
|
+
function travel (player) {
|
|
187
|
+
const ix = player.xxa
|
|
188
|
+
const iz = player.zza
|
|
189
|
+
if (player.swimming && !player.riding) swimTowardsLook(player)
|
|
190
|
+
if (!player.abilities.flying) {
|
|
191
|
+
livingTravel(player, ix, 0, iz)
|
|
192
|
+
return
|
|
193
|
+
}
|
|
194
|
+
const startVy = player.vel.y
|
|
195
|
+
const saved = player.legacyFlyingSpeed
|
|
196
|
+
if (!player.V.flyingSpeedLive) player.legacyFlyingSpeed = f32(player.abilities.flyingSpeed * (player.sprinting ? 2 : 1))
|
|
197
|
+
livingTravel(player, ix, 0, iz)
|
|
198
|
+
player.vel.y = startVy * 0.6
|
|
199
|
+
player.legacyFlyingSpeed = saved
|
|
200
|
+
player.fallDistance = 0
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
module.exports = { travel, handleJump }
|
package/lib/engine/version.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use strict'
|
|
2
|
-
//
|
|
3
|
-
//
|
|
2
|
+
// Client behaviour that changed between 1.16.5 and 26.x, keyed by protocol number
|
|
3
|
+
// ("1.21.3" is 768, the same as 1.21.2).
|
|
4
4
|
|
|
5
5
|
const PV = {
|
|
6
6
|
'1.16.5': 754,
|
|
7
7
|
'1.17': 755,
|
|
8
|
+
'1.18.2': 758,
|
|
8
9
|
'1.19.4': 762,
|
|
9
10
|
'1.20': 763,
|
|
10
11
|
'1.20.2': 764,
|
|
11
|
-
'1.20.3': 765,
|
|
12
12
|
'1.20.5': 766,
|
|
13
13
|
'1.21': 767,
|
|
14
14
|
'1.21.2': 768,
|
|
@@ -19,34 +19,57 @@ const PV = {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
function versionFlags (registry) {
|
|
22
|
-
const pv = registry.version
|
|
22
|
+
const pv = registry.version.version
|
|
23
23
|
const at = (name) => pv >= PV[name]
|
|
24
24
|
return {
|
|
25
25
|
protocol: pv,
|
|
26
26
|
name: registry.version.minecraftVersion,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
movementFlags: at('1.21.2'),
|
|
31
|
-
tickEnd: at('1.21.2'),
|
|
32
|
-
playerInputPacket: at('1.21.2'),
|
|
33
|
-
shiftInInput: at('1.21.6'),
|
|
34
|
-
clientLoaded: at('1.21.4'),
|
|
35
|
-
posRotBeforeConfirm: pv === PV['1.21.2'],
|
|
36
|
-
relativeTeleportVelocity: at('1.21.2'),
|
|
37
|
-
lpVelocity: at('1.21.9'),
|
|
38
|
-
//
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
27
|
+
|
|
28
|
+
// connection
|
|
29
|
+
configPhase: at('1.20.2'),
|
|
30
|
+
movementFlags: at('1.21.2'),
|
|
31
|
+
tickEnd: at('1.21.2'),
|
|
32
|
+
playerInputPacket: at('1.21.2'),
|
|
33
|
+
shiftInInput: at('1.21.6'),
|
|
34
|
+
clientLoaded: at('1.21.4'),
|
|
35
|
+
posRotBeforeConfirm: pv === PV['1.21.2'],
|
|
36
|
+
relativeTeleportVelocity: at('1.21.2'),
|
|
37
|
+
lpVelocity: at('1.21.9'),
|
|
38
|
+
pointThree: !at('1.18.2'), // position is only reported after moving 0.03 (later 0.0002)
|
|
39
|
+
|
|
40
|
+
// input
|
|
41
|
+
inputModel: at('1.21.5') ? 'modern' : 'legacy',
|
|
42
|
+
floatSqrt: !at('1.17'),
|
|
43
|
+
normalizeEpsilon: at('1.21.2') ? Math.fround(1.0e-5) : 1.0e-4,
|
|
44
|
+
horizontalThreshold: at('1.21.5'), // tiny horizontal speed is cut by length, not per axis
|
|
45
|
+
|
|
46
|
+
// movement
|
|
47
|
+
posFromBoundingBox: !at('1.17'),
|
|
48
|
+
epsilonCollisionFlags: at('1.18.2'),
|
|
49
|
+
keepsXOnCornerCollision: !at('1.18.2'), // 1.14 - 1.18.1 bug
|
|
50
|
+
modernMoveThreshold: at('1.21.2'),
|
|
51
|
+
modernStepUp: at('1.21'),
|
|
52
|
+
supportingBlock: at('1.20'),
|
|
53
|
+
minorCollision: at('1.19.4'),
|
|
49
54
|
fallDistanceDouble: at('1.21.5'),
|
|
55
|
+
|
|
56
|
+
// speed
|
|
57
|
+
flyingSpeedLive: at('1.19.4'),
|
|
58
|
+
airSprintFloatSum: at('1.18.2'),
|
|
59
|
+
attributes2005: at('1.20.5'),
|
|
60
|
+
efficiencyAttributes: at('1.21'), // movement_efficiency / water_movement_efficiency
|
|
61
|
+
soulSpeedBoots: pv >= 751 && !at('1.21'),
|
|
62
|
+
jumpDoubleSprintBoost: at('1.20.5'),
|
|
63
|
+
jumpKeepsHigherY: at('1.21.2'),
|
|
64
|
+
|
|
65
|
+
// world interaction
|
|
66
|
+
blockEffectsAfterTravel: at('1.21.2'),
|
|
67
|
+
blockEffectsPerAxis: at('1.21.5'),
|
|
68
|
+
insideBlockDeflate: at('1.19.4') ? 1.0e-5 : 0.001,
|
|
69
|
+
fluidRecheckInMove: pv !== PV['1.21.4'],
|
|
70
|
+
swimmingNeedsFeetInWater: at('1.17'),
|
|
71
|
+
powderSnow: at('1.17'),
|
|
72
|
+
|
|
50
73
|
// vehicles
|
|
51
74
|
moveVehicleOnGround: at('1.21.2')
|
|
52
75
|
}
|
package/lib/engine/world.js
CHANGED
|
@@ -79,9 +79,12 @@ class WorldView {
|
|
|
79
79
|
isPowderSnow: name === 'powder_snow',
|
|
80
80
|
isScaffolding: name === 'scaffolding',
|
|
81
81
|
isFenceLike: name.endsWith('_fence') || name.endsWith('_wall') || name.endsWith('_fence_gate'),
|
|
82
|
+
isBubbleColumn: name === 'bubble_column',
|
|
83
|
+
bubbleDrag: props.drag === true || props.drag === 'true',
|
|
82
84
|
fullCube: shapes.length === 1 && shapes[0].every((v, k) => v === FULL[k]),
|
|
83
85
|
fluid: null
|
|
84
86
|
}
|
|
87
|
+
info.suffocating = info.fullCube && !(b?.transparent ?? true)
|
|
85
88
|
// fluids
|
|
86
89
|
if (name === 'water' || name === 'lava' || name === 'flowing_water' || name === 'flowing_lava') {
|
|
87
90
|
const level = Number(props.level ?? 0)
|