Exemplo n.º 1
0
        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);
        }