Package me.daddychurchill.CityWorld.Support

Source Code of me.daddychurchill.CityWorld.Support.PlatMap

package me.daddychurchill.CityWorld.Support;

import me.daddychurchill.CityWorld.WorldGenerator;
import me.daddychurchill.CityWorld.Clipboard.Clipboard;
import me.daddychurchill.CityWorld.Clipboard.ClipboardLot;
import me.daddychurchill.CityWorld.Context.DataContext;
import me.daddychurchill.CityWorld.Plats.PlatLot;
import me.daddychurchill.CityWorld.Plats.RoadLot;
import me.daddychurchill.CityWorld.Plats.PlatLot.LotStyle;
import me.daddychurchill.CityWorld.Plugins.ShapeProvider;

import org.bukkit.block.BlockFace;
import org.bukkit.generator.ChunkGenerator.BiomeGrid;

public class PlatMap {
 
  // Class Constants
  public static final int Width = 10;
 
  // Instance data
//  public World world;
  public WorldGenerator generator;
  public int originX;
  public int originZ;
  public DataContext context;
  protected PlatLot[][] platLots;
  private float naturalPlats;

  public PlatMap(WorldGenerator generator, ShapeProvider shapeProvider, int originX, int originZ) {
    super();
   
    // populate the instance data
//    this.world = generator.getWorld();
    this.generator = generator;
    this.originX = originX;
    this.originZ = originZ;

    // make room for plat data
    platLots = new PlatLot[Width][Width];
    naturalPlats = 0;
   
    // do the deed
    shapeProvider.populateLots(generator, this);
   
    // recycle all the remaining holes
    for (int x = 0; x < Width; x++) {
      for (int z = 0; z < Width; z++) {
        if (isEmptyLot(x, z))
          recycleLot(x, z);
      }
    }
  }
 
  public float getNaturePercent() {
    return naturalPlats / (Width * Width);
  }
 
  public Odds getOddsGenerator() {
    return generator.shapeProvider.getMacroOddsGeneratorAt(originX, originZ);
  }
 
  public Odds getChunkOddsGenerator(SupportChunk chunk) {
    return generator.shapeProvider.getMicroOddsGeneratorAt(chunk.chunkX, chunk.chunkZ);
  }
 
  public Odds getChunkOddsGenerator(int chunkX, int chunkZ) {
    return generator.shapeProvider.getMicroOddsGeneratorAt(chunkX, chunkZ);
  }
 
  public void generateChunk(ByteChunk chunk, BiomeGrid biomes) {

    // depending on the platchunk's type render a layer
    int platX = chunk.chunkX - originX;
    int platZ = chunk.chunkZ - originZ;
   
    PlatLot platlot = platLots[platX][platZ];
    if (platlot != null) {

      // do what we came here for
      platlot.generateChunk(generator, this, chunk, biomes, context, platX, platZ);
    }
  }
 
  public void generateBlocks(RealChunk chunk) {

    // depending on the platchunk's type render a layer
    int platX = chunk.chunkX - originX;
    int platZ = chunk.chunkZ - originZ;
    PlatLot platlot = platLots[platX][platZ];
    if (platlot != null) {

      // do what we came here for
      platlot.generateBlocks(generator, this, chunk, context, platX, platZ);
    }
  }
 
 
  public int getNumberOfRoads() {
    int result = 0;
    for (int x = 0; x < Width; x++) {
      for (int z = 0; z < Width; z++) {
        if (platLots[x][z] != null && platLots[x][z].style == LotStyle.ROAD)
          result++;
      }
    }
    return result;
  }
 
  public PlatLot getLot(int x, int z) {
    if (x >= 0 && x < Width && z >= 0 && z < Width)
      return platLots[x][z];
    else
      return null;
  }
 
  public PlatLot getMapLot(int chunkX, int chunkZ) throws IndexOutOfBoundsException {
    int platX = chunkX - originX;
    int platZ = chunkZ - originZ;
   
    // range check
    if (platX >= 0 && platX < Width && platZ >= 0 && platZ < Width)
      return platLots[platX][platZ];
    else
      throw new IndexOutOfBoundsException("Location specified is not in this PlatMap");
  }
 
  public boolean isEmptyLot(int x, int z) {
    if (x >= 0 && x < Width && z >= 0 && z < Width)
      return platLots[x][z] == null;
    else
      return true;
  }
 
  public boolean isInnerReallyEmptyLot(int centerX, int centerZ) {
    if (centerX >= 1 && centerX < Width - 1 && centerZ >= 1 && centerZ < Width - 1) {
      for (int x = centerX - 1; x < centerX + 2; x++) {
        for (int z = centerZ - 1; z < centerZ + 2; z++) {
          if (platLots[x][z] != null)
            return false;
        }
      }
      return true;
    } else
      return false;
  }
 
  public boolean isNaturalLot(int x, int z) {
    if (x >= 0 && x < Width && z >= 0 && z < Width)
      return platLots[x][z] == null || platLots[x][z].style == LotStyle.NATURE;
    else
      return true;
  }
 
  public boolean isStructureLot(int x, int z) {
    if (x >= 0 && x < Width && z >= 0 && z < Width)
      return platLots[x][z] != null && platLots[x][z].style == LotStyle.STRUCTURE;
    else
      return false;
  }
 
  public boolean isExistingRoad(int x, int z) {
    if (x >= 0 && x < Width && z >= 0 && z < Width)
      return isRoad(x, z);
    else
      return false;
  }

  protected boolean isRoad(int x, int z) {
    PlatLot current = platLots[x][z];
    return current != null && (current.style == LotStyle.ROAD || current.style == LotStyle.ROUNDABOUT);
  }
 
  public void recycleLot(int x, int z) {

    // if it is not natural, make it so
    PlatLot current = platLots[x][z];
    if (current == null || current.style != LotStyle.NATURE) {
   
      // place nature
      platLots[x][z] = generator.shapeProvider.createNaturalLot(generator, this, x, z);
      naturalPlats++;
    }
  }
 
  public void paveLot(int x, int z, boolean roundaboutPart) {
    if (generator.settings.inRoadRange(originX + x, originZ + z) &&
      (platLots[x][z] == null || roundaboutPart || platLots[x][z].style != LotStyle.ROAD)) {
     
      // remember the old one
      PlatLot oldLot = platLots[x][z];
     
      // clear it please
      emptyLot(x, z);
     
      // place the lot
      platLots[x][z] = generator.shapeProvider.createRoadLot(generator, this, x, z, roundaboutPart, oldLot);
    }
  }
 
  public boolean setLot(int x, int z, PlatLot lot) {
    if (lot == null) {
      emptyLot(x, z);
      return true;
    } else {
      boolean result = lot.isPlaceableAt(generator, originX + x, originZ + z);
      if (result) {
       
        // clear it please
        emptyLot(x, z);
       
        // place the lot
        platLots[x][z] = lot;
      }
      return result;
    }
  }
 
  public void emptyLot(int x, int z) {
   
    // keep track of the nature count
    PlatLot current = platLots[x][z];
    if (current != null && current.style == LotStyle.NATURE)
      naturalPlats--;
   
    // empty this one out
    platLots[x][z] = null;
  }
 
  public boolean isTrulyIsolatedLot(int x, int z) {
     
    // check each neighbor to see if it is also trulyIsolated
    for (int lotX = x - 1; lotX < x + 2; lotX++) {
      for (int lotZ = z - 1; lotZ < z + 2; lotZ++) {
        if (lotX != x && lotZ != z) {
          PlatLot neighbor = getLot(lotX, lotZ);
          if (neighbor != null && neighbor.trulyIsolated)
            return false;
        }
      }
    }
     
    // all done
    return true;
  }
 
  public void populateRoads() {
   
    // place the big four
    placeIntersection(RoadLot.PlatMapRoadInset - 1, RoadLot.PlatMapRoadInset - 1);
    placeIntersection(RoadLot.PlatMapRoadInset - 1, Width - RoadLot.PlatMapRoadInset);
    placeIntersection(Width - RoadLot.PlatMapRoadInset, RoadLot.PlatMapRoadInset - 1);
    placeIntersection(Width - RoadLot.PlatMapRoadInset, Width - RoadLot.PlatMapRoadInset);
  }
 
  public void validateRoads() {
   
    // any roads leading out?
    if (!(isRoad(0, RoadLot.PlatMapRoadInset - 1) ||
        isRoad(0, Width - RoadLot.PlatMapRoadInset) ||
        isRoad(Width - 1, RoadLot.PlatMapRoadInset - 1) ||
        isRoad(Width - 1, Width - RoadLot.PlatMapRoadInset) ||
        isRoad(RoadLot.PlatMapRoadInset - 1, 0) ||
        isRoad(Width - RoadLot.PlatMapRoadInset, 0) ||
        isRoad(RoadLot.PlatMapRoadInset - 1, Width - 1) ||
        isRoad(Width - RoadLot.PlatMapRoadInset, Width - 1))) {
     
      // reclaim all of the silly roads
      for (int x = 0; x < Width; x++) {
        for (int z = 0; z < Width; z++) {
          if (isRoad(x, z))
            recycleLot(x, z);
        }
      }
     
    } else {
     
      //TODO any other validation?
    }
  }
 
  protected void placeIntersection(int x, int z) {
    boolean roadToNorth = false, roadToSouth = false,
        roadToEast = false, roadToWest = false,
        roadHere = false;
   
    // is there a road here?
    if (isEmptyLot(x, z)) {
   
      // are there roads from here?
      roadToNorth = isRoadTowards(x, z, 0, -5);
      roadToSouth = isRoadTowards(x, z, 0, 5);
      roadToEast = isRoadTowards(x, z, 5, 0);
      roadToWest = isRoadTowards(x, z, -5, 0);
     
      // is there a need for this intersection?
      if (roadToNorth || roadToSouth || roadToEast || roadToWest) {
     
        // are the odds in favor of a roundabout? AND..
        // are all the surrounding chunks empty (connecting roads shouldn't be there yet)
        if (generator.settings.includeRoundabouts &&
          generator.shapeProvider.isRoundaboutAt(originX + x, originZ + z, context.oddsOfRoundAbouts) &&
          isEmptyLot(x - 1, z - 1) && isEmptyLot(x - 1, z) &&  isEmptyLot(x - 1, z + 1) &&
          isEmptyLot(x, z - 1) &&  isEmptyLot(x, z + 1) &&
          isEmptyLot(x + 1, z - 1) &&  isEmptyLot(x + 1, z) &&  isEmptyLot(x + 1, z + 1)) {
         
          paveLot(x - 1, z - 1, true);
          paveLot(x - 1, z    , true);
          paveLot(x - 1, z + 1, true);
         
          paveLot(x    , z - 1, true);
          setLot(x, z, generator.shapeProvider.createRoundaboutStatueLot(generator, this, originX + x, originZ + z));
          paveLot(x    , z + 1, true);
     
          paveLot(x + 1, z - 1, true);
          paveLot(x + 1, z    , true);
          paveLot(x + 1, z + 1, true);
       
        // place the intersection then
        } else {
          roadHere = true;
        }
      }
   
    // now figure out if we are within a bridge/tunnel
    } else {
     
      // are there roads from here?
      if (isBridgeTowardsNorth(x, z) &&
        isBridgeTowardsSouth(x, z)) {
        roadToNorth = true;
        roadToSouth = true;
        roadHere = true;
       
      } else if (isBridgeTowardsEast(x, z) &&
             isBridgeTowardsWest(x, z)) {
        roadToEast = true;
        roadToWest = true;
        roadHere = true;
      }
    }
   
    // now place any remaining roads we need
    if (roadHere)
      paveLot(x, z, false);
    if (roadToNorth) {
      paveLot(x, z - 1, false);
      paveLot(x, z - 2, false);
    }
    if (roadToSouth) {
      paveLot(x, z + 1, false);
      paveLot(x, z + 2, false);
    }
    if (roadToEast) {
      paveLot(x + 1, z, false);
      paveLot(x + 2, z, false);
    }
    if (roadToWest) {
      paveLot(x - 1, z, false);
      paveLot(x - 2, z, false);
    }
  }
 
  private boolean isRoadTowards(int x, int z, int deltaX, int deltaZ) {
   
    // is this a "real" spot?
    boolean result = HeightInfo.isBuildableAt(generator, (originX + x + deltaX) * SupportChunk.chunksBlockWidth,
                                   (originZ + z + deltaZ) * SupportChunk.chunksBlockWidth);
   
    // if this isn't a buildable spot, is there a bridge or tunnel that gets us there?
    if (!result)
      result = isBridgeTowards(x, z, deltaX, deltaZ);
   
    // report back
    return result;
  }
 
  public boolean isBridgeTowardsNorth(int x, int z) {
    return isBridgeTowards(x, z, 0, -5);
  }
 
  public boolean isBridgeTowardsSouth(int x, int z) {
    return isBridgeTowards(x, z, 0, 5);
  }
 
  public boolean isBridgeTowardsWest(int x, int z) {
    return isBridgeTowards(x, z, -5, 0);
  }
 
  public boolean isBridgeTowardsEast(int x, int z) {
    return isBridgeTowards(x, z, 5, 0);
  }
 
  private boolean isBridgeTowards(int x, int z, int deltaX, int deltaZ) {
   
    // how far do we go?
    int offsetX = deltaX * SupportChunk.chunksBlockWidth;
    int offsetZ = deltaZ * SupportChunk.chunksBlockWidth;
   
    // where do we test?
    int chunkX = (originX + x) * SupportChunk.chunksBlockWidth;
    int chunkZ = (originZ + z) * SupportChunk.chunksBlockWidth;
   
    // what is the polarity of this spot
    boolean originPolarity = generator.shapeProvider.getBridgePolarityAt(chunkX, chunkZ);
    boolean currentPolarity = originPolarity;
   
    // short cut things a bit by looking for impossible things (polarity doesn't match the delta values)
    if (originPolarity) {
      if (deltaX != 0)
        return false;
    } else {
      if (deltaZ != 0)
        return false;
    }
   
    // keep searching in the delta direction until polarity shifts
    while (originPolarity == currentPolarity) {
     
      // move it along a bit
      chunkX += offsetX;
      chunkZ += offsetZ;
     
      //TODO should test for a maximum length of bridge/tunnel
     
      // keep going as long it is the same polarity
      currentPolarity = generator.shapeProvider.getBridgePolarityAt(chunkX, chunkZ);
     
      // did we found a "real" spot and the polarity is still the same
      if (currentPolarity == originPolarity && HeightInfo.isBuildableAt(generator, chunkX, chunkZ))
        return true;
    };
   
    // we have failed to find a real bridge/tunnel
    return false;
  }

  private final static int maxPlaceTries = 16;
  public void placeSpecificClip(WorldGenerator generator, Odds odds, Clipboard clip) {
    int chunksX = clip.chunkX;
    int chunksZ = clip.chunkZ;
   
    // find a lot that fits into the current platmap
    for (int attempt = 0; attempt < maxPlaceTries; attempt++) {
      int placeX = odds.getRandomInt(PlatMap.Width - chunksX);
      int placeZ = odds.getRandomInt(PlatMap.Width - chunksZ);
     
      // is this space completely empty?
      boolean empty = true;
      for (int x = placeX; x < placeX + chunksX; x++) {
        for (int z = placeZ; z < placeZ + chunksZ; z++) {
          empty = platLots[x][z] == null;
          if (!empty)
            break;
        }
        if (!empty)
          break;
      }
       
      // found one?
      if (empty) {
       
        // put it there
        placeSpecificClip(generator, odds, clip, placeX, placeZ);
       
        // all done
        return;
      }
    }
  }

  public void placeSpecificClip(WorldGenerator generator, Odds odds, Clipboard clip, int placeX, int placeZ) {
    int chunksX = clip.chunkX;
    int chunksZ = clip.chunkZ;
   
    // what way are we facing?
    BlockFace facing = odds.getRandomFacing();
   
    // calculate the various template plats
    for (int x = 0; x < chunksX; x++) {
      for (int z = 0; z < chunksZ; z++) {
        setLot(placeX + x, placeZ + z, new ClipboardLot(this,
                                originX + placeX + x, originZ + placeZ + z,
                                clip, facing, x, z));
      }
    }
  }
}
TOP

Related Classes of me.daddychurchill.CityWorld.Support.PlatMap

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.