/// <summary> /// Melee Attack Solver. Given two parties a CombatResult will be generated /// </summary> public static CRCombatResult ResolveMelee(CROffence offence, CRWeaponItem weapon, float multiplier, float bonus, CRDefence defence, Dictionary<CRCombatEvent, float> chances = null) { if (null == defence) { defence = CRCombatManager.defaultDefence; } // Create the Combat Table CRCombatTable combatTable = new CRCombatTable(); if (null != chances) { foreach (KeyValuePair<CRCombatEvent, float> chance in chances) { combatTable.AddChance(chance.Key, chance.Value); } } // Add attack parameters combatTable.AddChance(CRCombatEvent.MISS, offence.missChance(defence.level)); combatTable.AddChance(CRCombatEvent.CRIT, offence.critChance(defence.level)); combatTable.AddChance(CRCombatEvent.CRUSH, offence.crushChance(defence.level)); // Add defend parameters combatTable.AddChance(CRCombatEvent.MISS, defence.avoidChance(offence.level)); combatTable.AddChance(CRCombatEvent.DODGE, defence.dodgeChance(offence.level)); combatTable.AddChance(CRCombatEvent.PARRY, defence.parryChance(offence.level)); combatTable.AddChance(CRCombatEvent.BLOCK, defence.blockChance(offence.level)); combatTable.AddChance(CRCombatEvent.DEFLECT, defence.deflectChance(offence.level)); combatTable.AddChance(CRCombatEvent.REFLECT, defence.reflectChance(offence.level)); // Do the combat roll CRCombatEvent combatEvent = combatTable.Roll(CRCombatType.MELEE); // Generate the attack results CRCombatResult result = new CRCombatResult(); result.combatEvent = combatEvent; // Is there a potential for damage to be done if (combatEvent == CRCombatEvent.HIT || combatEvent == CRCombatEvent.CRIT || combatEvent == CRCombatEvent.CRUSH || combatEvent == CRCombatEvent.BLOCK) { // Yes we need to perform a damage calculation float min = (weapon.minDamage / weapon.speed + offence.attack / 14.0f) * weapon.speed * multiplier + bonus; // * (penalty) dual weild etc float max = (weapon.maxDamage / weapon.speed + offence.attack / 14.0f) * weapon.speed * multiplier + bonus; // * (penalty) dual weild etc float damage = Random.Range(min, max); damage *= 0.01f * offence.damage; //apply crit modifier if (combatEvent == CRCombatEvent.CRIT) { damage += damage * offence.critDamage * 0.01f; } else if (combatEvent == CRCombatEvent.CRUSH) { damage += damage * offence.crushDamage * 0.01f; } else if (combatEvent == CRCombatEvent.BLOCK) { // Remove blocked amount } // Remove any absorbtion // Calculate mitigation based on defenders armor and the attackers level float mitigation = defence.armor / (50 * offence.level + defence.armor); // Add any raw mitigation the defender has mitigation += defence.mitigation; // Remove any mitigation from armor penetration // Mitigation can not be more than 100%, however it can be negative making the defender take more than normal damage mitigation = 1 - Mathf.Min(1, mitigation); result.amount = Mathf.CeilToInt(damage * mitigation); result.threat = result.amount; } return result; }
private void Awake() { _attributeManager = GetComponentInChildren<CRAttributeManager>(); _abilityManager = GetComponentInChildren<CRAbilityManager>(); _effectManager = gameObject.AddComponent<CREffectManager>(); _conditionManager = gameObject.AddComponent<CRConditionManager>(); _equipment = GetComponentInChildren<CREquipment>(); _inventory = GetComponentInChildren<CRInventory>(); _offence = GetComponent<CROffence>(); _defence = GetComponent<CRDefence>(); _faction = GetComponent<CRFaction>(); if (_equipment && _attributeManager) _equipment.attributeManager = _attributeManager; _effectManager.creature = this; }