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); } } } }
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)); }
public WorldDescription(FixedTerrain terrain, IEnumerable <WorldObjectDescription> objects) { Terrain = terrain; Objects = objects.ToLookup(o => o.Tag); }
public WorldDescription(FixedTerrain terrain) { Terrain = terrain; Objects = new List <WorldObjectDescription>().ToLookup(o => o.Tag); }
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)); }
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; } }