const chancePerScroll = 0.3 const notFoundBonusRolls = 2 const hexCastingScrollTables = { few: [ "minecraft:chests/jungle_temple", "repurposed_structures:archaeology/monument_jungle", "minecraft:chests/simple_dungeon", "betterdungeons:zombie_dungeon/chests/special", "betterdungeons:skeleton_dungeon/chests/middle", "betterdungeons:small_dungeon/chests/loot_piles", // "betterdungeons:spider_dungeon/chests/egg_room", "nova_structures:archaelogy/desert_ruin_inside_temple", "nova_structures:chests/stray_fort_tresure", /^repurposed_structures:chests\/dungeons\//, "repurposed_structures:chests/bastions/underground/treasure" ], some: [ "minecraft:chests/bastion_treasure", "minecraft:chests/shipwreck_map", /^repurposed_structures:chests\/shipwrecks\/\w+\/map$/, "nova_structures:chests/desert_ruins/desert_ruin_main_temple", "nova_structures:chests/witch_villa/lab" ], many: [ "minecraft:chests/stronghold_library", "betterfortresses:chests/worship" ] } LootJS.modifiers(event => { event .addLootTableModifier(hexCastingScrollTables.few) .apply(catchWrap(rollScrolls(1))) event .addLootTableModifier(hexCastingScrollTables.some) .apply(catchWrap(rollScrolls(2))) event .addLootTableModifier(hexCastingScrollTables.many) .apply(catchWrap(rollScrolls(3))) }) function catchWrap(method) { return function(a) { try { return method.call(this, a) } catch(err) { console.error(err) } } } // const PatternRegistry = Java.loadClass('at.petrak.hexcasting.api.PatternRegistry') const IXplatAbstractions = Java.loadClass('at.petrak.hexcasting.xplat.IXplatAbstractions') const HexUtils = Java.loadClass('at.petrak.hexcasting.api.utils.HexUtils') const HexTags = Java.loadClass('at.petrak.hexcasting.api.mod.HexTags') const PatternRegistryManifest = Java.loadClass('at.petrak.hexcasting.common.casting.PatternRegistryManifest') // const HexPattern = Java.loadClass('at.petrak.hexcasting.api.spell.math.HexPattern') const CompoundTag = Java.loadClass('net.minecraft.nbt.CompoundTag') ServerEvents.highPriorityData(datapack => { // let perworldPatterns = PatternRegistry.getAllPerWorldPatternNames().toArray() let patternKeys = getPerWorldPatternKeys() for(let key of patternKeys) { let resourcePath = `kubejs:advancements/${getAdvancementPath(key)}` datapack.addJson( resourcePath, createScrollAdvancement(key) ) } }) const getAdvancementPath = patternKey => { let rl = patternKey.location() return `scrolls/${rl.getNamespace()}/${rl.getPath()}` } const createScrollAdvancement = patternKey => ({ "criteria": { "requirement": { "trigger": "minecraft:inventory_changed", "conditions": { "items": [ { "items": [ "hexcasting:scroll" ], "nbt": JSON.stringify({ op_id: patternKey.toString() }) } ] } } } }) // https://github.com/FallingColors/HexMod/issues/629 const rollScrolls = count => lootContext => { console.log('Loading scrolls') // Remove the scrolls already added by hexcasting lootContext.removeLoot(Ingredient.of("hexcasting:scroll")) if(lootContext.getPlayer() == null) { console.error('Cannot generate scrolls without a player') return } // let worldLookup = PatternRegistry.getPerWorldPatterns(lootContext.getLevel()) let table = createWeightedPatternTable(lootContext, getPerWorldPatternKeys(), notFoundBonusRolls) let random = lootContext.getRandom() for(let i = 0; i < count; i++) { let patternKey = table[random.nextInt(table.length)] let pattern = PatternRegistryManifest.getCanonicalStrokesPerWorld(patternKey, lootContext.getServer().getOverworld()) let entry = LootEntry.of('hexcasting:scroll', createScrollTag(patternKey, pattern)) .when(c => c.randomChance(chancePerScroll)) lootContext.addLoot(entry) } } const createWeightedPatternTable = (lootContext, patternKeys, notFoundBonus) => { let player = lootContext.getPlayer() // https://github.com/FallingColors/HexMod/blob/6286da360820cf542b38b862cfc1011145e2f78b/Common/src/main/java/at/petrak/hexcasting/common/loot/AddPerWorldPatternToScrollFunc.java#L43 let table = [] for(let patternKey of patternKeys) { let advancementId = new ResourceLocation('kubejs', getAdvancementPath(patternKey)) let advancement = player.server.getAdvancement(advancementId).advancement let hasFound = player.advancements.getOrStartProgress(advancement).done if(!hasFound) { for(let i = 0; i < notFoundBonus; i++) { table.push(patternKey) } } table.push(patternKey) } return table } const resourceKeyIsOfTag = 'isOfTag(net.minecraft.core.Registry,net.minecraft.resources.ResourceKey,net.minecraft.tags.TagKey)' const getPerWorldPatternKeys = () => { let actionRegistry = IXplatAbstractions.INSTANCE.getActionRegistry() return actionRegistry.registryKeySet() .toArray() .filter(key => { return HexUtils[resourceKeyIsOfTag](actionRegistry, key, HexTags.Actions.PER_WORLD_PATTERN) }) } // https://github.com/FallingColors/HexMod/blob/6286da360820cf542b38b862cfc1011145e2f78b/Common/src/main/java/at/petrak/hexcasting/common/loot/AddPerWorldPatternToScrollFunc.java#L50 const createScrollTag = (patternKey, pattern) => { let tag = new CompoundTag() tag.putString('op_id', patternKey.location().toString()) tag.put('pattern', pattern.serializeToNBT()) return tag }