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; [Export] private Camera3D _camera; 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) { Vector2 mousePosition = GetViewport().GetMousePosition(); var dropPlane = new Plane(new Vector3(0, 0, 10), 10); Vector3? position3D = dropPlane.IntersectsRay(_camera.ProjectRayOrigin(mousePosition), _camera.ProjectRayNormal(mousePosition)); Debug.Print(position3D.ToString()); if (position3D.HasValue) { Vector2I adjustedPosition = new Vector2I(AdjustValue(position3D.Value.X), AdjustValue(position3D.Value.Y)); if (@event.IsActionPressed("click") && _hoeInHand) { MakeField(adjustedPosition); } if (@event.IsActionPressed("click") && _waterCanInHand) { WaterTheField(adjustedPosition); } } } private void WaterTheField(Vector2I fieldPosition) { FieldBehaviour field = FieldParent.Get(fieldPosition); if (field == null) return; field.Water(); } private void MakeField(Vector2I fieldPosition) { if(FieldParent == null || _fieldPrefab == null) return; // only instantiate a field if there isn't one already. if(FieldParent.Get(fieldPosition) == 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(fieldPosition, fields[0] as FieldBehaviour); // reposition and reparent the instance field3d.Position = new Vector3(fieldPosition.X, 0.1f, fieldPosition.Y * -1);; FieldParent.AddChild(fieldInstance); } } } private int AdjustValue(float value) { return (int) Mathf.Floor(value); } }