Rendering patches (#5262)

This commit is contained in:
tterrag authored and LexManos committed 2018-12-21 14:45:35 -08:00
1 parent 0bfa76251d
commit b3b8c78527
122 files changed
+2354 -2888

No files matched your search

@@ -25,14 +25,11 @@ import static net.minecraftforge.fml.VersionChecker.Status.BETA_OUTDATED;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.function.Predicate;
import javax.annotation.Nonnull;
import javax.vecmath.Matrix3f;
@@ -40,22 +37,25 @@ import javax.vecmath.Matrix4f;
import javax.vecmath.Vector3f;
import javax.vecmath.Vector4f;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.BufferUtils;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.GameSettings;
import net.minecraft.client.MainWindow;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.ISound;
import net.minecraft.client.audio.SoundHandler;
import net.minecraft.client.audio.SoundManager;
import net.minecraft.client.gui.BossInfoClient;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.BlockRendererDispatcher;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderGlobal;
import net.minecraft.client.renderer.block.model.BakedQuad;
@@ -72,27 +72,17 @@ import net.minecraft.client.renderer.color.ItemColors;
import net.minecraft.client.renderer.entity.model.ModelBiped;
import net.minecraft.client.renderer.texture.NativeImage;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.client.renderer.vertex.VertexFormatElement.EnumUsage;
import net.minecraft.client.resources.FoliageColorReloadListener;
import net.minecraft.client.resources.GrassColorReloadListener;
import net.minecraft.client.resources.I18n;
import net.minecraft.client.resources.LanguageManager;
import net.minecraft.client.util.SearchTreeManager;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.passive.EntityHorse;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.fluid.IFluidState;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.resources.IResourceManagerReloadListener;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
@@ -124,24 +114,16 @@ import net.minecraftforge.client.model.ModelDynBucket;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.animation.Animation;
import net.minecraftforge.common.ForgeMod;
import net.minecraftforge.versions.forge.ForgeVersion;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.model.IModelPart;
import net.minecraftforge.common.model.ITransformation;
import net.minecraftforge.common.model.TRSRTransformation;
import net.minecraftforge.fml.VersionChecker;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.resource.IResourceType;
import net.minecraftforge.resource.ReloadRequirements;
import net.minecraftforge.resource.SelectiveReloadStateHandler;
import net.minecraftforge.resource.VanillaResourceType;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.BufferUtils;
import com.google.common.collect.Maps;
import net.minecraftforge.versions.forge.ForgeVersion;
public class ForgeHooksClient
{
@@ -165,9 +147,9 @@ public class ForgeHooksClient
MinecraftForge.EVENT_BUS.post(new RenderWorldLastEvent(context, partialTicks));
}
public static boolean renderFirstPersonHand(RenderGlobal context, float partialTicks, int renderPass)
public static boolean renderFirstPersonHand(RenderGlobal context, float partialTicks)
{
return MinecraftForge.EVENT_BUS.post(new RenderHandEvent(context, partialTicks, renderPass));
return MinecraftForge.EVENT_BUS.post(new RenderHandEvent(context, partialTicks));
}
public static boolean renderSpecificFirstPersonHand(EnumHand hand, float partialTicks, float interpPitch, float swingProgress, float equipProgress, ItemStack stack)
@@ -249,8 +231,8 @@ public class ForgeHooksClient
return fovUpdateEvent.getNewfov();
}
public static float getFOVModifier(EntityRenderer renderer, Entity entity, IBlockState state, double renderPartialTicks, float fov) {
EntityViewRenderEvent.FOVModifier event = new EntityViewRenderEvent.FOVModifier(renderer, entity, state, renderPartialTicks, fov);
public static double getFOVModifier(EntityRenderer renderer, Entity entity, IBlockState blockState, IFluidState fluidState, double renderPartialTicks, double fov) {
EntityViewRenderEvent.FOVModifier event = new EntityViewRenderEvent.FOVModifier(renderer, entity, blockState, fluidState, renderPartialTicks, fov);
MinecraftForge.EVENT_BUS.post(event);
return event.getFOV();
}
@@ -366,16 +348,16 @@ public class ForgeHooksClient
MinecraftForge.EVENT_BUS.post(new GuiScreenEvent.DrawScreenEvent.Post(screen, mouseX, mouseY, partialTicks));
}
public static float getFogDensity(EntityRenderer renderer, Entity entity, IBlockState state, float partial, float density)
public static float getFogDensity(FogRenderer fogRenderer, EntityRenderer renderer, Entity entity, IBlockState state, IFluidState fluidState, float partial, float density)
{
EntityViewRenderEvent.FogDensity event = new EntityViewRenderEvent.FogDensity(renderer, entity, state, partial, density);
EntityViewRenderEvent.FogDensity event = new EntityViewRenderEvent.FogDensity(fogRenderer, renderer, entity, state, fluidState, partial, density);
if (MinecraftForge.EVENT_BUS.post(event)) return event.getDensity();
return -1;
}
public static void onFogRender(EntityRenderer renderer, Entity entity, IBlockState state, float partial, int mode, float distance)
public static void onFogRender(FogRenderer fogRenderer, EntityRenderer renderer, Entity entity, IBlockState state, IFluidState fluidState, float partial, int mode, float distance)
{
MinecraftForge.EVENT_BUS.post(new EntityViewRenderEvent.RenderFogEvent(renderer, entity, state, partial, mode, distance));
MinecraftForge.EVENT_BUS.post(new EntityViewRenderEvent.RenderFogEvent(fogRenderer, renderer, entity, state, fluidState, partial, mode, distance));
}
public static void onModelBake(ModelManager modelManager, IRegistry<ModelResourceLocation, IBakedModel> modelRegistry, ModelLoader modelLoader)
@@ -562,21 +544,6 @@ public class ForgeHooksClient
}
}
private static Map<Pair<Item, Integer>, Class<? extends TileEntity>> tileItemMap = Maps.newHashMap();
public static void renderTileItem(Item item, int metadata)
{
Class<? extends TileEntity> tileClass = tileItemMap.get(Pair.of(item, metadata));
if (tileClass != null)
{
TileEntityRenderer<?> r = TileEntityRendererDispatcher.instance.getRenderer(tileClass);
if (r != null)
{
r.render(null, 0, 0, 0, 0, -1);
}
}
}
/**
* internal, relies on fixed format of FaceBakery
*/
@@ -21,7 +21,9 @@ package net.minecraftforge.client.event;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.fluid.IFluidState;
import net.minecraftforge.eventbus.api.Cancelable;
import net.minecraftforge.eventbus.api.Event;
@@ -36,13 +38,15 @@ public abstract class EntityViewRenderEvent extends net.minecraftforge.eventbus.
private final EntityRenderer renderer;
private final Entity entity;
private final IBlockState state;
private final IFluidState fluidState;
private final double renderPartialTicks;
public EntityViewRenderEvent(EntityRenderer renderer, Entity entity, IBlockState state, double renderPartialTicks)
public EntityViewRenderEvent(EntityRenderer renderer, Entity entity, IBlockState state, IFluidState fluidState, double renderPartialTicks)
{
this.renderer = renderer;
this.entity = entity;
this.state = state;
this.fluidState = fluidState;
this.renderPartialTicks = renderPartialTicks;
}
@@ -56,28 +60,46 @@ public abstract class EntityViewRenderEvent extends net.minecraftforge.eventbus.
return entity;
}
public IBlockState getState()
public IBlockState getBlockState()
{
return state;
}
public IFluidState getFluidState()
{
return fluidState;
}
public double getRenderPartialTicks()
{
return renderPartialTicks;
}
private static class FogEvent extends EntityViewRenderEvent
{
private final FogRenderer fogRenderer;
protected FogEvent(FogRenderer fogRenderer, EntityRenderer renderer, Entity entity, IBlockState state, IFluidState fluidState, double renderPartialTicks)
{
super(renderer, entity, state, fluidState, renderPartialTicks);
this.fogRenderer = fogRenderer;
}
public FogRenderer getFogRenderer() { return fogRenderer; }
}
/**
* Event that allows any feature to customize the fog density the player sees.
* NOTE: In order to make this event have an effect, you must cancel the event
*/
@Cancelable
public static class FogDensity extends EntityViewRenderEvent
public static class FogDensity extends FogEvent
{
private float density;
public FogDensity(EntityRenderer renderer, Entity entity, IBlockState state, double renderPartialTicks, float density)
public FogDensity(FogRenderer fogRenderer, EntityRenderer renderer, Entity entity, IBlockState state, IFluidState fluidState, double renderPartialTicks, float density)
{
super(renderer, entity, state, renderPartialTicks);
super(fogRenderer, renderer, entity, state, fluidState, renderPartialTicks);
this.setDensity(density);
}
@@ -96,14 +118,14 @@ public abstract class EntityViewRenderEvent extends net.minecraftforge.eventbus.
* Event that allows any feature to customize the rendering of fog.
*/
@HasResult
public static class RenderFogEvent extends EntityViewRenderEvent
public static class RenderFogEvent extends FogEvent
{
private final int fogMode;
private final float farPlaneDistance;
public RenderFogEvent(EntityRenderer renderer, Entity entity, IBlockState state, double renderPartialTicks, int fogMode, float farPlaneDistance)
public RenderFogEvent(FogRenderer fogRenderer, EntityRenderer renderer, Entity entity, IBlockState state, IFluidState fluidState, double renderPartialTicks, int fogMode, float farPlaneDistance)
{
super(renderer, entity, state, renderPartialTicks);
super(fogRenderer, renderer, entity, state, fluidState, renderPartialTicks);
this.fogMode = fogMode;
this.farPlaneDistance = farPlaneDistance;
}
@@ -123,15 +145,15 @@ public abstract class EntityViewRenderEvent extends net.minecraftforge.eventbus.
* Event that allows any feature to customize the color of fog the player sees.
* NOTE: Any change made to one of the color variables will affect the result seen in-game.
*/
public static class FogColors extends EntityViewRenderEvent
{
public static class FogColors extends FogEvent
{
private float red;
private float green;
private float blue;
public FogColors(EntityRenderer renderer, Entity entity, IBlockState state, double renderPartialTicks, float red, float green, float blue)
public FogColors(FogRenderer fogRenderer, EntityRenderer renderer, Entity entity, IBlockState state, IFluidState fluidState, double renderPartialTicks, float red, float green, float blue)
{
super(renderer, entity, state, renderPartialTicks);
super(fogRenderer, renderer, entity, state, fluidState, renderPartialTicks);
this.setRed(red);
this.setGreen(green);
this.setBlue(blue);
@@ -154,9 +176,9 @@ public abstract class EntityViewRenderEvent extends net.minecraftforge.eventbus.
private float pitch;
private float roll;
public CameraSetup(EntityRenderer renderer, Entity entity, IBlockState state, double renderPartialTicks, float yaw, float pitch, float roll)
public CameraSetup(EntityRenderer renderer, Entity entity, IBlockState state, IFluidState fluidState, double renderPartialTicks, float yaw, float pitch, float roll)
{
super(renderer, entity, state, renderPartialTicks);
super(renderer, entity, state, fluidState, renderPartialTicks);
this.setYaw(yaw);
this.setPitch(pitch);
this.setRoll(roll);
@@ -176,18 +198,18 @@ public abstract class EntityViewRenderEvent extends net.minecraftforge.eventbus.
* */
public static class FOVModifier extends EntityViewRenderEvent
{
private float fov;
private double fov;
public FOVModifier(EntityRenderer renderer, Entity entity, IBlockState state, double renderPartialTicks, float fov) {
super(renderer, entity, state, renderPartialTicks);
public FOVModifier(EntityRenderer renderer, Entity entity, IBlockState state, IFluidState fluidState, double renderPartialTicks, double fov) {
super(renderer, entity, state, fluidState, renderPartialTicks);
this.setFOV(fov);
}
public float getFOV() {
public double getFOV() {
return fov;
}
public void setFOV(float fov) {
public void setFOV(double fov) {
this.fov = fov;
}
}
@@ -35,12 +35,10 @@ public class RenderHandEvent extends net.minecraftforge.eventbus.api.Event
{
private final RenderGlobal context;
private final float partialTicks;
private final int renderPass;
public RenderHandEvent(RenderGlobal context, float partialTicks, int renderPass)
public RenderHandEvent(RenderGlobal context, float partialTicks)
{
this.context = context;
this.partialTicks = partialTicks;
this.renderPass = renderPass;
}
public RenderGlobal getContext()
@@ -52,9 +50,4 @@ public class RenderHandEvent extends net.minecraftforge.eventbus.api.Event
{
return partialTicks;
}
public int getRenderPass()
{
return renderPass;
}
}
@@ -0,0 +1,24 @@
package net.minecraftforge.client.extensions;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
public interface IForgeBakedModel
{
default IBakedModel getBakedModel()
{
return (IBakedModel) this;
}
default boolean isAmbientOcclusion(IBlockState state) { return getBakedModel().isAmbientOcclusion(); }
/*
* Returns the pair of the model for the given perspective, and the matrix that
* should be applied to the GL state before rendering it (matrix may be null).
*/
default org.apache.commons.lang3.tuple.Pair<? extends IBakedModel, javax.vecmath.Matrix4f> handlePerspective(ItemCameraTransforms.TransformType cameraTransformType)
{
return net.minecraftforge.client.ForgeHooksClient.handlePerspective(getBakedModel(), cameraTransformType);
}
}
@@ -0,0 +1,26 @@
package net.minecraftforge.client.extensions;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ChunkCache;
import net.minecraft.world.World;
public interface IForgeRenderChunk
{
/**
* Creates a new RegionRenderCache instance.<br>
* Extending classes can change the behavior of the cache, allowing to visually change
* blocks (schematics etc).
*
* @see RegionRenderCache
* @param world The world to cache.
* @param from The starting position of the chunk minus one on each axis.
* @param to The ending position of the chunk plus one on each axis.
* @param subtract Padding used internally by the RegionRenderCache constructor to make
* the cache a 20x20x20 cube, for a total of 8000 states in the cache.
* @return new RegionRenderCache instance
*/
default ChunkCache createRegionRenderCache(World world, BlockPos from, BlockPos to, int subtract)
{
return new ChunkCache(world, from, to, subtract);
}
}
@@ -0,0 +1,46 @@
package net.minecraftforge.client.extensions;
import java.util.Collection;
import java.util.function.Function;
import com.google.common.collect.ImmutableList;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
public interface IForgeTextureAtlasSprite
{
/**
* The result of this function determines is the below 'load' function is called, and the
* default vanilla loading code is bypassed completely.
* @param manager Main resource manager
* @param location File resource location
* @return True to use your own custom load code and bypass vanilla loading.
*/
default boolean hasCustomLoader(IResourceManager manager, ResourceLocation location)
{
return false;
}
/**
* Load the specified resource as this sprite's data.
* Returning false from this function will prevent this icon from being stitched onto the master texture.
* @param manager Main resource manager
* @param location File resource location
* @param textureGetter accessor for dependencies. All of them will be loaded before this one
* @return False to prevent this Icon from being stitched
*/
default boolean load(IResourceManager manager, ResourceLocation location, Function<ResourceLocation, TextureAtlasSprite> textureGetter)
{
return true;
}
/**
* @return all textures that should be loaded before this texture.
*/
default Collection<ResourceLocation> getDependencies()
{
return ImmutableList.of();
}
}
@@ -305,14 +305,14 @@ public final class ModelDynBucket implements IUnbakedModel
if (getResource(new ResourceLocation(ForgeVersion.MOD_ID, "textures/items/bucket_cover.png")) == null)
{
ResourceLocation bucketCover = new ResourceLocation(ForgeVersion.MOD_ID, "items/bucket_cover");
BucketCoverSprite bucketCoverSprite = new BucketCoverSprite(getResource(bucketCover));
BucketCoverSprite bucketCoverSprite = new BucketCoverSprite(bucketCover);
// map.setTextureEntry(bucketCoverSprite);
}
if (getResource(new ResourceLocation(ForgeVersion.MOD_ID, "textures/items/bucket_base.png")) == null)
{
ResourceLocation bucketBase = new ResourceLocation(ForgeVersion.MOD_ID, "items/bucket_base");
BucketBaseSprite bucketBaseSprite = new BucketBaseSprite(getResource(bucketBase));
BucketBaseSprite bucketBaseSprite = new BucketBaseSprite(bucketBase);
// map.setTextureEntry(bucketBaseSprite);
}
}
@@ -320,12 +320,12 @@ public final class ModelDynBucket implements IUnbakedModel
private static final class BucketBaseSprite extends TextureAtlasSprite
{
private final ResourceLocation bucket = new ResourceLocation("items/bucket_empty");
private final ResourceLocation bucket = new ResourceLocation("item/bucket");
private final ImmutableList<ResourceLocation> dependencies = ImmutableList.of(bucket);
private BucketBaseSprite(IResource resource)
private BucketBaseSprite(ResourceLocation res)
{
super(resource.getLocation(), getSizeInfo(resource), resource.getMetadata(AnimationMetadataSection.SERIALIZER));
super(res, getSizeInfo(getResource(new ResourceLocation("textures/item/bucket.png"))), getResource(new ResourceLocation("textures/item/bucket.png")).getMetadata(AnimationMetadataSection.SERIALIZER));
}
/* TODO Custom TAS
@@ -361,13 +361,13 @@ public final class ModelDynBucket implements IUnbakedModel
*/
private static final class BucketCoverSprite extends TextureAtlasSprite
{
private final ResourceLocation bucket = new ResourceLocation("items/bucket_empty");
private final ResourceLocation bucketCoverMask = new ResourceLocation(ForgeVersion.MOD_ID, "items/vanilla_bucket_cover_mask");
private final ResourceLocation bucket = new ResourceLocation("item/bucket");
private final ResourceLocation bucketCoverMask = new ResourceLocation(ForgeVersion.MOD_ID, "item/vanilla_bucket_cover_mask");
private final ImmutableList<ResourceLocation> dependencies = ImmutableList.of(bucket, bucketCoverMask);
private BucketCoverSprite(IResource resource)
private BucketCoverSprite(ResourceLocation res)
{
super(resource.getLocation(), getSizeInfo(resource), resource.getMetadata(AnimationMetadataSection.SERIALIZER));
super(res, getSizeInfo(getResource(new ResourceLocation("textures/item/bucket.png"))), getResource(new ResourceLocation("textures/item/bucket.png")).getMetadata(AnimationMetadataSection.SERIALIZER));
}
/* TODO Custom TAS
@@ -1009,8 +1009,7 @@ public final class ModelLoader extends ModelBakery
shapes.registerBlockWithStateMapper(e.getKey().get(), e.getValue());
}
}
private static final Map<IRegistryDelegate<Item>, ItemMeshDefinition> customMeshDefinitions = com.google.common.collect.Maps.newHashMap();
*/
private static final Map<Pair<IRegistryDelegate<Item>, Integer>, ModelResourceLocation> customModels = com.google.common.collect.Maps.newHashMap();
/**
@@ -1039,10 +1038,10 @@ public final class ModelLoader extends ModelBakery
ModelLoader.setCustomMeshDefinition(item, stack -> ModelDynBucket.LOCATION);
ModelBakery.registerItemVariants(item, ModelDynBucket.LOCATION);
}
*/
/**
* Internal, do not use.
*//*
*/
public static void onRegisterItems(ItemModelMesher mesher)
{
for (Entry<Pair<IRegistryDelegate<Item>, Integer>, ModelResourceLocation> e : customModels.entrySet())
@@ -1050,7 +1049,7 @@ public final class ModelLoader extends ModelBakery
mesher.register(e.getKey().getLeft().get(), e.getValue());
}
}
*/
private static enum DefaultTextureGetter implements Function<ResourceLocation, TextureAtlasSprite>
{
INSTANCE;
@@ -167,7 +167,7 @@ public class VertexLighterFlat extends QuadGatheringTransformer
float y = position[v][1] - .5f;
float z = position[v][2] - .5f;
//if(blockInfo.getBlock().isFullCube())
// if(blockInfo.getState().getBlock().isFullCube(blockInfo.getState()))
{
x += normal[v][0] * .5f;
y += normal[v][1] * .5f;
@@ -24,11 +24,21 @@ import java.util.function.Predicate;
import javax.annotation.Nullable;
import net.minecraft.block.*;
import net.minecraft.block.Block;
import net.minecraft.block.BlockBed;
import net.minecraft.block.BlockFarmland;
import net.minecraft.block.BlockFence;
import net.minecraft.block.BlockFire;
import net.minecraft.block.BlockHorizontal;
import net.minecraft.block.BlockStainedGlass;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.BlockFaceShape;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.particle.ParticleManager;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
@@ -51,8 +61,12 @@ import net.minecraft.state.IProperty;
import net.minecraft.state.properties.BedPart;
import net.minecraft.tags.BlockTags;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.*;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
@@ -67,7 +81,6 @@ import net.minecraft.world.WorldServer;
import net.minecraft.world.dimension.EndDimension;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.EnumPlantType;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.common.IPlantable;
import net.minecraftforge.common.ToolType;
@@ -260,7 +273,7 @@ public interface IForgeBlock
* @param player The player or camera entity, null in some cases.
* @return True to treat this as a bed
*/
default boolean isBed(IBlockState state, IBlockReader world, BlockPos pos, @Nullable EntityPlayer player)
default boolean isBed(IBlockState state, IBlockReader world, BlockPos pos, @Nullable Entity player)
{
return this.getBlock() instanceof BlockBed; //TODO: Forge: Keep isBed function?
}
@@ -780,7 +793,7 @@ public interface IForgeBlock
/**
* Queries if this block should render in a given layer.
* ISmartBlockModel can use {@link net.minecraftforge.client.MinecraftForgeClient#getRenderLayer()} to alter their model based on layer.
* A custom {@link IBakedModel} can use {@link net.minecraftforge.client.MinecraftForgeClient#getRenderLayer()} to alter the model based on layer.
*/
default boolean canRenderInLayer(IBlockState state, BlockRenderLayer layer)
{
@@ -861,7 +874,7 @@ public interface IForgeBlock
* @param viewpoint the viewpoint
* @return the block state that should be 'seen'
*/
default IBlockState getStateAtViewpoint(IBlockState state, IWorldReader world, BlockPos pos, Vec3d viewpoint)
default IBlockState getStateAtViewpoint(IBlockState state, IBlockReader world, BlockPos pos, Vec3d viewpoint)
{
return state;
}
@@ -26,6 +26,7 @@ import javax.annotation.Nullable;
import net.minecraft.block.*;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.particle.ParticleManager;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
@@ -680,8 +681,8 @@ public interface IForgeBlockState
}
/**
* Queries if this block should render in a given layer.
* ISmartBlockModel can use {@link net.minecraftforge.client.MinecraftForgeClient#getRenderLayer()} to alter their model based on layer.
* Queries if this blockstate should render in a given layer.
* A custom {@link IBakedModel} can use {@link net.minecraftforge.client.MinecraftForgeClient#getRenderLayer()} to alter the model based on layer.
*/
default boolean canRenderInLayer(BlockRenderLayer layer)
{
@@ -111,6 +111,20 @@ public interface IForgeDimension
@OnlyIn(Dist.CLIENT)
void setWeatherRenderer(IRenderHandler renderer);
/**
* Allows for manipulating the coloring of the lightmap texture.
* Will be called for each 16*16 combination of sky/block light values.
*
* @param partialTicks Progress between ticks.
* @param sunBrightness Current sun brightness.
* @param skyLight Sky light brightness factor.
* @param blockLight Block light brightness factor.
* @param colors The color values that will be used: [r, g, b].
*
* @see net.minecraft.client.renderer.EntityRenderer#updateLightmap(float)
*/
default void getLightmapColors(float partialTicks, float sunBrightness, float skyLight, float blockLight, float[] colors) {}
void resetRainAndThunder();
@@ -22,11 +22,12 @@ package net.minecraftforge.common.extensions;
import javax.annotation.Nullable;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.entity.Entity;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.IFluidState;
import net.minecraft.tags.Tag;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.Explosion;
@@ -98,4 +99,13 @@ public interface IForgeFluid
{
return state.getExplosionResistance();
}
/**
* Queries if this fluid should render in a given layer.
* A custom {@link IBakedModel} can use {@link net.minecraftforge.client.MinecraftForgeClient#getRenderLayer()} to alter the model based on layer.
*/
default boolean canRenderInLayer(IFluidState state, BlockRenderLayer layer)
{
return this.getFluid().getRenderLayer() == layer;
}
}
@@ -21,10 +21,12 @@ package net.minecraftforge.common.extensions;
import javax.annotation.Nullable;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.entity.Entity;
import net.minecraft.fluid.Fluid;
import net.minecraft.fluid.IFluidState;
import net.minecraft.tags.Tag;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.Explosion;
import net.minecraft.world.IWorldReader;
@@ -67,4 +69,13 @@ public interface IForgeFluidState
{
return getFluidState().getFluid().getExplosionResistance(getFluidState(), world, pos, exploder, explosion);
}
/**
* Queries if this fluidstate should render in a given layer.
* A custom {@link IBakedModel} can use {@link net.minecraftforge.client.MinecraftForgeClient#getRenderLayer()} to alter the model based on layer.
*/
default boolean canRenderInLayer(BlockRenderLayer layer)
{
return getFluidState().getFluid().canRenderInLayer(getFluidState(), layer);
}
}
@@ -19,8 +19,16 @@
package net.minecraftforge.common.extensions;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
public interface IForgeTileEntity extends ICapabilitySerializable<NBTTagCompound>
@@ -78,5 +86,86 @@ public interface IForgeTileEntity extends ICapabilitySerializable<NBTTagCompound
* Called when this is first added to the world (by {@link World#addTileEntity(TileEntity)}).
* Override instead of adding {@code if (firstTick)} stuff in update.
*/
default void onLoad(){}
default void onLoad(){}
default boolean shouldRenderInPass(int pass)
{
return pass == 0;
}
/**
* Sometimes default render bounding box: infinite in scope. Used to control rendering on {@link TileEntitySpecialRenderer}.
*/
public static final AxisAlignedBB INFINITE_EXTENT_AABB = new net.minecraft.util.math.AxisAlignedBB(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
/**
* Return an {@link AxisAlignedBB} that controls the visible scope of a {@link TileEntitySpecialRenderer} associated with this {@link TileEntity}
* Defaults to the collision bounding box {@link Block#getCollisionBoundingBoxFromPool(World, int, int, int)} associated with the block
* at this location.
*
* @return an appropriately size {@link AxisAlignedBB} for the {@link TileEntity}
*/
@OnlyIn(Dist.CLIENT)
default AxisAlignedBB getRenderBoundingBox()
{
AxisAlignedBB bb = INFINITE_EXTENT_AABB;
IBlockState state = getTileEntity().getBlockState();
Block block = state.getBlock();
BlockPos pos = getTileEntity().getPos();
if (block == Blocks.ENCHANTING_TABLE)
{
bb = new AxisAlignedBB(pos, pos.add(1, 1, 1));
}
else if (block == Blocks.CHEST || block == Blocks.TRAPPED_CHEST)
{
bb = new AxisAlignedBB(pos.add(-1, 0, -1), pos.add(2, 2, 2));
}
else if (block == Blocks.STRUCTURE_BLOCK)
{
bb = INFINITE_EXTENT_AABB;
}
else if (block != null && block != Blocks.BEACON)
{
AxisAlignedBB cbb = null;
try
{
cbb = state.getCollisionShape(getTileEntity().getWorld(), pos).getBoundingBox().offset(pos);
}
catch (Exception e)
{
// We have to capture any exceptions that may occur here because BUKKIT servers like to send
// the tile entity data BEFORE the chunk data, you know, the OPPOSITE of what vanilla does!
// So we can not GARENTEE that the world state is the real state for the block...
// So, once again in the long line of US having to accommodate BUKKIT breaking things,
// here it is, assume that the TE is only 1 cubic block. Problem with this is that it may
// cause the TileEntity renderer to error further down the line! But alas, nothing we can do.
cbb = new net.minecraft.util.math.AxisAlignedBB(pos.add(-1, 0, -1), pos.add(1, 1, 1));
}
if (cbb != null) bb = cbb;
}
return bb;
}
/**
* Checks if this tile entity knows how to render its 'breaking' overlay effect.
* If this returns true, The TileEntitySpecialRenderer will be called again with break progress set.
* @return True to re-render tile with breaking effect.
*/
default boolean canRenderBreaking()
{
Block block = getTileEntity().getBlockState().getBlock();
return (block instanceof net.minecraft.block.BlockChest ||
block instanceof net.minecraft.block.BlockEnderChest ||
block instanceof net.minecraft.block.BlockSign ||
block instanceof net.minecraft.block.BlockSkull);
}
/**
* If the TileEntitySpecialRenderer associated with this TileEntity can be batched in with another renderers, and won't access the GL state.
* If TileEntity returns true, then TESR should have the same functionality as (and probably extend) the FastTESR class.
*/
default boolean hasFastRenderer()
{
return false;
}
}
@@ -19,12 +19,32 @@
package net.minecraftforge.fml.client;
import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
import com.google.common.base.CharMatcher;
import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import com.google.common.collect.Table;
import com.google.gson.JsonObject;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiConnecting;
@@ -35,23 +55,16 @@ import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.ServerStatusResponse;
import net.minecraft.resources.AbstractResourcePack;
import net.minecraft.resources.FallbackResourceManager;
import net.minecraft.resources.IResourcePack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.storage.WorldSummary;
import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fml.StartupQuery;
import net.minecraftforge.fml.client.gui.GuiAccessDenied;
import net.minecraftforge.fml.language.IModInfo;
import net.minecraftforge.fml.packs.ModFileResourcePack;
import net.minecraftforge.registries.GameData;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
import javax.annotation.Nullable;
import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
public class ClientHooks
{
@@ -220,4 +233,103 @@ public class ClientHooks
// We can't handle many unicode points in the splash renderer
return DISALLOWED_CHAR_MATCHER.removeFrom(net.minecraft.util.StringUtils.stripControlCodes(message));
}
private static SetMultimap<String,ResourceLocation> missingTextures = HashMultimap.create();
private static Set<String> badTextureDomains = Sets.newHashSet();
private static Table<String, String, Set<ResourceLocation>> brokenTextures = HashBasedTable.create();
public static void trackMissingTexture(ResourceLocation resourceLocation)
{
badTextureDomains.add(resourceLocation.getNamespace());
missingTextures.put(resourceLocation.getNamespace(),resourceLocation);
}
public static void trackBrokenTexture(ResourceLocation resourceLocation, String error)
{
badTextureDomains.add(resourceLocation.getNamespace());
Set<ResourceLocation> badType = brokenTextures.get(resourceLocation.getNamespace(), error);
if (badType == null)
{
badType = Sets.newHashSet();
brokenTextures.put(resourceLocation.getNamespace(), MoreObjects.firstNonNull(error, "Unknown error"), badType);
}
badType.add(resourceLocation);
}
public static void logMissingTextureErrors()
{
if (missingTextures.isEmpty() && brokenTextures.isEmpty())
{
return;
}
Logger logger = LogManager.getLogger("FML.TEXTURE_ERRORS");
logger.error(Strings.repeat("+=", 25));
logger.error("The following texture errors were found.");
Map<String,FallbackResourceManager> resManagers = null;// TODO ObfuscationReflectionHelper.getPrivateValue(SimpleReloadableResourceManager.class, (SimpleReloadableResourceManager)Minecraft.getMinecraft().getResourceManager(), "field_110548"+"_a");
for (String resourceDomain : badTextureDomains)
{
Set<ResourceLocation> missing = missingTextures.get(resourceDomain);
logger.error(Strings.repeat("=", 50));
logger.error(" DOMAIN {}", resourceDomain);
logger.error(Strings.repeat("-", 50));
logger.error(" domain {} is missing {} texture{}",resourceDomain, missing.size(),missing.size()!=1 ? "s" : "");
FallbackResourceManager fallbackResourceManager = resManagers.get(resourceDomain);
if (fallbackResourceManager == null)
{
logger.error(" domain {} is missing a resource manager - it is probably a side-effect of automatic texture processing", resourceDomain);
}
else
{
List<IResourcePack> resPacks = null;//ObfuscationReflectionHelper.getPrivateValue(FallbackResourceManager.class, fallbackResourceManager, "field_110540"+"_a");
logger.error(" domain {} has {} location{}:",resourceDomain, resPacks.size(), resPacks.size() != 1 ? "s" :"");
for (IResourcePack resPack : resPacks)
{
if (resPack instanceof ModFileResourcePack) {
ModFileResourcePack modRP = (ModFileResourcePack) resPack;
List<IModInfo> mods = modRP.getModFile().getModInfos();
logger.error(" mod(s) {} resources at {}", mods.stream().map(IModInfo::getDisplayName).collect(Collectors.toList()), modRP.getModFile().getFilePath());
}
else if (resPack instanceof AbstractResourcePack)
{
AbstractResourcePack resourcePack = (AbstractResourcePack) resPack;
File resPath = null;// TODO bfuscationReflectionHelper.getPrivateValue(AbstractResourcePack.class, resourcePack, "field_110597"+"_b");
logger.error(" resource pack at path {}",resPath.getPath());
}
else
{
logger.error(" unknown resourcepack type {} : {}", resPack.getClass().getName(), resPack.getName());
}
}
}
logger.error(Strings.repeat("-", 25));
if (missingTextures.containsKey(resourceDomain)) {
logger.error(" The missing resources for domain {} are:", resourceDomain);
for (ResourceLocation rl : missing) {
logger.error(" {}", rl.getPath());
}
logger.error(Strings.repeat("-", 25));
}
if (!brokenTextures.containsRow(resourceDomain))
{
logger.error(" No other errors exist for domain {}", resourceDomain);
}
else
{
logger.error(" The following other errors were reported for domain {}:",resourceDomain);
Map<String, Set<ResourceLocation>> resourceErrs = brokenTextures.row(resourceDomain);
for (String error: resourceErrs.keySet())
{
logger.error(Strings.repeat("-", 25));
logger.error(" Problem: {}", error);
for (ResourceLocation rl : resourceErrs.get(error))
{
logger.error(" {}",rl.getPath());
}
}
}
logger.error(Strings.repeat("=", 50));
}
logger.error(Strings.repeat("+=", 25));
}
}
@@ -78,6 +78,8 @@ public class ClientModLoader
GlStateManager.enableTexture2D();
if (error != null) {
mc.displayGuiScreen(new LoadingErrorScreen(error));
} else {
ClientHooks.logMissingTextureErrors();
}
}
@@ -60,7 +60,7 @@ public enum SelectiveReloadStateHandler
*/
public Predicate<IResourceType> get()
{
if (this.currentPredicate == null && false) // TODO configs || !ForgeMod.selectiveResourceReloadEnabled)
if (this.currentPredicate == null || true) // TODO configs || !ForgeMod.selectiveResourceReloadEnabled)
{
return ReloadRequirements.all();
}