Views
Actions
Difference between revisions of "Datageneration/Loot Tables"
Ferri Arnus (talk | contribs) |
(Update to 1.17, needs major rewrite) |
||
Line 21: | Line 21: | ||
Also you would need a Function to save the Tables | Also you would need a Function to save the Tables | ||
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
− | private void writeTables( | + | private void writeTables(HashCache cache, Map<ResourceLocation, LootTable> tables) { |
Path outputFolder = this.generator.getOutputFolder(); | Path outputFolder = this.generator.getOutputFolder(); | ||
tables.forEach((key, lootTable) -> { | tables.forEach((key, lootTable) -> { | ||
Path path = outputFolder.resolve("data/" + key.getNamespace() + "/loot_tables/" + key.getPath() + ".json"); | Path path = outputFolder.resolve("data/" + key.getNamespace() + "/loot_tables/" + key.getPath() + ".json"); | ||
try { | try { | ||
− | + | DataProvider.save(GSON, cache, LootTables.serialize(lootTable), path); | |
} catch (IOException e) { | } catch (IOException e) { | ||
LOGGER.error("Couldn't write loot table {}", path, (Object) e); | LOGGER.error("Couldn't write loot table {}", path, (Object) e); | ||
Line 53: | Line 53: | ||
* <code>.name</code> is used for the pool name. | * <code>.name</code> is used for the pool name. | ||
* <code>.setRolls</code> is used for the amount. | * <code>.setRolls</code> is used for the amount. | ||
− | * <code>.add</code> is used to add an <code> | + | * <code>.add</code> is used to add an <code>LootPoolEntryContainer$Builder</code>. You can have multiple entries. |
− | + | A <code>LootPoolEntryContainer$Builder</code> defines what entry container is returned, and which functions and/or conditions are applied (see [https://minecraft.fandom.com/wiki/Loot_table Loot table] for the vanilla functions and conditions). | |
− | * <code>. | + | * <code>.when</code> is used to apply a condition. These themselves can have multiple operations. |
− | |||
− | After all attributes have been added the <code>LootPool.Builder</code> can be used to make a <code>LootTable.Builder</code> of the proper <code> | + | After all attributes have been added the <code>LootPool.Builder</code> can be used to make a <code>LootTable.Builder</code> of the proper <code>LootContextParamSet</code>. This builder can then be added to an entry in the <code>lootTables</code> map made in the previous section (you should do this in the overwritten abstract method). |
<syntaxhighlight lang="java"> | <syntaxhighlight lang="java"> | ||
LootPool.Builder builder = LootPool.lootPool() | LootPool.Builder builder = LootPool.lootPool() | ||
.name(...) | .name(...) | ||
.setRolls(...) | .setRolls(...) | ||
− | .add( | + | .add(LootItem.lootTableItem(...) |
− | .apply( | + | .apply(function1) |
− | .apply( | + | .apply(function2) |
− | . | + | .when(condition1) |
− | . | + | .when(condition2)) |
); | ); | ||
LootTable.lootTable().withPool(builder).setParamSet(...); | LootTable.lootTable().withPool(builder).setParamSet(...); | ||
</syntaxhighlight>[[Category:Data Generation]] | </syntaxhighlight>[[Category:Data Generation]] |
Revision as of 23:18, 31 July 2021
This page is under construction.
This page is incomplete, and needs more work. Feel free to edit and improve this page!
Loot Tables are not so polished like the other Providers. You need need to do some work to get them to a good state.
Preperation
First you would need a new Class that extend the LootTableProvider
. In this class you would override the run
and optionally getName
Method.
In the getName
you just return the Name shown in the Logs.
Also you should create a abstract Method which you would override in subclasses but this is not strictly needed.
Also you need a Gson constant. You would create it like this private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
You should also save the DataGenerator
for later use since you can't access from the LootTableProvider
.
Also you would need two Maps, one with the the Class which is used to get the Lootable Resource Location in this example the Block and one the Loot Table Builder.
The second Map consist of a ResourceLocation
and the actual LootTable
. Look at the Code for more info.
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(); protected final Map<Block, LootTable.Builder> lootTables = new HashMap<>(); public static Map<ResourceLocation, LootTable> tables = new HashMap<>(); protected final DataGenerator generator;
Also you would need a Function to save the Tables
private void writeTables(HashCache cache, Map<ResourceLocation, LootTable> tables) { Path outputFolder = this.generator.getOutputFolder(); tables.forEach((key, lootTable) -> { Path path = outputFolder.resolve("data/" + key.getNamespace() + "/loot_tables/" + key.getPath() + ".json"); try { DataProvider.save(GSON, cache, LootTables.serialize(lootTable), path); } catch (IOException e) { LOGGER.error("Couldn't write loot table {}", path, (Object) e); } }); }
For the writeTables method you would need to convert the First Map to the second map, for this we need to iterate over the first map.
lootTables.forEach(blockBuilderMap -> { for (Map.Entry<Block, LootTable.Builder> entry : blockBuilderMap.entrySet()) { tables.put(entry.getKey().getLootTable(), entry.getValue().build()); } });
in the run
method you would then first call the method where you create the tables or just create them in there (if you do you can ignore the next section), then you would convert the Tables and at last you would save the loottables.
The actual Class for Lootables
Another class (Optional)
Create a new class that extends from the Class you created in the Section above and override the abstract function in there you can begin to create your Lootables.
The LootPool Builder
This is where you actually make a loottable. You start with an empty LootPool
and add the necessary attributes to it.
.name
is used for the pool name..setRolls
is used for the amount..add
is used to add anLootPoolEntryContainer$Builder
. You can have multiple entries.
A LootPoolEntryContainer$Builder
defines what entry container is returned, and which functions and/or conditions are applied (see Loot table for the vanilla functions and conditions).
.when
is used to apply a condition. These themselves can have multiple operations.
After all attributes have been added the LootPool.Builder
can be used to make a LootTable.Builder
of the proper LootContextParamSet
. This builder can then be added to an entry in the lootTables
map made in the previous section (you should do this in the overwritten abstract method).
LootPool.Builder builder = LootPool.lootPool() .name(...) .setRolls(...) .add(LootItem.lootTableItem(...) .apply(function1) .apply(function2) .when(condition1) .when(condition2)) ); LootTable.lootTable().withPool(builder).setParamSet(...);