/*
* This file is part of Matter Overdrive
* Copyright (c) 2015., Simeon Radivoev, All rights reserved.
*
* Matter Overdrive 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.
*
* Matter Overdrive 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 Matter Overdrive. If not, see <http://www.gnu.org/licenses>.
*/
package matteroverdrive.world;
import matteroverdrive.MatterOverdrive;
import matteroverdrive.data.world.GenPositionWorldData;
import matteroverdrive.data.world.WorldPosition2D;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkProvider;
import org.apache.logging.log4j.Level;
import java.util.Random;
/**
* Created by Simeon on 11/26/2015.
*/
public abstract class MOWorldGenBuilding extends MOImageGen implements IMOWorldGenBuilding {
int yOffset = -1;
int maxDistanceToAir = 2;
String name;
protected Block[] validSpawnBlocks;
public MOWorldGenBuilding(String name,ResourceLocation texture, int layerWidth,int layerHeight)
{
super(texture,layerWidth,layerHeight);
this.name = name;
validSpawnBlocks = new Block[] {Blocks.stone,Blocks.grass,Blocks.dirt};
}
@Override
public void generate(Random random, int x,int y,int z, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider,int layer,int placeNotify)
{
generateFromImage(world, random, x, y + getYOffset(), z,layer,placeNotify);
}
public boolean locationIsValidSpawn(World world, int i, int j, int k){
int distanceToAir = 0;
Block check = world.getBlock(i, j, k);
while (check != Blocks.air){
if (distanceToAir > getMaxDistanceToAir()){
return false;
}
distanceToAir++;
check = world.getBlock(i, j + distanceToAir, k);
}
j += distanceToAir - 1;
Block block = world.getBlock(i, j, k);
Block blockAbove = world.getBlock(i, j+1, k);
Block blockBelow = world.getBlock(i, j-1, k);
for (Block x : getValidSpawnBlocks()){
if (blockAbove != Blocks.air){
return false;
}
if (block == x){
return true;
}else if (block == Blocks.snow && blockBelow == x){
return true;
}
}
return false;
}
@Override
public String getName() {
return name;
}
public void setMaxDistanceToAir(int maxDistanceToAir)
{
this.maxDistanceToAir = maxDistanceToAir;
}
protected int getMaxDistanceToAir()
{
return maxDistanceToAir;
}
protected Block[] getValidSpawnBlocks() {
return validSpawnBlocks;
}
public int getYOffset()
{
return yOffset;
}
public void setyOffset(int yOffset)
{
this.yOffset = yOffset;
}
protected abstract void onGeneration(Random random,World world,int x,int y,int z);
protected abstract boolean shouldGenerate(Random random,World world,int x,int y,int z);
public abstract void onGenerationWorkerCreated(WorldGenBuildingWorker worldGenBuildingWorker);
protected boolean isLocationValid(World world,int x,int y,int z)
{
return locationIsValidSpawn(world, x, y, z) && locationIsValidSpawn(world, x + layerWidth, y, z) && locationIsValidSpawn(world, x + layerWidth, y, z + layerHeight) && locationIsValidSpawn(world, x, y, z + layerHeight);
}
public boolean isFarEnoughFromOthers(World world,int x,int z,int minDistance)
{
GenPositionWorldData worldData = MOWorldGen.getWorldPositionData(world);
if (worldData != null)
{
return worldData.isFarEnough(getName(),x,z,minDistance);
}
return true;
}
public WorldGenBuildingWorker createWorker(Random random,int x,int y,int z,World world,IChunkProvider chunkGenerator, IChunkProvider chunkProvider)
{
WorldGenBuildingWorker worldGenBuildingWorker = new WorldGenBuildingWorker(this,random,x,y,z,world,chunkGenerator,chunkProvider);
onGenerationWorkerCreated(worldGenBuildingWorker);
GenPositionWorldData data = MOWorldGen.getWorldPositionData(world);
data.addPosition(getName(),new WorldPosition2D(x+layerWidth/2,z+layerHeight/2));
return worldGenBuildingWorker;
}
public static class WorldGenBuildingWorker
{
int currentLayer;
Random random;
int x,y,z;
World world;
IChunkProvider chunkGenerator;
IChunkProvider chunkProvider;
MOWorldGenBuilding worldGenBuilding;
int placeNotify;
public WorldGenBuildingWorker(){}
public WorldGenBuildingWorker(MOWorldGenBuilding worldGenBuilding,Random random,int x,int y,int z,World world,IChunkProvider chunkGenerator, IChunkProvider chunkProvider)
{
init(worldGenBuilding,random,x,y,z,world,chunkGenerator,chunkProvider);
}
public WorldGenBuildingWorker init(MOWorldGenBuilding worldGenBuilding,Random random,int x,int y,int z,World world,IChunkProvider chunkGenerator, IChunkProvider chunkProvider)
{
this.worldGenBuilding = worldGenBuilding;
this.worldGenBuilding.manageTextureLoading();
this.x = x;
this.y = y;
this.z = z;
this.random = random;
this.world = world;
this.chunkGenerator = chunkGenerator;
this.chunkProvider = chunkProvider;
this.placeNotify = this.worldGenBuilding.placeNotify;
return this;
}
public boolean generate()
{
try
{
if (currentLayer >= worldGenBuilding.getLayerCount())
{
worldGenBuilding.onGeneration(random,world,x,y,z);
return true;
}else
{
worldGenBuilding.generate(random,x,y,z,world,chunkGenerator,chunkProvider,currentLayer,placeNotify);
currentLayer++;
return false;
}
}catch (Exception e)
{
MatterOverdrive.log.log(Level.ERROR,e,"There was a problem while generating layer %s of %s",currentLayer,worldGenBuilding.getName());
}
return false;
}
public WorldGenBuildingWorker setPlaceNotify(int placeNotify)
{
this.placeNotify = placeNotify;
return this;
}
}
}