diff --git a/project.godot b/project.godot index 41b70bf8..fe76e6f5 100644 --- a/project.godot +++ b/project.godot @@ -209,6 +209,7 @@ locale/translations_pot_files=PackedStringArray("res://src/dialog/Dialogue.dialo 3d_physics/layer_9="Teleport" 3d_physics/layer_10="Minimap" 3d_physics/layer_11="ItemRescue" +3d_physics/layer_12="EnemyHitbox" [physics] diff --git a/src/enemy/Enemy.cs b/src/enemy/Enemy.cs index cc241e9a..5b7d8642 100644 --- a/src/enemy/Enemy.cs +++ b/src/enemy/Enemy.cs @@ -8,6 +8,7 @@ namespace GameJamDungeon; [Meta(typeof(IAutoNode))] public partial class Enemy : RigidBody3D, IEnemy, IProvide { + #region Registration public override void _Notification(int what) => this.Notify(what); private IEnemyLogic _enemyLogic { get; set; } = default!; @@ -15,6 +16,7 @@ public partial class Enemy : RigidBody3D, IEnemy, IProvide IEnemyLogic IProvide.Value() => _enemyLogic; public EnemyLogic.IBinding EnemyBinding { get; set; } = default!; + #endregion #region Dependencies @@ -24,7 +26,7 @@ public partial class Enemy : RigidBody3D, IEnemy, IProvide #endregion #region Exports - [Export] private EnemyStatResource _enemyStatResource { get; set; } = default!; + [Export] protected EnemyStatResource _enemyStatResource { get; set; } = default!; #endregion #region Node Dependencies @@ -57,11 +59,6 @@ public partial class Enemy : RigidBody3D, IEnemy, IProvide _enemyLogic.Set(GameRepo); } - public void OnReady() - { - SetPhysicsProcess(true); - } - public void TakeDamage(double damage, ElementType elementType, bool isCriticalHit = false, bool ignoreDefense = false, bool ignoreElementalResistance = false) { if (_currentHP.Value > 0) @@ -77,6 +74,10 @@ public partial class Enemy : RigidBody3D, IEnemy, IProvide GD.Print($"Enemy Hit for {damage} damage."); _currentHP.OnNext(_currentHP.Value - damage); GD.Print("Current HP: " + _currentHP.Value); + + if (_currentHP.Value <= 0) + return; + EnemyModelView.PlayHitAnimation(); _enemyLogic.Input(new EnemyLogic.Input.Alerted()); } @@ -90,8 +91,8 @@ public partial class Enemy : RigidBody3D, IEnemy, IProvide var velocity = (targetPosition - GlobalTransform.Origin).Normalized() * 2f * delta; var lookAtDir = GlobalTransform.Origin - velocity; var lookAtPosition = new Vector3(lookAtDir.X, GlobalPosition.Y, lookAtDir.Z); - if (GlobalPosition.DistanceTo(target) > 1.0f && !velocity.IsEqualApprox(Vector3.Zero) && !GlobalPosition.IsEqualApprox(lookAtPosition)) - LookAt(lookAtPosition); + if (GlobalPosition.DistanceTo(target) > 1.0f && !velocity.IsEqualApprox(Vector3.Zero) && !Position.IsEqualApprox(lookAtPosition)) + LookAt(lookAtPosition + new Vector3(0.001f, 0.001f, 0.001f), Vector3.Up); EnemyModelView.RotateModel(GlobalTransform.Basis, -GameRepo.PlayerGlobalTransform.Value.Basis.Z); _knockbackStrength = _knockbackStrength * 0.9f; MoveAndCollide(velocity + (_knockbackDirection * _knockbackStrength)); @@ -118,7 +119,6 @@ public partial class Enemy : RigidBody3D, IEnemy, IProvide }) .Handle((in EnemyLogic.Output.Defeated output) => { - Die(); }); this.Provide(); diff --git a/src/enemy/EnemyModelView.cs b/src/enemy/EnemyModelView.cs index 26c8bccd..a9c35caa 100644 --- a/src/enemy/EnemyModelView.cs +++ b/src/enemy/EnemyModelView.cs @@ -13,6 +13,7 @@ public interface IEnemyModelView : INode3D public void PlayPrimarySkillAnimation(); public void PlayHitAnimation(); + public void PlayDeathAnimation(); public void RotateModel(Basis enemyBasis, Vector3 cameraDirection); diff --git a/src/enemy/EnemyStatResource.cs b/src/enemy/EnemyStatResource.cs index 77fb8456..db6ee79e 100644 --- a/src/enemy/EnemyStatResource.cs +++ b/src/enemy/EnemyStatResource.cs @@ -44,12 +44,6 @@ namespace GameJamDungeon [Export] public double FerrumResistance { get; set; } - [Export] - public ElementType SecondaryAttackElementalType { get; set; } - - [Export] - public double SecondaryAttackElementalDamageBonus { get; set; } = 1.0; - [Export] public float DropsSoulGemChance { get; set; } = 0.75f; } diff --git a/src/enemy/IEnemy.cs.uid b/src/enemy/IEnemy.cs.uid new file mode 100644 index 00000000..a4ac4c65 --- /dev/null +++ b/src/enemy/IEnemy.cs.uid @@ -0,0 +1 @@ +uid://baq35syngyqo3 diff --git a/src/enemy/enemy_types/chariot/Chariot.cs.uid b/src/enemy/enemy_types/chariot/Chariot.cs.uid new file mode 100644 index 00000000..07c3b145 --- /dev/null +++ b/src/enemy/enemy_types/chariot/Chariot.cs.uid @@ -0,0 +1 @@ +uid://djx5x5bhkku85 diff --git a/src/enemy/enemy_types/chariot/Chariot.tscn b/src/enemy/enemy_types/chariot/Chariot.tscn index 33dfedb4..c50c879a 100644 --- a/src/enemy/enemy_types/chariot/Chariot.tscn +++ b/src/enemy/enemy_types/chariot/Chariot.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=137 format=3 uid="uid://dlw5cvutvypxn"] -[ext_resource type="Script" path="res://src/enemy/enemy_types/chariot/Chariot.cs" id="1_hqeyd"] +[ext_resource type="Script" uid="uid://djx5x5bhkku85" path="res://src/enemy/enemy_types/chariot/Chariot.cs" id="1_hqeyd"] [ext_resource type="Script" uid="uid://dnkmr0eq1sij0" path="res://src/enemy/EnemyStatResource.cs" id="2_77bk6"] [ext_resource type="Script" uid="uid://6edayafleq8y" path="res://src/hitbox/Hitbox.cs" id="3_lg405"] [ext_resource type="Texture2D" uid="uid://c6fvuw1escea1" path="res://src/enemy/enemy_types/chariot/animations/Chariot Back Walk/Layer 1.png" id="4_fokm1"] diff --git a/src/enemy/enemy_types/filth_eater/FilthEater.cs.uid b/src/enemy/enemy_types/filth_eater/FilthEater.cs.uid new file mode 100644 index 00000000..d29c5401 --- /dev/null +++ b/src/enemy/enemy_types/filth_eater/FilthEater.cs.uid @@ -0,0 +1 @@ +uid://cohal8w5ceneg diff --git a/src/enemy/enemy_types/filth_eater/FilthEater.tscn b/src/enemy/enemy_types/filth_eater/FilthEater.tscn index fba3a108..da75fc7b 100644 --- a/src/enemy/enemy_types/filth_eater/FilthEater.tscn +++ b/src/enemy/enemy_types/filth_eater/FilthEater.tscn @@ -104,8 +104,6 @@ AeolicResistance = 0.0 HydricResistance = 0.0 IgneousResistance = 0.0 FerrumResistance = 0.0 -PrimaryAttackElementalType = 0 -PrimaryAttackElementalDamageBonus = 1.0 SecondaryAttackElementalType = 2 SecondaryAttackElementalDamageBonus = 1.15 DropsSoulGemChance = 0.75 @@ -615,6 +613,8 @@ axis_lock_angular_x = true contact_monitor = true max_contacts_reported = 1 script = ExtResource("1_fyc13") +SecondaryAttackElementalType = 2 +SecondaryAttackElementalDamageBonus = 1.15 _enemyStatResource = SubResource("Resource_0y048") [node name="CollisionShape3D" type="CollisionShape3D" parent="."] diff --git a/src/enemy/enemy_types/michael/Michael.cs b/src/enemy/enemy_types/michael/Michael.cs index 150829d9..d78c36b8 100644 --- a/src/enemy/enemy_types/michael/Michael.cs +++ b/src/enemy/enemy_types/michael/Michael.cs @@ -12,12 +12,35 @@ public partial class Michael : Enemy, IHasPrimaryAttack [Export] public double PrimaryAttackElementalDamageBonus { get; set; } = 1.0; + public void OnReady() + { + SetPhysicsProcess(true); + EnemyModelView.AnimationTree.AnimationFinished += AnimationPlayer_AnimationFinished; + } + + private void AnimationPlayer_AnimationFinished(StringName animName) + { + if (animName == "primary_attack") + EnemyModelView.Hitbox.AreaEntered -= Hitbox_AreaEntered; + } + public override void TakeAction() { PrimaryAttack(); } public void PrimaryAttack() { + EnemyModelView.Hitbox.AreaEntered += Hitbox_AreaEntered; EnemyModelView.PlayPrimaryAttackAnimation(); } + + private void Hitbox_AreaEntered(Area3D area) + { + var target = area.GetOwner(); + if (target is IPlayer player) + { + var damage = _enemyStatResource.CurrentAttack * PrimaryAttackElementalDamageBonus; + player.TakeDamage(damage, PrimaryAttackElementalType, BattleExtensions.IsCriticalHit(_enemyStatResource.Luck)); + } + } } \ No newline at end of file diff --git a/src/enemy/enemy_types/michael/Michael.cs.uid b/src/enemy/enemy_types/michael/Michael.cs.uid new file mode 100644 index 00000000..ff021ea2 --- /dev/null +++ b/src/enemy/enemy_types/michael/Michael.cs.uid @@ -0,0 +1 @@ +uid://c4pdledq3bll3 diff --git a/src/enemy/enemy_types/michael/Michael.tscn b/src/enemy/enemy_types/michael/Michael.tscn index 09c24be9..6f3f3bfb 100644 --- a/src/enemy/enemy_types/michael/Michael.tscn +++ b/src/enemy/enemy_types/michael/Michael.tscn @@ -1,8 +1,27 @@ -[gd_scene load_steps=5 format=3 uid="uid://b0gwivt7cw7nd"] +[gd_scene load_steps=7 format=3 uid="uid://b0gwivt7cw7nd"] -[ext_resource type="Script" path="res://src/enemy/enemy_types/michael/Michael.cs" id="1_wfjxm"] +[ext_resource type="Script" uid="uid://c4pdledq3bll3" path="res://src/enemy/enemy_types/michael/Michael.cs" id="1_wfjxm"] +[ext_resource type="Script" uid="uid://dnkmr0eq1sij0" path="res://src/enemy/EnemyStatResource.cs" id="2_wrps7"] [ext_resource type="PackedScene" uid="uid://bjg8wyvp8q6oc" path="res://src/enemy/enemy_types/michael/MichaelModelView.tscn" id="3_wrps7"] +[sub_resource type="Resource" id="Resource_xhsah"] +script = ExtResource("2_wrps7") +CurrentHP = 50.0 +MaximumHP = 50.0 +CurrentAttack = 0 +CurrentDefense = 0 +MaxAttack = 0 +MaxDefense = 0 +ExpFromDefeat = 0 +Luck = 0.05 +TelluricResistance = 0.0 +AeolicResistance = 0.0 +HydricResistance = 0.0 +IgneousResistance = 0.0 +FerrumResistance = 0.0 +DropsSoulGemChance = 0.75 +metadata/_custom_type_script = ExtResource("2_wrps7") + [sub_resource type="CylinderShape3D" id="CylinderShape3D_jbgmx"] height = 5.0 radius = 1.0 @@ -18,6 +37,7 @@ collision_mask = 11 axis_lock_linear_y = true axis_lock_angular_x = true script = ExtResource("1_wfjxm") +_enemyStatResource = SubResource("Resource_xhsah") [node name="LineOfSight" type="Area3D" parent="."] unique_name_in_owner = true diff --git a/src/enemy/enemy_types/sproingy/Sproingy.cs b/src/enemy/enemy_types/sproingy/Sproingy.cs index 6d2e1ef9..68834944 100644 --- a/src/enemy/enemy_types/sproingy/Sproingy.cs +++ b/src/enemy/enemy_types/sproingy/Sproingy.cs @@ -7,17 +7,42 @@ namespace GameJamDungeon; [Meta(typeof(IAutoNode))] public partial class Sproingy : Enemy, IHasPrimaryAttack { + public override void _Notification(int what) => this.Notify(what); + [Export] public ElementType PrimaryAttackElementalType { get; set; } = ElementType.None; [Export] public double PrimaryAttackElementalDamageBonus { get; set; } = 1.0; + public void OnReady() + { + SetPhysicsProcess(true); + EnemyModelView.AnimationTree.AnimationFinished += AnimationPlayer_AnimationFinished; + } + + private void AnimationPlayer_AnimationFinished(StringName animName) + { + if (animName == "primary_attack") + EnemyModelView.Hitbox.AreaEntered -= Hitbox_AreaEntered; + } + public override void TakeAction() { PrimaryAttack(); } public void PrimaryAttack() { + EnemyModelView.Hitbox.AreaEntered += Hitbox_AreaEntered; EnemyModelView.PlayPrimaryAttackAnimation(); } + + private void Hitbox_AreaEntered(Area3D area) + { + var target = area.GetOwner(); + if (target is IPlayer player) + { + var damage = _enemyStatResource.CurrentAttack * PrimaryAttackElementalDamageBonus; + player.TakeDamage(damage, PrimaryAttackElementalType, BattleExtensions.IsCriticalHit(_enemyStatResource.Luck)); + } + } } \ No newline at end of file diff --git a/src/enemy/enemy_types/sproingy/Sproingy.cs.uid b/src/enemy/enemy_types/sproingy/Sproingy.cs.uid new file mode 100644 index 00000000..241ed3c3 --- /dev/null +++ b/src/enemy/enemy_types/sproingy/Sproingy.cs.uid @@ -0,0 +1 @@ +uid://jjulhqd5g3be diff --git a/src/enemy/enemy_types/sproingy/Sproingy.tscn b/src/enemy/enemy_types/sproingy/Sproingy.tscn index cf6f7ccd..ce544a34 100644 --- a/src/enemy/enemy_types/sproingy/Sproingy.tscn +++ b/src/enemy/enemy_types/sproingy/Sproingy.tscn @@ -1,8 +1,27 @@ -[gd_scene load_steps=5 format=3 uid="uid://bksq62muhk3h5"] +[gd_scene load_steps=8 format=3 uid="uid://bksq62muhk3h5"] -[ext_resource type="Script" path="res://src/enemy/enemy_types/sproingy/Sproingy.cs" id="1_ldo22"] +[ext_resource type="Script" uid="uid://jjulhqd5g3be" path="res://src/enemy/enemy_types/sproingy/Sproingy.cs" id="1_ldo22"] +[ext_resource type="Script" uid="uid://dnkmr0eq1sij0" path="res://src/enemy/EnemyStatResource.cs" id="2_8vcnq"] [ext_resource type="PackedScene" uid="uid://bli0t0d6ommvi" path="res://src/enemy/enemy_types/sproingy/SproingyModelView.tscn" id="4_o3b7p"] +[sub_resource type="Resource" id="Resource_o3b7p"] +script = ExtResource("2_8vcnq") +CurrentHP = 50.0 +MaximumHP = 50.0 +CurrentAttack = 8 +CurrentDefense = 5 +MaxAttack = 8 +MaxDefense = 5 +ExpFromDefeat = 15 +Luck = 0.05 +TelluricResistance = 0.0 +AeolicResistance = 0.0 +HydricResistance = 0.0 +IgneousResistance = 0.0 +FerrumResistance = 0.0 +DropsSoulGemChance = 0.75 +metadata/_custom_type_script = ExtResource("2_8vcnq") + [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_cwfph"] radius = 0.226425 height = 2.02807 @@ -11,6 +30,9 @@ height = 2.02807 height = 5.0 radius = 1.0 +[sub_resource type="SphereShape3D" id="SphereShape3D_8vcnq"] +radius = 1.20703 + [node name="Sproingy" type="RigidBody3D"] process_mode = 1 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0) @@ -21,6 +43,7 @@ axis_lock_angular_x = true contact_monitor = true max_contacts_reported = 1 script = ExtResource("1_ldo22") +_enemyStatResource = SubResource("Resource_o3b7p") [node name="CollisionShape3D" type="CollisionShape3D" parent="."] transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0, 0) @@ -62,3 +85,10 @@ collision_mask = 3 [node name="EnemyModelView" parent="." instance=ExtResource("4_o3b7p")] unique_name_in_owner = true transform = Transform3D(1.5, 0, 0, 0, 1.5, 0, 0, 0, 1.5, 0, 0.0862446, 0) + +[node name="Area3D" type="Area3D" parent="."] +collision_layer = 2048 +collision_mask = 0 + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Area3D"] +shape = SubResource("SphereShape3D_8vcnq") diff --git a/src/enemy/enemy_types/sproingy/SproingyModelView.tscn b/src/enemy/enemy_types/sproingy/SproingyModelView.tscn index 6136939f..c24e8c69 100644 --- a/src/enemy/enemy_types/sproingy/SproingyModelView.tscn +++ b/src/enemy/enemy_types/sproingy/SproingyModelView.tscn @@ -280,6 +280,18 @@ tracks/1/keys = { "update": 0, "values": [0] } +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Hitbox/CollisionShape3D:disabled") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [true] +} [sub_resource type="Animation" id="Animation_1tda5"] resource_name = "idle_back_walk" @@ -399,6 +411,18 @@ tracks/1/keys = { "update": 0, "values": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] } +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Hitbox/CollisionShape3D:disabled") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.332842, 0.66857), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [true, false, true] +} [sub_resource type="AnimationLibrary" id="AnimationLibrary_6tj5r"] _data = { diff --git a/src/game/ElementType.cs.uid b/src/game/ElementType.cs.uid new file mode 100644 index 00000000..e760ffd4 --- /dev/null +++ b/src/game/ElementType.cs.uid @@ -0,0 +1 @@ +uid://d2jmqna6ogv8t diff --git a/src/game/IGame.cs.uid b/src/game/IGame.cs.uid new file mode 100644 index 00000000..e3ab8843 --- /dev/null +++ b/src/game/IGame.cs.uid @@ -0,0 +1 @@ +uid://cql33235m74q7 diff --git a/src/hitbox/Hitbox.cs b/src/hitbox/Hitbox.cs index e2c6bda4..2335b124 100644 --- a/src/hitbox/Hitbox.cs +++ b/src/hitbox/Hitbox.cs @@ -1,7 +1,5 @@ using Chickensoft.GodotNodeInterfaces; -using GameJamDungeon; using Godot; -using System; public interface IHitbox : IArea3D { diff --git a/src/map/dungeon/floors/Floor01.tscn b/src/map/dungeon/floors/Floor01.tscn index 86e063f7..e79026ff 100644 --- a/src/map/dungeon/floors/Floor01.tscn +++ b/src/map/dungeon/floors/Floor01.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=13 format=3 uid="uid://bc1sp6xwe0j65"] -[ext_resource type="Script" path="res://src/map/dungeon/code/DungeonFloor.cs" id="1_0ecnn"] -[ext_resource type="Script" path="res://addons/SimpleDungeons/DungeonGenerator3D.gd" id="2_cxmwa"] +[ext_resource type="Script" uid="uid://dwt6302nsf4vq" path="res://src/map/dungeon/code/DungeonFloor.cs" id="1_0ecnn"] +[ext_resource type="Script" uid="uid://b1x125h0tya2w" path="res://addons/SimpleDungeons/DungeonGenerator3D.gd" id="2_cxmwa"] [ext_resource type="PackedScene" uid="uid://dpec2lbt83dhe" path="res://src/map/dungeon/scenes/Antechamber.tscn" id="3_tsw3y"] [ext_resource type="PackedScene" uid="uid://b82dx66mgs2d7" path="res://src/map/dungeon/scenes/BasinRoom.tscn" id="4_b2rkl"] [ext_resource type="PackedScene" uid="uid://bn4gslp2gk8ds" path="res://src/map/dungeon/corridor/Corridor.tscn" id="4_gni6i"] diff --git a/src/map/dungeon/scenes/Antechamber.tscn b/src/map/dungeon/scenes/Antechamber.tscn index 1d308894..59a7587a 100644 --- a/src/map/dungeon/scenes/Antechamber.tscn +++ b/src/map/dungeon/scenes/Antechamber.tscn @@ -1,7 +1,7 @@ -[gd_scene load_steps=59 format=4 uid="uid://dpec2lbt83dhe"] +[gd_scene load_steps=60 format=4 uid="uid://dpec2lbt83dhe"] -[ext_resource type="Script" path="res://addons/SimpleDungeons/DungeonRoom3D.gd" id="1_ho6e8"] -[ext_resource type="Script" path="res://src/map/dungeon/code/DungeonRoom.cs" id="2_iwuh7"] +[ext_resource type="Script" uid="uid://ce73fuh74l81l" path="res://addons/SimpleDungeons/DungeonRoom3D.gd" id="1_ho6e8"] +[ext_resource type="Script" uid="uid://daetb3e2nm56p" path="res://src/map/dungeon/code/DungeonRoom.cs" id="2_iwuh7"] [ext_resource type="Texture2D" uid="uid://ba5yl0syukqtx" path="res://src/map/dungeon/models/antechamber_1/ANTECHAMBER_TYPE1_VER2_WALL TILE 1.jpg" id="3_isaec"] [ext_resource type="Texture2D" uid="uid://vtnruibl68fq" path="res://src/map/dungeon/models/antechamber_1/ANTECHAMBER_TYPE1_VER2_FLOOR1.jpg" id="4_5vwwt"] [ext_resource type="Texture2D" uid="uid://b21vqw03xewaq" path="res://src/map/dungeon/models/antechamber_1/ANTECHAMBER_TYPE1_VER2_TILE4.png" id="5_4tpx2"] @@ -16,12 +16,13 @@ [ext_resource type="Texture2D" uid="uid://cpln18w0wvan" path="res://src/map/dungeon/models/antechamber_1/ANTECHAMBER_TYPE1_VER2_mother.png" id="14_1wlp7"] [ext_resource type="Texture2D" uid="uid://b8dow4tvs1ktr" path="res://src/map/dungeon/models/antechamber_1/ANTECHAMBER_TYPE1_VER2_brick3.png" id="15_rowg2"] [ext_resource type="PackedScene" uid="uid://twrj4wixcbu7" path="res://src/items/ItemDatabase.tscn" id="17_25wvm"] +[ext_resource type="PackedScene" uid="uid://bksq62muhk3h5" path="res://src/enemy/enemy_types/sproingy/Sproingy.tscn" id="18_6qc76"] [ext_resource type="PackedScene" uid="uid://dbvr8ewajja6a" path="res://src/enemy/EnemyDatabase.tscn" id="18_v6hub"] [ext_resource type="Texture2D" uid="uid://bkvegamuqdsdd" path="res://src/map/dungeon/corridor/CORRIDOR test_FLOOR1.jpg" id="19_06gih"] [ext_resource type="Texture2D" uid="uid://del2dfj3etokd" path="res://src/map/dungeon/textures/BLOCKED-DOOR_REGULAR.png" id="20_le1vp"] [ext_resource type="Material" uid="uid://bsafm3t4drpl" path="res://src/map/dungeon/textures/MinimapTexture.tres" id="21_8vpi3"] -[ext_resource type="Script" path="res://src/map/dungeon/code/MinimapManager.cs" id="21_h0ti6"] -[ext_resource type="Script" path="res://src/map/dungeon/corridor/remove_unused_doors.gd" id="21_m6pqv"] +[ext_resource type="Script" uid="uid://c6s8hvdj3u3aq" path="res://src/map/dungeon/code/MinimapManager.cs" id="21_h0ti6"] +[ext_resource type="Script" uid="uid://yl7wyeo5m725" path="res://src/map/dungeon/corridor/remove_unused_doors.gd" id="21_m6pqv"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_3hnk1"] resource_name = "Material.041" @@ -737,6 +738,8 @@ unique_name_in_owner = true [node name="EnemyDatabase" parent="Antechamber" instance=ExtResource("18_v6hub")] unique_name_in_owner = true +EnemyList = Array[PackedScene]([ExtResource("18_6qc76")]) +SpawnRate = PackedFloat32Array(0.5) [node name="TeleportSpawn" type="Marker3D" parent="Antechamber"] unique_name_in_owner = true diff --git a/src/map/dungeon/scenes/Antechamber_2.tscn b/src/map/dungeon/scenes/Antechamber_2.tscn index 5a99a71d..946629fc 100644 --- a/src/map/dungeon/scenes/Antechamber_2.tscn +++ b/src/map/dungeon/scenes/Antechamber_2.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=89 format=4 uid="uid://vdhl32je6hq2"] +[gd_scene load_steps=90 format=4 uid="uid://vdhl32je6hq2"] [ext_resource type="Script" uid="uid://ce73fuh74l81l" path="res://addons/SimpleDungeons/DungeonRoom3D.gd" id="1_j1kxr"] [ext_resource type="Script" uid="uid://daetb3e2nm56p" path="res://src/map/dungeon/code/DungeonRoom.cs" id="2_6qgti"] @@ -25,6 +25,7 @@ [ext_resource type="PackedScene" uid="uid://twrj4wixcbu7" path="res://src/items/ItemDatabase.tscn" id="23_rhlsp"] [ext_resource type="PackedScene" uid="uid://dbvr8ewajja6a" path="res://src/enemy/EnemyDatabase.tscn" id="24_168rc"] [ext_resource type="Script" uid="uid://yl7wyeo5m725" path="res://src/map/dungeon/corridor/remove_unused_doors.gd" id="25_8521a"] +[ext_resource type="PackedScene" uid="uid://bksq62muhk3h5" path="res://src/enemy/enemy_types/sproingy/Sproingy.tscn" id="25_qsemm"] [ext_resource type="Script" uid="uid://c6s8hvdj3u3aq" path="res://src/map/dungeon/code/MinimapManager.cs" id="26_tvm82"] [ext_resource type="Material" uid="uid://bsafm3t4drpl" path="res://src/map/dungeon/textures/MinimapTexture.tres" id="27_mgor6"] @@ -1812,6 +1813,8 @@ unique_name_in_owner = true [node name="EnemyDatabase" parent="Antechamber2" instance=ExtResource("24_168rc")] unique_name_in_owner = true +EnemyList = Array[PackedScene]([ExtResource("25_qsemm")]) +SpawnRate = PackedFloat32Array(0.5) [node name="TeleportSpawn" type="Marker3D" parent="Antechamber2"] unique_name_in_owner = true diff --git a/src/map/dungeon/scenes/ColumnRoom.tscn b/src/map/dungeon/scenes/ColumnRoom.tscn index 7eda58c5..c100d0e1 100644 --- a/src/map/dungeon/scenes/ColumnRoom.tscn +++ b/src/map/dungeon/scenes/ColumnRoom.tscn @@ -1,7 +1,8 @@ -[gd_scene load_steps=107 format=4 uid="uid://c1qicmrcg6q6x"] +[gd_scene load_steps=108 format=4 uid="uid://c1qicmrcg6q6x"] -[ext_resource type="Script" path="res://addons/SimpleDungeons/DungeonRoom3D.gd" id="1_x1cte"] -[ext_resource type="Script" path="res://src/map/dungeon/code/DungeonRoom.cs" id="2_g5xc4"] +[ext_resource type="Script" uid="uid://ce73fuh74l81l" path="res://addons/SimpleDungeons/DungeonRoom3D.gd" id="1_x1cte"] +[ext_resource type="Script" uid="uid://daetb3e2nm56p" path="res://src/map/dungeon/code/DungeonRoom.cs" id="2_g5xc4"] +[ext_resource type="PackedScene" uid="uid://bksq62muhk3h5" path="res://src/enemy/enemy_types/sproingy/Sproingy.tscn" id="5_nsoky"] [ext_resource type="Texture2D" uid="uid://b2h2devo04do7" path="res://src/map/dungeon/models/column_room/COLUMN_ROOM_VER3_COLUMN-DARKER.png" id="7_uspsn"] [ext_resource type="Texture2D" uid="uid://dafrf8sqqrhlr" path="res://src/map/dungeon/models/column_room/COLUMN_ROOM_VER3_effed-TILES-2.png" id="8_hk2oq"] [ext_resource type="Texture2D" uid="uid://cg2mvnq7f8uhj" path="res://src/map/dungeon/models/column_room/COLUMN_ROOM_VER3_WALL TILE 1.jpg" id="9_r0ib2"] @@ -13,7 +14,7 @@ [ext_resource type="Texture2D" uid="uid://bont0nuph50qn" path="res://src/map/dungeon/models/column_room/COLUMN_ROOM_VER3_5r4b2vhc34xa1.png" id="15_k21dx"] [ext_resource type="Texture2D" uid="uid://ne8b5ixuw7wy" path="res://src/map/dungeon/models/column_room/COLUMN_ROOM_VER3_hand-tiile.png" id="16_84ul5"] [ext_resource type="Texture2D" uid="uid://dfidrnk2qw3pf" path="res://src/map/dungeon/models/column_room/COLUMN_ROOM_VER3_CEILING_1.jpg" id="17_8kv76"] -[ext_resource type="Shader" path="res://src/map/overworld/water.gdshader" id="18_8816c"] +[ext_resource type="Shader" uid="uid://blrcjqdo7emhs" path="res://src/map/overworld/water.gdshader" id="18_8816c"] [ext_resource type="Texture2D" uid="uid://1knt4qif78c1" path="res://src/map/dungeon/models/column_room/COLUMN_ROOM_VER3_COLUMN.jpg" id="18_v5tkv"] [ext_resource type="Texture2D" uid="uid://bn5lx2dal2x23" path="res://src/map/dungeon/models/column_room/COLUMN_ROOM_VER3_others_0020_color_1k.jpg" id="19_3akwg"] [ext_resource type="Texture2D" uid="uid://c5c3i2b10oslb" path="res://src/map/dungeon/models/column_room/COLUMN_ROOM_VER3_COLUMN_13.jpg" id="20_ae12c"] @@ -27,8 +28,8 @@ [ext_resource type="Material" uid="uid://bsafm3t4drpl" path="res://src/map/dungeon/textures/MinimapTexture.tres" id="25_3jgi2"] [ext_resource type="Texture2D" uid="uid://ca36l3t6htau7" path="res://src/map/dungeon/models/column_room/COLUMN_ROOM_VER3_brick3.png" id="25_hncep"] [ext_resource type="PackedScene" uid="uid://dbvr8ewajja6a" path="res://src/enemy/EnemyDatabase.tscn" id="25_jy2bd"] -[ext_resource type="Script" path="res://src/map/dungeon/code/MinimapManager.cs" id="26_l3250"] -[ext_resource type="Script" path="res://src/map/dungeon/corridor/remove_unused_doors.gd" id="26_uyqow"] +[ext_resource type="Script" uid="uid://c6s8hvdj3u3aq" path="res://src/map/dungeon/code/MinimapManager.cs" id="26_l3250"] +[ext_resource type="Script" uid="uid://yl7wyeo5m725" path="res://src/map/dungeon/corridor/remove_unused_doors.gd" id="26_uyqow"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_rone1"] resource_name = "Material.263" @@ -1537,6 +1538,8 @@ unique_name_in_owner = true [node name="EnemyDatabase" parent="ColumnRoom" instance=ExtResource("25_jy2bd")] unique_name_in_owner = true +EnemyList = Array[PackedScene]([ExtResource("5_nsoky")]) +SpawnRate = PackedFloat32Array(0.5) [node name="TeleportSpawn" type="Marker3D" parent="ColumnRoom"] unique_name_in_owner = true diff --git a/src/map/dungeon/scenes/InnerBalcony.tscn b/src/map/dungeon/scenes/InnerBalcony.tscn index d028c487..95c176cf 100644 --- a/src/map/dungeon/scenes/InnerBalcony.tscn +++ b/src/map/dungeon/scenes/InnerBalcony.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=85 format=4 uid="uid://b7111krf365x0"] +[gd_scene load_steps=86 format=4 uid="uid://b7111krf365x0"] [ext_resource type="Script" uid="uid://ce73fuh74l81l" path="res://addons/SimpleDungeons/DungeonRoom3D.gd" id="1_jccmw"] [ext_resource type="Script" uid="uid://daetb3e2nm56p" path="res://src/map/dungeon/code/DungeonRoom.cs" id="2_5p5p8"] @@ -18,6 +18,7 @@ [ext_resource type="PackedScene" uid="uid://twrj4wixcbu7" path="res://src/items/ItemDatabase.tscn" id="15_n8s21"] [ext_resource type="PackedScene" uid="uid://dbvr8ewajja6a" path="res://src/enemy/EnemyDatabase.tscn" id="16_mk0iw"] [ext_resource type="Script" uid="uid://yl7wyeo5m725" path="res://src/map/dungeon/corridor/remove_unused_doors.gd" id="17_atu1n"] +[ext_resource type="PackedScene" uid="uid://bksq62muhk3h5" path="res://src/enemy/enemy_types/sproingy/Sproingy.tscn" id="18_j7bvl"] [ext_resource type="Material" uid="uid://bsafm3t4drpl" path="res://src/map/dungeon/textures/MinimapTexture.tres" id="19_dmkqn"] [ext_resource type="Script" uid="uid://c6s8hvdj3u3aq" path="res://src/map/dungeon/code/MinimapManager.cs" id="19_gi8bh"] @@ -1192,6 +1193,8 @@ unique_name_in_owner = true [node name="EnemyDatabase" parent="InnerBalcony" instance=ExtResource("16_mk0iw")] unique_name_in_owner = true +EnemyList = Array[PackedScene]([ExtResource("18_j7bvl")]) +SpawnRate = PackedFloat32Array(0.5) [node name="TeleportSpawn" type="Marker3D" parent="InnerBalcony"] unique_name_in_owner = true diff --git a/src/map/dungeon/scenes/PitRoom2.tscn b/src/map/dungeon/scenes/PitRoom2.tscn index 417cb62a..036e516e 100644 --- a/src/map/dungeon/scenes/PitRoom2.tscn +++ b/src/map/dungeon/scenes/PitRoom2.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=87 format=4 uid="uid://cam640h4euewx"] +[gd_scene load_steps=88 format=4 uid="uid://cam640h4euewx"] [ext_resource type="Script" uid="uid://ce73fuh74l81l" path="res://addons/SimpleDungeons/DungeonRoom3D.gd" id="1_hww7y"] [ext_resource type="Script" uid="uid://daetb3e2nm56p" path="res://src/map/dungeon/code/DungeonRoom.cs" id="2_abm0b"] @@ -21,6 +21,7 @@ [ext_resource type="PackedScene" uid="uid://twrj4wixcbu7" path="res://src/items/ItemDatabase.tscn" id="19_yh0qc"] [ext_resource type="PackedScene" uid="uid://dbvr8ewajja6a" path="res://src/enemy/EnemyDatabase.tscn" id="20_5xp0x"] [ext_resource type="Script" uid="uid://yl7wyeo5m725" path="res://src/map/dungeon/corridor/remove_unused_doors.gd" id="21_5mo1p"] +[ext_resource type="PackedScene" uid="uid://bksq62muhk3h5" path="res://src/enemy/enemy_types/sproingy/Sproingy.tscn" id="21_ex11s"] [ext_resource type="Script" uid="uid://c6s8hvdj3u3aq" path="res://src/map/dungeon/code/MinimapManager.cs" id="22_h4dhe"] [ext_resource type="Material" uid="uid://bsafm3t4drpl" path="res://src/map/dungeon/textures/MinimapTexture.tres" id="23_2yaqs"] @@ -1303,6 +1304,8 @@ unique_name_in_owner = true [node name="EnemyDatabase" parent="PitRoom" instance=ExtResource("20_5xp0x")] unique_name_in_owner = true +EnemyList = Array[PackedScene]([ExtResource("21_ex11s")]) +SpawnRate = PackedFloat32Array(0.5) [node name="DirectionalLight3D" type="DirectionalLight3D" parent="PitRoom"] transform = Transform3D(-0.866024, -0.433016, 0.250001, 0, 0.499998, 0.866026, -0.500003, 0.749999, -0.43301, 0.764877, 4.39249, -0.482112) diff --git a/src/map/dungeon/scenes/WaterRoom.tscn b/src/map/dungeon/scenes/WaterRoom.tscn index 368342e3..328a2021 100644 --- a/src/map/dungeon/scenes/WaterRoom.tscn +++ b/src/map/dungeon/scenes/WaterRoom.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=89 format=4 uid="uid://dfpyfpnya0f4u"] +[gd_scene load_steps=90 format=4 uid="uid://dfpyfpnya0f4u"] [ext_resource type="Script" uid="uid://ce73fuh74l81l" path="res://addons/SimpleDungeons/DungeonRoom3D.gd" id="1_ulct7"] [ext_resource type="Script" uid="uid://daetb3e2nm56p" path="res://src/map/dungeon/code/DungeonRoom.cs" id="2_7yem4"] @@ -27,6 +27,7 @@ [ext_resource type="PackedScene" uid="uid://twrj4wixcbu7" path="res://src/items/ItemDatabase.tscn" id="24_7qo1y"] [ext_resource type="Material" uid="uid://bsafm3t4drpl" path="res://src/map/dungeon/textures/MinimapTexture.tres" id="24_w0ing"] [ext_resource type="PackedScene" uid="uid://dbvr8ewajja6a" path="res://src/enemy/EnemyDatabase.tscn" id="25_bfjom"] +[ext_resource type="PackedScene" uid="uid://bksq62muhk3h5" path="res://src/enemy/enemy_types/sproingy/Sproingy.tscn" id="25_hc66w"] [ext_resource type="Script" uid="uid://yl7wyeo5m725" path="res://src/map/dungeon/corridor/remove_unused_doors.gd" id="26_c86xl"] [ext_resource type="Script" uid="uid://c6s8hvdj3u3aq" path="res://src/map/dungeon/code/MinimapManager.cs" id="28_txiha"] @@ -1194,6 +1195,8 @@ unique_name_in_owner = true [node name="EnemyDatabase" parent="Water Room" instance=ExtResource("25_bfjom")] unique_name_in_owner = true +EnemyList = Array[PackedScene]([ExtResource("25_hc66w")]) +SpawnRate = PackedFloat32Array(0.5) [node name="TeleportSpawn" type="Marker3D" parent="Water Room"] unique_name_in_owner = true diff --git a/src/player/Player.cs b/src/player/Player.cs index a23213e1..f82fb157 100644 --- a/src/player/Player.cs +++ b/src/player/Player.cs @@ -17,6 +17,8 @@ namespace GameJamDungeon public void ApplyCentralImpulseToPlayer(Vector3 velocity); + public void TakeDamage(double damage, ElementType elementType, bool isCriticalHit = false); + public void LevelUp(); event Player.InventoryButtonPressedEventHandler InventoryButtonPressed; @@ -185,19 +187,22 @@ namespace GameJamDungeon Hitbox.AreaEntered += Hitbox_AreaEntered; } - private void Hitbox_AreaEntered(Area3D area) - { - var enemy = Hitbox.GetParent(); - enemy.TakeDamage((PlayerStatResource.CurrentAttack + PlayerStatResource.BonusAttack) * PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.ElementalDamageBonus, - PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.WeaponElement, - ignoreElementalResistance: PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.WeaponTags.Contains(WeaponTag.IgnoreAffinity)); - } - public void OnReady() { SetPhysicsProcess(true); } + public void TakeDamage(double damage, ElementType elementType, bool isCriticalHit = false) + { + if (PlayerData.CurrentHP.Value > 0) + { + damage = CalculateDefenseResistance(damage); + if (isCriticalHit) + damage *= 2; + PlayerData.SetCurrentHP(PlayerData.CurrentHP.Value - (int)damage); + } + } + public void LevelUp() { var nextLevel = PlayerData.CurrentLevel.Value + 1; @@ -342,5 +347,22 @@ namespace GameJamDungeon if (PlayerData.CurrentExp.Value >= PlayerData.ExpToNextLevel.Value) LevelUp(); } + + private double CalculateDefenseResistance(double incomingDamage) + { + return Mathf.Max(incomingDamage - (PlayerData.CurrentDefense.Value + PlayerData.BonusDefense), 0.0); + } + + private void Hitbox_AreaEntered(Area3D area) + { + var target = area.GetOwner(); + if (target is IEnemy enemy) + { + enemy.TakeDamage( + (PlayerStatResource.CurrentAttack + PlayerStatResource.BonusAttack + PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.Damage) * PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.ElementalDamageBonus, + PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.WeaponElement, + ignoreElementalResistance: PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.WeaponTags.Contains(WeaponTag.IgnoreAffinity)); + } + } } } diff --git a/src/player/Player.tscn b/src/player/Player.tscn index f6039a90..686b79da 100644 --- a/src/player/Player.tscn +++ b/src/player/Player.tscn @@ -355,8 +355,8 @@ _defaultArmor = ExtResource("4_bj1ma") [node name="Hitbox" type="Area3D" parent="."] unique_name_in_owner = true transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, -1) -collision_layer = 16 -collision_mask = 16 +collision_layer = 2048 +collision_mask = 2048 script = ExtResource("2_lb3qc") [node name="HitboxCollision" type="CollisionShape3D" parent="Hitbox"] diff --git a/src/system/IHasPrimaryAttack.cs.uid b/src/system/IHasPrimaryAttack.cs.uid new file mode 100644 index 00000000..b1ba9022 --- /dev/null +++ b/src/system/IHasPrimaryAttack.cs.uid @@ -0,0 +1 @@ +uid://dwis2q4bq3mhn diff --git a/src/system/stats/BattleExtensions.cs b/src/system/stats/BattleExtensions.cs new file mode 100644 index 00000000..6f2bec0a --- /dev/null +++ b/src/system/stats/BattleExtensions.cs @@ -0,0 +1,16 @@ +using Godot; + +namespace GameJamDungeon +{ + public static class BattleExtensions + { + public static bool IsCriticalHit(double luckStat) + { + var rng = new RandomNumberGenerator(); + rng.Randomize(); + var roll = rng.Randf(); + var isCriticalHit = roll <= luckStat; + return isCriticalHit; + } + } +} diff --git a/src/system/stats/DamageCalculator.cs b/src/system/stats/DamageCalculator.cs deleted file mode 100644 index 56656ee1..00000000 --- a/src/system/stats/DamageCalculator.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Godot; - -namespace GameJamDungeon -{ - public static class DamageCalculator - { - public static double CalculateWeaponAttackDamage(int totalAttack, WeaponStats weapon) - { - var totalDamage = totalAttack * weapon.ElementalDamageBonus; - return Mathf.Max(totalDamage, 0.0); - } - } -}