Push of current world generation code. Doesn't compile yet.
This commit is contained in:
parent
48a003012a
commit
858874b66b
9 changed files with 506 additions and 0 deletions
|
@ -9,6 +9,8 @@ import com.zixiken.dimdoors.shared.items.ModItems;
|
|||
import com.zixiken.dimdoors.shared.RiftRegistry;
|
||||
import com.zixiken.dimdoors.shared.SchematicHandler;
|
||||
import com.zixiken.dimdoors.shared.util.DefaultSchematicGenerator;
|
||||
import com.zixiken.dimdoors.shared.world.gateways.GatewayGenerator;
|
||||
import lombok.Getter;
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -19,6 +21,7 @@ import net.minecraftforge.fml.common.FMLLog;
|
|||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.SidedProxy;
|
||||
import net.minecraftforge.fml.common.event.*;
|
||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
|
@ -29,6 +32,7 @@ public class DimDoors {
|
|||
|
||||
public static final String MODID = "dimdoors";
|
||||
public static final String VERSION = "${version}";
|
||||
@Getter private GatewayGenerator gatewayGenerator;
|
||||
|
||||
@SidedProxy(clientSide = "com.zixiken.dimdoors.client.DDProxyClient",
|
||||
serverSide = "com.zixiken.dimdoors.server.DDProxyServer")
|
||||
|
@ -45,6 +49,7 @@ public class DimDoors {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
@Mod.EventHandler
|
||||
public void onPreInitialization(FMLPreInitializationEvent event) {
|
||||
proxy.onPreInitialization(event);
|
||||
|
@ -54,6 +59,8 @@ public class DimDoors {
|
|||
@Mod.EventHandler
|
||||
public void onInitialization(FMLInitializationEvent event) {
|
||||
proxy.onInitialization(event);
|
||||
gatewayGenerator = new GatewayGenerator();
|
||||
GameRegistry.registerWorldGenerator(gatewayGenerator, 0);
|
||||
}
|
||||
|
||||
@Mod.EventHandler
|
||||
|
|
|
@ -11,6 +11,8 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.zixiken.dimdoors.shared.world.gateways.DimensionFilter;
|
||||
import com.zixiken.dimdoors.shared.world.gateways.GatewayGenerator;
|
||||
import lombok.Getter;
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
import net.minecraftforge.common.config.Property;
|
||||
|
@ -44,6 +46,18 @@ public class DDConfig {
|
|||
@Getter private static boolean dangerousLimboMonolithsEnabled = false;
|
||||
@Getter private static boolean monolithTeleportationEnabled = true;
|
||||
|
||||
@Getter private static int clusterGenerationChance;
|
||||
@Getter private static int gatewayGenerationChance;
|
||||
|
||||
@Getter private static boolean limboEscapeEnabled;
|
||||
@Getter private static boolean universalLimboEnabled;
|
||||
|
||||
@Getter private static DimensionFilter riftClusterDimensions;
|
||||
@Getter private static DimensionFilter riftGatewayDimensions;
|
||||
|
||||
//Names of categories
|
||||
private static final String CATEGORY_WORLD_GENERATION = "world generation";
|
||||
|
||||
private static int setConfigIntWithMaxAndMin(Configuration config, String category, String key, int defaultValue, String comment, int minValue, int maxValue) {
|
||||
Property prop = config.get(category, key, defaultValue, comment, minValue, maxValue);
|
||||
int value = prop.getInt(defaultValue);
|
||||
|
@ -122,6 +136,35 @@ public class DDConfig {
|
|||
publicPocketSize = setConfigIntWithMaxAndMin(config, "pocket_dimension", "publicPocketSize", publicPocketSize,
|
||||
"Sets how deep and wide any public pocket can be. [min: 0, max: maxPocketSize, default: 2]", 0, maxPocketSize);
|
||||
|
||||
clusterGenerationChance = config.get(Configuration.CATEGORY_GENERAL, "Cluster Generation Chance", 2,
|
||||
"Sets the chance (out of " + GatewayGenerator.MAX_CLUSTER_GENERATION_CHANCE + ") that a cluster of rifts will " +
|
||||
"generate in a given chunk. The default chance is 2.").getInt();
|
||||
|
||||
gatewayGenerationChance = config.get(Configuration.CATEGORY_GENERAL, "Gateway Generation Chance", 15,
|
||||
"Sets the chance (out of " + GatewayGenerator.MAX_GATEWAY_GENERATION_CHANCE + ") that a Rift Gateway will " +
|
||||
"generate in a given chunk. The default chance is 15.").getInt();
|
||||
|
||||
//World Generation
|
||||
config.addCustomCategoryComment(CATEGORY_WORLD_GENERATION,
|
||||
"The following settings require lists of dimensions in a specific format. " +
|
||||
"A list must consist of ranges separated by commas. A range may be a single number to indicate " +
|
||||
"just one dimension or two numbers in the form \"X - Y\". Spaces are permitted " +
|
||||
"but not required. Example: -100, -10 - -1, 20 - 30");
|
||||
|
||||
riftClusterDimensions = loadFilter(config, "Rift Cluster", "Rift Clusters");
|
||||
riftGatewayDimensions = loadFilter(config, "Rift Gateway", "Rift Gateways");
|
||||
|
||||
limboEscapeEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Limbo Escape", true,
|
||||
"Sets whether players are teleported out of Limbo when walking over the Eternal Fabric that " +
|
||||
"generates near the bottom of the dimension. If disabled, players could still leave through " +
|
||||
"dungeons in Limbo or by dying (if Hardcore Limbo is disabled). The default value is true.").getBoolean(true);
|
||||
|
||||
universalLimboEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Universal Limbo", false,
|
||||
"Sets whether players are teleported to Limbo when they die in any dimension (except Limbo). " +
|
||||
"Normally, players only go to Limbo if they die in a pocket dimension. This setting will not " +
|
||||
"affect deaths in Limbo, which can be set with the Hardcore Limbo option. " +
|
||||
"The default value is false.").getBoolean(false);
|
||||
|
||||
// Save config
|
||||
config.save();
|
||||
}
|
||||
|
@ -142,4 +185,27 @@ public class DDConfig {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static DimensionFilter loadFilter(Configuration config, String prefix, String description) {
|
||||
boolean enableBlacklist = config.get(CATEGORY_WORLD_GENERATION, "Enable " + prefix + " Blacklist", true,
|
||||
"Sets whether " + description + " will not generate in certain blacklisted dimensions. " +
|
||||
"If set to false, then " + description + " will follow a whitelist instead.").getBoolean(true);
|
||||
|
||||
String whitelist = config.get(CATEGORY_WORLD_GENERATION, prefix + " Whitelist", "",
|
||||
"A list of the only dimensions in which " + description + " may generate.").getString();
|
||||
|
||||
String blacklist = config.get(CATEGORY_WORLD_GENERATION, prefix + " Blacklist", "",
|
||||
"A list of dimensions in which " + description + " may not generate.").getString();
|
||||
|
||||
try {
|
||||
if (enableBlacklist) {
|
||||
return DimensionFilter.parseBlacklist(blacklist);
|
||||
} else {
|
||||
return DimensionFilter.parseWhitelist(whitelist);
|
||||
}
|
||||
} catch (Exception inner) {
|
||||
throw new RuntimeException("An error occurred while loading a whitelist or blacklist setting for " +
|
||||
description + ". Please make sure that your configuration file is set up correctly.", inner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
package com.zixiken.dimdoors.shared.world.gateways;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
||||
public abstract class BaseGateway {
|
||||
public BaseGateway() { }
|
||||
|
||||
/**
|
||||
* Generates the gateway centered on the given coordinates
|
||||
* @param world - the world in which to generate the gateway
|
||||
* @param x - the x-coordinate at which to center the gateway; usually where the door is placed
|
||||
* @param y - the y-coordinate of the block on which the gateway may be built
|
||||
* @param z - the z-coordinate at which to center the gateway; usually where the door is placed
|
||||
*/
|
||||
public abstract boolean generate(World world, int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Determines whether the specified biome is a valid biome in which to generate this gateway
|
||||
* @param biome - the biome to be checked
|
||||
* @return <code>true</code> true if the specified biome is a valid for generating this gateway, otherwise <code>false</code>
|
||||
*/
|
||||
protected boolean isBiomeValid(Biome biome) {
|
||||
Biome[] biomes = this.getBiomes();
|
||||
if (biomes != null) {
|
||||
for (Biome b : biomes) {
|
||||
if (b.equals(biome)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the specified world and coordinates are a valid location for generating this gateway
|
||||
* @param world - the world in which to generate the gateway
|
||||
* @param x - the x-coordinate at which to center the gateway; usually where the door is placed
|
||||
* @param y - the y-coordinate of the block on which the gateway may be built
|
||||
* @param z - the z-coordinate at which to center the gateway; usually where the door is placed
|
||||
* @return <code>true</code> if the location is valid, otherwise <code>false</code>
|
||||
*/
|
||||
public boolean isLocationValid(World world, int x, int y, int z)
|
||||
{
|
||||
return isBiomeValid(world.getBiome(new BlockPos(x,y,z)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lowercase keywords to be used in checking whether a given biome is a valid location for this gateway
|
||||
* @return an array of biome keywords to match against
|
||||
*/
|
||||
public Biome[] getBiomes() {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package com.zixiken.dimdoors.shared.world.gateways;
|
||||
|
||||
import com.zixiken.dimdoors.DimDoors;
|
||||
import com.zixiken.dimdoors.shared.SchematicHandler;
|
||||
import com.zixiken.dimdoors.shared.util.Schematic;
|
||||
import com.zixiken.dimdoors.shared.util.SchematicConverter;
|
||||
import net.minecraft.nbt.CompressedStreamTools;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public abstract class BaseSchematicGateway extends BaseGateway {
|
||||
private Schematic schematic;
|
||||
|
||||
public BaseSchematicGateway(String name) {
|
||||
String schematicJarDirectory = "/assets/dimdoors/gateways/";
|
||||
|
||||
//Initialising the possible locations/formats for the schematic file
|
||||
InputStream oldVersionSchematicStream = DimDoors.class.getResourceAsStream(schematicJarDirectory + name + ".schematic"); //@todo also check for other schematics
|
||||
|
||||
//determine which location to load the schematic file from (and what format)
|
||||
DataInputStream schematicDataStream = null;
|
||||
boolean streamOpened = false;
|
||||
if (oldVersionSchematicStream != null) {
|
||||
schematicDataStream = new DataInputStream(oldVersionSchematicStream);
|
||||
streamOpened = true;
|
||||
} else {
|
||||
DimDoors.warn(SchematicHandler.class, "Schematic '" + name + "' was not found in the jar or config directory, neither with the .schem extension, nor with the .schematic extension.");
|
||||
}
|
||||
|
||||
NBTTagCompound schematicNBT;
|
||||
this.schematic = null;
|
||||
if (streamOpened) {
|
||||
try {
|
||||
schematicNBT = CompressedStreamTools.readCompressed(schematicDataStream);
|
||||
schematic = SchematicConverter.loadOldDimDoorSchematicFromNBT(schematicNBT, name);
|
||||
schematicDataStream.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SchematicHandler.class.getName()).log(Level.SEVERE, "Schematic file for " + name + " could not be read as a valid schematic NBT file.", ex);
|
||||
} finally {
|
||||
try {
|
||||
schematicDataStream.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(SchematicHandler.class.getName()).log(Level.SEVERE, "Error occured while closing schematicDataStream", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generate(World world, int x, int y, int z) {
|
||||
Schematic.place(schematic, world, x, y, z);
|
||||
this.generateRandomBits(world, x, y, z);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates randomized portions of the gateway structure (e.g. rubble, foliage)
|
||||
*
|
||||
* @param world - the world in which to generate the gateway
|
||||
* @param x - the x-coordinate at which to center the gateway; usually where the door is placed
|
||||
* @param y - the y-coordinate of the block on which the gateway may be built
|
||||
* @param z - the z-coordinate at which to center the gateway; usually where the door is placed
|
||||
*/
|
||||
protected void generateRandomBits(World world, int x, int y, int z) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package com.zixiken.dimdoors.shared.world.gateways;
|
||||
|
||||
import com.google.common.collect.Range;
|
||||
import com.google.common.collect.RangeSet;
|
||||
import com.google.common.collect.TreeRangeSet;
|
||||
|
||||
public class DimensionFilter {
|
||||
private RangeSet<Integer> blacklist;
|
||||
|
||||
private DimensionFilter(RangeSet<Integer> blacklist) {
|
||||
this.blacklist = blacklist;
|
||||
}
|
||||
|
||||
public boolean isAccepted(int dimensionID) {
|
||||
return !blacklist.contains(dimensionID);
|
||||
}
|
||||
|
||||
public boolean isRejected(int dimensionID) {
|
||||
return blacklist.contains(dimensionID);
|
||||
}
|
||||
|
||||
private static RangeSet<Integer> parseRangeSet(String list) {
|
||||
int index;
|
||||
int start;
|
||||
int end;
|
||||
String startPart;
|
||||
String endPart;
|
||||
String[] intervals;
|
||||
RangeSet<Integer> ranges = TreeRangeSet.create();
|
||||
|
||||
// Strip out all whitespace characters
|
||||
list = list.replaceAll("\\s", "");
|
||||
if (list.isEmpty()) {
|
||||
return ranges;
|
||||
}
|
||||
intervals = list.split(",");
|
||||
|
||||
// Iterate over all the interval strings
|
||||
for (String interval : intervals) {
|
||||
// Check if the interval contains a minus sign after the first character
|
||||
// That indicates that we're dealing with an interval and not a single number
|
||||
if (interval.length() > 1) {
|
||||
index = interval.indexOf("-", 1);
|
||||
} else {
|
||||
index = -1;
|
||||
} try {
|
||||
if (index >= 0) {
|
||||
// Parse this as a range with two values as endpoints
|
||||
startPart = interval.substring(0, index);
|
||||
endPart = interval.substring(index + 1);
|
||||
start = Integer.parseInt(startPart);
|
||||
end = Integer.parseInt(endPart);
|
||||
} else {
|
||||
// Parse this as a single value
|
||||
start = Integer.parseInt(interval);
|
||||
end = start;
|
||||
}
|
||||
// Add the interval to the set of intervals
|
||||
ranges.add( Range.closed(start, end) );
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException("\"" + interval + "\" is not a valid value or range for dimension IDs");
|
||||
}
|
||||
}
|
||||
|
||||
return ranges;
|
||||
}
|
||||
|
||||
public static DimensionFilter parseWhitelist(String list) {
|
||||
return new DimensionFilter(parseRangeSet(list).complement());
|
||||
}
|
||||
|
||||
public static DimensionFilter parseBlacklist(String list) {
|
||||
return new DimensionFilter(parseRangeSet(list));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
package com.zixiken.dimdoors.shared.world.gateways;
|
||||
|
||||
import com.zixiken.dimdoors.shared.DDConfig;
|
||||
import com.zixiken.dimdoors.shared.PocketRegistry;
|
||||
import com.zixiken.dimdoors.shared.blocks.ModBlocks;
|
||||
import com.zixiken.dimdoors.shared.world.PocketProvider;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.IChunkProvider;
|
||||
import net.minecraft.world.gen.IChunkGenerator;
|
||||
import net.minecraftforge.fml.common.IWorldGenerator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
public class GatewayGenerator implements IWorldGenerator
|
||||
{
|
||||
public static final int MAX_GATEWAY_GENERATION_CHANCE = 10000;
|
||||
public static final int MAX_CLUSTER_GENERATION_CHANCE = 10000;
|
||||
private static final int CLUSTER_GROWTH_CHANCE = 80;
|
||||
private static final int MAX_CLUSTER_GROWTH_CHANCE = 100;
|
||||
private static final int MIN_RIFT_Y = 4;
|
||||
private static final int MAX_RIFT_Y = 240;
|
||||
private static final int CHUNK_LENGTH = 16;
|
||||
private static final int GATEWAY_RADIUS = 4;
|
||||
private static final int MAX_GATEWAY_GENERATION_ATTEMPTS = 10;
|
||||
private static final int OVERWORLD_DIMENSION_ID = 0;
|
||||
private static final int NETHER_DIMENSION_ID = -1;
|
||||
private static final int END_DIMENSION_ID = 1;
|
||||
|
||||
private ArrayList<BaseGateway> gateways;
|
||||
private BaseGateway defaultGateway;
|
||||
|
||||
public GatewayGenerator() {
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
gateways = new ArrayList<>();
|
||||
defaultGateway = new GatewayTwoPillars();
|
||||
|
||||
// Add gateways here
|
||||
gateways.add(new GatewaySandstonePillars());
|
||||
gateways.add(new GatewayLimbo());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkGenerator chunkGenerator, IChunkProvider chunkProvider) {
|
||||
// Don't generate rifts or gateways if the current world is a pocket dimension or the world is remote.
|
||||
// Also don't generate anything in the Nether, The End, or in Witchery's Spirit World.
|
||||
// We only match against Spirit World using hashing to speed up the process a little (hopefully).
|
||||
int dimensionID = world.provider.getDimension();
|
||||
if (world.isRemote || (world.provider instanceof PocketProvider) || (dimensionID == END_DIMENSION_ID) || (dimensionID == NETHER_DIMENSION_ID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int x, y, z;
|
||||
int attempts;
|
||||
boolean valid;
|
||||
|
||||
// Check if we're allowed to generate rift clusters in this dimension.
|
||||
// If so, randomly decide whether to one.
|
||||
if (DDConfig.getRiftClusterDimensions().isAccepted(dimensionID) && random.nextInt(MAX_CLUSTER_GENERATION_CHANCE) < DDConfig.getClusterGenerationChance()) {
|
||||
do {
|
||||
//Pick a random point on the surface of the chunk
|
||||
x = chunkX * CHUNK_LENGTH + random.nextInt(CHUNK_LENGTH);
|
||||
z = chunkZ * CHUNK_LENGTH + random.nextInt(CHUNK_LENGTH);
|
||||
y = world.getHeight(x, z);
|
||||
|
||||
//If the point is within the acceptable altitude range, the block above is empty, and we're
|
||||
//not building on bedrock, then generate a rift there
|
||||
if (y >= MIN_RIFT_Y && y <= MAX_RIFT_Y && world.isAirBlock(new BlockPos(x, y + 1, z)) &&
|
||||
world.getBlockState(new BlockPos(x, y, z)).getBlock() != Blocks.BEDROCK && //<-- Stops Nether roof spawning. DO NOT REMOVE!
|
||||
world.getBlockState(new BlockPos(x, y - 1, z)).getBlock() != Blocks.BEDROCK &&
|
||||
world.getBlockState(new BlockPos(x, y - 2, z)).getBlock() != Blocks.BEDROCK) {
|
||||
//Create a link. If this is not the first time, create a child link and connect it to the first link.
|
||||
world.setBlockState(new BlockPos(x,y,z), ModBlocks.RIFT.getDefaultState());
|
||||
}
|
||||
}
|
||||
//Randomly decide whether to repeat the process and add another rift to the cluster
|
||||
while (random.nextInt(MAX_CLUSTER_GROWTH_CHANCE) < CLUSTER_GROWTH_CHANCE);
|
||||
}
|
||||
|
||||
// Check if we can place a Rift Gateway in this dimension, then randomly decide whether to place one.
|
||||
// This only happens if a rift cluster was NOT generated.
|
||||
else if (DDConfig.getRiftGatewayDimensions().isAccepted(dimensionID) && random.nextInt(MAX_GATEWAY_GENERATION_CHANCE) < DDConfig.getGatewayGenerationChance()) {
|
||||
valid = false;
|
||||
x = y = z = 0; //Stop the compiler from freaking out
|
||||
|
||||
//Check locations for the gateway until we are satisfied or run out of attempts.
|
||||
for (attempts = 0; attempts < MAX_GATEWAY_GENERATION_ATTEMPTS && !valid; attempts++) {
|
||||
//Pick a random point on the surface of the chunk and check its materials
|
||||
x = chunkX * CHUNK_LENGTH + random.nextInt(CHUNK_LENGTH);
|
||||
z = chunkZ * CHUNK_LENGTH + random.nextInt(CHUNK_LENGTH);
|
||||
y = world.getHeight(x, z);
|
||||
valid = checkGatewayLocation(world, new BlockPos(x, y, z));
|
||||
}
|
||||
|
||||
// Build the gateway if we found a valid location
|
||||
if (valid) {
|
||||
ArrayList<BaseGateway> validGateways = new ArrayList<BaseGateway>();
|
||||
for (BaseGateway gateway : gateways) {
|
||||
if (gateway.isLocationValid(world, x, y, z)) {
|
||||
validGateways.add(gateway);
|
||||
}
|
||||
}
|
||||
// Add the default gateway if the rest were rejected
|
||||
if (validGateways.isEmpty()) {
|
||||
validGateways.add(defaultGateway);
|
||||
}
|
||||
// Randomly select a gateway from the pool of viable gateways
|
||||
validGateways.get(random.nextInt(validGateways.size())).generate(world, x, y - 1, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkGatewayLocation(World world, BlockPos pos) {
|
||||
//Check if the point is within the acceptable altitude range, the block above that point is empty,
|
||||
//and the block two levels down is opaque and has a reasonable material. Plus that we're not building
|
||||
//on top of bedrock.
|
||||
return (pos.getY() >= MIN_RIFT_Y && pos.getY() <= MAX_RIFT_Y &&
|
||||
world.isAirBlock(pos.up()) &&
|
||||
world.getBlockState(pos).getBlock() != Blocks.BEDROCK && //<-- Stops Nether roof spawning. DO NOT REMOVE!
|
||||
world.getBlockState(pos.down()) != Blocks.BEDROCK &&
|
||||
checkFoundationMaterial(world, pos.down()));
|
||||
}
|
||||
|
||||
private static boolean checkFoundationMaterial(World world, BlockPos pos) {
|
||||
//We check the material and opacity to prevent generating gateways on top of trees or houses,
|
||||
//or on top of strange things like tall grass, water, slabs, or torches.
|
||||
//We also want to avoid generating things on top of the Nether's bedrock!
|
||||
Material material = world.getBlockState(pos).getMaterial();
|
||||
return (material != Material.LEAVES && material != Material.WOOD && material != Material.GOURD
|
||||
&& world.isBlockNormalCube(pos, false) && world.getBlockState(pos).getBlock() != Blocks.BEDROCK);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.zixiken.dimdoors.shared.world.gateways;
|
||||
|
||||
import com.zixiken.dimdoors.shared.blocks.BlockFabric;
|
||||
import com.zixiken.dimdoors.shared.blocks.ModBlocks;
|
||||
import com.zixiken.dimdoors.shared.world.limbodimension.WorldProviderLimbo;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.item.ItemDoor;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class GatewayLimbo extends BaseGateway {
|
||||
@Override
|
||||
public boolean generate(World world, int x, int y, int z)
|
||||
{
|
||||
IBlockState limbo = ModBlocks.FABRIC.getDefaultState().withProperty(BlockFabric.TYPE, BlockFabric.EnumType.UNRAVELED);
|
||||
// Build the gateway out of Unraveled Fabric. Since nearly all the blocks in Limbo are of
|
||||
// that type, there is no point replacing the ground.
|
||||
world.setBlockState(new BlockPos(x, y + 3, z + 1), limbo);
|
||||
world.setBlockState(new BlockPos(x, y + 3, z - 1), limbo);
|
||||
|
||||
// Build the columns around the door
|
||||
world.setBlockState(new BlockPos(x, y + 2, z - 1), limbo);
|
||||
world.setBlockState(new BlockPos(x, y + 2, z + 1), limbo);
|
||||
world.setBlockState(new BlockPos(x, y + 1, z - 1), limbo);
|
||||
world.setBlockState(new BlockPos(x, y + 1, z + 1), limbo);
|
||||
|
||||
ItemDoor.placeDoor(world, new BlockPos(x, y + 1, z), EnumFacing.getHorizontal(0), ModBlocks.TRANSIENT_DIMENSIONAL_DOOR, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocationValid(World world, int x, int y, int z) {
|
||||
return world.provider instanceof WorldProviderLimbo;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.zixiken.dimdoors.shared.world.gateways;
|
||||
|
||||
import net.minecraft.init.Biomes;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
||||
public class GatewaySandstonePillars extends BaseSchematicGateway {
|
||||
public GatewaySandstonePillars() {
|
||||
super("sandstonePillars");
|
||||
}
|
||||
|
||||
public Biome[] getBiomes() {
|
||||
return new Biome[] {Biomes.DESERT, Biomes.DESERT_HILLS, Biomes.MUTATED_DESERT};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.zixiken.dimdoors.shared.world.gateways;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class GatewayTwoPillars extends BaseSchematicGateway {
|
||||
private static final int GATEWAY_RADIUS = 4;
|
||||
|
||||
public GatewayTwoPillars() {
|
||||
super("twoPillars");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateRandomBits(World world, int x, int y, int z) {
|
||||
IBlockState state = Blocks.STONEBRICK.getDefaultState();
|
||||
|
||||
//Replace some of the ground around the gateway with bricks
|
||||
for (int xc = -GATEWAY_RADIUS; xc <= GATEWAY_RADIUS; xc++) {
|
||||
for (int zc = -GATEWAY_RADIUS; zc <= GATEWAY_RADIUS; zc++) {
|
||||
//Check that the block is supported by an opaque block.
|
||||
//This prevents us from building over a cliff, on the peak of a mountain,
|
||||
//or the surface of the ocean or a frozen lake.
|
||||
if (world.getBlockState(new BlockPos(x + xc, y - 1, z + zc)).getMaterial().isSolid()) {
|
||||
//Randomly choose whether to place bricks or not. The math is designed so that the
|
||||
//chances of placing a block decrease as we get farther from the gateway's center.
|
||||
if (Math.abs(xc) + Math.abs(zc) < world.rand.nextInt(2) + 3) {
|
||||
//Place Stone Bricks
|
||||
world.setBlockState(new BlockPos(x + xc, y, z + zc), state);
|
||||
} else if (Math.abs(xc) + Math.abs(zc) < world.rand.nextInt(3) + 3) {
|
||||
//Place Cracked Stone Bricks
|
||||
world.setBlockState(new BlockPos(x + xc, y, z + zc), state); //TODO find out what the data for cracked Stonebrick is.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue