Jump to content

JoieNL

Members
  • Posts

    32
  • Joined

  • Last visited

Everything posted by JoieNL

  1. Heya, thanks for the swift reply. Changing the method return value to InteractionResult.sidedSuccess(level.isClientSide) actually resolved the issue somehow. Thanks for pointing out the flags in the Block class too, I was looking for those exactly. Not that I need them anymore, but at least I know where to look now.
  2. Hey y'all, I've been working on a simple farming mod for a while, and I ran into some trouble trying to implement a scythe tool. When the player right-clicks on a crop using the tool, I want that crop and the two adjacent crops (in the direction perpendicular to the player's horizontal view direction) to break. Currently, when I right-click a crop with a scythe, the clicked crop breaks normally but the adjacent crops stay behind as ghost blocks. All three crops do drop their respective loot, however. Interacting with the ghost blocks makes them vanish. Here's my relevant code in the ScytheItem class: My guess is that I should pass some (non-default) integer flag in all the calls to destroyBlock. I can't seem to find what each integer flag does though. Any help would be greatly appreciated!
  3. Alright, I'm an idiot. I was registering my codec in a static initialiser in the biome provider class, meaning it was only registered when the class was loaded (i.e. when creating a world with my custom world type). I moved the registration to common setup and it works fine now.
  4. Hey guys, I've been working on my custom world type lately, and I ran into an issue again. My custom world type is based off of the default world type, but I would like to replace the default fluid used below sea level by compressed ice. I noticed that vanilla defines the default fluid using the DimensionSettings class. I would like to use my custom settings (say "FROZEN_OVERWORLD_SETTINGS") for the NoiseChunkGenerator constructor that I pass to the ForgeWorldType constructor: new ForgeWorldType((biomeRegistry, dimensionSettingsRegistry, seed) -> new NoiseChunkGenerator(new FrozenOverworldBiomeProvider(seed, false, false, biomeRegistry), seed, () -> FROZEN_OVERWORLD_SETTINGS) ) The problem is: I can't instantiate DimensionSettings without using reflection. The constructor is private, the class is final, and there is no builder method. Using reflection seems to work when first creating a world and entering is as long as the client is left running. But after closing the game and rerunning it, I am unable to re-enter the world, instead getting the following error message: [13:07:56] [Render thread/ERROR] [minecraft/SaveFormat]: WorldGenSettings: Unknown registry key: aid:biome_source missed input: {"minecraft:overworld":{generator:{settings:"aid:frozen_overworld",seed:-2783071959927850081L,biome_source:{seed:-2783071959927850081L,large_biomes:0b,type:"aid:biome_source"},type:"minecraft:noise"},type:"minecraft:overworld"}}; Overworld settings missing I know this error message is referring to the registry key I use to register my biome provider codec in my FrozenOverworldBiomeProvider class: Registry.register(Registry.BIOME_PROVIDER_CODEC, new ResourceLocation(MOD_ID, "biome_source"), CODEC); Yet this line seems necessary, because I get this error message when creating a world without the codec being registered: [13:27:33] [Render thread/ERROR] [minecraft/Minecraft]: Error reading worldgen settings after loading data packs: Unknown registry element RecordCodec[UnitDecoder[joienl.world.FrozenOverworldBiomeProvider$$Lambda$4386/249483336@a859c5] * Field[seed: Long] * OptionalFieldCodec[legacy_biome_init_layer: Bool][flatXmapped] * Field[large_biomes: Bool][mapResult OrElse[false]] * RegistryLookupCodec[ResourceKey[minecraft:root / minecraft:worldgen/biome]]] [13:27:33] [Render thread/ERROR] [minecraft/ServerWorldInfo]: WorldGenSettings: Unknown registry element RecordCodec[UnitDecoder[joienl.world.FrozenOverworldBiomeProvider$$Lambda$4386/249483336@a859c5] * Field[seed: Long] * OptionalFieldCodec[legacy_biome_init_layer: Bool][flatXmapped] * Field[large_biomes: Bool][mapResult OrElse[false]] * RegistryLookupCodec[ResourceKey[minecraft:root / minecraft:worldgen/biome]]] I am unable to reload the world at all if I don't register the codec. I just don't know where to look anymore. Any help would be greatly appreciated.
  5. So it took me a few days, but I managed to figure things out myself. First of all, apparently RegistryObject<Biome> fields used with DeferredRegister cannot be referenced directly. When you want to reference your custom biomes, you need to get them from the biome registry itself. This solves the issues I had with the getNoiseBiome method. Secondly, the codec thing. All I had to do to get that working, was to register the codec in a static initialiser in my biome provider class: static { Registry.register(Registry.BIOME_PROVIDER_CODEC, new ResourceLocation(MOD_ID, "biome_source"), CODEC); } I hope this helps anyone trying this for themselves.
  6. Hey y'all, I've been trying my hands at making a new world type lately. This works exactly as it should using the recently added class ForgeWorldType . Now, I want my custom world type to use a set of custom biomes, and this is where I run into trouble. I've copied the code in OverworldBiomeProvider and swapped the entries of the biomes field out for my custom biomes. However, the vanilla biomes spawn like in the Default world type when I generate a world using my custom world type. And for the record: yes, I am passing it into the constructor of ForgeWorldType. I have already located the issue: the getNoiseBiome method in my copied biome provider class uses a lookup registry that always contains the vanilla biomes. How would I go about correctly implementing this method, such that my custom biomes generate instead? And on the subject of implementing biome provider methods, how do I implement the getBiomeProviderCodec method? TL;DR: How do I implement BiomeProvider's abstract methods in my custom biome provider class?
  7. Good thing this forum has people with functional brain cells to compensate for my lack thereof. I was running runClient instead of runData. I'll look into generating the bow model files once I find the time to. If I run into any problems along the way, I'll post them here.
  8. I can't believe I've never seen this Forge test library before, thanks for sharing! I'm still having trouble though. My model provider class listens to GatherDataEvent and the listener is registered to the mod event bus like in the Forge test, but it seems the event never fires. The model provider should spit some "Hello World"s into the console but it never does. Here's the relevant part of my model provider class: public class ModelGenerators { static { System.out.println("Hello World!"); } @SubscribeEvent public static void gatherData(GatherDataEvent event) { System.out.println("Hello World!"); DataGenerator generator = event.getGenerator(); ExistingFileHelper helper = event.getExistingFileHelper(); if (event.includeClient()) { generator.addProvider(new BowModelProvider(generator, helper)); } } } In my main mod class I have added the following line: FMLJavaModLoadingContext.get().getModEventBus().addListener(ModelGenerators::gatherData); What's going wrong here?
  9. Hmm... extending ItemModelProvider seems like the way to go, but how would I implement the registerModels method? The documentation on https://mcforge.readthedocs.io/en/1.16.x/datagen/modelproviders/ is rather concise and there's obviously no vanilla implementations to look at.
  10. Hiya guys, I'm developing a mod that adds, among other things, custom bows and arrows to the game. The different arrows can have different damage output, knockback, velocity, or even special attributes. I would like the player to be able to see which arrow they're using when pulling a bow, as opposed to how vanilla handles things. That is, I want to be able to dynamically add another layer to my bow models depending on the arrow used, without having to write a .json file for every combination of bow, arrow, and pull phase. Now I know that ItemModelsProperties are a thing, but I feel like this is not the right approach. I'm pretty sure I'd have to add overrides for every new arrow type to every new bow type model if I used that. And if I were to add another arrow type, I'd have to change every bow model again. Seems like a lot of unnecessary work. I looked at vanilla's DynamicBucketModel and forge's ItemLayerModel , and these look promising. I'm just not sure how to go about making these bow models in code, and especially where to register them. Could anyone point me in the right direction or provide some relevant documentation/code? Thanks in advance!
  11. You're right, I completely missed that because it's called twice during setup as well and it crashed before I could test stuff in-game. It was stupid of me to assume it wasn't called in-game. I got things working now with a simple nullity check on the world parameter. Thanks for clearing things up!
  12. Hey everyone, I've always been a fan of dynamic items that display useful information like the clock and compass, and I want to make my own take on the clock this time. Instead of having the texture update though, I would like it to display the current day time as a tooltip. Is this possible? From what I've gathered, tooltips are generated whenever an ItemStack is created, and then never touched again. Maybe I can do something with NBT? Hopefully someone can help me out, because I'm rather stuck.
  13. Thanks everyone! I got things working with ease thanks to your help. Here's what my ModItemGroup class looks like now for future reference: public class ModItemGroup extends ItemGroup { private Supplier<ItemStack> displayStack; public static final ModItemGroup ACCESSORIES = new ModItemGroup("accessories", () -> new ItemStack(ModItems.SHACKLE.get())); private ModItemGroup(String label, Supplier<ItemStack> displayStack) { super(label); this.displayStack = displayStack; } @Override public ItemStack createIcon() { return displayStack.get(); } }
  14. Hey y'all, I'm currently working on a mod that adds a bunch of equipable accessories to the game. I've put them all in their own creative tab, which works fine. The only thing I'm stuck on is the icon. I'd like it to be one of the accessories, but this creates a reference loop. I need to supply the custom ItemGroup to the Item when I register it: public static final RegistryObject<Item> SHACKLE = ITEMS.register("shackle", () -> new Item(new Item.Properties().group(ModItemGroup.ACCESSORIES))); But at the same time I need to supply the Item to the custom ItemGroup when I create it: public static final ItemGroup ACCESSORIES = new ItemGroup("accessories") { @Override public ItemStack createIcon() { return new ItemStack(ModItems.SHACKLE.get(); } }; How do I work around this issue? I've tried registering the Shackle without an ItemGroup first, then creating the ItemGroup, and then setting the Shackle's ItemGroup with SHACKLE.get().getCreativeTabs().add(), but this doesn't work either. I'm probably overlooking something really simple, but my brain has just been refusing to work lately. Thanks in advance for any help!
  15. Thanks for the quick reply. I had indeed already had a look at this post and read about the offsetting by (8, 8). But I don't think this is the problem. I believe that vanilla methods like MapGenStructure#generateStructure handle that: int i = (chunkCoord.x << 4) + 8; int j = (chunkCoord.z << 4) + 8; I think things are going wrong because pieces of the structure (and with pieces I mean StructureFrozenNetherBridgePieces.Pieces) are being generated in unloaded chunks when they should not. I believe that pieces that are awaiting generation are stored in StructureFrozenNetherBridgePieces.Start#pendingChildren and generated in MapGenFrozenNetherBridge.Start like such: List<StructureComponent> list = structurefrozennetherbridgepieces$start.pendingChildren; while (!list.isEmpty()) { int i = random.nextInt(list.size()); StructureComponent structurecomponent = list.remove(i); structurecomponent.buildComponent(structurefrozennetherbridgepieces$start, this.components, random); } My hypothesis that somehow all pieces of the structure end up in this list when the first crossing is initialised and everything tries to generate at once. Does anyone know how this could be? Edit: I should've definitely checked this before I made this post... Printing the list after it is initialised reveals that it is always empty of all things: [13:37:16] [Server thread/INFO]: [STDOUT]: [] Does this mean that all the structure pieces generate even before entering this list? It would explain why it remains empty. I will conduct further research regarding this finding. Edit again: I did some more testing and it turns out that this list was empty because things were passing null all over the place. Bottom line is: IntelliJ was trying to be a smartass, replacing this... return isAboveGround(structureboundingbox) && StructureComponent.findIntersecting(p_175882_0_, structureboundingbox) == null ? new StructureFrozenNetherBridgePieces.Straight(p_175882_6_, p_175882_1_, structureboundingbox, p_175882_5_) : null; ...with... return null; ...for every piece. Now that that's solved, the entire structure spawns, but the cascading worldgen lag remains. I'll continue my investigations. I keep having to edit this post: I've 'turned off' all world generation features for my dimension except fortresses, and the cascading worldgen lag is gone. This means that there has been something besides the fortresses causing lag as well. I will now turn all features on again one by one to see if I can determine which of them causes the lag. One last edit: All is well now! I figured out this line was the culprit: this.lavaTrapGen.generate(this.world, this.rand, blockpos.add(this.rand.nextInt(16), this.rand.nextInt(108) + 4, this.rand.nextInt(16))); So I added an (8, 8) offset and things are working fine now! Thanks again for the help jabelar.
  16. Hello fellow modders, Currently I am working on a mod that, among other things, adds a Frozen Nether dimension. In this dimension, I want to generate Frozen Nether Fortresses. These structures look just like the normal variants, except, well, frozen. To create these structures, I have copied code from vanilla's MapGenNetherBridge and StructureNetherBridgePieces classes, and just changed some blocks. The structure is used in ChunkGeneratorFrozenHell (which also takes after the vanilla version) and registered in my ModStructures class. Now for the issue. When I move around in the Frozen Nether, I experience extreme amounts of lag, and the structures only spawn one part in one chunk (always the Crossing). I've looked around already, and I know what causes this. The structure is trying to generate in unloaded chunks. This makes Minecraft load a large amount of chunks quickly, resulting in - as the console calls it - cascading worldgen lag. And because things cannot generate in unloaded chunks, only a single piece of the structure is actually generated. I may know the cause of my problems, but what I cannot find is a descriptive solution. People are saying to generate the structure as the chunks are loaded, but I have no idea how I would go about this. Any help would be greatly appreciated. For reference, the classes involved can be found on my GitHub (some of them are too big to post here directly): https://github.com/JoieNL/Winter-Is-Here. These classes are potentially important: StructureFrozenNetherBridgePieces (in /world/gen/structure/). MapGenFrozenNetherBridge (in /world/gen/structure). ModStructures (in /world/gen/structure). ChunkGeneratorFrozenHell (in /world/gen). Thanks in advance!
  17. I thought maybe another mod's code might help me out. I know Twilight Forest has some custom armour models and luckily for me the source code is on GitHub. I will look into things a bit more and report my findings.
  18. It has been over two weeks since my original post and I have not made even the slightest amount of progress. Any help would be greatly appreciated.
  19. Right, that was just a thing I left there for no reason. The casting is to RendererLivingEntity by the way, not ModelBase. Here's the preferred thing: ModelBase defaultModel = ((RendererLivingEntity) Minecraft.getMinecraft().getRenderManager().getEntityRenderObject(entity)).getMainModel(); The weird cast was there because I was getting confused with both RendererLiving and Render being generic classes. Anyway, this is kind of besides the point of the thread, and I still haven't made any progress on the topic.
  20. A few days have passed now and I have made little progress. I have found a way to easily apply most important attributes that the model can have: @Override @SideOnly(Side.CLIENT) public ModelBiped getArmorModel(EntityLivingBase entity, ItemStack stack, int armorSlot) { [...] ModelElementalArmourIce model = ClientProxy.getElementalArmourModel(4 - armorSlot); ModelBase defaultModel = RendererLivingEntity.class.cast(Minecraft.getMinecraft().getRenderManager().getEntityRenderObject(entity)).getMainModel(); model.setModelAttributes(defaultModel); return model; } This way of doing things does not look particularly beautiful and I would not be surprised if there was some better way of retrieving an entity's default model. Of course, my problem still stands. I have experimented some more with the armour, and have been able to pinpoint several issues that all relate to the entity wearing the armour. - On armour stands, the helmet's front always faces south and the arms move (idle animation). - For entities that have their arms sticking forward (e.g. zombies, skeletons), the armour's arms simply hang downwards. - Zombie villagers also have their heads sticking out the top of the helmet. I will persist in trying to find a solution. I hope someone may be able to help me out.
  21. Recently I've gotten into making custom models for my armour sets. I have used this tutorial to guide me. Now, the armour works mostly fine. The only thing that goes wrong is that the armour model does not change according to the entity wearing it. That is, it is always rendered small, the arms always move (even on armour stands) and the armour does not follow the player sneaking, holding an item, guarding with a sword, etc. I do realise that some of these things can be circumvented by changing certain fields in ModelBiped and ModelBase (e.g. isChild, isSneaking), but these fields do not cover every movement. How would I go about making the armour render correctly according to the attributes of the entity wearing it? Thanks in advance for any help! Here are the classes involved for reference: ModelElementalArmourIce.java: ElementalArmourItem.java: ClientProxy.java:
  22. Well, after a lot of trial and error, I've figured things out. I am now able to configure the specifics of a generated mob spawner, as well as the specifics of the entitiy it should spawn. All these values are contained within the MobSpawnerBaseLogic class. I created a class, MobSpawnerExtendedLogic, that extends that class in which I created methods for modifying all these values. The methods I created use Java's reflection system. The methods are static because I have to use them in a static context. The argument to pass in as spawnerLogic should be the logic of the spawner you are trying to modify. For a spawner positioned at BlockPos pos in World world, you would pass ((TileEntityMobSpawner) world.getTileEntity(pos))).getSpawnerBaseLogic(). Here are my MobSpawnerExtendedLogic class and an implementation of the methods within it: MobSpawnerExtendedLogic.class: An implementation of the methods:
  23. Things are getting awkwardly silent around here... Consider this post a bump.
  24. Perhaps I should have been a bit more elaborate. The array of ItemStacks would be the equipment the Entity must have. As for my current code... MobSpawnerExtendedLogic.class: WaterTower.class: world.setBlockState(origin.add(11, 1, 11), Blocks.mob_spawner.getDefaultState()); TileEntityMobSpawner spawner = (TileEntityMobSpawner) world.getTileEntity(origin.add(11, 1, 11)); setNBT(spawner.getSpawnerBaseLogic());
  25. I have figured out how to edit the mob spawner's characteristics through the use of reflection. Now, I have been trying to configure the spawned entity's characteristics by using reflection to edit the NBTTagCompound "nbtData" in the inner class WeightedRandomMinecart in MobSpawnerBaseLogic. After many fruitless attempts, I just don't know what to try anymore. How do I go about setting "nbtData" while using the right arguments in Field::set(Object obj, Object value) and how do I convert (an array of) ItemStacks to NBT that MobSpawnerBaseLogic can read?
×
×
  • Create New...

Important Information

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