Пример #1
0
 public MonsterCollectionState(Address address, int level, long blockIndex,
                               MonsterCollectionRewardSheet monsterCollectionRewardSheet) : base(address)
 {
     Level             = level;
     StartedBlockIndex = blockIndex;
     ExpiredBlockIndex = blockIndex + LockUpInterval;
     List <MonsterCollectionRewardSheet.RewardInfo> rewardInfos = monsterCollectionRewardSheet[level].Rewards;
 }
Пример #2
0
        public void Update(int level, long rewardLevel, MonsterCollectionRewardSheet monsterCollectionRewardSheet)
        {
            Level = level;
            List <MonsterCollectionRewardSheet.RewardInfo> rewardInfos = monsterCollectionRewardSheet[level].Rewards;

            for (long i = rewardLevel; i < RewardLevelMap.Count; i++)
            {
                RewardLevelMap[i + 1] = rewardInfos;
            }
        }
Пример #3
0
        public override IAccountStateDelta Execute(IActionContext context)
        {
            IAccountStateDelta states            = context.PreviousStates;
            Address            collectionAddress = MonsterCollectionState0.DeriveAddress(context.Signer, collectRound);

            if (context.Rehearsal)
            {
                return(states
                       .SetState(collectionAddress, MarkChanged)
                       .MarkBalanceChanged(GoldCurrencyMock, collectionAddress, context.Signer));
            }

            CheckObsolete(BlockChain.Policy.BlockPolicySource.V100080ObsoleteIndex, context);

            AgentState agentState = states.GetAgentState(context.Signer);

            if (agentState is null)
            {
                throw new FailedLoadStateException("Aborted as the agent state failed to load.");
            }

            if (!states.TryGetState(collectionAddress, out Dictionary stateDict))
            {
                throw new FailedLoadStateException($"Aborted as the monster collection state failed to load.");
            }

            MonsterCollectionState0 monsterCollectionState = new MonsterCollectionState0(stateDict);
            Currency               currency = states.GetGoldCurrency();
            FungibleAssetValue     balance  = 0 * currency;
            MonsterCollectionSheet monsterCollectionSheet = states.GetSheet <MonsterCollectionSheet>();
            int currentLevel = monsterCollectionState.Level;

            if (currentLevel <= level || level <= 0)
            {
                throw new InvalidLevelException($"The level must be greater than 0 and less than {currentLevel}.");
            }

            if (monsterCollectionState.End)
            {
                throw new MonsterCollectionExpiredException($"{collectionAddress} has already expired on {monsterCollectionState.ExpiredBlockIndex}");
            }

            long rewardLevel = monsterCollectionState.GetRewardLevel(context.BlockIndex);
            MonsterCollectionRewardSheet monsterCollectionRewardSheet = states.GetSheet <MonsterCollectionRewardSheet>();

            monsterCollectionState.Update(level, rewardLevel, monsterCollectionRewardSheet);
            for (int i = currentLevel; i > level; i--)
            {
                balance += monsterCollectionSheet[i].RequiredGold * currency;
            }

            return(states
                   .SetState(collectionAddress, monsterCollectionState.Serialize())
                   .TransferAsset(collectionAddress, context.Signer, balance));
        }
Пример #4
0
        public MonsterCollectionState0(Address address, int level, long blockIndex,
                                       MonsterCollectionRewardSheet monsterCollectionRewardSheet) : base(address)
        {
            Level             = level;
            StartedBlockIndex = blockIndex;
            ExpiredBlockIndex = blockIndex + ExpirationIndex;
            RewardMap         = new Dictionary <long, MonsterCollectionResult>();
            List <MonsterCollectionRewardSheet.RewardInfo> rewardInfos = monsterCollectionRewardSheet[level].Rewards;

            RewardLevelMap = new Dictionary <long, List <MonsterCollectionRewardSheet.RewardInfo> >
            {
                [1] = rewardInfos,
                [2] = rewardInfos,
                [3] = rewardInfos,
                [4] = rewardInfos,
            };
        }
        public void SetToSheet()
        {
            var sheet = new MonsterCollectionRewardSheet();

            sheet.Set("collection_level,item_id,quantity\n1,1,1\n1,2,2");

            MonsterCollectionRewardSheet.Row row = sheet[1];
            Assert.Equal(1, row.MonsterCollectionLevel);

            List <MonsterCollectionRewardSheet.RewardInfo> rewards = row.Rewards;

            for (int i = 0; i < rewards.Count; i++)
            {
                MonsterCollectionRewardSheet.RewardInfo reward = rewards[i];
                Assert.Equal(i + 1, reward.ItemId);
                Assert.Equal(i + 1, reward.Quantity);
            }
        }
Пример #6
0
        public List <MonsterCollectionRewardSheet.RewardInfo> CalculateRewards(
            MonsterCollectionRewardSheet sheet,
            long blockIndex
            )
        {
            int step = CalculateStep(blockIndex);

            if (step > 0)
            {
                return(sheet[Level].Rewards
                       .GroupBy(ri => ri.ItemId)
                       .Select(g => new MonsterCollectionRewardSheet.RewardInfo(
                                   g.Key,
                                   g.Sum(ri => ri.Quantity) * step))
                       .ToList());
            }
            else
            {
                return(new List <MonsterCollectionRewardSheet.RewardInfo>());
            }
        }
Пример #7
0
        public override IAccountStateDelta Execute(IActionContext context)
        {
            IAccountStateDelta states = context.PreviousStates;
            Address            monsterCollectionAddress = MonsterCollectionState0.DeriveAddress(context.Signer, collectionRound);

            if (context.Rehearsal)
            {
                return(states
                       .SetState(monsterCollectionAddress, MarkChanged)
                       .SetState(context.Signer, MarkChanged)
                       .MarkBalanceChanged(GoldCurrencyMock, context.Signer, monsterCollectionAddress));
            }

            CheckObsolete(BlockChain.Policy.BlockPolicySource.V100080ObsoleteIndex, context);

            MonsterCollectionSheet monsterCollectionSheet = states.GetSheet <MonsterCollectionSheet>();

            AgentState agentState = states.GetAgentState(context.Signer);

            if (agentState is null)
            {
                throw new FailedLoadStateException("Aborted as the agent state failed to load.");
            }

            if (agentState.MonsterCollectionRound != collectionRound)
            {
                throw new InvalidMonsterCollectionRoundException(
                          $"Expected collection round is {agentState.MonsterCollectionRound}, but actual collection round is {collectionRound}.");
            }

            if (!monsterCollectionSheet.TryGetValue(level, out MonsterCollectionSheet.Row _))
            {
                throw new SheetRowNotFoundException(nameof(MonsterCollectionSheet), level);
            }

            Currency currency = states.GetGoldCurrency();
            // Set default gold value.
            FungibleAssetValue requiredGold = currency * 0;
            FungibleAssetValue balance      = states.GetBalance(context.Signer, states.GetGoldCurrency());

            MonsterCollectionState0 monsterCollectionState;
            int currentLevel = 1;
            MonsterCollectionRewardSheet monsterCollectionRewardSheet = states.GetSheet <MonsterCollectionRewardSheet>();

            if (states.TryGetState(monsterCollectionAddress, out Dictionary stateDict))
            {
                monsterCollectionState = new MonsterCollectionState0(stateDict);

                if (monsterCollectionState.ExpiredBlockIndex < context.BlockIndex)
                {
                    throw new MonsterCollectionExpiredException(
                              $"{monsterCollectionAddress} has already expired on {monsterCollectionState.ExpiredBlockIndex}");
                }

                if (monsterCollectionState.Level >= level)
                {
                    throw new InvalidLevelException($"The level must be greater than {monsterCollectionState.Level}.");
                }

                currentLevel = monsterCollectionState.Level + 1;
                long rewardLevel = monsterCollectionState.GetRewardLevel(context.BlockIndex);
                monsterCollectionState.Update(level, rewardLevel, monsterCollectionRewardSheet);
            }
            else
            {
                monsterCollectionState = new MonsterCollectionState0(monsterCollectionAddress, level, context.BlockIndex, monsterCollectionRewardSheet);
            }

            for (int i = currentLevel; i < level + 1; i++)
            {
                requiredGold += currency * monsterCollectionSheet[i].RequiredGold;
            }

            if (balance < requiredGold)
            {
                throw new InsufficientBalanceException(context.Signer, requiredGold,
                                                       $"There is no sufficient balance for {context.Signer}: {balance} < {requiredGold}");
            }
            states = states.TransferAsset(context.Signer, monsterCollectionAddress, requiredGold);
            states = states.SetState(monsterCollectionAddress, monsterCollectionState.Serialize());
            return(states);
        }