newlon/scripts/gui/ShovelButton.cs
2025-07-28 05:45:31 +05:00

171 lines
5.5 KiB
C#

using Godot;
using Newlon.Components.Plants;
using Newlon.Components.Level;
using Newlon.Components.Zombies;
namespace Newlon.Components.GUI;
public partial class ShovelButton : TextureButton
{
const float CONE_HEALTH = 295.0f;
[Export] private PackedScene particles;
private Entity hoveredEntity;
private bool Selected => hoveredEntity != null;
[Export]
private RayCast2D raycast;
[Export]
private Timer timer;
private void OnFocusExited()
{
ButtonPressed = false;
}
public override void _Ready()
{
raycast.Reparent(PoolContainer.Instance);
FocusExited += OnFocusExited;
timer.Timeout += OnTimerTimeout;
}
public override void _Toggled(bool toggledOn)
{
Cursor.Instance.shovel = toggledOn;
}
public override void _Input(InputEvent @event)
{
if (@event.IsActionPressed("primary_action") && ButtonPressed)
{
if (hoveredEntity != null)
{
if (hoveredEntity is RuntimePlantData hoveredPlant)
{
hoveredPlant.Kill();
PoolContainer.Instance.SpawnParticles(particles, hoveredPlant.GlobalPosition + Vector2.Down * FieldParams.TileHeight / 2.0f);
}
else
{
hoveredEntity.TakeDamage(CONE_HEALTH, null);
timer.Start();
Disabled = true;
}
}
GetViewport().SetInputAsHandled();
hoveredEntity?.GetNode<FlashShaderController>("FlashController").Deselect();
hoveredEntity = null;
ButtonPressed = false;
}
if (@event.IsActionPressed("cancel_action") && ButtonPressed)
{
hoveredEntity?.GetNode<FlashShaderController>("FlashController").Deselect();
hoveredEntity = null;
ButtonPressed = false;
}
}
public override void _Process(double delta)
{
UpdateTimer();
if (ButtonPressed)
{
var gridEntity = GetTile(Cursor.GetCursorPosition());
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 = Cursor.GetCursorPosition();
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;
}
}
else
{
hoveredEntity?.GetNode<FlashShaderController>("FlashController").Deselect();
hoveredEntity = null;
return false;
}
return hoveredEntity != null && hoveredEntity is RuntimeZombieData;
}
private void UpdateTimer()
{
((ShaderMaterial)Material).SetShaderParameter("progress", 1.0-timer.TimeLeft/timer.WaitTime);
}
private void OnTimerTimeout()
{
Disabled = false;
}
}