fixed a few issues
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 30s
Create tag and build when new code gets to main / Export (push) Successful in 6m0s

This commit is contained in:
2026-05-06 16:25:56 +02:00
parent bcc748ca6b
commit 7ba4a3db3f
22 changed files with 133 additions and 660 deletions

View File

@@ -26,7 +26,6 @@ public partial class Enemy : CharacterBody3D,
ISpawnable,
IKnockbackable,
ITargetable,
IStunnable,
IForgeEntity
{
public override void _Notification(int what) => this.Notify(what);
@@ -166,7 +165,7 @@ public partial class Enemy : CharacterBody3D,
public void ProcessGameplay(double delta)
{
if (IsStunned || _hitAbilityHandle == null) return;
if (_hitAbilityHandle == null) return;
var bodies = DamageBox.GetOverlappingBodies();
foreach (var body in bodies)
@@ -186,16 +185,16 @@ public partial class Enemy : CharacterBody3D,
public void OnDamageReceived(EventData<DamageDone> data)
{
var source = data.Source as Node;
var sourceName = source?.Name ?? "unknown damage dealer";
GD.Print($"Ouch! Fuck you {sourceName}!");
if (data.Payload.OverkillDamage > 0) GD.Print($"Overkill! {data.Payload.OverkillDamage} damage");
// var source = data.Source as Node;
// var sourceName = source?.Name ?? "unknown damage dealer";
// GD.Print($"Ouch! Fuck you {sourceName}!");
// if (data.Payload.OverkillDamage > 0) GD.Print($"Overkill! {data.Payload.OverkillDamage} damage");
}
private void OnHealthChanged(EntityAttribute healthAttribute, int i)
{
if (healthAttribute.CurrentValue > healthAttribute.Min) return;
Events.Raise(new EventData
{
EventTags = Tag.RequestTag(TagsManager, "events.combat.death").GetSingleTagContainer()!
@@ -213,13 +212,11 @@ public partial class Enemy : CharacterBody3D,
// Remove weapon that might be planted there
foreach (var child in GetChildren())
{
if (child is WeaponSystem system)
{
CallDeferred(Node.MethodName.RemoveChild, system);
GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, system);
system.CallDeferred(Node3D.MethodName.SetGlobalPosition, GlobalPosition + Vector3.Up*EnemyHeight);
system.CallDeferred(WeaponSystem.MethodName.RethrowWeapon);
}
if (child is not WeaponSystem system) continue;
CallDeferred(Node.MethodName.RemoveChild, system);
GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, system);
system.CallDeferred(Node3D.MethodName.SetGlobalPosition, GlobalPosition + Vector3.Up*EnemyHeight);
system.CallDeferred(WeaponSystem.MethodName.RethrowWeapon);
}
foreach (var killable in DeathEffects.ToIKillables())
@@ -243,19 +240,4 @@ public partial class Enemy : CharacterBody3D,
{
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;
}
}

View File

@@ -60,6 +60,7 @@ collision_layer = 0
collision_mask = 16
monitorable = false
script = ExtResource("1_82hkh")
Damage = 20.0
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=1259903749]
shape = SubResource("SphereShape3D_82hkh")

View File

@@ -3,7 +3,7 @@ using System;
using Movementtests.interfaces;
[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()
{
@@ -16,15 +16,15 @@ public partial class FixedDashthroughTarget : AnimatableBody3D, ITargetable, ISt
_defaultCollisionMask = CollisionMask;
}
public bool IsStunned { get; set; }
public float StunDuration { get; set; } = 0.1f;
public void Stun()
public bool IsDisabled { get; set; }
public float DisableDuration { get; set; } = 0.1f;
public void Disable()
{
_defaultCollisionMask = 0;
GetTree().CreateTimer(StunDuration).Timeout += Unstun;
GetTree().CreateTimer(DisableDuration).Timeout += Enable;
}
public void Unstun()
public void Enable()
{
_defaultCollisionMask = CollisionMask;
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -115,7 +115,8 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
public required EventManager Events { 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 FlyingTickBinding { get; set; }
@@ -743,22 +744,32 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
}
// 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.StoppedFlying, new EventElements(StoppedFlyingBinding, InventoryManager.StoppedFlyingAbilities)},
{ WeaponSystem.WeaponEvent.FlyingTick, new EventElements(FlyingTickBinding, InventoryManager.FlyingTickAbilities) },
{ WeaponSystem.WeaponEvent.StartedFlying, StartedFlyingBinding },
{ WeaponSystem.WeaponEvent.StoppedFlying, StoppedFlyingBinding },
{ WeaponSystem.WeaponEvent.FlyingTick, FlyingTickBinding },
{ WeaponSystem.WeaponEvent.StartedPlanted, new EventElements(StartedPlantedBinding, InventoryManager.StartedPlantedAbilities) },
{ WeaponSystem.WeaponEvent.StoppedPlanted, new EventElements(StoppedPlantedBinding, InventoryManager.StoppedPlantedAbilities) },
{ WeaponSystem.WeaponEvent.PlantedTick, new EventElements(PlantedTickBinding, InventoryManager.PlantedTickAbilities) },
{ WeaponSystem.WeaponEvent.StartedPlanted, StartedPlantedBinding },
{ WeaponSystem.WeaponEvent.StoppedPlanted, StoppedPlantedBinding },
{ WeaponSystem.WeaponEvent.PlantedTick, PlantedTickBinding },
};
foreach (var forEvent in EventElementsMap.Keys)
EventInventoryMap = new Dictionary<WeaponSystem.WeaponEvent, IAutoSet<ForgeAbilityBehavior>>
{
var element = EventElementsMap[forEvent];
element.Binding = element.Inventory.Bind();
element.Binding
{ WeaponSystem.WeaponEvent.StartedFlying, InventoryManager.StartedFlyingAbilities },
{ WeaponSystem.WeaponEvent.StoppedFlying, InventoryManager.StoppedFlyingAbilities },
{ 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))
.OnRemove(behavior => WeaponSystem.RemoveAbilityForEvent(forEvent, behavior))
.OnClear(() => WeaponSystem.RemoveAbilitiesForEvent(forEvent));
@@ -769,8 +780,8 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
{
GC.SuppressFinalize(this);
foreach (var element in EventElementsMap.Values)
element.Binding.Dispose();
foreach (var binding in EventBindingsMap.Values)
binding.Dispose();
base.Dispose();
}
@@ -2328,8 +2339,8 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
_hitEnemies.Add(entity);
TriggerDamage();
}
if (enemy is IStunnable stunnable)
stunnable.Stun();
if (enemy is IDisableable disableable)
disableable.Disable();
}
public void OnWeaponDashFinished()
@@ -2485,9 +2496,9 @@ public partial class PlayerController : CharacterBody3D, IForgeEntity, ICueHandl
{
TriggerSimpleDashThroughDamage(entity);
}
if (_targetObject is IStunnable stunnable)
if (_targetObject is IDisableable disableable)
{
stunnable.Stun();
disableable.Disable();
}
IsInvincible = false;
_playerState.SendEvent("attack_finished");

View File

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

View File

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