コード例 #1
0
        /// <summary>
        /// Applies some amount of damage to this monster from source
        /// </summary>
        /// <param name="source">The attacker / source of damage</param>
        /// <param name="amount">The amount of damage rounded</param>
        public virtual uint TakeDamage(WorldObject source, DamageType damageType, float amount, bool crit = false)
        {
            var tryDamage = (int)Math.Round(amount);
            var damage    = -UpdateVitalDelta(Health, -tryDamage);

            // TODO: update monster stamina?

            // source should only be null for combined DoT ticks from multiple sources
            if (source != null)
            {
                if (damage >= 0)
                {
                    DamageHistory.Add(source, damageType, (uint)damage);
                }
                else
                {
                    DamageHistory.OnHeal((uint)-damage);
                }
            }

            if (Health.Current <= 0)
            {
                OnDeath(DamageHistory.LastDamager, damageType, crit);

                Die();
            }
            return((uint)Math.Max(0, damage));
        }
コード例 #2
0
        /// <summary>
        /// Applies damages to a player from a physical damage source
        /// </summary>
        public void TakeDamage(WorldObject source, DamageType damageType, float _amount, BodyPart bodyPart, bool crit = false)
        {
            if (Invincible ?? false)
            {
                return;
            }

            // check lifestone protection
            if (UnderLifestoneProtection)
            {
                HandleLifestoneProtection();
                return;
            }

            var amount  = (uint)Math.Round(_amount);
            var percent = (float)amount / Health.MaxValue;

            // update health
            var damageTaken = (uint)-UpdateVitalDelta(Health, (int)-amount);

            DamageHistory.Add(source, damageType, damageTaken);

            // update stamina
            UpdateVitalDelta(Stamina, -1);

            if (Fellowship != null)
            {
                Fellowship.OnVitalUpdate(this);
            }

            if (Health.Current == 0)
            {
                OnDeath(source, damageType, crit);
                Die();
                return;
            }

            var damageLocation = (DamageLocation)BodyParts.Indices[bodyPart];

            // send network messages
            var creature = source as Creature;
            var hotspot  = source as Hotspot;

            if (creature != null)
            {
                var text = new GameEventDefenderNotification(Session, creature.Name, damageType, percent, amount, damageLocation, crit, AttackConditions.None);
                Session.Network.EnqueueSend(text);

                var hitSound = new GameMessageSound(Guid, GetHitSound(source, bodyPart), 1.0f);
                var splatter = new GameMessageScript(Guid, (PlayScript)Enum.Parse(typeof(PlayScript), "Splatter" + creature.GetSplatterHeight() + creature.GetSplatterDir(this)));
                EnqueueBroadcast(hitSound, splatter);
            }

            if (percent >= 0.1f)
            {
                EnqueueBroadcast(new GameMessageSound(Guid, Sound.Wound1, 1.0f));
            }
        }
コード例 #3
0
ファイル: Player_Combat.cs プロジェクト: Plover99/ACE
        /// <summary>
        /// Applies damages to a player from a physical damage source
        /// </summary>
        public void TakeDamage(WorldObject source, DamageType damageType, float _amount, BodyPart bodyPart, bool crit = false)
        {
            if (Invincible ?? false)
            {
                return;
            }

            var amount  = (uint)Math.Round(_amount);
            var percent = (float)amount / Health.MaxValue;

            // update health
            var damageTaken = (uint)-UpdateVitalDelta(Health, (int)-amount);

            DamageHistory.Add(source, damageType, damageTaken);

            if (Health.Current == 0)
            {
                OnDeath(source, damageType, crit);
                Die();
                return;
            }

            // update stamina
            UpdateVitalDelta(Stamina, -1);

            var damageLocation = (DamageLocation)BodyParts.Indices[bodyPart];

            // send network messages
            var creature = source as Creature;
            var hotspot  = source as Hotspot;

            if (creature != null)
            {
                var text = new GameEventDefenderNotification(Session, creature.Name, damageType, percent, amount, damageLocation, crit, AttackConditions.None);
                Session.Network.EnqueueSend(text);

                var hitSound = new GameMessageSound(Guid, GetHitSound(source, bodyPart), 1.0f);
                var splatter = new GameMessageScript(Guid, (PlayScript)Enum.Parse(typeof(PlayScript), "Splatter" + creature.GetSplatterHeight() + creature.GetSplatterDir(this)));
                EnqueueBroadcast(hitSound, splatter);
            }
            else if (hotspot != null)
            {
                if (!string.IsNullOrWhiteSpace(hotspot.ActivationTalkString))
                {
                    Session.Network.EnqueueSend(new GameMessageSystemChat(hotspot.ActivationTalkString.Replace("%i", amount.ToString()), ChatMessageType.Craft));
                }
                if (!hotspot.Visibility)
                {
                    hotspot.EnqueueBroadcast(new GameMessageSound(hotspot.Guid, Sound.TriggerActivated, 1.0f));
                }
            }

            if (percent >= 0.1f)
            {
                EnqueueBroadcast(new GameMessageSound(Guid, Sound.Wound1, 1.0f));
            }
        }
コード例 #4
0
        /// <summary>
        /// Applies some amount of damage to this monster from source
        /// </summary>
        /// <param name="source">The attacker / source of damage</param>
        /// <param name="amount">The amount of damage rounded</param>
        public virtual void TakeDamage(WorldObject source, DamageType damageType, float amount, bool crit = false)
        {
            var tryDamage = (uint)Math.Round(amount);
            var damage    = (uint)-UpdateVitalDelta(Health, (int)-tryDamage);

            // TODO: update monster stamina?

            // source should only be null for combined DoT ticks from multiple sources
            if (source != null)
            {
                DamageHistory.Add(source, damageType, damage);
            }

            if (Health.Current <= 0)
            {
                OnDeath();
                Die();

                // this should only probably go to the last damager
                var lastDamager = DamageHistory.LastDamager as Player;
                if (lastDamager != null)
                {
                    var deathMessage = Strings.GetDeathMessage(damageType, crit);
                    lastDamager.Session.Network.EnqueueSend(new GameMessageSystemChat(string.Format(deathMessage.Killer, Name), ChatMessageType.Broadcast));
                }

                // split xp between players in damage history?
                foreach (var kvp in DamageHistory.TotalDamage)
                {
                    var damager     = kvp.Key;
                    var totalDamage = kvp.Value;

                    var playerDamager = damager as Player;
                    if (playerDamager == null)
                    {
                        continue;
                    }

                    var damagePercent = totalDamage / Health.MaxValue;
                    var totalXP       = (XpOverride ?? 0) * damagePercent;

                    playerDamager.EarnXP((long)Math.Round(totalXP));
                }
            }
        }
コード例 #5
0
        /// <summary>
        /// Applies some amount of damage to this monster from source
        /// </summary>
        /// <param name="source">The attacker / source of damage</param>
        /// <param name="amount">The amount of damage rounded</param>
        public virtual void TakeDamage(WorldObject source, float amount, bool crit = false)
        {
            var tryDamage = (uint)Math.Round(amount);
            var damage    = (uint)-UpdateVitalDelta(Health, (int)-tryDamage);

            DamageHistory.Add(source, damage);

            if (Health.Current <= 0)
            {
                OnDeath();
                Die();

                var player = source as Player;
                if (player != null)
                {
                    var deathMessage = GetDeathMessage(source, crit);
                    player.Session.Network.EnqueueSend(new GameMessageSystemChat(string.Format(deathMessage, Name), ChatMessageType.Broadcast));
                    player.EarnXP((long)XpOverride);
                }
            }
        }
コード例 #6
0
ファイル: Player_Move.cs プロジェクト: nbucciarelli/ACE
        public void TakeDamage_Falling(float amount)
        {
            if (IsDead || Invincible)
            {
                return;
            }

            // handle lifestone protection?
            if (UnderLifestoneProtection)
            {
                HandleLifestoneProtection();
                return;
            }

            // scale by bludgeon protection
            var resistance = EnchantmentManager.GetResistanceMod(DamageType.Bludgeon);
            var damage     = (uint)Math.Round(amount * resistance);

            // update health
            var damageTaken = (uint)-UpdateVitalDelta(Health, (int)-damage);

            DamageHistory.Add(this, DamageType.Bludgeon, damageTaken);

            var msg = Strings.GetFallMessage(damageTaken, Health.MaxValue);

            SendMessage(msg, ChatMessageType.Combat);

            if (Health.Current <= 0)
            {
                OnDeath(new DamageHistoryInfo(this), DamageType.Bludgeon, false);
                Die();
            }
            else
            {
                EnqueueBroadcast(new GameMessageSound(Guid, Sound.Wound3, 1.0f));
            }
        }
コード例 #7
0
ファイル: Creature_Vitals.cs プロジェクト: delizin/ACE
        /// <summary>
        /// Updates a particular vital according to regeneration rate
        /// </summary>
        /// <param name="vital">The vital stat to update (health/stamina/mana)</param>
        /// <returns>TRUE if vital has changed</returns>
        public bool VitalHeartBeat(CreatureVital vital)
        {
            // Current and MaxValue are properties and include overhead in getting their values. We cache them so we only hit the overhead once.
            var vitalCurrent = vital.Current;
            var vitalMax     = vital.MaxValue;

            if (vitalCurrent >= vitalMax && vital.RegenRate > 0)
            {
                return(false);
            }

            if (vitalCurrent > vitalMax)
            {
                UpdateVital(vital, vitalMax);
                return(true);
            }

            if (vital.RegenRate == 0.0)
            {
                return(false);
            }

            // take attributes into consideration (strength, endurance)
            var attributeMod = GetAttributeMod(vital);

            // take stance into consideration (combat, crouch, sitting, sleeping)
            var stanceMod = GetStanceMod(vital);

            // take enchantments into consideration:
            // (regeneration / rejuvenation / mana renewal / etc.)
            var enchantmentMod = EnchantmentManager.GetRegenerationMod(vital);

            var augMod = 1.0f;

            if (this is Player player && player.AugmentationFasterRegen > 0)
            {
                augMod += player.AugmentationFasterRegen;
            }

            // cap rate?
            var currentTick = vital.RegenRate * attributeMod * stanceMod * enchantmentMod * augMod;

            // add in partially accumulated / rounded vitals from previous tick(s)
            var totalTick = currentTick + vital.PartialRegen;

            // accumulate partial vital rates between ticks
            var intTick = (int)totalTick;

            vital.PartialRegen = totalTick - intTick;

            if (intTick != 0)
            {
                //if (this is Player)
                //Console.WriteLine($"VitalTick({vital.Vital.ToSentence()}): attributeMod={attributeMod}, stanceMod={stanceMod}, enchantmentMod={enchantmentMod}, regenRate={vital.RegenRate}, currentTick={currentTick}, totalTick={totalTick}, accumulated={vital.PartialRegen}");

                UpdateVitalDelta(vital, intTick);
                if (vital.Vital == PropertyAttribute2nd.MaxHealth)
                {
                    if (intTick > 0)
                    {
                        DamageHistory.OnHeal((uint)intTick);
                    }
                    else
                    {
                        DamageHistory.Add(this, DamageType.Health, (uint)intTick);

                        if (Health.Current <= 0)
                        {
                            OnDeath(DamageHistory.LastDamager, DamageType.Health);
                            Die();
                        }
                    }

                    return(true);
                }
            }
            return(false);
        }