Compare commits
No commits in common. "a23db504caea8c53d24e8c6d5f12e6ff9f77c821" and "412736b9d5a70754c2af3bc9cb8c2b3c58a8785b" have entirely different histories.
a23db504ca
...
412736b9d5
189
node_3d.tscn
189
node_3d.tscn
File diff suppressed because one or more lines are too long
|
@ -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)
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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"]
|
||||
|
|
|
@ -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"
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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("../../..")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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
|
|
@ -1 +0,0 @@
|
|||
uid://ckf7i6ig4twnq
|
|
@ -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,36 +31,14 @@ 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] = {}
|
||||
|
||||
func _ready() -> void:
|
||||
if nav_obstacle != null:
|
||||
functional_changed.connect(func(enable:bool): nav_obstacle.enabled = enable)
|
||||
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
#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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"):
|
||||
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_action("building_cancel"):
|
||||
placement_cancel()
|
||||
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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -1 +0,0 @@
|
|||
uid://ba5aqcwabpfp0
|
|
@ -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:
|
||||
|
|
|
@ -2,6 +2,3 @@ extends Unit
|
|||
class_name Enemy
|
||||
|
||||
var sighted: bool = true
|
||||
|
||||
func _ready() -> void:
|
||||
go_to_destination(Vector3(17,1,15))
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
|
@ -1 +0,0 @@
|
|||
uid://cc3hwuckhboi1
|
|
@ -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,25 +38,16 @@ 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))
|
||||
#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 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:
|
||||
|
@ -91,7 +59,8 @@ func _process(delta: float) -> void:
|
|||
stuck_timer = 0
|
||||
if global_position.y <= -10:
|
||||
unstuck()
|
||||
DebugDraw3D.draw_sphere(nav_agent_3d.target_position, 0.5, Color.RED)
|
||||
#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)
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue