/** Adds a miss swipe to characters frame. */ private void addSwipe(MDRActor source) { var newSwipe = new GuiAttackSwipe(0.5f, 0.05f); newSwipe.X = 3 + Util.Roll(5); newSwipe.Y = 1 + Util.Roll(5); Add(newSwipe); }
/** * Calculates the change this source could backstab hit the target. */ public static float BackstabChance(MDRActor source, MDRActor target) { float baseChance = (float)source.TotalBackstabChance / 100f; float levelDelta = (source.CombatLevel - target.CombatLevel) / 5f; float levelModifier = CalculateLogDifference(levelDelta); return(baseChance * (1f + levelModifier)); }
/** * Calculates the change this source could critical hit the target. */ public static float CriticalHitChance(MDRActor source, MDRActor target) { float baseChance = (float)source.TotalCriticalHitChance / 100f; float levelDelta = (source.CombatLevel - target.CombatLevel) / 5f; float levelModifier = CalculateLogDifference(levelDelta); float final = baseChance * (1f + levelModifier); return(final); }
/** * Calculates chance one actor can hit another. */ public static float CalculateChanceToHit(MDRActor source, MDRActor target) { // We calculate a base hit from guild level then offset it by dexterity. float dexterityDelta = source.Stats.Dex - target.Stats.Dex; float dexMod = dexterityDelta >= 0 ? (Mathf.Sqrt(1 + dexterityDelta / 4f) - 1f) * 0.5f : (Mathf.Sqrt(1 - dexterityDelta / 4f) - 1f) * -0.5f; float origionalDexMod = dexMod; float levelDelta = (source.CombatLevel - target.CombatLevel) / 5f; float levelModifier = CalculateLogDifference(levelDelta); // adjust deviation if (levelModifier < 0 && dexMod > 0) { float dexModReduction = Util.Clamp(-levelModifier * 4f, 0f, 1f); dexMod *= dexModReduction; } // bonus from defending. float baseHit = (target.ActionThisRound == ActionType.Defend) ? 0.4f : 0.6f; float chanceToHit = baseHit + levelModifier + dexMod + (float)source.TotalHitBonus / 100f; float clampedChanceToHit = Util.Clamp(chanceToHit, 0.03f, 0.97f); /* * if (Settings.Advanced.LogCombat && Engines.CombatEngine.CurrentInstance != null) { * * var debugString = String.Format("\nChance to hit breakdown [{0:0.00}]:" + * "\n baseHit: {1:0.00}" + * "\n levelMod: {2:0.00}" + * ((dexMod != origionalDexMod) ? "\n dexMod: {3:0.00} (reduced from {4:0.00})" : "\n dexMod: {3:0.00}") + * "\n hitBonus: {5:0.00}", chanceToHit, baseHit, levelModifier, dexMod, origionalDexMod, (float)source.TotalHitBonus / 100f); * Engines.CombatEngine.CombatLog.Add(new UI.MessageEntry(debugString, Color.gray)); * } */ return(clampedChanceToHit); }
/** * Calculates damage from one actor to another. */ public static int CalculateDamage(MDRActor source, MDRActor target, bool didCrit, bool didBackstab, out int mitigation) { // First work out how much damage this source could inflict. int damageRoll = Util.Roll(6) + Util.Roll(6) + Util.Roll(6); float critFactor = didCrit ? 1.5f : 1f; float backstabFactor = didBackstab ? 1.25f : 1f; float baseDamage = source.NominalDamage * ((float)damageRoll / 9f) * critFactor * backstabFactor; float strengthBonus = Util.Clamp(source.Stats.Str - 15, 0f, 99f); float strengthHandicap = Util.Clamp(source.Stats.Str - 10, -99f, 0f) * 0.5f; float levelDelta = (source.CombatLevel - target.CombatLevel) / 5f; float levelModifier = CalculateLogDifference(levelDelta); float finalDamage = (int)((1f + levelModifier) * (baseDamage + strengthBonus) + strengthHandicap); // Next work out how much of this damage the target's armour can exporbe float baseMitigation = target.TotalArmour; float modifiedMitigation = baseMitigation; // Armour ability is reduced by level modifier. if (levelModifier < 0) { modifiedMitigation *= (1 + levelModifier); } // bonus from defending. if (target.ActionThisRound == ActionType.Defend) { modifiedMitigation *= 1.5f; } if (didBackstab) { modifiedMitigation *= 0.25f; } if (didCrit) { modifiedMitigation *= 0.75f; } // Pentration due to weapon and strength. var weaponPiercing = source.TotalArmourPierce + strengthBonus * 2f; modifiedMitigation -= Util.Clamp(weaponPiercing, 0f, 999f); // Strong hits go through weak armour float strongHitModifer = finalDamage / 2f; modifiedMitigation -= strongHitModifer; modifiedMitigation = Util.Clamp(modifiedMitigation, 0f, 999f) / 2f; float mitigationReductionFactor = (finalDamage) / (finalDamage + modifiedMitigation); float mitigatedDamage = (int)(finalDamage * (1f - mitigationReductionFactor)); mitigation = (int)mitigatedDamage; /* * if (Settings.Advanced.LogCombat && Engines.CombatEngine.CurrentInstance != null) { * var debugString = String.Format("Damage caused breakdown [{0}]: \n" + * "SourceSTR:{1}={2} NominalDamage:{3} DamageRoll{4} Final:{10}\n" + * "levelDelta:{5} level modifier:{6}\n" + * "mitigation - base:{7} modified:{8} factor:{9}", * mitigatedDamage, source.Stats.Str, strengthBonus + strengthHandicap, * source.NominalDamage, damageRoll, levelDelta, levelModifier, baseMitigation, modifiedMitigation, mitigationReductionFactor, finalDamage); * Engines.CombatEngine.CombatLog.Add(new UI.MessageEntry(debugString, Color.gray)); * } */ return((int)Util.Clamp(finalDamage - mitigatedDamage, 1f, 999f)); }