CreateMod/src/main/java/com/simibubi/create/content/schematics/SchematicInstances.java
2023-05-21 21:48:39 +02:00

95 lines
3 KiB
Java

package com.simibubi.create.content.schematics;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.simibubi.create.content.contraptions.StructureTransform;
import com.simibubi.create.foundation.utility.WorldAttached;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Vec3i;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
public class SchematicInstances {
public static final WorldAttached<Cache<Integer, SchematicWorld>> loadedSchematics;
static {
loadedSchematics = new WorldAttached<>($ -> CacheBuilder.newBuilder()
.expireAfterAccess(5, TimeUnit.MINUTES)
.build());
}
public static void register() {}
@Nullable
public static SchematicWorld get(Level world, ItemStack schematic) {
Cache<Integer, SchematicWorld> map = loadedSchematics.get(world);
int hash = getHash(schematic);
SchematicWorld ifPresent = map.getIfPresent(hash);
if (ifPresent != null)
return ifPresent;
SchematicWorld loadWorld = loadWorld(world, schematic);
if (loadWorld == null)
return null;
map.put(hash, loadWorld);
return loadWorld;
}
private static SchematicWorld loadWorld(Level wrapped, ItemStack schematic) {
if (schematic == null || !schematic.hasTag())
return null;
if (!schematic.getTag()
.getBoolean("Deployed"))
return null;
StructureTemplate activeTemplate = SchematicItem.loadSchematic(schematic);
if (activeTemplate.getSize()
.equals(Vec3i.ZERO))
return null;
BlockPos anchor = NbtUtils.readBlockPos(schematic.getTag()
.getCompound("Anchor"));
SchematicWorld world = new SchematicWorld(anchor, wrapped);
StructurePlaceSettings settings = SchematicItem.getSettings(schematic);
activeTemplate.placeInWorld(world, anchor, anchor, settings, wrapped.getRandom(), Block.UPDATE_CLIENTS);
StructureTransform transform = new StructureTransform(settings.getRotationPivot(), Direction.Axis.Y,
settings.getRotation(), settings.getMirror());
for (BlockEntity be : world.getBlockEntities())
transform.apply(be);
return world;
}
public static void clearHash(ItemStack schematic) {
if (schematic == null || !schematic.hasTag())
return;
schematic.getTag()
.remove("SchematicHash");
}
public static int getHash(ItemStack schematic) {
if (schematic == null || !schematic.hasTag())
return -1;
CompoundTag tag = schematic.getTag();
if (!tag.contains("SchematicHash"))
tag.putInt("SchematicHash", tag.toString()
.hashCode());
return tag.getInt("SchematicHash");
}
}