Compare commits

...
6 Commits
Author SHA1 Message Date
Jason Mitchell b999279656 More thread safe, again. (#30) 2025-05-04 08:08:02 +09:00
mts2200 1879ba2071 Improve NPE checks (#26) 2025-01-08 18:51:06 +00:00
Martin Robertz 9d600169ac update 2024-12-22 01:38:26 +01:00
charagarlnad 4e7eb37f3f use ZipFile instead of ZipInputStream in ClassDiscoverer (#25) 2024-12-20 15:18:04 +01:00
glowredman 22dfc1360e Allow colorful Tooltips (#24) 2024-11-13 06:47:10 +00:00
Maya 7bf5935f69 add issue templates 2024-11-11 04:15:39 -06:00
18 changed files with 214 additions and 83 deletions

No files matched your search

+62
View File
@@ -0,0 +1,62 @@
name: Report Bug
description: "Report a bug."
body:
- type: markdown
attributes:
value: "A bug/crash report with sufficient information and logs to reproduce and track down."
- type: input
id: discord
attributes:
label: Your GTNH Discord Username
description: Leave empty if you don't have one, but this will make it harder to contact you if we need additional info.
placeholder: "Example: Fake#1234"
- type: input
id: version
attributes:
label: Mod Version
description: "What version of the Mod are you using?"
placeholder: "Example: 1.0.0"
validations:
required: true
- type: textarea
id: report
attributes:
label: Bug Report
description: "Relevant information, as well as relevant logs attached such as `logs/fml-client-latest.log."
placeholder: "Example: https://mclo.gs/ OR submit the file to github by dragging it to this textbox."
validations:
required: true
- type: dropdown
id: java
attributes:
label: Java Version
description: What Java version are you using? It's worth mentioning that if you play on Java9+ you should try update to latest minor release (e.g. prefer Java 17.0.6 over 17.0.2) of that version.
options:
- Java 8
- Java 9
- Java 11
- Java 17
- Java 19
- Java 20
- Java 21
- Other (Please Specify)
validations:
required: true
- type: textarea
id: modlist
attributes:
label: Mod List or GTNH Pack Version
description: "List of mods, ideally a minimal reproducible set (can be retrieved from latest.log). If using GTNH please indicate pack version and any changed mods, not the entire modlist."
placeholder: "List of mods or GTNH Pack version goes here"
validations:
required: true
- type: checkboxes
id: final
attributes:
label: Final Checklist
description: Certify that you read things
options:
- label: "I have searched the issues and haven't found a similar issue."
required: true
@@ -0,0 +1,28 @@
name: Feature Request
description: "Request a feature."
body:
- type: markdown
attributes:
value: "Please use this form to request features. We ask you check if it was already requested though"
- type: input
id: discord
attributes:
label: Your GTNH Discord Username
description: Leave empty if you don't have one, but this will make it harder to contact you if we need additional info.
placeholder: "Example: Wumpus#1234"
- type: textarea
id: request
attributes:
label: Feature Request
description: "Relevant information, as well as relevant images"
placeholder: "Example: https://mclo.gs/ OR submit the file to github by dragging it to this textbox."
validations:
required: true
- type: checkboxes
id: final
attributes:
label: Final Checklist
description: Certify that you read things
options:
- label: "I have searched the issues and haven't found a similar issue."
required: true
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
+1
View File
@@ -1,4 +1,5 @@
// Add any additional repositiroes for your dependencies here
repositories {
mavenLocal()
}
+1 -1
View File
@@ -17,7 +17,7 @@ pluginManagement {
}
plugins {
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.27'
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.30'
}
@@ -1,13 +1,13 @@
package codechicken.core;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipFile;
import net.minecraft.launchwrapper.Launch;
@@ -114,21 +114,18 @@ public class ClassDiscoverer {
}
private void readFromZipFile(File file) throws IOException {
FileInputStream fileinputstream = new FileInputStream(file);
ZipInputStream zipinputstream = new ZipInputStream(fileinputstream);
do {
ZipEntry zipentry = zipinputstream.getNextEntry();
if (zipentry == null) {
break;
try (ZipFile zipFile = new ZipFile(file)) {
Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();
while (zipEntries.hasMoreElements()) {
ZipEntry zipentry = zipEntries.nextElement();
String fullname = zipentry.getName().replace('\\', '/');
int pos = fullname.lastIndexOf('/');
String name = pos == -1 ? fullname : fullname.substring(pos + 1);
if (!zipentry.isDirectory() && matcher.matches(name)) {
checkAddClass(fullname);
}
}
String fullname = zipentry.getName().replace('\\', '/');
int pos = fullname.lastIndexOf('/');
String name = pos == -1 ? fullname : fullname.substring(pos + 1);
if (!zipentry.isDirectory() && matcher.matches(name)) {
checkAddClass(fullname);
}
} while (true);
fileinputstream.close();
}
}
private void readFromDirectory(File directory, File basedirectory) {
@@ -59,7 +59,12 @@ public class RedirectorTransformer implements IClassTransformer, Opcodes {
"hasBrightness",
"brightness",
"side",
"lc"
"lc",
"normalAttrib",
"colourAttrib",
"lightCoordAttrib",
"sideAttrib",
"lightingAttrib"
);
Collections.addAll(redirectedSimpleMethods, "reset", "pullLightmap", "pushLightmap", "setDynamic", "draw");
+23 -13
View File
@@ -162,6 +162,11 @@ public class GuiDraw {
}
public static void drawMultilineTip(FontRenderer font, int x, int y, List<String> list) {
drawMultilineTip(font, x, y, list, 0xf0100010, 0xf0100010, 0x505000ff, 0x5028007F);
}
public static void drawMultilineTip(FontRenderer font, int x, int y, List<String> list, int bgStart, int bgEnd,
int borderStart, int borderEnd) {
if (list.isEmpty()) return;
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
@@ -189,7 +194,7 @@ public class GuiDraw {
y = (int) MathHelper.clip(y, 8, displaySize().height - 8 - h);
gui.incZLevel(300);
drawTooltipBox(x - 4, y - 4, w + 7, h + 7);
drawTooltipBox(x - 4, y - 4, w + 7, h + 7, bgStart, bgEnd, borderStart, borderEnd);
for (String s : list) {
ITooltipLineHandler line = getTipLine(s);
if (line != null) {
@@ -210,18 +215,23 @@ public class GuiDraw {
}
public static void drawTooltipBox(int x, int y, int w, int h) {
int bg = 0xf0100010;
drawGradientRect(x + 1, y, w - 1, 1, bg, bg);
drawGradientRect(x + 1, y + h, w - 1, 1, bg, bg);
drawGradientRect(x + 1, y + 1, w - 1, h - 1, bg, bg); // center
drawGradientRect(x, y + 1, 1, h - 1, bg, bg);
drawGradientRect(x + w, y + 1, 1, h - 1, bg, bg);
int grad1 = 0x505000ff;
int grad2 = 0x5028007F;
drawGradientRect(x + 1, y + 2, 1, h - 3, grad1, grad2);
drawGradientRect(x + w - 1, y + 2, 1, h - 3, grad1, grad2);
drawTooltipBox(x, y, w, h, 0xf0100010, 0xf0100010, 0x505000ff, 0x5028007F);
}
drawGradientRect(x + 1, y + 1, w - 1, 1, grad1, grad1);
drawGradientRect(x + 1, y + h - 1, w - 1, 1, grad2, grad2);
public static void drawTooltipBox(int x, int y, int w, int h, int bgStart, int bgEnd, int borderStart,
int borderEnd) {
// spotless:off
// draw background
drawGradientRect(x + 1, y, w - 1, 1, bgStart, bgStart); // top
drawGradientRect(x + 1, y + h, w - 1, 1, bgEnd, bgEnd); // bottom
drawGradientRect(x + 1, y + 1, w - 1, h - 1, bgStart, bgEnd); // center
drawGradientRect(x, y + 1, 1, h - 1, bgStart, bgEnd); // left
drawGradientRect(x + w, y + 1, 1, h - 1, bgStart, bgEnd); // right
// draw inner border
drawGradientRect(x + 1, y + 2, 1, h - 3, borderStart, borderEnd); // left
drawGradientRect(x + w - 1, y + 2, 1, h - 3, borderStart, borderEnd); // right
drawGradientRect(x + 1, y + 1, w - 1, 1, borderStart, borderStart); // top
drawGradientRect(x + 1, y + h - 1, w - 1, 1, borderEnd, borderEnd); // bottom
// spotless:on
}
}
@@ -81,8 +81,8 @@ public class LightModel implements CCRenderState.IVertexOperation {
public boolean load(CCRenderState state) {
if (!state.computeLighting) return false;
state.pipeline.addDependency(CCRenderState.normalAttrib);
state.pipeline.addDependency(CCRenderState.colourAttrib);
state.pipeline.addDependency(CCRenderState.normalAttrib());
state.pipeline.addDependency(CCRenderState.colourAttrib());
return true;
}
@@ -40,7 +40,7 @@ public class PlanarLightMatrix extends PlanarLightModel {
@Override
public boolean load(CCRenderState state) {
state.pipeline.addDependency(CCRenderState.sideAttrib);
state.pipeline.addDependency(CCRenderState.sideAttrib());
return true;
}
@@ -20,8 +20,8 @@ public class PlanarLightModel implements CCRenderState.IVertexOperation {
public boolean load(CCRenderState state) {
if (!state.computeLighting) return false;
state.pipeline.addDependency(CCRenderState.sideAttrib);
state.pipeline.addDependency(CCRenderState.colourAttrib);
state.pipeline.addDependency(CCRenderState.sideAttrib());
state.pipeline.addDependency(CCRenderState.colourAttrib());
return true;
}
@@ -40,7 +40,7 @@ public class SimpleBrightnessModel implements CCRenderState.IVertexOperation {
@Override
public boolean load(CCRenderState state) {
state.pipeline.addDependency(CCRenderState.sideAttrib);
state.pipeline.addDependency(CCRenderState.sideAttrib());
return true;
}
@@ -20,12 +20,12 @@ public class BlockRenderer {
@Override
public <T> T getAttributes(CCRenderState.VertexAttribute<T> attr) {
return attr == CCRenderState.lightCoordAttrib && lcComputed ? (T) lightCoords : null;
return attr == CCRenderState.lightCoordAttrib() && lcComputed ? (T) lightCoords : null;
}
@Override
public boolean hasAttribute(CCRenderState.VertexAttribute<?> attr) {
return attr == CCRenderState.sideAttrib || attr == CCRenderState.lightCoordAttrib && lcComputed;
return attr == CCRenderState.sideAttrib() || attr == CCRenderState.lightCoordAttrib() && lcComputed;
}
@Override
@@ -136,12 +136,12 @@ public class BlockRenderer {
@Override
public <T> T getAttributes(VertexAttribute<T> attr) {
return attr == CCRenderState.lightCoordAttrib ? (T) lightCoords : null;
return attr == CCRenderState.lightCoordAttrib() ? (T) lightCoords : null;
}
@Override
public boolean hasAttribute(VertexAttribute<?> attr) {
return attr == CCRenderState.sideAttrib || attr == CCRenderState.lightCoordAttrib;
return attr == CCRenderState.sideAttrib() || attr == CCRenderState.lightCoordAttrib();
}
@Override
@@ -164,7 +164,7 @@ public class BlockRenderer {
/**
* Renders faces of a block-like model based on a sideMask. Eg for side 2, verts 8-11 will be rendered
*
*
* @param sideMask A mask of faces not to render
*/
// public static void renderFaces(int sideMask) {
@@ -184,7 +184,7 @@ public class BlockRenderer {
/**
* Renders faces of a cuboid with texture coordinates mapped to match a standard minecraft block
*
*
* @param bounds The bounding cuboid to render
* @param sideMask A mask of faces not to render
*/
@@ -68,7 +68,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
}
public Vector3[] normals() {
return getAttributes(CCRenderState.normalAttrib);
return getAttributes(CCRenderState.normalAttrib());
}
@Override
@@ -102,7 +102,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Each pixel corresponds to one unit of position when generating the model
*
*
* @param i Vertex index to start generating at
* @param x1 The minX bound of the box
* @param y1 The minY bound of the box
@@ -195,7 +195,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Generates a box, uv mapped to be the same as a minecraft block with the same bounds
*
*
* @param i The vertex index to start generating at
* @param bounds The bounds of the block, 0 to 1
* @return The generated model. When rendering an icon will need to be supplied for the UV transformation.
@@ -222,7 +222,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Generates a box, uv mapped to be the same as a minecraft block with the same bounds
*
*
* @param i The vertex index to start generating at
* @param x1 minX
* @param y1 minY
@@ -311,7 +311,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Computes the normals of all faces in the model. Uses the cross product of the vectors along 2 sides of the face
*
*
* @param start The first vertex to generate normals for
* @param length The number of vertices to generate normals for. Note this must be a multiple of 3 for triangles or
* 4 for quads
@@ -321,7 +321,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
if (length % vp != 0 || start % vp != 0)
throw new IllegalArgumentException("Cannot generate normals across polygons");
Vector3[] normals = getOrAllocate(CCRenderState.normalAttrib);
Vector3[] normals = getOrAllocate(CCRenderState.normalAttrib());
for (int k = 0; k < length; k += vp) {
int i = k + start;
Vector3 diff1 = verts[i + 1].vec.copy().subtract(verts[i].vec);
@@ -336,14 +336,14 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Computes lighting using the normals add a light model If the model is rotated, the lighting will no longer be
* valid
*
*
* @return The model
*/
public CCModel computeLighting(LightModel light) {
Vector3[] normals = normals();
int[] colours = getAttributes(CCRenderState.lightingAttrib);
int[] colours = getAttributes(CCRenderState.lightingAttrib());
if (colours == null) {
colours = getOrAllocate(CCRenderState.lightingAttrib);
colours = getOrAllocate(CCRenderState.lightingAttrib());
Arrays.fill(colours, -1);
}
for (int k = 0; k < verts.length; k++) colours[k] = light.apply(colours[k], normals[k]);
@@ -351,18 +351,18 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
}
public CCModel setColour(int c) {
int[] colours = getOrAllocate(CCRenderState.colourAttrib);
int[] colours = getOrAllocate(CCRenderState.colourAttrib());
Arrays.fill(colours, c);
return this;
}
/**
* Computes the minecraft lighting coordinates for use with a LightMatrix
*
*
* @return The model
*/
public CCModel computeLightCoords() {
LC[] lcs = getOrAllocate(CCRenderState.lightCoordAttrib);
LC[] lcs = getOrAllocate(CCRenderState.lightCoordAttrib());
Vector3[] normals = normals();
for (int i = 0; i < verts.length; i++) lcs[i] = new LC().compute(verts[i].vec, normals[i]);
return this;
@@ -370,7 +370,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Averages all normals at the same position to produce a smooth lighting effect.
*
*
* @return The model
*/
public CCModel smoothNormals() {
@@ -461,7 +461,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Renders vertices start through start+length-1 of the model
*
*
* @param start The first vertex index to render
* @param end The vertex index to render until
* @param ops Operations to apply
@@ -520,7 +520,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Parses vertices, texture coords, normals and polygons from a WaveFront Obj file
*
*
* @param input An input stream to a obj file
* @param vertexMode The vertex mode to create the model for (GL_TRIANGLES or GL_QUADS)
* @param coordSystem The cooridnate system transformation to apply
@@ -624,7 +624,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Parses vertices, texture coords, normals and polygons from a WaveFront Obj file
*
*
* @param res The resource for the obj file
* @return A map of group names to models
*/
@@ -634,7 +634,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Parses vertices, texture coords, normals and polygons from a WaveFront Obj file
*
*
* @param res The resource for the obj file
* @param coordSystem The cooridnate system transformation to apply
* @return A map of group names to models
@@ -652,7 +652,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Parses vertices, texture coords, normals and polygons from a WaveFront Obj file
*
*
* @param res The resource for the obj file
* @param vertexMode The vertex mode to create the model for (GL_TRIANGLES or GL_QUADS)
* @param coordSystem The cooridnate system transformation to apply
@@ -678,7 +678,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
boolean hasNormals = polys.get(0)[2] > 0;
CCModel model = CCModel.newModel(vertexMode, polys.size());
if (hasNormals) model.getOrAllocate(CCRenderState.normalAttrib);
if (hasNormals) model.getOrAllocate(CCRenderState.normalAttrib());
for (int i = 0; i < polys.size(); i++) {
int[] ai = polys.get(i);
@@ -807,7 +807,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Generate models rotated to the other 5 sides of the block
*
*
* @param models An array of 6 models
* @param side The side of this model
* @param point The rotation point
@@ -822,7 +822,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Generate models rotated to the other 3 horizontal of the block
*
*
* @param models An array of 4 models
* @param side The side of this model
* @param point The rotation point
@@ -841,7 +841,7 @@ public class CCModel implements CCRenderState.IVertexSource, Copyable<CCModel> {
/**
* Generates copies of faces with clockwise vertices
*
*
* @return The model
*/
public static CCModel generateBackface(CCModel src, int srcpos, CCModel dst, int destpos, int length) {
@@ -169,7 +169,27 @@ public class CCRenderState {
}
}
public static VertexAttribute<Vector3[]> normalAttrib = new VertexAttribute<>() {
public static VertexAttribute<Vector3[]> normalAttrib() {
return instances.get().normalAttrib;
}
public static VertexAttribute<int[]> colourAttrib() {
return instances.get().colourAttrib;
}
public static VertexAttribute<LC[]> lightCoordAttrib() {
return instances.get().lightCoordAttrib;
}
public static VertexAttribute<int[]> sideAttrib() {
return instances.get().sideAttrib;
}
public static VertexAttribute<int[]> lightingAttrib() {
return instances.get().lightingAttrib;
}
public VertexAttribute<Vector3[]> normalAttrib = new VertexAttribute<>() {
private Vector3[] normalRef;
@@ -197,7 +217,7 @@ public class CCRenderState {
else state.setNormalInstance(Rotation.axes[state.side]);
}
};
public static VertexAttribute<int[]> colourAttrib = new VertexAttribute<>() {
public VertexAttribute<int[]> colourAttrib = new VertexAttribute<>() {
private int[] colourRef;
@@ -219,7 +239,7 @@ public class CCRenderState {
else state.setColourInstance(state.baseColour);
}
};
public static VertexAttribute<int[]> lightingAttrib = new VertexAttribute<>() {
public VertexAttribute<int[]> lightingAttrib = new VertexAttribute<>() {
private int[] colourRef;
@@ -245,7 +265,7 @@ public class CCRenderState {
state.setColourInstance(ColourRGBA.multiply(state.colour, colourRef[state.vertexIndex]));
}
};
public static VertexAttribute<int[]> sideAttrib = new VertexAttribute<>() {
public VertexAttribute<int[]> sideAttrib = new VertexAttribute<>() {
private int[] sideRef;
@@ -272,7 +292,7 @@ public class CCRenderState {
/**
* Uses the position of the lightmatrix to compute LC if not provided
*/
public static VertexAttribute<LC[]> lightCoordAttrib = new VertexAttribute<>() {
public VertexAttribute<LC[]> lightCoordAttrib = new VertexAttribute<>() {
private LC[] lcRef;
private final Vector3 vec = new Vector3(); // for computation
@@ -14,14 +14,14 @@ public abstract class Transformation extends ITransformation<Vector3, Transforma
/**
* Applies this transformation to a normal (doesn't translate)
*
*
* @param normal The normal to transform
*/
public abstract void applyN(Vector3 normal);
/**
* Applies this transformation to a matrix as a multiplication on the right hand side.
*
*
* @param mat The matrix to combine this transformation with
*/
public abstract void apply(Matrix4 mat);
@@ -39,14 +39,14 @@ public abstract class Transformation extends ITransformation<Vector3, Transforma
@Override
public boolean load(CCRenderState state) {
state.pipeline.addRequirement(CCRenderState.normalAttrib.operationID());
state.pipeline.addRequirement(CCRenderState.normalAttrib().operationID());
return !isRedundant();
}
@Override
public void operate(CCRenderState state) {
apply(state.vert.vec);
if (CCRenderState.normalAttrib.active) applyN(state.normal);
if (CCRenderState.normalAttrib().active) applyN(state.normal);
}
@Override
@@ -79,17 +79,25 @@ public class WorldExtensionManager {
@SubscribeEvent
public void onChunkWatch(Watch event) {
Chunk chunk = event.player.worldObj.getChunkFromChunkCoords(event.chunk.chunkXPos, event.chunk.chunkZPos);
for (WorldExtension extension : worldMap.get(event.player.worldObj))
extension.watchChunk(chunk, event.player);
WorldExtension[] extensions = worldMap.get(event.player.worldObj);
if (extensions != null) {
Chunk chunk = event.player.worldObj
.getChunkFromChunkCoords(event.chunk.chunkXPos, event.chunk.chunkZPos);
for (WorldExtension extension : extensions) extension.watchChunk(chunk, event.player);
}
}
@SubscribeEvent
@SideOnly(Side.CLIENT)
public void onChunkUnWatch(UnWatch event) {
Chunk chunk = event.player.worldObj.getChunkFromChunkCoords(event.chunk.chunkXPos, event.chunk.chunkZPos);
for (WorldExtension extension : worldMap.get(event.player.worldObj))
extension.unwatchChunk(chunk, event.player);
WorldExtension[] extensions = worldMap.get(event.player.worldObj);
if (extensions != null) {
Chunk chunk = event.player.worldObj
.getChunkFromChunkCoords(event.chunk.chunkXPos, event.chunk.chunkZPos);
for (WorldExtension extension : extensions) extension.unwatchChunk(chunk, event.player);
}
}
@SubscribeEvent
@@ -110,7 +118,7 @@ public class WorldExtensionManager {
}
private static boolean initialised;
private static ArrayList<WorldExtensionInstantiator> extensionIntialisers = new ArrayList<WorldExtensionInstantiator>();
private static ArrayList<WorldExtensionInstantiator> extensionIntialisers = new ArrayList<>();
public static void registerWorldExtension(WorldExtensionInstantiator init) {
if (!initialised) init();
@@ -125,7 +133,7 @@ public class WorldExtensionManager {
FMLCommonHandler.instance().bus().register(new WorldExtensionEventHandler());
}
private static HashMap<World, WorldExtension[]> worldMap = new HashMap<World, WorldExtension[]>();
private static HashMap<World, WorldExtension[]> worldMap = new HashMap<>();
private static void onWorldLoad(World world) {
WorldExtension[] extensions = new WorldExtension[extensionIntialisers.size()];