diff --git a/common/src/main/java/dev/dubhe/anvilcraft/api/chargecollector/ChargeCollectorManager.java b/common/src/main/java/dev/dubhe/anvilcraft/api/chargecollector/ChargeCollectorManager.java index 1f86b1571..a88607f50 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/api/chargecollector/ChargeCollectorManager.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/api/chargecollector/ChargeCollectorManager.java @@ -1,12 +1,13 @@ package dev.dubhe.anvilcraft.api.chargecollector; import dev.dubhe.anvilcraft.block.entity.ChargeCollectorBlockEntity; + import java.util.Collection; -import java.util.Comparator; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.stream.Collectors; + import net.minecraft.core.BlockPos; import org.joml.Vector3f; @@ -34,11 +35,29 @@ public static Collection> getNearestCha Map distanceMap = new HashMap<>(); for (Map.Entry entry : CHARGE_COLLECTOR_MAP.entrySet()) { float distance = Vector3f.distance( - entry.getKey().getX(), entry.getKey().getY(), entry.getKey().getZ(), - blockPos.getX(), blockPos.getY(), blockPos.getZ()); + entry.getKey().getX(), entry.getKey().getY(), entry.getKey().getZ(), + blockPos.getX(), blockPos.getY(), blockPos.getZ()); distanceMap.put(distance, entry.getValue()); } return distanceMap.entrySet().stream() - .sorted(Comparator.comparing(Entry::getKey)).collect(Collectors.toList()); + .sorted(Entry.comparingByKey()).collect(Collectors.toList()); + } + + /** + * 判断是否能被集电器收集 + * + * @param blockEntity 集电器方块实体 + * @param blockPos 电荷的位置 + * @return 是否能被集点器收集 + */ + public static boolean canCollect(ChargeCollectorBlockEntity blockEntity, BlockPos blockPos) { + System.out.println(blockEntity.getPos()); + System.out.println(blockPos); + return blockEntity.getPos().getX() - 2 <= blockPos.getX() + && blockEntity.getPos().getY() - 2 <= blockPos.getY() + && blockEntity.getPos().getZ() - 2 <= blockPos.getZ() + && blockEntity.getPos().getX() + 2 >= blockPos.getX() + && blockEntity.getPos().getY() + 2 >= blockPos.getY() + && blockEntity.getPos().getZ() + 2 >= blockPos.getZ(); } } diff --git a/common/src/main/java/dev/dubhe/anvilcraft/block/PiezoelectricCrystalBlock.java b/common/src/main/java/dev/dubhe/anvilcraft/block/PiezoelectricCrystalBlock.java index 32f60055a..6decac650 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/block/PiezoelectricCrystalBlock.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/block/PiezoelectricCrystalBlock.java @@ -3,10 +3,12 @@ import dev.dubhe.anvilcraft.api.chargecollector.ChargeCollectorManager; import dev.dubhe.anvilcraft.api.hammer.IHammerRemovable; import dev.dubhe.anvilcraft.block.entity.ChargeCollectorBlockEntity; + import java.util.Collection; import java.util.Iterator; import java.util.Map.Entry; import javax.annotation.Nonnull; + import net.minecraft.core.BlockPos; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.block.Block; @@ -53,16 +55,10 @@ public void onHitByAnvil(float fallDistance, BlockPos blockPos) { .getNearestChargeCollect(blockPos); Iterator> iterator = chargeCollectorCollection.iterator(); int surplus = chargeNum; - for (int i = 0; i < chargeCollectorCollection.size(); i++) { - ChargeCollectorBlockEntity chargeCollectorBlockEntity = iterator.next().getValue(); - int x = chargeCollectorBlockEntity.getPos().getX(); - int y = chargeCollectorBlockEntity.getPos().getY(); - int z = chargeCollectorBlockEntity.getPos().getZ(); - if (((x - 2) > blockPos.getX() || (x + 2) < blockPos.getX()) - || ((y - 2) > blockPos.getY() || (y + 2) < blockPos.getY()) - || ((z - 2) > blockPos.getZ() || (z + 2) < blockPos.getZ())) { - return; - } + while (iterator.hasNext()) { + Entry entry = iterator.next(); + ChargeCollectorBlockEntity chargeCollectorBlockEntity = entry.getValue(); + if (!ChargeCollectorManager.canCollect(chargeCollectorBlockEntity, blockPos)) return; surplus = chargeCollectorBlockEntity.incomingCharge(surplus); if (surplus == 0) return; } diff --git a/common/src/main/java/dev/dubhe/anvilcraft/event/LightningEventListener.java b/common/src/main/java/dev/dubhe/anvilcraft/event/LightningEventListener.java index 576113573..19364c553 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/event/LightningEventListener.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/event/LightningEventListener.java @@ -1,14 +1,19 @@ package dev.dubhe.anvilcraft.event; import dev.dubhe.anvilcraft.AnvilCraft; +import dev.dubhe.anvilcraft.api.chargecollector.ChargeCollectorManager; import dev.dubhe.anvilcraft.api.event.SubscribeEvent; import dev.dubhe.anvilcraft.api.event.entity.LightningStrikeEvent; +import dev.dubhe.anvilcraft.block.entity.ChargeCollectorBlockEntity; import dev.dubhe.anvilcraft.init.ModBlocks; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.NotNull; +import java.util.Collection; +import java.util.Map; + public class LightningEventListener { /** * 侦听雷击事件 @@ -19,6 +24,7 @@ public class LightningEventListener { public void onLightingStrike(@NotNull LightningStrikeEvent event) { BlockPos pos = event.getPos(); BlockState state = event.getLevel().getBlockState(pos); + lightningCharge(pos, state); if (state.is(Blocks.LIGHTNING_ROD)) pos = pos.below(); int depth = AnvilCraft.config.lightningStrikeDepth; int radius = AnvilCraft.config.lightningStrikeRadius; @@ -38,4 +44,19 @@ public void onLightingStrike(@NotNull LightningStrikeEvent event) { } } } + + private void lightningCharge(BlockPos pos, BlockState state) { + if (state.is(Blocks.COPPER_BLOCK) || state.is(Blocks.LIGHTNING_ROD)) { + int unCharged = 16; + Collection> nearestChargeCollect = + ChargeCollectorManager.getNearestChargeCollect(pos); + for (var floatChargeCollectorBlockEntityEntry : nearestChargeCollect) { + ChargeCollectorBlockEntity blockEntity = floatChargeCollectorBlockEntityEntry.getValue(); + if (ChargeCollectorManager.canCollect(blockEntity, pos)) { + unCharged = blockEntity.incomingCharge(unCharged); + if (unCharged <= 0) break; + } + } + } + } } diff --git a/common/src/main/java/dev/dubhe/anvilcraft/event/PistonMoveBlockListener.java b/common/src/main/java/dev/dubhe/anvilcraft/event/PistonMoveBlockListener.java new file mode 100644 index 000000000..e8b14a64b --- /dev/null +++ b/common/src/main/java/dev/dubhe/anvilcraft/event/PistonMoveBlockListener.java @@ -0,0 +1,48 @@ +package dev.dubhe.anvilcraft.event; + +import dev.dubhe.anvilcraft.api.chargecollector.ChargeCollectorManager; +import dev.dubhe.anvilcraft.block.entity.ChargeCollectorBlockEntity; +import dev.dubhe.anvilcraft.init.ModBlocks; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +public class PistonMoveBlockListener { + public static void onPistonMoveBlocks(Level level, List blocks) { + RandomSource random = level.random; + for (BlockPos pos : blocks) { + if (!level.getBlockState(pos).is(ModBlocks.MAGNET_BLOCK.get())) continue; + boolean b = isNearbyCopperBlock(level, pos); + double r = random.nextDouble(); + if (b && r < 0.25) { + Collection> nearestChargeCollect = + ChargeCollectorManager.getNearestChargeCollect(pos); + for (var floatChargeCollectorBlockEntityEntry : nearestChargeCollect) { + ChargeCollectorBlockEntity blockEntity = floatChargeCollectorBlockEntityEntry.getValue(); + if (ChargeCollectorManager.canCollect(blockEntity, pos)) { + int unCharged = blockEntity.incomingCharge(1); + if (unCharged == 0) { + break; + } + + } + } + } + } + } + + private static boolean isNearbyCopperBlock(Level level, BlockPos pos) { + for (Direction face : Direction.values()) { + if (level.getBlockState(pos.relative(face)).is(Blocks.COPPER_BLOCK)) { + return true; + } + } + return false; + } +} diff --git a/common/src/main/java/dev/dubhe/anvilcraft/mixin/PistonStructureResolverMixin.java b/common/src/main/java/dev/dubhe/anvilcraft/mixin/PistonStructureResolverMixin.java new file mode 100644 index 000000000..d52711375 --- /dev/null +++ b/common/src/main/java/dev/dubhe/anvilcraft/mixin/PistonStructureResolverMixin.java @@ -0,0 +1,32 @@ +package dev.dubhe.anvilcraft.mixin; + +import dev.dubhe.anvilcraft.event.PistonMoveBlockListener; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.piston.PistonStructureResolver; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.ArrayList; +import java.util.List; + +@Mixin(PistonStructureResolver.class) +public class PistonStructureResolverMixin { + @Shadow @Final private List toPush; + + @Shadow @Final private Level level; + + @Inject(method = "resolve", at = @At("RETURN")) + private void onPistonResolve(CallbackInfoReturnable cir) { + if (level.isClientSide()) { + return; + } + if (!cir.getReturnValue()) return; + List toPushBlocks = new ArrayList<>(toPush); + PistonMoveBlockListener.onPistonMoveBlocks(level, toPushBlocks); + } +} diff --git a/common/src/main/resources/anvilcraft-common.mixins.json b/common/src/main/resources/anvilcraft-common.mixins.json index 24b7d2c2a..cd68b514a 100644 --- a/common/src/main/resources/anvilcraft-common.mixins.json +++ b/common/src/main/resources/anvilcraft-common.mixins.json @@ -18,6 +18,7 @@ "HoeItemMixin", "ItemEntityMixin", "LivingEntityMixin", + "PistonStructureResolverMixin", "PlayerHitEntityMixin", "SolidBucketItemMixin", "accessor.BaseSpawnerAccessor", @@ -32,5 +33,5 @@ ], "injectors": { "defaultRequire": 1 - } + } }