public void SendDamage(DamagePackage damage, BodyPart bodyPart) { damageReceiver = damage.Target; damageHandler = null; damageWorldItem = null; damage.OnPackageSent.SafeInvoke(); if (damageReceiver != null) { //check if it's a player because it's the eaiest switch (damageReceiver.IOIType) { case ItemOfInterestType.Player: damageHandler = Player.Local.DamageHandler; break; case ItemOfInterestType.WorldItem: Damageable damageable = null; damageWorldItem = damageReceiver.worlditem; if (damageReceiver.worlditem.Is <Damageable> (out damageable)) { damageHandler = damageable; } else { //if it's an instant kill, destroy it now if (damage.InstantKill) { Debug.Log("Instant kill in damage manager"); damage.HitTarget = true; damage.TargetIsDead = true; damage.DamageDealt = damage.DamageSent; damageReceiver.worlditem.RemoveFromGame(); return; } } break; case ItemOfInterestType.Scenery: DamageableChild dc = null; if (damageReceiver.gameObject.HasComponent <DamageableChild> (out dc)) //get the parent from the damageable child { damageHandler = dc.DamageableParent; } else { //if it's not a world item and it's not a body part check for a general damage handler //this includes the player's damage handler damageHandler = (IDamageable)damageReceiver.gameObject.GetComponent(typeof(IDamageable)); } break; default: break; } } //apply damage using the damage handler if (damageHandler != null) { receiverMaterial = damageHandler.BaseMaterialType; receiverArmorMaterials = damageHandler.ArmorMaterialTypes; int receiverArmorLevel = 0; if (receiverArmorMaterials != WIMaterialType.None) { receiverArmorLevel = damageHandler.ArmorLevel(receiverArmorMaterials); } //get damage multiplier for material types //TODO re-enable these //damage.DamageSent = damage.DamageSent * BaseWeaponDamageMultiplier (damage.SenderMaterial, receiverMaterial); //damage.DamageSent = damage.DamageSent * BaseArmorReductionMultiplier (damage.SenderMaterial, receiverArmorMaterials); //check if there's a material bonus for this damage sender if (damage.MaterialBonus != WIMaterialType.None) { if (Flags.Check((uint)receiverMaterial, (uint)damage.MaterialBonus, Flags.CheckType.MatchAny)) { damage.DamageSent *= Globals.DamageMaterialBonusMultiplier; } } if (damage.MaterialPenalty != WIMaterialType.None) { if (Flags.Check((uint)receiverMaterial, (uint)damage.MaterialPenalty, Flags.CheckType.MatchAny)) { damage.DamageSent *= Globals.DamageMaterialPenaltyMultiplier; } } damageHandler.LastDamageSource = damage.Source; //this has a good chance of being null damageHandler.LastBodyPartHit = bodyPart; if (damage.InstantKill) { damageHandler.InstantKill(damage.Source); } else { damage.HitTarget = damageHandler.TakeDamage(damage.SenderMaterial, damage.Point, damage.DamageSent, damage.Force, damage.SenderName, out damage.DamageDealt, out damage.TargetIsDead); } if (damage.HitTarget) { SpawnDamageFX(damage.Point, receiverMaterial, damage.DamageDealt); PlayDamageSound(damage.Point, receiverMaterial, damage.DamageDealt); if (bodyPart != null && !damage.TargetIsDead) { switch (bodyPart.Type) { case BodyPartType.Eye: GUI.GUIManager.PostSuccess("Inflicted eye wound"); damage.DamageSent = Globals.DamageBodyPartEyeMultiplier; break; case BodyPartType.Head: case BodyPartType.Face: case BodyPartType.Neck: GUI.GUIManager.PostSuccess("Inflicted head wound"); damage.DamageSent *= Globals.DamageBodyPartHeadMultiplier; break; case BodyPartType.Chest: case BodyPartType.Hip: case BodyPartType.Segment: case BodyPartType.Shoulder: case BodyPartType.None: default: GUI.GUIManager.PostSuccess("Inflicted torso wound"); damage.DamageSent *= Globals.DamageBodyPartTorsoMultiplier; break; case BodyPartType.Finger: case BodyPartType.Hand: case BodyPartType.Wrist: case BodyPartType.Arm: case BodyPartType.Foot: case BodyPartType.Shin: case BodyPartType.Leg: GUI.GUIManager.PostSuccess("Inflicted limb wound"); damage.DamageSent *= Globals.DamageBodyPartLimbMultiplier; break; } } } damage.OnPackageReceived.SafeInvoke(); } else { //if we didn't find a damage handler but we did find a worlditem //send force to the worlditem so it doesn't just sit there if (damageWorldItem != null) { damageWorldItem.ApplyForce(damage.Force, damage.Point); } } //play the sender's fx no matter what SpawnDamageFX(damage.Point, damage.SenderMaterial, damage.DamageDealt); PlayDamageSound(damage.Point, damage.SenderMaterial, damage.DamageDealt); }