You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Babushka/scripts/CSharp/Common/Farming/PlantBehaviour2D.cs

211 lines
5.9 KiB

using System;
using System.Diagnostics;
using Babushka.scripts.CSharp.Common.Inventory;
using Babushka.scripts.CSharp.Low_Code.Variables;
using Godot;
using Godot.Collections;
namespace Babushka.scripts.CSharp.Common.Farming;
/// <summary>
/// Determines the behaviour of a plant in Babushka.
/// </summary>
public partial class PlantBehaviour2D : Node2D
{
[ExportGroup("Plant State")]
[Export] private Sprite2D[] _seeds;
[Export] private Sprite2D[] _smallPlants;
[Export] private Sprite2D[] _bigPlants;
[Export] private Sprite2D[] _readyPlants;
[Export] private PlantState _state = PlantState.None;
[Export] private FieldBehaviour2D _field;
[Export] private ItemOnGround2D _harvestablePlant;
[Export] private CpuParticles2D _magicEffect;
[Export] private bool _magicWordNeeded = true;
[ExportGroup("PlantConfig")]
[Export] private string _prefabPath;
[Export] private VariableNode _lifecycle;
[Export] private int _daysWatered;
private string _magicWordDialogicEventName = "MagicWord";
private Sprite2D? _currentPlantSprite = null;
private bool _magicWordSaid = false;
private bool _calledOnReady = false;
private int _dayPlanted;
private int _currentDay;
public PlantState State
{
get => _state;
set => _state = value;
}
/// <summary>
/// The day count at the day this plant was planted.
/// </summary>
public int DayPlanted
{
get => _dayPlanted;
set => _dayPlanted = value;
}
public int CurrentDayInCalendar
{
get => _currentDay;
set
{
if (_currentDay == value) return;
_currentDay = value;
DaysGrowingChanged();
}
}
public string PrefabPath => _prefabPath;
/// <summary>
/// public accessor for the field reference
/// </summary>
public FieldBehaviour2D Field
{
get => _field;
set => _field = value;
}
public int DaysWatered
{
get => _daysWatered;
set
{
_daysWatered = value;
}
}
public override void _Ready()
{
if (_state == PlantState.None)
{
_state = PlantState.Planted;
_currentPlantSprite = GetRandomSprite(_seeds);
_currentPlantSprite.Visible = true;
}
else
{
_calledOnReady = true;
GrowPlant();
}
}
private void DaysGrowingChanged()
{
int lifecycle = _lifecycle.Payload.AsInt32();
Debug.Assert(lifecycle > 0);
float growth = (float)_daysWatered / lifecycle;
int growthFloor = Mathf.FloorToInt(growth);
_state = growthFloor switch
{
0 => PlantState.None,
1 => PlantState.Planted,
2 => PlantState.SmallPlant,
_ => PlantState.BigPlant
};
_calledOnReady = true;
Grow();
}
public void Grow()
{
GrowPlant();
}
/// <summary>
/// Transitions the plant to its next growth stage.
/// </summary>
public void GrowPlant()
{
if (!_calledOnReady)
{
if (_field.FieldState != FieldState.Watered || _magicWordSaid != _magicWordNeeded)
return;
}
switch (_state)
{
case PlantState.None:
_state = PlantState.Planted;
_currentPlantSprite = GetRandomSprite(_seeds);
_currentPlantSprite.Visible = true;
break;
case PlantState.Planted:
_state = PlantState.SmallPlant;
if(_currentPlantSprite != null)
_currentPlantSprite.Visible = false;
_currentPlantSprite = GetRandomSprite(_smallPlants);
_currentPlantSprite.Visible = true;
break;
case PlantState.SmallPlant:
_state = PlantState.BigPlant;
if(_currentPlantSprite != null)
_currentPlantSprite.Visible = false;
_currentPlantSprite = GetRandomSprite(_bigPlants);
_currentPlantSprite.Visible = true;
break;
case PlantState.BigPlant:
_state = PlantState.Ready;
if(_currentPlantSprite != null)
_currentPlantSprite.Visible = false;
_currentPlantSprite = GetRandomSprite(_readyPlants);
_currentPlantSprite.Visible = true;
//ActivatePickupAfterDelay(true);
SetActiveHarvestablePlant(true);
break;
case PlantState.Ready:
_state = PlantState.None;
if(_currentPlantSprite != null)
_currentPlantSprite.Visible = false;
_currentPlantSprite = null;
//ActivatePickupAfterDelay(false);
SetActiveHarvestablePlant(false);
break;
default:
break;
}
_field.UpdateFieldState(FieldState.Tilled);
_magicWordSaid = false;
_calledOnReady = false;
}
private Sprite2D GetRandomSprite(Sprite2D[] sprites)
{
Random rand = new Random();
return sprites[rand.Next(sprites.Length)];
}
public async void ActivatePickupAfterDelay(bool activate)
{
await ToSignal(GetTree().CreateTimer(1.0f), "timeout");
SetActiveHarvestablePlant(activate);
}
private void SetActiveHarvestablePlant(bool active)
{
_harvestablePlant.IsActive = active;
_harvestablePlant.UpdateVisuals();
}
public void SayMagicWord(string wordEvent)
{
if (_magicWordDialogicEventName != wordEvent)
return;
_magicEffect.Emitting = true;
_magicEffect.OneShot = true;
_magicWordSaid = true;
Grow();
}
}