Improved Rift Gateway Generation and Fixed Several Bugs #26

Merged
SenseiKiwi merged 7 commits from master into master 2013-06-17 21:16:09 +00:00
4 changed files with 232 additions and 204 deletions

View File

@@ -3,6 +3,7 @@ package StevenDimDoors.mod_pocketDim;
import java.util.Random; import java.util.Random;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.chunk.IChunkProvider;
import StevenDimDoors.mod_pocketDim.helpers.dimHelper; import StevenDimDoors.mod_pocketDim.helpers.dimHelper;
@@ -20,6 +21,7 @@ public class RiftGenerator implements IWorldGenerator
private static final int MAX_RIFT_Y = 250; private static final int MAX_RIFT_Y = 250;
private static final int CHUNK_LENGTH = 16; private static final int CHUNK_LENGTH = 16;
private static final int GATEWAY_RADIUS = 4; private static final int GATEWAY_RADIUS = 4;
private static final int MAX_GATEWAY_GENERATION_ATTEMPTS = 10;
private static DDProperties properties = null; private static DDProperties properties = null;
public RiftGenerator() public RiftGenerator()
@@ -39,7 +41,9 @@ public class RiftGenerator implements IWorldGenerator
} }
int x, y, z; int x, y, z;
int attempts;
int blockID; int blockID;
boolean valid;
LinkData link; LinkData link;
//Randomly decide whether to place a cluster of rifts here //Randomly decide whether to place a cluster of rifts here
@@ -49,12 +53,16 @@ public class RiftGenerator implements IWorldGenerator
do do
{ {
//Pick a random point on the surface of the chunk //Pick a random point on the surface of the chunk
x = chunkX * CHUNK_LENGTH - random.nextInt(CHUNK_LENGTH); x = chunkX * CHUNK_LENGTH + random.nextInt(CHUNK_LENGTH);
z = chunkZ * CHUNK_LENGTH - random.nextInt(CHUNK_LENGTH); z = chunkZ * CHUNK_LENGTH + random.nextInt(CHUNK_LENGTH);
y = world.getHeightValue(x, z); y = world.getHeightValue(x, z);
//If the point is within the acceptable altitude range and the block above is empty, then place a rift //If the point is within the acceptable altitude range, the block above is empty, and we're
if (y >= MIN_RIFT_Y && y <= MAX_RIFT_Y && world.isAirBlock(x, y + 1, z)) //not building on bedrock, then generate a rift there
if (y >= MIN_RIFT_Y && y <= MAX_RIFT_Y && world.isAirBlock(x, y + 1, z) &&
world.getBlockId(x, y, z) != Block.bedrock.blockID && //<-- Stops Nether roof spawning. DO NOT REMOVE!
world.getBlockId(x, y - 1, z) != Block.bedrock.blockID &&
world.getBlockId(x, y - 2, z) != Block.bedrock.blockID)
{ {
//Create a link. If this is the first time, create a dungeon pocket and create a two-way link. //Create a link. If this is the first time, create a dungeon pocket and create a two-way link.
//Otherwise, create a one-way link and connect to the destination of the first link. //Otherwise, create a one-way link and connect to the destination of the first link.
@@ -77,15 +85,21 @@ public class RiftGenerator implements IWorldGenerator
//This only happens if a rift cluster was NOT generated. //This only happens if a rift cluster was NOT generated.
else if (random.nextInt(MAX_GATEWAY_GENERATION_CHANCE) < properties.GatewayGenerationChance) else if (random.nextInt(MAX_GATEWAY_GENERATION_CHANCE) < properties.GatewayGenerationChance)
{ {
//Pick a random point on the surface of the chunk valid = false;
x = chunkX * CHUNK_LENGTH - random.nextInt(CHUNK_LENGTH); x = y = z = 0; //Stop the compiler from freaking out
z = chunkZ * CHUNK_LENGTH - random.nextInt(CHUNK_LENGTH);
y = world.getHeightValue(x, z);
//Check if the point is within the acceptable altitude range, the block above that point is empty, //Check locations for the gateway until we are satisfied or run out of attempts.
//and at least one of the two blocks under that point are opaque for (attempts = 0; attempts < MAX_GATEWAY_GENERATION_ATTEMPTS && !valid; attempts++)
if (y >= MIN_RIFT_Y && y <= MAX_RIFT_Y && world.isAirBlock(x, y + 1, z) && {
world.isBlockOpaqueCube(x, y - 2, z) || world.isBlockOpaqueCube(x, y - 1, z)) //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.getHeightValue(x, z);
valid = checkGatewayLocation(world, x, y, z);
}
//Build the gateway if we found a valid location
if (valid)
{ {
//Create a two-way link between the upper block of the gateway and a pocket dimension //Create a two-way link between the upper block of the gateway and a pocket dimension
//That pocket dimension is where we'll start a dungeon! //That pocket dimension is where we'll start a dungeon!
@@ -112,39 +126,62 @@ public class RiftGenerator implements IWorldGenerator
if (Math.abs(xc) + Math.abs(zc) < random.nextInt(2) + 3) if (Math.abs(xc) + Math.abs(zc) < random.nextInt(2) + 3)
{ {
//Place Stone Bricks //Place Stone Bricks
world.setBlock(x + xc, y - 1, z + zc, blockID,0,2); world.setBlock(x + xc, y - 1, z + zc, blockID, 0, 3);
} }
else if (Math.abs(xc) + Math.abs(zc) < random.nextInt(3) + 3) else if (Math.abs(xc) + Math.abs(zc) < random.nextInt(3) + 3)
{ {
//Place Cracked Stone Bricks //Place Cracked Stone Bricks
world.setBlock(x + xc, y - 1, z + zc, blockID, 2, 2); world.setBlock(x + xc, y - 1, z + zc, blockID, 2, 3);
} }
} }
} }
} }
//Use Chiseled Stone Bricks to top off the pillars around the door //Use Chiseled Stone Bricks to top off the pillars around the door
world.setBlock(x, y + 2, z + 1, blockID, 3, 2); world.setBlock(x, y + 2, z + 1, blockID, 3, 3);
world.setBlock(x, y + 2, z - 1, blockID, 3, 2); world.setBlock(x, y + 2, z - 1, blockID, 3, 3);
} }
else else
{ {
//Build the gateway out of Unraveled Fabric. Since nearly all the blocks in Limbo are of //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. Just build the tops of the columns here. //that type, there is no point replacing the ground. Just build the tops of the columns here.
blockID = properties.LimboBlockID; blockID = properties.LimboBlockID;
world.setBlock(x, y + 2, z + 1, blockID, 0, 2); world.setBlock(x, y + 2, z + 1, blockID, 0, 3);
world.setBlock(x, y + 2, z - 1, blockID, 0, 2); world.setBlock(x, y + 2, z - 1, blockID, 0, 3);
} }
//Place the shiny transient door into a dungeon //Place the shiny transient door into a dungeon
ItemRiftBlade.placeDoorBlock(world, x, y + 1, z, 0, mod_pocketDim.transientDoor); ItemRiftBlade.placeDoorBlock(world, x, y + 1, z, 0, mod_pocketDim.transientDoor);
//Build the columns around the door //Build the columns around the door
world.setBlock(x, y + 1, z - 1, blockID, 0, 2); world.setBlock(x, y + 1, z - 1, blockID, 0, 3);
world.setBlock(x, y + 1, z + 1, blockID, 0, 2); world.setBlock(x, y + 1, z + 1, blockID, 0, 3);
world.setBlock(x, y, z - 1, blockID, 0, 2); world.setBlock(x, y, z - 1, blockID, 0, 3);
world.setBlock(x, y, z + 1, blockID, 0, 2); world.setBlock(x, y, z + 1, blockID, 0, 3);
} }
} }
} }
private static boolean checkGatewayLocation(World world, int x, int y, int z)
{
//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 (y >= MIN_RIFT_Y &&
y <= MAX_RIFT_Y &&
world.isAirBlock(x, y + 1, z) &&
world.getBlockId(x, y, z) != Block.bedrock.blockID && //<-- Stops Nether roof spawning. DO NOT REMOVE!
world.getBlockId(x, y - 1, z) != Block.bedrock.blockID &&
checkFoundationMaterial(world, x, y - 2, z));
}
private static boolean checkFoundationMaterial(World world, int x, int y, int z)
{
//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.getBlockMaterial(x, y, z);
return (material != Material.leaves && material != Material.wood && material != Material.pumpkin
&& world.isBlockOpaqueCube(x, y, z) && world.getBlockId(x, y, z) != Block.bedrock.blockID);
}
} }

View File

@@ -1,20 +1,14 @@
package StevenDimDoors.mod_pocketDim.commands; package StevenDimDoors.mod_pocketDim.commands;
import java.util.ArrayList; import java.util.Collection;
import cpw.mods.fml.common.FMLCommonHandler;
import StevenDimDoors.mod_pocketDim.DimData;
import StevenDimDoors.mod_pocketDim.DungeonGenerator;
import StevenDimDoors.mod_pocketDim.LinkData;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
import StevenDimDoors.mod_pocketDim.helpers.dimHelper;
import net.minecraft.command.CommandBase; import net.minecraft.command.CommandBase;
import net.minecraft.command.ICommandSender; import net.minecraft.command.ICommandSender;
import net.minecraft.util.MathHelper; import net.minecraft.util.MathHelper;
import net.minecraft.world.MinecraftException; import StevenDimDoors.mod_pocketDim.DungeonGenerator;
import net.minecraft.world.World; import StevenDimDoors.mod_pocketDim.LinkData;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
import StevenDimDoors.mod_pocketDim.helpers.dimHelper;
public class CommandAddDungeonRift extends CommandBase public class CommandAddDungeonRift extends CommandBase
{ {
@@ -54,39 +48,13 @@ public class CommandAddDungeonRift extends CommandBase
link = dimHelper.instance.createPocket(link,true, true); link = dimHelper.instance.createPocket(link,true, true);
} }
else if(var2.length!=0&&var2[0].equals("list")) else if (var2.length != 0 && var2[0].equals("list"))
{ {
for(DungeonGenerator dungeonGen : dungeonHelper.registeredDungeons) Collection<String> dungeonNames = dungeonHelper.getDungeonNames();
for (String name : dungeonNames)
{ {
String dungeonName =dungeonGen.schematicPath; getCommandSenderAsPlayer(var1).sendChatToPlayer(name);
if(dungeonName.contains("DimDoors_Custom_schematics"))
{
dungeonName= dungeonName.substring(dungeonName.indexOf("DimDoors_Custom_schematics")+26);
} }
dungeonName =dungeonName.replace("/", "").replace(".", "").replace("schematics", "").replace("schematic", "");
this.getCommandSenderAsPlayer(var1).sendChatToPlayer(dungeonName);
}
for(DungeonGenerator dungeonGen : dungeonHelper.customDungeons)
{
String dungeonName =dungeonGen.schematicPath;
if(dungeonName.contains("DimDoors_Custom_schematics"))
{
dungeonName= dungeonName.substring(dungeonName.indexOf("DimDoors_Custom_schematics")+26);
}
dungeonName =dungeonName.replace("/", "").replace(".", "").replace("schematics", "").replace("schematic", "");
this.getCommandSenderAsPlayer(var1).sendChatToPlayer(dungeonName);
}
} }
else if(var2.length!=0) else if(var2.length!=0)

View File

@@ -3,6 +3,8 @@ package StevenDimDoors.mod_pocketDim.helpers;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Random; import java.util.Random;
@@ -216,16 +218,19 @@ public class DungeonHelper
} }
} }
public void importCustomDungeons(String dir) public void importCustomDungeons(String path)
{ {
File file = new File(dir); File directory = new File(path);
File[] schematicNames = file.listFiles(); File[] schematicNames = directory.listFiles();
if (schematicNames!=null) if (schematicNames != null)
{ {
for(File schematicFile: schematicNames) for (File schematicFile: schematicNames)
{ {
this.registerCustomDungeon(schematicFile); if (schematicFile.getName().endsWith(SCHEMATIC_FILE_EXTENSION))
{
registerCustomDungeon(schematicFile);
}
} }
} }
} }
@@ -657,4 +662,36 @@ public class DungeonHelper
} }
dimHelper.dimList.get(incoming.destDimID).dungeonGenerator = dungeon; dimHelper.dimList.get(incoming.destDimID).dungeonGenerator = dungeon;
} }
public Collection<String> getDungeonNames() {
//Use a HashSet to guarantee that all dungeon names will be distinct.
//This shouldn't be necessary if we keep proper lists without repetitions,
//but it's a fool-proof workaround.
HashSet<String> dungeonNames = new HashSet<String>();
dungeonNames.addAll( parseDungeonNames(registeredDungeons) );
dungeonNames.addAll( parseDungeonNames(customDungeons) );
//Sort dungeon names alphabetically
ArrayList<String> sortedNames = new ArrayList<String>(dungeonNames);
Collections.sort(sortedNames);
return sortedNames;
}
private static ArrayList<String> parseDungeonNames(ArrayList<DungeonGenerator> dungeons)
{
String name;
File schematic;
ArrayList<String> names = new ArrayList<String>(dungeons.size());
for (DungeonGenerator dungeon : dungeons)
{
//Retrieve the file name and strip off the file extension
schematic = new File(dungeon.schematicPath);
name = schematic.getName();
name = name.substring(0, name.length() - SCHEMATIC_FILE_EXTENSION.length());
names.add(name);
}
return names;
}
} }

View File

@@ -93,17 +93,12 @@ public class ItemStableFabric extends Item
public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer) public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
{ {
if (this.isSteven(par3EntityPlayer))
if(this.isSteven(par3EntityPlayer))
{ {
new Spells(par3EntityPlayer, par1ItemStack.stackSize).cast(); new Spells(par3EntityPlayer, par1ItemStack.stackSize).cast();
//mod_pocketDim.proxy.startCasting(par3EntityPlayer, par1ItemStack.stackSize); //mod_pocketDim.proxy.startCasting(par3EntityPlayer, par1ItemStack.stackSize);
} }
Boolean didFindThing=false; Boolean didFindThing=false;
MovingObjectPosition hit = this.getMovingObjectPositionFromPlayer(par3EntityPlayer.worldObj, par3EntityPlayer, false ); MovingObjectPosition hit = this.getMovingObjectPositionFromPlayer(par3EntityPlayer.worldObj, par3EntityPlayer, false );
if(hit!=null&&!par2World.isRemote) if(hit!=null&&!par2World.isRemote)
@@ -143,44 +138,35 @@ public class ItemStableFabric extends Item
switch(link.linkOrientation) switch(link.linkOrientation)
{ {
case 0: cardinal = "East"; case 0:
cardinal = "East";
break; break;
case 1: cardinal = "South"; case 1:
cardinal = "South";
break; break;
case 2: cardinal = "West"; case 2:
cardinal = "West";
break; break;
case 3: cardinal = "North"; case 3:
cardinal = "North";
break; break;
} }
System.out.println("Link orientation is " + link.linkOrientation + "- "+cardinal); System.out.println("Link orientation is " + link.linkOrientation + " - " + cardinal);
} }
} }
} }
} }
return par1ItemStack; return par1ItemStack;
} }
public boolean isSteven(EntityPlayer player) public boolean isSteven(EntityPlayer player)
{ {
if(player.username=="stevenrs11"||player.username=="Stevenrs11"||player.username=="StevenRS11") return (player.username.equalsIgnoreCase("stevenrs11"));
{
return true;
}
return false;
} }
public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4) public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4)
{ {
} }
} }