185 lines
6.6 KiB
Java
Executable file
185 lines
6.6 KiB
Java
Executable file
package server.worldgen;
|
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
|
|
import common.block.Material;
|
|
import common.entity.npc.EntityArachnoid;
|
|
import common.entity.npc.EntityUndead;
|
|
import common.entity.npc.EntityZombie;
|
|
import common.entity.types.EntityLiving;
|
|
import common.init.Blocks;
|
|
import common.init.Items;
|
|
import common.item.RngLoot;
|
|
import common.rng.Random;
|
|
import common.rng.WeightedList;
|
|
import common.tileentity.TileEntity;
|
|
import common.tileentity.TileEntityChest;
|
|
import common.util.BlockPos;
|
|
import common.util.Facing;
|
|
import common.world.World;
|
|
import server.vars.SVars;
|
|
import server.world.WorldServer;
|
|
|
|
public class FeatureDungeons
|
|
{
|
|
private static final Class<? extends EntityLiving>[] MOB_TYPES = new Class[] {EntityUndead.class, EntityZombie.class, EntityZombie.class, EntityArachnoid.class};
|
|
|
|
private final int chance;
|
|
|
|
public FeatureDungeons(int chance) {
|
|
this.chance = chance;
|
|
}
|
|
|
|
|
|
public boolean generate(WorldServer worldIn, Random rand, BlockPos position) {
|
|
boolean flag = false;
|
|
for(int z = 0; z < this.chance; z++) {
|
|
flag |= this.generateDungeon(worldIn, rand, position.add(rand.chOffset(), rand.zrange(256), rand.chOffset()));
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
private boolean generateDungeon(WorldServer worldIn, Random rand, BlockPos position)
|
|
{
|
|
int i = 3;
|
|
int j = rand.zrange(2) + 2;
|
|
int k = -j - 1;
|
|
int l = j + 1;
|
|
int i1 = -1;
|
|
int j1 = 4;
|
|
int k1 = rand.zrange(2) + 2;
|
|
int l1 = -k1 - 1;
|
|
int i2 = k1 + 1;
|
|
int j2 = 0;
|
|
|
|
for (int k2 = k; k2 <= l; ++k2)
|
|
{
|
|
for (int l2 = -1; l2 <= 4; ++l2)
|
|
{
|
|
for (int i3 = l1; i3 <= i2; ++i3)
|
|
{
|
|
BlockPos blockpos = position.add(k2, l2, i3);
|
|
Material material = worldIn.getState(blockpos).getBlock().getMaterial();
|
|
boolean flag = material.isSolid();
|
|
|
|
if (l2 == -1 && !flag)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (l2 == 4 && !flag)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if ((k2 == k || k2 == l || i3 == l1 || i3 == i2) && l2 == 0 && worldIn.isAirBlock(blockpos) && worldIn.isAirBlock(blockpos.up()))
|
|
{
|
|
++j2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (j2 >= 1 && j2 <= 5)
|
|
{
|
|
for (int k3 = k; k3 <= l; ++k3)
|
|
{
|
|
for (int i4 = 3; i4 >= -1; --i4)
|
|
{
|
|
for (int k4 = l1; k4 <= i2; ++k4)
|
|
{
|
|
BlockPos blockpos1 = position.add(k3, i4, k4);
|
|
|
|
if (k3 != k && i4 != -1 && k4 != l1 && k3 != l && i4 != 4 && k4 != i2)
|
|
{
|
|
if (worldIn.getState(blockpos1).getBlock() != Blocks.chest)
|
|
{
|
|
worldIn.setBlockToAir(blockpos1);
|
|
}
|
|
}
|
|
else if (blockpos1.getY() >= 0 && !worldIn.getState(blockpos1.down()).getBlock().getMaterial().isSolid())
|
|
{
|
|
worldIn.setBlockToAir(blockpos1);
|
|
}
|
|
else if (worldIn.getState(blockpos1).getBlock().getMaterial().isSolid() && worldIn.getState(blockpos1).getBlock() != Blocks.chest)
|
|
{
|
|
if (i4 == -1 && rand.zrange(4) != 0)
|
|
{
|
|
worldIn.setState(blockpos1, Blocks.mossy_cobblestone.getState(), 2);
|
|
}
|
|
else
|
|
{
|
|
worldIn.setState(blockpos1, Blocks.cobblestone.getState(), 2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int l3 = 0; l3 < 2; ++l3)
|
|
{
|
|
for (int j4 = 0; j4 < 3; ++j4)
|
|
{
|
|
int l4 = position.getX() + rand.zrange(j * 2 + 1) - j;
|
|
int i5 = position.getY();
|
|
int j5 = position.getZ() + rand.zrange(k1 * 2 + 1) - k1;
|
|
BlockPos blockpos2 = new BlockPos(l4, i5, j5);
|
|
|
|
if (worldIn.isAirBlock(blockpos2))
|
|
{
|
|
int j3 = 0;
|
|
|
|
for (Facing enumfacing : Facing.Plane.HORIZONTAL)
|
|
{
|
|
if (worldIn.getState(blockpos2.offset(enumfacing)).getBlock().getMaterial().isSolid())
|
|
{
|
|
++j3;
|
|
}
|
|
}
|
|
|
|
if (j3 == 1)
|
|
{
|
|
worldIn.setState(blockpos2, Blocks.chest.correctFacing(worldIn, blockpos2, Blocks.chest.getState()), 2);
|
|
WeightedList<RngLoot> list = RngLoot.addToList(LootConstants.DUNGEON_CHEST, Items.enchanted_book.getRandom(rand));
|
|
TileEntity tileentity1 = worldIn.getTileEntity(blockpos2);
|
|
|
|
if (tileentity1 instanceof TileEntityChest)
|
|
{
|
|
RngLoot.generateChestContents(rand, list, (TileEntityChest)tileentity1, 8);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(SVars.mobs && SVars.spawnDungeonMobs > 0) {
|
|
for(int z = 0; z < SVars.spawnDungeonMobs; z++) {
|
|
EntityLiving entity = this.pickMobSpawner(rand, worldIn);
|
|
entity.setLocationAndAngles((double)position.getX() + rand.doublev(), (double)position.getY(), (double)position.getZ() + rand.doublev(), worldIn.rand.floatv() * 360.0F, 0.0F);
|
|
entity.onInitialSpawn(null);
|
|
worldIn.spawnEntityInWorld(entity);
|
|
if(rand.chance(5))
|
|
break;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private EntityLiving pickMobSpawner(Random rand, WorldServer world)
|
|
{
|
|
try {
|
|
return rand.pick(MOB_TYPES).getConstructor(World.class).newInstance(world);
|
|
}
|
|
catch(InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
}
|