Skip to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

V0idWa1k3r

Members
  • Joined

  • Last visited

Everything posted by V0idWa1k3r

  1. In said class you can do whatever you want to do. The class would be dependent on the api provided by another mod. Don't invoke that method unless Loader.isModLoaded returns true. Then the class will not be loaded. If you really need to interact with the capability in an another class you can create a wrapper. Example scenario: // Depends on ModA class EnergyCapabilityA { int getEnergy(); void setEnergy(int i); } // Depends on ModB class EnergyCapabilityB { int getEnergy(); void addEnergy(int i); void removeEnergy(int i); } // Your generic wrapper interface, depends on nothing interface ICompatibleEnergyCapability { int getEnergy(); void addEnergy(int i); void remEnergy(int i); } // Your wrapper provider interface, depends on nothing interface ICECProvider { ICompatibleEnergyCapability createWrapper(TileEntity tile, EnumFacing side); } // A custom caster class, depends on ModA class AWrapperProvider implements ICECProvider { ICompatibleEnergyCapability createWrapper(TileEntity tile, EnumFacing side) { EnergyCapabilityA capA = tile.getCapability(A_ENERGY_CAP, side) return new ICompatibleEnergyCapability(){ int getEnergy(){ return capA.getEnergy(); } void addEnergy(int i){ capA.setEnergy(capA.getEnergy() + i); } void remEnergy(int i){ capA.setEnergy(capA.getEnergy() - i); } } } } // A custom caster class, depends on ModB class BWrapperProvider implements ICECProvider { ICompatibleEnergyCapability createWrapper(TileEntity tile, EnumFacing side) { EnergyCapabilityB capB = tile.getCapability(B_ENERGY_CAP, side) return new ICompatibleEnergyCapability(){ int getEnergy(){ return capB.getEnergy(); } void addEnergy(int i){ capB.addEnergy(i); } void remEnergy(int i){ capB.removeEnergy(i); } } } } // A class containing the wrappers, depends on nothing class WrappersHolder { ICECProvider wrapperA; ICECProvider wrapperB; void init() { if (Loader.isModLoaded("ModA")) { wrapperA = Class.forName("AWrapperProvider").newInstance(); } if (Loader.isModLoaded("ModB")) { wrapperB = Class.forName("BWrapperProvider").newInstance(); } } } // Whenever you need to work with your capabilities class Worker { void work() { if (WrappersHolder.instance.wrapperA != null) { ICECProvider aProvider = WrappersHolder.instance.wrapperA; ICompatibleEnergyCapability cap = aProvider.createWrapper(tile, side); // Do whatever you want with the cap } } } This way everything is safe to use since you are not loading any classes that may or may not be present and everything is nicely in a wrapper and bound to a common interface. If you want your has/getCapability to return a capability of an another mod it is a bit more tricky but also possible by creating wrappers for those capabilities in a similar way that depend on your main capability, only constructing them if the mod is present and returning them. You would need to be careful with your Capability<> instances though.
  2. As far as I am aware the Optional is going away in 1.13. CapabilityInject will not insert a capability that isn't provided thus it will stay null. But that kinda requires a hard dependency anyway since you need to pass a class to the annotation. My solution would be to put all interaction with potentially present capabilities in a separate class and don't load or ever touch it if the mod providing the capability isn't present.
  3. After you've changed the data of the capability on the server you need to send the changes to the client so the client is aware of the change. GUIs are client side only.
  4. You actually don't have to create a block to make your fluids have textures. The reason you don't see a texture without a fluid block is because it's not stitched to the texture atlas. Creating a block automatically stiches the texture and so you now have the ability to see it. However that is not the only way to do this and in fact is not the preffered way. Just stitch your fluid texture in the TextureStitchEvent.
  5. I am pretty sure these don't get synced to the client. You shouldn't be using this anyway, use capabilities. There are no reasons whatsoever to push/pop matrix here. You are not changing the matrix in any way. If you change the GL state to something change it back when you are done. If you are enabling blend then specify the blend profile too. Why are you modding for 1.10.2 anyway? It's outdated, use 1.12.2.
  6. What exactly are you trying to do? If you want to obtain a color of an item you can use ItemColors#colorMultiplier. Mind you this will return a white color if the item has no IItemColor associated with it. If you want to get the color from the texture you would need to somehow get the file that is responsible for the sprite, read it(to a BufferedImage perhaps) and then get the color of the pixel you want(or all pixels and average the color)(for a BufferedImage it would be BufferedImage#getRGB). Mind you that this approach is rather expensive. Alternatively you could read the pixels at specific coordinates on a texture using GL11.glReadPixels. The texture could be grayscaled to later be colored by an IItemColor. For this approach you would need to know the coordinates of the pixel on the sprite map though so you would need a sprite in the first place. Also the mod you've linked is open source. You could see how they did it. And keeping a list of each color value for each ingot is not that bad. It is actually the most sensical approach. It's just an integer per ingot you wish to register after all. And I have no idea why you are implying that you are modding for 1.13. Forge for 1.13 isn't out yet.
  7. I think it is done this way to make as little patches as possible and have the patches be as small as possible. 1 patch to the Item class < 1 patch to the Item class and 1 patch to the ItemShield class.
  8. You would need to ray trace the block the player is looking at(World#rayTraceBlocks). This gets you a RayTraceResult that contains the side that has been hit.
  9. The reason it's implemented like is is because it's a forge patch. Vanilla simply did item == Items.SHIELD when checking for a shield in various places. Forge removed those direct checks and instead did this patch to the item class. It's functionally the same, preserves vanilla's functionality and allows anyone to override this when they want to make a custom shield themselves. Or at least I assume it's a forge patch because it's together with the rest of them and has a javadoc.
  10. That is for bedrock entity models. Or obj models. Not a java entity model so no go there. Notice how you used multiple independent models there. Not a single obj/json model but a collection of different ones. If you are rendering them through vanilla's renderers then yes, you do need to stitch a texture since this is where the game will look for it. You would also need to bind the default sprite atlas. However if you simply have a model that is not a IBakedModel you can just bind the texture and as long as your vertices carry the correct texture coordinates everything will just work.
  11. I don't know about FBX but OBJ is a pretty straightforward format. It is easy to write a parser and a vertex uploader for an obj model. Something kinda like I did here. The OP wants to render mob models, not block/item models though. While it is possible to use an item/block model for an entity model it is impractical. Animating it for example would be a nightmare. I also have no idea what you are talking about with this You don't need to stitch anything for rendering an entity.
  12. Well, BlockRendererDispatcher is a dispatcher. When the time comes to redraw a region the game iterates over blocks and sends the blockstates and positions it iterated through to the BlockRendererDispatcher along with the world the rendering is going in + the buffer for the vertices. That's all 4 arguments to the BlockRendererDispatcher#renderBlock. The dispatcher then decides how to render the block. It gets the EnumBlockRenderType from the state passed and checks against it. If it is INVISIBLE the block isn't rendered at all. If it is MODEL then the dispatcher gets the model for the blockstate it was passed and passes the rendering to BlockModelRenderer. If the render type is a LIQUID then it passes the rendering to a BlockFluidRenderer. Otherwise no rendering is done. BlockModelRenderer gets the model and iterates it's quads by side. It checks whether the quad should be rendered and if it is uploads it to the buffer(before that it applies lighting and color multiplier to the quad though). Oh and it also decides whether to render the quads "smooth"(read: with ambient occlusion) or "flat". BlockFluidRenderer is only used for water and lava since forge added fluids actually have a fluid model(kinda). Then it calculates the sides that should be rendered, the heights of the corners of the fluid interpolates the texture and uploads the resulting quads to the buffer. That's about how it all works. Since all methods are public you can invoke any part of the process yourself and render models/quads/blockstates to a custom BufferBuilder.
  13. What exactly are you doing? You don't need to construct a new instance of BlockRendererDispatcher. All you need to do is call BlockRendererDispatcher#renderBlock. You can get an instance of BlockRendererDispatcher from MInecraft#getBlockRendererDispatcher and you can get an instance of Minecraft from Minecraft.getMinecraft(). That's it. However there is an issue with BlockRendererDispatcher#renderBlock where it asks the block for an extended blockstate. If it is a mod block that uses a TileEntity and extended state to pass some properties from the tile entity to the blockstate this will crash the game if the mod assumes that there is a tile entity at the position passed. That's why usually when people want to render blocks that aren't really there a fake world is used.
  14. While it can be as big as you want the selection detection only works when you look at the 1x1.5x1 cube and not anywhere else. If you make your selection box a 10x10x10 you will only be able to see it when mousing over the 1x1x1 cube that produces this box. You will see the whole 10x10x10 box though. But this is not the behaviour you want since you want to see the box when you look at it, not the cube producing it.
  15. As far as I am aware snow doesn't fall on blocks that are not full cubes(return false in Block#isFullCube)
  16. Since the model is an obj model you can't scale it down using json(although you might be able to do something with the forge blockstates format since it allows you to specify transforms but I am no expert on that and whether you can specify your own custom transforms). However the issue here is different. You are trying to use a big model for a 1x1x1 cube. That will not work for a multitude of reasons. One of which you've discovered already - you can't use the same scaled model for an item model. The other issues would be the collision box, the selection box(none of which work with boxes bigger than 1x1.5x1), the block placement(blocks could be placed into your blockspace occupied by the model) and the frustrum culling(look up from your block and the model will dissappear from sight as soon as the block dissappears from sight(will only work in certain positions of the chunk if I understand MC's chunk rendering correctly as it uses and culls 16x16x16 regions, not individual blocks)) The solution to all those issues would be to scale your model down to a 1x1x1 cube and use a TESR to render it with the scale you need it instead. This solves all but 1(block placement, could be solved with transparent placeholder blocks) issues.
  17. I don't think the OP wants to render fluids since they mentioned that they need the sprite for the average color to draw on a minimap. My solution would be to get the fluid associated with the block if it has one. If the block is LAVA or WATER then default to FluidRegistry.WATER/LAVA respectively, otherwise check if the block is an instance of IFluidBlock and use IFluidBlock#getFluid to obtain the fluid. Then once you know the fluid you can querry the sprite name using Fluid#getStill/getFlowing. Lastly you can now use TextureMap#getAtlasSprite to get the actual sprite(like I do here). You can even get the fluid's color from the fluid by using Fluid#getColor.
  18. You can try it out. However if you are changing the player's motion parameters then you need to do so on the client - player movement is controlled by the client.
  19. getLookVec is the direction he is looking at. It's the direction vector.
  20. That gets the helper, not the direction which the OP was asking for. @Niinnnnnn use Entity#getLookVec
  21. Because it is ancient. Do you really expect us to provide support for code that is outdated by 4.5 years at this point? Most of it no longer works since it was heavily changed(models, registries, capabilities, etc).
  22. I just told you how. Ditch it entirely and register your models in the ModelRegistryEvent directly. Like I do here if you need an example. I have yet to see a "good" modding tutorial on youtube. All of them make mistakes like this, or static initializers, or CommonProxy or something else posts on this forum are plagued by. The truth is they don't know much more than you. They've just learned how to make their code not explode in their faces and they are eager to share that knowledge with the world even if their code makes no sense(CommonProxy, IHasModel) or is plain incorrect(static initializers)
  23. IHasModel is stupid. All items need models, all of them, no exceptions. Nothing that is required by model registration is private to your item class either. Just register the model in the ModelRegistryEvent directly. This line screams "I was initialized in a static initializer!". Don't use static initializers. Instantinate your stuff directly in the RegistryEvent.Register. Like this. Not only is this the correct way of registering and instantinating stuff it also shortens your code to a 33% of what it used to be. See above. Don't use static initializers. Ever. fm is a terrible modid. Modids can be up to 64 characters long. Use those characters. No it doesn't. it crashes the game. Not the launcher. There is a big difference. It most likely does that because you are using a wrong super constructor invocation. The one that only takes in the ToolMaterial will crash the game since it does a lookup in an array by the material's index. And since the array isn't big enough it crashes the game. Use the other constructor, the one that takes 2 additional floats. But what do I know. You've never posted the code for the Axe, or the crash report. Apart from that we need the debug.log to figure out the problem. The log will have an error message telling you what exactly is wrong.
  24. 1.7.10 is no longer supported on this forum. Update to receive support.
  25. Stop using IHasModel, it is stupid. All items have models. All of them, no exceptions. Nothing that is required by model registering is private to your item class. Model registration needs to happen in ModelRegistryEvent so do it there directly. Al this stack tag compound nonesense is no longer needed. It was a solution to a 1.7 problem. Nowdays the attack speed is controlled by the attack speed attribute modifier. ^This line. The -1.8D is the modifier. Change it to something else. This line screams "I was initialized in a static initializer!". Don't use static initializers. Instantinate your stuff directly in the RegistryEvent.Register. Like this. Not only is this the correct way of registering and instantinating stuff it also shortens your code to a 33% of what it used to be.

Important Information

By using this site, you agree to our Terms of Use.

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.