-
Posts
29 -
Joined
-
Last visited
Recent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
Blazer Nitrox's Achievements

Tree Puncher (2/8)
2
Reputation
-
[1.15.2] Registering a custom texture atlas' reload listener
Blazer Nitrox replied to Blazer Nitrox's topic in Modder Support
I... well, that worked. I'm not exactly a fan, but that worked. I'll have to dig into this a bit more and see if there isn't some way an event can be added for this kind of stuff, because despite what Google turned up I can't imagine I'm the only one doing this kind of thing, and doing it this way just... ew. -
When you say touching, do you mean which side they're bumping against, or which side they're clicking on? For clicking on, there's an event that gets fired (PlayerInteractEvent) that includes the face of the block they interacted with. Or, if you want a block to do something depending on which face the player interacts with, the Block class has onBlockActivated which takes a BlockRayTraceResult, which contains the side of the block that was clicked. For which side a player has run in to, that's a bit tricker. I don't think there's any event which gets fired off for that, so the easiest way would be to check PlayerTickEvent or some other similar event and just see if a player is colliding with any blocks, and then from there it'd be pretty simple (i.e. if the player is colliding with a block in the +x direction, then they must be touching the western face (since the block is to their east, the player is to the block's west)).
-
As the title says. A few months ago I had to mess around with creating my own texture atlas in order to render some GUI elements. A problem I ran into then, that didn't really fit the direction of the initial thread (which I'm also not really willing to necro at this point) is that despite the atlas registering itself as a reload listener with the texture manager, it doesn't get loaded at start up. It does, however, automatically reload any time a reload request is sent (either through changing resource packs or via F3+T). My interim solution was to simply request a reload in FMLLoadComplete. This is what we in the business call a "dumb solution." So: Where am I supposed to be registering the reload listener? I've been doing it in FMLClientSetup, but that was apparently too late, and the texture manager had already loaded (and for some reason doesn't like auto-loading any listeners that get added when they're added). I tried doing it in ModelBake, but that was also too late it seems. Near as I can tell, the TextureStitchEvent for each vanilla atlas is fired after FMLClientSetup, but before FMLLoadComplete. All of my searching both here and across Google has turned up nothing. What am I missing here?
-
There are absolute gods out there who occasionally make a TL;DR of the Forge changes and how to update to the newest version. 1.16 is still hot off the presses so it'll probably be a bit, but you can always download the MDK and troll through the provided code; except in rare circumstances (1.7 to 1.8, and 1.12 to 1.13) the changes are usually pretty small.
-
1a) Forge 1.12 is no longer supported, as in nobody on this forum is working on the 1.12 version, and so if you want support here you need to use a newer Forge version (most mods I've seen are updated to 1.15; you might give that a try.) 1b) Your thread was locked by a mod for the above reason 2) If you want to use 1.12 mods, I'd recommend downloading from CurseForge; if you need support with your mod setup, go over to the official Minecraft Forums. I'm not sure if they will be able to help you, but it's worth a try.
-
[1.15.2] Questions regarding dynamically-generated GUIs
Blazer Nitrox replied to Blazer Nitrox's topic in Modder Support
Right, and that's how I've been doing it. I think you actually might have touched on the underlying problem... data structures have always kind of confused me for some reason, and I think part of the problem is in some ways I'm still thinking of this as a tree when in reality what I need is a graph, just with a pseudo-root node. -
[1.15.2] Questions regarding dynamically-generated GUIs
Blazer Nitrox replied to Blazer Nitrox's topic in Modder Support
@Draco18s I took another look at the advancements screen and realized I was a complete moron lol. I had been avoiding doing a proper parent/child hierarchy because I want the player to be able to loop around the tree like so: (excuse the terrible quality, I threw this together in like 2 minutes in Paint because I didn't feel like waiting for GIMP to load) At the time, I had thought that a parent/child hierarchy wouldn't be capable of this because the last node in the sequence (top right) wouldn't have it's parent node active, and so it would think that it couldn't be activated. And I only just now realized that when the player tries to activate the node I could just... check if any child nodes are activated as well. All of this is to say that I've been a miserable fool who wasted his time because his solution was only half-baked. Nice. -
[1.15.2] Questions regarding dynamically-generated GUIs
Blazer Nitrox replied to Blazer Nitrox's topic in Modder Support
Under normal circumstances I would have done it that way, however I know that over time I'm going to be adding nodes to the tree (and potentially letting other mods add nodes to the tree as well), so I want to be able to programmatically add the nodes to the tree, meaning I won't know their textures or positions until they are registered. While it does mean I have to do more work in building the screen, theoretically it will also allow me to simply register a new node without having to modify the tree itself. It would also potentially allow me to create a tool later on which allows me to visually build the tree out and then simply export it as a JSON which the mod could then load, although it'll be a looong time before I pursue that route. -
[1.15.2] Questions regarding dynamically-generated GUIs
Blazer Nitrox replied to Blazer Nitrox's topic in Modder Support
Okay, having taken a bit to mess around with everything, I think I understand how I need to go about this. I did notice that SpriteUploader doesn't seem to have any markers for being called on reload, is there some way I should be registering it with the resource manager, or does it take care of that itself somewhere that I'm not seeing? There certainly doesn't appear to be any events I can attach to for registration or to manually call reload(), nor does TextureManager provide any such functionality. -
[1.15.2] Questions regarding dynamically-generated GUIs
Blazer Nitrox replied to Blazer Nitrox's topic in Modder Support
I hadn't even thought of that, but since it would have to grab each advancement's icon as it draws, that could be very useful. Good call -
[1.15.2] Questions regarding dynamically-generated GUIs
Blazer Nitrox replied to Blazer Nitrox's topic in Modder Support
Oh, hey! In the process of updating my MCP mappings I noticed that for some reason Forge was claiming it was 1.15 (and downloading Minecraft 1.15), but it was using the 1.14 MCP mappings, so I had no idea that AbstractGui#blit had a version which took a TextureAtlasSprite. So SpriteUploader seems to do exactly what I was originally expecting, with the added bonus of being able to be called whenever the resource engine reloads. That is very useful, although SpriteUploader#getSprite is set to protected, limiting its use pretty drasically IMHO. I assume the idea is that I would ask it to bind the texture atlas and then access the atlas directly from there. As far as checking the rendering thread, I figured that the relevant methods would always be called on the rendering thread, but since bindTexture does it I figured it wouldn't hurt. All of this has been extremely helpful, thanks a bunch! -
[1.15.2] Questions regarding dynamically-generated GUIs
Blazer Nitrox replied to Blazer Nitrox's topic in Modder Support
Okay, I did some poking around with AtlasTexture, and I think I figured out how to do what I need to. I'm going to record it here for future generations, and as a second post because it just doesn't make sense to me to combine this with the above, since they're mostly unrelated (and the separation will help identify this as me explaining what I think I need to do). AtlasTexture texture = new AtlasTexture(new ResourceLocation(MODID, "atlas")); Stream<ResourceLocation> stream = list.stream(); //We get a stream of all of the textures we want, probably using Collection#stream() SheetData data = texture.func_229220_a_((IResourceManager) Minecraft.getInstance().getTextureManager(), stream, Minecraft.getInstance().getProfiler(), 0); //Last argument is mipmap level, we use 0 map.upload(data); So, first I must actually create a new AtlasTexture, passing in a ResourceLocation which will act as a registry name. Then, to actually generate the stitched texture, I must call AtlasTexture#func229220_a_. It seems I should pass in Minecraft.getInstance().getTextureManager() (which I can do because I'm specifically doing this on Dist.CLIENT) for the first argument, a Stream containing the ResourceLocation's of all of the textures I want to stitch (so this will be done after all of the nodes are registered, no surprise there), an IProfiler (whatever that is, it seems to be used to track the progress of the texture stitching), and an integer mipmapping level (I would assume I'd use either 0 or 1, since I won't need mipmapping for a GUI I don't think). I would capture the output of this and pass it to AtlasTexture#upload, which would actually create the texture information I would then use for drawing. At this point, the AtlasTexture is ready for use. if (!RenderSystem.isOnRenderThread()) { RenderSystem.recordRenderCall(() -> { manager.func_229263_a(texture.func_229223_g_(), texture); texture.func_229148_d_(); }); } else { textureManager.func_229263_a(texture.func_229223_g_(), texture); texture.func_229148_d(); } When we first start drawing, we have to bind the texture. First, we must ensure we are actually on the rendering thread, and ask the rendering thread to do it if we aren't. Then we call TextureManager#func_229263_a, which takes two arguments, a ResourceLocation we want to use as a key for our AtlasTexture and the AtlasTexture itself. We can cheat the first argument here by calling AtlasTexture#func_229223_g_, which is essentially getRegistryName. This will set up our texture so it's ready to be bound to OpenGL (the above is ripped directly from TextureManager#bindTexture). We then call Texture#func229148_d, which actually binds the texture. ((I would provide a code example, except that Screen doesn't seem to provide any way to draw textures using UV coordinates which is all TextureAtlasSprite provides, and directly drawing via OpenGL requires calling Tessellator to get a BufferBuilder, and none of the methods in BufferBuilder (or, for that matter, Screen) have been deobfuscated yet.)) Now, in order to draw a texture from the Atlas onto the GUI, we call AtlasTexture#getSprite and pass in the key for the particular texture we want. That returns a TextureAtlasSprite, which contains the coordinates of our texture on the Atlas in absolute pixels as well as the relative min/max UV coordinates of our texture. Asking OpenGL to draw the part of the texture from min UV to max UV will draw our chosen texture and only that texture. -
[1.15.2] [SOLVED] Creating Custom Recipes for own Crafting-System
Blazer Nitrox replied to Skyriis's topic in Modder Support
I don't know of any tutorials which really lay it out for 1.15, but the Forge docs are helpful. First thing you'll need is a class which implements IRecipe<C extends IInventory>. When you create the recipe JSON (i.e. a crafting table recipe), that JSON will get converted into one of these objects. All the JSON says is what should be used as inputs and what should be used as outputs. Your object is a code representation of that data, which provides methods for getting the input list, checking if a given inventory matches your crafting requirements, getting the result of the crafting, and so on. Once you have that, you will need a factory which will take the provided JSON and convert it into your IRecipe object. The factory should extend ForgeRegistryEntry<IRecipeSerializer<?>> and implement IRecipeSerializer<((whatever your IRecipe class is))>. The factory will have methods for getting the recipe from either JSON or from the network, and will produce your IRecipe object. I hope I've helped to clarify some. As I said, the docs are a great resource (when they actually have what you're looking for, that is), and a lot of what my code is based on what I've read from the docs, examples I've found online, or just trolling through Minecraft's code until I find what I'm looking for. -
[1.15.2] Questions regarding dynamically-generated GUIs
Blazer Nitrox replied to Blazer Nitrox's topic in Modder Support
That's what I'm doing, sorry I didn't make that clear. As part of the node's data I've got the position and the resource location for the appropriate texture. My main concern was that since I won't know where the node will be located until it gets registered I can't just include the path as part of the background texture, so I would have to dynamically draw it. I suspected this would be the case, but thanks for confirming it. I assume I can still use Screen for a convenient way to access the GUI, and then override the various rendering methods in order to actually draw what I need? Side note: how did you code-ify `Screen`? -
Okay, so admittedly this is a really complex thing I'm trying to do, but I figure I'd learn some things along the way, so I decided to give it a shot. My goal is to recreate something like a skill tree in Minecraft. Specifically, my inspiration comes from the Passive Skill Tree in Path of Exile. I definitely do NOT expect to replicate the kind of complexity they've got, as the skill tree has evolved over the course of many years. I've (mostly) figured out my implementation for the skill tree, and now I need to have a GUI allowing the player to actually allocate their skill points. This, unfortunately, seems to be much harder than the tree implementation itself, while also being extremely important to using the tree (I suppose I could implement the whole thing using commands, but I'm going to have to create a GUI at some point so I might as well ask now). Currently, I'm trying to future-proof by using a custom registry for my SkillNodes. While this will allow me to easily add nodes programmatically (and will allow other mods to expand upon the skill tree), it also means that I have no way of knowing what nodes will need to be drawn to the tree at compile time, so I have to dynamically generate the GUI. I likewise have no way of knowing what positions I will need to draw the nodes' textures at, which means I won't know until runtime how long I will need to make the paths between each node. So, here are my questions: 1. I expect I will need to take advantage of Minecraft's built-in texture stitching, that way I don't have to rebind the texture every time I draw a node. Near as I can tell, there is no built-in GUI TextureAtlas, so I would need to create my own. How would I go about doing that, and would it need to be registered somewhere in order to still fire TextureStitchEvents? 2a. Since I also don't know each node's position until runtime, I will need to dynamically draw the paths between them, which means I won't know the lengths of each path and therefore can't just draw a texture 1:1 between each node. 2b. I would like to make the paths straight lines between each node, which means I could potentially be dealing with diagonals as well. Can `Screen` handle either of these scenarios, or would I need to directly access OpenGL? This situation is something I'm not very experienced with at all, so please bear with me. I'll probably be asking several more questions to make sure I understand what I need to do here. And as I said, I know I'm probably biting off more than I can chew, but I find that I learn best by bodging a solution together at first and then rewriting it with the knowledge I gained.