void SpawnPickupsFromBlock(World3 bashBlock, Color color) { // Spawn a cube of pickups to replace the block for (int x = 1; x < 4; x += 2) { for (int y = 1; y < 4; y += 2) { for (int z = 1; z < 4; z += 2) { if (UnityEngine.Random.value > Config.BlockSpawnChance) { continue; } PooledObject obj = World.Spawn.Object ( Spawns.Pickup, color, new Vector3(bashBlock.x + 0.25f * x, bashBlock.y + 0.25f * y, bashBlock.z + 0.25f * z), 0f ); if (obj != null) { blockSpawns.Add(obj); } } } } }
IEnumerator AwaitBuildComplete() { while (true) { yield return(null); bool complete = true; for (int i = currentBuilds.Count - 1; i >= 0; i--) { World3 pos = currentBuilds[i]; Chunk chunk = World.GetChunk(pos); if (chunk == null) { currentBuilds.RemoveAt(i); } else if (!chunk.built) { complete = false; break; } } if (complete) { building = false; break; } } }
int[,,] getSubset(int[,,] fullData, Region fullRegion, Region subRegion) { if (subRegion.sizeX != fullRegion.sizeX || subRegion.sizeY != fullRegion.sizeY || subRegion.sizeZ != fullRegion.sizeZ) { int[,,] subset = new int[subRegion.sizeX, subRegion.sizeY, subRegion.sizeZ]; World3 offset = new World3( subRegion.min.x - fullRegion.min.x, subRegion.min.y - fullRegion.min.y, subRegion.min.z - fullRegion.min.z ); for (int z = 0; z < subRegion.sizeZ; ++z) { for (int y = 0; y < subRegion.sizeY; ++y) { Array.Copy(fullData, offset.x + fullRegion.sizeX * (y + offset.y + fullRegion.sizeY * (z + offset.z)), subset, subRegion.sizeX * (y + subRegion.sizeY * z), subRegion.sizeX); } } return(subset); } return(fullData); }
public static void UpdatePosition(World3 pos) { if (!Active) { return; } if (ShowStats) { _instance.chunkText.text = "X: " + pos.x.ToString() + ", Y: " + pos.y.ToString() + ", Z: " + pos.z.ToString(); } // Track position for respawning Column column = World.GetColumn(pos); if (column != null) { SampleSet results; InterpolatedNoise.Results.TryGetValue(column.region, out results); if (results != null) { LastGoodPosition = new Vector3 ( pos.x + Chunk.HalfSize + 0.5f, results.spawnMap.height[Chunk.HalfSize, Chunk.HalfSize], pos.z + Chunk.HalfSize + 0.5f ); } } }
public Region(World3 min, World3 max) { this.min = min; this.max = max; this.sizeX = max.x - min.x + 1; this.sizeY = max.y - min.y + 1; this.sizeZ = max.z - min.z + 1; }
public static Chunk GetChunk(World3 pos) { Chunk chunk = null; Chunks.TryGetValue(pos.GetHashCode(), out chunk); return(chunk); }
public static void DestroyChunkAt(World3 pos) { Chunk chunk = null; if (Chunks.TryGetValue(pos.GetHashCode(), out chunk)) { DestroyChunk(chunk); } }
public void SpawnPane(World3 block, Block.Direction side, Color color) { template.colors.Clear(); for (int i = 1; i < template.vertices.Count; i++) { template.colors.Add(color); } }
public Save(Chunk chunk) { for (int i = 0; i < chunk._changes.Count; i++) { uint index = chunk._changes[i]; World3 pos = Chunk.BlockPosition(index); blocks.Add(pos, chunk._blocks[index]); } }
bool CheckNeighbors(Chunk chunk) { // check around for (int xi = -1; xi <= 1; xi += 2) { World3 pos = new World3( chunk.pos.x + (xi * Chunk.Size), chunk.pos.y, chunk.pos.z); Chunk neighbor = World.GetChunk(pos); if (neighbor == null || !neighbor.built) { return(false); } } for (int zi = -1; zi <= 1; zi += 2) { World3 pos = new World3( chunk.pos.x, chunk.pos.y, chunk.pos.z + (zi * Chunk.Size)); Chunk neighbor = World.GetChunk(pos); if (neighbor == null || !neighbor.built) { return(false); } } int yStart = chunk.pos.y == 0 ? -1 : 1; int yEnd = chunk.pos.y == -((Config.WorldSize - 1f) * Chunk.Size) ? 1 : -1; // check above and/or below for (int yi = yStart; yi <= yEnd; yi++) { World3 pos = new World3 ( chunk.pos.x, chunk.pos.y + (yi * Chunk.Size), chunk.pos.z ); Chunk neighbor = World.GetChunk(pos); if (neighbor == null || !neighbor.built) { return(false); } } return(true); }
public static void CreateChunk(int x, int y, int z) { // Get a chunk, either from the pool or brand new Chunk newChunk = InstantiateChunk(); // Set the position of the chunk World3 pos = new World3(x, y, z); newChunk.transform.position = pos.ToVector3(); newChunk.transparentChunk.transform.position = pos.ToVector3(); newChunk.pos = pos; // Add the chunk to the world chunks World.Chunks.Add(pos.GetHashCode(), newChunk); World.ChunkList.Add(newChunk); // Look for the rest of the chunks in this column of chunks bool columnBuilt = true; for (int i = 1 - Config.WorldHeight; i < 1; i++) { World3 chunkPos = new World3(pos.x, i * Chunk.Size, pos.z); Chunk chunk; if (Chunks.TryGetValue(chunkPos.GetHashCode(), out chunk)) { columnChunks[i + Config.WorldHeight - 1] = chunk; } else { columnBuilt = false; break; } } // If they exist we are ready to generate the column if (columnBuilt) { // Does this column already exist? World3 columnLocation = new World3(columnChunks[0].pos.x, 0, columnChunks[0].pos.z); if (!Columns.ContainsKey(columnLocation.GetHashCode())) { // Initialize the generator if it isn't if (!World._instance.generator.initialized) { World._instance.generator.Initialize(); } // Kick off generation. We get a region back that encompasses these chunks. Region region = Generator.Generate(columnChunks); Column column = new Column(region, columnChunks); Columns.Add(columnLocation.GetHashCode(), column); } } }
public void CreateCollider(MeshData meshData, ushort[] blocks, World3 pos) { if (Config.Multithreaded) { this.StartCoroutineAsync(CreateCollisionMeshData(meshData, blocks, pos)); } else { StartCoroutine(CreateCollisionMeshData(meshData, blocks, pos)); } }
public void Create(MeshData meshData, ushort[] blocks, World3 pos, bool transparent) { if (Config.Multithreaded) { this.StartCoroutineAsync(CreateMeshData(meshData, blocks, pos, transparent)); } else { StartCoroutine(CreateMeshData(meshData, blocks, pos, transparent)); } }
static void UpdateIfEqual(int value1, int value2, World3 pos, bool playerHit) { if (value1 == value2) { Chunk chunk = GetChunk(GetChunkPosition(pos)); if (chunk != null) { chunk.update = true; } } }
public static void SetBlock(World3 pos, ushort block, bool playerHit) { ushort current = World.GetBlock(pos); if (current == Block.Air && block != Block.Air) { World.SetBlock(pos.x, pos.y, pos.z, block, playerHit); } else if (current != Block.Air && block == Block.Air && pos.y != -48) { World.SetBlock(pos.x, pos.y, pos.z, block, playerHit); } }
void ExecuteSpawn() { if (!Game.Active) { return; } if (World.Columns.Count > 0) { for (int i = 0; i < ChunkData.SpawnOrder.Count(); i++) { //translate the player position and array position into chunk position World3 spawnPosition = new World3 ( ChunkData.SpawnOrder[i].x * Chunk.Size + playerChunkPos.x, 0, ChunkData.SpawnOrder[i].z * Chunk.Size + playerChunkPos.z ); Column column; if (World.Columns.TryGetValue(spawnPosition.GetHashCode(), out column)) { if (!column.spawned && column.rendered) { // Only spawn if the player is still around World3 currentPosition = World.GetChunkPosition(new Vector3 ( Game.Player.transform.position.x, 0, Game.Player.transform.position.z )); World3 columnPosition = World.GetChunkPosition(new Vector3 ( column.region.min.x, 0, column.region.min.z )); float distance = Vector3.Distance(columnPosition.ToVector3(), currentPosition.ToVector3()); if (distance <= Config.SpawnRadius * Chunk.Size) { column.SpawnColumn(spawnPosition, World.Spawn); } } } } } }
public static void SetSphere(World3 pos, ushort block, int diameter) { int r = Mathf.FloorToInt(diameter / 2f); for (int z = -r; z < r + 1; z++) { for (int y = -r; y < r + 1; y++) { for (int x = -r; x < r + 1; x++) { if (Mathf.FloorToInt(Mathf.Sqrt(x * x + y * y + z * z)) == r) { SetBlock(new World3(pos.x + x, pos.y + y, pos.z + z), block); } } } } }
public static World.Direction GetDirection(World3 from, World3 to) { if (to.z > from.z) { if (to.x < from.x) { return(World.Direction.northwest); } else if (to.x > from.x) { return(World.Direction.northeast); } else { return(World.Direction.north); } } else if (to.z < from.z) { if (to.x < from.x) { return(World.Direction.southwest); } else if (to.x > from.x) { return(World.Direction.southeast); } else { return(World.Direction.south); } } else if (to.x < from.x) { return(World.Direction.west); } else if (to.x > from.x) { return(World.Direction.east); } return(World.Direction.none); }
public void CreateBlocks() { // if (camOp.FirstPerson) // { // Vector3 camForward = Vector3.Scale(Game.MainCamera.transform.forward, new Vector3(1, 0, 1)).normalized; // Vector3 editLocation = transform.position + camForward; // World3 editBlock = World.GetBlockPosition(editLocation); // ushort block = World.GetBlock(editBlock); // if (block == Block.Air) // { // VoxelEditor.SetBlock(editBlock, Blocks.Glass(0)); // } // } // else // { for (int x = -1; x < 2; x++) { for (int y = -3; y < 0; y++) { for (int z = -1; z < 2; z++) { Vector3 editLocation = new Vector3( gameObject.transform.position.x + x, gameObject.transform.position.y + y, gameObject.transform.position.z + z); World3 editBlock = World.GetBlockPosition(editLocation); ushort block = World.GetBlock(editBlock); if (block == Block.Air) { VoxelEditor.SetBlock(editBlock, Blocks.Glass(0)); } } } } //} }
public static void SetBlock(World3 pos, ushort block, bool playerHit) { SetBlock(pos.x, pos.y, pos.x, block, playerHit); }
void AvoidTerrain(Boid boid) { if (transform == null) { return; } float s = 0.75f; int hits = 0; bool directHit = false; for (float x = -s; x <= s; x = x + s) { for (float y = -s; y <= s; y = y + s) { for (float z = -s; z <= s; z = z + s) { Vector3 p = new Vector3(boid.position.x + x, boid.position.y + y, boid.position.z + z); Vector3 pos = p + boid.velocity * Time.deltaTime * 2f; World3 worldPos = new World3(transform.TransformPoint(pos)); ushort block = World.GetBlock(worldPos); if ((block != Block.Air && block != Block.Null && worldPos.y < 16) || worldPos.y < -48) { hits++; if (x == 0 && y == 0 && z == 0) { directHit = true; } } } } } for (float x = -s; x <= s; x = x + s) { for (float y = -s; y <= s; y = y + s) { for (float z = -s; z <= s; z = z + s) { Vector3 p = new Vector3(boid.position.x + x, boid.position.y + y, boid.position.z + z); Vector3 pos = p + boid.velocity; World3 worldPos = new World3(transform.TransformPoint(pos)); ushort block = World.GetBlock(worldPos); if ((block != Block.Air && block != Block.Null && worldPos.y < 16) || worldPos.y < -48) { hits++; if (x == 0 && y == 0 && z == 0) { directHit = true; } } } } } if (hits == 0) { boid.rotation = Quaternion.FromToRotation(Vector3.up, boid.velocity); } else { boid.rotation = Quaternion.FromToRotation(Vector3.up, Vector3.RotateTowards(boid.velocity, -boid.velocity, Time.deltaTime * hits, 0f)); } if (directHit) { boid.velocity -= Vector3.up * 100f; boid.velocity = Vector3.ClampMagnitude(boid.velocity, maxSpeed); } if (hits > 0) { boid.velocity = Vector3.RotateTowards(boid.velocity, -boid.velocity, Time.deltaTime * hits * 5f, 0f); boid.velocity *= flutterBoost; boid.velocity += Vector3.up; boid.velocity = Vector3.ClampMagnitude(boid.velocity, maxSpeed); } }
private void DoFreeBlockSearch(float startDistance) { float testDistance = startDistance; //bool lookingUp = (freeLookCamera.m_TiltAngle <= 0); // Incremental search for a free location from the camera towards the player do { // Position forward of target camera position Vector3 forwardPos = cameraPosition - cameraDirection * (testDistance + 1f); // Block at the forward position World3 testBlockPosForward = World.GetBlockPosition(forwardPos); ushort tbForward = World.GetBlock(testBlockPosForward); cameraForwardBlock = tbForward; // If the forward position looks clear, perform further checks if (IsEmpty(tbForward)) { // Block slightly above the forward position World3 testSpreadUp = World.GetBlockPosition(forwardPos + _camera.transform.up * Mathf.Lerp(spread / 3f, spread, freeLookCamera.m_TiltAngle / 15f)); // Block slightly below the forward position World3 testSpreadDown = World.GetBlockPosition(forwardPos - _camera.transform.up * Mathf.Lerp(spread / 3f, spread, freeLookCamera.m_TiltAngle / 15f)); // Block slightly left of the forward position World3 testSpreadLeft = World.GetBlockPosition(forwardPos - _camera.transform.right * spread); // Block slightly right of the forward position World3 testSpreadRight = World.GetBlockPosition(forwardPos + _camera.transform.right * spread); ushort tbUp = World.GetBlock(testSpreadUp); ushort tbDown = World.GetBlock(testSpreadDown); ushort tbLeft = World.GetBlock(testSpreadLeft); ushort tbRight = World.GetBlock(testSpreadRight); bool down = IsEmpty(tbDown); bool up = IsEmpty(tbUp); bool left = IsEmpty(tbLeft); bool right = IsEmpty(tbRight); if (up && down && left && right) { if (Mathf.Abs(freeLookCamera.m_TiltAngle) <= 10) { break; } // Diagonals World3 testSpreadUpLeft = World.GetBlockPosition( forwardPos + _camera.transform.up - _camera.transform.right * Mathf.Lerp(spread / 3f, spread / 2f, freeLookCamera.m_TiltAngle / 15f) ); World3 testSpreadUpRight = World.GetBlockPosition( forwardPos + _camera.transform.up + _camera.transform.right * Mathf.Lerp(spread / 3f, spread / 2f, freeLookCamera.m_TiltAngle / 15f) ); World3 testSpreadDownLeft = World.GetBlockPosition( forwardPos - _camera.transform.up - _camera.transform.right * Mathf.Lerp(spread / 3f, spread / 2f, freeLookCamera.m_TiltAngle / 15f) ); World3 testSpreadDownRight = World.GetBlockPosition( forwardPos - _camera.transform.up + _camera.transform.right * Mathf.Lerp(spread / 3f, spread / 2f, freeLookCamera.m_TiltAngle / 15f) ); ushort tbUpLeft = World.GetBlock(testSpreadUpLeft); ushort tbUpRight = World.GetBlock(testSpreadUpRight); ushort tbDownLeft = World.GetBlock(testSpreadDownLeft); ushort tbDownRight = World.GetBlock(testSpreadDownRight); bool upLeft = IsEmpty(tbUpLeft); bool upRight = IsEmpty(tbUpRight); bool downLeft = IsEmpty(tbDownLeft); bool downRight = IsEmpty(tbDownRight); if (upLeft && upRight && downLeft && downRight) { break; } } } testDistance += 0.05f; }while(testDistance <= targetDist); // Adjust target distance targetDist = targetDist - testDistance - 1f; }
public static Chunk GetChunk(Vector3 pos) { World3 worldPos = World.GetChunkPosition(pos); return(GetChunk(worldPos)); }
void PopulateSpawns(SampleSet sampleSet, World3 pos) { for (int x = pos.x; x < pos.x + Chunk.Size; x++) { for (int z = pos.z; z < pos.z + Chunk.Size; z++) { // Value controls the type of item (if any) that can spawn at this location sampleSet.spawnMap.value[x - pos.x, z - pos.z] = //Chunk.NoSpawn; GetNoise2D(new Vector3(pos.x + x, pos.z + z, 0), Config.Instance.spawns.type, NoiseType.SimplexValue); // Frequency is a base control on how many of the item will spawn int frequency = GetNoise2D(new Vector3(pos.x + x, pos.z + z, 0), Config.Instance.spawns.frequency, NoiseType.SimplexValue); // And intensity controls how 'intense' the spawning action is at this location int intensity = GetNoise2D( new Vector3(pos.x + x, pos.z + z, 0), Config.Instance.spawns.intensity, NoiseType.SimplexValue ); sampleSet.spawnMap.intensity[x - pos.x, z - pos.z] = intensity; if (frequency < 50) { sampleSet.spawnMap.frequency[x - pos.x, z - pos.z] = 1; } else if (frequency < 70) { sampleSet.spawnMap.frequency[x - pos.x, z - pos.z] = 2; } else if (frequency < 75) { sampleSet.spawnMap.frequency[x - pos.x, z - pos.z] = 3; } else if (frequency < 80) { sampleSet.spawnMap.frequency[x - pos.x, z - pos.z] = 4; } else if (frequency < 85) { sampleSet.spawnMap.frequency[x - pos.x, z - pos.z] = 5; } else if (frequency < 90) { sampleSet.spawnMap.frequency[x - pos.x, z - pos.z] = 6; } else if (frequency < 95) { sampleSet.spawnMap.frequency[x - pos.x, z - pos.z] = 7; } else if (frequency < 98) { sampleSet.spawnMap.frequency[x - pos.x, z - pos.z] = 8; } else { sampleSet.spawnMap.frequency[x - pos.x, z - pos.z] = 9; } sampleSet.spawnMap.height[x - pos.x, z - pos.z] = Chunk.NoSpawn; } } }
void Update() { if (!Game.Active) { return; } if (camOp.FirstPerson) { if (!robotForm.activeSelf) { robotForm.SetActive(true); } } else if (robotForm.activeSelf) { robotForm.SetActive(false); boostEffect.SetActive(true); // strange bug makes the ball roll funny if this isn't toggled! } // Get input force Vector2 input = GameInput.Movement; // Get flags for current actions boosting = GameInput.Boosting; jumping = GameInput.Jumping; create = GameInput.CreateBlock; pound = GameInput.GroundPound; // calculate camera relative direction to move: camForward = Vector3.Scale(cam.forward, new Vector3(1, 0, 1)).normalized; Vector3 cameraY = input.y * camForward; Vector3 cameraX = input.x * cam.right; move = (cameraY + cameraX).normalized; Vector3 worldMove = cam.TransformDirection(move); //Game.Log("X: " + worldMove.x + " Y: " + worldMove.z); Debug.DrawRay(transform.position, move, Color.cyan, 0.1f); // stop bumping up against blocks and jiggling around due to physics if (camOp.FirstPerson) { World3 blockPos = World.GetBlockPosition(Game.Player.transform.position + move); ushort block = World.GetBlock(blockPos); if (block != Block.Air) { World.Direction direction = World.GetDirection(World.GetBlockPosition(Game.Player.transform.position), blockPos); if (direction != lastDirection) { prevDirection = lastDirection; } lastDirection = direction; Game.Log(direction.ToString()); Vector3 projectRight = Vector3.Project(move, Vector3.right); Vector3 projectForward = Vector3.Project(move, Vector3.forward); Debug.DrawRay(transform.position, projectRight.normalized, Color.red, 0.1f); Debug.DrawRay(transform.position, projectForward.normalized, Color.yellow, 0.1f); //if (worldMove.z > 0) if ( worldMove.z > 0 || direction == World.Direction.north || direction == World.Direction.south ) { block = World.GetBlock(World.GetBlockPosition(Game.Player.transform.position + projectRight.normalized)); if (block == Block.Air) { move = projectRight; } else { move = Vector3.zero; } } else if ( worldMove.z < 0 || direction == World.Direction.east || direction == World.Direction.west ) { block = World.GetBlock(World.GetBlockPosition(Game.Player.transform.position + projectForward.normalized)); if (block == Block.Air) { move = projectForward; } else { move = Vector3.zero; } } else { move = Vector3.zero; } } } if (create) { roller.CreateBlocks(); } // TODO: Centralize all input handling if (Input.GetKey(KeyCode.Y)) { roller.CreateSphere(); } if (GameInput.SwapInputs) { Config.SwapInputs = !Config.SwapInputs; } bool boostOn = roller.GetAfterburnerState(); if (!camOp.FirstPerson && camOp.Distance > 2f) { boostEffect.SetActive(boostOn); } else { boostEffect.SetActive(false); } if ((int)Config.QualityLevel >= 2) { if (boostOn && !camOp.FirstPerson) { boostLight.intensity = 1f; } else { boostLight.intensity = 0f; } } // bash blocks if (!create && (boosting || pound)) { Vector3 planePos = new Vector3(transform.position.x, 0, transform.position.z); Vector3 planeLastPos = new Vector3(lastPosition.x, 0, lastPosition.z); Vector3 forwardNormal = Vector3.Normalize(planePos - planeLastPos); float speed = Mathf.Abs(Vector3.Distance(transform.position, lastPosition)); roller.BashBlocks(forwardNormal, speed, boosting, jumping, camOp.FirstPerson); } }
public static void CreateChunk(World3 pos) { CreateChunk(pos.x, pos.y, pos.z); }
public static void SetBlock(World3 pos, ushort block) { SetBlock(pos, block, false); }
public static World3 GetChunkPosition(World3 pos) { return(GetChunkPosition(new Vector3(pos.x, pos.y, pos.z))); }
public static ushort GetBlock(World3 pos) { return(GetBlock(pos.x, pos.y, pos.z)); }
public static Column GetColumn(World3 pos) { pos = GetChunkPosition(pos); return(GetColumn(pos.x, pos.z)); }