fixed a few issues
This commit is contained in:
35
forge/abilities/ForgeManualCancelHitBehavior.cs
Normal file
35
forge/abilities/ForgeManualCancelHitBehavior.cs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
using Gamesmiths.Forge.Abilities;
|
||||||
|
using Gamesmiths.Forge.Effects;
|
||||||
|
using Gamesmiths.Forge.Godot.Resources;
|
||||||
|
using Gamesmiths.Forge.Godot.Resources.Abilities;
|
||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Movementtests.forge.abilities;
|
||||||
|
|
||||||
|
public class ManualCancelHitBehavior(ForgeEffectData? damage) : IAbilityBehavior
|
||||||
|
{
|
||||||
|
public void OnStarted(AbilityBehaviorContext context)
|
||||||
|
{
|
||||||
|
if (context.Target == null || damage == null) return;
|
||||||
|
|
||||||
|
var sourceLocation = (context.Source as Node3D)?.GlobalPosition ?? Vector3.Zero;
|
||||||
|
var targetLocation = (context.Target as Node3D)?.GlobalPosition ?? Vector3.Zero;
|
||||||
|
|
||||||
|
var magnitude = context.Magnitude == 0 ? 1 : context.Magnitude;
|
||||||
|
var effect = new Effect(damage.GetEffectData(), new EffectOwnership(context.Owner, context.Owner));
|
||||||
|
context.Target.EffectsManager.ApplyEffect(effect, new SimpleHitEffectData(sourceLocation, targetLocation, magnitude));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnEnded(AbilityBehaviorContext context)
|
||||||
|
{
|
||||||
|
context.AbilityHandle.CommitAbility();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Tool]
|
||||||
|
[GlobalClass]
|
||||||
|
public partial class ForgeManualCancelHitBehavior : ForgeAbilityBehavior
|
||||||
|
{
|
||||||
|
[Export] public ForgeEffectData? DamageEffect { get; set; }
|
||||||
|
public override IAbilityBehavior GetBehavior() => new ManualCancelHitBehavior(DamageEffect);
|
||||||
|
}
|
||||||
1
forge/abilities/ForgeManualCancelHitBehavior.cs.uid
Normal file
1
forge/abilities/ForgeManualCancelHitBehavior.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://d1bb1fvh1mnpd
|
||||||
@@ -21,12 +21,12 @@ public class SimpleHitBehavior(ForgeEffectData? damage) : IAbilityBehavior
|
|||||||
var effect = new Effect(damage.GetEffectData(), new EffectOwnership(context.Owner, context.Owner));
|
var effect = new Effect(damage.GetEffectData(), new EffectOwnership(context.Owner, context.Owner));
|
||||||
context.Target.EffectsManager.ApplyEffect(effect, new SimpleHitEffectData(sourceLocation, targetLocation, magnitude));
|
context.Target.EffectsManager.ApplyEffect(effect, new SimpleHitEffectData(sourceLocation, targetLocation, magnitude));
|
||||||
|
|
||||||
// context.InstanceHandle.End();
|
context.AbilityHandle.CommitAbility();
|
||||||
|
context.InstanceHandle.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnEnded(AbilityBehaviorContext context)
|
public void OnEnded(AbilityBehaviorContext context)
|
||||||
{
|
{
|
||||||
context.AbilityHandle.CommitAbility();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ metadata/_custom_type_script = "uid://cfx62w40nd84v"
|
|||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_ndb8p"]
|
[sub_resource type="Resource" id="Resource_ndb8p"]
|
||||||
script = ExtResource("5_tw4gc")
|
script = ExtResource("5_tw4gc")
|
||||||
Modifier = 100.0
|
Modifier = 500.0
|
||||||
metadata/_custom_type_script = "uid://b44cse62qru7j"
|
metadata/_custom_type_script = "uid://b44cse62qru7j"
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_dy671"]
|
[sub_resource type="Resource" id="Resource_dy671"]
|
||||||
@@ -57,7 +57,6 @@ BaseValue = 1.0
|
|||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_qqpg8"]
|
[sub_resource type="Resource" id="Resource_qqpg8"]
|
||||||
script = ExtResource("11_bs6rs")
|
script = ExtResource("11_bs6rs")
|
||||||
BaseValue = 10.0
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_igmn0"]
|
[sub_resource type="Resource" id="Resource_igmn0"]
|
||||||
script = ExtResource("11_bs6rs")
|
script = ExtResource("11_bs6rs")
|
||||||
@@ -70,6 +69,7 @@ metadata/_custom_type_script = "uid://cn3b4ya15fg7e"
|
|||||||
[sub_resource type="Resource" id="Resource_xwtie"]
|
[sub_resource type="Resource" id="Resource_xwtie"]
|
||||||
script = ExtResource("12_a6jts")
|
script = ExtResource("12_a6jts")
|
||||||
Attribute = "MetaAttributeSet.IncomingDamage"
|
Attribute = "MetaAttributeSet.IncomingDamage"
|
||||||
|
Operation = 2
|
||||||
CalculationType = 1
|
CalculationType = 1
|
||||||
ScalableFloat = SubResource("Resource_acqnn")
|
ScalableFloat = SubResource("Resource_acqnn")
|
||||||
CapturedAttribute = "MetaAttributeSet.Level"
|
CapturedAttribute = "MetaAttributeSet.Level"
|
||||||
@@ -107,7 +107,6 @@ metadata/_custom_type_script = "uid://n6efm5o4uxvr"
|
|||||||
[resource]
|
[resource]
|
||||||
script = ExtResource("16_hhyju")
|
script = ExtResource("16_hhyju")
|
||||||
Name = "Explosion "
|
Name = "Explosion "
|
||||||
InstancingPolicy = 1
|
|
||||||
CooldownEffects = []
|
CooldownEffects = []
|
||||||
AbilityBehavior = SubResource("Resource_ba5lh")
|
AbilityBehavior = SubResource("Resource_ba5lh")
|
||||||
metadata/_custom_type_script = "uid://dhxfbxh54pyxp"
|
metadata/_custom_type_script = "uid://dhxfbxh54pyxp"
|
||||||
|
|||||||
@@ -2,20 +2,19 @@
|
|||||||
|
|
||||||
[ext_resource type="Resource" uid="uid://bn1getr10b4dx" path="res://forge/resources/effect_datas/simple_player_hit.tres" id="1_c4wry"]
|
[ext_resource type="Resource" uid="uid://bn1getr10b4dx" path="res://forge/resources/effect_datas/simple_player_hit.tres" id="1_c4wry"]
|
||||||
[ext_resource type="Script" uid="uid://1hgogislo1l6" path="res://addons/forge/resources/magnitudes/ForgeScalableInt.cs" id="1_l0l1a"]
|
[ext_resource type="Script" uid="uid://1hgogislo1l6" path="res://addons/forge/resources/magnitudes/ForgeScalableInt.cs" id="1_l0l1a"]
|
||||||
[ext_resource type="Script" uid="uid://n6efm5o4uxvr" path="res://forge/abilities/ForgeSimpleHitBehavior.cs" id="1_n2s8d"]
|
|
||||||
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_w1wo0"]
|
[ext_resource type="Script" uid="uid://cw525n4mjqgw0" path="res://addons/forge/resources/ForgeTagContainer.cs" id="1_w1wo0"]
|
||||||
[ext_resource type="Script" uid="uid://b83hf13nj37k3" path="res://addons/forge/resources/ForgeEffectData.cs" id="2_5vjbv"]
|
[ext_resource type="Script" uid="uid://b83hf13nj37k3" path="res://addons/forge/resources/ForgeEffectData.cs" id="2_5vjbv"]
|
||||||
|
[ext_resource type="Script" uid="uid://d1bb1fvh1mnpd" path="res://forge/abilities/ForgeManualCancelHitBehavior.cs" id="2_c4wry"]
|
||||||
[ext_resource type="Script" uid="uid://dngf30hxy5go4" path="res://addons/forge/resources/components/ModifierTags.cs" id="2_jwyed"]
|
[ext_resource type="Script" uid="uid://dngf30hxy5go4" path="res://addons/forge/resources/components/ModifierTags.cs" id="2_jwyed"]
|
||||||
[ext_resource type="Script" uid="uid://dhxfbxh54pyxp" path="res://addons/forge/resources/abilities/ForgeAbilityData.cs" id="3_w1wo0"]
|
[ext_resource type="Script" uid="uid://dhxfbxh54pyxp" path="res://addons/forge/resources/abilities/ForgeAbilityData.cs" id="3_w1wo0"]
|
||||||
[ext_resource type="Script" uid="uid://cn3b4ya15fg7e" path="res://addons/forge/resources/magnitudes/ForgeScalableFloat.cs" id="4_c4wry"]
|
[ext_resource type="Script" uid="uid://cn3b4ya15fg7e" path="res://addons/forge/resources/magnitudes/ForgeScalableFloat.cs" id="4_c4wry"]
|
||||||
[ext_resource type="Script" uid="uid://2gm1hdhi8u08" path="res://addons/forge/resources/magnitudes/ForgeModifierMagnitude.cs" id="5_0cyim"]
|
[ext_resource type="Script" uid="uid://2gm1hdhi8u08" path="res://addons/forge/resources/magnitudes/ForgeModifierMagnitude.cs" id="5_0cyim"]
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_r7waw"]
|
[sub_resource type="Resource" id="Resource_0cyim"]
|
||||||
script = ExtResource("1_n2s8d")
|
script = ExtResource("2_c4wry")
|
||||||
DamageEffect = ExtResource("1_c4wry")
|
DamageEffect = ExtResource("1_c4wry")
|
||||||
Name = "PlayerHitEffect"
|
Name = "Player hit"
|
||||||
Description = "Effect applied to target on player hit"
|
metadata/_custom_type_script = "uid://d1bb1fvh1mnpd"
|
||||||
metadata/_custom_type_script = "uid://n6efm5o4uxvr"
|
|
||||||
|
|
||||||
[sub_resource type="Resource" id="Resource_qk2av"]
|
[sub_resource type="Resource" id="Resource_qk2av"]
|
||||||
script = ExtResource("1_w1wo0")
|
script = ExtResource("1_w1wo0")
|
||||||
@@ -94,6 +93,6 @@ script = ExtResource("3_w1wo0")
|
|||||||
Name = "PlayerHitAbility"
|
Name = "PlayerHitAbility"
|
||||||
RetriggerInstancedAbility = true
|
RetriggerInstancedAbility = true
|
||||||
CooldownEffects = [SubResource("Resource_cmmfb")]
|
CooldownEffects = [SubResource("Resource_cmmfb")]
|
||||||
AbilityBehavior = SubResource("Resource_r7waw")
|
AbilityBehavior = SubResource("Resource_0cyim")
|
||||||
ActivationBlockedTags = SubResource("Resource_qk2av")
|
ActivationBlockedTags = SubResource("Resource_qk2av")
|
||||||
metadata/_custom_type_script = "uid://dhxfbxh54pyxp"
|
metadata/_custom_type_script = "uid://dhxfbxh54pyxp"
|
||||||
|
|||||||
12
interfaces/IDisableable.cs
Normal file
12
interfaces/IDisableable.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
namespace Movementtests.interfaces;
|
||||||
|
|
||||||
|
public interface IDisableable
|
||||||
|
{
|
||||||
|
bool IsDisabled { get; set; }
|
||||||
|
[Export] float DisableDuration { get; set; }
|
||||||
|
|
||||||
|
void Disable();
|
||||||
|
void Enable();
|
||||||
|
}
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
using Godot;
|
|
||||||
|
|
||||||
namespace Movementtests.interfaces;
|
|
||||||
|
|
||||||
public interface IStunnable
|
|
||||||
{
|
|
||||||
bool IsStunned { get; set; }
|
|
||||||
[Export] float StunDuration { get; set; }
|
|
||||||
|
|
||||||
void Stun();
|
|
||||||
void Unstun();
|
|
||||||
}
|
|
||||||
@@ -34,43 +34,38 @@ public partial class InventoryManager : Node, IDisposable
|
|||||||
private readonly AutoMap<WeaponSystem.WeaponEvent, AutoSet<ForgeAbilityBehavior>> _weaponEventsInventory = new();
|
private readonly AutoMap<WeaponSystem.WeaponEvent, AutoSet<ForgeAbilityBehavior>> _weaponEventsInventory = new();
|
||||||
public IAutoMap<WeaponSystem.WeaponEvent, AutoSet<ForgeAbilityBehavior>> WeaponEventsInventory => _weaponEventsInventory;
|
public IAutoMap<WeaponSystem.WeaponEvent, AutoSet<ForgeAbilityBehavior>> WeaponEventsInventory => _weaponEventsInventory;
|
||||||
|
|
||||||
public Dictionary<WeaponSystem.WeaponEvent, AutoSet<ForgeAbilityBehavior>> GetEventElements()
|
|
||||||
{
|
|
||||||
return new Dictionary<WeaponSystem.WeaponEvent, AutoSet<ForgeAbilityBehavior>>
|
|
||||||
{
|
|
||||||
{ WeaponSystem.WeaponEvent.StartedFlying, _startedFlyingAbilities },
|
|
||||||
{ WeaponSystem.WeaponEvent.StoppedFlying, _stoppedFlyingAbilities},
|
|
||||||
{ WeaponSystem.WeaponEvent.FlyingTick, _flyingTickAbilities },
|
|
||||||
|
|
||||||
{ WeaponSystem.WeaponEvent.StartedPlanted, _startedPlantedAbilities },
|
|
||||||
{ WeaponSystem.WeaponEvent.StoppedPlanted, _stoppedPlantedAbilities },
|
|
||||||
{ WeaponSystem.WeaponEvent.PlantedTick, _plantedTickAbilities },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnReady()
|
public void OnReady()
|
||||||
{
|
{
|
||||||
foreach (var (forEvent, behaviorSet) in GetEventElements())
|
_weaponEventsInventory[WeaponSystem.WeaponEvent.StartedFlying] = _startedFlyingAbilities;
|
||||||
{
|
_weaponEventsInventory[WeaponSystem.WeaponEvent.StoppedFlying] = _stoppedFlyingAbilities;
|
||||||
_weaponEventsInventory[forEvent] = behaviorSet;
|
_weaponEventsInventory[WeaponSystem.WeaponEvent.FlyingTick] = _flyingTickAbilities;
|
||||||
}
|
_weaponEventsInventory[WeaponSystem.WeaponEvent.StartedPlanted] = _startedPlantedAbilities;
|
||||||
|
_weaponEventsInventory[WeaponSystem.WeaponEvent.StoppedPlanted] = _stoppedPlantedAbilities;
|
||||||
|
_weaponEventsInventory[WeaponSystem.WeaponEvent.PlantedTick] = _plantedTickAbilities;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitializeFromResource(WeaponInventory inventory)
|
public void InitializeFromResource(WeaponInventory inventory)
|
||||||
{
|
{
|
||||||
var elements = GetEventElements();
|
var eventMap = inventory.GetEventAbilitiesMap();
|
||||||
foreach (var forEvent in elements.Keys)
|
_startedFlyingAbilities = new AutoSet<ForgeAbilityBehavior>(eventMap[WeaponSystem.WeaponEvent.StartedFlying]);
|
||||||
{
|
_stoppedFlyingAbilities = new AutoSet<ForgeAbilityBehavior>(eventMap[WeaponSystem.WeaponEvent.StoppedFlying]);
|
||||||
elements[forEvent] = new AutoSet<ForgeAbilityBehavior>(inventory.EventMap[forEvent]);
|
_flyingTickAbilities = new AutoSet<ForgeAbilityBehavior>(eventMap[WeaponSystem.WeaponEvent.FlyingTick]);
|
||||||
}
|
|
||||||
|
_startedPlantedAbilities = new AutoSet<ForgeAbilityBehavior>(eventMap[WeaponSystem.WeaponEvent.StartedPlanted]);
|
||||||
|
_stoppedPlantedAbilities = new AutoSet<ForgeAbilityBehavior>(eventMap[WeaponSystem.WeaponEvent.StoppedPlanted]);
|
||||||
|
_plantedTickAbilities = new AutoSet<ForgeAbilityBehavior>(eventMap[WeaponSystem.WeaponEvent.PlantedTick]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public new void Dispose()
|
public new void Dispose()
|
||||||
{
|
{
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
|
|
||||||
foreach (var element in GetEventElements().Values)
|
_startedFlyingAbilities.Dispose();
|
||||||
element.Dispose();
|
_stoppedFlyingAbilities.Dispose();
|
||||||
|
_flyingTickAbilities.Dispose();
|
||||||
|
_startedPlantedAbilities.Dispose();
|
||||||
|
_stoppedPlantedAbilities.Dispose();
|
||||||
|
_plantedTickAbilities.Dispose();
|
||||||
|
|
||||||
_weaponEventsInventory.Dispose();
|
_weaponEventsInventory.Dispose();
|
||||||
|
|
||||||
|
|||||||
@@ -31,11 +31,13 @@ public partial class WeaponInventory(
|
|||||||
[Export]
|
[Export]
|
||||||
public ForgeAbilityBehavior[] OnWeaponStoppedPlantedAbilities { get; set; } = onWeaponStoppedPlantedAbilities;
|
public ForgeAbilityBehavior[] OnWeaponStoppedPlantedAbilities { get; set; } = onWeaponStoppedPlantedAbilities;
|
||||||
|
|
||||||
public Dictionary<WeaponSystem.WeaponEvent, ForgeAbilityBehavior[]> EventMap { get; private set; } = [];
|
|
||||||
|
|
||||||
public WeaponInventory() : this([], [], [], [], [], [])
|
public WeaponInventory() : this([], [], [], [], [], [])
|
||||||
{
|
{
|
||||||
EventMap = new Dictionary<WeaponSystem.WeaponEvent, ForgeAbilityBehavior[]>
|
}
|
||||||
|
|
||||||
|
public Dictionary<WeaponSystem.WeaponEvent, ForgeAbilityBehavior[]> GetEventAbilitiesMap()
|
||||||
|
{
|
||||||
|
return new Dictionary<WeaponSystem.WeaponEvent, ForgeAbilityBehavior[]>
|
||||||
{
|
{
|
||||||
{ WeaponSystem.WeaponEvent.StartedFlying, OnWeaponStartedFlyingAbilities },
|
{ WeaponSystem.WeaponEvent.StartedFlying, OnWeaponStartedFlyingAbilities },
|
||||||
{ WeaponSystem.WeaponEvent.StoppedFlying, OnWeaponStoppedFlyingAbilities },
|
{ WeaponSystem.WeaponEvent.StoppedFlying, OnWeaponStoppedFlyingAbilities },
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ public partial class MainSceneTemplate : Node3D, IProvide<InventoryManager>, IPr
|
|||||||
InventoryManager.InitializeFromResource(InitialWeaponInventory);
|
InventoryManager.InitializeFromResource(InitialWeaponInventory);
|
||||||
AddChild(InventoryManager);
|
AddChild(InventoryManager);
|
||||||
this.Provide();
|
this.Provide();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetPlayerPosition()
|
public void ResetPlayerPosition()
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ script = ExtResource("3_nix1q")
|
|||||||
OnWeaponStartedFlyingAbilities = Array[Object]([ExtResource("2_ctafv")])
|
OnWeaponStartedFlyingAbilities = Array[Object]([ExtResource("2_ctafv")])
|
||||||
OnWeaponFlyingTickAbilities = Array[Object]([ExtResource("2_ctafv")])
|
OnWeaponFlyingTickAbilities = Array[Object]([ExtResource("2_ctafv")])
|
||||||
OnWeaponStoppedFlyingAbilities = Array[Object]([ExtResource("2_ctafv")])
|
OnWeaponStoppedFlyingAbilities = Array[Object]([ExtResource("2_ctafv")])
|
||||||
|
OnWeaponStartedPlantedAbilities = null
|
||||||
|
OnWeaponPlantedTickAbilities = null
|
||||||
|
OnWeaponStoppedPlantedAbilities = null
|
||||||
metadata/_custom_type_script = "uid://cgaahnfgxcrr6"
|
metadata/_custom_type_script = "uid://cgaahnfgxcrr6"
|
||||||
|
|
||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_lthgu"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_lthgu"]
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ public partial class Enemy : CharacterBody3D,
|
|||||||
ISpawnable,
|
ISpawnable,
|
||||||
IKnockbackable,
|
IKnockbackable,
|
||||||
ITargetable,
|
ITargetable,
|
||||||
IStunnable,
|
|
||||||
IForgeEntity
|
IForgeEntity
|
||||||
{
|
{
|
||||||
public override void _Notification(int what) => this.Notify(what);
|
public override void _Notification(int what) => this.Notify(what);
|
||||||
@@ -166,7 +165,7 @@ public partial class Enemy : CharacterBody3D,
|
|||||||
|
|
||||||
public void ProcessGameplay(double delta)
|
public void ProcessGameplay(double delta)
|
||||||
{
|
{
|
||||||
if (IsStunned || _hitAbilityHandle == null) return;
|
if (_hitAbilityHandle == null) return;
|
||||||
|
|
||||||
var bodies = DamageBox.GetOverlappingBodies();
|
var bodies = DamageBox.GetOverlappingBodies();
|
||||||
foreach (var body in bodies)
|
foreach (var body in bodies)
|
||||||
@@ -186,10 +185,10 @@ public partial class Enemy : CharacterBody3D,
|
|||||||
|
|
||||||
public void OnDamageReceived(EventData<DamageDone> data)
|
public void OnDamageReceived(EventData<DamageDone> data)
|
||||||
{
|
{
|
||||||
var source = data.Source as Node;
|
// var source = data.Source as Node;
|
||||||
var sourceName = source?.Name ?? "unknown damage dealer";
|
// var sourceName = source?.Name ?? "unknown damage dealer";
|
||||||
GD.Print($"Ouch! Fuck you {sourceName}!");
|
// GD.Print($"Ouch! Fuck you {sourceName}!");
|
||||||
if (data.Payload.OverkillDamage > 0) GD.Print($"Overkill! {data.Payload.OverkillDamage} damage");
|
// if (data.Payload.OverkillDamage > 0) GD.Print($"Overkill! {data.Payload.OverkillDamage} damage");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnHealthChanged(EntityAttribute healthAttribute, int i)
|
private void OnHealthChanged(EntityAttribute healthAttribute, int i)
|
||||||
@@ -213,13 +212,11 @@ public partial class Enemy : CharacterBody3D,
|
|||||||
// Remove weapon that might be planted there
|
// Remove weapon that might be planted there
|
||||||
foreach (var child in GetChildren())
|
foreach (var child in GetChildren())
|
||||||
{
|
{
|
||||||
if (child is WeaponSystem system)
|
if (child is not WeaponSystem system) continue;
|
||||||
{
|
CallDeferred(Node.MethodName.RemoveChild, system);
|
||||||
CallDeferred(Node.MethodName.RemoveChild, system);
|
GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, system);
|
||||||
GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, system);
|
system.CallDeferred(Node3D.MethodName.SetGlobalPosition, GlobalPosition + Vector3.Up*EnemyHeight);
|
||||||
system.CallDeferred(Node3D.MethodName.SetGlobalPosition, GlobalPosition + Vector3.Up*EnemyHeight);
|
system.CallDeferred(WeaponSystem.MethodName.RethrowWeapon);
|
||||||
system.CallDeferred(WeaponSystem.MethodName.RethrowWeapon);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var killable in DeathEffects.ToIKillables())
|
foreach (var killable in DeathEffects.ToIKillables())
|
||||||
@@ -243,19 +240,4 @@ public partial class Enemy : CharacterBody3D,
|
|||||||
{
|
{
|
||||||
return TargetComponent.GlobalPosition;
|
return TargetComponent.GlobalPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stun management
|
|
||||||
public bool IsStunned { get; set; }
|
|
||||||
|
|
||||||
[Export(PropertyHint.Range, "0.1, 2, 0.1, or_greater")]
|
|
||||||
public float StunDuration { get; set; } = 1f;
|
|
||||||
public void Stun()
|
|
||||||
{
|
|
||||||
IsStunned = true;
|
|
||||||
GetTree().CreateTimer(StunDuration).Timeout += Unstun;
|
|
||||||
}
|
|
||||||
public void Unstun()
|
|
||||||
{
|
|
||||||
IsStunned = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ collision_layer = 0
|
|||||||
collision_mask = 16
|
collision_mask = 16
|
||||||
monitorable = false
|
monitorable = false
|
||||||
script = ExtResource("1_82hkh")
|
script = ExtResource("1_82hkh")
|
||||||
|
Damage = 20.0
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=1259903749]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=1259903749]
|
||||||
shape = SubResource("SphereShape3D_82hkh")
|
shape = SubResource("SphereShape3D_82hkh")
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using System;
|
|||||||
using Movementtests.interfaces;
|
using Movementtests.interfaces;
|
||||||
|
|
||||||
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_target.png")]
|
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_target.png")]
|
||||||
public partial class FixedDashthroughTarget : AnimatableBody3D, ITargetable, IStunnable
|
public partial class FixedDashthroughTarget : AnimatableBody3D, ITargetable, IDisableable
|
||||||
{
|
{
|
||||||
public Vector3 GetTargetGlobalPosition()
|
public Vector3 GetTargetGlobalPosition()
|
||||||
{
|
{
|
||||||
@@ -16,15 +16,15 @@ public partial class FixedDashthroughTarget : AnimatableBody3D, ITargetable, ISt
|
|||||||
_defaultCollisionMask = CollisionMask;
|
_defaultCollisionMask = CollisionMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsStunned { get; set; }
|
public bool IsDisabled { get; set; }
|
||||||
public float StunDuration { get; set; } = 0.1f;
|
public float DisableDuration { get; set; } = 0.1f;
|
||||||
public void Stun()
|
public void Disable()
|
||||||
{
|
{
|
||||||
_defaultCollisionMask = 0;
|
_defaultCollisionMask = 0;
|
||||||
GetTree().CreateTimer(StunDuration).Timeout += Unstun;
|
GetTree().CreateTimer(DisableDuration).Timeout += Enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Unstun()
|
public void Enable()
|
||||||
{
|
{
|
||||||
_defaultCollisionMask = CollisionMask;
|
_defaultCollisionMask = CollisionMask;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,470 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Godot;
|
|
||||||
|
|
||||||
namespace Movementtests.player_controller.Scripts;
|
|
||||||
|
|
||||||
public partial class HealthSystem : Node3D
|
|
||||||
{
|
|
||||||
new enum Rotation
|
|
||||||
{
|
|
||||||
NoRotation = 0,
|
|
||||||
CameraRotationTriggered = 1,
|
|
||||||
RotatingOnZAxis = 2,
|
|
||||||
ReturningBack = 3,
|
|
||||||
}
|
|
||||||
|
|
||||||
[ExportGroup("Health Metrics")]
|
|
||||||
[ExportSubgroup("Amounts")]
|
|
||||||
[Export(PropertyHint.Range, "0,100,0.1,or_greater")]
|
|
||||||
public float MaxHealth { get; set; } = 100.0f;
|
|
||||||
[Export(PropertyHint.Range, "0,100,0.1,or_greater")]
|
|
||||||
public float CurrentHealth { get; set; } = 100.0f;
|
|
||||||
[Export(PropertyHint.Range, "0,100,0.1,or_greater")]
|
|
||||||
public float MinimalDamageUnit { get; set; } = 25.0f;
|
|
||||||
[Export(PropertyHint.Range, "-100,0,0.1,or_smaller")]
|
|
||||||
public float ThresholdVelYForDamage { get; set; } = -15.0f;
|
|
||||||
[ExportSubgroup("Regeneration")]
|
|
||||||
[Export(PropertyHint.Range, "0,10,0.01,suffix:s,or_greater")]
|
|
||||||
public float SecondsBeforeRegeneration { get; set; } = 5.5f;
|
|
||||||
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
|
|
||||||
public float RegenerationSpeed { get; set; } = 10.0f;
|
|
||||||
|
|
||||||
[ExportGroup("Damage Camera Effects")]
|
|
||||||
[ExportSubgroup("Camera Shake")]
|
|
||||||
[Export(PropertyHint.Range, "0,100,0.1,or_greater")]
|
|
||||||
public float RotationSpeed { get; set; } = 9.0f;
|
|
||||||
[Export(PropertyHint.Range, "0,180,0.1,degrees")]
|
|
||||||
public float RotationDegree { get; set; } = 14.0f;
|
|
||||||
[ExportSubgroup("Visual Distortion")]
|
|
||||||
// Screen darkness controls how dark the screen will be, where 0.0 - natural
|
|
||||||
// color of the screen(unaltered) and 1.0 - black screen
|
|
||||||
[Export(PropertyHint.Range, "0.0,1.0,0.01")]
|
|
||||||
public float ScreenDarknessMin { get; set; } = 0.0f;
|
|
||||||
[Export(PropertyHint.Range, "0.0,1.0,0.01")]
|
|
||||||
public float ScreenDarknessMax { get; set; } = 0.3f;
|
|
||||||
[Export(PropertyHint.Range, "0.0,1.0,0.01")]
|
|
||||||
public float DistortionSpeedMin { get; set; } = 0.0f;
|
|
||||||
[Export(PropertyHint.Range, "0.0,1.0,0.01")]
|
|
||||||
public float DistortionSpeedMax { get; set; } = 0.6f;
|
|
||||||
[Export(PropertyHint.Range, "0.0,1.0,0.01")]
|
|
||||||
public float DistortionSizeMin { get; set; } = 0.0f;
|
|
||||||
[Export(PropertyHint.Range, "0.0,1.0,0.01")]
|
|
||||||
public float DistortionSizeMax { get; set; } = 1.0f;
|
|
||||||
[ExportSubgroup("Vignetting")]
|
|
||||||
[Export(PropertyHint.Range, "0.0,1.0,0.01")]
|
|
||||||
public float ActiveZoneMultiplierMin { get; set; } = 0.45f;
|
|
||||||
[Export(PropertyHint.Range, "0.0,1.0,0.01")]
|
|
||||||
public float ActiveZoneMultiplierMax { get; set; } = 0.475f;
|
|
||||||
[Export(PropertyHint.Range, "0.0,1.0,0.01,or_greater")]
|
|
||||||
public float MultiplierDeltaForAnimation { get; set; } = 0.066f;
|
|
||||||
[Export(PropertyHint.Range, "0.0,1.0,0.01")]
|
|
||||||
public float Softness { get; set; } = 1.0f;
|
|
||||||
[Export(PropertyHint.Range, "0.0,10,0.01")]
|
|
||||||
public float SpeedMin { get; set; } = 2.95f;
|
|
||||||
[Export(PropertyHint.Range, "0.0,10,0.01")]
|
|
||||||
public float SpeedMax { get; set; } = 4.0f;
|
|
||||||
|
|
||||||
// Death / GameOver
|
|
||||||
[ExportGroup("Death")]
|
|
||||||
[ExportSubgroup("Before Fade Out")]
|
|
||||||
[Export(PropertyHint.Range, "0,1,0.01,or_less,or_greater")]
|
|
||||||
public float BlurLimitValueToStartFadeOut { get; set; } = 0.3f;
|
|
||||||
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
|
|
||||||
public float BlurValueToStartFadeOut { get; set; } = 3.376f;
|
|
||||||
[ExportSubgroup("Speeds")]
|
|
||||||
[Export(PropertyHint.Range, "0.1,20.0,0.1,or_greater")]
|
|
||||||
public float CameraDropSpeedOnDeath { get; set; } = 18.0f;
|
|
||||||
[Export(PropertyHint.Range, "0.01,5.0,0.01,or_greater")]
|
|
||||||
public float FadeOutSpeed { get; set; } = 0.11f;
|
|
||||||
|
|
||||||
[Export(PropertyHint.Range, "0.1,10,0.01,or_greater")]
|
|
||||||
public float BlurLimitSpeedOnDeath { get; set; } = 0.9f;
|
|
||||||
[Export(PropertyHint.Range, "0.1,10,0.01,or_greater")]
|
|
||||||
public float BlurSpeedOnDeath { get; set; } = 1.5f;
|
|
||||||
|
|
||||||
[ExportSubgroup("Target values")]
|
|
||||||
[Export(PropertyHint.Range, "0,5.0,0.01,suffix:m,or_greater")]
|
|
||||||
public float CameraHeightOnDeath { get; set; } = 0.68f;
|
|
||||||
[Export(PropertyHint.Range, "0,5.0,0.01,suffix:m,or_greater")]
|
|
||||||
public float FadeOutTargetValue { get; set; } = 4.0f;
|
|
||||||
|
|
||||||
// TODO: add setter: BlurLimitValueToStartFadeOut should always be less than BlurLimitTargetValue
|
|
||||||
// (control it in editor)
|
|
||||||
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
|
|
||||||
public float BlurLimitTargetValue { get; set; } = 0.5f;
|
|
||||||
|
|
||||||
// TODO: add setter: BlurValueToStartFadeOut should always be less than BlurTargetValue
|
|
||||||
// (control it in editor)
|
|
||||||
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
|
|
||||||
public float BlurTargetValue { get; set; } = 7.0f;
|
|
||||||
|
|
||||||
[ExportSubgroup("Other")]
|
|
||||||
[Export(PropertyHint.Range, "0.0,4.0,0.01,suffix:s,or_greater")]
|
|
||||||
public float ScreenDarknessToReloadScene { get; set; } = 1.74f;
|
|
||||||
|
|
||||||
|
|
||||||
// Required to hide Vignette effect
|
|
||||||
private float _currentHealthInPrevFrame;
|
|
||||||
|
|
||||||
private float _currentVelocityYInAir;
|
|
||||||
|
|
||||||
private CharacterBody3D _characterBody3D;
|
|
||||||
|
|
||||||
private Camera3D _camera;
|
|
||||||
private float _cameraInitialRotationZ;
|
|
||||||
private float _targetRotationZAxis;
|
|
||||||
private Rotation _cameraRotation = Rotation.NoRotation;
|
|
||||||
private float _progressOnCamRotation;
|
|
||||||
|
|
||||||
private Vector2 _uvOffset = Vector2.Zero;
|
|
||||||
private float _offsetResetThreshold = 5.0f;
|
|
||||||
|
|
||||||
private ShaderMaterial _distortionMaterial;
|
|
||||||
|
|
||||||
private float _timeAccumulator;
|
|
||||||
|
|
||||||
private float _currentSpeed;
|
|
||||||
|
|
||||||
private const float InitialMultiplierMidVal = 0.6f;
|
|
||||||
private const float MultiplierMidValToHideVignette = 0.8f;
|
|
||||||
private float _currentMultiplierMidValue;
|
|
||||||
|
|
||||||
private ShaderMaterial _vignetteMaterial;
|
|
||||||
|
|
||||||
private bool _deathAnimationPlayed;
|
|
||||||
private float _screenDarknessOnDeath;
|
|
||||||
private float _currentBlurLimit;
|
|
||||||
private float _currentBlur;
|
|
||||||
private float _currentScreenDarkness;
|
|
||||||
|
|
||||||
private bool _dead;
|
|
||||||
private Node3D _head;
|
|
||||||
private ShaderMaterial _blurMaterial;
|
|
||||||
|
|
||||||
public struct HealthSystemInitParams
|
|
||||||
{
|
|
||||||
public CharacterBody3D Parent;
|
|
||||||
public Camera3D Camera;
|
|
||||||
public Node3D Head;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Init(HealthSystemInitParams initParams)
|
|
||||||
{
|
|
||||||
_currentHealthInPrevFrame = CurrentHealth;
|
|
||||||
_currentMultiplierMidValue = InitialMultiplierMidVal;
|
|
||||||
|
|
||||||
_currentSpeed = SpeedMin;
|
|
||||||
|
|
||||||
_characterBody3D = initParams.Parent;
|
|
||||||
_camera = initParams.Camera;
|
|
||||||
|
|
||||||
_head = initParams.Head;
|
|
||||||
|
|
||||||
// Resetting shaders' parameters
|
|
||||||
|
|
||||||
_vignetteMaterial.SetShaderParameter(Constants.VIGNETTE_SHADER_MULTIPLIER, 1.0f);
|
|
||||||
_vignetteMaterial.SetShaderParameter(Constants.VIGNETTE_SHADER_SOFTNESS, 1.0f);
|
|
||||||
|
|
||||||
_distortionMaterial.SetShaderParameter(Constants.DISTORTION_SHADER_SCREEN_DARKNESS, 0.0f);
|
|
||||||
_distortionMaterial.SetShaderParameter(Constants.DISTORTION_SHADER_DARKNESS_PROGRESSION, 0.0f);
|
|
||||||
|
|
||||||
_distortionMaterial.SetShaderParameter(
|
|
||||||
Constants.DISTORTION_SHADER_UV_OFFSET, new Vector2(0.0f, 0.0f));
|
|
||||||
|
|
||||||
_distortionMaterial.SetShaderParameter(Constants.DISTORTION_SHADER_SIZE, 0.0);
|
|
||||||
|
|
||||||
_blurMaterial.SetShaderParameter(Constants.BLUR_SHADER_LIMIT, 0.0f);
|
|
||||||
_blurMaterial.SetShaderParameter(Constants.BLUR_SHADER_BLUR, 0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void _Process(double delta)
|
|
||||||
{
|
|
||||||
float deltaConverted = (float)delta;
|
|
||||||
|
|
||||||
HandleDeath(deltaConverted);
|
|
||||||
|
|
||||||
HandleVignetteShader(deltaConverted);
|
|
||||||
HandleDistortionShader(deltaConverted);
|
|
||||||
|
|
||||||
HandleCameraRotationOnHit(deltaConverted);
|
|
||||||
HandleDamageOnFall();
|
|
||||||
|
|
||||||
HandleHealthRegeneration(deltaConverted);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void TakeDamage(float amount)
|
|
||||||
{
|
|
||||||
if (_dead)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_cameraRotation == Rotation.NoRotation)
|
|
||||||
{
|
|
||||||
_cameraRotation = Rotation.CameraRotationTriggered;
|
|
||||||
}
|
|
||||||
|
|
||||||
CurrentHealth -= amount;
|
|
||||||
CurrentHealth = Mathf.Clamp(CurrentHealth, 0, MaxHealth);
|
|
||||||
|
|
||||||
if (CurrentHealth == 0)
|
|
||||||
{
|
|
||||||
_dead = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_lastHitTime = DateTime.UtcNow;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float GetCurrentHealth() { return CurrentHealth; }
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
public override void _UnhandledInput(InputEvent @event)
|
|
||||||
{
|
|
||||||
if (@event is InputEventKey eventKey)
|
|
||||||
|
|
||||||
if (eventKey.Pressed && eventKey.Keycode == Key.H)
|
|
||||||
TakeDamage(MinimalDamageUnit);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public bool IsDead() { return _dead; }
|
|
||||||
|
|
||||||
private void HandleDeath(float delta)
|
|
||||||
{
|
|
||||||
if (!_dead) { return; }
|
|
||||||
|
|
||||||
if (!_deathAnimationPlayed)
|
|
||||||
{
|
|
||||||
_deathAnimationPlayed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector3 newPosition = _head.Position;
|
|
||||||
newPosition.Y = Mathf.Lerp(newPosition.Y, CameraHeightOnDeath, CameraDropSpeedOnDeath * delta);
|
|
||||||
|
|
||||||
if (newPosition.Y < CameraHeightOnDeath) { newPosition.Y = CameraHeightOnDeath; }
|
|
||||||
|
|
||||||
_head.Position = newPosition;
|
|
||||||
|
|
||||||
_currentBlurLimit = Mathf.Lerp(
|
|
||||||
_currentBlurLimit, BlurLimitTargetValue, BlurLimitSpeedOnDeath * delta);
|
|
||||||
|
|
||||||
_blurMaterial.SetShaderParameter(Constants.BLUR_SHADER_LIMIT, _currentBlurLimit);
|
|
||||||
|
|
||||||
_currentBlur = Mathf.Lerp(_currentBlur, BlurTargetValue, BlurSpeedOnDeath * delta);
|
|
||||||
_blurMaterial.SetShaderParameter(Constants.BLUR_SHADER_BLUR, _currentBlur);
|
|
||||||
|
|
||||||
if (_currentBlurLimit >= BlurLimitValueToStartFadeOut && _currentBlur >= BlurValueToStartFadeOut)
|
|
||||||
{
|
|
||||||
float currentScreenDarknessVariant = (float)_distortionMaterial.GetShaderParameter(
|
|
||||||
Constants.DISTORTION_SHADER_SCREEN_DARKNESS);
|
|
||||||
|
|
||||||
_screenDarknessOnDeath = Mathf.Lerp(
|
|
||||||
currentScreenDarknessVariant, FadeOutTargetValue, FadeOutSpeed * delta);
|
|
||||||
|
|
||||||
_distortionMaterial.SetShaderParameter(
|
|
||||||
Constants.DISTORTION_SHADER_SCREEN_DARKNESS, _screenDarknessOnDeath);
|
|
||||||
|
|
||||||
if (_screenDarknessOnDeath >= ScreenDarknessToReloadScene)
|
|
||||||
{
|
|
||||||
GD.Print("reload");
|
|
||||||
// Reload the current scene
|
|
||||||
GetTree().ReloadCurrentScene();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleVignetteShader(float delta)
|
|
||||||
{
|
|
||||||
if (Mathf.IsEqualApprox(CurrentHealth, MaxHealth))
|
|
||||||
{
|
|
||||||
_currentHealthInPrevFrame = CurrentHealth;
|
|
||||||
_currentMultiplierMidValue = InitialMultiplierMidVal;
|
|
||||||
_timeAccumulator = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float healthNormalized = CurrentHealth / MaxHealth;
|
|
||||||
float healthReverted = 1.0f - healthNormalized;
|
|
||||||
|
|
||||||
float newAnimationSpeed = Mathf.Lerp(SpeedMin, SpeedMax, healthReverted);
|
|
||||||
_currentSpeed = Mathf.Lerp(_currentSpeed, newAnimationSpeed, delta);
|
|
||||||
|
|
||||||
float completeSinCycle = Mathf.Tau / _currentSpeed;
|
|
||||||
|
|
||||||
_timeAccumulator = Mathf.Wrap(_timeAccumulator + delta, 0.0f, completeSinCycle);
|
|
||||||
|
|
||||||
float rawAnimationWeight = Mathf.Sin(_timeAccumulator * _currentSpeed);
|
|
||||||
|
|
||||||
float animationWeight = Mathf.Abs(rawAnimationWeight);
|
|
||||||
|
|
||||||
float difference = _currentHealthInPrevFrame - CurrentHealth;
|
|
||||||
|
|
||||||
float newMultiplierMidValue;
|
|
||||||
|
|
||||||
if (difference < 0)
|
|
||||||
{
|
|
||||||
newMultiplierMidValue = Mathf.Lerp(
|
|
||||||
MultiplierMidValToHideVignette, ActiveZoneMultiplierMin, healthReverted);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
newMultiplierMidValue = Mathf.Lerp(
|
|
||||||
ActiveZoneMultiplierMax, ActiveZoneMultiplierMin, healthReverted);
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentMultiplierMidValue = Mathf.Lerp(
|
|
||||||
_currentMultiplierMidValue, newMultiplierMidValue, delta);
|
|
||||||
|
|
||||||
float multiplier = Mathf.Lerp(
|
|
||||||
_currentMultiplierMidValue - MultiplierDeltaForAnimation,
|
|
||||||
_currentMultiplierMidValue + MultiplierDeltaForAnimation,
|
|
||||||
animationWeight * animationWeight
|
|
||||||
);
|
|
||||||
|
|
||||||
_vignetteMaterial.SetShaderParameter(Constants.VIGNETTE_SHADER_MULTIPLIER, multiplier);
|
|
||||||
_vignetteMaterial.SetShaderParameter(Constants.VIGNETTE_SHADER_SOFTNESS, Softness);
|
|
||||||
|
|
||||||
_currentHealthInPrevFrame = CurrentHealth;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleDistortionShader(float delta)
|
|
||||||
{
|
|
||||||
if (Mathf.IsEqualApprox(CurrentHealth, MaxHealth))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float healthNormalized = CurrentHealth / MaxHealth;
|
|
||||||
float healthReverted = 1 - healthNormalized;
|
|
||||||
|
|
||||||
_distortionMaterial.SetShaderParameter(
|
|
||||||
Constants.DISTORTION_SHADER_DARKNESS_PROGRESSION, healthReverted);
|
|
||||||
|
|
||||||
if (!_dead)
|
|
||||||
{
|
|
||||||
float screenDarkness = Mathf.Remap(
|
|
||||||
healthReverted, 0, 1, ScreenDarknessMin, ScreenDarknessMax);
|
|
||||||
|
|
||||||
_distortionMaterial.SetShaderParameter(
|
|
||||||
Constants.DISTORTION_SHADER_SCREEN_DARKNESS, screenDarkness);
|
|
||||||
}
|
|
||||||
|
|
||||||
float distortionSpeed = Mathf.Remap(
|
|
||||||
healthReverted, 0.0f, 1.0f, DistortionSpeedMin, DistortionSpeedMax);
|
|
||||||
|
|
||||||
float offsetVal = delta * distortionSpeed;
|
|
||||||
|
|
||||||
_uvOffset += new Vector2(offsetVal, offsetVal);
|
|
||||||
|
|
||||||
_distortionMaterial.SetShaderParameter(
|
|
||||||
Constants.DISTORTION_SHADER_UV_OFFSET, _uvOffset);
|
|
||||||
|
|
||||||
if (_uvOffset.X > _offsetResetThreshold) { _uvOffset.X = 0.0f; _uvOffset.Y = 0.0f; }
|
|
||||||
|
|
||||||
float distortionSize = Mathf.Remap(
|
|
||||||
healthReverted, 0.0f, 1.0f, DistortionSizeMin, DistortionSizeMax);
|
|
||||||
|
|
||||||
_distortionMaterial.SetShaderParameter(
|
|
||||||
Constants.DISTORTION_SHADER_SIZE, distortionSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RotateCameraOnZAxis(float delta, float targetAngleInRadians, Rotation rotationStateToSetOnFinish)
|
|
||||||
{
|
|
||||||
_progressOnCamRotation += delta * RotationSpeed;
|
|
||||||
_progressOnCamRotation = Mathf.Clamp(_progressOnCamRotation, 0f, 1f);
|
|
||||||
|
|
||||||
float lerpedAngleZ = Mathf.LerpAngle(
|
|
||||||
_camera.Rotation.Z,targetAngleInRadians, _progressOnCamRotation);
|
|
||||||
|
|
||||||
_camera.Rotation = new Vector3(_camera.Rotation.X, _camera.Rotation.Y, lerpedAngleZ);
|
|
||||||
|
|
||||||
float difference = Mathf.Abs(targetAngleInRadians - _camera.Rotation.Z);
|
|
||||||
|
|
||||||
if (difference < Constants.ACCEPTABLE_TOLERANCE)
|
|
||||||
{
|
|
||||||
_cameraRotation = rotationStateToSetOnFinish;
|
|
||||||
_progressOnCamRotation = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleCameraRotationOnHit(float delta)
|
|
||||||
{
|
|
||||||
if (_cameraRotation == Rotation.NoRotation || _dead) return;
|
|
||||||
|
|
||||||
if (_cameraRotation == Rotation.CameraRotationTriggered)
|
|
||||||
{
|
|
||||||
if (GD.Randi() % 2 == 0)
|
|
||||||
{
|
|
||||||
_targetRotationZAxis = Mathf.DegToRad(RotationDegree * -1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_targetRotationZAxis = Mathf.DegToRad(RotationDegree);
|
|
||||||
}
|
|
||||||
|
|
||||||
_cameraRotation = Rotation.RotatingOnZAxis;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_cameraRotation == Rotation.RotatingOnZAxis)
|
|
||||||
{
|
|
||||||
RotateCameraOnZAxis(delta, _targetRotationZAxis, Rotation.ReturningBack);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_cameraRotation == Rotation.ReturningBack)
|
|
||||||
{
|
|
||||||
RotateCameraOnZAxis(delta, 0, Rotation.NoRotation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleDamageOnFall()
|
|
||||||
{
|
|
||||||
if (_dead) { return;}
|
|
||||||
|
|
||||||
if (!_characterBody3D.IsOnFloor())
|
|
||||||
{
|
|
||||||
_currentVelocityYInAir = _characterBody3D.Velocity.Y;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_currentVelocityYInAir < ThresholdVelYForDamage && ThresholdVelYForDamage > 0)
|
|
||||||
{
|
|
||||||
float hit = Mathf.Remap(_currentVelocityYInAir,
|
|
||||||
ThresholdVelYForDamage, ThresholdVelYForDamage - 9.0f,
|
|
||||||
MinimalDamageUnit, MaxHealth);
|
|
||||||
|
|
||||||
GD.Print("Hit damage: ", hit);
|
|
||||||
|
|
||||||
TakeDamage(hit);
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentVelocityYInAir = 0.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private DateTime? _lastHitTime;
|
|
||||||
|
|
||||||
private void HandleHealthRegeneration(float delta)
|
|
||||||
{
|
|
||||||
if (_lastHitTime == null || _dead) return;
|
|
||||||
|
|
||||||
DateTime lastHitTimeConverted = (DateTime)_lastHitTime;
|
|
||||||
|
|
||||||
double differenceInSeconds = (DateTime.UtcNow - lastHitTimeConverted).TotalSeconds;
|
|
||||||
float differenceInSecondsConverted = (float)differenceInSeconds;
|
|
||||||
|
|
||||||
if (differenceInSecondsConverted < SecondsBeforeRegeneration)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Mathf.IsEqualApprox(CurrentHealth, MaxHealth))
|
|
||||||
{
|
|
||||||
CurrentHealth = MaxHealth;
|
|
||||||
_lastHitTime = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CurrentHealth += delta * RegenerationSpeed;
|
|
||||||
CurrentHealth = Mathf.Clamp(CurrentHealth, 0, MaxHealth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://dv7v1ywmbvvcd
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Godot;
|
|
||||||
|
|
||||||
namespace Movementtests.player_controller.Scripts;
|
|
||||||
|
|
||||||
public partial class Mouse : Node3D
|
|
||||||
{
|
|
||||||
[Export(PropertyHint.Range, "0,0.1,0.001,or_greater")]
|
|
||||||
public float Sensitivity { get; set; } = 0.004f;
|
|
||||||
|
|
||||||
private Node3D _head;
|
|
||||||
private Camera3D _camera;
|
|
||||||
|
|
||||||
public delegate bool IsDead();
|
|
||||||
|
|
||||||
private IsDead _isPlayerDead;
|
|
||||||
|
|
||||||
public void Init(Node3D head, Camera3D cam, IsDead isDeadFunc)
|
|
||||||
{
|
|
||||||
Input.SetMouseMode(Input.MouseModeEnum.Captured);
|
|
||||||
|
|
||||||
_head = head;
|
|
||||||
_camera = cam;
|
|
||||||
_isPlayerDead = isDeadFunc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LookAround(Vector2 lookDir)
|
|
||||||
{
|
|
||||||
// Horizontal movement of head
|
|
||||||
float angleForHorizontalRotation = lookDir.X * Sensitivity;
|
|
||||||
_head.RotateY(angleForHorizontalRotation);
|
|
||||||
|
|
||||||
// Vertical movement of head
|
|
||||||
Vector3 currentCameraRotation = _camera.Rotation;
|
|
||||||
currentCameraRotation.X += Convert.ToSingle(lookDir.Y * Sensitivity);
|
|
||||||
currentCameraRotation.X = Mathf.Clamp(currentCameraRotation.X, Mathf.DegToRad(-90f), Mathf.DegToRad(90f));
|
|
||||||
|
|
||||||
_camera.Rotation = currentCameraRotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://c6bx47wr7fbdm
|
|
||||||
@@ -115,7 +115,8 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
|
|||||||
public required EventManager Events { get; set; }
|
public required EventManager Events { get; set; }
|
||||||
public required Variables SharedVariables { get; set; }
|
public required Variables SharedVariables { get; set; }
|
||||||
|
|
||||||
public Dictionary<WeaponSystem.WeaponEvent, EventElements> EventElementsMap { get; private set; } = [];
|
public Dictionary<WeaponSystem.WeaponEvent, AutoSet<ForgeAbilityBehavior>.Binding> EventBindingsMap { get; private set; } = [];
|
||||||
|
public Dictionary<WeaponSystem.WeaponEvent, IAutoSet<ForgeAbilityBehavior>> EventInventoryMap { get; private set; } = [];
|
||||||
|
|
||||||
public AutoSet<ForgeAbilityBehavior>.Binding StartedFlyingBinding { get; set; }
|
public AutoSet<ForgeAbilityBehavior>.Binding StartedFlyingBinding { get; set; }
|
||||||
public AutoSet<ForgeAbilityBehavior>.Binding FlyingTickBinding { get; set; }
|
public AutoSet<ForgeAbilityBehavior>.Binding FlyingTickBinding { get; set; }
|
||||||
@@ -743,22 +744,32 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Inventory changes signal binding
|
// Inventory changes signal binding
|
||||||
EventElementsMap = new Dictionary<WeaponSystem.WeaponEvent, EventElements>
|
EventBindingsMap = new Dictionary<WeaponSystem.WeaponEvent, AutoSet<ForgeAbilityBehavior>.Binding>
|
||||||
{
|
{
|
||||||
{ WeaponSystem.WeaponEvent.StartedFlying, new EventElements(StartedFlyingBinding, InventoryManager.StartedFlyingAbilities) },
|
{ WeaponSystem.WeaponEvent.StartedFlying, StartedFlyingBinding },
|
||||||
{ WeaponSystem.WeaponEvent.StoppedFlying, new EventElements(StoppedFlyingBinding, InventoryManager.StoppedFlyingAbilities)},
|
{ WeaponSystem.WeaponEvent.StoppedFlying, StoppedFlyingBinding },
|
||||||
{ WeaponSystem.WeaponEvent.FlyingTick, new EventElements(FlyingTickBinding, InventoryManager.FlyingTickAbilities) },
|
{ WeaponSystem.WeaponEvent.FlyingTick, FlyingTickBinding },
|
||||||
|
|
||||||
{ WeaponSystem.WeaponEvent.StartedPlanted, new EventElements(StartedPlantedBinding, InventoryManager.StartedPlantedAbilities) },
|
{ WeaponSystem.WeaponEvent.StartedPlanted, StartedPlantedBinding },
|
||||||
{ WeaponSystem.WeaponEvent.StoppedPlanted, new EventElements(StoppedPlantedBinding, InventoryManager.StoppedPlantedAbilities) },
|
{ WeaponSystem.WeaponEvent.StoppedPlanted, StoppedPlantedBinding },
|
||||||
{ WeaponSystem.WeaponEvent.PlantedTick, new EventElements(PlantedTickBinding, InventoryManager.PlantedTickAbilities) },
|
{ WeaponSystem.WeaponEvent.PlantedTick, PlantedTickBinding },
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var forEvent in EventElementsMap.Keys)
|
EventInventoryMap = new Dictionary<WeaponSystem.WeaponEvent, IAutoSet<ForgeAbilityBehavior>>
|
||||||
{
|
{
|
||||||
var element = EventElementsMap[forEvent];
|
{ WeaponSystem.WeaponEvent.StartedFlying, InventoryManager.StartedFlyingAbilities },
|
||||||
element.Binding = element.Inventory.Bind();
|
{ WeaponSystem.WeaponEvent.StoppedFlying, InventoryManager.StoppedFlyingAbilities },
|
||||||
element.Binding
|
{ WeaponSystem.WeaponEvent.FlyingTick, InventoryManager.FlyingTickAbilities },
|
||||||
|
|
||||||
|
{ WeaponSystem.WeaponEvent.StartedPlanted, InventoryManager.StartedPlantedAbilities },
|
||||||
|
{ WeaponSystem.WeaponEvent.StoppedPlanted, InventoryManager.StoppedPlantedAbilities },
|
||||||
|
{ WeaponSystem.WeaponEvent.PlantedTick, InventoryManager.PlantedTickAbilities },
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var forEvent in EventBindingsMap.Keys)
|
||||||
|
{
|
||||||
|
EventBindingsMap[forEvent] = EventInventoryMap[forEvent].Bind();
|
||||||
|
EventBindingsMap[forEvent]
|
||||||
.OnAdd(behavior => WeaponSystem.GrantNewAbilityForEvent(forEvent, behavior))
|
.OnAdd(behavior => WeaponSystem.GrantNewAbilityForEvent(forEvent, behavior))
|
||||||
.OnRemove(behavior => WeaponSystem.RemoveAbilityForEvent(forEvent, behavior))
|
.OnRemove(behavior => WeaponSystem.RemoveAbilityForEvent(forEvent, behavior))
|
||||||
.OnClear(() => WeaponSystem.RemoveAbilitiesForEvent(forEvent));
|
.OnClear(() => WeaponSystem.RemoveAbilitiesForEvent(forEvent));
|
||||||
@@ -769,8 +780,8 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
|
|||||||
{
|
{
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
|
|
||||||
foreach (var element in EventElementsMap.Values)
|
foreach (var binding in EventBindingsMap.Values)
|
||||||
element.Binding.Dispose();
|
binding.Dispose();
|
||||||
|
|
||||||
base.Dispose();
|
base.Dispose();
|
||||||
}
|
}
|
||||||
@@ -2328,8 +2339,8 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
|
|||||||
_hitEnemies.Add(entity);
|
_hitEnemies.Add(entity);
|
||||||
TriggerDamage();
|
TriggerDamage();
|
||||||
}
|
}
|
||||||
if (enemy is IStunnable stunnable)
|
if (enemy is IDisableable disableable)
|
||||||
stunnable.Stun();
|
disableable.Disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnWeaponDashFinished()
|
public void OnWeaponDashFinished()
|
||||||
@@ -2485,9 +2496,9 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
|
|||||||
{
|
{
|
||||||
TriggerSimpleDashThroughDamage(entity);
|
TriggerSimpleDashThroughDamage(entity);
|
||||||
}
|
}
|
||||||
if (_targetObject is IStunnable stunnable)
|
if (_targetObject is IDisableable disableable)
|
||||||
{
|
{
|
||||||
stunnable.Stun();
|
disableable.Disable();
|
||||||
}
|
}
|
||||||
IsInvincible = false;
|
IsInvincible = false;
|
||||||
_playerState.SendEvent("attack_finished");
|
_playerState.SendEvent("attack_finished");
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
using Godot;
|
|
||||||
|
|
||||||
namespace Movementtests.player_controller.Scripts;
|
|
||||||
|
|
||||||
public partial class Stamina : Node
|
|
||||||
{
|
|
||||||
[Export(PropertyHint.Range, "0,60,0.1,suffix:s,or_greater")]
|
|
||||||
public float MaxRunTime { get; set; } = 10.0f;
|
|
||||||
// Regenerate run time multiplier (when run 10s and RunTimeMultiplier = 2.0f to full regenerate you need 5s)
|
|
||||||
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
|
|
||||||
public float RunTimeMultiplier { get; set; } = 2.0f;
|
|
||||||
|
|
||||||
private float _currentRunTime;
|
|
||||||
|
|
||||||
private float _walkSpeed;
|
|
||||||
private float _sprintSpeed;
|
|
||||||
|
|
||||||
public void SetSpeeds(float walkSpeed, float sprintSpeed)
|
|
||||||
{
|
|
||||||
_walkSpeed = walkSpeed;
|
|
||||||
_sprintSpeed = sprintSpeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float AccountStamina(double delta, float wantedSpeed)
|
|
||||||
{
|
|
||||||
if (Mathf.Abs(wantedSpeed - _sprintSpeed) > 0.1f)
|
|
||||||
{
|
|
||||||
float runtimeLeft = _currentRunTime - (RunTimeMultiplier * (float)delta);
|
|
||||||
|
|
||||||
if (_currentRunTime != 0.0f)
|
|
||||||
_currentRunTime = Mathf.Clamp(runtimeLeft, 0, MaxRunTime);
|
|
||||||
|
|
||||||
return wantedSpeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentRunTime = Mathf.Clamp(_currentRunTime + (float) delta, 0, MaxRunTime);
|
|
||||||
|
|
||||||
return _currentRunTime >= MaxRunTime ? _walkSpeed : wantedSpeed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://vuq8rjq3vegn
|
|
||||||
Reference in New Issue
Block a user