Rework enemy behavior (still in progress but shouldn't crash)

This commit is contained in:
2025-10-20 19:24:50 -07:00
parent 20b659681a
commit 44fd8c82b0
135 changed files with 2165 additions and 2415 deletions

View File

@@ -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);
}
}

View File

@@ -0,0 +1 @@
uid://ci7va4hsq6hyt

View File

@@ -0,0 +1 @@
uid://87d8kluait8y

View File

@@ -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

View File

@@ -0,0 +1,3 @@
namespace Zennysoft.Ma.Adapter;
public record Damage(int BaseDamage, ElementType ElementType, bool IsCriticalHit, bool IgnoreDefense, bool IgnoreElementalResistance);

View 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);
}
}

View File

@@ -0,0 +1,9 @@
using Godot;
namespace Zennysoft.Ma.Adapter.Entity
{
public interface IKnockbackable
{
void Knockback(float impulse, Vector3 direction);
}
}

View File

@@ -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")]

View 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; }
}

View 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; }
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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>