Implement plasma sword instakill

This commit is contained in:
2026-02-09 23:01:52 -08:00
parent bfaa324e6a
commit aba325ff2b
12 changed files with 273 additions and 219 deletions

View File

@@ -108,6 +108,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
private Vector3 _knockbackDirection = Vector3.Zero;
private ItemReroller _itemReroller;
private PlayerEffectService _playerEffectService;
public void Initialize()
{
@@ -128,6 +129,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
EquipmentComponent = new EquipmentComponent();
_itemReroller = new ItemReroller(ItemDatabase.Instance);
_playerEffectService = new PlayerEffectService(this);
Settings = new PlayerLogic.Settings() { RotationSpeed = RotationSpeed, MoveSpeed = MoveSpeed, Acceleration = Acceleration };
@@ -212,7 +214,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
{
_camera3D.AddShake(1.0f);
TakeDamageAnimationPlayer.Play("take_damage");
var damageReceived = DamageCalculator.CalculateDamage(damage, DefenseComponent.CurrentDefense.Value + EquipmentComponent.BonusDefense, EquipmentComponent.ElementalResistance);
var damageReceived = DamageCalculator.CalculateDamage(damage, TotalDefense, EquipmentComponent.ElementalResistance);
HealthComponent.Damage(damageReceived);
SfxDatabase.Instance.Play(SoundEffect.TakeDamage);
}
@@ -225,6 +227,12 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
public void PlayJumpScareAnimation() => PlayerFXAnimations.Play("jump_scare");
public int TotalAttack => AttackComponent.CurrentAttack.Value + EquipmentComponent.BonusAttack;
public int TotalDefense => DefenseComponent.CurrentDefense.Value + EquipmentComponent.BonusDefense;
public int TotalLuck => LuckComponent.Luck.Value + EquipmentComponent.BonusLuck;
public void LevelUp()
{
ExperiencePointsComponent.LevelUp();
@@ -414,11 +422,9 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
private void HitEnemy(IEnemy enemy)
{
var ignoreElementalResistance = (EquipmentComponent.EquippedWeapon.Value as Weapon).WeaponTag == WeaponTag.IgnoreAffinity;
var ignoreDefense = (EquipmentComponent.EquippedWeapon.Value as Weapon).WeaponTag == WeaponTag.IgnoreDefense;
var isCriticalHit = BattleExtensions.IsCriticalHit(LuckComponent.Luck.Value + EquipmentComponent.BonusLuck);
var totalDamage = AttackComponent.CurrentAttack.Value + EquipmentComponent.BonusAttack;
var element = (EquipmentComponent.EquippedWeapon.Value as Weapon).WeaponElement;
var weapon = EquipmentComponent.EquippedWeapon.Value as Weapon;
var isCriticalHit = BattleExtensions.IsCriticalHit(TotalLuck);
var totalDamage = TotalAttack;
if (isCriticalHit)
{
@@ -426,21 +432,16 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
SfxDatabase.Instance.Play(SoundEffect.Crit);
}
var baseAttack = new AttackData(totalDamage, element, ignoreDefense, ignoreElementalResistance);
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);
enemy.HealthComponent.Damage(damageDealt);
if (((Weapon)EquipmentComponent.EquippedWeapon.Value).WeaponTag == WeaponTag.Knockback && enemy is IKnockbackable knockbackable)
if (weapon.WeaponTag == WeaponTag.Knockback && enemy is IKnockbackable knockbackable)
knockbackable.Knockback(0.3f, -CurrentBasis.Z.Normalized());
if (((Weapon)EquipmentComponent.EquippedWeapon.Value).WeaponTag == WeaponTag.SelfDamage)
HealthComponent.Damage(5);
if (((Weapon)EquipmentComponent.EquippedWeapon.Value).WeaponTag == WeaponTag.Instakill)
{
var rng = new RandomNumberGenerator();
rng.Randomize();
if (rng.Randf() <= LuckComponent.Luck.Value)
enemy.Die();
}
if (weapon.WeaponTag == WeaponTag.SelfDamage)
_playerEffectService.TakeSelfDamage(weapon.Stats.SelfDamage);
if (weapon.WeaponTag == WeaponTag.Instakill)
_playerEffectService.Instakill(enemy);
}
private void CollisionDetector_AreaEntered(Area3D area)

View File

@@ -427,6 +427,34 @@ tracks/1/keys = {
"values": [0, 29]
}
[sub_resource type="Animation" id="Animation_wvcio"]
resource_name = "jump_scare"
length = 5.0005
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("SubViewportContainer/SubViewport/Prosc Message:texture")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 4.2),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [ExtResource("6_bj1ma"), ExtResource("6_bj1ma")]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("SubViewportContainer/SubViewport/Prosc Message:modulate")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.6, 1.6, 2.6, 3.6, 4.16667),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1),
"update": 0,
"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 1), Color(1, 1, 1, 0.48), Color(1, 1, 1, 1), Color(1, 1, 1, 0.48), Color(1, 1, 1, 0)]
}
[sub_resource type="Animation" id="Animation_v5qoq"]
resource_name = "normal_attack"
length = 0.666669
@@ -456,34 +484,6 @@ tracks/1/keys = {
"values": [0, 30]
}
[sub_resource type="Animation" id="Animation_wvcio"]
resource_name = "jump_scare"
length = 5.0005
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("SubViewportContainer/SubViewport/Prosc Message:texture")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 4.2),
"transitions": PackedFloat32Array(1, 1),
"update": 1,
"values": [ExtResource("6_bj1ma"), ExtResource("6_bj1ma")]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("SubViewportContainer/SubViewport/Prosc Message:modulate")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0, 0.6, 1.6, 2.6, 3.6, 4.16667),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1),
"update": 0,
"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 1), Color(1, 1, 1, 0.48), Color(1, 1, 1, 1), Color(1, 1, 1, 0.48), Color(1, 1, 1, 0)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_ebyyx"]
_data = {
&"Divinity_Recall": SubResource("Animation_j5wmh"),
@@ -12094,6 +12094,7 @@ animations = [{
collision_layer = 802
collision_mask = 775
script = ExtResource("1_xcol5")
HealthTimerIsActive = true
[node name="MainCollision" type="CollisionShape3D" parent="."]
unique_name_in_owner = true
@@ -12112,6 +12113,7 @@ unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 0.999848, -0.0174524, 0, 0.0174524, 0.999848, 0.003, 2.1, -0.01)
current = true
fov = 52.9
_maxZ = null
[node name="MeshInstance3D" type="MeshInstance3D" parent="Camera/Camera3D"]
extra_cull_margin = 16384.0

View File

@@ -0,0 +1,26 @@
using Godot;
using Zennysoft.Ma.Adapter;
using Zennysoft.Ma.Adapter.Entity;
internal class PlayerEffectService
{
private IPlayer _player;
public PlayerEffectService(IPlayer player)
{
_player = player;
}
public void TakeSelfDamage(int damage)
{
_player.TakeDamage(new AttackData(5, ElementType.None, true, true));
}
public void Instakill(IEnemy enemy)
{
var rng = new RandomNumberGenerator();
rng.Randomize();
var rand = rng.RandiRange(1, 100);
if (rand <= _player.TotalLuck)
enemy.Die();
}
}

View File

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