From ccd3952076072a6a17059260be5103d9d0ffecdb Mon Sep 17 00:00:00 2001 From: Xenmai Date: Fri, 31 Mar 2017 07:27:09 +0200 Subject: [PATCH] Right Clicks Air Fixes (#9) * Fixed right clicks air contexts Also added player.block_on_cursor[#] tag. * Default Distance for the Previous Commit %.0 when on creative, 4.0 otherwise. * Documentation Improvements * Player Clicks Block Contexts Also moved a check to an Utilities file. * Fix Formatting Flaw --- .../PlayerRightClicksBlockScriptEvent.java | 41 ++++++++++++++----- .../tags/objects/PlayerTag.java | 18 ++++++-- .../denizen2sponge/utilities/Utilities.java | 11 +++++ 3 files changed, 55 insertions(+), 15 deletions(-) create mode 100644 src/main/java/com/denizenscript/denizen2sponge/utilities/Utilities.java diff --git a/src/main/java/com/denizenscript/denizen2sponge/events/player/PlayerRightClicksBlockScriptEvent.java b/src/main/java/com/denizenscript/denizen2sponge/events/player/PlayerRightClicksBlockScriptEvent.java index 337f9b2..fa3b6a1 100644 --- a/src/main/java/com/denizenscript/denizen2sponge/events/player/PlayerRightClicksBlockScriptEvent.java +++ b/src/main/java/com/denizenscript/denizen2sponge/events/player/PlayerRightClicksBlockScriptEvent.java @@ -8,11 +8,16 @@ import com.denizenscript.denizen2sponge.events.D2SpongeEventHelper; import com.denizenscript.denizen2sponge.tags.objects.LocationTag; import com.denizenscript.denizen2sponge.tags.objects.PlayerTag; +import com.denizenscript.denizen2sponge.utilities.Utilities; import org.spongepowered.api.Sponge; import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.entity.living.player.gamemode.GameModes; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.block.InteractBlockEvent; import org.spongepowered.api.event.filter.cause.Root; +import org.spongepowered.api.util.blockray.BlockRay; +import org.spongepowered.api.util.blockray.BlockRayHit; +import org.spongepowered.api.world.World; import java.util.HashMap; @@ -22,7 +27,7 @@ public class PlayerRightClicksBlockScriptEvent extends ScriptEvent { // @Events // player right clicks block // - // @Updated 2017/03/28 + // @Updated 2017/03/30 // // @Cancellable true // @@ -36,7 +41,9 @@ public class PlayerRightClicksBlockScriptEvent extends ScriptEvent { // @Context // player (PlayerTag) returns the player that did the right clicking. // location (LocationTag) returns the location of the block that was right clicked. - // intersection (LocationTag) returns the exact point of intersection on the block where it was clicked (When available). + // precise_location (LocationTag) returns the exact point that was right clicked in the world. + // intersection_point (LocationTag) returns the exact point of intersection relative to the block (When available). + // impact_normal (LocationTag) returns the normal vector from the side of the block that was right clicked. // hand (TextTag) returns the hand type that triggered the event. // // @Determinations @@ -63,7 +70,11 @@ public boolean matches(ScriptEventData data) { public LocationTag location; - public LocationTag intersection; + public LocationTag precise_location; + + public LocationTag intersection_point; + + public LocationTag impact_normal; public TextTag hand; @@ -74,7 +85,9 @@ public HashMap getDefinitions(ScriptEventData data) { HashMap defs = super.getDefinitions(data); defs.put("player", player); defs.put("location", location); - defs.put("intersection", intersection); + defs.put("precise_location", precise_location); + defs.put("intersection_point", intersection_point); + defs.put("impact_normal", impact_normal); defs.put("hand", hand); return defs; } @@ -94,14 +107,20 @@ public void onRightClickBlock(InteractBlockEvent.Secondary evt, @Root Player pla PlayerRightClicksBlockScriptEvent event = (PlayerRightClicksBlockScriptEvent) clone(); event.internal = evt; event.player = new PlayerTag(player); - if (!evt.getTargetBlock().getLocation().isPresent()) { - // Sponge is dumb! - return; + if (evt.getTargetBlock().getLocation().isPresent()) { + event.location = new LocationTag(evt.getTargetBlock().getLocation().get()); + event.precise_location = new LocationTag(evt.getInteractionPoint().get().add(evt.getTargetBlock().getPosition().toDouble())); + event.precise_location.getInternal().world = event.location.getInternal().world; + event.intersection_point = new LocationTag(evt.getInteractionPoint().get()); + event.impact_normal = new LocationTag(evt.getTargetSide().asOffset()); } - event.location = new LocationTag(evt.getTargetBlock().getLocation().get()); - if (evt.getInteractionPoint().isPresent()) { - event.intersection = new LocationTag(evt.getInteractionPoint().get()); - event.intersection.getInternal().world = event.location.getInternal().world; + else { + BlockRayHit brh = BlockRay.from(player).distanceLimit(Utilities.getHandReach(player)).build().end().get(); + event.location = new LocationTag(brh.getLocation()); + event.precise_location = new LocationTag(brh.getPosition()); + event.precise_location.getInternal().world = event.location.getInternal().world; + event.intersection_point = new LocationTag(brh.getPosition().sub(brh.getBlockPosition().toDouble())); + event.impact_normal = new LocationTag(0, 0, 0); } event.hand = new TextTag(CoreUtilities.toLowerCase(evt.getHandType().toString())); event.cancelled = evt.isCancelled(); diff --git a/src/main/java/com/denizenscript/denizen2sponge/tags/objects/PlayerTag.java b/src/main/java/com/denizenscript/denizen2sponge/tags/objects/PlayerTag.java index a3e8920..ecf1cb8 100644 --- a/src/main/java/com/denizenscript/denizen2sponge/tags/objects/PlayerTag.java +++ b/src/main/java/com/denizenscript/denizen2sponge/tags/objects/PlayerTag.java @@ -7,12 +7,11 @@ import com.denizenscript.denizen2core.tags.objects.TextTag; import com.denizenscript.denizen2core.utilities.Action; import com.denizenscript.denizen2core.utilities.Function2; +import com.denizenscript.denizen2sponge.utilities.Utilities; import org.spongepowered.api.Sponge; -import org.spongepowered.api.data.type.HandTypes; import org.spongepowered.api.entity.living.player.Player; -import org.spongepowered.api.item.ItemType; -import org.spongepowered.api.item.ItemTypes; -import org.spongepowered.api.item.inventory.ItemStack; +import org.spongepowered.api.entity.living.player.gamemode.GameModes; +import org.spongepowered.api.util.blockray.BlockRay; import java.util.HashMap; import java.util.Optional; @@ -81,6 +80,17 @@ public Player getInternal() { // @Returns the gamemode of the player. // --> handlers.put("gamemode", (dat, obj) -> new TextTag(((PlayerTag) obj).internal.gameMode().get().toString())); + // <--[tag] + // @Name PlayerTag.block_on_cursor[] + // @Updated 2017/03/30 + // @Group Current Information + // @ReturnType LocationTag + // @Returns the block the player has their cursor on, up to a maximum distance. If no distance is specified, the default hand-reach distance is used. + // --> + handlers.put("block_on_cursor", (dat, obj) -> new LocationTag(BlockRay.from(((PlayerTag) obj).internal) + .stopFilter(BlockRay.continueAfterFilter(BlockRay.onlyAirFilter(), 1)) + .distanceLimit(dat.hasNextModifier() ? NumberTag.getFor(dat.error, dat.getNextModifier()).getInternal() : + (Utilities.getHandReach(((PlayerTag) obj).internal))).build().end().get().getLocation())); } public static PlayerTag getFor(Action error, String text) { diff --git a/src/main/java/com/denizenscript/denizen2sponge/utilities/Utilities.java b/src/main/java/com/denizenscript/denizen2sponge/utilities/Utilities.java new file mode 100644 index 0000000..cd3aab1 --- /dev/null +++ b/src/main/java/com/denizenscript/denizen2sponge/utilities/Utilities.java @@ -0,0 +1,11 @@ +package com.denizenscript.denizen2sponge.utilities; + +import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.entity.living.player.gamemode.GameModes; + +public class Utilities { + + public static double getHandReach(Player player) { + return player.gameMode().equals(GameModes.CREATIVE) ? 5.0 : 4.0; + } +}