diff --git a/kubejs/server_scripts/src/custom_trades.js b/kubejs/server_scripts/src/custom_trades.js index 8ee5e8f..63bca23 100644 --- a/kubejs/server_scripts/src/custom_trades.js +++ b/kubejs/server_scripts/src/custom_trades.js @@ -182,8 +182,72 @@ const gems = [ '6x amethyst_shard', ]; +/** + * explorer maps: + * - villages: not very useful, since we're already in one. could be good for biome discovery though. + * - dungeons & mineshafts: fights with chests but are optional. good candidates. + * - shipwreck / ocean_ruins / pyramids / temples / pillager_outpost: optional treasures. + * - woodland mansion & ocean monuments: important for exclusive loot. + * - ancient city: again, exclusive loot. + * - nether portal: required to get to the nether. + * + * it makes little sense to gate the maps, since structures can be stumbled upon anyway and are optional anyway. + * only two maps are created per cartographer upgrade, and you need to move them into the wild. + * so we want to tie new maps to villages, since new villages have new cartographers. + * + * let's do 3 trades + * - a village from a different biome. + * - one of woodland mansion / ocean monument / ancient city / nether portal. + * - one of dungeon / mineshaft / pyramid / temple / pillager outpost. + */ +const treasure_structures = { + '#minecraft:mineshaft': 10, + '#minecraft:pillager_outpost' : 10, + '#betterdungeons:better_dungeons': 5, +}; +const progression_structures = { + '#minecraft:ruined_portal' : 15, + '#minecraft:ancient_city' : 5, + '#minecraft:mansion' : 5, + '#betteroceanmonuments:better_ocean_monuments' : 5, +}; +const village_structures = { + 'village_desert': 1, + 'village_plains': 1, + 'village_savanna': 1, + 'village_snowy': 1, + 'village_taiga': 1, + 'mmv:village_jungle': 1, + 'mmv:village_swamp': 1, + "atmospheric:village_scrubland" : 1 +}; +/** + * @param {Record} map + */ +function make_weighted_list(map){ + const list = MoreJS.weightedList(); + for(const [key, weight] of Object.entries(map)){ + list.add(weight, key); + } + return list; +} + MoreJSEvents.villagerTrades((event) => { event.removeVanillaTrades(); + event.removeModdedTrades(); + + const villages = make_weighted_list(village_structures) + const villageTrade = VillagerUtils.createStructureMapTrade(['empty_map', '2x emerald'], villages); + event.addTrade('cartographer', 2, villageTrade); + + const treasures = make_weighted_list(treasure_structures); + const treasureTrade = VillagerUtils.createStructureMapTrade(['empty_map', '3x emerald'], treasures); + event.addTrade('cartographer', 2, treasureTrade); + + const progression = make_weighted_list(progression_structures); + const progressionTrade = VillagerUtils.createStructureMapTrade(['empty_map', '5x emerald'], progression); + event.addTrade('cartographer', 2, progressionTrade); + const professions = VillagerUtils.getProfessions(); professions.forEach(prof => { const profName = prof.name(); @@ -221,14 +285,15 @@ MoreJSEvents.villagerTrades((event) => { offer.setPriceMultiplier(1); }); // level 2 - event.addCustomTrade(prof, 2, (offer, entity, random) => { - offer.setFirstInput('2x emerald'); - if(rolls > 0) offer.setOutput(genEnchanted(staples, enchantments, rolls, random, true)); - else offer.setOutput(roll(staples, random)); - offer.setMaxUses(1); - offer.setVillagerExperience(1); - offer.setPriceMultiplier(1); - }); + if(staples.length > 0) + event.addCustomTrade(prof, 2, (offer, entity, random) => { + offer.setFirstInput('2x emerald'); + if(rolls > 0) offer.setOutput(genEnchanted(staples, enchantments, rolls, random, true)); + else offer.setOutput(roll(staples, random)); + offer.setMaxUses(1); + offer.setVillagerExperience(1); + offer.setPriceMultiplier(1); + }); // level 1 event.addCustomTrade(prof, 1, (offer, entity, random) => { offer.setFirstInput(roll(food_list, random));