public override bool Process(ICharacter source, ICharacter victim, IAbility ability, CombatHelpers.AttackResults attackResult) { int amount = ComputeAttributeBasedAmount(source, Attribute, Factor); PerformDamage(source, victim, ability, attackResult, amount, School); return(true); }
private static void ProcessOnOneTarget(ICharacter source, ICharacter victim, IAbility ability, bool cannotMiss, bool cannotBeDodgedParriedBlocked) { if (ability?.Effects == null || ability.Effects.Count == 0 || !source.IsValid || !victim.IsValid) { return; } // Miss/Dodge/Parray/Block check (only for harmful ability) CombatHelpers.AttackResults attackResult = CombatHelpers.AttackResults.Hit; if (ability.Behavior == AbilityBehaviors.Harmful) { // Starts fight if needed (if A attacks B, A fights B and B fights A) if (source != victim) { if (source.Fighting == null) { source.StartFighting(victim); } if (victim.Fighting == null) { victim.StartFighting(source); } // TODO: Cannot attack slave without breaking slavery } if (ability.Kind == AbilityKinds.Skill) { // TODO: refactor same code in Character.OneHit // Miss, dodge, parry, ... attackResult = CombatHelpers.YellowMeleeAttack(source, victim, cannotMiss, cannotBeDodgedParriedBlocked); Log.Default.WriteLine(LogLevels.Debug, $"{source.DebugName} -> {victim.DebugName} : attack result = {attackResult}"); switch (attackResult) { case CombatHelpers.AttackResults.Miss: victim.Act(ActOptions.ToCharacter, "{0} misses you.", source); source.Act(ActOptions.ToCharacter, "You miss {0}.", victim); return; // no effect applied case CombatHelpers.AttackResults.Dodge: victim.Act(ActOptions.ToCharacter, "You dodge {0}'s {1}.", source, ability.Name); source.Act(ActOptions.ToCharacter, "{0} dodges your {1}.", victim, ability.Name); return; // no effect applied case CombatHelpers.AttackResults.Parry: victim.Act(ActOptions.ToCharacter, "You parry {0}'s {1}.", source, ability.Name); source.Act(ActOptions.ToCharacter, "{0} parries your {1}.", victim, ability.Name); return; // no effect applied case CombatHelpers.AttackResults.Block: EquipedItem victimShield = victim.Equipments.FirstOrDefault(x => x.Item != null && x.Slot == EquipmentSlots.Shield); if (victimShield != null) // will never be null because MeleeAttack will not return Block if no shield { victim.Act(ActOptions.ToCharacter, "You block {0}'s {1} with {2}.", source, ability.Name, victimShield.Item); source.Act(ActOptions.ToCharacter, "{0} blocks your {1} with {2}.", victim, ability.Name, victimShield.Item); } // effect applied break; case CombatHelpers.AttackResults.Critical: case CombatHelpers.AttackResults.CrushingBlow: case CombatHelpers.AttackResults.Hit: // effect applied break; default: Log.Default.WriteLine(LogLevels.Error, $"Ability {ability.Name}[{ability.Kind}] returned an invalid attack result: {attackResult}"); break; } } else if (ability.Kind == AbilityKinds.Spell && ability.Behavior == AbilityBehaviors.Harmful) { // Miss/Hit/Critical attackResult = CombatHelpers.SpellAttack(source, victim, cannotMiss); switch (attackResult) { case CombatHelpers.AttackResults.Miss: victim.Act(ActOptions.ToCharacter, "{0} misses you.", source); source.Act(ActOptions.ToCharacter, "You miss {0}.", victim); return; // no effect applied case CombatHelpers.AttackResults.Hit: case CombatHelpers.AttackResults.Critical: // effect applied break; default: Log.Default.WriteLine(LogLevels.Error, $"Ability {ability.Name}[{ability.Kind}] returned an invalid attack result: {attackResult}"); break; } } else { Log.Default.WriteLine(LogLevels.Error, $"Ability {ability.Name} has an invalid kind: {ability.Kind}"); } } // Apply effects foreach (AbilityEffect effect in ability.Effects) { effect.Process(source, victim, ability, attackResult); } }
public override bool Process(ICharacter source, ICharacter victim, IAbility ability, CombatHelpers.AttackResults attackResult) { if (victim.Auras.Any(x => x.Ability != null && x.Ability == DependencyContainer.Instance.GetInstance <IAbilityManager>().WeakenedSoulAbility)) { source.Act(ActOptions.ToCharacter, "{0} cannot be targeted by {1}.", victim, ability.Name); return(false); } int amount = ComputeAttributeBasedAmount(source, SecondaryAttributeTypes.SpellPower, 45.9m); DependencyContainer.Instance.GetInstance <IWorld>().AddAura(victim, ability, source, AuraModifiers.DamageAbsorb, amount, AmountOperators.Fixed, ability.Duration, true); DependencyContainer.Instance.GetInstance <IWorld>().AddAura(victim, DependencyContainer.Instance.GetInstance <IAbilityManager>().WeakenedSoulAbility, source, AuraModifiers.None, 0, AmountOperators.None, 15, true); return(true); }
public override bool Process(ICharacter source, ICharacter victim, IAbility ability, CombatHelpers.AttackResults attackResult) { if (victim.Form == Form) { return(victim.ChangeForm(Forms.Normal)); } return(victim.ChangeForm(Form)); }
public override bool Process(ICharacter source, ICharacter victim, IAbility ability, CombatHelpers.AttackResults attackResult) { int amount = ComputeAttributeBasedAmount(source, Attribute, Factor); int totalTicks = ability.Duration / TickDelay; DependencyContainer.Instance.GetInstance <IWorld>().AddPeriodicAura(victim, ability, source, amount, AmountOperators.Fixed, true, TickDelay, totalTicks); return(true); }
public override bool Process(ICharacter source, ICharacter victim, IAbility ability, CombatHelpers.AttackResults attackResult) { // TODO: difference between buff/debuff to handle Offensive flag // Check periodic aura IPeriodicAura periodicAura = victim.PeriodicAuras.FirstOrDefault(x => x.Ability != null && x.Ability.DispelType == DispelType); if (periodicAura != null) { victim.RemovePeriodicAura(periodicAura); return(true); } // Check aura IAura aura = victim.Auras.FirstOrDefault(x => x.Ability != null && x.Ability.DispelType == DispelType); if (aura != null) { victim.RemoveAura(aura, true); return(true); } return(true); }
public override bool Process(ICharacter source, ICharacter victim, IAbility ability, CombatHelpers.AttackResults attackResult) { DependencyContainer.Instance.GetInstance <IWorld>().AddAura(victim, ability, source, Modifier, Amount, AmountOperator, ability.Duration, true); return(true); }
protected void PerformDamage(ICharacter source, ICharacter victim, IAbility ability, CombatHelpers.AttackResults attackResult, int damage, SchoolTypes damageType) { if (ability.Kind == AbilityKinds.Skill) { // TODO: refactor same code in Character.OneHit switch (attackResult) { case CombatHelpers.AttackResults.Miss: case CombatHelpers.AttackResults.Dodge: case CombatHelpers.AttackResults.Parry: return; // no damage case CombatHelpers.AttackResults.Block: damage = (damage * 7) / 10; break; case CombatHelpers.AttackResults.Critical: // TODO http://wow.gamepedia.com/Critical_strike if (victim.ImpersonatedBy != null) // PVP { damage = (damage * 150) / 200; } else // PVE { damage *= 2; } break; case CombatHelpers.AttackResults.CrushingBlow: // http://wow.gamepedia.com/Crushing_Blow damage = (damage * 150) / 200; break; case CombatHelpers.AttackResults.Hit: // not modified break; } } else if (ability.Kind == AbilityKinds.Spell) { // Miss/Hit/Critical switch (attackResult) { case CombatHelpers.AttackResults.Miss: return; // no damage case CombatHelpers.AttackResults.Critical: // http://wow.gamepedia.com/Spell_critical_strike damage *= 2; break; case CombatHelpers.AttackResults.Hit: // no modifier break; } } victim.AbilityDamage(source, ability, damage, damageType, true); }
public override bool Process(ICharacter source, ICharacter victim, IAbility ability, CombatHelpers.AttackResults attackResult) { int amount = ComputeAttributeBasedAmount(source, Attribute, Factor); source.Heal(source, ability, amount, true); return(true); }
public override bool Process(ICharacter source, ICharacter victim, IAbility ability, CombatHelpers.AttackResults attackResult) { int amount = RandomizeHelpers.Instance.Randomizer.Next(MinDamage, MaxDamage + 1); PerformDamage(source, victim, ability, attackResult, amount, School); return(true); }
public abstract bool Process(ICharacter source, ICharacter victim, IAbility ability, CombatHelpers.AttackResults attackResult);