Jump to content

TheGreyGhost

Members
  • Posts

    3280
  • Joined

  • Last visited

  • Days Won

    8

Everything posted by TheGreyGhost

  1. Hi This example project might give you some inspiration (see mbe21) https://github.com/TheGreyGhost/MinecraftByExample If you want a block model, the easiest way is like you said to register a block with a model, let Forge load it and stitch the texture etc, then grab it using the code in your question. The block associated with your TileEntity is probably the best spot. If your tileentity block already has another model, you can add a blockstate property purely for the purposes of accessing the correct model. Or create an entirely new, unused block. However if you really don't like that idea, you can access the ModelRegistryEvent and ModelLoader.addSpecialModel() instead. -TGG
  2. Howdy Your TE should have these methods in addition to your read and write method // When the world loads from disk, the server needs to send the TileEntity information to the client // it uses getUpdatePacket(), getUpdateTag(), onDataPacket(), and handleUpdateTag() to do this: // getUpdatePacket() and onDataPacket() are used for one-at-a-time TileEntity updates // getUpdateTag() and handleUpdateTag() are used by vanilla to collate together into a single chunk update packet @Override @Nullable public SUpdateTileEntityPacket getUpdatePacket() { CompoundNBT nbtTagCompound = new CompoundNBT(); write(nbtTagCompound); int tileEntityType = 42; // arbitrary number; only used for vanilla TileEntities. You can use it, or not, as you want. return new SUpdateTileEntityPacket(this.pos, tileEntityType, nbtTagCompound); } @Override public void onDataPacket(NetworkManager net, SUpdateTileEntityPacket pkt) { read(pkt.getNbtCompound()); } /* Creates a tag containing all of the TileEntity information, used by vanilla to transmit from server to client */ @Override public CompoundNBT getUpdateTag() { CompoundNBT nbtTagCompound = new CompoundNBT(); write(nbtTagCompound); return nbtTagCompound; } /* Populates this TileEntity with information from the tag, used by vanilla to transmit from server to client */ @Override public void handleUpdateTag(CompoundNBT tag) { this.read(tag); } In addition, whenever your code changes the data in the TileEntity, you should call markDirty(). -TGG
  3. Hi My guess: your IRunicPower.getPower() does not return a float. (it's not enough for RunicPower implements IRunicPower .getPower() to return a float, IRunicPower.getPower() must also do so). -TGG
  4. Hi Looks like some of your model files don't match the blockstate names. The item is ok, and some of the placed blocks, but others aren't. Check the console log, it might have some clues for you. -TGG
  5. Sorry, I have no clue about that, it sounds to me like MatrixStack is changing its transformation based on what the player is doing, unlike the various other world rendering (blocks, entities, etc) where it's tied to the world x,y,z. You could try tracing through the vanilla render code and/or inspecting the MatrixStack (using a breakpoint) to see what is going on, it may be hard work... Williewillus may know- see here https://gist.github.com/williewillus/353c872bcf1a6ace9921189f6100d09a ... since this looks promising... Unfortunately the link appears to be busted. If you comment on that gist (s)he may reply, has been pretty responsive in the past -TGG
  6. Howdy I've never done that yet but based on Vanilla, yes it looks about right IRenderTypeBuffer buffer = IRenderTypeBuffer.getImpl(Tessellator.getInstance().getBuffer()); // set up your render settings // do your render buffer.finish(); perhaps wrapped in RenderSystem.pushMatrix(); RenderSystem.popMatrix(); -TGG
  7. Hi Looking at where RenderWorldLastEvent is called in the vanilla code, it appears to be called after all the vanilla render buffers have already been finished, so there's nothing for you to write to. (See WorldRenderer::updateCameraAndRender and ::renderWorld Based on this link you can create your own buffer- https://gist.github.com/williewillus/30d7e3f775fe93c503bddf054ef3f93e But it may be difficult to achieve the effects you want if you're drawing out of the correct sequence; especially translucent blocks can be very sensitive to the order that you draw them in. You might be better off drawing the blocks a different way (for example: tileentity). -TGG
  8. Are banners transparent (cutout)? That may be the problem if you've copied the texture gen code from banners. The vanilla elytra isn't really transparent, it's cutout so the blending function is irrelevant, the alpha test is the important function. i.e. if alpha is less than the cutoff it's transparent, otherwise it's opaque. I can't tell from your code whether cutout (alpha test) is enabled or not. But if it renders as opaque no matter what RGBA you write into the texture, then it's probably disabled. The first thing I'd try is something like this: for (int height = 0; height < nativeimage2.getHeight(); ++height) { for (int width = 0; width < nativeimage2.getWidth(); ++width) { int pixelRGBA = nativeimage2.getPixelRGBA(width, height); if (height == width) { nativeimage1.setPixelRGBA(width, height, 0); // will be transparent } else { nativeimage1.setPixelRGBA(width, height, pixelRGBA); } } } If that has cutout pixels in it, you know that the rendering is ok. Otherwise your rendering mode is wrong (alpha cutoff is not correct). I think your code for generating the texture is not right. The int RGBA value that you get is actually composed of four components bits 0 -> 7 are red bits 8 -> 15 are green bits 16 -> 23 are blue bits 24 -> 31 are the alpha value. so you calculate int alphaValue = (pixelRGBA >> 24) & 0xff; int colourWithoutAlpha = (pixelRGBA & 0xffffff); // blend your colours without Alpha here then int newRGBA = (alphaValue << 24) | (newColourWithoutAlpha); using blendPixel probably won't give you what you want because it blends the alpha channels as well which will probably mess up your culling. Perhaps if you describe how exactly you want the two textures to be combined it might help. Do you want partial blending of the banner texture onto the elytra? Or are you just wanting the elytra to be coloured to match the banner except where the elytra has a cutout (i.e. all-or-nothing blending)? In the second case I don't think you need blendPixel at all - just check every pixel in the elytra texture and if the alphaValue is above the cutoff, write the banner pixel to the output texture, otherwise write a transparent pixel (alpha of zero) -TGG
  9. When I search for Slot#onSlotChanged I find it being called from two important vanilla base classes Slot class: putStack and onTake Container class: slotClick and mergeItemStack Perhaps I'll try modifying SlotItemHandler to perform the notification via onSlotChanged and see if it makes any practical difference vs onContentsChanged. The other callbacks in IInventory don't appear to be important unless you're extending vanilla containers. -TGG
  10. Slot.onSlotChanged calls IInventory.markDirty, but SlotItemHandler doesn't. This means that the parent TileEntity isn't informed when a slot has poked around in the container. I presume that this is important because Vanilla does a lot of it from a variety of places. I agree with your comments about capability, composition vs inheritance, and that you can use IItemHandler for a lot more than just TileEntity-based containers. The only reason I see not to use it is communication back to the parent TileEntity which it doesn't do properly. Perhaps this could be addressed by modifying or extending SlotItemHandler to give it a lambda function for dirty notification, but this is currently not the case and it's not clear that ItemStackHandler.onContentsChanged is called in all cases that Slot.onSlotChanged is called.
  11. Howdy Are you sure this blend function is what you intend? GlStateManager.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); Normally I would expect to see something like GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); Your texture generator doesn't appear to handle alpha values explicitly? It seems to be doing some sort of magic manipulations there, it would help if you named your variables more clearly. This in particular just doesn't look right; I presume it is trying to extract the alpha value but it's not clear to me why the alpha value is in the lowest 8 bits initially but needs to be shifted to the upper 8 bits int j1 = (i1 & 255) << 24 & -16777216; -TGG
  12. @diesieben07 IItemHandler is not a suitable replacement for IInventory if you are using a GUI - where you have container Slots which needs to communicate with the parent TileEntity (via markDirty()). I think there is nothing wrong with IInventory if you use it properly. IItemHandler has some useful methods but is not intended to be a drop in replacement for IInventory. @IceMetalPunkYou might find these working examples helpful https://github.com/TheGreyGhost/MinecraftByExample mbe20, mbe21 for synchronising tileentity data mbe30 for containers -TGG
  13. Hi Yeah it's possible if you're willing to poke deep into the vanilla code. Your code can do basically anything it wants; use Reflection to change the access levels of fields and then you can modify the render structures to your heart's content. Look at WorldRenderer and especially WorldRenderer ::updateCameraAndRender. The problem with doing this is that it often isn't robust, and will likely make your mod incompatible with others. Thread safety can be difficult as well. But it's for sure possible. Cheers TGG
  14. Hi You might find this tutorial project useful, it has a working example of a player container which explains how slots are configured https://github.com/TheGreyGhost/MinecraftByExample see mbe30 and/or mbe31 -TGG
  15. Hi Have a look at this example project https://github.com/TheGreyGhost/MinecraftByExample mbe04 does something similar Where do you want to render it? In a TileEntityRenderer, or an Entity, or somewhere else? Cheers TGG
  16. I don't think so, no. Based on my testing the "loader": "forge:obj", needs to go in the model file itself -TGG
  17. Howdy This error means that either * two different threads are attempting to modify your HashMap at the same time, or * you are iterating through a hashmap and trying to modify it at the same time (eg using remove or add) -TGG
  18. Hi I agree with dieSieben, with some caveats: My own rules of thumb: The number of blocks should generally match the number of items 1) If you have a modest number of blocks that are present as different items (eg different colours of stone - let's say up to 64 or so), make a json for each one. Keep the blockstates for placement or state (lit / not lit, waterlogged, etc) information only, as you said in your question 2) If you have a large variety of blocks (eg can be a wide range of colours), and this can be deduced from world information (eg like grass colour which uses a callback during rendering to determine the correct shade of green), then use a custom IBakedModel for your block rendering with IModelData (IForgeBakedModel::getModelData). You can either use a custom loader, or you can find & replace with your custom IBakedModels during ModelBakeEvent. 3) Otherwise- (eg if your player is not able to hold all the different types of block in their hand and/or place them directly) - use a tileentity. Generating a lot of json can be tedious, I've found Microsoft Excel spreadsheets to be very useful for that- don't even need macros, just formulae with lookups; copy/paste; then export as text. Much faster! -TGG
  19. Hi Yes you do need to do something different. The "RenderTyper" determines how your textures will be drawn. For example the Slimes have both a solid layer and a transparent (alpha blending) layer. Have a look at SlimeRenderer and SlimeGelLayer for more inspiration, especially this bit IVertexBuilder ivertexbuilder = bufferIn.getBuffer(RenderType.getEntityTranslucent(this.getEntityTexture(entitylivingbaseIn))); Browsing through RenderType will show you the various types of rendering that Vanilla uses for entities. Cheers TGG
  20. Howdy Looks like this is null TrackedEntity:: public void sendSpawnPackets(Consumer<IPacket<?>> p_219452_1_) { if (this.trackedEntity.removed) { LOGGER.warn("Fetching packet for removed entity " + this.trackedEntity); } IPacket<?> ipacket = this.trackedEntity.createSpawnPacket(); '<--- null here Have you created a custom entity and not properly implemented createSpawnPacket? -TGG
  21. Hi Do you mean * fully transparent (i.e. each pixel is either present or absent) - in which case getCutout is the right renderlayer * partially transparent (i.e. alpha blending - like glass panes where you can see through them) - in which case you will probably need to use a Forge multilayer block { "loader": "forge:multi-layer", "credit": "Made with Blockbench", "layers": { "solid": { "parent": "block/block", "textures": { "1": "block/frosted_ice_0", "2": "block/ice", "3": "block/white_stained_glass", "particle": "block/lantern", "all": "block/lantern" }, "elements": [ { "name": "top", "from": [5, 6, 5], "to": [11, 7, 11], "faces": { "north": {"uv": [0, 2, 6, 3], "texture": "#all"}, "east": {"uv": [0, 2, 6, 3], "texture": "#all"}, "south": {"uv": [0, 2, 6, 3], "texture": "#all"}, "west": {"uv": [0, 2, 6, 3], "texture": "#all"}, "up": {"uv": [0, 9, 6, 15], "texture": "#all"}, "down": {"uv": [0, 9, 6, 15], "texture": "#all", "cullface": "down"} } } ] }, "translucent": { "parent": "block/block", "textures": { "1": "block/frosted_ice_0", "2": "block/ice", "3": "block/white_stained_glass", "particle": "block/lantern", "all": "block/lantern" }, "elements": [ { "name": "glass", "from": [5, 1, 5], "to": [11, 6, 11], "faces": { "east": {"uv": [5, 1, 10, 7], "texture": "#3"}, "south": {"uv": [0, 0, 5, 5], "texture": "#1"}, "west": {"uv": [0, 0, 5, 5], "texture": "#2"} } } ] } } } Cheers TGG PS forgot to mention - for multilayer you will also need to set the RenderLayer like this: @SubscribeEvent public static void onClientSetupEvent(FMLClientSetupEvent event) { RenderTypeLookup.setRenderLayer(StartupCommon.blockGlassLantern, StartupClientOnly::isGlassLanternValidLayer); } // does the Glass Lantern render in the given layer (RenderType) - used as Predicate<RenderType> lambda for setRenderLayer public static boolean isGlassLanternValidLayer(RenderType layerToCheck) { return layerToCheck == RenderType.getSolid() || layerToCheck == RenderType.getTranslucent(); }
  22. Hi If you post a link to a GitHub I'll fork it and have a look in the next couple of days, if you like. Cheers TGG
  23. Hi What errors did you find with the example? It works fine for me. Did you try putting a suitable breakpoint into OBJModel and/or OBJloader to see whether the model is being loaded and parsed correctly? -TGG
  24. Howdy Containers, TileEntity, and ContainerScreen synchronisation has a few traps, you might find the working examples in this tutorial project useful (mbe30, mbe31) https://github.com/TheGreyGhost/MinecraftByExample The main trap is: your server-side Container will access the TileEntity, but your client side should not, otherwise you will probably get synchronisation problems because your client-side container is getting two copies of information: one via the container update packets, and one via tile-entity update packets. This page also has more background information http://greyminecraftcoder.blogspot.com/2020/04/containers-1144.html -TGG
  25. Hi Yeah that's me I got all the breath weapon sounds from freesound.org- things like bunsen burners, ice cracking, wind, waterfalls. I did layer a few sounds together using Audacity but nothing complicated. I've found most of the samples on the site to be decent quality because they're usually submitted by enthusiasts with good quality recording gear. Plenty good enough for minecraft mods Cheers TGG
×
×
  • Create New...

Important Information

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