public void CastTestPushbackChannelSkill() { long delay = 10; BaseEntity mob = new MockEntity(Engine); double expectedMobHealth = mob.GetProperty(Entity.HP_KEY).Value - 50; _testPlayer.Cast(mob, _testChannelSkill.Key); _testPlayer.AddPushback(delay); MockTimer timer = (MockTimer)Engine.GetTimer(); MeNode duration = _testChannelSkill.ByLevel[0].Duration; duration = Sanitizer.ReplaceTargetAndSource(duration, _testPlayer, _testPlayer); long skillDuration = duration.Resolve().Value.ToLong(); for (int i = 0; i < skillDuration; ++i) { timer.ForceTick(); _testPlayer.Update(); mob.Update(); } timer.ForceTick(); _testPlayer.Update(); mob.Update(); Assert.AreEqual(expectedMobHealth, mob.GetProperty(Entity.HP_KEY).Value); }
public void CastTestNonInterrupt() { BaseEntity mob = new MockEntity(Engine); double expectedMobHealth = mob.GetProperty(Entity.HP_KEY).Value - 10; _testPlayer.Cast(mob, _unpushable.Key); _testPlayer.InterruptCasting(); MockTimer timer = (MockTimer)Engine.GetTimer(); MeNode duration = _unpushable.ByLevel[0].Duration; duration = Sanitizer.ReplaceTargetAndSource(duration, _testPlayer, _testPlayer); long skillDuration = duration.Resolve().Value.ToLong(); for (int i = 0; i < skillDuration; ++i) { timer.ForceTick(); } timer.ForceTick(); _testPlayer.Update(); Assert.AreEqual(expectedMobHealth, mob.GetProperty(Entity.HP_KEY).Value); }
public SkillCastData(SkillInstance instance, Entity target, Entity source, long now) { Skill = instance; Target = target; Source = source; MeNode interruptible = Skill.Values().Interruptible; interruptible = Sanitizer.ReplaceTargetAndSource(interruptible, Source, Target); Interruptible = interruptible.Resolve().Value.ToBoolean(); MeNode pushbackAble = Skill.Values().PushBack; pushbackAble = Sanitizer.ReplaceTargetAndSource(pushbackAble, Source, Target); PushBackable = pushbackAble.Resolve().Value.ToBoolean(); NextInterval = 0; MeNode castDuration = Skill.Values().Duration; castDuration = Sanitizer.ReplaceTargetAndSource(castDuration, Source, Target); CastFinishTime = now + (long)castDuration.Resolve().Value.ToDouble() * 1000; if (Skill.Skill.Type == SkillType.Channel) { MeNode interval = Skill.Values().Interval; interval = Sanitizer.ReplaceTargetAndSource(interval, Source, Target); Interval = interval.Resolve().Value.ToLong(); } else { Interval = 0; } }
private void AddStatusFromTemplate(StatusTemplate status, Entity source, double duration, double[] values) { long removeTime = GetRemoveTime(duration); AppliedStatus newStatus = new AppliedStatus() { Source = source, LastTick = 0, RemovalTime = removeTime, Template = status, NumericValues = values }; MeNode intervalTree = Sanitizer.ReplaceTargetAndSource(status.Interval, source, this); newStatus.Interval = intervalTree.Resolve().Value.ToLong(); Statuses.Add(newStatus); foreach (MeNode tree in newStatus.Template.Modifiers) { StatModifier mod = Engine.GetSanitizer().ResolveStatus(tree, newStatus.NumericValues).ToModifier(); newStatus.MyMods.Add(mod); Attributes[mod.StatKey].Modifiers.Add(mod); } RefreshProperties(); int stackCount = 0; foreach (AppliedStatus sts in Statuses) { if (sts.Template.Key.Equals(newStatus.Template.Key)) { ++stackCount; } } Engine.Log().Log($"[{Name}] Affected by {status.Name}[{stackCount}]."); }
private void SetCurrentCD() { //set skill's cooldown] if (CurrentlyCasting == null) { return; } MeNode cd = CurrentlyCasting.Skill.Values().Cooldown; cd = Sanitizer.ReplaceTargetAndSource(cd, this, CurrentlyCasting.Target); CurrentlyCasting.Skill.CooldownFinishTime = Engine.GetTimer().GetFuture((long)cd.Resolve().Value.ToDouble()); }
private void TickCurrentCast() { if (CurrentlyCasting == null) { return; } long now = Engine.GetTimer().GetNow(); if (CurrentlyCasting.Skill.Skill.Type == SkillType.Cast) { if (CurrentlyCasting.CastFinishTime <= now) { string castedFinish = Key.Equals(CurrentlyCasting.Target.Key) ? "" : $" on {CurrentlyCasting.Target.Name}"; Engine.Log().Log($"[{Name}] Casted {CurrentlyCasting.Skill.Skill.Name}{castedFinish}."); //casting has finished so resolve the formula MeNode[] toResolve = CurrentlyCasting.Skill.Formulas; foreach (MeNode node in toResolve) { MeNode sanitized = Sanitizer.ReplaceTargetAndSource(node, this, CurrentlyCasting.Target); sanitized.Resolve(); } FinishCasting(); } } else if (CurrentlyCasting.Skill.Skill.Type == SkillType.Channel) { if (CurrentlyCasting.CastFinishTime <= now) { Engine.Log().Log($"[{Name}] Finished channeling {CurrentlyCasting.Skill.Skill.Name}."); FinishCasting(); } else { //apply the formulas if it's the case if (CurrentlyCasting.NextInterval == 0 || CurrentlyCasting.NextInterval < now) { MeNode[] toResolve = CurrentlyCasting.Skill.Formulas; foreach (MeNode node in toResolve) { Sanitizer.ReplaceTargetAndSource(node, this, CurrentlyCasting.Target).Resolve(); } CurrentlyCasting.NextInterval = now + CurrentlyCasting.Interval * 1000; } } } }
public double GetMitigatedAmount(double amount, Entity source, Entity target) { bool crited; if (CriticalChance != null) { MeNode resolvedCritChance = Sanitizer.ReplaceTargetAndSource(CriticalChance, source, target) .Resolve(); crited = Utils.Utility.Chance(resolvedCritChance.Value.ToDouble()); } else { crited = false; } double mutliplier = 1.0; if (crited) { if (CriticalModifier != null) { mutliplier = Sanitizer.ReplaceTargetAndSource(CriticalModifier, source, target) .Resolve().Value.ToDouble(); } } double finalAmount = mutliplier * amount; if (Mitigation != null) { MeNode mitigation = Sanitizer.SanitizeMitigation(Mitigation, target, source, finalAmount) .Resolve(); return(mitigation.Value.ToDouble()); } else { return(finalAmount); } }
public void CastTestChannelSkill() { BaseEntity mob = new MockEntity(Engine); double expected = mob.GetProperty(Entity.HP_KEY).Value - 60; _testPlayer.Cast(mob, _testChannelSkill.Key); MockTimer timer = (MockTimer)Engine.GetTimer(); MeNode duration = _testChannelSkill.ByLevel[0].Duration; duration = Sanitizer.ReplaceTargetAndSource(duration, _testPlayer, _testPlayer); long skillDuration = duration.Resolve().Value.ToLong(); for (int i = 0; i <= skillDuration; ++i) { timer.ForceTick(); _testPlayer.Update(); } double actual = mob.GetProperty(Entity.HP_KEY).Value; Assert.AreEqual(expected, actual); }
public void CastTestFormulaIsExecutedWithTime() { double expected = _testPlayer.GetProperty(Entity.HP_KEY).Value - 10; double before = _testPlayer.GetProperty(Entity.HP_KEY).Value; _testPlayer.Cast(_testPlayer, _testSkill.Key); MockTimer timer = (MockTimer)Engine.GetTimer(); MeNode duration = _testSkill.ByLevel[0].Duration; duration = Sanitizer.ReplaceTargetAndSource(duration, _testPlayer, _testPlayer); double actual; long skillDuration = duration.Resolve().Value.ToLong();; for (int i = 0; i < skillDuration; ++i) { timer.ForceTick(); actual = _testPlayer.GetProperty(Entity.HP_KEY).Value; Assert.AreEqual(before, actual); _testPlayer.Update(); } actual = _testPlayer.GetProperty(Entity.HP_KEY).Value; Assert.AreEqual(expected, actual); }
private void ApplyHealAndHarm() { foreach (AppliedStatus status in Statuses) { if (IsTime(status)) { foreach (MeNode tree in status.Template.HpMods) { MeNode newTree = Sanitizer.ReplaceTargetAndSource(tree, status.Source, this); Engine.GetSanitizer().ReplaceNumericPlaceholders(newTree, status.NumericValues); newTree = newTree.Resolve(); if (tree.Value.GetString() == LConstants.HEAL_F) { status.TotalHeal += newTree.Value.ToDouble(); } else { status.TotalDamamge += newTree.Value.ToDouble(); } } status.LastTick = Engine.GetTimer().GetNow(); } } }
public bool GetDodge(Entity source, Entity target) { return(Dodge != null && Utils.Utility.Chance(Sanitizer.ReplaceTargetAndSource(Dodge, source, target).Resolve().Value.ToDouble())); }