250 lines
9.5 KiB
Java
250 lines
9.5 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*
|
|
* Could not load the following classes:
|
|
* org.jspecify.annotations.Nullable
|
|
*/
|
|
package net.minecraft.world.entity.projectile;
|
|
|
|
import java.util.UUID;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.SectionPos;
|
|
import net.minecraft.core.particles.ParticleTypes;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
import net.minecraft.sounds.SoundEvents;
|
|
import net.minecraft.sounds.SoundSource;
|
|
import net.minecraft.world.entity.Entity;
|
|
import net.minecraft.world.entity.EntityReference;
|
|
import net.minecraft.world.entity.EntitySpawnReason;
|
|
import net.minecraft.world.entity.EntityType;
|
|
import net.minecraft.world.entity.LivingEntity;
|
|
import net.minecraft.world.entity.Relative;
|
|
import net.minecraft.world.entity.monster.Endermite;
|
|
import net.minecraft.world.entity.projectile.ThrowableItemProjectile;
|
|
import net.minecraft.world.item.Item;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.item.Items;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.level.block.Blocks;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.level.gamerules.GameRules;
|
|
import net.minecraft.world.level.portal.TeleportTransition;
|
|
import net.minecraft.world.phys.EntityHitResult;
|
|
import net.minecraft.world.phys.HitResult;
|
|
import net.minecraft.world.phys.Vec3;
|
|
import org.jspecify.annotations.Nullable;
|
|
|
|
public class ThrownEnderpearl
|
|
extends ThrowableItemProjectile {
|
|
private long ticketTimer = 0L;
|
|
|
|
public ThrownEnderpearl(EntityType<? extends ThrownEnderpearl> type, Level level) {
|
|
super((EntityType<? extends ThrowableItemProjectile>)type, level);
|
|
}
|
|
|
|
public ThrownEnderpearl(Level level, LivingEntity mob, ItemStack itemStack) {
|
|
super(EntityType.ENDER_PEARL, mob, level, itemStack);
|
|
}
|
|
|
|
@Override
|
|
protected Item getDefaultItem() {
|
|
return Items.ENDER_PEARL;
|
|
}
|
|
|
|
@Override
|
|
protected void setOwner(@Nullable EntityReference<Entity> owner) {
|
|
this.deregisterFromCurrentOwner();
|
|
super.setOwner(owner);
|
|
this.registerToCurrentOwner();
|
|
}
|
|
|
|
private void deregisterFromCurrentOwner() {
|
|
Entity entity = this.getOwner();
|
|
if (entity instanceof ServerPlayer) {
|
|
ServerPlayer serverPlayer = (ServerPlayer)entity;
|
|
serverPlayer.deregisterEnderPearl(this);
|
|
}
|
|
}
|
|
|
|
private void registerToCurrentOwner() {
|
|
Entity entity = this.getOwner();
|
|
if (entity instanceof ServerPlayer) {
|
|
ServerPlayer serverPlayer = (ServerPlayer)entity;
|
|
serverPlayer.registerEnderPearl(this);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public @Nullable Entity getOwner() {
|
|
Level level;
|
|
if (this.owner == null || !((level = this.level()) instanceof ServerLevel)) {
|
|
return super.getOwner();
|
|
}
|
|
ServerLevel serverLevel = (ServerLevel)level;
|
|
return this.owner.getEntity(serverLevel, Entity.class);
|
|
}
|
|
|
|
private static @Nullable Entity findOwnerIncludingDeadPlayer(ServerLevel serverLevel, UUID uuid) {
|
|
Entity owner = serverLevel.getEntityInAnyDimension(uuid);
|
|
if (owner != null) {
|
|
return owner;
|
|
}
|
|
return serverLevel.getServer().getPlayerList().getPlayer(uuid);
|
|
}
|
|
|
|
@Override
|
|
protected void onHitEntity(EntityHitResult hitResult) {
|
|
super.onHitEntity(hitResult);
|
|
hitResult.getEntity().hurt(this.damageSources().thrown(this, this.getOwner()), 0.0f);
|
|
}
|
|
|
|
@Override
|
|
protected void onHit(HitResult hitResult) {
|
|
ServerLevel level;
|
|
block14: {
|
|
block13: {
|
|
super.onHit(hitResult);
|
|
for (int i = 0; i < 32; ++i) {
|
|
this.level().addParticle(ParticleTypes.PORTAL, this.getX(), this.getY() + this.random.nextDouble() * 2.0, this.getZ(), this.random.nextGaussian(), 0.0, this.random.nextGaussian());
|
|
}
|
|
Level level2 = this.level();
|
|
if (!(level2 instanceof ServerLevel)) break block13;
|
|
level = (ServerLevel)level2;
|
|
if (!this.isRemoved()) break block14;
|
|
}
|
|
return;
|
|
}
|
|
Entity owner = this.getOwner();
|
|
if (owner == null || !ThrownEnderpearl.isAllowedToTeleportOwner(owner, level)) {
|
|
this.discard();
|
|
return;
|
|
}
|
|
Vec3 teleportPos = this.oldPosition();
|
|
if (owner instanceof ServerPlayer) {
|
|
ServerPlayer player = (ServerPlayer)owner;
|
|
if (player.connection.isAcceptingMessages()) {
|
|
ServerPlayer newOwner;
|
|
Endermite endermite;
|
|
if (this.random.nextFloat() < 0.05f && level.isSpawningMonsters() && (endermite = EntityType.ENDERMITE.create(level, EntitySpawnReason.TRIGGERED)) != null) {
|
|
endermite.snapTo(owner.getX(), owner.getY(), owner.getZ(), owner.getYRot(), owner.getXRot());
|
|
level.addFreshEntity(endermite);
|
|
}
|
|
if (this.isOnPortalCooldown()) {
|
|
owner.setPortalCooldown();
|
|
}
|
|
if ((newOwner = player.teleport(new TeleportTransition(level, teleportPos, Vec3.ZERO, 0.0f, 0.0f, Relative.union(Relative.ROTATION, Relative.DELTA), TeleportTransition.DO_NOTHING))) != null) {
|
|
newOwner.resetFallDistance();
|
|
newOwner.resetCurrentImpulseContext();
|
|
newOwner.hurtServer(player.level(), this.damageSources().enderPearl(), 5.0f);
|
|
}
|
|
this.playSound(level, teleportPos);
|
|
}
|
|
} else {
|
|
Entity newOwner = owner.teleport(new TeleportTransition(level, teleportPos, owner.getDeltaMovement(), owner.getYRot(), owner.getXRot(), TeleportTransition.DO_NOTHING));
|
|
if (newOwner != null) {
|
|
newOwner.resetFallDistance();
|
|
}
|
|
this.playSound(level, teleportPos);
|
|
}
|
|
this.discard();
|
|
}
|
|
|
|
private static boolean isAllowedToTeleportOwner(Entity owner, Level newLevel) {
|
|
if (owner.level().dimension() == newLevel.dimension()) {
|
|
if (owner instanceof LivingEntity) {
|
|
LivingEntity livingOwner = (LivingEntity)owner;
|
|
return livingOwner.isAlive() && !livingOwner.isSleeping();
|
|
}
|
|
return owner.isAlive();
|
|
}
|
|
return owner.canUsePortal(true);
|
|
}
|
|
|
|
/*
|
|
* Unable to fully structure code
|
|
*/
|
|
@Override
|
|
public void tick() {
|
|
var2_1 = this.level();
|
|
if (!(var2_1 instanceof ServerLevel)) {
|
|
super.tick();
|
|
return;
|
|
}
|
|
serverLevel = (ServerLevel)var2_1;
|
|
previousChunkX = SectionPos.blockToSectionCoord(this.position().x());
|
|
previousChunkZ = SectionPos.blockToSectionCoord(this.position().z());
|
|
v0 = owner = this.owner != null ? ThrownEnderpearl.findOwnerIncludingDeadPlayer(serverLevel, this.owner.getUUID()) : null;
|
|
if (!(owner instanceof ServerPlayer)) ** GOTO lbl-1000
|
|
serverPlayer = (ServerPlayer)owner;
|
|
if (!owner.isAlive() && !serverPlayer.wonGame && serverPlayer.level().getGameRules().get(GameRules.ENDER_PEARLS_VANISH_ON_DEATH).booleanValue()) {
|
|
this.discard();
|
|
} else lbl-1000:
|
|
// 2 sources
|
|
|
|
{
|
|
super.tick();
|
|
}
|
|
if (!this.isAlive()) {
|
|
return;
|
|
}
|
|
currentPos = BlockPos.containing(this.position());
|
|
if ((--this.ticketTimer <= 0L || previousChunkX != SectionPos.blockToSectionCoord(currentPos.getX()) || previousChunkZ != SectionPos.blockToSectionCoord(currentPos.getZ())) && owner instanceof ServerPlayer) {
|
|
serverPlayer = (ServerPlayer)owner;
|
|
this.ticketTimer = serverPlayer.registerAndUpdateEnderPearlTicket(this);
|
|
}
|
|
}
|
|
|
|
private void playSound(Level level, Vec3 position) {
|
|
level.playSound(null, position.x, position.y, position.z, SoundEvents.PLAYER_TELEPORT, SoundSource.PLAYERS);
|
|
}
|
|
|
|
@Override
|
|
public @Nullable Entity teleport(TeleportTransition transition) {
|
|
Entity newEntity = super.teleport(transition);
|
|
if (newEntity != null) {
|
|
newEntity.placePortalTicket(BlockPos.containing(newEntity.position()));
|
|
}
|
|
return newEntity;
|
|
}
|
|
|
|
@Override
|
|
public boolean canTeleport(Level from, Level to) {
|
|
Entity entity;
|
|
if (from.dimension() == Level.END && to.dimension() == Level.OVERWORLD && (entity = this.getOwner()) instanceof ServerPlayer) {
|
|
ServerPlayer player = (ServerPlayer)entity;
|
|
return super.canTeleport(from, to) && player.seenCredits;
|
|
}
|
|
return super.canTeleport(from, to);
|
|
}
|
|
|
|
@Override
|
|
protected void onInsideBlock(BlockState state) {
|
|
Entity entity;
|
|
super.onInsideBlock(state);
|
|
if (state.is(Blocks.END_GATEWAY) && (entity = this.getOwner()) instanceof ServerPlayer) {
|
|
ServerPlayer player = (ServerPlayer)entity;
|
|
player.onInsideBlock(state);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onRemoval(Entity.RemovalReason reason) {
|
|
if (reason != Entity.RemovalReason.UNLOADED_WITH_PLAYER) {
|
|
this.deregisterFromCurrentOwner();
|
|
}
|
|
super.onRemoval(reason);
|
|
}
|
|
|
|
@Override
|
|
public void onAboveBubbleColumn(boolean dragDown, BlockPos pos) {
|
|
Entity.handleOnAboveBubbleColumn(this, dragDown, pos);
|
|
}
|
|
|
|
@Override
|
|
public void onInsideBubbleColumn(boolean dragDown) {
|
|
Entity.handleOnInsideBubbleColumn(this, dragDown);
|
|
}
|
|
}
|
|
|