From d438d2aa14f4679fb889ade4a3240b857bbfd7f8 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Sun, 7 Feb 2021 01:01:37 +0300 Subject: [PATCH] Linked GravityModel to a WorldGenerator and added GM comms transfer - WorldData no longer acquires a GravityModel automatically - On the server, GravityModel is specified by WorldGenerator - On the client, GravityModel is received from the server via a PacketSetGravityModel --- .../common/world/PacketSetGravityModel.java | 56 +++++++++++++++++++ .../progressia/common/world/WorldData.java | 17 ++++-- .../server/comms/ClientManager.java | 5 ++ .../progressia/server/world/WorldLogic.java | 2 + .../generation/AbstractWorldGenerator.java | 16 +++++- .../world/generation/WorldGenerator.java | 3 + .../test/gen/TestWorldGenerator.java | 2 +- 7 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java diff --git a/src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java b/src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java new file mode 100644 index 0000000..7e7f95e --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/common/world/PacketSetGravityModel.java @@ -0,0 +1,56 @@ +/* + * Progressia + * Copyright (C) 2020-2021 Wind Corporation and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package ru.windcorp.progressia.common.world; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +public class PacketSetGravityModel extends PacketAffectWorld { + + private String gravityModelId; + + public PacketSetGravityModel() { + this("Core:SetGravityModel"); + } + + protected PacketSetGravityModel(String id) { + super(id); + } + + public void set(GravityModel model) { + this.gravityModelId = model.getId(); + } + + @Override + public void read(DataInput input) throws IOException, DecodingException { + gravityModelId = input.readUTF(); + } + + @Override + public void write(DataOutput output) throws IOException { + output.writeUTF(gravityModelId); + } + + @Override + public void apply(WorldData world) { + GravityModel model = GravityModelRegistry.getInstance().get(gravityModelId); + world.setGravityModel(model); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/common/world/WorldData.java b/src/main/java/ru/windcorp/progressia/common/world/WorldData.java index 6806c1b..625b8c2 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/WorldData.java +++ b/src/main/java/ru/windcorp/progressia/common/world/WorldData.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + package ru.windcorp.progressia.common.world; import java.util.ArrayList; @@ -51,8 +51,8 @@ public class WorldData private final TLongObjectMap entitiesById = TCollections.synchronizedMap(new TLongObjectHashMap<>()); private final Collection entities = Collections.unmodifiableCollection(entitiesById.valueCollection()); - - private GravityModel gravityModel = GravityModelRegistry.getInstance().get("Test:TheGravityModel"); + + private GravityModel gravityModel = null; private float time = 0; @@ -202,18 +202,25 @@ public class WorldData return null; return block.getCollisionModel(); } - + /** * @return the gravity model */ public GravityModel getGravityModel() { return gravityModel; } - + /** * @param gravityModel the gravity model to set */ public void setGravityModel(GravityModel gravityModel) { + if (!chunks.isEmpty()) { + throw new IllegalStateException( + "Attempted to change gravity model to " + gravityModel + " while " + chunks.size() + + " chunks were loaded" + ); + } + this.gravityModel = gravityModel; } diff --git a/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java b/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java index cb4b80b..74c636d 100644 --- a/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java +++ b/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java @@ -28,6 +28,7 @@ import gnu.trove.map.TIntObjectMap; import gnu.trove.map.hash.TIntObjectHashMap; import ru.windcorp.progressia.common.comms.CommsChannel.State; import ru.windcorp.progressia.common.comms.packets.Packet; +import ru.windcorp.progressia.common.world.PacketSetGravityModel; import ru.windcorp.progressia.common.world.PacketSetLocalPlayer; import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.server.Player; @@ -73,6 +74,10 @@ public class ClientManager { private void addClientPlayer(ClientPlayer client) { String login = client.getLogin(); + + PacketSetGravityModel setGravityModelPacket = new PacketSetGravityModel(); + setGravityModelPacket.set(getServer().getWorld().getData().getGravityModel()); + client.sendPacket(setGravityModelPacket); EntityData entity = getServer().getPlayerManager().conjurePlayerEntity(login); Player player = new Player(entity, getServer(), client); diff --git a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java index ad255f0..5931e34 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java +++ b/src/main/java/ru/windcorp/progressia/server/world/WorldLogic.java @@ -55,7 +55,9 @@ public class WorldLogic public WorldLogic(WorldData data, Server server, Function worldGeneratorConstructor) { this.data = data; this.server = server; + this.generator = worldGeneratorConstructor.apply(this); + data.setGravityModel(getGenerator().getGravityModel()); data.addListener(new WorldDataListener() { @Override diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java index ffb5c06..74583ff 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/AbstractWorldGenerator.java @@ -25,14 +25,23 @@ import java.util.Objects; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.DecodingException; +import ru.windcorp.progressia.common.world.GravityModel; +import ru.windcorp.progressia.common.world.GravityModelRegistry; public abstract class AbstractWorldGenerator extends WorldGenerator { private final Class hintClass; + + private final GravityModel gravityModel; - public AbstractWorldGenerator(String id, Class hintClass) { + public AbstractWorldGenerator(String id, Class hintClass, String gravityModelId) { super(id); this.hintClass = Objects.requireNonNull(hintClass, "hintClass"); + this.gravityModel = GravityModelRegistry.getInstance().get(Objects.requireNonNull(gravityModelId, "gravityModelId")); + + if (this.gravityModel == null) { + throw new IllegalArgumentException("Gravity model with ID \"" + gravityModelId + "\" not found"); + } } @Override @@ -63,5 +72,10 @@ public abstract class AbstractWorldGenerator extends WorldGenerator { protected void setHint(ChunkData chunk, H hint) { chunk.setGenerationHint(hint); } + + @Override + public GravityModel getGravityModel() { + return gravityModel; + } } diff --git a/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java b/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java index afed281..6a85e45 100644 --- a/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/server/world/generation/WorldGenerator.java @@ -26,6 +26,7 @@ import glm.vec._3.i.Vec3i; import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.world.ChunkData; import ru.windcorp.progressia.common.world.DecodingException; +import ru.windcorp.progressia.common.world.GravityModel; import ru.windcorp.progressia.common.world.WorldData; public abstract class WorldGenerator extends Namespaced { @@ -42,5 +43,7 @@ public abstract class WorldGenerator extends Namespaced { public abstract void writeGenerationHint(DataOutputStream output, Object hint) throws IOException; public abstract boolean isChunkReady(Object hint); + + public abstract GravityModel getGravityModel(); } diff --git a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java index 6a2f1cb..9d4ff6e 100644 --- a/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java +++ b/src/main/java/ru/windcorp/progressia/test/gen/TestWorldGenerator.java @@ -44,7 +44,7 @@ public class TestWorldGenerator extends AbstractWorldGenerator { private final TestTerrainGenerator terrainGen; public TestWorldGenerator(WorldLogic world) { - super("Test:WorldGenerator", Boolean.class); + super("Test:WorldGenerator", Boolean.class, "Test:TheGravityModel"); this.terrainGen = new TestTerrainGenerator(this, world); world.getData().addListener(new WorldDataListener() {