Package Hexel.chunk

Source Code of Hexel.chunk.Chunks

package Hexel.chunk;

import java.util.concurrent.ExecutionException;

import Hexel.blocks.types.Block;
import Hexel.blocks.types.BlockTransparent;
import Hexel.generation.ChunkGenerator;
import Hexel.math.HexGeometry;
import Hexel.math.Vector2i;
import Hexel.math.Vector3i;
import Hexel.util.Cleanup;
import Hexel.util.Container;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalNotification;

public class Chunks {

  public ChunkGenerator chunkGenerator;
  private LoadingCache<Vector3i, Chunk> chunkCache;
  private LoadingCache<Vector2i, HighestBlockChunk> highestBlockCache;

  private Cleanup cleanup;

  public Chunks(Cleanup cleanup, int numToBuffer) {
    this.cleanup = cleanup;
    this.chunkCache = CacheBuilder.newBuilder().maximumSize(numToBuffer)
        .recordStats()
        .removalListener(new RemovalListener<Vector3i, Chunk>() {
          @Override
          public void onRemoval(
              RemovalNotification<Vector3i, Chunk> notification) {
            Chunk c = notification.getValue();
            if (c != null && c.modified) {
              ChunkFile.save(c);
            }
          }
        }).build(new CacheLoader<Vector3i, Chunk>() {
          @Override
          public Chunk load(Vector3i p) {
            Chunk chunk;
            if (ChunkFile.has(p)) {
              chunk = ChunkFile.load(p);
            } else {
              chunk = Chunks.this.chunkGenerator.genChunk(p);
            }
            return chunk;
          }
        });
    this.highestBlockCache = CacheBuilder.newBuilder().maximumSize(numToBuffer)
        .removalListener(new RemovalListener<Vector2i, HighestBlockChunk>() {
          @Override
          public void onRemoval(
              RemovalNotification<Vector2i, HighestBlockChunk> notification) {
            HighestBlockChunk map = notification.getValue();
            Vector2i loc = notification.getKey();
            if (map != null) {
              HighestBlockFile.save(loc, map);
            }
          }
        }).build(new CacheLoader<Vector2i, HighestBlockChunk>() {
          @Override
          public HighestBlockChunk load(Vector2i p) {
            HighestBlockChunk map;
            if (HighestBlockFile.has(p)) {
              map = HighestBlockFile.load(p);
            } else {
              map = new HighestBlockChunk();
              map.x = p.x;
              map.y = p.y;
              map.highestBlocks = new int[Chunk.WIDTH][Chunk.HEIGHT];
              for (int x = 0; x < Chunk.WIDTH; x++){
                for (int y = 0; y < Chunk.HEIGHT; y++){
                  map.highestBlocks[x][y] = Integer.MIN_VALUE;
                }
              }
            }
            return map;
          }
        });


    cleanup.add(new Runnable() {
      @Override
      public void run() {
        unloadAllChunks();
      }
    });
  }

  public void setSeed(int seed){
    this.chunkGenerator = new ChunkGenerator(seed, this, cleanup);
  }

  public Chunk getChunk(Vector3i cpos) {
    try {
      Chunk c = this.chunkCache.getIfPresent(cpos);
      if (c != null)
        return c;
      else
        return this.chunkCache.get(new Vector3i(cpos));
    } catch (Exception e) {
      System.out.println("Caught Exception retrieving chunk from cache!");
      e.printStackTrace();
      System.exit(1);
      return null;
    }
  }

  public HighestBlockChunk getHighestBlockChunk(Vector2i pos){
    try {
      HighestBlockChunk hbm = this.highestBlockCache.getIfPresent(pos);
      if (hbm != null)
        return hbm;
      else
        return this.highestBlockCache.get(new Vector2i(pos));
    } catch (Exception e) {
      System.out.println("Caught Exception retrieving highest block map from cache!");
      e.printStackTrace();
      System.exit(1);
      return null;
    }
  }

  public void unloadAllChunks() {
    this.chunkCache.invalidateAll();
    this.highestBlockCache.invalidateAll();
  }

  public HighestBlockChunk getHighestBlockChunkAtXY(int x, int y, Vector2i pos){
    int cx = (int) Math.floor(x / 32.0);
    int cy = (int) Math.floor(y / 16.0);

    int bx = x - cx * 32;
    int by = y - cy * 16;
    pos.x = cx;
    pos.y = cy;
    HighestBlockChunk heights = this.getHighestBlockChunk(pos);
    return heights;
  }

  public int getHighestBlockAtXY(int x, int y, Vector2i pos){
    int cx = (int) Math.floor(x / 32.0);
    int cy = (int) Math.floor(y / 16.0);

    int bx = x - cx * 32;
    int by = y - cy * 16;
    pos.x = cx;
    pos.y = cy;
    HighestBlockChunk heights = this.getHighestBlockChunk(pos);
    return heights.highestBlocks[bx][by];
  }

  public int getHighestBlockAtXY(int x, int y, Vector2i pos, Container<HighestBlockChunk> hbc){
    int cx = (int) Math.floor(x / 32.0);
    int cy = (int) Math.floor(y / 16.0);

    int bx = x - cx * 32;
    int by = y - cy * 16;
    if (hbc.contents == null || !hbc.contents.containsPoint(x, y)){
      pos.x = cx;
      pos.y = cy;
      hbc.contents = this.getHighestBlockChunk(pos);
    }
    return hbc.contents.highestBlocks[bx][by];
  }

  public void updateHighestBlockAtXY(int x, int y, int z, Vector2i pos){
    int cx = (int) Math.floor(x / 32.0);
    int cy = (int) Math.floor(y / 16.0);

    int bx = x - cx * 32;
    int by = y - cy * 16;
    pos.x = cx;
    pos.y = cy;
    HighestBlockChunk heights;
    try {
      heights = this.highestBlockCache.get(pos);
      if (z > heights.highestBlocks[bx][by])
        heights.highestBlocks[bx][by] = z;
    } catch (ExecutionException e) {
      e.printStackTrace();
      System.exit(1);
    }
  }

  public Block getBlock(int x, int y, int z, Vector3i p, Chunk chunk) {
    int cx = (int) Math.floor(x / 32.0);
    int cy = (int) Math.floor(y / 16.0);
    int cz = (int) Math.floor(z / 32.0);

    int bx = x - cx * 32;
    int by = y - cy * 16;
    int bz = z - cz * 32;
    if (chunk == null || !chunk.containsPoint(x, y, z)){
      p.x = cx;
      p.y = cy;
      p.z = cz;
      chunk = getChunk(p);
    }
    return chunk.get(bx, by, bz);
  }

  public Block getBlock(int x, int y, int z, Vector3i p, Container<Chunk> chunk) {
    int cx = (int) Math.floor(x / 32.0);
    int cy = (int) Math.floor(y / 16.0);
    int cz = (int) Math.floor(z / 32.0);

    int bx = x - cx * 32;
    int by = y - cy * 16;
    int bz = z - cz * 32;
    if (chunk.contents == null || !chunk.contents.containsPoint(x, y, z)){
      p.x = cx;
      p.y = cy;
      p.z = cz;
      chunk.contents = getChunk(p);
    }
    return chunk.contents.get(bx, by, bz);
  }

  public Block getBlock(int cx, int cy, int cz, int x, int y, int z, Vector3i p, Chunk c) {
    int gx = cx * 32 + x;
    int gy = cy * 16 + y;
    int gz = cz * 32 + z;

    return this.getBlock(gx, gy, gz, p, c);
  }

  public void setStepsToSim(int x, int y, int z, int stepsToSim, Vector3i p){
    int cx = (int) Math.floor(x / 32.0);
    int cy = (int) Math.floor(y / 16.0);
    int cz = (int) Math.floor(z / 32.0);

    int bx = x - cx * 32;
    int by = y - cy * 16;
    int bz = z - cz * 32;

    p.x = cx;
    p.y = cy;
    p.z = cz;
    Chunk chunk = getChunk(p);
    chunk.stepsToSim[bx][by][bz] = stepsToSim;
    if (stepsToSim > 0)
      chunk.nextSimStep = -1;
  }

  public int getStepsToSim(int x, int y, int z, Vector3i p, Chunk chunk){
    int cx = (int) Math.floor(x / 32.0);
    int cy = (int) Math.floor(y / 16.0);
    int cz = (int) Math.floor(z / 32.0);

    int bx = x - cx * 32;
    int by = y - cy * 16;
    int bz = z - cz * 32;

    p.x = cx;
    p.y = cy;
    p.z = cz;
    if (chunk == null || !chunk.containsPoint(x, y, z)){
      p.x = cx;
      p.y = cy;
      p.z = cz;
      chunk = getChunk(p);
    }
    return chunk.stepsToSim[bx][by][bz];
  }

  public int getStepsToSim(int x, int y, int z, Vector3i p, Container<Chunk> chunk) {
    int cx = (int) Math.floor(x / 32.0);
    int cy = (int) Math.floor(y / 16.0);
    int cz = (int) Math.floor(z / 32.0);

    int bx = x - cx * 32;
    int by = y - cy * 16;
    int bz = z - cz * 32;
    if (chunk.contents == null || !chunk.contents.containsPoint(x, y, z)){
      p.x = cx;
      p.y = cy;
      p.z = cz;
      chunk.contents = getChunk(p);
    }
    return chunk.contents.stepsToSim[bx][by][bz];
  }

  public Chunk simBlock(int x, int y, int z, Vector3i p, Chunk chunk){
    int cx = (int) Math.floor(x / 32.0);
    int cy = (int) Math.floor(y / 16.0);
    int cz = (int) Math.floor(z / 32.0);

    int bx = x - cx * 32;
    int by = y - cy * 16;
    int bz = z - cz * 32;
    if (chunk == null || !chunk.containsPoint(x, y, z)){
      p.x = cx;
      p.y = cy;
      p.z = cz;
      chunk = getChunk(p);
    }
    chunk.nextSimSteps[bx][by][bz] = -1;
    chunk.nextSimStep = -1;
    return chunk;
  }

  public void setBlock(int x, int y, int z, Block b, Vector3i p, Vector2i tmp2, Chunk chunk) {
    int cx = (int) Math.floor(x / 32.0);
    int cy = (int) Math.floor(y / 16.0);
    int cz = (int) Math.floor(z / 32.0);

    int bx = x - cx * 32;
    int by = y - cy * 16;
    int bz = z - cz * 32;
    if (chunk == null || !chunk.containsPoint(x, y, z)){
      p.x = cx;
      p.y = cy;
      p.z = cz;
      chunk = getChunk(p);
    }

    chunk.set(bx, by, bz, b);
    chunk.setDirty(true);
    this.simBlock(x, y, z, p, chunk);

    if (! (b instanceof BlockTransparent)){
      updateHighestBlockAtXY(x, y, z, tmp2);
    }

    chunk.modified = true;

    Vector3i[] neighbors;
    if (x % 2 == 0) {
      neighbors = HexGeometry.evenAllNeighbors;
    } else {
      neighbors = HexGeometry.oddAllNeighbors;
    }
    for (Vector3i neighbor : neighbors){
      int x2 = x + neighbor.x;
      int y2 = y + neighbor.y;
      int z2 = z + neighbor.z;
      Chunk chunk2 = this.simBlock(x2, y2, z2, p, chunk);
      chunk2.setDirty(true);
    }
  }
}
TOP

Related Classes of Hexel.chunk.Chunks

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.