Jump to content

SoLegendary

Members
  • Posts

    95
  • Joined

  • Last visited

Everything posted by SoLegendary

  1. I got this crash while running my mod on the Forge client https://pastebin.com/GkGJi2gx java.lang.AbstractMethodError: Receiver class com.solegendary.reignofnether.unit.units.villagers.IronGolemUnit does not define or inherit an implementation of the resolved method 'abstract float getAttackDamage()' of interface For some context, I have an interface "AttackerUnit" with an abstract method "getAttackDamage" defined here: https://github.com/SoLegendary/reignofnether/blob/1.19/src/main/java/com/solegendary/reignofnether/unit/interfaces/AttackerUnit.java#L28 A few of my mod's mobs implement AttackerUnit, including my IronGolemUnit and VindicatorUnit, defined here: https://github.com/SoLegendary/reignofnether/blob/1.19/src/main/java/com/solegendary/reignofnether/unit/units/villagers/IronGolemUnit.java#L75 https://github.com/SoLegendary/reignofnether/blob/1.19/src/main/java/com/solegendary/reignofnether/unit/units/villagers/VindicatorUnit.java#L84 I am very confused as to why the client thinks that method isn't implemented when it clearly is, right there on line 75. IntelliJ would have highlighted a build error and not allowed me to compile. Even weirder is that my other AttackerUnit classes like the VindicatorUnit implement the method in the exact same way and they DO work, it's the just the IronGolemUnit that causes this crash. As far as I can tell they're implemented in identical ways. Additionally, for some reason this crash ONLY happens on the Forge client. When I run the code on my local testing environment (single player and multiplayer) it works completely fine.
  2. Oh, that was way simpler than I thought lol, thanks
  3. I'm forcing chunks around my entities like so: ChunkAccess chunk = level.getChunk(entity.getOnPos()); ForgeChunkManager.forceChunk(level, ReignOfNether.MOD_ID, entity, chunk.getPos().x, chunk.getPos().z, true, true); However, when they die/leave the level I need to remove these forced chunks. How can I get an instance of ForgeChunkManager.TicketHelper so that I can remove these chunks? It isn't static like the forceChunk method and I'm not sure where to get all of the paramters for the constructor to create my own instance (if that is even the intended way).
  4. I'm trying to modify the damage of ranged weapons (bows and crossbows) without having to enchant them. So far I've tried this, but it only modifies the left click melee damage, not the ranged damage dealt by firing them: ItemStack cbowStack = new ItemStack(Items.CROSSBOW); AttributeModifier mod = new AttributeModifier(UUID.randomUUID().toString(), 100.0D, AttributeModifier.Operation.ADDITION); cbowStack.addAttributeModifier(Attributes.ATTACK_DAMAGE, mod, EquipmentSlot.MAINHAND); evt.getEntity().setItemSlot(EquipmentSlot.MAINHAND, cbowStack); I also don't want to modify any ammo since I'm planning to give these weapons to mobs (who I assume do not use ammo).
  5. Ok so after banging my head against chunk and entity rendering code for a day I just thought: "wait, what if I just kept the entity reference after it leaves the ClientLevel in EntityLeaveLevelEvent?" So that's what I did, and apparently it worked, I can now retain selection of my entities and issue them commands after moving the player far off, even beyond chunk rendering distance without forcing chunks. Though this method does it have its downsides: I can't update clientside data for the entity while its outside of view (eg. health and position). I have no reliable way to detect when an entity actually properly leaves the level (ie. by dying or changing dimensions). I'm assuming this method works because the server is still tracking all of these entities regardless of the player's distance, so maybe I can sync the data from the server?
  6. I intend for this game mode in my mod to be fully compatible with regular vanilla players so I don't want to make separate virtual levels at all. Is it possible to replicate the same logic that ClientPlayers have to have the chunks around them be rendered and have it apply to my Unit entities as well? I'm sure that if I can do that along with Serverside chunk forcing, I can get this to work as intended. I could even lower their effective chunk render distance to be 1 since all I really need is the chunk they're currently standing on. Do you know the class where that kind of logic is handled?
  7. I'm creating an RTS mod with a top-down camera view. This means that the player has to be able to pan their camera far away and still retain selection of units (eg. sending an army across the map to an opponent's base). 'Panning the camera' simply means moving their player entity in spectator mode. However, unit commands rely on the entity and its chunk still being loaded, watch what happens in my mod when I move the camera too far (ignore the weird villager rendering bug): https://i.imgur.com/kFguQBF.mp4 This happens because I retain selection with this code: @SubscribeEvent public static void onRenderLivingEntity(RenderLivingEvent.Pre<? extends LivingEntity, ? extends Model> evt) { ArrayList<LivingEntity> units = UnitClientEvents.getSelectedUnits(); units.sort(Comparator.comparing(HudClientEvents::getSimpleEntityName)); if (units.size() <= 0) hudSelectedEntity = null; else if (hudSelectedEntity == null || units.size() == 1 || !units.contains(hudSelectedEntity)) hudSelectedEntity = units.get(0); } In UnitClientEvents I maintain a list of my unit Ids with EntityLeaveLevelEvent and EntityJoinLevelEvent and moving out of render range appears to remove them from this list until I move back into render range: @SubscribeEvent public static void onEntityLeave(EntityLeaveLevelEvent evt) { Entity entity = evt.getEntity(); if (entity instanceof Unit unit && evt.getLevel().isClientSide) allUnitIds.removeIf(e -> e == entity.getId()); } @SubscribeEvent public static void onEntityJoin(EntityJoinLevelEvent evt) { Entity entity = evt.getEntity(); if (entity instanceof Unit unit && evt.getLevel().isClientSide) allUnitIds.add(entity.getId()); } I assumed that forcing a chunk would also render the entities too but that doesn't seem to be the case, either because forced chunks don't care about rendering and/or the 'forcing' doesn't care about the client at all. EDIT: I found this post that references rendering faraway chunks clientside in 1.12 but is there a 1.19.2 equivalent of these classes?
  8. @ChampionAsh5357 I should have been a bit more specific with my question. The method to force a chunk for an entity is: forceChunk(ServerLevel level, String modId, Entity owner, int chunkX, int chunkZ, boolean add, boolean ticking) But the fact it accepts a chunkX and chunkZ kind of implies that it keeps only the chunk that is passed loaded and does not move. Does the forced automatically chunk change as the entity moves or do I have to check myself if the entity moved into a new chunk each tick? EDIT: I'm trying to force a chunk with my entities here but it doesn't seem to work (I lose access to them via level.getEntity once my player's out of range): @SubscribeEvent public static void onEntityJoin(EntityJoinLevelEvent evt) { Entity entity = evt.getEntity(); if (entity instanceof Unit && !evt.getLevel().isClientSide) { ChunkAccess chunk = evt.getLevel().getChunk(entity.getOnPos()); ForgeChunkManager.forceChunk((ServerLevel) evt.getLevel(), ReignOfNether.MOD_ID, entity, chunk.getPos().x, chunk.getPos().z, true, true); } }
  9. I recently read up about ForgeChunkManager and how it can be used to keep particular chunks loaded. Namely that you submit 'tickets' for each forced chunk which are tagged by UUID, BlockPos or Entity. However, I want to keep the chunks around particular non-player entities loaded - do I have to check the position on every tick for every one of these entities in order to change its associated ticket? (ie. remove the old one and create a new one) That doesn't seem very efficient to me. Is there a more built-in way to automatically keep the chunk around an entity loaded?
  10. To anyone who is trying to do this I solved it - the issue was purely bad paths. I moved my resource_icons.json to assets/<modid>/font/ and changed the file lines to this style: "file": "reignofnether:icons/items/wheat.png", The ResourceLocation in my withFont() call is now: new ResourceLocation(ReignOfNether.MOD_ID, "resource_icons"))) Thanks for the help @warjort, but now do you know how to mix multiple fonts on the same line in a tooltip? When I mix regular text with this unicode mapping on one line the regular text just shows as rectangle (and I really don't want to have to remap all letters and numbers manually in my JSON) EDIT: nevermind, realised I can just copy the vanilla MC's default.json mapping for ASCII characters: { "type": "bitmap", "file": "minecraft:font/ascii.png", "ascent": 7, "chars": [ "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000", "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000", "\u0020\u0021\u0022\u0023\u0024\u0025\u0026\u0027\u0028\u0029\u002a\u002b\u002c\u002d\u002e\u002f", "\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u003a\u003b\u003c\u003d\u003e\u003f", "\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004a\u004b\u004c\u004d\u004e\u004f", "\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057\u0058\u0059\u005a\u005b\u005c\u005d\u005e\u005f", "\u0060\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068\u0069\u006a\u006b\u006c\u006d\u006e\u006f", "\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077\u0078\u0079\u007a\u007b\u007c\u007d\u007e\u0000", "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000", "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u00a3\u0000\u0000\u0192", "\u0000\u0000\u0000\u0000\u0000\u0000\u00aa\u00ba\u0000\u0000\u00ac\u0000\u0000\u0000\u00ab\u00bb", "\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510", "\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567", "\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580", "\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u2205\u2208\u0000", "\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u0000\u221a\u207f\u00b2\u25a0\u0000" ] },
  11. I've got working code to render a tooltip, and I have a folder full of icons that I want to turn into unicode symbols in my tooltip. I know that with resourcepacks this is possible, as seen in this video but I don't want to have users of my mod download and install a resourcepack separately. I have this JSON file at resources/assets/reignofnether/fonts/resource_icons.json { "providers": [ { "type": "bitmap", "file": "reignofnether/textures/icons/items/wheat.png", "ascent": 9, "height": 9, "chars": ["\uE000"] }, { "type": "bitmap", "file": "reignofnether/textures/icons/items/wood.png", "ascent": 9, "height": 9, "chars": ["\uE001"] } ] } And tried using it with this code: List<FormattedCharSequence> tooltipLines = List.of( List.of(FormattedCharSequence.forward( "\uE000 \uE001 test regular text", Style.EMPTY.withFont(new ResourceLocation(ReignOfNether.MOD_ID, "textures/fonts/resource_icons.json")))) ) MC.screen.renderTooltip(poseStack, tooltipLines, mouseX, mouseY, MC.font); But all I get are invalid characters like this:
  12. I have a similar feature on my own mod (though I think my solution is a bit overkill). I put my .nbt files in src/main/resources/data/<modid>/structures And I read the files in with these functions: public static ArrayList<BuildingBlock> getBuildingBlocks(String structureName, LevelAccessor level) { ResourceManager resourceManager; if (level.isClientSide()) resourceManager = Minecraft.getInstance().getResourceManager(); else resourceManager = level.getServer().getResourceManager(); CompoundTag nbt = getBuildingNbt(structureName, resourceManager); ArrayList<BuildingBlock> blocks = new ArrayList<>(); // load in blocks (list of blockPos and their palette index) ListTag blocksNbt = nbt.getList("blocks", 10); ArrayList<BlockState> palette = getBuildingPalette(nbt); for(int i = 0; i < blocksNbt.size(); i++) { CompoundTag blockNbt = blocksNbt.getCompound(i); ListTag blockPosNbt = blockNbt.getList("pos", 3); blocks.add(new BuildingBlock( new BlockPos( blockPosNbt.getInt(0), blockPosNbt.getInt(1), blockPosNbt.getInt(2) ), palette.get(blockNbt.getInt("state")) )); } return blocks; } public static CompoundTag getBuildingNbt(String structureName, ResourceManager resManager) { try { ResourceLocation rl = new ResourceLocation("reignofnether", "structures/" + structureName + ".nbt"); Optional<Resource> rs = resManager.getResource(rl); return NbtIo.readCompressed(rs.get().open()); } catch (Exception e) { System.out.println(e); return null; } } public static ArrayList<BlockState> getBuildingPalette(CompoundTag nbt) { ArrayList<BlockState> palette = new ArrayList<>(); // load in palette (list of unique blockstates) ListTag paletteNbt = nbt.getList("palette", 10); for(int i = 0; i < paletteNbt.size(); i++) palette.add(NbtUtils.readBlockState(paletteNbt.getCompound(i))); return palette; } BuildingBlock is just my own class that combines BlockPos, BlockState and has a checker to see if it exists in the world yet. I spawn the building in with this function. Remember placing any block needs to be done serverside, so Level level here needs to be from a WorldTickEvent where level is serverside. I just call buildNextBlock() on every tick. private void buildNextBlock(Level level) { ArrayList<BuildingBlock> unplacedBlocks = new ArrayList<>(blocks.stream().filter(b -> !b.isPlaced).toList()); int minY = getMinCorner(unplacedBlocks).getY(); ArrayList<BuildingBlock> validBlocks = new ArrayList<>(); // iterate through unplaced blocks and start at the bottom Y values for (BuildingBlock block : unplacedBlocks) { BlockPos bp = block.getBlockPos(); if ((bp.getY() <= minY) && (!level.getBlockState(bp.below()).isAir() || !level.getBlockState(bp.east()).isAir() || !level.getBlockState(bp.west()).isAir() || !level.getBlockState(bp.south()).isAir() || !level.getBlockState(bp.north()).isAir() || !level.getBlockState(bp.above()).isAir())) validBlocks.add(block); } if (validBlocks.size() > 0) validBlocks.get(0).place(); } BuildingBlock.place() is: BlockPos bp = nextBlock.getBlockPos(); BlockState bs = nextBlock.getBlockState(); if (serverLevel.isLoaded(bp)) { serverLevel.setBlockAndUpdate(bp, bs); serverLevel.levelEvent(LevelEvent.PARTICLES_DESTROY_BLOCK, bp, Block.getId(bs)); serverLevel.levelEvent(bs.getSoundType().getPlaceSound().hashCode(), bp, Block.getId(bs)); blockPlaceQueue.removeIf(i -> i.equals(nextBlock)); } The reason I say this is a bit overkill is my code builds the building over the course of a few seconds from the ground up (1 block per tick) with sound and particle effects - it's a pretty fancy way to do it but if you just want to place all the blocks at once with no effects, you can probably ignore that 2nd chunk of code and skip straight to serverLevel.setBlockAndUpdate()
  13. Ok cool, I got it working now. One other feature I would like is rendering icons on the box, inline if possible. Unicode sounds like the most compatible solution but barring that if I could at least get the coordinates that the tooltip box corners are rendered at so I can just blit my own graphics that'd work too.
  14. I'm looking to render a tooltip text box like the one you get for hovering over items, eg: I know the basics of rendering including usage of poseStack in render events, but I just don't know where I can find a class method that can do this. I'm also hoping said function includes text formatting (bold, italics, colour, etc.) and (if possible) multiline text wrapping but if I have to write that myself any tips for it would be greatly appreciated.
  15. @warjort I've removed the call from Server -> Client to update blocks and its seemed to have stopped the crashes for the time being. However, when I use setBlockAndUpdate() it doesn't seem to trigger a BlockEvent.EntityPlaceEvent on the client side. I want to set and destroy a dummy block on the spot with each block creation so that we get the particle and sound effects on each block being built. This is the code I added to BuildingClientEvents: @SubscribeEvent public static void onBlockPlace(BlockEvent.EntityPlaceEvent evt) { BlockPos bp = evt.getPos(); BlockState bs = evt.getState(); if (MC.level != null && MC.level.isLoaded(bp)) { MC.level.setBlock(bp.east(), bs, 1); MC.level.destroyBlock(bp, false); } }
  16. Thanks for the pointers... I probably will need to do quite a bit of refactoring - I also didn't know about a lot of these methods lie setBlockAndUpdate
  17. I have a feature whereby a user can set a predefined structure on and it will place the blocks both serverside and clientside once every few ticks (currently every 6 ticks). The general logic flow I have is: User selects and places a Building (array of BlockPos/BlockState pairs) Client -> Server packet to initialise a Building object containing this block data On every 6th tick: Server places a block from the array Server -> Client packet to place the same block Video of this in action: https://imgur.com/a/gb9rpJ3 However, sometimes when I do this I get an error in the LongOpenHashSet java class after some of the blocks are placed. java.lang.ArrayIndexOutOfBoundsException: Index 126 out of bounds for length 65 (note the index numbers are always different on each crash) It seems random to me how many blocks it places before crashing or whether it even crashes at all. Full crash log: https://pastebin.com/6JC9nm5B Link to the code that seems to be causing the error (When I comment these lines out the issue stops, but of course, then I don't get the blocks placed clientside): https://github.com/SoLegendary/reignofnether/blob/1.19/src/main/java/com/solegendary/reignofnether/building/BuildingClientEvents.java#L358-L360 I tried wrapping the above lines in a try-catch block but it doesn't seem to actually catch anything.
  18. I updated to the new class and method names but am getting this error on running the build. I also deleted my .gradle and buiild folders, ran genIntellijRuns again and refreshed my gradle dependencies. This is my build.gradle: https://pastebin.com/bGTkx3vi This is the crash error: 2022-08-29 23:49:58,221 main WARN Advanced terminal features are not available in this environment [23:49:58] [main/INFO] [cp.mo.mo.Launcher/MODLAUNCHER]: ModLauncher running: args [--launchTarget, forgeclientuserdev, --version, MOD_DEV, --assetIndex, 1.18, --assetsDir, C:\Users\Nick\.gradle\caches\forge_gradle\assets, --gameDir, ., --fml.forgeVersion, 40.0.40, --fml.mcVersion, 1.18.2, --fml.forgeGroup, net.minecraftforge, --fml.mcpVersion, 20220404.173914, -mixin.config=reignofnether.mixins.json] [23:49:58] [main/INFO] [cp.mo.mo.Launcher/MODLAUNCHER]: ModLauncher 10.0.8+10.0.8+main.0ef7e830 starting: java version 17.0.2 by Eclipse Adoptium; OS Windows 10 arch amd64 version 10.0 [23:49:58] [main/DEBUG] [cp.mo.mo.LaunchServiceHandler/MODLAUNCHER]: Found launch services [fmlclientdev,forgeclient,minecraft,forgegametestserverdev,fmlserveruserdev,fmlclient,fmldatauserdev,forgeserverdev,forgeserveruserdev,forgeclientdev,forgeclientuserdev,forgeserver,forgedatadev,fmlserver,fmlclientuserdev,fmlserverdev,forgedatauserdev,testharness,forgegametestserveruserdev] [23:49:58] [main/DEBUG] [cp.mo.mo.NameMappingServiceHandler/MODLAUNCHER]: Found naming services : [srgtomcp] Exception in thread "main" java.lang.IllegalAccessError: class cpw.mods.modlauncher.util.ServiceLoaderUtils (in module cpw.mods.modlauncher) cannot access class cpw.mods.niofs.union.UnionFileSystem (in module cpw.mods.securejarhandler) because module cpw.mods.securejarhandler does not export cpw.mods.niofs.union to module cpw.mods.modlauncher at MC-BOOTSTRAP/[email protected]/cpw.mods.modlauncher.util.ServiceLoaderUtils.lambda$fileNameFor$2(ServiceLoaderUtils.java:52) at java.base/java.util.Optional.map(Optional.java:260) at MC-BOOTSTRAP/[email protected]/cpw.mods.modlauncher.util.ServiceLoaderUtils.fileNameFor(ServiceLoaderUtils.java:52) at MC-BOOTSTRAP/[email protected]/cpw.mods.modlauncher.LaunchPluginHandler.lambda$new$2(LaunchPluginHandler.java:50) at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) at java.base/java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1850) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575) at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260) at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616) at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622) at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:627) at MC-BOOTSTRAP/[email protected]/cpw.mods.modlauncher.LaunchPluginHandler.<init>(LaunchPluginHandler.java:51) at MC-BOOTSTRAP/[email protected]/cpw.mods.modlauncher.Launcher.<init>(Launcher.java:64) at MC-BOOTSTRAP/[email protected]/cpw.mods.modlauncher.Launcher.main(Launcher.java:77) at MC-BOOTSTRAP/[email protected]/cpw.mods.modlauncher.BootstrapLaunchConsumer.accept(BootstrapLaunchConsumer.java:26) at MC-BOOTSTRAP/[email protected]/cpw.mods.modlauncher.BootstrapLaunchConsumer.accept(BootstrapLaunchConsumer.java:23) at [email protected]/cpw.mods.bootstraplauncher.BootstrapLauncher.main(BootstrapLauncher.java:149) Process finished with exit code 1
  19. originPos is just the corner of the structure I'm placing, because the structure only has relative BlockPos data starting at (0,0) - this can be wherever you want it to be, whether its the blocks the player is looking at or something else. In my case im building a top down gamemode, so its whatever my mouse cursor is over.
  20. Just one more thing I want to do: create a green OverlayTexture (to indicate the structure is a valid placement that doesn't clip other blocks). It seems the OverlayTexture class only has RED_OVERLAY_V and WHITE_OVERLAY_V available.
  21. Ok so I managed to figure out the parameters, but the question of position remains, and my current code is just rendering all of the blocks on top of each other at the centre of my screen (it should be rendering that house). Ok solved it - just forgot to push, translate and pop the matrix - I'll leave my final code below to anyone who wants to know how to do the same thing: My current code (BuildingBlock is my custom class): for (BuildingBlock block : blocksToPlace) { BlockRenderDispatcher renderer = MC.getBlockRenderer(); BlockState bs = block.getBlockState; BlockPos bp = block.blockPos; IModelData modelData = renderer.getBlockModel(bs).getModelData(MC.level, bp, bs, ModelDataManager.getModelData(MC.level, bp)); matrix.pushPose(); matrix.translate( bp.getX() - originPos.getX(), bp.getY() - originPos.getY(), bp.getZ() - originPos.getZ()); renderer.renderSingleBlock( bs, matrix, MC.renderBuffers().crumblingBufferSource(), 15728880, OverlayTexture.NO_OVERLAY, modelData); matrix.popPose(); }
  22. I want to use BlockRendererDispatcher.renderSingleBlock() to render a block model in the world clientside only so that the player can see where they're about to place a structure without actually placing it. I have the BlockPos and BlockState of each block I want to render this way, but I don't know how to get the MultiBufferSource and the IModelData. In fact, renderSingleBlock() doesn't even accept any BlockPos as a parameter so how does it know where to render it?
  23. I'm trying to read some .nbt files that I've generated in-game (and moved to my mod's resources directory) with this code: ResourceLocation fullRl = new ResourceLocation("reignofnether", "structures/" + structureName + ".nbt"); Resource rs = manager.resourceManager.getResource(fullRl); CompoundTag nbt = NbtIo.readCompressed(rs.getInputStream()); System.out.println(nbt); I keep getting this error: java.io.FileNotFoundException: reignofnether:structures/villager_house.nbt Even though I've made ResourceLocations to all of those other resources just fine in the same way, eg: private static final ResourceLocation TEXTURE_CURSOR = new ResourceLocation("reignofnether", "textures/cursors/customcursor.png"); EDIT: ok so I realised I was running the above code serverside because I needed access to ServerLevel.getStructureManager(), and I guess maybe resources aren't available serverside? How can I access the .nbt files inside the world save folder instead serverside?
  24. I'm trying to do an RTS-style fog of war effect by darkening all blocks not within range of a particular mob. My current method of doing this is to simply iterate over all blocks in the view cone (that are exposed to air) and draw a dark block around them using a vertexConsumer with this result: my code: https://pastebin.com/SfmCGHKj The problem with this is 3 fold: looks very glitchy with lots of tearing during camera movement doesn't account for non-solid blocks like tall grass - these show a visible black cube around them performance is terrible, my FPS drops by half whenever I run it I can solve the weird grid-like effect on the water and the performance somewhat by drawing only block faces next to air but the other problems remain. I can only think of two solutions to this either of which I have no idea how to implement: GLSL shaders Changing block light render values (clientside only) Which way would be better, and/or is there another option I haven't thought of? How difficult would either of these options be?
  25. I managed to get the box drawn, but no matter how I change the colour() params, it seems to always be a black box... https://pastebin.com/BSjw2Ch1
×
×
  • Create New...

Important Information

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