Skip to content

Commit

Permalink
Remove all entities (except for the player) when switching dimensions…
Browse files Browse the repository at this point in the history
…, and implement instant respawning (no respawn gui yet)
  • Loading branch information
stackotter committed Jun 6, 2024
1 parent de31540 commit 264da59
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 15 deletions.
11 changes: 11 additions & 0 deletions Sources/Core/Sources/Game.swift
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,17 @@ public final class Game: @unchecked Sendable {
// TODO: Make this threadsafe
self.world = newWorld
tickScheduler.setWorld(to: newWorld)

nexusLock.acquireWriteLock()
defer { nexusLock.unlock() }

entityIdToEntityIdentifier = entityIdToEntityIdentifier.filter { (id, identifier) in
let isClientPlayer = id == player.entityId.id
if !isClientPlayer {
nexus.destroy(entityId: identifier)
}
return isClientPlayer
}
}

/// Stops the tick scheduler.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public struct ChangeGameStatePacket: ClientboundPacket {
}

public func handle(for client: Client) throws {
print("Received ChangeGameStatePacket with reason \(reason)")
switch reason {
case .changeGamemode:
let rawValue = Int8(value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ public struct EntityStatusPacket: ClientboundEntityPacket {
/// Should only be called if a nexus lock has already been acquired.
public func handle(for client: Client) throws {
if status == .death {
// TODO: Play a death animation instead of instantly removing entities on death
client.game.removeEntity(acquireLock: false, id: entityId)
if entityId != client.game.accessPlayer(acquireLock: false, action: \.entityId.id) {
// TODO: Play a death animation instead of instantly removing entities on death
client.game.removeEntity(acquireLock: false, id: entityId)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ public enum RespawnPacketError: LocalizedError {
switch self {
case .invalidPreviousGamemodeRawValue(let rawValue):
return """
Invalid previous gamemode raw value.
Raw value: \(rawValue)
"""
Invalid previous gamemode raw value.
Raw value: \(rawValue)
"""
}
}
}
Expand Down Expand Up @@ -52,13 +52,17 @@ public struct RespawnPacket: ClientboundPacket {

isDebug = try packetReader.readBool()
isFlat = try packetReader.readBool()
copyMetadata = try packetReader.readBool() // TODO: not used yet
copyMetadata = try packetReader.readBool() // TODO: not used yet
}

public func handle(for client: Client) throws {
guard let currentDimension = client.game.dimensions.first(where: { dimension in
return dimension.identifier == currentDimensionIdentifier
}) else {
print("Received RespawnPacket")

guard
let currentDimension = client.game.dimensions.first(where: { dimension in
return dimension.identifier == currentDimensionIdentifier
})
else {
throw ClientboundPacketError.invalidDimension(currentDimensionIdentifier)
}

Expand All @@ -81,6 +85,10 @@ public struct RespawnPacket: ClientboundPacket {
client.game.accessPlayer { player in
player.gamemode.gamemode = gamemode
player.playerAttributes.previousGamemode = previousGamemode

// Reset player physics
player.acceleration.vector = .zero
player.velocity.vector = .zero
}

// TODO: get auto respawn working
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,28 @@ import Foundation

public struct UpdateHealthPacket: ClientboundPacket {
public static let id: Int = 0x49

public var health: Float
public var food: Int
public var foodSaturation: Float

public init(from packetReader: inout PacketReader) throws {
health = try packetReader.readFloat()
food = try packetReader.readVarInt()
food = try packetReader.readVarInt()
foodSaturation = try packetReader.readFloat()
}

public func handle(for client: Client) throws {
client.game.accessPlayer { player in
player.health.health = health
player.nutrition.food = food
player.nutrition.saturation = foodSaturation
}

if health <= 0 {
// TODO: Handle death
log.debug("Died")
// TODO: Implement respawn screen (shown when world has respawnScreenEnabled), for now
// we just instantly respawn.
try client.sendPacket(ClientStatusPacket(action: .performRespawn))
}
}
}

0 comments on commit 264da59

Please sign in to comment.