
Asleep365
Members-
Posts
21 -
Joined
-
Last visited
Everything posted by Asleep365
-
I'm making modifications to vanilla blocks from world generation, and due to issues related to overwriting vanilla blocks I need to access all blocks of the type after they are finished generating to prevent any glitched blocks. In particular, I'm making modifications to dirt, cobble, and sugarcane. There doesn't seem to be any issue with generation of structures (village, dungeon etc) so I won't need to access those post-generation. I don't think other mod generation of these resources should cause glitches, but I'll deal with it when the situation arises. To my knowledge, cobblestone only generates in structures and are thus not a concern (mossy cobble doesn't count); sugarcane generates during the VEGETAL_DECORATION stage, and dirt generation occurs in the RAW_GENERATION and UNDERGROUND_ORE stages. I'm pretty sure the generation stages go RAW_GENERATION > UNDERGROUND_ORE > VEGETAL_DECORATION, but that still leaves out UNDERGROUND_DECORATION, LOCAL_MODIFICATIONS, SURFACE_STRUCTURES, TOP_LAYER_MODIFICATIONS, and UNDERGROUND_STRUCTURES. For now I only need a stage that occurs after VEGETAL_DECORATION if possible, but knowledge of the where the other stages fit into generation would be very helpful in reducing potential generation weirdness.
-
Overriding Vanilla Block(s) complications
Asleep365 replied to Asleep365's topic in Support & Bug Reports
I'm trying to change the core gameplay to remove dirt and cobble as extremely accessible building materials that don't fall in midair. Unless I change the base properties of dirt and cobble, many of the building materials in my mod would find little value outside of aesthetics. Education is a major portion of my mod, and that includes what constitutes a good building material (dense materials for walls, lighter sturdy materials like wood for floors). I'm all for another solution if there is one, but making all vanilla dirt and/or mod recipes drop modded dirt, and all mod recipes using vanilla dirt that is now unobtainable is very inconvenient for any player. Anyway, I already found a way to overwrite the dirt in the VEGETAL_DECORATION stage, was just asking to know if there was an easier way. I'd like to know if the order of Minecraft vanilla generation stages is documented so I can be sure there aren't any remaining glitched blocks. Do the modded actions in the same stage (ex. VEGETAL_DECORATION) occur after the vanilla actions in the stage? What order do LOCAL_MODIFICATION, TOP_LAYER_MODIFICATION and VEGETAL_DECORATION go? -
I've been having issues over-riding vanilla dirt, but I think it goes beyond what should be expected from over-riding a vanilla block. Over-writing the registry for minecraft:dirt changed it's properties, but it glitches in world generation. Replacing all instances of glitched dirt is a very complex task, as it also seems like anything that would normally generate on dirt (seagrass, etc) would not generate. My modded version doesn't add any properties (open, lit, etc), so I don't think it should be a data issue. The custom dirt generates and functions perfectly fine in default super flat worlds and when pulled from the creative menu, so it's definitely an issue with generation. I would expect re-registering a vanilla block in Forge should only change the properties and should not affect world generation. If replacing vanilla blocks is not an intended feature of Forge, I can raise the topic in suggestions instead.
-
[1.15.2] Override vanilla block and/or properties
Asleep365 replied to Asleep365's topic in Modder Support
Using string.equals() comparison works, as long as it occurs after all dirt is successfully generated. Will need a few modifications to instead generate mud in rivers and oceans, but for the most part doesn't have significant issues. I'll probably need to update Seagrass, and sugarcane to grow on mud also as mud doesn't have a solid topside. Going to leave kelp out since kelp attaches to rocks, and doesn't have roots. Unfortunately I can't find any documentation on worldgen stages. I need a stage to generate the dirt that still has another stage after it to generate dirt ores. Should occur after UNDERGROUND_STRUCTURES preferably to ensure mineshafts generate correctly. Preferably not VEGETAL_DECORATIONS as that seems to prevent the spawning of seagrass and other plants. The generation stages are: VEGETAL_DECORATION, UNDERGROUND_DECORATION, UNDERGROUND_ORES, RAW_GENERATION, LOCAL_MODIFICATIONS, SURFACE_STRUCTURES, TOP_LAYER_MODIFICATIONS, UNDERGROUND_STRUCTURES. Setting it in RAW_GENERATION still results in some bugged blocks (presumably dirt generated after RAW_GENERATION). VEGETAL_DECORATION results in plants etc that would be generated on dirt don't generate. Simplest solution would be if I could make a custom worldgen stage post-generation to replace all dirt, cobble, seagrass, sugarcane, and whatever else I may need (coral etc). After that, another worldgen stage to replace some dirt with dirt ores. If this is possible with a custom world type that would be acceptable as well. EDIT: Plants actually generate correctly. Should potentially be fairly straight forward then, just need to make sure I don't miss any stages of generation -
[1.15.2] Override vanilla block and/or properties
Asleep365 replied to Asleep365's topic in Modder Support
I don't think cave_air would be practical since it would fill in all the caves with dirt. I could try void, but since I'm also planning on replacing cobblestone it wouldn't be a long term solution even if it worked. Part of my reasoning for the falling dirt is 1. an additional environmental hazard, 2. being a fundamentally different material for construction. Replacing the item alone would only solve number 2. Falling cobble is similar, biggest thing I need to worry about is the roofs of plains village temples and jungle temples. If the System.out.println(block) or blockstate thinks it's dirt, there has to be some way to check in code whether it is dirt. EDIT: Thought of an idea, if System.out.println() identifies correctly, what if I just use block.toString() and compare that to Block{minecraft:dirt}? Probably not the best solution, but it might work -
[1.15.2] Override vanilla block and/or properties
Asleep365 replied to Asleep365's topic in Modder Support
The problem with having a separate block is that when grass dies, hoe'd dirt is trampled, and any modded recipes or interactions etc I need it to turn into the custom dirt. Even if I were to change every dirt related block I can't change the recipes in other mods. Note that grass and other dirt variants not being replaced is intended behavior. I just need to find what the glitched blocks are an instance of, or be able to extract some unique property that only exists in minecraft:dirt -
[1.15.2] Override vanilla block and/or properties
Asleep365 replied to Asleep365's topic in Modder Support
Okay, I got my replacement function working "correctly", in the sense that I can replace a block with another on world generation, using something similar to the one I linked. The problem now is that neither replacing Blocks.AIR or Blocks.DIRT replace the missing, glitched blocks. I'll try some functions to identify the "block type" of one of the glitched blocks EDIT: System.out.println() says the block is "Block{minecraft:dirt}", but equality (==) comparisons of the block to Blocks.DIRT, ModBlocks.DIRT.get(), and Blocks.AIR all return false. Have no idea what the block really is -
[1.15.2] Override vanilla block and/or properties
Asleep365 replied to Asleep365's topic in Modder Support
From research it might be possible to replace the dirt after generation when loading new chunks. Something like this maybe: My problem however is a bit more complicated. In addition to changing the vanilla dirt properties, I also have "dirt ores" that replace dirt. If the vanilla dirt generation occurs in the RAW_GENERATION stage, and the "dirt ores" generate in the UNDERGROUND_ORE phase, there isn't much extra room to replace vanilla dirt with the custom dirt. -
[1.15.2] Override vanilla block and/or properties
Asleep365 replied to Asleep365's topic in Modder Support
It seems like replacing vanilla blocks causes the world generation to bug out. The world generation occurs like normal except all the dirt is invisible, solid, but cannot be punched. Lighting updates proceed as if they weren't there. Placing a block where there should be dirt has a no-texture block, F3 says it's "minecraft:air". Strangely, it works fine in super-flat worlds, so I might have to overwrite the dirt generation to also to use the custom dirt. EDIT: Leaving the area and coming back causes all glitched blocks to be replaced with normal, "real" air, no lighting glitches like above EDIT2: NVM that was just my night vision potion, lighting still glitched, but not solid anymore -
[1.15.2] Override vanilla block and/or properties
Asleep365 replied to Asleep365's topic in Modder Support
@Mod(Solidarity.MOD_ID) public class Solidarity { public static final String MOD_ID = "solidarity"; private static final Logger LOGGER = LogManager.getLogger(); public static IEventBus MOD_EVENT_BUS; public Solidarity() { MinecraftForge.EVENT_BUS.register(this); MOD_EVENT_BUS = FMLJavaModLoadingContext.get().getModEventBus(); ModBlocks.BLOCKS.register(MOD_EVENT_BUS); ModItems.ITEMS.register(MOD_EVENT_BUS); ModTileEntities.TILE_ENTITY_TYPES.register(MOD_EVENT_BUS); ModContainers.CONTAINERS.register(MOD_EVENT_BUS); ModRecipeSerializers.RECIPE_SERIALIZERS.register(MOD_EVENT_BUS); DistExecutor.runWhenOn(Dist.CLIENT, () -> Solidarity::registerClientOnlyEvents); } Removed comments to conserve space. Have a feeling you're probably right, I don't have a ModBlocks.VANILLA_BLOCKS etc. I'm guessing it'll need a different MOD_EVENT_BUS? -
[1.15.2] Override vanilla block and/or properties
Asleep365 replied to Asleep365's topic in Modder Support
I haven't been able to get this to work. A sample of my code is below: public static final DeferredRegister<Block> VANILLA_BLOCKS = new DeferredRegister(ForgeRegistries.BLOCKS, "minecraft"); //Overwrite vanilla items public static final RegistryObject<Block> DIRT = registerVanillaBuildingBlockWithDefaultItem( "dirt", () -> new NewDirtBlock()); public static final RegistryObject<Block> DIRTTEST = registerBlockWithDefaultItem( "dirttest", () -> new NewDirtBlock()); public static <T extends Block> RegistryObject<T> registerBlockWithDefaultItem(String name, Supplier<? extends T>blockSupplier) { RegistryObject<T> block = BLOCKS.register(name, blockSupplier); ModItems.ITEMS.register(name, () -> new BlockItem(block.get(), new Item.Properties().group(ModItems.solidarityGroup))); return block; } public static <T extends Block> RegistryObject<T> registerVanillaBuildingBlockWithDefaultItem(String name, Supplier<? extends T>blockSupplier) { RegistryObject<T> block = VANILLA_BLOCKS.register(name, blockSupplier); ModItems.VANILLA_ITEMS.register(name, () -> new BlockItem(block.get(), new Item.Properties().group(ItemGroup.BUILDING_BLOCKS))); return block; } NewDirtBlock(): public class NewDirtBlock extends FallingBlock { private final BlockState solidifiedState; public NewDirtBlock() { super(Block.Properties.create(Material.EARTH, MaterialColor.DIRT).hardnessAndResistance(0.5F).sound(SoundType.GROUND)); this.solidifiedState = ModBlocks.MUD.get().getDefaultState(); } ... } ModItems.VANILLA_ITEMS: public static final DeferredRegister<Item> VANILLA_ITEMS = new DeferredRegister(ForgeRegistries.ITEMS, "minecraft"); When registered under "dirttest", the properties all function as intended. However, when registered under "minecraft:dirt" it only seems to have vanilla dirt properties (doesn't fall, convert to mud etc). What is wrong with the above code? -
How would I override vanilla block properties? For example, decrease obsidian blast resistance, make cobble a falling block, make wool inflammable, etc. Blocks.OBSIDIAN etc are final values and cannot be directly modified. Also is it possible to modify wool and other colored block properties without manually entering each wool color in an array and parsing through etc?
-
I feel like this should be fairly straightforward, but I can't figure out how to get the BlockPos for a custom furnace. As containers are not moveable by pistons etc. it could potentially be set on initialization, but then I would need to get the BlockPos from the respective Block class, and I'm not sure how to do that either.
-
[1.15.2] Generating/replacing resources in biomes
Asleep365 replied to Asleep365's topic in Modder Support
I think I figured out the problem, for anyone with a similar issue, following the advice from The generation stage should be set to something after raw_generation, for example underground ores. -
[1.15.2] Generating/replacing resources in biomes
Asleep365 replied to Asleep365's topic in Modder Support
I figured out how to avoid the ore generation timing; by setting GenerationStage.Decoration.UNDERGROUND_ORES to RAW_GENERATION, the ores will only show up on stone. Still can't figure out how to generate over the limestone yet -
In my mod I'm generating a variety of resources. Most of these aren't too fancy, and can be handled using vanilla generation methods. Currently using code similar to the below: //Generate significant clay near the world surface at the shores of plains biomes Biomes.PLAINS.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Feature.DISK.withConfiguration( new SphereReplaceConfig(Blocks.CLAY.getDefaultState(), 7, 5, Lists.newArrayList(new BlockState[]{DIRT, GRASS_BLOCK}))) .withPlacement(Placement.COUNT_TOP_SOLID.configure(new FrequencyConfig(100))) ); //Non-biome specific for (Biome biome : ForgeRegistries.BIOMES) { //Natural Stone is any of stone, andesite, granite, diorite //OreFeatureConfig Target, state, size //CountRangeConfig is count, bottom offset, top offset, maximum (altitude?) //DepthAverageConfig is count, baseline, spread biome.addFeature(GenerationStage.Decoration.UNDERGROUND_ORES, Feature.ORE.withConfiguration( new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NATURAL_STONE, ModBlocks.LIMESTONE.get().getDefaultState(), 120)) .withPlacement(Placement.COUNT_DEPTH_AVERAGE.configure(new DepthAverageConfig(2, 55, 16)))); //COUNT_RANGE.configure(new CountRangeConfig(10, 0, 0, 256)))); } The code above has the following effects: In plains biomes only, many parts of the coast next to rivers generate clumps of clay in large quantities. Intended effect. In all biomes, most of the stone (but not all) around sea level is replaced with limestone using placement generation similar to that of Lapis. However, the vanilla ore has already generated by this point, and the vanilla coal on stone backdrop doesn't blend well on limestone. My goal is to have portions of vanilla stone replaced with limestone, portions of that replaced with carbonate minerals and dolomite (dolomitic limestone), and portions of the dolomite replaced with zinc/lead sulfides. Vanilla ores will remain embedded in vanilla stone only in lower and higher depths, but not in limestone. How would I go about setting a ore generation order (stone->carving?->limestone->vanilla ores)? Would I need to create my own Feature, FeatureConfig, and/or Placement classes to achieve desired functionality? In addition, how would I modify existing generated structures, either through removing/replacing? For example, for fossils to generate with pyrite blocks instead of coal blocks.
-
Register an item that uses another as a container? (1.15.2)
Asleep365 replied to Asleep365's topic in Modder Support
Worked. Not sure why I didn't think of it myself, guess I need more practice with Java -
I recently changed my registration structure to use deferred register for scalability reasons and have encountered an error. One of my items called GAS_TANK, and is being registered like so: //Gas Tanks public static final RegistryObject<Item> GAS_TANK = ITEMS.register("gas_tank", () -> new Item(PropertiesGeneric)); private static final Item.Properties PropertiesGasTank = new Item.Properties().group(solidarityGroup)//solidarityGroup) .maxStackSize(1).containerItem(GAS_TANK.get()); public static final RegistryObject<Item> GAS_TANK_CO2 = ITEMS.register("gas_tank_co2", () -> new Item(PropertiesGasTank)); public static final RegistryObject<Item> GAS_TANK_SO2 = ITEMS.register("gas_tank_so2", () -> new Item(PropertiesGasTank)); I'm trying to make some more items that use GAS_TANK as a containerItem, similar water/lava buckets, so they won't be consumed when used as an ingredient or fuel. However, since GAS_TANK won't be registered yet, it gives me an error when trying to run the line that defines PropertiesGasTank. How should I arrange/modify the code so that I can set GAS_TANK as the containerItem for the gas tank variants?
-
Creation/registering of recipes for custom machines (1.15.2)
Asleep365 replied to Asleep365's topic in Modder Support
In the examples for IRecipes you gave and in vanilla minecraft they override the functions ItemStack GetCraftingResult() and GetRecipeOutput(), which each have exactly one output by design, and the concept is that for each product item they have recipes to produce that one product, thus why each recipe is named after the output. Instead I'm trying to have a generic a+b+c->d+e+f, but since there's nothing in IRecipe forcing me to use those functions, I might be able to just have similar ones with a class/struct return value. The only issue I foresee is that recipe tracking in vanilla and/or other mods might have weird responses if I don't add manual compatibility, but that's a lesser concern at the moment. -
Creation/registering of recipes for custom machines (1.15.2)
Asleep365 replied to Asleep365's topic in Modder Support
Like the vanilla IRecipeType? Or IRecipe? Most, if not all, of the vanilla recipes only have exactly one output, so I'm not sure I can use those. -
The mod I'm currently working on creating has custom furnaces/machines that will take in multiple inputs (fuel, multiple resources, containers) and produce multiple outputs (solid, liquid, gas, and ash from spent fuel). Currently my machine processes vanilla furnace recipes, but my goal is for the machine to process recipes in the format {unordered set with between 1-3 items}+[gas input (optional)] + [bool endothermic?] + [catalyst (optional)] -> number*[solid (optional)] + number*[liquid (optional)] + number*[gas(optional)]. The specifics of implementation aren't a major issue at the current time, I'm pretty confident with my general programming knowledge. I know how to register vanilla crafting table and furnace recipes, but I'd like to know if there is a means to process any generic multiple input->multiple output formulas from JSON without hardcoding all the recipes. Vanilla code like the firework crafting recipe processes a variable numbers of ingredients in a crafting recipe, but I would still effectively be hard-coding each recipe type. As I'm expecting ~300 unique recipes in total I'd prefer to isolate the recipes in an easily accessed format, otherwise I'll probably just make it like in vanilla with a function that takes in the relevant inputs and after running through hard-coded recipes produces a struct containing the output info, then I can process what the machine does from there.