Adds basic camp generation and placement logic to the map generation process. It attempts to place the camp in a valid location, avoiding paths and water bodies. It also sets the player's spawn point to the center of the generated camp, including some basic camp props like a tent, campfire, and bed. Additionally, vegetation spawning is now dependent on the `should_spawn_*` methods of the `CellDataResource`, allowing more control over what spawns where.
75 lines
2.1 KiB
GDScript
75 lines
2.1 KiB
GDScript
extends Node3D
|
|
|
|
@export var spawn_area_size: Vector2 = Vector2(2.0, 2.0)
|
|
@export var min_distance: float = 0.5
|
|
|
|
var spawned_positions: Array[Vector3] = []
|
|
var parent_ground_tile: GroundTile
|
|
|
|
func _ready():
|
|
parent_ground_tile = get_parent() as GroundTile
|
|
|
|
func spawn_trees_for_cell(cell_info: CellDataResource):
|
|
if not cell_info:
|
|
return
|
|
|
|
if not parent_ground_tile:
|
|
return
|
|
|
|
# Clear existing trees WITHOUT queue_free()
|
|
for child in get_children():
|
|
child.free() # Immediate cleanup instead of queue_free()
|
|
spawned_positions.clear()
|
|
|
|
# Spawn each tree in the array
|
|
var spawned_count = 0
|
|
var attempts = 0
|
|
var max_attempts = cell_info.trees.size() * 10
|
|
|
|
for tree_resource in cell_info.trees:
|
|
if attempts >= max_attempts:
|
|
Log.pr("Reached max attempts, could only spawn %d of %d trees" % [spawned_count, cell_info.trees.size()])
|
|
break
|
|
|
|
var pos = get_random_position()
|
|
|
|
if is_position_valid(pos):
|
|
spawn_tree_at_position(pos, tree_resource as TreeDataResource)
|
|
spawned_positions.append(pos)
|
|
spawned_count += 1
|
|
|
|
attempts += 1
|
|
|
|
#Log.pr("Spawned %d of %d trees in cell" % [spawned_count, cell_info.trees.size()])
|
|
|
|
func get_random_position() -> Vector3:
|
|
var rng = parent_ground_tile.get_rng()
|
|
var x = rng.randf_range(-spawn_area_size.x / 2, spawn_area_size.x / 2)
|
|
var z = rng.randf_range(-spawn_area_size.y / 2, spawn_area_size.y / 2)
|
|
return Vector3(x, 0, z)
|
|
|
|
func spawn_tree_at_position(pos: Vector3, tree_resource: TreeDataResource):
|
|
if not tree_resource:
|
|
Log.pr("No tree resource provided")
|
|
return
|
|
|
|
|
|
var tree_scene = preload("res://Entities/Tree/Tree.tscn")
|
|
var tree_instance = tree_scene.instantiate()
|
|
add_child(tree_instance)
|
|
tree_instance.position = pos
|
|
|
|
var rng = parent_ground_tile.get_rng()
|
|
tree_instance.rotation.y = rng.randf() * TAU
|
|
|
|
# Pass the TreeDataResource to the Tree instance
|
|
if tree_instance.has_method("set_tree_data"):
|
|
tree_instance.set_tree_data(tree_resource)
|
|
else:
|
|
Log.pr("Tree instance doesn't have set_tree_data() method")
|
|
|
|
func is_position_valid(pos: Vector3) -> bool:
|
|
for existing_pos in spawned_positions:
|
|
if pos.distance_to(existing_pos) < min_distance:
|
|
return false
|
|
return true
|