diff --git a/patches/minecraft/net/minecraft/client/renderer/block/model/ItemOverrideList.java.patch b/patches/minecraft/net/minecraft/client/renderer/block/model/ItemOverrideList.java.patch index c6a455d288..a000941766 100644 --- a/patches/minecraft/net/minecraft/client/renderer/block/model/ItemOverrideList.java.patch +++ b/patches/minecraft/net/minecraft/client/renderer/block/model/ItemOverrideList.java.patch @@ -8,7 +8,7 @@ public ResourceLocation func_188021_a(ItemStack p_188021_1_, World p_188021_2_, EntityLivingBase p_188021_3_) { if (!this.field_188023_b.isEmpty()) -@@ -42,4 +43,18 @@ +@@ -42,4 +43,23 @@ return null; } @@ -25,5 +25,10 @@ + } + } + return originalModel; ++ } ++ ++ public com.google.common.collect.ImmutableList getOverrides() ++ { ++ return com.google.common.collect.ImmutableList.copyOf(field_188023_b); + } } diff --git a/patches/minecraft/net/minecraft/item/Item.java.patch b/patches/minecraft/net/minecraft/item/Item.java.patch index 46f446cc99..23d952ef4e 100644 --- a/patches/minecraft/net/minecraft/item/Item.java.patch +++ b/patches/minecraft/net/minecraft/item/Item.java.patch @@ -57,7 +57,7 @@ Vec3d vec3d1 = vec3d.func_72441_c((double)f6 * d3, (double)f5 * d3, (double)f7 * d3); return p_77621_1_.func_147447_a(vec3d, vec3d1, p_77621_3_, !p_77621_3_, false); } -@@ -422,11 +431,588 @@ +@@ -422,11 +431,606 @@ return false; } @@ -641,12 +641,30 @@ + { + return null; + } ++ ++ public com.google.common.collect.ImmutableMap getAnimationParameters(final ItemStack stack, final World world, final EntityLivingBase entity) ++ { ++ com.google.common.collect.ImmutableMap.Builder builder = com.google.common.collect.ImmutableMap.builder(); ++ for(ResourceLocation location : field_185051_m.func_148742_b()) ++ { ++ final IItemPropertyGetter parameter = field_185051_m.func_82594_a(location); ++ builder.put(location.toString(), new net.minecraftforge.client.model.animation.ITimeValue() ++ { ++ public float apply(float input) ++ { ++ return parameter.func_185085_a(stack, world, entity); ++ } ++ }); ++ } ++ return builder.build(); ++ } ++ + /* ======================================== FORGE END =====================================*/ + public static void func_150900_l() { func_179214_a(Blocks.field_150348_b, (new ItemMultiTexture(Blocks.field_150348_b, Blocks.field_150348_b, new Function() -@@ -935,6 +1521,10 @@ +@@ -935,6 +1539,10 @@ private final float field_78011_i; private final int field_78008_j; @@ -657,7 +675,7 @@ private ToolMaterial(int p_i1874_3_, int p_i1874_4_, float p_i1874_5_, float p_i1874_6_, int p_i1874_7_) { this.field_78001_f = p_i1874_3_; -@@ -969,9 +1559,36 @@ +@@ -969,9 +1577,36 @@ return this.field_78008_j; } diff --git a/src/main/java/net/minecraftforge/client/model/BlockStateLoader.java b/src/main/java/net/minecraftforge/client/model/BlockStateLoader.java index e813982b18..89141ec737 100644 --- a/src/main/java/net/minecraftforge/client/model/BlockStateLoader.java +++ b/src/main/java/net/minecraftforge/client/model/BlockStateLoader.java @@ -185,9 +185,7 @@ public class BlockStateLoader IModel model = ModelLoaderRegistry.getModelOrLogError(part.getModelLocation(), "Unable to load block sub-model: \'" + part.getModelLocation()); - IModelState partState = new ModelStateComposition(baseTr, part.getState()); - - models.put(entry.getKey(), Pair.of(runModelHooks(model, part.smooth, part.gui3d, part.uvLock, part.getTextures(), part.getCustomData()), partState)); + models.put(entry.getKey(), Pair.of(runModelHooks(model, part.smooth, part.gui3d, part.uvLock, part.getTextures(), part.getCustomData()), part.getState())); } return new MultiModel(getModelLocation(), hasBase ? base : null, baseTr, models.build()); diff --git a/src/main/java/net/minecraftforge/client/model/ModelLoader.java b/src/main/java/net/minecraftforge/client/model/ModelLoader.java index b72b8cf46c..395913f585 100644 --- a/src/main/java/net/minecraftforge/client/model/ModelLoader.java +++ b/src/main/java/net/minecraftforge/client/model/ModelLoader.java @@ -28,6 +28,7 @@ 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.ItemModelGenerator; +import net.minecraft.client.renderer.block.model.ItemOverrideList; import net.minecraft.client.renderer.block.model.ModelBakery; import net.minecraft.client.renderer.block.model.ModelBlock; import net.minecraft.client.renderer.block.model.ModelBlockDefinition; @@ -57,6 +58,7 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.registry.IRegistry; import net.minecraftforge.client.model.animation.Animation; +import net.minecraftforge.client.model.animation.AnimationItemOverrideList; import net.minecraftforge.client.model.animation.IAnimatedModel; import net.minecraftforge.client.model.animation.IClip; import net.minecraftforge.client.model.animation.ModelBlockAnimation; @@ -497,17 +499,18 @@ public final class ModelLoader extends ModelBakery return new ItemLayerModel(model).bake(perState, format, bakedTextureGetter); } if(isCustomRenderer(model)) return new BuiltInModel(transforms, model.createOverrides()); - return bakeNormal(model, perState, state.apply(Optional.absent()).or(TRSRTransformation.identity()), newTransforms, format, bakedTextureGetter, uvlock); + return bakeNormal(model, perState, state, newTransforms, format, bakedTextureGetter, uvlock); } - private IBakedModel bakeNormal(ModelBlock model, IModelState perState, final TRSRTransformation modelState, List newTransforms, final VertexFormat format, final Function bakedTextureGetter, boolean uvLocked) + private IBakedModel bakeNormal(ModelBlock model, IModelState perState, final IModelState modelState, List newTransforms, final VertexFormat format, final Function bakedTextureGetter, boolean uvLocked) { + final TRSRTransformation baseState = modelState.apply(Optional.absent()).or(TRSRTransformation.identity()); TextureAtlasSprite particle = bakedTextureGetter.apply(new ResourceLocation(model.resolveTextureName("particle"))); SimpleBakedModel.Builder builder = (new SimpleBakedModel.Builder(model, model.createOverrides())).setTexture(particle); for(int i = 0; i < model.getElements().size(); i++) { BlockPart part = model.getElements().get(i); - TRSRTransformation transformation = modelState; + TRSRTransformation transformation = baseState; if(newTransforms.get(i) != null) { transformation = transformation.compose(newTransforms.get(i)); @@ -525,13 +528,15 @@ public final class ModelLoader extends ModelBakery } else { - builder.addFaceQuad(modelState.rotate(e.getValue().cullFace), makeBakedQuad(part, e.getValue(), textureatlassprite1, e.getKey(), transformation, uvLocked)); + builder.addFaceQuad(baseState.rotate(e.getValue().cullFace), makeBakedQuad(part, e.getValue(), textureatlassprite1, e.getKey(), transformation, uvLocked)); } } } return new IPerspectiveAwareModel.MapWrapper(builder.makeBakedModel(), perState) { + private final ItemOverrideList overrides = new AnimationItemOverrideList(VanillaModelWrapper.this, modelState, format, bakedTextureGetter, super.getOverrides()); + @Override public List getQuads(IBlockState state, EnumFacing side, long rand) { @@ -550,6 +555,12 @@ public final class ModelLoader extends ModelBakery } return super.getQuads(state, side, rand); }; + + @Override + public ItemOverrideList getOverrides() + { + return overrides; + } }; } diff --git a/src/main/java/net/minecraftforge/client/model/MultiModel.java b/src/main/java/net/minecraftforge/client/model/MultiModel.java index a6f3b6c8c8..7db688ee40 100644 --- a/src/main/java/net/minecraftforge/client/model/MultiModel.java +++ b/src/main/java/net/minecraftforge/client/model/MultiModel.java @@ -14,11 +14,15 @@ 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.texture.TextureAtlasSprite; import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; import net.minecraftforge.fml.common.FMLLog; import org.apache.commons.lang3.tuple.Pair; @@ -28,6 +32,7 @@ import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; import com.google.common.collect.Sets; // TODO: Switch to vanilla class, or to something similar @@ -36,15 +41,55 @@ public final class MultiModel implements IModel { private static final class Baked implements IPerspectiveAwareModel { + private final ResourceLocation location; private final IBakedModel base; private final ImmutableMap parts; private final IBakedModel internalBase; private ImmutableMap, ImmutableList> quads; private final ImmutableMap> transforms; + private final ItemOverrideList overrides = new ItemOverrideList(Lists.newArrayList()) + { + @Override + public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity) + { + if(originalModel != Baked.this) + { + return originalModel; + } + boolean dirty = false; + IBakedModel newBase = null; + + if(base != null) + { + newBase = base.getOverrides().handleItemState(base, stack, world, entity); + if(base != newBase) + { + dirty = true; + } + } + ImmutableMap.Builder builder = ImmutableMap.builder(); + for(Map.Entry entry : parts.entrySet()) + { + IBakedModel newPart = entry.getValue().getOverrides().handleItemState(entry.getValue(), stack, world, entity); + builder.put(entry.getKey(), newPart); + if(entry.getValue() != newPart) + { + dirty = true; + } + } + if(dirty) + { + // TODO: caching? + return new Baked(location, newBase instanceof IPerspectiveAwareModel, newBase, builder.build()); + } + return Baked.this; + } + }; public Baked(ResourceLocation location, boolean perspective, IBakedModel base, ImmutableMap parts) { + this.location = location; this.base = base; this.parts = parts; @@ -120,22 +165,22 @@ public final class MultiModel implements IModel ImmutableList.Builder quads = ImmutableList.builder(); if (base != null) { - quads.addAll(base.getQuads(null, face, 0)); + quads.addAll(base.getQuads(state, face, 0)); } for (IBakedModel bakedPart : parts.values()) { - quads.addAll(bakedPart.getQuads(null, face, 0)); + quads.addAll(bakedPart.getQuads(state, face, 0)); } builder.put(Optional.of(face), quads.build()); } ImmutableList.Builder quads = ImmutableList.builder(); if (base != null) { - quads.addAll(base.getQuads(null, null, 0)); + quads.addAll(base.getQuads(state, null, 0)); } for (IBakedModel bakedPart : parts.values()) { - quads.addAll(bakedPart.getQuads(null, null, 0)); + quads.addAll(bakedPart.getQuads(state, null, 0)); } builder.put(Optional.absent(), quads.build()); this.quads = builder.build(); @@ -154,7 +199,7 @@ public final class MultiModel implements IModel @Override public ItemOverrideList getOverrides() { - return ItemOverrideList.NONE; + return overrides; } } @@ -217,7 +262,7 @@ public final class MultiModel implements IModel for (Entry> entry : parts.entrySet()) { Pair pair = entry.getValue(); - mapBuilder.put(entry.getKey(), pair.getLeft().bake(pair.getRight(), format, bakedTextureGetter)); + mapBuilder.put(entry.getKey(), pair.getLeft().bake(new ModelStateComposition(state, pair.getRight()), format, bakedTextureGetter)); } if(bakedBase == null && parts.isEmpty()) diff --git a/src/main/java/net/minecraftforge/client/model/animation/Animation.java b/src/main/java/net/minecraftforge/client/model/animation/Animation.java index 75cc9ccac1..e25786c528 100644 --- a/src/main/java/net/minecraftforge/client/model/animation/Animation.java +++ b/src/main/java/net/minecraftforge/client/model/animation/Animation.java @@ -107,7 +107,7 @@ public enum Animation implements IResourceManagerReloadListener return defaultModelBlockAnimation; } ModelBlockAnimation mba = mbaGson.fromJson(new InputStreamReader(resource.getInputStream(), "UTF-8"), ModelBlockAnimation.class); - String json = mbaGson.toJson(mba); + //String json = mbaGson.toJson(mba); return mba; } catch(IOException e) @@ -124,7 +124,7 @@ public enum Animation implements IResourceManagerReloadListener private IResourceManager manager; - private final AnimationStateMachine missing = new AnimationStateMachine( + protected final AnimationStateMachine missing = new AnimationStateMachine( ImmutableMap.of(), ImmutableMap.of("missingno", (IClip)Clips.IdentityClip.instance), ImmutableList.of("missingno"), diff --git a/src/main/java/net/minecraftforge/client/model/animation/AnimationItemOverrideList.java b/src/main/java/net/minecraftforge/client/model/animation/AnimationItemOverrideList.java new file mode 100644 index 0000000000..9fe76315fe --- /dev/null +++ b/src/main/java/net/minecraftforge/client/model/animation/AnimationItemOverrideList.java @@ -0,0 +1,63 @@ +package net.minecraftforge.client.model.animation; + +import java.util.List; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.block.model.ItemOverride; +import net.minecraft.client.renderer.block.model.ItemOverrideList; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import net.minecraftforge.client.model.IModel; +import net.minecraftforge.client.model.IModelState; +import net.minecraftforge.client.model.ModelStateComposition; +import net.minecraftforge.common.model.animation.IAnimationStateMachine; + +import com.google.common.base.Function; + +public final class AnimationItemOverrideList extends ItemOverrideList +{ + private final IModel model; + private final IModelState state; + private final VertexFormat format; + private final Function bakedTextureGetter; + + public AnimationItemOverrideList(IModel model, IModelState state, VertexFormat format, Function bakedTextureGetter, ItemOverrideList overrides) + { + this(model, state, format, bakedTextureGetter, overrides.getOverrides()); + } + + public AnimationItemOverrideList(IModel model, IModelState state, VertexFormat format, Function bakedTextureGetter, List overrides) + { + super(overrides); + this.model = model; + this.state = state; + this.format = format; + this.bakedTextureGetter = bakedTextureGetter; + } + + @Override + public IBakedModel handleItemState(IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity) + { + if(stack.hasCapability(net.minecraftforge.client.model.animation.CapabilityAnimation.ANIMATION_CAPABILITY, null)) + { + // TODO: caching? + IAnimationStateMachine asm = stack.getCapability(CapabilityAnimation.ANIMATION_CAPABILITY, null); + if(world == null) + { + world = entity.worldObj; + } + if(world == null) + { + world = Minecraft.getMinecraft().theWorld; + } + IModelState state = asm.apply(Animation.getWorldTime(world, Animation.getPartialTickTime())).getLeft(); + return model.bake(new ModelStateComposition(state, this.state), format, bakedTextureGetter); + } + return originalModel; + } +} diff --git a/src/main/java/net/minecraftforge/client/model/animation/AnimationModelBase.java b/src/main/java/net/minecraftforge/client/model/animation/AnimationModelBase.java index 6174ee335c..3273967920 100644 --- a/src/main/java/net/minecraftforge/client/model/animation/AnimationModelBase.java +++ b/src/main/java/net/minecraftforge/client/model/animation/AnimationModelBase.java @@ -14,9 +14,11 @@ import net.minecraft.entity.Entity; import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.model.IModel; import net.minecraftforge.client.model.IModelState; import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.client.model.ModelLoaderRegistry; import net.minecraftforge.client.model.pipeline.VertexLighterFlat; import net.minecraftforge.client.model.pipeline.VertexBufferConsumer; @@ -28,14 +30,14 @@ import org.lwjgl.opengl.GL11; * Some quirks are still left, deprecated for the moment. */ @Deprecated -public class AnimationModelBase extends ModelBase implements IEventHandler +public class AnimationModelBase extends ModelBase implements IEventHandler { private final VertexLighterFlat lighter; - private final IModel model; + private final ResourceLocation modelLocation; - public AnimationModelBase(IModel model, VertexLighterFlat lighter) + public AnimationModelBase(ResourceLocation modelLocation, VertexLighterFlat lighter) { - this.model = model; + this.modelLocation = modelLocation; this.lighter = lighter; } @@ -43,13 +45,14 @@ public class AnimationModelBase extends M @Override public void render(Entity entity, float limbSwing, float limbSwingSpeed, float timeAlive, float yawHead, float rotationPitch, float scale) { - if(!(entity instanceof IAnimationProvider)) + if(!(entity.hasCapability(CapabilityAnimation.ANIMATION_CAPABILITY, null))) { - throw new ClassCastException("AnimationModelBase expects IAnimationProvider"); + return; } - Pair> pair = ((IAnimationProvider)entity).asm().apply(timeAlive / 20); + Pair> pair = entity.getCapability(CapabilityAnimation.ANIMATION_CAPABILITY, null).apply(timeAlive / 20); handleEvents((T)entity, timeAlive / 20, pair.getRight()); + IModel model = ModelLoaderRegistry.getModelOrMissing(modelLocation); IBakedModel bakedModel = model.bake(pair.getLeft(), DefaultVertexFormats.ITEM, ModelLoader.defaultTextureGetter()); BlockPos pos = new BlockPos(entity.posX, entity.posY + entity.height, entity.posZ); diff --git a/src/main/java/net/minecraftforge/client/model/animation/AnimationTESR.java b/src/main/java/net/minecraftforge/client/model/animation/AnimationTESR.java index ac6ec94d6f..db81f323d7 100644 --- a/src/main/java/net/minecraftforge/client/model/animation/AnimationTESR.java +++ b/src/main/java/net/minecraftforge/client/model/animation/AnimationTESR.java @@ -18,12 +18,16 @@ import org.apache.commons.lang3.tuple.Pair; /** * Generic TileEntitySpecialRenderer that works with the Forge model system and animations. */ -public class AnimationTESR extends FastTESR implements IEventHandler +public class AnimationTESR extends FastTESR implements IEventHandler { protected static BlockRendererDispatcher blockRenderer; public void renderTileEntityFast(T te, double x, double y, double z, float partialTick, int breakStage, VertexBuffer renderer) { + if(!te.hasCapability(CapabilityAnimation.ANIMATION_CAPABILITY, null)) + { + return; + } if(blockRenderer == null) blockRenderer = Minecraft.getMinecraft().getBlockRendererDispatcher(); BlockPos pos = te.getPos(); IBlockAccess world = MinecraftForgeClient.getRegionRenderCache(te.getWorld(), pos); @@ -38,7 +42,7 @@ public class AnimationTESR extends Fa if(exState.getUnlistedNames().contains(Properties.AnimationProperty)) { float time = Animation.getWorldTime(getWorld(), partialTick); - Pair> pair = te.asm().apply(time); + Pair> pair = te.getCapability(CapabilityAnimation.ANIMATION_CAPABILITY, null).apply(time); handleEvents(te, time, pair.getRight()); // TODO: caching? diff --git a/src/main/java/net/minecraftforge/client/model/animation/CapabilityAnimation.java b/src/main/java/net/minecraftforge/client/model/animation/CapabilityAnimation.java new file mode 100644 index 0000000000..3181e463d2 --- /dev/null +++ b/src/main/java/net/minecraftforge/client/model/animation/CapabilityAnimation.java @@ -0,0 +1,61 @@ +package net.minecraftforge.client.model.animation; + +import java.util.concurrent.Callable; + +import net.minecraft.nbt.NBTBase; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.CapabilityInject; +import net.minecraftforge.common.capabilities.CapabilityManager; +import net.minecraftforge.common.capabilities.ICapabilityProvider; +import net.minecraftforge.common.model.animation.IAnimationStateMachine; + +public class CapabilityAnimation +{ + @CapabilityInject(IAnimationStateMachine.class) + public static Capability ANIMATION_CAPABILITY = null; + + public static void register() + { + CapabilityManager.INSTANCE.register(IAnimationStateMachine.class, new Capability.IStorage() + { + public NBTBase writeNBT(Capability capability, IAnimationStateMachine instance, EnumFacing side) + { + return null; + } + + public void readNBT(Capability capability, IAnimationStateMachine instance, EnumFacing side, NBTBase nbt) {} + }, new Callable() + { + public IAnimationStateMachine call() throws Exception + { + return Animation.INSTANCE.missing; + } + }); + } + + public static class DefaultItemAnimationCapabilityProvider implements ICapabilityProvider + { + private final IAnimationStateMachine asm; + + public DefaultItemAnimationCapabilityProvider(IAnimationStateMachine asm) + { + this.asm = asm; + } + + public boolean hasCapability(Capability capability, EnumFacing facing) + { + return capability == ANIMATION_CAPABILITY; + } + + @SuppressWarnings("unchecked") + public T getCapability(Capability capability, EnumFacing facing) + { + if(capability == ANIMATION_CAPABILITY) + { + return (T)asm; + } + return null; + } + } +} diff --git a/src/main/java/net/minecraftforge/client/model/animation/IAnimationProvider.java b/src/main/java/net/minecraftforge/client/model/animation/IAnimationProvider.java deleted file mode 100644 index 94723d38f1..0000000000 --- a/src/main/java/net/minecraftforge/client/model/animation/IAnimationProvider.java +++ /dev/null @@ -1,12 +0,0 @@ -package net.minecraftforge.client.model.animation; - -import net.minecraftforge.common.model.animation.IAnimationStateMachine; - - -/** - * Something that can provide the Animation State Machine, for example and Entity or a Block - */ -public interface IAnimationProvider -{ - public IAnimationStateMachine asm(); -} diff --git a/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java b/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java index 6e9cf90719..9ae3fdc8e3 100644 --- a/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java +++ b/src/main/java/net/minecraftforge/client/model/b3d/B3DLoader.java @@ -49,7 +49,6 @@ import net.minecraftforge.client.model.b3d.B3DModel.Mesh; import net.minecraftforge.client.model.b3d.B3DModel.Node; import net.minecraftforge.client.model.b3d.B3DModel.Texture; import net.minecraftforge.client.model.b3d.B3DModel.Vertex; -import net.minecraftforge.client.model.pipeline.LightUtil; import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; @@ -680,9 +679,16 @@ public final class B3DLoader implements ICustomModelLoader if(quads == null) { ImmutableList.Builder builder = ImmutableList.builder(); - generateQuads(builder, node, modelState); + generateQuads(builder, node, this.state); quads = builder.build(); } + // TODO: caching? + if(this.state != modelState) + { + ImmutableList.Builder builder = ImmutableList.builder(); + generateQuads(builder, node, modelState); + return builder.build(); + } return quads; } diff --git a/src/test/java/net/minecraftforge/debug/ModelAnimationDebug.java b/src/test/java/net/minecraftforge/debug/ModelAnimationDebug.java index 3156a226fb..07c248117d 100644 --- a/src/test/java/net/minecraftforge/debug/ModelAnimationDebug.java +++ b/src/test/java/net/minecraftforge/debug/ModelAnimationDebug.java @@ -1,7 +1,5 @@ package net.minecraftforge.debug; -import java.io.IOException; - import net.minecraft.block.Block; import net.minecraft.block.BlockPistonBase; import net.minecraft.block.material.Material; @@ -20,7 +18,9 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; @@ -28,23 +28,17 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import net.minecraftforge.client.model.IModel; -import net.minecraftforge.client.model.IModelState; -import net.minecraftforge.client.model.IRetexturableModel; import net.minecraftforge.client.model.ModelLoader; -import net.minecraftforge.client.model.ModelLoaderRegistry; -import net.minecraftforge.client.model.ModelProcessingHelper; -import net.minecraftforge.client.model.MultiModel; -import net.minecraftforge.client.model.TRSRTransformation; import net.minecraftforge.client.model.animation.Animation; -import net.minecraftforge.client.model.animation.AnimationModelBase; import net.minecraftforge.client.model.animation.AnimationTESR; +import net.minecraftforge.client.model.animation.CapabilityAnimation; import net.minecraftforge.client.model.animation.Event; -import net.minecraftforge.client.model.animation.IAnimationProvider; import net.minecraftforge.client.model.animation.ITimeValue; import net.minecraftforge.client.model.animation.TimeValues.VariableValue; import net.minecraftforge.client.model.b3d.B3DLoader; import net.minecraftforge.client.model.pipeline.VertexLighterSmoothAo; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.ICapabilityProvider; import net.minecraftforge.common.model.animation.IAnimationStateMachine; import net.minecraftforge.common.property.ExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; @@ -60,8 +54,6 @@ import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.registry.EntityRegistry; import net.minecraftforge.fml.common.registry.GameRegistry; -import org.apache.commons.lang3.tuple.Pair; - import com.google.common.collect.ImmutableMap; @Mod(modid = ModelAnimationDebug.MODID, version = ModelAnimationDebug.VERSION) @@ -156,6 +148,14 @@ public class ModelAnimationDebug } return true; } + }, null, blockName); + GameRegistry.registerItem(new ItemBlock(GameRegistry.findBlock(MODID, blockName)) + { + @Override + public ICapabilityProvider initCapabilities(ItemStack stack, NBTTagCompound nbt) + { + return new ItemAnimationHolder(); + } }, blockName); GameRegistry.registerTileEntity(Chest.class, MODID + ":" + "tile_" + blockName); } @@ -192,6 +192,7 @@ public class ModelAnimationDebug EntityRegistry.registerModEntity(EntityChest.class, entityName, 0, ModelAnimationDebug.instance, 64, 20, true, 0xFFAAAA00, 0xFFDDDD00); RenderingRegistry.registerEntityRenderingHandler(EntityChest.class, new IRenderFactory() { + @SuppressWarnings("deprecation") public Render createRenderFor(RenderManager manager) { /*model = ModelLoaderRegistry.getModel(new ResourceLocation(ModelLoaderRegistryDebug.MODID, "block/chest.b3d")); @@ -203,25 +204,8 @@ public class ModelAnimationDebug { model = ((IModelCustomData)model).process(ImmutableMap.of("mesh", "[\"Base\", \"Lid\"]")); }*/ - IModel base = ModelLoaderRegistry.getModelOrMissing(new ResourceLocation(ModelAnimationDebug.MODID, "block/engine")); - IModel ring = ModelLoaderRegistry.getModelOrMissing(new ResourceLocation(ModelAnimationDebug.MODID, "block/engine_ring")); - ImmutableMap textures = ImmutableMap.of( - "base", "blocks/stone", - "front", "blocks/log_oak", - "chamber", "blocks/redstone_block", - "trunk", "blocks/end_stone" - ); - base = ModelProcessingHelper.retexture(base, textures); - ring = ModelProcessingHelper.retexture(base, textures); - IModel model = new MultiModel( - new ResourceLocation(ModelAnimationDebug.MODID, "builtin/engine"), - ring, - TRSRTransformation.identity(), - ImmutableMap.of( - "base", Pair.of(base, TRSRTransformation.identity()) - ) - ); - return new RenderLiving(manager, new AnimationModelBase(model, new VertexLighterSmoothAo(Minecraft.getMinecraft().getBlockColors())) + ResourceLocation location = new ModelResourceLocation(new ResourceLocation(MODID, blockName), "entity"); + return new RenderLiving(manager, new net.minecraftforge.client.model.animation.AnimationModelBase(location, new VertexLighterSmoothAo(Minecraft.getMinecraft().getBlockColors())) { @Override public void handleEvents(EntityChest chest, float time, Iterable pastEvents) @@ -246,10 +230,34 @@ public class ModelAnimationDebug } + private static class ItemAnimationHolder implements ICapabilityProvider + { + private final VariableValue cycleLength = new VariableValue(4); + + private final IAnimationStateMachine asm = proxy.load(new ResourceLocation(MODID.toLowerCase(), "asms/block/engine.json"), ImmutableMap.of( + "cycle_length", cycleLength + )); + + public boolean hasCapability(Capability capability, EnumFacing facing) + { + return capability == CapabilityAnimation.ANIMATION_CAPABILITY; + } + + @SuppressWarnings("unchecked") + public T getCapability(Capability capability, EnumFacing facing) + { + if(capability == CapabilityAnimation.ANIMATION_CAPABILITY) + { + return (T)asm; + } + return null; + } + } + @EventHandler public void preInit(FMLPreInitializationEvent event) { proxy.preInit(event); } - public static class Chest extends TileEntity implements IAnimationProvider + public static class Chest extends TileEntity { private final IAnimationStateMachine asm; private final VariableValue cycleLength = new VariableValue(4); @@ -319,25 +327,37 @@ public class ModelAnimationDebug } } - public IAnimationStateMachine asm() + @Override + public boolean hasCapability(Capability capability, EnumFacing side) { - return asm; + if(capability == CapabilityAnimation.ANIMATION_CAPABILITY) + { + return true; + } + return super.hasCapability(capability, side); + } + + @SuppressWarnings("unchecked") + @Override + public T getCapability(Capability capability, EnumFacing side) + { + if(capability == CapabilityAnimation.ANIMATION_CAPABILITY) + { + return (T)asm; + } + return super.getCapability(capability, side); } } - public static class EntityChest extends EntityLiving implements IAnimationProvider + public static class EntityChest extends EntityLiving { private final IAnimationStateMachine asm; - private VariableValue cycleLength; + private final VariableValue cycleLength = new VariableValue(getHealth() / 5); public EntityChest(World world) { super(world); setSize(1, 1); - if(cycleLength == null) - { - cycleLength = new VariableValue(getHealth() / 5); - } asm = proxy.load(new ResourceLocation(MODID.toLowerCase(), "asms/block/engine.json"), ImmutableMap.of( "cycle_length", cycleLength )); @@ -348,25 +368,15 @@ public class ModelAnimationDebug // TODO Auto-generated method stub } - public IAnimationStateMachine asm() + @Override + public void onEntityUpdate() { - return asm; - } - - // FIXME update health - /*@Override - public void func_184206_a(DataParameter key) - { - super.func_184206_a(key); - if(field_184632_c.equals(key)) // health + super.onEntityUpdate(); + if(worldObj.isRemote && cycleLength != null) { - if(cycleLength == null) - { - cycleLength = new VariableValue(0); - } cycleLength.setValue(getHealth() / 5); } - }*/ + } @Override protected void applyEntityAttributes() @@ -374,6 +384,27 @@ public class ModelAnimationDebug super.applyEntityAttributes(); this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(60); } + + @Override + public boolean hasCapability(Capability capability, EnumFacing side) + { + if(capability == CapabilityAnimation.ANIMATION_CAPABILITY) + { + return true; + } + return super.hasCapability(capability, side); + } + + @SuppressWarnings("unchecked") + @Override + public T getCapability(Capability capability, EnumFacing side) + { + if(capability == CapabilityAnimation.ANIMATION_CAPABILITY) + { + return (T)asm; + } + return super.getCapability(capability, side); + } } } diff --git a/src/test/resources/assets/forgedebugmodelanimation/blockstates/test_animation_block.json b/src/test/resources/assets/forgedebugmodelanimation/blockstates/test_animation_block.json index f2faef79e5..26dc74ed9d 100644 --- a/src/test/resources/assets/forgedebugmodelanimation/blockstates/test_animation_block.json +++ b/src/test/resources/assets/forgedebugmodelanimation/blockstates/test_animation_block.json @@ -43,6 +43,12 @@ }*/ "model": "forgedebugmodelanimation:engine_ring" } - } + }, + "entity": [{ + "model": "forgedebugmodelanimation:engine", + "submodel": { + "ring": { "model": "forgedebugmodelanimation:engine_ring" } + } + }] } }