using BlueWater.Utility; using Sirenix.OdinInspector; using UnityEngine; namespace BlueWater.Tycoons { public static class LiquidBarrelSpineAnimation { public const string Idle = "IdleNormal"; public const string Mold = "IdleDirty"; public const string ChangeIdle = "ChangeClean"; public const string ChangeMold = "ChangeDirty"; } public class LiquidBarrel : Barrel { [SerializeField, Required] private SpriteRenderer _liquidImage; [SerializeField, Required] private SpriteRenderer _fill; [SerializeField, Range(1f, 5f), Tooltip("목표 색상 * 밝기")] private float _colorIntensity = 2f; [field: SerializeField] public bool IsMoldy { get; private set; } [SerializeField] private float _playerHoldingTime = 3f; private Material _instanceMaterial; private bool _isPlayerInteracting; // Hashes private static readonly int LiquidAmountHash = Shader.PropertyToID("_LiquidAmount"); private static readonly int LiquidColorHash = Shader.PropertyToID("_LiquidColor"); protected override void Awake() { base.Awake(); _instanceMaterial = Instantiate(_fill.material); _fill.material = _instanceMaterial; } protected override void Start() { base.Start(); _liquidImage.sprite = IsActivated ? LiquidData.Sprite : DataManager.Instance.SpriteDataSo.BarrelLock; _instanceMaterial.SetColor(LiquidColorHash, LiquidData.Color * _colorIntensity); if (!IsStatue) { SpineController.PlayAnimation(LiquidBarrelSpineAnimation.Idle, false); } } private void Update() { if (IsShowing) { var holdingGauge = Mathf.Clamp(HoldingElapsedTime / _playerHoldingTime, 0f, 1f); EventManager.InvokeHoldInteracting(holdingGauge); } if (IsMoldy) { if (HoldingElapsedTime >= _playerHoldingTime) { Recovery(); } if (_isPlayerInteracting) { HoldingElapsedTime += Time.deltaTime; } else { if (HoldingElapsedTime > 0f) { HoldingElapsedTime -= Time.deltaTime; } } } else { if (!IsAutoSupply) return; if (SupplyElapsedTime >= 1f) { AddCurrentAmount(TycoonManager.Instance.TycoonStatus.BarrelAutoIncrease); SupplyElapsedTime -= 1f; } SupplyElapsedTime += Time.deltaTime; } } public override void Interaction() { if (!IsMoldy) { OnBarrelInteracted?.Invoke(this); GameManager.Instance.CurrentTycoonPlayer.IsMakingCocktail = true; } else { _isPlayerInteracting = true; } } public override void CancelInteraction() { if (!IsMoldy) { OnBarrelCancelInteracted?.Invoke(); GameManager.Instance.CurrentTycoonPlayer.IsMakingCocktail = false; } else { _isPlayerInteracting = false; HoldingElapsedTime = 0f; } } /// /// 1. 플레이어가 빈 잔을 들고 있거나 완성되지 않은 잔을 들고 있을 때 /// public override bool CanInteraction() { return IsActivated && !CurrentTycoonPlayer.TycoonPickupHandler.IsPickedUpItem && ((!IsMoldy && CanConsume(1)) || IsMoldy); } public override void ShowInteractionUi() { if (IsMoldy) { UpdateLocalizedString("InteractionMold"); } else { InteractionMessage = $"{Utils.GetLocalizedString(LiquidData.Idx)} {Utils.GetLocalizedString("Pour")}"; } if (IsStatue) { base.ShowInteractionUi(); } else { SpineController.EnableCustomMaterial(); EventManager.InvokeShowInteractionUi(InteractionMessage); IsShowing = true; } } public override void HideInteractionUi() { if (IsStatue) { base.HideInteractionUi(); } else { SpineController.DisableCustomMaterial(); EventManager.InvokeHideInteractionUi(); IsShowing = false; } } public override void SetCurrentAmount(int amount) { base.SetCurrentAmount(amount); var liquidAmount = CurrentAmount / VisualMaxFill; _instanceMaterial.SetFloat(LiquidAmountHash, liquidAmount); } public override void Activate() { base.Activate(); _liquidImage.sprite = IsActivated ? LiquidData.Sprite : DataManager.Instance.SpriteDataSo.BarrelLock; } public override bool CanMakingCocktailCrew(int amount) { return IsActivated && !IsMoldy && CanConsume(amount); } public override bool CanMold() { return !IsStatue && IsActivated && !IsMoldy; } public override void Mold() { IsMoldy = true; SpineController.PlayAnimation(LiquidBarrelSpineAnimation.ChangeMold, false); SpineController.AddAnimation(LiquidBarrelSpineAnimation.Mold, true); } public void Recovery() { CancelInteraction(); IsMoldy = false; SpineController.PlayAnimation(LiquidBarrelSpineAnimation.ChangeIdle, false); SpineController.AddAnimation(LiquidBarrelSpineAnimation.Idle, false); } } }