Add synchronized time and weather systems
This commit is contained in:
parent
30ad9215ca
commit
58fb3d6605
37 changed files with 1900 additions and 17 deletions
152
world/world_weather_service.gd
Normal file
152
world/world_weather_service.gd
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
class_name WorldWeatherService
|
||||
extends Node
|
||||
|
||||
signal weather_changed(weather: Weather, seconds_remaining: float)
|
||||
|
||||
enum Weather {
|
||||
SUNNY,
|
||||
CLOUDY,
|
||||
RAINY,
|
||||
FOGGY,
|
||||
}
|
||||
|
||||
const DEFAULT_WEATHER: Weather = Weather.SUNNY
|
||||
const SUNNY_DURATION_RANGE := Vector2(480.0, 900.0)
|
||||
const CLOUDY_DURATION_RANGE := Vector2(300.0, 720.0)
|
||||
const RAINY_DURATION_RANGE := Vector2(300.0, 600.0)
|
||||
const FOGGY_DURATION_RANGE := Vector2(300.0, 600.0)
|
||||
|
||||
var _weather: Weather = DEFAULT_WEATHER
|
||||
var _seconds_remaining: float = SUNNY_DURATION_RANGE.x
|
||||
var _running_authority: bool = false
|
||||
var _rng := RandomNumberGenerator.new()
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
set_process(false)
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
advance_weather(delta)
|
||||
|
||||
|
||||
func begin_authoritative_session(seed_value: int) -> void:
|
||||
_rng.seed = seed_value
|
||||
_running_authority = true
|
||||
set_process(true)
|
||||
_set_weather(DEFAULT_WEATHER, _roll_duration(DEFAULT_WEATHER), true)
|
||||
|
||||
|
||||
func begin_remote_session() -> void:
|
||||
_running_authority = false
|
||||
set_process(false)
|
||||
_set_weather(DEFAULT_WEATHER, SUNNY_DURATION_RANGE.x, true)
|
||||
|
||||
|
||||
func end_session() -> void:
|
||||
_running_authority = false
|
||||
set_process(false)
|
||||
_set_weather(DEFAULT_WEATHER, SUNNY_DURATION_RANGE.x, true)
|
||||
|
||||
|
||||
func advance_weather(real_seconds: float) -> void:
|
||||
if not _running_authority or real_seconds <= 0.0:
|
||||
return
|
||||
_seconds_remaining -= real_seconds
|
||||
while _seconds_remaining <= 0.0:
|
||||
var overrun: float = -_seconds_remaining
|
||||
var next_weather: Weather = _choose_next_weather()
|
||||
_set_weather(next_weather, _roll_duration(next_weather), true)
|
||||
_seconds_remaining -= overrun
|
||||
|
||||
|
||||
func apply_authoritative_snapshot(
|
||||
weather: Weather,
|
||||
seconds_remaining: float,
|
||||
) -> void:
|
||||
if not is_valid_weather(int(weather)) or not is_finite(seconds_remaining):
|
||||
return
|
||||
_set_weather(weather, maxf(seconds_remaining, 0.0), false)
|
||||
|
||||
|
||||
func get_weather() -> Weather:
|
||||
return _weather
|
||||
|
||||
|
||||
func get_seconds_remaining() -> float:
|
||||
return _seconds_remaining
|
||||
|
||||
|
||||
func is_raining() -> bool:
|
||||
return _weather == Weather.RAINY
|
||||
|
||||
|
||||
func is_foggy() -> bool:
|
||||
return _weather == Weather.FOGGY
|
||||
|
||||
|
||||
func get_weather_name() -> String:
|
||||
return weather_name(_weather)
|
||||
|
||||
|
||||
static func is_valid_weather(value: int) -> bool:
|
||||
return value >= Weather.SUNNY and value <= Weather.FOGGY
|
||||
|
||||
|
||||
static func weather_name(weather: Weather) -> String:
|
||||
match weather:
|
||||
Weather.SUNNY:
|
||||
return "sunny"
|
||||
Weather.CLOUDY:
|
||||
return "cloudy"
|
||||
Weather.RAINY:
|
||||
return "rainy"
|
||||
Weather.FOGGY:
|
||||
return "foggy"
|
||||
return "unknown"
|
||||
|
||||
|
||||
func _set_weather(
|
||||
weather: Weather,
|
||||
seconds_remaining: float,
|
||||
force_emit: bool,
|
||||
) -> void:
|
||||
var changed: bool = weather != _weather
|
||||
_weather = weather
|
||||
_seconds_remaining = maxf(seconds_remaining, 0.0)
|
||||
if force_emit or changed:
|
||||
weather_changed.emit(_weather, _seconds_remaining)
|
||||
|
||||
|
||||
func _choose_next_weather() -> Weather:
|
||||
match _weather:
|
||||
Weather.SUNNY:
|
||||
return Weather.CLOUDY
|
||||
Weather.RAINY, Weather.FOGGY:
|
||||
return Weather.CLOUDY
|
||||
Weather.CLOUDY:
|
||||
var roll: float = _rng.randf()
|
||||
if roll < 0.45:
|
||||
return Weather.SUNNY
|
||||
if roll < 0.80:
|
||||
return Weather.RAINY
|
||||
return Weather.FOGGY
|
||||
return Weather.SUNNY
|
||||
|
||||
|
||||
func _roll_duration(weather: Weather) -> float:
|
||||
var duration_range: Vector2 = _duration_range(weather)
|
||||
return _rng.randf_range(duration_range.x, duration_range.y)
|
||||
|
||||
|
||||
func _duration_range(weather: Weather) -> Vector2:
|
||||
match weather:
|
||||
Weather.SUNNY:
|
||||
return SUNNY_DURATION_RANGE
|
||||
Weather.CLOUDY:
|
||||
return CLOUDY_DURATION_RANGE
|
||||
Weather.RAINY:
|
||||
return RAINY_DURATION_RANGE
|
||||
Weather.FOGGY:
|
||||
return FOGGY_DURATION_RANGE
|
||||
return SUNNY_DURATION_RANGE
|
||||
Loading…
Add table
Add a link
Reference in a new issue