diff --git a/src/game.zig b/src/game.zig index a23e18967c..0f828a43ac 100644 --- a/src/game.zig +++ b/src/game.zig @@ -408,11 +408,19 @@ pub const DamageType = enum(u8) { }; pub const Player = struct { // MARK: Player + pub const EyeData = struct { + pos: Vec3d = .{0, 0, 0}, + vel: Vec3d = .{0, 0, 0}, + coyote: f64 = 0.0, + step: @Vector(3, bool) = .{false, false, false}, + box: collision.Box = .{ + .min = -Vec3d{standingBoundingBoxExtent[0]*0.2, standingBoundingBoxExtent[1]*0.2, 0.6}, + .max = Vec3d{standingBoundingBoxExtent[0]*0.2, standingBoundingBoxExtent[1]*0.2, 0.9 - 0.05}, + }, + desiredPos: Vec3d = .{0, 0, 1.7 - standingBoundingBoxExtent[2]}, + }; pub var super: main.server.Entity = .{}; - pub var eyePos: Vec3d = .{0, 0, 0}; - pub var eyeVel: Vec3d = .{0, 0, 0}; - pub var eyeCoyote: f64 = 0; - pub var eyeStep: @Vector(3, bool) = .{false, false, false}; + pub var eye: EyeData = .{}; pub var crouching: bool = false; pub var id: u32 = 0; pub var gamemode: Atomic(Gamemode) = .init(.creative); @@ -446,11 +454,6 @@ pub const Player = struct { // MARK: Player .min = -standingBoundingBoxExtent, .max = standingBoundingBoxExtent, }; - pub var eyeBox: collision.Box = .{ - .min = -Vec3d{standingBoundingBoxExtent[0]*0.2, standingBoundingBoxExtent[1]*0.2, 0.6}, - .max = Vec3d{standingBoundingBoxExtent[0]*0.2, standingBoundingBoxExtent[1]*0.2, 0.9 - 0.05}, - }; - pub var desiredEyePos: Vec3d = .{0, 0, 1.7 - standingBoundingBoxExtent[2]}; pub const jumpHeight = 1.25; fn loadFrom(zon: ZonElement) void { @@ -478,19 +481,19 @@ pub const Player = struct { // MARK: Player pub fn getEyePosBlocking() Vec3d { mutex.lock(); defer mutex.unlock(); - return eyePos + super.pos + desiredEyePos; + return eye.pos + super.pos + eye.desiredPos; } pub fn getEyeVelBlocking() Vec3d { mutex.lock(); defer mutex.unlock(); - return eyeVel; + return eye.vel; } pub fn getEyeCoyoteBlocking() f64 { mutex.lock(); defer mutex.unlock(); - return eyeCoyote; + return eye.coyote; } pub fn getJumpCoyoteBlocking() f64 { @@ -547,11 +550,8 @@ pub const Player = struct { // MARK: Player Player.super.health = Player.super.maxHealth; Player.super.energy = Player.super.maxEnergy; - Player.eyePos = .{0, 0, 0}; - Player.eyeVel = .{0, 0, 0}; - Player.eyeCoyote = 0; + Player.eye = .{}; Player.jumpCoyote = 0; - Player.eyeStep = .{false, false, false}; } pub fn breakBlock(deltaTime: f64) void { @@ -878,7 +878,7 @@ pub fn update(deltaTime: f64) void { // MARK: update() jumping = true; Player.jumpCooldown = Player.jumpCooldownConstant; if(!Player.onGround) { - Player.eyeCoyote = 0; + Player.eye.coyote = 0; } Player.jumpCoyote = 0; } else if(!KeyBoard.key("fall").pressed) { @@ -955,11 +955,11 @@ pub fn update(deltaTime: f64) void { // MARK: update() .min = -Player.outerBoundingBoxExtent, .max = Player.outerBoundingBoxExtent, }; - Player.eyeBox = .{ + Player.eye.box = .{ .min = -Vec3d{Player.outerBoundingBoxExtent[0]*0.2, Player.outerBoundingBoxExtent[1]*0.2, Player.outerBoundingBoxExtent[2] - 0.2}, .max = Vec3d{Player.outerBoundingBoxExtent[0]*0.2, Player.outerBoundingBoxExtent[1]*0.2, Player.outerBoundingBoxExtent[2] - 0.05}, }; - Player.desiredEyePos = (Vec3d{0, 0, 1.3 - Player.crouchingBoundingBoxExtent[2]} - Vec3d{0, 0, 1.7 - Player.standingBoundingBoxExtent[2]})*@as(Vec3f, @splat(smoothPerc)) + Vec3d{0, 0, 1.7 - Player.standingBoundingBoxExtent[2]}; + Player.eye.desiredPos = (Vec3d{0, 0, 1.3 - Player.crouchingBoundingBoxExtent[2]} - Vec3d{0, 0, 1.7 - Player.standingBoundingBoxExtent[2]})*@as(Vec3f, @splat(smoothPerc)) + Vec3d{0, 0, 1.7 - Player.standingBoundingBoxExtent[2]}; } physics.update(deltaTime, acc, jumping); diff --git a/src/itemdrop.zig b/src/itemdrop.zig index 57ea278f3b..b4f0aca85c 100644 --- a/src/itemdrop.zig +++ b/src/itemdrop.zig @@ -558,7 +558,7 @@ pub const ItemDisplayManager = struct { // MARK: ItemDisplayManager if(deltaTime == 0) return; const dt: f32 = @floatCast(deltaTime); - var playerVel: Vec3f = .{@floatCast((game.Player.super.vel[2]*0.009 + game.Player.eyeVel[2]*0.0075)), 0, 0}; + var playerVel: Vec3f = .{@floatCast((game.Player.super.vel[2]*0.009 + game.Player.eye.vel[2]*0.0075)), 0, 0}; playerVel = vec.clampMag(playerVel, 0.32); // TODO: add *smooth* item sway diff --git a/src/physics.zig b/src/physics.zig index 83c144eebe..b9aa7db27e 100644 --- a/src/physics.zig +++ b/src/physics.zig @@ -84,10 +84,10 @@ pub fn update(deltaTime: f64, inputAcc: Vec3d, jumping: bool) void { // MARK: up 30, 30, }; - const strength = (-Player.eyePos)/(Player.eyeBox.max - Player.eyeBox.min); + const strength = (-Player.eye.pos)/(Player.eye.box.max - Player.eye.box.min); const force = strength*forceMultipliers; const friction = frictionMultipliers; - springConstants += forceMultipliers/(Player.eyeBox.max - Player.eyeBox.min); + springConstants += forceMultipliers/(Player.eye.box.max - Player.eye.box.min); directionalFrictionCoefficients += @floatCast(friction); acc += force; } @@ -97,21 +97,21 @@ pub fn update(deltaTime: f64, inputAcc: Vec3d, jumping: bool) void { // MARK: up // dx/dt = v // Where a is the acceleration, k is the spring constant and λ is the friction coefficient inline for(0..3) |i| blk: { - if(Player.eyeStep[i]) { - const oldPos = Player.eyePos[i]; - const newPos = oldPos + Player.eyeVel[i]*deltaTime; - if(newPos*std.math.sign(Player.eyeVel[i]) <= -0.1) { - Player.eyePos[i] = newPos; + if(Player.eye.step[i]) { + const oldPos = Player.eye.pos[i]; + const newPos = oldPos + Player.eye.vel[i]*deltaTime; + if(newPos*std.math.sign(Player.eye.vel[i]) <= -0.1) { + Player.eye.pos[i] = newPos; break :blk; } else { - Player.eyeStep[i] = false; + Player.eye.step[i] = false; } } - if(i == 2 and Player.eyeCoyote > 0) { + if(i == 2 and Player.eye.coyote > 0) { break :blk; } const frictionCoefficient = directionalFrictionCoefficients[i]; - const v_0 = Player.eyeVel[i]; + const v_0 = Player.eye.vel[i]; const k = springConstants[i]; const a = acc[i]; // here we need to solve the full equation: @@ -141,8 +141,8 @@ pub fn update(deltaTime: f64, inputAcc: Vec3d, jumping: bool) void { // MARK: up // x(t) = a/k + c_1 e^(1/2 t (-c_3 - λ)) + c_2 e^(1/2 t (c_3 - λ)) const firstTerm = c_1.mul((c_3.negate().subScalar(frictionCoefficient)).mulScalar(deltaTime/2).exp()); const secondTerm = c_2.mul((c_3.subScalar(frictionCoefficient)).mulScalar(deltaTime/2).exp()); - Player.eyeVel[i] = firstTerm.mul(c_3.negate().subScalar(frictionCoefficient).mulScalar(0.5)).add(secondTerm.mul((c_3.subScalar(frictionCoefficient)).mulScalar(0.5))).val[0]; - Player.eyePos[i] += firstTerm.add(secondTerm).addScalar(a/k).val[0]; + Player.eye.vel[i] = firstTerm.mul(c_3.negate().subScalar(frictionCoefficient).mulScalar(0.5)).add(secondTerm.mul((c_3.subScalar(frictionCoefficient)).mulScalar(0.5))).val[0]; + Player.eye.pos[i] += firstTerm.add(secondTerm).addScalar(a/k).val[0]; } } @@ -155,7 +155,7 @@ pub fn update(deltaTime: f64, inputAcc: Vec3d, jumping: bool) void { // MARK: up if(Player.super.vel[2] > 0) { steppingHeight = Player.super.vel[2]*Player.super.vel[2]/gravity/2; } - steppingHeight = @min(steppingHeight, Player.eyePos[2] - Player.eyeBox.min[2]); + steppingHeight = @min(steppingHeight, Player.eye.pos[2] - Player.eye.box.min[2]); const slipLimit = 0.25*Player.currentFriction; @@ -186,17 +186,17 @@ pub fn update(deltaTime: f64, inputAcc: Vec3d, jumping: bool) void { // MARK: up const stepAmount = xMovement[2] + yMovement[2]; if(stepAmount > 0) { - if(Player.eyeCoyote <= 0) { - Player.eyeVel[2] = @max(1.5*vec.length(Player.super.vel), Player.eyeVel[2], 4); - Player.eyeStep[2] = true; + if(Player.eye.coyote <= 0) { + Player.eye.vel[2] = @max(1.5*vec.length(Player.super.vel), Player.eye.vel[2], 4); + Player.eye.step[2] = true; if(Player.super.vel[2] > 0) { - Player.eyeVel[2] = Player.super.vel[2]; - Player.eyeStep[2] = false; + Player.eye.vel[2] = Player.super.vel[2]; + Player.eye.step[2] = false; } } else { - Player.eyeCoyote = 0; + Player.eye.coyote = 0; } - Player.eyePos[2] -= stepAmount; + Player.eye.pos[2] -= stepAmount; move[2] = -0.01; Player.onGround = true; } @@ -207,12 +207,12 @@ pub fn update(deltaTime: f64, inputAcc: Vec3d, jumping: bool) void { // MARK: up if(collision.collides(.client, .z, -move[2], Player.super.pos, hitBox)) |box| { if(move[2] < 0) { if(!wasOnGround) { - Player.eyeVel[2] = Player.super.vel[2]; - Player.eyePos[2] -= (box.max[2] - hitBox.min[2] - Player.super.pos[2]); + Player.eye.vel[2] = Player.super.vel[2]; + Player.eye.pos[2] -= (box.max[2] - hitBox.min[2] - Player.super.pos[2]); } Player.onGround = true; Player.super.pos[2] = box.max[2] - hitBox.min[2]; - Player.eyeCoyote = 0; + Player.eye.coyote = 0; } else { Player.super.pos[2] = box.min[2] - hitBox.max[2]; } @@ -226,7 +226,7 @@ pub fn update(deltaTime: f64, inputAcc: Vec3d, jumping: bool) void { // MARK: up velocityChange = Player.super.vel[2]*@as(f64, @floatCast(1 - bounciness)); Player.super.vel[2] = -Player.super.vel[2]*bounciness; Player.jumpCoyote = Player.jumpCoyoteTimeConstant + deltaTime; - Player.eyeVel[2] *= 2; + Player.eye.vel[2] *= 2; } else { velocityChange = Player.super.vel[2]; Player.super.vel[2] = 0; @@ -244,19 +244,19 @@ pub fn update(deltaTime: f64, inputAcc: Vec3d, jumping: bool) void { // MARK: up // If the player drops off a ledge, they might just be walking over a small gap, so lock the y position of the eyes that long. // This calculates how long the player has to fall until we know they're not walking over a small gap. // We add deltaTime because we subtract deltaTime at the bottom of update - Player.eyeCoyote = @sqrt(2*Player.steppingHeight()[2]/gravity) + deltaTime; + Player.eye.coyote = @sqrt(2*Player.steppingHeight()[2]/gravity) + deltaTime; Player.jumpCoyote = Player.jumpCoyoteTimeConstant + deltaTime; - Player.eyePos[2] -= move[2]; - } else if(Player.eyeCoyote > 0) { - Player.eyePos[2] -= move[2]; + Player.eye.pos[2] -= move[2]; + } else if(Player.eye.coyote > 0) { + Player.eye.pos[2] -= move[2]; } collision.touchBlocks(&Player.super, hitBox, .client, deltaTime); } else { Player.super.pos += move; } - // Clamp the eyePosition and subtract eye coyote time. - Player.eyePos = @max(Player.eyeBox.min, @min(Player.eyePos, Player.eyeBox.max)); - Player.eyeCoyote -= deltaTime; + // Clamp the eye.position and subtract eye coyote time. + Player.eye.pos = @max(Player.eye.box.min, @min(Player.eye.pos, Player.eye.box.max)); + Player.eye.coyote -= deltaTime; Player.jumpCoyote -= deltaTime; }