minecraft-src/net/minecraft/world/item/consume_effects/TeleportRandomlyConsumeEffect.java
2025-07-04 03:45:38 +03:00

85 lines
3.1 KiB
Java

package net.minecraft.world.item.consume_effects;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.animal.Fox;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.consume_effects.ConsumeEffect.Type;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.gameevent.GameEvent.Context;
import net.minecraft.world.phys.Vec3;
public record TeleportRandomlyConsumeEffect(float diameter) implements ConsumeEffect {
private static final float DEFAULT_DIAMETER = 16.0F;
public static final MapCodec<TeleportRandomlyConsumeEffect> CODEC = RecordCodecBuilder.mapCodec(
instance -> instance.group(ExtraCodecs.POSITIVE_FLOAT.optionalFieldOf("diameter", 16.0F).forGetter(TeleportRandomlyConsumeEffect::diameter))
.apply(instance, TeleportRandomlyConsumeEffect::new)
);
public static final StreamCodec<RegistryFriendlyByteBuf, TeleportRandomlyConsumeEffect> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.FLOAT, TeleportRandomlyConsumeEffect::diameter, TeleportRandomlyConsumeEffect::new
);
public TeleportRandomlyConsumeEffect() {
this(16.0F);
}
@Override
public Type<TeleportRandomlyConsumeEffect> getType() {
return Type.TELEPORT_RANDOMLY;
}
@Override
public boolean apply(Level level, ItemStack stack, LivingEntity entity) {
boolean bl = false;
for (int i = 0; i < 16; i++) {
double d = entity.getX() + (entity.getRandom().nextDouble() - 0.5) * this.diameter;
double e = Mth.clamp(
entity.getY() + (entity.getRandom().nextDouble() - 0.5) * this.diameter,
(double)level.getMinY(),
(double)(level.getMinY() + ((ServerLevel)level).getLogicalHeight() - 1)
);
double f = entity.getZ() + (entity.getRandom().nextDouble() - 0.5) * this.diameter;
if (entity.isPassenger()) {
entity.stopRiding();
}
Vec3 vec3 = entity.position();
if (entity.randomTeleport(d, e, f, true)) {
level.gameEvent(GameEvent.TELEPORT, vec3, Context.of(entity));
SoundSource soundSource;
SoundEvent soundEvent;
if (entity instanceof Fox) {
soundEvent = SoundEvents.FOX_TELEPORT;
soundSource = SoundSource.NEUTRAL;
} else {
soundEvent = SoundEvents.CHORUS_FRUIT_TELEPORT;
soundSource = SoundSource.PLAYERS;
}
level.playSound(null, entity.getX(), entity.getY(), entity.getZ(), soundEvent, soundSource);
entity.resetFallDistance();
bl = true;
break;
}
}
if (bl && entity instanceof Player player) {
player.resetCurrentImpulseContext();
}
return bl;
}
}