/// <summary> /// Combat calculations for PC hitting an NPC /// </summary> /// <param name="playerUW">Player Character</param> /// <param name="npc">Npc.</param> /// <param name="hit">Hit.</param> public static void PC_Hits_NPC(UWCharacter playerUW, WeaponMelee currentWeapon, string StrikeName, float StrikeCharge, NPC npc, RaycastHit hit) { int attackScore = 0; int flankingbonus = 0; //need to calcu but depending on relative headings between attacker and defender. int magicbonus = 0; //currently unknown what provides this but is calculated by casting/5 + 0xA when set. short MinCharge; short MaxCharge; if (npc != null) { //recalc position to get the correct heading for the flanking bonus npc.objInt().UpdatePosition(); flankingbonus = CalcFlankingBonus(playerUW.currentHeading, npc.objInt().heading); } if (currentWeapon != null) { attackScore = (playerUW.PlayerSkills.GetSkill(Skills.SkillAttack) >> 1) + playerUW.PlayerSkills.GetSkill(currentWeapon.GetSkill()) + (playerUW.PlayerSkills.DEX / 7) + magicbonus + flankingbonus; if (GameWorldController.instance.difficulty == 0) {//bonus of 7 for easy difficulty attackScore += 7; } attackScore += currentWeapon.AccuracyBonus();//Given by the accuracy enchantments. Note in vanilla UW2 accuracy actually increases damage and not attack score. This is fixed here. MinCharge = currentWeapon.GetMinCharge(); MaxCharge = currentWeapon.GetMaxCharge(); } else { //use the unarmed calculations attackScore = (playerUW.PlayerSkills.GetSkill(Skills.SkillAttack) >> 1) + playerUW.PlayerSkills.GetSkill(Skills.SkillUnarmed) + (playerUW.PlayerSkills.DEX / 7) + magicbonus + flankingbonus; if (GameWorldController.instance.difficulty == 0) {//bonus of 7 for easy difficulty attackScore += 7; } MinCharge = WeaponMelee.GetMeleeMinCharge(); MaxCharge = WeaponMelee.GetMeleeMaxCharge(); } //Get base damage int BaseSwingDamage = GetPlayerBaseDamage(currentWeapon, StrikeName); int basePower = (short)(GameWorldController.instance.objDat.critterStats[63].Strength / 9); //the player is actually a critter so power in this case is their STR. int WeaponBonusDamage = 0; if (currentWeapon != null) { WeaponBonusDamage = currentWeapon.DamageBonus(); } else { //unarmed basePower = (short)(GameWorldController.instance.objDat.critterStats[63].Strength / 6); //the player is actually a critter so power in this case is their STR. basePower += (playerUW.PlayerSkills.GetSkill(Skills.SkillUnarmed) / 5); } //scale base damage by charge. Min damage is always 2. short Damage = (short)(basePower + BaseSwingDamage + WeaponBonusDamage); // damage % 6 no of 1D6s to calculate the actual damage and then add the remainder as a final roll 1-remainder Damage = (short)(DamageRoll((short)(Damage / 6), 6) + DamageRoll(1, (short)(Damage % 6))); //Damage is scaled by the amount of weapon charge built up. Damage = CalcAttackChargeDamage((short)StrikeCharge, MinCharge, MaxCharge, Damage); //And a flat flanking bonus Damage += (short)flankingbonus; //Min damage will be 2. Damage = (short)(Mathf.Max(Damage, 2)); Skills.SkillRollResult rollresult = Skills.SkillRoll(attackScore, npc.Defence()); bool CriticalHit = RollForCritDamage(ref Damage, rollresult); switch (rollresult) { case Skills.SkillRollResult.CriticalSuccess: case Skills.SkillRollResult.Success: { Debug.Log("Base Damage = " + ((short)(basePower + BaseSwingDamage + WeaponBonusDamage)) + " Final Damage = " + Damage); if (CriticalHit) { Impact.SpawnHitImpact(Impact.ImpactBlood(), npc.GetImpactPoint() + Vector3.up * 0.1f, npc.objInt().GetHitFrameStart(), npc.objInt().GetHitFrameEnd()); } npc.ApplyAttack(Damage, playerUW.gameObject); Impact.SpawnHitImpact(Impact.ImpactBlood(), npc.GetImpactPoint(), npc.objInt().GetHitFrameStart(), npc.objInt().GetHitFrameEnd()); if (currentWeapon != null) { ///Performs the onHit action of the melee weapon. currentWeapon.onHit(hit.transform.gameObject); } break; } case Skills.SkillRollResult.Failure: npc.ApplyAttack(0, playerUW.gameObject); npc.npc_aud.PlayCombatMissed(); break; case Skills.SkillRollResult.CriticalFailure: { npc.ApplyAttack(0, playerUW.gameObject); npc.npc_aud.PlayCombatMissed(); //Damage weapon short durability = currentWeapon.getDurability(); if (durability <= 30) { currentWeapon.SelfDamage((short)Mathf.Max(0, Random.Range(0, npc.EquipDamage + 1) - durability)); } break; } } }