aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOwen <[email protected]>2022-10-11 17:04:26 -0400
committerGitHub <[email protected]>2022-10-11 22:04:26 +0100
commit6b26cfcd310c7345330e46e89fc90b0e3368f0e0 (patch)
tree5acd45d487c4a7ab95ae18eac6b7920630a83b01
parentb097a241c0eed9235be1dae195cb7929fb701527 (diff)
downloadPaper-6b26cfcd310c7345330e46e89fc90b0e3368f0e0.tar.gz
Paper-6b26cfcd310c7345330e46e89fc90b0e3368f0e0.zip
Add missing Entity + Projectile API (#7632)
-rw-r--r--build-data/paper.at24
-rw-r--r--patches/api/0311-Missing-Entity-Behavior-API.patch436
-rw-r--r--patches/api/0370-More-Projectile-API.patch186
-rw-r--r--patches/server/0619-Add-more-WanderingTrader-API.patch4
-rw-r--r--patches/server/0657-Missing-Entity-Behavior-API.patch356
-rw-r--r--patches/server/0828-More-Projectile-API.patch133
6 files changed, 1124 insertions, 15 deletions
diff --git a/build-data/paper.at b/build-data/paper.at
index b5098bd7a7..c7312d8e58 100644
--- a/build-data/paper.at
+++ b/build-data/paper.at
@@ -223,9 +223,24 @@ public net.minecraft.world.entity.animal.Panda getEatCounter()I
public net.minecraft.world.entity.animal.Panda setEatCounter(I)V
public net.minecraft.world.entity.animal.Bee isRolling()Z
public net.minecraft.world.entity.animal.Bee setRolling(Z)V
+public net.minecraft.world.entity.animal.Bee numCropsGrownSincePollination
+public net.minecraft.world.entity.animal.Bee ticksWithoutNectarSinceExitingHive
public net.minecraft.world.entity.monster.piglin.Piglin isChargingCrossbow()Z
public net.minecraft.world.entity.monster.Vex hasLimitedLife
public net.minecraft.world.entity.monster.Vex limitedLifeTicks
+public net.minecraft.world.entity.npc.WanderingTrader wanderTarget
+public net.minecraft.world.entity.animal.MushroomCow effect
+public net.minecraft.world.entity.animal.MushroomCow effectDuration
+public net.minecraft.world.entity.ambient.Bat targetPosition
+public net.minecraft.world.entity.monster.Ravager attackTick
+public net.minecraft.world.entity.monster.Ravager stunnedTick
+public net.minecraft.world.entity.monster.Ravager roarTick
+public net.minecraft.world.entity.vehicle.MinecartTNT fuse
+public net.minecraft.world.entity.monster.Endermite life
+public net.minecraft.world.entity.vehicle.MinecartHopper cooldownTime
+public net.minecraft.world.entity.projectile.AbstractArrow soundEvent
+public net.minecraft.world.entity.monster.Phantom anchorPoint
+
# Cook speed multipler API
public net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity recipeType
@@ -332,6 +347,15 @@ public net.minecraft.world.entity.projectile.FireworkRocketEntity life
# More Projectile API
public net.minecraft.world.entity.projectile.FishingHook timeUntilLured
+public net.minecraft.world.entity.projectile.ShulkerBullet targetDeltaX
+public net.minecraft.world.entity.projectile.ShulkerBullet targetDeltaY
+public net.minecraft.world.entity.projectile.ShulkerBullet targetDeltaZ
+public net.minecraft.world.entity.projectile.ShulkerBullet currentMoveDirection
+public net.minecraft.world.entity.projectile.ShulkerBullet flightSteps
+public net.minecraft.world.entity.projectile.AbstractArrow soundEvent
+public net.minecraft.world.entity.projectile.ThrownTrident dealtDamage
+public net.minecraft.world.entity.projectile.Projectile hasBeenShot
+public net.minecraft.world.entity.projectile.Projectile leftOwner
# Teleport API
public net.minecraft.server.network.ServerGamePacketListenerImpl internalTeleport(DDDFFLjava/util/Set;Z)V
diff --git a/patches/api/0311-Missing-Entity-Behavior-API.patch b/patches/api/0311-Missing-Entity-Behavior-API.patch
index 78378f8e51..77c9e6677d 100644
--- a/patches/api/0311-Missing-Entity-Behavior-API.patch
+++ b/patches/api/0311-Missing-Entity-Behavior-API.patch
@@ -5,12 +5,30 @@ Subject: [PATCH] Missing Entity Behavior API
Co-authored-by: Nassim Jahnke <[email protected]>
Co-authored-by: Jake Potrebic <[email protected]>
+Co-authored-by: William Blake Galbreath <[email protected]>
diff --git a/src/main/java/org/bukkit/entity/AbstractHorse.java b/src/main/java/org/bukkit/entity/AbstractHorse.java
-index 0d88dce9978243a1f995c5fb448c5d71b01136eb..cad47139de57642fb3bb483e7a5acaa7fea78cb4 100644
+index 0d88dce9978243a1f995c5fb448c5d71b01136eb..1c117ca4aebc2ff9e2f5458346fa0c090a0d7280 100644
--- a/src/main/java/org/bukkit/entity/AbstractHorse.java
+++ b/src/main/java/org/bukkit/entity/AbstractHorse.java
-@@ -119,4 +119,58 @@ public interface AbstractHorse extends Vehicle, InventoryHolder, Tameable {
+@@ -106,17 +106,72 @@ public interface AbstractHorse extends Vehicle, InventoryHolder, Tameable {
+ * Gets whether the horse is currently grazing hay.
+ *
+ * @return true if eating hay
++ * @deprecated use {@link #isEatingGrass()}, this name is incorrect
+ */
++ @Deprecated // Paper - Horse API
+ boolean isEatingHaystack();
+
+ /**
+ * Sets whether the horse is grazing hay.
+ *
+ * @param eatingHaystack new hay grazing status
++ * @deprecated use {@link #setEatingGrass(boolean)}, this name is incorrect
+ */
++ @Deprecated // Paper - Horse API
+ void setEatingHaystack(boolean eatingHaystack);
+
@NotNull
@Override
public AbstractHorseInventory getInventory();
@@ -20,9 +38,7 @@ index 0d88dce9978243a1f995c5fb448c5d71b01136eb..cad47139de57642fb3bb483e7a5acaa7
+ * Gets if a horse is in their eating grass animation.
+ *
+ * @return eating grass animation is active
-+ * @deprecated use {@link #isEatingHaystack()}
+ */
-+ @Deprecated
+ public boolean isEatingGrass();
+
+ /**
@@ -33,7 +49,6 @@ index 0d88dce9978243a1f995c5fb448c5d71b01136eb..cad47139de57642fb3bb483e7a5acaa7
+ * @param eating eating grass animation is active
+ * @deprecated use {@link #setEatingHaystack(boolean)}
+ */
-+ @Deprecated
+ public void setEatingGrass(boolean eating);
+
+ /**
@@ -69,11 +84,39 @@ index 0d88dce9978243a1f995c5fb448c5d71b01136eb..cad47139de57642fb3bb483e7a5acaa7
+ public void setEating(boolean eating);
+ // Paper end - Horse API
}
+diff --git a/src/main/java/org/bukkit/entity/Bat.java b/src/main/java/org/bukkit/entity/Bat.java
+index bd73f22ef7e79e1ade69e860e7ae1d3dcd6fc858..b9f8b14d90a758672642222675d2f5664d4f67b4 100644
+--- a/src/main/java/org/bukkit/entity/Bat.java
++++ b/src/main/java/org/bukkit/entity/Bat.java
+@@ -24,4 +24,23 @@ public interface Bat extends Ambient {
+ * @param state the new state
+ */
+ void setAwake(boolean state);
++
++ // Paper start
++ /**
++ * Gets the location that this bat is currently trying to move towards.
++ *
++ * @return target location, or null if it's going to find a new location
++ */
++ @org.jetbrains.annotations.Nullable
++ org.bukkit.Location getTargetLocation();
++
++ /**
++ * Sets the location that this bat is currently trying to move towards.
++ * <p>
++ * This can be set to null to cause the bat to recalculate its target location
++ *
++ * @param location location to move towards (world is ignored, will always use the entity's world)
++ */
++ void setTargetLocation(@org.jetbrains.annotations.Nullable org.bukkit.Location location);
++ // Paper end
+ }
diff --git a/src/main/java/org/bukkit/entity/Bee.java b/src/main/java/org/bukkit/entity/Bee.java
-index adb20a9abba33c32d553f620fa82b27dff64ab5f..ca6baec5ce00b4d169ab4ff416f616db32615010 100644
+index adb20a9abba33c32d553f620fa82b27dff64ab5f..1f6702b0de00b87dbed7f6d93e911655e8667b0b 100644
--- a/src/main/java/org/bukkit/entity/Bee.java
+++ b/src/main/java/org/bukkit/entity/Bee.java
-@@ -93,4 +93,28 @@ public interface Bee extends Animals {
+@@ -93,4 +93,56 @@ public interface Bee extends Animals {
* @param ticks Ticks the bee cannot enter a hive for
*/
void setCannotEnterHiveTicks(int ticks);
@@ -100,6 +143,34 @@ index adb20a9abba33c32d553f620fa82b27dff64ab5f..ca6baec5ce00b4d169ab4ff416f616db
+ * @return is rolling
+ */
+ boolean isRolling();
++
++ /**
++ * Sets how many crops this bee has grown since it last
++ * pollinated.
++ * @param crops number of crops
++ */
++ void setCropsGrownSincePollination(int crops);
++
++ /**
++ * Gets how many crops this bee has grown since it last
++ * pollinated.
++ * @return number of crops
++ */
++ int getCropsGrownSincePollination();
++
++ /**
++ * Sets how many ticks this bee has gone without pollinating.
++ *
++ * @param ticks number of ticks
++ */
++ void setTicksSincePollination(int ticks);
++
++ /**
++ * Gets how many ticks this bee has gone without pollinating
++ *
++ * @return number of ticks
++ */
++ int getTicksSincePollination();
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/entity/Cat.java b/src/main/java/org/bukkit/entity/Cat.java
@@ -143,6 +214,47 @@ index c2a566b864c82ffb094b7334d9e6e25a1bfc87d1..c340fecb61bac66baf0f44189d21bc85
+ public boolean isHeadUp();
+ // Paper End - More cat api
}
+diff --git a/src/main/java/org/bukkit/entity/Chicken.java b/src/main/java/org/bukkit/entity/Chicken.java
+index cb3ec6ef6c38c2071cb6ad91da094fca2de8d5c6..b4c1a262602d4ca5ffc9fcc21d6aa79af8c040a7 100644
+--- a/src/main/java/org/bukkit/entity/Chicken.java
++++ b/src/main/java/org/bukkit/entity/Chicken.java
+@@ -3,4 +3,35 @@ package org.bukkit.entity;
+ /**
+ * Represents a Chicken.
+ */
+-public interface Chicken extends Animals {}
++// Paper start
++public interface Chicken extends Animals {
++
++ /**
++ * Gets if this chicken was spawned as a chicken jockey.
++ *
++ * @return is chicken jockey
++ */
++ boolean isChickenJockey();
++
++ /**
++ * Sets if this chicken was spawned as a chicken jockey.
++ *
++ * @param isChickenJockey is chicken jockey
++ */
++ void setIsChickenJockey(boolean isChickenJockey);
++
++ /**
++ * Gets the number of ticks till this chicken lays an egg.
++ *
++ * @return ticks till the chicken lays an egg
++ */
++ int getEggLayTime();
++
++ /**
++ * Sets the number of ticks till this chicken lays an egg.
++ *
++ * @param eggLayTime ticks till the chicken lays an egg
++ */
++ void setEggLayTime(int eggLayTime);
++}
++// Paper end
diff --git a/src/main/java/org/bukkit/entity/Enderman.java b/src/main/java/org/bukkit/entity/Enderman.java
index 94f3a8c4bf8cf14263d34d866db66728e98dfdb0..7937a0e082199554d3e8db1f9811be29abc9b3fd 100644
--- a/src/main/java/org/bukkit/entity/Enderman.java
@@ -184,6 +296,33 @@ index 94f3a8c4bf8cf14263d34d866db66728e98dfdb0..7937a0e082199554d3e8db1f9811be29
+ void setHasBeenStaredAt(boolean hasBeenStaredAt);
+ // Paper end
}
+diff --git a/src/main/java/org/bukkit/entity/Endermite.java b/src/main/java/org/bukkit/entity/Endermite.java
+index 9e7f42caab1204036f4203354c115fd40c6def92..138d2530de2410f4a9424dabd3e5ce0cd1c1dcd2 100644
+--- a/src/main/java/org/bukkit/entity/Endermite.java
++++ b/src/main/java/org/bukkit/entity/Endermite.java
+@@ -23,4 +23,22 @@ public interface Endermite extends Monster {
+ */
+ @Deprecated
+ void setPlayerSpawned(boolean playerSpawned);
++ // Paper start
++ /**
++ * Sets how many ticks this endermite has been living for.
++ * If this value is greater than 2400, this endermite will despawn.
++ *
++ * @param ticks lifetime ticks
++ */
++ void setLifetimeTicks(int ticks);
++
++ /**
++ * Gets how long this endermite has been living for.
++ * This value will tick up while {@link LivingEntity#getRemoveWhenFarAway()} is false.
++ * If this value is greater than 2400, this endermite will despawn.
++ *
++ * @return lifetime ticks
++ */
++ int getLifetimeTicks();
++ // Paper end
+ }
diff --git a/src/main/java/org/bukkit/entity/Fox.java b/src/main/java/org/bukkit/entity/Fox.java
index c61a473453f33f9d10c330fc46cfa9d52251fe49..473a7e36ad64f866d1d2e09e2ecb2e9881668faf 100644
--- a/src/main/java/org/bukkit/entity/Fox.java
@@ -270,6 +409,112 @@ index d8eb2b5007091c25a14321cb389f3219d76ce452..0fc8a4fcc3ec2ce60bb095c31eb35333
+ void setExplosionPower(int explosionPower);
+ // Paper end
}
+diff --git a/src/main/java/org/bukkit/entity/Llama.java b/src/main/java/org/bukkit/entity/Llama.java
+index d23226ccb0f6c25028f000ce31346cd0a8898e6a..bc84b892cae5fe7019a3ad481e9da79956efa1fe 100644
+--- a/src/main/java/org/bukkit/entity/Llama.java
++++ b/src/main/java/org/bukkit/entity/Llama.java
+@@ -67,4 +67,56 @@ public interface Llama extends ChestedHorse, RangedEntity { // Paper
+ @NotNull
+ @Override
+ LlamaInventory getInventory();
++
++ // Paper start
++ /**
++ * Checks if this llama is in a caravan.
++ * This means that this llama is currently following
++ * another llama.
++ *
++ * @return is in caravan
++ */
++ boolean inCaravan();
++
++ /**
++ * Joins a caravan, with the provided llama being the leader
++ * of the caravan.
++ * This llama will then follow the provided llama.
++ *
++ * @param llama head of caravan to join
++ */
++ void joinCaravan(@NotNull Llama llama);
++
++ /**
++ * Leaves the current caravan that they are in.
++ */
++ void leaveCaravan();
++
++ /**
++ * Get the llama that this llama is following.
++ * <p>
++ * Does not necessarily mean the leader of the entire caravan.
++ *
++ * @return the llama currently being followed
++ */
++ @org.jetbrains.annotations.Nullable
++ Llama getCaravanHead();
++
++ /**
++ * Checks if another llama is currently following behind
++ * this llama.
++ *
++ * @return true if being followed in the caravan
++ */
++ boolean hasCaravanTail();
++
++ /**
++ * Gets the llama that is currently following behind
++ * this llama.
++ *
++ * @return the llama following this llama, or null if none is following them
++ */
++ @org.jetbrains.annotations.Nullable
++ Llama getCaravanTail();
++ // Paper end
+ }
+diff --git a/src/main/java/org/bukkit/entity/MushroomCow.java b/src/main/java/org/bukkit/entity/MushroomCow.java
+index 939a3dbfcf38f38e4e39d28973ef723157ce0a50..738d547d2a6966122cb2f9f6e94263ee526d9fab 100644
+--- a/src/main/java/org/bukkit/entity/MushroomCow.java
++++ b/src/main/java/org/bukkit/entity/MushroomCow.java
+@@ -35,4 +35,40 @@ public interface MushroomCow extends Cow {
+ */
+ BROWN;
+ }
++ // Paper start
++
++ /**
++ * Gets how long the effect applied to stew
++ * from this mushroom cow is.
++ *
++ * @return duration of the effect (in ticks)
++ */
++ int getStewEffectDuration();
++
++ /**
++ * Sets how long the effect applied to stew
++ * from this mushroom cow is.
++ *
++ * @param duration duration of the effect (in ticks)
++ */
++ void setStewEffectDuration(int duration);
++
++ /**
++ * Gets the type of effect applied to stew
++ * from this mushroom cow is.
++ *
++ * @return effect type, or null if an effect is currently not set
++ */
++ @org.jetbrains.annotations.Nullable
++ org.bukkit.potion.PotionEffectType getStewEffectType();
++
++ /**
++ * Sets the type of effect applied to stew
++ * from this mushroom cow is.
++ *
++ * @param type new effect type
++ * or null if this cow does not give effects
++ */
++ void setStewEffect(@org.jetbrains.annotations.Nullable org.bukkit.potion.PotionEffectType type);
++ // Paper end
+ }
diff --git a/src/main/java/org/bukkit/entity/Panda.java b/src/main/java/org/bukkit/entity/Panda.java
index 1f027927a1194f4f8e86c1375a2772e6e261c151..57cf24cfd15a541f60aafc8507c189344aead0f7 100644
--- a/src/main/java/org/bukkit/entity/Panda.java
@@ -362,6 +607,32 @@ index 1f027927a1194f4f8e86c1375a2772e6e261c151..57cf24cfd15a541f60aafc8507c18934
public enum Gene {
NORMAL(false),
+diff --git a/src/main/java/org/bukkit/entity/Phantom.java b/src/main/java/org/bukkit/entity/Phantom.java
+index a40b045f08b85e22e75459b547e7e7c0b95103ed..277bebe057439a0c48b0c6e9c003b27565eb4bd2 100644
+--- a/src/main/java/org/bukkit/entity/Phantom.java
++++ b/src/main/java/org/bukkit/entity/Phantom.java
+@@ -40,5 +40,21 @@ public interface Phantom extends Flying {
+ * @param shouldBurnInDay True to burn in sunlight
+ */
+ public void setShouldBurnInDay(boolean shouldBurnInDay);
++
++ /**
++ * Gets the location that this phantom circles around when not attacking a player
++ * This will be changed after attacking a player.
++ *
++ * @return circling location
++ */
++ @org.jetbrains.annotations.NotNull
++ org.bukkit.Location getAnchorLocation();
++
++ /**
++ * Sets the location that this phantom circles around when not attacking a player
++ *
++ * @param location circling location (world is ignored, will always use the entity's world)
++ */
++ void setAnchorLocation(@org.jetbrains.annotations.NotNull org.bukkit.Location location);
+ // Paper end
+ }
diff --git a/src/main/java/org/bukkit/entity/Piglin.java b/src/main/java/org/bukkit/entity/Piglin.java
index 6fdc0e0bb62189dbf3cf9ce7a87b7fbb995956a3..d4cb4b0ed1d9766a87867dcf1a3a839526ba9332 100644
--- a/src/main/java/org/bukkit/entity/Piglin.java
@@ -393,10 +664,10 @@ index 6fdc0e0bb62189dbf3cf9ce7a87b7fbb995956a3..d4cb4b0ed1d9766a87867dcf1a3a8395
+
}
diff --git a/src/main/java/org/bukkit/entity/PolarBear.java b/src/main/java/org/bukkit/entity/PolarBear.java
-index 479f7a7c54c85cb685f56e60906650d1989c03ff..60267ee382de80fab86b440ff72a2455f427d148 100644
+index 479f7a7c54c85cb685f56e60906650d1989c03ff..4e526ba6aa462a484984fb9f0512b8db113086fe 100644
--- a/src/main/java/org/bukkit/entity/PolarBear.java
+++ b/src/main/java/org/bukkit/entity/PolarBear.java
-@@ -3,4 +3,21 @@ package org.bukkit.entity;
+@@ -3,4 +3,22 @@ package org.bukkit.entity;
/**
* Represents a polar bear.
*/
@@ -417,6 +688,7 @@ index 479f7a7c54c85cb685f56e60906650d1989c03ff..60267ee382de80fab86b440ff72a2455
+ * @param standing whether the polar bear should be standing
+ */
+ void setStanding(boolean standing);
++
+}
+// Paper end
diff --git a/src/main/java/org/bukkit/entity/Raider.java b/src/main/java/org/bukkit/entity/Raider.java
@@ -444,6 +716,73 @@ index 987f9b0866b213450b4de1310600161c8587a545..144fdcfd1f35b6346b672006905aedb8
+ void setCelebrating(boolean celebrating);
+ // Paper end
}
+diff --git a/src/main/java/org/bukkit/entity/Ravager.java b/src/main/java/org/bukkit/entity/Ravager.java
+index 4374d5206d4d15a4d8d228c137ed9a96821a1f02..0eb7214472f3a43641a3526000af6beeefb7b36f 100644
+--- a/src/main/java/org/bukkit/entity/Ravager.java
++++ b/src/main/java/org/bukkit/entity/Ravager.java
+@@ -3,4 +3,61 @@ package org.bukkit.entity;
+ /**
+ * Illager beast.
+ */
+-public interface Ravager extends Raider { }
++// Paper start - Missing Entity Behavior
++public interface Ravager extends Raider {
++
++ /**
++ * Gets how many ticks this ravager is attacking for.
++ * When attacking, the ravager cannot move.
++ *
++ * @return ticks attacking or -1 if they are currently not attacking
++ */
++ int getAttackTicks();
++
++ /**
++ * Sets how many ticks this ravager is attacking for.
++ * When attacking, the ravager cannot move.
++ * This will tick down till it gets to -1, where this ravager will no longer be attacking.
++ *
++ * @param ticks ticks attacking or -1 if they should no longer be attacking
++ */
++ void setAttackTicks(int ticks);
++
++ /**
++ * Gets how many ticks the ravager is stunned for.
++ * The ravager cannot move or attack while stunned.
++ * At 0, this will cause the ravager to roar.
++ *
++ * @return ticks stunned or -1 if they are currently not stunned
++ */
++ int getStunnedTicks();
++
++ /**
++ * Sets how many ticks the ravager is stunned for.
++ * The ravager cannot move or attack while stunned.
++ * At 0, this will cause the ravager to roar.
++ *
++ * @param ticks ticks stunned or -1 if they should no longer be stunned
++ */
++ void setStunnedTicks(int ticks);
++
++ /**
++ * Gets how many ticks the ravager is roaring for.
++ * While roaring, the ravager cannot move
++ *
++ * @return ticks roaring or -1 if they are currently not roaring
++ */
++ int getRoarTicks();
++
++ /**
++ * Sets how many ticks the ravager is roaring for.
++ * While roaring, the ravager cannot move
++ * This will tick down till it gets to -1, where it is no longer active.
++ * If set to 11, this will play a sound and hurt nearby players.
++ *
++ * @param ticks ticks roaring or -1 if they should no longer be roaring
++ */
++ void setRoarTicks(int ticks);
++
++}
++// Paper end
diff --git a/src/main/java/org/bukkit/entity/Trident.java b/src/main/java/org/bukkit/entity/Trident.java
index 28cdb3b544572ba7aeb9061e3163e3895ac7d4e6..c8015ff610e3c1222cb368ea1d8a0c2f3785d9c7 100644
--- a/src/main/java/org/bukkit/entity/Trident.java
@@ -563,6 +902,37 @@ index 627e3c1a96ae3331f5aa2dd7803dd2a31c7204be..3c447d2300c866ae605eeca97bd869f4
+ void setLimitedLifetimeTicks(int ticks);
// Paper end
}
+diff --git a/src/main/java/org/bukkit/entity/WanderingTrader.java b/src/main/java/org/bukkit/entity/WanderingTrader.java
+index da76e1ed5406322073dd8c7a89ca55aa68620ac4..9f25774659b29d8fcca3eb9d9487edff42dbad13 100644
+--- a/src/main/java/org/bukkit/entity/WanderingTrader.java
++++ b/src/main/java/org/bukkit/entity/WanderingTrader.java
+@@ -53,5 +53,26 @@ public interface WanderingTrader extends AbstractVillager {
+ * @return whether the mob will drink
+ */
+ public boolean canDrinkMilk();
++
++ /**
++ * Gets the location that this wandering trader is currently
++ * wandering towards.
++ * <p>
++ * This will return null if the wandering trader has finished
++ * wandering towards the given location.
++ *
++ * @return the location currently wandering towards, or null if not wandering
++ */
++ @org.jetbrains.annotations.Nullable
++ org.bukkit.Location getWanderingTowards();
++
++ /**
++ * Sets the location that this wandering trader is currently wandering towards.
++ * <p>
++ * This can be set to null to prevent the wandering trader from wandering further.
++ *
++ * @param location location to wander towards (world is ignored, will always use the entity's world)
++ */
++ void setWanderingTowards(@org.jetbrains.annotations.Nullable org.bukkit.Location location);
+ // Paper end
+ }
diff --git a/src/main/java/org/bukkit/entity/Warden.java b/src/main/java/org/bukkit/entity/Warden.java
index 3794db8867b53f3b3735ad82fdd8765a26df2bfb..efaa45f41bc1dc8df6665c55b4e5ade343d60d4c 100644
--- a/src/main/java/org/bukkit/entity/Warden.java
@@ -653,3 +1023,51 @@ index 7cc1d9a966454af70b7c25735fe474fe3eb97eb4..ad2eaee347cd2864aef30d2af48c1be6
+ void setConversionTime(int time, boolean broadcastEntityEvent);
+ // Paper stop - missing entity behaviour api - converting without entity event
}
+diff --git a/src/main/java/org/bukkit/entity/minecart/ExplosiveMinecart.java b/src/main/java/org/bukkit/entity/minecart/ExplosiveMinecart.java
+index a4411daca0d8a770b0d15e08847b82df8a3ec27f..50464aa8c38cd47fc049ee022e25cb4976260fa0 100644
+--- a/src/main/java/org/bukkit/entity/minecart/ExplosiveMinecart.java
++++ b/src/main/java/org/bukkit/entity/minecart/ExplosiveMinecart.java
+@@ -6,4 +6,19 @@ import org.bukkit.entity.Minecart;
+ * Represents a Minecart with TNT inside it that can explode when triggered.
+ */
+ public interface ExplosiveMinecart extends Minecart {
++ // Paper start - Entity API
++ /**
++ * Set the number of ticks until the minecart explodes after being primed.
++ *
++ * @param fuseTicks fuse ticks or -1 if the fuse isn't primed
++ */
++ void setFuseTicks(int fuseTicks);
++
++ /**
++ * Retrieve the number of ticks until the explosive minecart explodes
++ *
++ * @return number of ticks or -1 if the fuse isn't primed
++ */
++ int getFuseTicks();
++ // Paper end
+ }
+diff --git a/src/main/java/org/bukkit/entity/minecart/HopperMinecart.java b/src/main/java/org/bukkit/entity/minecart/HopperMinecart.java
+index db69687a7ad4b18d17ab1677cae5d8dd4dcd3678..8e4c6ec409f49d4a3378c466acc47f62c7689c0b 100644
+--- a/src/main/java/org/bukkit/entity/minecart/HopperMinecart.java
++++ b/src/main/java/org/bukkit/entity/minecart/HopperMinecart.java
+@@ -24,4 +24,19 @@ public interface HopperMinecart extends Minecart, InventoryHolder, LootableEntit
+ * @param enabled new enabled state
+ */
+ void setEnabled(boolean enabled);
++ // Paper start
++ /**
++ * Gets the number of ticks that this hopper minecart cannot pickup items up for.
++ *
++ * @return ticks left on cooldown
++ */
++ int getPickupCooldown();
++
++ /**
++ * Sets the number of ticks that this hopper minecart cannot pickup items for.
++ *
++ * @param cooldown cooldown length in ticks
++ */
++ void setPickupCooldown(int cooldown);
++ // Paper end
+ }
diff --git a/patches/api/0370-More-Projectile-API.patch b/patches/api/0370-More-Projectile-API.patch
index 80f2397953..0841766648 100644
--- a/patches/api/0370-More-Projectile-API.patch
+++ b/patches/api/0370-More-Projectile-API.patch
@@ -5,6 +5,47 @@ Subject: [PATCH] More Projectile API
Co-authored-by: Nassim Jahnke <[email protected]>
+diff --git a/src/main/java/org/bukkit/entity/AbstractArrow.java b/src/main/java/org/bukkit/entity/AbstractArrow.java
+index 225a24898acd25038ea2a8448f9f3b57643d3026..d173010d51d05928c35bb4bf5fbc08ce221ec474 100644
+--- a/src/main/java/org/bukkit/entity/AbstractArrow.java
++++ b/src/main/java/org/bukkit/entity/AbstractArrow.java
+@@ -151,6 +151,36 @@ public interface AbstractArrow extends Projectile {
+ @NotNull
+ org.bukkit.inventory.ItemStack getItemStack();
+
++ /**
++ * Sets the amount of ticks this arrow has been alive in the world
++ * This is used to determine when the arrow should be automatically despawned.
++ *
++ * @param ticks lifetime ticks
++ */
++ void setLifetimeTicks(int ticks);
++
++ /**
++ * Gets how many ticks this arrow has been in the world for.
++ *
++ * @return ticks this arrow has been in the world
++ */
++ int getLifetimeTicks();
++
++ /**
++ * Gets the sound that is played when this arrow hits an entity.
++ *
++ * @return sound that plays
++ */
++ @NotNull
++ org.bukkit.Sound getHitSound();
++
++ /**
++ * Sets the sound that is played when this arrow hits an entity.
++ *
++ * @param sound sound that is played
++ */
++ void setHitSound(@NotNull org.bukkit.Sound sound);
++
+ /**
+ * Sets this arrow to "noclip" status.
+ *
diff --git a/src/main/java/org/bukkit/entity/Firework.java b/src/main/java/org/bukkit/entity/Firework.java
index 0d31aa0b22cf1e849572294e2cfe38b48c9210af..571712e17551f24b369044b8215b722f7183ae7d 100644
--- a/src/main/java/org/bukkit/entity/Firework.java
@@ -136,6 +177,122 @@ index d1b37530319f6d37ee37f62080289c1e45848bc8..e94c7e279356c510f60508b26277d489
+ void setWaitTime(int ticks);
+ // Paper end
}
+diff --git a/src/main/java/org/bukkit/entity/Projectile.java b/src/main/java/org/bukkit/entity/Projectile.java
+index a523fca4baab447181ef91df67fa69b24e010149..6935f8806ca1ed87fa761e73bc0f6c41ab60453e 100644
+--- a/src/main/java/org/bukkit/entity/Projectile.java
++++ b/src/main/java/org/bukkit/entity/Projectile.java
+@@ -43,4 +43,45 @@ public interface Projectile extends Entity {
+ */
+ @Deprecated(forRemoval = true) // Paper
+ public void setBounce(boolean doesBounce);
++ // Paper start
++
++ /**
++ * Gets whether the projectile has left the
++ * hitbox of their shooter and can now hit entities.
++ *
++ * @return has left shooter's hitbox
++ */
++ boolean hasLeftShooter();
++
++ /**
++ * Sets whether the projectile has left the
++ * hitbox of their shooter and can now hit entities.
++ *
++ * This is recalculated each tick if the projectile has a shooter.
++ *
++ * @param leftShooter has left shooter's hitbox
++ */
++ void setHasLeftShooter(boolean leftShooter);
++
++ /**
++ * Gets whether the projectile has been
++ * shot into the world and has sent a projectile
++ * shot game event.
++ *
++ * @return has been shot into the world
++ */
++ boolean hasBeenShot();
++
++ /**
++ * Sets whether the projectile has been
++ * shot into the world and has sent a projectile
++ * shot game event in the next tick.
++ *
++ * Setting this to false will cause a game event
++ * to fire and the value to be set back to true.
++ *
++ * @param beenShot has been in shot into the world
++ */
++ void setHasBeenShot(boolean beenShot);
++ // Paper end
+ }
+diff --git a/src/main/java/org/bukkit/entity/ShulkerBullet.java b/src/main/java/org/bukkit/entity/ShulkerBullet.java
+index 4623e0d767b343cbdc6fcf20b3b2ff7ff14863cf..dd69a68d1f005c25329bb0366d161ae9b061e108 100644
+--- a/src/main/java/org/bukkit/entity/ShulkerBullet.java
++++ b/src/main/java/org/bukkit/entity/ShulkerBullet.java
+@@ -18,4 +18,61 @@ public interface ShulkerBullet extends Projectile {
+ * @param target the entity to target
+ */
+ void setTarget(@Nullable Entity target);
++ // Paper start
++ /**
++ * Gets the relative offset that this shulker bullet should move towards,
++ * note that this will change each tick as the skulker bullet approaches the target.
++ *
++ * @return target delta offset
++ */
++ @org.jetbrains.annotations.NotNull
++ org.bukkit.util.Vector getTargetDelta();
++
++
++ /**
++ * Sets the relative offset that this shulker bullet should move towards,
++ * note that this will change each tick as the skulker bullet approaches the target.
++ * This is usually relative towards their target.
++ *
++ * @param vector target
++ */
++ void setTargetDelta(@org.jetbrains.annotations.NotNull org.bukkit.util.Vector vector);
++
++ /**
++ * Gets the current movement direction.
++ * This is used to determine the next movement direction to ensure
++ * that the bullet does not move in the same direction.
++ *
++ * @return null or their current direction
++ */
++ @Nullable
++ org.bukkit.block.BlockFace getCurrentMovementDirection();
++
++ /**
++ * Set the current movement direction.
++ * This is used to determine the next movement direction to ensure
++ * that the bullet does not move in the same direction.
++ *
++ * Set to null to simply pick a random direction.
++ *
++ * @param movementDirection null or a direction
++ */
++ void setCurrentMovementDirection(@Nullable org.bukkit.block.BlockFace movementDirection);
++
++ /**
++ * Gets how many ticks this shulker bullet
++ * will attempt to move in its current direction.
++ *
++ * @return number of steps
++ */
++ int getFlightSteps();
++
++ /**
++ * Sets how many ticks this shulker bullet
++ * will attempt to move in its current direction.
++ *
++ * @param steps number of steps
++ */
++ void setFlightSteps(int steps);
++ // Paper end
+ }
diff --git a/src/main/java/org/bukkit/entity/ThrownPotion.java b/src/main/java/org/bukkit/entity/ThrownPotion.java
index 7051e07b4e456aae0ec9e37808b59e5fa62a4027..225ac312613b9e8f3cf680819f2ebe350d1bf48a 100644
--- a/src/main/java/org/bukkit/entity/ThrownPotion.java
@@ -179,3 +336,32 @@ index 7051e07b4e456aae0ec9e37808b59e5fa62a4027..225ac312613b9e8f3cf680819f2ebe35
+ void splash();
+ // Paper end
}
+diff --git a/src/main/java/org/bukkit/entity/Trident.java b/src/main/java/org/bukkit/entity/Trident.java
+index c8015ff610e3c1222cb368ea1d8a0c2f3785d9c7..02584eced96944a551140f8150c65a7c0f4bb55e 100644
+--- a/src/main/java/org/bukkit/entity/Trident.java
++++ b/src/main/java/org/bukkit/entity/Trident.java
+@@ -38,5 +38,24 @@ public interface Trident extends AbstractArrow, ThrowableProjectile {
+ * @throws IllegalArgumentException if the loyalty level is lower than 0 or greater than 127
+ */
+ void setLoyaltyLevel(int loyaltyLevel);
++
++ /**
++ * Gets if this trident has dealt damage to an
++ * entity yet or has hit the floor.
++ *
++ * If neither of these events have occurred yet, this will
++ * return false.
++ *
++ * @return has dealt damage
++ */
++ boolean hasDealtDamage();
++
++ /**
++ * Sets if this trident has dealt damage to an entity
++ * yet or has hit the floor.
++ *
++ * @param hasDealtDamage has dealt damage or hit the floor
++ */
++ void setHasDealtDamage(boolean hasDealtDamage);
+ }
+ // Paper end
diff --git a/patches/server/0619-Add-more-WanderingTrader-API.patch b/patches/server/0619-Add-more-WanderingTrader-API.patch
index 65d351d6df..548c498631 100644
--- a/patches/server/0619-Add-more-WanderingTrader-API.patch
+++ b/patches/server/0619-Add-more-WanderingTrader-API.patch
@@ -5,12 +5,12 @@ Subject: [PATCH] Add more WanderingTrader API
diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java
-index abb2c5c4ac481c7529aa29322babb1929235e15a..86e1ba898d6b92735258419fa74352e5116226dc 100644
+index 9162f3e5752a7bee825e7ae21e9fb950cf4eb644..af092098cdfc528bd9f5d771ead1b685aa051bee 100644
--- a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java
+++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java
@@ -56,6 +56,10 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill
@Nullable
- private BlockPos wanderTarget;
+ public BlockPos wanderTarget;
private int despawnDelay;
+ // Paper start - Add more WanderingTrader API
+ public boolean canDrinkPotion = true;
diff --git a/patches/server/0657-Missing-Entity-Behavior-API.patch b/patches/server/0657-Missing-Entity-Behavior-API.patch
index fecc136bbf..fe8e4b40a2 100644
--- a/patches/server/0657-Missing-Entity-Behavior-API.patch
+++ b/patches/server/0657-Missing-Entity-Behavior-API.patch
@@ -5,9 +5,10 @@ Subject: [PATCH] Missing Entity Behavior API
Co-authored-by: Nassim Jahnke <[email protected]>
Co-authored-by: Jake Potrebic <[email protected]>
+Co-authored-by: William Blake Galbreath <[email protected]>
diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java
-index d13f3460644f635ded96bf92ddf9ecf8984c8e47..bd048cc30046f19f9eee89c6ba45d0816a160e67 100644
+index 66293e620dcf2c7ee3e2fc91f8a7cf52f2950de1..f2243f65cdf0e4b327e8597dfefe5b2de8912cef 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Bee.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java
@@ -540,11 +540,13 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
@@ -55,6 +56,19 @@ index 04a119e6641898454253e2478bc1b4dff181b5ee..a8da601b8342aa6e4902b452eb588c76
public void setStanding(boolean angry) {
if (angry) {
this.setEating(false);
+diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java
+index 5ffae9d3be22b5e78645da57a6bd0e7350749ef1..9aec9f80c564fa3ae03e445423d9e50afc45f837 100644
+--- a/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java
++++ b/src/main/java/net/minecraft/world/entity/animal/horse/Llama.java
+@@ -67,7 +67,7 @@ public class Llama extends AbstractChestedHorse implements RangedAttackMob {
+ @Nullable
+ private Llama caravanHead;
+ @Nullable
+- private Llama caravanTail;
++ public Llama caravanTail; // Paper
+
+ public Llama(EntityType<? extends Llama> type, Level world) {
+ super(type, world);
diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
index 1fc862a3b5d40a45cf91703051bcfb06ec1b177a..02d7cd9cd27ff9254c3e99e3e94309a8cb8b243d 100644
--- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
@@ -145,7 +159,7 @@ index e93a2634cd80cd4f1caf6bd60e569783bc6b577c..fb0a77b4cf1ba47c73c00993bd9b7454
@Override
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java
-index a367f50b0e3fe9e7a1b87892a8c98e88bd678f6f..1b31b32d42eeb54680b902cd7e82d10ba7daa5d0 100644
+index c5b82dcf6c9da9d6699f699c3e13d9b949128cc8..d890446315787b7aaa2869637e905c25c93558aa 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownTrident.java
@@ -105,6 +105,20 @@ public class ThrownTrident extends AbstractArrow {
@@ -210,11 +224,41 @@ index 254d4f2e45d7c8f572a4368eccd84560d4d0d836..299ab868252c8f326e3a56e878c9ee23
+ }
+ // Paper end - Horse API
}
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java
+index 3b960a832df1fe496ea036962083f1ac507a7db7..ee5534972a2b26402f29b146d1f3da69052672b0 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java
+@@ -33,4 +33,25 @@ public class CraftBat extends CraftAmbient implements Bat {
+ public void setAwake(boolean state) {
+ this.getHandle().setResting(!state);
+ }
++ // Paper start
++ @Override
++ public org.bukkit.Location getTargetLocation() {
++ net.minecraft.core.BlockPos pos = this.getHandle().targetPosition;
++ if (pos == null) {
++ return null;
++ }
++
++ return net.minecraft.server.MCUtil.toLocation(this.getHandle().getLevel(), pos);
++ }
++
++ @Override
++ public void setTargetLocation(org.bukkit.Location location) {
++ net.minecraft.core.BlockPos pos = null;
++ if (location != null) {
++ pos = net.minecraft.server.MCUtil.toBlockPosition(location);
++ }
++
++ this.getHandle().targetPosition = pos;
++ }
++ // Paper end
+ }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftBee.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftBee.java
-index 8ada3dfbe89c8b55d85c31c71e365af0cbf66d19..b5d3a00a48d3b7618f974bb0f6909aa7c304b012 100644
+index 8ada3dfbe89c8b55d85c31c71e365af0cbf66d19..1ae8d6e819cd9d195e1bd31ccf55d2893ba00e2a 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftBee.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftBee.java
-@@ -91,4 +91,22 @@ public class CraftBee extends CraftAnimals implements Bee {
+@@ -91,4 +91,42 @@ public class CraftBee extends CraftAnimals implements Bee {
public void setCannotEnterHiveTicks(int ticks) {
this.getHandle().setStayOutOfHiveCountdown(ticks);
}
@@ -235,6 +279,26 @@ index 8ada3dfbe89c8b55d85c31c71e365af0cbf66d19..b5d3a00a48d3b7618f974bb0f6909aa7
+ public net.kyori.adventure.util.TriState getRollingOverride() {
+ return this.getHandle().rollingOverride;
+ }
++
++ @Override
++ public void setCropsGrownSincePollination(int crops) {
++ this.getHandle().numCropsGrownSincePollination = crops;
++ }
++
++ @Override
++ public int getCropsGrownSincePollination() {
++ return this.getHandle().numCropsGrownSincePollination;
++ }
++
++ @Override
++ public void setTicksSincePollination(int ticks) {
++ this.getHandle().ticksWithoutNectarSinceExitingHive = ticks;
++ }
++
++ @Override
++ public int getTicksSincePollination() {
++ return this.getHandle().ticksWithoutNectarSinceExitingHive;
++ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java
@@ -267,6 +331,36 @@ index 37352ca3ff267d02a26ed182ce3df3ef775fa9bc..6a504f61c55d3983871f8d1c5c002c7a
+ }
+ // Paper End - More cat api
}
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftChicken.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftChicken.java
+index 178328042ad62f32ca2ae14a6bcf2b694418eb8c..fd87f979ee207dac13e4028d76bdd40911509e56 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftChicken.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftChicken.java
+@@ -24,4 +24,25 @@ public class CraftChicken extends CraftAnimals implements Chicken {
+ public EntityType getType() {
+ return EntityType.CHICKEN;
+ }
++ // Paper start
++ @Override
++ public boolean isChickenJockey() {
++ return this.getHandle().isChickenJockey();
++ }
++
++ @Override
++ public void setIsChickenJockey(boolean isChickenJockey) {
++ this.getHandle().setChickenJockey(isChickenJockey);
++ }
++
++ @Override
++ public int getEggLayTime() {
++ return this.getHandle().eggTime;
++ }
++
++ @Override
++ public void setEggLayTime(int eggLayTime) {
++ this.getHandle().eggTime = eggLayTime;
++ }
++ // Paper end
+ }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java
index ae669a970aa1f17ed786640de8a481364543c58e..acdc4e578d70f8121c8c6be7682ba1ecef7687cf 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java
@@ -300,6 +394,26 @@ index ae669a970aa1f17ed786640de8a481364543c58e..acdc4e578d70f8121c8c6be7682ba1ec
@Override
public EnderMan getHandle() {
return (EnderMan) entity;
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java
+index 04976616da8c85b1278dad33ff05554aa74a6b33..75c7645fb5732c43d1da15181cf5c7ee4c3ecd6c 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEndermite.java
+@@ -34,4 +34,15 @@ public class CraftEndermite extends CraftMonster implements Endermite {
+ public void setPlayerSpawned(boolean playerSpawned) {
+ // Nop
+ }
++ // Paper start
++ @Override
++ public void setLifetimeTicks(int ticks) {
++ this.getHandle().life = ticks;
++ }
++
++ @Override
++ public int getLifetimeTicks() {
++ return this.getHandle().life;
++ }
++ // Paper end
+ }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java
index f6369a1b0ea3fc64e9e7902d9da25924a0745855..fce96b67300b8808984904ee19d4e987f5235bfd 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java
@@ -368,6 +482,140 @@ index 7adda5c93e7c172ea0ba4a3f15828b5e54a283e7..fffaf4108b632ceabac4186d93b34ad0
+ }
+ // Paper end
}
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
+index ae05f526f9ec70a2992ef3ee66b7f57eca2351fc..15e2c2653d7d41e8bafa0ffe1afaa733c569b2ab 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
+@@ -64,4 +64,36 @@ public class CraftLlama extends CraftChestedHorse implements Llama, com.destroys
+ public EntityType getType() {
+ return EntityType.LLAMA;
+ }
++
++ // Paper start
++ @Override
++ public boolean inCaravan() {
++ return this.getHandle().inCaravan();
++ }
++
++ @Override
++ public void joinCaravan(@org.jetbrains.annotations.NotNull Llama llama) {
++ this.getHandle().joinCaravan(((CraftLlama) llama).getHandle());
++ }
++
++ @Override
++ public void leaveCaravan() {
++ this.getHandle().leaveCaravan();
++ }
++
++ @Override
++ public boolean hasCaravanTail() {
++ return this.getHandle().hasCaravanTail();
++ }
++
++ @Override
++ public Llama getCaravanHead() {
++ return this.getHandle().getCaravanHead() == null ? null : (Llama) this.getHandle().getCaravanHead().getBukkitEntity();
++ }
++
++ @Override
++ public Llama getCaravanTail() {
++ return this.getHandle().caravanTail == null ? null : (Llama) this.getHandle().caravanTail.getBukkitEntity();
++ }
++ // Paper end
+ }
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java
+index ee9648739fb39c5842063d7442df6eb5c9336d7f..569763b3c9e92a4071884f139fb1263201f80e43 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java
+@@ -39,4 +39,20 @@ public final class CraftMinecartHopper extends CraftMinecartContainer implements
+ public void setEnabled(boolean enabled) {
+ ((MinecartHopper) getHandle()).setEnabled(enabled);
+ }
++ // Paper start
++ @Override
++ public net.minecraft.world.entity.vehicle.MinecartHopper getHandle() {
++ return (net.minecraft.world.entity.vehicle.MinecartHopper) super.getHandle();
++ }
++
++ @Override
++ public int getPickupCooldown() {
++ return this.getHandle().cooldownTime;
++ }
++
++ @Override
++ public void setPickupCooldown(int cooldown) {
++ this.getHandle().setCooldown(cooldown);
++ }
++ // Paper end
+ }
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartTNT.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartTNT.java
+index 9569068c0a6e1eb934f063634f5d3efe674aa33d..dfd5e830fd262b72256b361e094f6769b323e9c8 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartTNT.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartTNT.java
+@@ -19,4 +19,20 @@ final class CraftMinecartTNT extends CraftMinecart implements ExplosiveMinecart
+ public EntityType getType() {
+ return EntityType.MINECART_TNT;
+ }
++ // Paper start
++ @Override
++ public net.minecraft.world.entity.vehicle.MinecartTNT getHandle() {
++ return (net.minecraft.world.entity.vehicle.MinecartTNT) entity;
++ }
++
++ @Override
++ public void setFuseTicks(int fuseTicks) {
++ this.getHandle().fuse = fuseTicks;
++ }
++
++ @Override
++ public int getFuseTicks() {
++ return this.getHandle().getFuse();
++ }
++ // Paper end
+ }
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java
+index 7fe1eae79dfac7e02f85bae9c1990467a4b0037b..b68e0dbd709085df795dc72b552ced9ac5de47e7 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java
+@@ -28,6 +28,38 @@ public class CraftMushroomCow extends CraftCow implements MushroomCow {
+ this.getHandle().setMushroomType(net.minecraft.world.entity.animal.MushroomCow.MushroomType.values()[variant.ordinal()]);
+ }
+
++ // Paper start
++ @Override
++ public int getStewEffectDuration() {
++ return this.getHandle().effectDuration;
++ }
++
++ @Override
++ public void setStewEffectDuration(int duration) {
++ this.getHandle().effectDuration = duration;
++ }
++
++ @Override
++ public org.bukkit.potion.PotionEffectType getStewEffectType() {
++ net.minecraft.world.effect.MobEffect effect = this.getHandle().effect;
++ if (effect == null) {
++ return null;
++ }
++
++ return org.bukkit.potion.PotionEffectType.getById(net.minecraft.world.effect.MobEffect.getId(effect));
++ }
++
++ @Override
++ public void setStewEffect(org.bukkit.potion.PotionEffectType type) {
++ net.minecraft.world.effect.MobEffect effect = null;
++ if (type != null) {
++ effect = net.minecraft.world.effect.MobEffect.byId(type.getId());
++ }
++
++ this.getHandle().effect = effect;
++ }
++ // Paper end
++
+ @Override
+ public String toString() {
+ return "CraftMushroomCow";
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPanda.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPanda.java
index ff9f711b83a8ea1bf4135751a9ba865224bce787..1f6dcad764240e15083731d017f9bb1c5c84622f 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPanda.java
@@ -405,6 +653,36 @@ index ff9f711b83a8ea1bf4135751a9ba865224bce787..1f6dcad764240e15083731d017f9bb1c
@Override
public boolean isRolling() {
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
+index dce23f3878b1588c26b6116d80e597d08070edbc..eaa0358051c4ac32cc7e6a45039374dd5c036fa2 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
+@@ -50,5 +50,25 @@ public class CraftPhantom extends CraftFlying implements Phantom {
+ public void setShouldBurnInDay(boolean shouldBurnInDay) {
+ getHandle().setShouldBurnInDay(shouldBurnInDay);
+ }
++
++ @Override
++ public org.bukkit.Location getAnchorLocation() {
++ net.minecraft.core.BlockPos pos = this.getHandle().anchorPoint;
++ if (pos == null) {
++ return null;
++ }
++
++ return net.minecraft.server.MCUtil.toLocation(this.getHandle().getLevel(), pos);
++ }
++
++ @Override
++ public void setAnchorLocation(org.bukkit.Location location) {
++ net.minecraft.core.BlockPos pos = null;
++ if (location != null) {
++ pos = net.minecraft.server.MCUtil.toBlockPosition(location);
++ }
++
++ this.getHandle().anchorPoint = pos;
++ }
+ // Paper end
+ }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
index aeda5fc001fe4ce55ee467240b275b6050a29f98..48d0a4e42e1b90d1323784d1284acabfe9497dd6 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
@@ -467,6 +745,46 @@ index b10bcbc19362f0f8596ebcf3f3e1060486cfc74f..e24eec79402843105a13de2bb8554260
+ }
+ // Paper end
}
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftRavager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftRavager.java
+index 796b784d7a50e3a4aea5c67b7cd16d288ed392b0..84899714b96a7ed31ceee10373a62c37cab2ad2a 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftRavager.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftRavager.java
+@@ -24,4 +24,35 @@ public class CraftRavager extends CraftRaider implements Ravager {
+ public String toString() {
+ return "CraftRavager";
+ }
++ // Paper start - Missing Entity Behavior
++ @Override
++ public int getAttackTicks() {
++ return this.getHandle().getAttackTick();
++ }
++
++ @Override
++ public void setAttackTicks(int ticks) {
++ this.getHandle().attackTick = ticks;
++ }
++
++ @Override
++ public int getStunnedTicks() {
++ return this.getHandle().getStunnedTick();
++ }
++
++ @Override
++ public void setStunnedTicks(int ticks) {
++ this.getHandle().stunnedTick = ticks;
++ }
++
++ @Override
++ public int getRoarTicks() {
++ return this.getHandle().getRoarTick();
++ }
++
++ @Override
++ public void setRoarTicks(int ticks) {
++ this.getHandle().roarTick = ticks;
++ }
++ // Paper end
+ }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java
index bf5b2fd6676c4430578db4cc6c603c501cc5e349..832981b07ef5c633ef00a382f56798ee87eec0df 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java
@@ -556,6 +874,36 @@ index 8a0a905f6701c6e94cbbf15793788350958fb728..2a74e6ecb4f57bc6879b37f7bc067541
}
}
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWanderingTrader.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWanderingTrader.java
+index fa7107593b20e0151d8d67104e4a92dcc697d461..d3618b2fd698552b2331f1114654b3339f3f066f 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWanderingTrader.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWanderingTrader.java
+@@ -55,5 +55,25 @@ public class CraftWanderingTrader extends CraftAbstractVillager implements Wande
+ public boolean canDrinkMilk() {
+ return getHandle().canDrinkMilk;
+ }
++
++ @Override
++ public org.bukkit.Location getWanderingTowards() {
++ net.minecraft.core.BlockPos pos = this.getHandle().wanderTarget;
++ if (pos == null) {
++ return null;
++ }
++
++ return net.minecraft.server.MCUtil.toLocation(this.getHandle().getLevel(), pos);
++ }
++
++ @Override
++ public void setWanderingTowards(org.bukkit.Location location) {
++ net.minecraft.core.BlockPos pos = null;
++ if (location != null) {
++ pos = net.minecraft.server.MCUtil.toBlockPosition(location);
++ }
++
++ this.getHandle().wanderTarget = pos;
++ }
+ // Paper end
+ }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWarden.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWarden.java
index 7ece945d1a4fa29c7b98532788076483037f4bda..963928fc8e29b8abc2026c0b0183ebb07f0de4d1 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWarden.java
diff --git a/patches/server/0828-More-Projectile-API.patch b/patches/server/0828-More-Projectile-API.patch
index d15949da57..cc09814a54 100644
--- a/patches/server/0828-More-Projectile-API.patch
+++ b/patches/server/0828-More-Projectile-API.patch
@@ -30,6 +30,74 @@ index fee09e6ff72cf1da389d5811dd005642cd50a5b4..4f276b2a86735a2c664738450ae0fbdd
}
}
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java
+index 40e5b19bc8fa3de3b3d54da0762aee5bd7bb8d7b..825fdc6162797ade8e76e1ca3a863ed5fb48f936 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java
+@@ -21,5 +21,31 @@ public abstract class AbstractProjectile extends CraftEntity implements Projecti
+ public void setBounce(boolean doesBounce) {
+ this.doesBounce = doesBounce;
+ }
++ // Paper start
++ @Override
++ public boolean hasLeftShooter() {
++ return this.getHandle().leftOwner;
++ }
++
++ @Override
++ public void setHasLeftShooter(boolean leftShooter) {
++ this.getHandle().leftOwner = leftShooter;
++ }
++
++ @Override
++ public boolean hasBeenShot() {
++ return this.getHandle().hasBeenShot;
++ }
++
++ @Override
++ public void setHasBeenShot(boolean beenShot) {
++ this.getHandle().hasBeenShot = beenShot;
++ }
++
++ @Override
++ public net.minecraft.world.entity.projectile.Projectile getHandle() {
++ return (net.minecraft.world.entity.projectile.Projectile) entity;
++ }
++ // Paper end
+
+ }
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
+index 15abd085eeb0a31a925c1a8d6de903c9d4625a29..40ae8e43f40f9bf457d2917ac4f131b21e4f8dd2 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java
+@@ -108,6 +108,27 @@ public class CraftArrow extends AbstractProjectile implements AbstractArrow {
+ return org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(getHandle().getPickupItem());
+ }
+
++ @Override
++ public void setLifetimeTicks(int ticks) {
++ this.getHandle().life = ticks;
++ }
++
++ @Override
++ public int getLifetimeTicks() {
++ return this.getHandle().life;
++ }
++
++ @org.jetbrains.annotations.NotNull
++ @Override
++ public org.bukkit.Sound getHitSound() {
++ return org.bukkit.craftbukkit.CraftSound.getBukkit(this.getHandle().soundEvent);
++ }
++
++ @Override
++ public void setHitSound(@org.jetbrains.annotations.NotNull org.bukkit.Sound sound) {
++ this.getHandle().setSoundEvent(org.bukkit.craftbukkit.CraftSound.getSoundEffect(sound));
++ }
++
+ @Override
+ public void setNoPhysics(boolean noPhysics) {
+ this.getHandle().setNoPhysics(noPhysics);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
index c242f654c88ca1773429348939d3bb2ffae3768c..d1c7ab67cba881d96b7a5e9220130d86d0514304 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
@@ -157,6 +225,51 @@ index 6bfa984781a483d048ef4318761203c701d8a632..5e0c2c5094e1578162d1a50d50701fbd
+ }
+ // Paper end
}
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java
+index 20b54f8896be1f8744a29e1d0205e58d27049f1f..ca8a9b2773d70a8800b2179b164ce33d7e2bdc5e 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftShulkerBullet.java
+@@ -40,6 +40,40 @@ public class CraftShulkerBullet extends AbstractProjectile implements ShulkerBul
+ this.getHandle().setTarget(target == null ? null : ((CraftEntity) target).getHandle());
+ }
+
++ @Override
++ public org.bukkit.util.Vector getTargetDelta() {
++ net.minecraft.world.entity.projectile.ShulkerBullet bullet = this.getHandle();
++ return new org.bukkit.util.Vector(bullet.targetDeltaX, bullet.targetDeltaY, bullet.targetDeltaZ);
++ }
++
++ @Override
++ public void setTargetDelta(org.bukkit.util.Vector vector) {
++ net.minecraft.world.entity.projectile.ShulkerBullet bullet = this.getHandle();
++ bullet.targetDeltaX = vector.getX();
++ bullet.targetDeltaY = vector.getY();
++ bullet.targetDeltaZ = vector.getZ();
++ }
++
++ @Override
++ public org.bukkit.block.BlockFace getCurrentMovementDirection() {
++ return org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(this.getHandle().currentMoveDirection);
++ }
++
++ @Override
++ public void setCurrentMovementDirection(org.bukkit.block.BlockFace movementDirection) {
++ this.getHandle().currentMoveDirection = org.bukkit.craftbukkit.block.CraftBlock.blockFaceToNotch(movementDirection);
++ }
++
++ @Override
++ public int getFlightSteps() {
++ return this.getHandle().flightSteps;
++ }
++
++ @Override
++ public void setFlightSteps(int steps) {
++ this.getHandle().flightSteps = steps;
++ }
++
+ @Override
+ public String toString() {
+ return "CraftShulkerBullet";
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
index 0db8aa840ea026d48215ac5dc80ffde5f12725b1..397e0df15a0e64e5bc522f62f3b327a5039ec4c8 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java
@@ -194,6 +307,26 @@ index 0db8aa840ea026d48215ac5dc80ffde5f12725b1..397e0df15a0e64e5bc522f62f3b327a5
@Override
public net.minecraft.world.entity.projectile.ThrownPotion getHandle() {
return (net.minecraft.world.entity.projectile.ThrownPotion) entity;
+diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java
+index 832981b07ef5c633ef00a382f56798ee87eec0df..faf071201b7c1414225a33fe9641eac9477d53c7 100644
+--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java
++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftTrident.java
+@@ -59,5 +59,15 @@ public class CraftTrident extends CraftArrow implements Trident {
+ com.google.common.base.Preconditions.checkArgument(loyaltyLevel >= 0 && loyaltyLevel <= 127, "The loyalty level has to be between 0 and 127");
+ this.getHandle().setLoyalty((byte) loyaltyLevel);
+ }
++
++ @Override
++ public boolean hasDealtDamage() {
++ return this.getHandle().dealtDamage;
++ }
++
++ @Override
++ public void setHasDealtDamage(boolean hasDealtDamage) {
++ this.getHandle().dealtDamage = hasDealtDamage;
++ }
+ // Paper end
+ }
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
index f3abcd5949011eaef3d1ba68f4cc0751042d2834..bfb1ad0b6e20e10fee53f94a3e6c4f8aad7aae7d 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java