Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SGCraft Loot is unmodifiable #183

Open
Daomephsta opened this issue Apr 7, 2021 · 0 comments
Open

SGCraft Loot is unmodifiable #183

Daomephsta opened this issue Apr 7, 2021 · 0 comments

Comments

@Daomephsta
Copy link

Daomephsta commented Apr 7, 2021

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant