Switched animation system to capabilities, added animated item example, fixed state passing in MultiModel.

This commit is contained in:
RainWarrior 2016-03-21 09:15:39 +03:00
parent 558348125d
commit 5f62404f8a
14 changed files with 338 additions and 99 deletions

View file

@ -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<ItemOverride> getOverrides()
+ {
+ return com.google.common.collect.ImmutableList.copyOf(field_188023_b);
+ }
}

View file

@ -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<String, net.minecraftforge.client.model.animation.ITimeValue> getAnimationParameters(final ItemStack stack, final World world, final EntityLivingBase entity)
+ {
+ com.google.common.collect.ImmutableMap.Builder<String, net.minecraftforge.client.model.animation.ITimeValue> 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<ItemStack, String>()
@@ -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;
}

View file

@ -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.<IModel, IModelState>of(runModelHooks(model, part.smooth, part.gui3d, part.uvLock, part.getTextures(), part.getCustomData()), partState));
models.put(entry.getKey(), Pair.<IModel, IModelState>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());

View file

@ -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.<IModelPart>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<TRSRTransformation> newTransforms, final VertexFormat format, final Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter, boolean uvLocked)
private IBakedModel bakeNormal(ModelBlock model, IModelState perState, final IModelState modelState, List<TRSRTransformation> newTransforms, final VertexFormat format, final Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter, boolean uvLocked)
{
final TRSRTransformation baseState = modelState.apply(Optional.<IModelPart>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<BakedQuad> 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;
}
};
}

View file

@ -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<String, IBakedModel> parts;
private final IBakedModel internalBase;
private ImmutableMap<Optional<EnumFacing>, ImmutableList<BakedQuad>> quads;
private final ImmutableMap<TransformType, Pair<Baked, TRSRTransformation>> transforms;
private final ItemOverrideList overrides = new ItemOverrideList(Lists.<ItemOverride>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<String, IBakedModel> builder = ImmutableMap.builder();
for(Map.Entry<String, IBakedModel> 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<String, IBakedModel> parts)
{
this.location = location;
this.base = base;
this.parts = parts;
@ -120,22 +165,22 @@ public final class MultiModel implements IModel
ImmutableList.Builder<BakedQuad> 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<BakedQuad> 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.<EnumFacing>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<String, Pair<IModel, IModelState>> entry : parts.entrySet())
{
Pair<IModel, IModelState> 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())

View file

@ -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.<String, ITimeValue>of(),
ImmutableMap.of("missingno", (IClip)Clips.IdentityClip.instance),
ImmutableList.of("missingno"),

View file

@ -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<ResourceLocation, TextureAtlasSprite> bakedTextureGetter;
public AnimationItemOverrideList(IModel model, IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter, ItemOverrideList overrides)
{
this(model, state, format, bakedTextureGetter, overrides.getOverrides());
}
public AnimationItemOverrideList(IModel model, IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter, List<ItemOverride> 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;
}
}

View file

@ -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<T extends Entity & IAnimationProvider> extends ModelBase implements IEventHandler<T>
public class AnimationModelBase<T extends Entity> extends ModelBase implements IEventHandler<T>
{
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<T extends Entity & IAnimationProvider> 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<IModelState, Iterable<Event>> pair = ((IAnimationProvider)entity).asm().apply(timeAlive / 20);
Pair<IModelState, Iterable<Event>> 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);

View file

@ -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<T extends TileEntity & IAnimationProvider> extends FastTESR<T> implements IEventHandler<T>
public class AnimationTESR<T extends TileEntity> extends FastTESR<T> implements IEventHandler<T>
{
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<T extends TileEntity & IAnimationProvider> extends Fa
if(exState.getUnlistedNames().contains(Properties.AnimationProperty))
{
float time = Animation.getWorldTime(getWorld(), partialTick);
Pair<IModelState, Iterable<Event>> pair = te.asm().apply(time);
Pair<IModelState, Iterable<Event>> pair = te.getCapability(CapabilityAnimation.ANIMATION_CAPABILITY, null).apply(time);
handleEvents(te, time, pair.getRight());
// TODO: caching?

View file

@ -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<IAnimationStateMachine> ANIMATION_CAPABILITY = null;
public static void register()
{
CapabilityManager.INSTANCE.register(IAnimationStateMachine.class, new Capability.IStorage<IAnimationStateMachine>()
{
public NBTBase writeNBT(Capability<IAnimationStateMachine> capability, IAnimationStateMachine instance, EnumFacing side)
{
return null;
}
public void readNBT(Capability<IAnimationStateMachine> capability, IAnimationStateMachine instance, EnumFacing side, NBTBase nbt) {}
}, new Callable<IAnimationStateMachine>()
{
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> T getCapability(Capability<T> capability, EnumFacing facing)
{
if(capability == ANIMATION_CAPABILITY)
{
return (T)asm;
}
return null;
}
}
}

View file

@ -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();
}

View file

@ -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<BakedQuad> builder = ImmutableList.builder();
generateQuads(builder, node, modelState);
generateQuads(builder, node, this.state);
quads = builder.build();
}
// TODO: caching?
if(this.state != modelState)
{
ImmutableList.Builder<BakedQuad> builder = ImmutableList.builder();
generateQuads(builder, node, modelState);
return builder.build();
}
return quads;
}

View file

@ -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<EntityChest>()
{
@SuppressWarnings("deprecation")
public Render<EntityChest> 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<String, String> 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.<IModel, IModelState>of(base, TRSRTransformation.identity())
)
);
return new RenderLiving<EntityChest>(manager, new AnimationModelBase<EntityChest>(model, new VertexLighterSmoothAo(Minecraft.getMinecraft().getBlockColors()))
ResourceLocation location = new ModelResourceLocation(new ResourceLocation(MODID, blockName), "entity");
return new RenderLiving<EntityChest>(manager, new net.minecraftforge.client.model.animation.AnimationModelBase<EntityChest>(location, new VertexLighterSmoothAo(Minecraft.getMinecraft().getBlockColors()))
{
@Override
public void handleEvents(EntityChest chest, float time, Iterable<Event> 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.<String, ITimeValue>of(
"cycle_length", cycleLength
));
public boolean hasCapability(Capability<?> capability, EnumFacing facing)
{
return capability == CapabilityAnimation.ANIMATION_CAPABILITY;
}
@SuppressWarnings("unchecked")
public <T> T getCapability(Capability<T> 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> T getCapability(Capability<T> 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.<String, ITimeValue>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> T getCapability(Capability<T> capability, EnumFacing side)
{
if(capability == CapabilityAnimation.ANIMATION_CAPABILITY)
{
return (T)asm;
}
return super.getCapability(capability, side);
}
}
}

View file

@ -43,6 +43,12 @@
}*/
"model": "forgedebugmodelanimation:engine_ring"
}
}
},
"entity": [{
"model": "forgedebugmodelanimation:engine",
"submodel": {
"ring": { "model": "forgedebugmodelanimation:engine_ring" }
}
}]
}
}