Ejemplo n.º 1
0
		public static int GetValue( Mobile m, AbsorptionAttribute attribute )
		{
			int value = 0;

			foreach ( var item in m.GetEquippedItems() )
			{
				if ( item is IAbsorption )
				{
					AbsorptionAttributes attrs = ( (IAbsorption) item ).AbsorptionAttributes;

					if ( attrs != null )
						value += attrs[attribute];
				}
			}

			return value;
		}
Ejemplo n.º 2
0
        public static int Damage(bool directDamage, Mobile m, Mobile from, int damage, int phys, int fire, int cold, int pois, int nrgy, int chao, bool keepAlive)
        {
            if (m == null || m.Deleted || !m.Alive || damage <= 0)
            {
                return(0);
            }

            if (phys == 0 && fire == 100 && cold == 0 && pois == 0 && nrgy == 0)
            {
                Mobiles.MeerMage.StopEffect(m, true);
            }

            Fix(ref phys);
            Fix(ref fire);
            Fix(ref cold);
            Fix(ref pois);
            Fix(ref nrgy);
            Fix(ref chao);

            switch (Utility.RandomMinMax(1, 5))
            {
            case 1: phys += chao; break;

            case 2: fire += chao; break;

            case 3: cold += chao; break;

            case 4: pois += chao; break;

            case 5: nrgy += chao; break;
            }

            chao = 0;

            int resPhys = m.PhysicalResistance;
            int resFire = m.FireResistance;
            int resCold = m.ColdResistance;
            int resPois = m.PoisonResistance;
            int resNrgy = m.EnergyResistance;

            if (m_ArmorIgnore)
            {
                resPhys = fire = cold = pois = nrgy = 0;
                phys    = 100;
            }

            if (m_ArmorPierce)
            {
                double delta = 0.6;                 // is this correct?

                resPhys -= (int)(delta * resPhys);
            }

            int totalDamage;

            totalDamage  = damage * phys * (100 - resPhys);
            totalDamage += damage * fire * (100 - resFire);
            totalDamage += damage * cold * (100 - resCold);
            totalDamage += damage * pois * (100 - resPois);
            totalDamage += damage * nrgy * (100 - resNrgy);

            totalDamage /= 10000;

            if (totalDamage < 1)
            {
                totalDamage = 1;
            }

            int absorbed;

            #region Damage Eater
            int dmgEater = Math.Min((int)AbsorptionAttributes.GetValue(m, AbsorptionAttribute.DamageEater), 18);

            int physEater = dmgEater;
            int fireEater = dmgEater;
            int coldEater = dmgEater;
            int poisEater = dmgEater;
            int nrgyEater = dmgEater;

            if (!m_ArmorIgnore)
            {
                physEater = Math.Min(Math.Max(AbsorptionAttributes.GetValue(m, AbsorptionAttribute.KineticEater), dmgEater), 30);
                fireEater = Math.Min(Math.Max(AbsorptionAttributes.GetValue(m, AbsorptionAttribute.FireEater), dmgEater), 30);
                coldEater = Math.Min(Math.Max(AbsorptionAttributes.GetValue(m, AbsorptionAttribute.ColdEater), dmgEater), 30);
                poisEater = Math.Min(Math.Max(AbsorptionAttributes.GetValue(m, AbsorptionAttribute.PoisonEater), dmgEater), 30);
                nrgyEater = Math.Min(Math.Max(AbsorptionAttributes.GetValue(m, AbsorptionAttribute.EnergyEater), dmgEater), 30);
            }

            absorbed  = damage * phys * (100 - resPhys) * physEater;
            absorbed += damage * fire * (100 - resFire) * fireEater;
            absorbed += damage * cold * (100 - resCold) * coldEater;
            absorbed += damage * pois * (100 - resPois) * poisEater;
            absorbed += damage * nrgy * (100 - resNrgy) * nrgyEater;

            absorbed /= 1000000;

            if (m is PlayerMobile)
            {
                ((PlayerMobile)m).EatDamage(absorbed);
            }
            #endregion

            if (!m_ArmorIgnore)
            {
                #region Resonance
                if (m.Spell is Spell && m.Spell.IsCasting)
                {
                    for (int i = 0; i < 5; i++)
                    {
                        double chance = 0.0;

                        switch (i)
                        {
                        case 0: chance = (double)AbsorptionAttributes.GetValue(m, AbsorptionAttribute.KineticResonance) / phys; break;

                        case 1: chance = (double)AbsorptionAttributes.GetValue(m, AbsorptionAttribute.FireResonance) / fire; break;

                        case 2: chance = (double)AbsorptionAttributes.GetValue(m, AbsorptionAttribute.ColdResonance) / cold; break;

                        case 3: chance = (double)AbsorptionAttributes.GetValue(m, AbsorptionAttribute.PoisonResonance) / pois; break;

                        case 4: chance = (double)AbsorptionAttributes.GetValue(m, AbsorptionAttribute.EnergyResonance) / nrgy; break;
                        }

                        if (chance > Utility.RandomDouble())
                        {
                            ((Spell)m.Spell).Resonates = true;
                            break;
                        }
                    }
                }
                #endregion
            }

            #region Dragon Barding
            if ((from == null || !from.IsPlayer) && m.IsPlayer && m.Mount is SwampDragon)
            {
                SwampDragon pet = m.Mount as SwampDragon;

                if (pet != null && pet.HasBarding)
                {
                    int percent = (pet.BardingExceptional ? 20 : 10);
                    absorbed = Scale(totalDamage, percent);

                    totalDamage -= absorbed;
                    if (!(pet is ParoxysmusSwampDragon))
                    {
                        pet.BardingHP -= absorbed;
                    }

                    if (pet.BardingHP < 0)
                    {
                        pet.HasBarding = false;
                        pet.BardingHP  = 0;

                        m.SendLocalizedMessage(1053031);                           // Your dragon's barding has been destroyed!
                    }
                }
            }
            #endregion

            if (keepAlive && totalDamage > m.Hits)
            {
                totalDamage = m.Hits;
            }

            if (from != null)
            {
                int reflectPhys = m.GetMagicalAttribute(MagicalAttribute.ReflectPhysical);

                if (reflectPhys != 0)
                {
                    if (from is ExodusMinion && ((ExodusMinion)from).FieldActive || from is ExodusOverseer && ((ExodusOverseer)from).FieldActive)
                    {
                        from.FixedParticles(0x376A, 20, 10, 0x2530, EffectLayer.Waist);
                        from.PlaySound(0x2F4);
                        m.SendAsciiMessage("Your weapon cannot penetrate the creature's magical barrier");
                    }
                    else
                    {
                        int rpd_damage = Scale((damage * phys * (100 - from.PhysicalResistance)) / 10000, reflectPhys);
                        if (m is PlayerMobile && from is PlayerMobile && directDamage)
                        {
                            rpd_damage = Math.Min(rpd_damage, 35);
                        }
                        from.Damage(rpd_damage, m);
                    }
                }
            }

            if (from is BaseCreature)
            {
                Mobile master = ((BaseCreature)from).ControlMaster;

                if (master != null)
                {
                    master.RevealingAction();
                }

                #region Talismans
                BaseTalisman talis = BaseTalisman.GetTalisman(m);

                if (talis != null && talis.ProtectionTalis != NPC_Name.None && talis.ProtectionValue > 0)
                {
                    if (ProtectionKillerEntry.IsProtectionKiller(talis.ProtectionTalis, from))
                    {
                        totalDamage = totalDamage - ((totalDamage * talis.ProtectionValue) / 100);
                    }
                }
                #endregion
            }

            if (from != null)
            {
                Item cloak     = from.FindItemOnLayer(Layer.Cloak);
                Item twohanded = from.FindItemOnLayer(Layer.TwoHanded);

                if (directDamage && cloak is BaseQuiver && twohanded is BaseRanged)
                {
                    BaseQuiver quiver = cloak as BaseQuiver;
                    totalDamage += (int)(totalDamage * quiver.DamageModifier * 0.01);
                }
            }

            if (m is PlayerMobile && from is PlayerMobile && directDamage)
            {
                totalDamage = Math.Min(totalDamage, 35);
            }

            /* TODO: El efecto del Attunement debería ir despues de aplicar el Blood Oath.
             * Según parece, en OSI los Necro-Arcanists lo usan mucho en PvP, de manera que
             * el daño recibido se refleja al atacante por Blood Oath, pero luego es
             * absorbido por el Attunement en el defensor.
             */
            if (directDamage)
            {
                Spells.Spellweaving.AttunementSpell.TryAbsorb(m, ref totalDamage);
            }

            if (from != null)
            {
                SpellHelper.DoLeech(totalDamage, from, m);
            }

            m.Damage(totalDamage, from);

            return(totalDamage);
        }