Compare commits

..

No commits in common. "a23db504caea8c53d24e8c6d5f12e6ff9f77c821" and "412736b9d5a70754c2af3bc9cb8c2b3c58a8785b" have entirely different histories.

27 changed files with 150 additions and 673 deletions

File diff suppressed because one or more lines are too long

View File

@ -1,15 +1,9 @@
[gd_scene load_steps=10 format=3 uid="uid://b1fnsl3k1mo5c"]
[gd_scene load_steps=7 format=3 uid="uid://b1fnsl3k1mo5c"]
[ext_resource type="Script" uid="uid://dvgo3kpjr2mmj" path="res://scripts/building_components/building.gd" id="1_k07no"]
[ext_resource type="Script" uid="uid://bcp3fwf3nds3k" path="res://scripts/nav_obstacle.gd" id="2_0gk2u"]
[ext_resource type="Script" uid="uid://kcdpck5ufgcc" path="res://scripts/item.gd" id="2_fahfx"]
[ext_resource type="Resource" uid="uid://dxlb2ixt3fx7l" path="res://items/ore.tres" id="3_w18nb"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_0gk2u"]
albedo_color = Color(0.245167, 1, 0, 1)
[sub_resource type="BoxMesh" id="BoxMesh_cee1v"]
material = SubResource("StandardMaterial3D_0gk2u")
size = Vector3(2, 2, 2)
[sub_resource type="BoxShape3D" id="BoxShape3D_k07no"]
@ -24,13 +18,10 @@ agent_radius = 0.2
size = Vector2(2, 2)
orientation = 1
[node name="Building" type="StaticBody3D" groups=["Buildings"]]
[node name="Building" type="StaticBody3D"]
collision_layer = 2
collision_mask = 15
script = ExtResource("1_k07no")
build_materials_needed = Dictionary[ExtResource("2_fahfx"), int]({
ExtResource("3_w18nb"): 5
})
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)

View File

@ -1,18 +1,14 @@
[gd_scene load_steps=7 format=3 uid="uid://chd531mdaek3"]
[gd_scene load_steps=6 format=3 uid="uid://chd531mdaek3"]
[ext_resource type="PackedScene" uid="uid://b1fnsl3k1mo5c" path="res://objects/buildings/building.tscn" id="1_8r86l"]
[ext_resource type="Script" uid="uid://6dy54s70qf0x" path="res://scripts/buildings/miner.gd" id="2_k13eg"]
[ext_resource type="PackedScene" uid="uid://dx13fyjv0d8st" path="res://assets/blends/Miner.blend" id="2_la0h1"]
[ext_resource type="Script" uid="uid://kcdpck5ufgcc" path="res://scripts/item.gd" id="3_8y6s2"]
[ext_resource type="Resource" uid="uid://dxlb2ixt3fx7l" path="res://items/ore.tres" id="3_k13eg"]
[ext_resource type="Script" uid="uid://c4fquatkjmsgu" path="res://scripts/building_components/producer.gd" id="5_65oni"]
[node name="Miner" instance=ExtResource("1_8r86l")]
script = ExtResource("2_k13eg")
mine_period = 1.0
hologram_build_min = 0.0
hologram_build_max = 2.0
build_materials_needed = Dictionary[ExtResource("3_8y6s2"), int]({})
can_stack = false
[node name="MeshInstance3D" parent="." index="0"]

View File

@ -2,7 +2,7 @@
[ext_resource type="PackedScene" uid="uid://b1fnsl3k1mo5c" path="res://objects/buildings/building.tscn" id="1_hxugg"]
[ext_resource type="Script" uid="uid://c3bqfgoof2c83" path="res://scripts/buildings/processor.gd" id="2_evfwj"]
[ext_resource type="Script" uid="uid://kcdpck5ufgcc" path="res://scripts/item.gd" id="3_dx8de"]
[ext_resource type="Script" uid="uid://kcdpck5ufgcc" path="res://scripts/item.gd" id="3_3h7kv"]
[ext_resource type="Resource" uid="uid://ed64yksg1y6m" path="res://items/bullets.tres" id="4_3h7kv"]
[ext_resource type="Script" uid="uid://bshiyw2k3op02" path="res://scripts/building_components/consumer.gd" id="4_dx8de"]
[ext_resource type="Script" uid="uid://c4fquatkjmsgu" path="res://scripts/building_components/producer.gd" id="5_p3dou"]
@ -17,7 +17,7 @@ size = Vector3(2, 2, 2)
[node name="Processor" instance=ExtResource("1_hxugg")]
script = ExtResource("2_evfwj")
ingredients = Dictionary[ExtResource("3_dx8de"), int]({
ingredients = Dictionary[ExtResource("3_3h7kv"), int]({
ExtResource("7_dx8de"): 2
})
process_time = 1.0
@ -27,7 +27,7 @@ mesh = SubResource("BoxMesh_3h7kv")
[node name="Consumer" type="Node" parent="." index="2"]
script = ExtResource("4_dx8de")
accepted_items = Array[ExtResource("3_dx8de")]([ExtResource("7_dx8de")])
accepted_items = Array[ExtResource("3_3h7kv")]([ExtResource("7_dx8de")])
metadata/_custom_type_script = "uid://bshiyw2k3op02"
[node name="Producer" type="Node" parent="." index="3"]

View File

@ -1,29 +0,0 @@
[gd_scene load_steps=7 format=3 uid="uid://buoyeprlof38x"]
[ext_resource type="PackedScene" uid="uid://b1fnsl3k1mo5c" path="res://objects/buildings/building.tscn" id="1_7qwib"]
[ext_resource type="Script" uid="uid://bshiyw2k3op02" path="res://scripts/building_components/consumer.gd" id="2_36s1u"]
[ext_resource type="Script" uid="uid://ba5aqcwabpfp0" path="res://scripts/buildings/storage.gd" id="2_evbsr"]
[ext_resource type="Script" uid="uid://c4fquatkjmsgu" path="res://scripts/building_components/producer.gd" id="3_evbsr"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_nr174"]
albedo_color = Color(0, 1, 0.979857, 1)
[sub_resource type="BoxMesh" id="BoxMesh_36s1u"]
material = SubResource("StandardMaterial3D_nr174")
size = Vector3(2, 2, 2)
[node name="Building" instance=ExtResource("1_7qwib")]
script = ExtResource("2_evbsr")
[node name="MeshInstance3D" parent="." index="0"]
mesh = SubResource("BoxMesh_36s1u")
[node name="Consumer" type="Node" parent="." index="6"]
script = ExtResource("2_36s1u")
storage_size = 250
max_inputs = 3
metadata/_custom_type_script = "uid://bshiyw2k3op02"
[node name="Producer" type="Node" parent="." index="7"]
script = ExtResource("3_evbsr")
metadata/_custom_type_script = "uid://c4fquatkjmsgu"

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=9 format=3 uid="uid://cw3vtaevqx20y"]
[gd_scene load_steps=8 format=3 uid="uid://cw3vtaevqx20y"]
[ext_resource type="PackedScene" uid="uid://b1fnsl3k1mo5c" path="res://objects/buildings/building.tscn" id="1_cgb0l"]
[ext_resource type="Script" uid="uid://bl78fqp1abxd6" path="res://scripts/buildings/turret.gd" id="2_brx0q"]
@ -8,10 +8,6 @@
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_cgb0l"]
albedo_color = Color(0, 0.00397563, 1, 1)
[sub_resource type="BoxMesh" id="BoxMesh_kpsgq"]
material = SubResource("StandardMaterial3D_cgb0l")
size = Vector3(2, 2, 2)
[sub_resource type="CylinderMesh" id="CylinderMesh_kpsgq"]
material = SubResource("StandardMaterial3D_cgb0l")
top_radius = 1.0
@ -34,13 +30,13 @@ fire_cooldown_time = 0.2
reload_time = 1.0
bullet_scene = ExtResource("3_kpsgq")
fire_position = Vector3(0, 2.1, 0)
shot_velocity = 50.0
shot_velocity = 20.0
lead_shots = true
compensate_for_gravity = true
use_artillery_firing_solution = false
[node name="MeshInstance3D" parent="." index="0"]
mesh = SubResource("BoxMesh_kpsgq")
material_override = SubResource("StandardMaterial3D_cgb0l")
[node name="MeshInstance3D" type="MeshInstance3D" parent="MeshInstance3D" index="0"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.25, 0)

View File

@ -105,13 +105,12 @@ size = Vector2(0.1, 0.1)
[node name="Bullet" type="RigidBody3D"]
collision_layer = 16
collision_mask = 21
collision_mask = 5
continuous_cd = true
contact_monitor = true
max_contacts_reported = 1
angular_velocity = Vector3(0, 0, 6.28319)
script = ExtResource("1_rsjgb")
damage_per_speed = 2.0
damage_per_speed = 100.0
min_damage = 1.0
lifetime = 5.0
@ -121,7 +120,7 @@ shape = SubResource("CapsuleShape3D_3ndsa")
[node name="GPUTrail3D" type="GPUParticles3D" parent="."]
physics_interpolation_mode = 2
transform = Transform3D(0.0233971, -0.0972244, 0, 0.0972244, 0.0233971, 0, 0, 0, 0.1, 0, 0.0926043, -0.000724986)
transform = Transform3D(0.0233971, -0.0972244, 0, 0.0972244, 0.0233971, 0, 0, 0, 0.1, 0, 0, 0)
amount = 19
lifetime = 19.0
explosiveness = 1.0

View File

@ -1,19 +1,10 @@
@tool
extends Unit
class_name Citizen
@onready var body: Sprite3D = $Body
@onready var hands: Sprite3D = $Body/Hands
var task: Task = null
var working: bool = false
enum WorkStatus { NONE, CONSTRUCTING_BUILDING }
var work_status: WorkStatus
var work_building: Building = null
func _ready() -> void:
held_item_meshinstance = $"Body/Hands/Held Item"
func _process(delta: float) -> void:
super(delta)
var camera: Camera3D
@ -28,48 +19,6 @@ func _process(delta: float) -> void:
var facing_right: bool = camera_local_facing.x > 0
body.frame = 1 if facing_away else 0
#hands.frame = 1 if facing_away else 0
hands.frame = 1 if facing_away else 0
body.flip_h = facing_right
hands.flip_h = facing_right
if !working and task != null:
working = true
var ok: bool = await task.execute(self)
if !ok:
CitizenManager._instance.add_task(task)
task = null
working = false
if work_status == WorkStatus.CONSTRUCTING_BUILDING:
work_building.build_progress += delta
if work_building.build_state == Building.BuildState.READY:
send_task_update(TaskStatus.DONE)
elif work_building.build_state != Building.BuildState.BUILDING:
send_task_update(TaskStatus.IMPOSSIBLE)
func assign_task(t: Task) -> void:
task = t
func is_idle() -> bool:
return task == null
func put_item_in_building_materials(building: Building) -> bool:
building._add_build_material(held_item)
held_item = null
return true
func put_item_in_building_storage(building: Building) -> bool:
if building.consumer == null:
return false
if !building.consumer.offer_item(held_item):
return false
held_item = null
return true
func build_building(building: Building) -> bool:
work_building = building
work_status = WorkStatus.CONSTRUCTING_BUILDING
var ok: bool = await wait_for_task_update() == TaskStatus.DONE
work_building = null
work_status = WorkStatus.NONE
return ok

View File

@ -4,7 +4,7 @@
[ext_resource type="Script" uid="uid://b7xficxq807qd" path="res://objects/units/citizen.gd" id="2_dv62s"]
[ext_resource type="Texture2D" uid="uid://brjswv5ryy8om" path="res://assets/images/lilguy.png" id="3_pedvu"]
[ext_resource type="Texture2D" uid="uid://cpov32m0nxjvh" path="res://assets/images/lilguy_arms.png" id="4_i1unn"]
[ext_resource type="ArrayMesh" uid="uid://c6yj8uwsgqxv0" path="res://assets/models/Ingot.obj" id="5_dv62s"]
[ext_resource type="ArrayMesh" uid="uid://gf0q5hs4wjva" path="res://assets/models/Ore.obj" id="5_dds8f"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_vpcy6"]
albedo_texture = ExtResource("3_pedvu")
@ -13,14 +13,13 @@ billboard_mode = 2
[sub_resource type="QuadMesh" id="QuadMesh_5xmhx"]
material = SubResource("StandardMaterial3D_vpcy6")
[node name="Citizen" groups=["Citizens"] instance=ExtResource("1_6046h")]
[node name="Citizen" instance=ExtResource("1_6046h")]
collision_layer = 8
collision_mask = 5
script = ExtResource("2_dv62s")
stuck_time = 5.0
[node name="NavigationAgent3D" parent="." index="0"]
target_position = Vector3(18.6013, 1, 14.148)
target_position = Vector3(21.7818, 1, 12.7739)
velocity = Vector3(0.811107, 0, -0.811107)
[node name="MeshInstance3D" parent="." index="2"]
@ -40,7 +39,7 @@ texture = ExtResource("3_pedvu")
hframes = 2
[node name="Hands" type="Sprite3D" parent="Body" index="0"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.0522564)
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.01)
billboard = 2
shaded = true
alpha_cut = 1
@ -48,7 +47,6 @@ texture_filter = 0
texture = ExtResource("4_i1unn")
[node name="Held Item" type="MeshInstance3D" parent="Body/Hands" index="0"]
transform = Transform3D(0.17, 0, 0, 0, 0.17, 0, 0, 0, 0.17, 5.96046e-08, -0.0189633, -0.0170195)
visible = false
mesh = ExtResource("5_dv62s")
transform = Transform3D(0.17, 0, 0, 0, 0.17, 0, 0, 0, 0.17, 5.96046e-08, -0.0580646, -0.0773078)
mesh = ExtResource("5_dds8f")
skeleton = NodePath("../../..")

View File

@ -31,7 +31,7 @@ max_speed = 5.0
[node name="NavigationAgent3D" type="NavigationAgent3D" parent="."]
path_desired_distance = 0.5
target_desired_distance = 2.0
target_desired_distance = 0.5
path_max_distance = 1.01
avoidance_enabled = true
radius = 1.0

View File

@ -28,7 +28,6 @@ run/main_scene="uid://bwftban1ppo17"
config/features=PackedStringArray("4.4")
config/icon="uid://u1hpdb62rxlc"
addons/icon_finder/preview_size=25
config/git_describe="78bfcde"
[autoload]
@ -48,7 +47,6 @@ gdscript/warnings/unsafe_property_access=1
gdscript/warnings/unsafe_method_access=1
gdscript/warnings/unsafe_cast=1
gdscript/warnings/unsafe_call_argument=2
gdscript/warnings/return_value_discarded=1
gdscript/warnings/static_called_on_instance=2
gdscript/warnings/missing_tool=2
gdscript/warnings/assert_always_false=2
@ -74,8 +72,6 @@ enabled=PackedStringArray("res://addons/GPUTrail/plugin.cfg", "res://addons/Path
[global_group]
Enemies=""
Citizens=""
Buildings=""
[input]
@ -125,13 +121,6 @@ building_place={
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
]
}
building_cancel={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":2,"canceled":false,"pressed":false,"double_click":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":false,"script":null)
]
}
[layer_names]

View File

@ -1,57 +0,0 @@
extends Node
class_name CitizenManager
@export var task_assignment_rate: float = 100
var task_assignment_budget: float = 0
var task_queue: Array[Task] = []
static var _instance: CitizenManager = null
#signal task_queue_updated(task_queue: Array[Task])
func _init() -> void:
if _instance == null:
_instance = self
else:
assert(false, "A second CitizenManager was created you fucking moron")
func _process(delta: float) -> void:
task_assignment_budget += task_assignment_rate * delta
if task_assignment_budget >= task_assignment_rate:
task_assignment_budget = task_assignment_rate
var idle_workers: Array[Citizen] = []
for worker in get_children():
if worker is Citizen:
if worker.is_idle():
idle_workers.append(worker)
#idle_workers.shuffle()
while !idle_workers.is_empty() and !task_queue.is_empty() and task_assignment_budget >= 1:
var task: Task = task_queue.pop_front()
task_assignment_budget -= 1
if task.is_ready_to_start():
# TODO: this currently assigns to the first worker found
var worker: Citizen = idle_workers.pop_front()
worker.assign_task(task)
else:
add_task(task)
func remove_task(task: Task):
var idx: int = task_queue.find(task)
if idx >= 0:
task_queue.remove_at(idx)
func add_task(task: Task):
print("Task added to queue: %s" % task.get_task_name())
var idx: int = task_queue.bsearch_custom(task, sort_tasks, false)
task_queue.insert(idx, task)
func sort_tasks(a: Task,b: Task) -> bool:
return a.priority > b.priority
const TASK_PRIORITY_ANYTIME = 0
const TASK_PRIORITY_BY_WAVE_START = 10
const TASK_PRIORITY_ASAP = 20

View File

@ -1 +0,0 @@
uid://ckf7i6ig4twnq

View File

@ -1,14 +1,6 @@
extends Node3D
class_name Building
@export var hologram_material: Material = preload("res://shaders/hologram_material.tres")
@export var hologram_build_min: float = -1
@export var hologram_build_max: float = 1
@export_group("Construction", "build")
@export var build_time: float = 5.0 ## Worker-time taken for 1 citizen to finish the building, in citizen-seconds.
@export var build_materials_needed: Dictionary[Item, int] = {}
@export_group("Defence")
@export var max_hp: int = 100 ## Amount of damage this building can sustain before being destroyed.
@ -39,35 +31,13 @@ const PLACEMENT_PART_ADDED: int = 0b0100
const PLACEMENT_COMPLETED: int = 0b1000
var hp: int = max_hp
var build_progress: float = 0.0:
set(val):
build_progress = val
if build_progress >= build_time:
build_state = BuildState.READY
var build_percent: float = build_progress / build_time
set_visual_build_progress(build_percent)
var stacked_buildings: Array[Building] = []
var build_state: BuildState = BuildState.READY:
set(state):
if state != build_state:
build_state = state
functional_changed.emit(is_functional())
if build_state == BuildState.BUILDING:
for item in build_materials_needed.keys():
for i in range(build_materials_needed.get(item)):
var task: Task.FetchItemTask = Task.FetchItemTask.new()
task.building = self
task.item = item
CitizenManager._instance.add_task(task)
check_buildable()
set_visual_build_progress(0.0)
elif build_state == BuildState.READY:
set_visual_build_progress(1.0)
var build_materials_used: Dictionary[Item, int] = {}
build_state = state
functional_changed.emit(is_functional())
func _ready() -> void:
if nav_obstacle != null:
@ -109,7 +79,7 @@ func _start_placement() -> void:
build_state = BuildState.UNPLACED
func _end_placement() -> void:
build_state = BuildState.BUILDING
build_state = BuildState.READY
func _placement_select_building(building: Building, confirmed: bool) -> int:
while !building.stacked_buildings.is_empty():
@ -140,33 +110,3 @@ func _placement_select_position(pos: Vector3, confirmed: bool) -> int:
ret |= PLACEMENT_COMPLETED
return ret
func check_buildable() -> void:
if can_build():
var task: Task.BuildTask = Task.BuildTask.new()
task.building = self
CitizenManager._instance.add_task(task)
func _add_build_material(item: Item) -> void:
build_materials_used.set(item, build_materials_used.get(item, 0) + 1)
check_buildable()
func can_build() -> bool:
for item in build_materials_needed.keys():
if build_materials_used.get(item,0) < build_materials_needed.get(item,0):
return false
return true
func set_visual_build_progress(ratio: float) -> void:
var geometries: Array[Node] = find_children("", "GeometryInstance3D", true)
for node in geometries:
var geometry: GeometryInstance3D = node as GeometryInstance3D
if geometry != null:
if ratio >= 1.0:
geometry.material_override = null
else:
geometry.material_override = hologram_material
var built_amount: float = remap(ratio, 0, 1, hologram_build_min, hologram_build_max)
geometry.set_instance_shader_parameter("built_amount", built_amount)
#var opacity: float = 0.5 + (ratio * 0.5)
#geometry.transparency = 1.0 - opacity

View File

@ -10,18 +10,6 @@ signal item_added(item: Item)
var storage_total: int = 0
var storage: Dictionary[Item, int] = {}
class ItemRequest:
var item: Item
var timeout: float
var requests: Array[ItemRequest] = []
signal requested_item_received(request: ItemRequest)
func _process(delta: float) -> void:
for request in requests:
request.timeout -= delta
if request.timeout <= 0:
cancel_request(request)
func can_accept_item(item: Item) -> bool:
return ((storage_total < storage_size) or void_excess_items) \
and (accepted_items.has(item) or accepted_items.is_empty()) \
@ -35,19 +23,10 @@ func offer_item(item: Item) -> bool:
var old_count: int = storage.get(item, 0)
storage.set(item, old_count + 1)
storage_total += 1
if !check_requested_items(item):
item_added.emit(item)
#print("Added %s to %s storage; previously had %d, new total %d" % [item.name, get_parent().name, old_count, storage_total])
item_added.emit(item)
return true
func check_requested_items(new_item: Item):
for request in requests:
if new_item == request.item:
requested_item_received.emit(request)
break
func cancel_request(request: ItemRequest):
requested_item_received.emit(request)
func check_storage_for_item(item: Item) -> bool:
return check_storage_for_items({item:1})
@ -68,19 +47,6 @@ func take_any_item_from_storage() -> Item:
func take_item_from_storage(item: Item) -> bool:
return take_items_from_storage({item: 1})
## Waits for an item to be available at this storage, or a timeout to be reached.
func wait_for_item(item: Item, timeout: float) -> bool:
if check_storage_for_item(item):
return true
var request: ItemRequest = ItemRequest.new()
request.item = item
request.timeout = timeout
requests.append(request)
var finished_request: ItemRequest = null
while finished_request != request:
finished_request = await requested_item_received
return check_storage_for_item(item)
func take_items_from_storage(items: Dictionary[Item, int]) -> bool:
if !check_storage_for_items(items):
return false

View File

@ -10,18 +10,11 @@ var last_consumer_idx: int = 0
#var output_timer: float = 0.0
#var output_item: Item
class ItemRequest:
var item: Item
var timeout: float
var requests: Array[ItemRequest] = []
signal requested_item_received(request: ItemRequest)
func _process(delta: float) -> void:
for request in requests:
request.timeout -= delta
if request.timeout <= 0:
cancel_request(request)
#func _process(delta: float) -> void:
#output_timer += delta
#if output_timer >= output_period:
#output_timer -= output_period
#output()
func can_produce() -> bool:
return can_send_item(produced_item)
@ -31,9 +24,6 @@ func produce() -> bool:
func can_send_item(item: Item) -> bool:
if !enabled:
return false
for request in requests:
if request.item == item:
return true
for consumer in consumers:
if consumer.can_accept_item(item):
return true
@ -42,8 +32,6 @@ func can_send_item(item: Item) -> bool:
func send_item(item: Item) -> bool:
if !enabled:
return false
if check_requested_items(item):
return true
if consumers.is_empty():
return false
var start_idx: int = last_consumer_idx
@ -62,24 +50,4 @@ func send_item(item: Item) -> bool:
return true
return false
func check_requested_items(new_item: Item) -> bool:
for request in requests:
if new_item == request.item:
requested_item_received.emit(request)
return true
return false
func cancel_request(request: ItemRequest):
requested_item_received.emit(request)
## Waits for an item to be available at this storage, or a timeout to be reached.
func wait_for_item(item: Item, timeout: float) -> bool:
var request: ItemRequest = ItemRequest.new()
request.item = item
request.timeout = timeout
requests.append(request)
var finished_request: ItemRequest = null
while finished_request != request:
finished_request = await requested_item_received
requests.erase(request)
return finished_request.timeout > 0

View File

@ -14,13 +14,9 @@ func start_placement(scene: PackedScene) -> void:
func _input(event: InputEvent) -> void:
if placing_building == null:
return
if event is InputEventMouseButton:
if event.is_action("building_place"):
placement_mouse_input((event as InputEventMouseButton).global_position, true)
get_viewport().set_input_as_handled()
elif event.is_action("building_cancel"):
placement_cancel()
get_viewport().set_input_as_handled()
if event is InputEventMouseButton and event.is_action("building_place"):
placement_mouse_input((event as InputEventMouseButton).global_position, true)
get_viewport().set_input_as_handled()
elif event is InputEventMouseMotion:
placement_mouse_input((event as InputEventMouseMotion).global_position, false)
get_viewport().set_input_as_handled()
@ -45,7 +41,3 @@ func placement_mouse_input(screen_position: Vector2, confirmed: bool) -> void:
if placment_feedback & Building.PLACEMENT_COMPLETED:
placing_building._end_placement()
placing_building = null
func placement_cancel() -> void:
placing_building.queue_free()
placing_building = null

View File

@ -30,12 +30,6 @@ var output_building: Building = null:
var waypoints: Array[Vector3] = []
var editing_waypoint: int = 0
func _exit_tree() -> void:
if input_building != null:
input_building.producer.consumers.erase(consumer)
if output_building != null:
producer.consumers.erase(output_building.consumer)
func _placement_select_building(building: Building, confirmed: bool) -> int:
var ret: int = 0
if input_building == null:
@ -101,7 +95,7 @@ func _ready() -> void:
path.curve = path.curve.duplicate()
func _process(delta: float) -> void:
belt_moving = is_functional() and check_items_at_end()
belt_moving = check_items_at_end()
consumer.enabled = belt_moving and (closest_item >= spacing)
var movement: float = (delta * speed)

View File

@ -1,10 +0,0 @@
extends Building
var held_item: Item = null
func _process(delta: float) -> void:
if !producer.consumers.is_empty():
held_item = consumer.take_any_item_from_storage()
if held_item != null and producer.send_item(held_item):
held_item = null

View File

@ -1 +0,0 @@
uid://ba5aqcwabpfp0

View File

@ -87,14 +87,14 @@ func fire_at_target() -> void:
if lead_shots:
aim_target += current_target.linear_velocity * shot_time
target_range = bullet_pos.distance_to(aim_target)
#DebugDraw3D.draw_sphere(aim_target, 0.25, Color.RED, shot_time)
DebugDraw3D.draw_sphere(aim_target, 0.25, Color.RED, shot_time)
var fire_direction: Vector3
if compensate_for_gravity:
var elevation: float = find_fire_angle(target_range, (aim_target.y - bullet_pos.y), use_artillery_firing_solution)
var azimuth: float = Vector3.FORWARD.signed_angle_to((aim_target-bullet_pos).slide(Vector3.UP), Vector3.UP)
var elevation: float = find_fire_angle(target_range, aim_target.y - bullet_pos.y, use_artillery_firing_solution)
var azimuth: float = Vector3.FORWARD.signed_angle_to(aim_target-global_position, Vector3.UP)
print("Shot params: θ=%d φ=%d" % [rad_to_deg(elevation), rad_to_deg(azimuth)])
if elevation < -PI or elevation > PI or is_nan(elevation):
if elevation < -PI or elevation > PI:
print("wtf?? θ=%d" % rad_to_deg(elevation))
return
fire_direction = Vector3.FORWARD
@ -103,12 +103,12 @@ func fire_at_target() -> void:
else:
fire_direction = (aim_target - bullet_pos).normalized()
#DebugDraw3D.draw_arrow_ray(bullet_pos, fire_direction, target_range, Color.RED, 0.5, true, shot_time)
DebugDraw3D.draw_arrow_ray(bullet_pos, fire_direction, target_range, Color.RED, 0.5, true, shot_time)
bullet.look_at(bullet_pos+fire_direction)
bullet.linear_velocity = (-bullet.global_basis.z * shot_velocity)
bullet.linear_velocity = (-bullet.global_basis.z) * shot_velocity
#bullet.apply_impulse((aim_target - bullet.global_position).normalized()*shot_impulse)
bullet.angular_velocity = (bullet.global_basis * Vector3(0,0,deg_to_rad(1080)))
bullet.angular_velocity = (bullet.global_basis * Vector3(0,0,-10))
current_target = null
ammo -= 1
if ammo <= 0:

View File

@ -2,6 +2,3 @@ extends Unit
class_name Enemy
var sighted: bool = true
func _ready() -> void:
go_to_destination(Vector3(17,1,15))

View File

@ -2,7 +2,6 @@ extends Node3D
@export var spawn_scene: PackedScene = null
@export var spawn_time: float = 5.0
@export var enabled: bool = true
var spawn_timer: float = 0.0

View File

@ -1,89 +0,0 @@
extends RefCounted
class_name Task
#var name: String
#var source: TaskManager
var solicitation_time: float = 1.0
var priority: int = TASK_PRIORITY_ANYTIME
var min_worker_count: int = 1
var max_worker_count: int = 1
var potential_workers: Dictionary[Citizen, float] = {}
var workers: Array[Citizen] = []
const FLOAT64_MAX: float = 2.0**1023 * (2 - 2.0**-52)
const TASK_PRIORITY_ANYTIME = 0
const TASK_PRIORITY_BY_WAVE_START = 10
const TASK_PRIORITY_ASAP = 20
func get_task_name() -> String:
return ""
func is_ready_to_start() -> bool:
return true
func get_location() -> Vector3:
return Vector3()
func run() -> void:
for worker in workers:
worker.assign_task(self)
func execute(worker: Citizen) -> bool:
return false
func interrupt(worker: Citizen) -> void:
workers.erase(worker)
if workers.size() < min_worker_count:
cancel()
func cancel() -> void:
pass
static func sort_tasks(a: Task, b: Task) -> bool:
return a.priority > b.priority
class BuildTask extends Task:
var building: Building
func _init() -> void:
priority = 1
func get_task_name() -> String:
return "Build " + building.name
func is_ready_to_start() -> bool:
return super() and building.can_build()
func get_location() -> Vector3:
return building.global_position
func execute(worker: Citizen) -> bool:
if !await worker.go_to_destination(building.position): return false
if !await worker.build_building(building): return false
return true
class FetchItemTask extends Task:
var building: Building
var item: Item
func get_task_name() -> String:
return "Transfer " + item.name + " to " + building.name
func execute(worker: Citizen) -> bool:
# find the item from nearby buildings
# TODO: also look for items on the floor?
var storage_building: Building = null
var closest: float = FLOAT64_MAX
for building2 in worker.get_tree().get_nodes_in_group("Buildings"):
if building2 is not Building:
continue
var item_found: bool = false
#if building2.consumer != null:
#item_found |= building2.consumer.check_storage_for_item(item)
if building2.producer != null:
item_found = building2.producer.produced_item == item
if item_found:
var distance_sqr: float = building2.global_position.distance_squared_to(worker.position)
if distance_sqr < closest:
storage_building = building2
closest = distance_sqr
if storage_building == null: return false
# go to the storage
if !await worker.go_to_destination(storage_building.global_position): return false
# pick up the item
if !await worker.take_item_from_building(item, storage_building): return false
# carry the item to the construction site
if !await worker.go_to_destination(building.global_position): return false
# store the item in the construction site
if !await worker.put_item_in_building_materials(building): return false
return true

View File

@ -1 +0,0 @@
uid://cc3hwuckhboi1

View File

@ -19,35 +19,12 @@ var avoidance_velocity: Vector3 = Vector3()
var avoidance_timeout: float = 0.0
var last_distance_to_target: float = 0.0
var stuck_timer: float = 0.0
var moving: bool = false
var move_target: Vector3 = Vector3(16, 1, 13):
set(target):
move_target = target
nav_agent_3d.target_position = move_target
var move_target: Vector3 = Vector3(16, 1, 13)
var move_radius: float = 5.0
var held_item: Item = null:
set(val):
held_item = val
if held_item_meshinstance != null:
if held_item != null:
held_item_meshinstance.mesh = held_item.model
held_item_meshinstance.visible = (held_item != null)
@onready var shapecast_3d: ShapeCast3D = $ShapeCast3D
@onready var nav_agent_3d: NavigationAgent3D = $NavigationAgent3D
@onready var label_3d: Label3D = $Label3D
@onready var held_item_meshinstance: MeshInstance3D = null
var action_timeout: float = 0.0
enum TaskStatus {
INTERRUPTED,
TIMED_OUT,
IMPOSSIBLE,
DONE,
}
signal task_updated(task_status: TaskStatus)
func _ready() -> void:
nav_agent_3d.connect("velocity_computed", avoidance_velocity_computed)
@ -61,45 +38,37 @@ func avoidance_velocity_computed(velocity: Vector3) -> void:
func _process(delta: float) -> void:
label_3d.text = "HP: %d" % hp
if action_timeout > 0:
action_timeout -= delta
if action_timeout <= 0:
task_updated.emit(TaskStatus.TIMED_OUT)
if moving:
if nav_agent_3d.is_target_reached() \
or nav_agent_3d.target_position.is_zero_approx() \
or !nav_agent_3d.is_target_reachable():
moving = false
task_updated.emit(TaskStatus.DONE)
target_velocity = Vector3()
#nav_agent_3d.target_position = move_target + Vector3(randfn(0, move_radius), 0, randfn(0, move_radius))
#nav_agent_3d.target_position = NavigationServer3D.map_get_random_point(NavigationServer3D.get_maps()[0], 1, true)
last_distance_to_target = nav_agent_3d.distance_to_target()
else:
var next_point: Vector3 = nav_agent_3d.get_next_path_position()
if shapecast_3d.is_colliding():
var distance_to_target: float = global_position.distance_to(next_point)
var progress_rate: float = (last_distance_to_target - distance_to_target) / delta
last_distance_to_target = distance_to_target
if progress_rate < minimum_progress_rate:
stuck_timer += delta
if stuck_timer >= stuck_time:
unstuck()
else:
label_3d.modulate = Color.WHITE
stuck_timer = 0
if global_position.y <= -10:
unstuck()
DebugDraw3D.draw_sphere(nav_agent_3d.target_position, 0.5, Color.RED)
#DebugDraw3D.draw_sphere(next_point, 0.1, Color.YELLOW)
var direction: Vector3 = (next_point - global_position).normalized()
#basis = Basis.looking_at(direction)
#DebugDraw3D.draw_line(global_position, global_position + linear_velocity, Color.BLUE)
target_velocity = direction * max_speed
nav_agent_3d.velocity = target_velocity
#DebugDraw3D.draw_line(global_position, global_positiaon + target_velocity, Color.MAGENTA)
#DebugDraw3D.draw_text(global_position + Vector3(0,1,0), "%f" % nav_agent_3d.distance_to_target())
if nav_agent_3d.is_target_reached() \
or nav_agent_3d.target_position.is_zero_approx() \
or !nav_agent_3d.is_target_reachable():
#target_velocity = Vector3()
nav_agent_3d.target_position = move_target + Vector3(randfn(0, move_radius), 0, randfn(0, move_radius))
#nav_agent_3d.target_position = NavigationServer3D.map_get_random_point(NavigationServer3D.get_maps()[0], 1, true)
last_distance_to_target = nav_agent_3d.distance_to_target()
else:
if shapecast_3d.is_colliding():
var distance_to_target: float = nav_agent_3d.distance_to_target()
var progress_rate: float = (last_distance_to_target - distance_to_target) / delta
last_distance_to_target = distance_to_target
if progress_rate < minimum_progress_rate:
stuck_timer += delta
if stuck_timer >= stuck_time:
unstuck()
else:
label_3d.modulate = Color.WHITE
stuck_timer = 0
if global_position.y <= -10:
unstuck()
#DebugDraw3D.draw_sphere(nav_agent_3d.target_position, 0.5, Color.RED)
var next_point: Vector3 = nav_agent_3d.get_next_path_position()
#DebugDraw3D.draw_sphere(next_point, 0.1, Color.YELLOW)
var direction: Vector3 = (next_point - global_position).normalized()
#basis = Basis.looking_at(direction)
#DebugDraw3D.draw_line(global_position, global_position + linear_velocity, Color.BLUE)
target_velocity = direction * max_speed
nav_agent_3d.velocity = target_velocity
#DebugDraw3D.draw_line(global_position, global_positiaon + target_velocity, Color.MAGENTA)
#DebugDraw3D.draw_text(global_position + Vector3(0,1,0), "%f" % nav_agent_3d.distance_to_target())
func unstuck() -> void:
# teleport to next path point
@ -132,32 +101,3 @@ func _physics_process(delta: float) -> void:
apply_torque(Vector3(0,force_direction.normalized().signed_angle_to(-global_basis.z, Vector3.DOWN) * rotation_torque,0))
#DebugDraw3D.draw_line(global_position, global_position - global_basis.z, Color.BLUE)
#DebugDraw3D.draw_line(global_position, global_position + force_direction, Color.RED)
func send_task_update(task_status: TaskStatus) -> void:
task_updated.emit(task_status)
func wait_for_task_update() -> TaskStatus:
var status_received: TaskStatus = await task_updated;
return status_received
func go_to_destination(destination: Vector3) -> bool:
move_target = destination
moving = true
return (await wait_for_task_update()) == TaskStatus.DONE
func take_item_from_building(item: Item, building: Building) -> bool:
if held_item != null:
return false
if building.producer != null:
if !await building.producer.wait_for_item(item, 3.0):
return false
#if building.consumer == null:
#return false
#if await building.consumer.wait_for_item(item, 3.0):
#if !building.consumer.take_item_from_storage(item):
#return false
held_item = item
return true
func drop_item() -> bool:
return false

View File

@ -1,12 +0,0 @@
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://8s2tly6ax07u"]
[ext_resource type="Shader" uid="uid://bqr6jesnetffs" path="res://shaders/hologram.gdshader" id="1_p0wwg"]
[resource]
render_priority = 0
shader = ExtResource("1_p0wwg")
shader_parameter/albedo_color = Color(1, 1, 1, 1)
shader_parameter/enable_warp = true
shader_parameter/warp_vector = Vector3(0.1, 0, 0.1)
shader_parameter/warp_strength = 0.576
shader_parameter/warp_rate = 29.667