Jump to content

JimiIT92

Members
  • Posts

    866
  • Joined

  • Last visited

  • Days Won

    3

JimiIT92 last won the day on August 27 2023

JimiIT92 had the most liked content!

Converted

  • Gender
    Male
  • URL
    https://www.youtube.com/Minehendrix
  • Location
    Italy
  • Personal Text
    Creator of MineWorld mod!

Recent Profile Visitors

63838 profile views

JimiIT92's Achievements

Dragon Slayer

Dragon Slayer (6/8)

27

Reputation

  1. It depends on the data you want to save, but generally speaking you should use some custom Player Capabilities, attach to the Player and use them to store/retrieve any kind of data you want. You can find how to make them work for 1.20.x in the documentation here: https://docs.minecraftforge.net/en/latest/datastorage/capabilities/
  2. Hi, thank you for your response. Unfortunately it seems like the MissingMappingsEvent is not fired in this scenario. What I did is creating a world with the old biome ID, change the biome ID and then load the world ath the biome location. When the world is loaded I get the errors but the breakpoint inside the event listener is never hit This is how I registered the event listener @Mod.EventBusSubscriber(modid = MineWorld.MOD_ID) public final class MissingMappingEvents { /** * Handle the missing mappings and replace them with a valid one * * @param event {@link MissingMappingsEvent The Missing Mappings Event} */ @SubscribeEvent public static void onMissingMapping(final MissingMappingsEvent event) { if(event.getKey().location().equals(new ResourceLocation("mineworld", "volcanic_peak"))) { //Do Stuff } } } If I set the breakpoint directly on the if statement it never gets hit. I've also tried to add a Sysout before the if statement just to see if something gets logged, but it doesn't, so it looks like the event is never called (at least for biomes). I've tried removing an Item and in that case the breakpoint got hit, so I'm assuming is just the biomes? EDIT: I don't know if it matters but I'm using Terrablender for adding Biomes to the world. You can also see how I'm registering biomes here: https://github.com/JimiIT92/MineWorld/blob/master/src/main/java/org/mineworld/core/MWBiomes.java
  3. Hi everyone I've renamed a Biome Id in my mod, and as such, when I load a pre-existing world, I get this error when teleporting to said biome [Server thread/ERROR] [minecraft/ChunkSerializer]: Recoverable errors when loading section [-9, 0, 159]: (Unknown registry key in ResourceKey[minecraft:root / minecraft:worldgen/biome]: mineworld:volcanic_peak -> using default) -> volcanic peaks identified as plains where volcanic_peak is the old Id and volcanic_peaks is the new one. As such, the pre-generated biome is now identified as plains, causing some unintended behaviors in that biome (like rain and mobs spawning, wich my custom biome overrides). Is there a way to automatically convert the biome Id for old worlds? For example when loading the world or the chunk?
  4. I don't think that's possible easily without accessing the vanilla classes (using an AT and some Mixins). If 1.18 is not a requirement (quick note: 1.18 is no longer supported), you can upgrade to 1.20.x and listen for the BuildCreativeModeTabContentsEvent. In this event you can check when a Creative Tab is being "constructed" (either a Vanilla Tab or a Modded Tab) and decide if you want to do something with it (tipically add an Item to that tab). In your case you could add your Item before the vanilla Apple using the putBefore / putAfter methods. For instance, here I'm adding an Apple before the Bone Meal in the Ingredients Tab @SubscribeEvent public static void onTabBuildContents(final BuildCreativeModeTabContentsEvent event) { final ResourceKey<CreativeModeTab> tab = event.getTabKey(); if(tab.equals(CreativeModeTabs.INGREDIENTS)) { event.getEntries().putBefore(Items.BONE_MEAL.getDefaultInstance(), Items.APPLE.getDefaultInstance(), CreativeModeTab.TabVisibility.PARENT_AND_SEARCH_TABS); } } And in game, if we open the Ingredients tab, we get this result
  5. I'm assuming you are using the Terrablender API for this (if not please tell me how you added a new biome to the Overworld without that, since it looks like that's the only way 🤣). Anyway you coul always look at how vanilla does declare these Surface Rules, specifically the one for the mountain biomes (I think they are actually defined in the JSON file, but from the code you can get an idea of how these conditions works). One condition I can think would be interesting is the SurfaceRules.VerticalGradientConditionSource condition. Judging from the name you can guess that this is the condition used to create some gradients. For instance, if we look at the Overworld noise settings file (worldgen/noise_settings/overworld.json), this is used to generate the Bedrock layer at the bottom of the World and make it transitioning from Bedrock to Deepslate to not have it flat { "type": "minecraft:condition", "if_true": { "type": "minecraft:vertical_gradient", "false_at_and_above": { "above_bottom": 5 }, "random_name": "minecraft:bedrock_floor", "true_at_and_below": { "above_bottom": 0 } }, "then_run": { "type": "minecraft:block", "result_state": { "Name": "minecraft:bedrock" } } } And a similar condition is also applied to generate the Deepslate transition from Stone starting from Y level 8 to Y level 0 (notice the "false_at_and_above" and "true_at_and_below" properties) { "type": "minecraft:condition", "if_true": { "type": "minecraft:vertical_gradient", "false_at_and_above": { "absolute": 8 }, "random_name": "minecraft:deepslate", "true_at_and_below": { "absolute": 0 } }, "then_run": { "type": "minecraft:block", "result_state": { "Name": "minecraft:deepslate", "Properties": { "axis": "y" } } } } So starting from this you can get an idea of how to create smooth transitions between your "biome layers". Now, to generate blocks only at the top 10 blocks of the biome right now I can't think about any vanilla biome that does a similar thing, but maybe looking at how the Badlands or the Snowy Slope biome are constructed may be a good ay to follow
  6. EDIT: NVM, the enchantment ID was wrong and that was causing the issue. Not sure why it doesn't let me delete this post Hi, I'm trying to make a "smelting" enchantment Global Loot Modifier, but for some reason the game could not decode its related JSON file, altough is applying the Loot Modifier to every single loot When I join a world I get this error in the console [01:08:01] [Render thread/WARN] [ne.mi.co.lo.LootModifierManager/]: Could not decode GlobalLootModifier with json id mineworld:enchantments/fiery_touch - error: Not a json array: {"condition":"minecraft:match_tool","predicate":{"enchantments":[{"enchantment":"mineworld:smelting","levels":{"min":1}}]}} The GLM Json file is the following { "type": "mineworld:fiery_touch", "conditions": [ { "condition": "minecraft:match_tool", "predicate": { "enchantments": [ { "enchantment": "mineworld:smelting", "levels": { "min": 1 } } ] } } ] } And this is the LootModifier class package org.mineworld.loot; import com.google.common.base.Suppliers; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.minecraft.core.RegistryAccess; import net.minecraft.world.Container; import net.minecraft.world.SimpleContainer; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Recipe; import net.minecraft.world.item.crafting.RecipeManager; import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.level.Level; import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; import net.minecraftforge.common.loot.IGlobalLootModifier; import net.minecraftforge.common.loot.LootModifier; import net.minecraftforge.items.ItemHandlerHelper; import org.jetbrains.annotations.NotNull; import org.mineworld.MineWorld; import java.util.List; import java.util.Optional; import java.util.function.Supplier; import java.util.stream.IntStream; /** * {@link MineWorld MineWorld} loot modifier for smelting a drop from a block */ public final class FieryTouchModifier extends LootModifier { /** * {@link Supplier<Codec> The loot codec supplier} */ public static final Supplier<Codec<FieryTouchModifier>> CODEC = Suppliers.memoize(() -> RecordCodecBuilder.create(inst -> codecStart(inst).apply(inst, FieryTouchModifier::new))); /** * Constructor. Set the {@link LootItemCondition loot id conditions} * * @param lootConditions {@index ILootCondition The conditions that need to be matched before the loot is modified} */ public FieryTouchModifier(final LootItemCondition[] lootConditions) { super(lootConditions); } /** * Add the {@link MWLootItem items} to the loot * * @param loot {@link ObjectArrayList<ItemStack> The current loot} * @param context {@link LootContext The loot context} * @return {@link ObjectArrayList<ItemStack> The modified loot} */ @Override protected @NotNull ObjectArrayList<ItemStack> doApply(final ObjectArrayList<ItemStack> loot, final LootContext context) { if(context.hasParam(LootContextParams.BLOCK_STATE)) { final Level level = context.getLevel(); final RecipeManager recipeManager = level.getRecipeManager(); final RegistryAccess registryAccess = level.registryAccess(); IntStream.range(0, loot.size()).forEach(index -> { final ItemStack drop = loot.get(index); final ItemStack smeltedDrop = tryGetSmeltedDrop(recipeManager, RecipeType.SMELTING, level, registryAccess, drop) .orElse(tryGetSmeltedDrop(recipeManager, RecipeType.SMITHING, level, registryAccess, drop) .orElse(tryGetSmeltedDrop(recipeManager, RecipeType.BLASTING, level, registryAccess, drop) .orElse(tryGetSmeltedDrop(recipeManager, RecipeType.SMOKING, level, registryAccess, drop) .orElse(tryGetSmeltedDrop(recipeManager, RecipeType.CAMPFIRE_COOKING, level, registryAccess, drop) .orElse(ItemStack.EMPTY))))); if(!smeltedDrop.isEmpty()) { loot.set(index, smeltedDrop); } }); } return loot; } /** * Get the {@link Codec loot modifier codec} * * @return {@link #CODEC The loot modifier codec} */ @Override public Codec<? extends IGlobalLootModifier> codec() { return CODEC.get(); } /** * Try to set the smelted drop to the {@link List<ItemStack> block drop list} * * @param recipeManager {@link RecipeManager The recipe manager} * @param recipeType {@link RecipeType The recipe type} * @param level {@link Level The level reference} * @param registryAccess {@link RegistryAccess The registry access} * @param drop {@link ItemStack The dropped item} * @return {@link ItemStack The smelted ItemStack} */ private static <C extends Container, T extends Recipe<C>> Optional<ItemStack> tryGetSmeltedDrop(final RecipeManager recipeManager, final RecipeType<T> recipeType, final Level level, final RegistryAccess registryAccess, final ItemStack drop) { return recipeManager.getRecipeFor(recipeType, (C) new SimpleContainer(drop), level) .map(recipe -> recipe.value().getResultItem(registryAccess)) .filter(itemStack -> !itemStack.isEmpty()) .map(itemStack -> ItemHandlerHelper.copyStackWithSize(itemStack, drop.getCount() * itemStack.getCount())); } } I have another GLM that has some entries as well and doesn't have any issues
  7. Why are you doing this instead of just playing the sound using the level or the player method?
  8. It might just be a misleading log, if you run the command while debugging what's the outcome? I've tried checking the item inside the RightClickBlock event and it works just fine private static final Ingredient FOOD_ITEMS = Ingredient.of(Items.WHEAT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.BEETROOT_SEEDS, Items.TORCHFLOWER_SEEDS, Items.PITCHER_POD); @SubscribeEvent public static void onRightClickBlock(final PlayerInteractEvent.RightClickBlock event) { final ItemStack itemStack = event.getItemStack(); LOGGER.info(FOOD_ITEMS.test(itemStack) + ""); } When I right click a block with an Item it checks if is one of the ingredients of FOOD_ITEMS. Clicking with an empty hand (air) logs false, as expected. Tip: please use the "spoiler" tags for long code snippets and don't merge all your classes into one code snippet EDIT: just noticed you are on 1.20.1. Maybe is just a bug with the Forge version? Try update to the latest Forge 1.20.2 and see if it still occurs
  9. 1.12 is no longer supported Please update to a newer supported version (like 1.19 or even better 1.20). If you absolutely need to use 1.12 you can try to ask someone on the discord server
  10. Is the code inside the event event gets called? I believe that event listeners needs to be public static and the Level parameter should be retrieved from the event itself (not sure if you can provide it as a listener parameter, I don't think so tbh)
  11. Because air is good! Jokes aside, how can you tell that your mob is eating air? Like, there's an actual action in game that you can observe? Also show the full entity code, maybe there's something weird going on there as well PS: don't bump posts, someone will eventually show up You should also consider asking questions in the discord server, wherre is more likely that you'll get a quick response
  12. Are the missing textures coming from a mod you're coding? If not you should contact the mod's authors and report this issue to them Strange issue btw, never heard of that
  13. One quick solution I can think of is to slightly light up the structure so regular mobs can't spawn (they only spawn in complete darkness). Another useful way would be to look at some vanilla structures that doesn't spawn mobs other than the one related to that structure, like the new trial chambers in 1.21 (you can look if there's something particular in the structure json file inside a snapshot jar file) or maybe the end cities (where only Shulkers spawns inside, not even Enderman if I remember correctly)
×
×
  • Create New...

Important Information

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