mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-13 19:45:53 +00:00
Implemented vending machine
This commit is contained in:
parent
d78daf4e18
commit
e5ffb0cf94
32 changed files with 3074 additions and 1992 deletions
222
Scripts/Actors/3D/VendingMachine3D.cs
Normal file
222
Scripts/Actors/3D/VendingMachine3D.cs
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Cirno.Scripts.Interactables;
|
||||
using Cirno.Scripts.Resources;
|
||||
using Cirno.Scripts.UI;
|
||||
using Cirno.Scripts.Utils;
|
||||
using Godot;
|
||||
|
||||
namespace Cirno.Scripts.Actors._3D;
|
||||
|
||||
[Tool]
|
||||
public partial class VendingMachine3D : Interactable3D
|
||||
{
|
||||
public sealed class RuntimeShopEntry
|
||||
{
|
||||
public RuntimeShopEntry(VendingShopEntry entry)
|
||||
{
|
||||
Entry = entry;
|
||||
RemainingQuantity = Math.Max(0, entry.StartingQuantity);
|
||||
}
|
||||
|
||||
public VendingShopEntry Entry { get; }
|
||||
|
||||
public LootItem Item => Entry.Item;
|
||||
|
||||
public bool Unlimited => Entry.Unlimited;
|
||||
|
||||
public int RemainingQuantity { get; private set; }
|
||||
|
||||
public bool CanPurchase(int purchaseCount = 1)
|
||||
{
|
||||
return purchaseCount <= 0 || Unlimited || RemainingQuantity >= purchaseCount;
|
||||
}
|
||||
|
||||
public bool TryConsume(int purchaseCount = 1)
|
||||
{
|
||||
if (purchaseCount <= 0 || Unlimited)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (RemainingQuantity < purchaseCount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RemainingQuantity -= purchaseCount;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[Signal]
|
||||
public delegate void ShopOpenedEventHandler();
|
||||
|
||||
[Signal]
|
||||
public delegate void ShopClosedEventHandler();
|
||||
|
||||
[Export]
|
||||
public PackedScene ShopUiScene { get; private set; } =
|
||||
ResourceLoader.Load<PackedScene>("res://Scenes/HUD/VendingMachineShopUi.tscn");
|
||||
|
||||
[Export]
|
||||
public VendingShopDefinition ShopDefinition { get; private set; } =
|
||||
ResourceLoader.Load<VendingShopDefinition>("res://Resources/Shops/VendingMachine_Default.tres");
|
||||
|
||||
private readonly List<RuntimeShopEntry> _runtimeEntries = [];
|
||||
private VendingMachineShopUi _activeShopUi;
|
||||
private bool _runtimeInitialized;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
AddToGroup("Interactable");
|
||||
|
||||
if (Engine.IsEditorHint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureRuntimeEntries();
|
||||
}
|
||||
|
||||
public override bool CanActivate()
|
||||
{
|
||||
if (Engine.IsEditorHint())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
EnsureRuntimeEntries();
|
||||
|
||||
return !IsShopOpen()
|
||||
&& ShopUiScene != null
|
||||
&& _runtimeEntries.Count > 0
|
||||
&& GameStateManager.Instance?.GameState is not GameState.Shop;
|
||||
}
|
||||
|
||||
public override bool Activate(ActivationType activationType = ActivationType.Toggle)
|
||||
{
|
||||
if (Engine.IsEditorHint())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var typeToUse = activationType is ActivationType.Toggle ? ActivationType.Use : activationType;
|
||||
if (typeToUse is not ActivationType.Use)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!MeetsRequirements() || !CanActivate())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
EnsureRuntimeEntries();
|
||||
|
||||
if (GameStateManager.Instance == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
GameStateManager.Instance.ChangeState(GameState.Shop);
|
||||
|
||||
_activeShopUi = ShopUiScene.Instantiate<VendingMachineShopUi>();
|
||||
_activeShopUi.Init(this);
|
||||
_activeShopUi.Closed += OnShopUiClosed;
|
||||
|
||||
var parent = GetTree().CurrentScene ?? GetTree().Root;
|
||||
parent.AddChild(_activeShopUi);
|
||||
|
||||
EmitSignal(SignalName.ShopOpened);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
if (IsInstanceValid(_activeShopUi))
|
||||
{
|
||||
_activeShopUi.Closed -= OnShopUiClosed;
|
||||
_activeShopUi.QueueFree();
|
||||
}
|
||||
|
||||
_activeShopUi = null;
|
||||
}
|
||||
|
||||
public IReadOnlyList<RuntimeShopEntry> GetEntries()
|
||||
{
|
||||
EnsureRuntimeEntries();
|
||||
return _runtimeEntries;
|
||||
}
|
||||
|
||||
public RuntimeShopEntry FindEntry(StringName itemKey)
|
||||
{
|
||||
EnsureRuntimeEntries();
|
||||
return _runtimeEntries.FirstOrDefault(entry => entry.Item?.ItemKey == itemKey);
|
||||
}
|
||||
|
||||
public bool TryConsumeStock(StringName itemKey, int purchaseCount = 1)
|
||||
{
|
||||
var entry = FindEntry(itemKey);
|
||||
return entry?.TryConsume(purchaseCount) ?? false;
|
||||
}
|
||||
|
||||
// public void _func_godot_apply_properties(Godot.Collections.Dictionary props)
|
||||
// {
|
||||
// if (props.TryGetValue("shop_definition_path", out var shopDefinitionPath))
|
||||
// {
|
||||
// var path = shopDefinitionPath.AsString();
|
||||
// if (!string.IsNullOrWhiteSpace(path))
|
||||
// {
|
||||
// var loadedDefinition = ResourceLoader.Load<VendingShopDefinition>(path);
|
||||
// if (loadedDefinition != null)
|
||||
// {
|
||||
// ShopDefinition = loadedDefinition;
|
||||
// _runtimeInitialized = false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// GD.PrintErr($"Failed to load vending shop definition from '{path}'");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private void EnsureRuntimeEntries()
|
||||
{
|
||||
if (_runtimeInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_runtimeInitialized = true;
|
||||
_runtimeEntries.Clear();
|
||||
|
||||
if (ShopDefinition == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var entry in ShopDefinition.Entries.Where(entry => entry?.Item != null))
|
||||
{
|
||||
_runtimeEntries.Add(new RuntimeShopEntry(entry));
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsShopOpen()
|
||||
{
|
||||
return IsInstanceValid(_activeShopUi);
|
||||
}
|
||||
|
||||
private void OnShopUiClosed()
|
||||
{
|
||||
if (IsInstanceValid(_activeShopUi))
|
||||
{
|
||||
_activeShopUi.Closed -= OnShopUiClosed;
|
||||
}
|
||||
|
||||
_activeShopUi = null;
|
||||
EmitSignal(SignalName.ShopClosed);
|
||||
}
|
||||
}
|
||||
1
Scripts/Actors/3D/VendingMachine3D.cs.uid
Normal file
1
Scripts/Actors/3D/VendingMachine3D.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://kt08ji546nms
|
||||
Loading…
Add table
Add a link
Reference in a new issue