Random object generation

Godot Version

v4.3.stable.steam [77dcf97d8]

Question

I am randomly generating a topdown world using the Gaea addon: GitHub - BenjaTK/Gaea: Procedural generation add-on for Godot 4.
and I have a script to spawn trees around (green squares) the problem is the trees will spawn anywhere like on water, so I need a way to control where they spawn I only want them to spawn on certain tiles I’ve tried using metadata and atlas cords source ids, don’t seem to work because most of my tiles have the same as I’m using a tilemap

I also need it to beable to add intractability easily (like so the player can chop down the tree)

Extra stuff

here is my code (for randomly generating trees):

extends Node2D

@export var tree_scene: PackedScene
@export var object_count: int = 100
@export var map_width: int = 135
@export var map_height: int = 135
@export var tile_size: int = 16

@onready var tilemap = get_node("../TileMap")  # Adjust the path if necessary

# Dictionary mapping valid tile IDs to whether they are spawnable
var spawnable_tiles = {
	0: true,  # Example: Tile ID 1 is spawnable
	1: true   # Example: Tile ID 2 is spawnable
}

func _ready():
	if not tilemap:
		print("TileMap not found! Check the node path.")
		return
	print("TileMap found: ", tilemap)

	spawn_objects()

func spawn_objects():
	var spawned_count = 0
	var attempts = 0

	while spawned_count < object_count and attempts < object_count * 10:
		# Generate random tile coordinates
		var random_tile = Vector2i(
			randi() % map_width,
			randi() % map_height
		)

		# Get the source ID of the tile
		var tile_id = tilemap.get_cell_source_id(0, random_tile)
		print("Attempt ", attempts, ": Tile ID at ", random_tile, ": ", tile_id)

		if tile_id != -1:  # Ensure the tile is valid
			# Check if the tile is marked as spawnable
			if spawnable_tiles.get(tile_id, false):
				# Convert tile coordinates to world position
				var world_pos = Vector2(random_tile) * tile_size + tilemap.position
				print("Spawning at ", world_pos, " with tile ID ", tile_id)
				spawn_object(world_pos)
				spawned_count += 1
			else:
				print("Tile ID ", tile_id, " is not spawnable.")
		else:
			print("Invalid tile at ", random_tile)

		attempts += 1

	print("Spawned ", spawned_count, " objects out of ", object_count, " after ", attempts, " attempts.")


func spawn_object(spawn_pos: Vector2):
	var instance = tree_scene.instantiate()
	instance.position = spawn_pos
	add_child(instance)

my main world scene setup (note some of these nodes are customly added by the Gaea addon:

image

the Gaea addon (Im using this to randomly generate terrain):

Thank you

if you want interactability you should instead use a scene-atlas, which allows you to place scenes as tiles in your tilemap