[1.9] Loot hooks#2543
Conversation
| * Add your own loot pool to the Loot Table. | ||
| * @param pool The pool to add to the list of pools. | ||
| */ | ||
| public void addPool(LootPool pool) |
There was a problem hiding this comment.
Why not expose the pools list instead? Doing so will allow clearing, removing, adding etc.
There was a problem hiding this comment.
It's not exposed for removal because Loot Pools have NO identifying information whatsoever. You'd have no idea at all what you're removing
This is the part I need to figure out, because for a true alternative to the old hooks ee need to be able to merge pools together, not just tables
There was a problem hiding this comment.
You may not be able to identify them easily, but it's still nice to be able to control the list directly. addAll, clear, etc methods are available there, whereas there's just an add method here
There was a problem hiding this comment.
Again, we can FORCE mod ones to have unique identifiers, and we should.
As for vanilla we can fake these unique identifiers quite a bit.
| * Call this anytime during startup. | ||
| */ | ||
| public static void registerOverride(Function<ResourceLocation, InputStream> override) | ||
| { |
There was a problem hiding this comment.
What prevents ModA taking over loot tables for ModB directly?
|
Yeah not sure where I wanna go with this :P |
|
So reading through the vanilla spec, I just realized that a loot entry can simply point to another loot table. So my idea is, at least for the time being so we get feature parity again, is that on startup modders call some registration method and specify the Loot Table + Loot Pool that they want to add an entry to, as well as the resource path of their loot table. Forge will than inject another loot entry that points to the modder's loot table. |
|
The issue is still uniquely identifying the loot pools/entries in the cases where vanilla specify multiple of them {there are like 5 cases} As any entry that is a table is just a link to another table not it's own instance, we don't have to care about recursion. tables.get('minecraft:fishing').getPool('main').getEntry('minecraft:fishing/treasure') is the same exact result as tables.get('minecraft:fishing/treasure') Anyways what i'm thinking is two processes: To edit existing ones, im not to sure. We could either do it in code 'LootTableLoadEvent' and let them do their own modification in code which SHOULD look something like: And then something like this for removing/adding entries for items: Now, what happens if ModA removes "minecraft:fish.1" does "minecraft:fish.2" becomes .1? No, These IDs are static and will be generated at the beginning. Just some things i've been spit-balling around. Think you could poke at it willie? |
|
Mmm that seems like a sound idea Idk if I can do it though, I want to work on getting my PIE PR in, and between that and Botania and ProjectE and school I probably don't have time to spend on loot tables much (I don't really need it that desperately, really). If other modders need it more desperately feel free to whip up your own impl based on what Lex has said above, feel free to steal code from this impl. |
|
superseded |
Preliminary draft:
Done so far:
Not done yet:
I thought I'd start off the discussion for this, since it's one of the parts I'm most interested in in 1.9.
Some terminology
Ctrl+F "Loot tables" in this for some basic terminology
https://gist.github.com/williewillus/e37edde85dc78d2e138c
Adding pieces to the looting system
Activation of the looting system
EntityLivingBase#onDeathcallsdropLoot, which is fully overriden by EntityLiving.dropFewItemsdoesn't do anything anymore (except for slimes which still use it for some reason.EntityLivingBase#onDeathand should still capture all loot dropped. Perhaps we should provide the loot context in LivingDropsEvent, though that would require us to move the event. A more viable alternative is to expose the LootContext in an event, allowing others to modify the Loot Tables in code?Loading of loot tables
Probably the most difficulty piece to figure out currently.
Although loot tables in the vanilla jar are in the "/assets/" directory, they are far from being part of the powerful cascading resource pack / clientside asset system. What vanilla does currently in
LootTableManager.Loader.load(ResourceLocation)is look for loot jsons in the world directory (new File(LootTableManager#baseFolder, ...)), a vanilla feature allowing mappers to override tables, and then fall back directly to the classpath (mod jars) if the former is missing (LootTableManager.class.getResource(URL)), then to an empty table if it's still missing.The easiest solution is simply to place a hook directly below the loading from world folder call, that loads from mod jars, but still lets mappers' world-specific tables have top priority
The question arises is that with this, we don't know what jar to look in. Looking at the resource domain of the resource location to determine which jar to search would be a fallback but it would prevent an addon for example from changing its parent mod's tables. Or we could scan through all jars to look for any loot json, but that implicitly enforces an ordering in the case of conflicting jsons.
(Or we could find a way to bring that whole cascading resource system to the serverside? I don't know that system well enough to say if that's feasible)
Alternatively we could just forego this entirely, use the vanilla registries, and just have mods "figure it out" how to get an instance of
LootTableto the registry. (i.e. they handle deserialization themselves). But that's meh.Thoughts?
What would get obsoleted
ChestGenHooksandFishingHooksare both going to go away