/// <summary> /// Checks if target has Defense skill activated and makes the necessary /// changes to the actions, stun times, and damage. /// </summary> /// <param name="aAction"></param> /// <param name="tAction"></param> /// <param name="damage"></param> /// <returns></returns> public static bool HandleDefense(AttackerAction aAction, TargetAction tAction, ref float damage) { // Defense if (!tAction.Creature.Skills.IsActive(SkillId.Defense)) { return(false); } // Update actions tAction.Type = CombatActionType.Defended; tAction.SkillId = SkillId.Defense; tAction.Creature.Stun = tAction.Stun = DefenseTargetStun; aAction.Creature.Stun = aAction.Stun = DefenseAttackerStun; // Reduce damage var defenseSkill = tAction.Creature.Skills.Get(SkillId.Defense); if (defenseSkill != null) { damage -= defenseSkill.RankData.Var3; } Send.SkillUseStun(tAction.Creature, SkillId.Defense, 1000, 0); return(true); }
/// <summary> /// Checks if target's Mana Shield is active, calculates mana /// damage, and sets target action's Mana Damage property if applicable. /// </summary> /// <param name="target"></param> /// <param name="damage"></param> /// <param name="tAction"></param> public static void HandleManaShield(Creature target, ref float damage, TargetAction tAction) { // Mana Shield active? if (!target.Conditions.Has(ConditionsA.ManaShield)) { return; } // Get Mana Shield skill to get the rank's vars var manaShield = target.Skills.Get(SkillId.ManaShield); if (manaShield == null) // Checks for things that should never ever happen, yay. { return; } // Var 1 = Efficiency var manaDamage = damage / manaShield.RankData.Var1; if (target.Mana >= manaDamage) { // Damage is 0 if target's mana is enough to cover it damage = 0; } else { // Set mana damage to target's mana and reduce the remaining // damage from life if the mana is not enough. damage -= (manaDamage - target.Mana) * manaShield.RankData.Var1; manaDamage = target.Mana; } // Reduce mana target.Mana -= manaDamage; if (target.Mana <= 0) { ChannelServer.Instance.SkillManager.GetHandler <StartStopSkillHandler>(SkillId.ManaShield).Stop(target, manaShield); } tAction.ManaDamage = manaDamage; }
/// <summary> /// Checks if attacker has Critical Hit and applies crit bonus /// by chance. Also sets the target action's critical option if a /// crit happens. /// </summary> /// <param name="attacker"></param> /// <param name="critChance"></param> /// <param name="damage"></param> /// <param name="tAction"></param> public static void HandleCritical(Creature attacker, float critChance, ref float damage, TargetAction tAction) { // Check if attacker actually has critical hit var critSkill = attacker.Skills.Get(SkillId.CriticalHit); if (critSkill == null) { return; } // Does the crit happen? if (RandomProvider.Get().NextDouble() > critChance) { return; } // Add crit bonus var bonus = critSkill.RankData.Var1 / 100f; damage = damage + (damage * bonus); // Set target option tAction.Set(TargetOptions.Critical); }
/// <summary> /// Calculates and sets splash damage reductions and bonuses against splashTarget. /// </summary> /// <param name="splashTarget"></param> /// <param name="damageSplash"></param> /// <param name="skill"></param> /// <param name="critSkill"></param> /// <param name="aAction"></param> /// <param name="tAction"></param> /// <param name="tSplashAction"></param> public void CalculateSplashDamage(Creature splashTarget, ref float damageSplash, Skill skill, Skill critSkill, AttackerAction aAction, TargetAction tAction, TargetAction tSplashAction, Item weapon = null) { //Splash Damage Reduction if (skill.Info.Id == SkillId.Smash) damageSplash *= skill.Info.Rank < SkillRank.R1 ? 0.1f : 0.2f; else damageSplash *= weapon != null ? weapon.Data.SplashDamage : 0f; // 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 = damageSplash; //Damage without Defense and Protection // Subtract splashTarget def/prot SkillHelper.HandleDefenseProtection(splashTarget, ref damageSplash); // Defense Channel.Skills.Combat.Defense.Handle(aAction, tSplashAction, ref damageSplash); // Mana Shield ManaShield.Handle(splashTarget, ref damageSplash, tSplashAction, maxDamageSplash); if (damageSplash <= 0f) damageSplash = 1f; }
// ------------------------------------------------------------------ /// <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) || action.Has(TargetOptions.Smash)) && _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> /// Called when creature is hit. /// </summary> /// <param name="action"></param> public virtual void OnHit(TargetAction action) { 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); } }