Rework enemy behavior (still in progress but shouldn't crash)
This commit is contained in:
@@ -3,50 +3,33 @@ using Zennysoft.Ma.Adapter.Entity;
|
||||
|
||||
namespace Zennysoft.Ma.Adapter
|
||||
{
|
||||
public class DamageCalculator : IDamageCalculator
|
||||
public static class DamageCalculator
|
||||
{
|
||||
public double CalculateDamage(double damage,
|
||||
ElementType elementType,
|
||||
double defense,
|
||||
ElementalResistanceSet elementalResistanceSet,
|
||||
bool isCriticalHit = false,
|
||||
bool ignoreDefense = false,
|
||||
bool ignoreElementalResistance = false)
|
||||
public static int CalculateDamage(Damage damage, double defense, ElementalResistanceSet elementalResistanceSet)
|
||||
{
|
||||
var calculatedDamage = damage;
|
||||
if (!ignoreElementalResistance)
|
||||
calculatedDamage = CalculateElementalResistance(calculatedDamage, elementType, elementalResistanceSet);
|
||||
if (!ignoreDefense)
|
||||
var calculatedDamage = damage.BaseDamage;
|
||||
if (!damage.IgnoreDefense)
|
||||
calculatedDamage = CalculateDefenseResistance(calculatedDamage, defense);
|
||||
if (isCriticalHit)
|
||||
if (!damage.IgnoreElementalResistance)
|
||||
calculatedDamage = CalculateElementalResistance(calculatedDamage, elementalResistanceSet.ElementalResistance[damage.ElementType]);
|
||||
if (damage.IsCriticalHit)
|
||||
calculatedDamage *= 2;
|
||||
|
||||
return calculatedDamage;
|
||||
return Mathf.Max(1, calculatedDamage);
|
||||
}
|
||||
|
||||
private static double CalculateDefenseResistance(double incomingDamage, double defense)
|
||||
private static int CalculateDefenseResistance(int incomingDamage, double defense)
|
||||
{
|
||||
return Mathf.Max(incomingDamage - defense, 0.0);
|
||||
var result = incomingDamage - (int)(incomingDamage * (defense / 100));
|
||||
return result;
|
||||
}
|
||||
|
||||
private static double CalculateElementalResistance(
|
||||
double incomingDamage,
|
||||
ElementType incomingElementType,
|
||||
ElementalResistanceSet elementalResistanceSet)
|
||||
private static int CalculateElementalResistance(
|
||||
int incomingDamage,
|
||||
double elementalResistance)
|
||||
{
|
||||
var resistance = elementalResistanceSet.ElementalResistance[incomingElementType];
|
||||
return Mathf.Max(incomingDamage - (incomingDamage * resistance), 0.0);
|
||||
var result = incomingDamage - (int)(incomingDamage * (elementalResistance / 100));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
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 @@
|
||||
uid://ci7va4hsq6hyt
|
||||
@@ -0,0 +1 @@
|
||||
uid://87d8kluait8y
|
||||
@@ -0,0 +1,9 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://c7e5g8l6wuph"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://87d8kluait8y" path="res://src/enemy/behaviors/PatrolBehavior.cs" id="1_lobva"]
|
||||
|
||||
[node name="NavigationAgent" type="NavigationAgent3D"]
|
||||
avoidance_enabled = true
|
||||
debug_enabled = true
|
||||
script = ExtResource("1_lobva")
|
||||
_patrolSpeed = 100.0
|
||||
3
Zennysoft.Game.Ma.Implementation/Entity/Damage.cs
Normal file
3
Zennysoft.Game.Ma.Implementation/Entity/Damage.cs
Normal file
@@ -0,0 +1,3 @@
|
||||
namespace Zennysoft.Ma.Adapter;
|
||||
|
||||
public record Damage(int BaseDamage, ElementType ElementType, bool IsCriticalHit, bool IgnoreDefense, bool IgnoreElementalResistance);
|
||||
29
Zennysoft.Game.Ma.Implementation/Entity/IEnemy.cs
Normal file
29
Zennysoft.Game.Ma.Implementation/Entity/IEnemy.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using Godot;
|
||||
using System.Collections.Immutable;
|
||||
using Zennysoft.Game.Ma;
|
||||
|
||||
namespace Zennysoft.Ma.Adapter.Entity
|
||||
{
|
||||
public interface IEnemy
|
||||
{
|
||||
public void Activate();
|
||||
|
||||
public void Idle();
|
||||
|
||||
public void Die();
|
||||
|
||||
public void PerformAction();
|
||||
|
||||
public void ReturnToDefaultState();
|
||||
|
||||
public void TakeDamage(int damage);
|
||||
|
||||
public void SetTarget(Vector3 targetPosition);
|
||||
|
||||
public void SetEnemyPosition(Vector3 position);
|
||||
|
||||
public void LookAtTarget(Vector3 target);
|
||||
|
||||
public IDungeonRoom GetCurrentRoom(ImmutableList<IDungeonRoom> dungeonRooms);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using Godot;
|
||||
|
||||
namespace Zennysoft.Ma.Adapter.Entity
|
||||
{
|
||||
public interface IKnockbackable
|
||||
{
|
||||
void Knockback(float impulse, Vector3 direction);
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ public abstract partial class InventoryItem : Node3D
|
||||
[Save("inventory_item_spawn_rate")]
|
||||
public abstract float SpawnRate { get; }
|
||||
[Save("inventory_item_throw_damage")]
|
||||
public abstract double ThrowDamage { get; }
|
||||
public abstract int ThrowDamage { get; }
|
||||
[Save("inventory_item_throw_speed")]
|
||||
public abstract float ThrowSpeed { get; }
|
||||
[Save("inventory_item_tag")]
|
||||
|
||||
15
Zennysoft.Game.Ma.Implementation/Map/IDungeonFloor.cs
Normal file
15
Zennysoft.Game.Ma.Implementation/Map/IDungeonFloor.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Chickensoft.GodotNodeInterfaces;
|
||||
using Godot;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
public interface IDungeonFloor : INode3D
|
||||
{
|
||||
void InitializeDungeon();
|
||||
|
||||
public Transform3D GetPlayerSpawnPoint();
|
||||
|
||||
public ImmutableList<IDungeonRoom> Rooms { get; }
|
||||
|
||||
public bool FloorIsLoaded { get; set; }
|
||||
}
|
||||
13
Zennysoft.Game.Ma.Implementation/Map/IDungeonRoom.cs
Normal file
13
Zennysoft.Game.Ma.Implementation/Map/IDungeonRoom.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Chickensoft.GodotNodeInterfaces;
|
||||
using System.Collections.Immutable;
|
||||
using Zennysoft.Ma.Adapter.Entity;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
public interface IDungeonRoom : INode3D
|
||||
{
|
||||
bool IsPlayerInRoom { get; }
|
||||
|
||||
bool PlayerDiscoveredRoom { get; }
|
||||
|
||||
ImmutableList<IEnemy> EnemiesInRoom { get; }
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
using SimpleInjector;
|
||||
using System.IO.Abstractions;
|
||||
using Zennysoft.Game.Abstractions;
|
||||
using Zennysoft.Game.Abstractions.Entity;
|
||||
using Zennysoft.Game.Implementation;
|
||||
using Zennysoft.Ma.Adapter.Entity;
|
||||
|
||||
namespace Zennysoft.Ma.Adapter;
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ public interface IPlayer : IKillable
|
||||
|
||||
public void Attack();
|
||||
|
||||
public void TakeDamage(double damage, ElementType elementType = ElementType.None, bool isCriticalHit = false);
|
||||
public void TakeDamage(Damage damage);
|
||||
|
||||
public void Knockback(float impulse);
|
||||
|
||||
|
||||
@@ -8,11 +8,8 @@
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Game\state\states\**" />
|
||||
<Compile Remove="Map\**" />
|
||||
<EmbeddedResource Remove="Game\state\states\**" />
|
||||
<EmbeddedResource Remove="Map\**" />
|
||||
<None Remove="Game\state\states\**" />
|
||||
<None Remove="Map\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -31,4 +28,8 @@
|
||||
<ProjectReference Include="..\Zennysoft.Game.Godot.Implementation\Zennysoft.Game.Implementation.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Actions\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user