Initial commit

This commit is contained in:
dfsek
2021-10-17 15:38:31 -07:00
commit 6002620d4d
3 changed files with 221 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
plugins {
id("com.github.johnrengelman.shadow")
}
repositories {
maven { url = uri("https://jitpack.io/") }
}
dependencies {
"shadedApi"("commons-io:commons-io:2.6")
"shadedApi"("com.github.Querz:NBT:6.1")
}
tasks.named<ShadowJar>("shadowJar") {
archiveClassifier.set("")
relocate("org.apache.commons", "com.dfsek.terra.addons.sponge.lib.commons")
}
tasks.named("build") {
finalizedBy(tasks.named("shadowJar"))
}

View File

@@ -0,0 +1,101 @@
package com.dfsek.terra.addons.sponge;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.addon.TerraAddon;
import com.dfsek.terra.api.addon.annotations.Addon;
import com.dfsek.terra.api.addon.annotations.Author;
import com.dfsek.terra.api.addon.annotations.Version;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
import com.dfsek.terra.api.inject.annotations.Inject;
import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.structure.Structure;
import com.dfsek.terra.api.util.StringUtil;
import net.querz.nbt.io.NBTDeserializer;
import net.querz.nbt.tag.ByteArrayTag;
import net.querz.nbt.tag.CompoundTag;
import net.querz.nbt.tag.IntTag;
import net.querz.nbt.tag.Tag;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPInputStream;
@Addon("structure-sponge-loader")
@Author("Terra")
@Version("1.0.0")
public class SpongeSchematicAddon extends TerraAddon {
@Inject
private Platform platform;
@Override
public void initialize() {
platform.getEventManager()
.getHandler(FunctionalEventHandler.class)
.register(this, ConfigPackPreLoadEvent.class)
.then(event -> {
CheckedRegistry<Structure> structureRegistry = event.getPack().getOrCreateRegistry(Structure.class);
event.getPack().getLoader().open("", ".schem").thenEntries(entries -> {
for(Map.Entry<String, InputStream> entry : entries) {
String id = StringUtil.fileName(entry.getKey());
structureRegistry.register(id, convert(entry.getValue(), id));
}
}).close();
})
.failThrough();
}
public SpongeStructure convert(InputStream in, String id) {
try {
CompoundTag baseTag = (CompoundTag) new NBTDeserializer(false).fromStream(detectDecompression(in)).getTag();
int wid = baseTag.getShort("Width");
int len = baseTag.getShort("Length");
int hei = baseTag.getShort("Height");
ByteArrayTag blocks = baseTag.getByteArrayTag("BlockData");
CompoundTag palette = (CompoundTag) baseTag.get("Palette");
Map<Integer, String> data = new HashMap<>();
for(Map.Entry<String, Tag<?>> entry : palette.entrySet()) {
data.put(((IntTag) entry.getValue()).asInt(), entry.getKey());
}
BlockState[][][] states = new BlockState[wid][len][hei];
byte[] arr = blocks.getValue();
for(int x = 0; x < wid; x++) {
for(int z = 0; z < len; z++) {
for(int y = 0; y < hei; y++) {
String block = data.get((int) arr[x + z * wid + y * wid * len]);
if(block.startsWith("minecraft:structure_void")) continue;
states[x][z][y] = platform.getWorldHandle().createBlockData(block);
}
}
}
return new SpongeStructure(states, platform, id);
} catch(IOException e) {
throw new IllegalArgumentException("Failed to parse Sponge schematic: ", e);
}
}
private static InputStream detectDecompression(InputStream is) throws IOException {
PushbackInputStream pbis = new PushbackInputStream(is, 2);
int signature = (pbis.read() & 0xFF) + (pbis.read() << 8);
pbis.unread(signature >> 8);
pbis.unread(signature & 0xFF);
if(signature == GZIPInputStream.GZIP_MAGIC) {
return new GZIPInputStream(pbis);
}
return pbis;
}
}

View File

@@ -0,0 +1,97 @@
package com.dfsek.terra.addons.sponge;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.structure.Structure;
import com.dfsek.terra.api.structure.buffer.Buffer;
import com.dfsek.terra.api.structure.buffer.items.BufferedBlock;
import com.dfsek.terra.api.structure.rotation.Rotation;
import com.dfsek.terra.api.util.RotationUtil;
import com.dfsek.terra.api.util.vector.Vector2;
import com.dfsek.terra.api.util.vector.Vector3;
import com.dfsek.terra.api.world.Chunk;
import com.dfsek.terra.api.world.World;
import net.jafama.FastMath;
import java.util.Random;
public class SpongeStructure implements Structure {
private final BlockState[][][] blocks;
private final Platform platform;
private final String id;
public SpongeStructure(BlockState[][][] blocks, Platform platform, String id) {
this.blocks = blocks;
this.platform = platform;
this.id = id;
}
@Override
public boolean generate(Vector3 location, World world, Chunk chunk, Random random, Rotation rotation) {
int bX = location.getBlockX();
int bY = location.getBlockY();
int bZ = location.getBlockZ();
for(int x = 0; x < blocks.length; x++) {
for(int z = 0; z < blocks[x].length; z++) {
Vector2 r = RotationUtil.rotateVector(new Vector2(x, z), rotation);
int rX = r.getBlockX();
int rZ = r.getBlockZ();
if(FastMath.floorDiv(bX+rX, 16) != chunk.getX() || FastMath.floorDiv(bZ+rZ, 16) != chunk.getZ()) {
continue;
}
for(int y = 0; y < blocks[z].length; y++) {
BlockState state = blocks[x][z][y];
if(state == null) continue;
world.setBlockData(bX+rX, bY+y, bZ+rZ, state);
}
}
}
return true;
}
@Override
public boolean generate(Buffer buffer, World world, Random random, Rotation rotation, int recursions) {
for(int x = 0; x < blocks.length; x++) {
for(int z = 0; z < blocks[x].length; z++) {
Vector2 r = RotationUtil.rotateVector(new Vector2(x, z), rotation);
int rX = r.getBlockX();
int rZ = r.getBlockZ();
for(int y = 0; y < blocks[z].length; y++) {
BlockState state = blocks[x][z][y];
if(state == null) continue;
buffer.addItem(new BufferedBlock(state, true, platform, false), new Vector3(rX, y, rZ));
}
}
}
return true;
}
@Override
public boolean generate(Vector3 location, World world, Random random, Rotation rotation) {
int bX = location.getBlockX();
int bY = location.getBlockY();
int bZ = location.getBlockZ();
for(int x = 0; x < blocks.length; x++) {
for(int z = 0; z < blocks[x].length; z++) {
Vector2 r = RotationUtil.rotateVector(new Vector2(x, z), rotation);
int rX = r.getBlockX();
int rZ = r.getBlockZ();
for(int y = 0; y < blocks[z].length; y++) {
BlockState state = blocks[x][z][y];
if(state == null) continue;
world.setBlockData(bX+rX, bY+y, bZ+rZ, state);
}
}
}
return true;
}
@Override
public String getID() {
return id;
}
}