diff --git a/gameserver/src/main/java/brainwine/gameserver/GameServer.java b/gameserver/src/main/java/brainwine/gameserver/GameServer.java index 8ecc27a..d8f4903 100644 --- a/gameserver/src/main/java/brainwine/gameserver/GameServer.java +++ b/gameserver/src/main/java/brainwine/gameserver/GameServer.java @@ -27,7 +27,8 @@ public class GameServer { private final ZoneManager zoneManager; private final PlayerManager playerManager; private final Server server; - private long lastSave = System.currentTimeMillis(); + private long lastTick = System.currentTimeMillis(); + private long lastSave = lastTick; private boolean shutdownRequested; public GameServer() { @@ -56,6 +57,10 @@ public class GameServer { } public void tick() { + long now = System.currentTimeMillis(); + float deltaTime = (now - lastTick) / 1000.0F; // in seconds + lastTick = now; + while(!tasks.isEmpty()) { tasks.poll().run(); } @@ -66,7 +71,7 @@ public class GameServer { lastSave = System.currentTimeMillis(); } - zoneManager.tick(); + zoneManager.tick(deltaTime); playerManager.tick(); } diff --git a/gameserver/src/main/java/brainwine/gameserver/zone/WeatherManager.java b/gameserver/src/main/java/brainwine/gameserver/zone/WeatherManager.java new file mode 100644 index 0000000..7b783ef --- /dev/null +++ b/gameserver/src/main/java/brainwine/gameserver/zone/WeatherManager.java @@ -0,0 +1,66 @@ +package brainwine.gameserver.zone; + +import brainwine.gameserver.util.MathUtils; +import io.netty.util.internal.ThreadLocalRandom; + +/** + * TODO save weather in zone config + */ +public class WeatherManager { + + private static final ThreadLocalRandom random = ThreadLocalRandom.current(); + private long rainStart; + private long rainDuration; + private float rainPower; + private float precipitation; + private float wind; + private float cloudiness; + + public WeatherManager() { + createRandomRain(random.nextBoolean()); + } + + public void tick(float deltaTime) { + long now = System.currentTimeMillis(); + + if(now > rainStart + rainDuration) { + createRandomRain(rainPower > 0 ? true : false); + } + + float lerp = (float)(deltaTime * MathUtils.lerp(0.02F, 0.1F, (now - rainStart) / (float)rainDuration)); + // Why are these separate, again? + precipitation = (float)MathUtils.lerp(precipitation, rainPower, lerp); + wind = precipitation; + cloudiness = precipitation; + } + + public void setRain(float power, long duration) { + rainStart = System.currentTimeMillis(); + rainPower = power; + rainDuration = duration; + } + + public void createRandomRain(boolean dry) { + rainStart = System.currentTimeMillis(); + + if(dry) { + rainDuration = (long)(random.nextDouble(12, 17) * 60000); + rainPower = 0; + } else { + rainDuration = (long)(random.nextDouble(2.5, 4) * 60000); + rainPower = (float)random.nextDouble(0.33, 1.0); + } + } + + public float getPrecipitation() { + return precipitation; + } + + public float getWind() { + return wind; + } + + public float getCloudiness() { + return cloudiness; + } +} diff --git a/gameserver/src/main/java/brainwine/gameserver/zone/Zone.java b/gameserver/src/main/java/brainwine/gameserver/zone/Zone.java index bb76757..225c989 100644 --- a/gameserver/src/main/java/brainwine/gameserver/zone/Zone.java +++ b/gameserver/src/main/java/brainwine/gameserver/zone/Zone.java @@ -62,14 +62,12 @@ public class Zone { private int[] surface; private int[] sunlight; private boolean[] chunksExplored; - private float time = 5000; + private float time = (float)Math.random(); // TODO temporary private float temperature = 0; - private float wind = 0; - private float cloudiness = 5000; - private float precipitation = 0; private float acidity = 0; private final ChunkManager chunkManager; - private final Queue digQueue = new ArrayDeque<>(); // TODO should be saved + private final WeatherManager weatherManager = new WeatherManager(); + private final Queue digQueue = new ArrayDeque<>(); private final Set pendingSunlight = new HashSet<>(); private final Map entities = new HashMap<>(); private final List players = new ArrayList<>(); @@ -78,6 +76,7 @@ public class Zone { private final Map metaBlocks = new HashMap<>(); private final Map globalMetaBlocks = new HashMap<>(); private final Map fieldBlocks = new HashMap<>(); + private long lastStatusUpdate = System.currentTimeMillis(); protected Zone(String documentId, ZoneConfig config, ZoneData data) { this(documentId, config.getName(), config.getBiome(), config.getWidth(), config.getHeight()); @@ -107,15 +106,32 @@ public class Zone { return GameServer.getInstance().getZoneManager().getZone(id); } - public void tick() { + public void tick(float deltaTime) { + long now = System.currentTimeMillis(); + weatherManager.tick(deltaTime); + for(Entity entity : getEntities()) { entity.tick(); } + // One full cycle = 1200 seconds = 20 minutes + time += deltaTime * (1.0F / 1200.0F); + + if(time >= 1.0F) { + time -= 1.0F; + } + + if(!players.isEmpty()) { + if(now >= lastStatusUpdate + 4000) { + sendMessage(new ZoneStatusMessage(getStatusConfig())); + lastStatusUpdate = now; + } + } + if(!digQueue.isEmpty()) { DugBlock dugBlock = digQueue.peek(); - if(System.currentTimeMillis() >= dugBlock.getTime()) { + if(now >= dugBlock.getTime()) { digQueue.poll(); int x = dugBlock.getX(); int y = dugBlock.getY(); @@ -928,7 +944,14 @@ public class Zone { */ public Map getStatusConfig() { Map config = new HashMap<>(); - config.put("w", new float[]{time, temperature, wind, cloudiness, precipitation, acidity}); + config.put("w", new int[] { + (int)(time * 10000), + (int)(temperature * 10000), + (int)(weatherManager.getWind() * 10000), + (int)(weatherManager.getCloudiness() * 10000), + (int)(weatherManager.getPrecipitation() * 10000), + (int)(acidity * 10000) + }); return config; } diff --git a/gameserver/src/main/java/brainwine/gameserver/zone/ZoneManager.java b/gameserver/src/main/java/brainwine/gameserver/zone/ZoneManager.java index 845030c..1f08f4e 100644 --- a/gameserver/src/main/java/brainwine/gameserver/zone/ZoneManager.java +++ b/gameserver/src/main/java/brainwine/gameserver/zone/ZoneManager.java @@ -58,9 +58,9 @@ public class ZoneManager { asyncGenerator.start(); } - public void tick() { + public void tick(float deltaTime) { for(Zone zone : getZones()) { - zone.tick(); + zone.tick(deltaTime); } }