deleted demo task and added placable extractors
Build Godot Project (Linux) / build-linux (push) Successful in 28s

This commit is contained in:
2026-06-22 16:34:38 -06:00
parent 2d2485910f
commit 9d003b03d8
11 changed files with 194 additions and 36 deletions
+124 -15
View File
@@ -6,13 +6,21 @@ extends Node2D
@export var RENDER_RADIUS: int = 20
@export_range(0.0, 1.0) var producer_spawn_chance: float = 0.015 # 1.5% chance per tile
# preload scenes that we can place:
const EXTRACTOR_SCENE = preload("res://extractor.tscn")
const BELT_SCENE = preload("res://belt.tscn")
enum Mode { NONE, PLACE_EXTRACTOR, PLACE_BELT, DELETE }
var current_mode = Mode.NONE
var preview_item: Node2D = null # Holds the visual for the mouse
# These should likely be changed to be the same format as above
@export var producer_scene: PackedScene
@export var consumer_scene: PackedScene
var render_radius_x = RENDER_RADIUS
var render_radius_y = RENDER_RADIUS
# --- PHASE 1 DATA STRUCTURES ---
# This dictionary tracks what physical entity occupies a grid coordinate.
# Format: Vector2i(x, y) : { "type": "consumer" } or { "type": "producer", "value": 10 }
var grid_data: Dictionary = {}
@@ -25,11 +33,44 @@ func _ready() -> void:
initialize_world_center()
func _process(_delta: float) -> void:
#print(camera.position)
#print(get_global_mouse_position())
#print(get_grid_snapped_mouse_position())
if camera:
render_radius_x = RENDER_RADIUS / camera.zoom[0]
render_radius_y = RENDER_RADIUS / camera.zoom[1]
generate_and_render_around_camera()
# Update the preview item's position and snap to the grid
if preview_item and (current_mode != Mode.NONE and current_mode != Mode.DELETE):
var grid_pos = get_grid_snapped_mouse_position()
preview_item.global_position = tile_layer.map_to_local(grid_pos)
# var scaled_pos = (get_grid_snapped_mouse_position() * 32)
# scaled_pos[0] += 32
# scaled_pos[1] += 32
# preview_item.global_position = scaled_pos
func _input(event):
# Detect left mouse click
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
match current_mode:
Mode.PLACE_EXTRACTOR:
place_item(EXTRACTOR_SCENE)
Mode.PLACE_BELT:
place_item(BELT_SCENE)
Mode.DELETE:
delete_item(get_grid_snapped_mouse_position())
# Right-click cancels the current action
elif event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_RIGHT and event.pressed:
clear_preview()
current_mode = Mode.NONE
# Returns the grid position of the mouse
func get_grid_snapped_mouse_position() -> Vector2i:
return tile_layer.local_to_map(get_global_mouse_position())
# Define the absolute center data rule
func initialize_world_center() -> void:
@@ -73,11 +114,15 @@ func generate_and_render_around_camera() -> void:
# This is where Phase 2 will plug in to evaluate if a producer should spawn
process_grid_data_at(tile_coords)
# PHASE 2: Distance Math & Random Generation
func process_grid_data_at(coords: Vector2i) -> void:
# If this coordinate is already occupied (like by our 3x3 Consumer), skip it!
if grid_data.has(coords):
return
# This ensures that there is a 3x3 space to spawn item in. This is required for the producers
for x in range(-1, 2):
for y in range(-1, 2):
if grid_data.has(coords + Vector2i(x, y)):
return
# Roll the dice to see if a Producer should spawn here
if randf() < producer_spawn_chance:
@@ -90,6 +135,14 @@ func process_grid_data_at(coords: Vector2i) -> void:
var producer_value = 1 + floor(distance / 10.0)
# Register the producer in our global data registry
# disabled: for x in range(-1, 2):
# disabled: for y in range(-1, 2):
# disabled: grid_data[coords + Vector2i(x, y)] = {
# disabled: "type": "producer",
# disabled: "value": producer_value
# disabled: }
grid_data[coords] = {
"type": "producer",
"value": producer_value
@@ -99,24 +152,67 @@ func process_grid_data_at(coords: Vector2i) -> void:
print("Placing producer at " + str(coords.x) + ", " + str(coords.y))
# 1. Create a live instance of the saved scene file
var new_producer = producer_scene.instantiate()
var pixel_position = tile_layer.map_to_local(coords)
new_producer.global_position = pixel_position
new_producer.setup(int(producer_value))
# 2. Add it as a child of the world so it exists in the active game tree
add_child(new_producer)
# 3. Convert grid coordinates back to exact engine pixel coordinates
# map_to_local gives us the exact center point of that grid tile
var pixel_position = tile_layer.map_to_local(coords)
new_producer.global_position = pixel_position
# 4. Optional: If your Producer scene has a script on it,
# you can pass its distance value directly to it right here!
# new_producer.output_value = producer_value
## --- VISUAL PLACEMENT ---
## Tell your TileMapLayer to draw the Producer asset on top of the floor.
## Replace Vector2i(1, 0) with the actual atlas coordinates of your Producer image in your TileSet!
#tile_layer.set_cell(coords, 0, Vector2i(1, 0))
# Spawns the preview item following the cursor
func set_preview_mode(mode_type: Mode, scene_to_preview: PackedScene):
clear_preview()
current_mode = mode_type
if scene_to_preview:
preview_item = scene_to_preview.instantiate()
# Optional: Make the preview slightly transparent
preview_item.modulate.a = 0.5
add_child(preview_item)
func clear_preview():
if preview_item:
preview_item.queue_free()
preview_item = null
# Places an item onto the game board
func place_item(item: PackedScene):
var spawn_pos = get_grid_snapped_mouse_position()
print("attempting placement at %s, %s" % [spawn_pos[0], spawn_pos[1]])
# Check if there is something under us
var object_at_coords = get_object_at_coordinate(spawn_pos)
print(object_at_coords)
if object_at_coords != null:
if item == EXTRACTOR_SCENE && object_at_coords['type'] == 'producer':
print("You are placing an extractor and it is on top of a producer")
pass # Do not return if we are placing an extractor and we are on top of a producer
else:
print("Failed to place due to %s in the way" % object_at_coords['type'])
return
else: # If we are not over something
if item == EXTRACTOR_SCENE: # And we are placing an extractor
print("You must place an extractor on top of a producer")
return # Do not place
print("Placing object")
var new_item = item.instantiate()
new_item.global_position = tile_layer.map_to_local(spawn_pos)
new_item.add_to_group("Placed_objects")
add_child(new_item)
register_object_at_coordinate(
spawn_pos,
{
"type": new_item.name,
})
func delete_item(target_pos: Vector2i):
var targets = get_tree().get_nodes_in_group("Placed_objects")
for item in targets:
if item.global_position == target_pos:
item.queue_free()
break # Prevents deleting multiple items.
# Helper function: Check if a coordinate is occupied by a building
func get_object_at_coordinate(coords: Vector2i):
@@ -127,3 +223,16 @@ func get_object_at_coordinate(coords: Vector2i):
# Helper function: Force place an object into the grid data registry
func register_object_at_coordinate(coords: Vector2i, object_data: Dictionary) -> void:
grid_data[coords] = object_data
# --- UI Button Signals ---
func _on_extractor_button_pressed():
set_preview_mode(Mode.PLACE_EXTRACTOR, EXTRACTOR_SCENE)
##
##func _on_belt_button_pressed():
## set_preview_mode(Mode.PLACE_BELT, BELT_SCENE)
##
##func _on_delete_button_pressed():
## clear_preview()
## current_mode = Mode.DELETE
##