mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-15 14:13:56 +01:00
Restore vanilla entity drops behavior
Instead of just tracking the itemstacks, this tracks with it, the action to take with that itemstack to apply the correct logic on dropping the item instead of generalizing it for all dropped items like CB does.
This commit is contained in:
parent
ec3623bcc2
commit
ddbfcd4403
7 changed files with 141 additions and 108 deletions
|
@ -622,7 +622,7 @@
|
||||||
+ if (this.isRemoved()) {
|
+ if (this.isRemoved()) {
|
||||||
+ return;
|
+ return;
|
||||||
+ }
|
+ }
|
||||||
+ java.util.List<org.bukkit.inventory.ItemStack> loot = new java.util.ArrayList<>(this.getInventory().getContainerSize());
|
+ List<DefaultDrop> loot = new java.util.ArrayList<>(this.getInventory().getContainerSize()); // Paper - Restore vanilla drops behavior
|
||||||
+ boolean keepInventory = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || this.isSpectator();
|
+ boolean keepInventory = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || this.isSpectator();
|
||||||
|
|
||||||
- if (flag) {
|
- if (flag) {
|
||||||
|
@ -630,14 +630,14 @@
|
||||||
+ if (!keepInventory) {
|
+ if (!keepInventory) {
|
||||||
+ for (ItemStack item : this.getInventory().getContents()) {
|
+ for (ItemStack item : this.getInventory().getContents()) {
|
||||||
+ if (!item.isEmpty() && !EnchantmentHelper.has(item, EnchantmentEffectComponents.PREVENT_EQUIPMENT_DROP)) {
|
+ if (!item.isEmpty() && !EnchantmentHelper.has(item, EnchantmentEffectComponents.PREVENT_EQUIPMENT_DROP)) {
|
||||||
+ loot.add(CraftItemStack.asCraftMirror(item).markForInventoryDrop());
|
+ loot.add(new DefaultDrop(item, stack -> this.drop(stack, true, false, false))); // Paper - Restore vanilla drops behavior; drop function taken from Inventory#dropAll (don't fire drop event)
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+ if (this.shouldDropLoot() && this.serverLevel().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - fix player loottables running when mob loot gamerule is false
|
+ if (this.shouldDropLoot() && this.serverLevel().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - fix player loottables running when mob loot gamerule is false
|
||||||
+ // SPIGOT-5071: manually add player loot tables (SPIGOT-5195 - ignores keepInventory rule)
|
+ // SPIGOT-5071: manually add player loot tables (SPIGOT-5195 - ignores keepInventory rule)
|
||||||
+ this.dropFromLootTable(this.serverLevel(), damageSource, this.lastHurtByPlayerTime > 0);
|
+ this.dropFromLootTable(this.serverLevel(), damageSource, this.lastHurtByPlayerTime > 0);
|
||||||
+ this.dropCustomDeathLoot(this.serverLevel(), damageSource, flag);
|
+ // Paper - Restore vanilla drops behaviour; custom death loot is a noop on server player, remove.
|
||||||
|
|
||||||
+ loot.addAll(this.drops);
|
+ loot.addAll(this.drops);
|
||||||
+ this.drops.clear(); // SPIGOT-5188: make sure to clear
|
+ this.drops.clear(); // SPIGOT-5188: make sure to clear
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.block.FenceGateBlock;
|
import net.minecraft.world.level.block.FenceGateBlock;
|
||||||
@@ -138,8 +138,152 @@
|
@@ -138,9 +138,153 @@
|
||||||
import net.minecraft.world.scores.ScoreHolder;
|
import net.minecraft.world.scores.ScoreHolder;
|
||||||
import net.minecraft.world.scores.Team;
|
import net.minecraft.world.scores.Team;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -99,7 +99,7 @@
|
||||||
+ public int next(int bits) {
|
+ public int next(int bits) {
|
||||||
+ return super.next(bits);
|
+ return super.next(bits);
|
||||||
+ }
|
+ }
|
||||||
+
|
|
||||||
+ @Override
|
+ @Override
|
||||||
+ public int nextInt(int origin, int bound) {
|
+ public int nextInt(int origin, int bound) {
|
||||||
+ return net.minecraft.world.level.levelgen.BitRandomSource.super.nextInt(origin, bound);
|
+ return net.minecraft.world.level.levelgen.BitRandomSource.super.nextInt(origin, bound);
|
||||||
|
@ -168,9 +168,10 @@
|
||||||
+ return Entity.TOTAL_AIR_SUPPLY;
|
+ return Entity.TOTAL_AIR_SUPPLY;
|
||||||
+ }
|
+ }
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
|
+
|
||||||
private static final Logger LOGGER = LogUtils.getLogger();
|
private static final Logger LOGGER = LogUtils.getLogger();
|
||||||
public static final String ID_TAG = "id";
|
public static final String ID_TAG = "id";
|
||||||
|
public static final String PASSENGERS_TAG = "Passengers";
|
||||||
@@ -224,7 +368,7 @@
|
@@ -224,7 +368,7 @@
|
||||||
private static final EntityDataAccessor<Boolean> DATA_CUSTOM_NAME_VISIBLE = SynchedEntityData.defineId(Entity.class, EntityDataSerializers.BOOLEAN);
|
private static final EntityDataAccessor<Boolean> DATA_CUSTOM_NAME_VISIBLE = SynchedEntityData.defineId(Entity.class, EntityDataSerializers.BOOLEAN);
|
||||||
private static final EntityDataAccessor<Boolean> DATA_SILENT = SynchedEntityData.defineId(Entity.class, EntityDataSerializers.BOOLEAN);
|
private static final EntityDataAccessor<Boolean> DATA_SILENT = SynchedEntityData.defineId(Entity.class, EntityDataSerializers.BOOLEAN);
|
||||||
|
@ -410,19 +411,21 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final AABB makeBoundingBox() {
|
protected final AABB makeBoundingBox() {
|
||||||
@@ -462,10 +734,20 @@
|
@@ -460,12 +732,22 @@
|
||||||
this.baseTick();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public void tick() {
|
||||||
|
this.baseTick();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
+ // CraftBukkit start
|
+ // CraftBukkit start
|
||||||
+ public void postTick() {
|
+ public void postTick() {
|
||||||
+ // No clean way to break out of ticking once the entity has been copied to a new world, so instead we move the portalling later in the tick cycle
|
+ // No clean way to break out of ticking once the entity has been copied to a new world, so instead we move the portalling later in the tick cycle
|
||||||
+ if (!(this instanceof ServerPlayer) && this.isAlive()) { // Paper - don't attempt to teleport dead entities
|
+ if (!(this instanceof ServerPlayer) && this.isAlive()) { // Paper - don't attempt to teleport dead entities
|
||||||
+ this.handlePortal();
|
+ this.handlePortal();
|
||||||
+ }
|
+ }
|
||||||
+ }
|
}
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
+
|
|
||||||
public void baseTick() {
|
public void baseTick() {
|
||||||
ProfilerFiller gameprofilerfiller = Profiler.get();
|
ProfilerFiller gameprofilerfiller = Profiler.get();
|
||||||
|
|
||||||
|
@ -601,12 +604,10 @@
|
||||||
BlockPos blockposition = (BlockPos) this.mainSupportingBlockPos.get();
|
BlockPos blockposition = (BlockPos) this.mainSupportingBlockPos.get();
|
||||||
|
|
||||||
if (offset <= 1.0E-5F) {
|
if (offset <= 1.0E-5F) {
|
||||||
@@ -1131,7 +1477,21 @@
|
@@ -1133,6 +1479,20 @@
|
||||||
|
|
||||||
protected SoundEvent getSwimHighSpeedSplashSound() {
|
|
||||||
return SoundEvents.GENERIC_SPLASH;
|
return SoundEvents.GENERIC_SPLASH;
|
||||||
+ }
|
}
|
||||||
+
|
|
||||||
+ // CraftBukkit start - Add delegate methods
|
+ // CraftBukkit start - Add delegate methods
|
||||||
+ public SoundEvent getSwimSound0() {
|
+ public SoundEvent getSwimSound0() {
|
||||||
+ return this.getSwimSound();
|
+ return this.getSwimSound();
|
||||||
|
@ -618,11 +619,12 @@
|
||||||
+
|
+
|
||||||
+ public SoundEvent getSwimHighSpeedSplashSound0() {
|
+ public SoundEvent getSwimHighSpeedSplashSound0() {
|
||||||
+ return this.getSwimHighSpeedSplashSound();
|
+ return this.getSwimHighSpeedSplashSound();
|
||||||
}
|
+ }
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
|
+
|
||||||
public void recordMovementThroughBlocks(Vec3 oldPos, Vec3 newPos) {
|
public void recordMovementThroughBlocks(Vec3 oldPos, Vec3 newPos) {
|
||||||
this.movementThisTick.add(new Entity.Movement(oldPos, newPos));
|
this.movementThisTick.add(new Entity.Movement(oldPos, newPos));
|
||||||
|
}
|
||||||
@@ -1599,6 +1959,7 @@
|
@@ -1599,6 +1959,7 @@
|
||||||
this.setXRot(Mth.clamp(pitch, -90.0F, 90.0F) % 360.0F);
|
this.setXRot(Mth.clamp(pitch, -90.0F, 90.0F) % 360.0F);
|
||||||
this.yRotO = this.getYRot();
|
this.yRotO = this.getYRot();
|
||||||
|
@ -690,7 +692,7 @@
|
||||||
this.hasImpulse = true;
|
this.hasImpulse = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1858,8 +2243,20 @@
|
@@ -1858,9 +2243,21 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPushable() {
|
public boolean isPushable() {
|
||||||
|
@ -702,15 +704,16 @@
|
||||||
+ // Paper end - Climbing should not bypass cramming gamerule
|
+ // Paper end - Climbing should not bypass cramming gamerule
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
+
|
|
||||||
+ // CraftBukkit start - collidable API
|
+ // CraftBukkit start - collidable API
|
||||||
+ public boolean canCollideWithBukkit(Entity entity) {
|
+ public boolean canCollideWithBukkit(Entity entity) {
|
||||||
+ return this.isPushable();
|
+ return this.isPushable();
|
||||||
+ }
|
+ }
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
|
+
|
||||||
public void awardKillScore(Entity entityKilled, DamageSource damageSource) {
|
public void awardKillScore(Entity entityKilled, DamageSource damageSource) {
|
||||||
if (entityKilled instanceof ServerPlayer) {
|
if (entityKilled instanceof ServerPlayer) {
|
||||||
|
CriteriaTriggers.ENTITY_KILLED_PLAYER.trigger((ServerPlayer) entityKilled, this, damageSource);
|
||||||
@@ -1889,74 +2286,133 @@
|
@@ -1889,74 +2286,133 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1014,21 +1017,51 @@
|
||||||
protected abstract void readAdditionalSaveData(CompoundTag nbt);
|
protected abstract void readAdditionalSaveData(CompoundTag nbt);
|
||||||
|
|
||||||
protected abstract void addAdditionalSaveData(CompoundTag nbt);
|
protected abstract void addAdditionalSaveData(CompoundTag nbt);
|
||||||
@@ -2153,9 +2707,31 @@
|
@@ -2150,12 +2704,60 @@
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public ItemEntity spawnAtLocation(ServerLevel world, ItemStack stack, float yOffset) {
|
||||||
|
+ // Paper start - Restore vanilla drops behavior
|
||||||
|
+ return this.spawnAtLocation(world, stack, yOffset, null);
|
||||||
|
+ }
|
||||||
|
+ public record DefaultDrop(Item item, org.bukkit.inventory.ItemStack stack, @Nullable java.util.function.Consumer<ItemStack> dropConsumer) {
|
||||||
|
+ public DefaultDrop(final ItemStack stack, final java.util.function.Consumer<ItemStack> dropConsumer) {
|
||||||
|
+ this(stack.getItem(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), dropConsumer);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public void runConsumer(final java.util.function.Consumer<org.bukkit.inventory.ItemStack> fallback) {
|
||||||
|
+ if (this.dropConsumer == null || org.bukkit.craftbukkit.inventory.CraftItemType.bukkitToMinecraft(this.stack.getType()) != this.item) {
|
||||||
|
+ fallback.accept(this.stack);
|
||||||
|
+ } else {
|
||||||
|
+ this.dropConsumer.accept(org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(this.stack));
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ @Nullable
|
||||||
|
+ public ItemEntity spawnAtLocation(ServerLevel world, ItemStack stack, float yOffset, @Nullable java.util.function.Consumer<? super ItemEntity> delayedAddConsumer) {
|
||||||
|
+ // Paper end - Restore vanilla drops behavior
|
||||||
if (stack.isEmpty()) {
|
if (stack.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
- ItemEntity entityitem = new ItemEntity(world, this.getX(), this.getY() + (double) yOffset, this.getZ(), stack);
|
- ItemEntity entityitem = new ItemEntity(world, this.getX(), this.getY() + (double) yOffset, this.getZ(), stack);
|
||||||
+ // CraftBukkit start - Capture drops for death event
|
+ // CraftBukkit start - Capture drops for death event
|
||||||
+ if (this instanceof net.minecraft.world.entity.LivingEntity && !((net.minecraft.world.entity.LivingEntity) this).forceDrops) {
|
+ if (this instanceof net.minecraft.world.entity.LivingEntity && !((net.minecraft.world.entity.LivingEntity) this).forceDrops) {
|
||||||
+ ((net.minecraft.world.entity.LivingEntity) this).drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack)); // Paper - mirror so we can destroy it later
|
+ // Paper start - Restore vanilla drops behavior
|
||||||
|
+ ((net.minecraft.world.entity.LivingEntity) this).drops.add(new net.minecraft.world.entity.Entity.DefaultDrop(stack, itemStack -> {
|
||||||
|
+ ItemEntity itemEntity = new ItemEntity(this.level, this.getX(), this.getY() + (double) yOffset, this.getZ(), itemStack); // stack is copied before consumer
|
||||||
|
+ itemEntity.setDefaultPickUpDelay();
|
||||||
|
+ this.level.addFreshEntity(itemEntity);
|
||||||
|
+ if (delayedAddConsumer != null) delayedAddConsumer.accept(itemEntity);
|
||||||
|
+ }));
|
||||||
|
+ // Paper end - Restore vanilla drops behavior
|
||||||
+ return null;
|
+ return null;
|
||||||
+ }
|
+ }
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
+ ItemEntity entityitem = new ItemEntity(world, this.getX(), this.getY() + (double) yOffset, this.getZ(), stack.copy()); // Paper - copy so we can destroy original
|
+ ItemEntity entityitem = new ItemEntity(world, this.getX(), this.getY() + (double) yOffset, this.getZ(), stack.copy()); // Paper - copy so we can destroy original
|
||||||
+ stack.setCount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe
|
+ stack.setCount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe
|
||||||
|
|
||||||
entityitem.setDefaultPickUpDelay();
|
- entityitem.setDefaultPickUpDelay();
|
||||||
|
+ entityitem.setDefaultPickUpDelay(); // Paper - diff on change (in dropConsumer)
|
||||||
+ // Paper start - Call EntityDropItemEvent
|
+ // Paper start - Call EntityDropItemEvent
|
||||||
+ return this.spawnAtLocation(world, entityitem);
|
+ return this.spawnAtLocation(world, entityitem);
|
||||||
+ }
|
+ }
|
||||||
|
@ -1047,7 +1080,7 @@
|
||||||
world.addFreshEntity(entityitem);
|
world.addFreshEntity(entityitem);
|
||||||
return entityitem;
|
return entityitem;
|
||||||
}
|
}
|
||||||
@@ -2184,7 +2760,16 @@
|
@@ -2184,7 +2786,16 @@
|
||||||
if (this.isAlive() && this instanceof Leashable leashable) {
|
if (this.isAlive() && this instanceof Leashable leashable) {
|
||||||
if (leashable.getLeashHolder() == player) {
|
if (leashable.getLeashHolder() == player) {
|
||||||
if (!this.level().isClientSide()) {
|
if (!this.level().isClientSide()) {
|
||||||
|
@ -1065,7 +1098,7 @@
|
||||||
leashable.removeLeash();
|
leashable.removeLeash();
|
||||||
} else {
|
} else {
|
||||||
leashable.dropLeash();
|
leashable.dropLeash();
|
||||||
@@ -2200,6 +2785,14 @@
|
@@ -2200,6 +2811,14 @@
|
||||||
|
|
||||||
if (itemstack.is(Items.LEAD) && leashable.canHaveALeashAttachedToIt()) {
|
if (itemstack.is(Items.LEAD) && leashable.canHaveALeashAttachedToIt()) {
|
||||||
if (!this.level().isClientSide()) {
|
if (!this.level().isClientSide()) {
|
||||||
|
@ -1080,7 +1113,7 @@
|
||||||
leashable.setLeashedTo(player, true);
|
leashable.setLeashedTo(player, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2265,15 +2858,15 @@
|
@@ -2265,15 +2884,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean showVehicleHealth() {
|
public boolean showVehicleHealth() {
|
||||||
|
@ -1099,7 +1132,7 @@
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
for (Entity entity1 = entity; entity1.vehicle != null; entity1 = entity1.vehicle) {
|
for (Entity entity1 = entity; entity1.vehicle != null; entity1 = entity1.vehicle) {
|
||||||
@@ -2285,11 +2878,32 @@
|
@@ -2285,11 +2904,32 @@
|
||||||
if (!force && (!this.canRide(entity) || !entity.canAddPassenger(this))) {
|
if (!force && (!this.canRide(entity) || !entity.canAddPassenger(this))) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1133,7 +1166,7 @@
|
||||||
this.vehicle = entity;
|
this.vehicle = entity;
|
||||||
this.vehicle.addPassenger(this);
|
this.vehicle.addPassenger(this);
|
||||||
entity.getIndirectPassengersStream().filter((entity2) -> {
|
entity.getIndirectPassengersStream().filter((entity2) -> {
|
||||||
@@ -2314,19 +2928,30 @@
|
@@ -2314,19 +2954,30 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeVehicle() {
|
public void removeVehicle() {
|
||||||
|
@ -1166,7 +1199,7 @@
|
||||||
protected void addPassenger(Entity passenger) {
|
protected void addPassenger(Entity passenger) {
|
||||||
if (passenger.getVehicle() != this) {
|
if (passenger.getVehicle() != this) {
|
||||||
throw new IllegalStateException("Use x.startRiding(y), not y.addPassenger(x)");
|
throw new IllegalStateException("Use x.startRiding(y), not y.addPassenger(x)");
|
||||||
@@ -2349,21 +2974,53 @@
|
@@ -2349,21 +3000,53 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1226,7 +1259,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean canAddPassenger(Entity passenger) {
|
protected boolean canAddPassenger(Entity passenger) {
|
||||||
@@ -2464,7 +3121,7 @@
|
@@ -2464,7 +3147,7 @@
|
||||||
if (teleporttransition != null) {
|
if (teleporttransition != null) {
|
||||||
ServerLevel worldserver1 = teleporttransition.newLevel();
|
ServerLevel worldserver1 = teleporttransition.newLevel();
|
||||||
|
|
||||||
|
@ -1235,7 +1268,7 @@
|
||||||
this.teleport(teleporttransition);
|
this.teleport(teleporttransition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2547,7 +3204,7 @@
|
@@ -2547,7 +3230,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCrouching() {
|
public boolean isCrouching() {
|
||||||
|
@ -1244,7 +1277,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSprinting() {
|
public boolean isSprinting() {
|
||||||
@@ -2563,7 +3220,7 @@
|
@@ -2563,7 +3246,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isVisuallySwimming() {
|
public boolean isVisuallySwimming() {
|
||||||
|
@ -1253,7 +1286,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isVisuallyCrawling() {
|
public boolean isVisuallyCrawling() {
|
||||||
@@ -2571,6 +3228,13 @@
|
@@ -2571,6 +3254,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSwimming(boolean swimming) {
|
public void setSwimming(boolean swimming) {
|
||||||
|
@ -1267,7 +1300,7 @@
|
||||||
this.setSharedFlag(4, swimming);
|
this.setSharedFlag(4, swimming);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2609,6 +3273,7 @@
|
@@ -2609,6 +3299,7 @@
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public PlayerTeam getTeam() {
|
public PlayerTeam getTeam() {
|
||||||
|
@ -1275,7 +1308,7 @@
|
||||||
return this.level().getScoreboard().getPlayersTeam(this.getScoreboardName());
|
return this.level().getScoreboard().getPlayersTeam(this.getScoreboardName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2624,8 +3289,12 @@
|
@@ -2624,8 +3315,12 @@
|
||||||
return this.getTeam() != null ? this.getTeam().isAlliedTo(team) : false;
|
return this.getTeam() != null ? this.getTeam().isAlliedTo(team) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1289,7 +1322,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getSharedFlag(int index) {
|
public boolean getSharedFlag(int index) {
|
||||||
@@ -2644,7 +3313,7 @@
|
@@ -2644,7 +3339,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxAirSupply() {
|
public int getMaxAirSupply() {
|
||||||
|
@ -1298,7 +1331,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getAirSupply() {
|
public int getAirSupply() {
|
||||||
@@ -2652,7 +3321,18 @@
|
@@ -2652,7 +3347,18 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAirSupply(int air) {
|
public void setAirSupply(int air) {
|
||||||
|
@ -1318,7 +1351,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTicksFrozen() {
|
public int getTicksFrozen() {
|
||||||
@@ -2679,11 +3359,44 @@
|
@@ -2679,11 +3385,44 @@
|
||||||
|
|
||||||
public void thunderHit(ServerLevel world, LightningBolt lightning) {
|
public void thunderHit(ServerLevel world, LightningBolt lightning) {
|
||||||
this.setRemainingFireTicks(this.remainingFireTicks + 1);
|
this.setRemainingFireTicks(this.remainingFireTicks + 1);
|
||||||
|
@ -1365,7 +1398,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onAboveBubbleCol(boolean drag) {
|
public void onAboveBubbleCol(boolean drag) {
|
||||||
@@ -2713,7 +3426,7 @@
|
@@ -2713,7 +3452,7 @@
|
||||||
this.resetFallDistance();
|
this.resetFallDistance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1374,7 +1407,7 @@
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2818,7 +3531,7 @@
|
@@ -2818,7 +3557,7 @@
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String s = this.level() == null ? "~NULL~" : this.level().toString();
|
String s = this.level() == null ? "~NULL~" : this.level().toString();
|
||||||
|
|
||||||
|
@ -1383,7 +1416,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isInvulnerableToBase(DamageSource damageSource) {
|
public final boolean isInvulnerableToBase(DamageSource damageSource) {
|
||||||
@@ -2838,6 +3551,13 @@
|
@@ -2838,6 +3577,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void restoreFrom(Entity original) {
|
public void restoreFrom(Entity original) {
|
||||||
|
@ -1397,7 +1430,7 @@
|
||||||
CompoundTag nbttagcompound = original.saveWithoutId(new CompoundTag());
|
CompoundTag nbttagcompound = original.saveWithoutId(new CompoundTag());
|
||||||
|
|
||||||
nbttagcompound.remove("Dimension");
|
nbttagcompound.remove("Dimension");
|
||||||
@@ -2850,8 +3570,57 @@
|
@@ -2850,8 +3596,57 @@
|
||||||
public Entity teleport(TeleportTransition teleportTarget) {
|
public Entity teleport(TeleportTransition teleportTarget) {
|
||||||
Level world = this.level();
|
Level world = this.level();
|
||||||
|
|
||||||
|
@ -1455,7 +1488,7 @@
|
||||||
ServerLevel worldserver1 = teleportTarget.newLevel();
|
ServerLevel worldserver1 = teleportTarget.newLevel();
|
||||||
boolean flag = worldserver1.dimension() != worldserver.dimension();
|
boolean flag = worldserver1.dimension() != worldserver.dimension();
|
||||||
|
|
||||||
@@ -2918,10 +3687,19 @@
|
@@ -2918,10 +3713,19 @@
|
||||||
gameprofilerfiller.pop();
|
gameprofilerfiller.pop();
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1476,7 +1509,7 @@
|
||||||
Iterator iterator1 = list1.iterator();
|
Iterator iterator1 = list1.iterator();
|
||||||
|
|
||||||
while (iterator1.hasNext()) {
|
while (iterator1.hasNext()) {
|
||||||
@@ -2947,7 +3725,7 @@
|
@@ -2947,7 +3751,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendTeleportTransitionToRidingPlayers(TeleportTransition teleportTarget) {
|
private void sendTeleportTransitionToRidingPlayers(TeleportTransition teleportTarget) {
|
||||||
|
@ -1485,7 +1518,7 @@
|
||||||
Iterator iterator = this.getIndirectPassengers().iterator();
|
Iterator iterator = this.getIndirectPassengers().iterator();
|
||||||
|
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
@@ -2995,9 +3773,17 @@
|
@@ -2995,9 +3799,17 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void removeAfterChangingDimensions() {
|
protected void removeAfterChangingDimensions() {
|
||||||
|
@ -1506,7 +1539,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3006,11 +3792,34 @@
|
@@ -3006,11 +3818,34 @@
|
||||||
return PortalShape.getRelativePosition(portalRect, portalAxis, this.position(), this.getDimensions(this.getPose()));
|
return PortalShape.getRelativePosition(portalRect, portalAxis, this.position(), this.getDimensions(this.getPose()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1541,7 +1574,7 @@
|
||||||
if (from.dimension() == Level.END && to.dimension() == Level.OVERWORLD) {
|
if (from.dimension() == Level.END && to.dimension() == Level.OVERWORLD) {
|
||||||
Iterator iterator = this.getPassengers().iterator();
|
Iterator iterator = this.getPassengers().iterator();
|
||||||
|
|
||||||
@@ -3134,10 +3943,16 @@
|
@@ -3134,10 +3969,16 @@
|
||||||
return (Boolean) this.entityData.get(Entity.DATA_CUSTOM_NAME_VISIBLE);
|
return (Boolean) this.entityData.get(Entity.DATA_CUSTOM_NAME_VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1561,7 +1594,7 @@
|
||||||
return entity != null;
|
return entity != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3187,7 +4002,7 @@
|
@@ -3187,7 +4028,7 @@
|
||||||
/** @deprecated */
|
/** @deprecated */
|
||||||
@Deprecated
|
@Deprecated
|
||||||
protected void fixupDimensions() {
|
protected void fixupDimensions() {
|
||||||
|
@ -1570,7 +1603,7 @@
|
||||||
EntityDimensions entitysize = this.getDimensions(entitypose);
|
EntityDimensions entitysize = this.getDimensions(entitypose);
|
||||||
|
|
||||||
this.dimensions = entitysize;
|
this.dimensions = entitysize;
|
||||||
@@ -3196,7 +4011,7 @@
|
@@ -3196,7 +4037,7 @@
|
||||||
|
|
||||||
public void refreshDimensions() {
|
public void refreshDimensions() {
|
||||||
EntityDimensions entitysize = this.dimensions;
|
EntityDimensions entitysize = this.dimensions;
|
||||||
|
@ -1579,7 +1612,7 @@
|
||||||
EntityDimensions entitysize1 = this.getDimensions(entitypose);
|
EntityDimensions entitysize1 = this.getDimensions(entitypose);
|
||||||
|
|
||||||
this.dimensions = entitysize1;
|
this.dimensions = entitysize1;
|
||||||
@@ -3258,10 +4073,29 @@
|
@@ -3258,10 +4099,29 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void setBoundingBox(AABB boundingBox) {
|
public final void setBoundingBox(AABB boundingBox) {
|
||||||
|
@ -1611,7 +1644,7 @@
|
||||||
return this.getDimensions(pose).eyeHeight();
|
return this.getDimensions(pose).eyeHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3300,7 +4134,14 @@
|
@@ -3300,7 +4160,14 @@
|
||||||
|
|
||||||
public void startSeenByPlayer(ServerPlayer player) {}
|
public void startSeenByPlayer(ServerPlayer player) {}
|
||||||
|
|
||||||
|
@ -1627,7 +1660,7 @@
|
||||||
|
|
||||||
public float rotate(Rotation rotation) {
|
public float rotate(Rotation rotation) {
|
||||||
float f = Mth.wrapDegrees(this.getYRot());
|
float f = Mth.wrapDegrees(this.getYRot());
|
||||||
@@ -3335,7 +4176,7 @@
|
@@ -3335,7 +4202,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -1636,7 +1669,7 @@
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3373,20 +4214,34 @@
|
@@ -3373,20 +4240,34 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stream<Entity> getIndirectPassengersStream() {
|
private Stream<Entity> getIndirectPassengersStream() {
|
||||||
|
@ -1671,7 +1704,7 @@
|
||||||
return () -> {
|
return () -> {
|
||||||
return this.getIndirectPassengersStream().iterator();
|
return this.getIndirectPassengersStream().iterator();
|
||||||
};
|
};
|
||||||
@@ -3399,6 +4254,7 @@
|
@@ -3399,6 +4280,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasExactlyOnePlayerPassenger() {
|
public boolean hasExactlyOnePlayerPassenger() {
|
||||||
|
@ -1679,7 +1712,7 @@
|
||||||
return this.countPlayerPassengers() == 1;
|
return this.countPlayerPassengers() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3435,7 +4291,7 @@
|
@@ -3435,7 +4317,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isControlledByLocalInstance() {
|
public boolean isControlledByLocalInstance() {
|
||||||
|
@ -1688,7 +1721,7 @@
|
||||||
|
|
||||||
if (entityliving instanceof Player entityhuman) {
|
if (entityliving instanceof Player entityhuman) {
|
||||||
return entityhuman.isLocalPlayer();
|
return entityhuman.isLocalPlayer();
|
||||||
@@ -3445,7 +4301,7 @@
|
@@ -3445,7 +4327,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isControlledByClient() {
|
public boolean isControlledByClient() {
|
||||||
|
@ -1697,7 +1730,7 @@
|
||||||
|
|
||||||
return entityliving != null && entityliving.isControlledByClient();
|
return entityliving != null && entityliving.isControlledByClient();
|
||||||
}
|
}
|
||||||
@@ -3463,7 +4319,7 @@
|
@@ -3463,7 +4345,7 @@
|
||||||
return new Vec3((double) f1 * d2 / (double) f3, 0.0D, (double) f2 * d2 / (double) f3);
|
return new Vec3((double) f1 * d2 / (double) f3, 0.0D, (double) f2 * d2 / (double) f3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1706,7 +1739,7 @@
|
||||||
return new Vec3(this.getX(), this.getBoundingBox().maxY, this.getZ());
|
return new Vec3(this.getX(), this.getBoundingBox().maxY, this.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3489,8 +4345,37 @@
|
@@ -3489,8 +4371,37 @@
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1745,7 +1778,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void lookAt(EntityAnchorArgument.Anchor anchorPoint, Vec3 target) {
|
public void lookAt(EntityAnchorArgument.Anchor anchorPoint, Vec3 target) {
|
||||||
@@ -3551,6 +4436,11 @@
|
@@ -3551,6 +4462,11 @@
|
||||||
vec3d = vec3d.add(vec3d1);
|
vec3d = vec3d.add(vec3d1);
|
||||||
++k1;
|
++k1;
|
||||||
}
|
}
|
||||||
|
@ -1757,7 +1790,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3613,7 +4503,7 @@
|
@@ -3613,7 +4529,7 @@
|
||||||
return new ClientboundAddEntityPacket(this, entityTrackerEntry);
|
return new ClientboundAddEntityPacket(this, entityTrackerEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1766,7 +1799,7 @@
|
||||||
return this.type.getDimensions();
|
return this.type.getDimensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3714,7 +4604,39 @@
|
@@ -3714,7 +4630,39 @@
|
||||||
return this.getZ((2.0D * this.random.nextDouble() - 1.0D) * widthScale);
|
return this.getZ((2.0D * this.random.nextDouble() - 1.0D) * widthScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1806,7 +1839,7 @@
|
||||||
if (this.position.x != x || this.position.y != y || this.position.z != z) {
|
if (this.position.x != x || this.position.y != y || this.position.z != z) {
|
||||||
this.position = new Vec3(x, y, z);
|
this.position = new Vec3(x, y, z);
|
||||||
int i = Mth.floor(x);
|
int i = Mth.floor(x);
|
||||||
@@ -3732,6 +4654,12 @@
|
@@ -3732,6 +4680,12 @@
|
||||||
this.levelCallback.onMove();
|
this.levelCallback.onMove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1819,7 +1852,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkDespawn() {}
|
public void checkDespawn() {}
|
||||||
@@ -3818,8 +4746,17 @@
|
@@ -3818,8 +4772,17 @@
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void setRemoved(Entity.RemovalReason reason) {
|
public final void setRemoved(Entity.RemovalReason reason) {
|
||||||
|
@ -1838,7 +1871,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.removalReason.shouldDestroy()) {
|
if (this.removalReason.shouldDestroy()) {
|
||||||
@@ -3827,14 +4764,30 @@
|
@@ -3827,14 +4790,30 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getPassengers().forEach(Entity::stopRiding);
|
this.getPassengers().forEach(Entity::stopRiding);
|
||||||
|
@ -1871,7 +1904,7 @@
|
||||||
@Override
|
@Override
|
||||||
public void setLevelCallback(EntityInLevelCallback changeListener) {
|
public void setLevelCallback(EntityInLevelCallback changeListener) {
|
||||||
this.levelCallback = changeListener;
|
this.levelCallback = changeListener;
|
||||||
@@ -3887,7 +4840,7 @@
|
@@ -3887,7 +4866,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vec3 getKnownMovement() {
|
public Vec3 getKnownMovement() {
|
||||||
|
@ -1880,7 +1913,7 @@
|
||||||
|
|
||||||
if (entityliving instanceof Player entityhuman) {
|
if (entityliving instanceof Player entityhuman) {
|
||||||
if (this.isAlive()) {
|
if (this.isAlive()) {
|
||||||
@@ -3962,4 +4915,14 @@
|
@@ -3962,4 +4941,14 @@
|
||||||
|
|
||||||
void accept(Entity entity, double x, double y, double z);
|
void accept(Entity entity, double x, double y, double z);
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@
|
||||||
protected float appliedScale;
|
protected float appliedScale;
|
||||||
+ // CraftBukkit start
|
+ // CraftBukkit start
|
||||||
+ public int expToDrop;
|
+ public int expToDrop;
|
||||||
+ public ArrayList<org.bukkit.inventory.ItemStack> drops = new ArrayList<org.bukkit.inventory.ItemStack>();
|
+ public ArrayList<DefaultDrop> drops = new ArrayList<>(); // Paper - Restore vanilla drops behavior
|
||||||
+ public final org.bukkit.craftbukkit.attribute.CraftAttributeMap craftAttributes;
|
+ public final org.bukkit.craftbukkit.attribute.CraftAttributeMap craftAttributes;
|
||||||
+ public boolean collides = true;
|
+ public boolean collides = true;
|
||||||
+ public Set<UUID> collidableExemptions = new HashSet<>();
|
+ public Set<UUID> collidableExemptions = new HashSet<>();
|
||||||
|
|
|
@ -126,6 +126,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth());
|
this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth());
|
||||||
|
@@ -488,10 +535,10 @@
|
||||||
|
@Override
|
||||||
|
protected void dropCustomDeathLoot(ServerLevel world, DamageSource source, boolean causedByPlayer) {
|
||||||
|
super.dropCustomDeathLoot(world, source, causedByPlayer);
|
||||||
|
- ItemEntity entityitem = this.spawnAtLocation(world, (ItemLike) Items.NETHER_STAR);
|
||||||
|
+ ItemEntity entityitem = this.spawnAtLocation(world, new net.minecraft.world.item.ItemStack(Items.NETHER_STAR), 0, ItemEntity::setExtendedLifetime); // Paper - Restore vanilla drops behavior; spawnAtLocation returns null so modify the item entity with a consumer
|
||||||
|
|
||||||
|
if (entityitem != null) {
|
||||||
|
- entityitem.setExtendedLifetime();
|
||||||
|
+ entityitem.setExtendedLifetime(); // Paper - diff on change
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -499,7 +546,7 @@
|
@@ -499,7 +546,7 @@
|
||||||
@Override
|
@Override
|
||||||
public void checkDespawn() {
|
public void checkDespawn() {
|
||||||
|
|
|
@ -347,7 +347,7 @@
|
||||||
itemstack.set(DataComponents.CUSTOM_NAME, this.getCustomName());
|
itemstack.set(DataComponents.CUSTOM_NAME, this.getCustomName());
|
||||||
- Block.popResource(this.level(), this.blockPosition(), itemstack);
|
- Block.popResource(this.level(), this.blockPosition(), itemstack);
|
||||||
- this.brokenByAnything(world, damageSource);
|
- this.brokenByAnything(world, damageSource);
|
||||||
+ this.drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops
|
+ this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior
|
||||||
+ return this.brokenByAnything(world, damageSource); // Paper
|
+ return this.brokenByAnything(world, damageSource); // Paper
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,7 +364,7 @@
|
||||||
itemstack = (ItemStack) this.handItems.get(i);
|
itemstack = (ItemStack) this.handItems.get(i);
|
||||||
if (!itemstack.isEmpty()) {
|
if (!itemstack.isEmpty()) {
|
||||||
- Block.popResource(this.level(), this.blockPosition().above(), itemstack);
|
- Block.popResource(this.level(), this.blockPosition().above(), itemstack);
|
||||||
+ this.drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)); // CraftBukkit - add to drops // Paper - mirror so we can destroy it later - though this call site was safe
|
+ this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly
|
||||||
this.handItems.set(i, ItemStack.EMPTY);
|
this.handItems.set(i, ItemStack.EMPTY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -373,7 +373,7 @@
|
||||||
itemstack = (ItemStack) this.armorItems.get(i);
|
itemstack = (ItemStack) this.armorItems.get(i);
|
||||||
if (!itemstack.isEmpty()) {
|
if (!itemstack.isEmpty()) {
|
||||||
- Block.popResource(this.level(), this.blockPosition().above(), itemstack);
|
- Block.popResource(this.level(), this.blockPosition().above(), itemstack);
|
||||||
+ this.drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)); // CraftBukkit - add to drops // Paper - mirror so we can destroy it later - though this call site was safe
|
+ this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly
|
||||||
this.armorItems.set(i, ItemStack.EMPTY);
|
this.armorItems.set(i, ItemStack.EMPTY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -973,19 +973,25 @@ public class CraftEventFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource) {
|
public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource) {
|
||||||
return CraftEventFactory.callEntityDeathEvent(victim, damageSource, new ArrayList<org.bukkit.inventory.ItemStack>(0));
|
return CraftEventFactory.callEntityDeathEvent(victim, damageSource, new ArrayList<>(0)); // Paper - Restore vanilla drops behavior
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List<org.bukkit.inventory.ItemStack> drops) {
|
public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List<Entity.DefaultDrop> drops) { // Paper - Restore vanilla drops behavior
|
||||||
// Paper start
|
// Paper start
|
||||||
return CraftEventFactory.callEntityDeathEvent(victim, damageSource, drops, com.google.common.util.concurrent.Runnables.doNothing());
|
return CraftEventFactory.callEntityDeathEvent(victim, damageSource, drops, com.google.common.util.concurrent.Runnables.doNothing());
|
||||||
}
|
}
|
||||||
public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List<org.bukkit.inventory.ItemStack> drops, Runnable lootCheck) {
|
|
||||||
|
private static final java.util.function.Function<org.bukkit.inventory.ItemStack, Entity.DefaultDrop> FROM_FUNCTION = stack -> {
|
||||||
|
if (stack == null) return null;
|
||||||
|
return new Entity.DefaultDrop(CraftItemType.bukkitToMinecraft(stack.getType()), stack, null);
|
||||||
|
};
|
||||||
|
|
||||||
|
public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, DamageSource damageSource, List<Entity.DefaultDrop> drops, Runnable lootCheck) { // Paper - Restore vanilla drops behavior
|
||||||
// Paper end
|
// Paper end
|
||||||
CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
|
CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
|
||||||
CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
|
CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
|
||||||
CraftWorld world = (CraftWorld) entity.getWorld();
|
CraftWorld world = (CraftWorld) entity.getWorld();
|
||||||
EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(world.getHandle(), damageSource.getEntity()));
|
EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(world.getHandle(), damageSource.getEntity())); // Paper - Restore vanilla drops behavior
|
||||||
populateFields(victim, event); // Paper - make cancellable
|
populateFields(victim, event); // Paper - make cancellable
|
||||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||||
|
|
||||||
|
@ -998,20 +1004,24 @@ public class CraftEventFactory {
|
||||||
victim.expToDrop = event.getDroppedExp();
|
victim.expToDrop = event.getDroppedExp();
|
||||||
lootCheck.run(); // Paper - advancement triggers before destroying items
|
lootCheck.run(); // Paper - advancement triggers before destroying items
|
||||||
|
|
||||||
for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
|
// Paper start - Restore vanilla drops behavior
|
||||||
|
for (Entity.DefaultDrop drop : drops) {
|
||||||
|
if (drop == null) continue;
|
||||||
|
final org.bukkit.inventory.ItemStack stack = drop.stack();
|
||||||
|
// Paper end - Restore vanilla drops behavior
|
||||||
if (stack == null || stack.getType() == Material.AIR || stack.getAmount() == 0) continue;
|
if (stack == null || stack.getType() == Material.AIR || stack.getAmount() == 0) continue;
|
||||||
|
|
||||||
world.dropItem(entity.getLocation(), stack); // Paper - note: dropItem already clones due to this being bukkit -> NMS
|
drop.runConsumer(s -> world.dropItem(entity.getLocation(), s)); // Paper - Restore vanilla drops behavior
|
||||||
if (stack instanceof CraftItemStack) stack.setAmount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe, but don't nuke bukkit stacks of manually added items
|
if (stack instanceof CraftItemStack) stack.setAmount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe, but don't nuke bukkit stacks of manually added items
|
||||||
}
|
}
|
||||||
|
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, DamageSource damageSource, List<org.bukkit.inventory.ItemStack> drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure
|
public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, DamageSource damageSource, List<Entity.DefaultDrop> drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure & Restore vanilla drops behavior
|
||||||
CraftPlayer entity = victim.getBukkitEntity();
|
CraftPlayer entity = victim.getBukkitEntity();
|
||||||
CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
|
CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
|
||||||
PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, drops, victim.getExpReward(victim.serverLevel(), damageSource.getEntity()), 0, deathMessage);
|
PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(victim.serverLevel(), damageSource.getEntity()), 0, deathMessage); // Paper - Restore vanilla drops behavior
|
||||||
event.setKeepInventory(keepInventory);
|
event.setKeepInventory(keepInventory);
|
||||||
event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel
|
event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel
|
||||||
populateFields(victim, event); // Paper - make cancellable
|
populateFields(victim, event); // Paper - make cancellable
|
||||||
|
@ -1029,16 +1039,14 @@ public class CraftEventFactory {
|
||||||
victim.expToDrop = event.getDroppedExp();
|
victim.expToDrop = event.getDroppedExp();
|
||||||
victim.newExp = event.getNewExp();
|
victim.newExp = event.getNewExp();
|
||||||
|
|
||||||
for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
|
// Paper start - Restore vanilla drops behavior
|
||||||
|
for (Entity.DefaultDrop drop : drops) {
|
||||||
|
if (drop == null) continue;
|
||||||
|
final org.bukkit.inventory.ItemStack stack = drop.stack();
|
||||||
|
// Paper end - Restore vanilla drops behavior
|
||||||
if (stack == null || stack.getType() == Material.AIR) continue;
|
if (stack == null || stack.getType() == Material.AIR) continue;
|
||||||
|
|
||||||
if (stack instanceof CraftItemStack craftItemStack && craftItemStack.isForInventoryDrop()) {
|
drop.runConsumer(s -> victim.drop(CraftItemStack.unwrap(s), true, false, false)); // Paper - Restore vanilla drops behavior
|
||||||
victim.drop(CraftItemStack.asNMSCopy(stack), true, false, false); // SPIGOT-7800, SPIGOT-7801: Vanilla Behaviour for Player Inventory dropped items
|
|
||||||
} else {
|
|
||||||
victim.forceDrops = true;
|
|
||||||
victim.spawnAtLocation(victim.serverLevel(), CraftItemStack.asNMSCopy(stack)); // SPIGOT-7806: Vanilla Behaviour for items not related to Player Inventory dropped items
|
|
||||||
victim.forceDrops = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return event;
|
return event;
|
||||||
|
|
|
@ -142,27 +142,6 @@ public final class CraftItemStack extends ItemStack {
|
||||||
this.setItemMeta(itemMeta);
|
this.setItemMeta(itemMeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets if the item is marked as an inventory drop in death events.
|
|
||||||
*
|
|
||||||
* @return true if the item is marked as an inventory drop
|
|
||||||
*/
|
|
||||||
@ApiStatus.Internal
|
|
||||||
public boolean isForInventoryDrop() {
|
|
||||||
return this.isForInventoryDrop;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Marks this item as an inventory drop in death events.
|
|
||||||
*
|
|
||||||
* @return the ItemStack marked as an inventory drop
|
|
||||||
*/
|
|
||||||
@ApiStatus.Internal
|
|
||||||
public ItemStack markForInventoryDrop() {
|
|
||||||
this.isForInventoryDrop = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MaterialData getData() {
|
public MaterialData getData() {
|
||||||
return this.handle != null ? CraftMagicNumbers.getMaterialData(this.handle.getItem()) : super.getData();
|
return this.handle != null ? CraftMagicNumbers.getMaterialData(this.handle.getItem()) : super.getData();
|
||||||
|
|
Loading…
Reference in a new issue