Implement some Sigil behaviors

This commit is contained in:
2026-06-06 23:32:13 -07:00
parent 72f8b5c050
commit d2a81bb1cf
6 changed files with 182 additions and 168 deletions
@@ -1,26 +1,22 @@
using Godot;
using Zennysoft.Ma.Adapter;
using Zennysoft.Ma.Adapter.Entity;
namespace Zennysoft.Ma;
public interface ISigil
{
public double AttackModifier { get; }
[Export]
public double DamageModifier { get; }
[Export]
public double DefenseModifier { get; }
public double MoveSpeedModifier { get; }
[Export]
public int HealthModifier { get; }
[Export]
public int VTModifier { get; }
[Export]
public double LuckModifier { get; }
[Export]
public double ElementalModifier { get; }
public bool AutoRevive { get; }
[Export]
public ElementType ElementType { get; }
[Export]
public ElementalResistanceSet ElementalResistanceSet { get; }
}
@@ -150,9 +150,6 @@ public class ItemDatabase
database.Add(jewelItemScene);
}
var plastiqueScene = ResourceLoader.Load<PackedScene>("res://src/items/misc/SetItem.tscn").Instantiate<SetItem>();
database.Add(plastiqueScene);
Items = [.. database];
}
}
@@ -1,4 +1,4 @@
[gd_resource type="CameraAttributesPractical" format=3 uid="uid://dmxxjkk3faxy6"]
[gd_resource type="CameraAttributesPractical" load_steps=0 format=3 uid="uid://dmxxjkk3faxy6"]
[resource]
auto_exposure_enabled = true
+12 -6
View File
@@ -297,8 +297,11 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
_camera3D.AddShake(1.0f);
TakeDamageAnimationPlayer.Play("take_damage");
var defense = TotalDefense * SigilComponent.Sigil.DefenseModifier;
var damageReceived = DamageCalculator.CalculateDamage(damage, defense, EquipmentComponent.ElementalResistance);
var defense = TotalDefense;
var elementalResistance = EquipmentComponent.ElementalResistance + SigilComponent.Sigil.ElementalResistanceSet;
var damageReceived = DamageCalculator.CalculateDamage(damage, defense, elementalResistance);
damageReceived *= Mathf.RoundToInt(1 + SigilComponent.Sigil.DamageModifier);
GD.Print($"Damage dealt: {damageReceived}");
HealthComponent.Damage(damageReceived, damage.ElementType);
SfxDatabase.Instance.Play(SoundEffect.TakeDamage);
@@ -341,7 +344,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
{
PlayerFXAnimations.Play("death");
if (AutoRevive)
if (AutoRevive || SigilComponent.Sigil.AutoRevive)
return;
SetSigil(new NoneSigil());
@@ -790,7 +793,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
{
if (animName == "death")
{
if (AutoRevive)
if (AutoRevive || SigilComponent.Sigil.AutoRevive)
PlayerFXAnimations.PlayBackwards("revive");
else
PlayerDied?.Invoke();
@@ -856,6 +859,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
var rawInput = GlobalInputVector;
var strafeLeftInput = LeftStrafeInputVector;
var strafeRightInput = RightStrafeInputVector;
var moveSpeed = Settings.MoveSpeed * (1 + SigilComponent.Sigil.MoveSpeedModifier);
var transform = Transform;
transform.Basis = new Basis(Vector3.Up, Settings.RotationSpeed * -rawInput.X * delta) * transform.Basis;
@@ -872,7 +876,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
else if (WalkSFX.Playing)
WalkSFX.Stop();
var velocity = (Basis * moveDirection * Settings.MoveSpeed * Settings.Acceleration);
var velocity = (Basis * moveDirection * (float)moveSpeed * Settings.Acceleration);
if (_debugSprint)
velocity *= 2;
_knockbackStrength *= 0.9f;
@@ -916,7 +920,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
if (SigilComponent.Sigil.ElementType == weapon.WeaponElement)
totalDamage = Mathf.RoundToInt(totalDamage * 1.15f);
totalDamage = Mathf.RoundToInt(totalDamage * (1 + SigilComponent.Sigil.AttackModifier));
totalDamage = Mathf.RoundToInt(totalDamage * (1 + SigilComponent.Sigil.DamageModifier));
if (isCriticalHit)
{
@@ -924,6 +928,8 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
SfxDatabase.Instance.Play(SoundEffect.Crit);
}
GD.Print($"Damage dealt: {totalDamage}");
var baseAttack = new AttackData(totalDamage, weapon.WeaponElement, weapon.WeaponTag == WeaponTag.IgnoreDefense, weapon.WeaponTag == WeaponTag.IgnoreAffinity);
var damageDealt = DamageCalculator.CalculateDamage(baseAttack, enemy.DefenseComponent.CurrentDefense.Value, enemy.ElementalResistanceSet);
+96 -96
View File
@@ -946,6 +946,54 @@ tracks/1/keys = {
"values": [0, 159]
}
[sub_resource type="Animation" id="Animation_53c8b"]
resource_name = "Kyuuketsuki"
length = 1.78334
step = 0.0166667
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Control/Spell Signs:animation")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [&"Kyuuketsuki"]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Control/Spell Signs:frame")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 1.78333),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [0, 107]
}
tracks/2/type = "audio"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("../Weapon Slashes")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"clips": [{
"end_offset": 0.0,
"start_offset": 0.0,
"stream": ExtResource("8_jxml1")
}],
"times": PackedFloat32Array(0)
}
tracks/2/use_blend = true
[sub_resource type="Animation" id="Animation_rucep"]
resource_name = "Persiko"
step = 0.0166667
[sub_resource type="Animation" id="Animation_k8fmf"]
length = 0.001
tracks/0/type = "value"
@@ -1002,54 +1050,6 @@ tracks/1/keys = {
"values": [0, 107]
}
[sub_resource type="Animation" id="Animation_rucep"]
resource_name = "Persiko"
step = 0.0166667
[sub_resource type="Animation" id="Animation_53c8b"]
resource_name = "Kyuuketsuki"
length = 1.78334
step = 0.0166667
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Control/Spell Signs:animation")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [&"Kyuuketsuki"]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Control/Spell Signs:frame")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 1.78333),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [0, 107]
}
tracks/2/type = "audio"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("../Weapon Slashes")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"clips": [{
"end_offset": 0.0,
"start_offset": 0.0,
"stream": ExtResource("8_jxml1")
}],
"times": PackedFloat32Array(0)
}
tracks/2/use_blend = true
[sub_resource type="AnimationLibrary" id="AnimationLibrary_1mpss"]
_data = {
&"AnBradan": SubResource("Animation_dbr2j"),
@@ -1158,6 +1158,54 @@ tracks/3/keys = {
}
tracks/3/use_blend = true
[sub_resource type="Animation" id="Animation_a0pdj"]
resource_name = "Kyuuketsuki"
length = 2.65
step = 0.0166667
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Control/Spell Signs:animation")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [&"Kyuuketsuki"]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Control/Spell Signs:frame")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 2.65),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [0, 159]
}
tracks/2/type = "audio"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("../Weapon Slashes")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"clips": [{
"end_offset": 0.0,
"start_offset": 0.0,
"stream": ExtResource("8_jxml1")
}],
"times": PackedFloat32Array(0)
}
tracks/2/use_blend = true
[sub_resource type="Animation" id="Animation_dckm0"]
resource_name = "Persiko"
step = 0.0166667
[sub_resource type="Animation" id="Animation_jtmj1"]
length = 0.001
tracks/0/type = "value"
@@ -1445,54 +1493,6 @@ tracks/4/keys = {
"values": [Vector3(1, 1, 1), Vector3(1, 1, 0)]
}
[sub_resource type="Animation" id="Animation_dckm0"]
resource_name = "Persiko"
step = 0.0166667
[sub_resource type="Animation" id="Animation_a0pdj"]
resource_name = "Kyuuketsuki"
length = 2.65
step = 0.0166667
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Control/Spell Signs:animation")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [&"Kyuuketsuki"]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Control/Spell Signs:frame")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 2.65),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [0, 159]
}
tracks/2/type = "audio"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("../Weapon Slashes")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"clips": [{
"end_offset": 0.0,
"start_offset": 0.0,
"stream": ExtResource("8_jxml1")
}],
"times": PackedFloat32Array(0)
}
tracks/2/use_blend = true
[sub_resource type="AnimationLibrary" id="AnimationLibrary_ebyyx"]
_data = {
&"AnBradan": SubResource("Animation_en41m"),
+65 -50
View File
@@ -1,6 +1,6 @@
using Godot;
using Zennysoft.Ma;
using Zennysoft.Ma;
using Zennysoft.Ma.Adapter;
using Zennysoft.Ma.Adapter.Entity;
public class SigilComponent : ISigilComponent
{
@@ -14,88 +14,103 @@ public class SigilComponent : ISigilComponent
public partial class NoneSigil : ISigil
{
public double AttackModifier { get; set; }
public double DefenseModifier { get; set; }
public int HealthModifier { get; set; }
public int VTModifier { get; set; }
public double LuckModifier { get; set; }
public double ElementalModifier { get; set; }
public double DamageModifier { get; } = 0;
public double MoveSpeedModifier { get; } = 0;
public bool AutoRevive { get; } = false;
public ElementType ElementType { get; } = ElementType.None;
public ElementalResistanceSet ElementalResistanceSet => ElementalResistanceSet.None;
}
public partial class AeolicSigil : ISigil
{
public double AttackModifier { get; set; }
public double DefenseModifier { get; set; }
public int HealthModifier { get; set; }
public int VTModifier { get; set; }
public double LuckModifier { get; set; }
public double ElementalModifier { get; set; }
public double DamageModifier { get; } = 0;
public double MoveSpeedModifier { get; } = 0.25;
public bool AutoRevive { get; } = false;
public ElementType ElementType { get; } = ElementType.Aeolic;
public ElementalResistanceSet ElementalResistanceSet => new ElementalResistanceSet(0.25, 0, -0.25, 0, 0, 0, 0);
}
public partial class IgneousSigil : ISigil
{
public double AttackModifier { get; set; }
public double DefenseModifier { get; set; }
public int HealthModifier { get; set; }
public int VTModifier { get; set; }
public double LuckModifier { get; set; }
public double ElementalModifier { get; set; }
public double DamageModifier { get; } = 0.5;
public double MoveSpeedModifier { get; } = 0;
public bool AutoRevive { get; } = false;
public ElementType ElementType { get; } = ElementType.Igneous;
public ElementalResistanceSet ElementalResistanceSet => new ElementalResistanceSet(0, -0.25, 0.25, 0, 0, 0, 0);
}
public partial class TelluricSigil : ISigil
{
public double AttackModifier { get; set; }
public double DefenseModifier { get; set; }
public int HealthModifier { get; set; }
public int VTModifier { get; set; }
public double LuckModifier { get; set; }
public double ElementalModifier { get; set; }
public double DamageModifier { get; } = 0;
public double MoveSpeedModifier { get; } = 0;
public bool AutoRevive { get; } = false;
public ElementType ElementType { get; } = ElementType.Telluric;
public ElementalResistanceSet ElementalResistanceSet => new ElementalResistanceSet(-0.25, 0, 0, 0, 0.25, 0, 0);
}
public partial class HydricSigil : ISigil
{
public double AttackModifier { get; set; }
public double DefenseModifier { get; set; }
public int HealthModifier { get; set; }
public int VTModifier { get; set; }
public double LuckModifier { get; set; }
public double ElementalModifier { get; set; }
public double DamageModifier { get; } = 0;
public double MoveSpeedModifier { get; } = 0;
public bool AutoRevive { get; } = false;
public ElementType ElementType { get; } = ElementType.Hydric;
public ElementalResistanceSet ElementalResistanceSet => new ElementalResistanceSet(0, 0.25, 0, 0, -0.25, 0, 0);
}
public partial class FerrumSigil : ISigil
{
public double AttackModifier { get; set; }
public double DefenseModifier { get; set; }
public int HealthModifier { get; set; }
public int VTModifier { get; set; }
public double LuckModifier { get; set; }
public double ElementalModifier { get; set; }
public double DamageModifier { get; }
public double MoveSpeedModifier { get; } = 0;
public bool AutoRevive { get; } = false;
public ElementType ElementType { get; } = ElementType.Ferrum;
public ElementalResistanceSet ElementalResistanceSet => new ElementalResistanceSet(-0.25, -0.25, -0.25, 0.25, -0.25, -0.25, -0.25);
}
public partial class SanktaSigil : ISigil
{
public double AttackModifier { get; set; }
public double DefenseModifier { get; set; }
public int HealthModifier { get; set; }
public int VTModifier { get; set; }
public double LuckModifier { get; set; }
public double ElementalModifier { get; set; }
public double DamageModifier { get; }
public double MoveSpeedModifier { get; } = 0;
public bool AutoRevive { get; } = true;
public ElementType ElementType { get; } = ElementType.Sankta;
public ElementalResistanceSet ElementalResistanceSet => new ElementalResistanceSet(0, 0, 0, 0, 0, 0.25, -0.25);
}
public partial class ShuraSigil : ISigil
{
public double AttackModifier { get; set; }
public double DefenseModifier { get; set; }
public int HealthModifier { get; set; }
public int VTModifier { get; set; }
public double LuckModifier { get; set; }
public double ElementalModifier { get; set; }
public double DamageModifier { get; }
public double MoveSpeedModifier { get; } = 0;
public bool AutoRevive { get; } = false;
public ElementType ElementType { get; } = ElementType.Shura;
public ElementalResistanceSet ElementalResistanceSet => new ElementalResistanceSet(0, 0, 0, 0, 0, -0.25, 0.25);
}