From d2a81bb1cffa74b88b6f4f57d67c9870f0ac68e9 Mon Sep 17 00:00:00 2001 From: Zenny Date: Sat, 6 Jun 2026 23:32:13 -0700 Subject: [PATCH] Implement some Sigil behaviors --- .../Components/ISigil.cs | 20 +- Zennysoft.Game.Ma/src/items/ItemDatabase.cs | 3 - .../OutsideEnvironmentCameraAtt.tres | 2 +- Zennysoft.Game.Ma/src/player/Player.cs | 18 +- Zennysoft.Game.Ma/src/player/Player.tscn | 192 +++++++++--------- Zennysoft.Game.Ma/src/sigil/SigilComponent.cs | 115 ++++++----- 6 files changed, 182 insertions(+), 168 deletions(-) diff --git a/Zennysoft.Game.Ma.Implementation/Components/ISigil.cs b/Zennysoft.Game.Ma.Implementation/Components/ISigil.cs index 187e71fe..7913418a 100644 --- a/Zennysoft.Game.Ma.Implementation/Components/ISigil.cs +++ b/Zennysoft.Game.Ma.Implementation/Components/ISigil.cs @@ -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; } } diff --git a/Zennysoft.Game.Ma/src/items/ItemDatabase.cs b/Zennysoft.Game.Ma/src/items/ItemDatabase.cs index 11a748b4..c33df305 100644 --- a/Zennysoft.Game.Ma/src/items/ItemDatabase.cs +++ b/Zennysoft.Game.Ma/src/items/ItemDatabase.cs @@ -150,9 +150,6 @@ public class ItemDatabase database.Add(jewelItemScene); } - var plastiqueScene = ResourceLoader.Load("res://src/items/misc/SetItem.tscn").Instantiate(); - database.Add(plastiqueScene); - Items = [.. database]; } } diff --git a/Zennysoft.Game.Ma/src/map/dungeon/rooms/Special Rooms/OutsideEnvironmentCameraAtt.tres b/Zennysoft.Game.Ma/src/map/dungeon/rooms/Special Rooms/OutsideEnvironmentCameraAtt.tres index 8e0dbc47..96d36ac7 100644 --- a/Zennysoft.Game.Ma/src/map/dungeon/rooms/Special Rooms/OutsideEnvironmentCameraAtt.tres +++ b/Zennysoft.Game.Ma/src/map/dungeon/rooms/Special Rooms/OutsideEnvironmentCameraAtt.tres @@ -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 diff --git a/Zennysoft.Game.Ma/src/player/Player.cs b/Zennysoft.Game.Ma/src/player/Player.cs index 5db7d8cf..8bd59dd7 100644 --- a/Zennysoft.Game.Ma/src/player/Player.cs +++ b/Zennysoft.Game.Ma/src/player/Player.cs @@ -297,8 +297,11 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide _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 { 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 { 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 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 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 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 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); diff --git a/Zennysoft.Game.Ma/src/player/Player.tscn b/Zennysoft.Game.Ma/src/player/Player.tscn index ece6d9b7..9cc142f6 100644 --- a/Zennysoft.Game.Ma/src/player/Player.tscn +++ b/Zennysoft.Game.Ma/src/player/Player.tscn @@ -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"), diff --git a/Zennysoft.Game.Ma/src/sigil/SigilComponent.cs b/Zennysoft.Game.Ma/src/sigil/SigilComponent.cs index ca9e437b..0f92055d 100644 --- a/Zennysoft.Game.Ma/src/sigil/SigilComponent.cs +++ b/Zennysoft.Game.Ma/src/sigil/SigilComponent.cs @@ -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); }