Skip to content

Commit ea8480b

Browse files
committed
Embed a heavily modified version of dragonfly into the multipart module.
1 parent 3cf2747 commit ea8480b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1807
-129
lines changed

multipart/build.gradle

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,19 @@ dependencies {
2626
implementation "org.slf4j:slf4j-api:1.8.0-beta4"
2727
implementation "org.apache.logging.log4j:log4j-slf4j18-impl:2.16.0"
2828
implementation 'com.google.guava:guava:33.0.0-jre'
29-
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.9'
29+
implementation group: 'com.google.code.gson', name: 'gson', version: '2.10.1'
3030
var log4jVersion = "2.20.0"
3131
implementation("org.apache.logging.log4j:log4j-core:${log4jVersion}")
3232
implementation("org.apache.logging.log4j:log4j-api:${log4jVersion}")
3333
implementation("org.apache.logging.log4j:log4j-1.2-api:${log4jVersion}")
34+
include(implementation("org.apache.commons:commons-lang3:3.12.0"))
3435

3536
modRuntimeOnly "objects:client:43db9b498cb67058d2e12d394e6507722e71bb45" // https://piston-data.mojang.com/v1/objects/43db9b498cb67058d2e12d394e6507722e71bb45/client.jar
3637
modImplementation "fabric-loader:fabric-loader:${project.loader_version}"
3738

3839
modImplementation "bta-halplibe:halplibe:${project.halplibe_version}"
3940
modImplementation "ModMenu:ModMenu:${project.mod_menu_version}"
40-
modImplementation "DragonFly:dragonfly:1.5.0-7.2-pre2"
41+
4142
}
4243

4344
java {

multipart/src/main/java/sunsetsatellite/catalyst/CatalystMultipart.java

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package sunsetsatellite.catalyst;
22

3+
import com.google.gson.Gson;
4+
import com.google.gson.GsonBuilder;
35
import net.fabricmc.api.ModInitializer;
46
import net.minecraft.core.block.Block;
57
import net.minecraft.core.block.tag.BlockTags;
@@ -14,10 +16,15 @@
1416
import net.minecraft.core.item.tag.ItemTags;
1517
import net.minecraft.core.item.tool.ItemToolPickaxe;
1618
import net.minecraft.core.sound.BlockSounds;
19+
import net.minecraft.core.util.helper.Side;
1720
import org.slf4j.Logger;
1821
import org.slf4j.LoggerFactory;
1922
import sunsetsatellite.catalyst.core.util.MpGuiEntry;
2023
import sunsetsatellite.catalyst.multipart.api.MultipartType;
24+
import sunsetsatellite.catalyst.multipart.api.impl.dragonfly.model.block.adapters.*;
25+
import sunsetsatellite.catalyst.multipart.api.impl.dragonfly.model.block.data.*;
26+
import sunsetsatellite.catalyst.multipart.api.impl.dragonfly.vector.Vector3f;
27+
import sunsetsatellite.catalyst.multipart.api.impl.dragonfly.vector.Vector3fJsonAdapter;
2128
import sunsetsatellite.catalyst.multipart.block.BlockCarpenterWorkbench;
2229
import sunsetsatellite.catalyst.multipart.block.BlockMultipart;
2330
import sunsetsatellite.catalyst.multipart.block.entity.TileEntityCarpenterWorkbench;
@@ -60,6 +67,17 @@ public class CatalystMultipart implements ModInitializer, GameStartEntrypoint, R
6067
public static final Tag<Block> CAN_BE_MULTIPART = Tag.of("can_be_multipart");
6168
public static final HashMap<String,Tag<Block>> TYPE_TAGS = new HashMap<>();
6269

70+
public static final Gson GSON = new GsonBuilder()
71+
.registerTypeAdapter(Vector3f.class, new Vector3fJsonAdapter())
72+
.registerTypeAdapter(ModelData.class, new ModelDataJsonAdapter())
73+
.registerTypeAdapter(PositionData.class, new PositionDataJsonAdapter())
74+
.registerTypeAdapter(CubeData.class, new CubeDataJsonAdapter())
75+
.registerTypeAdapter(FaceData.class, new FaceDataJsonAdapter())
76+
.registerTypeAdapter(RotationData.class, new RotationDataJsonAdapter())
77+
.create();
78+
public static final Side[] sides = new Side[]{Side.BOTTOM, Side.TOP, Side.NORTH, Side.SOUTH, Side.WEST, Side.EAST};
79+
public static String renderState = "gui";
80+
6381
static {
6482
List<Field> blockFields = Arrays.stream(CatalystMultipart.class.getDeclaredFields()).filter((F) -> Block.class.isAssignableFrom(F.getType())).collect(Collectors.toList());
6583
List<Field> itemFields = Arrays.stream(CatalystMultipart.class.getDeclaredFields()).filter((F) -> Item.class.isAssignableFrom(F.getType())).collect(Collectors.toList());
@@ -129,7 +147,6 @@ public class CatalystMultipart implements ModInitializer, GameStartEntrypoint, R
129147
.setResistance(20)
130148
.setBlockModel(block ->
131149
new MultipartBlockModelBuilder(MOD_ID)
132-
.setBlockModel("cover.json")
133150
.build(block))
134151
.setTextures("minecraft:block/stone")
135152
.setTags(BlockTags.NOT_IN_CREATIVE_MENU)
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
package sunsetsatellite.catalyst.multipart.api;
22

3-
import org.useless.dragonfly.helper.ModelHelper;
4-
import org.useless.dragonfly.model.block.data.CubeData;
5-
import org.useless.dragonfly.model.block.processed.ModernBlockModel;
6-
import org.useless.dragonfly.utilities.NamespaceId;
7-
import sunsetsatellite.catalyst.multipart.block.model.ModernMultipartBlockModel;
8-
93
import java.util.HashMap;
104

115
public class MultipartType {
@@ -36,23 +30,4 @@ public MultipartType(String name, String model, int thickness, int cubesPerSide)
3630
public static final MultipartType HOLLOW_PANEL = new MultipartType("hollow_panel", "hollow_panel",4, 4);
3731
public static final MultipartType HOLLOW_SLAB = new MultipartType("hollow_slab", "hollow_slab",8, 4);
3832
//public static final MultipartType PILLAR = new MultipartType("pillar", "pillar",16, 1);
39-
40-
public static ModernBlockModel getOrCreateBlockModel(String modId, Multipart multipart) {
41-
NamespaceId namespaceId = new NamespaceId(modId, multipart.type.model+"_"+multipart.block.getKey().replace("tile","").replace(modId,"").replace(".","_").toLowerCase());
42-
if(multipart.specifiedSideOnly){
43-
namespaceId = new NamespaceId(modId, multipart.type.model+"_"+multipart.block.getKey().replace("tile","").replace(modId,"").replace(".","_").toLowerCase()+"_"+multipart.side.name().toLowerCase());
44-
}
45-
NamespaceId modelId = new NamespaceId(modId, multipart.type.model);
46-
if (ModelHelper.registeredModels.containsKey(namespaceId)){
47-
return ModelHelper.registeredModels.get(namespaceId);
48-
}
49-
ModernMultipartBlockModel model = new ModernMultipartBlockModel(modelId, multipart.textures);
50-
for (CubeData cube : model.getModelData().elements) {
51-
cube.faces.forEach((K,V)->{
52-
V.texture = "#"+K;
53-
});
54-
}
55-
ModelHelper.registeredModels.put(namespaceId, model);
56-
return model;
57-
}
5833
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package sunsetsatellite.catalyst.multipart.api.impl.dragonfly;
2+
3+
public class NamespaceId {
4+
public static final String coreNamespaceId = "minecraft"; // This is also used as the default namespace if one is not provided
5+
private final String namespace;
6+
private final String id;
7+
public NamespaceId(String namespace, String id){
8+
this.namespace = namespace.toLowerCase();
9+
if (!namespace.equals(this.namespace)) throw new IllegalArgumentException("Namespaces must be lowercase! '" + namespace + "'");
10+
this.id = id.toLowerCase();
11+
if (!id.equals(this.id)) throw new IllegalArgumentException("ID must be lowercase! '" + id + "'");
12+
}
13+
public String getNamespace(){
14+
return namespace;
15+
}
16+
public String getId(){
17+
return id;
18+
}
19+
public String toString(){
20+
return (namespace + ":" + id);
21+
}
22+
23+
@Override
24+
public boolean equals(Object obj) {
25+
if (obj instanceof String){
26+
return this.toString().equals(((String) obj).toLowerCase());
27+
}
28+
if (obj instanceof NamespaceId){
29+
return this.namespace.equals(((NamespaceId) obj).namespace) && this.id.equals(((NamespaceId) obj).id);
30+
}
31+
return super.equals(obj);
32+
}
33+
@Override
34+
public int hashCode()
35+
{
36+
return toString().hashCode();
37+
}
38+
39+
public static NamespaceId idFromString(String formattedString){
40+
String formattedStringLower = formattedString.toLowerCase();
41+
if (!formattedString.equals(formattedStringLower)) throw new IllegalArgumentException("All Namespaces and IDs must be lowercase! '" + formattedString + "'");
42+
String namespace = coreNamespaceId;
43+
String id;
44+
if (formattedStringLower.contains(":")){
45+
namespace = formattedStringLower.split(":")[0];
46+
id = formattedStringLower.split(":")[1];
47+
} else {
48+
id = formattedStringLower;
49+
}
50+
51+
if (namespace.contains(":") || namespace.isEmpty()) throw new IllegalArgumentException("Namespace '" + namespace + "' is not formatted correctly!");
52+
if (id.contains(":") || id.isEmpty()) throw new IllegalArgumentException("Id '" + id + "' is not formatted correctly!");
53+
54+
return new NamespaceId(namespace, id);
55+
}
56+
}
57+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package sunsetsatellite.catalyst.multipart.api.impl.dragonfly;
2+
3+
4+
import com.google.gson.JsonArray;
5+
import net.fabricmc.loader.api.FabricLoader;
6+
import net.minecraft.client.Minecraft;
7+
import net.minecraft.core.data.DataLoader;
8+
import net.minecraft.core.util.helper.Axis;
9+
import sunsetsatellite.catalyst.multipart.api.impl.dragonfly.vector.Vector3f;
10+
11+
import java.io.InputStream;
12+
import java.lang.reflect.Field;
13+
import java.util.Objects;
14+
import java.util.Random;
15+
16+
public class Utilities {
17+
public static final float COMPARE_CONST = 0.001f;
18+
public static String writeFields(Class<?> clazz){
19+
Field[] fields = clazz.getFields();
20+
StringBuilder builder = new StringBuilder();
21+
for (int i = 0; i < fields.length; i++) {
22+
Field field = fields[i];
23+
builder.append(field.getName()).append(": ").append(field.getClass().cast(field));
24+
if (i < fields.length-1){
25+
builder.append("\n");
26+
}
27+
}
28+
return builder.toString();
29+
}
30+
public static String tabBlock(String string, int tabAmount){
31+
StringBuilder builder = new StringBuilder();
32+
for (String line: string.split("\n")) {
33+
builder.append(tabString(tabAmount)).append(line).append("\n");
34+
}
35+
return builder.toString();
36+
}
37+
public static String tabString(int tabAmount){
38+
StringBuilder builder = new StringBuilder();
39+
for (int i = 0; i < tabAmount; i++) {
40+
builder.append("\t");
41+
}
42+
return builder.toString();
43+
}
44+
public static boolean equalFloats(float a, float b){
45+
return Math.abs(Float.compare(a, b)) < COMPARE_CONST;
46+
}
47+
public static Vector3f rotatePoint(Vector3f point, Vector3f origin, Axis axis, float angle){
48+
switch (axis){
49+
case X:
50+
return point.rotateAroundX(origin, -angle);
51+
case Y:
52+
return point.rotateAroundY(origin, angle);
53+
case Z:
54+
return point.rotateAroundZ(origin, -angle);
55+
}
56+
throw new RuntimeException("Axis " + axis + " Is not 'X', 'Y', or 'Z'!");
57+
}
58+
59+
/**
60+
* Tries to load resource from multiple classes, if they all fail it throws an exception
61+
*/
62+
public static InputStream getResourceAsStream(String path){
63+
try {
64+
Class.forName("net.minecraft.client.Minecraft");
65+
try {
66+
return Objects.requireNonNull(Minecraft.getMinecraft(Utilities.class).texturePackList.getResourceAsStream(path));
67+
} catch (Exception ignored){}
68+
} catch (Exception ignored) {}
69+
try {
70+
return Objects.requireNonNull(DataLoader.class.getResourceAsStream(path));
71+
} catch (Exception ignored){}
72+
try {
73+
return Objects.requireNonNull(Utilities.class.getResourceAsStream(path));
74+
} catch (Exception ignored){}
75+
try {
76+
return Objects.requireNonNull(FabricLoader.getInstance().getClass().getResourceAsStream(path));
77+
} catch (Exception ignored){}
78+
try {
79+
return Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResourceAsStream(path));
80+
} catch (Exception ignored){}
81+
throw new RuntimeException("Resource at '" + path + "' returned null! Does this file exist?");
82+
}
83+
public static float[] floatArrFromJsonArr(JsonArray arr){
84+
float[] result = new float[arr.size()];
85+
for (int i = 0; i < arr.size(); i++) {
86+
result[i] = arr.get(i).getAsFloat();
87+
}
88+
return result;
89+
}
90+
public static double[] doubleArrFromJsonArr(JsonArray arr){
91+
double[] result = new double[arr.size()];
92+
for (int i = 0; i < arr.size(); i++) {
93+
result[i] = arr.get(i).getAsDouble();
94+
}
95+
return result;
96+
}
97+
98+
public static boolean equalFloat(double a, double b) {
99+
return Math.abs(a - b) < 1e-9;
100+
}
101+
public static Random getRandomFromPos(int x, int y, int z){
102+
Random rand = new Random(0);
103+
long l1 = rand.nextLong() / 2L * 2L + 1L;
104+
long l2 = rand.nextLong() / 2L * 2L + 1L;
105+
long l3 = rand.nextLong() / 2L * 2L + 1L;
106+
rand.setSeed((long)x * l1 + (long)z * l2 + y * l3);
107+
return rand;
108+
}
109+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package sunsetsatellite.catalyst.multipart.api.impl.dragonfly.helper;
2+
3+
import com.google.gson.stream.JsonReader;
4+
import sunsetsatellite.catalyst.CatalystMultipart;
5+
import sunsetsatellite.catalyst.multipart.api.Multipart;
6+
import sunsetsatellite.catalyst.multipart.api.impl.dragonfly.NamespaceId;
7+
import sunsetsatellite.catalyst.multipart.api.impl.dragonfly.Utilities;
8+
import sunsetsatellite.catalyst.multipart.api.impl.dragonfly.model.block.data.CubeData;
9+
import sunsetsatellite.catalyst.multipart.api.impl.dragonfly.model.block.data.ModelData;
10+
import sunsetsatellite.catalyst.multipart.block.model.ModernMultipartBlockModel;
11+
12+
import java.io.BufferedReader;
13+
import java.io.InputStreamReader;
14+
import java.util.*;
15+
16+
public class ModelHelper {
17+
public static final Map<NamespaceId, ModelData> modelDataFiles = new HashMap<>();
18+
public static final Map<NamespaceId, ModernMultipartBlockModel> registeredModels = new HashMap<>();
19+
20+
/**
21+
* Place mod models in the <i>assets/modid/models/block/</i> directory for them to be seen.
22+
*/
23+
public static ModernMultipartBlockModel getOrCreateBlockModel(String modId, Multipart multipart) {
24+
NamespaceId namespaceId = new NamespaceId(modId, multipart.type.model+"_"+multipart.meta+multipart.block.getKey().replace("tile","").replace(modId,"").replace(".","_").toLowerCase());
25+
if(multipart.specifiedSideOnly){
26+
namespaceId = new NamespaceId(modId, multipart.type.model+"_"+multipart.meta+multipart.block.getKey().replace("tile","").replace(modId,"").replace(".","_").toLowerCase()+"_"+multipart.side.name().toLowerCase());
27+
}
28+
NamespaceId modelId = new NamespaceId(modId, multipart.type.model);
29+
if (ModelHelper.registeredModels.containsKey(namespaceId)){
30+
return registeredModels.get(namespaceId);
31+
}
32+
ModernMultipartBlockModel model = new ModernMultipartBlockModel(modelId, multipart.textures);
33+
for (CubeData cube : model.getModelData().elements) {
34+
cube.faces.forEach((K,V)->{
35+
V.texture = "#"+K;
36+
});
37+
}
38+
ModelHelper.registeredModels.put(namespaceId, model);
39+
return model;
40+
}
41+
42+
public static ModelData loadBlockModel(NamespaceId namespaceId){
43+
if (modelDataFiles.containsKey(namespaceId)){
44+
return modelDataFiles.get(namespaceId);
45+
}
46+
return Objects.requireNonNull(createBlockModel(namespaceId));
47+
}
48+
private static ModelData createBlockModel(NamespaceId namespaceId){
49+
JsonReader reader = new JsonReader(new BufferedReader(new InputStreamReader(Utilities.getResourceAsStream(getModelLocation(namespaceId)))));
50+
ModelData modelData = CatalystMultipart.GSON.fromJson(reader, ModelData.class);
51+
modelDataFiles.put(namespaceId, modelData);
52+
return modelData;
53+
}
54+
55+
public static String getModelLocation(NamespaceId namespaceId){
56+
String modelSource = namespaceId.getId();
57+
if (!modelSource.contains(".json")){
58+
modelSource += ".json";
59+
}
60+
return "/assets/" + namespaceId.getNamespace() + "/models/" + modelSource;
61+
}
62+
public static String getBlockStateLocation(NamespaceId namespaceId){
63+
String modelSource = namespaceId.getId();
64+
if (!modelSource.contains(".json")){
65+
modelSource += ".json";
66+
}
67+
return "/assets/" + namespaceId.getNamespace() + "/blockstates/" + modelSource;
68+
}
69+
public static void refreshModels(){
70+
Set<NamespaceId> blockModelDataKeys = new HashSet<>(modelDataFiles.keySet());
71+
72+
for (NamespaceId modelDataKey : blockModelDataKeys){
73+
createBlockModel(modelDataKey);
74+
}
75+
for (ModernMultipartBlockModel model : registeredModels.values()){
76+
model.refreshModel();
77+
}
78+
}
79+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package sunsetsatellite.catalyst.multipart.api.impl.dragonfly.model.block.adapters;
2+
3+
4+
import com.google.gson.*;
5+
import org.apache.commons.lang3.NotImplementedException;
6+
import sunsetsatellite.catalyst.CatalystMultipart;
7+
import sunsetsatellite.catalyst.multipart.api.impl.dragonfly.Utilities;
8+
import sunsetsatellite.catalyst.multipart.api.impl.dragonfly.model.block.data.CubeData;
9+
import sunsetsatellite.catalyst.multipart.api.impl.dragonfly.model.block.data.FaceData;
10+
import sunsetsatellite.catalyst.multipart.api.impl.dragonfly.model.block.data.RotationData;
11+
12+
import java.lang.reflect.Type;
13+
import java.util.Map;
14+
15+
public class CubeDataJsonAdapter implements JsonDeserializer<CubeData>, JsonSerializer<CubeData> {
16+
@Override
17+
public CubeData deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
18+
JsonObject obj = json.getAsJsonObject();
19+
CubeData data = new CubeData();
20+
21+
if (obj.has("from")) data.from = Utilities.floatArrFromJsonArr(obj.getAsJsonArray("from"));
22+
if (obj.has("to")) data.to = Utilities.floatArrFromJsonArr(obj.getAsJsonArray("to"));
23+
if (obj.has("rotation")) data.rotation = CatalystMultipart.GSON.fromJson(obj.getAsJsonObject("rotation"), RotationData.class);
24+
if (obj.has("shade")) data.shade = obj.get("shade").getAsBoolean();
25+
if (obj.has("faces")){
26+
for (Map.Entry<String, JsonElement> e : obj.getAsJsonObject("faces").asMap().entrySet()){
27+
data.faces.put(e.getKey(), CatalystMultipart.GSON.fromJson(e.getValue(), FaceData.class));
28+
}
29+
}
30+
return data;
31+
}
32+
33+
@Override
34+
public JsonElement serialize(CubeData src, Type typeOfSrc, JsonSerializationContext context) {
35+
throw new NotImplementedException();
36+
}
37+
}

0 commit comments

Comments
 (0)