/// <summary> /// Handles training based on what happened in the combat action. /// </summary> /// <param name="tAction"></param> private void OnCreatureAttack(TargetAction tAction) { if (!tAction.Has(TargetOptions.Critical)) { return; } var attackerSkill = tAction.Attacker.Skills.Get(SkillId.CriticalHit); var targetSkill = tAction.Creature.Skills.Get(SkillId.CriticalHit); if (attackerSkill.Info.Rank == SkillRank.Novice) { if (tAction.Is(CombatActionType.CounteredHit2)) { attackerSkill.Train(1); // Novice -> RF } } else { attackerSkill.Train(1); // Land a critical hit. if (tAction.Creature.IsDead) { attackerSkill.Train(3); // Finish off with critical hit. } } if (targetSkill != null && targetSkill.Info.Rank >= SkillRank.RF) { attackerSkill.Train(2); // Learn from enemy's critical hit. } }
/// <summary> /// Handles training based on what happened in the combat action. /// </summary> /// <param name="tAction"></param> private void OnCreatureAttack(TargetAction tAction) { if (!tAction.Has(TargetOptions.Critical)) return; var attackerSkill = tAction.Attacker.Skills.Get(SkillId.CriticalHit); var targetSkill = tAction.Creature.Skills.Get(SkillId.CriticalHit); if (attackerSkill.Info.Rank == SkillRank.Novice) { if (tAction.Is(CombatActionType.CounteredHit2)) attackerSkill.Train(1); // Novice -> RF } else { attackerSkill.Train(1); // Land a critical hit. if (tAction.Creature.IsDead) attackerSkill.Train(3); // Finish off with critical hit. } if (targetSkill != null && targetSkill.Info.Rank >= SkillRank.RF) attackerSkill.Train(2); // Learn from enemy's critical hit. }
/// <summary> /// Uses WM, attacking targets. /// </summary> /// <param name="attacker"></param> /// <param name="skill"></param> /// <param name="packet"></param> public void Use(Creature attacker, Skill skill, Packet packet) { var targetAreaId = packet.GetLong(); var unkInt1 = packet.GetInt(); var unkInt2 = packet.GetInt(); var range = this.GetRange(attacker, skill); var targets = attacker.GetTargetableCreaturesInRange(range); // Check targets if (targets.Count == 0) { Send.Notice(attacker, Localization.Get("There isn't a target nearby to use that on.")); Send.SkillUseSilentCancel(attacker); return; } // Create actions var cap = new CombatActionPack(attacker, skill.Info.Id); var aAction = new AttackerAction(CombatActionType.SpecialHit, attacker, skill.Info.Id, targetAreaId); aAction.Set(AttackerOptions.Result); cap.Add(aAction); var survived = new List <Creature>(); foreach (var target in targets) { target.StopMove(); var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Info.Id); tAction.Delay = 300; // Usually 300, sometimes 350? // Calculate damage and crit var damage = attacker.GetRndTotalDamage(); var critChance = attacker.CriticalBase; damage *= skill.RankData.Var1 / 100f; // Handle skills and reductions CriticalHit.Handle(attacker, critChance, ref damage, tAction); SkillHelper.HandleDefenseProtection(target, ref damage); Defense.Handle(aAction, tAction, ref damage); ManaShield.Handle(target, ref damage, tAction); // Clean Hit if not defended nor critical if (!tAction.Is(CombatActionType.Defended) && !tAction.Has(TargetOptions.Critical)) { tAction.Set(TargetOptions.CleanHit); } // Take damage if any is left if (damage > 0) { target.TakeDamage(tAction.Damage = damage, attacker); } // Finish if dead, knock down if not defended if (target.IsDead) { tAction.Set(TargetOptions.KnockDownFinish); } else if (!tAction.Is(CombatActionType.Defended)) { tAction.Set(TargetOptions.KnockDown); } // Anger Management if (!target.IsDead) { survived.Add(target); } // Stun & knock back aAction.Stun = CombatMastery.GetAttackerStun(attacker.AverageKnockCount, attacker.AverageAttackSpeed, true); if (!tAction.Is(CombatActionType.Defended)) { tAction.Stun = CombatMastery.GetTargetStun(attacker.AverageKnockCount, attacker.AverageAttackSpeed, true); target.Stability = Creature.MinStability; attacker.Shove(target, KnockbackDistance); } // Add action cap.Add(tAction); } // Only select a random aggro if there is no aggro yet, // WM only aggroes one target at a time. if (survived.Count != 0 && attacker.Region.CountAggro(attacker) < 1) { var rnd = RandomProvider.Get(); var aggroTarget = survived.Random(); aggroTarget.Aggro(attacker); } // Spin it~ Send.UseMotion(attacker, 8, 4); cap.Handle(); Send.SkillUse(attacker, skill.Info.Id, targetAreaId, unkInt1, unkInt2); skill.Stacks = 0; }