public override void Update(float deltaTime)
        {
            if (downloading)
            {
                if (bytesTotal > 0)
                {
                    barAnim.Step(deltaTime * 10);
                    byteAnim.Step(deltaTime * 10);

                    bar.Size.X.Scale = barAnim.Value;
                    statusLabel.Text = string.Format("{0}/{1} bytes", (int)byteAnim.Value, bytesTotal);
                }
            }
            else if (terrain != null)
            {
                barAnim.SetTarget((float)(chunksTotal - terrain.UnfinishedChunks) / chunksTotal);
                barAnim.Step(deltaTime * 10);

                bar.Size.X.Scale = barAnim.Value;
                statusLabel.Text = string.Format("{0}/{1} chunks loaded", chunksTotal - terrain.UnfinishedChunks, chunksTotal);

                if (terrain.UnfinishedChunks == 0)
                {
                    terrain = null;
                    Visible = false;
                }
            }

            base.Update(deltaTime);
        }
        public void SetTerrain(FixedTerrain terrain)
        {
            UnloadTerrain();
            Terrain             = terrain;
            terrainPhys.Terrain = terrain;

            gameObjects.Clear();
        }
 public void SwitchToTerrainLoading(FixedTerrain terrain)
 {
     downloading      = false;
     Title            = "Loading terrain...";
     bar.Size.X.Scale = 0;
     this.terrain     = terrain;
     chunksTotal      = terrain.Width * terrain.Height * terrain.Depth;
 }
        public void Save(Stream stream, WorldDescription desc)
        {
            FixedTerrain terrain = desc.Terrain;

            using (BinaryWriter writer = new BinaryWriter(stream))
            {
                writer.Write(1.0f);
                writer.Write(terrain.Chunks.Count);

                foreach (Chunk chunk in terrain.Chunks.Values)
                {
                    writer.Write((ushort)chunk.IndexPosition.X);
                    writer.Write((ushort)chunk.IndexPosition.Y);
                    writer.Write((ushort)chunk.IndexPosition.Z);
                    writer.Write(false);
                    //if (!chunk.IsEmpty)
                    {
                        ushort skip = 0;

                        for (int x = 0; x < Chunk.HSIZE; x++)
                        {
                            for (int y = 0; y < Chunk.VSIZE; y++)
                            {
                                for (int z = 0; z < Chunk.HSIZE; z++)
                                {
                                    Block block = chunk.Blocks[z, y, x];
                                    //if (block != Block.AIR)
                                    {
                                        if (skip > 0)
                                        {
                                            writer.Write(true);
                                            writer.Write(skip);
                                            skip = 0;
                                        }

                                        writer.Write(block == Block.AIR);
                                        writer.Write(block.R);
                                        writer.Write(block.G);
                                        writer.Write(block.B);
                                        writer.Write(block.Data.Value);
                                    }
                                    //else
                                    //    skip++;
                                }
                            }
                        }

                        if (skip > 0)
                        {
                            writer.Write(true);
                            writer.Write(skip);
                            skip = 0;
                        }
                    }
                }
            }
        }
 public void UnloadTerrain()
 {
     if (Terrain != null)
     {
         Terrain.Dispose();
         Terrain             = null;
         terrainPhys.Terrain = null;
         GC.Collect(1, GCCollectionMode.Forced, true, true);
         GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
         GC.Collect();
     }
 }
        public void LoadNewFlatWorld(int x, int y, int z)
        {
            World.UnloadTerrain();
            FixedTerrain terrain = new FixedTerrain(renderer);

            terrain.GenerateFlat(x, y, z);
            World.SetTerrain(terrain);
            WorldEditor.TerrainEditor.ClearUndoRedo();

            Window.UpdateTitle(null);
            CurrentFile = null;
        }
        public void Save(Stream stream, WorldDescription desc)
        {
            FixedTerrain terrain = desc.Terrain;

            using (GZipStream gz = new GZipStream(stream, CompressionMode.Compress))
                using (BinaryWriter writer = new BinaryWriter(gz))
                {
                    writer.Write(2.0f);

                    writer.Write((ushort)terrain.Chunks.Count);
                    foreach (Chunk chunk in terrain.Chunks.Values)
                    {
                        writer.Write((byte)0);
                        writer.Write((short)chunk.IndexPosition.X);
                        writer.Write((short)chunk.IndexPosition.Y);
                        writer.Write((short)chunk.IndexPosition.Z);

                        Block?lastBlock = null;
                        int   numRead   = 0;

                        for (int x = 0; x < chunk.Width; x++)
                        {
                            for (int y = 0; y < chunk.Height; y++)
                            {
                                for (int z = 0; z < chunk.Depth; z++)
                                {
                                    Block block      = chunk.Blocks[z, y, x];
                                    bool  blocksDiff = lastBlock.HasValue ? BlocksDifferent(block, lastBlock.Value) : false;

                                    if (blocksDiff)
                                    {
                                        Block b = lastBlock ?? block;
                                        WriteBlocks(writer, b, numRead);
                                        numRead = 0;
                                    }

                                    numRead++;
                                    lastBlock = block;
                                }
                            }
                        }

                        if (numRead > 0)
                        {
                            WriteBlocks(writer, lastBlock.Value, numRead);
                        }
                    }
                }
        }
Example #8
0
        public void Update(float deltaTime)
        {
            FixedTerrain terrain = screen.World.Terrain;

            if (terrain != null)
            {
                statusLeft.Text = string.Format("Dimensions: {0}x{1}x{2}",
                                                terrain.Width, terrain.Height, terrain.Depth);
            }
            else
            {
                statusLeft.Text = "";
            }

            statusRight.Text = string.Format("{0}fps", (int)Math.Round(screen.Window.FPS));
        }
Example #9
0
 public WorldDescription(FixedTerrain terrain, IEnumerable <WorldObjectDescription> objects)
 {
     Terrain = terrain;
     Objects = objects.ToLookup(o => o.Tag);
 }
Example #10
0
 public WorldDescription(FixedTerrain terrain)
 {
     Terrain = terrain;
     Objects = new List <WorldObjectDescription>().ToLookup(o => o.Tag);
 }
Example #11
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);
                            }
                        }
                    }
                }
            }

            // 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;
            }
        }
        public WorldDescription Load(Stream stream)
        {
            FixedTerrain terrain = new FixedTerrain(MasterRenderer.Instance);

            using (BinaryReader reader = new BinaryReader(stream))
            {
                ushort numChunks    = reader.ReadUInt16();
                Chunk  currentChunk = null;
                int    blockI       = 0;
                int    ci           = 0;

                while (ci <= numChunks && reader.BaseStream.Position < reader.BaseStream.Length)
                {
                    byte type = reader.ReadByte();

                    if (type == 0) // New Chunk
                    {
                        int ix = reader.ReadInt16();
                        int iy = reader.ReadInt16();
                        int iz = reader.ReadInt16();

                        IndexPosition ipos = new IndexPosition(ix, iy, iz);
                        currentChunk = new Chunk(terrain, ipos, AceOfSpades.Terrain.ChunkToWorldCoords(ipos));
                        currentChunk.InitBlocks(Chunk.HSIZE, Chunk.VSIZE, Chunk.HSIZE);
                        currentChunk.State   = ChunkState.Unlit;
                        currentChunk.IsDirty = true;
                        terrain.Chunks.TryAdd(ipos, currentChunk);

                        blockI = 0;
                        ci++;
                    }
                    else if (type == 1) // Block section
                    {
                        ushort  numBlocks = reader.ReadUInt16();
                        byte    d = reader.ReadByte();
                        Nybble2 n = new Nybble2(d);
                        byte    mat = n.Lower;
                        byte    r = 255, g = 255, b = 255;
                        if (mat != Block.AIR.Material)
                        {
                            r = reader.ReadByte();
                            g = reader.ReadByte();
                            b = reader.ReadByte();
                        }

                        Block block = new Block(n, r, g, b);

                        for (int i = 0; i < numBlocks; i++)
                        {
                            int z = blockI % Chunk.HSIZE;
                            int y = (blockI / Chunk.HSIZE) % Chunk.VSIZE;
                            int x = blockI / (Chunk.VSIZE * Chunk.HSIZE);

                            currentChunk.Blocks[z, y, x] = block;
                            blockI++;
                        }
                    }
                }

                if (currentChunk != null)
                {
                    currentChunk.BakeColors();
                }
            }

            return(new WorldDescription(terrain));
        }
 protected void GetLocalBlockCoords(IndexPosition global, out IndexPosition chunkPos, out IndexPosition blockPos)
 {
     FixedTerrain.GetLocalBlockCoords(global, out chunkPos, out blockPos);
 }
 protected IndexPosition GetGlobalBlockCoords(IndexPosition chunkPos, IndexPosition blockPos)
 {
     return(FixedTerrain.GetGlobalBlockCoords(chunkPos, blockPos));
 }
Example #15
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;
            }
        }