From 28d8882fa4f0265d6b511e68892ba1a404e717d2 Mon Sep 17 00:00:00 2001 From: LLytho Date: Fri, 26 Jul 2024 15:00:10 +0200 Subject: [PATCH] refactor trades and prepare more 1.21 stuff --- CHANGELOG.md | 2 +- build.gradle.kts | 1 + example_scripts/trading.js | 52 +++++++++++++++- gradle.properties | 2 +- .../almostreliable/morejs/MoreJSBinding.java | 33 ++++++++--- .../features/villager/VillagerUtils.java | 18 ++++-- .../features/villager/trades/MapPosInfo.java | 16 ----- .../villager/trades/TreasureMapTrade.java | 59 ++++--------------- .../morejs/util/BlockPosFinder.java | 14 +++++ .../morejs/util/LevelUtils.java | 41 ------------- 10 files changed, 115 insertions(+), 123 deletions(-) delete mode 100644 src/main/java/com/almostreliable/morejs/features/villager/trades/MapPosInfo.java create mode 100644 src/main/java/com/almostreliable/morejs/util/BlockPosFinder.java delete mode 100644 src/main/java/com/almostreliable/morejs/util/LevelUtils.java diff --git a/CHANGELOG.md b/CHANGELOG.md index f97c759..b7371fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [0.11.0] - TBA +## [Unreleased] - Update to 1.21 diff --git a/build.gradle.kts b/build.gradle.kts index ff6dadd..b285243 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -21,6 +21,7 @@ plugins { } repositories { + mavenLocal() maven("https://maven.saps.dev/minecraft") maven("https://www.cursemaven.com") } diff --git a/example_scripts/trading.js b/example_scripts/trading.js index 72ee38f..6e1d70c 100644 --- a/example_scripts/trading.js +++ b/example_scripts/trading.js @@ -42,7 +42,55 @@ MoreJS.updateOffer((event) => { }); MoreJS.updateOffer((event) => { - if (event.isProfession("minecraft:cartographer")) { + if (event.isProfession("minecraft:cartographer") && event.random.nextDouble() < 0.7) { + const randomBiome = Registry.of("worldgen/biome").getValues("#minecraft:is_overworld").getRandom(); + const trade = VillagerUtils.createBiomeMapTrade("minecraft:emerald_block", randomBiome).displayName( + "Random biome" + ); + event.setOffer(trade); + } +}); +MoreJS.updateOffer((event) => { + if (!event.isProfession("farmer")) { + return; } -}) + + const tag = "#minecraft:is_savanna"; + const registry = Registry.of("worldgen/biome"); + const holders = registry.getValues(tag); + const biome = registry.getRandom(); + const biomeId = registry.getId(biome); + const biome2 = holders.getRandom(); + const biome2Id = registry.getId(biome2); + console.log("==============="); + console.log(`All overworld biomes: ${holders.keys}`); + console.log(`Biome: ${biomeId} contains in ${tag}: ${holders.containsValue(biome)} / ${holders.contains(biomeId)}`); + console.log( + `Biome 2: ${biome2Id} contains in ${tag}: ${holders.containsValue(biome2)} / ${holders.contains(biome2Id)}` + ); + console.log(`Biomes do exist: ${registry.containsValue(biome)} / ${registry.containsValue(biome2)}`); + console.log(registry.getValues(tag).size()); +}); + +MoreJS.updateOffer((event) => { + if (!event.isProfession("farmer")) { + return; + } + + const ItemAttributeModifiers = Java.loadClass("net.minecraft.world.item.component.ItemAttributeModifiers"); + + const attributes = ItemAttributeModifiers.builder() + .add( + "minecraft:generic.attack_damage", + { + id: "minecraft:base_attack_damage", + operation: "add_value", + amount: 4.0, + }, + "mainhand" + ) + .build(); + const item = Item.of("minecraft:stick").set("minecraft:attribute_modifiers", attributes); + event.offer.output = item; +}); diff --git a/gradle.properties b/gradle.properties index 6821eda..97a29d2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ modDescription = More KubeJS stuff. # Common minecraftVersion = 1.21 neoforgeVersion = 21.0.98-beta -kubejsVersion = 2100.7.0-build.96 +kubejsVersion = 2100.7.0-build.109 # Github githubUser = AlmostReliable diff --git a/src/main/java/com/almostreliable/morejs/MoreJSBinding.java b/src/main/java/com/almostreliable/morejs/MoreJSBinding.java index a566ef3..1c60744 100644 --- a/src/main/java/com/almostreliable/morejs/MoreJSBinding.java +++ b/src/main/java/com/almostreliable/morejs/MoreJSBinding.java @@ -2,15 +2,15 @@ import com.almostreliable.morejs.features.villager.IntRange; import com.almostreliable.morejs.features.villager.TradeItem; -import com.almostreliable.morejs.util.LevelUtils; -import com.almostreliable.morejs.util.ResourceOrTag; import com.almostreliable.morejs.util.Utils; import com.almostreliable.morejs.util.WeightedList; +import com.mojang.datafixers.util.Pair; import dev.latvian.mods.kubejs.item.ItemStackJS; import dev.latvian.mods.kubejs.util.RegistryAccessContainer; import dev.latvian.mods.kubejs.util.UtilsJS; import net.minecraft.core.BlockPos; -import net.minecraft.core.registries.Registries; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderSet; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.levelgen.structure.Structure; @@ -20,15 +20,30 @@ public class MoreJSBinding { @Nullable - public static BlockPos findStructure(BlockPos position, ServerLevel level, String structure, int chunkRadius) { - ResourceOrTag rot = ResourceOrTag.get(structure, Registries.STRUCTURE); - return LevelUtils.findStructure(position, level, rot, chunkRadius); + public static BlockPos findStructure(BlockPos position, ServerLevel level, HolderSet structures, int chunkRadius) { + var result = level + .getChunkSource() + .getGenerator() + .findNearestMapStructure(level, structures, position, chunkRadius, true); + if (result == null) { + return null; + } + + return result.getFirst(); } @Nullable - public static BlockPos findBiome(BlockPos position, ServerLevel level, String biome, int chunkRadius) { - ResourceOrTag rot = ResourceOrTag.get(biome, Registries.BIOME); - return LevelUtils.findBiome(position, level, rot, chunkRadius); + public static BlockPos findBiome(BlockPos position, ServerLevel level, HolderSet biomes, int chunkRadius) { + Pair> nearestBiome = level.findClosestBiome3d(biomes::contains, + position, + chunkRadius * 16, + 32, + 64); + if (nearestBiome != null) { + return nearestBiome.getFirst(); + } + + return null; } public static WeightedList.Builder weightedList() { diff --git a/src/main/java/com/almostreliable/morejs/features/villager/VillagerUtils.java b/src/main/java/com/almostreliable/morejs/features/villager/VillagerUtils.java index 9060cb1..e2ae209 100644 --- a/src/main/java/com/almostreliable/morejs/features/villager/VillagerUtils.java +++ b/src/main/java/com/almostreliable/morejs/features/villager/VillagerUtils.java @@ -1,8 +1,10 @@ package com.almostreliable.morejs.features.villager; +import com.almostreliable.morejs.MoreJSBinding; import com.almostreliable.morejs.features.villager.trades.*; -import com.almostreliable.morejs.util.WeightedList; +import com.almostreliable.morejs.util.BlockPosFinder; import com.google.common.collect.ImmutableList; +import net.minecraft.core.HolderSet; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceLocation; @@ -11,6 +13,8 @@ import net.minecraft.world.entity.npc.VillagerProfession; import net.minecraft.world.entity.npc.VillagerTrades; import net.minecraft.world.item.Item; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.levelgen.structure.Structure; import java.util.*; import java.util.concurrent.ThreadLocalRandom; @@ -66,15 +70,17 @@ public static CustomTrade createCustomTrade(TransformableTrade.Transformer trans return new CustomTrade(transformer); } - public static TreasureMapTrade createStructureMapTrade(TradeItem[] inputs, WeightedList structures) { - return TreasureMapTrade.forStructure(inputs, structures); + public static TreasureMapTrade createStructureMapTrade(TradeItem[] inputs, HolderSet structures) { + return new TreasureMapTrade(inputs, + (level, entity) -> MoreJSBinding.findStructure(entity.blockPosition(), level, structures, 100)); } - public static TreasureMapTrade createBiomeMapTrade(TradeItem[] inputs, WeightedList biomes) { - return TreasureMapTrade.forBiome(inputs, biomes); + public static TreasureMapTrade createBiomeMapTrade(TradeItem[] inputs, HolderSet biomes) { + return new TreasureMapTrade(inputs, + (level, entity) -> MoreJSBinding.findBiome(entity.blockPosition(), level, biomes, 250)); } - public static TreasureMapTrade createCustomMapTrade(TradeItem[] inputs, MapPosInfo.Provider func) { + public static TreasureMapTrade createCustomMapTrade(TradeItem[] inputs, BlockPosFinder func) { return new TreasureMapTrade(inputs, func); } diff --git a/src/main/java/com/almostreliable/morejs/features/villager/trades/MapPosInfo.java b/src/main/java/com/almostreliable/morejs/features/villager/trades/MapPosInfo.java deleted file mode 100644 index 2005dce..0000000 --- a/src/main/java/com/almostreliable/morejs/features/villager/trades/MapPosInfo.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.almostreliable.morejs.features.villager.trades; - -import net.minecraft.core.BlockPos; -import net.minecraft.network.chat.Component; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.Entity; - -import javax.annotation.Nullable; - -public record MapPosInfo(BlockPos pos, Component name) { - @FunctionalInterface - public interface Provider { - @Nullable - MapPosInfo apply(ServerLevel level, Entity entity); - } -} diff --git a/src/main/java/com/almostreliable/morejs/features/villager/trades/TreasureMapTrade.java b/src/main/java/com/almostreliable/morejs/features/villager/trades/TreasureMapTrade.java index 605a40f..b22f9e2 100644 --- a/src/main/java/com/almostreliable/morejs/features/villager/trades/TreasureMapTrade.java +++ b/src/main/java/com/almostreliable/morejs/features/villager/trades/TreasureMapTrade.java @@ -1,13 +1,9 @@ package com.almostreliable.morejs.features.villager.trades; import com.almostreliable.morejs.features.villager.TradeItem; -import com.almostreliable.morejs.util.LevelUtils; -import com.almostreliable.morejs.util.ResourceOrTag; -import com.almostreliable.morejs.util.WeightedList; -import net.minecraft.core.BlockPos; +import com.almostreliable.morejs.util.BlockPosFinder; import net.minecraft.core.Holder; import net.minecraft.core.component.DataComponents; -import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.RandomSource; @@ -22,50 +18,16 @@ import javax.annotation.Nullable; public class TreasureMapTrade extends TransformableTrade { - protected final MapPosInfo.Provider destinationPositionFunc; + protected final BlockPosFinder blockPosFinder; @Nullable protected Component displayName; protected Holder destinationType = MapDecorationTypes.RED_X; private boolean renderBiomePreviewMap = true; private byte mapViewScale = 2; - public TreasureMapTrade(TradeItem[] inputs, MapPosInfo.Provider destinationPositionFunc) { + public TreasureMapTrade(TradeItem[] inputs, BlockPosFinder blockPosFinder) { super(inputs); - this.destinationPositionFunc = destinationPositionFunc; - } - - public static TreasureMapTrade forStructure(TradeItem[] input, WeightedList entries) { - var list = entries.map(o -> { - if (o == null) { - return null; - } - return ResourceOrTag.get(o.toString(), Registries.STRUCTURE); - }); - - MapPosInfo.Provider func = (level, entity) -> { - var roll = list.roll(level.random); - BlockPos pos = LevelUtils.findStructure(entity.blockPosition(), level, roll, 100); - if (pos == null) return null; - return new MapPosInfo(pos, roll.getName()); - }; - return new TreasureMapTrade(input, func); - } - - public static TreasureMapTrade forBiome(TradeItem[] input, WeightedList entries) { - var list = entries.map(o -> { - if (o == null) { - return null; - } - return ResourceOrTag.get(o.toString(), Registries.BIOME); - }); - - MapPosInfo.Provider func = (level, entity) -> { - var roll = list.roll(level.random); - BlockPos pos = LevelUtils.findBiome(entity.blockPosition(), level, roll, 250); - if (pos == null) return null; - return new MapPosInfo(pos, roll.getName()); - }; - return new TreasureMapTrade(input, func); + this.blockPosFinder = blockPosFinder; } public TreasureMapTrade displayName(Component name) { @@ -92,13 +54,16 @@ public TreasureMapTrade scale(byte scale) { @Nullable public MerchantOffer createOffer(Entity trader, RandomSource random) { if (trader.level() instanceof ServerLevel level) { - MapPosInfo info = destinationPositionFunc.apply(level, trader); - if (info == null) return null; + var pos = blockPosFinder.findPosition(level, trader); + if (pos == null) return null; - ItemStack map = MapItem.create(level, info.pos().getX(), info.pos().getZ(), this.mapViewScale, true, true); + ItemStack map = MapItem.create(level, pos.getX(), pos.getZ(), this.mapViewScale, true, true); if (renderBiomePreviewMap) MapItem.renderBiomePreviewMap(level, map); - MapItemSavedData.addTargetDecoration(map, info.pos(), "+", destinationType); - map.set(DataComponents.CUSTOM_NAME, displayName == null ? info.name() : displayName); + MapItemSavedData.addTargetDecoration(map, pos, "+", destinationType); + if (displayName != null) { + map.set(DataComponents.CUSTOM_NAME, displayName); + } + return createOffer(map, random); } diff --git a/src/main/java/com/almostreliable/morejs/util/BlockPosFinder.java b/src/main/java/com/almostreliable/morejs/util/BlockPosFinder.java new file mode 100644 index 0000000..e10690d --- /dev/null +++ b/src/main/java/com/almostreliable/morejs/util/BlockPosFinder.java @@ -0,0 +1,14 @@ +package com.almostreliable.morejs.util; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; + +import javax.annotation.Nullable; + +@FunctionalInterface +public interface BlockPosFinder { + + @Nullable + BlockPos findPosition(ServerLevel level, Entity entity); +} diff --git a/src/main/java/com/almostreliable/morejs/util/LevelUtils.java b/src/main/java/com/almostreliable/morejs/util/LevelUtils.java deleted file mode 100644 index 566328b..0000000 --- a/src/main/java/com/almostreliable/morejs/util/LevelUtils.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.almostreliable.morejs.util; - -import com.mojang.datafixers.util.Pair; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.registries.Registries; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.levelgen.structure.Structure; - -import javax.annotation.Nullable; - -public class LevelUtils { - - @Nullable - public static BlockPos findStructure(BlockPos position, ServerLevel level, ResourceOrTag rot, int chunkRadius) { - return level - .registryAccess() - .registry(Registries.STRUCTURE) - .flatMap(rot::asHolderSet) - .map(holderSet -> level - .getChunkSource() - .getGenerator() - .findNearestMapStructure(level, holderSet, position, chunkRadius, true)) - .map(Pair::getFirst) - .orElse(null); - } - - @Nullable - public static BlockPos findBiome(BlockPos position, ServerLevel level, ResourceOrTag rot, int chunkRadius) { - Pair> nearestBiome = level.findClosestBiome3d(rot.asHolderPredicate(), - position, - chunkRadius * 16, - 32, - 64); - if (nearestBiome != null) { - return nearestBiome.getFirst(); - } - return null; - } -}