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 get all armour of living entities #5456

Merged
merged 7 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 54 additions & 34 deletions src/main/java/ch/njol/skript/expressions/ExprArmorSlot.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,69 +18,89 @@
*/
package ch.njol.skript.expressions;

import java.util.Arrays;
import java.util.Locale;
import java.util.stream.Stream;

import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Event;
import org.bukkit.inventory.EntityEquipment;
import org.eclipse.jdt.annotation.Nullable;

import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Keywords;
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.util.slot.EquipmentSlot;
import ch.njol.skript.util.slot.EquipmentSlot.EquipSlot;
import ch.njol.skript.util.slot.Slot;
import ch.njol.util.Kleenean;

/**
* @author Peter Güttinger
*/
@Name("Armour Slot")
@Description("A part of a player's armour, i.e. the boots, leggings, chestplate or helmet.")
@Examples({"set chestplate of the player to a diamond chestplate",
"helmet of player is neither a helmet nor air # player is wearing a block, e.g. from another plugin"})
@Since("1.0")
public class ExprArmorSlot extends SimplePropertyExpression<LivingEntity, Slot> {
@Description("Equipment of living entities, i.e. the boots, leggings, chestplate or helmet.")
@Examples({
"set chestplate of the player to a diamond chestplate",
"helmet of player is neither a helmet nor air # player is wearing a block, e.g. from another plugin"
})
@Keywords({"armor slot", "armor"})
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved
@Since("1.0, INSERT VERSION (Armour)")
public class ExprArmorSlot extends PropertyExpression<LivingEntity, Slot> {

static {
register(ExprArmorSlot.class, Slot.class, "(0¦boot[s]|0¦shoe[s]|1¦leg[ging][s]|2¦chestplate[s]|3¦helm[et][s]) [(item|slot)]", "livingentities");
register(ExprArmorSlot.class, Slot.class, "((:boots|:shoes|leggings:leg[ging]s|chestplate:chestplate[s]|helmet:helmet[s]) [(item|:slot)]|armour:armo[u]r[s])", "livingentities");
}
@SuppressWarnings("null")

@Nullable
private EquipSlot slot;
private boolean explicitSlot;

private final static EquipSlot[] slots = {EquipSlot.BOOTS, EquipSlot.LEGGINGS, EquipSlot.CHESTPLATE, EquipSlot.HELMET};

@SuppressWarnings("null")

@Override
public boolean init(final Expression<?>[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) {
super.init(exprs, matchedPattern, isDelayed, parseResult);
slot = slots[parseResult.mark & 3]; // 3 least significant bits determine armor type
explicitSlot = (parseResult.mark >>> 2) == 1; // User explicitly asked for SLOT, not item
@SuppressWarnings("unchecked")
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
slot = parseResult.hasTag("armour") ? null : EquipSlot.valueOf(parseResult.tags.get(0).toUpperCase(Locale.ENGLISH));
explicitSlot = parseResult.hasTag("slot"); // User explicitly asked for SLOT, not item
setExpr((Expression<? extends LivingEntity>) exprs[0]);
return true;
}

@Override
@Nullable
public Slot convert(final LivingEntity e) {
final EntityEquipment eq = e.getEquipment();
if (eq == null)
return null;
return new EquipmentSlot(eq, slot, explicitSlot);
}


@Override
protected String getPropertyName() {
return "" + slot.name().toLowerCase(Locale.ENGLISH);
protected Slot[] get(Event event, LivingEntity[] source) {
if (slot == null) { // All Armour
return Arrays.stream(source)
.map(LivingEntity::getEquipment)
.flatMap(equipment -> {
if (equipment == null)
return null;
return Stream.of(
new EquipmentSlot(equipment, EquipSlot.HELMET, explicitSlot),
new EquipmentSlot(equipment, EquipSlot.CHESTPLATE, explicitSlot),
new EquipmentSlot(equipment, EquipSlot.LEGGINGS, explicitSlot),
new EquipmentSlot(equipment, EquipSlot.BOOTS, explicitSlot)
);
})
.toArray(Slot[]::new);
}
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved

return get(source, entity -> {
EntityEquipment equipment = entity.getEquipment();
if (equipment == null)
return null;
return new EquipmentSlot(equipment, slot, explicitSlot);
});
}

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


@Override
public String toString(@Nullable Event event, boolean debug) {
return slot == null ? "armour" : slot.name().toLowerCase(Locale.ENGLISH) + " of " + getExpr().toString(event, debug);
}

}
14 changes: 14 additions & 0 deletions src/test/skript/tests/syntaxes/expressions/ExprArmorSlot.sk
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
test "armour slot":
spawn zombie at spawn of world "world":
set boots of event-entity to gold boots
assert boots of event-entity are gold boots with "Gold boots were not applied"
set leggings of event-entity to iron leggings
assert leggings of event-entity are iron leggings with "Iron leggings were not applied"
set chestplate of event-entity to diamond chestplate
assert chestplate of event-entity is diamond chestplate with "Diamond chestplate was not applied"
set helmet of event-entity to dirt block
assert helmet of event-entity is dirt block with "Dirt helmet was not applied"
assert armour of event-entity contains dirt block, diamond chestplate, iron leggings and gold boots with "Armour contents were not correct"
clear armour of event-entity
assert armour of event-entity does not contain dirt block, diamond chestplate, iron leggings and gold boots with "Failed to clear EquipmentSlots"
delete event-entity