Add building contruction, and various other changes.
This commit is contained in:
parent
db4d405464
commit
a176f50a14
|
@ -9,3 +9,17 @@
|
||||||
*.so filter=lfs diff=lfs merge=lfs -text
|
*.so filter=lfs diff=lfs merge=lfs -text
|
||||||
*.dylib filter=lfs diff=lfs merge=lfs -text
|
*.dylib filter=lfs diff=lfs merge=lfs -text
|
||||||
*.wasm filter=lfs diff=lfs merge=lfs -text
|
*.wasm filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.dmg filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.apk filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.ipa filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.exe filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.dll filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.so filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.dylib filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.psd filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.ai filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.sketch filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.blend filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.fbx filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.obj filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.xcf filter=lfs diff=lfs merge=lfs -text
|
||||||
|
|
|
@ -10,10 +10,22 @@
|
||||||
"resource_name": {
|
"resource_name": {
|
||||||
"visibility": 0.0
|
"visibility": 0.0
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"res://objects/buildings/": {
|
||||||
|
"metadata/_custom_type_script": {
|
||||||
|
"visibility": 0.0
|
||||||
|
},
|
||||||
|
"resource_local_to_scene": {
|
||||||
|
"visibility": 0.0
|
||||||
|
},
|
||||||
|
"resource_name": {
|
||||||
|
"visibility": 0.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"recent_paths": [
|
"recent_paths": [
|
||||||
"res://items/"
|
"res://items/",
|
||||||
|
"res://objects/buildings/"
|
||||||
],
|
],
|
||||||
"table_functions": {
|
"table_functions": {
|
||||||
"filter": [
|
"filter": [
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
assets/models/Block Nav.obj (Stored with Git LFS)
BIN
assets/models/Block Nav.obj (Stored with Git LFS)
Binary file not shown.
BIN
assets/models/Block.obj (Stored with Git LFS)
BIN
assets/models/Block.obj (Stored with Git LFS)
Binary file not shown.
BIN
assets/models/Bullets.obj (Stored with Git LFS)
BIN
assets/models/Bullets.obj (Stored with Git LFS)
Binary file not shown.
BIN
assets/models/Conveyor.obj (Stored with Git LFS)
BIN
assets/models/Conveyor.obj (Stored with Git LFS)
Binary file not shown.
BIN
assets/models/Ingot.obj (Stored with Git LFS)
BIN
assets/models/Ingot.obj (Stored with Git LFS)
Binary file not shown.
BIN
assets/models/Miner.obj (Stored with Git LFS)
BIN
assets/models/Miner.obj (Stored with Git LFS)
Binary file not shown.
BIN
assets/models/Ore.obj (Stored with Git LFS)
BIN
assets/models/Ore.obj (Stored with Git LFS)
Binary file not shown.
BIN
assets/models/Ramp Corner Inner Nav.obj (Stored with Git LFS)
BIN
assets/models/Ramp Corner Inner Nav.obj (Stored with Git LFS)
Binary file not shown.
BIN
assets/models/Ramp Corner Inner.obj (Stored with Git LFS)
BIN
assets/models/Ramp Corner Inner.obj (Stored with Git LFS)
Binary file not shown.
BIN
assets/models/Ramp Corner Outer Nav.obj (Stored with Git LFS)
BIN
assets/models/Ramp Corner Outer Nav.obj (Stored with Git LFS)
Binary file not shown.
BIN
assets/models/Ramp Corner Outer.obj (Stored with Git LFS)
BIN
assets/models/Ramp Corner Outer.obj (Stored with Git LFS)
Binary file not shown.
BIN
assets/models/Ramp Nav.obj (Stored with Git LFS)
BIN
assets/models/Ramp Nav.obj (Stored with Git LFS)
Binary file not shown.
BIN
assets/models/Ramp.obj (Stored with Git LFS)
BIN
assets/models/Ramp.obj (Stored with Git LFS)
Binary file not shown.
|
@ -1,4 +1,5 @@
|
||||||
extends GridMap
|
@tool
|
||||||
|
extends CustomGridMap
|
||||||
|
|
||||||
var postprocess_done: bool = false
|
var postprocess_done: bool = false
|
||||||
|
|
||||||
|
|
192
node_3d.tscn
192
node_3d.tscn
File diff suppressed because one or more lines are too long
|
@ -30,11 +30,10 @@ mesh = SubResource("BoxMesh_cee1v")
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
||||||
shape = SubResource("BoxShape3D_k07no")
|
shape = SubResource("BoxShape3D_k07no")
|
||||||
disabled = true
|
|
||||||
|
|
||||||
[node name="NavObstacle" type="Node3D" parent="."]
|
[node name="NavObstacle" type="Node3D" parent="."]
|
||||||
script = ExtResource("2_0gk2u")
|
script = ExtResource("2_0gk2u")
|
||||||
make_solid = false
|
enabled = true
|
||||||
|
|
||||||
[node name="NavigationObstacle3D" type="NavigationObstacle3D" parent="."]
|
[node name="NavigationObstacle3D" type="NavigationObstacle3D" parent="."]
|
||||||
radius = 2.0
|
radius = 2.0
|
||||||
|
@ -47,3 +46,9 @@ navigation_mesh = SubResource("NavigationMesh_0gk2u")
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0)
|
||||||
visible = false
|
visible = false
|
||||||
mesh = SubResource("QuadMesh_oywkk")
|
mesh = SubResource("QuadMesh_oywkk")
|
||||||
|
|
||||||
|
[node name="Label3D" type="Label3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3.00872, 0)
|
||||||
|
billboard = 1
|
||||||
|
text = "Input: 1
|
||||||
|
Output: 2"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
[gd_scene load_steps=8 format=3 uid="uid://dhfqv26h4i0i3"]
|
[gd_scene load_steps=10 format=3 uid="uid://dhfqv26h4i0i3"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://cnoyykkcidp1d" path="res://scripts/buildings/conveyor.gd" id="1_m8ga5"]
|
[ext_resource type="Script" uid="uid://cnoyykkcidp1d" path="res://scripts/buildings/conveyor.gd" id="1_m8ga5"]
|
||||||
[ext_resource type="ArrayMesh" uid="uid://bv225xw8xssl4" path="res://assets/models/Conveyor.obj" id="2_dyib0"]
|
[ext_resource type="ArrayMesh" uid="uid://bv225xw8xssl4" path="res://assets/models/Conveyor.obj" id="2_dyib0"]
|
||||||
|
@ -6,25 +6,36 @@
|
||||||
[ext_resource type="Script" uid="uid://c4fquatkjmsgu" path="res://scripts/building_components/producer.gd" id="4_d3uke"]
|
[ext_resource type="Script" uid="uid://c4fquatkjmsgu" path="res://scripts/building_components/producer.gd" id="4_d3uke"]
|
||||||
[ext_resource type="ArrayMesh" uid="uid://c6yj8uwsgqxv0" path="res://assets/models/Ingot.obj" id="5_w2262"]
|
[ext_resource type="ArrayMesh" uid="uid://c6yj8uwsgqxv0" path="res://assets/models/Ingot.obj" id="5_w2262"]
|
||||||
|
|
||||||
[sub_resource type="Curve3D" id="Curve3D_r3fl7"]
|
[sub_resource type="Curve3D" id="Curve3D_m8ga5"]
|
||||||
_data = {
|
_data = {
|
||||||
"points": PackedVector3Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2),
|
"points": PackedVector3Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2),
|
||||||
"tilts": PackedFloat32Array(0, 0)
|
"tilts": PackedFloat32Array(0, 0)
|
||||||
}
|
}
|
||||||
point_count = 2
|
point_count = 2
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_m8ga5"]
|
||||||
|
albedo_color = Color(0.0703125, 0.0703125, 0.0703125, 1)
|
||||||
|
|
||||||
|
[sub_resource type="BoxMesh" id="BoxMesh_dyib0"]
|
||||||
|
material = SubResource("StandardMaterial3D_m8ga5")
|
||||||
|
size = Vector3(0.5, 0.3, 1)
|
||||||
|
|
||||||
[sub_resource type="MultiMesh" id="MultiMesh_6iypd"]
|
[sub_resource type="MultiMesh" id="MultiMesh_6iypd"]
|
||||||
transform_format = 1
|
transform_format = 1
|
||||||
instance_count = 1
|
instance_count = 1
|
||||||
mesh = ExtResource("5_w2262")
|
mesh = ExtResource("5_w2262")
|
||||||
buffer = PackedFloat32Array(1, 8.40779e-44, 8.54792e-44, 9.10844e-44, 8.54792e-44, 1, 9.10844e-44, 0.325, 8.82818e-44, 9.10844e-44, 1, 8.96831e-44)
|
buffer = PackedFloat32Array(1, 8.40779e-44, 8.54792e-44, 9.10844e-44, 8.54792e-44, 1, 9.10844e-44, 0.325, 8.82818e-44, 9.10844e-44, 1, 8.96831e-44)
|
||||||
|
|
||||||
[node name="Conveyor" type="Path3D"]
|
[node name="Conveyor" type="Node3D"]
|
||||||
curve = SubResource("Curve3D_r3fl7")
|
|
||||||
script = ExtResource("1_m8ga5")
|
script = ExtResource("1_m8ga5")
|
||||||
item_offset = Vector3(0, 0.325, 0)
|
item_offset = Vector3(0, 0.325, 0)
|
||||||
|
spacing = 0.5
|
||||||
|
|
||||||
[node name="PathMesh3D" type="PathMesh3D" parent="." node_paths=PackedStringArray("path_3d")]
|
[node name="Path3D" type="Path3D" parent="."]
|
||||||
|
curve = SubResource("Curve3D_m8ga5")
|
||||||
|
|
||||||
|
[node name="PathMesh3D" type="PathMesh3D" parent="Path3D" node_paths=PackedStringArray("path_3d")]
|
||||||
|
mesh_transform = 1
|
||||||
mesh = ExtResource("2_dyib0")
|
mesh = ExtResource("2_dyib0")
|
||||||
path_3d = NodePath("..")
|
path_3d = NodePath("..")
|
||||||
surface_0/tile_rotation = Vector3(0, 0, 0)
|
surface_0/tile_rotation = Vector3(0, 0, 0)
|
||||||
|
@ -43,19 +54,37 @@ surface_1/warp_along_curve = true
|
||||||
surface_1/sample_cubic = false
|
surface_1/sample_cubic = false
|
||||||
surface_1/tilt = true
|
surface_1/tilt = true
|
||||||
surface_1/offset = Vector2(0, 0)
|
surface_1/offset = Vector2(0, 0)
|
||||||
|
visibility_range_end = 100.0
|
||||||
|
|
||||||
|
[node name="PathMesh3D2" type="PathMesh3D" parent="Path3D" node_paths=PackedStringArray("path_3d")]
|
||||||
|
mesh_transform = 1
|
||||||
|
mesh = SubResource("BoxMesh_dyib0")
|
||||||
|
path_3d = NodePath("..")
|
||||||
|
surface_0/tile_rotation = Vector3(0, 0, 0)
|
||||||
|
surface_0/tile_rotation_order = 2
|
||||||
|
surface_0/distribution = 0
|
||||||
|
surface_0/alignment = 0
|
||||||
|
surface_0/warp_along_curve = true
|
||||||
|
surface_0/sample_cubic = false
|
||||||
|
surface_0/tilt = true
|
||||||
|
surface_0/offset = Vector2(0, 0)
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.1, 0)
|
||||||
|
visibility_range_begin = 100.0
|
||||||
|
|
||||||
[node name="Consumer" type="Node" parent="."]
|
[node name="Consumer" type="Node" parent="."]
|
||||||
script = ExtResource("3_vjqud")
|
script = ExtResource("3_vjqud")
|
||||||
storage_size = 1
|
storage_size = 1
|
||||||
metadata/_custom_type_script = "uid://bshiyw2k3op02"
|
metadata/_custom_type_script = "uid://bshiyw2k3op02"
|
||||||
|
|
||||||
[node name="Producer" type="Node" parent="." node_paths=PackedStringArray("consumers")]
|
[node name="Producer" type="Node" parent="."]
|
||||||
script = ExtResource("4_d3uke")
|
script = ExtResource("4_d3uke")
|
||||||
consumers = [null]
|
|
||||||
metadata/_custom_type_script = "uid://c4fquatkjmsgu"
|
metadata/_custom_type_script = "uid://c4fquatkjmsgu"
|
||||||
|
|
||||||
[node name="MultiMeshInstance3D" type="MultiMeshInstance3D" parent="."]
|
[node name="MultiMeshInstance3D" type="MultiMeshInstance3D" parent="."]
|
||||||
physics_interpolation_mode = 2
|
physics_interpolation_mode = 2
|
||||||
|
visibility_range_end = 50.0
|
||||||
|
visibility_range_end_margin = 50.0
|
||||||
|
visibility_range_fade_mode = 1
|
||||||
multimesh = SubResource("MultiMesh_6iypd")
|
multimesh = SubResource("MultiMesh_6iypd")
|
||||||
|
|
||||||
[connection signal="item_added" from="Consumer" to="." method="consumer_has_item"]
|
[connection signal="item_added" from="Consumer" to="." method="consumer_has_item"]
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://b1fnsl3k1mo5c" path="res://objects/buildings/building.tscn" id="1_8r86l"]
|
[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="Script" uid="uid://6dy54s70qf0x" path="res://scripts/buildings/miner.gd" id="2_k13eg"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cjg7f5ktk20yq" path="res://assets/blends/Miner.blend" id="2_la0h1"]
|
[ext_resource type="PackedScene" uid="uid://dx13fyjv0d8st" path="res://assets/blends/Miner.blend" id="2_la0h1"]
|
||||||
[ext_resource type="Resource" uid="uid://dbkxys3mr5u80" path="res://items/metal.tres" 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"]
|
[ext_resource type="Script" uid="uid://c4fquatkjmsgu" path="res://scripts/building_components/producer.gd" id="5_65oni"]
|
||||||
|
|
||||||
[node name="Miner" instance=ExtResource("1_8r86l")]
|
[node name="Miner" instance=ExtResource("1_8r86l")]
|
||||||
script = ExtResource("2_k13eg")
|
script = ExtResource("2_k13eg")
|
||||||
mined_item = ExtResource("3_8y6s2")
|
|
||||||
mine_period = 1.0
|
mine_period = 1.0
|
||||||
|
can_stack = false
|
||||||
|
|
||||||
[node name="MeshInstance3D" parent="." index="0"]
|
[node name="MeshInstance3D" parent="." index="0"]
|
||||||
visible = false
|
visible = false
|
||||||
|
@ -18,4 +18,5 @@ visible = false
|
||||||
|
|
||||||
[node name="Producer" type="Node" parent="." index="6"]
|
[node name="Producer" type="Node" parent="." index="6"]
|
||||||
script = ExtResource("5_65oni")
|
script = ExtResource("5_65oni")
|
||||||
|
produced_item = ExtResource("3_k13eg")
|
||||||
metadata/_custom_type_script = "uid://c4fquatkjmsgu"
|
metadata/_custom_type_script = "uid://c4fquatkjmsgu"
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
[ext_resource type="Script" uid="uid://kcdpck5ufgcc" path="res://scripts/item.gd" id="3_3h7kv"]
|
[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="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://bshiyw2k3op02" path="res://scripts/building_components/consumer.gd" id="4_dx8de"]
|
||||||
[ext_resource type="Resource" uid="uid://dbkxys3mr5u80" path="res://items/metal.tres" id="4_miqab"]
|
|
||||||
[ext_resource type="Script" uid="uid://c4fquatkjmsgu" path="res://scripts/building_components/producer.gd" id="5_p3dou"]
|
[ext_resource type="Script" uid="uid://c4fquatkjmsgu" path="res://scripts/building_components/producer.gd" id="5_p3dou"]
|
||||||
|
[ext_resource type="Resource" uid="uid://dxlb2ixt3fx7l" path="res://items/ore.tres" id="7_dx8de"]
|
||||||
|
|
||||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_evfwj"]
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_evfwj"]
|
||||||
albedo_color = Color(0.023159, 1, 0, 1)
|
albedo_color = Color(0.023159, 1, 0, 1)
|
||||||
|
@ -18,18 +18,19 @@ size = Vector3(2, 2, 2)
|
||||||
[node name="Processor" instance=ExtResource("1_hxugg")]
|
[node name="Processor" instance=ExtResource("1_hxugg")]
|
||||||
script = ExtResource("2_evfwj")
|
script = ExtResource("2_evfwj")
|
||||||
ingredients = Dictionary[ExtResource("3_3h7kv"), int]({
|
ingredients = Dictionary[ExtResource("3_3h7kv"), int]({
|
||||||
ExtResource("4_miqab"): 2
|
ExtResource("7_dx8de"): 2
|
||||||
})
|
})
|
||||||
process_time = 1.0
|
process_time = 1.0
|
||||||
created_item = ExtResource("4_3h7kv")
|
|
||||||
|
|
||||||
[node name="MeshInstance3D" parent="." index="0"]
|
[node name="MeshInstance3D" parent="." index="0"]
|
||||||
mesh = SubResource("BoxMesh_3h7kv")
|
mesh = SubResource("BoxMesh_3h7kv")
|
||||||
|
|
||||||
[node name="Consumer" type="Node" parent="." index="2"]
|
[node name="Consumer" type="Node" parent="." index="2"]
|
||||||
script = ExtResource("4_dx8de")
|
script = ExtResource("4_dx8de")
|
||||||
|
accepted_items = Array[ExtResource("3_3h7kv")]([ExtResource("7_dx8de")])
|
||||||
metadata/_custom_type_script = "uid://bshiyw2k3op02"
|
metadata/_custom_type_script = "uid://bshiyw2k3op02"
|
||||||
|
|
||||||
[node name="Producer" type="Node" parent="." index="3"]
|
[node name="Producer" type="Node" parent="." index="3"]
|
||||||
script = ExtResource("5_p3dou")
|
script = ExtResource("5_p3dou")
|
||||||
|
produced_item = ExtResource("4_3h7kv")
|
||||||
metadata/_custom_type_script = "uid://c4fquatkjmsgu"
|
metadata/_custom_type_script = "uid://c4fquatkjmsgu"
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
[gd_scene load_steps=17 format=3 uid="uid://cav22qho14o47"]
|
[gd_scene load_steps=25 format=3 uid="uid://cav22qho14o47"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://ca8i18spgok4i" path="res://scripts/bullet.gd" id="1_rsjgb"]
|
[ext_resource type="Script" uid="uid://ca8i18spgok4i" path="res://scripts/bullet.gd" id="1_rsjgb"]
|
||||||
[ext_resource type="Shader" uid="uid://jtlad4viky6j" path="res://addons/GPUTrail/shaders/trail.gdshader" id="1_ucnj8"]
|
[ext_resource type="Shader" uid="uid://jtlad4viky6j" path="res://addons/GPUTrail/shaders/trail.gdshader" id="1_ucnj8"]
|
||||||
[ext_resource type="Shader" uid="uid://cxd8wfunwre2a" path="res://addons/GPUTrail/shaders/trail_draw_pass.gdshader" id="2_rsjgb"]
|
[ext_resource type="Shader" uid="uid://cxd8wfunwre2a" path="res://addons/GPUTrail/shaders/trail_draw_pass.gdshader" id="2_rsjgb"]
|
||||||
[ext_resource type="Script" uid="uid://cdubip3a6325r" path="res://addons/GPUTrail/GPUTrail3D.gd" id="4_pt3a8"]
|
[ext_resource type="Script" uid="uid://cdubip3a6325r" path="res://addons/GPUTrail/GPUTrail3D.gd" id="4_pt3a8"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://ct31fhxvcragr" path="res://addons/GPUTrail/defaults/curve.tres" id="4_rsjgb"]
|
||||||
|
|
||||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_3ndsa"]
|
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_3ndsa"]
|
||||||
radius = 0.1
|
radius = 0.1
|
||||||
|
@ -13,21 +14,12 @@ height = 0.3
|
||||||
shader = ExtResource("1_ucnj8")
|
shader = ExtResource("1_ucnj8")
|
||||||
|
|
||||||
[sub_resource type="Gradient" id="Gradient_6sxjd"]
|
[sub_resource type="Gradient" id="Gradient_6sxjd"]
|
||||||
offsets = PackedFloat32Array(0, 0.150862, 0.642241, 1)
|
offsets = PackedFloat32Array(0, 0.0818966, 0.965517, 1)
|
||||||
colors = PackedColorArray(1, 1, 1, 1, 1, 0.920817, 0, 0.849138, 0.695312, 0.044384, 0, 0.357759, 1, 1, 1, 0)
|
colors = PackedColorArray(0.983734, 1, 0.952478, 0, 0.996515, 0.887301, 0.259986, 1, 1, 0.0352941, 0.0352941, 1, 1, 0, 0.0265193, 0)
|
||||||
|
|
||||||
[sub_resource type="GradientTexture1D" id="GradientTexture1D_od3fb"]
|
[sub_resource type="GradientTexture1D" id="GradientTexture1D_od3fb"]
|
||||||
gradient = SubResource("Gradient_6sxjd")
|
gradient = SubResource("Gradient_6sxjd")
|
||||||
|
|
||||||
[sub_resource type="Curve" id="Curve_tmmim"]
|
|
||||||
_limits = [0.0, 0.1, 0.0, 1.0]
|
|
||||||
bake_resolution = 16
|
|
||||||
_data = [Vector2(0, 0.1), 0.0, -0.167493, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
|
||||||
point_count = 2
|
|
||||||
|
|
||||||
[sub_resource type="CurveTexture" id="CurveTexture_7thed"]
|
|
||||||
curve = SubResource("Curve_tmmim")
|
|
||||||
|
|
||||||
[sub_resource type="Curve" id="Curve_ucnj8"]
|
[sub_resource type="Curve" id="Curve_ucnj8"]
|
||||||
_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.511628, 1), -1.30273, -1.30273, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.511628, 1), -1.30273, -1.30273, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
||||||
point_count = 3
|
point_count = 3
|
||||||
|
@ -41,9 +33,9 @@ shader = ExtResource("2_rsjgb")
|
||||||
shader_parameter/tex = SubResource("CurveTexture_rsjgb")
|
shader_parameter/tex = SubResource("CurveTexture_rsjgb")
|
||||||
shader_parameter/uv_offset = Vector2(0, 0)
|
shader_parameter/uv_offset = Vector2(0, 0)
|
||||||
shader_parameter/color_ramp = SubResource("GradientTexture1D_od3fb")
|
shader_parameter/color_ramp = SubResource("GradientTexture1D_od3fb")
|
||||||
shader_parameter/curve = SubResource("CurveTexture_7thed")
|
shader_parameter/curve = ExtResource("4_rsjgb")
|
||||||
shader_parameter/emmission_transform = Projection(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
|
shader_parameter/emmission_transform = Projection(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
|
||||||
shader_parameter/flags = 45
|
shader_parameter/flags = 47
|
||||||
|
|
||||||
[sub_resource type="QuadMesh" id="QuadMesh_ucnj8"]
|
[sub_resource type="QuadMesh" id="QuadMesh_ucnj8"]
|
||||||
material = SubResource("ShaderMaterial_xbcx7")
|
material = SubResource("ShaderMaterial_xbcx7")
|
||||||
|
@ -63,6 +55,54 @@ height = 0.3
|
||||||
radial_segments = 6
|
radial_segments = 6
|
||||||
rings = 0
|
rings = 0
|
||||||
|
|
||||||
|
[sub_resource type="Curve" id="Curve_rsjgb"]
|
||||||
|
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), -2.95938, 0.0, 0, 0]
|
||||||
|
point_count = 2
|
||||||
|
|
||||||
|
[sub_resource type="CurveTexture" id="CurveTexture_4agyf"]
|
||||||
|
curve = SubResource("Curve_rsjgb")
|
||||||
|
|
||||||
|
[sub_resource type="Gradient" id="Gradient_pt3a8"]
|
||||||
|
colors = PackedColorArray(1, 0.952478, 0.959973, 1, 1, 0, 0.00575256, 1)
|
||||||
|
|
||||||
|
[sub_resource type="GradientTexture1D" id="GradientTexture1D_fsn5s"]
|
||||||
|
gradient = SubResource("Gradient_pt3a8")
|
||||||
|
|
||||||
|
[sub_resource type="Gradient" id="Gradient_od3fb"]
|
||||||
|
colors = PackedColorArray(1, 1, 1, 1, 0.995088, 1, 0, 1)
|
||||||
|
|
||||||
|
[sub_resource type="GradientTexture1D" id="GradientTexture1D_tmmim"]
|
||||||
|
gradient = SubResource("Gradient_od3fb")
|
||||||
|
|
||||||
|
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_7thed"]
|
||||||
|
particle_flag_align_y = true
|
||||||
|
direction = Vector3(1, 0.2, 0)
|
||||||
|
spread = 5.164
|
||||||
|
initial_velocity_max = 67.46
|
||||||
|
scale_max = 3.0
|
||||||
|
color = Color(0.946782, 1, 0.245254, 1)
|
||||||
|
color_ramp = SubResource("GradientTexture1D_tmmim")
|
||||||
|
color_initial_ramp = SubResource("GradientTexture1D_fsn5s")
|
||||||
|
alpha_curve = SubResource("CurveTexture_4agyf")
|
||||||
|
turbulence_enabled = true
|
||||||
|
turbulence_influence_min = 0.0
|
||||||
|
|
||||||
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1r0jv"]
|
||||||
|
transparency = 1
|
||||||
|
vertex_color_use_as_albedo = true
|
||||||
|
albedo_color = Color(0.978998, 1, 0.633145, 1)
|
||||||
|
emission_enabled = true
|
||||||
|
emission = Color(1, 1, 1, 1)
|
||||||
|
emission_energy_multiplier = 4.1
|
||||||
|
billboard_mode = 3
|
||||||
|
particles_anim_h_frames = 1
|
||||||
|
particles_anim_v_frames = 1
|
||||||
|
particles_anim_loop = false
|
||||||
|
|
||||||
|
[sub_resource type="QuadMesh" id="QuadMesh_oabvv"]
|
||||||
|
material = SubResource("StandardMaterial3D_1r0jv")
|
||||||
|
size = Vector2(0.1, 0.1)
|
||||||
|
|
||||||
[node name="Bullet" type="RigidBody3D"]
|
[node name="Bullet" type="RigidBody3D"]
|
||||||
collision_layer = 16
|
collision_layer = 16
|
||||||
collision_mask = 5
|
collision_mask = 5
|
||||||
|
@ -79,7 +119,7 @@ shape = SubResource("CapsuleShape3D_3ndsa")
|
||||||
|
|
||||||
[node name="GPUTrail3D" type="GPUParticles3D" parent="."]
|
[node name="GPUTrail3D" type="GPUParticles3D" parent="."]
|
||||||
physics_interpolation_mode = 2
|
physics_interpolation_mode = 2
|
||||||
transform = Transform3D(0.233971, -0.972243, 0, 0.972243, 0.233971, 0, 0, 0, 1, 0, 0, 0)
|
transform = Transform3D(0.0233971, -0.0972244, 0, 0.0972244, 0.0233971, 0, 0, 0, 0.1, 0, 0, 0)
|
||||||
amount = 19
|
amount = 19
|
||||||
lifetime = 19.0
|
lifetime = 19.0
|
||||||
explosiveness = 1.0
|
explosiveness = 1.0
|
||||||
|
@ -91,8 +131,8 @@ length = 19
|
||||||
length_seconds = 0.322034
|
length_seconds = 0.322034
|
||||||
texture = SubResource("CurveTexture_rsjgb")
|
texture = SubResource("CurveTexture_rsjgb")
|
||||||
color_ramp = SubResource("GradientTexture1D_od3fb")
|
color_ramp = SubResource("GradientTexture1D_od3fb")
|
||||||
curve = SubResource("CurveTexture_7thed")
|
|
||||||
vertical_texture = true
|
vertical_texture = true
|
||||||
|
use_red_as_alpha = true
|
||||||
billboard = true
|
billboard = true
|
||||||
_defaults_have_been_set = true
|
_defaults_have_been_set = true
|
||||||
metadata/_custom_type_script = "uid://cdubip3a6325r"
|
metadata/_custom_type_script = "uid://cdubip3a6325r"
|
||||||
|
@ -105,4 +145,12 @@ mesh = SubResource("CylinderMesh_xbcx7")
|
||||||
[node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="."]
|
[node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="."]
|
||||||
max_polyphony = 2
|
max_polyphony = 2
|
||||||
|
|
||||||
|
[node name="GPUParticles3D" type="GPUParticles3D" parent="."]
|
||||||
|
transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, 0, 0, 0)
|
||||||
|
visible = false
|
||||||
|
emitting = false
|
||||||
|
amount = 40
|
||||||
|
process_material = SubResource("ParticleProcessMaterial_7thed")
|
||||||
|
draw_pass_1 = SubResource("QuadMesh_oabvv")
|
||||||
|
|
||||||
[connection signal="body_entered" from="." to="." method="_on_body_entered"]
|
[connection signal="body_entered" from="." to="." method="_on_body_entered"]
|
||||||
|
|
|
@ -27,7 +27,7 @@ config/name="TowerGame3D"
|
||||||
run/main_scene="uid://bwftban1ppo17"
|
run/main_scene="uid://bwftban1ppo17"
|
||||||
config/features=PackedStringArray("4.4")
|
config/features=PackedStringArray("4.4")
|
||||||
config/icon="uid://u1hpdb62rxlc"
|
config/icon="uid://u1hpdb62rxlc"
|
||||||
addons/icon_finder/preview_size=24
|
addons/icon_finder/preview_size=25
|
||||||
|
|
||||||
[autoload]
|
[autoload]
|
||||||
|
|
||||||
|
@ -36,6 +36,20 @@ IconsFonts="*res://addons/icons-fonts/icons_fonts/IconsFonts.gd"
|
||||||
[debug]
|
[debug]
|
||||||
|
|
||||||
settings/stdout/print_fps=true
|
settings/stdout/print_fps=true
|
||||||
|
gdscript/warnings/unassigned_variable=2
|
||||||
|
gdscript/warnings/unassigned_variable_op_assign=2
|
||||||
|
gdscript/warnings/shadowed_variable=2
|
||||||
|
gdscript/warnings/shadowed_variable_base_class=2
|
||||||
|
gdscript/warnings/shadowed_global_identifier=2
|
||||||
|
gdscript/warnings/incompatible_ternary=2
|
||||||
|
gdscript/warnings/untyped_declaration=1
|
||||||
|
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/static_called_on_instance=2
|
||||||
|
gdscript/warnings/missing_tool=2
|
||||||
|
gdscript/warnings/assert_always_false=2
|
||||||
shapes/navigation/enable_edge_connections=false
|
shapes/navigation/enable_edge_connections=false
|
||||||
shapes/navigation/enable_edge_connections_xray=false
|
shapes/navigation/enable_edge_connections_xray=false
|
||||||
shapes/navigation/enable_edge_lines_xray=false
|
shapes/navigation/enable_edge_lines_xray=false
|
||||||
|
@ -90,6 +104,23 @@ camera_set_target={
|
||||||
"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":3,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
"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":3,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
camera_zoom_in={
|
||||||
|
"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":4,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
camera_zoom_out={
|
||||||
|
"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":5,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
building_place={
|
||||||
|
"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":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
||||||
|
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194309,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
[layer_names]
|
[layer_names]
|
||||||
|
|
||||||
|
@ -109,6 +140,7 @@ camera_set_target={
|
||||||
|
|
||||||
3d/default_edge_connection_margin=0.6
|
3d/default_edge_connection_margin=0.6
|
||||||
3d/default_link_connection_radius=0.5
|
3d/default_link_connection_radius=0.5
|
||||||
|
pathfinding/max_threads=-1
|
||||||
|
|
||||||
[physics]
|
[physics]
|
||||||
|
|
||||||
|
@ -118,6 +150,3 @@ common/physics_interpolation=true
|
||||||
|
|
||||||
lights_and_shadows/directional_shadow/soft_shadow_filter_quality=0
|
lights_and_shadows/directional_shadow/soft_shadow_filter_quality=0
|
||||||
lights_and_shadows/positional_shadow/soft_shadow_filter_quality=0
|
lights_and_shadows/positional_shadow/soft_shadow_filter_quality=0
|
||||||
anti_aliasing/quality/msaa_2d=1
|
|
||||||
anti_aliasing/quality/msaa_3d=1
|
|
||||||
anti_aliasing/quality/screen_space_aa=1
|
|
||||||
|
|
|
@ -1,8 +1,23 @@
|
||||||
extends Node3D
|
extends Node3D
|
||||||
class_name Building
|
class_name Building
|
||||||
|
|
||||||
|
@export_category("Defence")
|
||||||
@export var max_hp: int = 100
|
@export var max_hp: int = 100
|
||||||
|
|
||||||
|
@export_category("Stacking")
|
||||||
|
@export var can_stack: bool = true
|
||||||
|
@export var can_be_stacked_on: bool = true
|
||||||
|
@export var stack_position: Vector3 = Vector3(0,2,0)
|
||||||
|
|
||||||
|
@onready var build_position: Vector3 = global_position
|
||||||
|
|
||||||
|
@onready var nav_obstacle: NavObstable = $NavObstacle
|
||||||
|
@onready var consumer: Consumer = $Consumer
|
||||||
|
@onready var producer: Producer = $Producer
|
||||||
|
@onready var collision_shape: CollisionShape3D = $CollisionShape3D
|
||||||
|
|
||||||
|
signal functional_changed(functional: bool)
|
||||||
|
|
||||||
enum BuildState {
|
enum BuildState {
|
||||||
UNPLACED,
|
UNPLACED,
|
||||||
BUILDING,
|
BUILDING,
|
||||||
|
@ -10,11 +25,88 @@ enum BuildState {
|
||||||
DESTROYED
|
DESTROYED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PLACEMENT_POSITION_OK: int = 0b0001
|
||||||
|
const PLACEMENT_FOUNDATION_REQUIRED: int = 0b0010
|
||||||
|
const PLACEMENT_PART_ADDED: int = 0b0100
|
||||||
|
const PLACEMENT_COMPLETED: int = 0b1000
|
||||||
|
|
||||||
var hp: int = max_hp
|
var hp: int = max_hp
|
||||||
|
|
||||||
|
var stacked_buildings: Array[Building] = []
|
||||||
|
|
||||||
var build_state: BuildState = BuildState.READY:
|
var build_state: BuildState = BuildState.READY:
|
||||||
set(state):
|
set(state):
|
||||||
build_state = state
|
build_state = state
|
||||||
|
functional_changed.emit(is_functional())
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
if nav_obstacle != null:
|
||||||
|
functional_changed.connect(func(enable:bool): nav_obstacle.enabled = enable)
|
||||||
|
if consumer != null:
|
||||||
|
functional_changed.connect(func(enable:bool): consumer.enabled = enable)
|
||||||
|
if producer != null:
|
||||||
|
functional_changed.connect(func(enable:bool): producer.enabled = enable)
|
||||||
|
if collision_shape != null:
|
||||||
|
functional_changed.connect(func(enable:bool): collision_shape.disabled = !enable)
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
if build_state == BuildState.UNPLACED:
|
||||||
|
global_position = global_position.lerp(build_position, 0.4)
|
||||||
|
|
||||||
|
var debug_text: String = ""
|
||||||
|
debug_text += "State: %s\n" % build_state
|
||||||
|
if consumer != null:
|
||||||
|
var consumer_state: String
|
||||||
|
if consumer.enabled:
|
||||||
|
consumer_state = "OK"
|
||||||
|
else:
|
||||||
|
consumer_state = "Off"
|
||||||
|
debug_text += "Input: %s \nStorage: %d\n" % [consumer_state, consumer.storage_total]
|
||||||
|
if producer != null:
|
||||||
|
var producer_state = "OK"
|
||||||
|
if !producer.enabled:
|
||||||
|
producer_state = "Off"
|
||||||
|
elif !producer.can_produce():
|
||||||
|
producer_state = "Blocked"
|
||||||
|
debug_text += "Output: %s\n" % producer_state
|
||||||
|
|
||||||
|
$Label3D.text = debug_text
|
||||||
|
|
||||||
func is_functional() -> bool:
|
func is_functional() -> bool:
|
||||||
return build_state == BuildState.READY
|
return build_state == BuildState.READY
|
||||||
|
|
||||||
|
func _start_placement() -> void:
|
||||||
|
build_state = BuildState.UNPLACED
|
||||||
|
|
||||||
|
func _end_placement() -> void:
|
||||||
|
build_state = BuildState.READY
|
||||||
|
|
||||||
|
func _placement_select_building(building: Building, confirmed: bool) -> int:
|
||||||
|
while !building.stacked_buildings.is_empty():
|
||||||
|
building = building.stacked_buildings[0]
|
||||||
|
|
||||||
|
var stack_ok: bool = can_stack and building.can_be_stacked_on
|
||||||
|
var ret: int = 0
|
||||||
|
|
||||||
|
if stack_ok:
|
||||||
|
build_position = building.global_position + building.stack_position
|
||||||
|
ret |= PLACEMENT_POSITION_OK
|
||||||
|
|
||||||
|
if confirmed and stack_ok:
|
||||||
|
global_position = build_position
|
||||||
|
building.stacked_buildings.append(self)
|
||||||
|
|
||||||
|
ret |= PLACEMENT_COMPLETED
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
func _placement_select_position(pos: Vector3, confirmed: bool) -> int:
|
||||||
|
var ret: int = 0
|
||||||
|
|
||||||
|
ret |= PLACEMENT_POSITION_OK
|
||||||
|
build_position = Vector3(roundf(pos.x), ceilf(pos.y-0.01), roundf(pos.z))
|
||||||
|
if confirmed:
|
||||||
|
build_state = BuildState.BUILDING
|
||||||
|
ret |= PLACEMENT_COMPLETED
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
extends Node
|
||||||
|
class_name BuildingPart
|
||||||
|
|
||||||
|
@export var enabled: bool = true
|
|
@ -0,0 +1 @@
|
||||||
|
uid://cfx1esms1e7py
|
|
@ -1,4 +1,4 @@
|
||||||
extends Node
|
extends BuildingPart
|
||||||
class_name Consumer
|
class_name Consumer
|
||||||
signal item_added(item: Item)
|
signal item_added(item: Item)
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@ var storage: Dictionary[Item, int] = {}
|
||||||
|
|
||||||
func can_accept_item(item: Item) -> bool:
|
func can_accept_item(item: Item) -> bool:
|
||||||
return ((storage_total < storage_size) or void_excess_items) \
|
return ((storage_total < storage_size) or void_excess_items) \
|
||||||
and (accepted_items.has(item) or accepted_items.is_empty())
|
and (accepted_items.has(item) or accepted_items.is_empty()) \
|
||||||
|
and enabled
|
||||||
|
|
||||||
func offer_item(item: Item) -> bool:
|
func offer_item(item: Item) -> bool:
|
||||||
if !can_accept_item(item):
|
if !can_accept_item(item):
|
||||||
|
@ -30,13 +31,13 @@ func check_storage_for_item(item: Item) -> bool:
|
||||||
return check_storage_for_items({item:1})
|
return check_storage_for_items({item:1})
|
||||||
|
|
||||||
func check_storage_for_items(items: Dictionary[Item, int]) -> bool:
|
func check_storage_for_items(items: Dictionary[Item, int]) -> bool:
|
||||||
for item in items.keys():
|
for item: Item in items.keys():
|
||||||
if storage.get(item, 0) < items[item]:
|
if storage.get(item, 0) < items[item]:
|
||||||
return false
|
return false
|
||||||
return true
|
return true
|
||||||
|
|
||||||
func take_any_item_from_storage() -> Item:
|
func take_any_item_from_storage() -> Item:
|
||||||
for item in storage.keys():
|
for item: Item in storage.keys():
|
||||||
if storage[item] >= 1:
|
if storage[item] >= 1:
|
||||||
storage[item] -= 1
|
storage[item] -= 1
|
||||||
storage_total -= 1
|
storage_total -= 1
|
||||||
|
@ -49,7 +50,7 @@ func take_item_from_storage(item: Item) -> bool:
|
||||||
func take_items_from_storage(items: Dictionary[Item, int]) -> bool:
|
func take_items_from_storage(items: Dictionary[Item, int]) -> bool:
|
||||||
if !check_storage_for_items(items):
|
if !check_storage_for_items(items):
|
||||||
return false
|
return false
|
||||||
for item in items.keys():
|
for item: Item in items.keys():
|
||||||
var old_count: int = storage.get(item, 0)
|
var old_count: int = storage.get(item, 0)
|
||||||
storage.set(item, old_count - items[item])
|
storage.set(item, old_count - items[item])
|
||||||
storage_total -= items[item]
|
storage_total -= items[item]
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
extends Node
|
extends BuildingPart
|
||||||
class_name Producer
|
class_name Producer
|
||||||
|
|
||||||
|
@export var produced_item: Item
|
||||||
@export var output_period: float = 0.1
|
@export var output_period: float = 0.1
|
||||||
@export var max_outputs: int = 1
|
@export var max_outputs: int = 1
|
||||||
@export var consumers: Array[Consumer]
|
@export var consumers: Array[Consumer]
|
||||||
|
|
||||||
var next_consumer_idx: int = 0
|
var last_consumer_idx: int = 0
|
||||||
#var output_timer: float = 0.0
|
#var output_timer: float = 0.0
|
||||||
#var output_item: Item
|
#var output_item: Item
|
||||||
|
|
||||||
|
@ -14,16 +15,39 @@ var next_consumer_idx: int = 0
|
||||||
#if output_timer >= output_period:
|
#if output_timer >= output_period:
|
||||||
#output_timer -= output_period
|
#output_timer -= output_period
|
||||||
#output()
|
#output()
|
||||||
|
func can_produce() -> bool:
|
||||||
|
return can_send_item(produced_item)
|
||||||
|
|
||||||
|
func produce() -> bool:
|
||||||
|
return send_item(produced_item)
|
||||||
|
|
||||||
|
func can_send_item(item: Item) -> bool:
|
||||||
|
if !enabled:
|
||||||
|
return false
|
||||||
|
for consumer in consumers:
|
||||||
|
if consumer.can_accept_item(item):
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
func send_item(item: Item) -> bool:
|
func send_item(item: Item) -> bool:
|
||||||
|
if !enabled:
|
||||||
|
return false
|
||||||
if consumers.is_empty():
|
if consumers.is_empty():
|
||||||
return false
|
return false
|
||||||
next_consumer_idx += 1
|
var start_idx: int = last_consumer_idx
|
||||||
if next_consumer_idx >= consumers.size():
|
var first_try: bool = true
|
||||||
next_consumer_idx = 0
|
var idx: int = start_idx
|
||||||
|
while idx != start_idx or first_try:
|
||||||
|
idx += 1
|
||||||
|
if idx >= consumers.size():
|
||||||
|
idx = 0
|
||||||
|
first_try = false
|
||||||
|
|
||||||
var consumer: Consumer = consumers[next_consumer_idx]
|
var consumer: Consumer = consumers[idx]
|
||||||
var accepted: bool = consumer.offer_item(item)
|
var accepted: bool = consumer.offer_item(item)
|
||||||
return accepted
|
if accepted:
|
||||||
|
last_consumer_idx = idx
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
extends Node3D
|
||||||
|
class_name BuildingManager
|
||||||
|
|
||||||
|
@export_flags_3d_physics var buildings_layer_mask: int = 0b10
|
||||||
|
var placing_building: Building = null
|
||||||
|
|
||||||
|
func start_placement(scene: PackedScene) -> void:
|
||||||
|
var object: Node = scene.instantiate()
|
||||||
|
add_child(object)
|
||||||
|
if object is Building:
|
||||||
|
placing_building = object
|
||||||
|
placing_building._start_placement()
|
||||||
|
|
||||||
|
func _input(event: InputEvent) -> void:
|
||||||
|
if placing_building == null:
|
||||||
|
return
|
||||||
|
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()
|
||||||
|
|
||||||
|
func placement_mouse_input(screen_position: Vector2, confirmed: bool) -> void:
|
||||||
|
# try to raycast to see what we clicked on/are hovering
|
||||||
|
var camera: Camera3D = get_viewport().get_camera_3d()
|
||||||
|
var ray_origin: Vector3 = camera.project_ray_origin(screen_position)
|
||||||
|
var ray_normal: Vector3 = ray_origin + camera.project_ray_normal(screen_position) * 200
|
||||||
|
var params: PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.create(ray_origin, ray_normal)
|
||||||
|
if placing_building.collision_shape != null:
|
||||||
|
params.exclude = [placing_building.get_rid()]
|
||||||
|
var result: Dictionary = get_world_3d().direct_space_state.intersect_ray(params)
|
||||||
|
|
||||||
|
var placment_feedback: int = 0
|
||||||
|
if result.has("collider") and result["collider"] is Building:
|
||||||
|
placment_feedback = placing_building._placement_select_building(result["collider"] as Building, confirmed)
|
||||||
|
elif result.has("position"):
|
||||||
|
DebugDraw3D.draw_sphere(result["position"] as Vector3)
|
||||||
|
placment_feedback = placing_building._placement_select_position(result["position"] as Vector3, confirmed)
|
||||||
|
|
||||||
|
if placment_feedback & Building.PLACEMENT_COMPLETED:
|
||||||
|
placing_building._end_placement()
|
||||||
|
placing_building = null
|
|
@ -0,0 +1 @@
|
||||||
|
uid://bxd8ftp1hcf7e
|
|
@ -0,0 +1,11 @@
|
||||||
|
@tool
|
||||||
|
extends Button
|
||||||
|
|
||||||
|
signal place_requested(scene: PackedScene)
|
||||||
|
@export var place_scene: PackedScene:
|
||||||
|
set(value):
|
||||||
|
place_scene = value
|
||||||
|
text = place_scene.get_state().get_node_name(0)
|
||||||
|
|
||||||
|
func _pressed() -> void:
|
||||||
|
place_requested.emit(place_scene)
|
|
@ -0,0 +1 @@
|
||||||
|
uid://tmyvv1p7co51
|
|
@ -1,35 +1,111 @@
|
||||||
extends Path3D
|
extends Building
|
||||||
|
|
||||||
@export var speed: float = 1.0
|
@export var speed: float = 1.0
|
||||||
@export var item_offset: Vector3 = Vector3(0,2.0,0)
|
@export var item_offset: Vector3 = Vector3(0,2.0,0)
|
||||||
@export var extra_distance_start: float = 1.0
|
@export var extra_distance_start: float = 1.0
|
||||||
@export var extra_distance_end: float = 1.0
|
@export var extra_distance_end: float = 1.0
|
||||||
|
@export var spacing: float = 1.0
|
||||||
|
|
||||||
var transported_items: Dictionary[Item, PackedFloat64Array] = {}
|
var transported_items: Dictionary[Item, PackedFloat64Array] = {}
|
||||||
|
var belt_moving: bool = true
|
||||||
|
var closest_item: float = 0.0
|
||||||
|
|
||||||
@onready var consumer: Consumer = $Consumer
|
@onready var path: Path3D = $Path3D
|
||||||
@onready var producer: Producer = $Producer
|
|
||||||
@onready var multimesh: MultiMeshInstance3D = $MultiMeshInstance3D
|
@onready var multimesh: MultiMeshInstance3D = $MultiMeshInstance3D
|
||||||
|
|
||||||
var test_timer: float = 0
|
var test_timer: float = 0
|
||||||
@onready var test_item: Item = load("res://items/metal.tres")
|
@onready var test_item: Item = load("res://items/metal.tres")
|
||||||
|
|
||||||
|
var input_building: Building = null:
|
||||||
|
set(value):
|
||||||
|
if value.producer != null:
|
||||||
|
input_building = value
|
||||||
|
input_building.producer.consumers.append(consumer)
|
||||||
|
var output_building: Building = null:
|
||||||
|
set(value):
|
||||||
|
if value.consumer != null:
|
||||||
|
output_building = value
|
||||||
|
producer.consumers.append(output_building.consumer)
|
||||||
|
|
||||||
|
var waypoints: Array[Vector3] = []
|
||||||
|
var editing_waypoint: int = 0
|
||||||
|
|
||||||
|
func _placement_select_building(building: Building, confirmed: bool) -> int:
|
||||||
|
var ret: int = 0
|
||||||
|
if input_building == null:
|
||||||
|
if building.producer != null:
|
||||||
|
ret |= PLACEMENT_POSITION_OK
|
||||||
|
if confirmed:
|
||||||
|
input_building = building
|
||||||
|
ret |= PLACEMENT_PART_ADDED
|
||||||
|
set_path_waypoint(building.global_position + Vector3(0,1,0), confirmed)
|
||||||
|
elif output_building == null and building != input_building:
|
||||||
|
if building.consumer != null:
|
||||||
|
ret |= PLACEMENT_POSITION_OK
|
||||||
|
if confirmed:
|
||||||
|
output_building = building
|
||||||
|
ret |= PLACEMENT_COMPLETED
|
||||||
|
set_path_waypoint(building.global_position + Vector3(0,1,0), confirmed)
|
||||||
|
return ret
|
||||||
|
#return super(building, confirmed)
|
||||||
|
|
||||||
|
func _placement_select_position(pos: Vector3, confirmed: bool) -> int:
|
||||||
|
var ret: int = PLACEMENT_POSITION_OK
|
||||||
|
set_path_waypoint(pos.round() + Vector3(0,1,0), confirmed)
|
||||||
|
if confirmed:
|
||||||
|
ret |= PLACEMENT_PART_ADDED
|
||||||
|
return confirmed
|
||||||
|
|
||||||
|
func set_path_waypoint(global_pos: Vector3, add: bool) -> void:
|
||||||
|
var local_pos: Vector3
|
||||||
|
if editing_waypoint == 0:
|
||||||
|
global_position = global_pos
|
||||||
|
local_pos = Vector3()
|
||||||
|
else:
|
||||||
|
local_pos = to_local(global_pos)
|
||||||
|
while waypoints.size() <= editing_waypoint:
|
||||||
|
waypoints.append(Vector3())
|
||||||
|
waypoints[editing_waypoint] = local_pos
|
||||||
|
if add:
|
||||||
|
editing_waypoint += 1
|
||||||
|
update_path_from_waypoints()
|
||||||
|
|
||||||
|
func update_path_from_waypoints() -> void:
|
||||||
|
path.curve.clear_points()
|
||||||
|
|
||||||
|
for waypoint in waypoints:
|
||||||
|
path.curve.add_point(waypoint)
|
||||||
|
# find paths between the defined points
|
||||||
|
#for i in range(1, waypoints.size()):
|
||||||
|
#var a: Vector3 = to_global(waypoints[i-1])
|
||||||
|
#var b: Vector3 = to_global(waypoints[i])
|
||||||
|
#var route: PackedVector3Array = NavigationServer3D.map_get_path(NavigationServer3D.get_maps()[0], a, b, false, 1)
|
||||||
|
#
|
||||||
|
#for point in route:
|
||||||
|
#path.curve.add_point(to_local(point + Vector3(0,1,0)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# set the path3d's points to the path points
|
||||||
|
# adjust the control points to some uniform amount
|
||||||
|
pass
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
multimesh.multimesh = multimesh.multimesh.duplicate()
|
multimesh.multimesh = multimesh.multimesh.duplicate()
|
||||||
|
path.curve = path.curve.duplicate()
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
#test_timer += delta
|
belt_moving = check_items_at_end()
|
||||||
#if test_timer >= 2.0:
|
consumer.enabled = belt_moving and (closest_item >= spacing)
|
||||||
#test_timer -= 2.0
|
|
||||||
#add_item(test_item)
|
|
||||||
|
|
||||||
var belt_moving: bool = check_items_at_end()
|
var movement: float = (delta * speed)
|
||||||
|
closest_item += movement
|
||||||
if belt_moving:
|
if belt_moving:
|
||||||
for transported_item_type in transported_items.keys():
|
for transported_item_type: Item in transported_items.keys():
|
||||||
var offsets: PackedFloat64Array = transported_items[transported_item_type]
|
var offsets: PackedFloat64Array = transported_items[transported_item_type]
|
||||||
multimesh.multimesh.instance_count = offsets.size()
|
multimesh.multimesh.instance_count = offsets.size()
|
||||||
for i in range(offsets.size()):
|
for i in range(offsets.size()):
|
||||||
offsets[i] += (delta * speed)
|
offsets[i] += movement
|
||||||
position_item(i, transported_item_type, offsets[i])
|
position_item(i, transported_item_type, offsets[i])
|
||||||
|
|
||||||
func consumer_has_item(item: Item) -> void:
|
func consumer_has_item(item: Item) -> void:
|
||||||
|
@ -47,45 +123,47 @@ func add_item(item: Item) -> void:
|
||||||
offsets = []
|
offsets = []
|
||||||
offsets.append(get_start_offset())
|
offsets.append(get_start_offset())
|
||||||
transported_items[item] = offsets
|
transported_items[item] = offsets
|
||||||
|
|
||||||
|
closest_item = 0.0
|
||||||
|
|
||||||
func check_items_at_end() -> bool:
|
func check_items_at_end() -> bool:
|
||||||
var length: float = get_end_offset()
|
var length: float = get_end_offset()
|
||||||
var belt_moving: bool = true
|
var ret: bool = true
|
||||||
for transported_item_type in transported_items.keys():
|
for transported_item_type: Item in transported_items.keys():
|
||||||
var offsets: PackedFloat64Array = transported_items[transported_item_type]
|
var offsets: PackedFloat64Array = transported_items[transported_item_type]
|
||||||
var to_delete: Array[int] = []
|
var to_delete: Array[int] = []
|
||||||
for i in range(offsets.size()):
|
for i in range(offsets.size()):
|
||||||
if offsets[i] >= length:
|
if offsets[i] >= length:
|
||||||
var sent: bool = producer.send_item(transported_item_type)
|
var sent: bool = producer.send_item(transported_item_type)
|
||||||
if !sent:
|
if !sent:
|
||||||
belt_moving = false
|
ret = false
|
||||||
else:
|
else:
|
||||||
to_delete.append(i)
|
to_delete.append(i)
|
||||||
for d in to_delete:
|
for d in to_delete:
|
||||||
offsets.remove_at(d)
|
offsets.remove_at(d)
|
||||||
return belt_moving
|
return ret
|
||||||
|
|
||||||
func get_start_offset() -> float:
|
func get_start_offset() -> float:
|
||||||
return -extra_distance_start
|
return -extra_distance_start
|
||||||
|
|
||||||
func get_end_offset() -> float:
|
func get_end_offset() -> float:
|
||||||
return curve.get_baked_length() + extra_distance_end
|
return path.curve.get_baked_length() + extra_distance_end
|
||||||
|
|
||||||
func position_item(instance: int, item: Item, offset: float) -> void:
|
func position_item(instance: int, _item: Item, offset: float) -> void:
|
||||||
var trans: Transform3D
|
var trans: Transform3D
|
||||||
trans = sample_curve_with_extrapolation(offset).translated_local(item_offset)
|
trans = sample_curve_with_extrapolation(offset).translated_local(item_offset)
|
||||||
multimesh.multimesh.set_instance_transform(instance, trans)
|
multimesh.multimesh.set_instance_transform(instance, trans)
|
||||||
|
|
||||||
func sample_curve_with_extrapolation(offset: float) -> Transform3D:
|
func sample_curve_with_extrapolation(offset: float) -> Transform3D:
|
||||||
var end_offset: float = curve.get_baked_length()
|
var end_offset: float = path.curve.get_baked_length()
|
||||||
if offset <= 0:
|
if offset <= 0:
|
||||||
var zero: Transform3D = curve.sample_baked_with_rotation(0)
|
var zero: Transform3D = path.curve.sample_baked_with_rotation(0)
|
||||||
var almost_zero: Transform3D = curve.sample_baked_with_rotation(0.1)
|
var almost_zero: Transform3D = path.curve.sample_baked_with_rotation(0.1)
|
||||||
return almost_zero.interpolate_with(zero, (0.1-offset) * 10)
|
return almost_zero.interpolate_with(zero, (0.1-offset) * 10)
|
||||||
elif offset > end_offset:
|
elif offset > end_offset:
|
||||||
var end: Transform3D = curve.sample_baked_with_rotation(end_offset)
|
var end: Transform3D = path.curve.sample_baked_with_rotation(end_offset)
|
||||||
var almost_end: Transform3D = curve.sample_baked_with_rotation(end_offset-0.1)
|
var almost_end: Transform3D = path.curve.sample_baked_with_rotation(end_offset-0.1)
|
||||||
return almost_end.interpolate_with(end, (offset - (end_offset - 0.1)) * 10)
|
return almost_end.interpolate_with(end, (offset - (end_offset - 0.1)) * 10)
|
||||||
else:
|
else:
|
||||||
return curve.sample_baked_with_rotation(offset)
|
return path.curve.sample_baked_with_rotation(offset)
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
extends Building
|
extends Building
|
||||||
|
|
||||||
@export var mined_item: Item = preload("res://items/metal.tres")
|
#@export var mined_item: Item = preload("res://items/metal.tres")
|
||||||
@export var mine_period: float = 1.0
|
@export var mine_period: float = 1.0
|
||||||
|
|
||||||
@onready var producer: Producer = $Producer
|
|
||||||
var mine_timer: float = 0.0
|
var mine_timer: float = 0.0
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
|
super(delta)
|
||||||
mine_timer += delta
|
mine_timer += delta
|
||||||
if mine_timer >= mine_period:
|
if mine_timer >= mine_period:
|
||||||
mine_timer -= mine_period
|
mine_timer -= mine_period
|
||||||
mine()
|
mine()
|
||||||
|
|
||||||
func mine() -> void:
|
func mine() -> void:
|
||||||
producer.send_item(mined_item)
|
producer.produce()
|
||||||
|
|
|
@ -2,15 +2,14 @@ extends Building
|
||||||
|
|
||||||
@export var ingredients: Dictionary[Item, int] = {}
|
@export var ingredients: Dictionary[Item, int] = {}
|
||||||
@export var process_time: float = 1.0
|
@export var process_time: float = 1.0
|
||||||
@export var created_item: Item
|
#@export var created_item: Item
|
||||||
|
|
||||||
var process_timer: float = 0.0
|
var process_timer: float = 0.0
|
||||||
var processing: bool = false
|
var processing: bool = false
|
||||||
@onready var consumer: Consumer = $Consumer
|
|
||||||
@onready var producer: Producer = $Producer
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
if is_functional():
|
super(delta)
|
||||||
|
if is_functional() and producer.can_produce():
|
||||||
if !processing:
|
if !processing:
|
||||||
processing = consume_ingredients()
|
processing = consume_ingredients()
|
||||||
if processing:
|
if processing:
|
||||||
|
@ -24,4 +23,4 @@ func consume_ingredients() -> bool:
|
||||||
return consumer.take_items_from_storage(ingredients)
|
return consumer.take_items_from_storage(ingredients)
|
||||||
|
|
||||||
func produce_item() -> void:
|
func produce_item() -> void:
|
||||||
producer.send_item(created_item)
|
producer.produce()
|
||||||
|
|
|
@ -8,7 +8,6 @@ extends Building
|
||||||
@export var shot_impulse: float = 100
|
@export var shot_impulse: float = 100
|
||||||
@export var lead_shot_factor: float = 0.01
|
@export var lead_shot_factor: float = 0.01
|
||||||
|
|
||||||
@onready var consumer: Consumer = $Consumer
|
|
||||||
enum LoadState {UNLOADED, RELOADING, LOADED}
|
enum LoadState {UNLOADED, RELOADING, LOADED}
|
||||||
|
|
||||||
@onready var ammo: int = 0
|
@onready var ammo: int = 0
|
||||||
|
@ -17,10 +16,11 @@ var cooldown_timer: float = 0.0
|
||||||
var reload_timer: float = 0.0
|
var reload_timer: float = 0.0
|
||||||
var current_target: Enemy = null
|
var current_target: Enemy = null
|
||||||
|
|
||||||
func _on_consumer_item_added(item: Item) -> void:
|
func _on_consumer_item_added(_item: Item) -> void:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
|
super(delta)
|
||||||
if loaded == LoadState.UNLOADED:
|
if loaded == LoadState.UNLOADED:
|
||||||
if consumer.take_any_item_from_storage():
|
if consumer.take_any_item_from_storage():
|
||||||
#Engine.time_scale = 1.0
|
#Engine.time_scale = 1.0
|
||||||
|
@ -47,25 +47,24 @@ func check_target_status() -> void:
|
||||||
func search_for_enemy() -> void:
|
func search_for_enemy() -> void:
|
||||||
var enemies: Array[Node] = get_tree().get_nodes_in_group("Enemies")
|
var enemies: Array[Node] = get_tree().get_nodes_in_group("Enemies")
|
||||||
var closest: float = 9999999999
|
var closest: float = 9999999999
|
||||||
for enemy in enemies:
|
for enemy: Enemy in enemies:
|
||||||
if enemy is Enemy:
|
if !enemy.sighted:
|
||||||
if !enemy.sighted:
|
continue
|
||||||
continue
|
var distance_sqr = global_position.distance_squared_to(enemy.global_position)
|
||||||
var distance_sqr = global_position.distance_squared_to(enemy.global_position)
|
if distance_sqr <= closest:
|
||||||
if distance_sqr <= closest:
|
var params: PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.new()
|
||||||
var params: PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.new()
|
params.collision_mask = 0b00101
|
||||||
params.collision_mask = 0b00101
|
params.from = to_global(fire_position)
|
||||||
params.from = to_global(fire_position)
|
params.to = enemy.global_position
|
||||||
params.to = enemy.global_position
|
var result: Dictionary = get_world_3d().direct_space_state.intersect_ray(params)
|
||||||
var result: Dictionary = get_world_3d().direct_space_state.intersect_ray(params)
|
#DebugDraw3D.draw_line_hit(params.from, params.to, result["position"] if result.has("position") else Vector3(), result.has("position"), 0.25, Color.YELLOW, Color.BLACK, 1.0)
|
||||||
#DebugDraw3D.draw_line_hit(params.from, params.to, result["position"] if result.has("position") else Vector3(), result.has("position"), 0.25, Color.YELLOW, Color.BLACK, 1.0)
|
if result.has("collider"):
|
||||||
if result.has("collider"):
|
if !result["collider"] is PhysicsBody3D:
|
||||||
if !result["collider"] is PhysicsBody3D:
|
continue
|
||||||
continue
|
var body: PhysicsBody3D = result["collider"]
|
||||||
var body: PhysicsBody3D = result["collider"]
|
if body is Enemy:
|
||||||
if body is Enemy:
|
current_target = body
|
||||||
current_target = body
|
closest = body.global_position.distance_squared_to(global_position)
|
||||||
closest = body.global_position.distance_squared_to(global_position)
|
|
||||||
|
|
||||||
func fire_at_target() -> void:
|
func fire_at_target() -> void:
|
||||||
#Engine.time_scale = 0.1
|
#Engine.time_scale = 0.1
|
||||||
|
@ -74,8 +73,8 @@ func fire_at_target() -> void:
|
||||||
bullet.global_position = to_global(fire_position)
|
bullet.global_position = to_global(fire_position)
|
||||||
|
|
||||||
var aim_target: Vector3 = current_target.global_position
|
var aim_target: Vector3 = current_target.global_position
|
||||||
var range: float = global_position.distance_to(current_target.global_position)
|
var target_range: float = global_position.distance_to(current_target.global_position)
|
||||||
aim_target += current_target.linear_velocity * lead_shot_factor * range
|
aim_target += current_target.linear_velocity * lead_shot_factor * target_range
|
||||||
DebugDraw3D.draw_sphere(aim_target, 0.25, Color.RED, 0.1)
|
DebugDraw3D.draw_sphere(aim_target, 0.25, Color.RED, 0.1)
|
||||||
|
|
||||||
bullet.look_at(aim_target)
|
bullet.look_at(aim_target)
|
||||||
|
|
|
@ -10,7 +10,7 @@ func _on_body_entered(body: Node) -> void:
|
||||||
var speed: float = linear_velocity.length()
|
var speed: float = linear_velocity.length()
|
||||||
var damage: float = speed * damage_per_speed
|
var damage: float = speed * damage_per_speed
|
||||||
if damage >= min_damage:
|
if damage >= min_damage:
|
||||||
body.hurt(damage)
|
(body as Unit).hurt(damage)
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
lifetime -= delta
|
lifetime -= delta
|
||||||
|
|
|
@ -1,40 +1,50 @@
|
||||||
extends Camera3D
|
extends Camera3D
|
||||||
|
class_name GameCamera
|
||||||
|
|
||||||
|
@export var keyboard_movement_speed: float = 10
|
||||||
|
@export var maximum_movement_speed: float = 30
|
||||||
|
@export var mouse_orbit_sensitivity: float = 0.003
|
||||||
|
@export var zoom_sensitivity: float = 0.1
|
||||||
|
@export var focus_follows_terrain: bool = true
|
||||||
|
|
||||||
@export var pan_speed: float = 10
|
|
||||||
var focus_offset: Vector3 = Vector3(10, 10, 10)
|
var focus_offset: Vector3 = Vector3(10, 10, 10)
|
||||||
var focus_object: Node3D = null
|
var focus_object: Node3D = null
|
||||||
var focus_position: Vector3
|
var focus_position: Vector3
|
||||||
|
var mouse_movement: Vector2
|
||||||
var last_mouse_position: Vector2
|
var mouse_wheel_delta: int = 0
|
||||||
|
|
||||||
@onready var focus_marker: Node3D = $"Camera Focus"
|
@onready var focus_marker: Node3D = $"Camera Focus"
|
||||||
|
@onready var viewport: Viewport = get_viewport()
|
||||||
|
|
||||||
func _physics_process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
var mouse_position: Vector2 = get_viewport().get_mouse_position()
|
if Input.is_action_just_released("camera_set_target"):
|
||||||
var ray_origin: Vector3 = project_ray_origin(mouse_position)
|
var mouse_position: Vector2 = get_viewport().get_mouse_position()
|
||||||
var ray_normal: Vector3 = ray_origin + project_ray_normal(mouse_position) * 200
|
var ray_origin: Vector3 = project_ray_origin(mouse_position)
|
||||||
var params = PhysicsRayQueryParameters3D.create(ray_origin, ray_normal)
|
var ray_normal: Vector3 = ray_origin + project_ray_normal(mouse_position) * 200
|
||||||
var result: Dictionary = get_world_3d().direct_space_state.intersect_ray(params)
|
var params: PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.create(ray_origin, ray_normal)
|
||||||
if result.has("position"):
|
var result: Dictionary = get_world_3d().direct_space_state.intersect_ray(params)
|
||||||
DebugDraw3D.draw_sphere(result["position"], 0.5, Color.REBECCA_PURPLE)
|
if result.has("position"):
|
||||||
if Input.is_action_just_released("camera_set_target"):
|
#DebugDraw3D.draw_sphere(result["position"], 0.5, Color.REBECCA_PURPLE)
|
||||||
if result.has("collider") and !(result["collider"] is GridMap):
|
if result.has("collider") and !(result["collider"] is GridMap):
|
||||||
focus_object = result["collider"]
|
focus_object = result["collider"]
|
||||||
else:
|
else:
|
||||||
focus_object = null
|
focus_object = null
|
||||||
focus_position = result["position"]
|
focus_position = result["position"]
|
||||||
|
|
||||||
if focus_object != null:
|
if focus_object != null:
|
||||||
focus_position = focus_object.global_position
|
focus_position = focus_object.global_position
|
||||||
|
|
||||||
process_focus_movement(delta)
|
process_focus_movement(delta)
|
||||||
process_camera_rotation(delta)
|
process_camera_rotation(delta)
|
||||||
|
process_camera_zoom(delta)
|
||||||
|
|
||||||
var target_position: Vector3 = focus_position + focus_offset
|
var target_position: Vector3 = focus_position + focus_offset
|
||||||
if target_position.distance_squared_to(global_position) > 0:
|
if target_position.distance_squared_to(global_position) > 0:
|
||||||
global_position = global_position.move_toward(target_position, 30*(1/60.0))
|
global_position = global_position.move_toward(target_position, maximum_movement_speed*delta)
|
||||||
else:
|
#else:
|
||||||
look_at(focus_position)
|
|
||||||
|
basis = basis.slerp(Basis.looking_at(focus_position - target_position), 0.05)
|
||||||
|
|
||||||
#global_position = global_position.lerp(target_position, 0.05)
|
#global_position = global_position.lerp(target_position, 0.05)
|
||||||
|
|
||||||
#basis = basis.slerp(Basis.looking_at(focus_position - global_position), 0.05)
|
#basis = basis.slerp(Basis.looking_at(focus_position - global_position), 0.05)
|
||||||
|
@ -58,29 +68,46 @@ func process_focus_movement(delta: float) -> void:
|
||||||
focus_object = null
|
focus_object = null
|
||||||
input = input_basis * input
|
input = input_basis * input
|
||||||
|
|
||||||
var movement: Vector3 = input * pan_speed * delta
|
var movement: Vector3 = input * keyboard_movement_speed * delta
|
||||||
global_position += movement
|
global_position += movement
|
||||||
focus_position += movement
|
focus_position += movement
|
||||||
|
|
||||||
# handle moving on/off ramps
|
# handle moving on/off ramps
|
||||||
var params: PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.new()
|
if focus_follows_terrain:
|
||||||
params.from = focus_position + Vector3(0,2,0)
|
var params: PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.new()
|
||||||
params.to = focus_position - Vector3(0,2,0)
|
params.from = focus_position + Vector3(0,2,0)
|
||||||
var result: Dictionary = get_world_3d().direct_space_state.intersect_ray(params)
|
params.to = focus_position - Vector3(0,2,0)
|
||||||
if result.has("position"):
|
params.collision_mask = 1
|
||||||
focus_position = result["position"]
|
var result: Dictionary = get_world_3d().direct_space_state.intersect_ray(params)
|
||||||
|
if result.has("position"):
|
||||||
|
focus_position = result["position"]
|
||||||
DebugDraw3D.draw_gizmo(Transform3D(input_basis, focus_position))
|
|
||||||
|
|
||||||
func process_camera_rotation(delta: float) -> void:
|
func process_camera_rotation(delta: float) -> void:
|
||||||
var mouse_position: Vector2 = get_viewport().get_mouse_position()
|
#var mouse_position: Vector2 = viewport.get_mouse_position()
|
||||||
var mouse_movement: Vector2 = mouse_position - last_mouse_position
|
#var mouse_position: Vector2 = Vector2()
|
||||||
last_mouse_position = mouse_position
|
#var mouse_movement: Vector2 = (mouse_position - last_mouse_position) * delta
|
||||||
|
#last_mouse_position = mouse_position
|
||||||
if Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT):
|
if Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT):
|
||||||
|
focus_offset = focus_offset.rotated(Vector3.UP, -mouse_movement.x * mouse_orbit_sensitivity)
|
||||||
focus_offset = focus_offset.rotated(Vector3.UP, -mouse_movement.x * 0.006)
|
|
||||||
var vertical_axis: Vector3 = focus_offset.cross(Vector3.UP).normalized()
|
var vertical_axis: Vector3 = focus_offset.cross(Vector3.UP).normalized()
|
||||||
focus_offset = focus_offset.rotated(vertical_axis, mouse_movement.y * 0.006)
|
focus_offset = focus_offset.rotated(vertical_axis, mouse_movement.y * mouse_orbit_sensitivity)
|
||||||
global_position = focus_position + focus_offset
|
global_position = focus_position + focus_offset
|
||||||
look_at(focus_position)
|
look_at(focus_position)
|
||||||
|
mouse_movement = Vector2()
|
||||||
|
|
||||||
|
func process_camera_zoom(_delta: float) -> void:
|
||||||
|
#var wheel_input: float = Input.get_axis("camera_zoom_in", "camera_zoom_out")
|
||||||
|
var change: float = 1.0 + (-mouse_wheel_delta * zoom_sensitivity)
|
||||||
|
focus_offset *= change
|
||||||
|
mouse_wheel_delta = 0
|
||||||
|
|
||||||
|
func _input(event: InputEvent) -> void:
|
||||||
|
if event is InputEventMouseButton:
|
||||||
|
var button_event: InputEventMouseButton = event
|
||||||
|
if button_event.button_index == MOUSE_BUTTON_WHEEL_UP:
|
||||||
|
mouse_wheel_delta += 1
|
||||||
|
elif button_event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
|
||||||
|
mouse_wheel_delta -= 1
|
||||||
|
elif event is InputEventMouseMotion:
|
||||||
|
var motion_event: InputEventMouseMotion = event
|
||||||
|
mouse_movement += motion_event.relative
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
@tool
|
||||||
|
extends GridMap
|
||||||
|
class_name CustomGridMap
|
||||||
|
|
||||||
|
@export var travel_costs: Dictionary[String, float]
|
||||||
|
|
||||||
|
func _enter_tree() -> void:
|
||||||
|
mesh_library.changed.connect(update_dicts)
|
||||||
|
|
||||||
|
func update_dicts() -> void:
|
||||||
|
var keys: Array[String] = []
|
||||||
|
mesh_library.get_item_list()
|
|
@ -0,0 +1 @@
|
||||||
|
uid://b61ea0hhhekmp
|
|
@ -0,0 +1,4 @@
|
||||||
|
extends Label
|
||||||
|
|
||||||
|
func _process(_delta: float) -> void:
|
||||||
|
text = "FPS: %d" % [Engine.get_frames_per_second()]
|
|
@ -0,0 +1 @@
|
||||||
|
uid://vcf7wcmyewl8
|
|
@ -1,20 +1,23 @@
|
||||||
extends Node3D
|
extends Node3D
|
||||||
|
class_name NavObstable
|
||||||
|
|
||||||
|
@export var enabled: bool = false:
|
||||||
|
set(val):
|
||||||
|
if val != enabled:
|
||||||
|
enabled = val
|
||||||
|
update(enabled)
|
||||||
@export var aabb: AABB = AABB(Vector3(-1,0,-1),Vector3(2,2,2))
|
@export var aabb: AABB = AABB(Vector3(-1,0,-1),Vector3(2,2,2))
|
||||||
@export var weight: float = 10.0
|
@export var weight: float = 10.0
|
||||||
@export var make_solid: bool = true
|
@export var make_solid: bool = false
|
||||||
|
|
||||||
var enable_timer: float = 1.0
|
var updated_regions: Array[RID] = []
|
||||||
var enabled: bool = false
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _exit_tree() -> void:
|
||||||
if enable_timer > 0:
|
update(false)
|
||||||
enable_timer -= delta
|
|
||||||
if !enabled and enable_timer <= 0:
|
|
||||||
enabled = true
|
|
||||||
update()
|
|
||||||
|
|
||||||
func update() -> void:
|
func update(enable: bool) -> void:
|
||||||
|
if !is_node_ready():
|
||||||
|
await ready
|
||||||
var global_aabb: AABB = global_transform * aabb
|
var global_aabb: AABB = global_transform * aabb
|
||||||
#DebugDraw3D.draw_aabb(global_aabb, Color.DARK_CYAN, 5)
|
#DebugDraw3D.draw_aabb(global_aabb, Color.DARK_CYAN, 5)
|
||||||
for map_rid in NavigationServer3D.get_maps():
|
for map_rid in NavigationServer3D.get_maps():
|
||||||
|
@ -22,6 +25,9 @@ func update() -> void:
|
||||||
var region_aabb: AABB = NavigationServer3D.region_get_bounds(region_rid).grow(0.1)
|
var region_aabb: AABB = NavigationServer3D.region_get_bounds(region_rid).grow(0.1)
|
||||||
#DebugDraw3D.draw_aabb(region_aabb, Color.YELLOW, 5)
|
#DebugDraw3D.draw_aabb(region_aabb, Color.YELLOW, 5)
|
||||||
if global_aabb.intersects(region_aabb):
|
if global_aabb.intersects(region_aabb):
|
||||||
NavigationServer3D.region_set_travel_cost(region_rid, weight)
|
var old_weight: float = NavigationServer3D.region_get_travel_cost(region_rid)
|
||||||
#NavigationServer3D.region_set_enabled(region_rid, false)
|
var new_weight: float = (old_weight * weight) if enable else (old_weight / weight)
|
||||||
DebugDraw3D.draw_aabb(region_aabb, Color.RED, 5)
|
NavigationServer3D.region_set_travel_cost(region_rid, new_weight)
|
||||||
|
if make_solid:
|
||||||
|
NavigationServer3D.region_set_enabled(region_rid, enable)
|
||||||
|
DebugDraw3D.draw_aabb(region_aabb, Color.RED if enable else Color.GREEN, 5)
|
||||||
|
|
|
@ -12,4 +12,4 @@ func _process(delta: float) -> void:
|
||||||
var node: Node = spawn_scene.instantiate()
|
var node: Node = spawn_scene.instantiate()
|
||||||
add_child(node)
|
add_child(node)
|
||||||
if node is Node3D:
|
if node is Node3D:
|
||||||
node.global_position = global_position
|
(node as Node3D).global_position = global_position
|
||||||
|
|
|
@ -16,8 +16,12 @@ var stuck_timer: float = 0.0
|
||||||
var move_target: Vector3 = Vector3(16, 1, 13)
|
var move_target: Vector3 = Vector3(16, 1, 13)
|
||||||
var move_radius: float = 5.0
|
var move_radius: float = 5.0
|
||||||
|
|
||||||
|
@onready var shapecast_3d: ShapeCast3D = $ShapeCast3D
|
||||||
|
@onready var nav_agent_3d: NavigationAgent3D = $NavigationAgent3D
|
||||||
|
@onready var label_3d: Label3D = $Label3D
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
$NavigationAgent3D.connect("velocity_computed", avoidance_velocity_computed)
|
nav_agent_3d.connect("velocity_computed", avoidance_velocity_computed)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
func avoidance_velocity_computed(velocity: Vector3) -> void:
|
func avoidance_velocity_computed(velocity: Vector3) -> void:
|
||||||
|
@ -26,17 +30,17 @@ func avoidance_velocity_computed(velocity: Vector3) -> void:
|
||||||
avoidance_timeout = 0.5
|
avoidance_timeout = 0.5
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _process(delta: float) -> void:
|
||||||
$Label3D.text = "HP: %d" % hp
|
label_3d.text = "HP: %d" % hp
|
||||||
|
|
||||||
if $NavigationAgent3D.is_target_reached() \
|
if nav_agent_3d.is_target_reached() \
|
||||||
or $NavigationAgent3D.target_position.is_zero_approx() \
|
or nav_agent_3d.target_position.is_zero_approx() \
|
||||||
or !$NavigationAgent3D.is_target_reachable():
|
or !nav_agent_3d.is_target_reachable():
|
||||||
$NavigationAgent3D.target_position = move_target + Vector3(randfn(0, move_radius), 0, randfn(0, move_radius))
|
nav_agent_3d.target_position = move_target + Vector3(randfn(0, move_radius), 0, randfn(0, move_radius))
|
||||||
#$NavigationAgent3D.target_position = NavigationServer3D.map_get_random_point(NavigationServer3D.get_maps()[0], 1, true)
|
#nav_agent_3d.target_position = NavigationServer3D.map_get_random_point(NavigationServer3D.get_maps()[0], 1, true)
|
||||||
last_distance_to_target = $NavigationAgent3D.distance_to_target()
|
last_distance_to_target = nav_agent_3d.distance_to_target()
|
||||||
else:
|
else:
|
||||||
if $ShapeCast3D.is_colliding():
|
if shapecast_3d.is_colliding():
|
||||||
var distance_to_target: float = $NavigationAgent3D.distance_to_target()
|
var distance_to_target: float = nav_agent_3d.distance_to_target()
|
||||||
var progress_rate: float = (last_distance_to_target - distance_to_target) / delta
|
var progress_rate: float = (last_distance_to_target - distance_to_target) / delta
|
||||||
last_distance_to_target = distance_to_target
|
last_distance_to_target = distance_to_target
|
||||||
if progress_rate < minimum_progress_rate:
|
if progress_rate < minimum_progress_rate:
|
||||||
|
@ -44,24 +48,24 @@ func _process(delta: float) -> void:
|
||||||
if stuck_timer >= stuck_time:
|
if stuck_timer >= stuck_time:
|
||||||
unstuck()
|
unstuck()
|
||||||
else:
|
else:
|
||||||
$Label3D.modulate = Color.WHITE
|
label_3d.modulate = Color.WHITE
|
||||||
stuck_timer = 0
|
stuck_timer = 0
|
||||||
if global_position.y <= -10:
|
if global_position.y <= -10:
|
||||||
unstuck()
|
unstuck()
|
||||||
#DebugDraw3D.draw_sphere($NavigationAgent3D.target_position, 0.5, Color.RED)
|
#DebugDraw3D.draw_sphere(nav_agent_3d.target_position, 0.5, Color.RED)
|
||||||
var next_point: Vector3 = $NavigationAgent3D.get_next_path_position()
|
var next_point: Vector3 = nav_agent_3d.get_next_path_position()
|
||||||
#DebugDraw3D.draw_sphere(next_point, 0.1, Color.YELLOW)
|
#DebugDraw3D.draw_sphere(next_point, 0.1, Color.YELLOW)
|
||||||
var direction: Vector3 = (next_point - global_position).normalized()
|
var direction: Vector3 = (next_point - global_position).normalized()
|
||||||
#DebugDraw3D.draw_line(global_position, global_position + linear_velocity, Color.BLUE)
|
#DebugDraw3D.draw_line(global_position, global_position + linear_velocity, Color.BLUE)
|
||||||
target_velocity = direction * max_speed
|
target_velocity = direction * max_speed
|
||||||
$NavigationAgent3D.velocity = target_velocity
|
nav_agent_3d.velocity = target_velocity
|
||||||
#DebugDraw3D.draw_line(global_position, global_position + target_velocity, Color.MAGENTA)
|
#DebugDraw3D.draw_line(global_position, global_position + target_velocity, Color.MAGENTA)
|
||||||
#DebugDraw3D.draw_text(global_position + Vector3(0,1,0), "%f" % $NavigationAgent3D.distance_to_target())
|
#DebugDraw3D.draw_text(global_position + Vector3(0,1,0), "%f" % nav_agent_3d.distance_to_target())
|
||||||
|
|
||||||
func unstuck() -> void:
|
func unstuck() -> void:
|
||||||
# teleport to next path point
|
# teleport to next path point
|
||||||
linear_velocity = Vector3()
|
linear_velocity = Vector3()
|
||||||
global_position = $NavigationAgent3D.get_next_path_position()
|
global_position = nav_agent_3d.get_next_path_position()
|
||||||
stuck_timer = 0
|
stuck_timer = 0
|
||||||
|
|
||||||
func hurt(damage: float) -> void:
|
func hurt(damage: float) -> void:
|
||||||
|
@ -74,14 +78,14 @@ func die() -> void:
|
||||||
queue_free()
|
queue_free()
|
||||||
|
|
||||||
func _physics_process(delta: float) -> void:
|
func _physics_process(delta: float) -> void:
|
||||||
if $ShapeCast3D.is_colliding():
|
if shapecast_3d.is_colliding():
|
||||||
var actual_target_velocity: Vector3 = target_velocity
|
var actual_target_velocity: Vector3 = target_velocity
|
||||||
if avoidance_timeout > 0:
|
if avoidance_timeout > 0:
|
||||||
avoidance_timeout -= delta
|
avoidance_timeout -= delta
|
||||||
actual_target_velocity = actual_target_velocity.slerp(avoidance_velocity, 0.25)
|
actual_target_velocity = actual_target_velocity.slerp(avoidance_velocity, 0.25)
|
||||||
#DebugDraw3D.draw_line(global_position, global_position + actual_target_velocity, Color.ORANGE)
|
#DebugDraw3D.draw_line(global_position, global_position + actual_target_velocity, Color.ORANGE)
|
||||||
var force_direction: Vector3 = (actual_target_velocity-linear_velocity)
|
var force_direction: Vector3 = (actual_target_velocity-linear_velocity)
|
||||||
var normal: Vector3 = $ShapeCast3D.get_collision_normal(0)
|
var normal: Vector3 = shapecast_3d.get_collision_normal(0)
|
||||||
#DebugDraw3D.draw_line(global_position, global_position + normal, Color.DODGER_BLUE)
|
#DebugDraw3D.draw_line(global_position, global_position + normal, Color.DODGER_BLUE)
|
||||||
var force: Vector3 = (force_direction * movement_force).slide(normal)
|
var force: Vector3 = (force_direction * movement_force).slide(normal)
|
||||||
#DebugDraw3D.draw_line(global_position, global_position + force, Color.GREEN)
|
#DebugDraw3D.draw_line(global_position, global_position + force, Color.GREEN)
|
||||||
|
|
Loading…
Reference in New Issue