minecraft-source/src/net/minecraft/world/entity/ExperienceOrb.java

258 lines
8.3 KiB
Java

package net.minecraft.world.entity;
import net.minecraft.network.protocol.game.ClientboundAddExperienceOrbPacket;
import net.minecraft.network.protocol.Packet;
import java.util.Map;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.phys.Vec3;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.core.BlockPos;
import net.minecraft.tags.FluidTags;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.player.Player;
public class ExperienceOrb extends Entity {
public int tickCount;
public int age;
public int throwTime;
private int health;
private int value;
private Player followingPlayer;
private int followingTime;
public ExperienceOrb(final Level bjt, final double double2, final double double3, final double double4, final int integer) {
this(EntityType.EXPERIENCE_ORB, bjt);
this.setPos(double2, double3, double4);
this.yRot = (float)(this.random.nextDouble() * 360.0);
this.setDeltaMovement((this.random.nextDouble() * 0.20000000298023224 - 0.10000000149011612) * 2.0, this.random.nextDouble() * 0.2 * 2.0, (this.random.nextDouble() * 0.20000000298023224 - 0.10000000149011612) * 2.0);
this.value = integer;
}
public ExperienceOrb(final EntityType<? extends ExperienceOrb> akr, final Level bjt) {
super(akr, bjt);
this.health = 5;
}
@Override
protected boolean isMovementNoisy() {
return false;
}
@Override
protected void defineSynchedData() {
}
@Override
public void tick() {
super.tick();
if (this.throwTime > 0) {
--this.throwTime;
}
this.xo = this.getX();
this.yo = this.getY();
this.zo = this.getZ();
if (this.isUnderLiquid(FluidTags.WATER)) {
this.setUnderwaterMovement();
}
else if (!this.isNoGravity()) {
this.setDeltaMovement(this.getDeltaMovement().add(0.0, -0.03, 0.0));
}
if (this.level.getFluidState(new BlockPos(this)).is(FluidTags.LAVA)) {
this.setDeltaMovement((this.random.nextFloat() - this.random.nextFloat()) * 0.2f, 0.20000000298023224, (this.random.nextFloat() - this.random.nextFloat()) * 0.2f);
this.playSound(SoundEvents.GENERIC_BURN, 0.4f, 2.0f + this.random.nextFloat() * 0.4f);
}
if (!this.level.noCollision(this.getBoundingBox())) {
this.checkInBlock(this.getX(), (this.getBoundingBox().minY + this.getBoundingBox().maxY) / 2.0, this.getZ());
}
final double double2 = 8.0;
if (this.followingTime < this.tickCount - 20 + this.getId() % 100) {
if (this.followingPlayer == null || this.followingPlayer.distanceToSqr(this) > 64.0) {
this.followingPlayer = this.level.getNearestPlayer(this, 8.0);
}
this.followingTime = this.tickCount;
}
if (this.followingPlayer != null && this.followingPlayer.isSpectator()) {
this.followingPlayer = null;
}
if (this.followingPlayer != null) {
final Vec3 cvi4 = new Vec3(this.followingPlayer.getX() - this.getX(), this.followingPlayer.getY() + this.followingPlayer.getEyeHeight() / 2.0 - this.getY(), this.followingPlayer.getZ() - this.getZ());
final double double3 = cvi4.lengthSqr();
if (double3 < 64.0) {
final double double4 = 1.0 - Math.sqrt(double3) / 8.0;
this.setDeltaMovement(this.getDeltaMovement().add(cvi4.normalize().scale(double4 * double4 * 0.1)));
}
}
this.move(MoverType.SELF, this.getDeltaMovement());
float float4 = 0.98f;
if (this.onGround) {
float4 = this.level.getBlockState(new BlockPos(this.getX(), this.getY() - 1.0, this.getZ())).getBlock().getFriction() * 0.98f;
}
this.setDeltaMovement(this.getDeltaMovement().multiply(float4, 0.98, float4));
if (this.onGround) {
this.setDeltaMovement(this.getDeltaMovement().multiply(1.0, -0.9, 1.0));
}
++this.tickCount;
++this.age;
if (this.age >= 6000) {
this.remove();
}
}
private void setUnderwaterMovement() {
final Vec3 cvi2 = this.getDeltaMovement();
this.setDeltaMovement(cvi2.x * 0.9900000095367432, Math.min(cvi2.y + 5.000000237487257E-4, 0.05999999865889549), cvi2.z * 0.9900000095367432);
}
@Override
protected void doWaterSplashEffect() {
}
@Override
protected void burn(final int integer) {
this.hurt(DamageSource.IN_FIRE, (float)integer);
}
@Override
public boolean hurt(final DamageSource ajw, final float float2) {
if (this.isInvulnerableTo(ajw)) {
return false;
}
this.markHurt();
this.health -= (int)float2;
if (this.health <= 0) {
this.remove();
}
return false;
}
public void addAdditionalSaveData(final CompoundTag jt) {
jt.putShort("Health", (short)this.health);
jt.putShort("Age", (short)this.age);
jt.putShort("Value", (short)this.value);
}
public void readAdditionalSaveData(final CompoundTag jt) {
this.health = jt.getShort("Health");
this.age = jt.getShort("Age");
this.value = jt.getShort("Value");
}
@Override
public void playerTouch(final Player ayg) {
if (this.level.isClientSide) {
return;
}
if (this.throwTime == 0 && ayg.takeXpDelay == 0) {
ayg.takeXpDelay = 2;
ayg.take(this, 1);
final Map.Entry<EquipmentSlot, ItemStack> entry3 = EnchantmentHelper.getRandomItemWith(Enchantments.MENDING, ayg);
if (entry3 != null) {
final ItemStack bek4 = entry3.getValue();
if (!bek4.isEmpty() && bek4.isDamaged()) {
final int integer5 = Math.min(this.xpToDurability(this.value), bek4.getDamageValue());
this.value -= this.durabilityToXp(integer5);
bek4.setDamageValue(bek4.getDamageValue() - integer5);
}
}
if (this.value > 0) {
ayg.giveExperiencePoints(this.value);
}
this.remove();
}
}
private int durabilityToXp(final int integer) {
return integer / 2;
}
private int xpToDurability(final int integer) {
return integer * 2;
}
public int getValue() {
return this.value;
}
public int getIcon() {
if (this.value >= 2477) {
return 10;
}
if (this.value >= 1237) {
return 9;
}
if (this.value >= 617) {
return 8;
}
if (this.value >= 307) {
return 7;
}
if (this.value >= 149) {
return 6;
}
if (this.value >= 73) {
return 5;
}
if (this.value >= 37) {
return 4;
}
if (this.value >= 17) {
return 3;
}
if (this.value >= 7) {
return 2;
}
if (this.value >= 3) {
return 1;
}
return 0;
}
public static int getExperienceValue(final int integer) {
if (integer >= 2477) {
return 2477;
}
if (integer >= 1237) {
return 1237;
}
if (integer >= 617) {
return 617;
}
if (integer >= 307) {
return 307;
}
if (integer >= 149) {
return 149;
}
if (integer >= 73) {
return 73;
}
if (integer >= 37) {
return 37;
}
if (integer >= 17) {
return 17;
}
if (integer >= 7) {
return 7;
}
if (integer >= 3) {
return 3;
}
return 1;
}
@Override
public boolean isAttackable() {
return false;
}
@Override
public Packet<?> getAddEntityPacket() {
return new ClientboundAddExperienceOrbPacket(this);
}
}