2e3df272ec
- Offset structures by minus half their width in x/z (as well as the usual +8), so they can't ever spill out of the 2x2 chunk area being generated (provided they are less than 16 blocks wide, which mine are) - Pass the block placement flags 16 | 2 to Template#addBlocksToWorld instead of just 2, to prevent neighbour updates - Ignore unloaded blocks when removing floating trees (in theory there can't be trees there anyway)
107 lines
3.8 KiB
Java
107 lines
3.8 KiB
Java
package electroblob.wizardry.worldgen;
|
|
|
|
import electroblob.wizardry.Wizardry;
|
|
import electroblob.wizardry.block.BlockRunestone;
|
|
import electroblob.wizardry.constants.Element;
|
|
import electroblob.wizardry.entity.living.EntityRemnant;
|
|
import electroblob.wizardry.integration.antiqueatlas.WizardryAntiqueAtlasIntegration;
|
|
import net.minecraft.init.Blocks;
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
import net.minecraft.tileentity.MobSpawnerBaseLogic;
|
|
import net.minecraft.tileentity.TileEntityMobSpawner;
|
|
import net.minecraft.util.Mirror;
|
|
import net.minecraft.util.ResourceLocation;
|
|
import net.minecraft.util.WeightedSpawnerEntity;
|
|
import net.minecraft.util.math.BlockPos;
|
|
import net.minecraft.world.World;
|
|
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 org.apache.commons.lang3.ArrayUtils;
|
|
|
|
import java.util.Map;
|
|
import java.util.Random;
|
|
|
|
public class WorldGenObelisk extends WorldGenSurfaceStructure {
|
|
|
|
private static final String SPAWNER_DATA_BLOCK_TAG = "spawner";
|
|
|
|
private static final ResourceLocation REMNANT_ID = new ResourceLocation(Wizardry.MODID, "remnant");
|
|
|
|
@Override
|
|
public String getStructureName(){
|
|
return "obelisk";
|
|
}
|
|
|
|
@Override
|
|
public long getRandomSeedModifier(){
|
|
return 19348242L;
|
|
}
|
|
|
|
@Override
|
|
public Mirror[] getValidMirrors(){
|
|
return new Mirror[]{Mirror.NONE}; // It's symmetrical so there's no point mirroring it
|
|
}
|
|
|
|
@Override
|
|
public boolean canGenerate(Random random, World world, int chunkX, int chunkZ){
|
|
return ArrayUtils.contains(Wizardry.settings.obeliskDimensions, world.provider.getDimension())
|
|
&& Wizardry.settings.obeliskRarity > 0 && random.nextInt(Wizardry.settings.obeliskRarity) == 0;
|
|
}
|
|
|
|
@Override
|
|
public ResourceLocation getStructureFile(Random random){
|
|
return Wizardry.settings.obeliskFiles[random.nextInt(Wizardry.settings.obeliskFiles.length)];
|
|
}
|
|
|
|
@Override
|
|
public void spawnStructure(Random random, World world, BlockPos origin, Template template, PlacementSettings settings, ResourceLocation structureFile){
|
|
|
|
final Element element = Element.values()[1 + random.nextInt(Element.values().length-1)];
|
|
|
|
ITemplateProcessor processor = (w, p, i) -> i.blockState.getBlock() instanceof BlockRunestone ? new Template.BlockInfo(
|
|
i.pos, i.blockState.withProperty(BlockRunestone.ELEMENT, element), i.tileentityData) : i;
|
|
|
|
template.addBlocksToWorld(world, origin, processor, settings, 2 | 16);
|
|
|
|
WizardryAntiqueAtlasIntegration.markObelisk(world, origin.getX(), origin.getZ());
|
|
|
|
// Mob spawner
|
|
Map<BlockPos, String> dataBlocks = template.getDataBlocks(origin, settings);
|
|
|
|
for(Map.Entry<BlockPos, String> entry : dataBlocks.entrySet()){
|
|
|
|
if(entry.getValue().equals(SPAWNER_DATA_BLOCK_TAG)){
|
|
|
|
BlockPos pos = entry.getKey();
|
|
|
|
world.setBlockState(pos, Blocks.MOB_SPAWNER.getDefaultState());
|
|
|
|
if(world.getTileEntity(pos) instanceof TileEntityMobSpawner){
|
|
|
|
MobSpawnerBaseLogic spawnerLogic = ((TileEntityMobSpawner)world.getTileEntity(pos)).getSpawnerBaseLogic();
|
|
|
|
EntityRemnant remant = new EntityRemnant(world);
|
|
remant.setElement(element);
|
|
remant.setBoundOrigin(pos);
|
|
|
|
NBTTagCompound entityTag = new NBTTagCompound();
|
|
entityTag.setString("id", REMNANT_ID.toString());
|
|
remant.writeEntityToNBT(entityTag);
|
|
NBTTagCompound nbt = new NBTTagCompound();
|
|
nbt.setTag("Entity", entityTag);
|
|
|
|
spawnerLogic.setNextSpawnData(new WeightedSpawnerEntity(nbt));
|
|
|
|
}else{
|
|
Wizardry.logger.info("Tried to set the mob spawned by an obelisk, but the expected TileEntityMobSpawner was not present");
|
|
}
|
|
|
|
}else{
|
|
// This probably shouldn't happen...
|
|
Wizardry.logger.info("Unrecognised data block value {} in structure {}", entry.getValue(), structureFile);
|
|
}
|
|
}
|
|
}
|
|
}
|