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
16 changes: 16 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 @@ -122,6 +122,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.PlayerPickupItemEvent;
Expand Down Expand Up @@ -1422,5 +1423,20 @@ public Egg get(PlayerEggThrowEvent event) {
return event.getEgg();
}
}, 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);
}
}
112 changes: 80 additions & 32 deletions src/main/java/ch/njol/skript/expressions/ExprHotbarSlot.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,69 +20,117 @@

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.Skript;
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.ExpressionType;
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 slot number of the currently selected hotbar slot."})
@Examples({"message \"%player's current hotbar slot%\"",
"set player's selected hotbar slot to slot 4 of player"})
@Description({
"The slot number of the currently selected hotbar slot.",
"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",
"",
"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");
Skript.registerExpression(ExprHotbarSlot.class, Slot.class, ExpressionType.PROPERTY,
"[the] [([current:currently] selected|current:current)] hotbar slot [of %players%]",
"%players%'[s] [([current:currently] selected|current:current)] hotbar slot");
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved
}

@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, 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);
}

}