diff --git a/.gitea/workflows/demo.yaml b/.gitea/workflows/demo.yaml deleted file mode 100644 index c537cc6..0000000 --- a/.gitea/workflows/demo.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: Gitea Actions Demo -run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 -on: [push] - -jobs: - Explore-Gitea-Actions: - runs-on: ubuntu-latest - steps: - - run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event." - - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!" - - run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}." - - name: Check out repository code - uses: actions/checkout@v4 - - run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner." - - run: echo "🖥️ The workflow is now ready to test your code on the runner." - - name: List files in the repository - run: | - ls ${{ gitea.workspace }} - - run: echo "🍏 This job's status is ${{ job.status }}." diff --git a/export_presets.cfg b/export_presets.cfg index 2773aca..08b3b1a 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -78,7 +78,7 @@ script_export_mode=2 custom_template/debug="" custom_template/release="" debug/export_console_wrapper=1 -binary_format/embed_pck=true +binary_format/embed_pck=false texture_format/s3tc_bptc=true texture_format/etc2_astc=false shader_baker/enabled=false diff --git a/extractor.gd b/extractor.gd new file mode 100644 index 0000000..98a6e52 --- /dev/null +++ b/extractor.gd @@ -0,0 +1,11 @@ +extends Sprite2D + + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + print("Placed Extractor at: (%s, %s)" % [self.global_position[0], self.global_position[1]]) + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + pass diff --git a/extractor.gd.uid b/extractor.gd.uid new file mode 100644 index 0000000..4ef0d1e --- /dev/null +++ b/extractor.gd.uid @@ -0,0 +1 @@ +uid://dwe2kdx6e4rni diff --git a/extractor.tscn b/extractor.tscn new file mode 100644 index 0000000..d33f9b6 --- /dev/null +++ b/extractor.tscn @@ -0,0 +1,8 @@ +[gd_scene format=3 uid="uid://bd4n2dafvc462"] + +[ext_resource type="Texture2D" uid="uid://lq8htcre3uve" path="res://assets/images/extractor.png" id="1_e3dte"] +[ext_resource type="Script" uid="uid://dwe2kdx6e4rni" path="res://extractor.gd" id="2_x82y0"] + +[node name="Sprite2D" type="Sprite2D" unique_id=1172832761] +texture = ExtResource("1_e3dte") +script = ExtResource("2_x82y0") diff --git a/game_scene.tscn b/game_scene.tscn index 213f8c4..03e2003 100644 --- a/game_scene.tscn +++ b/game_scene.tscn @@ -5,6 +5,7 @@ [ext_resource type="PackedScene" uid="uid://djs8jhub580bq" path="res://producer.tscn" id="2_mixcd"] [ext_resource type="PackedScene" uid="uid://bvytqfap2t478" path="res://consumer.tscn" id="3_mj2jn"] [ext_resource type="Script" uid="uid://iy6u4txips6p" path="res://main_game_camera.gd" id="3_v1wow"] +[ext_resource type="Texture2D" uid="uid://lq8htcre3uve" path="res://assets/images/extractor.png" id="6_kdryc"] [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_v1wow"] texture = ExtResource("1_mlf6e") @@ -25,3 +26,22 @@ tile_set = SubResource("TileSet_ylkns") [node name="main_game_camera" type="Camera2D" parent="." unique_id=1094262036] script = ExtResource("3_v1wow") + +[node name="CanvasLayer" type="CanvasLayer" parent="." unique_id=1153396713] + +[node name="Control" type="Control" parent="CanvasLayer" unique_id=1038745342] +layout_mode = 3 +anchors_preset = 0 +offset_right = 40.0 +offset_bottom = 40.0 + +[node name="VBoxContainer" type="VBoxContainer" parent="CanvasLayer/Control" unique_id=856029850] +layout_mode = 0 +offset_right = 40.0 +offset_bottom = 40.0 + +[node name="extractor_button" type="TextureButton" parent="CanvasLayer/Control/VBoxContainer" unique_id=438731803] +layout_mode = 2 +texture_normal = ExtResource("6_kdryc") + +[connection signal="pressed" from="CanvasLayer/Control/VBoxContainer/extractor_button" to="." method="_on_extractor_button_pressed"] diff --git a/main_game.gd b/main_game.gd index 9d59d91..46b5d14 100644 --- a/main_game.gd +++ b/main_game.gd @@ -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 +## diff --git a/main_game_background_tiles.gd b/main_game_background_tiles.gd index db73adb..c61c97f 100644 --- a/main_game_background_tiles.gd +++ b/main_game_background_tiles.gd @@ -3,7 +3,6 @@ extends TileMapLayer @onready var camera: Camera2D = $"../main_game_camera" @export var render_radius: int = 20 # How many tiles out from the center to draw -var tile_size: Vector2i = Vector2i(32, 32) # Change this to your actual asset square size (e.g., 32x32, 64x64) # Keep track of which grid coordinates we've already loaded var loaded_tiles: Dictionary = {} diff --git a/main_game_camera.gd b/main_game_camera.gd index 7bd7d16..ecf932c 100644 --- a/main_game_camera.gd +++ b/main_game_camera.gd @@ -32,6 +32,8 @@ func handle_keyboard_movement(delta: float) -> void: velocity.y -= 1 if Input.is_key_pressed(KEY_DOWN): velocity.y += 1 + if Input.is_key_pressed(KEY_SPACE): + global_position = Vector2i(0, 0) # Move the camera based on direction, speed, and time passed global_position += velocity.normalized() * KEYBOARD_SPEED * delta diff --git a/producer.gd b/producer.gd index 7dca965..2432651 100644 --- a/producer.gd +++ b/producer.gd @@ -3,8 +3,12 @@ extends Sprite2D var output_value: int func setup(output_value): + $tooltip.hide() print("Producer spawned physically with a value of: ", output_value) $text_value.text = str(output_value) + $tooltip.text = "Placed at: (%s, %s)" % [self.global_position[0], self.global_position[1]] + print($tooltip.size ) + $tooltip.size = Vector2i(100, 100) # Called when the node enters the scene tree for the first time. func _ready() -> void: @@ -14,3 +18,11 @@ func _ready() -> void: # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta: float) -> void: pass + + +func _on_control_mouse_entered() -> void: + $tooltip.show() + + +func _on_control_mouse_exited() -> void: + $tooltip.hide() diff --git a/producer.tscn b/producer.tscn index 24881a6..7d31f07 100644 --- a/producer.tscn +++ b/producer.tscn @@ -17,3 +17,18 @@ text = "-99" autowrap_mode = 0 horizontal_alignment = 1 vertical_alignment = 1 + +[node name="tooltip" type="RichTextLabel" parent="." unique_id=1644072015] +offset_left = -16.0 +offset_top = -16.0 +offset_right = 84.0 +offset_bottom = 84.0 +fit_content = true +autowrap_mode = 0 + +[node name="Control" type="Control" parent="." unique_id=966102127] +layout_mode = 3 +anchors_preset = 0 + +[connection signal="mouse_entered" from="Control" to="." method="_on_control_mouse_entered"] +[connection signal="mouse_exited" from="Control" to="." method="_on_control_mouse_exited"]