-
Posts
5160 -
Joined
-
Last visited
-
Days Won
76
Everything posted by Choonster
-
I have a chunk capability that stores an energy value for each chunk. The Capability.IStorage implementation calls ChunkEnergy#setEnergy when reading from NBT, this in turn calls ChunkEnergy#onEnergyChanged which sends a packet to update all clients tracking the chunk with the new energy value. In 1.12.2, I used World#isBlockLoaded before getting the Chunk from the World to prevent an infinite recursion scenario where loading the chunk attempts to load the chunk. In 1.14.4, I'm using IWorld#chunkExists instead; but this returns true even when the chunk is being loaded. If I then call World#getChunk while the chunk is being loaded, this seems to result in a deadlock where the chunk loading never completes and the world never loads. The code on GitHub currently uses world.getChunk(x, z), but I've tried calling world.getChunk(x, z, ChunkStatus.EMPTY, false) just to see if it will return null or an empty chunk and this results in the same deadlock. It seems like I could use ChunkHolder#func_219299_i and ChunkHolder#func_219278_b to get the ChunkStatus of a chunk, but there don't seem to be any public methods to get a ChunkHolder and I'm reluctant to use internal APIs if there are public APIs available. Does anyone know if there's a way to determine whether a chunk is fully loaded without causing a deadlock if called during chunk loading?
-
The closest equivalents I can see are World#func_225319_b or WorldRenderer#markBlockRangeForRenderUpdate, though a lot of places that used to call World#markBlockRangeForRenderUpdate don't seem to call anything in its place now.
-
Forge's fluid system (including the forge:fluid model) was removed in 1.13 due to large changes in the Vanilla fluid system. Forge's new fluid system is still being worked on, you can see some of the progress in this PR and KingLemming's fork. Until then, you could look at Vanilla's waterloggable blocks (IWaterLoggable) where the block can exist in the same space as a fluid (usually water). Extended states were replaced by the model data system in this PR.
-
AbstractFurnaceTileEntity stores its IRecipeType (BLASTING, SMELTING or SMOKING) in the protected AbstractFurnaceTileEntity#recipeType field, so you could use reflection to access this instead of using those instanceof checks. This would also handle any modded furnace that extends AbstractFurnaceTileEntity.
-
You'll probably have to wait until Forge's fluid system rewrite is completed, I'm pretty sure the Vanilla system only really supports water.
-
HarvestDropsEvent not working as expected.
Choonster replied to Andrew Murdza's topic in Modder Support
Bus.FORGE is the default, so it doesn't need to be specified manually. -
[1.12 to 1.14] Make custom mobs spawn only at night (custom biome)
Choonster replied to Alex Sim's topic in Modder Support
It was made public again in this PR (1.14.4-28.0.37). Update Forge. -
[1.12 to 1.14] Make custom mobs spawn only at night (custom biome)
Choonster replied to Alex Sim's topic in Modder Support
It looks like spawning conditions are handled by EntitySpawnPlacementRegistry in 1.14. You need to call EntitySpawnPlacementRegistry.register with your EntityType and a predicate that determines the conditions under which it can spawn. Zombies and other hostile mobs use MonsterEntity::func_223325_c for the predicate, this checks the difficulty and the light level. -
[1.12.2] Only first fluid registered renders properly
Choonster replied to Lyinginbedmon's topic in Modder Support
I don't know exactly what your issue is, but I can point you to my 1.12.2 fluid code where I have several fluids with their own textures: initialisation and registration, model registration, blockstates file. -
It turns out that the constructor of the @Mod class is too early to call CapabilityManager#registerCapability as it uses the CapabilityManager#callbacks map, but this is only initialised between RegistryEvent.NewRegistry and RegistryEvent.Register being fired. Due to this, I kept the capability registration in FMLCommonSetupEvent and just added null protection to the IForgeItem#initCapabilities implementations. This fixed the crash. You can see the changes I made in this commit.
-
ForgeConfigSpec implements UnmodifiableConfig, have you tried calling UnmodifiableConfig#getOrElse on your ForgeConfigSpec instance? Note that if you've followed Forge's example and made your ForgeConfigSpec fields private, you'll need to create a public method in your config class that calls UnmodifiableConfig#get(String) on the appropriate ForgeConfigSpec instance.
-
[1.14.4] PlayerInteractEvent.RightClickBlock event not firing
Choonster replied to Tschipp's topic in Modder Support
This is a known issue.- 1 reply
-
- 1
-
Minecraft Version: 1.14.4 Forge Version: 28.0.19 Code: https://github.com/Choonster-Minecraft-Mods/TestMod3/tree/ba1306dd180514cc7dd135b21262f8eb72cdd305 Log: https://gist.github.com/Choonster/2ee4d06856ca409f85b89728e9ddd47e After updating to 1.14.4 and attempting to run the client (the first time since updating to 1.14), I encountered a crash due to LastUseTimeModelItem#initCapabilities being called when LastUseTimeCapability.LAST_USE_TIME_CAPABILITY was still null. It appears that an ItemStack of this Item is being created in Minecraft#populateSearchTreeManager, which is called towards the end of Minecraft#init. ClientModLoader.begin is called earlier in Minecraft#init to start loading mods, but this doesn't actually fire FMLCommonSetupEvent (the event that Capabilities are registered in) directly; instead it registers a resource reload listener that fires the event (and the other setup events). The initial reload that calls this listener doesn't happen until the very end of Minecraft#init (after Minecraft#populateSearchTreeManager). It feels counter-intuitive that IForgeItem#initCapabilities can be called before Capabilities have actually been registered, but is this a bug or is it intended behaviour?
-
It looks like the possible trades for each level of each profession are stored in VillagerTrades.field_221239_a (may have a deobfuscated name in newer mappings). The trades for each level are stored in an array, so you can probably create a new array with the both existing trades and your new trades and then replace the existing array in the profession's Int2ObjectMap.
-
This was fixed by this pull request for 1.14.3. Update to the latest 1.14.3 version of Forge.
-
1.12.2 how to add multiple recipes for 1 item?
Choonster replied to madmagic's topic in Modder Support
Recipes don't have to have the same name as their output item, you can call your recipes whatever you want. -
how to play a sound when right clicking in 1.12
Choonster replied to madmagic's topic in Modder Support
All of the sound-playing methods in the documentation are methods of the class mentioned in the header. e.g. The first three are methods of World, which means you need to call them on an instance of World. -
[1.13.2] [Solved] Config Array with Range?
Choonster replied to FireController1847's topic in Modder Support
You could probably use ForgeConfigSpec.Builder#define(String, T, Predicate<Object>) with a Predicate that checks if every integer in the array is within the appropriate range. The only downside I can see is that Forge will correct single number properties outside the defined range to the minimum or maximum of the range; but if any number in your array is outside the defined range, Forge will correct the entire property to the default array value. -
[1.14.3] Reusing data values within recipes
Choonster replied to Algorythmis's topic in Modder Support
Metadata doesn't exist in 1.13+. To copy damage (or any other value) from an ingredient to the output, you'll need a custom recipe type that overrides IRecipe#getCraftingResult. You can see an example of this here, with a JSON recipe that uses it here. -
I ended up initialising my SoundEvents in a method called from RegistryEvent.Register<Item> and storing them in a temporary Map until they're registered in RegistryEvent.Register<SoundEvent>. You can see this here.