public static void Attack(CRController attacker, CRWeaponItem weapon, float multiplier, CRController defender) { // can't attack if we have no offence if (!attacker.creature.offence) return; int n = 1; float trip = attacker.creature.offence.tripleChance(attacker.creature.level) * 0.01f; float dbl = attacker.creature.offence.doubleChance(attacker.creature.level) * 0.01f; float v = Random.Range(0, 1.0f); if ( v < trip) { n = 3; } else if ( v < trip + dbl) { n = 2; } for (int i=0; i<n; i++) { CRCombatResult result = CRCombatManager.ResolveMelee(attacker.creature.offence, weapon, multiplier, 0, defender.creature.defence); result.attacker = attacker; result.defender = defender; Messenger<CRCombatResult>.Broadcast("CombatResult", result); if (result.amount > 0) { defender.BroadcastMessage("takeDamage", result); if (defender.creature.isDead()) { attacker.SendMessage("gainExperience", defender.creature.level * defender.creature.level * 500); break; } } NPCThreat threat = result.defender.GetComponent<NPCThreat>(); if (threat) threat.addThreat(result.attacker, result.threat); } }
void Awake() { int size = System.Enum.GetValues( typeof( CREquipSlot ) ).Length; base.Init(size); _defaultWeapon = CRWeaponItem.Hand(); _defaultWeapon.transform.parent = transform; SetDefault(_defaultWeapon, (int)CREquipSlot.PRIMARY); }
public void setWeapon(CRWeaponItem weapon) { this.weapon = weapon; if (null != weapon) { this.swing.length = weapon.swing; this.delay.length = weapon.delay; this.swing.Reset(); this.delay.Reset(); } swinging = false; }
/// <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; }
public CRArm(CRWeaponItem weapon) { setWeapon(weapon); }