Added Asteroid generation

Still untested prototype, and only generates core
This commit is contained in:
Francesco Macagno 2015-08-26 23:09:25 -07:00
parent b06a32b0bf
commit d3c6c7fb34
3 changed files with 75 additions and 43 deletions

View file

@ -1,13 +1,24 @@
package cr0s.warpdrive.config.structures;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.world.World;
import net.minecraft.world.gen.feature.WorldGenMinable;
import org.w3c.dom.Element;
import cr0s.warpdrive.config.InvalidXmlException;
public class Asteroid extends Orb {
public Asteroid(int diameter) {
super(diameter);
private Block coreBlock;
private int maxCoreSize, minCoreSize;
public Asteroid() {
super(0); //Diameter not relevant
}
@Override
@ -15,6 +26,35 @@ public class Asteroid extends Orb {
super.loadFromXmlElement(e);
String coreBlockName = e.getAttribute("coreBlock");
if (coreBlockName.isEmpty())
throw new InvalidXmlException("Asteroid is missing a coreBlock!");
coreBlock = Block.getBlockFromName(coreBlockName);
if (coreBlock == null)
throw new InvalidXmlException("Asteroid coreBlock doesnt exist!");
try {
maxCoreSize = Integer.parseInt(e.getAttribute("maxCoreSize"));
minCoreSize = Integer.parseInt(e.getAttribute("minCoreSize"));
} catch (NumberFormatException gdbg) {
throw new InvalidXmlException("Asteroid core size dimensions are NaN!");
}
}
@Override
public boolean generate(World world, Random rand, int x, int y, int z) {
int maxInc = maxCoreSize - minCoreSize;
new WorldGenMinable(coreBlock, minCoreSize + rand.nextInt(maxInc), Blocks.air).generate(world, rand, x, y, z);
//TODO: Build layer around it
return true;
}
}

View file

@ -23,6 +23,7 @@ public class StructureManager {
private static ArrayList<Star> stars = new ArrayList<Star>();
private static ArrayList<Planetoid> moons = new ArrayList<Planetoid>();
private static ArrayList<Planetoid> gasClouds = new ArrayList<Planetoid>();
private static ArrayList<Asteroid> asteroids = new ArrayList<Asteroid>();
public static void loadStructures(String structureConfDir) {
loadStructures(new File(structureConfDir));
@ -94,6 +95,10 @@ public class StructureManager {
Planetoid pl = new Planetoid(radius);
pl.loadFromXmlElement(struct);
moons.add(pl);
} else if (group.equalsIgnoreCase("asteroid")) {
Asteroid as = new Asteroid();
as.loadFromXmlElement(struct);
asteroids.add(as);
}
}
}
@ -106,6 +111,8 @@ public class StructureManager {
return stars.get(random.nextInt(stars.size()));
} else if (type.equalsIgnoreCase("moon")) {
return moons.get(random.nextInt(moons.size()));
} else if (type.equalsIgnoreCase("asteroid")) {
return asteroids.get(random.nextInt(asteroids.size()));
}
} else {
for (Star star : stars) {
@ -126,6 +133,10 @@ public class StructureManager {
return getStructure(random, name, "moon");
}
public static DeployableStructure getAsteroid(Random random, final String name) {
return getStructure(random, name, "asteroid");
}
public static DeployableStructure getGasCloud(Random random, final String name) {
return getStructure(random, name, "cloud");
}

View file

@ -2,8 +2,6 @@ package cr0s.warpdrive.world;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkProvider;
import cpw.mods.fml.common.IWorldGenerator;
@ -13,8 +11,8 @@ import cr0s.warpdrive.config.MetaBlock;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.config.structures.DeployableStructure;
import cr0s.warpdrive.config.structures.Orb;
import cr0s.warpdrive.config.structures.StructureManager;
import cr0s.warpdrive.config.structures.Orb.OrbShell;
import cr0s.warpdrive.config.structures.StructureManager;
/**
* @author Cr0s
@ -59,29 +57,16 @@ public class SpaceWorldGenerator implements IWorldGenerator {
}
int y = Y_LIMIT_SOFT_MIN + random.nextInt(Y_LIMIT_SOFT_MAX - Y_LIMIT_SOFT_MIN);
// Moon setup
if (random.nextInt(700) == 1)
if (random.nextInt(700) == 1) {
generateMoon(world, x, y, z, null);
// Simple asteroids
else if (random.nextInt(150) == 1) {
generateAsteroidOfBlock(world, x, y, z, 6, 11, null, 0);
// Simple asteroids
} else if (random.nextInt(150) == 1) {
generateRandomAsteroid(world, x, y, z);
// Random asteroid of block
} else if (random.nextInt(400) == 1) {
generateRandomAsteroid(world, x, y, z, 6, 11);
if (random.nextBoolean()) {
generateGasCloudOfColor(world, x, y, z, 6, 11, null);
}
} else if (random.nextInt(200) == 1) {// Ice asteroid
generateAsteroidOfBlock(world, x, y, z, 6, 11, Blocks.ice, 0);
} else if (random.nextInt(500) == 1) {// Asteroid field
generateAsteroidField(world, x, y, z);
} else if (random.nextInt(1400) == 1) {// Diamond asteroid
generateAsteroidOfBlock(world, x, y, z, 3, 2, Blocks.diamond_ore, 0);
// Diamond block core
world.setBlock(x, y, z, Blocks.diamond_block, 0, 2);
if (random.nextBoolean()) {
generateGasCloudOfColor(world, x, y, z, 6, 11, null);
}
}
} catch (Exception e) {
e.printStackTrace();
}
@ -90,7 +75,7 @@ public class SpaceWorldGenerator implements IWorldGenerator {
public static void generateMoon(World world, int x, int y, int z, final String moonName) {
DeployableStructure moon = StructureManager.getMoon(world.rand, moonName);
WarpDrive.logger.info("Generating moon (class " + moon + ") at " + x + " " + y + " " + z);
moon.generate(world, world.rand, x, y, z);
}
@ -117,11 +102,6 @@ public class SpaceWorldGenerator implements IWorldGenerator {
new WorldGenStation(world.rand.nextBoolean()).generate(world, world.rand, x2, y2, z2);
}
public static void generateRandomAsteroid(World world, int x, int y, int z, int asteroidSizeMax, int centerRadiusMax) {
generateAsteroidOfBlock(world, x, y, z, asteroidSizeMax, centerRadiusMax, null, 0);
}
private static float binomialRandom(World world) {
float linear = world.rand.nextFloat();
// ideal sphere repartition = x ^ 0.5 (sqrt)
@ -190,14 +170,14 @@ public class SpaceWorldGenerator implements IWorldGenerator {
int aX = (int) (x + Math.round(horizontalRange * Math.cos(bearing)));
int aY = (int) (y2 + Math.round(verticalRange * Math.cos(yawn)));
int aZ = (int) (z + Math.round(horizontalRange * Math.sin(bearing)));
if (WarpDriveConfig.LOGGING_WORLDGEN) {
System.out.println(String.format("Big asteroid: %.3f %.3f r %.3f r makes %3d, %3d, %3d",
new Object[] { Double.valueOf(binomial), Double.valueOf(bearing), Double.valueOf(yawn), Integer.valueOf(aX), Integer.valueOf(aY), Integer.valueOf(aZ) }));
}
// Place an asteroid
generateRandomAsteroid(world, aX, aY, aZ, 4, 6);
generateRandomAsteroid(world, aX, aY, aZ);
}
// Setting up small asteroids
@ -214,7 +194,7 @@ public class SpaceWorldGenerator implements IWorldGenerator {
// Placing
if (world.rand.nextInt(400) != 1) {
generateRandomAsteroid(world, aX, aY, aZ, 3, 3);
generateRandomAsteroid(world, aX, aY, aZ);
} else {
if (world.rand.nextInt(20) != 1) {
generateSmallShip(world, aX, aY, aZ, 8);
@ -267,13 +247,13 @@ public class SpaceWorldGenerator implements IWorldGenerator {
if (centerRadiusMax != 0)
centerRadius = Math.min(centerRadiusMax, centerRadius);
final int CENTER_SHIFT = 2; // Offset from center of central ball
DeployableStructure cloud = StructureManager.getGasCloud(world.rand, type);
if (cloud == null) {
WarpDrive.logger.error("No gaz cloud defined, cancelling world generation");
return;
}
for (int i = 1; i <= cloudSize; i++) {
int radius = 2 + world.rand.nextInt(centerRadius);
int newX = x + (((world.rand.nextBoolean()) ? -1 : 1) * world.rand.nextInt(CENTER_SHIFT + centerRadius / 2));
@ -292,14 +272,15 @@ public class SpaceWorldGenerator implements IWorldGenerator {
* coordinate of center
* @param z
* coordinate of center
* @param asteroidSizeMax
* maximum asteroid size (by number of balls it consists)
* @param centerRadiusMax
* maximum radius of central ball
*/
private static void generateAsteroidOfBlock(World world, int x, int y, int z, int asteroidSizeMax, int centerRadiusMax, Block ice, int meta) {
private static void generateRandomAsteroid(World world, int x, int y, int z) {
DeployableStructure asteroid = StructureManager.getAsteroid(world.rand, null);
WarpDrive.logger.info("Generating asteroid (class " + asteroid + ") at " + x + " " + y + " " + z);
asteroid.generate(world, world.rand, x, y, z);
/*
// FIXME: get a proper range of random instead of capping it
int asteroidSize = 1 + world.rand.nextInt(6);
if (asteroidSizeMax != 0) {
asteroidSize = Math.min(asteroidSizeMax, asteroidSize);
@ -329,7 +310,7 @@ public class SpaceWorldGenerator implements IWorldGenerator {
double radiusSq = radiusC * radiusC; // Optimization to avoid sqrts...
// sphere
int ceilRadius = (int) Math.ceil(radiusC);
// Pass the cube and check points for sphere equation x^2 + y^2 + z^2 = r^2
for (int x = 0; x <= ceilRadius; x++) {
double x2 = (x + 0.5D) * (x + 0.5D);
@ -347,7 +328,7 @@ public class SpaceWorldGenerator implements IWorldGenerator {
// Place blocks
// cheat by using axial symmetry so we don't create random numbers too frequently
OrbShell orbShell = orb.getShellForRadius(dSq);
MetaBlock metablock = orbShell.getRandomBlock(rand);
world.setBlock(xCoord + x, yCoord + y, zCoord + z, metablock.block, metablock.metadata, 2);