work on realtime
This commit is contained in:
parent
b2a474b011
commit
8931f32527
6 changed files with 87 additions and 13 deletions
|
@ -1,4 +1,6 @@
|
||||||
If you're using a firewall, you must whitelist the following domains:
|
If you're using a firewall, you must allow the following hosts:
|
||||||
|
- core functionality:
|
||||||
|
* rw-api.m724.eu
|
||||||
- weather:
|
- weather:
|
||||||
* api.openweathermap.org
|
* api.openweathermap.org
|
||||||
- thunder:
|
- thunder:
|
64
notes.txt
Normal file
64
notes.txt
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
goal: realtime to in game time conversion
|
||||||
|
There is no need to keep days
|
||||||
|
|
||||||
|
minecraft day is 0 - 24000 ticks
|
||||||
|
where 6000 ticks is noon (peak sun) and 18000 is midnight (peak moon)
|
||||||
|
|
||||||
|
irl day is 0 - 86400 seconds
|
||||||
|
|
||||||
|
0. s = epoch % 86400 to get seconds since midnight
|
||||||
|
^
|
||||||
|
(* scale) here
|
||||||
|
1. t = s / 72.0 to fit into minecraft day
|
||||||
|
2. t = t * 20 to convert that to ticks
|
||||||
|
3. t = t - 6000 to align noon and midnight
|
||||||
|
this leaves us with negative time, so
|
||||||
|
4. t = floorMod(t, 24000) to wrap if negative
|
||||||
|
|
||||||
|
example:
|
||||||
|
epoch = 1713593340
|
||||||
|
|
||||||
|
0. getting seconds since midnight
|
||||||
|
s = epoch % 86400
|
||||||
|
s = 1713593340 % 86400
|
||||||
|
s = 22140
|
||||||
|
|
||||||
|
1. conversion to minecraft day length
|
||||||
|
gs = s / 72.0
|
||||||
|
gs = 22140 / 72.0
|
||||||
|
gs = 307.5
|
||||||
|
|
||||||
|
2. to ticks
|
||||||
|
t = gs * 20
|
||||||
|
t = 307.5 * 20
|
||||||
|
t = 6150
|
||||||
|
|
||||||
|
3. step 3
|
||||||
|
t = t - 6000
|
||||||
|
t = 6150 - 6000
|
||||||
|
t = 150
|
||||||
|
|
||||||
|
4. wrapping
|
||||||
|
t = floorMod(150, 24000)
|
||||||
|
t = 150
|
||||||
|
|
||||||
|
|
||||||
|
goal: frequency of time update
|
||||||
|
|
||||||
|
t = 72 / scale
|
||||||
|
t is the period, in ticks of course
|
||||||
|
|
||||||
|
to see how many irl seconds a tick represents:
|
||||||
|
s = 3.6 * scale
|
||||||
|
(from 1 / (1/72 * 20 * scale))
|
||||||
|
|
||||||
|
however, some scales result in fractions
|
||||||
|
here's how many in game aligned seconds have passed at the end of a real day:
|
||||||
|
84000 / 72 * scale * floor(72/scale)
|
||||||
|
for scale 0.99: 83160
|
||||||
|
so we'll be 14 minutes behind
|
||||||
|
|
||||||
|
solution? for now let's warn and update time every tick
|
||||||
|
to check:
|
||||||
|
scale * floor(72/scale) == 72
|
||||||
|
|
|
@ -22,10 +22,11 @@ public class AsyncPlayerTimeTask extends BukkitRunnable {
|
||||||
this.timeConfig = timeConfig;
|
this.timeConfig = timeConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override // TODO TODO TODO
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
for (Player player : server.getOnlinePlayers()) {
|
for (Player player : server.getOnlinePlayers()) {
|
||||||
if (!player.hasPermission("realweather.dynamic")) continue;
|
if (!player.hasPermission("realweather.dynamic")) continue;
|
||||||
|
|
||||||
Weather weather = playerWeatherDirectory.getWeather(player);
|
Weather weather = playerWeatherDirectory.getWeather(player);
|
||||||
|
|
||||||
if (weather != null) {
|
if (weather != null) {
|
||||||
|
@ -33,9 +34,8 @@ public class AsyncPlayerTimeTask extends BukkitRunnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
Coordinates coordinates = mapper.locationToCoordinates(player.getLocation());
|
Coordinates coordinates = mapper.locationToCoordinates(player.getLocation());
|
||||||
long offsetTicks = (long) (coordinates.longitude / (360 / 1728000));
|
long offsetTicks = (long) ((coordinates.longitude / 15) * 1000 * timeConfig.scale);
|
||||||
player.setPlayerTime(offsetTicks, true);
|
player.setPlayerTime(offsetTicks, true); // TODO can this be negative?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO make this also a listener for player joins
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,12 @@ public class SyncTimeUpdateTask extends BukkitRunnable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
long now = System.currentTimeMillis() / 1000;
|
// TODO double?
|
||||||
long time = (long) (((now / 3600 * 1000) - 6000) * timeConfig.modifier % 24000); // TODO test this
|
long now = (long) (System.currentTimeMillis() * timeConfig.scale / 1000);
|
||||||
|
long time = Math.floorMod(now % 86400 / 72 * 20 - 6000, 24000);
|
||||||
|
|
||||||
mapper.getWorlds().forEach(world -> world.setFullTime(time));
|
mapper.getWorlds().forEach(world -> world.setFullTime(time));
|
||||||
|
// TODO add world handlers to mapper and don't calculate time each run
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ public class TimeConfig {
|
||||||
// state is per player
|
// state is per player
|
||||||
public boolean dynamic;
|
public boolean dynamic;
|
||||||
// x day cycles in 1 irl day
|
// x day cycles in 1 irl day
|
||||||
public double modifier;
|
public double scale;
|
||||||
|
|
||||||
public static TimeConfig fromConfiguration(ConfigurationSection configuration) {
|
public static TimeConfig fromConfiguration(ConfigurationSection configuration) {
|
||||||
TimeConfig timeConfig = new TimeConfig();
|
TimeConfig timeConfig = new TimeConfig();
|
||||||
|
@ -16,7 +16,7 @@ public class TimeConfig {
|
||||||
timeConfig.enabled = configuration.getBoolean("enabled");
|
timeConfig.enabled = configuration.getBoolean("enabled");
|
||||||
|
|
||||||
timeConfig.dynamic = configuration.getBoolean("dynamic");
|
timeConfig.dynamic = configuration.getBoolean("dynamic");
|
||||||
timeConfig.modifier = configuration.getDouble("modifier");
|
timeConfig.scale = configuration.getDouble("scale");
|
||||||
|
|
||||||
return timeConfig;
|
return timeConfig;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,17 @@ public class TimeMaster {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
long period = 1; // TODO calculate update period
|
long period = (long) (72 / config.scale);
|
||||||
new SyncTimeUpdateTask(config).runTaskTimer(plugin, 0, period);
|
|
||||||
new AsyncPlayerTimeTask(config).runTaskTimerAsynchronously(plugin, 0, period);
|
if (config.scale * Math.floor(period) == 72) {
|
||||||
|
// TODO log this properly
|
||||||
|
DebugLogger.info("Warning: RealTime scale is not optimal. Time will be out of sync.", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
new SyncTimeUpdateTask(config).runTaskTimer(plugin, 0, period);
|
||||||
|
new AsyncPlayerTimeTask(config).runTaskTimerAsynchronously(plugin, 0, period); // TODO maybe use a different period?
|
||||||
|
// TODO also make it on player join
|
||||||
|
|
||||||
// TODO start task, actually create that task, account for data from weather like sunrise sunset timezone
|
|
||||||
DebugLogger.info("time loaded", 1);
|
DebugLogger.info("time loaded", 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue