Files

265 lines
8.6 KiB
C#
Raw Permalink Normal View History

2025-07-06 23:48:01 +02:00
using System;
using Babushka.scripts.CSharp.Common.CharacterControls;
using Babushka.scripts.CSharp.Common.Inventory;
2025-11-12 18:46:30 +01:00
using Babushka.scripts.CSharp.Common.Savegame;
2025-11-11 15:51:15 +01:00
using Babushka.scripts.CSharp.Low_Code.Events;
using Babushka.scripts.CSharp.Low_Code.Variables;
2025-05-12 00:16:13 +02:00
using Godot;
2025-11-12 18:46:30 +01:00
using Godot.Collections;
2025-05-12 00:16:13 +02:00
namespace Babushka.scripts.CSharp.Common.Farming;
2025-11-12 18:46:30 +01:00
/// <summary>
/// Defines the behaviour of the field, i.e. interactions, states and effects.
/// </summary>
2025-05-12 00:16:13 +02:00
[GlobalClass]
public partial class FieldBehaviour2D : Sprite2D
{
2025-11-12 18:46:30 +01:00
[ExportGroup("Persistence")]
[Export] public string SaveId = "";
[Export] private VariableNode _fieldIndex;
[Export] public VariableResource _sceneKeyProvider;
[Export] public FieldState FieldState = FieldState.Tilled;
[ExportGroup("Field Visuals")]
2025-07-06 23:48:01 +02:00
[Export] private Sprite2D _fieldSprite;
[Export] private Sprite2D _maskSprite;
2025-11-07 19:47:23 +01:00
[Export] private Sprite2D _outlineSprite;
[Export] private Texture2D[] _maskOutlineTextures;
2025-07-06 23:48:01 +02:00
[Export] private Texture2D[] _maskTexture;
2025-05-12 00:16:13 +02:00
[Export] private Texture2D Tilled;
[Export] private Texture2D Watered;
2025-11-12 18:46:30 +01:00
[ExportGroup("Field Interactions")]
[Export] public InteractionArea2D PlantingInteraction;
2025-11-12 18:46:30 +01:00
[Export] public InteractionArea2D FieldInteractionArea;
[ExportGroup("Configuration")]
2025-08-17 21:57:57 +02:00
[Export] public Node2D PlantingPlaceholder;
2025-09-09 23:57:55 +02:00
[Export] public ItemRepository ItemRepository;
2025-11-11 15:51:15 +01:00
[Export] private CpuParticles2D _wateringParticles;
[Export] private EventResource _wateringEvent;
private bool _seedsActive;
2025-11-07 20:37:59 +01:00
private bool _wateringCanActive;
2025-11-11 15:51:15 +01:00
private bool _canPlant;
private bool _canWater;
2025-11-12 18:46:30 +01:00
private PlantBehaviour2D? _currentPlant;
[Signal] public delegate void PlantedEventHandler();
private void UpdateInteractionArea()
{
// fieldstate == tilled / watered && samen im Inventar
2025-11-11 15:51:15 +01:00
_canPlant = (FieldState == FieldState.Tilled || FieldState == FieldState.Watered) && _seedsActive;
// fieldstate == tilled && watering can ausgewählt
_canWater = (FieldState == FieldState.Tilled || FieldState == FieldState.Planted) && _wateringCanActive;
2025-11-11 15:51:15 +01:00
FieldInteractionArea.IsActive = _canPlant || _canWater;
}
public void ActivatedSeedInInventory(bool activated)
{
_seedsActive = activated;
UpdateInteractionArea();
}
2025-11-07 20:37:59 +01:00
public void ActivateWateringCanInInventory(bool activated)
{
_wateringCanActive = activated;
UpdateInteractionArea();
}
2025-11-12 18:46:30 +01:00
2025-05-12 00:16:13 +02:00
public override void _Ready()
{
LoadFromSaveData();
2025-11-12 18:46:30 +01:00
if(PlantingPlaceholder.GetChildCount() > 0)
_currentPlant = PlantingPlaceholder.GetChild<PlantBehaviour2D>(0);
2025-05-18 12:32:56 +02:00
UpdateFieldState(FieldState);
2025-11-12 18:46:30 +01:00
FieldService.Instance.TryAddEntry(_sceneKeyProvider.Payload.AsString(),_fieldIndex.Payload.AsInt32(), this);
2025-11-12 18:46:30 +01:00
2025-07-06 23:48:01 +02:00
int randomIndex = new Random().Next(0, _maskTexture.Length);
_maskSprite.Texture = _maskTexture[randomIndex];
2025-11-07 19:47:23 +01:00
_outlineSprite.Texture = _maskOutlineTextures[randomIndex];
2025-05-12 00:16:13 +02:00
base._Ready();
}
2025-05-18 12:32:56 +02:00
public void UpdateFieldState(FieldState state)
{
switch (state)
{
case FieldState.Empty:
FieldState = FieldState.Empty;
PlantingInteraction.IsActive = false;
2025-05-18 12:32:56 +02:00
break;
case FieldState.Tilled:
FieldState = FieldState.Tilled;
2025-07-06 23:48:01 +02:00
_fieldSprite.Texture = Tilled;
PlantingInteraction.IsActive = true;
2025-05-18 12:32:56 +02:00
break;
case FieldState.Watered:
FieldState = FieldState.Watered;
2025-07-06 23:48:01 +02:00
_fieldSprite.Texture = Watered;
PlantingInteraction.IsActive = true;
2025-05-18 12:32:56 +02:00
break;
case FieldState.Planted:
FieldState = FieldState.Planted;
2025-08-17 21:57:57 +02:00
_fieldSprite.Texture = Tilled;
PlantingInteraction.IsActive = false;
2025-05-18 12:32:56 +02:00
break;
default:
FieldState = FieldState.NotFound;
break;
}
2025-11-07 20:37:59 +01:00
UpdateInteractionArea();
2025-11-12 18:46:30 +01:00
UpdateSaveData();
2025-05-18 12:32:56 +02:00
}
2025-05-12 00:16:13 +02:00
public void Water()
{
if (WateringCanState.GetFillState() > 0)
{
UpdateFieldState(FieldState.Watered);
_wateringParticles.Emitting = true;
WateringCanState.Water();
_wateringEvent.Raise();
}
2025-05-12 00:16:13 +02:00
}
/// <summary>
/// Called when the player enters the field's interaction area and presses <E> or clicks.
2025-05-12 00:16:13 +02:00
/// </summary>
public void Farm()
{
if (_canPlant && TryPlant())
{
EmitSignal(SignalName.Planted);
UpdateFieldState(FieldState.Planted);
}
2025-11-11 15:51:15 +01:00
if (_canWater)
{
Water();
}
}
private bool TryPlant()
{
bool success = false;
int currentSlotIndex = InventoryManager.Instance.CurrentSelectedSlotIndex;
ItemInstance? item = InventoryManager.Instance.playerInventory.Slots[currentSlotIndex].itemInstance;
2025-09-17 15:07:17 +02:00
if (item == null || PlantingPlaceholder.GetChildCount() > 0 || item.amount == 0)
return success;
2025-09-10 15:06:49 +02:00
2025-11-12 18:46:30 +01:00
string plantPrefabPath = ItemRepository.TryGetPrefabPath(item.blueprint);
2025-11-12 18:46:30 +01:00
if (!string.IsNullOrEmpty(plantPrefabPath))
{
PlantPrefab(plantPrefabPath);
2025-09-17 15:07:17 +02:00
InventoryManager.Instance.playerInventory.RemoveItem(currentSlotIndex);
2025-09-09 23:57:55 +02:00
success = true;
2025-05-12 00:16:13 +02:00
}
return success;
2025-05-12 00:16:13 +02:00
}
private void PlantPrefab(string prefabPath)
{
PackedScene prefab = ResourceLoader.Load<PackedScene>(prefabPath, nameof(PackedScene));
Node2D plant2d = prefab.Instantiate<Node2D>();
PlantingPlaceholder.AddChild(plant2d);
plant2d.GlobalPosition = PlantingPlaceholder.GlobalPosition;
_currentPlant = plant2d as PlantBehaviour2D;
if (_currentPlant != null)
{
_currentPlant.Field = this;
}
}
2025-11-15 22:27:26 +01:00
#region SAVE AND LOAD
2025-11-12 18:46:30 +01:00
public void UpdateSaveData()
{
var saveData = new SaveData();
saveData.SceneName = _sceneKeyProvider.Payload.AsString();
saveData.Id = SaveId + _fieldIndex.Payload.AsString();
var payloadData = new Dictionary<string, Variant>
{
{ "field_state", (int)FieldState }
};
if (_currentPlant != null)
{
payloadData.Add(
"plant_data", new Dictionary<string, Variant>()
{
{ "prefab_path", _currentPlant.PrefabPath },
{ "plant_state", (int)_currentPlant.State },
{ "plant_days_growing", _currentPlant.DaysGrowing }
}
);
}
saveData.JsonPayload = Json.Stringify(payloadData, indent: "\t");
SavegameService.AppendSave(saveData);
}
public void LoadFromSaveData()
{
var sceneName = _sceneKeyProvider.Payload.AsString();
var id = SaveId + _fieldIndex.Payload.AsString();
string jsonPayload = SavegameService.GetSaveData(sceneName, id);
Dictionary<string, Variant> save = Json.ParseString(jsonPayload).AsGodotDictionary<string, Variant>();
if (save.Count > 0)
{
if (save.TryGetValue("field_state", out Variant fieldStateVar))
{
int fieldStateInt = fieldStateVar.AsInt32();
FieldState = (FieldState) fieldStateInt;
if (fieldStateInt != 0)
{
Visible = true;
UpdateFieldState(FieldState);
}
}
if (save.TryGetValue("plant_data", out Variant plantDataVar))
{
Dictionary<string, Variant> plantDataDict = plantDataVar.AsGodotDictionary<string, Variant>();
if (plantDataDict.TryGetValue("prefab_path", out Variant prefabPathVar))
{
PlantPrefab(prefabPathVar.AsString());
}
else
{
return;
}
if (plantDataDict.TryGetValue("plant_state", out Variant plantStateVar) && _currentPlant != null)
{
_currentPlant.State = (PlantState) plantStateVar.AsInt32();
_currentPlant.GrowPlant();
}
if (plantDataDict.TryGetValue("plant_days_growing", out Variant plantDaysGrowingVar) && _currentPlant != null)
{
_currentPlant.DaysGrowing = plantDaysGrowingVar.AsInt32();
}
}
}
}
2025-11-15 22:27:26 +01:00
#endregion
2025-11-12 18:46:30 +01:00
}