-
How to register new LootFunction - 1.16.5
Slight update - I had a bug in my code that caused minecraft to hang. Pretty sure directly registering it with Registry.register would have worked; but my question of how to do it the "right" way still stands. Right now the access transformer works as intended.
-
How to register new LootFunction - 1.16.5
I see now Astral is able to do that since they use an access transformer for that function. https://github.com/HellFirePvP/AstralSorcery/blob/e8434f1a09356632babefee1925626dc3deefb2a/src/main/resources/META-INF/accesstransformer.cfg#L12 Is that the only way to do this?
-
How to register new LootFunction - 1.16.5
Hi, I'm trying to register a new LootFunction to use in my loot table data generator. I was loosely basing it off of Astral Sorcery's loot table data generators, since I'm trying to achieve a similar effect. Here's my loot table provider: package org.tutmods.shungite.data; import com.google.common.collect.ImmutableList; import com.mojang.datafixers.util.Pair; import net.minecraft.block.Block; import net.minecraft.block.Blocks; import net.minecraft.data.DataGenerator; import net.minecraft.data.LootTableProvider; import net.minecraft.data.loot.BlockLootTables; import net.minecraft.enchantment.Enchantments; import net.minecraft.item.Item; import net.minecraft.item.Items; import net.minecraft.loot.ItemLootEntry; import net.minecraft.loot.LootParameterSet; import net.minecraft.loot.LootParameterSets; import net.minecraft.loot.LootPool; import net.minecraft.loot.LootTable; import net.minecraft.loot.LootTableManager; import net.minecraft.loot.RandomValueRange; import net.minecraft.loot.ValidationTracker; import net.minecraft.loot.functions.ApplyBonus; import net.minecraft.loot.functions.ExplosionDecay; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fml.RegistryObject; import org.tutmods.shungite.loot.ShungiteCrystalPropertiesLoot; import org.tutmods.shungite.setup.ModBlocks; import org.tutmods.shungite.setup.ModItems; import org.tutmods.shungite.setup.Registration; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.stream.Collectors; public class ModLootTableProvider extends LootTableProvider { public ModLootTableProvider(DataGenerator generator) { super(generator); } @Override protected List<Pair<Supplier<Consumer<BiConsumer<ResourceLocation, LootTable.Builder>>>, LootParameterSet>> getTables() { return ImmutableList.of(Pair.of(ModBlockLootTables::new, LootParameterSets.BLOCK)); } @Override protected void validate(Map<ResourceLocation, LootTable> map, ValidationTracker validationtracker) { map.forEach( (one, two) -> LootTableManager.validate(validationtracker, one, two)); } public static class ModBlockLootTables extends BlockLootTables { @Override protected void addTables() { this.add(ModBlocks.SHUNGITE_CRYSTAL_ORE.get(), (block) -> LootTable.lootTable() .withPool(LootPool.lootPool() .setRolls(RandomValueRange.between(2F, 5F)) .add(ItemLootEntry.lootTableItem(ModItems.SHUNGITE.get()) .apply(ExplosionDecay.explosionDecay()) .apply(ShungiteCrystalPropertiesLoot.builder())) )); } @Override protected Iterable<Block> getKnownBlocks() { return Registration.BLOCK_DEFERRED_REGISTER.getEntries() .stream().map(RegistryObject::get).collect(Collectors.toList()); } } } And the loot function I want to add: package org.tutmods.shungite.loot; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonObject; import net.minecraft.item.ItemStack; import net.minecraft.loot.LootContext; import net.minecraft.loot.LootFunction; import net.minecraft.loot.LootFunctionType; import net.minecraft.loot.conditions.ILootCondition; import org.tutmods.shungite.items.crystal.ShungiteCrystal; import org.tutmods.shungite.items.crystal.properties.ShungiteCrystalProperties; import org.tutmods.shungite.util.crystal.CrystalUtils; public class ShungiteCrystalPropertiesLoot extends LootFunction { protected ShungiteCrystalPropertiesLoot(ILootCondition[] conditions) { super(conditions); } @Override protected ItemStack run(ItemStack stack, LootContext lootContext) { if (stack.getItem() instanceof ShungiteCrystal) { final ShungiteCrystalProperties properties = CrystalPropertyGenerator.getRandomNewCrystalProperties(); CrystalUtils.putProperties(stack, properties); } return stack; } public static LootFunction.Builder<?> builder() { return simpleBuilder(ShungiteCrystalPropertiesLoot::new); } @Override public LootFunctionType getType() { return Functions.ShungiteCrystalsLoot; } public static class Functions { public static LootFunctionType ShungiteCrystalsLoot; } public static class Serializer extends LootFunction.Serializer<ShungiteCrystalPropertiesLoot> { @Override public ShungiteCrystalPropertiesLoot deserialize(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext, ILootCondition[] iLootConditions) { return new ShungiteCrystalPropertiesLoot(iLootConditions); } } } I see Astral doing similar things here: https://github.com/HellFirePvP/AstralSorcery/blob/1.16-indev/src/main/java/hellfirepvp/astralsorcery/common/loot/RandomCrystalProperty.java https://github.com/HellFirePvP/AstralSorcery/blob/e8434f1a09356632babefee1925626dc3deefb2a/src/main/java/hellfirepvp/astralsorcery/datagen/data/loot/BlockLootTableProvider.java#L77 However, my trouble comes when running the data generator. I can't register the serializer as Astral does here https://github.com/HellFirePvP/AstralSorcery/blob/e8434f1a09356632babefee1925626dc3deefb2a/src/main/java/hellfirepvp/astralsorcery/common/registry/RegistryLoot.java#L49, since LootFunctionManager.register is private. Is there a new way of doing this? I tried just calling Registry.register as LootFunctionManager.register does itself, and I was able to generate JSON with that, however my game hung as soon as I broke the block; so I assume I'm doing something wrong. I saw there's a new DeferredRegister for LootModifiers, but I'm not sure if that fulfills the same role as a LootFunction? So I guess I have two questions: How do I register my serializer for my LootFunction correctly? What's the difference between a LootFunction and a LootModifier?
-
[Solved] world.setBlockState not updating all blocks
I guess I was just confused as to how things were getting handled when something is updated on the server. Not sure how I didn't see it before, thanks all.
-
[Solved] world.setBlockState not updating all blocks
I see the issue. But I'm not sure why being on the server means the client isn't being updated, if the setBlock event should update the client?
-
[Solved] world.setBlockState not updating all blocks
Here's the whole class. public class ShungiteDowsingRod extends Item implements IForgeItem { public ShungiteDowsingRod(Properties properties) { super(properties); } @Override public ActionResultType useOn(ItemUseContext itemUseContext) { final World world = itemUseContext.getLevel(); if (!world.isClientSide()) { final Stream<BlockPos> blocksBetweenPlayerLookingAndDowsingEffect = BlockPos.betweenClosedStream( WorldHelper.getAABBInDirectionWithOffset( itemUseContext.getClickedPos(), itemUseContext.getClickedFace(), 0, 1, 1 ) ); blocksBetweenPlayerLookingAndDowsingEffect.forEach( blockPos -> { world.setBlock(blockPos, Blocks.CYAN_WOOL.defaultBlockState(), ( Constants.BlockFlags.DEFAULT_AND_RERENDER ) ); }); } return super.useOn(itemUseContext); } }
-
[Solved] world.setBlockState not updating all blocks
Thank you for letting me know! Unfortunately still having issues. I'm not sure why this code isn't working.. blocksBetweenPlayerLookingAndDowsingEffect.forEach( blockPos -> { world.setBlock(blockPos, Blocks.CYAN_WOOL.defaultBlockState(), ( Constants.BlockFlags.DEFAULT_AND_RERENDER ) ); }); Here's an example of the behavior I'm experiencing.. https://files.catbox.moe/z4ov1m.m4v
-
[Solved] world.setBlockState not updating all blocks
setBlockAndUpdate uses flag 3, but I've tried 1, 2, and 4 with no success. Is there any documentation on what these flags do? I found this thread but since I'm using the mojang mappings I don't think I have the same javadocs.
-
[Solved] world.setBlockState not updating all blocks
Hi, I have an AABB that I want to set all of the blocks in to a different block. final Stream<BlockPos> blocksBetweenPlayerLookingAndDowsingEffect = BlockPos.betweenClosedStream( WorldHelper.getAABBInDirectionWithOffset( itemUseContext.getClickedPos(), itemUseContext.getClickedFace(), 0, 1, 1 ) ); blocksBetweenPlayerLookingAndDowsingEffect.forEach( blockPos -> { world.setBlockAndUpdate(blockPos, Blocks.CYAN_WOOL.defaultBlockState()); }); I think there were different names for both of betweenClosedStream and setBlockAndUpdate in the MCP mappings. So it's been hard to find exactly the fix I'm looking for. The problem I'm facing now is that when I call setBlockAndUpdate, only the first clicked on block updates. The rest don't update until I restart the world. I assume this has something to do with being used in a stream, or the flag that's used on setBlock? I'm not entirely sure. Thanks!
-
[1.12] Cannot add ItemStack to Chest
Alright, one more question now that I've realized my issues. If I want to set the inventory of any TileEntity, I can do it straight from HuskItem's method? Are there any examples I can look at where syncing the inventory between client and server is necessary then? I think I'm just confused about when and where to use packets, I guess.
-
[1.12] Cannot add ItemStack to Chest
Holy shit I'm dumb. This is what I get for copy/pasting. Edit: Will do what you said as well. I can't believe that I haven't seen that though.
-
[1.12] Cannot add ItemStack to Chest
Alright, rebuilt how the item works now. I think it's much better this time around, but I'm having a strange crash. Is there some sort of limit on what I can write / read from the buffer? Or am I still doing something wrong and dumb? The code in the main post has been updated to the newest version. Crash log:
-
[1.12] Cannot add ItemStack to Chest
Ah. I'm really dumb. Got logical and physical confused. Thanks for making me not dumb.
-
[1.12] Cannot add ItemStack to Chest
Ok, I understand the last two points. However, I'm not sure how I would be on the server when I send the packet. I could be thinking about it all wrong, but from what I understand I am sending the packet on line 103 of the HuskItem class. How could I be on the server when I send the packet? Once again, I'm probably wrong here but FMLCommonHandler.getSide() returns that (when I'm sending the packet) I'm calling it from the client. Am I seeing something the wrong way?
-
[1.12.2] NullPointerException caused when accessing ArrayList in a packet
I just don't know why it's null. Is there something within Java that I just don't understand here? Edit: I think I got it. Trying some stuff now.
IPS spam blocked by CleanTalk.