diff --git a/Zennysoft.Game.Ma.Implementation/Components/IAttackComponent.cs b/Zennysoft.Game.Ma.Implementation/Components/IAttackComponent.cs index 9fd99d55..2cac061d 100644 --- a/Zennysoft.Game.Ma.Implementation/Components/IAttackComponent.cs +++ b/Zennysoft.Game.Ma.Implementation/Components/IAttackComponent.cs @@ -8,10 +8,6 @@ public interface IAttackComponent public IAutoProp MaximumAttack { get; } - public IAutoProp BonusAttack { get; } - - public int TotalAttack { get; } - public void Restore(int restoreAmount); public void Reduce(int reduceAmount); @@ -19,8 +15,4 @@ public interface IAttackComponent public void SetAttack(int attack); public void RaiseMaximumAttack(int raiseAmount); - - public void RaiseBonusAttack(int raiseAmount); - - public void ResetBonusAttack(); } diff --git a/Zennysoft.Game.Ma.Implementation/Components/IDefenseComponent.cs b/Zennysoft.Game.Ma.Implementation/Components/IDefenseComponent.cs index 153df64a..cdeb4ef0 100644 --- a/Zennysoft.Game.Ma.Implementation/Components/IDefenseComponent.cs +++ b/Zennysoft.Game.Ma.Implementation/Components/IDefenseComponent.cs @@ -8,10 +8,6 @@ public interface IDefenseComponent public IAutoProp MaximumDefense { get; } - public IAutoProp BonusDefense { get; } - - public int TotalDefense { get; } - public void Restore(int restoreAmount); public void Reduce(int reduceAmount); @@ -19,8 +15,4 @@ public interface IDefenseComponent public void SetDefense(int attack); public void RaiseMaximumDefense(int raiseAmount); - - public void RaiseBonusDefense(int raiseAmount); - - public void ResetBonusDefense(); } diff --git a/Zennysoft.Game.Ma.Implementation/Components/IEquipmentComponent.cs b/Zennysoft.Game.Ma.Implementation/Components/IEquipmentComponent.cs index c8b58e38..89c0f807 100644 --- a/Zennysoft.Game.Ma.Implementation/Components/IEquipmentComponent.cs +++ b/Zennysoft.Game.Ma.Implementation/Components/IEquipmentComponent.cs @@ -1,4 +1,5 @@ using Chickensoft.Collections; +using Zennysoft.Ma.Adapter.Entity; namespace Zennysoft.Ma.Adapter; public interface IEquipmentComponent @@ -25,4 +26,6 @@ public interface IEquipmentComponent public int BonusLuck { get; } + public ElementalResistanceSet ElementalResistance { get; } + } diff --git a/Zennysoft.Game.Ma.Implementation/Entity/ElementalResistanceSet.cs b/Zennysoft.Game.Ma.Implementation/Entity/ElementalResistanceSet.cs index 2d93c3c0..6a076275 100644 --- a/Zennysoft.Game.Ma.Implementation/Entity/ElementalResistanceSet.cs +++ b/Zennysoft.Game.Ma.Implementation/Entity/ElementalResistanceSet.cs @@ -18,5 +18,15 @@ { ElementType.Telluric, telluricResistance }, }; } + + public static ElementalResistanceSet operator +(ElementalResistanceSet left, ElementalResistanceSet right) + { + return new ElementalResistanceSet( + left.ElementalResistance[ElementType.Aeolic] + right.ElementalResistance[ElementType.Aeolic], + left.ElementalResistance[ElementType.Hydric] + right.ElementalResistance[ElementType.Hydric], + left.ElementalResistance[ElementType.Igneous] + right.ElementalResistance[ElementType.Igneous], + left.ElementalResistance[ElementType.Ferrum] + right.ElementalResistance[ElementType.Ferrum], + left.ElementalResistance[ElementType.Telluric] + right.ElementalResistance[ElementType.Telluric]); + } } } diff --git a/Zennysoft.Game.Ma.Implementation/Equipment/EquipableItem.cs b/Zennysoft.Game.Ma.Implementation/Equipment/EquipableItem.cs index bb77a30e..a97cb8d4 100644 --- a/Zennysoft.Game.Ma.Implementation/Equipment/EquipableItem.cs +++ b/Zennysoft.Game.Ma.Implementation/Equipment/EquipableItem.cs @@ -1,4 +1,5 @@ using Chickensoft.Introspection; +using Zennysoft.Ma.Adapter.Entity; namespace Zennysoft.Ma.Adapter; @@ -14,4 +15,6 @@ public abstract partial class EquipableItem : InventoryItem public virtual int BonusVT { get; } public virtual int BonusLuck { get; } + + public virtual ElementalResistanceSet ElementalResistance { get; } = new ElementalResistanceSet(0, 0, 0, 0, 0); } diff --git a/Zennysoft.Game.Ma/addons/dungeon_floor_layout/DungeonFloorLayout.cs b/Zennysoft.Game.Ma/addons/dungeon_floor_layout/DungeonFloorLayout.cs index 20fe4f07..32727212 100644 --- a/Zennysoft.Game.Ma/addons/dungeon_floor_layout/DungeonFloorLayout.cs +++ b/Zennysoft.Game.Ma/addons/dungeon_floor_layout/DungeonFloorLayout.cs @@ -22,10 +22,10 @@ public partial class DungeonFloorLayout : LayoutType public Callable PopulateMapList => Callable.From(() => PopulateDictionary(SetType)); [Export] - public Dictionary LayoutWithSpawnRate { get; private set; } + public Dictionary LayoutWithSpawnRate; [Export] - public Dictionary EnemySpawnRates { get; set; } = default!; + public Dictionary EnemySpawnRates; private string _floorPath = "res://src/map/dungeon/floors/"; private DungeonFloorSetType _setType; diff --git a/Zennysoft.Game.Ma/src/Components/DefenseComponent.cs b/Zennysoft.Game.Ma/src/Components/DefenseComponent.cs index 21470112..094e0660 100644 --- a/Zennysoft.Game.Ma/src/Components/DefenseComponent.cs +++ b/Zennysoft.Game.Ma/src/Components/DefenseComponent.cs @@ -10,21 +10,14 @@ public class DefenseComponent : IDefenseComponent public IAutoProp MaximumDefense => _maximumDefense; - public IAutoProp BonusDefense => _bonusDefense; - private readonly AutoProp _currentDefense; private readonly AutoProp _maximumDefense; - private readonly AutoProp _bonusDefense; - - public int TotalDefense => CurrentDefense.Value + BonusDefense.Value; - public DefenseComponent(int defenseValue) { _maximumDefense = new AutoProp(defenseValue); _currentDefense = new AutoProp(defenseValue); - _bonusDefense = new AutoProp(0); } public void Restore(int restoreAmount) @@ -50,14 +43,4 @@ public class DefenseComponent : IDefenseComponent _maximumDefense.OnNext(raiseAmount); Restore(raiseAmount); } - - public void RaiseBonusDefense(int raiseAmount) - { - _bonusDefense.OnNext(_bonusDefense.Value + raiseAmount); - } - - public void ResetBonusDefense() - { - _bonusDefense.OnNext(0); - } } diff --git a/Zennysoft.Game.Ma/src/Components/EquipmentComponent.cs b/Zennysoft.Game.Ma/src/Components/EquipmentComponent.cs index 4e5d6fab..9b58b694 100644 --- a/Zennysoft.Game.Ma/src/Components/EquipmentComponent.cs +++ b/Zennysoft.Game.Ma/src/Components/EquipmentComponent.cs @@ -1,5 +1,6 @@ using Chickensoft.Collections; using Zennysoft.Ma.Adapter; +using Zennysoft.Ma.Adapter.Entity; namespace Zennysoft.Game.Ma; public class EquipmentComponent : IEquipmentComponent @@ -26,6 +27,8 @@ public class EquipmentComponent : IEquipmentComponent public int BonusLuck => _equippedWeapon.Value.BonusLuck + _equippedArmor.Value.BonusLuck + _equippedAccessory.Value.BonusLuck; + public ElementalResistanceSet ElementalResistance => _equippedWeapon.Value.ElementalResistance + _equippedArmor.Value.ElementalResistance + _equippedAccessory.Value.ElementalResistance; + public EquipmentComponent() { _equippedWeapon = new AutoProp(new Weapon()); diff --git a/Zennysoft.Game.Ma/src/app/App.cs b/Zennysoft.Game.Ma/src/app/App.cs index 72bb8026..2f72fc15 100644 --- a/Zennysoft.Game.Ma/src/app/App.cs +++ b/Zennysoft.Game.Ma/src/app/App.cs @@ -150,5 +150,11 @@ public partial class App : Node, IApp AppLogic.Stop(); AppBinding.Dispose(); AppRepo.Dispose(); + + MainMenu.NewGame -= OnNewGame; + MainMenu.LoadGame -= OnLoadGame; + MainMenu.EnemyViewer -= OnEnemyViewer; + MainMenu.Quit -= OnQuit; + _loadedScene.Changed -= OnGameLoaded; } } diff --git a/Zennysoft.Game.Ma/src/enemy/AttackEventArgs.cs.uid b/Zennysoft.Game.Ma/src/enemy/AttackEventArgs.cs.uid new file mode 100644 index 00000000..b12f714a --- /dev/null +++ b/Zennysoft.Game.Ma/src/enemy/AttackEventArgs.cs.uid @@ -0,0 +1 @@ +uid://bml27mbsd1fip diff --git a/Zennysoft.Game.Ma/src/enemy/BossTypeA.cs b/Zennysoft.Game.Ma/src/enemy/BossTypeA.cs index e5ed67ec..9f015fe4 100644 --- a/Zennysoft.Game.Ma/src/enemy/BossTypeA.cs +++ b/Zennysoft.Game.Ma/src/enemy/BossTypeA.cs @@ -95,7 +95,7 @@ public partial class BossTypeA : Enemy, IHaveEngagePlayerBehavior, IHaveFollowBe { var target = area.GetOwner(); if (target is IPlayer player) - player.TakeDamage(new AttackData(AttackComponent.TotalAttack, PrimaryAttackElementalType)); + player.TakeDamage(new AttackData(AttackComponent.CurrentAttack.Value, PrimaryAttackElementalType)); } public void StartFight() @@ -142,5 +142,9 @@ public partial class BossTypeA : Enemy, IHaveEngagePlayerBehavior, IHaveFollowBe public override void _ExitTree() { + FollowBehavior.OnVelocityComputed -= OnVelocityComputed; + EngagePlayerBehavior.TakeAction -= PerformAction; + PlayerDetector.BodyEntered -= PlayerDetector_BodyEntered; + PlayerDetector.BodyExited -= PlayerDetector_BodyExited; } } diff --git a/Zennysoft.Game.Ma/src/enemy/Enemy.cs b/Zennysoft.Game.Ma/src/enemy/Enemy.cs index 917c7f64..1c6fd659 100644 --- a/Zennysoft.Game.Ma/src/enemy/Enemy.cs +++ b/Zennysoft.Game.Ma/src/enemy/Enemy.cs @@ -150,6 +150,9 @@ public abstract partial class Enemy : CharacterBody3D, IEnemy, IProvide SetPatrolTarget(); + + public void OnExitTree() + { + _patrolTimer.Stop(); + _patrolTimer.Timeout -= PatrolTimer_Timeout; + _navigationAgent.WaypointReached -= NavigationAgent_WaypointReached; + } } diff --git a/Zennysoft.Game.Ma/src/enemy/enemy_types/01. sproingy/Sproingy.cs b/Zennysoft.Game.Ma/src/enemy/enemy_types/01. sproingy/Sproingy.cs index c572acbe..a53d6da8 100644 --- a/Zennysoft.Game.Ma/src/enemy/enemy_types/01. sproingy/Sproingy.cs +++ b/Zennysoft.Game.Ma/src/enemy/enemy_types/01. sproingy/Sproingy.cs @@ -30,4 +30,14 @@ public partial class Sproingy : Enemy2D, IHavePatrolBehavior, IHaveEngagePlayerB PlayerDetector.BodyExited += PlayerDetector_BodyExited; SetPhysicsProcess(true); } + + public override void _ExitTree() + { + PatrolBehavior.OnVelocityComputed -= OnVelocityComputed; + FollowBehavior.OnVelocityComputed -= OnVelocityComputed; + EngagePlayerBehavior.TakeAction -= EngagePlayerBehavior_TakeAction; + EngagePlayerBehavior.AcquireTarget -= EngagePlayerBehavior_AcquireTarget; + PlayerDetector.BodyEntered -= PlayerDetector_BodyEntered; + PlayerDetector.BodyExited -= PlayerDetector_BodyExited; + } } \ No newline at end of file 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 f02bfb56..e38dc8f4 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 @@ -23,11 +23,23 @@ public partial class FilthEater : Enemy2D, IHavePatrolBehavior, IHaveEngagePlaye PatrolBehavior.HomePosition = GlobalPosition; PatrolBehavior.OnVelocityComputed += OnVelocityComputed; FollowBehavior.OnVelocityComputed += OnVelocityComputed; - EngagePlayerBehavior.TakeAction += EngagePlayerBehavior_TakeAction; + 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 override void _ExitTree() + { + PatrolBehavior.OnVelocityComputed -= OnVelocityComputed; + FollowBehavior.OnVelocityComputed -= OnVelocityComputed; + EngagePlayerBehavior.TakeAction -= EngagePlayerBehavior_TakeAction; + EngagePlayerBehavior.AcquireTarget -= EngagePlayerBehavior_AcquireTarget; + PlayerDetector.BodyEntered -= PlayerDetector_BodyEntered; + PlayerDetector.BodyExited -= PlayerDetector_BodyExited; + } } \ No newline at end of file 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 268c15bc..37ce1c30 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 @@ -24,6 +24,8 @@ Description = "This guy grosses me out." metadata/_custom_type_script = ExtResource("4_5eid5") [sub_resource type="CylinderShape3D" id="CylinderShape3D_qbmfg"] +height = 1.5 +radius = 3.0 [node name="FilthEater" type="CharacterBody3D"] process_mode = 1 @@ -71,6 +73,7 @@ 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.179932, 0) shape = SubResource("CylinderShape3D_qbmfg") [node name="Components" type="Node3D" parent="."] 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 aed490b9..05dc9315 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 @@ -1,8 +1,9 @@ -[gd_scene load_steps=302 format=3 uid="uid://bup8c4x1na3aw"] +[gd_scene load_steps=354 format=3 uid="uid://bup8c4x1na3aw"] [ext_resource type="Script" uid="uid://cvr1qimxpignl" path="res://src/enemy/EnemyModelView2D.cs" id="1_718m1"] [ext_resource type="Script" uid="uid://dlsgyx4i1jmp3" path="res://src/enemy/EnemyLoreInfo.cs" id="2_krqul"] [ext_resource type="Texture2D" uid="uid://bdar3daydbkge" path="res://src/enemy/enemy_types/03. filth_eater/animations/SWIPE/Layer 1.png" id="2_vpn42"] +[ext_resource type="Script" uid="uid://ctshiyffvt4y5" path="res://src/system/AttackDataResource.cs" id="3_4h5gj"] [ext_resource type="Texture2D" uid="uid://o214hr614jit" path="res://src/enemy/enemy_types/03. filth_eater/animations/SWIPE/Layer 2.png" id="3_7tggm"] [ext_resource type="Texture2D" uid="uid://hyipatqsvukp" path="res://src/enemy/enemy_types/03. filth_eater/animations/SWIPE/Layer 3.png" id="4_usgpm"] [ext_resource type="Texture2D" uid="uid://sgj8yf8vsocq" path="res://src/enemy/enemy_types/03. filth_eater/animations/SWIPE/Layer 4.png" id="5_ovibr"] @@ -197,6 +198,8 @@ [ext_resource type="AnimationNodeStateMachine" uid="uid://cbq8xog50cjjy" path="res://src/enemy/animation_state_machines/PrimaryAttackStateMachine.tres" id="195_5cwnl"] [ext_resource type="AnimationNodeStateMachine" uid="uid://clybvwx3itfeo" path="res://src/enemy/animation_state_machines/SecondaryAttackStateMachine.tres" id="196_e0gee"] [ext_resource type="AnimationNodeStateMachine" uid="uid://cy2ngl55c0rws" path="res://src/enemy/animation_state_machines/WalkingStateMachine.tres" id="197_mno7m"] +[ext_resource type="Texture2D" uid="uid://wqjql5n24h1l" path="res://src/vfx/Enemy/BLUE_FLAME.png" id="198_mno7m"] +[ext_resource type="Script" uid="uid://cqm6u7qa8japr" path="res://src/system/Projectile.cs" id="199_4h5gj"] [sub_resource type="Resource" id="Resource_pyy2h"] script = ExtResource("2_krqul") @@ -204,6 +207,12 @@ Name = "Filth Eater" Description = "yuck" metadata/_custom_type_script = "uid://dlsgyx4i1jmp3" +[sub_resource type="Resource" id="Resource_e5pq0"] +script = ExtResource("3_4h5gj") +Damage = 10 +ElementType = 0 +metadata/_custom_type_script = "uid://ctshiyffvt4y5" + [sub_resource type="ViewportTexture" id="ViewportTexture_7tggm"] viewport_path = NodePath("Sprite3D/SubViewportContainer/SubViewport") @@ -1582,40 +1591,38 @@ tracks/1/keys = { "update": 0, "values": [0, 39] } -tracks/2/type = "value" +tracks/2/type = "animation" tracks/2/imported = false tracks/2/enabled = true -tracks/2/path = NodePath("Hitbox/CollisionShape3D:disabled") +tracks/2/path = NodePath("attack VFX/attack VFX animplayer") tracks/2/interp = 1 tracks/2/loop_wrap = true tracks/2/keys = { -"times": PackedFloat32Array(0, 1.75453, 2.16781), -"transitions": PackedFloat32Array(1, 1, 1), -"update": 1, -"values": [true, false, true] -} -tracks/3/type = "animation" -tracks/3/imported = false -tracks/3/enabled = true -tracks/3/path = NodePath("attack VFX/attack VFX animplayer") -tracks/3/interp = 1 -tracks/3/loop_wrap = true -tracks/3/keys = { "clips": PackedStringArray("[stop]", "attack", "[stop]"), "times": PackedFloat32Array(0, 0.833333, 3.16667) } -tracks/4/type = "value" -tracks/4/imported = false -tracks/4/enabled = true -tracks/4/path = NodePath("OmniLight3D:light_energy") -tracks/4/interp = 1 -tracks/4/loop_wrap = true -tracks/4/keys = { +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("OmniLight3D:light_energy") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { "times": PackedFloat32Array(0.833333, 1.91667, 2, 2.16667), "transitions": PackedFloat32Array(1, 1, 1, 1), "update": 0, "values": [0.0, 10.0, 500.0, 0.0] } +tracks/4/type = "animation" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Attack Objects/Projectile1/Bullet/AnimationPlayer") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"clips": PackedStringArray("Fire"), +"times": PackedFloat32Array(1.91667) +} [sub_resource type="Animation" id="Animation_7a6is"] resource_name = "secondary_attack_back" @@ -2341,10 +2348,420 @@ _data = { &"attack": SubResource("Animation_nmlvd") } +[sub_resource type="Resource" id="Resource_mno7m"] +script = ExtResource("3_4h5gj") +Damage = 7 +ElementType = 4 +metadata/_custom_type_script = "uid://ctshiyffvt4y5" + +[sub_resource type="AtlasTexture" id="AtlasTexture_xrn7e"] +atlas = ExtResource("198_mno7m") +region = Rect2(1024, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_8qeb2"] +atlas = ExtResource("198_mno7m") +region = Rect2(1536, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_q8n6h"] +atlas = ExtResource("198_mno7m") +region = Rect2(2048, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_brbcy"] +atlas = ExtResource("198_mno7m") +region = Rect2(2560, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_dftoy"] +atlas = ExtResource("198_mno7m") +region = Rect2(3072, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_8u0x2"] +atlas = ExtResource("198_mno7m") +region = Rect2(3584, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_fqqmc"] +atlas = ExtResource("198_mno7m") +region = Rect2(4096, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_b1lif"] +atlas = ExtResource("198_mno7m") +region = Rect2(4608, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_f7ayv"] +atlas = ExtResource("198_mno7m") +region = Rect2(5120, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_2y7ln"] +atlas = ExtResource("198_mno7m") +region = Rect2(5632, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_311ch"] +atlas = ExtResource("198_mno7m") +region = Rect2(6144, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_60ajf"] +atlas = ExtResource("198_mno7m") +region = Rect2(6656, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_qcv8t"] +atlas = ExtResource("198_mno7m") +region = Rect2(7168, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ym3vo"] +atlas = ExtResource("198_mno7m") +region = Rect2(7680, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_5fqo7"] +atlas = ExtResource("198_mno7m") +region = Rect2(8192, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_w2bwt"] +atlas = ExtResource("198_mno7m") +region = Rect2(8704, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_qm55s"] +atlas = ExtResource("198_mno7m") +region = Rect2(9216, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_rdrim"] +atlas = ExtResource("198_mno7m") +region = Rect2(9728, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_kli1f"] +atlas = ExtResource("198_mno7m") +region = Rect2(10240, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_dif4r"] +atlas = ExtResource("198_mno7m") +region = Rect2(10752, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_4mwd1"] +atlas = ExtResource("198_mno7m") +region = Rect2(11264, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_npl5k"] +atlas = ExtResource("198_mno7m") +region = Rect2(11776, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_obbx1"] +atlas = ExtResource("198_mno7m") +region = Rect2(12288, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_4o8yi"] +atlas = ExtResource("198_mno7m") +region = Rect2(12800, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_kk4df"] +atlas = ExtResource("198_mno7m") +region = Rect2(13312, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_a212s"] +atlas = ExtResource("198_mno7m") +region = Rect2(13824, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ddop6"] +atlas = ExtResource("198_mno7m") +region = Rect2(14336, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_bsamt"] +atlas = ExtResource("198_mno7m") +region = Rect2(14848, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_lcs75"] +atlas = ExtResource("198_mno7m") +region = Rect2(15360, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_sv0jq"] +atlas = ExtResource("198_mno7m") +region = Rect2(15872, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ap565"] +atlas = ExtResource("198_mno7m") +region = Rect2(0, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_x7xwk"] +atlas = ExtResource("198_mno7m") +region = Rect2(512, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_gf7y0"] +atlas = ExtResource("198_mno7m") +region = Rect2(1024, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_n3cae"] +atlas = ExtResource("198_mno7m") +region = Rect2(1536, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_s3abf"] +atlas = ExtResource("198_mno7m") +region = Rect2(2048, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ldl6g"] +atlas = ExtResource("198_mno7m") +region = Rect2(2560, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ysnl1"] +atlas = ExtResource("198_mno7m") +region = Rect2(3072, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_l6jiv"] +atlas = ExtResource("198_mno7m") +region = Rect2(3584, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ra6k7"] +atlas = ExtResource("198_mno7m") +region = Rect2(4096, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_chxxr"] +atlas = ExtResource("198_mno7m") +region = Rect2(4608, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_1cxo4"] +atlas = ExtResource("198_mno7m") +region = Rect2(5120, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_sx8e2"] +atlas = ExtResource("198_mno7m") +region = Rect2(5632, 502, 512, 502) + +[sub_resource type="SpriteFrames" id="SpriteFrames_brsyt"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_xrn7e") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_8qeb2") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_q8n6h") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_brbcy") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_dftoy") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_8u0x2") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_fqqmc") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_b1lif") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_f7ayv") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_2y7ln") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_311ch") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_60ajf") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_qcv8t") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ym3vo") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_5fqo7") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_w2bwt") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_qm55s") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_rdrim") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_kli1f") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_dif4r") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_4mwd1") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_npl5k") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_obbx1") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_4o8yi") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_kk4df") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_a212s") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ddop6") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_bsamt") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_lcs75") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_sv0jq") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ap565") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_x7xwk") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_gf7y0") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_n3cae") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_s3abf") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ldl6g") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ysnl1") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_l6jiv") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ra6k7") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_chxxr") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_1cxo4") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_sx8e2") +}], +"loop": true, +"name": &"default", +"speed": 24.0 +}] + +[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" +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, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, 0, 10)] +} +tracks/1/type = "audio" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("../AudioStreamPlayer3D") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"clips": [{ +"end_offset": 0.0, +"start_offset": 0.0, +"stream": null +}], +"times": PackedFloat32Array(0.0333333) +} +tracks/1/use_blend = true +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("../ProjectileHitbox:monitoring") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.0333333, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [false, true, false] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath(".:visible") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.0333333, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [false, true, false] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_q8n6h"] +_data = { +&"Fire": SubResource("Animation_xrn7e"), +&"RESET": SubResource("Animation_8qeb2") +} + [node name="EnemyModelView" type="Node3D"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.97683, 0) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.5, 0) script = ExtResource("1_718m1") EnemyLoreInfo = SubResource("Resource_pyy2h") +AttackData = SubResource("Resource_e5pq0") [node name="Sprite3D" type="Sprite3D" parent="."] transform = Transform3D(1.5, 0, 0, 0, 1.5, 0, 0, 0, 1.5, 0, 0.0862446, 0) @@ -2411,3 +2828,36 @@ libraries = { transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.546972) light_color = Color(0.837456, 0.93601, 0.775258, 1) omni_attenuation = 0.2 + +[node name="Attack Objects" type="Node3D" parent="."] + +[node name="Projectile1" type="Node3D" parent="Attack Objects"] +script = ExtResource("199_4h5gj") +AttackData = SubResource("Resource_mno7m") + +[node name="Bullet" type="Node3D" parent="Attack Objects/Projectile1"] + +[node name="AnimatedSprite3D" type="AnimatedSprite3D" parent="Attack Objects/Projectile1/Bullet"] +visible = false +offset = Vector2(0, 150) +billboard = 1 +sprite_frames = SubResource("SpriteFrames_brsyt") +autoplay = "default" +frame_progress = 0.79063 + +[node name="ProjectileHitbox" type="Area3D" parent="Attack Objects/Projectile1/Bullet"] +unique_name_in_owner = true +collision_layer = 0 +collision_mask = 64 +monitoring = false + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Attack Objects/Projectile1/Bullet/ProjectileHitbox"] +shape = SubResource("SphereShape3D_kct8n") + +[node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="Attack Objects/Projectile1/Bullet"] + +[node name="AnimationPlayer" type="AnimationPlayer" parent="Attack Objects/Projectile1/Bullet"] +root_node = NodePath("../AnimatedSprite3D") +libraries = { +&"": SubResource("AnimationLibrary_q8n6h") +} 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 d982980a..9240d804 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 @@ -21,8 +21,8 @@ public partial class EnemyLogic OnDetach(() => { var enemy = Get(); - if (enemy is IHaveFollowBehavior patrolEnemy) - patrolEnemy.FollowBehavior.StopFollow(); + if (enemy is IHaveFollowBehavior followEnemy) + followEnemy.FollowBehavior.StopFollow(); }); } diff --git a/Zennysoft.Game.Ma/src/game/Game.cs b/Zennysoft.Game.Ma/src/game/Game.cs index 8422012e..5d277046 100644 --- a/Zennysoft.Game.Ma/src/game/Game.cs +++ b/Zennysoft.Game.Ma/src/game/Game.cs @@ -503,4 +503,20 @@ public partial class Game : Node3D, IGame private void OnQuit() { } + + public void OnExitTree() + { + InGameUI.UseTeleportPrompt.TeleportToNextFloor -= UseTeleportPrompt_TeleportToNextFloor; + InGameUI.UseTeleportPrompt.CloseTeleportPrompt -= UseTeleportPrompt_CloseTeleportPrompt; + FloorClearMenu.GoToNextFloor -= FloorClearMenu_GoToNextFloor; + FloorClearMenu.SaveAndExit -= FloorClearMenu_SaveAndExit; + FloorClearMenu.TransitionCompleted -= FloorClearMenu_TransitionCompleted; + + GameRepo.RestorativePickedUp -= GameEventDepot_RestorativePickedUp; + + DeathMenu.NewGame -= OnContinueGame; + DeathMenu.QuitGame -= OnQuit; + + GameRepo.IsPaused.Sync -= IsPaused_Sync; + } } diff --git a/Zennysoft.Game.Ma/src/items/EffectService.cs b/Zennysoft.Game.Ma/src/items/EffectService.cs index 6276840f..c8764a78 100644 --- a/Zennysoft.Game.Ma/src/items/EffectService.cs +++ b/Zennysoft.Game.Ma/src/items/EffectService.cs @@ -155,7 +155,6 @@ public class EffectService var currentWeapon = (Weapon)_player.EquipmentComponent.EquippedWeapon.Value; currentWeapon.IncreaseWeaponAttack(1); - _player.AttackComponent.RaiseBonusAttack(1); } public void RaiseCurrentArmorDefense() @@ -165,7 +164,6 @@ public class EffectService var currentArmor = (Armor)_player.EquipmentComponent.EquippedArmor.Value; currentArmor.IncreaseArmorDefense(1); - _player.DefenseComponent.RaiseBonusDefense(1); } public void RaiseLevel() => _player.LevelUp(); diff --git a/Zennysoft.Game.Ma/src/items/InventoryItemStats.cs b/Zennysoft.Game.Ma/src/items/InventoryItemStats.cs index 961f7e3d..1aae90aa 100644 --- a/Zennysoft.Game.Ma/src/items/InventoryItemStats.cs +++ b/Zennysoft.Game.Ma/src/items/InventoryItemStats.cs @@ -1,7 +1,6 @@ using Chickensoft.Introspection; using Chickensoft.Serialization; using Godot; -using Zennysoft.Game.Implementation; using Zennysoft.Ma.Adapter; namespace Zennysoft.Game.Ma; @@ -24,11 +23,26 @@ public abstract partial class InventoryItemStats : Resource [Export] [Save("armor_defense")] - public int Defense { get; set; } = 0; + public int BonusDefense { get; set; } = 0; [Export] [Save("weapon_luck")] - public double Luck { get; set; } = 0.05; + public double BonusLuck { get; set; } = 0.05; + + [Export] + public int AeolicResistance { get; set; } = 0; + + [Export] + public int TelluricResistance { get; set; } = 0; + + [Export] + public int HydricResistance { get; set; } = 0; + + [Export] + public int IgneousResistance { get; set; } = 0; + + [Export] + public int FerrumResistance { get; set; } = 0; [Export(PropertyHint.Range, "0, 25, 0.1")] public float ThrowSpeed { get; set; } = 12.0f; diff --git a/Zennysoft.Game.Ma/src/items/ItemDatabase.cs b/Zennysoft.Game.Ma/src/items/ItemDatabase.cs index 4dca7bde..2d3826cc 100644 --- a/Zennysoft.Game.Ma/src/items/ItemDatabase.cs +++ b/Zennysoft.Game.Ma/src/items/ItemDatabase.cs @@ -45,7 +45,8 @@ public partial class ItemDatabase : Node var armorInfo = GD.Load($"res://src/items/armor/resources/{armor}"); var armorScene = ResourceLoader.Load("res://src/items/armor/Armor.tscn").Instantiate(); armorScene.Stats = armorInfo; - database.Add(armorScene); + if (!database.Contains(armorScene)) + database.Add(armorScene); } foreach (var weapon in weaponResources) @@ -53,6 +54,8 @@ public partial class ItemDatabase : Node var weaponInfo = GD.Load($"res://src/items/weapons/resources/{weapon}"); var weaponScene = ResourceLoader.Load("res://src/items/weapons/Weapon.tscn").Instantiate(); weaponScene.Stats = weaponInfo; + if (!database.Contains(weaponScene)) + database.Add(weaponScene); database.Add(weaponScene); } @@ -61,6 +64,8 @@ public partial class ItemDatabase : Node var accessoryInfo = GD.Load($"res://src/items/accessory/resources/{accessory}"); var accessoryScene = ResourceLoader.Load("res://src/items/accessory/Accessory.tscn").Instantiate(); accessoryScene.Stats = accessoryInfo; + if (!database.Contains(accessoryScene)) + database.Add(accessoryScene); database.Add(accessoryScene); } @@ -69,6 +74,8 @@ public partial class ItemDatabase : Node var throwableItemInfo = GD.Load($"res://src/items/throwable/resources/{throwable}"); var throwableItemScene = ResourceLoader.Load("res://src/items/throwable/ThrowableItem.tscn").Instantiate(); throwableItemScene.Stats = throwableItemInfo; + if (!database.Contains(throwableItemScene)) + database.Add(throwableItemScene); database.Add(throwableItemScene); } @@ -77,6 +84,8 @@ public partial class ItemDatabase : Node var consumableItemInfo = GD.Load($"res://src/items/consumable/resources/{consumable}"); var consumableItemScene = ResourceLoader.Load("res://src/items/consumable/ConsumableItem.tscn").Instantiate(); consumableItemScene.Stats = consumableItemInfo; + if (!database.Contains(consumableItemScene)) + database.Add(consumableItemScene); database.Add(consumableItemScene); } @@ -85,6 +94,8 @@ public partial class ItemDatabase : Node var effectItemInfo = GD.Load($"res://src/items/effect/resources/{effectItem}"); var effectItemScene = ResourceLoader.Load("res://src/items/effect/EffectItem.tscn").Instantiate(); effectItemScene.Stats = effectItemInfo; + if (!database.Contains(effectItemScene)) + database.Add(effectItemScene); database.Add(effectItemScene); } diff --git a/Zennysoft.Game.Ma/src/items/accessory/Accessory.cs b/Zennysoft.Game.Ma/src/items/accessory/Accessory.cs index 5648aaa4..4e652eec 100644 --- a/Zennysoft.Game.Ma/src/items/accessory/Accessory.cs +++ b/Zennysoft.Game.Ma/src/items/accessory/Accessory.cs @@ -3,6 +3,7 @@ using Chickensoft.Introspection; using Chickensoft.Serialization; using Godot; using Zennysoft.Ma.Adapter; +using Zennysoft.Ma.Adapter.Entity; namespace Zennysoft.Game.Ma; @@ -27,6 +28,8 @@ public partial class Accessory : EquipableItem public override float ThrowSpeed => Stats.ThrowSpeed; + public override ElementalResistanceSet ElementalResistance => new ElementalResistanceSet(Stats.AeolicResistance, Stats.HydricResistance, Stats.IgneousResistance, Stats.FerrumResistance, Stats.TelluricResistance); + public AccessoryTag AccessoryTag => Stats.AccessoryTag; public override ItemTag ItemTag => Stats.ItemTag; diff --git a/Zennysoft.Game.Ma/src/items/armor/Armor.cs b/Zennysoft.Game.Ma/src/items/armor/Armor.cs index c14b49bd..6d4aae2f 100644 --- a/Zennysoft.Game.Ma/src/items/armor/Armor.cs +++ b/Zennysoft.Game.Ma/src/items/armor/Armor.cs @@ -3,6 +3,7 @@ using Chickensoft.Introspection; using Chickensoft.Serialization; using Godot; using Zennysoft.Ma.Adapter; +using Zennysoft.Ma.Adapter.Entity; namespace Zennysoft.Game.Ma; @@ -28,10 +29,12 @@ public partial class Armor : EquipableItem public override float ThrowSpeed => Stats.ThrowSpeed; - public override int BonusDefense => Stats.Defense + _bonusDefense; + public override int BonusDefense => Stats.BonusDefense + _bonusDefense; private int _bonusDefense { get; set; } = 0; + public override ElementalResistanceSet ElementalResistance => new ElementalResistanceSet(Stats.AeolicResistance, Stats.HydricResistance, Stats.IgneousResistance, Stats.FerrumResistance, Stats.TelluricResistance); + public void IncreaseArmorDefense(int bonus) => _bonusDefense += bonus; public override ItemTag ItemTag => Stats.ItemTag; diff --git a/Zennysoft.Game.Ma/src/items/weapons/Weapon.cs b/Zennysoft.Game.Ma/src/items/weapons/Weapon.cs index e70e5dcc..e50bc98c 100644 --- a/Zennysoft.Game.Ma/src/items/weapons/Weapon.cs +++ b/Zennysoft.Game.Ma/src/items/weapons/Weapon.cs @@ -3,6 +3,7 @@ using Chickensoft.Introspection; using Chickensoft.Serialization; using Godot; using Zennysoft.Ma.Adapter; +using Zennysoft.Ma.Adapter.Entity; namespace Zennysoft.Game.Ma; @@ -28,7 +29,7 @@ public partial class Weapon : EquipableItem public override float ThrowSpeed => Stats.ThrowSpeed; - public double Luck => Stats.Luck; + public double Luck => Stats.BonusLuck; public double AttackSpeed => Stats.AttackSpeed; @@ -38,6 +39,8 @@ public partial class Weapon : EquipableItem public ElementType WeaponElement => Stats.WeaponElement; + public override ElementalResistanceSet ElementalResistance => new ElementalResistanceSet(Stats.AeolicResistance, Stats.HydricResistance, Stats.IgneousResistance, Stats.FerrumResistance, Stats.TelluricResistance); + public void IncreaseWeaponAttack(int bonus) => _extraDamage += bonus; public override int BonusAttack { get => Stats.BonusAttack + _extraDamage; } diff --git a/Zennysoft.Game.Ma/src/map/Map.tscn b/Zennysoft.Game.Ma/src/map/Map.tscn index f332379f..39ce0773 100644 --- a/Zennysoft.Game.Ma/src/map/Map.tscn +++ b/Zennysoft.Game.Ma/src/map/Map.tscn @@ -78,12 +78,6 @@ unique_name_in_owner = true [node name="Floor01 (Press Populate Map Data Button to load floor from SetAFloors folder)" type="Node" parent="MapOrder"] script = ExtResource("3_v14r0") -LayoutWithSpawnRate = Dictionary[String, float]({ -"SetAFloors/test_floor.tscn": 1.0 -}) -EnemySpawnRates = { -0: 1.0 -} metadata/_custom_type_script = "uid://ci7o3nn4mdo8o" [node name="Overworld (Add SpecialFloorLayout node for special floors and pick the FloorName from the list)" type="Node" parent="MapOrder"] @@ -92,13 +86,8 @@ metadata/_custom_type_script = "uid://cabvj6s31iucg" [node name="Altar (Arrange order of nodes to change default load order)" type="Node" parent="MapOrder"] script = ExtResource("2_00xd7") -FloorName = 1 metadata/_custom_type_script = "uid://cabvj6s31iucg" [node name="Floor02 (Add DungeonFloorLayout node for regular dungeon floors)" type="Node" parent="MapOrder"] script = ExtResource("3_v14r0") -LayoutWithSpawnRate = Dictionary[String, float]({}) -EnemySpawnRates = { -0: 1.0 -} metadata/_custom_type_script = "uid://ci7o3nn4mdo8o" diff --git a/Zennysoft.Game.Ma/src/map/dungeon/code/DungeonFloor.cs b/Zennysoft.Game.Ma/src/map/dungeon/code/DungeonFloor.cs index dc0c359a..cc629980 100644 --- a/Zennysoft.Game.Ma/src/map/dungeon/code/DungeonFloor.cs +++ b/Zennysoft.Game.Ma/src/map/dungeon/code/DungeonFloor.cs @@ -20,41 +20,41 @@ public partial class DungeonFloor : Node3D, IDungeonFloor public void InitializeDungeon() { - Rooms = []; - Rooms = FindAllDungeonRooms([.. GetChildren()], Rooms); - _playerSpawnPoint = RandomizePlayerSpawnPoint(); + Rooms = []; + Rooms = FindAllDungeonRooms([.. GetChildren()], Rooms); + _playerSpawnPoint = RandomizePlayerSpawnPoint(); } public void SpawnEnemies(Godot.Collections.Dictionary enemyInfo) { - var monsterRooms = Rooms.OfType(); - foreach (var room in monsterRooms) - room.SpawnEnemies(enemyInfo); + var monsterRooms = Rooms.OfType(); + foreach (var room in monsterRooms) + room.SpawnEnemies(enemyInfo); } public Transform3D GetPlayerSpawnPoint() => new Transform3D(_playerSpawnPoint.Basis, new Vector3(_playerSpawnPoint.Origin.X, 0f, _playerSpawnPoint.Origin.Z)); private Transform3D RandomizePlayerSpawnPoint() { - var randomSpawnLocations = Rooms - .OfType() - .Select(x => x.PlayerSpawn); - var godotCollection = new Godot.Collections.Array(randomSpawnLocations); - var result = godotCollection.PickRandom(); - return result.GlobalTransform; + var randomSpawnLocations = Rooms + .OfType() + .Select(x => x.PlayerSpawn); + var godotCollection = new Godot.Collections.Array(randomSpawnLocations); + var result = godotCollection.PickRandom(); + return result.GlobalTransform; } private static ImmutableList FindAllDungeonRooms(List nodesToSearch, ImmutableList roomsFound) { - if (nodesToSearch.Count == 0) - return roomsFound; + if (nodesToSearch.Count == 0) + return roomsFound; - foreach (var node in nodesToSearch) - { - if (node is IDungeonRoom dungeonRoom) - roomsFound = roomsFound.Add(dungeonRoom); - } + foreach (var node in nodesToSearch) + { + if (node is IDungeonRoom dungeonRoom) + roomsFound = roomsFound.Add(dungeonRoom); + } - return FindAllDungeonRooms([.. nodesToSearch.SelectMany(x => x.GetChildren())], roomsFound); + return FindAllDungeonRooms([.. nodesToSearch.SelectMany(x => x.GetChildren())], roomsFound); } } diff --git a/Zennysoft.Game.Ma/src/map/dungeon/code/DungeonRoom.cs b/Zennysoft.Game.Ma/src/map/dungeon/code/DungeonRoom.cs index 2ccd0524..d5e7b31d 100644 --- a/Zennysoft.Game.Ma/src/map/dungeon/code/DungeonRoom.cs +++ b/Zennysoft.Game.Ma/src/map/dungeon/code/DungeonRoom.cs @@ -65,4 +65,10 @@ public abstract partial class DungeonRoom : Node3D, IDungeonRoom _playerDiscoveredRoom = true; _minimap.Show(); } + + public void OnExitTree() + { + _room.BodyEntered -= Room_BodyEntered; + _room.BodyExited -= Room_BodyExited; + } } diff --git a/Zennysoft.Game.Ma/src/player/Player.cs b/Zennysoft.Game.Ma/src/player/Player.cs index a513692a..8d3c8301 100644 --- a/Zennysoft.Game.Ma/src/player/Player.cs +++ b/Zennysoft.Game.Ma/src/player/Player.cs @@ -208,7 +208,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide this.Notify(what); + + [Dependency] protected IPlayer _player => this.DependOn(() => GetParent().GetChildren().OfType().Single()); + + [Node] public Area3D ProjectileHitbox { get; set; } + + [Node] public AnimationPlayer AnimationPlayer { get; set; } + + [Export] public AttackDataResource AttackData { get; set; } + + public void OnReady() + { + ProjectileHitbox.AreaEntered += Hitbox_AreaEntered; + } + + public void Fire() + { + AnimationPlayer.Play("Fire"); + } + + private void Hitbox_AreaEntered(Area3D area) + { + _player.TakeDamage(new AttackData(AttackData.Damage, AttackData.ElementType)); + } +} diff --git a/Zennysoft.Game.Ma/src/system/Projectile.cs.uid b/Zennysoft.Game.Ma/src/system/Projectile.cs.uid new file mode 100644 index 00000000..fad74d25 --- /dev/null +++ b/Zennysoft.Game.Ma/src/system/Projectile.cs.uid @@ -0,0 +1 @@ +uid://cqm6u7qa8japr diff --git a/Zennysoft.Game.Ma/src/system/SampleProjectile.tscn b/Zennysoft.Game.Ma/src/system/SampleProjectile.tscn new file mode 100644 index 00000000..ac9980da --- /dev/null +++ b/Zennysoft.Game.Ma/src/system/SampleProjectile.tscn @@ -0,0 +1,438 @@ +[gd_scene load_steps=50 format=3 uid="uid://36h8dl0tpmga"] + +[ext_resource type="Script" uid="uid://cqm6u7qa8japr" path="res://src/system/Projectile.cs" id="1_0hjuy"] +[ext_resource type="Texture2D" uid="uid://wqjql5n24h1l" path="res://src/vfx/Enemy/BLUE_FLAME.png" id="2_hwc8p"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_xrn7e"] +atlas = ExtResource("2_hwc8p") +region = Rect2(1024, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_8qeb2"] +atlas = ExtResource("2_hwc8p") +region = Rect2(1536, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_q8n6h"] +atlas = ExtResource("2_hwc8p") +region = Rect2(2048, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_brbcy"] +atlas = ExtResource("2_hwc8p") +region = Rect2(2560, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_dftoy"] +atlas = ExtResource("2_hwc8p") +region = Rect2(3072, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_8u0x2"] +atlas = ExtResource("2_hwc8p") +region = Rect2(3584, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_fqqmc"] +atlas = ExtResource("2_hwc8p") +region = Rect2(4096, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_b1lif"] +atlas = ExtResource("2_hwc8p") +region = Rect2(4608, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_f7ayv"] +atlas = ExtResource("2_hwc8p") +region = Rect2(5120, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_2y7ln"] +atlas = ExtResource("2_hwc8p") +region = Rect2(5632, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_311ch"] +atlas = ExtResource("2_hwc8p") +region = Rect2(6144, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_60ajf"] +atlas = ExtResource("2_hwc8p") +region = Rect2(6656, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_qcv8t"] +atlas = ExtResource("2_hwc8p") +region = Rect2(7168, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ym3vo"] +atlas = ExtResource("2_hwc8p") +region = Rect2(7680, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_5fqo7"] +atlas = ExtResource("2_hwc8p") +region = Rect2(8192, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_w2bwt"] +atlas = ExtResource("2_hwc8p") +region = Rect2(8704, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_qm55s"] +atlas = ExtResource("2_hwc8p") +region = Rect2(9216, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_rdrim"] +atlas = ExtResource("2_hwc8p") +region = Rect2(9728, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_kli1f"] +atlas = ExtResource("2_hwc8p") +region = Rect2(10240, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_dif4r"] +atlas = ExtResource("2_hwc8p") +region = Rect2(10752, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_4mwd1"] +atlas = ExtResource("2_hwc8p") +region = Rect2(11264, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_npl5k"] +atlas = ExtResource("2_hwc8p") +region = Rect2(11776, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_obbx1"] +atlas = ExtResource("2_hwc8p") +region = Rect2(12288, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_4o8yi"] +atlas = ExtResource("2_hwc8p") +region = Rect2(12800, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_kk4df"] +atlas = ExtResource("2_hwc8p") +region = Rect2(13312, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_a212s"] +atlas = ExtResource("2_hwc8p") +region = Rect2(13824, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ddop6"] +atlas = ExtResource("2_hwc8p") +region = Rect2(14336, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_bsamt"] +atlas = ExtResource("2_hwc8p") +region = Rect2(14848, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_lcs75"] +atlas = ExtResource("2_hwc8p") +region = Rect2(15360, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_sv0jq"] +atlas = ExtResource("2_hwc8p") +region = Rect2(15872, 0, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ap565"] +atlas = ExtResource("2_hwc8p") +region = Rect2(0, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_x7xwk"] +atlas = ExtResource("2_hwc8p") +region = Rect2(512, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_gf7y0"] +atlas = ExtResource("2_hwc8p") +region = Rect2(1024, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_n3cae"] +atlas = ExtResource("2_hwc8p") +region = Rect2(1536, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_s3abf"] +atlas = ExtResource("2_hwc8p") +region = Rect2(2048, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ldl6g"] +atlas = ExtResource("2_hwc8p") +region = Rect2(2560, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ysnl1"] +atlas = ExtResource("2_hwc8p") +region = Rect2(3072, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_l6jiv"] +atlas = ExtResource("2_hwc8p") +region = Rect2(3584, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ra6k7"] +atlas = ExtResource("2_hwc8p") +region = Rect2(4096, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_chxxr"] +atlas = ExtResource("2_hwc8p") +region = Rect2(4608, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_1cxo4"] +atlas = ExtResource("2_hwc8p") +region = Rect2(5120, 502, 512, 502) + +[sub_resource type="AtlasTexture" id="AtlasTexture_sx8e2"] +atlas = ExtResource("2_hwc8p") +region = Rect2(5632, 502, 512, 502) + +[sub_resource type="SpriteFrames" id="SpriteFrames_brsyt"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_xrn7e") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_8qeb2") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_q8n6h") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_brbcy") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_dftoy") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_8u0x2") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_fqqmc") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_b1lif") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_f7ayv") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_2y7ln") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_311ch") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_60ajf") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_qcv8t") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ym3vo") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_5fqo7") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_w2bwt") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_qm55s") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_rdrim") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_kli1f") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_dif4r") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_4mwd1") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_npl5k") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_obbx1") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_4o8yi") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_kk4df") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_a212s") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ddop6") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_bsamt") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_lcs75") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_sv0jq") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ap565") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_x7xwk") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_gf7y0") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_n3cae") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_s3abf") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ldl6g") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ysnl1") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_l6jiv") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ra6k7") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_chxxr") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_1cxo4") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_sx8e2") +}], +"loop": true, +"name": &"default", +"speed": 24.0 +}] + +[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" +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, 1), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, 0, 10)] +} +tracks/1/type = "audio" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("../AudioStreamPlayer3D") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"clips": [{ +"end_offset": 0.0, +"start_offset": 0.0, +"stream": null +}], +"times": PackedFloat32Array(0.0333333) +} +tracks/1/use_blend = true +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("../ProjectileHitbox:monitoring") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.0333333, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [false, true, false] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath(".:visible") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.0333333, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [false, true, false] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_q8n6h"] +_data = { +&"Fire": SubResource("Animation_xrn7e"), +&"RESET": SubResource("Animation_8qeb2") +} + +[node name="Projectile" type="Node3D"] +script = ExtResource("1_0hjuy") + +[node name="Bullet" type="Node3D" parent="."] + +[node name="AnimatedSprite3D" type="AnimatedSprite3D" parent="Bullet"] +visible = false +offset = Vector2(0, 150) +billboard = 1 +sprite_frames = SubResource("SpriteFrames_brsyt") +autoplay = "default" +frame_progress = 0.79063 + +[node name="ProjectileHitbox" type="Area3D" parent="Bullet"] +unique_name_in_owner = true +collision_layer = 0 +collision_mask = 64 +monitoring = false + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Bullet/ProjectileHitbox"] +shape = SubResource("SphereShape3D_kct8n") + +[node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="Bullet"] + +[node name="AnimationPlayer" type="AnimationPlayer" parent="Bullet"] +unique_name_in_owner = true +root_node = NodePath("../AnimatedSprite3D") +libraries = { +&"": SubResource("AnimationLibrary_q8n6h") +}