newlon/scripts/level/PlantField.cs
2025-07-17 11:44:10 +05:00

110 lines
3.5 KiB
C#

using Godot;
using Newlon.Components.GUI.Seedpackets;
using Newlon.Components.Plants;
namespace Newlon.Components.Level;
public partial class PlantField : Node2D
{
private Node2D _plantSetter;
private DisplayResource _resource;
private Seedpacket _slot;
private bool _previousCanPlace;
private ChannelPlayer player;
[Export] private PackedScene particles;
public static PlantField Instance {get; private set;}
public override void _Ready()
{
Instance = this;
_plantSetter = GetChild<Node2D>(0);
player = GetNode<ChannelPlayer>("PlantPlayer");
}
public void SetPlant(Seedpacket slot, DisplayResource resource)
{
_resource = resource;
_slot = slot;
if (resource == null)
{
foreach(var child in _plantSetter.GetChildren())
child.QueueFree();
}
else
{
var scene = resource.Scene.Instantiate<Node2D>();
_plantSetter.AddChild(scene);
scene.UseParentMaterial = true;
}
}
public void ResetPlant()
{
SetPlant(null,null);
}
public override void _Process(double delta)
{
// Getting and storing global mouse position, setting plant-poiner to it
var mouse_pos = GetGlobalMousePosition();
_plantSetter.GlobalPosition = mouse_pos;
// Getting position in grid coordinates
var expected_pos = (_plantSetter.GlobalPosition / FieldParams.Tile).Ceil() * FieldParams.Tile - new Vector2(20, 14);
// Checking for boundaries
bool inBoundary = expected_pos.X > FieldParams.LeftFieldBoundary.X && expected_pos.X < FieldParams.RightFieldBoundary.X && expected_pos.Y > FieldParams.LeftFieldBoundary.Y && expected_pos.Y < FieldParams.RightFieldBoundary.Y;
bool canPlace = _resource != null
&& inBoundary
&& PoolContainer.Instance.EntityField[_resource.Layer].ContainsKey(expected_pos) == false
&& RuntimeLevelData.Instance.CheckSpendSun(_resource.Cost);
// Setting visuals
if (_previousCanPlace != canPlace)
{
if (canPlace)
{
Material.Set("shader_parameter/amount", 0);
}
else
{
Material.Set("shader_parameter/amount", 1);
}
Cursor.Instance.plant = canPlace;
Cursor.Instance.UpdateCursor();
}
_previousCanPlace = canPlace;
if (canPlace)
_plantSetter.GlobalPosition = expected_pos;
}
public override void _UnhandledInput(InputEvent @event)
{
if (@event.IsActionPressed("cancel_plant") && _slot != null)
{
_slot.ReleaseFocus();
}
if (@event.IsActionPressed("primary_action") && _previousCanPlace)
{
var plant = _resource.Scene.Instantiate<RuntimePlantData>();
PoolContainer.Instance.Plants.AddChild(plant);
plant.GlobalPosition = (_plantSetter.GlobalPosition / FieldParams.Tile).Ceil() * FieldParams.Tile - new Vector2(20, 14);
plant.Resource = (PlantResource)_resource;
PoolContainer.Instance.EntityField[_resource.Layer].Add(plant.GlobalPosition, plant);
RuntimeLevelData.Instance.SpendSun(_resource.Cost);
PoolContainer.Instance.SpawnParticles(particles, plant.GlobalPosition + Vector2.Down * FieldParams.TileHeight/2.0f);
player.Play();
// Unfocusing and recharging slot
_slot.Recharge();
}
}
}