using System; using BlueWater.Audios; using BlueWater.Utility; using Sirenix.OdinInspector; using UnityEngine; namespace BlueWater.Tycoons { public static class StatueBarrelSpineAnimation { public const string Idle = "Idle"; } public static class LiquidBarrelSpineAnimation { public const string IdleLevel0 = "Empty"; public const string IdleLevel1 = "Idle1"; public const string IdleLevel2 = "Idle2"; public const string IdleLevel3 = "Idle3"; public const string IdleLevel4 = "Idle4"; public const string IdleLevel5 = "Idle5"; public const string MoldIdle = "IdleDirty"; public const string ChangeCleanLevel0 = "ChangeClean0"; public const string ChangeCleanLevel1 = "ChangeClean1"; public const string ChangeCleanLevel2 = "ChangeClean2"; public const string ChangeCleanLevel3 = "ChangeClean3"; public const string ChangeCleanLevel4 = "ChangeClean4"; public const string ChangeCleanLevel5 = "ChangeClean5"; public const string ChangeMoldLevel0 = "ChangeDirty0"; public const string ChangeMoldLevel1 = "ChangeDirty1"; public const string ChangeMoldLevel2 = "ChangeDirty2"; public const string ChangeMoldLevel3 = "ChangeDirty3"; public const string ChangeMoldLevel4 = "ChangeDirty4"; public const string ChangeMoldLevel5 = "ChangeDirty5"; public const string FillLevel1 = "FillBeer0to1"; public const string FillLevel2 = "FillBeer1to2"; public const string FillLevel3 = "FillBeer2to3"; public const string FillLevel4 = "FillBeer3to4"; public const string FillLevel5 = "FillBeer4to5"; public const string UnfillLevel0 = "EmptyBeer1to0"; public const string UnfillLevel1 = "EmptyBeer2to1"; public const string UnfillLevel2 = "EmptyBeer3to2"; public const string UnfillLevel3 = "EmptyBeer4to3"; public const string UnfillLevel4 = "EmptyBeer5to4"; public const string InteractionLevel0 = "ServingBeer0"; public const string InteractionLevel1 = "ServingBeer1"; public const string InteractionLevel2 = "ServingBeer2"; public const string InteractionLevel3 = "ServingBeer3"; public const string InteractionLevel4 = "ServingBeer4"; public const string InteractionLevel5 = "ServingBeer5"; } public class LiquidBarrel : Barrel { [SerializeField, Required] private SpriteRenderer _liquidImage; [field: SerializeField] public bool IsMoldy { get; private set; } [SerializeField] private float _playerHoldingTime = 3f; [SerializeField] private string _attackMoldSfxName = "AttackMold"; private bool _isPlayerInteracting; private int _currentLevel; protected override void Start() { base.Start(); _liquidImage.sprite = IsActivated ? LiquidData.Sprite : DataManager.Instance.SpriteDataSo.BarrelLock; if (IsStatue) { SpineController.PlayAnimation(StatueBarrelSpineAnimation.Idle, false); } else { SpineController.PlayAnimation(LiquidBarrelSpineAnimation.IdleLevel0, false); } EventManager.OnCleaningAll += RecoveryAll; } private void Update() { if (IsShowing) { EventManager.InvokeHoldInteracting(HoldingElapsedTime); } if (IsMoldy) { if (HoldingElapsedTime >= 1f) { Recovery(); } float playerHoldingDeltaTime = Time.deltaTime / _playerHoldingTime; if (_isPlayerInteracting) { HoldingElapsedTime += playerHoldingDeltaTime; } else { if (HoldingElapsedTime > 0f) { HoldingElapsedTime -= playerHoldingDeltaTime; } } } else { if (!IsAutoSupply) return; if (SupplyElapsedTime >= 1f) { AddCurrentAmount(TycoonManager.Instance.TycoonStatus.BarrelAutoIncrease); SupplyElapsedTime -= 1f; } SupplyElapsedTime += Time.deltaTime; } } protected override void OnDestroy() { base.OnDestroy(); EventManager.OnCleaningAll -= RecoveryAll; } public override void Interaction() { if (!IsMoldy) { OnBarrelInteracted?.Invoke(this); GameManager.Instance.CurrentTycoonPlayer.IsMakingCocktail = true; } else { AudioManager.Instance.PlaySfx(_attackMoldSfxName, true); GameManager.Instance.CurrentTycoonPlayer.IsCleaningMold = true; _isPlayerInteracting = true; } } public override void CancelInteraction() { if (!IsMoldy) { OnBarrelCancelInteracted?.Invoke(); GameManager.Instance.CurrentTycoonPlayer.IsMakingCocktail = false; } else { AudioManager.Instance.StopSfx(_attackMoldSfxName); GameManager.Instance.CurrentTycoonPlayer.IsCleaningMold = false; _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")}"; } SpineController.EnableCustomMaterial(); EventManager.InvokeShowInteractionUi(InteractionMessage); IsShowing = true; } public override void HideInteractionUi() { SpineController.DisableCustomMaterial(); EventManager.InvokeHideInteractionUi(); IsShowing = false; } public override void Activate() { base.Activate(); _liquidImage.sprite = IsActivated ? LiquidData.Sprite : DataManager.Instance.SpriteDataSo.BarrelLock; if (IsStatue) return; _currentLevel = GetCurrentLevel(); IdleAnimation(); } public override void Consume(int amount) { if (!IsActivated || IsMoldy || IsStatue) return; base.Consume(amount); int newLevel = GetCurrentLevel(); if (_currentLevel != newLevel) { UnfillAnimation(newLevel); _currentLevel = newLevel; } } public override void AddCurrentAmount(int addedValue) { if (!IsActivated || IsStatue) return; base.AddCurrentAmount(addedValue); int newLevel = GetCurrentLevel(); if (_currentLevel != newLevel) { FillAnimation(newLevel); _currentLevel = newLevel; } } 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; MoldAnimation(); } public void Recovery() { CancelInteraction(); IsMoldy = false; RecoveryAnimation(); } private void RecoveryAll() { if (!IsMoldy) return; IsMoldy = false; RecoveryAnimation(); } private int GetCurrentLevel() { if (CurrentAmount <= 0) return 0; if (CurrentAmount >= MaxFill) return 5; int range = (int)(MaxFill / 4f); int level = CurrentAmount / range; return level switch { 0 => 1, 1 => 2, 2 => 3, _ => 4 }; } private void IdleAnimation() { switch (_currentLevel) { case 0: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.IdleLevel0, false); break; case 1: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.IdleLevel1, false); break; case 2: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.IdleLevel2, false); break; case 3: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.IdleLevel3, false); break; case 4: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.IdleLevel4, false); break; case 5: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.IdleLevel5, false); break; default: throw new Exception("_currentLevel 존재하지 않는 값"); } } private void FillAnimation(int newLevel) { if (IsMoldy) return; switch (newLevel) { case 1: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.FillLevel1, false); break; case 2: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.FillLevel2, false); break; case 3: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.FillLevel3, false); break; case 4: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.FillLevel4, false); break; case 5: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.FillLevel5, false); break; default: throw new Exception("_currentLevel 존재하지 않는 값"); } } private void UnfillAnimation(int newLevel) { if (IsMoldy) return; switch (newLevel) { case 0: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.UnfillLevel0, false); break; case 1: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.UnfillLevel1, false); break; case 2: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.UnfillLevel2, false); break; case 3: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.UnfillLevel3, false); break; case 4: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.UnfillLevel4, false); break; default: throw new Exception("_currentLevel 존재하지 않는 값"); } } private void MoldAnimation() { switch (_currentLevel) { case 0: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.ChangeMoldLevel0, false); break; case 1: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.ChangeMoldLevel1, false); break; case 2: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.ChangeMoldLevel2, false); break; case 3: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.ChangeMoldLevel3, false); break; case 4: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.ChangeMoldLevel4, false); break; case 5: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.ChangeMoldLevel5, false); break; default: throw new Exception("_currentLevel 존재하지 않는 값"); } SpineController.AddAnimation(LiquidBarrelSpineAnimation.MoldIdle, true); } private void RecoveryAnimation() { switch (_currentLevel) { case 0: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.ChangeCleanLevel0, false); SpineController.AddAnimation(LiquidBarrelSpineAnimation.IdleLevel0, false); break; case 1: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.ChangeCleanLevel1, false); SpineController.AddAnimation(LiquidBarrelSpineAnimation.IdleLevel1, false); break; case 2: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.ChangeCleanLevel2, false); SpineController.AddAnimation(LiquidBarrelSpineAnimation.IdleLevel2, false); break; case 3: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.ChangeCleanLevel3, false); SpineController.AddAnimation(LiquidBarrelSpineAnimation.IdleLevel3, false); break; case 4: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.ChangeCleanLevel4, false); SpineController.AddAnimation(LiquidBarrelSpineAnimation.IdleLevel4, false); break; case 5: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.ChangeCleanLevel5, false); SpineController.AddAnimation(LiquidBarrelSpineAnimation.IdleLevel5, false); break; default: throw new Exception("_currentLevel 존재하지 않는 값"); } } private void InteractionAnimation() { switch (_currentLevel) { case 0: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.InteractionLevel0, false, trackIndex:1); break; case 1: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.InteractionLevel1, false, trackIndex:1); break; case 2: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.InteractionLevel2, false, trackIndex:1); break; case 3: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.InteractionLevel3, false, trackIndex:1); break; case 4: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.InteractionLevel4, false, trackIndex:1); break; case 5: SpineController.PlayAnimation(LiquidBarrelSpineAnimation.InteractionLevel5, false, trackIndex:1); break; default: throw new Exception("_currentLevel 존재하지 않는 값"); } } } }