-
Posts
33 -
Joined
-
Last visited
Everything posted by TheOnlyTrueEnte
-
I'm currently working on recipes for my custom paxel mod. Explanation with pictures: I created a custom recipe class for the recipe. The recipe accepts an axe, pickaxe, shovel and two sticks and yields a paxel. My recipe also works if the tools are damaged: the result is a damaged paxel. My problem is that when clicking on the recipe in the recipe book, it doesn't accept damaged items (or even undamaged, enchanted ones) from my inventory. Code of the 1.14.4 project for reference: In this version of the code, I hadn't written a proper json serializer yet so my recipe constructor is hardcoded to create the recipe for the golden paxel. This is probably more readable anyway. The method responsible for matching a recipe from the recipe book to my inventory seems to be IRecipe#getIngredients. Since Ingredient#test only tests for the ItemStack's Item and not other data though, I'm very confused as to why item stack's nbt matters there.
-
NoteBlock updates its INSTRUMENT property by calling NoteBlockInstrument#byState. This method is completely hardcoded. It would be nice if it instead did a lookup on a Map that modders can register their blocks to, for example. Currently, if you want your modded block to serve as a specific NoteBlockInstrument you have to intercept a NoteBlockEvent.Play and change its instrument there. This event is only fired when the NoteBlock is actually played and does not update the INSTRUMENT property. This sucks especially if you're using a resource pack to display the NoteBlock's instrument.
-
Hi there, I'm trying to render my custom entity's blockstate member with my own texture all over it but keeping the original alpha channel. If that's too hard I'll settle for rendering it in all white. I'm really new to GL11 and the closest I've gotten is this: GlStateManager.disableTexture(); //disables alpha as well GlStateManager.disableLighting(); GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F); blockrendererdispatcher.renderBlockBrightness(Blocks.TNT.getDefaultState(), 1.0F); But that completely disables the texture, including the alpha channel. If anyone could link any good resources to learn GL's basic function that would also be greatly appreciated.
-
No. If my TNT extends TNTBlock, dispensing Flint and Steel onto it will just spawn a vanilla TNTEntity. Here's an excerpt from IDispenseItemBehavior#init, of the OptionalDispenseBehavior for FLINT_AND_STEEL: if (blockstate.getBlock() instanceof TNTBlock) { TNTBlock.explode(world, blockpos); world.removeBlock(blockpos, false); } TNTBlock#explode is obviously a static method here so I can't do anything to sort of override it. EDIT: as of 1.14.4-28.1.92, this calls blockstate.catchFire which my TNT block can override.
-
Solved for my specific issue! My TNT just needed to override IForgeBlock#catchFire. Hi there, My mod adds new types of TNT and I would like Dispensers to be able to prime them with vanilla Flint and Steel. My problem is that DispenserBlock#registerDispenseBehavior(item, behavior) puts the specified behavior in a map with item as the key so if I register a new Behavior for Items.FLINT_AND_STEEL, the old vanilla behavior and/or behavior that another mod might have added gets overridden. Is there another way of doing it? I haven't found any sort of Dispenser event or Redstone event (although a Redstone event probably wouldn't work because I also need the exact slot of the dispenser that is being used). Cheers, TheOnlyTrueEnte
-
That's good to know, thanks. I managed to get it to work! EDIT: The fix (canceling the off-hand's event if the main hand's event stripped a log) now successfully prevents the offhand from placing dirt. If the offhand is holding an Ender Pearl, however, it is thrown regardless. I'll have to do some more testing tomorrow. Also, if another mod registers an event listener for the item in the off-hand and that listener is executed before mine, it will go through and I can't do anything against it.
-
Hi, I created a RightClickEvent to allow the player to strip my modded wood by right-clicking it with an axe. The problem is that if the player also has an item in their off-hand (e.g. dirt), that one is also used after the wood is stripped (e.g. the dirt is placed). The cause seems to be that the event is always for both hands even if one has already changed the result. I've tried every combination of setting event.useItem/useBlock/result to ALLOW/DEFAULT/DENY and calling event.setCancelled() but nothing helped. At the beginning of the method, event.getResult() always returns DEFAULT, so a special case there also doesn't help. My event is defined as: @SubscribeEvent public static void centeBlockStripping(PlayerInteractEvent.RightClickBlock event){ LOGGER.info("Event hand: "+event.getHand()); if(event.getItemStack().getItem() instanceof AxeItem){ if(event.getWorld().getBlockState(event.getPos()).getBlock() instanceof CustomLog) { stripWood(...); damageAxe(...); event.setResult(Event.Result.ALLOW); event.setUseItem(Event.Result.DENY); event.setUseBlock(Event.Result.DENY); } } } and every time I right click a block, the event is fired twice for each hand. Log: What am I doing wrong? Cheers
-
I'm creating a new type of dirt that I want the vanilla grass_block to be able to spread to. I could do this in custom_dirt#tick but I thought there was probably a way to do it better. I might also make grass be able to spread to soul sand, creating custom_soul_grass. The only way to do that is to add something to vanilla grass_block or soul_sand's tick which I don't know is possible.
-
I'm using Forge 1.14.4-28.1.0 I've been trying to figure out Forge's blockstate.jsons. I cannot get them to work even though I'm following the official docs closely. The block I'm trying them with is the acacia slab. The first thing I tried is have the "type" state change the textures. The model is correctly applied but the textures are not (the pink/black debug texture is shown): { "forge_marker": 1, "defaults": { "model": "block/pressure_plate_up" }, "variants": { "type": { "bottom": { "textures": { "texture": "block/black_wool" } }, "top": { "textures": { "texture": "block/blue_wool" } }, "double":{ "textures": { "texture": "block/red_wool" } } } } } In fact, not even this works, producing the same result: { "forge_marker": 1, "defaults": { "model": "block/pressure_plate_up", "textures": { "texture": "block/white_wool" } }, "variants": { "type": { "bottom": {}, "top": {}, "double":{} } } } This one breaks the model. Only the debug cube is shown. In fact I can't get any forge blockstate to work that doesn't have any states/variants, like cobblestone. { "forge_marker": 1, "defaults": { "model": "block/dirt" }, "variants": { "normal": [{}] } } What am I doing wrong? Thank you.
-
Hello everyone, on my laptop (Ubuntu), whenever I create a new project from a fresh mdk, there's a "<forge-version>-recomp.jar" in Project and External Dependencies, with correctly mapped variable names and comments. On my PC (Windows 10), there's always a "<forge-version>.jar" instead, with obfuscated variable/parameter names. I tried installing mappings from MCPBot but it looks like I'm doing it wrong and I can't find any helpful guide on how to do it right. Currently, I do this: 1. choose mapping at http://export.mcpbot.bspk.rs/ 2. in the build.gradle file of my project, in the minecraft block, replace the line "mappings channel: ..." with my chosen mapping, ex: "mappings = 'snapshot_20190912'" 3. run gradlew --refresh-dependencies The command line output even displays a line "New Dep: <my chosen mappings snapshot>" 4. refresh my project in Eclipse Nothing mush happens then, though. In my project's Project and External Dependencies, "mcp_snapshot-<version>.zip" appears but it only contains the mappings as .csv files. I must be misunderstanding something fundamentally because I haven't found any similar issues.
-
Static variables are fine but static initializers are weird because it isn't always apparent in what order values are initialized. In your case, for example, ItemList initializes items with their ItemGroups but ModItemGroup initializes itemgroups with their displayed Items. Well, which one's inizialized first? I mean I know its ModItemGroup but it's still not readable.
-
new ModItemGroup("name", ()->ItemList.moditem) doesn't just immediately evaluate the lambda and then pass its result. As you pointed out, it would evaluate to null and just pass null. Instead, it passes the entire function. The way I use IItemProvider in this case is as a function that returns an Item. The function is only evaluated in ModItemGroup#createIcon, inside of the ItemStack constructor (when it does ItemIn.asItem()). I just realized that this looks especially funky because you can directly pass IItemProvider to an ItemStack constructor, which is what I'm doing. It's easier to see what happens if you imagine that I use Supplier<Item> instead of IItemProvider and inside of createIcon I do: return new ItemStack(icon.get()); This way, it's apparent where the function is evaluated. I suggest that you read into Java Functional Interfaces such as Supplier<Item>. They're pretty sexy, especially for someone with a C++ background who really misses pointers sometimes.
-
[Solved] [1.13.2] Why is this code not working?
TheOnlyTrueEnte replied to Tameet's topic in Modder Support
Got it. -
I'm very new to Forge modding so take it with a grain of salt, but I have a static method ModItemGroup#initialize that initializes the fields. I call that method in the first line of my Item registry event listener. I hate that this prevents my ItemGroups from being final but I'm sure there's a way to inject them, similarly to how @ObjectHolder works.
-
The ItemStack constructor isn't the problem. When you do this: public static final ModItemGroup modItemGroup = new ModItemGroup("ModItemGroup", new ItemStack(ItemInit.moditem)); ItemInit.moditem hasn't been constructed yet. So its value is actually null and that's what gets passed to the ItemStack constructor. If the constructor was simply: this.item = ItemIn.asItem(); You'd get a NullPointerException because you can't do null.asItem(). You just can't create an ItemStack from moditem yet, there's no way around it, so you have to create it at a later time, like in ItemGroup#createIcon. The next logical step would be doing this: //don't do this it doesn't work public class ModItemGroup extends net.minecraft.item.ItemGroup { private Item icon; public ModItemGroup(String label, Item icon) { super(label); this.icon = icon; } @OnlyIn(Dist.CLIENT) @Override public ItemStack createIcon() { return new ItemStack(icon); } } You create an ItemStack in createIcon from the Item that you directly pass to your ModItemGroup's constructor. You still have the same problem though, moditem is null by the time the constructor's called and this.icon = icon just sets the Item icon to null. What you need is a reference to the Item that is updated when the Item is finally initialized. Java doesn't have references but the lambda ()->ItemList.moditem acts as one. If you evaluate it before moditem is inizialited, it returns null. If you evaluate it after it's initialized, such as in ItemGroup#createIcon, it correctly returns your item.
-
[Solved] [1.13.2] Why is this code not working?
TheOnlyTrueEnte replied to Tameet's topic in Modder Support
Try this: if ((event.getState().getBlock() instanceof BlockGravel)) { if (event.getHarvester() != null) { Item tool = event.getHarvester().getHeldItemMainhand().getItem(); if (tool == Items.STICK) { event.getDrops().add(new ItemStack(ItemList.test_item, 1)); event.setDropChance((float) 0.8); } } } -
Like Draco said, the ItemGroup constructor is called before your ItemInit.moditem has even been created. Generally, you can assume that ItemGroups are created before Items are. This is what I do to get around it: public class ModItemGroup extends net.minecraft.item.ItemGroup { private IItemProvider icon; public ModItemGroup(String label, IItemProvider icon) { super(label); this.icon = icon; } @OnlyIn(Dist.CLIENT) @Override public ItemStack createIcon() { return new ItemStack(icon); } } public static final ModItemGroup modItemGroup = new ModItemGroup("ModItemGroup", ()->(ItemInit.moditem)); Normally I would use Supplier<Item> here, but IItemProvider already does the same thing with better integration such as being able to be passed directly to an ItemStack's constructor. This doesn't care whether moditem has already been initialized when modItemGroup is created. It only needs to exist by the time modItemGroup.createIcon() is called. Either way though, static initializers are unpredictable and that's why I personally avoid them wherever possible.
-
[1.13.2] IItemColor help + Ore Dictionary
TheOnlyTrueEnte replied to Simon_kungen's topic in Modder Support
You need to register your IItemColors using the ColorHandlerEvent.Item event, fired on the MinecraftForge.EVENT_BUS. You don't need your item to implement IItemColor. -
What's the purpose of LazyLoadBase? I read its code but I don't understand how it's better than directly using Supplier<T>