コード例 #1
0
        public override void Explode(Explosion explosion)
        {
            base.Explode(explosion);

            // Shake camera
            float distToCam = (explosion.Origin - Camera.Active.Position).Length;
            float factor    = 5f / (distToCam * 0.3f); // maxShake / (distToCam * falloff)

            if (factor > 0.15f)                        // factor > minShake
            {
                Player.ShakeCamera(0.5f, factor);
            }

            // Damage player
            PlayerRaycastResult eResult = RaycastPlayer(explosion.Origin, Player, explosion.PlayerRadius);

            if (eResult.Intersects)
            {
                /*
                 *  Curve:
                 *  max(min((fa/max(x,0)) - (fa/d), a), 0)
                 *  where f = falloff rate, a = max damage, d = max distance,
                 *      x = distance
                 */

                //float damage = MathHelper.Clamp(
                //    explosion.Damage / (eResult.IntersectionDistance.Value * explosion.DamageFalloff),
                //    0, explosion.Damage);

                float damage = explosion.Damage * (float)Math.Cos(eResult.IntersectionDistance.Value / ((2 * explosion.PlayerRadius) / Math.PI));

                //float fa = explosion.DamageFalloff * explosion.Damage;
                // float damage = MathHelper.Clamp((fa / eResult.IntersectionDistance.Value) - (fa / 200f), 0, explosion.Damage);

                Player.Damage(damage, "Explosion");
            }
        }
コード例 #2
0
        public override void Explode(Explosion explosion)
        {
            // Destroy terrain
            Vector3 origin = explosion.Origin;
            float   radius = explosion.BlockRadius;

            IndexPosition cpos     = FixedTerrain.WorldToChunkCoords(origin);
            IndexPosition blockPos = Chunk.WorldToBlockCoords(origin);

            blockPos -= cpos * Chunk.SIZE;

            Chunk chunk;

            if (Terrain.Chunks.TryGetValue(cpos, out chunk))
            {
                int blockRadius = (int)(radius / Block.CUBE_SIZE);
                for (int x = -blockRadius; x <= blockRadius; x++)
                {
                    for (int y = -blockRadius; y <= blockRadius; y++)
                    {
                        for (int z = -blockRadius; z <= blockRadius; z++)
                        {
                            int nx = x + blockPos.X;
                            int ny = y + blockPos.Y;
                            int nz = z + blockPos.Z;

                            IndexPosition ncpos = chunk.WrapBlockCoords(ref nx, ref ny, ref nz);

                            if (!chunk.IsBlockCoordInRange(nx, ny, nz))
                            {
                                continue;
                            }

                            Vector3 apos = Chunk.ChunkBlockToWorldCoords(ncpos, new IndexPosition(nx, ny, nz))
                                           - Block.HALF_CUBE_3D_SIZE;

                            float dist = Maths.Distance(apos, origin);
                            if (dist > radius)
                            {
                                continue;
                            }

                            int damage = (int)(14 * (1f - (dist / radius)));

                            if (ncpos != cpos)
                            {
                                Chunk otherChunk;
                                if (Terrain.Chunks.TryGetValue(ncpos, out otherChunk))
                                {
                                    otherChunk.DamageBlock(new IndexPosition(nx, ny, nz), damage);
                                }
                            }
                            else
                            {
                                chunk.DamageBlock(new IndexPosition(nx, ny, nz), damage);
                            }
                        }
                    }
                }
            }

            // Apply grenade damage
            bool ff = DashCMD.GetCVar <bool>("mp_friendlyfire");

            if (!DashCMD.GetCVar <bool>("ch_infhealth"))
            {
                foreach (ServerMPPlayer player in players.Values)
                {
                    if (player.Health <= 0 || !ff && explosion.Owner.Team == player.Team && explosion.Owner != player)
                    {
                        continue;
                    }

                    PlayerRaycastResult eResult = RaycastPlayer(explosion.Origin, player, explosion.PlayerRadius);
                    if (eResult.Intersects)
                    {
                        /*
                         *  Curve:
                         *  max(min((fa/max(x,0)) - (fa/d), a), 0)
                         *  where f = falloff rate, a = max damage, d = max distance,
                         *      x = distance
                         */

                        //float damage = MathHelper.Clamp(
                        //    explosion.Damage / (eResult.IntersectionDistance.Value * explosion.DamageFalloff),
                        //    0, explosion.Damage);

                        float damage = explosion.Damage * (float)Math.Cos(eResult.IntersectionDistance.Value / ((2 * explosion.PlayerRadius) / Math.PI));

                        //float fa = explosion.DamageFalloff * explosion.Damage;
                        // float damage = MathHelper.Clamp((fa / eResult.IntersectionDistance.Value) - (fa / 200f), 0, explosion.Damage);

                        DamagePlayer((ServerMPPlayer)explosion.Owner, explosion.EntityName, player, damage, origin);
                    }
                }
            }

            // Fling other grenades
            radius = explosion.PlayerRadius;

            for (int i = 0; i < grenades.Count; i++)
            {
                GrenadeEntity grenade = grenades[i];

                Vector3 dirTo = grenade.Transform.Position - origin;
                float   dist  = dirTo.Length;
                if (dist > radius)
                {
                    continue;
                }

                dirTo += new Vector3(0, 1, 0);
                dirTo  = dirTo.Normalize();

                float kickBack = 60 * (1f - (dist / radius));
                grenade.PhysicsBody.Velocity += dirTo * kickBack;
                grenade.Transform.Position.Y += 0.01f;
            }
        }
コード例 #3
0
        public override void FireBullet(Player _player, Vector3 origin, Vector3 dir, Vector3 recoil,
                                        int blockDamage, float playerDamage, float maxDist = float.MaxValue)
        {
            ServerMPPlayer player = (ServerMPPlayer)_player;

            bool sv_impacts  = DashCMD.GetCVar <bool>("sv_impacts");
            bool sv_hitboxes = DashCMD.GetCVar <bool>("sv_hitboxes");

            int shooterPing    = player.StateInfo.Owner.Stats.Ping;
            int rollbackOffset = DashCMD.GetCVar <int>("rp_rollback_offset");
            int bulletDelta    = player.LastBulletDeltaTime;

            if (sv_hitboxes)
            {
                DashCMD.WriteLine("[RB] Starting bullet {0}ms delta with {1}ms offset",
                                  ConsoleColor.Green, bulletDelta, rollbackOffset);
            }

            // Raycast
            BeginRollback(shooterPing + bulletDelta + rollbackOffset);
            Ray ray = new Ray(origin, dir + recoil);
            WorldRaycastResult result = Raycast(ray, true, maxDist, player);

            EndRollback();

            // Handle intersection
            if (result.Intersects)
            {
                if (result.HitTerrain)
                {
                    // Damage terrain
                    TerrainRaycastResult tResult = result.TerrainResult;

                    if (blockDamage > 0)
                    {
                        tResult.Chunk.DamageBlock(tResult.BlockIndex.Value, blockDamage);
                    }
                }
                else if (result.HitPlayer)
                {
                    // Damage player
                    PlayerRaycastResult pResult = result.PlayerResult;

                    bool ff   = DashCMD.GetCVar <bool>("mp_friendlyfire");
                    bool infh = DashCMD.GetCVar <bool>("ch_infhealth");

                    if (!infh && (ff || player.Team != pResult.Player.Team))
                    {
                        DamagePlayer(player, player.ItemManager.SelectedItem.GetType().Name, (ServerMPPlayer)pResult.Player,
                                     playerDamage, origin);

                        if (sv_impacts)
                        {
                            DashCMD.WriteLine("[IMP] Hit player for {0} damage. Health After: {1}", playerDamage, pResult.Player.Health);
                        }
                    }
                }

                ImpactAt(result.IntersectionPosition.Value);
            }
        }