Demon wall implementation (attack data, takes damage, dies, etc) but mostly placeholders
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
using Godot;
|
||||
using Zennysoft.Ma.Adapter.Entity;
|
||||
|
||||
namespace Zennysoft.Ma.Adapter
|
||||
{
|
||||
public class DamageCalculator : IDamageCalculator
|
||||
{
|
||||
public double CalculateDamage(double damage,
|
||||
ElementType elementType,
|
||||
double defense,
|
||||
ElementalResistanceSet elementalResistanceSet,
|
||||
bool isCriticalHit = false,
|
||||
bool ignoreDefense = false,
|
||||
bool ignoreElementalResistance = false)
|
||||
{
|
||||
var calculatedDamage = damage;
|
||||
if (!ignoreElementalResistance)
|
||||
calculatedDamage = CalculateElementalResistance(calculatedDamage, elementType, elementalResistanceSet);
|
||||
if (!ignoreDefense)
|
||||
calculatedDamage = CalculateDefenseResistance(calculatedDamage, defense);
|
||||
if (isCriticalHit)
|
||||
calculatedDamage *= 2;
|
||||
|
||||
return calculatedDamage;
|
||||
}
|
||||
|
||||
private static double CalculateDefenseResistance(double incomingDamage, double defense)
|
||||
{
|
||||
return Mathf.Max(incomingDamage - defense, 0.0);
|
||||
}
|
||||
|
||||
private static double CalculateElementalResistance(
|
||||
double incomingDamage,
|
||||
ElementType incomingElementType,
|
||||
ElementalResistanceSet elementalResistanceSet)
|
||||
{
|
||||
var resistance = elementalResistanceSet.ElementalResistance[incomingElementType];
|
||||
return Mathf.Max(incomingDamage - (incomingDamage * resistance), 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
public interface IDamageCalculator
|
||||
{
|
||||
public double CalculateDamage(double damage,
|
||||
ElementType elementType,
|
||||
double defense,
|
||||
ElementalResistanceSet elementalResistanceSet,
|
||||
bool isCriticalHit = false,
|
||||
bool ignoreDefense = false,
|
||||
bool ignoreElementalResistance = false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
namespace Zennysoft.Ma.Adapter.Entity
|
||||
{
|
||||
public record ElementalResistanceSet
|
||||
{
|
||||
public Dictionary<ElementType, double> ElementalResistance { get; }
|
||||
|
||||
public ElementalResistanceSet(double aeolicResistance, double hydricResistance, double igneousResistance, double ferrumResistance, double telluricResistance)
|
||||
{
|
||||
ElementalResistance = new Dictionary<ElementType, double>
|
||||
{
|
||||
{ ElementType.None, 0 },
|
||||
{ ElementType.Aeolic, aeolicResistance },
|
||||
{ ElementType.Hydric, hydricResistance },
|
||||
{ ElementType.Igneous, igneousResistance },
|
||||
{ ElementType.Ferrum, ferrumResistance },
|
||||
{ ElementType.Telluric, telluricResistance },
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
using Chickensoft.Collections;
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Serialization;
|
||||
using Godot;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ public partial class BossTypeA : Enemy, IHasPrimaryAttack, IHasSecondaryAttack,
|
||||
|
||||
public double SecondaryAttackElementalDamageBonus { get; set; } = 1.0;
|
||||
|
||||
[Node] public new EnemyModelView3D _enemyModelView { get; set; }
|
||||
[Node] public new BossTypeAEnemyModelView _enemyModelView { get; set; }
|
||||
|
||||
[Node] public CollisionShape3D EnemyHitbox { get; set; } = default!;
|
||||
|
||||
|
||||
@@ -52,6 +52,8 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
|
||||
|
||||
private Vector3 _knockbackDirection = Vector3.Zero;
|
||||
|
||||
private IDamageCalculator _damageCalculator;
|
||||
|
||||
#region Godot methods
|
||||
public void Setup()
|
||||
{
|
||||
@@ -59,6 +61,7 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
|
||||
_enemyLogic.Set(_enemyStatResource);
|
||||
_enemyLogic.Set(this as IEnemy);
|
||||
_enemyLogic.Set(_player);
|
||||
_damageCalculator = new DamageCalculator();
|
||||
}
|
||||
|
||||
public void OnResolved()
|
||||
@@ -118,12 +121,13 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
|
||||
{
|
||||
if (CurrentHP.Value > 0)
|
||||
{
|
||||
if (!ignoreElementalResistance)
|
||||
damage = CalculateElementalResistance(damage, elementType);
|
||||
if (!ignoreDefense)
|
||||
damage = CalculateDefenseResistance(damage);
|
||||
if (isCriticalHit)
|
||||
damage *= 2;
|
||||
_damageCalculator.CalculateDamage(damage,
|
||||
elementType,
|
||||
_player.Stats.CurrentDefense.Value + _player.Stats.BonusDefense.Value,
|
||||
_enemyStatResource.ElementalResistance,
|
||||
isCriticalHit,
|
||||
ignoreDefense,
|
||||
ignoreElementalResistance);
|
||||
GD.Print($"Enemy Hit for {damage} damage.");
|
||||
CurrentHP.OnNext(CurrentHP.Value - damage);
|
||||
GD.Print("Current HP: " + CurrentHP.Value);
|
||||
@@ -151,7 +155,7 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
|
||||
_enemyLogic.Input(new EnemyLogic.Input.EnemyDefeated());
|
||||
_collisionShape.SetDeferred("disabled", true);
|
||||
_enemyModelView.PlayDeathAnimation();
|
||||
var tweener = GetTree().CreateTween();
|
||||
var tweener = CreateTween();
|
||||
tweener.TweenInterval(1.0f);
|
||||
tweener.TweenCallback(Callable.From(QueueFree));
|
||||
Game.EnemyDefeated(GlobalPosition, _enemyStatResource);
|
||||
@@ -238,22 +242,6 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
|
||||
Die();
|
||||
}
|
||||
|
||||
private double CalculateElementalResistance(double incomingDamage, ElementType incomingElementType)
|
||||
{
|
||||
if (incomingElementType == ElementType.Aeolic)
|
||||
return Mathf.Max(incomingDamage - (incomingDamage * _enemyStatResource.AeolicResistance), 0.0);
|
||||
if (incomingElementType == ElementType.Hydric)
|
||||
return Mathf.Max(incomingDamage - (incomingDamage * _enemyStatResource.HydricResistance), 0.0);
|
||||
if (incomingElementType == ElementType.Igneous)
|
||||
return Mathf.Max(incomingDamage - (incomingDamage * _enemyStatResource.IgneousResistance), 0.0);
|
||||
if (incomingElementType == ElementType.Ferrum)
|
||||
return Mathf.Max(incomingDamage - (incomingDamage * _enemyStatResource.FerrumResistance), 0.0);
|
||||
if (incomingElementType == ElementType.Telluric)
|
||||
return Mathf.Max(incomingDamage - (incomingDamage * _enemyStatResource.TelluricResistance), 0.0);
|
||||
|
||||
return Mathf.Max(incomingDamage, 0.0);
|
||||
}
|
||||
|
||||
private double CalculateDefenseResistance(double incomingDamage)
|
||||
{
|
||||
return Mathf.Max(incomingDamage - _enemyStatResource.CurrentDefense, 0.0);
|
||||
|
||||
@@ -24,14 +24,8 @@ public partial class EnemyModelView3D : Node3D, IEnemyModelView
|
||||
|
||||
[Node] public AnimationTree AnimationTree { get; set; } = default!;
|
||||
|
||||
[Node] public IHitbox Hitbox { get; set; } = default!;
|
||||
|
||||
[Node] public MeshInstance3D MeshInstance { get; set; } = default!;
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
}
|
||||
|
||||
public void PlayPrimaryAttackAnimation()
|
||||
{
|
||||
AnimationTree.Get(PARAMETERS_PLAYBACK).As<AnimationNodeStateMachinePlayback>().Travel(PRIMARY_ATTACK);
|
||||
@@ -49,7 +43,7 @@ public partial class EnemyModelView3D : Node3D, IEnemyModelView
|
||||
|
||||
public void PlayHitAnimation()
|
||||
{
|
||||
var tweener = GetTree().CreateTween();
|
||||
var tweener = CreateTween();
|
||||
ChangeMaterial();
|
||||
tweener.TweenMethod(Callable.From((float x) => SetTransparency(x)), 0.0f, 0.5f, 0.3f);
|
||||
tweener.TweenCallback(Callable.From(ClearDamageEffect));
|
||||
@@ -58,7 +52,7 @@ public partial class EnemyModelView3D : Node3D, IEnemyModelView
|
||||
public void PlayDeathAnimation()
|
||||
{
|
||||
LoadShader("res://src/enemy/EnemyDie.tres");
|
||||
var tweener = GetTree().CreateTween();
|
||||
var tweener = CreateTween();
|
||||
tweener.TweenMethod(Callable.From((float x) => SetTransparency(x)), 0.0f, 1.0f, 0.8f);
|
||||
tweener.TweenCallback(Callable.From(QueueFree));
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Godot;
|
||||
using Zennysoft.Ma.Adapter.Entity;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
@@ -30,19 +31,21 @@ public partial class EnemyStatResource : Resource
|
||||
public double Luck { get; set; } = 0.05f;
|
||||
|
||||
[Export]
|
||||
public double TelluricResistance { get; set; }
|
||||
private double _telluricResistance { get; set; }
|
||||
|
||||
[Export]
|
||||
public double AeolicResistance { get; set; }
|
||||
private double _aeolicResistance { get; set; }
|
||||
|
||||
[Export]
|
||||
public double HydricResistance { get; set; }
|
||||
private double _hydricResistance { get; set; }
|
||||
|
||||
[Export]
|
||||
public double IgneousResistance { get; set; }
|
||||
private double _igneousResistance { get; set; }
|
||||
|
||||
[Export]
|
||||
public double FerrumResistance { get; set; }
|
||||
private double _ferrumResistance { get; set; }
|
||||
|
||||
public ElementalResistanceSet ElementalResistance => new ElementalResistanceSet(_aeolicResistance, _hydricResistance, _igneousResistance, _ferrumResistance, _telluricResistance);
|
||||
|
||||
[Export]
|
||||
public float DropsSoulGemChance { get; set; } = 0.75f;
|
||||
|
||||
@@ -15,11 +15,11 @@ MaxAttack = 15
|
||||
MaxDefense = 0
|
||||
ExpFromDefeat = 5
|
||||
Luck = 0.05
|
||||
TelluricResistance = 0.0
|
||||
AeolicResistance = 0.0
|
||||
HydricResistance = 0.0
|
||||
IgneousResistance = 0.0
|
||||
FerrumResistance = 0.0
|
||||
_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")
|
||||
|
||||
|
||||
@@ -2,30 +2,6 @@
|
||||
|
||||
[sub_resource type="Animation" id="Animation_ttkyx"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("Hitbox/CollisionShape3D:disabled")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [true]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("Hitbox/CollisionShape3D:disabled")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [true]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_sfyuh"]
|
||||
resource_name = "idle"
|
||||
@@ -594,18 +570,6 @@ tracks/39/path = NodePath("Armature/Skeleton3D:heelIK_R")
|
||||
tracks/39/interp = 0
|
||||
tracks/39/loop_wrap = true
|
||||
tracks/39/keys = PackedFloat32Array(0, 1, -0.456756, -0.539878, 0.539587, 0.456893)
|
||||
tracks/40/type = "value"
|
||||
tracks/40/imported = false
|
||||
tracks/40/enabled = true
|
||||
tracks/40/path = NodePath("Hitbox/CollisionShape3D:disabled")
|
||||
tracks/40/interp = 1
|
||||
tracks/40/loop_wrap = true
|
||||
tracks/40/keys = {
|
||||
"times": PackedFloat32Array(0, 0.1, 0.2),
|
||||
"transitions": PackedFloat32Array(1, 1, 1),
|
||||
"update": 1,
|
||||
"values": [true, false, true]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_fdnqs"]
|
||||
resource_name = "SHIELD BASH"
|
||||
@@ -890,18 +854,6 @@ tracks/39/path = NodePath("Armature/Skeleton3D:heelIK_R")
|
||||
tracks/39/interp = 0
|
||||
tracks/39/loop_wrap = true
|
||||
tracks/39/keys = PackedFloat32Array(0, 1, -0.456756, -0.539878, 0.539587, 0.456893)
|
||||
tracks/40/type = "value"
|
||||
tracks/40/imported = false
|
||||
tracks/40/enabled = true
|
||||
tracks/40/path = NodePath("Hitbox/CollisionShape3D:disabled")
|
||||
tracks/40/interp = 1
|
||||
tracks/40/loop_wrap = true
|
||||
tracks/40/keys = {
|
||||
"times": PackedFloat32Array(0, 0.533333, 0.633333),
|
||||
"transitions": PackedFloat32Array(1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [true, false, true]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_ui3ue"]
|
||||
resource_name = "WALK"
|
||||
|
||||
@@ -14,11 +14,11 @@ MaxAttack = 0
|
||||
MaxDefense = 0
|
||||
ExpFromDefeat = 0
|
||||
Luck = 0.05
|
||||
TelluricResistance = 0.0
|
||||
AeolicResistance = 0.0
|
||||
HydricResistance = 0.0
|
||||
IgneousResistance = 0.0
|
||||
FerrumResistance = 0.0
|
||||
_telluricResistance = 0.0
|
||||
_aeolicResistance = 0.0
|
||||
_hydricResistance = 0.0
|
||||
_igneousResistance = 0.0
|
||||
_ferrumResistance = 0.0
|
||||
DropsSoulGemChance = 0.75
|
||||
metadata/_custom_type_script = "uid://dnkmr0eq1sij0"
|
||||
|
||||
|
||||
@@ -200,7 +200,7 @@ bones/0/name = "spine1"
|
||||
bones/0/parent = -1
|
||||
bones/0/rest = Transform3D(1.49012e-06, 0.00846654, -0.999964, 2.93367e-08, 0.999964, 0.00846654, 1, -4.23752e-08, 1.49012e-06, 0.000155807, -0.00105953, -2.01735)
|
||||
bones/0/enabled = true
|
||||
bones/0/position = Vector3(-0.260278, -1.0541, -1.96767)
|
||||
bones/0/position = Vector3(-0.259488, -0.96383, -1.97376)
|
||||
bones/0/rotation = Quaternion(0.0915277, -0.692111, -0.0341586, 0.715149)
|
||||
bones/0/scale = Vector3(1, 1, 1)
|
||||
bones/1/name = "spine0"
|
||||
@@ -243,7 +243,7 @@ bones/6/parent = 5
|
||||
bones/6/rest = Transform3D(0.0598389, 0.98531, 0.15995, -0.975271, 0.0235553, 0.219755, 0.212759, -0.169144, 0.962353, 3.65078e-07, 1.40318, 0)
|
||||
bones/6/enabled = true
|
||||
bones/6/position = Vector3(3.65078e-07, 1.40318, 0)
|
||||
bones/6/rotation = Quaternion(-0.0474983, -0.294201, -0.744151, 0.597854)
|
||||
bones/6/rotation = Quaternion(-0.0697867, -0.302352, -0.744713, 0.59086)
|
||||
bones/6/scale = Vector3(1, 1, 1)
|
||||
bones/7/name = "Bone.007"
|
||||
bones/7/parent = 6
|
||||
@@ -278,7 +278,7 @@ bones/11/parent = 1
|
||||
bones/11/rest = Transform3D(0.981457, 0.0769315, -0.175568, 0.18837, -0.217537, 0.957703, 0.035485, -0.973015, -0.227995, -1.09896e-07, 3.84743, -2.10479e-07)
|
||||
bones/11/enabled = true
|
||||
bones/11/position = Vector3(-1.09896e-07, 3.84743, -2.10479e-07)
|
||||
bones/11/rotation = Quaternion(-0.779754, -0.0572995, 0.0817541, 0.618075)
|
||||
bones/11/rotation = Quaternion(-0.784729, -0.0616535, 0.0718257, 0.612568)
|
||||
bones/11/scale = Vector3(1, 0.999999, 1)
|
||||
bones/12/name = "arm2_L"
|
||||
bones/12/parent = 11
|
||||
@@ -306,7 +306,7 @@ bones/15/parent = 1
|
||||
bones/15/rest = Transform3D(-0.98213, 0.0512573, -0.181089, -0.187541, -0.185921, 0.964501, 0.0157694, 0.981227, 0.192212, 0.00107862, 3.8461, -0.0821097)
|
||||
bones/15/enabled = true
|
||||
bones/15/position = Vector3(0.00107886, 3.8461, -0.0821095)
|
||||
bones/15/rotation = Quaternion(-0.215469, 0.745349, 0.613517, -0.147056)
|
||||
bones/15/rotation = Quaternion(-0.210671, 0.737877, 0.621635, -0.157245)
|
||||
bones/15/scale = Vector3(1, 1, 1)
|
||||
bones/16/name = "arm2_R"
|
||||
bones/16/parent = 15
|
||||
@@ -333,22 +333,22 @@ bones/19/name = "hip_L"
|
||||
bones/19/parent = -1
|
||||
bones/19/rest = Transform3D(0.138486, 0.897208, 0.419333, -0.129033, -0.403458, 0.905854, 0.981923, -0.179556, 0.059896, 0.000155807, -0.00105953, -2.01735)
|
||||
bones/19/enabled = true
|
||||
bones/19/position = Vector3(-0.381736, -1.20058, -1.71562)
|
||||
bones/19/rotation = Quaternion(0.627802, 0.292645, 0.544916, -0.472536)
|
||||
bones/19/position = Vector3(-0.309033, -1.1318, -1.95517)
|
||||
bones/19/rotation = Quaternion(0.612762, 0.310855, 0.569327, -0.451397)
|
||||
bones/19/scale = Vector3(1, 1, 1)
|
||||
bones/20/name = "leg1_L"
|
||||
bones/20/parent = 19
|
||||
bones/20/rest = Transform3D(0.945603, 0.113405, 0.304916, -0.324072, 0.410457, 0.852351, -0.0284943, -0.9048, 0.424881, 2.08616e-07, 2.00996, -7.1153e-07)
|
||||
bones/20/enabled = true
|
||||
bones/20/position = Vector3(2.08616e-07, 2.00996, -7.1153e-07)
|
||||
bones/20/rotation = Quaternion(-0.327961, -0.422555, -0.300918, 0.789517)
|
||||
bones/20/rotation = Quaternion(-0.312233, -0.440038, -0.274881, 0.795813)
|
||||
bones/20/scale = Vector3(1, 0.999999, 1)
|
||||
bones/21/name = "leg2_L"
|
||||
bones/21/parent = 20
|
||||
bones/21/rest = Transform3D(0.990336, -0.138679, 0.00180777, 0.138628, 0.990193, 0.0173138, -0.00419111, -0.0168959, 0.999848, 5.96046e-08, 5.85994, -5.23403e-07)
|
||||
bones/21/enabled = true
|
||||
bones/21/position = Vector3(5.96046e-08, 5.85994, -5.23403e-07)
|
||||
bones/21/rotation = Quaternion(-0.0604978, 0.00129835, 0.489732, 0.869771)
|
||||
bones/21/rotation = Quaternion(-0.0601745, 0.00130057, 0.487115, 0.871261)
|
||||
bones/21/scale = Vector3(1, 1, 1)
|
||||
bones/22/name = "foot1_L"
|
||||
bones/22/parent = 21
|
||||
@@ -382,7 +382,7 @@ bones/26/name = "hip_R"
|
||||
bones/26/parent = -1
|
||||
bones/26/rest = Transform3D(0.138486, -0.897208, -0.419333, 0.129033, -0.403458, 0.905854, -0.981923, -0.179556, 0.059896, -0.000155807, -0.00105953, -2.01735)
|
||||
bones/26/enabled = true
|
||||
bones/26/position = Vector3(-0.0213137, -1.11395, -2.01918)
|
||||
bones/26/position = Vector3(-0.235011, -1.11395, -2.01773)
|
||||
bones/26/rotation = Quaternion(0.608697, -0.3155, -0.575514, -0.445793)
|
||||
bones/26/scale = Vector3(1, 1, 1)
|
||||
bones/27/name = "leg1_R"
|
||||
@@ -390,14 +390,14 @@ bones/27/parent = 26
|
||||
bones/27/rest = Transform3D(0.945603, -0.113405, -0.304916, 0.324072, 0.410457, 0.852351, 0.0284943, -0.9048, 0.424881, -9.54606e-09, 2.00996, -3.52971e-07)
|
||||
bones/27/enabled = true
|
||||
bones/27/position = Vector3(-9.54606e-09, 2.00996, -3.52971e-07)
|
||||
bones/27/rotation = Quaternion(-0.202201, 0.424694, 0.137914, 0.871625)
|
||||
bones/27/rotation = Quaternion(-0.207711, 0.421647, 0.141893, 0.871169)
|
||||
bones/27/scale = Vector3(1, 0.999999, 1)
|
||||
bones/28/name = "leg2_R"
|
||||
bones/28/parent = 27
|
||||
bones/28/rest = Transform3D(0.990336, 0.138679, -0.00180777, -0.138628, 0.990193, 0.0173138, 0.00419111, -0.0168959, 0.999848, 4.51691e-08, 5.85994, -3.72529e-09)
|
||||
bones/28/enabled = true
|
||||
bones/28/position = Vector3(4.51691e-08, 5.85994, -3.72529e-09)
|
||||
bones/28/rotation = Quaternion(-0.0627787, -0.00116448, -0.501219, 0.863039)
|
||||
bones/28/rotation = Quaternion(-0.0640421, -0.00115636, -0.511308, 0.857007)
|
||||
bones/28/scale = Vector3(1, 1, 1)
|
||||
bones/29/name = "foot1_R"
|
||||
bones/29/parent = 28
|
||||
@@ -429,7 +429,7 @@ bones/32/rotation = Quaternion(0.456756, 0.539878, -0.539587, -0.456893)
|
||||
bones/32/scale = Vector3(1, 1, 1)
|
||||
|
||||
[node name="BoneAttachment3D" type="BoneAttachment3D" parent="Armature/Skeleton3D"]
|
||||
transform = Transform3D(-0.266252, -0.0359368, -0.963233, -0.333724, -0.934064, 0.127095, -0.904288, 0.355294, 0.236703, -1.68949, 8.19963, 4.95696)
|
||||
transform = Transform3D(-0.291816, -0.0758791, -0.95346, -0.329798, -0.927733, 0.174769, -0.897817, 0.36545, 0.245702, -1.66649, 8.30024, 4.94846)
|
||||
bone_name = "TOP OF SKULL"
|
||||
bone_idx = 8
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,26 +1,7 @@
|
||||
[gd_scene load_steps=11 format=3 uid="uid://dxrgfh28wj5su"]
|
||||
[gd_scene load_steps=10 format=3 uid="uid://dxrgfh28wj5su"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://vgvrmwsrwakf" path="res://src/enemy/enemy_types/16. demon wall/DemonWallArm.cs" id="1_fhrhk"]
|
||||
[ext_resource type="PackedScene" uid="uid://dafhaya5sejdj" path="res://src/enemy/enemy_types/16. demon wall/model/ARM3.glb" id="1_wuuwb"]
|
||||
[ext_resource type="Script" uid="uid://dnkmr0eq1sij0" path="res://src/enemy/EnemyStatResource.cs" id="2_afuej"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_gcbec"]
|
||||
script = ExtResource("2_afuej")
|
||||
CurrentHP = 20.0
|
||||
MaximumHP = 20
|
||||
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.0
|
||||
metadata/_custom_type_script = "uid://dnkmr0eq1sij0"
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_bpd8u"]
|
||||
animation = &"ARM 3 WALL CALL"
|
||||
@@ -46,11 +27,10 @@ states/idle/node = SubResource("AnimationNodeAnimation_ccv8a")
|
||||
states/idle/position = Vector2(339, 112)
|
||||
transitions = ["Start", "idle", SubResource("AnimationNodeStateMachineTransition_sjgs2"), "idle", "attack", SubResource("AnimationNodeStateMachineTransition_p21h7"), "attack", "idle", SubResource("AnimationNodeStateMachineTransition_1weac")]
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_fhrhk"]
|
||||
|
||||
[node name="Arm3" type="Node3D"]
|
||||
script = ExtResource("1_fhrhk")
|
||||
_enemyStatResource = SubResource("Resource_gcbec")
|
||||
PrimaryAttackElementalType = null
|
||||
PrimaryAttackElementalDamageBonus = null
|
||||
|
||||
[node name="ARM3" parent="." instance=ExtResource("1_wuuwb")]
|
||||
|
||||
@@ -59,3 +39,12 @@ unique_name_in_owner = true
|
||||
root_node = NodePath("%AnimationTree/..")
|
||||
tree_root = SubResource("AnimationNodeStateMachine_fhrhk")
|
||||
anim_player = NodePath("../AnimationPlayer")
|
||||
|
||||
[node name="Hitbox" type="Area3D" parent="ARM3"]
|
||||
unique_name_in_owner = true
|
||||
collision_layer = 0
|
||||
collision_mask = 0
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="ARM3/Hitbox"]
|
||||
shape = SubResource("BoxShape3D_fhrhk")
|
||||
disabled = true
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -1,4 +1,5 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Collections;
|
||||
using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
using System.Linq;
|
||||
@@ -7,7 +8,7 @@ using Zennysoft.Ma.Adapter;
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class DemonWall : CharacterBody3D
|
||||
public partial class DemonWall : CharacterBody3D, IEnemy
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
@@ -15,89 +16,87 @@ public partial class DemonWall : CharacterBody3D
|
||||
|
||||
[Export] protected EnemyStatResource _enemyStatResource { get; set; } = default!;
|
||||
|
||||
[Node] private DemonWallArm _arm3 { get; set; } = default!;
|
||||
[Node] public DemonWallModelView EnemyModelView { get; set; } = default!;
|
||||
|
||||
[Node] public Node3D LeftArms { get; set; } = default!;
|
||||
|
||||
[Node] public Node3D RightArms { get; set; } = default!;
|
||||
|
||||
[Node] public MeshInstance3D Eye { get; set; } = default!;
|
||||
|
||||
[Node] private Node3D _rotation { get; set; } = default!;
|
||||
|
||||
[Node] private AnimatableBody3D _opposingWall { get; set; } = default!;
|
||||
public AutoProp<double> CurrentHP { get; private set; }
|
||||
|
||||
[Export] private double _maximumWallMoveAmount = 24;
|
||||
|
||||
private Timer _attackTimer;
|
||||
|
||||
public void OnPhysicsProcess(double delta)
|
||||
private IDamageCalculator _damageCalculator;
|
||||
|
||||
public void OnReady()
|
||||
{
|
||||
var direction = GlobalPosition.DirectionTo(_player.CurrentPosition).Normalized();
|
||||
var rotationAngle = GetRotationAngle();
|
||||
RotateToPlayer(rotationAngle);
|
||||
CurrentHP = new AutoProp<double>(_enemyStatResource.MaximumHP);
|
||||
_attackTimer = new Timer { WaitTime = 5f };
|
||||
_attackTimer.Timeout += AttackTimer_Timeout;
|
||||
AddChild(_attackTimer);
|
||||
_damageCalculator = new DamageCalculator();
|
||||
CurrentHP.Sync += CurrentHP_Sync;
|
||||
}
|
||||
|
||||
public void RotateToPlayer(float rotationAngle)
|
||||
private void CurrentHP_Sync(double newHP)
|
||||
{
|
||||
var tweener = GetTree().CreateTween();
|
||||
tweener.TweenMethod(Callable.From((float x) => RotateTowardsPlayer(x)), Eye.Rotation.Y, rotationAngle, 1f);
|
||||
if (newHP <= 0)
|
||||
Die();
|
||||
}
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
_opposingWall.Show();
|
||||
var collisionShape = _opposingWall.GetChildren().OfType<CollisionShape3D>().Single();
|
||||
collisionShape.SetDeferred(CollisionShape3D.PropertyName.Disabled, false);
|
||||
|
||||
_attackTimer = new Timer { WaitTime = 5f };
|
||||
_attackTimer.Timeout += AttackTimer_Timeout;
|
||||
AddChild(_attackTimer);
|
||||
EnemyModelView.Activate();
|
||||
SetPhysicsProcess(true);
|
||||
_attackTimer.Start();
|
||||
StartAttackTimer();
|
||||
}
|
||||
|
||||
private void AttackTimer_Timeout()
|
||||
{
|
||||
var rng = new RandomNumberGenerator();
|
||||
rng.Randomize();
|
||||
|
||||
var leftArms = new Godot.Collections.Array<DemonWallArm>(LeftArms.GetChildren().Cast<DemonWallArm>());
|
||||
var rightArms = new Godot.Collections.Array<DemonWallArm>(RightArms.GetChildren().Cast<DemonWallArm>());
|
||||
|
||||
var leftArm = leftArms.PickRandom();
|
||||
var rightArm = rightArms.PickRandom();
|
||||
|
||||
leftArm.PrimaryAttack();
|
||||
rightArm.PrimaryAttack();
|
||||
|
||||
if (leftArm == _arm3 && _opposingWall.Position.Z > -_maximumWallMoveAmount)
|
||||
MoveWall();
|
||||
}
|
||||
|
||||
private float GetRotationAngle()
|
||||
{
|
||||
var target = new Vector3(_player.CurrentPosition.X, Position.Y, _player.CurrentPosition.Z);
|
||||
_rotation.LookAt(target, Vector3.Up, true);
|
||||
_rotation.RotateY(Rotation.Y);
|
||||
return _rotation.Rotation.Y;
|
||||
}
|
||||
|
||||
private void MoveWall()
|
||||
{
|
||||
var tweener = GetTree().CreateTween();
|
||||
tweener.TweenMethod(Callable.From((float x) => MoveWallTowardsPlayer(x)), _opposingWall.Position.Z, _opposingWall.Position.Z - 2, 3f);
|
||||
}
|
||||
|
||||
private void RotateTowardsPlayer(float angle) => Eye.Rotation = new Vector3(Eye.Rotation.X, angle, Eye.Rotation.Z);
|
||||
|
||||
private void MoveWallTowardsPlayer(float moveAmount)
|
||||
{
|
||||
_opposingWall.Position = new Vector3(_opposingWall.Position.X, _opposingWall.Position.Y, moveAmount);
|
||||
TakeAction();
|
||||
}
|
||||
|
||||
public void OnExitTree()
|
||||
{
|
||||
_attackTimer.Timeout -= AttackTimer_Timeout;
|
||||
}
|
||||
|
||||
public void TakeAction()
|
||||
{
|
||||
EnemyModelView.Attack(_maximumWallMoveAmount);
|
||||
}
|
||||
|
||||
public void Move(Vector3 velocity) => throw new System.NotImplementedException();
|
||||
|
||||
public void TakeDamage(double damage, ElementType elementType = ElementType.None, bool isCriticalHit = false, bool ignoreDefense = false, bool ignoreElementalResistance = false)
|
||||
{
|
||||
var damageTaken = _damageCalculator.CalculateDamage(
|
||||
damage,
|
||||
elementType,
|
||||
_enemyStatResource.CurrentDefense,
|
||||
_enemyStatResource.ElementalResistance,
|
||||
isCriticalHit,
|
||||
ignoreDefense,
|
||||
ignoreElementalResistance);
|
||||
|
||||
CurrentHP.OnNext(CurrentHP.Value - damageTaken);
|
||||
GD.Print($"Demon Wall HP Left: {CurrentHP.Value}");
|
||||
EnemyModelView.PlayHitAnimation();
|
||||
}
|
||||
|
||||
public void Knockback(float impulse, Vector3 direction) => throw new System.NotImplementedException();
|
||||
public void SetCurrentHP(int newHP) => throw new System.NotImplementedException();
|
||||
public int GetMaximumHP() => _enemyStatResource.MaximumHP;
|
||||
public void StartAttackTimer() => _attackTimer.Start();
|
||||
public void StopAttackTimer() => _attackTimer.Stop();
|
||||
public void SetTarget(Vector3 target) => throw new System.NotImplementedException();
|
||||
public void SetEnemyGlobalPosition(Vector3 target) => throw new System.NotImplementedException();
|
||||
public Vector3 GetEnemyGlobalPosition() => throw new System.NotImplementedException();
|
||||
public IDungeonRoom GetCurrentRoom() => throw new System.NotImplementedException();
|
||||
|
||||
public async void Die()
|
||||
{
|
||||
CurrentHP.OnCompleted();
|
||||
EnemyModelView.PlayDeathAnimation();
|
||||
await ToSignal(GetTree().CreateTimer(0.8f), "timeout");
|
||||
CallDeferred(MethodName.QueueFree);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,6 +1,7 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
using System.Linq;
|
||||
using Zennysoft.Ma.Adapter;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
@@ -16,13 +17,29 @@ public partial class DemonWallArm : Node3D
|
||||
private const string PARAMETERS_PLAYBACK = "parameters/playback";
|
||||
private const string ATTACK = "attack";
|
||||
|
||||
[Dependency] protected IPlayer _player => this.DependOn(() => GetParent().GetChildren().OfType<IPlayer>().Single());
|
||||
|
||||
[Node] public AnimationTree AnimationTree { get; set; } = default!;
|
||||
|
||||
[Export] protected EnemyStatResource _enemyStatResource { get; set; } = default!;
|
||||
[Node] public Area3D Hitbox { get; set; } = default!;
|
||||
|
||||
[Export] public double Damage { get; set; } = 15;
|
||||
|
||||
[Export] public ElementType PrimaryAttackElementalType { get; set; } = ElementType.None;
|
||||
|
||||
[Export] public double PrimaryAttackElementalDamageBonus { get; set; } = 1.0f;
|
||||
|
||||
public void PrimaryAttack() => AnimationTree.Get(PARAMETERS_PLAYBACK).As<AnimationNodeStateMachinePlayback>().Travel(ATTACK);
|
||||
|
||||
public void OnReady()
|
||||
{
|
||||
Hitbox.AreaEntered += Hitbox_AreaEntered;
|
||||
}
|
||||
|
||||
private void Hitbox_AreaEntered(Area3D area)
|
||||
{
|
||||
var target = area.GetOwner();
|
||||
if (target is IPlayer player)
|
||||
player.TakeDamage(Damage * PrimaryAttackElementalDamageBonus, PrimaryAttackElementalType, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Zennysoft.Ma.Adapter;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class DemonWallModelView : EnemyModelView3D
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
[Dependency] protected IPlayer _player => this.DependOn(() => GetParent().GetChildren().OfType<IPlayer>().Single());
|
||||
|
||||
[Node] public Node3D LeftArms { get; set; } = default!;
|
||||
|
||||
[Node] public Node3D RightArms { get; set; } = default!;
|
||||
|
||||
[Node] public MeshInstance3D Eye { get; set; } = default!;
|
||||
|
||||
[Node] private Node3D _rotation { get; set; } = default!;
|
||||
|
||||
[Node] private AnimatableBody3D _opposingWall { get; set; } = default!;
|
||||
|
||||
public void Activate()
|
||||
{
|
||||
_opposingWall.Show();
|
||||
var collisionShape = _opposingWall.GetChildren().OfType<CollisionShape3D>().Single();
|
||||
collisionShape.SetDeferred(CollisionShape3D.PropertyName.Disabled, false);
|
||||
SetPhysicsProcess(true);
|
||||
}
|
||||
|
||||
public void OnPhysicsProcess(double delta)
|
||||
{
|
||||
var direction = GlobalPosition.DirectionTo(_player.CurrentPosition).Normalized();
|
||||
var rotationAngle = GetRotationAngle(_rotation);
|
||||
RotateToPlayer(Eye, rotationAngle, 1f);
|
||||
}
|
||||
|
||||
public void RotateToPlayer(Node3D rotateObject, float rotationAngle, float timeInSeconds)
|
||||
{
|
||||
var tweener = CreateTween();
|
||||
tweener.TweenMethod(Callable.From((float x) => RotateTowardsPlayer(rotateObject, x)), rotateObject.Rotation.Y, rotationAngle, timeInSeconds);
|
||||
}
|
||||
|
||||
public async void Attack(double maximumWallMoveAmount)
|
||||
{
|
||||
var rng = new RandomNumberGenerator();
|
||||
rng.Randomize();
|
||||
|
||||
var leftArms = new Godot.Collections.Array<DemonWallArm>(LeftArms.GetChildren().Cast<DemonWallArm>());
|
||||
var rightArms = new Godot.Collections.Array<DemonWallArm>(RightArms.GetChildren().Cast<DemonWallArm>());
|
||||
|
||||
var leftArm = leftArms.PickRandom();
|
||||
var rightArm = rightArms.PickRandom();
|
||||
|
||||
leftArm.PrimaryAttack();
|
||||
rightArm.PrimaryAttack();
|
||||
|
||||
var arm1 = GetNode<DemonWallArm>("%Arm1");
|
||||
var arm2 = GetNode<DemonWallArm>("%Arm2");
|
||||
var arm7 = GetNode<DemonWallArm>("%Arm2");
|
||||
|
||||
if (leftArm == arm1)
|
||||
await AimAtPlayer(arm1, 2.1);
|
||||
if (leftArm == arm2)
|
||||
await AimAtPlayer(arm2, 1.5);
|
||||
if (leftArm == GetNode<DemonWallArm>("%Arm3") && _opposingWall.Position.Z > -maximumWallMoveAmount)
|
||||
MoveWall();
|
||||
if (rightArm == arm7)
|
||||
await AimAtPlayer(arm7, 2.5);
|
||||
}
|
||||
|
||||
private async Task AimAtPlayer(DemonWallArm arm, double animationLengthInSeconds)
|
||||
{
|
||||
var rotationAngle = GetRotationAngle(arm.GetNode<Node3D>("%Rotation"));
|
||||
RotateToPlayer(arm.GetNode<Node3D>("%Pivot"), rotationAngle, 0.3f);
|
||||
await ToSignal(GetTree().CreateTimer(animationLengthInSeconds), "timeout");
|
||||
RotateToPlayer(arm.GetNode<Node3D>("%Pivot"), 0, 0.3f);
|
||||
}
|
||||
|
||||
private async void MoveWall()
|
||||
{
|
||||
await ToSignal(GetTree().CreateTimer(1.5f), "timeout");
|
||||
var tweener = CreateTween();
|
||||
tweener.TweenMethod(Callable.From((float x) => MoveWallTowardsPlayer(x)), _opposingWall.Position.Z, _opposingWall.Position.Z - 2, 3f);
|
||||
}
|
||||
|
||||
private void MoveWallTowardsPlayer(float moveAmount)
|
||||
{
|
||||
_opposingWall.Position = new Vector3(_opposingWall.Position.X, _opposingWall.Position.Y, moveAmount);
|
||||
}
|
||||
|
||||
private float GetRotationAngle(Node3D rotationNode)
|
||||
{
|
||||
var target = new Vector3(_player.CurrentPosition.X, Position.Y, _player.CurrentPosition.Z);
|
||||
rotationNode.LookAt(target, Vector3.Up, true);
|
||||
rotationNode.RotateY(Rotation.Y);
|
||||
return rotationNode.Rotation.Y;
|
||||
}
|
||||
|
||||
private void RotateTowardsPlayer(Node3D rotationNode, float angle) => rotationNode.Rotation = new Vector3(rotationNode.Rotation.X, angle, rotationNode.Rotation.Z);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://d3cvsxlaohuqy
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class BossTypeAEnemyModelView : EnemyModelView3D
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
[Node] public IHitbox Hitbox { get; set; } = default!;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://bvcfww5827g74
|
||||
@@ -1,6 +1,7 @@
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Serialization;
|
||||
using Godot;
|
||||
using Zennysoft.Ma.Adapter.Entity;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
@@ -22,21 +23,23 @@ public partial class ArmorStats : InventoryItemStats
|
||||
|
||||
[Export]
|
||||
[Save("armor_telluric_resistance")]
|
||||
public double TelluricResistance { get; set; } = 0;
|
||||
private double _telluricResistance { get; set; } = 0;
|
||||
|
||||
[Export]
|
||||
[Save("armor_aeolic_resistance")]
|
||||
public double AeolicResistance { get; set; } = 0;
|
||||
private double _aeolicResistance { get; set; } = 0;
|
||||
|
||||
[Export]
|
||||
[Save("armor_hydric_resistance")]
|
||||
public double HydricResistance { get; set; } = 0;
|
||||
private double _hydricResistance { get; set; } = 0;
|
||||
|
||||
[Export]
|
||||
[Save("armor_igneous_resistance")]
|
||||
public double IgneousResistance { get; set; } = 0;
|
||||
private double _igneousResistance { get; set; } = 0;
|
||||
|
||||
[Export]
|
||||
[Save("armor_ferrum_resistance")]
|
||||
public double FerrumResistance { get; set; } = 0;
|
||||
private double _ferrumResistance { get; set; } = 0;
|
||||
|
||||
public ElementalResistanceSet ElementalResistanceSet => new ElementalResistanceSet(_aeolicResistance, _hydricResistance, _igneousResistance, _ferrumResistance, _telluricResistance);
|
||||
}
|
||||
|
||||
@@ -1946,3 +1946,4 @@ shape = SubResource("BoxShape3D_bxvob")
|
||||
[node name="DemonWall" parent="." instance=ExtResource("25_k2q0o")]
|
||||
unique_name_in_owner = true
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 21.2936, 55.334)
|
||||
_maximumWallMoveAmount = 24.0
|
||||
|
||||
@@ -7,7 +7,6 @@ using Godot;
|
||||
using Godot.Collections;
|
||||
using SimpleInjector;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Zennysoft.Ma.Adapter;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
@@ -96,6 +95,8 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
|
||||
|
||||
private Dictionary<int, int> _expToNextLevel;
|
||||
|
||||
private IDamageCalculator _damageCalculator;
|
||||
|
||||
#region Initialization
|
||||
public void Initialize()
|
||||
{
|
||||
@@ -110,6 +111,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
|
||||
{ 7, 417 },
|
||||
{ 8, 609 }
|
||||
};
|
||||
_damageCalculator = new DamageCalculator();
|
||||
}
|
||||
|
||||
public void Setup()
|
||||
@@ -147,10 +149,14 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
|
||||
PlayerLogic.Set(Stats);
|
||||
PlayerLogic.Set(_gameRepo);
|
||||
|
||||
var defaultWeapon = new Weapon();
|
||||
defaultWeapon.Stats = _defaultWeapon;
|
||||
var defaultArmor = new Armor();
|
||||
defaultArmor.Stats = _defaultArmor;
|
||||
var defaultWeapon = new Weapon
|
||||
{
|
||||
Stats = _defaultWeapon
|
||||
};
|
||||
var defaultArmor = new Armor
|
||||
{
|
||||
Stats = _defaultArmor
|
||||
};
|
||||
Inventory.TryAdd(defaultWeapon);
|
||||
Inventory.TryAdd(defaultArmor);
|
||||
|
||||
@@ -330,9 +336,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
|
||||
{
|
||||
if (Stats.CurrentHP.Value > 0)
|
||||
{
|
||||
damage = CalculateDefenseResistance(damage);
|
||||
if (isCriticalHit)
|
||||
damage *= 2;
|
||||
_damageCalculator.CalculateDamage(damage, elementType, Stats.CurrentDefense.Value + Stats.BonusDefense.Value, ((Armor)_equippedArmor.Value).Stats.ElementalResistanceSet);
|
||||
Stats.SetCurrentHP(Stats.CurrentHP.Value - (int)damage);
|
||||
}
|
||||
}
|
||||
@@ -537,11 +541,6 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
|
||||
LevelUp();
|
||||
}
|
||||
|
||||
private double CalculateDefenseResistance(double incomingDamage)
|
||||
{
|
||||
return Mathf.Max(incomingDamage - Stats.CurrentDefense.Value - Stats.BonusDefense.Value, 0.0);
|
||||
}
|
||||
|
||||
private void Hitbox_AreaEntered(Area3D area)
|
||||
{
|
||||
var target = area.GetOwner();
|
||||
|
||||
Reference in New Issue
Block a user