package net.minecraft.entity.player; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.mojang.authlib.GameProfile; import com.mojang.datafixers.util.Either; import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.OptionalInt; import java.util.UUID; import java.util.function.Predicate; import javax.annotation.Nullable; import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.block.BedBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.HorizontalBlock; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.CreatureAttribute; import net.minecraft.entity.Entity; import net.minecraft.entity.EntitySize; import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.MobEntity; import net.minecraft.entity.Pose; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.attributes.IAttributeInstance; import net.minecraft.entity.boss.dragon.EnderDragonPartEntity; import net.minecraft.entity.item.ArmorStandEntity; import net.minecraft.entity.item.BoatEntity; import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.item.minecart.AbstractMinecartEntity; import net.minecraft.entity.monster.MonsterEntity; import net.minecraft.entity.passive.ParrotEntity; import net.minecraft.entity.passive.PigEntity; import net.minecraft.entity.passive.TameableEntity; import net.minecraft.entity.passive.horse.AbstractHorseEntity; import net.minecraft.entity.projectile.FishingBobberEntity; import net.minecraft.inventory.EnderChestInventory; import net.minecraft.inventory.EquipmentSlotType; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.container.Container; import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.inventory.container.PlayerContainer; import net.minecraft.item.ArmorItem; import net.minecraft.item.AxeItem; import net.minecraft.item.ElytraItem; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.item.MerchantOffers; import net.minecraft.item.ShootableItem; import net.minecraft.item.SwordItem; import net.minecraft.item.crafting.IRecipe; import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.ListNBT; import net.minecraft.network.datasync.DataParameter; import net.minecraft.network.datasync.DataSerializers; import net.minecraft.network.datasync.EntityDataManager; import net.minecraft.network.play.server.SEntityVelocityPacket; import net.minecraft.particles.IParticleData; import net.minecraft.particles.ParticleTypes; import net.minecraft.potion.EffectInstance; import net.minecraft.potion.EffectUtils; import net.minecraft.potion.Effects; import net.minecraft.scoreboard.ScorePlayerTeam; import net.minecraft.scoreboard.Scoreboard; import net.minecraft.scoreboard.Team; import net.minecraft.stats.Stat; import net.minecraft.stats.Stats; import net.minecraft.tags.FluidTags; import net.minecraft.tileentity.CommandBlockLogic; import net.minecraft.tileentity.CommandBlockTileEntity; import net.minecraft.tileentity.JigsawTileEntity; import net.minecraft.tileentity.SignTileEntity; import net.minecraft.tileentity.StructureBlockTileEntity; import net.minecraft.util.ActionResultType; import net.minecraft.util.CachedBlockInfo; import net.minecraft.util.CooldownTracker; import net.minecraft.util.DamageSource; import net.minecraft.util.Direction; import net.minecraft.util.FoodStats; import net.minecraft.util.Hand; import net.minecraft.util.HandSide; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SharedConstants; import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvent; import net.minecraft.util.SoundEvents; import net.minecraft.util.Unit; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TranslationTextComponent; import net.minecraft.util.text.event.ClickEvent; import net.minecraft.world.Difficulty; import net.minecraft.world.GameRules; import net.minecraft.world.GameType; import net.minecraft.world.IWorldReader; import net.minecraft.world.World; import net.minecraft.world.server.ServerWorld; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; public abstract class PlayerEntity extends LivingEntity { public static final String PERSISTED_NBT_TAG = "PlayerPersisted"; protected java.util.HashMap spawnPosMap = new java.util.HashMap<>(); protected java.util.HashMap spawnForcedMap = new java.util.HashMap<>(); public static final net.minecraft.entity.ai.attributes.IAttribute REACH_DISTANCE = new net.minecraft.entity.ai.attributes.RangedAttribute(null, "generic.reachDistance", 5.0D, 0.0D, 1024.0D).setShouldWatch(true); public static final EntitySize STANDING_SIZE = EntitySize.flexible(0.6F, 1.8F); private static final Map SIZE_BY_POSE = ImmutableMap.builder().put(Pose.STANDING, STANDING_SIZE).put(Pose.SLEEPING, SLEEPING_SIZE).put(Pose.FALL_FLYING, EntitySize.flexible(0.6F, 0.6F)).put(Pose.SWIMMING, EntitySize.flexible(0.6F, 0.6F)).put(Pose.SPIN_ATTACK, EntitySize.flexible(0.6F, 0.6F)).put(Pose.SNEAKING, EntitySize.flexible(0.6F, 1.5F)).put(Pose.DYING, EntitySize.fixed(0.2F, 0.2F)).build(); private static final DataParameter ABSORPTION = EntityDataManager.createKey(PlayerEntity.class, DataSerializers.FLOAT); private static final DataParameter PLAYER_SCORE = EntityDataManager.createKey(PlayerEntity.class, DataSerializers.VARINT); protected static final DataParameter PLAYER_MODEL_FLAG = EntityDataManager.createKey(PlayerEntity.class, DataSerializers.BYTE); protected static final DataParameter MAIN_HAND = EntityDataManager.createKey(PlayerEntity.class, DataSerializers.BYTE); protected static final DataParameter LEFT_SHOULDER_ENTITY = EntityDataManager.createKey(PlayerEntity.class, DataSerializers.COMPOUND_NBT); protected static final DataParameter RIGHT_SHOULDER_ENTITY = EntityDataManager.createKey(PlayerEntity.class, DataSerializers.COMPOUND_NBT); private long field_223730_e; public final PlayerInventory inventory = new PlayerInventory(this); protected EnderChestInventory enterChestInventory = new EnderChestInventory(); public final PlayerContainer container; public Container openContainer; protected FoodStats foodStats = new FoodStats(); protected int flyToggleTimer; public float prevCameraYaw; public float cameraYaw; public int xpCooldown; public double prevChasingPosX; public double prevChasingPosY; public double prevChasingPosZ; public double chasingPosX; public double chasingPosY; public double chasingPosZ; private int sleepTimer; protected boolean eyesInWaterPlayer; protected BlockPos spawnPos; protected boolean spawnForced; public final PlayerAbilities abilities = new PlayerAbilities(); public int experienceLevel; public int experienceTotal; public float experience; protected int xpSeed; protected final float speedInAir = 0.02F; private int lastXPSound; private final GameProfile gameProfile; @OnlyIn(Dist.CLIENT) private boolean hasReducedDebug; private ItemStack itemStackMainHand = ItemStack.EMPTY; private final CooldownTracker cooldownTracker = this.createCooldownTracker(); @Nullable public FishingBobberEntity fishingBobber; private net.minecraft.world.dimension.DimensionType spawnDimension = net.minecraft.world.dimension.DimensionType.OVERWORLD; private final java.util.Collection prefixes = new java.util.LinkedList(); private final java.util.Collection suffixes = new java.util.LinkedList(); public PlayerEntity(World worldIn, GameProfile gameProfileIn) { super(EntityType.PLAYER, worldIn); this.setUniqueId(getUUID(gameProfileIn)); this.gameProfile = gameProfileIn; this.container = new PlayerContainer(this.inventory, !worldIn.isRemote, this); this.openContainer = this.container; BlockPos blockpos = worldIn.getSpawnPoint(); this.setLocationAndAngles((double)blockpos.getX() + 0.5D, (double)(blockpos.getY() + 1), (double)blockpos.getZ() + 0.5D, 0.0F, 0.0F); this.unused180 = 180.0F; } public boolean func_223729_a(World p_223729_1_, BlockPos p_223729_2_, GameType p_223729_3_) { if (!p_223729_3_.hasLimitedInteractions()) { return false; } else if (p_223729_3_ == GameType.SPECTATOR) { return true; } else if (this.isAllowEdit()) { return false; } else { ItemStack itemstack = this.getHeldItemMainhand(); return itemstack.isEmpty() || !itemstack.canDestroy(p_223729_1_.getTags(), new CachedBlockInfo(p_223729_1_, p_223729_2_, false)); } } protected void registerAttributes() { super.registerAttributes(); this.getAttributes().registerAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(1.0D); this.getAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue((double)0.1F); this.getAttributes().registerAttribute(SharedMonsterAttributes.ATTACK_SPEED); this.getAttributes().registerAttribute(SharedMonsterAttributes.LUCK); this.getAttributes().registerAttribute(REACH_DISTANCE); } protected void registerData() { super.registerData(); this.dataManager.register(ABSORPTION, 0.0F); this.dataManager.register(PLAYER_SCORE, 0); this.dataManager.register(PLAYER_MODEL_FLAG, (byte)0); this.dataManager.register(MAIN_HAND, (byte)1); this.dataManager.register(LEFT_SHOULDER_ENTITY, new CompoundNBT()); this.dataManager.register(RIGHT_SHOULDER_ENTITY, new CompoundNBT()); } /** * Called to update the entity's position/logic. */ public void tick() { net.minecraftforge.fml.hooks.BasicEventHooks.onPlayerPreTick(this); this.noClip = this.isSpectator(); if (this.isSpectator()) { this.onGround = false; } if (this.xpCooldown > 0) { --this.xpCooldown; } if (this.isSleeping()) { ++this.sleepTimer; if (this.sleepTimer > 100) { this.sleepTimer = 100; } if (!this.world.isRemote && !net.minecraftforge.event.ForgeEventFactory.fireSleepingTimeCheck(this, getBedPosition())) { this.wakeUpPlayer(false, true, true); } } else if (this.sleepTimer > 0) { ++this.sleepTimer; if (this.sleepTimer >= 110) { this.sleepTimer = 0; } } this.updateEyesInWaterPlayer(); super.tick(); if (!this.world.isRemote && this.openContainer != null && !this.openContainer.canInteractWith(this)) { this.closeScreen(); this.openContainer = this.container; } if (this.isBurning() && this.abilities.disableDamage) { this.extinguish(); } this.updateCape(); if (!this.world.isRemote) { this.foodStats.tick(this); this.addStat(Stats.PLAY_ONE_MINUTE); if (this.isAlive()) { this.addStat(Stats.TIME_SINCE_DEATH); } if (this.isSneaking()) { this.addStat(Stats.SNEAK_TIME); } if (!this.isSleeping()) { this.addStat(Stats.TIME_SINCE_REST); } } int i = 29999999; double d0 = MathHelper.clamp(this.posX, -2.9999999E7D, 2.9999999E7D); double d1 = MathHelper.clamp(this.posZ, -2.9999999E7D, 2.9999999E7D); if (d0 != this.posX || d1 != this.posZ) { this.setPosition(d0, this.posY, d1); } ++this.ticksSinceLastSwing; ItemStack itemstack = this.getHeldItemMainhand(); if (!ItemStack.areItemStacksEqual(this.itemStackMainHand, itemstack)) { if (!ItemStack.areItemsEqualIgnoreDurability(this.itemStackMainHand, itemstack)) { this.resetCooldown(); } this.itemStackMainHand = itemstack.isEmpty() ? ItemStack.EMPTY : itemstack.copy(); } this.updateTurtleHelmet(); this.cooldownTracker.tick(); this.updatePose(); net.minecraftforge.fml.hooks.BasicEventHooks.onPlayerPostTick(this); } protected boolean updateEyesInWaterPlayer() { this.eyesInWaterPlayer = this.areEyesInFluid(FluidTags.WATER, true); return this.eyesInWaterPlayer; } private void updateTurtleHelmet() { ItemStack itemstack = this.getItemStackFromSlot(EquipmentSlotType.HEAD); if (itemstack.getItem() == Items.TURTLE_HELMET && !this.areEyesInFluid(FluidTags.WATER)) { this.addPotionEffect(new EffectInstance(Effects.WATER_BREATHING, 200, 0, false, false, true)); } } protected CooldownTracker createCooldownTracker() { return new CooldownTracker(); } private void updateCape() { this.prevChasingPosX = this.chasingPosX; this.prevChasingPosY = this.chasingPosY; this.prevChasingPosZ = this.chasingPosZ; double d0 = this.posX - this.chasingPosX; double d1 = this.posY - this.chasingPosY; double d2 = this.posZ - this.chasingPosZ; double d3 = 10.0D; if (d0 > 10.0D) { this.chasingPosX = this.posX; this.prevChasingPosX = this.chasingPosX; } if (d2 > 10.0D) { this.chasingPosZ = this.posZ; this.prevChasingPosZ = this.chasingPosZ; } if (d1 > 10.0D) { this.chasingPosY = this.posY; this.prevChasingPosY = this.chasingPosY; } if (d0 < -10.0D) { this.chasingPosX = this.posX; this.prevChasingPosX = this.chasingPosX; } if (d2 < -10.0D) { this.chasingPosZ = this.posZ; this.prevChasingPosZ = this.chasingPosZ; } if (d1 < -10.0D) { this.chasingPosY = this.posY; this.prevChasingPosY = this.chasingPosY; } this.chasingPosX += d0 * 0.25D; this.chasingPosZ += d2 * 0.25D; this.chasingPosY += d1 * 0.25D; } protected void updatePose() { if (this.isPoseClear(Pose.SWIMMING)) { Pose pose; if (this.isElytraFlying()) { pose = Pose.FALL_FLYING; } else if (this.isSleeping()) { pose = Pose.SLEEPING; } else if (this.isSwimming()) { pose = Pose.SWIMMING; } else if (this.isSpinAttacking()) { pose = Pose.SPIN_ATTACK; } else if (this.isSneaking() && !this.abilities.isFlying) { pose = Pose.SNEAKING; } else { pose = Pose.STANDING; } Pose pose1; if (!this.isSpectator() && !this.isPassenger() && !this.isPoseClear(pose)) { if (this.isPoseClear(Pose.SNEAKING)) { pose1 = Pose.SNEAKING; } else { pose1 = Pose.SWIMMING; } } else { pose1 = pose; } this.setPose(pose1); } } /** * Return the amount of time this entity should stay in a portal before being transported. */ public int getMaxInPortalTime() { return this.abilities.disableDamage ? 1 : 80; } protected SoundEvent getSwimSound() { return SoundEvents.ENTITY_PLAYER_SWIM; } protected SoundEvent getSplashSound() { return SoundEvents.ENTITY_PLAYER_SPLASH; } protected SoundEvent getHighspeedSplashSound() { return SoundEvents.ENTITY_PLAYER_SPLASH_HIGH_SPEED; } /** * Return the amount of cooldown before this entity can use a portal again. */ public int getPortalCooldown() { return 10; } public void playSound(SoundEvent soundIn, float volume, float pitch) { this.world.playSound(this, this.posX, this.posY, this.posZ, soundIn, this.getSoundCategory(), volume, pitch); } public void func_213823_a(SoundEvent p_213823_1_, SoundCategory p_213823_2_, float p_213823_3_, float p_213823_4_) { } public SoundCategory getSoundCategory() { return SoundCategory.PLAYERS; } protected int getFireImmuneTicks() { return 20; } /** * Handler for {@link World#setEntityState} */ @OnlyIn(Dist.CLIENT) public void handleStatusUpdate(byte id) { if (id == 9) { this.onItemUseFinish(); } else if (id == 23) { this.hasReducedDebug = false; } else if (id == 22) { this.hasReducedDebug = true; } else if (id == 43) { this.func_213824_a(ParticleTypes.CLOUD); } else { super.handleStatusUpdate(id); } } @OnlyIn(Dist.CLIENT) private void func_213824_a(IParticleData p_213824_1_) { for(int i = 0; i < 5; ++i) { double d0 = this.rand.nextGaussian() * 0.02D; double d1 = this.rand.nextGaussian() * 0.02D; double d2 = this.rand.nextGaussian() * 0.02D; this.world.addParticle(p_213824_1_, this.posX + (double)(this.rand.nextFloat() * this.getWidth() * 2.0F) - (double)this.getWidth(), this.posY + 1.0D + (double)(this.rand.nextFloat() * this.getHeight()), this.posZ + (double)(this.rand.nextFloat() * this.getWidth() * 2.0F) - (double)this.getWidth(), d0, d1, d2); } } /** * set current crafting inventory back to the 2x2 square */ public void closeScreen() { this.openContainer = this.container; } /** * Handles updating while riding another entity */ public void updateRidden() { if (!this.world.isRemote && this.isSneaking() && this.isPassenger()) { this.stopRiding(); this.setSneaking(false); } else { double d0 = this.posX; double d1 = this.posY; double d2 = this.posZ; float f = this.rotationYaw; float f1 = this.rotationPitch; super.updateRidden(); this.prevCameraYaw = this.cameraYaw; this.cameraYaw = 0.0F; this.addMountedMovementStat(this.posX - d0, this.posY - d1, this.posZ - d2); if (this.getRidingEntity() instanceof LivingEntity && ((LivingEntity)this.getRidingEntity()).shouldRiderFaceForward(this)) { this.rotationPitch = f1; this.rotationYaw = f; this.renderYawOffset = ((LivingEntity)this.getRidingEntity()).renderYawOffset; } } } /** * Keeps moving the entity up so it isn't colliding with blocks and other requirements for this entity to be spawned * (only actually used on players though its also on Entity) */ @OnlyIn(Dist.CLIENT) public void preparePlayerToSpawn() { this.setPose(Pose.STANDING); super.preparePlayerToSpawn(); this.setHealth(this.getMaxHealth()); this.deathTime = 0; } protected void updateEntityActionState() { super.updateEntityActionState(); this.updateArmSwingProgress(); this.rotationYawHead = this.rotationYaw; } /** * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons * use this to react to sunlight and start to burn. */ public void livingTick() { if (this.flyToggleTimer > 0) { --this.flyToggleTimer; } if (this.world.getDifficulty() == Difficulty.PEACEFUL && this.world.getGameRules().getBoolean(GameRules.NATURAL_REGENERATION)) { if (this.getHealth() < this.getMaxHealth() && this.ticksExisted % 20 == 0) { this.heal(1.0F); } if (this.foodStats.needFood() && this.ticksExisted % 10 == 0) { this.foodStats.setFoodLevel(this.foodStats.getFoodLevel() + 1); } } this.inventory.tick(); this.prevCameraYaw = this.cameraYaw; super.livingTick(); IAttributeInstance iattributeinstance = this.getAttribute(SharedMonsterAttributes.MOVEMENT_SPEED); if (!this.world.isRemote) { iattributeinstance.setBaseValue((double)this.abilities.getWalkSpeed()); } this.jumpMovementFactor = 0.02F; if (this.isSprinting()) { this.jumpMovementFactor = (float)((double)this.jumpMovementFactor + 0.005999999865889549D); } this.setAIMoveSpeed((float)iattributeinstance.getValue()); float f; if (this.onGround && !(this.getHealth() <= 0.0F) && !this.isSwimming()) { f = Math.min(0.1F, MathHelper.sqrt(func_213296_b(this.getMotion()))); } else { f = 0.0F; } this.cameraYaw += (f - this.cameraYaw) * 0.4F; if (this.getHealth() > 0.0F && !this.isSpectator()) { AxisAlignedBB axisalignedbb; if (this.isPassenger() && !this.getRidingEntity().removed) { axisalignedbb = this.getBoundingBox().union(this.getRidingEntity().getBoundingBox()).grow(1.0D, 0.0D, 1.0D); } else { axisalignedbb = this.getBoundingBox().grow(1.0D, 0.5D, 1.0D); } List list = this.world.getEntitiesWithinAABBExcludingEntity(this, axisalignedbb); for(int i = 0; i < list.size(); ++i) { Entity entity = list.get(i); if (!entity.removed) { this.collideWithPlayer(entity); } } } this.playShoulderEntityAmbientSound(this.getLeftShoulderEntity()); this.playShoulderEntityAmbientSound(this.getRightShoulderEntity()); if (!this.world.isRemote && (this.fallDistance > 0.5F || this.isInWater() || this.isPassenger()) || this.abilities.isFlying || this.isSleeping()) { this.spawnShoulderEntities(); } } private void playShoulderEntityAmbientSound(@Nullable CompoundNBT p_192028_1_) { if (p_192028_1_ != null && !p_192028_1_.contains("Silent") || !p_192028_1_.getBoolean("Silent")) { String s = p_192028_1_.getString("id"); EntityType.byKey(s).filter((p_213830_0_) -> { return p_213830_0_ == EntityType.PARROT; }).ifPresent((p_213834_1_) -> { ParrotEntity.playAmbientSound(this.world, this); }); } } private void collideWithPlayer(Entity entityIn) { entityIn.onCollideWithPlayer(this); } public int getScore() { return this.dataManager.get(PLAYER_SCORE); } /** * Set player's score */ public void setScore(int scoreIn) { this.dataManager.set(PLAYER_SCORE, scoreIn); } /** * Add to player's score */ public void addScore(int scoreIn) { int i = this.getScore(); this.dataManager.set(PLAYER_SCORE, i + scoreIn); } /** * Called when the mob's health reaches 0. */ public void onDeath(DamageSource cause) { if (net.minecraftforge.common.ForgeHooks.onLivingDeath(this, cause)) return; super.onDeath(cause); this.setPosition(this.posX, this.posY, this.posZ); if (!this.isSpectator()) { this.spawnDrops(cause); } if (cause != null) { this.setMotion((double)(-MathHelper.cos((this.attackedAtYaw + this.rotationYaw) * ((float)Math.PI / 180F)) * 0.1F), (double)0.1F, (double)(-MathHelper.sin((this.attackedAtYaw + this.rotationYaw) * ((float)Math.PI / 180F)) * 0.1F)); } else { this.setMotion(0.0D, 0.1D, 0.0D); } this.addStat(Stats.DEATHS); this.takeStat(Stats.CUSTOM.get(Stats.TIME_SINCE_DEATH)); this.takeStat(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)); this.extinguish(); this.setFlag(0, false); } protected void dropInventory() { super.dropInventory(); if (!this.world.getGameRules().getBoolean(GameRules.KEEP_INVENTORY)) { this.destroyVanishingCursedItems(); this.inventory.dropAllItems(); } } protected void destroyVanishingCursedItems() { for(int i = 0; i < this.inventory.getSizeInventory(); ++i) { ItemStack itemstack = this.inventory.getStackInSlot(i); if (!itemstack.isEmpty() && EnchantmentHelper.hasVanishingCurse(itemstack)) { this.inventory.removeStackFromSlot(i); } } } protected SoundEvent getHurtSound(DamageSource damageSourceIn) { if (damageSourceIn == DamageSource.ON_FIRE) { return SoundEvents.ENTITY_PLAYER_HURT_ON_FIRE; } else if (damageSourceIn == DamageSource.DROWN) { return SoundEvents.ENTITY_PLAYER_HURT_DROWN; } else { return damageSourceIn == DamageSource.SWEET_BERRY_BUSH ? SoundEvents.ENTITY_PLAYER_HURT_SWEET_BERRY_BUSH : SoundEvents.ENTITY_PLAYER_HURT; } } protected SoundEvent getDeathSound() { return SoundEvents.ENTITY_PLAYER_DEATH; } /** * Drop one item out of the currently selected stack if {@code dropAll} is false. If {@code dropItem} is true the * entire stack is dropped. */ @Nullable public ItemEntity dropItem(boolean dropAll) { ItemStack stack = inventory.getCurrentItem(); if (stack.isEmpty() || !stack.onDroppedByPlayer(this)) return null; return net.minecraftforge.common.ForgeHooks.onPlayerTossEvent(this, this.inventory.decrStackSize(this.inventory.currentItem, dropAll && !this.inventory.getCurrentItem().isEmpty() ? this.inventory.getCurrentItem().getCount() : 1), true); } /** * Drops an item into the world. */ @Nullable public ItemEntity dropItem(ItemStack itemStackIn, boolean unused) { return net.minecraftforge.common.ForgeHooks.onPlayerTossEvent(this, itemStackIn, false); } /** * Creates and drops the provided item. Depending on the dropAround, it will drop teh item around the player, instead * of dropping the item from where the player is pointing at. Likewise, if traceItem is true, the dropped item entity * will have the thrower set as the player. */ @Nullable public ItemEntity dropItem(ItemStack droppedItem, boolean dropAround, boolean traceItem) { if (droppedItem.isEmpty()) { return null; } else { double d0 = this.posY - (double)0.3F + (double)this.getEyeHeight(); ItemEntity itementity = new ItemEntity(this.world, this.posX, d0, this.posZ, droppedItem); itementity.setPickupDelay(40); if (traceItem) { itementity.setThrowerId(this.getUniqueID()); } if (dropAround) { float f = this.rand.nextFloat() * 0.5F; float f1 = this.rand.nextFloat() * ((float)Math.PI * 2F); this.setMotion((double)(-MathHelper.sin(f1) * f), (double)0.2F, (double)(MathHelper.cos(f1) * f)); } else { float f7 = 0.3F; float f8 = MathHelper.sin(this.rotationPitch * ((float)Math.PI / 180F)); float f2 = MathHelper.cos(this.rotationPitch * ((float)Math.PI / 180F)); float f3 = MathHelper.sin(this.rotationYaw * ((float)Math.PI / 180F)); float f4 = MathHelper.cos(this.rotationYaw * ((float)Math.PI / 180F)); float f5 = this.rand.nextFloat() * ((float)Math.PI * 2F); float f6 = 0.02F * this.rand.nextFloat(); itementity.setMotion((double)(-f3 * f2 * 0.3F) + Math.cos((double)f5) * (double)f6, (double)(-f8 * 0.3F + 0.1F + (this.rand.nextFloat() - this.rand.nextFloat()) * 0.1F), (double)(f4 * f2 * 0.3F) + Math.sin((double)f5) * (double)f6); } return itementity; } } @Deprecated //Use location sensitive version below public float getDigSpeed(BlockState state) { return getDigSpeed(state, null); } public float getDigSpeed(BlockState state, @Nullable BlockPos pos) { float f = this.inventory.getDestroySpeed(state); if (f > 1.0F) { int i = EnchantmentHelper.getEfficiencyModifier(this); ItemStack itemstack = this.getHeldItemMainhand(); if (i > 0 && !itemstack.isEmpty()) { f += (float)(i * i + 1); } } if (EffectUtils.hasMiningSpeedup(this)) { f *= 1.0F + (float)(EffectUtils.getMiningSpeedup(this) + 1) * 0.2F; } if (this.isPotionActive(Effects.MINING_FATIGUE)) { float f1; switch(this.getActivePotionEffect(Effects.MINING_FATIGUE).getAmplifier()) { case 0: f1 = 0.3F; break; case 1: f1 = 0.09F; break; case 2: f1 = 0.0027F; break; case 3: default: f1 = 8.1E-4F; } f *= f1; } if (this.areEyesInFluid(FluidTags.WATER) && !EnchantmentHelper.hasAquaAffinity(this)) { f /= 5.0F; } if (!this.onGround) { f /= 5.0F; } f = net.minecraftforge.event.ForgeEventFactory.getBreakSpeed(this, state, f, pos); return f; } public boolean canHarvestBlock(BlockState state) { return net.minecraftforge.event.ForgeEventFactory.doPlayerHarvestCheck(this, state, state.getMaterial().isToolNotRequired() || this.inventory.canHarvestBlock(state)); } /** * (abstract) Protected helper method to read subclass entity data from NBT. */ public void readAdditional(CompoundNBT compound) { super.readAdditional(compound); this.setUniqueId(getUUID(this.gameProfile)); ListNBT listnbt = compound.getList("Inventory", 10); this.inventory.read(listnbt); this.inventory.currentItem = compound.getInt("SelectedItemSlot"); this.sleepTimer = compound.getShort("SleepTimer"); this.experience = compound.getFloat("XpP"); this.experienceLevel = compound.getInt("XpLevel"); this.experienceTotal = compound.getInt("XpTotal"); this.xpSeed = compound.getInt("XpSeed"); if (this.xpSeed == 0) { this.xpSeed = this.rand.nextInt(); } this.setScore(compound.getInt("Score")); if (compound.contains("SpawnX", 99) && compound.contains("SpawnY", 99) && compound.contains("SpawnZ", 99)) { this.spawnPos = new BlockPos(compound.getInt("SpawnX"), compound.getInt("SpawnY"), compound.getInt("SpawnZ")); this.spawnForced = compound.getBoolean("SpawnForced"); } compound.getList("Spawns", 10).forEach(e -> { CompoundNBT data = (CompoundNBT)e; ResourceLocation dim = new ResourceLocation(data.getString("Dim")); this.spawnPosMap.put(dim, new BlockPos(data.getInt("SpawnX"), data.getInt("SpawnY"), data.getInt("SpawnZ"))); this.spawnForcedMap.put(dim, data.getBoolean("SpawnForced")); }); net.minecraft.world.dimension.DimensionType spawnDim = null; if (compound.contains("SpawnDimension", net.minecraftforge.common.util.Constants.NBT.TAG_STRING)) spawnDim = net.minecraft.world.dimension.DimensionType.byName(new ResourceLocation(compound.getString("SpawnDimension"))); this.spawnDimension = spawnDim != null ? spawnDim : net.minecraft.world.dimension.DimensionType.OVERWORLD; this.foodStats.read(compound); this.abilities.read(compound); if (compound.contains("EnderItems", 9)) { this.enterChestInventory.read(compound.getList("EnderItems", 10)); } if (compound.contains("ShoulderEntityLeft", 10)) { this.setLeftShoulderEntity(compound.getCompound("ShoulderEntityLeft")); } if (compound.contains("ShoulderEntityRight", 10)) { this.setRightShoulderEntity(compound.getCompound("ShoulderEntityRight")); } } public void writeAdditional(CompoundNBT compound) { super.writeAdditional(compound); compound.putInt("DataVersion", SharedConstants.getVersion().getWorldVersion()); compound.put("Inventory", this.inventory.write(new ListNBT())); compound.putInt("SelectedItemSlot", this.inventory.currentItem); compound.putShort("SleepTimer", (short)this.sleepTimer); compound.putFloat("XpP", this.experience); compound.putInt("XpLevel", this.experienceLevel); compound.putInt("XpTotal", this.experienceTotal); compound.putInt("XpSeed", this.xpSeed); compound.putInt("Score", this.getScore()); if (this.spawnPos != null) { compound.putInt("SpawnX", this.spawnPos.getX()); compound.putInt("SpawnY", this.spawnPos.getY()); compound.putInt("SpawnZ", this.spawnPos.getZ()); compound.putBoolean("SpawnForced", this.spawnForced); } this.foodStats.write(compound); this.abilities.write(compound); compound.put("EnderItems", this.enterChestInventory.write()); if (!this.getLeftShoulderEntity().isEmpty()) { compound.put("ShoulderEntityLeft", this.getLeftShoulderEntity()); } if (!this.getRightShoulderEntity().isEmpty()) { compound.put("ShoulderEntityRight", this.getRightShoulderEntity()); } ListNBT spawnlist = new ListNBT(); spawnPosMap.forEach((dim, pos) -> { if (pos != null) { CompoundNBT data = new CompoundNBT(); data.putString("Dim", dim.toString()); data.putInt("SpawnX", pos.getX()); data.putInt("SpawnY", pos.getY()); data.putInt("SpawnZ", pos.getZ()); data.putBoolean("SpawnForced", spawnForcedMap.getOrDefault(dim, false)); spawnlist.add(data); } }); compound.put("Spawns", spawnlist); if (spawnDimension != net.minecraft.world.dimension.DimensionType.OVERWORLD) { compound.putString("SpawnDimension", spawnDimension.getRegistryName().toString()); } } /** * Called when the entity is attacked. */ public boolean attackEntityFrom(DamageSource source, float amount) { if (!net.minecraftforge.common.ForgeHooks.onPlayerAttack(this, source, amount)) return false; if (this.isInvulnerableTo(source)) { return false; } else if (this.abilities.disableDamage && !source.canHarmInCreative()) { return false; } else { this.idleTime = 0; if (this.getHealth() <= 0.0F) { return false; } else { this.spawnShoulderEntities(); if (source.isDifficultyScaled()) { if (this.world.getDifficulty() == Difficulty.PEACEFUL) { amount = 0.0F; } if (this.world.getDifficulty() == Difficulty.EASY) { amount = Math.min(amount / 2.0F + 1.0F, amount); } if (this.world.getDifficulty() == Difficulty.HARD) { amount = amount * 3.0F / 2.0F; } } return amount == 0.0F ? false : super.attackEntityFrom(source, amount); } } } protected void blockUsingShield(LivingEntity p_190629_1_) { super.blockUsingShield(p_190629_1_); if (p_190629_1_.getHeldItemMainhand().canDisableShield(this.activeItemStack, this, p_190629_1_)) { this.disableShield(true); } } public boolean canAttackPlayer(PlayerEntity other) { Team team = this.getTeam(); Team team1 = other.getTeam(); if (team == null) { return true; } else { return !team.isSameTeam(team1) ? true : team.getAllowFriendlyFire(); } } protected void damageArmor(float damage) { this.inventory.damageArmor(damage); } protected void damageShield(float damage) { if (damage >= 3.0F && this.activeItemStack.isShield(this)) { int i = 1 + MathHelper.floor(damage); Hand hand = this.getActiveHand(); this.activeItemStack.damageItem(i, this, (p_213833_1_) -> { p_213833_1_.sendBreakAnimation(hand); net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this, this.activeItemStack, hand); }); if (this.activeItemStack.isEmpty()) { if (hand == Hand.MAIN_HAND) { this.setItemStackToSlot(EquipmentSlotType.MAINHAND, ItemStack.EMPTY); } else { this.setItemStackToSlot(EquipmentSlotType.OFFHAND, ItemStack.EMPTY); } this.activeItemStack = ItemStack.EMPTY; this.playSound(SoundEvents.ITEM_SHIELD_BREAK, 0.8F, 0.8F + this.world.rand.nextFloat() * 0.4F); } } } /** * Deals damage to the entity. This will take the armor of the entity into consideration before damaging the health * bar. */ protected void damageEntity(DamageSource damageSrc, float damageAmount) { if (!this.isInvulnerableTo(damageSrc)) { damageAmount = net.minecraftforge.common.ForgeHooks.onLivingHurt(this, damageSrc, damageAmount); if (damageAmount <= 0) return; damageAmount = this.applyArmorCalculations(damageSrc, damageAmount); damageAmount = this.applyPotionDamageCalculations(damageSrc, damageAmount); float f = damageAmount; damageAmount = Math.max(damageAmount - this.getAbsorptionAmount(), 0.0F); this.setAbsorptionAmount(this.getAbsorptionAmount() - (f - damageAmount)); damageAmount = net.minecraftforge.common.ForgeHooks.onLivingDamage(this, damageSrc, damageAmount); float f1 = f - damageAmount; if (f1 > 0.0F && f1 < 3.4028235E37F) { this.addStat(Stats.DAMAGE_ABSORBED, Math.round(f1 * 10.0F)); } if (damageAmount != 0.0F) { this.addExhaustion(damageSrc.getHungerDamage()); float f2 = this.getHealth(); this.setHealth(this.getHealth() - damageAmount); this.getCombatTracker().trackDamage(damageSrc, f2, damageAmount); if (damageAmount < 3.4028235E37F) { this.addStat(Stats.DAMAGE_TAKEN, Math.round(damageAmount * 10.0F)); } } } } public void openSignEditor(SignTileEntity signTile) { } public void openMinecartCommandBlock(CommandBlockLogic commandBlock) { } public void openCommandBlock(CommandBlockTileEntity commandBlock) { } public void openStructureBlock(StructureBlockTileEntity structure) { } public void func_213826_a(JigsawTileEntity p_213826_1_) { } public void openHorseInventory(AbstractHorseEntity horse, IInventory inventoryIn) { } public OptionalInt openContainer(@Nullable INamedContainerProvider p_213829_1_) { return OptionalInt.empty(); } public void func_213818_a(int p_213818_1_, MerchantOffers p_213818_2_, int p_213818_3_, int p_213818_4_, boolean p_213818_5_, boolean p_213818_6_) { } public void openBook(ItemStack stack, Hand hand) { } public ActionResultType interactOn(Entity entityToInteractOn, Hand hand) { if (this.isSpectator()) { if (entityToInteractOn instanceof INamedContainerProvider) { this.openContainer((INamedContainerProvider)entityToInteractOn); } return ActionResultType.PASS; } else { ActionResultType cancelResult = net.minecraftforge.common.ForgeHooks.onInteractEntity(this, entityToInteractOn, hand); if (cancelResult != null) return cancelResult; ItemStack itemstack = this.getHeldItem(hand); ItemStack itemstack1 = itemstack.isEmpty() ? ItemStack.EMPTY : itemstack.copy(); if (entityToInteractOn.processInitialInteract(this, hand)) { if (this.abilities.isCreativeMode && itemstack == this.getHeldItem(hand) && itemstack.getCount() < itemstack1.getCount()) { itemstack.setCount(itemstack1.getCount()); } if (!this.abilities.isCreativeMode && itemstack.isEmpty()) { net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this, itemstack1, hand); } return ActionResultType.SUCCESS; } else { if (!itemstack.isEmpty() && entityToInteractOn instanceof LivingEntity) { if (this.abilities.isCreativeMode) { itemstack = itemstack1; } if (itemstack.interactWithEntity(this, (LivingEntity)entityToInteractOn, hand)) { if (itemstack.isEmpty() && !this.abilities.isCreativeMode) { net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this, itemstack1, hand); this.setHeldItem(hand, ItemStack.EMPTY); } return ActionResultType.SUCCESS; } } return ActionResultType.PASS; } } } /** * Returns the Y Offset of this entity. */ public double getYOffset() { return -0.35D; } /** * Dismounts this entity from the entity it is riding. */ public void stopRiding() { super.stopRiding(); this.rideCooldown = 0; } /** * Dead and sleeping entities cannot move */ protected boolean isMovementBlocked() { return super.isMovementBlocked() || this.isSleeping(); } /** * Attacks for the player the targeted entity with the currently equipped item. The equipped item has hitEntity * called on it. Args: targetEntity */ public void attackTargetEntityWithCurrentItem(Entity targetEntity) { if (!net.minecraftforge.common.ForgeHooks.onPlayerAttackTarget(this, targetEntity)) return; if (targetEntity.canBeAttackedWithItem()) { if (!targetEntity.hitByEntity(this)) { float f = (float)this.getAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).getValue(); float f1; if (targetEntity instanceof LivingEntity) { f1 = EnchantmentHelper.getModifierForCreature(this.getHeldItemMainhand(), ((LivingEntity)targetEntity).getCreatureAttribute()); } else { f1 = EnchantmentHelper.getModifierForCreature(this.getHeldItemMainhand(), CreatureAttribute.UNDEFINED); } float f2 = this.getCooledAttackStrength(0.5F); f = f * (0.2F + f2 * f2 * 0.8F); f1 = f1 * f2; this.resetCooldown(); if (f > 0.0F || f1 > 0.0F) { boolean flag = f2 > 0.9F; boolean flag1 = false; int i = 0; i = i + EnchantmentHelper.getKnockbackModifier(this); if (this.isSprinting() && flag) { this.world.playSound((PlayerEntity)null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_PLAYER_ATTACK_KNOCKBACK, this.getSoundCategory(), 1.0F, 1.0F); ++i; flag1 = true; } boolean flag2 = flag && this.fallDistance > 0.0F && !this.onGround && !this.isOnLadder() && !this.isInWater() && !this.isPotionActive(Effects.BLINDNESS) && !this.isPassenger() && targetEntity instanceof LivingEntity; flag2 = flag2 && !this.isSprinting(); net.minecraftforge.event.entity.player.CriticalHitEvent hitResult = net.minecraftforge.common.ForgeHooks.getCriticalHit(this, targetEntity, flag2, flag2 ? 1.5F : 1.0F); flag2 = hitResult != null; if (flag2) { f *= hitResult.getDamageModifier(); } f = f + f1; boolean flag3 = false; double d0 = (double)(this.distanceWalkedModified - this.prevDistanceWalkedModified); if (flag && !flag2 && !flag1 && this.onGround && d0 < (double)this.getAIMoveSpeed()) { ItemStack itemstack = this.getHeldItem(Hand.MAIN_HAND); if (itemstack.getItem() instanceof SwordItem) { flag3 = true; } } float f4 = 0.0F; boolean flag4 = false; int j = EnchantmentHelper.getFireAspectModifier(this); if (targetEntity instanceof LivingEntity) { f4 = ((LivingEntity)targetEntity).getHealth(); if (j > 0 && !targetEntity.isBurning()) { flag4 = true; targetEntity.setFire(1); } } Vec3d vec3d = targetEntity.getMotion(); boolean flag5 = targetEntity.attackEntityFrom(DamageSource.causePlayerDamage(this), f); if (flag5) { if (i > 0) { if (targetEntity instanceof LivingEntity) { ((LivingEntity)targetEntity).knockBack(this, (float)i * 0.5F, (double)MathHelper.sin(this.rotationYaw * ((float)Math.PI / 180F)), (double)(-MathHelper.cos(this.rotationYaw * ((float)Math.PI / 180F)))); } else { targetEntity.addVelocity((double)(-MathHelper.sin(this.rotationYaw * ((float)Math.PI / 180F)) * (float)i * 0.5F), 0.1D, (double)(MathHelper.cos(this.rotationYaw * ((float)Math.PI / 180F)) * (float)i * 0.5F)); } this.setMotion(this.getMotion().mul(0.6D, 1.0D, 0.6D)); this.setSprinting(false); } if (flag3) { float f3 = 1.0F + EnchantmentHelper.getSweepingDamageRatio(this) * f; for(LivingEntity livingentity : this.world.getEntitiesWithinAABB(LivingEntity.class, targetEntity.getBoundingBox().grow(1.0D, 0.25D, 1.0D))) { if (livingentity != this && livingentity != targetEntity && !this.isOnSameTeam(livingentity) && (!(livingentity instanceof ArmorStandEntity) || !((ArmorStandEntity)livingentity).hasMarker()) && this.getDistanceSq(livingentity) < 9.0D) { livingentity.knockBack(this, 0.4F, (double)MathHelper.sin(this.rotationYaw * ((float)Math.PI / 180F)), (double)(-MathHelper.cos(this.rotationYaw * ((float)Math.PI / 180F)))); livingentity.attackEntityFrom(DamageSource.causePlayerDamage(this), f3); } } this.world.playSound((PlayerEntity)null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_PLAYER_ATTACK_SWEEP, this.getSoundCategory(), 1.0F, 1.0F); this.spawnSweepParticles(); } if (targetEntity instanceof ServerPlayerEntity && targetEntity.velocityChanged) { ((ServerPlayerEntity)targetEntity).connection.sendPacket(new SEntityVelocityPacket(targetEntity)); targetEntity.velocityChanged = false; targetEntity.setMotion(vec3d); } if (flag2) { this.world.playSound((PlayerEntity)null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_PLAYER_ATTACK_CRIT, this.getSoundCategory(), 1.0F, 1.0F); this.onCriticalHit(targetEntity); } if (!flag2 && !flag3) { if (flag) { this.world.playSound((PlayerEntity)null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_PLAYER_ATTACK_STRONG, this.getSoundCategory(), 1.0F, 1.0F); } else { this.world.playSound((PlayerEntity)null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_PLAYER_ATTACK_WEAK, this.getSoundCategory(), 1.0F, 1.0F); } } if (f1 > 0.0F) { this.onEnchantmentCritical(targetEntity); } this.setLastAttackedEntity(targetEntity); if (targetEntity instanceof LivingEntity) { EnchantmentHelper.applyThornEnchantments((LivingEntity)targetEntity, this); } EnchantmentHelper.applyArthropodEnchantments(this, targetEntity); ItemStack itemstack1 = this.getHeldItemMainhand(); Entity entity = targetEntity; if (targetEntity instanceof EnderDragonPartEntity) { entity = ((EnderDragonPartEntity)targetEntity).dragon; } if (!this.world.isRemote && !itemstack1.isEmpty() && entity instanceof LivingEntity) { ItemStack copy = itemstack1.copy(); itemstack1.hitEntity((LivingEntity)entity, this); if (itemstack1.isEmpty()) { net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(this, copy, Hand.MAIN_HAND); this.setHeldItem(Hand.MAIN_HAND, ItemStack.EMPTY); } } if (targetEntity instanceof LivingEntity) { float f5 = f4 - ((LivingEntity)targetEntity).getHealth(); this.addStat(Stats.DAMAGE_DEALT, Math.round(f5 * 10.0F)); if (j > 0) { targetEntity.setFire(j * 4); } if (this.world instanceof ServerWorld && f5 > 2.0F) { int k = (int)((double)f5 * 0.5D); ((ServerWorld)this.world).spawnParticle(ParticleTypes.DAMAGE_INDICATOR, targetEntity.posX, targetEntity.posY + (double)(targetEntity.getHeight() * 0.5F), targetEntity.posZ, k, 0.1D, 0.0D, 0.1D, 0.2D); } } this.addExhaustion(0.1F); } else { this.world.playSound((PlayerEntity)null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_PLAYER_ATTACK_NODAMAGE, this.getSoundCategory(), 1.0F, 1.0F); if (flag4) { targetEntity.extinguish(); } } } } } } protected void spinAttack(LivingEntity p_204804_1_) { this.attackTargetEntityWithCurrentItem(p_204804_1_); } public void disableShield(boolean p_190777_1_) { float f = 0.25F + (float)EnchantmentHelper.getEfficiencyModifier(this) * 0.05F; if (p_190777_1_) { f += 0.75F; } if (this.rand.nextFloat() < f) { this.getCooldownTracker().setCooldown(this.getActiveItemStack().getItem(), 100); this.resetActiveHand(); this.world.setEntityState(this, (byte)30); } } /** * Called when the entity is dealt a critical hit. */ public void onCriticalHit(Entity entityHit) { } public void onEnchantmentCritical(Entity entityHit) { } public void spawnSweepParticles() { double d0 = (double)(-MathHelper.sin(this.rotationYaw * ((float)Math.PI / 180F))); double d1 = (double)MathHelper.cos(this.rotationYaw * ((float)Math.PI / 180F)); if (this.world instanceof ServerWorld) { ((ServerWorld)this.world).spawnParticle(ParticleTypes.SWEEP_ATTACK, this.posX + d0, this.posY + (double)this.getHeight() * 0.5D, this.posZ + d1, 0, d0, 0.0D, d1, 0.0D); } } @OnlyIn(Dist.CLIENT) public void respawnPlayer() { } @Override public void remove(boolean keepData) { super.remove(keepData); this.container.onContainerClosed(this); if (this.openContainer != null) { this.openContainer.onContainerClosed(this); } } /** * returns true if this is an EntityPlayerSP, or the logged in player. */ public boolean isUser() { return false; } /** * Returns the GameProfile for this player */ public GameProfile getGameProfile() { return this.gameProfile; } public Either trySleep(BlockPos at) { Optional optAt = Optional.of(at); PlayerEntity.SleepResult ret = net.minecraftforge.event.ForgeEventFactory.onPlayerSleepInBed(this, optAt); if (ret != null) return Either.left(ret); Direction direction = this.world.getBlockState(at).get(HorizontalBlock.HORIZONTAL_FACING); if (!this.world.isRemote) { if (this.isSleeping() || !this.isAlive()) { return Either.left(PlayerEntity.SleepResult.OTHER_PROBLEM); } if (!this.world.dimension.isSurfaceWorld()) { return Either.left(PlayerEntity.SleepResult.NOT_POSSIBLE_HERE); } if (!net.minecraftforge.event.ForgeEventFactory.fireSleepingTimeCheck(this, optAt)) { return Either.left(PlayerEntity.SleepResult.NOT_POSSIBLE_NOW); } if (!this.bedInRange(at, direction)) { return Either.left(PlayerEntity.SleepResult.TOO_FAR_AWAY); } if (this.func_213828_b(at, direction)) { return Either.left(PlayerEntity.SleepResult.OBSTRUCTED); } if (!this.isCreative()) { double d0 = 8.0D; double d1 = 5.0D; List list = this.world.getEntitiesWithinAABB(MonsterEntity.class, new AxisAlignedBB((double)at.getX() - 8.0D, (double)at.getY() - 5.0D, (double)at.getZ() - 8.0D, (double)at.getX() + 8.0D, (double)at.getY() + 5.0D, (double)at.getZ() + 8.0D), (p_213820_1_) -> { return p_213820_1_.isPreventingPlayerRest(this); }); if (!list.isEmpty()) { return Either.left(PlayerEntity.SleepResult.NOT_SAFE); } } } this.startSleeping(at); this.sleepTimer = 0; if (this.world instanceof ServerWorld) { ((ServerWorld)this.world).updateAllPlayersSleepingFlag(); } return Either.right(Unit.INSTANCE); } public void startSleeping(BlockPos p_213342_1_) { this.takeStat(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)); super.startSleeping(p_213342_1_); } private boolean bedInRange(BlockPos p_190774_1_, Direction p_190774_2_) { if (Math.abs(this.posX - (double)p_190774_1_.getX()) <= 3.0D && Math.abs(this.posY - (double)p_190774_1_.getY()) <= 2.0D && Math.abs(this.posZ - (double)p_190774_1_.getZ()) <= 3.0D) { return true; } else if (p_190774_2_ == null) { return false; } else { BlockPos blockpos = p_190774_1_.offset(p_190774_2_.getOpposite()); return Math.abs(this.posX - (double)blockpos.getX()) <= 3.0D && Math.abs(this.posY - (double)blockpos.getY()) <= 2.0D && Math.abs(this.posZ - (double)blockpos.getZ()) <= 3.0D; } } private boolean func_213828_b(BlockPos p_213828_1_, Direction p_213828_2_) { BlockPos blockpos = p_213828_1_.up(); return !this.isNormalCube(blockpos) || !this.isNormalCube(blockpos.offset(p_213828_2_.getOpposite())); } /** * Wake up the player if they're sleeping. */ public void wakeUpPlayer(boolean immediately, boolean updateWorldFlag, boolean setSpawn) { net.minecraftforge.event.ForgeEventFactory.onPlayerWakeup(this, immediately, updateWorldFlag, setSpawn); Optional optional = this.getBedPosition(); super.wakeUp(); if (this.world instanceof ServerWorld && updateWorldFlag) { ((ServerWorld)this.world).updateAllPlayersSleepingFlag(); } this.sleepTimer = immediately ? 0 : 100; if (setSpawn) { optional.ifPresent((p_213825_1_) -> { this.setSpawnPoint(p_213825_1_, false); }); } } public void wakeUp() { this.wakeUpPlayer(true, true, false); } public static Optional func_213822_a(IWorldReader p_213822_0_, BlockPos p_213822_1_, boolean p_213822_2_) { BlockState blockState = p_213822_0_.getBlockState(p_213822_1_); if (!(blockState.isBed(p_213822_0_, p_213822_1_, null))) { if (!p_213822_2_) { return Optional.empty(); } else { boolean flag = blockState.getBlock().canSpawnInBlock(); boolean flag1 = p_213822_0_.getBlockState(p_213822_1_.up()).getBlock().canSpawnInBlock(); return flag && flag1 ? Optional.of(new Vec3d((double)p_213822_1_.getX() + 0.5D, (double)p_213822_1_.getY() + 0.1D, (double)p_213822_1_.getZ() + 0.5D)) : Optional.empty(); } } else { return blockState.getBedSpawnPosition(EntityType.PLAYER, p_213822_0_, p_213822_1_, null); } } /** * Returns whether or not the player is asleep and the screen has fully faded. */ public boolean isPlayerFullyAsleep() { return this.isSleeping() && this.sleepTimer >= 100; } public int getSleepTimer() { return this.sleepTimer; } public void sendStatusMessage(ITextComponent chatComponent, boolean actionBar) { } @Deprecated //Forge: Use Dimension sensitive version public BlockPos getBedLocation() { return getBedLocation(this.dimension); } /** * A dimension aware version of getBedLocation. * @param dim The dimension to get the bed spawn for * @return The player specific spawn location for the dimension. May be null. */ public BlockPos getBedLocation(net.minecraft.world.dimension.DimensionType dim) { return dim == net.minecraft.world.dimension.DimensionType.OVERWORLD ? spawnPos : spawnPosMap.get(dim.getRegistryName()); } @Deprecated //Forge: Use Dimension sensitive version public boolean isSpawnForced() { return isSpawnForced(this.dimension); } /** * A dimension aware version of isSpawnForced. * Noramally isSpawnForced is used to determine if the respawn system should check for a bed or not. * This just extends that to be dimension aware. * @param dim The dimension to get whether to check for a bed before spawning for * @return The player specific spawn location for the dimension. May be null. */ public boolean isSpawnForced(net.minecraft.world.dimension.DimensionType dim) { return dim == net.minecraft.world.dimension.DimensionType.OVERWORLD ? spawnForced : spawnForcedMap.getOrDefault(dim.getRegistryName(), false); } @Deprecated //Forge: Use Dimension sensitive version public void setSpawnPoint(BlockPos pos, boolean forced) { setSpawnPoint(pos, forced, this.dimension); } /** * A dimension aware version of setSpawnChunk. * This functions identically, but allows you to specify which dimension to affect, rather than affecting the player's current dimension. * @param pos The spawn point to set as the player-specific spawn point for the dimension * @param forced Whether or not the respawn code should check for a bed at this location (true means it won't check for a bed) * @param dim Which dimension to apply the player-specific respawn point to */ public void setSpawnPoint(@Nullable BlockPos pos, boolean forced, net.minecraft.world.dimension.DimensionType dim) { if(net.minecraftforge.event.ForgeEventFactory.onPlayerSpawnSet(this, pos, forced)) return; if (dim != net.minecraft.world.dimension.DimensionType.OVERWORLD) { if (pos == null) { spawnPosMap.remove(dim.getRegistryName()); spawnForcedMap.remove(dim.getRegistryName()); } else { spawnPosMap.put(dim.getRegistryName(), pos); spawnForcedMap.put(dim.getRegistryName(), forced); } return; } if (pos != null) { this.spawnPos = pos; this.spawnForced = forced; } else { this.spawnPos = null; this.spawnForced = false; } } public void addStat(ResourceLocation stat) { this.addStat(Stats.CUSTOM.get(stat)); } public void addStat(ResourceLocation p_195067_1_, int p_195067_2_) { this.addStat(Stats.CUSTOM.get(p_195067_1_), p_195067_2_); } /** * Add a stat once */ public void addStat(Stat stat) { this.addStat(stat, 1); } /** * Adds a value to a statistic field. */ public void addStat(Stat stat, int amount) { } public void takeStat(Stat stat) { } public int unlockRecipes(Collection> p_195065_1_) { return 0; } public void unlockRecipes(ResourceLocation[] p_193102_1_) { } public int resetRecipes(Collection> p_195069_1_) { return 0; } /** * Causes this entity to do an upwards motion (jumping). */ public void jump() { super.jump(); this.addStat(Stats.JUMP); if (this.isSprinting()) { this.addExhaustion(0.2F); } else { this.addExhaustion(0.05F); } } public void travel(Vec3d p_213352_1_) { double d0 = this.posX; double d1 = this.posY; double d2 = this.posZ; if (this.isSwimming() && !this.isPassenger()) { double d3 = this.getLookVec().y; double d4 = d3 < -0.2D ? 0.085D : 0.06D; if (d3 <= 0.0D || this.isJumping || !this.world.getBlockState(new BlockPos(this.posX, this.posY + 1.0D - 0.1D, this.posZ)).getFluidState().isEmpty()) { Vec3d vec3d1 = this.getMotion(); this.setMotion(vec3d1.add(0.0D, (d3 - vec3d1.y) * d4, 0.0D)); } } if (this.abilities.isFlying && !this.isPassenger()) { double d5 = this.getMotion().y; float f = this.jumpMovementFactor; this.jumpMovementFactor = this.abilities.getFlySpeed() * (float)(this.isSprinting() ? 2 : 1); super.travel(p_213352_1_); Vec3d vec3d = this.getMotion(); this.setMotion(vec3d.x, d5 * 0.6D, vec3d.z); this.jumpMovementFactor = f; this.fallDistance = 0.0F; this.setFlag(7, false); } else { super.travel(p_213352_1_); } this.addMovementStat(this.posX - d0, this.posY - d1, this.posZ - d2); } public void updateSwimming() { if (this.abilities.isFlying) { this.setSwimming(false); } else { super.updateSwimming(); } } protected boolean isNormalCube(BlockPos pos) { return !this.world.getBlockState(pos).causesSuffocation(this.world, pos); } /** * the movespeed used for the new AI system */ public float getAIMoveSpeed() { return (float)this.getAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).getValue(); } /** * Adds a value to a movement statistic field - like run, walk, swin or climb. */ public void addMovementStat(double p_71000_1_, double p_71000_3_, double p_71000_5_) { if (!this.isPassenger()) { if (this.isSwimming()) { int i = Math.round(MathHelper.sqrt(p_71000_1_ * p_71000_1_ + p_71000_3_ * p_71000_3_ + p_71000_5_ * p_71000_5_) * 100.0F); if (i > 0) { this.addStat(Stats.SWIM_ONE_CM, i); this.addExhaustion(0.01F * (float)i * 0.01F); } } else if (this.areEyesInFluid(FluidTags.WATER, true)) { int j = Math.round(MathHelper.sqrt(p_71000_1_ * p_71000_1_ + p_71000_3_ * p_71000_3_ + p_71000_5_ * p_71000_5_) * 100.0F); if (j > 0) { this.addStat(Stats.WALK_UNDER_WATER_ONE_CM, j); this.addExhaustion(0.01F * (float)j * 0.01F); } } else if (this.isInWater()) { int k = Math.round(MathHelper.sqrt(p_71000_1_ * p_71000_1_ + p_71000_5_ * p_71000_5_) * 100.0F); if (k > 0) { this.addStat(Stats.WALK_ON_WATER_ONE_CM, k); this.addExhaustion(0.01F * (float)k * 0.01F); } } else if (this.isOnLadder()) { if (p_71000_3_ > 0.0D) { this.addStat(Stats.CLIMB_ONE_CM, (int)Math.round(p_71000_3_ * 100.0D)); } } else if (this.onGround) { int l = Math.round(MathHelper.sqrt(p_71000_1_ * p_71000_1_ + p_71000_5_ * p_71000_5_) * 100.0F); if (l > 0) { if (this.isSprinting()) { this.addStat(Stats.SPRINT_ONE_CM, l); this.addExhaustion(0.1F * (float)l * 0.01F); } else if (this.isSneaking()) { this.addStat(Stats.CROUCH_ONE_CM, l); this.addExhaustion(0.0F * (float)l * 0.01F); } else { this.addStat(Stats.WALK_ONE_CM, l); this.addExhaustion(0.0F * (float)l * 0.01F); } } } else if (this.isElytraFlying()) { int i1 = Math.round(MathHelper.sqrt(p_71000_1_ * p_71000_1_ + p_71000_3_ * p_71000_3_ + p_71000_5_ * p_71000_5_) * 100.0F); this.addStat(Stats.AVIATE_ONE_CM, i1); } else { int j1 = Math.round(MathHelper.sqrt(p_71000_1_ * p_71000_1_ + p_71000_5_ * p_71000_5_) * 100.0F); if (j1 > 25) { this.addStat(Stats.FLY_ONE_CM, j1); } } } } /** * Adds a value to a mounted movement statistic field - by minecart, boat, or pig. */ private void addMountedMovementStat(double p_71015_1_, double p_71015_3_, double p_71015_5_) { if (this.isPassenger()) { int i = Math.round(MathHelper.sqrt(p_71015_1_ * p_71015_1_ + p_71015_3_ * p_71015_3_ + p_71015_5_ * p_71015_5_) * 100.0F); if (i > 0) { if (this.getRidingEntity() instanceof AbstractMinecartEntity) { this.addStat(Stats.MINECART_ONE_CM, i); } else if (this.getRidingEntity() instanceof BoatEntity) { this.addStat(Stats.BOAT_ONE_CM, i); } else if (this.getRidingEntity() instanceof PigEntity) { this.addStat(Stats.PIG_ONE_CM, i); } else if (this.getRidingEntity() instanceof AbstractHorseEntity) { this.addStat(Stats.HORSE_ONE_CM, i); } } } } public void fall(float distance, float damageMultiplier) { if (!this.abilities.allowFlying) { if (distance >= 2.0F) { this.addStat(Stats.FALL_ONE_CM, (int)Math.round((double)distance * 100.0D)); } super.fall(distance, damageMultiplier); } else { net.minecraftforge.event.ForgeEventFactory.onPlayerFall(this, distance, damageMultiplier); } } /** * Plays the {@link #getSplashSound() splash sound}, and the {@link ParticleType#WATER_BUBBLE} and {@link * ParticleType#WATER_SPLASH} particles. */ protected void doWaterSplashEffect() { if (!this.isSpectator()) { super.doWaterSplashEffect(); } } protected SoundEvent getFallSound(int heightIn) { return heightIn > 4 ? SoundEvents.ENTITY_PLAYER_BIG_FALL : SoundEvents.ENTITY_PLAYER_SMALL_FALL; } /** * This method gets called when the entity kills another one. */ public void onKillEntity(LivingEntity entityLivingIn) { this.addStat(Stats.ENTITY_KILLED.get(entityLivingIn.getType())); } public void setMotionMultiplier(BlockState p_213295_1_, Vec3d p_213295_2_) { if (!this.abilities.isFlying) { super.setMotionMultiplier(p_213295_1_, p_213295_2_); } } public void giveExperiencePoints(int p_195068_1_) { this.addScore(p_195068_1_); this.experience += (float)p_195068_1_ / (float)this.xpBarCap(); this.experienceTotal = MathHelper.clamp(this.experienceTotal + p_195068_1_, 0, Integer.MAX_VALUE); while(this.experience < 0.0F) { float f = this.experience * (float)this.xpBarCap(); if (this.experienceLevel > 0) { this.addExperienceLevel(-1); this.experience = 1.0F + f / (float)this.xpBarCap(); } else { this.addExperienceLevel(-1); this.experience = 0.0F; } } while(this.experience >= 1.0F) { this.experience = (this.experience - 1.0F) * (float)this.xpBarCap(); this.addExperienceLevel(1); this.experience /= (float)this.xpBarCap(); } } public int getXPSeed() { return this.xpSeed; } public void onEnchant(ItemStack enchantedItem, int cost) { this.experienceLevel -= cost; if (this.experienceLevel < 0) { this.experienceLevel = 0; this.experience = 0.0F; this.experienceTotal = 0; } this.xpSeed = this.rand.nextInt(); } /** * Add experience levels to this player. */ public void addExperienceLevel(int levels) { this.experienceLevel += levels; if (this.experienceLevel < 0) { this.experienceLevel = 0; this.experience = 0.0F; this.experienceTotal = 0; } if (levels > 0 && this.experienceLevel % 5 == 0 && (float)this.lastXPSound < (float)this.ticksExisted - 100.0F) { float f = this.experienceLevel > 30 ? 1.0F : (float)this.experienceLevel / 30.0F; this.world.playSound((PlayerEntity)null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_PLAYER_LEVELUP, this.getSoundCategory(), f * 0.75F, 1.0F); this.lastXPSound = this.ticksExisted; } } /** * This method returns the cap amount of experience that the experience bar can hold. With each level, the experience * cap on the player's experience bar is raised by 10. */ public int xpBarCap() { if (this.experienceLevel >= 30) { return 112 + (this.experienceLevel - 30) * 9; } else { return this.experienceLevel >= 15 ? 37 + (this.experienceLevel - 15) * 5 : 7 + this.experienceLevel * 2; } } /** * increases exhaustion level by supplied amount */ public void addExhaustion(float exhaustion) { if (!this.abilities.disableDamage) { if (!this.world.isRemote) { this.foodStats.addExhaustion(exhaustion); } } } /** * Returns the player's FoodStats object. */ public FoodStats getFoodStats() { return this.foodStats; } public boolean canEat(boolean ignoreHunger) { return !this.abilities.disableDamage && (ignoreHunger || this.foodStats.needFood()); } /** * Checks if the player's health is not full and not zero. */ public boolean shouldHeal() { return this.getHealth() > 0.0F && this.getHealth() < this.getMaxHealth(); } public boolean isAllowEdit() { return this.abilities.allowEdit; } /** * Returns whether this player can modify the block at a certain location with the given stack. *

* The position being queried is {@code pos.offset(facing.getOpposite()))}. * * @return Whether this player may modify the queried location in the current world * @see ItemStack#canPlaceOn(Block) * @see ItemStack#canEditBlocks() * @see PlayerCapabilities#allowEdit */ public boolean canPlayerEdit(BlockPos pos, Direction facing, ItemStack stack) { if (this.abilities.allowEdit) { return true; } else { BlockPos blockpos = pos.offset(facing.getOpposite()); CachedBlockInfo cachedblockinfo = new CachedBlockInfo(this.world, blockpos, false); return stack.canPlaceOn(this.world.getTags(), cachedblockinfo); } } /** * Get the experience points the entity currently has. */ protected int getExperiencePoints(PlayerEntity player) { if (!this.world.getGameRules().getBoolean(GameRules.KEEP_INVENTORY) && !this.isSpectator()) { int i = this.experienceLevel * 7; return i > 100 ? 100 : i; } else { return 0; } } /** * Only use is to identify if class is an instance of player for experience dropping */ protected boolean isPlayer() { return true; } @OnlyIn(Dist.CLIENT) public boolean getAlwaysRenderNameTagForRender() { return true; } /** * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to * prevent them from trampling crops */ protected boolean canTriggerWalking() { return !this.abilities.isFlying; } /** * Sends the player's abilities to the server (if there is one). */ public void sendPlayerAbilities() { } /** * Sets the player's game mode and sends it to them. */ public void setGameType(GameType gameType) { } public ITextComponent getName() { return new StringTextComponent(this.gameProfile.getName()); } /** * Returns the InventoryEnderChest of this player. */ public EnderChestInventory getInventoryEnderChest() { return this.enterChestInventory; } public ItemStack getItemStackFromSlot(EquipmentSlotType slotIn) { if (slotIn == EquipmentSlotType.MAINHAND) { return this.inventory.getCurrentItem(); } else if (slotIn == EquipmentSlotType.OFFHAND) { return this.inventory.offHandInventory.get(0); } else { return slotIn.getSlotType() == EquipmentSlotType.Group.ARMOR ? this.inventory.armorInventory.get(slotIn.getIndex()) : ItemStack.EMPTY; } } public void setItemStackToSlot(EquipmentSlotType slotIn, ItemStack stack) { if (slotIn == EquipmentSlotType.MAINHAND) { this.playEquipSound(stack); this.inventory.mainInventory.set(this.inventory.currentItem, stack); } else if (slotIn == EquipmentSlotType.OFFHAND) { this.playEquipSound(stack); this.inventory.offHandInventory.set(0, stack); } else if (slotIn.getSlotType() == EquipmentSlotType.Group.ARMOR) { this.playEquipSound(stack); this.inventory.armorInventory.set(slotIn.getIndex(), stack); } } public boolean addItemStackToInventory(ItemStack p_191521_1_) { this.playEquipSound(p_191521_1_); return this.inventory.addItemStackToInventory(p_191521_1_); } public Iterable getHeldEquipment() { return Lists.newArrayList(this.getHeldItemMainhand(), this.getHeldItemOffhand()); } public Iterable getArmorInventoryList() { return this.inventory.armorInventory; } public boolean addShoulderEntity(CompoundNBT p_192027_1_) { if (!this.isPassenger() && this.onGround && !this.isInWater()) { if (this.getLeftShoulderEntity().isEmpty()) { this.setLeftShoulderEntity(p_192027_1_); this.field_223730_e = this.world.getGameTime(); return true; } else if (this.getRightShoulderEntity().isEmpty()) { this.setRightShoulderEntity(p_192027_1_); this.field_223730_e = this.world.getGameTime(); return true; } else { return false; } } else { return false; } } protected void spawnShoulderEntities() { if (this.field_223730_e + 20L < this.world.getGameTime()) { this.spawnShoulderEntity(this.getLeftShoulderEntity()); this.setLeftShoulderEntity(new CompoundNBT()); this.spawnShoulderEntity(this.getRightShoulderEntity()); this.setRightShoulderEntity(new CompoundNBT()); } } private void spawnShoulderEntity(CompoundNBT p_192026_1_) { if (!this.world.isRemote && !p_192026_1_.isEmpty()) { EntityType.loadEntityUnchecked(p_192026_1_, this.world).ifPresent((p_213827_1_) -> { if (p_213827_1_ instanceof TameableEntity) { ((TameableEntity)p_213827_1_).setOwnerId(this.entityUniqueID); } p_213827_1_.setPosition(this.posX, this.posY + (double)0.7F, this.posZ); ((ServerWorld)this.world).summonEntity(p_213827_1_); }); } } /** * Only used by renderer in EntityLivingBase subclasses. * Determines if an entity is visible or not to a specific player, if the entity is normally invisible. * For EntityLivingBase subclasses, returning false when invisible will render the entity semi-transparent. */ @OnlyIn(Dist.CLIENT) public boolean isInvisibleToPlayer(PlayerEntity player) { if (!this.isInvisible()) { return false; } else if (player.isSpectator()) { return false; } else { Team team = this.getTeam(); return team == null || player == null || player.getTeam() != team || !team.getSeeFriendlyInvisiblesEnabled(); } } /** * Returns true if the player is in spectator mode. */ public abstract boolean isSpectator(); public boolean isSwimming() { return !this.abilities.isFlying && !this.isSpectator() && super.isSwimming(); } public abstract boolean isCreative(); public boolean isPushedByWater() { return !this.abilities.isFlying; } public Scoreboard getWorldScoreboard() { return this.world.getScoreboard(); } public ITextComponent getDisplayName() { ITextComponent itextcomponent = new StringTextComponent(""); prefixes.forEach(e -> itextcomponent.appendSibling(e)); itextcomponent.appendSibling(ScorePlayerTeam.formatMemberName(this.getTeam(), this.getName())); suffixes.forEach(e -> itextcomponent.appendSibling(e)); return this.addTellEvent(itextcomponent); } public ITextComponent getDisplayNameAndUUID() { return (new StringTextComponent("")).appendSibling(this.getName()).appendText(" (").appendText(this.gameProfile.getId().toString()).appendText(")"); } private ITextComponent addTellEvent(ITextComponent p_208016_1_) { String s = this.getGameProfile().getName(); return p_208016_1_.applyTextStyle((p_211521_2_) -> { p_211521_2_.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/tell " + s + " ")).setHoverEvent(this.getHoverEvent()).setInsertion(s); }); } /** * Returns a String to use as this entity's name in the scoreboard/entity selector systems */ public String getScoreboardName() { return this.getGameProfile().getName(); } public float getStandingEyeHeight(Pose poseIn, EntitySize sizeIn) { switch(poseIn) { case SWIMMING: case FALL_FLYING: case SPIN_ATTACK: return 0.4F; case SNEAKING: return 1.27F; default: return 1.62F; } } public void setAbsorptionAmount(float amount) { if (amount < 0.0F) { amount = 0.0F; } this.getDataManager().set(ABSORPTION, amount); } /** * Returns the amount of health added by the Absorption effect. */ public float getAbsorptionAmount() { return this.getDataManager().get(ABSORPTION); } /** * Gets a players UUID given their GameProfie */ public static UUID getUUID(GameProfile profile) { UUID uuid = profile.getId(); if (uuid == null) { uuid = getOfflineUUID(profile.getName()); } return uuid; } public static UUID getOfflineUUID(String username) { return UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8)); } @OnlyIn(Dist.CLIENT) public boolean isWearing(PlayerModelPart part) { return (this.getDataManager().get(PLAYER_MODEL_FLAG) & part.getPartMask()) == part.getPartMask(); } public boolean replaceItemInInventory(int inventorySlot, ItemStack itemStackIn) { if (inventorySlot >= 0 && inventorySlot < this.inventory.mainInventory.size()) { this.inventory.setInventorySlotContents(inventorySlot, itemStackIn); return true; } else { EquipmentSlotType equipmentslottype; if (inventorySlot == 100 + EquipmentSlotType.HEAD.getIndex()) { equipmentslottype = EquipmentSlotType.HEAD; } else if (inventorySlot == 100 + EquipmentSlotType.CHEST.getIndex()) { equipmentslottype = EquipmentSlotType.CHEST; } else if (inventorySlot == 100 + EquipmentSlotType.LEGS.getIndex()) { equipmentslottype = EquipmentSlotType.LEGS; } else if (inventorySlot == 100 + EquipmentSlotType.FEET.getIndex()) { equipmentslottype = EquipmentSlotType.FEET; } else { equipmentslottype = null; } if (inventorySlot == 98) { this.setItemStackToSlot(EquipmentSlotType.MAINHAND, itemStackIn); return true; } else if (inventorySlot == 99) { this.setItemStackToSlot(EquipmentSlotType.OFFHAND, itemStackIn); return true; } else if (equipmentslottype == null) { int i = inventorySlot - 200; if (i >= 0 && i < this.enterChestInventory.getSizeInventory()) { this.enterChestInventory.setInventorySlotContents(i, itemStackIn); return true; } else { return false; } } else { if (!itemStackIn.isEmpty()) { if (!(itemStackIn.getItem() instanceof ArmorItem) && !(itemStackIn.getItem() instanceof ElytraItem)) { if (equipmentslottype != EquipmentSlotType.HEAD) { return false; } } else if (MobEntity.getSlotForItemStack(itemStackIn) != equipmentslottype) { return false; } } this.inventory.setInventorySlotContents(equipmentslottype.getIndex() + this.inventory.mainInventory.size(), itemStackIn); return true; } } } /** * Whether the "reducedDebugInfo" option is active for this player. */ @OnlyIn(Dist.CLIENT) public boolean hasReducedDebug() { return this.hasReducedDebug; } @OnlyIn(Dist.CLIENT) public void setReducedDebug(boolean reducedDebug) { this.hasReducedDebug = reducedDebug; } public HandSide getPrimaryHand() { return this.dataManager.get(MAIN_HAND) == 0 ? HandSide.LEFT : HandSide.RIGHT; } public void setPrimaryHand(HandSide hand) { this.dataManager.set(MAIN_HAND, (byte)(hand == HandSide.LEFT ? 0 : 1)); } public CompoundNBT getLeftShoulderEntity() { return this.dataManager.get(LEFT_SHOULDER_ENTITY); } protected void setLeftShoulderEntity(CompoundNBT tag) { this.dataManager.set(LEFT_SHOULDER_ENTITY, tag); } public CompoundNBT getRightShoulderEntity() { return this.dataManager.get(RIGHT_SHOULDER_ENTITY); } protected void setRightShoulderEntity(CompoundNBT tag) { this.dataManager.set(RIGHT_SHOULDER_ENTITY, tag); } public float getCooldownPeriod() { return (float)(1.0D / this.getAttribute(SharedMonsterAttributes.ATTACK_SPEED).getValue() * 20.0D); } /** * Returns the percentage of attack power available based on the cooldown (zero to one). */ public float getCooledAttackStrength(float adjustTicks) { return MathHelper.clamp(((float)this.ticksSinceLastSwing + adjustTicks) / this.getCooldownPeriod(), 0.0F, 1.0F); } public void resetCooldown() { this.ticksSinceLastSwing = 0; } public CooldownTracker getCooldownTracker() { return this.cooldownTracker; } public float getLuck() { return (float)this.getAttribute(SharedMonsterAttributes.LUCK).getValue(); } public boolean canUseCommandBlock() { return this.abilities.isCreativeMode && this.getPermissionLevel() >= 2; } public boolean func_213365_e(ItemStack p_213365_1_) { EquipmentSlotType equipmentslottype = MobEntity.getSlotForItemStack(p_213365_1_); return this.getItemStackFromSlot(equipmentslottype).isEmpty(); } public EntitySize getSize(Pose poseIn) { return SIZE_BY_POSE.getOrDefault(poseIn, STANDING_SIZE); } public ItemStack findAmmo(ItemStack shootable) { if (!(shootable.getItem() instanceof ShootableItem)) { return ItemStack.EMPTY; } else { Predicate predicate = ((ShootableItem)shootable.getItem()).getAmmoPredicate(); ItemStack itemstack = ShootableItem.getHeldAmmo(this, predicate); if (!itemstack.isEmpty()) { return itemstack; } else { predicate = ((ShootableItem)shootable.getItem()).getInventoryAmmoPredicate(); for(int i = 0; i < this.inventory.getSizeInventory(); ++i) { ItemStack itemstack1 = this.inventory.getStackInSlot(i); if (predicate.test(itemstack1)) { return itemstack1; } } return this.abilities.isCreativeMode ? new ItemStack(Items.ARROW) : ItemStack.EMPTY; } } } public ItemStack onFoodEaten(World p_213357_1_, ItemStack p_213357_2_) { this.getFoodStats().consume(p_213357_2_.getItem(), p_213357_2_); this.addStat(Stats.ITEM_USED.get(p_213357_2_.getItem())); p_213357_1_.playSound((PlayerEntity)null, this.posX, this.posY, this.posZ, SoundEvents.ENTITY_PLAYER_BURP, SoundCategory.PLAYERS, 0.5F, p_213357_1_.rand.nextFloat() * 0.1F + 0.9F); if (this instanceof ServerPlayerEntity) { CriteriaTriggers.CONSUME_ITEM.trigger((ServerPlayerEntity)this, p_213357_2_); } return super.onFoodEaten(p_213357_1_, p_213357_2_); } public static enum SleepResult { NOT_POSSIBLE_HERE, NOT_POSSIBLE_NOW(new TranslationTextComponent("block.minecraft.bed.no_sleep")), TOO_FAR_AWAY(new TranslationTextComponent("block.minecraft.bed.too_far_away")), OBSTRUCTED(new TranslationTextComponent("block.minecraft.bed.obstructed")), OTHER_PROBLEM, NOT_SAFE(new TranslationTextComponent("block.minecraft.bed.not_safe")); @Nullable private final ITextComponent message; private SleepResult() { this.message = null; } private SleepResult(ITextComponent msg) { this.message = msg; } @Nullable public ITextComponent getMessage() { return this.message; } } // =========== FORGE START ==============// public net.minecraft.world.dimension.DimensionType getSpawnDimension() { return this.spawnDimension; } public void setSpawnDimenion(net.minecraft.world.dimension.DimensionType dim) { this.spawnDimension = dim; } public Collection getPrefixes() { return this.prefixes; } public Collection getSuffixes() { return this.suffixes; } private final net.minecraftforge.common.util.LazyOptional playerMainHandler = net.minecraftforge.common.util.LazyOptional.of( () -> new net.minecraftforge.items.wrapper.PlayerMainInvWrapper(inventory)); private final net.minecraftforge.common.util.LazyOptional playerEquipmentHandler = net.minecraftforge.common.util.LazyOptional.of( () -> new net.minecraftforge.items.wrapper.CombinedInvWrapper( new net.minecraftforge.items.wrapper.PlayerArmorInvWrapper(inventory), new net.minecraftforge.items.wrapper.PlayerOffhandInvWrapper(inventory))); private final net.minecraftforge.common.util.LazyOptional playerJoinedHandler = net.minecraftforge.common.util.LazyOptional.of( () -> new net.minecraftforge.items.wrapper.PlayerInvWrapper(inventory)); @Override public net.minecraftforge.common.util.LazyOptional getCapability(net.minecraftforge.common.capabilities.Capability capability, @Nullable Direction facing) { if (this.isAlive() && capability == net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) { if (facing == null) return playerJoinedHandler.cast(); else if (facing.getAxis().isVertical()) return playerMainHandler.cast(); else if (facing.getAxis().isHorizontal()) return playerEquipmentHandler.cast(); } return super.getCapability(capability, facing); } }