Stargate Network

Stargate Network

3M Downloads

SGCraft Loot is unmodifiable

Daomephsta opened this issue ยท 0 comments

commented

The loot code in SGCraft has several issues:

  1. It misuses the custom flag here. When this flag is true, Forge names loaded entries using a hash, making the name session and JDK implementation dependent. Forge uses it to prevent mods from editing loot overridden by a save's /data folder. I do not recommend it's use by mods, as it makes it impossible for users to remove loot entries via LootTweaker or similar mods, as there is no consistent unique identifier for the loot entries.

  2. It injects frozen loot pools into non-frozen loot tables. After LootTableLoadEvent is fired for a table, that table and all its pools become frozen, any modification will throw an exception. Due to this, loading another table and copying its pools into the table currently being loaded, as SGCraft does, will add frozen pools. LootTweaker can safely modify these accidentally frozen pools, due to internal implementation details, but it's likely that other loot editing mods can't.

Below is an altered version of SGCraft's code, which uses a different method to add SGCraft's "inject" tables to the vanilla tables.
This method is known not to cause any issues, I first saw it in Botania.

    @SubscribeEvent
    public void onLootTableLoad(LootTableLoadEvent event) {
        ResourceLocation locn = event.getName();
        if (locn.getNamespace().equals("minecraft")) {
            String path = String.format("/assets/%s/loot_tables/%s.json", assetKey, locn.getPath());
            if (getClass().getResource(path) != null) { // Check if there's an inject table for this vanilla table
                event.getTable().addPool(new LootPool(new LootEntry[]
                    {
                        new LootEntryTable(new ResourceLocation(assetKey, locn.getPath()),
                            1, // Weight is arbitrary, as the pool contains only this entry
                            0, // 0 is default quality
                            new LootCondition[0], "sgcraft_inject_entry")
                    },
                    new LootCondition[0],
                    new RandomValueRange(1), // Roll the inject table exactly once, more wouldn't
                    new RandomValueRange(0), // be equivalent to directly injecting the pools
                    "sgcraft_inject_pool"));
            }
        }
    }

I would have made a PR, but the SpongeForge maven was breaking any attempt to fetch dependencies (Gradle tries every maven repository, but errors if any returns an error status code, regardless of whether one provided the dependency)