using System; using System.Collections.Generic; using IVDataFormat; using IVServerFormat; using System.Numerics; using BigFloatNumerics; [Serializable] public class ProtectTheMerchantDgData : GameModData, IHasRewards, IAutoProgressable { ProtectTheMerchantDgProp Property => property as ProtectTheMerchantDgProp; ProtectTheMerchantDgPlayProp PlayProperty => playProperty as ProtectTheMerchantDgPlayProp; IList requestRewards; int remainRequestCount; Action, bool> onDoneGetResult; public override string NameKey => "dungeon_title_ProtectTheMerchant"; public string BGMPath => Property.bgmPath; public string BackGroundPath => Property.backGroundPath; public int OpenStage => (int)Property.openStage; public bool AutoProgress { get; set; } public ProtectTheMerchantDgProp.MerchantCreator MerchantCreator => Property.merchantCreator; public IReadOnlyList NormalEnemyCreators => Property.normalEnemyCreator; public int WaveCount => Property.waveCount; public float WaveIntervalTime => Property.waveIntervalTime; public float LimitTime => Property.limitTime; public uint EnterTicketCount { get => PlayProperty.enterTicketCount; set => PlayProperty.enterTicketCount = value; } public ItemProp EnterCostItem => Property.enterCostItem; public uint TryCount { get => PlayProperty.tryCount; set => PlayProperty.tryCount = value; } public uint ClearCount { get => PlayProperty.clearCount; set => PlayProperty.clearCount = value; } public ProtectTheMerchantDgData(ProtectTheMerchantDgProp property, ProtectTheMerchantDgPlayProp playProperty) : base(property, playProperty) { SetLevel(Level); } public bool IsClear(uint level) => level < Level; public void TryGetReward(uint level, Action, bool> onRequestDone, float multifier = 1f, int count = 1) { if (requestRewards != null) return; requestRewards = new List(); for (int i = 0; i < count; i++) { var rewards = GetRewardList(level); for (int j = 0; j < rewards.Count; j++) { var reward = rewards[j]; reward.propertyCount = (BigFloat)reward.propertyCount * multifier; if (requestRewards.TryFind(rewards[j].IsSameGoods, out var result)) result.propertyCount += rewards[j].propertyCount; else requestRewards.OrderInsert(rewards[j], nGoods.CompareByID); } } remainRequestCount = requestRewards.Count; onDoneGetResult = onRequestDone; foreach (var reward in requestRewards) { SvConnectManager.Instance.RequestSvPost(true, 0, UrlApi.GetUrl(UrlApi.Property), typeof(nGoodsGet), OnGetRewardSuccess, OnGetRewardFail, reward, true); } if (requestRewards.Count == 0) onDoneGetResult?.Invoke(new nGoods[0], true); } private void OnGetRewardSuccess(object result, object request) { if (--remainRequestCount <= 0) { nGoodsGet data = result as nGoodsGet; DataHandler.AddGoods(requestRewards, data.playCurrency, true); onDoneGetResult?.Invoke(requestRewards, true); requestRewards = null; } } private void OnGetRewardFail(SvError error, object request) { onDoneGetResult?.Invoke(new nGoods[0], false); requestRewards = null; } public IList GetRewardList(uint level) { var rewards = new nGoods[Property.rewards.Length]; for (int i = 0; i < Property.rewards.Length; i++) { var reward = Property.rewards[i]; var goods = reward.itemProp.ConvertTo(reward.GetCount(level)); rewards[i] = goods; } return rewards; } public BigInteger GetRecommendBattlePower(uint level) { BigInteger total = 0; foreach (var creator in NormalEnemyCreators) { total += DataHandler.CalcBattlePower(creator.GetHp(level), creator.GetAtk()); } return total; } public bool CanSkip(uint level) => EnterTicketCount > 0 && level > 1; public float GetRewardMultiplier() => BuffMgr.Instance.GetProptectTheMerchantBonus() / dConst.RateMaxFloat; }