Start work on cloud structures

This commit is contained in:
Sollace 2019-02-15 21:15:19 +02:00
parent b0d3c5053c
commit 19d81acfc4
6 changed files with 315 additions and 0 deletions

View file

@ -15,6 +15,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.structure.MapGenStructureIO;
import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.event.entity.ProjectileImpactEvent; import net.minecraftforge.event.entity.ProjectileImpactEvent;
import net.minecraftforge.event.entity.item.ItemTossEvent; import net.minecraftforge.event.entity.item.ItemTossEvent;
@ -22,6 +23,8 @@ import net.minecraftforge.event.entity.living.LivingEntityUseItemEvent;
import net.minecraftforge.event.entity.player.PlayerDropsEvent; import net.minecraftforge.event.entity.player.PlayerDropsEvent;
import net.minecraftforge.event.entity.player.PlayerFlyableFallEvent; import net.minecraftforge.event.entity.player.PlayerFlyableFallEvent;
import net.minecraftforge.event.entity.player.UseHoeEvent; import net.minecraftforge.event.entity.player.UseHoeEvent;
import net.minecraftforge.event.terraingen.PopulateChunkEvent;
import net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType;
import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@ -60,7 +63,9 @@ import com.minelittlepony.unicopia.network.MsgRequestCapabilities;
import com.minelittlepony.unicopia.player.PlayerSpeciesList; import com.minelittlepony.unicopia.player.PlayerSpeciesList;
import com.minelittlepony.unicopia.power.PowersRegistry; import com.minelittlepony.unicopia.power.PowersRegistry;
import com.minelittlepony.unicopia.spell.SpellRegistry; import com.minelittlepony.unicopia.spell.SpellRegistry;
import com.minelittlepony.unicopia.structure.CloudDungeon;
import com.minelittlepony.unicopia.util.crafting.CraftingManager; import com.minelittlepony.unicopia.util.crafting.CraftingManager;
import com.minelittlepony.unicopia.world.CloudGen;
import com.minelittlepony.unicopia.world.UWorld; import com.minelittlepony.unicopia.world.UWorld;
@Mod( @Mod(
@ -122,6 +127,16 @@ public class Unicopia implements IGuiHandler {
UClient.instance().posInit(event); UClient.instance().posInit(event);
UItems.fixRecipes(); UItems.fixRecipes();
MapGenStructureIO.registerStructure(CloudGen.Start.class, "unicopia:clouds");
MapGenStructureIO.registerStructureComponent(CloudDungeon.class, "unicopia:cloud_dungeon");
}
@EventHandler
public static void onStructureGen(PopulateChunkEvent.Populate event) {
if (event.getType() == EventType.DUNGEON) {
UWorld.instance().generateStructures(event.getWorld(), event.getChunkX(), event.getChunkZ(), event.getGen());
}
} }
public static CraftingManager getCraftingManager() { public static CraftingManager getCraftingManager() {

View file

@ -0,0 +1,114 @@
package com.minelittlepony.unicopia.structure;
import java.util.Random;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockPos.MutableBlockPos;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.structure.StructureBoundingBox;
import net.minecraft.world.gen.structure.StructureComponent;
import net.minecraft.world.gen.structure.StructureStart;
import net.minecraft.world.gen.structure.template.TemplateManager;
public abstract class AbstractFeature extends StructureComponent {
protected int width;
protected int height;
protected int depth;
protected int horizontalPos = -1;
public AbstractFeature() {
}
protected AbstractFeature(Random rand, int x, int y, int z, int sizeX, int sizeY, int sizeZ) {
super(0);
width = sizeX;
height = sizeY;
depth = sizeZ;
setCoordBaseMode(EnumFacing.Plane.HORIZONTAL.random(rand));
if (getCoordBaseMode().getAxis() == EnumFacing.Axis.Z) {
boundingBox = new StructureBoundingBox(x, y, z, x + sizeX - 1, y + sizeY - 1, z + sizeZ - 1);
} else {
boundingBox = new StructureBoundingBox(x, y, z, x + sizeZ - 1, y + sizeY - 1, z + sizeX - 1);
}
}
@Override
protected void writeStructureToNBT(NBTTagCompound tagCompound) {
tagCompound.setInteger("Width", width);
tagCompound.setInteger("Height", height);
tagCompound.setInteger("Depth", depth);
tagCompound.setInteger("HPos", horizontalPos);
}
@Override
protected void readStructureFromNBT(NBTTagCompound tagCompound, TemplateManager templater) {
width = tagCompound.getInteger("Width");
height = tagCompound.getInteger("Height");
depth = tagCompound.getInteger("Depth");
horizontalPos = tagCompound.getInteger("HPos");
}
protected int getAverageStructureAltitude() {
return 64;
}
protected boolean offsetToAverageGroundLevel(World worldIn, StructureBoundingBox structurebb, int yOffset) {
if (horizontalPos >= 0) {
return true;
}
int xOff = 0;
int offsetIncrements = 0;
int targetY = getAverageStructureAltitude();
MutableBlockPos pos = new MutableBlockPos();
for (int z = boundingBox.minZ; z <= boundingBox.maxZ; ++z) {
for (int x = boundingBox.minX; x <= boundingBox.maxX; ++x) {
pos.setPos(x, targetY, z);
if (structurebb.isVecInside(pos)) {
xOff += Math.max(worldIn.getTopSolidOrLiquidBlock(pos).getY(), worldIn.provider.getAverageGroundLevel());
offsetIncrements++;
}
}
}
if (offsetIncrements == 0) {
return false;
}
horizontalPos = xOff / offsetIncrements;
boundingBox.offset(0, horizontalPos - boundingBox.minY + yOffset, 0);
return true;
}
public abstract static class Start extends StructureStart {
public Start() {
}
public Start(World world, Random rand, int x, int z) {
this(world, rand, x, z, world.getBiome(new BlockPos(x * 16 + 8, 0, z * 16 + 8)));
}
public Start(World world, Random rand, int x, int z, Biome biome) {
super(x, z);
addComponents(world, rand, x, z, biome);
updateBoundingBox();
}
protected abstract void addComponents(World world, Random ran, int x, int z, Biome biome);
}
}

View file

@ -0,0 +1,27 @@
package com.minelittlepony.unicopia.structure;
import java.util.Random;
import com.minelittlepony.unicopia.Unicopia;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.structure.template.PlacementSettings;
import net.minecraft.world.gen.structure.template.TemplateManager;
public class CloudDungeon extends TemplateBasedFeature {
private static final ResourceLocation STRUCTURE = new ResourceLocation(Unicopia.MODID, "cloud/dungeon_1");
public CloudDungeon(Random rand, int x, int z) {
super(rand, x, 120, z, 7, 5, 8);
}
@Override
public boolean addComponentParts(World world, BlockPos startPos, TemplateManager templates, PlacementSettings placement) {
applyTemplate(world, startPos, templates, placement, STRUCTURE);
return false;
}
}

View file

@ -0,0 +1,91 @@
package com.minelittlepony.unicopia.structure;
import java.util.Map;
import java.util.Random;
import javax.annotation.Nullable;
import java.util.Map.Entry;
import net.minecraft.init.Blocks;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityLockableLoot;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.structure.StructureBoundingBox;
import net.minecraft.world.gen.structure.template.PlacementSettings;
import net.minecraft.world.gen.structure.template.Template;
import net.minecraft.world.gen.structure.template.TemplateManager;
import net.minecraft.world.storage.loot.LootTableList;
public abstract class TemplateBasedFeature extends AbstractFeature {
public TemplateBasedFeature() {}
protected TemplateBasedFeature(Random rand, int x, int y, int z, int sizeX, int sizeY, int sizeZ) {
super(rand, x, y, z, sizeX, sizeY, sizeX);
}
@Override
public boolean addComponentParts(World world, Random rand, StructureBoundingBox bounds) {
if (!offsetToAverageGroundLevel(world, bounds, -1)) {
return false;
}
bounds = getBoundingBox();
BlockPos startPos = new BlockPos(bounds.minX, bounds.minY, bounds.minZ);
Rotation[] orientations = Rotation.values();
TemplateManager templates = world.getSaveHandler().getStructureTemplateManager();
PlacementSettings placement = new PlacementSettings()
.setRotation(orientations[rand.nextInt(orientations.length)])
.setReplacedBlock(Blocks.STRUCTURE_VOID)
.setBoundingBox(bounds);
return addComponentParts(world, startPos, templates, placement);
}
protected void applyTemplate(World world, BlockPos startPos, TemplateManager templates, PlacementSettings placement, ResourceLocation templateId) {
Template template = templates.get(world.getMinecraftServer(), templateId);
template.addBlocksToWorldChunk(world, startPos, placement);
Map<BlockPos, String> map = template.getDataBlocks(startPos, placement);
for (Entry<BlockPos, String> entry : map.entrySet()) {
applyLootTables(world, entry.getKey(), entry.getValue());
}
}
protected void applyLootTables(World world, BlockPos pos, String blockId) {
ResourceLocation lootTable = getLootTable(blockId);
if (lootTable != null) {
world.setBlockState(pos, Blocks.AIR.getDefaultState(), 3);
TileEntity tileentity = world.getTileEntity(pos.down());
if (tileentity instanceof TileEntityLockableLoot) {
((TileEntityLockableLoot)tileentity).setLootTable(lootTable, world.rand.nextLong());
}
}
}
@Nullable
protected ResourceLocation getLootTable(String blockId) {
if ("chest".equals(blockId)) {
return LootTableList.CHESTS_STRONGHOLD_LIBRARY;
}
return null;
}
public abstract boolean addComponentParts(World world, BlockPos startPos, TemplateManager templates, PlacementSettings placement);
}

View file

@ -0,0 +1,47 @@
package com.minelittlepony.unicopia.world;
import java.util.Random;
import com.minelittlepony.unicopia.structure.AbstractFeature;
import com.minelittlepony.unicopia.structure.CloudDungeon;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.structure.MapGenScatteredFeature;
import net.minecraft.world.gen.structure.StructureStart;
public class CloudGen extends MapGenScatteredFeature {
@Override
public String getStructureName() {
return "unicopia:clouds";
}
@Override
public boolean isSwampHut(BlockPos pos) {
return false;
}
@Override
protected StructureStart getStructureStart(int chunkX, int chunkZ) {
return new Start(world, rand, chunkX, chunkZ);
}
public static class Start extends AbstractFeature.Start {
public Start() { }
public Start(World world, Random rand, int x, int z) {
super(world, rand, x, z);
}
public Start(World world, Random rand, int x, int z, Biome biome) {
super(world, rand, x, z, biome);
}
@Override
protected void addComponents(World world, Random rand, int x, int z, Biome biome) {
components.add(new CloudDungeon(rand, x * 16, z * 16));
}
}
}

View file

@ -6,10 +6,19 @@ import com.google.common.collect.Queues;
import com.minelittlepony.jumpingcastle.Exceptions; import com.minelittlepony.jumpingcastle.Exceptions;
import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.Unicopia;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.gen.ChunkGeneratorOverworld;
import net.minecraft.world.gen.IChunkGenerator;
public class UWorld { public class UWorld {
private static final UWorld instance = new UWorld();
public static UWorld instance() {
return instance;
}
private static final Queue<Runnable> tickTasks = Queues.newArrayDeque(); private static final Queue<Runnable> tickTasks = Queues.newArrayDeque();
private static final Object locker = new Object(); private static final Object locker = new Object();
@ -28,4 +37,16 @@ public class UWorld {
tickTasks.add(task); tickTasks.add(task);
} }
} }
private CloudGen cloudStructureGen = new CloudGen();
public void generateStructures(World world, int chunkX, int chunkZ, IChunkGenerator gen) {
if (gen instanceof ChunkGeneratorOverworld) {
if (world.getWorldInfo().isMapFeaturesEnabled()) {
ChunkPos pos = new ChunkPos(chunkX, chunkZ);
cloudStructureGen.generateStructure(world, world.rand, pos);
}
}
}
} }