Exemplo n.º 1
0
        public void HandlePKDeathBroadcast(DamageHistoryInfo lastDamager, DamageHistoryInfo topDamager)
        {
            if (topDamager == null || !topDamager.IsPlayer)
            {
                return;
            }

            var pkPlayer = topDamager.TryGetAttacker() as Player;

            if (pkPlayer == null)
            {
                return;
            }

            if (IsPKDeath(topDamager))
            {
                pkPlayer.PkTimestamp = Time.GetUnixTime();
                pkPlayer.PlayerKillsPk++;

                var globalPKDe = $"{lastDamager.Name} has defeated {Name}!";

                if ((Location.Cell & 0xFFFF) < 0x100)
                {
                    globalPKDe += $" The kill occured at {Location.GetMapCoordStr()}";
                }

                globalPKDe += "\n[PKDe]";

                PlayerManager.BroadcastToAll(new GameMessageSystemChat(globalPKDe, ChatMessageType.Broadcast));
            }
            else if (IsPKLiteDeath(topDamager))
            {
                pkPlayer.PlayerKillsPkl++;
            }
        }
Exemplo n.º 2
0
        public void HandlePKDeathBroadcast(DamageHistoryInfo lastDamager, DamageHistoryInfo topDamager)
        {
            if (topDamager == null || !topDamager.IsPlayer)
            {
                return;
            }

            var pkPlayer = topDamager.TryGetAttacker() as Player;

            if (pkPlayer == null)
            {
                return;
            }

            if (IsPKDeath(topDamager))
            {
                pkPlayer.PkTimestamp = Time.GetUnixTime();
                pkPlayer.PlayerKillsPk++;

                string globalPKDe;
                if (pkPlayer.CurrentLandblock.RealmHelpers.IsDuel)
                {
                    globalPKDe = $"{lastDamager.Name} has defeated {Name} in a duel!";
                }
                else
                {
                    globalPKDe = $"{lastDamager.Name} has defeated {Name}!";
                    if (!Location.Indoors)
                    {
                        globalPKDe += $" The kill occured at {Location.GetMapCoordStr()}";
                    }
                }

                globalPKDe += "\n[PKDe]";

                PlayerManager.BroadcastToAll(new GameMessageSystemChat(globalPKDe, ChatMessageType.Broadcast));
            }
            else if (IsPKLiteDeath(topDamager))
            {
                pkPlayer.PlayerKillsPkl++;
            }
        }
Exemplo n.º 3
0
        public static void SendDeathDetailsViaHTTP(DamageHistoryInfo topDamager, DamageHistoryInfo killshot, WorldObject victim)
        {
            log.Info($"KILLSHOT. killer:{topDamager.Guid.Full}, victim:{victim.Guid.Full}, finisher:{killshot.Guid.Full}");
            var web_portal_api_killshot_on = PropertyManager.GetBool("web_portal_api_killshot_on").Item;

            if (web_portal_api_killshot_on)
            {
                var web_portal_url         = PropertyManager.GetString("web_portal_url").Item;
                var web_portal_api_version = PropertyManager.GetString("web_portal_api_version").Item;
                var web_portal_api_jwt     = PropertyManager.GetString("web_portal_api_jwt").Item;
                if (!string.IsNullOrEmpty(web_portal_url) || !string.IsNullOrEmpty(web_portal_api_version) || !string.IsNullOrEmpty(web_portal_api_jwt))
                {
                    var client = new RestClient(web_portal_url);
                    // client.Authenticator = new HttpBasicAuthenticator(username, password);

                    var request = new RestRequest("killshot" + web_portal_api_version + "/deaths", Method.POST);
                    request.AddHeader("Content-type", "application/json");
                    request.AddHeader("Authorization", web_portal_api_jwt);
                    request.AddJsonBody(new
                    {
                        killer   = topDamager.Guid.Full,
                        victim   = victim.Guid.Full,
                        finisher = killshot.Guid.Full,
                    });

                    // easy async support
                    client.ExecuteAsync(request, response => {
                        // Nothing here
                        var x = 1;
                    });
                }
                else
                {
                    log.Info("ERROR: Riptide API Web Portal not initialized");
                }
            }
        }
Exemplo n.º 4
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, false, 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.GetLandblock(new LandblockId(Sanctuary.Landblock << 16 | 0xFFFF), true);
                lifestoneBlock.EnqueueBroadcast(excludePlayers, true, Sanctuary, LocalBroadcastRangeSq, broadcastMsg);
            }

            return(deathMessage);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Broadcasts the player death animation, updates vitae, and sends network messages for player death
        /// Queues the action to call TeleportOnDeath and enter portal space soon
        /// </summary>
        protected override void Die(DamageHistoryInfo lastDamager, DamageHistoryInfo topDamager)
        {
            if (topDamager?.Guid == Guid && IsPKType)
            {
                var topDamagerOther = DamageHistory.GetTopDamager(false);

                if (topDamagerOther != null && topDamagerOther.IsPlayer)
                {
                    topDamager = topDamagerOther;
                }
            }

            UpdateVital(Health, 0);
            NumDeaths++;
            suicideInProgress = false;

            if (CombatMode == CombatMode.Magic && MagicState.IsCasting)
            {
                FailCast(false);
            }

            // TODO: instead of setting IsBusy here,
            // eventually all of the places that check for states such as IsBusy || Teleporting
            // might want to use a common function, and IsDead should return a separate error
            IsBusy = true;

            // killer = top damager for looting rights
            if (topDamager != null)
            {
                KillerId = topDamager.Guid.Full;
            }

            // broadcast death animation
            var deathAnim = new Motion(MotionStance.NonCombat, MotionCommand.Dead);

            EnqueueBroadcastMotion(deathAnim);

            // create network messages for player death
            var msgHealthUpdate = new GameMessagePrivateUpdateAttribute2ndLevel(this, Vital.Health, 0);

            // TODO: death sounds? seems to play automatically in client
            // var msgDeathSound = new GameMessageSound(Guid, Sound.Death1, 1.0f);
            var msgNumDeaths = new GameMessagePrivateUpdatePropertyInt(this, PropertyInt.NumDeaths, NumDeaths);

            // send network messages for player death
            Session.Network.EnqueueSend(msgHealthUpdate, msgNumDeaths);

            if (lastDamager?.Guid == Guid) // suicide
            {
                var msgSelfInflictedDeath = new GameEventWeenieError(Session, WeenieError.YouKilledYourself);
                Session.Network.EnqueueSend(msgSelfInflictedDeath);
            }

            // update vitae
            // players who died in a PKLite fight do not accrue vitae
            if (!IsPKLiteDeath(topDamager))
            {
                InflictVitaePenalty();
            }

            if (IsPKDeath(topDamager) || AugmentationSpellsRemainPastDeath == 0)
            {
                var msgPurgeEnchantments = new GameEventMagicPurgeEnchantments(Session);
                EnchantmentManager.RemoveAllEnchantments();
                Session.Network.EnqueueSend(msgPurgeEnchantments);
            }

            // wait for the death animation to finish
            var dieChain   = new ActionChain();
            var animLength = DatManager.PortalDat.ReadFromDat <MotionTable>(MotionTableId).GetAnimationLength(MotionCommand.Dead);

            dieChain.AddDelaySeconds(animLength + 1.0f);

            dieChain.AddAction(this, () =>
            {
                CreateCorpse(topDamager);

                ThreadSafeTeleportOnDeath(); // enter portal space

                if (IsPKDeath(topDamager) || IsPKLiteDeath(topDamager))
                {
                    SetMinimumTimeSincePK();
                }

                IsBusy = false;
            });

            dieChain.EnqueueChain();
        }