From 47213d6c4394900b8c6fe920f03f5e0064e2aabd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bj=C3=B8rge=20Andersen?= Date: Mon, 20 Jan 2025 23:55:05 +0100 Subject: [PATCH] feat: Allow sending spawnData when spawning entities using the MultiplayerService --- .../fxgl/multiplayer/MultiplayerService.kt | 13 +++++-- .../fxgl/multiplayer/NetworkSpawnData.kt | 36 +++++++++++++++++++ .../fxgl/multiplayer/ReplicationEvent.kt | 6 ++-- 3 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 fxgl/src/main/kotlin/com/almasb/fxgl/multiplayer/NetworkSpawnData.kt diff --git a/fxgl/src/main/kotlin/com/almasb/fxgl/multiplayer/MultiplayerService.kt b/fxgl/src/main/kotlin/com/almasb/fxgl/multiplayer/MultiplayerService.kt index df0c96207..14215a6d6 100644 --- a/fxgl/src/main/kotlin/com/almasb/fxgl/multiplayer/MultiplayerService.kt +++ b/fxgl/src/main/kotlin/com/almasb/fxgl/multiplayer/MultiplayerService.kt @@ -104,6 +104,10 @@ class MultiplayerService : EngineService() { } fun spawn(connection: Connection, entity: Entity, entityName: String) { + spawn(connection, entity, entityName, SpawnData(entity.x, entity.y, entity.z)) + } + + fun spawn(connection: Connection, entity: Entity, entityName: String, spawnData: SpawnData) { if (!entity.hasComponent(NetworkComponent::class.java)) { log.warning("Attempted to network-spawn entity $entityName, but it does not have NetworkComponent") return @@ -111,7 +115,7 @@ class MultiplayerService : EngineService() { val networkComponent = entity.getComponent(NetworkComponent::class.java) - val event = EntitySpawnEvent(networkComponent.id, entityName, entity.x, entity.y, entity.z) + val event = EntitySpawnEvent(networkComponent.id, entityName, NetworkSpawnData(spawnData)) // TODO: if not available val data = replicatedEntitiesMap[connection]!! @@ -129,7 +133,12 @@ class MultiplayerService : EngineService() { val id = event.networkID val entityName = event.entityName - val e = gameWorld.spawn(entityName, SpawnData(event.x, event.y, event.z)) + val networkSpawnData = event.networkSpawnData + val data = networkSpawnData.bundle.data + val spawnData = SpawnData(networkSpawnData.x, networkSpawnData.y, networkSpawnData.z) + data.forEach(spawnData::put) + + val e = gameWorld.spawn(entityName, spawnData) // TODO: show warning if not present e.getComponentOptional(NetworkComponent::class.java) diff --git a/fxgl/src/main/kotlin/com/almasb/fxgl/multiplayer/NetworkSpawnData.kt b/fxgl/src/main/kotlin/com/almasb/fxgl/multiplayer/NetworkSpawnData.kt new file mode 100644 index 000000000..d0eed7d57 --- /dev/null +++ b/fxgl/src/main/kotlin/com/almasb/fxgl/multiplayer/NetworkSpawnData.kt @@ -0,0 +1,36 @@ +/* + * FXGL - JavaFX Game Library. The MIT License (MIT). + * Copyright (c) AlmasB (almaslvl@gmail.com). + * See LICENSE for details. + */ + +package com.almasb.fxgl.multiplayer + +import com.almasb.fxgl.core.serialization.Bundle +import com.almasb.fxgl.entity.SpawnData +import java.io.Serializable + +/** + * Wrapper around SpawnData to be sent over network. + * + * @author Jonas Andersen (dev@jonasandersen.no) + */ +class NetworkSpawnData(spawnData: SpawnData) : Serializable { + + val bundle = Bundle("NetworkSpawnData") + var x: Double = 0.0 + var y: Double = 0.0 + var z: Double = 0.0 + + init { + x = spawnData.x + y = spawnData.y + z = spawnData.z + + spawnData.data.forEach { (key, value) -> + if (value is Serializable) { + bundle.put(key, value) + } + }; + } +} \ No newline at end of file diff --git a/fxgl/src/main/kotlin/com/almasb/fxgl/multiplayer/ReplicationEvent.kt b/fxgl/src/main/kotlin/com/almasb/fxgl/multiplayer/ReplicationEvent.kt index c7e95c11a..c616a7ffd 100644 --- a/fxgl/src/main/kotlin/com/almasb/fxgl/multiplayer/ReplicationEvent.kt +++ b/fxgl/src/main/kotlin/com/almasb/fxgl/multiplayer/ReplicationEvent.kt @@ -6,6 +6,7 @@ package com.almasb.fxgl.multiplayer +import com.almasb.fxgl.entity.SpawnData import javafx.event.Event import javafx.event.EventType import javafx.scene.input.KeyCode @@ -36,13 +37,10 @@ abstract class ReplicationEvent(eventType: EventType) : Ev } } -// TODO: consider SpawnData properties in the future class EntitySpawnEvent( val networkID: Long, val entityName: String, - val x: Double, - val y: Double, - val z: Double + val networkSpawnData: NetworkSpawnData, ) : ReplicationEvent(ENTITY_SPAWN) class EntityUpdateEvent(