Fix rain puddle splash lifecycle
This commit is contained in:
parent
2b5b0a63ec
commit
1163cef320
3 changed files with 55 additions and 28 deletions
|
|
@ -83,11 +83,14 @@ func add_item_to_storage(item_id: StringName, quantity: int = 1) -> bool:
|
|||
if existing != null:
|
||||
existing.quantity += quantity
|
||||
else:
|
||||
var owned := OwnedItemType.new()
|
||||
owned.item_id = item_id
|
||||
owned.quantity = quantity
|
||||
owned.storage_slot = _first_available_storage_slot(item, _items)
|
||||
_items.append(owned)
|
||||
var new_owned_item := OwnedItemType.new()
|
||||
new_owned_item.item_id = item_id
|
||||
new_owned_item.quantity = quantity
|
||||
new_owned_item.storage_slot = _first_available_storage_slot(
|
||||
item,
|
||||
_items,
|
||||
)
|
||||
_items.append(new_owned_item)
|
||||
contents_changed.emit()
|
||||
return true
|
||||
if existing != null:
|
||||
|
|
|
|||
|
|
@ -50,6 +50,19 @@ func _run() -> void:
|
|||
assert(not puddles.is_processing())
|
||||
puddles.set_active(true)
|
||||
assert(puddles.is_processing())
|
||||
var splash_root := puddles.get_node("PuddleSplashes") as Node3D
|
||||
assert(splash_root != null)
|
||||
splash_root.position = Vector3(5.0, 1.0, -4.0)
|
||||
var expected_splash_position := Vector3(1.5, 2.04, -3.0)
|
||||
puddles.call("_emit_splash", Vector3(1.5, 0.0, -3.0), 2.0)
|
||||
assert(splash_root.get_child_count() == 1)
|
||||
var splash := splash_root.get_child(0) as CPUParticles3D
|
||||
assert(splash != null and splash.is_inside_tree())
|
||||
assert(splash.global_position.is_equal_approx(expected_splash_position))
|
||||
await create_timer(0.55).timeout
|
||||
await process_frame
|
||||
assert(not is_instance_valid(splash))
|
||||
splash_root.position = Vector3.ZERO
|
||||
for _tick: int in 18:
|
||||
puddles.call("_process", 0.25)
|
||||
assert(puddles.get_active_puddle_count() > 0)
|
||||
|
|
|
|||
|
|
@ -286,21 +286,21 @@ func _spawn_puddle_near(player_position: Vector3) -> bool:
|
|||
if triangle_index < 0 or triangle_index >= _surface_triangles.size():
|
||||
return false
|
||||
var triangle: PackedVector3Array = _surface_triangles[triangle_index]
|
||||
var position: Vector3 = _random_point_in_triangle(triangle)
|
||||
var candidate_position: Vector3 = _random_point_in_triangle(triangle)
|
||||
var horizontal_distance: float = Vector2(
|
||||
position.x,
|
||||
position.z,
|
||||
candidate_position.x,
|
||||
candidate_position.z,
|
||||
).distance_to(Vector2(player_position.x, player_position.z))
|
||||
if (
|
||||
horizontal_distance < MINIMUM_PLAYER_DISTANCE
|
||||
or horizontal_distance > MAXIMUM_PLAYER_DISTANCE
|
||||
or _is_candidate_blocked(position)
|
||||
or _is_near_existing_puddle(position)
|
||||
or _is_candidate_blocked(candidate_position)
|
||||
or _is_near_existing_puddle(candidate_position)
|
||||
):
|
||||
continue
|
||||
var maximum_radius: float = minf(
|
||||
MAXIMUM_PUDDLE_RADIUS,
|
||||
_minimum_triangle_edge_distance(position, triangle) * 0.65,
|
||||
_minimum_triangle_edge_distance(candidate_position, triangle) * 0.65,
|
||||
)
|
||||
if maximum_radius < MINIMUM_PUDDLE_RADIUS:
|
||||
continue
|
||||
|
|
@ -311,7 +311,7 @@ func _spawn_puddle_near(player_position: Vector3) -> bool:
|
|||
var radius_z: float = radius_x * _random.randf_range(0.58, 0.86)
|
||||
_activate_puddle(
|
||||
puddle,
|
||||
position,
|
||||
candidate_position,
|
||||
Vector2(radius_x, radius_z),
|
||||
_random.randf_range(0.0, TAU),
|
||||
)
|
||||
|
|
@ -440,15 +440,15 @@ func _apply_puddle_alpha(puddle: PuddleState) -> void:
|
|||
puddle.material.albedo_color = color
|
||||
|
||||
|
||||
func _is_candidate_blocked(position: Vector3) -> bool:
|
||||
func _is_candidate_blocked(candidate_position: Vector3) -> bool:
|
||||
if not is_inside_tree():
|
||||
return false
|
||||
var world: World3D = get_world_3d()
|
||||
if world == null:
|
||||
return false
|
||||
var query := PhysicsRayQueryParameters3D.create(
|
||||
position + Vector3.UP * 0.05,
|
||||
position + Vector3.UP * 1.75,
|
||||
candidate_position + Vector3.UP * 0.05,
|
||||
candidate_position + Vector3.UP * 1.75,
|
||||
TERRAIN_COLLISION_MASK,
|
||||
)
|
||||
query.collide_with_areas = false
|
||||
|
|
@ -456,8 +456,11 @@ func _is_candidate_blocked(position: Vector3) -> bool:
|
|||
return not world.direct_space_state.intersect_ray(query).is_empty()
|
||||
|
||||
|
||||
func _is_near_existing_puddle(position: Vector3) -> bool:
|
||||
var horizontal_position := Vector2(position.x, position.z)
|
||||
func _is_near_existing_puddle(candidate_position: Vector3) -> bool:
|
||||
var horizontal_position := Vector2(
|
||||
candidate_position.x,
|
||||
candidate_position.z,
|
||||
)
|
||||
for puddle: PuddleState in _puddles:
|
||||
if not puddle.active:
|
||||
continue
|
||||
|
|
@ -505,15 +508,14 @@ func _update_player_splashes(
|
|||
|
||||
|
||||
func _emit_splash(player_position: Vector3, surface_height: float) -> void:
|
||||
if _splash_root == null or not _splash_root.visible:
|
||||
if (
|
||||
_splash_root == null
|
||||
or not _splash_root.is_inside_tree()
|
||||
or not _splash_root.visible
|
||||
):
|
||||
return
|
||||
var particles := CPUParticles3D.new()
|
||||
particles.name = "RainPuddleSplash"
|
||||
particles.global_position = Vector3(
|
||||
player_position.x,
|
||||
surface_height + 0.04,
|
||||
player_position.z,
|
||||
)
|
||||
particles.amount = 7
|
||||
particles.lifetime = 0.38
|
||||
particles.one_shot = true
|
||||
|
|
@ -535,7 +537,13 @@ func _emit_splash(player_position: Vector3, surface_height: float) -> void:
|
|||
droplet_mesh.size = Vector3(0.028, 0.04, 0.028)
|
||||
droplet_mesh.material = material
|
||||
particles.mesh = droplet_mesh
|
||||
particles.emitting = false
|
||||
_splash_root.add_child(particles)
|
||||
particles.global_position = Vector3(
|
||||
player_position.x,
|
||||
surface_height + 0.04,
|
||||
player_position.z,
|
||||
)
|
||||
particles.emitting = true
|
||||
var cleanup := create_tween()
|
||||
cleanup.tween_interval(0.5)
|
||||
|
|
@ -548,10 +556,10 @@ func _seed_for_world() -> int:
|
|||
return max(_test_world.get_generation_seed(), 1) ^ 0x5261696e
|
||||
|
||||
|
||||
func _surface_cell_for(position: Vector3) -> Vector2i:
|
||||
func _surface_cell_for(surface_position: Vector3) -> Vector2i:
|
||||
return Vector2i(
|
||||
floori(position.x / SURFACE_CELL_SIZE),
|
||||
floori(position.z / SURFACE_CELL_SIZE),
|
||||
floori(surface_position.x / SURFACE_CELL_SIZE),
|
||||
floori(surface_position.z / SURFACE_CELL_SIZE),
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -567,10 +575,13 @@ func _random_point_in_triangle(triangle: PackedVector3Array) -> Vector3:
|
|||
|
||||
|
||||
func _minimum_triangle_edge_distance(
|
||||
position: Vector3,
|
||||
candidate_position: Vector3,
|
||||
triangle: PackedVector3Array,
|
||||
) -> float:
|
||||
var horizontal_position := Vector2(position.x, position.z)
|
||||
var horizontal_position := Vector2(
|
||||
candidate_position.x,
|
||||
candidate_position.z,
|
||||
)
|
||||
return minf(
|
||||
_horizontal_distance_to_segment(
|
||||
horizontal_position,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue