net/minecraft/world/entity/item
This commit is contained in:
@@ -1,162 +0,0 @@
|
||||
--- a/net/minecraft/world/entity/item/FallingBlockEntity.java
|
||||
+++ b/net/minecraft/world/entity/item/FallingBlockEntity.java
|
||||
@@ -52,6 +52,11 @@
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
+// CraftBukkit start;
|
||||
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+// CraftBukkit end
|
||||
+
|
||||
public class FallingBlockEntity extends Entity {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
@@ -66,6 +71,7 @@
|
||||
public CompoundTag blockData;
|
||||
public boolean forceTickAfterTeleportToDuplicate;
|
||||
protected static final EntityDataAccessor<BlockPos> DATA_START_POS = SynchedEntityData.defineId(FallingBlockEntity.class, EntityDataSerializers.BLOCK_POS);
|
||||
+ public boolean autoExpire = true; // Paper - Expand FallingBlock API
|
||||
|
||||
public FallingBlockEntity(EntityType<? extends FallingBlockEntity> type, Level world) {
|
||||
super(type, world);
|
||||
@@ -87,10 +93,17 @@
|
||||
}
|
||||
|
||||
public static FallingBlockEntity fall(Level world, BlockPos pos, BlockState state) {
|
||||
- FallingBlockEntity entityfallingblock = new FallingBlockEntity(world, (double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D, state.hasProperty(BlockStateProperties.WATERLOGGED) ? (BlockState) state.setValue(BlockStateProperties.WATERLOGGED, false) : state);
|
||||
+ // CraftBukkit start
|
||||
+ return FallingBlockEntity.fall(world, pos, state, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT);
|
||||
+ }
|
||||
|
||||
- world.setBlock(pos, state.getFluidState().createLegacyBlock(), 3);
|
||||
- world.addFreshEntity(entityfallingblock);
|
||||
+ public static FallingBlockEntity fall(Level world, BlockPos blockposition, BlockState iblockdata, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) {
|
||||
+ // CraftBukkit end
|
||||
+ FallingBlockEntity entityfallingblock = new FallingBlockEntity(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, iblockdata.hasProperty(BlockStateProperties.WATERLOGGED) ? (BlockState) iblockdata.setValue(BlockStateProperties.WATERLOGGED, false) : iblockdata);
|
||||
+ if (!CraftEventFactory.callEntityChangeBlockEvent(entityfallingblock, blockposition, iblockdata.getFluidState().createLegacyBlock())) return entityfallingblock; // CraftBukkit
|
||||
+
|
||||
+ world.setBlock(blockposition, iblockdata.getFluidState().createLegacyBlock(), 3);
|
||||
+ world.addFreshEntity(entityfallingblock, spawnReason); // CraftBukkit
|
||||
return entityfallingblock;
|
||||
}
|
||||
|
||||
@@ -139,7 +152,7 @@
|
||||
@Override
|
||||
public void tick() {
|
||||
if (this.blockState.isAir()) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
} else {
|
||||
Block block = this.blockState.getBlock();
|
||||
|
||||
@@ -147,6 +160,16 @@
|
||||
this.applyGravity();
|
||||
this.move(MoverType.SELF, this.getDeltaMovement());
|
||||
this.applyEffectsFromBlocks();
|
||||
+ // Paper start - Configurable falling blocks height nerf
|
||||
+ if (this.level().paperConfig().fixes.fallingBlockHeightNerf.test(v -> this.getY() > v)) {
|
||||
+ if (this.dropItem && this.level() instanceof final ServerLevel serverLevel && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) {
|
||||
+ this.spawnAtLocation(serverLevel, block);
|
||||
+ }
|
||||
+
|
||||
+ this.discard(EntityRemoveEvent.Cause.OUT_OF_WORLD);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Configurable falling blocks height nerf
|
||||
this.handlePortal();
|
||||
Level world = this.level();
|
||||
|
||||
@@ -169,12 +192,12 @@
|
||||
}
|
||||
|
||||
if (!this.onGround() && !flag1) {
|
||||
- if (this.time > 100 && (blockposition.getY() <= this.level().getMinY() || blockposition.getY() > this.level().getMaxY()) || this.time > 600) {
|
||||
+ if ((this.time > 100 && autoExpire) && (blockposition.getY() <= this.level().getMinY() || blockposition.getY() > this.level().getMaxY()) || (this.time > 600 && autoExpire)) { // Paper - Expand FallingBlock API
|
||||
if (this.dropItem && worldserver.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) {
|
||||
this.spawnAtLocation(worldserver, (ItemLike) block);
|
||||
}
|
||||
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
} else {
|
||||
BlockState iblockdata = this.level().getBlockState(blockposition);
|
||||
@@ -191,9 +214,15 @@
|
||||
this.blockState = (BlockState) this.blockState.setValue(BlockStateProperties.WATERLOGGED, true);
|
||||
}
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ if (!CraftEventFactory.callEntityChangeBlockEvent(this, blockposition, this.blockState)) {
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // SPIGOT-6586 called before the event in previous versions
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
if (this.level().setBlock(blockposition, this.blockState, 3)) {
|
||||
((ServerLevel) this.level()).getChunkSource().chunkMap.broadcast(this, new ClientboundBlockUpdatePacket(blockposition, this.level().getBlockState(blockposition)));
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
if (block instanceof Fallable) {
|
||||
((Fallable) block).onLand(this.level(), blockposition, this.blockState, iblockdata, this);
|
||||
}
|
||||
@@ -221,19 +250,19 @@
|
||||
}
|
||||
}
|
||||
} else if (this.dropItem && worldserver.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
|
||||
this.callOnBrokenAfterFall(block, blockposition);
|
||||
this.spawnAtLocation(worldserver, (ItemLike) block);
|
||||
}
|
||||
} else {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause
|
||||
if (this.dropItem && worldserver.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) {
|
||||
this.callOnBrokenAfterFall(block, blockposition);
|
||||
this.spawnAtLocation(worldserver, (ItemLike) block);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
this.callOnBrokenAfterFall(block, blockposition);
|
||||
}
|
||||
}
|
||||
@@ -310,6 +339,7 @@
|
||||
}
|
||||
|
||||
nbt.putBoolean("CancelDrop", this.cancelDrop);
|
||||
+ if (!autoExpire) {nbt.putBoolean("Paper.AutoExpire", false);} // Paper - Expand FallingBlock API
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -328,7 +358,7 @@
|
||||
this.dropItem = nbt.getBoolean("DropItem");
|
||||
}
|
||||
|
||||
- if (nbt.contains("TileEntityData", 10)) {
|
||||
+ if (nbt.contains("TileEntityData", 10) && !(this.level().paperConfig().entities.spawning.filterBadTileEntityNbtFromFallingBlocks && this.blockState.getBlock() instanceof net.minecraft.world.level.block.GameMasterBlock)) { // Paper - Filter bad block entity nbt data from falling blocks
|
||||
this.blockData = nbt.getCompound("TileEntityData").copy();
|
||||
}
|
||||
|
||||
@@ -337,6 +367,11 @@
|
||||
this.blockState = Blocks.SAND.defaultBlockState();
|
||||
}
|
||||
|
||||
+ // Paper start - Expand FallingBlock API
|
||||
+ if (nbt.contains("Paper.AutoExpire")) {
|
||||
+ this.autoExpire = nbt.getBoolean("Paper.AutoExpire");
|
||||
+ }
|
||||
+ // Paper end - Expand FallingBlock API
|
||||
}
|
||||
|
||||
public void setHurtsEntities(float fallHurtAmount, int fallHurtMax) {
|
||||
@@ -395,7 +430,7 @@
|
||||
boolean flag = (resourcekey1 == Level.END || resourcekey == Level.END) && resourcekey1 != resourcekey;
|
||||
Entity entity = super.teleport(teleportTarget);
|
||||
|
||||
- this.forceTickAfterTeleportToDuplicate = entity != null && flag;
|
||||
+ this.forceTickAfterTeleportToDuplicate = entity != null && flag && io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowUnsafeEndPortalTeleportation; // Paper
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
@@ -1,389 +0,0 @@
|
||||
--- a/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -5,18 +5,6 @@
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
-import net.minecraft.core.BlockPos;
|
||||
-import net.minecraft.nbt.CompoundTag;
|
||||
-import net.minecraft.network.chat.Component;
|
||||
-import net.minecraft.network.syncher.EntityDataAccessor;
|
||||
-import net.minecraft.network.syncher.EntityDataSerializers;
|
||||
-import net.minecraft.network.syncher.SynchedEntityData;
|
||||
-import net.minecraft.server.level.ServerLevel;
|
||||
-import net.minecraft.sounds.SoundSource;
|
||||
-import net.minecraft.stats.Stats;
|
||||
-import net.minecraft.tags.FluidTags;
|
||||
-import net.minecraft.tags.ItemTags;
|
||||
-import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
@@ -24,7 +12,6 @@
|
||||
import net.minecraft.world.entity.MoverType;
|
||||
import net.minecraft.world.entity.SlotAccess;
|
||||
import net.minecraft.world.entity.TraceableEntity;
|
||||
-import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
@@ -33,6 +20,27 @@
|
||||
import net.minecraft.world.level.gameevent.GameEvent;
|
||||
import net.minecraft.world.level.portal.TeleportTransition;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.network.chat.Component;
|
||||
+import net.minecraft.network.syncher.EntityDataAccessor;
|
||||
+import net.minecraft.network.syncher.EntityDataSerializers;
|
||||
+import net.minecraft.network.syncher.SynchedEntityData;
|
||||
+// CraftBukkit start
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.sounds.SoundSource;
|
||||
+import net.minecraft.stats.Stats;
|
||||
+import net.minecraft.tags.FluidTags;
|
||||
+import net.minecraft.tags.ItemTags;
|
||||
+import net.minecraft.util.Mth;
|
||||
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.entity.EntityPickupItemEvent;
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+import org.bukkit.event.player.PlayerPickupItemEvent;
|
||||
+// CraftBukkit end
|
||||
+import org.bukkit.event.player.PlayerAttemptPickupItemEvent; // Paper
|
||||
|
||||
public class ItemEntity extends Entity implements TraceableEntity {
|
||||
|
||||
@@ -52,6 +60,10 @@
|
||||
@Nullable
|
||||
public UUID target;
|
||||
public final float bobOffs;
|
||||
+ // private int lastTick = MinecraftServer.currentTick - 1; // CraftBukkit // Paper - remove anti tick skipping measures / wall time
|
||||
+ public boolean canMobPickup = true; // Paper - Item#canEntityPickup
|
||||
+ private int despawnRate = -1; // Paper - Alternative item-despawn-rate
|
||||
+ public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API
|
||||
|
||||
public ItemEntity(EntityType<? extends ItemEntity> type, Level world) {
|
||||
super(type, world);
|
||||
@@ -61,7 +73,12 @@
|
||||
}
|
||||
|
||||
public ItemEntity(Level world, double x, double y, double z, ItemStack stack) {
|
||||
- this(world, x, y, z, stack, world.random.nextDouble() * 0.2D - 0.1D, 0.2D, world.random.nextDouble() * 0.2D - 0.1D);
|
||||
+ // Paper start - Don't use level random in entity constructors (to make them thread-safe)
|
||||
+ this(EntityType.ITEM, world);
|
||||
+ this.setPos(x, y, z);
|
||||
+ this.setDeltaMovement(this.random.nextDouble() * 0.2D - 0.1D, 0.2D, this.random.nextDouble() * 0.2D - 0.1D);
|
||||
+ this.setItem(stack);
|
||||
+ // Paper end - Don't use level random in entity constructors
|
||||
}
|
||||
|
||||
public ItemEntity(Level world, double x, double y, double z, ItemStack stack, double velocityX, double velocityY, double velocityZ) {
|
||||
@@ -133,12 +150,14 @@
|
||||
@Override
|
||||
public void tick() {
|
||||
if (this.getItem().isEmpty()) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
} else {
|
||||
super.tick();
|
||||
+ // Paper start - remove anti tick skipping measures / wall time - revert to vanilla
|
||||
if (this.pickupDelay > 0 && this.pickupDelay != 32767) {
|
||||
--this.pickupDelay;
|
||||
}
|
||||
+ // Paper end - remove anti tick skipping measures / wall time - revert to vanilla
|
||||
|
||||
this.xo = this.getX();
|
||||
this.yo = this.getY();
|
||||
@@ -162,12 +181,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
- if (!this.onGround() || this.getDeltaMovement().horizontalDistanceSqr() > 9.999999747378752E-6D || (this.tickCount + this.getId()) % 4 == 0) {
|
||||
+ if (!this.onGround() || this.getDeltaMovement().horizontalDistanceSqr() > 9.999999747378752E-6D || (this.tickCount + this.getId()) % 4 == 0) { // Paper - Diff on change; ActivationRange immunity
|
||||
this.move(MoverType.SELF, this.getDeltaMovement());
|
||||
this.applyEffectsFromBlocks();
|
||||
float f = 0.98F;
|
||||
|
||||
- if (this.onGround()) {
|
||||
+ // Paper start - Friction API
|
||||
+ if (frictionState == net.kyori.adventure.util.TriState.FALSE) {
|
||||
+ f = 1F;
|
||||
+ } else if (this.onGround()) {
|
||||
+ // Paper end - Friction API
|
||||
f = this.level().getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getBlock().getFriction() * 0.98F;
|
||||
}
|
||||
|
||||
@@ -188,9 +211,11 @@
|
||||
this.mergeWithNeighbours();
|
||||
}
|
||||
|
||||
+ // Paper - remove anti tick skipping measures / wall time - revert to vanilla /* CraftBukkit start - moved up
|
||||
if (this.age != -32768) {
|
||||
++this.age;
|
||||
}
|
||||
+ // CraftBukkit end */
|
||||
|
||||
this.hasImpulse |= this.updateInWaterStateAndDoFluidPushing();
|
||||
if (!this.level().isClientSide) {
|
||||
@@ -201,14 +226,44 @@
|
||||
}
|
||||
}
|
||||
|
||||
- if (!this.level().isClientSide && this.age >= 6000) {
|
||||
- this.discard();
|
||||
+ if (!this.level().isClientSide && this.age >= this.despawnRate) { // Spigot // Paper - Alternative item-despawn-rate
|
||||
+ // CraftBukkit start - fire ItemDespawnEvent
|
||||
+ if (CraftEventFactory.callItemDespawnEvent(this).isCancelled()) {
|
||||
+ this.age = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+ // Spigot start - copied from above
|
||||
@Override
|
||||
+ public void inactiveTick() {
|
||||
+ // Paper start - remove anti tick skipping measures / wall time - copied from above
|
||||
+ if (this.pickupDelay > 0 && this.pickupDelay != 32767) {
|
||||
+ --this.pickupDelay;
|
||||
+ }
|
||||
+ if (this.age != -32768) {
|
||||
+ ++this.age;
|
||||
+ }
|
||||
+ // Paper end - remove anti tick skipping measures / wall time - copied from above
|
||||
+
|
||||
+ if (!this.level().isClientSide && this.age >= this.despawnRate) { // Spigot // Paper - Alternative item-despawn-rate
|
||||
+ // CraftBukkit start - fire ItemDespawnEvent
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) {
|
||||
+ this.age = 0;
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
|
||||
+ }
|
||||
+ }
|
||||
+ // Spigot end
|
||||
+
|
||||
+ @Override
|
||||
public BlockPos getBlockPosBelowThatAffectsMyMovement() {
|
||||
return this.getOnPos(0.999999F);
|
||||
}
|
||||
@@ -229,7 +284,10 @@
|
||||
|
||||
private void mergeWithNeighbours() {
|
||||
if (this.isMergable()) {
|
||||
- List<ItemEntity> list = this.level().getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate(0.5D, 0.0D, 0.5D), (entityitem) -> {
|
||||
+ // Spigot start
|
||||
+ double radius = this.level().spigotConfig.itemMerge;
|
||||
+ List<ItemEntity> list = this.level().getEntitiesOfClass(ItemEntity.class, this.getBoundingBox().inflate(radius, this.level().paperConfig().entities.behavior.onlyMergeItemsHorizontally ? 0 : radius - 0.5D, radius), (entityitem) -> { // Paper - configuration to only merge items horizontally
|
||||
+ // Spigot end
|
||||
return entityitem != this && entityitem.isMergable();
|
||||
});
|
||||
Iterator iterator = list.iterator();
|
||||
@@ -238,6 +296,14 @@
|
||||
ItemEntity entityitem = (ItemEntity) iterator.next();
|
||||
|
||||
if (entityitem.isMergable()) {
|
||||
+ // Paper start - Fix items merging through walls
|
||||
+ if (this.level().paperConfig().fixes.fixItemsMergingThroughWalls) {
|
||||
+ if (this.level().clipDirect(this.position(), entityitem.position(),
|
||||
+ net.minecraft.world.phys.shapes.CollisionContext.of(this)) == net.minecraft.world.phys.HitResult.Type.BLOCK) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Fix items merging through walls
|
||||
this.tryToMerge(entityitem);
|
||||
if (this.isRemoved()) {
|
||||
break;
|
||||
@@ -251,7 +317,7 @@
|
||||
private boolean isMergable() {
|
||||
ItemStack itemstack = this.getItem();
|
||||
|
||||
- return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < 6000 && itemstack.getCount() < itemstack.getMaxStackSize();
|
||||
+ return this.isAlive() && this.pickupDelay != 32767 && this.age != -32768 && this.age < this.despawnRate && itemstack.getCount() < itemstack.getMaxStackSize(); // Paper - Alternative item-despawn-rate
|
||||
}
|
||||
|
||||
private void tryToMerge(ItemEntity other) {
|
||||
@@ -259,7 +325,7 @@
|
||||
ItemStack itemstack1 = other.getItem();
|
||||
|
||||
if (Objects.equals(this.target, other.target) && ItemEntity.areMergable(itemstack, itemstack1)) {
|
||||
- if (itemstack1.getCount() < itemstack.getCount()) {
|
||||
+ if (true || itemstack1.getCount() < itemstack.getCount()) { // Spigot
|
||||
ItemEntity.merge(this, itemstack, other, itemstack1);
|
||||
} else {
|
||||
ItemEntity.merge(other, itemstack1, this, itemstack);
|
||||
@@ -287,11 +353,16 @@
|
||||
}
|
||||
|
||||
private static void merge(ItemEntity targetEntity, ItemStack targetStack, ItemEntity sourceEntity, ItemStack sourceStack) {
|
||||
+ // CraftBukkit start
|
||||
+ if (!CraftEventFactory.callItemMergeEvent(sourceEntity, targetEntity)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
ItemEntity.merge(targetEntity, targetStack, sourceStack);
|
||||
targetEntity.pickupDelay = Math.max(targetEntity.pickupDelay, sourceEntity.pickupDelay);
|
||||
targetEntity.age = Math.min(targetEntity.age, sourceEntity.age);
|
||||
if (sourceStack.isEmpty()) {
|
||||
- sourceEntity.discard();
|
||||
+ sourceEntity.discard(EntityRemoveEvent.Cause.MERGE); // CraftBukkit - add Bukkit remove cause);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -320,12 +391,17 @@
|
||||
} else if (!this.getItem().canBeHurtBy(source)) {
|
||||
return false;
|
||||
} else {
|
||||
+ // CraftBukkit start
|
||||
+ if (CraftEventFactory.handleNonLivingEntityDamageEvent(this, source, amount)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
this.markHurt();
|
||||
this.health = (int) ((float) this.health - amount);
|
||||
this.gameEvent(GameEvent.ENTITY_DAMAGE, source.getEntity());
|
||||
if (this.health <= 0) {
|
||||
this.getItem().onDestroyed(this);
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -339,6 +415,11 @@
|
||||
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag nbt) {
|
||||
+ // Paper start - Friction API
|
||||
+ if (this.frictionState != net.kyori.adventure.util.TriState.NOT_SET) {
|
||||
+ nbt.putString("Paper.FrictionState", this.frictionState.toString());
|
||||
+ }
|
||||
+ // Paper end - Friction API
|
||||
nbt.putShort("Health", (short) this.health);
|
||||
nbt.putShort("Age", (short) this.age);
|
||||
nbt.putShort("PickupDelay", (short) this.pickupDelay);
|
||||
@@ -381,23 +462,98 @@
|
||||
this.setItem(ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
+ // Paper start - Friction API
|
||||
+ if (nbt.contains("Paper.FrictionState")) {
|
||||
+ String fs = nbt.getString("Paper.FrictionState");
|
||||
+ try {
|
||||
+ frictionState = net.kyori.adventure.util.TriState.valueOf(fs);
|
||||
+ } catch (Exception ignored) {
|
||||
+ com.mojang.logging.LogUtils.getLogger().error("Unknown friction state " + fs + " for " + this);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Friction API
|
||||
+
|
||||
if (this.getItem().isEmpty()) {
|
||||
- this.discard();
|
||||
+ this.discard(null); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void playerTouch(Player player) {
|
||||
+ public void playerTouch(net.minecraft.world.entity.player.Player player) {
|
||||
if (!this.level().isClientSide) {
|
||||
ItemStack itemstack = this.getItem();
|
||||
Item item = itemstack.getItem();
|
||||
int i = itemstack.getCount();
|
||||
+
|
||||
+ // CraftBukkit start - fire PlayerPickupItemEvent
|
||||
+ int canHold = player.getInventory().canHold(itemstack);
|
||||
+ int remaining = i - canHold;
|
||||
+ boolean flyAtPlayer = false; // Paper
|
||||
+
|
||||
+ // Paper start - PlayerAttemptPickupItemEvent
|
||||
+ if (this.pickupDelay <= 0) {
|
||||
+ PlayerAttemptPickupItemEvent attemptEvent = new PlayerAttemptPickupItemEvent((org.bukkit.entity.Player) player.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining);
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(attemptEvent);
|
||||
+
|
||||
+ flyAtPlayer = attemptEvent.getFlyAtPlayer();
|
||||
+ if (attemptEvent.isCancelled()) {
|
||||
+ if (flyAtPlayer) {
|
||||
+ player.take(this, i);
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - PlayerAttemptPickupItemEvent
|
||||
|
||||
+ if (this.pickupDelay <= 0 && canHold > 0) {
|
||||
+ itemstack.setCount(canHold);
|
||||
+ // Call legacy event
|
||||
+ PlayerPickupItemEvent playerEvent = new PlayerPickupItemEvent((Player) player.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining);
|
||||
+ playerEvent.setCancelled(!playerEvent.getPlayer().getCanPickupItems());
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(playerEvent);
|
||||
+ flyAtPlayer = playerEvent.getFlyAtPlayer(); // Paper
|
||||
+ if (playerEvent.isCancelled()) {
|
||||
+ itemstack.setCount(i); // SPIGOT-5294 - restore count
|
||||
+ // Paper start
|
||||
+ if (flyAtPlayer) {
|
||||
+ player.take(this, i);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // Call newer event afterwards
|
||||
+ EntityPickupItemEvent entityEvent = new EntityPickupItemEvent((Player) player.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining);
|
||||
+ entityEvent.setCancelled(!entityEvent.getEntity().getCanPickupItems());
|
||||
+ this.level().getCraftServer().getPluginManager().callEvent(entityEvent);
|
||||
+ if (entityEvent.isCancelled()) {
|
||||
+ itemstack.setCount(i); // SPIGOT-5294 - restore count
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // Update the ItemStack if it was changed in the event
|
||||
+ ItemStack current = this.getItem();
|
||||
+ if (!itemstack.equals(current)) {
|
||||
+ itemstack = current;
|
||||
+ } else {
|
||||
+ itemstack.setCount(canHold + remaining); // = i
|
||||
+ }
|
||||
+
|
||||
+ // Possibly < 0; fix here so we do not have to modify code below
|
||||
+ this.pickupDelay = 0;
|
||||
+ } else if (this.pickupDelay == 0) {
|
||||
+ // ensure that the code below isn't triggered if canHold says we can't pick the items up
|
||||
+ this.pickupDelay = -1;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
if (this.pickupDelay == 0 && (this.target == null || this.target.equals(player.getUUID())) && player.getInventory().add(itemstack)) {
|
||||
+ if (flyAtPlayer) // Paper - PlayerPickupItemEvent
|
||||
player.take(this, i);
|
||||
if (itemstack.isEmpty()) {
|
||||
- this.discard();
|
||||
+ this.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
|
||||
itemstack.setCount(i);
|
||||
}
|
||||
|
||||
@@ -438,6 +594,7 @@
|
||||
|
||||
public void setItem(ItemStack stack) {
|
||||
this.getEntityData().set(ItemEntity.DATA_ITEM, stack);
|
||||
+ this.despawnRate = this.level().paperConfig().entities.spawning.altItemDespawnRate.enabled ? this.level().paperConfig().entities.spawning.altItemDespawnRate.items.getOrDefault(stack.getItem(), this.level().spigotConfig.itemDespawnRate) : this.level().spigotConfig.itemDespawnRate; // Paper - Alternative item-despawn-rate
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -492,7 +649,7 @@
|
||||
|
||||
public void makeFakeItem() {
|
||||
this.setNeverPickUp();
|
||||
- this.age = 5999;
|
||||
+ this.age = this.despawnRate - 1; // Spigot // Paper - Alternative item-despawn-rate
|
||||
}
|
||||
|
||||
public static float getSpin(float f, float f1) {
|
||||
@@ -1,116 +0,0 @@
|
||||
--- a/net/minecraft/world/entity/item/PrimedTnt.java
|
||||
+++ b/net/minecraft/world/entity/item/PrimedTnt.java
|
||||
@@ -27,6 +27,12 @@
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.portal.TeleportTransition;
|
||||
|
||||
+// CraftBukkit start;
|
||||
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||
+import org.bukkit.event.entity.EntityRemoveEvent;
|
||||
+import org.bukkit.event.entity.ExplosionPrimeEvent;
|
||||
+// CraftBukkit end
|
||||
+
|
||||
public class PrimedTnt extends Entity implements TraceableEntity {
|
||||
|
||||
private static final EntityDataAccessor<Integer> DATA_FUSE_ID = SynchedEntityData.defineId(PrimedTnt.class, EntityDataSerializers.INT);
|
||||
@@ -51,6 +57,7 @@
|
||||
public LivingEntity owner;
|
||||
private boolean usedPortal;
|
||||
public float explosionPower;
|
||||
+ public boolean isIncendiary = false; // CraftBukkit - add field
|
||||
|
||||
public PrimedTnt(EntityType<? extends PrimedTnt> type, Level world) {
|
||||
super(type, world);
|
||||
@@ -61,7 +68,7 @@
|
||||
public PrimedTnt(Level world, double x, double y, double z, @Nullable LivingEntity igniter) {
|
||||
this(EntityType.TNT, world);
|
||||
this.setPos(x, y, z);
|
||||
- double d3 = world.random.nextDouble() * 6.2831854820251465D;
|
||||
+ double d3 = this.random.nextDouble() * 6.2831854820251465D; // Paper - Don't use level random in entity constructors
|
||||
|
||||
this.setDeltaMovement(-Math.sin(d3) * 0.02D, 0.20000000298023224D, -Math.cos(d3) * 0.02D);
|
||||
this.setFuse(80);
|
||||
@@ -94,10 +101,17 @@
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
+ if (this.level().spigotConfig.maxTntTicksPerTick > 0 && ++this.level().spigotConfig.currentPrimedTnt > this.level().spigotConfig.maxTntTicksPerTick) { return; } // Spigot
|
||||
this.handlePortal();
|
||||
this.applyGravity();
|
||||
this.move(MoverType.SELF, this.getDeltaMovement());
|
||||
this.applyEffectsFromBlocks();
|
||||
+ // Paper start - Configurable TNT height nerf
|
||||
+ if (this.level().paperConfig().fixes.tntEntityHeightNerf.test(v -> this.getY() > v)) {
|
||||
+ this.discard(EntityRemoveEvent.Cause.OUT_OF_WORLD);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Configurable TNT height nerf
|
||||
this.setDeltaMovement(this.getDeltaMovement().scale(0.98D));
|
||||
if (this.onGround()) {
|
||||
this.setDeltaMovement(this.getDeltaMovement().multiply(0.7D, -0.5D, 0.7D));
|
||||
@@ -107,10 +121,13 @@
|
||||
|
||||
this.setFuse(i);
|
||||
if (i <= 0) {
|
||||
- this.discard();
|
||||
+ // CraftBukkit start - Need to reverse the order of the explosion and the entity death so we have a location for the event
|
||||
+ // this.discard();
|
||||
if (!this.level().isClientSide) {
|
||||
this.explode();
|
||||
}
|
||||
+ this.discard(EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause
|
||||
+ // CraftBukkit end
|
||||
} else {
|
||||
this.updateInWaterStateAndDoFluidPushing();
|
||||
if (this.level().isClientSide) {
|
||||
@@ -118,10 +135,37 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Option to prevent TNT from moving in water
|
||||
+ if (!this.isRemoved() && this.wasTouchingWater && this.level().paperConfig().fixes.preventTntFromMovingInWater) {
|
||||
+ /*
|
||||
+ * Author: Jedediah Smith <jedediah@silencegreys.com>
|
||||
+ */
|
||||
+ // Send position and velocity updates to nearby players on every tick while the TNT is in water.
|
||||
+ // This does pretty well at keeping their clients in sync with the server.
|
||||
+ net.minecraft.server.level.ChunkMap.TrackedEntity ete = ((net.minecraft.server.level.ServerLevel) this.level()).getChunkSource().chunkMap.entityMap.get(this.getId());
|
||||
+ if (ete != null) {
|
||||
+ net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket velocityPacket = new net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket(this);
|
||||
+ net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket positionPacket = net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket.teleport(this.getId(), net.minecraft.world.entity.PositionMoveRotation.of(this), java.util.Set.of(), this.onGround);
|
||||
+
|
||||
+ ete.seenBy.stream()
|
||||
+ .filter(viewer -> (viewer.getPlayer().getX() - this.getX()) * (viewer.getPlayer().getY() - this.getY()) * (viewer.getPlayer().getZ() - this.getZ()) < 16 * 16)
|
||||
+ .forEach(viewer -> {
|
||||
+ viewer.send(velocityPacket);
|
||||
+ viewer.send(positionPacket);
|
||||
+ });
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Option to prevent TNT from moving in water
|
||||
}
|
||||
|
||||
private void explode() {
|
||||
- this.level().explode(this, Explosion.getDefaultDamageSource(this.level(), this), this.usedPortal ? PrimedTnt.USED_PORTAL_DAMAGE_CALCULATOR : null, this.getX(), this.getY(0.0625D), this.getZ(), this.explosionPower, false, Level.ExplosionInteraction.TNT);
|
||||
+ // CraftBukkit start
|
||||
+ ExplosionPrimeEvent event = CraftEventFactory.callExplosionPrimeEvent((org.bukkit.entity.Explosive) this.getBukkitEntity());
|
||||
+ if (event.isCancelled()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ this.level().explode(this, Explosion.getDefaultDamageSource(this.level(), this), this.usedPortal ? PrimedTnt.USED_PORTAL_DAMAGE_CALCULATOR : null, this.getX(), this.getY(0.0625D), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.TNT);
|
||||
+ // CraftBukkit end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -198,4 +242,11 @@
|
||||
public final boolean hurtServer(ServerLevel world, DamageSource source, float amount) {
|
||||
return false;
|
||||
}
|
||||
+
|
||||
+ // Paper start - Option to prevent TNT from moving in water
|
||||
+ @Override
|
||||
+ public boolean isPushedByFluid() {
|
||||
+ return !level().paperConfig().fixes.preventTntFromMovingInWater && super.isPushedByFluid();
|
||||
+ }
|
||||
+ // Paper end - Option to prevent TNT from moving in water
|
||||
}
|
||||
Reference in New Issue
Block a user