Jump to content

[SOLVED][1.17.1] Using functions inside Global Loot Modifiers


Recommended Posts

Posted (edited)

Hi everyone! :D As the title says, I am wondering if there is a way to use vanilla loot table functions inside a Global Loot Modifier. For instance: I want to add a Sword to the Mineshaft chests and I want this Sword to be randomly enchanted, kinda like vanilla does it to Desert Pyarmid chests or for End Cities. In the first case, this function is called

minecraft:enchant_randomly

while for End Cities is this one
 

{
	"function": "minecraft:enchant_with_levels",
	"levels": {
		"type": "minecraft:uniform",
		"min": 20.0,
		"max": 39.0
	},
	"treasure": true
}

Either way, using these functions the Item can sometime be enchanted. How can I make so in a Loot Modifier I can use these functions as well, if is ever possible? I read the doc about Global Item Modifier and of course have seen the GitHub examples. This helped me setting up some Loot Modifiers, which has no issues adding custom items to Vanilla Loot Tables, however I can't seem to find any example or indication about the possibility to use functions inside Loot Modifiers (aside from inserting some custom keywords in the json that if parsed will manually trigger the said function)

Edited by JimiIT92
solved

Don't blame me if i always ask for your help. I just want to learn to be better :)

Posted (edited)

Basically yes. You're probably going to have to do some poking around and testing on your own, but the Java side of a GlobalLootModifier is code like any other class, which means it has access to the vanilla loot functions. Just implement the doApply function and you're set.

If you're clever enough you can make your modifier parse the desired loot function and do a lookup (via the existing registry), rather than only do one thing.

The only reason that loot functions aren't parsed and handled for you (the way conditions are) is because generally a modifier is a loot function (that is, performing the same role), so there wasn't an explicit need.

Edited by Draco18s
  • Like 1

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

Alright, so after a whole morning of tries, I finally got it working!
Let's say I have this object inside my GLM json
 

{
      "item": "minecraft:emerald",
      "chance": 0.0265,
      "functions": [
        {
          "function": "minecraft:set_count",
          "count": {
            "type": "minecraft:uniform",
            "min": 2.0,
            "max": 7.0
          },
          "add": false
        }
      ]
    }

where I am saying that the emerald has a 2.65% chacne of being inside the chest loot. But, I want that the stack, if any, must be between 2 and 7 items. Sure I can add my "min" and "max" parameters, but since we already have a function that does this, why not using it? So I added the vanilla set_count function, using the exact same syntax as any vanilla loot table. In the deserializer (the class that extends GlobalLootModifierSerializer) I can read the functions array by doing so
 

var functionsArray = jsonObject.getAsJsonArray("functions");
if(functionsArray != null) {
	var functions = Deserializers.createFunctionSerializer().create().fromJson(functionsArray, LootItemFunction[].class);
}

This will return a LootItemFunction array that is the actual list of functions that are specified inside the JSON, correctly deserialized. So we can store these functions and use them when adding the ItemStack to the generated loot, by doing a simple for loop
 

var stack = new ItemStack(item);
if(functions != null && !functions.isEmpty()) {
	functions.forEach(function -> function.apply(stack, context));
}

By doing that the function will be applied to the item of the GLM! Of course we are not limited by the set_count, but we can use any vanilla function as we want (I think even custom functions, but I'm not sure about this since I haven't any of these).

To correctly serialize said functions, inside the write method, we can use this function
 

Deserializers.createFunctionSerializer().create().toJsonTree(functions)

assuming that functions is a variable containing all of the functions previously deserialized

  • Like 1

Don't blame me if i always ask for your help. I just want to learn to be better :)

  • JimiIT92 changed the title to [SOLVED][1.17.1] Using functions inside Global Loot Modifiers

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.