Plants flash and shovel alt
This commit is contained in:
parent
b4bf3ab8bc
commit
e4c25a1ca5
23 changed files with 451 additions and 195 deletions
|
|
@ -6,7 +6,9 @@ namespace Newlon.Components;
|
|||
public partial class Armor : Node
|
||||
{
|
||||
[Signal]
|
||||
public delegate void ArmorDamagedEventHandler(float hp);
|
||||
public delegate void DamagedEventHandler();
|
||||
[Signal]
|
||||
public delegate void HpChangedEventHandler(float hp);
|
||||
[Signal]
|
||||
public delegate void ArmorLostEventHandler();
|
||||
|
||||
|
|
@ -32,14 +34,16 @@ public partial class Armor : Node
|
|||
{
|
||||
var delta = _hp;
|
||||
_hp = 0;
|
||||
EmitSignal(SignalName.ArmorDamaged, delta);
|
||||
EmitSignal(SignalName.HpChanged, -delta);
|
||||
EmitSignal(SignalName.Damaged);
|
||||
EmitSignal(SignalName.ArmorLost);
|
||||
_lost = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_hp -= damage;
|
||||
EmitSignal(SignalName.ArmorDamaged, damage);
|
||||
EmitSignal(SignalName.HpChanged, -damage);
|
||||
EmitSignal(SignalName.Damaged);
|
||||
}
|
||||
return returnAmount;
|
||||
}
|
||||
|
|
@ -55,7 +59,7 @@ public partial class Armor : Node
|
|||
returnAmount = _hp-MaxHP;
|
||||
_hp = MaxHP;
|
||||
}
|
||||
EmitSignal(SignalName.ArmorDamaged,_hp);
|
||||
EmitSignal(SignalName.HpChanged,_hp);
|
||||
return returnAmount;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,21 +11,21 @@ public partial class ArmorHPObserver : Node
|
|||
|
||||
public override void _Ready()
|
||||
{
|
||||
_observedArmor.ArmorDamaged += OnHPChanged;
|
||||
_observedArmor.Damaged += OnDamaged;
|
||||
}
|
||||
|
||||
private void OnHPChanged(float delta)
|
||||
private void OnDamaged()
|
||||
{
|
||||
if (_setGreater == false && _observedArmor._hp / _observedArmor.MaxHP < _threshold)
|
||||
{
|
||||
EmitSignal(SignalName.ThresholdReached);
|
||||
_observedArmor.ArmorDamaged -= OnHPChanged;
|
||||
_observedArmor.Damaged -= OnDamaged;
|
||||
QueueFree();
|
||||
}
|
||||
else if (_setGreater && _observedArmor._hp / _observedArmor.MaxHP > _threshold)
|
||||
{
|
||||
EmitSignal(SignalName.ThresholdReached);
|
||||
_observedArmor.ArmorDamaged -= OnHPChanged;
|
||||
_observedArmor.Damaged -= OnDamaged;
|
||||
QueueFree();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ public partial class DegradingSprite : Sprite2D
|
|||
|
||||
public override void _Ready()
|
||||
{
|
||||
armor.ArmorDamaged += OnArmorHPChanged;
|
||||
armor.Damaged += OnDamaged;
|
||||
}
|
||||
|
||||
private void OnArmorHPChanged(float hp)
|
||||
private void OnDamaged()
|
||||
{
|
||||
float percent = armor._hp / armor.MaxHP;
|
||||
for (int i = 0; i < degradationStages.Count; i++)
|
||||
|
|
|
|||
|
|
@ -10,13 +10,15 @@ public partial class Entity : Node2D
|
|||
{
|
||||
#region Health points
|
||||
[Export] public float MaxHP;
|
||||
public float HP;
|
||||
[Export]public float HP;
|
||||
[Signal] public delegate void OnHPChangedEventHandler(EntitySignalContext context);
|
||||
[Signal] public delegate void OnDamagedEventHandler();
|
||||
|
||||
public virtual void TakeDamage(float amount, Node origin)
|
||||
{
|
||||
EmitSignal(SignalName.OnDamaged);
|
||||
if(amount > 0)
|
||||
EmitSignal(SignalName.OnDamaged);
|
||||
|
||||
var context = new EntitySignalContext()
|
||||
{
|
||||
target = this,
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
using Godot;
|
||||
using System;
|
||||
|
||||
namespace Newlon.Components;
|
||||
|
||||
public partial class FlashComponent : CanvasGroup
|
||||
{
|
||||
[Export] private float _flashDuration = 0.1f;
|
||||
private Tween _tween;
|
||||
private ShaderMaterial _shaderMaterial;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_shaderMaterial = Material as ShaderMaterial;
|
||||
}
|
||||
|
||||
public void DamageFlash(EntitySignalContext context)
|
||||
{
|
||||
Flash();
|
||||
}
|
||||
|
||||
|
||||
public void Flash()
|
||||
{
|
||||
_tween?.Kill();
|
||||
_tween = CreateTween();
|
||||
|
||||
Action<float> action = SetAmount;
|
||||
_tween.TweenMethod(Callable.From(action),0.8f,0.0f,_flashDuration);
|
||||
}
|
||||
|
||||
private void SetAmount(float amount)
|
||||
{
|
||||
_shaderMaterial.SetShaderParameter("amount",amount);
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://c5vfccegyy01t
|
||||
51
scripts/entities/FlashShaderController.cs
Normal file
51
scripts/entities/FlashShaderController.cs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
using Godot;
|
||||
using Newlon.Components;
|
||||
|
||||
public partial class FlashShaderController : Node
|
||||
{
|
||||
[Export] public float flashTime = 0.5f;
|
||||
[Export]
|
||||
private ShaderMaterial shaderMaterial;
|
||||
private uint toggleStack = 0;
|
||||
private Tween flashTween;
|
||||
public void DamageFlash()
|
||||
{
|
||||
Flash();
|
||||
}
|
||||
public void Flash(float customFlashTime = 0)
|
||||
{
|
||||
if (flashTween != null)
|
||||
flashTween.Kill();
|
||||
var time = flashTime;
|
||||
if (customFlashTime > 0)
|
||||
time = customFlashTime;
|
||||
|
||||
flashTween = CreateTween();
|
||||
flashTween.TweenMethod(Callable.From<float>(SetBlend), 1.0, 0.0, time);
|
||||
}
|
||||
public void Select()
|
||||
{
|
||||
toggleStack++;
|
||||
UpdateSelected();
|
||||
}
|
||||
public void Deselect()
|
||||
{
|
||||
toggleStack--;
|
||||
UpdateSelected();
|
||||
}
|
||||
private void SetBlend(float blend)
|
||||
{
|
||||
shaderMaterial.SetShaderParameter("blend", blend);
|
||||
}
|
||||
private void UpdateSelected()
|
||||
{
|
||||
if (toggleStack > 0)
|
||||
{
|
||||
shaderMaterial.SetShaderParameter("selected", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
shaderMaterial.SetShaderParameter("selected", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
1
scripts/entities/FlashShaderController.cs.uid
Normal file
1
scripts/entities/FlashShaderController.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://30pbgasu64aw
|
||||
|
|
@ -49,15 +49,18 @@ public partial class RuntimeZombieData : Entity
|
|||
damage = _armor.RecieveDamage(amount);
|
||||
}
|
||||
|
||||
EmitSignal(SignalName.OnDamaged);
|
||||
var context = new EntitySignalContext()
|
||||
{
|
||||
source = origin,
|
||||
target = this,
|
||||
actionAmount = amount
|
||||
};
|
||||
if(damage > 0)
|
||||
EmitSignal(SignalName.OnDamaged);
|
||||
|
||||
if (HP - damage <= 0)
|
||||
{
|
||||
|
||||
var delta = -HP;
|
||||
HP = 0;
|
||||
EmitSignal(SignalName.OnHPChanged, context);
|
||||
|
|
@ -80,7 +83,7 @@ public partial class RuntimeZombieData : Entity
|
|||
|
||||
EmitSignal(SignalName.HPChangedMixed, new EntitySignalContext()
|
||||
{
|
||||
deltaHP = -delta,
|
||||
deltaHP = delta,
|
||||
source = null,
|
||||
target = this,
|
||||
actionAmount = delta
|
||||
|
|
|
|||
|
|
@ -1,16 +1,26 @@
|
|||
using Godot;
|
||||
using Newlon.Components.Plants;
|
||||
using Newlon.Components.Level;
|
||||
using Newlon.Components.Zombies;
|
||||
|
||||
namespace Newlon.Components.GUI;
|
||||
|
||||
public partial class ShovelButton : TextureButton
|
||||
{
|
||||
[Export] private PackedScene particles;
|
||||
private Entity hoveredEntity;
|
||||
private bool Selected => hoveredEntity != null;
|
||||
[Export]
|
||||
private RayCast2D raycast;
|
||||
private void OnFocusExited()
|
||||
{
|
||||
ButtonPressed = false;
|
||||
}
|
||||
public override void _Ready()
|
||||
{
|
||||
raycast.Reparent(PoolContainer.Instance);
|
||||
}
|
||||
|
||||
public override void _Toggled(bool toggledOn)
|
||||
{
|
||||
Cursor.Instance.shovel = toggledOn;
|
||||
|
|
@ -22,24 +32,118 @@ public partial class ShovelButton : TextureButton
|
|||
|
||||
if (@event.IsActionPressed("primary_action") && ButtonPressed)
|
||||
{
|
||||
var checkedPosition = (PoolContainer.Instance.Plants.GetGlobalMousePosition() / FieldParams.Tile).Ceil() * FieldParams.Tile - new Vector2(20, 14);
|
||||
|
||||
for (int i = FieldParams.LayersCount - 1; i >= 0; i--)
|
||||
if (hoveredEntity != null)
|
||||
{
|
||||
if (PoolContainer.Instance.EntityField[i].TryGetValue(checkedPosition, out var entity) && entity is RuntimePlantData plantData)
|
||||
if (hoveredEntity is RuntimePlantData hoveredPlant)
|
||||
{
|
||||
plantData.Kill();
|
||||
|
||||
PoolContainer.Instance.SpawnParticles(particles, plantData.GlobalPosition + Vector2.Down * FieldParams.TileHeight / 2.0f);
|
||||
|
||||
break;
|
||||
hoveredPlant.Kill();
|
||||
PoolContainer.Instance.SpawnParticles(particles, hoveredPlant.GlobalPosition + Vector2.Down * FieldParams.TileHeight / 2.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
hoveredEntity.TakeDamage(205, null);
|
||||
}
|
||||
}
|
||||
hoveredEntity?.GetNode<FlashShaderController>("FlashController").Deselect();
|
||||
hoveredEntity = null;
|
||||
ButtonPressed = false;
|
||||
}
|
||||
if (@event.IsActionPressed("cancel_plant") && ButtonPressed)
|
||||
{
|
||||
hoveredEntity?.GetNode<FlashShaderController>("FlashController").Deselect();
|
||||
hoveredEntity = null;
|
||||
ButtonPressed = false;
|
||||
}
|
||||
}
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
|
||||
if (ButtonPressed)
|
||||
{
|
||||
var gridEntity = GetTile(PoolContainer.Instance.Plants.GetGlobalMousePosition());
|
||||
if (TrySetGridEntity(gridEntity)) return;
|
||||
if (TrySetDynEntity()) return;
|
||||
|
||||
else
|
||||
{
|
||||
if (Selected)
|
||||
{
|
||||
hoveredEntity.GetNode<FlashShaderController>("FlashController").Deselect();
|
||||
hoveredEntity = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Selected)
|
||||
{
|
||||
hoveredEntity.GetNode<FlashShaderController>("FlashController").Deselect();
|
||||
hoveredEntity = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
private Entity GetTile(Vector2 position)
|
||||
{
|
||||
var checkedPosition = (position / FieldParams.Tile).Ceil() * FieldParams.Tile - new Vector2(20, 14);
|
||||
for (int i = FieldParams.LayersCount - 1; i >= 0; i--)
|
||||
{
|
||||
if (PoolContainer.Instance.EntityField[i].TryGetValue(checkedPosition, out var entity) && entity is RuntimePlantData plantData)
|
||||
{
|
||||
return plantData;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private bool TrySetGridEntity(Entity chosenEntity)
|
||||
{
|
||||
if (chosenEntity != null && Selected == false)
|
||||
{
|
||||
hoveredEntity = chosenEntity;
|
||||
hoveredEntity.GetNode<FlashShaderController>("FlashController").Select();
|
||||
return true;
|
||||
}
|
||||
if (chosenEntity == null && Selected && hoveredEntity is RuntimePlantData)
|
||||
{
|
||||
hoveredEntity.GetNode<FlashShaderController>("FlashController").Deselect();
|
||||
hoveredEntity = null;
|
||||
return true;
|
||||
}
|
||||
if (hoveredEntity == null || chosenEntity == null) return false;
|
||||
if (chosenEntity != hoveredEntity && Selected)
|
||||
{
|
||||
hoveredEntity.GetNode<FlashShaderController>("FlashController").Deselect();
|
||||
hoveredEntity = chosenEntity;
|
||||
hoveredEntity.GetNode<FlashShaderController>("FlashController").Select();
|
||||
return true;
|
||||
}
|
||||
return hoveredEntity != null && hoveredEntity is RuntimeZombieData == false;
|
||||
}
|
||||
private bool TrySetDynEntity()
|
||||
{
|
||||
raycast.GlobalPosition = PoolContainer.Instance.GetGlobalMousePosition();
|
||||
|
||||
if (raycast.IsColliding())
|
||||
{
|
||||
var entity = ((Area2D)raycast.GetCollider()).GetParent() as Entity;
|
||||
|
||||
if (entity == null) return false;
|
||||
|
||||
if (Selected == false)
|
||||
{
|
||||
hoveredEntity = entity;
|
||||
hoveredEntity.GetNode<FlashShaderController>("FlashController").Select();
|
||||
return true;
|
||||
}
|
||||
if (hoveredEntity == null) return false;
|
||||
if (Selected && hoveredEntity != entity)
|
||||
{
|
||||
hoveredEntity.GetNode<FlashShaderController>("FlashController").Deselect();
|
||||
entity.GetNode<FlashShaderController>("FlashController").Select();
|
||||
hoveredEntity = entity;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return hoveredEntity != null && hoveredEntity is RuntimeZombieData;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue