Skip to content
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

Add time states for PlayerItemHeldEvent and hotbar slot #5271

Merged
merged 12 commits into from
Jun 27, 2023
Merged
17 changes: 17 additions & 0 deletions src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
import org.bukkit.event.player.PlayerItemBreakEvent;
import org.bukkit.event.player.PlayerItemConsumeEvent;
import org.bukkit.event.player.PlayerItemDamageEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerItemMendEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerPickupArrowEvent;
Expand Down Expand Up @@ -1650,6 +1651,22 @@ public Location get(LootGenerateEvent event) {
}, EventValues.TIME_NOW);
}

// PlayerItemHeldEvent
EventValues.registerEventValue(PlayerItemHeldEvent.class, Slot.class, new Getter<Slot, PlayerItemHeldEvent>() {
@Override
@Nullable
public Slot get(PlayerItemHeldEvent event) {
return new InventorySlot(event.getPlayer().getInventory(), event.getNewSlot());
}
}, EventValues.TIME_NOW);
EventValues.registerEventValue(PlayerItemHeldEvent.class, Slot.class, new Getter<Slot, PlayerItemHeldEvent>() {
@Override
@Nullable
public Slot get(PlayerItemHeldEvent event) {
return new InventorySlot(event.getPlayer().getInventory(), event.getPreviousSlot());
}
}, EventValues.TIME_PAST);

// PlayerPickupArrowEvent
// This event value is restricted to MC 1.14+ due to an API change which has the return type changed
// which throws a NoSuchMethodError if used in a 1.13 server.
Expand Down
112 changes: 79 additions & 33 deletions src/main/java/ch/njol/skript/expressions/ExprHotbarSlot.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,70 +20,116 @@

import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.inventory.PlayerInventory;
import org.eclipse.jdt.annotation.Nullable;

import ch.njol.skript.classes.Changer;
import ch.njol.skript.classes.Changer.ChangeMode;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.expressions.base.SimplePropertyExpression;
import ch.njol.skript.expressions.base.PropertyExpression;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.registrations.EventValues;
import ch.njol.skript.util.Getter;
import ch.njol.skript.util.slot.InventorySlot;
import ch.njol.skript.util.slot.Slot;
import ch.njol.util.Kleenean;

@Name("Hotbar Slot")
@Description({"The currently selected hotbar <a href='./classes.html#slot'>slot</a>. To retrieve its number use <a href='#ExprSlotIndex'>Slot Index</a> expression."})
@Examples({"message \"%player's current hotbar slot%\"",
"set player's selected hotbar slot to slot 4 of player",
"send \"index of player's current hotbar slot = 1\" # second slot from the left"})
@Description({
"The currently selected hotbar <a href='./classes.html#slot'>slot</a>.",
"To retrieve its number use <a href='#ExprSlotIndex'>Slot Index</a> expression.",
"Use future and past tense to grab the previous slot in an item change event, see example."
})
@Examples({
"message \"%player's current hotbar slot%\"",
"set player's selected hotbar slot to slot 4 of player",
"",
"send \"index of player's current hotbar slot = 1\" # second slot from the left",
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved
"",
"on item held change:",
"\tif the selected hotbar slot was a diamond:",
"\t\tset the currently selected hotbar slot to slot 5 of player"
})
@Since("2.2-dev36")
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved
public class ExprHotbarSlot extends SimplePropertyExpression<Player, Slot> {
public class ExprHotbarSlot extends PropertyExpression<Player, Slot> {

static {
register(ExprHotbarSlot.class, Slot.class, "[([currently] selected|current)] hotbar slot", "players");
registerDefault(ExprHotbarSlot.class, Slot.class, "[the] [([current:currently] selected|current:current)] hotbar slot[s]", "players");
}

@Override
@Nullable
public Slot convert(Player p) {
PlayerInventory invi = p.getInventory();
assert invi != null;
return new InventorySlot(invi, invi.getHeldItemSlot());
}


// This exists because time states should not register when the 'currently' tag of the syntax is present.
private boolean current;

@Override
protected String getPropertyName() {
return "hotbar slot";
@SuppressWarnings("unchecked")
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
setExpr((Expression<? extends Player>) exprs[0]);
current = parseResult.hasTag("current");
return true;
}

@Override
public Class<? extends Slot> getReturnType() {
return Slot.class;
protected Slot[] get(Event event, Player[] source) {
return get(source, new Getter<Slot, Player>() {
@Override
@Nullable
public Slot get(Player player) {
int time = getTime();
PlayerInventory inventory = player.getInventory();
if (event instanceof PlayerItemHeldEvent && time != EventValues.TIME_NOW) {
PlayerItemHeldEvent switchEvent = (PlayerItemHeldEvent) event;
if (time == EventValues.TIME_FUTURE)
return new InventorySlot(inventory, switchEvent.getNewSlot());
if (time == EventValues.TIME_PAST)
return new InventorySlot(inventory, switchEvent.getPreviousSlot());
}
return new InventorySlot(inventory, inventory.getHeldItemSlot());
}
});
}

@Override
@Nullable
public Class<?>[] acceptChange(Changer.ChangeMode mode) {
if (mode == Changer.ChangeMode.SET)
public Class<?>[] acceptChange(ChangeMode mode) {
if (mode == ChangeMode.SET)
return new Class[] {Slot.class};
return null;
}

@Override
public void change(Event e, @Nullable Object[] delta, Changer.ChangeMode mode) {
public void change(Event event, @Nullable Object[] delta, ChangeMode mode) {
assert delta != null;
Slot slot = (Slot) delta[0];
if (!(slot instanceof InventorySlot))
return; // Only inventory slots can be hotbar slots

int index = ((InventorySlot) slot).getIndex();
if (index > 8) // Only slots in hotbar can be current hotbar slot
return;

for (Player p : getExpr().getArray(e)) {
p.getInventory().setHeldItemSlot(index);
}

for (Player player : getExpr().getArray(event))
player.getInventory().setHeldItemSlot(index);
}


@Override
public boolean setTime(int time) {
if (current)
return super.setTime(time);
return super.setTime(time, getExpr(), PlayerItemHeldEvent.class);
}

@Override
public Class<? extends Slot> getReturnType() {
return Slot.class;
}

@Override
public String toString(@Nullable Event event, boolean debug) {
return "hotbar slot of " + getExpr().toString(event, debug);
}

}