-
Posts
75 -
Joined
-
Last visited
Everything posted by JayZX535
-
Hey all, I've got a few theoretical questions pertaining to an in-game mod manual. I've seen a lot of mods (especially tech ones) implementing their own lore/guide books, so that the player doesn't have to constantly toggle back and forth with the wiki to figure out what they're doing. The mod I'm working on has quite a bit of complexity to it, so I'd like to implement something similar-- a book you can refer back to if you're curious about how something works. There are a couple of caveats about how I'd like to do that, though, and I'm wondering how possible/easy/efficient they'd be to implement. First off, I'd like to make the info reveal a bit at a time as the player discovers stuff-- sort of like how the advancement system works. And secondly, I'd like to tie the information to the player itself, so if they die and lose their book, they can make a new one and the information is still there. (lore-wise, the book is considered to be magic and soul-bound). My first thought was that the capability system is probably the way to go. However, this book has the potential to hold a lot of unlockable segments. So for example, you might unlock the general category for an entity, which leads you to 5/6 more detailed categories about its regional traits, which could lead to even more details that unlock separately under each of those categories, depending on how much this player learns about the entity. It's a tree, much like the advancement system. So if I put that into a capability, I feel like it's just going to be a lot of "has the player unlocked this? y/n" booleans. That might not be bad? But I'm curious if there'd be a more efficient way of doing this, or if I just do need to store everything in a capability with a lot of booleans. Also, is it probably best to just store all the lore translations in the lang file the way advancements are, even if they're longer blocks of text (like, whole paragraphs/multiple paragraphs)? Or should I try to set up a different system of, say, storing them in .json files or something and have some other way of indicating which language they are? It's worth noting that I'm not locked into using the 1.14 update for this. If 1.15 introduces any changes that would make this easier, I'm not opposed to waiting until I upgrade the mod to add this in. Anyway, I'm not sure if I'm on the right track with this idea or not, but I figured I'd try and get some feedback on it before I start practically implementing it, so that if I do need to make tweaks I can do it while I'm still theory-crafting in the first place. Thank you for your time!
-
[1.14.4] Syncing rendered held item movement with head?
JayZX535 replied to JayZX535's topic in Modder Support
Hey again TGG, Thank you so much for the advice (and validation that this is heckin confusing haha). After a lot of fiddling, I was finally able to figure out the string of issues that was causing problems. In case anyone else ends up finding this later in search of help, here's what I ended up doing to solve my issues. Firstly, as it turns out you can't just use the yaw of the head, since that doesn't account for the model rotation. The headNetYaw variable calculates that difference out, so unless you mirror that rotation, you're better off using the variable itself. So I switched back to that method. To get around the issue of having multiple poses, some with fixed head position and some with dynamic, I built in some methods to the model class to check the entity's pose and return the proper value for the head position. I designed them to return either the raw version of the variable (needed for the item rotation), or the calculated one (needed for the rotation of the actual model parts), which allowed me to ensure that the proper result would be returned in both cases. This avoids the issue of having to write up a checker code within the item renderer itself, and that way I only have to worry about changing one set of code if I make any tweaks. Lastly, I finally figured out the biggest stumper, which was the fact that the rotation was still crooked even with the synchronized method. I tested each one individually by forcibly returning zero on the two I wasn't using, and determined that individually, they were all doing what they should be. However, they were messing up when combined. As it turned out, I had the order of rotation different on the item renderer (pitch > yaw > tilt) than on the entity model (tilt > yaw > pitch). Changing the rotations on the item class to match the order of the ones on the entity model solved the problem. So it did indeed come down to the order of transformation in the end. Definitely one of the tripper problems I've dealt with, but I'm happy to report I finally have it solved. Thank you guys again for your help! -
[1.14.4] Syncing rendered held item movement with head?
JayZX535 replied to JayZX535's topic in Modder Support
Hmmm. That's sort of what I was trying to do? I was attempting to compensate with the different pivot point of the head and item by setting the item to the head's rotation point, rotating it, and then positioning it at the mouth from there. Is the pivot point of the item the same as its origin? If not that could be screwing it up... Here's a more detailed breakdown of what this is (or is supposed to) do... float rotMultiplier = (float)Math.PI / 180F; GlStateManager.translatef((this.getEntityModel().getHead().rotationPointX / 16F), (this.getEntityModel().getHead().rotationPointY / 16F), (this.getEntityModel().getHead().rotationPointZ / 16F)); Sets a standardized rotation amount (and I'm not sure if this is correct, but it's the inverse of the calculations used to set the head animations for the entity model, and it looks like the item rotations should take the actual amounts-- so this should reverse it?), and then sets the item to the rotation point of the head. float calcHeadPitch = this.getEntityModel().getHead().rotateAngleZ / rotMultiplier; GlStateManager.rotatef(calcHeadPitch, 1.0F, 0.0F, 0.0F); float calcHeadYaw = this.getEntityModel().getHead().rotateAngleY / rotMultiplier; GlStateManager.rotatef(calcHeadYaw, 0.0F, 1.0F, 0.0F); float calcHeadTilt = this.getEntityModel().getHead().rotateAngleX / rotMultiplier; GlStateManager.rotatef(calcHeadTilt, 0.0F, 0.0F, 1.0F); Gets the X, Y, and Z rotation values from the head and applies them to the item. GlStateManager.translatef(0.001F, 0.1F, -0.3F); GlStateManager.rotatef(-90.0F, 1.0F, 0.0F, 0.0F); this.itemRenderer.renderItem(itemstack, entityIn, TransformType.GROUND, false); Translates the item to where it should be in the dog's mouth, rotates it 90 degrees (to make it lay flat), and then renders it. Note, the TransformType.GROUND does throw a deprecation error, which leads me to net.minecraftforge.client.extensions.IForgeBakedModel.handlePerspective(TransformType cameraTransformType) instead, but I'm trying to figure out how to actually use that? I'm not sure if that's what's causing the issue or not but it's worth noting... -
[1.14.4] Syncing rendered held item movement with head?
JayZX535 replied to JayZX535's topic in Modder Support
Shoot, that explains some things, hah-- thanks. Went ahead and swapped them, but it's still being a little funky... Updated code: @SuppressWarnings("deprecation") @OnlyIn(Dist.CLIENT) public class WCWolfHeldItemLayer extends LayerRenderer<WCWolfEntity, WCWolfModel<WCWolfEntity>> { private final ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer(); public WCWolfHeldItemLayer(IEntityRenderer<WCWolfEntity, WCWolfModel<WCWolfEntity>> wcwolf) { super(wcwolf); } public void render(WCWolfEntity entityIn, float limbSwing, float limbSwingAmount, float partialTick, float ageInTicks, float netHeadYaw, float headPitch, float scale) { ItemStack itemstack = entityIn.getStackInSlot(entityIn.getHeldSlotID()); if (!itemstack.isEmpty()) { GlStateManager.pushMatrix(); float rotMultiplier = (float)Math.PI / 180F; GlStateManager.translatef((this.getEntityModel().getHead().rotationPointX / 16F), (this.getEntityModel().getHead().rotationPointY / 16F), (this.getEntityModel().getHead().rotationPointZ / 16F)); float calcHeadPitch = this.getEntityModel().getHead().rotateAngleZ / rotMultiplier; GlStateManager.rotatef(calcHeadPitch, 1.0F, 0.0F, 0.0F); float calcHeadYaw = this.getEntityModel().getHead().rotateAngleY / rotMultiplier; GlStateManager.rotatef(calcHeadYaw, 0.0F, 1.0F, 0.0F); float calcHeadTilt = this.getEntityModel().getHead().rotateAngleX / rotMultiplier; GlStateManager.rotatef(calcHeadTilt, 0.0F, 0.0F, 1.0F); GlStateManager.translatef(0.001F, 0.1F, -0.3F); GlStateManager.rotatef(-90.0F, 1.0F, 0.0F, 0.0F); this.itemRenderer.renderItem(itemstack, entityIn, TransformType.GROUND, false); GlStateManager.popMatrix(); } } public boolean shouldCombineTextures() { return false; } } -
Hello, I have a dog entity that can carry food items in its mouth (much like foxes). I'm trying to make its held item actually render there as it eats, but I'm having a little trouble getting it to actually work properly. When the dog is standing still it works fine. However, when the dog moves its head to look at the player, tilting it in a certain way, it goes all askew for a bit until the dog fully stops moving. I've been looking at the fox's head movement in particular, but that class has a lot of variables and functions that still have the default names, which is giving me a hard time tracing what they're used for. It has a specific parameter to account for Z Axis tilt, but it's hard to figure out what conditions are actually causing it to be used and for what. My dog entities also have a lot of potential poses, so the more universalized my solution can be, the better. Right now the code I have is this, which works alright while the dog is perfectly still but when it looks around (particularly when turning its head at an angle to the player), the rendered item does that weird tilting. @SuppressWarnings("deprecation") @OnlyIn(Dist.CLIENT) public class WCWolfHeldItemLayer extends LayerRenderer<WCWolfEntity, WCWolfModel<WCWolfEntity>> { private final ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer(); public WCWolfHeldItemLayer(IEntityRenderer<WCWolfEntity, WCWolfModel<WCWolfEntity>> wcwolf) { super(wcwolf); } public void render(WCWolfEntity entityIn, float limbSwing, float limbSwingAmount, float partialTick, float ageInTicks, float netHeadYaw, float headPitch, float scale) { ItemStack itemstack = entityIn.getStackInSlot(entityIn.getHeldSlotID()); if (!itemstack.isEmpty()) { GlStateManager.pushMatrix(); float rotMultiplier = (float)Math.PI / 180F; GlStateManager.translatef((this.getEntityModel().getHead().rotationPointX / 16F), (this.getEntityModel().getHead().rotationPointY / 16F), (this.getEntityModel().getHead().rotationPointZ / 16F)); float calcHeadPitch = this.getEntityModel().getHead().rotateAngleX / rotMultiplier; GlStateManager.rotatef(calcHeadPitch, 1.0F, 0.0F, 0.0F); float calcHeadYaw = this.getEntityModel().getHead().rotateAngleY / rotMultiplier; GlStateManager.rotatef(calcHeadYaw, 0.0F, 1.0F, 0.0F); float calcHeadTilt = this.getEntityModel().getHead().rotateAngleZ / rotMultiplier; GlStateManager.rotatef(calcHeadTilt, 0.0F, 0.0F, 1.0F); GlStateManager.translatef(0.0F, 0.1F , -0.3F); GlStateManager.rotatef(-90.0F, 1.0F, 0.0F, 0.0F); GlStateManager.translatef(0.001F, 0.0F, 0.0F ); this.itemRenderer.renderItem(itemstack, entityIn, TransformType.GROUND, false); GlStateManager.popMatrix(); } } public boolean shouldCombineTextures() { return false; } } Stuff like the Math.PI calculation comes from what I've observed in other entity classes and it seems to be working at least in part? My current method here attempts to get the tilt value directly from the head itself. But that's still causing problems. So I'm wondering if maybe I'm getting the rotation value wrong? The value used in the model class seems to be handled differently than the rotation value here. Putting them in one-for-one causes negligible movement on the item while the head moves a lot. In the model class, the inputs like netHeadYaw and headPitch seem to be divided by that Math.PI / 180F value, whereas in the fox held item class it seemed like those values were inputted directly to the held item. There's not a visible tilt value though, not that I've found, and I have some custom animations defined within the model class that I need to account for. That's why I want to get the value directly from the head rotation if possible-- otherwise I'll have to figure out a way of patterning all the checks I do in the model class somehow, and I really don't want to have to have both classes running the same checks for pose and such if I can help it. Anyone else have an idea of what I could try here? Thanks.
-
[1.14.4] Z fighting issues with semi-transparent entity layers
JayZX535 replied to JayZX535's topic in Modder Support
Thank you! Hopefully what I learned here can benefit others too -
[1.14.4] Z fighting issues with semi-transparent entity layers
JayZX535 replied to JayZX535's topic in Modder Support
Sorry for the wait! I didn't use a self-contained project for this unfortunately, but these are the relevant parts of code I used to reference it. I assign a new texture handler from my ClientProxy, and use that to retrieve the handler to get the instance for my entity. Hopefully this should still be fairly easy to set up and test? Gist I didn't include the methods from my entity class used to get stuff like texture dimensions, path, etc. but you could easily put something static in instead. Those methods are just designed to standardize things so that I can more easily add new animals and their genetics in the future. Thank you again for all your help! Also, if you notice anything that I could streamline or that I'm not doing quite right, I'm all ears. Thanks! -
[1.14.4] Z fighting issues with semi-transparent entity layers
JayZX535 replied to JayZX535's topic in Modder Support
Sure thing! Let me finish up a few last things and clean/comment it. Would you prefer I share the whole renderer class, or just the parts that deal with the buffered image manipulation? -
[1.14.4] Z fighting issues with semi-transparent entity layers
JayZX535 replied to JayZX535's topic in Modder Support
Thank you for all your help! I tried intentionally setting the texture to a specific color, and it soon became apparent that it wasn't an issue with my color-setting. Even Java's default colors returned bizarre results. I couldn't see anything wrong with the in-game tinting, so I did some more research and testing. And... apparently it was actually an issue with Java reading the colors in as ABGR instead of ARGB. I'm not sure if this is due to me having missed a Java update or something, but I'm gonna be looking into that. In any case, it was reading my red value as blue, which is why everything was so bizarrely tinted. Built a function to swap those around and it seems to work beautifully, from what I've seen thus far. I'll probably also build a texture correction toggle into my config file, because if it's a java issue then I expect there could be potential problems depending on what's installed on user-end too. Thank you so much for all your time and help. I think I've finally got this all nailed down? If not I suppose I'll have to pop in with more questions haha. But I really appreciate it-- this seems to be a much more lightweight method than Minecraft's layer system, in addition to avoiding the Z fighting and flickering, so that's absolutely fantastic! -
[1.14.4] Z fighting issues with semi-transparent entity layers
JayZX535 replied to JayZX535's topic in Modder Support
Thank you again for all your time and help! I think I'm slowly getting the hang of this... So, I've kept playing around with this and had much more success. I also figured out what was going on with the for loops: I was having it print out the values of the pixels, which although it's a great debugging tool, apparently I'd severely underestimated its impact on performance. I'll be removing those troubleshooting println()s for the final version, and without them the lag is much more bearable-- only a few seconds even for a large number of entities. So that should be a non-issue. You were right in that I was accidentally drawing a fully transparent texture. I've continued messing around with it and now that's no longer the case! Graphics does work as well, I was also just using it wrong. I'm now using setComposite to combine layers, but when it comes to applying color I've had the best luck using for loops to multiply each pixel. So far that seems to be working almost perfectly. However, there's one remaining problem. Somehow, somewhere, the colors aren't rendering true. They're a little-- or in some cases a lot shifted. And it seems to be on the actual rendering and not the calculations? For example, I printed the RGB values used to set a pixel color for one dog's base color and got "0.73356414, 0.64879674, 0.5183853". When inputted into this color calculator, it shows up as a sandy yellow-brown. However the dog itself... It looks like the color is being assigned properly? There's a slight bit of deviance between the number I put into the color and the one I get out, but it's a difference of 0.0015 or so at most, which I don't think should be enough to shift the color value that drastically?? So I'm thinking it may have something to do with the color mode of the image and Java shifting colors that don't quite align with what it's seeing? Do you know how I could get Java to base the image color model around the actual colors I'm putting in? Or is something else going wrong? The actual colors coming from my print statements have seemed spot on when I put them into that color site, so this one has me stumped... Code is as follows... //img comes from another method that loads a greyscale texture from a file as a BufferedImage.TYPE_INT_ARGB . I've also been using BufferedImage.TRANPARENT . Not sure which is better but neither has fixed my problem. private BufferedImage applyColor(BufferedImage img, Color tint) { BufferedImage tintedImg = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB); Graphics2D graphics = tintedImg.createGraphics(); graphics.drawImage(img, 0, 0, null); graphics.dispose(); float redBase = (float) tint.getRed() * (1/255F); float greenBase = (float) tint.getGreen() * (1/255F); float blueBase = (float) tint.getBlue() * (1/255F); for (int i = 0; i < tintedImg.getWidth(); i++) { for (int j = 0; j < tintedImg.getHeight(); j++) { //I want to keep the alpha value of the source while only changing its color float alpha = (float) tintedImg.getColorModel().getAlpha(tintedImg.getRaster().getDataElements(i, j, null)) * (1/255F); float redTint = (float) tintedImg.getColorModel().getRed(tintedImg.getRaster().getDataElements(i, j, null)) * (1/255F); float greenTint = (float) tintedImg.getColorModel().getGreen(tintedImg.getRaster().getDataElements(i, j, null)) * (1/255F); float blueTint = (float) tintedImg.getColorModel().getBlue(tintedImg.getRaster().getDataElements(i, j, null)) * (1/255F); float redOut = redBase * redTint; float greenOut = greenBase * greenTint; float blueOut = blueBase * blueTint; Color colorOut = new Color (redOut, greenOut, blueOut, alpha); tintedImg.setRGB(i, j, colorOut.getRGB()); } } return tintedImg; } Thank you again! -
[1.14.4] Z fighting issues with semi-transparent entity layers
JayZX535 replied to JayZX535's topic in Modder Support
Hey again, That's good to know-- I was probably doing something wrong then. If the first method is faster, I probably do want to use that one, even if it's a bit harder to learn... Hm. Well due to some model changes, these wolves actually use a 64x64 texture, so it is double the size of the normal one. I think the problem may have been that I declared several variables within the for-loop though, now that I think back on it, so it was creating stuff every time. That combined with the number of entities may have escalated the slow-down. The current code I have for the color overlay method is this: BufferedImage tintedImage = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB); Color color = new Color(this.entity.getTextureColor(0)[0], this.entity.getTextureColor(0)[1], this.entity.getTextureColor(0)[2]); Graphics graphics = tintedImage.createGraphics(); graphics.setXORMode(color); graphics.drawImage(img, 0, 0, null); // NOT 'tintedImage' graphics.dispose(); return tintedImage; // Image will be tinted This has been based off recommendations I'm seeing elsewhere on the interwebs, however I think it's been for people drawing directly to the screen in a standalone application, and it doesn't seem to be returning right in my case. I'm getting what appears to be a completely transparent texture-- the entity exists in the world, but is completely invisible despite not throwing any errors. I haven't worked with any methods through OpenGL though, so if that's a faster way to go, that seems like it might be optimal. Do you have an example of that I could take a look at? In essence, what I'm trying to do is take a texture like this and apply an RGB value to it as a tint, basically as if you were using the "multiply" layer mode in an image editing program (preserving the texture of the base layer but with the new color). Then I'll have to take multiple colored layers (some with alpha transparency) and stack them, so that they blend together to make a unique marking pattern. The end result is something like this (picture from when I was using the old layer system, which had the Z fighting and/or glow issues). You can see how the white markings aren't fully opaque-- they blend into the black ones (which are on their own layer) gradually. So I need to be able to replicate that layered effect when combining my textures. I'm very new to graphical stuff, but I want to make sure I can have the most efficient solution for this so that people aren't waiting around for textures to load. If the OpenGL method would be more efficient, then if possible I think I'd like to try and figure that one out. Otherwise I'll take another crack at that for loop and see if I can get it to go a little faster this time. Thank you for the blending formula, too. That was one thing that had me really stumped! -
[1.14.4] Z fighting issues with semi-transparent entity layers
JayZX535 replied to JayZX535's topic in Modder Support
Hey again, Thank you so much for all your help! I've got the basics of the dynamic texture working-- I got it to load my base texture file and use it as a dynamic texture. This reduces lag immensely once the texture is active-- I was able to have 200-300 entities onscreen before my frame rate hit 30fps, so I'd count that pretty reasonable even in the event that someone does want to make a dog army. However, I'm now a bit stuck as to the next step. For one thing, I need to take a grey-and-white texture (think vanilla sheep's wool) and color it. For another, I then need to repeat that process several more times, combining the textures as I go into a single BufferedImage. And I've had very little success on either account. Most of the research I've been doing has been telling me to either use for loops and iterate through the image pixel by pixel, or to use Java's Graphics to create an overlay and color the image that way. The second method has seemed like the simplest/most intuitive, but I think it may be having some issues when handling an image that's not directly being rendered to the screen (the idea is to create/manipulate the texture as a BufferedImage, and then convert that into a NativeImage which is used for the texture). The result has always been an invisible entity, which has a shadow but doesn't render onscreen at all. I could be totally off-base, but I'm thinking maybe Graphics affects specifically what you draw on the screen, and since my BufferedImage isn't actually drawn until it's saved and converted to the texture, it just... isn't working. That, or I'm just not understanding it right. The for loop method has had marginally more success-- I've gotten it to actually start working (though I couldn't figure out the equation needed to multiply the new color over the base layer so it had a limited effect), but it's extremely slow. When trying to load in my entity stress test world, I froze for 3-5 minutes while the game ran a multitude of for-loops going pixel by pixel. This was with a lot of entities, however I only tried to color the first layer-- I haven't even tried adding more. And as far as I know, the game does continue to tick in the background. Being frozen for that long would be an actual hazard, since presumably the game continues to run logic even before the screen can catch up. I want to use the most efficient method possible here, though I do greatly prefer having a lag spike once when the entity loads/updates to having one every single time the game tries to render. However, such a massive spike is definitely not what I'd prefer. I think I either need a way to tint the texture all at once, or to space out the lag spikes a little at a time. I'd rather have the texture appear unfinished (I.e. you see the uncolored base coat, then its color, then the uncolored next layer, etc.) for a little while than have the entire screen freeze for a prolonged period of time. Is there a method I could use to color/combine textures with alpha values that doesn't require me to loop through pixel by pixel? (It has occurred to me that I might be able to use the same method I use to combine textures to color them-- if I create a layer that's just a solid color and combine it with the alpha-masked base layer). If I do have to go pixel by pixel, is there a good way I can run the calculations little-by-little in the background as the rest of the game continues to render and only update the texture when each step finishes completion? Do you have any recommendations as to how I can go about this? Thank you again! -
[1.14.4] Z fighting issues with semi-transparent entity layers
JayZX535 replied to JayZX535's topic in Modder Support
Okay, so I'm continuing on the attempt at making dynamic textures. I basically cloned the MapItemRenderer class, and reworked it to take info from one of my mod entities rather than MapData, and to draw a texture based off the entity's traits. However, now I'm not too sure how to register it. I see that MapItemRenderer is registered with this line in GameRenderer: this.mapItemRenderer = new MapItemRenderer(mcIn.getTextureManager()); I presume that I need to register my texture handler class somewhere on my end as well, but I'm not sure where that should actually go. It also looks like there are a variety of other methods there that reference it. Obviously I can't just edit that class, so how should I go about registering that code? Do I need to create an extension of GameRenderer with my own methods pertaining to my texture generator, and then register that? The only main difference between this and the MapItemRenderer class is that this just generates the textures-- and then, assuming that works, I'll just return the proper ResourceLocation for the actual entity texture from my entity renderer class... -
[1.14.4] Z fighting issues with semi-transparent entity layers
JayZX535 replied to JayZX535's topic in Modder Support
Ahh, I think I was trying to generate it every frame. That's likely what the problem was. I'll check on that approach again and see if I can get it to work better... that may be a lot more effective. Regarding rendering every frame, I highly suspect that's the case. My computer is pretty powerful, but I want to make the mod as accessible as possible, even for those with less powerful computers. If mine is struggling, that doesn't bode too well for those with weaker hardware, heh. I'll revisit my attempt at dynamic textures. It seems like that's probably going to be the best approach... thanks again! -
[1.14.4] Z fighting issues with semi-transparent entity layers
JayZX535 replied to JayZX535's topic in Modder Support
Update: Running some initial framerate diagnostics this morning to get more exact numbers... Singleplayer world (7260MB memory) run through Eclipse: Normally generated world (none of my entities)- 59-60 FPS, stable One of my entities- Brief drop to 56, then back to 60 stable Five of my entities- Brief drop, then back to 60 stable Twenty-five of my entities- Brief drop, then back to 60 stable Fifty of my entities- Started dropping with around thirty entities present, stabilized out at 30fps One hundred of my entities- continued to drop, stabilized out between 10-15fps I ran /debug with 100 of my entities spawned and it said I was getting 20 ticks per second, so definitely render lag. So it does take a decent number of entities spawned for this to be an issue. However, since this mob is meant to be a pet, it's not infeasible for someone to decide to have that many of them. Is there any way I can continue to reduce this lag, or is it an inherent issue with having that many alpha layers? -
[1.14.4] Z fighting issues with semi-transparent entity layers
JayZX535 replied to JayZX535's topic in Modder Support
Dang, that's more of a fundamental problem than I'd have liked, but it's good to know. Thank you so much for your explanation and suggestions! I've spent some time messing with the dynamic textures, but it seems like that really didn't like what I was trying to do. Spawning in one entity gave me about one frame every three seconds, so unfortunately I don't think the system likes entities a lot (as far as I can tell it's only used in Vanilla code with entities for the Ender Dragon's death animation, which doesn't have to read a texture at all and just relies on randomly generated numbers). I had better results with your other suggestion (scaling the size increase according to the player's distance), however. This works, technically! I'm not getting the Z fighting anymore, even when I have all 5 of my current layers applied. However, with five layers, the game does start chugging a bit when you have a lot of these entities spawned. It's nowhere near as bad as the lag I had with the dynamic textures, but it is noticeable, and I'd like to cut it down if possible (especially since I have a couple more layers I would like to add). This is my current render code-- is there any way I can do this in a more optimized manner so as to reduce lag? I highly suspect it's coming from the distance calculations, so I'm wondering if I can do those more efficiently... if (!wcWolf.isInvisible()) { PlayerEntity player = Minecraft.getInstance().player; float dist = wcWolf.getDistance(player); int scalemodifier = 1; GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); GlStateManager.enableBlend(); if (wcWolf.showMerle()) { float[] afloat = wcWolf.getEumelaninColor().getColorComponentValues(wcWolf.getEuShade()); GlStateManager.color3f(afloat[0], afloat[1], afloat[2]); this.bindTexture(this.getResourceLocation(wcWolf, 0)); this.wolfmodel = new WCWolfModel<WCWolfEntity>(0.001F * scalemodifier * dist); this.getEntityModel().setModelAttributes(this.wolfmodel); this.wolfmodel.setLivingAnimations(wcWolf, limbSwing, limbSwingAmount, partialTick); this.wolfmodel.render(wcWolf, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); scalemodifier ++; } if (wcWolf.showAgouti()) { float[] afloat = wcWolf.getPhaeomelaninColor().getColorComponentValues(wcWolf.getPhaeShade()); GlStateManager.color3f(afloat[0], afloat[1], afloat[2]); this.bindTexture(this.getResourceLocation(wcWolf, 1)); this.wolfmodel = new WCWolfModel<WCWolfEntity>(0.001F * scalemodifier * dist); this.getEntityModel().setModelAttributes(this.wolfmodel); this.wolfmodel.setLivingAnimations(wcWolf, limbSwing, limbSwingAmount, partialTick); this.wolfmodel.render(wcWolf, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); scalemodifier ++; } if (wcWolf.showUrajiro()) { float[] afloat = EnumWCFurColor.OFF_WHITE.getColorComponentValues(wcWolf.getPhaeShade()); GlStateManager.color3f(afloat[0], afloat[1], afloat[2]); this.bindTexture(this.getResourceLocation(wcWolf, 2)); this.wolfmodel = new WCWolfModel<WCWolfEntity>(0.001F * scalemodifier * dist); this.getEntityModel().setModelAttributes(this.wolfmodel); this.wolfmodel.setLivingAnimations(wcWolf, limbSwing, limbSwingAmount, partialTick); this.wolfmodel.render(wcWolf, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); scalemodifier ++; } if (wcWolf.showBrindle()) { float[] afloat = wcWolf.getEumelaninColor().getColorComponentValues(wcWolf.getEuShade()); GlStateManager.color3f(afloat[0], afloat[1], afloat[2]); this.bindTexture(this.getResourceLocation(wcWolf, 3)); this.wolfmodel = new WCWolfModel<WCWolfEntity>(0.001F * scalemodifier * dist); this.getEntityModel().setModelAttributes(this.wolfmodel); this.wolfmodel.setLivingAnimations(wcWolf, limbSwing, limbSwingAmount, partialTick); this.wolfmodel.render(wcWolf, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); scalemodifier ++; } if (wcWolf.showWhite()) { float[] afloat = EnumWCFurColor.WHITE.getColorComponentValues(0); GlStateManager.color3f(afloat[0], afloat[1], afloat[2]); this.bindTexture(this.getResourceLocation(wcWolf, 4)); this.wolfmodel = new WCWolfModel<WCWolfEntity>(0.001F * scalemodifier * dist); this.getEntityModel().setModelAttributes(this.wolfmodel); this.wolfmodel.setLivingAnimations(wcWolf, limbSwing, limbSwingAmount, partialTick); this.wolfmodel.render(wcWolf, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); scalemodifier ++; } GlStateManager.disableBlend(); } The checks to determine if the layer needs to be shown and the color grabbers shouldn't be the issue. At least, they worked well when everything was on its own render layer. When I had it set up like that, the game ran fine even with many entities spawned, but that was when I had the issues with the z fighting. Thank you again for your help! -
[1.14.4] Z fighting issues with semi-transparent entity layers
JayZX535 replied to JayZX535's topic in Modder Support
Bump. Still struggling with this. If y'all know of any good guides on GL11 that'd also be good too. It's one of the things I'm less versed in, so learning more about it def couldn't hurt. -
Hello all, I'm working with an entity that has a large number of layers (currently five, and I'll likely be adding a few more). Tl;dr, these entities can come in a LOT of different variations of coat color and markings. Up close, they look great, but if I get a little ways away, the ones that show multiple layers start to have Z fighting issues. You can see how the two entities with more markings here are showing that weird streaky pattern. That isn't supposed to be there. Most of the layers I have rely on transparency to blend well, and I've admittedly been fighting the GL system to make that work. I thought I had it figured out, but I'm wondering if I'm still missing something here. Minecraft doesn't have a good example of using multiple layers for something like this, so I'm struggling a little to figure out if I'm using the GL system properly. In the past, I countered this problem by using the same layer rendering system that horses use, and that appeared to work great. However, I've since switched to a system that colors the textures in the renderer itself (like sheep's wool does). This allows me to have many more diverse options of color, however I'm not at all sure how to make that work with the system the horse renderer uses. If I could switch back to that and retain the ability to color each layer independently I def would, but I'm not sure if that's possible or not. I've been trying to keep the layers as compact as possible, because there's enough of them that the entity starts to develop a slight "glow" when they're all enabled (I believe due to the semi-transparent outer layers). Right now they each have a size increase of 0.001. Stepping that up to 0.01 seemed to help with the Z fighting, but then I started getting the glow around the entity. The render code in the layer classes all runs along these lines: public void render(ModEntity entityIn, float p_212842_2_, float p_212842_3_, float p_212842_4_, float p_212842_5_, float p_212842_6_, float p_212842_7_, float p_212842_8_) { if (!entityIn.isInvisible() && entityIn.showThisMarkingLayer()) { this.bindTexture(this.getEntityTexture(entityIn)); GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); GlStateManager.enableBlend(); float[] afloat = entityIn.getColor().getColorComponentValues(entityIn.getShade()); GlStateManager.color3f(afloat[0], afloat[1], afloat[2]); this.getEntityModel().setModelAttributes(this.wolfmodel); this.wolfmodel.setLivingAnimations(entityIn, p_212842_2_, p_212842_3_, p_212842_4_); this.wolfmodel.render(entityIn, p_212842_2_, p_212842_3_, p_212842_5_, p_212842_6_, p_212842_7_, p_212842_8_); GlStateManager.disableBlend(); } } Is there something I could do to help stop the Z fighting? Also, is there a definitive order that I should be calling GL functions in? What I have appears to work but I'd rather get it spot on by the books if I can...
-
Ahh thanks for the update! Hopefully ongoing progress continues to go well-- best of luck to Cadiboo on that! Since release for my mod isn't imminent, I may hold off on this feature until the mod gets a bit closer to going public, however it's great to know that there is a workaround in case I finish my release before the interface is ready. Thanks!
-
Hey all, I'm starting to work with configs in 1.14 for the first time, and just coming from the 1.12.2 system where GUIs were basically automatic. However, it looks like that's not the case since the 1.13 update, and I'm finding conflicting reports on how it all works. Don't see anything in the docs either, unless I'm just really dang blind. Does anyone know the current state of this, if there's an easy way to accomplish this in the 1.14.4 system yet and, if not, do we have any word on when that'll be coming to 1.14.4?
-
Bump. Issue still persists, not sure what's causing it. Also worth noting, I'm checking if the function is running via a print statement in onBlockActivated within my block. The ones here in the event run, but the one in that function does not. Since there's no if statements or anything to interfere with onBlockActivated, I assume this issue has to be with the event either not being sent properly, or with me needing to use a different method or something. Does PlayerInteractEvent.RightClickBlock actually call onBlockActivated? Or do I have the wrong event/method?
-
Hey all, Got a bit of a stumper. I have a custom block that's supposed to run an interaction when clicked with a certain item. That's fine and great, I got that part working. However, because I'm using the onBlockActivated method, it doesn't fire when shift clicking (which I want it to do because I want it to activate a different function when shift clicked with that item). I looked it up and saw that this is an intended function, and that I need to override the PlayerInteractEvent.RightClickBlock event to make it allow the click. Which I did. Except no matter what I try, I can't get it to actually register the onBlockActivated event. It works as intended with a normal click. It's just shift clicking that's not working. My code is as follows: @SubscribeEvent public static void playerRightClickBlock(PlayerInteractEvent.RightClickBlock event) { if (event.getWorld().getBlockState(event.getPos()).getBlock() instanceof WCFoodBowlBlock) { if (WCFoodBowlTileEntity.isValidFood(event.getItemStack())) { System.out.println("Right Clicked on food bowl with valid item"); event.setUseBlock(Event.Result.ALLOW); } } } That print statement does fire. So the event is getting caught and running properly, and none of those if statements are throwing it off. I can only assume I either got the wrong event somehow, am using the wrong function to make the onBlockActivated method fire even while sneaking, or Forge itself has a bug. I'm using the latest stable version so if so, it must be something pretty recent... Thank you for your time, and have a great day!
-
[1.11.2] Help syncing tileentity IItemHandler from server to client
JayZX535 replied to JayZX535's topic in Modder Support
I announced that I'll be releasing the complete version of the mod's first update in 1.11, so I'll be continuing to work in 1.11 for now. There are a couple things here that were added unnecessarily, I'll take a look at those-- some can probably be deleted, while others may be for things I intend to alter later. I will definitely take a look at the EntityPlayer#openGUI part, as if that is the cause then this may be a simple fix. I'll update this later when I've had time to take a look at these suggestions. Thank you for your advice. -
Hello, all! I'm currently trying to develop a server-compatible mod for the first time, and I'm having some massive issues with my IItemHandler capability for a tileentity not properly syncing from the server to the client. It runs fine in singleplayer-- the inventory has expected behavior, as seen here: Everything seems to be working fine. I can drag stacks around, they register in the top, etc. No issues. (placeholder gui and .lang isn't set up, I know XD) But when I host from a server and connect to it... Clicking the item just ends with it glitching immediately back into its slot. Shift-clicking duplicates the item into the slot as a ghost item, which immediately disappears when clicked on. So this is definitely a big issue. One of the most requested features I had for the mod was server compatibility, so I'm not about to just give up, however this is my first experience with servers and there seem to be few good explanations/examples of how this even works. As I understand, IItemHandler doesn't automatically sync with the client the way IInventory does, but IInventory is an older, outdated method that's not the most effective one to use from what I've read. It sounds like I need to set up a packet system to sync the server to the client and back again, but I have very little idea of how to do that with an inventory. I've used packets before, but only ever for simple variables (i.e. ints and stuff), and I don't necessarily know enough about the inventories to know where I'd need to call/send these packets. So if anyone has experience/advice here, I would definitely appreciate it. If at all possible, I'd like to make this setup reusable-- though if that's not easily possible I understand. I want to keep the mod as clean as possible, without reusing code if I can help it, so if there's some way I can set this up automatically for future TileEntity inventories (i.e. a custom extension of the container class? Some way to automatically sync through my custom slot base class?) that is definitely preferable. Current code: Block TileEntity Container GUI GUIHandler I do use a custom slot class, but the only thing I added is a restriction for isItemValid (the slot is a food bowl, so I've restricted it to only accept my kibble items). You can see that code here: @Override public boolean isItemValid(ItemStack stack) { if (stack.isEmpty() || !(stack.getItem() instanceof ItemKibble)) return false; IItemHandler handler = this.getItemHandler(); ItemStack remainder; if (handler instanceof IItemHandlerModifiable) { IItemHandlerModifiable handlerModifiable = (IItemHandlerModifiable) handler; ItemStack currentStack = handlerModifiable.getStackInSlot(index); handlerModifiable.setStackInSlot(index, ItemStack.EMPTY); remainder = handlerModifiable.insertItem(index, stack, true); handlerModifiable.setStackInSlot(index, currentStack); } else { remainder = handler.insertItem(index, stack, true); } return remainder.isEmpty() || remainder.getCount() < stack.getCount(); } Thank you so much for your time, and have a great day!