예제 #1
0
        public void Damage(int damage, double penetration, DamageType type, out int damageResistance, out int damageDealt)
        {
            Contract.Ensures(Contract.ValueAtReturn(out damageDealt) >= 0);
            Contract.Ensures(Contract.ValueAtReturn(out damageResistance) >= 0);

            damageDealt      = damage;
            damageResistance = 0;

            if (Defender.Has <EquipmentComponent>())
            {
                var equipment = Defender.Get <EquipmentComponent>();

                if (equipment.ContainSlot(BodyPartTargetted.Name) && equipment.IsSlotEquipped(BodyPartTargetted.Name))
                {
                    var armorEntity = equipment.GetEquippedItemAt(BodyPartTargetted.Name);

                    if (armorEntity.Has <ArmorComponent>())
                    {
                        var armor = armorEntity.Get <ArmorComponent>();

                        if (armor.Defenses.ContainsKey(BodyPartTargetted.Name))
                        {
                            if (Rng.Chance(armor.Defenses[BodyPartTargetted.Name].Coverage / 100.0))
                            {
                                damageResistance = (int)Math.Floor(armor.Defenses[BodyPartTargetted.Name].Resistances[type] / penetration);
                                damageDealt      = Math.Max(damage - damageResistance, 0);
                                Logger.InfoFormat("Damage: {3} reduced to {0} because of {1} [DR: {2}]", damageDealt, armor.OwnerUId, damageResistance, damage);
                            }
                            else
                            {
                                // we hit a chink in the armor
                                damageResistance = 0;
                                Logger.InfoFormat("Hit a chink in the armor, DR = 0");
                            }
                        }
                    }
                }
            }

            if (Defender.Has <ActorComponent>())
            {
                Defender.Get <ActorComponent>().Disturb();
            }

            if (damageDealt > BodyPartTargetted.MaxHealth)
            {
                damageDealt = Math.Min(damage, BodyPartTargetted.MaxHealth);
                Logger.DebugFormat("Damage reduced to {0} because of {1}'s max health", damageDealt, BodyPartTargetted.Name);
            }

            BodyPartTargetted.Health       -= damageDealt;
            BodyPartTargetted.Owner.Health -= damageDealt;

            Logger.InfoFormat("{0}'s {1} was hurt ({2} damage)", Identifier.GetNameOrId(Defender), BodyPartTargetted.Name, damageDealt);
        }