Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

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

Featured Replies

Posted

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 :)

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

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.

  • Author

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

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...

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.