-
-
Notifications
You must be signed in to change notification settings - Fork 368
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simplify offhand swapping #5772
base: dev/feature
Are you sure you want to change the base?
Changes from all commits
66add57
f4029c6
c0488ce
f295818
6c3dd34
cc9f6ef
9450c9d
66b8670
c96a4b5
9131e16
80395b4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,18 +18,6 @@ | |
*/ | ||
package ch.njol.skript.expressions; | ||
|
||
import org.bukkit.entity.LivingEntity; | ||
import org.bukkit.entity.Player; | ||
import org.bukkit.event.Event; | ||
import org.bukkit.event.player.PlayerBucketEmptyEvent; | ||
import org.bukkit.event.player.PlayerBucketEvent; | ||
import org.bukkit.event.player.PlayerBucketFillEvent; | ||
import org.bukkit.event.player.PlayerItemHeldEvent; | ||
import org.bukkit.inventory.EntityEquipment; | ||
import org.bukkit.inventory.ItemStack; | ||
import org.bukkit.inventory.PlayerInventory; | ||
import org.eclipse.jdt.annotation.Nullable; | ||
|
||
import ch.njol.skript.Skript; | ||
import ch.njol.skript.doc.Description; | ||
import ch.njol.skript.doc.Examples; | ||
|
@@ -41,79 +29,123 @@ | |
import ch.njol.skript.lang.ExpressionType; | ||
import ch.njol.skript.lang.SkriptParser.ParseResult; | ||
import ch.njol.skript.registrations.Classes; | ||
import ch.njol.skript.registrations.EventValues; | ||
import ch.njol.skript.util.Getter; | ||
import ch.njol.skript.util.slot.CursorSlot; | ||
import ch.njol.skript.util.slot.EquipmentSlot; | ||
import ch.njol.skript.util.slot.InventorySlot; | ||
import ch.njol.skript.util.slot.Slot; | ||
import ch.njol.util.Kleenean; | ||
|
||
/** | ||
* @author Peter Güttinger | ||
*/ | ||
@Name("Tool") | ||
import org.bukkit.entity.LivingEntity; | ||
import org.bukkit.entity.Player; | ||
import org.bukkit.event.Event; | ||
import org.bukkit.event.inventory.ClickType; | ||
import org.bukkit.event.inventory.InventoryClickEvent; | ||
import org.bukkit.event.player.PlayerBucketEmptyEvent; | ||
import org.bukkit.event.player.PlayerBucketEvent; | ||
import org.bukkit.event.player.PlayerBucketFillEvent; | ||
import org.bukkit.event.player.PlayerItemHeldEvent; | ||
import org.bukkit.inventory.EntityEquipment; | ||
import org.bukkit.inventory.ItemStack; | ||
import org.bukkit.inventory.PlayerInventory; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
@Name("Tool/Offhand") | ||
@Description("The item an entity is holding in their main or off hand.") | ||
@Examples({"player's tool is a pickaxe", | ||
@Examples({ | ||
"player's tool is a pickaxe", | ||
"player's off hand tool is a shield", | ||
"set tool of all players to a diamond sword", | ||
"set offhand tool of target entity to a bow"}) | ||
@Since("1.0") | ||
"set offhand tool of target entity to a bow" | ||
}) | ||
@Since("1.0, 2.2-dev37 (offhand)") | ||
public class ExprTool extends PropertyExpression<LivingEntity, Slot> { | ||
|
||
static { | ||
Skript.registerExpression(ExprTool.class, Slot.class, ExpressionType.PROPERTY, | ||
"[the] ((tool|held item|weapon)|1¦(off[ ]hand (tool|item))) [of %livingentities%]", | ||
"%livingentities%'[s] ((tool|held item|weapon)|1¦(off[ ]hand (tool|item)))"); | ||
"[the] ((tool|held item|weapon)|offhand:(off[ ]hand (tool|weapon|[held] item))) [of %livingentities%]", | ||
"%livingentities%'[s] ((tool|held item|weapon)|offhand:(off[ ]hand (tool|weapon|[held] item)))" | ||
); | ||
} | ||
|
||
private boolean offHand; | ||
|
||
@SuppressWarnings({"unchecked", "null"}) | ||
@Override | ||
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parser) { | ||
@SuppressWarnings("unchecked") | ||
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { | ||
setExpr((Expression<LivingEntity>) exprs[0]); | ||
offHand = parser.mark == 1; | ||
offHand = parseResult.hasTag("offhand"); | ||
return true; | ||
} | ||
|
||
@Override | ||
protected Slot[] get(final Event e, final LivingEntity[] source) { | ||
final boolean delayed = Delay.isDelayed(e); | ||
protected Slot[] get(Event event, LivingEntity[] source) { | ||
boolean delayed = Delay.isDelayed(event); | ||
return get(source, new Getter<Slot, LivingEntity>() { | ||
@Override | ||
@Nullable | ||
public Slot get(final LivingEntity ent) { | ||
public Slot get(LivingEntity entity) { | ||
if (!delayed) { | ||
if (!offHand && e instanceof PlayerItemHeldEvent && ((PlayerItemHeldEvent) e).getPlayer() == ent) { | ||
final PlayerInventory i = ((PlayerItemHeldEvent) e).getPlayer().getInventory(); | ||
return new InventorySlot(i, getTime() >= 0 ? ((PlayerItemHeldEvent) e).getNewSlot() : ((PlayerItemHeldEvent) e).getPreviousSlot()); | ||
} else if (e instanceof PlayerBucketEvent && ((PlayerBucketEvent) e).getPlayer() == ent) { | ||
final PlayerInventory i = ((PlayerBucketEvent) e).getPlayer().getInventory(); | ||
boolean isOffHand = ((PlayerBucketEvent) e).getHand() == org.bukkit.inventory.EquipmentSlot.OFF_HAND || offHand; | ||
return new InventorySlot(i, isOffHand ? EquipmentSlot.EquipSlot.OFF_HAND.slotNumber | ||
: ((PlayerBucketEvent) e).getPlayer().getInventory().getHeldItemSlot()) { | ||
if (offHand && event instanceof InventoryClickEvent inventoryClickEvent && inventoryClickEvent.getWhoClicked().equals(entity) && getTime() == 1) { | ||
// When a player uses a number key to swap an item from hotbar to offhand. This simplifies the process with future states. | ||
if (inventoryClickEvent.getClick() == ClickType.NUMBER_KEY && inventoryClickEvent.getSlot() == EquipmentSlot.EquipSlot.OFF_HAND.slotNumber) { | ||
PlayerInventory inventory = inventoryClickEvent.getWhoClicked().getInventory(); | ||
return new InventorySlot(inventory, inventoryClickEvent.getHotbarButton()); | ||
sovdeeth marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} else if (inventoryClickEvent.getClick() == ClickType.SWAP_OFFHAND) { | ||
PlayerInventory inventory = inventoryClickEvent.getWhoClicked().getInventory(); | ||
return new InventorySlot(inventory, inventoryClickEvent.getSlot()); | ||
} else if (inventoryClickEvent.getSlot() == EquipmentSlot.EquipSlot.OFF_HAND.slotNumber) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about the case where another slot is being double clicked to collect_to_cursor, which pulls from the offhand? Currently it just says null for the future offhand tool. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't believe Spigot/Minecraft has an API for determining the slots a double click is pulling from. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah you'd have to manually write checks for this (from my experience with skript-gui) |
||
switch (inventoryClickEvent.getAction()) { | ||
case NOTHING: // When you double click to collect to cursor, it's not COLLECT_TO_CURSOR... | ||
case PICKUP_ALL: | ||
case PICKUP_HALF: | ||
case PICKUP_ONE: | ||
case PICKUP_SOME: | ||
return new InventorySlot(inventoryClickEvent.getClickedInventory(), inventoryClickEvent.getSlot()); | ||
case PLACE_ALL: | ||
case PLACE_ONE: | ||
case PLACE_SOME: | ||
case SWAP_WITH_CURSOR: | ||
return new CursorSlot((Player) inventoryClickEvent.getWhoClicked(), inventoryClickEvent.getCurrentItem()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be returning the value of the future offhand slot. Right now it's returning the future cursor slot. |
||
default: | ||
break; | ||
} | ||
} | ||
return null; | ||
} else if (!offHand && event instanceof PlayerItemHeldEvent playerItemHeldEvent && playerItemHeldEvent.getPlayer() == entity) { | ||
PlayerInventory inventory = playerItemHeldEvent.getPlayer().getInventory(); | ||
return new InventorySlot(inventory, getTime() >= EventValues.TIME_NOW ? playerItemHeldEvent.getNewSlot() : playerItemHeldEvent.getPreviousSlot()); | ||
} else if (event instanceof PlayerBucketEvent playerBucketEvent && playerBucketEvent.getPlayer() == entity) { | ||
PlayerInventory inventory = playerBucketEvent.getPlayer().getInventory(); | ||
boolean isOffHand = playerBucketEvent.getHand() == org.bukkit.inventory.EquipmentSlot.OFF_HAND || offHand; | ||
return new InventorySlot(inventory, isOffHand ? EquipmentSlot.EquipSlot.OFF_HAND.slotNumber | ||
: playerBucketEvent.getPlayer().getInventory().getHeldItemSlot()) { | ||
|
||
@Override | ||
@Nullable | ||
public ItemStack getItem() { | ||
return getTime() <= 0 ? super.getItem() : ((PlayerBucketEvent) e).getItemStack(); | ||
return getTime() <= EventValues.TIME_NOW ? super.getItem() : playerBucketEvent.getItemStack(); | ||
} | ||
|
||
@Override | ||
public void setItem(final @Nullable ItemStack item) { | ||
if (getTime() >= 0) { | ||
((PlayerBucketEvent) e).setItemStack(item); | ||
public void setItem(@Nullable ItemStack item) { | ||
if (getTime() >= EventValues.TIME_NOW) { | ||
playerBucketEvent.setItemStack(item); | ||
} else { | ||
super.setItem(item); | ||
} | ||
} | ||
}; | ||
} | ||
} | ||
final EntityEquipment eq = ent.getEquipment(); | ||
if (eq == null) | ||
EntityEquipment equipment = entity.getEquipment(); | ||
if (equipment == null) | ||
return null; | ||
return new EquipmentSlot(eq, offHand ? EquipmentSlot.EquipSlot.OFF_HAND : EquipmentSlot.EquipSlot.TOOL) { | ||
return new EquipmentSlot(equipment, offHand ? EquipmentSlot.EquipSlot.OFF_HAND : EquipmentSlot.EquipSlot.TOOL) { | ||
@Override | ||
public String toString(@Nullable Event event, boolean debug) { | ||
String time = getTime() == 1 ? "future " : getTime() == -1 ? "former " : ""; | ||
String time = getTime() == 1 ? "future " : getTime() == EventValues.TIME_PAST ? "former " : ""; | ||
String hand = offHand ? "off hand" : ""; | ||
String item = Classes.toString(getItem()); | ||
return String.format("%s %s tool of %s", time, hand, item); | ||
|
@@ -124,20 +156,19 @@ public String toString(@Nullable Event event, boolean debug) { | |
} | ||
|
||
@Override | ||
public Class<Slot> getReturnType() { | ||
return Slot.class; | ||
public boolean setTime(int time) { | ||
return super.setTime(time, PlayerItemHeldEvent.class, PlayerBucketFillEvent.class, PlayerBucketEmptyEvent.class, InventoryClickEvent.class); | ||
} | ||
|
||
@Override | ||
public String toString(final @Nullable Event e, final boolean debug) { | ||
String hand = offHand ? "off hand" : ""; | ||
return String.format("%s tool of %s", hand, getExpr().toString(e, debug)); | ||
public Class<Slot> getReturnType() { | ||
return Slot.class; | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
@Override | ||
public boolean setTime(final int time) { | ||
return super.setTime(time, getExpr(), PlayerItemHeldEvent.class, PlayerBucketFillEvent.class, PlayerBucketEmptyEvent.class); | ||
public String toString(@Nullable Event event, boolean debug) { | ||
String hand = offHand ? "off hand" : ""; | ||
return String.format("%s tool of %s", hand, getExpr().toString(event, debug)); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove license