Flandre923
704 words
4 minutes
23 海之嫌弃

23 海之嫌弃#

package com.mafuyu33.neomafishmod.mixin.enchantmentblockmixin.custom.badluckofsea;

// 使用 Mixin 注解,将这个类混入 FlowingFluid 类
@Mixin(FlowingFluid.class)
public abstract class FlowableFluidMixin {

    // 注入 canPassThroughWall 方法的头部,并使用 cancellable = true 使得该方法可被取消
    @Inject(at = @At("HEAD"), method = "canPassThroughWall", cancellable = true)
    private void init1(Direction face, BlockGetter world, BlockPos pos, BlockState state, BlockPos fromPos, BlockState fromState, CallbackInfoReturnable<Boolean> cir) {
        // 获取位置 pos 的 BAD_LUCK_OF_SEA 附魔等级
        int k = BlockEnchantmentStorage.getLevel(ModEnchantments.BAD_LUCK_OF_SEA,pos);
        if(k>0){
            System.out.println("receivesFlow");
            // 如果 world 是 Level 类型
            if (world instanceof Level mutableWorld) {
                // 调用 mafishmod$generateFallingBlock 方法生成掉落方块
                mafishmod$generateFallingBlock(pos,state,mutableWorld);
            }
            // 设置返回值为 true
            cir.setReturnValue(true);
        }
    }

    // 使用 @Unique 注解标记该方法为私有方法
    @Unique
    private void mafishmod$generateFallingBlock(BlockPos targetPos , BlockState blockState, Level world) {
        if(!world.isClientSide()) {
            // 获取目标位置的 BlockEntity
            BlockEntity blockEntity = world.getBlockEntity(targetPos);

            // 如果目标位置有附加的附魔信息
            if (!Objects.equals(BlockEnchantmentStorage.getEnchantmentsAtPosition(targetPos), new ListTag())) {
                // 删除附魔信息
                BlockEnchantmentStorage.removeBlockEnchantment(targetPos.immutable());
            }

            // 创建一个新的 FallingBlockEntity
            FallingBlockEntity fallingBlockEntity = new FallingBlockEntity(EntityType.FALLING_BLOCK, world);

            // 设置掉落方块的状态、时间、重力、建筑标志位、位置和速度
            fallingBlockEntity.blockState = blockState;
            fallingBlockEntity.time = 1;
            fallingBlockEntity.setNoGravity(false);
            fallingBlockEntity.blocksBuilding = true;
            fallingBlockEntity.setPos(targetPos.getX() + 0.5, targetPos.getY(), targetPos.getZ() + 0.5);
            fallingBlockEntity.setDeltaMovement(0, 0.2, 0);
            fallingBlockEntity.xOld = targetPos.getX() + 0.5;
            fallingBlockEntity.yOld = targetPos.getY();
            fallingBlockEntity.zOld = targetPos.getZ() + 0.5;
            fallingBlockEntity.setStartPos(targetPos);
            // 设置伤害
            fallingBlockEntity.setHurtsEntities(0, -1);

            // 如果原始方块有 BlockEntity 数据
            if (blockEntity != null) {
                CompoundTag blockEntityData = new CompoundTag();
                // 保存附加数据到 blockEntityData
                ((EntityBlockAccessor) blockEntity).saveAdditional(blockEntityData,world.registryAccess());
                fallingBlockEntity.blockData = blockEntityData;
            }

            // 将目标位置设置为空气
            world.setBlock(targetPos, Blocks.AIR.defaultBlockState(), 3);

            // 将掉落方块实体添加到世界中
            world.addFreshEntity(fallingBlockEntity);
        }
    }
}

这个类的作用主要是生成fallingBlockEntity实体.

package com.mafuyu33.neomafishmod.mixin.enchantmentblockmixin.custom.badluckofsea;

// 使用 Mixin 注解将这个类混入 FallingBlockEntity 类
@Mixin(FallingBlockEntity.class)
public abstract class FallingBlockEntityMixin extends Entity {

    // 获取 FallingBlockEntity 的 fallDamageMax 字段
    @Shadow private int fallDamageMax;

    public FallingBlockEntityMixin(EntityType<?> entityType, Level level) {
        super(entityType, level);
    }

    // 注入 tick 方法的头部
    @Inject(at = @At("HEAD"), method = "tick")
    private void init(CallbackInfo info){
        Level level = this.level();
        BlockPos blockPos = this.blockPosition();
        FluidState fluidState = level.getFluidState(blockPos);
        // 如果当前位置是水源方块,并且 fallDamageMax 为 40
        if (fluidState.is(FluidTags.WATER) && this.fallDamageMax==40){
            BlockPos closestNonLiquidBlockPos = null;
            double closestDistanceSq = Double.MAX_VALUE;

            // 在一定范围内寻找最近的非液体方块
            for (int xOffset=-20;xOffset<=19;xOffset++){
                for(int zOffset=-20;zOffset<=19;zOffset++){
                    BlockPos currentPos = blockPos.offset(xOffset,0,zOffset);
                    FluidState fluidState1 = level.getFluidState(currentPos);

                    if (!fluidState1.is(FluidTags.WATER)){
                        double distanceSq = this.distanceToSqr(Vec3.atCenterOf(currentPos));
                        if (distanceSq < closestDistanceSq){
                            closestDistanceSq = distanceSq;
                            closestNonLiquidBlockPos = currentPos;
                        }
                    }
                }
            }

            // 如果找到了最近的非液体方块
            if (closestNonLiquidBlockPos != null){
                Vec3 direction = Vec3.atCenterOf(closestNonLiquidBlockPos).subtract(this.position()).normalize();
                double speed = 0.15;

                Vec3 velocity = direction.scale(speed);
                // 添加向上和水平方向的速度
                this.addDeltaMovement(new Vec3(0,0.3,0));
                this.addDeltaMovement(velocity);

            }else{
                // 如果没有找到非液体方块,只添加向上的速度
                this.addDeltaMovement(new Vec3(0,0.3,0));
            }
        }
    }

    // 注入 tick 方法的指定位置
    @Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z"))
    public void init1(CallbackInfo info, @Local BlockPos blockPos){
        // 如果 fallDamageMax 为 40
        if (this.fallDamageMax == 40){
            ResourceKey<Enchantment> enchantment = ModEnchantments.BAD_LUCK_OF_SEA;
            ListTag enchantmentNbtList = new ListTag();

            CompoundTag enchantmentNbt = new CompoundTag();
            enchantmentNbt.putString("id",String.valueOf(enchantment));
            enchantmentNbt.putInt("lvl",3);

            enchantmentNbtList.add(enchantmentNbt);
            // 为该位置添加 BAD_LUCK_OF_SEA 附魔
            BlockEnchantmentStorage.addBlockEnchantment(blockPos.immutable(),enchantmentNbtList);
        }
    }
}

该类的主要作用就是移动FallingBlockEntity实体,朝着搜索到的非流体方块位置移动,如果找不到就在原地跳跃.

23 海之嫌弃
https://fuwari.vercel.app/posts/minecraft1_21_0/23_海之嫌弃/
Author
Flandre923
Published at
2024-08-24