Added experimental site export mod.
This commit is contained in:
+16
-1
@@ -82,11 +82,19 @@ sourceSets {
|
|||||||
compileClasspath += sourceSets.api.output
|
compileClasspath += sourceSets.api.output
|
||||||
runtimeClasspath += sourceSets.api.output
|
runtimeClasspath += sourceSets.api.output
|
||||||
}
|
}
|
||||||
|
siteexport {
|
||||||
|
compileClasspath += sourceSets.api.output
|
||||||
|
runtimeClasspath += sourceSets.api.output
|
||||||
|
compileClasspath += sourceSets.main.output
|
||||||
|
runtimeClasspath += sourceSets.main.output
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
apiCompile.extendsFrom(compileClasspath)
|
apiCompile.extendsFrom(compileClasspath)
|
||||||
datagenCompile.extendsFrom(compileClasspath)
|
datagenCompile.extendsFrom(compileClasspath)
|
||||||
|
siteexportCompile.extendsFrom(compileClasspath)
|
||||||
|
siteexportRuntime.extendsFrom(runtimeClasspath)
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: 'gradle/scripts/spotless.gradle'
|
apply from: 'gradle/scripts/spotless.gradle'
|
||||||
@@ -177,7 +185,7 @@ publishing {
|
|||||||
|
|
||||||
import net.fabricmc.loom.task.RunClientTask;
|
import net.fabricmc.loom.task.RunClientTask;
|
||||||
|
|
||||||
task generateData(type: RunClientTask, dependsOn: downloadAssets, group: "ae2") {
|
task generateData(type: RunClientTask, dependsOn: downloadAssets, group: "ae2", description: "Generates various JSON assets for the mod") {
|
||||||
classpath = configurations.runtimeClasspath
|
classpath = configurations.runtimeClasspath
|
||||||
classpath sourceSets.api.output
|
classpath sourceSets.api.output
|
||||||
classpath sourceSets.main.output
|
classpath sourceSets.main.output
|
||||||
@@ -185,3 +193,10 @@ task generateData(type: RunClientTask, dependsOn: downloadAssets, group: "ae2")
|
|||||||
systemProperty "appeng.generateData", "true"
|
systemProperty "appeng.generateData", "true"
|
||||||
}
|
}
|
||||||
build.dependsOn generateData
|
build.dependsOn generateData
|
||||||
|
|
||||||
|
task runSiteExport(type: RunClientTask, dependsOn: downloadAssets, group: "ae2", description: "Export game assets for the website") {
|
||||||
|
classpath = configurations.runtimeClasspath
|
||||||
|
classpath sourceSets.api.output
|
||||||
|
classpath sourceSets.main.output
|
||||||
|
classpath sourceSets.siteexport.output
|
||||||
|
}
|
||||||
|
|||||||
@@ -334,7 +334,7 @@ public class CachedPlane {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME check if this makes any sense at all to send changes to players asap
|
// FIXME check if this makes any sense at all to send changes to players asap
|
||||||
ServerChunkManager serverChunkProvider = (ServerChunkManager) world.getChunkManager();
|
ServerChunkManager serverChunkProvider = world.getChunkManager();
|
||||||
serverChunkProvider.tick(() -> false);
|
serverChunkProvider.tick(() -> false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
package appeng.siteexport;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL12;
|
||||||
|
|
||||||
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.gl.Framebuffer;
|
||||||
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
|
import net.minecraft.client.render.DiffuseLighting;
|
||||||
|
import net.minecraft.client.texture.NativeImage;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.collection.DefaultedList;
|
||||||
|
|
||||||
|
import appeng.api.definitions.IDefinitions;
|
||||||
|
import appeng.core.Api;
|
||||||
|
import appeng.core.CreativeTab;
|
||||||
|
|
||||||
|
public class Entrypoint implements ClientModInitializer {
|
||||||
|
|
||||||
|
private static final int FB_WIDTH = 128;
|
||||||
|
private static final int FB_HEIGHT = 128;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInitializeClient() {
|
||||||
|
ClientLifecycleEvents.CLIENT_STARTED.register(client -> {
|
||||||
|
client.currentScreen = new Screen(Text.of("DUMMY")) {
|
||||||
|
@Override
|
||||||
|
protected void init() {
|
||||||
|
while (true) {
|
||||||
|
runExport(client);
|
||||||
|
}
|
||||||
|
// client.getWindow().close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runExport(MinecraftClient client) {
|
||||||
|
|
||||||
|
// Set up GL state for GUI rendering
|
||||||
|
RenderSystem.matrixMode(GL12.GL_PROJECTION);
|
||||||
|
RenderSystem.loadIdentity();
|
||||||
|
RenderSystem.ortho(0.0D, 16, 16, 0.0D, 1000.0D, 3000.0D);
|
||||||
|
RenderSystem.matrixMode(GL12.GL_MODELVIEW);
|
||||||
|
RenderSystem.loadIdentity();
|
||||||
|
RenderSystem.translatef(0.0F, 0.0F, -2000.0F);
|
||||||
|
DiffuseLighting.enableGuiDepthLighting();
|
||||||
|
MatrixStack matrixStack = new MatrixStack();
|
||||||
|
|
||||||
|
IDefinitions definitions = Api.instance().definitions();
|
||||||
|
|
||||||
|
NativeImage nativeImage = new NativeImage(FB_WIDTH, FB_HEIGHT, true);
|
||||||
|
Framebuffer fb = new Framebuffer(FB_WIDTH, FB_HEIGHT, true, false);
|
||||||
|
fb.setClearColor(0, 0, 0, 0);
|
||||||
|
fb.clear(false);
|
||||||
|
|
||||||
|
// Iterate over all Applied Energistics items
|
||||||
|
DefaultedList<ItemStack> stacks = DefaultedList.of();
|
||||||
|
CreativeTab.INSTANCE.appendStacks(stacks);
|
||||||
|
|
||||||
|
// Compute the square grid size needed to have enough cells for the number of
|
||||||
|
// items we
|
||||||
|
// want to render
|
||||||
|
int s = (int) Math.ceil(Math.sqrt(stacks.size()));
|
||||||
|
// Add a transparent margin to avoid problems with texture interpolation
|
||||||
|
// grabbing pixels
|
||||||
|
// from adjacent items.
|
||||||
|
final int MARGIN = 1;
|
||||||
|
final int CELL_WIDTH = FB_WIDTH + 2 * MARGIN;
|
||||||
|
final int CELL_HEIGHT = FB_HEIGHT + 2 * MARGIN;
|
||||||
|
NativeImage result = new NativeImage(s * CELL_WIDTH, s * CELL_HEIGHT, true);
|
||||||
|
|
||||||
|
SpriteIndexWriter indexWriter = new SpriteIndexWriter(result.getWidth(), result.getHeight(), s, s, MARGIN);
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
for (ItemStack stack : stacks) {
|
||||||
|
// Render the item normally
|
||||||
|
fb.beginWrite(true);
|
||||||
|
GlStateManager.clear(GL12.GL_COLOR_BUFFER_BIT | GL12.GL_DEPTH_BUFFER_BIT, false);
|
||||||
|
client.getItemRenderer().renderInGui(stack, 0, 0);
|
||||||
|
fb.endWrite();
|
||||||
|
|
||||||
|
// Load the rendered item back into CPU memory
|
||||||
|
fb.beginRead();
|
||||||
|
nativeImage.loadFromTextureImage(0, false);
|
||||||
|
nativeImage.mirrorVertically();
|
||||||
|
fb.endRead();
|
||||||
|
|
||||||
|
// Copy it to the sprite-sheet
|
||||||
|
int xIdx = idx % s;
|
||||||
|
int xOut = xIdx * CELL_WIDTH + MARGIN;
|
||||||
|
int yIdx = idx / s;
|
||||||
|
int yOut = yIdx * CELL_HEIGHT + MARGIN;
|
||||||
|
idx++;
|
||||||
|
for (int y = 0; y < FB_HEIGHT; y++) {
|
||||||
|
for (int x = 0; x < FB_WIDTH; x++) {
|
||||||
|
result.setPixelColor(xOut + x, yOut + y, nativeImage.getPixelColor(x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add it to the index
|
||||||
|
indexWriter.add(stack, xIdx, yIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
result.writeFile(Paths.get("item_sheet.png"));
|
||||||
|
indexWriter.write(Paths.get("item_sheet.json"));
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
nativeImage.close();
|
||||||
|
result.close();
|
||||||
|
fb.delete();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package appeng.siteexport;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public final class ModVersion {
|
||||||
|
|
||||||
|
private static boolean initialized;
|
||||||
|
|
||||||
|
private static String modVersion;
|
||||||
|
|
||||||
|
private ModVersion() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String get() {
|
||||||
|
if (initialized) {
|
||||||
|
return modVersion;
|
||||||
|
}
|
||||||
|
initialized = true;
|
||||||
|
|
||||||
|
// GHETTO!
|
||||||
|
Process process = null;
|
||||||
|
Path tempOutput = null;
|
||||||
|
try {
|
||||||
|
tempOutput = Files.createTempFile("gitoutput", ".txt");
|
||||||
|
process = new ProcessBuilder("git", "rev-parse", "--short", "HEAD")
|
||||||
|
.redirectError(ProcessBuilder.Redirect.INHERIT).redirectInput(ProcessBuilder.Redirect.PIPE)
|
||||||
|
.redirectOutput(tempOutput.toFile()).start();
|
||||||
|
if (process.waitFor(10, TimeUnit.SECONDS)) {
|
||||||
|
String version = new String(Files.readAllBytes(tempOutput), StandardCharsets.UTF_8).trim();
|
||||||
|
if (version.isEmpty()) {
|
||||||
|
throw new Exception("Empty git output");
|
||||||
|
}
|
||||||
|
modVersion = version;
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
} finally {
|
||||||
|
if (tempOutput != null) {
|
||||||
|
try {
|
||||||
|
Files.deleteIfExists(tempOutput);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (process != null) {
|
||||||
|
try {
|
||||||
|
process.destroyForcibly();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
package appeng.siteexport;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.mojang.serialization.JsonOps;
|
||||||
|
|
||||||
|
import net.minecraft.MinecraftVersion;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.NbtOps;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
|
||||||
|
public class SpriteIndexWriter {
|
||||||
|
|
||||||
|
private final SpriteIndexJson spriteIndex = new SpriteIndexJson();
|
||||||
|
|
||||||
|
public SpriteIndexWriter(int width, int height, int rows, int cols, int margin) {
|
||||||
|
spriteIndex.modVersion = ModVersion.get();
|
||||||
|
spriteIndex.width = width;
|
||||||
|
spriteIndex.height = height;
|
||||||
|
spriteIndex.cols = cols;
|
||||||
|
spriteIndex.rows = rows;
|
||||||
|
spriteIndex.margin = margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(ItemStack stack, int x, int y) {
|
||||||
|
SpriteIndexEntryJson entry = new SpriteIndexEntryJson(stack, x, y);
|
||||||
|
spriteIndex.sprites.add(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(Path file) throws IOException {
|
||||||
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
try (Writer writer = Files.newBufferedWriter(file, StandardCharsets.UTF_8)) {
|
||||||
|
gson.toJson(spriteIndex, writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SpriteIndexJson {
|
||||||
|
|
||||||
|
private String generated;
|
||||||
|
|
||||||
|
private String gameVersion;
|
||||||
|
|
||||||
|
private String modVersion;
|
||||||
|
|
||||||
|
private String filename;
|
||||||
|
|
||||||
|
private int width;
|
||||||
|
|
||||||
|
private int height;
|
||||||
|
|
||||||
|
private int cols;
|
||||||
|
|
||||||
|
private int rows;
|
||||||
|
|
||||||
|
private int margin;
|
||||||
|
|
||||||
|
private List<SpriteIndexEntryJson> sprites = new ArrayList<>();
|
||||||
|
|
||||||
|
public SpriteIndexJson() {
|
||||||
|
generated = Instant.now().toString();
|
||||||
|
gameVersion = MinecraftVersion.create().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGenerated() {
|
||||||
|
return generated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGenerated(String generated) {
|
||||||
|
this.generated = generated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGameVersion() {
|
||||||
|
return gameVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGameVersion(String gameVersion) {
|
||||||
|
this.gameVersion = gameVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModVersion() {
|
||||||
|
return modVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModVersion(String modVersion) {
|
||||||
|
this.modVersion = modVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFilename() {
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFilename(String filename) {
|
||||||
|
this.filename = filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWidth() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWidth(int width) {
|
||||||
|
this.width = width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeight(int height) {
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCols() {
|
||||||
|
return cols;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCols(int cols) {
|
||||||
|
this.cols = cols;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRows() {
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRows(int rows) {
|
||||||
|
this.rows = rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SpriteIndexEntryJson> getSprites() {
|
||||||
|
return sprites;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMargin() {
|
||||||
|
return margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMargin(int margin) {
|
||||||
|
this.margin = margin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SpriteIndexEntryJson {
|
||||||
|
private String itemId;
|
||||||
|
private JsonElement tag;
|
||||||
|
private int x;
|
||||||
|
private int y;
|
||||||
|
|
||||||
|
public SpriteIndexEntryJson(ItemStack is, int x, int y) {
|
||||||
|
this.itemId = Registry.ITEM.getId(is.getItem()).toString();
|
||||||
|
if (is.hasTag()) {
|
||||||
|
this.tag = NbtOps.INSTANCE.convertMap(JsonOps.INSTANCE, is.getTag());
|
||||||
|
}
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getItemId() {
|
||||||
|
return itemId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonElement getTag() {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"id": "appliedenergistics2siteexport",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"name": "Applied Energistics 2 Site Export",
|
||||||
|
"description": "",
|
||||||
|
"authors": ["TeamAppliedEnergistics"],
|
||||||
|
"contact": {
|
||||||
|
"homepage": "https://ae-mod.info/",
|
||||||
|
"sources": "https://github.com/AppliedEnergistics/Applied-Energistics-2/"
|
||||||
|
},
|
||||||
|
"license": "LGPL",
|
||||||
|
"icon": "assets/appliedenergistics2/icon.png",
|
||||||
|
"environment": "client",
|
||||||
|
"entrypoints": {
|
||||||
|
"client": ["appeng.siteexport.Entrypoint"]
|
||||||
|
},
|
||||||
|
"depends": {
|
||||||
|
"fabricloader": ">=0.7.1",
|
||||||
|
"fabric": "*",
|
||||||
|
"minecraft": "1.16.x"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user