Exemple #1
0
        /// <summary>
        /// Called when a player dies, in conjunction with Die()
        /// </summary>
        /// <param name="lastDamager">The last damager that landed the death blow</param>
        /// <param name="damageType">The damage type for the death message</param>
        public override DeathMessage OnDeath(WorldObject lastDamager, DamageType damageType, bool criticalHit = false)
        {
            var deathMessage = base.OnDeath(lastDamager, damageType, criticalHit);

            lastDamager.EmoteManager.OnKill(this);

            var playerMsg    = string.Format(deathMessage.Victim, Name, lastDamager.Name);
            var msgYourDeath = new GameEventYourDeath(Session, playerMsg);

            Session.Network.EnqueueSend(msgYourDeath);

            // broadcast to nearby players
            var nearbyMsg    = string.Format(deathMessage.Broadcast, Name, lastDamager.Name);
            var broadcastMsg = new GameMessageSystemChat(nearbyMsg, ChatMessageType.Broadcast);

            var excludePlayers = new List <Player>();

            if (lastDamager is Player lastDamagerPlayer)
            {
                excludePlayers.Add(lastDamagerPlayer);
            }

            var nearbyPlayers = EnqueueBroadcast(excludePlayers, false, broadcastMsg);

            excludePlayers.AddRange(nearbyPlayers);
            excludePlayers.Add(this);   // exclude self

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

            // if the player's lifestone is in a different landblock, also broadcast their demise to that landblock
            if (Sanctuary != null && Location.Landblock != Sanctuary.Landblock)
            {
                // ActionBroadcastKill might not work if other players around lifestone aren't aware of this player yet...
                // this existing broadcast method is also based on the current visible objects to the player,
                // and the player hasn't entered portal space or teleported back to the lifestone yet, so this doesn't work
                //ActionBroadcastKill(nearbyMsg, Guid, lastDamager.Guid);

                // instead, we get all of the players in the lifestone landblock + adjacent landblocks,
                // and possibly limit that to some radius around the landblock?
                var lifestoneBlock = LandblockManager.GetLandblock(new LandblockId(Sanctuary.Landblock << 16 | 0xFFFF), true);
                lifestoneBlock.EnqueueBroadcast(excludePlayers, true, broadcastMsg);
            }

            return(deathMessage);
        }
Exemple #2
0
        /// <summary>
        /// Player Death/Kill, use this to kill a session's player
        /// </summary>
        /// <remarks>
        ///     TODO:
        ///         1. Find the best vitae formula and add vitae
        ///         2. Generate the correct death message, or have it passed in as a parameter.
        ///         3. Find the correct player death noise based on the player model and play on death.
        ///         4. Determine if we need to Send Queued Action for Lifestone Materialize, after Action Location.
        ///         5. Find the health after death formula and Set the correct health
        /// </remarks>
        private void OnKill(Session killerSession)
        {
            ObjectGuid killerId = killerSession.Player.Guid;

            IsAlive        = false;
            Health.Current = 0;  // Set the health to zero
            NumDeaths++;         // Increase the NumDeaths counter
            DeathLevel  = Level; // For calculating vitae XP
            VitaeCpPool = 0;     // Set vitae XP

            // TODO: Generate a death message based on the damage type to pass in to each death message:
            string currentDeathMessage = $"died to {killerSession.Player.Name}.";

            // Send Vicitim Notification, or "Your Death" event to the client:
            // create and send the client death event, GameEventYourDeath
            var msgYourDeath         = new GameEventYourDeath(Session, $"You have {currentDeathMessage}");
            var msgNumDeaths         = new GameMessagePrivateUpdatePropertyInt(this, PropertyInt.NumDeaths, NumDeaths ?? 0);
            var msgDeathLevel        = new GameMessagePrivateUpdatePropertyInt(this, PropertyInt.DeathLevel, DeathLevel ?? 0);
            var msgVitaeCpPool       = new GameMessagePrivateUpdatePropertyInt(this, PropertyInt.VitaeCpPool, VitaeCpPool.Value);
            var msgPurgeEnchantments = new GameEventPurgeAllEnchantments(Session);
            // var msgDeathSound = new GameMessageSound(Guid, Sound.Death1, 1.0f);

            // handle vitae
            var vitae = EnchantmentManager.UpdateVitae();

            var spellID             = (uint)Network.Enum.Spell.Vitae;
            var spellBase           = DatManager.PortalDat.SpellTable.Spells[spellID];
            var spell               = DatabaseManager.World.GetCachedSpell(spellID);
            var vitaeEnchantment    = new Enchantment(this, spellID, (double)spell.Duration, 0, spell.StatModType, vitae);
            var msgVitaeEnchantment = new GameEventMagicUpdateEnchantment(Session, vitaeEnchantment);

            var msgHealthUpdate = new GameMessagePrivateUpdateAttribute2ndLevel(this, Vital.Health, 0);

            // Send first death message group
            Session.Network.EnqueueSend(msgHealthUpdate, msgYourDeath, msgNumDeaths, msgDeathLevel, msgVitaeCpPool, msgPurgeEnchantments, msgVitaeEnchantment);

            // Broadcast the 019E: Player Killed GameMessage
            ActionBroadcastKill($"{Name} has {currentDeathMessage}", Guid, killerId);
        }