Merge branch 'develop' of bitbucket.org:usaya/popcorn into develop

This commit is contained in:
koya_15 2021-09-03 14:53:11 +09:00
commit 3fbb294d94
3 changed files with 215 additions and 125 deletions

View File

@ -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;
}
else
{
SetMove(CustomerMovingType.WalkCenter);
break;
case global::CustomerState.Wait:
// 順番待ち
// 近くの場合その場に待機
// まだ遠い場合待機場所に移動
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;

View File

@ -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:
// 売り切れの場合帰る
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,34 +150,66 @@ 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]);
this.CallWaitForSeconds(1.5f, () =>
{
// 購入
SellPopcorn(orderNum);
blueView.SellAction();
var flavors = orders.Select(x => (displayFlavors[x], 0)).ToList();
coin += SellPopcorn(flavors);
var remainStockCount = gameData.ShopStock.Count;
// 自動補充 refill
RefillOneProduct();
RefillProduct();
StockFlavorLog();
var setStockFlag = false;
// 補充された場合フレーバー再設定
var setStockFlag = false;
if (gameData.ShopStock.Count == ShopStockCount)
{
shuffledOrder.Add(orderNum);
displayFlavors[orderNum] = gameData.ShopStock.Last();
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))
{
@ -180,28 +224,46 @@ public class Market : MonoBehaviour
setStockFlag = true;
}
// 表示更新
this.CallWaitForSeconds(1.5f, () =>
{
foreach (var order in orders)
{
cartView.SellStock(order);
}
blueView.SellAction();
// コイン獲得
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, () =>
{
foreach (var customerController in customers)
{
var heartAnimation = customerController.GetComponent<HeartAnimation>();
heartAnimation.GetHeart(() =>
{
HeartMeter.Instance.AddHeart(3);
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,7 +316,10 @@ public class Market : MonoBehaviour
var customer = Instantiate(customerPrefab);
var customerController = customer.GetComponent<CustomerController>();
customerController.Setup();
customerController.MoveEndObservable.SkipLatestValueOnSubscribe().DistinctUntilChanged().Subscribe(type =>
customerController.MoveEndObservable
.SkipLatestValueOnSubscribe()
.DistinctUntilChanged()
.Subscribe(type =>
{
// Debug.Log($"move end {type}");
switch (type)
@ -264,6 +329,9 @@ public class Market : MonoBehaviour
customerList.Remove(customerController);
Destroy(customer);
break;
case CustomerMovingType.WalkBackHalf:
waitCustomerList.Add(customerController);
break;
case CustomerMovingType.StayBack:
requestSubject.OnNext(customerController);
break;
@ -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];
// フレーバーを売る
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);
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();
coin += flavorRecipe.Price * (1 + bonusRate / 100);
}
return coin;
}
private List<int> ShuffleOrder(int length)
@ -338,6 +405,31 @@ 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)

View File

@ -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);