Пример #1
0
        /// <summary>
        /// Applies an amount of damage to this player, updating their client and the server version of their health
        /// </summary>
        /// <param name="killer"></param>
        /// <param name="victim"></param>
        /// <param name="killersWeapon"></param>
        /// <param name="dir"></param>
        /// <param name="damage"></param>
        /// <param name="realDamage"></param>
        public void ApplyPlayerDamage(PlayerKiller killer, Item killersWeapon, int dir, int damage, int realDamage)
        {
            // Send the damage using the special method to avoid invincibility frames issue
            Controller.DataSender.SendPlayerDamage(TshockPlayer, dir, damage);
            Controller.RaisePlayerDamageEvent(this, new PlayerDamageEventArgs(killer.Player, TshockPlayer, killersWeapon, realDamage));
            TPlayer.statLife -= realDamage;

            // Hurt the player to prevent instant regen activating
            var savedHealth = TPlayer.statLife;

            TPlayer.Hurt(new PlayerDeathReason(), damage, 0, true, false, false, 3);
            TPlayer.statLife = savedHealth;

            if (TPlayer.statLife <= 0)
            {
                TshockPlayer.Dead = true;
                IsDead            = true;
                Controller.DataSender.SendPlayerDeath(TshockPlayer);

                if (TPlayer.hostile && killer != null)
                {
                    PlayerKillEventArgs killArgs = new PlayerKillEventArgs(killer.Player, TshockPlayer, killer.Weapon);
                    Controller.RaisePlayerKillEvent(this, killArgs);
                }
                return;
            }

            Controller.DataSender.SendClientHealth(this, TPlayer.statLife);
        }
Пример #2
0
        /// <summary>
        /// Determines whether to block damage if they have recently used a banned item or modifies damage
        /// if the projectile is on the modifications list.
        /// </summary>
        /// <param name="args">The GetDataHandlerArgs object containing the player who sent the packet and the
        /// data in it</param>
        /// <returns>Whether or not the packet was handled (and should therefore not be processed
        /// by anything else</returns>
        private bool HandleDamage(GetDataHandlerArgs args)
        {
            if (args.Player == null)
            {
                return(false);
            }
            var index             = args.Player.Index;
            var playerId          = (byte)args.Data.ReadByte();
            var damageSourceFlags = (BitsByte)args.Data.ReadByte();

            var sourceItemType       = -1;
            var sourceProjectileType = -1;
            var sourceItemPrefix     = -1;

            if (damageSourceFlags[0])
            {
                var sourcePlayerIndex = args.Data.ReadInt16();
            }
            if (damageSourceFlags[1])
            {
                var sourceNPCIndex = args.Data.ReadInt16();
            }
            if (damageSourceFlags[2])
            {
                var sourceProjectileIndex = args.Data.ReadInt16();
            }
            if (damageSourceFlags[3])
            {
                var sourceOtherIndex = args.Data.ReadByte();
            }
            if (damageSourceFlags[4])
            {
                sourceProjectileType = args.Data.ReadInt16();
            }
            if (damageSourceFlags[5])
            {
                sourceItemType = args.Data.ReadInt16();
            }
            if (damageSourceFlags[6])
            {
                sourceItemPrefix = args.Data.ReadByte();
            }

            var damage = args.Data.ReadInt16();
            var dir    = args.Data.ReadByte();
            var flags  = args.Data.ReadByte();

            args.Data.ReadByte();

            if (TShock.Players[playerId] == null || sourceItemType == -1 || args.Player.IsDead || Controller.Players[playerId].IsDead)
            {
                return(true);
            }

            // The sourceItemType is only reliable if no projectile is involved
            // as sourceItemType is simply the active slot item
            // TODO: Change this to use active slot item of server
            Item weapon = new Item();

            if (sourceProjectileType == -1)
            {
                weapon.SetDefaults(sourceItemType);
                weapon.Prefix(sourceItemPrefix);
                weapon.owner = args.Player.Index;
            }
            else if (args.Player.ProjectileWeapon[sourceProjectileType] != null)
            {
                Item bestWeaponGuess = args.Player.ProjectileWeapon[sourceProjectileType];
                weapon.SetDefaults(bestWeaponGuess.netID);
                weapon.Prefix(bestWeaponGuess.prefix);
                weapon.owner = args.Player.Index;
            }

            double internalDamage = Main.player[args.Player.Index].GetWeaponDamage(weapon);

            // Check whether the source of damage is banned
            if (Controller.Weapons.Count(p => p.netID == weapon.netID && p.banned) > 0 || Controller.Projectiles.Count(p => p.netID == sourceProjectileType && p.banned) > 0)
            {
                args.Player.TshockPlayer.SendData(PacketTypes.PlayerHp, "", playerId);
                return(true);
            }

            internalDamage = DamageController.DecideDamage(args.Player, Controller.Players[playerId], weapon, sourceProjectileType, internalDamage);

            // Send Damage and Damage Text
            int   realDamage = (int)Math.Round(DamageUtils.GetRealDamageFromInternalDamage(Main.player[playerId], internalDamage));
            Color msgColor   = new Color(162, 0, 255);

            NetMessage.SendData(119, index, -1, NetworkText.FromLiteral($"{realDamage}"), (int)msgColor.PackedValue, Main.player[playerId].position.X, Main.player[playerId].position.Y - 32);
            var killer = new PlayerKiller(args.Player.TshockPlayer, weapon);

            Controller.Players[playerId].ApplyPlayerDamage(killer, weapon, dir, (int)internalDamage, realDamage);
            NetMessage.SendData((int)PacketTypes.PlayerHp, -1, playerId, NetworkText.Empty, playerId);

            // Update spectating time so they cannot simply hide from their attacker
            if (Controller.Players[playerId].LastSpectating < DateTime.UtcNow.AddSeconds(-15))
            {
                Controller.Players[playerId].LastSpectating = DateTime.UtcNow.AddSeconds(-15);
            }
            return(true);
        }