public void ApplyProgress_PerkIsLevelCap_PerkDosntLeveledUp()
        {
            // ARRANGE
            var perkScheme = new PerkScheme
            {
                Levels = new[] {
                    new PerkLevelSubScheme {
                        MaxValue = 0,
                        Jobs     = new IJobSubScheme[] {
                            new TestJobSubScheme {
                                Type  = JobType.Defeats,
                                Value = 1
                            }
                        }
                    }
                }
            };

            var perkJobMock = new Mock <IJob>();

            perkJobMock.SetupProperty(x => x.Progress, 1);
            perkJobMock.SetupGet(x => x.Scheme)
            .Returns(perkScheme.Levels[0].Jobs[0]);
            perkJobMock.SetupProperty(x => x.IsComplete);
            var perkJob = perkJobMock.Object;


            var progressMock = new Mock <IJobProgress>();

            progressMock.Setup(x => x.ApplyToJobs(It.IsAny <IEnumerable <IJob> >()))
            .Returns(new[] { perkJob });
            var progress = progressMock.Object;

            var perkMock = new Mock <IPerk>();

            perkMock.SetupGet(x => x.Scheme)
            .Returns(perkScheme);
            perkMock.SetupGet(x => x.CurrentLevel)
            .Returns(new PerkLevel(0, 0));
            var perk = perkMock.Object;

            var perks = new[] {
                perk
            };
            var evolutionModuleMock = new Mock <IEvolutionModule>();

            evolutionModuleMock.SetupGet(x => x.Perks)
            .Returns(perks);
            var evolutionModule = evolutionModuleMock.Object;

            var perkResolver = new PerkResolver();

            // ACT
            perkResolver.ApplyProgress(progress, evolutionModule);

            // ASSERT
            evolutionModuleMock.Verify(x => x.PerkLevelUp(It.IsAny <IPerk>()), Times.Never);
        }
Esempio n. 2
0
        /// <summary>
        /// Преобразование уровня/подуровня в суммарный уровень.
        /// </summary>
        /// <param name="perkScheme">Схема.</param>
        /// <param name="level">Уровень перка.</param>
        /// <param name="subLevel">Подуровень перка.</param>
        /// <returns></returns>
        public static int?ConvertLevel(PerkScheme perkScheme, int?level, int subLevel)
        {
            if (level == null)
            {
                return(null);
            }

            var sum = 0;

            for (var i = 0; i <= level; i++)
            {
                if (i < level)
                {
                    sum += perkScheme.Levels[i].MaxValue + 1;
                }
                else
                {
                    sum += subLevel;
                }
            }

            return(sum);
        }
Esempio n. 3
0
        //public static PerkRuleSubScheme[] GetAllPerkRules(PerkScheme perkScheme, int? perkLevel, int perkSubLevel)
        //{
        //    if (perkLevel == null)
        //        return new PerkRuleSubScheme[0];

        //    var ruleList = new List<PerkRuleSubScheme>();
        //    for (var i = 0; i <= perkLevel.Value; i++)
        //    {
        //        var archievedSubLevel = 0;
        //        if (perkLevel.Value < i)
        //        {
        //            archievedSubLevel = perkScheme.Levels[i].MaxValue;
        //        }
        //        else
        //        {
        //            archievedSubLevel = Math.Min(perkSubLevel, perkScheme.Levels[i].MaxValue);
        //        }

        //        var levelRules = perkScheme.Levels[i].Rules;
        //        if (levelRules != null)
        //        {
        //            for (var j = 0; j <= archievedSubLevel; j++)
        //            {
        //                ruleList.AddRange(levelRules);
        //            }
        //        }
        //    }

        //    return ruleList.ToArray();
        //}

        //public static string DetectPerkChangesClass(PerkScheme perkScheme, int? currentLevel)
        //{
        //    if (currentLevel == null)
        //        return null;

        //    var rules = perkScheme.Levels[currentLevel.Value].Rules;
        //    if (rules == null)
        //        return null;

        //    var changeClassRule = rules.FirstOrDefault(x => x.ChangeClass != null);
        //    if (changeClassRule != null)
        //        return changeClassRule.ChangeClass;

        //    return null;
        //}

        ///// <summary>
        ///// Вычисляет прокаченную и целевую схему уровня перка.
        ///// </summary>
        ///// <param name="levelSchemes"> Все схемы уровня в порядке достижения. </param>
        ///// <param name="level"> Текущий уровень перка. </param>
        ///// <param name="subLevel"> Текущий подуровень перка. </param>
        ///// <param name="archievedLevelScheme">
        ///// Схема уровня перка, которая считается полученной на текущем уровне.
        ///// </param>
        ///// <param name="nextLevelScheme">
        ///// Схема уровня перка, которая будет следующей после достигнутой.
        ///// </param>
        //public static void CalcLevelScheme(PerkLevelSubScheme[] levelSchemes,
        //    int? level,
        //    int subLevel,
        //    out PerkLevelSubScheme archievedLevelScheme,
        //    out PerkLevelSubScheme nextLevelScheme)
        //{
        //    //Если уровень не определён, то перк ни на сколько не прокачен.
        //    // Значит берём первую схему уровня.
        //    if (level == null)
        //    {
        //        archievedLevelScheme = null;
        //        nextLevelScheme = levelSchemes[0];
        //        return;
        //    }

        //    // Извлекаем текущую схему уровня согласно текущему уровню..
        //    archievedLevelScheme = levelSchemes[level.Value];

        //    // Если все уровни перка прокачены, то возвращаем null.
        //    // Это означает, что дальнейшей прокачки нет. LevelCap
        //    if (level.Value + 1 < levelSchemes.Length)
        //    {
        //        // Если не все подуровни прокачены, то оставляем текущую схему подуровня.
        //        // Иначе возвращаем схему следующего уровеня перка.
        //        if (archievedLevelScheme.MaxValue > subLevel)
        //        {
        //            nextLevelScheme = archievedLevelScheme;
        //        }
        //        else
        //        {
        //            nextLevelScheme = levelSchemes[level.Value + 1];
        //        }
        //    }
        //    else
        //    {
        //        nextLevelScheme = null;
        //    }
        //}

        //public static Perk[] GetAllPerks(IEnumerable<PerkScheme> targetPerkSchemes, IDictionary<string, PerkScheme> perkSchemeDict,
        //     IDictionary<string, PropScheme> propSchemeDict)
        //{
        //    var perks = new List<Perk>();
        //    foreach (var perkScheme in targetPerkSchemes)
        //    {
        //        try
        //        {
        //            var perk = CreatePerk(perkScheme, null, 0, null, PerkState.None, false, perkSchemeDict, propSchemeDict);
        //            perks.Add(perk);
        //        }
        //        catch (Exception exception)
        //        {
        //            Logger.TraceError(LogCodes.ErrorCommon, $"Ошибка при обработки перка {perkScheme.Sid}.", exception);
        //        }
        //    }

        //    return perks.ToArray();
        //}

        ///// <summary>
        ///// Рассчитывает уровень персонажа исходя из прокаченных перков.
        ///// </summary>
        ///// <param name="perks">Прокаченные перки. Внутри всё равно есть проверка на наличие уровня у перка.</param>
        ///// <returns>Уровень персонажа</returns>
        //public static float CalcPersonLevel(IEnumerable<Perk> perks)
        //{
        //    var totalArchievedPersonLevel = 0f;
        //    foreach (var perk in perks)
        //    {
        //        if (perk.CurrentLevel == null)
        //            continue;

        //        var perkScheme = perk.Scheme;
        //        for (var i = 0; i <= perk.CurrentLevel.Value; i++)
        //        {
        //            var levelScheme = perkScheme.Levels[i];

        //            var perkPersonLevel = levelScheme.PersonLevel.Base + levelScheme.PersonLevel.LevelInc * perk.CurrentSubLevel;

        //            totalArchievedPersonLevel += perkPersonLevel;
        //        }
        //    }

        //    return totalArchievedPersonLevel + 1;
        //}

        //public static Perk[] FilterAvailability(IEnumerable<Perk> perks, PerkAvailabilityContext availabilityContext)
        //{
        //    var availablePerks = new List<Perk>();
        //    foreach (var perk in perks)
        //    {
        //        var isAvailable = IsAvailable(perk, availabilityContext);
        //        var isVisible = IsVisible(perk, availabilityContext);

        //        if (isAvailable || isVisible)
        //        {
        //            perk.IsAvailable = isAvailable;
        //            availablePerks.Add(perk);
        //        }
        //    }

        //    return availablePerks.ToArray();
        //}

        //public static bool IsPerkVisible(Perk perk, PerkAvailabilityContext availabilityContext)
        //{
        //    var isAvailableByCondition = IsAvailable(perk, availabilityContext);
        //    var isVisible = IsVisible(perk, availabilityContext);

        //    return isAvailableByCondition || isVisible;
        //}

        //public static bool CheckConditions(PerkConditionSubScheme[] conditions, PerkAvailabilityContext availabilityContext)
        //{
        //    foreach (var condition in conditions)
        //    {
        //        if (!CheckOneCondition(condition, availabilityContext))
        //        {
        //            return false;
        //        }
        //    }

        //    return true;
        //}

        //public static PropSet[] CalcTotalSources(PerkScheme perkScheme, int? perkLevel, int perkSubLevel, IDictionary<string, PropScheme> propSchemeDict)
        //{
        //    // Вычисляем текущий уровень перка
        //    CalcLevelScheme(perkScheme.Levels, perkLevel, perkSubLevel,
        //        out PerkLevelSubScheme archievedLevelScheme, out PerkLevelSubScheme targetLevelScheme);

        //    // Вычисляем стоимость
        //    var totalSources = new List<PropSet>();
        //    if (perkScheme.Sources != null)
        //    {
        //        foreach (var propSet in perkScheme.Sources)
        //        {
        //            //TODO Вынести в отдельный метод глубокое клонирование набора ресурсов
        //            totalSources.Add(propSet.Clone());
        //        }
        //    }

        //    if (targetLevelScheme != null && targetLevelScheme.Sources != null)
        //    {
        //        foreach (var propSet in targetLevelScheme.Sources)
        //        {
        //            if (!propSchemeDict.TryGetValue(propSet.PropSid, out PropScheme propScheme))
        //            {
        //                Logger.TraceError(LogCodes.ErrorCommon, $"Не найден предмет с Sid:{propSet.PropSid} при вычислении стоимости уровня {perkLevel}/{perkSubLevel} в перке {perkScheme.Sid}.");
        //            }

        //            var propClass = propScheme.GetPropClass();
        //            switch (propClass)
        //            {
        //                case PropClass.Equipment:
        //                    //Работаем с экипировкой
        //                    var equipmentPropSet = propSet.Clone();
        //                    equipmentPropSet.Count = 1;
        //                    totalSources.Add(equipmentPropSet);
        //                    break;

        //                case PropClass.Resource:
        //                    // Работает с ресурсами
        //                    var existsResource = totalSources.SingleOrDefault(x => x.PropSid == propSet.PropSid);
        //                    if (existsResource == null)
        //                    {
        //                        totalSources.Add(new PropSet
        //                        {
        //                            PropSid = propSet.PropSid,
        //                            Count = propSet.Count
        //                        });
        //                    }
        //                    else
        //                    {
        //                        existsResource.Count += propSet.Count;
        //                    }
        //                    break;

        //                default:
        //                    throw new AppException($"Для предмета Sid:{propScheme.Sid} класса {propClass} нет возможности учавствовать в качестве ресурса для перка. Sid перка: {perkScheme.Sid}");
        //            }
        //        }
        //    }

        //    return totalSources.ToArray();
        //}

        /// <summary>
        /// Преобразование суммарного уровня в уровень/подуровень для конкретной схемы перка.
        /// </summary>
        /// <param name="perkScheme">Схема.</param>
        /// <param name="totalLevel">Суммарный уровень.</param>
        /// <param name="level">Уровень перка.</param>
        /// <param name="subLevel">Подуровень перка.</param>
        public static void ConvertTotalLevel(PerkScheme perkScheme, int totalLevel, out int?level, out int?subLevel)
        {
            var levelRemains           = totalLevel + 1;
            var currentLevelPointer    = 0;
            var currentLevelCapability = 0;

            do
            {
                if (currentLevelPointer >= perkScheme.Levels.Length)
                {
                    level    = null;
                    subLevel = null;
                    return;
                }

                var levelScheme = perkScheme.Levels[currentLevelPointer];
                level    = currentLevelPointer;
                subLevel = levelRemains - 1;
                currentLevelPointer++;
                currentLevelCapability = levelScheme.MaxValue + 1;
                levelRemains          -= currentLevelCapability;
            } while (levelRemains >= currentLevelCapability);
        }
Esempio n. 4
0
        //public static Perk CreatePerk(PerkScheme perkScheme, int? perkLevel, int perkSubLevel, JobSubScheme[] doneLevelJobs, PerkState state, bool isLevelPaid,
        //    IDictionary<string, PerkScheme> perkSchemeDict, IDictionary<string, PropScheme> propSchemeDict)
        //{
        //    var perk = new Perk();

        //    perk.Scheme = perkScheme;

        //    perk.CurrentLevel = perkLevel;
        //    perk.CurrentSubLevel = perkSubLevel;

        //    CalcLevelScheme(perkScheme.Levels, perkLevel, perkSubLevel, out PerkLevelSubScheme archievedLevelScheme, out PerkLevelSubScheme nextLevelScheme);
        //    perk.ArchievedLevelScheme = archievedLevelScheme;
        //    perk.TargetLevelScheme = nextLevelScheme;
        //    perk.IsLevelPaid = isLevelPaid;

        //    if (doneLevelJobs != null)
        //    {
        //        perk.CurrentJobs = doneLevelJobs;
        //    }
        //    else
        //    {
        //        if (perk.TargetLevelScheme != null)
        //        {
        //            perk.CurrentJobs = perk.TargetLevelScheme.Jobs.CopyWithoutProgress();
        //        }
        //    }

        //    perk.State = state;

        //    return perk;
        //}

        public static PerkLevel GetNextLevel(PerkScheme perkScheme, PerkLevel level)
        {
            if (level == null)
            {
                return(new PerkLevel(0, 0));
            }

            var currentLevel    = level.Primary;
            var currentSubLevel = level.Sub;

            var currentLevelScheme = perkScheme.Levels[currentLevel];

            if (currentSubLevel + 1 > currentLevelScheme.MaxValue)
            {
                currentSubLevel = 0;
                currentLevel++;
            }
            else
            {
                currentSubLevel++;
            }

            return(new PerkLevel(currentLevel, currentSubLevel));
        }
Esempio n. 5
0
        public void ApplyProgress_AllJobsAreDone_EvolutionDataLevelUpCalled()
        {
            // ARRANGE
            var perkScheme = new PerkScheme
            {
                Levels = new[]
                {
                    new PerkLevelSubScheme
                    {
                        Jobs = new IJobSubScheme[]
                        {
                            new TestJobSubScheme
                            {
                                Type  = JobType.Defeats,
                                Value = 1
                            }
                        },
                        // Указываем минимальный подуровень.
                        // Чтобы при попытке прокачки не наткнуться на левелкап.
                        MaxValue = 1
                    }
                }
            };

            var perkJobMock = new Mock <IJob>();

            perkJobMock.SetupProperty(x => x.Progress, 1);
            perkJobMock.SetupGet(x => x.Scheme)
            .Returns(perkScheme.Levels[0].Jobs[0]);
            perkJobMock.SetupProperty(x => x.IsComplete);
            var perkJob = perkJobMock.Object;

            var progressMock = new Mock <IJobProgress>();

            progressMock.Setup(x => x.ApplyToJobs(It.IsAny <IEnumerable <IJob> >()))
            .Returns(new[] { perkJob });
            var progress = progressMock.Object;

            var perkMock = new Mock <IPerk>();

            perkMock.SetupGet(x => x.Scheme)
            .Returns(perkScheme);
            perkMock.SetupGet(x => x.CurrentLevel)
            // Перки, которые могут прокачиваться, должны обладать уровнем.
            // (0, 0) это минимальный уровень.
            .Returns(new PerkLevel(0, 0));
            var perk = perkMock.Object;

            var perks = new[]
            {
                perk
            };
            var evolutionModuleMock = new Mock <IEvolutionModule>();

            evolutionModuleMock.SetupGet(x => x.Perks)
            .Returns(perks);
            var evolutionModule = evolutionModuleMock.Object;

            var perkResolver = new PerkResolver();

            // ACT
            perkResolver.ApplyProgress(progress, evolutionModule);

            // ASSERT
            evolutionModuleMock.Verify(x => x.PerkLevelUp(It.IsAny <IPerk>()));
        }
Esempio n. 6
0
        public void ApplyProgress_AllJobsAreDone_EvolutionDataLevelUpCalled()
        {
            // ARRANGE
            var perkScheme = new PerkScheme
            {
                Levels = new[] {
                    new PerkLevelSubScheme {
                        Jobs = new IJobSubScheme[] {
                            new TestJobSubScheme {
                                Type  = JobType.Defeats,
                                Value = 1
                            }
                        }
                    }
                }
            };

            var perkJobMock = new Mock <IJob>();

            perkJobMock.SetupProperty(x => x.Progress, 1);
            perkJobMock.SetupGet(x => x.Scheme)
            .Returns(perkScheme.Levels[0].Jobs[0]);
            perkJobMock.SetupProperty(x => x.IsComplete);
            var perkJob = perkJobMock.Object;


            var progressMock = new Mock <IJobProgress>();

            progressMock.Setup(x => x.ApplyToJobs(It.IsAny <IEnumerable <IJob> >()))
            .Returns(new[] { perkJob });
            var progress = progressMock.Object;

            var perkMock = new Mock <IPerk>();

            perkMock.SetupGet(x => x.Scheme)
            .Returns(perkScheme);
            perkMock.SetupGet(x => x.CurrentLevel)
            .Returns((PerkLevel)null);
            var perk = perkMock.Object;

            var perks = new[] {
                perk
            };
            var evolutionDataMock = new Mock <IEvolutionData>();

            evolutionDataMock.SetupGet(x => x.Perks)
            .Returns(perks);
            var evolutionData = evolutionDataMock.Object;

            var perkResolver = new PerkResolver();



            // ACT
            perkResolver.ApplyProgress(progress, evolutionData);



            // ASSERT
            evolutionDataMock.Verify(x => x.PerkLevelUp(It.IsAny <IPerk>()));
        }