Improve the Forge Bucket (#4435)

This commit is contained in:
mezz authored and LexManos committed 2017-10-31 11:03:44 -07:00
1 parent 48320b315f
commit b5e88dd07b
13 files changed
+372 -199

No files matched your search

@@ -103,6 +103,7 @@ import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.client.event.ScreenshotEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.client.event.sound.PlaySoundEvent;
import net.minecraftforge.client.model.ModelDynBucket;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.animation.Animation;
import net.minecraftforge.common.ForgeModContainer;
@@ -174,6 +175,7 @@ public class ForgeHooksClient
{
MinecraftForge.EVENT_BUS.post(new TextureStitchEvent.Pre(map));
ModelLoader.White.INSTANCE.register(map);
ModelDynBucket.LoaderDynBucket.INSTANCE.register(map);
}
public static void onTextureStitchedPost(TextureMap map)
@@ -0,0 +1,119 @@
/*
* Minecraft Forge
* Copyright (c) 2016.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.client.model;
import javax.annotation.Nullable;
import javax.vecmath.Matrix4f;
import java.util.List;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType;
import net.minecraft.client.renderer.block.model.ItemOverrideList;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.model.TRSRTransformation;
import org.apache.commons.lang3.tuple.Pair;
public class BakedItemModel implements IBakedModel
{
protected final ImmutableList<BakedQuad> quads;
protected final TextureAtlasSprite particle;
protected final ImmutableMap<TransformType, TRSRTransformation> transforms;
protected final ItemOverrideList overrides;
protected final IBakedModel guiModel;
public BakedItemModel(ImmutableList<BakedQuad> quads, TextureAtlasSprite particle, ImmutableMap<TransformType, TRSRTransformation> transforms, ItemOverrideList overrides)
{
this.quads = quads;
this.particle = particle;
this.transforms = transforms;
this.overrides = overrides;
this.guiModel = new BakedGuiItemModel<>(this);
}
@Override public boolean isAmbientOcclusion() { return true; }
@Override public boolean isGui3d() { return false; }
@Override public boolean isBuiltInRenderer() { return false; }
@Override public TextureAtlasSprite getParticleTexture() { return particle; }
@Override public ItemOverrideList getOverrides() { return overrides; }
@Override
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand)
{
if (side == null)
{
return quads;
}
return ImmutableList.of();
}
@Override
public Pair<? extends IBakedModel, Matrix4f> handlePerspective(TransformType type)
{
if (type == TransformType.GUI)
{
return this.guiModel.handlePerspective(type);
}
return PerspectiveMapWrapper.handlePerspective(this, transforms, type);
}
public static class BakedGuiItemModel<T extends BakedItemModel> extends BakedModelWrapper<T>
{
private final ImmutableList<BakedQuad> quads;
public BakedGuiItemModel(T originalModel)
{
super(originalModel);
ImmutableList.Builder<BakedQuad> builder = ImmutableList.builder();
for (BakedQuad quad : originalModel.quads)
{
if (quad.getFace() == EnumFacing.SOUTH)
{
builder.add(quad);
}
}
this.quads = builder.build();
}
@Override
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand)
{
if(side == null)
{
return quads;
}
return ImmutableList.of();
}
@Override
public Pair<? extends IBakedModel, Matrix4f> handlePerspective(TransformType type)
{
if (type == TransformType.GUI)
{
return PerspectiveMapWrapper.handlePerspective(this, originalModel.transforms, type);
}
return this.originalModel.handlePerspective(type);
}
}
}
@@ -0,0 +1,90 @@
/*
* Minecraft Forge
* Copyright (c) 2016.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package net.minecraftforge.client.model;
import javax.annotation.Nullable;
import javax.vecmath.Matrix4f;
import java.util.List;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
import net.minecraft.client.renderer.block.model.ItemOverrideList;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.EnumFacing;
import org.apache.commons.lang3.tuple.Pair;
public abstract class BakedModelWrapper<T extends IBakedModel> implements IBakedModel
{
protected final T originalModel;
public BakedModelWrapper(T originalModel)
{
this.originalModel = originalModel;
}
@Override
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand)
{
return originalModel.getQuads(state, side, rand);
}
@Override
public boolean isAmbientOcclusion()
{
return originalModel.isAmbientOcclusion();
}
@Override
public boolean isGui3d()
{
return originalModel.isGui3d();
}
@Override
public boolean isBuiltInRenderer()
{
return originalModel.isBuiltInRenderer();
}
@Override
public TextureAtlasSprite getParticleTexture()
{
return originalModel.getParticleTexture();
}
@Override
public ItemCameraTransforms getItemCameraTransforms()
{
return originalModel.getItemCameraTransforms();
}
@Override
public ItemOverrideList getOverrides()
{
return originalModel.getOverrides();
}
@Override
public Pair<? extends IBakedModel, Matrix4f> handlePerspective(ItemCameraTransforms.TransformType cameraTransformType)
{
return originalModel.handlePerspective(cameraTransformType);
}
}
@@ -19,14 +19,10 @@
package net.minecraftforge.client.model;
import javax.annotation.Nullable;
import javax.vecmath.Matrix4f;
import javax.vecmath.Vector4f;
import net.minecraftforge.common.ForgeVersion;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType;
@@ -45,7 +41,6 @@ import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.EnumMap;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
@@ -122,69 +117,7 @@ public final class ItemLayerModel implements IModel
}
TextureAtlasSprite particle = bakedTextureGetter.apply(textures.isEmpty() ? new ResourceLocation("missingno") : textures.get(0));
ImmutableMap<TransformType, TRSRTransformation> map = PerspectiveMapWrapper.getTransforms(state);
return new BakedItemModel(builder.build(), particle, map, overrides, null);
}
private static final class BakedItemModel implements IBakedModel
{
private final ImmutableList<BakedQuad> quads;
private final TextureAtlasSprite particle;
private final ImmutableMap<TransformType, TRSRTransformation> transforms;
private final IBakedModel otherModel;
private final boolean isCulled;
private final ItemOverrideList overrides;
public BakedItemModel(ImmutableList<BakedQuad> quads, TextureAtlasSprite particle, ImmutableMap<TransformType, TRSRTransformation> transforms, ItemOverrideList overrides, @Nullable IBakedModel otherModel)
{
this.quads = quads;
this.particle = particle;
this.transforms = transforms;
this.overrides = overrides;
if(otherModel != null)
{
this.otherModel = otherModel;
this.isCulled = true;
}
else
{
ImmutableList.Builder<BakedQuad> builder = ImmutableList.builder();
for(BakedQuad quad : quads)
{
if(quad.getFace() == EnumFacing.SOUTH)
{
builder.add(quad);
}
}
this.otherModel = new BakedItemModel(builder.build(), particle, transforms, overrides, this);
isCulled = false;
}
}
public boolean isAmbientOcclusion() { return true; }
public boolean isGui3d() { return false; }
public boolean isBuiltInRenderer() { return false; }
public TextureAtlasSprite getParticleTexture() { return particle; }
public ItemOverrideList getOverrides() { return overrides; }
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand)
{
if(side == null) return quads;
return ImmutableList.of();
}
@Override
public Pair<? extends IBakedModel, Matrix4f> handlePerspective(TransformType type)
{
Pair<? extends IBakedModel, Matrix4f> pair = PerspectiveMapWrapper.handlePerspective(this, transforms, type);
if(type == TransformType.GUI && !isCulled && pair.getRight() == null)
{
return Pair.of(otherModel, null);
}
else if(type != TransformType.GUI && isCulled)
{
return Pair.of(otherModel, pair.getRight());
}
return pair;
}
return new BakedItemModel(builder.build(), particle, map, overrides);
}
public static ImmutableList<BakedQuad> getQuadsForSprite(int tint, TextureAtlasSprite sprite, VertexFormat format, Optional<TRSRTransformation> transform)
@@ -239,13 +239,12 @@ public final class ItemTextureQuadConverter
float x1, float y1, float x2, float y2, float z,
float u1, float v1, float u2, float v2)
{
side = side.getOpposite();
UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder(format);
builder.setQuadTint(-1);
builder.setQuadOrientation(side);
builder.setTexture(sprite);
if (side == EnumFacing.NORTH)
if (side == EnumFacing.SOUTH)
{
putVertex(builder, format, transform, side, x1, y1, z, u1, v2, color);
putVertex(builder, format, transform, side, x2, y1, z, u2, v2, color);
@@ -19,25 +19,24 @@
package net.minecraftforge.client.model;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.vecmath.Matrix4f;
import javax.vecmath.Quat4f;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType;
import net.minecraft.client.renderer.block.model.ItemOverride;
import net.minecraft.client.renderer.block.model.ItemOverrideList;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.resources.IResource;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
@@ -45,7 +44,6 @@ import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeVersion;
import net.minecraftforge.common.model.IModelPart;
import net.minecraftforge.common.model.IModelState;
import net.minecraftforge.common.model.TRSRTransformation;
import net.minecraftforge.fluids.Fluid;
@@ -53,10 +51,12 @@ import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil;
import org.apache.commons.lang3.tuple.Pair;
import java.util.Objects;
import java.util.function.Function;
import java.util.Optional;
import static net.minecraftforge.client.model.ModelDynBucket.LoaderDynBucket.getResource;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
@@ -67,8 +67,8 @@ public final class ModelDynBucket implements IModel
public static final ModelResourceLocation LOCATION = new ModelResourceLocation(new ResourceLocation(ForgeVersion.MOD_ID, "dynbucket"), "inventory");
// minimal Z offset to prevent depth-fighting
private static final float NORTH_Z_BASE = 7.496f / 16f;
private static final float SOUTH_Z_BASE = 8.504f / 16f;
private static final float NORTH_Z_COVER = 7.496f / 16f;
private static final float SOUTH_Z_COVER = 8.504f / 16f;
private static final float NORTH_Z_FLUID = 7.498f / 16f;
private static final float SOUTH_Z_FLUID = 8.502f / 16f;
@@ -127,6 +127,7 @@ public final class ModelDynBucket implements IModel
TRSRTransformation transform = state.apply(Optional.empty()).orElse(TRSRTransformation.identity());
TextureAtlasSprite fluidSprite = null;
TextureAtlasSprite particleSprite = null;
ImmutableList.Builder<BakedQuad> builder = ImmutableList.builder();
if(fluid != null) {
@@ -138,6 +139,7 @@ public final class ModelDynBucket implements IModel
// build base (insidest)
IBakedModel model = (new ItemLayerModel(ImmutableList.of(baseLocation))).bake(state, format, bakedTextureGetter);
builder.addAll(model.getQuads(null, null, 0));
particleSprite = model.getParticleTexture();
}
if (liquidLocation != null && fluidSprite != null)
{
@@ -145,17 +147,21 @@ public final class ModelDynBucket implements IModel
// build liquid layer (inside)
builder.addAll(ItemTextureQuadConverter.convertTexture(format, transform, liquid, fluidSprite, NORTH_Z_FLUID, EnumFacing.NORTH, fluid.getColor()));
builder.addAll(ItemTextureQuadConverter.convertTexture(format, transform, liquid, fluidSprite, SOUTH_Z_FLUID, EnumFacing.SOUTH, fluid.getColor()));
particleSprite = fluidSprite;
}
if (coverLocation != null)
{
// cover (the actual item around the other two)
TextureAtlasSprite base = bakedTextureGetter.apply(coverLocation);
builder.add(ItemTextureQuadConverter.genQuad(format, transform, 0, 0, 16, 16, NORTH_Z_BASE, base, EnumFacing.NORTH, 0xffffffff));
builder.add(ItemTextureQuadConverter.genQuad(format, transform, 0, 0, 16, 16, SOUTH_Z_BASE, base, EnumFacing.SOUTH, 0xffffffff));
TextureAtlasSprite cover = bakedTextureGetter.apply(coverLocation);
builder.add(ItemTextureQuadConverter.genQuad(format, transform, 0, 0, 16, 16, NORTH_Z_COVER, cover, EnumFacing.NORTH, 0xffffffff));
builder.add(ItemTextureQuadConverter.genQuad(format, transform, 0, 0, 16, 16, SOUTH_Z_COVER, cover, EnumFacing.SOUTH, 0xffffffff));
if (particleSprite == null)
{
particleSprite = cover;
}
}
return new BakedDynBucket(this, builder.build(), fluidSprite, format, Maps.immutableEnumMap(transformMap), Maps.newHashMap());
return new BakedDynBucket(this, builder.build(), particleSprite, format, Maps.immutableEnumMap(transformMap), Maps.newHashMap());
}
/**
@@ -235,6 +241,135 @@ public final class ModelDynBucket implements IModel
{
// no need to clear cache since we create a new model instance
}
public void register(TextureMap map)
{
// only create these textures if they are not added by a resource pack
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(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(bucketBase);
map.setTextureEntry(bucketBaseSprite);
}
}
@Nullable
protected static IResource getResource(ResourceLocation resourceLocation)
{
try
{
return Minecraft.getMinecraft().getResourceManager().getResource(resourceLocation);
}
catch (IOException ignored)
{
return null;
}
}
}
private static final class BucketBaseSprite extends TextureAtlasSprite
{
private final ResourceLocation bucket = new ResourceLocation("items/bucket_empty");
private final ImmutableList<ResourceLocation> dependencies = ImmutableList.of(bucket);
private BucketBaseSprite(ResourceLocation resourceLocation)
{
super(resourceLocation.toString());
}
@Override
public boolean hasCustomLoader(@Nonnull IResourceManager manager, @Nonnull ResourceLocation location)
{
return true;
}
@Override
public Collection<ResourceLocation> getDependencies()
{
return dependencies;
}
@Override
public boolean load(@Nonnull IResourceManager manager, @Nonnull ResourceLocation location, @Nonnull Function<ResourceLocation, TextureAtlasSprite> textureGetter)
{
final TextureAtlasSprite sprite = textureGetter.apply(bucket);
width = sprite.getIconWidth();
height = sprite.getIconHeight();
final int[][] pixels = sprite.getFrameTextureData(0);
this.clearFramesTextureData();
this.framesTextureData.add(pixels);
return false;
}
}
/**
* Creates a bucket cover sprite from the vanilla resource.
*/
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 ImmutableList<ResourceLocation> dependencies = ImmutableList.of(bucket, bucketCoverMask);
private BucketCoverSprite(ResourceLocation resourceLocation)
{
super(resourceLocation.toString());
}
@Override
public boolean hasCustomLoader(@Nonnull IResourceManager manager, @Nonnull ResourceLocation location)
{
return true;
}
@Override
public Collection<ResourceLocation> getDependencies()
{
return dependencies;
}
@Override
public boolean load(@Nonnull IResourceManager manager, @Nonnull ResourceLocation location, @Nonnull Function<ResourceLocation, TextureAtlasSprite> textureGetter)
{
final TextureAtlasSprite sprite = textureGetter.apply(bucket);
final TextureAtlasSprite alphaMask = textureGetter.apply(bucketCoverMask);
width = sprite.getIconWidth();
height = sprite.getIconHeight();
final int[][] pixels = new int[Minecraft.getMinecraft().gameSettings.mipmapLevels + 1][];
pixels[0] = new int[width * height];
IResource empty = getResource(new ResourceLocation("textures/items/bucket_empty.png"));
IResource mask = getResource(new ResourceLocation(ForgeVersion.MOD_ID, "textures/items/vanilla_bucket_cover_mask.png"));
// use the alpha mask if it fits, otherwise leave the cover texture blank
if (empty != null && mask != null && Objects.equals(empty.getResourcePackName(), mask.getResourcePackName()) &&
alphaMask.getIconWidth() == width && alphaMask.getIconHeight() == height)
{
final int[][] oldPixels = sprite.getFrameTextureData(0);
final int[][] alphaPixels = alphaMask.getFrameTextureData(0);
for (int p = 0; p < width * height; p++)
{
final int alphaMultiplier = alphaPixels[0][p] >>> 24;
final int oldPixel = oldPixels[0][p];
final int oldPixelAlpha = oldPixel >>> 24;
final int newAlpha = oldPixelAlpha * alphaMultiplier / 0xFF;
pixels[0][p] = (oldPixel & 0xFFFFFF) + (newAlpha << 24);
}
}
this.clearFramesTextureData();
this.framesTextureData.add(pixels);
return false;
}
}
private static final class BakedDynBucketOverrideHandler extends ItemOverrideList
@@ -278,51 +413,24 @@ public final class ModelDynBucket implements IModel
}
// the dynamic bucket is based on the empty bucket
private static final class BakedDynBucket implements IBakedModel
private static final class BakedDynBucket extends BakedItemModel
{
private final ModelDynBucket parent;
// FIXME: guava cache?
private final Map<String, IBakedModel> cache; // contains all the baked models since they'll never change
private final ImmutableMap<TransformType, TRSRTransformation> transforms;
private final ImmutableList<BakedQuad> quads;
private final TextureAtlasSprite particle;
private final VertexFormat format;
public BakedDynBucket(ModelDynBucket parent,
ImmutableList<BakedQuad> quads, TextureAtlasSprite particle, VertexFormat format, ImmutableMap<ItemCameraTransforms.TransformType, TRSRTransformation> transforms,
ImmutableList<BakedQuad> quads,
TextureAtlasSprite particle,
VertexFormat format,
ImmutableMap<TransformType, TRSRTransformation> transforms,
Map<String, IBakedModel> cache)
{
this.quads = quads;
this.particle = particle;
super(quads, particle, transforms, BakedDynBucketOverrideHandler.INSTANCE);
this.format = format;
this.parent = parent;
this.transforms = transforms;
this.cache = cache;
}
@Override
public ItemOverrideList getOverrides()
{
return BakedDynBucketOverrideHandler.INSTANCE;
}
@Override
public Pair<? extends IBakedModel, Matrix4f> handlePerspective(TransformType cameraTransformType)
{
return PerspectiveMapWrapper.handlePerspective(this, transforms, cameraTransformType);
}
@Override
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand)
{
if(side == null) return quads;
return ImmutableList.of();
}
public boolean isAmbientOcclusion() { return true; }
public boolean isGui3d() { return false; }
public boolean isBuiltInRenderer() { return false; }
public TextureAtlasSprite getParticleTexture() { return particle; }
}
}
@@ -318,79 +318,6 @@ public final class ModelLoader extends ModelBakery
}
}
ProgressManager.pop(itemBar);
// replace vanilla bucket models if desired. done afterwards for performance reasons
if(ForgeModContainer.replaceVanillaBucketModel)
{
// ensure the bucket model is loaded
if(!stateModels.containsKey(ModelDynBucket.LOCATION))
{
// load forges blockstate json for it
try
{
registerVariant(getModelBlockDefinition(ModelDynBucket.LOCATION), ModelDynBucket.LOCATION);
}
catch (Exception exception)
{
FMLLog.log.error("Could not load the forge bucket model from the blockstate", exception);
return;
}
}
// empty bucket
for(String s : getVariantNames(Items.BUCKET))
{
ModelResourceLocation memory = getInventoryVariant(s);
IModel model = ModelLoaderRegistry.getModelOrMissing(new ResourceLocation(ForgeVersion.MOD_ID, "item/bucket"));
// only on successful load, otherwise continue using the old model
if(model != getMissingModel())
{
stateModels.put(memory, model);
}
}
setBucketModel(Items.WATER_BUCKET);
setBucketModel(Items.LAVA_BUCKET);
// milk bucket only replaced if some mod adds milk
if(FluidRegistry.isFluidRegistered("milk"))
{
// can the milk be put into a bucket?
Fluid milk = FluidRegistry.getFluid("milk");
FluidStack milkStack = new FluidStack(milk, Fluid.BUCKET_VOLUME);
IFluidHandler bucketHandler = FluidUtil.getFluidHandler(new ItemStack(Items.BUCKET));
if (bucketHandler != null && bucketHandler.fill(milkStack, false) == Fluid.BUCKET_VOLUME)
{
setBucketModel(Items.MILK_BUCKET);
}
}
else
{
// milk bucket if no milk fluid is present
for(String s : getVariantNames(Items.MILK_BUCKET))
{
ModelResourceLocation memory = getInventoryVariant(s);
IModel model = ModelLoaderRegistry.getModelOrMissing(new ResourceLocation(ForgeVersion.MOD_ID, "item/bucket_milk"));
// only on successful load, otherwise continue using the old model
if(model != getMissingModel())
{
stateModels.put(memory, model);
}
}
}
}
}
private void setBucketModel(Item item)
{
for(String s : getVariantNames(item))
{
ModelResourceLocation memory = getInventoryVariant(s);
IModel model = stateModels.get(ModelDynBucket.LOCATION);
if(model != null)
{
stateModels.put(memory, model);
}
}
}
/**
@@ -112,6 +112,7 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC
public static boolean shouldSortRecipies = true;
public static boolean disableVersionCheck = false;
public static boolean forgeLightPipelineEnabled = true;
@Deprecated // TODO remove in 1.13
public static boolean replaceVanillaBucketModel = true;
public static boolean zoomInMissingModelTextInGui = false;
public static boolean disableStairSlabCulling = false; // Also known as the "DontCullStairsBecauseIUseACrappyTexturePackThatBreaksBasicBlockShapesSoICantTrustBasicBlockCulling" flag
@@ -213,6 +214,7 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC
if (config.getCategory(CATEGORY_GENERAL).containsKey("spawnHasFuzz")) config.getCategory(CATEGORY_GENERAL).remove("spawnHasFuzz");
if (config.getCategory(CATEGORY_GENERAL).containsKey("disableStitchedFileSaving")) config.getCategory(CATEGORY_GENERAL).remove("disableStitchedFileSaving");
if (config.getCategory(CATEGORY_CLIENT).containsKey("java8Reminder")) config.getCategory(CATEGORY_CLIENT).remove("java8Reminder");
if (config.getCategory(CATEGORY_CLIENT).containsKey("replaceVanillaBucketModel")) config.getCategory(CATEGORY_CLIENT).remove("replaceVanillaBucketModel");
// remap properties wrongly listed as general properties to client properties
remapGeneralPropertyToClient("biomeSkyBlendRange");
@@ -315,12 +317,6 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC
// Client-Side only properties
propOrder = new ArrayList<String>();
prop = config.get(Configuration.CATEGORY_CLIENT, "replaceVanillaBucketModel", false,
"Replace the vanilla bucket models with Forges own dynamic bucket model. Unifies bucket visuals if a mod uses the Forge bucket model.");
prop.setLanguageKey("forge.configgui.replaceBuckets").setRequiresMcRestart(true);
replaceVanillaBucketModel = prop.getBoolean(false);
propOrder.add(prop.getName());
prop = config.get(Configuration.CATEGORY_CLIENT, "zoomInMissingModelTextInGui", false,
"Toggle off to make missing model text in the gui fit inside the slot.");
zoomInMissingModelTextInGui = prop.getBoolean(false);