mirror of
https://github.com/LeavesMC/Leaves.git
synced 2025-12-19 14:59:32 +00:00
Update Jade Protocol, and fix #250
This commit is contained in:
@@ -44,17 +44,97 @@ index 055f4b87c01ee7ecf7d2a111b72cc5aa85d9fbe8..5d9030f4787a43c56ae9455180badd56
|
||||
protected long nextMobSpawnsAt;
|
||||
protected int totalMobsSpawned;
|
||||
public Optional<SpawnData> nextSpawnData;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/storage/loot/LootPool.java b/src/main/java/net/minecraft/world/level/storage/loot/LootPool.java
|
||||
index 38078c44b35e917d1d243a5f8599aa858d8611de..13dbadfb50278b79b33d9dce10413c93c9e4ff31 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/storage/loot/LootPool.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/storage/loot/LootPool.java
|
||||
@@ -36,7 +36,7 @@ public class LootPool {
|
||||
)
|
||||
.apply(instance, LootPool::new)
|
||||
);
|
||||
- private final List<LootPoolEntryContainer> entries;
|
||||
+ public final List<LootPoolEntryContainer> entries; // Leaves - private -> public
|
||||
private final List<LootItemCondition> conditions;
|
||||
private final Predicate<LootContext> compositeCondition;
|
||||
private final List<LootItemFunction> functions;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java b/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java
|
||||
index edaf7f1692ae059581f3abc24bb228874e6d114b..f09cfc472d4dbdc8cb0b6a45ef240b25a865ffba 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/storage/loot/LootTable.java
|
||||
@@ -58,7 +58,7 @@ public class LootTable {
|
||||
public static final Codec<Holder<LootTable>> CODEC = RegistryFileCodec.create(Registries.LOOT_TABLE, LootTable.DIRECT_CODEC);
|
||||
private final LootContextParamSet paramSet;
|
||||
private final Optional<ResourceLocation> randomSequence;
|
||||
- private final List<LootPool> pools;
|
||||
+ public final List<LootPool> pools; // Leaves - private -> public
|
||||
private final List<LootItemFunction> functions;
|
||||
private final BiFunction<ItemStack, LootContext, ItemStack> compositeFunction;
|
||||
public CraftLootTable craftLootTable; // CraftBukkit
|
||||
diff --git a/src/main/java/net/minecraft/world/level/storage/loot/entries/CompositeEntryBase.java b/src/main/java/net/minecraft/world/level/storage/loot/entries/CompositeEntryBase.java
|
||||
index 128792f76f02d74c1ccf84beb8e7973453424639..775fbddf3e3b133e33f54aaa8e8a07d131095e34 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/storage/loot/entries/CompositeEntryBase.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/storage/loot/entries/CompositeEntryBase.java
|
||||
@@ -9,7 +9,7 @@ import net.minecraft.world.level.storage.loot.ValidationContext;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
|
||||
public abstract class CompositeEntryBase extends LootPoolEntryContainer {
|
||||
- protected final List<LootPoolEntryContainer> children;
|
||||
+ public final List<LootPoolEntryContainer> children; // Leaves - private -> public
|
||||
private final ComposableEntryContainer composedChildren;
|
||||
|
||||
protected CompositeEntryBase(List<LootPoolEntryContainer> terms, List<LootItemCondition> conditions) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java b/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java
|
||||
index 1d2f2bb352abf6772cd20293575fc79e8e64ce3b..b157dfaf1efffebd3f2ae8cb8fcf0972fe742258 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer.java
|
||||
@@ -13,7 +13,7 @@ import net.minecraft.world.level.storage.loot.predicates.ConditionUserBuilder;
|
||||
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
|
||||
public abstract class LootPoolEntryContainer implements ComposableEntryContainer {
|
||||
- protected final List<LootItemCondition> conditions;
|
||||
+ public final List<LootItemCondition> conditions; // Leaves - private -> public
|
||||
private final Predicate<LootContext> compositeCondition;
|
||||
|
||||
protected LootPoolEntryContainer(List<LootItemCondition> conditions) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java b/src/main/java/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java
|
||||
index 71989359192c8f30a1a8d343a2c6cb5b92330491..ec273bd4d0e61f54532df599f00695e8b9d44800 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java
|
||||
@@ -25,7 +25,7 @@ public class NestedLootTable extends LootPoolSingletonContainer {
|
||||
.and(singletonFields(instance))
|
||||
.apply(instance, NestedLootTable::new)
|
||||
);
|
||||
- private final Either<ResourceKey<LootTable>, LootTable> contents;
|
||||
+ public final Either<ResourceKey<LootTable>, LootTable> contents; // Leaves - private -> public
|
||||
|
||||
private NestedLootTable(
|
||||
Either<ResourceKey<LootTable>, LootTable> value, int weight, int quality, List<LootItemCondition> conditions, List<LootItemFunction> functions
|
||||
diff --git a/src/main/java/net/minecraft/world/level/storage/loot/predicates/CompositeLootItemCondition.java b/src/main/java/net/minecraft/world/level/storage/loot/predicates/CompositeLootItemCondition.java
|
||||
index 30d0133a42ce990352f5c492fcf9beb105364848..1ab2eab686b3a89d406f127a6036c0e2932db4a6 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/storage/loot/predicates/CompositeLootItemCondition.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/storage/loot/predicates/CompositeLootItemCondition.java
|
||||
@@ -11,7 +11,7 @@ import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.level.storage.loot.ValidationContext;
|
||||
|
||||
public abstract class CompositeLootItemCondition implements LootItemCondition {
|
||||
- protected final List<LootItemCondition> terms;
|
||||
+ public final List<LootItemCondition> terms; // Leaves - private -> public
|
||||
private final Predicate<LootContext> composedPredicate;
|
||||
|
||||
protected CompositeLootItemCondition(List<LootItemCondition> terms, Predicate<LootContext> predicate) {
|
||||
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..33741d707715619929e5412a786470c5372f5978
|
||||
index 0000000000000000000000000000000000000000..0f40d3b95de7cefbf1318109cb45d13732f25534
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java
|
||||
@@ -0,0 +1,343 @@
|
||||
@@ -0,0 +1,397 @@
|
||||
+package org.leavesmc.leaves.protocol.jade;
|
||||
+
|
||||
+import io.netty.buffer.ByteBuf;
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.core.registries.BuiltInRegistries;
|
||||
+import net.minecraft.core.registries.Registries;
|
||||
+import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.network.FriendlyByteBuf;
|
||||
+import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
+import net.minecraft.network.codec.ByteBufCodecs;
|
||||
@@ -75,6 +155,7 @@ index 0000000000000000000000000000000000000000..33741d707715619929e5412a786470c5
|
||||
+import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
|
||||
+import net.minecraft.world.entity.monster.ZombieVillager;
|
||||
+import net.minecraft.world.item.ItemStack;
|
||||
+import net.minecraft.world.item.Items;
|
||||
+import net.minecraft.world.level.Level;
|
||||
+import net.minecraft.world.level.block.Block;
|
||||
+import net.minecraft.world.level.block.CampfireBlock;
|
||||
@@ -128,11 +209,13 @@ index 0000000000000000000000000000000000000000..33741d707715619929e5412a786470c5
|
||||
+import org.leavesmc.leaves.protocol.jade.provider.entity.StatusEffectsProvider;
|
||||
+import org.leavesmc.leaves.protocol.jade.provider.entity.ZombieVillagerProvider;
|
||||
+import org.leavesmc.leaves.protocol.jade.util.HierarchyLookup;
|
||||
+import org.leavesmc.leaves.protocol.jade.util.LootTableMineableCollector;
|
||||
+import org.leavesmc.leaves.protocol.jade.util.PairHierarchyLookup;
|
||||
+import org.leavesmc.leaves.protocol.jade.util.PriorityStore;
|
||||
+import org.leavesmc.leaves.protocol.jade.util.WrappedHierarchyLookup;
|
||||
+
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Collections;
|
||||
+import java.util.Comparator;
|
||||
+import java.util.List;
|
||||
+import java.util.function.Predicate;
|
||||
@@ -140,14 +223,12 @@ index 0000000000000000000000000000000000000000..33741d707715619929e5412a786470c5
|
||||
+
|
||||
+@LeavesProtocol(namespace = "jade")
|
||||
+public class JadeProtocol {
|
||||
+
|
||||
+ public static PriorityStore<ResourceLocation, IJadeProvider> priorities;
|
||||
+ private static List<Block> shearableBlocks = List.of();
|
||||
+
|
||||
+ public static final String PROTOCOL_ID = "jade";
|
||||
+
|
||||
+ // send
|
||||
+ public static final ResourceLocation PACKET_SERVER_PING = id("server_ping");
|
||||
+ public static final ResourceLocation PACKET_RECEIVE_DATA = id("receive_data");
|
||||
+
|
||||
+ private static final HierarchyLookup<IJadeDataProvider<EntityAccessor>> entityDataProviders = new HierarchyLookup<>(Entity.class);
|
||||
+ private static final PairHierarchyLookup<IJadeDataProvider<BlockAccessor>> blockDataProviders = new PairHierarchyLookup<>(new HierarchyLookup<>(Block.class), new HierarchyLookup<>(BlockEntity.class));
|
||||
+
|
||||
@@ -224,12 +305,20 @@ index 0000000000000000000000000000000000000000..33741d707715619929e5412a786470c5
|
||||
+ blockDataProviders.register(TrialSpawnerBlockEntity.class, MobSpawnerCooldownProvider.INSTANCE);
|
||||
+
|
||||
+ itemStorageProviders.register(CampfireBlock.class, CampfireProvider.INSTANCE);
|
||||
+
|
||||
+ try {
|
||||
+ shearableBlocks = Collections.unmodifiableList(LootTableMineableCollector.execute(
|
||||
+ MinecraftServer.getServer().registryAccess().registryOrThrow(Registries.LOOT_TABLE),
|
||||
+ Items.SHEARS.getDefaultInstance()));
|
||||
+ } catch (Throwable ignore) {
|
||||
+ LeavesLogger.LOGGER.severe("Failed to collect shearable blocks");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @ProtocolHandler.PlayerJoin
|
||||
+ public static void onPlayerJoin(ServerPlayer player) {
|
||||
+ if (LeavesConfig.jadeProtocol) {
|
||||
+ ProtocolUtils.sendPayloadPacket(player, PACKET_SERVER_PING, buf -> buf.writeUtf(""));
|
||||
+ ProtocolUtils.sendPayloadPacket(player, new ServerPingPayload("", shearableBlocks));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
@@ -273,7 +362,7 @@ index 0000000000000000000000000000000000000000..33741d707715619929e5412a786470c5
|
||||
+ }
|
||||
+ tag.putInt("EntityId", entity.getId());
|
||||
+
|
||||
+ ProtocolUtils.sendPayloadPacket(player, PACKET_RECEIVE_DATA, buf -> buf.writeNbt(tag));
|
||||
+ ProtocolUtils.sendPayloadPacket(player, new ReceiveDataPayload(tag));
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
@@ -327,7 +416,7 @@ index 0000000000000000000000000000000000000000..33741d707715619929e5412a786470c5
|
||||
+ tag.putInt("z", pos.getZ());
|
||||
+ tag.putString("BlockId", BuiltInRegistries.BLOCK.getKey(block).toString());
|
||||
+
|
||||
+ ProtocolUtils.sendPayloadPacket(player, PACKET_RECEIVE_DATA, buf -> buf.writeNbt(tag));
|
||||
+ ProtocolUtils.sendPayloadPacket(player, new ReceiveDataPayload(tag));
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
@@ -349,12 +438,12 @@ index 0000000000000000000000000000000000000000..33741d707715619929e5412a786470c5
|
||||
+ private static final ResourceLocation PACKET_REQUEST_ENTITY = JadeProtocol.id("request_entity");
|
||||
+
|
||||
+ @New
|
||||
+ public RequestEntityPayload(ResourceLocation id, FriendlyByteBuf buf) {
|
||||
+ public RequestEntityPayload(ResourceLocation id, @NotNull FriendlyByteBuf buf) {
|
||||
+ this(buf.readBoolean(), buf.readVarInt(), buf.readVarInt(), new Vec3(buf.readVector3f()));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void write(FriendlyByteBuf buf) {
|
||||
+ public void write(@NotNull FriendlyByteBuf buf) {
|
||||
+ buf.writeBoolean(showDetails);
|
||||
+ buf.writeVarInt(entityId);
|
||||
+ buf.writeVarInt(partIndex);
|
||||
@@ -369,17 +458,18 @@ index 0000000000000000000000000000000000000000..33741d707715619929e5412a786470c5
|
||||
+ }
|
||||
+
|
||||
+ public record RequestBlockPayload(boolean showDetails, BlockHitResult hitResult, BlockState blockState, ItemStack fakeBlock) implements LeavesCustomPayload<RequestBlockPayload> {
|
||||
+
|
||||
+ private static final ResourceLocation PACKET_REQUEST_BLOCK = JadeProtocol.id("request_block");
|
||||
+ private static final StreamCodec<RegistryFriendlyByteBuf, ItemStack> ITEM_STACK_CODEC = ItemStack.OPTIONAL_STREAM_CODEC;
|
||||
+ private static final StreamCodec<ByteBuf, BlockState> BLOCK_STATE_CODEC = ByteBufCodecs.idMapper(Block.BLOCK_STATE_REGISTRY);
|
||||
+ private static final ResourceLocation PACKET_REQUEST_BLOCK = JadeProtocol.id("request_block");
|
||||
+
|
||||
+ @New
|
||||
+ public RequestBlockPayload(ResourceLocation id, FriendlyByteBuf buf) {
|
||||
+ public RequestBlockPayload(ResourceLocation id, @NotNull FriendlyByteBuf buf) {
|
||||
+ this(buf.readBoolean(), buf.readBlockHitResult(), BLOCK_STATE_CODEC.decode(buf), ITEM_STACK_CODEC.decode(ProtocolUtils.decorate(buf)));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void write(FriendlyByteBuf buf) {
|
||||
+ public void write(@NotNull FriendlyByteBuf buf) {
|
||||
+ buf.writeBoolean(showDetails);
|
||||
+ buf.writeBlockHitResult(hitResult);
|
||||
+ BLOCK_STATE_CODEC.encode(buf, blockState);
|
||||
@@ -392,6 +482,48 @@ index 0000000000000000000000000000000000000000..33741d707715619929e5412a786470c5
|
||||
+ return PACKET_REQUEST_BLOCK;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public record ServerPingPayload(String serverConfig, List<Block> shearableBlocks) implements LeavesCustomPayload<ServerPingPayload> {
|
||||
+
|
||||
+ private static final ResourceLocation PACKET_SERVER_PING = JadeProtocol.id("server_ping_v1");
|
||||
+ private static final StreamCodec<RegistryFriendlyByteBuf, List<Block>> SHEARABLE_BLOCKS_CODEC = ByteBufCodecs.registry(Registries.BLOCK).apply(ByteBufCodecs.list());
|
||||
+
|
||||
+ @New
|
||||
+ public ServerPingPayload(ResourceLocation id, @NotNull FriendlyByteBuf buf) {
|
||||
+ this(buf.readUtf(), SHEARABLE_BLOCKS_CODEC.decode(ProtocolUtils.decorate(buf)));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void write(FriendlyByteBuf buf) {
|
||||
+ buf.writeUtf(serverConfig);
|
||||
+ SHEARABLE_BLOCKS_CODEC.encode(ProtocolUtils.decorate(buf), shearableBlocks);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ResourceLocation id() {
|
||||
+ return PACKET_SERVER_PING;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public record ReceiveDataPayload(CompoundTag tag) implements LeavesCustomPayload<ReceiveDataPayload> {
|
||||
+
|
||||
+ private static final ResourceLocation PACKET_RECEIVE_DATA = JadeProtocol.id("receive_data");
|
||||
+
|
||||
+ @New
|
||||
+ public ReceiveDataPayload(ResourceLocation id, FriendlyByteBuf buf) {
|
||||
+ this(buf.readNbt());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void write(@NotNull FriendlyByteBuf buf) {
|
||||
+ buf.writeNbt(tag);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ResourceLocation id() {
|
||||
+ return PACKET_RECEIVE_DATA;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/BlockAccessor.java b/src/main/java/org/leavesmc/leaves/protocol/jade/accessor/BlockAccessor.java
|
||||
new file mode 100644
|
||||
@@ -1565,6 +1697,151 @@ index 0000000000000000000000000000000000000000..d48ef5d8c72b57ff5525ab06b59724d0
|
||||
+ return MC_ZOMBIE_VILLAGER;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/tool/ShearsToolHandler.java b/src/main/java/org/leavesmc/leaves/protocol/jade/tool/ShearsToolHandler.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0e6f19a4cf55d952d8f20bf703635c8584a5f0bd
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/leavesmc/leaves/protocol/jade/tool/ShearsToolHandler.java
|
||||
@@ -0,0 +1,43 @@
|
||||
+package org.leavesmc.leaves.protocol.jade.tool;
|
||||
+
|
||||
+import com.google.common.collect.Sets;
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.world.item.ItemStack;
|
||||
+import net.minecraft.world.item.Items;
|
||||
+import net.minecraft.world.level.Level;
|
||||
+import net.minecraft.world.level.block.Block;
|
||||
+import net.minecraft.world.level.block.Blocks;
|
||||
+import net.minecraft.world.level.block.state.BlockState;
|
||||
+import org.leavesmc.leaves.protocol.jade.JadeProtocol;
|
||||
+
|
||||
+import java.util.Collection;
|
||||
+import java.util.List;
|
||||
+import java.util.Set;
|
||||
+
|
||||
+public class ShearsToolHandler extends SimpleToolHandler {
|
||||
+
|
||||
+ private static final ShearsToolHandler INSTANCE = new ShearsToolHandler();
|
||||
+
|
||||
+ public static ShearsToolHandler getInstance() {
|
||||
+ return INSTANCE;
|
||||
+ }
|
||||
+
|
||||
+ private final Set<Block> shearableBlocks = Sets.newIdentityHashSet();
|
||||
+
|
||||
+ public ShearsToolHandler() {
|
||||
+ super(JadeProtocol.id("shears"), List.of(Items.SHEARS.getDefaultInstance()), true);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ItemStack test(BlockState state, Level world, BlockPos pos) {
|
||||
+ if (state.is(Blocks.TRIPWIRE) || shearableBlocks.contains(state.getBlock())) {
|
||||
+ return tools.getFirst();
|
||||
+ }
|
||||
+ return super.test(state, world, pos);
|
||||
+ }
|
||||
+
|
||||
+ public void setShearableBlocks(Collection<Block> blocks) {
|
||||
+ shearableBlocks.clear();
|
||||
+ shearableBlocks.addAll(blocks);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/tool/SimpleToolHandler.java b/src/main/java/org/leavesmc/leaves/protocol/jade/tool/SimpleToolHandler.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..22fee6ecc49bbda94a7d32ee9dcf2a9ee661904b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/leavesmc/leaves/protocol/jade/tool/SimpleToolHandler.java
|
||||
@@ -0,0 +1,67 @@
|
||||
+package org.leavesmc.leaves.protocol.jade.tool;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import com.google.common.collect.Lists;
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.core.component.DataComponents;
|
||||
+import net.minecraft.resources.ResourceLocation;
|
||||
+import net.minecraft.world.item.Item;
|
||||
+import net.minecraft.world.item.ItemStack;
|
||||
+import net.minecraft.world.item.component.Tool;
|
||||
+import net.minecraft.world.level.Level;
|
||||
+import net.minecraft.world.level.block.state.BlockState;
|
||||
+
|
||||
+import java.util.List;
|
||||
+
|
||||
+public class SimpleToolHandler implements ToolHandler {
|
||||
+
|
||||
+ protected final List<ItemStack> tools = Lists.newArrayList();
|
||||
+ private final ResourceLocation uid;
|
||||
+ private final boolean skipInstaBreakingBlock;
|
||||
+
|
||||
+ protected SimpleToolHandler(ResourceLocation uid, List<ItemStack> tools, boolean skipInstaBreakingBlock) {
|
||||
+ this.uid = uid;
|
||||
+ Preconditions.checkArgument(!tools.isEmpty(), "tools cannot be empty");
|
||||
+ this.tools.addAll(tools);
|
||||
+ this.skipInstaBreakingBlock = skipInstaBreakingBlock;
|
||||
+ }
|
||||
+
|
||||
+ public static SimpleToolHandler create(ResourceLocation uid, List<Item> tools) {
|
||||
+ return create(uid, tools, true);
|
||||
+ }
|
||||
+
|
||||
+ public static SimpleToolHandler create(ResourceLocation uid, List<Item> tools, boolean skipInstaBreakingBlock) {
|
||||
+ return new SimpleToolHandler(uid, Lists.transform(tools, Item::getDefaultInstance), skipInstaBreakingBlock);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ItemStack test(BlockState state, Level world, BlockPos pos) {
|
||||
+ if (skipInstaBreakingBlock && !state.requiresCorrectToolForDrops() && state.getDestroySpeed(world, pos) == 0) {
|
||||
+ return ItemStack.EMPTY;
|
||||
+ }
|
||||
+ return test(state);
|
||||
+ }
|
||||
+
|
||||
+ public ItemStack test(BlockState state) {
|
||||
+ for (ItemStack toolItem : tools) {
|
||||
+ if (toolItem.isCorrectToolForDrops(state)) {
|
||||
+ return toolItem;
|
||||
+ }
|
||||
+ Tool tool = toolItem.get(DataComponents.TOOL);
|
||||
+ if (tool != null && tool.getMiningSpeed(state) > tool.defaultMiningSpeed()) {
|
||||
+ return toolItem;
|
||||
+ }
|
||||
+ }
|
||||
+ return ItemStack.EMPTY;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public List<ItemStack> getTools() {
|
||||
+ return tools;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ResourceLocation getUid() {
|
||||
+ return uid;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/tool/ToolHandler.java b/src/main/java/org/leavesmc/leaves/protocol/jade/tool/ToolHandler.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..18f11e701189ce3615e08c631e31112d53ea5686
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/leavesmc/leaves/protocol/jade/tool/ToolHandler.java
|
||||
@@ -0,0 +1,17 @@
|
||||
+package org.leavesmc.leaves.protocol.jade.tool;
|
||||
+
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.world.item.ItemStack;
|
||||
+import net.minecraft.world.level.Level;
|
||||
+import net.minecraft.world.level.block.state.BlockState;
|
||||
+import org.leavesmc.leaves.protocol.jade.provider.IJadeProvider;
|
||||
+
|
||||
+import java.util.List;
|
||||
+
|
||||
+public interface ToolHandler extends IJadeProvider {
|
||||
+
|
||||
+ ItemStack test(BlockState state, Level world, BlockPos pos);
|
||||
+
|
||||
+ List<ItemStack> getTools();
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/util/HierarchyLookup.java b/src/main/java/org/leavesmc/leaves/protocol/jade/util/HierarchyLookup.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..9e88dc87bd4a86c15b2b0d11ac4b095174b1c3d3
|
||||
@@ -1962,6 +2239,116 @@ index 0000000000000000000000000000000000000000..4d65e9a8b5224bd268b1bf18bc39a58d
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/util/LootTableMineableCollector.java b/src/main/java/org/leavesmc/leaves/protocol/jade/util/LootTableMineableCollector.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c811f89295964b1cb86c3eea39cd20f979ebceb9
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/leavesmc/leaves/protocol/jade/util/LootTableMineableCollector.java
|
||||
@@ -0,0 +1,104 @@
|
||||
+package org.leavesmc.leaves.protocol.jade.util;
|
||||
+
|
||||
+import com.google.common.collect.Lists;
|
||||
+import net.minecraft.advancements.critereon.ItemPredicate;
|
||||
+import net.minecraft.core.Registry;
|
||||
+import net.minecraft.core.registries.BuiltInRegistries;
|
||||
+import net.minecraft.world.item.ItemStack;
|
||||
+import net.minecraft.world.level.block.Block;
|
||||
+import net.minecraft.world.level.storage.loot.LootPool;
|
||||
+import net.minecraft.world.level.storage.loot.LootTable;
|
||||
+import net.minecraft.world.level.storage.loot.entries.AlternativesEntry;
|
||||
+import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer;
|
||||
+import net.minecraft.world.level.storage.loot.entries.NestedLootTable;
|
||||
+import net.minecraft.world.level.storage.loot.predicates.AnyOfCondition;
|
||||
+import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
|
||||
+import net.minecraft.world.level.storage.loot.predicates.MatchTool;
|
||||
+import org.leavesmc.leaves.protocol.jade.tool.ShearsToolHandler;
|
||||
+
|
||||
+import java.util.List;
|
||||
+import java.util.function.Function;
|
||||
+
|
||||
+public class LootTableMineableCollector {
|
||||
+
|
||||
+ private final Registry<LootTable> lootRegistry;
|
||||
+ private final ItemStack toolItem;
|
||||
+
|
||||
+ public LootTableMineableCollector(Registry<LootTable> lootRegistry, ItemStack toolItem) {
|
||||
+ this.lootRegistry = lootRegistry;
|
||||
+ this.toolItem = toolItem;
|
||||
+ }
|
||||
+
|
||||
+ public static List<Block> execute(Registry<LootTable> lootRegistry, ItemStack toolItem) {
|
||||
+ LootTableMineableCollector collector = new LootTableMineableCollector(lootRegistry, toolItem);
|
||||
+ List<Block> list = Lists.newArrayList();
|
||||
+ for (Block block : BuiltInRegistries.BLOCK) {
|
||||
+ if (!ShearsToolHandler.getInstance().test(block.defaultBlockState()).isEmpty()) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ LootTable lootTable = lootRegistry.get(block.getLootTable());
|
||||
+ if (collector.doLootTable(lootTable)) {
|
||||
+ list.add(block);
|
||||
+ }
|
||||
+ }
|
||||
+ return list;
|
||||
+ }
|
||||
+
|
||||
+ private boolean doLootTable(LootTable lootTable) {
|
||||
+ if (lootTable == null || lootTable == LootTable.EMPTY) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ for (LootPool pool : lootTable.pools) {
|
||||
+ if (doLootPool(pool)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ private boolean doLootPool(LootPool lootPool) {
|
||||
+ for (LootPoolEntryContainer entry : lootPool.entries) {
|
||||
+ if (doLootPoolEntry(entry)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ private boolean doLootPoolEntry(LootPoolEntryContainer entry) {
|
||||
+ if (entry instanceof AlternativesEntry alternativesEntry) {
|
||||
+ for (LootPoolEntryContainer child : alternativesEntry.children) {
|
||||
+ if (doLootPoolEntry(child)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ } else if (entry instanceof NestedLootTable nestedLootTable) {
|
||||
+ LootTable lootTable = nestedLootTable.contents.map(lootRegistry::get, Function.identity());
|
||||
+ return doLootTable(lootTable);
|
||||
+ } else {
|
||||
+ return isCorrectConditions(entry.conditions, toolItem);
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ public static boolean isCorrectConditions(List<LootItemCondition> conditions, ItemStack toolItem) {
|
||||
+ if (conditions.size() != 1) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ LootItemCondition condition = conditions.getFirst();
|
||||
+ if (condition instanceof MatchTool matchTool) {
|
||||
+ ItemPredicate itemPredicate = matchTool.predicate().orElse(null);
|
||||
+ return itemPredicate != null && itemPredicate.test(toolItem);
|
||||
+ } else if (condition instanceof AnyOfCondition anyOfCondition) {
|
||||
+ for (LootItemCondition child : anyOfCondition.terms) {
|
||||
+ if (isCorrectConditions(List.of(child), toolItem)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/util/PairHierarchyLookup.java b/src/main/java/org/leavesmc/leaves/protocol/jade/util/PairHierarchyLookup.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..580b299d9dc2514d9758c04caac39a82982c0ca1
|
||||
|
||||
Reference in New Issue
Block a user