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: | ||||
|   * api.openweathermap.org | ||||
| - 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; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override // TODO TODO TODO | ||||
| 	@Override | ||||
| 	public void run() { | ||||
| 		for (Player player : server.getOnlinePlayers()) { | ||||
| 			if (!player.hasPermission("realweather.dynamic")) continue; | ||||
| 			 | ||||
| 			Weather weather = playerWeatherDirectory.getWeather(player); | ||||
| 			 | ||||
| 			if (weather != null) { | ||||
|  | @ -33,9 +34,8 @@ public class AsyncPlayerTimeTask extends BukkitRunnable { | |||
| 			} | ||||
| 			 | ||||
| 			Coordinates coordinates = mapper.locationToCoordinates(player.getLocation()); | ||||
| 			long offsetTicks = (long) (coordinates.longitude / (360 / 1728000)); | ||||
| 			player.setPlayerTime(offsetTicks, true); | ||||
| 			long offsetTicks = (long) ((coordinates.longitude / 15) * 1000 * timeConfig.scale); | ||||
| 			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 | ||||
| 	public void run() { | ||||
| 		long now = System.currentTimeMillis() / 1000; | ||||
| 		long time = (long) (((now / 3600 * 1000) - 6000) * timeConfig.modifier % 24000); // TODO test this | ||||
| 		// TODO double? | ||||
| 		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)); | ||||
| 		 // TODO add world handlers to mapper and don't calculate time each run | ||||
| 	} | ||||
| 	 | ||||
| } | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ public class TimeConfig { | |||
| 	// state is per player | ||||
| 	public boolean dynamic; | ||||
| 	// x day cycles in 1 irl day | ||||
| 	public double modifier; | ||||
| 	public double scale; | ||||
| 	 | ||||
| 	public static TimeConfig fromConfiguration(ConfigurationSection configuration) { | ||||
| 		TimeConfig timeConfig = new TimeConfig(); | ||||
|  | @ -16,7 +16,7 @@ public class TimeConfig { | |||
| 		timeConfig.enabled = configuration.getBoolean("enabled"); | ||||
| 		 | ||||
| 		timeConfig.dynamic = configuration.getBoolean("dynamic"); | ||||
| 		timeConfig.modifier = configuration.getDouble("modifier"); | ||||
| 		timeConfig.scale = configuration.getDouble("scale"); | ||||
| 		 | ||||
| 		return timeConfig; | ||||
| 	} | ||||
|  |  | |||
|  | @ -25,11 +25,17 @@ public class TimeMaster { | |||
| 			return; | ||||
| 		 | ||||
| 		 | ||||
| 		long period = 1; // TODO calculate update period | ||||
| 		new SyncTimeUpdateTask(config).runTaskTimer(plugin, 0, period); | ||||
| 		new AsyncPlayerTimeTask(config).runTaskTimerAsynchronously(plugin, 0, period); | ||||
| 		long period = (long) (72 / config.scale); | ||||
| 		 | ||||
| 		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); | ||||
| 	} | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Minecon724
				Minecon724