MainシーンWorld対応

This commit is contained in:
kimura 2022-09-27 15:25:55 +09:00
parent 02668100ba
commit 8c409936c5
3 changed files with 181 additions and 182 deletions

View File

@ -251,4 +251,59 @@ public class BulkOrder : MonoBehaviour
}
return Mathf.CeilToInt(totalBonus / resultData.Count);
}
public static BulkOrderData CheckBulkOrder()
{
var globalGameData = GameDataManager.GameData;
var cityGameData = GameDataManager.GetCurrentCityGameData();
var nextOrderLevel = cityGameData.AchievedOrderLevel + 1;
if (globalGameData.ViewedShopLevel < nextOrderLevel)
{
return null;
}
var bulkOrderList = SpreadsheetDataManager.Instance.GetBaseDataList<BulkOrderData>(Const.BulkOrderDataSheet);
if (!bulkOrderList.Exists(data => data.shopLevel == nextOrderLevel))
{
return null;
}
var nextOrderList = bulkOrderList.Where(data => data.shopLevel == nextOrderLevel).ToList();
var firstTime = !nextOrderList.Exists(data => data.id == cityGameData.OrderIdInProgress);
var achieved = cityGameData.DeliveredOrder.Contains(cityGameData.OrderIdInProgress);
var canceled = cityGameData.OrderIdInProgress == cityGameData.CancelOrderId;
#if UNITY_EDITOR
Debug.Log("delivered:"+cityGameData.DeliveredOrder.Aggregate(string.Empty, (s, data) => $"{s}, {data}"));
Debug.Log($@"CheckBulkOrder NextOrder
shopLevel: {globalGameData.ViewedShopLevel} nextOrderLevel: {nextOrderLevel}
firstTime: {firstTime} achieved: {achieved} canceled: {canceled} {cityGameData.OrderIdInProgress} == {cityGameData.CancelOrderId}
next: {nextOrderList.Aggregate(string.Empty, (s, data) => $"{s}, {data.shopLevel} {data.maxOrder}")}
");
#endif
if (!(firstTime || achieved || canceled))
{
return null;
}
// 未達成のオーダーリスト
var orderList = nextOrderList.Where(data => !cityGameData.DeliveredOrder.Contains(data.id)).ToList();
if (orderList.Count == 0)
{
#if UNITY_EDITOR
// オーダーリストがすべて達成済みの場合エラー
Debug.LogError(
$@"大量注文レベル{nextOrderLevel}に受けられるオーダーがありませんデータを確認してください
orderCount:{nextOrderList.Count} maxOrder:{nextOrderList[0].maxOrder}
orderList:{nextOrderList.Aggregate(string.Empty, (s, data) => $"{s}, {data.id}")}
delivered:{cityGameData.DeliveredOrder.Aggregate(string.Empty, (s, data) => $"{s}, {data}")}
");
#endif
return null;
}
var orderData = orderList.FirstOrDefault(data => data.id > cityGameData.OrderIdInProgress) ?? nextOrderList[0];
// キャンセル時retryConditionを使う
var condition = canceled ? orderData.retryCondition : orderData.firstOrderCondition;
#if UNITY_EDITOR
Debug.Log($"nextOrderId: {orderData.id} use {(canceled ? "retryCondition" : "firstOrderCondition")} ({cityGameData.OrderConditionCount}/{condition})");
#endif
return condition <= cityGameData.OrderConditionCount ? orderData : null;
}
}

View File

@ -21,6 +21,7 @@ public class KitchenManager : MonoBehaviour
[SerializeField] private KitchenView kitchenView;
[SerializeField] private BulkOrderIndicatorView orderIndicatorView;
[SerializeField] private AutoCookView autoCookView;
[SerializeField] private PartTimerButtonView partTimerButtonView;
private readonly Subject<Unit> showAdDialogSubject = new Subject<Unit>();
private IDisposable timerDisposable = null;
@ -31,7 +32,14 @@ public class KitchenManager : MonoBehaviour
{
showAdDialogSubject.AddTo(this);
SoundManager.Instance.PlayBGM("bgm_Main");
var gameData = GameDataManager.GameData;
var globalGameData = GameDataManager.GameData;
var newGameData = GameDataUtils.CreateCityData(2);
// newGameData.IsFundingCompleted = true;
newGameData.Heart = 100;
// gameData.IsFundingCompleted = true;
// gameData.PartTimerElapsed = 100;
// globalGameData.CurrentCityId = Const.DefaultCityId;
var cityGameData = GameDataManager.GetCurrentCityGameData();
// レシピの表示
cookingButton.OnClickAsObservable().Subscribe(_ =>
@ -39,31 +47,41 @@ public class KitchenManager : MonoBehaviour
RecipeSelectDialog.ShowDialog(ProductViewType.Default);
});
// 大量注文データ
var bulkOrderList = SpreadsheetDataManager.Instance.GetBaseDataList<BulkOrderData>(Const.BulkOrderDataSheet);
var bulkOrderData = bulkOrderList.FirstOrDefault(data => data.id == gameData.OrderIdInProgress);
var achieved = bulkOrderData is null || gameData.DeliveredOrder.Contains(bulkOrderData.id) || gameData.AchievedOrderLevel == bulkOrderData.shopLevel;
var cancelled = gameData.OrderIdInProgress == gameData.CancelOrderId;
CheckOrderAndSetPhoneTap();
// 大量注文達成通知
if (bulkOrderData == null)
/*
*
* ()
*/
var isPartTimer = !GameDataUtils.CheckLatestCity(globalGameData.CurrentCityId);
if (isPartTimer)
{
orderIndicatorView.SetBadgeActive(false);
}
else
{
var orderList = new List<int>
{
bulkOrderData.productId1,
bulkOrderData.productId2,
bulkOrderData.productId3,
};
var completed = gameData.CompletedProductList.Count == orderList.Count(x => x != 0);
orderIndicatorView.SetBadgeActive(completed && !achieved && !cancelled);
CheckOrderAndSetPhoneTap();
}
// バイト有効時は自動調理と大量注文が非表示
partTimerButtonView.gameObject.SetActive(isPartTimer);
orderIndicatorView.gameObject.SetActive(!isPartTimer);
autoCookView.SetActive(!isPartTimer && globalGameData.ViewedShopLevel >= Const.AutoCookAvailableLevel);
kitchenView.SetActive(!isPartTimer);
// 大量注文達成通知
var bulkOrderList = SpreadsheetDataManager.Instance.GetBaseDataList<BulkOrderData>(Const.BulkOrderDataSheet);
if (bulkOrderList.FirstOrDefault(data => data.id == cityGameData.OrderIdInProgress) is { } bulkOrderData)
{
var completed = cityGameData.CompletedProductList.Count == bulkOrderData.OrderList.Count(tuple => tuple.productId != 0);
var achieved = cityGameData.AchievedOrderLevel == bulkOrderData.shopLevel || cityGameData.DeliveredOrder.Contains(bulkOrderData.id);
var cancelled = cityGameData.OrderIdInProgress == cityGameData.CancelOrderId;
orderIndicatorView.SetBadgeActive(completed && !achieved && !cancelled);
orderIndicatorView.SetIndicate(false, achieved || cancelled);
}
else
{
orderIndicatorView.SetBadgeActive(false);
orderIndicatorView.SetIndicate(false, true);
}
// 大量注文の調理から戻ってきたときにダイアログ開く
if (LocalCacheManager.Load(Const.ProductViewTypeTag, ProductViewType.Default) == ProductViewType.BulkOrder)
{
@ -72,40 +90,37 @@ public class KitchenManager : MonoBehaviour
// 自動調理
autoCookView.Initialize();
// レベル確認
autoCookView.SetActive(gameData.ViewedShopLevel >= Const.AutoCookAvailableLevel);
var autoCookDataList = SpreadsheetDataManager.Instance.GetBaseDataList<AutoCookData>(Const.AutoCookDataSheet);
if (autoCookDataList.FirstOrDefault(data => data.level == gameData.AutoCookLevel) is AutoCookData autoCookData)
if (autoCookDataList.FirstOrDefault(data => data.level == cityGameData.AutoCookLevel) is AutoCookData autoCookData)
{
autoCookView.CheckNotify();
CookState state;
var remainingTime = DateTime.FromBinary(gameData.AutoCookFinishTime).Subtract(DateTime.UtcNow);
if (gameData.AutoCookProducts.Length > 0)
var remainingTime = DateTime.FromBinary(cityGameData.AutoCookFinishTime).Subtract(DateTime.UtcNow);
if (cityGameData.AutoCookProducts.Length > 0)
{
autoCookView.ResetTimer((int)remainingTime.TotalSeconds, (int)TimeSpan.FromHours(autoCookData.duration).TotalSeconds);
}
autoCookView.Button.ThrottleFirst(TimeSpan.FromSeconds(.3f)).Subscribe(_ =>
{
// 自動調理チュートリアル
if (!gameData.FinishedFlags.HasFlag(TutorialFlag.AutoCook))
if (!globalGameData.FinishedFlags.HasFlag(TutorialFlag.AutoCook))
{
TutorialManager.Instance.ShowTutorialConversation(14, () =>
{
gameData.FinishedFlags |= TutorialFlag.AutoCook;
globalGameData.FinishedFlags |= TutorialFlag.AutoCook;
GameDataManager.SaveGameData();
autoCookView.ShowDialog(CookState.Ready, () =>
{
autoCookView.CheckNotify();
remainingTime = DateTime.FromBinary(gameData.AutoCookFinishTime).Subtract(DateTime.UtcNow);
remainingTime = DateTime.FromBinary(cityGameData.AutoCookFinishTime).Subtract(DateTime.UtcNow);
autoCookView.ResetTimer((int)remainingTime.TotalSeconds, (int)TimeSpan.FromHours(autoCookData.duration).TotalSeconds);
});
});
return;
}
remainingTime = DateTime.FromBinary(gameData.AutoCookFinishTime).Subtract(DateTime.UtcNow);
if (gameData.AutoCookProducts.Length == 0)
remainingTime = DateTime.FromBinary(cityGameData.AutoCookFinishTime).Subtract(DateTime.UtcNow);
if (cityGameData.AutoCookProducts.Length == 0)
{
state = CookState.Ready;
}
@ -121,13 +136,13 @@ public class KitchenManager : MonoBehaviour
autoCookView.ShowDialog(state, () =>
{
autoCookView.CheckNotify();
if (gameData.AutoCookProducts.Length == 0)
if (cityGameData.AutoCookProducts.Length == 0)
{
autoCookView.Ready();
}
else
{
remainingTime = DateTime.FromBinary(gameData.AutoCookFinishTime).Subtract(DateTime.UtcNow);
remainingTime = DateTime.FromBinary(cityGameData.AutoCookFinishTime).Subtract(DateTime.UtcNow);
autoCookView.ResetTimer((int)remainingTime.TotalSeconds, (int)TimeSpan.FromHours(autoCookData.duration).TotalSeconds);
}
});
@ -135,25 +150,25 @@ public class KitchenManager : MonoBehaviour
}
// tutorial
if (!gameData.FinishedFlags.HasFlag(TutorialFlag.FirstPlay))
if (!globalGameData.FinishedFlags.HasFlag(TutorialFlag.FirstPlay))
{
if (TutorialManager.Instance.Index == 0)
{
gameData.ViewedShopLevel = 0;
globalGameData.ViewedShopLevel = 0;
// アイテム付与
gameData.CornSeed = 100;
gameData.Coin = 0;
if (!(gameData.Material.FirstOrDefault(x => x.Id == 2) is MaterialData materialData))
globalGameData.CornSeed = 100;
globalGameData.Coin = 0;
if (!(globalGameData.Material.FirstOrDefault(x => x.Id == 2) is MaterialData materialData))
{
materialData = new MaterialData {Id = 2};
gameData.Material.Add(materialData);
globalGameData.Material.Add(materialData);
}
materialData.Amount++;
gameData.InitTank();
gameData.ShopStock.Clear();
globalGameData.InitTank();
globalGameData.ShopStock.Clear();
// ミッションカウンターリセット
gameData.ResetNormalTotalCount();
gameData.ResetDailyTotalCount();
globalGameData.ResetNormalTotalCount();
globalGameData.ResetDailyTotalCount();
// 店舗レベル1達成表示
kitchenView.SetActive(false);
@ -188,21 +203,25 @@ public class KitchenManager : MonoBehaviour
}
}
CoinManager.Instance.ChangeCoin(gameData.Coin);
HeartMeter.Instance.Initialize(gameData.ViewedShopLevel, gameData.Heart);
CoinManager.Instance.ChangeCoin(cityGameData.Coin);
HeartMeter.Instance.Initialize(globalGameData.ViewedShopLevel, cityGameData.Heart);
// ハートゲージがフルかつダイアログが開いていない場合レベルアップ
HeartMeter.Instance.FulledHeart
.SkipWhile(_ => !gameData.FinishedFlags.HasFlag(TutorialFlag.FirstPlay))
.SkipWhile(_ => !globalGameData.FinishedFlags.HasFlag(TutorialFlag.FirstPlay))
.DelaySubscription(TimeSpan.FromSeconds(.4f))
.Subscribe(_ =>
{
kitchenView.SetActive(false);
ShopLevelUp.ShowDialog(gameData.ViewedShopLevel + 1, () =>
ShopLevelUp.ShowDialog(globalGameData.ViewedShopLevel + 1, () =>
{
if (isPartTimer)
{
return;
}
kitchenView.SetActive(true);
CheckOrderAndSetPhoneTap();
autoCookView.SetActive(gameData.ViewedShopLevel >= Const.AutoCookAvailableLevel);
autoCookView.SetActive(globalGameData.ViewedShopLevel >= Const.AutoCookAvailableLevel);
});
}).AddTo(this);
@ -214,6 +233,16 @@ public class KitchenManager : MonoBehaviour
HeartMeter.Instance.AddHeart(pair.Current - pair.Previous);
}).AddTo(this);
this.OnDestroyAsObservable()
.Subscribe(_ =>
{
if (!SoundManager.ExistsInstance)
{
return;
}
SoundManager.Instance.StopSE("se_Main_phone_sound");
}).AddTo(this);
kitchenView.Initialize();
adButton.OnClickAsObservable()
.Merge(showAdDialogSubject)
@ -225,13 +254,13 @@ public class KitchenManager : MonoBehaviour
CoinGetDialog.ShowDialog(refreshRewardCoin, () =>
{
CoinManager.Instance.AddCoin(refreshRewardCoin);
gameData.Coin = CoinManager.Instance.OwnCoin;
gameData.kitchenRefreshTime = DateTime.UtcNow.AddSeconds(refreshWaitTime).ToBinary();
cityGameData.Coin = CoinManager.Instance.OwnCoin;
globalGameData.kitchenRefreshTime = DateTime.UtcNow.AddSeconds(refreshWaitTime).ToBinary();
GameDataManager.SaveGameData();
// SetTimer((int)refreshWaitTime);
adButton.gameObject.SetActive(false);
if (gameData.kitchenRefreshTime % 10 < livelyRate)
if (globalGameData.kitchenRefreshTime % 10 < livelyRate)
{
kitchenView.SetLivelyAnimation();
}
@ -244,21 +273,21 @@ public class KitchenManager : MonoBehaviour
}).AddTo(this);
// 休憩リワード
var remaining = (int) DateTime.FromBinary(gameData.kitchenRefreshTime).Subtract(DateTime.UtcNow).TotalSeconds;
var remaining = (int) DateTime.FromBinary(globalGameData.kitchenRefreshTime).Subtract(DateTime.UtcNow).TotalSeconds;
// timerDisposable = SetTimer(remaining);
// 商品在庫計算
var shopStock = gameData.ShopStock.Count;
var tankStock = gameData.StorageTanks.Sum(x => x.Stock);
var shopStock = cityGameData.ShopStock.Count;
var tankStock = cityGameData.StorageTanks.Sum(x => x.Stock);
var totalStock = shopStock + tankStock;
if (remaining <= 0 && gameData.FinishedFlags.HasFlag(TutorialFlag.FirstPlay))
if (remaining <= 0 && globalGameData.FinishedFlags.HasFlag(TutorialFlag.FirstPlay))
{
// コイン獲得有効
adButton.gameObject.SetActive(true);
kitchenView.SetNormalAnimation();
}
else if (gameData.Coin + gameData.Material.Sum(data => data.Amount) + totalStock == 0)
else if (cityGameData.Coin + cityGameData.Material.Sum(data => data.Amount) + totalStock == 0)
{
// 所持金0救済
adButton.gameObject.SetActive(true);
@ -269,7 +298,7 @@ public class KitchenManager : MonoBehaviour
{
// 獲得後
adButton.gameObject.SetActive(false);
if (gameData.kitchenRefreshTime % 10 < livelyRate)
if (globalGameData.kitchenRefreshTime % 10 < livelyRate)
{
kitchenView.SetLivelyAnimation();
}
@ -286,7 +315,7 @@ public class KitchenManager : MonoBehaviour
}
#if UNITY_EDITOR
Debug.Log($"remaining: {remaining}");
Debug.Log($"remaining: {Mathf.Max(remaining, 0)}");
Market.StockFlavorLog();
#endif
@ -295,66 +324,50 @@ public class KitchenManager : MonoBehaviour
// 大量注文タップ時の挙動設定
private void CheckOrderAndSetPhoneTap()
{
if (BulkOrder.CheckBulkOrder() is { } nextOrderData)
{
orderIndicatorView.SetIndicate(true, false);
SetPhoneTap(nextOrderData);
return;
}
var gameData = GameDataManager.GameData;
// 大量注文データ
var bulkOrderList = SpreadsheetDataManager.Instance.GetBaseDataList<BulkOrderData>(Const.BulkOrderDataSheet);
var bulkOrderData = bulkOrderList.FirstOrDefault(data => data.id == gameData.OrderIdInProgress);
var achieved = bulkOrderData is null || gameData.DeliveredOrder.Contains(bulkOrderData.id) || gameData.AchievedOrderLevel == bulkOrderData.shopLevel;
var cancelled = gameData.OrderIdInProgress == gameData.CancelOrderId;
var result = CheckBulkOrder();
orderIndicatorView.SetIndicate(result.newOrder, achieved || cancelled);
if (!result.newOrder)
if (cancelled)
{
if (!cancelled)
{
SetPhoneTap();
}
}
else
{
// 新着処理
SoundManager.Instance.StopSE("se_Main_phone_sound");
var messageList = SpreadsheetDataManager.Instance.GetBaseDataList<BulkOrderTextData>(Const.BulkOrderTextDataSheet);
var nextMessageList = messageList.Where(data => data.shopLevel == result.nextOrderLevel).ToList();
tapPhoneDisposable?.Dispose();
tapPhoneDisposable = orderIndicatorView.TappedPhone.Take(1).Subscribe(_ =>
{
// タップで更新
gameData.CompletedProductList.Clear();
gameData.OrderIdInProgress = result.nextOrderId;
if (nextMessageList.Exists(data => data.id == gameData.OrderTextId))
{
var nextMessageIndex = nextMessageList.FindIndex(data => data.id == gameData.OrderTextId) + 1;
gameData.OrderTextId = nextMessageList[nextMessageIndex >= nextMessageList.Count ? 0 : nextMessageIndex].id;
}
else
{
gameData.OrderTextId = nextMessageList.First().id;
}
GameDataManager.SaveGameData();
var orderData = bulkOrderList.First(data => data.id == result.nextOrderId);
LocalCacheManager.Save(BulkOrder.DataTag, orderData);
BulkOrderNotifyView.ShowDialog(BulkOrderShowDialogWithSetup);
// 通知をタップ後タップ動作を切り替える
SetPhoneTap();
orderIndicatorView.SetIndicate(false, false);
}).AddTo(this);
return;
}
SetPhoneTap();
}
private void SetPhoneTap()
private void SetPhoneTap(BulkOrderData nextOrderData = null)
{
tapPhoneDisposable?.Dispose();
tapPhoneDisposable = orderIndicatorView.TappedPhone
.ThrottleFirst(TimeSpan.FromSeconds(1f))
.Subscribe(_ =>
{
BulkOrderShowDialogWithSetup();
}).AddTo(this);
if (nextOrderData is null)
{
tapPhoneDisposable = orderIndicatorView.TappedPhone
.ThrottleFirst(TimeSpan.FromSeconds(1f))
.Subscribe(_ => BulkOrderShowDialogWithSetup()).AddTo(this);
return;
}
// 新着処理
SoundManager.Instance.StopSE("se_Main_phone_sound");
var messageList = SpreadsheetDataManager.Instance.GetBaseDataList<BulkOrderTextData>(Const.BulkOrderTextDataSheet);
var nextMessageList = messageList.Where(data => data.shopLevel == nextOrderData.shopLevel).ToList();
tapPhoneDisposable = orderIndicatorView.TappedPhone.Take(1).Subscribe(_ =>
{
// タップで更新
var gameData = GameDataManager.GameData;
gameData.CompletedProductList.Clear();
gameData.OrderIdInProgress = nextOrderData.id;
gameData.OrderTextId = nextMessageList.FirstOrDefault(data => data.id > gameData.OrderTextId)?.id ?? nextMessageList[0].id;
GameDataManager.SaveGameData();
SetPhoneTap();
orderIndicatorView.SetIndicate(false, false);
LocalCacheManager.Save(BulkOrder.DataTag, nextOrderData);
BulkOrderNotifyView.ShowDialog(BulkOrderShowDialogWithSetup);
}).AddTo(this);
}
private void BulkOrderShowDialogWithSetup()
@ -372,68 +385,6 @@ public class KitchenManager : MonoBehaviour
});
}
private (bool newOrder, int nextOrderId, int nextOrderLevel) CheckBulkOrder()
{
var gameData = GameDataManager.GameData;
var nextOrderLevel = 0;
var nextOrderId = gameData.OrderIdInProgress;
var bulkOrderList = SpreadsheetDataManager.Instance.GetBaseDataList<BulkOrderData>(Const.BulkOrderDataSheet);
if (!(bulkOrderList.FirstOrDefault(data => data.shopLevel >= gameData.AchievedOrderLevel + 1) is BulkOrderData bulkOrderData))
{
return (false, nextOrderId, nextOrderLevel);
}
nextOrderLevel = bulkOrderData.shopLevel;
if (gameData.ViewedShopLevel < nextOrderLevel)
{
return (false, nextOrderId, nextOrderLevel);
}
var achieved = gameData.DeliveredOrder.Contains(gameData.OrderIdInProgress);
var canceled = gameData.OrderIdInProgress == gameData.CancelOrderId;
var nextOrderList = bulkOrderList.Where(data => data.shopLevel == nextOrderLevel).ToList();
if (!nextOrderList.Exists(data => data.id == gameData.OrderIdInProgress))
{
// まだ次のオーダーが設定されてない場合nextOrderListの一番若いIDを設定
nextOrderId = nextOrderList.First().id;
}
else if (achieved || canceled)
{
// 達成済みか、キャンセルされた場合次のIDを設定
// 未達成のオーダー
var orderList = nextOrderList.Where(data => !gameData.DeliveredOrder.Contains(data.id)).ToList();
if (orderList.Count <= 0)
{
#if UNITY_EDITOR
// オーダーリストがすべて達成済みの場合エラー
Debug.LogError($"大量注文レベル{nextOrderLevel}に受けられるオーダーがありませんデータを確認してください\n" +
$"maxOrder:{nextOrderList[0].maxOrder}\n" +
$"delivered:{gameData.DeliveredOrder.Aggregate(string.Empty, (s, data) => $"{s}, {data}")}\n" +
$"orderList:{nextOrderList.Aggregate(string.Empty, (s, data) => $"{s}, {data.id}")}");
#endif
return (false, nextOrderId, nextOrderLevel);
}
var nextIndex = orderList.FindIndex(data => data.id > gameData.OrderIdInProgress);
nextOrderId = orderList[Mathf.Max(0, nextIndex)].id;
}
if (gameData.OrderIdInProgress == nextOrderId)
{
return (false, nextOrderId, nextOrderLevel);
}
var orderData = nextOrderList.First(data => data.id == nextOrderId);
// キャンセル時retryConditionを使う
var condition = canceled ? orderData.retryCondition : orderData.firstOrderCondition;
#if UNITY_EDITOR
Debug.Log($"nextOrderId: {nextOrderId} use {(canceled ? "retryCondition" : "firstOrderCondition")} ({gameData.OrderConditionCount}/{condition})");
#endif
// 条件チェック
return (condition <= gameData.OrderConditionCount, nextOrderId, nextOrderLevel);
}
private IDisposable SetTimer(int time)
{
timerDisposable?.Dispose();
@ -447,12 +398,4 @@ public class KitchenManager : MonoBehaviour
adButton.gameObject.SetActive(true);
}).AddTo(this);
}
private void OnDestroy()
{
if (SoundManager.ExistsInstance)
{
SoundManager.Instance.StopSE("se_Main_phone_sound");
}
}
}

View File

@ -43,6 +43,7 @@ public static class Const {
public static readonly string LanguageDataTypeTag = "LanguageDataType";
public static readonly string LocalNotificationTag = "LocalNotification";
public static readonly string ProductViewTypeTag = "ProductViewType";
public static readonly string ChangeCityFlagTag = "ChangeCityFlag";
// sns
public static readonly string LineURL = "http://nav.cx/aVZ8nEK";