From 6620c86f5790d61657302ddbb87d3a00a35cfef1 Mon Sep 17 00:00:00 2001 From: Zenny Date: Sat, 13 Jun 2026 21:42:42 -0700 Subject: [PATCH] Additional collision/avoidance changes for monstos --- .../src/enemy/behaviors/FleeBehavior.cs | 1 - .../enemy/enemy_types/02. michael/Michael.cs | 37 +++--- .../enemy_types/03. filth_eater/FilthEater.cs | 3 +- .../03. filth_eater/FilthEater.tscn | 114 ++++++++++-------- .../enemy_types/07. chinthe/Chinthe.tscn | 6 +- .../07. chinthe/ChintheModelView.tscn | 4 +- .../enemy_types/10. Eden Pillar/EdenPillar.cs | 103 ++++++++-------- .../states/EnemyLogic.State.EngagePlayer.cs | 4 + .../states/EnemyLogic.State.FollowPlayer.cs | 2 + .../states/EnemyLogic.State.Patrolling.cs | 2 + Zennysoft.Game.Ma/src/items/ItemDatabase.cs | 1 - Zennysoft.Game.Ma/src/map/Map.cs | 12 +- .../src/map/dungeon/code/MonsterRoom.cs | 17 ++- .../rooms/Set B/25. Pedestal Room.tscn | 2 + 14 files changed, 170 insertions(+), 138 deletions(-) diff --git a/Zennysoft.Game.Ma/src/enemy/behaviors/FleeBehavior.cs b/Zennysoft.Game.Ma/src/enemy/behaviors/FleeBehavior.cs index 472241df..38ea2ead 100644 --- a/Zennysoft.Game.Ma/src/enemy/behaviors/FleeBehavior.cs +++ b/Zennysoft.Game.Ma/src/enemy/behaviors/FleeBehavior.cs @@ -55,6 +55,5 @@ public partial class FleeBehavior : Node3D, IBehavior var parent = GetParent() as Node3D; var velocity = parent.GlobalPosition.DirectionTo(nextVelocity) * (float)FleeSpeed * (float)delta; _navigationAgent.Velocity = velocity; - //EmitSignal(SignalName.OnVelocityComputed, velocity); } } diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/02. michael/Michael.cs b/Zennysoft.Game.Ma/src/enemy/enemy_types/02. michael/Michael.cs index 00e6a3a6..2027457d 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/02. michael/Michael.cs +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/02. michael/Michael.cs @@ -1,7 +1,6 @@ using Chickensoft.AutoInject; using Chickensoft.Introspection; using Godot; -using System.Linq; namespace Zennysoft.Game.Ma; @@ -19,33 +18,33 @@ public partial class Michael : Enemy2D, IHavePatrolBehavior, IHaveEngagePlayerBe public void OnReady() { - FollowBehavior.Init(NavigationAgent); - PatrolBehavior.Init(NavigationAgent); - PatrolBehavior.HomePosition = GlobalPosition; - PatrolBehavior.OnVelocityComputed += OnVelocityComputed; - FollowBehavior.OnVelocityComputed += OnVelocityComputed; - EngagePlayerBehavior.TakeAction += EngagePlayerBehavior_TakeAction; - EngagePlayerBehavior.AcquireTarget += EngagePlayerBehavior_AcquireTarget; - PlayerDetector.BodyEntered += PlayerDetector_BodyEntered; - PlayerDetector.BodyExited += PlayerDetector_BodyExited; - SetPhysicsProcess(true); + FollowBehavior.Init(NavigationAgent); + PatrolBehavior.Init(NavigationAgent); + PatrolBehavior.HomePosition = GlobalPosition; + PatrolBehavior.OnVelocityComputed += OnVelocityComputed; + FollowBehavior.OnVelocityComputed += OnVelocityComputed; + EngagePlayerBehavior.TakeAction += EngagePlayerBehavior_TakeAction; + EngagePlayerBehavior.AcquireTarget += EngagePlayerBehavior_AcquireTarget; + PlayerDetector.BodyEntered += PlayerDetector_BodyEntered; + PlayerDetector.BodyExited += PlayerDetector_BodyExited; + SetPhysicsProcess(true); } public void OnResolved() { - _enemyLogic.Input(new EnemyLogic.Input.Patrol()); + _enemyLogic.Input(new EnemyLogic.Input.Patrol()); } public override void Move() => EnemyModelView.PlayIdleAnimation(); public new void OnExitTree() { - base.OnExitTree(); - PatrolBehavior.OnVelocityComputed -= OnVelocityComputed; - FollowBehavior.OnVelocityComputed -= OnVelocityComputed; - EngagePlayerBehavior.TakeAction -= EngagePlayerBehavior_TakeAction; - EngagePlayerBehavior.AcquireTarget -= EngagePlayerBehavior_AcquireTarget; - PlayerDetector.BodyEntered -= PlayerDetector_BodyEntered; - PlayerDetector.BodyExited -= PlayerDetector_BodyExited; + base.OnExitTree(); + PatrolBehavior.OnVelocityComputed -= OnVelocityComputed; + FollowBehavior.OnVelocityComputed -= OnVelocityComputed; + EngagePlayerBehavior.TakeAction -= EngagePlayerBehavior_TakeAction; + EngagePlayerBehavior.AcquireTarget -= EngagePlayerBehavior_AcquireTarget; + PlayerDetector.BodyEntered -= PlayerDetector_BodyEntered; + PlayerDetector.BodyExited -= PlayerDetector_BodyExited; } } diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/03. filth_eater/FilthEater.cs b/Zennysoft.Game.Ma/src/enemy/enemy_types/03. filth_eater/FilthEater.cs index 5b678a99..3fc8f877 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/03. filth_eater/FilthEater.cs +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/03. filth_eater/FilthEater.cs @@ -36,14 +36,13 @@ public partial class FilthEater : Enemy2D, IHavePatrolBehavior, IHaveEngagePlaye public void OnResolved() { - _enemyLogic.Input(new EnemyLogic.Input.Activate()); _enemyLogic.Input(new EnemyLogic.Input.Patrol()); } public override void PerformAction() { var enemyPosition = new Vector3(GlobalPosition.X, _player.GlobalPosition.Y, GlobalPosition.Z); - if (enemyPosition.DistanceTo(_player.GlobalPosition) > 3) + if (enemyPosition.DistanceTo(_player.GlobalPosition) > 1) EnemyModelView.PlaySecondaryAttackAnimation(); else EnemyModelView.PlayPrimaryAttackAnimation(); diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/03. filth_eater/FilthEater.tscn b/Zennysoft.Game.Ma/src/enemy/enemy_types/03. filth_eater/FilthEater.tscn index e663b0ab..44b34fdc 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/03. filth_eater/FilthEater.tscn +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/03. filth_eater/FilthEater.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=16 format=3 uid="uid://bl426uws0i86l"] +[gd_scene load_steps=18 format=3 uid="uid://bl426uws0i86l"] [ext_resource type="Script" uid="uid://cohal8w5ceneg" path="res://src/enemy/enemy_types/03. filth_eater/FilthEater.cs" id="1_p438s"] +[ext_resource type="Script" uid="uid://bei3s7yr6xkc0" path="res://src/enemy/EnemyLootTable.cs" id="3_g602r"] [ext_resource type="PackedScene" uid="uid://b6sa6ntu4rbrm" path="res://src/enemy/enemy_types/03. filth_eater/FilthEaterModelView.tscn" id="3_rrwed"] [ext_resource type="Script" uid="uid://dlsgyx4i1jmp3" path="res://src/enemy/EnemyLoreInfo.cs" id="4_5eid5"] [ext_resource type="PackedScene" uid="uid://cn4fv2gv6raql" path="res://src/enemy/behaviors/PatrolBehavior.tscn" id="5_pvjvo"] @@ -9,18 +10,12 @@ [ext_resource type="AudioStream" uid="uid://ba8xendacec6" path="res://src/audio/sfx/item_kyuu_layer_2.ogg" id="7_qbmfg"] [ext_resource type="AudioStream" uid="uid://b7ycb6qvitpmw" path="res://src/audio/sfx/player_HITENEMY_3.ogg" id="8_m7220"] [ext_resource type="AudioStream" uid="uid://bf7adfdd857hw" path="res://src/audio/sfx/enemy_morph.ogg" id="9_g602r"] -[ext_resource type="AudioStream" uid="uid://6r74nka4oh20" path="res://src/audio/sfx/ENEMY_filth_aggro.ogg" id="11_qbmfg"] +[ext_resource type="AudioStream" uid="uid://bn6ns3jxkw03b" path="res://src/audio/sfx/ENEMY_SPROING_death.ogg" id="12_m7220"] -[sub_resource type="CylinderShape3D" id="CylinderShape3D_jbgmx"] -height = 5.0 -radius = 1.0 - -[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_cwfph"] -radius = 2.54294 -height = 5.08589 - -[sub_resource type="SphereShape3D" id="SphereShape3D_0y048"] -radius = 2.30121 +[sub_resource type="Resource" id="Resource_06aiy"] +script = ExtResource("3_g602r") +Items = [] +metadata/_custom_type_script = "uid://bei3s7yr6xkc0" [sub_resource type="Resource" id="Resource_fv5vf"] script = ExtResource("4_5eid5") @@ -39,9 +34,19 @@ TertiaryAttackName = "" TertiaryAttackType = 0 metadata/_custom_type_script = ExtResource("4_5eid5") -[sub_resource type="CylinderShape3D" id="CylinderShape3D_qbmfg"] -height = 5.81738 -radius = 3.91016 +[sub_resource type="CylinderShape3D" id="CylinderShape3D_g602r"] +height = 5.0 +radius = 1.0 + +[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_06aiy"] +radius = 2.5 +height = 6.0 + +[sub_resource type="CylinderShape3D" id="CylinderShape3D_ygtll"] +radius = 4.0 + +[sub_resource type="SphereShape3D" id="SphereShape3D_ebx6c"] +radius = 0.552847 [node name="FilthEater" type="CharacterBody3D" groups=["enemy"]] process_mode = 1 @@ -49,64 +54,71 @@ collision_layer = 10 collision_mask = 11 axis_lock_linear_y = true axis_lock_angular_x = true +axis_lock_angular_z = true script = ExtResource("1_p438s") - -[node name="LineOfSight" type="Area3D" parent="."] -unique_name_in_owner = true -transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 2.25757, 0) -collision_layer = 2 -collision_mask = 2 - -[node name="CollisionShape3D" type="CollisionShape3D" parent="LineOfSight"] -transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, -2) -shape = SubResource("CylinderShape3D_jbgmx") - -[node name="CollisionShape" type="CollisionShape3D" parent="."] -unique_name_in_owner = true -transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 2.25757, 0) -shape = SubResource("CapsuleShape3D_cwfph") - -[node name="Raycast" type="RayCast3D" parent="."] -unique_name_in_owner = true -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3.31086, 0) -target_position = Vector3(0, 0, -5) -collision_mask = 3 - -[node name="Collision" type="Area3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.25757, 0) -collision_layer = 2048 -collision_mask = 0 - -[node name="CollisionShape3D" type="CollisionShape3D" parent="Collision"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.120117, 0.221246, 0) -shape = SubResource("SphereShape3D_0y048") +_lootTable = SubResource("Resource_06aiy") [node name="EnemyModelView" parent="." instance=ExtResource("3_rrwed")] unique_name_in_owner = true transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.114099, 0) EnemyLoreInfo = SubResource("Resource_fv5vf") +[node name="LineOfSight" type="Area3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 1.71715, 0) +collision_layer = 2 +collision_mask = 2 + +[node name="CollisionShape3D" type="CollisionShape3D" parent="LineOfSight"] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, -2) +shape = SubResource("CylinderShape3D_g602r") + +[node name="Raycast" type="RayCast3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 1.71715, 0) +target_position = Vector3(0, 0, -5) +collision_mask = 3 +debug_shape_custom_color = Color(1, 0, 0, 1) + +[node name="CollisionShape" type="CollisionShape3D" parent="."] +unique_name_in_owner = true +transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, -0.0824751, 3.16485, 0) +shape = SubResource("CapsuleShape3D_06aiy") + [node name="PlayerDetector" type="Area3D" parent="."] unique_name_in_owner = true -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.25757, 0) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.71715, 0) collision_layer = 0 collision_mask = 34 [node name="CollisionShape3D" type="CollisionShape3D" parent="PlayerDetector"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.2771, 0) -shape = SubResource("CylinderShape3D_qbmfg") +shape = SubResource("CylinderShape3D_ygtll") + +[node name="Collision" type="Area3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.71715, 0) +collision_layer = 2048 +collision_mask = 0 + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Collision"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.120117, 0.221246, 0) +shape = SubResource("SphereShape3D_ebx6c") [node name="Components" type="Node3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.25757, 0) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.71715, 0) [node name="PatrolBehavior" parent="Components" instance=ExtResource("5_pvjvo")] unique_name_in_owner = true +_patrolRange = 15.0 +_patrolTime = 20.0 [node name="FollowBehavior" parent="Components" instance=ExtResource("6_fccr3")] unique_name_in_owner = true +FollowSpeed = 175.0 [node name="EngagePlayerBehavior" parent="Components" instance=ExtResource("7_8l567")] unique_name_in_owner = true +_minimumAttackTime = 1.0 +_maximumAttackTime = 3.0 _acquireTargetTime = 2.0 [node name="NavigationAgent" type="NavigationAgent3D" parent="Components"] @@ -117,7 +129,7 @@ avoidance_layers = 9 avoidance_mask = 9 [node name="HitSounds" type="Node3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.25757, 0) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.71715, 0) [node name="AbsorbSFX" type="AudioStreamPlayer3D" parent="HitSounds"] unique_name_in_owner = true @@ -136,9 +148,9 @@ bus = &"SFX" [node name="DieSFX" type="AudioStreamPlayer3D" parent="HitSounds"] unique_name_in_owner = true +stream = ExtResource("12_m7220") bus = &"SFX" [node name="AggroSFX" type="AudioStreamPlayer3D" parent="HitSounds"] unique_name_in_owner = true -stream = ExtResource("11_qbmfg") bus = &"SFX" diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/07. chinthe/Chinthe.tscn b/Zennysoft.Game.Ma/src/enemy/enemy_types/07. chinthe/Chinthe.tscn index d9269e27..3839d947 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/07. chinthe/Chinthe.tscn +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/07. chinthe/Chinthe.tscn @@ -10,8 +10,8 @@ [ext_resource type="AudioStream" uid="uid://bf7adfdd857hw" path="res://src/audio/sfx/enemy_morph.ogg" id="8_a4ku4"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_cwfph"] -radius = 0.226425 -height = 2.02807 +radius = 1.0 +height = 3.90429 [sub_resource type="CylinderShape3D" id="CylinderShape3D_jbgmx"] height = 5.0 @@ -52,7 +52,7 @@ script = ExtResource("1_120m2") [node name="CollisionShape" type="CollisionShape3D" parent="."] unique_name_in_owner = true -transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 1.46013, 0) +transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 1.92003, 0) shape = SubResource("CapsuleShape3D_cwfph") [node name="LineOfSight" type="Area3D" parent="."] diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/07. chinthe/ChintheModelView.tscn b/Zennysoft.Game.Ma/src/enemy/enemy_types/07. chinthe/ChintheModelView.tscn index 3ccf8109..48b5dd29 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/07. chinthe/ChintheModelView.tscn +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/07. chinthe/ChintheModelView.tscn @@ -6514,7 +6514,7 @@ tracks/15/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 1, -"values": [&"WATER DAMAGE"] +"values": [&"EARTH DAMAGE"] } tracks/16/type = "value" tracks/16/imported = false @@ -6747,7 +6747,7 @@ frame = 47 position = Vector2(500, 500) scale = Vector2(4, 4) sprite_frames = SubResource("SpriteFrames_8u7he") -animation = &"WATER DAMAGE" +animation = &"EARTH DAMAGE" [node name="Hitbox" type="Area3D" parent="."] unique_name_in_owner = true diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/10. Eden Pillar/EdenPillar.cs b/Zennysoft.Game.Ma/src/enemy/enemy_types/10. Eden Pillar/EdenPillar.cs index e6196e93..68f9dd15 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/10. Eden Pillar/EdenPillar.cs +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/10. Eden Pillar/EdenPillar.cs @@ -51,104 +51,101 @@ public partial class EdenPillar : Enemy3D, IHasPrimaryAttack, IHasSecondaryAttac public void OnReady() { - PlayerDetector.BodyEntered += PlayerDetector_BodyEntered; - LoseTrackOfPlayer.BodyExited += LoseTrackOfPlayer_BodyExited; - EngagePlayerBehavior.TakeAction += PerformAction; - HealthComponent.HealthReachedZero += HealthComponent_HealthReachedZero; + PlayerDetector.BodyEntered += PlayerDetector_BodyEntered; + LoseTrackOfPlayer.BodyExited += LoseTrackOfPlayer_BodyExited; + EngagePlayerBehavior.TakeAction += PerformAction; + HealthComponent.HealthReachedZero += HealthComponent_HealthReachedZero; } private void LoseTrackOfPlayer_BodyExited(Node3D body) => EngagePlayerBehavior.Disengage(); private void HealthComponent_HealthReachedZero() { - StoneRotation.Stop(); + StoneRotation.Stop(); } private void PlayerDetector_BodyEntered(Node3D body) { - EngagePlayerBehavior.Engage(); + EngagePlayerBehavior.Engage(); } public override void PerformAction() { - var rng = new RandomNumberGenerator(); - var options = new List() { PrimaryAttack, SecondaryAttack, TertiaryAttack }; - var selection = rng.RandWeighted([1, 1, 1]); - options[(int)selection].Invoke(); + var rng = new RandomNumberGenerator(); + var options = new List() { PrimaryAttack, SecondaryAttack, TertiaryAttack }; + var selection = rng.RandWeighted([1, 1, 1]); + options[(int)selection].Invoke(); } public void PrimaryAttack() { - var rotationAngle = GetRotationAngle(Mathf.DegToRad(_primaryAngle)); - if (!StoneRotation.Playing && !Mathf.IsEqualApprox(Rotation.Y, rotationAngle)) - StoneRotation.Play(); - var tweener = GetTree().CreateTween(); - tweener.TweenMethod(Callable.From((float x) => RotateTowardsPlayer(x)), Rotation.Y, rotationAngle, 5f); - tweener.TweenCallback(Callable.From(FirePrimaryShot)); + var rotationAngle = GetRotationAngle(Mathf.DegToRad(_primaryAngle)); + if (!StoneRotation.Playing && !Mathf.IsEqualApprox(Rotation.Y, rotationAngle)) + StoneRotation.Play(); + var tweener = GetTree().CreateTween(); + tweener.TweenMethod(Callable.From((float x) => RotateTowardsPlayer(x)), Rotation.Y, rotationAngle, 5f); + tweener.TweenCallback(Callable.From(FirePrimaryShot)); } public void SecondaryAttack() { - var rotationAngle = GetRotationAngle(Mathf.DegToRad(_secondaryAngle)); - if (!StoneRotation.Playing && !Mathf.IsEqualApprox(Rotation.Y, rotationAngle)) - StoneRotation.Play(); - var tweener = GetTree().CreateTween(); - tweener.TweenMethod(Callable.From((float x) => RotateTowardsPlayer(x)), Rotation.Y, rotationAngle, 5f); - tweener.TweenCallback(Callable.From(FireSecondaryShot)); + var rotationAngle = GetRotationAngle(Mathf.DegToRad(_secondaryAngle)); + if (!StoneRotation.Playing && !Mathf.IsEqualApprox(Rotation.Y, rotationAngle)) + StoneRotation.Play(); + var tweener = GetTree().CreateTween(); + tweener.TweenMethod(Callable.From((float x) => RotateTowardsPlayer(x)), Rotation.Y, rotationAngle, 5f); + tweener.TweenCallback(Callable.From(FireSecondaryShot)); } public void TertiaryAttack() { - var rotationAngle = GetRotationAngle(Mathf.DegToRad(_tertiaryAngle)); - if (!StoneRotation.Playing && !Mathf.IsEqualApprox(Rotation.Y, rotationAngle)) - StoneRotation.Play(); - var tweener = GetTree().CreateTween(); - tweener.TweenMethod(Callable.From((float x) => RotateTowardsPlayer(x)), Rotation.Y, rotationAngle, 5f); - tweener.TweenCallback(Callable.From(FireTertiaryShot)); + var rotationAngle = GetRotationAngle(Mathf.DegToRad(_tertiaryAngle)); + if (!StoneRotation.Playing && !Mathf.IsEqualApprox(Rotation.Y, rotationAngle)) + StoneRotation.Play(); + var tweener = GetTree().CreateTween(); + tweener.TweenMethod(Callable.From((float x) => RotateTowardsPlayer(x)), Rotation.Y, rotationAngle, 5f); + tweener.TweenCallback(Callable.From(FireTertiaryShot)); } private void FirePrimaryShot() { - if (HealthComponent.CurrentHP.Value <= 0) - return; - StoneRotation.Stop(); - FireSFX.Play(); - GD.Print("Fire primary shot"); - FireProjectile.Fire(); + if (HealthComponent.CurrentHP.Value <= 0) + return; + StoneRotation.Stop(); + FireSFX.Play(); + FireProjectile.Fire(); } private void FireSecondaryShot() { - if (HealthComponent.CurrentHP.Value <= 0) - return; - StoneRotation.Stop(); - FireSFX.Play(); - GD.Print("Fire secondary shot"); - AirProjectile.Fire(); + if (HealthComponent.CurrentHP.Value <= 0) + return; + StoneRotation.Stop(); + FireSFX.Play(); + AirProjectile.Fire(); } private void FireTertiaryShot() { - if (HealthComponent.CurrentHP.Value <= 0) - return; - StoneRotation.Stop(); - FireSFX.Play(); - GD.Print("Fire tertiary shot"); - WaterProjectile.Fire(); + if (HealthComponent.CurrentHP.Value <= 0) + return; + StoneRotation.Stop(); + FireSFX.Play(); + WaterProjectile.Fire(); } private float GetRotationAngle(float angleOffsetInRadians) { - var target = new Vector3(_player.GlobalPosition.X, Position.Y, _player.GlobalPosition.Z); - _rotation.LookAt(target, Vector3.Up, true); - _rotation.RotateY(Rotation.Y + angleOffsetInRadians); - return _rotation.Rotation.Y; + var target = new Vector3(_player.GlobalPosition.X, Position.Y, _player.GlobalPosition.Z); + _rotation.LookAt(target, Vector3.Up, true); + _rotation.RotateY(Rotation.Y + angleOffsetInRadians); + return _rotation.Rotation.Y; } private void RotateTowardsPlayer(float angle) { - if (HealthComponent.CurrentHP.Value <= 0) - return; - Rotation = new Vector3(Rotation.X, angle, Rotation.Z); + if (HealthComponent.CurrentHP.Value <= 0) + return; + Rotation = new Vector3(Rotation.X, angle, Rotation.Z); } } diff --git a/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.EngagePlayer.cs b/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.EngagePlayer.cs index be669999..ed3cd5c4 100644 --- a/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.EngagePlayer.cs +++ b/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.EngagePlayer.cs @@ -1,4 +1,5 @@ using Chickensoft.Introspection; +using Godot; using Zennysoft.Ma.Adapter.Entity; namespace Zennysoft.Game.Ma; @@ -16,7 +17,10 @@ public partial class EnemyLogic { var enemy = Get(); if (enemy is IHaveEngagePlayerBehavior engagePlayerEnemy) + { + GD.PrintRich($"[color=red]{(enemy as Enemy).EnemyModelView.EnemyLoreInfo.Name}[/color] is engaging the player."); engagePlayerEnemy.EngagePlayerBehavior.Engage(); + } }); OnDetach(() => { diff --git a/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.FollowPlayer.cs b/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.FollowPlayer.cs index 2d526f4b..1c08070a 100644 --- a/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.FollowPlayer.cs +++ b/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.FollowPlayer.cs @@ -1,4 +1,5 @@ using Chickensoft.Introspection; +using Godot; using Zennysoft.Ma.Adapter.Entity; namespace Zennysoft.Game.Ma; @@ -17,6 +18,7 @@ public partial class EnemyLogic var enemy = Get(); if (enemy is IHaveFollowBehavior followEnemy) { + GD.PrintRich($"[color=red]{(enemy as Enemy).EnemyModelView.EnemyLoreInfo.Name}[/color] is following the player."); followEnemy.FollowBehavior.StartFollow(followEnemy.NavigationAgent); Output(new Output.Move()); } diff --git a/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.Patrolling.cs b/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.Patrolling.cs index d5138975..b02878ab 100644 --- a/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.Patrolling.cs +++ b/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.Patrolling.cs @@ -1,4 +1,5 @@ using Chickensoft.Introspection; +using Godot; using Zennysoft.Ma.Adapter.Entity; using static Zennysoft.Game.Ma.EnemyLogic.Input; @@ -18,6 +19,7 @@ public partial class EnemyLogic var enemy = Get(); if (enemy is IHavePatrolBehavior patrolEnemy) { + GD.PrintRich($"[color=red]{(enemy as Enemy).EnemyModelView.EnemyLoreInfo.Name}[/color] is patrolling."); patrolEnemy.PatrolBehavior.StartPatrol(); Output(new Output.Move()); } diff --git a/Zennysoft.Game.Ma/src/items/ItemDatabase.cs b/Zennysoft.Game.Ma/src/items/ItemDatabase.cs index 235e6faf..75b26edc 100644 --- a/Zennysoft.Game.Ma/src/items/ItemDatabase.cs +++ b/Zennysoft.Game.Ma/src/items/ItemDatabase.cs @@ -55,7 +55,6 @@ public class ItemDatabase var weights = validItems.Select(x => x.SpawnRate).ToArray(); var index = rng.RandWeighted(weights); - GD.Print($"Item Spawn Index: {index}, Array Size: {validItems.Length}"); var selectedItem = validItems[index]; return selectedItem; } diff --git a/Zennysoft.Game.Ma/src/map/Map.cs b/Zennysoft.Game.Ma/src/map/Map.cs index 4757a965..0b7596be 100644 --- a/Zennysoft.Game.Ma/src/map/Map.cs +++ b/Zennysoft.Game.Ma/src/map/Map.cs @@ -4,6 +4,7 @@ using Chickensoft.Introspection; using Godot; using Godot.Collections; using System; +using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Zennysoft.Game.Abstractions; @@ -41,6 +42,8 @@ public partial class Map : Node3D, IMap private string _floorToLoad; + private Stopwatch _elapsedTime; + public override void _EnterTree() { FloorRoute = [.. BaseRoute]; @@ -73,7 +76,8 @@ public partial class Map : Node3D, IMap public async Task LoadFloor(FloorScene floorToLoad) { - GD.Print($"Pause for load at {DateTime.Now.Minute}:{DateTime.Now.Second}:{DateTime.Now.Millisecond}"); + _elapsedTime = new Stopwatch(); + _elapsedTime.Start(); Game.Pause(); // Clean up current floor CleanupCurrentFloor(); @@ -85,7 +89,6 @@ public partial class Map : Node3D, IMap public async Task LoadFloorByPath(string filePath) { - GD.Print($"Pause for load at {DateTime.Now.Minute}:{DateTime.Now.Second}:{DateTime.Now.Millisecond}"); Game.Pause(); // Clean up current floor CleanupCurrentFloor(); @@ -119,14 +122,12 @@ public partial class Map : Node3D, IMap { SpawnPointCreated?.Invoke((Vector3.Forward, new Vector3(-999, -999, -999))); var newFloor = await LoadSceneFile(filePath); - GD.Print($"Floor finished load at {DateTime.Now.Minute}:{DateTime.Now.Second}:{DateTime.Now.Millisecond}"); // New floor created, remove old floor ClearFloor(); // Setup new floor AddChild(newFloor); - GD.Print($"Floor added at {DateTime.Now.Minute:D2}:{DateTime.Now.Second:D2}:{DateTime.Now.Millisecond}"); CurrentFloor = newFloor as IDungeonFloor; CurrentFloor.InitializeDungeon(); SpawnPointCreated?.Invoke(CurrentFloor.GetPlayerSpawnPoint()); @@ -138,7 +139,8 @@ public partial class Map : Node3D, IMap SpawnItems(); CurrentFloor.FloorIsLoaded = true; FloorLoaded?.Invoke(); - GD.Print($"Floor loaded invoked {DateTime.Now.Minute}:{DateTime.Now.Second}:{DateTime.Now.Millisecond}"); + _elapsedTime.Stop(); + GD.Print($"Floor loaded in {_elapsedTime.ElapsedMilliseconds}ms."); } private void CleanupCurrentFloor() diff --git a/Zennysoft.Game.Ma/src/map/dungeon/code/MonsterRoom.cs b/Zennysoft.Game.Ma/src/map/dungeon/code/MonsterRoom.cs index 6b529ba4..0279c491 100644 --- a/Zennysoft.Game.Ma/src/map/dungeon/code/MonsterRoom.cs +++ b/Zennysoft.Game.Ma/src/map/dungeon/code/MonsterRoom.cs @@ -20,6 +20,8 @@ public partial class MonsterRoom : DungeonRoom [Node] public Marker3D PlayerSpawn { get; set; } = default!; + private string _color = "white"; + public void SpawnEnemies(Array spawnTable) { if (spawnTable.Count == 0) @@ -42,6 +44,7 @@ public partial class MonsterRoom : DungeonRoom AddChild(instantiatedEnemy); instantiatedEnemy.GlobalPosition = new Vector3(spawnPoint.GlobalPosition.X, 0f, spawnPoint.GlobalPosition.Z); ResetPhysicsInterpolation(); + GD.PrintRich($"Spawned [color=red]{selectedEnemy.EnemyType}[/color] at {instantiatedEnemy.GlobalPosition}"); } } @@ -67,22 +70,34 @@ public partial class MonsterRoom : DungeonRoom var rarity = RarityTag.Common; var rarityGroup = rng.Randf(); if (rarityGroup < 0.5f) + { rarity = RarityTag.Common; + _color = "white"; + } else if (rarityGroup < 0.85f) + { rarity = RarityTag.Uncommon; + _color = "green"; + } else if (rarityGroup < 0.99f) + { rarity = RarityTag.Rare; + _color = "cyan"; + } else + { rarity = RarityTag.Legendary; + _color = "gold"; + } spawnableItems = [.. spawnableItems.Where(x => x.RarityTag == rarity)]; if (spawnableItems.Count() == 0) break; var selectedItem = database.PickItemFromList(spawnableItems) as Node3D; - GD.Print($"Item spawned: {(selectedItem as IBaseInventoryItem).ItemName}"); var duplicated = selectedItem.Duplicate((int)DuplicateFlags.UseInstantiation) as Node3D; AddChild(duplicated); duplicated.Position = new Vector3(spawnPoint.Position.X, 0, spawnPoint.Position.Z); + GD.PrintRich($"Item spawned: [b]{(selectedItem as IBaseInventoryItem).ItemName}[/b] at {duplicated.GlobalPosition}. Rolled a {rarityGroup} for a [color={_color}]{rarity}"); } } } diff --git a/Zennysoft.Game.Ma/src/map/dungeon/rooms/Set B/25. Pedestal Room.tscn b/Zennysoft.Game.Ma/src/map/dungeon/rooms/Set B/25. Pedestal Room.tscn index a01000fb..5c14b2f3 100644 --- a/Zennysoft.Game.Ma/src/map/dungeon/rooms/Set B/25. Pedestal Room.tscn +++ b/Zennysoft.Game.Ma/src/map/dungeon/rooms/Set B/25. Pedestal Room.tscn @@ -263,3 +263,5 @@ lifetime = 41.19 local_coords = true process_material = SubResource("ParticleProcessMaterial_kdgfu") draw_pass_1 = SubResource("QuadMesh_ec0oy") + +[editable path="Model/A2-Deadend"]