{"action":"closed","issue":{"url":"https://api.github.com/repos/MinecraftForge/MinecraftForge/issues/2540","repository_url":"https://api.github.com/repos/MinecraftForge/MinecraftForge","labels_url":"https://api.github.com/repos/MinecraftForge/MinecraftForge/issues/2540/labels{/name}","comments_url":"https://api.github.com/repos/MinecraftForge/MinecraftForge/issues/2540/comments","events_url":"https://api.github.com/repos/MinecraftForge/MinecraftForge/issues/2540/events","html_url":"https://github.com/MinecraftForge/MinecraftForge/issues/2540","id":140453312,"number":2540,"title":"[1.9] Loot table hooking","user":{"login":"williewillus","id":2015032,"avatar_url":"https://avatars.githubusercontent.com/u/2015032?v=3","gravatar_id":"","url":"https://api.github.com/users/williewillus","html_url":"https://github.com/williewillus","followers_url":"https://api.github.com/users/williewillus/followers","following_url":"https://api.github.com/users/williewillus/following{/other_user}","gists_url":"https://api.github.com/users/williewillus/gists{/gist_id}","starred_url":"https://api.github.com/users/williewillus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/williewillus/subscriptions","organizations_url":"https://api.github.com/users/williewillus/orgs","repos_url":"https://api.github.com/users/williewillus/repos","events_url":"https://api.github.com/users/williewillus/events{/privacy}","received_events_url":"https://api.github.com/users/williewillus/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-03-13T06:09:43Z","updated_at":"2016-03-14T23:21:44Z","closed_at":"2016-03-14T23:21:44Z","body":"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.\r\n\r\n### Some terminology\r\nCtrl+F \"Loot tables\" in this for some basic terminology\r\n[https://gist.github.com/williewillus/e37edde85dc78d2e138c](https://gist.github.com/williewillus/e37edde85dc78d2e138c)\r\n\r\n### Adding pieces to the looting system\r\n* All the abovementioned classes are easy to add to in code. Each class has its own registry where you can register your object to a name, e.g. I can register a LootFunction \"botania:add_mana\" that takes a stack and adds mana to it simply by calling LootFunctionManager.registerFunction(Serializer). For all of these, you have to pass in a serializer describing how it'll be (de)serialized from JSON form.\r\n\r\n### Activation of the looting system\r\n* For living entities: The entire loot table system is only queried for subclasses of EntityLiving. `EntityLivingBase#onDeath` calls `dropLoot`, which is fully overriden by EntityLiving. `dropFewItems` doesn't do anything anymore (except for slimes which still use it for some reason.\r\n    * The loot table to use is an NBT tag in the entity, \"DeathLootTable\". Falls back to a default for vanilla mobs.\r\n    * The forge hook to capture drops is in `EntityLivingBase#onDeath` and 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?\r\n* For TE's and things like minecarts. These implement ILootableContainer, which contains a single method returning the ResourceLocation of the loot table to generate. TE's and carts have a field/NBT tag that holds this ResourceLocation. Upon the first opening of the container, the loot table is queried and then the loot table field in the object is set to null. It's possible in code for the loot table to be re-set so that it regenerates again whenever the container is opened next. I don't think this requires any hooking/modification.\r\n\r\n### Loading of loot tables\r\nProbably the most difficulty piece to figure out currently.\r\nAlthough 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 jar if the former is missing (LootTableManager.class.getResource(URL)), then to an empty table if it's still missing.\r\nThe 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\r\nThe 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.\r\n(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)\r\n\r\nAlternatively we could just forego this entirely, use the vanilla registries, and just have mods \"figure it out\" how to get an instance of `LootTable` to the registry. (i.e. they handle deserialization themselves). But that's meh.\r\n\r\nThoughts?\r\n\r\n### What would get obsoleted\r\n* `ChestGenHooks` and `FishingHooks` are both going to go away\r\n    * This requires us to determine a way to inject mod entries into the main loot tables. Can't replace the tables because then mods would conflict. Would using the events proposed above be suitable?"}}