diff --git a/.gitmodules b/.gitmodules index 7a1cf2d..5c3d02c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ [submodule "godot-cpp"] path = godot-cpp url = https://github.com/godotengine/godot-cpp.git - branch = 4.2 + branch = 4.1 [submodule "src/utils"] path = src/utils diff --git a/godot-cpp b/godot-cpp index 51c752c..4b63d79 160000 --- a/godot-cpp +++ b/godot-cpp @@ -1 +1 @@ -Subproject commit 51c752c46b44769d3b6c661526c364a18ea64781 +Subproject commit 4b63d795e4279838d988399f008eec47eb2dcc7f diff --git a/godot/Environments/Non-Modular/whiteblock-station-level.glb b/godot/Environments/Non-Modular/whiteblock-station-level.glb deleted file mode 100644 index 5182955..0000000 --- a/godot/Environments/Non-Modular/whiteblock-station-level.glb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a0d53925838978886ecf8ca5f6d13d5f602f0c8b594746dd57a94a0d972a649e -size 1270856 diff --git a/godot/Environments/Non-Modular/whiteblock-station-level.glb.import b/godot/Environments/Non-Modular/whiteblock-station-level.glb.import deleted file mode 100644 index fcafa8e..0000000 --- a/godot/Environments/Non-Modular/whiteblock-station-level.glb.import +++ /dev/null @@ -1,41 +0,0 @@ -[remap] - -importer="scene" -importer_version=1 -type="PackedScene" -uid="uid://bw3gqiinifef4" -path="res://.godot/imported/whiteblock-station-level.glb-0ec8b9e904d919ae6bf68126120ff1a4.scn" - -[deps] - -source_file="res://Environments/Non-Modular/whiteblock-station-level.glb" -dest_files=["res://.godot/imported/whiteblock-station-level.glb-0ec8b9e904d919ae6bf68126120ff1a4.scn"] - -[params] - -nodes/root_type="" -nodes/root_name="" -nodes/apply_root_scale=true -nodes/root_scale=1.0 -meshes/ensure_tangents=true -meshes/generate_lods=true -meshes/create_shadow_meshes=true -meshes/light_baking=2 -meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false -skins/use_named_skins=true -animation/import=true -animation/fps=30 -animation/trimming=false -animation/remove_immutable_tracks=true -import_script/path="" -_subresources={ -"materials": { -"Shadow": { -"use_external/enabled": true, -"use_external/path": "res://Environments/Special Materials/shadow.tres" -} -} -} -gltf/naming_version=1 -gltf/embedded_image_handling=1 diff --git a/godot/Environments/Non-Modular/whiteblock-station-level.glb.unwrap_cache b/godot/Environments/Non-Modular/whiteblock-station-level.glb.unwrap_cache deleted file mode 100644 index a2ec780..0000000 Binary files a/godot/Environments/Non-Modular/whiteblock-station-level.glb.unwrap_cache and /dev/null differ diff --git a/godot/Environments/Roots/roots_a.glb b/godot/Environments/Roots/roots_a.glb deleted file mode 100644 index e489eaf..0000000 --- a/godot/Environments/Roots/roots_a.glb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5b7418158328aaae28ff12f507c2c8ff4ac1799068f79f9be7ae7285ee649a90 -size 120196 diff --git a/godot/Environments/Roots/roots_a.glb.import b/godot/Environments/Roots/roots_a.glb.import deleted file mode 100644 index a388e23..0000000 --- a/godot/Environments/Roots/roots_a.glb.import +++ /dev/null @@ -1,34 +0,0 @@ -[remap] - -importer="scene" -importer_version=1 -type="PackedScene" -uid="uid://d3apnkhay2yq3" -path="res://.godot/imported/roots_a.glb-3fef5f980b3fb4c8f2d3e000d80eb81e.scn" - -[deps] - -source_file="res://Environments/Roots/roots_a.glb" -dest_files=["res://.godot/imported/roots_a.glb-3fef5f980b3fb4c8f2d3e000d80eb81e.scn"] - -[params] - -nodes/root_type="" -nodes/root_name="" -nodes/apply_root_scale=true -nodes/root_scale=1.0 -meshes/ensure_tangents=true -meshes/generate_lods=true -meshes/create_shadow_meshes=true -meshes/light_baking=1 -meshes/lightmap_texel_size=0.2 -meshes/force_disable_compression=false -skins/use_named_skins=true -animation/import=true -animation/fps=30 -animation/trimming=false -animation/remove_immutable_tracks=true -import_script/path="" -_subresources={} -gltf/naming_version=1 -gltf/embedded_image_handling=1 diff --git a/godot/Environments/Special Materials/shadow.tres b/godot/Environments/Special Materials/shadow.tres deleted file mode 100644 index 3d59dc3..0000000 --- a/godot/Environments/Special Materials/shadow.tres +++ /dev/null @@ -1,5 +0,0 @@ -[gd_resource type="StandardMaterial3D" format=3 uid="uid://ccujbp2eghtha"] - -[resource] -shading_mode = 0 -albedo_color = Color(0, 0, 0, 1) diff --git a/godot/Weapons/pistol.tres b/godot/Weapons/pistol.tres index 35b087a..0a0ce7a 100644 --- a/godot/Weapons/pistol.tres +++ b/godot/Weapons/pistol.tres @@ -8,6 +8,7 @@ point_count = 2 [resource] projectile_scene = ExtResource("1_h12ld") -range = 25.0 +range = 15.0 rounds_per_second = 10.0 +allow_automatic = true projectile_speed = SubResource("Curve_tdh3d") diff --git a/godot/game_root.tscn b/godot/game_root.tscn index 73e3477..bc41b4b 100644 --- a/godot/game_root.tscn +++ b/godot/game_root.tscn @@ -4,7 +4,3 @@ [node name="GameRoot" type="GameRoot3D"] first_boot_level = ExtResource("1_4g2mr") - -[node name="GlobalWorldState" type="GlobalWorldState" parent="."] -process_priority = -1 -process_physics_priority = -1 diff --git a/godot/player.tscn b/godot/player.tscn index 0a00d6f..7961e9c 100644 --- a/godot/player.tscn +++ b/godot/player.tscn @@ -1,36 +1,21 @@ -[gd_scene load_steps=4 format=3 uid="uid://cqkbxe758jr7p"] +[gd_scene load_steps=3 format=3 uid="uid://cqkbxe758jr7p"] [sub_resource type="Curve" id="Curve_bxjan"] _data = [Vector2(0, 0), 0.0, 3.33407, 0, 0, Vector2(0.430894, 0.692308), 0.730621, 0.730621, 0, 0, Vector2(1, 1), 0.0, 0.0, 0, 0] point_count = 3 -[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_i3qba"] -no_depth_test = true -shading_mode = 0 -disable_ambient_light = true -disable_fog = true -albedo_color = Color(1, 0.596078, 0.0705882, 1) -billboard_mode = 1 -grow_amount = -1.0 - -[sub_resource type="PlaneMesh" id="PlaneMesh_rug6u"] -material = SubResource("StandardMaterial3D_i3qba") -size = Vector2(0.3, 0.3) -orientation = 2 +[sub_resource type="SphereMesh" id="SphereMesh_jkn5p"] +radius = 0.2 +height = 0.4 [node name="TunnelsPlayer" type="TunnelsPlayer"] camera_rotation_ramp = SubResource("Curve_bxjan") [node name="Camera3D" type="Camera3D" parent="."] transform = Transform3D(-1, -6.99417e-08, 5.24488e-08, 1.59825e-08, 0.443572, 0.896239, -8.59493e-08, 0.896239, -0.443572, -2.38419e-07, 9.56087, -0.526886) -cull_mask = 1048571 fov = 100.0 -near = 0.1 -far = 1000.0 [node name="Reticle" type="Node3D" parent="."] [node name="MeshInstance3D" type="MeshInstance3D" parent="Reticle"] -layers = 8 -gi_mode = 0 -mesh = SubResource("PlaneMesh_rug6u") +mesh = SubResource("SphereMesh_jkn5p") diff --git a/godot/player_character.tscn b/godot/player_character.tscn index 846e5e5..924af26 100644 --- a/godot/player_character.tscn +++ b/godot/player_character.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=11 format=3 uid="uid://dpda341t6ipiv"] +[gd_scene load_steps=9 format=3 uid="uid://dpda341t6ipiv"] [sub_resource type="Curve" id="Curve_7rmf4"] min_value = 0.2 @@ -6,8 +6,20 @@ max_value = 2.0 _data = [Vector2(0.145299, 0.2), 0.0, 0.482143, 0, 0, Vector2(0.594017, 2), 0.0, 0.0, 0, 0] point_count = 2 +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_3g72p"] +height = 1.59321 + +[sub_resource type="CapsuleMesh" id="CapsuleMesh_rwcvu"] +height = 1.605 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_scmx3"] +albedo_color = Color(0.94902, 0.909804, 0, 1) + +[sub_resource type="BoxMesh" id="BoxMesh_f5yvh"] +size = Vector3(0.125, 0.14, 0.94) + [sub_resource type="MoveStateArgs" id="MoveStateArgs_ibmkn"] -argument_property = &"g_player_character" +argument_property = &"player_character" [sub_resource type="Action" id="Action_gtisq"] effects = { @@ -15,15 +27,6 @@ effects = { } apply_state = SubResource("MoveStateArgs_ibmkn") -[sub_resource type="MoveStateArgs" id="MoveStateArgs_vyebd"] -argument_property = &"target" - -[sub_resource type="Action" id="Action_cwmvs"] -effects = { -"is_near_target": true -} -apply_state = SubResource("MoveStateArgs_vyebd") - [sub_resource type="Goal" id="Goal_sqtwb"] goal_state = { "is_near_player": true @@ -32,51 +35,36 @@ prerequisites = { "is_near_player": false } -[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_3g72p"] - -[sub_resource type="CapsuleMesh" id="CapsuleMesh_rwcvu"] -radial_segments = 12 -rings = 1 - -[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_scmx3"] -albedo_color = Color(0.94902, 0.909804, 0, 1) - -[sub_resource type="BoxMesh" id="BoxMesh_f5yvh"] -size = Vector3(0.125, 0.14, 0.94) - [node name="PlayerCharacter" type="CharacterActor"] rotation_speed_curve = SubResource("Curve_7rmf4") collision_layer = 7 -[node name="Planner" type="Planner" parent="."] -actions = [SubResource("Action_gtisq"), SubResource("Action_cwmvs")] -goals = [SubResource("Goal_sqtwb")] - [node name="Health" type="Health" parent="."] max_health = 5 [node name="ProjectilePool" type="ProjectilePool" parent="."] -[node name="WeaponMuzzle" type="WeaponMuzzle" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.53551, 1.36699, 0.121549) - [node name="NavigationAgent3D" type="NavigationAgent3D" parent="."] avoidance_enabled = true radius = 1.0 [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, 0.802835, 0) shape = SubResource("CapsuleShape3D_3g72p") [node name="MeshInstance3D" type="MeshInstance3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.99491, 0) -layers = 2 +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.8121, 0) mesh = SubResource("CapsuleMesh_rwcvu") surface_material_override/0 = SubResource("StandardMaterial3D_scmx3") -[node name="MeshInstance3D2" type="MeshInstance3D" parent="MeshInstance3D"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.509142, 0.361236, 0.380722) -layers = 2 +[node name="MeshInstance3D2" type="MeshInstance3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.509142, 0.986876, 0.380722) mesh = SubResource("BoxMesh_f5yvh") -skeleton = NodePath("../..") surface_material_override/0 = SubResource("StandardMaterial3D_scmx3") + +[node name="WeaponMuzzle" type="WeaponMuzzle" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.53551, 0.931313, 0) + +[node name="Planner" type="Planner" parent="."] +actions = [SubResource("Action_gtisq")] +goals = [SubResource("Goal_sqtwb")] diff --git a/godot/project.godot b/godot/project.godot index 7e8e3f3..9af50fe 100644 --- a/godot/project.godot +++ b/godot/project.godot @@ -42,19 +42,9 @@ fire={ "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) ] } -tactics_mode={ -"deadzone": 0.5, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"echo":false,"script":null) -] -} [layer_names] -3d_render/layer_1="Default" -3d_render/layer_2="Entities" -3d_render/layer_3="TacticsModeOnly" -3d_render/layer_4="NoShadows" 3d_physics/layer_1="Default" 3d_physics/layer_2="Vision" 3d_physics/layer_3="Hitboxes" -3d_physics/layer_4="Markers" diff --git a/godot/test_level.exr b/godot/test_level.exr deleted file mode 100644 index c5b54fd..0000000 Binary files a/godot/test_level.exr and /dev/null differ diff --git a/godot/test_level.exr.import b/godot/test_level.exr.import deleted file mode 100644 index 3500482..0000000 --- a/godot/test_level.exr.import +++ /dev/null @@ -1,26 +0,0 @@ -[remap] - -importer="2d_array_texture" -type="CompressedTexture2DArray" -uid="uid://batsfdiilq57g" -path="res://.godot/imported/test_level.exr-33d7ba8e62b2edfcc804854db2b1cf50.ctexarray" -metadata={ -"vram_texture": false -} - -[deps] - -source_file="res://test_level.exr" -dest_files=["res://.godot/imported/test_level.exr-33d7ba8e62b2edfcc804854db2b1cf50.ctexarray"] - -[params] - -compress/mode=3 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/channel_pack=1 -mipmaps/generate=false -mipmaps/limit=-1 -slices/horizontal=1 -slices/vertical=1 diff --git a/godot/test_level.tscn b/godot/test_level.tscn index 4cbf0f6..54de2c2 100644 --- a/godot/test_level.tscn +++ b/godot/test_level.tscn @@ -1,10 +1,9 @@ -[gd_scene load_steps=16 format=3 uid="uid://m36guasmi3c1"] +[gd_scene load_steps=12 format=3 uid="uid://m36guasmi3c1"] [ext_resource type="TunnelsGameState" uid="uid://cl0iikkau5mio" path="res://tunnels_game_state.tres" id="1_aove2"] [ext_resource type="PackedScene" uid="uid://cqkbxe758jr7p" path="res://player.tscn" id="2_6yx24"] +[ext_resource type="PackedScene" uid="uid://deb8qiasxsobt" path="res://Enemies/enemy.tscn" id="2_10wh5"] [ext_resource type="PackedScene" uid="uid://dpda341t6ipiv" path="res://player_character.tscn" id="4_22npn"] -[ext_resource type="PackedScene" uid="uid://bw3gqiinifef4" path="res://Environments/Non-Modular/whiteblock-station-level.glb" id="4_s3gmy"] -[ext_resource type="PackedScene" uid="uid://d3apnkhay2yq3" path="res://Environments/Roots/roots_a.glb" id="5_q78oq"] [sub_resource type="TunnelsGameMode" id="TunnelsGameMode_hnap3"] game_state = ExtResource("1_aove2") @@ -16,85 +15,42 @@ player_scene = ExtResource("2_6yx24") sky_material = SubResource("ProceduralSkyMaterial_s4k5k") [sub_resource type="Environment" id="Environment_mt2l0"] -background_mode = 1 -background_color = Color(0.109804, 0.219608, 0.25098, 1) -background_energy_multiplier = 0.0 +background_mode = 2 sky = SubResource("Sky_oquga") -ambient_light_source = 2 -ambient_light_color = Color(0.427451, 0.443137, 0.501961, 1) -ambient_light_sky_contribution = 0.0 -ambient_light_energy = 0.22 -[sub_resource type="NavigationMesh" id="NavigationMesh_pvpdb"] -vertices = PackedVector3Array(138.038, 0.2545, 109.215, 139.538, 0.2545, 109.215, 139.788, 0.2545, 108.215, 133.538, 0.2545, 108.215, 133.538, 0.2545, 108.215, 133.538, 0.2545, 125.465, 138.038, 0.2545, 109.215, 139.788, 0.2545, 108.215, 139.538, 0.2545, 109.215, 143.788, 0.2545, 110.215, 148.538, 0.2545, 111.215, 148.538, 0.2545, 108.215, 143.788, 0.2545, 110.215, 143.788, 0.2545, 111.965, 148.538, 0.2545, 111.215, 148.538, 0.2545, 108.215, 148.538, 0.2545, 111.215, 149.288, 0.2545, 111.965, 150.788, 0.2545, 120.965, 153.038, 0.2545, 120.715, 153.288, 0.2545, 116.965, 149.288, 0.2545, 111.965, 158.538, 0.2545, 116.965, 158.788, 0.2545, 118.715, 163.538, 0.2545, 118.465, 163.538, 0.2545, 108.215, 148.538, 0.2545, 108.215, 149.288, 0.2545, 111.965, 153.288, 0.2545, 116.965, 158.538, 0.2545, 116.965, 163.538, 0.2545, 108.215, 141.288, 6.2545, 111.715, 141.288, 6.2545, 110.715, 138.038, 5.2545, 109.965, 133.538, 5.0045, 125.965, 133.538, 5.2545, 127.965, 136.538, 6.2545, 128.715, 140.038, 0.5045, 111.465, 140.038, 0.5045, 110.715, 139.538, 0.2545, 110.715, 134.788, 0.2545, 127.715, 135.538, 0.5045, 127.965, 149.788, 5.0045, 112.465, 149.538, 5.0045, 111.965, 148.288, 5.5045, 111.965, 146.538, 6.5045, 112.465, 149.788, 7.0045, 130.465, 153.038, 5.5045, 129.965, 149.773, 5.0045, 115.226, 139.788, 0.2545, 126.215, 139.788, 0.2545, 126.715, 140.288, 0.2545, 126.715, 141.538, 0.2545, 125.965, 143.538, 0.2545, 113.465, 145.288, 0.2545, 126.215, 147.038, 0.2545, 127.715, 143.538, 0.2545, 113.465, 144.288, 0.2545, 125.965, 145.288, 0.2545, 126.215, 143.538, 0.2545, 113.465, 143.538, 0.2545, 113.465, 141.538, 0.2545, 125.965, 144.288, 0.2545, 125.965, 154.038, 5.5045, 117.965, 154.038, 5.5045, 136.465, 157.788, 5.5045, 136.465, 157.788, 5.5045, 117.965, 154.288, 0.2545, 118.215, 154.288, 0.2545, 136.215, 157.538, 0.2545, 136.215, 157.538, 0.2545, 118.215, 158.788, 0.2545, 118.715, 158.788, 0.2545, 155.465, 163.538, 0.2545, 155.715, 163.538, 0.2545, 118.465, 150.788, 0.2545, 120.965, 151.788, 0.2545, 126.715, 153.038, 0.2545, 126.465, 153.038, 0.2545, 120.715, 152.538, 0.2545, 131.215, 151.538, 0.2545, 131.465, 152.538, 0.2545, 131.965, 153.038, 0.2545, 126.465, 151.788, 0.2545, 126.715, 152.538, 0.2545, 129.965, 152.538, 0.2545, 131.965, 152.038, 0.2545, 135.465, 153.038, 0.2545, 135.715, 152.538, 0.2545, 131.215, 152.538, 0.2545, 131.965, 153.038, 0.2545, 135.715, 152.538, 0.2545, 131.215, 153.038, 0.2545, 135.715, 153.038, 0.2545, 126.465, 152.538, 0.2545, 129.965, 139.538, 0.2545, 133.215, 140.288, 0.2545, 134.215, 142.288, 0.2545, 135.215, 142.288, 0.2545, 135.215, 143.538, 0.2545, 135.215, 145.538, 0.2545, 134.215, 143.538, 0.2545, 127.465, 140.538, 0.2545, 128.215, 139.288, 0.2545, 129.965, 145.538, 0.2545, 134.215, 146.788, 0.2545, 131.965, 146.038, 0.2545, 128.965, 139.288, 0.2545, 129.965, 139.538, 0.2545, 133.215, 142.288, 0.2545, 135.215, 145.538, 0.2545, 134.215, 146.038, 0.2545, 128.965, 143.538, 0.2545, 127.465, 146.038, 9.5045, 129.715, 145.288, 9.5045, 128.715, 143.788, 9.5045, 127.965, 141.288, 9.5045, 128.215, 140.288, 9.5045, 128.965, 139.538, 9.5045, 130.465, 144.788, 9.5045, 134.215, 146.288, 9.5045, 132.215, 146.038, 9.5045, 129.715, 140.038, 9.5045, 133.215, 142.288, 9.5045, 134.715, 144.788, 9.5045, 134.215, 143.788, 9.5045, 127.965, 141.288, 9.5045, 128.215, 139.538, 9.5045, 130.465, 140.038, 9.5045, 133.215, 144.788, 9.5045, 134.215, 146.038, 9.5045, 129.715, 133.538, 0.2545, 131.465, 137.538, 0.2545, 130.715, 137.538, 0.2545, 129.965, 133.538, 0.2545, 128.965, 136.788, 6.2545, 131.965, 133.538, 5.0045, 132.465, 133.538, 5.0045, 134.465, 136.788, 5.2545, 150.465, 140.288, 6.5045, 149.965, 137.239, 6.0045, 134.288, 136.788, 6.0045, 137.695, 135.038, 0.2545, 132.465, 137.538, 0.5045, 144.465, 136.288, 0.5045, 133.215, 136.038, 0.5045, 132.215, 145.788, 6.7545, 149.965, 145.788, 6.5045, 150.465, 146.538, 6.2545, 150.715, 145.788, 6.7545, 149.965, 146.538, 6.2545, 150.715, 149.038, 4.7545, 150.965, 152.788, 5.0045, 134.215, 152.788, 5.2545, 132.965, 149.788, 7.0045, 132.465, 150.263, 6.2545, 133.19, 147.284, 6.0045, 147.191, 133.538, 0.2545, 142.965, 135.288, 0.2545, 142.715, 133.538, 0.2545, 135.215, 150.788, 0.2545, 140.215, 153.038, 0.2545, 140.715, 153.038, 0.2545, 135.715, 152.038, 0.2545, 135.465, 146.288, 0.2545, 136.715, 146.288, 0.2545, 135.715, 144.288, 0.2545, 136.715, 142.788, 0.2545, 149.715, 141.538, 0.2545, 136.715, 140.288, 0.2545, 136.215, 142.788, 0.2545, 149.715, 142.788, 0.2545, 149.715, 144.288, 0.2545, 136.715, 141.538, 0.2545, 136.715, 154.038, 5.5045, 137.715, 154.038, 5.5045, 156.215, 157.788, 5.5045, 156.215, 157.788, 5.5045, 137.715, 154.288, 0.2545, 137.965, 154.288, 0.2545, 155.965, 157.538, 0.2545, 155.965, 157.538, 0.2545, 137.965, 149.288, 0.2545, 147.215, 153.038, 0.2545, 147.715, 153.038, 0.2545, 140.715, 150.788, 0.2545, 140.215, 133.538, 0.2545, 142.965, 133.538, 0.2545, 147.965, 136.288, 0.2545, 147.465, 135.288, 0.2545, 142.715, 149.538, 0.2545, 167.215, 149.038, 0.2545, 168.715, 152.788, 0.2545, 168.215, 149.538, 0.2545, 167.215, 152.788, 0.2545, 168.215, 152.288, 0.2545, 164.965, 149.038, 0.2545, 166.465, 142.288, 0.2545, 166.465, 143.288, 0.2545, 166.465, 152.538, 0.2545, 163.715, 143.288, 0.2545, 166.465, 144.788, 0.2545, 167.465, 147.288, 0.2545, 166.465, 152.538, 0.2545, 163.715, 136.788, 0.2545, 150.965, 136.288, 0.2545, 147.465, 133.538, 0.2545, 147.965, 149.038, 0.2545, 166.465, 152.288, 0.2545, 164.965, 152.538, 0.2545, 163.715, 147.288, 0.2545, 166.465, 137.288, 0.2545, 151.465, 136.788, 0.2545, 150.965, 133.538, 0.2545, 147.965, 133.538, 0.2545, 171.465, 141.538, 0.2545, 167.215, 142.288, 0.2545, 166.465, 138.538, 0.2545, 171.465, 141.538, 0.2545, 169.465, 141.538, 0.2545, 167.215, 133.538, 0.2545, 171.465, 143.038, 0.2545, 150.965, 142.788, 0.2545, 150.465, 137.288, 0.2545, 151.465, 153.038, 0.2545, 147.715, 149.288, 0.2545, 147.215, 148.538, 0.2545, 151.465, 148.038, 0.2545, 151.965, 143.038, 0.2545, 150.965, 137.288, 0.2545, 151.465, 142.288, 0.2545, 166.465, 152.538, 0.2545, 163.715, 153.038, 0.2545, 156.965, 153.538, 0.2545, 163.215, 153.538, 0.2545, 157.215, 153.038, 0.2545, 156.965, 152.538, 0.2545, 163.715, 153.038, 0.2545, 147.715, 148.538, 0.2545, 151.465, 148.038, 0.2545, 151.965, 153.038, 0.2545, 156.965, 154.538, 0.2545, 163.715, 154.788, 0.2545, 164.965, 155.788, 0.2545, 165.215, 155.788, 0.2545, 165.215, 156.538, 0.2545, 166.965, 158.288, 0.2545, 166.715, 154.538, 0.2545, 163.715, 155.788, 0.2545, 165.215, 158.288, 0.2545, 166.715, 163.538, 0.2545, 155.715, 158.788, 0.2545, 155.465, 158.538, 0.2545, 157.215, 158.288, 0.2545, 166.715, 162.538, 0.2545, 163.965, 163.538, 0.2545, 163.215, 163.538, 0.2545, 155.715, 158.538, 0.2545, 157.215, 154.538, 0.2545, 163.715, 153.538, 0.2545, 157.215, 153.538, 0.2545, 163.215, 154.538, 0.2545, 163.715, 158.538, 0.2545, 157.215, 154.038, 1.7545, 166.215, 153.538, 1.7545, 165.215, 153.788, 1.7545, 167.465, 153.788, 1.7545, 167.465, 155.288, 2.0045, 167.465, 155.288, 1.7545, 166.715, 154.038, 1.7545, 166.215, 142.788, 1.2545, 167.715, 143.788, 1.5045, 170.965, 144.288, 1.7545, 168.715, 144.288, 1.7545, 168.215, 145.038, 5.7545, 170.965, 145.538, 5.7545, 171.215, 146.788, 5.7545, 171.215, 147.288, 5.7545, 169.965, 146.038, 5.7545, 168.965, 145.038, 5.7545, 169.215, 142.788, 0.2545, 171.465, 142.538, 0.2545, 170.215, 141.538, 0.2545, 169.465, 139.038, 0.2545, 171.715, 139.038, 0.2545, 172.465, 141.538, 0.2545, 169.465, 138.538, 0.2545, 171.465, 139.038, 0.2545, 171.715, 138.038, 0.2545, 174.715, 133.538, 0.2545, 181.465, 144.788, 0.2545, 181.465, 144.788, 0.2545, 172.715, 138.038, 0.2545, 174.715, 133.538, 0.2545, 175.465, 133.538, 0.2545, 181.465, 144.788, 0.2545, 172.715, 142.788, 0.2545, 171.465, 139.038, 0.2545, 172.465, 138.038, 0.2545, 174.715, 133.538, 4.5045, 172.465, 133.538, 4.7545, 174.465, 137.288, 2.0045, 173.715, 137.788, 2.0045, 172.715, 134.475, 4.2545, 174.278, 134.273, 4.0045, 173.706, 133.538, 0.2545, 172.965, 133.538, 0.2545, 174.215, 136.288, 0.2545, 173.715, 136.788, 0.2545, 172.965, 132.788, 5.7545, 182.465, 146.038, 5.7545, 182.715, 145.788, 5.7545, 182.215) -polygons = [PackedInt32Array(1, 0, 2), PackedInt32Array(2, 0, 3), PackedInt32Array(6, 5, 4), PackedInt32Array(8, 7, 9), PackedInt32Array(9, 7, 11), PackedInt32Array(9, 11, 10), PackedInt32Array(14, 13, 12), PackedInt32Array(17, 16, 15), PackedInt32Array(19, 18, 20), PackedInt32Array(20, 18, 21), PackedInt32Array(23, 22, 24), PackedInt32Array(24, 22, 25), PackedInt32Array(27, 26, 28), PackedInt32Array(28, 26, 29), PackedInt32Array(29, 26, 30), PackedInt32Array(32, 31, 33), PackedInt32Array(33, 31, 34), PackedInt32Array(34, 31, 35), PackedInt32Array(35, 31, 36), PackedInt32Array(38, 37, 39), PackedInt32Array(39, 37, 40), PackedInt32Array(40, 37, 41), PackedInt32Array(46, 48, 47), PackedInt32Array(47, 48, 42), PackedInt32Array(42, 44, 43), PackedInt32Array(44, 48, 45), PackedInt32Array(45, 48, 46), PackedInt32Array(48, 44, 42), PackedInt32Array(50, 49, 51), PackedInt32Array(51, 49, 52), PackedInt32Array(52, 49, 53), PackedInt32Array(56, 55, 54), PackedInt32Array(59, 58, 57), PackedInt32Array(62, 61, 60), PackedInt32Array(66, 65, 63), PackedInt32Array(63, 65, 64), PackedInt32Array(70, 69, 67), PackedInt32Array(67, 69, 68), PackedInt32Array(71, 74, 72), PackedInt32Array(72, 74, 73), PackedInt32Array(76, 75, 77), PackedInt32Array(77, 75, 78), PackedInt32Array(81, 80, 79), PackedInt32Array(84, 83, 82), PackedInt32Array(87, 86, 85), PackedInt32Array(90, 89, 88), PackedInt32Array(94, 93, 91), PackedInt32Array(91, 93, 92), PackedInt32Array(97, 96, 95), PackedInt32Array(100, 99, 98), PackedInt32Array(103, 102, 101), PackedInt32Array(104, 106, 105), PackedInt32Array(108, 107, 109), PackedInt32Array(109, 107, 110), PackedInt32Array(110, 107, 112), PackedInt32Array(110, 112, 111), PackedInt32Array(115, 114, 113), PackedInt32Array(118, 117, 116), PackedInt32Array(121, 120, 119), PackedInt32Array(124, 123, 122), PackedInt32Array(126, 125, 127), PackedInt32Array(127, 125, 128), PackedInt32Array(128, 125, 130), PackedInt32Array(128, 130, 129), PackedInt32Array(132, 131, 133), PackedInt32Array(133, 131, 134), PackedInt32Array(138, 141, 139), PackedInt32Array(139, 141, 140), PackedInt32Array(140, 136, 135), PackedInt32Array(136, 140, 137), PackedInt32Array(137, 141, 138), PackedInt32Array(141, 137, 140), PackedInt32Array(145, 144, 142), PackedInt32Array(142, 144, 143), PackedInt32Array(148, 147, 146), PackedInt32Array(153, 155, 154), PackedInt32Array(154, 156, 149), PackedInt32Array(149, 156, 150), PackedInt32Array(150, 156, 151), PackedInt32Array(151, 156, 152), PackedInt32Array(152, 155, 153), PackedInt32Array(155, 156, 154), PackedInt32Array(156, 155, 152), PackedInt32Array(159, 158, 157), PackedInt32Array(163, 162, 160), PackedInt32Array(160, 162, 161), PackedInt32Array(165, 164, 166), PackedInt32Array(166, 164, 167), PackedInt32Array(170, 169, 168), PackedInt32Array(173, 172, 171), PackedInt32Array(177, 176, 174), PackedInt32Array(174, 176, 175), PackedInt32Array(181, 180, 178), PackedInt32Array(178, 180, 179), PackedInt32Array(185, 184, 182), PackedInt32Array(182, 184, 183), PackedInt32Array(189, 188, 186), PackedInt32Array(186, 188, 187), PackedInt32Array(190, 192, 191), PackedInt32Array(196, 195, 193), PackedInt32Array(193, 195, 194), PackedInt32Array(199, 198, 197), PackedInt32Array(201, 200, 202), PackedInt32Array(202, 200, 203), PackedInt32Array(206, 205, 204), PackedInt32Array(208, 207, 209), PackedInt32Array(209, 207, 210), PackedInt32Array(212, 211, 213), PackedInt32Array(213, 211, 216), PackedInt32Array(213, 216, 215), PackedInt32Array(213, 215, 214), PackedInt32Array(218, 217, 219), PackedInt32Array(219, 217, 220), PackedInt32Array(223, 222, 221), PackedInt32Array(226, 225, 224), PackedInt32Array(228, 227, 229), PackedInt32Array(229, 227, 232), PackedInt32Array(229, 232, 231), PackedInt32Array(229, 231, 230), PackedInt32Array(234, 233, 235), PackedInt32Array(235, 233, 236), PackedInt32Array(238, 237, 239), PackedInt32Array(239, 237, 240), PackedInt32Array(243, 242, 241), PackedInt32Array(246, 245, 244), PackedInt32Array(249, 248, 247), PackedInt32Array(252, 251, 250), PackedInt32Array(254, 253, 255), PackedInt32Array(255, 253, 258), PackedInt32Array(255, 258, 257), PackedInt32Array(255, 257, 256), PackedInt32Array(260, 259, 261), PackedInt32Array(261, 259, 262), PackedInt32Array(265, 264, 263), PackedInt32Array(268, 267, 269), PackedInt32Array(269, 267, 266), PackedInt32Array(273, 272, 270), PackedInt32Array(270, 272, 271), PackedInt32Array(275, 274, 276), PackedInt32Array(276, 274, 277), PackedInt32Array(277, 274, 278), PackedInt32Array(278, 274, 279), PackedInt32Array(281, 280, 282), PackedInt32Array(282, 280, 283), PackedInt32Array(283, 280, 284), PackedInt32Array(287, 286, 285), PackedInt32Array(291, 290, 288), PackedInt32Array(288, 290, 289), PackedInt32Array(294, 293, 292), PackedInt32Array(296, 295, 297), PackedInt32Array(297, 295, 298), PackedInt32Array(301, 304, 302), PackedInt32Array(302, 304, 299), PackedInt32Array(299, 304, 300), PackedInt32Array(300, 304, 303), PackedInt32Array(303, 304, 301), PackedInt32Array(306, 305, 307), PackedInt32Array(307, 305, 308), PackedInt32Array(311, 310, 309)] -geometry_parsed_geometry_type = 1 -region_merge_size = 10.0 -detail_sample_distance = 2.0 +[sub_resource type="NavigationMesh" id="NavigationMesh_gx4lq"] +vertices = PackedVector3Array(-9.5, 0.625, -9.5, -9.5, 0.625, 9.5, 9.5, 0.625, 9.5, 9.5, 0.625, -9.5) +polygons = [PackedInt32Array(3, 2, 0), PackedInt32Array(0, 2, 1)] -[sub_resource type="BoxShape3D" id="BoxShape3D_twf2f"] -size = Vector3(13.56, 5.17578, 1) +[sub_resource type="BoxMesh" id="BoxMesh_5glbk"] +size = Vector3(20, 0.25, 20) -[sub_resource type="Goal" id="Goal_4rwap"] -goal_state = { -"is_near_target": true -} - -[sub_resource type="BoxShape3D" id="BoxShape3D_yc06m"] -size = Vector3(3.41748, 0.0739746, 1.1123) - -[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1xg52"] -shading_mode = 0 - -[sub_resource type="QuadMesh" id="QuadMesh_3t5bq"] -material = SubResource("StandardMaterial3D_1xg52") -size = Vector2(3.425, 1.115) -orientation = 1 +[sub_resource type="BoxShape3D" id="BoxShape3D_kacqg"] +size = Vector3(20, 0.25, 20) [node name="Level3D" type="Level3D"] game_mode_prototype = SubResource("TunnelsGameMode_hnap3") -[node name="PlayerCharacter" parent="." instance=ExtResource("4_22npn")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -9.69579, 0.125, 37.5582) - [node name="WorldEnvironment" type="WorldEnvironment" parent="."] environment = SubResource("Environment_mt2l0") [node name="NavigationRegion3D" type="NavigationRegion3D" parent="WorldEnvironment"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -146.118, 0, -141.107) -navigation_mesh = SubResource("NavigationMesh_pvpdb") +navigation_mesh = SubResource("NavigationMesh_gx4lq") -[node name="whiteblock-station-level" parent="WorldEnvironment/NavigationRegion3D" instance=ExtResource("4_s3gmy")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 139.108, -0.147458, 175.634) +[node name="MeshInstance3D" type="MeshInstance3D" parent="WorldEnvironment/NavigationRegion3D"] +mesh = SubResource("BoxMesh_5glbk") +skeleton = NodePath("../../..") -[node name="SpawnPoint3D" type="SpawnPoint3D" parent="WorldEnvironment/NavigationRegion3D/whiteblock-station-level"] -transform = Transform3D(-0.998702, 0, 0.0509415, 0, 1, 0, -0.0509415, 0, -0.998702, 1.35011, 0, 4.47903) +[node name="StaticBody3D" type="StaticBody3D" parent="WorldEnvironment/NavigationRegion3D/MeshInstance3D"] -[node name="StaticBody3D" type="StaticBody3D" parent="WorldEnvironment/NavigationRegion3D"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 139.524, 2.55327, 182.601) - -[node name="CollisionShape3D" type="CollisionShape3D" parent="WorldEnvironment/NavigationRegion3D/StaticBody3D"] -shape = SubResource("BoxShape3D_twf2f") - -[node name="roots_a" parent="WorldEnvironment/NavigationRegion3D" instance=ExtResource("5_q78oq")] -transform = Transform3D(-0.270684, 0, 0.962668, 0, 1, 0, -0.962668, 0, -0.270684, 153.864, 0.00155933, 166.723) +[node name="CollisionShape3D" type="CollisionShape3D" parent="WorldEnvironment/NavigationRegion3D/MeshInstance3D/StaticBody3D"] +shape = SubResource("BoxShape3D_kacqg") [node name="DirectionalLight3D" type="DirectionalLight3D" parent="WorldEnvironment"] -transform = Transform3D(-0.997622, -0.0563777, -0.0396435, -0.0654108, 0.593285, 0.80233, -0.0217137, 0.803016, -0.595562, 0, 13.5543, 0) -light_energy = 0.2 -shadow_enabled = true +transform = Transform3D(0.581243, 0.357328, -0.731077, 0, 0.898426, 0.439124, 0.81373, -0.255238, 0.522204, 0, 2.44259, 0) -[node name="LineGoalMarker" type="LineGoalMarker" parent="."] -extent = 1.5 -goal = SubResource("Goal_4rwap") -transform = Transform3D(-0.987153, 0, -0.159778, 0, 1, 0, 0.159778, 0, -0.987153, -9.71596, 0, 34.0804) -collision_layer = 8 -collision_mask = 0 +[node name="Enemy" parent="." instance=ExtResource("2_10wh5")] +transform = Transform3D(-0.925514, 0, -0.378713, 0, 1, 0, 0.378713, 0, -0.925514, -7.55551, 0.125, 8.12958) -[node name="CollisionShape3D" type="CollisionShape3D" parent="LineGoalMarker"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.53674e-07, 0, -0.370167) -shape = SubResource("BoxShape3D_yc06m") - -[node name="MeshInstance3D" type="MeshInstance3D" parent="LineGoalMarker"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.0594978, -0.383129) -mesh = SubResource("QuadMesh_3t5bq") +[node name="PlayerCharacter" parent="." instance=ExtResource("4_22npn")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5.12963, 0.125, -3.38872) diff --git a/models/long_light_a.blend b/models/long_light_a.blend deleted file mode 100644 index 42863fb..0000000 --- a/models/long_light_a.blend +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f1fdbc4ec1dfcc11637e434c78a7771456496667a7c39a33fc7416f291acd5cc -size 949720 diff --git a/models/long_light_a.blend1 b/models/long_light_a.blend1 deleted file mode 100644 index 6f08db4..0000000 Binary files a/models/long_light_a.blend1 and /dev/null differ diff --git a/models/roots_a.blend b/models/roots_a.blend deleted file mode 100644 index ecd5ce8..0000000 --- a/models/roots_a.blend +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8c3dcfc172af39ef3075343e1d82e94bfd9c47b409104a979b71bbd877b17d27 -size 1008424 diff --git a/models/roots_a.blend1 b/models/roots_a.blend1 deleted file mode 100644 index 5351b4b..0000000 Binary files a/models/roots_a.blend1 and /dev/null differ diff --git a/models/tunnel_wall_segment_a.blend b/models/tunnel_wall_segment_a.blend deleted file mode 100644 index 3a36fdf..0000000 --- a/models/tunnel_wall_segment_a.blend +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cbea95d73ae5763ef91acf5abd3b83907e9aae9200c5e5387c1ddb35caa49c09 -size 863296 diff --git a/models/tunnel_wall_segment_a.blend1 b/models/tunnel_wall_segment_a.blend1 deleted file mode 100644 index dbb5c61..0000000 Binary files a/models/tunnel_wall_segment_a.blend1 and /dev/null differ diff --git a/models/whiteblock-level.blend b/models/whiteblock-level.blend deleted file mode 100644 index 8680f97..0000000 --- a/models/whiteblock-level.blend +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9890da1ce90de973473ce712b27caa8b1ce2b9572ab282bfd5c18433c912efe6 -size 1229468 diff --git a/models/whiteblock-level.blend1 b/models/whiteblock-level.blend1 deleted file mode 100644 index ae66492..0000000 Binary files a/models/whiteblock-level.blend1 and /dev/null differ diff --git a/src/character_actor.cpp b/src/character_actor.cpp index 273d0fb..525b294 100644 --- a/src/character_actor.cpp +++ b/src/character_actor.cpp @@ -1,5 +1,4 @@ #include "character_actor.hpp" -#include "goal_marker.hpp" #include "planner.hpp" #include "projectile_pool.hpp" #include "state.hpp" @@ -16,41 +15,34 @@ namespace godot { void CharacterActor::_bind_methods() { #define CLASSNAME CharacterActor GDPROPERTY_HINTED(rotation_speed_curve, Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Curve"); - GDPROPERTY_HINTED(target, Variant::OBJECT, PROPERTY_HINT_NODE_TYPE, "Node"); - GDPROPERTY(acceleration, Variant::FLOAT); - GDPROPERTY(walk_speed, Variant::FLOAT); - GDPROPERTY(sprint_speed, Variant::FLOAT); - GDPROPERTY(rotation_speed, Variant::FLOAT); + GDFUNCTION_ARGS(set_velocity_target, "value"); GDFUNCTION(get_is_near_player); + GDFUNCTION(get_player_character); } void CharacterActor::_enter_tree() { GDGAMEONLY(); this->nav_agent = this->get_node("NavigationAgent3D"); - this->nav_agent->connect("velocity_computed", callable_mp(this, &CharacterActor::set_velocity_target)); + this->nav_agent->connect("velocity_computed", Callable(this, "set_velocity_target")); this->target_rotation = this->get_global_transform().get_basis().get_quaternion(); this->health = this->get_node("Health"); this->primary_weapon_pool = this->get_node("ProjectilePool"); this->planner = this->get_node("Planner"); - Ref game_mode = GameRoot::get_singleton()->get_game_mode(); - game_mode->register_player_character(this); } void CharacterActor::_process(double delta_time) { GDGAMEONLY(); + this->process_rotation(delta_time); if(!this->mode_manual) { this->process_behaviour(delta_time); this->process_navigation(delta_time); - if(!this->velocity_target.is_zero_approx()) - this->aim_direction(this->velocity_target.normalized()); } if(this->firing) { this->try_fire_weapon(); } - this->process_rotation(delta_time); } void CharacterActor::_physics_process(double delta_time) { GDGAMEONLY(); // accelerate towards velocity target - Vector3 const new_velocity = this->get_velocity().move_toward(this->velocity_target, delta_time * CharacterActor::acceleration); + Vector3 const new_velocity = this->get_velocity().move_toward(this->velocity_target, delta_time * CharacterActor::ACCELERATION); Vector3 const gravity{Vector3{0.f, this->get_velocity().y - 9.8f, 0.f}}; // apply either gravity or walking velocity depending on results this->set_velocity(this->is_on_floor() ? new_velocity : this->get_velocity() + gravity); @@ -59,7 +51,7 @@ void CharacterActor::_physics_process(double delta_time) { GDGAMEONLY(); } void CharacterActor::move(Vector3 world_vector) { - this->velocity_target = world_vector * CharacterActor::walk_speed; + this->velocity_target = world_vector * CharacterActor::WALK_SPEED; } void CharacterActor::aim(Vector3 at) { @@ -90,10 +82,6 @@ void CharacterActor::shoot_at(Vector3 at) { this->set_firing(true); } -void CharacterActor::force_update_action() { - this->set_state(this->planner->get_next_state()); -} - void CharacterActor::set_firing(bool firing) { this->firing = firing; } @@ -141,40 +129,12 @@ Vector3 CharacterActor::get_velocity_target() const { } bool CharacterActor::get_is_near_player() const { - return Ref(GameRoot::get_singleton()->get_game_mode()) - ->get_player_instance() - ->get_character() - ->get_global_position().distance_to(this->get_global_position()) < 5.f; + return this->get_player_character()->get_global_position().distance_to(this->get_global_position()) < 5.f; } -bool CharacterActor::get_is_near_target() const { - GoalMarker *target_marker = Object::cast_to(this->target); - Node3D *target_node3d = Object::cast_to(this->target); - return target_marker - ? target_marker->is_point_on(this->get_global_position()) - : (target_node3d && target_node3d->get_global_position().distance_to(this->get_global_position()) < 5.f); -} - -Vector3 CharacterActor::get_move_target() const { - GoalMarker *as_marker = Object::cast_to(this->current_state.move_to); - if(as_marker) - return as_marker->nearest_point_on(this->get_global_position()); - Node3D *as_node3d = Object::cast_to(this->current_state.move_to); - if(as_node3d) - return as_node3d->get_global_position(); - return this->get_global_position(); -} - -void CharacterActor::set_target(Node *target) { - this->target = target; -} - -Node *CharacterActor::get_target() const { - return this->target; -} - -goap::Planner *CharacterActor::get_planner() const { - return this->planner; +CharacterActor *CharacterActor::get_player_character() const { + Ref game_mode = GameRoot::get_singleton()->get_game_mode(); + return game_mode->get_player_instance()->get_character(); } void CharacterActor::set_state(goap::State state) { @@ -190,7 +150,7 @@ void CharacterActor::set_state(goap::State state) { default: break; case goap::State::STATE_MOVE_TO: - this->move_to(this->get_move_target()); + this->move_to(state.move_to->get_global_position()); break; } } @@ -202,8 +162,8 @@ void CharacterActor::process_behaviour(double delta_time) { default: break; case goap::State::STATE_MOVE_TO: - if(this->nav_agent->get_target_position().distance_to(this->get_move_target()) > 2.f) - this->nav_agent->set_target_position(this->get_move_target()); + if(this->nav_agent->get_target_position().distance_to(this->current_state.move_to->get_global_position()) > 2.f) + this->nav_agent->set_target_position(this->current_state.move_to->get_global_position()); break; case goap::State::STATE_ACTIVATE: break; @@ -219,7 +179,7 @@ void CharacterActor::process_navigation(double delta_time) { Vector3 const target_position = this->nav_agent->get_next_path_position(); Vector3 const direction = (target_position - this->get_global_position()).normalized(); if(this->nav_agent->get_avoidance_enabled()) - this->nav_agent->set_velocity(direction * CharacterActor::walk_speed); + this->nav_agent->set_velocity(direction * CharacterActor::WALK_SPEED); else this->move(direction); } @@ -236,7 +196,7 @@ void CharacterActor::process_rotation(double delta_time) { // calculate the angle that still needs to be traveled float const angle = current_quaternion.angle_to(target_quaternion); // calculate the angle amount that can be moved this frame - float const angle_step{float(this->rotation_speed_curve->sample(angle) * CharacterActor::rotation_speed * delta_time)}; + float const angle_step{float(this->rotation_speed_curve->sample(angle) * CharacterActor::ROTATION_SPEED * delta_time)}; // update this object's global transform with the new rotation basis.set_quaternion(angle < angle_step ? target_quaternion // to avoid overshooting, check if the max step is smaller than the angle distance : current_quaternion.slerp(target_quaternion, angle_step / angle)); // convert the angle step to a lerp t value between current and target rotations @@ -255,35 +215,8 @@ void CharacterActor::try_fire_weapon() { node->set_global_transform(this->weapon_muzzle->get_global_transform()); } -void CharacterActor::set_acceleration(float acceleration) { - this->acceleration = acceleration; -} - -float CharacterActor::get_acceleration() const { - return this->acceleration; -} - -void CharacterActor::set_walk_speed(float walk_speed) { - this->walk_speed = walk_speed; -} - -float CharacterActor::get_walk_speed() const { - return this->walk_speed; -} - -void CharacterActor::set_sprint_speed(float sprint_speed) { - this->sprint_speed = sprint_speed; -} - -float CharacterActor::get_sprint_speed() const { - return this->sprint_speed; -} - -void CharacterActor::set_rotation_speed(float rotation_speed) { - this->rotation_speed = rotation_speed; -} - -float CharacterActor::get_rotation_speed() const { - return this->rotation_speed; -} +float const CharacterActor::ACCELERATION{20.f}; +float const CharacterActor::WALK_SPEED{3.f}; +float const CharacterActor::SPRINT_SPEED{5.f}; +float const CharacterActor::ROTATION_SPEED{10.f}; } diff --git a/src/character_actor.hpp b/src/character_actor.hpp index ca434ae..1d83bce 100644 --- a/src/character_actor.hpp +++ b/src/character_actor.hpp @@ -12,17 +12,10 @@ namespace godot { class NavigationAgent3D; class TunnelsPlayer; class AnimationPlayer; - namespace goap { class Planner; }; -enum class Team { - CHARACTER_TEAM_WORLD = 0u, - CHARACTER_TEAM_PLAYER = 1u, - CHARACTER_TEAM_ENEMY = 2u, -}; - class CharacterActor : public CharacterBody3D, public IHealthEntity { GDCLASS(CharacterActor, CharacterBody3D); @@ -43,42 +36,21 @@ public: // fire weapon at a target position // calls aim(at) and set_firing(true) void shoot_at(Vector3 at); - // refresh the current action, ending the previous one - void force_update_action(); // getter-setters void set_firing(bool firing); void set_manual_mode(bool value); void set_rotation_speed_curve(Ref curve); Ref get_rotation_speed_curve() const; - virtual Health *get_health() override; virtual Health const *get_health() const override; - void set_character_data(Ref data); void set_weapon_muzzle(Node3D *node); void set_velocity_target(Vector3 value); Vector3 get_velocity_target() const; - - // planner getters bool get_is_near_player() const; - bool get_is_near_target() const; - Vector3 get_move_target() const; - - // getter - setters - void set_target(Node *target); - Node *get_target() const; - goap::Planner *get_planner() const; + CharacterActor *get_player_character() const; void set_state(goap::State state); - - void set_acceleration(float acceleration); - float get_acceleration() const; - void set_walk_speed(float walk_speed); - float get_walk_speed() const; - void set_sprint_speed(float sprint_speed); - float get_sprint_speed() const; - void set_rotation_speed(float rotation_speed); - float get_rotation_speed() const; protected: void process_behaviour(double delta_time); void process_navigation(double delta_time); @@ -113,10 +85,10 @@ private: Ref data; float fire_interval{0.f}; // derived from 1 / the current weapon's rps - float acceleration{20.f}; - float walk_speed{3.f}; - float sprint_speed{5.f}; - float rotation_speed{10.f}; + static float const ACCELERATION; + static float const WALK_SPEED; + static float const SPRINT_SPEED; + static float const ROTATION_SPEED; }; } diff --git a/src/global_world_state.cpp b/src/global_world_state.cpp index 4eb6cf6..3152b07 100644 --- a/src/global_world_state.cpp +++ b/src/global_world_state.cpp @@ -1,13 +1,10 @@ #include "global_world_state.hpp" #include "character_actor.hpp" #include "utils/game_root.hpp" -#include "utils/godot_macros.h" -#include namespace godot::goap { void GlobalWorldState::_bind_methods() { #define CLASSNAME GlobalWorldState - GDFUNCTION(get_player_character); } bool GlobalWorldState::has_singleton() { @@ -18,27 +15,26 @@ GlobalWorldState *GlobalWorldState::get_singleton() { return GlobalWorldState::singleton_instance; } -void GlobalWorldState::_enter_tree() { GDGAMEONLY(); - if(GlobalWorldState::singleton_instance == nullptr) { +void GlobalWorldState::_enter_tree() { + if(GlobalWorldState::singleton_instance == nullptr) GlobalWorldState::singleton_instance = this; - } } -void GlobalWorldState::_exit_tree() { GDGAMEONLY(); +void GlobalWorldState::_ready() { + this->game_mode = GameRoot::get_singleton()->get_game_mode(); +} + +void GlobalWorldState::_exit_tree() { if(GlobalWorldState::singleton_instance == this) GlobalWorldState::singleton_instance = nullptr; } -void GlobalWorldState::_process(double delta_time) { GDGAMEONLY(); +void GlobalWorldState::_process(double delta_time) { global_state_cache.clear(); // invalidate cache } -Vector3 GlobalWorldState::get_player_position() const { - return this->get_player_character()->get_global_position(); -} - -CharacterActor *GlobalWorldState::get_player_character() const { - return Ref(GameRoot::get_singleton()->get_game_mode())->get_player_instance()->get_character(); +Vector3 GlobalWorldState::get_player_position() { + return this->game_mode->get_player_instance()->get_character()->get_global_position(); } Variant GlobalWorldState::get_world_property(StringName prop_key) { @@ -49,18 +45,14 @@ Variant GlobalWorldState::get_world_property(StringName prop_key) { else if(global_state_cache.has(prop_key)) return global_state_cache.get(prop_key); // fetch by function name - StringName const fn = "get_" + prop_key.erase(0, 2); + StringName const fn = "get_" + prop_key.right(prop_key.length() - 2); if(this->has_method(fn)) { Variant result = this->call(fn); // cache and return this->global_state_cache.insert(prop_key, result); return result; - } else { -#ifdef DEBUG_ENABLED_ENABLED - abort(); -#endif - return nullptr; } + return nullptr; } GlobalWorldState *GlobalWorldState::singleton_instance{nullptr}; diff --git a/src/global_world_state.hpp b/src/global_world_state.hpp index 834f665..a8f1eed 100644 --- a/src/global_world_state.hpp +++ b/src/global_world_state.hpp @@ -14,15 +14,16 @@ public: static GlobalWorldState *get_singleton(); virtual void _enter_tree() override; + virtual void _ready() override; virtual void _exit_tree() override; virtual void _process(double delta_time) override; - Vector3 get_player_position() const; - CharacterActor *get_player_character() const; + Vector3 get_player_position(); Variant get_world_property(StringName prop_key); private: WorldState global_state_cache{}; + Ref game_mode{}; static GlobalWorldState *singleton_instance; }; } diff --git a/src/goal_marker.cpp b/src/goal_marker.cpp deleted file mode 100644 index 833d9b0..0000000 --- a/src/goal_marker.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "goal_marker.hpp" -#include "godot_cpp/core/math.hpp" -#include "planner.hpp" -#include "utils/godot_macros.h" -#include - -namespace godot { -void GoalMarker::_bind_methods() { -#define CLASSNAME GoalMarker - GDPROPERTY_HINTED(goal, Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Goal"); -} - -bool GoalMarker::is_point_on(Vector3 point) { - return point.distance_squared_to(this->get_global_position()) <= .5f * .5f; -} - -Vector3 GoalMarker::nearest_point_on(Vector3 nearest_to) { - return this->get_global_position(); -} - -void GoalMarker::set_goal(Ref goal) { - this->goal = goal; -} - -Ref GoalMarker::get_goal() const { - return this->goal; -} - -void GoalMarker::set_radius(float radius) { - this->radius = radius; -} - -float GoalMarker::get_radius() const { - return this->radius; -} - -#undef CLASSNAME - -void LineGoalMarker::_bind_methods() { -#define CLASSNAME LineGoalMarker - GDPROPERTY(extent, Variant::FLOAT); -} - -bool LineGoalMarker::is_point_on(Vector3 point) { - return this->nearest_point_on(point).distance_to(point) < this->radius * this->radius; -} - -Vector3 LineGoalMarker::nearest_point_on(Vector3 point) { - Basis const &basis{this->get_global_basis()}; - Vector3 const left_unit{basis.get_column(0).normalized()}; - Vector3 const right_vec{this->get_global_position() + left_unit * -extent}; - float const length{extent * 2.f}; - return right_vec + left_unit * Math::clamp(left_unit.dot(point - right_vec), 0.f, length); -} - -void LineGoalMarker::set_extent(float extent) { - this->extent = extent; -} - -float LineGoalMarker::get_extent() const { - return this->extent; -} -} diff --git a/src/goal_marker.hpp b/src/goal_marker.hpp deleted file mode 100644 index e9b198b..0000000 --- a/src/goal_marker.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef GOAL_MARKER_HPP -#define GOAL_MARKER_HPP - -#include - -namespace godot { -class CharacterActor; -namespace goap { - class Planner; - class Goal; -} - -class GoalMarker : public Area3D { - GDCLASS(GoalMarker, Area3D); - static void _bind_methods(); -public: - virtual bool is_point_on(Vector3 point); - virtual Vector3 nearest_point_on(Vector3 near_to); - - void set_goal(Ref goal); - Ref get_goal() const; - void set_radius(float radius); - float get_radius() const; -protected: - Ref goal{nullptr}; - float radius{0.2f}; -}; - -class LineGoalMarker : public GoalMarker { - GDCLASS(LineGoalMarker, GoalMarker); - static void _bind_methods(); -public: - virtual bool is_point_on(Vector3 point) override; - virtual Vector3 nearest_point_on(Vector3 near_to) override; - - void set_extent(float left); - float get_extent() const; -private: - float extent{0.5f}; -}; -} - -#endif // !GOAL_MARKER_HPP diff --git a/src/pellet_projectile.cpp b/src/pellet_projectile.cpp index 6552394..b9a537c 100644 --- a/src/pellet_projectile.cpp +++ b/src/pellet_projectile.cpp @@ -19,14 +19,15 @@ void PelletProjectile::_physics_process(double delta_time) { GDGAMEONLY(); float const speed = this->data->get_projectile_speed()->sample(distance_traveled / this->data->get_range()); this->distance_traveled += speed; Vector3 const next_position{this->get_global_position() + this->get_global_transform().basis.get_column(2) * speed}; - if(this->check_hit(next_position) || this->distance_traveled > this->data->get_range()) + if(this->check_hit(next_position) || this->distance_traveled > this->data->get_range()) { this->return_to_pool(); - else + } else { this->set_global_position(next_position); + } } bool PelletProjectile::check_hit(Vector3 next_position) { - Ref query{PhysicsRayQueryParameters3D::create(this->get_global_position(), next_position, 0b101)}; + Ref query{PhysicsRayQueryParameters3D::create(this->get_global_position(), next_position, 0x4)}; Dictionary hit = this->get_world_3d()->get_direct_space_state()->intersect_ray(query); if(hit.is_empty()) return false; @@ -35,7 +36,7 @@ bool PelletProjectile::check_hit(Vector3 next_position) { return false; IHealthEntity *health_entity = dynamic_cast(collider); if(health_entity == nullptr) - return true; + return false; health_entity->get_health()->damage(this->data->get_damage()); return true; } diff --git a/src/pellet_projectile.hpp b/src/pellet_projectile.hpp index b62f9e0..b86b532 100644 --- a/src/pellet_projectile.hpp +++ b/src/pellet_projectile.hpp @@ -1,6 +1,7 @@ #ifndef PELLET_PROJECTILE_HPP #define PELLET_PROJECTILE_HPP +#include "weapon_data.hpp" #include "projectile.hpp" #include diff --git a/src/planner.cpp b/src/planner.cpp index 60078d9..cdd1235 100644 --- a/src/planner.cpp +++ b/src/planner.cpp @@ -13,8 +13,8 @@ #include namespace godot::goap { -typedef HashMap NodeNodeMap; -typedef HashMap NodeScoreMap; +typedef HashMap FromMap; +typedef HashMap ScoreMap; typedef HashSet NodeSet; void Goal::_bind_methods() { @@ -64,12 +64,12 @@ void Planner::_bind_methods() { GDPROPERTY_HINTED(goals, Variant::ARRAY, PROPERTY_HINT_ARRAY_TYPE, GDRESOURCETYPE(Goal)); } -void Planner::_enter_tree() { +void Planner::_ready() { this->global_world_state = GlobalWorldState::get_singleton(); this->actor = Object::cast_to(this->get_parent()); } -static Vector> trace_path(NodeNodeMap &map, PlannerNode &end) { +static Vector> trace_path(FromMap &map, PlannerNode &end) { Vector> edges{}; PlannerNode node{end}; while(node.last_edge.is_valid()) { @@ -82,29 +82,24 @@ static Vector> trace_path(NodeNodeMap &map, PlannerNode &end) { Vector> Planner::make_plan() { // clear cache every planning phase this->cached_world_state.clear(); - // select the most desirable goal available Ref goal = this->select_goal(); - if(!goal.is_valid()) { - this->plan = {}; - return this->plan; - } + if(!goal.is_valid()) + return {}; // ordered list of all nodes still being considered Vector open{PlannerNode::goal_node(goal->goal_state)}; PlannerNode first = open.get(0); - NodeNodeMap from{}; // mapping states to the previous in the path - NodeScoreMap dist_traveled{}; // mapping states to the shortest found distance from start + FromMap from{}; // mapping states to the previous in the path + ScoreMap dist_traveled{}; // mapping states to the shortest found distance from start dist_traveled.insert(first, 0); - NodeScoreMap best_guess{}; // mapping states to the best guess of the distance to the goal + ScoreMap best_guess{}; // mapping states to the best guess of the distance to the goal best_guess.insert(first, first.open_requirements.size()); PlannerNode current{}; // state we're checking for neighbours or completion while(!open.is_empty()) { // current is the top of the ordered list current = open.get(0); // check if we've reached the goal - if(current.open_requirements.is_empty()) { - this->plan = trace_path(from, current); - return this->plan; - } + if(current.open_requirements.is_empty()) + return trace_path(from, current); // current is no longer considered as it cannot be the end open.erase(current); // find all neighbours of this state @@ -123,15 +118,19 @@ Vector> Planner::make_plan() { } } } - UtilityFunctions::push_warning("Failed to find a plan satisfying goal"); - this->plan = {}; - return this->plan; + return {}; } Ref Planner::select_goal() { for(Ref const &goal : this->goals) { - if(this->can_do(goal)) - return goal; + bool can_try{true}; + for(WorldProperty const &prop : goal->prerequisites) { + if(prop.value != this->get_world_property(prop.key)) { + can_try = false; + break; + } + } + if(can_try) return goal; } return {}; } @@ -149,16 +148,10 @@ Variant Planner::get_world_property(StringName prop_key) { } bool Planner::can_do(Ref action) { - for(WorldProperty &prop : action->context_prerequisites) - if(this->get_world_property(prop.key) != prop.value) - return false; - return true; -} - -bool Planner::can_do(Ref goal) { - for(WorldProperty const &prop : goal->prerequisites) + for(WorldProperty &prop : action->context_prerequisites) { if(this->get_world_property(prop.key) != prop.value) return false; + } return true; } @@ -203,7 +196,7 @@ State Planner::get_next_state() { this->plan = this->make_plan(); if(this->plan.is_empty()) return State::new_invalid(); - return this->plan.get(0)->apply_state->construct(this); + return this->plan.get(0)->apply_state->construct(this->actor); } void Planner::set_actions(Array value) { @@ -241,14 +234,4 @@ Array Planner::get_goals() const { } return array; } - -bool Planner::add_goal(Ref goal) { - bool can_do = this->can_do(goal); - this->goals.insert(0, goal); - return can_do; -} - -void Planner::remove_goal(Ref goal) { - this->goals.erase(goal); -} } diff --git a/src/planner.hpp b/src/planner.hpp index fee995c..9bf9e73 100644 --- a/src/planner.hpp +++ b/src/planner.hpp @@ -2,7 +2,6 @@ #define GOAP_PLANNER_HPP #include "action.hpp" -#include "goal_marker.hpp" #include "godot_cpp/variant/variant.hpp" #include #include @@ -45,7 +44,7 @@ class Planner : public Node { GDCLASS(Planner, Node); static void _bind_methods(); public: - virtual void _enter_tree() override; + virtual void _ready() override; Vector> make_plan(); Ref select_goal(); @@ -53,7 +52,6 @@ public: Variant get_world_property(StringName prop_key); bool can_do(Ref action); - bool can_do(Ref goal); Vector find_neighbours_of(PlannerNode &node); Vector> find_actions_satisfying(WorldState requirements); @@ -64,8 +62,6 @@ public: Array get_actions() const; void set_goals(Array goals); Array get_goals() const; - bool add_goal(Ref goal); - void remove_goal(Ref goal); private: CharacterActor *actor{nullptr}; // the parent actor of this planner WorldState cached_world_state{}; // the cached worldstate, cleared for every make_plan call diff --git a/src/register_types.cpp b/src/register_types.cpp index 0beb221..8a05f53 100644 --- a/src/register_types.cpp +++ b/src/register_types.cpp @@ -4,7 +4,6 @@ #include "character_data.hpp" #include "enemy.hpp" #include "global_world_state.hpp" -#include "goal_marker.hpp" #include "health.hpp" #include "pellet_projectile.hpp" #include "planner.hpp" @@ -65,8 +64,6 @@ void initialize_gdextension_types(ModuleInitializationLevel p_level) ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); - ClassDB::register_class(); - ClassDB::register_class(); } extern "C" diff --git a/src/state.cpp b/src/state.cpp index 2dcb68f..bdb1900 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -1,6 +1,5 @@ #include "state.hpp" #include "character_actor.hpp" -#include "planner.hpp" #include "utils/godot_macros.h" namespace godot::goap { @@ -52,7 +51,7 @@ void StateArgs::_bind_methods() { GDPROPERTY(argument_property, Variant::STRING_NAME); } -State StateArgs::construct(Planner *context) const { +State StateArgs::construct(Node *context) const { return { .type = State::STATE_TYPE_MAX }; } @@ -61,21 +60,21 @@ StringName StateArgs::get_argument_property() const { return this->argument_prop void MoveStateArgs::_bind_methods() {} -State MoveStateArgs::construct(Planner *context) const { - Node3D *node = Object::cast_to(context->get_world_property(this->argument_property)); +State MoveStateArgs::construct(Node *context) const { + Node3D *node = Object::cast_to(context->call("get_" + this->argument_property)); return State::new_move_to(node); } void AnimateStateArgs::_bind_methods() {} -State AnimateStateArgs::construct(Planner *context) const { - return State::new_animate(context->get_world_property(this->argument_property)); +State AnimateStateArgs::construct(Node *context) const { + return State::new_animate(context->call("get_" + this->argument_property)); } void ActivateStateArgs::_bind_methods() {} -State ActivateStateArgs::construct(Planner *context) const { - Node *node = Object::cast_to(context->get_world_property(this->argument_property)); +State ActivateStateArgs::construct(Node *context) const { + Node *node = Object::cast_to(context->call("get_" + this->argument_property)); return State::new_activate(node); } } diff --git a/src/state.hpp b/src/state.hpp index 4cbf89e..1e9986c 100644 --- a/src/state.hpp +++ b/src/state.hpp @@ -9,8 +9,6 @@ namespace godot { class CharacterActor; } namespace godot::goap { -class Planner; - struct State { ~State(); static State new_move_to(Node3D *location); @@ -38,7 +36,7 @@ class StateArgs : public Resource { GDCLASS(StateArgs, Resource); static void _bind_methods(); public: - virtual State construct(Planner *context) const; + virtual State construct(Node *context) const; void set_argument_property(StringName name); StringName get_argument_property() const; StringName argument_property; @@ -47,21 +45,21 @@ public: class MoveStateArgs : public StateArgs { GDCLASS(MoveStateArgs, StateArgs); static void _bind_methods(); - virtual State construct(Planner *context) const override; + virtual State construct(Node *context) const override; }; class AnimateStateArgs : public StateArgs { GDCLASS(AnimateStateArgs, StateArgs); static void _bind_methods(); public: - virtual State construct(Planner *context) const override; + virtual State construct(Node *context) const override; }; class ActivateStateArgs : public StateArgs { GDCLASS(ActivateStateArgs, StateArgs); static void _bind_methods(); public: - virtual State construct(Planner *context) const override; + virtual State construct(Node *context) const override; }; }; diff --git a/src/tunnels_game_mode.cpp b/src/tunnels_game_mode.cpp index 0d279c0..a222e3a 100644 --- a/src/tunnels_game_mode.cpp +++ b/src/tunnels_game_mode.cpp @@ -1,12 +1,8 @@ #include "tunnels_game_mode.hpp" -#include "character_actor.hpp" +#include "godot_cpp/variant/utility_functions.hpp" #include "utils/game_root.hpp" #include "utils/godot_macros.h" #include -#include -#include -#include -#include namespace godot { void TunnelsGameMode::_bind_methods() { @@ -25,27 +21,4 @@ void TunnelsGameMode::on_player_spawned(Node *player) { TunnelsPlayer *TunnelsGameMode::get_player_instance() const { return this->player; } - -void TunnelsGameMode::register_player_character(CharacterActor *actor) { - if(!this->player_characters.has(actor)) { - this->player_characters.push_back(actor); - actor->connect("tree_exited", callable_mp(this, &TunnelsGameMode::on_character_destroyed).bind(actor)); - } -} - -void TunnelsGameMode::set_manual_character(CharacterActor *actor) { - if(!this->player_characters.has(actor)) - this->register_player_character(actor); - this->manual_character = actor; -} - -void TunnelsGameMode::on_character_destroyed(CharacterActor *actor) { - this->player_characters.erase(actor); - if(this->manual_character == actor) - this->manual_character = nullptr; -} - -Vector const &TunnelsGameMode::get_player_characters() const { - return this->player_characters; -} } diff --git a/src/tunnels_game_mode.hpp b/src/tunnels_game_mode.hpp index ea20832..937942e 100644 --- a/src/tunnels_game_mode.hpp +++ b/src/tunnels_game_mode.hpp @@ -1,9 +1,9 @@ #ifndef TUNNELS_GAME_MODE_HPP #define TUNNELS_GAME_MODE_HPP +#include "tunnels_game_state.hpp" #include "tunnels_player.hpp" #include "utils/game_mode.hpp" -#include namespace godot { class TunnelsGameMode : public GameMode { @@ -15,14 +15,8 @@ public: void on_player_spawned(Node *player); TunnelsPlayer *get_player_instance() const; - void register_player_character(CharacterActor *actor); - void set_manual_character(CharacterActor *actor); - void on_character_destroyed(CharacterActor *actor); - Vector const &get_player_characters() const; private: TunnelsPlayer *player{nullptr}; - CharacterActor *manual_character{nullptr}; - Vector player_characters{}; }; } diff --git a/src/tunnels_player.cpp b/src/tunnels_player.cpp index a053525..9653b55 100644 --- a/src/tunnels_player.cpp +++ b/src/tunnels_player.cpp @@ -1,42 +1,34 @@ #include "tunnels_player.hpp" -#include "character_actor.hpp" #include "character_data.hpp" -#include "goal_marker.hpp" -#include "godot_cpp/variant/callable_method_pointer.hpp" -#include "godot_cpp/variant/utility_functions.hpp" -#include "planner.hpp" -#include "tunnels_game_mode.hpp" +#include "godot_cpp/variant/plane.hpp" +#include "godot_cpp/variant/projection.hpp" +#include "character_actor.hpp" #include "tunnels_game_state.hpp" #include "utils/game_root.hpp" #include "utils/godot_macros.h" #include "utils/player_input.hpp" #include #include -#include -#include #include #include #include -#include -#include -#include namespace godot { void TunnelsPlayer::_bind_methods() { #define CLASSNAME TunnelsPlayer + GDFUNCTION_ARGS(horizontal_move_input, "event", "value"); + GDFUNCTION_ARGS(vertical_move_input, "event", "value"); + GDFUNCTION_ARGS(fire_pressed, "event", "value"); GDPROPERTY_HINTED(camera_rotation_ramp, Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, "Curve"); } -void TunnelsPlayer::_enter_tree() { GDGAMEONLY(); +void TunnelsPlayer::_ready() { GDGAMEONLY(); + this->camera = this->get_viewport()->get_camera_3d(); this->initialize_character(); this->camera_rotation_ramp->bake(); this->reticle = this->get_node("Reticle"); } -void TunnelsPlayer::_ready() { - this->camera = this->get_viewport()->get_camera_3d(); -} - void TunnelsPlayer::_exit_tree() { GDGAMEONLY(); GameRoot::get_singleton()->remove_player(this->get_player_id()); } @@ -60,11 +52,10 @@ void TunnelsPlayer::_process(double delta_time) { GDGAMEONLY(); this->set_global_position(this->character->get_global_position()); break; case State::Tactics: - // move camera along with the input - this->set_global_position(this->get_global_position() + this->get_world_move_input().normalized() * - delta_time * TunnelsPlayer::TACTICS_MOVEMENT_SPEED); break; case State::Overview: + // move camera along with the input + this->set_global_position(this->get_global_position() + this->get_world_move_input().normalized()); break; } } @@ -82,16 +73,15 @@ void TunnelsPlayer::process_camera_rotation(double delta_time) { Vector3 rotation = this->get_global_rotation(); // the influence of the mouse's y position on the rotation speed float const y_multiplier = std::max(TunnelsPlayer::ROTATION_Y_MIN_INFLUENCE, this->mouse_location.y); - float const margin = TunnelsPlayer::ROTATION_MARGIN * (this->state == State::Tactics ? TunnelsPlayer::ROTATION_MARGIN_TACTICS_MUL : 1.f); // rotate the camera when the mouse is close to the edge of the screen - if(this->mouse_location.x < margin) { + if(this->mouse_location.x < TunnelsPlayer::ROTATION_MARGIN) { // normalized measurement of how far into the rotation margin the mouse is - float const normalized{1.f - (this->mouse_location.x / margin)}; + float const normalized{1.f - (this->mouse_location.x / TunnelsPlayer::ROTATION_MARGIN)}; // rotate based on delta time and use a curve to make the rotation zone feel more natural rotation.y += delta_time * double(TunnelsPlayer::ROTATION_SPEED * camera_rotation_ramp->sample(normalized) * y_multiplier); } - if(this->mouse_location.x > 1.f - margin) { - float const normalized{((this->mouse_location.x - (1.f - margin)) / margin)}; + if(this->mouse_location.x > 1.f - TunnelsPlayer::ROTATION_MARGIN) { + float const normalized{((this->mouse_location.x - (1.f - TunnelsPlayer::ROTATION_MARGIN)) / TunnelsPlayer::ROTATION_MARGIN)}; rotation.y -= delta_time * double(TunnelsPlayer::ROTATION_SPEED * camera_rotation_ramp->sample(normalized) * y_multiplier); } @@ -105,21 +95,15 @@ void TunnelsPlayer::process_camera_rotation(double delta_time) { } void TunnelsPlayer::setup_player_input(PlayerInput *input) { - input->listen_to(PlayerInput::Listener("move_left", "move_right", callable_mp(this, &TunnelsPlayer::horizontal_move_input))); - input->listen_to(PlayerInput::Listener("move_forward", "move_backward", callable_mp(this, &TunnelsPlayer::vertical_move_input))); - input->listen_to(PlayerInput::Listener("fire", callable_mp(this, &TunnelsPlayer::fire_pressed))); - input->listen_to(PlayerInput::Listener("tactics_mode", callable_mp(this, &TunnelsPlayer::mode_switch_input))); + input->listen_to(PlayerInput::Listener("move_left", "move_right", this, "horizontal_move_input")); + input->listen_to(PlayerInput::Listener("move_forward", "move_backward", this, "vertical_move_input")); + input->listen_to(PlayerInput::Listener("fire", this, "fire_pressed")); } Node *TunnelsPlayer::to_node() { return Object::cast_to(this); } -void TunnelsPlayer::spawn_at_position(Transform3D const &at) { - this->character->set_global_transform(at); - this->set_global_basis(at.get_basis()); -} - void TunnelsPlayer::horizontal_move_input(Ref event, float value) { this->move_input.x = value; } @@ -128,70 +112,8 @@ void TunnelsPlayer::vertical_move_input(Ref event, float value) { this->move_input.y = value; } -void TunnelsPlayer::mode_switch_input(Ref event, float value) { - if(value != 0.f) - this->state = this->state == State::Tactics ? State::ManualControl : State::Tactics; -} - void TunnelsPlayer::fire_pressed(Ref event, float value) { - switch(this->state) { - case State::ManualControl: - this->character->set_firing(value != 0); - break; - case State::Tactics: - if(value == 1.f) - this->try_select_marker(); - break; - case State::Overview: - break; - } -} - -void TunnelsPlayer::try_select_marker() { - UtilityFunctions::print("TunnelsPlayer::try_select_marker()"); - Transform3D const &camera_trans{this->camera->get_global_transform()}; - // prepare raycast query - Ref params{PhysicsRayQueryParameters3D::create(camera_trans.origin, camera_trans.origin + this->mouse_world_ray_normal * 1000.f)}; - params->set_collision_mask(1u << 3u); - params->set_collide_with_areas(true); - // fetch current physics state and cast ray - PhysicsDirectSpaceState3D *state = this->get_world_3d()->get_direct_space_state(); - Dictionary dict{state->intersect_ray(params)}; - // fail if nothing was hit - if(dict.is_empty()) - return; - // attempt to cast hit node to a marker - GoalMarker *marker{Object::cast_to(dict["collider"])}; - // fail if hit object is not a marker - if(marker == nullptr) - return; - UtilityFunctions::print("Hit: ", marker->get_path()); - CharacterActor *target_character{nullptr}; - for(CharacterActor *loop_character : Ref(GameRoot::get_singleton()->get_game_mode())->get_player_characters()) { - if(loop_character != this->character) { - target_character = loop_character; - break; - } - } - // no non-player ally was found - if(target_character == nullptr) - return; - // cache planner component - goap::Planner *planner{target_character->get_planner()}; - // cache previous target in case planning fails - Node *previous_target{target_character->get_target()}; - // attempt to find a plan to marker's goal - target_character->set_target(marker); - if(planner->can_do(marker->get_goal())) { - planner->add_goal(marker->get_goal()); - planner->make_plan(); - target_character->force_update_action(); - UtilityFunctions::print("Made plan for character ", target_character->get_path()); - } else { - // reset character to the state it was in before attempts to change goal - UtilityFunctions::push_warning("Failed to make plan for ", marker->get_goal()->get_path()); - target_character->set_target(previous_target); - } + this->character->set_firing(value != 0); } void TunnelsPlayer::initialize_character() { @@ -201,7 +123,6 @@ void TunnelsPlayer::initialize_character() { return; if(player_scene->get_state()->get_node_type(0) != StringName("CharacterActor")) return; - UtilityFunctions::print("initialize_character pos: ", this->get_global_position()); // instantiate and store the player character this->character = Object::cast_to(player_scene->instantiate()); this->get_parent()->add_child(this->character); @@ -211,7 +132,6 @@ void TunnelsPlayer::initialize_character() { this->character->set_character_data(game_state->get_characters()[0]); // disable navmesh navigation and start using player input this->character->set_manual_mode(true); - Ref(GameRoot::get_singleton()->get_game_mode())->set_manual_character(this->character); } Vector3 TunnelsPlayer::get_world_move_input() const { @@ -255,6 +175,4 @@ CharacterActor *TunnelsPlayer::get_character() const { float const TunnelsPlayer::ROTATION_SPEED{0.5f}; float const TunnelsPlayer::ROTATION_Y_MIN_INFLUENCE{7.f}; float const TunnelsPlayer::ROTATION_MARGIN{0.4f}; -float const TunnelsPlayer::ROTATION_MARGIN_TACTICS_MUL{0.6f}; -float const TunnelsPlayer::TACTICS_MOVEMENT_SPEED{10.f}; } diff --git a/src/tunnels_player.hpp b/src/tunnels_player.hpp index 86c15f0..3e47485 100644 --- a/src/tunnels_player.hpp +++ b/src/tunnels_player.hpp @@ -1,7 +1,6 @@ #ifndef TUNNELS_PLAYER_HPP #define TUNNELS_PLAYER_HPP -#include "godot_cpp/variant/transform3d.hpp" #include "utils/player.hpp" #include "utils/player_input.hpp" #include @@ -23,7 +22,6 @@ class TunnelsPlayer : public Node3D, public IPlayer { }; public: - virtual void _enter_tree() override; virtual void _ready() override; virtual void _exit_tree() override; virtual void _process(double delta_time) override; @@ -33,14 +31,11 @@ public: virtual void setup_player_input(PlayerInput *input) override; virtual Node *to_node() override; - virtual void spawn_at_position(Transform3D const &at) override; void horizontal_move_input(Ref event, float value); void vertical_move_input(Ref event, float value); - void mode_switch_input(Ref event, float value); void fire_pressed(Ref event, float value); - void try_select_marker(); void initialize_character(); Vector3 get_world_move_input() const; @@ -64,9 +59,7 @@ private: static float const ROTATION_SPEED; static float const ROTATION_Y_MIN_INFLUENCE; - static float const ROTATION_MARGIN_TACTICS_MUL; static float const ROTATION_MARGIN; - static float const TACTICS_MOVEMENT_SPEED; }; } diff --git a/src/utils b/src/utils index d81ad91..f0bddcf 160000 --- a/src/utils +++ b/src/utils @@ -1 +1 @@ -Subproject commit d81ad91a885a74338c02edf1d52a2fa5aa8746b6 +Subproject commit f0bddcf074f040e6a02f70a26c58507580669327