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("FlashController").Deselect(); hoveredEntity = null; ButtonPressed = false; } if (@event.IsActionPressed("cancel_plant") && ButtonPressed) { hoveredEntity?.GetNode("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("FlashController").Deselect(); hoveredEntity = null; return; } } } else { if (Selected) { hoveredEntity.GetNode("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("FlashController").Select(); return true; } if (chosenEntity == null && Selected && hoveredEntity is RuntimePlantData) { hoveredEntity.GetNode("FlashController").Deselect(); hoveredEntity = null; return true; } if (hoveredEntity == null || chosenEntity == null) return false; if (chosenEntity != hoveredEntity && Selected) { hoveredEntity.GetNode("FlashController").Deselect(); hoveredEntity = chosenEntity; hoveredEntity.GetNode("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("FlashController").Select(); return true; } if (hoveredEntity == null) return false; if (Selected && hoveredEntity != entity) { hoveredEntity.GetNode("FlashController").Deselect(); entity.GetNode("FlashController").Select(); hoveredEntity = entity; return true; } } else { hoveredEntity?.GetNode("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; } }