public MotionCommand GetMotion(MotionStance stance, AttackHeight attackHeight, AttackType attackType, uint minSkillLevel = 0) { if (!Stances.TryGetValue(stance, out var attackHeights)) { return(MotionCommand.Invalid); } if (!attackHeights.Table.TryGetValue(attackHeight, out var attackTypes)) { return(MotionCommand.Invalid); } if (!attackTypes.Table.TryGetValue(attackType, out var minSkillLevels)) { return(MotionCommand.Invalid); } foreach (var kvp in minSkillLevels.Table) { if (kvp.Key > minSkillLevel) { continue; } return(kvp.Value); } return(MotionCommand.Invalid); }
public Quadrant GetQuadrant(Creature defender, Creature attacker, AttackHeight attackHeight, WorldObject damageSource) { var quadrant = attackHeight.ToQuadrant(); var wo = damageSource.CurrentLandblock != null ? damageSource : attacker; quadrant |= wo.GetRelativeDir(defender); return(quadrant); }
/// <summary> /// Returns a body part for a creature defender /// </summary> public void GetBodyPart(AttackHeight attackHeight, Creature defender) { // select random body part @ current attack height BiotaPropertiesBodyPart = BodyParts.GetBodyPart(defender, attackHeight); if (BiotaPropertiesBodyPart == null) { Evaded = true; return; } CreaturePart = new Creature_BodyPart(defender, BiotaPropertiesBodyPart); }
public static BodyPart GetBodyPart(AttackHeight attackHeight) { switch (attackHeight) { case AttackHeight.High: return(GetBodyPart(Upper)); case AttackHeight.Medium: return(GetBodyPart(Mid)); case AttackHeight.Low: default: return(GetBodyPart(Lower)); } }
public static string GetString(this AttackHeight attackHeight) { switch (attackHeight) { case AttackHeight.High: return("High"); case AttackHeight.Medium: return("Med"); case AttackHeight.Low: return("Low"); } return(null); }
public static Quadrant ToQuadrant(this AttackHeight attackHeight) { switch (attackHeight) { case AttackHeight.High: return(Quadrant.High); case AttackHeight.Medium: return(Quadrant.Medium); case AttackHeight.Low: return(Quadrant.Low); default: return(Quadrant.None); } }
public MotionCommand GetMotion(MotionStance stance, AttackHeight attackHeight, AttackType attackType, MotionCommand prevMotion) { if (!Stances.TryGetValue(stance, out var attackHeights)) { return(MotionCommand.Invalid); } if (!attackHeights.Table.TryGetValue(attackHeight, out var attackTypes)) { return(MotionCommand.Invalid); } if (!attackTypes.Table.TryGetValue(attackType, out var maneuvers)) { return(MotionCommand.Invalid); } if (maneuvers.Count == 1) { return(maneuvers[0]); } /*Console.WriteLine($"CombatManeuverTable({Id:X8}).GetMotion({stance}, {attackHeight}, {attackType}) - found {maneuvers.Count} maneuvers"); * foreach (var maneuver in maneuvers) * Console.WriteLine(maneuver);*/ // CombatManeuverTable(30000000).GetMotion(SwordCombat, Medium, Slash) - found 2 maneuvers // SlashMed // BackhandMed // rng, or alternate? for (var i = 0; i < maneuvers.Count; i++) { var maneuver = maneuvers[i]; if (maneuver == prevMotion) { if (i < maneuvers.Count - 1) { return(maneuvers[i + 1]); } else { return(maneuvers[0]); } } } return(maneuvers[0]); }
public List <MotionCommand> GetMotion(MotionStance stance, AttackHeight attackHeight, AttackType attackType, MotionCommand prevMotion) { if (!Stances.TryGetValue(stance, out var attackHeights)) { return(Invalid); } if (!attackHeights.Table.TryGetValue(attackHeight, out var attackTypes)) { return(Invalid); } if (!attackTypes.Table.TryGetValue(attackType, out var maneuvers)) { return(Invalid); } //if (maneuvers.Count == 1) //return maneuvers[0]; /*Console.WriteLine($"CombatManeuverTable({Id:X8}).GetMotion({stance}, {attackHeight}, {attackType}) - found {maneuvers.Count} maneuvers"); * foreach (var maneuver in maneuvers) * Console.WriteLine(maneuver);*/ // CombatManeuverTable(30000000).GetMotion(SwordCombat, Medium, Slash) - found 2 maneuvers // SlashMed // BackhandMed // rng, or alternate? /*for (var i = 0; i < maneuvers.Count; i++) * { * var maneuver = maneuvers[i]; * * if (maneuver == prevMotion) * { * if (i < maneuvers.Count - 1) * return maneuvers[i + 1]; * else * return maneuvers[0]; * } * } * return maneuvers[0];*/ // if the CMT contains > 1 entries for this lookup, return both // the code determines which motion to use based on the power bar return(maneuvers); }
public void HandleActionTargetedMeleeAttack(ObjectGuid guid, uint attackHeight, float powerLevel) { /*Console.WriteLine("HandleActionTargetedMeleeAttack"); * Console.WriteLine("Target ID: " + guid.Full.ToString("X8")); * Console.WriteLine("Attack height: " + attackHeight); * Console.WriteLine("Power level: " + powerLevel);*/ // sanity check powerLevel = Math.Clamp(powerLevel, 0.0f, 1.0f); AttackHeight = (AttackHeight)attackHeight; PowerLevel = powerLevel; // get world object of target guid var target = CurrentLandblock.GetObject(guid); if (target == null) { log.Warn("Unknown target guid " + guid.Full.ToString("X8")); return; } if (MeleeTarget == null) { MeleeTarget = target; } else { return; } // get distance from target var dist = GetDistance(target); // get angle to target var angle = GetAngle(target); //Console.WriteLine("Dist: " + dist); //Console.WriteLine("Angle: " + angle); // turn / moveto if required Rotate(target); MoveTo(target); // do melee attack Attack(target); }
public static BiotaPropertiesBodyPart GetBodyPart(WorldObject target, AttackHeight height) { var creature = target as Creature; if (creature == null) { return(null); } // get all of the body parts for this creature // at this attack height var heightParts = creature.Biota.BiotaPropertiesBodyPart.Where(b => b.BH == (int)height).ToList(); if (heightParts.Count == 0) { return(null); } // get random body part var rng = Physics.Common.Random.RollDice(0, heightParts.Count - 1); var part = heightParts[rng]; return(part); }
/// <summary> /// Returns a body part for a player defender /// </summary> public void GetBodyPart(AttackHeight attackHeight) { // select random body part @ current attack height BodyPart = BodyParts.GetBodyPart(attackHeight); }
private float DoCalculateDamage(Creature attacker, Creature defender, WorldObject damageSource) { var playerAttacker = attacker as Player; var playerDefender = defender as Player; Attacker = attacker; Defender = defender; CombatType = damageSource.ProjectileSource == null?attacker.GetCombatType() : CombatType.Missile; DamageSource = damageSource; Weapon = damageSource.ProjectileSource == null?attacker.GetEquippedWeapon() : damageSource.ProjectileLauncher; AttackType = attacker.GetAttackType(Weapon, CombatManeuver); AttackHeight = attacker.AttackHeight ?? AttackHeight.Medium; // check lifestone protection if (playerDefender != null && playerDefender.UnderLifestoneProtection) { LifestoneProtection = true; playerDefender.HandleLifestoneProtection(); return(0.0f); } if (defender.Invincible) { return(0.0f); } // evasion chance EvasionChance = GetEvadeChance(attacker, defender); if (EvasionChance > ThreadSafeRandom.Next(0.0f, 1.0f)) { Evaded = true; return(0.0f); } // get base damage if (playerAttacker != null) { GetBaseDamage(playerAttacker, CombatManeuver); } else { GetBaseDamage(attacker, CombatManeuver); } if (DamageType == DamageType.Undef) { log.Error($"DamageEvent.DoCalculateDamage({attacker?.Name} ({attacker?.Guid}), {defender?.Name} ({defender?.Guid}), {damageSource?.Name} ({damageSource?.Guid})) - DamageType == DamageType.Undef"); GeneralFailure = true; } if (GeneralFailure) { return(0.0f); } // get damage modifiers PowerMod = attacker.GetPowerMod(Weapon); AttributeMod = attacker.GetAttributeMod(Weapon); SlayerMod = WorldObject.GetWeaponCreatureSlayerModifier(attacker, defender); // ratings DamageRatingBaseMod = Creature.GetPositiveRatingMod(attacker.GetDamageRating()); RecklessnessMod = Creature.GetRecklessnessMod(attacker, defender); SneakAttackMod = attacker.GetSneakAttackMod(defender); HeritageMod = attacker.GetHeritageBonus(Weapon) ? 1.05f : 1.0f; DamageRatingMod = Creature.AdditiveCombine(DamageRatingBaseMod, RecklessnessMod, SneakAttackMod, HeritageMod); // damage before mitigation DamageBeforeMitigation = BaseDamage * AttributeMod * PowerMod * SlayerMod * DamageRatingMod; // critical hit? var attackSkill = attacker.GetCreatureSkill(attacker.GetCurrentWeaponSkill()); CriticalChance = WorldObject.GetWeaponCritChanceModifier(attacker, attackSkill, defender); if (CriticalChance > ThreadSafeRandom.Next(0.0f, 1.0f)) { if (playerDefender != null && playerDefender.AugmentationCriticalDefense > 0) { var criticalDefenseMod = playerAttacker != null ? 0.05f : 0.25f; var criticalDefenseChance = playerDefender.AugmentationCriticalDefense * criticalDefenseMod; if (criticalDefenseChance > ThreadSafeRandom.Next(0.0f, 1.0f)) { CriticalDefended = true; } } if (!CriticalDefended) { IsCritical = true; CriticalDamageMod = 1.0f + WorldObject.GetWeaponCritDamageMod(attacker, attackSkill, defender); // recklessness excluded from crits RecklessnessMod = 1.0f; DamageRatingMod = Creature.AdditiveCombine(DamageRatingBaseMod, SneakAttackMod, HeritageMod); DamageBeforeMitigation = BaseDamageMod.MaxDamage * AttributeMod * PowerMod * SlayerMod * DamageRatingMod * CriticalDamageMod; } } // Armor Rending reduces physical armor too? var armorRendingMod = 1.0f; if (Weapon != null && Weapon.HasImbuedEffect(ImbuedEffectType.ArmorRending)) { armorRendingMod = WorldObject.GetArmorRendingMod(attackSkill); } // get body part / armor pieces / armor modifier if (playerDefender != null) { // select random body part @ current attack height GetBodyPart(AttackHeight); // get player armor pieces Armor = attacker.GetArmorLayers(playerDefender, BodyPart); // get armor modifiers ArmorMod = attacker.GetArmorMod(DamageType, Armor, Weapon, armorRendingMod); } else { // select random body part @ current attack height GetBodyPart(AttackHeight, defender); if (Evaded) { return(0.0f); } Armor = CreaturePart.GetArmorLayers((CombatBodyPart)BiotaPropertiesBodyPart.Key); // get target armor ArmorMod = CreaturePart.GetArmorMod(DamageType, Armor, Weapon, armorRendingMod); } if (Weapon != null && Weapon.HasImbuedEffect(ImbuedEffectType.IgnoreAllArmor)) { ArmorMod = 1.0f; } // get resistance modifiers WeaponResistanceMod = WorldObject.GetWeaponResistanceModifier(attacker, attackSkill, DamageType); if (playerDefender != null) { ResistanceMod = playerDefender.GetResistanceMod(DamageType, Weapon, WeaponResistanceMod); } else { var resistanceType = Creature.GetResistanceType(DamageType); ResistanceMod = (float)defender.GetResistanceMod(resistanceType, Weapon, WeaponResistanceMod); } // damage resistance rating DamageResistanceRatingMod = Creature.GetNegativeRatingMod(defender.GetDamageResistRating(CombatType)); // get shield modifier ShieldMod = defender.GetShieldMod(attacker, DamageType, Weapon); // calculate final output damage Damage = DamageBeforeMitigation * ArmorMod * ShieldMod * ResistanceMod * DamageResistanceRatingMod; DamageMitigated = DamageBeforeMitigation - Damage; return(Damage); }
private float DoCalculateDamage(Creature attacker, Creature defender, WorldObject damageSource) { var playerAttacker = attacker as Player; var playerDefender = defender as Player; Attacker = attacker; Defender = defender; CombatType = damageSource.ProjectileSource == null ? CombatType.Melee : CombatType.Missile; DamageSource = damageSource; Weapon = damageSource.ProjectileSource == null?attacker.GetEquippedMeleeWeapon() : damageSource.ProjectileLauncher; AttackType = attacker.AttackType; AttackHeight = attacker.AttackHeight ?? AttackHeight.Medium; // check lifestone protection if (playerDefender != null && playerDefender.UnderLifestoneProtection) { LifestoneProtection = true; playerDefender.HandleLifestoneProtection(); return(0.0f); } if (defender.Invincible) { return(0.0f); } // overpower if (attacker.Overpower != null) { Overpower = Creature.GetOverpower(attacker, defender); } // evasion chance if (!Overpower) { EvasionChance = GetEvadeChance(attacker, defender); if (EvasionChance > ThreadSafeRandom.Next(0.0f, 1.0f)) { Evaded = true; return(0.0f); } } // get base damage if (playerAttacker != null) { GetBaseDamage(playerAttacker); } else { GetBaseDamage(attacker, AttackMotion ?? MotionCommand.Invalid); } if (DamageType == DamageType.Undef && !AllowDamageTypeUndef.Contains(damageSource.WeenieClassId)) { log.Error($"DamageEvent.DoCalculateDamage({attacker?.Name} ({attacker?.Guid}), {defender?.Name} ({defender?.Guid}), {damageSource?.Name} ({damageSource?.Guid})) - DamageType == DamageType.Undef"); GeneralFailure = true; } if (GeneralFailure) { return(0.0f); } // get damage modifiers PowerMod = attacker.GetPowerMod(Weapon); AttributeMod = attacker.GetAttributeMod(Weapon); SlayerMod = WorldObject.GetWeaponCreatureSlayerModifier(attacker, defender); // ratings DamageRatingBaseMod = Creature.GetPositiveRatingMod(attacker.GetDamageRating()); RecklessnessMod = Creature.GetRecklessnessMod(attacker, defender); SneakAttackMod = attacker.GetSneakAttackMod(defender); HeritageMod = attacker.GetHeritageBonus(Weapon) ? 1.05f : 1.0f; DamageRatingMod = Creature.AdditiveCombine(DamageRatingBaseMod, RecklessnessMod, SneakAttackMod, HeritageMod); // damage before mitigation DamageBeforeMitigation = BaseDamage * AttributeMod * PowerMod * SlayerMod * DamageRatingMod; // critical hit? var attackSkill = attacker.GetCreatureSkill(attacker.GetCurrentWeaponSkill()); CriticalChance = WorldObject.GetWeaponCriticalChance(attacker, attackSkill, defender); // https://asheron.fandom.com/wiki/Announcements_-_2002/08_-_Atonement // It should be noted that any time a character is logging off, PK or not, all physical attacks against them become automatically critical. // (Note that spells do not share this behavior.) We hope this will stress the need to log off in a safe place. if (playerDefender != null && (playerDefender.IsLoggingOut || playerDefender.PKLogout)) { CriticalChance = 1.0f; } if (CriticalChance > ThreadSafeRandom.Next(0.0f, 1.0f)) { if (playerDefender != null && playerDefender.AugmentationCriticalDefense > 0) { var criticalDefenseMod = playerAttacker != null ? 0.05f : 0.25f; var criticalDefenseChance = playerDefender.AugmentationCriticalDefense * criticalDefenseMod; if (criticalDefenseChance > ThreadSafeRandom.Next(0.0f, 1.0f)) { CriticalDefended = true; } } if (!CriticalDefended) { IsCritical = true; CriticalDamageMod = 1.0f + WorldObject.GetWeaponCritDamageMod(attacker, attackSkill, defender); // recklessness excluded from crits RecklessnessMod = 1.0f; DamageRatingMod = Creature.AdditiveCombine(DamageRatingBaseMod, SneakAttackMod, HeritageMod); DamageBeforeMitigation = BaseDamageMod.MaxDamage * AttributeMod * PowerMod * SlayerMod * DamageRatingMod * CriticalDamageMod; } } // armor rending and cleaving var armorRendingMod = 1.0f; if (Weapon != null && Weapon.HasImbuedEffect(ImbuedEffectType.ArmorRending)) { armorRendingMod = WorldObject.GetArmorRendingMod(attackSkill); } var armorCleavingMod = attacker.GetArmorCleavingMod(Weapon); var ignoreArmorMod = Math.Min(armorRendingMod, armorCleavingMod); // get body part / armor pieces / armor modifier if (playerDefender != null) { // select random body part @ current attack height GetBodyPart(AttackHeight); // get player armor pieces Armor = attacker.GetArmorLayers(playerDefender, BodyPart); // get armor modifiers ArmorMod = attacker.GetArmorMod(DamageType, Armor, Weapon, ignoreArmorMod); } else { // determine height quadrant Quadrant = GetQuadrant(Defender, Attacker, AttackHeight, DamageSource); // select random body part @ current attack height GetBodyPart(Defender, Quadrant); if (Evaded) { return(0.0f); } Armor = CreaturePart.GetArmorLayers(PropertiesBodyPart.Key); // get target armor ArmorMod = CreaturePart.GetArmorMod(DamageType, Armor, Attacker, Weapon, ignoreArmorMod); } if (Weapon != null && Weapon.HasImbuedEffect(ImbuedEffectType.IgnoreAllArmor)) { ArmorMod = 1.0f; } // get resistance modifiers WeaponResistanceMod = WorldObject.GetWeaponResistanceModifier(attacker, attackSkill, DamageType); if (playerDefender != null) { ResistanceMod = playerDefender.GetResistanceMod(DamageType, Attacker, Weapon, WeaponResistanceMod); } else { var resistanceType = Creature.GetResistanceType(DamageType); ResistanceMod = (float)Math.Max(0.0f, defender.GetResistanceMod(resistanceType, Attacker, Weapon, WeaponResistanceMod)); } // damage resistance rating DamageResistanceRatingMod = defender.GetDamageResistRatingMod(CombatType); // get shield modifier ShieldMod = defender.GetShieldMod(attacker, DamageType, Weapon); // calculate final output damage Damage = DamageBeforeMitigation * ArmorMod * ShieldMod * ResistanceMod * DamageResistanceRatingMod; DamageMitigated = DamageBeforeMitigation - Damage; return(Damage); }
/// <summary> /// Returns the current attack height as an enumerable string /// </summary> public string GetAttackHeight() { return(AttackHeight?.GetString()); }
private float DoCalculateDamage(Creature attacker, Creature defender, WorldObject damageSource) { var playerAttacker = attacker as Player; var playerDefender = defender as Player; Attacker = attacker; Defender = defender; CombatType = attacker.GetCombatType(); DamageSource = damageSource; Weapon = attacker.GetEquippedWeapon(); AttackType = attacker.GetAttackType(Weapon, CombatManeuver); AttackHeight = attacker.AttackHeight ?? AttackHeight.Medium; // check lifestone protection if (playerDefender != null && playerDefender.UnderLifestoneProtection) { LifestoneProtection = true; playerDefender.HandleLifestoneProtection(); return(0.0f); } if (defender.Invincible ?? false) { return(0.0f); } // evasion chance EvasionChance = GetEvadeChance(attacker, defender); if (EvasionChance > ThreadSafeRandom.Next(0.0f, 1.0f)) { Evaded = true; return(0.0f); } // get base damage if (playerAttacker != null) { GetBaseDamage(playerAttacker, CombatManeuver); } else { GetBaseDamage(attacker, CombatManeuver); } if (GeneralFailure) { return(0.0f); } // get damage modifiers PowerMod = attacker.GetPowerMod(Weapon); AttributeMod = attacker.GetAttributeMod(Weapon); SlayerMod = WorldObject.GetWeaponCreatureSlayerModifier(attacker, defender); // additive? ElementalDamageBonus = WorldObject.GetMissileElementalDamageModifier(attacker, defender, DamageType); // ratings DamageRatingBaseMod = Creature.GetPositiveRating(attacker.GetProperty(PropertyInt.DamageRating) ?? 0); RecklessnessMod = Creature.GetRecklessnessMod(attacker, defender); SneakAttackMod = attacker.GetSneakAttackMod(defender); HeritageMod = attacker.GetHeritageBonus(Weapon) ? 1.05f : 1.0f; DamageRatingMod = Creature.AdditiveCombine(DamageRatingBaseMod, RecklessnessMod, SneakAttackMod, HeritageMod, Creature.GetRatingMod(attacker.EnchantmentManager.GetDamageRating())); // damage before mitigation DamageBeforeMitigation = BaseDamage * AttributeMod * PowerMod * SlayerMod * DamageRatingMod + ElementalDamageBonus; // additives on the end? // critical hit? var attackSkill = attacker.GetCreatureSkill(attacker.GetCurrentWeaponSkill()); CriticalChance = WorldObject.GetWeaponCritChanceModifier(attacker, attackSkill); if (CriticalChance > ThreadSafeRandom.Next(0.0f, 1.0f)) { IsCritical = true; CriticalDamageMod = 1.0f + WorldObject.GetWeaponCritDamageMod(attacker, attackSkill); // recklessness excluded from crits RecklessnessMod = 1.0f; DamageRatingMod = Creature.AdditiveCombine(DamageRatingBaseMod, SneakAttackMod, HeritageMod, Creature.GetRatingMod(attacker.EnchantmentManager.GetDamageRating())); DamageBeforeMitigation = BaseDamageRange.Max * AttributeMod * PowerMod * SlayerMod * DamageRatingMod * CriticalDamageMod + ElementalDamageBonus; } // get armor rending mod here? var armorRendingMod = 1.0f; if (Weapon != null && Weapon.HasImbuedEffect(ImbuedEffectType.ArmorRending)) { armorRendingMod = WorldObject.GetArmorRendingMod(attackSkill); } // get body part / armor pieces / armor modifier if (playerDefender != null) { // select random body part @ current attack height GetBodyPart(AttackHeight); // get armor pieces Armor = attacker.GetArmorLayers(BodyPart); // this uses attacker.AttackTarget // get armor modifiers ArmorMod = attacker.GetArmorMod(DamageType, Armor, DamageSource, armorRendingMod); } else { // select random body part @ current attack height GetBodyPart(AttackHeight, defender); if (Evaded) { return(0.0f); } Armor = CreaturePart.GetArmorLayers((CombatBodyPart)BiotaPropertiesBodyPart.Key); // get target armor ArmorMod = CreaturePart.GetArmorMod(DamageType, Armor, DamageSource, armorRendingMod); } // get resistance modifiers WeaponResistanceMod = WorldObject.GetWeaponResistanceModifier(attacker, attackSkill, DamageType); if (playerDefender != null) { ResistanceMod = playerDefender.GetResistanceMod(DamageType, DamageSource, WeaponResistanceMod); } else { // todo: move out of creature part, not part-related? ResistanceMod = CreaturePart.GetResistanceMod(DamageType, DamageSource, WeaponResistanceMod); } // damage resistance rating DamageResistanceRatingMod = Creature.GetNegativeRatingMod(defender.EnchantmentManager.GetDamageResistRating()); // get shield modifier ShieldMod = defender.GetShieldMod(attacker, DamageType); // calculate final output damage Damage = DamageBeforeMitigation * ArmorMod * ShieldMod * ResistanceMod * DamageResistanceRatingMod; DamageMitigated = DamageBeforeMitigation - Damage; HandleLogging(playerAttacker, playerDefender); return(Damage); }
public override string GetAttackHeight() { return AttackHeight?.GetString(); }