Jump to content
Search In
  • More options...
Find results that contain...
Find results in...


  • Posts

  • Joined

  • Last visited


  • Gender
  • Location
  • Personal Text
    Obese Platypus

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

PianoManu's Achievements

Tree Puncher

Tree Puncher (2/8)



  1. Hey, thank you very much for your tip! Your approach was very veeeeeery helpful. That gave me a good idea and it works now, although I've chosen a slightly different way. This is how I solved the problem: At first I took a look into the PlayerEvent class (which is highly documentated, special thanks to whoever did that - it is unfortunately not very common), so I had the idea to search for some sort of "WorldEvent" class and check, whether it contains some useful events, and tah-dah, it contains a static class "WorldEvent.Load", where I can get an IWorld-instance, that features a player list. (The WorldEvent class is also documented pretty well, thanks again, you've made it easy for me!) I concluded, that I have to listen for both events, since I need the world (with the player list) and the player entity (to check, whether he is already registered in said list. The exact code looks like this: @SubscribeEvent public void playerLogginIn(final PlayerEvent.PlayerLoggedInEvent event) { //listen for "logging in"-event ServerPlayerEntity player = (ServerPlayerEntity) event.getPlayer(); if (!world.players().contains(player)) { //check whether the player (who is logging in) is already listed in the list of players on this world ServerWorld deepDark = player.server.getLevel(DDDMain.DEEP_DARK_DIMENSION); //if it's not the case (i.e. the player is new to this world), we need to teleport the player to this dimension instead if (deepDark != null) { DDDTeleporter teleporter = new DDDTeleporter(DDDConfig.SPAWN_POS); teleporter.setOverworldTeleporterPos(player.blockPosition()); player.setPos(DDDConfig.SPAWN_POS.getX(), DDDConfig.SPAWN_POS.getY(), DDDConfig.SPAWN_POS.getZ()); player.changeDimension(deepDark, teleporter); } } } @SubscribeEvent public void playerLoadsWorld(final WorldEvent.Load event) { //is called before "playerLoggingIn", so we can collect the world the player is joining world = event.getWorld(); //world is a private static IWorld-variable } After that, I registered this class to the MinecraftForge.EVENT_BUS in my Main class between "enqueueIMC" and "processIMC". I hope this was correct, I'm not quite sure where to put it, but it's working, so I think it should be okay. (Pls correct me if I'm wrong) Thanks again to you @ChampionAsh5357 for your helpful tip ❤️ Kind regards, Manu
  2. Hey guys, I made a custom dimension and everything is working completely fine (like world-generation, entering and exiting the dimension via portal block, respawning in the dimension, etc.), so I had the idea that after creating a new world, the player would start directly in my dimension instead of in the overworld. How could I achieve this? Thanks in advance, and kind regards, Manu Edit: if you need my github repository, here it is!
  3. Hey guys! I have some problems with the RenderLayers when testing my mod together with OptiFine. Some backstory: I made blocks, that can take on the model of any block using a tileentity that "stores" said block, and I also created baked models for all of them. It worked fine for solid blocks but not for transparent blocks, as they lose their transparency (see below). So I decided to change the RenderLayer to "translucent" using RenderTypeLookup.setRenderLayer(Registration.FRAMEBLOCK.get(), RenderType.getTranslucent()); where FRAMEBLOCK is the corresponding RegistryObject and "Registration" is the class where I register all my blocks and items. Right now it looks like that: (below you can see the "empty" frame blocks, namely cube, slab and stairs) You can right-click them to change the texture to the texture of the block you're holding. As I said, I used baked models to achieve the "mimicking"-effect. As you can see, it works fine, but only without OptiFine. When I use OptiFine, all my blocks are invisible and you can only see the black boundary box. I guess, it has something to do with the render layers, because I changed the RenderLayer for the "cube"-block to "solid", and the model is being rendered, again (but without transparency, see below) (Same three blocks, but I changed the RenderLayer-Type to "solid" for the cube block, the other two blocks - glass slab and stairs - are invisible, probably because of them being "translucent" and I guess OptiFine changes something how baked models are rendered) Now my question is: what can I do to make it work when using OptiFine? I already tried using "cutout" and "cutout-mipped" render types, but it wont change anything, the blocks stay invisible... Any help is appreciated. Regards, Manu If you want to take a look at the baked model: https://pastebin.com/MVPR7JW0 In case you need it, this is the github repository of my mod: https://github.com/PianoManu/BlockCarpentry/tree/Forge-1.16.2
  4. Thanks to you both @Beethoven92 and @Draco18s. That fixed my problem and helped a lot!
  5. Hey guys! I ran into some obstinate NoSuchMethodError today whilst testing my mod on a server (locally). I made a block with a tile entity, that mimics another block when it's right-clicked with said block. When I break the block containing the other block, my method "dropContainedBlock" is called to spawn an ItemEntity of the mimicked block. Now that is where I get the NoSuchMethodError exception and the server crashes. Here's my method. I mainly copied it from the vanilla jukebox, but the jukebox works a bit different because it "stores" only records, not blocks: //Used to drop the contained block //We check the tile entity, get the block from the tile entity and drop it at the block pos plus some small random coords in the world protected void dropContainedBlock(World worldIn, BlockPos pos) { if (!worldIn.isRemote) { TileEntity tileentity = worldIn.getTileEntity(pos); if (tileentity instanceof FrameBlockTile) { FrameBlockTile frameTileEntity = (FrameBlockTile) tileentity; //My custom tile entity BlockState blockState = frameTileEntity.getMimic(); //the contained blockstate if (!(blockState == null)) { worldIn.playEvent(1010, pos, 0); //some coords to spawn the item entity double d0 = (double) (worldIn.rand.nextFloat() * 0.7F) + (double) 0.15F; double d1 = (double) (worldIn.rand.nextFloat() * 0.7F) + (double) 0.060000002F + 0.6D; double d2 = (double) (worldIn.rand.nextFloat() * 0.7F) + (double) 0.15F; ItemStack itemstack1 = blockState.getBlock().asItem().getDefaultInstance(); //<---- THAT IS WHERE I GET THE ERROR ItemEntity itementity = new ItemEntity(worldIn, (double) pos.getX() + d0, (double) pos.getY() + d1, (double) pos.getZ() + d2, itemstack1); itementity.setDefaultPickupDelay(); worldIn.addEntity(itementity); //this should spawn the item entity - works fine in singleplayer but not on servers frameTileEntity.clear(); //resets my tile entity } } } } It works fine in singleplayer, but when I tried it on a local server, it crashes. I get the following error: "java.lang.NoSuchMethodError: net.minecraft.item.Item.func_190903_i()Lnet/minecraft/item/ItemStack;". This "func_190903_i()" has to be the "getDefaultInstance()"-method, it is annotated as @OnlyIn(Dist.CLIENT) and I guess that's the reason why it does not work on servers. Now my question: How do I get it to work on servers? Sorry if this is dumb, I'm pretty new and inexperienced... Regards, Manu In case you need the complete crash report: https://pastebin.com/hAa3Mcfz
  6. Oh okay, I didn't know this. I'll continue experimenting with this. Glass was the more important block right now. Thank you very much for your help! Regards, Manu
  7. I'm so stupid, you're right. Thank you so much! It works for glass, but the ice fence is still not translucent... I've changed the alpha value to 0.0f and it's working fine for glass. I also changed the render layer as you said: public static void setup() { RenderTypeLookup.setRenderLayer(Registration.FENCE_FRAMEBLOCK.get(), RenderType.getTranslucent()); } This method is called when the FMLClientSetupEvent is fired. Did I forget something concerning the ice block? As I wrote in the first post, it only needs to be translucent for ice and glass blocks and it is already very nice, that it works for glass. Thank you so much! Regards, Manu
  8. Hey guys, I'm again having a question concerning baked quads/models. How do I create transparent quads? This fence block I created takes the texture of the block it is clicked with (it can mimic blocks), but for glass and ice, the block appears solid. How can I make them transparent? Here you can see an example screenshot of the problem so far. I made a class that implements IDynamicBakedModel and for the getQuads(...)-method I made a method "createCuboid()" that returns a list of baked quads The createCuboid(...)-method: public static List<BakedQuad> createCuboid(float xl, float xh, float yl, float yh, float zl, float zh, TextureAtlasSprite texture, int tintIndex) { List<BakedQuad> quads = new ArrayList<>(); //Eight corners of the block Vec3d NWU = v(xl, yh, zl); //North-West-Up Vec3d NEU = v(xl, yh, zh); //... Vec3d NWD = v(xl, yl, zl); Vec3d NED = v(xl, yl, zh); Vec3d SWU = v(xh, yh, zl); Vec3d SEU = v(xh, yh, zh); Vec3d SWD = v(xh, yl, zl); Vec3d SED = v(xh, yl, zh); //South-East-Down //following if statements check whether one of the values goes over the block bounds -> increment/decrement them if (xl < 0) { xl++; } if (xh > 1) { xh--; } if (yl < 0) { yl++; } if (yh > 1) { yh--; } if (zl < 0) { zl++; } if (zh > 1) { zh--; } //six faces of the block, createQuad(...)-method is shown below // 1st vector, 2nd, 3rd, 4th, , small u, high u, small v, high v, quads.add(createQuad(NWU, NEU, SEU, SWU, texture, xl * 16, xh * 16, zl * 16, zh * 16, tintIndex)); quads.add(createQuad(SWD, SED, NED, NWD, texture, xl * 16, xh * 16, zl * 16, zh * 16, tintIndex)); quads.add(createQuad(SWU, SWD, NWD, NWU, texture, xl * 16, xh * 16, 16 - yh * 16, 16 - yl * 16, tintIndex)); quads.add(createQuad(NEU, NED, SED, SEU, texture, xl * 16, xh * 16, 16 - yh * 16, 16 - yl * 16, tintIndex)); quads.add(createQuad(NWU, NWD, NED, NEU, texture, zl * 16, zh * 16, 16 - yh * 16, 16 - yl * 16, tintIndex)); quads.add(createQuad(SEU, SED, SWD, SWU, texture, zl * 16, zh * 16, 16 - yh * 16, 16 - yl * 16, tintIndex)); return quads; } The createQuad(...)-method: private static BakedQuad createQuad(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, TextureAtlasSprite sprite, float ulow, float uhigh, float vlow, float vhigh, int tintIndex) { //normal vector for vertices and orientation Vec3d normal = v3.subtract(v2).crossProduct(v1.subtract(v2)).normalize(); BakedQuadBuilder builder = new BakedQuadBuilder(sprite); builder.setQuadOrientation(Direction.getFacingFromVector(normal.x, normal.y, normal.z)); //I've tried adding diffuse lighting but it didn't change much builder.setApplyDiffuseLighting(true); //only for tintable blocks like grass if (tintIndex > -1) { builder.setQuadTint(tintIndex); } //constructing vertices for the quad putVertex(builder, normal, v1.x, v1.y, v1.z, ulow, vlow, sprite, 1.0f, 1.0f, 1.0f); putVertex(builder, normal, v2.x, v2.y, v2.z, ulow, vhigh, sprite, 1.0f, 1.0f, 1.0f); putVertex(builder, normal, v3.x, v3.y, v3.z, uhigh, vhigh, sprite, 1.0f, 1.0f, 1.0f); putVertex(builder, normal, v4.x, v4.y, v4.z, uhigh, vlow, sprite, 1.0f, 1.0f, 1.0f); return builder.build(); } And the putVertex(...)-method: private static void putVertex(BakedQuadBuilder builder, Vec3d normal, double x, double y, double z, float u, float v, TextureAtlasSprite sprite, float r, float g, float b) { //lift of all vertexFormatElements saved in the builder and created in the makeQuads(...)-method ImmutableList<VertexFormatElement> elements = builder.getVertexFormat().getElements().asList(); for (int j = 0; j < elements.size(); j++) { //iterate through all elements and get the usage, add the corresponding values VertexFormatElement e = elements.get(j); switch (e.getUsage()) { case POSITION: builder.put(j, (float) x, (float) y, (float) z, 1.0f); break; case COLOR: builder.put(j, r, g, b, 1.0f); break; case UV: switch (e.getIndex()) { case 0: float iu = sprite.getInterpolatedU(u); float iv = sprite.getInterpolatedV(v); builder.put(j, iu, iv); break; case 2: builder.put(j, (short) 0, (short) 0); break; default: builder.put(j); break; } break; case NORMAL: builder.put(j, (float) normal.x, (float) normal.y, (float) normal.z); break; default: builder.put(j); break; } } } For this method, I've got some help from a tutorial by TurtyWurty Now as I said, I'm trying to get transparent quads. How would I achieve that? Thanks in advance, Manu
  9. I'm sorry to bother you again, but how would I do that? I've tried it that way: BlockState mimic = ...; //the block I want my block to mimic (from vanilla minecraft) ModelResourceLocation location = BlockModelShapes.getModelLocation(mimic); IBakedModel model = Minecraft.getInstance().getModelManager().getModel(location); //and now? How do I get the texture of the IBakedModel? I found no methods that would return the texture but I can't figure out how to get the texture of the model... Thanks for your help in advance! Regards, Manu
  10. Hey guys! I want to read a string from a json file. To be specific, I want to get the textures from a given block, that are included in its model file as a string. To be more specific, I need the texture of the given block, because I made a block that mimics said block using baked models (these work quite fine right now). The reason for this topic is, that there are blocks with different textures on each side (e.g. furnace has at least 4 textures, I think). Now I think, I know the basics of Gson and Json, but I have two questions: 1. How do I get the path of the model file of the said block? I've thought of something like this: public static TextureAtlasSprite getTextureFromJson(Block block, String namespace, String blockName) { Gson gson = new Gson(); String location = block.getRegistryName().getPath(); try { //determine the needed file - that's the problem BufferedReader br = new BufferedReader(new FileReader("--- I don't know what to put here ---")); //read value from file - I hope that's correct String blockTexture = gson.fromJson(br,String.class); //get the correct texture from the TextureAtlas, determined by the namespace (see question 2) and the read value from the model file return Minecraft.getInstance().getAtlasSpriteGetter(AtlasTexture.LOCATION_BLOCKS_TEXTURE).apply(new ResourceLocation(namespace, blockTexture));; } catch (FileNotFoundException e) { e.printStackTrace(); } return null; } And as I said, I don't know what to put in the FileReader... or should I use a completely different way? 2. How would I do the same with blocks from other mods? Yeah, I would use the namespace for the last part (getting the texture from the Atlas), but AFAIK model files from modded blocks are saved in their assets/models/block - directory or something like that. That second question is not very important at the moment, I would be glad, if I could get some help for the first question, maybe I could figure out the answer for the second question myself. Thanks in advance, I hope the questions are not too stupid Regards, Manu Sorry for bad english, I tried my best
  11. I'M COMPLETELY STUPID. You're right, at least nearly. I put the wrong blockstate in the getMimicQuads method, that's why I got those errors. It's working pretty well by now. That means I only had to change the first parameter from the method from "mimic" (which would be the block in the slab) to "state" (which is the state of the button) So I changed in the code from if (model != null) { //only if model (from block saved in tile entity) exists: return getMimicQuads(mimic, side, rand, extraData); } to if (model != null) { //only if model (from block saved in tile entity) exists: return getMimicQuads(state, side, rand, extraData); //first parameter was the problem } Thank you very much, dear SoulQuantum! (Thread can be closed, Problem is solved)
  12. Thanks for your reply! Yeah, that's what I tried at first, but the problem is, that this state only determines the block, that is saved in the button, not the button itself. I just tried it again, but Minecraft crashes and I get the error "Cannot get property DirectionProperty{name=facing, clazz=class net.minecraft.util.Direction, values=[north, south, west, east]} as it does not exist in Block{minecraft:spruce_planks}", obviously because Minecraft tries to get directions from planks, which have no directions... I still haven't found a solution Nevermind, SoulQuantum is right and I'm retarded (see last post)
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.