using System.Collections.Generic; using System.Diagnostics; using System.Linq; using Godot; using Godot.Collections; namespace Babushka.scripts.CSharp.Common.Farming; [GlobalClass] public partial class FarmingControls : Node3D { [Export] private Sprite3D _hoeSprite; [Export] private Sprite3D _wateringCanSprite; [Export] private PackedScene _fieldPrefab; [Export] private Node3D _movingPlayer; public FieldService FieldParent; private bool _hoeInHand = false; private bool _waterCanInHand = false; #region Tools public bool ActivateHoe(bool activate) { bool success = ActivateTool(activate, _hoeSprite); _hoeInHand = success; return success; } public bool ActivateWateringCan(bool activate) { bool success = ActivateTool(activate, _wateringCanSprite); _waterCanInHand = success; return success; } private bool ActivateTool(bool activate, Sprite3D tool) { tool.Visible = !activate; return !activate; } #endregion public override void _Input(InputEvent @event) { if (@event.IsActionPressed("click") && _hoeInHand) { MakeField(); } if (@event.IsActionPressed("click") && _waterCanInHand) { WaterTheField(); } } private void WaterTheField() { Vector2I currentPos = new Vector2I(AdjustValue(_movingPlayer.GlobalPosition.X), AdjustValue(_movingPlayer.GlobalPosition.Z)); FieldBehaviour field = FieldParent.Get(currentPos); if (field == null) return; field.Water(); Debug.Print("Watered the field."); } private void MakeField() { if(FieldParent == null || _fieldPrefab == null) return; // get current player position and adjust it to field / dictionary needs Vector3 playerPos = _movingPlayer.GlobalPosition; playerPos = new Vector3(AdjustValue(playerPos.X), 0.1f, AdjustValue(playerPos.Z)); Vector2I intPosition = new Vector2I((int) playerPos.X, (int) playerPos.Z); // only instantiate a field if there isn't one already. if(FieldParent.Get(intPosition) == null) { Node fieldInstance = _fieldPrefab.Instantiate(); if (fieldInstance is Node3D field3d) { // add dictionary entry for the field Array fields = field3d.FindChildren("*", nameof(FieldBehaviour)); if (fields.Count > 0) FieldParent.TryAddEntry(intPosition, fields[0] as FieldBehaviour); // reposition and reparent the instance field3d.Position = playerPos; FieldParent.AddChild(fieldInstance); } } } private int AdjustValue(float value) { return (int) Mathf.Floor(value); } }