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
|
||||
*.dylib 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": {
|
||||
"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": [
|
||||
"res://items/"
|
||||
"res://items/",
|
||||
"res://objects/buildings/"
|
||||
],
|
||||
"table_functions": {
|
||||
"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
|
||||
|
||||
|
|
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="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
||||
shape = SubResource("BoxShape3D_k07no")
|
||||
disabled = true
|
||||
|
||||
[node name="NavObstacle" type="Node3D" parent="."]
|
||||
script = ExtResource("2_0gk2u")
|
||||
make_solid = false
|
||||
enabled = true
|
||||
|
||||
[node name="NavigationObstacle3D" type="NavigationObstacle3D" parent="."]
|
||||
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)
|
||||
visible = false
|
||||
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="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="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 = {
|
||||
"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)
|
||||
}
|
||||
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"]
|
||||
transform_format = 1
|
||||
instance_count = 1
|
||||
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)
|
||||
|
||||
[node name="Conveyor" type="Path3D"]
|
||||
curve = SubResource("Curve3D_r3fl7")
|
||||
[node name="Conveyor" type="Node3D"]
|
||||
script = ExtResource("1_m8ga5")
|
||||
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")
|
||||
path_3d = NodePath("..")
|
||||
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/tilt = true
|
||||
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="."]
|
||||
script = ExtResource("3_vjqud")
|
||||
storage_size = 1
|
||||
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")
|
||||
consumers = [null]
|
||||
metadata/_custom_type_script = "uid://c4fquatkjmsgu"
|
||||
|
||||
[node name="MultiMeshInstance3D" type="MultiMeshInstance3D" parent="."]
|
||||
physics_interpolation_mode = 2
|
||||
visibility_range_end = 50.0
|
||||
visibility_range_end_margin = 50.0
|
||||
visibility_range_fade_mode = 1
|
||||
multimesh = SubResource("MultiMesh_6iypd")
|
||||
|
||||
[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="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="Resource" uid="uid://dbkxys3mr5u80" path="res://items/metal.tres" id="3_8y6s2"]
|
||||
[ext_resource type="PackedScene" uid="uid://dx13fyjv0d8st" path="res://assets/blends/Miner.blend" id="2_la0h1"]
|
||||
[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")
|
||||
mined_item = ExtResource("3_8y6s2")
|
||||
mine_period = 1.0
|
||||
can_stack = false
|
||||
|
||||
[node name="MeshInstance3D" parent="." index="0"]
|
||||
visible = false
|
||||
|
@ -18,4 +18,5 @@ visible = false
|
|||
|
||||
[node name="Producer" type="Node" parent="." index="6"]
|
||||
script = ExtResource("5_65oni")
|
||||
produced_item = ExtResource("3_k13eg")
|
||||
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="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="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="Resource" uid="uid://dxlb2ixt3fx7l" path="res://items/ore.tres" id="7_dx8de"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_evfwj"]
|
||||
albedo_color = Color(0.023159, 1, 0, 1)
|
||||
|
@ -18,18 +18,19 @@ size = Vector3(2, 2, 2)
|
|||
[node name="Processor" instance=ExtResource("1_hxugg")]
|
||||
script = ExtResource("2_evfwj")
|
||||
ingredients = Dictionary[ExtResource("3_3h7kv"), int]({
|
||||
ExtResource("4_miqab"): 2
|
||||
ExtResource("7_dx8de"): 2
|
||||
})
|
||||
process_time = 1.0
|
||||
created_item = ExtResource("4_3h7kv")
|
||||
|
||||
[node name="MeshInstance3D" parent="." index="0"]
|
||||
mesh = SubResource("BoxMesh_3h7kv")
|
||||
|
||||
[node name="Consumer" type="Node" parent="." index="2"]
|
||||
script = ExtResource("4_dx8de")
|
||||
accepted_items = Array[ExtResource("3_3h7kv")]([ExtResource("7_dx8de")])
|
||||
metadata/_custom_type_script = "uid://bshiyw2k3op02"
|
||||
|
||||
[node name="Producer" type="Node" parent="." index="3"]
|
||||
script = ExtResource("5_p3dou")
|
||||
produced_item = ExtResource("4_3h7kv")
|
||||
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="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="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"]
|
||||
radius = 0.1
|
||||
|
@ -13,21 +14,12 @@ height = 0.3
|
|||
shader = ExtResource("1_ucnj8")
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_6sxjd"]
|
||||
offsets = PackedFloat32Array(0, 0.150862, 0.642241, 1)
|
||||
colors = PackedColorArray(1, 1, 1, 1, 1, 0.920817, 0, 0.849138, 0.695312, 0.044384, 0, 0.357759, 1, 1, 1, 0)
|
||||
offsets = PackedFloat32Array(0, 0.0818966, 0.965517, 1)
|
||||
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"]
|
||||
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"]
|
||||
_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
|
||||
|
@ -41,9 +33,9 @@ shader = ExtResource("2_rsjgb")
|
|||
shader_parameter/tex = SubResource("CurveTexture_rsjgb")
|
||||
shader_parameter/uv_offset = Vector2(0, 0)
|
||||
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/flags = 45
|
||||
shader_parameter/flags = 47
|
||||
|
||||
[sub_resource type="QuadMesh" id="QuadMesh_ucnj8"]
|
||||
material = SubResource("ShaderMaterial_xbcx7")
|
||||
|
@ -63,6 +55,54 @@ height = 0.3
|
|||
radial_segments = 6
|
||||
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"]
|
||||
collision_layer = 16
|
||||
collision_mask = 5
|
||||
|
@ -79,7 +119,7 @@ shape = SubResource("CapsuleShape3D_3ndsa")
|
|||
|
||||
[node name="GPUTrail3D" type="GPUParticles3D" parent="."]
|
||||
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
|
||||
lifetime = 19.0
|
||||
explosiveness = 1.0
|
||||
|
@ -91,8 +131,8 @@ length = 19
|
|||
length_seconds = 0.322034
|
||||
texture = SubResource("CurveTexture_rsjgb")
|
||||
color_ramp = SubResource("GradientTexture1D_od3fb")
|
||||
curve = SubResource("CurveTexture_7thed")
|
||||
vertical_texture = true
|
||||
use_red_as_alpha = true
|
||||
billboard = true
|
||||
_defaults_have_been_set = true
|
||||
metadata/_custom_type_script = "uid://cdubip3a6325r"
|
||||
|
@ -105,4 +145,12 @@ mesh = SubResource("CylinderMesh_xbcx7")
|
|||
[node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="."]
|
||||
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"]
|
||||
|
|
|
@ -27,7 +27,7 @@ config/name="TowerGame3D"
|
|||
run/main_scene="uid://bwftban1ppo17"
|
||||
config/features=PackedStringArray("4.4")
|
||||
config/icon="uid://u1hpdb62rxlc"
|
||||
addons/icon_finder/preview_size=24
|
||||
addons/icon_finder/preview_size=25
|
||||
|
||||
[autoload]
|
||||
|
||||
|
@ -36,6 +36,20 @@ IconsFonts="*res://addons/icons-fonts/icons_fonts/IconsFonts.gd"
|
|||
[debug]
|
||||
|
||||
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_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)
|
||||
]
|
||||
}
|
||||
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]
|
||||
|
||||
|
@ -109,6 +140,7 @@ camera_set_target={
|
|||
|
||||
3d/default_edge_connection_margin=0.6
|
||||
3d/default_link_connection_radius=0.5
|
||||
pathfinding/max_threads=-1
|
||||
|
||||
[physics]
|
||||
|
||||
|
@ -118,6 +150,3 @@ common/physics_interpolation=true
|
|||
|
||||
lights_and_shadows/directional_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
|
||||
class_name Building
|
||||
|
||||
@export_category("Defence")
|
||||
@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 {
|
||||
UNPLACED,
|
||||
BUILDING,
|
||||
|
@ -10,11 +25,88 @@ enum BuildState {
|
|||
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 stacked_buildings: Array[Building] = []
|
||||
|
||||
var build_state: BuildState = BuildState.READY:
|
||||
set(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:
|
||||
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
|
||||
signal item_added(item: Item)
|
||||
|
||||
|
@ -12,7 +12,8 @@ var storage: Dictionary[Item, int] = {}
|
|||
|
||||
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())
|
||||
and (accepted_items.has(item) or accepted_items.is_empty()) \
|
||||
and enabled
|
||||
|
||||
func offer_item(item: Item) -> bool:
|
||||
if !can_accept_item(item):
|
||||
|
@ -30,13 +31,13 @@ func check_storage_for_item(item: Item) -> bool:
|
|||
return check_storage_for_items({item:1})
|
||||
|
||||
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]:
|
||||
return false
|
||||
return true
|
||||
|
||||
func take_any_item_from_storage() -> Item:
|
||||
for item in storage.keys():
|
||||
for item: Item in storage.keys():
|
||||
if storage[item] >= 1:
|
||||
storage[item] -= 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:
|
||||
if !check_storage_for_items(items):
|
||||
return false
|
||||
for item in items.keys():
|
||||
for item: Item in items.keys():
|
||||
var old_count: int = storage.get(item, 0)
|
||||
storage.set(item, old_count - items[item])
|
||||
storage_total -= items[item]
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
extends Node
|
||||
extends BuildingPart
|
||||
class_name Producer
|
||||
|
||||
@export var produced_item: Item
|
||||
@export var output_period: float = 0.1
|
||||
@export var max_outputs: int = 1
|
||||
@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_item: Item
|
||||
|
||||
|
@ -14,16 +15,39 @@ var next_consumer_idx: int = 0
|
|||
#if output_timer >= output_period:
|
||||
#output_timer -= output_period
|
||||
#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:
|
||||
if !enabled:
|
||||
return false
|
||||
if consumers.is_empty():
|
||||
return false
|
||||
next_consumer_idx += 1
|
||||
if next_consumer_idx >= consumers.size():
|
||||
next_consumer_idx = 0
|
||||
var start_idx: int = last_consumer_idx
|
||||
var first_try: bool = true
|
||||
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 accepted: bool = consumer.offer_item(item)
|
||||
return accepted
|
||||
var consumer: Consumer = consumers[idx]
|
||||
var accepted: bool = consumer.offer_item(item)
|
||||
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 item_offset: Vector3 = Vector3(0,2.0,0)
|
||||
@export var extra_distance_start: float = 1.0
|
||||
@export var extra_distance_end: float = 1.0
|
||||
@export var spacing: float = 1.0
|
||||
|
||||
var transported_items: Dictionary[Item, PackedFloat64Array] = {}
|
||||
var belt_moving: bool = true
|
||||
var closest_item: float = 0.0
|
||||
|
||||
@onready var consumer: Consumer = $Consumer
|
||||
@onready var producer: Producer = $Producer
|
||||
@onready var path: Path3D = $Path3D
|
||||
@onready var multimesh: MultiMeshInstance3D = $MultiMeshInstance3D
|
||||
|
||||
var test_timer: float = 0
|
||||
@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:
|
||||
multimesh.multimesh = multimesh.multimesh.duplicate()
|
||||
path.curve = path.curve.duplicate()
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
#test_timer += delta
|
||||
#if test_timer >= 2.0:
|
||||
#test_timer -= 2.0
|
||||
#add_item(test_item)
|
||||
belt_moving = check_items_at_end()
|
||||
consumer.enabled = belt_moving and (closest_item >= spacing)
|
||||
|
||||
var belt_moving: bool = check_items_at_end()
|
||||
var movement: float = (delta * speed)
|
||||
closest_item += movement
|
||||
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]
|
||||
multimesh.multimesh.instance_count = offsets.size()
|
||||
for i in range(offsets.size()):
|
||||
offsets[i] += (delta * speed)
|
||||
offsets[i] += movement
|
||||
position_item(i, transported_item_type, offsets[i])
|
||||
|
||||
func consumer_has_item(item: Item) -> void:
|
||||
|
@ -48,44 +124,46 @@ func add_item(item: Item) -> void:
|
|||
offsets.append(get_start_offset())
|
||||
transported_items[item] = offsets
|
||||
|
||||
closest_item = 0.0
|
||||
|
||||
func check_items_at_end() -> bool:
|
||||
var length: float = get_end_offset()
|
||||
var belt_moving: bool = true
|
||||
for transported_item_type in transported_items.keys():
|
||||
var ret: bool = true
|
||||
for transported_item_type: Item in transported_items.keys():
|
||||
var offsets: PackedFloat64Array = transported_items[transported_item_type]
|
||||
var to_delete: Array[int] = []
|
||||
for i in range(offsets.size()):
|
||||
if offsets[i] >= length:
|
||||
var sent: bool = producer.send_item(transported_item_type)
|
||||
if !sent:
|
||||
belt_moving = false
|
||||
ret = false
|
||||
else:
|
||||
to_delete.append(i)
|
||||
for d in to_delete:
|
||||
offsets.remove_at(d)
|
||||
return belt_moving
|
||||
return ret
|
||||
|
||||
func get_start_offset() -> float:
|
||||
return -extra_distance_start
|
||||
|
||||
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
|
||||
trans = sample_curve_with_extrapolation(offset).translated_local(item_offset)
|
||||
multimesh.multimesh.set_instance_transform(instance, trans)
|
||||
|
||||
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:
|
||||
var zero: Transform3D = curve.sample_baked_with_rotation(0)
|
||||
var almost_zero: Transform3D = curve.sample_baked_with_rotation(0.1)
|
||||
var zero: Transform3D = path.curve.sample_baked_with_rotation(0)
|
||||
var almost_zero: Transform3D = path.curve.sample_baked_with_rotation(0.1)
|
||||
return almost_zero.interpolate_with(zero, (0.1-offset) * 10)
|
||||
elif offset > end_offset:
|
||||
var end: Transform3D = curve.sample_baked_with_rotation(end_offset)
|
||||
var almost_end: Transform3D = curve.sample_baked_with_rotation(end_offset-0.1)
|
||||
var end: Transform3D = path.curve.sample_baked_with_rotation(end_offset)
|
||||
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)
|
||||
else:
|
||||
return curve.sample_baked_with_rotation(offset)
|
||||
return path.curve.sample_baked_with_rotation(offset)
|
||||
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
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
|
||||
|
||||
@onready var producer: Producer = $Producer
|
||||
var mine_timer: float = 0.0
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
super(delta)
|
||||
mine_timer += delta
|
||||
if mine_timer >= mine_period:
|
||||
mine_timer -= mine_period
|
||||
mine()
|
||||
|
||||
func mine() -> void:
|
||||
producer.send_item(mined_item)
|
||||
producer.produce()
|
||||
|
|
|
@ -2,15 +2,14 @@ extends Building
|
|||
|
||||
@export var ingredients: Dictionary[Item, int] = {}
|
||||
@export var process_time: float = 1.0
|
||||
@export var created_item: Item
|
||||
#@export var created_item: Item
|
||||
|
||||
var process_timer: float = 0.0
|
||||
var processing: bool = false
|
||||
@onready var consumer: Consumer = $Consumer
|
||||
@onready var producer: Producer = $Producer
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if is_functional():
|
||||
super(delta)
|
||||
if is_functional() and producer.can_produce():
|
||||
if !processing:
|
||||
processing = consume_ingredients()
|
||||
if processing:
|
||||
|
@ -24,4 +23,4 @@ func consume_ingredients() -> bool:
|
|||
return consumer.take_items_from_storage(ingredients)
|
||||
|
||||
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 lead_shot_factor: float = 0.01
|
||||
|
||||
@onready var consumer: Consumer = $Consumer
|
||||
enum LoadState {UNLOADED, RELOADING, LOADED}
|
||||
|
||||
@onready var ammo: int = 0
|
||||
|
@ -17,10 +16,11 @@ var cooldown_timer: float = 0.0
|
|||
var reload_timer: float = 0.0
|
||||
var current_target: Enemy = null
|
||||
|
||||
func _on_consumer_item_added(item: Item) -> void:
|
||||
func _on_consumer_item_added(_item: Item) -> void:
|
||||
pass
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
super(delta)
|
||||
if loaded == LoadState.UNLOADED:
|
||||
if consumer.take_any_item_from_storage():
|
||||
#Engine.time_scale = 1.0
|
||||
|
@ -47,25 +47,24 @@ func check_target_status() -> void:
|
|||
func search_for_enemy() -> void:
|
||||
var enemies: Array[Node] = get_tree().get_nodes_in_group("Enemies")
|
||||
var closest: float = 9999999999
|
||||
for enemy in enemies:
|
||||
if enemy is Enemy:
|
||||
if !enemy.sighted:
|
||||
continue
|
||||
var distance_sqr = global_position.distance_squared_to(enemy.global_position)
|
||||
if distance_sqr <= closest:
|
||||
var params: PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.new()
|
||||
params.collision_mask = 0b00101
|
||||
params.from = to_global(fire_position)
|
||||
params.to = enemy.global_position
|
||||
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)
|
||||
if result.has("collider"):
|
||||
if !result["collider"] is PhysicsBody3D:
|
||||
continue
|
||||
var body: PhysicsBody3D = result["collider"]
|
||||
if body is Enemy:
|
||||
current_target = body
|
||||
closest = body.global_position.distance_squared_to(global_position)
|
||||
for enemy: Enemy in enemies:
|
||||
if !enemy.sighted:
|
||||
continue
|
||||
var distance_sqr = global_position.distance_squared_to(enemy.global_position)
|
||||
if distance_sqr <= closest:
|
||||
var params: PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.new()
|
||||
params.collision_mask = 0b00101
|
||||
params.from = to_global(fire_position)
|
||||
params.to = enemy.global_position
|
||||
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)
|
||||
if result.has("collider"):
|
||||
if !result["collider"] is PhysicsBody3D:
|
||||
continue
|
||||
var body: PhysicsBody3D = result["collider"]
|
||||
if body is Enemy:
|
||||
current_target = body
|
||||
closest = body.global_position.distance_squared_to(global_position)
|
||||
|
||||
func fire_at_target() -> void:
|
||||
#Engine.time_scale = 0.1
|
||||
|
@ -74,8 +73,8 @@ func fire_at_target() -> void:
|
|||
bullet.global_position = to_global(fire_position)
|
||||
|
||||
var aim_target: Vector3 = current_target.global_position
|
||||
var range: float = global_position.distance_to(current_target.global_position)
|
||||
aim_target += current_target.linear_velocity * lead_shot_factor * range
|
||||
var target_range: float = global_position.distance_to(current_target.global_position)
|
||||
aim_target += current_target.linear_velocity * lead_shot_factor * target_range
|
||||
DebugDraw3D.draw_sphere(aim_target, 0.25, Color.RED, 0.1)
|
||||
|
||||
bullet.look_at(aim_target)
|
||||
|
|
|
@ -10,7 +10,7 @@ func _on_body_entered(body: Node) -> void:
|
|||
var speed: float = linear_velocity.length()
|
||||
var damage: float = speed * damage_per_speed
|
||||
if damage >= min_damage:
|
||||
body.hurt(damage)
|
||||
(body as Unit).hurt(damage)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
lifetime -= delta
|
||||
|
|
|
@ -1,40 +1,50 @@
|
|||
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_object: Node3D = null
|
||||
var focus_position: Vector3
|
||||
|
||||
var last_mouse_position: Vector2
|
||||
var mouse_movement: Vector2
|
||||
var mouse_wheel_delta: int = 0
|
||||
|
||||
@onready var focus_marker: Node3D = $"Camera Focus"
|
||||
@onready var viewport: Viewport = get_viewport()
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
var mouse_position: Vector2 = get_viewport().get_mouse_position()
|
||||
var ray_origin: Vector3 = project_ray_origin(mouse_position)
|
||||
var ray_normal: Vector3 = ray_origin + project_ray_normal(mouse_position) * 200
|
||||
var params = PhysicsRayQueryParameters3D.create(ray_origin, ray_normal)
|
||||
var result: Dictionary = get_world_3d().direct_space_state.intersect_ray(params)
|
||||
if result.has("position"):
|
||||
DebugDraw3D.draw_sphere(result["position"], 0.5, Color.REBECCA_PURPLE)
|
||||
if Input.is_action_just_released("camera_set_target"):
|
||||
if result.has("collider") and !(result["collider"] is GridMap):
|
||||
focus_object = result["collider"]
|
||||
else:
|
||||
focus_object = null
|
||||
focus_position = result["position"]
|
||||
func _process(delta: float) -> void:
|
||||
if Input.is_action_just_released("camera_set_target"):
|
||||
var mouse_position: Vector2 = get_viewport().get_mouse_position()
|
||||
var ray_origin: Vector3 = project_ray_origin(mouse_position)
|
||||
var ray_normal: Vector3 = ray_origin + project_ray_normal(mouse_position) * 200
|
||||
var params: PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.create(ray_origin, ray_normal)
|
||||
var result: Dictionary = get_world_3d().direct_space_state.intersect_ray(params)
|
||||
if result.has("position"):
|
||||
#DebugDraw3D.draw_sphere(result["position"], 0.5, Color.REBECCA_PURPLE)
|
||||
if result.has("collider") and !(result["collider"] is GridMap):
|
||||
focus_object = result["collider"]
|
||||
else:
|
||||
focus_object = null
|
||||
focus_position = result["position"]
|
||||
|
||||
if focus_object != null:
|
||||
focus_position = focus_object.global_position
|
||||
|
||||
process_focus_movement(delta)
|
||||
process_camera_rotation(delta)
|
||||
process_camera_zoom(delta)
|
||||
|
||||
var target_position: Vector3 = focus_position + focus_offset
|
||||
if target_position.distance_squared_to(global_position) > 0:
|
||||
global_position = global_position.move_toward(target_position, 30*(1/60.0))
|
||||
else:
|
||||
look_at(focus_position)
|
||||
global_position = global_position.move_toward(target_position, maximum_movement_speed*delta)
|
||||
#else:
|
||||
|
||||
basis = basis.slerp(Basis.looking_at(focus_position - 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)
|
||||
|
@ -58,29 +68,46 @@ func process_focus_movement(delta: float) -> void:
|
|||
focus_object = null
|
||||
input = input_basis * input
|
||||
|
||||
var movement: Vector3 = input * pan_speed * delta
|
||||
var movement: Vector3 = input * keyboard_movement_speed * delta
|
||||
global_position += movement
|
||||
focus_position += movement
|
||||
|
||||
# handle moving on/off ramps
|
||||
var params: PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.new()
|
||||
params.from = focus_position + Vector3(0,2,0)
|
||||
params.to = focus_position - Vector3(0,2,0)
|
||||
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))
|
||||
if focus_follows_terrain:
|
||||
var params: PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.new()
|
||||
params.from = focus_position + Vector3(0,2,0)
|
||||
params.to = focus_position - Vector3(0,2,0)
|
||||
params.collision_mask = 1
|
||||
var result: Dictionary = get_world_3d().direct_space_state.intersect_ray(params)
|
||||
if result.has("position"):
|
||||
focus_position = result["position"]
|
||||
|
||||
func process_camera_rotation(delta: float) -> void:
|
||||
var mouse_position: Vector2 = get_viewport().get_mouse_position()
|
||||
var mouse_movement: Vector2 = mouse_position - last_mouse_position
|
||||
last_mouse_position = mouse_position
|
||||
#var mouse_position: Vector2 = viewport.get_mouse_position()
|
||||
#var mouse_position: Vector2 = Vector2()
|
||||
#var mouse_movement: Vector2 = (mouse_position - last_mouse_position) * delta
|
||||
#last_mouse_position = mouse_position
|
||||
if Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT):
|
||||
|
||||
focus_offset = focus_offset.rotated(Vector3.UP, -mouse_movement.x * 0.006)
|
||||
focus_offset = focus_offset.rotated(Vector3.UP, -mouse_movement.x * mouse_orbit_sensitivity)
|
||||
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
|
||||
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
|
||||
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 weight: float = 10.0
|
||||
@export var make_solid: bool = true
|
||||
@export var make_solid: bool = false
|
||||
|
||||
var enable_timer: float = 1.0
|
||||
var enabled: bool = false
|
||||
var updated_regions: Array[RID] = []
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if enable_timer > 0:
|
||||
enable_timer -= delta
|
||||
if !enabled and enable_timer <= 0:
|
||||
enabled = true
|
||||
update()
|
||||
func _exit_tree() -> void:
|
||||
update(false)
|
||||
|
||||
func update() -> void:
|
||||
func update(enable: bool) -> void:
|
||||
if !is_node_ready():
|
||||
await ready
|
||||
var global_aabb: AABB = global_transform * aabb
|
||||
#DebugDraw3D.draw_aabb(global_aabb, Color.DARK_CYAN, 5)
|
||||
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)
|
||||
#DebugDraw3D.draw_aabb(region_aabb, Color.YELLOW, 5)
|
||||
if global_aabb.intersects(region_aabb):
|
||||
NavigationServer3D.region_set_travel_cost(region_rid, weight)
|
||||
#NavigationServer3D.region_set_enabled(region_rid, false)
|
||||
DebugDraw3D.draw_aabb(region_aabb, Color.RED, 5)
|
||||
var old_weight: float = NavigationServer3D.region_get_travel_cost(region_rid)
|
||||
var new_weight: float = (old_weight * weight) if enable else (old_weight / weight)
|
||||
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()
|
||||
add_child(node)
|
||||
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_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:
|
||||
$NavigationAgent3D.connect("velocity_computed", avoidance_velocity_computed)
|
||||
nav_agent_3d.connect("velocity_computed", avoidance_velocity_computed)
|
||||
pass
|
||||
|
||||
func avoidance_velocity_computed(velocity: Vector3) -> void:
|
||||
|
@ -26,17 +30,17 @@ func avoidance_velocity_computed(velocity: Vector3) -> void:
|
|||
avoidance_timeout = 0.5
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
$Label3D.text = "HP: %d" % hp
|
||||
label_3d.text = "HP: %d" % hp
|
||||
|
||||
if $NavigationAgent3D.is_target_reached() \
|
||||
or $NavigationAgent3D.target_position.is_zero_approx() \
|
||||
or !$NavigationAgent3D.is_target_reachable():
|
||||
$NavigationAgent3D.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)
|
||||
last_distance_to_target = $NavigationAgent3D.distance_to_target()
|
||||
if nav_agent_3d.is_target_reached() \
|
||||
or nav_agent_3d.target_position.is_zero_approx() \
|
||||
or !nav_agent_3d.is_target_reachable():
|
||||
nav_agent_3d.target_position = move_target + Vector3(randfn(0, move_radius), 0, randfn(0, move_radius))
|
||||
#nav_agent_3d.target_position = NavigationServer3D.map_get_random_point(NavigationServer3D.get_maps()[0], 1, true)
|
||||
last_distance_to_target = nav_agent_3d.distance_to_target()
|
||||
else:
|
||||
if $ShapeCast3D.is_colliding():
|
||||
var distance_to_target: float = $NavigationAgent3D.distance_to_target()
|
||||
if shapecast_3d.is_colliding():
|
||||
var distance_to_target: float = nav_agent_3d.distance_to_target()
|
||||
var progress_rate: float = (last_distance_to_target - distance_to_target) / delta
|
||||
last_distance_to_target = distance_to_target
|
||||
if progress_rate < minimum_progress_rate:
|
||||
|
@ -44,24 +48,24 @@ func _process(delta: float) -> void:
|
|||
if stuck_timer >= stuck_time:
|
||||
unstuck()
|
||||
else:
|
||||
$Label3D.modulate = Color.WHITE
|
||||
label_3d.modulate = Color.WHITE
|
||||
stuck_timer = 0
|
||||
if global_position.y <= -10:
|
||||
unstuck()
|
||||
#DebugDraw3D.draw_sphere($NavigationAgent3D.target_position, 0.5, Color.RED)
|
||||
var next_point: Vector3 = $NavigationAgent3D.get_next_path_position()
|
||||
#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()
|
||||
#DebugDraw3D.draw_line(global_position, global_position + linear_velocity, Color.BLUE)
|
||||
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_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:
|
||||
# teleport to next path point
|
||||
linear_velocity = Vector3()
|
||||
global_position = $NavigationAgent3D.get_next_path_position()
|
||||
global_position = nav_agent_3d.get_next_path_position()
|
||||
stuck_timer = 0
|
||||
|
||||
func hurt(damage: float) -> void:
|
||||
|
@ -74,14 +78,14 @@ func die() -> void:
|
|||
queue_free()
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if $ShapeCast3D.is_colliding():
|
||||
if shapecast_3d.is_colliding():
|
||||
var actual_target_velocity: Vector3 = target_velocity
|
||||
if avoidance_timeout > 0:
|
||||
avoidance_timeout -= delta
|
||||
actual_target_velocity = actual_target_velocity.slerp(avoidance_velocity, 0.25)
|
||||
#DebugDraw3D.draw_line(global_position, global_position + actual_target_velocity, Color.ORANGE)
|
||||
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)
|
||||
var force: Vector3 = (force_direction * movement_force).slide(normal)
|
||||
#DebugDraw3D.draw_line(global_position, global_position + force, Color.GREEN)
|
||||
|
|
Loading…
Reference in New Issue