Jump to content

[1.10.2] Animated Block is only animated in inventory


SuperHB

Recommended Posts

I'm currently trying to use the animation system to move the sentry gun back and forth which I got it to animate in my inventory, but when I place it down its just a static block. All I did was just copy the code from the MinecraftForge GitHub on this but I can't figure out why this is happening.

 

Here is the code:

 

Main

@Mod(modid = Refrence.MODID, name = Refrence.MODID, version = Refrence.VERSION)
public class Main {
@SidedProxy(clientSide = Refrence.CLIENT_PROXY, serverSide = Refrence.COMMON_PROXY)
public static CommonProxy proxy;

@Instance(Refrence.MODID)
public static Main instance;

@EventHandler
public void preInit (FMLPreInitializationEvent event) {

	TFCBlocks.init();
	TFCBlocks.register();

	proxy.init();

	ClientRegistry.bindTileEntitySpecialRenderer(TileEntitySentry.class, new AnimationTESR<TileEntitySentry>() {
		@Override
		public void handleEvents(TileEntitySentry te, float time, Iterable<Event> pastEvents) {
			super.handleEvents(te, time, pastEvents);
			te.handleEvents(time, pastEvents);
		}
	});
}

@EventHandler
public void init (FMLInitializationEvent event) {
	GameRegistry.registerTileEntity(TileEntitySentry.class, Refrence.MODID + ":sentry_tile");
}
}

 

ClientProxy

public class ClientProxy extends CommonProxy {
@Override
public void init () {
	TFCBlocks.registerRenders();
}

@Override
public IAnimationStateMachine load(ResourceLocation location, ImmutableMap<String, ITimeValue> parameters) {
	return ModelLoaderRegistry.loadASM(location, parameters);
}
}

 

TFCBlocks

public class TFCBlocks {
public static Block sentry;

public static void init () {
	sentry = new BlockSentry(Material.IRON).setUnlocalizedName("sentry").setCreativeTab(tab);
}

public static void register () {
	//registerBlock(sentry);
	GameRegistry.register(sentry.setRegistryName(sentry.getUnlocalizedName().substring(5)));
	ItemBlockSentry sen = new ItemBlockSentry(sentry);
	sen.setRegistryName(sentry.getRegistryName());
	GameRegistry.register(sen);
}

public static void registerRenders () {
	registerRender(sentry);
}

public static void registerRender (Block block) {
	ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 0, new ModelResourceLocation(Refrence.MODID + ":" + block.getUnlocalizedName().substring(5), "inventory"));
}
}

 

BlockSentry

public class BlockSentry extends Block implements ITileEntityProvider {
public BlockSentry(Material materialIn) {
	super(materialIn);
}

@Override
public boolean isFullCube (IBlockState state) {
	return false;
}

@Override
public boolean isOpaqueCube (IBlockState state) {
	return false;
}

@Nonnull
@Override
protected ExtendedBlockState createBlockState () {
	//return new ExtendedBlockState(this, new IProperty[] { Properties.StaticProperty }, new IUnlistedProperty[] { Properties.AnimationProperty });
	return new ExtendedBlockState(this, new IProperty[0], new IUnlistedProperty[] { Properties.AnimationProperty });
}

@Override
public boolean hasTileEntity (IBlockState state) {
	return true;
}

@Override
public TileEntity createNewTileEntity (World worldIn, int meta) {
	return new TileEntitySentry();
}
}

 

TileEntitySentry

public class TileEntitySentry extends TileEntity {
private final IAnimationStateMachine stateMachine;
private final VariableValue cycleLength = new VariableValue(4);
private final VariableValue clickTime = new VariableValue(Float.NEGATIVE_INFINITY);

public TileEntitySentry () {
	stateMachine = Main.proxy.load(new ResourceLocation(Refrence.MODID, "asms/block/sentry.json"), ImmutableMap.<String, ITimeValue>of("cycle_length", cycleLength, "click_time", clickTime));
}

public void handleEvents (float time, Iterable<Event> pastEvents) {
	for (Event event : pastEvents) {
		System.out.println("Event: " + event.event() + " " + event.offset() + " " + getPos() + " " + time);
	}
}

@Override
public boolean hasFastRenderer() {
	return true;
}

public void click (boolean sneaking) {
	if (stateMachine != null) {
		if (sneaking) {
			cycleLength.setValue(6 - cycleLength.apply(0));
		} else if (stateMachine.currentState().equals("default")) {
			float time = Animation.getWorldTime(getWorld(), Animation.getPartialTickTime());
			clickTime.setValue(time);
			stateMachine.transition("starting");
		} else if (stateMachine.currentState().equals("moving")) {
			clickTime.setValue(Animation.getWorldTime(getWorld(), Animation.getPartialTickTime()));
			stateMachine.transition("stopping");
		}
	}
}

@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
	if (capability == CapabilityAnimation.ANIMATION_CAPABILITY) return true;
	return super.hasCapability(capability, facing);
}

@Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
	if (capability == CapabilityAnimation.ANIMATION_CAPABILITY) return CapabilityAnimation.ANIMATION_CAPABILITY.cast(stateMachine);
	return super.getCapability(capability, facing);
}
}

 

ItemBlockSentry

public class ItemBlockSentry extends ItemBlock {
public ItemBlockSentry (Block block) {
	super(block);
}

@Override
public ICapabilityProvider initCapabilities (ItemStack stack, NBTTagCompound nbt) {
	return new ItemAnimationHolder();
}
}

 

ItemAnimationHolder

public class ItemAnimationHolder implements ICapabilityProvider {
    private final VariableValue cycleLength = new VariableValue(4);

    private final IAnimationStateMachine asm = Main.proxy.load(new ResourceLocation(Refrence.MODID, "asms/block/sentry.json"), ImmutableMap.<String, ITimeValue>of("cycle_length", cycleLength));

    public boolean hasCapability (Capability<?> capability, EnumFacing facing) {
    	return capability == CapabilityAnimation.ANIMATION_CAPABILITY;
    }

public <T> T getCapability (Capability<T> capability, EnumFacing facing) {
    	if (capability == CapabilityAnimation.ANIMATION_CAPABILITY) return CapabilityAnimation.ANIMATION_CAPABILITY.cast(asm);
        return null;
}
}

 

armatures/block/sentry_gun

{
"joints": {
	"back": { "2": [1.0] },
	"gun": { "0": [1.0] },
	"barrel": { "1": [1.0] }
},
"clips": {
	"default": {
		"loop": false,
		"joint_clips": {},
		"events": {}
	},
	"moving": {
		"loop": true,
		"joint_clips": {
			"back": [{
				"variable": "axis_y",
				"type": "uniform",
				"interpolation": "nearest",
				"samples": [1]
			},
			{
				"variable": "angle",
				"type": "uniform",
				"interpolation": "linear",
				"samples": [
				0, 120, 240,
				0, 120, 240,
				0, 120, 240,
				0, 120, 240
				]
			}],
			"gun": [{
                    "variable": "axis_y",
                    "type": "uniform",
                    "interpolation": "nearest",
                    "samples": [1]
                },
                {
                    "variable": "angle",
                    "type": "uniform",
                    "interpolation": "linear",
                    "samples": [
                    0, 120, 240,
                    0, 120, 240,
                    0, 120, 240,
                    0, 120, 240
                    ]
                }],
                "barrel": [{
                    "variable": "axis_y",
                    "type": "uniform",
                    "interpolation": "nearest",
                    "samples": [1]
                },
                {
                    "variable": "angle",
                    "type": "uniform",
                    "interpolation": "linear",
                    "samples": [
                    0, 120, 240,
                    0, 120, 240,
                    0, 120, 240,
                    0, 120, 240
                    ]
                }]
		},
		"events": {
			"0.5": "boop"
		}
	}
}
}

 

asms/block/sentry

{
    "parameters": {
    	"world_to_cycle": [ "/", "#cycle_length"],
    	"round_cycle": [ "compose", [ "R", "#cycle_length" ], "#click_time" ],
    	"end_cycle": [ "-", "#round_cycle" ]
    },
    "clips": {
        "default": "tfc:block/sentry_gun@default",
        "starting": [ "trigger_positive", "#default", "#end_cycle", "!transition:moving" ],
        "moving": [ "apply", "tfc:block/sentry_gun@moving", "#world_to_cycle" ],
        "stopping": [ "trigger_positive", "#moving", "#end_cycle", "!transition:default" ]
    },
    "states": [
        "default",
        "starting",
        "moving",
        "stopping"
    ],
    "transitions": {
        "default": "starting",
        "starting": [ "moving" ],
        "moving": "stopping",
        "stopping": "default"
    },
    "start_state": "moving"
}

 

blockstate/sentry

{
"forge_marker": 1,
    "variants": {
        "normal": [{
        	"model": "tfc:sentry",
            "submodel": { "gun": { "model": "tfc:sentry_gun" } },
            "textures": { "color": "tfc:blocks/sentry_blue" }
        }],
        "inventory": [{
        	"model": "tfc:sentry",
        	"submodel": { "gun": { "model": "tfc:sentry_gun" } },
        	"textures": { "color": "tfc:blocks/sentry_blue" }
        }]
    }
}

 

Link to comment
Share on other sites

You need to clean your code up.

I see you have client-only code, in your main.

ClientRegistry.bindTileEntitySpecialRenderer(TileEntitySentry.class, new AnimationTESR<TileEntitySentry>(). Hint is in the Client part of the method.

Your ClientProxy barely does anything related to rendering. Client is the only side that handles rendering. Do anything with rendering on the server-side, and oooops, crash.

You also need to do as the guide shows, and create a new Entity, for your Tile.

 

 

Also:

ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 0, new ModelResourceLocation(Refrence.MODID + ":" + block.getUnlocalizedName().substring(5), "inventory"));

*Eye twitch*

In your IDE:

[*]Simply search for the interface "IForgeRegistryEntry"

[*]Read the documentation for RegistryNames

Also previously known as eAndPi.

"Pi, is there a station coming up where we can board your train of thought?" -Kronnn

Published Mods: Underworld

Handy links: Vic_'s Forge events Own WIP Tutorials.

Link to comment
Share on other sites

You need to clean your code up.

I see you have client-only code, in your main.

ClientRegistry.bindTileEntitySpecialRenderer(TileEntitySentry.class, new AnimationTESR<TileEntitySentry>(). Hint is in the Client part of the method.

Your ClientProxy barely does anything related to rendering. Client is the only side that handles rendering. Do anything with rendering on the server-side, and oooops, crash.

You also need to do as the guide shows, and create a new Entity, for your Tile.

 

 

Also:

ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(block), 0, new ModelResourceLocation(Refrence.MODID + ":" + block.getUnlocalizedName().substring(5), "inventory"));

*Eye twitch*

In your IDE:

[*]Simply search for the interface "IForgeRegistryEntry"

[*]Read the documentation for RegistryNames

 

I've created an Entity for it and looked through the forge code and I don't see how the Entity connects with the Block. Here is the code I've added:

 

ModelLoader.setCustomModelResourceLocation(Item.REGISTRY.getObject(new ResourceLocation(Reference.MODID + ":" + sentry.getUnlocalizedName().substring(5))), 0, new ModelResourceLocation(Reference.MODID + ":" + sentry.getUnlocalizedName().substring(5), "inventory"));

 

ClientRegistry.bindTileEntitySpecialRenderer(TileEntitySentry.class, new AnimationTESR<TileEntitySentry>() {
		@Override
		public void handleEvents(TileEntitySentry te, float time, Iterable<Event> pastEvents) {
			super.handleEvents(te, time, pastEvents);
			te.handleEvents(time, pastEvents);
		}
	});

	EntityRegistry.registerModEntity(EntitySentry.class, "entity_sentry", 0, Main.instance, 54, 20, true);
	RenderingRegistry.registerEntityRenderingHandler(EntitySentry.class, new IRenderFactory<EntitySentry>() {
		@Override
		public Render<EntitySentry> createRenderFor(RenderManager manager) {
			ResourceLocation location = new ModelResourceLocation(new ResourceLocation(Reference.MODID, "sentry"), "entity");

			return new RenderLiving<EntitySentry>(manager, new AnimationModelBase<EntitySentry>(location, new VertexLighterSmoothAo(Minecraft.getMinecraft().getBlockColors())) {
				public void handleEvents(EntitySentry sentry, float time, Iterable<Event> pastEvents) {
					sentry.handleEvents(time, pastEvents);
				}}, 0.5F) {
				protected ResourceLocation getEntityTexture(EntitySentry entity) {
					return TextureMap.LOCATION_BLOCKS_TEXTURE;
				}
			};
		}
	});

 

public class EntitySentry extends EntityLiving {
private final IAnimationStateMachine asm;
private final VariableValue cycleLength = new VariableValue(getHealth() / 6);

public EntitySentry (World worldIn) {
	super(worldIn);

	setSize(1, 1);

	asm = Main.proxy.load(new ResourceLocation(Reference.MODID, "asms/block/sentry.json"), ImmutableMap.<String, ITimeValue>of("cycle_length", cycleLength));
}

public void handleEvents (float time, Iterable<Event> pastEvents) {}

@Override
public void onEntityUpdate() {
	super.onEntityUpdate();

	if (worldObj.isRemote && cycleLength != null) cycleLength.setValue(getHealth() / 5);
}

@Override
protected void applyEntityAttributes() {
	super.applyEntityAttributes();
	getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(60);
}

@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
	if (capability == CapabilityAnimation.ANIMATION_CAPABILITY) return true;
	return super.hasCapability(capability, facing);
}

@Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
	if (capability == CapabilityAnimation.ANIMATION_CAPABILITY) return CapabilityAnimation.ANIMATION_CAPABILITY.cast(asm);
	return super.getCapability(capability, facing);
}
}

 

I also added this to the sentry blockstate

"entity": [{
            "model": "tfc:sentry",
            "submodel": { "gun": { "model": "tfc:sentry_gun" } }
        }]

Link to comment
Share on other sites

The "connection" is made here:

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()))

 

The code -is- hard to read. It's dynamic in places, like here (blockName is, oddly enough, the name of the block the entity is supposed to be rendered as  ;) ), and then hard-coded names in other places.

 

I can't help much more atm, as I'm not too familiar with this type of rendering, though I'll probably sit down and tear the ModelAnimationDebug into their own proper damned classes, to get a better overview of it, in a few hours.

 

 

Oh, and once again:

*Eye twitch* x2

Fix that, please excuse my language, completely redundant, moronic, atrocious and gratuitous use of

modid + ":" + getUnlocalizedName().substring()

.

You have to use

setRegistryName(name)

for blocks and items. Instead of all that modid & substringing, just use "item(or block).getRegistryName()" and you are done.

getRegistryName() already returns "modid:name" for you. Just be sure to set the registryName first, then if you want the unlocalized name to mirror that, use getRegistryName().toString. Registry name is what you use for saying what is what, unlocalized name is purely to describe it in various languages.

"...Unlocalized names have NOTHING to do with unique modifiers."-Docmentation of setRegistryName().

I don't fault you for using it, I fault whatever piece of proverbial waste that keep producing tutorials that use that method.

Also previously known as eAndPi.

"Pi, is there a station coming up where we can board your train of thought?" -Kronnn

Published Mods: Underworld

Handy links: Vic_'s Forge events Own WIP Tutorials.

Link to comment
Share on other sites

The "connection" is made here:

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()))

 

The code -is- hard to read. It's dynamic in places, like here (blockName is, oddly enough, the name of the block the entity is supposed to be rendered as  ;) ), and then hard-coded names in other places.

 

I can't help much more atm, as I'm not too familiar with this type of rendering, though I'll probably sit down and tear the ModelAnimationDebug into their own proper damned classes, to get a better overview of it, in a few hours.

 

 

Oh, and once again:

*Eye twitch* x2

Fix that, please excuse my language, completely redundant, moronic, atrocious and gratuitous use of

modid + ":" + getUnlocalizedName().substring()

.

You have to use

setRegistryName(name)

for blocks and items. Instead of all that modid & substringing, just use "item(or block).getRegistryName()" and you are done.

getRegistryName() already returns "modid:name" for you. Just be sure to set the registryName first, then if you want the unlocalized name to mirror that, use getRegistryName().toString. Registry name is what you use for saying what is what, unlocalized name is purely to describe it in various languages.

"...Unlocalized names have NOTHING to do with unique modifiers."-Docmentation of setRegistryName().

I don't fault you for using it, I fault whatever piece of proverbial waste that keep producing tutorials that use that method.

 

Sorry about that, I just used MrCrayFish's old tutorial around a year ago to update another mod and I just stuck with that format ever since. I'll switch as soon as I get this to work.

Link to comment
Share on other sites

You won't be ABLE to get it to work without switching.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Link to comment
Share on other sites

I feel like I should add, he wasn't saying that changing to registry names would fix everything, he was saying that even if everything else was perfect, it wouldn't work until you switched to registry names.  So basically, don't stop looking for answers yourself because that change didn't fix everything.

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.