add gradle
This commit is contained in:
parent
bb6ebb0be8
commit
4e51e18bdc
3033 changed files with 470 additions and 0 deletions
1328
server/src/main/java/server/Server.java
Executable file
1328
server/src/main/java/server/Server.java
Executable file
File diff suppressed because it is too large
Load diff
22
server/src/main/java/server/biome/BiomeBeach.java
Executable file
22
server/src/main/java/server/biome/BiomeBeach.java
Executable file
|
@ -0,0 +1,22 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.init.Blocks;
|
||||
import common.rng.WeightedList;
|
||||
|
||||
public class BiomeBeach extends GenBiome
|
||||
{
|
||||
public BiomeBeach(boolean cold)
|
||||
{
|
||||
super(cold ? Biome.COLDBEACH : Biome.BEACH);
|
||||
this.topBlock = Blocks.sand.getState();
|
||||
this.fillerBlock = Blocks.sand.getState();
|
||||
this.treesPerChunk = -999;
|
||||
this.deadBushPerChunk = 0;
|
||||
this.reedsPerChunk = 0;
|
||||
this.cactiPerChunk = 0;
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
}
|
35
server/src/main/java/server/biome/BiomeBlackened.java
Normal file
35
server/src/main/java/server/biome/BiomeBlackened.java
Normal file
|
@ -0,0 +1,35 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.block.foliage.BlockFlower;
|
||||
import common.entity.npc.EntityMetalhead;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.util.BlockPos;
|
||||
import server.worldgen.tree.WorldGenBaseTree;
|
||||
import server.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeBlackened extends GenBiome {
|
||||
protected final WorldGenTree treeGen = new WorldGenBaseTree(false, Blocks.blackwood_log.getState(), Blocks.blackwood_leaves.getState());
|
||||
|
||||
public BiomeBlackened() {
|
||||
super(Biome.BLACKENED);
|
||||
this.topBlock = Blocks.blackened_soil.getState();
|
||||
this.fillerBlock = Blocks.blackened_dirt.getState();
|
||||
this.treesPerChunk = 3;
|
||||
this.generateLakes = false;
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
mobs.add(new RngSpawn(EntityMetalhead.class, 50, 1, 1));
|
||||
}
|
||||
|
||||
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos) {
|
||||
return BlockFlower.EnumFlowerType.BLACK_LOTUS;
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand) {
|
||||
return this.treeGen;
|
||||
}
|
||||
}
|
45
server/src/main/java/server/biome/BiomeChaos.java
Executable file
45
server/src/main/java/server/biome/BiomeChaos.java
Executable file
|
@ -0,0 +1,45 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.entity.Entity;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.init.Blocks;
|
||||
import common.init.EntityRegistry;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.util.BlockPos;
|
||||
import server.world.WorldServer;
|
||||
import server.worldgen.FeatureGenerator;
|
||||
import server.worldgen.foliage.WorldGenMushroom;
|
||||
|
||||
public class BiomeChaos extends GenBiome
|
||||
{
|
||||
protected FeatureGenerator mushroomBlueGen = new WorldGenMushroom(Blocks.blue_mushroom);
|
||||
|
||||
public BiomeChaos()
|
||||
{
|
||||
super(Biome.CHAOS);
|
||||
this.topBlock = Blocks.obsidian.getState();
|
||||
this.fillerBlock = Blocks.obsidian.getState();
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
for(Class<? extends Entity> clazz : EntityRegistry.getAllClasses()) {
|
||||
if(EntityLiving.class.isAssignableFrom(clazz))
|
||||
mobs.add(new RngSpawn((Class<? extends EntityLiving>)clazz, 1, 1, 8));
|
||||
}
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
super.decorate(worldIn, rand, pos);
|
||||
|
||||
if (rand.chance(10))
|
||||
{
|
||||
int i8 = rand.chOffset();
|
||||
int l11 = rand.chOffset();
|
||||
BlockPos blockpos2 = worldIn.getHeight(pos.add(i8, 0, l11));
|
||||
this.mushroomBlueGen.generate(worldIn, rand, blockpos2);
|
||||
}
|
||||
}
|
||||
}
|
40
server/src/main/java/server/biome/BiomeDesert.java
Executable file
40
server/src/main/java/server/biome/BiomeDesert.java
Executable file
|
@ -0,0 +1,40 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.util.BlockPos;
|
||||
import server.world.WorldServer;
|
||||
import server.worldgen.feature.WorldGenDesertWells;
|
||||
|
||||
public class BiomeDesert extends GenBiome
|
||||
{
|
||||
public BiomeDesert(boolean hills)
|
||||
{
|
||||
super(hills ? Biome.DESERTHILLS : Biome.DESERT);
|
||||
this.topBlock = Blocks.sand.getState();
|
||||
this.fillerBlock = Blocks.sand.getState();
|
||||
this.treesPerChunk = -999;
|
||||
this.deadBushPerChunk = 2;
|
||||
this.reedsPerChunk = 50;
|
||||
this.cactiPerChunk = 10;
|
||||
this.generateLakes = false;
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
super.decorate(worldIn, rand, pos);
|
||||
|
||||
if (rand.chance(1000))
|
||||
{
|
||||
int i = rand.chOffset();
|
||||
int j = rand.chOffset();
|
||||
BlockPos blockpos = worldIn.getHeight(pos.add(i, 0, j)).up();
|
||||
(new WorldGenDesertWells()).generate(worldIn, rand, blockpos);
|
||||
}
|
||||
}
|
||||
}
|
22
server/src/main/java/server/biome/BiomeExterminated.java
Executable file
22
server/src/main/java/server/biome/BiomeExterminated.java
Executable file
|
@ -0,0 +1,22 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.util.BlockPos;
|
||||
import server.world.WorldServer;
|
||||
|
||||
public class BiomeExterminated extends GenBiome {
|
||||
public BiomeExterminated() {
|
||||
super(Biome.EXTERMINATED);
|
||||
this.topBlock = Blocks.air.getState();
|
||||
this.fillerBlock = Blocks.air.getState();
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos) {
|
||||
}
|
||||
}
|
223
server/src/main/java/server/biome/BiomeForest.java
Executable file
223
server/src/main/java/server/biome/BiomeForest.java
Executable file
|
@ -0,0 +1,223 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.block.foliage.BlockDoublePlant;
|
||||
import common.block.foliage.BlockFlower;
|
||||
import common.entity.animal.EntityWolf;
|
||||
import common.entity.npc.EntityElf;
|
||||
import common.entity.npc.EntityWoodElf;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.util.ExtMath;
|
||||
import server.world.WorldServer;
|
||||
import server.worldgen.foliage.WorldGenBigMushroom;
|
||||
import server.worldgen.tree.WorldGenBaseTree;
|
||||
import server.worldgen.tree.WorldGenBigTree;
|
||||
import server.worldgen.tree.WorldGenBirch;
|
||||
import server.worldgen.tree.WorldGenDarkOak;
|
||||
import server.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeForest extends GenBiome
|
||||
{
|
||||
private static final BlockDoublePlant.EnumPlantType[] FLOWER_TYPES = new BlockDoublePlant.EnumPlantType[] {
|
||||
BlockDoublePlant.EnumPlantType.SYRINGA, BlockDoublePlant.EnumPlantType.ROSE, BlockDoublePlant.EnumPlantType.PAEONIA
|
||||
};
|
||||
protected static final WorldGenBirch tallBirch = new WorldGenBirch(false, true);
|
||||
protected static final WorldGenBirch normalBirch = new WorldGenBirch(false, false);
|
||||
protected static final WorldGenDarkOak darkOak = new WorldGenDarkOak(false);
|
||||
|
||||
private final int subType;
|
||||
// protected LeavesType leavesType = null;
|
||||
// protected WorldGenBaseTree cherry;
|
||||
// protected WorldGenBaseTree maple;
|
||||
// protected WorldGenBigTree cherryBig;
|
||||
// protected WorldGenBigTree mapleBig;
|
||||
protected WorldGenBaseTree cherry = new WorldGenBaseTree(false, Blocks.cherry_log.getState(), // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.CHERRY),
|
||||
Blocks.cherry_leaves.getState()); // .withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
|
||||
protected WorldGenBaseTree maple = new WorldGenBaseTree(false, Blocks.maple_log.getState(), // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.MAPLE),
|
||||
Blocks.maple_leaves.getState()); // .withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
|
||||
protected WorldGenBigTree cherryBig = new WorldGenBigTree(false, Blocks.cherry_log.getState(), // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.CHERRY),
|
||||
Blocks.cherry_leaves.getState()); // .withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
|
||||
protected WorldGenBigTree mapleBig = new WorldGenBigTree(false, Blocks.maple_log.getState(), // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.MAPLE),
|
||||
Blocks.maple_leaves.getState()); // .withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
|
||||
|
||||
public BiomeForest(Biome base, int type)
|
||||
{
|
||||
super(base);
|
||||
this.subType = type;
|
||||
this.treesPerChunk = 10;
|
||||
this.grassPerChunk = 2;
|
||||
|
||||
if (this.subType == 1)
|
||||
{
|
||||
this.treesPerChunk = 6;
|
||||
this.flowersPerChunk = 100;
|
||||
this.grassPerChunk = 1;
|
||||
}
|
||||
|
||||
if (this.subType == 4)
|
||||
{
|
||||
this.treesPerChunk = 20;
|
||||
this.flowersPerChunk = 20;
|
||||
this.grassPerChunk = 1;
|
||||
this.reedsPerChunk = 50;
|
||||
this.waterlilyPerChunk = 4;
|
||||
}
|
||||
|
||||
if (this.subType == 0)
|
||||
{
|
||||
this.mobs.add(new RngSpawn(EntityWolf.class, 5, 4, 4));
|
||||
}
|
||||
|
||||
if (this.subType == 3)
|
||||
{
|
||||
this.treesPerChunk = -999;
|
||||
}
|
||||
|
||||
if(this.subType != 4) {
|
||||
this.mobs.add(new RngSpawn(EntityWoodElf.class, 3, 2, 6));
|
||||
}
|
||||
else {
|
||||
this.mobs.add(new RngSpawn(EntityWoodElf.class, 100, 4, 16));
|
||||
this.mobs.add(new RngSpawn(EntityElf.class, 12, 4, 16));
|
||||
}
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return (WorldGenTree)
|
||||
(this.subType == 3 && rand.rarity(3) ? darkOak :
|
||||
(this.subType != 2 && rand.rarity(5) ? (this.subType != 3 && this.subType != 4 && rand.chance(this.subType == 1 ? 2 : 30) ? (rand.chance(25) ? this.cherryBig : this.cherry) :
|
||||
this.subType == 4 && rand.chance(42) ? this.worldGeneratorBigTree : this.worldGeneratorTrees) :
|
||||
(this.subType == 4 || rand.chance(this.subType == 2 ? 30 : 2) ? (rand.chance(this.subType == 4 ? 32 : 5) ? this.mapleBig : this.maple) : normalBirch)));
|
||||
}
|
||||
|
||||
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
|
||||
{
|
||||
if (this.subType == 1)
|
||||
{
|
||||
double d0 = ExtMath.clampd((1.0D + GRASS_NOISE.generate((double)pos.getX() / 48.0D, (double)pos.getZ() / 48.0D)) / 2.0D, 0.0D, 0.9999D);
|
||||
BlockFlower.EnumFlowerType blockflower$enumflowertype = BlockFlower.EnumFlowerType.values()[(int)(d0 * (double)BlockFlower.EnumFlowerType.values().length)];
|
||||
return blockflower$enumflowertype == BlockFlower.EnumFlowerType.BLUE_ORCHID ? BlockFlower.EnumFlowerType.ROSE : blockflower$enumflowertype;
|
||||
}
|
||||
else if (this.subType == 4)
|
||||
{
|
||||
double d0 = ExtMath.clampd((1.0D + GRASS_NOISE.generate((double)pos.getX() / 48.0D, (double)pos.getZ() / 48.0D)) / 2.0D, 0.0D, 0.9999D);
|
||||
return BlockFlower.EnumFlowerType.values()[(int)(d0 * (double)BlockFlower.EnumFlowerType.values().length)];
|
||||
}
|
||||
else
|
||||
{
|
||||
return super.pickRandomFlower(rand, pos);
|
||||
}
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
// if(worldIn.getLeavesGen() != this.leavesType) {
|
||||
// this.leavesType = worldIn.getLeavesGen();
|
||||
// this.cherry = new WorldGenBaseTree(false, Blocks.log2.getDefaultState().withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.CHERRY),
|
||||
// Blocks.cherry_leaves.getDefaultState().withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
|
||||
// this.maple = new WorldGenBaseTree(false, Blocks.log2.getDefaultState().withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.MAPLE),
|
||||
// Blocks.maple_leaves.getDefaultState().withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
|
||||
// this.cherryBig = new WorldGenBigTree(false, Blocks.log2.getDefaultState().withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.CHERRY),
|
||||
// Blocks.cherry_leaves.getDefaultState().withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
|
||||
// this.mapleBig = new WorldGenBigTree(false, Blocks.log2.getDefaultState().withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.MAPLE),
|
||||
// Blocks.maple_leaves.getDefaultState().withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
|
||||
// }
|
||||
|
||||
if (this.subType == 3)
|
||||
{
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
int k = i * 4 + rand.range(9, 11);
|
||||
int l = j * 4 + rand.range(9, 11);
|
||||
BlockPos blockpos = worldIn.getHeight(pos.add(k, 0, l));
|
||||
|
||||
if (rand.chance(20))
|
||||
{
|
||||
WorldGenBigMushroom worldgenbigmushroom = new WorldGenBigMushroom();
|
||||
worldgenbigmushroom.generate(worldIn, rand, blockpos);
|
||||
}
|
||||
else
|
||||
{
|
||||
WorldGenTree worldgenabstracttree = this.genBigTreeChance(rand);
|
||||
worldgenabstracttree.prepare();
|
||||
|
||||
if (worldgenabstracttree.generate(worldIn, rand, blockpos))
|
||||
{
|
||||
worldgenabstracttree.finish(worldIn, rand, blockpos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int j1 = rand.range(-3, 1);
|
||||
|
||||
if (this.subType == 1)
|
||||
{
|
||||
j1 += 2;
|
||||
}
|
||||
|
||||
for (int k1 = 0; k1 < j1; ++k1)
|
||||
{
|
||||
// int l1 = rand.nextInt(3);
|
||||
|
||||
// if (l1 == 0)
|
||||
// {
|
||||
DOUBLE_PLANT_GEN.setPlantType(rand.pick(FLOWER_TYPES));
|
||||
// }
|
||||
// else if (l1 == 1)
|
||||
// {
|
||||
// DOUBLE_PLANT_GENERATOR.setPlantType();
|
||||
// }
|
||||
// else if (l1 == 2)
|
||||
// {
|
||||
// DOUBLE_PLANT_GENERATOR.setPlantType();
|
||||
// }
|
||||
|
||||
for (int i2 = 0; i2 < 5; ++i2)
|
||||
{
|
||||
int j2 = rand.chOffset();
|
||||
int k2 = rand.chOffset();
|
||||
int i1 = rand.zrange(worldIn.getHeight(pos.add(j2, 0, k2)).getY() + 32);
|
||||
|
||||
if (DOUBLE_PLANT_GEN.generate(worldIn, rand, new BlockPos(pos.getX() + j2, i1, pos.getZ() + k2)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.decorate(worldIn, rand, pos);
|
||||
}
|
||||
|
||||
protected GenBiome createMutatedBiome(Biome base)
|
||||
{
|
||||
if (this.base == Biome.FOREST)
|
||||
{
|
||||
BiomeForest biomegenforest = new BiomeForest(base, 1);
|
||||
biomegenforest.setScaling(this.depth, this.scale + 0.2F);
|
||||
return biomegenforest;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.base != Biome.BIRCHFOREST && this.base != Biome.BIRCHFORESTHILLS ? new BiomeMutated(base, this)
|
||||
{
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
this.baseBiome.decorate(worldIn, rand, pos);
|
||||
}
|
||||
}: new BiomeMutated(base, this)
|
||||
{
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return rand.chance() ? BiomeForest.tallBirch : BiomeForest.normalBirch;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
129
server/src/main/java/server/biome/BiomeHell.java
Executable file
129
server/src/main/java/server/biome/BiomeHell.java
Executable file
|
@ -0,0 +1,129 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.entity.npc.EntityBloodElf;
|
||||
import common.entity.npc.EntityCultivator;
|
||||
import common.entity.npc.EntityFireDemon;
|
||||
import common.entity.npc.EntityMagma;
|
||||
import common.entity.npc.EntityMetalhead;
|
||||
import common.entity.npc.EntityTiefling;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.util.BlockPos;
|
||||
import server.world.WorldServer;
|
||||
import server.worldgen.FeatureOres;
|
||||
import server.worldgen.feature.WorldGenFire;
|
||||
import server.worldgen.feature.WorldGenGlowStone;
|
||||
import server.worldgen.feature.WorldGenHellLava;
|
||||
import server.worldgen.foliage.WorldGenMushroom;
|
||||
|
||||
public class BiomeHell extends GenBiome
|
||||
{
|
||||
private final int subtype;
|
||||
private final WorldGenFire fireGen;
|
||||
private final WorldGenGlowStone glowStoneGen1;
|
||||
private final WorldGenGlowStone glowStoneGen2;
|
||||
private final FeatureOres quartzGen;
|
||||
private final WorldGenHellLava lavaGen1;
|
||||
private final WorldGenHellLava lavaGen2;
|
||||
private final WorldGenMushroom brownMushroomGen;
|
||||
private final WorldGenMushroom redMushroomGen;
|
||||
|
||||
public BiomeHell(Biome base, int subtype)
|
||||
{
|
||||
super(base);
|
||||
this.subtype = subtype;
|
||||
if(this.subtype == 0) {
|
||||
this.mobs.add(new RngSpawn(EntityBloodElf.class, 10, 1, 2));
|
||||
this.mobs.add(new RngSpawn(EntityMetalhead.class, 1, 1, 1));
|
||||
this.fireGen = new WorldGenFire();
|
||||
this.glowStoneGen1 = new WorldGenGlowStone();
|
||||
this.glowStoneGen2 = new WorldGenGlowStone();
|
||||
this.quartzGen = new FeatureOres(Blocks.quartz_ore.getState(), 16, 0, 14, 10, 118, false);
|
||||
this.lavaGen1 = new WorldGenHellLava(Blocks.flowing_lava, true);
|
||||
this.lavaGen2 = new WorldGenHellLava(Blocks.flowing_lava, false);
|
||||
this.brownMushroomGen = new WorldGenMushroom(Blocks.brown_mushroom);
|
||||
this.redMushroomGen = new WorldGenMushroom(Blocks.red_mushroom);
|
||||
}
|
||||
else {
|
||||
this.mobs.add(new RngSpawn(EntityBloodElf.class, 50, 2, 10));
|
||||
this.mobs.add(new RngSpawn(EntityCultivator.class, 10, 1, 1));
|
||||
this.fireGen = null;
|
||||
this.glowStoneGen1 = null;
|
||||
this.glowStoneGen2 = null;
|
||||
this.quartzGen = null;
|
||||
this.lavaGen1 = null;
|
||||
this.lavaGen2 = null;
|
||||
this.brownMushroomGen = null;
|
||||
this.redMushroomGen = null;
|
||||
}
|
||||
if(this.subtype == 2) {
|
||||
this.topBlock = Blocks.ash.getState();
|
||||
this.fillerBlock = Blocks.rock.getState();
|
||||
}
|
||||
else {
|
||||
this.topBlock = Blocks.hellrock.getState();
|
||||
this.fillerBlock = Blocks.hellrock.getState();
|
||||
}
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
mobs.add(new RngSpawn(EntityFireDemon.class, 50, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityTiefling.class, 100, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityMagma.class, 1, 4, 4));
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
if(this.subtype == 0) {
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
this.lavaGen2.generate(worldIn, rand, pos.add(rand.zrange(16) + 8, rand.zrange(120) + 4, rand.zrange(16) + 8));
|
||||
}
|
||||
|
||||
for (int j = 0; j < rand.zrange(rand.zrange(10) + 1) + 1; ++j)
|
||||
{
|
||||
this.fireGen.generate(worldIn, rand, pos.add(rand.zrange(16) + 8, rand.zrange(120) + 4, rand.zrange(16) + 8));
|
||||
}
|
||||
|
||||
for (int k = 0; k < rand.zrange(rand.zrange(10) + 1); ++k)
|
||||
{
|
||||
this.glowStoneGen1.generate(worldIn, rand, pos.add(rand.zrange(16) + 8, rand.zrange(120) + 4, rand.zrange(16) + 8));
|
||||
}
|
||||
|
||||
for (int l = 0; l < 10; ++l)
|
||||
{
|
||||
this.glowStoneGen2.generate(worldIn, rand, pos.add(rand.zrange(16) + 8, rand.zrange(128), rand.zrange(16) + 8));
|
||||
}
|
||||
|
||||
if (rand.chance())
|
||||
{
|
||||
this.brownMushroomGen.generate(worldIn, rand, pos.add(rand.zrange(16) + 8, rand.zrange(128), rand.zrange(16) + 8));
|
||||
}
|
||||
|
||||
if (rand.chance())
|
||||
{
|
||||
this.redMushroomGen.generate(worldIn, rand, pos.add(rand.zrange(16) + 8, rand.zrange(128), rand.zrange(16) + 8));
|
||||
}
|
||||
|
||||
// for (int i1 = 0; i1 < 16; ++i1)
|
||||
// {
|
||||
this.quartzGen.generate(worldIn, rand, pos); // .add(rand.nextInt(16), rand.nextInt(108) + 10, rand.nextInt(16)));
|
||||
// }
|
||||
|
||||
for (int j1 = 0; j1 < 16; ++j1)
|
||||
{
|
||||
this.lavaGen1.generate(worldIn, rand, pos.add(rand.zrange(16), rand.zrange(108) + 10, rand.zrange(16)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
super.decorate(worldIn, rand, pos);
|
||||
}
|
||||
}
|
||||
|
||||
// protected Decorator createBiomeDecorator()
|
||||
// {
|
||||
// return this.subtype == 0 ? new DecoratorHell() : super.createBiomeDecorator();
|
||||
// }
|
||||
}
|
101
server/src/main/java/server/biome/BiomeHills.java
Executable file
101
server/src/main/java/server/biome/BiomeHills.java
Executable file
|
@ -0,0 +1,101 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import server.world.WorldServer;
|
||||
import server.worldgen.ChunkPrimer;
|
||||
import server.worldgen.FeatureOres;
|
||||
import server.worldgen.tree.WorldGenTaiga2;
|
||||
import server.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeHills extends GenBiome
|
||||
{
|
||||
// private FeatureGenerator theWorldGenerator = new FeatureOres(Blocks.monster_egg.getDefaultState().withProperty(BlockSilverfish.VARIANT, BlockSilverfish.EnumType.STONE), false, 7, 9, 0, 64);
|
||||
private FeatureOres theEmeraldGenerator = new FeatureOres(Blocks.emerald_ore.getState(), 3, 5, 1, 4, 32, false);
|
||||
private WorldGenTaiga2 field_150634_aD = new WorldGenTaiga2(false);
|
||||
private int field_150635_aE = 0;
|
||||
private int field_150636_aF = 1;
|
||||
private int field_150637_aG = 2;
|
||||
private int field_150638_aH;
|
||||
|
||||
protected BiomeHills(Biome base, boolean large)
|
||||
{
|
||||
super(base);
|
||||
this.field_150638_aH = this.field_150635_aE;
|
||||
|
||||
if (large)
|
||||
{
|
||||
this.treesPerChunk = 3;
|
||||
this.field_150638_aH = this.field_150636_aF;
|
||||
}
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return (WorldGenTree)(rand.rarity(3) ? this.field_150634_aD : super.genBigTreeChance(rand));
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
super.decorate(worldIn, rand, pos);
|
||||
// int i = 3 + rand.nextInt(6);
|
||||
//
|
||||
// for (int j = 0; j < i; ++j)
|
||||
// {
|
||||
// int k = rand.nextInt(16);
|
||||
// int l = rand.nextInt(28) + 4;
|
||||
// int i1 = rand.nextInt(16);
|
||||
// BlockPos blockpos = pos.add(k, l, i1);
|
||||
//
|
||||
// if (worldIn.getBlockState(blockpos).getBlock() == Blocks.stone)
|
||||
// {
|
||||
// worldIn.setBlockState(blockpos, Blocks.emerald_ore.getDefaultState(), 2);
|
||||
// }
|
||||
// }
|
||||
this.theEmeraldGenerator.generate(worldIn, rand, pos);
|
||||
|
||||
// for (i = 0; i < 7; ++i)
|
||||
// {
|
||||
// int j1 = rand.nextInt(16);
|
||||
// int k1 = rand.nextInt(64);
|
||||
// int l1 = rand.nextInt(16);
|
||||
// this.theWorldGenerator.generate(worldIn, rand, pos); // .add(j1, k1, l1));
|
||||
// }
|
||||
}
|
||||
|
||||
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
|
||||
{
|
||||
this.topBlock = Blocks.grass.getState();
|
||||
this.fillerBlock = Blocks.dirt.getState();
|
||||
|
||||
if ((noiseVal < -1.0D || noiseVal > 2.0D) && this.field_150638_aH == this.field_150637_aG)
|
||||
{
|
||||
this.topBlock = Blocks.gravel.getState();
|
||||
this.fillerBlock = Blocks.gravel.getState();
|
||||
}
|
||||
else if (noiseVal > 1.0D && this.field_150638_aH != this.field_150636_aF)
|
||||
{
|
||||
this.topBlock = Blocks.stone.getState();
|
||||
this.fillerBlock = Blocks.stone.getState();
|
||||
}
|
||||
|
||||
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* this creates a mutation specific to Hills biomes
|
||||
*/
|
||||
private BiomeHills mutateHills(GenBiome p_150633_1_)
|
||||
{
|
||||
this.field_150638_aH = this.field_150637_aG;
|
||||
this.setScaling(p_150633_1_.depth, p_150633_1_.scale);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected GenBiome createMutatedBiome(Biome base)
|
||||
{
|
||||
return (new BiomeHills(base, false)).mutateHills(this);
|
||||
}
|
||||
}
|
84
server/src/main/java/server/biome/BiomeJungle.java
Executable file
84
server/src/main/java/server/biome/BiomeJungle.java
Executable file
|
@ -0,0 +1,84 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.block.foliage.BlockTallGrass;
|
||||
import common.entity.animal.EntityChicken;
|
||||
import common.entity.animal.EntityOcelot;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.world.State;
|
||||
import server.world.WorldServer;
|
||||
import server.worldgen.FeatureGenerator;
|
||||
import server.worldgen.foliage.WorldGenMelon;
|
||||
import server.worldgen.foliage.WorldGenShrub;
|
||||
import server.worldgen.foliage.WorldGenTallGrass;
|
||||
import server.worldgen.foliage.WorldGenVines;
|
||||
import server.worldgen.tree.WorldGenBaseTree;
|
||||
import server.worldgen.tree.WorldGenJungle;
|
||||
import server.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeJungle extends GenBiome
|
||||
{
|
||||
private static final State LOG = Blocks.jungle_log.getState(); // .withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE);
|
||||
private static final State LEAVES = Blocks.jungle_leaves.getState(); // .withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.JUNGLE); // .withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false));
|
||||
private static final State BUSH = Blocks.oak_leaves.getState(); // .withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.OAK); // .withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false));
|
||||
|
||||
private final boolean edge;
|
||||
|
||||
public BiomeJungle(Biome base, boolean edge)
|
||||
{
|
||||
super(base);
|
||||
this.edge = edge;
|
||||
|
||||
if (edge)
|
||||
{
|
||||
this.treesPerChunk = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.treesPerChunk = 50;
|
||||
}
|
||||
|
||||
this.grassPerChunk = 25;
|
||||
this.flowersPerChunk = 4;
|
||||
|
||||
if (!edge)
|
||||
{
|
||||
this.mobs.add(new RngSpawn(EntityOcelot.class, 2, 1, 1));
|
||||
}
|
||||
|
||||
this.mobs.add(new RngSpawn(EntityChicken.class, 10, 4, 4));
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return (WorldGenTree)(rand.chance(10) ? this.worldGeneratorBigTree : (rand.chance(2) ? new WorldGenShrub(LOG, BUSH) : (!this.edge && rand.chance(3) ? new WorldGenJungle(false, 10, 20, LOG, LEAVES) : new WorldGenBaseTree(false, rand.range(4, 10), LOG, LEAVES, true))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a WorldGen appropriate for this biome.
|
||||
*/
|
||||
public FeatureGenerator getRandomWorldGenForGrass(Random rand)
|
||||
{
|
||||
return rand.chance(4) ? new WorldGenTallGrass(BlockTallGrass.EnumType.FERN) : new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS);
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
super.decorate(worldIn, rand, pos);
|
||||
int i = rand.chOffset();
|
||||
int j = rand.chOffset();
|
||||
int k = rand.zrange(worldIn.getHeight(pos.add(i, 0, j)).getY() * 2);
|
||||
(new WorldGenMelon()).generate(worldIn, rand, pos.add(i, k, j));
|
||||
WorldGenVines worldgenvines = new WorldGenVines();
|
||||
|
||||
for (j = 0; j < 50; ++j)
|
||||
{
|
||||
k = rand.chOffset();
|
||||
int l = 128;
|
||||
int i1 = rand.chOffset();
|
||||
worldgenvines.generate(worldIn, rand, pos.add(k, 128, i1));
|
||||
}
|
||||
}
|
||||
}
|
331
server/src/main/java/server/biome/BiomeMesa.java
Executable file
331
server/src/main/java/server/biome/BiomeMesa.java
Executable file
|
@ -0,0 +1,331 @@
|
|||
package server.biome;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.block.Block;
|
||||
import common.block.BlockColored;
|
||||
import common.block.natural.BlockDirt;
|
||||
import common.block.natural.BlockSand;
|
||||
import common.color.DyeColor;
|
||||
import common.init.Blocks;
|
||||
import common.rng.PerlinGen;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.util.BlockPos;
|
||||
import common.world.State;
|
||||
import server.world.WorldServer;
|
||||
import server.worldgen.ChunkPrimer;
|
||||
import server.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeMesa extends GenBiome
|
||||
{
|
||||
private final boolean bryce;
|
||||
private final boolean soil;
|
||||
|
||||
private State[] layers;
|
||||
private long layerSeed;
|
||||
private PerlinGen baseBryceGen;
|
||||
private PerlinGen highBryceGen;
|
||||
private PerlinGen clayColorGen;
|
||||
|
||||
public BiomeMesa(Biome base, boolean bryce, boolean soil)
|
||||
{
|
||||
super(base);
|
||||
this.bryce = bryce;
|
||||
this.soil = soil;
|
||||
// this.setDisableRain();
|
||||
// this.setTemperatureLegacy(2.0F).setHumidity(0.0F);
|
||||
// this.mobs.clear();
|
||||
this.topBlock = Blocks.sand.getState().withProperty(BlockSand.VARIANT, BlockSand.EnumType.RED_SAND);
|
||||
this.fillerBlock = Blocks.stained_hardened_clay.getState();
|
||||
this.treesPerChunk = -999;
|
||||
this.deadBushPerChunk = 20;
|
||||
this.reedsPerChunk = 3;
|
||||
this.cactiPerChunk = 5;
|
||||
this.flowersPerChunk = 0;
|
||||
// this.mobs.clear();
|
||||
|
||||
if (soil)
|
||||
{
|
||||
this.treesPerChunk = 5;
|
||||
}
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return this.worldGeneratorTrees;
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
super.decorate(worldIn, rand, pos);
|
||||
}
|
||||
|
||||
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
|
||||
{
|
||||
if (this.layers == null || this.layerSeed != worldIn.getSeed())
|
||||
{
|
||||
this.setupLayers(worldIn.getSeed());
|
||||
}
|
||||
|
||||
if (this.baseBryceGen == null || this.highBryceGen == null || this.layerSeed != worldIn.getSeed())
|
||||
{
|
||||
Random random = new Random(this.layerSeed);
|
||||
this.baseBryceGen = new PerlinGen(random, 4);
|
||||
this.highBryceGen = new PerlinGen(random, 1);
|
||||
}
|
||||
|
||||
this.layerSeed = worldIn.getSeed();
|
||||
double d4 = 0.0D;
|
||||
|
||||
if (this.bryce)
|
||||
{
|
||||
int i = (x & -16) + (z & 15);
|
||||
int j = (z & -16) + (x & 15);
|
||||
double d0 = Math.min(Math.abs(noiseVal), this.baseBryceGen.generate((double)i * 0.25D, (double)j * 0.25D));
|
||||
|
||||
if (d0 > 0.0D)
|
||||
{
|
||||
double d1 = 0.001953125D;
|
||||
double d2 = Math.abs(this.highBryceGen.generate((double)i * d1, (double)j * d1));
|
||||
d4 = d0 * d0 * 2.5D;
|
||||
double d3 = Math.ceil(d2 * 50.0D) + 14.0D;
|
||||
|
||||
if (d4 > d3)
|
||||
{
|
||||
d4 = d3;
|
||||
}
|
||||
|
||||
d4 = d4 + 64.0D;
|
||||
}
|
||||
}
|
||||
|
||||
int j1 = x & 15;
|
||||
int k1 = z & 15;
|
||||
int l1 = worldIn.getSeaLevel();
|
||||
State iblockstate = Blocks.stained_hardened_clay.getState();
|
||||
State iblockstate3 = this.fillerBlock;
|
||||
int k = (int)(noiseVal / 3.0D + 3.0D + rand.doublev() * 0.25D);
|
||||
boolean flag = Math.cos(noiseVal / 3.0D * Math.PI) > 0.0D;
|
||||
int l = -1;
|
||||
boolean flag1 = false;
|
||||
State worldState = worldIn.dimension.getFiller();
|
||||
Block worldBlock = worldState.getBlock();
|
||||
State worldAlt = worldIn.dimension.getAltFiller1();
|
||||
State liquid = worldIn.getSurfaceLiquid();
|
||||
// IBlockState bottom = worldIn.dimension.hasBedrock() ? Blocks.bedrock.getDefaultState() : Blocks.air.getDefaultState();
|
||||
|
||||
for (int i1 = chunkPrimerIn.height - 1; i1 >= 0; --i1)
|
||||
{
|
||||
if (chunkPrimerIn.get(k1, i1, j1).getBlock() == Blocks.air && i1 < (int)d4)
|
||||
{
|
||||
chunkPrimerIn.set(k1, i1, j1, worldState);
|
||||
}
|
||||
|
||||
// if (i1 <= rand.zrange(5) && bedrock)
|
||||
// {
|
||||
// chunkPrimerIn.set(k1, i1, j1, bottom);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
State iblockstate1 = chunkPrimerIn.get(k1, i1, j1);
|
||||
|
||||
if (iblockstate1.getBlock() == Blocks.air)
|
||||
{
|
||||
l = -1;
|
||||
}
|
||||
else if (iblockstate1.getBlock() == worldBlock)
|
||||
{
|
||||
if (l == -1)
|
||||
{
|
||||
flag1 = false;
|
||||
|
||||
if (k <= 0)
|
||||
{
|
||||
iblockstate = null;
|
||||
iblockstate3 = worldState;
|
||||
}
|
||||
else if (i1 >= l1 - 4 && i1 <= l1 + 1)
|
||||
{
|
||||
iblockstate = Blocks.stained_hardened_clay.getState();
|
||||
iblockstate3 = this.fillerBlock;
|
||||
}
|
||||
|
||||
if (i1 < l1 && (iblockstate == null || iblockstate.getBlock() == Blocks.air))
|
||||
{
|
||||
iblockstate = liquid;
|
||||
}
|
||||
|
||||
l = k + Math.max(0, i1 - l1);
|
||||
|
||||
if (i1 < l1 - 1)
|
||||
{
|
||||
chunkPrimerIn.set(k1, i1, j1, iblockstate3);
|
||||
|
||||
if (iblockstate3.getBlock() == Blocks.stained_hardened_clay)
|
||||
{
|
||||
chunkPrimerIn.set(k1, i1, j1, iblockstate3.getBlock().getState().withProperty(BlockColored.COLOR, DyeColor.ORANGE));
|
||||
}
|
||||
}
|
||||
else if (this.soil && i1 > 86 + k * 2)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
chunkPrimerIn.set(k1, i1, j1, Blocks.dirt.getState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.COARSE_DIRT));
|
||||
}
|
||||
else
|
||||
{
|
||||
chunkPrimerIn.set(k1, i1, j1, Blocks.grass.getState());
|
||||
}
|
||||
}
|
||||
else if (i1 <= l1 + 3 + k)
|
||||
{
|
||||
chunkPrimerIn.set(k1, i1, j1, this.topBlock);
|
||||
flag1 = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
State iblockstate4;
|
||||
|
||||
if (i1 >= 64 && i1 <= 127)
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
iblockstate4 = Blocks.hardened_clay.getState();
|
||||
}
|
||||
else
|
||||
{
|
||||
iblockstate4 = this.getBlockAt(x, i1, z);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iblockstate4 = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.ORANGE);
|
||||
}
|
||||
|
||||
chunkPrimerIn.set(k1, i1, j1, iblockstate4);
|
||||
}
|
||||
}
|
||||
else if (l > 0)
|
||||
{
|
||||
--l;
|
||||
|
||||
if (flag1)
|
||||
{
|
||||
chunkPrimerIn.set(k1, i1, j1, Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.ORANGE));
|
||||
}
|
||||
else
|
||||
{
|
||||
State iblockstate2 = this.getBlockAt(x, i1, z);
|
||||
chunkPrimerIn.set(k1, i1, j1, iblockstate2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
private void setupLayers(long seed)
|
||||
{
|
||||
this.layers = new State[64];
|
||||
Arrays.fill(this.layers, Blocks.hardened_clay.getState());
|
||||
Random random = new Random(seed);
|
||||
this.clayColorGen = new PerlinGen(random, 1);
|
||||
|
||||
for (int l1 = 0; l1 < 64; ++l1)
|
||||
{
|
||||
l1 += random.roll(5);
|
||||
|
||||
if (l1 < 64)
|
||||
{
|
||||
this.layers[l1] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.ORANGE);
|
||||
}
|
||||
}
|
||||
|
||||
int i2 = random.range(2, 5);
|
||||
|
||||
for (int i = 0; i < i2; ++i)
|
||||
{
|
||||
int j = random.roll(3);
|
||||
int k = random.zrange(64);
|
||||
|
||||
for (int l = 0; k + l < 64 && l < j; ++l)
|
||||
{
|
||||
this.layers[k + l] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.YELLOW);
|
||||
}
|
||||
}
|
||||
|
||||
int j2 = random.range(2, 5);
|
||||
|
||||
for (int k2 = 0; k2 < j2; ++k2)
|
||||
{
|
||||
int i3 = random.range(2, 4);
|
||||
int l3 = random.zrange(64);
|
||||
|
||||
for (int i1 = 0; l3 + i1 < 64 && i1 < i3; ++i1)
|
||||
{
|
||||
this.layers[l3 + i1] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.BROWN);
|
||||
}
|
||||
}
|
||||
|
||||
int l2 = random.range(2, 5);
|
||||
|
||||
for (int j3 = 0; j3 < l2; ++j3)
|
||||
{
|
||||
int i4 = random.roll(3);
|
||||
int k4 = random.zrange(64);
|
||||
|
||||
for (int j1 = 0; k4 + j1 < 64 && j1 < i4; ++j1)
|
||||
{
|
||||
this.layers[k4 + j1] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.RED);
|
||||
}
|
||||
}
|
||||
|
||||
int k3 = random.range(3, 5);
|
||||
int j4 = 0;
|
||||
|
||||
for (int l4 = 0; l4 < k3; ++l4)
|
||||
{
|
||||
int i5 = 1;
|
||||
j4 += random.range(4, 19);
|
||||
|
||||
for (int k1 = 0; j4 + k1 < 64 && k1 < i5; ++k1)
|
||||
{
|
||||
this.layers[j4 + k1] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.WHITE);
|
||||
|
||||
if (j4 + k1 > 1 && random.chance())
|
||||
{
|
||||
this.layers[j4 + k1 - 1] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.SILVER);
|
||||
}
|
||||
|
||||
if (j4 + k1 < 63 && random.chance())
|
||||
{
|
||||
this.layers[j4 + k1 + 1] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.SILVER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private State getBlockAt(int x, int y, int z)
|
||||
{
|
||||
int i = (int)Math.round(this.clayColorGen.generate((double)x * 1.0D / 512.0D, (double)x * 1.0D / 512.0D) * 2.0D);
|
||||
return this.layers[(y + i + 64) % 64];
|
||||
}
|
||||
|
||||
protected GenBiome createMutatedBiome(Biome base)
|
||||
{
|
||||
boolean bryce = this.base == Biome.MESA;
|
||||
BiomeMesa mesa = new BiomeMesa(base, bryce, this.soil);
|
||||
|
||||
if (!bryce)
|
||||
{
|
||||
mesa.setScaling(Scaling.HILLS_LOW);
|
||||
}
|
||||
|
||||
return mesa;
|
||||
}
|
||||
}
|
26
server/src/main/java/server/biome/BiomeMoon.java
Executable file
26
server/src/main/java/server/biome/BiomeMoon.java
Executable file
|
@ -0,0 +1,26 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.util.BlockPos;
|
||||
import server.world.WorldServer;
|
||||
import server.worldgen.FeatureOres;
|
||||
|
||||
public class BiomeMoon extends GenBiome {
|
||||
private FeatureOres cheeseGenerator = new FeatureOres(Blocks.moon_cheese.getState(), 8, 8, 12, 24, 52, false);
|
||||
|
||||
public BiomeMoon() {
|
||||
super(Biome.MOON);
|
||||
this.topBlock = Blocks.moon_rock.getState();
|
||||
this.fillerBlock = Blocks.moon_rock.getState();
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos) {
|
||||
this.cheeseGenerator.generate(worldIn, rand, pos);
|
||||
}
|
||||
}
|
24
server/src/main/java/server/biome/BiomeMushroom.java
Executable file
24
server/src/main/java/server/biome/BiomeMushroom.java
Executable file
|
@ -0,0 +1,24 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.entity.animal.EntityMooshroom;
|
||||
import common.init.Blocks;
|
||||
import common.rng.WeightedList;
|
||||
|
||||
public class BiomeMushroom extends GenBiome
|
||||
{
|
||||
public BiomeMushroom()
|
||||
{
|
||||
super(Biome.MUSHROOMPLAINS);
|
||||
this.treesPerChunk = -100;
|
||||
this.flowersPerChunk = -100;
|
||||
this.grassPerChunk = -100;
|
||||
this.mushroomsPerChunk = 1;
|
||||
this.bigMushroomsPerChunk = 1;
|
||||
this.topBlock = Blocks.mycelium.getState();
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
mobs.add(new RngSpawn(EntityMooshroom.class, 8, 4, 8));
|
||||
}
|
||||
}
|
83
server/src/main/java/server/biome/BiomeMutated.java
Executable file
83
server/src/main/java/server/biome/BiomeMutated.java
Executable file
|
@ -0,0 +1,83 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.util.BlockPos;
|
||||
import server.world.WorldServer;
|
||||
import server.worldgen.ChunkPrimer;
|
||||
import server.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeMutated extends GenBiome
|
||||
{
|
||||
protected GenBiome baseBiome;
|
||||
|
||||
public BiomeMutated(Biome base, GenBiome biome)
|
||||
{
|
||||
super(base);
|
||||
this.baseBiome = biome;
|
||||
this.topBlock = biome.topBlock;
|
||||
this.fillerBlock = biome.fillerBlock;
|
||||
// this.minHeight = biome.minHeight;
|
||||
// this.maxHeight = biome.maxHeight;
|
||||
this.allowColdBeach = biome.allowColdBeach;
|
||||
// this.enableRain = biome.enableRain;
|
||||
// this.mobs.clear();
|
||||
this.mobs.addAll(biome.mobs);
|
||||
// this.mobs = new WeightedList(biome.mobs);
|
||||
// this.monsters = new WeightedList(biome.monsters);
|
||||
// this.caveMobs = new WeightedList(biome.caveMobs);
|
||||
// this.waterMobs = new WeightedList(biome.waterMobs);
|
||||
// this.npcs = new WeightedList(biome.npcs);
|
||||
// this.temperature = biome.temperature;
|
||||
// this.humidity = biome.humidity;
|
||||
this.depth = biome.depth + 0.1F;
|
||||
this.scale = biome.scale + 0.2F;
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
this.baseBiome.decorate(worldIn, rand, pos); // TODO: check
|
||||
}
|
||||
|
||||
public void decorateNormal(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
super.decorate(worldIn, rand, pos);
|
||||
}
|
||||
|
||||
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
|
||||
{
|
||||
this.baseBiome.genTerrainBlocks(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
|
||||
}
|
||||
|
||||
public float getMobGenChance()
|
||||
{
|
||||
return this.baseBiome.getMobGenChance();
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return this.baseBiome.genBigTreeChance(rand);
|
||||
}
|
||||
|
||||
public Class <? extends GenBiome > getBiomeClass()
|
||||
{
|
||||
return this.baseBiome.getBiomeClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if the biome specified is equal to this biome
|
||||
*/
|
||||
public boolean isEqualTo(GenBiome biome)
|
||||
{
|
||||
return this.baseBiome.isEqualTo(biome);
|
||||
}
|
||||
|
||||
public Temperature getTempCategory()
|
||||
{
|
||||
return this.baseBiome.getTempCategory();
|
||||
}
|
||||
}
|
30
server/src/main/java/server/biome/BiomeNone.java
Executable file
30
server/src/main/java/server/biome/BiomeNone.java
Executable file
|
@ -0,0 +1,30 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.util.BlockPos;
|
||||
import server.world.WorldServer;
|
||||
import server.worldgen.ChunkPrimer;
|
||||
|
||||
public class BiomeNone extends GenBiome {
|
||||
public BiomeNone() {
|
||||
super(Biome.NONE);
|
||||
this.topBlock = Blocks.air.getState();
|
||||
this.fillerBlock = Blocks.air.getState();
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
|
||||
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) {
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos) {
|
||||
}
|
||||
|
||||
public Temperature getTempCategory() {
|
||||
return Temperature.SEA;
|
||||
}
|
||||
}
|
120
server/src/main/java/server/biome/BiomePlains.java
Executable file
120
server/src/main/java/server/biome/BiomePlains.java
Executable file
|
@ -0,0 +1,120 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.block.foliage.BlockDoublePlant;
|
||||
import common.block.foliage.BlockFlower;
|
||||
import common.entity.animal.EntityHorse;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import server.world.WorldServer;
|
||||
|
||||
public class BiomePlains extends GenBiome
|
||||
{
|
||||
private static final BlockFlower.EnumFlowerType[] TULIP_TYPES = new BlockFlower.EnumFlowerType[] {
|
||||
BlockFlower.EnumFlowerType.ORANGE_TULIP, BlockFlower.EnumFlowerType.RED_TULIP,
|
||||
BlockFlower.EnumFlowerType.PINK_TULIP, BlockFlower.EnumFlowerType.WHITE_TULIP
|
||||
};
|
||||
|
||||
private static final BlockFlower.EnumFlowerType[] FLOWER_TYPES = new BlockFlower.EnumFlowerType[] {
|
||||
BlockFlower.EnumFlowerType.POPPY, BlockFlower.EnumFlowerType.HOUSTONIA, BlockFlower.EnumFlowerType.OXEYE_DAISY
|
||||
};
|
||||
|
||||
// protected boolean field_150628_aC;
|
||||
|
||||
protected BiomePlains()
|
||||
{
|
||||
super(Biome.PLAINS);
|
||||
this.setScaling(Scaling.PLAINS_LOW);
|
||||
this.mobs.add(new RngSpawn(EntityHorse.class, 5, 2, 6));
|
||||
this.treesPerChunk = -999;
|
||||
this.flowersPerChunk = 4;
|
||||
this.grassPerChunk = 10;
|
||||
}
|
||||
|
||||
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
|
||||
{
|
||||
double d0 = GRASS_NOISE.generate((double)pos.getX() / 200.0D, (double)pos.getZ() / 200.0D);
|
||||
|
||||
if (d0 < -0.8D)
|
||||
{
|
||||
return rand.pick(TULIP_TYPES);
|
||||
// int j = rand.nextInt(4);
|
||||
//
|
||||
// switch (j)
|
||||
// {
|
||||
// case 0:
|
||||
// return BlockFlower.EnumFlowerType.ORANGE_TULIP;
|
||||
//
|
||||
// case 1:
|
||||
// return BlockFlower.EnumFlowerType.RED_TULIP;
|
||||
//
|
||||
// case 2:
|
||||
// return BlockFlower.EnumFlowerType.PINK_TULIP;
|
||||
//
|
||||
// case 3:
|
||||
// default:
|
||||
// return BlockFlower.EnumFlowerType.WHITE_TULIP;
|
||||
// }
|
||||
}
|
||||
else if (rand.rarity(3))
|
||||
{
|
||||
return rand.pick(FLOWER_TYPES);
|
||||
// int i = rand.nextInt(3);
|
||||
// return i == 0 ? BlockFlower.EnumFlowerType.POPPY : (i == 1 ? BlockFlower.EnumFlowerType.HOUSTONIA : BlockFlower.EnumFlowerType.OXEYE_DAISY);
|
||||
}
|
||||
else
|
||||
{
|
||||
return BlockFlower.EnumFlowerType.DANDELION;
|
||||
}
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
double d0 = GRASS_NOISE.generate((double)(pos.getX() + 8) / 200.0D, (double)(pos.getZ() + 8) / 200.0D);
|
||||
|
||||
if (d0 < -0.8D)
|
||||
{
|
||||
this.flowersPerChunk = 15;
|
||||
this.grassPerChunk = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.flowersPerChunk = 4;
|
||||
this.grassPerChunk = 10;
|
||||
DOUBLE_PLANT_GEN.setPlantType(BlockDoublePlant.EnumPlantType.GRASS);
|
||||
|
||||
for (int i = 0; i < 7; ++i)
|
||||
{
|
||||
int j = rand.chOffset();
|
||||
int k = rand.chOffset();
|
||||
int l = rand.zrange(worldIn.getHeight(pos.add(j, 0, k)).getY() + 32);
|
||||
DOUBLE_PLANT_GEN.generate(worldIn, rand, pos.add(j, l, k));
|
||||
}
|
||||
}
|
||||
|
||||
// int n = rand.range(0, 2);
|
||||
if (rand.chance())
|
||||
{
|
||||
DOUBLE_PLANT_GEN.setPlantType(BlockDoublePlant.EnumPlantType.SUNFLOWER);
|
||||
|
||||
// for (int i1 = 0; i1 < 10; ++i1)
|
||||
// {
|
||||
int j1 = rand.chOffset();
|
||||
int k1 = rand.chOffset();
|
||||
int l1 = rand.zrange(worldIn.getHeight(pos.add(j1, 0, k1)).getY() + 32);
|
||||
DOUBLE_PLANT_GEN.generate(worldIn, rand, pos.add(j1, l1, k1));
|
||||
// }
|
||||
}
|
||||
|
||||
super.decorate(worldIn, rand, pos);
|
||||
}
|
||||
|
||||
// protected Biome createMutatedBiome(int p_180277_1_)
|
||||
// {
|
||||
// BiomePlains biomegenplains = new BiomePlains(p_180277_1_);
|
||||
// biomegenplains.setBiomeName("sunflowerPlains");
|
||||
// biomegenplains.field_150628_aC = true;
|
||||
// biomegenplains.setColor(9286496);
|
||||
// return biomegenplains;
|
||||
// }
|
||||
}
|
89
server/src/main/java/server/biome/BiomeSavanna.java
Executable file
89
server/src/main/java/server/biome/BiomeSavanna.java
Executable file
|
@ -0,0 +1,89 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.block.foliage.BlockDoublePlant;
|
||||
import common.block.natural.BlockDirt;
|
||||
import common.entity.animal.EntityHorse;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import server.world.WorldServer;
|
||||
import server.worldgen.ChunkPrimer;
|
||||
import server.worldgen.tree.WorldGenSavanna;
|
||||
import server.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeSavanna extends GenBiome
|
||||
{
|
||||
private static final WorldGenSavanna field_150627_aC = new WorldGenSavanna(false);
|
||||
|
||||
protected BiomeSavanna(boolean plateau)
|
||||
{
|
||||
super(plateau ? Biome.SAVANNAPLATEAU : Biome.SAVANNA);
|
||||
this.mobs.add(new RngSpawn(EntityHorse.class, 1, 2, 6));
|
||||
this.treesPerChunk = 1;
|
||||
this.flowersPerChunk = 4;
|
||||
this.grassPerChunk = 20;
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return (WorldGenTree)(rand.rarity(5) ? field_150627_aC : this.worldGeneratorTrees);
|
||||
}
|
||||
|
||||
protected GenBiome createMutatedBiome(Biome base)
|
||||
{
|
||||
GenBiome biomegenbase = new BiomeSavanna.Mutated(base, this);
|
||||
biomegenbase.depth = this.depth * 0.5F + 0.3F;
|
||||
biomegenbase.scale = this.scale * 0.5F + 1.2F;
|
||||
return biomegenbase;
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
DOUBLE_PLANT_GEN.setPlantType(BlockDoublePlant.EnumPlantType.GRASS);
|
||||
|
||||
for (int i = 0; i < 7; ++i)
|
||||
{
|
||||
int j = rand.chOffset();
|
||||
int k = rand.chOffset();
|
||||
int l = rand.zrange(worldIn.getHeight(pos.add(j, 0, k)).getY() + 32);
|
||||
DOUBLE_PLANT_GEN.generate(worldIn, rand, pos.add(j, l, k));
|
||||
}
|
||||
|
||||
super.decorate(worldIn, rand, pos);
|
||||
}
|
||||
|
||||
public static class Mutated extends BiomeMutated
|
||||
{
|
||||
public Mutated(Biome base, GenBiome p_i45382_2_)
|
||||
{
|
||||
super(base, p_i45382_2_);
|
||||
this.treesPerChunk = 2;
|
||||
this.flowersPerChunk = 2;
|
||||
this.grassPerChunk = 5;
|
||||
}
|
||||
|
||||
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
|
||||
{
|
||||
this.topBlock = Blocks.grass.getState();
|
||||
this.fillerBlock = Blocks.dirt.getState();
|
||||
|
||||
if (noiseVal > 1.75D)
|
||||
{
|
||||
this.topBlock = Blocks.stone.getState();
|
||||
this.fillerBlock = Blocks.stone.getState();
|
||||
}
|
||||
else if (noiseVal > -0.5D)
|
||||
{
|
||||
this.topBlock = Blocks.dirt.getState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.COARSE_DIRT);
|
||||
}
|
||||
|
||||
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
this.decorateNormal(worldIn, rand, pos);
|
||||
}
|
||||
}
|
||||
}
|
65
server/src/main/java/server/biome/BiomeSnow.java
Executable file
65
server/src/main/java/server/biome/BiomeSnow.java
Executable file
|
@ -0,0 +1,65 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.util.BlockPos;
|
||||
import server.world.WorldServer;
|
||||
import server.worldgen.feature.WorldGenIcePath;
|
||||
import server.worldgen.feature.WorldGenIceSpike;
|
||||
import server.worldgen.tree.WorldGenTaiga2;
|
||||
import server.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeSnow extends GenBiome
|
||||
{
|
||||
private final WorldGenIceSpike spikeGen = new WorldGenIceSpike();
|
||||
private final WorldGenIcePath pathGen = new WorldGenIcePath(4);
|
||||
private final boolean spiky;
|
||||
|
||||
public BiomeSnow(Biome base, boolean spiky)
|
||||
{
|
||||
super(base);
|
||||
this.spiky = spiky;
|
||||
if(spiky)
|
||||
this.topBlock = Blocks.snow.getState();
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
if (this.spiky)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
int j = rand.chOffset();
|
||||
int k = rand.chOffset();
|
||||
this.spikeGen.generate(worldIn, rand, worldIn.getHeight(pos.add(j, 0, k)));
|
||||
}
|
||||
|
||||
for (int l = 0; l < 2; ++l)
|
||||
{
|
||||
int i1 = rand.chOffset();
|
||||
int j1 = rand.chOffset();
|
||||
this.pathGen.generate(worldIn, rand, worldIn.getHeight(pos.add(i1, 0, j1)));
|
||||
}
|
||||
}
|
||||
|
||||
super.decorate(worldIn, rand, pos);
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return new WorldGenTaiga2(false);
|
||||
}
|
||||
|
||||
protected GenBiome createMutatedBiome(Biome base)
|
||||
{
|
||||
GenBiome biomegenbase = (new BiomeSnow(base, true)).enableColdBeach().setScaling(this.depth + 0.1F, this.scale + 0.1F);
|
||||
biomegenbase.depth = this.depth + 0.3F;
|
||||
biomegenbase.scale = this.scale + 0.4F;
|
||||
return biomegenbase;
|
||||
}
|
||||
}
|
23
server/src/main/java/server/biome/BiomeSnowLand.java
Executable file
23
server/src/main/java/server/biome/BiomeSnowLand.java
Executable file
|
@ -0,0 +1,23 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.entity.animal.EntitySheep;
|
||||
import common.entity.npc.EntitySpirit;
|
||||
import common.init.Blocks;
|
||||
import common.rng.WeightedList;
|
||||
|
||||
public class BiomeSnowLand extends GenBiome
|
||||
{
|
||||
public BiomeSnowLand()
|
||||
{
|
||||
super(Biome.SNOWLAND);
|
||||
this.topBlock = Blocks.snow.getState();
|
||||
this.fillerBlock = Blocks.snow.getState();
|
||||
this.mushroomsPerChunk = -1;
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
mobs.add(new RngSpawn(EntitySheep.class, 50, 4, 4));
|
||||
mobs.add(new RngSpawn(EntitySpirit.class, 10, 1, 1));
|
||||
}
|
||||
}
|
39
server/src/main/java/server/biome/BiomeSpace.java
Executable file
39
server/src/main/java/server/biome/BiomeSpace.java
Executable file
|
@ -0,0 +1,39 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.block.natural.BlockDirt;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.util.BlockPos;
|
||||
import server.world.WorldServer;
|
||||
import server.worldgen.FeatureGenerator;
|
||||
import server.worldgen.feature.WorldGenAsteroid;
|
||||
|
||||
public class BiomeSpace extends GenBiome
|
||||
{
|
||||
protected FeatureGenerator asteroidGen1 = new WorldGenAsteroid(Blocks.stone.getState(),
|
||||
Blocks.rock.getState());
|
||||
protected FeatureGenerator asteroidGen2 = new WorldGenAsteroid(Blocks.dirt.getState(),
|
||||
Blocks.dirt.getState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.COARSE_DIRT));
|
||||
|
||||
public BiomeSpace()
|
||||
{
|
||||
super(Biome.SPACE);
|
||||
this.topBlock = Blocks.air.getState();
|
||||
this.fillerBlock = Blocks.air.getState();
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
if(rand.chance(5)) {
|
||||
int x = rand.chOffset();
|
||||
int z = rand.chOffset();
|
||||
rand.chance(this.asteroidGen1, this.asteroidGen2, 100).generate(worldIn, rand,
|
||||
pos.add(x, rand.range(16, 495), z));
|
||||
}
|
||||
}
|
||||
}
|
23
server/src/main/java/server/biome/BiomeStoneBeach.java
Executable file
23
server/src/main/java/server/biome/BiomeStoneBeach.java
Executable file
|
@ -0,0 +1,23 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.init.Blocks;
|
||||
import common.rng.WeightedList;
|
||||
|
||||
public class BiomeStoneBeach extends GenBiome
|
||||
{
|
||||
public BiomeStoneBeach()
|
||||
{
|
||||
super(Biome.STONEBEACH);
|
||||
// this.mobs.clear();
|
||||
this.topBlock = Blocks.stone.getState();
|
||||
this.fillerBlock = Blocks.stone.getState();
|
||||
this.treesPerChunk = -999;
|
||||
this.deadBushPerChunk = 0;
|
||||
this.reedsPerChunk = 0;
|
||||
this.cactiPerChunk = 0;
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
}
|
||||
}
|
74
server/src/main/java/server/biome/BiomeSwamp.java
Executable file
74
server/src/main/java/server/biome/BiomeSwamp.java
Executable file
|
@ -0,0 +1,74 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.block.BlockDirectional;
|
||||
import common.block.foliage.BlockFlower;
|
||||
import common.entity.npc.EntitySlime;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Facing;
|
||||
import server.world.WorldServer;
|
||||
import server.worldgen.ChunkPrimer;
|
||||
import server.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeSwamp extends GenBiome
|
||||
{
|
||||
protected BiomeSwamp()
|
||||
{
|
||||
super(Biome.SWAMPLAND);
|
||||
this.treesPerChunk = 2;
|
||||
this.flowersPerChunk = 1;
|
||||
this.deadBushPerChunk = 1;
|
||||
this.mushroomsPerChunk = 8;
|
||||
this.reedsPerChunk = 10;
|
||||
this.clayPerChunk = 1;
|
||||
this.waterlilyPerChunk = 4;
|
||||
this.sandPerChunk2 = 0;
|
||||
this.sandPerChunk = 0;
|
||||
this.grassPerChunk = 5;
|
||||
this.mobs.add(new RngSpawn(EntitySlime.class, 1, 1, 1));
|
||||
this.disableBeach();
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return this.worldGeneratorSwamp;
|
||||
}
|
||||
|
||||
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
|
||||
{
|
||||
return BlockFlower.EnumFlowerType.BLUE_ORCHID;
|
||||
}
|
||||
|
||||
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
|
||||
{
|
||||
double d0 = GRASS_NOISE.generate((double)x * 0.25D, (double)z * 0.25D);
|
||||
|
||||
if (d0 > 0.0D)
|
||||
{
|
||||
int i = x & 15;
|
||||
int j = z & 15;
|
||||
|
||||
for (int k = chunkPrimerIn.height - 1; k >= 0; --k)
|
||||
{
|
||||
if (chunkPrimerIn.get(j, k, i).getBlock() != Blocks.air)
|
||||
{
|
||||
if (k == 62 && chunkPrimerIn.get(j, k, i).getBlock() != Blocks.water)
|
||||
{
|
||||
chunkPrimerIn.set(j, k, i, Blocks.water.getState());
|
||||
|
||||
if (d0 < 0.12D)
|
||||
{
|
||||
chunkPrimerIn.set(j, k + 1, i, Blocks.waterlily.getState().withProperty(BlockDirectional.FACING, Facing.randHorizontal(rand)));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
|
||||
}
|
||||
}
|
115
server/src/main/java/server/biome/BiomeTaiga.java
Executable file
115
server/src/main/java/server/biome/BiomeTaiga.java
Executable file
|
@ -0,0 +1,115 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.block.foliage.BlockDoublePlant;
|
||||
import common.block.foliage.BlockTallGrass;
|
||||
import common.block.natural.BlockDirt;
|
||||
import common.entity.animal.EntityWolf;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import server.world.WorldServer;
|
||||
import server.worldgen.ChunkPrimer;
|
||||
import server.worldgen.FeatureGenerator;
|
||||
import server.worldgen.feature.WorldGenBlockBlob;
|
||||
import server.worldgen.foliage.WorldGenTallGrass;
|
||||
import server.worldgen.tree.WorldGenPine;
|
||||
import server.worldgen.tree.WorldGenTaiga1;
|
||||
import server.worldgen.tree.WorldGenTaiga2;
|
||||
import server.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeTaiga extends GenBiome
|
||||
{
|
||||
private static final WorldGenTaiga1 field_150639_aC = new WorldGenTaiga1();
|
||||
private static final WorldGenTaiga2 field_150640_aD = new WorldGenTaiga2(false);
|
||||
private static final WorldGenPine field_150641_aE = new WorldGenPine(false, false);
|
||||
private static final WorldGenPine field_150642_aF = new WorldGenPine(false, true);
|
||||
private static final WorldGenBlockBlob field_150643_aG = new WorldGenBlockBlob(Blocks.mossy_cobblestone, 0);
|
||||
private int field_150644_aH;
|
||||
|
||||
public BiomeTaiga(Biome base, int p_i45385_2_)
|
||||
{
|
||||
super(base);
|
||||
this.field_150644_aH = p_i45385_2_;
|
||||
this.mobs.add(new RngSpawn(EntityWolf.class, 8, 4, 4));
|
||||
this.treesPerChunk = 10;
|
||||
|
||||
if (p_i45385_2_ != 1 && p_i45385_2_ != 2)
|
||||
{
|
||||
this.grassPerChunk = 1;
|
||||
this.mushroomsPerChunk = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.grassPerChunk = 7;
|
||||
this.deadBushPerChunk = 1;
|
||||
this.mushroomsPerChunk = 3;
|
||||
}
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return (WorldGenTree)((this.field_150644_aH == 1 || this.field_150644_aH == 2) && rand.chance(3) ? (this.field_150644_aH != 2 && rand.rarity(13) ? field_150641_aE : field_150642_aF) : (rand.chance(3) ? field_150639_aC : field_150640_aD));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a WorldGen appropriate for this biome.
|
||||
*/
|
||||
public FeatureGenerator getRandomWorldGenForGrass(Random rand)
|
||||
{
|
||||
return rand.rarity(5) ? new WorldGenTallGrass(BlockTallGrass.EnumType.FERN) : new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS);
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
if (this.field_150644_aH == 1 || this.field_150644_aH == 2)
|
||||
{
|
||||
int i = rand.zrange(3);
|
||||
|
||||
for (int j = 0; j < i; ++j)
|
||||
{
|
||||
int k = rand.chOffset();
|
||||
int l = rand.chOffset();
|
||||
BlockPos blockpos = worldIn.getHeight(pos.add(k, 0, l));
|
||||
field_150643_aG.generate(worldIn, rand, blockpos);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_PLANT_GEN.setPlantType(BlockDoublePlant.EnumPlantType.FERN);
|
||||
|
||||
for (int i1 = 0; i1 < 7; ++i1)
|
||||
{
|
||||
int j1 = rand.chOffset();
|
||||
int k1 = rand.chOffset();
|
||||
int l1 = rand.zrange(worldIn.getHeight(pos.add(j1, 0, k1)).getY() + 32);
|
||||
DOUBLE_PLANT_GEN.generate(worldIn, rand, pos.add(j1, l1, k1));
|
||||
}
|
||||
|
||||
super.decorate(worldIn, rand, pos);
|
||||
}
|
||||
|
||||
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
|
||||
{
|
||||
if (this.field_150644_aH == 1 || this.field_150644_aH == 2)
|
||||
{
|
||||
this.topBlock = Blocks.grass.getState();
|
||||
this.fillerBlock = Blocks.dirt.getState();
|
||||
|
||||
if (noiseVal > 1.75D)
|
||||
{
|
||||
this.topBlock = Blocks.dirt.getState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.COARSE_DIRT);
|
||||
}
|
||||
else if (noiseVal > -0.95D)
|
||||
{
|
||||
this.topBlock = Blocks.dirt.getState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.PODZOL);
|
||||
}
|
||||
}
|
||||
|
||||
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
|
||||
}
|
||||
|
||||
protected GenBiome createMutatedBiome(Biome base)
|
||||
{
|
||||
return this.base == Biome.MEGATAIGA ? (new BiomeTaiga(base, 2)).setScaling(this.depth, this.scale) : super.createMutatedBiome(base);
|
||||
}
|
||||
}
|
83
server/src/main/java/server/biome/BiomeTian.java
Executable file
83
server/src/main/java/server/biome/BiomeTian.java
Executable file
|
@ -0,0 +1,83 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.block.foliage.BlockFlower;
|
||||
import common.entity.animal.EntityBat;
|
||||
import common.entity.animal.EntityMouse;
|
||||
import common.entity.animal.EntityRabbit;
|
||||
import common.entity.npc.EntityCultivator;
|
||||
import common.init.Blocks;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.util.BlockPos;
|
||||
import server.world.WorldServer;
|
||||
import server.worldgen.FeatureGenerator;
|
||||
import server.worldgen.feature.WorldGenSpikes;
|
||||
import server.worldgen.foliage.WorldGenMushroom;
|
||||
import server.worldgen.tree.WorldGenBaseTree;
|
||||
import server.worldgen.tree.WorldGenBigTree;
|
||||
import server.worldgen.tree.WorldGenTree;
|
||||
|
||||
public class BiomeTian extends GenBiome
|
||||
{
|
||||
protected FeatureGenerator spikeGen = new WorldGenSpikes(Blocks.tian_soil, 128, 2, 3, Blocks.obsidian.getState(), true);
|
||||
protected FeatureGenerator mushroomBlueGen = new WorldGenMushroom(Blocks.blue_mushroom);
|
||||
protected WorldGenTree treeGen1 = new WorldGenBigTree(false, Blocks.tian_log.getState(), Blocks.tian_leaves.getState())
|
||||
.setHeightLimit(6, 8);
|
||||
protected WorldGenTree treeGen2 = new WorldGenBigTree(false, Blocks.tian_log.getState(), Blocks.tian_leaves.getState())
|
||||
.setHeightLimit(14, 20);
|
||||
protected WorldGenTree treeGen3 = new WorldGenBaseTree(false, Blocks.tian_log.getState(), Blocks.tian_leaves.getState());
|
||||
protected WorldGenTree treeGen4 = new WorldGenBigTree(false, Blocks.tian_log.getState(), Blocks.tian_leaves.getState())
|
||||
.setHeightLimit(12, 15);
|
||||
|
||||
public BiomeTian()
|
||||
{
|
||||
super(Biome.TIAN);
|
||||
this.topBlock = Blocks.tian_soil.getState();
|
||||
this.fillerBlock = Blocks.tian.getState();
|
||||
this.mushroomsPerChunk = -1;
|
||||
this.grassPerChunk = 0;
|
||||
this.treesPerChunk = 1;
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
// mobs.add(new Biome.RngSpawn(EntityHaunter.class, 50, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityCultivator.class, 50, 1, 1));
|
||||
mobs.add(new RngSpawn(EntityRabbit.class, 10, 3, 10));
|
||||
mobs.add(new RngSpawn(EntityBat.class, 10, 8, 8));
|
||||
mobs.add(new RngSpawn(EntityMouse.class, 10, 8, 8));
|
||||
}
|
||||
|
||||
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
|
||||
{
|
||||
return BlockFlower.EnumFlowerType.BLACK_LOTUS;
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return rand.pick(rand.chance(this.treeGen2, this.treeGen1, 4), rand.chance(this.treeGen3, this.treeGen4, 15));
|
||||
}
|
||||
|
||||
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
|
||||
{
|
||||
super.decorate(worldIn, rand, pos);
|
||||
|
||||
for (int l3 = 0; l3 < 2; ++l3)
|
||||
{
|
||||
if (rand.chance(4))
|
||||
{
|
||||
int i8 = rand.chOffset();
|
||||
int l11 = rand.chOffset();
|
||||
BlockPos blockpos2 = worldIn.getHeight(pos.add(i8, 0, l11));
|
||||
this.mushroomBlueGen.generate(worldIn, rand, blockpos2);
|
||||
}
|
||||
}
|
||||
|
||||
if (rand.chance(4))
|
||||
{
|
||||
int i = rand.chOffset();
|
||||
int j = rand.chOffset();
|
||||
this.spikeGen.generate(worldIn, rand, worldIn.getTopSolidOrLiquidBlock(pos.add(i, 0, j)));
|
||||
}
|
||||
}
|
||||
}
|
23
server/src/main/java/server/biome/BiomeWater.java
Executable file
23
server/src/main/java/server/biome/BiomeWater.java
Executable file
|
@ -0,0 +1,23 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.entity.animal.EntitySquid;
|
||||
import common.rng.WeightedList;
|
||||
|
||||
public class BiomeWater extends GenBiome {
|
||||
private final boolean river;
|
||||
|
||||
public BiomeWater(Biome base, boolean river) {
|
||||
super(base);
|
||||
this.river = river;
|
||||
this.disableBeach();
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
mobs.add(new RngSpawn(EntitySquid.class, 10, 4, 4));
|
||||
}
|
||||
|
||||
public Temperature getTempCategory() {
|
||||
return this.river ? super.getTempCategory() : Temperature.SEA;
|
||||
}
|
||||
}
|
874
server/src/main/java/server/biome/GenBiome.java
Executable file
874
server/src/main/java/server/biome/GenBiome.java
Executable file
|
@ -0,0 +1,874 @@
|
|||
package server.biome;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.biome.IBiome;
|
||||
import common.block.Block;
|
||||
import common.block.BlockColored;
|
||||
import common.block.Material;
|
||||
import common.block.foliage.BlockFlower;
|
||||
import common.block.foliage.BlockSapling;
|
||||
import common.block.foliage.BlockTallGrass;
|
||||
import common.block.natural.BlockSand;
|
||||
import common.color.DyeColor;
|
||||
import common.entity.animal.EntityBat;
|
||||
import common.entity.animal.EntityChicken;
|
||||
import common.entity.animal.EntityCow;
|
||||
import common.entity.animal.EntityMouse;
|
||||
import common.entity.animal.EntityPig;
|
||||
import common.entity.animal.EntityRabbit;
|
||||
import common.entity.animal.EntitySheep;
|
||||
import common.entity.animal.EntitySquid;
|
||||
import common.entity.npc.EntityArachnoid;
|
||||
import common.entity.npc.EntityHaunter;
|
||||
import common.entity.npc.EntityMage;
|
||||
import common.entity.npc.EntitySlime;
|
||||
import common.entity.npc.EntityUndead;
|
||||
import common.entity.npc.EntityZombie;
|
||||
import common.init.Blocks;
|
||||
import common.init.WoodType;
|
||||
import common.log.Log;
|
||||
import common.rng.PerlinGen;
|
||||
import common.rng.Random;
|
||||
import common.rng.WeightedList;
|
||||
import common.util.BlockPos;
|
||||
import common.world.AWorldServer;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
import server.world.WorldServer;
|
||||
import server.worldgen.ChunkPrimer;
|
||||
import server.worldgen.FeatureGenerator;
|
||||
import server.worldgen.feature.WorldGenClay;
|
||||
import server.worldgen.feature.WorldGenClayExt;
|
||||
import server.worldgen.feature.WorldGenSand;
|
||||
import server.worldgen.foliage.FeatureDoublePlant;
|
||||
import server.worldgen.foliage.WorldGenBigMushroom;
|
||||
import server.worldgen.foliage.WorldGenCactus;
|
||||
import server.worldgen.foliage.WorldGenDeadBush;
|
||||
import server.worldgen.foliage.WorldGenFlowers;
|
||||
import server.worldgen.foliage.WorldGenMushroom;
|
||||
import server.worldgen.foliage.WorldGenPumpkin;
|
||||
import server.worldgen.foliage.WorldGenReed;
|
||||
import server.worldgen.foliage.WorldGenTallGrass;
|
||||
import server.worldgen.foliage.WorldGenWaterlily;
|
||||
import server.worldgen.tree.WorldGenBaseTree;
|
||||
import server.worldgen.tree.WorldGenBigTree;
|
||||
import server.worldgen.tree.WorldGenBirch;
|
||||
import server.worldgen.tree.WorldGenDarkOak;
|
||||
import server.worldgen.tree.WorldGenJungle;
|
||||
import server.worldgen.tree.WorldGenPine;
|
||||
import server.worldgen.tree.WorldGenSavanna;
|
||||
import server.worldgen.tree.WorldGenSwamp;
|
||||
import server.worldgen.tree.WorldGenTaiga2;
|
||||
import server.worldgen.tree.WorldGenTree;
|
||||
|
||||
public abstract class GenBiome implements IBiome {
|
||||
public static final GenBiome[] BIOMES = new GenBiome[256];
|
||||
|
||||
public static final GenBiome none = (new BiomeNone());
|
||||
|
||||
public static final GenBiome plains = (new BiomePlains());
|
||||
public static final GenBiome desert = (new BiomeDesert(false)).setScaling(Scaling.PLAINS_LOW);
|
||||
public static final GenBiome extremeHills = (new BiomeHills(Biome.EXTREMEHILLS, false)).setScaling(Scaling.HILLS_LARGE);
|
||||
public static final GenBiome forest = (new BiomeForest(Biome.FOREST, 0));
|
||||
public static final GenBiome taiga = (new BiomeTaiga(Biome.TAIGA, 0)).setScaling(Scaling.PLAINS_MEDIUM);
|
||||
public static final GenBiome swampland = (new BiomeSwamp()).setScaling(Scaling.SEA_POND);
|
||||
public static final GenBiome river = (new BiomeWater(Biome.RIVER, true)).setScaling(Scaling.SEA_SHALLOW);
|
||||
|
||||
public static final GenBiome exterminated = (new BiomeExterminated());
|
||||
public static final GenBiome space = (new BiomeSpace());
|
||||
|
||||
public static final GenBiome frozenSea = (new BiomeWater(Biome.FROZENSEA, false)).enableColdBeach().setScaling(Scaling.SEA_MEDIUM);
|
||||
public static final GenBiome frozenRiver = (new BiomeWater(Biome.FROZENRIVER, true)).enableColdBeach().setScaling(Scaling.SEA_SHALLOW);
|
||||
public static final GenBiome icePlains = (new BiomeSnow(Biome.ICEPLAINS, false)).enableColdBeach().setScaling(Scaling.PLAINS_LOW);
|
||||
public static final GenBiome iceMountains = (new BiomeSnow(Biome.ICEMOUNTAINS, false)).enableColdBeach().setScaling(Scaling.HILLS_LOW);
|
||||
public static final GenBiome mushroomPlains = (new BiomeMushroom()).setScaling(Scaling.PLAINS_VARYING);
|
||||
public static final GenBiome blackened = (new BiomeBlackened());
|
||||
public static final GenBiome beach = (new BiomeBeach(false)).setScaling(Scaling.SEA_SHORE);
|
||||
public static final GenBiome desertHills = (new BiomeDesert(true)).setScaling(Scaling.HILLS_LOW);
|
||||
public static final GenBiome forestHills = (new BiomeForest(Biome.FORESTHILLS, 0)).setScaling(Scaling.HILLS_LOW);
|
||||
public static final GenBiome taigaHills = (new BiomeTaiga(Biome.TAIGAHILLS, 0)).setScaling(Scaling.HILLS_LOW);
|
||||
public static final GenBiome extremeHillsEdge = (new BiomeHills(Biome.EXTREMEHILLSEDGE, true)).setScaling(Scaling.HILLS_MEDIUM);
|
||||
public static final GenBiome jungle = (new BiomeJungle(Biome.JUNGLE, false));
|
||||
public static final GenBiome jungleHills = (new BiomeJungle(Biome.JUNGLEHILLS, false)).setScaling(Scaling.HILLS_LOW);
|
||||
public static final GenBiome jungleEdge = (new BiomeJungle(Biome.JUNGLEEDGE, true));
|
||||
public static final GenBiome sea = (new BiomeWater(Biome.SEA, false)).setScaling(Scaling.SEA_MEDIUM);
|
||||
public static final GenBiome stoneBeach = (new BiomeStoneBeach()).setScaling(Scaling.SEA_VARYING);
|
||||
public static final GenBiome coldBeach = (new BiomeBeach(true)).setScaling(Scaling.SEA_SHORE).enableColdBeach();
|
||||
public static final GenBiome birchForest = (new BiomeForest(Biome.BIRCHFOREST, 2));
|
||||
public static final GenBiome birchForestHills = (new BiomeForest(Biome.BIRCHFORESTHILLS, 2)).setScaling(Scaling.HILLS_LOW);
|
||||
public static final GenBiome roofedForest = (new BiomeForest(Biome.ROOFEDFOREST, 3));
|
||||
public static final GenBiome coldTaiga = (new BiomeTaiga(Biome.COLDTAIGA, 0)).enableColdBeach().setScaling(Scaling.PLAINS_MEDIUM);
|
||||
public static final GenBiome coldTaigaHills = (new BiomeTaiga(Biome.COLDTAIGAHILLS, 0)).enableColdBeach().setScaling(Scaling.HILLS_LOW);
|
||||
public static final GenBiome megaTaiga = (new BiomeTaiga(Biome.MEGATAIGA, 1)).setScaling(Scaling.PLAINS_MEDIUM);
|
||||
public static final GenBiome megaTaigaHills = (new BiomeTaiga(Biome.MEGATAIGAHILLS, 1)).setScaling(Scaling.HILLS_LOW);
|
||||
public static final GenBiome extremeHillsPlus = (new BiomeHills(Biome.EXTREMEHILLSPLUS, true)).setScaling(Scaling.HILLS_LARGE);
|
||||
public static final GenBiome savanna = (new BiomeSavanna(false)).setScaling(Scaling.PLAINS_LOW);
|
||||
public static final GenBiome savannaPlateau = (new BiomeSavanna(true)).setScaling(Scaling.HILLS_PLATEAU);
|
||||
|
||||
public static final GenBiome mesa = (new BiomeMesa(Biome.MESA, false, false));
|
||||
public static final GenBiome mesaPlateau_F = (new BiomeMesa(Biome.MESAPLATEAUF, false, true)).setScaling(Scaling.HILLS_PLATEAU);
|
||||
public static final GenBiome mesaPlateau = (new BiomeMesa(Biome.MESAPLATEAU, false, false)).setScaling(Scaling.HILLS_PLATEAU);
|
||||
|
||||
public static final GenBiome snowLand = (new BiomeSnowLand()).enableColdBeach();
|
||||
public static final GenBiome tian = (new BiomeTian()).setScaling(Scaling.VARYING_MEDIUM);
|
||||
public static final GenBiome elvenForest = (new BiomeForest(Biome.ELVENFOREST, 4));
|
||||
public static final GenBiome upperHell = (new BiomeHell(Biome.UPPERHELL, 0));
|
||||
public static final GenBiome lowerHell = (new BiomeHell(Biome.LOWERHELL, 1));
|
||||
public static final GenBiome hellHills = (new BiomeHell(Biome.HELLHILLS, 1)).setScaling(Scaling.HILLS_LARGE);
|
||||
public static final GenBiome soulPlains = (new BiomeHell(Biome.SOULPLAINS, 1)).setScaling(Scaling.SEA_POND);
|
||||
public static final GenBiome ashLand = (new BiomeHell(Biome.ASHLAND, 2)).setScaling(Scaling.PLAINS_LOW);
|
||||
public static final GenBiome moon = (new BiomeMoon()).setScaling(Scaling.PLAINS_LOW);
|
||||
public static final GenBiome chaos = (new BiomeChaos()).setScaling(Scaling.VARYING_CHAOTIC);
|
||||
|
||||
protected static final PerlinGen TREE_NOISE = new PerlinGen(new Random(726528729282625L), 8);
|
||||
protected static final PerlinGen GRASS_NOISE = new PerlinGen(new Random(297363826225L), 1);
|
||||
protected static final FeatureDoublePlant DOUBLE_PLANT_GEN = new FeatureDoublePlant();
|
||||
|
||||
public final Biome base;
|
||||
|
||||
protected final WeightedList<RngSpawn> mobs = new WeightedList<RngSpawn>();
|
||||
protected final WorldGenBaseTree worldGeneratorTrees = new WorldGenBaseTree(false);
|
||||
protected final WorldGenBigTree worldGeneratorBigTree = new WorldGenBigTree(false);
|
||||
protected final WorldGenSwamp worldGeneratorSwamp = new WorldGenSwamp();
|
||||
private final FeatureGenerator clayGen = new WorldGenClay(4);
|
||||
private final FeatureGenerator sandGen = new WorldGenSand(Blocks.sand, 7);
|
||||
private final FeatureGenerator gravelAsSandGen = new WorldGenSand(Blocks.gravel, 6);
|
||||
private final WorldGenFlowers yellowFlowerGen = new WorldGenFlowers(Blocks.flower, BlockFlower.EnumFlowerType.DANDELION);
|
||||
private final FeatureGenerator mushroomBrownGen = new WorldGenMushroom(Blocks.brown_mushroom);
|
||||
private final FeatureGenerator mushroomRedGen = new WorldGenMushroom(Blocks.red_mushroom);
|
||||
private final FeatureGenerator bigMushroomGen = new WorldGenBigMushroom();
|
||||
private final FeatureGenerator reedGen = new WorldGenReed();
|
||||
private final FeatureGenerator cactusGen = new WorldGenCactus();
|
||||
private final FeatureGenerator waterlilyGen = new WorldGenWaterlily();
|
||||
private final FeatureGenerator clayGenExt = new WorldGenClayExt(32);
|
||||
|
||||
public State topBlock = Blocks.grass.getState();
|
||||
public State fillerBlock = Blocks.dirt.getState();
|
||||
public float depth = Scaling.VARYING_LOW.depth;
|
||||
public float scale = Scaling.VARYING_LOW.scale;
|
||||
public boolean generateLakes = true;
|
||||
public boolean generateLiquids = true;
|
||||
public boolean allowColdBeach = false;
|
||||
public boolean disallowBeach = false;
|
||||
|
||||
protected int waterlilyPerChunk = 0;
|
||||
protected int treesPerChunk = 0;
|
||||
protected int flowersPerChunk = 2;
|
||||
protected int grassPerChunk = 1;
|
||||
protected int deadBushPerChunk = 0;
|
||||
protected int mushroomsPerChunk = 0;
|
||||
protected int reedsPerChunk = 0;
|
||||
protected int cactiPerChunk = 0;
|
||||
protected int sandPerChunk = 1;
|
||||
protected int sandPerChunk2 = 3;
|
||||
protected int clayPerChunk = 1;
|
||||
protected int clayExtPerChunk = 0; // 10
|
||||
protected int bigMushroomsPerChunk = 0;
|
||||
|
||||
public static GenBiome getBiome(int id)
|
||||
{
|
||||
if (id >= 0 && id < BIOMES.length)
|
||||
{
|
||||
return BIOMES[id];
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.TICK.warn("Biom-ID ist nicht im Bereich: " + id + ", verwende " + Biome.DEF_BIOME.id + " (" + Biome.DEF_BIOME.name + ")");
|
||||
return BIOMES[Biome.DEF_BIOME.id];
|
||||
}
|
||||
}
|
||||
|
||||
public static void setAsProvider() {
|
||||
IBiome.setProvider(new IBiome.BiomeProvider() {
|
||||
public final IBiome getBiome(Biome base) {
|
||||
return BIOMES[base.id];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static {
|
||||
desert.createMutatedBiome(Biome.DESERTM);
|
||||
forest.createMutatedBiome(Biome.FLOWERFOREST);
|
||||
taiga.createMutatedBiome(Biome.TAIGAM);
|
||||
swampland.createMutatedBiome(Biome.SWAMPLANDM);
|
||||
icePlains.createMutatedBiome(Biome.ICEPLAINSSPIKES);
|
||||
jungle.createMutatedBiome(Biome.JUNGLEM);
|
||||
jungleEdge.createMutatedBiome(Biome.JUNGLEEDGEM);
|
||||
coldTaiga.createMutatedBiome(Biome.COLDTAIGAM);
|
||||
savanna.createMutatedBiome(Biome.SAVANNAM);
|
||||
savannaPlateau.createMutatedBiome(Biome.SAVANNAPLATEAUM);
|
||||
mesa.createMutatedBiome(Biome.MESABRYCE);
|
||||
mesaPlateau_F.createMutatedBiome(Biome.MESAPLATEAUFM);
|
||||
mesaPlateau.createMutatedBiome(Biome.MESAPLATEAUM);
|
||||
birchForest.createMutatedBiome(Biome.BIRCHFORESTM);
|
||||
birchForestHills.createMutatedBiome(Biome.BIRCHFORESTHILLSM);
|
||||
roofedForest.createMutatedBiome(Biome.ROOFEDFORESTM);
|
||||
megaTaiga.createMutatedBiome(Biome.MEGASPRUCETAIGA);
|
||||
extremeHills.createMutatedBiome(Biome.EXTREMEHILLSM);
|
||||
extremeHillsPlus.createMutatedBiome(Biome.EXTREMEHILLSPLUSM);
|
||||
megaTaiga.createMutatedBiome(Biome.REDWOODTAIGAHILLSM);
|
||||
}
|
||||
|
||||
protected GenBiome(Biome base) {
|
||||
BIOMES[base.id] = this;
|
||||
this.base = base;
|
||||
this.addMobs(this.mobs);
|
||||
}
|
||||
|
||||
protected void addMobs(WeightedList<RngSpawn> mobs) {
|
||||
mobs.add(new RngSpawn(EntitySheep.class, 12, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityRabbit.class, 10, 3, 10));
|
||||
mobs.add(new RngSpawn(EntityPig.class, 10, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityChicken.class, 10, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityCow.class, 8, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityArachnoid.class, 100, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityZombie.class, 100, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityUndead.class, 100, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityHaunter.class, 100, 4, 4));
|
||||
mobs.add(new RngSpawn(EntitySlime.class, 100, 4, 4));
|
||||
// mobs.add(new Biome.RngSpawn(EntityEnder....class, 10, 1, 4));
|
||||
mobs.add(new RngSpawn(EntityMage.class, 5, 1, 1));
|
||||
mobs.add(new RngSpawn(EntitySquid.class, 10, 4, 4));
|
||||
mobs.add(new RngSpawn(EntityBat.class, 10, 8, 8));
|
||||
mobs.add(new RngSpawn(EntityMouse.class, 10, 8, 8));
|
||||
}
|
||||
|
||||
protected final GenBiome setScaling(Scaling scaling)
|
||||
{
|
||||
return this.setScaling(scaling.depth, scaling.scale);
|
||||
}
|
||||
|
||||
protected final GenBiome setScaling(float depth, float scale)
|
||||
{
|
||||
this.depth = depth;
|
||||
this.scale = scale;
|
||||
return this;
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeChance(Random rand)
|
||||
{
|
||||
return rand.chance(10) ? this.worldGeneratorBigTree : this.worldGeneratorTrees;
|
||||
}
|
||||
|
||||
public WorldGenTree genBigTreeLegacy(Random rand, BlockPos pos)
|
||||
{
|
||||
int noise = (int)((TREE_NOISE.generate((double)pos.getX() * 0.5D, (double)pos.getZ() * 0.5D) / 8D + rand.doublev() * 4D + 4D) / 3D);
|
||||
return (noise > 0 && rand.chance(noise)) || (this.base.isHighHumidity() && rand.chance(3)) ? this.worldGeneratorBigTree :
|
||||
this.worldGeneratorTrees;
|
||||
}
|
||||
|
||||
public FeatureGenerator getRandomWorldGenForGrass(Random rand)
|
||||
{
|
||||
return new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS);
|
||||
}
|
||||
|
||||
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
|
||||
{
|
||||
return rand.rarity(3) ? BlockFlower.EnumFlowerType.DANDELION : BlockFlower.EnumFlowerType.ROSE;
|
||||
}
|
||||
|
||||
public State getFiller() {
|
||||
return this.fillerBlock;
|
||||
}
|
||||
|
||||
public State getTop() {
|
||||
return this.topBlock;
|
||||
}
|
||||
|
||||
protected GenBiome enableColdBeach()
|
||||
{
|
||||
this.allowColdBeach = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected GenBiome disableBeach()
|
||||
{
|
||||
this.disallowBeach = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public WeightedList<RngSpawn> getMobs()
|
||||
{
|
||||
return this.mobs;
|
||||
}
|
||||
|
||||
public float getMobGenChance()
|
||||
{
|
||||
return 0.1F;
|
||||
}
|
||||
|
||||
public void decorate(WorldServer world, Random rand, BlockPos pos)
|
||||
{
|
||||
for (int i = 0; i < this.sandPerChunk2; ++i)
|
||||
{
|
||||
int j = rand.chOffset();
|
||||
int k = rand.chOffset();
|
||||
this.sandGen.generate(world, rand, world.getTopSolidOrLiquidBlock(pos.add(j, 0, k)));
|
||||
}
|
||||
|
||||
for (int i1 = 0; i1 < this.clayPerChunk; ++i1)
|
||||
{
|
||||
int l1 = rand.chOffset();
|
||||
int i6 = rand.chOffset();
|
||||
this.clayGen.generate(world, rand, world.getTopSolidOrLiquidBlock(pos.add(l1, 0, i6)));
|
||||
}
|
||||
|
||||
for (int j1 = 0; j1 < this.sandPerChunk; ++j1)
|
||||
{
|
||||
int i2 = rand.chOffset();
|
||||
int j6 = rand.chOffset();
|
||||
this.gravelAsSandGen.generate(world, rand, world.getTopSolidOrLiquidBlock(pos.add(i2, 0, j6)));
|
||||
}
|
||||
|
||||
for (int i1 = 0; i1 < this.clayExtPerChunk; ++i1)
|
||||
{
|
||||
int l1 = rand.chOffset();
|
||||
int i6 = rand.chOffset();
|
||||
this.clayGenExt.generate(world, rand, world.getTopSolidOrLiquidBlock(pos.add(l1, 0, i6)));
|
||||
}
|
||||
|
||||
int k1 = this.treesPerChunk;
|
||||
|
||||
if (rand.chance(10))
|
||||
{
|
||||
++k1;
|
||||
}
|
||||
|
||||
for (int j2 = 0; j2 < k1; ++j2)
|
||||
{
|
||||
int k6 = rand.chOffset();
|
||||
int l = rand.chOffset();
|
||||
WorldGenTree treeGen = this.genBigTreeChance(rand);
|
||||
treeGen.prepare();
|
||||
BlockPos blockpos = world.getHeight(pos.add(k6, 0, l));
|
||||
|
||||
if (treeGen.generate(world, rand, blockpos))
|
||||
{
|
||||
treeGen.finish(world, rand, blockpos);
|
||||
}
|
||||
}
|
||||
|
||||
for (int k2 = 0; k2 < this.bigMushroomsPerChunk; ++k2)
|
||||
{
|
||||
int l6 = rand.chOffset();
|
||||
int k10 = rand.chOffset();
|
||||
this.bigMushroomGen.generate(world, rand, world.getHeight(pos.add(l6, 0, k10)));
|
||||
}
|
||||
|
||||
for (int l2 = 0; l2 < this.flowersPerChunk; ++l2)
|
||||
{
|
||||
int i7 = rand.chOffset();
|
||||
int l10 = rand.chOffset();
|
||||
int j14 = world.getHeight(pos.add(i7, 0, l10)).getY() + 32;
|
||||
|
||||
if (j14 > 0)
|
||||
{
|
||||
int k17 = rand.zrange(j14);
|
||||
BlockPos blockpos1 = pos.add(i7, k17, l10);
|
||||
BlockFlower.EnumFlowerType blockflower$enumflowertype = this.pickRandomFlower(rand, blockpos1);
|
||||
BlockFlower blockflower = blockflower$enumflowertype.getBlockType().getBlock();
|
||||
|
||||
if (blockflower != Blocks.air)
|
||||
{
|
||||
this.yellowFlowerGen.setGeneratedBlock(blockflower, blockflower$enumflowertype);
|
||||
this.yellowFlowerGen.generate(world, rand, blockpos1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i3 = 0; i3 < this.grassPerChunk; ++i3)
|
||||
{
|
||||
int j7 = rand.chOffset();
|
||||
int i11 = rand.chOffset();
|
||||
int k14 = world.getHeight(pos.add(j7, 0, i11)).getY() * 2;
|
||||
|
||||
if (k14 > 0)
|
||||
{
|
||||
int l17 = rand.zrange(k14);
|
||||
this.getRandomWorldGenForGrass(rand).generate(world, rand, pos.add(j7, l17, i11));
|
||||
}
|
||||
}
|
||||
|
||||
for (int j3 = 0; j3 < this.deadBushPerChunk; ++j3)
|
||||
{
|
||||
int k7 = rand.chOffset();
|
||||
int j11 = rand.chOffset();
|
||||
int l14 = world.getHeight(pos.add(k7, 0, j11)).getY() * 2;
|
||||
|
||||
if (l14 > 0)
|
||||
{
|
||||
int i18 = rand.zrange(l14);
|
||||
(new WorldGenDeadBush()).generate(world, rand, pos.add(k7, i18, j11));
|
||||
}
|
||||
}
|
||||
|
||||
for (int k3 = 0; k3 < this.waterlilyPerChunk; ++k3)
|
||||
{
|
||||
int l7 = rand.chOffset();
|
||||
int k11 = rand.chOffset();
|
||||
int i15 = world.getHeight(pos.add(l7, 0, k11)).getY() * 2;
|
||||
|
||||
if (i15 > 0)
|
||||
{
|
||||
int j18 = rand.zrange(i15);
|
||||
BlockPos blockpos4;
|
||||
BlockPos blockpos7;
|
||||
|
||||
for (blockpos4 = pos.add(l7, j18, k11); blockpos4.getY() > 0; blockpos4 = blockpos7)
|
||||
{
|
||||
blockpos7 = blockpos4.down();
|
||||
|
||||
if (!world.isAirBlock(blockpos7))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.waterlilyGen.generate(world, rand, blockpos4);
|
||||
}
|
||||
}
|
||||
|
||||
for (int l3 = 0; l3 < this.mushroomsPerChunk; ++l3)
|
||||
{
|
||||
if (rand.chance(4))
|
||||
{
|
||||
int i8 = rand.chOffset();
|
||||
int l11 = rand.chOffset();
|
||||
BlockPos blockpos2 = world.getHeight(pos.add(i8, 0, l11));
|
||||
this.mushroomBrownGen.generate(world, rand, blockpos2);
|
||||
}
|
||||
|
||||
if (rand.chance(8))
|
||||
{
|
||||
int j8 = rand.chOffset();
|
||||
int i12 = rand.chOffset();
|
||||
int j15 = world.getHeight(pos.add(j8, 0, i12)).getY() * 2;
|
||||
|
||||
if (j15 > 0)
|
||||
{
|
||||
int k18 = rand.zrange(j15);
|
||||
BlockPos blockpos5 = pos.add(j8, k18, i12);
|
||||
this.mushroomRedGen.generate(world, rand, blockpos5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.mushroomsPerChunk != -1 && rand.chance(4))
|
||||
{
|
||||
int i4 = rand.chOffset();
|
||||
int k8 = rand.chOffset();
|
||||
int j12 = world.getHeight(pos.add(i4, 0, k8)).getY() * 2;
|
||||
|
||||
if (j12 > 0)
|
||||
{
|
||||
int k15 = rand.zrange(j12);
|
||||
this.mushroomBrownGen.generate(world, rand, pos.add(i4, k15, k8));
|
||||
}
|
||||
}
|
||||
|
||||
if (this.mushroomsPerChunk != -1 && rand.chance(8))
|
||||
{
|
||||
int j4 = rand.chOffset();
|
||||
int l8 = rand.chOffset();
|
||||
int k12 = world.getHeight(pos.add(j4, 0, l8)).getY() * 2;
|
||||
|
||||
if (k12 > 0)
|
||||
{
|
||||
int l15 = rand.zrange(k12);
|
||||
this.mushroomRedGen.generate(world, rand, pos.add(j4, l15, l8));
|
||||
}
|
||||
}
|
||||
|
||||
for (int k4 = 0; k4 < this.reedsPerChunk; ++k4)
|
||||
{
|
||||
int i9 = rand.chOffset();
|
||||
int l12 = rand.chOffset();
|
||||
int i16 = world.getHeight(pos.add(i9, 0, l12)).getY() * 2;
|
||||
|
||||
if (i16 > 0)
|
||||
{
|
||||
int l18 = rand.zrange(i16);
|
||||
this.reedGen.generate(world, rand, pos.add(i9, l18, l12));
|
||||
}
|
||||
}
|
||||
|
||||
for (int l4 = 0; l4 < 10; ++l4)
|
||||
{
|
||||
int j9 = rand.chOffset();
|
||||
int i13 = rand.chOffset();
|
||||
int j16 = world.getHeight(pos.add(j9, 0, i13)).getY() * 2;
|
||||
|
||||
if (j16 > 0)
|
||||
{
|
||||
int i19 = rand.zrange(j16);
|
||||
this.reedGen.generate(world, rand, pos.add(j9, i19, i13));
|
||||
}
|
||||
}
|
||||
|
||||
if (rand.chance(32))
|
||||
{
|
||||
int i5 = rand.chOffset();
|
||||
int k9 = rand.chOffset();
|
||||
int j13 = world.getHeight(pos.add(i5, 0, k9)).getY() * 2;
|
||||
|
||||
if (j13 > 0)
|
||||
{
|
||||
int k16 = rand.zrange(j13);
|
||||
(new WorldGenPumpkin()).generate(world, rand, pos.add(i5, k16, k9));
|
||||
}
|
||||
}
|
||||
|
||||
for (int j5 = 0; j5 < this.cactiPerChunk; ++j5)
|
||||
{
|
||||
int l9 = rand.chOffset();
|
||||
int k13 = rand.chOffset();
|
||||
int l16 = world.getHeight(pos.add(l9, 0, k13)).getY() * 2;
|
||||
|
||||
if (l16 > 0)
|
||||
{
|
||||
int j19 = rand.zrange(l16);
|
||||
this.cactusGen.generate(world, rand, pos.add(l9, j19, k13));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
|
||||
{
|
||||
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given x, z coordinates, we count down all the y positions starting at height - 1 and working our way down. When we hit a
|
||||
* non-air block, we replace it with this.topBlock (default grass, descendants may set otherwise), and then a
|
||||
* relatively shallow layer of blocks of type this.fillerBlock (default dirt). A random set of blocks below y == 5
|
||||
* (but always including y == 0) is replaced with bedrock in Chunk(...).
|
||||
*
|
||||
* If we don't hit non-air until somewhat below sea level, we top with gravel and fill down with stone.
|
||||
*
|
||||
* If this.fillerBlock is red sand, we replace some of that with red sandstone.
|
||||
*/
|
||||
public final void generateBiomeTerrain(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
|
||||
{
|
||||
int i = worldIn.getSeaLevel();
|
||||
State worldState = worldIn.dimension.getFiller();
|
||||
Block worldBlock = worldState.getBlock();
|
||||
State worldAlt = worldIn.dimension.getAltFiller1();
|
||||
State liquid = worldIn.getSurfaceLiquid();
|
||||
boolean freeze = liquid.getBlock().getMaterial() == Material.WATER;
|
||||
State iblockstate = this.topBlock;
|
||||
State iblockstate1 = this.fillerBlock;
|
||||
int j = -1;
|
||||
int k = (int)(noiseVal / 3.0D + 3.0D + rand.doublev() * 0.25D);
|
||||
int l = x & 15;
|
||||
int i1 = z & 15;
|
||||
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
|
||||
|
||||
for (int j1 = chunkPrimerIn.height - 1; j1 >= 0; --j1)
|
||||
{
|
||||
State iblockstate2 = chunkPrimerIn.get(i1, j1, l);
|
||||
|
||||
if (iblockstate2.getBlock() == Blocks.air)
|
||||
{
|
||||
j = -1;
|
||||
}
|
||||
else if (iblockstate2.getBlock() == worldBlock)
|
||||
{
|
||||
if (j == -1)
|
||||
{
|
||||
if (k <= 0)
|
||||
{
|
||||
iblockstate = null;
|
||||
iblockstate1 = worldState;
|
||||
}
|
||||
else if (j1 >= i - 4 && j1 <= i + 1)
|
||||
{
|
||||
iblockstate = this.topBlock;
|
||||
iblockstate1 = this.fillerBlock;
|
||||
}
|
||||
|
||||
if (j1 < i && (iblockstate == null || iblockstate.getBlock() == Blocks.air))
|
||||
{
|
||||
if (freeze && World.ABSOLUTE_ZERO + worldIn.getTempOffset() + this.base.getTemperature(blockpos$mutableblockpos.set(x, j1, z)) <= 0.0F)
|
||||
{
|
||||
iblockstate = Blocks.ice.getState();
|
||||
}
|
||||
else
|
||||
{
|
||||
iblockstate = liquid;
|
||||
}
|
||||
}
|
||||
|
||||
j = k;
|
||||
|
||||
if (j1 >= i - 1)
|
||||
{
|
||||
chunkPrimerIn.set(i1, j1, l, iblockstate);
|
||||
}
|
||||
else if (j1 < i - 7 - k)
|
||||
{
|
||||
iblockstate = null;
|
||||
iblockstate1 = worldState;
|
||||
chunkPrimerIn.set(i1, j1, l, worldAlt);
|
||||
}
|
||||
else
|
||||
{
|
||||
chunkPrimerIn.set(i1, j1, l, iblockstate1);
|
||||
}
|
||||
}
|
||||
else if (j > 0)
|
||||
{
|
||||
--j;
|
||||
chunkPrimerIn.set(i1, j1, l, iblockstate1);
|
||||
|
||||
if (j == 0 && iblockstate1.getBlock() == Blocks.sand)
|
||||
{
|
||||
j = rand.zrange(4) + Math.max(0, j1 - 63);
|
||||
iblockstate1 = iblockstate1.getValue(BlockSand.VARIANT) == BlockSand.EnumType.RED_SAND ? Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.ORANGE) : Blocks.sandstone.getState(); //TODO: check!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean generateBigMushroom(AWorldServer worldIn, BlockPos pos, State state, Random rand)
|
||||
{
|
||||
worldIn.setBlockToAir(pos);
|
||||
FeatureGenerator worldgenerator = null;
|
||||
|
||||
if (state.getBlock() == Blocks.brown_mushroom)
|
||||
{
|
||||
worldgenerator = new WorldGenBigMushroom(Blocks.brown_mushroom_block);
|
||||
}
|
||||
else if (state.getBlock() == Blocks.red_mushroom)
|
||||
{
|
||||
worldgenerator = new WorldGenBigMushroom(Blocks.red_mushroom_block);
|
||||
}
|
||||
|
||||
if (worldgenerator != null && worldgenerator.generate((WorldServer)worldIn, rand, pos))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
worldIn.setState(pos, state, 3);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isTypeAt(World worldIn, BlockPos pos, WoodType type)
|
||||
{
|
||||
State iblockstate = worldIn.getState(pos);
|
||||
return iblockstate.getBlock() instanceof BlockSapling && ((BlockSapling)iblockstate.getBlock()).getWoodType() == type;
|
||||
}
|
||||
|
||||
private boolean isSameSaplingTypeIn(World worldIn, BlockPos pos, int xOff, int yOff, WoodType type)
|
||||
{
|
||||
return this.isTypeAt(worldIn, pos.add(xOff, 0, yOff), type) && this.isTypeAt(worldIn, pos.add(xOff + 1, 0, yOff), type) && this.isTypeAt(worldIn, pos.add(xOff, 0, yOff + 1), type) && this.isTypeAt(worldIn, pos.add(xOff + 1, 0, yOff + 1), type);
|
||||
}
|
||||
|
||||
public void generateTree(AWorldServer worldIn, BlockPos pos, State state, Random rand)
|
||||
{
|
||||
WoodType type = state.getBlock() instanceof BlockSapling ? ((BlockSapling)state.getBlock()).getWoodType() : WoodType.OAK;
|
||||
State log = type == WoodType.CHERRY ? Blocks.cherry_log.getState() : // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.CHERRY) :
|
||||
(type == WoodType.MAPLE ? Blocks.maple_log.getState() /* .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.MAPLE) */ : Blocks.oak_log.getState());
|
||||
State leaves = type == WoodType.CHERRY ? Blocks.cherry_leaves.getState() :
|
||||
(type == WoodType.MAPLE ? Blocks.maple_leaves.getState() : Blocks.oak_leaves.getState());
|
||||
FeatureGenerator worldgenerator = (FeatureGenerator)(rand.chance(10) ? new WorldGenBigTree(true, log, leaves) : new WorldGenBaseTree(true, log, leaves));
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
boolean flag = false;
|
||||
// leaves = leaves.withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen());
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case SPRUCE:
|
||||
label114:
|
||||
for (i = 0; i >= -1; --i)
|
||||
{
|
||||
for (j = 0; j >= -1; --j)
|
||||
{
|
||||
if (this.isSameSaplingTypeIn(worldIn, pos, i, j, WoodType.SPRUCE))
|
||||
{
|
||||
worldgenerator = new WorldGenPine(false, rand.chance());
|
||||
flag = true;
|
||||
break label114;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!flag)
|
||||
{
|
||||
j = 0;
|
||||
i = 0;
|
||||
worldgenerator = new WorldGenTaiga2(true);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case BIRCH:
|
||||
worldgenerator = new WorldGenBirch(true, false);
|
||||
break;
|
||||
|
||||
case TIAN:
|
||||
worldgenerator = new WorldGenBigTree(true, Blocks.tian_log.getState(), Blocks.tian_leaves.getState())
|
||||
.setHeightLimit(6, 20);
|
||||
break;
|
||||
|
||||
case JUNGLE:
|
||||
State iblockstate = Blocks.jungle_log.getState(); // .withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE);
|
||||
State iblockstate1 = Blocks.jungle_leaves.getState(); // .withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.JUNGLE); // .withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false));
|
||||
label269:
|
||||
|
||||
for (i = 0; i >= -1; --i)
|
||||
{
|
||||
for (j = 0; j >= -1; --j)
|
||||
{
|
||||
if (this.isSameSaplingTypeIn(worldIn, pos, i, j, WoodType.JUNGLE))
|
||||
{
|
||||
worldgenerator = new WorldGenJungle(true, 10, 20, iblockstate, iblockstate1);
|
||||
flag = true;
|
||||
break label269;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!flag)
|
||||
{
|
||||
j = 0;
|
||||
i = 0;
|
||||
worldgenerator = new WorldGenBaseTree(true, rand.range(4, 10), iblockstate, iblockstate1, false);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ACACIA:
|
||||
worldgenerator = new WorldGenSavanna(true);
|
||||
break;
|
||||
|
||||
case DARK_OAK:
|
||||
label390:
|
||||
for (i = 0; i >= -1; --i)
|
||||
{
|
||||
for (j = 0; j >= -1; --j)
|
||||
{
|
||||
if (this.isSameSaplingTypeIn(worldIn, pos, i, j, WoodType.DARK_OAK))
|
||||
{
|
||||
worldgenerator = new WorldGenDarkOak(true);
|
||||
flag = true;
|
||||
break label390;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!flag)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
case OAK:
|
||||
case CHERRY:
|
||||
case MAPLE:
|
||||
}
|
||||
|
||||
State iblockstate2 = Blocks.air.getState();
|
||||
|
||||
if (flag)
|
||||
{
|
||||
worldIn.setState(pos.add(i, 0, j), iblockstate2, 4);
|
||||
worldIn.setState(pos.add(i + 1, 0, j), iblockstate2, 4);
|
||||
worldIn.setState(pos.add(i, 0, j + 1), iblockstate2, 4);
|
||||
worldIn.setState(pos.add(i + 1, 0, j + 1), iblockstate2, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
worldIn.setState(pos, iblockstate2, 4);
|
||||
}
|
||||
|
||||
if (!worldgenerator.generate((WorldServer)worldIn, rand, pos.add(i, 0, j)))
|
||||
{
|
||||
if (flag)
|
||||
{
|
||||
worldIn.setState(pos.add(i, 0, j), state, 4);
|
||||
worldIn.setState(pos.add(i + 1, 0, j), state, 4);
|
||||
worldIn.setState(pos.add(i, 0, j + 1), state, 4);
|
||||
worldIn.setState(pos.add(i + 1, 0, j + 1), state, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
worldIn.setState(pos, state, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void growGrass(AWorldServer worldIn, BlockPos pos, State state, Random rand)
|
||||
{
|
||||
BlockPos blockpos = pos.up();
|
||||
|
||||
for (int i = 0; i < 128; ++i)
|
||||
{
|
||||
BlockPos blockpos1 = blockpos;
|
||||
int j = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (j >= i / 16)
|
||||
{
|
||||
if (worldIn.getState(blockpos1).getBlock() == Blocks.air)
|
||||
{
|
||||
if (rand.chance(8))
|
||||
{
|
||||
BlockFlower.EnumFlowerType blockflower$enumflowertype = BIOMES[worldIn.getBiomeGenForCoords(blockpos1).id].pickRandomFlower(rand, blockpos1);
|
||||
BlockFlower blockflower = blockflower$enumflowertype.getBlockType().getBlock();
|
||||
State iblockstate = blockflower.getState().withProperty(blockflower.getTypeProperty(), blockflower$enumflowertype);
|
||||
|
||||
if (blockflower.canBlockStay(worldIn, blockpos1, iblockstate))
|
||||
{
|
||||
worldIn.setState(blockpos1, iblockstate, 3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
State iblockstate1 = Blocks.tallgrass.getState().withProperty(BlockTallGrass.TYPE, BlockTallGrass.EnumType.GRASS);
|
||||
|
||||
if (Blocks.tallgrass.canBlockStay(worldIn, blockpos1, iblockstate1))
|
||||
{
|
||||
worldIn.setState(blockpos1, iblockstate1, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
blockpos1 = blockpos1.add(rand.zrange(3) - 1, (rand.zrange(3) - 1) * rand.zrange(3) / 2, rand.zrange(3) - 1);
|
||||
|
||||
if (worldIn.getState(blockpos1.down()).getBlock() != Blocks.grass || worldIn.getState(blockpos1).getBlock().isNormalCube())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
++j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected GenBiome createMutatedBiome(Biome base)
|
||||
{
|
||||
return new BiomeMutated(base, this);
|
||||
}
|
||||
|
||||
public Class <? extends GenBiome > getBiomeClass()
|
||||
{
|
||||
return this.getClass();
|
||||
}
|
||||
|
||||
public boolean isEqualTo(GenBiome biome)
|
||||
{
|
||||
return biome == this ? true : (biome == null ? false : this.getBiomeClass() == biome.getBiomeClass());
|
||||
}
|
||||
|
||||
public Temperature getTempCategory()
|
||||
{
|
||||
return this.base.temperature < -12.0f ? Temperature.COLD : (this.base.temperature < 20.0f ? Temperature.MEDIUM : Temperature.WARM);
|
||||
}
|
||||
}
|
17
server/src/main/java/server/biome/RngSpawn.java
Normal file
17
server/src/main/java/server/biome/RngSpawn.java
Normal file
|
@ -0,0 +1,17 @@
|
|||
package server.biome;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.rng.RngItem;
|
||||
|
||||
public class RngSpawn extends RngItem {
|
||||
public final Class<? extends EntityLiving> type;
|
||||
public final int min;
|
||||
public final int max;
|
||||
|
||||
public RngSpawn(Class<? extends EntityLiving> type, int weight, int min, int max) {
|
||||
super(weight);
|
||||
this.type = type;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
}
|
28
server/src/main/java/server/biome/Scaling.java
Normal file
28
server/src/main/java/server/biome/Scaling.java
Normal file
|
@ -0,0 +1,28 @@
|
|||
package server.biome;
|
||||
|
||||
public enum Scaling {
|
||||
VARYING_LOW(0.1F, 0.2F),
|
||||
VARYING_MEDIUM(0.1F, 1.0F),
|
||||
VARYING_CHAOTIC(1.0F, 2.0F),
|
||||
SEA_VARYING(0.1F, 0.8F),
|
||||
SEA_SHORE(0.0F, 0.025F),
|
||||
SEA_POND(-0.2F, 0.1F),
|
||||
SEA_SHALLOW(-0.5F, 0.0F),
|
||||
SEA_MEDIUM(-1.0F, 0.1F),
|
||||
SEA_DEEP(-1.8F, 0.1F),
|
||||
PLAINS_LOW(0.125F, 0.05F),
|
||||
PLAINS_MEDIUM(0.2F, 0.2F),
|
||||
PLAINS_VARYING(0.2F, 0.3F),
|
||||
HILLS_LOW(0.45F, 0.3F),
|
||||
HILLS_MEDIUM(0.8F, 0.3F),
|
||||
HILLS_LARGE(1.0F, 0.5F),
|
||||
HILLS_PLATEAU(1.5F, 0.025F);
|
||||
|
||||
public final float depth;
|
||||
public final float scale;
|
||||
|
||||
private Scaling(float depth, float scale) {
|
||||
this.depth = depth;
|
||||
this.scale = scale;
|
||||
}
|
||||
}
|
5
server/src/main/java/server/biome/Temperature.java
Normal file
5
server/src/main/java/server/biome/Temperature.java
Normal file
|
@ -0,0 +1,5 @@
|
|||
package server.biome;
|
||||
|
||||
public enum Temperature {
|
||||
SEA, COLD, MEDIUM, WARM;
|
||||
}
|
111
server/src/main/java/server/clipboard/BlockTransform.java
Executable file
111
server/src/main/java/server/clipboard/BlockTransform.java
Executable file
|
@ -0,0 +1,111 @@
|
|||
package server.clipboard;
|
||||
|
||||
public class BlockTransform {
|
||||
private double m00, m01, m02, m03;
|
||||
private double m10, m11, m12, m13;
|
||||
private double m20, m21, m22, m23;
|
||||
|
||||
public BlockTransform() {
|
||||
m00 = m11 = m22 = 1;
|
||||
m01 = m02 = m03 = 0;
|
||||
m10 = m12 = m13 = 0;
|
||||
m20 = m21 = m23 = 0;
|
||||
}
|
||||
|
||||
private BlockTransform(double xx, double yx, double zx, double tx,
|
||||
double xy, double yy, double zy, double ty, double xz, double yz,
|
||||
double zz, double tz) {
|
||||
m00 = xx;
|
||||
m01 = yx;
|
||||
m02 = zx;
|
||||
m03 = tx;
|
||||
m10 = xy;
|
||||
m11 = yy;
|
||||
m12 = zy;
|
||||
m13 = ty;
|
||||
m20 = xz;
|
||||
m21 = yz;
|
||||
m22 = zz;
|
||||
m23 = tz;
|
||||
}
|
||||
|
||||
private BlockTransform concatenate(BlockTransform that) {
|
||||
double n00 = m00 * that.m00 + m01 * that.m10 + m02 * that.m20;
|
||||
double n01 = m00 * that.m01 + m01 * that.m11 + m02 * that.m21;
|
||||
double n02 = m00 * that.m02 + m01 * that.m12 + m02 * that.m22;
|
||||
double n03 = m00 * that.m03 + m01 * that.m13 + m02 * that.m23 + m03;
|
||||
double n10 = m10 * that.m00 + m11 * that.m10 + m12 * that.m20;
|
||||
double n11 = m10 * that.m01 + m11 * that.m11 + m12 * that.m21;
|
||||
double n12 = m10 * that.m02 + m11 * that.m12 + m12 * that.m22;
|
||||
double n13 = m10 * that.m03 + m11 * that.m13 + m12 * that.m23 + m13;
|
||||
double n20 = m20 * that.m00 + m21 * that.m10 + m22 * that.m20;
|
||||
double n21 = m20 * that.m01 + m21 * that.m11 + m22 * that.m21;
|
||||
double n22 = m20 * that.m02 + m21 * that.m12 + m22 * that.m22;
|
||||
double n23 = m20 * that.m03 + m21 * that.m13 + m22 * that.m23 + m23;
|
||||
return new BlockTransform(
|
||||
n00, n01, n02, n03,
|
||||
n10, n11, n12, n13,
|
||||
n20, n21, n22, n23);
|
||||
}
|
||||
|
||||
public BlockTransform rotateY(int theta) {
|
||||
double cot = dCos(theta);
|
||||
double sit = dSin(theta);
|
||||
return concatenate(
|
||||
new BlockTransform(
|
||||
cot, 0, sit, 0,
|
||||
0, 1, 0, 0,
|
||||
-sit, 0, cot, 0));
|
||||
}
|
||||
|
||||
public BlockTransform scale(Vector vec) {
|
||||
return concatenate(new BlockTransform(vec.getX(), 0, 0, 0, 0, vec.getY(), 0, 0, 0, 0, vec.getZ(), 0));
|
||||
}
|
||||
|
||||
public Vector apply(Vector vector) {
|
||||
return new Vector(
|
||||
vector.getX() * m00 + vector.getY() * m01 + vector.getZ() * m02 + m03,
|
||||
vector.getX() * m10 + vector.getY() * m11 + vector.getZ() * m12 + m13,
|
||||
vector.getX() * m20 + vector.getY() * m21 + vector.getZ() * m22 + m23);
|
||||
}
|
||||
|
||||
private static double dSin(int degrees) {
|
||||
if (degrees % 90 == 0) {
|
||||
degrees %= 360;
|
||||
if (degrees < 0) {
|
||||
degrees += 360;
|
||||
}
|
||||
switch (degrees) {
|
||||
case 0:
|
||||
return 0.0;
|
||||
case 90:
|
||||
return 1.0;
|
||||
case 180:
|
||||
return 0.0;
|
||||
case 270:
|
||||
return -1.0;
|
||||
}
|
||||
}
|
||||
return Math.cos(Math.toRadians(degrees));
|
||||
}
|
||||
|
||||
private static double dCos(int degrees) {
|
||||
if (degrees % 90 == 0) {
|
||||
degrees %= 360;
|
||||
if (degrees < 0) {
|
||||
degrees += 360;
|
||||
}
|
||||
switch (degrees) {
|
||||
case 0:
|
||||
return 1.0;
|
||||
case 90:
|
||||
return 0.0;
|
||||
case 180:
|
||||
return -1.0;
|
||||
case 270:
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
return Math.cos(Math.toRadians(degrees));
|
||||
}
|
||||
}
|
33
server/src/main/java/server/clipboard/ClipboardBlock.java
Executable file
33
server/src/main/java/server/clipboard/ClipboardBlock.java
Executable file
|
@ -0,0 +1,33 @@
|
|||
package server.clipboard;
|
||||
|
||||
import common.nbt.NBTTagCompound;
|
||||
import common.tileentity.TileEntity;
|
||||
import common.world.State;
|
||||
|
||||
public class ClipboardBlock {
|
||||
private State state;
|
||||
private NBTTagCompound nbt;
|
||||
|
||||
public ClipboardBlock(State state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public ClipboardBlock(State data, TileEntity tile) {
|
||||
this(data);
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tile.writeToNBT(tag);
|
||||
this.nbt = tag;
|
||||
}
|
||||
|
||||
public State getState() {
|
||||
return this.state;
|
||||
}
|
||||
|
||||
public void setState(State state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public NBTTagCompound getNbtData() {
|
||||
return this.nbt;
|
||||
}
|
||||
}
|
163
server/src/main/java/server/clipboard/ClipboardPlacer.java
Executable file
163
server/src/main/java/server/clipboard/ClipboardPlacer.java
Executable file
|
@ -0,0 +1,163 @@
|
|||
package server.clipboard;
|
||||
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.ITileEntityProvider;
|
||||
import common.block.artificial.BlockDoor;
|
||||
import common.block.tech.BlockRailBase;
|
||||
import common.collect.Lists;
|
||||
import common.init.Blocks;
|
||||
import common.inventory.IInventory;
|
||||
import common.tileentity.TileEntity;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Vec3i;
|
||||
import server.world.WorldServer;
|
||||
|
||||
public class ClipboardPlacer {
|
||||
private static class BlockEntry {
|
||||
private final BlockPos pos;
|
||||
private final ClipboardBlock block;
|
||||
|
||||
private BlockEntry(BlockPos pos, ClipboardBlock block) {
|
||||
this.pos = pos;
|
||||
this.block = block;
|
||||
}
|
||||
}
|
||||
|
||||
private final WorldServer world;
|
||||
private final List<BlockEntry> stage1 = Lists.newArrayList();
|
||||
private final List<BlockEntry> stage2 = Lists.newArrayList();
|
||||
private final List<BlockEntry> stage3 = Lists.newArrayList();
|
||||
|
||||
public ClipboardPlacer(WorldServer world) {
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public void setBlock(BlockPos location, ClipboardBlock block) {
|
||||
Block type = block.getState().getBlock();
|
||||
if (ReorderRegistry.shouldPlaceLast(type)) {
|
||||
// Place torches, etc. last
|
||||
this.stage2.add(new BlockEntry(location, block));
|
||||
} else if (ReorderRegistry.shouldPlaceFinal(type)) {
|
||||
// Place signs, reed, etc even later
|
||||
this.stage3.add(new BlockEntry(location, block));
|
||||
} else if (ReorderRegistry.shouldPlaceLast(this.world.getState(location).getBlock())) {
|
||||
// Destroy torches, etc. first
|
||||
this.setBlockQuirk(location, new ClipboardBlock(Blocks.air.getState()));
|
||||
this.setBlockQuirk(location, block);
|
||||
} else {
|
||||
this.stage1.add(new BlockEntry(location, block));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean setBlockQuirk(BlockPos location, ClipboardBlock block) {
|
||||
Block existing = this.world.getState(location).getBlock();
|
||||
if (existing instanceof ITileEntityProvider) {
|
||||
TileEntity tile = this.world.getTileEntity(location);
|
||||
if ((tile instanceof IInventory)) {
|
||||
IInventory inv = (IInventory) tile;
|
||||
int size = inv.getSizeInventory();
|
||||
for (int i = 0; i < size; i++) {
|
||||
inv.setInventorySlotContents(i, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (existing == Blocks.ice) {
|
||||
this.world.setBlock(location, new ClipboardBlock(Blocks.air.getState())); // Ice turns until water so this has to be done first
|
||||
}
|
||||
return this.world.setBlock(location, block);
|
||||
}
|
||||
|
||||
public void commit() {
|
||||
// Iterator<Entry<BlockEntry>> iterator = Iterators.concat(this.stage1.iterator(), this.stage2.iterator());
|
||||
// while (iterator.hasNext()) {
|
||||
// Map.Entry<BlockPos, EditBlock> entry = iterator.next();
|
||||
//
|
||||
// }
|
||||
for(BlockEntry entry : this.stage1) {
|
||||
this.setBlockQuirk(entry.pos, entry.block);
|
||||
}
|
||||
this.stage1.clear();
|
||||
for(BlockEntry entry : this.stage2) {
|
||||
this.setBlockQuirk(entry.pos, entry.block);
|
||||
}
|
||||
this.stage2.clear();
|
||||
|
||||
final Set<BlockPos> blocks = new HashSet<BlockPos>();
|
||||
final Map<BlockPos, ClipboardBlock> blockTypes = new HashMap<BlockPos, ClipboardBlock>();
|
||||
for(BlockEntry entry : this.stage3) {
|
||||
// final BlockPos pt = entry.getKey();
|
||||
blocks.add(entry.pos);
|
||||
blockTypes.put(entry.pos, entry.block);
|
||||
}
|
||||
this.stage3.clear();
|
||||
|
||||
while (!blocks.isEmpty()) {
|
||||
BlockPos current = blocks.iterator().next();
|
||||
if (!blocks.contains(current)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final Deque<BlockPos> walked = new LinkedList<BlockPos>();
|
||||
|
||||
while (true) {
|
||||
walked.addFirst(current);
|
||||
|
||||
assert (blockTypes.containsKey(current));
|
||||
|
||||
final ClipboardBlock baseBlock = blockTypes.get(current);
|
||||
|
||||
final Block type = baseBlock.getState().getBlock();
|
||||
|
||||
if(type instanceof BlockDoor) {
|
||||
if (baseBlock.getState().getValue(BlockDoor.HALF) == BlockDoor.EnumDoorHalf.LOWER) {
|
||||
// Deal with lower door halves being attached to the floor AND the upper half
|
||||
BlockPos upperBlock = current.add(0, 1, 0);
|
||||
if (blocks.contains(upperBlock) && !walked.contains(upperBlock)) {
|
||||
walked.addFirst(upperBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(type instanceof BlockRailBase) {
|
||||
// Here, rails are hardcoded to be attached to the block below them.
|
||||
// They're also attached to the block they're ascending towards via BlockType.getAttachment.
|
||||
BlockPos lowerBlock = current.add(0, -1, 0);
|
||||
if (blocks.contains(lowerBlock) && !walked.contains(lowerBlock)) {
|
||||
walked.addFirst(lowerBlock);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
final Vec3i attachment = ReorderRegistry.getAttachment(baseBlock.getState());
|
||||
if (attachment == null) {
|
||||
// Block is not attached to anything => we can place it
|
||||
break;
|
||||
}
|
||||
|
||||
current = current.add(attachment);
|
||||
|
||||
if (!blocks.contains(current)) {
|
||||
// We ran outside the remaining set => assume we can place blocks on this
|
||||
break;
|
||||
}
|
||||
|
||||
if (walked.contains(current)) {
|
||||
// Cycle detected => This will most likely go wrong, but there's nothing we can do about it.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(BlockPos pt : walked) {
|
||||
this.setBlockQuirk(pt, blockTypes.get(pt));
|
||||
blocks.remove(pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
230
server/src/main/java/server/clipboard/ReorderRegistry.java
Executable file
230
server/src/main/java/server/clipboard/ReorderRegistry.java
Executable file
|
@ -0,0 +1,230 @@
|
|||
package server.clipboard;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.artificial.BlockBed;
|
||||
import common.block.artificial.BlockDoor;
|
||||
import common.color.DyeColor;
|
||||
import common.init.BlockRegistry;
|
||||
import common.init.Blocks;
|
||||
import common.init.WoodType;
|
||||
import common.util.Facing;
|
||||
import common.util.Vec3i;
|
||||
import common.world.State;
|
||||
|
||||
public abstract class ReorderRegistry {
|
||||
private static final Set<Block> PLACE_LAST = new HashSet<Block>();
|
||||
private static final Set<Block> PLACE_FINAL = new HashSet<Block>();
|
||||
private static final Map<State, Vec3i> STATE_ATTACH = new HashMap<State, Vec3i>();
|
||||
private static final Map<Block, Vec3i> BLOCK_ATTACH = new HashMap<Block, Vec3i>();
|
||||
|
||||
public static boolean shouldPlaceLast(Block id) {
|
||||
return PLACE_LAST.contains(id);
|
||||
}
|
||||
|
||||
public static boolean shouldPlaceFinal(Block id) {
|
||||
return PLACE_FINAL.contains(id) || id instanceof BlockDoor;
|
||||
}
|
||||
|
||||
public static Vec3i getAttachment(State state) {
|
||||
Vec3i direction = BLOCK_ATTACH.get(state.getBlock());
|
||||
if (direction != null) return direction;
|
||||
return STATE_ATTACH.get(state);
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
for(WoodType wood : WoodType.values()) {
|
||||
PLACE_LAST.add(BlockRegistry.getRegisteredBlock(wood.getName() + "_sapling"));
|
||||
}
|
||||
// PLACE_LAST.add(Blocks.bed);
|
||||
for(DyeColor color : BlockBed.COLORS) {
|
||||
PLACE_LAST.add(BlockRegistry.getRegisteredBlock(color.getName() + "_bed"));
|
||||
}
|
||||
PLACE_LAST.add(Blocks.golden_rail);
|
||||
PLACE_LAST.add(Blocks.detector_rail);
|
||||
PLACE_LAST.add(Blocks.tallgrass);
|
||||
PLACE_LAST.add(Blocks.deadbush);
|
||||
PLACE_LAST.add(Blocks.piston_head);
|
||||
PLACE_LAST.add(Blocks.flower);
|
||||
PLACE_LAST.add(Blocks.brown_mushroom);
|
||||
PLACE_LAST.add(Blocks.red_mushroom_block);
|
||||
PLACE_LAST.add(Blocks.torch);
|
||||
PLACE_LAST.add(Blocks.fire);
|
||||
PLACE_LAST.add(Blocks.soul_fire);
|
||||
PLACE_LAST.add(Blocks.black_fire);
|
||||
PLACE_LAST.add(Blocks.redstone);
|
||||
PLACE_LAST.add(Blocks.wheat);
|
||||
PLACE_LAST.add(Blocks.ladder);
|
||||
PLACE_LAST.add(Blocks.rail);
|
||||
PLACE_LAST.add(Blocks.lever);
|
||||
PLACE_LAST.add(Blocks.stone_pressure_plate);
|
||||
PLACE_LAST.add(Blocks.wooden_pressure_plate);
|
||||
PLACE_LAST.add(Blocks.unlit_redstone_torch);
|
||||
PLACE_LAST.add(Blocks.redstone_torch);
|
||||
PLACE_LAST.add(Blocks.stone_button);
|
||||
PLACE_LAST.add(Blocks.snow_layer);
|
||||
PLACE_LAST.add(Blocks.portal);
|
||||
PLACE_LAST.add(Blocks.repeater);
|
||||
PLACE_LAST.add(Blocks.powered_repeater);
|
||||
PLACE_LAST.add(Blocks.trapdoor);
|
||||
PLACE_LAST.add(Blocks.vine);
|
||||
PLACE_LAST.add(Blocks.waterlily);
|
||||
PLACE_LAST.add(Blocks.soul_wart);
|
||||
PLACE_LAST.add(Blocks.piston);
|
||||
PLACE_LAST.add(Blocks.sticky_piston);
|
||||
PLACE_LAST.add(Blocks.piston_head);
|
||||
PLACE_LAST.add(Blocks.piston_extension);
|
||||
PLACE_LAST.add(Blocks.cocoa);
|
||||
PLACE_LAST.add(Blocks.tripwire_hook);
|
||||
PLACE_LAST.add(Blocks.string);
|
||||
PLACE_LAST.add(Blocks.flower_pot);
|
||||
PLACE_LAST.add(Blocks.carrot);
|
||||
PLACE_LAST.add(Blocks.potato);
|
||||
PLACE_LAST.add(Blocks.wooden_button);
|
||||
PLACE_LAST.add(Blocks.anvil); // becomes relevant with asynchronous placement
|
||||
PLACE_LAST.add(Blocks.light_weighted_pressure_plate);
|
||||
PLACE_LAST.add(Blocks.heavy_weighted_pressure_plate);
|
||||
PLACE_LAST.add(Blocks.comparator);
|
||||
PLACE_LAST.add(Blocks.powered_comparator);
|
||||
PLACE_LAST.add(Blocks.activator_rail);
|
||||
PLACE_LAST.add(Blocks.iron_trapdoor);
|
||||
PLACE_LAST.add(Blocks.carpet);
|
||||
PLACE_LAST.add(Blocks.double_plant);
|
||||
PLACE_LAST.add(Blocks.daylight_detector_inverted);
|
||||
// shouldPlaceLast.add(Blocks.daylight_detector);
|
||||
PLACE_LAST.add(Blocks.blue_mushroom);
|
||||
PLACE_LAST.add(Blocks.red_button);
|
||||
}
|
||||
|
||||
static {
|
||||
PLACE_FINAL.add(Blocks.sign);
|
||||
PLACE_FINAL.add(Blocks.wall_sign);
|
||||
PLACE_FINAL.add(Blocks.cactus);
|
||||
PLACE_FINAL.add(Blocks.reeds);
|
||||
PLACE_FINAL.add(Blocks.cake);
|
||||
PLACE_FINAL.add(Blocks.piston_head);
|
||||
PLACE_FINAL.add(Blocks.piston_extension);
|
||||
PLACE_FINAL.add(Blocks.banner);
|
||||
PLACE_FINAL.add(Blocks.wall_banner);
|
||||
}
|
||||
|
||||
private static void addAttach(State state, Facing dir) {
|
||||
STATE_ATTACH.put(state, dir.getDirectionVec());
|
||||
}
|
||||
|
||||
private static void addAttach(Block block, Facing dir) {
|
||||
BLOCK_ATTACH.put(block, dir.getDirectionVec());
|
||||
}
|
||||
|
||||
private static void addCardinals(Block type, int west, int north, int east, int south) {
|
||||
addAttach(type.getStateFromMeta(west), Facing.WEST);
|
||||
addAttach(type.getStateFromMeta(north), Facing.NORTH);
|
||||
addAttach(type.getStateFromMeta(east), Facing.EAST);
|
||||
addAttach(type.getStateFromMeta(south), Facing.SOUTH);
|
||||
}
|
||||
|
||||
static {
|
||||
for(WoodType wood : WoodType.values()) {
|
||||
addAttach(BlockRegistry.getRegisteredBlock(wood.getName() + "_sapling"), Facing.DOWN);
|
||||
}
|
||||
addAttach(Blocks.tallgrass, Facing.DOWN);
|
||||
addAttach(Blocks.deadbush, Facing.DOWN);
|
||||
for (int offset = 0; offset < 16; offset += 8) {
|
||||
addAttach(Blocks.piston_head.getStateFromMeta(offset + 0), Facing.UP);
|
||||
addAttach(Blocks.piston_head.getStateFromMeta(offset + 1), Facing.DOWN);
|
||||
addCardinals(Blocks.piston_head, offset + 2, offset + 5, offset + 3, offset + 4);
|
||||
}
|
||||
addAttach(Blocks.flower, Facing.DOWN);
|
||||
addAttach(Blocks.brown_mushroom, Facing.DOWN);
|
||||
addAttach(Blocks.red_mushroom, Facing.DOWN);
|
||||
for (Block blockId : new Block[] { Blocks.torch, Blocks.redstone_torch, Blocks.unlit_redstone_torch }) {
|
||||
addAttach(blockId.getStateFromMeta(0), Facing.DOWN);
|
||||
addAttach(blockId.getStateFromMeta(5), Facing.DOWN); // According to the wiki, this one is history. Keeping both, for now...
|
||||
addCardinals(blockId, 4, 1, 3, 2);
|
||||
}
|
||||
addAttach(Blocks.redstone, Facing.DOWN);
|
||||
addAttach(Blocks.wheat, Facing.DOWN);
|
||||
addAttach(Blocks.sign, Facing.DOWN);
|
||||
addCardinals(Blocks.ladder, 2, 5, 3, 4);
|
||||
addCardinals(Blocks.wall_sign, 2, 5, 3, 4);
|
||||
for (int offset = 0; offset < 16; offset += 8) {
|
||||
addCardinals(Blocks.lever, offset + 4, offset + 1, offset + 3, offset + 2);
|
||||
addAttach(Blocks.lever.getStateFromMeta(offset + 5), Facing.DOWN);
|
||||
addAttach(Blocks.lever.getStateFromMeta(offset + 6), Facing.DOWN);
|
||||
addAttach(Blocks.lever.getStateFromMeta(offset + 7), Facing.UP);
|
||||
addAttach(Blocks.lever.getStateFromMeta(offset + 0), Facing.UP);
|
||||
}
|
||||
addAttach(Blocks.stone_pressure_plate, Facing.DOWN);
|
||||
addAttach(Blocks.iron_door, Facing.DOWN);
|
||||
addAttach(Blocks.wooden_pressure_plate, Facing.DOWN);
|
||||
// redstone torches: see torches
|
||||
for (int offset = 0; offset < 16; offset += 8) {
|
||||
addCardinals(Blocks.stone_button, offset + 4, offset + 1, offset + 3, offset + 2);
|
||||
addCardinals(Blocks.wooden_button, offset + 4, offset + 1, offset + 3, offset + 2);
|
||||
addCardinals(Blocks.red_button, offset + 4, offset + 1, offset + 3, offset + 2);
|
||||
}
|
||||
addAttach(Blocks.stone_button.getStateFromMeta(0), Facing.UP);
|
||||
addAttach(Blocks.stone_button.getStateFromMeta(5), Facing.DOWN);
|
||||
addAttach(Blocks.wooden_button.getStateFromMeta(0), Facing.UP);
|
||||
addAttach(Blocks.wooden_button.getStateFromMeta(5), Facing.DOWN);
|
||||
addAttach(Blocks.red_button.getStateFromMeta(0), Facing.UP);
|
||||
addAttach(Blocks.red_button.getStateFromMeta(5), Facing.DOWN);
|
||||
addAttach(Blocks.cactus, Facing.DOWN);
|
||||
addAttach(Blocks.reeds, Facing.DOWN);
|
||||
addAttach(Blocks.cake, Facing.DOWN);
|
||||
addAttach(Blocks.repeater, Facing.DOWN);
|
||||
addAttach(Blocks.powered_repeater, Facing.DOWN);
|
||||
for (int offset = 0; offset < 16; offset += 4) {
|
||||
addCardinals(Blocks.trapdoor, offset + 0, offset + 3, offset + 1, offset + 2);
|
||||
addCardinals(Blocks.iron_trapdoor, offset + 0, offset + 3, offset + 1, offset + 2);
|
||||
}
|
||||
addAttach(Blocks.pumpkin_stem, Facing.DOWN);
|
||||
addAttach(Blocks.melon_stem, Facing.DOWN);
|
||||
// vines are complicated, but I'll list the single-attachment variants anyway
|
||||
addAttach(Blocks.vine.getStateFromMeta(0), Facing.UP);
|
||||
addCardinals(Blocks.vine, 1, 2, 4, 8);
|
||||
addAttach(Blocks.soul_wart, Facing.DOWN);
|
||||
for (int offset = 0; offset < 16; offset += 4) {
|
||||
addCardinals(Blocks.cocoa, offset + 0, offset + 1, offset + 2, offset + 3);
|
||||
}
|
||||
for (int offset = 0; offset < 16; offset += 4) {
|
||||
addCardinals(Blocks.tripwire_hook, offset + 2, offset + 3, offset + 0, offset + 1);
|
||||
}
|
||||
addAttach(Blocks.string, Facing.DOWN);
|
||||
addAttach(Blocks.flower_pot, Facing.DOWN);
|
||||
addAttach(Blocks.carrot, Facing.DOWN);
|
||||
addAttach(Blocks.potato, Facing.DOWN);
|
||||
addAttach(Blocks.anvil, Facing.DOWN);
|
||||
addAttach(Blocks.light_weighted_pressure_plate, Facing.DOWN);
|
||||
addAttach(Blocks.heavy_weighted_pressure_plate, Facing.DOWN);
|
||||
addAttach(Blocks.comparator, Facing.DOWN);
|
||||
addAttach(Blocks.powered_comparator, Facing.DOWN);
|
||||
addAttach(Blocks.carpet, Facing.DOWN);
|
||||
addAttach(Blocks.double_plant, Facing.DOWN);
|
||||
addAttach(Blocks.banner, Facing.DOWN);
|
||||
addCardinals(Blocks.wall_banner, 4, 2, 5, 3);
|
||||
addAttach(Blocks.oak_door, Facing.DOWN);
|
||||
addAttach(Blocks.spruce_door, Facing.DOWN);
|
||||
addAttach(Blocks.birch_door, Facing.DOWN);
|
||||
addAttach(Blocks.jungle_door, Facing.DOWN);
|
||||
addAttach(Blocks.acacia_door, Facing.DOWN);
|
||||
addAttach(Blocks.dark_oak_door, Facing.DOWN);
|
||||
addAttach(Blocks.cherry_door, Facing.DOWN);
|
||||
addAttach(Blocks.maple_door, Facing.DOWN);
|
||||
|
||||
// Rails are hardcoded to be attached to the block below them.
|
||||
// In addition to that, let's attach ascending rails to the block they're ascending towards.
|
||||
for (int offset = 0; offset < 16; offset += 8) {
|
||||
addCardinals(Blocks.golden_rail, offset + 3, offset + 4, offset + 2, offset + 5);
|
||||
addCardinals(Blocks.detector_rail, offset + 3, offset + 4, offset + 2, offset + 5);
|
||||
addCardinals(Blocks.rail, offset + 3, offset + 4, offset + 2, offset + 5);
|
||||
addCardinals(Blocks.activator_rail, offset + 3, offset + 4, offset + 2, offset + 5);
|
||||
}
|
||||
|
||||
addAttach(Blocks.blue_mushroom, Facing.DOWN);
|
||||
}
|
||||
}
|
43
server/src/main/java/server/clipboard/Rotation.java
Executable file
43
server/src/main/java/server/clipboard/Rotation.java
Executable file
|
@ -0,0 +1,43 @@
|
|||
package server.clipboard;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class Rotation {
|
||||
private final RotationValue[] values;
|
||||
private final boolean[] dirFlags = new boolean[16];
|
||||
|
||||
public Rotation(RotationValue[] values, Predicate<Integer> predicate) {
|
||||
this.values = values;
|
||||
for(int z = 0; z < 16; z++) {
|
||||
if(predicate != null && !predicate.test(z)) {
|
||||
this.dirFlags[z] = false;
|
||||
continue;
|
||||
}
|
||||
boolean flag = false;
|
||||
for(RotationValue value : values) {
|
||||
if(value.getDirection() != null) {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.dirFlags[z] = flag;
|
||||
}
|
||||
}
|
||||
|
||||
public RotationValue[] getValues() {
|
||||
return this.values;
|
||||
}
|
||||
|
||||
public RotationValue getValue(int meta) {
|
||||
for (RotationValue value : this.values) {
|
||||
if (value.isSet(meta)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean hasDirection(int meta) {
|
||||
return this.dirFlags[meta & 15];
|
||||
}
|
||||
}
|
129
server/src/main/java/server/clipboard/RotationRegistry.java
Executable file
129
server/src/main/java/server/clipboard/RotationRegistry.java
Executable file
|
@ -0,0 +1,129 @@
|
|||
package server.clipboard;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.BlockRotatedPillar;
|
||||
import common.block.artificial.BlockDoor;
|
||||
import common.block.artificial.BlockPortal;
|
||||
import common.block.artificial.BlockQuartz;
|
||||
import common.block.foliage.BlockLog;
|
||||
import common.block.tech.BlockLever;
|
||||
import common.block.tech.BlockRail;
|
||||
import common.block.tech.BlockRailBase;
|
||||
import common.block.tech.BlockRailDetector;
|
||||
import common.block.tech.BlockRailPowered;
|
||||
import common.collect.Lists;
|
||||
import common.collect.Maps;
|
||||
import common.properties.IProperty;
|
||||
import common.properties.PropertyDirection;
|
||||
import common.util.Facing;
|
||||
import common.util.Vec3i;
|
||||
import common.world.State;
|
||||
|
||||
public abstract class RotationRegistry {
|
||||
private static final Map<Block, Rotation> MAP = new HashMap<Block, Rotation>();
|
||||
|
||||
public static void register() {
|
||||
for(Block block : common.init.BlockRegistry.REGISTRY) {
|
||||
for(IProperty<?> prop : block.getPropertyMap()) {
|
||||
Predicate<Integer> predicate = null;
|
||||
if(prop == BlockDoor.FACING) {
|
||||
predicate = new Predicate<Integer>() {
|
||||
@Override
|
||||
public boolean test(Integer meta) {
|
||||
return (meta & 8) == 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
List<RotationValue> values = Lists.newArrayList();
|
||||
Map<Object, Byte> map = Maps.newHashMap();
|
||||
for(int z = 15; z >= 0; z--) {
|
||||
State st = block.getStateFromMeta(z);
|
||||
if(st.getProperties().containsKey(prop)) {
|
||||
map.put(st.getProperties().get(prop), (byte)z);
|
||||
}
|
||||
}
|
||||
|
||||
byte mask = 0;
|
||||
for(Object v : prop.getAllowedValues()) {
|
||||
if(map.get(v) == null) {
|
||||
continue;
|
||||
}
|
||||
mask |= map.get(v);
|
||||
}
|
||||
if(mask == 0) {
|
||||
continue;
|
||||
}
|
||||
for(Object v : prop.getAllowedValues()) {
|
||||
if(map.get(v) == null) {
|
||||
continue;
|
||||
}
|
||||
Vec3i dv = null;
|
||||
Facing.Axis axis = null;
|
||||
if(prop instanceof PropertyDirection) {
|
||||
dv = ((Facing)v).getDirectionVec();
|
||||
}
|
||||
else if(prop == BlockRotatedPillar.AXIS) {
|
||||
axis = ((Facing.Axis)v);
|
||||
}
|
||||
else if(prop == BlockPortal.AXIS) {
|
||||
axis = ((Facing.Axis)v);
|
||||
}
|
||||
else if(prop == BlockLog.LOG_AXIS) {
|
||||
axis = ((BlockLog.EnumAxis)v).getAxis();
|
||||
}
|
||||
else if(prop == BlockQuartz.VARIANT) {
|
||||
axis = ((BlockQuartz.EnumType)v).getAxis();
|
||||
}
|
||||
else if(prop == BlockLever.FACING) {
|
||||
dv = ((BlockLever.EnumOrientation)v).getFacing().getDirectionVec();
|
||||
}
|
||||
else if(prop == BlockRail.SHAPE || prop == BlockRailDetector.SHAPE || prop == BlockRailPowered.SHAPE) {
|
||||
dv = ((BlockRailBase.EnumRailDirection)v).getFacing().getDirectionVec();
|
||||
}
|
||||
// else if(prop == BlockDoor.HINGE) {
|
||||
// dv = ((BlockDoor.EnumHingePosition)v) == BlockDoor.EnumHingePosition.LEFT ? new Vec3i(-1, 0, 0) : new Vec3i(1, 0, 0);
|
||||
// }
|
||||
if(axis != null) {
|
||||
switch(axis) {
|
||||
case X:
|
||||
dv = new Vec3i(1, 0, 0);
|
||||
break;
|
||||
case Y:
|
||||
dv = new Vec3i(0, 1, 0);
|
||||
break;
|
||||
case Z:
|
||||
dv = new Vec3i(0, 0, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(dv == null) {
|
||||
continue;
|
||||
}
|
||||
values.add(new RotationValue(mask, (byte)(map.get(v) & mask), new Vector(dv.getX(), dv.getY(), dv.getZ())));
|
||||
if(axis != null) {
|
||||
values.add(new RotationValue(mask, (byte)(map.get(v) & mask), new Vector(-dv.getX(), -dv.getY(), -dv.getZ())));
|
||||
}
|
||||
}
|
||||
if(!values.isEmpty()) {
|
||||
int legacyId = common.init.BlockRegistry.getIdFromBlock(block);
|
||||
Rotation state = new Rotation(values.toArray(new RotationValue[values.size()]), predicate);
|
||||
// Log.CONFIG.debug("Block " + game.init.BlockRegistry.REGISTRY.getNameForObject(block) + "/" + legacyId + " mask = " + String.format("0x%x", mask));
|
||||
// for(RotationValue value : values) {
|
||||
// Log.CONFIG.debug(" meta " + value.data + " -> " + value.direction.toString());
|
||||
// }
|
||||
MAP.put(block, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static Rotation getRotation(Block block) {
|
||||
return MAP.get(block);
|
||||
}
|
||||
}
|
25
server/src/main/java/server/clipboard/RotationValue.java
Executable file
25
server/src/main/java/server/clipboard/RotationValue.java
Executable file
|
@ -0,0 +1,25 @@
|
|||
package server.clipboard;
|
||||
|
||||
public class RotationValue {
|
||||
public final byte mask;
|
||||
public final byte data;
|
||||
public final Vector direction;
|
||||
|
||||
public RotationValue(byte mask, byte data, Vector direction) {
|
||||
this.mask = mask;
|
||||
this.data = data;
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
public boolean isSet(int meta) {
|
||||
return (meta & mask) == data;
|
||||
}
|
||||
|
||||
public int set(int meta) {
|
||||
return ((meta & ~mask) | data);
|
||||
}
|
||||
|
||||
public Vector getDirection() {
|
||||
return direction;
|
||||
}
|
||||
}
|
802
server/src/main/java/server/clipboard/Vector.java
Executable file
802
server/src/main/java/server/clipboard/Vector.java
Executable file
|
@ -0,0 +1,802 @@
|
|||
package server.clipboard;
|
||||
|
||||
public class Vector implements Comparable<Vector> {
|
||||
public static final Vector ZERO = new Vector(0, 0, 0);
|
||||
|
||||
protected final double x, y, z;
|
||||
|
||||
public Vector(double x, double y, double z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Construct an instance.
|
||||
// *
|
||||
// * @param x the X coordinate
|
||||
// * @param y the Y coordinate
|
||||
// * @param z the Z coordinate
|
||||
// */
|
||||
// public Vector(int x, int y, int z) {
|
||||
// this.x = (double) x;
|
||||
// this.y = (double) y;
|
||||
// this.z = (double) z;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Construct an instance.
|
||||
// *
|
||||
// * @param x the X coordinate
|
||||
// * @param y the Y coordinate
|
||||
// * @param z the Z coordinate
|
||||
// */
|
||||
// public Vector(float x, float y, float z) {
|
||||
// this.x = (double) x;
|
||||
// this.y = (double) y;
|
||||
// this.z = (double) z;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Copy another vector.
|
||||
// *
|
||||
// * @param other another vector to make a copy of
|
||||
// */
|
||||
// public Vector(Vector other) {
|
||||
// this.x = other.x;
|
||||
// this.y = other.y;
|
||||
// this.z = other.z;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Construct a new instance with X, Y, and Z coordinates set to 0.
|
||||
*
|
||||
* <p>One can also refer to a static {@link #ZERO}.</p>
|
||||
*/
|
||||
public Vector() {
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.z = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the X coordinate.
|
||||
*
|
||||
* @return the x coordinate
|
||||
*/
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the X coordinate rounded.
|
||||
*
|
||||
* @return the x coordinate
|
||||
*/
|
||||
public int getBlockX() {
|
||||
return (int) Math.round(x);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Set the X coordinate.
|
||||
// *
|
||||
// * @param x the new X
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector setX(double x) {
|
||||
// return new Vector(x, y, z);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Set the X coordinate.
|
||||
// *
|
||||
// * @param x the X coordinate
|
||||
// * @return new vector
|
||||
// */
|
||||
// public Vector setX(int x) {
|
||||
// return new Vector(x, y, z);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get the Y coordinate.
|
||||
*
|
||||
* @return the y coordinate
|
||||
*/
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Y coordinate rounded.
|
||||
*
|
||||
* @return the y coordinate
|
||||
*/
|
||||
public int getBlockY() {
|
||||
return (int) Math.round(y);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Set the Y coordinate.
|
||||
// *
|
||||
// * @param y the new Y
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector setY(double y) {
|
||||
// return new Vector(x, y, z);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Set the Y coordinate.
|
||||
// *
|
||||
// * @param y the new Y
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector setY(int y) {
|
||||
// return new Vector(x, y, z);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get the Z coordinate.
|
||||
*
|
||||
* @return the z coordinate
|
||||
*/
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Z coordinate rounded.
|
||||
*
|
||||
* @return the z coordinate
|
||||
*/
|
||||
public int getBlockZ() {
|
||||
return (int) Math.round(z);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Set the Z coordinate.
|
||||
// *
|
||||
// * @param z the new Z
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector setZ(double z) {
|
||||
// return new Vector(x, y, z);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Set the Z coordinate.
|
||||
// *
|
||||
// * @param z the new Z
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector setZ(int z) {
|
||||
// return new Vector(x, y, z);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Add another vector to this vector and return the result as a new vector.
|
||||
// *
|
||||
// * @param other the other vector
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector add(Vector other) {
|
||||
// return new Vector(x + other.x, y + other.y, z + other.z);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Add another vector to this vector and return the result as a new vector.
|
||||
// *
|
||||
// * @param x the value to add
|
||||
// * @param y the value to add
|
||||
// * @param z the value to add
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector add(double x, double y, double z) {
|
||||
// return new Vector(this.x + x, this.y + y, this.z + z);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Add another vector to this vector and return the result as a new vector.
|
||||
// *
|
||||
// * @param x the value to add
|
||||
// * @param y the value to add
|
||||
// * @param z the value to add
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector add(int x, int y, int z) {
|
||||
// return new Vector(this.x + x, this.y + y, this.z + z);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Add a list of vectors to this vector and return the
|
||||
// * result as a new vector.
|
||||
// *
|
||||
// * @param others an array of vectors
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector add(Vector... others) {
|
||||
// double newX = x, newY = y, newZ = z;
|
||||
//
|
||||
// for (Vector other : others) {
|
||||
// newX += other.x;
|
||||
// newY += other.y;
|
||||
// newZ += other.z;
|
||||
// }
|
||||
//
|
||||
// return new Vector(newX, newY, newZ);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Subtract another vector from this vector and return the result
|
||||
* as a new vector.
|
||||
*
|
||||
* @param other the other vector
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector subtract(Vector other) {
|
||||
return new Vector(x - other.x, y - other.y, z - other.z);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Subtract another vector from this vector and return the result
|
||||
// * as a new vector.
|
||||
// *
|
||||
// * @param x the value to subtract
|
||||
// * @param y the value to subtract
|
||||
// * @param z the value to subtract
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector subtract(double x, double y, double z) {
|
||||
// return new Vector(this.x - x, this.y - y, this.z - z);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Subtract another vector from this vector and return the result
|
||||
// * as a new vector.
|
||||
// *
|
||||
// * @param x the value to subtract
|
||||
// * @param y the value to subtract
|
||||
// * @param z the value to subtract
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector subtract(int x, int y, int z) {
|
||||
// return new Vector(this.x - x, this.y - y, this.z - z);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Subtract a list of vectors from this vector and return the result
|
||||
// * as a new vector.
|
||||
// *
|
||||
// * @param others an array of vectors
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector subtract(Vector... others) {
|
||||
// double newX = x, newY = y, newZ = z;
|
||||
//
|
||||
// for (Vector other : others) {
|
||||
// newX -= other.x;
|
||||
// newY -= other.y;
|
||||
// newZ -= other.z;
|
||||
// }
|
||||
//
|
||||
// return new Vector(newX, newY, newZ);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Multiply this vector by another vector on each component.
|
||||
// *
|
||||
// * @param other the other vector
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector multiply(Vector other) {
|
||||
// return new Vector(x * other.x, y * other.y, z * other.z);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Multiply this vector by another vector on each component.
|
||||
// *
|
||||
// * @param x the value to multiply
|
||||
// * @param y the value to multiply
|
||||
// * @param z the value to multiply
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector multiply(double x, double y, double z) {
|
||||
// return new Vector(this.x * x, this.y * y, this.z * z);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Multiply this vector by another vector on each component.
|
||||
// *
|
||||
// * @param x the value to multiply
|
||||
// * @param y the value to multiply
|
||||
// * @param z the value to multiply
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector multiply(int x, int y, int z) {
|
||||
// return new Vector(this.x * x, this.y * y, this.z * z);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Multiply this vector by zero or more vectors on each component.
|
||||
// *
|
||||
// * @param others an array of vectors
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector multiply(Vector... others) {
|
||||
// double newX = x, newY = y, newZ = z;
|
||||
//
|
||||
// for (Vector other : others) {
|
||||
// newX *= other.x;
|
||||
// newY *= other.y;
|
||||
// newZ *= other.z;
|
||||
// }
|
||||
//
|
||||
// return new Vector(newX, newY, newZ);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Perform scalar multiplication and return a new vector.
|
||||
// *
|
||||
// * @param n the value to multiply
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector multiply(double n) {
|
||||
// return new Vector(this.x * n, this.y * n, this.z * n);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Perform scalar multiplication and return a new vector.
|
||||
// *
|
||||
// * @param n the value to multiply
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector multiply(float n) {
|
||||
// return new Vector(this.x * n, this.y * n, this.z * n);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Perform scalar multiplication and return a new vector.
|
||||
// *
|
||||
// * @param n the value to multiply
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector multiply(int n) {
|
||||
// return new Vector(this.x * n, this.y * n, this.z * n);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Divide this vector by another vector on each component.
|
||||
// *
|
||||
// * @param other the other vector
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector divide(Vector other) {
|
||||
// return new Vector(x / other.x, y / other.y, z / other.z);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Divide this vector by another vector on each component.
|
||||
// *
|
||||
// * @param x the value to divide by
|
||||
// * @param y the value to divide by
|
||||
// * @param z the value to divide by
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector divide(double x, double y, double z) {
|
||||
// return new Vector(this.x / x, this.y / y, this.z / z);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Divide this vector by another vector on each component.
|
||||
// *
|
||||
// * @param x the value to divide by
|
||||
// * @param y the value to divide by
|
||||
// * @param z the value to divide by
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector divide(int x, int y, int z) {
|
||||
// return new Vector(this.x / x, this.y / y, this.z / z);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Perform scalar division and return a new vector.
|
||||
// *
|
||||
// * @param n the value to divide by
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector divide(int n) {
|
||||
// return new Vector(x / n, y / n, z / n);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Perform scalar division and return a new vector.
|
||||
*
|
||||
* @param n the value to divide by
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector divide(double n) {
|
||||
return new Vector(x / n, y / n, z / n);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Perform scalar division and return a new vector.
|
||||
// *
|
||||
// * @param n the value to divide by
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector divide(float n) {
|
||||
// return new Vector(x / n, y / n, z / n);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get the length of the vector.
|
||||
*
|
||||
* @return length
|
||||
*/
|
||||
public double length() {
|
||||
return Math.sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Get the length, squared, of the vector.
|
||||
// *
|
||||
// * @return length, squared
|
||||
// */
|
||||
// public double lengthSq() {
|
||||
// return x * x + y * y + z * z;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Get the distance between this vector and another vector.
|
||||
// *
|
||||
// * @param other the other vector
|
||||
// * @return distance
|
||||
// */
|
||||
// public double distance(Vector other) {
|
||||
// return Math.sqrt(Math.pow(other.x - x, 2) +
|
||||
// Math.pow(other.y - y, 2) +
|
||||
// Math.pow(other.z - z, 2));
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Get the distance between this vector and another vector, squared.
|
||||
// *
|
||||
// * @param other the other vector
|
||||
// * @return distance
|
||||
// */
|
||||
// public double distanceSq(Vector other) {
|
||||
// return Math.pow(other.x - x, 2) +
|
||||
// Math.pow(other.y - y, 2) +
|
||||
// Math.pow(other.z - z, 2);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Get the normalized vector, which is the vector divided by its
|
||||
* length, as a new vector.
|
||||
*
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector normalize() {
|
||||
return divide(length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the dot product of this and another vector.
|
||||
*
|
||||
* @param other the other vector
|
||||
* @return the dot product of this and the other vector
|
||||
*/
|
||||
public double dot(Vector other) {
|
||||
return x * other.x + y * other.y + z * other.z;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Gets the cross product of this and another vector.
|
||||
// *
|
||||
// * @param other the other vector
|
||||
// * @return the cross product of this and the other vector
|
||||
// */
|
||||
// public Vector cross(Vector other) {
|
||||
// return new Vector(
|
||||
// y * other.z - z * other.y,
|
||||
// z * other.x - x * other.z,
|
||||
// x * other.y - y * other.x
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Checks to see if a vector is contained with another.
|
||||
// *
|
||||
// * @param min the minimum point (X, Y, and Z are the lowest)
|
||||
// * @param max the maximum point (X, Y, and Z are the lowest)
|
||||
// * @return true if the vector is contained
|
||||
// */
|
||||
// public boolean containedWithin(Vector min, Vector max) {
|
||||
// return x >= min.x && x <= max.x && y >= min.y && y <= max.y && z >= min.z && z <= max.z;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Checks to see if a vector is contained with another, comparing
|
||||
// * using discrete comparisons, inclusively.
|
||||
// *
|
||||
// * @param min the minimum point (X, Y, and Z are the lowest)
|
||||
// * @param max the maximum point (X, Y, and Z are the lowest)
|
||||
// * @return true if the vector is contained
|
||||
// */
|
||||
// public boolean containedWithinBlock(Vector min, Vector max) {
|
||||
// return getBlockX() >= min.getBlockX() && getBlockX() <= max.getBlockX()
|
||||
// && getBlockY() >= min.getBlockY() && getBlockY() <= max.getBlockY()
|
||||
// && getBlockZ() >= min.getBlockZ() && getBlockZ() <= max.getBlockZ();
|
||||
// }
|
||||
|
||||
/**
|
||||
* Clamp the Y component.
|
||||
*
|
||||
* @param min the minimum value
|
||||
* @param max the maximum value
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector clampY(int min, int max) {
|
||||
return new Vector(x, Math.max(min, Math.min(max, y)), z);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Floors the values of all components.
|
||||
// *
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector floor() {
|
||||
// return new Vector(Math.floor(x), Math.floor(y), Math.floor(z));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Rounds all components up.
|
||||
// *
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector ceil() {
|
||||
// return new Vector(Math.ceil(x), Math.ceil(y), Math.ceil(z));
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Rounds all components to the closest integer.
|
||||
// *
|
||||
// * <p>Components < 0.5 are rounded down, otherwise up.</p>
|
||||
// *
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector round() {
|
||||
// return new Vector(Math.floor(x + 0.5), Math.floor(y + 0.5), Math.floor(z + 0.5));
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Returns a vector with the absolute values of the components of
|
||||
// * this vector.
|
||||
// *
|
||||
// * @return a new vector
|
||||
// */
|
||||
// public Vector positive() {
|
||||
// return new Vector(Math.abs(x), Math.abs(y), Math.abs(z));
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Perform a 2D transformation on this vector and return a new one.
|
||||
// *
|
||||
// * @param angle in degrees
|
||||
// * @param aboutX about which x coordinate to rotate
|
||||
// * @param aboutZ about which z coordinate to rotate
|
||||
// * @param translateX what to add after rotation
|
||||
// * @param translateZ what to add after rotation
|
||||
// * @return a new vector
|
||||
// * @see AffineTransform another method to transform vectors
|
||||
// */
|
||||
// public Vector transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) {
|
||||
// angle = Math.toRadians(angle);
|
||||
// double x = this.x - aboutX;
|
||||
// double z = this.z - aboutZ;
|
||||
// double x2 = x * Math.cos(angle) - z * Math.sin(angle);
|
||||
// double z2 = x * Math.sin(angle) + z * Math.cos(angle);
|
||||
//
|
||||
// return new Vector(
|
||||
// x2 + aboutX + translateX,
|
||||
// y,
|
||||
// z2 + aboutZ + translateZ
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Returns whether this vector is collinear with another vector.
|
||||
// *
|
||||
// * @param other the other vector
|
||||
// * @return true if collinear
|
||||
// */
|
||||
// public boolean isCollinearWith(Vector other) {
|
||||
// if (x == 0 && y == 0 && z == 0) {
|
||||
// // this is a zero vector
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// final double otherX = other.x;
|
||||
// final double otherY = other.y;
|
||||
// final double otherZ = other.z;
|
||||
//
|
||||
// if (otherX == 0 && otherY == 0 && otherZ == 0) {
|
||||
// // other is a zero vector
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// if ((x == 0) != (otherX == 0)) return false;
|
||||
// if ((y == 0) != (otherY == 0)) return false;
|
||||
// if ((z == 0) != (otherZ == 0)) return false;
|
||||
//
|
||||
// final double quotientX = otherX / x;
|
||||
// if (!Double.isNaN(quotientX)) {
|
||||
// return other.equals(multiply(quotientX));
|
||||
// }
|
||||
//
|
||||
// final double quotientY = otherY / y;
|
||||
// if (!Double.isNaN(quotientY)) {
|
||||
// return other.equals(multiply(quotientY));
|
||||
// }
|
||||
//
|
||||
// final double quotientZ = otherZ / z;
|
||||
// if (!Double.isNaN(quotientZ)) {
|
||||
// return other.equals(multiply(quotientZ));
|
||||
// }
|
||||
//
|
||||
// throw new RuntimeException("This should not happen");
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Get this vector's pitch as used within the game.
|
||||
// *
|
||||
// * @return pitch in radians
|
||||
// */
|
||||
// public float toPitch() {
|
||||
// double x = getX();
|
||||
// double z = getZ();
|
||||
//
|
||||
// if (x == 0 && z == 0) {
|
||||
// return getY() > 0 ? -90 : 90;
|
||||
// } else {
|
||||
// double x2 = x * x;
|
||||
// double z2 = z * z;
|
||||
// double xz = Math.sqrt(x2 + z2);
|
||||
// return (float) Math.toDegrees(Math.atan(-getY() / xz));
|
||||
// }
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Get this vector's yaw as used within the game.
|
||||
// *
|
||||
// * @return yaw in radians
|
||||
// */
|
||||
// public float toYaw() {
|
||||
// double x = getX();
|
||||
// double z = getZ();
|
||||
//
|
||||
// double t = Math.atan2(-x, z);
|
||||
// double _2pi = 2 * Math.PI;
|
||||
//
|
||||
// return (float) Math.toDegrees(((t + _2pi) % _2pi));
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Create a new {@code BlockVector} using the given components.
|
||||
// *
|
||||
// * @param x the X coordinate
|
||||
// * @param y the Y coordinate
|
||||
// * @param z the Z coordinate
|
||||
// * @return a new {@code BlockVector}
|
||||
// */
|
||||
// public static BlockVector toBlockPoint(double x, double y, double z) {
|
||||
// return new BlockVector(
|
||||
// Math.floor(x),
|
||||
// Math.floor(y),
|
||||
// Math.floor(z)
|
||||
// );
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Create a new {@code BlockVector} from this vector.
|
||||
// *
|
||||
// * @return a new {@code BlockVector}
|
||||
// */
|
||||
// public BlockVector toBlockVector() {
|
||||
// return new BlockVector(this);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Creates a 2D vector by dropping the Y component from this vector.
|
||||
// *
|
||||
// * @return a new {@code Vector2D}
|
||||
// */
|
||||
// public Vector2D toVector2D() {
|
||||
// return new Vector2D(x, z);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof Vector)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector other = (Vector) obj;
|
||||
return other.x == this.x && other.y == this.y && other.z == this.z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Vector other) {
|
||||
if (other == null) {
|
||||
throw new IllegalArgumentException("null not supported");
|
||||
}
|
||||
if (y != other.y) return Double.compare(y, other.y);
|
||||
if (z != other.z) return Double.compare(z, other.z);
|
||||
if (x != other.x) return Double.compare(x, other.x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
|
||||
hash = 79 * hash + (int) (Double.doubleToLongBits(this.x) ^ (Double.doubleToLongBits(this.x) >>> 32));
|
||||
hash = 79 * hash + (int) (Double.doubleToLongBits(this.y) ^ (Double.doubleToLongBits(this.y) >>> 32));
|
||||
hash = 79 * hash + (int) (Double.doubleToLongBits(this.z) ^ (Double.doubleToLongBits(this.z) >>> 32));
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return x + ", " + y + ", " + z;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Gets the minimum components of two vectors.
|
||||
// *
|
||||
// * @param v1 the first vector
|
||||
// * @param v2 the second vector
|
||||
// * @return minimum
|
||||
// */
|
||||
// public static Vector getMinimum(Vector v1, Vector v2) {
|
||||
// return new Vector(
|
||||
// Math.min(v1.x, v2.x),
|
||||
// Math.min(v1.y, v2.y),
|
||||
// Math.min(v1.z, v2.z)
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Gets the maximum components of two vectors.
|
||||
// *
|
||||
// * @param v1 the first vector
|
||||
// * @param v2 the second vector
|
||||
// * @return maximum
|
||||
// */
|
||||
// public static Vector getMaximum(Vector v1, Vector v2) {
|
||||
// return new Vector(
|
||||
// Math.max(v1.x, v2.x),
|
||||
// Math.max(v1.y, v2.y),
|
||||
// Math.max(v1.z, v2.z)
|
||||
// );
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Gets the midpoint of two vectors.
|
||||
// *
|
||||
// * @param v1 the first vector
|
||||
// * @param v2 the second vector
|
||||
// * @return maximum
|
||||
// */
|
||||
// public static Vector getMidpoint(Vector v1, Vector v2) {
|
||||
// return new Vector(
|
||||
// (v1.x + v2.x) / 2,
|
||||
// (v1.y + v2.y) / 2,
|
||||
// (v1.z + v2.z) / 2
|
||||
// );
|
||||
// }
|
||||
|
||||
// public BlockPos toBlockPos() {
|
||||
// return new BlockPos(x, y, z);
|
||||
// }
|
||||
}
|
7
server/src/main/java/server/command/ArgCombiner.java
Normal file
7
server/src/main/java/server/command/ArgCombiner.java
Normal file
|
@ -0,0 +1,7 @@
|
|||
package server.command;
|
||||
|
||||
public interface ArgCombiner<T> {
|
||||
Object combine(T[] values);
|
||||
Class<?> getTypeClass();
|
||||
Class<T> getInputClass();
|
||||
}
|
33
server/src/main/java/server/command/Argument.java
Normal file
33
server/src/main/java/server/command/Argument.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class Argument {
|
||||
private final Parameter parameter;
|
||||
private final int position;
|
||||
private final String[] inputs;
|
||||
private final Map<String, Object> values;
|
||||
|
||||
public Argument(Parameter parameter, int position, String[] inputs, Map<String, Object> values) {
|
||||
this.parameter = parameter;
|
||||
this.position = position;
|
||||
this.inputs = inputs;
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public Parameter getParameter() {
|
||||
return this.parameter;
|
||||
}
|
||||
|
||||
public int getPosition() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
public String[] getInputs() {
|
||||
return this.inputs;
|
||||
}
|
||||
|
||||
public Map<String, Object> getValues() {
|
||||
return this.values;
|
||||
}
|
||||
}
|
100
server/src/main/java/server/command/ArgumentParser.java
Normal file
100
server/src/main/java/server/command/ArgumentParser.java
Normal file
|
@ -0,0 +1,100 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import common.collect.Lists;
|
||||
|
||||
public abstract class ArgumentParser {
|
||||
public static String[][] splitString(String str) {
|
||||
// if(str.isEmpty()) {
|
||||
// return new String[0];
|
||||
// }
|
||||
int pos;
|
||||
int last = 0;
|
||||
boolean space = true;
|
||||
boolean quote = false;
|
||||
boolean escape = false;
|
||||
char c;
|
||||
String arg = "";
|
||||
List<String> args = Lists.<String>newArrayList();
|
||||
List<String[]> cmds = Lists.<String[]>newArrayList();
|
||||
for(pos = 0; pos < str.length(); pos++) {
|
||||
c = str.charAt(pos);
|
||||
if(escape) {
|
||||
escape = false;
|
||||
switch(c) {
|
||||
case '\\':
|
||||
case ' ':
|
||||
case '"':
|
||||
case ';':
|
||||
arg += c;
|
||||
break;
|
||||
default:
|
||||
throw new RunException("Unbekannte Sequenz bei Zeichen %d: '\\%c'", pos + 1, c);
|
||||
}
|
||||
}
|
||||
else if(c == '\\') {
|
||||
space = false;
|
||||
escape = true;
|
||||
}
|
||||
else if(c == '"') {
|
||||
space = false;
|
||||
quote = !quote;
|
||||
last = pos;
|
||||
}
|
||||
else if(c == ' ' && !quote) {
|
||||
if(!space) {
|
||||
args.add(arg);
|
||||
arg = "";
|
||||
}
|
||||
space = true;
|
||||
}
|
||||
else if(c == ';' && !quote) {
|
||||
if(!space) {
|
||||
args.add(arg);
|
||||
arg = "";
|
||||
}
|
||||
space = true;
|
||||
if(!args.isEmpty()) {
|
||||
cmds.add(args.toArray(new String[args.size()]));
|
||||
args.clear();
|
||||
}
|
||||
}
|
||||
else {
|
||||
space = false;
|
||||
arg += c;
|
||||
}
|
||||
}
|
||||
if(escape)
|
||||
throw new RunException("Unvollständige Sequenz bei Zeichen %d", pos + 1);
|
||||
if(quote)
|
||||
throw new RunException("Nicht geschlossenes Anführungszeichen bei %d", last + 1);
|
||||
if(!space)
|
||||
args.add(arg);
|
||||
if(!args.isEmpty()) {
|
||||
cmds.add(args.toArray(new String[args.size()]));
|
||||
args.clear();
|
||||
}
|
||||
return cmds.toArray(new String[cmds.size()][]);
|
||||
}
|
||||
|
||||
private final String name;
|
||||
|
||||
public ArgumentParser(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public abstract Object parse(CommandEnvironment env, String input);
|
||||
public abstract Object getDefault(CommandEnvironment env);
|
||||
public abstract Collection<String> getCompletions(CommandEnvironment env);
|
||||
public abstract Class<?> getTypeClass(boolean required);
|
||||
|
||||
public final String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public final String toString() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
411
server/src/main/java/server/command/ArgumentSplitter.java
Normal file
411
server/src/main/java/server/command/ArgumentSplitter.java
Normal file
|
@ -0,0 +1,411 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.collect.Maps;
|
||||
import common.collect.Sets;
|
||||
|
||||
public class ArgumentSplitter {
|
||||
private final String command;
|
||||
private final Map<String, Argument> arguments;
|
||||
private final CommandEnvironment env;
|
||||
|
||||
protected ArgumentSplitter(Map<String, Argument> arguments, String command, CommandEnvironment env) {
|
||||
this.arguments = arguments;
|
||||
this.command = command;
|
||||
this.env = env;
|
||||
}
|
||||
|
||||
private static <T> String joinArgs(Iterable<T> iter) {
|
||||
StringBuilder sb = new StringBuilder("'");
|
||||
for(T obj : iter) {
|
||||
if(sb.length() > 1)
|
||||
sb.append("', '");
|
||||
sb.append(String.valueOf(obj));
|
||||
}
|
||||
return sb.append("'").toString();
|
||||
}
|
||||
|
||||
public static ArgumentSplitter parseArgs(CommandEnvironment env, String str, String[] argv, CachedExecutable cached) {
|
||||
Map<String, Parameter> parameters = cached.getParameters();
|
||||
List<Parameter> positionals = Lists.newArrayList(cached.getPositionals());
|
||||
// String[] argv = ArgumentParser.splitString(str);
|
||||
Map<String, Argument> args = Maps.newHashMap();
|
||||
int ppos = 0;
|
||||
boolean parse = true;
|
||||
for(int z = 1; z < argv.length; z++) {
|
||||
String arg = argv[z];
|
||||
Parameter param = null;
|
||||
boolean pos = false;
|
||||
if(parse && arg.equals("--")) {
|
||||
parse = false;
|
||||
continue;
|
||||
}
|
||||
else if(parse && (arg.startsWith("--") || (arg.startsWith("-") && arg.length() == 2))) {
|
||||
param = parameters.get(arg.substring(arg.startsWith("--") ? 2 : 1));
|
||||
if(param != null && param.isPositional() && !args.containsKey(param.getName())) {
|
||||
for(int n = 0; n < positionals.size(); n++) {
|
||||
if(param == positionals.get(n)) {
|
||||
positionals.remove(n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(ppos < positionals.size()) {
|
||||
param = positionals.get(ppos++);
|
||||
pos = true;
|
||||
}
|
||||
else {
|
||||
throw new RunException("Position %d: Parameter '%s' ist überflüssig", z, arg);
|
||||
}
|
||||
if(param == null)
|
||||
throw new RunException("Position %d: Argument '%s' ist unbekannt", z, arg);
|
||||
if(args.containsKey(param.getName()))
|
||||
throw new RunException("Position %d: Parameter '%s' mehrfach angegeben", z, param.getName());
|
||||
int nargs = param.getParsers().size();
|
||||
// if(!pos)
|
||||
// z += 1;
|
||||
if(z + (pos ? 0 : 1) + nargs > argv.length)
|
||||
if(nargs == 1 && param.getName().equals(param.getParsers().get(0).getName()))
|
||||
throw new RunException("Position %d: Argument '%s' benötigt einen Parameter", z, param.getName());
|
||||
else
|
||||
throw new RunException("Position %d: Argument '%s' benötigt %d Parameter (%s)", z, param.getName(), nargs,
|
||||
joinArgs(param.getParsers()));
|
||||
Map<String, Object> params = Maps.newHashMapWithExpectedSize(nargs);
|
||||
String[] inputs = new String[nargs + (pos ? 0 : 1)];
|
||||
int apos = 0;
|
||||
for(int n = pos ? 0 : 1; n < nargs + (pos ? 0 : 1); n++) {
|
||||
String par = inputs[n] = argv[z + n];
|
||||
ArgumentParser parser = param.getParsers().get(apos);
|
||||
if(parse && (par.startsWith("--") || (par.startsWith("-") && par.length() == 2)))
|
||||
if(nargs == 1 && param.getName().equals(parser.getName()))
|
||||
throw new RunException("Position %d: Argument '%s': '%s' als Parameter verwendet", z + n, param.getName(), par);
|
||||
else
|
||||
throw new RunException("Position %d: Argument '%s': '%s' als Parameter '%s' (#%d) verwendet", z + n,
|
||||
param.getName(), par, parser.getName(), apos + 1);
|
||||
try {
|
||||
params.put(parser.getName(), parser.parse(env, par));
|
||||
}
|
||||
catch(Throwable e) {
|
||||
if(nargs == 1 && param.getName().equals(parser.getName()))
|
||||
throw new RunException(e, "Position %d: Argument '%s': Parameter konnte nicht interpretiert werden", z + n,
|
||||
param.getName());
|
||||
else
|
||||
throw new RunException(e, "Position %d: Argument '%s': Parameter '%s' (#%d) konnte nicht interpretiert werden", z + n,
|
||||
param.getName(), parser.getName(), apos + 1);
|
||||
}
|
||||
apos += 1;
|
||||
}
|
||||
if(!pos)
|
||||
inputs[0] = arg;
|
||||
args.put(param.getName(), new Argument(param, z, inputs, params));
|
||||
z += nargs - (pos ? 1 : 0);
|
||||
}
|
||||
for(Parameter param : parameters.values()) {
|
||||
if(!args.containsKey(param.getName())) {
|
||||
if(param.isRequired()) {
|
||||
for(ArgumentParser parser : param.getParsers()) {
|
||||
if(parser.getDefault(env) == null)
|
||||
throw new RunException("Argument '%s' muss angegeben werden", param.getName());
|
||||
}
|
||||
}
|
||||
else if(param.getParsers().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
Map<String, Object> params = Maps.newHashMapWithExpectedSize(param.getParsers().size());
|
||||
for(ArgumentParser parser : param.getParsers()) {
|
||||
params.put(parser.getName(), parser.getDefault(env));
|
||||
}
|
||||
args.put(param.getName(), new Argument(param, -1, null, params));
|
||||
}
|
||||
}
|
||||
return new ArgumentSplitter(args, str, env);
|
||||
}
|
||||
|
||||
private static Iterable<String> getParam(CommandEnvironment env, String[] argv, CachedExecutable cached) {
|
||||
Map<String, Parameter> parameters = cached.getParameters();
|
||||
List<Parameter> positionals = Lists.newArrayList(cached.getPositionals());
|
||||
Set<String> args = Sets.newHashSet();
|
||||
int ppos = 0;
|
||||
boolean parse = true;
|
||||
for(int z = 1; z < argv.length; z++) {
|
||||
String arg = argv[z];
|
||||
Parameter param = null;
|
||||
boolean pos = false;
|
||||
if(z == argv.length - 1) {
|
||||
if(ppos < positionals.size()) {
|
||||
param = positionals.get(ppos);
|
||||
if(param.getParsers().isEmpty()) // np
|
||||
return null;
|
||||
return param.getParsers().get(0).getCompletions(env);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if(parse && arg.equals("--")) {
|
||||
parse = false;
|
||||
continue;
|
||||
}
|
||||
else if(parse && (arg.startsWith("--") || (arg.startsWith("-") && arg.length() == 2))) {
|
||||
param = parameters.get(arg.substring(arg.startsWith("--") ? 2 : 1));
|
||||
if(param != null && param.isPositional() && !args.contains(param.getName())) {
|
||||
for(int n = 0; n < positionals.size(); n++) {
|
||||
if(param == positionals.get(n)) {
|
||||
positionals.remove(n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(ppos < positionals.size()) {
|
||||
param = positionals.get(ppos++);
|
||||
pos = true;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
if(param == null || args.contains(param.getName()))
|
||||
return null;
|
||||
int nargs = param.getParsers().size();
|
||||
// if(z + (pos ? 0 : 1) + nargs > argv.length - 1) {
|
||||
// return param.getParsers().get(argv.length - z).getCompletions(env);
|
||||
// }
|
||||
int apos = 0;
|
||||
for(int n = pos ? 0 : 1; n < nargs + (pos ? 0 : 1); n++) {
|
||||
if(z + n == argv.length - 1)
|
||||
return param.getParsers().get(apos).getCompletions(env);
|
||||
String par = argv[z + n];
|
||||
if(parse && (par.startsWith("--") || (par.startsWith("-") && par.length() == 2)))
|
||||
return null;
|
||||
apos += 1;
|
||||
}
|
||||
args.add(param.getName());
|
||||
z += nargs - (pos ? 1 : 0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Iterable<String> parseComplete(CommandEnvironment env, String[] argv, CachedExecutable cached, String last) {
|
||||
Iterable<String> comp = getParam(env, argv, cached);
|
||||
if(comp == null /* || comp.length == 0 */ ) {
|
||||
Set<String> params = Sets.newTreeSet();
|
||||
boolean all = last.startsWith("--");
|
||||
for(String param : cached.getParameters().keySet()) {
|
||||
if(all || param.length() == 1)
|
||||
params.add(param.length() == 1 ? "-" + param : ("--" + param));
|
||||
}
|
||||
return params;
|
||||
}
|
||||
return comp;
|
||||
}
|
||||
|
||||
// public ScriptArg getArg(String name) {
|
||||
// return this.arguments.get(name);
|
||||
// }
|
||||
|
||||
public boolean hasArg(String name) {
|
||||
return this.arguments.containsKey(name);
|
||||
}
|
||||
|
||||
// public boolean has(String name, String par) {
|
||||
// return this.arguments.containsKey(name) && this.arguments.get(name).getValues().containsKey(par);
|
||||
// }
|
||||
|
||||
// public boolean has(String name) {
|
||||
// return this.has(name, name);
|
||||
// }
|
||||
|
||||
// public <T> T getDefault(String name, String par, T def) {
|
||||
// ScriptArg arg = this.arguments.get(name);
|
||||
// if(arg == null)
|
||||
// return def;
|
||||
// Object value = arg.getValues().get(par);
|
||||
// return value == null ? def : (T)value;
|
||||
// }
|
||||
//
|
||||
// public <T> T getDefault(String name, T def) {
|
||||
// return this.getDefault(name, name, def);
|
||||
// }
|
||||
//
|
||||
// public <T> T getUnchecked(String name, String par) {
|
||||
// return this.getDefault(name, par, null);
|
||||
// }
|
||||
|
||||
public <T> T getUnchecked(String name, String par) {
|
||||
Argument arg = this.arguments.get(name);
|
||||
if(arg == null)
|
||||
return null;
|
||||
Object value = arg.getValues().get(par);
|
||||
return value == null ? null : (T)value;
|
||||
}
|
||||
|
||||
// public <T> T getUnchecked(String name) {
|
||||
// return this.getDefault(name, null);
|
||||
// }
|
||||
//
|
||||
// public boolean getBool(String name, boolean def) {
|
||||
// return this.getDefault(name, def);
|
||||
// }
|
||||
//
|
||||
// public boolean getBool(String name) {
|
||||
// return this.getUnchecked(name);
|
||||
// }
|
||||
//
|
||||
// public <T extends Enum<?>> T getEnum(String name, T def) {
|
||||
// return this.getDefault(name, def);
|
||||
// }
|
||||
//
|
||||
// public <T extends Enum<?>> T getEnum(String name) {
|
||||
// return this.getUnchecked(name);
|
||||
// }
|
||||
//
|
||||
// public int getInt(String name, int def) {
|
||||
// return this.getDefault(name, def);
|
||||
// }
|
||||
//
|
||||
// public int getInt(String name) {
|
||||
// return this.getUnchecked(name);
|
||||
// }
|
||||
//
|
||||
// public long getLong(String name, long def) {
|
||||
// return this.getDefault(name, def);
|
||||
// }
|
||||
//
|
||||
// public long getLong(String name) {
|
||||
// return this.getUnchecked(name);
|
||||
// }
|
||||
//
|
||||
// public double getDouble(String name, double def) {
|
||||
// return this.getDefault(name, def);
|
||||
// }
|
||||
//
|
||||
// public double getDouble(String name) {
|
||||
// return this.getUnchecked(name);
|
||||
// }
|
||||
//
|
||||
// public String getString(String name, String def) {
|
||||
// return this.getDefault(name, def);
|
||||
// }
|
||||
//
|
||||
// public String getString(String name) {
|
||||
// return this.getUnchecked(name);
|
||||
// }
|
||||
//
|
||||
// public String[] getStrings(String name, String[] def) {
|
||||
// return this.getDefault(name, def);
|
||||
// }
|
||||
//
|
||||
// public String[] getStrings(String name) {
|
||||
// return this.getUnchecked(name);
|
||||
// }
|
||||
//
|
||||
// public Entity getEntity(String name, Entity def) {
|
||||
// return this.getDefault(name, def);
|
||||
// }
|
||||
//
|
||||
// public Entity getEntity(String name) {
|
||||
// return this.getUnchecked(name);
|
||||
// }
|
||||
//
|
||||
// public EntityLiving getLiving(String name, EntityLiving def) {
|
||||
// return this.getDefault(name, def);
|
||||
// }
|
||||
//
|
||||
// public EntityLiving getLiving(String name) {
|
||||
// return this.getUnchecked(name);
|
||||
// }
|
||||
//
|
||||
// public EntityNPC getNpc(String name, EntityNPC def) {
|
||||
// return this.getDefault(name, def);
|
||||
// }
|
||||
//
|
||||
// public EntityNPC getNpc(String name) {
|
||||
// return this.getUnchecked(name);
|
||||
// }
|
||||
//
|
||||
// public Block getBlock(String name, Block def) {
|
||||
// return this.getDefault(name, def);
|
||||
// }
|
||||
//
|
||||
// public Block getBlock(String name) {
|
||||
// return this.getUnchecked(name);
|
||||
// }
|
||||
//
|
||||
// public State getState(String name, State def) {
|
||||
// return this.getDefault(name, def);
|
||||
// }
|
||||
//
|
||||
// public State getState(String name) {
|
||||
// return this.getUnchecked(name);
|
||||
// }
|
||||
//
|
||||
// public Item getItem(String name, Item def) {
|
||||
// return this.getDefault(name, def);
|
||||
// }
|
||||
//
|
||||
// public Item getItem(String name) {
|
||||
// return this.getUnchecked(name);
|
||||
// }
|
||||
//
|
||||
// public ItemStack getStack(String name, ItemStack def) {
|
||||
// return this.getDefault(name, def);
|
||||
// }
|
||||
//
|
||||
// public ItemStack getStack(String name) {
|
||||
// return this.getUnchecked(name);
|
||||
// }
|
||||
//
|
||||
// public BlockPos getColumnPos(String name, BlockPos def) {
|
||||
// return this.hasArg(name) ? this.getColumnPos(name) : def;
|
||||
// }
|
||||
//
|
||||
// public BlockPos getColumnPos(String name) {
|
||||
// return new BlockPos(this.getUnchecked(name, "x"), 0, this.getUnchecked(name, "z"));
|
||||
// }
|
||||
//
|
||||
// public BlockPos getBlockPos(String name, BlockPos def) {
|
||||
// return this.hasArg(name) ? this.getBlockPos(name) : def;
|
||||
// }
|
||||
//
|
||||
// public BlockPos getBlockPos(String name) {
|
||||
// return new BlockPos(this.getUnchecked(name, "x"), this.getUnchecked(name, "y"), this.getUnchecked(name, "z"));
|
||||
// }
|
||||
//
|
||||
// public WorldPos getWorldPos(String name, WorldPos def) {
|
||||
// return this.hasArg(name) ? this.getWorldPos(name) : def;
|
||||
// }
|
||||
//
|
||||
// public WorldPos getWorldPos(String name) {
|
||||
// return new WorldPos(this.getUnchecked(name, "x"), this.getUnchecked(name, "y"), this.getUnchecked(name, "z"),
|
||||
// this.getUnchecked(name, "dim"));
|
||||
// }
|
||||
//
|
||||
// public Vec3 getVector2D(String name, Vec3 def) {
|
||||
// return this.hasArg(name) ? this.getVector2D(name) : def;
|
||||
// }
|
||||
//
|
||||
// public Vec3 getVector2D(String name) {
|
||||
// return new Vec3(this.getUnchecked(name, "x"), 0.0, this.getUnchecked(name, "z"));
|
||||
// }
|
||||
//
|
||||
// public Vec3 getVector(String name, Vec3 def) {
|
||||
// return this.hasArg(name) ? this.getVector(name) : def;
|
||||
// }
|
||||
//
|
||||
// public Vec3 getVector(String name) {
|
||||
// return new Vec3(this.getUnchecked(name, "x"), this.getUnchecked(name, "y"), this.getUnchecked(name, "z"));
|
||||
// }
|
||||
//
|
||||
// public WorldServer getWorld(String name) {
|
||||
// return this.getUnchecked(name);
|
||||
// }
|
||||
//
|
||||
// public NBTTagCompound getTag(String name) {
|
||||
// return this.getUnchecked(name);
|
||||
// }
|
||||
}
|
11
server/src/main/java/server/command/BooleanParser.java
Normal file
11
server/src/main/java/server/command/BooleanParser.java
Normal file
|
@ -0,0 +1,11 @@
|
|||
package server.command;
|
||||
|
||||
public class BooleanParser extends EnumParser<Boolean> {
|
||||
public BooleanParser(String name, Boolean def) {
|
||||
super(name, Boolean.class, def, true, false);
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return this.hasDefault() || required ? boolean.class : Boolean.class;
|
||||
}
|
||||
}
|
93
server/src/main/java/server/command/CachedExecutable.java
Normal file
93
server/src/main/java/server/command/CachedExecutable.java
Normal file
|
@ -0,0 +1,93 @@
|
|||
package server.command;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.collect.Maps;
|
||||
|
||||
public class CachedExecutable {
|
||||
private final Executable executable;
|
||||
private final String name;
|
||||
private final Map<String, Parameter> parameters;
|
||||
private final List<Parameter> positionals;
|
||||
private final Method method;
|
||||
|
||||
protected CachedExecutable(Executable executable, Map<String, Parameter> parameters, List<Parameter> positionals, Method method) {
|
||||
this.executable = executable;
|
||||
this.parameters = parameters;
|
||||
this.positionals = positionals;
|
||||
this.name = executable.getName();
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public static CachedExecutable cacheExecutable(Executable executable) {
|
||||
Map<String, Parameter> parameters = Maps.newTreeMap();
|
||||
Map<String, Parameter> params = executable.getParameters();
|
||||
parameters.putAll(params);
|
||||
Parameter[] positions = new Parameter[parameters.size()];
|
||||
int pos = -1;
|
||||
for(Parameter param : params.values()) {
|
||||
if(param.isPositional()) {
|
||||
positions[param.getPosition()] = param;
|
||||
pos = param.getPosition() > pos ? param.getPosition() : pos;
|
||||
}
|
||||
if(param.hasShortName())
|
||||
parameters.put("" + param.getShortName(), param);
|
||||
}
|
||||
List<Parameter> positionals = Lists.newArrayList();
|
||||
for(int z = 0; z <= pos; z++) {
|
||||
if(positions[z] == null)
|
||||
throw new NullPointerException("positions[" + z + "]");
|
||||
positionals.add(positions[z]);
|
||||
}
|
||||
List<Class<?>> classes = Lists.newArrayList(CommandEnvironment.class, Executor.class);
|
||||
for(Parameter param : executable.getParamList()) {
|
||||
ArgCombiner<?> combiner = param.getCombiner();
|
||||
if(combiner != null) {
|
||||
classes.add(combiner.getTypeClass());
|
||||
continue;
|
||||
}
|
||||
if(param.getParsers().isEmpty()) {
|
||||
classes.add(boolean.class);
|
||||
continue;
|
||||
}
|
||||
for(ArgumentParser parser : param.getParsers()) {
|
||||
classes.add(parser.getTypeClass(param.isRequired()));
|
||||
}
|
||||
}
|
||||
Method method;
|
||||
try {
|
||||
method = executable.getClass().getDeclaredMethod("exec", classes.toArray(new Class<?>[classes.size()]));
|
||||
}
|
||||
catch(NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return new CachedExecutable(executable, parameters, positionals, method);
|
||||
}
|
||||
|
||||
public Executable getExecutable() {
|
||||
return this.executable;
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return this.method;
|
||||
}
|
||||
|
||||
public Map<String, Parameter> getParameters() {
|
||||
return this.parameters;
|
||||
}
|
||||
|
||||
public List<Parameter> getPositionals() {
|
||||
return this.positionals;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
27
server/src/main/java/server/command/ColorParser.java
Normal file
27
server/src/main/java/server/command/ColorParser.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
package server.command;
|
||||
|
||||
import common.color.DyeColor;
|
||||
|
||||
public class ColorParser extends IntParser {
|
||||
public ColorParser(String name, Integer def, Object ... completions) {
|
||||
super(name, true, def, null, null, completions);
|
||||
}
|
||||
|
||||
public ColorParser(String name, Integer def) {
|
||||
this(name, def, (Object[])DyeColor.values());
|
||||
}
|
||||
|
||||
public Integer parse(CommandEnvironment env, String input) {
|
||||
if(input.startsWith("#")) {
|
||||
input = input.substring(1);
|
||||
}
|
||||
else {
|
||||
DyeColor color = DyeColor.getByString(input);
|
||||
if(color != null)
|
||||
return color.getColor();
|
||||
}
|
||||
if(input.length() != 6)
|
||||
throw new RunException("Der Farbcode muss 6 Stellen haben, habe %d ('%s')", input.length(), input);
|
||||
return super.parse(env, input);
|
||||
}
|
||||
}
|
220
server/src/main/java/server/command/Command.java
Normal file
220
server/src/main/java/server/command/Command.java
Normal file
|
@ -0,0 +1,220 @@
|
|||
package server.command;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.collect.Maps;
|
||||
import common.util.CharValidator;
|
||||
import common.util.Vec3;
|
||||
import common.world.World;
|
||||
import server.command.DoubleParser.DefType;
|
||||
|
||||
public abstract class Command implements Executable {
|
||||
private final String name;
|
||||
private final Map<String, Parameter> parameters = Maps.newHashMap();
|
||||
private final List<Parameter> argList = Lists.newArrayList();
|
||||
|
||||
private int parPos = 0;
|
||||
private boolean parReq = true;
|
||||
|
||||
protected Command(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
protected Command setParamsOptional() {
|
||||
this.parReq = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Command addParameter(String name, ArgCombiner<?> combiner, ArgumentParser ... parsers) {
|
||||
Parameter param = new Parameter(name, (char)0, this.parPos++, this.parReq, Lists.newArrayList(parsers), combiner);
|
||||
this.parameters.put(name, param);
|
||||
this.argList.add(param);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Command addParameter(String name, char shortName, ArgCombiner<?> combiner, ArgumentParser ... parsers) {
|
||||
Parameter param = new Parameter(name, shortName, -1, false, Lists.newArrayList(parsers), combiner);
|
||||
this.parameters.put(name, param);
|
||||
this.argList.add(param);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Command addParameter(String name, ArgumentParser ... parsers) {
|
||||
return this.addParameter(name, null, parsers);
|
||||
}
|
||||
|
||||
protected Command addParameter(String name, char shortName, ArgumentParser ... parsers) {
|
||||
return this.addParameter(name, shortName, null, parsers);
|
||||
}
|
||||
|
||||
protected Command addParameter(ArgumentParser parser) {
|
||||
return this.addParameter(parser.getName(), parser);
|
||||
}
|
||||
|
||||
protected Command addParameter(char shortName, ArgumentParser parser) {
|
||||
return this.addParameter(parser.getName(), shortName, parser);
|
||||
}
|
||||
|
||||
protected Command addVector(String name, boolean defaulted, boolean centered) {
|
||||
return this.addParameter(name, new ArgCombiner<Double>() {
|
||||
public Vec3 combine(Double[] values) {
|
||||
return new Vec3(values[0], values[1], values[2]);
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass() {
|
||||
return Vec3.class;
|
||||
}
|
||||
|
||||
public Class<Double> getInputClass() {
|
||||
return Double.class;
|
||||
}
|
||||
},
|
||||
new DoubleParser("x", defaulted ? DefType.X : null, (double)(-World.MAX_SIZE), (double)World.MAX_SIZE, centered),
|
||||
new DoubleParser("y", defaulted ? DefType.Y : null, (double)(-World.MAX_SIZE_Y), (double)World.MAX_SIZE_Y, false),
|
||||
new DoubleParser("z", defaulted ? DefType.Z : null, (double)(-World.MAX_SIZE), (double)World.MAX_SIZE, centered));
|
||||
}
|
||||
|
||||
protected Command addWorld(String name, boolean defaulted) {
|
||||
return this.addParameter(new WorldParser(name, false, defaulted));
|
||||
}
|
||||
|
||||
protected Command addDimension(String name, boolean defaulted) {
|
||||
return this.addParameter(new DimensionParser(name, defaulted));
|
||||
}
|
||||
|
||||
protected Command addInt(String name, char shortName, int min, int max, int def) {
|
||||
return this.addParameter(shortName, new IntParser(name, false, def, min, max, def));
|
||||
}
|
||||
|
||||
protected Command addInt(String name, int min, int max, int def) {
|
||||
return this.addParameter(new IntParser(name, false, def, min, max, def));
|
||||
}
|
||||
|
||||
protected Command addDouble(String name, char shortName, double min, double max, double def) {
|
||||
return this.addParameter(shortName, new DoubleParser(name, def, min, max, false, def));
|
||||
}
|
||||
|
||||
protected Command addDouble(String name, double min, double max, double def) {
|
||||
return this.addParameter(new DoubleParser(name, def, min, max, false, def));
|
||||
}
|
||||
|
||||
protected Command addInt(String name, char shortName, int min, int max) {
|
||||
return this.addParameter(shortName, new IntParser(name, false, null, min, max));
|
||||
}
|
||||
|
||||
protected Command addInt(String name, int min, int max) {
|
||||
return this.addParameter(new IntParser(name, false, null, min, max));
|
||||
}
|
||||
|
||||
protected Command addDouble(String name, char shortName, double min, double max) {
|
||||
return this.addParameter(shortName, new DoubleParser(name, null, min, max, false));
|
||||
}
|
||||
|
||||
protected Command addDouble(String name, double min, double max) {
|
||||
return this.addParameter(new DoubleParser(name, null, min, max, false));
|
||||
}
|
||||
|
||||
protected Command addFlag(String name, char shortName) {
|
||||
return this.addParameter(name, shortName);
|
||||
}
|
||||
|
||||
// protected ScriptExecutable addFlag(String name) {
|
||||
// return this.addParameter(name, name.charAt(0));
|
||||
// }
|
||||
|
||||
protected <T> Command addEnum(String name, T def, Class<T> clazz, T ... values) {
|
||||
return this.addParameter(new EnumParser<T>(name, clazz, def, values));
|
||||
}
|
||||
|
||||
protected <T> Command addEnum(String name, Class<T> clazz, T ... values) {
|
||||
return this.addEnum(name, null, clazz, values);
|
||||
}
|
||||
|
||||
protected <T> Command addEnum(String name, T def, Class<T> clazz, Collection<T> values) {
|
||||
return this.addEnum(name, def, clazz, values.toArray((T[])Array.newInstance(clazz, values.size())));
|
||||
}
|
||||
|
||||
protected <T> Command addEnum(String name, Class<T> clazz, Collection<T> values) {
|
||||
return this.addEnum(name, null, clazz, values);
|
||||
}
|
||||
|
||||
protected <T> Command addEnum(String name, char shortName, T def, Class<T> clazz, T ... values) {
|
||||
return this.addParameter(shortName, new EnumParser<T>(name, clazz, def, values));
|
||||
}
|
||||
|
||||
protected Command addTag(String name) {
|
||||
return this.addParameter(new TagParser(name, null));
|
||||
}
|
||||
|
||||
protected Command addTag(String name, char shortName) {
|
||||
return this.addParameter(shortName, new TagParser(name, null));
|
||||
}
|
||||
|
||||
protected Command addPlayer(String name, boolean defaulted) {
|
||||
return this.addParameter(new PlayerParser(name, defaulted));
|
||||
}
|
||||
|
||||
protected Command addPlayerEntity(String name, boolean defaulted) {
|
||||
return this.addParameter(new PlayerEntityParser(name, defaulted));
|
||||
}
|
||||
|
||||
protected Command addEntity(String name, boolean defaulted) {
|
||||
return this.addParameter(new EntityParser(name, defaulted, false));
|
||||
}
|
||||
|
||||
protected Command addEntity(String name, char shortName, boolean defaulted) {
|
||||
return this.addParameter(shortName, new EntityParser(name, defaulted, false));
|
||||
}
|
||||
|
||||
protected Command addEntityList(String name, boolean defaulted) {
|
||||
return this.addParameter(new EntityListParser(name, defaulted, false));
|
||||
}
|
||||
|
||||
protected Command addEntityList(String name, char shortName, boolean defaulted) {
|
||||
return this.addParameter(shortName, new EntityListParser(name, defaulted, false));
|
||||
}
|
||||
|
||||
protected Command addLivingEntity(String name, boolean defaulted) {
|
||||
return this.addParameter(new EntityParser(name, defaulted, true));
|
||||
}
|
||||
|
||||
protected Command addLivingEntityList(String name, boolean defaulted) {
|
||||
return this.addParameter(new EntityListParser(name, defaulted, true));
|
||||
}
|
||||
|
||||
protected Command addString(String name, boolean allowEmpty, Object ... completions) {
|
||||
return this.addParameter(new StringParser(name, null, allowEmpty, null, null, null, completions));
|
||||
}
|
||||
|
||||
protected Command addString(String name, boolean allowEmpty, StringCompleter completer) {
|
||||
return this.addParameter(new StringParser(name, null, allowEmpty, null, null, null, completer));
|
||||
}
|
||||
|
||||
protected Command addString(String name, String def, boolean allowEmpty, Object ... completions) {
|
||||
return this.addParameter(new StringParser(name, def, allowEmpty, null, null, null, completions));
|
||||
}
|
||||
|
||||
protected Command addString(String name, String def, boolean allowEmpty, StringCompleter completer) {
|
||||
return this.addParameter(new StringParser(name, def, allowEmpty, null, null, null, completer));
|
||||
}
|
||||
|
||||
protected Command addString(String name, boolean allowEmpty, Integer min, Integer max, CharValidator validator) {
|
||||
return this.addParameter(new StringParser(name, null, allowEmpty, min, max, validator));
|
||||
}
|
||||
|
||||
public Map<String, Parameter> getParameters() {
|
||||
return this.parameters;
|
||||
}
|
||||
|
||||
public List<Parameter> getParamList() {
|
||||
return this.argList;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
285
server/src/main/java/server/command/CommandEnvironment.java
Normal file
285
server/src/main/java/server/command/CommandEnvironment.java
Normal file
|
@ -0,0 +1,285 @@
|
|||
package server.command;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.collect.Maps;
|
||||
import common.collect.Sets;
|
||||
import common.color.TextColor;
|
||||
import common.log.Log;
|
||||
import server.Server;
|
||||
import server.command.commands.CommandAdmin;
|
||||
import server.command.commands.CommandHelp;
|
||||
import server.command.commands.CommandKick;
|
||||
import server.command.commands.CommandMessage;
|
||||
import server.command.commands.CommandMilk;
|
||||
import server.command.commands.CommandOfflinetp;
|
||||
import server.command.commands.CommandPasswd;
|
||||
import server.command.commands.CommandPlayers;
|
||||
import server.command.commands.CommandPotion;
|
||||
import server.command.commands.CommandRegister;
|
||||
import server.command.commands.CommandRemove;
|
||||
import server.command.commands.CommandRevoke;
|
||||
import server.command.commands.CommandSave;
|
||||
import server.command.commands.CommandShutdown;
|
||||
import server.command.commands.CommandSpawn;
|
||||
import server.command.commands.CommandTele;
|
||||
import server.command.commands.CommandTime;
|
||||
import server.command.commands.CommandTp;
|
||||
import server.command.commands.CommandWarp;
|
||||
import server.command.commands.CommandWeather;
|
||||
import server.command.commands.CommandWorld;
|
||||
|
||||
public class CommandEnvironment {
|
||||
private final Server server;
|
||||
private final Map<String, CachedExecutable> executables = Maps.newTreeMap();
|
||||
private final List<PatternReplacer> replacers = Lists.newArrayList();
|
||||
private final Set<String> builtins = Sets.newHashSet();
|
||||
private final Map<String, String> variables = Maps.newHashMap();
|
||||
|
||||
private Executor currentExecutor;
|
||||
private Object previousOutput;
|
||||
|
||||
public CommandEnvironment(Server server) {
|
||||
this.server = server;
|
||||
this.registerDefaults();
|
||||
}
|
||||
|
||||
public void registerExecutable(Executable executable) {
|
||||
CachedExecutable cached = CachedExecutable.cacheExecutable(executable);
|
||||
if(this.executables.containsKey(cached.getName()))
|
||||
throw new IllegalStateException("Befehl " + cached.getName() + " ist bereits registriert");
|
||||
this.executables.put(cached.getName(), cached);
|
||||
this.registerReplacer(cached.getName(), new Function<String, String>() {
|
||||
public String apply(String str) {
|
||||
Object o;
|
||||
try {
|
||||
o = CommandEnvironment.this.execute(str, false);
|
||||
}
|
||||
catch(Throwable e) {
|
||||
throw new RunException(e, "Variable konnte nicht ersetzt werden: '%s' konnte nicht ausgeführt werden", str);
|
||||
}
|
||||
if(o == null)
|
||||
throw new RunException("Variable konnte nicht ersetzt werden: null von '%s' zurückgegeben", str);
|
||||
return o.toString();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void registerReplacer(String var, Function<String, String> function) {
|
||||
if(this.builtins.contains(var))
|
||||
throw new IllegalStateException("Variable " + var + " ist bereits registriert");
|
||||
this.replacers.add(new PatternReplacer(var, true, function));
|
||||
this.builtins.add(var);
|
||||
}
|
||||
|
||||
public void registerVariable(String var, Variable variable) {
|
||||
if(this.builtins.contains(var))
|
||||
throw new IllegalStateException("Variable " + var + " ist bereits registriert");
|
||||
this.replacers.add(new PatternReplacer(var, false, new Function<String, String>() {
|
||||
public String apply(String ign) {
|
||||
return variable.get();
|
||||
}
|
||||
}));
|
||||
this.builtins.add(var);
|
||||
}
|
||||
|
||||
public Server getServer() {
|
||||
return this.server;
|
||||
}
|
||||
|
||||
public Map<String, CachedExecutable> getExecutables() {
|
||||
return this.executables;
|
||||
}
|
||||
|
||||
public Executor getExecutor() {
|
||||
return this.currentExecutor;
|
||||
}
|
||||
|
||||
private String substitute(String str) {
|
||||
StringBuffer sb = new StringBuffer(str);
|
||||
for(PatternReplacer replacer : this.replacers) {
|
||||
replacer.replaceVar(sb);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private Object execute(String cmd, boolean setPrev) {
|
||||
String line = this.substitute(cmd);
|
||||
String[][] cmds = ArgumentParser.splitString(line);
|
||||
Object o = null;
|
||||
for(String[] argv : cmds) {
|
||||
String exec = argv[0];
|
||||
String var = null;
|
||||
int eq = exec.indexOf('=');
|
||||
if(eq >= 0) {
|
||||
var = exec.substring(0, eq);
|
||||
exec = exec.substring(eq + 1);
|
||||
}
|
||||
CachedExecutable cached = this.executables.get(exec);
|
||||
if(cached == null)
|
||||
throw new RunException("Befehl '%s' existiert nicht", exec);
|
||||
for(int z = 0; z < argv.length; z++) {
|
||||
String arg = argv[z];
|
||||
if(arg.startsWith("$(") && arg.endsWith(")")) {
|
||||
String resolve = this.variables.get(arg.substring(2, arg.length() - 1));
|
||||
if(resolve != null)
|
||||
argv[z] = resolve;
|
||||
}
|
||||
}
|
||||
ArgumentSplitter args = ArgumentSplitter.parseArgs(this, cmd, argv, cached);
|
||||
List<Object> params = Lists.newArrayList(this, this.currentExecutor);
|
||||
for(Parameter param : cached.getExecutable().getParamList()) {
|
||||
ArgCombiner combiner = param.getCombiner();
|
||||
if(combiner != null) {
|
||||
Object[] data = (Object[])Array.newInstance(combiner.getInputClass(), param.getParsers().size());
|
||||
for(int z = 0; z < data.length; z++) {
|
||||
data[z] = args.getUnchecked(param.getName(), param.getParsers().get(z).getName());
|
||||
if(data[z] == null) {
|
||||
data = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
params.add(data == null ? null : combiner.combine(data));
|
||||
continue;
|
||||
}
|
||||
if(param.getParsers().isEmpty()) {
|
||||
params.add(args.hasArg(param.getName()));
|
||||
continue;
|
||||
}
|
||||
for(ArgumentParser parser : param.getParsers()) {
|
||||
params.add(args.getUnchecked(param.getName(), parser.getName()));
|
||||
}
|
||||
}
|
||||
try {
|
||||
o = cached.getMethod().invoke(cached.getExecutable(), params.toArray(new Object[params.size()]));
|
||||
}
|
||||
catch(InvocationTargetException e) {
|
||||
if(e.getCause() instanceof RuntimeException)
|
||||
throw ((RuntimeException)e.getCause());
|
||||
else
|
||||
throw new RuntimeException(e.getCause());
|
||||
}
|
||||
catch(IllegalAccessException | IllegalArgumentException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// o = cached.getExecutable().exec(this, args);
|
||||
if(setPrev)
|
||||
this.previousOutput = o;
|
||||
if(var != null && !var.isEmpty() && !this.builtins.contains(var)) {
|
||||
if(o != null)
|
||||
this.variables.put(var, String.valueOf(o));
|
||||
else
|
||||
this.variables.remove(var);
|
||||
}
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
public void execute(String cmd, Executor exec) {
|
||||
this.currentExecutor = exec;
|
||||
try {
|
||||
this.execute(cmd, true);
|
||||
}
|
||||
catch(RunException e) {
|
||||
Throwable cause = e;
|
||||
do {
|
||||
exec.logConsole(TextColor.RED + cause.getMessage());
|
||||
cause = cause.getCause();
|
||||
}
|
||||
while(cause != null);
|
||||
}
|
||||
catch(Throwable t) {
|
||||
exec.logConsole(TextColor.RED + "Fehler: %s", t.getMessage());
|
||||
Log.CONSOLE.error(t, "Fehler beim Ausführen von Befehl '%s'", cmd);
|
||||
}
|
||||
finally {
|
||||
this.currentExecutor = null;
|
||||
this.previousOutput = null;
|
||||
this.variables.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> complete(String cmd, Executor exec) {
|
||||
this.currentExecutor = exec;
|
||||
List<String> list = Lists.newArrayList();
|
||||
try {
|
||||
String[][] cmds = ArgumentParser.splitString(cmd.endsWith(" ") ? cmd + "END" : cmd);
|
||||
if(cmds.length == 0)
|
||||
return list;
|
||||
String[] argv = cmds[cmds.length - 1];
|
||||
if(argv.length == 0)
|
||||
return list;
|
||||
String param = cmd.endsWith(" ") ? "" : argv[argv.length - 1];
|
||||
Iterable<String> comp;
|
||||
if(argv.length > 1) {
|
||||
int eq = argv[0].indexOf('=');
|
||||
CachedExecutable cached = this.executables.get(eq >= 0 ? argv[0].substring(eq + 1) : argv[0]);
|
||||
if(cached == null)
|
||||
return list;
|
||||
comp = ArgumentSplitter.parseComplete(this, argv, cached, param);
|
||||
}
|
||||
else {
|
||||
comp = this.executables.keySet();
|
||||
}
|
||||
for(String cmp : comp) {
|
||||
if(cmp.regionMatches(true, 0, param, 0, param.length()))
|
||||
list.add(cmp);
|
||||
}
|
||||
}
|
||||
catch(Throwable t) {
|
||||
list.clear();
|
||||
Log.CONSOLE.error(t, "Konnte Befehl '%s' nicht vervollständigen", cmd);
|
||||
}
|
||||
finally {
|
||||
this.currentExecutor = null;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public void registerDefaults() {
|
||||
this.registerVariable("*", new Variable() {
|
||||
public String get() {
|
||||
return CommandEnvironment.this.currentExecutor.getExecId();
|
||||
}
|
||||
});
|
||||
this.registerVariable("name", new Variable() {
|
||||
public String get() {
|
||||
return CommandEnvironment.this.currentExecutor.getExecName();
|
||||
}
|
||||
});
|
||||
this.registerVariable("!", new Variable() {
|
||||
public String get() {
|
||||
return CommandEnvironment.this.previousOutput == null ? null : CommandEnvironment.this.previousOutput.toString();
|
||||
}
|
||||
});
|
||||
|
||||
this.registerExecutable(new CommandSpawn());
|
||||
this.registerExecutable(new CommandPotion());
|
||||
this.registerExecutable(new CommandMilk());
|
||||
this.registerExecutable(new CommandAdmin());
|
||||
this.registerExecutable(new CommandRevoke());
|
||||
this.registerExecutable(new CommandTp());
|
||||
this.registerExecutable(new CommandTele());
|
||||
this.registerExecutable(new CommandWorld());
|
||||
this.registerExecutable(new CommandOfflinetp());
|
||||
this.registerExecutable(new CommandWarp());
|
||||
this.registerExecutable(new CommandTime());
|
||||
this.registerExecutable(new CommandRemove());
|
||||
this.registerExecutable(new CommandWeather());
|
||||
this.registerExecutable(new CommandKick());
|
||||
this.registerExecutable(new CommandMessage());
|
||||
this.registerExecutable(new CommandShutdown());
|
||||
this.registerExecutable(new CommandPasswd());
|
||||
this.registerExecutable(new CommandPlayers());
|
||||
this.registerExecutable(new CommandSave());
|
||||
this.registerExecutable(new CommandRegister());
|
||||
|
||||
this.registerExecutable(new CommandHelp(this));
|
||||
}
|
||||
}
|
7
server/src/main/java/server/command/Completer.java
Normal file
7
server/src/main/java/server/command/Completer.java
Normal file
|
@ -0,0 +1,7 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface Completer {
|
||||
void complete(List<String> comp, CommandEnvironment env, ArgumentSplitter args, Argument arg);
|
||||
}
|
21
server/src/main/java/server/command/CompletingParser.java
Normal file
21
server/src/main/java/server/command/CompletingParser.java
Normal file
|
@ -0,0 +1,21 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class CompletingParser extends ArgumentParser {
|
||||
private final List<String> defCompletions;
|
||||
|
||||
public CompletingParser(String name, Object ... completions) {
|
||||
super(name);
|
||||
this.defCompletions = new ArrayList<String>(completions.length);
|
||||
for(Object comp : completions) {
|
||||
this.defCompletions.add(String.valueOf(comp));
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<String> getCompletions(CommandEnvironment env) {
|
||||
return this.defCompletions;
|
||||
}
|
||||
}
|
18
server/src/main/java/server/command/DefaultingParser.java
Normal file
18
server/src/main/java/server/command/DefaultingParser.java
Normal file
|
@ -0,0 +1,18 @@
|
|||
package server.command;
|
||||
|
||||
public abstract class DefaultingParser extends CompletingParser {
|
||||
private final Object def;
|
||||
|
||||
public DefaultingParser(String name, Object def, Object ... completions) {
|
||||
super(name, completions);
|
||||
this.def = def;
|
||||
}
|
||||
|
||||
public Object getDefault(CommandEnvironment env) {
|
||||
return this.def;
|
||||
}
|
||||
|
||||
protected final boolean hasDefault() {
|
||||
return this.def != null;
|
||||
}
|
||||
}
|
49
server/src/main/java/server/command/DimensionParser.java
Normal file
49
server/src/main/java/server/command/DimensionParser.java
Normal file
|
@ -0,0 +1,49 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import common.dimension.Dimension;
|
||||
import common.init.UniverseRegistry;
|
||||
import common.util.Position;
|
||||
|
||||
public class DimensionParser extends CompletingParser {
|
||||
private final boolean useSender;
|
||||
|
||||
public DimensionParser(String name, boolean useSender) {
|
||||
super(name);
|
||||
this.useSender = useSender;
|
||||
}
|
||||
|
||||
public Object parse(CommandEnvironment env, String input) {
|
||||
Dimension dim = UniverseRegistry.getDimension(input);
|
||||
if(dim != null)
|
||||
return dim;
|
||||
int id = Integer.MIN_VALUE;
|
||||
try {
|
||||
id = Integer.parseInt(input);
|
||||
}
|
||||
catch(NumberFormatException e) {
|
||||
}
|
||||
dim = UniverseRegistry.getDimension(id);
|
||||
if(dim == null)
|
||||
throw new RunException("Unbekannte Dimension '%s'", input);
|
||||
return dim;
|
||||
}
|
||||
|
||||
public Object getDefault(CommandEnvironment env) {
|
||||
if(!this.useSender)
|
||||
return null;
|
||||
Position pos = env.getExecutor().getExecPos();
|
||||
return pos == null ? null : UniverseRegistry.getDimension(pos.dim);
|
||||
// if(dim == null)
|
||||
// throw new ScriptException("Unbekannte Dimension '%s'");
|
||||
}
|
||||
|
||||
public Collection<String> getCompletions(CommandEnvironment env) {
|
||||
return UniverseRegistry.getWorldNames();
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return Dimension.class;
|
||||
}
|
||||
}
|
95
server/src/main/java/server/command/DoubleParser.java
Normal file
95
server/src/main/java/server/command/DoubleParser.java
Normal file
|
@ -0,0 +1,95 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Position;
|
||||
|
||||
public class DoubleParser extends DefaultingParser {
|
||||
public static enum DefType {
|
||||
X, Y, Z, YAW, PITCH;
|
||||
}
|
||||
|
||||
private final DefType defType;
|
||||
private final Double min;
|
||||
private final Double max;
|
||||
private final boolean center;
|
||||
|
||||
public DoubleParser(String name, Double def, Double min, Double max, boolean center, Object ... completions) {
|
||||
super(name, def, completions);
|
||||
this.defType = null;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.center = center;
|
||||
}
|
||||
|
||||
public DoubleParser(String name, DefType type, Double min, Double max, boolean center) {
|
||||
super(name, null);
|
||||
this.defType = type;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.center = center;
|
||||
}
|
||||
|
||||
public Double parse(CommandEnvironment env, String input) {
|
||||
Double pre = this.defType != null && input.startsWith("~") ? this.getDefault(env) : null;
|
||||
input = pre != null ? input.substring(1) : input;
|
||||
double value;
|
||||
try {
|
||||
value = Double.parseDouble(input);
|
||||
}
|
||||
catch(NumberFormatException e) {
|
||||
throw new RunException("Ungültige Gleitkommazahl '%s'", input);
|
||||
}
|
||||
if(this.center && pre == null && input.indexOf('.') < 0)
|
||||
value += 0.5;
|
||||
if(this.min != null && value < this.min)
|
||||
if(this.max != null)
|
||||
throw new RunException("Die Zahl muss im Bereich %f .. %f liegen, habe %f", this.min, this.max, value);
|
||||
else
|
||||
throw new RunException("Die Zahl muss mindestens %f betragen, habe %f", this.min, value);
|
||||
if(this.max != null && value > this.max)
|
||||
if(this.min != null)
|
||||
throw new RunException("Die Zahl muss im Bereich %f .. %f liegen, habe %f", this.min, this.max, value);
|
||||
else
|
||||
throw new RunException("Die Zahl darf höchstens %f betragen, habe %f", this.max, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
public Double getDefault(CommandEnvironment env) {
|
||||
Position pos = this.defType == null ? null : env.getExecutor().getExecPos();
|
||||
if(this.defType != null)
|
||||
switch(this.defType) {
|
||||
case X:
|
||||
return pos == null ? null : pos.x;
|
||||
case Y:
|
||||
return pos == null ? null : pos.y;
|
||||
case Z:
|
||||
return pos == null ? null : pos.z;
|
||||
case YAW:
|
||||
return pos == null ? null : (double)pos.yaw;
|
||||
case PITCH:
|
||||
return pos == null ? null : (double)pos.pitch;
|
||||
}
|
||||
return (Double)super.getDefault(env);
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return this.hasDefault() || required ? double.class : Double.class;
|
||||
}
|
||||
|
||||
public Collection<String> getCompletions(CommandEnvironment env) {
|
||||
BlockPos pos = this.defType == null ? null : env.getExecutor().getPointedPosition();
|
||||
if(this.defType != null)
|
||||
switch(this.defType) {
|
||||
case X:
|
||||
return pos == null ? null : Lists.newArrayList("" + pos.getX());
|
||||
case Y:
|
||||
return pos == null ? null : Lists.newArrayList("" + pos.getY());
|
||||
case Z:
|
||||
return pos == null ? null : Lists.newArrayList("" + pos.getZ());
|
||||
}
|
||||
return super.getCompletions(env);
|
||||
}
|
||||
}
|
135
server/src/main/java/server/command/EntityListParser.java
Normal file
135
server/src/main/java/server/command/EntityListParser.java
Normal file
|
@ -0,0 +1,135 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.collect.Sets;
|
||||
import common.entity.Entity;
|
||||
import common.entity.EntityType;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.init.EntityRegistry;
|
||||
import server.network.Player;
|
||||
import server.world.WorldServer;
|
||||
|
||||
public class EntityListParser extends EntityParser {
|
||||
public EntityListParser(String name, boolean useSender, boolean livingOnly) {
|
||||
super(name, useSender, livingOnly);
|
||||
}
|
||||
|
||||
public Object parse(CommandEnvironment env, String input) {
|
||||
if(input.equals("**")) {
|
||||
List<Entity> list = Lists.newArrayList();
|
||||
for(WorldServer world : env.getServer().getWorlds()) {
|
||||
if(this.livingOnly) {
|
||||
for(Entity ent : world.getEntities()) {
|
||||
if(ent instanceof EntityLiving)
|
||||
list.add(ent);
|
||||
}
|
||||
}
|
||||
else {
|
||||
list.addAll(world.getEntities());
|
||||
}
|
||||
}
|
||||
if(list.isEmpty())
|
||||
throw new RunException(this.livingOnly ? "Keine lebendigen Objekte gefunden" : "Keine Objekte gefunden");
|
||||
return list;
|
||||
}
|
||||
else if(input.equals("*")) {
|
||||
List<Entity> list = Lists.newArrayList();
|
||||
for(Player plr : env.getServer().getPlayers()) {
|
||||
if(plr.getPresentEntity() != null)
|
||||
list.add(plr.getPresentEntity());
|
||||
}
|
||||
if(list.isEmpty())
|
||||
throw new RunException("Keine Spieler gefunden");
|
||||
return list;
|
||||
}
|
||||
Set<Class<? extends Entity>> classes = Sets.newHashSet();
|
||||
Set<EntityType> types = Sets.newHashSet();
|
||||
Set<Entity> entities = Sets.newHashSet();
|
||||
Set<Class<? extends Entity>> nclasses = Sets.newHashSet();
|
||||
Set<EntityType> ntypes = Sets.newHashSet();
|
||||
Set<Entity> nentities = Sets.newHashSet();
|
||||
Boolean living = null;
|
||||
Boolean player = null;
|
||||
for(String tok : input.split(",", -1)) {
|
||||
boolean negate = tok.startsWith("!");
|
||||
tok = negate ? tok.substring(1) : tok;
|
||||
Class<? extends Entity> clazz = EntityRegistry.getEntityClass(tok);
|
||||
if(clazz != null) {
|
||||
if(classes.contains(clazz) || nclasses.contains(clazz))
|
||||
throw new RunException("Objekttyp %s mehrfach angegeben", EntityRegistry.getEntityName(EntityRegistry.getEntityString(clazz)));
|
||||
if(this.livingOnly && !EntityLiving.class.isAssignableFrom(clazz))
|
||||
throw new RunException("Objekttyp %s ist nicht lebendig", EntityRegistry.getEntityName(EntityRegistry.getEntityString(clazz)));
|
||||
(negate ? nclasses : classes).add(clazz);
|
||||
}
|
||||
else if(tok.equals("Player")) {
|
||||
if(player != null)
|
||||
throw new RunException("'Player' mehrfach angegeben");
|
||||
player = !negate;
|
||||
}
|
||||
else if(tok.equals("Living")) {
|
||||
if(living != null)
|
||||
throw new RunException("'Living' mehrfach angegeben");
|
||||
if(this.livingOnly)
|
||||
throw new RunException("Kann nicht 'Living' als Objekttypen angeben");
|
||||
living = !negate;
|
||||
}
|
||||
else {
|
||||
EntityType type = EntityType.getByName(tok);
|
||||
if(type != null) {
|
||||
if(types.contains(type) || ntypes.contains(type))
|
||||
throw new RunException("Objekttyp %s mehrfach angegeben", type.getDisplay());
|
||||
(negate ? ntypes : types).add(type);
|
||||
}
|
||||
else {
|
||||
Entity ent = (Entity)super.parse(env, tok);
|
||||
if(entities.contains(ent) || nentities.contains(ent))
|
||||
throw new RunException("Objekt '%s' mehrfach angegeben", tok);
|
||||
(negate ? nentities : entities).add(ent);
|
||||
}
|
||||
}
|
||||
}
|
||||
List<Entity> filtered = Lists.newArrayList(entities);
|
||||
boolean negateOnly = (living == null && player == null && types.isEmpty() && classes.isEmpty() && entities.isEmpty());
|
||||
for(WorldServer world : env.getServer().getWorlds()) {
|
||||
for(Entity ent : world.getEntities()) {
|
||||
if((!this.livingOnly || ent instanceof EntityLiving) &&
|
||||
(negateOnly || (living != null && types.isEmpty() && classes.isEmpty() && living == (ent instanceof EntityLiving)) || (player != null && types.isEmpty() && classes.isEmpty() && player == ent.isPlayer()) || types.contains(ent.getType()) ||
|
||||
classes.contains(ent.getClass())) &&
|
||||
(living == null || living == (ent instanceof EntityLiving)) && (player == null || player == ent.isPlayer()) &&
|
||||
!ntypes.contains(ent.getType()) && !nclasses.contains(ent.getClass()) && !nentities.contains(ent) && !entities.contains(ent))
|
||||
filtered.add(ent);
|
||||
}
|
||||
}
|
||||
if(filtered.isEmpty())
|
||||
throw new RunException("Keine Objekte gefunden");
|
||||
return filtered;
|
||||
}
|
||||
|
||||
public Object getDefault(CommandEnvironment env) {
|
||||
Entity entity = (Entity)super.getDefault(env);
|
||||
return entity == null ? null : Lists.newArrayList(entity);
|
||||
}
|
||||
|
||||
public Collection<String> getCompletions(CommandEnvironment env) {
|
||||
Collection<String> comp = super.getCompletions(env);
|
||||
comp.add("*");
|
||||
for(Class<? extends Entity> clazz : EntityRegistry.getAllClasses()) {
|
||||
if(!this.livingOnly || EntityLiving.class.isAssignableFrom(clazz))
|
||||
comp.add(EntityRegistry.getEntityString(clazz));
|
||||
}
|
||||
for(EntityType type : EntityType.values()) {
|
||||
comp.add(type.getName());
|
||||
}
|
||||
Collections.addAll(comp, "Player", "Living", "**");
|
||||
return comp;
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return List.class;
|
||||
}
|
||||
}
|
60
server/src/main/java/server/command/EntityParser.java
Normal file
60
server/src/main/java/server/command/EntityParser.java
Normal file
|
@ -0,0 +1,60 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.entity.Entity;
|
||||
import common.entity.types.EntityLiving;
|
||||
import server.world.WorldServer;
|
||||
|
||||
public class EntityParser extends PlayerEntityParser {
|
||||
protected final boolean livingOnly;
|
||||
|
||||
public EntityParser(String name, boolean useSender, boolean livingOnly) {
|
||||
super(name, useSender);
|
||||
this.livingOnly = livingOnly;
|
||||
}
|
||||
|
||||
public Object parse(CommandEnvironment env, String input) {
|
||||
Entity entity = null;
|
||||
if(input.startsWith("#")) {
|
||||
int id = -1;
|
||||
try {
|
||||
id = Integer.parseInt(input.substring(1));
|
||||
}
|
||||
catch(NumberFormatException e) {
|
||||
}
|
||||
if(id != -1) {
|
||||
for(WorldServer world : env.getServer().getWorlds()) {
|
||||
entity = world.getEntityByID(id);
|
||||
if(entity != null)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
entity = (Entity)super.parse(env, input);
|
||||
}
|
||||
if(entity == null)
|
||||
throw new RunException("Objekt '%s' wurde nicht gefunden", input);
|
||||
else if(this.livingOnly && !(entity instanceof EntityLiving))
|
||||
throw new RunException("Objekt '%s' muss lebendig sein", input);
|
||||
return entity;
|
||||
}
|
||||
|
||||
public Object getDefault(CommandEnvironment env) {
|
||||
return this.useSender && (this.livingOnly ? (env.getExecutor() instanceof EntityLiving) : (env.getExecutor() instanceof Entity)) ? env.getExecutor() : super.getDefault(env);
|
||||
}
|
||||
|
||||
public Collection<String> getCompletions(CommandEnvironment env) {
|
||||
Entity target = env.getExecutor().getPointedEntity();
|
||||
List<String> comp = target == null || (this.livingOnly && !(target instanceof EntityLiving)) ? Lists.newArrayList() : Lists.newArrayList("#" + target.getId());
|
||||
comp.addAll(super.getCompletions(env));
|
||||
return comp;
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return this.livingOnly ? EntityLiving.class : Entity.class;
|
||||
}
|
||||
}
|
50
server/src/main/java/server/command/EnumParser.java
Normal file
50
server/src/main/java/server/command/EnumParser.java
Normal file
|
@ -0,0 +1,50 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import common.collect.Maps;
|
||||
|
||||
public class EnumParser<T> extends DefaultingParser {
|
||||
private final Class<T> clazz;
|
||||
private final Map<String, T> lookup = Maps.newHashMap();
|
||||
private final T[] selections;
|
||||
|
||||
private static <T> String joinArgs(T[] iter) {
|
||||
StringBuilder sb = new StringBuilder("'");
|
||||
for(T obj : iter) {
|
||||
if(sb.length() > 1)
|
||||
sb.append("', '");
|
||||
sb.append(String.valueOf(obj));
|
||||
}
|
||||
return sb.append("'").toString();
|
||||
}
|
||||
|
||||
public EnumParser(String name, Class<T> clazz, T def, T ... selections) {
|
||||
super(name, def, selections);
|
||||
this.clazz = clazz;
|
||||
this.selections = selections;
|
||||
for(T o : selections) {
|
||||
this.lookup.put(o.toString().toLowerCase(), o);
|
||||
}
|
||||
}
|
||||
|
||||
public T parse(CommandEnvironment env, String input) {
|
||||
T value = this.lookup.get(input.toLowerCase());
|
||||
if(value != null)
|
||||
return value;
|
||||
int id = -1;
|
||||
try {
|
||||
id = Integer.parseInt(input);
|
||||
}
|
||||
catch(NumberFormatException e) {
|
||||
}
|
||||
if(id < 0 || id >= this.selections.length)
|
||||
throw new RunException("Ungültige Auswahl '%s', muss eine von diesen Optionen sein: %s", input,
|
||||
joinArgs(this.selections));
|
||||
return this.selections[id];
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return this.clazz;
|
||||
}
|
||||
}
|
11
server/src/main/java/server/command/Executable.java
Normal file
11
server/src/main/java/server/command/Executable.java
Normal file
|
@ -0,0 +1,11 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface Executable {
|
||||
// Object exec(ScriptEnvironment env, ScriptArgs args);
|
||||
Map<String, Parameter> getParameters();
|
||||
List<Parameter> getParamList();
|
||||
String getName();
|
||||
}
|
27
server/src/main/java/server/command/Executor.java
Normal file
27
server/src/main/java/server/command/Executor.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
package server.command;
|
||||
|
||||
import common.entity.Entity;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Position;
|
||||
import server.network.Player;
|
||||
|
||||
public interface Executor {
|
||||
void logConsole(String msg);
|
||||
String getExecId();
|
||||
String getExecName();
|
||||
Position getExecPos();
|
||||
Entity getPointedEntity();
|
||||
BlockPos getPointedPosition();
|
||||
|
||||
default boolean isConsole() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean isPlayer() {
|
||||
return this instanceof Player;
|
||||
}
|
||||
|
||||
default void logConsole(String fmt, Object ... args) {
|
||||
this.logConsole(String.format(fmt, args));
|
||||
}
|
||||
}
|
57
server/src/main/java/server/command/FixedExecutor.java
Normal file
57
server/src/main/java/server/command/FixedExecutor.java
Normal file
|
@ -0,0 +1,57 @@
|
|||
package server.command;
|
||||
|
||||
import common.entity.Entity;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Position;
|
||||
import server.Server;
|
||||
|
||||
public class FixedExecutor implements Executor {
|
||||
private final Server server;
|
||||
private final String id;
|
||||
|
||||
private String name;
|
||||
private Position position;
|
||||
|
||||
public FixedExecutor(Server server, String id, String name, Position pos) {
|
||||
this.server = server;
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.position = pos;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setPosition(Position pos) {
|
||||
this.position = pos;
|
||||
}
|
||||
|
||||
public void logConsole(String msg) {
|
||||
this.server.logConsole(msg);
|
||||
}
|
||||
|
||||
public String getExecId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getExecName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public Position getExecPos() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
public Entity getPointedEntity() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public BlockPos getPointedPosition() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isConsole() {
|
||||
return true;
|
||||
}
|
||||
}
|
39
server/src/main/java/server/command/IntParser.java
Normal file
39
server/src/main/java/server/command/IntParser.java
Normal file
|
@ -0,0 +1,39 @@
|
|||
package server.command;
|
||||
|
||||
public class IntParser extends DefaultingParser {
|
||||
private final Integer min;
|
||||
private final Integer max;
|
||||
private final boolean hex;
|
||||
|
||||
public IntParser(String name, boolean hex, Integer def, Integer min, Integer max, Object ... completions) {
|
||||
super(name, def, completions);
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.hex = hex;
|
||||
}
|
||||
|
||||
public Integer parse(CommandEnvironment env, String input) {
|
||||
int value;
|
||||
try {
|
||||
value = Integer.parseInt(input, this.hex ? 16 : 10);
|
||||
}
|
||||
catch(NumberFormatException e) {
|
||||
throw new RunException("Ungültige " + (this.hex ? "Hexadezimalzahl" : "Ganzzahl") + " '%s'", input);
|
||||
}
|
||||
if(this.min != null && value < this.min)
|
||||
if(this.max != null)
|
||||
throw new RunException("Die Zahl muss im Bereich %d .. %d liegen, habe %d", this.min, this.max, value);
|
||||
else
|
||||
throw new RunException("Die Zahl muss mindestens %d betragen, habe %d", this.min, value);
|
||||
if(this.max != null && value > this.max)
|
||||
if(this.min != null)
|
||||
throw new RunException("Die Zahl muss im Bereich %d .. %d liegen, habe %d", this.min, this.max, value);
|
||||
else
|
||||
throw new RunException("Die Zahl darf höchstens %d betragen, habe %d", this.max, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return this.hasDefault() || required ? int.class : Integer.class;
|
||||
}
|
||||
}
|
37
server/src/main/java/server/command/LongParser.java
Normal file
37
server/src/main/java/server/command/LongParser.java
Normal file
|
@ -0,0 +1,37 @@
|
|||
package server.command;
|
||||
|
||||
public class LongParser extends DefaultingParser {
|
||||
private final Long min;
|
||||
private final Long max;
|
||||
|
||||
public LongParser(String name, Long def, Long min, Long max, Object ... completions) {
|
||||
super(name, def, completions);
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public Long parse(CommandEnvironment env, String input) {
|
||||
long value;
|
||||
try {
|
||||
value = Long.parseLong(input);
|
||||
}
|
||||
catch(NumberFormatException e) {
|
||||
throw new RunException("Ungültige Ganzzahl '%s'", input);
|
||||
}
|
||||
if(this.min != null && value < this.min)
|
||||
if(this.max != null)
|
||||
throw new RunException("Die Zahl muss im Bereich %d .. %d liegen, habe %d", this.min, this.max, value);
|
||||
else
|
||||
throw new RunException("Die Zahl muss mindestens %d betragen, habe %d", this.min, value);
|
||||
if(this.max != null && value > this.max)
|
||||
if(this.min != null)
|
||||
throw new RunException("Die Zahl muss im Bereich %d .. %d liegen, habe %d", this.min, this.max, value);
|
||||
else
|
||||
throw new RunException("Die Zahl darf höchstens %d betragen, habe %d", this.max, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return this.hasDefault() || required ? long.class : Long.class;
|
||||
}
|
||||
}
|
11
server/src/main/java/server/command/NonDefaultingParser.java
Normal file
11
server/src/main/java/server/command/NonDefaultingParser.java
Normal file
|
@ -0,0 +1,11 @@
|
|||
package server.command;
|
||||
|
||||
public abstract class NonDefaultingParser extends CompletingParser {
|
||||
public NonDefaultingParser(String name, Object ... completions) {
|
||||
super(name, completions);
|
||||
}
|
||||
|
||||
public Object getDefault(CommandEnvironment env) {
|
||||
return null;
|
||||
}
|
||||
}
|
53
server/src/main/java/server/command/Parameter.java
Normal file
53
server/src/main/java/server/command/Parameter.java
Normal file
|
@ -0,0 +1,53 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Parameter {
|
||||
private final String name;
|
||||
private final char shortName;
|
||||
private final boolean required;
|
||||
private final int position;
|
||||
private final List<ArgumentParser> parsers;
|
||||
private final ArgCombiner<?> combiner;
|
||||
|
||||
public Parameter(String name, char shortName, int position, boolean required, List<ArgumentParser> parsers, ArgCombiner<?> combiner) {
|
||||
this.name = name;
|
||||
this.shortName = shortName;
|
||||
this.position = position;
|
||||
this.required = required;
|
||||
this.parsers = parsers;
|
||||
this.combiner = combiner;
|
||||
}
|
||||
|
||||
public boolean isPositional() {
|
||||
return this.position >= 0;
|
||||
}
|
||||
|
||||
public int getPosition() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
public List<ArgumentParser> getParsers() {
|
||||
return this.parsers;
|
||||
}
|
||||
|
||||
public ArgCombiner<?> getCombiner() {
|
||||
return this.combiner;
|
||||
}
|
||||
|
||||
public boolean isRequired() {
|
||||
return this.required;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public boolean hasShortName() {
|
||||
return this.shortName != 0;
|
||||
}
|
||||
|
||||
public char getShortName() {
|
||||
return this.shortName;
|
||||
}
|
||||
}
|
49
server/src/main/java/server/command/PatternReplacer.java
Normal file
49
server/src/main/java/server/command/PatternReplacer.java
Normal file
|
@ -0,0 +1,49 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class PatternReplacer {
|
||||
private final String variable;
|
||||
private final boolean matchAll;
|
||||
private final Pattern pattern;
|
||||
private final Function<String, String> function;
|
||||
|
||||
public PatternReplacer(String variable, boolean matchAll, Function<String, String> function) {
|
||||
this.variable = variable;
|
||||
this.matchAll = matchAll;
|
||||
this.pattern = Pattern.compile("\\$\\((" + Pattern.quote(variable) + (matchAll ? "[^\\)]*" : "") + ")\\)");
|
||||
this.function = function;
|
||||
}
|
||||
|
||||
public void replaceVar(StringBuffer sb) {
|
||||
String str = sb.toString();
|
||||
sb.delete(0, sb.length());
|
||||
Matcher matcher = this.pattern.matcher(str);
|
||||
while(matcher.find()) {
|
||||
String orig = matcher.group(1);
|
||||
String rep = this.function.apply(orig);
|
||||
if(rep == null)
|
||||
throw new RunException("Variable '%s' konnte in diesem Kontext nicht ersetzt werden", orig);
|
||||
matcher.appendReplacement(sb, rep);
|
||||
}
|
||||
matcher.appendTail(sb);
|
||||
}
|
||||
|
||||
public String getVariable() {
|
||||
return this.variable;
|
||||
}
|
||||
|
||||
public boolean matchesAll() {
|
||||
return this.matchAll;
|
||||
}
|
||||
|
||||
public Pattern getPattern() {
|
||||
return this.pattern;
|
||||
}
|
||||
|
||||
public Function<String, String> getFunction() {
|
||||
return this.function;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.collect.Sets;
|
||||
import common.entity.Entity;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import server.network.Player;
|
||||
|
||||
public class PlayerEntityListParser extends PlayerEntityParser {
|
||||
public PlayerEntityListParser(String name, boolean useSender) {
|
||||
super(name, useSender);
|
||||
}
|
||||
|
||||
public Object parse(CommandEnvironment env, String input) {
|
||||
if(input.equals("*")) {
|
||||
List<Entity> list = Lists.newArrayList();
|
||||
for(Player plr : env.getServer().getPlayers()) {
|
||||
if(plr.getPresentEntity() != null)
|
||||
list.add(plr.getPresentEntity());
|
||||
}
|
||||
if(list.isEmpty())
|
||||
throw new RunException("Keine Spieler gefunden");
|
||||
return list;
|
||||
}
|
||||
Set<EntityNPC> set = Sets.newHashSet();
|
||||
for(String tok : input.split(",", -1)) {
|
||||
set.add((EntityNPC)super.parse(env, tok));
|
||||
}
|
||||
if(set.isEmpty())
|
||||
throw new RunException("Keine Spieler gefunden");
|
||||
return Lists.newArrayList(set);
|
||||
}
|
||||
|
||||
public Object getDefault(CommandEnvironment env) {
|
||||
EntityNPC entity = (EntityNPC)super.getDefault(env);
|
||||
return entity == null ? null : Lists.newArrayList(entity);
|
||||
}
|
||||
|
||||
public Collection<String> getCompletions(CommandEnvironment env) {
|
||||
Collection<String> comp = super.getCompletions(env);
|
||||
comp.add("*");
|
||||
return comp;
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return List.class;
|
||||
}
|
||||
}
|
27
server/src/main/java/server/command/PlayerEntityParser.java
Normal file
27
server/src/main/java/server/command/PlayerEntityParser.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
package server.command;
|
||||
|
||||
import common.entity.npc.EntityNPC;
|
||||
import server.network.Player;
|
||||
|
||||
public class PlayerEntityParser extends PlayerParser {
|
||||
public PlayerEntityParser(String name, boolean useSender) {
|
||||
super(name, useSender);
|
||||
}
|
||||
|
||||
public Object parse(CommandEnvironment env, String input) {
|
||||
Player net = (Player)super.parse(env, input);
|
||||
EntityNPC entity = net.getPresentEntity();
|
||||
if(entity == null)
|
||||
throw new RunException("Spieler-Objekt von '%s' wurde nicht gefunden", input);
|
||||
return entity;
|
||||
}
|
||||
|
||||
public Object getDefault(CommandEnvironment env) {
|
||||
Player net = (Player)super.getDefault(env);
|
||||
return net == null ? null : net.getPresentEntity();
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return EntityNPC.class;
|
||||
}
|
||||
}
|
45
server/src/main/java/server/command/PlayerListParser.java
Normal file
45
server/src/main/java/server/command/PlayerListParser.java
Normal file
|
@ -0,0 +1,45 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.collect.Sets;
|
||||
import server.network.Player;
|
||||
|
||||
public class PlayerListParser extends PlayerParser {
|
||||
public PlayerListParser(String name, boolean useSender) {
|
||||
super(name, useSender);
|
||||
}
|
||||
|
||||
public Object parse(CommandEnvironment env, String input) {
|
||||
if(input.equals("*")) {
|
||||
if(env.getServer().getPlayers().isEmpty())
|
||||
throw new RunException("Keine Spieler gefunden");
|
||||
return Lists.newArrayList(env.getServer().getPlayers());
|
||||
}
|
||||
Set<Player> set = Sets.newHashSet();
|
||||
for(String tok : input.split(",", -1)) {
|
||||
set.add((Player)super.parse(env, tok));
|
||||
}
|
||||
if(set.isEmpty())
|
||||
throw new RunException("Keine Spieler gefunden");
|
||||
return Lists.newArrayList(set);
|
||||
}
|
||||
|
||||
public Object getDefault(CommandEnvironment env) {
|
||||
Player net = (Player)super.getDefault(env);
|
||||
return net == null ? null : Lists.newArrayList(net);
|
||||
}
|
||||
|
||||
public Collection<String> getCompletions(CommandEnvironment env) {
|
||||
Collection<String> comp = super.getCompletions(env);
|
||||
comp.add("*");
|
||||
return comp;
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return List.class;
|
||||
}
|
||||
}
|
33
server/src/main/java/server/command/PlayerParser.java
Normal file
33
server/src/main/java/server/command/PlayerParser.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import server.network.Player;
|
||||
|
||||
public class PlayerParser extends CompletingParser {
|
||||
protected final boolean useSender;
|
||||
|
||||
public PlayerParser(String name, boolean useSender) {
|
||||
super(name);
|
||||
this.useSender = useSender;
|
||||
}
|
||||
|
||||
public Object parse(CommandEnvironment env, String input) {
|
||||
Player net = env.getServer().getPlayer(input);
|
||||
if(net == null)
|
||||
throw new RunException("Spieler '%s' wurde nicht gefunden", input);
|
||||
return net;
|
||||
}
|
||||
|
||||
public Object getDefault(CommandEnvironment env) {
|
||||
return this.useSender && env.getExecutor().isPlayer() ? (Player)env.getExecutor() : null;
|
||||
}
|
||||
|
||||
public Collection<String> getCompletions(CommandEnvironment env) {
|
||||
return env.getServer().getAllUsernames();
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return Player.class;
|
||||
}
|
||||
}
|
28
server/src/main/java/server/command/RunException.java
Normal file
28
server/src/main/java/server/command/RunException.java
Normal file
|
@ -0,0 +1,28 @@
|
|||
package server.command;
|
||||
|
||||
public class RunException extends RuntimeException {
|
||||
public RunException(String desc) {
|
||||
super(desc);
|
||||
this.setStackTrace(new StackTraceElement[0]);
|
||||
}
|
||||
|
||||
public RunException(String fmt, Object ... args) {
|
||||
super(String.format(fmt, args));
|
||||
this.setStackTrace(new StackTraceElement[0]);
|
||||
}
|
||||
|
||||
public RunException(Throwable cause, String desc) {
|
||||
super(desc, cause);
|
||||
this.setStackTrace(new StackTraceElement[0]);
|
||||
}
|
||||
|
||||
public RunException(Throwable cause, String fmt, Object ... args) {
|
||||
super(String.format(fmt, args), cause);
|
||||
this.setStackTrace(new StackTraceElement[0]);
|
||||
}
|
||||
|
||||
public synchronized Throwable fillInStackTrace() {
|
||||
this.setStackTrace(new StackTraceElement[0]);
|
||||
return this;
|
||||
}
|
||||
}
|
7
server/src/main/java/server/command/StringCompleter.java
Normal file
7
server/src/main/java/server/command/StringCompleter.java
Normal file
|
@ -0,0 +1,7 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface StringCompleter {
|
||||
Collection<String> complete(CommandEnvironment env);
|
||||
}
|
63
server/src/main/java/server/command/StringParser.java
Normal file
63
server/src/main/java/server/command/StringParser.java
Normal file
|
@ -0,0 +1,63 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import common.util.CharValidator;
|
||||
|
||||
public class StringParser extends DefaultingParser {
|
||||
private final boolean allowEmpty;
|
||||
private final Integer minLength;
|
||||
private final Integer maxLength;
|
||||
private final CharValidator validator;
|
||||
private final StringCompleter completer;
|
||||
|
||||
public StringParser(String name, String def, boolean allowEmpty, Integer minLength, Integer maxLength, CharValidator validator,
|
||||
Object ... completions) {
|
||||
super(name, def, completions);
|
||||
this.allowEmpty = allowEmpty;
|
||||
this.minLength = minLength;
|
||||
this.maxLength = maxLength;
|
||||
this.validator = validator;
|
||||
this.completer = null;
|
||||
}
|
||||
|
||||
public StringParser(String name, String def, boolean allowEmpty, Integer minLength, Integer maxLength, CharValidator validator,
|
||||
StringCompleter completer) {
|
||||
super(name, def);
|
||||
this.allowEmpty = allowEmpty;
|
||||
this.minLength = minLength;
|
||||
this.maxLength = maxLength;
|
||||
this.validator = validator;
|
||||
this.completer = completer;
|
||||
}
|
||||
|
||||
public String parse(CommandEnvironment env, String input) {
|
||||
if(!this.allowEmpty && input.isEmpty())
|
||||
throw new RunException("Die Zeichenkette darf nicht leer sein");
|
||||
if(this.minLength != null && input.length() < this.minLength)
|
||||
if(this.maxLength != null)
|
||||
throw new RunException("Die Zeichenkette muss zwischen %d .. %d Zeichen lang sein, habe %d ('%s')",
|
||||
this.minLength, this.maxLength, input.length(), input);
|
||||
else
|
||||
throw new RunException("Die Zeichenkette muss mindestens %d Zeichen lang sein, habe %d ('%s')",
|
||||
this.minLength, input.length(), input);
|
||||
if(this.maxLength != null && input.length() > this.maxLength)
|
||||
if(this.minLength != null)
|
||||
throw new RunException("Die Zeichenkette muss zwischen %d .. %d Zeichen lang sein, habe %d ('%s')",
|
||||
this.minLength, this.maxLength, input.length(), input);
|
||||
else
|
||||
throw new RunException("Die Zeichenkette darf höchstens %d Zeichen lang sein, habe %d ('%s')",
|
||||
this.maxLength, input.length(), input);
|
||||
if(this.validator != null && !this.validator.valid(input))
|
||||
throw new RunException("Die Zeichenkette '%s' enthält ungültige Zeichen", input);
|
||||
return input;
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
public Collection<String> getCompletions(CommandEnvironment env) {
|
||||
return this.completer != null ? this.completer.complete(env) : super.getCompletions(env);
|
||||
}
|
||||
}
|
26
server/src/main/java/server/command/TagParser.java
Normal file
26
server/src/main/java/server/command/TagParser.java
Normal file
|
@ -0,0 +1,26 @@
|
|||
package server.command;
|
||||
|
||||
import common.nbt.NBTException;
|
||||
import common.nbt.NBTParser;
|
||||
import common.nbt.NBTTagCompound;
|
||||
|
||||
public class TagParser extends DefaultingParser {
|
||||
public TagParser(String name, NBTTagCompound def, Object ... completions) {
|
||||
super(name, def, completions);
|
||||
}
|
||||
|
||||
public NBTTagCompound parse(CommandEnvironment env, String input) {
|
||||
NBTTagCompound value;
|
||||
try {
|
||||
value = NBTParser.parseTag(input);
|
||||
}
|
||||
catch(NBTException e) {
|
||||
throw new RunException(e, "Ungültiger NBT-Tag '%s'", input);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return NBTTagCompound.class;
|
||||
}
|
||||
}
|
5
server/src/main/java/server/command/Variable.java
Normal file
5
server/src/main/java/server/command/Variable.java
Normal file
|
@ -0,0 +1,5 @@
|
|||
package server.command;
|
||||
|
||||
public interface Variable {
|
||||
public String get();
|
||||
}
|
48
server/src/main/java/server/command/WorldParser.java
Normal file
48
server/src/main/java/server/command/WorldParser.java
Normal file
|
@ -0,0 +1,48 @@
|
|||
package server.command;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.dimension.Dimension;
|
||||
import server.world.WorldServer;
|
||||
|
||||
public class WorldParser extends DimensionParser {
|
||||
private final boolean loadedOnly;
|
||||
|
||||
public WorldParser(String name, boolean loadedOnly, boolean useSender) {
|
||||
super(name, useSender);
|
||||
this.loadedOnly = loadedOnly;
|
||||
}
|
||||
|
||||
public WorldServer parse(CommandEnvironment env, String input) {
|
||||
Dimension dim = (Dimension)super.parse(env, input);
|
||||
WorldServer world = this.loadedOnly ? env.getServer().getWorldNoLoad(dim.getDimensionId()) : env.getServer().getWorld(dim.getDimensionId());
|
||||
if(world == null)
|
||||
throw new RunException("Dimension '%s' ist nicht geladen", dim.getFormattedName(false));
|
||||
return world;
|
||||
}
|
||||
|
||||
public WorldServer getDefault(CommandEnvironment env) {
|
||||
Dimension dim = (Dimension)super.getDefault(env);
|
||||
return this.loadedOnly ? env.getServer().getWorldNoLoad(dim.getDimensionId()) : env.getServer().getWorld(dim.getDimensionId());
|
||||
// if(world == null)
|
||||
// throw new ScriptException("Dimension '%s' ist nicht geladen", dim.getFormattedName(false));
|
||||
// return world;
|
||||
}
|
||||
|
||||
public Collection<String> getCompletions(CommandEnvironment env) {
|
||||
if(this.loadedOnly) {
|
||||
List<String> loaded = Lists.newArrayList();
|
||||
for(WorldServer world : env.getServer().getWorlds()) {
|
||||
loaded.add(world.dimension.getDimensionName());
|
||||
}
|
||||
return loaded;
|
||||
}
|
||||
return super.getCompletions(env);
|
||||
}
|
||||
|
||||
public Class<?> getTypeClass(boolean required) {
|
||||
return WorldServer.class;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package server.command.commands;
|
||||
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
import server.command.RunException;
|
||||
import server.network.Player;
|
||||
|
||||
public class CommandAdmin extends Command {
|
||||
public CommandAdmin() {
|
||||
super("admin");
|
||||
|
||||
this.addPlayer("player", false);
|
||||
}
|
||||
|
||||
public void exec(CommandEnvironment env, Executor exec, Player player) {
|
||||
if(player == exec)
|
||||
throw new RunException("Du kannst nicht deinen eigenen Admin-Status erneut setzen");
|
||||
else if(player.getAdmin())
|
||||
throw new RunException("%s ist bereits ein Admin", player.getUser());
|
||||
player.setAdmin(true);
|
||||
player.logConsole("Du hast Administatorrechte von %s bekommen", exec.getExecId());
|
||||
exec.logConsole("%s ist jetzt ein Admin", player.getUser());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package server.command.commands;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.function.Function;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.util.Util;
|
||||
import server.command.ArgumentParser;
|
||||
import server.command.CachedExecutable;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
import server.command.Parameter;
|
||||
|
||||
public class CommandHelp extends Command {
|
||||
public CommandHelp(CommandEnvironment env) {
|
||||
super("help");
|
||||
|
||||
this.setParamsOptional();
|
||||
this.addEnum("command", CachedExecutable.class, env.getExecutables().values());
|
||||
}
|
||||
|
||||
public void exec(CommandEnvironment env, Executor exec, CachedExecutable command) {
|
||||
if(command == null) {
|
||||
for(CachedExecutable cmd : env.getExecutables().values()) {
|
||||
this.exec(env, exec, cmd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
List<String> list = Lists.newArrayList();
|
||||
for(Entry<String, Parameter> entry : command.getParameters().entrySet()) {
|
||||
Parameter param = entry.getValue();
|
||||
if(entry.getKey().length() == 1 && !param.isPositional() && param.hasShortName()) {
|
||||
list.add("-" + param.getShortName() + (param.getParsers().isEmpty() ? " (" + param.getName() + ")" : (param.getParsers().size() == 1 &&
|
||||
param.getParsers().get(0).getName().equals(param.getName()) ? " <" + param.getName() + ">" :
|
||||
" (" + param.getName() + ")" + Util.buildLines(" ", new Function<ArgumentParser, String>() {
|
||||
public String apply(ArgumentParser parser) {
|
||||
return "<" + parser.getName() + ">";
|
||||
}
|
||||
}, param.getParsers()))));
|
||||
}
|
||||
}
|
||||
for(Parameter param : command.getPositionals()) {
|
||||
list.add((param.isRequired() ? "<" : "[") + (param.getParsers().size() == 1 &&
|
||||
param.getParsers().get(0).getName().equals(param.getName()) ? param.getName() :
|
||||
"(" + param.getName() + ") " + Util.buildLines(" ", new Function<ArgumentParser, String>() {
|
||||
public String apply(ArgumentParser parser) {
|
||||
return "<" + parser.getName() + ">";
|
||||
}
|
||||
}, param.getParsers())) + (param.isRequired() ? ">" : "]"));
|
||||
}
|
||||
exec.logConsole("%s %s", command.getName(), Util.buildLines(" ", list));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package server.command.commands;
|
||||
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
import server.command.RunException;
|
||||
import server.network.Player;
|
||||
|
||||
public class CommandKick extends Command {
|
||||
public CommandKick() {
|
||||
super("kick");
|
||||
|
||||
this.addPlayer("player", false);
|
||||
this.setParamsOptional();
|
||||
this.addString("message", "Du wurdest vom Server geworfen", false);
|
||||
}
|
||||
|
||||
public void exec(CommandEnvironment env, Executor exec, Player player, String message) {
|
||||
if(player == exec)
|
||||
throw new RunException("Du kannst nicht dich nicht selbst vom Server werfen");
|
||||
else if(player.getAdmin())
|
||||
throw new RunException("%s ist ein Admin", player.getUser());
|
||||
player.disconnect(message);
|
||||
exec.logConsole("%s wurde vom Server geworfen", player.getUser());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package server.command.commands;
|
||||
|
||||
import common.packet.SPacketMessage;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
|
||||
public class CommandMessage extends Command {
|
||||
public CommandMessage() {
|
||||
super("message");
|
||||
|
||||
this.addString("message", false);
|
||||
|
||||
this.addEnum("type", 't', SPacketMessage.Type.CHAT, SPacketMessage.Type.class, SPacketMessage.Type.values());
|
||||
}
|
||||
|
||||
public void exec(CommandEnvironment env, Executor exec, String message, SPacketMessage.Type type) {
|
||||
env.getServer().sendPacket(new SPacketMessage(message, type));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package server.command.commands;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.potion.Potion;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
|
||||
public class CommandMilk extends Command {
|
||||
public CommandMilk() {
|
||||
super("milk");
|
||||
|
||||
this.addLivingEntityList("entities", true);
|
||||
this.setParamsOptional();
|
||||
List<Potion> potions = Lists.newArrayList();
|
||||
for(Potion potion : Potion.values()) {
|
||||
if(!potion.isInstant())
|
||||
potions.add(potion);
|
||||
}
|
||||
this.addEnum("type", Potion.class, potions);
|
||||
|
||||
this.addFlag("negative", 'n');
|
||||
}
|
||||
|
||||
public Object exec(CommandEnvironment env, Executor exec, List<EntityLiving> entities, Potion type, boolean negative) {
|
||||
int done = 0;
|
||||
for(EntityLiving entity : entities) {
|
||||
if(type != null && entity.hasEffect(type)) {
|
||||
entity.removeEffect(type);
|
||||
exec.logConsole("%s von %s entfernt", type.getDisplay(), entity.getCommandName());
|
||||
done++;
|
||||
}
|
||||
else if(type == null && !entity.getEffects().isEmpty()) {
|
||||
entity.clearEffects(negative);
|
||||
exec.logConsole("Alle Effekte von %s entfernt", entity.getCommandName());
|
||||
done++;
|
||||
}
|
||||
}
|
||||
if(done > 1)
|
||||
exec.logConsole(type == null ? "Alle Effekte von %d Objekten entfernt" : "%d Effekte entfernt", entities.size());
|
||||
return done;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package server.command.commands;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.entity.Entity;
|
||||
import common.init.UniverseRegistry;
|
||||
import common.util.Position;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
import server.command.RunException;
|
||||
import server.command.StringCompleter;
|
||||
import server.network.Player;
|
||||
|
||||
public class CommandOfflinetp extends Command {
|
||||
public CommandOfflinetp() {
|
||||
super("offlinetp");
|
||||
|
||||
this.addString("user", false, new StringCompleter() {
|
||||
public Collection<String> complete(CommandEnvironment env) {
|
||||
return Lists.newArrayList(env.getServer().getUsers());
|
||||
}
|
||||
});
|
||||
|
||||
this.addEntityList("entities", 'e', true);
|
||||
}
|
||||
|
||||
public Object exec(CommandEnvironment env, Executor exec, String user, List<Entity> entities) {
|
||||
Player player = env.getServer().getPlayer(user);
|
||||
Position pos = player != null ? (player.getPresentEntity() != null ? player.getPresentEntity().getPos() : null) : env.getServer().getOfflinePosition(user);
|
||||
if(pos == null)
|
||||
throw new RunException("Spieler '%s' konnte nicht gefunden werden", user);
|
||||
for(Entity entity : entities) {
|
||||
entity.teleport(pos);
|
||||
exec.logConsole("%s nach %d, %d, %d in %s teleportiert", entity.getCommandName(), (int)pos.x, (int)pos.y, (int)pos.z, UniverseRegistry.getDimension(pos.dim).getFormattedName(false));
|
||||
}
|
||||
return entities.size();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package server.command.commands;
|
||||
|
||||
import common.color.TextColor;
|
||||
import common.init.Config;
|
||||
import common.network.IPlayer;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
import server.command.RunException;
|
||||
import server.network.Player;
|
||||
import server.util.Form;
|
||||
|
||||
public class CommandPasswd extends Command {
|
||||
public CommandPasswd() {
|
||||
super("passwd");
|
||||
|
||||
this.addPlayer("player", true);
|
||||
this.setParamsOptional();
|
||||
this.addString("password", false);
|
||||
}
|
||||
|
||||
public void exec(CommandEnvironment env, Executor exec, Player player, String password) {
|
||||
if(exec.isPlayer()) {
|
||||
if(password != null)
|
||||
throw new RunException("Bei Verwendung als Spieler darf kein Passwort angegeben werden");
|
||||
if(player.getAdmin() && player != exec)
|
||||
throw new RunException("%s ist ein Admin", player.getUser());
|
||||
((Player)exec).displayForm(new Form() {
|
||||
private Field checkField;
|
||||
private Field passwordField;
|
||||
private Field confirmField;
|
||||
|
||||
protected void init() {
|
||||
this.checkField = player != exec ? null : this.addPassword("Aktuelles Passwort", 0, IPlayer.MAX_PASS_LENGTH, "");
|
||||
this.passwordField = this.addPassword("Neues Passwort", Config.minPassLength, IPlayer.MAX_PASS_LENGTH, "");
|
||||
this.confirmField = this.addPassword("Passwort bestätigen", Config.minPassLength, IPlayer.MAX_PASS_LENGTH, "");
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return "Passwort für " + player.getUser() + " ändern";
|
||||
}
|
||||
|
||||
protected void accept() {
|
||||
Player plr = env.getServer().getPlayer(player.getUser());
|
||||
if(!((Player)exec).isAdmin() || plr == null || (plr.isAdmin() && plr != exec)) {
|
||||
exec.logConsole(TextColor.DRED + "Ein Fehler ist aufgetreten");
|
||||
return;
|
||||
}
|
||||
if(this.checkField != null && !this.checkField.get().equals(plr.getPassword())) {
|
||||
exec.logConsole(TextColor.RED + "Falsches Passwort eingegeben");
|
||||
return;
|
||||
}
|
||||
if(!this.passwordField.get().equals(this.confirmField.get())) {
|
||||
exec.logConsole(TextColor.RED + "Passwörter stimmen nicht überein");
|
||||
return;
|
||||
}
|
||||
plr.setPassword(this.passwordField.get());
|
||||
exec.logConsole(TextColor.GREEN + "Passwort" + (plr != exec ? " für %s" : "") + " gesetzt", plr.getUser());
|
||||
}
|
||||
});
|
||||
}
|
||||
else if(exec.isConsole()) {
|
||||
if(password == null)
|
||||
throw new RunException("Bei Verwendung in der Konsole muss ein Passwort angegeben werden");
|
||||
player.setPassword(password);
|
||||
exec.logConsole(TextColor.GREEN + "Passwort für %s gesetzt", player.getUser());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package server.command.commands;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.color.TextColor;
|
||||
import common.entity.npc.EntityNPC;
|
||||
import common.util.ExtMath;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
import server.network.Player;
|
||||
|
||||
public class CommandPlayers extends Command {
|
||||
public CommandPlayers() {
|
||||
super("players");
|
||||
|
||||
this.addFlag("coords", 'c');
|
||||
}
|
||||
|
||||
public void exec(CommandEnvironment env, Executor exec, boolean coords) {
|
||||
List<Player> players = env.getServer().getPlayers();
|
||||
if(players.isEmpty()) {
|
||||
exec.logConsole(TextColor.DGRAY + "Es sind keine Spieler online");
|
||||
return;
|
||||
}
|
||||
exec.logConsole(TextColor.GREEN + "Es " + (players.size() == 1 ? "ist" : "sind") + " " + TextColor.YELLOW + "%d" + TextColor.GREEN + " Spieler online", players.size());
|
||||
for(Player player : players) {
|
||||
EntityNPC entity = player.getPresentEntity();
|
||||
exec.logConsole("%s%s" + TextColor.GRAY + ": '%s" + TextColor.GRAY + "'" + (coords ? " [" + TextColor.ORANGE + "%s @ %d, %d, %d" + TextColor.GRAY + "]" : ""), player.isAdmin() ? TextColor.RED : TextColor.NEON, player.getUser(), entity == null ? TextColor.DGRAY + "<->" : TextColor.ACID + entity.getCommandName(), entity == null ? null : entity.worldObj.dimension.getFormattedName(false), entity == null ? null : ExtMath.floord(entity.posX), entity == null ? null : ExtMath.floord(entity.posY), entity == null ? null : ExtMath.floord(entity.posZ));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package server.command.commands;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.potion.Potion;
|
||||
import common.potion.PotionEffect;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
|
||||
public class CommandPotion extends Command {
|
||||
public CommandPotion() {
|
||||
super("potion");
|
||||
|
||||
this.addLivingEntityList("entities", true);
|
||||
this.addEnum("type", Potion.class, Potion.values());
|
||||
this.setParamsOptional();
|
||||
this.addInt("duration", 0, 1000000, 1000000);
|
||||
this.addInt("strength", 1, 256, 1);
|
||||
|
||||
this.addFlag("particles", 'p');
|
||||
this.addFlag("ambient", 'a');
|
||||
this.addFlag("keep", 'k');
|
||||
}
|
||||
|
||||
public Object exec(CommandEnvironment env, Executor exec, List<EntityLiving> entities, Potion type, int duration, int strength, boolean particles, boolean ambient, boolean keep) {
|
||||
int done = 0;
|
||||
for(EntityLiving entity : entities) {
|
||||
if(entity.isPotionApplicable(type)) {
|
||||
if(type.isInstant()) {
|
||||
type.onImpact(null, null, entity, strength - 1, 1.0);
|
||||
}
|
||||
else {
|
||||
PotionEffect effect = new PotionEffect(type, duration == 0 ? Integer.MAX_VALUE : (duration * 20), strength - 1, ambient, particles);
|
||||
if(!keep && entity.hasEffect(type))
|
||||
entity.removeEffect(type);
|
||||
entity.addEffect(effect);
|
||||
}
|
||||
if(type.isInstant() || duration == 0)
|
||||
exec.logConsole("%d * %s an %s gegeben", strength, type.getDisplay(), entity.getCommandName());
|
||||
else
|
||||
exec.logConsole("%d * %s für %d Sekunden an %s gegeben", strength, type.getDisplay(), duration, entity.getCommandName());
|
||||
done++;
|
||||
}
|
||||
}
|
||||
if(done > 1)
|
||||
exec.logConsole("%d Effekte vergeben", done);
|
||||
return done;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package server.command.commands;
|
||||
|
||||
import common.color.TextColor;
|
||||
import common.init.Config;
|
||||
import common.nbt.NBTTagCompound;
|
||||
import common.network.IPlayer;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
import server.command.RunException;
|
||||
import server.network.Player;
|
||||
import server.util.Form;
|
||||
|
||||
public class CommandRegister extends Command {
|
||||
public CommandRegister() {
|
||||
super("register");
|
||||
|
||||
this.addString("username", false, null, IPlayer.MAX_USER_LENGTH, IPlayer.VALID_USER);
|
||||
this.setParamsOptional();
|
||||
this.addString("password", false);
|
||||
this.addFlag("admin", 'a');
|
||||
}
|
||||
|
||||
public void exec(CommandEnvironment env, Executor exec, String username, String password, boolean admin) {
|
||||
Player player = env.getServer().getPlayer(username);
|
||||
if(player != null)
|
||||
throw new RunException("Ein Spieler mit diesem Nutzernamen ist bereits online");
|
||||
NBTTagCompound tag = env.getServer().loadPlayerData(username);
|
||||
if(tag != null)
|
||||
throw new RunException("Ein Spieler mit diesem Nutzernamen ist bereits registriert");
|
||||
if(exec.isPlayer()) {
|
||||
if(password != null)
|
||||
throw new RunException("Bei Verwendung als Spieler darf kein Passwort angegeben werden");
|
||||
((Player)exec).displayForm(new Form() {
|
||||
private Field passwordField;
|
||||
private Field confirmField;
|
||||
|
||||
protected void init() {
|
||||
this.passwordField = this.addPassword("Passwort", Config.minPassLength, IPlayer.MAX_PASS_LENGTH, "");
|
||||
this.confirmField = this.addPassword("Passwort bestätigen", Config.minPassLength, IPlayer.MAX_PASS_LENGTH, "");
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return "Spieler " + username + " registrieren";
|
||||
}
|
||||
|
||||
protected void accept() {
|
||||
if(!((Player)exec).isAdmin() || env.getServer().getPlayer(username) != null || env.getServer().loadPlayerData(username) != null) {
|
||||
exec.logConsole(TextColor.DRED + "Ein Fehler ist aufgetreten");
|
||||
return;
|
||||
}
|
||||
if(!this.passwordField.get().equals(this.confirmField.get())) {
|
||||
exec.logConsole(TextColor.RED + "Passwörter stimmen nicht überein");
|
||||
return;
|
||||
}
|
||||
NBTTagCompound user = new NBTTagCompound();
|
||||
user.setString("password", this.passwordField.get());
|
||||
env.getServer().writePlayerData(username, user);
|
||||
exec.logConsole(TextColor.GREEN + "Spieler %s registriert", username);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if(exec.isConsole()) {
|
||||
if(password == null)
|
||||
throw new RunException("Bei Verwendung in der Konsole muss ein Passwort angegeben werden");
|
||||
NBTTagCompound user = new NBTTagCompound();
|
||||
user.setString("password", password);
|
||||
env.getServer().writePlayerData(username, user);
|
||||
exec.logConsole(TextColor.GREEN + "Spieler %s registriert", username);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package server.command.commands;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.entity.Entity;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
|
||||
public class CommandRemove extends Command {
|
||||
public CommandRemove() {
|
||||
super("remove");
|
||||
|
||||
this.addEntityList("entities", true);
|
||||
|
||||
this.addFlag("kill", 'k');
|
||||
}
|
||||
|
||||
public Object exec(CommandEnvironment env, Executor exec, List<Entity> entities, boolean kill) {
|
||||
int done = 0;
|
||||
for(Entity entity : entities) {
|
||||
if(entity.isEntityAlive()) {
|
||||
if(kill || entity.isPlayer())
|
||||
entity.kill();
|
||||
else
|
||||
entity.setDead();
|
||||
exec.logConsole(kill ? "%s getötet" : "%s entfernt", entity.getCommandName());
|
||||
done++;
|
||||
}
|
||||
}
|
||||
if(done > 1)
|
||||
exec.logConsole(kill ? "%d Objekte getötet" : "%d Objekte entfernt", done);
|
||||
return done;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package server.command.commands;
|
||||
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
import server.command.RunException;
|
||||
import server.network.Player;
|
||||
|
||||
public class CommandRevoke extends Command {
|
||||
public CommandRevoke() {
|
||||
super("revoke");
|
||||
|
||||
this.addPlayer("player", false);
|
||||
}
|
||||
|
||||
public void exec(CommandEnvironment env, Executor exec, Player player) {
|
||||
if(!exec.isConsole())
|
||||
throw new RunException("Dieser Befehl kann nur der Konsole ausgeführt werden");
|
||||
// else if(player == exec)
|
||||
// throw new RunException("Du kannst nicht deinen eigenen Admin-Status entfernen");
|
||||
else if(!player.getAdmin())
|
||||
throw new RunException("%s ist kein Admin", player.getUser());
|
||||
player.setAdmin(false);
|
||||
player.logConsole("Der Host hat deine Administatorrechte entfernt");
|
||||
exec.logConsole("%s ist jetzt kein Admin mehr", player.getUser());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package server.command.commands;
|
||||
|
||||
import common.color.TextColor;
|
||||
import common.packet.SPacketMessage;
|
||||
import common.packet.SPacketMessage.Type;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
import server.world.Region;
|
||||
|
||||
public class CommandSave extends Command {
|
||||
public CommandSave() {
|
||||
super("save");
|
||||
|
||||
this.addFlag("message", 'm');
|
||||
this.addFlag("flush", 'f');
|
||||
}
|
||||
|
||||
public void exec(CommandEnvironment env, Executor exec, boolean message, boolean flush) {
|
||||
if(message)
|
||||
env.getServer().sendPacket(new SPacketMessage(TextColor.RED + "Speichere Serverdaten, der Server könnte kurz einfrieren", Type.FEED));
|
||||
exec.logConsole(TextColor.ORANGE + "Speichere Spielerdaten ...");
|
||||
env.getServer().saveAllPlayerData(true);
|
||||
exec.logConsole(TextColor.ORANGE + "Speichere Weltdaten ...");
|
||||
env.getServer().saveAllWorlds(true);
|
||||
env.getServer().resetSaveTimer();
|
||||
if(flush) {
|
||||
exec.logConsole(TextColor.ORANGE + "Beende E/A ...");
|
||||
Region.finishWrite();
|
||||
}
|
||||
exec.logConsole(TextColor.DGREEN + "Alle Serverdaten wurden gespeichert");
|
||||
if(message)
|
||||
env.getServer().sendPacket(new SPacketMessage(TextColor.GREEN + "Die Serverdaten wurden gespeichert", Type.FEED));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package server.command.commands;
|
||||
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
|
||||
public class CommandShutdown extends Command {
|
||||
public CommandShutdown() {
|
||||
super("shutdown");
|
||||
|
||||
this.setParamsOptional();
|
||||
this.addString("message", "Server beendet", false);
|
||||
}
|
||||
|
||||
public void exec(CommandEnvironment env, Executor exec, String message) {
|
||||
env.getServer().shutdown(message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package server.command.commands;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.collect.Sets;
|
||||
import common.entity.Entity;
|
||||
import common.entity.types.EntityLiving;
|
||||
import common.init.EntityRegistry;
|
||||
import common.nbt.NBTTagCompound;
|
||||
import common.util.Util;
|
||||
import common.util.Vec3;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
import server.command.RunException;
|
||||
import server.network.Player;
|
||||
import server.world.WorldServer;
|
||||
|
||||
public class CommandSpawn extends Command {
|
||||
public CommandSpawn() {
|
||||
super("spawn");
|
||||
|
||||
Set<String> names = Sets.newTreeSet();
|
||||
for(Class<? extends Entity> clazz : EntityRegistry.getAllClasses()) {
|
||||
names.add(EntityRegistry.getEntityString(clazz));
|
||||
}
|
||||
names.add("Lightning");
|
||||
this.addEnum("type", String.class, names);
|
||||
this.setParamsOptional();
|
||||
this.addVector("position", true, true);
|
||||
this.addWorld("dim", true);
|
||||
this.addTag("tag");
|
||||
|
||||
this.addFlag("noinit", 'n');
|
||||
this.addInt("count", 'c', 1, 1024, 1);
|
||||
this.addTag("postTag", 'p');
|
||||
}
|
||||
|
||||
public Object exec(CommandEnvironment env, Executor exec, String type, Vec3 pos, WorldServer world, NBTTagCompound tag, boolean noinit, int count, NBTTagCompound postTag) {
|
||||
if(type.equalsIgnoreCase("Lightning")) {
|
||||
for(int z = 0; z < count; z++) {
|
||||
int color = 0xffffff;
|
||||
if(tag != null && tag.hasKey("color", 3))
|
||||
color = tag.getInteger("color");
|
||||
else if(tag != null && tag.hasKey("color", 8)) {
|
||||
try {
|
||||
color = Integer.parseUnsignedInt(tag.getString("color"), 16);
|
||||
}
|
||||
catch(NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
world.strikeLightning(pos.xCoord, pos.yCoord, pos.zCoord, color,
|
||||
tag != null && tag.hasKey("damage", 3) ? tag.getInteger("damage") : 0, tag != null && tag.hasKey("fire", 1) && tag.getBoolean("fire"),
|
||||
exec.isPlayer() && tag != null && tag.hasKey("summoned", 1) && tag.getBoolean("summoned") ? ((Player)exec).getPresentEntity() : null);
|
||||
}
|
||||
exec.logConsole("%sBlitz bei %d, %d, %d in %s erschaffen", count == 1 ? "" : (count + "x "), (int)pos.xCoord, (int)pos.yCoord, (int)pos.zCoord, world.dimension.getFormattedName(false));
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
List<String> spawned = Lists.newArrayList();
|
||||
for(int z = 0; z < count; z++) {
|
||||
Entity entity = EntityRegistry.createEntityByName(type, world);
|
||||
if(entity == null)
|
||||
throw new RunException("Objekt konnte nicht erzeugt werden");
|
||||
entity.setLocationAndAngles(pos.xCoord, pos.yCoord, pos.zCoord, world.rand.floatv() * 360.0f, 0.0f);
|
||||
if(tag != null) {
|
||||
NBTTagCompound ent = new NBTTagCompound();
|
||||
entity.writeToNBT(ent);
|
||||
ent.merge(tag);
|
||||
entity.readFromNBT(ent);
|
||||
}
|
||||
if(!noinit && (entity instanceof EntityLiving))
|
||||
((EntityLiving)entity).onInitialSpawn(null);
|
||||
world.spawnEntityInWorld(entity);
|
||||
if(postTag != null) {
|
||||
NBTTagCompound ent = new NBTTagCompound();
|
||||
entity.writeToNBT(ent);
|
||||
ent.merge(postTag);
|
||||
entity.readFromNBT(ent);
|
||||
}
|
||||
spawned.add("#" + entity.getId());
|
||||
}
|
||||
exec.logConsole("%s%s bei %d, %d, %d in %s erschaffen", count == 1 ? "" : (count + "x "), EntityRegistry.getEntityName(type), (int)pos.xCoord, (int)pos.yCoord, (int)pos.zCoord, world.dimension.getFormattedName(false));
|
||||
return Util.buildLines(",", spawned);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package server.command.commands;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.dimension.Dimension;
|
||||
import common.entity.Entity;
|
||||
import common.util.Vec3;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
|
||||
public class CommandTele extends Command {
|
||||
public CommandTele() {
|
||||
super("tele");
|
||||
|
||||
this.addVector("position", false, true);
|
||||
this.setParamsOptional();
|
||||
this.addDimension("dim", true);
|
||||
this.addDouble("yaw", -180.0, 180.0);
|
||||
this.addDouble("pitch", -89.0, 89.0);
|
||||
|
||||
this.addEntityList("entities", 'e', true);
|
||||
}
|
||||
|
||||
public Object exec(CommandEnvironment env, Executor exec, Vec3 position, Dimension dim, Double yaw, Double pitch, List<Entity> entities) {
|
||||
for(Entity entity : entities) {
|
||||
entity.teleport(position.xCoord, position.yCoord, position.zCoord, yaw == null ? entity.rotYaw : yaw.floatValue(), pitch == null ? entity.rotPitch : pitch.floatValue(), dim.getDimensionId());
|
||||
exec.logConsole("%s nach %d, %d, %d in %s teleportiert", entity.getCommandName(), (int)position.xCoord, (int)position.yCoord, (int)position.zCoord, dim.getFormattedName(false));
|
||||
}
|
||||
return entities.size();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package server.command.commands;
|
||||
|
||||
import common.dimension.Dimension;
|
||||
import common.item.ItemSpaceNavigator;
|
||||
import common.util.Position;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
import server.command.RunException;
|
||||
import server.world.WorldServer;
|
||||
|
||||
public class CommandTime extends Command {
|
||||
public CommandTime() {
|
||||
super("time");
|
||||
|
||||
this.addString("time", false, "day", "night", "noon", "midnight", "sunrise", "sunset");
|
||||
|
||||
this.addFlag("absolute", 'a');
|
||||
}
|
||||
|
||||
private long parseInt(String input, long max) {
|
||||
long num;
|
||||
try {
|
||||
num = Long.parseLong(input);
|
||||
}
|
||||
catch(NumberFormatException e) {
|
||||
throw new RunException("'%s' ist keine gültige Zahl", input);
|
||||
}
|
||||
if(num < 0)
|
||||
throw new RunException("Die Zeit muss mindestens 0 betragen", num);
|
||||
else if(num > max)
|
||||
throw new RunException("Die Zeit darf höchstens %d betragen", num, max);
|
||||
return num;
|
||||
}
|
||||
|
||||
private long parseDayTime(Dimension dim, String arg) {
|
||||
if(arg.equalsIgnoreCase("sunrise"))
|
||||
return dim.getRotationalPeriod() / 6L;
|
||||
else if(arg.equalsIgnoreCase("day"))
|
||||
return dim.getRotationalPeriod() * 5L / 24L;
|
||||
else if(arg.equalsIgnoreCase("noon"))
|
||||
return dim.getRotationalPeriod() / 2L;
|
||||
else if(arg.equalsIgnoreCase("sunset"))
|
||||
return dim.getRotationalPeriod() * 5L / 6L;
|
||||
else if(arg.equalsIgnoreCase("night"))
|
||||
return dim.getRotationalPeriod() * 21L / 24L;
|
||||
else if(arg.equalsIgnoreCase("midnight"))
|
||||
return 0L;
|
||||
else if(arg.startsWith("@"))
|
||||
return this.parseInt(arg.substring(1), dim.getRotationalPeriod() - 1);
|
||||
else
|
||||
return -1L;
|
||||
}
|
||||
|
||||
private long parseTime(Dimension dim, String arg) {
|
||||
long t;
|
||||
if(arg.toLowerCase().endsWith("y"))
|
||||
t = dim.getOrbitalPeriod();
|
||||
else if(arg.toLowerCase().endsWith("d"))
|
||||
t = dim.getRotationalPeriod();
|
||||
else if(arg.toLowerCase().endsWith("h"))
|
||||
t = 1000L;
|
||||
else
|
||||
t = -1L;
|
||||
arg = t == -1L ? arg : arg.substring(0, arg.length() - 1);
|
||||
t = t < 1L ? 1L : t;
|
||||
return t * this.parseInt(arg, Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
public Object exec(CommandEnvironment env, Executor exec, String timeStr, boolean absolute) {
|
||||
Position pos = exec.getExecPos();
|
||||
WorldServer world = pos == null ? env.getServer().getSpace() : env.getServer().getWorld(pos.dim);
|
||||
long time = absolute ? 0L : world.getDayTime();
|
||||
long fwd = parseDayTime(world.dimension, timeStr);
|
||||
if(fwd >= 0L) {
|
||||
if(absolute) {
|
||||
time += fwd;
|
||||
}
|
||||
else {
|
||||
time -= world.getDayTime() % world.dimension.getRotationalPeriod();
|
||||
time += fwd;
|
||||
time += time <= world.getDayTime() ? world.dimension.getRotationalPeriod() : 0L;
|
||||
}
|
||||
}
|
||||
else {
|
||||
time += parseTime(world.dimension, timeStr);
|
||||
}
|
||||
for(WorldServer dim : env.getServer().getWorlds()) {
|
||||
dim.setDayTime(time);
|
||||
dim.resetWeather();
|
||||
}
|
||||
exec.logConsole("Zeit auf %s gesetzt", ItemSpaceNavigator.formatImperialTime(world, false));
|
||||
return time;
|
||||
}
|
||||
}
|
29
server/src/main/java/server/command/commands/CommandTp.java
Normal file
29
server/src/main/java/server/command/commands/CommandTp.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
package server.command.commands;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.entity.Entity;
|
||||
import common.init.UniverseRegistry;
|
||||
import common.util.Position;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
|
||||
public class CommandTp extends Command {
|
||||
public CommandTp() {
|
||||
super("tp");
|
||||
|
||||
this.addEntity("target", false);
|
||||
|
||||
this.addEntityList("entities", 'e', true);
|
||||
}
|
||||
|
||||
public Object exec(CommandEnvironment env, Executor exec, Entity target, List<Entity> entities) {
|
||||
Position pos = target.getPos();
|
||||
for(Entity entity : entities) {
|
||||
entity.teleport(pos);
|
||||
exec.logConsole("%s nach %d, %d, %d in %s teleportiert", entity.getCommandName(), (int)pos.x, (int)pos.y, (int)pos.z, UniverseRegistry.getDimension(pos.dim).getFormattedName(false));
|
||||
}
|
||||
return entities.size();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package server.command.commands;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import common.entity.Entity;
|
||||
import common.init.UniverseRegistry;
|
||||
import common.util.Position;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
import server.command.RunException;
|
||||
import server.command.StringCompleter;
|
||||
|
||||
public class CommandWarp extends Command {
|
||||
public CommandWarp() {
|
||||
super("warp");
|
||||
|
||||
this.addString("warp", true, new StringCompleter() {
|
||||
public Collection<String> complete(CommandEnvironment env) {
|
||||
// List<String> warps = Lists.newArrayList("spawn");
|
||||
// warps.addAll(env.getServer().getWarps().keySet());
|
||||
return env.getServer().getWarps().keySet();
|
||||
}
|
||||
});
|
||||
|
||||
this.addEntityList("entities", 'e', true);
|
||||
}
|
||||
|
||||
public Object exec(CommandEnvironment env, Executor exec, String warp, List<Entity> entities) {
|
||||
Position // pos;
|
||||
// if(warp.equals("spawn")) {
|
||||
// WorldServer world = env.getServer().getWorld(Config.spawnDim);
|
||||
// world = world == null ? env.getServer().getSpace() : world;
|
||||
// int y = Config.spawnY;
|
||||
// while(world.getState(new BlockPos(Config.spawnX, y, Config.spawnZ)).getBlock().getMaterial().blocksMovement() && y < 511)
|
||||
// y++;
|
||||
// pos = new Position(Config.spawnX + 0.5d, (double)y, Config.spawnZ + 0.5d,
|
||||
// Config.spawnYaw, Config.spawnPitch, world.dimension.getDimensionId());
|
||||
// }
|
||||
// else {
|
||||
pos = env.getServer().getWarps().get(warp);
|
||||
if(pos == null)
|
||||
throw new RunException("Warp '%s' existiert nicht", warp);
|
||||
else if(env.getServer().getWorld(pos.dim) == null)
|
||||
throw new RunException("Warp '%s' hat kein Level (%s)", warp, pos.dim);
|
||||
// }
|
||||
for(Entity entity : entities) {
|
||||
entity.teleport(pos);
|
||||
exec.logConsole("%s nach %d, %d, %d in %s teleportiert", entity.getCommandName(), (int)pos.x, (int)pos.y, (int)pos.z, UniverseRegistry.getDimension(pos.dim).getFormattedName(false));
|
||||
}
|
||||
return entities.size();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package server.command.commands;
|
||||
|
||||
import common.world.Weather;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
import server.command.RunException;
|
||||
import server.world.WorldServer;
|
||||
|
||||
public class CommandWeather extends Command {
|
||||
public CommandWeather() {
|
||||
super("weather");
|
||||
|
||||
this.addEnum("weather", Weather.class, Weather.values());
|
||||
this.setParamsOptional();
|
||||
this.addWorld("dim", true);
|
||||
|
||||
this.addFlag("transition", 't');
|
||||
}
|
||||
|
||||
public void exec(CommandEnvironment env, Executor exec, Weather weather, WorldServer world, boolean transition) {
|
||||
if(!world.dimension.getType().weather)
|
||||
throw new RunException("Welt %s hat kein Wetter", world.dimension.getFormattedName(false));
|
||||
else if(world.isExterminated())
|
||||
throw new RunException("Welt %s ist zerstört", world.dimension.getFormattedName(false));
|
||||
world.setWeather(weather);
|
||||
if(!transition)
|
||||
world.resetWeather();
|
||||
exec.logConsole("Wetter in %s zu %s geändert", world.dimension.getFormattedName(false), weather.getDisplay());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package server.command.commands;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.entity.Entity;
|
||||
import common.util.BlockPos;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
import server.world.WorldServer;
|
||||
|
||||
public class CommandWorld extends Command {
|
||||
public CommandWorld() {
|
||||
super("world");
|
||||
|
||||
this.addWorld("dim", true);
|
||||
|
||||
this.addEntityList("entities", 'e', true);
|
||||
}
|
||||
|
||||
public Object exec(CommandEnvironment env, Executor exec, WorldServer world, List<Entity> entities) {
|
||||
for(Entity entity : entities) {
|
||||
BlockPos pos = entity.getPosition();
|
||||
pos = pos.getY() < 0 ? new BlockPos(pos.getX(), 0, pos.getZ()) : pos;
|
||||
if(world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) {
|
||||
while((world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) && pos.getY() < 511)
|
||||
pos = pos.up();
|
||||
}
|
||||
else {
|
||||
while(!(world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) && pos.getY() > 0)
|
||||
pos = pos.down();
|
||||
pos = pos.up();
|
||||
}
|
||||
entity.teleport(pos, world.dimension.getDimensionId());
|
||||
exec.logConsole("%s nach %d, %d, %d in %s teleportiert", entity.getCommandName(), pos.getX(), pos.getY(), pos.getZ(), world.dimension.getFormattedName(false));
|
||||
}
|
||||
return entities.size();
|
||||
}
|
||||
}
|
51
server/src/main/java/server/network/HandshakeHandler.java
Executable file
51
server/src/main/java/server/network/HandshakeHandler.java
Executable file
|
@ -0,0 +1,51 @@
|
|||
package server.network;
|
||||
|
||||
import common.network.IHandshakeHandler;
|
||||
import common.network.NetConnection;
|
||||
import common.network.NetHandler;
|
||||
import common.network.PacketRegistry;
|
||||
import common.packet.HPacketHandshake;
|
||||
import common.packet.RPacketDisconnect;
|
||||
import common.util.Util;
|
||||
import server.Server;
|
||||
|
||||
public class HandshakeHandler extends NetHandler implements IHandshakeHandler
|
||||
{
|
||||
private final Server server;
|
||||
private final NetConnection networkManager;
|
||||
|
||||
public HandshakeHandler(Server serverIn, NetConnection netManager)
|
||||
{
|
||||
this.server = serverIn;
|
||||
this.networkManager = netManager;
|
||||
}
|
||||
|
||||
public void onDisconnect(String reason)
|
||||
{
|
||||
}
|
||||
|
||||
public void processHandshake(HPacketHandshake packetIn)
|
||||
{
|
||||
if(packetIn.getProtocolVersion() == 0) {
|
||||
this.networkManager.closeChannel("Inkompatibel!");
|
||||
return;
|
||||
}
|
||||
this.networkManager.setConnectionState(PacketRegistry.LOGIN);
|
||||
if (packetIn.getProtocolVersion() != Util.PROTOCOL)
|
||||
{
|
||||
String comp;
|
||||
if(packetIn.getProtocolVersion() < Util.PROTOCOL)
|
||||
comp = "Der Server nutzt eine neuere Version: " + Util.VERSION;
|
||||
else
|
||||
comp = "Der Server nutzt eine ältere Version: " + Util.VERSION;
|
||||
this.networkManager.sendPacket(new RPacketDisconnect(comp));
|
||||
this.networkManager.closeChannel(comp);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoginHandler handler = new LoginHandler(this.server, this.networkManager);
|
||||
this.networkManager.setNetHandler(handler);
|
||||
handler.sendLoginPacket();
|
||||
}
|
||||
}
|
||||
}
|
142
server/src/main/java/server/network/LoginHandler.java
Executable file
142
server/src/main/java/server/network/LoginHandler.java
Executable file
|
@ -0,0 +1,142 @@
|
|||
package server.network;
|
||||
|
||||
import java.security.PrivateKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import common.color.TextColor;
|
||||
import common.init.Config;
|
||||
import common.log.Log;
|
||||
import common.network.ILoginHandler;
|
||||
import common.network.IPlayer;
|
||||
import common.network.NetConnection;
|
||||
import common.network.NetHandler;
|
||||
import common.packet.LPacketPasswordResponse;
|
||||
import common.packet.LPacketStartEncrypt;
|
||||
import common.packet.RPacketDisconnect;
|
||||
import common.packet.RPacketRequestEncrypt;
|
||||
import server.Server;
|
||||
|
||||
public class LoginHandler extends NetHandler implements ILoginHandler
|
||||
{
|
||||
private static enum LoginState {
|
||||
INIT, ENCRYPT, PASSWORD, AUTHENTICATED, ACCEPTED;
|
||||
}
|
||||
|
||||
private static final SecureRandom TOKEN_RNG = new SecureRandom();
|
||||
|
||||
private final Server server;
|
||||
public final NetConnection netManager;
|
||||
|
||||
private LoginState state = LoginState.INIT;
|
||||
private int timer;
|
||||
private String loginUser;
|
||||
private String loginPass;
|
||||
private byte[] loginToken;
|
||||
|
||||
public LoginHandler(Server server, NetConnection netManager)
|
||||
{
|
||||
this.netManager = netManager;
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
public void closeConnection(String reason)
|
||||
{
|
||||
try
|
||||
{
|
||||
Log.NETWORK.info("Trenne " + this.getConnectionInfo());
|
||||
this.netManager.sendPacket(new RPacketDisconnect(reason));
|
||||
this.netManager.closeChannel(reason);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.NETWORK.error(exception, "Fehler beim Trennen des Spielers beim Login");
|
||||
}
|
||||
}
|
||||
|
||||
public void onDisconnect(String reason)
|
||||
{
|
||||
Log.NETWORK.info(this.getConnectionInfo() + " wurde beim Login getrennt: " + TextColor.stripCodes(reason));
|
||||
}
|
||||
|
||||
public String getConnectionInfo()
|
||||
{
|
||||
return this.loginUser != null ? (this.loginUser + " (" + this.netManager.getCutAddress()
|
||||
+ ")") : this.netManager.getCutAddress();
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
if(this.state == LoginState.AUTHENTICATED)
|
||||
this.tryAcceptPlayer();
|
||||
// else if (this.currentLoginState == LoginState.DELAY_ACCEPT)
|
||||
// {
|
||||
// if (this.server.getPlayer(this.loginUser) == null)
|
||||
// {
|
||||
// this.currentLoginState = LoginState.ACCEPTED;
|
||||
// this.server.addPlayer(this.networkManager, this.loginUser);
|
||||
// }
|
||||
// }
|
||||
if(this.timer++ == 600)
|
||||
this.closeConnection("Anmeldung dauerte zu lange");
|
||||
}
|
||||
|
||||
private void tryAcceptPlayer()
|
||||
{
|
||||
if(this.server.getPlayer(this.loginUser) != null) {
|
||||
this.closeConnection("Nutzername '" + this.loginUser + "' ist bereits vergeben.");
|
||||
return;
|
||||
}
|
||||
// if (this.server.getPlayer(this.loginUser) != null)
|
||||
// {
|
||||
// this.closeConnection("Nutzername '" + this.loginUser + "' ist bereits vergeben.");
|
||||
// return;
|
||||
//// this.currentLoginState = LoginState.DELAY_ACCEPT;
|
||||
//// player.netHandler.kick("Du hast dich von einen anderen Ort verbunden");
|
||||
// }
|
||||
// this.networkManager.sendPacket(new RPacketLoginSuccess());
|
||||
String kick = this.server.addPlayer(this.netManager, this.loginUser, this.loginPass);
|
||||
if(kick != null)
|
||||
this.closeConnection(kick);
|
||||
else
|
||||
this.state = LoginState.ACCEPTED;
|
||||
}
|
||||
|
||||
public void sendLoginPacket() {
|
||||
if(this.state != LoginState.INIT)
|
||||
throw new IllegalStateException("Unerwartetes Handshake-Paket");
|
||||
this.state = LoginState.ENCRYPT;
|
||||
this.loginToken = new byte[4];
|
||||
TOKEN_RNG.nextBytes(this.loginToken);
|
||||
this.netManager.sendPacket(new RPacketRequestEncrypt(this.server.getPublicKey(), this.loginToken));
|
||||
}
|
||||
|
||||
public void processEncryption(LPacketStartEncrypt packet) {
|
||||
if(this.state != LoginState.ENCRYPT)
|
||||
throw new IllegalStateException("Unerwartetes Verschlüsselungs-Paket");
|
||||
PrivateKey pkey = this.server.getPrivateKey();
|
||||
if(!Arrays.equals(this.loginToken, packet.getToken(pkey)))
|
||||
throw new IllegalStateException("Fehlerhaftes Token");
|
||||
SecretKey key = packet.getKey(pkey);
|
||||
this.netManager.startEncryption(key);
|
||||
this.state = LoginState.PASSWORD;
|
||||
}
|
||||
|
||||
public void processPasswordResponse(LPacketPasswordResponse packetIn) {
|
||||
if(this.state != LoginState.PASSWORD)
|
||||
throw new IllegalStateException("Unerwartetes Passwort-Paket");
|
||||
this.loginUser = packetIn.getUser();
|
||||
this.loginPass = packetIn.getPassword();
|
||||
if(this.loginUser.isEmpty() || !IPlayer.isValidUser(this.loginUser))
|
||||
throw new IllegalStateException("Ungültiger Nutzername!");
|
||||
// if(!this.checkConnect(packetIn.getAccess()))
|
||||
// return;
|
||||
if(!Config.password.isEmpty() && !Config.password.equals(packetIn.getAccess())) {
|
||||
this.closeConnection("Falsches Zugangspasswort");
|
||||
return;
|
||||
}
|
||||
this.state = LoginState.AUTHENTICATED;
|
||||
}
|
||||
}
|
3241
server/src/main/java/server/network/Player.java
Executable file
3241
server/src/main/java/server/network/Player.java
Executable file
File diff suppressed because it is too large
Load diff
185
server/src/main/java/server/util/Form.java
Normal file
185
server/src/main/java/server/util/Form.java
Normal file
|
@ -0,0 +1,185 @@
|
|||
package server.util;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import common.collect.Lists;
|
||||
import common.util.Displayable;
|
||||
import common.util.Triplet;
|
||||
|
||||
public abstract class Form {
|
||||
private abstract class FormElement {
|
||||
protected final String name;
|
||||
|
||||
protected FormElement(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
protected abstract Object getInputData();
|
||||
protected abstract int getInputParameter();
|
||||
protected abstract boolean acceptValue(Object obj);
|
||||
}
|
||||
|
||||
protected class Toggle extends FormElement {
|
||||
private boolean value;
|
||||
|
||||
protected Toggle(String name, boolean value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
protected Object getInputData() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
protected int getInputParameter() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected boolean acceptValue(Object obj) {
|
||||
if(obj instanceof Boolean)
|
||||
this.value = (Boolean)obj;
|
||||
return obj instanceof Boolean;
|
||||
}
|
||||
|
||||
public boolean get() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
protected class Switch<T> extends FormElement {
|
||||
private final T[] values;
|
||||
private final int def;
|
||||
|
||||
private T value;
|
||||
|
||||
protected Switch(String name, T[] values, T value) {
|
||||
super(name);
|
||||
this.values = values;
|
||||
this.value = value;
|
||||
int def = 0;
|
||||
for(int z = 0; z < values.length; z++) {
|
||||
if(values[z] == value) {
|
||||
def = z;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.def = def;
|
||||
}
|
||||
|
||||
protected Object getInputData() {
|
||||
String[] strs = new String[this.values.length];
|
||||
for(int z = 0; z < strs.length; z++) {
|
||||
strs[z] = this.values[z] instanceof Displayable ? ((Displayable)this.values[z]).getDisplay() : String.valueOf(this.values[z]);
|
||||
}
|
||||
return strs;
|
||||
}
|
||||
|
||||
protected int getInputParameter() {
|
||||
return this.def;
|
||||
}
|
||||
|
||||
protected boolean acceptValue(Object obj) {
|
||||
if(obj instanceof Integer && (Integer)obj >= 0 && (Integer)obj < this.values.length) {
|
||||
this.value = this.values[(Integer)obj];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public T get() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
protected class Field extends FormElement {
|
||||
private final int minLength;
|
||||
private final int maxLength;
|
||||
private final boolean password;
|
||||
|
||||
private String value;
|
||||
|
||||
protected Field(String name, String value, int min, int max, boolean password) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
this.minLength = min;
|
||||
this.maxLength = max;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
protected Object getInputData() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
protected int getInputParameter() {
|
||||
return (this.password ? 0x80000000 : 0) | (this.minLength << 16) | this.maxLength;
|
||||
}
|
||||
|
||||
protected boolean acceptValue(Object obj) {
|
||||
if(obj instanceof String && ((String)obj).length() >= this.minLength && ((String)obj).length() <= this.maxLength) {
|
||||
this.value = (String)obj;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String get() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
private final List<FormElement> inputs = Lists.newArrayList();
|
||||
|
||||
public Form() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
private <T extends FormElement> T add(T elem) {
|
||||
this.inputs.add(elem);
|
||||
return elem;
|
||||
}
|
||||
|
||||
protected Toggle addToggle(String name, boolean def) {
|
||||
return this.add(new Toggle(name, def));
|
||||
}
|
||||
|
||||
protected <T> Switch<T> addSwitch(String name, T def, T ... values) {
|
||||
return this.add(new Switch<T>(name, values, def));
|
||||
}
|
||||
|
||||
protected Field addField(String name, int minLength, int maxLength, String def) {
|
||||
return this.add(new Field(name, def, minLength, maxLength, false));
|
||||
}
|
||||
|
||||
protected Field addPassword(String name, int minLength, int maxLength, String def) {
|
||||
return this.add(new Field(name, def, minLength, maxLength, true));
|
||||
}
|
||||
|
||||
public abstract String getTitle();
|
||||
protected abstract void init();
|
||||
protected abstract void accept();
|
||||
|
||||
protected void cancel() {
|
||||
}
|
||||
|
||||
public final Triplet<String, Object, Integer>[] getInputList() {
|
||||
Triplet<String, Object, Integer>[] data = new Triplet[this.inputs.size()];
|
||||
for(int z = 0; z < data.length; z++) {
|
||||
data[z] = new Triplet<String, Object, Integer>(this.inputs.get(z).name, this.inputs.get(z).getInputData(), this.inputs.get(z).getInputParameter());
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public final void accept(Object[] data) {
|
||||
if(data == null || data.length != this.inputs.size()) {
|
||||
this.cancel();
|
||||
return;
|
||||
}
|
||||
for(int z = 0; z < data.length; z++) {
|
||||
if(!this.inputs.get(z).acceptValue(data[z])) {
|
||||
this.cancel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.accept();
|
||||
}
|
||||
}
|
273
server/src/main/java/server/village/VillageCollection.java
Executable file
273
server/src/main/java/server/village/VillageCollection.java
Executable file
|
@ -0,0 +1,273 @@
|
|||
package server.village;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import common.block.Block;
|
||||
import common.block.Material;
|
||||
import common.block.artificial.BlockDoor;
|
||||
import common.collect.Lists;
|
||||
import common.nbt.NBTTagCompound;
|
||||
import common.nbt.NBTTagList;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Facing;
|
||||
import common.village.Village;
|
||||
import common.village.VillageDoorInfo;
|
||||
import server.world.WorldServer;
|
||||
|
||||
public class VillageCollection
|
||||
{
|
||||
private final List<BlockPos> villagerPositionsList = Lists.<BlockPos>newArrayList();
|
||||
private final List<VillageDoorInfo> newDoors = Lists.<VillageDoorInfo>newArrayList();
|
||||
private final List<Village> villageList = Lists.<Village>newArrayList();
|
||||
private int tickCounter;
|
||||
private boolean dirty;
|
||||
|
||||
public VillageCollection(NBTTagCompound nbt) {
|
||||
if(nbt != null) {
|
||||
this.tickCounter = nbt.getInteger("Tick");
|
||||
NBTTagList nbttaglist = nbt.getTagList("Villages", 10);
|
||||
|
||||
for (int i = 0; i < nbttaglist.tagCount(); ++i)
|
||||
{
|
||||
NBTTagCompound nbttagcompound = nbttaglist.getCompoundTagAt(i);
|
||||
Village village = new Village();
|
||||
village.readVillageDataFromNBT(nbttagcompound);
|
||||
this.villageList.add(village);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addToVillagerPositionList(BlockPos pos)
|
||||
{
|
||||
if (this.villagerPositionsList.size() <= 64)
|
||||
{
|
||||
if (!this.positionInList(pos))
|
||||
{
|
||||
this.villagerPositionsList.add(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void tick(WorldServer world)
|
||||
{
|
||||
++this.tickCounter;
|
||||
|
||||
for (Village village : this.villageList)
|
||||
{
|
||||
village.tick(world, this.tickCounter);
|
||||
}
|
||||
|
||||
this.removeAnnihilatedVillages();
|
||||
this.dropOldestVillagerPosition(world);
|
||||
this.addNewDoorsToVillageOrCreateVillage();
|
||||
|
||||
if (this.tickCounter % 400 == 0)
|
||||
{
|
||||
this.dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void removeAnnihilatedVillages()
|
||||
{
|
||||
Iterator<Village> iterator = this.villageList.iterator();
|
||||
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
Village village = (Village)iterator.next();
|
||||
|
||||
if (village.isAnnihilated())
|
||||
{
|
||||
iterator.remove();
|
||||
this.dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<Village> getVillageList()
|
||||
{
|
||||
return this.villageList;
|
||||
}
|
||||
|
||||
public Village getNearestVillage(BlockPos doorBlock, int radius)
|
||||
{
|
||||
Village village = null;
|
||||
double d0 = 3.4028234663852886E38D;
|
||||
|
||||
for (Village village1 : this.villageList)
|
||||
{
|
||||
double d1 = village1.getCenter().distanceSq(doorBlock);
|
||||
|
||||
if (d1 < d0)
|
||||
{
|
||||
float f = (float)(radius + village1.getRadius());
|
||||
|
||||
if (d1 <= (double)(f * f))
|
||||
{
|
||||
village = village1;
|
||||
d0 = d1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return village;
|
||||
}
|
||||
|
||||
private void dropOldestVillagerPosition(WorldServer world)
|
||||
{
|
||||
if (!this.villagerPositionsList.isEmpty())
|
||||
{
|
||||
this.addDoorsAround(world, this.villagerPositionsList.remove(0));
|
||||
}
|
||||
}
|
||||
|
||||
private void addNewDoorsToVillageOrCreateVillage()
|
||||
{
|
||||
for (int i = 0; i < this.newDoors.size(); ++i)
|
||||
{
|
||||
VillageDoorInfo villagedoorinfo = (VillageDoorInfo)this.newDoors.get(i);
|
||||
Village village = this.getNearestVillage(villagedoorinfo.getDoorBlockPos(), 32);
|
||||
|
||||
if (village == null)
|
||||
{
|
||||
village = new Village();
|
||||
this.villageList.add(village);
|
||||
this.dirty = true;
|
||||
}
|
||||
|
||||
village.addDoor(villagedoorinfo);
|
||||
}
|
||||
|
||||
this.newDoors.clear();
|
||||
}
|
||||
|
||||
private void addDoorsAround(WorldServer world, BlockPos central)
|
||||
{
|
||||
int i = 16;
|
||||
int j = 4;
|
||||
int k = 16;
|
||||
|
||||
for (int l = -i; l < i; ++l)
|
||||
{
|
||||
for (int i1 = -j; i1 < j; ++i1)
|
||||
{
|
||||
for (int j1 = -k; j1 < k; ++j1)
|
||||
{
|
||||
BlockPos blockpos = central.add(l, i1, j1);
|
||||
|
||||
if (this.isWoodDoor(world, blockpos))
|
||||
{
|
||||
VillageDoorInfo villagedoorinfo = this.checkDoorExistence(blockpos);
|
||||
|
||||
if (villagedoorinfo == null)
|
||||
{
|
||||
this.addToNewDoorsList(world, blockpos);
|
||||
}
|
||||
else
|
||||
{
|
||||
villagedoorinfo.func_179849_a(this.tickCounter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private VillageDoorInfo checkDoorExistence(BlockPos doorBlock)
|
||||
{
|
||||
for (VillageDoorInfo villagedoorinfo : this.newDoors)
|
||||
{
|
||||
if (villagedoorinfo.getDoorBlockPos().getX() == doorBlock.getX() && villagedoorinfo.getDoorBlockPos().getZ() == doorBlock.getZ() && Math.abs(villagedoorinfo.getDoorBlockPos().getY() - doorBlock.getY()) <= 1)
|
||||
{
|
||||
return villagedoorinfo;
|
||||
}
|
||||
}
|
||||
|
||||
for (Village village : this.villageList)
|
||||
{
|
||||
VillageDoorInfo villagedoorinfo1 = village.getExistedDoor(doorBlock);
|
||||
|
||||
if (villagedoorinfo1 != null)
|
||||
{
|
||||
return villagedoorinfo1;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void addToNewDoorsList(WorldServer world, BlockPos doorBlock)
|
||||
{
|
||||
Facing enumfacing = BlockDoor.getFacing(world, doorBlock);
|
||||
Facing enumfacing1 = enumfacing.getOpposite();
|
||||
int i = this.countBlocksCanSeeSky(world, doorBlock, enumfacing, 5);
|
||||
int j = this.countBlocksCanSeeSky(world, doorBlock, enumfacing1, i + 1);
|
||||
|
||||
if (i != j)
|
||||
{
|
||||
this.newDoors.add(new VillageDoorInfo(doorBlock, i < j ? enumfacing : enumfacing1, this.tickCounter));
|
||||
}
|
||||
}
|
||||
|
||||
private int countBlocksCanSeeSky(WorldServer world, BlockPos centerPos, Facing direction, int limitation)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (int j = 1; j <= 5; ++j)
|
||||
{
|
||||
if (world.canSeeSky(centerPos.offset(direction, j)))
|
||||
{
|
||||
++i;
|
||||
|
||||
if (i >= limitation)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
private boolean positionInList(BlockPos pos)
|
||||
{
|
||||
for (BlockPos blockpos : this.villagerPositionsList)
|
||||
{
|
||||
if (blockpos.equals(pos))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isWoodDoor(WorldServer world, BlockPos doorPos)
|
||||
{
|
||||
Block block = world.getState(doorPos).getBlock();
|
||||
return block instanceof BlockDoor ? block.getMaterial() == Material.WOOD : false;
|
||||
}
|
||||
|
||||
public NBTTagCompound writeToNBT()
|
||||
{
|
||||
NBTTagCompound nbt = new NBTTagCompound();
|
||||
nbt.setInteger("Tick", this.tickCounter);
|
||||
NBTTagList nbttaglist = new NBTTagList();
|
||||
|
||||
for (Village village : this.villageList)
|
||||
{
|
||||
NBTTagCompound nbttagcompound = new NBTTagCompound();
|
||||
village.writeVillageDataToNBT(nbttagcompound);
|
||||
nbttaglist.appendTag(nbttagcompound);
|
||||
}
|
||||
|
||||
nbt.setTag("Villages", nbttaglist);
|
||||
this.dirty = false;
|
||||
return nbt;
|
||||
}
|
||||
|
||||
public boolean isDirty()
|
||||
{
|
||||
return this.dirty;
|
||||
}
|
||||
}
|
63
server/src/main/java/server/world/BlockEventData.java
Executable file
63
server/src/main/java/server/world/BlockEventData.java
Executable file
|
@ -0,0 +1,63 @@
|
|||
package server.world;
|
||||
|
||||
import common.block.Block;
|
||||
import common.util.BlockPos;
|
||||
|
||||
public class BlockEventData
|
||||
{
|
||||
private BlockPos position;
|
||||
private Block blockType;
|
||||
|
||||
/** Different for each blockID */
|
||||
private int eventID;
|
||||
private int eventParameter;
|
||||
|
||||
public BlockEventData(BlockPos pos, Block blockType, int eventId, int p_i45756_4_)
|
||||
{
|
||||
this.position = pos;
|
||||
this.eventID = eventId;
|
||||
this.eventParameter = p_i45756_4_;
|
||||
this.blockType = blockType;
|
||||
}
|
||||
|
||||
public BlockPos getPosition()
|
||||
{
|
||||
return this.position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Event ID (different for each BlockID)
|
||||
*/
|
||||
public int getEventID()
|
||||
{
|
||||
return this.eventID;
|
||||
}
|
||||
|
||||
public int getEventParameter()
|
||||
{
|
||||
return this.eventParameter;
|
||||
}
|
||||
|
||||
public Block getBlock()
|
||||
{
|
||||
return this.blockType;
|
||||
}
|
||||
|
||||
public boolean equals(Object p_equals_1_)
|
||||
{
|
||||
if (!(p_equals_1_ instanceof BlockEventData))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockEventData blockeventdata = (BlockEventData)p_equals_1_;
|
||||
return this.position.equals(blockeventdata.position) && this.eventID == blockeventdata.eventID && this.eventParameter == blockeventdata.eventParameter && this.blockType == blockeventdata.blockType;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "TE(" + this.position + ")," + this.eventID + "," + this.eventParameter + "," + this.blockType;
|
||||
}
|
||||
}
|
226
server/src/main/java/server/world/ChunkServer.java
Normal file
226
server/src/main/java/server/world/ChunkServer.java
Normal file
|
@ -0,0 +1,226 @@
|
|||
package server.world;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import common.biome.Biome;
|
||||
import common.block.Block;
|
||||
import common.entity.Entity;
|
||||
import common.init.BlockRegistry;
|
||||
import common.init.Blocks;
|
||||
import common.log.Log;
|
||||
import common.rng.Random;
|
||||
import common.tileentity.TileEntity;
|
||||
import common.util.BlockPos;
|
||||
import common.world.BlockArray;
|
||||
import common.world.Chunk;
|
||||
import common.world.State;
|
||||
import common.world.World;
|
||||
import server.worldgen.BiomeGenerator;
|
||||
|
||||
public class ChunkServer extends Chunk {
|
||||
private long lastSave;
|
||||
private long inhabited;
|
||||
|
||||
public ChunkServer(World world, int x, int z) {
|
||||
super(world, x, z);
|
||||
}
|
||||
|
||||
public ChunkServer(World world, short[] data, int height, boolean base, boolean ceil, Random rand, Biome[] biomes, int x, int z) {
|
||||
this(world, x, z);
|
||||
boolean sky = !world.dimension.hasNoLight();
|
||||
for(int bx = 0; bx < 16; ++bx) {
|
||||
for(int bz = 0; bz < 16; ++bz) {
|
||||
for(int by = 0; by < height; ++by) {
|
||||
State state = BlockRegistry.STATEMAP.getByValue(data[bx << 4 | bz | by << 8]);
|
||||
if(state != null && state.getBlock() != Blocks.air) {
|
||||
int y = by >> 4;
|
||||
BlockArray arr = this.getArray(y);
|
||||
if(arr == null) {
|
||||
arr = new BlockArray(y << 4, sky, null);
|
||||
this.setArray(arr);
|
||||
}
|
||||
arr.set(bx, by & 15, bz, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(base) {
|
||||
Block caves = world.dimension.getCaveFiller().getBlock();
|
||||
BlockArray arr = this.getArray(0);
|
||||
if(arr == null) {
|
||||
arr = new BlockArray(0, sky, null);
|
||||
this.setArray(arr);
|
||||
}
|
||||
for(int bx = 0; bx < 16; ++bx) {
|
||||
for(int bz = 0; bz < 16; ++bz) {
|
||||
for(int by = 0; by < 5; ++by) {
|
||||
if(by <= rand.zrange(5)) {
|
||||
Block block = arr.get(bx, by, bz).getBlock();
|
||||
if(block == Blocks.air || block.getMaterial().isLiquid() || block == caves)
|
||||
arr.set(bx, by, bz, this.filler);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(ceil) {
|
||||
int y = (height - 1) >> 4;
|
||||
BlockArray arr = this.getArray(y);
|
||||
if(arr == null) {
|
||||
arr = new BlockArray(y << 4, sky, null);
|
||||
this.setArray(arr);
|
||||
}
|
||||
y = (height - 5) >> 4;
|
||||
arr = this.getArray(y);
|
||||
if(arr == null) {
|
||||
arr = new BlockArray(y << 4, sky, null);
|
||||
this.setArray(arr);
|
||||
}
|
||||
for(int bx = 0; bx < 16; ++bx) {
|
||||
for(int bz = 0; bz < 16; ++bz) {
|
||||
for(int by = height - 1; by >= height - 5; --by) {
|
||||
if(by >= (height - 1) - rand.zrange(5))
|
||||
this.getArray(by >> 4).set(bx, by & 15, bz, Blocks.air.getState());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for(int n = 0; n < this.biomes.length; ++n) {
|
||||
this.biomes[n] = (byte)biomes[n].id;
|
||||
}
|
||||
if(ceil)
|
||||
this.resetRelight();
|
||||
else
|
||||
this.genSkyLight();
|
||||
}
|
||||
|
||||
public int getTopSegment() {
|
||||
return this.top;
|
||||
}
|
||||
|
||||
public int getBottomSegment() {
|
||||
return this.bottom;
|
||||
}
|
||||
|
||||
public Set<BlockArray> getStorage() {
|
||||
return this.blockList;
|
||||
}
|
||||
|
||||
public void addTileEntity(TileEntity tile) {
|
||||
this.addTileEntity(tile.getPos(), tile);
|
||||
|
||||
if(this.loaded) {
|
||||
this.world.addTileEntity(tile);
|
||||
}
|
||||
}
|
||||
|
||||
public void onChunkLoad() {
|
||||
this.loaded = true;
|
||||
this.world.addTileEntities(this.tiles.values());
|
||||
|
||||
for(int n = 0; n < this.entities.length; ++n) {
|
||||
for(Entity entity : this.entities[n]) {
|
||||
entity.onChunkLoad();
|
||||
}
|
||||
|
||||
this.world.loadEntities(this.entities[n]);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDirty(long time) {
|
||||
if(this.hasEntity && time != this.lastSave || this.modified) {
|
||||
return true;
|
||||
}
|
||||
return this.modified;
|
||||
}
|
||||
|
||||
public void setStorage(BlockArray[] data) {
|
||||
for(BlockArray arr : data) {
|
||||
this.setArray(arr);
|
||||
}
|
||||
}
|
||||
|
||||
public Biome getBiome(BlockPos pos, BiomeGenerator gen) {
|
||||
int x = pos.getX() & 15;
|
||||
int z = pos.getZ() & 15;
|
||||
int o = this.biomes[z << 4 | x] & 255;
|
||||
|
||||
if(o == 255) {
|
||||
Biome biome = gen == null ? Biome.DEF_BIOME : gen.getBiomeGenerator(pos, Biome.DEF_BIOME);
|
||||
o = biome.id;
|
||||
this.biomes[z << 4 | x] = (byte)(o & 255);
|
||||
}
|
||||
|
||||
return Biome.getBiomeDef(o);
|
||||
}
|
||||
|
||||
public byte[] getBiomes() {
|
||||
return this.biomes;
|
||||
}
|
||||
|
||||
public void setBiomes(byte[] biomes) {
|
||||
if(this.biomes.length != biomes.length) {
|
||||
Log.IO.warn("Konnte Biome des Chunks nicht setzen, Länge des Arrays ist " + biomes.length + " statt " + this.biomes.length);
|
||||
}
|
||||
else {
|
||||
for(int n = 0; n < this.biomes.length; ++n) {
|
||||
this.biomes[n] = biomes[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getHeights() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public void setHeights(int[] map) {
|
||||
if(this.height.length != map.length) {
|
||||
Log.IO.warn("Konnte Höhen des Chunks nicht setzen, Länge des Arrays ist " + map.length + " statt " + this.height.length);
|
||||
}
|
||||
else {
|
||||
for(int n = 0; n < this.height.length; ++n) {
|
||||
this.height[n] = map[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<BlockPos, TileEntity> getTiles() {
|
||||
return this.tiles;
|
||||
}
|
||||
|
||||
public boolean isTerrainPopulated() {
|
||||
return this.populated;
|
||||
}
|
||||
|
||||
public void setTerrainPopulated(boolean populated) {
|
||||
this.populated = populated;
|
||||
}
|
||||
|
||||
public boolean isLightPopulated() {
|
||||
return this.lightInit;
|
||||
}
|
||||
|
||||
public void setLightPopulated(boolean populated) {
|
||||
this.lightInit = populated;
|
||||
}
|
||||
|
||||
public void setModified(boolean modified) {
|
||||
this.modified = modified;
|
||||
}
|
||||
|
||||
public void setHasEntities(boolean entities) {
|
||||
this.hasEntity = entities;
|
||||
}
|
||||
|
||||
public void setSaved(long time) {
|
||||
this.lastSave = time;
|
||||
}
|
||||
|
||||
public long getInhabited() {
|
||||
return this.inhabited;
|
||||
}
|
||||
|
||||
public void setInhabited(long time) {
|
||||
this.inhabited = time;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue