aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/unapplied/server/0211-PlayerLaunchProjectileEvent.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/unapplied/server/0211-PlayerLaunchProjectileEvent.patch')
-rw-r--r--patches/unapplied/server/0211-PlayerLaunchProjectileEvent.patch377
1 files changed, 377 insertions, 0 deletions
diff --git a/patches/unapplied/server/0211-PlayerLaunchProjectileEvent.patch b/patches/unapplied/server/0211-PlayerLaunchProjectileEvent.patch
new file mode 100644
index 0000000000..de1f0193b6
--- /dev/null
+++ b/patches/unapplied/server/0211-PlayerLaunchProjectileEvent.patch
@@ -0,0 +1,377 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: BillyGalbreath <[email protected]>
+Date: Sat, 21 Jul 2018 03:11:03 -0500
+Subject: [PATCH] PlayerLaunchProjectileEvent
+
+
+diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
+index f8ae12a3540c4a7aa7e2c1656cbd866e33e11f57..d6dfda0580d919eb8a000113e7f9dd9794117b45 100644
+--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
++++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
+@@ -197,7 +197,12 @@ public abstract class Projectile extends Entity implements TraceableEntity {
+ }
+
+ public static <T extends Projectile> T spawnProjectileFromRotation(Projectile.ProjectileFactory<T> creator, ServerLevel world, ItemStack projectileStack, LivingEntity shooter, float roll, float power, float divergence) {
+- return Projectile.spawnProjectile(creator.create(world, shooter, projectileStack), world, projectileStack, (iprojectile) -> {
++ // Paper start - PlayerLaunchProjectileEvent
++ return spawnProjectileFromRotationDelayed(creator, world, projectileStack, shooter, roll, power, divergence).spawn();
++ }
++ public static <T extends Projectile> Delayed<T> spawnProjectileFromRotationDelayed(Projectile.ProjectileFactory<T> creator, ServerLevel world, ItemStack projectileStack, LivingEntity shooter, float roll, float power, float divergence) {
++ return Projectile.spawnProjectileDelayed(creator.create(world, shooter, projectileStack), world, projectileStack, (iprojectile) -> {
++ // Paper end - PlayerLaunchProjectileEvent
+ iprojectile.shootFromRotation(shooter, shooter.getXRot(), shooter.getYRot(), roll, power, divergence);
+ });
+ }
+diff --git a/src/main/java/net/minecraft/world/item/EggItem.java b/src/main/java/net/minecraft/world/item/EggItem.java
+index 8ddc1fa76244265616309322170c3a1b821c5092..3ddd34e5d05fa1355a2affd329d72dea216cd0e4 100644
+--- a/src/main/java/net/minecraft/world/item/EggItem.java
++++ b/src/main/java/net/minecraft/world/item/EggItem.java
+@@ -26,7 +26,19 @@ public class EggItem extends Item implements ProjectileItem {
+ // world.playSound((EntityHuman) null, entityhuman.getX(), entityhuman.getY(), entityhuman.getZ(), SoundEffects.EGG_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); // CraftBukkit - moved down
+ if (world instanceof ServerLevel worldserver) {
+ // CraftBukkit start
+- if (Projectile.spawnProjectileFromRotation(ThrownEgg::new, worldserver, itemstack, user, 0.0F, 1.5F, 1.0F).isRemoved()) {
++ // Paper start - PlayerLaunchProjectileEvent
++ final Projectile.Delayed<ThrownEgg> thrownEgg = Projectile.spawnProjectileFromRotationDelayed(ThrownEgg::new, worldserver, itemstack, user, 0.0F, 1.5F, 1.0F);
++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) thrownEgg.projectile().getBukkitEntity());
++ if (event.callEvent() && thrownEgg.attemptSpawn()) {
++ if (event.shouldConsume()) {
++ itemstack.consume(1, user);
++ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
++ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
++ }
++
++ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EGG_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
++ user.awardStat(Stats.ITEM_USED.get(this));
++ } else {
+ if (user instanceof net.minecraft.server.level.ServerPlayer) {
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
+ }
+@@ -35,9 +47,7 @@ public class EggItem extends Item implements ProjectileItem {
+ // CraftBukkit end
+ }
+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EGG_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
+-
+- user.awardStat(Stats.ITEM_USED.get(this));
+- itemstack.consume(1, user);
++ // Paper - PlayerLaunchProjectileEvent - moved up
+ return InteractionResult.SUCCESS;
+ }
+
+diff --git a/src/main/java/net/minecraft/world/item/EnderpearlItem.java b/src/main/java/net/minecraft/world/item/EnderpearlItem.java
+index b9e24451a8f87479377e3324b3a956c0efc3e53c..b232390d8ee8e449e61c0ea7f3af60df507abb97 100644
+--- a/src/main/java/net/minecraft/world/item/EnderpearlItem.java
++++ b/src/main/java/net/minecraft/world/item/EnderpearlItem.java
+@@ -23,7 +23,20 @@ public class EnderpearlItem extends Item {
+
+ if (world instanceof ServerLevel worldserver) {
+ // CraftBukkit start
+- if (Projectile.spawnProjectileFromRotation(ThrownEnderpearl::new, worldserver, itemstack, user, 0.0F, 1.5F, 1.0F).isRemoved()) {
++ // Paper start - PlayerLaunchProjectileEvent
++ final Projectile.Delayed<ThrownEnderpearl> thrownEnderpearl = Projectile.spawnProjectileFromRotationDelayed(ThrownEnderpearl::new, worldserver, itemstack, user, 0.0F, 1.5F, 1.0F);
++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) thrownEnderpearl.projectile().getBukkitEntity());
++ if (event.callEvent() && thrownEnderpearl.attemptSpawn()) {
++ if (event.shouldConsume()) {
++ itemstack.consume(1, user);
++ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
++ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
++ }
++
++ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
++ user.awardStat(Stats.ITEM_USED.get(this));
++ } else {
++ // Paper end - PlayerLaunchProjectileEvent
+ if (user instanceof net.minecraft.server.level.ServerPlayer) {
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
+ }
+@@ -33,8 +46,7 @@ public class EnderpearlItem extends Item {
+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
+ // CraftBukkit end
+
+- user.awardStat(Stats.ITEM_USED.get(this));
+- itemstack.consume(1, user);
++ // Paper - PlayerLaunchProjectileEvent - moved up
+ return InteractionResult.SUCCESS;
+ }
+ }
+diff --git a/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java b/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java
+index b255e40277585928a767e5efd4b61708e13dab50..dfa3f9534159400e539ee61debedffb5f978aae8 100644
+--- a/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java
++++ b/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java
+@@ -21,22 +21,38 @@ public class ExperienceBottleItem extends Item implements ProjectileItem {
+ @Override
+ public InteractionResult use(Level world, Player user, InteractionHand hand) {
+ ItemStack itemStack = user.getItemInHand(hand);
+- world.playSound(
+- null,
+- user.getX(),
+- user.getY(),
+- user.getZ(),
+- SoundEvents.EXPERIENCE_BOTTLE_THROW,
+- SoundSource.NEUTRAL,
+- 0.5F,
+- 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)
+- );
++ // Paper - PlayerLaunchProjectileEvent - moved down
+ if (world instanceof ServerLevel serverLevel) {
+- Projectile.spawnProjectileFromRotation(ThrownExperienceBottle::new, serverLevel, itemStack, user, -20.0F, 0.7F, 1.0F);
++ // Paper start - PlayerLaunchProjectileEvent
++ final Projectile.Delayed<ThrownExperienceBottle> thrownExperienceBottle = Projectile.spawnProjectileFromRotationDelayed(ThrownExperienceBottle::new, serverLevel, itemStack, user, -20.0F, 0.7F, 1.0F);
++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownExperienceBottle.projectile().getBukkitEntity());
++ if (event.callEvent() && thrownExperienceBottle.attemptSpawn()) {
++ if (event.shouldConsume()) {
++ itemStack.consume(1, user);
++ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
++ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
++ }
++
++ world.playSound(
++ null,
++ user.getX(),
++ user.getY(),
++ user.getZ(),
++ SoundEvents.EXPERIENCE_BOTTLE_THROW,
++ SoundSource.NEUTRAL,
++ 0.5F,
++ 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)
++ );
++ } else {
++ if (user instanceof net.minecraft.server.level.ServerPlayer) {
++ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
++ }
++ return InteractionResult.FAIL;
++ }
++ // Paper end - PlayerLaunchProjectileEvent
+ }
+
+- user.awardStat(Stats.ITEM_USED.get(this));
+- itemStack.consume(1, user);
++ // Paper - PlayerLaunchProjectileEvent - moved up
+ return InteractionResult.SUCCESS;
+ }
+
+diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
+index 400ad0fa1d07c8b120e3c3b5488dfa315aa2d23f..29a048a9b09166838616ac7ba1d31625d56b0bca 100644
+--- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
++++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
+@@ -33,7 +33,7 @@ public class FireworkRocketItem extends Item implements ProjectileItem {
+ ItemStack itemStack = context.getItemInHand();
+ Vec3 vec3 = context.getClickLocation();
+ Direction direction = context.getClickedFace();
+- Projectile.spawnProjectile(
++ final Projectile.Delayed<FireworkRocketEntity> fireworkRocketEntity = Projectile.spawnProjectileDelayed( // Paper - PlayerLaunchProjectileEvent
+ new FireworkRocketEntity(
+ level,
+ context.getPlayer(),
+@@ -45,7 +45,12 @@ public class FireworkRocketItem extends Item implements ProjectileItem {
+ serverLevel,
+ itemStack, f -> f.spawningEntity = context.getPlayer() == null ? null : context.getPlayer().getUUID() // Paper - firework api - assign spawning entity uuid
+ );
+- itemStack.shrink(1);
++ // Paper start - PlayerLaunchProjectileEvent
++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) fireworkRocketEntity.projectile().getBukkitEntity());
++ if (!event.callEvent() || !fireworkRocketEntity.attemptSpawn()) return InteractionResult.PASS;
++ if (event.shouldConsume() && !context.getPlayer().hasInfiniteMaterials()) itemStack.shrink(1);
++ else if (context.getPlayer() instanceof net.minecraft.server.level.ServerPlayer) ((net.minecraft.server.level.ServerPlayer) context.getPlayer()).getBukkitEntity().updateInventory();
++ // Paper end - PlayerLaunchProjectileEvent
+ }
+
+ return InteractionResult.SUCCESS;
+diff --git a/src/main/java/net/minecraft/world/item/LingeringPotionItem.java b/src/main/java/net/minecraft/world/item/LingeringPotionItem.java
+index 7a5045469bc2d383ed087dcc094b6f97df4ec7ab..fa92a1346825f00a585503d0a0825711fe3f754e 100644
+--- a/src/main/java/net/minecraft/world/item/LingeringPotionItem.java
++++ b/src/main/java/net/minecraft/world/item/LingeringPotionItem.java
+@@ -24,6 +24,10 @@ public class LingeringPotionItem extends ThrowablePotionItem {
+
+ @Override
+ public InteractionResult use(Level world, Player user, InteractionHand hand) {
++ // Paper start - PlayerLaunchProjectileEvent
++ final InteractionResult wrapper = super.use(world, user, hand);
++ if (wrapper instanceof InteractionResult.Fail) return wrapper;
++ // Paper end - PlayerLaunchProjectileEvent
+ world.playSound(
+ null,
+ user.getX(),
+@@ -34,6 +38,6 @@ public class LingeringPotionItem extends ThrowablePotionItem {
+ 0.5F,
+ 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)
+ );
+- return super.use(world, user, hand);
++ return wrapper; // Paper - PlayerLaunchProjectileEvent
+ }
+ }
+diff --git a/src/main/java/net/minecraft/world/item/SnowballItem.java b/src/main/java/net/minecraft/world/item/SnowballItem.java
+index ada9bc42a788b5f472324a0765edf5766d729784..57872ebef6beb8cdc03c9f8f19de94652ee19062 100644
+--- a/src/main/java/net/minecraft/world/item/SnowballItem.java
++++ b/src/main/java/net/minecraft/world/item/SnowballItem.java
+@@ -26,17 +26,26 @@ public class SnowballItem extends Item implements ProjectileItem {
+ // CraftBukkit start - moved down
+ // world.playSound((EntityHuman) null, entityhuman.getX(), entityhuman.getY(), entityhuman.getZ(), SoundEffects.SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
+ if (world instanceof ServerLevel worldserver) {
+- if (Projectile.spawnProjectileFromRotation(Snowball::new, worldserver, itemstack, user, 0.0F, 1.5F, 1.0F).isAlive()) {
+- itemstack.consume(1, user);
++ // Paper start - PlayerLaunchProjectileEvent
++ final Projectile.Delayed<Snowball> snowball = Projectile.spawnProjectileFromRotationDelayed(Snowball::new, worldserver, itemstack, user, 0.0F, 1.5F, 1.0F);
++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) snowball.projectile().getBukkitEntity());
++ if (event.callEvent() && snowball.attemptSpawn()) {
++ user.awardStat(Stats.ITEM_USED.get(this));
++ if (event.shouldConsume()) {
++ itemstack.consume(1, user);
++ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
++ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
++ }
++ // Paper end - PlayerLaunchProjectileEvent
+
+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.SNOWBALL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
+- } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
++ } else { if (user instanceof net.minecraft.server.level.ServerPlayer) { // Paper - PlayerLaunchProjectileEvent - return fail
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
+- }
++ } return InteractionResult.FAIL; } // Paper - PlayerLaunchProjectileEvent - return fail
+ // CraftBukkit end
+ }
+
+- user.awardStat(Stats.ITEM_USED.get(this));
++ // Paper - PlayerLaunchProjectileEvent - moved up
+ // itemstack.consume(1, entityhuman); // CraftBukkit - moved up
+ return InteractionResult.SUCCESS;
+ }
+diff --git a/src/main/java/net/minecraft/world/item/SplashPotionItem.java b/src/main/java/net/minecraft/world/item/SplashPotionItem.java
+index 6d622d276a632c9c29ab04a01fbe7adbf10c35cd..577e66a7ff64d9569ee2402ecc26b0aa1105fe9a 100644
+--- a/src/main/java/net/minecraft/world/item/SplashPotionItem.java
++++ b/src/main/java/net/minecraft/world/item/SplashPotionItem.java
+@@ -14,6 +14,10 @@ public class SplashPotionItem extends ThrowablePotionItem {
+
+ @Override
+ public InteractionResult use(Level world, Player user, InteractionHand hand) {
++ // Paper start - PlayerLaunchProjectileEvent
++ final InteractionResult wrapper = super.use(world, user, hand);
++ if (wrapper instanceof InteractionResult.Fail) return wrapper;
++ // Paper end - PlayerLaunchProjectileEvent
+ world.playSound(
+ null,
+ user.getX(),
+@@ -24,6 +28,6 @@ public class SplashPotionItem extends ThrowablePotionItem {
+ 0.5F,
+ 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)
+ );
+- return super.use(world, user, hand);
++ return wrapper; // Paper - PlayerLaunchProjectileEvent
+ }
+ }
+diff --git a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
+index e3eb733f18c23ae3fcc4c271843d285b217d1a7d..fa9d2ae44fcdd06f8f33cd14ffca422b20a01451 100644
+--- a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
++++ b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
+@@ -20,11 +20,28 @@ public class ThrowablePotionItem extends PotionItem implements ProjectileItem {
+ public InteractionResult use(Level world, Player user, InteractionHand hand) {
+ ItemStack itemStack = user.getItemInHand(hand);
+ if (world instanceof ServerLevel serverLevel) {
+- Projectile.spawnProjectileFromRotation(ThrownPotion::new, serverLevel, itemStack, user, -20.0F, 0.5F, 1.0F);
++ // Paper start - PlayerLaunchProjectileEvent
++ final Projectile.Delayed<ThrownPotion> thrownPotion = Projectile.spawnProjectileFromRotationDelayed(ThrownPotion::new, serverLevel, itemStack, user, -20.0F, 0.5F, 1.0F);
++ // Paper start - PlayerLaunchProjectileEvent
++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownPotion.projectile().getBukkitEntity());
++ if (event.callEvent() && thrownPotion.attemptSpawn()) {
++ if (event.shouldConsume()) {
++ itemStack.consume(1, user);
++ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
++ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
++ }
++
++ user.awardStat(Stats.ITEM_USED.get(this));
++ } else {
++ if (user instanceof net.minecraft.server.level.ServerPlayer) {
++ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
++ }
++ return InteractionResult.FAIL;
++ }
++ // Paper end - PlayerLaunchProjectileEvent
+ }
+
+- user.awardStat(Stats.ITEM_USED.get(this));
+- itemStack.consume(1, user);
++ // Paper - PlayerLaunchProjectileEvent - move up
+ return InteractionResult.SUCCESS;
+ }
+
+diff --git a/src/main/java/net/minecraft/world/item/TridentItem.java b/src/main/java/net/minecraft/world/item/TridentItem.java
+index 22aa715c4ef615c2c9d795cc2e11b7099d5167da..8b9a93ef71164cce8a616735b71d96d37e83b1a8 100644
+--- a/src/main/java/net/minecraft/world/item/TridentItem.java
++++ b/src/main/java/net/minecraft/world/item/TridentItem.java
+@@ -87,21 +87,26 @@ public class TridentItem extends Item implements ProjectileItem {
+
+ // itemstack.hurtWithoutBreaking(1, entityhuman); // CraftBukkit - moved down
+ if (f == 0.0F) {
+- ThrownTrident entitythrowntrident = (ThrownTrident) Projectile.spawnProjectileFromRotation(ThrownTrident::new, worldserver, stack, entityhuman, 0.0F, 2.5F, 1.0F);
+- // CraftBukkit start
+- if (entitythrowntrident.isRemoved()) {
++ // Paper start - PlayerLaunchProjectileEvent
++ Projectile.Delayed<ThrownTrident> tridentDelayed = Projectile.spawnProjectileFromRotationDelayed(ThrownTrident::new, worldserver, stack, entityhuman, 0.0F, 2.5F, 1.0F);
++ // Paper start - PlayerLaunchProjectileEvent
++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), (org.bukkit.entity.Projectile) tridentDelayed.projectile().getBukkitEntity());
++ if (!event.callEvent() || !tridentDelayed.attemptSpawn()) {
++ // CraftBukkit start
++ // Paper end - PlayerLaunchProjectileEvent
+ if (entityhuman instanceof net.minecraft.server.level.ServerPlayer) {
+ ((net.minecraft.server.level.ServerPlayer) entityhuman).getBukkitEntity().updateInventory();
+ }
+ return false;
+ }
+- stack.hurtWithoutBreaking(1, entityhuman);
++ ThrownTrident entitythrowntrident = tridentDelayed.projectile(); // Paper - PlayerLaunchProjectileEvent
++ if (event.shouldConsume()) stack.hurtWithoutBreaking(1, entityhuman); // Paper - PlayerLaunchProjectileEvent
+ entitythrowntrident.pickupItemStack = stack.copy(); // SPIGOT-4511 update since damage call moved
+ // CraftBukkit end
+
+ if (entityhuman.hasInfiniteMaterials()) {
+ entitythrowntrident.pickup = AbstractArrow.Pickup.CREATIVE_ONLY;
+- } else {
++ } else if (event.shouldConsume()) { // Paper - PlayerLaunchProjectileEvent
+ entityhuman.getInventory().removeItem(stack);
+ }
+
+diff --git a/src/main/java/net/minecraft/world/item/WindChargeItem.java b/src/main/java/net/minecraft/world/item/WindChargeItem.java
+index 79fdb78a4c3c7e324f0ed84a3dad9a3a80a6456a..0ce52d239b5bfb63e09cf5df679eee177f7bc5b0 100644
+--- a/src/main/java/net/minecraft/world/item/WindChargeItem.java
++++ b/src/main/java/net/minecraft/world/item/WindChargeItem.java
+@@ -25,7 +25,7 @@ public class WindChargeItem extends Item implements ProjectileItem {
+ public InteractionResult use(Level world, Player user, InteractionHand hand) {
+ ItemStack itemStack = user.getItemInHand(hand);
+ if (world instanceof ServerLevel serverLevel) {
+- Projectile.spawnProjectileFromRotation(
++ final Projectile.Delayed<WindCharge> windCharge = Projectile.spawnProjectileFromRotationDelayed( // Paper - PlayerLaunchProjectileEvent
+ (world2, shooter, stack) -> new WindCharge(user, world, user.position().x(), user.getEyePosition().y(), user.position().z()),
+ serverLevel,
+ itemStack,
+@@ -34,6 +34,21 @@ public class WindChargeItem extends Item implements ProjectileItem {
+ 1.5F,
+ 1.0F
+ );
++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) windCharge.projectile().getBukkitEntity());
++ if (!event.callEvent() || !windCharge.attemptSpawn()) {
++ user.containerMenu.sendAllDataToRemote();
++ if (user instanceof net.minecraft.server.level.ServerPlayer player) {
++ player.connection.send(new net.minecraft.network.protocol.game.ClientboundCooldownPacket(user.getCooldowns().getCooldownGroup(itemStack), 0)); // prevent visual desync of cooldown on the slot
++ }
++ return InteractionResult.FAIL;
++ }
++
++ user.awardStat(Stats.ITEM_USED.get(this));
++ if (event.shouldConsume()) itemStack.consume(1, user);
++ else if (!user.hasInfiniteMaterials()) {
++ user.containerMenu.sendAllDataToRemote();
++ }
++ // Paper end - PlayerLaunchProjectileEvent
+ }
+
+ world.playSound(
+@@ -46,8 +61,6 @@ public class WindChargeItem extends Item implements ProjectileItem {
+ 0.5F,
+ 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)
+ );
+- user.awardStat(Stats.ITEM_USED.get(this));
+- itemStack.consume(1, user);
+ return InteractionResult.SUCCESS;
+ }
+