타이쿤 업데이트

This commit is contained in:
Nam Tae Gun 2025-02-18 06:47:56 +09:00
parent bf08756a77
commit 62f936092d
248 changed files with 59128 additions and 26776 deletions

File diff suppressed because it is too large Load Diff

View File

@ -26,12 +26,12 @@ namespace DDD.BehaviorTrees.Actions
return TaskStatus.Success; return TaskStatus.Success;
} }
var emptyServingTable = tycoonManager.ServingTableController.FindEmptyServingTable(); // var emptyServingTable = tycoonManager.ServingTableController.FindEmptyServingTable();
if (emptyServingTable) // if (emptyServingTable)
{ // {
_serverCrew.OnMission(emptyServingTable, null, ActionType.PlaceOnServingTable); // _serverCrew.OnMission(emptyServingTable, null, ActionType.PlaceOnServingTable);
return TaskStatus.Success; // return TaskStatus.Success;
} // }
return TaskStatus.Running; return TaskStatus.Running;
} }

View File

@ -1,6 +1,7 @@
using System; using System;
using BehaviorDesigner.Runtime.Tasks; using BehaviorDesigner.Runtime.Tasks;
using DDD.Npcs.Customers; using DDD.Npcs.Customers;
using DDD.Tycoons;
using UnityEngine; using UnityEngine;
using Action = BehaviorDesigner.Runtime.Tasks.Action; using Action = BehaviorDesigner.Runtime.Tasks.Action;
@ -25,7 +26,7 @@ namespace DDD.BehaviorTrees.Actions
public override TaskStatus OnUpdate() public override TaskStatus OnUpdate()
{ {
if (_elapsedTime <= _customer.CurrentLevelData.EatingTime) if (_elapsedTime <= TycoonManager.Instance.TycoonStageController.StageDataSo.EatingTime)
{ {
_elapsedTime += Time.deltaTime; _elapsedTime += Time.deltaTime;
return TaskStatus.Running; return TaskStatus.Running;

View File

@ -81,7 +81,7 @@ namespace DDD.Npcs.Crews.Bartender
public void SetBartenderTable(BartenderTable bartenderTable) public void SetBartenderTable(BartenderTable bartenderTable)
{ {
MyBartenderTable = bartenderTable; MyBartenderTable = bartenderTable;
MyBartenderTable.Active(); //MyBartenderTable.Active();
} }
public void SetOrderedCustomer(Customer orderedCustomer) public void SetOrderedCustomer(Customer orderedCustomer)
@ -111,7 +111,7 @@ namespace DDD.Npcs.Crews.Bartender
OrderedCustomer.CurrentBill.BartenderCompleteMakingCocktail(); OrderedCustomer.CurrentBill.BartenderCompleteMakingCocktail();
} }
MyBartenderTable.CompleteMakingCocktail(_makingCocktailData); //MyBartenderTable.CompleteMakingCocktail(_makingCocktailData);
EventManager.InvokeCocktailCompleted(_makingCocktailData, false); EventManager.InvokeCocktailCompleted(_makingCocktailData, false);
ResetMission(); ResetMission();
} }

View File

@ -8,8 +8,10 @@ using DDD.Items;
using DDD.Npcs.Crews; using DDD.Npcs.Crews;
using DDD.Npcs.Crews.Server; using DDD.Npcs.Crews.Server;
using DDD.Players; using DDD.Players;
using DDD.ScriptableObjects;
using DDD.Tycoons; using DDD.Tycoons;
using DDD.Uis; using DDD.Uis;
using DDD.Uis.Tycoon;
using Pathfinding; using Pathfinding;
using PixelCrushers.DialogueSystem; using PixelCrushers.DialogueSystem;
using Sirenix.OdinInspector; using Sirenix.OdinInspector;
@ -59,7 +61,7 @@ namespace DDD.Npcs.Customers
public enum CustomerInteractionType public enum CustomerInteractionType
{ {
None = 0, None = 0,
ServedCocktail OrderedCook
} }
public enum CustomerSkin public enum CustomerSkin
@ -138,6 +140,9 @@ namespace DDD.Npcs.Customers
[field: SerializeField] [field: SerializeField]
public CocktailData OrderedCocktailData { get; private set; } public CocktailData OrderedCocktailData { get; private set; }
[field: SerializeField]
public CraftRecipeData OrderedCraftRecipeData { get; private set; }
[field: SerializeField] [field: SerializeField]
public Bill CurrentBill { get; private set; } public Bill CurrentBill { get; private set; }
@ -345,61 +350,6 @@ namespace DDD.Npcs.Customers
}; };
VisualLook.localScale = localScale; VisualLook.localScale = localScale;
} }
public void SetTableSeat(TableSeat tableSeat)
{
CurrentTableSeat = tableSeat;
}
public void SetCurrentDirection(Vector3 normalDirection) => CurrentDirection = normalDirection;
public void SetTableSeatPositionAndDirection()
{
transform.position = CurrentTableSeat.SeatTransform.position;
CurrentTableSeat.OccupySeat();
CurrentTableSeat.UnreserveSeat();
SetCurrentDirection(CurrentTableSeat.TableDirection);
}
public void ServedItem(CocktailData cocktailData)
{
CurrentTableSeat.MenuBalloonUi.ReceiveItem(cocktailData);
if (IsOrderedCorrected)
{
CurrentTableSeat.SetFood(cocktailData.Sprite);
StateMachineController.TransitionToState(HappyState, this);
int tip;
if (IsServedPlayer)
{
if (TycoonManager.Instance.TycoonStatus.ContainsPassiveCard(PassiveCard.ServingBonus))
{
TycoonManager.Instance.TycoonStageController.ServingBonus();
}
tip = (int)(CurrentLevelData.Gold * TycoonManager.Instance.TycoonStatus.TipMultiplier);
}
else
{
tip = (int)(CurrentLevelData.Gold * TycoonManager.Instance.TycoonStatus.ServerTipMultiplier);
}
if (tip > 0)
{
var payMoneyUi = Instantiate(_payMoneyUiObject, transform.position + _offset,
Quaternion.identity, TycoonUiManager.Instance.WorldCanvas.transform);
payMoneyUi.Initialize(tip, true);
}
}
else
{
StateMachineController.TransitionToState(UpsetState, this);
}
EventManager.InvokeCocktailServedToCustomer(cocktailData, IsServedPlayer);
EventManager.InvokeOrderResult(this, IsOrderedCorrected);
EventManager.InvokeSucceedServing(IsOrderedCorrected);
EventManager.InvokeCheckedSkin(CustomerSkin);
}
public void Interaction() public void Interaction()
{ {
@ -407,14 +357,15 @@ namespace DDD.Npcs.Customers
{ {
case CustomerInteractionType.None: case CustomerInteractionType.None:
break; break;
case CustomerInteractionType.ServedCocktail: case CustomerInteractionType.OrderedCook:
var currentPickupItem = GameManager.Instance.CurrentTycoonPlayer.TycoonPickupHandler.CurrentPickupItem; CraftRecipeData playerPickupCook = GameManager.Instance.CurrentTycoonPlayer.TycoonPickupHandler.CurrentCraftRecipeData;
//var servedCocktailData = ItemManager.Instance.CocktailDataSo.GetDataByIdx(currentPickupItem.Idx); //var servedCocktailData = ItemManager.Instance.CocktailDataSo.GetDataByIdx(currentPickupItem.Idx);
IsOrderedCorrected = currentPickupItem.Idx == OrderedCocktailData.Idx; //IsOrderedCorrected = currentPickupItem.Idx == OrderedCocktailData.Idx;
IsReceivedItem = true; IsReceivedItem = true;
IsServedPlayer = true; IsServedPlayer = true;
AudioManager.Instance.PlaySfx(IsOrderedCorrected ? _succeedServingSfxName : _failedServingSfxName); IsOrderedCorrected = true;
//ServedItem(servedCocktailData); AudioManager.Instance.PlaySfx(_succeedServingSfxName);
ServedItem(playerPickupCook);
break; break;
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
@ -429,9 +380,9 @@ namespace DDD.Npcs.Customers
{ {
case CustomerInteractionType.None: case CustomerInteractionType.None:
return false; return false;
case CustomerInteractionType.ServedCocktail: case CustomerInteractionType.OrderedCook:
var currentPickupItem = GameManager.Instance.CurrentTycoonPlayer.TycoonPickupHandler.CurrentPickupItem; CraftRecipeData playerPickupCook = GameManager.Instance.CurrentTycoonPlayer.TycoonPickupHandler.CurrentCraftRecipeData;
return currentPickupItem != null; return playerPickupCook?.Idx == OrderedCraftRecipeData.Idx;
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }
@ -490,6 +441,85 @@ namespace DDD.Npcs.Customers
_customerInteractionType = CustomerInteractionType.None; _customerInteractionType = CustomerInteractionType.None;
} }
public void OrderCook()
{
IsReceivedItem = false;
OrderedCraftRecipeData = FindAnyObjectByType<MenuBoardUi>().GetRandomTodayMenu();
HurryTime = CurrentLevelData.HurryTime + TycoonManager.Instance.TycoonStatus.CustomerHurryTimeIncrease;
CurrentTableSeat.OrderCook(OrderedCraftRecipeData, isReverse:true);
_customerInteractionType = CustomerInteractionType.OrderedCook;
RegisterPlayerInteraction();
EventManager.InvokeOrderedCocktail(this);
// if (!ES3.Load(SaveData.TutorialB, false))
// {
// EventManager.InvokeTutorial(TutorialName.TutorialB);
// ES3.Save(SaveData.TutorialB, true);
// }
//
// if (!ES3.Load(SaveData.TutorialJ, false) && OrderedCocktailData.Idx == "Cocktail006")
// {
// EventManager.InvokeTutorial(TutorialName.TutorialJ);
// ES3.Save(SaveData.TutorialJ, true);
// }
}
public void SetTableSeat(TableSeat tableSeat)
{
CurrentTableSeat = tableSeat;
}
public void SetCurrentDirection(Vector3 normalDirection) => CurrentDirection = normalDirection;
public void SetTableSeatPositionAndDirection()
{
transform.position = CurrentTableSeat.SeatTransform.position;
CurrentTableSeat.OccupySeat();
CurrentTableSeat.UnreserveSeat();
SetCurrentDirection(CurrentTableSeat.TableDirection);
}
public void ServedItem(CraftRecipeData craftRecipeData)
{
CurrentTableSeat.MenuBalloonUi.ReceiveItem();
if (IsOrderedCorrected)
{
CurrentTableSeat.SetFood(craftRecipeData.Sprite);
StateMachineController.TransitionToState(HappyState, this);
// int tip;
// if (IsServedPlayer)
// {
// if (TycoonManager.Instance.TycoonStatus.ContainsPassiveCard(PassiveCard.ServingBonus))
// {
// TycoonManager.Instance.TycoonStageController.ServingBonus();
// }
//
// tip = (int)(CurrentLevelData.Gold * TycoonManager.Instance.TycoonStatus.TipMultiplier);
// }
// else
// {
// tip = (int)(CurrentLevelData.Gold * TycoonManager.Instance.TycoonStatus.ServerTipMultiplier);
// }
//
// if (tip > 0)
// {
// var payMoneyUi = Instantiate(_payMoneyUiObject, transform.position + _offset,
// Quaternion.identity, TycoonUiManager.Instance.WorldCanvas.transform);
// payMoneyUi.Initialize(tip, true);
// }
}
else
{
StateMachineController.TransitionToState(UpsetState, this);
}
EventManager.InvokeServedCookToCustomer();
EventManager.InvokeServedResult(this, IsOrderedCorrected);
//EventManager.InvokeSucceedServing(IsOrderedCorrected);
//EventManager.InvokeCheckedSkin(CustomerSkin);
}
public void Bark(string conversation, BarkOrder barkOrder = BarkOrder.Random) public void Bark(string conversation, BarkOrder barkOrder = BarkOrder.Random)
{ {
@ -525,7 +555,7 @@ namespace DDD.Npcs.Customers
CurrentTableSeat.CleanTable(); CurrentTableSeat.CleanTable();
} }
GainExp(); //GainExp();
} }
private void GainExp() private void GainExp()
@ -541,11 +571,11 @@ namespace DDD.Npcs.Customers
_moneyCounter.AddCurrentGold(gold); _moneyCounter.AddCurrentGold(gold);
if (!ES3.Load(SaveData.TutorialC, false)) // if (!ES3.Load(SaveData.TutorialC, false))
{ // {
EventManager.InvokeTutorial(TutorialName.TutorialC); // EventManager.InvokeTutorial(TutorialName.TutorialC);
ES3.Save(SaveData.TutorialC, true); // ES3.Save(SaveData.TutorialC, true);
} // }
} }
public void Vomit() public void Vomit()
@ -577,7 +607,7 @@ namespace DDD.Npcs.Customers
OrderedCocktailData = TycoonManager.Instance.TycoonIngredientController.GetRandomCocktailData(); OrderedCocktailData = TycoonManager.Instance.TycoonIngredientController.GetRandomCocktailData();
HurryTime = CurrentLevelData.HurryTime + TycoonManager.Instance.TycoonStatus.CustomerHurryTimeIncrease; HurryTime = CurrentLevelData.HurryTime + TycoonManager.Instance.TycoonStatus.CustomerHurryTimeIncrease;
CurrentTableSeat.OrderCocktail(OrderedCocktailData.Idx, CurrentLevelData.WaitTime, HurryTime, true); CurrentTableSeat.OrderCocktail(OrderedCocktailData.Idx, CurrentLevelData.WaitTime, HurryTime, true);
_customerInteractionType = CustomerInteractionType.ServedCocktail; _customerInteractionType = CustomerInteractionType.OrderedCook;
RegisterPlayerInteraction(); RegisterPlayerInteraction();
EventManager.InvokeOrderedCocktail(this); EventManager.InvokeOrderedCocktail(this);

View File

@ -70,6 +70,14 @@ namespace DDD.Players.Tycoons
{ {
return TycoonPlayerSpineAnimation.AttackLimeTree; return TycoonPlayerSpineAnimation.AttackLimeTree;
} }
if (character.IsCookingFried)
{
return TycoonPlayerSpineAnimation.CookingFried;
}
if (character.IsCookingStew)
{
return TycoonPlayerSpineAnimation.CookingStew;
}
return null; return null;
} }

View File

@ -1,4 +1,5 @@
using DDD.Interfaces; using DDD.Interfaces;
using DDD.ScriptableObjects;
using Sirenix.OdinInspector; using Sirenix.OdinInspector;
using UnityEngine; using UnityEngine;
@ -15,7 +16,11 @@ namespace DDD.Players.Tycoons
[field: SerializeField] [field: SerializeField]
public bool IsPickedUpItem { get; private set; } public bool IsPickedUpItem { get; private set; }
[field: SerializeField]
public bool IsPickedUpCook { get; private set; }
public IPickup CurrentPickupItem { get; private set; } public IPickup CurrentPickupItem { get; private set; }
public CraftRecipeData CurrentCraftRecipeData { get; private set; }
private void Awake() private void Awake()
{ {
@ -107,5 +112,59 @@ namespace DDD.Players.Tycoons
CurrentPickupItem = item; CurrentPickupItem = item;
EventManager.InvokeChangedPickupItem(CurrentPickupItem?.Idx); EventManager.InvokeChangedPickupItem(CurrentPickupItem?.Idx);
} }
public bool PickupCook(CraftRecipeData craftRecipeData)
{
if (IsPickedUpCook)
{
Debug.Log("이미 밀키트를 들고 있습니다.");
return false;
}
SetCurrentCraftRecipeData(craftRecipeData);
IsUnfinishedCocktailPickedUp = false;
_itemRenderer.enabled = false;
//_itemRenderer.sprite = item.Sprite;
IsPickedUpCook = true;
return true;
}
public void InteractionCraftingTool()
{
CurrentCraftRecipeData.CraftingToolQueue.Dequeue();
if (CurrentCraftRecipeData.CraftingToolQueue.Count <= 0)
{
// TODO : 요리 완성 처리
EventManager.InvokeChangedCraftingTool(null);
}
else
{
EventManager.InvokeChangedCraftingTool(CurrentCraftRecipeData.CraftingToolQueue.Peek());
}
}
public void DiscardCook()
{
SetCurrentCraftRecipeData(null);
_itemRenderer.sprite = null;
IsPickedUpCook = false;
}
public void SetCurrentCraftRecipeData(CraftRecipeData craftRecipeData)
{
CurrentCraftRecipeData = craftRecipeData;
EventManager.InvokeChangedPickupItem(CurrentCraftRecipeData?.Idx);
if (CurrentCraftRecipeData == null || CurrentCraftRecipeData.CraftingToolQueue.Count <= 0)
{
EventManager.InvokeChangedCraftingTool(null);
}
else
{
EventManager.InvokeChangedCraftingTool(CurrentCraftRecipeData.CraftingToolQueue.Peek());
}
}
} }
} }

View File

@ -1,5 +1,6 @@
using DDD.Interfaces; using DDD.Interfaces;
using DDD.Items; using DDD.Items;
using DDD.ScriptableObjects;
using DDD.Tycoons; using DDD.Tycoons;
using DDD.Uis; using DDD.Uis;
using Sirenix.OdinInspector; using Sirenix.OdinInspector;
@ -11,16 +12,18 @@ namespace DDD.Players.Tycoons
public static class TycoonPlayerSpineAnimation public static class TycoonPlayerSpineAnimation
{ {
public const string Idle = "Idle"; public const string Idle = "Idle";
public const string Walking = "Run"; public const string Walking = "RunFast";
public const string ServingIdle = "ServingIdle"; public const string ServingIdle = "Serving/ServingIdle";
public const string Serving = "Serving"; public const string Serving = "Serving/ServingFast";
public const string Dash = "Dash"; public const string Dash = "Dash";
public const string CleaningFloor = "CleaningFloor"; public const string CleaningFloor = "Cleaning/CleaningFloor";
public const string CleaningTable = "CleaningTable"; public const string CleaningTable = "Cleaning/CleaningTable";
public const string MakingCocktail = "BeerMaker"; public const string MakingCocktail = "BeerMaker";
public const string Pumping = "AttackWhip"; public const string Pumping = "Attack/AttackWhip";
public const string AttackSlime = "AttackSlime"; public const string AttackSlime = "Attack/AttackSlime";
public const string AttackLimeTree = "AttackBat"; public const string AttackLimeTree = "Attack/AttackBat";
public const string CookingFried = "Cooking/CookingFried";
public const string CookingStew = "Cooking/CookingStew";
} }
[DefaultExecutionOrder(-1)] [DefaultExecutionOrder(-1)]
@ -75,6 +78,8 @@ namespace DDD.Players.Tycoons
public bool IsPumping { get; set; } public bool IsPumping { get; set; }
public bool IsInteractedSlimeGarnish { get; set; } public bool IsInteractedSlimeGarnish { get; set; }
public bool IsInteractedLimeTreeGarnish { get; set; } public bool IsInteractedLimeTreeGarnish { get; set; }
public bool IsCookingFried { get; set; }
public bool IsCookingStew { get; set; }
// State // State
public StateMachineController<TycoonPlayer> StateMachineController { get; private set; } public StateMachineController<TycoonPlayer> StateMachineController { get; private set; }
@ -107,6 +112,10 @@ namespace DDD.Players.Tycoons
EventManager.OnChangedRandomCocktail += ChangeCocktail; EventManager.OnChangedRandomCocktail += ChangeCocktail;
EventManager.OnPickupCocktail += PickupCocktail; EventManager.OnPickupCocktail += PickupCocktail;
EventManager.OnPlaceOnServingTable += PlaceOnServingTable; EventManager.OnPlaceOnServingTable += PlaceOnServingTable;
// 밀키트 이벤트
EventManager.OnPickupMealKit += PickupCook;
EventManager.OnServedCookToCustomer += ServedCook;
TycoonMovement.OnSucceedDash += DashSucceed; TycoonMovement.OnSucceedDash += DashSucceed;
@ -139,6 +148,10 @@ namespace DDD.Players.Tycoons
EventManager.OnPickupCocktail -= PickupCocktail; EventManager.OnPickupCocktail -= PickupCocktail;
EventManager.OnPlaceOnServingTable -= PlaceOnServingTable; EventManager.OnPlaceOnServingTable -= PlaceOnServingTable;
// 밀키트 이벤트
EventManager.OnPickupMealKit -= PickupCook;
EventManager.OnServedCookToCustomer -= ServedCook;
TycoonMovement.OnSucceedDash -= DashSucceed; TycoonMovement.OnSucceedDash -= DashSucceed;
} }
@ -200,6 +213,21 @@ namespace DDD.Players.Tycoons
TycoonPickupHandler.PickupItem(cocktailData, true); TycoonPickupHandler.PickupItem(cocktailData, true);
InteractionCanvas.BalloonUi.SetItemImage(cocktailData); InteractionCanvas.BalloonUi.SetItemImage(cocktailData);
} }
public void PickupCook(CraftRecipeData craftRecipeData)
{
bool succeedPickUp = TycoonPickupHandler.PickupCook(craftRecipeData);
if (succeedPickUp)
{
InteractionCanvas.BalloonUi.SetItemImage(craftRecipeData.Sprite);
}
}
public void ServedCook()
{
TycoonPickupHandler.DiscardCook();
InteractionCanvas.BalloonUi.DiscardItem();
}
public void PlaceOnServingTable() public void PlaceOnServingTable()
{ {
@ -237,7 +265,7 @@ namespace DDD.Players.Tycoons
public bool IsInteracting() public bool IsInteracting()
{ {
return IsMakingCocktail || IsCleaningFloor || IsCleaningTable || IsCleaningMold || IsPumping || return IsMakingCocktail || IsCleaningFloor || IsCleaningTable || IsCleaningMold || IsPumping ||
IsInteractedSlimeGarnish || IsInteractedLimeTreeGarnish; IsInteractedSlimeGarnish || IsInteractedLimeTreeGarnish || IsCookingFried || IsCookingStew;
} }
#endregion #endregion

View File

@ -9,61 +9,61 @@ namespace DDD.Tycoons
{ {
public class BartenderTable : ServingTable public class BartenderTable : ServingTable
{ {
[SerializeField] // [SerializeField]
private Sprite _activeSprite; // private Sprite _activeSprite;
//
// [SerializeField]
// private Sprite _inactiveSprite;
//
// protected override void Awake()
// {
// base.Awake();
//
// VisualLook.sprite = _inactiveSprite;
// }
//
// public void Active()
// {
// VisualLook.sprite = _activeSprite;
// }
//
// public override void Interaction()
// {
// // 테이블의 칵테일을 가져가는 경우
// if (CurrentPickupItem != null)
// {
// //CocktailData currentCocktailData = ItemManager.Instance.CocktailDataSo.GetDataByIdx(CurrentPickupItem.Idx);
// //EventManager.InvokePickupCocktail(currentCocktailData);
// CocktailGlassImage.sprite = null;
// CocktailGlassImage.enabled = false;
// // InteractionCanvas.BalloonUi.DiscardItem();
// CurrentPickupItem = null;
// OrderedCustomer = null;
// }
// }
[SerializeField] // public override bool CanInteraction()
private Sprite _inactiveSprite; // {
// return CurrentPickupItem != null && !CurrentTycoonPlayer.TycoonPickupHandler.IsPickedUpAnything();
protected override void Awake() // }
{
base.Awake();
VisualLook.sprite = _inactiveSprite;
}
public void Active()
{
VisualLook.sprite = _activeSprite;
}
public override void Interaction()
{
// 테이블의 칵테일을 가져가는 경우
if (CurrentPickupItem != null)
{
//CocktailData currentCocktailData = ItemManager.Instance.CocktailDataSo.GetDataByIdx(CurrentPickupItem.Idx);
//EventManager.InvokePickupCocktail(currentCocktailData);
CocktailGlassImage.sprite = null;
CocktailGlassImage.enabled = false;
// InteractionCanvas.BalloonUi.DiscardItem();
CurrentPickupItem = null;
OrderedCustomer = null;
}
}
public override bool CanInteraction() // public override bool CanInteractionCrew(Crew crew = null)
{ // {
return CurrentPickupItem != null && !CurrentTycoonPlayer.TycoonPickupHandler.IsPickedUpAnything(); // var servingCrew = (ServerCrew)crew;
} // if (!servingCrew)
// {
public override bool CanInteractionCrew(Crew crew = null) // throw new Exception("상호작용 오브젝트 오류");
{ // }
var servingCrew = (ServerCrew)crew; //
if (!servingCrew) // return servingCrew.CurrentActionType == ActionType.TakeCocktail && CurrentPickupItem != null && OrderedCustomer;
{ // }
throw new Exception("상호작용 오브젝트 오류"); //
} // public void CompleteMakingCocktail(IPickup cocktailData)
// {
return servingCrew.CurrentActionType == ActionType.TakeCocktail && CurrentPickupItem != null && OrderedCustomer; // CurrentPickupItem = cocktailData;
} // CocktailGlassImage.sprite = CurrentPickupItem.Sprite;
// CocktailGlassImage.enabled = true;
public void CompleteMakingCocktail(IPickup cocktailData) // // InteractionCanvas.BalloonUi.SetItemImage(CurrentPickupItem);
{ // }
CurrentPickupItem = cocktailData;
CocktailGlassImage.sprite = CurrentPickupItem.Sprite;
CocktailGlassImage.enabled = true;
// InteractionCanvas.BalloonUi.SetItemImage(CurrentPickupItem);
}
} }
} }

View File

@ -178,7 +178,7 @@ namespace DDD.Tycoons
{ {
if (IsMoldy) if (IsMoldy)
{ {
UpdateLocalizedString("InteractionMold"); InteractionMessage = Utils.GetLocalizedString("InteractionMold");
} }
else else
{ {

View File

@ -1,184 +0,0 @@
using System;
using System.Collections;
using DDD.Audios;
using DDD.Interfaces;
using DDD.Items;
using DDD.Npcs.Crews;
using DDD.Npcs.Crews.Server;
using DDD.Npcs.Customers;
using DDD.Utility;
using UnityEngine;
using UnityEngine.Serialization;
namespace DDD.Tycoons
{
public class ServingTable : InteractionFurniture, ICrewInteraction
{
[FormerlySerializedAs("_cocktailGlassImage")]
[SerializeField]
protected SpriteRenderer CocktailGlassImage;
[SerializeField]
private string _putDownSfxName = "PutDownCocktail";
// 서빙 테이블 기준 아이템이 있는지 없는지
private IPickup _currentPickupItem;
public IPickup CurrentPickupItem
{
get => _currentPickupItem;
protected set
{
_currentPickupItem = value;
if (_currentPickupItem != null)
{
Utils.StartUniqueCoroutine(this, ref _findCustomerMatchingItemInstance, FindCustomerMatchingItem());
}
else
{
if (_findCustomerMatchingItemInstance != null)
{
StopCoroutine(_findCustomerMatchingItemInstance);
_findCustomerMatchingItemInstance = null;
}
if (_findServerCrewInstance != null)
{
StopCoroutine(_findServerCrewInstance);
_findServerCrewInstance = null;
}
}
}
}
protected Customer OrderedCustomer;
private Material _originalCocktailGlassMaterial;
private Coroutine _findCustomerMatchingItemInstance;
private Coroutine _findServerCrewInstance;
public event Action OnInteractionCompleted;
protected override void Awake()
{
base.Awake();
_originalCocktailGlassMaterial = CocktailGlassImage.material;
CocktailGlassImage.sprite = null;
CocktailGlassImage.enabled = false;
}
public override void Interaction()
{
// 테이블의 칵테일을 가져가는 경우
if (CurrentPickupItem != null)
{
//CocktailData currentCocktailData = ItemManager.Instance.CocktailDataSo.GetDataByIdx(CurrentPickupItem.Idx);
//EventManager.InvokePickupCocktail(currentCocktailData);
CocktailGlassImage.sprite = null;
CocktailGlassImage.enabled = false;
// InteractionCanvas.BalloonUi.DiscardItem();
CurrentPickupItem = null;
OrderedCustomer = null;
}
// 테이블에 칵테일을 놓는 경우
else
{
AudioManager.Instance.PlaySfx(_putDownSfxName);
CurrentPickupItem = CurrentTycoonPlayer.TycoonPickupHandler.CurrentPickupItem;
CocktailGlassImage.sprite = CurrentPickupItem.Sprite;
CocktailGlassImage.enabled = true;
// InteractionCanvas.BalloonUi.SetItemImage(CurrentPickupItem);
EventManager.InvokePlaceOnServingTable();
}
}
public override bool CanInteraction()
{
// 1. 테이블에 칵테일이 있고, 플레이어가 칵테일을 들고 있지 않은 경우
// 2. 테이블에 칵테일이 없고, 플레이어가 칵테일을 들고 있는 경우 (정상적인 칵테일만)
return (CurrentPickupItem != null && !CurrentTycoonPlayer.TycoonPickupHandler.IsPickedUpAnything()) ||
(CurrentPickupItem == null && CurrentTycoonPlayer.TycoonPickupHandler.IsServablePickupItem());
}
public override void ShowInteractionUi()
{
if (CurrentPickupItem != null)
{
UpdateLocalizedString("InteractionServingTablePickUp");
}
else
{
UpdateLocalizedString("InteractionServingTablePutDown");
}
base.ShowInteractionUi();
CocktailGlassImage.material = OutlineMaterial;
}
public override void HideInteractionUi()
{
base.HideInteractionUi();
CocktailGlassImage.material = _originalCocktailGlassMaterial;
}
public void InteractionCrew(Crew crew)
{
// 종업원이 테이블의 칵테일을 가져가는 경우
if (CurrentPickupItem != null)
{
var serverCrew = (ServerCrew)crew;
serverCrew.TakeFromServingTable(CurrentPickupItem, OrderedCustomer);
CocktailGlassImage.enabled = false;
// InteractionCanvas.BalloonUi.DiscardItem();
CurrentPickupItem = null;
OrderedCustomer = null;
}
// 종업원이 테이블에 칵테일을 놓는 경우
else
{
var serverCrew = (ServerCrew)crew;
CurrentPickupItem = serverCrew.CurrentPickupItem;
CocktailGlassImage.sprite = CurrentPickupItem.Sprite;
CocktailGlassImage.enabled = true;
// InteractionCanvas.BalloonUi.SetItemImage(CurrentPickupItem);
serverCrew.ResetMission();
}
}
public void CancelInteractionCrew()
{
throw new NotImplementedException();
}
public virtual bool CanInteractionCrew(Crew crew = null)
{
var servingCrew = (ServerCrew)crew;
if (!servingCrew)
{
throw new Exception("상호작용 오브젝트 오류");
}
return (servingCrew.CurrentActionType == ActionType.TakeCocktail && CurrentPickupItem != null && OrderedCustomer) ||
servingCrew.CurrentActionType == ActionType.PlaceOnServingTable && CurrentPickupItem == null;
}
private IEnumerator FindCustomerMatchingItem()
{
var waitTime = new WaitForSeconds(2f);
while (true)
{
OrderedCustomer = TycoonManager.Instance.CustomerController.FindCustomerMatchingItem(_currentPickupItem);
if (OrderedCustomer && OrderedCustomer.CanInteractionCrew())
{
var crewController = TycoonManager.Instance.CrewController;
Utils.StartUniqueCoroutine(this, ref _findServerCrewInstance,
crewController.FindClosestCrewCoroutine(CenterTransform.position, crewController.ServerCrews,
crew => crew.OnMission(this, OrderedCustomer, ActionType.TakeCocktail)));
}
yield return waitTime;
}
}
}
}

View File

@ -2,6 +2,7 @@ using DDD.Audios;
using DDD.Interfaces; using DDD.Interfaces;
using DDD.Items; using DDD.Items;
using DDD.Players; using DDD.Players;
using DDD.Utility;
using Sirenix.OdinInspector; using Sirenix.OdinInspector;
using UnityEngine; using UnityEngine;
@ -169,11 +170,11 @@ namespace DDD.Tycoons
{ {
if (_isChanged) if (_isChanged)
{ {
UpdateLocalizedString("InteractionTrashCanChange"); InteractionMessage = Utils.GetLocalizedString("InteractionTrashCanChange");
} }
else else
{ {
UpdateLocalizedString("InteractionTrashCanDiscard"); InteractionMessage = Utils.GetLocalizedString("InteractionTrashCanDiscard");
} }
_spineController.EnableCustomMaterial(); _spineController.EnableCustomMaterial();

View File

@ -172,7 +172,7 @@ namespace DDD.Tycoons
foreach (var element in BartenderCrews) foreach (var element in BartenderCrews)
{ {
if (element.MyBartenderTable.CurrentPickupItem != null || element.IsOnMission) continue; // if (element.MyBartenderTable.CurrentPickupItem != null || element.IsOnMission) continue;
var orderedCocktailIngredients = orderedCocktailData.ValidIngredients; var orderedCocktailIngredients = orderedCocktailData.ValidIngredients;
if (!tycoonIngredientController.IsMakingCocktail(orderedCocktailIngredients)) break; if (!tycoonIngredientController.IsMakingCocktail(orderedCocktailIngredients)) break;

View File

@ -27,11 +27,11 @@ namespace DDD.Tycoons
if (_customerTableRoot) if (_customerTableRoot)
{ {
_customerTables = _customerTableRoot.GetComponentsInChildren<CustomerTable>().ToList(); _customerTables = _customerTableRoot.GetComponentsInChildren<CustomerTable>(false).ToList();
for (var i = 0; i < _customerTables.Count; i++) for (var i = 0; i < _customerTables.Count; i++)
{ {
HideCustomerTable(i); ShowCustomerTable(i);
} }
} }
} }

View File

@ -17,9 +17,9 @@ namespace DDD.Tycoons
//_servingTables = _servingTableRoot.GetComponentsInChildren<ServingTable>().ToList(); //_servingTables = _servingTableRoot.GetComponentsInChildren<ServingTable>().ToList();
} }
public ServingTable FindEmptyServingTable() // public ServingTable FindEmptyServingTable()
{ // {
return _servingTables.FirstOrDefault(element => element.CurrentPickupItem == null); // return _servingTables.FirstOrDefault(element => element.CurrentPickupItem == null);
} // }
} }
} }

View File

@ -8,6 +8,12 @@ namespace DDD.Tycoons
[field: SerializeField] [field: SerializeField]
public float WaitTimeInStarted { get; private set; } = 5f; public float WaitTimeInStarted { get; private set; } = 5f;
[field: SerializeField]
public float CustomerDelay { get; private set; } = 5f;
[field: SerializeField]
public float EatingTime { get; private set; } = 10f;
[field: SerializeField] [field: SerializeField]
public float VomitingPercent { get; private set; } = 10f; public float VomitingPercent { get; private set; } = 10f;

View File

@ -2,6 +2,7 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using DDD.Items; using DDD.Items;
using DDD.Uis.Tycoon;
using DDD.Utility; using DDD.Utility;
using Sirenix.OdinInspector; using Sirenix.OdinInspector;
using UnityEngine; using UnityEngine;
@ -34,6 +35,7 @@ namespace DDD.Tycoons
private bool _isClosedTime; private bool _isClosedTime;
private TycoonManager _tycoonManager; private TycoonManager _tycoonManager;
private MenuBoardUi _menuBoardUi;
private Coroutine _startStageCoroutineInstance; private Coroutine _startStageCoroutineInstance;
private TimeSpan _closedTime; private TimeSpan _closedTime;
@ -41,6 +43,8 @@ namespace DDD.Tycoons
private void Awake() private void Awake()
{ {
_menuBoardUi = FindAnyObjectByType<MenuBoardUi>();
EventManager.OnTycoonGameStarted += StartStage; EventManager.OnTycoonGameStarted += StartStage;
EventManager.OnMakeCocktailCompleted += AddInstanceCocktail; EventManager.OnMakeCocktailCompleted += AddInstanceCocktail;
EventManager.OnCocktailServedToCustomer += RemoveInstanceCocktail; EventManager.OnCocktailServedToCustomer += RemoveInstanceCocktail;
@ -78,13 +82,13 @@ namespace DDD.Tycoons
private IEnumerator StartStageCoroutine() private IEnumerator StartStageCoroutine()
{ {
yield return new WaitForSeconds(StageDataSo.WaitTimeInStarted); yield return new WaitForSeconds(StageDataSo.WaitTimeInStarted);
int orderedCount = _menuBoardUi.GetTodayMenusCount();
while (true) while (orderedCount > 0)
{ {
var currentLevelData = _tycoonManager.GetCurrentLevelData();
EventManager.InvokeCreateCustomer(); EventManager.InvokeCreateCustomer();
orderedCount--;
yield return new WaitForSeconds(currentLevelData.CustomerRespawn); yield return new WaitForSeconds(StageDataSo.CustomerDelay);
} }
} }

View File

@ -1,6 +1,8 @@
using System; using System;
using DDD.Interfaces; using DDD.Interfaces;
using DDD.Items; using DDD.Items;
using DDD.Managers;
using DDD.ScriptableObjects;
using DG.Tweening; using DG.Tweening;
using Sirenix.OdinInspector; using Sirenix.OdinInspector;
using UnityEngine; using UnityEngine;
@ -47,6 +49,7 @@ namespace DDD.Uis
private bool _isItemReceived; private bool _isItemReceived;
public CocktailData OrderCocktailData { get; private set; } public CocktailData OrderCocktailData { get; private set; }
public CraftRecipeData OrderedCraftRecipeData { get; private set; }
private Tween _fillTween; private Tween _fillTween;
private Color _previousColor; private Color _previousColor;
@ -82,6 +85,12 @@ namespace DDD.Uis
SetItemSprite(item.Sprite); SetItemSprite(item.Sprite);
ShowUi(); ShowUi();
} }
public void SetItemImage(Sprite sprite)
{
SetItemSprite(sprite);
ShowUi();
}
private void ResetUi() private void ResetUi()
{ {
@ -108,13 +117,27 @@ namespace DDD.Uis
ResetUi(); ResetUi();
} }
public void OrderItem(string itemIdx, float waitTime, float hurryTime, bool isReverse = false) public void OrderCook(CraftRecipeData orderedCraftRecipeData, float waitTime, float hurryTime, bool isReverse = false)
{ {
//OrderCocktailData = ItemManager.Instance.CocktailDataSo.GetDataByIdx(itemIdx); OrderedCraftRecipeData = orderedCraftRecipeData;
_isOrdered = true; _isOrdered = true;
_isWaitTimeOver = false; _isWaitTimeOver = false;
_isItemReceived = false; _isItemReceived = false;
SetItemImage(OrderCocktailData); SetItemImage(OrderedCraftRecipeData.Sprite);
_fillImage.fillAmount = 1f;
UpdateFillColor(_fillImage.fillAmount);
// SetTween(waitTime, hurryTime, isReverse);
}
public void OrderItem(string itemIdx, float waitTime, float hurryTime, bool isReverse = false)
{
//OrderCocktailData
_isOrdered = true;
_isWaitTimeOver = false;
_isItemReceived = false;
//SetItemSprite(itemIdx);
ShowUi();
SetTween(waitTime, hurryTime, isReverse); SetTween(waitTime, hurryTime, isReverse);
} }
@ -132,12 +155,13 @@ namespace DDD.Uis
public void OrderItem(float waitTime, float hurryTime, bool isReverse = false) public void OrderItem(float waitTime, float hurryTime, bool isReverse = false)
{ {
_fillImage.fillAmount = 1f;
_isOrdered = true; _isOrdered = true;
_isWaitTimeOver = false; _isWaitTimeOver = false;
_isItemReceived = false; _isItemReceived = false;
ShowUi(); ShowUi();
//SetTween(waitTime, hurryTime, isReverse);
SetTween(waitTime, hurryTime, isReverse);
} }
public void SetTween(float waitTime, float hurryTime, bool isReverse = false) public void SetTween(float waitTime, float hurryTime, bool isReverse = false)
@ -182,7 +206,7 @@ namespace DDD.Uis
public bool IsWaitServing() => !_isItemReceived && _isOrdered && !_isWaitTimeOver; public bool IsWaitServing() => !_isItemReceived && _isOrdered && !_isWaitTimeOver;
public bool IsFoodReceive() => _isItemReceived; public bool IsFoodReceive() => _isItemReceived;
public void ReceiveItem(IPickup pickupItem) public void ReceiveItem()
{ {
HideUi(); HideUi();
SetEmpty(); SetEmpty();

View File

@ -82,7 +82,7 @@ namespace DDD
_maxDistance = Vector3.Distance(_rect.anchoredPosition, billInfoPosition0); _maxDistance = Vector3.Distance(_rect.anchoredPosition, billInfoPosition0);
_slider.value = 1f; _slider.value = 1f;
_slider.gameObject.SetActive(true); _slider.gameObject.SetActive(true);
_orderImage.sprite = customer.OrderedCocktailData.Sprite; _orderImage.sprite = customer.OrderedCraftRecipeData.Sprite;
_orderImage.gameObject.SetActive(true); _orderImage.gameObject.SetActive(true);
_makingCocktailPivotObject.SetActive(false); _makingCocktailPivotObject.SetActive(false);
_checkImageObject.SetActive(false); _checkImageObject.SetActive(false);
@ -90,7 +90,7 @@ namespace DDD
_tableNumberText.text = customer.CurrentTableSeat.TableNumber.ToString(); _tableNumberText.text = customer.CurrentTableSeat.TableNumber.ToString();
_tableNumberImageObject.SetActive(true); _tableNumberImageObject.SetActive(true);
SetTween(customer.CurrentLevelData.WaitTime, customer.HurryTime); // SetTween(customer.CurrentLevelData.WaitTime, customer.HurryTime);
} }
public void SetTween(int waitTime, int hurryTime) public void SetTween(int waitTime, int hurryTime)

View File

@ -48,6 +48,9 @@ namespace DDD.Uis
_customerBills.ItemRemoved += UpdateBillInfo; _customerBills.ItemRemoved += UpdateBillInfo;
EventManager.OnOrderedCocktail += OrderedCocktail; EventManager.OnOrderedCocktail += OrderedCocktail;
EventManager.OnOrderResult += OrderResult; EventManager.OnOrderResult += OrderResult;
EventManager.OnOrderedCook += OrderedCook;
EventManager.OnServedResult += OrderResult;
} }
private void OnDestroy() private void OnDestroy()
@ -56,6 +59,9 @@ namespace DDD.Uis
_customerBills.ItemRemoved -= UpdateBillInfo; _customerBills.ItemRemoved -= UpdateBillInfo;
EventManager.OnOrderedCocktail -= OrderedCocktail; EventManager.OnOrderedCocktail -= OrderedCocktail;
EventManager.OnOrderResult -= OrderResult; EventManager.OnOrderResult -= OrderResult;
EventManager.OnOrderedCook -= OrderedCook;
EventManager.OnServedResult -= OrderResult;
} }
private void OrderedCocktail(Customer customer) private void OrderedCocktail(Customer customer)
@ -67,6 +73,16 @@ namespace DDD.Uis
instance.Initialize(customer, _spawnPosition, _billInfos[0].Position, () => _customerBills.Remove(newKeyValuePair)); instance.Initialize(customer, _spawnPosition, _billInfos[0].Position, () => _customerBills.Remove(newKeyValuePair));
customer.SetCurrentBill(instance); customer.SetCurrentBill(instance);
} }
private void OrderedCook(Customer customer)
{
var instance = Instantiate(_billPrefab, _spawnLocation);
var newKeyValuePair = new KeyValuePair<Customer, Bill>(customer, instance);
_customerBills.Add(newKeyValuePair);
instance.Initialize(customer, _spawnPosition, _billInfos[0].Position, () => _customerBills.Remove(newKeyValuePair));
customer.SetCurrentBill(instance);
}
private void OrderResult(Customer customer, bool isCorrected) private void OrderResult(Customer customer, bool isCorrected)
{ {

View File

@ -112,10 +112,10 @@ namespace DDD.Uis
AudioManager.Instance.PlayBgm(_dailyBgm); AudioManager.Instance.PlayBgm(_dailyBgm);
} }
if (!ES3.Load(SaveData.TutorialA, false)) // if (!ES3.Load(SaveData.TutorialA, false))
{ // {
Invoke(nameof(InvokeTutorialA), 1f); // Invoke(nameof(InvokeTutorialA), 1f);
} // }
}); });
}); });
}); });

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8f1a3dacb5e0a8948a7c8753fb197253
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 712e72dfac34cb544ab0a4b2ee5adb47
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 74b25efeacf2e3848aa1b38d2ca181f1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,38 @@
using System;
using BehaviorDesigner.Runtime.Tasks;
using DDD.Npcs.Customers;
using UnityEngine;
using Action = BehaviorDesigner.Runtime.Tasks.Action;
namespace DDD.BehaviorTrees.Actions
{
[TaskCategory("Custom/Npc/Customer")]
[Serializable]
public class EatCook : Action
{
private Customer _customer;
private float _elapsedTime;
public override void OnAwake()
{
_customer = GetComponent<Customer>();
}
public override void OnStart()
{
_elapsedTime = 0;
}
public override TaskStatus OnUpdate()
{
if (_elapsedTime <= _customer.CurrentLevelData.EatingTime)
{
_elapsedTime += Time.deltaTime;
return TaskStatus.Running;
}
_customer.FinishFood();
return TaskStatus.Success;
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 27e3b22e25bcbe247b86ff05d1d29a4d

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e60a123943f8cc44c87c627d6a44f534
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,32 @@
using System;
using BehaviorDesigner.Runtime.Tasks;
using DDD.Npcs.Customers;
namespace DDD.BehaviorTrees.Actions
{
[TaskCategory("Custom/Npc/Customer")]
[Serializable]
public class OrderCook : Conditional
{
private Customer _customer;
public override void OnAwake()
{
_customer = GetComponent<Customer>();
}
public override void OnStart()
{
_customer.OrderCook();
}
public override TaskStatus OnUpdate()
{
if (!_customer.IsReceivedItem) return TaskStatus.Running;
_customer.UnregisterPlayerInteraction();
return TaskStatus.Success;
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 1ad0550de46d2ae4496d3411913ea34c

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ea9d737d86859d040908dc9c73174024
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 26bfedb32002cfd4c85c4af23a8d5214
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -63,8 +63,8 @@ namespace DDD.Tycoons
public void Show() public void Show()
{ {
_collider.enabled = true; //_collider.enabled = true;
_carpetRenderer.sprite = _carpetOnSprite; //_carpetRenderer.sprite = _carpetOnSprite;
_visualLookObject.SetActive(true); _visualLookObject.SetActive(true);
foreach (var element in TableSeats) foreach (var element in TableSeats)
@ -78,8 +78,8 @@ namespace DDD.Tycoons
public void Hide() public void Hide()
{ {
_collider.enabled = false; //_collider.enabled = false;
_carpetRenderer.sprite = _carpetOffSprite; //_carpetRenderer.sprite = _carpetOffSprite;
_visualLookObject.SetActive(false); _visualLookObject.SetActive(false);
} }
} }

View File

@ -0,0 +1,91 @@
using System;
using System.Collections;
using System.Threading.Tasks;
using DDD.ScriptableObjects;
using Sirenix.OdinInspector;
using UnityEngine;
namespace DDD.Tycoons
{
[Serializable]
public class Frying : InteractionFurniture
{
[SerializeField]
private AnimationController _animationController;
[Title("연출")]
[SerializeField]
private Color _enableColor = Color.white;
[SerializeField]
private Color _disableColor = Color.gray;
private Material _instanceMaterial;
private CraftingTool _craftingTool = CraftingTool.Frying;
private const string IsEnabledHash = "isEnabled";
protected override void Start()
{
base.Start();
HoldingAction = SuccessHoldingAction;
_instanceMaterial = VisualLook.material;
VisualLook.material = Instantiate(_instanceMaterial);
EventManager.OnChangedCraftingTool += ChangeColor;
}
protected override void OnDestroy()
{
base.OnDestroy();
EventManager.OnChangedCraftingTool -= ChangeColor;
}
public override void Interaction()
{
base.Interaction();
GameManager.Instance.CurrentTycoonPlayer.IsCookingFried = true;
//_animationController.SetAnimationParameter(IsEnabledHash, true);
}
public override void CancelInteraction()
{
base.CancelInteraction();
GameManager.Instance.CurrentTycoonPlayer.IsCookingFried = false;
//_animationController.SetAnimationParameter(IsEnabledHash, false);
}
public override bool CanInteraction()
{
CraftRecipeData playerCraftRecipeData = CurrentTycoonPlayer.TycoonPickupHandler.CurrentCraftRecipeData;
if (playerCraftRecipeData == null || playerCraftRecipeData.CraftingToolQueue.Count <= 0) return false;
CraftingTool playerCraftingTool = playerCraftRecipeData.CraftingToolQueue.Peek();
return IsOpened && playerCraftingTool == _craftingTool;
}
private void SuccessHoldingAction()
{
CurrentTycoonPlayer.TycoonPickupHandler.InteractionCraftingTool();
CancelInteraction();
}
private async void ChangeColor(CraftingTool? playerCraftingTool)
{
await Task.Delay(100);
if (playerCraftingTool == null)
{
VisualLook.material.color = _enableColor;
}
else
{
VisualLook.material.color = (CraftingTool)playerCraftingTool == _craftingTool ? _enableColor : _disableColor;
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 79123d5b4a061a4448855b69ca24e1c6

View File

@ -1,11 +1,9 @@
using System; using System;
using System.Collections;
using DDD.Interfaces; using DDD.Interfaces;
using DDD.Players.Tycoons; using DDD.Players.Tycoons;
using DDD.Uis; using DDD.Uis;
using Sirenix.OdinInspector; using Sirenix.OdinInspector;
using UnityEngine; using UnityEngine;
using UnityEngine.Localization.Components;
namespace DDD.Tycoons namespace DDD.Tycoons
{ {
@ -24,9 +22,6 @@ namespace DDD.Tycoons
[field: SerializeField, BoxGroup("컴포넌트")] [field: SerializeField, BoxGroup("컴포넌트")]
public Material OutlineMaterial { get; private set; } public Material OutlineMaterial { get; private set; }
[field: SerializeField, BoxGroup("컴포넌트")]
public LocalizeStringEvent LocalizeStringEvent { get; protected set; }
[BoxGroup("변수")] [BoxGroup("변수")]
[field: SerializeField, BoxGroup("변수")] [field: SerializeField, BoxGroup("변수")]
public bool EnableInteraction { get; private set; } = true; public bool EnableInteraction { get; private set; } = true;
@ -37,6 +32,13 @@ namespace DDD.Tycoons
[field: SerializeField, BoxGroup("변수")] [field: SerializeField, BoxGroup("변수")]
public string InteractionMessage { get; set; } public string InteractionMessage { get; set; }
[BoxGroup("상호작용")]
[field: SerializeField, BoxGroup("상호작용")]
public bool EnableHoldingInteraction;
[field: SerializeField, BoxGroup("상호작용")]
public float PlayerHoldingTime = 1f;
[Title("실시간 데이터")] [Title("실시간 데이터")]
[SerializeField] [SerializeField]
protected bool IsOpened; protected bool IsOpened;
@ -45,7 +47,9 @@ namespace DDD.Tycoons
protected Material OriginalMaterial; protected Material OriginalMaterial;
protected bool IsQuitting; protected bool IsQuitting;
protected bool IsShowing; protected bool IsShowing;
protected bool IsPlayerInteracting;
protected float HoldingElapsedTime; protected float HoldingElapsedTime;
protected Action HoldingAction;
private void OnDrawGizmosSelected() private void OnDrawGizmosSelected()
{ {
@ -77,7 +81,36 @@ namespace DDD.Tycoons
{ {
} }
protected void FixedUpdate()
{
if (!EnableHoldingInteraction) return;
if (IsShowing)
{
EventManager.InvokeHoldInteracting(HoldingElapsedTime);
}
if (HoldingElapsedTime > PlayerHoldingTime)
{
HoldingElapsedTime -= PlayerHoldingTime;
HoldingAction?.Invoke();
}
float playerHoldingDeltaTime = Time.deltaTime / PlayerHoldingTime;
if (IsPlayerInteracting)
{
HoldingElapsedTime += playerHoldingDeltaTime;
}
else
{
if (HoldingElapsedTime > 0f)
{
HoldingElapsedTime -= playerHoldingDeltaTime;
}
}
}
protected virtual void OnDisable() protected virtual void OnDisable()
{ {
if (IsQuitting) return; if (IsQuitting) return;
@ -108,20 +141,28 @@ namespace DDD.Tycoons
VisualLook = transform.Find("VisualLook").GetComponent<SpriteRenderer>(); VisualLook = transform.Find("VisualLook").GetComponent<SpriteRenderer>();
InteractionCanvas = transform.Find("InteractionCanvas").GetComponent<InteractionCanvas>(); InteractionCanvas = transform.Find("InteractionCanvas").GetComponent<InteractionCanvas>();
LocalizeStringEvent = transform.GetComponent<LocalizeStringEvent>();
CurrentTycoonPlayer = GameManager.Instance.CurrentTycoonPlayer; CurrentTycoonPlayer = GameManager.Instance.CurrentTycoonPlayer;
} }
public abstract void Interaction(); public virtual void Interaction()
{
IsPlayerInteracting = true;
}
public virtual void CancelInteraction() { } public virtual void CancelInteraction()
{
IsPlayerInteracting = false;
}
public virtual bool CanInteraction() => true; public virtual bool CanInteraction() => true;
public virtual void ShowInteractionUi() public virtual void ShowInteractionUi()
{ {
VisualLook.material = OutlineMaterial; if (OutlineMaterial)
{
VisualLook.material = OutlineMaterial;
}
EventManager.InvokeShowInteractionUi(InteractionMessage); EventManager.InvokeShowInteractionUi(InteractionMessage);
EventManager.InvokeHoldInteracting(HoldingElapsedTime); EventManager.InvokeHoldInteracting(HoldingElapsedTime);
IsShowing = true; IsShowing = true;
@ -129,7 +170,7 @@ namespace DDD.Tycoons
public virtual void HideInteractionUi() public virtual void HideInteractionUi()
{ {
if (VisualLook) if (OutlineMaterial && VisualLook)
{ {
VisualLook.material = OriginalMaterial; VisualLook.material = OriginalMaterial;
} }
@ -162,30 +203,5 @@ namespace DDD.Tycoons
{ {
IsOpened = false; IsOpened = false;
} }
protected void UpdateLocalizedString(string entryName)
{
if (!LocalizeStringEvent) return;
LocalizeStringEvent.StringReference.TableReference = "StringDataTable";
LocalizeStringEvent.StringReference.TableEntryReference = entryName;
StartCoroutine(LoadLocalizedString());
}
protected IEnumerator LoadLocalizedString()
{
var getLocalizedStringOperation = LocalizeStringEvent.StringReference.GetLocalizedStringAsync();
yield return getLocalizedStringOperation;
if (getLocalizedStringOperation.IsDone)
{
InteractionMessage = getLocalizedStringOperation.Result;
}
else
{
Debug.LogError("Failed to load localized string.");
}
}
} }
} }

View File

@ -17,6 +17,8 @@ namespace DDD.Tycoons
public override void Interaction() public override void Interaction()
{ {
base.Interaction();
_menuBoardUi.Open(); _menuBoardUi.Open();
} }

View File

@ -0,0 +1,89 @@
using System;
using System.Threading.Tasks;
using DDD.ScriptableObjects;
using Sirenix.OdinInspector;
using UnityEngine;
namespace DDD.Tycoons
{
[Serializable]
public class Pot : InteractionFurniture
{
[SerializeField]
private AnimationController _animationController;
[Title("연출")]
[SerializeField]
private Color _enableColor = Color.white;
[SerializeField]
private Color _disableColor = Color.gray;
private Material _instanceMaterial;
private CraftingTool _craftingTool = CraftingTool.Pot;
private const string IsEnabledHash = "isEnabled";
protected override void Start()
{
base.Start();
HoldingAction = SuccessHoldingAction;
_instanceMaterial = VisualLook.material;
VisualLook.material = Instantiate(_instanceMaterial);
EventManager.OnChangedCraftingTool += ChangeColor;
}
protected override void OnDestroy()
{
base.OnDestroy();
EventManager.OnChangedCraftingTool -= ChangeColor;
}
public override void Interaction()
{
base.Interaction();
GameManager.Instance.CurrentTycoonPlayer.IsCookingStew = true;
_animationController.SetAnimationParameter(IsEnabledHash, true);
}
public override void CancelInteraction()
{
base.CancelInteraction();
GameManager.Instance.CurrentTycoonPlayer.IsCookingStew = false;
_animationController.SetAnimationParameter(IsEnabledHash, false);
}
public override bool CanInteraction()
{
CraftRecipeData playerCraftRecipeData = CurrentTycoonPlayer.TycoonPickupHandler.CurrentCraftRecipeData;
if (playerCraftRecipeData == null || playerCraftRecipeData.CraftingToolQueue.Count <= 0) return false;
CraftingTool playerCraftingTool = playerCraftRecipeData.CraftingToolQueue.Peek();
return IsOpened && playerCraftingTool == _craftingTool;
}
private void SuccessHoldingAction()
{
CurrentTycoonPlayer.TycoonPickupHandler.InteractionCraftingTool();
CancelInteraction();
}
private async void ChangeColor(CraftingTool? playerCraftingTool)
{
await Task.Delay(100);
if (playerCraftingTool == null)
{
VisualLook.material.color = _enableColor;
}
else
{
VisualLook.material.color = (CraftingTool)playerCraftingTool == _craftingTool ? _enableColor : _disableColor;
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 31db3e16bd7611d46899027f48aa0349

View File

@ -0,0 +1,25 @@
using System;
using DDD.Uis.Tycoon;
using UnityEngine;
namespace DDD.Tycoons
{
[Serializable]
public class Refrigerator : InteractionFurniture
{
[SerializeField]
private MealKitUi _mealKitUi;
public override void Interaction()
{
base.Interaction();
_mealKitUi.Open();
}
public override bool CanInteraction()
{
return IsOpened && _mealKitUi.CanOpen() && !CurrentTycoonPlayer.TycoonPickupHandler.IsPickedUpCook;
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 699ff6e4c09966148b659b8a1595c0e4

View File

@ -0,0 +1,11 @@
using System.Collections.Generic;
using UnityEngine;
namespace DDD.Tycoons
{
public class ServingTable : MonoBehaviour
{
[field: SerializeField]
public List<ServingTableSeat> ServingTableSeats { get; private set; } = new(2);
}
}

View File

@ -0,0 +1,93 @@
using System.Collections.Generic;
using DDD.Audios;
using DDD.ScriptableObjects;
using DDD.Utility;
using UnityEngine;
namespace DDD.Tycoons
{
public class ServingTableSeat : InteractionFurniture
{
[SerializeField]
private List<SpriteRenderer> _outlineRenderers = new();
[SerializeField]
private string _putDownSfxName = "PutDownCocktail";
public CraftRecipeData CurrentCraftRecipeData { get; private set; }
private List<Material> _originalMaterials;
protected override void Awake()
{
base.Awake();
VisualLook.sprite = null;
VisualLook.enabled = false;
_originalMaterials = new List<Material>(_outlineRenderers.Count);
for (int i = 0; i < _outlineRenderers.Count; i++)
{
_originalMaterials.Add(_outlineRenderers[i].material);
}
}
public override void Interaction()
{
// 테이블의 칵테일을 가져가는 경우
if (CurrentCraftRecipeData != null)
{
CurrentTycoonPlayer.PickupCook(CurrentCraftRecipeData);
VisualLook.sprite = null;
VisualLook.enabled = false;
CurrentCraftRecipeData = null;
}
// 테이블에 칵테일을 놓는 경우
else
{
AudioManager.Instance.PlaySfx(_putDownSfxName);
CurrentCraftRecipeData = CurrentTycoonPlayer.TycoonPickupHandler.CurrentCraftRecipeData;
VisualLook.sprite = CurrentCraftRecipeData.Sprite;
VisualLook.enabled = true;
CurrentTycoonPlayer.ServedCook();
}
}
public override bool CanInteraction()
{
// 1. 테이블에 음식이 있고, 플레이어가 음식을 들고 있지 않은 경우
// 2. 테이블에 음식이 없고, 플레이어가 음식을 들고 있는 경우
return (CurrentCraftRecipeData != null && !CurrentTycoonPlayer.TycoonPickupHandler.IsPickedUpCook) ||
(CurrentCraftRecipeData == null && CurrentTycoonPlayer.TycoonPickupHandler.IsPickedUpCook);
}
public override void ShowInteractionUi()
{
if (CurrentCraftRecipeData != null)
{
InteractionMessage = Utils.GetLocalizedString("InteractionServingTablePickUp");
}
else
{
InteractionMessage = Utils.GetLocalizedString("InteractionServingTablePutDown");
}
base.ShowInteractionUi();
for (int i = 0; i < _outlineRenderers.Count; i++)
{
_outlineRenderers[i].material = OutlineMaterial;
}
}
public override void HideInteractionUi()
{
base.HideInteractionUi();
for (int i = 0; i < _outlineRenderers.Count; i++)
{
_outlineRenderers[i].material = _originalMaterials[i];
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d627e8f515556f74eb5297b0bec9819c

View File

@ -3,6 +3,7 @@ using DDD.Audios;
using DDD.Interfaces; using DDD.Interfaces;
using DDD.Npcs.Crews; using DDD.Npcs.Crews;
using DDD.Npcs.Crews.Cleaner; using DDD.Npcs.Crews.Cleaner;
using DDD.ScriptableObjects;
using DDD.Uis; using DDD.Uis;
using DDD.Utility; using DDD.Utility;
using Sirenix.OdinInspector; using Sirenix.OdinInspector;
@ -222,9 +223,9 @@ namespace DDD.Tycoons
InteractionCanvas.BalloonUi.OrderItem(0, TycoonManager.Instance.TycoonStageController.StageDataSo.DirtyTableWaitTime); InteractionCanvas.BalloonUi.OrderItem(0, TycoonManager.Instance.TycoonStageController.StageDataSo.DirtyTableWaitTime);
IsCleaned = false; IsCleaned = false;
var crewController = TycoonManager.Instance.CrewController; // var crewController = TycoonManager.Instance.CrewController;
Utils.StartUniqueCoroutine(this, ref _findCleanerCrewInstance, // Utils.StartUniqueCoroutine(this, ref _findCleanerCrewInstance,
crewController.FindClosestCrewCoroutine(CenterTransform.position, crewController.CleanerCrews, crew => crew.OnMission(this))); // crewController.FindClosestCrewCoroutine(CenterTransform.position, crewController.CleanerCrews, crew => crew.OnMission(this)));
} }
public void Purify() public void Purify()
@ -263,6 +264,12 @@ namespace DDD.Tycoons
CleanTable(); CleanTable();
} }
public void OrderCook(CraftRecipeData orderedCraftRecipeData, float waitTime = float.PositiveInfinity, float hurryTime = float.PositiveInfinity, bool isReverse = false)
{
MenuBalloonUi.OrderCook(orderedCraftRecipeData, waitTime, hurryTime, isReverse);
ChangeMenuColor(GameManager.Instance.CurrentTycoonPlayer.TycoonPickupHandler.CurrentCraftRecipeData?.Idx);
}
public void OrderCocktail(string itemIdx, float waitTime, float hurryTime, bool isReverse = false) public void OrderCocktail(string itemIdx, float waitTime, float hurryTime, bool isReverse = false)
{ {
@ -274,7 +281,7 @@ namespace DDD.Tycoons
{ {
if (MenuBalloonUi.gameObject.activeInHierarchy) if (MenuBalloonUi.gameObject.activeInHierarchy)
{ {
if (idx == null || (MenuBalloonUi.IsWaitServing() && MenuBalloonUi.OrderCocktailData?.Idx == idx)) if (idx == null || (MenuBalloonUi.IsWaitServing() && MenuBalloonUi.OrderedCraftRecipeData?.Idx == idx))
{ {
ChangeMenuOriginalColor(); ChangeMenuOriginalColor();
} }

View File

@ -0,0 +1,30 @@
using System;
using DDD.Uis.Tycoon;
namespace DDD.Tycoons
{
[Serializable]
public class TycoonSwitch : InteractionFurniture
{
private MenuBoardUi _menuBoardUi;
protected override void Awake()
{
base.Awake();
_menuBoardUi = FindAnyObjectByType<MenuBoardUi>();
}
public override void Interaction()
{
base.Interaction();
EventManager.InvokeTycoonGameStarted();
}
public override bool CanInteraction()
{
return !IsOpened && _menuBoardUi.CanOpen();
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 9bf1e24eedd5ff848967d5e84b77e145

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using DDD.Interfaces; using DDD.Interfaces;
using DDD.Uis.Tycoon; using DDD.Uis.Tycoon;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -68,6 +69,10 @@ namespace DDD.ScriptableObjects
[field: SerializeField, Tooltip("제작 순서"), BoxGroup("Json 데이터 영역")] [field: SerializeField, Tooltip("제작 순서"), BoxGroup("Json 데이터 영역")]
public int CraftOrder { get; set; } public int CraftOrder { get; set; }
[JsonProperty]
[field: SerializeField, Tooltip("해시 태그"), BoxGroup("Json 데이터 영역")]
public string HashTag { get; set; }
[BoxGroup("직접 추가하는 영역")] [BoxGroup("직접 추가하는 영역")]
[JsonIgnore] [JsonIgnore]
[field: SerializeField, BoxGroup("직접 추가하는 영역")] [field: SerializeField, BoxGroup("직접 추가하는 영역")]
@ -75,12 +80,36 @@ namespace DDD.ScriptableObjects
[JsonIgnore] [JsonIgnore]
[field: SerializeField] [field: SerializeField]
public List<CraftingIngredient> ValidIngredients { get; set; } = new(3); public List<CraftingIngredient> ValidIngredients { get; set; }
[JsonIgnore] [JsonIgnore]
[field: ShowInInspector] [field: ShowInInspector]
public Queue<CraftingTool> CraftingToolQueue { get; set; } = new(4); public Queue<CraftingTool> CraftingToolQueue { get; set; }
[JsonIgnore]
[field: SerializeField]
public List<string> ValidHashTags { get; set; }
public CraftRecipeData(CraftRecipeData copy)
{
Idx = copy.Idx;
Name = copy.Name;
Description = copy.Description;
Price = copy.Price;
IngredientIdx1 = copy.IngredientIdx1;
IngredientCount1 = copy.IngredientCount1;
IngredientIdx2 = copy.IngredientIdx2;
IngredientCount2 = copy.IngredientCount2;
IngredientIdx3 = copy.IngredientIdx3;
IngredientCount3 = copy.IngredientCount3;
CraftOrder = copy.CraftOrder;
HashTag = copy.HashTag;
Sprite = copy.Sprite;
ValidIngredients = new List<CraftingIngredient>(copy.ValidIngredients);
CraftingToolQueue = new Queue<CraftingTool>(copy.CraftingToolQueue);
ValidHashTags = new List<string>(copy.ValidHashTags);
}
public List<CraftingIngredient> GetValidIngredients() public List<CraftingIngredient> GetValidIngredients()
{ {
List<CraftingIngredient> newList = new List<CraftingIngredient>(); List<CraftingIngredient> newList = new List<CraftingIngredient>();
@ -119,5 +148,14 @@ namespace DDD.ScriptableObjects
} }
return newQueue; return newQueue;
} }
public List<string> GetValidHashTags()
{
List<string> newList = new List<string>(3);
newList = HashTag.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
return newList;
}
} }
} }

View File

@ -13,6 +13,7 @@ namespace DDD.ScriptableObjects
{ {
element.ValidIngredients = element.GetValidIngredients(); element.ValidIngredients = element.GetValidIngredients();
element.CraftingToolQueue = element.GetCraftingToolQueue(); element.CraftingToolQueue = element.GetCraftingToolQueue();
element.ValidHashTags = element.GetValidHashTags();
} }
} }
} }

View File

@ -26,10 +26,14 @@ MonoBehaviour:
<IngredientIdx3>k__BackingField: <IngredientIdx3>k__BackingField:
<IngredientCount3>k__BackingField: 0 <IngredientCount3>k__BackingField: 0
<CraftOrder>k__BackingField: 12 <CraftOrder>k__BackingField: 12
<HashTag>k__BackingField: HashTag001, HashTag002
<Sprite>k__BackingField: {fileID: 0} <Sprite>k__BackingField: {fileID: 0}
<ValidIngredients>k__BackingField: <ValidIngredients>k__BackingField:
- <Idx>k__BackingField: Ingredient001 - <Idx>k__BackingField: Ingredient001
<Count>k__BackingField: 1 <Count>k__BackingField: 1
<ValidHashTags>k__BackingField:
- HashTag001
- HashTag002
- <Key>k__BackingField: CraftRecipe002 - <Key>k__BackingField: CraftRecipe002
<Value>k__BackingField: <Value>k__BackingField:
<Idx>k__BackingField: CraftRecipe002 <Idx>k__BackingField: CraftRecipe002
@ -43,12 +47,17 @@ MonoBehaviour:
<IngredientIdx3>k__BackingField: <IngredientIdx3>k__BackingField:
<IngredientCount3>k__BackingField: 0 <IngredientCount3>k__BackingField: 0
<CraftOrder>k__BackingField: 3 <CraftOrder>k__BackingField: 3
<Sprite>k__BackingField: {fileID: 0} <HashTag>k__BackingField: HashTag003, HashTag004, HashTag005
<Sprite>k__BackingField: {fileID: 21300000, guid: 471f30d31984bb64d929cf9cd729f5f3, type: 3}
<ValidIngredients>k__BackingField: <ValidIngredients>k__BackingField:
- <Idx>k__BackingField: Ingredient002 - <Idx>k__BackingField: Ingredient002
<Count>k__BackingField: 1 <Count>k__BackingField: 1
- <Idx>k__BackingField: Ingredient004 - <Idx>k__BackingField: Ingredient004
<Count>k__BackingField: 2 <Count>k__BackingField: 2
<ValidHashTags>k__BackingField:
- HashTag003
- HashTag004
- HashTag005
- <Key>k__BackingField: CraftRecipe003 - <Key>k__BackingField: CraftRecipe003
<Value>k__BackingField: <Value>k__BackingField:
<Idx>k__BackingField: CraftRecipe003 <Idx>k__BackingField: CraftRecipe003
@ -62,6 +71,7 @@ MonoBehaviour:
<IngredientIdx3>k__BackingField: Ingredient001 <IngredientIdx3>k__BackingField: Ingredient001
<IngredientCount3>k__BackingField: 1 <IngredientCount3>k__BackingField: 1
<CraftOrder>k__BackingField: 34 <CraftOrder>k__BackingField: 34
<HashTag>k__BackingField: HashTag006, HashTag007
<Sprite>k__BackingField: {fileID: 0} <Sprite>k__BackingField: {fileID: 0}
<ValidIngredients>k__BackingField: <ValidIngredients>k__BackingField:
- <Idx>k__BackingField: Ingredient003 - <Idx>k__BackingField: Ingredient003
@ -70,6 +80,9 @@ MonoBehaviour:
<Count>k__BackingField: 2 <Count>k__BackingField: 2
- <Idx>k__BackingField: Ingredient001 - <Idx>k__BackingField: Ingredient001
<Count>k__BackingField: 1 <Count>k__BackingField: 1
<ValidHashTags>k__BackingField:
- HashTag006
- HashTag007
- <Key>k__BackingField: CraftRecipe004 - <Key>k__BackingField: CraftRecipe004
<Value>k__BackingField: <Value>k__BackingField:
<Idx>k__BackingField: CraftRecipe004 <Idx>k__BackingField: CraftRecipe004
@ -82,7 +95,8 @@ MonoBehaviour:
<IngredientCount2>k__BackingField: 2 <IngredientCount2>k__BackingField: 2
<IngredientIdx3>k__BackingField: Ingredient008 <IngredientIdx3>k__BackingField: Ingredient008
<IngredientCount3>k__BackingField: 1 <IngredientCount3>k__BackingField: 1
<CraftOrder>k__BackingField: 34 <CraftOrder>k__BackingField: 32
<HashTag>k__BackingField: HashTag006, HashTag007, HashTag008
<Sprite>k__BackingField: {fileID: 21300000, guid: 12a978bb397d4194a9795a3daf6fad84, type: 3} <Sprite>k__BackingField: {fileID: 21300000, guid: 12a978bb397d4194a9795a3daf6fad84, type: 3}
<ValidIngredients>k__BackingField: <ValidIngredients>k__BackingField:
- <Idx>k__BackingField: Ingredient006 - <Idx>k__BackingField: Ingredient006
@ -91,6 +105,10 @@ MonoBehaviour:
<Count>k__BackingField: 2 <Count>k__BackingField: 2
- <Idx>k__BackingField: Ingredient008 - <Idx>k__BackingField: Ingredient008
<Count>k__BackingField: 1 <Count>k__BackingField: 1
<ValidHashTags>k__BackingField:
- HashTag006
- HashTag007
- HashTag008
- <Key>k__BackingField: CraftRecipe005 - <Key>k__BackingField: CraftRecipe005
<Value>k__BackingField: <Value>k__BackingField:
<Idx>k__BackingField: CraftRecipe005 <Idx>k__BackingField: CraftRecipe005
@ -103,11 +121,15 @@ MonoBehaviour:
<IngredientCount2>k__BackingField: 0 <IngredientCount2>k__BackingField: 0
<IngredientIdx3>k__BackingField: <IngredientIdx3>k__BackingField:
<IngredientCount3>k__BackingField: 0 <IngredientCount3>k__BackingField: 0
<CraftOrder>k__BackingField: 12 <CraftOrder>k__BackingField: 23
<HashTag>k__BackingField: HashTag009, HashTag010
<Sprite>k__BackingField: {fileID: 21300000, guid: 1002a5b83127f3c43a8cfdf2f8567473, type: 3} <Sprite>k__BackingField: {fileID: 21300000, guid: 1002a5b83127f3c43a8cfdf2f8567473, type: 3}
<ValidIngredients>k__BackingField: <ValidIngredients>k__BackingField:
- <Idx>k__BackingField: Ingredient011 - <Idx>k__BackingField: Ingredient011
<Count>k__BackingField: 1 <Count>k__BackingField: 1
<ValidHashTags>k__BackingField:
- HashTag009
- HashTag010
- <Key>k__BackingField: CraftRecipe006 - <Key>k__BackingField: CraftRecipe006
<Value>k__BackingField: <Value>k__BackingField:
<Idx>k__BackingField: CraftRecipe006 <Idx>k__BackingField: CraftRecipe006
@ -121,9 +143,13 @@ MonoBehaviour:
<IngredientIdx3>k__BackingField: <IngredientIdx3>k__BackingField:
<IngredientCount3>k__BackingField: 0 <IngredientCount3>k__BackingField: 0
<CraftOrder>k__BackingField: 3 <CraftOrder>k__BackingField: 3
<HashTag>k__BackingField: HashTag011, HashTag012
<Sprite>k__BackingField: {fileID: 21300000, guid: 1921548edfb697e4c813502ad856e15d, type: 3} <Sprite>k__BackingField: {fileID: 21300000, guid: 1921548edfb697e4c813502ad856e15d, type: 3}
<ValidIngredients>k__BackingField: <ValidIngredients>k__BackingField:
- <Idx>k__BackingField: Ingredient008 - <Idx>k__BackingField: Ingredient008
<Count>k__BackingField: 1 <Count>k__BackingField: 1
- <Idx>k__BackingField: Ingredient0010 - <Idx>k__BackingField: Ingredient010
<Count>k__BackingField: 2 <Count>k__BackingField: 2
<ValidHashTags>k__BackingField:
- HashTag011
- HashTag012

View File

@ -1,16 +0,0 @@
using UnityEngine;
public class MenuIngre : MonoBehaviour
{
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: aa95d22b420ae1d41bd189e9efaf3ac8

View File

@ -209,8 +209,6 @@ namespace DDD.Uis.Tycoon
DataManager.Instance.Inventory.RemoveItem(slot, CraftableCount * ingredient.Count); DataManager.Instance.Inventory.RemoveItem(slot, CraftableCount * ingredient.Count);
} }
EventManager.OnAddedTodayMenu?.Invoke(CurrentCraftRecipeData, CraftableCount);
Close(); Close();
} }
} }

View File

@ -242,7 +242,6 @@ namespace DDD.Uis.Tycoon
public override void Open() public override void Open()
{ {
print("add 오픈");
AddedCount = 1; AddedCount = 1;
if (_currentTodayMenu.IsAddedMenu) if (_currentTodayMenu.IsAddedMenu)
{ {
@ -293,7 +292,6 @@ namespace DDD.Uis.Tycoon
{ {
if (IsAddedMenu) if (IsAddedMenu)
{ {
print("메뉴 등록");
// 메뉴 등록 // 메뉴 등록
if (IsCraftable) if (IsCraftable)
{ {
@ -304,7 +302,6 @@ namespace DDD.Uis.Tycoon
} }
else else
{ {
print("레시피 선택");
// 레시피 선택 // 레시피 선택
_menuButton.onClick.Invoke(); _menuButton.onClick.Invoke();
} }
@ -359,6 +356,19 @@ namespace DDD.Uis.Tycoon
_nameText.text = AddedCraftRecipeData.Name; _nameText.text = AddedCraftRecipeData.Name;
_descriptionText.text = Utils.GetLocalizedString(AddedCraftRecipeData.Description); _descriptionText.text = Utils.GetLocalizedString(AddedCraftRecipeData.Description);
_countText.text = $"{AddedCount}/{_maxCraftingCount}"; _countText.text = $"{AddedCount}/{_maxCraftingCount}";
int validHashTagCount = AddedCraftRecipeData.ValidHashTags.Count;
for (int i = 0; i < _maxHashTagCount; i++)
{
if (i >= validHashTagCount)
{
_menuHashTags[i].HideUi();
continue;
}
_menuHashTags[i].SetTag(AddedCraftRecipeData.ValidHashTags[i]);
_menuHashTags[i].ShowUi();
}
IsAddedMenu = true; IsAddedMenu = true;
} }

View File

@ -33,6 +33,7 @@ namespace DDD.Uis.Tycoon
private AddIngredientUi _addIngredientUi; private AddIngredientUi _addIngredientUi;
[Title("오늘의 메뉴")] [Title("오늘의 메뉴")]
[SerializeField]
private int _maxTodayMenuCount = 6; private int _maxTodayMenuCount = 6;
[Title("실시간 데이터")] [Title("실시간 데이터")]

View File

@ -1,6 +1,5 @@
using DDD.ScriptableObjects; using DDD.ScriptableObjects;
using Sirenix.OdinInspector; using Sirenix.OdinInspector;
using TMPro;
using UnityEngine; using UnityEngine;
using UnityEngine.Events; using UnityEngine.Events;
using UnityEngine.UI; using UnityEngine.UI;
@ -9,9 +8,9 @@ namespace DDD.Uis.Tycoon
{ {
public class CraftRecipeButton : MonoBehaviour public class CraftRecipeButton : MonoBehaviour
{ {
[Title("컴포넌트")] [field: Title("컴포넌트")]
[SerializeField] [field: SerializeField]
private Button _button; public Button Button { get; private set; }
[SerializeField] [SerializeField]
private Image _image; private Image _image;
@ -30,14 +29,14 @@ namespace DDD.Uis.Tycoon
public void RegisterButtonListener(UnityAction clickAction) public void RegisterButtonListener(UnityAction clickAction)
{ {
_clickAction = clickAction; _clickAction = clickAction;
_button.onClick.AddListener(_clickAction); Button.onClick.AddListener(_clickAction);
} }
private void UnregisterButtonListener() private void UnregisterButtonListener()
{ {
if (_clickAction == null) return; if (_clickAction == null) return;
_button.onClick.RemoveListener(_clickAction); Button.onClick.RemoveListener(_clickAction);
_clickAction = null; _clickAction = null;
} }
@ -53,7 +52,7 @@ namespace DDD.Uis.Tycoon
public void OnClicked() public void OnClicked()
{ {
_button.onClick.Invoke(); Button.onClick.Invoke();
} }
private void UpdateIngredients() private void UpdateIngredients()

View File

@ -65,6 +65,8 @@ namespace DDD.Uis.Tycoon
craftRecipeButton.SetCraftRecipeData(craftRecipeData); craftRecipeButton.SetCraftRecipeData(craftRecipeData);
_craftRecipeButtons.Add(craftRecipeButton); _craftRecipeButtons.Add(craftRecipeButton);
} }
SetNavigationCraftRecipeButtons();
_panel.SetActive(false); _panel.SetActive(false);
} }
@ -121,7 +123,6 @@ namespace DDD.Uis.Tycoon
private void OnInteractionE(InputAction.CallbackContext context) private void OnInteractionE(InputAction.CallbackContext context)
{ {
print("레시피 선택 E키");
if (!EventSystem.current) return; if (!EventSystem.current) return;
GameObject currentObject = EventSystem.current.currentSelectedGameObject; GameObject currentObject = EventSystem.current.currentSelectedGameObject;
@ -132,10 +133,54 @@ namespace DDD.Uis.Tycoon
private void OnClickedCraftRecipe(CraftRecipeButton clickedCraftRecipeButton) private void OnClickedCraftRecipe(CraftRecipeButton clickedCraftRecipeButton)
{ {
print("레시피 선택 버튼 클릭");
CurrentCraftRecipeButton = clickedCraftRecipeButton; CurrentCraftRecipeButton = clickedCraftRecipeButton;
Close(); Close();
} }
private void SetNavigationCraftRecipeButtons()
{
int columnCount = 4;
int totalCount = ItemManager.Instance.AcquiredCraftRecipeDatas.Count;
for (int i = 0; i < totalCount; i++)
{
Navigation navigation = _craftRecipeButtons[i].Button.navigation;
navigation.mode = Navigation.Mode.Explicit;
// 상(Up) 버튼 설정
int upIndex = i - columnCount;
if (upIndex >= 0)
{
navigation.selectOnUp = _craftRecipeButtons[upIndex].Button;
}
// 하(Down) 버튼 설정
int downIndex = i + columnCount;
if (downIndex < totalCount)
{
navigation.selectOnDown = _craftRecipeButtons[downIndex].Button;
}
// 좌(Left) 버튼 설정
int leftIndex = i - 1;
// 같은 행(=i/columnCount)이면 연결, 그렇지 않다면 연결 X
if (leftIndex >= 0 && (leftIndex / columnCount) == (i / columnCount))
{
navigation.selectOnLeft = _craftRecipeButtons[leftIndex].Button;
}
// 우(Right) 버튼 설정
int rightIndex = i + 1;
// 같은 행(=i/columnCount)이면 연결, 그렇지 않다면 연결 X
if (rightIndex < totalCount && (rightIndex / columnCount) == (i / columnCount))
{
navigation.selectOnRight = _craftRecipeButtons[rightIndex].Button;
}
// 설정한 내비게이션 정보를 버튼에 반영
_craftRecipeButtons[i].Button.navigation = navigation;
}
}
public void SetSelectRecipeAction(UnityAction selectRecipeAction) => _selectRecipeAction = selectRecipeAction; public void SetSelectRecipeAction(UnityAction selectRecipeAction) => _selectRecipeAction = selectRecipeAction;
} }

View File

@ -0,0 +1,87 @@
using DDD.ScriptableObjects;
using Sirenix.OdinInspector;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
namespace DDD.Uis.Tycoon
{
public class MealKitButton : MonoBehaviour
{
[field: Title("컴포넌트")]
[field: SerializeField]
public Button Button { get; private set; }
[SerializeField]
private Image _image;
[SerializeField]
private TMP_Text _countText;
[Title("연출")]
[SerializeField]
private Color _enableColor = Color.white;
[SerializeField]
private Color _disableColor = Color.gray;
[field: Title("레시피 데이터")]
[field: SerializeField]
public CraftRecipeData CraftRecipeData { get; private set; }
[field: SerializeField]
public int Count { get; private set; }
private UnityAction _clickAction;
private void OnDestroy()
{
UnregisterButtonListener();
}
public void RegisterButtonListener(UnityAction clickAction)
{
_clickAction = clickAction;
Button.onClick.AddListener(_clickAction);
}
private void UnregisterButtonListener()
{
if (_clickAction == null) return;
Button.onClick.RemoveListener(_clickAction);
_clickAction = null;
}
public void SetMealKit(CraftRecipeData craftRecipeData, int count)
{
CraftRecipeData = craftRecipeData;
Count = count;
UpdateUi();
}
private void UpdateUi()
{
Button.interactable = Count > 0;
_image.sprite = CraftRecipeData?.Sprite;
_countText.text = Count.ToString();
Button.targetGraphic.color = Button.interactable ? _enableColor : _disableColor;
_image.color = Button.interactable ? _enableColor : _disableColor;
}
public bool CanInteraction()
{
return CraftRecipeData != null && Count > 0 && Button.interactable;
}
public void PickupMealKit()
{
Count--;
UpdateUi();
}
public void ShowUi() => gameObject.SetActive(true);
public void HideUi() => gameObject.SetActive(false);
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0f9e325c61194864da05f41c9ded8809

View File

@ -0,0 +1,277 @@
using System.Collections.Generic;
using System.Linq;
using DDD.ScriptableObjects;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.UI;
namespace DDD.Uis.Tycoon
{
public class MealKitUi : PopupUi
{
[Title("프리팹")]
[SerializeField]
private MealKitButton _mealKitButtonPrefab;
[Title("컴포넌트")]
[SerializeField]
private GameObject _panel;
[SerializeField]
private GameObject _mealKitsLocation;
[Title("클래스")]
[SerializeField]
private UiEventsController _uiEventsController;
[Title("데이터")]
[SerializeField]
private int _maxMealKitCount = 6;
[Title("실시간 데이터")]
[SerializeField]
private List<MealKitButton> _mealKitButtons;
private InputAction _interactionEAction;
private InputAction _cancelAction;
private InputAction _pressFAction;
private void Awake()
{
// 더미 데이터 삭제
foreach (Transform element in _mealKitsLocation.transform)
{
if (element)
{
Destroy(element.gameObject);
}
}
}
private void Start()
{
EventManager.OnAddedMealKit += SetTodayMenus;
_interactionEAction =
PlayerInputKeyManager.Instance.GetAction(InputActionMaps.TycoonUi, TycoonUiActions.InteractionE);
_cancelAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.TycoonUi, TycoonUiActions.Cancel);
_pressFAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.TycoonUi, TycoonUiActions.PressF);
_mealKitButtons = new List<MealKitButton>(_maxMealKitCount);
for (int i = 0; i < _maxMealKitCount; i++)
{
MealKitButton mealKitButton = Instantiate(_mealKitButtonPrefab, _mealKitsLocation.transform);
mealKitButton.RegisterButtonListener(() => OnClickedMealKit(mealKitButton));
_mealKitButtons.Add(mealKitButton);
}
_panel.SetActive(false);
}
private void OnDestroy()
{
EventManager.OnAddedMealKit -= SetTodayMenus;
}
private void OnClickedMealKit(MealKitButton mealKitButton)
{
if (mealKitButton.CanInteraction())
{
CraftRecipeData newCraftRecipeData = new CraftRecipeData(mealKitButton.CraftRecipeData);
EventManager.InvokePickupMealKit(newCraftRecipeData);
mealKitButton.PickupMealKit();
Close();
}
}
public bool CanOpen()
{
return _mealKitButtons.Any(mealKitButton => mealKitButton.CanInteraction());
}
public override void Open()
{
base.Open();
_panel.SetActive(true);
PlayerInputKeyManager.Instance.SwitchCurrentActionMap(InputActionMaps.TycoonUi);
SortMealKitButtons();
_uiEventsController.SetSelectObject(_mealKitButtons[0].gameObject);
EventSystem.current.SetSelectedGameObject(_uiEventsController.SelectObject);
}
public void OnClose(InputAction.CallbackContext context)
{
Close();
}
public override void Close()
{
_panel.SetActive(false);
base.Close();
if (PopupUiController.IsPopupListEmpty() || !PopupUiController.IsPausedPopupList())
{
PlayerInputKeyManager.Instance.SwitchCurrentActionMap(InputActionMaps.Tycoon);
}
}
public override void EnableInput()
{
_interactionEAction.performed += OnInteractionE;
_cancelAction.performed += OnClose;
_pressFAction.performed += OnClose;
_uiEventsController.EnableAutoNavigate();
}
public override void DisableInput()
{
_interactionEAction.performed -= OnInteractionE;
_cancelAction.performed -= OnClose;
_pressFAction.performed -= OnClose;
_uiEventsController.DisableAutoNavigate();
}
private void OnInteractionE(InputAction.CallbackContext context)
{
if (!EventSystem.current) return;
EventSystem.current.currentSelectedGameObject.GetComponent<Button>()?.onClick.Invoke();
}
private void SetTodayMenus(List<TodayMenu> todayMenus)
{
for (int i = 0; i < _maxMealKitCount; i++)
{
_mealKitButtons[i].SetMealKit(todayMenus[i].AddedCraftRecipeData, todayMenus[i].AddedCount);
if (todayMenus[i].AddedCraftRecipeData == null)
{
_mealKitButtons[i].HideUi();
}
else
{
_mealKitButtons[i].ShowUi();
}
}
}
private void SortMealKitButtons()
{
// 1) 임시 리스트에 인터랙션 가능한 버튼만 먼저 담는다(Stable).
List<MealKitButton> sortedList = new List<MealKitButton>(_mealKitButtons.Count);
foreach (var mealKitButton in _mealKitButtons)
{
if (mealKitButton.CanInteraction())
{
sortedList.Add(mealKitButton);
}
}
// 2) 그 다음 인터랙션 불가능한 버튼들을 뒤에 붙인다.
foreach (var mealKitButton in _mealKitButtons)
{
if (!mealKitButton.CanInteraction())
{
sortedList.Add(mealKitButton);
}
}
// 3) 재배치한 리스트를 원본 리스트에 반영
_mealKitButtons = sortedList;
// 4) 실제 UI 계층(트랜스폼) 순서도 변경하여 GridLayoutGroup이 의도한 순서로 그리도록 설정
for (int i = 0; i < _mealKitButtons.Count; i++)
{
// i번째 순서대로 형제 인덱스(Sibling Index)를 지정
_mealKitButtons[i].transform.SetSiblingIndex(i);
}
// 5) 정렬 이후, 내비게이션도 재설정 (정렬 순서가 바뀌었으므로)
SetNavigationMealKitButtons();
}
private bool IsButtonValid(MealKitButton mealKitButton)
{
return mealKitButton != null
&& mealKitButton.gameObject.activeInHierarchy
&& mealKitButton.Button != null
&& mealKitButton.Button.interactable;
}
private void SetNavigationMealKitButtons()
{
int columnCount = 3;
int count = _mealKitButtons.Count;
for (int i = 0; i < count; i++)
{
MealKitButton currentMealKit = _mealKitButtons[i];
Button currentButton = currentMealKit.Button;
// 새로운 Navigation 객체 생성 및 Explicit 모드 설정
Navigation nav = new Navigation { mode = Navigation.Mode.Explicit };
// 현재 버튼이 비활성(혹은 인터랙션 불가능)하면 내비게이션 항목은 모두 null 처리
if (!IsButtonValid(currentMealKit))
{
currentButton.navigation = nav; // 모든 방향 null
continue;
}
// 상(Up) 이웃 버튼: 인덱스 i - columnCount
int upIndex = i - columnCount;
if (upIndex >= 0 && IsButtonValid(_mealKitButtons[upIndex]))
{
nav.selectOnUp = _mealKitButtons[upIndex].Button;
}
else
{
nav.selectOnUp = null;
}
// 하(Down) 이웃 버튼: 인덱스 i + columnCount
int downIndex = i + columnCount;
if (downIndex < count && IsButtonValid(_mealKitButtons[downIndex]))
{
nav.selectOnDown = _mealKitButtons[downIndex].Button;
}
else
{
nav.selectOnDown = null;
}
// 좌(Left) 이웃 버튼: 인덱스 i - 1 (같은 행인지 체크)
int leftIndex = i - 1;
if (leftIndex >= 0
&& (i / columnCount == leftIndex / columnCount)
&& IsButtonValid(_mealKitButtons[leftIndex]))
{
nav.selectOnLeft = _mealKitButtons[leftIndex].Button;
}
else
{
nav.selectOnLeft = null;
}
// 우(Right) 이웃 버튼: 인덱스 i + 1 (같은 행인지 체크)
int rightIndex = i + 1;
if (rightIndex < count
&& (i / columnCount == rightIndex / columnCount)
&& IsButtonValid(_mealKitButtons[rightIndex]))
{
nav.selectOnRight = _mealKitButtons[rightIndex].Button;
}
else
{
nav.selectOnRight = null;
}
// 최종 Navigation 할당
currentButton.navigation = nav;
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ab45660cb40d6c34c8172959f9c74c8b

View File

@ -1,4 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using DDD.ScriptableObjects;
using DG.Tweening; using DG.Tweening;
using Sirenix.OdinInspector; using Sirenix.OdinInspector;
using UnityEngine; using UnityEngine;
@ -78,6 +80,8 @@ namespace DDD.Uis.Tycoon
private void Start() private void Start()
{ {
EventManager.OnTycoonGameStarted += AddMealKit;
_interactionEAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.TycoonUi, TycoonUiActions.InteractionE); _interactionEAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.TycoonUi, TycoonUiActions.InteractionE);
_cancelAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.TycoonUi, TycoonUiActions.Cancel); _cancelAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.TycoonUi, TycoonUiActions.Cancel);
_pressFAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.TycoonUi, TycoonUiActions.PressF); _pressFAction = PlayerInputKeyManager.Instance.GetAction(InputActionMaps.TycoonUi, TycoonUiActions.PressF);
@ -114,6 +118,8 @@ namespace DDD.Uis.Tycoon
private void OnDestroy() private void OnDestroy()
{ {
EventManager.OnTycoonGameStarted -= AddMealKit;
_openAddMenuUiSequence?.Kill(); _openAddMenuUiSequence?.Kill();
_closeAddMenuUiSequence?.Kill(); _closeAddMenuUiSequence?.Kill();
_interactionEAction = null; _interactionEAction = null;
@ -148,7 +154,7 @@ namespace DDD.Uis.Tycoon
public override void EnableInput() public override void EnableInput()
{ {
//_interactionEAction.performed += OnInteractionE; _interactionEAction.performed += OnInteractionE;
_cancelAction.performed += OnClose; _cancelAction.performed += OnClose;
_pressFAction.performed += OnClose; _pressFAction.performed += OnClose;
_uiEventsController.EnableAutoNavigate(); _uiEventsController.EnableAutoNavigate();
@ -167,7 +173,7 @@ namespace DDD.Uis.Tycoon
public override void DisableInput() public override void DisableInput()
{ {
//_interactionEAction.performed -= OnInteractionE; _interactionEAction.performed -= OnInteractionE;
_cancelAction.performed -= OnClose; _cancelAction.performed -= OnClose;
_pressFAction.performed -= OnClose; _pressFAction.performed -= OnClose;
_uiEventsController.DisableAutoNavigate(); _uiEventsController.DisableAutoNavigate();
@ -209,5 +215,50 @@ namespace DDD.Uis.Tycoon
} }
} }
} }
public bool CanOpen()
{
bool canOpen = false;
foreach (TodayMenu todayMenu in _todayMenus)
{
if (!todayMenu.IsAddedMenu) continue;
canOpen = true;
break;
}
return canOpen;
}
private void AddMealKit()
{
EventManager.InvokeAddedMealKit(_todayMenus);
}
public int GetTodayMenusCount()
{
return _todayMenus.Sum(menu => menu.AddedCount);
}
public CraftRecipeData GetRandomTodayMenu()
{
List<TodayMenu> availableMenus = _todayMenus.Where(menu => menu.CanOrderMenu()).ToList();
if (availableMenus.Count == 0)
{
Debug.LogError("주문 가능한 메뉴가 없습니다");
return null;
}
// 랜덤으로 하나의 메뉴를 선택합니다.
int randomIndex = Random.Range(0, availableMenus.Count);
TodayMenu selectedMenu = availableMenus[randomIndex];
// 선택한 메뉴에 대해 주문 처리를 진행합니다.
selectedMenu.OrderMenu();
// 선택된 메뉴의 CraftRecipeData를 반환합니다.
return selectedMenu.AddedCraftRecipeData;
}
} }
} }

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using DDD.ScriptableObjects; using DDD.ScriptableObjects;
using Sirenix.OdinInspector; using Sirenix.OdinInspector;
using TMPro; using TMPro;
@ -44,6 +45,9 @@ namespace DDD.Uis.Tycoon
[Title("데이터")] [Title("데이터")]
[SerializeField] [SerializeField]
private Sprite _emptySprite; private Sprite _emptySprite;
[SerializeField]
private int _maxHashTagCount = 3;
[Title("실시간 데이터")] [Title("실시간 데이터")]
[SerializeField, DisableIf("@true")] [SerializeField, DisableIf("@true")]
@ -72,6 +76,9 @@ namespace DDD.Uis.Tycoon
public CraftRecipeData AddedCraftRecipeData { get; private set; } public CraftRecipeData AddedCraftRecipeData { get; private set; }
public int AddedCount { get; private set; } public int AddedCount { get; private set; }
[SerializeField]
private List<MenuHashTag> _menuHashTags;
private UnityAction _clickAction; private UnityAction _clickAction;
@ -86,6 +93,14 @@ namespace DDD.Uis.Tycoon
} }
} }
_menuHashTags = new List<MenuHashTag>(_maxHashTagCount);
for (int i = 0; i < _maxHashTagCount; i++)
{
MenuHashTag menuHashTag = Instantiate(_menuHashTagPrefab, _menuHashTagsPanel.transform);
menuHashTag.HideUi();
_menuHashTags.Add(menuHashTag);
}
SetEmpty(); SetEmpty();
} }
@ -125,6 +140,19 @@ namespace DDD.Uis.Tycoon
_priceText.text = (craftRecipeData.Price * AddedCount).ToString(); _priceText.text = (craftRecipeData.Price * AddedCount).ToString();
_countText.text = AddedCount.ToString(); _countText.text = AddedCount.ToString();
int validHashTagCount = AddedCraftRecipeData.ValidHashTags.Count;
for (int i = 0; i < _maxHashTagCount; i++)
{
if (i >= validHashTagCount)
{
_menuHashTags[i].HideUi();
continue;
}
_menuHashTags[i].SetTag(AddedCraftRecipeData.ValidHashTags[i]);
_menuHashTags[i].ShowUi();
}
} }
public void SetEmpty() public void SetEmpty()
@ -136,9 +164,24 @@ namespace DDD.Uis.Tycoon
_countText.text = null; _countText.text = null;
_nameText.text = null; _nameText.text = null;
for (int i = 0; i < _maxHashTagCount; i++)
{
_menuHashTags[i].HideUi();
}
_isAddedMenu = false; _isAddedMenu = false;
_menuInformationPanel.SetActive(false); _menuInformationPanel.SetActive(false);
} }
public bool CanOrderMenu()
{
return AddedCraftRecipeData != null && AddedCount > 0;
}
public void OrderMenu()
{
AddedCount--;
}
} }
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using DDD; using DDD;
using DDD.Items; using DDD.Items;
using DDD.Npcs.Crews.Bartender; using DDD.Npcs.Crews.Bartender;
@ -6,6 +7,7 @@ using DDD.Npcs.Crews.Cleaner;
using DDD.Npcs.Crews.Server; using DDD.Npcs.Crews.Server;
using DDD.Npcs.Customers; using DDD.Npcs.Customers;
using DDD.ScriptableObjects; using DDD.ScriptableObjects;
using DDD.Uis.Tycoon;
using UnityEngine; using UnityEngine;
public static class EventManager public static class EventManager
@ -96,7 +98,6 @@ public static class EventManager
// 타이쿤 시작 이벤트 // 타이쿤 시작 이벤트
public static Action OnTycoonGameStarted; public static Action OnTycoonGameStarted;
public static void InvokeTycoonGameStarted() public static void InvokeTycoonGameStarted()
{ {
OnTycoonGameStarted?.Invoke(); OnTycoonGameStarted?.Invoke();
@ -194,7 +195,6 @@ public static class EventManager
// Npc // Npc
// 손님 생성 이벤트 // 손님 생성 이벤트
public static Action OnCreateCustomer; public static Action OnCreateCustomer;
public static void InvokeCreateCustomer() public static void InvokeCreateCustomer()
{ {
OnCreateCustomer?.Invoke(); OnCreateCustomer?.Invoke();
@ -430,12 +430,46 @@ public static class EventManager
// Tycoon // Tycoon
// 메뉴를 추가할 때 이벤트 // 게임 시작할 때, 밀키트를 추가하는 이벤트
public static Action<CraftRecipeData, int> OnAddedTodayMenu; public static Action<List<TodayMenu>> OnAddedMealKit;
public static void InvokeAddedMealKit(List<TodayMenu> todayMenus)
public static void InvokeAddedTodayMenu(CraftRecipeData addedCraftRecipeData, int count)
{ {
OnAddedTodayMenu?.Invoke(addedCraftRecipeData, count); OnAddedMealKit?.Invoke(todayMenus);
}
// 플레이어가 밀키트를 냉장고에서 꺼내는 이벤트
public static Action<CraftRecipeData> OnPickupMealKit;
public static void InvokePickupMealKit(CraftRecipeData craftRecipeData)
{
OnPickupMealKit?.Invoke(craftRecipeData);
}
// 플레이어가 들고 있는 요리 도구 정보가 바뀌는 경우
public static Action<CraftingTool?> OnChangedCraftingTool;
public static void InvokeChangedCraftingTool(CraftingTool? craftingTool)
{
OnChangedCraftingTool?.Invoke(craftingTool);
}
// 손님이 음식을 주문하는 이벤트
public static Action<Customer> OnOrderedCook;
public static void InvokeOrderedCook(Customer orderedCustomer)
{
OnOrderedCook?.Invoke(orderedCustomer);
}
// 손님이 음식을 받을때 이벤트
public static Action OnServedCookToCustomer;
public static void InvokeServedCookToCustomer()
{
OnServedCookToCustomer?.Invoke();
}
// 손님이 음식을 받을때 결과 이벤트
public static Action<Customer, bool> OnServedResult;
public static void InvokeServedResult(Customer orderedCustomer, bool orderedCorrected)
{
OnServedResult?.Invoke(orderedCustomer, orderedCorrected);
} }
#endregion #endregion

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 87c01d94bd1f8c947bf23c08f4a0a233
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b37ca68d525e1d343b4fe58b472e0f24
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 142 KiB

View File

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 149 KiB

View File

Before

Width:  |  Height:  |  Size: 159 KiB

After

Width:  |  Height:  |  Size: 159 KiB

View File

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 104 KiB

View File

Before

Width:  |  Height:  |  Size: 500 KiB

After

Width:  |  Height:  |  Size: 500 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

View File

@ -0,0 +1,156 @@
fileFormatVersion: 2
guid: 2e134437be9e8bc419ac54ce318fb735
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 1
wrapV: 1
wrapW: 0
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 9
spritePivot: {x: 0.5, y: 0.07}
spritePixelsToUnits: 512
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 4
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: iOS
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 4
buildTarget: WindowsStoreApps
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
customData:
physicsShape: []
bones: []
spriteID: 5e97eb03825dee720800000000000000
internalID: 1537655665
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
spriteCustomMetadata:
entries: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More