using Babushka.scripts.CSharp.Low_Code.Variables; using Godot; using Godot.Collections; namespace Babushka.scripts.CSharp.Common.Farming; [GlobalClass] public partial class FarmingControls2D : Node2D { [Export] private VariableResource _sceneKeyProvider; [Export] private PackedScene? _fieldPrefab = null!; [Export] private Node2D _movingPlayer; [Export] private Camera2D _camera; [Export] private CpuParticles2D _wateringParticles; [Export] private float _wateringCanParticlesVerticalOffset = 50f; private int _toolId = -1; private bool _wateringCanFilled = false; [Signal] public delegate void WateringFieldEventHandler(); #region Tools /// /// If no tool has been set, then set the current tool to the incoming tool id. /// /// The id of the tool to activate if possible /// If the tool in question was activated. public bool TryActivateTool(int toolId) { bool activate; //if our hands are empty, activate if (toolId == -1) { activate = false; } else { activate = true; } _toolId = activate ? toolId : -1; WateringCanState.SetActive(_toolId == WateringCanState.WATERING_CAN_ID); return activate; } #endregion public override void _Input(InputEvent @event) { if (@event.IsActionPressed("click") && _toolId == WateringCanState.WATERING_CAN_ID && WateringCanState.GetFillState() > 0) { GD.Print("Trying to use the watering can."); Vector2I adjustedPosition = GetAdjustedMousePosition(); WaterTheField(adjustedPosition); } } private Vector2I GetAdjustedMousePosition() { Vector2 mousePosition = _camera.GetGlobalMousePosition(); Vector2I mousePositionInteger = (Vector2I) mousePosition; Vector2I adjustedPosition = AdjustValue(mousePositionInteger, new Vector2I(735, 651)); return adjustedPosition; } /// /// Called by the allowed farming area collision area 2d. /// /// /// /// public void InputEventPressedOn(Node node, InputEvent inputEvent, int shapeIndex) { if (!inputEvent.IsPressed()) { return; } if (!inputEvent.IsActionPressed("click")) return; if (inputEvent is InputEventMouseButton inputEventMouseButton) { if (!inputEventMouseButton.Pressed) { return; } } else { return; } if (_toolId == 0) { Vector2I adjustedPosition = GetAdjustedMousePosition(); MakeField(adjustedPosition); } } #region WATERING public void FillWateringCan() { if (_toolId == WateringCanState.WATERING_CAN_ID) { WateringCanState.Fill(); } } private void WaterTheField(Vector2I fieldPosition) { FieldBehaviour2D? field = FieldService.Instance.TryGet(_sceneKeyProvider.Payload.AsString(), fieldPosition); if (field == null || field.FieldState == FieldState.Watered) { GD.Print($"The field at position {fieldPosition} is null!"); return; } field.Water(); _wateringParticles.GlobalPosition = new Vector2(field.GlobalPosition.X, field.GlobalPosition.Y + _wateringCanParticlesVerticalOffset); WateringCanState.Water(); GD.Print($"Watered the field at {fieldPosition}."); EmitSignal(SignalName.WateringField); } #endregion #region FIELD CREATION private void MakeField(Vector2I fieldPosition) { if(_fieldPrefab == null) return; // only instantiate a field if there isn't one already. if(FieldService.Instance.TryGet(_sceneKeyProvider.Payload.AsString(), fieldPosition) == null) { GD.Print($"FarmingControls: Creating a field at {fieldPosition}"); Node fieldInstance = _fieldPrefab.Instantiate(); if (fieldInstance is Node2D field2d) { // add dictionary entry for the field Array fields = field2d.FindChildren("*", nameof(FieldBehaviour2D)); if (fields.Count > 0) FieldService.Instance.TryAddEntry(_sceneKeyProvider.Payload.AsString(), fieldPosition, fields[0] as FieldBehaviour2D); // reposition and reparent the instance field2d.Position = new Vector2(fieldPosition.X, fieldPosition.Y);; FieldService.Instance.AddChild(fieldInstance); } } else { GD.Print($"FarmingControls: Could not create a field at {fieldPosition}."); } } private int AdjustValue(float value) { float adjustedValue = value / 500; adjustedValue = Mathf.RoundToInt(adjustedValue); adjustedValue *= 500; return (int)adjustedValue; } private Vector2I AdjustValue(Vector2I input, Vector2I step) { return input.Snapped(step); } #endregion }