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


  • Posts

  • Joined

  • Last visited

Recent Profile Visitors

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

Cratthorax's Achievements

Tree Puncher

Tree Puncher (2/8)



  1. That's interesting you say that. So basically the RegistryObject can be whatever it wants, but the new BlockCrudeOil is the one addressing the object.class? This might be very well the reason why I can't get my custom oil tags working. I'd still have to "hack" the minecraft.water tag in order to give proper physics etc. to my custom fluid. I've found some leftover traces from you, over here. But it wasn't a priority on my list, so after some struggle and fail I just moved on to more important topics. I shall test this tag thingy again with my newly gained kiddy skills...:)
  2. WorldGen you ask? I'd have examples for Decorations, BiomeHandlers, and Features as well. You can refer to post 3 in this thread for some input.
  3. Good evening, a bit more progress and inherited info. I finally managed to understand why I couldn't perfectly connect my registry's to the object.class. You guys were right all the way. It was all about basic understanding of Java, and to correctly use fields, constants, properties etc. It's just one of 6 code languages I'm script kiddying, so bare with me. It also made sense to understand, that my Fluid.class(not FluidBlock.class) was, from its logic, actually a "register".class just as my main register .class, and I could basically just have used all my fluid.class code inside the general registry as well. So it seems important you also give perfect label/naming/package structure to your mod, though I know from scripting with Papyrus, it isn't the worst thing to multithread. However, the FluidRegistry.class has the FluidBlock.class registered like that now:
  4. Don't be silly. A script kiddie is capable of basic copy pasting. I can't even do that. However, one more thing to add. How do you connect the registered FlowingFluidBlock, to your actual FluidBlock.class? I wasn't aware that you can actually customize the FlowingFluidBlock RegistryObject(or any other RegistryObject in that regard). Do it like that, and take info from the vanilla FluidBlocks how to build your FluidBlock.class accordingly: Change that... public static final RegistryObject<FlowingFluidBlock> OIL_BLOCK = MatLibRegister.BLOCKS.register("crudeoil", () -> new FlowingFluidBlock(() -> MatLibFluidOil.OIL_FLUID.get(), AbstractBlock.Properties.create(MATOIL) .doesNotBlockMovement().hardnessAndResistance(100f).noDrops())); ...to that... public static final RegistryObject<MyCustomFluidBlock> OIL_BLOCK = MatLibRegister.BLOCKS.register("crudeoil", () -> new MyCustomFluidBlock(() -> MatLibFluidOil.OIL_FLUID.get(), AbstractBlock.Properties.create(MATOIL) .doesNotBlockMovement().hardnessAndResistance(100f).noDrops())); ...and name your FluidBlock MyCustomFluidBlock.class. As far as I understand you do not want to extend to FlowableFluidBlock, but to FlowableFluid. I've yet to understand why, because in the past a fluid block, was still a block. It seems like it is now an "in between" thingy, or no longer a block at all. I hope someone of the wizards can spread some wisdom on that? And if it's just to ease the tinkering...👍 Edit: If someone wants more learning material, I'd recommend the TechReborn FlowableFluid.class, and their actual Fluid.class(Fabric only, so lots of adaptions needed, but good for getting an idea of structure), or PneumaticCraft(Forge). Notice they seem to be on 1.16.5 or even 1.17.1, but the code is compiling fine and dandy with minor adaptions(for 1.17.1 only?). You'd quickly find traces on how to "adapt" by highlighting methods/fields/etc., and open the declaration. Trouble starts really if references aren't public, because then you have to @Override in a custom.class. Which is something I've yet to learn as well. In the past, for 1.7(yes, that's 2013), it looked something like that:
  5. Ok so, this is going to be a long one. This will show you(probably in a ugly, hacky way), how to spawn your custom fluid in patches of custom lakes in worldGen for 1.16.4. It may as well work for 1.16-1.16.5. But don't nail me on this one. Notice that all terminology and labels containing the words oil, or crudeoil, can very well be anything you want. Be sure to first do the tutorial I posted upside, or find your individual way of creating a custom fluid. This will also have the bucketItem covered you'd need to pick up your customFluid. What you need for the DataPack(click the links for code on pastebin, the .meta files basically just contain one column handling animation frames, search online for how to do this, it's really easy): assets/yourmod/blockstate/crudeoil.json, assets/yourmod/lang/en_us.json, assets/yourmod/models/block/crudeoil.json, assets/yourmod/textures/fluid/oil_flow.png; oil_flow.png.meta; oil_overlay.png; oil_still.png; oil_still.png.meta, assets/yourmod/worldgen/configured_feature/lake_oil.json Now the actual .java code: In your main file register the DECORATORS and FEATURES with a modBus, the worldGen clientside with an event.enqueueWork(), and the onBiomeLoading event with a forgeBus. It should look something like this: @Mod(MatLibMain.MODID) public class MatLibMain { public static final String MODID = "matlib"; public static final String ModName = "Material Library"; public static final String VersionMajor = "0"; public static final String VersionMinor = "4"; public static final String VersionPatch = "0"; public static final String BuildVersion = VersionMajor + "." + VersionMinor + "." + VersionPatch; public static final String MinecraftVersion = "1.16.4"; public MatLibMain() { // Register the setup method for modloading IEventBus eventBus = FMLJavaModLoadingContext.get().getModEventBus(); IEventBus forgeBus = MinecraftForge.EVENT_BUS; MatLibRegister.register(eventBus); MatLibFluids.register(eventBus); MatLibRegister.DECORATORS.register(eventBus); MatLibRegister.FEATURES.register(eventBus); eventBus.addListener(this::setup); // Register the enqueueIMC method for modloading eventBus.addListener(this::enqueueIMC); // Register the processIMC method for modloading eventBus.addListener(this::processIMC); // Register the doClientStuff method for modloading eventBus.addListener(this::doClientStuff); // Register ourselves for server and other game events we are interested in MinecraftForge.EVENT_BUS.register(this); forgeBus.addListener(EventPriority.HIGH, MatLibWorldGen::onBiomeLoading); } private void doClientStuff(final FMLClientSetupEvent event) { event.enqueueWork(() -> { MatLibWorldGen.registerConfiguredFeatures(); RenderTypeLookup.setRenderLayer(MatLibFluids.OIL_FLUID.get(), RenderType.getTranslucent()); RenderTypeLookup.setRenderLayer(MatLibFluids.OIL_BLOCK.get(), RenderType.getTranslucent()); RenderTypeLookup.setRenderLayer(MatLibFluids.OIL_FLOWING.get(), RenderType.getTranslucent()); }); } ==================================================here is a code break========================================================= The register can happen in your main file as well, but I do it inside a dedicated MatLibRegister.class. //decorators public static final DeferredRegister<Placement<?>> DECORATORS = DeferredRegister.create(ForgeRegistries.DECORATORS, MatLibMain.MODID); public static final RegistryObject<MatLibLakePlacement> OIL_DECO = registerDeco("oil_deco", () -> new MatLibLakePlacement(ChanceConfig.CODEC)); private static <T extends Placement<?>> RegistryObject<T> registerDeco(final String name, final Supplier<T> sup) { return DECORATORS.register(name, sup); } //features public static final DeferredRegister<Feature<?>> FEATURES = DeferredRegister.create(ForgeRegistries.FEATURES, MatLibMain.MODID); public static final RegistryObject<Feature<BlockStateFeatureConfig>> OIL_FEAT = registerFeat("oil_feat", MatLibLakeFeature::new); private static <T extends Feature<?>> RegistryObject<T> registerFeat(String name, final Supplier<T> sup) { return FEATURES.register(name, sup); } The MatLibLakeFeature.class: public class MatLibLakeFeature extends LakesFeature { public MatLibLakeFeature() { super(BlockStateFeatureConfig.field_236455_a_); } @Override public boolean generate(ISeedReader level, ChunkGenerator generator, Random rand, BlockPos pos, BlockStateFeatureConfig config) { return super.generate(level, generator, rand, pos, config); } } The MatLibLakePlacement.class: public class MatLibLakePlacement extends Placement<ChanceConfig> { public static int genChance = 100; public MatLibLakePlacement(Codec<ChanceConfig> codec) { super(codec); } @Override public Stream<BlockPos> getPositions(WorldDecoratingHelper helper, Random rand, ChanceConfig chanceConfig, BlockPos pos) { if (rand.nextInt(100) < chanceConfig.chance) { int x = rand.nextInt(16) + pos.getX(); int z = rand.nextInt(16) + pos.getZ(); int y = rand.nextInt(rand.nextInt(helper.func_242891_a() - + 8); // sea level check to reduce random placement chance if (y < helper.func_242895_b() || rand.nextInt(100) < genChance) { return Stream.of(new BlockPos(x, y, z)); } } return Stream.empty(); } } And last but not least, the MatLibWorldGen.class: public class MatLibWorldGen { public static ConfiguredFeature<?,?> OIL_LAKES; public static void registerConfiguredFeatures() { Registry<ConfiguredFeature<?, ?>> registry = WorldGenRegistries.CONFIGURED_FEATURE; OIL_LAKES = MatLibRegister.OIL_FEAT.get() .withConfiguration(new BlockStateFeatureConfig(MatLibFluids.OIL_BLOCK.get().getDefaultState())) .withPlacement(MatLibRegister.OIL_DECO.get().configure(new ChanceConfig(100))); Registry.register(registry, RL("oil_lakes"), OIL_LAKES); } public static ResourceLocation RL(String path) { return new ResourceLocation(MatLibMain.MODID, path); } @SubscribeEvent(priority = EventPriority.HIGHEST) public static void onBiomeLoading(final BiomeLoadingEvent event) { event.getGeneration().withFeature(GenerationStage.Decoration.LAKES, OIL_LAKES); } } If you have questions, ask right away. Also, make sure to keep the names of the .class files, unless you know how to change and how to fix the refactorings you did. Oh yeah, and the fluid.class according to the video. Make sure to register in your main/register-file, and don't forget the DataPack for your bucketitem.: public class MatLibFluids { public static final ResourceLocation OIL_STILL_RL = new ResourceLocation("fluid/oil_still"); public static final ResourceLocation OIL_FLOWING_RL = new ResourceLocation("fluid/oil_flow"); public static final ResourceLocation OIL_OVERLAY_RL = new ResourceLocation("fluid/oil_overlay"); public static final DeferredRegister<Fluid> FLUIDS = DeferredRegister.create(ForgeRegistries.FLUIDS, MatLibMain.MODID); public static final RegistryObject<FlowingFluid> OIL_FLUID = FLUIDS.register("oil_fluid", () -> new ForgeFlowingFluid.Source(MatLibFluids.OIL_PROPERTIES)); public static final RegistryObject<FlowingFluid> OIL_FLOWING = FLUIDS.register("oil_flowing", () -> new ForgeFlowingFluid.Flowing(MatLibFluids.OIL_PROPERTIES)); public static final ForgeFlowingFluid.Properties OIL_PROPERTIES = new ForgeFlowingFluid.Properties( () -> OIL_FLUID.get(), () -> OIL_FLOWING.get(), FluidAttributes.builder(OIL_STILL_RL, OIL_FLOWING_RL) .density(800).temperature(300).viscosity(10000).sound(SoundEvents.ITEM_HONEY_BOTTLE_DRINK).overlay(OIL_OVERLAY_RL) .color(0xff000000)).slopeFindDistance(2).levelDecreasePerBlock(2).tickRate(45) .block(() -> MatLibFluids.OIL_BLOCK.get()).bucket(() -> MatLibRegister.BUCKETOIL.get()); public static class Source extends ForgeFlowingFluid.Source { public Source() { super(OIL_PROPERTIES); } public int getTickDelay(IWorldReader world) { return 20; } } public static final RegistryObject<FlowingFluidBlock> OIL_BLOCK = MatLibRegister.BLOCKS.register("crudeoil", () -> new FlowingFluidBlock(() -> MatLibFluids.OIL_FLUID.get(), AbstractBlock.Properties.create(Material.WATER) .doesNotBlockMovement().hardnessAndResistance(100f).noDrops())); public static void register(IEventBus eventBus) { FLUIDS.register(eventBus); } }
  6. I disagree. A coder is someone doing what you just said on a professional level. I'm not a professional. But I get things working, even if it doesn't look nice, and takes ages. By that I'd label me an endurant tinkerer...:D You may as well just close this thread, as I figured how to solve my fluid/lake/worldGen problem as well. For anyone interested, it basically also covers the issue I had posted inside here: How to make a fluid, and spawn in it worldGen(without building an object.class)
  7. @Sieben, always a charming...:D I already made clear that I'm not a coder, but a mod building hacker. The reason for this has been stated as well. Limited time and other obligations. I do hear you though, once I get to be a pensioner, and have the time to spend all my focus on coding Java....in like 20 years from now. However. The correct answer would have been: "You can either define object.class logic/properties in the place you are doing the register, OR you can do it in the object.class, and then refer to this object.class in your register method. You can't do both, because they are two different objects.". Sure it does. The underlying problem was, and still is, I'm used to 2013/2015 code, and 2021 is far away from that. I have to accept that starting from all over would have been the better solution when I started. But now that I've done so much "conversion work" already, I might have done things more complicated than they need to be.
  8. I'm sorry, but you guys seem to understand my problem just as much as I understand the technical details you're directing me at. What you said @Sieben is not my problem. My problem is, I, somehow managed to create a custom object(regardless of being block, item, or fluid, or whatever) without using an actual item./block./fluid.class. And I fail at connecting a(n) item/block/fluid.class to the registered version of my already existing object. Hence why I'm asking which name I need to give the .class object in order to make the registered object use the .class's logic? So again, if I have my registered object: public static final RegistryObject<Item> GRAVELANTIMONY = ITEMS.register("gravelantimony", () -> new Item( new Item.Properties().group(MATLIB_GROUP))); And I have my item.class which is named ItemGravelAntimony.java, and use the naming method posted downside, inside the item.class, why does the registered item not make use of the actual item.class? public ItemGravelAntimony(String name){ this(name, MatLibMain.MODID, "item/" + "gravelantimony"); }
  9. Found the tutorial. Please don't judge me. The guy just presented a very convenient and easy way to implement fluids.
  10. So I just followed this tutorial, which I can't even find any longer, about creating fluids. The very cool thing about the whole tutorial was that I could easily do this inside a single file. Don't ask me why, but I hate spreading it all over the place. The .class looks like this:
  11. Yeah. Obviously I had the details mixed up. Forgive me, as I am still in a state of confusion about the whole DataPack way of doing things. But I get to understand a bit more every week. So, if I have registered my item like this: public static final RegistryObject<Item> GRAVELANTIMONY = ITEMS.register("gravelantimony", () -> new Item( new Item.Properties().group(MATLIB_GROUP))); Which would be the correct naming for the corresponding item.class? The one with the capital letters, or the non capital letters? The DataPacks are referring to the one with non capital inside the strings, but the actual .json files have the corresponding object type as starting name convention, like this f.e: blockantimony itemgravelantimony fluidcrudeoil etc. etc. etc. Oh wait. The actual item.class is supposed to have the same naming convention as the DataPack name declaration, right? Edit: shit's going to get even more confused now, since I just last week started to implement custom fluids. But I'm gonna make a new thread for this.
  12. Good day, I'm trying to get a second mod running from inside the run/mods folder, when ever I would test my current project. For one I'm trying to make my current project based on one of my library's, second, since I would spawn an awful lot of new blocks during world creation, I would use a X-Ray mod in the past, in order to quickly verify my ore spawn is actually working. Unfortunately I can't get any of the already compiled mods running from inside the run/mods folder. I remember this was perfectly possible in the past.
  13. Well, me neither English. So language barriers are indeed a problem sometimes. The above code I posted is sitting inside my registry.class, where I register all blocks/items. I combine this with DataPacks to create the items/blocks via .json. Now @Sieben said you can't do all you want inside the DataPacks, that you could do inside a "regular" item.class. But since the registry method already does what I had done inside the item.class in the past, I'm asking if all methods that I would use in the item.class are useable in the registry method properties as well?
  14. Quite easy. I don't know how to embed item.class code into registry methods...;) So I can entirely mimic item.class code inside a registry method as well?
  15. Ok. I was about to say "wtf!" since you two guys were just recommending to me 2 weeks ago, or so, to do items/blocks via DataPacks. So if I use the same ID that I'm using for said item/block in my registerMain.class, will it refer to the corresponding item/block.class? Because I'm already using that kind of code structure in my registry for items/blocks:
  • Create New...

Important Information

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