All Downloads are FREE. Search and download functionalities are using the official Maven repository.

se.llbit.chunky.map.MapTile Maven / Gradle / Ivy

There is a newer version: 1.4.5
Show newest version
/* Copyright (c) 2016 Jesper Öqvist 
 *
 * This file is part of Chunky.
 *
 * Chunky is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Chunky is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with Chunky.  If not, see .
 */
package se.llbit.chunky.map;

import javafx.scene.paint.Color;
import se.llbit.chunky.resources.BitmapImage;
import se.llbit.chunky.world.Chunk;
import se.llbit.chunky.world.ChunkPosition;
import se.llbit.chunky.world.ChunkView;
import se.llbit.chunky.world.Region;
import se.llbit.math.ColorUtil;

/**
 * A tile in the 2D world map or minimap. The tile contains either a chunk or a region.
 * The scale of the tile can not be changed.
 */
public class MapTile {
  int[] pixels;

  public ChunkPosition pos;

  /**
   * Decides if each tile is a chunk or a region (tile=chunk if true).
   */
  private boolean chunkMode;

  /**
   * Size of a single chunk in pixels.
   */
  public int scale;

  /**
   * Size of the pixel buffer.
   */
  public int size;

  public boolean isCached = false;

  public MapTile(ChunkPosition position, ChunkView view) {
    rebuild(position, view);
  }

  public void drawCached(MapBuffer buffer, WorldMapLoader mapLoader, ChunkView view) {
    if (isCached) {
      drawCached(buffer, view);
    } else {
      draw(buffer, mapLoader, view);
    }
  }

  public void draw(MapBuffer buffer, WorldMapLoader mapLoader, ChunkView view) {
    if (scale >= 16) {
      Chunk chunk = mapLoader.getWorld().getChunk(pos);
      view.renderer.render(chunk, this);
      if (buffer.highlightEnabled()) {
        Color fxColor = buffer.highlightColor();
        int hlColor = ColorUtil.getArgb(fxColor.getRed(), fxColor.getGreen(), fxColor.getBlue(),
            fxColor.getOpacity());
        chunk.renderHighlight(this, buffer.highlightBlock(), hlColor);
      }
      if (mapLoader.getChunkSelection().isSelected(pos)) {
        for (int i = 0; i < size * size; ++i) {
          pixels[i] = selectionTint(pixels[i]);
        }
      }
    } else {
      Region region = mapLoader.getWorld().getRegion(pos);
      int pixelOffset = 0;
      for (int z = 0; z < 32; ++z) {
        for (int x = 0; x < 32; ++x) {
          Chunk chunk = region.getChunk(x, z);
          pixels[pixelOffset] = view.renderer.getChunkColor(chunk);
          if (mapLoader.getChunkSelection().isSelected(chunk.getPosition())) {
            pixels[pixelOffset] = selectionTint(pixels[pixelOffset]);
          }
          pixelOffset += 1;
        }
      }
    }
    drawCached(buffer, view);
    isCached = true;
  }

  /** @return the argb color value tinted with the selection color. */
  private int selectionTint(int argb) {
    int red = (argb >> 16) & 0xFF;
    int green = (argb >> 8) & 0xFF;
    int blue = argb & 0xFF;
    return (argb & 0xFF000000) | ((red / 2 + 0x7F) << 16) | (green / 2) << 8 | (blue / 2);
  }

  private void drawCached(MapBuffer buffer, ChunkView view) {
    if (view.isVisible(pos)) {
      int x0;
      int z0;
      if (chunkMode) {
        x0 = size * (pos.x - view.px0);
        z0 = size * (pos.z - view.pz0);
      } else {
        x0 = size * (pos.x - view.prx0);
        z0 = size * (pos.z - view.prz0);
      }
      int srcPos = 0;
      for (int z = 0; z < size; ++z) {
        buffer.copyPixels(pixels, srcPos, x0, z0 + z, size);
        srcPos += size;
      }
    }
  }

  public void setPixel(int x, int z, int argb) {
    pixels[z * size + x] = argb;

  }

  public void setPixels(int[] newPixels) {
    System.arraycopy(newPixels, 0, pixels, 0, size * size);
  }

  public void fill(int argb) {
    int[] pixels = new int[size * size];
    for (int i = 0; i < size * size; ++i) {
      pixels[i] = argb;
    }
    setPixels(pixels);
  }

  public void rebuild(ChunkPosition newPos, ChunkView view) {
    isCached = false;
    pos = newPos;
    scale = view.chunkScale;
    chunkMode = scale >= 16;
    int newSize = chunkMode ? scale : 32;
    // Resize buffer if needed.
    if (newSize != size) {
      size = newSize;
      pixels = new int[size * size];
    }
  }

  /**
   * Draw a bitmap image to this map tile.
   */
  public void drawImage(BitmapImage image) {
    // Safety check to see that the image has the correct size.
    // This check fails when trying to draw static icons not rendered to the tile size.
    // TODO: ensure that the image is always scaled to the tile size.
    if (image.width == size || image.height == size) {
      System.arraycopy(image.data, 0, pixels, 0, size * size);
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy