From be0d8a5f742ae257e4122d89992893a7f645863c Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Mon, 18 Jun 2018 01:13:16 -0400
Subject: [PATCH] PlayerReadyArrowEvent

Called when a player is firing a bow and the server is choosing an arrow to use.
Plugins can skip selection of certain arrows and control which is used.
---
 .../PlayerReadyArrowEvent.patch               | 103 ++++++++++++++++++
 .../PlayerReadyArrowEvent.patch               |  77 +++++++++++++
 2 files changed, 180 insertions(+)
 create mode 100644 Spigot-API-Patches/PlayerReadyArrowEvent.patch
 create mode 100644 Spigot-Server-Patches/PlayerReadyArrowEvent.patch

diff --git a/Spigot-API-Patches/PlayerReadyArrowEvent.patch b/Spigot-API-Patches/PlayerReadyArrowEvent.patch
new file mode 100644
index 0000000000..4d80e48443
--- /dev/null
+++ b/Spigot-API-Patches/PlayerReadyArrowEvent.patch
@@ -0,0 +1,103 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Aikar <aikar@aikar.co>
+Date: Mon, 18 Jun 2018 01:09:27 -0400
+Subject: [PATCH] PlayerReadyArrowEvent
+
+Called when a player is firing a bow and the server is choosing an arrow to use.
+Plugins can skip selection of certain arrows and control which is used.
+
+diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerReadyArrowEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerReadyArrowEvent.java
+new file mode 100644
+index 00000000..c6add1b1
+--- /dev/null
++++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerReadyArrowEvent.java
+@@ -0,0 +0,0 @@
++/*
++ * Copyright (c) 2018 Daniel Ennis (Aikar) MIT License
++ *
++ *  Permission is hereby granted, free of charge, to any person obtaining
++ *  a copy of this software and associated documentation files (the
++ *  "Software"), to deal in the Software without restriction, including
++ *  without limitation the rights to use, copy, modify, merge, publish,
++ *  distribute, sublicense, and/or sell copies of the Software, and to
++ *  permit persons to whom the Software is furnished to do so, subject to
++ *  the following conditions:
++ *
++ *  The above copyright notice and this permission notice shall be
++ *  included in all copies or substantial portions of the Software.
++ *
++ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++ *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++ *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++ *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++ */
++
++package com.destroystokyo.paper.event.player;
++
++import org.bukkit.entity.Player;
++import org.bukkit.event.Cancellable;
++import org.bukkit.event.Event;
++import org.bukkit.event.HandlerList;
++import org.bukkit.event.player.PlayerEvent;
++import org.bukkit.inventory.ItemStack;
++
++/**
++ * Called when a player is firing a bow and the server is choosing an arrow to use.
++ */
++public class PlayerReadyArrowEvent extends PlayerEvent implements Cancellable {
++    private final ItemStack bow;
++    private final ItemStack arrow;
++
++    public PlayerReadyArrowEvent(Player player, ItemStack bow, ItemStack arrow) {
++        super(player);
++        this.bow = bow;
++        this.arrow = arrow;
++    }
++
++    /**
++     * What bow the player is using to fire the arrow
++     */
++    public ItemStack getBow() {
++        return bow;
++    }
++
++    /**
++     * What arrow is being attempted to use
++     */
++    public ItemStack getArrow() {
++        return arrow;
++    }
++
++    private static final HandlerList handlers = new HandlerList();
++
++    public HandlerList getHandlers() {
++        return handlers;
++    }
++
++    public static HandlerList getHandlerList() {
++        return handlers;
++    }
++
++    private boolean cancelled = false;
++
++    /**
++     * Whether or not use of this arrow is cancelled. On cancel, the server will try the next arrow available and fire another event.
++     */
++    @Override
++    public boolean isCancelled() {
++        return cancelled;
++    }
++
++    /**
++     * Cancel use of this arrow. On cancel, the server will try the next arrow available and fire another event.
++     * @param cancel true if you wish to cancel this event
++     */
++    @Override
++    public void setCancelled(boolean cancel) {
++        cancelled = cancel;
++    }
++}
+--
\ No newline at end of file
diff --git a/Spigot-Server-Patches/PlayerReadyArrowEvent.patch b/Spigot-Server-Patches/PlayerReadyArrowEvent.patch
new file mode 100644
index 0000000000..a4917870fd
--- /dev/null
+++ b/Spigot-Server-Patches/PlayerReadyArrowEvent.patch
@@ -0,0 +1,77 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Aikar <aikar@aikar.co>
+Date: Mon, 18 Jun 2018 01:12:53 -0400
+Subject: [PATCH] PlayerReadyArrowEvent
+
+Called when a player is firing a bow and the server is choosing an arrow to use.
+Plugins can skip selection of certain arrows and control which is used.
+
+diff --git a/src/main/java/net/minecraft/server/ItemBow.java b/src/main/java/net/minecraft/server/ItemBow.java
+index 327d31e19..44e7be58e 100644
+--- a/src/main/java/net/minecraft/server/ItemBow.java
++++ b/src/main/java/net/minecraft/server/ItemBow.java
+@@ -0,0 +0,0 @@
+ package net.minecraft.server;
+ 
++import org.bukkit.craftbukkit.inventory.CraftItemStack;
+ import org.bukkit.event.entity.EntityCombustEvent; // CraftBukkit
+ 
+ public class ItemBow extends Item {
+@@ -0,0 +0,0 @@ public class ItemBow extends Item {
+         });
+     }
+ 
+-    private ItemStack a(EntityHuman entityhuman) {
+-        if (this.d(entityhuman.b(EnumHand.OFF_HAND))) {
++    private ItemStack a(EntityHuman entityhuman, ItemStack bow) { // Paper
++        if (this.d(entityhuman, bow, entityhuman.b(EnumHand.OFF_HAND))) { // Paper
+             return entityhuman.b(EnumHand.OFF_HAND);
+-        } else if (this.d(entityhuman.b(EnumHand.MAIN_HAND))) {
++        } else if (this.d(entityhuman, bow, entityhuman.b(EnumHand.MAIN_HAND))) { // Paper
+             return entityhuman.b(EnumHand.MAIN_HAND);
+         } else {
+             for (int i = 0; i < entityhuman.inventory.getSize(); ++i) {
+                 ItemStack itemstack = entityhuman.inventory.getItem(i);
+ 
+-                if (this.d(itemstack)) {
++                if (this.d(entityhuman, bow, itemstack)) { // Paper
+                     return itemstack;
+                 }
+             }
+@@ -0,0 +0,0 @@ public class ItemBow extends Item {
+         }
+     }
+ 
+-    protected boolean d(ItemStack itemstack) {
+-        return itemstack.getItem() instanceof ItemArrow;
++    // Paper start
++    protected boolean d(EntityHuman player, ItemStack bow, ItemStack itemstack) {
++        return itemstack.getItem() instanceof ItemArrow && (
++                !(player instanceof EntityPlayer) ||
++                new com.destroystokyo.paper.event.player.PlayerReadyArrowEvent(
++                        ((EntityPlayer) player).getBukkitEntity(),
++                        CraftItemStack.asCraftMirror(bow),
++                        CraftItemStack.asCraftMirror(itemstack)
++                    ).callEvent());
++        // Paper end
+     }
+ 
+     public void a(ItemStack itemstack, World world, EntityLiving entityliving, int i) {
+         if (entityliving instanceof EntityHuman) {
+             EntityHuman entityhuman = (EntityHuman) entityliving;
+             boolean flag = entityhuman.abilities.canInstantlyBuild || EnchantmentManager.getEnchantmentLevel(Enchantments.ARROW_INFINITE, itemstack) > 0;
+-            ItemStack itemstack1 = this.a(entityhuman);
++            ItemStack itemstack1 = this.a(entityhuman, itemstack); // Paper
+ 
+             if (!itemstack1.isEmpty() || flag) {
+                 if (itemstack1.isEmpty()) {
+@@ -0,0 +0,0 @@ public class ItemBow extends Item {
+ 
+     public InteractionResultWrapper<ItemStack> a(World world, EntityHuman entityhuman, EnumHand enumhand) {
+         ItemStack itemstack = entityhuman.b(enumhand);
+-        boolean flag = !this.a(entityhuman).isEmpty();
++        boolean flag = !this.a(entityhuman, itemstack).isEmpty(); // Paper
+ 
+         if (!entityhuman.abilities.canInstantlyBuild && !flag) {
+             return flag ? new InteractionResultWrapper(EnumInteractionResult.PASS, itemstack) : new InteractionResultWrapper(EnumInteractionResult.FAIL, itemstack);
+--
\ No newline at end of file