That's one heck of a commit you've got there...
I may have got a bit behind with version control. A lot behind, in fact. Maybe I'll go back and split this sometime - then again, I probably won't. But hey, at least it's here!
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
package electroblob.wizardry.worldgen;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.entity.living.EntityEvilWizard;
|
||||
import electroblob.wizardry.entity.living.EntityWizard;
|
||||
import electroblob.wizardry.integration.antiqueatlas.WizardryAntiqueAtlasIntegration;
|
||||
import electroblob.wizardry.util.WizardryUtilities;
|
||||
import net.minecraft.block.BlockPlanks;
|
||||
import net.minecraft.block.BlockStainedHardenedClay;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Biomes;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.EnumDyeColor;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.structure.template.ITemplateProcessor;
|
||||
import net.minecraft.world.gen.structure.template.PlacementSettings;
|
||||
import net.minecraft.world.gen.structure.template.Template;
|
||||
import net.minecraftforge.common.BiomeDictionary;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
public class WorldGenWizardTower extends WorldGenSurfaceStructure {
|
||||
|
||||
// TODO: Add wizard towers to the /locate command
|
||||
// This requires some careful manipulation of Random objects to replicate the positions exactly for the current
|
||||
// world. See the end of ChunkGeneratorOverworld for the relevant methods.
|
||||
|
||||
private static final String WIZARD_DATA_BLOCK_TAG = "wizard";
|
||||
private static final String EVIL_WIZARD_DATA_BLOCK_TAG = "evil_wizard";
|
||||
|
||||
private final Map<BiomeDictionary.Type, IBlockState> SPECIAL_WALL_BLOCKS;
|
||||
|
||||
public WorldGenWizardTower(){
|
||||
// These are initialised here because it's a convenient point after the blocks are registered
|
||||
SPECIAL_WALL_BLOCKS = ImmutableMap.of(
|
||||
BiomeDictionary.Type.MESA, Blocks.RED_SANDSTONE.getDefaultState(),
|
||||
BiomeDictionary.Type.MOUNTAIN, Blocks.STONEBRICK.getDefaultState(),
|
||||
BiomeDictionary.Type.NETHER, Blocks.NETHER_BRICK.getDefaultState(),
|
||||
BiomeDictionary.Type.SANDY, Blocks.SANDSTONE.getDefaultState()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStructureName(){
|
||||
return "wizard_tower";
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRandomSeedModifier(){
|
||||
return 10473957L; // Yep, I literally typed 8 digits at random
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canGenerate(Random random, World world, int chunkX, int chunkZ){
|
||||
return ArrayUtils.contains(Wizardry.settings.towerDimensions, world.provider.getDimension())
|
||||
&& Wizardry.settings.towerRarity > 0 && random.nextInt(Wizardry.settings.towerRarity) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getStructureFile(Random random){
|
||||
return random.nextDouble() < Wizardry.settings.evilWizardChance ?
|
||||
Wizardry.settings.towerWithChestFiles[random.nextInt(Wizardry.settings.towerWithChestFiles.length)] :
|
||||
Wizardry.settings.towerFiles[random.nextInt(Wizardry.settings.towerFiles.length)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawnStructure(Random random, World world, BlockPos origin, Template template, PlacementSettings settings, ResourceLocation structureFile){
|
||||
|
||||
final EnumDyeColor colour = EnumDyeColor.values()[random.nextInt(EnumDyeColor.values().length)];
|
||||
final Biome biome = world.getBiome(origin);
|
||||
|
||||
final IBlockState wallMaterial = SPECIAL_WALL_BLOCKS.keySet().stream().filter(t -> BiomeDictionary.hasType(biome, t))
|
||||
.findFirst().map(SPECIAL_WALL_BLOCKS::get).orElse(Blocks.COBBLESTONE.getDefaultState());
|
||||
|
||||
final float mossiness = getBiomeMossiness(biome);
|
||||
final BlockPlanks.EnumType woodType = getBiomeWoodVariant(biome);
|
||||
|
||||
final Set<BlockPos> blocksPlaced = new HashSet<>();
|
||||
|
||||
ITemplateProcessor processor = new MultiTemplateProcessor(true,
|
||||
// Roof colour
|
||||
(w, p, i) -> i.blockState.getBlock() instanceof BlockStainedHardenedClay ? new Template.BlockInfo(
|
||||
i.pos, i.blockState.withProperty(BlockStainedHardenedClay.COLOR, colour), i.tileentityData) : i,
|
||||
// Wall material
|
||||
(w, p, i) -> i.blockState.getBlock() == Blocks.COBBLESTONE ? new Template.BlockInfo(i.pos,
|
||||
wallMaterial, i.tileentityData) : i,
|
||||
// Wood type
|
||||
new WoodTypeTemplateProcessor(woodType),
|
||||
// Mossifier
|
||||
new MossifierTemplateProcessor(mossiness, 0.04f, origin.getY() + 1),
|
||||
// Block recording (the process() method doesn't get called for structure voids)
|
||||
(w, p, i) -> {if(i.blockState.getBlock() != Blocks.AIR) blocksPlaced.add(p); return i;}
|
||||
);
|
||||
|
||||
template.addBlocksToWorld(world, origin, processor, settings, 2);
|
||||
|
||||
WizardryAntiqueAtlasIntegration.markTower(world, origin.getX(), origin.getZ());
|
||||
|
||||
// Wizard spawning
|
||||
Map<BlockPos, String> dataBlocks = template.getDataBlocks(origin, settings);
|
||||
|
||||
for(Map.Entry<BlockPos, String> entry : dataBlocks.entrySet()){
|
||||
|
||||
Vec3d vec = WizardryUtilities.getCentre(entry.getKey());
|
||||
|
||||
if(entry.getValue().equals(WIZARD_DATA_BLOCK_TAG)){
|
||||
|
||||
EntityWizard wizard = new EntityWizard(world);
|
||||
wizard.setLocationAndAngles(vec.x, vec.y, vec.z, 0, 0);
|
||||
wizard.onInitialSpawn(world.getDifficultyForLocation(origin), null);
|
||||
wizard.setTowerBlocks(blocksPlaced);
|
||||
world.spawnEntity(wizard);
|
||||
|
||||
}else if(entry.getValue().equals(EVIL_WIZARD_DATA_BLOCK_TAG)){
|
||||
|
||||
EntityEvilWizard wizard = new EntityEvilWizard(world);
|
||||
wizard.setLocationAndAngles(vec.x, vec.y, vec.z, 0, 0);
|
||||
wizard.hasStructure = true; // Stops it despawning
|
||||
wizard.onInitialSpawn(world.getDifficultyForLocation(origin), null);
|
||||
world.spawnEntity(wizard);
|
||||
|
||||
}else{
|
||||
// This probably shouldn't happen...
|
||||
Wizardry.logger.info("Unrecognised data block value {} in structure {}", entry.getValue(), structureFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static float getBiomeMossiness(Biome biome){
|
||||
if(BiomeDictionary.hasType(biome, BiomeDictionary.Type.DENSE)) return 0.7f;
|
||||
if(BiomeDictionary.hasType(biome, BiomeDictionary.Type.JUNGLE)) return 0.7f;
|
||||
if(BiomeDictionary.hasType(biome, BiomeDictionary.Type.WET)) return 0.5f;
|
||||
if(BiomeDictionary.hasType(biome, BiomeDictionary.Type.SWAMP)) return 0.5f;
|
||||
if(BiomeDictionary.hasType(biome, BiomeDictionary.Type.FOREST)) return 0.3f;
|
||||
if(BiomeDictionary.hasType(biome, BiomeDictionary.Type.LUSH)) return 0.3f;
|
||||
if(BiomeDictionary.hasType(biome, BiomeDictionary.Type.DRY)) return 0;
|
||||
if(BiomeDictionary.hasType(biome, BiomeDictionary.Type.COLD)) return 0;
|
||||
if(BiomeDictionary.hasType(biome, BiomeDictionary.Type.DEAD)) return 0;
|
||||
if(BiomeDictionary.hasType(biome, BiomeDictionary.Type.WASTELAND)) return 0;
|
||||
if(BiomeDictionary.hasType(biome, BiomeDictionary.Type.NETHER)) return 0;
|
||||
return 0.1f; // Everything else (plains, etc.) has a small amount of moss
|
||||
}
|
||||
|
||||
private static BlockPlanks.EnumType getBiomeWoodVariant(Biome biome){
|
||||
// Unfortunately, I can't check all the wood types with the biome dictionary
|
||||
if(BiomeDictionary.hasType(biome, BiomeDictionary.Type.CONIFEROUS)) return BlockPlanks.EnumType.SPRUCE;
|
||||
if(biome == Biomes.BIRCH_FOREST || biome == Biomes.BIRCH_FOREST_HILLS) return BlockPlanks.EnumType.BIRCH;
|
||||
if(BiomeDictionary.hasType(biome, BiomeDictionary.Type.JUNGLE)) return BlockPlanks.EnumType.JUNGLE;
|
||||
if(BiomeDictionary.hasType(biome, BiomeDictionary.Type.SAVANNA)) return BlockPlanks.EnumType.ACACIA;
|
||||
// Not technically a tree type, but I think it fits quite well anyway
|
||||
if(BiomeDictionary.hasType(biome, BiomeDictionary.Type.SPOOKY)) return BlockPlanks.EnumType.DARK_OAK;
|
||||
// Everything else is oak
|
||||
return BlockPlanks.EnumType.OAK;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user