Add synchronized time and weather systems
This commit is contained in:
parent
30ad9215ca
commit
58fb3d6605
37 changed files with 1900 additions and 17 deletions
182
tests/world_time_validation.gd
Normal file
182
tests/world_time_validation.gd
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
extends SceneTree
|
||||
|
||||
const WorldTimeServiceType = preload("res://world/world_time_service.gd")
|
||||
const WorldTimeVisualControllerType = preload(
|
||||
"res://world/world_time_visual_controller.gd"
|
||||
)
|
||||
const NetworkWorldTimeServiceType = preload(
|
||||
"res://network/network_world_time_service.gd"
|
||||
)
|
||||
const FishingContextType = preload("res://fishing/fishing_context.gd")
|
||||
const FishDataType = preload("res://fish/fish_data.gd")
|
||||
const FishPoolType = preload("res://fish/fish_pool.gd")
|
||||
const FishingSpotType = preload("res://fishing/fishing_spot.gd")
|
||||
const FishableWaterRegionType = preload(
|
||||
"res://world/fishable_water_region.gd"
|
||||
)
|
||||
|
||||
const Catalog: FishPoolType = preload("res://fish/pools/fish_catalog.tres")
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
call_deferred("_run")
|
||||
|
||||
|
||||
func _run() -> void:
|
||||
_validate_clock_boundaries_and_duration()
|
||||
_validate_fishing_availability()
|
||||
_validate_fishing_spot_context()
|
||||
_validate_network_snapshot_bounds()
|
||||
_validate_environment_presentation()
|
||||
print("World time validation: PASS")
|
||||
quit()
|
||||
|
||||
|
||||
func _validate_clock_boundaries_and_duration() -> void:
|
||||
assert(WorldTimeServiceType.REAL_SECONDS_PER_CYCLE == 3600.0)
|
||||
assert(
|
||||
WorldTimeServiceType.phase_for_hour(7.49)
|
||||
== WorldTimeServiceType.Phase.NIGHT
|
||||
)
|
||||
assert(
|
||||
WorldTimeServiceType.phase_for_hour(7.5)
|
||||
== WorldTimeServiceType.Phase.DAWN
|
||||
)
|
||||
assert(
|
||||
WorldTimeServiceType.phase_for_hour(8.49)
|
||||
== WorldTimeServiceType.Phase.DAWN
|
||||
)
|
||||
assert(
|
||||
WorldTimeServiceType.phase_for_hour(8.5)
|
||||
== WorldTimeServiceType.Phase.DAY
|
||||
)
|
||||
assert(
|
||||
WorldTimeServiceType.phase_for_hour(19.5)
|
||||
== WorldTimeServiceType.Phase.DUSK
|
||||
)
|
||||
assert(
|
||||
WorldTimeServiceType.phase_for_hour(20.5)
|
||||
== WorldTimeServiceType.Phase.NIGHT
|
||||
)
|
||||
assert(WorldTimeServiceType.format_clock_time(0.0) == "12:00 am")
|
||||
assert(WorldTimeServiceType.format_clock_time(8.0) == "8:00 am")
|
||||
assert(WorldTimeServiceType.format_clock_time(20.5) == "8:30 pm")
|
||||
|
||||
var clock := WorldTimeServiceType.new()
|
||||
root.add_child(clock)
|
||||
clock.begin_session(8.0)
|
||||
clock.advance_time(1800.0)
|
||||
assert(is_equal_approx(clock.get_time_hours(), 20.0))
|
||||
assert(clock.is_night_period())
|
||||
assert(clock.is_transition())
|
||||
clock.advance_time(1800.0)
|
||||
assert(is_equal_approx(clock.get_time_hours(), 8.0))
|
||||
assert(not clock.is_night_period())
|
||||
assert(clock.is_transition())
|
||||
clock.queue_free()
|
||||
|
||||
|
||||
func _validate_fishing_availability() -> void:
|
||||
var day_context := FishingContextType.new()
|
||||
day_context.location_tags = [&"starter_pond"]
|
||||
day_context.is_night = false
|
||||
var night_context := FishingContextType.new()
|
||||
night_context.location_tags = [&"starter_pond"]
|
||||
night_context.is_night = true
|
||||
var transition_context := FishingContextType.new()
|
||||
transition_context.location_tags = [&"starter_pond"]
|
||||
transition_context.is_night = true
|
||||
transition_context.is_day_night_transition = true
|
||||
|
||||
for fish_id: StringName in [&"bluegill", &"sunfish"]:
|
||||
var day_fish: FishDataType = Catalog.get_fish_by_id(fish_id)
|
||||
assert(day_fish.availability.is_available(day_context))
|
||||
assert(not day_fish.availability.is_available(night_context))
|
||||
assert(day_fish.availability.is_available(transition_context))
|
||||
for fish_id: StringName in [
|
||||
&"catfish_blue",
|
||||
&"catfish_channel",
|
||||
&"catfish_flathead",
|
||||
&"catfish_white",
|
||||
]:
|
||||
var night_fish: FishDataType = Catalog.get_fish_by_id(fish_id)
|
||||
assert(not night_fish.availability.is_available(day_context))
|
||||
assert(night_fish.availability.is_available(night_context))
|
||||
assert(night_fish.availability.is_available(transition_context))
|
||||
for fish_id: StringName in [&"bass", &"carp"]:
|
||||
var all_time_fish: FishDataType = Catalog.get_fish_by_id(fish_id)
|
||||
assert(all_time_fish.availability.is_available(day_context))
|
||||
assert(all_time_fish.availability.is_available(night_context))
|
||||
assert(all_time_fish.availability.is_available(transition_context))
|
||||
|
||||
|
||||
func _validate_fishing_spot_context() -> void:
|
||||
var clock := WorldTimeServiceType.new()
|
||||
clock.begin_session(20.25)
|
||||
var fishing_spot := FishingSpotType.new()
|
||||
fishing_spot.set("_world_time", clock)
|
||||
var region := FishableWaterRegionType.new()
|
||||
region.location_tags = [&"starter_pond"]
|
||||
region.water_type = WaterType.Type.FRESH_WATER
|
||||
var dusk_context: FishingContext = fishing_spot.build_network_context(region)
|
||||
assert(dusk_context.is_night)
|
||||
assert(dusk_context.is_day_night_transition)
|
||||
clock.synchronize_time(14.0)
|
||||
var day_context: FishingContext = fishing_spot.build_network_context(region)
|
||||
assert(not day_context.is_night)
|
||||
assert(not day_context.is_day_night_transition)
|
||||
region.free()
|
||||
fishing_spot.free()
|
||||
clock.free()
|
||||
|
||||
|
||||
func _validate_network_snapshot_bounds() -> void:
|
||||
assert(NetworkWorldTimeServiceType.validate_snapshot({
|
||||
"session_id": "session",
|
||||
"time_hours": 8.25,
|
||||
"sequence": 1,
|
||||
}))
|
||||
assert(not NetworkWorldTimeServiceType.validate_snapshot({
|
||||
"session_id": "session",
|
||||
"time_hours": 24.0,
|
||||
"sequence": 1,
|
||||
}))
|
||||
assert(not NetworkWorldTimeServiceType.validate_snapshot({
|
||||
"session_id": "",
|
||||
"time_hours": 8.0,
|
||||
"sequence": 1,
|
||||
}))
|
||||
|
||||
|
||||
func _validate_environment_presentation() -> void:
|
||||
var world_root := Node3D.new()
|
||||
root.add_child(world_root)
|
||||
var world_environment := WorldEnvironment.new()
|
||||
var environment := Environment.new()
|
||||
var sky := Sky.new()
|
||||
sky.sky_material = ProceduralSkyMaterial.new()
|
||||
environment.sky = sky
|
||||
environment.adjustment_enabled = true
|
||||
environment.fog_enabled = true
|
||||
world_environment.environment = environment
|
||||
world_root.add_child(world_environment)
|
||||
var sun := DirectionalLight3D.new()
|
||||
world_root.add_child(sun)
|
||||
var clock := WorldTimeServiceType.new()
|
||||
world_root.add_child(clock)
|
||||
var visuals := WorldTimeVisualControllerType.new()
|
||||
world_root.add_child(visuals)
|
||||
visuals.setup(clock, world_environment, sun)
|
||||
visuals.apply_time_immediately(12.0)
|
||||
var runtime_environment: Environment = world_environment.environment
|
||||
var runtime_sky_material := (
|
||||
runtime_environment.sky.sky_material as ProceduralSkyMaterial
|
||||
)
|
||||
var day_horizon: Color = runtime_sky_material.sky_horizon_color
|
||||
var day_ambient_energy: float = runtime_environment.ambient_light_energy
|
||||
visuals.apply_time_immediately(0.0)
|
||||
assert(runtime_sky_material.sky_horizon_color != day_horizon)
|
||||
assert(runtime_environment.ambient_light_energy < day_ambient_energy)
|
||||
visuals.apply_time_immediately(20.0)
|
||||
assert(runtime_sky_material.sky_horizon_color.r > day_horizon.r)
|
||||
world_root.queue_free()
|
||||
Loading…
Add table
Add a link
Reference in a new issue