Skip to content

Commit

Permalink
Fix EntityMovementSystem (accidentally early exited loop whenever a l…
Browse files Browse the repository at this point in the history
…erping entity was reached, causing subsequent entities to never get updated)
  • Loading branch information
stackotter committed Jun 5, 2024
1 parent 10c4d32 commit a06d64a
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 16 deletions.
26 changes: 22 additions & 4 deletions Sources/Core/Sources/ECS/Components/EntityLerpState.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Foundation
import CoreFoundation
import FirebladeECS
import FirebladeMath
import Foundation

/// A component storing the lerp (if any) that an entity is currently undergoing; lerp is short
/// for linear interpolation.
Expand Down Expand Up @@ -46,8 +46,17 @@ public class EntityLerpState: Component {

/// Ticks an entities current lerp returning the entity's new position, pitch, and yaw. If there's no current
/// lerp, then `nil` is returned.
public func tick(position: Vec3d, pitch: Float, yaw: Float) -> (position: Vec3d, pitch: Float, yaw: Float)? {
guard var lerp = currentLerp else {
public func tick(
position: Vec3d,
pitch: Float,
yaw: Float
) -> (
position: Vec3d,
pitch: Float,
yaw: Float
)? {
guard var lerp = currentLerp, lerp.ticksRemaining > 0 else {
currentLerp = nil
return nil
}

Expand All @@ -60,10 +69,19 @@ public class EntityLerpState: Component {
currentLerp = lerp
}

let targetYaw: Float
if yaw - lerp.targetYaw > .pi {
targetYaw = lerp.targetYaw + 2 * .pi
} else if yaw - lerp.targetYaw < -.pi {
targetYaw = lerp.targetYaw - 2 * .pi
} else {
targetYaw = lerp.targetYaw
}

return (
MathUtil.lerp(from: position, to: lerp.targetPosition, progress: progress),
MathUtil.lerp(from: pitch, to: lerp.targetPitch, progress: Float(progress)),
MathUtil.lerp(from: yaw, to: lerp.targetYaw, progress: Float(progress))
MathUtil.lerp(from: yaw, to: targetYaw, progress: Float(progress))
)
}
}
9 changes: 6 additions & 3 deletions Sources/Core/Sources/ECS/Systems/EntityMovementSystem.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import FirebladeECS

/// Updates the position of each entity according to its velocity (excluding the player,
/// because velocity for the player is handled by the ``PlayerVelocitySystem-30ewl``).
/// because velocity for the player is handled by the ``PlayerVelocitySystem``). Also handles
/// position/rotation lerping.
public struct EntityMovementSystem: System {
public func update(_ nexus: Nexus, _ world: World) {
let physicsEntities = nexus.family(
Expand All @@ -20,11 +21,13 @@ public struct EntityMovementSystem: System {
continue
}

if let (newPosition, newPitch, newYaw) = lerpState.tick(position: position.vector, pitch: rotation.pitch, yaw: rotation.yaw) {
if let (newPosition, newPitch, newYaw) = lerpState.tick(
position: position.vector, pitch: rotation.pitch, yaw: rotation.yaw)
{
position.vector = newPosition
rotation.pitch = newPitch
rotation.yaw = newYaw
return
continue
}

velocity.vector *= 0.98
Expand Down
3 changes: 2 additions & 1 deletion Sources/Core/Sources/Game.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ public final class Game: @unchecked Sendable {
// together for the specific case of PlayerInputSystem); proper resource pack propagation
// will probably take quite a bit of work.
tickScheduler.addSystem(
PlayerInputSystem(connection, self, eventBus, configuration, font, locale))
PlayerInputSystem(connection, self, eventBus, configuration, font, locale)
)
tickScheduler.addSystem(PlayerFlightSystem())
tickScheduler.addSystem(PlayerAccelerationSystem())
tickScheduler.addSystem(PlayerJumpSystem())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Foundation
import FirebladeMath
import Foundation

public struct EntityPositionPacket: ClientboundEntityPacket {
public static let id: Int = 0x28
Expand Down Expand Up @@ -39,6 +39,9 @@ public struct EntityPositionPacket: ClientboundEntityPacket {
let kind = entity.get(component: EntityKindId.self)?.entityKind,
let onGroundComponent = entity.get(component: EntityOnGround.self)
else {
log.warning(
"Entity '\(entityId)' is missing required components to handle EntityPositionPacket"
)
return
}

Expand All @@ -50,8 +53,8 @@ public struct EntityPositionPacket: ClientboundEntityPacket {
onGroundComponent.onGround = onGround
lerpState.lerp(
to: currentTargetPosition + relativePosition,
pitch: rotation.pitch,
yaw: rotation.yaw,
pitch: lerpState.currentLerp?.targetPitch ?? rotation.pitch,
yaw: lerpState.currentLerp?.targetYaw ?? rotation.yaw,
duration: kind.defaultLerpDuration
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public struct EntityVelocityPacket: ClientboundEntityPacket {
) { velocityComponent in
// TODO: Figure out why handling velocity is causing entities to drift (observe spiders for a while
// to reproduce issue). Works best if spider is trying to climb a wall but it stuck under a roof.
// velocityComponent.vector = velocity
velocityComponent.vector = velocity
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation
import FirebladeECS
import FirebladeMath
import Foundation

public struct SpawnEntityPacket: ClientboundPacket {
public static let id: Int = 0x00
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Foundation
import FirebladeMath
import Foundation

public struct SpawnLivingEntityPacket: ClientboundPacket {
public static let id: Int = 0x02
Expand Down Expand Up @@ -30,7 +30,7 @@ public struct SpawnLivingEntityPacket: ClientboundPacket {
}

client.game.createEntity(id: entityId) {
LivingEntity() // Mark it as a living entity
LivingEntity() // Mark it as a living entity
EntityKindId(type)
EntityId(entityId)
EntityUUID(entityUUID)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Foundation
import FirebladeMath
import Foundation

public struct SpawnPlayerPacket: ClientboundPacket {
public static let id: Int = 0x04
Expand Down

0 comments on commit a06d64a

Please sign in to comment.