diff --git a/Code/Factories/ComponentFactory.cs b/Code/Factories/ComponentFactory.cs index 395f733..79afd26 100644 --- a/Code/Factories/ComponentFactory.cs +++ b/Code/Factories/ComponentFactory.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; +using CryptonymThunder.Code.Extensions; using CryptonymThunder.Code.Resources; +using GameCore.AI; using GameCore.Attributes; using GameCore.Combat; using GameCore.Combat.Interfaces; @@ -46,6 +48,8 @@ public class ComponentFactory Register(res => new WorldIdComponent(res.WorldId)); Register(CreateButtonComponent); Register(CreateLogicSequenceComponent); + Register(CreateAIComponent); + Register(CreatePatrolComponent); } public IComponent Create(Resource resource) @@ -187,4 +191,25 @@ public class ComponentFactory return component; } + + private AIComponent CreateAIComponent(AIComponentResource resource) + { + return new AIComponent + { + CurrentState = resource.InitialState, + SightRange = resource.SightRange, + FieldOfView = resource.FieldOfView, + AttackRange = resource.AttackRange, + ChaseGiveUpTime = resource.ChaseGiveUpTime, + ReactionTime = resource.ReactionTime, + }; + } + + private PatrolComponent CreatePatrolComponent(PatrolComponentResource resource) + { + return new PatrolComponent + { + IsLooping = resource.IsLooping, + }; + } } \ No newline at end of file diff --git a/Code/Presenters/CharacterBody3DPresenter.cs b/Code/Presenters/CharacterBody3DPresenter.cs index 33b231f..d9a0d70 100644 --- a/Code/Presenters/CharacterBody3DPresenter.cs +++ b/Code/Presenters/CharacterBody3DPresenter.cs @@ -11,6 +11,8 @@ namespace CryptonymThunder.Code.Presenters; [GlobalClass] public partial class CharacterBody3DPresenter : CharacterBody3D, IEntityPresenter, IPresenterComponent { + [Export] private Node3D _muzzleNode; + private World _world; private VelocityComponent _velocity; private PositionComponent _position; @@ -30,7 +32,7 @@ public partial class CharacterBody3DPresenter : CharacterBody3D, IEntityPresente _rotation = _world.GetComponent(CoreEntity); _inputState = _world.GetComponent(CoreEntity); _characterState = _world.GetComponent(CoreEntity); - _camera = GetNode("CameraPivot/Camera3D"); + _camera = GetNodeOrNull("CameraPivot/Camera3D"); } public void SyncToPresentation(float delta) @@ -40,8 +42,12 @@ public partial class CharacterBody3DPresenter : CharacterBody3D, IEntityPresente var coreRotation = _rotation.Rotation; Rotation = new Vector3(Rotation.X, coreRotation.Y, Rotation.Z); } - - if (_velocity == null) return; + + if (_velocity == null) + { + _world.Logger.Warn("No VelocityComponent found for CharacterBody3DPresenter."); + return; + } var godotVelocity = Velocity; godotVelocity.X = _velocity.DesiredVelocity.X; @@ -57,10 +63,24 @@ public partial class CharacterBody3DPresenter : CharacterBody3D, IEntityPresente if (_position != null) _position.Position = GlobalPosition.ToGameCore(); if (_velocity != null) _velocity.ActualVelocity = Velocity.ToGameCore(); if (_characterState != null) _characterState.IsOnFloor = IsOnFloor(); - if (_inputState != null && _camera != null) + if (_inputState != null) { - _inputState.MuzzlePosition = _camera.GlobalPosition.ToGameCore(); - _inputState.MuzzleDirection = (-_camera.GlobalTransform.Basis.Z).ToGameCore(); + if (_camera != null) + { + _inputState.MuzzlePosition = _camera.GlobalPosition.ToGameCore(); + _inputState.MuzzleDirection = (-_camera.GlobalTransform.Basis.Z).ToGameCore(); + } + else + { + if (_muzzleNode != null) + { + _inputState.MuzzlePosition = _muzzleNode.GlobalPosition.ToGameCore(); + } + else + { + _inputState.MuzzlePosition = GlobalPosition.ToGameCore(); + } + } } } } \ No newline at end of file diff --git a/Code/Presenters/GamePresenter.cs b/Code/Presenters/GamePresenter.cs index 00130a5..5484a90 100644 --- a/Code/Presenters/GamePresenter.cs +++ b/Code/Presenters/GamePresenter.cs @@ -4,6 +4,7 @@ using CryptonymThunder.Code.Autoloads; using CryptonymThunder.Code.Factories; using CryptonymThunder.Code.Resources; using CryptonymThunder.Code.Services; +using GameCore.AI; using GameCore.Attributes; using GameCore.Combat; using GameCore.Config; @@ -101,6 +102,11 @@ public partial class GamePresenter : Node _world.RegisterSystem(new HealingSystem(_world)); _world.RegisterSystem(new DamageSystem(_world)); + + _world.RegisterSystem(new AIPerceptionSystem()); + _world.RegisterSystem(new AIPathfindingSystem()); + _world.RegisterSystem(new AIAimSystem()); + _world.RegisterSystem(new ProjectileCleanupSystem()); _world.RegisterSystem(new DestructionSystem()); @@ -112,6 +118,8 @@ public partial class GamePresenter : Node var playerData = _presenterFactory.CreateEntityFromArchetype(PlayerArchetype); _presenters.Add(playerData.Entity.Id, playerData.Presenter); _presenterComponents.Add(playerData.Entity.Id, playerData.Components); + + _world.GameState.SetStatus(GameStatus.InGame); } public override void _Input(InputEvent @event) diff --git a/Code/Presenters/PatrolComponentPresenter.cs b/Code/Presenters/PatrolComponentPresenter.cs new file mode 100644 index 0000000..a37c32f --- /dev/null +++ b/Code/Presenters/PatrolComponentPresenter.cs @@ -0,0 +1,38 @@ +using CryptonymThunder.Code.Extensions; +using GameCore.AI; +using GameCore.ECS; +using GameCore.ECS.Interfaces; +using Godot; +using Godot.Collections; + +namespace CryptonymThunder.Code.Presenters; + +[GlobalClass] +public partial class PatrolComponentPresenter : Node, IPresenterComponent +{ + [Export] public Array PatrolPoints { get; set; }= []; + + public void Initialize(Entity coreEntity, World world) + { + var patrolComponent = world.GetComponent(coreEntity); + if (patrolComponent == null) + { + world.Logger.Warn($"Entity '{coreEntity.Id}' does not have a PatrolComponent."); + return; + } + + patrolComponent.PatrolPoints.Clear(); + foreach (var marker in PatrolPoints) + { + patrolComponent.PatrolPoints.Add(marker.GlobalPosition.ToGameCore()); + } + } + + public void SyncToPresentation(float delta) + { + } + + public void SyncToCore(float delta) + { + } +} \ No newline at end of file diff --git a/Code/Presenters/PatrolComponentPresenter.cs.uid b/Code/Presenters/PatrolComponentPresenter.cs.uid new file mode 100644 index 0000000..fc34189 --- /dev/null +++ b/Code/Presenters/PatrolComponentPresenter.cs.uid @@ -0,0 +1 @@ +uid://b583iynr5p62n diff --git a/Code/Resources/AIComponentResource.cs b/Code/Resources/AIComponentResource.cs new file mode 100644 index 0000000..d7e6c03 --- /dev/null +++ b/Code/Resources/AIComponentResource.cs @@ -0,0 +1,17 @@ +using GameCore.AI; +using Godot; + +namespace CryptonymThunder.Code.Resources; + +[GlobalClass] +public partial class AIComponentResource : Resource +{ + [Export] public AIState InitialState { get; set; } = AIState.Idle; + + [ExportGroup("Personality")] + [Export(PropertyHint.Range, "1.0, 100.0, 0.1")] public float SightRange { get; set; } = 20f; + [Export(PropertyHint.Range, "1.0, 180.0, 0.1")] public float FieldOfView { get; set; } = 90f; // In degrees + [Export(PropertyHint.Range, "0.1, 100.0, 0.1")] public float AttackRange { get; set; } = 10f; + [Export(PropertyHint.Range, "0.0, 30.0, 0.1")] public float ChaseGiveUpTime { get; set; } = 5.0f; // Time to chase after losing sight + [Export(PropertyHint.Range, "0.0, 5.0, 0.05")] public float ReactionTime { get; set; } = 0.5f; // Delay before seeing player +} \ No newline at end of file diff --git a/Code/Resources/AIComponentResource.cs.uid b/Code/Resources/AIComponentResource.cs.uid new file mode 100644 index 0000000..edb9e90 --- /dev/null +++ b/Code/Resources/AIComponentResource.cs.uid @@ -0,0 +1 @@ +uid://cq6c0en5gw7ia diff --git a/Code/Resources/PatrolComponentResource.cs b/Code/Resources/PatrolComponentResource.cs new file mode 100644 index 0000000..93f9e57 --- /dev/null +++ b/Code/Resources/PatrolComponentResource.cs @@ -0,0 +1,10 @@ +using Godot; +using Godot.Collections; + +namespace CryptonymThunder.Code.Resources; + +[GlobalClass] +public partial class PatrolComponentResource : Resource +{ + [Export] public bool IsLooping { get; set; } = false; +} \ No newline at end of file diff --git a/Code/Resources/PatrolComponentResource.cs.uid b/Code/Resources/PatrolComponentResource.cs.uid new file mode 100644 index 0000000..a2d6801 --- /dev/null +++ b/Code/Resources/PatrolComponentResource.cs.uid @@ -0,0 +1 @@ +uid://dknbh3vlew4v5 diff --git a/Code/Services/GodotAudioService.cs.uid b/Code/Services/GodotAudioService.cs.uid new file mode 100644 index 0000000..4bb4e50 --- /dev/null +++ b/Code/Services/GodotAudioService.cs.uid @@ -0,0 +1 @@ +uid://brwkqiox7aijm diff --git a/Code/Services/GodotParticleService.cs.uid b/Code/Services/GodotParticleService.cs.uid new file mode 100644 index 0000000..4c65153 --- /dev/null +++ b/Code/Services/GodotParticleService.cs.uid @@ -0,0 +1 @@ +uid://dyyu7jl3gfjpg diff --git a/Code/Services/GodotWorldQuery.cs b/Code/Services/GodotWorldQuery.cs index f074db3..c81f137 100644 --- a/Code/Services/GodotWorldQuery.cs +++ b/Code/Services/GodotWorldQuery.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using CryptonymThunder.Code.Autoloads; using CryptonymThunder.Code.Extensions; using CryptonymThunder.Code.Presenters; @@ -101,4 +102,12 @@ public class GodotWorldQuery(GamePresenter ownerNode) : IWorldQuery } } } + + public List GetPath(Vector3 start, Vector3 end) + { + var map = _godotWorld.NavigationMap; + var pathPoints = NavigationServer3D.MapGetPath(map, start.ToGodot(), end.ToGodot(), true); + + return pathPoints.Select(p => p.ToGameCore()).ToList(); + } } \ No newline at end of file diff --git a/Models/Character Enemy.glb b/Models/Character Enemy.glb new file mode 100644 index 0000000..722e86f Binary files /dev/null and b/Models/Character Enemy.glb differ diff --git a/Models/Character Enemy.glb.import b/Models/Character Enemy.glb.import new file mode 100644 index 0000000..c292eef --- /dev/null +++ b/Models/Character Enemy.glb.import @@ -0,0 +1,42 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://d1h1fhxmbdjus" +path="res://.godot/imported/Character Enemy.glb-4b0b69a2e73ec600948328b5031362d9.scn" + +[deps] + +source_file="res://Models/Character Enemy.glb" +dest_files=["res://.godot/imported/Character Enemy.glb-4b0b69a2e73ec600948328b5031362d9.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="" +nodes/root_script=null +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +nodes/use_name_suffixes=true +nodes/use_node_type_suffixes=true +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 +animation/import_rest_as_RESET=false +import_script/path="" +materials/extract=0 +materials/extract_format=0 +materials/extract_path="" +_subresources={} +gltf/naming_version=2 +gltf/embedded_image_handling=1 diff --git a/Models/Pistol.glb b/Models/Pistol.glb new file mode 100644 index 0000000..46ebf0a Binary files /dev/null and b/Models/Pistol.glb differ diff --git a/Models/Pistol.glb.import b/Models/Pistol.glb.import new file mode 100644 index 0000000..6455a1c --- /dev/null +++ b/Models/Pistol.glb.import @@ -0,0 +1,42 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://dnvm48evffkym" +path="res://.godot/imported/Pistol.glb-ded06dd2bffc2ef90a3d18fe45accadf.scn" + +[deps] + +source_file="res://Models/Pistol.glb" +dest_files=["res://.godot/imported/Pistol.glb-ded06dd2bffc2ef90a3d18fe45accadf.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="" +nodes/root_script=null +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +nodes/use_name_suffixes=true +nodes/use_node_type_suffixes=true +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 +animation/import_rest_as_RESET=false +import_script/path="" +materials/extract=0 +materials/extract_format=0 +materials/extract_path="" +_subresources={} +gltf/naming_version=2 +gltf/embedded_image_handling=1 diff --git a/Objects/enemy_ai.tscn b/Objects/enemy_ai.tscn new file mode 100644 index 0000000..2cc896c --- /dev/null +++ b/Objects/enemy_ai.tscn @@ -0,0 +1,96 @@ +[gd_scene load_steps=27 format=3 uid="uid://c52xl2srv7vg5"] + +[ext_resource type="Script" uid="uid://hkiny1ftv4r7" path="res://Code/Presenters/CharacterBody3DPresenter.cs" id="1_1hk3o"] +[ext_resource type="PackedScene" uid="uid://d1h1fhxmbdjus" path="res://Models/Character Enemy.glb" id="2_fhco6"] +[ext_resource type="Script" uid="uid://b6x8llipvutqs" path="res://Code/Presenters/SceneEntity.cs" id="3_vwa28"] +[ext_resource type="Script" uid="uid://df5wmj1jp2oy5" path="res://Code/Resources/PositionComponentResource.cs" id="4_s341x"] +[ext_resource type="Script" uid="uid://blm62f85g7icn" path="res://Code/Resources/RotationComponentResource.cs" id="5_egcsl"] +[ext_resource type="Script" uid="uid://y4cbuh2wxigy" path="res://Code/Resources/InputStateComponentResource.cs" id="6_50v7i"] +[ext_resource type="Script" uid="uid://cht6trljihvle" path="res://Code/Resources/Effects/FireProjectileEffectResource.cs" id="7_w3mrt"] +[ext_resource type="Script" uid="uid://hf0iut8o8do3" path="res://Code/Resources/WeaponResource.cs" id="8_vsm2y"] +[ext_resource type="Script" uid="uid://bp7mufswr41w6" path="res://Code/Resources/WeaponComponentResource.cs" id="9_dof3w"] +[ext_resource type="Script" uid="uid://cq6c0en5gw7ia" path="res://Code/Resources/AIComponentResource.cs" id="10_qcp8w"] +[ext_resource type="Script" uid="uid://dknbh3vlew4v5" path="res://Code/Resources/PatrolComponentResource.cs" id="11_24ld1"] +[ext_resource type="Script" uid="uid://dc7wq2ij5kwj5" path="res://Code/Resources/AttributeComponentResource.cs" id="12_fhco6"] +[ext_resource type="Script" uid="uid://t4j1urlupxxv" path="res://Code/Resources/VelocityComponentResource.cs" id="13_s341x"] +[ext_resource type="Script" uid="uid://cdpbn8eiypfbd" path="res://Code/Resources/CharacterStateComponentResource.cs" id="14_egcsl"] + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_tm0j5"] +height = 2.6 + +[sub_resource type="Resource" id="Resource_7qdsq"] +script = ExtResource("4_s341x") +metadata/_custom_type_script = "uid://df5wmj1jp2oy5" + +[sub_resource type="Resource" id="Resource_s7syo"] +script = ExtResource("5_egcsl") +metadata/_custom_type_script = "uid://blm62f85g7icn" + +[sub_resource type="Resource" id="Resource_g7qmq"] +script = ExtResource("6_50v7i") +metadata/_custom_type_script = "uid://y4cbuh2wxigy" + +[sub_resource type="Resource" id="Resource_44i0g"] +script = ExtResource("7_w3mrt") +ProjectileArchetypeId = "basic_bullet" +ProjectileSpeed = 5.0 +metadata/_custom_type_script = "uid://cht6trljihvle" + +[sub_resource type="Resource" id="Resource_xigcj"] +script = ExtResource("8_vsm2y") +FireCosts = null +OnFireEffects = Array[Object]([SubResource("Resource_44i0g")]) +OnHitEffects = null +metadata/_custom_type_script = "uid://hf0iut8o8do3" + +[sub_resource type="Resource" id="Resource_fjq05"] +script = ExtResource("9_dof3w") +WeaponData = SubResource("Resource_xigcj") +metadata/_custom_type_script = "uid://bp7mufswr41w6" + +[sub_resource type="Resource" id="Resource_1cf6p"] +script = ExtResource("10_qcp8w") +metadata/_custom_type_script = "uid://cq6c0en5gw7ia" + +[sub_resource type="Resource" id="Resource_jfe8j"] +script = ExtResource("11_24ld1") +IsLooping = true +metadata/_custom_type_script = "uid://dknbh3vlew4v5" + +[sub_resource type="Resource" id="Resource_vwa28"] +script = ExtResource("12_fhco6") +BaseValues = Dictionary[int, float]({ +0: 15.0, +1: 100.0, +3: 1.0, +4: 2.0, +5: 9.0 +}) +metadata/_custom_type_script = "uid://dc7wq2ij5kwj5" + +[sub_resource type="Resource" id="Resource_50v7i"] +script = ExtResource("13_s341x") +metadata/_custom_type_script = "uid://t4j1urlupxxv" + +[sub_resource type="Resource" id="Resource_w3mrt"] +script = ExtResource("14_egcsl") +metadata/_custom_type_script = "uid://cdpbn8eiypfbd" + +[node name="Enemy AI" type="CharacterBody3D" node_paths=PackedStringArray("_muzzleNode")] +script = ExtResource("1_1hk3o") +_muzzleNode = NodePath("Muzzle") +metadata/_custom_type_script = "uid://hkiny1ftv4r7" + +[node name="Muzzle" type="Marker3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.28748727, 0.7570933, 1.7204188) + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9892893, 0) +shape = SubResource("CapsuleShape3D_tm0j5") + +[node name="Root Scene" parent="." instance=ExtResource("2_fhco6")] + +[node name="SceneEntity" type="Node" parent="." groups=["SceneEntities"]] +script = ExtResource("3_vwa28") +ComponentResources = Array[Resource]([SubResource("Resource_7qdsq"), SubResource("Resource_s7syo"), SubResource("Resource_g7qmq"), SubResource("Resource_fjq05"), SubResource("Resource_1cf6p"), SubResource("Resource_jfe8j"), SubResource("Resource_vwa28"), SubResource("Resource_50v7i"), SubResource("Resource_w3mrt")]) +metadata/_custom_type_script = "uid://b6x8llipvutqs" diff --git a/Scenes/game_world.tscn b/Scenes/game_world.tscn index 46c9b1a..62021a5 100644 --- a/Scenes/game_world.tscn +++ b/Scenes/game_world.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=34 format=4 uid="uid://bkvgcsb8d3v7p"] +[gd_scene load_steps=37 format=4 uid="uid://bkvgcsb8d3v7p"] [ext_resource type="Script" uid="uid://cfpm5p102f65x" path="res://Code/Presenters/GamePresenter.cs" id="1_qvgq0"] [ext_resource type="Resource" uid="uid://biev6ri5s8kyf" path="res://Resources/Entities/player.tres" id="2_alii3"] @@ -18,19 +18,25 @@ [ext_resource type="Script" uid="uid://dngi4w4ae8wyr" path="res://Code/Resources/OpenDoorActionResource.cs" id="16_vpkaq"] [ext_resource type="Script" uid="uid://c4csquqmqqqww" path="res://Code/Resources/LogicSequenceComponentResource.cs" id="17_df4ul"] [ext_resource type="Script" uid="uid://d3u3q5yhenegb" path="res://Code/Resources/CloseDoorActionResource.cs" id="17_q0a86"] +[ext_resource type="PackedScene" uid="uid://c52xl2srv7vg5" path="res://Objects/enemy_ai.tscn" id="19_q0a86"] +[ext_resource type="Script" uid="uid://b583iynr5p62n" path="res://Code/Presenters/PatrolComponentPresenter.cs" id="20_3hp7m"] -[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_ucfah"] -data = PackedVector3Array(-4.282257, -0.5, 4.977783, -4.282257, -0.5, -4.977783, -4.282257, 0.5, -4.977783, 4.282257, -0.5, -4.977783, -4.282257, -0.5, -4.977783, -4.282257, -0.5, 4.977783, -4.282257, 0.5, -4.977783, -4.282257, -0.5, -4.977783, 4.282257, -0.5, -4.977783, -4.282257, 0.5, -4.977783, -4.282257, 0.5, 4.977783, -4.282257, -0.5, 4.977783, -4.282257, -0.5, 4.977783, -4.282257, 0.5, 4.977783, 4.282257, 0.5, 4.977783, 4.282257, 0.5, 4.977783, -4.282257, 0.5, 4.977783, -4.282257, 0.5, -4.977783, -4.282257, -0.5, 4.977783, 4.282257, -0.5, 4.977783, 4.282257, -0.5, -4.977783, 4.282257, 0.5, 4.977783, 4.282257, -0.5, 4.977783, -4.282257, -0.5, 4.977783, 4.282257, -0.5, -4.977783, 4.282257, -0.5, 4.977783, 4.282257, 0.5, 4.977783, 4.282257, -0.5, -4.977783, 4.282257, 0.5, -4.977783, -4.282257, 0.5, -4.977783, -4.282257, 0.5, -4.977783, 4.282257, 0.5, -4.977783, 4.282257, 0.5, 4.977783, 4.282257, 0.5, 4.977783, 4.282257, 0.5, -4.977783, 4.282257, -0.5, -4.977783) +[sub_resource type="NavigationMesh" id="NavigationMesh_q0a86"] +vertices = PackedVector3Array(-12.066559, 0.14160275, -15.827454, -12.066559, 0.14160275, 10.172546, 12.183441, 0.14160275, 10.172546, 12.183441, 0.14160275, -15.827454) +polygons = [PackedInt32Array(3, 2, 0), PackedInt32Array(0, 2, 1)] -[sub_resource type="ArrayMesh" id="ArrayMesh_ucfah"] +[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_df4ul"] +data = PackedVector3Array(-12.6594925, -0.5, 13.537674, -12.6594925, -0.5, -13.537674, -12.6594925, 0.5, -13.537674, 12.6594925, -0.5, -13.537674, -12.6594925, -0.5, -13.537674, -12.6594925, -0.5, 13.537674, -12.6594925, 0.5, -13.537674, -12.6594925, -0.5, -13.537674, 12.6594925, -0.5, -13.537674, -12.6594925, 0.5, -13.537674, -12.6594925, 0.5, 13.537674, -12.6594925, -0.5, 13.537674, -12.6594925, -0.5, 13.537674, -12.6594925, 0.5, 13.537674, 12.6594925, 0.5, 13.537674, 12.6594925, 0.5, 13.537674, -12.6594925, 0.5, 13.537674, -12.6594925, 0.5, -13.537674, -12.6594925, -0.5, 13.537674, 12.6594925, -0.5, 13.537674, 12.6594925, -0.5, -13.537674, 12.6594925, 0.5, 13.537674, 12.6594925, -0.5, 13.537674, -12.6594925, -0.5, 13.537674, 12.6594925, -0.5, -13.537674, 12.6594925, -0.5, 13.537674, 12.6594925, 0.5, 13.537674, 12.6594925, -0.5, -13.537674, 12.6594925, 0.5, -13.537674, -12.6594925, 0.5, -13.537674, -12.6594925, 0.5, -13.537674, 12.6594925, 0.5, -13.537674, 12.6594925, 0.5, 13.537674, 12.6594925, 0.5, 13.537674, 12.6594925, 0.5, -13.537674, 12.6594925, -0.5, -13.537674) + +[sub_resource type="ArrayMesh" id="ArrayMesh_q0a86"] _surfaces = [{ -"aabb": AABB(-4.282257, -0.5, -4.977783, 8.564514, 1, 9.955566), +"aabb": AABB(-12.6594925, -0.5, -13.537674, 25.318985, 1, 27.075348), "attribute_data": PackedByteArray("AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/"), "format": 34359738391, "primitive": 3, "uv_scale": Vector4(0, 0, 0, 0), "vertex_count": 36, -"vertex_data": PackedByteArray("QAiJwAAAAL8ASp9AQAiJwAAAAL8ASp/AQAiJwAAAAD8ASp/AQAiJQAAAAL8ASp/AQAiJwAAAAL8ASp/AQAiJwAAAAL8ASp9AQAiJwAAAAD8ASp/AQAiJwAAAAL8ASp/AQAiJQAAAAL8ASp/AQAiJwAAAAD8ASp/AQAiJwAAAAD8ASp9AQAiJwAAAAL8ASp9AQAiJwAAAAL8ASp9AQAiJwAAAAD8ASp9AQAiJQAAAAD8ASp9AQAiJQAAAAD8ASp9AQAiJwAAAAD8ASp9AQAiJwAAAAD8ASp/AQAiJwAAAAL8ASp9AQAiJQAAAAL8ASp9AQAiJQAAAAL8ASp/AQAiJQAAAAD8ASp9AQAiJQAAAAL8ASp9AQAiJwAAAAL8ASp9AQAiJQAAAAL8ASp/AQAiJQAAAAL8ASp9AQAiJQAAAAD8ASp9AQAiJQAAAAL8ASp/AQAiJQAAAAD8ASp/AQAiJwAAAAD8ASp/AQAiJwAAAAD8ASp/AQAiJQAAAAD8ASp/AQAiJQAAAAD8ASp9AQAiJQAAAAD8ASp9AQAiJQAAAAD8ASp/AQAiJQAAAAL8ASp/AAAD/f/9//n8AAP9//3/+fwAA/3//f/5//38AAP//AAD/fwAA//8AAP9/AAD//wAA/////wAA/z//////AAD/P/////8AAP8/AAD/f/9//n8AAP9//3/+fwAA/3//f/5//3//fwAA/z//f/9/AAD/P/9//38AAP8//3//////AAD/f/////8AAP9//////wAA/38AAP//AAD/fwAA//8AAP9/AAD//wAA/3//fwAA/z//f/9/AAD/P/9//38AAP8/////f/9//n////9//3/+f////3//f/5//////wAA/z//////AAD/P/////8AAP8//3//////AAD/f/////8AAP9//////wAA////f/9//n////9//3/+f////3//f/5/") +"vertex_data": PackedByteArray("SI1KwQAAAL9QmlhBSI1KwQAAAL9QmljBSI1KwQAAAD9QmljBSI1KQQAAAL9QmljBSI1KwQAAAL9QmljBSI1KwQAAAL9QmlhBSI1KwQAAAD9QmljBSI1KwQAAAL9QmljBSI1KQQAAAL9QmljBSI1KwQAAAD9QmljBSI1KwQAAAD9QmlhBSI1KwQAAAL9QmlhBSI1KwQAAAL9QmlhBSI1KwQAAAD9QmlhBSI1KQQAAAD9QmlhBSI1KQQAAAD9QmlhBSI1KwQAAAD9QmlhBSI1KwQAAAD9QmljBSI1KwQAAAL9QmlhBSI1KQQAAAL9QmlhBSI1KQQAAAL9QmljBSI1KQQAAAD9QmlhBSI1KQQAAAL9QmlhBSI1KwQAAAL9QmlhBSI1KQQAAAL9QmljBSI1KQQAAAL9QmlhBSI1KQQAAAD9QmlhBSI1KQQAAAL9QmljBSI1KQQAAAD9QmljBSI1KwQAAAD9QmljBSI1KwQAAAD9QmljBSI1KQQAAAD9QmljBSI1KQQAAAD9QmlhBSI1KQQAAAD9QmlhBSI1KQQAAAD9QmljBSI1KQQAAAL9QmljBAAD/f/9//n8AAP9//3/+fwAA/3//f/5//38AAP//AAD/fwAA//8AAP9/AAD//wAA/////wAA/z//////AAD/P/////8AAP8/AAD/f/9//n8AAP9//3/+fwAA/3//f/5//3//fwAA/z//f/9/AAD/P/9//38AAP8//3//////AAD/f/////8AAP9//////wAA/38AAP//AAD/fwAA//8AAP9/AAD//wAA/3//fwAA/z//f/9/AAD/P/9//38AAP8/////f/9//n////9//3/+f////3//f/5//////wAA/z//////AAD/P/////8AAP8//3//////AAD/f/////8AAP9//////wAA////f/9//n////9//3/+f////3//f/5/") }] [sub_resource type="SphereMesh" id="SphereMesh_27os8"] @@ -92,18 +98,23 @@ metadata/_custom_type_script = "uid://c4csquqmqqqww" [node name="Geometry" type="Node" parent="."] [node name="CSGBox3D" type="CSGBox3D" parent="Geometry"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.23013306, 0, 0.34545898) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.092933655, 15.962494, -2.7897797) visible = false -size = Vector3(8.564514, 1, 9.955566) +size = Vector3(25.318985, 1, 27.075348) -[node name="CSGBakedMeshInstance3D" type="StaticBody3D" parent="Geometry"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.23013306, -1.5645537, 0.34545898) +[node name="NavigationRegion3D" type="NavigationRegion3D" parent="Geometry"] +navigation_mesh = SubResource("NavigationMesh_q0a86") -[node name="CSGBakedCollisionShape3D" type="CollisionShape3D" parent="Geometry/CSGBakedMeshInstance3D"] -shape = SubResource("ConcavePolygonShape3D_ucfah") +[node name="StaticBody3D" type="StaticBody3D" parent="Geometry/NavigationRegion3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.73305273, 0) -[node name="CSGBakedMeshInstance3D2" type="MeshInstance3D" parent="Geometry/CSGBakedMeshInstance3D"] -mesh = SubResource("ArrayMesh_ucfah") +[node name="CSGBakedCollisionShape3D" type="CollisionShape3D" parent="Geometry/NavigationRegion3D/StaticBody3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.092933655, 0, -2.7897797) +shape = SubResource("ConcavePolygonShape3D_df4ul") + +[node name="CSGBakedMeshInstance3D" type="MeshInstance3D" parent="Geometry/NavigationRegion3D/StaticBody3D"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.092933655, -0.8753445, -2.7897797) +mesh = SubResource("ArrayMesh_q0a86") skeleton = NodePath("../../..") [node name="MeshInstance3D" type="MeshInstance3D" parent="Geometry"] @@ -267,10 +278,10 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.5896075, -0.81455386, -3.99 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.4061804, -0.56455374, 4.434821) [node name="Knife" parent="." instance=ExtResource("11_l855d")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.7087288, -0.8145535, 4.6141477) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.7087288, -0.03280258, 4.6141477) [node name="Pistol" parent="." instance=ExtResource("12_00aki")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.122588, -0.81455374, 1.582226) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.122588, 0.07612455, 1.582226) [node name="GreenDoor" parent="." instance=ExtResource("13_00aki")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.8655286, -0.0645535, 5.593994) @@ -289,3 +300,19 @@ metadata/_custom_type_script = "uid://cb7vaw6xqjs1i" script = ExtResource("5_f1ejf") ComponentResources = Array[Resource]([SubResource("Resource_3hp7m")]) metadata/_custom_type_script = "uid://b6x8llipvutqs" + +[node name="Enemy AI" parent="." instance=ExtResource("19_q0a86")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.73215866, -1.0429426, -12.651663) + +[node name="PatrolComponentPresenter" type="Node" parent="Enemy AI" node_paths=PackedStringArray("PatrolPoints")] +script = ExtResource("20_3hp7m") +PatrolPoints = [NodePath("../../PatrolPoints/Marker3D"), NodePath("../../PatrolPoints/Marker3D2")] +metadata/_custom_type_script = "uid://b583iynr5p62n" + +[node name="PatrolPoints" type="Node3D" parent="."] + +[node name="Marker3D" type="Marker3D" parent="PatrolPoints"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -12.76429) + +[node name="Marker3D2" type="Marker3D" parent="PatrolPoints"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.840687, 0, -12.76429)