From dde17defa577ecd599bb2e12c3dbd54e109abca3 Mon Sep 17 00:00:00 2001 From: Bjarne Koll <git@lynxplay.dev> Date: Sat, 14 Dec 2024 17:17:03 +0100 Subject: [PATCH] net/minecraft/world/entity/vehicle --- .../entity/vehicle/AbstractBoat.java.patch | 67 ++++------ .../vehicle/AbstractChestBoat.java.patch | 63 ++++------ .../vehicle/AbstractMinecart.java.patch | 119 +++++++----------- .../AbstractMinecartContainer.java.patch | 83 ++++++++++++ .../entity/vehicle/ContainerEntity.java.patch | 45 ++++--- .../vehicle/MinecartCommandBlock.java.patch | 24 ++++ .../entity/vehicle/MinecartTNT.java.patch | 56 +++++++++ .../vehicle/NewMinecartBehavior.java.patch | 73 +++++++++++ .../vehicle/OldMinecartBehavior.java.patch | 58 +++++++++ .../entity/vehicle/VehicleEntity.java.patch | 42 +++++++ .../AbstractMinecartContainer.java.patch | 98 --------------- .../vehicle/MinecartCommandBlock.java.patch | 23 ---- .../entity/vehicle/MinecartTNT.java.patch | 53 -------- .../vehicle/NewMinecartBehavior.java.patch | 83 ------------ .../vehicle/OldMinecartBehavior.java.patch | 75 ----------- .../entity/vehicle/VehicleEntity.java.patch | 64 ---------- 16 files changed, 452 insertions(+), 574 deletions(-) rename paper-server/patches/{unapplied => sources}/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch (62%) rename paper-server/patches/{unapplied => sources}/net/minecraft/world/entity/vehicle/AbstractChestBoat.java.patch (51%) rename paper-server/patches/{unapplied => sources}/net/minecraft/world/entity/vehicle/AbstractMinecart.java.patch (58%) create mode 100644 paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java.patch rename paper-server/patches/{unapplied => sources}/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch (61%) create mode 100644 paper-server/patches/sources/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/entity/vehicle/MinecartTNT.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/entity/vehicle/VehicleEntity.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/MinecartTNT.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/VehicleEntity.java.patch diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch similarity index 62% rename from paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch rename to paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch index 28b20b3791..20b17c550f 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch @@ -1,21 +1,6 @@ --- a/net/minecraft/world/entity/vehicle/AbstractBoat.java +++ b/net/minecraft/world/entity/vehicle/AbstractBoat.java -@@ -47,6 +47,14 @@ - import net.minecraft.world.phys.shapes.BooleanOp; - import net.minecraft.world.phys.shapes.Shapes; - import net.minecraft.world.phys.shapes.VoxelShape; -+// CraftBukkit start -+import org.bukkit.Location; -+import org.bukkit.craftbukkit.util.CraftLocation; -+import org.bukkit.entity.Vehicle; -+import org.bukkit.event.entity.EntityRemoveEvent; -+import org.bukkit.event.vehicle.VehicleEntityCollisionEvent; -+import org.bukkit.event.vehicle.VehicleMoveEvent; -+// CraftBukkit end - - public abstract class AbstractBoat extends VehicleEntity implements Leashable { - -@@ -87,6 +95,14 @@ +@@ -83,6 +_,14 @@ private Leashable.LeashData leashData; private final Supplier<Item> dropItem; @@ -27,10 +12,10 @@ + public boolean landBoats = false; + // CraftBukkit end + - public AbstractBoat(EntityType<? extends AbstractBoat> type, Level world, Supplier<Item> itemSupplier) { - super(type, world); - this.dropItem = itemSupplier; -@@ -128,7 +144,7 @@ + public AbstractBoat(EntityType<? extends AbstractBoat> entityType, Level level, Supplier<Item> dropItem) { + super(entityType, level); + this.dropItem = dropItem; +@@ -124,7 +_,7 @@ } @Override @@ -39,7 +24,7 @@ return true; } -@@ -180,11 +196,32 @@ +@@ -177,11 +_,30 @@ @Override public void push(Entity entity) { @@ -48,12 +33,11 @@ if (entity.getBoundingBox().minY < this.getBoundingBox().maxY) { + // CraftBukkit start + if (!this.isPassengerOfSameVehicle(entity)) { -+ VehicleEntityCollisionEvent event = new VehicleEntityCollisionEvent((Vehicle) this.getBukkitEntity(), entity.getBukkitEntity()); -+ this.level().getCraftServer().getPluginManager().callEvent(event); -+ -+ if (event.isCancelled()) { -+ return; -+ } ++ org.bukkit.event.vehicle.VehicleEntityCollisionEvent event = new org.bukkit.event.vehicle.VehicleEntityCollisionEvent( ++ (org.bukkit.entity.Vehicle) this.getBukkitEntity(), ++ entity.getBukkitEntity() ++ ); ++ if (!event.callEvent()) return; + } + // CraftBukkit end super.push(entity); @@ -61,26 +45,25 @@ } else if (entity.getBoundingBox().minY <= this.getBoundingBox().minY) { + // CraftBukkit start + if (!this.isPassengerOfSameVehicle(entity)) { -+ VehicleEntityCollisionEvent event = new VehicleEntityCollisionEvent((Vehicle) this.getBukkitEntity(), entity.getBukkitEntity()); -+ this.level().getCraftServer().getPluginManager().callEvent(event); -+ -+ if (event.isCancelled()) { -+ return; -+ } ++ org.bukkit.event.vehicle.VehicleEntityCollisionEvent event = new org.bukkit.event.vehicle.VehicleEntityCollisionEvent( ++ (org.bukkit.entity.Vehicle) this.getBukkitEntity(), ++ entity.getBukkitEntity() ++ ); ++ if (!event.callEvent()) return; + } + // CraftBukkit end super.push(entity); } - -@@ -247,6 +284,7 @@ + } +@@ -243,6 +_,7 @@ return this.getDirection().getClockWise(); } -+ private Location lastLocation; // CraftBukkit ++ private org.bukkit.Location lastLocation; // CraftBukkit @Override public void tick() { this.oldStatus = this.status; -@@ -287,6 +325,21 @@ +@@ -283,6 +_,21 @@ this.setDeltaMovement(Vec3.ZERO); } @@ -88,13 +71,13 @@ + org.bukkit.Server server = this.level().getCraftServer(); + org.bukkit.World bworld = this.level().getWorld(); + -+ Location to = CraftLocation.toBukkit(this.position(), bworld, this.getYRot(), this.getXRot()); -+ Vehicle vehicle = (Vehicle) this.getBukkitEntity(); ++ org.bukkit.Location to = org.bukkit.craftbukkit.util.CraftLocation.toBukkit(this.position(), bworld, this.getYRot(), this.getXRot()); ++ org.bukkit.entity.Vehicle vehicle = (org.bukkit.entity.Vehicle) this.getBukkitEntity(); + + server.getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleUpdateEvent(vehicle)); + + if (this.lastLocation != null && !this.lastLocation.equals(to)) { -+ VehicleMoveEvent event = new VehicleMoveEvent(vehicle, this.lastLocation, to); ++ org.bukkit.event.vehicle.VehicleMoveEvent event = new org.bukkit.event.vehicle.VehicleMoveEvent(vehicle, this.lastLocation, to); + server.getPluginManager().callEvent(event); + } + this.lastLocation = vehicle.getLocation(); @@ -102,7 +85,7 @@ this.applyEffectsFromBlocks(); this.applyEffectsFromBlocks(); this.tickBubbleColumn(); -@@ -790,11 +843,18 @@ +@@ -762,11 +_,18 @@ @Override public void remove(Entity.RemovalReason reason) { @@ -112,7 +95,7 @@ + } + + @Override -+ public void remove(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { ++ public void remove(Entity.RemovalReason entity_removalreason, org.bukkit.event.entity.EntityRemoveEvent.Cause cause) { + // CraftBukkit end + if (!this.level().isClientSide && entity_removalreason.shouldDestroy() && this.isLeashed()) { this.dropLeash(); diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/AbstractChestBoat.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractChestBoat.java.patch similarity index 51% rename from paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/AbstractChestBoat.java.patch rename to paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractChestBoat.java.patch index f23f862b79..3dc8fe5278 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/AbstractChestBoat.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractChestBoat.java.patch @@ -1,69 +1,51 @@ --- a/net/minecraft/world/entity/vehicle/AbstractChestBoat.java +++ b/net/minecraft/world/entity/vehicle/AbstractChestBoat.java -@@ -27,6 +27,15 @@ - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.level.storage.loot.LootTable; - -+// CraftBukkit start -+import java.util.List; -+import org.bukkit.Location; -+import org.bukkit.craftbukkit.entity.CraftHumanEntity; -+import org.bukkit.entity.HumanEntity; -+import org.bukkit.event.entity.EntityRemoveEvent; -+import org.bukkit.inventory.InventoryHolder; -+// CraftBukkit end -+ - public abstract class AbstractChestBoat extends AbstractBoat implements HasCustomInventoryScreen, ContainerEntity { - - private static final int CONTAINER_SIZE = 27; -@@ -70,11 +79,18 @@ +@@ -66,11 +_,18 @@ @Override public void remove(Entity.RemovalReason reason) { -- if (!this.level().isClientSide && reason.shouldDestroy()) { + // CraftBukkit start - add Bukkit remove cause + this.remove(reason, null); + } + + @Override -+ public void remove(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { ++ public void remove(Entity.RemovalReason reason, org.bukkit.event.entity.EntityRemoveEvent.Cause cause) { + // CraftBukkit end -+ if (!this.level().isClientSide && entity_removalreason.shouldDestroy()) { - Containers.dropContents(this.level(), (Entity) this, (Container) this); + if (!this.level().isClientSide && reason.shouldDestroy()) { + Containers.dropContents(this.level(), this, this); } - super.remove(reason); -+ super.remove(entity_removalreason, cause); // CraftBukkit - add Bukkit remove cause ++ super.remove(reason, cause); // CraftBukkit - add Bukkit remove cause } @Override -@@ -109,10 +125,10 @@ +@@ -97,8 +_,8 @@ @Override public void openCustomInventoryScreen(Player player) { - player.openMenu(this); +- if (player.level() instanceof ServerLevel serverLevel) { + // Paper - fix inventory open cancel - moved into below if - Level world = player.level(); - -- if (world instanceof ServerLevel worldserver) { -+ if (world instanceof ServerLevel worldserver && player.openMenu(this).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation ++ if (player.level() instanceof ServerLevel serverLevel && player.openMenu(this).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation this.gameEvent(GameEvent.CONTAINER_OPEN, player); - PiglinAi.angerNearbyPiglins(worldserver, player, true); + PiglinAi.angerNearbyPiglins(serverLevel, player, true); } -@@ -165,7 +181,7 @@ +@@ -151,7 +_,7 @@ @Nullable @Override - public AbstractContainerMenu createMenu(int syncId, Inventory playerInventory, Player player) { + public AbstractContainerMenu createMenu(int containerId, Inventory playerInventory, Player player) { - if (this.lootTable != null && player.isSpectator()) { + if (this.lootTable != null && player.isSpectator()) { // Paper - LootTable API (TODO spectators can open chests that aren't ready to be re-generated but this doesn't support that) return null; } else { this.unpackLootTable(playerInventory.player); -@@ -212,4 +228,59 @@ +@@ -198,4 +_,59 @@ public void stopOpen(Player player) { - this.level().gameEvent((Holder) GameEvent.CONTAINER_CLOSE, this.position(), GameEvent.Context.of((Entity) player)); + this.level().gameEvent(GameEvent.CONTAINER_CLOSE, this.position(), GameEvent.Context.of(player)); } + ++ + // Paper start - LootTable API + final com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData = new com.destroystokyo.paper.loottable.PaperLootableInventoryData(); + @@ -73,34 +55,33 @@ + } + // Paper end - LootTable API + // CraftBukkit start -+ public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>(); ++ public java.util.List<org.bukkit.entity.HumanEntity> transaction = new java.util.ArrayList<>(); + private int maxStack = MAX_STACK; + + @Override -+ public List<ItemStack> getContents() { ++ public java.util.List<net.minecraft.world.item.ItemStack> getContents() { + return this.itemStacks; + } + + @Override -+ public void onOpen(CraftHumanEntity who) { ++ public void onOpen(org.bukkit.craftbukkit.entity.CraftHumanEntity who) { + this.transaction.add(who); + } + + @Override -+ public void onClose(CraftHumanEntity who) { ++ public void onClose(org.bukkit.craftbukkit.entity.CraftHumanEntity who) { + this.transaction.remove(who); + } + + @Override -+ public List<HumanEntity> getViewers() { ++ public java.util.List<org.bukkit.entity.HumanEntity> getViewers() { + return this.transaction; + } + + @Override -+ public InventoryHolder getOwner() { ++ public org.bukkit.inventory.InventoryHolder getOwner() { + org.bukkit.entity.Entity entity = this.getBukkitEntity(); -+ if (entity instanceof InventoryHolder) return (InventoryHolder) entity; -+ return null; ++ return entity instanceof final org.bukkit.inventory.InventoryHolder inventoryHolder ? inventoryHolder : null; + } + + @Override @@ -114,7 +95,7 @@ + } + + @Override -+ public Location getLocation() { ++ public org.bukkit.Location getLocation() { + return this.getBukkitEntity().getLocation(); + } + // CraftBukkit end diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/AbstractMinecart.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractMinecart.java.patch similarity index 58% rename from paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/AbstractMinecart.java.patch rename to paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractMinecart.java.patch index e7b99cb727..ea248c3955 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/AbstractMinecart.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractMinecart.java.patch @@ -1,23 +1,9 @@ --- a/net/minecraft/world/entity/vehicle/AbstractMinecart.java +++ b/net/minecraft/world/entity/vehicle/AbstractMinecart.java -@@ -42,6 +42,13 @@ - import net.minecraft.world.level.block.state.properties.RailShape; - import net.minecraft.world.phys.AABB; - import net.minecraft.world.phys.Vec3; -+// CraftBukkit start -+import org.bukkit.Location; -+import org.bukkit.craftbukkit.util.CraftLocation; -+import org.bukkit.entity.Vehicle; -+import org.bukkit.event.vehicle.VehicleEntityCollisionEvent; -+import org.bukkit.util.Vector; -+// CraftBukkit end - - public abstract class AbstractMinecart extends VehicleEntity { - -@@ -76,6 +83,18 @@ - enummap.put(RailShape.NORTH_EAST, Pair.of(baseblockposition2, baseblockposition1)); +@@ -74,6 +_,17 @@ + map.put(RailShape.NORTH_WEST, Pair.of(unitVec3i2, unitVec3i)); + map.put(RailShape.NORTH_EAST, Pair.of(unitVec3i2, unitVec3i1)); }); - + // CraftBukkit start + public boolean slowWhenEmpty = true; + private double derailedX = 0.5; @@ -27,32 +13,22 @@ + private double flyingY = 0.95; + private double flyingZ = 0.95; + public Double maxSpeed; -+ // CraftBukkit end + public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API -+ - protected AbstractMinecart(EntityType<?> type, Level world) { - super(type, world); - this.blocksBuilding = true; -@@ -101,7 +120,7 @@ ++ // CraftBukkit end - @Nullable - public static <T extends AbstractMinecart> T createMinecart(Level world, double x, double y, double z, EntityType<T> type, EntitySpawnReason reason, ItemStack stack, @Nullable Player player) { -- T t0 = (AbstractMinecart) type.create(world, reason); -+ T t0 = (T) type.create(world, reason); // CraftBukkit - decompile error - - if (t0 != null) { - t0.setInitialPos(x, y, z); -@@ -139,11 +158,19 @@ + protected AbstractMinecart(EntityType<?> entityType, Level level) { + super(entityType, level); +@@ -134,11 +_,19 @@ @Override - public boolean canCollideWith(Entity other) { -- return AbstractBoat.canVehicleCollide(this, other); + public boolean canCollideWith(Entity entity) { +- return AbstractBoat.canVehicleCollide(this, entity); + // Paper start - fix VehicleEntityCollisionEvent not called when colliding with player -+ boolean collides = AbstractBoat.canVehicleCollide(this, other); ++ boolean collides = AbstractBoat.canVehicleCollide(this, entity); + if (!collides) { + return false; + } -+ org.bukkit.event.vehicle.VehicleEntityCollisionEvent collisionEvent = new org.bukkit.event.vehicle.VehicleEntityCollisionEvent((org.bukkit.entity.Vehicle) getBukkitEntity(), other.getBukkitEntity()); ++ org.bukkit.event.vehicle.VehicleEntityCollisionEvent collisionEvent = new org.bukkit.event.vehicle.VehicleEntityCollisionEvent((org.bukkit.entity.Vehicle) getBukkitEntity(), entity.getBukkitEntity()); + + return collisionEvent.callEvent(); + // Paper end - fix VehicleEntityCollisionEvent not called when colliding with player @@ -64,7 +40,7 @@ return true; } -@@ -262,6 +289,14 @@ +@@ -239,6 +_,14 @@ @Override public void tick() { @@ -79,7 +55,7 @@ if (this.getHurtTime() > 0) { this.setHurtTime(this.getHurtTime() - 1); } -@@ -271,8 +306,20 @@ +@@ -248,8 +_,20 @@ } this.checkBelowWorld(); @@ -88,24 +64,24 @@ this.behavior.tick(); + // CraftBukkit start + org.bukkit.World bworld = this.level().getWorld(); -+ Location from = new Location(bworld, prevX, prevY, prevZ, prevYaw, prevPitch); -+ Location to = CraftLocation.toBukkit(this.position(), bworld, this.getYRot(), this.getXRot()); -+ Vehicle vehicle = (Vehicle) this.getBukkitEntity(); ++ org.bukkit.Location from = new org.bukkit.Location(bworld, prevX, prevY, prevZ, prevYaw, prevPitch); ++ org.bukkit.Location to = org.bukkit.craftbukkit.util.CraftLocation.toBukkit(this.position(), bworld, this.getYRot(), this.getXRot()); ++ org.bukkit.entity.Vehicle vehicle = (org.bukkit.entity.Vehicle) this.getBukkitEntity(); + -+ this.level().getCraftServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleUpdateEvent(vehicle)); ++ new org.bukkit.event.vehicle.VehicleUpdateEvent(vehicle).callEvent(); + + if (!from.equals(to)) { -+ this.level().getCraftServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleMoveEvent(vehicle, from, to)); ++ new org.bukkit.event.vehicle.VehicleMoveEvent(vehicle, from, to).callEvent(); + } + // CraftBukkit end this.updateInWaterStateAndDoFluidPushing(); if (this.isInLava()) { this.lavaHurt(); -@@ -385,12 +432,16 @@ - - this.setDeltaMovement(Mth.clamp(vec3d.x, -d0, d0), vec3d.y, Mth.clamp(vec3d.z, -d0, d0)); +@@ -360,12 +_,16 @@ + Vec3 deltaMovement = this.getDeltaMovement(); + this.setDeltaMovement(Mth.clamp(deltaMovement.x, -maxSpeed, maxSpeed), deltaMovement.y, Mth.clamp(deltaMovement.z, -maxSpeed, maxSpeed)); if (this.onGround()) { -- this.setDeltaMovement(this.getDeltaMovement().scale(0.5D)); +- this.setDeltaMovement(this.getDeltaMovement().scale(0.5)); + // CraftBukkit start - replace magic numbers with our variables + this.setDeltaMovement(new Vec3(this.getDeltaMovement().x * this.derailedX, this.getDeltaMovement().y * this.derailedY, this.getDeltaMovement().z * this.derailedZ)); + // CraftBukkit end @@ -113,20 +89,20 @@ this.move(MoverType.SELF, this.getDeltaMovement()); if (!this.onGround()) { -- this.setDeltaMovement(this.getDeltaMovement().scale(0.95D)); +- this.setDeltaMovement(this.getDeltaMovement().scale(0.95)); + // CraftBukkit start - replace magic numbers with our variables + this.setDeltaMovement(new Vec3(this.getDeltaMovement().x * this.flyingX, this.getDeltaMovement().y * this.flyingY, this.getDeltaMovement().z * this.flyingZ)); + // CraftBukkit end } - } -@@ -502,6 +553,16 @@ - this.flipped = nbt.getBoolean("FlippedRotation"); - this.firstTick = nbt.getBoolean("HasTicked"); +@@ -469,6 +_,16 @@ + + this.flipped = compound.getBoolean("FlippedRotation"); + this.firstTick = compound.getBoolean("HasTicked"); + // Paper start - Friction API -+ if (nbt.contains("Paper.FrictionState")) { -+ String fs = nbt.getString("Paper.FrictionState"); ++ if (compound.contains("Paper.FrictionState")) { ++ String fs = compound.getString("Paper.FrictionState"); + try { + frictionState = net.kyori.adventure.util.TriState.valueOf(fs); + } catch (Exception ignored) { @@ -137,14 +113,14 @@ } @Override -@@ -514,13 +575,28 @@ +@@ -481,13 +_,27 @@ - nbt.putBoolean("FlippedRotation", this.flipped); - nbt.putBoolean("HasTicked", this.firstTick); + compound.putBoolean("FlippedRotation", this.flipped); + compound.putBoolean("HasTicked", this.firstTick); + + // Paper start - Friction API + if (this.frictionState != net.kyori.adventure.util.TriState.NOT_SET) { -+ nbt.putString("Paper.FrictionState", this.frictionState.toString()); ++ compound.putString("Paper.FrictionState", this.frictionState.toString()); + } + // Paper end - Friction API } @@ -156,37 +132,36 @@ + if (!this.level().paperConfig().collisions.allowVehicleCollisions && this.level().paperConfig().collisions.onlyPlayersCollide && !(entity instanceof Player)) return; // Paper - Collision option for requiring a player participant if (!this.hasPassenger(entity)) { + // CraftBukkit start -+ VehicleEntityCollisionEvent collisionEvent = new VehicleEntityCollisionEvent((Vehicle) this.getBukkitEntity(), entity.getBukkitEntity()); -+ this.level().getCraftServer().getPluginManager().callEvent(collisionEvent); -+ -+ if (collisionEvent.isCancelled()) { -+ return; -+ } ++ org.bukkit.event.vehicle.VehicleEntityCollisionEvent collisionEvent = new org.bukkit.event.vehicle.VehicleEntityCollisionEvent( ++ (org.bukkit.entity.Vehicle) this.getBukkitEntity(), ++ entity.getBukkitEntity() ++ ); ++ if (!collisionEvent.callEvent()) return; + // CraftBukkit end - double d0 = entity.getX() - this.getX(); + double d = entity.getX() - this.getX(); double d1 = entity.getZ() - this.getZ(); - double d2 = d0 * d0 + d1 * d1; -@@ -645,4 +721,27 @@ + double d2 = d * d + d1 * d1; +@@ -602,4 +_,27 @@ public boolean isFurnace() { return false; } + + // CraftBukkit start - Methods for getting and setting flying and derailed velocity modifiers -+ public Vector getFlyingVelocityMod() { -+ return new Vector(this.flyingX, this.flyingY, this.flyingZ); ++ public org.bukkit.util.Vector getFlyingVelocityMod() { ++ return new org.bukkit.util.Vector(this.flyingX, this.flyingY, this.flyingZ); + } + -+ public void setFlyingVelocityMod(Vector flying) { ++ public void setFlyingVelocityMod(org.bukkit.util.Vector flying) { + this.flyingX = flying.getX(); + this.flyingY = flying.getY(); + this.flyingZ = flying.getZ(); + } + -+ public Vector getDerailedVelocityMod() { -+ return new Vector(this.derailedX, this.derailedY, this.derailedZ); ++ public org.bukkit.util.Vector getDerailedVelocityMod() { ++ return new org.bukkit.util.Vector(this.derailedX, this.derailedY, this.derailedZ); + } + -+ public void setDerailedVelocityMod(Vector derailed) { ++ public void setDerailedVelocityMod(org.bukkit.util.Vector derailed) { + this.derailedX = derailed.getX(); + this.derailedY = derailed.getY(); + this.derailedZ = derailed.getZ(); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java.patch new file mode 100644 index 0000000000..5a1e4c8f55 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java.patch @@ -0,0 +1,83 @@ +--- a/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java ++++ b/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java +@@ -21,11 +_,59 @@ + import net.minecraft.world.phys.Vec3; + + public abstract class AbstractMinecartContainer extends AbstractMinecart implements ContainerEntity { +- private NonNullList<ItemStack> itemStacks = NonNullList.withSize(36, ItemStack.EMPTY); ++ private NonNullList<ItemStack> itemStacks = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); // CraftBukkit - SPIGOT-3513 + @Nullable + public ResourceKey<LootTable> lootTable; + public long lootTableSeed; + ++ // Paper start - LootTable API ++ final com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData = new com.destroystokyo.paper.loottable.PaperLootableInventoryData(); ++ ++ @Override ++ public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData() { ++ return this.lootableData; ++ } ++ // Paper end - LootTable API ++ // CraftBukkit start ++ public java.util.List<org.bukkit.entity.HumanEntity> transaction = new java.util.ArrayList<>(); ++ private int maxStack = MAX_STACK; ++ ++ public java.util.List<net.minecraft.world.item.ItemStack> getContents() { ++ return this.itemStacks; ++ } ++ ++ public void onOpen(org.bukkit.craftbukkit.entity.CraftHumanEntity who) { ++ this.transaction.add(who); ++ } ++ ++ public void onClose(org.bukkit.craftbukkit.entity.CraftHumanEntity who) { ++ this.transaction.remove(who); ++ } ++ ++ public java.util.List<org.bukkit.entity.HumanEntity> getViewers() { ++ return this.transaction; ++ } ++ ++ public org.bukkit.inventory.InventoryHolder getOwner() { ++ return this.getBukkitEntity() instanceof final org.bukkit.inventory.InventoryHolder inventoryHolder ? inventoryHolder : null; ++ } ++ ++ @Override ++ public int getMaxStackSize() { ++ return this.maxStack; ++ } ++ ++ public void setMaxStackSize(int size) { ++ this.maxStack = size; ++ } ++ ++ @Override ++ public org.bukkit.Location getLocation() { ++ return this.getBukkitEntity().getLocation(); ++ } ++ // CraftBukkit end ++ ++ + protected AbstractMinecartContainer(EntityType<?> entityType, Level level) { + super(entityType, level); + } +@@ -72,11 +_,18 @@ + + @Override + public void remove(Entity.RemovalReason reason) { ++ // CraftBukkit start - add Bukkit remove cause ++ this.remove(reason, null); ++ } ++ ++ @Override ++ public void remove(Entity.RemovalReason reason, org.bukkit.event.entity.EntityRemoveEvent.Cause cause) { ++ // CraftBukkit end - add Bukkit remove cause + if (!this.level().isClientSide && reason.shouldDestroy()) { + Containers.dropContents(this.level(), this, this); + } + +- super.remove(reason); ++ super.remove(reason, cause); // CraftBukkit - add Bukkit remove cause + } + + @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch similarity index 61% rename from paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch rename to paper-server/patches/sources/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch index 3ac071ee7d..fea198069c 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch @@ -1,38 +1,38 @@ --- a/net/minecraft/world/entity/vehicle/ContainerEntity.java +++ b/net/minecraft/world/entity/vehicle/ContainerEntity.java -@@ -62,22 +62,26 @@ - default void addChestVehicleSaveData(CompoundTag nbt, HolderLookup.Provider registries) { +@@ -62,22 +_,26 @@ + default void addChestVehicleSaveData(CompoundTag tag, HolderLookup.Provider levelRegistry) { if (this.getContainerLootTable() != null) { - nbt.putString("LootTable", this.getContainerLootTable().location().toString()); -+ this.lootableData().saveNbt(nbt); // Paper + tag.putString("LootTable", this.getContainerLootTable().location().toString()); ++ this.lootableData().saveNbt(tag); // Paper if (this.getContainerLootTableSeed() != 0L) { - nbt.putLong("LootTableSeed", this.getContainerLootTableSeed()); + tag.putLong("LootTableSeed", this.getContainerLootTableSeed()); } - } else { -- ContainerHelper.saveAllItems(nbt, this.getItemStacks(), registries); +- ContainerHelper.saveAllItems(tag, this.getItemStacks(), levelRegistry); } -+ ContainerHelper.saveAllItems(nbt, this.getItemStacks(), registries); // Paper - always save the items, table may still remain ++ ContainerHelper.saveAllItems(tag, this.getItemStacks(), levelRegistry); // Paper - always save the items, table may still remain } - default void readChestVehicleSaveData(CompoundTag nbt, HolderLookup.Provider registries) { + default void readChestVehicleSaveData(CompoundTag tag, HolderLookup.Provider levelRegistry) { this.clearItemStacks(); - if (nbt.contains("LootTable", 8)) { -- this.setContainerLootTable(ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(nbt.getString("LootTable")))); -+ this.setContainerLootTable(net.minecraft.Optionull.map(ResourceLocation.tryParse(nbt.getString("LootTable")), rl -> ResourceKey.create(Registries.LOOT_TABLE, rl))); // Paper - Validate ResourceLocation + if (tag.contains("LootTable", 8)) { +- this.setContainerLootTable(ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(tag.getString("LootTable")))); ++ this.setContainerLootTable(net.minecraft.Optionull.map(ResourceLocation.tryParse(tag.getString("LootTable")), rl -> ResourceKey.create(Registries.LOOT_TABLE, rl))); // Paper - Validate ResourceLocation + // Paper start - LootTable API + if (this.getContainerLootTable() != null) { -+ this.lootableData().loadNbt(nbt); ++ this.lootableData().loadNbt(tag); + } + // Paper end - LootTable API - this.setContainerLootTableSeed(nbt.getLong("LootTableSeed")); + this.setContainerLootTableSeed(tag.getLong("LootTableSeed")); - } else { -- ContainerHelper.loadAllItems(nbt, this.getItemStacks(), registries); +- ContainerHelper.loadAllItems(tag, this.getItemStacks(), levelRegistry); } -+ ContainerHelper.loadAllItems(nbt, this.getItemStacks(), registries); // Paper - always save the items, table may still remain ++ ContainerHelper.loadAllItems(tag, this.getItemStacks(), levelRegistry); // Paper - always read the items, table may still remain } - default void chestVehicleDestroyed(DamageSource source, ServerLevel world, Entity vehicle) { -@@ -91,19 +95,28 @@ + default void chestVehicleDestroyed(DamageSource damageSource, ServerLevel level, Entity entity) { +@@ -91,19 +_,27 @@ } default InteractionResult interactWithContainerVehicle(Player player) { @@ -46,10 +46,10 @@ } default void unpackChestVehicleLootTable(@Nullable Player player) { - MinecraftServer minecraftServer = this.level().getServer(); -- if (this.getContainerLootTable() != null && minecraftServer != null) { -+ if (minecraftServer != null && this.lootableData().shouldReplenish(this, com.destroystokyo.paper.loottable.PaperLootableInventoryData.ENTITY, player)) { // Paper - LootTable API - LootTable lootTable = minecraftServer.reloadableRegistries().getLootTable(this.getContainerLootTable()); + MinecraftServer server = this.level().getServer(); +- if (this.getContainerLootTable() != null && server != null) { ++ if (server != null && this.lootableData().shouldReplenish(this, com.destroystokyo.paper.loottable.PaperLootableInventoryData.ENTITY, player)) { // Paper - LootTable API + LootTable lootTable = server.reloadableRegistries().getLootTable(this.getContainerLootTable()); if (player != null) { CriteriaTriggers.GENERATE_LOOT.trigger((ServerPlayer)player, this.getContainerLootTable()); } @@ -60,11 +60,10 @@ + this.setContainerLootTable(null); + } + // Paper end - LootTable API -+ LootParams.Builder builder = new LootParams.Builder((ServerLevel)this.level()).withParameter(LootContextParams.ORIGIN, this.position()); if (player != null) { builder.withLuck(player.getLuck()).withParameter(LootContextParams.THIS_ENTITY, player); -@@ -173,4 +186,14 @@ +@@ -173,4 +_,14 @@ default boolean isChestVehicleStillValid(Player player) { return !this.isRemoved() && player.canInteractWithEntity(this.getBoundingBox(), 4.0); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java.patch new file mode 100644 index 0000000000..7a3a6b08c0 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java.patch @@ -0,0 +1,24 @@ +--- a/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java ++++ b/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java +@@ -126,7 +_,7 @@ + MinecartCommandBlock.this.position(), + MinecartCommandBlock.this.getRotationVector(), + this.getLevel(), +- 2, ++ this.getLevel().paperConfig().commandBlocks.permissionsLevel, // Paper - configurable command block perm level + this.getName().getString(), + MinecartCommandBlock.this.getDisplayName(), + this.getLevel().getServer(), +@@ -138,5 +_,12 @@ + public boolean isValid() { + return !MinecartCommandBlock.this.isRemoved(); + } ++ ++ // CraftBukkit start ++ @Override ++ public org.bukkit.command.CommandSender getBukkitSender(CommandSourceStack wrapper) { ++ return net.minecraft.world.entity.vehicle.MinecartCommandBlock.this.getBukkitEntity(); ++ } ++ // CraftBukkit end + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/MinecartTNT.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/MinecartTNT.java.patch new file mode 100644 index 0000000000..8cfbf8de7d --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/MinecartTNT.java.patch @@ -0,0 +1,56 @@ +--- a/net/minecraft/world/entity/vehicle/MinecartTNT.java ++++ b/net/minecraft/world/entity/vehicle/MinecartTNT.java +@@ -33,6 +_,7 @@ + public int fuse = -1; + public float explosionPowerBase = 4.0F; + public float explosionSpeedFactor = 1.0F; ++ public boolean isIncendiary = false; // CraftBukkit - add field + + public MinecartTNT(EntityType<? extends MinecartTNT> entityType, Level level) { + super(entityType, level); +@@ -47,6 +_,12 @@ + public void tick() { + super.tick(); + if (this.fuse > 0) { ++ // Paper start - Configurable TNT height nerf ++ if (this.level().paperConfig().fixes.tntEntityHeightNerf.test(v -> this.getY() > v)) { ++ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.OUT_OF_WORLD); ++ return; ++ } ++ // Paper end - Configurable TNT height nerf + this.fuse--; + this.level().addParticle(ParticleTypes.SMOKE, this.getX(), this.getY() + 0.5, this.getZ(), 0.0, 0.0, 0.0); + } else if (this.fuse == 0) { +@@ -101,6 +_,17 @@ + protected void explode(@Nullable DamageSource damageSource, double radiusModifier) { + if (this.level() instanceof ServerLevel serverLevel) { + double min = Math.min(Math.sqrt(radiusModifier), 5.0); ++ // CraftBukkit start ++ org.bukkit.event.entity.ExplosionPrimeEvent event = new org.bukkit.event.entity.ExplosionPrimeEvent( ++ this.getBukkitEntity(), ++ (float) ((double) this.explosionPowerBase + (double) this.explosionSpeedFactor * this.random.nextDouble() * 1.5D * min), ++ this.isIncendiary ++ ); ++ if (!event.callEvent()) { ++ this.fuse = -1; ++ return; ++ } ++ // CraftBukkit end + serverLevel.explode( + this, + damageSource, +@@ -108,11 +_,11 @@ + this.getX(), + this.getY(), + this.getZ(), +- (float)(this.explosionPowerBase + this.explosionSpeedFactor * this.random.nextDouble() * 1.5 * min), +- false, ++ event.getRadius(), // CraftBukkit - explosion prime event ++ event.getFire(), // CraftBukkit - explosion prime event + Level.ExplosionInteraction.TNT + ); +- this.discard(); ++ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause + } + } + diff --git a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java.patch new file mode 100644 index 0000000000..510d8fd645 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java.patch @@ -0,0 +1,73 @@ +--- a/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java ++++ b/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java +@@ -479,6 +_,12 @@ + + @Override + public double getMaxSpeed(ServerLevel level) { ++ // CraftBukkit start ++ Double maxSpeed = this.minecart.maxSpeed; ++ if (maxSpeed != null) { ++ return (this.minecart.isInWater() ? maxSpeed / 2.0D : maxSpeed); ++ } ++ // CraftBukkit end + return level.getGameRules().getInt(GameRules.RULE_MINECART_MAX_SPEED) * (this.minecart.isInWater() ? 0.5 : 1.0) / 20.0; + } + +@@ -494,7 +_,8 @@ + + @Override + public double getSlowdownFactor() { +- return this.minecart.isVehicle() ? 0.997 : 0.975; ++ if (this.minecart.frictionState == net.kyori.adventure.util.TriState.FALSE) return 1; // Paper ++ return this.minecart.isVehicle() || !this.minecart.slowWhenEmpty ? 0.997D : 0.975D; // CraftBukkit - add !this.slowWhenEmpty + } + + @Override +@@ -518,6 +_,13 @@ + && !(entity instanceof AbstractMinecart) + && !this.minecart.isVehicle() + && !entity.isPassenger()) { ++ // CraftBukkit start ++ org.bukkit.event.vehicle.VehicleEntityCollisionEvent collisionEvent = new org.bukkit.event.vehicle.VehicleEntityCollisionEvent( ++ (org.bukkit.entity.Vehicle) this.minecart.getBukkitEntity(), ++ entity.getBukkitEntity() ++ ); ++ if (!collisionEvent.callEvent()) continue; ++ // CraftBukkit end + boolean flag = entity.startRiding(this.minecart); + if (flag) { + return true; +@@ -541,6 +_,17 @@ + || entity instanceof AbstractMinecart + || this.minecart.isVehicle() + || entity.isPassenger()) { ++ // CraftBukkit start ++ if (!this.minecart.isPassengerOfSameVehicle(entity)) { ++ org.bukkit.event.vehicle.VehicleEntityCollisionEvent collisionEvent = new org.bukkit.event.vehicle.VehicleEntityCollisionEvent( ++ (org.bukkit.entity.Vehicle) this.minecart.getBukkitEntity(), ++ entity.getBukkitEntity() ++ ); ++ if (!collisionEvent.callEvent()) { ++ continue; ++ } ++ } ++ // CraftBukkit end + entity.push(this.minecart); + flag = true; + } +@@ -549,6 +_,15 @@ + } else { + for (Entity entity1 : this.level().getEntities(this.minecart, box)) { + if (!this.minecart.hasPassenger(entity1) && entity1.isPushable() && entity1 instanceof AbstractMinecart) { ++ // CraftBukkit start ++ org.bukkit.event.vehicle.VehicleEntityCollisionEvent collisionEvent = new org.bukkit.event.vehicle.VehicleEntityCollisionEvent( ++ (org.bukkit.entity.Vehicle) this.minecart.getBukkitEntity(), ++ entity1.getBukkitEntity() ++ ); ++ if (!collisionEvent.callEvent()) { ++ continue; ++ } ++ // CraftBukkit end + entity1.push(this.minecart); + flag = true; + } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java.patch new file mode 100644 index 0000000000..71af93aa6c --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java.patch @@ -0,0 +1,58 @@ +--- a/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java ++++ b/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java +@@ -414,8 +_,22 @@ + && !(entity instanceof AbstractMinecart) + && !this.minecart.isVehicle() + && !entity.isPassenger()) { ++ // CraftBukkit start ++ org.bukkit.event.vehicle.VehicleEntityCollisionEvent collisionEvent = new org.bukkit.event.vehicle.VehicleEntityCollisionEvent( ++ (org.bukkit.entity.Vehicle) this.minecart.getBukkitEntity(), entity.getBukkitEntity() ++ ); ++ if (!collisionEvent.callEvent()) continue; ++ // CraftBukkit end + entity.startRiding(this.minecart); + } else { ++ // CraftBukkit start ++ if (!this.minecart.isPassengerOfSameVehicle(entity)) { ++ org.bukkit.event.vehicle.VehicleEntityCollisionEvent collisionEvent = new org.bukkit.event.vehicle.VehicleEntityCollisionEvent( ++ (org.bukkit.entity.Vehicle) this.minecart.getBukkitEntity(), entity.getBukkitEntity() ++ ); ++ if (!collisionEvent.callEvent()) continue; ++ } ++ // CraftBukkit end + entity.push(this.minecart); + } + } +@@ -423,6 +_,12 @@ + } else { + for (Entity entity1 : this.level().getEntities(this.minecart, aabb)) { + if (!this.minecart.hasPassenger(entity1) && entity1.isPushable() && entity1 instanceof AbstractMinecart) { ++ // CraftBukkit start ++ org.bukkit.event.vehicle.VehicleEntityCollisionEvent collisionEvent = new org.bukkit.event.vehicle.VehicleEntityCollisionEvent( ++ (org.bukkit.entity.Vehicle) this.minecart.getBukkitEntity(), entity1.getBukkitEntity() ++ ); ++ if (!collisionEvent.callEvent()) continue; ++ // CraftBukkit end + entity1.push(this.minecart); + } + } +@@ -443,11 +_,18 @@ + + @Override + public double getMaxSpeed(ServerLevel level) { ++ // CraftBukkit start ++ Double maxSpeed = this.minecart.maxSpeed; ++ if (maxSpeed != null) { ++ return (this.minecart.isInWater() ? maxSpeed / 2.0D : maxSpeed); ++ } ++ // CraftBukkit end + return this.minecart.isInWater() ? 0.2 : 0.4; + } + + @Override + public double getSlowdownFactor() { +- return this.minecart.isVehicle() ? 0.997 : 0.96; ++ if (this.minecart.frictionState == net.kyori.adventure.util.TriState.FALSE) return 1; // Paper ++ return this.minecart.isVehicle() || !this.minecart.slowWhenEmpty ? 0.997D : 0.96D; // CraftBukkit - add !this.slowWhenEmpty + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/VehicleEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/VehicleEntity.java.patch new file mode 100644 index 0000000000..0020b09f51 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/VehicleEntity.java.patch @@ -0,0 +1,42 @@ +--- a/net/minecraft/world/entity/vehicle/VehicleEntity.java ++++ b/net/minecraft/world/entity/vehicle/VehicleEntity.java +@@ -38,6 +_,14 @@ + } else if (this.isInvulnerableToBase(damageSource)) { + return false; + } else { ++ // CraftBukkit start ++ org.bukkit.entity.Vehicle vehicle = (org.bukkit.entity.Vehicle) this.getBukkitEntity(); ++ org.bukkit.entity.Entity attacker = (damageSource.getEntity() == null) ? null : damageSource.getEntity().getBukkitEntity(); ++ ++ org.bukkit.event.vehicle.VehicleDamageEvent event = new org.bukkit.event.vehicle.VehicleDamageEvent(vehicle, attacker, amount); ++ if (!event.callEvent()) return false; ++ amount = (float) event.getDamage(); ++ // CraftBukkit end + this.setHurtDir(-this.getHurtDir()); + this.setHurtTime(10); + this.markHurt(); +@@ -46,9 +_,23 @@ + boolean flag = damageSource.getEntity() instanceof Player player && player.getAbilities().instabuild; + if ((flag || !(this.getDamage() > 40.0F)) && !this.shouldSourceDestroy(damageSource)) { + if (flag) { +- this.discard(); ++ // CraftBukkit start ++ org.bukkit.event.vehicle.VehicleDestroyEvent destroyEvent = new org.bukkit.event.vehicle.VehicleDestroyEvent(vehicle, attacker); ++ if (!destroyEvent.callEvent()) { ++ this.setDamage(40.0F); // Maximize damage so this doesn't get triggered again right away ++ return true; ++ } ++ // CraftBukkit end ++ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause + } + } else { ++ // CraftBukkit start ++ org.bukkit.event.vehicle.VehicleDestroyEvent destroyEvent = new org.bukkit.event.vehicle.VehicleDestroyEvent(vehicle, attacker); ++ if (!destroyEvent.callEvent()) { ++ this.setDamage(40.0F); // Maximize damage so this doesn't get triggered again right away ++ return true; ++ } ++ // CraftBukkit end + this.destroy(level, damageSource); + } + diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java.patch deleted file mode 100644 index b33136b346..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java.patch +++ /dev/null @@ -1,98 +0,0 @@ ---- a/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java -+++ b/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java -@@ -20,6 +20,14 @@ - import net.minecraft.world.level.Level; - import net.minecraft.world.level.storage.loot.LootTable; - import net.minecraft.world.phys.Vec3; -+// CraftBukkit start -+import java.util.List; -+import org.bukkit.Location; -+import org.bukkit.craftbukkit.entity.CraftHumanEntity; -+import org.bukkit.entity.HumanEntity; -+import org.bukkit.event.entity.EntityRemoveEvent; -+import org.bukkit.inventory.InventoryHolder; -+// CraftBukkit end - - public abstract class AbstractMinecartContainer extends AbstractMinecart implements ContainerEntity { - -@@ -28,9 +36,58 @@ - public ResourceKey<LootTable> lootTable; - public long lootTableSeed; - -+ // Paper start - LootTable API -+ final com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData = new com.destroystokyo.paper.loottable.PaperLootableInventoryData(); -+ -+ @Override -+ public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData() { -+ return this.lootableData; -+ } -+ // Paper end - LootTable API -+ // CraftBukkit start -+ public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>(); -+ private int maxStack = MAX_STACK; -+ -+ public List<ItemStack> getContents() { -+ return this.itemStacks; -+ } -+ -+ public void onOpen(CraftHumanEntity who) { -+ this.transaction.add(who); -+ } -+ -+ public void onClose(CraftHumanEntity who) { -+ this.transaction.remove(who); -+ } -+ -+ public List<HumanEntity> getViewers() { -+ return this.transaction; -+ } -+ -+ public InventoryHolder getOwner() { -+ org.bukkit.entity.Entity cart = this.getBukkitEntity(); -+ if(cart instanceof InventoryHolder) return (InventoryHolder) cart; -+ return null; -+ } -+ -+ @Override -+ public int getMaxStackSize() { -+ return this.maxStack; -+ } -+ -+ public void setMaxStackSize(int size) { -+ this.maxStack = size; -+ } -+ -+ @Override -+ public Location getLocation() { -+ return this.getBukkitEntity().getLocation(); -+ } -+ // CraftBukkit end -+ - protected AbstractMinecartContainer(EntityType<?> type, Level world) { - super(type, world); -- this.itemStacks = NonNullList.withSize(36, ItemStack.EMPTY); -+ this.itemStacks = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); // CraftBukkit - SPIGOT-3513 - } - - @Override -@@ -74,11 +131,18 @@ - - @Override - public void remove(Entity.RemovalReason reason) { -- if (!this.level().isClientSide && reason.shouldDestroy()) { -+ // CraftBukkit start - add Bukkit remove cause -+ this.remove(reason, null); -+ } -+ -+ @Override -+ public void remove(Entity.RemovalReason entity_removalreason, EntityRemoveEvent.Cause cause) { -+ // CraftBukkit end -+ if (!this.level().isClientSide && entity_removalreason.shouldDestroy()) { - Containers.dropContents(this.level(), (Entity) this, (Container) this); - } - -- super.remove(reason); -+ super.remove(entity_removalreason, cause); // CraftBukkit - add Bukkit remove cause - } - - @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java.patch deleted file mode 100644 index 7c789e80ad..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java -+++ b/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java -@@ -128,12 +128,19 @@ - - @Override - public CommandSourceStack createCommandSourceStack() { -- return new CommandSourceStack(this, MinecartCommandBlock.this.position(), MinecartCommandBlock.this.getRotationVector(), this.getLevel(), 2, this.getName().getString(), MinecartCommandBlock.this.getDisplayName(), this.getLevel().getServer(), MinecartCommandBlock.this); -+ return new CommandSourceStack(this, MinecartCommandBlock.this.position(), MinecartCommandBlock.this.getRotationVector(), this.getLevel(), this.getLevel().paperConfig().commandBlocks.permissionsLevel, this.getName().getString(), MinecartCommandBlock.this.getDisplayName(), this.getLevel().getServer(), MinecartCommandBlock.this); // Paper - configurable command block perm level - } - - @Override - public boolean isValid() { - return !MinecartCommandBlock.this.isRemoved(); - } -+ -+ // CraftBukkit start -+ @Override -+ public org.bukkit.command.CommandSender getBukkitSender(CommandSourceStack wrapper) { -+ return (org.bukkit.craftbukkit.entity.CraftMinecartCommand) MinecartCommandBlock.this.getBukkitEntity(); -+ } -+ // CraftBukkit end - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/MinecartTNT.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/MinecartTNT.java.patch deleted file mode 100644 index 7fdf216d8a..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/MinecartTNT.java.patch +++ /dev/null @@ -1,53 +0,0 @@ ---- a/net/minecraft/world/entity/vehicle/MinecartTNT.java -+++ b/net/minecraft/world/entity/vehicle/MinecartTNT.java -@@ -25,6 +25,10 @@ - import net.minecraft.world.level.block.Blocks; - import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.level.material.FluidState; -+// CraftBukkit start -+import org.bukkit.event.entity.EntityRemoveEvent; -+import org.bukkit.event.entity.ExplosionPrimeEvent; -+// CraftBukkit end - - public class MinecartTNT extends AbstractMinecart { - -@@ -37,6 +41,7 @@ - public int fuse = -1; - public float explosionPowerBase = 4.0F; - public float explosionSpeedFactor = 1.0F; -+ public boolean isIncendiary = false; // CraftBukkit - add field - - public MinecartTNT(EntityType<? extends MinecartTNT> type, Level world) { - super(type, world); -@@ -51,6 +56,12 @@ - public void tick() { - super.tick(); - if (this.fuse > 0) { -+ // 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.fuse; - this.level().addParticle(ParticleTypes.SMOKE, this.getX(), this.getY() + 0.5D, this.getZ(), 0.0D, 0.0D, 0.0D); - } else if (this.fuse == 0) { -@@ -117,8 +128,16 @@ - if (world instanceof ServerLevel worldserver) { - double d1 = Math.min(Math.sqrt(power), 5.0D); - -- worldserver.explode(this, damageSource, (ExplosionDamageCalculator) null, this.getX(), this.getY(), this.getZ(), (float) ((double) this.explosionPowerBase + (double) this.explosionSpeedFactor * this.random.nextDouble() * 1.5D * d1), false, Level.ExplosionInteraction.TNT); -- this.discard(); -+ // CraftBukkit start -+ ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), (float) ((double) this.explosionPowerBase + (double) this.explosionSpeedFactor * this.random.nextDouble() * 1.5D * d1), this.isIncendiary); -+ worldserver.getCraftServer().getPluginManager().callEvent(event); -+ if (event.isCancelled()) { -+ this.fuse = -1; -+ return; -+ } -+ worldserver.explode(this, damageSource, (ExplosionDamageCalculator) null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.TNT); -+ // CraftBukkit end -+ this.discard(EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause - } - - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java.patch deleted file mode 100644 index 8bed619b55..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java.patch +++ /dev/null @@ -1,83 +0,0 @@ ---- a/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java -+++ b/net/minecraft/world/entity/vehicle/NewMinecartBehavior.java -@@ -27,6 +27,10 @@ - import net.minecraft.world.level.block.state.properties.RailShape; - import net.minecraft.world.phys.AABB; - import net.minecraft.world.phys.Vec3; -+// CraftBukkit start -+import org.bukkit.entity.Vehicle; -+import org.bukkit.event.vehicle.VehicleEntityCollisionEvent; -+// CraftBukkit end - - public class NewMinecartBehavior extends MinecartBehavior { - -@@ -516,6 +520,12 @@ - - @Override - public double getMaxSpeed(ServerLevel world) { -+ // CraftBukkit start -+ Double maxSpeed = this.minecart.maxSpeed; -+ if (maxSpeed != null) { -+ return (this.minecart.isInWater() ? maxSpeed / 2.0D : maxSpeed); -+ } -+ // CraftBukkit end - return (double) world.getGameRules().getInt(GameRules.RULE_MINECART_MAX_SPEED) * (this.minecart.isInWater() ? 0.5D : 1.0D) / 20.0D; - } - -@@ -544,7 +554,8 @@ - - @Override - public double getSlowdownFactor() { -- return this.minecart.isVehicle() ? 0.997D : 0.975D; -+ if (this.minecart.frictionState == net.kyori.adventure.util.TriState.FALSE) return 1; // Paper -+ return this.minecart.isVehicle() || !this.minecart.slowWhenEmpty ? 0.997D : 0.975D; // CraftBukkit - add !this.slowWhenEmpty - } - - @Override -@@ -571,6 +582,14 @@ - Entity entity = (Entity) iterator.next(); - - if (!(entity instanceof Player) && !(entity instanceof IronGolem) && !(entity instanceof AbstractMinecart) && !this.minecart.isVehicle() && !entity.isPassenger()) { -+ // CraftBukkit start -+ VehicleEntityCollisionEvent collisionEvent = new VehicleEntityCollisionEvent((Vehicle) this.minecart.getBukkitEntity(), entity.getBukkitEntity()); -+ this.level().getCraftServer().getPluginManager().callEvent(collisionEvent); -+ -+ if (collisionEvent.isCancelled()) { -+ continue; -+ } -+ // CraftBukkit end - boolean flag = entity.startRiding(this.minecart); - - if (flag) { -@@ -597,6 +616,16 @@ - Entity entity = (Entity) iterator.next(); - - if (entity instanceof Player || entity instanceof IronGolem || entity instanceof AbstractMinecart || this.minecart.isVehicle() || entity.isPassenger()) { -+ // CraftBukkit start -+ if (!this.minecart.isPassengerOfSameVehicle(entity)) { -+ VehicleEntityCollisionEvent collisionEvent = new VehicleEntityCollisionEvent((Vehicle) this.minecart.getBukkitEntity(), entity.getBukkitEntity()); -+ this.level().getCraftServer().getPluginManager().callEvent(collisionEvent); -+ -+ if (collisionEvent.isCancelled()) { -+ continue; -+ } -+ } -+ // CraftBukkit end - entity.push((Entity) this.minecart); - flag = true; - } -@@ -609,6 +638,14 @@ - Entity entity1 = (Entity) iterator1.next(); - - if (!this.minecart.hasPassenger(entity1) && entity1.isPushable() && entity1 instanceof AbstractMinecart) { -+ // CraftBukkit start -+ VehicleEntityCollisionEvent collisionEvent = new VehicleEntityCollisionEvent((Vehicle) this.minecart.getBukkitEntity(), entity1.getBukkitEntity()); -+ this.level().getCraftServer().getPluginManager().callEvent(collisionEvent); -+ -+ if (collisionEvent.isCancelled()) { -+ continue; -+ } -+ // CraftBukkit end - entity1.push((Entity) this.minecart); - flag = true; - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java.patch deleted file mode 100644 index 5f791f5901..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java.patch +++ /dev/null @@ -1,75 +0,0 @@ ---- a/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java -+++ b/net/minecraft/world/entity/vehicle/OldMinecartBehavior.java -@@ -24,6 +24,10 @@ - import net.minecraft.world.level.block.state.properties.RailShape; - import net.minecraft.world.phys.AABB; - import net.minecraft.world.phys.Vec3; -+// CraftBukkit start -+import org.bukkit.entity.Vehicle; -+import org.bukkit.event.vehicle.VehicleEntityCollisionEvent; -+// CraftBukkit end - - public class OldMinecartBehavior extends MinecartBehavior { - -@@ -454,8 +458,26 @@ - Entity entity = (Entity) iterator.next(); - - if (!(entity instanceof Player) && !(entity instanceof IronGolem) && !(entity instanceof AbstractMinecart) && !this.minecart.isVehicle() && !entity.isPassenger()) { -+ // CraftBukkit start -+ VehicleEntityCollisionEvent collisionEvent = new VehicleEntityCollisionEvent((Vehicle) this.minecart.getBukkitEntity(), entity.getBukkitEntity()); -+ this.level().getCraftServer().getPluginManager().callEvent(collisionEvent); -+ -+ if (collisionEvent.isCancelled()) { -+ continue; -+ } -+ // CraftBukkit end - entity.startRiding(this.minecart); - } else { -+ // CraftBukkit start -+ if (!this.minecart.isPassengerOfSameVehicle(entity)) { -+ VehicleEntityCollisionEvent collisionEvent = new VehicleEntityCollisionEvent((Vehicle) this.minecart.getBukkitEntity(), entity.getBukkitEntity()); -+ this.level().getCraftServer().getPluginManager().callEvent(collisionEvent); -+ -+ if (collisionEvent.isCancelled()) { -+ continue; -+ } -+ } -+ // CraftBukkit end - entity.push((Entity) this.minecart); - } - } -@@ -467,6 +489,14 @@ - Entity entity1 = (Entity) iterator1.next(); - - if (!this.minecart.hasPassenger(entity1) && entity1.isPushable() && entity1 instanceof AbstractMinecart) { -+ // CraftBukkit start -+ VehicleEntityCollisionEvent collisionEvent = new VehicleEntityCollisionEvent((Vehicle) this.minecart.getBukkitEntity(), entity1.getBukkitEntity()); -+ this.level().getCraftServer().getPluginManager().callEvent(collisionEvent); -+ -+ if (collisionEvent.isCancelled()) { -+ continue; -+ } -+ // CraftBukkit end - entity1.push((Entity) this.minecart); - } - } -@@ -487,11 +517,18 @@ - - @Override - public double getMaxSpeed(ServerLevel world) { -+ // CraftBukkit start -+ Double maxSpeed = this.minecart.maxSpeed; -+ if (maxSpeed != null) { -+ return (this.minecart.isInWater() ? maxSpeed / 2.0D : maxSpeed); -+ } -+ // CraftBukkit end - return this.minecart.isInWater() ? 0.2D : 0.4D; - } - - @Override - public double getSlowdownFactor() { -- return this.minecart.isVehicle() ? 0.997D : 0.96D; -+ if (this.minecart.frictionState == net.kyori.adventure.util.TriState.FALSE) return 1; // Paper -+ return this.minecart.isVehicle() || !this.minecart.slowWhenEmpty ? 0.997D : 0.96D; // CraftBukkit - add !this.slowWhenEmpty - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/VehicleEntity.java.patch b/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/VehicleEntity.java.patch deleted file mode 100644 index 10fce15f79..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/entity/vehicle/VehicleEntity.java.patch +++ /dev/null @@ -1,64 +0,0 @@ ---- a/net/minecraft/world/entity/vehicle/VehicleEntity.java -+++ b/net/minecraft/world/entity/vehicle/VehicleEntity.java -@@ -17,6 +17,13 @@ - import net.minecraft.world.level.Level; - import net.minecraft.world.level.gameevent.GameEvent; - -+// CraftBukkit start -+import org.bukkit.entity.Vehicle; -+import org.bukkit.event.entity.EntityRemoveEvent; -+import org.bukkit.event.vehicle.VehicleDamageEvent; -+import org.bukkit.event.vehicle.VehicleDestroyEvent; -+// CraftBukkit end -+ - public abstract class VehicleEntity extends Entity { - - protected static final EntityDataAccessor<Integer> DATA_ID_HURT = SynchedEntityData.defineId(VehicleEntity.class, EntityDataSerializers.INT); -@@ -40,6 +47,18 @@ - return false; - } else { - boolean flag; -+ // CraftBukkit start -+ Vehicle vehicle = (Vehicle) this.getBukkitEntity(); -+ org.bukkit.entity.Entity attacker = (source.getEntity() == null) ? null : source.getEntity().getBukkitEntity(); -+ -+ VehicleDamageEvent event = new VehicleDamageEvent(vehicle, attacker, (double) amount); -+ this.level().getCraftServer().getPluginManager().callEvent(event); -+ -+ if (event.isCancelled()) { -+ return false; -+ } -+ amount = (float) event.getDamage(); -+ // CraftBukkit end - label32: - { - this.setHurtDir(-this.getHurtDir()); -@@ -65,9 +84,27 @@ - - if ((flag1 || this.getDamage() <= 40.0F) && !this.shouldSourceDestroy(source)) { - if (flag1) { -- this.discard(); -+ // CraftBukkit start -+ VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, attacker); -+ this.level().getCraftServer().getPluginManager().callEvent(destroyEvent); -+ -+ if (destroyEvent.isCancelled()) { -+ this.setDamage(40.0F); // Maximize damage so this doesn't get triggered again right away -+ return true; -+ } -+ // CraftBukkit end -+ this.discard(EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause - } - } else { -+ // CraftBukkit start -+ VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, attacker); -+ this.level().getCraftServer().getPluginManager().callEvent(destroyEvent); -+ -+ if (destroyEvent.isCancelled()) { -+ this.setDamage(40.0F); // Maximize damage so this doesn't get triggered again right away -+ return true; -+ } -+ // CraftBukkit end - this.destroy(world, source); - } -