private SkillLevelTemplate LevelFromJson(JObject levelValue, SkillTemplate skill) { SkillLevelTemplate levelTemplate = new SkillLevelTemplate(); //get cost levelTemplate.Cost = CostFromJson(levelValue[GcConstants.Skills.COST], skill); //get needed level, push-back and interrupt because they have default values levelTemplate.NeededLevel = JsonUtils.GetValueOrDefault <long>(levelValue, GcConstants.Skills.NEEDED_LEVEL, GcConstants.Skills.DEFAULT_NEEDED_LEVEL); levelTemplate.PushBack = new MeNode(JsonUtils.GetValueOrDefault(levelValue, GcConstants.Skills.PUSH_BACK, GcConstants.Skills.DEFAULT_PUSHBACK)); levelTemplate.Interruptible = new MeNode(JsonUtils.GetValueOrDefault(levelValue, GcConstants.Skills.INTERRUPT, GcConstants.Skills.DEFAULT_INTERRUPT)); //get cast duration string durationFormula = JsonUtils.GetValueOrDefault(levelValue, GcConstants.Skills.CAST_DURATION, GcConstants.Skills.DEFAULT_CAST_DURATION); levelTemplate.Duration = TreeConverter.Build(durationFormula, Engine); //get cooldown string cdFormula = JsonUtils.GetValueOrDefault( levelValue, GcConstants.Skills.COOLDOWN, GcConstants.Skills.DEFAULT_COOLDOWN); levelTemplate.Cooldown = TreeConverter.Build(cdFormula, Engine); //get skill threat string threatFormula = JsonUtils.GetValueOrDefault <string>(levelValue, GcConstants.Skills.THREAT, null); if (threatFormula == null) { threatFormula = Engine.GetCoreManager().DefaultSkillThreat.ToString(); } levelTemplate.SkillThreat = TreeConverter.Build(threatFormula, Engine); //get formulas string formulas = JsonUtils.ValidateJsonEntry(GcConstants.General.FORMULA, levelValue, JTokenType.String, $"Missing formula for skill {skill.Name}.").ToString(); levelTemplate.Formulas.AddRange(Engine.GetSanitizer().SplitAndConvert(formulas)); //get interval if (skill.Type == SkillType.Channel) { string intervalFormula = JsonUtils.GetValueOrDefault( levelValue, GcConstants.Skills.INTERVAL, GcConstants.Skills.DEFAULT_INTERVAL_VALUE); levelTemplate.Interval = TreeConverter.Build(intervalFormula, Engine); } return(levelTemplate); }
public static void StartUp(TestContext ctx) { Definer.Instance().Engine = Engine; DamageTypeTemplate trueDamage = new DamageTypeTemplate(Engine, null, null, null, null); trueDamage.Name = "true"; trueDamage.Key = "T"; Engine.AddDamageType(trueDamage); ResourceTemplate res = new ResourceTemplate() { Key = "MP" }; SkillCost nullCost = new SkillCost(res, TreeConverter.Build("0", Engine)); _testSkill = new SkillTemplate(); _testSkill.Type = SkillType.Cast; _testSkill.Key = "TEST_CAST"; SkillLevelTemplate testLevelTemplate = new SkillLevelTemplate(); testLevelTemplate.Cooldown = TreeConverter.Build("3", Engine); testLevelTemplate.Duration = TreeConverter.Build($"{LConstants.SourceKeyword}{LConstants.PROP_OP}INT", Engine); testLevelTemplate.Interruptible = TreeConverter.Build("true", Engine); testLevelTemplate.Formulas.Add(TreeConverter.Build($"{LConstants.HARM_F}({LConstants.TargetKeyword},{LConstants.SourceKeyword},{trueDamage.Key},10)", Engine)); testLevelTemplate.PushBack = TreeConverter.Build("true", Engine); testLevelTemplate.Cost = nullCost; _testSkill.ByLevel.Add(testLevelTemplate); Engine.GetSkillManager().AddSkill(_testSkill); BaseObject bDmg = new BaseObject() { Description = "", Key = "BASE_DMG", Name = "Base damage" }; Engine.GetPropertyManager().BaseValues.Add("BASE_DMG", bDmg); BaseObject intellect = new BaseObject() { Description = "", Key = "INT", Name = "Intellect" }; Engine.GetPropertyManager().Attributes.Add("INT", intellect); }
public void SkillReaderTestDefaultValues() { string key = "TEST_STATUS"; string jsonStr = $"{{\"{GcConstants.General.KEY}\":\"{key}\","; jsonStr += $"\"{GcConstants.Skills.VALUES_BY_LEVEL}\":["; jsonStr += "{"; jsonStr += $"\"{GcConstants.General.FORMULA}\":"; jsonStr += $"\"{LConstants.HARM_F}({LConstants.TargetKeyword},{LConstants.SourceKeyword},T,10)\""; jsonStr += "}"; jsonStr += "]}"; JObject json = JObject.Parse(jsonStr); SkillTemplate skill = Reader.FromJson(json); Assert.AreEqual(skill.Key, key); Assert.AreEqual(1, skill.Aliases.Count); Assert.AreEqual(key, skill.Aliases[0]); Assert.AreEqual(skill.Type, SkillType.Cast); Assert.AreEqual(1, skill.ByLevel.Count); SkillLevelTemplate levelTemplate = skill.ByLevel[0]; Assert.AreEqual(double.Parse(GcConstants.Skills.DEFAULT_COST_VALUE), levelTemplate.Cost.Amount.Value.ToDouble()); Assert.AreEqual(Entity.HP_KEY, levelTemplate.Cost.Resource.Key); Assert.AreEqual(GcConstants.Skills.DEFAULT_NEEDED_LEVEL, levelTemplate.NeededLevel); Assert.AreEqual(double.Parse(GcConstants.Skills.DEFAULT_CAST_DURATION), levelTemplate.Duration.Value.ToDouble()); Assert.AreEqual(double.Parse(GcConstants.Skills.DEFAULT_COOLDOWN), levelTemplate.Cooldown.Value.ToDouble()); Assert.AreEqual(GcConstants.Core.DEFAULT_THREAT, levelTemplate.SkillThreat.Value.ToDouble()); Assert.IsNull(levelTemplate.Interval); Assert.AreEqual(GcConstants.Skills.DEFAULT_INTERRUPT, levelTemplate.PushBack.Value.ToBoolean()); Assert.AreEqual(GcConstants.Skills.DEFAULT_PUSHBACK, levelTemplate.Interruptible.Value.ToBoolean()); Assert.AreEqual(1, levelTemplate.Formulas.Count); Assert.IsNotNull(levelTemplate.Formulas[0]); }
public static IDictionary <TemporaryStatType, short> GetTemporaryStats(this SkillLevelTemplate template) { var stats = new Dictionary <TemporaryStatType, short>(); if (template.PAD != 0) { stats.Add(TemporaryStatType.PAD, template.PAD); } if (template.PDD != 0) { stats.Add(TemporaryStatType.PDD, template.PDD); } if (template.MAD != 0) { stats.Add(TemporaryStatType.MAD, template.MAD); } if (template.MDD != 0) { stats.Add(TemporaryStatType.MDD, template.MDD); } if (template.ACC != 0) { stats.Add(TemporaryStatType.ACC, template.ACC); } if (template.EVA != 0) { stats.Add(TemporaryStatType.EVA, template.EVA); } if (template.Craft != 0) { stats.Add(TemporaryStatType.Craft, template.Craft); } if (template.Speed != 0) { stats.Add(TemporaryStatType.Speed, template.Speed); } if (template.Jump != 0) { stats.Add(TemporaryStatType.Jump, template.Jump); } if (template.Morph > 0) { stats.Add(TemporaryStatType.Morph, template.Morph); } if (template.EMHP != 0) { stats.Add(TemporaryStatType.EMHP, template.EMHP); } if (template.EMMP != 0) { stats.Add(TemporaryStatType.EMMP, template.EMMP); } if (template.EPAD != 0) { stats.Add(TemporaryStatType.EPAD, template.EPAD); } if (template.EPDD != 0) { stats.Add(TemporaryStatType.EPDD, template.EPDD); } // if (template.EMAD != 0) temporaryStats.Add(TemporaryStatType.EMAD, template.EMAD); if (template.EMDD != 0) { stats.Add(TemporaryStatType.EMDD, template.EMDD); } switch ((Skill)template.SkillID) { case Skill.MagicianMagicGuard: case Skill.FlamewizardMagicGuard: case Skill.EvanMagicGuard: stats.Add(TemporaryStatType.MagicGuard, template.X); break; case Skill.RogueDarkSight: case Skill.NightwalkerDarkSight: stats.Add(TemporaryStatType.DarkSight, template.X); break; case Skill.FighterWeaponBooster: case Skill.PageWeaponBooster: case Skill.SpearmanWeaponBooster: case Skill.Mage1MagicBooster: case Skill.Mage2MagicBooster: case Skill.HunterBowBooster: case Skill.CrossbowmanCrossbowBooster: case Skill.AssassinJavelinBooster: case Skill.ThiefDaggerBooster: case Skill.Dual1DualBooster: case Skill.InfighterKnuckleBooster: case Skill.GunslingerGunBooster: case Skill.StrikerKnuckleBooster: case Skill.SoulmasterSwordBooster: case Skill.FlamewizardMagicBooster: case Skill.WindbreakerBowBooster: case Skill.NightwalkerJavelinBooster: case Skill.AranPolearmBooster: case Skill.EvanMagicBooster: case Skill.BmageStaffBooster: case Skill.WildhunterCrossbowBooster: case Skill.MechanicBooster: stats.Add(TemporaryStatType.Booster, template.X); break; case Skill.FighterPowerGuard: case Skill.PagePowerGuard: stats.Add(TemporaryStatType.PowerGuard, template.X); break; case Skill.NoviceHyperBody: case Skill.SpearmanHyperBody: case Skill.AdminHyperBody: case Skill.NoblesseHyperBody: case Skill.LegendHyperBody: case Skill.EvanjrHyperBody: case Skill.CitizenHyperBody: stats.Add(TemporaryStatType.MaxHP, template.X); stats.Add(TemporaryStatType.MaxMP, template.Y); break; case Skill.ClericInvincible: stats.Add(TemporaryStatType.Invincible, template.X); break; case Skill.HunterSoulArrowBow: case Skill.CrossbowmanSoulArrowCrossbow: case Skill.WindbreakerSoulArrowBow: case Skill.WildhunterSoulArrowCrossbow: stats.Add(TemporaryStatType.SoulArrow, template.X); break; // TODO: Combo attack // TODO: Weapon charge case Skill.DragonknightDragonBlood: stats.Add(TemporaryStatType.DragonBlood, template.X); break; case Skill.PriestHolySymbol: case Skill.AdminHolySymbol: stats.Add(TemporaryStatType.HolySymbol, template.X); break; case Skill.HermitMesoUp: stats.Add(TemporaryStatType.MesoUp, template.X); break; case Skill.HermitShadowPartner: case Skill.ThiefmasterShadowPartner: case Skill.Dual4MirrorImaging: case Skill.NightwalkerShadowPartner: stats.Add(TemporaryStatType.ShadowPartner, template.X); break; case Skill.ThiefmasterPickpocket: stats.Add(TemporaryStatType.PickPocket, template.X); break; case Skill.ThiefmasterMesoGuard: stats.Add(TemporaryStatType.MesoGuard, template.X); break; case Skill.HeroMapleHero: case Skill.PaladinMapleHero: case Skill.DarkknightMapleHero: case Skill.Archmage1MapleHero: case Skill.Archmage2MapleHero: case Skill.BishopMapleHero: case Skill.BowmasterMapleHero: case Skill.CrossbowmasterMapleHero: case Skill.NightlordMapleHero: case Skill.ShadowerMapleHero: case Skill.Dual5MapleHero: case Skill.ViperMapleHero: case Skill.CaptainMapleHero: case Skill.AranMapleHero: case Skill.EvanMapleHero: case Skill.BmageMapleHero: case Skill.WildhunterMapleHero: case Skill.MechanicMapleHero: stats.Add(TemporaryStatType.BasicStatUp, template.X); break; case Skill.HeroStance: case Skill.PaladinStance: case Skill.DarkknightStance: case Skill.AranFreezeStanding: case Skill.BmageStance: stats.Add(TemporaryStatType.Stance, template.X); break; // TODO: sharp eyes case Skill.Archmage1ManaReflection: case Skill.Archmage2ManaReflection: case Skill.BishopManaReflection: stats.Add(TemporaryStatType.ManaReflection, template.X); break; case Skill.NightlordSpiritJavelin: stats.Add(TemporaryStatType.SpiritJavelin, template.X); break; case Skill.Archmage1Infinity: case Skill.Archmage2Infinity: case Skill.BishopInfinity: stats.Add(TemporaryStatType.Infinity, template.X); break; case Skill.BishopHolyShield: stats.Add(TemporaryStatType.Holyshield, template.X); break; case Skill.BowmasterHamstring: stats.Add(TemporaryStatType.HamString, template.X); break; case Skill.CrossbowmasterBlind: case Skill.WildhunterBlind: stats.Add(TemporaryStatType.Blind, template.X); break; case Skill.BowmasterConcentration: stats.Add(TemporaryStatType.Concentration, template.X); break; case Skill.NoviceMaxlevelEchobuff: case Skill.NoblesseMaxlevelEchobuff: case Skill.LegendMaxlevelEchobuff: case Skill.EvanjrMaxlevelEchobuff: case Skill.CitizenMaxlevelEchobuff: stats.Add(TemporaryStatType.MaxLevelBuff, template.X); break; } return(stats); }
public static IDictionary <TemporaryStatType, short> GetTemporaryStats(this SkillLevelTemplate template) { var stats = new Dictionary <TemporaryStatType, short>(); if (template.PAD > 0) { stats.Add(TemporaryStatType.PAD, template.PAD); } if (template.PDD > 0) { stats.Add(TemporaryStatType.PDD, template.PDD); } if (template.MAD > 0) { stats.Add(TemporaryStatType.MAD, template.MAD); } if (template.MDD > 0) { stats.Add(TemporaryStatType.MDD, template.MDD); } if (template.ACC > 0) { stats.Add(TemporaryStatType.ACC, template.ACC); } if (template.EVA > 0) { stats.Add(TemporaryStatType.EVA, template.EVA); } if (template.Craft > 0) { stats.Add(TemporaryStatType.Craft, template.Craft); } if (template.Speed > 0) { stats.Add(TemporaryStatType.Speed, template.Speed); } if (template.Jump > 0) { stats.Add(TemporaryStatType.Jump, template.Jump); } if (template.Morph > 0) { stats.Add(TemporaryStatType.Morph, template.Morph); } if (template.EMHP > 0) { stats.Add(TemporaryStatType.EMHP, template.EMHP); } if (template.EMMP > 0) { stats.Add(TemporaryStatType.EMMP, template.EMMP); } if (template.EPAD > 0) { stats.Add(TemporaryStatType.EPAD, template.EPAD); } if (template.EPDD > 0) { stats.Add(TemporaryStatType.EPDD, template.EPDD); } // if (template.EMAD > 0) temporaryStats.Add(TemporaryStatType.EMAD, template.EMAD); if (template.EMDD > 0) { stats.Add(TemporaryStatType.EMDD, template.EMDD); } var skill = (Skill)template.TemplateID; switch (skill) { case Skill.MagicianMagicGuard: case Skill.FlamewizardMagicGuard: case Skill.EvanMagicGuard: stats.Add(TemporaryStatType.MagicGuard, template.X); break; case Skill.RogueDarkSight: case Skill.NightwalkerDarkSight: stats.Add(TemporaryStatType.DarkSight, template.X); break; case Skill.FighterWeaponBooster: case Skill.PageWeaponBooster: case Skill.SpearmanWeaponBooster: case Skill.Mage1MagicBooster: case Skill.Mage2MagicBooster: case Skill.HunterBowBooster: case Skill.CrossbowmanCrossbowBooster: case Skill.AssassinJavelinBooster: case Skill.ThiefDaggerBooster: case Skill.Dual1DualBooster: case Skill.InfighterKnuckleBooster: case Skill.GunslingerGunBooster: case Skill.StrikerKnuckleBooster: case Skill.SoulmasterSwordBooster: case Skill.FlamewizardMagicBooster: case Skill.WindbreakerBowBooster: case Skill.NightwalkerJavelinBooster: case Skill.AranPolearmBooster: case Skill.EvanMagicBooster: case Skill.BmageStaffBooster: case Skill.WildhunterCrossbowBooster: case Skill.MechanicBooster: stats.Add(TemporaryStatType.Booster, template.X); break; case Skill.FighterPowerGuard: case Skill.PagePowerGuard: stats.Add(TemporaryStatType.PowerGuard, template.X); break; case Skill.NoviceHyperBody: case Skill.SpearmanHyperBody: case Skill.AdminHyperBody: case Skill.NoblesseHyperBody: case Skill.LegendHyperBody: case Skill.EvanjrHyperBody: case Skill.CitizenHyperBody: stats.Add(TemporaryStatType.MaxHP, template.X); stats.Add(TemporaryStatType.MaxMP, template.Y); break; case Skill.ClericInvincible: stats.Add(TemporaryStatType.Invincible, template.X); break; case Skill.HunterSoulArrowBow: case Skill.CrossbowmanSoulArrowCrossbow: case Skill.WindbreakerSoulArrowBow: case Skill.WildhunterSoulArrowCrossbow: stats.Add(TemporaryStatType.SoulArrow, template.X); break; // TODO: more buffs } return(stats); }
public static void StartUp(TestContext context) { DamageTypeTemplate trueDamage = new DamageTypeTemplate(Engine, null, null, null, null); trueDamage.Key = "T"; trueDamage.Name = "true"; Engine.AddDamageType(trueDamage); ResourceTemplate res = new ResourceTemplate() { Key = "MP" }; SkillCost nullCost = new SkillCost(res, TreeConverter.Build("0", Engine)); SkillCost notFree = new SkillCost(res, TreeConverter.Build("50", Engine)); _testSkill = new SkillTemplate(); _testSkill.Type = SkillType.Cast; _testSkill.Key = "TEST_CAST"; SkillLevelTemplate testLevelTemplate = new SkillLevelTemplate(); testLevelTemplate.Cooldown = TreeConverter.Build("3", Engine); testLevelTemplate.Duration = TreeConverter.Build($"{LConstants.SourceKeyword}{LConstants.PROP_OP}INT", Engine); testLevelTemplate.Interruptible = TreeConverter.Build("true", Engine); testLevelTemplate.Formulas.Add(TreeConverter.Build($"{LConstants.HARM_F}({LConstants.TargetKeyword},{LConstants.SourceKeyword},{trueDamage.Key},10)", Engine)); testLevelTemplate.PushBack = TreeConverter.Build("true", Engine); testLevelTemplate.Cost = nullCost; _testSkill.ByLevel.Add(testLevelTemplate); _testChannelSkill = new SkillTemplate(); _testChannelSkill.Type = SkillType.Channel; _testChannelSkill.Key = "TEST_CHANNEL"; SkillLevelTemplate testLevelTemplate2 = new SkillLevelTemplate(); testLevelTemplate2.Cooldown = TreeConverter.Build("120", Engine); testLevelTemplate2.Duration = TreeConverter.Build("60", Engine); testLevelTemplate2.Interval = TreeConverter.Build("10", Engine); testLevelTemplate2.PushBack = TreeConverter.Build("true", Engine); testLevelTemplate2.Interruptible = TreeConverter.Build("true", Engine); testLevelTemplate2.Cost = nullCost; MeNode channelFormula = TreeConverter.Build( $"{LConstants.HARM_F}({LConstants.TargetKeyword},{LConstants.SourceKeyword},{trueDamage.Key},10)", Engine); Engine.GetSanitizer().SetHarmsToPeriodic(channelFormula); testLevelTemplate2.Formulas.Add(channelFormula); _testChannelSkill.ByLevel.Add(testLevelTemplate2); _instantHarm = new SkillTemplate(); _instantHarm.Type = SkillType.Cast; _instantHarm.Key = "HURT"; SkillLevelTemplate hurtLevelTemplate = new SkillLevelTemplate(); hurtLevelTemplate.Cooldown = TreeConverter.Build("0", Engine); hurtLevelTemplate.Duration = TreeConverter.Build("0", Engine); hurtLevelTemplate.PushBack = TreeConverter.Build("false", Engine); hurtLevelTemplate.Interruptible = TreeConverter.Build("true", Engine); hurtLevelTemplate.Formulas.Add(TreeConverter.Build($"{LConstants.HARM_F}({LConstants.TargetKeyword},{LConstants.SourceKeyword},{trueDamage.Key},10)", Engine)); hurtLevelTemplate.Cost = nullCost; _instantHarm.ByLevel.Add(hurtLevelTemplate); _unpushable = new SkillTemplate(); _unpushable.Type = SkillType.Cast; _unpushable.Key = "NOPUSH"; SkillLevelTemplate unpushTemplate = new SkillLevelTemplate(); unpushTemplate.Cooldown = TreeConverter.Build("0", Engine); unpushTemplate.Duration = TreeConverter.Build("5", Engine); unpushTemplate.Interruptible = TreeConverter.Build("false", Engine); unpushTemplate.PushBack = TreeConverter.Build("false", Engine); unpushTemplate.Formulas.Add(TreeConverter.Build($"{LConstants.HARM_F}({LConstants.TargetKeyword},{LConstants.SourceKeyword},{trueDamage.Key},10)", Engine)); unpushTemplate.Cost = nullCost; _unpushable.ByLevel.Add(unpushTemplate); _costly = new SkillTemplate(); _costly.Type = SkillType.Cast; _costly.Key = "COSTLY"; SkillLevelTemplate costlyTemplate = new SkillLevelTemplate(); costlyTemplate.Cooldown = TreeConverter.Build("0", Engine); costlyTemplate.Duration = TreeConverter.Build("0", Engine); costlyTemplate.Interruptible = TreeConverter.Build("true", Engine); costlyTemplate.Formulas.Add(TreeConverter.Build($"{LConstants.HARM_F}({LConstants.TargetKeyword},{LConstants.SourceKeyword},{trueDamage.Key},10)", Engine)); costlyTemplate.PushBack = TreeConverter.Build("true", Engine); costlyTemplate.Cost = notFree; _costly.ByLevel.Add(costlyTemplate); _skillUsingStat = new SkillTemplate(); _skillUsingStat.Type = SkillType.Cast; _skillUsingStat.Key = "WITH_STAT"; SkillLevelTemplate withStaTemplate = new SkillLevelTemplate(); withStaTemplate.Cooldown = TreeConverter.Build("0", Engine); withStaTemplate.Duration = TreeConverter.Build("0", Engine); withStaTemplate.Interruptible = TreeConverter.Build("true", Engine); withStaTemplate.Formulas.Add(TreeConverter.Build($"{LConstants.HARM_F}({LConstants.TargetKeyword},{LConstants.SourceKeyword},{trueDamage.Key},10*{LConstants.SourceKeyword}{LConstants.PROP_OP}STR+{LConstants.GET_PROP_F}({LConstants.SourceKeyword},{BASE_VALUE}))", Engine)); withStaTemplate.PushBack = TreeConverter.Build("true", Engine); withStaTemplate.Cost = nullCost; _skillUsingStat.ByLevel.Add(withStaTemplate); }
public void SkillReaderTestNonDefaultValue() { string key = "TEST_STATUS"; string testAlias = "TEST_ALIAS"; string testAlias2 = "TEST_ALIAS2"; JObject json = new JObject(); json.Add(new JProperty(GcConstants.General.KEY, key)); json.Add(new JProperty(GcConstants.Skills.ALIASES, new JArray(new[] { testAlias, testAlias2 }))); json.Add(GcConstants.Skills.SKILL_TYPE, SkillType.Channel.ToString().ToLower()); JArray valuesByLevel = new JArray(); JObject valueByLevel1 = new JObject(); valueByLevel1.Add(GcConstants.General.FORMULA, $"{LConstants.HARM_F}({LConstants.TargetKeyword},{LConstants.SourceKeyword},T,10)"); valueByLevel1.Add(GcConstants.Skills.CAST_DURATION, "10*10"); JObject cost = new JObject(); cost.Add(GcConstants.General.KEY, "MP"); cost.Add(GcConstants.General.VALUE, 100); valueByLevel1.Add(GcConstants.Skills.COST, cost); long level = 10; valueByLevel1.Add(GcConstants.Skills.NEEDED_LEVEL, level); long cd = 25; valueByLevel1.Add(GcConstants.Skills.COOLDOWN, cd); long interval = 15; valueByLevel1.Add(GcConstants.Skills.INTERVAL, interval); long threat = 3; valueByLevel1.Add(GcConstants.Skills.THREAT, threat); valueByLevel1.Add(GcConstants.Skills.INTERRUPT, false); valueByLevel1.Add(GcConstants.Skills.PUSH_BACK, false); valuesByLevel.Add(valueByLevel1); json.Add(new JProperty(GcConstants.Skills.VALUES_BY_LEVEL, valuesByLevel)); SkillTemplate skill = Reader.FromJson(json); SkillLevelTemplate levelTemplate = skill.ByLevel[0]; Assert.AreEqual(2, skill.Aliases.Count); Assert.AreEqual(testAlias, skill.Aliases[0]); Assert.AreEqual(testAlias2, skill.Aliases[1]); Assert.AreEqual(skill.Key, key); Assert.AreEqual(skill.Type, SkillType.Channel); Assert.AreEqual(1, skill.ByLevel.Count); Assert.AreEqual(100, levelTemplate.Cost.Amount.Value.ToDouble()); Assert.AreEqual("MP", levelTemplate.Cost.Resource.Key); Assert.AreEqual(100, levelTemplate.Duration.Resolve().Value.ToDouble()); Assert.AreEqual(cd, levelTemplate.Cooldown.Value.ToDouble()); Assert.AreEqual(level, levelTemplate.NeededLevel); Assert.AreEqual(threat, levelTemplate.SkillThreat.Value.ToDouble()); Assert.AreEqual(interval, levelTemplate.Interval.Value.ToDouble()); Assert.AreEqual(false, levelTemplate.PushBack.Value.ToBoolean()); Assert.AreEqual(false, levelTemplate.Interruptible.Value.ToBoolean()); Assert.AreEqual(1, levelTemplate.Formulas.Count); Assert.IsNotNull(levelTemplate.Formulas[0]); }