Jump to content

[1.15.2] Manipulate Actual Block Drops (not WHAT can drop)


Recommended Posts

Posted

I was wondering if anyone had any breadcrumbs I could follow to figure out how to manipulate the drop of a block after it has been destroyed (by a player, don't care about any other way), i.e. remove the drop entity from the world and place into players pack.

I've looked into events, but there either isn't one, or I looked right past it, as well as methods to override in ToolItem.

I'd like to be able to do this with any block and its drops, so overriding a method in Block didn't seem like the way to go.

I haven't looked into if this is done using LootTables or not yet, since I only know basic loot tables so far, but I guess that's probably where I'll be looking next?

 

Thanks for any pointers :)

Posted

EntityJoinWorldEvent

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.

Posted
27 minutes ago, Draco18s said:

EntityJoinWorldEvent

Thanks for the reply :)

I took a look at that, and I think it might be too broad, I wasn't descriptive enough about what I need I think.

I need to be able to know when my tool breaks a block, and then either prevent the entity from spawning, or more or less immediately remove the entity, and put the corresponding item into the players inventory. I don't need to change what is dropping for loot, just manipulate the results as I hope I've described well enough.

 

Still tinkering, I'll update if I figure something out, and certainly open to pointers/ideas! :)

Posted

In order to do that you need to wait at a minimum until the item entity exists and has joined the world.

The earliest point you can be sure that that has happened is EntityJoinWorldEvent. Just check that the entity is an ItemEntity.

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.

Posted

So it's easy enough to determine if the entity spawning is an ItemEntity, but how do I differentiate between the stone that I mined with the tool I'm using or the cobblestone someone standing next to me is throwing away? They both fire the event, and I can't see a way to determine between the two.

Posted

Check the itemstack in the entity's item.

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.

Posted
3 minutes ago, Draco18s said:

Check the itemstack in the entity's item.

I guess i'm missing where the ItemStack lets me know it was a harvested block :(

Posted (edited)

The event has an entity, you already know how to check if it is an ItemEntity

ItemEntity#getItem()

Edited by Draco18s

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.

Posted
19 minutes ago, Draco18s said:

The event has an entity, you already know how to check if it is an ItemEntity

ItemEntity#getItem()

You misunderstand me.

I can get the itemstack, I know how :)

But, how would this itemstack of a mined stone (resulting in an itemstack of cobblestone) differ from an itemstack of cobble someone threw? Or 2 different itemstacks of cobble from different pickaxes?

I wish I knew how to rephrase my question to make it more clear.

Posted

You may have to tag the stacks with a global loot modifier in some manner.

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.

Posted (edited)
14 hours ago, Draco18s said:

You may have to tag the stacks with a global loot modifier in some manner.

Thanks, I've been looking into this, and using the global_loot_test on github as an example.

I'm using DeferredRegister, and adding it to the modbus in my mod constructor, and things seem all good, however I'm getting this error:

Quote

[08:06:49] [Server thread/ERROR] [ne.mi.co.lo.LootModifierManager/]: Couldn't parse loot modifier bunchostuff:sinaite_modifier
java.lang.NullPointerException: null
    at net.minecraftforge.common.loot.LootModifierManager.deserializeModifier(LootModifierManager.java:111) ~[?:?] {re:classloading}

DeferredRegister setup

public static final DeferredRegister<GlobalLootModifierSerializer<?>> LOOT_MODIFIERS = 
	new DeferredRegister<GlobalLootModifierSerializer<?>>(ForgeRegistries.LOOT_MODIFIER_SERIALIZERS, "bunchostuff");
public RegistryObject<GlobalLootModifierSerializer<?>> SINAITE_MODIFIER = 
	LOOT_MODIFIERS.register("sinaite_modifier", () -> new SinaiteModifier.Serializer());

In my mod constructor:

ModLootModifiers.LOOT_MODIFIERS.register(modEventBus);

 

my loot modifier in data/bunchostuff/loot_modifiers/sinaite_modifier.json

{
  "type": "bunchostuff:sinaite_modifier",
  "conditions": [
    {
      "condition": "minecraft:match_tool",
      "predicate": {
            "item": "bunchostuff:sinaite_pickaxe"
      }
    }
  ]
}

and of course data/forge/loot_modifiers/global_loot_modifiers.json

{
	"replace": false,
	"entries": [
		"bunchostuff:sinaite_modifier"
	]
}

 

Totally at a loss, everything looks right, debugging and stepping into it, the best I can come up with is something missing from conditions resulting in it being null,

*edit: so it makes it here in LootModifierManager without any incident, as far as I can tell:

return ForgeRegistries.LOOT_MODIFIER_SERIALIZERS.getValue(serializer).read(location, object, lootConditions); //line 139

but stepping into that, when it goes into ForgeRegistry, things just go null, despite checking serializer, location, object, and lootConditions, which all appear to have the correct stuff in them; both serializer and location are my modid:loot_modifier, object appears to be the entire json of my loot modifier, and lootConditions has MatchTool and the details of the tool  I wanted it to match, so it seems to be finding that part.

*end edit

 

but it all looks right to me, and I can't see what's missing. I haven't made too many loot tables, so I'm sure I missed something or messed something up despite getting the basic idea of it.

 

All I'm trying to do in the modifier is print to the log when the tool match is true. Modifier class if needed, but it's awful basic:

package ugdhar.mod.bunchostuff.loot;

import java.util.List;

import com.google.gson.JsonObject;

import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.storage.loot.LootContext;
import net.minecraft.world.storage.loot.conditions.ILootCondition;
import net.minecraftforge.common.loot.GlobalLootModifierSerializer;
import net.minecraftforge.common.loot.LootModifier;
import ugdhar.mod.bunchostuff.BunchOStuff;

public class SinaiteModifier extends LootModifier {

	public SinaiteModifier(ILootCondition[] conditionsIn) {
		super(conditionsIn);
	}

	@Override
	public List<ItemStack> doApply(List<ItemStack> generatedLoot, LootContext context) {
		BunchOStuff.LOGGER.info("Made it into the doApply method of our loot modifier!");
		return generatedLoot;
	}
	
    public static class Serializer extends GlobalLootModifierSerializer<SinaiteModifier> {
        @Override
        public SinaiteModifier read(ResourceLocation name, JsonObject json, ILootCondition[] conditionsIn) {
            return new SinaiteModifier(conditionsIn);
        }
    }	

}

 

*edit: This is with forge 1.15.2-31.1.44 and mappings from 20200413

 

Thanks for taking the time to check this out and give me pointers!

Edited by Ugdhar
made constructor/methods in modifier public, didn't change results.
Posted

Line 111 is:

return ForgeRegistries.LOOT_MODIFIER_SERIALIZERS.getValue(location).read(location, object, ailootcondition);

So it looks like your serializer isn't getting registered correctly.

 

I can't tell why.

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.

Posted
2 hours ago, Ugdhar said:

public static final DeferredRegister<GlobalLootModifierSerializer<?>> LOOT_MODIFIERS =

Did you remember to give this the Mod Event Bus?

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted
1 minute ago, Animefan8888 said:

Did you remember to give this the Mod Event Bus?

 

2 hours ago, Ugdhar said:

In my mod constructor:


ModLootModifiers.LOOT_MODIFIERS.register(modEventBus);

 

I figured it out though.

 

11 minutes ago, Draco18s said:

Line 111 is:

return ForgeRegistries.LOOT_MODIFIER_SERIALIZERS.getValue(location).read(location, object, ailootcondition);

So it looks like your serializer isn't getting registered correctly.

 

I can't tell why.

 

Evidently, I either used DeferredRegister wrong, or this feature does not work with DeferredRegister. I rewrote it like this:

 

in ModLootModifiers:

	@ObjectHolder("bunchostuff:sinaite_modifier")
	public static GlobalLootModifierSerializer<?> SINAITE_MODIFIER = null;

and made a new class since I didn't have anything doing any registering:

@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)
public class EventHandlerClass {

	@SubscribeEvent
	public static void regLootModifier(RegistryEvent.Register<GlobalLootModifierSerializer<?>> args) {
		args.getRegistry().register(new SinaiteModifier.Serializer().setRegistryName("bunchostuff", "sinaite_modifier"));
	}
	
}

and of course commented out the deferredregister stuff, and now I'm getting my logging as expected.

 

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

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