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实体,朝着搜索到的非流体方块位置移动,如果找不到就在原地跳跃.