You can use your debugger to step through the code or just continue, I was mainly interested in whether the methods were being called.
If you continue after the first breakpoint is hit, is the second one hit?
I don't like the look of this code. Automatically downloading mods at runtime is a potential security risk. A mod that has a "Pro" license type sounds like it could be a violation of Mojang's EULA. Your code uses Windows-only paths that won't work on other OSes.
Forge's blockstates format is optimised for use with properties that each have their own effect on the model (e.g. one property controls textures, another controls rotation), but it doesn't really handle the case of multiple properties affecting the model together (e.g. the combination of the variant and connection properties controls the texture for each side) unless you use fully-specified variants (like the vanilla format).
I think your situation is best handled by registering an IStateMapper so that the light and dark infusers use separate blockstates files, each of which specifies its own textures depending on the connection properties. This will achieve the nested behaviour you want.
To create the IStateMapper, create an instance of StateMap.Builder, call StateMap.Builder#withName with the variant property, call StateMap.Builder#withSuffix with a suffix like "_infuser" and then call StateMap.Builder#build. This will tell Minecraft to use the light_infuser.json and dark_infuser.json blockstates files instead of infuser.json.
Set a breakpoint on the line where you call EventBus#post and in the onDataGet method and run Minecraft in debug mode. Is either breakpoint hit?
Post the class where you call EventBus#post.
In future, please use Gist or Pastebin to post logs/crash reports (if applicable) and code with syntax highlighting. To get syntax highlighting on Gist, give each file the appropriate extension (.java for Java code). To get syntax highlighting on Pastebin, select the language from the dropdown at the bottom of the page.
It's much easier to read code with proper formatting and syntax highlighting.
Each key in the "variants" object must be either a fully-specified variant (e..g. "inventory,variant=light") or a property name (e.g. "variant").
Each property must have its own key in the "variants" object and contain a key for each possible value of the property (whose value is a variant). You can't nest one property (e.g. "north", "south", "east" or "west") inside another property's value (e.g. "ight" or "dark").
You can see examples of blockstates files with multiple properties here and here.
On a related note: In the EnumInfuser loop in ModBlocks.initClient, the final registerBlockModel call for each EnumInfuser value will overwrite the previous two calls made in the boolean loop. This makes those calls pointless.
You never assign a value to the field, so it's null when you pass it to EventBus#post; this causes the NullPointerException to be thrown.
Events aren't singletons, you should create a new instance every time you fire the event instead of trying to store a single instance in a field.
The only thing you need in your Event class is the data that's required by the event's subscribers (if any). All you need for it to be a valid event is to extend Event.
What is the purpose of this event? When is it fired? What do you expect subscribers to do with it?
It should be as simple as creating a class that extends (directly or indirectly) net.minecraftforge.fml.common.eventhandler.Event and then creating an instance of it and calling EventBus#post when you want to fire it.
Risugami's ModLoader no longer exists. Forge ModLoader (FML) was created to replace it, and now Forge and FML have been merged.
Forge's documentation explains how to set up a development workspace here.
There's a list of tutorials for 1.9.x/1.10.x here. 1.11.2 is fairly similar to 1.9.x/1.10.x and several of the tutorials in that thread have already been updated for it.
Hm, not exactly sure how to step through the code but I pressed the continue button and it just kept running as normal.
Use the Step Into, Step Over and Step Out buttons to step through the code. The documentation of your IDE's debugger should explain these in more detail.
I didn't see any errors, but this was before I started trying to compare code from other mods and use IItemHandler, I probably should have saved a previous version but I don't have a Github for it yet so maybe I will add that if this current attempt doesn't work.
You can create a local Git repository without pushing it to a remote repository like GitHub.
You're missing the World#setBlockToAir call in harvestBlock, though what you have should at least drop the item.
Put a breakpoint in each of the new methods and run Minecraft in debug mode, are they being called when you break the block?
IItemHandler is Forge's inventory API, a replacement for IInventory. Instead of implementing IInventory on your TileEntity and storing a collection of ItemStacks, you store an instance of IItemHandler and expose it via the Capability System.
The default IItemHandler implementation is ItemStackHandler, you can generally use or extend this.
First you need to ensure that the TileEntity isn't removed until after Block#getDrops is called. Look at Forge's patch to BlockFlowerPot for an example of this.
Then you need to add the TileEntity's contents to the drops list in Block#getDrops. Vanilla uses InventoryHelper#dropInventoryItems(World, BlockPos, IInventory) to drop the contents of a block's IInventory on the ground, I use this method to create a list of an IItemHandler's contents with the stacks randomly split (like the vanilla method).
If you aren't already using IItemHandler, start using it.
Could you link a Block and TileEntity pair that stores the facing in the TileEntity and uses Block#getActualState to set an EnumFacing property from this?
The closest I can see is BlockInfuser/TileEntityInfuser, but BlockInfuser doesn't override Block#getActualState.
I have some working examples of Blocks that set an EnumFacing property from a TileEntity here:
Does your TileEntity sync its EnumFacing field to the client in the update tag and packet?
There's no point in calling World#setBlockState with the actual state of a block, since only properties that are stored in metadata have their values stored in the chunk. Any properties whose values are set in Block#getActualState will be ignored by World#setBlockState/World#getBlockState. Forge's documentation has a page on block states (including an explanation of actual states) here.
There's no need to check for null before an instanceof check, instanceof will simply return false if the value is null.
In future, please use Gist or Pastebin to post logs/crash reports (if applicable) and code with syntax highlighting. To get syntax highlighting on Gist, give each file the appropriate extension (.java for Java code). To get syntax highlighting on Pastebin, select the language from the dropdown at the bottom of the page.
It's much easier to read code with proper formatting and syntax highlighting. The code formatting here is pretty bad even when it works.
The World#spawnParticle overloads all call IWorldEventListener#spawnParticle, which is implemented by ServerWorldEventHandler (the server-side IWorldEventListener) to do absolutely nothing.
To spawn particles on the logical server, you need to use one of the WorldServer#spawnParticle overloads. This sends a packet to all nearby clients telling them to spawn the specified particle(s).
0
You can use your debugger to step through the code or just continue, I was mainly interested in whether the methods were being called.
If you continue after the first breakpoint is hit, is the second one hit?
I don't like the look of this code. Automatically downloading mods at runtime is a potential security risk. A mod that has a "Pro" license type sounds like it could be a violation of Mojang's EULA. Your code uses Windows-only paths that won't work on other OSes.
0
Forge's blockstates format is optimised for use with properties that each have their own effect on the model (e.g. one property controls textures, another controls rotation), but it doesn't really handle the case of multiple properties affecting the model together (e.g. the combination of the variant and connection properties controls the texture for each side) unless you use fully-specified variants (like the vanilla format).
I think your situation is best handled by registering an IStateMapper so that the light and dark infusers use separate blockstates files, each of which specifies its own textures depending on the connection properties. This will achieve the nested behaviour you want.
To create the IStateMapper, create an instance of StateMap.Builder, call StateMap.Builder#withName with the variant property, call StateMap.Builder#withSuffix with a suffix like "_infuser" and then call StateMap.Builder#build. This will tell Minecraft to use the light_infuser.json and dark_infuser.json blockstates files instead of infuser.json.
0
Set a breakpoint on the line where you call EventBus#post and in the onDataGet method and run Minecraft in debug mode. Is either breakpoint hit?
Post the class where you call EventBus#post.
In future, please use Gist or Pastebin to post logs/crash reports (if applicable) and code with syntax highlighting. To get syntax highlighting on Gist, give each file the appropriate extension (.java for Java code). To get syntax highlighting on Pastebin, select the language from the dropdown at the bottom of the page.
It's much easier to read code with proper formatting and syntax highlighting.
0
Your blockstates file is invalid.
Each key in the "variants" object must be either a fully-specified variant (e..g. "inventory,variant=light") or a property name (e.g. "variant").
Each property must have its own key in the "variants" object and contain a key for each possible value of the property (whose value is a variant). You can't nest one property (e.g. "north", "south", "east" or "west") inside another property's value (e.g. "ight" or "dark").
You can see examples of blockstates files with multiple properties here and here.
On a related note: In the EnumInfuser loop in ModBlocks.initClient, the final registerBlockModel call for each EnumInfuser value will overwrite the previous two calls made in the boolean loop. This makes those calls pointless.
1
You never assign a value to the field, so it's null when you pass it to EventBus#post; this causes the NullPointerException to be thrown.
Events aren't singletons, you should create a new instance every time you fire the event instead of trying to store a single instance in a field.
The only thing you need in your Event class is the data that's required by the event's subscribers (if any). All you need for it to be a valid event is to extend Event.
What is the purpose of this event? When is it fired? What do you expect subscribers to do with it?
0
It should be as simple as creating a class that extends (directly or indirectly) net.minecraftforge.fml.common.eventhandler.Event and then creating an instance of it and calling EventBus#post when you want to fire it.
0
Risugami's ModLoader no longer exists. Forge ModLoader (FML) was created to replace it, and now Forge and FML have been merged.
Forge's documentation explains how to set up a development workspace here.
There's a list of tutorials for 1.9.x/1.10.x here. 1.11.2 is fairly similar to 1.9.x/1.10.x and several of the tutorials in that thread have already been updated for it.
0
Use the Step Into, Step Over and Step Out buttons to step through the code. The documentation of your IDE's debugger should explain these in more detail.
You can create a local Git repository without pushing it to a remote repository like GitHub.
0
Did you step through the code after the breakpoint was hit?
No, that shouldn't happen. Something strange is going on.
Do you get any errors?
You should switch to IItemHandler, but that shouldn't affect this situation.
Do you have a Git repository for this mod? I can try and debug it myself.
0
You're missing the World#setBlockToAir call in harvestBlock, though what you have should at least drop the item.
Put a breakpoint in each of the new methods and run Minecraft in debug mode, are they being called when you break the block?
IItemHandler is Forge's inventory API, a replacement for IInventory. Instead of implementing IInventory on your TileEntity and storing a collection of ItemStacks, you store an instance of IItemHandler and expose it via the Capability System.
The default IItemHandler implementation is ItemStackHandler, you can generally use or extend this.
0
First you need to ensure that the TileEntity isn't removed until after Block#getDrops is called. Look at Forge's patch to BlockFlowerPot for an example of this.
Then you need to add the TileEntity's contents to the drops list in Block#getDrops. Vanilla uses InventoryHelper#dropInventoryItems(World, BlockPos, IInventory) to drop the contents of a block's IInventory on the ground, I use this method to create a list of an IItemHandler's contents with the stacks randomly split (like the vanilla method).
If you aren't already using IItemHandler, start using it.
0
Could you link a Block and TileEntity pair that stores the facing in the TileEntity and uses Block#getActualState to set an EnumFacing property from this?
The closest I can see is BlockInfuser/TileEntityInfuser, but BlockInfuser doesn't override Block#getActualState.
I have some working examples of Blocks that set an EnumFacing property from a TileEntity here:
0
Does your TileEntity sync its EnumFacing field to the client in the update tag and packet?
There's no point in calling World#setBlockState with the actual state of a block, since only properties that are stored in metadata have their values stored in the chunk. Any properties whose values are set in Block#getActualState will be ignored by World#setBlockState/World#getBlockState. Forge's documentation has a page on block states (including an explanation of actual states) here.
There's no need to check for null before an instanceof check, instanceof will simply return false if the value is null.
In future, please use Gist or Pastebin to post logs/crash reports (if applicable) and code with syntax highlighting. To get syntax highlighting on Gist, give each file the appropriate extension (.java for Java code). To get syntax highlighting on Pastebin, select the language from the dropdown at the bottom of the page.
It's much easier to read code with proper formatting and syntax highlighting. The code formatting here is pretty bad even when it works.
2
You're casting the World to WorldServer, but you're still calling one of the overloads defined in the World class.
Use one of the following overloads:
Note the int argument between the position and offset arguments that controls how many particles are spawned.
0
The World#spawnParticle overloads all call IWorldEventListener#spawnParticle, which is implemented by ServerWorldEventHandler (the server-side IWorldEventListener) to do absolutely nothing.
To spawn particles on the logical server, you need to use one of the WorldServer#spawnParticle overloads. This sends a packet to all nearby clients telling them to spawn the specified particle(s).