- 7
- 1
- 1
Добрый день. Хочу добавить эффект, который позволил бы ходить по воде так же как и по твёрдому блоку. Пример такого поведения Лавомерка или Running Shoes из Artifacts. У меня в голове логика следующая:Я новичок в java, так что, если у вас горит сидалище, то объясните почему и где узнать столь очевидную инфу.
1. Отслеживаем, есть ли вода под игроком;
2. Выталкиваем игрока, если он ниже поверхности воды;
3. Поднимаем хитбокс игрока на 0.2, чтобы он не соприкосался с блоком воды, так как реально вода высотой 0.8, то я опускаю игрока на 0.2 ниже и из-за пересечения воды и хитбокса к игроку применяются эффекты (импульс и вязкость) будто бы я в воде.
Проблема в том, что хитбокс поднимается, но при любом движении становится стандартным и замедляет меня. Как жестко установить размер хитбокса или какую логику лучше использовать, чтобы достичь нужного эффекта?
Java:
public class WaterWalkEffect extends MobEffect {
public WaterWalkEffect(MobEffectCategory category, int color) {
super(category, color);
}
@Override
public boolean applyEffectTick(LivingEntity livingEntity, int amplifier) {
if (livingEntity instanceof Player player) {
Level level = player.level();
BlockPos belowPos = player.blockPosition();
Minecraft mc = Minecraft.getInstance();
boolean isOnWater = level.getBlockState(belowPos).is(Blocks.WATER)
&& level.getBlockState(belowPos.above()).isAir()
&& !player.isSwimming()
&& !player.isShiftKeyDown()
&& !mc.options.keyJump.isDown();
if (isOnWater) {
Vec3 velocity = player.getDeltaMovement();
double waterSurface = belowPos.getY() + 0.8;
if (player.getY() < waterSurface) {
player.setDeltaMovement(velocity.x, (waterSurface - player.getY()) * 0.2, velocity.z);
}
player.setOnGround(true);
AABB newBox = new AABB(
player.getX() - 0.3, player.getY() + 0.2, player.getZ() - 0.3, // Нижняя граница
player.getX() + 0.3, player.getY() + 1.8, player.getZ() + 0.3 // Верхняя граница
);
player.setBoundingBox(newBox);
return true;
}
}
return super.applyEffectTick(livingEntity, amplifier);
}
@Override
public boolean shouldApplyEffectTickThisTick(int duration, int amplifier) {
return true;
}
}