From 2d55ae9cc4a5bcd8a99b325deba3d36310cdfdd3 Mon Sep 17 00:00:00 2001 From: Zenny Date: Mon, 27 Oct 2025 18:03:14 -0700 Subject: [PATCH] Add secondary attack options --- .../03. filth_eater/FilthEater.tscn | 2 +- .../src/enemy/enemy_types/04. sara/Sara.cs | 14 +++++++++++ .../enemy/enemy_types/05. ballos/Ballos.cs | 14 +++++++++++ .../enemy/enemy_types/06. chariot/Chariot.cs | 14 +++++++++++ .../enemy/enemy_types/07. chinthe/Chinthe.cs | 2 +- .../enemy_types/07. chinthe/Chinthe.tscn | 2 +- .../enemy_types/08a. Ambassador/Ambassador.cs | 13 ++++++++++ .../enemy/enemy_types/09. Agni/AgniDemon.cs | 14 +++++++++++ .../09. Agni/AgniDemonModelView.tscn | 1 - .../src/enemy/enemy_types/11. Palan/Palan.cs | 14 +++++++++++ .../enemy_types/11. Palan/PalanModelView.tscn | 24 +++++++++---------- .../9b. Aqueos Demon/AqueosDemon.cs | 14 +++++++++++ 12 files changed, 112 insertions(+), 16 deletions(-) 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 37ce1c30..cebc58d3 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 @@ -25,7 +25,7 @@ metadata/_custom_type_script = ExtResource("4_5eid5") [sub_resource type="CylinderShape3D" id="CylinderShape3D_qbmfg"] height = 1.5 -radius = 3.0 +radius = 2.0 [node name="FilthEater" type="CharacterBody3D"] process_mode = 1 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 9f8f2f0a..c44cc4a5 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 @@ -1,6 +1,8 @@ using Chickensoft.AutoInject; using Chickensoft.Introspection; using Godot; +using System; +using System.Collections.Generic; using Zennysoft.Game.Ma; [Meta(typeof(IAutoNode))] @@ -8,6 +10,10 @@ public partial class Sara : Enemy2D, IHavePatrolBehavior, IHaveEngagePlayerBehav { public override void _Notification(int what) => 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!; @@ -29,4 +35,12 @@ public partial class Sara : Enemy2D, IHavePatrolBehavior, IHaveEngagePlayerBehav PlayerDetector.BodyExited += PlayerDetector_BodyExited; SetPhysicsProcess(true); } + + 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(); + } } 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 d42fff06..f1cb54b3 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 @@ -1,6 +1,8 @@ using Chickensoft.AutoInject; using Chickensoft.Introspection; using Godot; +using System; +using System.Collections.Generic; using Zennysoft.Game.Ma; [Meta(typeof(IAutoNode))] @@ -8,6 +10,10 @@ public partial class Ballos : Enemy2D, IHavePatrolBehavior, IHaveEngagePlayerBeh { public override void _Notification(int what) => 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!; @@ -29,4 +35,12 @@ public partial class Ballos : Enemy2D, IHavePatrolBehavior, IHaveEngagePlayerBeh PlayerDetector.BodyExited += PlayerDetector_BodyExited; SetPhysicsProcess(true); } + + 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(); + } } \ No newline at end of file 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 56ba728a..2fb95e7e 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 @@ -1,6 +1,8 @@ using Chickensoft.AutoInject; using Chickensoft.Introspection; using Godot; +using System; +using System.Collections.Generic; using Zennysoft.Game.Ma; [Meta(typeof(IAutoNode))] @@ -8,6 +10,10 @@ public partial class Chariot : Enemy2D, IHavePatrolBehavior, IHaveEngagePlayerBe { public override void _Notification(int what) => 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!; @@ -34,4 +40,12 @@ public partial class Chariot : Enemy2D, IHavePatrolBehavior, IHaveEngagePlayerBe { EnemyModelView.PlayActivateAnimation(); } + + 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(); + } } \ No newline at end of file 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 84f4097a..98fc9e16 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 @@ -10,7 +10,7 @@ public partial class Chinthe : Enemy2D, IHaveEngagePlayerBehavior, IHaveFollowBe { public override void _Notification(int what) => this.Notify(what); - [Export] private float PrimaryAttackChance { get; set; } = 0.7f; + [Export] private float PrimaryAttackChance { get; set; } = 0.9f; [Export] private float PrimarySkillChance { get; set; } = 0.1f; 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 4d9c2a0f..08929810 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 @@ -24,7 +24,7 @@ metadata/_custom_type_script = "uid://dlsgyx4i1jmp3" radius = 1.20703 [sub_resource type="CylinderShape3D" id="CylinderShape3D_q6h01"] -radius = 1.26172 +radius = 1.6 [node name="Chinthe" type="CharacterBody3D"] process_mode = 1 diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/08a. Ambassador/Ambassador.cs b/Zennysoft.Game.Ma/src/enemy/enemy_types/08a. Ambassador/Ambassador.cs index 349d3b75..3b6f456c 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/08a. Ambassador/Ambassador.cs +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/08a. Ambassador/Ambassador.cs @@ -1,12 +1,17 @@ using Chickensoft.AutoInject; using Chickensoft.Introspection; using Godot; +using System; +using System.Collections.Generic; using Zennysoft.Game.Ma; [Meta(typeof(IAutoNode))] public partial class Ambassador : Enemy2D, IHavePatrolBehavior, IHaveEngagePlayerBehavior, IHaveFollowBehavior { public override void _Notification(int what) => 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!; @@ -29,4 +34,12 @@ public partial class Ambassador : Enemy2D, IHavePatrolBehavior, IHaveEngagePlaye PlayerDetector.BodyExited += PlayerDetector_BodyExited; SetPhysicsProcess(true); } + + 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(); + } } \ No newline at end of file diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/09. Agni/AgniDemon.cs b/Zennysoft.Game.Ma/src/enemy/enemy_types/09. Agni/AgniDemon.cs index 53aa0fe7..f90ae323 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/09. Agni/AgniDemon.cs +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/09. Agni/AgniDemon.cs @@ -1,6 +1,8 @@ using Chickensoft.AutoInject; using Chickensoft.Introspection; using Godot; +using System; +using System.Collections.Generic; using Zennysoft.Game.Ma; [Meta(typeof(IAutoNode))] @@ -8,6 +10,10 @@ public partial class AgniDemon : Enemy2D, IHavePatrolBehavior, IHaveEngagePlayer { public override void _Notification(int what) => 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!; @@ -29,4 +35,12 @@ public partial class AgniDemon : Enemy2D, IHavePatrolBehavior, IHaveEngagePlayer PlayerDetector.BodyExited += PlayerDetector_BodyExited; SetPhysicsProcess(true); } + + 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(); + } } \ No newline at end of file diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/09. Agni/AgniDemonModelView.tscn b/Zennysoft.Game.Ma/src/enemy/enemy_types/09. Agni/AgniDemonModelView.tscn index 66d847ea..87f1181e 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/09. Agni/AgniDemonModelView.tscn +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/09. Agni/AgniDemonModelView.tscn @@ -2068,7 +2068,6 @@ _data = { [node name="EnemyModelView" type="Node3D"] script = ExtResource("1_wl7dh") EnemyLoreInfo = SubResource("Resource_f45wt") -_enemyDirection = 0 [node name="Sprite3D" type="Sprite3D" parent="."] transform = Transform3D(1.5, 0, 0, 0, 1.5, 0, 0, 0, 1.5, 0, 0.530475, 0) diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/11. Palan/Palan.cs b/Zennysoft.Game.Ma/src/enemy/enemy_types/11. Palan/Palan.cs index 8e116aa4..b6d2f3f6 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/11. Palan/Palan.cs +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/11. Palan/Palan.cs @@ -1,6 +1,8 @@ using Chickensoft.AutoInject; using Chickensoft.Introspection; using Godot; +using System; +using System.Collections.Generic; using Zennysoft.Game.Ma; [Meta(typeof(IAutoNode))] @@ -8,6 +10,10 @@ public partial class Palan : Enemy2D, IHavePatrolBehavior, IHaveEngagePlayerBeha { public override void _Notification(int what) => 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!; @@ -29,4 +35,12 @@ public partial class Palan : Enemy2D, IHavePatrolBehavior, IHaveEngagePlayerBeha PlayerDetector.BodyExited += PlayerDetector_BodyExited; SetPhysicsProcess(true); } + + 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(); + } } \ No newline at end of file diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/11. Palan/PalanModelView.tscn b/Zennysoft.Game.Ma/src/enemy/enemy_types/11. Palan/PalanModelView.tscn index 6eb91cd5..affb78bc 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/11. Palan/PalanModelView.tscn +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/11. Palan/PalanModelView.tscn @@ -1608,20 +1608,20 @@ states/Walking/position = Vector2(705, 100) transitions = ["Start", "Idle", SubResource("AnimationNodeStateMachineTransition_0yqqu"), "Primary Attack", "Idle", SubResource("AnimationNodeStateMachineTransition_r6aec"), "Secondary Attack", "Idle", SubResource("AnimationNodeStateMachineTransition_lid5r"), "Idle", "Walking", SubResource("AnimationNodeStateMachineTransition_au0i1"), "Walking", "Idle", SubResource("AnimationNodeStateMachineTransition_jbc40"), "Idle", "Primary Attack", SubResource("AnimationNodeStateMachineTransition_0qt6f"), "Idle", "Secondary Attack", SubResource("AnimationNodeStateMachineTransition_2bn25"), "Walking", "Secondary Attack", SubResource("AnimationNodeStateMachineTransition_h2ml5"), "Walking", "Primary Attack", SubResource("AnimationNodeStateMachineTransition_uma8i")] graph_offset = Vector2(-15, 35) -[sub_resource type="Animation" id="Animation_0qt6f"] -resource_name = "Sunblast" -length = 0.500003 +[sub_resource type="Animation" id="Animation_h2ml5"] +resource_name = "Primary Attack" +length = 1.03334 tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true -tracks/0/path = NodePath(".:frame") +tracks/0/path = NodePath("../Primary Attack:frame") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { -"times": PackedFloat32Array(0, 0.5), +"times": PackedFloat32Array(0, 1), "transitions": PackedFloat32Array(1, 1), "update": 0, -"values": [0, 15] +"values": [0, 57] } [sub_resource type="Animation" id="Animation_2bn25"] @@ -1651,20 +1651,20 @@ tracks/1/keys = { "values": [14] } -[sub_resource type="Animation" id="Animation_h2ml5"] -resource_name = "Primary Attack" -length = 1.03334 +[sub_resource type="Animation" id="Animation_0qt6f"] +resource_name = "Sunblast" +length = 0.500003 tracks/0/type = "value" tracks/0/imported = false tracks/0/enabled = true -tracks/0/path = NodePath("../Primary Attack:frame") +tracks/0/path = NodePath(".:frame") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { -"times": PackedFloat32Array(0, 1), +"times": PackedFloat32Array(0, 0.5), "transitions": PackedFloat32Array(1, 1), "update": 0, -"values": [0, 57] +"values": [0, 15] } [sub_resource type="AnimationLibrary" id="AnimationLibrary_uma8i"] diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/9b. Aqueos Demon/AqueosDemon.cs b/Zennysoft.Game.Ma/src/enemy/enemy_types/9b. Aqueos Demon/AqueosDemon.cs index 3c312226..ecd80237 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/9b. Aqueos Demon/AqueosDemon.cs +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/9b. Aqueos Demon/AqueosDemon.cs @@ -1,6 +1,8 @@ using Chickensoft.AutoInject; using Chickensoft.Introspection; using Godot; +using System; +using System.Collections.Generic; using Zennysoft.Game.Ma; [Meta(typeof(IAutoNode))] @@ -8,6 +10,10 @@ public partial class AqueousDemon : Enemy2D, IHavePatrolBehavior, IHaveEngagePla { public override void _Notification(int what) => 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!; @@ -29,4 +35,12 @@ public partial class AqueousDemon : Enemy2D, IHavePatrolBehavior, IHaveEngagePla PlayerDetector.BodyExited += PlayerDetector_BodyExited; SetPhysicsProcess(true); } + + 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(); + } } \ No newline at end of file