예제 #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(DamageHistoryInfo lastDamager, DamageType damageType, bool criticalHit = false)
        {
            var topDamager = DamageHistory.GetTopDamager(false);

            HandlePKDeathBroadcast(lastDamager, topDamager);

            var deathMessage = base.OnDeath(lastDamager, damageType, criticalHit);

            var lastDamagerObj = lastDamager?.TryGetAttacker();

            if (lastDamagerObj != null)
            {
                lastDamagerObj.EmoteManager.OnKill(this);
            }

            var playerMsg = "";

            if (lastDamager != null)
            {
                playerMsg = string.Format(deathMessage.Victim, Name, lastDamager.Name);
            }
            else
            {
                playerMsg = deathMessage.Victim;
            }

            var msgYourDeath = new GameEventVictimNotification(Session, playerMsg);

            Session.Network.EnqueueSend(msgYourDeath);

            // broadcast to nearby players
            var nearbyMsg = "";

            if (lastDamager != null)
            {
                nearbyMsg = string.Format(deathMessage.Broadcast, Name, lastDamager.Name);
            }
            else
            {
                nearbyMsg = deathMessage.Broadcast;
            }

            var broadcastMsg = new GameMessagePlayerKilled(nearbyMsg, Guid, lastDamager?.Guid ?? ObjectGuid.Invalid);

            log.Debug("[CORPSE] " + nearbyMsg);

            var excludePlayers = new List <Player>();

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

            excludePlayers.AddRange(nearbyPlayers);

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

            // if the player's lifestone is in a different landblock, also broadcast their demise to that landblock
            if (PropertyManager.GetBool("lifestone_broadcast_death").Item&& 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.GetLandblockBase(Sanctuary.ObjCellID, true);
                lifestoneBlock.EnqueueBroadcast(excludePlayers, true, Sanctuary, LocalBroadcastRangeSq, broadcastMsg);
            }

            return(deathMessage);
        }