001    package org.bukkit.event.player;
002    
003    import org.bukkit.block.Block;
004    import org.bukkit.block.BlockFace;
005    import org.bukkit.event.HandlerList;
006    import org.bukkit.inventory.ItemStack;
007    import org.bukkit.Material;
008    import org.bukkit.entity.Player;
009    import org.bukkit.event.Cancellable;
010    import org.bukkit.event.block.Action;
011    
012    /**
013     * Called when a player interacts with an object or air.
014     */
015    public class PlayerInteractEvent extends PlayerEvent implements Cancellable {
016        private static final HandlerList handlers = new HandlerList();
017        protected ItemStack item;
018        protected Action action;
019        protected Block blockClicked;
020        protected BlockFace blockFace;
021        private Result useClickedBlock;
022        private Result useItemInHand;
023    
024        public PlayerInteractEvent(final Player who, final Action action, final ItemStack item, final Block clickedBlock, final BlockFace clickedFace) {
025            super(who);
026            this.action = action;
027            this.item = item;
028            this.blockClicked = clickedBlock;
029            this.blockFace = clickedFace;
030    
031            useItemInHand = Result.DEFAULT;
032            useClickedBlock = clickedBlock == null ? Result.DENY : Result.ALLOW;
033        }
034    
035        /**
036         * Returns the action type
037         *
038         * @return Action returns the type of interaction
039         */
040        public Action getAction() {
041            return action;
042        }
043    
044        /**
045         * Gets the cancellation state of this event. Set to true if you want to
046         * prevent buckets from placing water and so forth
047         *
048         * @return boolean cancellation state
049         */
050        public boolean isCancelled() {
051            return useInteractedBlock() == Result.DENY;
052        }
053    
054        /**
055         * Sets the cancellation state of this event. A canceled event will not be
056         * executed in the server, but will still pass to other plugins
057         * <p>
058         * Canceling this event will prevent use of food (player won't lose the
059         * food item), prevent bows/snowballs/eggs from firing, etc. (player won't
060         * lose the ammo)
061         *
062         * @param cancel true if you wish to cancel this event
063         */
064        public void setCancelled(boolean cancel) {
065            setUseInteractedBlock(cancel ? Result.DENY : useInteractedBlock() == Result.DENY ? Result.DEFAULT : useInteractedBlock());
066            setUseItemInHand(cancel ? Result.DENY : useItemInHand() == Result.DENY ? Result.DEFAULT : useItemInHand());
067        }
068    
069        /**
070         * Returns the item in hand represented by this event
071         *
072         * @return ItemStack the item used
073         */
074        public ItemStack getItem() {
075            return this.item;
076        }
077    
078        /**
079         * Convenience method. Returns the material of the item represented by
080         * this event
081         *
082         * @return Material the material of the item used
083         */
084        public Material getMaterial() {
085            if (!hasItem()) {
086                return Material.AIR;
087            }
088    
089            return item.getType();
090        }
091    
092        /**
093         * Check if this event involved a block
094         *
095         * @return boolean true if it did
096         */
097        public boolean hasBlock() {
098            return this.blockClicked != null;
099        }
100    
101        /**
102         * Check if this event involved an item
103         *
104         * @return boolean true if it did
105         */
106        public boolean hasItem() {
107            return this.item != null;
108        }
109    
110        /**
111         * Convenience method to inform the user whether this was a block
112         * placement event.
113         *
114         * @return boolean true if the item in hand was a block
115         */
116        public boolean isBlockInHand() {
117            if (!hasItem()) {
118                return false;
119            }
120    
121            return item.getType().isBlock();
122        }
123    
124        /**
125         * Returns the clicked block
126         *
127         * @return Block returns the block clicked with this item.
128         */
129        public Block getClickedBlock() {
130            return blockClicked;
131        }
132    
133        /**
134         * Returns the face of the block that was clicked
135         *
136         * @return BlockFace returns the face of the block that was clicked
137         */
138        public BlockFace getBlockFace() {
139            return blockFace;
140        }
141    
142        /**
143         * This controls the action to take with the block (if any) that was
144         * clicked on. This event gets processed for all blocks, but most don't
145         * have a default action
146         *
147         * @return the action to take with the interacted block
148         */
149        public Result useInteractedBlock() {
150            return useClickedBlock;
151        }
152    
153        /**
154         * @param useInteractedBlock the action to take with the interacted block
155         */
156        public void setUseInteractedBlock(Result useInteractedBlock) {
157            this.useClickedBlock = useInteractedBlock;
158        }
159    
160        /**
161         * This controls the action to take with the item the player is holding.
162         * This includes both blocks and items (such as flint and steel or
163         * records). When this is set to default, it will be allowed if no action
164         * is taken on the interacted block.
165         *
166         * @return the action to take with the item in hand
167         */
168        public Result useItemInHand() {
169            return useItemInHand;
170        }
171    
172        /**
173         * @param useItemInHand the action to take with the item in hand
174         */
175        public void setUseItemInHand(Result useItemInHand) {
176            this.useItemInHand = useItemInHand;
177        }
178    
179        @Override
180        public HandlerList getHandlers() {
181            return handlers;
182        }
183    
184        public static HandlerList getHandlerList() {
185            return handlers;
186        }
187    }