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 dataBlocks = template.getDataBlocks(origin, settings); for(Map.Entry 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); } } } }