builder) {
- super.fillStateContainer(builder);
- builder.add(HORIZONTAL_FACING);
- builder.add(BURNING);
- }
-
- /**
- * Returns the blockstate with the given rotation from the passed blockstate.
- * If inapplicable, returns the passed blockstate.
- *
- * @deprecated call via {@link BlockState#rotate(Rotation)} whenever possible. Implementing/overriding is fine.
- */
- @Override
- public BlockState rotate(BlockState state, Rotation rot) {
- return state.with(HORIZONTAL_FACING, rot.rotate(state.get(HORIZONTAL_FACING)));
- }
-
- /**
- * Returns the blockstate with the given mirror of the passed blockstate.
- * If inapplicable, returns the passed blockstate.
- *
- * @deprecated call via {@link BlockState#mirror(Mirror)} whenever possible. Implementing/overriding is fine.
- */
- @Override
- public BlockState mirror(BlockState state, Mirror mirrorIn) {
- return state.rotate(mirrorIn.toRotation(state.get(HORIZONTAL_FACING)));
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/block/package-info.java b/src/main/java/io/github/cadiboo/examplemod/block/package-info.java
new file mode 100644
index 0000000..42c492f
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/block/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Contains our mod's {@link net.minecraft.block.Block}s
+ */
+
+package io.github.cadiboo.examplemod.block;
diff --git a/src/main/java/io/github/cadiboo/examplemod/client/ClientEventSubscriber.java b/src/main/java/io/github/cadiboo/examplemod/client/ClientEventSubscriber.java
new file mode 100644
index 0000000..9f13dde
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/client/ClientEventSubscriber.java
@@ -0,0 +1,92 @@
+package io.github.cadiboo.examplemod.client;
+
+import com.google.common.base.Preconditions;
+import io.github.cadiboo.examplemod.client.render.tileentity.RenderExampleTileEntity;
+import io.github.cadiboo.examplemod.init.ModBlocks;
+import io.github.cadiboo.examplemod.init.ModItems;
+import io.github.cadiboo.examplemod.tileentity.TileEntityExampleTileEntity;
+import io.github.cadiboo.examplemod.util.ModReference;
+import net.minecraft.block.Block;
+import net.minecraft.client.renderer.block.model.ModelResourceLocation;
+import net.minecraft.item.Item;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.client.event.ModelRegistryEvent;
+import net.minecraftforge.client.event.TextureStitchEvent;
+import net.minecraftforge.client.model.ModelLoader;
+import net.minecraftforge.fml.client.registry.ClientRegistry;
+import net.minecraftforge.fml.common.Mod;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import javax.annotation.Nonnull;
+
+import static net.minecraftforge.fml.relauncher.Side.CLIENT;
+
+/**
+ * Subscribe to events that should be handled on the PHYSICAL CLIENT in this class
+ *
+ * @author Cadiboo
+ */
+@Mod.EventBusSubscriber(modid = ModReference.MOD_ID, value = CLIENT)
+public final class ClientEventSubscriber {
+
+ private static final Logger LOGGER = LogManager.getLogger();
+ private static final String DEFAULT_VARIANT = "normal";
+
+ @SubscribeEvent
+ public static void onRegisterModelsEvent(@Nonnull final ModelRegistryEvent event) {
+
+ registerTileEntitySpecialRenderers();
+ LOGGER.debug("Registered tile entity special renderers");
+
+ registerEntityRenderers();
+ LOGGER.debug("Registered entity renderers");
+
+ // Registration can be automated like this
+ // But when you're learning its better to manually register your objects
+// ForgeRegistries.BLOCKS.getValuesCollection().stream()
+// .filter(block -> block.getRegistryName().getNamespace().equals(MOD_ID))
+// .forEach(ClientEventSubscriber::registerItemBlockModel);
+
+ registerItemBlockModel(ModBlocks.EXAMPLE_BLOCK);
+ registerItemBlockModel(ModBlocks.EXAMPLE_ORE);
+ registerItemBlockModel(ModBlocks.EXAMPLE_TILE_ENTITY);
+
+ registerItemModel(ModItems.EXAMPLE_ITEM);
+ registerItemModel(ModItems.EXAMPLE_INGOT);
+
+ LOGGER.debug("Registered models");
+
+ }
+
+ private static void registerTileEntitySpecialRenderers() {
+ ClientRegistry.bindTileEntitySpecialRenderer(TileEntityExampleTileEntity.class, new RenderExampleTileEntity());
+ }
+
+ private static void registerEntityRenderers() {
+// RenderingRegistry.registerEntityRenderingHandler(Entity___.class, renderManager -> new Entity___Renderer(renderManager));
+ }
+
+ private static void registerItemModel(@Nonnull final Item item) {
+ Preconditions.checkNotNull(item, "Item cannot be null!");
+ final ResourceLocation registryName = item.getRegistryName();
+ Preconditions.checkNotNull(registryName, "Item Registry Name cannot be null!");
+ ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(item.getRegistryName(), DEFAULT_VARIANT));
+ }
+
+ private static void registerItemBlockModel(@Nonnull final Block block) {
+ Preconditions.checkNotNull(block, "Block cannot be null!");
+ final ResourceLocation registryName = block.getRegistryName();
+ Preconditions.checkNotNull(registryName, "Block Registry Name cannot be null!");
+ ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 0, new ModelResourceLocation(block.getRegistryName(), DEFAULT_VARIANT));
+ }
+
+ @SubscribeEvent
+ public static void onTextureStitchEvent(@Nonnull final TextureStitchEvent event) {
+ // register texture for example tile entity
+ final ResourceLocation registryName = ModBlocks.EXAMPLE_TILE_ENTITY.getRegistryName();
+ event.getMap().registerSprite(new ResourceLocation(registryName.getNamespace(), "block/" + registryName.getPath()));
+ }
+
+}
diff --git a/src/main/java/io/github/cadiboo/examplemod/client/ClientForgeEventSubscriber.java b/src/main/java/io/github/cadiboo/examplemod/client/ClientForgeEventSubscriber.java
deleted file mode 100644
index 1257594..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/client/ClientForgeEventSubscriber.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package io.github.cadiboo.examplemod.client;
-
-import io.github.cadiboo.examplemod.ExampleMod;
-import net.minecraftforge.api.distmarker.Dist;
-import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
-
-/**
- * Subscribe to events from the FORGE EventBus that should be handled on the PHYSICAL CLIENT side in this class
- *
- * @author Cadiboo
- */
-@EventBusSubscriber(modid = ExampleMod.MODID, bus = EventBusSubscriber.Bus.FORGE, value = Dist.CLIENT)
-public final class ClientForgeEventSubscriber {
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/client/ClientModEventSubscriber.java b/src/main/java/io/github/cadiboo/examplemod/client/ClientModEventSubscriber.java
deleted file mode 100644
index 5b288b4..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/client/ClientModEventSubscriber.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package io.github.cadiboo.examplemod.client;
-
-import io.github.cadiboo.examplemod.ExampleMod;
-import io.github.cadiboo.examplemod.client.gui.ElectricFurnaceScreen;
-import io.github.cadiboo.examplemod.client.gui.HeatCollectorScreen;
-import io.github.cadiboo.examplemod.client.gui.ModFurnaceScreen;
-import io.github.cadiboo.examplemod.client.render.entity.WildBoarRenderer;
-import io.github.cadiboo.examplemod.client.render.tileentity.ElectricFurnaceTileEntityRenderer;
-import io.github.cadiboo.examplemod.client.render.tileentity.MiniModelTileEntityRenderer;
-import io.github.cadiboo.examplemod.init.ModContainerTypes;
-import io.github.cadiboo.examplemod.init.ModEntityTypes;
-import io.github.cadiboo.examplemod.init.ModTileEntityTypes;
-import net.minecraft.client.gui.ScreenManager;
-import net.minecraftforge.api.distmarker.Dist;
-import net.minecraftforge.eventbus.api.SubscribeEvent;
-import net.minecraftforge.fml.DeferredWorkQueue;
-import net.minecraftforge.fml.client.registry.ClientRegistry;
-import net.minecraftforge.fml.client.registry.RenderingRegistry;
-import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
-import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-/**
- * Subscribe to events from the MOD EventBus that should be handled on the PHYSICAL CLIENT side in this class
- *
- * @author Cadiboo
- */
-@EventBusSubscriber(modid = ExampleMod.MODID, bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
-public final class ClientModEventSubscriber {
-
- private static final Logger LOGGER = LogManager.getLogger(ExampleMod.MODID + " Client Mod Event Subscriber");
-
- /**
- * We need to register our renderers on the client because rendering code does not exist on the server
- * and trying to use it on a dedicated server will crash the game.
- *
- * This method will be called by Forge when it is time for the mod to do its client-side setup
- * This method will always be called after the Registry events.
- * This means that all Blocks, Items, TileEntityTypes, etc. will all have been registered already
- */
- @SubscribeEvent
- public static void onFMLClientSetupEvent(final FMLClientSetupEvent event) {
-
- // Register TileEntity Renderers
- ClientRegistry.bindTileEntityRenderer(ModTileEntityTypes.MINI_MODEL.get(), MiniModelTileEntityRenderer::new);
- ClientRegistry.bindTileEntityRenderer(ModTileEntityTypes.ELECTRIC_FURNACE.get(), ElectricFurnaceTileEntityRenderer::new);
- LOGGER.debug("Registered TileEntity Renderers");
-
- // Register Entity Renderers
- RenderingRegistry.registerEntityRenderingHandler(ModEntityTypes.WILD_BOAR.get(), WildBoarRenderer::new);
- LOGGER.debug("Registered Entity Renderers");
-
- // Register ContainerType Screens
- // ScreenManager.registerFactory is not safe to call during parallel mod loading so we queue it to run later
- DeferredWorkQueue.runLater(() -> {
- ScreenManager.registerFactory(ModContainerTypes.HEAT_COLLECTOR.get(), HeatCollectorScreen::new);
- ScreenManager.registerFactory(ModContainerTypes.ELECTRIC_FURNACE.get(), ElectricFurnaceScreen::new);
- ScreenManager.registerFactory(ModContainerTypes.MOD_FURNACE.get(), ModFurnaceScreen::new);
- LOGGER.debug("Registered ContainerType Screens");
- });
-
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/client/ClientProxy.java b/src/main/java/io/github/cadiboo/examplemod/client/ClientProxy.java
new file mode 100644
index 0000000..8d7dba6
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/client/ClientProxy.java
@@ -0,0 +1,30 @@
+package io.github.cadiboo.examplemod.client;
+
+import io.github.cadiboo.examplemod.ExampleMod;
+import io.github.cadiboo.examplemod.util.IProxy;
+import net.minecraft.client.resources.I18n;
+import net.minecraftforge.fml.relauncher.Side;
+
+/**
+ * The version of IProxy that gets injected into {@link ExampleMod#proxy} on a PHYSICAL CLIENT
+ *
+ * @author Cadiboo
+ */
+public final class ClientProxy implements IProxy {
+
+ @Override
+ public String localize(final String unlocalized) {
+ return this.localizeAndFormat(unlocalized);
+ }
+
+ @Override
+ public String localizeAndFormat(final String unlocalized, final Object... args) {
+ return I18n.format(unlocalized, args);
+ }
+
+ @Override
+ public Side getPhysicalSide() {
+ return Side.CLIENT;
+ }
+
+}
diff --git a/src/main/java/io/github/cadiboo/examplemod/client/ClientUtil.java b/src/main/java/io/github/cadiboo/examplemod/client/ClientUtil.java
new file mode 100644
index 0000000..027b92f
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/client/ClientUtil.java
@@ -0,0 +1,381 @@
+package io.github.cadiboo.examplemod.client;
+
+import net.minecraft.block.state.IBlockState;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.BufferBuilder;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.client.renderer.block.model.BakedQuad;
+import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import net.minecraft.crash.CrashReport;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.util.ReportedException;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.math.Vec3d;
+import net.minecraftforge.client.model.pipeline.LightUtil;
+import net.minecraftforge.client.model.pipeline.VertexBufferConsumer;
+import net.minecraftforge.fml.relauncher.ReflectionHelper;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+import org.lwjgl.util.vector.Matrix4f;
+import org.lwjgl.util.vector.Vector3f;
+import org.lwjgl.util.vector.Vector4f;
+
+import javax.annotation.Nonnull;
+import java.lang.reflect.Field;
+import java.nio.IntBuffer;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+/**
+ * Util that is only used on the Physical Client i.e. Rendering code
+ *
+ * @author Cadiboo
+ * @author V0idW4lk3r
+ */
+@SuppressWarnings("WeakerAccess")
+@SideOnly(Side.CLIENT)
+public final class ClientUtil {
+
+ /**
+ * A vertex definition for a simple 2-dimensional quad defined in counter-clockwise order with the top-left origin.
+ */
+ public static final Vector4f[] SIMPLE_QUAD = {
+ new Vector4f(1, 1, 0, 0),
+ new Vector4f(1, 0, 0, 0),
+ new Vector4f(0, 0, 0, 0),
+ new Vector4f(0, 1, 0, 0)
+ };
+ // add or subtract from the sprites UV location to remove transparent lines in between textures
+ private static final float UV_CORRECT = 1F / 16F / 10000;
+ /**
+ * A field reference to the rawIntBuffer of the BufferBuilder class. Need reflection since the field is private.
+ */
+// private static final Field bufferBuilder_rawIntBuffer = ReflectionHelper.findField(BufferBuilder.class, "rawIntBuffer", "field_178999_b");
+ // use the old (Class, String...) instead of the new (Class, String, String) for backwards compatibility
+ //TODO: change back to (Class, String, String) soon
+ private static final Field bufferBuilder_rawIntBuffer = ReflectionHelper.findField(BufferBuilder.class, "rawIntBuffer", "field_178999_b", "field_178999_b");
+
+
+ /**
+ * Rotation algorithm Taken off Max_the_Technomancer from here
+ *
+ * @param face the {@link EnumFacing face} to rotate for
+ */
+ public static void rotateForFace(final EnumFacing face) {
+ GlStateManager.rotate(face == EnumFacing.DOWN ? 0 : face == EnumFacing.UP ? 180F : (face == EnumFacing.NORTH) || (face == EnumFacing.EAST) ? 90F : -90F, face.getAxis() == EnumFacing.Axis.Z ? 1 : 0, 0, face.getAxis() == EnumFacing.Axis.Z ? 0 : 1);
+ GlStateManager.rotate(-90, 0, 0, 1);
+ }
+
+ /**
+ * Put a lot of effort into this, it gets the entities exact (really, really exact) position
+ *
+ * @param entity The entity to calculate the position of
+ * @param partialTicks The multiplier used to predict where the entity is/will be
+ * @return The position of the entity as a Vec3d
+ */
+ @Nonnull
+ public static Vec3d getEntityRenderPos(@Nonnull final Entity entity, @Nonnull final double partialTicks) {
+ double flyingMultiplier = 1.825;
+ double yFlying = 1.02;
+ double yAdd = 0.0784000015258789;
+
+ if ((entity instanceof EntityPlayer) && ((EntityPlayer) entity).capabilities.isFlying) {
+ flyingMultiplier = 1.1;
+ yFlying = 1.67;
+ yAdd = 0;
+ }
+
+ final double yGround = ((entity.motionY + yAdd) == 0) && (entity.prevPosY > entity.posY) ? entity.posY - entity.prevPosY : 0;
+ double xFall = 1;
+ if (flyingMultiplier == 1.825) {
+ if (entity.motionX != 0) {
+ if ((entity.motionY + yAdd) != 0) {
+ xFall = 0.6;
+ } else if (yGround != 0) {
+ xFall = 0.6;
+ }
+ } else {
+ xFall = 0.6;
+ }
+ }
+
+ double zFall = 1;
+ if (flyingMultiplier == 1.825) {
+ if (entity.motionZ != 0) {
+ if ((entity.motionY + yAdd) != 0) {
+ zFall = 0.6;
+ } else if (yGround != 0) {
+ zFall = 0.6;
+ }
+ } else {
+ zFall = 0.6;
+ }
+ }
+
+ final double dX = entity.posX - ((entity.prevPosX - entity.posX) * partialTicks) - ((entity.motionX * xFall) * flyingMultiplier);
+ final double dY = entity.posY - yGround - ((entity.prevPosY - entity.posY) * partialTicks) - ((entity.motionY + yAdd) * yFlying);
+ final double dZ = entity.posZ - ((entity.prevPosZ - entity.posZ) * partialTicks) - ((entity.motionZ * zFall) * flyingMultiplier);
+
+ return new Vec3d(dX, dY, dZ);
+ }
+
+ /**
+ * Rotates around X axis based on Pitch input and around Y axis based on Yaw input
+ *
+ * @param pitch the pitch
+ * @param yaw the yaw
+ */
+ public static void rotateForPitchYaw(final double pitch, final double yaw) {
+ GlStateManager.rotate((float) yaw, 0, 1, 0);
+ GlStateManager.rotate((float) pitch, 1, 0, 0);
+ }
+
+ /**
+ * Gets the pitch rotation between two vectors
+ *
+ * @param source the source vector
+ * @param destination the destination vector
+ * @return the pitch rotation
+ */
+ public static double getPitch(@Nonnull final Vec3d source, @Nonnull final Vec3d destination) {
+ double pitch = Math.atan2(destination.y, Math.sqrt((destination.x * destination.x) + (destination.z * destination.z)));
+ pitch = pitch * (180 / Math.PI);
+ pitch = pitch < 0 ? 360 - (-pitch) : pitch;
+ return 90 - pitch;
+ }
+
+ /**
+ * Gets the yaw rotation between two vectors
+ *
+ * @param source the source vector
+ * @param destination the destination vector
+ * @return the yaw rotation
+ */
+ public static double getYaw(@Nonnull final Vec3d source, @Nonnull final Vec3d destination) {
+ double yaw = Math.atan2(destination.x - source.x, destination.z - source.z);
+ yaw = yaw * (180 / Math.PI);
+ yaw = yaw < 0 ? 360 - (-yaw) : yaw;
+ return yaw + 90;
+ }
+
+ /**
+ * @param red the red value of the color, between 0x00 (decimal 0) and 0xFF (decimal 255)
+ * @param green the red value of the color, between 0x00 (decimal 0) and 0xFF (decimal 255)
+ * @param blue the red value of the color, between 0x00 (decimal 0) and 0xFF (decimal 255)
+ * @return the color in ARGB format
+ */
+ public static int color(int red, int green, int blue) {
+
+ red = MathHelper.clamp(red, 0x00, 0xFF);
+ green = MathHelper.clamp(green, 0x00, 0xFF);
+ blue = MathHelper.clamp(blue, 0x00, 0xFF);
+
+ final int alpha = 0xFF;
+
+ // 0x alpha red green blue
+ // 0xaarrggbb
+
+ // int colorRGBA = 0;
+ // colorRGBA |= red << 16;
+ // colorRGBA |= green << 8;
+ // colorRGBA |= blue << 0;
+ // colorRGBA |= alpha << 24;
+
+ return blue | red << 16 | green << 8 | alpha << 24;
+
+ }
+
+ /**
+ * @param red the red value of the color, 0F and 1F
+ * @param green the green value of the color, 0F and 1F
+ * @param blue the blue value of the color, 0F and 1F
+ * @return the color in ARGB format
+ */
+ public static int colorf(final float red, final float green, final float blue) {
+ final int redInt = Math.max(0, Math.min(255, Math.round(red * 255)));
+ final int greenInt = Math.max(0, Math.min(255, Math.round(green * 255)));
+ final int blueInt = Math.max(0, Math.min(255, Math.round(blue * 255)));
+ return color(redInt, greenInt, blueInt);
+ }
+
+ // Below are some helper methods to upload data to the buffer for use by FastTESRs
+
+ public static int getLightmapSkyLightCoordsFromPackedLightmapCoords(int packedLightmapCoords) {
+ return (packedLightmapCoords >> 16) & 0xFFFF; // get upper 4 bytes
+ }
+
+ public static int getLightmapBlockLightCoordsFromPackedLightmapCoords(int packedLightmapCoords) {
+ return packedLightmapCoords & 0xFFFF; // get lower 4 bytes
+ }
+
+ /**
+ * Renders a simple 2 dimensional quad at a given position to a given buffer with the given transforms, color, texture and lightmap values.
+ *
+ * @param baseOffset the base offset. This will be untouched by the model matrix transformations.
+ * @param buffer the buffer to upload the quads to. Vertex format of BLOCK is assumed.
+ * @param transform the model matrix to use as the transform matrix.
+ * @param color the color of the quad. The format is ARGB where each component is represented by a byte.
+ * @param texture the TextureAtlasSprite object to gain the UV data from.
+ * @param lightmapSkyLight the skylight lightmap coordinates for the quad.
+ * @param lightmapBlockLight the blocklight lightmap coordinates for the quad.
+ */
+ public static void renderSimpleQuad(Vector3f baseOffset, BufferBuilder buffer, Matrix4f transform, int color, TextureAtlasSprite texture, int lightmapSkyLight, int lightmapBlockLight) {
+ renderCustomQuad(SIMPLE_QUAD, baseOffset, buffer, transform, color, texture, lightmapSkyLight, lightmapBlockLight);
+ }
+
+ /**
+ * Renders a simple 2 dimensional quad at a given position to a given buffer with the given transforms, color, texture and lightmap values.
+ *
+ * @param baseOffset the base offset. This will be untouched by the model matrix transformations.
+ * @param buffer the buffer to upload the quads to. Vertex format of BLOCK is assumed.
+ * @param transform the model matrix to use as the transform matrix.
+ * @param color the color of the quad. The format is ARGB where each component is represented by a byte.
+ * @param texture the TextureAtlasSprite object to gain the UV data from.
+ * @param lightmapSkyLight the skylight lightmap coordinates for the quad.
+ * @param lightmapBlockLight the blocklight lightmap coordinates for the quad.
+ */
+ public static void renderCustomQuad(final Vector4f[] customQuad, Vector3f baseOffset, BufferBuilder buffer, Matrix4f transform, int color, TextureAtlasSprite texture, int lightmapSkyLight, int lightmapBlockLight) {
+ // A quad consists of 4 vertices so the loop is executed 4 times.
+ for (int i = 0; i < 4; ++i) {
+ // Getting the vertex position from a set of predefined positions for a basic quad.
+ Vector4f quadPos = customQuad[i];
+
+ // Transforming the position vector by the transform matrix.
+ quadPos = Matrix4f.transform(transform, quadPos, new Vector4f());
+
+ // Getting the RGBA values from the color. (The color is in ARGB format)
+ // To put it another way - unpacking an int representation of a color to a 4-component float vector representation.
+ float r = ((color & 0xFF0000) >> 16) / 255F;
+ float g = ((color & 0xFF00) >> 8) / 255F;
+ float b = (color & 0xFF) / 255F;
+ float a = ((color & 0xFF000000) >> 24) / 255F;
+
+ // Getting the texture UV coordinates from an index. The quad looks like this
+ /*0 3
+ 1 2*/
+ float u = i < 2 ? texture.getMaxU() - UV_CORRECT : texture.getMinU() + UV_CORRECT;
+ float v = i == 1 || i == 2 ? texture.getMaxV() - UV_CORRECT : texture.getMinV() + UV_CORRECT;
+
+ // Uploading the quad data to the buffer.
+ buffer.pos(quadPos.x + baseOffset.x, quadPos.y + baseOffset.y, quadPos.z + baseOffset.z).color(r, g, b, a).tex(u, v).lightmap(lightmapSkyLight, lightmapBlockLight).endVertex();
+ }
+ }
+
+ /**
+ * Renders a collection of BakedQuads into the BufferBuilder given. This method allows you to render any model in game in the FastTESR, be it a block model or an item model.
+ * Alternatively a custom list of quads may be constructed at runtime to render things like text.
+ * Drawbacks: doesn't transform normals as they are not guaranteed to be present in the buffer. Not relevant for a FastTESR but may cause issues with Optifine's shaders.
+ *
+ * @param quads the iterable of BakedQuads. This may be any iterable object.
+ * @param baseOffset the base position offset for the rendering. This position will not be transformed by the model matrix.
+ * @param pipeline the vertex consumer object. It is a parameter for optimization reasons. It may simply be constructed as new VertexBufferConsumer(buffer) and may be reused indefinately in the scope of the render pass.
+ * @param buffer the buffer to upload vertices to.
+ * @param transform the model matrix that is used to transform quad vertices.
+ * @param brightness the brightness of the model. The packed lightmap coordinate system is pretty complex and a lot of parameters are not necessary here so only the dominant one is implemented.
+ * @param color the color of the quad. This is a color multiplier in the ARGB format.
+ */
+ public static void renderQuads(Iterable quads, Vector3f baseOffset, VertexBufferConsumer pipeline, BufferBuilder buffer, Matrix4f transform, float brightness, int color) {
+ // Get the raw int buffer of the buffer builder object.
+ IntBuffer intBuf = getIntBuffer(buffer);
+
+ // Iterate the iterable
+ for (BakedQuad quad : quads) {
+ // Push the quad to the consumer so it can be uploaded onto the buffer.
+ LightUtil.putBakedQuad(pipeline, quad);
+
+ // After the quad has been uploaded the buffer contains enough info to apply the model matrix transformation.
+ // Getting the vertex size for the given format.
+ int vertexSize = buffer.getVertexFormat().getIntegerSize();
+
+ // Getting the offset for the current quad.
+ int quadOffset = (buffer.getVertexCount() - 4) * vertexSize;
+
+ // Each quad is made out of 4 vertices, so looping 4 times.
+ for (int k = 0; k < 4; ++k) {
+ // Getting the offset for the current vertex.
+ int vertexIndex = quadOffset + k * vertexSize;
+
+ // Grabbing the position vector from the buffer.
+ float vertX = Float.intBitsToFloat(intBuf.get(vertexIndex));
+ float vertY = Float.intBitsToFloat(intBuf.get(vertexIndex + 1));
+ float vertZ = Float.intBitsToFloat(intBuf.get(vertexIndex + 2));
+ Vector4f vert = new Vector4f(vertX, vertY, vertZ, 1);
+
+ // Transforming it by the model matrix.
+ vert = Matrix4f.transform(transform, vert, new Vector4f());
+
+ // Uploading the difference back to the buffer. Have to use the helper function since the provided putX methods upload the data for a quad, not a vertex and this data is vertex-dependent.
+ putPositionForVertex(buffer, intBuf, vertexIndex, new Vector3f(vert.x - vertX, vert.y - vertY, vert.z - vertZ));
+ }
+
+ // Uploading the origin position to the buffer. This is an addition operation.
+ buffer.putPosition(baseOffset.x, baseOffset.y, baseOffset.z);
+
+ // Constructing the most basic packed lightmap data with a mask of 0x00FF0000.
+ int bVal = ((byte) (brightness * 255)) << 16;
+
+ // Uploading the brightness to the buffer.
+ buffer.putBrightness4(bVal, bVal, bVal, bVal);
+
+ // Uploading the color multiplier to the buffer
+ buffer.putColor4(color);
+ }
+ }
+
+ /**
+ * A helper method that grabs all BakedQuads of a given model of a given IBlockState and joins them onto a single iterable.
+ *
+ * @param state the block state object to get the quads from.
+ * @return the iterable of BakedQuads.
+ */
+ public static Iterable iterateQuadsOfBlock(IBlockState state) {
+ return Arrays.stream(EnumFacing.values()).map(q -> Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(state).getQuads(state, q, 0L)).flatMap(Collection::stream).distinct().collect(Collectors.toList());
+ }
+
+ /**
+ * A setter for the vertex-based positions for a given BufferBuilder object.
+ *
+ * @param buffer the buffer to set the positions in.
+ * @param intBuf the raw int buffer.
+ * @param offset the offset for the int buffer, in ints.
+ * @param pos the position to add to the buffer.
+ */
+ public static void putPositionForVertex(BufferBuilder buffer, IntBuffer intBuf, int offset, Vector3f pos) {
+ // Getting the old position data in the buffer currently.
+ float ox = Float.intBitsToFloat(intBuf.get(offset));
+ float oy = Float.intBitsToFloat(intBuf.get(offset + 1));
+ float oz = Float.intBitsToFloat(intBuf.get(offset + 2));
+
+ // Converting the new data to ints.
+ int x = Float.floatToIntBits(pos.x + ox);
+ int y = Float.floatToIntBits(pos.y + oy);
+ int z = Float.floatToIntBits(pos.z + oz);
+
+ // Putting the data into the buffer
+ intBuf.put(offset, x);
+ intBuf.put(offset + 1, y);
+ intBuf.put(offset + 2, z);
+ }
+
+ /**
+ * A getter for the rawIntBuffer field value of the BufferBuilder.
+ *
+ * @param buffer the buffer builder to get the buffer from
+ * @return the rawIntbuffer component
+ */
+ @Nonnull
+ public static IntBuffer getIntBuffer(BufferBuilder buffer) {
+ try {
+ return (IntBuffer) bufferBuilder_rawIntBuffer.get(buffer);
+ } catch (IllegalAccessException exception) {
+ // Some other mod messed up and reset the access flag of the field.
+ CrashReport crashReport = new CrashReport("An impossible error has occurred!", exception);
+ crashReport.makeCategory("Reflectively Accessing BufferBuilder#rawIntBuffer");
+ throw new ReportedException(crashReport);
+ }
+ }
+
+}
diff --git a/src/main/java/io/github/cadiboo/examplemod/client/gui/ElectricFurnaceScreen.java b/src/main/java/io/github/cadiboo/examplemod/client/gui/ElectricFurnaceScreen.java
deleted file mode 100644
index 010624f..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/client/gui/ElectricFurnaceScreen.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package io.github.cadiboo.examplemod.client.gui;
-
-import com.mojang.blaze3d.systems.RenderSystem;
-import io.github.cadiboo.examplemod.ExampleMod;
-import io.github.cadiboo.examplemod.container.ElectricFurnaceContainer;
-import io.github.cadiboo.examplemod.tileentity.ElectricFurnaceTileEntity;
-import net.minecraft.client.gui.screen.inventory.ContainerScreen;
-import net.minecraft.entity.player.PlayerInventory;
-import net.minecraft.util.ResourceLocation;
-import net.minecraft.util.text.ITextComponent;
-import net.minecraft.util.text.TranslationTextComponent;
-import net.minecraftforge.energy.EnergyStorage;
-
-/**
- * @author Cadiboo
- */
-public class ElectricFurnaceScreen extends ContainerScreen {
-
- private static final ResourceLocation BACKGROUND_TEXTURE = new ResourceLocation(ExampleMod.MODID, "textures/gui/container/electric_furnace.png");
-
- public ElectricFurnaceScreen(final ElectricFurnaceContainer container, final PlayerInventory inventory, final ITextComponent title) {
- super(container, inventory, title);
- }
-
- @Override
- public void render(final int mouseX, final int mouseY, final float partialTicks) {
- this.renderBackground();
- super.render(mouseX, mouseY, partialTicks);
- this.renderHoveredToolTip(mouseX, mouseY);
-
- int relMouseX = mouseX - this.guiLeft;
- int relMouseY = mouseY - this.guiTop;
- final ElectricFurnaceTileEntity tileEntity = this.container.tileEntity;
- boolean energyBarHovered = relMouseX > 151 && relMouseX < 166 && relMouseY > 10 && relMouseY < 76;
- if (energyBarHovered) {
- String tooltip = new TranslationTextComponent(
- "gui." + ExampleMod.MODID + ".energy",
- tileEntity.energy.getEnergyStored()
- ).getFormattedText();
- this.renderTooltip(tooltip, mouseX, mouseY);
- }
- boolean arrowHovered = relMouseX > 79 && relMouseX < 104 && relMouseY > 34 && relMouseY < 50;
- if (arrowHovered && tileEntity.maxSmeltTime > 0) {
- String tooltip = new TranslationTextComponent(
- "gui." + ExampleMod.MODID + ".smeltTimeProgress",
- tileEntity.smeltTimeLeft, tileEntity.maxSmeltTime
- ).getFormattedText();
- this.renderTooltip(tooltip, mouseX, mouseY);
- }
- }
-
- @Override
- protected void drawGuiContainerForegroundLayer(final int mouseX, final int mouseY) {
- super.drawGuiContainerForegroundLayer(mouseX, mouseY);
- // Copied from AbstractFurnaceScreen#drawGuiContainerForegroundLayer
- String s = this.title.getFormattedText();
- this.font.drawString(s, (float) (this.xSize / 2 - this.font.getStringWidth(s) / 2), 6.0F, 0x404040);
- this.font.drawString(this.playerInventory.getDisplayName().getFormattedText(), 8.0F, (float) (this.ySize - 96 + 2), 0x404040);
- }
-
- @Override
- protected void drawGuiContainerBackgroundLayer(final float partialTicks, final int mouseX, final int mouseY) {
- RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
- getMinecraft().getTextureManager().bindTexture(BACKGROUND_TEXTURE);
- int startX = this.guiLeft;
- int startY = this.guiTop;
-
- // Screen#blit draws a part of the current texture (assumed to be 256x256) to the screen
- // The parameters are (x, y, u, v, width, height)
-
- this.blit(startX, startY, 0, 0, this.xSize, this.ySize);
-
- final ElectricFurnaceTileEntity tileEntity = container.tileEntity;
- if (tileEntity.energy.getEnergyStored() > 0) { // Draw energy bar
- int energyProgress = getEnergyProgressScaled();
- this.blit(
- startX + 152, startY + 10 + 65 - energyProgress,
- 176, 16,
- 14, energyProgress
- );
- }
- if (tileEntity.smeltTimeLeft > 0) {
- // Draw progress arrow
- int arrowWidth = getSmeltTimeScaled();
- this.blit(
- startX + 79, startY + 34,
- 176, 0,
- arrowWidth, 16
- );
- }
- }
-
- private int getEnergyProgressScaled() {
- final ElectricFurnaceTileEntity tileEntity = this.container.tileEntity;
- final EnergyStorage energy = tileEntity.energy;
- final int energyStored = energy.getEnergyStored();
- final int maxEnergyStored = energy.getMaxEnergyStored();
- return Math.round((float) energyStored / maxEnergyStored * 65); // 65 is the height of the arrow
- }
-
- private int getSmeltTimeScaled() {
- final ElectricFurnaceTileEntity tileEntity = this.container.tileEntity;
- final short smeltTimeLeft = tileEntity.smeltTimeLeft;
- final short maxSmeltTime = tileEntity.maxSmeltTime;
- if (smeltTimeLeft <= 0 || maxSmeltTime <= 0)
- return 0;
- return (maxSmeltTime - smeltTimeLeft) * 24 / maxSmeltTime; // 24 is the width of the arrow
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/client/gui/HeatCollectorScreen.java b/src/main/java/io/github/cadiboo/examplemod/client/gui/HeatCollectorScreen.java
deleted file mode 100644
index 3dbbb07..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/client/gui/HeatCollectorScreen.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package io.github.cadiboo.examplemod.client.gui;
-
-import com.mojang.blaze3d.systems.RenderSystem;
-import io.github.cadiboo.examplemod.ExampleMod;
-import io.github.cadiboo.examplemod.container.HeatCollectorContainer;
-import io.github.cadiboo.examplemod.energy.SettableEnergyStorage;
-import io.github.cadiboo.examplemod.tileentity.HeatCollectorTileEntity;
-import net.minecraft.client.gui.screen.inventory.ContainerScreen;
-import net.minecraft.entity.player.PlayerInventory;
-import net.minecraft.util.ResourceLocation;
-import net.minecraft.util.text.ITextComponent;
-import net.minecraft.util.text.TranslationTextComponent;
-
-/**
- * @author Cadiboo
- */
-public class HeatCollectorScreen extends ContainerScreen {
-
- private static final ResourceLocation BACKGROUND_TEXTURE = new ResourceLocation(ExampleMod.MODID, "textures/gui/container/heat_collector.png");
-
- public HeatCollectorScreen(final HeatCollectorContainer container, final PlayerInventory inventory, final ITextComponent title) {
- super(container, inventory, title);
- }
-
- @Override
- public void render(final int mouseX, final int mouseY, final float partialTicks) {
- this.renderBackground();
- super.render(mouseX, mouseY, partialTicks);
- this.renderHoveredToolTip(mouseX, mouseY);
-
- int relMouseX = mouseX - this.guiLeft;
- int relMouseY = mouseY - this.guiTop;
- boolean energyBarHovered = relMouseX > 151 && relMouseX < 166 && relMouseY > 10 && relMouseY < 76;
- if (energyBarHovered) {
- String tooltip = new TranslationTextComponent(
- "gui." + ExampleMod.MODID + ".energy",
- this.container.tileEntity.energy.getEnergyStored()
- ).getFormattedText();
- this.renderTooltip(tooltip, mouseX, mouseY);
- }
- }
-
- @Override
- protected void drawGuiContainerForegroundLayer(final int mouseX, final int mouseY) {
- super.drawGuiContainerForegroundLayer(mouseX, mouseY);
- // Copied from AbstractFurnaceScreen#drawGuiContainerForegroundLayer
- String s = this.title.getFormattedText();
- this.font.drawString(s, (float) (this.xSize / 2 - this.font.getStringWidth(s) / 2), 6.0F, 0x404040);
- this.font.drawString(this.playerInventory.getDisplayName().getFormattedText(), 8.0F, (float) (this.ySize - 96 + 2), 0x404040);
- }
-
- @Override
- protected void drawGuiContainerBackgroundLayer(final float partialTicks, final int mouseX, final int mouseY) {
- RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
- getMinecraft().getTextureManager().bindTexture(BACKGROUND_TEXTURE);
- int startX = this.guiLeft;
- int startY = this.guiTop;
-
- // Screen#blit draws a part of the current texture (assumed to be 256x256) to the screen
- // The parameters are (x, y, u, v, width, height)
-
- this.blit(startX, startY, 0, 0, this.xSize, this.ySize);
-
- final HeatCollectorTileEntity tileEntity = container.tileEntity;
-
- final SettableEnergyStorage energy = tileEntity.energy;
- final int energyStored = energy.getEnergyStored();
- if (energyStored > 0) { // Draw energy bar
- final int energyProgress = Math.round((float) energyStored / energy.getMaxEnergyStored() * 65);
- this.blit(
- startX + 152, startY + 10 + 65 - energyProgress,
- 176, 14,
- 14, energyProgress
- );
- }
-
- if (!tileEntity.inventory.getStackInSlot(HeatCollectorTileEntity.FUEL_SLOT).isEmpty()) // Draw flames
- this.blit(
- startX + 81, startY + 58,
- 176, 0,
- 14, 14
- );
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/client/gui/MiniModelScreen.java b/src/main/java/io/github/cadiboo/examplemod/client/gui/MiniModelScreen.java
deleted file mode 100644
index 06a1448..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/client/gui/MiniModelScreen.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package io.github.cadiboo.examplemod.client.gui;
-
-import io.github.cadiboo.examplemod.ExampleMod;
-import io.github.cadiboo.examplemod.client.render.MiniModel;
-import io.github.cadiboo.examplemod.init.ModBlocks;
-import io.github.cadiboo.examplemod.tileentity.MiniModelTileEntity;
-import net.minecraft.client.gui.screen.Screen;
-import net.minecraft.client.resources.I18n;
-import net.minecraftforge.fml.client.gui.widget.ExtendedButton;
-
-/**
- * A Screen for refreshing our MiniMode.
- * It contains two buttons "Refresh Mini Model" and "Done"
- *
- * @author Cadiboo
- */
-public class MiniModelScreen extends Screen {
-
- private final MiniModelTileEntity tileEntity;
-
- public MiniModelScreen(final MiniModelTileEntity tileEntity) {
- super(ModBlocks.MINI_MODEL.get().getNameTextComponent());
- this.tileEntity = tileEntity;
- }
-
- @Override
- public void render(final int mouseX, final int mouseY, final float partialTicks) {
- this.renderBackground();
- super.render(mouseX, mouseY, partialTicks);
- }
-
- @Override
- protected void init() {
- final int halfW = this.width / 2;
- final int halfH = this.height / 2;
- // "Refresh Mini Model" button rebuilds the tile's MiniModel
- this.addButton(new ExtendedButton(halfW - 150, halfH, 150, 20, I18n.format("gui." + ExampleMod.MODID + ".refresh_mini_model"),
- $ -> {
- final MiniModel miniModel = this.tileEntity.miniModel;
- if (miniModel != null)
- miniModel.compile();
- }
- ));
- // "Done" button exits the GUI
- this.addButton(new ExtendedButton(halfW, halfH, 150, 20, I18n.format("gui.done"),
- $ -> this.minecraft.displayGuiScreen(null)
- ));
- super.init();
- }
-
- @Override
- public boolean isPauseScreen() {
- return false; // Don't pause the game when this screen is open
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/client/gui/ModFurnaceScreen.java b/src/main/java/io/github/cadiboo/examplemod/client/gui/ModFurnaceScreen.java
deleted file mode 100644
index ea4f49e..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/client/gui/ModFurnaceScreen.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package io.github.cadiboo.examplemod.client.gui;
-
-import com.mojang.blaze3d.systems.RenderSystem;
-import io.github.cadiboo.examplemod.ExampleMod;
-import io.github.cadiboo.examplemod.container.ModFurnaceContainer;
-import io.github.cadiboo.examplemod.tileentity.ModFurnaceTileEntity;
-import net.minecraft.client.gui.screen.inventory.ContainerScreen;
-import net.minecraft.entity.player.PlayerInventory;
-import net.minecraft.util.ResourceLocation;
-import net.minecraft.util.text.ITextComponent;
-import net.minecraft.util.text.TranslationTextComponent;
-
-/**
- * @author Cadiboo
- */
-public class ModFurnaceScreen extends ContainerScreen {
-
- private static final ResourceLocation BACKGROUND_TEXTURE = new ResourceLocation("minecraft", "textures/gui/container/furnace.png");
-
- public ModFurnaceScreen(final ModFurnaceContainer container, final PlayerInventory inventory, final ITextComponent title) {
- super(container, inventory, title);
- }
-
- @Override
- public void render(final int mouseX, final int mouseY, final float partialTicks) {
- this.renderBackground();
- super.render(mouseX, mouseY, partialTicks);
- this.renderHoveredToolTip(mouseX, mouseY);
-
- int relMouseX = mouseX - this.guiLeft;
- int relMouseY = mouseY - this.guiTop;
- final ModFurnaceTileEntity tileEntity = this.container.tileEntity;
- boolean arrowHovered = relMouseX > 79 && relMouseX < 104 && relMouseY > 34 && relMouseY < 50;
- if (arrowHovered && tileEntity.maxSmeltTime > 0) {
- String tooltip = new TranslationTextComponent(
- "gui." + ExampleMod.MODID + ".smeltTimeProgress",
- tileEntity.smeltTimeLeft, tileEntity.maxSmeltTime
- ).getFormattedText();
- this.renderTooltip(tooltip, mouseX, mouseY);
- }
- boolean fireHovered = relMouseX > 56 && relMouseX < 70 && relMouseY > 36 && relMouseY < 50;
- if (fireHovered && tileEntity.maxFuelBurnTime > 0) {
- String tooltip = new TranslationTextComponent(
- "gui." + ExampleMod.MODID + ".fuelBurnTimeProgress",
- tileEntity.fuelBurnTimeLeft, tileEntity.maxFuelBurnTime
- ).getFormattedText();
- this.renderTooltip(tooltip, mouseX, mouseY);
- }
- }
-
- @Override
- protected void drawGuiContainerForegroundLayer(final int mouseX, final int mouseY) {
- super.drawGuiContainerForegroundLayer(mouseX, mouseY);
- // Copied from AbstractFurnaceScreen#drawGuiContainerForegroundLayer
- String s = this.title.getFormattedText();
- this.font.drawString(s, (float) (this.xSize / 2 - this.font.getStringWidth(s) / 2), 6.0F, 0x404040);
- this.font.drawString(this.playerInventory.getDisplayName().getFormattedText(), 8.0F, (float) (this.ySize - 96 + 2), 0x404040);
-
- final ModFurnaceTileEntity tileEntity = this.container.tileEntity;
- if (tileEntity.smeltTimeLeft > 0)
- this.font.drawString(tileEntity.smeltTimeLeft + " / " + tileEntity.maxSmeltTime, 8.0F, this.ySize, 0x404040);
- this.font.drawString(tileEntity.fuelBurnTimeLeft + " / " + tileEntity.maxFuelBurnTime, 8.0F, this.ySize + 14, 0x404040);
- }
-
- @Override
- protected void drawGuiContainerBackgroundLayer(final float partialTicks, final int mouseX, final int mouseY) {
- RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
- getMinecraft().getTextureManager().bindTexture(BACKGROUND_TEXTURE);
- int startX = this.guiLeft;
- int startY = this.guiTop;
-
- // Screen#blit draws a part of the current texture (assumed to be 256x256) to the screen
- // The parameters are (x, y, u, v, width, height)
-
- this.blit(startX, startY, 0, 0, this.xSize, this.ySize);
-
- final ModFurnaceTileEntity tileEntity = container.tileEntity;
- if (tileEntity.smeltTimeLeft > 0) {
- // Draw progress arrow
- int arrowWidth = getSmeltTimeScaled();
- this.blit(
- startX + 79, startY + 34,
- 176, 14,
- arrowWidth, 14
- );
- }
- if (tileEntity.isBurning()) {
- // Draw flames
- int flameHeight = getFuelBurnTimeScaled();
- this.blit(
- startX + 56, startY + 50 - flameHeight,
- 176, 14 - flameHeight,
- 14, flameHeight
- );
- }
- }
-
- private int getSmeltTimeScaled() {
- final ModFurnaceTileEntity tileEntity = this.container.tileEntity;
- final short smeltTimeLeft = tileEntity.smeltTimeLeft;
- final short maxSmeltTime = tileEntity.maxSmeltTime;
- if (smeltTimeLeft <= 0 || maxSmeltTime <= 0)
- return 0;
- return (maxSmeltTime - smeltTimeLeft) * 24 / maxSmeltTime; // 24 is the width of the arrow
- }
-
- private int getFuelBurnTimeScaled() {
- final ModFurnaceTileEntity tileEntity = this.container.tileEntity;
- if (tileEntity.maxFuelBurnTime <= 0)
- return 0;
- return tileEntity.fuelBurnTimeLeft * 16 / tileEntity.maxFuelBurnTime; // 14 is the height of the flames
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/client/package-info.java b/src/main/java/io/github/cadiboo/examplemod/client/package-info.java
new file mode 100644
index 0000000..7580997
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/client/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Contains code that will crash on the physical/dedicated server
+ */
+
+package io.github.cadiboo.examplemod.client;
diff --git a/src/main/java/io/github/cadiboo/examplemod/client/render/MiniModel.java b/src/main/java/io/github/cadiboo/examplemod/client/render/MiniModel.java
deleted file mode 100644
index 62b7ed8..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/client/render/MiniModel.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package io.github.cadiboo.examplemod.client.render;
-
-import net.minecraft.tileentity.TileEntity;
-
-/**
- * A wrapper around ChunkRender.
- * Stores the a render of the chunk (16x16x16) surrounding a TileEntity
- * TODO: Make this work on 1.15
- *
- * @author Cadiboo
- */
-public class MiniModel {
-
-// // We only create one of these per cache, we reset it each time we rebuild
-// public final RegionRenderCacheBuilder regionRenderCacheBuilder;
-// private final ChunkRender chunkRender;
-// public ChunkRenderTask generator;
- private boolean isCompiled = false;
-
-// private MiniModel(final ChunkRender chunkRender, final RegionRenderCacheBuilder regionRenderCacheBuilder) {
-// this.chunkRender = chunkRender;
-// this.regionRenderCacheBuilder = regionRenderCacheBuilder;
-// }
-
- public static MiniModel forTileEntity(final TileEntity tileEntity) {
-// final ChunkRender chunkRender = new ChunkRender(tileEntity.getWorld(), Minecraft.getInstance().worldRenderer);
-// final BlockPos pos = tileEntity.getPos();
-//
-// // We want to render everything in a 16x16x16 radius, with the centre being the TileEntity
-// chunkRender.setPosition(pos.getX() - 8, pos.getY() - 8, pos.getZ() - 8);
-//
-// return new MiniModel(chunkRender, new RegionRenderCacheBuilder());
- return null;
- }
-
- /**
- * (re)build the render
- */
- public void compile() {
-// final ChunkRender chunkRender = this.chunkRender;
-// final RegionRenderCacheBuilder buffers = this.regionRenderCacheBuilder;
-//
-// final ChunkRenderTask generator = chunkRender.makeCompileTaskChunk();
-// this.generator = generator;
-//
-// // Setup generator
-// generator.setStatus(ChunkRenderTask.Status.COMPILING);
-// generator.setRegionRenderCacheBuilder(buffers);
-//
-// final Vec3d vec3d = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView();
-//
-// // Rebuild the ChunkRender.
-// // This resets all the buffers it uses and renders every block in the chunk to the buffers
-// chunkRender.rebuildChunk((float) vec3d.x, (float) vec3d.y, (float) vec3d.z, generator);
-//
-// // ChunkRender#rebuildChunk increments this, we don't want it incremented so we decrement it.
-// --ChunkRender.renderChunksUpdated;
-//
-// // Set the translation of each buffer back to 0
-// final int length = BLOCK_RENDER_LAYERS.length;
-// for (int ordinal = 0; ordinal < length; ++ordinal) {
-// buffers.getBuilder(ordinal).setTranslation(0, 0, 0);
-// }
-// this.isBuilt = true;
- }
-
- public boolean isCompiled() {
- return isCompiled;
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/client/render/entity/WildBoarRenderer.java b/src/main/java/io/github/cadiboo/examplemod/client/render/entity/WildBoarRenderer.java
deleted file mode 100644
index 5e8675e..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/client/render/entity/WildBoarRenderer.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package io.github.cadiboo.examplemod.client.render.entity;
-
-import io.github.cadiboo.examplemod.ExampleMod;
-import io.github.cadiboo.examplemod.client.render.entity.layer.WildBoarSaddleLayer;
-import io.github.cadiboo.examplemod.entity.WildBoarEntity;
-import net.minecraft.client.renderer.entity.EntityRendererManager;
-import net.minecraft.client.renderer.entity.MobRenderer;
-import net.minecraft.client.renderer.entity.model.PigModel;
-import net.minecraft.util.ResourceLocation;
-
-/**
- * Handles rendering all WildBoar Entities.
- * The render method is called once each frame for every visible WildBoar.
- *
- * We use a PigModel in our renderer and simply change it's texture.
- *
- * @author Cadiboo
- */
-public class WildBoarRenderer extends MobRenderer> {
-
- private static final ResourceLocation WILD_BOAR_TEXTURE = new ResourceLocation(ExampleMod.MODID, "textures/entity/wild_boar/wild_boar.png");
-
- public WildBoarRenderer(final EntityRendererManager manager) {
- super(manager, new PigModel<>(), 0.7F);
- this.addLayer(new WildBoarSaddleLayer(this));
- }
-
- @Override
- public ResourceLocation getEntityTexture(final WildBoarEntity entity) {
- return WILD_BOAR_TEXTURE;
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/client/render/entity/layer/WildBoarSaddleLayer.java b/src/main/java/io/github/cadiboo/examplemod/client/render/entity/layer/WildBoarSaddleLayer.java
deleted file mode 100644
index 8121a6c..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/client/render/entity/layer/WildBoarSaddleLayer.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package io.github.cadiboo.examplemod.client.render.entity.layer;
-
-import com.mojang.blaze3d.matrix.MatrixStack;
-import com.mojang.blaze3d.vertex.IVertexBuilder;
-import io.github.cadiboo.examplemod.ExampleMod;
-import io.github.cadiboo.examplemod.entity.WildBoarEntity;
-import net.minecraft.client.renderer.IRenderTypeBuffer;
-import net.minecraft.client.renderer.RenderType;
-import net.minecraft.client.renderer.entity.IEntityRenderer;
-import net.minecraft.client.renderer.entity.layers.LayerRenderer;
-import net.minecraft.client.renderer.entity.layers.SaddleLayer;
-import net.minecraft.client.renderer.entity.model.PigModel;
-import net.minecraft.client.renderer.texture.OverlayTexture;
-import net.minecraft.util.ResourceLocation;
-
-/**
- * Copy of {@link SaddleLayer} with tweaks to make it work for WildBoarEntity.
- *
- * @author Cadiboo
- */
-public class WildBoarSaddleLayer extends LayerRenderer> {
-
- private static final ResourceLocation TEXTURE = new ResourceLocation(ExampleMod.MODID, "textures/entity/wild_boar/wild_boar_saddle.png");
- private final PigModel pigModel = new PigModel<>(0.5F);
-
- public WildBoarSaddleLayer(IEntityRenderer> p_i50927_1_) {
- super(p_i50927_1_);
- }
-
- @Override
- public void render(MatrixStack matrixStack, IRenderTypeBuffer renderTypeBuffer, int light, WildBoarEntity entity, float p_225628_5_, float p_225628_6_, float p_225628_7_, float p_225628_8_, float p_225628_9_, float p_225628_10_) {
- if (entity.getSaddled()) {
- this.getEntityModel().setModelAttributes(this.pigModel);
- this.pigModel.setLivingAnimations(entity, p_225628_5_, p_225628_6_, p_225628_7_);
- this.pigModel.render(entity, p_225628_5_, p_225628_6_, p_225628_8_, p_225628_9_, p_225628_10_);
- IVertexBuilder buffer = renderTypeBuffer.getBuffer(RenderType.entityCutoutNoCull(TEXTURE));
- this.pigModel.render(matrixStack, buffer, light, OverlayTexture.DEFAULT_LIGHT, 1.0F, 1.0F, 1.0F, 1.0F);
- }
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/client/render/tileentity/ElectricFurnaceTileEntityRenderer.java b/src/main/java/io/github/cadiboo/examplemod/client/render/tileentity/ElectricFurnaceTileEntityRenderer.java
deleted file mode 100644
index 9230ff7..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/client/render/tileentity/ElectricFurnaceTileEntityRenderer.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package io.github.cadiboo.examplemod.client.render.tileentity;
-
-import com.mojang.blaze3d.matrix.MatrixStack;
-import io.github.cadiboo.examplemod.config.ExampleModConfig;
-import io.github.cadiboo.examplemod.tileentity.ElectricFurnaceTileEntity;
-import net.minecraft.block.BlockState;
-import net.minecraft.block.Blocks;
-import net.minecraft.block.RedstoneTorchBlock;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.IRenderTypeBuffer;
-import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
-import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
-
-/**
- * Handles rendering all ElectricFurnace TileEntities.
- * The render method is called once each frame for every visible ElectricFurnace.
- *
- * @author Cadiboo
- */
-public class ElectricFurnaceTileEntityRenderer extends TileEntityRenderer {
-
- public ElectricFurnaceTileEntityRenderer(final TileEntityRendererDispatcher tileEntityRendererDispatcher) {
- super(tileEntityRendererDispatcher);
- }
-
- /**
- * Render our TileEntity
- */
- @Override
- public void render(final ElectricFurnaceTileEntity tileEntityIn, final float partialTicks, final MatrixStack matrixStack, final IRenderTypeBuffer renderTypeBuffer, final int packedLight, final int backupPackedLight) {
- // TODO: Fix this up to actually do the rendering I want
-
- final boolean hasEnergy = tileEntityIn.energy.getEnergyStored() >= ExampleModConfig.electricFurnaceEnergySmeltCostPerTick;
- final BlockState renderState = Blocks.REDSTONE_TORCH.getDefaultState()
- .with(RedstoneTorchBlock.LIT, hasEnergy);
- // Render the torch (We use the depreciated method because we don't have an IModelData instance and want to use the default one)
- Minecraft.getInstance().getBlockRendererDispatcher().renderBlock(renderState, matrixStack, renderTypeBuffer, packedLight, backupPackedLight);
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/client/render/tileentity/MiniModelTileEntityRenderer.java b/src/main/java/io/github/cadiboo/examplemod/client/render/tileentity/MiniModelTileEntityRenderer.java
deleted file mode 100644
index abfd959..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/client/render/tileentity/MiniModelTileEntityRenderer.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package io.github.cadiboo.examplemod.client.render.tileentity;
-
-import com.mojang.blaze3d.matrix.MatrixStack;
-import com.mojang.blaze3d.systems.RenderSystem;
-import io.github.cadiboo.examplemod.client.render.MiniModel;
-import io.github.cadiboo.examplemod.config.ExampleModConfig;
-import io.github.cadiboo.examplemod.tileentity.MiniModelTileEntity;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.BufferBuilder;
-import net.minecraft.client.renderer.IRenderTypeBuffer;
-import net.minecraft.client.renderer.RenderHelper;
-import net.minecraft.client.renderer.WorldVertexBufferUploader;
-import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
-import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
-import org.lwjgl.opengl.GL11;
-
-import java.nio.ByteBuffer;
-
-/**
- * Handles rendering all MiniModel TileEntities.
- * The render method is called once each frame for every visible MiniModel.
- *
- * Renders a model of the surrounding blocks.
- * This should really probably not be in an examplemod for beginners,
- * but I added comments to it so its all good
- *
- * TODO: Update this to 1.15
- *
- * @author Cadiboo
- */
-public class MiniModelTileEntityRenderer extends TileEntityRenderer {
-
- public MiniModelTileEntityRenderer(final TileEntityRendererDispatcher tileEntityRendererDispatcher) {
- super(tileEntityRendererDispatcher);
- }
-
- /**
- * Render our TileEntity
- */
- @Override
- public void render(final MiniModelTileEntity tileEntityIn, final float partialTicks, final MatrixStack matrixStack, final IRenderTypeBuffer renderTypeBuffer, final int packedLight, final int backupPackedLight) {
-
-// final MiniModel miniModel = tileEntityIn.miniModel;
-//
-// if (miniModel == null)
-// return;
-//
-// if (!miniModel.isBuilt())
-// miniModel.rebuild();
-//
-// // Setup correct GL state
-//// this.field_228858_b_.textureManager.bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE);
-// RenderHelper.disableStandardItemLighting();
-// // Translucency
-// if (ExampleModConfig.modelTranslucency) {
-// RenderSystem.blendFunc(GL11.GL_ONE, GL11.GL_ONE);
-// } else {
-// RenderSystem.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
-// }
-// RenderSystem.enableBlend();
-//
-// if (Minecraft.isAmbientOcclusionEnabled()) {
-// RenderSystem.shadeModel(GL11.GL_SMOOTH);
-// } else {
-// RenderSystem.shadeModel(GL11.GL_FLAT);
-// }
-//
-// GlStateManager.pushMatrix();
-//
-// // Translate to render pos. The 0.5 is to translate into the centre of the block, rather than to the corner of it
-// GlStateManager.translated(x + 0.5, y + 0.5, z + 0.5);
-//
-// final double scale = ExampleModConfig.modelScale;
-// GlStateManager.scaled(scale, scale, scale);
-//
-// // Translate to start of render (our TileEntity is at its centre)
-// GlStateManager.translated(-8, -8, -8);
-//
-// // Render the buffers
-// renderChunkBuffers(miniModel.regionRenderCacheBuilder, miniModel.generator.getCompiledChunk());
-//
-// GlStateManager.popMatrix();
-//
-// // Clean up GL state
-// RenderHelper.enableStandardItemLighting();
-
- }
-
- /**
- * This renderer is a global renderer.
- * This means that it will always render, even if the player is not able to see it's block.
- * This is useful for rendering larger models or dynamically sized models.
- * The Beacon's beam is also a global renderer
- */
- @Override
- public boolean isGlobalRenderer(final MiniModelTileEntity te) {
- return true;
- }
-
-// /**
-// * Loops through every non-empty {@link BufferBuilder} in buffers and renders the buffer without resetting it
-// *
-// * @param buffers The {@link RegionRenderCacheBuilder} to get {@link BufferBuilder}s from
-// * @param compiledChunk The {@link CompiledChunk} to use to check if a layer has any rendered blocks
-// */
-// private void renderChunkBuffers(final RegionRenderCacheBuilder buffers, final CompiledChunk compiledChunk) {
-// final int length = BLOCK_RENDER_LAYERS.length;
-// // Render each buffer that has been used
-// for (int layerOrdinal = 0; layerOrdinal < length; ++layerOrdinal) {
-// if (!compiledChunk.isLayerEmpty(BLOCK_RENDER_LAYERS[layerOrdinal])) {
-// drawBufferWithoutResetting(buffers.getBuilder(layerOrdinal));
-// }
-// }
-// }
-//
-// /**
-// * This should work.
-// * Draws a BufferBuilder without resetting its internal data.
-// *
-// * @param bufferBuilder The BufferBuilder to draw (but not reset)
-// */
-// private void drawBufferWithoutResetting(final BufferBuilder bufferBuilder) {
-// // Get the internal data from the BufferBuilder (This resets the BufferBuilder's own copy of this data)
-// final ByteBuffer byteBuffer = bufferBuilder.getAndResetData().getSecond();
-// // Set the BufferBuilder's internal data to the original data
-// bufferBuilder.putBulkData(byteBuffer);
-// // Draw the BufferBuilder (This resets the BufferBuilder's data)
-// WorldVertexBufferUploader.draw(bufferBuilder);
-// // Set the BufferBuilder's internal data back to the original data
-// bufferBuilder.putBulkData(byteBuffer);
-// }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/client/render/tileentity/RenderExampleTileEntity.java b/src/main/java/io/github/cadiboo/examplemod/client/render/tileentity/RenderExampleTileEntity.java
new file mode 100644
index 0000000..777eda7
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/client/render/tileentity/RenderExampleTileEntity.java
@@ -0,0 +1,104 @@
+package io.github.cadiboo.examplemod.client.render.tileentity;
+
+import io.github.cadiboo.examplemod.client.ClientUtil;
+import io.github.cadiboo.examplemod.init.ModBlocks;
+import io.github.cadiboo.examplemod.tileentity.TileEntityExampleTileEntity;
+import io.github.cadiboo.examplemod.util.ModUtil;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.BufferBuilder;
+import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.client.model.animation.FastTESR;
+import org.lwjgl.util.vector.Matrix4f;
+import org.lwjgl.util.vector.Vector3f;
+
+import javax.annotation.Nonnull;
+
+/**
+ * @author V0IDW4LK3R
+ * @author Cadiboo
+ */
+public class RenderExampleTileEntity extends FastTESR {
+
+ /**
+ * The render method that gets called for your FastTESR implementation. This is where you render things.
+ *
+ * @param tileEntity your TileEntity instance.
+ * @param x the X position of the TE in view space.
+ * @param y the Y position of the TE in view space.
+ * @param z the Z position of the TE in view space.
+ * @param partialTicks the amount of partial ticks escaped. Partial ticks happen when there are multiple frames per tick.
+ * @param destroyStage the destroy progress of the TE. You may use it to render the "breaking" animation.
+ * @param partial currently seems to be a 1.0 constant.
+ * @param buffer the BufferBuilder containing vertex data for vertices being rendered. It is safe to assume that the format is {@link DefaultVertexFormats#BLOCK}. It is also safe to assume that the GL primitive for drawing is QUADS.
+ */
+ @Override
+ public void renderTileEntityFast(@Nonnull final TileEntityExampleTileEntity tileEntity, final double x, final double y, final double z, final float partialTicks, final int destroyStage, final float partial, @Nonnull final BufferBuilder buffer) {
+ final ResourceLocation registryName = ModBlocks.EXAMPLE_TILE_ENTITY.getRegistryName();
+ final TextureAtlasSprite sprite = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(new ResourceLocation(registryName.getNamespace(), "block/" + registryName.getPath()).toString());
+
+ // rotations need to be in radians
+ final float quarterRotation = (float) Math.PI / 2;
+ final float rotation = (float) ModUtil.map(getWorld().getTotalWorldTime() + partialTicks % 360, 0, 360, -Math.PI, Math.PI);
+
+ // the 4 forward rotating quads
+ for (int i = 0; i < 4; i++) {
+ ClientUtil.renderSimpleQuad(
+ new Vector3f((float) x + 0.5F, (float) y, (float) z + 0.5F),
+ buffer,
+ new Matrix4f()
+ .rotate(rotation + quarterRotation * i, new Vector3f(0, 1, 0)),
+ ClientUtil.color(0xFF, 0xFF, 0xFF),
+ sprite,
+ 240,
+ 0
+ );
+ }
+ // the 4 backward rotating quads
+ for (int i = 0; i < 4; i++) {
+ ClientUtil.renderSimpleQuad(
+ new Vector3f((float) x + 0.5F, (float) y, (float) z + 0.5F),
+ buffer,
+ new Matrix4f()
+ .rotate(rotation + quarterRotation * i, new Vector3f(0, -1, 0)),
+ ClientUtil.color(0xFF, 0xFF, 0xFF),
+ sprite,
+ 240,
+ 0
+ );
+ }
+ //TODO top & translations
+ // the bottom horizontal quad
+ final Matrix4f matrixBottom = Matrix4f.mul(
+ Matrix4f
+ .rotate(quarterRotation,
+ new Vector3f(1, 0, 0),
+ Matrix4f.setIdentity(new Matrix4f()),
+ Matrix4f.setIdentity(new Matrix4f())
+ )
+ ,
+ Matrix4f
+ .rotate(
+ rotation,
+ new Vector3f(0, 0, 1),
+ Matrix4f.setIdentity(new Matrix4f()),
+ Matrix4f.setIdentity(new Matrix4f())
+ )
+ ,
+ new Matrix4f()
+ ).scale(new Vector3f(0.5F, 0.5F, 0.5F)
+ );
+ ClientUtil.renderSimpleQuad(
+ new Vector3f((float) x + 0.5F, (float) y, (float) z + 0.5F),
+ buffer,
+ matrixBottom,
+ ClientUtil.color(0xFF, 0xFF, 0xFF),
+ sprite,
+ 240,
+ 0
+ );
+
+ }
+
+}
diff --git a/src/main/java/io/github/cadiboo/examplemod/client/render/tileentity/package-info.java b/src/main/java/io/github/cadiboo/examplemod/client/render/tileentity/package-info.java
new file mode 100644
index 0000000..44bb53f
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/client/render/tileentity/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Contains the {@link net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer}s for our mod's {@link net.minecraft.tileentity.TileEntity TileEntities}
+ */
+
+package io.github.cadiboo.examplemod.client.render.tileentity;
diff --git a/src/main/java/io/github/cadiboo/examplemod/config/ClientConfig.java b/src/main/java/io/github/cadiboo/examplemod/config/ClientConfig.java
deleted file mode 100644
index 2c0d8cd..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/config/ClientConfig.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package io.github.cadiboo.examplemod.config;
-
-import io.github.cadiboo.examplemod.ExampleMod;
-import net.minecraft.item.DyeColor;
-import net.minecraftforge.common.ForgeConfigSpec;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * For configuration settings that change the behaviour of code on the LOGICAL CLIENT.
- * This can be moved to an inner class of ExampleModConfig, but is separate because of personal preference and to keep the code organised
- *
- * @author Cadiboo
- */
-final class ClientConfig {
-
- final ForgeConfigSpec.BooleanValue clientBoolean;
- final ForgeConfigSpec.ConfigValue> clientStringList;
- final ForgeConfigSpec.EnumValue clientDyeColorEnum;
-
- final ForgeConfigSpec.BooleanValue modelTranslucency;
- final ForgeConfigSpec.DoubleValue modelScale;
-
- ClientConfig(final ForgeConfigSpec.Builder builder) {
- builder.push("general");
- clientBoolean = builder
- .comment("An example boolean in the client config")
- .translation(ExampleMod.MODID + ".config.clientBoolean")
- .define("clientBoolean", true);
- clientStringList = builder
- .comment("An example list of Strings in the client config")
- .translation(ExampleMod.MODID + ".config.clientStringList")
- .define("clientStringList", new ArrayList<>());
- clientDyeColorEnum = builder
- .comment("An example DyeColor enum in the client config")
- .translation(ExampleMod.MODID + ".config.clientDyeColorEnum")
- .defineEnum("clientDyeColorEnum", DyeColor.WHITE);
-
- modelTranslucency = builder
- .comment("If the model should be rendered translucent")
- .translation(ExampleMod.MODID + ".config.modelTranslucency")
- .define("modelTranslucency", true);
- modelScale = builder
- .comment("The scale to render the model at")
- .translation(ExampleMod.MODID + ".config.modelScale")
- .defineInRange("modelScale", 0.0625F, 0.0001F, 100F);
- builder.pop();
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/config/ConfigHelper.java b/src/main/java/io/github/cadiboo/examplemod/config/ConfigHelper.java
deleted file mode 100644
index 4d4bb65..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/config/ConfigHelper.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package io.github.cadiboo.examplemod.config;
-
-import net.minecraftforge.fml.config.ModConfig;
-
-/**
- * This bakes the config values to normal fields
- *
- * @author Cadiboo
- * It can be merged into the main ExampleModConfig class, but is separate because of personal preference and to keep the code organised
- */
-public final class ConfigHelper {
-
- public static void bakeClient(final ModConfig config) {
- ExampleModConfig.clientBoolean = ConfigHolder.CLIENT.clientBoolean.get();
- ExampleModConfig.clientStringList = ConfigHolder.CLIENT.clientStringList.get();
- ExampleModConfig.clientDyeColorEnum = ConfigHolder.CLIENT.clientDyeColorEnum.get();
-
- ExampleModConfig.modelTranslucency = ConfigHolder.CLIENT.modelTranslucency.get();
- ExampleModConfig.modelScale = ConfigHolder.CLIENT.modelScale.get().floatValue();
- }
-
- public static void bakeServer(final ModConfig config) {
- ExampleModConfig.serverBoolean = ConfigHolder.SERVER.serverBoolean.get();
- ExampleModConfig.serverStringList = ConfigHolder.SERVER.serverStringList.get();
- ExampleModConfig.serverEnumDyeColor = ConfigHolder.SERVER.serverEnumDyeColor.get();
-
- ExampleModConfig.electricFurnaceEnergySmeltCostPerTick = ConfigHolder.SERVER.electricFurnaceEnergySmeltCostPerTick.get();
- ExampleModConfig.heatCollectorTransferAmountPerTick = ConfigHolder.SERVER.heatCollectorTransferAmountPerTick.get();
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/config/ConfigHolder.java b/src/main/java/io/github/cadiboo/examplemod/config/ConfigHolder.java
deleted file mode 100644
index 7d68e1d..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/config/ConfigHolder.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package io.github.cadiboo.examplemod.config;
-
-import net.minecraftforge.common.ForgeConfigSpec;
-import org.apache.commons.lang3.tuple.Pair;
-
-/**
- * This holds the Client & Server Configs and the Client & Server ConfigSpecs.
- * It can be merged into the main ExampleModConfig class, but is separate because of personal preference and to keep the code organised
- *
- * @author Cadiboo
- */
-public final class ConfigHolder {
-
- public static final ForgeConfigSpec CLIENT_SPEC;
- public static final ForgeConfigSpec SERVER_SPEC;
- static final ClientConfig CLIENT;
- static final ServerConfig SERVER;
- static {
- {
- final Pair specPair = new ForgeConfigSpec.Builder().configure(ClientConfig::new);
- CLIENT = specPair.getLeft();
- CLIENT_SPEC = specPair.getRight();
- }
- {
- final Pair specPair = new ForgeConfigSpec.Builder().configure(ServerConfig::new);
- SERVER = specPair.getLeft();
- SERVER_SPEC = specPair.getRight();
- }
- }
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/config/ExampleModConfig.java b/src/main/java/io/github/cadiboo/examplemod/config/ExampleModConfig.java
deleted file mode 100644
index 0f8b16c..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/config/ExampleModConfig.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package io.github.cadiboo.examplemod.config;
-
-import net.minecraft.item.DyeColor;
-
-import java.util.List;
-
-/**
- * This holds the baked (runtime) values for our config.
- * These values should never be from changed outside this package.
- * This can be split into multiple classes (Server, Client, Player, Common)
- * but has been kept in one class for simplicity
- *
- * @author Cadiboo
- */
-public final class ExampleModConfig {
-
- // Client
- public static boolean clientBoolean;
- public static List clientStringList;
- public static DyeColor clientDyeColorEnum;
-
- public static boolean modelTranslucency;
- public static float modelScale;
-
- // Server
- public static boolean serverBoolean;
- public static List serverStringList;
- public static DyeColor serverEnumDyeColor;
-
- public static int electricFurnaceEnergySmeltCostPerTick = 100;
- public static int heatCollectorTransferAmountPerTick = 100;
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/config/ModConfig.java b/src/main/java/io/github/cadiboo/examplemod/config/ModConfig.java
new file mode 100644
index 0000000..1489d7a
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/config/ModConfig.java
@@ -0,0 +1,65 @@
+package io.github.cadiboo.examplemod.config;
+
+import io.github.cadiboo.examplemod.util.ModReference;
+import net.minecraftforge.common.config.Config;
+import net.minecraftforge.common.config.Config.Comment;
+import net.minecraftforge.common.config.Config.LangKey;
+import net.minecraftforge.common.config.ConfigManager;
+import net.minecraftforge.fml.client.event.ConfigChangedEvent;
+import net.minecraftforge.fml.common.Mod;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+import static io.github.cadiboo.examplemod.util.ModReference.*;
+
+/**
+ * Our Mod's configuration
+ *
+ * @author Cadiboo
+ */
+@SuppressWarnings("WeakerAccess")
+@Config(modid = MOD_ID)
+@LangKey(MOD_ID + ".config.title")
+public final class ModConfig {
+
+ @Comment("Boolean")
+ public static boolean exampleBoolean = false;
+
+ //sub category
+ @Comment("Numbers")
+ public static Numbers numbers = new Numbers(1, 2.5f, 3.1d);
+
+ public static class Numbers {
+
+ @Comment("An Integer (int) type number")
+ public int int_;
+ @Comment("A Float (floating point) type number")
+ public float float_;
+ @Comment("A Double (double length floating point) type number")
+ public double double_;
+
+ public Numbers(final int int_, final float float_, final double double_) {
+ this.int_ = int_;
+ this.float_ = float_;
+ this.double_ = double_;
+ }
+
+ }
+
+ @Mod.EventBusSubscriber(modid = MOD_ID)
+ private static class EventHandler {
+
+ /**
+ * Inject the new values and save to the config file when the config has been changed from the GUI.
+ *
+ * @param event The event
+ */
+ @SubscribeEvent
+ public static void onConfigChanged(final ConfigChangedEvent.OnConfigChangedEvent event) {
+ if (event.getModID().equals(MOD_ID)) {
+ ConfigManager.sync(MOD_ID, Config.Type.INSTANCE);
+ }
+ }
+
+ }
+
+}
diff --git a/src/main/java/io/github/cadiboo/examplemod/config/ServerConfig.java b/src/main/java/io/github/cadiboo/examplemod/config/ServerConfig.java
deleted file mode 100644
index 0189ed9..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/config/ServerConfig.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package io.github.cadiboo.examplemod.config;
-
-import io.github.cadiboo.examplemod.ExampleMod;
-import net.minecraft.item.DyeColor;
-import net.minecraftforge.common.ForgeConfigSpec;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * For configuration settings that change the behaviour of code on the LOGICAL SERVER.
- * This can be moved to an inner class of ExampleModConfig, but is separate because of personal preference and to keep the code organised
- *
- * @author Cadiboo
- */
-final class ServerConfig {
-
- final ForgeConfigSpec.BooleanValue serverBoolean;
- final ForgeConfigSpec.ConfigValue> serverStringList;
- final ForgeConfigSpec.ConfigValue serverEnumDyeColor;
-
- final ForgeConfigSpec.IntValue electricFurnaceEnergySmeltCostPerTick;
- final ForgeConfigSpec.IntValue heatCollectorTransferAmountPerTick;
-
- ServerConfig(final ForgeConfigSpec.Builder builder) {
- builder.push("general");
- serverBoolean = builder
- .comment("An example boolean in the server config")
- .translation(ExampleMod.MODID + ".config.serverBoolean")
- .define("serverBoolean", true);
- serverStringList = builder
- .comment("An example list of Strings in the server config")
- .translation(ExampleMod.MODID + ".config.serverStringList")
- .define("serverStringList", new ArrayList<>());
- serverEnumDyeColor = builder
- .comment("An example enum DyeColor in the server config")
- .translation(ExampleMod.MODID + ".config.serverEnumDyeColor")
- .defineEnum("serverEnumDyeColor", DyeColor.WHITE);
-
- electricFurnaceEnergySmeltCostPerTick = builder
- .comment("How much energy for the Electric Furnace to consume to smelt an item per tick")
- .translation(ExampleMod.MODID + ".config.electricFurnaceEnergySmeltCostPerTick")
- .defineInRange("electricFurnaceEnergySmeltCostPerTick", 100, 0, Integer.MAX_VALUE);
- heatCollectorTransferAmountPerTick = builder
- .comment("How much energy for the Heat Collector to try and transfer in each direction per tick")
- .translation(ExampleMod.MODID + ".config.heatCollectorTransferAmountPerTick")
- .defineInRange("heatCollectorTransferAmountPerTick", 100, 0, Integer.MAX_VALUE);
- builder.pop();
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/config/package-info.java b/src/main/java/io/github/cadiboo/examplemod/config/package-info.java
new file mode 100644
index 0000000..038128b
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/config/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Contains our mod's Configuration/Settings
+ */
+
+package io.github.cadiboo.examplemod.config;
diff --git a/src/main/java/io/github/cadiboo/examplemod/container/ElectricFurnaceContainer.java b/src/main/java/io/github/cadiboo/examplemod/container/ElectricFurnaceContainer.java
deleted file mode 100644
index 3ce50aa..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/container/ElectricFurnaceContainer.java
+++ /dev/null
@@ -1,140 +0,0 @@
-package io.github.cadiboo.examplemod.container;
-
-import io.github.cadiboo.examplemod.init.ModBlocks;
-import io.github.cadiboo.examplemod.init.ModContainerTypes;
-import io.github.cadiboo.examplemod.tileentity.ElectricFurnaceTileEntity;
-import net.minecraft.client.network.play.ClientPlayNetHandler;
-import net.minecraft.entity.player.PlayerEntity;
-import net.minecraft.entity.player.PlayerInventory;
-import net.minecraft.entity.player.ServerPlayerEntity;
-import net.minecraft.inventory.container.Container;
-import net.minecraft.inventory.container.ContainerType;
-import net.minecraft.inventory.container.Slot;
-import net.minecraft.item.ItemStack;
-import net.minecraft.network.PacketBuffer;
-import net.minecraft.network.play.server.SWindowPropertyPacket;
-import net.minecraft.tileentity.TileEntity;
-import net.minecraft.util.IWorldPosCallable;
-import net.minecraft.util.IntReferenceHolder;
-import net.minecraftforge.fml.network.IContainerFactory;
-import net.minecraftforge.items.SlotItemHandler;
-
-import javax.annotation.Nonnull;
-import java.util.Objects;
-
-/**
- * Smelt time is synced with
- * Server: Each tick {@link #detectAndSendChanges()} is called ({@link ServerPlayerEntity#tick()})
- * Server: The (tracked) value of the tile's energy is updated ({@link #updateProgressBar(int, int)})
- * Server: If the value is different from the value last sent to the client ({@link IntReferenceHolder#isDirty()}),
- * it is synced to the client ({@link ServerPlayerEntity#sendWindowProperty(Container, int, int)})
- * Client: The sync packet is received ({@link ClientPlayNetHandler#handleWindowProperty(SWindowPropertyPacket)})
- * and the tracked value of is updated ({@link Container#updateProgressBar(int, int)})
- * Client: The tile's data is set to the new value
- *
- * @author Cadiboo
- */
-public class ElectricFurnaceContainer extends Container {
-
- public final ElectricFurnaceTileEntity tileEntity;
- private final IWorldPosCallable canInteractWithCallable;
-
- /**
- * Logical-client-side constructor, called from {@link ContainerType#create(IContainerFactory)}
- * Calls the logical-server-side constructor with the TileEntity at the pos in the PacketBuffer
- */
- public ElectricFurnaceContainer(final int windowId, final PlayerInventory playerInventory, final PacketBuffer data) {
- this(windowId, playerInventory, getTileEntity(playerInventory, data));
- }
-
- /**
- * Constructor called logical-server-side from {@link ElectricFurnaceTileEntity#createMenu}
- * and logical-client-side from {@link #ElectricFurnaceContainer(int, PlayerInventory, PacketBuffer)}
- */
- public ElectricFurnaceContainer(final int windowId, final PlayerInventory playerInventory, final ElectricFurnaceTileEntity tileEntity) {
- super(ModContainerTypes.ELECTRIC_FURNACE.get(), windowId);
- this.tileEntity = tileEntity;
- this.canInteractWithCallable = IWorldPosCallable.of(tileEntity.getWorld(), tileEntity.getPos());
-
- // Add tracking for data (Syncs to client/updates value when it changes)
- this.trackInt(new FunctionalIntReferenceHolder(() -> tileEntity.smeltTimeLeft, v -> tileEntity.smeltTimeLeft = (short) v));
- this.trackInt(new FunctionalIntReferenceHolder(() -> tileEntity.maxSmeltTime, v -> tileEntity.maxSmeltTime = (short) v));
-
- // Add all the slots for the tileEntity's inventory and the playerInventory to this container
-
- // Tile inventory slot(s)
- this.addSlot(new SlotItemHandler(tileEntity.inventory, ElectricFurnaceTileEntity.INPUT_SLOT, 56, 35));
- this.addSlot(new SlotItemHandler(tileEntity.inventory, ElectricFurnaceTileEntity.OUTPUT_SLOT, 116, 35));
-
- final int playerInventoryStartX = 8;
- final int playerInventoryStartY = 84;
- final int slotSizePlus2 = 18; // slots are 16x16, plus 2 (for spacing/borders) is 18x18
-
- // Player Top Inventory slots
- for (int row = 0; row < 3; ++row) {
- for (int column = 0; column < 9; ++column) {
- this.addSlot(new Slot(playerInventory, 9 + (row * 9) + column, playerInventoryStartX + (column * slotSizePlus2), playerInventoryStartY + (row * slotSizePlus2)));
- }
- }
-
- final int playerHotbarY = playerInventoryStartY + slotSizePlus2 * 3 + 4;
- // Player Hotbar slots
- for (int column = 0; column < 9; ++column) {
- this.addSlot(new Slot(playerInventory, column, playerInventoryStartX + (column * slotSizePlus2), playerHotbarY));
- }
- }
-
- private static ElectricFurnaceTileEntity getTileEntity(final PlayerInventory playerInventory, final PacketBuffer data) {
- Objects.requireNonNull(playerInventory, "playerInventory cannot be null!");
- Objects.requireNonNull(data, "data cannot be null!");
- final TileEntity tileAtPos = playerInventory.player.world.getTileEntity(data.readBlockPos());
- if (tileAtPos instanceof ElectricFurnaceTileEntity)
- return (ElectricFurnaceTileEntity) tileAtPos;
- throw new IllegalStateException("Tile entity is not correct! " + tileAtPos);
- }
-
- /**
- * Generic & dynamic version of {@link Container#transferStackInSlot(PlayerEntity, int)}.
- * Handle when the stack in slot {@code index} is shift-clicked.
- * Normally this moves the stack between the player inventory and the other inventory(s).
- *
- * @param player the player passed in
- * @param index the index passed in
- * @return the {@link ItemStack}
- */
- @Nonnull
- @Override
- public ItemStack transferStackInSlot(final PlayerEntity player, final int index) {
- ItemStack returnStack = ItemStack.EMPTY;
- final Slot slot = this.inventorySlots.get(index);
- if (slot != null && slot.getHasStack()) {
- final ItemStack slotStack = slot.getStack();
- returnStack = slotStack.copy();
-
- final int containerSlots = this.inventorySlots.size() - player.inventory.mainInventory.size();
- if (index < containerSlots) {
- if (!mergeItemStack(slotStack, containerSlots, this.inventorySlots.size(), true)) {
- return ItemStack.EMPTY;
- }
- } else if (!mergeItemStack(slotStack, 0, containerSlots, false)) {
- return ItemStack.EMPTY;
- }
- if (slotStack.getCount() == 0) {
- slot.putStack(ItemStack.EMPTY);
- } else {
- slot.onSlotChanged();
- }
- if (slotStack.getCount() == returnStack.getCount()) {
- return ItemStack.EMPTY;
- }
- slot.onTake(player, slotStack);
- }
- return returnStack;
- }
-
- @Override
- public boolean canInteractWith(@Nonnull final PlayerEntity player) {
- return isWithinUsableDistance(canInteractWithCallable, player, ModBlocks.ELECTRIC_FURNACE.get());
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/container/FunctionalIntReferenceHolder.java b/src/main/java/io/github/cadiboo/examplemod/container/FunctionalIntReferenceHolder.java
deleted file mode 100644
index 828eaa4..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/container/FunctionalIntReferenceHolder.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package io.github.cadiboo.examplemod.container;
-
-import net.minecraft.util.IntReferenceHolder;
-
-import java.util.function.IntConsumer;
-import java.util.function.IntSupplier;
-
-/**
- * An {@link IntReferenceHolder} that uses {@link IntSupplier}s for its getter and setter
- *
- * @author Cadiboo
- */
-public class FunctionalIntReferenceHolder extends IntReferenceHolder {
-
- private final IntSupplier getter;
- private final IntConsumer setter;
-
- public FunctionalIntReferenceHolder(final IntSupplier getter, final IntConsumer setter) {
- this.getter = getter;
- this.setter = setter;
- }
-
- @Override
- public int get() {
- return this.getter.getAsInt();
- }
-
- @Override
- public void set(final int newValue) {
- this.setter.accept(newValue);
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/container/HeatCollectorContainer.java b/src/main/java/io/github/cadiboo/examplemod/container/HeatCollectorContainer.java
deleted file mode 100644
index a67fa77..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/container/HeatCollectorContainer.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package io.github.cadiboo.examplemod.container;
-
-import io.github.cadiboo.examplemod.init.ModBlocks;
-import io.github.cadiboo.examplemod.init.ModContainerTypes;
-import io.github.cadiboo.examplemod.tileentity.HeatCollectorTileEntity;
-import net.minecraft.entity.player.PlayerEntity;
-import net.minecraft.entity.player.PlayerInventory;
-import net.minecraft.inventory.container.Container;
-import net.minecraft.inventory.container.ContainerType;
-import net.minecraft.inventory.container.Slot;
-import net.minecraft.item.ItemStack;
-import net.minecraft.network.PacketBuffer;
-import net.minecraft.tileentity.TileEntity;
-import net.minecraft.util.IWorldPosCallable;
-import net.minecraftforge.fml.network.IContainerFactory;
-import net.minecraftforge.items.SlotItemHandler;
-
-import javax.annotation.Nonnull;
-import java.util.Objects;
-
-/**
- * @author Cadiboo
- */
-public class HeatCollectorContainer extends Container {
-
- public final HeatCollectorTileEntity tileEntity;
- private final IWorldPosCallable canInteractWithCallable;
-
- /**
- * Logical-client-side constructor, called from {@link ContainerType#create(IContainerFactory)}
- * Calls the logical-server-side constructor with the TileEntity at the pos in the PacketBuffer
- */
- public HeatCollectorContainer(final int windowId, final PlayerInventory playerInventory, final PacketBuffer data) {
- this(windowId, playerInventory, getTileEntity(playerInventory, data));
- }
-
- /**
- * Constructor called logical-server-side from {@link HeatCollectorTileEntity#createMenu}
- * and logical-client-side from {@link #HeatCollectorContainer(int, PlayerInventory, PacketBuffer)}
- */
- public HeatCollectorContainer(final int windowId, final PlayerInventory playerInventory, final HeatCollectorTileEntity tileEntity) {
- super(ModContainerTypes.HEAT_COLLECTOR.get(), windowId);
- this.tileEntity = tileEntity;
- this.canInteractWithCallable = IWorldPosCallable.of(tileEntity.getWorld(), tileEntity.getPos());
-
- // Add all the slots for the tileEntity's inventory and the playerInventory to this container
-
- // Tile inventory slot(s)
- this.addSlot(new SlotItemHandler(tileEntity.inventory, HeatCollectorTileEntity.FUEL_SLOT, 80, 35));
-
- final int playerInventoryStartX = 8;
- final int playerInventoryStartY = 84;
- final int slotSizePlus2 = 18; // slots are 16x16, plus 2 (for spacing/borders) is 18x18
-
- // Player Top Inventory slots
- for (int row = 0; row < 3; ++row) {
- for (int column = 0; column < 9; ++column) {
- this.addSlot(new Slot(playerInventory, 9 + (row * 9) + column, playerInventoryStartX + (column * slotSizePlus2), playerInventoryStartY + (row * slotSizePlus2)));
- }
- }
-
- final int playerHotbarY = playerInventoryStartY + slotSizePlus2 * 3 + 4;
- // Player Hotbar slots
- for (int column = 0; column < 9; ++column) {
- this.addSlot(new Slot(playerInventory, column, playerInventoryStartX + (column * slotSizePlus2), playerHotbarY));
- }
- }
-
- private static HeatCollectorTileEntity getTileEntity(final PlayerInventory playerInventory, final PacketBuffer data) {
- Objects.requireNonNull(playerInventory, "playerInventory cannot be null!");
- Objects.requireNonNull(data, "data cannot be null!");
- final TileEntity tileAtPos = playerInventory.player.world.getTileEntity(data.readBlockPos());
- if (tileAtPos instanceof HeatCollectorTileEntity)
- return (HeatCollectorTileEntity) tileAtPos;
- throw new IllegalStateException("Tile entity is not correct! " + tileAtPos);
- }
-
- /**
- * Generic & dynamic version of {@link Container#transferStackInSlot(PlayerEntity, int)}.
- * Handle when the stack in slot {@code index} is shift-clicked.
- * Normally this moves the stack between the player inventory and the other inventory(s).
- *
- * @param player the player passed in
- * @param index the index passed in
- * @return the {@link ItemStack}
- */
- @Nonnull
- @Override
- public ItemStack transferStackInSlot(final PlayerEntity player, final int index) {
- ItemStack returnStack = ItemStack.EMPTY;
- final Slot slot = this.inventorySlots.get(index);
- if (slot != null && slot.getHasStack()) {
- final ItemStack slotStack = slot.getStack();
- returnStack = slotStack.copy();
-
- final int containerSlots = this.inventorySlots.size() - player.inventory.mainInventory.size();
- if (index < containerSlots) {
- if (!mergeItemStack(slotStack, containerSlots, this.inventorySlots.size(), true)) {
- return ItemStack.EMPTY;
- }
- } else if (!mergeItemStack(slotStack, 0, containerSlots, false)) {
- return ItemStack.EMPTY;
- }
- if (slotStack.getCount() == 0) {
- slot.putStack(ItemStack.EMPTY);
- } else {
- slot.onSlotChanged();
- }
- if (slotStack.getCount() == returnStack.getCount()) {
- return ItemStack.EMPTY;
- }
- slot.onTake(player, slotStack);
- }
- return returnStack;
- }
-
- @Override
- public boolean canInteractWith(@Nonnull final PlayerEntity player) {
- return isWithinUsableDistance(canInteractWithCallable, player, ModBlocks.HEAT_COLLECTOR.get());
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/container/ModFurnaceContainer.java b/src/main/java/io/github/cadiboo/examplemod/container/ModFurnaceContainer.java
deleted file mode 100644
index 9b2321c..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/container/ModFurnaceContainer.java
+++ /dev/null
@@ -1,143 +0,0 @@
-package io.github.cadiboo.examplemod.container;
-
-import io.github.cadiboo.examplemod.init.ModBlocks;
-import io.github.cadiboo.examplemod.init.ModContainerTypes;
-import io.github.cadiboo.examplemod.tileentity.ModFurnaceTileEntity;
-import net.minecraft.client.network.play.ClientPlayNetHandler;
-import net.minecraft.entity.player.PlayerEntity;
-import net.minecraft.entity.player.PlayerInventory;
-import net.minecraft.entity.player.ServerPlayerEntity;
-import net.minecraft.inventory.container.Container;
-import net.minecraft.inventory.container.ContainerType;
-import net.minecraft.inventory.container.Slot;
-import net.minecraft.item.ItemStack;
-import net.minecraft.network.PacketBuffer;
-import net.minecraft.network.play.server.SWindowPropertyPacket;
-import net.minecraft.tileentity.TileEntity;
-import net.minecraft.util.IWorldPosCallable;
-import net.minecraft.util.IntReferenceHolder;
-import net.minecraftforge.fml.network.IContainerFactory;
-import net.minecraftforge.items.SlotItemHandler;
-
-import javax.annotation.Nonnull;
-import java.util.Objects;
-
-/**
- * Smelt time is synced with
- * Server: Each tick {@link #detectAndSendChanges()} is called ({@link ServerPlayerEntity#tick()})
- * Server: The (tracked) value of the tile's energy is updated ({@link #updateProgressBar(int, int)})
- * Server: If the value is different from the value last sent to the client ({@link IntReferenceHolder#isDirty()}),
- * it is synced to the client ({@link ServerPlayerEntity#sendWindowProperty(Container, int, int)})
- * Client: The sync packet is received ({@link ClientPlayNetHandler#handleWindowProperty(SWindowPropertyPacket)})
- * and the tracked value of is updated ({@link Container#updateProgressBar(int, int)})
- * Client: The tile's data is set to the new value
- *
- * @author Cadiboo
- */
-public class ModFurnaceContainer extends Container {
-
- public final ModFurnaceTileEntity tileEntity;
- private final IWorldPosCallable canInteractWithCallable;
-
- /**
- * Logical-client-side constructor, called from {@link ContainerType#create(IContainerFactory)}
- * Calls the logical-server-side constructor with the TileEntity at the pos in the PacketBuffer
- */
- public ModFurnaceContainer(final int windowId, final PlayerInventory playerInventory, final PacketBuffer data) {
- this(windowId, playerInventory, getTileEntity(playerInventory, data));
- }
-
- /**
- * Constructor called logical-server-side from {@link ModFurnaceTileEntity#createMenu}
- * and logical-client-side from {@link #ModFurnaceContainer(int, PlayerInventory, PacketBuffer)}
- */
- public ModFurnaceContainer(final int windowId, final PlayerInventory playerInventory, final ModFurnaceTileEntity tileEntity) {
- super(ModContainerTypes.MOD_FURNACE.get(), windowId);
- this.tileEntity = tileEntity;
- this.canInteractWithCallable = IWorldPosCallable.of(tileEntity.getWorld(), tileEntity.getPos());
-
- // Add tracking for data (Syncs to client/updates value when it changes)
- this.trackInt(new FunctionalIntReferenceHolder(() -> tileEntity.smeltTimeLeft, v -> tileEntity.smeltTimeLeft = (short) v));
- this.trackInt(new FunctionalIntReferenceHolder(() -> tileEntity.maxSmeltTime, v -> tileEntity.maxSmeltTime = (short) v));
- this.trackInt(new FunctionalIntReferenceHolder(() -> tileEntity.fuelBurnTimeLeft, v -> tileEntity.fuelBurnTimeLeft = (short) v));
- this.trackInt(new FunctionalIntReferenceHolder(() -> tileEntity.maxFuelBurnTime, v -> tileEntity.maxFuelBurnTime = (short) v));
-
- // Add all the slots for the tileEntity's inventory and the playerInventory to this container
-
- // Tile inventory slot(s)
- this.addSlot(new SlotItemHandler(tileEntity.inventory, ModFurnaceTileEntity.FUEL_SLOT, 56, 53));
- this.addSlot(new SlotItemHandler(tileEntity.inventory, ModFurnaceTileEntity.INPUT_SLOT, 56, 17));
- this.addSlot(new SlotItemHandler(tileEntity.inventory, ModFurnaceTileEntity.OUTPUT_SLOT, 116, 35));
-
- final int playerInventoryStartX = 8;
- final int playerInventoryStartY = 84;
- final int slotSizePlus2 = 18; // slots are 16x16, plus 2 (for spacing/borders) is 18x18
-
- // Player Top Inventory slots
- for (int row = 0; row < 3; ++row) {
- for (int column = 0; column < 9; ++column) {
- this.addSlot(new Slot(playerInventory, 9 + (row * 9) + column, playerInventoryStartX + (column * slotSizePlus2), playerInventoryStartY + (row * slotSizePlus2)));
- }
- }
-
- final int playerHotbarY = playerInventoryStartY + slotSizePlus2 * 3 + 4;
- // Player Hotbar slots
- for (int column = 0; column < 9; ++column) {
- this.addSlot(new Slot(playerInventory, column, playerInventoryStartX + (column * slotSizePlus2), playerHotbarY));
- }
- }
-
- private static ModFurnaceTileEntity getTileEntity(final PlayerInventory playerInventory, final PacketBuffer data) {
- Objects.requireNonNull(playerInventory, "playerInventory cannot be null!");
- Objects.requireNonNull(data, "data cannot be null!");
- final TileEntity tileAtPos = playerInventory.player.world.getTileEntity(data.readBlockPos());
- if (tileAtPos instanceof ModFurnaceTileEntity)
- return (ModFurnaceTileEntity) tileAtPos;
- throw new IllegalStateException("Tile entity is not correct! " + tileAtPos);
- }
-
- /**
- * Generic & dynamic version of {@link Container#transferStackInSlot(PlayerEntity, int)}.
- * Handle when the stack in slot {@code index} is shift-clicked.
- * Normally this moves the stack between the player inventory and the other inventory(s).
- *
- * @param player the player passed in
- * @param index the index passed in
- * @return the {@link ItemStack}
- */
- @Nonnull
- @Override
- public ItemStack transferStackInSlot(final PlayerEntity player, final int index) {
- ItemStack returnStack = ItemStack.EMPTY;
- final Slot slot = this.inventorySlots.get(index);
- if (slot != null && slot.getHasStack()) {
- final ItemStack slotStack = slot.getStack();
- returnStack = slotStack.copy();
-
- final int containerSlots = this.inventorySlots.size() - player.inventory.mainInventory.size();
- if (index < containerSlots) {
- if (!mergeItemStack(slotStack, containerSlots, this.inventorySlots.size(), true)) {
- return ItemStack.EMPTY;
- }
- } else if (!mergeItemStack(slotStack, 0, containerSlots, false)) {
- return ItemStack.EMPTY;
- }
- if (slotStack.getCount() == 0) {
- slot.putStack(ItemStack.EMPTY);
- } else {
- slot.onSlotChanged();
- }
- if (slotStack.getCount() == returnStack.getCount()) {
- return ItemStack.EMPTY;
- }
- slot.onTake(player, slotStack);
- }
- return returnStack;
- }
-
- @Override
- public boolean canInteractWith(@Nonnull final PlayerEntity player) {
- return isWithinUsableDistance(canInteractWithCallable, player, ModBlocks.MOD_FURNACE.get());
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/creativetab/ModCreativeTabs.java b/src/main/java/io/github/cadiboo/examplemod/creativetab/ModCreativeTabs.java
new file mode 100644
index 0000000..4e9c5a4
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/creativetab/ModCreativeTabs.java
@@ -0,0 +1,76 @@
+package io.github.cadiboo.examplemod.creativetab;
+
+import net.minecraft.creativetab.CreativeTabs;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.NonNullList;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+import java.util.function.Supplier;
+
+import static io.github.cadiboo.examplemod.util.ModReference.MOD_ID;
+
+/**
+ * All the creative tabs of our mod
+ * Modified by Cadiboo
+ *
+ * @author jabelar
+ * @author Cadiboo
+ */
+public final class ModCreativeTabs {
+
+ /**
+ * Instantiate creative tabs
+ */
+ public static final CustomCreativeTab CREATIVE_TAB = new CustomCreativeTab(MOD_ID, true, () -> new ItemStack(ModBlocks.EXAMPLE_BLOCK));
+
+ /**
+ * This class is used for an extra tab in the creative inventory.
+ * Many mods like to group their special items and blocks in a dedicated tab although it is also perfectly acceptable to put them in the vanilla tabs where it makes sense.
+ */
+ public static class CustomCreativeTab extends CreativeTabs {
+
+ private final boolean hasSearchBar;
+ private final Supplier iconSupplier;
+
+ public CustomCreativeTab(final String name, final boolean hasSearchBar, final Supplier iconSupplier) {
+ super(name);
+ this.hasSearchBar = hasSearchBar;
+ this.iconSupplier = iconSupplier;
+ }
+
+ /**
+ * Gets the {@link ItemStack} to display for the tab's icon
+ */
+ @SideOnly(Side.CLIENT)
+ @Override
+ public ItemStack createIcon() {
+ return iconSupplier.get();
+ }
+
+ @Override
+ public String getBackgroundImageName() {
+ if (this.hasSearchBar) {
+ return "item_search.png";
+ } else {
+ return super.getBackgroundImageName();
+ }
+ }
+
+ /**
+ * Useful for adding extra items such as full variants of energy related items
+ */
+ @SideOnly(Side.CLIENT)
+ @Override
+ public void displayAllRelevantItems(final NonNullList items) {
+ super.displayAllRelevantItems(items);
+ }
+
+ @Override
+ public boolean hasSearchBar() {
+ return this.hasSearchBar;
+ }
+
+ }
+
+}
diff --git a/src/main/java/io/github/cadiboo/examplemod/creativetab/package-info.java b/src/main/java/io/github/cadiboo/examplemod/creativetab/package-info.java
new file mode 100644
index 0000000..d512025
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/creativetab/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Contains our mod's {@link net.minecraft.creativetab.CreativeTabs}
+ */
+
+package io.github.cadiboo.examplemod.creativetab;
diff --git a/src/main/java/io/github/cadiboo/examplemod/energy/SettableEnergyStorage.java b/src/main/java/io/github/cadiboo/examplemod/energy/SettableEnergyStorage.java
deleted file mode 100644
index dcbdb98..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/energy/SettableEnergyStorage.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package io.github.cadiboo.examplemod.energy;
-
-import net.minecraftforge.energy.EnergyStorage;
-
-/**
- * @author Cadiboo
- */
-public class SettableEnergyStorage extends EnergyStorage {
-
- public SettableEnergyStorage(final int capacity) {
- super(capacity);
- }
-
- public SettableEnergyStorage(final int capacity, final int maxTransfer) {
- super(capacity, maxTransfer);
- }
-
- public SettableEnergyStorage(final int capacity, final int maxReceive, final int maxExtract) {
- super(capacity, maxReceive, maxExtract);
- }
-
- public SettableEnergyStorage(final int capacity, final int maxReceive, final int maxExtract, final int energy) {
- super(capacity, maxReceive, maxExtract, energy);
- }
-
- /**
- * @return The amount of energy that was put into the storage
- */
- public int setEnergy(final int maxSet) {
- return this.energy = Math.min(this.capacity, maxSet);
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/entity/WildBoarEntity.java b/src/main/java/io/github/cadiboo/examplemod/entity/WildBoarEntity.java
deleted file mode 100644
index c8f33ea..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/entity/WildBoarEntity.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package io.github.cadiboo.examplemod.entity;
-
-import net.minecraft.entity.AgeableEntity;
-import net.minecraft.entity.EntityType;
-import net.minecraft.entity.SharedMonsterAttributes;
-import net.minecraft.entity.passive.PigEntity;
-import net.minecraft.entity.passive.horse.AbstractHorseEntity;
-import net.minecraft.network.IPacket;
-import net.minecraft.world.World;
-import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
-import net.minecraftforge.fml.network.FMLPlayMessages;
-import net.minecraftforge.fml.network.NetworkHooks;
-
-/**
- * A Wild Boar entity.
- * Literally just a pig (with a different texture).
- * TODO: Will have more stuff added to it soon. (Will charge at player
- *
- * @author Cadiboo
- */
-public class WildBoarEntity extends PigEntity {
-
- public WildBoarEntity(final EntityType extends WildBoarEntity> entityType, final World world) {
- super(entityType, world);
- }
-
- @Override
- protected void registerAttributes() {
- super.registerAttributes();
-
- final double baseSpeed = this.getAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).getBaseValue();
- final double baseHealth = this.getAttribute(SharedMonsterAttributes.MAX_HEALTH).getBaseValue();
- // Multiply base health and base speed by one and a half
- this.getAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(baseSpeed * 1.5D);
- this.getAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(baseHealth * 1.5D);
- }
-
- /**
- * Creates a child new entity from the parent entity.
- * Can be used to set additional on the child entity based on the parent.
- *
- * @param parent The entity that made this child
- * @return A new WildBoar
- * @see AbstractHorseEntity#setOffspringAttributes(AgeableEntity, AbstractHorseEntity)
- */
- @Override
- public WildBoarEntity createChild(final AgeableEntity parent) {
- // Use getType to support overrides in subclasses
- return (WildBoarEntity) getType().create(this.world);
- }
-
- /**
- * Called on the logical server to get a packet to send to the client containing data necessary to spawn your entity.
- * Using Forge's method instead of the default vanilla one allows extra stuff to work such as sending extra data,
- * using a non-default entity factory and having {@link IEntityAdditionalSpawnData} work.
- *
- * It is not actually necessary for our WildBoarEntity to use Forge's method as it doesn't need any of this extra
- * functionality, however, this is an example mod and many modders are unaware that Forge's method exists.
- *
- * @return The packet with data about your entity
- * @see FMLPlayMessages.SpawnEntity
- */
- @Override
- public IPacket> createSpawnPacket() {
- return NetworkHooks.getEntitySpawningPacket(this);
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/entity/package-info.java b/src/main/java/io/github/cadiboo/examplemod/entity/package-info.java
new file mode 100644
index 0000000..a3ec6d5
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/entity/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Contains our mod's {@link net.minecraft.entity.Entity Entities}
+ */
+
+package io.github.cadiboo.examplemod.entity;
diff --git a/src/main/java/io/github/cadiboo/examplemod/init/ModBlocks.java b/src/main/java/io/github/cadiboo/examplemod/init/ModBlocks.java
index 7f67659..63f39bd 100644
--- a/src/main/java/io/github/cadiboo/examplemod/init/ModBlocks.java
+++ b/src/main/java/io/github/cadiboo/examplemod/init/ModBlocks.java
@@ -1,42 +1,25 @@
package io.github.cadiboo.examplemod.init;
-import io.github.cadiboo.examplemod.ExampleMod;
-import io.github.cadiboo.examplemod.block.ElectricFurnaceBlock;
-import io.github.cadiboo.examplemod.block.HeatCollectorBlock;
-import io.github.cadiboo.examplemod.block.MiniModelBlock;
-import io.github.cadiboo.examplemod.block.ModFurnaceBlock;
+import io.github.cadiboo.examplemod.block.BlockExampleTileEntity;
+import io.github.cadiboo.examplemod.block.BlockModOre;
+import io.github.cadiboo.examplemod.block.BlockResource;
+import io.github.cadiboo.examplemod.util.ModReference;
import net.minecraft.block.Block;
-import net.minecraft.block.SoundType;
-import net.minecraft.block.material.Material;
-import net.minecraft.block.material.MaterialColor;
-import net.minecraftforge.fml.RegistryObject;
-import net.minecraftforge.registries.DeferredRegister;
-import net.minecraftforge.registries.ForgeRegistries;
+import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder;
/**
- * Holds a list of all our {@link Block}s.
- * Suppliers that create Blocks are added to the DeferredRegister.
- * The DeferredRegister is then added to our mod event bus in our constructor.
- * When the Block Registry Event is fired by Forge and it is time for the mod to
- * register its Blocks, our Blocks are created and registered by the DeferredRegister.
- * The Block Registry Event will always be called before the Item registry is filled.
- * Note: This supports registry overrides.
+ * {@link Block} Instances class
+ * All the blocks in here will be public static final and null as their values will be filled by the magical @ObjectHolder
*
* @author Cadiboo
*/
+@ObjectHolder(ModReference.MOD_ID)
public final class ModBlocks {
- public static final DeferredRegister BLOCKS = new DeferredRegister<>(ForgeRegistries.BLOCKS, ExampleMod.MODID);
+ public static final BlockResource EXAMPLE_BLOCK = null;
- // This block has the ROCK material, meaning it needs at least a wooden pickaxe to break it. It is very similar to Iron Ore
- public static final RegistryObject EXAMPLE_ORE = BLOCKS.register("example_ore", () -> new Block(Block.Properties.create(Material.ROCK).hardnessAndResistance(3.0F, 3.0F)));
- // This block has the IRON material, meaning it needs at least a stone pickaxe to break it. It is very similar to the Iron Block
- public static final RegistryObject EXAMPLE_BLOCK = BLOCKS.register("example_block", () -> new Block(Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(5.0F, 6.0F).sound(SoundType.METAL)));
- // This block has the MISCELLANEOUS material. It is very similar to the Redstone Torch
- public static final RegistryObject MINI_MODEL = BLOCKS.register("mini_model", () -> new MiniModelBlock(Block.Properties.create(Material.MISCELLANEOUS).hardnessAndResistance(1.5F).lightValue(13).doesNotBlockMovement()));
- // This block has the ROCK material, meaning it needs at least a wooden pickaxe to break it. It is very similar to the Furnace
- public static final RegistryObject HEAT_COLLECTOR = BLOCKS.register("heat_collector", () -> new HeatCollectorBlock(Block.Properties.create(Material.ROCK).hardnessAndResistance(3.5F).lightValue(13)));
- public static final RegistryObject ELECTRIC_FURNACE = BLOCKS.register("electric_furnace", () -> new ElectricFurnaceBlock(Block.Properties.create(Material.ROCK).hardnessAndResistance(3.5F)));
- public static final RegistryObject MOD_FURNACE = BLOCKS.register("mod_furnace", () -> new ModFurnaceBlock(Block.Properties.create(Material.ROCK).hardnessAndResistance(3.5F).lightValue(13)));
+ public static final BlockModOre EXAMPLE_ORE = null;
+
+ public static final BlockExampleTileEntity EXAMPLE_TILE_ENTITY = null;
}
diff --git a/src/main/java/io/github/cadiboo/examplemod/init/ModContainerTypes.java b/src/main/java/io/github/cadiboo/examplemod/init/ModContainerTypes.java
deleted file mode 100644
index 05fe095..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/init/ModContainerTypes.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package io.github.cadiboo.examplemod.init;
-
-import io.github.cadiboo.examplemod.ExampleMod;
-import io.github.cadiboo.examplemod.container.ElectricFurnaceContainer;
-import io.github.cadiboo.examplemod.container.HeatCollectorContainer;
-import io.github.cadiboo.examplemod.container.ModFurnaceContainer;
-import net.minecraft.inventory.container.ContainerType;
-import net.minecraftforge.common.extensions.IForgeContainerType;
-import net.minecraftforge.fml.RegistryObject;
-import net.minecraftforge.registries.DeferredRegister;
-import net.minecraftforge.registries.ForgeRegistries;
-
-/**
- * Holds a list of all our {@link ContainerType}s.
- * Suppliers that create ContainerTypes are added to the DeferredRegister.
- * The DeferredRegister is then added to our mod event bus in our constructor.
- * When the ContainerType Registry Event is fired by Forge and it is time for the mod to
- * register its ContainerTypes, our ContainerTypes are created and registered by the DeferredRegister.
- * The ContainerType Registry Event will always be called after the Block and Item registries are filled.
- * Note: This supports registry overrides.
- *
- * @author Cadiboo
- */
-public final class ModContainerTypes {
-
- public static final DeferredRegister> CONTAINER_TYPES = new DeferredRegister<>(ForgeRegistries.CONTAINERS, ExampleMod.MODID);
-
- public static final RegistryObject> HEAT_COLLECTOR = CONTAINER_TYPES.register("heat_collector", () -> IForgeContainerType.create(HeatCollectorContainer::new));
- public static final RegistryObject> ELECTRIC_FURNACE = CONTAINER_TYPES.register("electric_furnace", () -> IForgeContainerType.create(ElectricFurnaceContainer::new));
- public static final RegistryObject> MOD_FURNACE = CONTAINER_TYPES.register("mod_furnace", () -> IForgeContainerType.create(ModFurnaceContainer::new));
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/init/ModEntities.java b/src/main/java/io/github/cadiboo/examplemod/init/ModEntities.java
new file mode 100644
index 0000000..7bb3101
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/init/ModEntities.java
@@ -0,0 +1,15 @@
+package io.github.cadiboo.examplemod.init;
+
+import io.github.cadiboo.examplemod.util.ModReference;
+import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder;
+
+/**
+ * Entity Instances class
+ * All the entity entries in here will be public static final and null as their values will be filled by the magical @ObjectHolder
+ *
+ * @author Cadiboo
+ */
+@ObjectHolder(ModReference.MOD_ID)
+public final class ModEntities {
+
+}
diff --git a/src/main/java/io/github/cadiboo/examplemod/init/ModEntityTypes.java b/src/main/java/io/github/cadiboo/examplemod/init/ModEntityTypes.java
deleted file mode 100644
index 4a7aa84..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/init/ModEntityTypes.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package io.github.cadiboo.examplemod.init;
-
-import io.github.cadiboo.examplemod.ExampleMod;
-import io.github.cadiboo.examplemod.entity.WildBoarEntity;
-import net.minecraft.entity.EntityClassification;
-import net.minecraft.entity.EntityType;
-import net.minecraft.util.ResourceLocation;
-import net.minecraftforge.fml.RegistryObject;
-import net.minecraftforge.registries.DeferredRegister;
-import net.minecraftforge.registries.ForgeRegistries;
-
-/**
- * Holds a list of all our {@link EntityType}s.
- * Suppliers that create EntityTypes are added to the DeferredRegister.
- * The DeferredRegister is then added to our mod event bus in our constructor.
- * When the EntityType Registry Event is fired by Forge and it is time for the mod to
- * register its EntityTypes, our EntityTypes are created and registered by the DeferredRegister.
- * The EntityType Registry Event will always be called after the Block and Item registries are filled.
- * Note: This supports registry overrides.
- *
- * @author Cadiboo
- */
-public final class ModEntityTypes {
-
- public static final DeferredRegister> ENTITY_TYPES = new DeferredRegister<>(ForgeRegistries.ENTITIES, ExampleMod.MODID);
-
- public static final String WILD_BOAR_NAME = "wild_boar";
- public static final RegistryObject> WILD_BOAR = ENTITY_TYPES.register(WILD_BOAR_NAME, () ->
- EntityType.Builder.create(WildBoarEntity::new, EntityClassification.CREATURE)
- .size(EntityType.PIG.getWidth(), EntityType.PIG.getHeight())
- .build(new ResourceLocation(ExampleMod.MODID, WILD_BOAR_NAME).toString())
- );
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/init/ModItemGroups.java b/src/main/java/io/github/cadiboo/examplemod/init/ModItemGroups.java
deleted file mode 100644
index 15c3ab9..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/init/ModItemGroups.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package io.github.cadiboo.examplemod.init;
-
-import io.github.cadiboo.examplemod.ExampleMod;
-import net.minecraft.item.ItemGroup;
-import net.minecraft.item.ItemStack;
-
-import javax.annotation.Nonnull;
-import java.util.function.Supplier;
-
-/**
- * This class holds all our ItemGroups (Formerly called CreativeTabs).
- * Static initialisers are fine here.
- *
- * @author Cadiboo
- */
-public final class ModItemGroups {
-
- public static final ItemGroup MOD_ITEM_GROUP = new ModItemGroup(ExampleMod.MODID, () -> new ItemStack(ModItems.EXAMPLE_CRYSTAL.get()));
-
- public static final class ModItemGroup extends ItemGroup {
-
- @Nonnull
- private final Supplier iconSupplier;
-
- public ModItemGroup(@Nonnull final String name, @Nonnull final Supplier iconSupplier) {
- super(name);
- this.iconSupplier = iconSupplier;
- }
-
- @Override
- @Nonnull
- public ItemStack createIcon() {
- return iconSupplier.get();
- }
-
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/init/ModItems.java b/src/main/java/io/github/cadiboo/examplemod/init/ModItems.java
index 01d3e57..feb5728 100644
--- a/src/main/java/io/github/cadiboo/examplemod/init/ModItems.java
+++ b/src/main/java/io/github/cadiboo/examplemod/init/ModItems.java
@@ -1,29 +1,20 @@
package io.github.cadiboo.examplemod.init;
-import io.github.cadiboo.examplemod.ExampleMod;
-import io.github.cadiboo.examplemod.item.ModdedSpawnEggItem;
+import io.github.cadiboo.examplemod.item.ItemExampleIngot;
+import io.github.cadiboo.examplemod.util.ModReference;
import net.minecraft.item.Item;
-import net.minecraftforge.fml.RegistryObject;
-import net.minecraftforge.registries.DeferredRegister;
-import net.minecraftforge.registries.ForgeRegistries;
+import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder;
/**
- * Holds a list of all our {@link Item}s.
- * Suppliers that create Items are added to the DeferredRegister.
- * The DeferredRegister is then added to our mod event bus in our constructor.
- * When the Item Registry Event is fired by Forge and it is time for the mod to
- * register its Items, our Items are created and registered by the DeferredRegister.
- * The Item Registry Event will always be called after the Block registry is filled.
- * Note: This supports registry overrides.
+ * {@link Item} Instances class
+ * All the items in here will be public static final and null as their values will be filled by the magical @ObjectHolder
*
* @author Cadiboo
*/
+@ObjectHolder(ModReference.MOD_ID)
public final class ModItems {
- public static final DeferredRegister- ITEMS = new DeferredRegister<>(ForgeRegistries.ITEMS, ExampleMod.MODID);
-
- // This is a very simple Item. It has no special properties except for being on our creative tab.
- public static final RegistryObject
- EXAMPLE_CRYSTAL = ITEMS.register("example_crystal", () -> new Item(new Item.Properties().group(ModItemGroups.MOD_ITEM_GROUP)));
- public static final RegistryObject WILD_BOAR_SPAWN_EGG = ITEMS.register("wild_boar_spawn_egg", () -> new ModdedSpawnEggItem(ModEntityTypes.WILD_BOAR, 0xF0A5A2, 0xA9672B, new Item.Properties().group(ModItemGroups.MOD_ITEM_GROUP)));
+ public static final Item EXAMPLE_ITEM = null;
+ public static final ItemExampleIngot EXAMPLE_INGOT = null;
}
diff --git a/src/main/java/io/github/cadiboo/examplemod/init/ModTileEntityTypes.java b/src/main/java/io/github/cadiboo/examplemod/init/ModTileEntityTypes.java
deleted file mode 100644
index 289482a..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/init/ModTileEntityTypes.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package io.github.cadiboo.examplemod.init;
-
-import io.github.cadiboo.examplemod.ExampleMod;
-import io.github.cadiboo.examplemod.tileentity.ElectricFurnaceTileEntity;
-import io.github.cadiboo.examplemod.tileentity.HeatCollectorTileEntity;
-import io.github.cadiboo.examplemod.tileentity.MiniModelTileEntity;
-import io.github.cadiboo.examplemod.tileentity.ModFurnaceTileEntity;
-import net.minecraft.tileentity.TileEntityType;
-import net.minecraftforge.fml.RegistryObject;
-import net.minecraftforge.registries.DeferredRegister;
-import net.minecraftforge.registries.ForgeRegistries;
-
-/**
- * Holds a list of all our {@link TileEntityType}s.
- * Suppliers that create TileEntityTypes are added to the DeferredRegister.
- * The DeferredRegister is then added to our mod event bus in our constructor.
- * When the TileEntityType Registry Event is fired by Forge and it is time for the mod to
- * register its TileEntityTypes, our TileEntityTypes are created and registered by the DeferredRegister.
- * The TileEntityType Registry Event will always be called after the Block and Item registries are filled.
- * Note: This supports registry overrides.
- *
- * @author Cadiboo
- */
-public final class ModTileEntityTypes {
-
- public static final DeferredRegister> TILE_ENTITY_TYPES = new DeferredRegister<>(ForgeRegistries.TILE_ENTITIES, ExampleMod.MODID);
-
- // We don't have a datafixer for our TileEntities, so we pass null into build.
- public static final RegistryObject> MINI_MODEL = TILE_ENTITY_TYPES.register("mini_model", () ->
- TileEntityType.Builder.create(MiniModelTileEntity::new, ModBlocks.MINI_MODEL.get())
- .build(null)
- );
- public static final RegistryObject> HEAT_COLLECTOR = TILE_ENTITY_TYPES.register("heat_collector", () ->
- TileEntityType.Builder.create(HeatCollectorTileEntity::new, ModBlocks.HEAT_COLLECTOR.get())
- .build(null)
- );
- public static final RegistryObject> ELECTRIC_FURNACE = TILE_ENTITY_TYPES.register("electric_furnace", () ->
- TileEntityType.Builder.create(ElectricFurnaceTileEntity::new, ModBlocks.ELECTRIC_FURNACE.get())
- .build(null)
- );
- public static final RegistryObject> MOD_FURNACE = TILE_ENTITY_TYPES.register("mod_furnace", () ->
- TileEntityType.Builder.create(ModFurnaceTileEntity::new, ModBlocks.MOD_FURNACE.get())
- .build(null)
- );
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/init/package-info.java b/src/main/java/io/github/cadiboo/examplemod/init/package-info.java
new file mode 100644
index 0000000..b938e6c
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/init/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Contains static references that are filled by {@link net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder} to our mod's objects
+ */
+
+package io.github.cadiboo.examplemod.init;
diff --git a/src/main/java/io/github/cadiboo/examplemod/item/ItemExampleIngot.java b/src/main/java/io/github/cadiboo/examplemod/item/ItemExampleIngot.java
new file mode 100644
index 0000000..f8fcb51
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/item/ItemExampleIngot.java
@@ -0,0 +1,20 @@
+package io.github.cadiboo.examplemod.item;
+
+import io.github.cadiboo.examplemod.util.ModUtil;
+import net.minecraft.item.Item;
+
+import javax.annotation.Nonnull;
+
+/**
+ * The same as an Iron Ingot or a Gold Ingot but for our stuff
+ *
+ * @author Cadiboo
+ */
+public class ItemExampleIngot extends Item {
+
+ public ItemExampleIngot(@Nonnull String name) {
+ ModUtil.setRegistryNames(this, name);
+ ModUtil.setCreativeTab(this);
+ }
+
+}
diff --git a/src/main/java/io/github/cadiboo/examplemod/item/ModdedSpawnEggItem.java b/src/main/java/io/github/cadiboo/examplemod/item/ModdedSpawnEggItem.java
deleted file mode 100644
index e7a8afd..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/item/ModdedSpawnEggItem.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package io.github.cadiboo.examplemod.item;
-
-import net.minecraft.block.DispenserBlock;
-import net.minecraft.dispenser.DefaultDispenseItemBehavior;
-import net.minecraft.dispenser.IBlockSource;
-import net.minecraft.entity.EntityType;
-import net.minecraft.entity.SpawnReason;
-import net.minecraft.item.ItemStack;
-import net.minecraft.item.SpawnEggItem;
-import net.minecraft.nbt.CompoundNBT;
-import net.minecraft.util.Direction;
-import net.minecraftforge.common.util.Lazy;
-import net.minecraftforge.common.util.NonNullSupplier;
-import net.minecraftforge.fml.RegistryObject;
-import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
-
-import javax.annotation.Nullable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Exists to work around a limitation with Spawn Eggs:
- * Spawn Eggs require an EntityType, but EntityTypes are created AFTER Items.
- * Therefore it is "impossible" for modded spawn eggs to exist.
- * This class gets around it by passing "null" to the SpawnEggItem constructor
- * and doing the initialisation after registry events have finished firing.
- *
- * TODO: Remove once Forge adds this stuff in itself.
- *
- * @author Cadiboo
- */
-public class ModdedSpawnEggItem extends SpawnEggItem {
-
- protected static final List UNADDED_EGGS = new ArrayList<>();
- private final Lazy extends EntityType>> entityTypeSupplier;
-
- public ModdedSpawnEggItem(final NonNullSupplier extends EntityType>> entityTypeSupplier, final int p_i48465_2_, final int p_i48465_3_, final Properties p_i48465_4_) {
- super(null, p_i48465_2_, p_i48465_3_, p_i48465_4_);
- this.entityTypeSupplier = Lazy.of(entityTypeSupplier::get);
- UNADDED_EGGS.add(this);
- }
-
- public ModdedSpawnEggItem(final RegistryObject extends EntityType>> entityTypeSupplier, final int p_i48465_2_, final int p_i48465_3_, final Properties p_i48465_4_) {
- super(null, p_i48465_2_, p_i48465_3_, p_i48465_4_);
- this.entityTypeSupplier = Lazy.of(entityTypeSupplier);
- UNADDED_EGGS.add(this);
- }
-
- /**
- * Adds all the supplier based spawn eggs to vanilla's map and registers an
- * IDispenseItemBehavior for each of them as normal spawn eggs have one
- * registered for each of them during {@link net.minecraft.dispenser.IDispenseItemBehavior#init()}
- * but supplier based ones won't have had their EntityTypes created yet.
- */
- public static void initUnaddedEggs() {
- final Map, SpawnEggItem> EGGS = ObfuscationReflectionHelper.getPrivateValue(SpawnEggItem.class, null, "field_195987_b");
- DefaultDispenseItemBehavior defaultDispenseItemBehavior = new DefaultDispenseItemBehavior() {
- public ItemStack dispenseStack(IBlockSource source, ItemStack stack) {
- Direction direction = source.getBlockState().get(DispenserBlock.FACING);
- EntityType> entitytype = ((SpawnEggItem) stack.getItem()).getType(stack.getTag());
- entitytype.spawn(source.getWorld(), stack, null, source.getBlockPos().offset(direction), SpawnReason.DISPENSER, direction != Direction.UP, false);
- stack.shrink(1);
- return stack;
- }
- };
- for (final SpawnEggItem egg : UNADDED_EGGS) {
- EGGS.put(egg.getType(null), egg);
- DispenserBlock.registerDispenseBehavior(egg, defaultDispenseItemBehavior);
- // ItemColors for each spawn egg don't need to be registered because this method is called before ItemColors is created
- }
- UNADDED_EGGS.clear();
- }
-
- @Override
- public EntityType> getType(@Nullable final CompoundNBT p_208076_1_) {
- return entityTypeSupplier.get();
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/item/package-info.java b/src/main/java/io/github/cadiboo/examplemod/item/package-info.java
new file mode 100644
index 0000000..a0ad647
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/item/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Contains our mod's {@link net.minecraft.item.Item}s
+ */
+
+package io.github.cadiboo.examplemod.item;
diff --git a/src/main/java/io/github/cadiboo/examplemod/network/ModNetworkManager.java b/src/main/java/io/github/cadiboo/examplemod/network/ModNetworkManager.java
new file mode 100644
index 0000000..17cfcdc
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/network/ModNetworkManager.java
@@ -0,0 +1,38 @@
+package io.github.cadiboo.examplemod.network;
+
+import net.minecraftforge.fml.common.network.NetworkRegistry;
+import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import static io.github.cadiboo.examplemod.util.ModReference.MOD_ID;
+
+/**
+ * Manages the registry of the of network packets (it does more than this but everything's handled automagically by forge)
+ *
+ * @author Cadiboo
+ */
+public final class ModNetworkManager {
+
+ public static final String CHANNEL = StringUtils.substring(MOD_ID, 0, 20);
+ public static final SimpleNetworkWrapper NETWORK = NetworkRegistry.INSTANCE.newSimpleChannel(CHANNEL);
+ private static final Logger LOGGER = LogManager.getLogger();
+ static {
+ if (CHANNEL.length() != MOD_ID.length()) {
+ // Network Channel CAN'T be longer than 20 characters due to Minecraft & Forge's packet system
+ LOGGER.error("Network Channel was clamped to 20 characters! {}, {}", CHANNEL, MOD_ID);
+ }
+ }
+
+ public ModNetworkManager() {
+ int networkIds = 0;
+
+ /* Client -> Server */
+// NETWORK.registerMessage(CPacket___.class, CPacket___.class, networkIds++, Side.SERVER);
+ /* Server -> Client */
+// NETWORK.registerMessage(SPacket___.class, SPacket___.class, networkIds++, Side.CLIENT);
+
+ }
+
+}
diff --git a/src/main/java/io/github/cadiboo/examplemod/network/package-info.java b/src/main/java/io/github/cadiboo/examplemod/network/package-info.java
new file mode 100644
index 0000000..cc85849
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/network/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Contains our mod's networking code i.e. the {@link io.github.cadiboo.examplemod.network.ModNetworkManager}
+ */
+
+package io.github.cadiboo.examplemod.network;
diff --git a/src/main/java/io/github/cadiboo/examplemod/package-info.java b/src/main/java/io/github/cadiboo/examplemod/package-info.java
new file mode 100644
index 0000000..0dad55c
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Contains our mod's main class and its' common EventSubscriber
+ */
+
+package io.github.cadiboo.examplemod;
diff --git a/src/main/java/io/github/cadiboo/examplemod/server/ServerEventSubscriber.java b/src/main/java/io/github/cadiboo/examplemod/server/ServerEventSubscriber.java
new file mode 100644
index 0000000..b645e0d
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/server/ServerEventSubscriber.java
@@ -0,0 +1,15 @@
+package io.github.cadiboo.examplemod.server;
+
+import io.github.cadiboo.examplemod.util.ModReference;
+import net.minecraftforge.fml.common.Mod;
+
+import static io.github.cadiboo.examplemod.util.ModReference.*;
+import static net.minecraftforge.fml.relauncher.Side.SERVER;
+
+/**
+ * Subscribe to events that should be handled on the PHYSICAL/DEDICATED SERVER in this class
+ */
+@Mod.EventBusSubscriber(modid = MOD_ID, value = SERVER)
+public final class ServerEventSubscriber {
+
+}
diff --git a/src/main/java/io/github/cadiboo/examplemod/server/ServerProxy.java b/src/main/java/io/github/cadiboo/examplemod/server/ServerProxy.java
new file mode 100644
index 0000000..5ce5f6b
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/server/ServerProxy.java
@@ -0,0 +1,28 @@
+package io.github.cadiboo.examplemod.server;
+
+import io.github.cadiboo.examplemod.ExampleMod;
+import io.github.cadiboo.examplemod.util.IProxy;
+import net.minecraft.util.text.translation.I18n;
+import net.minecraftforge.fml.relauncher.Side;
+
+/**
+ * The version of IProxy that gets injected into {@link ExampleMod#proxy} on a PHYSICAL/DEDICATED SERVER
+ */
+public final class ServerProxy implements IProxy {
+
+ @Override
+ public String localize(final String unlocalized) {
+ return I18n.translateToLocal(unlocalized);
+ }
+
+ @Override
+ public String localizeAndFormat(final String unlocalized, final Object... args) {
+ return I18n.translateToLocalFormatted(unlocalized, args);
+ }
+
+ @Override
+ public Side getPhysicalSide() {
+ return Side.SERVER;
+ }
+
+}
diff --git a/src/main/java/io/github/cadiboo/examplemod/server/ServerUtil.java b/src/main/java/io/github/cadiboo/examplemod/server/ServerUtil.java
new file mode 100644
index 0000000..05a405c
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/server/ServerUtil.java
@@ -0,0 +1,10 @@
+package io.github.cadiboo.examplemod.server;
+
+/**
+ * Util that is only used on the Physical/Dedicated Server
+ *
+ * @author Cadiboo
+ */
+public final class ServerUtil {
+
+}
diff --git a/src/main/java/io/github/cadiboo/examplemod/server/package-info.java b/src/main/java/io/github/cadiboo/examplemod/server/package-info.java
new file mode 100644
index 0000000..7e362e1
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/server/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Contains code that will crash on the physical client
+ */
+
+package io.github.cadiboo.examplemod.server;
diff --git a/src/main/java/io/github/cadiboo/examplemod/tileentity/ElectricFurnaceTileEntity.java b/src/main/java/io/github/cadiboo/examplemod/tileentity/ElectricFurnaceTileEntity.java
deleted file mode 100644
index c8ff965..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/tileentity/ElectricFurnaceTileEntity.java
+++ /dev/null
@@ -1,343 +0,0 @@
-package io.github.cadiboo.examplemod.tileentity;
-
-import io.github.cadiboo.examplemod.block.ElectricFurnaceBlock;
-import io.github.cadiboo.examplemod.config.ExampleModConfig;
-import io.github.cadiboo.examplemod.container.ElectricFurnaceContainer;
-import io.github.cadiboo.examplemod.energy.SettableEnergyStorage;
-import io.github.cadiboo.examplemod.init.ModBlocks;
-import io.github.cadiboo.examplemod.init.ModTileEntityTypes;
-import net.minecraft.block.BlockState;
-import net.minecraft.entity.player.PlayerEntity;
-import net.minecraft.entity.player.PlayerInventory;
-import net.minecraft.inventory.IInventory;
-import net.minecraft.inventory.Inventory;
-import net.minecraft.inventory.container.Container;
-import net.minecraft.inventory.container.INamedContainerProvider;
-import net.minecraft.item.ItemStack;
-import net.minecraft.item.crafting.AbstractCookingRecipe;
-import net.minecraft.item.crafting.FurnaceRecipe;
-import net.minecraft.item.crafting.IRecipeType;
-import net.minecraft.nbt.CompoundNBT;
-import net.minecraft.network.NetworkManager;
-import net.minecraft.network.play.server.SUpdateTileEntityPacket;
-import net.minecraft.tileentity.AbstractFurnaceTileEntity;
-import net.minecraft.tileentity.ITickableTileEntity;
-import net.minecraft.tileentity.TileEntity;
-import net.minecraft.util.Direction;
-import net.minecraft.util.text.ITextComponent;
-import net.minecraft.util.text.TranslationTextComponent;
-import net.minecraftforge.common.capabilities.Capability;
-import net.minecraftforge.common.util.LazyOptional;
-import net.minecraftforge.energy.CapabilityEnergy;
-import net.minecraftforge.energy.EnergyStorage;
-import net.minecraftforge.fml.network.NetworkHooks;
-import net.minecraftforge.items.CapabilityItemHandler;
-import net.minecraftforge.items.IItemHandlerModifiable;
-import net.minecraftforge.items.ItemStackHandler;
-import net.minecraftforge.items.wrapper.RangedWrapper;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import java.util.Optional;
-
-/**
- * @author Cadiboo
- */
-public class ElectricFurnaceTileEntity extends TileEntity implements ITickableTileEntity, INamedContainerProvider {
-
- public static final int INPUT_SLOT = 0;
- public static final int OUTPUT_SLOT = 1;
-
- private static final String INVENTORY_TAG = "inventory";
- private static final String SMELT_TIME_LEFT_TAG = "smeltTimeLeft";
- private static final String MAX_SMELT_TIME_TAG = "maxSmeltTime";
- private static final String ENERGY_TAG = "energy";
- public final ItemStackHandler inventory = new ItemStackHandler(2) {
- @Override
- public boolean isItemValid(final int slot, @Nonnull final ItemStack stack) {
- switch (slot) {
- case INPUT_SLOT:
- return isInput(stack);
- case OUTPUT_SLOT:
- return isOutput(stack);
- default:
- return false;
- }
- }
-
- @Override
- protected void onContentsChanged(final int slot) {
- super.onContentsChanged(slot);
- // Mark the tile entity as having changed whenever its inventory changes.
- // "markDirty" tells vanilla that the chunk containing the tile entity has
- // changed and means the game will save the chunk to disk later.
- ElectricFurnaceTileEntity.this.markDirty();
- }
- };
- public final SettableEnergyStorage energy = new SettableEnergyStorage(100_000);
-
- // Store the capability lazy optionals as fields to keep the amount of objects we use to a minimum
- private final LazyOptional inventoryCapabilityExternal = LazyOptional.of(() -> this.inventory);
- // Machines (hoppers, pipes) connected to this furnace's top can only insert/extract items from the input slot
- private final LazyOptional inventoryCapabilityExternalUpAndSides = LazyOptional.of(() -> new RangedWrapper(this.inventory, INPUT_SLOT, INPUT_SLOT + 1));
- // Machines (hoppers, pipes) connected to this furnace's bottom can only insert/extract items from the output slot
- private final LazyOptional inventoryCapabilityExternalDown = LazyOptional.of(() -> new RangedWrapper(this.inventory, OUTPUT_SLOT, OUTPUT_SLOT + 1));
- private final LazyOptional energyCapabilityExternal = LazyOptional.of(() -> this.energy);
-
- public short smeltTimeLeft = -1;
- public short maxSmeltTime = -1;
- private int lastEnergy = -1;
-
- public ElectricFurnaceTileEntity() {
- super(ModTileEntityTypes.ELECTRIC_FURNACE.get());
- }
-
- /**
- * @return If the stack is not empty and has a smelting recipe associated with it
- */
- private boolean isInput(final ItemStack stack) {
- if (stack.isEmpty())
- return false;
- return getRecipe(stack).isPresent();
- }
-
- /**
- * @return If the stack's item is equal to the result of smelting our input
- */
- private boolean isOutput(final ItemStack stack) {
- final Optional result = getResult(inventory.getStackInSlot(INPUT_SLOT));
- return result.isPresent() && ItemStack.areItemsEqual(result.get(), stack);
- }
-
- /**
- * @return The smelting recipe for the input stack
- */
- private Optional getRecipe(final ItemStack input) {
- // Due to vanilla's code we need to pass an IInventory into RecipeManager#getRecipe so we make one here.
- return getRecipe(new Inventory(input));
- }
-
- /**
- * @return The smelting recipe for the inventory
- */
- private Optional getRecipe(final IInventory inventory) {
- return world.getRecipeManager().getRecipe(IRecipeType.SMELTING, inventory, world);
- }
-
- /**
- * @return The result of smelting the input stack
- */
- private Optional getResult(final ItemStack input) {
- // Due to vanilla's code we need to pass an IInventory into RecipeManager#getRecipe and
- // AbstractCookingRecipe#getCraftingResult() so we make one here.
- final Inventory dummyInventory = new Inventory(input);
- return getRecipe(dummyInventory).map(recipe -> recipe.getCraftingResult(dummyInventory));
- }
-
- /**
- * Called every tick to update our tile entity
- */
- @Override
- public void tick() {
- if (world == null || world.isRemote)
- return;
-
- // Energy will get pushed into our machine by generators/wires
-
- // Smelting code
-
- final ItemStack input = inventory.getStackInSlot(INPUT_SLOT).copy();
- final ItemStack result = getResult(input).orElse(ItemStack.EMPTY);
-
- if (!result.isEmpty() && isInput(input)) {
- final boolean canInsertResultIntoOutput = inventory.insertItem(OUTPUT_SLOT, result, true).isEmpty();
- if (canInsertResultIntoOutput) {
- // Energy consuming code
- final int energySmeltCostPerTick = ExampleModConfig.electricFurnaceEnergySmeltCostPerTick;
- boolean hasEnergy = false;
- if (energy.extractEnergy(energySmeltCostPerTick, true) == energySmeltCostPerTick) {
- hasEnergy = true;
- energy.extractEnergy(energySmeltCostPerTick, false);
- }
- if (hasEnergy) {
- if (smeltTimeLeft == -1) { // Item has not been smelted before
- smeltTimeLeft = maxSmeltTime = getSmeltTime(input);
- } else { // Item was already being smelted
- --smeltTimeLeft;
- if (smeltTimeLeft == 0) {
- inventory.insertItem(OUTPUT_SLOT, result, false);
- if (input.hasContainerItem())
- inventory.setStackInSlot(INPUT_SLOT, input.getContainerItem());
- else {
- input.shrink(1);
- inventory.setStackInSlot(INPUT_SLOT, input); // Update the data
- }
- smeltTimeLeft = -1; // Set to -1 so we smelt the next stack on the next tick
- }
- }
- } else // No energy -> add to smelt time left to simulate cooling
- if (smeltTimeLeft < maxSmeltTime)
- ++smeltTimeLeft;
- }
- } else // We have an invalid input stack (somehow)
- smeltTimeLeft = maxSmeltTime = -1;
-
- // If the energy has changed.
- if (lastEnergy != energy.getEnergyStored()) {
-
- // "markDirty" tells vanilla that the chunk containing the tile entity has
- // changed and means the game will save the chunk to disk later.
- this.markDirty();
-
- // Notify clients of a block update.
- // This will result in the packet from getUpdatePacket being sent to the client
- // and our energy being synced.
- final BlockState blockState = this.getBlockState();
- // Flag 2: Send the change to clients
- world.notifyBlockUpdate(pos, blockState, blockState, 2);
-
- // Update the last synced energy to the current energy
- lastEnergy = energy.getEnergyStored();
- }
-
- }
-
- /**
- * Mimics the code in {@link AbstractFurnaceTileEntity#func_214005_h()}
- *
- * @return The custom smelt time or 200 if there is no recipe for the input
- */
- private short getSmeltTime(final ItemStack input) {
- return getRecipe(input)
- .map(AbstractCookingRecipe::getCookTime)
- .orElse(200)
- .shortValue();
- }
-
- /**
- * Retrieves the Optional handler for the capability requested on the specific side.
- *
- * @param cap The capability to check
- * @param side The Direction to check from. CAN BE NULL! Null is defined to represent 'internal' or 'self'
- * @return The requested an optional holding the requested capability.
- */
- @Nonnull
- @Override
- public LazyOptional getCapability(@Nonnull final Capability cap, @Nullable final Direction side) {
- if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
- if (side == null)
- return inventoryCapabilityExternal.cast();
- switch (side) {
- case DOWN:
- return inventoryCapabilityExternalDown.cast();
- case UP:
- case NORTH:
- case SOUTH:
- case WEST:
- case EAST:
- return inventoryCapabilityExternalUpAndSides.cast();
- }
- }
- if (cap == CapabilityEnergy.ENERGY)
- return energyCapabilityExternal.cast();
- return super.getCapability(cap, side);
- }
-
- /**
- * Handle a packet created in {@link #getUpdatePacket()}
- */
- @Override
- public void onDataPacket(final NetworkManager net, final SUpdateTileEntityPacket pkt) {
- this.energy.setEnergy(pkt.getNbtCompound().getInt(ENERGY_TAG));
- }
-
- @Override
- public void onLoad() {
- super.onLoad();
- // We set this in onLoad instead of the constructor so that TileEntities
- // constructed from NBT (saved tile entities) have this set to the proper value
- if (world != null && !world.isRemote)
- lastEnergy = energy.getEnergyStored();
- }
-
- /**
- * Read saved data from disk into the tile.
- */
- @Override
- public void read(final CompoundNBT compound) {
- super.read(compound);
- this.inventory.deserializeNBT(compound.getCompound(INVENTORY_TAG));
- this.smeltTimeLeft = compound.getShort(SMELT_TIME_LEFT_TAG);
- this.maxSmeltTime = compound.getShort(MAX_SMELT_TIME_TAG);
- this.energy.setEnergy(compound.getInt(ENERGY_TAG));
- }
-
- /**
- * Write data from the tile into a compound tag for saving to disk.
- */
- @Nonnull
- @Override
- public CompoundNBT write(final CompoundNBT compound) {
- super.write(compound);
- compound.put(INVENTORY_TAG, this.inventory.serializeNBT());
- compound.putShort(SMELT_TIME_LEFT_TAG, this.smeltTimeLeft);
- compound.putShort(MAX_SMELT_TIME_TAG, this.maxSmeltTime);
- compound.putInt(ENERGY_TAG, this.energy.getEnergyStored());
- return compound;
- }
-
- /**
- * Retrieves packet to send to the client whenever this Tile Entity is re-synced via World#notifyBlockUpdate.
- * This packet comes back client-side in {@link #onDataPacket}
- */
- @Nullable
- public SUpdateTileEntityPacket getUpdatePacket() {
- final CompoundNBT tag = new CompoundNBT();
- tag.putInt(ENERGY_TAG, this.energy.getEnergyStored());
- // We pass 0 for tileEntityTypeIn because we have a modded TE. See ClientPlayNetHandler#handleUpdateTileEntity(SUpdateTileEntityPacket)
- return new SUpdateTileEntityPacket(this.pos, 0, tag);
- }
-
- /**
- * Get an NBT compound to sync to the client with SPacketChunkData, used for initial loading of the
- * chunk or when many blocks change at once.
- * This compound comes back to you client-side in {@link #handleUpdateTag}
- * The default implementation ({@link TileEntity#handleUpdateTag}) calls {@link #writeInternal)}
- * which doesn't save any of our extra data so we override it to call {@link #write} instead
- */
- @Nonnull
- public CompoundNBT getUpdateTag() {
- return this.write(new CompoundNBT());
- }
-
- /**
- * Invalidates our tile entity
- */
- @Override
- public void remove() {
- super.remove();
- // We need to invalidate our capability references so that any cached references (by other mods) don't
- // continue to reference our capabilities and try to use them and/or prevent them from being garbage collected
- inventoryCapabilityExternal.invalidate();
- energyCapabilityExternal.invalidate();
- }
-
- @Nonnull
- @Override
- public ITextComponent getDisplayName() {
- return new TranslationTextComponent(ModBlocks.ELECTRIC_FURNACE.get().getTranslationKey());
- }
-
- /**
- * Called from {@link NetworkHooks#openGui}
- * (which is called from {@link ElectricFurnaceBlock#onBlockActivated} on the logical server)
- *
- * @return The logical-server-side Container for this TileEntity
- */
- @Nonnull
- @Override
- public Container createMenu(final int windowId, final PlayerInventory inventory, final PlayerEntity player) {
- return new ElectricFurnaceContainer(windowId, inventory, this);
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/tileentity/HeatCollectorTileEntity.java b/src/main/java/io/github/cadiboo/examplemod/tileentity/HeatCollectorTileEntity.java
deleted file mode 100644
index 1b5ed7e..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/tileentity/HeatCollectorTileEntity.java
+++ /dev/null
@@ -1,269 +0,0 @@
-package io.github.cadiboo.examplemod.tileentity;
-
-import io.github.cadiboo.examplemod.ModUtil;
-import io.github.cadiboo.examplemod.block.HeatCollectorBlock;
-import io.github.cadiboo.examplemod.config.ExampleModConfig;
-import io.github.cadiboo.examplemod.container.HeatCollectorContainer;
-import io.github.cadiboo.examplemod.energy.SettableEnergyStorage;
-import io.github.cadiboo.examplemod.init.ModBlocks;
-import io.github.cadiboo.examplemod.init.ModTileEntityTypes;
-import net.minecraft.block.BlockState;
-import net.minecraft.block.Blocks;
-import net.minecraft.entity.player.PlayerEntity;
-import net.minecraft.entity.player.PlayerInventory;
-import net.minecraft.fluid.IFluidState;
-import net.minecraft.inventory.container.Container;
-import net.minecraft.inventory.container.INamedContainerProvider;
-import net.minecraft.item.ItemStack;
-import net.minecraft.nbt.CompoundNBT;
-import net.minecraft.network.NetworkManager;
-import net.minecraft.network.play.server.SUpdateTileEntityPacket;
-import net.minecraft.tags.FluidTags;
-import net.minecraft.tileentity.FurnaceTileEntity;
-import net.minecraft.tileentity.ITickableTileEntity;
-import net.minecraft.tileentity.TileEntity;
-import net.minecraft.util.Direction;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.util.text.ITextComponent;
-import net.minecraft.util.text.TranslationTextComponent;
-import net.minecraft.world.World;
-import net.minecraftforge.common.ForgeHooks;
-import net.minecraftforge.common.capabilities.Capability;
-import net.minecraftforge.common.util.LazyOptional;
-import net.minecraftforge.energy.CapabilityEnergy;
-import net.minecraftforge.energy.EnergyStorage;
-import net.minecraftforge.fml.network.NetworkHooks;
-import net.minecraftforge.items.CapabilityItemHandler;
-import net.minecraftforge.items.ItemStackHandler;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-
-/**
- * @author Cadiboo
- */
-public class HeatCollectorTileEntity extends TileEntity implements ITickableTileEntity, INamedContainerProvider {
-
- public static final int FUEL_SLOT = 0;
-
- private static final String INVENTORY_TAG = "inventory";
- private static final String ENERGY_TAG = "energy";
-
- public final ItemStackHandler inventory = new ItemStackHandler(1) {
- @Override
- public boolean isItemValid(final int slot, @Nonnull final ItemStack stack) {
- return FurnaceTileEntity.isFuel(stack);
- }
-
- @Override
- protected void onContentsChanged(final int slot) {
- super.onContentsChanged(slot);
- // Mark the tile entity as having changed whenever its inventory changes.
- // "markDirty" tells vanilla that the chunk containing the tile entity has
- // changed and means the game will save the chunk to disk later.
- HeatCollectorTileEntity.this.markDirty();
- }
- };
- public final SettableEnergyStorage energy = new SettableEnergyStorage(100_000);
-
- // Store the capability lazy optionals as fields to keep the amount of objects we use to a minimum
- private final LazyOptional inventoryCapabilityExternal = LazyOptional.of(() -> this.inventory);
- private final LazyOptional energyCapabilityExternal = LazyOptional.of(() -> this.energy);
- private int lastEnergy = -1;
-
- public HeatCollectorTileEntity() {
- super(ModTileEntityTypes.HEAT_COLLECTOR.get());
- }
-
- @Override
- public void tick() {
-
- final World world = this.world;
- if (world == null || world.isRemote)
- return;
-
- final BlockPos pos = this.pos;
- final SettableEnergyStorage energy = this.energy;
-
- final ItemStack fuelStack = this.inventory.getStackInSlot(FUEL_SLOT).copy();
- if (!fuelStack.isEmpty()) {
- int energyToReceive = ForgeHooks.getBurnTime(fuelStack);
- // Only use the stack if we can receive 100% of the energy from it
- if (energy.receiveEnergy(energyToReceive, true) == energyToReceive) {
- energy.receiveEnergy(energyToReceive, false);
- if (fuelStack.hasContainerItem())
- inventory.setStackInSlot(FUEL_SLOT, fuelStack.getContainerItem());
- else {
- fuelStack.shrink(1);
- inventory.setStackInSlot(FUEL_SLOT, fuelStack); // Update the data
- }
- }
- }
-
- // Collect from all heat blocks in a 5 block radius
- for (final BlockPos blockPos : BlockPos.getAllInBoxMutable(pos.add(-5, -5, -5), pos.add(5, 5, 5))) {
- final BlockState blockState = world.getBlockState(blockPos);
- final IFluidState fluidState = world.getFluidState(blockPos);
-
- int fireEnergy = 0;
-
- if (blockState.getBlock() == Blocks.FIRE)
- fireEnergy += 20;
- else if (blockState.getBlock() == Blocks.CAMPFIRE)
- fireEnergy += 10;
-
- if (fluidState.isTagged(FluidTags.LAVA))
- fireEnergy += 50;
-
- if (fireEnergy > 0)
- energy.receiveEnergy(fireEnergy, false);
-
- }
-
- final int transferAmountPerTick = ExampleModConfig.heatCollectorTransferAmountPerTick;
- // Skip trying to transfer if there isn't enough energy to transfer
- if (energy.getEnergyStored() >= transferAmountPerTick) {
- for (Direction direction : ModUtil.DIRECTIONS) {
- final TileEntity te = world.getTileEntity(pos.offset(direction));
- if (te == null) {
- continue;
- }
- te.getCapability(CapabilityEnergy.ENERGY, direction).ifPresent(otherTileEnergy -> {
- if (!otherTileEnergy.canReceive()) {
- // Optimisation: Skip this tile if it can't receive
- return;
- }
- energy.extractEnergy(
- otherTileEnergy.receiveEnergy(
- energy.extractEnergy(100, true),
- false
- ),
- false
- );
- });
- }
- }
-
- // If the energy has changed.
- if (lastEnergy != energy.getEnergyStored()) {
-
- // "markDirty" tells vanilla that the chunk containing the tile entity has
- // changed and means the game will save the chunk to disk later.
- this.markDirty();
-
- // Notify clients of a block update.
- // This will result in the packet from getUpdatePacket being sent to the client
- // and our energy being synced.
- final BlockState blockState = this.getBlockState();
- // Flag 2: Send the change to clients
- world.notifyBlockUpdate(pos, blockState, blockState, 2);
-
- // Update the last synced energy to the current energy
- lastEnergy = energy.getEnergyStored();
- }
-
- }
-
- @Nonnull
- @Override
- public LazyOptional getCapability(@Nonnull final Capability cap, @Nullable final Direction side) {
- if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
- return inventoryCapabilityExternal.cast();
- if (cap == CapabilityEnergy.ENERGY)
- return energyCapabilityExternal.cast();
- return super.getCapability(cap, side);
- }
-
- /**
- * Handle a packet created in {@link #getUpdatePacket()}
- */
- @Override
- public void onDataPacket(final NetworkManager net, final SUpdateTileEntityPacket pkt) {
- this.energy.setEnergy(pkt.getNbtCompound().getInt(ENERGY_TAG));
- }
-
- @Override
- public void onLoad() {
- super.onLoad();
- // We set this in onLoad instead of the constructor so that TileEntities
- // constructed from NBT (saved tile entities) have this set to the proper value
- if (world != null && !world.isRemote)
- lastEnergy = energy.getEnergyStored();
- }
-
- /**
- * Read saved data from disk into the tile.
- */
- @Override
- public void read(final CompoundNBT compound) {
- super.read(compound);
- this.inventory.deserializeNBT(compound.getCompound(INVENTORY_TAG));
- this.energy.setEnergy(compound.getInt(ENERGY_TAG));
- }
-
- /**
- * Write data from the tile into a compound tag for saving to disk.
- */
- @Nonnull
- @Override
- public CompoundNBT write(final CompoundNBT compound) {
- super.write(compound);
- compound.put(INVENTORY_TAG, this.inventory.serializeNBT());
- compound.putInt(ENERGY_TAG, this.energy.getEnergyStored());
- return compound;
- }
-
- /**
- * Retrieves packet to send to the client whenever this Tile Entity is re-synced via World#notifyBlockUpdate.
- * This packet comes back client-side in {@link #onDataPacket}
- */
- @Nullable
- public SUpdateTileEntityPacket getUpdatePacket() {
- final CompoundNBT tag = new CompoundNBT();
- tag.putInt(ENERGY_TAG, this.energy.getEnergyStored());
- return new SUpdateTileEntityPacket(this.pos, 0, tag);
- }
-
- /**
- * Get an NBT compound to sync to the client with SPacketChunkData, used for initial loading of the
- * chunk or when many blocks change at once.
- * This compound comes back to you client-side in {@link #handleUpdateTag}
- * The default implementation ({@link TileEntity#handleUpdateTag}) calls {@link #writeInternal)}
- * which doesn't save any of our extra data so we override it to call {@link #write} instead
- */
- @Nonnull
- public CompoundNBT getUpdateTag() {
- return this.write(new CompoundNBT());
- }
-
- /**
- * Invalidates our tile entity
- */
- @Override
- public void remove() {
- super.remove();
- // We need to invalidate our capability references so that any cached references (by other mods) don't
- // continue to reference our capabilities and try to use them and/or prevent them from being garbage collected
- inventoryCapabilityExternal.invalidate();
- energyCapabilityExternal.invalidate();
- }
-
- @Nonnull
- @Override
- public ITextComponent getDisplayName() {
- return new TranslationTextComponent(ModBlocks.HEAT_COLLECTOR.get().getTranslationKey());
- }
-
- /**
- * Called from {@link NetworkHooks#openGui}
- * (which is called from {@link HeatCollectorBlock#onBlockActivated} on the logical server)
- *
- * @return The logical-server-side Container for this TileEntity
- */
- @Nonnull
- @Override
- public Container createMenu(final int windowId, final PlayerInventory inventory, final PlayerEntity player) {
- return new HeatCollectorContainer(windowId, inventory, this);
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/tileentity/MiniModelTileEntity.java b/src/main/java/io/github/cadiboo/examplemod/tileentity/MiniModelTileEntity.java
deleted file mode 100644
index 3b4fbf2..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/tileentity/MiniModelTileEntity.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package io.github.cadiboo.examplemod.tileentity;
-
-import io.github.cadiboo.examplemod.client.render.MiniModel;
-import io.github.cadiboo.examplemod.init.ModTileEntityTypes;
-import net.minecraft.tileentity.TileEntity;
-import net.minecraft.tileentity.TileEntityType;
-import net.minecraft.util.math.AxisAlignedBB;
-import net.minecraft.world.World;
-import net.minecraftforge.api.distmarker.Dist;
-import net.minecraftforge.api.distmarker.OnlyIn;
-
-import javax.annotation.Nullable;
-
-/**
- * This is the TileEntity for our MiniModel.
- * It stores the render data for its surroundings.
- *
- * Rendering code only exists on the client distribution so @OnlyIn is used a lot.
- * The @OnlyIn annotation makes it so that a class/field/method annotated with it does not
- * exist on the other distribution. This is important as TileEntities exist on both distributions
- * but rendering only happens on the client.
- * As a general rule you should avoid using @OnlyIn unless it is absolutely necessary.
- *
- * @author Cadiboo
- */
-public class MiniModelTileEntity extends TileEntity {
-
- @Nullable // May be accessed before onLoad
- // @OnlyIn(Dist.CLIENT) Makes it so this field will be removed from the class on the PHYSICAL SERVER
- // This is because we only want the MiniModel on the physical client - its rendering only.
- @OnlyIn(Dist.CLIENT)
- public MiniModel miniModel;
-
- // Constructor without hardcoded TileEntityType so that subclasses can use their own.
- // Alternatively, subclasses can also override getType if a hardcoded type is used in a superclass' constructor
- public MiniModelTileEntity(final TileEntityType> type) {
- super(type);
- }
-
- public MiniModelTileEntity() {
- this(ModTileEntityTypes.MINI_MODEL.get());
- }
-
- // @OnlyIn(Dist.CLIENT) Makes it so this method will be removed from the class on the PHYSICAL SERVER
- // This is because we only want the MiniModel on the physical client - its rendering only.
- @OnlyIn(Dist.CLIENT)
- @Override
- public void onLoad() {
- super.onLoad();
- World world = getWorld();
- if (world == null || !world.isRemote)
- return; // Return if the world is null or if we are on the logical server
- miniModel = MiniModel.forTileEntity(this);
- }
-
- @Override
- public AxisAlignedBB getRenderBoundingBox() {
- // This, combined with isGlobalRenderer in the TileEntityRenderer makes it so that the
- // render does not disappear if the player can't see the block
- // This is useful for rendering larger models or dynamically sized models
- return INFINITE_EXTENT_AABB;
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/tileentity/ModFurnaceTileEntity.java b/src/main/java/io/github/cadiboo/examplemod/tileentity/ModFurnaceTileEntity.java
deleted file mode 100644
index ec5e332..0000000
--- a/src/main/java/io/github/cadiboo/examplemod/tileentity/ModFurnaceTileEntity.java
+++ /dev/null
@@ -1,356 +0,0 @@
-package io.github.cadiboo.examplemod.tileentity;
-
-import io.github.cadiboo.examplemod.block.ElectricFurnaceBlock;
-import io.github.cadiboo.examplemod.block.ModFurnaceBlock;
-import io.github.cadiboo.examplemod.container.ModFurnaceContainer;
-import io.github.cadiboo.examplemod.init.ModBlocks;
-import io.github.cadiboo.examplemod.init.ModTileEntityTypes;
-import net.minecraft.block.BlockState;
-import net.minecraft.entity.player.PlayerEntity;
-import net.minecraft.entity.player.PlayerInventory;
-import net.minecraft.inventory.IInventory;
-import net.minecraft.inventory.Inventory;
-import net.minecraft.inventory.container.Container;
-import net.minecraft.inventory.container.INamedContainerProvider;
-import net.minecraft.item.ItemStack;
-import net.minecraft.item.crafting.AbstractCookingRecipe;
-import net.minecraft.item.crafting.FurnaceRecipe;
-import net.minecraft.item.crafting.IRecipeType;
-import net.minecraft.nbt.CompoundNBT;
-import net.minecraft.tileentity.AbstractFurnaceTileEntity;
-import net.minecraft.tileentity.FurnaceTileEntity;
-import net.minecraft.tileentity.ITickableTileEntity;
-import net.minecraft.tileentity.TileEntity;
-import net.minecraft.util.Direction;
-import net.minecraft.util.text.ITextComponent;
-import net.minecraft.util.text.TranslationTextComponent;
-import net.minecraftforge.common.ForgeHooks;
-import net.minecraftforge.common.capabilities.Capability;
-import net.minecraftforge.common.util.LazyOptional;
-import net.minecraftforge.fml.network.NetworkHooks;
-import net.minecraftforge.items.CapabilityItemHandler;
-import net.minecraftforge.items.IItemHandlerModifiable;
-import net.minecraftforge.items.ItemStackHandler;
-import net.minecraftforge.items.wrapper.RangedWrapper;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import java.util.Optional;
-
-/**
- * @author Cadiboo
- */
-public class ModFurnaceTileEntity extends TileEntity implements ITickableTileEntity, INamedContainerProvider {
-
- public static final int FUEL_SLOT = 0;
- public static final int INPUT_SLOT = 1;
- public static final int OUTPUT_SLOT = 2;
-
- private static final String INVENTORY_TAG = "inventory";
- private static final String SMELT_TIME_LEFT_TAG = "smeltTimeLeft";
- private static final String MAX_SMELT_TIME_TAG = "maxSmeltTime";
- private static final String FUEL_BURN_TIME_LEFT_TAG = "fuelBurnTimeLeft";
- private static final String MAX_FUEL_BURN_TIME_TAG = "maxFuelBurnTime";
-
- public final ItemStackHandler inventory = new ItemStackHandler(3) {
- @Override
- public boolean isItemValid(final int slot, @Nonnull final ItemStack stack) {
- switch (slot) {
- case FUEL_SLOT:
- return FurnaceTileEntity.isFuel(stack);
- case INPUT_SLOT:
- return isInput(stack);
- case OUTPUT_SLOT:
- return isOutput(stack);
- default:
- return false;
- }
- }
-
- @Override
- protected void onContentsChanged(final int slot) {
- super.onContentsChanged(slot);
- // Mark the tile entity as having changed whenever its inventory changes.
- // "markDirty" tells vanilla that the chunk containing the tile entity has
- // changed and means the game will save the chunk to disk later.
- ModFurnaceTileEntity.this.markDirty();
- }
- };
-
- // Store the capability lazy optionals as fields to keep the amount of objects we use to a minimum
- private final LazyOptional inventoryCapabilityExternal = LazyOptional.of(() -> this.inventory);
- // Machines (hoppers, pipes) connected to this furnace's top can only insert/extract items from the input slot
- private final LazyOptional inventoryCapabilityExternalUp = LazyOptional.of(() -> new RangedWrapper(this.inventory, INPUT_SLOT, INPUT_SLOT + 1));
- // Machines (hoppers, pipes) connected to this furnace's bottom can only insert/extract items from the output slot
- private final LazyOptional inventoryCapabilityExternalDown = LazyOptional.of(() -> new RangedWrapper(this.inventory, OUTPUT_SLOT, OUTPUT_SLOT + 1));
- // Machines (hoppers, pipes) connected to this furnace's side can only insert/extract items from the fuel and input slots
- private final LazyOptional inventoryCapabilityExternalSides = LazyOptional.of(() -> new RangedWrapper(this.inventory, FUEL_SLOT, INPUT_SLOT + 1));
-
- public short smeltTimeLeft = -1;
- public short maxSmeltTime = -1;
- public short fuelBurnTimeLeft = -1;
- public short maxFuelBurnTime = -1;
- private boolean lastBurning = false;
-
- public ModFurnaceTileEntity() {
- super(ModTileEntityTypes.MOD_FURNACE.get());
- }
-
- /**
- * @return If the stack is not empty and has a smelting recipe associated with it
- */
- private boolean isInput(final ItemStack stack) {
- if (stack.isEmpty())
- return false;
- return getRecipe(stack).isPresent();
- }
-
- /**
- * @return If the stack's item is equal to the result of smelting our input
- */
- private boolean isOutput(final ItemStack stack) {
- final Optional result = getResult(inventory.getStackInSlot(INPUT_SLOT));
- return result.isPresent() && ItemStack.areItemsEqual(result.get(), stack);
- }
-
- /**
- * @return The smelting recipe for the input stack
- */
- private Optional getRecipe(final ItemStack input) {
- // Due to vanilla's code we need to pass an IInventory into RecipeManager#getRecipe so we make one here.
- return getRecipe(new Inventory(input));
- }
-
- /**
- * @return The smelting recipe for the inventory
- */
- private Optional getRecipe(final IInventory inventory) {
- return world.getRecipeManager().getRecipe(IRecipeType.SMELTING, inventory, world);
- }
-
- /**
- * @return The result of smelting the input stack
- */
- private Optional getResult(final ItemStack input) {
- // Due to vanilla's code we need to pass an IInventory into RecipeManager#getRecipe and
- // AbstractCookingRecipe#getCraftingResult() so we make one here.
- final Inventory dummyInventory = new Inventory(input);
- return getRecipe(dummyInventory).map(recipe -> recipe.getCraftingResult(dummyInventory));
- }
-
- /**
- * Called every tick to update our tile entity
- */
- @Override
- public void tick() {
- if (world == null || world.isRemote)
- return;
-
- // Fuel burning code
-
- boolean hasFuel = false;
- if (isBurning()) {
- hasFuel = true;
- --fuelBurnTimeLeft;
- }
-
- // Smelting code
-
- final ItemStack input = inventory.getStackInSlot(INPUT_SLOT).copy();
- final ItemStack result = getResult(input).orElse(ItemStack.EMPTY);
-
- if (!result.isEmpty() && isInput(input)) {
- final boolean canInsertResultIntoOutput = inventory.insertItem(OUTPUT_SLOT, result, true).isEmpty();
- if (canInsertResultIntoOutput) {
- if (!hasFuel)
- if (burnFuel())
- hasFuel = true;
- if (hasFuel) {
- if (smeltTimeLeft == -1) { // Item has not been smelted before
- smeltTimeLeft = maxSmeltTime = getSmeltTime(input);
- } else { // Item was already being smelted
- --smeltTimeLeft;
- if (smeltTimeLeft == 0) {
- inventory.insertItem(OUTPUT_SLOT, result, false);
- if (input.hasContainerItem())
- inventory.setStackInSlot(INPUT_SLOT, input.getContainerItem());
- else {
- input.shrink(1);
- inventory.setStackInSlot(INPUT_SLOT, input); // Update the data
- }
- smeltTimeLeft = -1; // Set to -1 so we smelt the next stack on the next tick
- }
- }
- } else // No fuel -> add to smelt time left to simulate cooling
- if (smeltTimeLeft < maxSmeltTime)
- ++smeltTimeLeft;
- }
- } else // We have an invalid input stack (somehow)
- smeltTimeLeft = maxSmeltTime = -1;
-
- // Syncing code
-
- // If the burning state has changed.
- if (lastBurning != hasFuel) { // We use hasFuel because the current fuel may be all burnt out but we have more that will be used next tick
-
- // "markDirty" tells vanilla that the chunk containing the tile entity has
- // changed and means the game will save the chunk to disk later.
- this.markDirty();
-
- final BlockState newState = this.getBlockState()
- .with(ModFurnaceBlock.BURNING, hasFuel);
-
- // Flag 2: Send the change to clients
- world.setBlockState(pos, newState, 2);
-
- // Update the last synced burning state to the current burning state
- lastBurning = hasFuel;
- }
-
- }
-
- /**
- * Mimics the code in {@link AbstractFurnaceTileEntity#func_214005_h()}
- *
- * @return The custom smelt time or 200 if there is no recipe for the input
- */
- private short getSmeltTime(final ItemStack input) {
- return getRecipe(input)
- .map(AbstractCookingRecipe::getCookTime)
- .orElse(200)
- .shortValue();
- }
-
- /**
- * @return If the fuel was burnt
- */
- private boolean burnFuel() {
- final ItemStack fuelStack = inventory.getStackInSlot(FUEL_SLOT).copy();
- if (!fuelStack.isEmpty()) {
- final int burnTime = ForgeHooks.getBurnTime(fuelStack);
- if (burnTime > 0) {
- fuelBurnTimeLeft = maxFuelBurnTime = ((short) burnTime);
- if (fuelStack.hasContainerItem())
- inventory.setStackInSlot(FUEL_SLOT, fuelStack.getContainerItem());
- else {
- fuelStack.shrink(1);
- inventory.setStackInSlot(FUEL_SLOT, fuelStack); // Update the data
- }
- return true;
- }
- }
- fuelBurnTimeLeft = maxFuelBurnTime = -1;
- return false;
- }
-
- public boolean isBurning() {
- return this.fuelBurnTimeLeft > 0;
- }
-
- /**
- * Retrieves the Optional handler for the capability requested on the specific side.
- *
- * @param cap The capability to check
- * @param side The Direction to check from. CAN BE NULL! Null is defined to represent 'internal' or 'self'
- * @return The requested an optional holding the requested capability.
- */
- @Nonnull
- @Override
- public LazyOptional getCapability(@Nonnull final Capability cap, @Nullable final Direction side) {
- if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
- if (side == null)
- return inventoryCapabilityExternal.cast();
- switch (side) {
- case DOWN:
- return inventoryCapabilityExternalDown.cast();
- case UP:
- return inventoryCapabilityExternalUp.cast();
- case NORTH:
- case SOUTH:
- case WEST:
- case EAST:
- return inventoryCapabilityExternalSides.cast();
- }
- }
- return super.getCapability(cap, side);
- }
-
- @Override
- public void onLoad() {
- super.onLoad();
- // We set this in onLoad instead of the constructor so that TileEntities
- // constructed from NBT (saved tile entities) have this set to the proper value
- if (world != null && !world.isRemote)
- lastBurning = isBurning();
- }
-
- /**
- * Read saved data from disk into the tile.
- */
- @Override
- public void read(final CompoundNBT compound) {
- super.read(compound);
- this.inventory.deserializeNBT(compound.getCompound(INVENTORY_TAG));
- this.smeltTimeLeft = compound.getShort(SMELT_TIME_LEFT_TAG);
- this.maxSmeltTime = compound.getShort(MAX_SMELT_TIME_TAG);
- this.fuelBurnTimeLeft = compound.getShort(FUEL_BURN_TIME_LEFT_TAG);
- this.maxFuelBurnTime = compound.getShort(MAX_FUEL_BURN_TIME_TAG);
- }
-
- /**
- * Write data from the tile into a compound tag for saving to disk.
- */
- @Nonnull
- @Override
- public CompoundNBT write(final CompoundNBT compound) {
- super.write(compound);
- compound.put(INVENTORY_TAG, this.inventory.serializeNBT());
- compound.putShort(SMELT_TIME_LEFT_TAG, this.smeltTimeLeft);
- compound.putShort(MAX_SMELT_TIME_TAG, this.maxSmeltTime);
- compound.putShort(FUEL_BURN_TIME_LEFT_TAG, this.fuelBurnTimeLeft);
- compound.putShort(MAX_FUEL_BURN_TIME_TAG, this.maxFuelBurnTime);
- return compound;
- }
-
- /**
- * Get an NBT compound to sync to the client with SPacketChunkData, used for initial loading of the
- * chunk or when many blocks change at once.
- * This compound comes back to you client-side in {@link #handleUpdateTag}
- * The default implementation ({@link TileEntity#handleUpdateTag}) calls {@link #writeInternal)}
- * which doesn't save any of our extra data so we override it to call {@link #write} instead
- */
- @Nonnull
- public CompoundNBT getUpdateTag() {
- return this.write(new CompoundNBT());
- }
-
- /**
- * Invalidates our tile entity
- */
- @Override
- public void remove() {
- super.remove();
- // We need to invalidate our capability references so that any cached references (by other mods) don't
- // continue to reference our capabilities and try to use them and/or prevent them from being garbage collected
- inventoryCapabilityExternal.invalidate();
- }
-
- @Nonnull
- @Override
- public ITextComponent getDisplayName() {
- return new TranslationTextComponent(ModBlocks.MOD_FURNACE.get().getTranslationKey());
- }
-
- /**
- * Called from {@link NetworkHooks#openGui}
- * (which is called from {@link ElectricFurnaceBlock#onBlockActivated} on the logical server)
- *
- * @return The logical-server-side Container for this TileEntity
- */
- @Nonnull
- @Override
- public Container createMenu(final int windowId, final PlayerInventory inventory, final PlayerEntity player) {
- return new ModFurnaceContainer(windowId, inventory, this);
- }
-
-}
diff --git a/src/main/java/io/github/cadiboo/examplemod/tileentity/TileEntityExampleTileEntity.java b/src/main/java/io/github/cadiboo/examplemod/tileentity/TileEntityExampleTileEntity.java
new file mode 100644
index 0000000..654b5ea
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/tileentity/TileEntityExampleTileEntity.java
@@ -0,0 +1,11 @@
+package io.github.cadiboo.examplemod.tileentity;
+
+import net.minecraft.tileentity.TileEntity;
+
+public class TileEntityExampleTileEntity extends TileEntity {
+
+ public TileEntityExampleTileEntity() {
+
+ }
+
+}
diff --git a/src/main/java/io/github/cadiboo/examplemod/tileentity/package-info.java b/src/main/java/io/github/cadiboo/examplemod/tileentity/package-info.java
new file mode 100644
index 0000000..730efd2
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/tileentity/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Contains our mod's {@link net.minecraft.tileentity.TileEntity TileEntities}
+ */
+
+package io.github.cadiboo.examplemod.tileentity;
diff --git a/src/main/java/io/github/cadiboo/examplemod/util/IProxy.java b/src/main/java/io/github/cadiboo/examplemod/util/IProxy.java
new file mode 100644
index 0000000..e227b4c
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/util/IProxy.java
@@ -0,0 +1,23 @@
+package io.github.cadiboo.examplemod.util;
+
+import net.minecraftforge.fml.relauncher.Side;
+import org.apache.logging.log4j.Logger;
+
+/**
+ * Some basic functions that differ depending on the physical side
+ *
+ * @author Cadiboo
+ */
+public interface IProxy {
+
+ String localize(String unlocalized);
+
+ String localizeAndFormat(String unlocalized, Object... args);
+
+ default void logPhysicalSide(Logger logger) {
+ logger.debug("Physical Side: " + getPhysicalSide());
+ }
+
+ Side getPhysicalSide();
+
+}
diff --git a/src/main/java/io/github/cadiboo/examplemod/util/ModGuiHandler.java b/src/main/java/io/github/cadiboo/examplemod/util/ModGuiHandler.java
new file mode 100644
index 0000000..e7c42bf
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/util/ModGuiHandler.java
@@ -0,0 +1,67 @@
+package io.github.cadiboo.examplemod.util;
+
+import net.minecraft.client.gui.Gui;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.inventory.Container;
+import net.minecraft.world.World;
+import net.minecraftforge.fml.common.network.IGuiHandler;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.fml.relauncher.SideOnly;
+
+/**
+ * Handles the opening (creation) of Guis for both the server and client
+ *
+ * @author Cadiboo
+ */
+public final class ModGuiHandler implements IGuiHandler {
+
+ public static final int EXAMPLE_GUI_1 = 0;
+ public static final int EXAMPLE_GUI_2 = 1;
+ public static final int EXAMPLE_GUI_3 = 2;
+
+ /**
+ * gets the server's part of a Gui
+ *
+ * @return a {@link Container} for the server
+ */
+ @Override
+ public Container getServerGuiElement(final int ID, final EntityPlayer player, final World world, final int x, final int y, final int z) {
+ switch (ID) {
+ case EXAMPLE_GUI_1:
+ // get container for gui
+ return null;
+ case EXAMPLE_GUI_2:
+ // get container for gui
+ return null;
+ case EXAMPLE_GUI_3:
+ // get container for gui
+ return null;
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * gets the client's part of a Gui
+ *
+ * @return a {@link GuiScreen} for the client
+ */
+ @Override
+ @SideOnly(Side.CLIENT)
+ public Gui getClientGuiElement(final int ID, final EntityPlayer player, final World world, final int x, final int y, final int z) {
+ switch (ID) {
+ case EXAMPLE_GUI_1:
+ // get gui for gui
+ return null;
+ case EXAMPLE_GUI_2:
+ // get gui for gui
+ return null;
+ case EXAMPLE_GUI_3:
+ // get gui for gui
+ return null;
+ default:
+ return null;
+ }
+ }
+
+}
diff --git a/src/main/java/io/github/cadiboo/examplemod/util/ModReference.java b/src/main/java/io/github/cadiboo/examplemod/util/ModReference.java
new file mode 100644
index 0000000..140afa5
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/util/ModReference.java
@@ -0,0 +1,60 @@
+package io.github.cadiboo.examplemod.util;
+
+import io.github.cadiboo.examplemod.ExampleMod;
+
+/**
+ * Holds mod-wide constant values
+ *
+ * @author Cadiboo
+ */
+@SuppressWarnings("WeakerAccess")
+public final class ModReference {
+
+ /**
+ * This is our Mod's Name.
+ */
+ public static final String MOD_NAME = "Cadiboo's Example Mod";
+
+ /**
+ * This is our Mod's Mod Id that is used for stuff like resource locations.
+ */
+ public static final String MOD_ID = "examplemod";
+
+ /**
+ * The fully qualified name of the version of IProxy that gets injected into {@link ExampleMod#proxy} on a PHYSICAL CLIENT
+ */
+ public static final String CLIENT_PROXY_CLASS = "io.github.cadiboo.examplemod.client.ClientProxy";
+
+ /**
+ * The fully qualified name of the version of IProxy that gets injected into {@link ExampleMod#proxy} on a PHYSICAL/DEDICATED SERVER
+ */
+ public static final String SERVER_PROXY_CLASS = "io.github.cadiboo.examplemod.server.ServerProxy";
+
+ /**
+ * @see "https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html"
+ */
+ public static final String ACCEPTED_VERSIONS = "[1.12.2]";
+
+ /**
+ * @see "https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html"
+ */
+ public static final String DEPENDENCIES = "" +
+ "required-after:minecraft;" +
+ "required-after:forge@[14.23.5.2768,);" +
+ "";
+
+ /**
+ * "@VERSION@" is replaced by build.gradle with the actual version
+ *
+ * @see Forge Versioning Docs
+ */
+ public static final String VERSION = "@VERSION@";
+
+ /**
+ * "@FINGERPRINT@" is replaced by build.gradle with the actual fingerprint
+ *
+ * @see "https://tutorials.darkhax.net/tutorials/jar_signing/"
+ */
+ public static final String CERTIFICATE_FINGERPRINT = "@FINGERPRINT@";
+
+}
diff --git a/src/main/java/io/github/cadiboo/examplemod/util/ModUtil.java b/src/main/java/io/github/cadiboo/examplemod/util/ModUtil.java
new file mode 100644
index 0000000..405892e
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/util/ModUtil.java
@@ -0,0 +1,168 @@
+package io.github.cadiboo.examplemod.util;
+
+import com.google.common.base.Preconditions;
+import io.github.cadiboo.examplemod.creativetab.ModCreativeTabs;
+import net.minecraft.block.Block;
+import net.minecraft.creativetab.CreativeTabs;
+import net.minecraft.item.Item;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.world.World;
+import net.minecraftforge.fml.relauncher.Side;
+import net.minecraftforge.registries.IForgeRegistryEntry;
+import net.minecraftforge.registries.IForgeRegistryEntry.Impl;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Logger;
+
+import javax.annotation.Nonnull;
+import java.lang.reflect.Field;
+import java.util.Random;
+
+/**
+ * Util that is used on BOTH physical sides
+ *
+ * @author Cadiboo
+ */
+@SuppressWarnings("WeakerAccess")
+public final class ModUtil {
+
+ private static final Random RANDOM = new Random();
+
+ /**
+ * Sets the {@link Impl#setRegistryName(ResourceLocation) Registry Name} and the {@link Item#setTranslationKey(String) Translation Key} (if applicable) for the entry
+ *
+ * @param entry the {@link Impl IForgeRegistryEntry.Impl>} to set the names for
+ * @param name the name for the entry that the registry name is derived from
+ * @return the entry
+ */
+ @Nonnull
+ public static > T setRegistryNames(@Nonnull final T entry, @Nonnull final String name) {
+ return setRegistryNames(entry, new ResourceLocation(ModReference.MOD_ID, name));
+ }
+
+ /**
+ * Sets the {@link Impl#setRegistryName(ResourceLocation) Registry Name} and the {@link Item#setTranslationKey(String) Translation Key} (if applicable) for the entry
+ *
+ * @param entry the {@link Impl IForgeRegistryEntry.Impl>} to set the names for
+ * @param registryName the registry name for the entry that the translation key is also derived from
+ * @return the entry
+ */
+ @Nonnull
+ public static > T setRegistryNames(@Nonnull final T entry, @Nonnull final ResourceLocation registryName) {
+ return setRegistryNames(entry, registryName, registryName.getPath());
+ }
+
+ /**
+ * Sets the {@link Impl#setRegistryName(ResourceLocation) Registry Name} and the {@link Item#setTranslationKey(String) Translation Key} (if applicable) for the entry
+ *
+ * @param entry the {@link Impl IForgeRegistryEntry.Impl>} to set the names for
+ * @param registryName the registry name for the entry
+ * @param translationKey the unlocalized name for the entry
+ * @return the entry
+ */
+ @Nonnull
+ public static > T setRegistryNames(@Nonnull final T entry, @Nonnull final ResourceLocation registryName, @Nonnull final String translationKey) {
+ entry.setRegistryName(registryName);
+ if (entry instanceof Block) {
+ ((Block) entry).setTranslationKey(translationKey);
+ }
+ if (entry instanceof Item) {
+ ((Item) entry).setTranslationKey(translationKey);
+ }
+ return entry;
+ }
+
+ @Nonnull
+ public static > T setCreativeTab(@Nonnull final T entry) {
+ return setCreativeTab(entry, ModCreativeTabs.CREATIVE_TAB);
+ }
+
+ @Nonnull
+ public static > T setCreativeTab(@Nonnull final T entry, final CreativeTabs creativeTab) {
+ if (entry instanceof Block) {
+ ((Block) entry).setCreativeTab(creativeTab);
+ }
+ if (entry instanceof Item) {
+ ((Item) entry).setCreativeTab(creativeTab);
+ }
+ return entry;
+ }
+
+ /**
+ * Utility method to make sure that all our items appear on our creative tab, the search tab and any other tab they specify
+ *
+ * @param item the {@link Item Item}
+ * @return an array of all tabs that this item is on.
+ */
+ @Nonnull
+ public static CreativeTabs[] getCreativeTabs(@Nonnull final Item item) {
+ Preconditions.checkNotNull(item, "Item cannot be null!");
+ if (item.getRegistryName().getNamespace().equals(ModReference.MOD_ID)) {
+ return new CreativeTabs[]{item.getCreativeTab(), ModCreativeTabs.CREATIVE_TAB, CreativeTabs.SEARCH};
+ }
+ return new CreativeTabs[]{item.getCreativeTab(), CreativeTabs.SEARCH};
+ }
+
+ /**
+ * Returns a random between the specified values;
+ *
+ * @param min the minimum value of the random number
+ * @param max the maximum value of the random number
+ * @return the random number
+ */
+ public static double randomBetween(final int min, final int max) {
+ return RANDOM.nextInt((max - min) + 1) + min;
+ }
+
+ /**
+ * Maps a value from one range to another range. Taken from https://stackoverflow.com/a/5732117
+ *
+ * @param input the input
+ * @param inputStart the start of the input's range
+ * @param inputEnd the end of the input's range
+ * @param outputStart the start of the output's range
+ * @param outputEnd the end of the output's range
+ * @return the newly mapped value
+ */
+ public static double map(final double input, final double inputStart, final double inputEnd, final double outputStart, final double outputEnd) {
+ final double input_range = inputEnd - inputStart;
+ final double output_range = outputEnd - outputStart;
+
+ return (((input - inputStart) * output_range) / input_range) + outputStart;
+ }
+
+ @Nonnull
+ public static Side getLogicalSide(@Nonnull final World world) {
+ if (world.isRemote) {
+ return Side.CLIENT;
+ } else {
+ return Side.SERVER;
+ }
+ }
+
+ public static void logLogicalSide(@Nonnull final Logger logger, @Nonnull final World world) {
+ logger.info("Logical Side: " + getLogicalSide(world));
+ }
+
+ /**
+ * Logs all {@link Field Field}s and their values of an object with the {@link Level#INFO INFO} level.
+ *
+ * @param logger the logger to dump on
+ * @param objects the objects to dump.
+ */
+ public static void dump(@Nonnull final Logger logger, @Nonnull final Object... objects) {
+ for (final Object object : objects) {
+ final Field[] fields = object.getClass().getDeclaredFields();
+ logger.info("Dump of " + object + ":");
+ for (final Field field : fields) {
+ try {
+ field.setAccessible(true);
+ logger.info(field.getName() + " - " + field.get(object));
+ } catch (IllegalArgumentException | IllegalAccessException e) {
+ logger.info("Error getting field " + field.getName());
+ logger.info(e.getLocalizedMessage());
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/io/github/cadiboo/examplemod/util/package-info.java b/src/main/java/io/github/cadiboo/examplemod/util/package-info.java
new file mode 100644
index 0000000..65e1575
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/util/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Contains common utility code
+ */
+
+package io.github.cadiboo.examplemod.util;
diff --git a/src/main/java/io/github/cadiboo/examplemod/world/gen/ModWorldGenerator.java b/src/main/java/io/github/cadiboo/examplemod/world/gen/ModWorldGenerator.java
new file mode 100644
index 0000000..a0ec192
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/world/gen/ModWorldGenerator.java
@@ -0,0 +1,57 @@
+package io.github.cadiboo.examplemod.world.gen;
+
+import io.github.cadiboo.examplemod.init.ModBlocks;
+import io.github.cadiboo.examplemod.util.ModUtil;
+import net.minecraft.block.state.IBlockState;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.World;
+import net.minecraft.world.chunk.IChunkProvider;
+import net.minecraft.world.gen.IChunkGenerator;
+import net.minecraft.world.gen.feature.WorldGenMinable;
+import net.minecraftforge.fml.common.IWorldGenerator;
+
+import javax.annotation.Nonnull;
+import java.util.Random;
+
+/**
+ * Basic world generator that generates ores
+ *
+ * @author Cadiboo
+ */
+public class ModWorldGenerator implements IWorldGenerator {
+
+ /* these values are very similar to Iron */
+ private static final int OVERWORLD_MIN_Y = 8;
+ private static final int OVERWORLD_MAX_Y = 64;
+ private static final int OVERWORLD_SIZE = 6;
+ private static final int OVERWORLD_CHANCE = 4;
+
+ @Override
+ public void generate(@Nonnull final Random random, final int chunkX, final int chunkZ, @Nonnull final World world, @Nonnull final IChunkGenerator chunkGenerator, @Nonnull final IChunkProvider chunkProvider) {
+ switch (world.provider.getDimensionType()) {
+ case NETHER:
+ break;
+ case OVERWORLD:
+ this.generateOverworld(random, chunkX, chunkZ, world, chunkGenerator, chunkProvider);
+ break;
+ case THE_END:
+ break;
+ default:
+ break;
+
+ }
+ }
+
+ private void generateOverworld(@Nonnull final Random random, final int chunkX, final int chunkZ, @Nonnull final World world, @Nonnull final IChunkGenerator chunkGenerator, @Nonnull final IChunkProvider chunkProvider) {
+ this.generateOre(ModBlocks.EXAMPLE_ORE.getDefaultState(), world, random, chunkX << 4, chunkZ << 4, OVERWORLD_MIN_Y, OVERWORLD_MAX_Y, OVERWORLD_SIZE, OVERWORLD_CHANCE);
+ }
+
+ private void generateOre(@Nonnull final IBlockState ore, @Nonnull final World world, @Nonnull final Random random, final int x, final int z, final int minY, final int maxY, final int size, final int chances) {
+ for (int chance = 0; chance < chances; chance++) {
+ final BlockPos pos = new BlockPos(x + random.nextInt(16), minY + ModUtil.randomBetween(minY, maxY), z + random.nextInt(16));
+ final WorldGenMinable generator = new WorldGenMinable(ore, size);
+ generator.generate(world, random, pos);
+ }
+ }
+
+}
diff --git a/src/main/java/io/github/cadiboo/examplemod/world/gen/package-info.java b/src/main/java/io/github/cadiboo/examplemod/world/gen/package-info.java
new file mode 100644
index 0000000..9c53c4e
--- /dev/null
+++ b/src/main/java/io/github/cadiboo/examplemod/world/gen/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Contains our mod's world generator
+ */
+
+package io.github.cadiboo.examplemod.world.gen;
diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml
deleted file mode 100644
index b82d29b..0000000
--- a/src/main/resources/META-INF/mods.toml
+++ /dev/null
@@ -1,64 +0,0 @@
-# This is an example mods.toml file. It contains the data relating to the loading mods.
-# There are several mandatory fields (#mandatory), and many more that are optional (#optional).
-# The overall format is standard TOML format, v0.5.0.
-# Note that there are a couple of TOML lists in this file.
-# Find more information on toml format here: https://github.com/toml-lang/toml
-
-# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
-modLoader="javafml" #mandatory
-
-# A version range to match for said mod loader - for regular FML @Mod it will be the forge version
-# See "https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html"
-# 24 is 1.13-pre, 25 is 1.13.2, 26 is 1.14.2, 27 is 1.14.3, 28 is 1.14.4, 29 is 1.15, 30 is 1.15.1, 31 is 1.15.2
-loaderVersion="[31,)" #mandatory
-
-# A URL to refer people to when problems occur with this mod
-issueTrackerURL="http://github.com/YourName/Your-Mod-Name/issues" #optional
-
-# A list of mods - how many allowed here is determined by the individual mod loader
-[[mods]] #mandatory
-# The modid of the mod
-modId="examplemod" #mandatory
-# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it
-version="${version}" #mandatory
-# A display name for the mod
-displayName="Example Mod" #mandatory
-# A URL to query for updates for this mod. See the JSON update specification
-updateJSONURL="http://github.com/YourName/Your-Mod-Name/update.json" #optional
-# A URL for the "homepage" for this mod, displayed in the mod UI
-displayURL="http://github.com/YourName/Your-Mod-Name" #optional
-# A file name (in the root of the mod JAR) containing a logo for display
-logoFile="examplemod.png" #optional
-# A text field displayed in the mod UI
-credits="Thanks for this example mod goes to Java. The logo for this mod was taken from a post by DavidM on the Forge Forums" #optional
-# A text field displayed in the mod UI
-authors="Love, Cheese and small house plants" #optional
-# The description text for the mod (multi line!) (#mandatory)
-description='''
-This is a long form description of the mod. You can write whatever you want here
-
-Have some lorem ipsum.
-
-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis lacinia magna. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed sagittis luctus odio eu tempus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Pellentesque volutpat ligula eget lacus auctor sagittis. In hac habitasse platea dictumst. Nunc gravida elit vitae sem vehicula efficitur. Donec mattis ipsum et arcu lobortis, eleifend sagittis sem rutrum. Cras pharetra quam eget posuere fermentum. Sed id tincidunt justo. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
-'''
-
-# A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional.
-[[dependencies.examplemod]] #optional
-# The modid of the dependency
-modId="forge" #mandatory
-# Does this dependency have to exist - if not, ordering below must be specified
-mandatory=true #mandatory
-# The version range of the dependency (see "https://maven.apache.org/enforcer/enforcer-rules/versionRanges.html")
-versionRange="[31,)" #mandatory
-# An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory
-ordering="NONE"
-# Side this dependency is applied on - BOTH, CLIENT or SERVER
-side="BOTH"
-
-# Here's another dependency
-[[dependencies.examplemod]]
-modId="minecraft"
-mandatory=true
-versionRange="[1.15.2]"
-ordering="NONE"
-side="BOTH"
diff --git a/src/main/resources/assets/examplemod/blockstates/electric_furnace.json b/src/main/resources/assets/examplemod/blockstates/electric_furnace.json
deleted file mode 100755
index 2bcc663..0000000
--- a/src/main/resources/assets/examplemod/blockstates/electric_furnace.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "variants": {
- "facing=north": { "model": "examplemod:block/electric_furnace" },
- "facing=south": { "model": "examplemod:block/electric_furnace", "y": 180 },
- "facing=west": { "model": "examplemod:block/electric_furnace", "y": 270 },
- "facing=east": { "model": "examplemod:block/electric_furnace", "y": 90 }
- }
-}
diff --git a/src/main/resources/assets/examplemod/blockstates/example_block.json b/src/main/resources/assets/examplemod/blockstates/example_block.json
index 2cd6fb0..de3d579 100644
--- a/src/main/resources/assets/examplemod/blockstates/example_block.json
+++ b/src/main/resources/assets/examplemod/blockstates/example_block.json
@@ -1,7 +1,7 @@
{
- "variants": {
- "": {
- "model": "examplemod:block/example_block"
- }
- }
+ "variants": {
+ "normal": [
+ {"model": "examplemod:example_block"}
+ ]
+ }
}
diff --git a/src/main/resources/assets/examplemod/blockstates/example_ore.json b/src/main/resources/assets/examplemod/blockstates/example_ore.json
index 9eeb993..248c496 100644
--- a/src/main/resources/assets/examplemod/blockstates/example_ore.json
+++ b/src/main/resources/assets/examplemod/blockstates/example_ore.json
@@ -1,7 +1,7 @@
{
- "variants": {
- "": {
- "model": "examplemod:block/example_ore"
- }
- }
+ "variants": {
+ "normal": [
+ {"model": "examplemod:example_ore"}
+ ]
+ }
}
diff --git a/src/main/resources/assets/examplemod/blockstates/heat_collector.json b/src/main/resources/assets/examplemod/blockstates/heat_collector.json
deleted file mode 100644
index 9c747f6..0000000
--- a/src/main/resources/assets/examplemod/blockstates/heat_collector.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "variants": {
- "": {
- "model": "examplemod:block/heat_collector"
- }
- }
-}
diff --git a/src/main/resources/assets/examplemod/blockstates/mini_model.json b/src/main/resources/assets/examplemod/blockstates/mini_model.json
deleted file mode 100644
index 7ddeb7d..0000000
--- a/src/main/resources/assets/examplemod/blockstates/mini_model.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "variants": {
- "": {
- "model": "examplemod:block/mini_model"
- }
- }
-}
diff --git a/src/main/resources/assets/examplemod/blockstates/mod_furnace.json b/src/main/resources/assets/examplemod/blockstates/mod_furnace.json
deleted file mode 100755
index 7efe9a9..0000000
--- a/src/main/resources/assets/examplemod/blockstates/mod_furnace.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "variants": {
- "facing=north,burning=false": { "model": "examplemod:block/mod_furnace" },
- "facing=south,burning=false": { "model": "examplemod:block/mod_furnace", "y": 180 },
- "facing=west,burning=false": { "model": "examplemod:block/mod_furnace", "y": 270 },
- "facing=east,burning=false": { "model": "examplemod:block/mod_furnace", "y": 90 },
- "facing=north,burning=true": { "model": "examplemod:block/mod_furnace_burning" },
- "facing=south,burning=true": { "model": "examplemod:block/mod_furnace_burning", "y": 180 },
- "facing=west,burning=true": { "model": "examplemod:block/mod_furnace_burning", "y": 270 },
- "facing=east,burning=true": { "model": "examplemod:block/mod_furnace_burning", "y": 90 }
- }
-}
diff --git a/src/main/resources/assets/examplemod/lang/en_us.json b/src/main/resources/assets/examplemod/lang/en_us.json
deleted file mode 100644
index e13729c..0000000
--- a/src/main/resources/assets/examplemod/lang/en_us.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "block.examplemod.example_ore": "Example Ore",
- "block.examplemod.example_block": "Example Block",
- "block.examplemod.mini_model": "Mini Model",
- "block.examplemod.heat_collector": "Heat Collector",
- "block.examplemod.electric_furnace": "Electric Furnace",
- "block.examplemod.mod_furnace": "Mod Furnace",
- "itemGroup.examplemod": "Example Mod",
- "item.examplemod.example_crystal": "Example Crystal",
- "item.examplemod.wild_boar_spawn_egg": "Wild Boar Spawn Egg",
- "gui.examplemod.refresh_mini_model": "Refresh Mini Model",
- "gui.examplemod.energy": "Energy %s",
- "gui.examplemod.smeltTimeProgress": "Smelt time %s/%s",
- "gui.examplemod.fuelBurnTimeProgress": "Fuel burn time %s/%s"
-}
diff --git a/src/main/resources/assets/examplemod/lang/en_us.lang b/src/main/resources/assets/examplemod/lang/en_us.lang
new file mode 100644
index 0000000..7203e41
--- /dev/null
+++ b/src/main/resources/assets/examplemod/lang/en_us.lang
@@ -0,0 +1,14 @@
+#Items
+item.example_item.name=Example Item
+item.example_ingot.name=Example Ingot
+
+#Blocks
+tile.example_block.name=Example Block
+tile.example_ore.name=Example Ore
+tile.example_tile_entity.name=Example Tile Entity
+
+#Tile Entities
+example_tile_entity.name=Example Tile Entity
+
+#Creative Tab(s)
+itemGroup.examplemod=Example Mod
diff --git a/src/main/resources/assets/examplemod/models/block/electric_furnace.json b/src/main/resources/assets/examplemod/models/block/electric_furnace.json
deleted file mode 100755
index 032a0e0..0000000
--- a/src/main/resources/assets/examplemod/models/block/electric_furnace.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "parent": "block/furnace",
- "textures": {
- "front": "examplemod:block/electric_furnace_front"
- }
-}
diff --git a/src/main/resources/assets/examplemod/models/block/example_block.json b/src/main/resources/assets/examplemod/models/block/example_block.json
index ac510d4..f4bb856 100644
--- a/src/main/resources/assets/examplemod/models/block/example_block.json
+++ b/src/main/resources/assets/examplemod/models/block/example_block.json
@@ -1,6 +1,6 @@
{
- "parent": "block/cube_all",
- "textures": {
- "all": "examplemod:block/example_block"
- }
+ "parent": "block/cube_all",
+ "textures": {
+ "all": "examplemod:block/example_block"
+ }
}
diff --git a/src/main/resources/assets/examplemod/models/block/example_ore.json b/src/main/resources/assets/examplemod/models/block/example_ore.json
index 26708b3..6867a6d 100644
--- a/src/main/resources/assets/examplemod/models/block/example_ore.json
+++ b/src/main/resources/assets/examplemod/models/block/example_ore.json
@@ -1,6 +1,6 @@
{
- "parent": "block/cube_all",
- "textures": {
- "all": "examplemod:block/example_ore"
- }
+ "parent": "block/cube_all",
+ "textures": {
+ "all": "examplemod:block/example_ore"
+ }
}
diff --git a/src/main/resources/assets/examplemod/models/block/heat_collector.json b/src/main/resources/assets/examplemod/models/block/heat_collector.json
deleted file mode 100644
index 326155f..0000000
--- a/src/main/resources/assets/examplemod/models/block/heat_collector.json
+++ /dev/null
@@ -1,368 +0,0 @@
-{
- "credit": "Made with Blockbench",
- "parent": "block/block",
- "textures": {
- "0": "block/anvil_top",
- "1": "block/anvil",
- "2": "block/obsidian",
- "particle": "block/anvil_top"
- },
- "elements": [
- {
- "from": [
- 11,
- 0,
- 0
- ],
- "to": [
- 16,
- 16,
- 5
- ],
- "faces": {
- "north": {
- "uv": [
- 3,
- 0,
- 13,
- 16
- ],
- "texture": "#0",
- "cullface": "north"
- },
- "east": {
- "uv": [
- 3,
- 0,
- 13,
- 16
- ],
- "texture": "#0",
- "cullface": "east"
- },
- "south": {
- "uv": [
- 3,
- 0,
- 13,
- 16
- ],
- "texture": "#0"
- },
- "west": {
- "uv": [
- 3,
- 0,
- 13,
- 16
- ],
- "texture": "#0"
- },
- "up": {
- "uv": [
- 0,
- 0,
- 16,
- 16
- ],
- "texture": "#1",
- "cullface": "up"
- },
- "down": {
- "uv": [
- 0,
- 0,
- 16,
- 16
- ],
- "texture": "#1",
- "cullface": "down"
- }
- }
- },
- {
- "from": [
- 11,
- 0,
- 11
- ],
- "to": [
- 16,
- 16,
- 16
- ],
- "faces": {
- "north": {
- "uv": [
- 3,
- 0,
- 13,
- 16
- ],
- "texture": "#0"
- },
- "east": {
- "uv": [
- 3,
- 0,
- 13,
- 16
- ],
- "texture": "#0",
- "cullface": "east"
- },
- "south": {
- "uv": [
- 3,
- 0,
- 13,
- 16
- ],
- "texture": "#0",
- "cullface": "south"
- },
- "west": {
- "uv": [
- 3,
- 0,
- 13,
- 16
- ],
- "texture": "#0"
- },
- "up": {
- "uv": [
- 0,
- 0,
- 16,
- 16
- ],
- "texture": "#1",
- "cullface": "up"
- },
- "down": {
- "uv": [
- 0,
- 0,
- 16,
- 16
- ],
- "texture": "#1",
- "cullface": "down"
- }
- }
- },
- {
- "from": [
- 0,
- 0,
- 11
- ],
- "to": [
- 5,
- 16,
- 16
- ],
- "faces": {
- "north": {
- "uv": [
- 3,
- 0,
- 13,
- 16
- ],
- "texture": "#0"
- },
- "east": {
- "uv": [
- 3,
- 0,
- 13,
- 16
- ],
- "texture": "#0"
- },
- "south": {
- "uv": [
- 3,
- 0,
- 13,
- 16
- ],
- "texture": "#0",
- "cullface": "south"
- },
- "west": {
- "uv": [
- 3,
- 0,
- 13,
- 16
- ],
- "texture": "#0",
- "cullface": "west"
- },
- "up": {
- "uv": [
- 0,
- 0,
- 16,
- 16
- ],
- "texture": "#1",
- "cullface": "up"
- },
- "down": {
- "uv": [
- 0,
- 0,
- 16,
- 16
- ],
- "texture": "#1",
- "cullface": "down"
- }
- }
- },
- {
- "from": [
- 0,
- 0,
- 0
- ],
- "to": [
- 5,
- 16,
- 5
- ],
- "faces": {
- "north": {
- "uv": [
- 3,
- 0,
- 13,
- 16
- ],
- "texture": "#0",
- "cullface": "north"
- },
- "east": {
- "uv": [
- 3,
- 0,
- 13,
- 16
- ],
- "texture": "#0"
- },
- "south": {
- "uv": [
- 3,
- 0,
- 13,
- 16
- ],
- "texture": "#0"
- },
- "west": {
- "uv": [
- 3,
- 0,
- 13,
- 16
- ],
- "texture": "#0",
- "cullface": "west"
- },
- "up": {
- "uv": [
- 0,
- 0,
- 16,
- 16
- ],
- "texture": "#1",
- "cullface": "up"
- },
- "down": {
- "uv": [
- 0,
- 0,
- 16,
- 16
- ],
- "texture": "#1",
- "cullface": "down"
- }
- }
- },
- {
- "from": [
- 5,
- 5,
- 5
- ],
- "to": [
- 11,
- 11,
- 11
- ],
- "faces": {
- "north": {
- "uv": [
- 0,
- 0,
- 16,
- 16
- ],
- "texture": "#2"
- },
- "east": {
- "uv": [
- 0,
- 0,
- 16,
- 16
- ],
- "texture": "#2"
- },
- "south": {
- "uv": [
- 0,
- 0,
- 16,
- 16
- ],
- "texture": "#2"
- },
- "west": {
- "uv": [
- 0,
- 0,
- 16,
- 16
- ],
- "texture": "#2"
- },
- "up": {
- "uv": [
- 0,
- 0,
- 16,
- 16
- ],
- "texture": "#2"
- },
- "down": {
- "uv": [
- 0,
- 0,
- 16,
- 16
- ],
- "texture": "#2"
- }
- }
- }
- ]
-}
diff --git a/src/main/resources/assets/examplemod/models/block/mini_model.json b/src/main/resources/assets/examplemod/models/block/mini_model.json
deleted file mode 100644
index cc3d6b9..0000000
--- a/src/main/resources/assets/examplemod/models/block/mini_model.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "parent": "block/block",
- "textures": {
- "particle": "examplemod:block/mini_model"
- }
-}
diff --git a/src/main/resources/assets/examplemod/models/block/mod_furnace.json b/src/main/resources/assets/examplemod/models/block/mod_furnace.json
deleted file mode 100755
index b3b2cb8..0000000
--- a/src/main/resources/assets/examplemod/models/block/mod_furnace.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "parent": "block/furnace"
-}
diff --git a/src/main/resources/assets/examplemod/models/block/mod_furnace_burning.json b/src/main/resources/assets/examplemod/models/block/mod_furnace_burning.json
deleted file mode 100644
index e2cd86b..0000000
--- a/src/main/resources/assets/examplemod/models/block/mod_furnace_burning.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "parent": "block/furnace_on"
-}
diff --git a/src/main/resources/assets/examplemod/models/item/electric_furnace.json b/src/main/resources/assets/examplemod/models/item/electric_furnace.json
deleted file mode 100644
index 946e0e6..0000000
--- a/src/main/resources/assets/examplemod/models/item/electric_furnace.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "parent": "examplemod:block/electric_furnace"
-}
diff --git a/src/main/resources/assets/examplemod/models/item/example_block.json b/src/main/resources/assets/examplemod/models/item/example_block.json
deleted file mode 100644
index 75f0184..0000000
--- a/src/main/resources/assets/examplemod/models/item/example_block.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "parent": "examplemod:block/example_block"
-}
diff --git a/src/main/resources/assets/examplemod/models/item/example_crystal.json b/src/main/resources/assets/examplemod/models/item/example_crystal.json
deleted file mode 100755
index 6cbe814..0000000
--- a/src/main/resources/assets/examplemod/models/item/example_crystal.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "parent": "item/generated",
- "textures": {
- "layer0": "examplemod:item/example_crystal"
- }
-}
diff --git a/src/main/resources/assets/examplemod/models/item/example_ingot.json b/src/main/resources/assets/examplemod/models/item/example_ingot.json
new file mode 100644
index 0000000..f36cf5d
--- /dev/null
+++ b/src/main/resources/assets/examplemod/models/item/example_ingot.json
@@ -0,0 +1,6 @@
+{
+ "parent": "item/generated",
+ "textures": {
+ "layer0": "examplemod:item/example_ingot"
+ }
+}
diff --git a/src/main/resources/assets/examplemod/models/item/example_item.json b/src/main/resources/assets/examplemod/models/item/example_item.json
new file mode 100644
index 0000000..a167d7c
--- /dev/null
+++ b/src/main/resources/assets/examplemod/models/item/example_item.json
@@ -0,0 +1,6 @@
+{
+ "parent": "item/generated",
+ "textures": {
+ "layer0": "examplemod:item/example_item"
+ }
+}
diff --git a/src/main/resources/assets/examplemod/models/item/example_ore.json b/src/main/resources/assets/examplemod/models/item/example_ore.json
deleted file mode 100644
index a99ffff..0000000
--- a/src/main/resources/assets/examplemod/models/item/example_ore.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "parent": "examplemod:block/example_ore"
-}
diff --git a/src/main/resources/assets/examplemod/models/item/example_tile_entity.json b/src/main/resources/assets/examplemod/models/item/example_tile_entity.json
new file mode 100644
index 0000000..12df6e3
--- /dev/null
+++ b/src/main/resources/assets/examplemod/models/item/example_tile_entity.json
@@ -0,0 +1,6 @@
+{
+ "parent": "block/cube_all",
+ "textures": {
+ "all": "examplemod:block/example_tile_entity"
+ }
+}
diff --git a/src/main/resources/assets/examplemod/models/item/heat_collector.json b/src/main/resources/assets/examplemod/models/item/heat_collector.json
deleted file mode 100644
index 012af12..0000000
--- a/src/main/resources/assets/examplemod/models/item/heat_collector.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "parent": "examplemod:block/heat_collector"
-}
diff --git a/src/main/resources/assets/examplemod/models/item/mini_model.json b/src/main/resources/assets/examplemod/models/item/mini_model.json
deleted file mode 100644
index d6688c0..0000000
--- a/src/main/resources/assets/examplemod/models/item/mini_model.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "parent": "block/cube_all",
- "textures": {
- "all": "examplemod:block/mini_model"
- }
-}
diff --git a/src/main/resources/assets/examplemod/models/item/mod_furnace.json b/src/main/resources/assets/examplemod/models/item/mod_furnace.json
deleted file mode 100644
index e058c15..0000000
--- a/src/main/resources/assets/examplemod/models/item/mod_furnace.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "parent": "examplemod:block/mod_furnace"
-}
diff --git a/src/main/resources/assets/examplemod/models/item/wild_boar_spawn_egg.json b/src/main/resources/assets/examplemod/models/item/wild_boar_spawn_egg.json
deleted file mode 100644
index 765225c..0000000
--- a/src/main/resources/assets/examplemod/models/item/wild_boar_spawn_egg.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "parent": "item/template_spawn_egg"
-}
diff --git a/src/main/resources/assets/examplemod/recipes/example_recipe.json b/src/main/resources/assets/examplemod/recipes/example_recipe.json
new file mode 100644
index 0000000..9b2295e
--- /dev/null
+++ b/src/main/resources/assets/examplemod/recipes/example_recipe.json
@@ -0,0 +1,53 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "group": "identifier",
+ "pattern": [
+ "AA ",
+ "11 ",
+ "## "
+ ],
+ "key": {
+ "A": {
+ "item": "minecraft:stone",
+ "data": 0,
+ "count": 1
+ },
+ "1": {
+ "item": "minecraft:dirt",
+ "data": 0,
+ "count": 1
+ },
+ "#": {
+ "item": "minecraft:cobblestone",
+ "data": 0,
+ "count": 1
+ }
+ },
+ "ingredients": [
+ {
+ "item": "minecraft:stone",
+ "data": 0,
+ "count": 1
+ }
+ ],
+ "result": {
+ "item": "minecraft:bedrock",
+ "data": 0,
+ "count": 1
+ }
+}
+
+{
+ "type": "crafting_shapeless",
+ "ingredients": [
+ {
+ "item": "minecraft:diamond"
+ },
+ {
+ "item": "minecraft:nether_star"
+ }
+ ],
+ "result": {
+ "item": "minecraft:stick"
+ }
+}
diff --git a/src/main/resources/assets/examplemod/textures/block/electric_furnace_front.png b/src/main/resources/assets/examplemod/textures/block/electric_furnace_front.png
deleted file mode 100755
index 1ac5b7f..0000000
Binary files a/src/main/resources/assets/examplemod/textures/block/electric_furnace_front.png and /dev/null differ
diff --git a/src/main/resources/assets/examplemod/textures/block/example_block.png b/src/main/resources/assets/examplemod/textures/block/example_block.png
index 63f9816..c755453 100755
Binary files a/src/main/resources/assets/examplemod/textures/block/example_block.png and b/src/main/resources/assets/examplemod/textures/block/example_block.png differ
diff --git a/src/main/resources/assets/examplemod/textures/block/mini_model.png b/src/main/resources/assets/examplemod/textures/block/example_tile_entity.png
similarity index 100%
rename from src/main/resources/assets/examplemod/textures/block/mini_model.png
rename to src/main/resources/assets/examplemod/textures/block/example_tile_entity.png
diff --git a/src/main/resources/assets/examplemod/textures/entity/wild_boar/wild_boar.png b/src/main/resources/assets/examplemod/textures/entity/wild_boar/wild_boar.png
deleted file mode 100755
index 7fed2ed..0000000
Binary files a/src/main/resources/assets/examplemod/textures/entity/wild_boar/wild_boar.png and /dev/null differ
diff --git a/src/main/resources/assets/examplemod/textures/entity/wild_boar/wild_boar_saddle.png b/src/main/resources/assets/examplemod/textures/entity/wild_boar/wild_boar_saddle.png
deleted file mode 100755
index c7e2de8..0000000
Binary files a/src/main/resources/assets/examplemod/textures/entity/wild_boar/wild_boar_saddle.png and /dev/null differ
diff --git a/src/main/resources/assets/examplemod/textures/gui/container/electric_furnace.png b/src/main/resources/assets/examplemod/textures/gui/container/electric_furnace.png
deleted file mode 100755
index 3902920..0000000
Binary files a/src/main/resources/assets/examplemod/textures/gui/container/electric_furnace.png and /dev/null differ
diff --git a/src/main/resources/assets/examplemod/textures/gui/container/heat_collector.png b/src/main/resources/assets/examplemod/textures/gui/container/heat_collector.png
deleted file mode 100755
index c662ffd..0000000
Binary files a/src/main/resources/assets/examplemod/textures/gui/container/heat_collector.png and /dev/null differ
diff --git a/src/main/resources/assets/examplemod/textures/item/example_crystal.png b/src/main/resources/assets/examplemod/textures/item/example_ingot.png
similarity index 68%
rename from src/main/resources/assets/examplemod/textures/item/example_crystal.png
rename to src/main/resources/assets/examplemod/textures/item/example_ingot.png
index fb76786..dd76c5f 100755
Binary files a/src/main/resources/assets/examplemod/textures/item/example_crystal.png and b/src/main/resources/assets/examplemod/textures/item/example_ingot.png differ
diff --git a/src/main/resources/assets/examplemod/textures/item/example_item.png b/src/main/resources/assets/examplemod/textures/item/example_item.png
new file mode 100644
index 0000000..8cd5384
Binary files /dev/null and b/src/main/resources/assets/examplemod/textures/item/example_item.png differ
diff --git a/src/main/resources/data/examplemod/loot_tables/blocks/electric_furnace.json b/src/main/resources/data/examplemod/loot_tables/blocks/electric_furnace.json
deleted file mode 100644
index a4a629a..0000000
--- a/src/main/resources/data/examplemod/loot_tables/blocks/electric_furnace.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "type": "minecraft:block",
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "minecraft:item",
- "name": "examplemod:electric_furnace"
- }
- ],
- "conditions": [
- {
- "condition": "minecraft:survives_explosion"
- }
- ]
- }
- ]
-}
diff --git a/src/main/resources/data/examplemod/loot_tables/blocks/example_block.json b/src/main/resources/data/examplemod/loot_tables/blocks/example_block.json
deleted file mode 100644
index a947118..0000000
--- a/src/main/resources/data/examplemod/loot_tables/blocks/example_block.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "type": "minecraft:block",
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "minecraft:item",
- "name": "examplemod:example_block"
- }
- ],
- "conditions": [
- {
- "condition": "minecraft:survives_explosion"
- }
- ]
- }
- ]
-}
diff --git a/src/main/resources/data/examplemod/loot_tables/blocks/example_ore.json b/src/main/resources/data/examplemod/loot_tables/blocks/example_ore.json
deleted file mode 100644
index 018278c..0000000
--- a/src/main/resources/data/examplemod/loot_tables/blocks/example_ore.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "type": "minecraft:block",
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "minecraft:item",
- "name": "examplemod:example_ore"
- }
- ],
- "conditions": [
- {
- "condition": "minecraft:survives_explosion"
- }
- ]
- }
- ]
-}
diff --git a/src/main/resources/data/examplemod/loot_tables/blocks/heat_collector.json b/src/main/resources/data/examplemod/loot_tables/blocks/heat_collector.json
deleted file mode 100644
index 027f82c..0000000
--- a/src/main/resources/data/examplemod/loot_tables/blocks/heat_collector.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "type": "minecraft:block",
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "minecraft:item",
- "name": "examplemod:heat_collector"
- }
- ],
- "conditions": [
- {
- "condition": "minecraft:survives_explosion"
- }
- ]
- }
- ]
-}
diff --git a/src/main/resources/data/examplemod/loot_tables/blocks/mini_model.json b/src/main/resources/data/examplemod/loot_tables/blocks/mini_model.json
deleted file mode 100644
index 2bf5e0c..0000000
--- a/src/main/resources/data/examplemod/loot_tables/blocks/mini_model.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "type": "minecraft:block",
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "minecraft:item",
- "name": "examplemod:mini_model"
- }
- ],
- "conditions": [
- {
- "condition": "minecraft:survives_explosion"
- }
- ]
- }
- ]
-}
diff --git a/src/main/resources/data/examplemod/loot_tables/blocks/mod_furnace.json b/src/main/resources/data/examplemod/loot_tables/blocks/mod_furnace.json
deleted file mode 100644
index 8f22d35..0000000
--- a/src/main/resources/data/examplemod/loot_tables/blocks/mod_furnace.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "type": "minecraft:block",
- "pools": [
- {
- "rolls": 1,
- "entries": [
- {
- "type": "minecraft:item",
- "name": "examplemod:mod_furnace"
- }
- ],
- "conditions": [
- {
- "condition": "minecraft:survives_explosion"
- }
- ]
- }
- ]
-}
diff --git a/src/main/resources/data/examplemod/recipes/example_block_from_example_crystal.json b/src/main/resources/data/examplemod/recipes/example_block_from_example_crystal.json
deleted file mode 100755
index 7ff1100..0000000
--- a/src/main/resources/data/examplemod/recipes/example_block_from_example_crystal.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "type": "minecraft:crafting_shaped",
- "pattern": [
- "###",
- "###",
- "###"
- ],
- "key": {
- "#": {
- "item": "examplemod:example_crystal"
- }
- },
- "result": {
- "item": "examplemod:example_block"
- }
-}
diff --git a/src/main/resources/data/examplemod/recipes/example_crystal_from_example_block.json b/src/main/resources/data/examplemod/recipes/example_crystal_from_example_block.json
deleted file mode 100755
index d6204d5..0000000
--- a/src/main/resources/data/examplemod/recipes/example_crystal_from_example_block.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "type": "minecraft:crafting_shapeless",
- "ingredients": [
- {
- "item": "examplemod:example_block"
- }
- ],
- "result": {
- "item": "examplemod:example_crystal",
- "count": 9
- }
-}
diff --git a/src/main/resources/data/examplemod/recipes/example_crystal_from_smelting.json b/src/main/resources/data/examplemod/recipes/example_crystal_from_smelting.json
deleted file mode 100755
index 7b36aaa..0000000
--- a/src/main/resources/data/examplemod/recipes/example_crystal_from_smelting.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "type": "minecraft:smelting",
- "ingredient": {
- "item": "examplemod:example_ore"
- },
- "result": "examplemod:example_crystal",
- "experience": 0.7,
- "cookingtime": 200
-}
diff --git a/src/main/resources/data/examplemod/recipes/heat_collector.json b/src/main/resources/data/examplemod/recipes/heat_collector.json
deleted file mode 100755
index dd13bf6..0000000
--- a/src/main/resources/data/examplemod/recipes/heat_collector.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "type": "minecraft:crafting_shaped",
- "pattern": [
- "i i",
- " o ",
- "i i"
- ],
- "key": {
- "i": {
- "item": "minecraft:iron_block"
- },
- "o": {
- "item": "minecraft:obsidian"
- }
- },
- "result": {
- "item": "examplemod:heat_collector"
- }
-}
diff --git a/src/main/resources/data/examplemod/recipes/mini_model.json b/src/main/resources/data/examplemod/recipes/mini_model.json
deleted file mode 100755
index dd76efe..0000000
--- a/src/main/resources/data/examplemod/recipes/mini_model.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "type": "minecraft:crafting_shapeless",
- "ingredients": [
- {
- "item": "minecraft:map"
- },
- {
- "item": "minecraft:beacon"
- }
- ],
- "result": {
- "item": "examplemod:mini_model"
- }
-}
diff --git a/src/main/resources/examplemod.png b/src/main/resources/examplemod.png
deleted file mode 100644
index 3a19628..0000000
Binary files a/src/main/resources/examplemod.png and /dev/null differ
diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info
new file mode 100644
index 0000000..8bfa732
--- /dev/null
+++ b/src/main/resources/mcmod.info
@@ -0,0 +1,16 @@
+[
+{
+ "modid": "examplemod",
+ "name": "Example Mod",
+ "description": "An example mod with some good code practices already in it.",
+ "version": "0.0.0",
+ "mcversion": "1.12.2",
+ "url": "https://github.com/Cadiboo/Cadiboo_Example_Mod_1_12_2/",
+ "updateUrl": "",
+ "authorList": ["Cadiboo"],
+ "credits": "Cadiboo and the Forge and FML guys, for making this example",
+ "logoFile": "",
+ "screenshots": [],
+ "dependencies": []
+}
+]
diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta
index c092327..4018267 100644
--- a/src/main/resources/pack.mcmeta
+++ b/src/main/resources/pack.mcmeta
@@ -1,7 +1,7 @@
{
- "pack": {
- "description": "examplemod resources",
- "pack_format": 5,
- "_comment": "A pack_format of 5 requires json lang files and some texture changes from 1.15. Note: Forge requires v5 pack meta for all mods."
- }
+ "pack": {
+ "description": "examplemod resources",
+ "pack_format": 3,
+ "_comment": "A pack_format of 3 should be used starting with Minecraft 1.11. All resources, including language files, should be lowercase (eg: en_us.lang). A pack_format of 2 will load your mod resources with LegacyV2Adapter, which requires language files to have uppercase letters (eg: en_US.lang)."
+ }
}