Added a simple weather & day/night system

This commit is contained in:
kuroppoi 2022-01-15 01:16:45 +01:00
parent c1940fbb5b
commit 4852ed89b1
4 changed files with 106 additions and 12 deletions

View file

@ -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();
}

View file

@ -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;
}
}

View file

@ -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<DugBlock> digQueue = new ArrayDeque<>(); // TODO should be saved
private final WeatherManager weatherManager = new WeatherManager();
private final Queue<DugBlock> digQueue = new ArrayDeque<>();
private final Set<Integer> pendingSunlight = new HashSet<>();
private final Map<Integer, Entity> entities = new HashMap<>();
private final List<Player> players = new ArrayList<>();
@ -78,6 +76,7 @@ public class Zone {
private final Map<Integer, MetaBlock> metaBlocks = new HashMap<>();
private final Map<Integer, MetaBlock> globalMetaBlocks = new HashMap<>();
private final Map<Integer, MetaBlock> 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<String, Object> getStatusConfig() {
Map<String, Object> 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;
}

View file

@ -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);
}
}