Sinhika Posted April 6, 2020 Share Posted April 6, 2020 (edited) After explanations from Draco18s (which, with his permission, I have documented for future use here: How to use Global Loot Modifiers ), I have tried to implement a loot_modifier that looks for the modded shears items defined in my SimpleOres mod, and then regenerates the loot table as if they were silk touch items (or real minecraft:shears, I have tried both). The goal is to implement modded shears in a other-mod-friendly fashion; overriding vanilla loot tables, the only way I was able to do it previously, is extremely unfriendly to other mods. The mod source code in question is here: https://github.com/Sinhika/SimpleOres2 The loot modifier stuff is in https://github.com/Sinhika/SimpleOres2/blob/1.15/src/main/java/mod/alexndr/simpleores/helpers/SimpleOresLootModifiers.java (Don't want to clutter up this post with lots of source code). It is registered (along with everything else) in https://github.com/Sinhika/SimpleOres2/blob/1.15/src/main/java/mod/alexndr/simpleores/ModEventSubscriber.java I've cut down the loot_modifier/mod_shears_harvest.json to a minimal test case, like so: { "conditions": [ { "condition": "minecraft:match_tool", "predicate": { "item": "simpleores:copper_shears" } } ] } Based on the logs, or lack thereof, the function is being registered, but isn't being called when it ought to be. Can anyone see any reason why, when I whack a leaf block with the copper shears, the loot modifier function isn't being called? Edited April 6, 2020 by Sinhika line breaks messed up looks Quote Stuff I maintain: https://minecraft.curseforge.com/members/sinhika/projects Repositories: https://github.com/Sinhika?tab=repositories Link to comment Share on other sites More sharing options...
Draco18s Posted April 6, 2020 Share Posted April 6, 2020 (edited) Your code looks fine, my guess is that the tool predicate is returning false. Ie. that the item you're using doesn't match "simpleores:copper_shears" Double check your registry names. Scratch that, this file is in the wrong folder: https://github.com/Sinhika/SimpleOres2/blob/1.15/src/main/resources/data/forge/global_loot_modifiers/global_loot_modifiers.json Should be forge/loot_modifiers not forge/global_loot_modifiers. Edited April 6, 2020 by Draco18s 1 Quote Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given. Link to comment Share on other sites More sharing options...
Sinhika Posted April 6, 2020 Author Share Posted April 6, 2020 That does appear to have been the problem! Going on to test with some further refinements. Thank you. Quote Stuff I maintain: https://minecraft.curseforge.com/members/sinhika/projects Repositories: https://github.com/Sinhika?tab=repositories Link to comment Share on other sites More sharing options...
Kalma Posted October 19, 2020 Share Posted October 19, 2020 Hi Sinhika! Thanks a lot for taking the time to make this very useful tutorial (https://dragoness-e.dreamwidth.org/136561.html), there isn't much practical info you can find besides that!!! What it is not clear to me is how to inject custom loot pools into existing vanilla chests tables using this method. Did you find out how to, or you have any "pointer" I can follow? I am working on 1.16.3 version now. Thx again! Quote Link to comment Share on other sites More sharing options...
Kalma Posted October 19, 2020 Share Posted October 19, 2020 Thx for your reply! I guess you mean here: { "conditions": [ { "condition": "minecraft:match_tool", "predicate": { "item": "minecraft:shears" } }, { "condition": "block_state_property", "block":"minecraft:wheat" } ], "seedItem": "minecraft:wheat_seeds", "numSeeds": 3, "replacement": "minecraft:wheat" } I can see there is a "replacement" part which might be the key part (right?), but I don't want to replace it, I would like to add custom items to the vanilla chests loots without replacing it. Quote Link to comment Share on other sites More sharing options...
Kalma Posted October 19, 2020 Share Posted October 19, 2020 Thanks again! I see... may be you mean here? @Nonnull @Override public List<ItemStack> doApply(List<ItemStack> generatedLoot, LootContext context) { // // Additional conditions can be checked, though as much as possible should be parameterized via JSON data. // It is better to write a new ILootCondition implementation than to do things here. // int numSeeds = 0; for(ItemStack stack : generatedLoot) { if(stack.getItem() == itemToCheck) numSeeds+=stack.getCount(); } if(numSeeds >= numSeedsToConvert) { generatedLoot.removeIf(x -> x.getItem() == itemToCheck); generatedLoot.add(new ItemStack(itemReward, (numSeeds/numSeedsToConvert))); numSeeds = numSeeds%numSeedsToConvert; if(numSeeds > 0) generatedLoot.add(new ItemStack(itemToCheck, numSeeds)); } return generatedLoot; } If so, where can I find some info about how to use all this stuff, specially adding or injecting custom loots into existing ones? There isn't anything similar I can search in vanilla classes as far as I know (if there is, sorry, I couldn't find it) Quote Link to comment Share on other sites More sharing options...
Kalma Posted October 19, 2020 Share Posted October 19, 2020 Still not totally clear, sorry, but I think I have a point to start on. I will make some additional tests to try to figure out the solution or make the questions better ! Thanks again! Quote Link to comment Share on other sites More sharing options...
Draco18s Posted October 19, 2020 Share Posted October 19, 2020 See these lines? 3 hours ago, Kalma said: generatedLoot.add(new ItemStack(itemToCheck, numSeeds)); 3 hours ago, Kalma said: generatedLoot.add(new ItemStack(itemReward, (numSeeds/numSeedsToConvert))); That's how you add stuff. The items and amounts in question are initialized by values stored in the json: 3 hours ago, Kalma said: "seedItem": "minecraft:wheat_seeds", "numSeeds": 3, "replacement": "minecraft:wheat" Quote Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given. Link to comment Share on other sites More sharing options...
Kalma Posted October 19, 2020 Share Posted October 19, 2020 Understood. Much clear to me now. Thanks a lot!!! (I had to port my mod to 1.16.3 from 1.14.4 since my last question regarding this very same issue... it is worth anyway). Quote Link to comment Share on other sites More sharing options...
Kalma Posted October 21, 2020 Share Posted October 21, 2020 Hi again! I have been searching and testing a lot. I think I have everything in place (global_loot_modifier.json file, my custom .json file, the class which extends LootModifier class, and the registry stuff). What I still don't get to know is how to add my custom items to the vanilla chests. I guess it is something related to the "conditions" or "type" part of my custom loot_modifier.json, right? I have tried to find out the right option, and I think it can be related to "table_bonus" (though inside the class seems to be related to enchantments) or "reference"... but I am not able to find the "predicate" or whatever is needed to "hook" my items to the chests loot ... Am I missing anything? My global_loot_modifier.json: { "replace": false, "entries": [ "lazybuilder:chests_lazy_builder" ] } My custom loot_modifier.json { "type": "lazybuilder:chests_lazy_builder", "conditions": [ { "condition": "WHAT SHOULD GO HERE???: e.g. reference???", "name":"AND HERE?: e.g. minecraft:chests???" } ], "items": [ { "item": "lazybuilder:start_block", "weight": 20 }, { "item": "lazybuilder:mid_block", "weight": 30 }, { "item": "lazybuilder:end_block", "weight": 20 }, { "item": "lazybuilder:copy_paste_block", "weight": 10 } ] } My LootModifier class public class ChestLootModifier extends LootModifier { @SuppressWarnings("unused") private static final Logger LOGGER = LogManager.getLogger(); private final List<Item> itemToAdd; private final List<Integer> weights; private final String addTo = "minecraft:chests"; ILootCondition[] conditions; public ChestLootModifier(ILootCondition[] conditionsIn, List<Item> itemLoot, List<Integer> itemWeights) { super(conditionsIn); itemToAdd = itemLoot; weights = itemWeights; } @Nonnull @Override public List<ItemStack> doApply(List<ItemStack> generatedLoot, LootContext context) { if (false) { // How do I hook to chests loot to add my stuff??? for (int i = 0; i < itemToAdd.size() && i < weights.size(); ++i) { int randValue = new Random().nextInt(101); int count = 0; if (randValue <= weights.get(i)) { count = 1; } generatedLoot.add(new ItemStack(itemToAdd.get(i), count)); } } return generatedLoot; } public static class Serializer extends GlobalLootModifierSerializer<ChestLootModifier> { @Override public ChestLootModifier read(ResourceLocation name, JsonObject object, ILootCondition[] conditionsIn) { List<Item> blockStack = new ArrayList<Item>(); List<Integer> weightList = new ArrayList<Integer>(); for (JsonElement item : JSONUtils.getJsonArray(object, "items")) { blockStack.add(ForgeRegistries.ITEMS.getValue(new ResourceLocation(JSONUtils.getString(item.getAsJsonObject(), "item")))); weightList.add(JSONUtils.getInt(item.getAsJsonObject(), "weight")); } return new ChestLootModifier(conditionsIn, blockStack, weightList); } @Override public JsonObject write(ChestLootModifier instance) { // TODO Auto-generated method stub return null; } } } Quote Link to comment Share on other sites More sharing options...
Kalma Posted October 21, 2020 Share Posted October 21, 2020 HAHAHAHA! Well... I learned a lot on the way! So, I should stick to the "old" method, right? public class onLootTableLoadListener { @SubscribeEvent public void LootTablesLoad(final LootTableLoadEvent event) { String prefix = "minecraft:chests/"; String name = event.getName().toString(); // Test: /loot give @p loot minecraft:chests/pillager_outpost if (name.startsWith(prefix)) { event.getTable().addPool(LootPool.builder() .addEntry(TableLootEntry.builder(new ResourceLocation(Refs.MODID, "chests/lazy_builder")) .weight(1)) .bonusRolls(0, 1) .name(Refs.MODID) .build() ); } } } Thank you anyway! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.