ワールド対応(マーケット
This commit is contained in:
parent
60ccfc860e
commit
10cb205ca5
|
|
@ -1,13 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.ExceptionServices;
|
||||||
using MyGame.Scenes.marketing.Scripts;
|
using MyGame.Scenes.marketing.Scripts;
|
||||||
using MyGame.Scripts;
|
using MyGame.Scripts;
|
||||||
using TMPro;
|
|
||||||
using UniRx;
|
using UniRx;
|
||||||
using UniRx.Triggers;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Debug = UnityEngine.Debug;
|
||||||
using Random = UnityEngine.Random;
|
using Random = UnityEngine.Random;
|
||||||
|
|
||||||
public enum ShopState
|
public enum ShopState
|
||||||
|
|
@ -22,6 +22,7 @@ public class Market : MonoBehaviour
|
||||||
// 購入時アニメーションタイミング
|
// 購入時アニメーションタイミング
|
||||||
private static readonly float waitSellTime = 1.5f;
|
private static readonly float waitSellTime = 1.5f;
|
||||||
private static readonly float waitRefillTime = 1f;
|
private static readonly float waitRefillTime = 1f;
|
||||||
|
private static readonly float DummyUsedCapacity = .5f;
|
||||||
|
|
||||||
[SerializeField] private CustomerFlow customerFlow;
|
[SerializeField] private CustomerFlow customerFlow;
|
||||||
[SerializeField] private GameObject orderPosisionObject;
|
[SerializeField] private GameObject orderPosisionObject;
|
||||||
|
|
@ -36,7 +37,14 @@ public class Market : MonoBehaviour
|
||||||
private List<ProductStockData> displayFlavors = new List<ProductStockData>();
|
private List<ProductStockData> displayFlavors = new List<ProductStockData>();
|
||||||
public List<int> ShuffledOrder => shuffledOrder;
|
public List<int> ShuffledOrder => shuffledOrder;
|
||||||
private List<int> shuffledOrder = new List<int>();
|
private List<int> shuffledOrder = new List<int>();
|
||||||
|
|
||||||
|
private List<ProductStockData> ShopStock => IsPartTimer ? dummyStock : cityGameData.ShopStock;
|
||||||
|
private readonly List<ProductStockData> dummyStock = new();
|
||||||
|
private readonly List<ProductStockData> dummyStorageTank = new();
|
||||||
|
|
||||||
|
public bool IsPartTimer { get; private set; }
|
||||||
|
public bool IsLatestCity { get; private set; }
|
||||||
|
|
||||||
public IReadOnlyReactiveProperty<ShopState> CurrentShopState => shopState;
|
public IReadOnlyReactiveProperty<ShopState> CurrentShopState => shopState;
|
||||||
private readonly ReactiveProperty<ShopState> shopState = new ReactiveProperty<ShopState>();
|
private readonly ReactiveProperty<ShopState> shopState = new ReactiveProperty<ShopState>();
|
||||||
public IReadOnlyReactiveCollection<CustomerController> CustomerControllerList => customerControllerList;
|
public IReadOnlyReactiveCollection<CustomerController> CustomerControllerList => customerControllerList;
|
||||||
|
|
@ -60,7 +68,8 @@ public class Market : MonoBehaviour
|
||||||
private int orderIndex;
|
private int orderIndex;
|
||||||
private int oneByOneIndex = 0;
|
private int oneByOneIndex = 0;
|
||||||
private int salesBonus = 0;
|
private int salesBonus = 0;
|
||||||
private GameData gameData;
|
private GameData globalGameData;
|
||||||
|
private GameData cityGameData;
|
||||||
|
|
||||||
// Start is called before the first frame update
|
// Start is called before the first frame update
|
||||||
void Start()
|
void Start()
|
||||||
|
|
@ -72,33 +81,36 @@ public class Market : MonoBehaviour
|
||||||
orderSubject.AddTo(this);
|
orderSubject.AddTo(this);
|
||||||
IsPause.AddTo(this);
|
IsPause.AddTo(this);
|
||||||
isPromotion.AddTo(this);
|
isPromotion.AddTo(this);
|
||||||
|
}
|
||||||
gameData = GameDataManager.GameData;
|
|
||||||
|
public void Initialize(int cityId)
|
||||||
UpdateBonus(ShopCustomize.GetBonusList(gameData.ShopCustomizeLevel));
|
{
|
||||||
|
IsLatestCity = GameDataUtils.CheckLatestCity(cityId);
|
||||||
|
cityGameData = GameDataManager.GetCityGameData(cityId);
|
||||||
|
globalGameData = GameDataManager.GameData;
|
||||||
|
UpdateBonus(ShopCustomize.GetBonusList(globalGameData.ShopCustomizeLevel));
|
||||||
|
customerFlow.SetCityGameData(cityGameData);
|
||||||
|
|
||||||
#if UNITY_EDITOR || DEVELOPMENT_BUILD
|
|
||||||
CheckAndFixStock();
|
CheckAndFixStock();
|
||||||
WorldMarketManager.StockFlavorLog();
|
WorldMarketManager.StockFlavorLog();
|
||||||
#endif
|
|
||||||
|
|
||||||
// 陳列/売り順決定
|
// 陳列/売り順決定
|
||||||
ReShuffle(gameData.ShopStock);
|
ReShuffle(ShopStock);
|
||||||
|
|
||||||
Observable.Interval(TimeSpan.FromSeconds(1f))
|
Observable.Interval(TimeSpan.FromSeconds(1f))
|
||||||
.Where(_ => shuffledOrder.Count == 0)
|
.Where(_ => shuffledOrder.Count == 0)
|
||||||
.Where(_ => gameData.ShopStock.Count > 0)
|
.Where(_ => ShopStock.Count > 0)
|
||||||
.Subscribe(_ =>
|
.Subscribe(_ =>
|
||||||
{
|
{
|
||||||
#if UNITY_EDITOR || DEVELOPMENT_BUILD
|
#if UNITY_EDITOR || DEVELOPMENT_BUILD
|
||||||
Debug.Log("displayFlavors updated");
|
Debug.LogWarning("displayFlavors updated");
|
||||||
#endif
|
#endif
|
||||||
ReShuffle(gameData.ShopStock);
|
ReShuffle(ShopStock);
|
||||||
shopState.Value = ShopState.Open;
|
shopState.Value = ShopState.Open;
|
||||||
});
|
}).AddTo(this);
|
||||||
|
|
||||||
// お店の状態設定
|
// お店の状態設定
|
||||||
CheckStock(gameData.ShopStock);
|
UpdateShopState();
|
||||||
|
|
||||||
// 購入リクエスト
|
// 購入リクエスト
|
||||||
var maxOrder = orderPosisionObject.transform.childCount;
|
var maxOrder = orderPosisionObject.transform.childCount;
|
||||||
|
|
@ -131,24 +143,10 @@ public class Market : MonoBehaviour
|
||||||
|
|
||||||
requestSubject.BatchFrame().Subscribe(customers =>
|
requestSubject.BatchFrame().Subscribe(customers =>
|
||||||
{
|
{
|
||||||
// 来客数カウント
|
|
||||||
gameData.AddCustomerCount(customers.Count);
|
|
||||||
|
|
||||||
var orders = new List<int>();
|
var orders = new List<int>();
|
||||||
var dontBuyCustomerList = new List<CustomerController>();
|
var dontBuyCustomerList = new List<CustomerController>();
|
||||||
foreach (var controller in customers)
|
foreach (var controller in customers)
|
||||||
{
|
{
|
||||||
// 何も買わない
|
|
||||||
if (displayFlavors.Count == 0 || controller.OrderCount == 0)
|
|
||||||
{
|
|
||||||
controller.CallWaitForSeconds(1.5f, () =>
|
|
||||||
{
|
|
||||||
controller.ChangeCustomerState(CustomerState.Leave);
|
|
||||||
});
|
|
||||||
dontBuyCustomerList.Add(controller);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 売り切れ
|
// 売り切れ
|
||||||
if (shuffledOrder.Count == 0)
|
if (shuffledOrder.Count == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -166,27 +164,22 @@ public class Market : MonoBehaviour
|
||||||
var tmpOrderCount = Mathf.Min(controller.OrderCount, shuffledOrder.Count);
|
var tmpOrderCount = Mathf.Min(controller.OrderCount, shuffledOrder.Count);
|
||||||
var tmpOrders = shuffledOrder.GetRange(0, tmpOrderCount);
|
var tmpOrders = shuffledOrder.GetRange(0, tmpOrderCount);
|
||||||
shuffledOrder.RemoveRange(0, tmpOrderCount);
|
shuffledOrder.RemoveRange(0, tmpOrderCount);
|
||||||
orders.AddRange(tmpOrders);
|
|
||||||
|
|
||||||
// コーンの味吹き出しを設定
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 不正なオーダーの場合お客さん制御
|
// 不正なオーダーチェック
|
||||||
foreach (var t in tmpOrders)
|
var checkedOrders = tmpOrders.Where(order => ShopStock.Contains(displayFlavors[order])).ToList();
|
||||||
{
|
controller.OrderCount = checkedOrders.Count;
|
||||||
if (gameData.ShopStock.Contains(displayFlavors[t]))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (controller.OrderCount >= 1)
|
|
||||||
{
|
|
||||||
controller.OrderCount--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#if UNITY_EDITOR || DEVELOPMENT_BUILD
|
||||||
|
if (tmpOrderCount != checkedOrders.Count)
|
||||||
|
throw new Exception($@"tmpOrder:{string.Join(".", tmpOrders)}
|
||||||
|
shuffledOrder:{shuffledOrder.OrderBy(x => x).Aggregate("", (s, num) => $"{s},{num}")}
|
||||||
|
shopStock:{ShopStock.Aggregate("", (s, data) => $"{s},{data.FlavorId}")}
|
||||||
|
display:{displayFlavors.Aggregate("", (s, data) => $"{s},{data.FlavorId}")}");
|
||||||
|
#endif
|
||||||
// 購入しないお客さん扱いで退場
|
// 購入しないお客さん扱いで退場
|
||||||
if (controller.OrderCount == 0)
|
if (displayFlavors.Count == 0 || controller.OrderCount == 0)
|
||||||
{
|
{
|
||||||
controller.CallWaitForSeconds(1.5f, () =>
|
controller.CallWaitForSeconds(1.5f, () =>
|
||||||
{
|
{
|
||||||
|
|
@ -195,17 +188,14 @@ public class Market : MonoBehaviour
|
||||||
dontBuyCustomerList.Add(controller);
|
dontBuyCustomerList.Add(controller);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// コーンの味吹き出しを設定
|
||||||
controller.SetWantFlavor(displayFlavors[tmpOrders.RandomChoose()]);
|
controller.SetWantFlavor(displayFlavors[checkedOrders.RandomChoose()]);
|
||||||
|
orders.AddRange(checkedOrders);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
/*
|
// 動作止めずに例外スロー
|
||||||
* 例外握りつぶし
|
Observable.NextFrame().Subscribe(_ => { ExceptionDispatchInfo.Capture(e).Throw();});
|
||||||
* 存在しないorderを引いたのでそのまま処理せず逃がす
|
|
||||||
*/
|
|
||||||
Debug.LogError($"d:{displayFlavors.Count}, {string.Join("", tmpOrders)}" +
|
|
||||||
$"\nshuffled:{shuffledOrder.Count}, maxNum:{shuffledOrder.Max()}");
|
|
||||||
controller.CallWaitForSeconds(1.5f, () =>
|
controller.CallWaitForSeconds(1.5f, () =>
|
||||||
{
|
{
|
||||||
controller.ChangeCustomerState(CustomerState.Leave);
|
controller.ChangeCustomerState(CustomerState.Leave);
|
||||||
|
|
@ -217,7 +207,7 @@ public class Market : MonoBehaviour
|
||||||
{
|
{
|
||||||
customers.Remove(customerController);
|
customers.Remove(customerController);
|
||||||
}
|
}
|
||||||
if (gameData.ShopStock.Count == 0)
|
if (ShopStock.Count == 0)
|
||||||
{
|
{
|
||||||
shopState.Value = ShopState.Close;
|
shopState.Value = ShopState.Close;
|
||||||
}
|
}
|
||||||
|
|
@ -227,48 +217,63 @@ public class Market : MonoBehaviour
|
||||||
}
|
}
|
||||||
|
|
||||||
// 購入
|
// 購入
|
||||||
var flavors = orders.Select(x => displayFlavors[x]).ToList();
|
var flavors = orders.Select(x => displayFlavors[x]).ToList();
|
||||||
var (coin, count) = SellPopcorn(flavors);
|
var (coin, count) = SellPopcorn(flavors);
|
||||||
|
|
||||||
// 獲得処理(遅延追加用変数に加算)
|
|
||||||
gameData.WaitAddCoin += coin;
|
|
||||||
gameData.WaitAddHeart += count;
|
|
||||||
gameData.AddVipCustomerCount(customers.Count(data => data.CustomerType == CustomerType.Vip));
|
|
||||||
GameDataManager.SaveGameData();
|
|
||||||
|
|
||||||
// 商品補充
|
|
||||||
RefillShopStockData();
|
|
||||||
|
|
||||||
// 表示データ更新
|
|
||||||
var isReorder = false;
|
var isReorder = false;
|
||||||
var refillList = new List<int>();
|
var refillList = new List<int>();
|
||||||
if (gameData.ShopStock.Count > shuffledOrder.Count)
|
if (IsPartTimer)
|
||||||
{
|
{
|
||||||
refillList = RefillDisplayFlavors(gameData.ShopStock);
|
// 商品補充
|
||||||
|
RefillDummyShopStockData();
|
||||||
|
refillList = RefillDisplayFlavors();
|
||||||
|
|
||||||
|
// 在庫生成
|
||||||
|
if (dummyStorageTank.Count <= 0)
|
||||||
|
{
|
||||||
|
GenerateDummyStock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
isReorder = CheckRemaining(gameData.ShopStock.Count);
|
// 獲得処理(遅延追加用変数に加算)
|
||||||
if (isReorder)
|
cityGameData.WaitAddCoin += coin;
|
||||||
|
cityGameData.WaitAddHeart += count;
|
||||||
|
cityGameData.AddCustomerCount(customers.Count);
|
||||||
|
cityGameData.AddVipCustomerCount(customers.Count(data => data.CustomerType == CustomerType.Vip));
|
||||||
|
GameDataManager.SaveGameData();
|
||||||
|
|
||||||
|
// 商品補充
|
||||||
|
RefillShopStockData();
|
||||||
|
|
||||||
|
// 表示データ更新
|
||||||
|
if (ShopStock.Count > shuffledOrder.Count)
|
||||||
{
|
{
|
||||||
ReShuffle(gameData.ShopStock);
|
refillList = RefillDisplayFlavors();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isReorder = CheckRemaining(ShopStock.Count);
|
||||||
|
if (isReorder)
|
||||||
|
{
|
||||||
|
ReShuffle(ShopStock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.CallWaitForSeconds(waitSellTime, () =>
|
this.CallWaitForSeconds(waitSellTime, () =>
|
||||||
{
|
{
|
||||||
// 獲得処理
|
// 獲得処理
|
||||||
gameData.MoveCoin(coin);
|
cityGameData.MoveCoin(coin);
|
||||||
GameDataManager.SaveGameData();
|
GameDataManager.SaveGameData();
|
||||||
|
|
||||||
sellObservable.OnNext(coin);
|
sellObservable.OnNext(coin);
|
||||||
sellOrderSubject.OnNext(orders);
|
sellOrderSubject.OnNext(orders);
|
||||||
CheckStock(gameData.ShopStock);
|
UpdateShopState();
|
||||||
|
|
||||||
this.CallWaitForSeconds(waitRefillTime, () =>
|
this.CallWaitForSeconds(waitRefillTime, () =>
|
||||||
{
|
{
|
||||||
// 獲得処理
|
// 獲得処理
|
||||||
gameData.MoveHeart(count);
|
cityGameData.MoveHeart(count);
|
||||||
GameDataManager.SaveGameData();
|
GameDataManager.SaveGameData();
|
||||||
|
|
||||||
refillSubject.OnNext((isReorder, refillList));
|
refillSubject.OnNext((isReorder, refillList));
|
||||||
|
|
@ -300,6 +305,7 @@ public class Market : MonoBehaviour
|
||||||
controller.ChangeCustomerState(CustomerState.Leave);
|
controller.ChangeCustomerState(CustomerState.Leave);
|
||||||
}).AddTo(controller);
|
}).AddTo(controller);
|
||||||
|
|
||||||
|
// ステートが変わるたびにオーダーチェック
|
||||||
controller.State
|
controller.State
|
||||||
.Where(x => x != CustomerState.Order)
|
.Where(x => x != CustomerState.Order)
|
||||||
.Subscribe(c =>
|
.Subscribe(c =>
|
||||||
|
|
@ -320,33 +326,24 @@ public class Market : MonoBehaviour
|
||||||
}
|
}
|
||||||
|
|
||||||
// チュートリアル中は抑制
|
// チュートリアル中は抑制
|
||||||
if (!gameData.FinishedFlags.HasFlag(TutorialFlag.FirstPlay))
|
if (!globalGameData.FinishedFlags.HasFlag(TutorialFlag.FirstPlay))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 一般客orセレブ
|
// 一般客orセレブ
|
||||||
CustomerState customerState;
|
|
||||||
|
var customerState = customerType switch
|
||||||
switch (customerType)
|
|
||||||
{
|
{
|
||||||
case CustomerType.Walker:
|
CustomerType.Walker => CustomerState.Walk,
|
||||||
customerState = CustomerState.Walk;
|
CustomerType.Customer => CustomerState.WalkShop,
|
||||||
break;
|
CustomerType.Vip => CustomerState.WalkShop,
|
||||||
case CustomerType.Customer:
|
_ => throw new ArgumentOutOfRangeException(nameof(customerType), customerType, null)
|
||||||
customerState = CustomerState.WalkShop;
|
};
|
||||||
break;
|
|
||||||
case CustomerType.Vip:
|
|
||||||
customerState = CustomerState.WalkShop;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(customerType), customerType, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
var (isSpecial, orderCount) = customerSetting.GetCustomerData(customerType);
|
var (isSpecial, orderCount) = customerSetting.GetCustomerData(customerType);
|
||||||
var customerController = SpawnCustomer();
|
var customerController = SpawnCustomer();
|
||||||
customerController.Setup(orderPosisionObject.transform.GetComponentsInChildren<Transform>().ToList().Skip(1).ToList());
|
customerController.Setup(orderPosisionObject.transform.GetComponentsInChildren<Transform>().ToList().Skip(1).ToList());
|
||||||
customerController.ChangeCustomerState(customerState);
|
customerController.ChangeCustomerState(customerState);
|
||||||
// 複数パターンある場合ChooseRandom
|
|
||||||
customerController.CustomerPrefab = isSpecial ? customerData.ChooseSpecialPrefab() : customerData.ChooseNormalPrefab();
|
customerController.CustomerPrefab = isSpecial ? customerData.ChooseSpecialPrefab() : customerData.ChooseNormalPrefab();
|
||||||
customerController.OrderCount = orderCount;
|
customerController.OrderCount = orderCount;
|
||||||
customerController.CustomerType = customerType;
|
customerController.CustomerType = customerType;
|
||||||
|
|
@ -354,17 +351,11 @@ public class Market : MonoBehaviour
|
||||||
|
|
||||||
customerController.TappedObservable
|
customerController.TappedObservable
|
||||||
.Take(1)
|
.Take(1)
|
||||||
.Subscribe(_ =>
|
.Subscribe(_ => customerController.ChangeCustomerState(shopState.Value switch
|
||||||
{
|
{
|
||||||
if (shopState.Value == ShopState.Open)
|
ShopState.Open => CustomerState.TouchNotice,
|
||||||
{
|
_ => CustomerState.TouchQuestion
|
||||||
customerController.ChangeCustomerState(CustomerState.TouchNotice);
|
})).AddTo(customerController);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
customerController.ChangeCustomerState(CustomerState.TouchQuestion);
|
|
||||||
}
|
|
||||||
}).AddTo(customerController);
|
|
||||||
}).AddTo(this);
|
}).AddTo(this);
|
||||||
|
|
||||||
// お客さんが少なくなったら弟が走る
|
// お客さんが少なくなったら弟が走る
|
||||||
|
|
@ -389,7 +380,7 @@ public class Market : MonoBehaviour
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BrotherPinkView.Instance.StopPromotion();
|
BrotherPinkView.Instance.StopPromotion();
|
||||||
if (gameData.TastingCount > 0 && shopState.Value == ShopState.Open)
|
if (cityGameData.TastingCount > 0 && shopState.Value == ShopState.Open)
|
||||||
{
|
{
|
||||||
BrotherPinkView.Instance.StartTasting();
|
BrotherPinkView.Instance.StartTasting();
|
||||||
}
|
}
|
||||||
|
|
@ -412,9 +403,7 @@ public class Market : MonoBehaviour
|
||||||
{
|
{
|
||||||
case CustomerMovingType.WalkSide:
|
case CustomerMovingType.WalkSide:
|
||||||
case CustomerMovingType.WalkSideEat:
|
case CustomerMovingType.WalkSideEat:
|
||||||
customerList.Remove(customerController);
|
DestroyCustomer(customerController);
|
||||||
customerControllerList.Remove(customerController);
|
|
||||||
Destroy(customerController.gameObject);
|
|
||||||
break;
|
break;
|
||||||
case CustomerMovingType.TouchNotice:
|
case CustomerMovingType.TouchNotice:
|
||||||
customerList.Add(customerController);
|
customerList.Add(customerController);
|
||||||
|
|
@ -441,11 +430,17 @@ public class Market : MonoBehaviour
|
||||||
return customerController;
|
return customerController;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DestroyCustomer(CustomerController customerController)
|
||||||
|
{
|
||||||
|
customerControllerList.Remove(customerController);
|
||||||
|
customerList.Remove(customerController);
|
||||||
|
Destroy(customerController.gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
private (int coin, int count) SellPopcorn(List<ProductStockData> stockDataList)
|
private (int coin, int count) SellPopcorn(List<ProductStockData> stockDataList)
|
||||||
{
|
{
|
||||||
var gameData = GameDataManager.GameData;
|
|
||||||
// 品切れ
|
// 品切れ
|
||||||
if (gameData.ShopStock.Count == 0)
|
if (ShopStock.Count == 0)
|
||||||
{
|
{
|
||||||
return (0, 0);
|
return (0, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -459,18 +454,20 @@ public class Market : MonoBehaviour
|
||||||
{
|
{
|
||||||
var productData = recipeList.First(data => data.id == stockData.FlavorId);
|
var productData = recipeList.First(data => data.id == stockData.FlavorId);
|
||||||
var rarityData = rarityList.First(data => data.Rarity == stockData.Rarity);
|
var rarityData = rarityList.First(data => data.Rarity == stockData.Rarity);
|
||||||
var targetIndex = gameData.ShopStock.FindIndex(data => data.FlavorId == stockData.FlavorId && data.Rarity == stockData.Rarity);
|
var targetIndex = ShopStock.FindIndex(data => data.FlavorId == stockData.FlavorId && data.Rarity == stockData.Rarity);
|
||||||
if (targetIndex == -1)
|
if (targetIndex == -1)
|
||||||
{
|
{
|
||||||
Debug.LogError($@"data
|
Debug.LogError($@"data
|
||||||
-----stockData: {stockData.FlavorId}, {stockData.Rarity}
|
-----stockData: {stockData.FlavorId}, {stockData.Rarity}
|
||||||
-----shopStock: {gameData.ShopStock.Aggregate("", (s, data) => $"{s},{data.FlavorId}")}
|
-----shopStock: {ShopStock.Aggregate("", (s, data) => $"{s},{data.FlavorId}")}
|
||||||
displayFlavors: {displayFlavors.Aggregate("", (s, data) => $"{s},{data.FlavorId}")}");
|
displayFlavors: {displayFlavors.Aggregate("", (s, data) => $"{s},{data.FlavorId}")}");
|
||||||
Observable.NextFrame().Subscribe(_ => throw new Exception("DisplayFlavors Invalid")).AddTo(this);
|
Observable.NextFrame().Subscribe(_ => throw new Exception("DisplayFlavors Invalid")).AddTo(this);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
gameData.ShopStock.RemoveAt(targetIndex);
|
ShopStock.RemoveAt(targetIndex);
|
||||||
gameData.AddSalesCount(stockData.FlavorId, 1, stockData.Rarity);
|
// バイトは削除処理のみ
|
||||||
|
if (IsPartTimer) continue;
|
||||||
|
cityGameData.AddSalesCount(stockData.FlavorId, 1, stockData.Rarity);
|
||||||
coin += productData.GetRarityPrice(rarityData.Rarity);
|
coin += productData.GetRarityPrice(rarityData.Rarity);
|
||||||
coin += salesBonus;
|
coin += salesBonus;
|
||||||
count++;
|
count++;
|
||||||
|
|
@ -488,33 +485,32 @@ displayFlavors: {displayFlavors.Aggregate("", (s, data) => $"{s},{data.FlavorId}
|
||||||
{
|
{
|
||||||
// 手前のタンクから出し多分stockをへらす
|
// 手前のタンクから出し多分stockをへらす
|
||||||
// へらした分を店頭リストに追加する
|
// へらした分を店頭リストに追加する
|
||||||
var gameData = GameDataManager.GameData;
|
var shopSpace = WorldMarketManager.ShopStockCount - ShopStock.Count;
|
||||||
var shopSpace = WorldMarketManager.ShopStockCount - gameData.ShopStock.Count;
|
switch (cityGameData.RefillMode)
|
||||||
switch (gameData.RefillMode)
|
|
||||||
{
|
{
|
||||||
case ProductRefillMode.OneByOne:
|
case ProductRefillMode.OneByOne:
|
||||||
while (shopSpace > 0 && gameData.StorageTanks.Sum(data => data.Stock) > 0)
|
while (shopSpace > 0 && cityGameData.StorageTanks.Sum(data => data.Stock) > 0)
|
||||||
{
|
{
|
||||||
var tanks = gameData.StorageTanks.Where(tank => !tank.IsEmpty).ToList();
|
var tanks = cityGameData.StorageTanks.Where(tank => !tank.IsEmpty).ToList();
|
||||||
if (oneByOneIndex >= tanks.Count)
|
if (oneByOneIndex >= tanks.Count)
|
||||||
{
|
{
|
||||||
oneByOneIndex = 0;
|
oneByOneIndex = 0;
|
||||||
}
|
}
|
||||||
var stockList = tanks[oneByOneIndex].GetStock(1);
|
var stockList = tanks[oneByOneIndex].GetStock(1);
|
||||||
gameData.ShopStock.AddRange(stockList);
|
ShopStock.AddRange(stockList);
|
||||||
shopSpace -= stockList.Count;
|
shopSpace -= stockList.Count;
|
||||||
oneByOneIndex++;
|
oneByOneIndex++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ProductRefillMode.TankByTank:
|
case ProductRefillMode.TankByTank:
|
||||||
foreach (var tank in gameData.StorageTanks.Where(tank => !tank.IsEmpty))
|
foreach (var tank in cityGameData.StorageTanks.Where(tank => !tank.IsEmpty))
|
||||||
{
|
{
|
||||||
if (shopSpace == 0)
|
if (shopSpace == 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
var stockList = tank.GetStock(shopSpace);
|
var stockList = tank.GetStock(shopSpace);
|
||||||
gameData.ShopStock.AddRange(stockList);
|
ShopStock.AddRange(stockList);
|
||||||
shopSpace -= stockList.Count;
|
shopSpace -= stockList.Count;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -524,28 +520,32 @@ displayFlavors: {displayFlavors.Aggregate("", (s, data) => $"{s},{data.FlavorId}
|
||||||
GameDataManager.SaveGameData();
|
GameDataManager.SaveGameData();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<int> RefillDisplayFlavors(List<ProductStockData> shopStock)
|
/// <summary>
|
||||||
|
/// shopStockを確認して追加差分をDisplayFlavorsとShuffledOrderにAddする
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public List<int> RefillDisplayFlavors()
|
||||||
{
|
{
|
||||||
// 補充された場合店頭のフレーバー入れ替え
|
// 補充された場合店頭のフレーバー入れ替え
|
||||||
var refillCount = shopStock.Count - shuffledOrder.Count;
|
var refillCount = ShopStock.Count - shuffledOrder.Count;
|
||||||
if (refillCount <= 0)
|
if (refillCount <= 0)
|
||||||
{
|
{
|
||||||
return new List<int>();
|
return new List<int>();
|
||||||
}
|
}
|
||||||
// 補充候補リスト
|
// 補充候補リスト
|
||||||
var orders = Enumerable.Range(0, shopStock.Count).Except(shuffledOrder).ToList();
|
var orders = Enumerable.Range(0, ShopStock.Count).Except(shuffledOrder).ToList();
|
||||||
var refillList = orders.GetRange(0, refillCount).OrderBy(_ => Random.value).ToList();
|
var refillList = orders.GetRange(0, refillCount).OrderBy(_ => Random.value).ToList();
|
||||||
shuffledOrder.AddRange(refillList);
|
shuffledOrder.AddRange(refillList);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var diffDisplayCount = shopStock.Count - displayFlavors.Count;
|
var diffDisplayCount = ShopStock.Count - displayFlavors.Count;
|
||||||
if (diffDisplayCount > 0)
|
if (diffDisplayCount > 0)
|
||||||
{
|
{
|
||||||
displayFlavors.AddRange(shopStock.GetRange(displayFlavors.Count, diffDisplayCount));
|
displayFlavors.AddRange(ShopStock.GetRange(displayFlavors.Count, diffDisplayCount));
|
||||||
}
|
}
|
||||||
for (int i = 0; i < refillList.Count; i++)
|
for (int i = 0; i < refillList.Count; i++)
|
||||||
{
|
{
|
||||||
displayFlavors[refillList[i]] = shopStock[shopStock.Count - 1 - i];
|
displayFlavors[refillList[i]] = ShopStock[ShopStock.Count - 1 - i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|
@ -569,15 +569,15 @@ displayFlavors: {displayFlavors.Aggregate("", (s, data) => $"{s},{data.FlavorId}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReShuffle(List<ProductStockData> shopStock)
|
private void ReShuffle(List<ProductStockData> shopStock)
|
||||||
{
|
{
|
||||||
displayFlavors = shopStock.ToList();
|
displayFlavors = shopStock.ToList();
|
||||||
shuffledOrder = ShuffleOrder(displayFlavors.Count);
|
shuffledOrder = ShuffleOrder(displayFlavors.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CheckStock(List<ProductStockData> shopStock)
|
public void UpdateShopState()
|
||||||
{
|
{
|
||||||
shopState.Value = shopStock.Count == 0 ? ShopState.Close : ShopState.Open;
|
shopState.Value = ShopStock.Count == 0 ? ShopState.Close : ShopState.Open;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AdClickAction()
|
public void AdClickAction()
|
||||||
|
|
@ -620,14 +620,72 @@ displayFlavors: {displayFlavors.Aggregate("", (s, data) => $"{s},{data.FlavorId}
|
||||||
return customerController;
|
return customerController;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 兄弟モードで在庫がなくなった場合にバイト君に切り替えるためのチェック
|
||||||
|
/// </summary>
|
||||||
|
public void CheckPartTimerMode()
|
||||||
|
{
|
||||||
|
var shopStock = cityGameData.ShopStock.Count;
|
||||||
|
var tankStock = cityGameData.StorageTanks.Sum(x => x.Stock);
|
||||||
|
if (IsLatestCity || shopStock + tankStock > 0)
|
||||||
|
{
|
||||||
|
if (!IsPartTimer) return;
|
||||||
|
ReShuffle(ShopStock);
|
||||||
|
IsPartTimer = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
IsPartTimer = true;
|
||||||
|
// バイト用ダミー生成処理
|
||||||
|
if (dummyStorageTank.Count <= 0) GenerateDummyStock();
|
||||||
|
RefillDummyShopStockData();
|
||||||
|
ReShuffle(ShopStock);
|
||||||
|
UpdateShopState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetLatestCity(bool active) => IsLatestCity = active;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ダミー在庫生成
|
||||||
|
/// ダミータンクが0の場合に入手済みレシピからランダムでフレーバー選ぶ
|
||||||
|
/// 1度の生成で10個(volume), 0になる度に全部で30くらいつくっておく
|
||||||
|
/// </summary>
|
||||||
|
private void GenerateDummyStock()
|
||||||
|
{
|
||||||
|
foreach (var recipeId in globalGameData.MyRecipes.RandomChoose(3))
|
||||||
|
{
|
||||||
|
dummyStorageTank.AddRange(Enumerable.Repeat(new ProductStockData
|
||||||
|
{
|
||||||
|
FlavorId = recipeId,
|
||||||
|
Rarity = ProductRarity.Normal
|
||||||
|
}, 10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefillDummyShopStockData()
|
||||||
|
{
|
||||||
|
var shopSpace = WorldMarketManager.ShopStockCount - ShopStock.Count;
|
||||||
|
var refillCount = Mathf.Min(dummyStorageTank.Count, shopSpace);
|
||||||
|
ShopStock.AddRange(dummyStorageTank.GetRange(0, refillCount));
|
||||||
|
dummyStorageTank.RemoveRange(0, refillCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float GetUsedStorageCapacity()
|
||||||
|
{
|
||||||
|
if (IsPartTimer) return DummyUsedCapacity;
|
||||||
|
var totalCapacity = cityGameData.StorageTanks.Sum(x => x.Capacity);
|
||||||
|
var totalStock = cityGameData.StorageTanks.Sum(x => x.Stock);
|
||||||
|
return (float)totalStock / totalCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Conditional("UNITY_EDITOR"), Conditional("DEVELOPMENT_BUILD")]
|
||||||
private void CheckAndFixStock()
|
private void CheckAndFixStock()
|
||||||
{
|
{
|
||||||
if (GameDataManager.GameData.ShopStock.Count > WorldMarketManager.ShopStockCount)
|
if (ShopStock.Count > WorldMarketManager.ShopStockCount)
|
||||||
{
|
{
|
||||||
GameDataManager.GameData.ShopStock.RemoveRange(0, GameDataManager.GameData.ShopStock.Count - WorldMarketManager.ShopStockCount);
|
ShopStock.RemoveRange(0, ShopStock.Count - WorldMarketManager.ShopStockCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var stockData in GameDataManager.GameData.ShopStock.Where(stockData => stockData.FlavorId < 1))
|
foreach (var stockData in ShopStock.Where(stockData => stockData.FlavorId < 1))
|
||||||
{
|
{
|
||||||
stockData.FlavorId = 1;
|
stockData.FlavorId = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -639,8 +697,8 @@ displayFlavors: {displayFlavors.Aggregate("", (s, data) => $"{s},{data.FlavorId}
|
||||||
/// <param name="newGameData"></param>
|
/// <param name="newGameData"></param>
|
||||||
public void ResetGameData(GameData newGameData)
|
public void ResetGameData(GameData newGameData)
|
||||||
{
|
{
|
||||||
gameData = newGameData;
|
cityGameData = newGameData;
|
||||||
ReShuffle(gameData.ShopStock);
|
ReShuffle(ShopStock);
|
||||||
CheckStock(gameData.ShopStock);
|
UpdateShopState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ public class MarketManager : MonoBehaviour
|
||||||
[SerializeField] private TutorialObjectMask walkerMask;
|
[SerializeField] private TutorialObjectMask walkerMask;
|
||||||
private Market market;
|
private Market market;
|
||||||
List<ProductData> productDataList;
|
List<ProductData> productDataList;
|
||||||
|
private bool isPartTimer;
|
||||||
|
|
||||||
private readonly Subject<Unit> customerRewardTimerUpdateSubject = new Subject<Unit>();
|
private readonly Subject<Unit> customerRewardTimerUpdateSubject = new Subject<Unit>();
|
||||||
private readonly Subject<Unit> vipTimerUpdateSubject = new Subject<Unit>();
|
private readonly Subject<Unit> vipTimerUpdateSubject = new Subject<Unit>();
|
||||||
|
|
@ -38,17 +39,27 @@ public class MarketManager : MonoBehaviour
|
||||||
customerRewardTimerUpdateSubject.AddTo(this);
|
customerRewardTimerUpdateSubject.AddTo(this);
|
||||||
vipTimerUpdateSubject.AddTo(this);
|
vipTimerUpdateSubject.AddTo(this);
|
||||||
market = WorldMarketManager.Instance.GetCurrentCityMarket();
|
market = WorldMarketManager.Instance.GetCurrentCityMarket();
|
||||||
|
market.CheckPartTimerMode();
|
||||||
|
isPartTimer = market.IsPartTimer;
|
||||||
|
|
||||||
SoundManager.Instance.PlayBGM("bgm_marketing");
|
SoundManager.Instance.PlayBGM("bgm_marketing");
|
||||||
var gameData = GameDataManager.GameData;
|
var globalGameData = GameDataManager.GameData;
|
||||||
|
var cityGameData = GameDataManager.GetCurrentCityGameData();
|
||||||
|
|
||||||
// カスタマイズ読み込み
|
// カスタマイズ読み込み
|
||||||
marketView.SetAllItem();
|
marketView.SetAllItem();
|
||||||
stockView = marketView.GetTarget(ShopCustomizeCategory.Category4).GetComponentInChildren<ShopStockView>();
|
stockView = marketView.GetTarget(ShopCustomizeCategory.Category4).GetComponentInChildren<ShopStockView>();
|
||||||
stockView.SetTextActive(true);
|
stockView.SetTextActive(true);
|
||||||
ShopCustomizeCoinManager.Instance.ChangeCoin(gameData.ShopCustomizeCoin);
|
ShopCustomizeCoinManager.Instance.ChangeCoin(globalGameData.ShopCustomizeCoin);
|
||||||
|
|
||||||
|
if (isPartTimer)
|
||||||
|
{
|
||||||
|
partTimerView.StartAnimation();
|
||||||
|
rewardButtonView.gameObject.SetActive(false);
|
||||||
|
vipCustomerButtonView.gameObject.SetActive(false);
|
||||||
|
}
|
||||||
|
|
||||||
if (!gameData.FinishedFlags.HasFlag(TutorialFlag.FirstPlay))
|
if (!globalGameData.FinishedFlags.HasFlag(TutorialFlag.FirstPlay))
|
||||||
{
|
{
|
||||||
if (TutorialManager.Instance.Index == 3)
|
if (TutorialManager.Instance.Index == 3)
|
||||||
{
|
{
|
||||||
|
|
@ -78,7 +89,7 @@ public class MarketManager : MonoBehaviour
|
||||||
.Subscribe(_ => { }, () =>
|
.Subscribe(_ => { }, () =>
|
||||||
{
|
{
|
||||||
// チュートリアル終了
|
// チュートリアル終了
|
||||||
gameData.FinishTutorial();
|
globalGameData.FinishTutorial();
|
||||||
GameDataManager.SaveGameData();
|
GameDataManager.SaveGameData();
|
||||||
walkerMask.gameObject.SetActive(false);
|
walkerMask.gameObject.SetActive(false);
|
||||||
customerRewardTimerUpdateSubject.OnNext(Unit.Default);
|
customerRewardTimerUpdateSubject.OnNext(Unit.Default);
|
||||||
|
|
@ -88,8 +99,8 @@ public class MarketManager : MonoBehaviour
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CoinManager.Instance.ChangeCoin(gameData.Coin);
|
CoinManager.Instance.ChangeCoin(cityGameData.Coin);
|
||||||
HeartMeter.Instance.Initialize(gameData.ViewedShopLevel, gameData.Heart);
|
HeartMeter.Instance.Initialize(globalGameData.ViewedShopLevel, cityGameData.Heart);
|
||||||
|
|
||||||
// ハートゲージがフルかつダイアログが開いていない場合レベルアップ
|
// ハートゲージがフルかつダイアログが開いていない場合レベルアップ
|
||||||
HeartMeter.Instance.FulledHeart
|
HeartMeter.Instance.FulledHeart
|
||||||
|
|
@ -100,14 +111,14 @@ public class MarketManager : MonoBehaviour
|
||||||
.Subscribe(_ =>
|
.Subscribe(_ =>
|
||||||
{
|
{
|
||||||
market.IsPause.Value = true;
|
market.IsPause.Value = true;
|
||||||
ShopLevelUp.ShowDialog(gameData.ViewedShopLevel + 1, () =>
|
ShopLevelUp.ShowDialog(globalGameData.ViewedShopLevel + 1, () =>
|
||||||
{
|
{
|
||||||
market.IsPause.Value = false;
|
market.IsPause.Value = false;
|
||||||
});
|
});
|
||||||
}).AddTo(this);
|
}).AddTo(this);
|
||||||
|
|
||||||
productDataList = SpreadsheetDataManager.Instance.GetBaseDataList<ProductData>(Const.ProductDataSheet);
|
productDataList = SpreadsheetDataManager.Instance.GetBaseDataList<ProductData>(Const.ProductDataSheet);
|
||||||
stockView.SetStock(gameData.StorageTanks);
|
stockView.SetStock(market.GetUsedStorageCapacity());
|
||||||
List<(int, ProductStockData)> startStocks;
|
List<(int, ProductStockData)> startStocks;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -134,8 +145,9 @@ public class MarketManager : MonoBehaviour
|
||||||
{
|
{
|
||||||
vipCustomerButtonView.SetActive(isPause);
|
vipCustomerButtonView.SetActive(isPause);
|
||||||
// 兄弟非表示
|
// 兄弟非表示
|
||||||
blueView.SetActive(!isPause);
|
blueView.SetActive(!isPartTimer && !isPause);
|
||||||
BrotherPinkView.Instance.SetActive(!isPause);
|
BrotherPinkView.Instance.SetActive(!isPartTimer && !isPause);
|
||||||
|
partTimerView.SetActive(isPartTimer && !isPause);
|
||||||
}).AddTo(this);
|
}).AddTo(this);
|
||||||
|
|
||||||
// 宣伝ボタン
|
// 宣伝ボタン
|
||||||
|
|
@ -144,11 +156,11 @@ public class MarketManager : MonoBehaviour
|
||||||
GetRewardDialog.ShowIncreaseCustomerDialog(() =>
|
GetRewardDialog.ShowIncreaseCustomerDialog(() =>
|
||||||
{
|
{
|
||||||
market.AdClickAction();
|
market.AdClickAction();
|
||||||
gameData.increaseCustomerTime = DateTime.UtcNow.AddSeconds(refreshWaitTime).ToBinary();
|
globalGameData.increaseCustomerTime = DateTime.UtcNow.AddSeconds(refreshWaitTime).ToBinary();
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
gameData.increaseCustomerTime = DateTime.UtcNow.AddSeconds(10).ToBinary();
|
globalGameData.increaseCustomerTime = DateTime.UtcNow.AddSeconds(10).ToBinary();
|
||||||
#endif
|
#endif
|
||||||
gameData.AddUseAdWalker();
|
cityGameData.AddUseAdWalker();
|
||||||
GameDataManager.SaveGameData();
|
GameDataManager.SaveGameData();
|
||||||
customerRewardTimerUpdateSubject.OnNext(Unit.Default);
|
customerRewardTimerUpdateSubject.OnNext(Unit.Default);
|
||||||
});
|
});
|
||||||
|
|
@ -161,38 +173,37 @@ public class MarketManager : MonoBehaviour
|
||||||
{
|
{
|
||||||
market.VipAction();
|
market.VipAction();
|
||||||
// 現在時刻に設定して期限切れにする
|
// 現在時刻に設定して期限切れにする
|
||||||
gameData.vipCustomerLimitTime = DateTime.UtcNow.ToBinary();
|
globalGameData.vipCustomerLimitTime = DateTime.UtcNow.ToBinary();
|
||||||
vipTimerUpdateSubject.OnNext(Unit.Default);
|
vipTimerUpdateSubject.OnNext(Unit.Default);
|
||||||
}, () =>
|
}, () =>
|
||||||
{
|
{
|
||||||
// 現在時刻に設定して期限切れにする
|
// 現在時刻に設定して期限切れにする
|
||||||
gameData.vipCustomerLimitTime = DateTime.UtcNow.ToBinary();
|
globalGameData.vipCustomerLimitTime = DateTime.UtcNow.ToBinary();
|
||||||
vipTimerUpdateSubject.OnNext(Unit.Default);
|
vipTimerUpdateSubject.OnNext(Unit.Default);
|
||||||
});
|
});
|
||||||
}).AddTo(this);
|
}).AddTo(this);
|
||||||
|
|
||||||
// onNextをトリガーに実行
|
// onNextをトリガーに実行
|
||||||
customerRewardTimerUpdateSubject
|
customerRewardTimerUpdateSubject
|
||||||
.Select(_ => (int) DateTime.FromBinary(gameData.increaseCustomerTime).Subtract(DateTime.UtcNow).TotalSeconds)
|
.StartWith()
|
||||||
|
.Select(_ => (int) DateTime.FromBinary(globalGameData.increaseCustomerTime).Subtract(DateTime.UtcNow).TotalSeconds)
|
||||||
.Subscribe(time =>
|
.Subscribe(time =>
|
||||||
{
|
{
|
||||||
rewardButtonView.ResetTimer(time);
|
rewardButtonView.ResetTimer(time);
|
||||||
}).AddTo(this);
|
}).AddTo(this);
|
||||||
|
|
||||||
if (DateTime.FromBinary(gameData.vipCustomerLimitTime) >= DateTime.UtcNow)
|
if (DateTime.FromBinary(globalGameData.vipCustomerLimitTime) >= DateTime.UtcNow)
|
||||||
{
|
{
|
||||||
vipCustomerButtonView.ShowButton(gameData.vipCustomerFirstOpen);
|
vipCustomerButtonView.ShowButton(globalGameData.vipCustomerFirstOpen);
|
||||||
gameData.vipCustomerFirstOpen = false;
|
globalGameData.vipCustomerFirstOpen = false;
|
||||||
vipTimerUpdateSubject
|
vipTimerUpdateSubject
|
||||||
.Select(_ => (int) DateTime.FromBinary(gameData.vipCustomerLimitTime).Subtract(DateTime.UtcNow).TotalSeconds)
|
.StartWith()
|
||||||
|
.Select(_ => (int) DateTime.FromBinary(globalGameData.vipCustomerLimitTime).Subtract(DateTime.UtcNow).TotalSeconds)
|
||||||
.Subscribe(time =>
|
.Subscribe(time =>
|
||||||
{
|
{
|
||||||
vipCustomerButtonView.ResetTimer(time);
|
vipCustomerButtonView.ResetTimer(time);
|
||||||
}).AddTo(this);
|
}).AddTo(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
customerRewardTimerUpdateSubject.OnNext(Unit.Default);
|
|
||||||
vipTimerUpdateSubject.OnNext(Unit.Default);
|
|
||||||
|
|
||||||
// アプリ復帰時に残り時間更新
|
// アプリ復帰時に残り時間更新
|
||||||
Observable.EveryApplicationPause()
|
Observable.EveryApplicationPause()
|
||||||
|
|
@ -222,11 +233,12 @@ public class MarketManager : MonoBehaviour
|
||||||
market.SellObservable.Subscribe(coin =>
|
market.SellObservable.Subscribe(coin =>
|
||||||
{
|
{
|
||||||
// コイン獲得エフェクト
|
// コイン獲得エフェクト
|
||||||
|
blueView.SellAction();
|
||||||
|
if (coin == 0) return;
|
||||||
CoinEffect(coin, pos =>
|
CoinEffect(coin, pos =>
|
||||||
{
|
{
|
||||||
CoinManager.Instance.AddCoinWithEffect(coin, pos);
|
CoinManager.Instance.AddCoinWithEffect(coin, pos);
|
||||||
});
|
});
|
||||||
blueView.SellAction();
|
|
||||||
}).AddTo(this);
|
}).AddTo(this);
|
||||||
|
|
||||||
market.SellOrderSubject.Subscribe(orders =>
|
market.SellOrderSubject.Subscribe(orders =>
|
||||||
|
|
@ -240,37 +252,32 @@ public class MarketManager : MonoBehaviour
|
||||||
|
|
||||||
market.RefillSubject.Subscribe(x =>
|
market.RefillSubject.Subscribe(x =>
|
||||||
{
|
{
|
||||||
stockView.SetStock(gameData.StorageTanks);
|
stockView.SetStock(market.GetUsedStorageCapacity());
|
||||||
if (x.isReorder)
|
if (x.isReorder)
|
||||||
{
|
{
|
||||||
// 陳列表示更新(陳列13=650ms,7=350ms)
|
// 陳列表示更新(陳列13=650ms,7=350ms)
|
||||||
var stocks = market.ShuffledOrder.Select(i => (i, market.DisplayFlavors[i])).ToList();
|
var stocks = market.ShuffledOrder.Select(i => (i, market.DisplayFlavors[i])).ToList();
|
||||||
cartView.SetStock(stocks, true);
|
cartView.SetStock(stocks, true);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
var isError = false;
|
|
||||||
// 補充したフレーバーのスキンを設定
|
|
||||||
foreach (var order in x.refillList)
|
|
||||||
{
|
|
||||||
if (order >= market.DisplayFlavors.Count)
|
|
||||||
{
|
|
||||||
isError = true;
|
|
||||||
Debug.LogError($@"mismatch order:{order}, displayFlavors:{market.DisplayFlavors.Count}");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
cartView.Refill(order, market.DisplayFlavors[order]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isError)
|
// 補充したフレーバーのスキンを設定
|
||||||
|
foreach (var order in x.refillList)
|
||||||
|
{
|
||||||
|
if (order >= market.DisplayFlavors.Count)
|
||||||
{
|
{
|
||||||
Debug.LogError($@"list
|
continue;
|
||||||
shopStock: {gameData.ShopStock.Aggregate("", (s, data) => $"{s},{data.FlavorId}")}
|
}
|
||||||
|
cartView.Refill(order, market.DisplayFlavors[order]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNITY_EDITOR || DEVELOPMENT_BUILD
|
||||||
|
if (x.refillList.DefaultIfEmpty().Max() < market.DisplayFlavors.Count) return;
|
||||||
|
Debug.LogError($@"list
|
||||||
displayFlavors: {market.DisplayFlavors.Aggregate("", (s, data) => $"{s},{data.FlavorId}")}
|
displayFlavors: {market.DisplayFlavors.Aggregate("", (s, data) => $"{s},{data.FlavorId}")}
|
||||||
refillList: {x.refillList.Aggregate("", (s, order) => $"{s},{order}")}");
|
refillList: {x.refillList.Aggregate("", (s, order) => $"{s},{order}")}");
|
||||||
throw new Exception("RefillList Invalid");
|
throw new Exception("RefillList Invalid");
|
||||||
}
|
#endif
|
||||||
}
|
|
||||||
}).AddTo(this);
|
}).AddTo(this);
|
||||||
|
|
||||||
// 開閉店
|
// 開閉店
|
||||||
|
|
@ -281,58 +288,66 @@ displayFlavors: {market.DisplayFlavors.Aggregate("", (s, data) => $"{s},{data.Fl
|
||||||
}).AddTo(this);
|
}).AddTo(this);
|
||||||
|
|
||||||
// 試食看板はStart時非表示
|
// 試食看板はStart時非表示
|
||||||
signBoardView.SetActiveTastingBoard(false);
|
// signBoardView.SetActiveTastingBoard(false);
|
||||||
|
|
||||||
// 宣伝ボタン/試食表示切替
|
// 宣伝ボタン/試食表示切替
|
||||||
var tastingComplete = new Subject<Unit>().AddTo(this);
|
var tastingComplete = new Subject<Unit>().AddTo(this);
|
||||||
|
IDisposable tastingDisposable = null;
|
||||||
market.CurrentShopState
|
market.CurrentShopState
|
||||||
.SkipWhile(_ => !gameData.FinishedFlags.HasFlag(TutorialFlag.FirstPlay))
|
.SkipWhile(_ => !globalGameData.FinishedFlags.HasFlag(TutorialFlag.FirstPlay))
|
||||||
.CombineLatest(market.IsPromotion, tastingComplete, (shopState, isPromotion, _) => (shopState == ShopState.Open, isPromotion))
|
.CombineLatest(market.IsPromotion, tastingComplete, (shopState, isPromotion, _) => (shopState == ShopState.Close, isPromotion))
|
||||||
.Subscribe(x =>
|
.Subscribe(x =>
|
||||||
{
|
{
|
||||||
var (isOpen, isPromotion) = x;
|
var (isClose, isPromotion) = x;
|
||||||
if (isOpen)
|
if (isClose || isPartTimer)
|
||||||
{
|
{
|
||||||
if (isPromotion)
|
BrotherPinkView.Instance.StopTasting();
|
||||||
{
|
rewardButtonView.gameObject.SetActive(false);
|
||||||
signBoardView.SetActiveTastingBoard(false);
|
// signBoardView.CancelTasting();
|
||||||
// 宣伝ボタン表示
|
tastingDisposable?.Dispose();
|
||||||
rewardButtonView.gameObject.SetActive(true);
|
|
||||||
BrotherPinkView.Instance.StartPromotion();
|
// VIP宣伝を非表示
|
||||||
}
|
globalGameData.vipCustomerLimitTime = DateTime.UtcNow.ToBinary();
|
||||||
else if (gameData.TastingCount > 0)
|
vipTimerUpdateSubject.OnNext(Unit.Default);
|
||||||
{
|
return;
|
||||||
rewardButtonView.gameObject.SetActive(false);
|
}
|
||||||
// 試食表示
|
if (isPromotion)
|
||||||
signBoardView.SetActiveTastingBoard(true);
|
{
|
||||||
BrotherPinkView.Instance.StartTasting();
|
// signBoardView.SetActiveTastingBoard(false);
|
||||||
BrotherPinkView.Instance.SetTastingCount(gameData.TastingCount);
|
// 宣伝ボタン表示
|
||||||
signBoardView.SetTimer(gameData.TastingCount * (int)market.TastingCustomerInterval, () =>
|
rewardButtonView.gameObject.SetActive(true);
|
||||||
{
|
BrotherPinkView.Instance.StartPromotion();
|
||||||
BrotherPinkView.Instance.SetTastingCount(gameData.TastingCount);
|
return;
|
||||||
}, () =>
|
}
|
||||||
|
if (cityGameData.TastingCount > 0)
|
||||||
|
{
|
||||||
|
rewardButtonView.gameObject.SetActive(false);
|
||||||
|
// 試食表示
|
||||||
|
// signBoardView.SetActiveTastingBoard(true);
|
||||||
|
BrotherPinkView.Instance.StartTasting();
|
||||||
|
BrotherPinkView.Instance.SetTastingCount(cityGameData.TastingCount);
|
||||||
|
var remaining = cityGameData.TastingCount * (int)market.TastingCustomerInterval;
|
||||||
|
tastingDisposable = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1f))
|
||||||
|
.TakeWhile(x => (int)(remaining - x) >= 0)
|
||||||
|
.Subscribe(_ => BrotherPinkView.Instance.SetTastingCount(cityGameData.TastingCount), () =>
|
||||||
{
|
{
|
||||||
// 試食タイマーが終わったら表示更新トリガー
|
// 試食タイマーが終わったら表示更新トリガー
|
||||||
tastingComplete.OnNext(Unit.Default);
|
tastingComplete.OnNext(Unit.Default);
|
||||||
BrotherPinkView.Instance.StopTasting();
|
BrotherPinkView.Instance.StopTasting();
|
||||||
});
|
}).AddTo(this);
|
||||||
}
|
// signBoardView.SetTimer(gameData.TastingCount * (int)market.TastingCustomerInterval,
|
||||||
else // 宣伝も試食も未発動
|
// () => { BrotherPinkView.Instance.SetTastingCount(gameData.TastingCount); }, () =>
|
||||||
{
|
// {
|
||||||
BrotherPinkView.Instance.StopTasting();
|
// // 試食タイマーが終わったら表示更新トリガー
|
||||||
rewardButtonView.gameObject.SetActive(true);
|
// tastingComplete.OnNext(Unit.Default);
|
||||||
}
|
// BrotherPinkView.Instance.StopTasting();
|
||||||
}
|
// });
|
||||||
else // 閉店
|
return;
|
||||||
{
|
|
||||||
BrotherPinkView.Instance.StopTasting();
|
|
||||||
rewardButtonView.gameObject.SetActive(false);
|
|
||||||
signBoardView.CancelTasting();
|
|
||||||
|
|
||||||
// VIP宣伝を非表示
|
|
||||||
gameData.vipCustomerLimitTime = DateTime.UtcNow.ToBinary();
|
|
||||||
vipTimerUpdateSubject.OnNext(Unit.Default);
|
|
||||||
}
|
}
|
||||||
|
// 宣伝も試食も未発動
|
||||||
|
BrotherPinkView.Instance.StopTasting();
|
||||||
|
rewardButtonView.gameObject.SetActive(true);
|
||||||
|
|
||||||
}).AddTo(this);
|
}).AddTo(this);
|
||||||
// CombineLatest動かすのに必要
|
// CombineLatest動かすのに必要
|
||||||
tastingComplete.OnNext(Unit.Default);
|
tastingComplete.OnNext(Unit.Default);
|
||||||
|
|
@ -462,6 +477,7 @@ displayFlavors: {market.DisplayFlavors.Aggregate("", (s, data) => $"{s},{data.Fl
|
||||||
}).AddTo(customerAnimator);
|
}).AddTo(customerAnimator);
|
||||||
var eventTrigger = customerAnimator.gameObject.AddComponent<ObservableEventTrigger>();
|
var eventTrigger = customerAnimator.gameObject.AddComponent<ObservableEventTrigger>();
|
||||||
eventTrigger.OnPointerClickAsObservable()
|
eventTrigger.OnPointerClickAsObservable()
|
||||||
|
.Where(_ => !isPartTimer)
|
||||||
.Take(1)
|
.Take(1)
|
||||||
.Subscribe(_ =>
|
.Subscribe(_ =>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,10 @@ public class ShopStockView : MonoBehaviour
|
||||||
textObject.SetActive(false);
|
textObject.SetActive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetStock(List<StorageTank> tanks)
|
public void SetStock(float value)
|
||||||
{
|
{
|
||||||
var totalCapacity = tanks.Sum(x => x.Capacity);
|
|
||||||
var totalStock = tanks.Sum(x => x.Stock);
|
|
||||||
var newPos = popcornImage.transform.localPosition;
|
var newPos = popcornImage.transform.localPosition;
|
||||||
newPos.y = Mathf.Lerp(minPosision, maxPosision, (float) totalStock / totalCapacity);
|
newPos.y = Mathf.Lerp(minPosision, maxPosision, value);
|
||||||
popcornImage.transform.localPosition = newPos;
|
popcornImage.transform.localPosition = newPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using MyGame.Scripts;
|
||||||
using UniRx;
|
using UniRx;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Debug = UnityEngine.Debug;
|
||||||
|
|
||||||
namespace MyGame.Scenes.marketing.Scripts
|
namespace MyGame.Scenes.marketing.Scripts
|
||||||
{
|
{
|
||||||
|
|
@ -19,18 +22,63 @@ namespace MyGame.Scenes.marketing.Scripts
|
||||||
private readonly Dictionary<int, Market> cityMarketDict = new();
|
private readonly Dictionary<int, Market> cityMarketDict = new();
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
var newGameData = GameDataUtils.CreateCityData(2);
|
||||||
|
newGameData.IsFundingCompleted = true;
|
||||||
|
newGameData.Heart = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// 各都市マーケット生成
|
||||||
|
var latestCityId = GameDataUtils.GetLatestCityId();
|
||||||
|
CreateMarket(Const.DefaultCityId).CheckPartTimerMode();
|
||||||
|
foreach (var (cityId, gameData) in GameDataManager.GameData.CityGameDataDict)
|
||||||
|
{
|
||||||
|
if (!gameData.IsFundingCompleted) return;
|
||||||
|
var market = CreateMarket(cityId);
|
||||||
|
market.CheckPartTimerMode();
|
||||||
|
market.SetLatestCity(cityId == latestCityId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Market CreateMarket(int cityId)
|
||||||
|
{
|
||||||
var market = Instantiate(marketPrefab, transform);
|
var market = Instantiate(marketPrefab, transform);
|
||||||
cityMarketDict.Add(Const.DefaultCityId, market);
|
market.Initialize(cityId);
|
||||||
|
cityMarketDict.Add(cityId, market);
|
||||||
|
return market;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Market GetMarket(int cityId)
|
public Market GetMarket(int cityId)
|
||||||
{
|
{
|
||||||
return cityMarketDict[Const.DefaultCityId];
|
return cityMarketDict[cityId];
|
||||||
}
|
}
|
||||||
|
|
||||||
public Market GetCurrentCityMarket()
|
public Market GetCurrentCityMarket()
|
||||||
{
|
{
|
||||||
return cityMarketDict[Const.DefaultCityId];
|
return cityMarketDict[GameDataManager.GameData.CurrentCityId];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 選択中の都市と、最新の都市以外のMarketの動きを止める
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="currentCityId"></param>
|
||||||
|
public void UpdateCurrentCity(int currentCityId)
|
||||||
|
{
|
||||||
|
var latestCityId = GameDataUtils.GetLatestCityId();
|
||||||
|
foreach (var (cityId, market) in cityMarketDict)
|
||||||
|
{
|
||||||
|
if (cityId == currentCityId || cityId == latestCityId)
|
||||||
|
{
|
||||||
|
market.IsPause.Value = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
market.IsPause.Value = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetActiveMarket(int cityId, bool active)
|
||||||
|
{
|
||||||
|
cityMarketDict[cityId].IsPause.Value = !active;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -39,7 +87,10 @@ namespace MyGame.Scenes.marketing.Scripts
|
||||||
/// <param name="bonusList"></param>
|
/// <param name="bonusList"></param>
|
||||||
public void UpdateBonus(Dictionary<ShopCustomizeBonusCategory, (int bonusLevel, int value)> bonusList)
|
public void UpdateBonus(Dictionary<ShopCustomizeBonusCategory, (int bonusLevel, int value)> bonusList)
|
||||||
{
|
{
|
||||||
cityMarketDict[Const.DefaultCityId].UpdateBonus(bonusList);
|
foreach (var (_, market) in cityMarketDict)
|
||||||
|
{
|
||||||
|
market.UpdateBonus(bonusList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetGameData(GameData gameData)
|
public void ResetGameData(GameData gameData)
|
||||||
|
|
@ -47,6 +98,7 @@ namespace MyGame.Scenes.marketing.Scripts
|
||||||
cityMarketDict[Const.DefaultCityId].ResetGameData(gameData);
|
cityMarketDict[Const.DefaultCityId].ResetGameData(gameData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Conditional("UNITY_EDITOR"), Conditional("DEVELOPMENT_BUILD")]
|
||||||
public static void StockFlavorLog(int cityId = -1)
|
public static void StockFlavorLog(int cityId = -1)
|
||||||
{
|
{
|
||||||
if (GameDataManager.GetCityGameData(cityId) is not {} cityGameData)
|
if (GameDataManager.GetCityGameData(cityId) is not {} cityGameData)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue