extends Node3D @export var spread_radius := 2.0 @export var spread_interval_min := 5.0 @export var spread_interval_max := 15.0 @export var max_mushrooms_in_radius := 3 @export var check_radius := 1.5 @export var max_total_mushrooms := 50 static var total_mushrooms := 0 @onready var spread_timer: Timer = $SpreadTimer @onready var ground_ray: RayCast3D = $GroundRay func _ready() -> void: total_mushrooms += 1 _setup_timer() # Randomize initial scale for variety scale = Vector3.ONE * randf_range(0.8, 1.2) rotation.y = randf_range(0, TAU) func _setup_timer() -> void: spread_timer.wait_time = randf_range(spread_interval_min, spread_interval_max) spread_timer.start() func _on_spread_timer_timeout() -> void: if total_mushrooms >= max_total_mushrooms: return if _count_nearby_mushrooms() >= max_mushrooms_in_radius: # Too crowded, try again later _setup_timer() return _attempt_spread() _setup_timer() func _attempt_spread() -> void: var random_angle := randf_range(0, TAU) var random_dist := randf_range(spread_radius * 0.5, spread_radius) var offset := Vector3(cos(random_angle) * random_dist, 5.0, sin(random_angle) * random_dist) ground_ray.position = offset ground_ray.force_raycast_update() if ground_ray.is_colliding(): var collision_point := ground_ray.get_collision_point() var collision_normal := ground_ray.get_collision_normal() # Only spread on relatively flat surfaces if collision_normal.dot(Vector3.UP) > 0.7: _spawn_mushroom(collision_point) func _spawn_mushroom(pos: Vector3) -> void: var mushroom_scene = load(scene_file_path) var new_mushroom = mushroom_scene.instantiate() get_parent().add_child(new_mushroom) new_mushroom.global_position = pos # Visual feedback/animation new_mushroom.scale = Vector3.ZERO var tween = create_tween() tween.tween_property(new_mushroom, "scale", Vector3.ONE * randf_range(0.8, 1.2), 1.0).set_trans(Tween.TRANS_BACK).set_ease(Tween.EASE_OUT) func _count_nearby_mushrooms() -> int: var count := 0 for mushroom in get_tree().get_nodes_in_group("mushrooms"): if mushroom == self: continue if global_position.distance_to(mushroom.global_position) < check_radius: count += 1 return count func _exit_tree() -> void: total_mushrooms -= 1