lazy pocket gen for SchematicGenerator

This commit is contained in:
CreepyCre 2021-02-22 00:23:28 +01:00
parent a3233054f1
commit 6de63151cb
42 changed files with 352 additions and 53 deletions

View file

@ -1,8 +1,11 @@
package org.dimdev.dimdoors.listener;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerChunkEvents;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.ServerTask;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.world.chunk.WorldChunk;
import org.dimdev.dimdoors.DimensionalDoorsInitializer;
import org.dimdev.dimdoors.pockets.generator.LazyPocketGenerator;
import org.dimdev.dimdoors.world.ModDimensions;
import org.dimdev.dimdoors.world.level.DimensionalRegistry;
@ -18,7 +21,8 @@ public class ChunkLoadListener implements ServerChunkEvents.Load {
if (LazyPocketGenerator.currentlyGenerating) {
LazyPocketGenerator.generationQueue.add(chunk);
} else {
((LazyGenerationPocket) pocket).chunkLoaded(chunk);
MinecraftServer server = DimensionalDoorsInitializer.getServer();
DimensionalDoorsInitializer.getServer().send(new ServerTask(server.getTicks(), () -> ((LazyGenerationPocket) pocket).chunkLoaded(chunk)));
}
}
}

View file

@ -1,15 +1,20 @@
package org.dimdev.dimdoors.pockets;
import net.minecraft.world.chunk.Chunk;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dimdev.dimdoors.DimensionalDoorsInitializer;
import org.dimdev.dimdoors.block.entity.RiftBlockEntity;
import org.dimdev.dimdoors.util.schematic.v2.Schematic;
import org.dimdev.dimdoors.util.schematic.v2.SchematicPlacer;
import org.dimdev.dimdoors.world.pocket.type.LazyGenerationPocket;
import org.dimdev.dimdoors.world.pocket.type.Pocket;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import java.util.List;
public class PocketTemplateV2 {
private static final Logger LOGGER = LogManager.getLogger();
private static final boolean replacingPlaceholders = false;
@ -61,9 +66,22 @@ public class PocketTemplateV2 {
ServerWorld world = DimensionalDoorsInitializer.getWorld(pocket.getWorld());
BlockPos origin = pocket.getOrigin();
LOGGER.info("Placing new pocket using schematic " + this.id + " at x = " + origin.getX() + ", z = " + origin.getZ());
SchematicPlacer.place(this.schematic, world, origin);
SchematicPlacer.place(this.schematic, world, origin);
}
public List<RiftBlockEntity> placeRiftsOnly(Pocket pocket) {
pocket.setSize(schematic.getWidth(), schematic.getHeight(), schematic.getLength());
ServerWorld world = DimensionalDoorsInitializer.getWorld(pocket.getWorld());
BlockPos origin = pocket.getOrigin();
LOGGER.info("Placing new pocket using schematic " + this.id + " at x = " + origin.getX() + ", z = " + origin.getZ());
return SchematicPlacer.placeRiftsOnly(this.schematic, world, origin);
}
public void place(LazyGenerationPocket pocket, Chunk chunk, BlockPos originalOrigin) {
BlockPos origin = pocket.getOrigin();
SchematicPlacer.place(this.schematic, DimensionalDoorsInitializer.getWorld(pocket.getWorld()), chunk, originalOrigin);
}
public static boolean isReplacingPlaceholders() {
return replacingPlaceholders;
}

View file

@ -71,6 +71,9 @@ public class TemplateUtils {
}
LootContext ctx = new LootContext.Builder(world).random(world.random).parameter(LootContextParameters.ORIGIN, Vec3d.of(tile.getPos())).build(LootContextTypes.CHEST);
table.supplyInventory(inventory, ctx);
if (inventory.isEmpty()) {
logger.error(", however Inventory is: empty!");
}
}
static public void registerRifts(List<? extends RiftBlockEntity> rifts, VirtualTarget linkTo, LinkProperties linkProperties, Pocket pocket) {

View file

@ -1,8 +1,16 @@
package org.dimdev.dimdoors.pockets.generator;
import net.minecraft.block.entity.ChestBlockEntity;
import net.minecraft.block.entity.DispenserBlockEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.Chunk;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dimdev.dimdoors.DimensionalDoorsInitializer;
import org.dimdev.dimdoors.pockets.TemplateUtils;
import org.dimdev.dimdoors.pockets.modifier.LazyModifier;
import org.dimdev.dimdoors.pockets.modifier.Modifier;
import org.dimdev.dimdoors.pockets.modifier.RiftManager;
@ -13,6 +21,8 @@ import java.util.*;
import java.util.stream.Collectors;
public abstract class LazyPocketGenerator extends PocketGenerator {
private static final Logger LOGGER = LogManager.getLogger();
public static boolean currentlyGenerating = false;
public static Queue<Chunk> generationQueue = new LinkedList<>();
@ -60,20 +70,24 @@ public abstract class LazyPocketGenerator extends PocketGenerator {
@Override
public RiftManager getRiftManager(Pocket pocket) {
return new RiftManager(pocket, true);
if (pocket instanceof LazyGenerationPocket) {
return new RiftManager(pocket, true);
} else {
return new RiftManager(pocket, false);
}
}
public void attachLazyModifiers(Collection<LazyModifier> lazyModifiers) {
this.lazyModifierList.addAll(lazyModifiers);
}
public LazyPocketGenerator cloneWithLazyModifiers() {
LazyPocketGenerator clone = cloneWithEmptyModifiers();
public LazyPocketGenerator cloneWithLazyModifiers(BlockPos originalOrigin) {
LazyPocketGenerator clone = cloneWithEmptyModifiers(originalOrigin);
clone.attachLazyModifiers(this.modifierList.stream().filter(LazyModifier.class::isInstance).map(LazyModifier.class::cast).collect(Collectors.toList()));
return clone;
}
public LazyPocketGenerator cloneWithEmptyModifiers() {
public LazyPocketGenerator cloneWithEmptyModifiers(BlockPos originalOrigin) {
LazyPocketGenerator generator = getNewInstance();
// Builder/ weight related stuff seems irrelevant here
@ -82,5 +96,22 @@ public abstract class LazyPocketGenerator extends PocketGenerator {
return generator;
}
public void setSetupLoot(Boolean setupLoot) {
this.setupLoot = setupLoot;
}
abstract public LazyPocketGenerator getNewInstance();
public void setupChunk(Pocket pocket, Chunk chunk, boolean setupLootTables) {
chunk.getBlockEntityPositions().stream().map(chunk::getBlockEntity).forEach(blockEntity -> { // RiftBlockEntities should already be initialized here
if (setupLootTables && blockEntity instanceof Inventory) {
Inventory inventory = (Inventory) blockEntity;
if (inventory.isEmpty()) {
if (blockEntity instanceof ChestBlockEntity || blockEntity instanceof DispenserBlockEntity) {
TemplateUtils.setupLootTable(DimensionalDoorsInitializer.getWorld(pocket.getWorld()), blockEntity, inventory, LOGGER);
}
}
}
});
}
}

View file

@ -15,6 +15,7 @@ import net.minecraft.util.math.Vec3i;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.util.registry.SimpleRegistry;
import net.minecraft.world.chunk.Chunk;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dimdev.dimdoors.DimensionalDoorsInitializer;
@ -146,8 +147,8 @@ public abstract class PocketGenerator implements Weighted<PocketGenerationParame
return this.weightEquation.apply(parameters.toVariableMap(new HashMap<>()));
}
public Boolean getSetupLoot() {
return setupLoot;
public boolean isSetupLoot() {
return setupLoot != null && setupLoot;
}
public void applyModifiers(PocketGenerationParameters parameters, RiftManager manager) {

View file

@ -1,23 +1,30 @@
package org.dimdev.dimdoors.pockets.generator;
import net.fabricmc.fabric.api.util.NbtType;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.chunk.Chunk;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dimdev.dimdoors.block.entity.RiftBlockEntity;
import org.dimdev.dimdoors.pockets.PocketTemplateV2;
import org.dimdev.dimdoors.pockets.SchematicV2Handler;
import org.dimdev.dimdoors.pockets.modifier.RiftManager;
import org.dimdev.dimdoors.util.PocketGenerationParameters;
import org.dimdev.dimdoors.util.math.Equation;
import org.dimdev.dimdoors.util.schematic.v2.Schematic;
import org.dimdev.dimdoors.world.level.DimensionalRegistry;
import org.dimdev.dimdoors.world.pocket.type.LazyGenerationPocket;
import org.dimdev.dimdoors.world.pocket.type.Pocket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SchematicGenerator extends PocketGenerator {
public class SchematicGenerator extends LazyPocketGenerator{
private static final Logger LOGGER = LogManager.getLogger();
public static final String KEY = "schematic";
@ -31,6 +38,8 @@ public class SchematicGenerator extends PocketGenerator {
private String id;
private Identifier templateID;
private final List<RiftBlockEntity> rifts = new ArrayList<>();
private BlockPos origin;
public SchematicGenerator() {
}
@ -49,12 +58,26 @@ public class SchematicGenerator extends PocketGenerator {
return templateID;
}
@Override
public void generateChunk(LazyGenerationPocket pocket, Chunk chunk) {
PocketTemplateV2 template = SchematicV2Handler.getInstance().getTemplates().get(templateID);
if (template == null) throw new RuntimeException("Pocket template of id " + templateID + " not found!");
template.place(pocket, chunk, origin);
setupChunk(pocket, chunk, isSetupLoot());
super.generateChunk(pocket, chunk);
}
@Override
public PocketGenerator fromTag(CompoundTag tag) {
super.fromTag(tag);
this.id = tag.getString("id");
this.id = tag.getString("id"); // TODO: should we force having the "dimdoors:" in the json?
this.templateID = new Identifier("dimdoors", id);
if (tag.contains("origin", NbtType.INT_ARRAY)) {
int[] originInts = tag.getIntArray("origin");
this.origin = new BlockPos(originInts[0], originInts[1], originInts[2]);
}
SchematicV2Handler.getInstance().loadSchematic(templateID, id);
@ -66,10 +89,36 @@ public class SchematicGenerator extends PocketGenerator {
super.toTag(tag);
tag.putString("id", this.id);
if (origin != null) tag.putIntArray("origin", new int[]{origin.getX(), origin.getY(), origin.getZ()});
return tag;
}
@Override
public RiftManager getRiftManager(Pocket pocket) {
RiftManager manager = super.getRiftManager(pocket);
rifts.forEach(manager::add);
return manager;
}
@Override
public LazyPocketGenerator cloneWithEmptyModifiers(BlockPos originalOrigin) {
SchematicGenerator generator = (SchematicGenerator) super.cloneWithEmptyModifiers(originalOrigin);
generator.id = id;
generator.templateID = templateID;
generator.origin = originalOrigin;
return generator;
}
@Override
public LazyPocketGenerator getNewInstance() {
return new SchematicGenerator();
}
@Override
public Pocket prepareAndPlacePocket(PocketGenerationParameters parameters, Pocket.PocketBuilder<?, ?> builder) {
ServerWorld world = parameters.getWorld();
@ -81,9 +130,11 @@ public class SchematicGenerator extends PocketGenerator {
Pocket pocket = DimensionalRegistry.getPocketDirectory(world.getRegistryKey()).newPocket(builder);
LOGGER.info("Generating pocket from template " + template.getId() + " at location " + pocket.getOrigin());
template.place(pocket);
pocket.virtualLocation = parameters.getSourceVirtualLocation(); // TODO: this makes very little sense
if (pocket instanceof LazyGenerationPocket) {
rifts.addAll(template.placeRiftsOnly(pocket));
} else {
template.place(pocket);
}
return pocket;
}

View file

@ -1,6 +1,7 @@
package org.dimdev.dimdoors.pockets.generator;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -79,8 +80,8 @@ public class VoidGenerator extends LazyPocketGenerator {
}
@Override
public LazyPocketGenerator cloneWithEmptyModifiers() {
VoidGenerator generator = (VoidGenerator) super.cloneWithEmptyModifiers();
public LazyPocketGenerator cloneWithEmptyModifiers(BlockPos originalOrigin) {
VoidGenerator generator = (VoidGenerator) super.cloneWithEmptyModifiers(originalOrigin);
generator.width = width;
generator.height = height;
generator.length = length;

View file

@ -21,6 +21,7 @@ import net.minecraft.world.chunk.Chunk;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dimdev.dimdoors.util.BlockBoxUtil;
import org.dimdev.dimdoors.util.PocketGenerationParameters;
import org.dimdev.dimdoors.util.math.Equation;
import org.dimdev.dimdoors.util.schematic.v2.SchematicBlockPalette;
@ -66,42 +67,42 @@ public class ShellModifier implements LazyModifier {
// x-planes
temp = BlockBox.create(boxToDrawAround.maxX + 1 + boxExpansion, boxToDrawAround.minY - thickness - boxExpansion, boxToDrawAround.minZ - thickness - boxExpansion, boxToDrawAround.maxX + thickness + boxExpansion, boxToDrawAround.maxY + thickness + boxExpansion, boxToDrawAround.maxZ + thickness + boxExpansion);
temp = intersection(temp, chunkBox);
if (isRealBox(temp)) BlockPos.stream(temp)
temp = BlockBoxUtil.intersection(temp, chunkBox);
if (BlockBoxUtil.isRealBox(temp)) BlockPos.stream(temp)
.forEach(blockPos -> {
if(chunk.getBlockState(blockPos).isAir()) chunk.setBlockState(blockPos, blockState, false);
});
temp = BlockBox.create(boxToDrawAround.minX - 1 - boxExpansion, boxToDrawAround.minY - thickness - boxExpansion, boxToDrawAround.minZ - thickness - boxExpansion, boxToDrawAround.minX - thickness - boxExpansion, boxToDrawAround.maxY + thickness + boxExpansion, boxToDrawAround.maxZ + thickness + boxExpansion);
temp = intersection(temp, chunkBox);
if (isRealBox(temp)) BlockPos.stream(temp)
temp = BlockBoxUtil.intersection(temp, chunkBox);
if (BlockBoxUtil.isRealBox(temp)) BlockPos.stream(temp)
.forEach(blockPos -> {
if(chunk.getBlockState(blockPos).isAir()) chunk.setBlockState(blockPos, blockState, false);
});
// y-planes
temp = BlockBox.create(boxToDrawAround.minX - boxExpansion, boxToDrawAround.maxY + 1 + boxExpansion, boxToDrawAround.minZ - thickness - boxExpansion, boxToDrawAround.maxX + boxExpansion, boxToDrawAround.maxY + thickness + boxExpansion, boxToDrawAround.maxZ + thickness + boxExpansion);
temp = intersection(temp, chunkBox);
if (isRealBox(temp)) BlockPos.stream(temp)
temp = BlockBoxUtil.intersection(temp, chunkBox);
if (BlockBoxUtil.isRealBox(temp)) BlockPos.stream(temp)
.forEach(blockPos -> {
if(chunk.getBlockState(blockPos).getBlock() instanceof AirBlock) chunk.setBlockState(blockPos, blockState, false);
});
temp = BlockBox.create(boxToDrawAround.minX - boxExpansion, boxToDrawAround.minY - 1 - boxExpansion, boxToDrawAround.minZ - thickness - boxExpansion, boxToDrawAround.maxX + boxExpansion, boxToDrawAround.minY - thickness - boxExpansion, boxToDrawAround.maxZ + thickness + boxExpansion);
temp = intersection(temp, chunkBox);
if (isRealBox(temp)) BlockPos.stream(temp)
temp = BlockBoxUtil.intersection(temp, chunkBox);
if (BlockBoxUtil.isRealBox(temp)) BlockPos.stream(temp)
.forEach(blockPos -> {
if(chunk.getBlockState(blockPos).isAir()) chunk.setBlockState(blockPos, blockState, false);
});
// z-planes
temp = BlockBox.create(boxToDrawAround.minX - boxExpansion, boxToDrawAround.minY - boxExpansion, boxToDrawAround.minZ - 1 - boxExpansion, boxToDrawAround.maxX + boxExpansion, boxToDrawAround.maxY + boxExpansion, boxToDrawAround.minZ - thickness - boxExpansion);
temp = intersection(temp, chunkBox);
if (isRealBox(temp)) BlockPos.stream(temp)
temp = BlockBoxUtil.intersection(temp, chunkBox);
if (BlockBoxUtil.isRealBox(temp)) BlockPos.stream(temp)
.forEach(blockPos -> {
if(chunk.getBlockState(blockPos).isAir()) chunk.setBlockState(blockPos, blockState, false);
});
temp = BlockBox.create(boxToDrawAround.minX - boxExpansion, boxToDrawAround.minY - boxExpansion, boxToDrawAround.maxZ + 1 + boxExpansion, boxToDrawAround.maxX + boxExpansion, boxToDrawAround.maxY + boxExpansion, boxToDrawAround.maxZ + thickness + boxExpansion);
temp = intersection(temp, chunkBox);
if (isRealBox(temp)) BlockPos.stream(temp)
temp = BlockBoxUtil.intersection(temp, chunkBox);
if (BlockBoxUtil.isRealBox(temp)) BlockPos.stream(temp)
.forEach(blockPos -> {
if(chunk.getBlockState(blockPos).isAir()) chunk.setBlockState(blockPos, blockState, false);
});
@ -234,13 +235,4 @@ public class ShellModifier implements LazyModifier {
return new Layer(tag.getString("block_state"), tag.getString("thickness"));
}
}
// intersection might be non real box, check with isRealBox
private BlockBox intersection(BlockBox box1, BlockBox box2) {
return new BlockBox(Math.max(box1.minX, box2.minX), Math.max(box1.minY, box2.minY), Math.max(box1.minZ, box2.minZ), Math.min(box1.maxX, box2.maxX), Math.min(box1.maxY, box2.maxY), Math.min(box1.maxZ, box2.maxZ));
}
private boolean isRealBox(BlockBox box) {
return box.minX <= box.maxX && box.minY <= box.maxY && box.minZ <= box.maxZ;
}
}

View file

@ -7,9 +7,13 @@ import java.util.stream.Collectors;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import net.fabricmc.fabric.api.util.NbtType;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.ServerTask;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.Chunk;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dimdev.dimdoors.DimensionalDoorsInitializer;
import org.dimdev.dimdoors.pockets.generator.LazyPocketGenerator;
import org.dimdev.dimdoors.pockets.generator.PocketGenerator;
import org.dimdev.dimdoors.pockets.modifier.LazyModifier;
@ -131,24 +135,29 @@ public abstract class PocketGeneratorReference extends VirtualSingularPocket {
LazyPocketGenerator.currentlyGenerating = true;
Pocket pocket = generator.prepareAndPlacePocket(parameters, builder);
BlockPos originalOrigin = pocket.getOrigin();
RiftManager manager = generator.getRiftManager(pocket);
generator.applyModifiers(parameters, manager);
this.applyModifiers(parameters, manager);
generator.setup(pocket, manager, parameters, setupLoot != null ? setupLoot : (generator.getSetupLoot()) != null ? generator.getSetupLoot() : true);
generator.setup(pocket, manager, parameters, setupLoot != null ? setupLoot : generator.isSetupLoot());
if (pocket instanceof LazyGenerationPocket) {
if (!(generator instanceof LazyPocketGenerator)) throw new RuntimeException("pocket was instance of LazyGenerationPocket but generator was not instance of LazyPocketGenerator");
LazyGenerationPocket lazyPocket = (LazyGenerationPocket) pocket;
LazyPocketGenerator clonedGenerator = ((LazyPocketGenerator) generator).cloneWithLazyModifiers();
LazyPocketGenerator clonedGenerator = ((LazyPocketGenerator) generator).cloneWithLazyModifiers(originalOrigin);
if (setupLoot != null) clonedGenerator.setSetupLoot(setupLoot);
attachLazyModifiers(clonedGenerator);
clonedGenerator.attachToPocket(lazyPocket);
lazyPocket.init();
LazyPocketGenerator.currentlyGenerating = false;
while (!LazyPocketGenerator.generationQueue.isEmpty()) {
lazyPocket.chunkLoaded(LazyPocketGenerator.generationQueue.remove());
Chunk chunk = LazyPocketGenerator.generationQueue.remove();
MinecraftServer server = DimensionalDoorsInitializer.getServer();
DimensionalDoorsInitializer.getServer().send(new ServerTask(server.getTicks(), () -> (lazyPocket).chunkLoaded(chunk)));
}
} else {
LazyPocketGenerator.generationQueue.clear();

View file

@ -0,0 +1,14 @@
package org.dimdev.dimdoors.util;
import net.minecraft.util.math.BlockBox;
public class BlockBoxUtil {
// intersection might be non real box, check with isRealBox
public static BlockBox intersection(BlockBox box1, BlockBox box2) {
return new BlockBox(Math.max(box1.minX, box2.minX), Math.max(box1.minY, box2.minY), Math.max(box1.minZ, box2.minZ), Math.min(box1.maxX, box2.maxX), Math.min(box1.maxY, box2.maxY), Math.min(box1.maxZ, box2.maxZ));
}
public static boolean isRealBox(BlockBox box) {
return box.minX <= box.maxX && box.minY <= box.maxY && box.minZ <= box.maxZ;
}
}

View file

@ -2,6 +2,9 @@
"type": "dimdoors:schematic",
"setup_loot": true,
"id": "v2/custom/broken_pillars",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -2,6 +2,9 @@
"type": "dimdoors:schematic",
"setup_loot": true,
"id": "v2/custom/buggy_top_entry",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -2,6 +2,9 @@
"type": "dimdoors:schematic",
"id": "v2/custom/cage_monolithless",
"setup_loot": true,
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"layers": [

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/chain_crossing",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/chain_t",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/collapsed_single_tunnel",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/crumbled_hall",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/decaying_chain_tunnel",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/door_totem_ruins",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/exit_cube",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/exit_ruins_with_hidden_door",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/honey_parkour",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/lantredom",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/lantredom_end",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/lantredom_red",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/line_walker",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/mob_prison",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/monolith_cage",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/party",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/returning_eye",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/rising_hand",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/river_road_twin_bridges",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/silverfish_bridge",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -2,6 +2,9 @@
"type": "dimdoors:schematic",
"setup_loot": true,
"id": "v2/custom/smile_6",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"layers": [
@ -17,8 +20,5 @@
"ids": [0],
"rift_data": "rift_data/pocket_entrance"
}
],
"offset_x": "1",
"offset_y": "1",
"offset_z": "1"
]
}

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/stone_brick_bridge",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -2,6 +2,9 @@
"type": "dimdoors:schematic",
"setup_loot": true,
"id": "v2/custom/trap_rib_tunnel",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/upwards_pillars",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -2,6 +2,9 @@
"type": "dimdoors:schematic",
"id": "v2/custom/upwards_t_treasure",
"setup_loot": true,
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,6 +1,9 @@
{
"type": "dimdoors:schematic",
"id": "v2/custom/waiting_room",
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -2,6 +2,9 @@
"type": "dimdoors:schematic",
"id": "v2/custom/white_fabric_maze",
"setup_loot": true,
"builder": {
"type": "dimdoors:lazy_gen_pocket"
},
"modifiers": [
{
"type": "dimdoors:rift_data",

View file

@ -1,19 +1,18 @@
package org.dimdev.dimdoors.util.schematic.v2;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.*;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.Maps;
import net.minecraft.block.*;
import net.minecraft.util.math.*;
import net.minecraft.world.chunk.Chunk;
import org.dimdev.dimdoors.block.entity.RiftBlockEntity;
import org.dimdev.dimdoors.util.BlockBoxUtil;
import org.jetbrains.annotations.Nullable;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
@ -21,8 +20,6 @@ import net.minecraft.fluid.FluidState;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.BlockView;
import net.minecraft.world.ModifiableWorld;
import net.minecraft.world.StructureWorldAccess;
@ -131,6 +128,71 @@ public class RelativeBlockSample implements BlockView, ModifiableWorld {
}
}
public void place(BlockPos origin, StructureWorldAccess world, Chunk chunk, boolean biomes) {
ChunkPos pos = chunk.getPos();
BlockBox chunkBox = BlockBox.create(pos.getStartX(), chunk.getBottomY(), pos.getStartZ(), pos.getEndX(), chunk.getTopY(), pos.getEndZ());
BlockBox schemBox = BlockBox.create(origin.getX(), origin.getY(), origin.getZ(), origin.getX() + schematic.getWidth() - 1, origin.getY() + schematic.getHeight() - 1, origin.getZ() + schematic.getLength() - 1);
BlockBox intersection = BlockBoxUtil.intersection(chunkBox, schemBox);
if (!BlockBoxUtil.isRealBox(intersection)) return;
BlockPos.stream(intersection).forEach(blockPos -> {
if(chunk.getBlockState(blockPos).isAir()) chunk.setBlockState(blockPos, this.blockContainer.get(blockPos.subtract(origin)), false);
});
// TODO: depending on size of blockEntityContainer it might be faster to iterate over BlockPos.stream(intersection) instead
this.blockEntityContainer.forEach((blockPos, tag) -> {
BlockPos actualPos = blockPos.add(origin);
if (intersection.contains(actualPos)) {
if(tag.contains("Id")) {
tag.put("id", tag.get("Id")); // boogers
tag.remove("Id");
}
BlockEntity blockEntity = BlockEntity.createFromTag(actualPos, this.getBlockState(blockPos), tag);
if (blockEntity != null && !(blockEntity instanceof RiftBlockEntity)) {
chunk.setBlockEntity(blockEntity);
}
}
});
this.entityContainer.forEach(((tag, vec3d) -> {
ListTag doubles = tag.getList("Pos", NbtType.DOUBLE);
Vec3d vec = vec3d.add(origin.getX(), origin.getY(), origin.getZ());
if (intersection.contains(new Vec3i(vec.x, vec.y, vec.z))) {
doubles.set(0, NbtOps.INSTANCE.createDouble(vec.x));
doubles.set(1, NbtOps.INSTANCE.createDouble(vec.y));
doubles.set(2, NbtOps.INSTANCE.createDouble(vec.z));
tag.put("Pos", doubles);
Entity entity = EntityType.getEntityFromTag(tag, world.toServerWorld()).orElseThrow(NoSuchElementException::new);
world.spawnEntity(entity);
}
}));
}
public List<RiftBlockEntity> placeRiftsOnly(BlockPos origin, StructureWorldAccess world) {
List<RiftBlockEntity> rifts = new ArrayList<>();
this.blockEntityContainer.forEach( (blockPos, tag) -> {
BlockPos actualPos = origin.add(blockPos);
if(tag.contains("Id")) {
tag.put("id", tag.get("Id")); // boogers
tag.remove("Id");
}
BlockState state = getBlockState(blockPos);
BlockEntity blockEntity = BlockEntity.createFromTag(actualPos, state, tag);
if (blockEntity instanceof RiftBlockEntity) {
world.setBlockState(actualPos, state, 0);
if (state.getBlock() instanceof DoorBlock) {
world.setBlockState(actualPos.up(), getBlockState(blockPos.up()), 0);
}
world.toServerWorld().addBlockEntity(blockEntity);
rifts.add((RiftBlockEntity) blockEntity);
}
});
return rifts;
}
public int[][][] getBlockData() {
return this.blockData;
}

View file

@ -4,6 +4,7 @@ import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
import net.minecraft.world.chunk.Chunk;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -17,6 +18,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.StructureWorldAccess;
import net.fabricmc.loader.api.FabricLoader;
import org.dimdev.dimdoors.block.entity.RiftBlockEntity;
public final class SchematicPlacer {
public static final Logger LOGGER = LogManager.getLogger();
@ -35,6 +37,30 @@ public final class SchematicPlacer {
blockSample.place(origin, world, false);
}
public static List<RiftBlockEntity> placeRiftsOnly(Schematic schematic, StructureWorldAccess world, BlockPos origin) {
LOGGER.debug("Placing schematic rifts only: {}", schematic.getMetadata().getName());
for (String id : schematic.getMetadata().getRequiredMods()) {
if (!FabricLoader.getInstance().isModLoaded(id)) {
LOGGER.warn("Schematic \"" + schematic.getMetadata().getName() + "\" depends on mod \"" + id + "\", which is missing!");
}
}
RelativeBlockSample blockSample = Schematic.getBlockSample(schematic);
return blockSample.placeRiftsOnly(origin, world);
}
public static void place(Schematic schematic, StructureWorldAccess world, Chunk chunk, BlockPos origin) {
LOGGER.debug("Placing schematic: {}", schematic.getMetadata().getName());
for (String id : schematic.getMetadata().getRequiredMods()) {
if (!FabricLoader.getInstance().isModLoaded(id)) {
LOGGER.warn("Schematic \"" + schematic.getMetadata().getName() + "\" depends on mod \"" + id + "\", which is missing!");
}
}
RelativeBlockSample blockSample = Schematic.getBlockSample(schematic);
blockSample.place(origin, world, chunk, false);
}
public static int[][][] getBlockData(Schematic schematic) {
int width = schematic.getWidth();
int height = schematic.getHeight();