/// <summary> /// Handles the majority of the skill training. /// </summary> /// <param name="tAction"></param> private void OnCreatureAttacks(TargetAction tAction) { if (tAction.AttackerSkillId != SkillId.MagnumShot) { return; } var attackerSkill = tAction.Attacker.Skills.Get(SkillId.MagnumShot); if (attackerSkill != null) { attackerSkill.Train(1); // Attack an enemy. if (tAction.Has(TargetOptions.Critical)) { attackerSkill.Train(2); } if (tAction.Creature.IsDead) // Kill an enemy. { attackerSkill.Train(3); if (tAction.Has(TargetOptions.Critical)) { attackerSkill.Train(4); } } } }
/// <summary> /// Skill training, called when someone attacks something /// </summary> /// <param name="action"></param> public void OnCreatureAttackedByPlayer(TargetAction action) { // Check skill if (action.AttackerSkillId != SkillId.ChargingStrike) { return; } // Get skill var attackerSkill = action.Attacker.Skills.Get(SkillId.ChargingStrike); if (attackerSkill == null) { return; } // Training switch (attackerSkill.Info.Rank) { case SkillRank.Novice: attackerSkill.Train(1); // Use the skill successfully. break; case SkillRank.RF: case SkillRank.RE: case SkillRank.RD: case SkillRank.RC: case SkillRank.RB: case SkillRank.RA: case SkillRank.R9: case SkillRank.R8: case SkillRank.R7: case SkillRank.R6: case SkillRank.R5: case SkillRank.R4: case SkillRank.R3: attackerSkill.Train(1); // Use the skill successfully. if (action.Has(TargetOptions.Critical)) { attackerSkill.Train(2); // Get a Critical Hit with Charging Strike. } break; case SkillRank.R2: if (action.Creature.HasTag("/ogre/")) { attackerSkill.Train(1); // Use the skill successfully on an Ogre. } break; case SkillRank.R1: attackerSkill.Train(1); // Use the skill successfully. if (action.Has(TargetOptions.Critical)) { attackerSkill.Train(2); // Get a Critical Hit with Charging Strike. } break; } }
/// <summary> /// Called when creature is hit while a bolt skill is active. /// </summary> /// <param name="creature"></param> /// <param name="tAction"></param> public void CustomHitCancel(Creature creature, TargetAction tAction) { var skill = creature.Skills.ActiveSkill; // Cancel skill on knock down, or if only one stack is left if (tAction.Has(TargetOptions.KnockDown) || tAction.Has(TargetOptions.KnockDown) || skill.Stacks <= 1) { creature.Skills.CancelActiveSkill(); return; } // Reduce stack by one on hit skill.Stacks -= 1; }
/// <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> /// Called when creature is hit. /// </summary> /// <param name="action"></param> public virtual void OnHit(TargetAction action) { // Aggro attacker if there is not current target, // or if there is a target but it's not a player, and the attacker is one, // or if the current target is not aggroed yet. //if (this.Creature.Target == null || (this.Creature.Target != null && action.Attacker != null && !this.Creature.Target.IsPlayer && action.Attacker.IsPlayer) || _state != AiState.Aggro) //{ // this.AggroCreature(action.Attacker); //} var activeSkillWas = SkillId.None; if (this.Creature.Skills.ActiveSkill != null) { activeSkillWas = this.Creature.Skills.ActiveSkill.Info.Id; this.SharpMind(this.Creature.Skills.ActiveSkill.Info.Id, SharpMindStatus.Cancelling); } lock (_reactions) { if (activeSkillWas == SkillId.Defense && _reactions[_state].ContainsKey(AiEvent.DefenseHit)) { this.SwitchAction(_reactions[_state][AiEvent.DefenseHit]); } else if (action.Has(TargetOptions.KnockDown) && _reactions[_state].ContainsKey(AiEvent.KnockDown)) { this.SwitchAction(_reactions[_state][AiEvent.KnockDown]); } else if (_reactions[_state].ContainsKey(AiEvent.Hit)) { this.SwitchAction(_reactions[_state][AiEvent.Hit]); } } }
/// <summary> /// Skill training, called when someone attacks something /// </summary> /// <param name="action"></param> public void OnCreatureAttackedByPlayer(TargetAction action) { // Check skill if (action.AttackerSkillId != SkillId.DropKick) { return; } // Get skill var attackerSkill = action.Attacker.Skills.Get(SkillId.DropKick); if (attackerSkill == null) { return; } // Disregard the second splash CombatActionPack for this training if (!action.Has(TargetOptions.FighterUnk)) { return; } // Training switch (attackerSkill.Info.Rank) { case SkillRank.RF: case SkillRank.RE: case SkillRank.RD: case SkillRank.RC: case SkillRank.RB: case SkillRank.RA: case SkillRank.R9: case SkillRank.R8: case SkillRank.R7: case SkillRank.R6: case SkillRank.R5: case SkillRank.R4: case SkillRank.R3: case SkillRank.R1: if (action.Has(TargetOptions.Critical)) { attackerSkill.Train(2); // Get a critical hit with Drop Kick. } break; } }
/// <summary> /// Trains the skill for attacker and target, based on what happened. /// </summary> /// <param name="aAction"></param> /// <param name="tAction"></param> public void Training(AttackerAction aAction, TargetAction tAction) { var attackerSkill = aAction.Creature.Skills.Get(SkillId.Counterattack); var targetSkill = tAction.Creature.Skills.Get(SkillId.Counterattack); if (attackerSkill.Info.Rank == SkillRank.RF) { attackerSkill.Train(2); // Successfully counter enemy's attack. if (tAction.SkillId == SkillId.Smash) { attackerSkill.Train(4); // Counter enemy's special attack. } if (tAction.Has(TargetOptions.Critical)) { attackerSkill.Train(5); // Counter with critical hit. } } else { attackerSkill.Train(1); // Successfully counter enemy's attack. if (tAction.SkillId == SkillId.Smash) { attackerSkill.Train(2); // Counter enemy's special attack. } if (tAction.Has(TargetOptions.Critical)) { attackerSkill.Train(4); // Counter with critical hit. } } if (targetSkill != null) { targetSkill.Train(3); // Learn from the enemy's counter attack. } else if (tAction.Creature.LearningSkillsEnabled) { tAction.Creature.Skills.Give(SkillId.Counterattack, SkillRank.Novice); // Obtaining the Skill } }
public void OnCreatureAttackedByPlayer(TargetAction tAction) { // the One Who Removed Siren's Mask (male) or // the One Who Exposed Siren's Identity (female) // Enable when hitting a siren with a critical smash // without killing the siren // ------------------------------------------------------------------ if (tAction.AttackerSkillId != SkillId.Smash) { return; } if (!tAction.Attacker.CanUseTitle(86)) { if (tAction.Has(TargetOptions.Critical) && !tAction.Creature.IsDead && tAction.Creature.HasTag("/siren/")) { tAction.Attacker.EnableTitle(86); } } }
/// <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 the majority of the skill training. /// </summary> /// <param name="tAction"></param> private void OnCreatureAttacks(TargetAction tAction) { if (tAction.AttackerSkillId != SkillId.RangedAttack) { return; } var attackerSkill = tAction.Attacker.Skills.Get(SkillId.RangedAttack); var targetSkill = tAction.Creature.Skills.Get(SkillId.RangedAttack); var targetPowerRating = tAction.Attacker.GetPowerRating(tAction.Creature); var attackerPowerRating = tAction.Creature.GetPowerRating(tAction.Attacker); if (attackerSkill != null) { if (attackerSkill.Info.Rank == SkillRank.RF) { attackerSkill.Train(2); // Attack an enemy. if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(3); // Down the enemy with continuous hit. } if (tAction.Creature.IsDead) { attackerSkill.Train(4); // Kill an enemy. } } else if (attackerSkill.Info.Rank == SkillRank.RE) { if (targetPowerRating == PowerRating.Normal) { attackerSkill.Train(3); // Attack a same level enemy. } if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(1); // Down the enemy with continuous hit. if (targetPowerRating == PowerRating.Normal) { attackerSkill.Train(4); // Down a same level enemy. } if (targetPowerRating == PowerRating.Strong) { attackerSkill.Train(6); // Down a strong enemy. } } if (tAction.Creature.IsDead) { attackerSkill.Train(2); // Kill an enemy. if (targetPowerRating == PowerRating.Normal) { attackerSkill.Train(5); // Kill a same level enemy. } if (targetPowerRating == PowerRating.Strong) { attackerSkill.Train(7); // Kill a strong enemy. } } } else if (attackerSkill.Info.Rank == SkillRank.RD) { attackerSkill.Train(1); // Attack any enemy. if (targetPowerRating == PowerRating.Normal) { attackerSkill.Train(4); // Attack a same level enemy. } if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(2); // Down the enemy with continuous hit. if (targetPowerRating == PowerRating.Normal) { attackerSkill.Train(5); // Down a same level enemy. } if (targetPowerRating == PowerRating.Strong) { attackerSkill.Train(7); // Down a strong enemy. } } if (tAction.Creature.IsDead) { attackerSkill.Train(3); // Kill an enemy. if (targetPowerRating == PowerRating.Normal) { attackerSkill.Train(6); // Kill a same level enemy. } if (targetPowerRating == PowerRating.Strong) { attackerSkill.Train(8); // Kill a strong enemy. } } } else if (attackerSkill.Info.Rank >= SkillRank.RC && attackerSkill.Info.Rank <= SkillRank.RB) { if (targetPowerRating == PowerRating.Normal) { attackerSkill.Train(1); // Attack a same level enemy. } if (tAction.Has(TargetOptions.KnockDown)) { if (targetPowerRating == PowerRating.Normal) { attackerSkill.Train(2); // Down a same level enemy. } if (targetPowerRating == PowerRating.Strong) { attackerSkill.Train(4); // Down a strong enemy. } if (targetPowerRating == PowerRating.Awful) { attackerSkill.Train(6); // Down an awful enemy. } } if (tAction.Creature.IsDead) { if (targetPowerRating == PowerRating.Normal) { attackerSkill.Train(3); // Kill a same level enemy. } if (targetPowerRating == PowerRating.Strong) { attackerSkill.Train(5); // Kill a strong enemy. } if (targetPowerRating == PowerRating.Awful) { attackerSkill.Train(7); // Kill an awful enemy. } } } else if (attackerSkill.Info.Rank >= SkillRank.RA && attackerSkill.Info.Rank <= SkillRank.R8) { if (tAction.Has(TargetOptions.KnockDown)) { if (targetPowerRating == PowerRating.Normal) { attackerSkill.Train(1); // Down a same level enemy. } if (targetPowerRating == PowerRating.Strong) { attackerSkill.Train(3); // Down a strong enemy. } if (targetPowerRating == PowerRating.Awful) { attackerSkill.Train(5); // Down an awful enemy. } if (targetPowerRating == PowerRating.Boss && attackerSkill.Info.Rank == SkillRank.R8) { attackerSkill.Train(7); // Down a boss level enemy. } } if (tAction.Creature.IsDead) { if (targetPowerRating == PowerRating.Normal) { attackerSkill.Train(2); // Kill a same level enemy. } if (targetPowerRating == PowerRating.Strong) { attackerSkill.Train(4); // Kill a strong enemy. } if (targetPowerRating == PowerRating.Awful) { attackerSkill.Train(6); // Kill an awful enemy. } if (targetPowerRating == PowerRating.Boss && attackerSkill.Info.Rank == SkillRank.R8) { attackerSkill.Train(8); // Kill a boss level enemy. } } } else if (attackerSkill.Info.Rank >= SkillRank.R7 && attackerSkill.Info.Rank <= SkillRank.R1) { if (tAction.Has(TargetOptions.KnockDown)) { if (targetPowerRating == PowerRating.Strong) { attackerSkill.Train(1); // Down a strong enemy. } if (targetPowerRating == PowerRating.Awful) { attackerSkill.Train(3); // Down an awful enemy. } if (targetPowerRating == PowerRating.Boss) { attackerSkill.Train(5); // Down a boss level enemy. } } if (tAction.Creature.IsDead) { if (targetPowerRating == PowerRating.Strong) { attackerSkill.Train(2); // Kill a strong enemy. } if (targetPowerRating == PowerRating.Awful) { attackerSkill.Train(4); // Kill an awful enemy. } if (targetPowerRating == PowerRating.Boss) { attackerSkill.Train(6); // Kill a boss level enemy. } } } } if (targetSkill != null) { if (targetSkill.Info.Rank == SkillRank.RF) { if (tAction.Has(TargetOptions.KnockDown)) { targetSkill.Train(5); // Learn by falling down. } if (tAction.Creature.IsDead) { targetSkill.Train(6); // Learn through losing. } } else if (targetSkill.Info.Rank == SkillRank.RD) { if (attackerPowerRating == PowerRating.Strong) { targetSkill.Train(8); // Receive a powerful attack from a powerful enemy. } } else if (targetSkill.Info.Rank == SkillRank.R7) { if (attackerPowerRating == PowerRating.Strong) { targetSkill.Train(7); // Receive a powerful attack from a powerful enemy. } } } }
/// <summary> /// Handles the skill training. /// </summary> /// <param name="tAction"></param> private void OnCreatureAttacks(TargetAction tAction) { if (tAction.AttackerSkillId != SkillId.SupportShot) return; var skill = tAction.Attacker.Skills.Get(SkillId.SupportShot); if (skill == null) return; var powerRating = tAction.Attacker.GetPowerRating(tAction.Creature); if (skill.Info.Rank >= SkillRank.RF && skill.Info.Rank <= SkillRank.RA) { skill.Train(1); // Successfully use the skill. if (!tAction.IsKnockBack) skill.Train(2); // Successfully use Support Shot without knocking down the enemy. if (tAction.Has(TargetOptions.Critical)) skill.Train(3); // Succeed in a Critical Hit with Support Shot. } else if (skill.Info.Rank == SkillRank.R9) { if (powerRating == PowerRating.Normal) skill.Train(1); // Successfully use the skill on a similarly ranked enemy. if (powerRating == PowerRating.Strong) { skill.Train(2); // Successfully use the skill on a Strong enemy. if (tAction.Has(TargetOptions.Critical)) skill.Train(4); // Succeed in a Critical Hit against a Strong enemy. } if (!tAction.IsKnockBack) skill.Train(3); // Successfully use Support Shot without knocking down the enemy. } else if (skill.Info.Rank >= SkillRank.R8 && skill.Info.Rank <= SkillRank.R4) { if (powerRating == PowerRating.Strong) skill.Train(1); // Successfully use the skill on a Strong enemy. if (powerRating == PowerRating.Awful) { skill.Train(2); // Successfully use the skill on a Awful enemy. if (tAction.Has(TargetOptions.Critical)) skill.Train(4); // Succeed in a Critical Hit against a Awful enemy. } if (!tAction.IsKnockBack) skill.Train(3); // Successfully use Support Shot without knocking down the enemy. } else if (skill.Info.Rank >= SkillRank.R3 && skill.Info.Rank <= SkillRank.R1) { if (powerRating == PowerRating.Awful) skill.Train(1); // Successfully use the skill on a Awful enemy. if (powerRating == PowerRating.Boss) { skill.Train(2); // Successfully use the skill on a Boss enemy. if (tAction.Has(TargetOptions.Critical)) skill.Train(4); // Succeed in a Critical Hit against a Boss enemy. } if (!tAction.IsKnockBack) skill.Train(3); // Successfully use Support Shot without knocking down the enemy. } }
/// <summary> /// Uses WM, attacking targets. /// </summary> /// <param name="attacker"></param> /// <param name="skill"></param> /// <param name="targetAreaId"></param> /// <param name="unkInt1"></param> /// <param name="unkInt2"></param> public void Use(Creature attacker, Skill skill, long targetAreaId, int unkInt1, int unkInt2) { var range = this.GetRange(attacker, skill); var targets = attacker.GetTargetableCreaturesInRange(range, true); // 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 var damage = attacker.GetRndTotalDamage(); damage *= skill.RankData.Var1 / 100f; // Handle skills and reductions CriticalHit.Handle(attacker, attacker.GetTotalCritChance(0), 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.SkillId != SkillId.Defense && !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.SkillId != SkillId.Defense) 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.SkillId != SkillId.Defense) { 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); } // Reduce life in old combat system if (!AuraData.FeaturesDb.IsEnabled("CombatSystemRenewal")) { var amount = (attacker.LifeMax < 10 ? 2 : attacker.LifeMax / 10); attacker.ModifyLife(-amount); // TODO: Invincibility } // Spin it~ Send.UseMotion(attacker, 8, 4); cap.Handle(); Send.SkillUse(attacker, skill.Info.Id, targetAreaId, unkInt1, unkInt2); skill.Stacks = 0; }
/// <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; }
/// <summary> /// Uses WM, attacking targets. /// </summary> /// <param name="attacker"></param> /// <param name="skill"></param> /// <param name="targetAreaId"></param> /// <param name="unkInt1"></param> /// <param name="unkInt2"></param> public void Use(Creature attacker, Skill skill, long targetAreaId, int unkInt1, int unkInt2) { var range = this.GetRange(attacker, skill); var targets = attacker.GetTargetableCreaturesInRange(range, TargetableOptions.AddAttackRange); // 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, targetAreaId); aAction.Set(AttackerOptions.Result); aAction.Stun = CombatMastery.GetAttackerStun(attacker.AverageKnockCount, attacker.AverageAttackSpeed, true); cap.Add(aAction); var survived = new List <Creature>(); var rnd = RandomProvider.Get(); // Check crit var crit = false; if (attacker.Skills.Has(SkillId.CriticalHit, SkillRank.RF)) { crit = (rnd.Next(100) < attacker.GetTotalCritChance(0)); } // Handle all targets 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 var damage = attacker.GetRndTotalDamage(); damage *= skill.RankData.Var1 / 100f; // Elementals damage *= attacker.CalculateElementalDamageMultiplier(target); // Crit bonus if (crit) { CriticalHit.Handle(attacker, 100, ref damage, tAction); } // Handle skills and reductions SkillHelper.HandleDefenseProtection(target, ref damage); SkillHelper.HandleConditions(attacker, target, ref damage); Defense.Handle(aAction, tAction, ref damage); ManaShield.Handle(target, ref damage, tAction); HeavyStander.Handle(attacker, target, ref damage, tAction); // Clean Hit if not defended nor critical if (tAction.SkillId != SkillId.Defense && !tAction.Has(TargetOptions.Critical)) { tAction.Set(TargetOptions.CleanHit); } // Take damage if any is left if (damage > 0) { target.TakeDamage(tAction.Damage = damage, attacker); } // Knock down on deadly if (target.Conditions.Has(ConditionsA.Deadly)) { tAction.Set(TargetOptions.KnockDown); tAction.Stun = CombatMastery.GetTargetStun(attacker.AverageKnockCount, attacker.AverageAttackSpeed, true); } // Finish if dead, knock down if not defended if (target.IsDead) { tAction.Set(TargetOptions.KnockDownFinish); } else if (tAction.SkillId != SkillId.Defense) { tAction.Set(TargetOptions.KnockDown); } // Anger Management if (!target.IsDead) { survived.Add(target); } // Stun and shove if not defended if (target.IsDead || tAction.SkillId != SkillId.Defense || target.Conditions.Has(ConditionsA.Deadly)) { tAction.Stun = CombatMastery.GetTargetStun(attacker.AverageKnockCount, attacker.AverageAttackSpeed, true); target.Stability = Creature.MinStability; attacker.Shove(target, KnockbackDistance); } // Add action cap.Add(tAction); } // Update current weapon SkillHelper.UpdateWeapon(attacker, targets.FirstOrDefault(), ProficiencyGainType.Melee, attacker.RightHand, attacker.LeftHand); // 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 aggroTarget = survived.Random(); aggroTarget.Aggro(attacker); } // Reduce life in old combat system if (!AuraData.FeaturesDb.IsEnabled("CombatSystemRenewal")) { var amount = (attacker.LifeMax < 10 ? 2 : attacker.LifeMax / 10); attacker.ModifyLife(-amount); // TODO: Invincibility } // Spin it~ Send.UseMotion(attacker, 8, 4); cap.Handle(); Send.SkillUse(attacker, skill.Info.Id, targetAreaId, unkInt1, unkInt2); skill.Stacks = 0; }
/// <summary> /// Training, called when someone attacks something. /// </summary> /// <param name="tAction"></param> public void OnCreatureAttackedByPlayer(TargetAction tAction) { // Only train if used skill was Smash if (tAction.AttackerSkillId != SkillId.Smash) return; // Get skill var attackerSkill = tAction.Attacker.Skills.Get(SkillId.Smash); if (attackerSkill == null) return; // Should be impossible. // Learning by attacking switch (attackerSkill.Info.Rank) { case SkillRank.RF: case SkillRank.RE: attackerSkill.Train(1); // Use the skill successfully. if (tAction.Has(TargetOptions.Critical)) attackerSkill.Train(2); // Critical Hit with Smash. if (tAction.Creature.IsDead) attackerSkill.Train(3); // Finishing blow with Smash. break; case SkillRank.RD: case SkillRank.RC: case SkillRank.RB: case SkillRank.RA: case SkillRank.R9: case SkillRank.R8: case SkillRank.R7: if (tAction.Has(TargetOptions.Critical) && tAction.Creature.IsDead) attackerSkill.Train(4); // Finishing blow with Critical Hit. goto case SkillRank.RF; case SkillRank.R6: case SkillRank.R5: case SkillRank.R4: case SkillRank.R3: case SkillRank.R2: case SkillRank.R1: if (tAction.Has(TargetOptions.Critical)) attackerSkill.Train(1); // Critical Hit with Smash. if (tAction.Creature.IsDead) attackerSkill.Train(2); // Finishing blow with Smash. if (tAction.Has(TargetOptions.Critical) && tAction.Creature.IsDead) attackerSkill.Train(3); // Finishing blow with Critical Hit. break; } }
public CombatSkillResult Use(Creature attacker, Skill skill, long targetEntityId) { if (attacker.IsStunned) return CombatSkillResult.Okay; var target = attacker.Region.GetCreature(targetEntityId); if (target == null) return CombatSkillResult.Okay; if (!attacker.GetPosition().InRange(target.GetPosition(), attacker.AttackRangeFor(target))) return CombatSkillResult.OutOfRange; attacker.StopMove(); var targetPosition = target.StopMove(); var rightWeapon = attacker.Inventory.RightHand; var leftWeapon = attacker.Inventory.LeftHand; var magazine = attacker.Inventory.Magazine; var dualWield = (rightWeapon != null && leftWeapon != null); var maxHits = (byte)(dualWield ? 2 : 1); int prevId = 0; for (byte i = 1; i <= maxHits; ++i) { var weapon = (i == 1 ? rightWeapon : leftWeapon); var cap = new CombatActionPack(attacker, skill.Info.Id); var aAction = new AttackerAction(CombatActionType.Hit, attacker, skill.Info.Id, targetEntityId); var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Info.Id); cap.Add(aAction, tAction); cap.Hit = i; cap.MaxHits = maxHits; cap.PrevId = prevId; prevId = cap.Id; aAction.Set(AttackerOptions.Result); if (dualWield) aAction.Set(AttackerOptions.DualWield); var damage = attacker.GetRndDamage(weapon); tAction.Damage = damage; target.TakeDamage(tAction.Damage, attacker); if (!target.IsDead) { target.KnockBack += this.GetKnockBack(weapon) / maxHits; if (target.KnockBack >= 100 && target.Is(RaceStands.KnockBackable)) tAction.Set(tAction.Has(TargetOptions.Critical) ? TargetOptions.KnockDown : TargetOptions.KnockBack); } else { tAction.Set(TargetOptions.FinishingKnockDown); } if (tAction.IsKnockBack) { var newPos = attacker.GetPosition().GetRelative(targetPosition, KnockBackDistance); Position intersection; if (target.Region.Collissions.Find(targetPosition, newPos, out intersection)) newPos = targetPosition.GetRelative(intersection, -50); target.SetPosition(newPos.X, newPos.Y); aAction.Set(AttackerOptions.KnockBackHit2); cap.MaxHits = cap.Hit; } aAction.Stun = this.GetAttackerStun(weapon, tAction.IsKnockBack); tAction.Stun = this.GetTargetStun(weapon, tAction.IsKnockBack); cap.Handle(); if (tAction.IsKnockBack) break; } return CombatSkillResult.Okay; }
/// <summary> /// Uses the skill. /// </summary> /// <param name="attacker"></param> /// <param name="skill"></param> /// <param name="targetEntityId"></param> /// <returns></returns> public CombatSkillResult Use(Creature attacker, Skill skill, long targetEntityId) { // Get target var target = attacker.Region.GetCreature(targetEntityId); if (target == null) return CombatSkillResult.InvalidTarget; if (target.IsNotReadyToBeHit) return CombatSkillResult.Okay; // Actions var cap = new CombatActionPack(attacker, skill.Info.Id); var aAction = new AttackerAction(CombatActionType.RangeHit, attacker, skill.Info.Id, targetEntityId); aAction.Set(AttackerOptions.Result); aAction.Stun = AttackerStun; cap.Add(aAction); // Hit by chance var chance = attacker.AimMeter.GetAimChance(target); var rnd = RandomProvider.Get(); if (rnd.NextDouble() * 100 < chance) { aAction.Set(AttackerOptions.KnockBackHit2); var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Info.Id); tAction.Set(TargetOptions.Result | TargetOptions.CleanHit); tAction.Stun = TargetStun; cap.Add(tAction); // Damage var damage = this.GetDamage(attacker, skill); // More damage with fire arrow if (attacker.Temp.FireArrow) damage *= FireBonus; // Critical Hit var critShieldReduction = (target.LeftHand != null ? target.LeftHand.Data.DefenseBonusCrit : 0); var critChance = attacker.GetRightCritChance(target.Protection + critShieldReduction); CriticalHit.Handle(attacker, critChance, ref damage, tAction); var maxDamage = damage; //Damage without Defense and Protection // Subtract target def/prot SkillHelper.HandleDefenseProtection(target, ref damage); // Defense Defense.Handle(aAction, tAction, ref damage); // Mana Shield ManaShield.Handle(target, ref damage, tAction, maxDamage); // Deal with it! if (damage > 0) target.TakeDamage(tAction.Damage = damage, attacker); // TODO: We have to calculate knockback distance right // TODO: Target with Defense and shield shouldn't be knocked back attacker.Shove(target, KnockBackDistance); // Aggro target.Aggro(attacker); tAction.Set(TargetOptions.KnockDownFinish); if (target.IsDead) { aAction.Set(AttackerOptions.KnockBackHit1); tAction.Set(TargetOptions.Finished); } var weapon = attacker.RightHand; var critSkill = attacker.Skills.Get(SkillId.CriticalHit); if (skill.Info.Rank >= SkillRank.R5 && weapon != null && weapon.Data.SplashRadius != 0 && weapon.Data.SplashAngle != 0) { ICollection<Creature> targets = attacker.GetTargetableCreaturesInCone(weapon != null ? (int)weapon.Data.SplashRadius : 200, weapon != null ? (int)weapon.Data.SplashAngle : 20); foreach (var splashTarget in targets) { if (splashTarget != target) { if (splashTarget.IsNotReadyToBeHit) continue; TargetAction tSplashAction = new TargetAction(CombatActionType.TakeHit, splashTarget, attacker, skill.Info.Id); tSplashAction.Set(TargetOptions.Result | TargetOptions.CleanHit); splashTarget.Stun = TargetStun; // Base damage var damageSplash = this.GetDamage(attacker, skill); // Critical Hit if (critSkill != null && tAction.Has(TargetOptions.Critical)) { // Add crit bonus var bonus = critSkill.RankData.Var1 / 100f; damageSplash = damageSplash + (damageSplash * bonus); // Set splashTarget option tSplashAction.Set(TargetOptions.Critical); } var maxDamageSplash = damage; //Damage without Defense and Protection // Subtract splashTarget def/prot SkillHelper.HandleDefenseProtection(splashTarget, ref damageSplash); // Defense Defense.Handle(aAction, tSplashAction, ref damageSplash, true); // Mana Shield ManaShield.Handle(splashTarget, ref damageSplash, tSplashAction, maxDamageSplash); //Splash Damage Reduction damageSplash *= skill.Info.Rank < SkillRank.R1 ? 0.1f : 0.2f; // Deal with it! if (damageSplash > 0) splashTarget.TakeDamage(tSplashAction.Damage = damageSplash, attacker); attacker.Shove(splashTarget, KnockBackDistance); // Alert Network.Sending.Send.SetCombatTarget(splashTarget, attacker.EntityId, TargetMode.Alert); tAction.Set(TargetOptions.KnockDownFinish); if (splashTarget.IsDead) { aAction.Set(AttackerOptions.KnockBackHit1); tSplashAction.Set(TargetOptions.Finished); } cap.Add(tSplashAction); } } } } else { aAction.Set(AttackerOptions.Missed); } // Reduce arrows if (attacker.Magazine != null && !ChannelServer.Instance.Conf.World.InfiniteArrows) attacker.Inventory.Decrement(attacker.Magazine); // Disable fire arrow effect if (attacker.Temp.FireArrow) Send.Effect(attacker, Effect.FireArrow, false); // "Cancels" the skill // 800 = old load time? == aAction.Stun? Varies? Doesn't seem to be a stun. Send.SkillUse(attacker, skill.Info.Id, 800, 1); cap.Handle(); return CombatSkillResult.Okay; }
/// <summary> /// Handles attack. /// </summary> /// <param name="attacker">The creature attacking.</param> /// <param name="skill">The skill being used.</param> /// <param name="targetEntityId">The entity id of the target.</param> /// <returns></returns> public CombatSkillResult Use(Creature attacker, Skill skill, long targetEntityId) { if (attacker.IsStunned) { return(CombatSkillResult.Okay); } var target = attacker.Region.GetCreature(targetEntityId); if (target == null) { return(CombatSkillResult.Okay); } if (!attacker.GetPosition().InRange(target.GetPosition(), attacker.AttackRangeFor(target))) { return(CombatSkillResult.OutOfRange); } attacker.StopMove(); var targetPosition = target.StopMove(); // Counter if (Counterattack.Handle(target, attacker)) { return(CombatSkillResult.Okay); } var rightWeapon = attacker.Inventory.RightHand; var leftWeapon = attacker.Inventory.LeftHand; var magazine = attacker.Inventory.Magazine; var dualWield = (rightWeapon != null && leftWeapon != null && leftWeapon.Data.WeaponType != 0); var maxHits = (byte)(dualWield ? 2 : 1); int prevId = 0; for (byte i = 1; i <= maxHits; ++i) { var weapon = (i == 1 ? rightWeapon : leftWeapon); var weaponIsKnuckle = (weapon != null && weapon.Data.HasTag("/knuckle/")); var aAction = new AttackerAction(CombatActionType.Hit, attacker, skill.Info.Id, targetEntityId); var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Info.Id); var cap = new CombatActionPack(attacker, skill.Info.Id, aAction, tAction); cap.Hit = i; cap.MaxHits = maxHits; cap.PrevId = prevId; prevId = cap.Id; // Default attacker options aAction.Set(AttackerOptions.Result); if (dualWield) { aAction.Set(AttackerOptions.DualWield); } // Base damage var damage = attacker.GetRndDamage(weapon); // Critical Hit CriticalHit.Handle(attacker, attacker.GetCritChanceFor(target), ref damage, tAction); // Subtract target def/prot SkillHelper.HandleDefenseProtection(target, ref damage); // Defense Defense.Handle(aAction, tAction, ref damage); // Mana Shield ManaShield.Handle(target, ref damage, tAction); // Deal with it! if (damage > 0) { target.TakeDamage(tAction.Damage = damage, attacker); } // Aggro target.Aggro(attacker); // Evaluate caused damage if (!target.IsDead) { if (tAction.Type != CombatActionType.Defended) { target.Stability -= this.GetStabilityReduction(attacker, weapon) / maxHits; // React normal for CombatMastery, knock down if // FH and not dual wield, don't knock at all if dual. if (skill.Info.Id != SkillId.FinalHit) { if (target.IsUnstable && target.Is(RaceStands.KnockBackable)) { tAction.Set(tAction.Has(TargetOptions.Critical) ? TargetOptions.KnockDown : TargetOptions.KnockBack); } } else if (!dualWield && !weaponIsKnuckle) { target.Stability = Creature.MinStability; tAction.Set(TargetOptions.KnockDown); } } } else { tAction.Set(TargetOptions.FinishingKnockDown); } // React to knock back if (tAction.IsKnockBack) { attacker.Shove(target, KnockBackDistance); aAction.Set(AttackerOptions.KnockBackHit2); // Remove dual wield option if last hit doesn't come from // the second weapon. if (cap.MaxHits != cap.Hit) { aAction.Options &= ~AttackerOptions.DualWield; } } // Set stun time if (tAction.Type != CombatActionType.Defended) { aAction.Stun = GetAttackerStun(attacker, weapon, tAction.IsKnockBack && (skill.Info.Id != SkillId.FinalHit || !dualWield)); tAction.Stun = GetTargetStun(attacker, weapon, tAction.IsKnockBack); } // Second hit doubles stun time for normal hits if (cap.Hit == 2 && !tAction.IsKnockBack) { aAction.Stun *= 2; } // Update current weapon SkillHelper.UpdateWeapon(attacker, target, weapon); cap.Handle(); // No second hit if target was knocked back if (tAction.IsKnockBack) { break; } } return(CombatSkillResult.Okay); }
/// <summary> /// Handles using the skill. /// </summary> /// <param name="attacker"></param> /// <param name="skill"></param> /// <param name="targetAreaId"></param> /// <param name="unkInt1"></param> /// <param name="unkInt2"></param> public void Use(Creature attacker, Skill skill, long targetAreaId, int unkInt1, int unkInt2) { var range = this.GetRange(attacker, skill); var targets = attacker.GetTargetableCreaturesInRange(range, true); var rnd = RandomProvider.Get(); // Create actions var cap = new CombatActionPack(attacker, skill.Info.Id); var aAction = new AttackerAction(CombatActionType.Attacker, attacker, skill.Info.Id, targetAreaId); aAction.Set(AttackerOptions.Result); aAction.Stun = AttackerStun; cap.Add(aAction); foreach (var target in targets) { // Check if hit var hitChance = this.GetHitChance(attacker, target, skill); if (rnd.Next(0, 100) > hitChance) { continue; } target.StopMove(); var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Info.Id); tAction.Set(TargetOptions.Result); tAction.Delay = 300; // Calculate damage var damage = this.GetDamage(attacker, skill); // Handle skills and reductions CriticalHit.Handle(attacker, attacker.GetTotalCritChance(0), ref damage, tAction); SkillHelper.HandleDefenseProtection(target, ref damage); ManaShield.Handle(target, ref damage, tAction); // Clean Hit if not critical if (!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 { tAction.Set(TargetOptions.KnockDown); } // Anger Management if (!target.IsDead) { target.Aggro(attacker); } // Stun & knock down tAction.Stun = CombatMastery.GetTargetStun(attacker.AverageKnockCount, attacker.AverageAttackSpeed, true); target.Stability = Creature.MinStability; // Add action cap.Add(tAction); } Send.UseMotion(attacker, 10, 1); cap.Handle(); Send.SkillUse(attacker, skill.Info.Id, targetAreaId, unkInt1, unkInt2); }
public CombatSkillResult Use(Creature attacker, Skill skill, long targetEntityId) { if (attacker.IsStunned) { return(CombatSkillResult.Okay); } var target = attacker.Region.GetCreature(targetEntityId); if (target == null) { return(CombatSkillResult.Okay); } if (!attacker.GetPosition().InRange(target.GetPosition(), attacker.AttackRangeFor(target))) { return(CombatSkillResult.OutOfRange); } attacker.StopMove(); var targetPosition = target.StopMove(); // Counter if (SkillHelper.HandleCounter(target, attacker)) { return(CombatSkillResult.Okay); } var rightWeapon = attacker.Inventory.RightHand; var leftWeapon = attacker.Inventory.LeftHand; var magazine = attacker.Inventory.Magazine; var dualWield = (rightWeapon != null && leftWeapon != null && leftWeapon.Data.WeaponType != 0); var maxHits = (byte)(dualWield ? 2 : 1); int prevId = 0; for (byte i = 1; i <= maxHits; ++i) { var weapon = (i == 1 ? rightWeapon : leftWeapon); var aAction = new AttackerAction(CombatActionType.Hit, attacker, skill.Info.Id, targetEntityId); var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Info.Id); var cap = new CombatActionPack(attacker, skill.Info.Id, aAction, tAction); cap.Hit = i; cap.MaxHits = maxHits; cap.PrevId = prevId; prevId = cap.Id; // Default attacker options aAction.Set(AttackerOptions.Result); if (dualWield) { aAction.Set(AttackerOptions.DualWield); } // Base damage var damage = attacker.GetRndDamage(weapon); // Critical Hit SkillHelper.HandleCritical(attacker, attacker.GetCritChanceFor(target), ref damage, tAction); // Subtract target def/prot SkillHelper.HandleDefenseProtection(target, ref damage); // Defense SkillHelper.HandleDefense(aAction, tAction, ref damage); // Mana Shield SkillHelper.HandleManaShield(target, ref damage, tAction); // Deal with it! if (damage > 0) { target.TakeDamage(tAction.Damage = damage, attacker); } // Evaluate caused damage if (!target.IsDead) { if (tAction.Type != CombatActionType.Defended) { target.KnockBack += this.GetKnockBack(weapon) / maxHits; if (target.KnockBack >= 100 && target.Is(RaceStands.KnockBackable)) { tAction.Set(tAction.Has(TargetOptions.Critical) ? TargetOptions.KnockDown : TargetOptions.KnockBack); } } } else { tAction.Set(TargetOptions.FinishingKnockDown); } // React to knock back if (tAction.IsKnockBack) { var newPos = attacker.GetPosition().GetRelative(targetPosition, KnockBackDistance); Position intersection; if (target.Region.Collisions.Find(targetPosition, newPos, out intersection)) { newPos = targetPosition.GetRelative(intersection, -50); } target.SetPosition(newPos.X, newPos.Y); aAction.Set(AttackerOptions.KnockBackHit2); // Remove dual wield option if last hit doesn't come from // the second weapon. if (cap.MaxHits != cap.Hit) { aAction.Options &= ~AttackerOptions.DualWield; } } // Set stun time if (tAction.Type != CombatActionType.Defended) { aAction.Stun = this.GetAttackerStun(weapon, tAction.IsKnockBack); tAction.Stun = this.GetTargetStun(weapon, tAction.IsKnockBack); } // Second hit doubles stun time for normal hits if (cap.Hit == 2 && !tAction.IsKnockBack) { aAction.Stun *= 2; } // Update current weapon SkillHelper.UpdateWeapon(attacker, target, weapon); cap.Handle(); // No second hit if target was knocked back if (tAction.IsKnockBack) { break; } } return(CombatSkillResult.Okay); }
/// <summary> /// Training, called when someone attacks something. /// </summary> /// <param name="tAction"></param> public void OnCreatureAttackedByPlayer(TargetAction tAction) { // Only train if used skill was Smash if (tAction.AttackerSkillId != SkillId.Smash) { return; } // Get skill var attackerSkill = tAction.Attacker.Skills.Get(SkillId.Smash); if (attackerSkill == null) { return; // Should be impossible. } // Learning by attacking switch (attackerSkill.Info.Rank) { case SkillRank.RF: case SkillRank.RE: attackerSkill.Train(1); // Use the skill successfully. if (tAction.Has(TargetOptions.Critical)) { attackerSkill.Train(2); // Critical Hit with Smash. } if (tAction.Creature.IsDead) { attackerSkill.Train(3); // Finishing blow with Smash. } break; case SkillRank.RD: case SkillRank.RC: case SkillRank.RB: case SkillRank.RA: case SkillRank.R9: case SkillRank.R8: case SkillRank.R7: if (tAction.Has(TargetOptions.Critical) && tAction.Creature.IsDead) { attackerSkill.Train(4); // Finishing blow with Critical Hit. } goto case SkillRank.RF; case SkillRank.R6: case SkillRank.R5: case SkillRank.R4: case SkillRank.R3: case SkillRank.R2: case SkillRank.R1: if (tAction.Has(TargetOptions.Critical)) { attackerSkill.Train(1); // Critical Hit with Smash. } if (tAction.Creature.IsDead) { attackerSkill.Train(2); // Finishing blow with Smash. } if (tAction.Has(TargetOptions.Critical) && tAction.Creature.IsDead) { attackerSkill.Train(3); // Finishing blow with Critical Hit. } break; } }
/// <summary> /// Uses WM, attacking targets. /// </summary> /// <param name="attacker"></param> /// <param name="skill"></param> /// <param name="targetAreaId"></param> /// <param name="unkInt1"></param> /// <param name="unkInt2"></param> public void Use(Creature attacker, Skill skill, long targetAreaId, int unkInt1, int unkInt2) { var range = this.GetRange(attacker, skill); var targets = attacker.GetTargetableCreaturesInRange(range, TargetableOptions.AddAttackRange); // 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, targetAreaId); aAction.Set(AttackerOptions.Result); aAction.Stun = CombatMastery.GetAttackerStun(attacker.AverageKnockCount, attacker.AverageAttackSpeed, true); cap.Add(aAction); var survived = new List<Creature>(); var rnd = RandomProvider.Get(); // Check crit var crit = false; if (attacker.Skills.Has(SkillId.CriticalHit, SkillRank.RF)) crit = (rnd.Next(100) < attacker.GetTotalCritChance(0)); // Handle all targets 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 var damage = attacker.GetRndTotalDamage(); damage *= skill.RankData.Var1 / 100f; // Elementals damage *= attacker.CalculateElementalDamageMultiplier(target); // Crit bonus if (crit) CriticalHit.Handle(attacker, 100, ref damage, tAction); // Handle skills and reductions SkillHelper.HandleDefenseProtection(target, ref damage); SkillHelper.HandleConditions(attacker, target, ref damage); Defense.Handle(aAction, tAction, ref damage); ManaShield.Handle(target, ref damage, tAction); HeavyStander.Handle(attacker, target, ref damage, tAction); // Clean Hit if not defended nor critical if (tAction.SkillId != SkillId.Defense && !tAction.Has(TargetOptions.Critical)) tAction.Set(TargetOptions.CleanHit); // Take damage if any is left if (damage > 0) target.TakeDamage(tAction.Damage = damage, attacker); // Knock down on deadly if (target.Conditions.Has(ConditionsA.Deadly)) { tAction.Set(TargetOptions.KnockDown); tAction.Stun = CombatMastery.GetTargetStun(attacker.AverageKnockCount, attacker.AverageAttackSpeed, true); } // Finish if dead, knock down if not defended if (target.IsDead) tAction.Set(TargetOptions.KnockDownFinish); else if (tAction.SkillId != SkillId.Defense) tAction.Set(TargetOptions.KnockDown); // Anger Management if (!target.IsDead) survived.Add(target); // Stun and shove if not defended if (target.IsDead || tAction.SkillId != SkillId.Defense || target.Conditions.Has(ConditionsA.Deadly)) { tAction.Stun = CombatMastery.GetTargetStun(attacker.AverageKnockCount, attacker.AverageAttackSpeed, true); target.Stability = Creature.MinStability; attacker.Shove(target, KnockbackDistance); } // Add action cap.Add(tAction); } // Update current weapon SkillHelper.UpdateWeapon(attacker, targets.FirstOrDefault(), ProficiencyGainType.Melee, attacker.RightHand, attacker.LeftHand); // 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 aggroTarget = survived.Random(); aggroTarget.Aggro(attacker); } // Reduce life in old combat system if (!AuraData.FeaturesDb.IsEnabled("CombatSystemRenewal")) { // Default reduction is 10%, it's reduced to 2% if attacker // has less max life than the rate is set to. var lifeReducationRate = skill.RankData.Var2; if (attacker.LifeMax < lifeReducationRate) lifeReducationRate /= 5; var amount = attacker.LifeMax / 100f * lifeReducationRate; attacker.ModifyLife(-amount); // TODO: Invincibility } // Spin it~ Send.UseMotion(attacker, 8, 4); cap.Handle(); Send.SkillUse(attacker, skill.Info.Id, targetAreaId, unkInt1, unkInt2); skill.Stacks = 0; }
/// <summary> /// Called for training the skill, based on what happened. /// </summary> /// <param name="attackerSkill"></param> /// <param name="tAction"></param> private void Train(Skill attackerSkill, TargetAction tAction) { var target = tAction.Creature; if (attackerSkill.Info.Rank == SkillRank.RF) { attackerSkill.Train(1); // Attack an enemy. if (target.IsDead) attackerSkill.Train(2); // Defeat an enemy. return; } var rating = tAction.Attacker.GetPowerRating(target); if (attackerSkill.Info.Rank >= SkillRank.RE && attackerSkill.Info.Rank <= SkillRank.RD) { attackerSkill.Train(1); // Attack an enemy. if (target.IsDead) attackerSkill.Train(2); // Defeat an enemy. if (rating == PowerRating.Normal) { attackerSkill.Train(3); // Attack a similar-ranked enemy. if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(4); // Knock down a similar-ranked enemy. if (target.IsDead) attackerSkill.Train(5); // Defeat a similar-ranked enemy. } else if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(6); // Knock down a powerful enemy. if (target.IsDead) attackerSkill.Train(7); // Defeat a powerful enemy. } return; } if (attackerSkill.Info.Rank >= SkillRank.RC && attackerSkill.Info.Rank <= SkillRank.RB) { if (rating == PowerRating.Normal) { attackerSkill.Train(1); // Attack a similar-ranked enemy. if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(2); // Knock down a similar-ranked enemy. if (target.IsDead) attackerSkill.Train(3); // Defeat a similar-ranked enemy. } else if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(4); // Knock down a powerful enemy. if (target.IsDead) attackerSkill.Train(5); // Defeat a powerful enemy. } else if (rating == PowerRating.Awful) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(6); // Knock down a very powerful enemy. if (target.IsDead) attackerSkill.Train(7); // Defeat a very powerful enemy. } return; } if (attackerSkill.Info.Rank >= SkillRank.RA && attackerSkill.Info.Rank <= SkillRank.R9) { if (rating == PowerRating.Normal) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(1); // Knock down a similar-ranked enemy. if (target.IsDead) attackerSkill.Train(2); // Defeat a similar-ranked enemy. } else if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(3); // Knock down a powerful enemy. if (target.IsDead) attackerSkill.Train(4); // Defeat a powerful enemy. } else if (rating == PowerRating.Awful) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(5); // Knock down a very powerful enemy. if (target.IsDead) attackerSkill.Train(6); // Defeat a very powerful enemy. } return; } if (attackerSkill.Info.Rank == SkillRank.R8) { if (rating == PowerRating.Normal) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(1); // Knock down a similar-ranked enemy. if (target.IsDead) attackerSkill.Train(2); // Defeat a similar-ranked enemy. } else if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(3); // Knock down a powerful enemy. if (target.IsDead) attackerSkill.Train(4); // Defeat a powerful enemy. } else if (rating == PowerRating.Awful) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(5); // Knock down a very powerful enemy. if (target.IsDead) attackerSkill.Train(6); // Defeat a very powerful enemy. } else if (rating == PowerRating.Boss) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(7); // Knock down a boss-level enemy. if (target.IsDead) attackerSkill.Train(8); // Defeat a boss-level enemy. } return; } if (attackerSkill.Info.Rank == SkillRank.R7) { if (rating == PowerRating.Normal) { if (target.IsDead) attackerSkill.Train(1); // Defeat a similar-ranked enemy. } else if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(2); // Knock down a powerful enemy. if (target.IsDead) attackerSkill.Train(3); // Defeat a powerful enemy. } else if (rating == PowerRating.Awful) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(4); // Knock down a very powerful enemy. if (target.IsDead) attackerSkill.Train(5); // Defeat a very powerful enemy. } else if (rating == PowerRating.Boss) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(6); // Knock down a boss-level enemy. if (target.IsDead) attackerSkill.Train(7); // Defeat a boss-level enemy. } return; } if (attackerSkill.Info.Rank >= SkillRank.R6 && attackerSkill.Info.Rank <= SkillRank.R1) { if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(1); // Knock down a powerful enemy. if (target.IsDead) attackerSkill.Train(2); // Defeat a powerful enemy. } else if (rating == PowerRating.Awful) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(3); // Knock down a very powerful enemy. if (target.IsDead) attackerSkill.Train(4); // Defeat a very powerful enemy. } else if (rating == PowerRating.Boss) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(5); // Knock down a boss-level enemy. if (target.IsDead) attackerSkill.Train(6); // Defeat a boss-level enemy. } return; } }
/// <summary> /// Skill training, called when someone attacks something /// </summary> /// <param name="action"></param> public void OnCreatureAttackedByPlayer(TargetAction action) { // Check skill if (action.AttackerSkillId != SkillId.SpinningUppercut) { return; } // Get skill var attackerSkill = action.Attacker.Skills.Get(SkillId.SpinningUppercut); if (attackerSkill == null) { return; } // Training switch (attackerSkill.Info.Rank) { case SkillRank.Novice: attackerSkill.Train(1); // Use the skill successfully. break; case SkillRank.RF: case SkillRank.RE: case SkillRank.RD: case SkillRank.RC: case SkillRank.RB: case SkillRank.RA: case SkillRank.R9: case SkillRank.R8: case SkillRank.R7: case SkillRank.R6: attackerSkill.Train(1); // Use the skill successfully. if (action.Attacker.Temp.SpinningUppercutDebuffApplied == true) { attackerSkill.Train(2); // Decrease an enemy's Defense and Protection with Spinning Uppercut. } action.Attacker.Temp.SpinningUppercutDebuffApplied = false; // Reset temp variable break; case SkillRank.R5: case SkillRank.R4: case SkillRank.R3: if (action.Has(TargetOptions.Critical)) { attackerSkill.Train(1); // Get a Critical Hit with Spinning Uppercut. } if (action.Attacker.Temp.SpinningUppercutDebuffApplied == true) { attackerSkill.Train(2); // Decrease an enemy's Defense and Protection with Spinning Uppercut. } action.Attacker.Temp.SpinningUppercutDebuffApplied = false; // Reset temp variable break; case SkillRank.R2: if (action.Attacker.Temp.SpinningUppercutDebuffApplied == true && action.Creature.HasTag("/ghost/")) { attackerSkill.Train(1); // Lower the Defense and Protection of a Ghost. } action.Attacker.Temp.SpinningUppercutDebuffApplied = false; // Reset temp variable break; case SkillRank.R1: if (action.Has(TargetOptions.Critical)) { attackerSkill.Train(1); // Get a Critical Hit with Spinning Uppercut. } if (action.Attacker.Temp.SpinningUppercutDebuffApplied == true) { attackerSkill.Train(2); // Decrease an enemy's Defense and Protection with Spinning Uppercut. } action.Attacker.Temp.SpinningUppercutDebuffApplied = false; // Reset temp variable break; } }
/// <summary> /// Handles using the skill. /// </summary> /// <param name="attacker"></param> /// <param name="skill"></param> /// <param name="targetAreaId"></param> /// <param name="unkInt1"></param> /// <param name="unkInt2"></param> public void Use(Creature attacker, Skill skill, long targetAreaId, int unkInt1, int unkInt2) { var range = this.GetRange(attacker, skill); var targets = attacker.GetTargetableCreaturesInRange(range, TargetableOptions.AddAttackRange); var rnd = RandomProvider.Get(); // Create actions var cap = new CombatActionPack(attacker, skill.Info.Id); var aAction = new AttackerAction(CombatActionType.Attacker, attacker, targetAreaId); aAction.Set(AttackerOptions.Result); aAction.Stun = AttackerStun; cap.Add(aAction); foreach (var target in targets) { // Check if hit var hitChance = this.GetHitChance(attacker, target, skill); if (rnd.Next(0, 100) > hitChance) continue; target.StopMove(); var tAction = new TargetAction(CombatActionType.TakeHit, target, attacker, skill.Info.Id); tAction.Set(TargetOptions.Result); tAction.Delay = 300; // Calculate damage var damage = this.GetDamage(attacker, skill); // Elementals damage *= attacker.CalculateElementalDamageMultiplier(target); // Handle skills and reductions CriticalHit.Handle(attacker, attacker.GetTotalCritChance(0), ref damage, tAction); SkillHelper.HandleDefenseProtection(target, ref damage); ManaShield.Handle(target, ref damage, tAction); HeavyStander.Handle(attacker, target, ref damage, tAction); // Clean Hit if not critical if (!tAction.Has(TargetOptions.Critical)) tAction.Set(TargetOptions.CleanHit); // Take damage if any is left if (damage > 0) { target.TakeDamage(tAction.Damage = damage, attacker); SkillHelper.HandleInjury(attacker, target, damage); } // Finish if dead, knock down if not defended if (target.IsDead) tAction.Set(TargetOptions.KnockDownFinish); else tAction.Set(TargetOptions.KnockDown); // Anger Management if (!target.IsDead) target.Aggro(attacker); // Stun & knock down tAction.Stun = CombatMastery.GetTargetStun(attacker.AverageKnockCount, attacker.AverageAttackSpeed, true); target.Stability = Creature.MinStability; // Add action cap.Add(tAction); } Send.UseMotion(attacker, 10, 1); cap.Handle(); Send.SkillUse(attacker, skill.Info.Id, targetAreaId, unkInt1, unkInt2); }
/// <summary> /// Trains the skill for attacker and target, based on what happened. /// </summary> /// <param name="aAction"></param> /// <param name="tAction"></param> public void Training(AttackerAction aAction, TargetAction tAction) { var attackerSkill = aAction.Creature.Skills.Get(SkillId.Counterattack); var targetSkill = tAction.Creature.Skills.Get(SkillId.Counterattack); if (attackerSkill.Info.Rank == SkillRank.RF) { attackerSkill.Train(2); // Successfully counter enemy's attack. if (tAction.SkillId == SkillId.Smash) attackerSkill.Train(4); // Counter enemy's special attack. if (tAction.Has(TargetOptions.Critical)) attackerSkill.Train(5); // Counter with critical hit. } else { attackerSkill.Train(1); // Successfully counter enemy's attack. if (tAction.SkillId == SkillId.Smash) attackerSkill.Train(2); // Counter enemy's special attack. if (tAction.Has(TargetOptions.Critical)) attackerSkill.Train(4); // Counter with critical hit. } if (targetSkill != null) targetSkill.Train(3); // Learn from the enemy's counter attack. else if (tAction.Creature.LearningSkillsEnabled) tAction.Creature.Skills.Give(SkillId.Counterattack, SkillRank.Novice); // Obtaining the Skill }
/// <summary> /// Trains skill based on target action. /// </summary> /// <param name="tAction"></param> /// <param name="attackerSkill"></param> protected virtual void Train(TargetAction tAction, Skill attackerSkill) { var rating = tAction.Attacker.GetPowerRating(tAction.Creature); if (attackerSkill.Info.Rank == SkillRank.RF) { attackerSkill.Train(1); // Attack anything. attackerSkill.Train(2); // Attack an enemy. if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(3); // Knock down an enemy using combo attack. if (tAction.Creature.IsDead) attackerSkill.Train(4); // Defeat an enemy. return; } if (attackerSkill.Info.Rank == SkillRank.RE) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(1); // Knock down an enemy using combo attack. if (tAction.Creature.IsDead) attackerSkill.Train(2); // Defeat an enemy. if (rating == PowerRating.Normal) { attackerSkill.Train(3); // Attack a similar-ranked enemy. if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(4); // Knock down a similar-ranked enemy. if (tAction.Creature.IsDead) attackerSkill.Train(5); // Defeat a similar-ranked enemy. } else if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(6); // Knock down a powerful enemy. if (tAction.Creature.IsDead) attackerSkill.Train(7); // Defeat a powerful enemy. } return; } if (attackerSkill.Info.Rank == SkillRank.RD) { attackerSkill.Train(1); // Defeat an enemy (They probably mean attack?) if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(2); // Knock down an enemy using combo attack. if (tAction.Creature.IsDead) attackerSkill.Train(3); // Defeat an enemy. if (rating == PowerRating.Normal) { attackerSkill.Train(4); // Attack a similar-ranked enemy. if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(5); // Knock down a similar-ranked enemy. if (tAction.Creature.IsDead) attackerSkill.Train(6); // Defeat a similar-ranked enemy. } else if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(7); // Knock down a powerful enemy. if (tAction.Creature.IsDead) attackerSkill.Train(8); // Defeat a powerful enemy. } return; } if (attackerSkill.Info.Rank >= SkillRank.RC && attackerSkill.Info.Rank <= SkillRank.RB) { if (rating == PowerRating.Normal) { attackerSkill.Train(1); // Attack a similar-ranked enemy. if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(2); // Knock down a similar-ranked enemy. if (tAction.Creature.IsDead) attackerSkill.Train(3); // Defeat a similar-ranked enemy. } else if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(4); // Knock down a powerful enemy. if (tAction.Creature.IsDead) attackerSkill.Train(5); // Defeat a powerful enemy. } else if (rating == PowerRating.Awful) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(6); // Knock down a very powerful enemy. if (tAction.Creature.IsDead) attackerSkill.Train(7); // Defeat a very powerful enemy. } return; } if (attackerSkill.Info.Rank >= SkillRank.RA && attackerSkill.Info.Rank <= SkillRank.R9) { if (rating == PowerRating.Normal) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(1); // Knock down a similar-ranked enemy. if (tAction.Creature.IsDead) attackerSkill.Train(2); // Defeat a similar-ranked enemy. } else if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(3); // Knock down a powerful enemy. if (tAction.Creature.IsDead) attackerSkill.Train(4); // Defeat a powerful enemy. } else if (rating == PowerRating.Awful) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(5); // Knock down a very powerful enemy. if (tAction.Creature.IsDead) attackerSkill.Train(6); // Defeat a very powerful enemy. } return; } if (attackerSkill.Info.Rank == SkillRank.R8) { if (rating == PowerRating.Normal) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(1); // Knock down a similar-ranked enemy. if (tAction.Creature.IsDead) attackerSkill.Train(2); // Defeat a similar-ranked enemy. } else if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(3); // Knock down a powerful enemy. if (tAction.Creature.IsDead) attackerSkill.Train(4); // Defeat a powerful enemy. } else if (rating == PowerRating.Awful) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(5); // Knock down a very powerful enemy. if (tAction.Creature.IsDead) attackerSkill.Train(6); // Defeat a very powerful enemy. } else if (rating == PowerRating.Boss) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(7); // Knock down a boss-level enemy. if (tAction.Creature.IsDead) attackerSkill.Train(8); // Defeat a boss-level enemy. } return; } if (attackerSkill.Info.Rank == SkillRank.R7) { if (rating == PowerRating.Normal) { if (tAction.Creature.IsDead) attackerSkill.Train(1); // Defeat a similar-ranked enemy. } else if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(2); // Knock down a powerful enemy. if (tAction.Creature.IsDead) attackerSkill.Train(3); // Defeat a powerful enemy. } else if (rating == PowerRating.Awful) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(4); // Knock down a very powerful enemy. if (tAction.Creature.IsDead) attackerSkill.Train(5); // Defeat a very powerful enemy. } else if (rating == PowerRating.Boss) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(6); // Knock down a boss-level enemy. if (tAction.Creature.IsDead) attackerSkill.Train(7); // Defeat a boss-level enemy. } return; } if (attackerSkill.Info.Rank >= SkillRank.R6 && attackerSkill.Info.Rank <= SkillRank.R1) { if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(1); // Knock down a powerful enemy. if (tAction.Creature.IsDead) attackerSkill.Train(2); // Defeat a powerful enemy. } else if (rating == PowerRating.Awful) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(3); // Knock down a very powerful enemy. if (tAction.Creature.IsDead) attackerSkill.Train(4); // Defeat a very powerful enemy. } else if (rating == PowerRating.Boss) { if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(5); // Knock down a boss-level enemy. if (tAction.Creature.IsDead) attackerSkill.Train(6); // Defeat a boss-level enemy. } return; } }
/// <summary> /// Trains skill based on target action. /// </summary> /// <param name="tAction"></param> /// <param name="attackerSkill"></param> protected virtual void Train(TargetAction tAction, Skill attackerSkill) { var rating = tAction.Attacker.GetPowerRating(tAction.Creature); if (attackerSkill.Info.Rank == SkillRank.RF) { attackerSkill.Train(1); // Attack anything. attackerSkill.Train(2); // Attack an enemy. if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(3); // Knock down an enemy using combo attack. } if (tAction.Creature.IsDead) { attackerSkill.Train(4); // Defeat an enemy. } return; } if (attackerSkill.Info.Rank == SkillRank.RE) { if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(1); // Knock down an enemy using combo attack. } if (tAction.Creature.IsDead) { attackerSkill.Train(2); // Defeat an enemy. } if (rating == PowerRating.Normal) { attackerSkill.Train(3); // Attack a similar-ranked enemy. if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(4); // Knock down a similar-ranked enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(5); // Defeat a similar-ranked enemy. } } else if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(6); // Knock down a powerful enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(7); // Defeat a powerful enemy. } } return; } if (attackerSkill.Info.Rank == SkillRank.RD) { attackerSkill.Train(1); // Defeat an enemy (They probably mean attack?) if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(2); // Knock down an enemy using combo attack. } if (tAction.Creature.IsDead) { attackerSkill.Train(3); // Defeat an enemy. } if (rating == PowerRating.Normal) { attackerSkill.Train(4); // Attack a similar-ranked enemy. if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(5); // Knock down a similar-ranked enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(6); // Defeat a similar-ranked enemy. } } else if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(7); // Knock down a powerful enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(8); // Defeat a powerful enemy. } } return; } if (attackerSkill.Info.Rank >= SkillRank.RC && attackerSkill.Info.Rank <= SkillRank.RB) { if (rating == PowerRating.Normal) { attackerSkill.Train(1); // Attack a similar-ranked enemy. if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(2); // Knock down a similar-ranked enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(3); // Defeat a similar-ranked enemy. } } else if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(4); // Knock down a powerful enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(5); // Defeat a powerful enemy. } } else if (rating == PowerRating.Awful) { if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(6); // Knock down a very powerful enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(7); // Defeat a very powerful enemy. } } return; } if (attackerSkill.Info.Rank >= SkillRank.RA && attackerSkill.Info.Rank <= SkillRank.R9) { if (rating == PowerRating.Normal) { if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(1); // Knock down a similar-ranked enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(2); // Defeat a similar-ranked enemy. } } else if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(3); // Knock down a powerful enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(4); // Defeat a powerful enemy. } } else if (rating == PowerRating.Awful) { if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(5); // Knock down a very powerful enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(6); // Defeat a very powerful enemy. } } return; } if (attackerSkill.Info.Rank == SkillRank.R8) { if (rating == PowerRating.Normal) { if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(1); // Knock down a similar-ranked enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(2); // Defeat a similar-ranked enemy. } } else if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(3); // Knock down a powerful enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(4); // Defeat a powerful enemy. } } else if (rating == PowerRating.Awful) { if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(5); // Knock down a very powerful enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(6); // Defeat a very powerful enemy. } } else if (rating == PowerRating.Boss) { if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(7); // Knock down a boss-level enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(8); // Defeat a boss-level enemy. } } return; } if (attackerSkill.Info.Rank == SkillRank.R7) { if (rating == PowerRating.Normal) { if (tAction.Creature.IsDead) { attackerSkill.Train(1); // Defeat a similar-ranked enemy. } } else if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(2); // Knock down a powerful enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(3); // Defeat a powerful enemy. } } else if (rating == PowerRating.Awful) { if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(4); // Knock down a very powerful enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(5); // Defeat a very powerful enemy. } } else if (rating == PowerRating.Boss) { if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(6); // Knock down a boss-level enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(7); // Defeat a boss-level enemy. } } return; } if (attackerSkill.Info.Rank >= SkillRank.R6 && attackerSkill.Info.Rank <= SkillRank.R1) { if (rating == PowerRating.Strong) { if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(1); // Knock down a powerful enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(2); // Defeat a powerful enemy. } } else if (rating == PowerRating.Awful) { if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(3); // Knock down a very powerful enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(4); // Defeat a very powerful enemy. } } else if (rating == PowerRating.Boss) { if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(5); // Knock down a boss-level enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(6); // Defeat a boss-level enemy. } } return; } }
/// <summary> /// Handles the majority of the skill training. /// </summary> /// <param name="obj"></param> private void OnCreatureAttacks(TargetAction tAction) { if (tAction.SkillId != SkillId.RangedAttack) return; var attackerSkill = tAction.Attacker.Skills.Get(SkillId.RangedAttack); var targetSkill = tAction.Creature.Skills.Get(SkillId.RangedAttack); var targetPowerRating = tAction.Attacker.GetPowerRating(tAction.Creature); var attackerPowerRating = tAction.Creature.GetPowerRating(tAction.Attacker); if (attackerSkill != null) { if (attackerSkill.Info.Rank == SkillRank.RF) { attackerSkill.Train(2); // Attack an enemy. if (tAction.Has(TargetOptions.KnockDown)) attackerSkill.Train(3); // Down the enemy with continuous hit. if (tAction.Creature.IsDead) attackerSkill.Train(4); // Kill an enemy. } else if (attackerSkill.Info.Rank == SkillRank.RE) { if (targetPowerRating == PowerRating.Normal) attackerSkill.Train(3); // Attack a same level enemy. if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(1); // Down the enemy with continuous hit. if (targetPowerRating == PowerRating.Normal) attackerSkill.Train(4); // Down a same level enemy. if (targetPowerRating == PowerRating.Strong) attackerSkill.Train(6); // Down a strong enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(2); // Kill an enemy. if (targetPowerRating == PowerRating.Normal) attackerSkill.Train(5); // Kill a same level enemy. if (targetPowerRating == PowerRating.Strong) attackerSkill.Train(7); // Kill a strong enemy. } } else if (attackerSkill.Info.Rank == SkillRank.RD) { attackerSkill.Train(1); // Attack any enemy. if (targetPowerRating == PowerRating.Normal) attackerSkill.Train(4); // Attack a same level enemy. if (tAction.Has(TargetOptions.KnockDown)) { attackerSkill.Train(2); // Down the enemy with continuous hit. if (targetPowerRating == PowerRating.Normal) attackerSkill.Train(5); // Down a same level enemy. if (targetPowerRating == PowerRating.Strong) attackerSkill.Train(7); // Down a strong enemy. } if (tAction.Creature.IsDead) { attackerSkill.Train(3); // Kill an enemy. if (targetPowerRating == PowerRating.Normal) attackerSkill.Train(6); // Kill a same level enemy. if (targetPowerRating == PowerRating.Strong) attackerSkill.Train(8); // Kill a strong enemy. } } else if (attackerSkill.Info.Rank >= SkillRank.RC && attackerSkill.Info.Rank <= SkillRank.RB) { if (targetPowerRating == PowerRating.Normal) attackerSkill.Train(1); // Attack a same level enemy. if (tAction.Has(TargetOptions.KnockDown)) { if (targetPowerRating == PowerRating.Normal) attackerSkill.Train(2); // Down a same level enemy. if (targetPowerRating == PowerRating.Strong) attackerSkill.Train(4); // Down a strong enemy. if (targetPowerRating == PowerRating.Awful) attackerSkill.Train(6); // Down an awful enemy. } if (tAction.Creature.IsDead) { if (targetPowerRating == PowerRating.Normal) attackerSkill.Train(3); // Kill a same level enemy. if (targetPowerRating == PowerRating.Strong) attackerSkill.Train(5); // Kill a strong enemy. if (targetPowerRating == PowerRating.Awful) attackerSkill.Train(7); // Kill an awful enemy. } } else if (attackerSkill.Info.Rank >= SkillRank.RA && attackerSkill.Info.Rank <= SkillRank.R8) { if (tAction.Has(TargetOptions.KnockDown)) { if (targetPowerRating == PowerRating.Normal) attackerSkill.Train(1); // Down a same level enemy. if (targetPowerRating == PowerRating.Strong) attackerSkill.Train(3); // Down a strong enemy. if (targetPowerRating == PowerRating.Awful) attackerSkill.Train(5); // Down an awful enemy. if (targetPowerRating == PowerRating.Boss && attackerSkill.Info.Rank == SkillRank.R8) attackerSkill.Train(7); // Down a boss level enemy. } if (tAction.Creature.IsDead) { if (targetPowerRating == PowerRating.Normal) attackerSkill.Train(2); // Kill a same level enemy. if (targetPowerRating == PowerRating.Strong) attackerSkill.Train(4); // Kill a strong enemy. if (targetPowerRating == PowerRating.Awful) attackerSkill.Train(6); // Kill an awful enemy. if (targetPowerRating == PowerRating.Boss && attackerSkill.Info.Rank == SkillRank.R8) attackerSkill.Train(8); // Kill a boss level enemy. } } else if (attackerSkill.Info.Rank >= SkillRank.R7 && attackerSkill.Info.Rank <= SkillRank.R1) { if (tAction.Has(TargetOptions.KnockDown)) { if (targetPowerRating == PowerRating.Strong) attackerSkill.Train(1); // Down a strong enemy. if (targetPowerRating == PowerRating.Awful) attackerSkill.Train(3); // Down an awful enemy. if (targetPowerRating == PowerRating.Boss) attackerSkill.Train(5); // Down a boss level enemy. } if (tAction.Creature.IsDead) { if (targetPowerRating == PowerRating.Strong) attackerSkill.Train(2); // Kill a strong enemy. if (targetPowerRating == PowerRating.Awful) attackerSkill.Train(4); // Kill an awful enemy. if (targetPowerRating == PowerRating.Boss) attackerSkill.Train(6); // Kill a boss level enemy. } } } if (targetSkill != null) { if (targetSkill.Info.Rank == SkillRank.RF) { if (tAction.Has(TargetOptions.KnockDown)) targetSkill.Train(5); // Learn by falling down. if (tAction.Creature.IsDead) targetSkill.Train(6); // Learn through losing. } else if (targetSkill.Info.Rank == SkillRank.RD) { if (attackerPowerRating == PowerRating.Strong) targetSkill.Train(8); // Receive a powerful attack from a powerful enemy. } else if (targetSkill.Info.Rank == SkillRank.R7) { if (attackerPowerRating == PowerRating.Strong) targetSkill.Train(7); // Receive a powerful attack from a powerful enemy. } } }
/// <summary> /// Handles the majority of the skill training. /// </summary> /// <param name="tAction"></param> private void OnCreatureAttacks(TargetAction tAction) { if (tAction.AttackerSkillId != SkillId.MagnumShot) return; var attackerSkill = tAction.Attacker.Skills.Get(SkillId.MagnumShot); if (attackerSkill != null) { attackerSkill.Train(1); // Attack an enemy. if (tAction.Has(TargetOptions.Critical)) attackerSkill.Train(2); if (tAction.Creature.IsDead) // Kill an enemy. { attackerSkill.Train(3); if (tAction.Has(TargetOptions.Critical)) attackerSkill.Train(4); } } }
/// <summary> /// Handles the skill training. /// </summary> /// <param name="tAction"></param> private void OnCreatureAttacks(TargetAction tAction) { if (tAction.AttackerSkillId != SkillId.SupportShot) { return; } var skill = tAction.Attacker.Skills.Get(SkillId.SupportShot); if (skill == null) { return; } var powerRating = tAction.Attacker.GetPowerRating(tAction.Creature); if (skill.Info.Rank >= SkillRank.RF && skill.Info.Rank <= SkillRank.RA) { skill.Train(1); // Successfully use the skill. if (!tAction.IsKnockBack) { skill.Train(2); // Successfully use Support Shot without knocking down the enemy. } if (tAction.Has(TargetOptions.Critical)) { skill.Train(3); // Succeed in a Critical Hit with Support Shot. } } else if (skill.Info.Rank == SkillRank.R9) { if (powerRating == PowerRating.Normal) { skill.Train(1); // Successfully use the skill on a similarly ranked enemy. } if (powerRating == PowerRating.Strong) { skill.Train(2); // Successfully use the skill on a strong enemy. } if (!tAction.IsKnockBack) { skill.Train(3); // Successfully use Support Shot without knocking down the enemy. } if (tAction.Has(TargetOptions.Critical)) { skill.Train(4); // Succeed in a Critical Hit with Support Shot. } } else if (skill.Info.Rank == SkillRank.R8) { if (powerRating == PowerRating.Normal) { skill.Train(1); // Successfully use the skill on a similarly ranked enemy. } if (powerRating == PowerRating.Strong) { skill.Train(2); // Successfully use the skill on a Strong enemy. if (tAction.Has(TargetOptions.Critical)) { skill.Train(4); // Succeed in a Critical Hit against a Strong enemy. } } if (!tAction.IsKnockBack) { skill.Train(3); // Successfully use Support Shot without knocking down the enemy. } } else if (skill.Info.Rank >= SkillRank.R7 && skill.Info.Rank <= SkillRank.R6) { if (powerRating == PowerRating.Strong) { skill.Train(1); // Successfully use the skill on a Strong enemy. if (tAction.Has(TargetOptions.Critical)) { skill.Train(4); // Succeed in a Critical Hit against a Strong enemy. } } if (powerRating == PowerRating.Awful) { skill.Train(2); // Successfully use the skill on an Awful enemy. } if (!tAction.IsKnockBack) { skill.Train(3); // Successfully use Support Shot without knocking down the enemy. } } else if (skill.Info.Rank >= SkillRank.R5 && skill.Info.Rank <= SkillRank.R4) { if (powerRating == PowerRating.Strong) { skill.Train(1); // Successfully use the skill on a Strong enemy. } if (powerRating == PowerRating.Awful) { skill.Train(2); // Successfully use the skill on an Awful enemy. if (tAction.Has(TargetOptions.Critical)) { skill.Train(4); // Succeed in a Critical Hit against an Awful enemy. } } if (!tAction.IsKnockBack) { skill.Train(3); // Successfully use Support Shot without knocking down the enemy. } } else if (skill.Info.Rank >= SkillRank.R3 && skill.Info.Rank <= SkillRank.R1) { if (powerRating == PowerRating.Awful) { skill.Train(1); // Successfully use the skill on an Awful enemy. } if (powerRating == PowerRating.Boss) { skill.Train(2); // Successfully use the skill on a Boss-level enemy. if (tAction.Has(TargetOptions.Critical)) { skill.Train(4); // Succeed in a Critical Hit against a Boss-level enemy. } } if (!tAction.IsKnockBack) { skill.Train(3); // Successfully use Support Shot without knocking down the enemy. } } }