@@ -109,7 +109,7 @@ public boolean check(final Event e) {
109109
110110 Player player = clickEvent .getPlayer ();
111111 assert player != null ;
112- boolean useOffHand = checkOffHandUse ( mainHand , offHand , click , player , null );
112+ boolean useOffHand = checkUseOffHand ( player , click , null );
113113 if ((useOffHand && clickEvent .getHand () == EquipmentSlot .HAND ) || (!useOffHand && clickEvent .getHand () == EquipmentSlot .OFF_HAND )) {
114114 return false ;
115115 }
@@ -127,7 +127,9 @@ public boolean check(final Event e) {
127127
128128 Player player = clickEvent .getPlayer ();
129129 assert player != null ;
130- boolean useOffHand = checkOffHandUse (mainHand , offHand , click , player , clickEvent .getClickedBlock ());
130+ boolean useOffHand = checkUseOffHand (player , click , clickEvent .getClickedBlock ());
131+ //Skript.info("useOffHand: " + useOffHand);
132+ //Skript.info("Event hand: " + clickEvent.getHand());
131133 if ((useOffHand && clickEvent .getHand () == EquipmentSlot .HAND ) || (!useOffHand && clickEvent .getHand () == EquipmentSlot .OFF_HAND )) {
132134 return false ;
133135 }
@@ -186,7 +188,157 @@ public String toString(final @Nullable Event e, final boolean debug) {
186188 return (click == LEFT ? "left" : click == RIGHT ? "right" : "" ) + "click" + (types != null ? " on " + types .toString (e , debug ) : "" ) + (tools != null ? " holding " + tools .toString (e , debug ) : "" );
187189 }
188190
189- private boolean checkOffHandUse (@ Nullable ItemStack mainHand , @ Nullable ItemStack offHand , int clickType , Player player , @ Nullable Block target ) {
191+ public static boolean checkUseOffHand (Player player , int clickType , @ Nullable Block block ) {
192+ if (clickType != RIGHT ) return false ; // Attacking with off hand is not possible
193+
194+ boolean mainUsable = false ; // Usable item
195+ boolean offUsable = false ;
196+ ItemStack mainHand = player .getInventory ().getItemInMainHand ();
197+ ItemStack offHand = player .getInventory ().getItemInOffHand ();
198+
199+ switch (offHand .getType ()) {
200+ case BOW :
201+ case EGG :
202+ case SPLASH_POTION :
203+ case SNOW_BALL :
204+ case BUCKET :
205+ case FISHING_ROD :
206+ case FLINT_AND_STEEL :
207+ case WOOD_HOE :
208+ case STONE_HOE :
209+ case IRON_HOE :
210+ case GOLD_HOE :
211+ case DIAMOND_HOE :
212+ case LEASH :
213+ case SHEARS :
214+ case WOOD_SPADE :
215+ case STONE_SPADE :
216+ case IRON_SPADE :
217+ case GOLD_SPADE :
218+ case DIAMOND_SPADE :
219+ case SHIELD :
220+ case ENDER_PEARL :
221+ offUsable = true ;
222+ break ;
223+ //$CASES-OMITTED$
224+ default :
225+ offUsable = false ;
226+ }
227+
228+ // Seriously? Empty hand -> block in hand, since id of AIR < 256 :O
229+ if ((offHand .getType ().isBlock () && offHand .getType () != Material .AIR ) || offHand .getType ().isEdible ()) {
230+ offUsable = true ;
231+ }
232+
233+ switch (mainHand .getType ()) {
234+ case BOW :
235+ case EGG :
236+ case SPLASH_POTION :
237+ case SNOW_BALL :
238+ case BUCKET :
239+ case FISHING_ROD :
240+ case FLINT_AND_STEEL :
241+ case WOOD_HOE :
242+ case STONE_HOE :
243+ case IRON_HOE :
244+ case GOLD_HOE :
245+ case DIAMOND_HOE :
246+ case LEASH :
247+ case SHEARS :
248+ case WOOD_SPADE :
249+ case STONE_SPADE :
250+ case IRON_SPADE :
251+ case GOLD_SPADE :
252+ case DIAMOND_SPADE :
253+ case ENDER_PEARL :
254+ mainUsable = true ;
255+ break ;
256+ //$CASES-OMITTED$
257+ default :
258+ mainUsable = false ;
259+ }
260+
261+ // Seriously? Empty hand -> block in hand, since id of AIR < 256 :O
262+ if ((mainHand .getType ().isBlock () && mainHand .getType () != Material .AIR ) || mainHand .getType ().isEdible ()) {
263+ mainUsable = true ;
264+ }
265+
266+ boolean blockUsable = false ;
267+ if (block != null ) {
268+ switch (block .getType ()) {
269+ case ANVIL :
270+ case BEACON :
271+ case BED :
272+ case BREWING_STAND :
273+ case CAKE :
274+ case CAULDRON :
275+ case CHEST :
276+ case TRAPPED_CHEST :
277+ case ENDER_CHEST :
278+ case WORKBENCH :
279+ case ENCHANTMENT_TABLE :
280+ case FURNACE :
281+ case WOODEN_DOOR :
282+ case ACACIA_DOOR :
283+ case JUNGLE_DOOR :
284+ case DARK_OAK_DOOR :
285+ case SPRUCE_DOOR :
286+ case BIRCH_DOOR :
287+ case IRON_DOOR :
288+ case TRAP_DOOR :
289+ case IRON_TRAPDOOR :
290+ case FENCE_GATE :
291+ case ACACIA_FENCE_GATE :
292+ case JUNGLE_FENCE_GATE :
293+ case DARK_OAK_FENCE_GATE :
294+ case SPRUCE_FENCE_GATE :
295+ case BIRCH_FENCE_GATE :
296+ case HOPPER :
297+ case DISPENSER :
298+ case DROPPER :
299+ case LEVER :
300+ case WOOD_BUTTON :
301+ case STONE_BUTTON :
302+ case COMMAND :
303+ case ITEM_FRAME :
304+ blockUsable = true ;
305+ break ;
306+ //$CASES-OMITTED$
307+ default :
308+ blockUsable = false ;
309+ }
310+ }
311+
312+ boolean isSneaking = player .isSneaking ();
313+ boolean blockInMain = mainHand .getType ().isBlock () && mainHand .getType () != Material .AIR ;
314+ boolean blockInOff = offHand .getType ().isBlock () && offHand .getType () != Material .AIR ;
315+
316+ if (blockUsable ) { // Special behavior
317+ if (isSneaking ) {
318+ //Skript.info("Is sneaking on usable block!");
319+ if (offHand .getType () != Material .AIR ) return false ;
320+ if (mainHand .getType () != Material .AIR ) return true ;
321+ //Skript.info("Sneak checks didn't pass.");
322+ } else { // When not sneaking, main hand is ALWAYS used
323+ return false ;
324+ }
325+ }
326+
327+ //Skript.info("Check for usable items...");
328+ if (mainUsable ) return false ;
329+ if (offUsable ) return true ;
330+ //Skript.info("No hand has usable item");
331+
332+ // Still not returned?
333+ if (mainHand .getType () != Material .AIR ) return false ;
334+ //Skript.info("Main hand is an item.");
335+ if (offHand .getType () != Material .AIR ) return true ;
336+
337+ //Skript.info("Final return!");
338+ return false ; // Both hands are AIR material!
339+ }
340+
341+ private boolean checkOffHandUse2 (@ Nullable ItemStack mainHand , @ Nullable ItemStack offHand , int clickType , Player player , @ Nullable Block target ) {
190342 boolean mainUsable = false ;
191343 boolean offUsable = false ;
192344
0 commit comments