diff --git a/Zennysoft.Game.Ma/src/enemy/Enemy.cs b/Zennysoft.Game.Ma/src/enemy/Enemy.cs index 7a9dc196..e5119a0b 100644 --- a/Zennysoft.Game.Ma/src/enemy/Enemy.cs +++ b/Zennysoft.Game.Ma/src/enemy/Enemy.cs @@ -65,18 +65,19 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide { if (!_activated) + { Activate(); - _activated = true; + _activated = true; + + if (this is IHaveFollowBehavior) + _enemyLogic.Input(new EnemyLogic.Input.Follow()); + } }) .Handle((in EnemyLogic.Output.Idle _) => { @@ -99,7 +100,6 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide this.Notify(what); + [Export] private float PrimaryAttackChance { get; set; } = 0.75f; + + [Export] private float SecondaryAttackChance { get; set; } = 0.25f; + [Node] public NavigationAgent3D NavigationAgent { get; set; } [Node] public PatrolBehavior PatrolBehavior { get; set; } = default!; [Node] public FollowBehavior FollowBehavior { get; set; } = default!; @@ -25,13 +31,23 @@ public partial class FilthEater : Enemy2D, IHavePatrolBehavior, IHaveEngagePlaye FollowBehavior.OnVelocityComputed += OnVelocityComputed; EngagePlayerBehavior.TakeAction += PerformAction; EngagePlayerBehavior.AcquireTarget += EngagePlayerBehavior_AcquireTarget; - _enemyLogic.Input(new EnemyLogic.Input.Patrol()); PlayerDetector.BodyEntered += PlayerDetector_BodyEntered; PlayerDetector.BodyExited += PlayerDetector_BodyExited; SetPhysicsProcess(true); } - public override void PerformAction() => EnemyModelView.PlaySecondaryAttackAnimation(); + public void OnResolved() + { + _enemyLogic.Input(new EnemyLogic.Input.Patrol()); + } + + public override void PerformAction() + { + var rng = new RandomNumberGenerator(); + var options = new List() { EnemyModelView.PlayPrimaryAttackAnimation, EnemyModelView.PlaySecondaryAttackAnimation }; + var selection = rng.RandWeighted([PrimaryAttackChance, SecondaryAttackChance]); + options[(int)selection].Invoke(); + } public override void _ExitTree() { diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/03. filth_eater/FilthEaterModelView.tscn b/Zennysoft.Game.Ma/src/enemy/enemy_types/03. filth_eater/FilthEaterModelView.tscn index 05dc9315..0c880a9d 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/03. filth_eater/FilthEaterModelView.tscn +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/03. filth_eater/FilthEaterModelView.tscn @@ -2658,45 +2658,6 @@ animations = [{ [sub_resource type="SphereShape3D" id="SphereShape3D_kct8n"] -[sub_resource type="Animation" id="Animation_8qeb2"] -length = 0.001 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("..:position") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [Vector3(0, 0, 0)] -} -tracks/1/type = "value" -tracks/1/imported = false -tracks/1/enabled = true -tracks/1/path = NodePath("../ProjectileHitbox:monitoring") -tracks/1/interp = 1 -tracks/1/loop_wrap = true -tracks/1/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [false] -} -tracks/2/type = "value" -tracks/2/imported = false -tracks/2/enabled = true -tracks/2/path = NodePath(".:visible") -tracks/2/interp = 1 -tracks/2/loop_wrap = true -tracks/2/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 1, -"values": [false] -} - [sub_resource type="Animation" id="Animation_xrn7e"] resource_name = "fire" tracks/0/type = "value" @@ -2751,6 +2712,45 @@ tracks/3/keys = { "values": [false, true, false] } +[sub_resource type="Animation" id="Animation_8qeb2"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("..:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("../ProjectileHitbox:monitoring") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath(".:visible") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [false] +} + [sub_resource type="AnimationLibrary" id="AnimationLibrary_q8n6h"] _data = { &"Fire": SubResource("Animation_xrn7e"), diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/04. sara/Sara.cs b/Zennysoft.Game.Ma/src/enemy/enemy_types/04. sara/Sara.cs index c44cc4a5..ec8dfed8 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/04. sara/Sara.cs +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/04. sara/Sara.cs @@ -30,12 +30,16 @@ public partial class Sara : Enemy2D, IHavePatrolBehavior, IHaveEngagePlayerBehav FollowBehavior.OnVelocityComputed += OnVelocityComputed; EngagePlayerBehavior.TakeAction += EngagePlayerBehavior_TakeAction; EngagePlayerBehavior.AcquireTarget += EngagePlayerBehavior_AcquireTarget; - _enemyLogic.Input(new EnemyLogic.Input.Patrol()); PlayerDetector.BodyEntered += PlayerDetector_BodyEntered; PlayerDetector.BodyExited += PlayerDetector_BodyExited; SetPhysicsProcess(true); } + public void OnResolved() + { + _enemyLogic.Input(new EnemyLogic.Input.Patrol()); + } + public override void PerformAction() { var rng = new RandomNumberGenerator(); diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/05. ballos/Ballos.cs b/Zennysoft.Game.Ma/src/enemy/enemy_types/05. ballos/Ballos.cs index f1cb54b3..79d0be0a 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/05. ballos/Ballos.cs +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/05. ballos/Ballos.cs @@ -30,12 +30,16 @@ public partial class Ballos : Enemy2D, IHavePatrolBehavior, IHaveEngagePlayerBeh FollowBehavior.OnVelocityComputed += OnVelocityComputed; EngagePlayerBehavior.TakeAction += EngagePlayerBehavior_TakeAction; EngagePlayerBehavior.AcquireTarget += EngagePlayerBehavior_AcquireTarget; - _enemyLogic.Input(new EnemyLogic.Input.Patrol()); PlayerDetector.BodyEntered += PlayerDetector_BodyEntered; PlayerDetector.BodyExited += PlayerDetector_BodyExited; SetPhysicsProcess(true); } + public void OnResolved() + { + _enemyLogic.Input(new EnemyLogic.Input.Patrol()); + } + public override void PerformAction() { var rng = new RandomNumberGenerator(); diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/06. chariot/Chariot.cs b/Zennysoft.Game.Ma/src/enemy/enemy_types/06. chariot/Chariot.cs index 2fb95e7e..a326ecac 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/06. chariot/Chariot.cs +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/06. chariot/Chariot.cs @@ -36,6 +36,11 @@ public partial class Chariot : Enemy2D, IHavePatrolBehavior, IHaveEngagePlayerBe SetPhysicsProcess(true); } + public void OnResolved() + { + _enemyLogic.Input(new EnemyLogic.Input.Patrol()); + } + public override void Activate() { EnemyModelView.PlayActivateAnimation(); diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/07. chinthe/Chinthe.cs b/Zennysoft.Game.Ma/src/enemy/enemy_types/07. chinthe/Chinthe.cs index 98fc9e16..6122366d 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/07. chinthe/Chinthe.cs +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/07. chinthe/Chinthe.cs @@ -54,12 +54,6 @@ public partial class Chinthe : Enemy2D, IHaveEngagePlayerBehavior, IHaveFollowBe EnemyModelView.PlayActivateAnimation(); } - public override void Idle() - { - EnemyModelView.PlayIdleAnimation(); - EnemyModelView.PlayIdleAnimation(); - } - private void Teleport(object sender, EventArgs e) { var targetPosition = _player.GlobalBasis.Z; diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/12. Shield of Heaven/ShieldModelView.tscn b/Zennysoft.Game.Ma/src/enemy/enemy_types/12. Shield of Heaven/ShieldModelView.tscn index 61cab783..88ec5257 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/12. Shield of Heaven/ShieldModelView.tscn +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/12. Shield of Heaven/ShieldModelView.tscn @@ -3004,7 +3004,7 @@ tracks/0/keys = { "times": PackedFloat32Array(0), "transitions": PackedFloat32Array(1), "update": 1, -"values": [23] +"values": [0] } [sub_resource type="AnimationLibrary" id="AnimationLibrary_yuosm"] @@ -3294,7 +3294,6 @@ modulate = Color(1, 1, 1, 0.788235) billboard = 1 texture_filter = 0 sprite_frames = SubResource("SpriteFrames_ie7uh") -frame = 23 [node name="Attack 2 VFX" type="AnimatedSprite3D" parent="VFX Animation Player"] sprite_frames = SubResource("SpriteFrames_lgwan") diff --git a/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.Activated.cs b/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.Activated.cs index b6154731..8f7b3be3 100644 --- a/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.Activated.cs +++ b/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.Activated.cs @@ -9,18 +9,9 @@ public partial class EnemyLogic { [Meta, Id("enemy_logic_state_activated")] public partial record Activated : Alive, - IGet, - IGet, - IGet, IGet { public Activated() => OnAttach(() => Output(new Output.Activate())); } - - public Transition On(in ReachedPlayer input) => To(); - - public Transition On(in Patrol _) => To(); - - public Transition On(in Follow _) => To(); } } \ No newline at end of file diff --git a/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.Alive.cs b/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.Alive.cs index 38fffe18..908f5df9 100644 --- a/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.Alive.cs +++ b/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.Alive.cs @@ -11,6 +11,9 @@ public partial class EnemyLogic public abstract partial record Alive : State, IGet, IGet, + IGet, + IGet, + IGet, IGet { public Transition On(in Reset input) @@ -21,11 +24,13 @@ public partial class EnemyLogic public Transition On(in Input.Defeated input) => To(); - public Transition On(in Input.Idle input) - { - Output(new Output.Idle()); - return ToSelf(); - } + public Transition On(in Input.Idle input) => To(); + + public Transition On(in Follow _) => To(); + + public Transition On(in ReachedPlayer input) => To(); + + public Transition On(in Patrol _) => To(); public Transition On(in Move input) { 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 bbb63f17..fdf39ce6 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 @@ -8,7 +8,7 @@ public partial class EnemyLogic public partial record State { [Meta, Id("enemy_logic_state_engage_player")] - public partial record EngagePlayer : Activated + public partial record EngagePlayer : Alive { public EngagePlayer() { @@ -18,7 +18,6 @@ public partial class EnemyLogic if (enemy is IHaveEngagePlayerBehavior engagePlayerEnemy) { engagePlayerEnemy.EngagePlayerBehavior.Engage(); - Input(new Input.Idle()); } }); OnDetach(() => @@ -27,7 +26,6 @@ public partial class EnemyLogic if (enemy is IHaveEngagePlayerBehavior engagePlayerEnemy) { engagePlayerEnemy.EngagePlayerBehavior.Disengage(); - Input(new Input.Idle()); } }); } 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 69322c0e..484b76c3 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 @@ -8,7 +8,7 @@ public partial class EnemyLogic public partial record State { [Meta, Id("enemy_logic_state_followplayer")] - public partial record FollowPlayer : Activated, IGet + public partial record FollowPlayer : Alive, IGet { public FollowPlayer() { @@ -18,7 +18,6 @@ public partial class EnemyLogic if (enemy is IHaveFollowBehavior followEnemy) { followEnemy.FollowBehavior.StartFollow(followEnemy.NavigationAgent); - Input(new Input.Move()); } }); OnDetach(() => @@ -27,7 +26,6 @@ public partial class EnemyLogic if (enemy is IHaveFollowBehavior followEnemy) { followEnemy.FollowBehavior.StopFollow(); - Input(new Input.Idle()); } }); } diff --git a/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.Idle.cs b/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.Idle.cs index a818a1d3..3d012b56 100644 --- a/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.Idle.cs +++ b/Zennysoft.Game.Ma/src/enemy/state/states/EnemyLogic.State.Idle.cs @@ -7,7 +7,7 @@ public partial class EnemyLogic public partial record State { [Meta, Id("enemy_logic_state_idle")] - public partial record Idle : Activated + public partial record Idle : Alive { public Idle() => OnAttach(() => Output(new Output.Idle())); } 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 3961a1d5..10d64b02 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,5 +1,4 @@ using Chickensoft.Introspection; -using Godot; using Zennysoft.Ma.Adapter.Entity; namespace Zennysoft.Game.Ma; @@ -9,7 +8,7 @@ public partial class EnemyLogic public partial record State { [Meta, Id("enemy_logic_state_patrolling")] - public partial record Patrolling : Activated + public partial record Patrolling : Alive { public Patrolling() { @@ -19,7 +18,6 @@ public partial class EnemyLogic if (enemy is IHavePatrolBehavior patrolEnemy) { patrolEnemy.PatrolBehavior.StartPatrol(); - Input(new Input.Move()); } }); OnDetach(() => @@ -28,7 +26,6 @@ public partial class EnemyLogic if (enemy is IHavePatrolBehavior patrolEnemy) { patrolEnemy.PatrolBehavior.StopPatrol(); - Input(new Input.Idle()); } }); } diff --git a/Zennysoft.Game.Ma/src/map/Map.tscn b/Zennysoft.Game.Ma/src/map/Map.tscn index 54829a7b..b29c35eb 100644 --- a/Zennysoft.Game.Ma/src/map/Map.tscn +++ b/Zennysoft.Game.Ma/src/map/Map.tscn @@ -80,7 +80,7 @@ unique_name_in_owner = true script = ExtResource("2_00xd7") FolderName = "SetAFloors" FloorOdds = Array[float]([0.0, 1.0]) -Chinthe = 1.0 +Sproingy = 1.0 [node name="Overworld" type="Node" parent="MapOrder"] script = ExtResource("3_v14r0")