Merge branch 'develop' of bitbucket.org:usaya/popcorn into develop
This commit is contained in:
commit
3fbb294d94
|
|
@ -21,7 +21,6 @@ public enum CustomerMovingType
|
|||
public enum CustomerState
|
||||
{
|
||||
Walk,
|
||||
Want,
|
||||
Wait,
|
||||
Order,
|
||||
Leave,
|
||||
|
|
@ -76,12 +75,12 @@ public class CustomerController : MonoBehaviour
|
|||
private float walkSideDirection;
|
||||
public IReadOnlyReactiveProperty<CustomerMovingType> MoveEndObservable => moveEndSubject;
|
||||
private readonly ReactiveProperty<CustomerMovingType> moveEndSubject = new ReactiveProperty<CustomerMovingType>();
|
||||
public IReadOnlyReactiveProperty<CustomerState> CustomerState => customerState;
|
||||
private readonly ReactiveProperty<CustomerState> customerState = new ReactiveProperty<CustomerState>();
|
||||
public IReadOnlyReactiveProperty<CustomerState> State => state;
|
||||
private readonly ReactiveProperty<CustomerState> state = new ReactiveProperty<CustomerState>();
|
||||
|
||||
private void Start()
|
||||
{
|
||||
customerState.AddTo(this);
|
||||
state.AddTo(this);
|
||||
durationDelta = 0f;
|
||||
this.UpdateAsObservable().Subscribe(_ =>
|
||||
{
|
||||
|
|
@ -118,43 +117,42 @@ public class CustomerController : MonoBehaviour
|
|||
|
||||
public void ChangeCustomerState(CustomerState state)
|
||||
{
|
||||
customerState.Value = state;
|
||||
this.state.Value = state;
|
||||
Debug.Log(state);
|
||||
switch (state)
|
||||
{
|
||||
case global::CustomerState.Walk:
|
||||
case CustomerState.Walk:
|
||||
SetMove(CustomerMovingType.WalkCenter);
|
||||
// 数秒立ち止まる
|
||||
AddMove(CustomerMovingType.StayBackLook, 2f);
|
||||
AddMove(CustomerMovingType.WalkSide);
|
||||
break;
|
||||
case global::CustomerState.Want:
|
||||
// 店に向かう
|
||||
case CustomerState.Wait:
|
||||
// 店に向かう&順番待ち
|
||||
// 近くの場合その場に待機
|
||||
// まだ遠い場合待機場所に移動
|
||||
moves.Clear();
|
||||
if (currentMovingType == CustomerMovingType.StayBackLook)
|
||||
{
|
||||
SetMove(CustomerMovingType.WalkBackHalf);
|
||||
break;
|
||||
}
|
||||
SetMove(CustomerMovingType.WalkCenter);
|
||||
break;
|
||||
case global::CustomerState.Wait:
|
||||
// 順番待ち
|
||||
// 近くの場合その場に待機
|
||||
// まだ遠い場合待機場所に移動
|
||||
AddMove(CustomerMovingType.WalkBackHalf);
|
||||
else
|
||||
{
|
||||
SetMove(CustomerMovingType.WalkCenter);
|
||||
AddMove(CustomerMovingType.WalkBackHalf);
|
||||
}
|
||||
AddMove(CustomerMovingType.StayBackLook);
|
||||
break;
|
||||
case global::CustomerState.Order:
|
||||
case CustomerState.Order:
|
||||
// 受付まで行く
|
||||
AddMove(CustomerMovingType.WalkBack);
|
||||
AddMove(CustomerMovingType.StayBack);
|
||||
break;
|
||||
case global::CustomerState.Leave:
|
||||
case CustomerState.Leave:
|
||||
moves.Clear();
|
||||
SetMove(CustomerMovingType.WalkSide);
|
||||
break;
|
||||
case global::CustomerState.EatingLeave:
|
||||
case CustomerState.EatingLeave:
|
||||
AddMove(CustomerMovingType.WalkFrontEat);
|
||||
AddMove(CustomerMovingType.WalkSideEat);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ public class Market : MonoBehaviour
|
|||
private ReactiveProperty<ShopState> shopState = new ReactiveProperty<ShopState>();
|
||||
private ReactiveCollection<CustomerController> waitCustomerList = new ReactiveCollection<CustomerController>();
|
||||
private Subject<CustomerController> requestSubject = new Subject<CustomerController>();
|
||||
private Subject<Unit> orderSubject = new Subject<Unit>();
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
|
|
@ -36,6 +37,7 @@ public class Market : MonoBehaviour
|
|||
shopState.AddTo(this);
|
||||
waitCustomerList.AddTo(this);
|
||||
requestSubject.AddTo(this);
|
||||
orderSubject.AddTo(this);
|
||||
|
||||
var gameData = GameDataManager.GameData;
|
||||
CoinManager.Instance.ChangeCoin(gameData.coin);
|
||||
|
|
@ -65,7 +67,8 @@ public class Market : MonoBehaviour
|
|||
};
|
||||
|
||||
HeartMeter.Instance.Initialize(shopLevelList.Select(x => x.heart).ToList());
|
||||
HeartMeter.Instance.SetHeart(15);
|
||||
HeartMeter.Instance.SetHeart(gameData.Heart);
|
||||
HeartMeter.Instance.SetHeart(99999);
|
||||
|
||||
// 在庫数表示
|
||||
stockView.SetStock(gameData.StorageTanks);
|
||||
|
|
@ -83,54 +86,63 @@ public class Market : MonoBehaviour
|
|||
// お店の状態設定
|
||||
shopState.Value = gameData.ShopStock.Count == 0 ? ShopState.Close : ShopState.Open;
|
||||
|
||||
// 購入リクエスト
|
||||
shopState
|
||||
.Where(x => x == ShopState.Open)
|
||||
.Where(_ => waitCustomerList.Count > 0)
|
||||
.Select(_ => waitCustomerList[0])
|
||||
.Merge(waitCustomerList.ObserveAdd().Select(x => x.Value))
|
||||
.BatchFrame()
|
||||
.Select(x => x.RandomChoose()) // 同時にリクエストが有った場合1人選ぶ
|
||||
.Where(_ => shopState.Value == ShopState.Open) // 他に購入中の客がいないことを確認
|
||||
.Subscribe(x =>
|
||||
{
|
||||
Debug.Log($"RequestComfirmed");
|
||||
waitCustomerList.Remove(x);
|
||||
// 購入へ
|
||||
x.ChangeCustomerState(CustomerState.Order);
|
||||
shopState.Value = ShopState.Busy;
|
||||
}).AddTo(this);
|
||||
|
||||
// お客さん一覧
|
||||
var customerList = new ReactiveCollection<CustomerController>();
|
||||
customerList.AddTo(this);
|
||||
|
||||
// 購入リクエスト
|
||||
orderSubject
|
||||
.Merge(waitCustomerList.ObserveAdd().AsUnitObservable())
|
||||
.Merge(shopState.Where(x => x == ShopState.Open).AsUnitObservable())
|
||||
.Where(_ => shopState.Value == ShopState.Open)
|
||||
.BatchFrame()
|
||||
.Where(_ => waitCustomerList.Count > 0)
|
||||
.SelectMany(_ => waitCustomerList.ToList().GetRange(0, Mathf.Min(3, waitCustomerList.Count)))
|
||||
.Subscribe(customer =>
|
||||
{
|
||||
Debug.Log($"aa order:{customerList.Count(x => x.State.Value == CustomerState.Order)} Request {Time.time} {customer.GetHashCode()}");
|
||||
if (customerList.Count(x => x.State.Value == CustomerState.Order) >= 3)
|
||||
{
|
||||
shopState.Value = ShopState.Busy;
|
||||
return;
|
||||
}
|
||||
waitCustomerList.Remove(customer);
|
||||
// 購入へ
|
||||
customer.ChangeCustomerState(CustomerState.Order);
|
||||
}).AddTo(this);
|
||||
|
||||
// 購入客
|
||||
customerList.ObserveAdd()
|
||||
.Select(x => x.Value)
|
||||
.Subscribe(customerController =>
|
||||
{
|
||||
customerController.State.Subscribe(c =>
|
||||
{
|
||||
if (c == CustomerState.EatingLeave)
|
||||
{
|
||||
Debug.Log($"aa order:{customerList.Count(x => x.State.Value == CustomerState.Order)} EatingLeave");
|
||||
orderSubject.OnNext(default);
|
||||
}
|
||||
}).AddTo(customerController);
|
||||
// 店に向かう
|
||||
customerController.ChangeCustomerState(CustomerState.Want);
|
||||
waitCustomerList.Add(customerController);
|
||||
|
||||
customerController.ChangeCustomerState(CustomerState.Wait);
|
||||
shopState.Subscribe(x =>
|
||||
{
|
||||
switch (x)
|
||||
{
|
||||
case ShopState.Open:
|
||||
break;
|
||||
case ShopState.Busy:
|
||||
// 自分が購入中
|
||||
if (customerController.CustomerState.Value == CustomerState.Order)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// 待機
|
||||
customerController.ChangeCustomerState(CustomerState.Wait);
|
||||
break;
|
||||
case ShopState.Close:
|
||||
// 売り切れの場合帰る
|
||||
customerController.ChangeCustomerState(CustomerState.Leave);
|
||||
if (customerController.State.Value == CustomerState.Order)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.CallWaitForSeconds(Random.Range(0f, .4f), () =>
|
||||
{
|
||||
customerController.ChangeCustomerState(CustomerState.Leave);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(x), x, null);
|
||||
|
|
@ -138,70 +150,120 @@ public class Market : MonoBehaviour
|
|||
}).AddTo(customerController);
|
||||
}).AddTo(this);
|
||||
|
||||
requestSubject.Subscribe(customerController =>
|
||||
requestSubject.BatchFrame(30, FrameCountType.Update).Subscribe(customers =>
|
||||
{
|
||||
// 売り切れ
|
||||
if (gameData.ShopStock.Count == 0)
|
||||
{
|
||||
shopState.Value = ShopState.Close;
|
||||
}
|
||||
var coin = 0;
|
||||
var orders = new List<int>();
|
||||
var dontBuyCustomerList = new List<CustomerController>();
|
||||
foreach (var controller in customers)
|
||||
{
|
||||
Debug.Log(shuffledOrder.Aggregate("", (s, i) => $"{s},{i}"));
|
||||
// 売り切れ
|
||||
if (shuffledOrder.Count == 0)
|
||||
{
|
||||
controller.ChangeCustomerState(CustomerState.Leave);
|
||||
dontBuyCustomerList.Add(controller);
|
||||
break;
|
||||
}
|
||||
|
||||
// オーダー数
|
||||
var orderCount = Random.Range(1,5);
|
||||
// 在庫取得
|
||||
var tmpOrderCount = Mathf.Min(orderCount, shuffledOrder.Count);
|
||||
// shuffledOrder順に販売
|
||||
orders.AddRange(shuffledOrder.GetRange(0, tmpOrderCount));
|
||||
shuffledOrder.RemoveRange(0, tmpOrderCount);
|
||||
|
||||
// コーンの味吹き出しを設定(レア度優先など
|
||||
controller.ChangeWantFlavor(displayFlavors[orders.RandomChoose()]);
|
||||
}
|
||||
foreach (var customerController in dontBuyCustomerList)
|
||||
{
|
||||
customers.Remove(customerController);
|
||||
}
|
||||
if (orders.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// shuffledOrder順に販売
|
||||
Debug.Log(shuffledOrder.Aggregate("", (s, i) => s + i));
|
||||
var orderNum = shuffledOrder[0];
|
||||
shuffledOrder.RemoveAt(0);
|
||||
// コーンの味吹き出しを設定
|
||||
customerController.ChangeWantFlavor(displayFlavors[orderNum]);
|
||||
|
||||
// 購入
|
||||
var flavors = orders.Select(x => (displayFlavors[x], 0)).ToList();
|
||||
coin += SellPopcorn(flavors);
|
||||
var remainStockCount = gameData.ShopStock.Count;
|
||||
|
||||
// 自動補充 refill
|
||||
RefillProduct();
|
||||
StockFlavorLog();
|
||||
|
||||
// 補充された場合フレーバー再設定
|
||||
var setStockFlag = false;
|
||||
if (gameData.ShopStock.Count == ShopStockCount)
|
||||
{
|
||||
shuffledOrder.AddRange(orders);
|
||||
Debug.Log($"remain {remainStockCount}, order {orders.Count}");
|
||||
var stock = gameData.ShopStock.GetRange(remainStockCount, orders.Count).ToArray();
|
||||
for (int i = 0; i < orders.Count; i++)
|
||||
{
|
||||
displayFlavors[orders[i]] = stock[i];
|
||||
}
|
||||
}
|
||||
else if (gameData.ShopStock.Count <= 13 && shuffledOrder.Exists(x => x > 13))
|
||||
{
|
||||
displayFlavors = gameData.ShopStock.Select(x => x).ToList();
|
||||
shuffledOrder = ShuffleOrder(displayFlavors.Count);
|
||||
setStockFlag = true;
|
||||
}
|
||||
else if (gameData.ShopStock.Count <= 7 && shuffledOrder.Exists(x => x > 7))
|
||||
{
|
||||
displayFlavors = gameData.ShopStock.Select(x => x).ToList();
|
||||
shuffledOrder = ShuffleOrder(displayFlavors.Count);
|
||||
setStockFlag = true;
|
||||
}
|
||||
|
||||
this.CallWaitForSeconds(1.5f, () =>
|
||||
{
|
||||
// 購入
|
||||
SellPopcorn(orderNum);
|
||||
foreach (var order in orders)
|
||||
{
|
||||
cartView.SellStock(order);
|
||||
}
|
||||
blueView.SellAction();
|
||||
// 自動補充 refill
|
||||
RefillOneProduct();
|
||||
StockFlavorLog();
|
||||
var setStockFlag = false;
|
||||
// 補充された場合フレーバー再設定
|
||||
if (gameData.ShopStock.Count == ShopStockCount)
|
||||
{
|
||||
shuffledOrder.Add(orderNum);
|
||||
displayFlavors[orderNum] = gameData.ShopStock.Last();
|
||||
}
|
||||
else if (gameData.ShopStock.Count <= 13 && shuffledOrder.Exists(x => x > 13))
|
||||
{
|
||||
displayFlavors = gameData.ShopStock.Select(x => x).ToList();
|
||||
shuffledOrder = ShuffleOrder(displayFlavors.Count);
|
||||
setStockFlag = true;
|
||||
}
|
||||
else if (gameData.ShopStock.Count <= 7 && shuffledOrder.Exists(x => x > 7))
|
||||
{
|
||||
displayFlavors = gameData.ShopStock.Select(x => x).ToList();
|
||||
shuffledOrder = ShuffleOrder(displayFlavors.Count);
|
||||
setStockFlag = true;
|
||||
}
|
||||
// コイン獲得
|
||||
CoinManager.Instance.AddCoinWithEffect(coin, () => { });
|
||||
gameData.coin = CoinManager.Instance.OwnCoin;
|
||||
gameData.Heart += customers.Count;
|
||||
GameDataManager.SaveGameData();
|
||||
shopState.Value = gameData.ShopStock.Count == 0 ? ShopState.Close : ShopState.Open;
|
||||
|
||||
// 表示更新
|
||||
// 表示更新(陳列13=650ms,7=350ms)
|
||||
this.CallWaitForSeconds(1f, () =>
|
||||
{
|
||||
var heartAnimation = customerController.GetComponent<HeartAnimation>();
|
||||
heartAnimation.GetHeart(() =>
|
||||
foreach (var customerController in customers)
|
||||
{
|
||||
HeartMeter.Instance.AddHeart(3);
|
||||
});
|
||||
customerController.ChangeCustomerState(CustomerState.EatingLeave);
|
||||
|
||||
var heartAnimation = customerController.GetComponent<HeartAnimation>();
|
||||
heartAnimation.GetHeart(() =>
|
||||
{
|
||||
HeartMeter.Instance.AddHeart(1);
|
||||
});
|
||||
customerController.ChangeCustomerState(CustomerState.EatingLeave);
|
||||
}
|
||||
stockView.SetStock(gameData.StorageTanks);
|
||||
if (gameData.ShopStock.Count == ShopStockCount)
|
||||
{
|
||||
// 補充したフレーバーのスキンを設定
|
||||
cartView.Refill(orderNum, displayFlavors[orderNum]);
|
||||
foreach (var order in orders)
|
||||
{
|
||||
cartView.Refill(order, displayFlavors[order]);
|
||||
}
|
||||
}
|
||||
else if (setStockFlag)
|
||||
{
|
||||
cartView.SetStock(displayFlavors);
|
||||
}
|
||||
});
|
||||
shopState.Value = gameData.ShopStock.Count == 0 ? ShopState.Close : ShopState.Open;
|
||||
});
|
||||
}).AddTo(this);
|
||||
|
||||
|
|
@ -254,23 +316,29 @@ public class Market : MonoBehaviour
|
|||
var customer = Instantiate(customerPrefab);
|
||||
var customerController = customer.GetComponent<CustomerController>();
|
||||
customerController.Setup();
|
||||
customerController.MoveEndObservable.SkipLatestValueOnSubscribe().DistinctUntilChanged().Subscribe(type =>
|
||||
{
|
||||
// Debug.Log($"move end {type}");
|
||||
switch (type)
|
||||
customerController.MoveEndObservable
|
||||
.SkipLatestValueOnSubscribe()
|
||||
.DistinctUntilChanged()
|
||||
.Subscribe(type =>
|
||||
{
|
||||
case CustomerMovingType.WalkSide:
|
||||
case CustomerMovingType.WalkSideEat:
|
||||
customerList.Remove(customerController);
|
||||
Destroy(customer);
|
||||
break;
|
||||
case CustomerMovingType.StayBack:
|
||||
requestSubject.OnNext(customerController);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}).AddTo(customerController);
|
||||
// Debug.Log($"move end {type}");
|
||||
switch (type)
|
||||
{
|
||||
case CustomerMovingType.WalkSide:
|
||||
case CustomerMovingType.WalkSideEat:
|
||||
customerList.Remove(customerController);
|
||||
Destroy(customer);
|
||||
break;
|
||||
case CustomerMovingType.WalkBackHalf:
|
||||
waitCustomerList.Add(customerController);
|
||||
break;
|
||||
case CustomerMovingType.StayBack:
|
||||
requestSubject.OnNext(customerController);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}).AddTo(customerController);
|
||||
|
||||
if (x.isCustomer)
|
||||
{
|
||||
|
|
@ -290,28 +358,27 @@ public class Market : MonoBehaviour
|
|||
}).AddTo(this);
|
||||
}
|
||||
|
||||
private void SellPopcorn(int orderNum)
|
||||
private int SellPopcorn(List<(int flavor, int bonusRate)> flavors)
|
||||
{
|
||||
var gameData = GameDataManager.GameData;
|
||||
// 品切れ
|
||||
if (gameData.ShopStock.Count == 0)
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
var targetFlavorId = displayFlavors[orderNum];
|
||||
Debug.Log($"sell:{orderNum} flavor:{targetFlavorId} {shuffledOrder.Count}");
|
||||
Debug.Log($"sellCount:{flavors.Count} {shuffledOrder.Count}");
|
||||
|
||||
var targetIndex = gameData.ShopStock.FindIndex(x => x == targetFlavorId);
|
||||
var stockData = gameData.ShopStock[targetIndex];
|
||||
gameData.ShopStock.RemoveAt(targetIndex);
|
||||
cartView.SellStock(orderNum);
|
||||
|
||||
// コイン獲得
|
||||
var bonusRate = 0;
|
||||
var flavor = allRecipe.First(x => x.RecipeId == stockData);
|
||||
CoinManager.Instance.AddCoinWithEffect(flavor.Price * (1 + bonusRate / 100), () => { });
|
||||
gameData.coin = CoinManager.Instance.OwnCoin;
|
||||
GameDataManager.SaveGameData();
|
||||
// フレーバーを売る
|
||||
var coin = 0;
|
||||
foreach (var flavorData in flavors)
|
||||
{
|
||||
var targetIndex = gameData.ShopStock.FindIndex(x => x == flavorData.flavor);
|
||||
var flavorRecipe = allRecipe.First(x => x.RecipeId == gameData.ShopStock[targetIndex]);
|
||||
gameData.ShopStock.RemoveAt(targetIndex);
|
||||
var bonusRate = 0;
|
||||
coin += flavorRecipe.Price * (1 + bonusRate / 100);
|
||||
}
|
||||
return coin;
|
||||
}
|
||||
|
||||
private List<int> ShuffleOrder(int length)
|
||||
|
|
@ -337,7 +404,32 @@ public class Market : MonoBehaviour
|
|||
}
|
||||
GameDataManager.SaveGameData();
|
||||
}
|
||||
|
||||
|
||||
private void RefillProduct()
|
||||
{
|
||||
// 手前のタンクから出し多分stockをへらす
|
||||
// へらした分を店頭リストに追加する
|
||||
var gameData = GameDataManager.GameData;
|
||||
var shopSpace = ShopStockCount - gameData.ShopStock.Count;
|
||||
var index = 0;
|
||||
var tankCount = gameData.StorageTanks.Count;
|
||||
while (shopSpace > 0)
|
||||
{
|
||||
if (index > tankCount - 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
var tank = gameData.StorageTanks[index];
|
||||
var stockCount = Mathf.Min(shopSpace, tank.Stock);
|
||||
gameData.ShopStock.AddRange(Enumerable.Repeat(tank.FlavorId, stockCount));
|
||||
shopSpace -= stockCount;
|
||||
tank.Stock -= stockCount;
|
||||
gameData.StorageTanks[index] = tank;
|
||||
index++;
|
||||
}
|
||||
GameDataManager.SaveGameData();
|
||||
}
|
||||
|
||||
private void CheckAndFixStock()
|
||||
{
|
||||
if (GameDataManager.GameData.ShopStock.Count > ShopStockCount)
|
||||
|
|
|
|||
|
|
@ -75,8 +75,8 @@ public sealed class GameData {
|
|||
// タンクポップコーン在庫
|
||||
[DataMember(Name = "Data20")]
|
||||
public List<StorageTank> StorageTanks;
|
||||
|
||||
|
||||
[DataMember(Name = "Data21")]
|
||||
public int Heart = 0;
|
||||
|
||||
// public void ChangeAvatar(AvatarData avatarData){
|
||||
// newAvatarIdList.Remove(avatarData.id);
|
||||
|
|
|
|||
Loading…
Reference in New Issue