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

Minecraft Tags #7127

Merged
merged 30 commits into from
Jan 1, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
74212a1
minecraft tags part 1
sovdeeth Oct 3, 2024
cc91087
tags part 2
sovdeeth Oct 3, 2024
85d3a43
forgot to remove _settag for entity tags too
sovdeeth Oct 3, 2024
6d2f935
all tags of type
sovdeeth Oct 3, 2024
4ccf691
major refactor
sovdeeth Oct 3, 2024
c7cc80a
Add origin filtering
sovdeeth Oct 3, 2024
9e84318
populate omitted namespaces
sovdeeth Oct 3, 2024
a509e46
implement simplify for future use cases
sovdeeth Oct 3, 2024
6ebdf64
Merge branch 'dev/feature' into feature/block-tags
sovdeeth Oct 3, 2024
ed88f9a
all the documentation you could ever want!
sovdeeth Oct 4, 2024
012fe09
Merge branch 'feature/block-tags' of https://github.com/sovdeeth/Skri…
sovdeeth Oct 4, 2024
9b87198
gatekeep gaslight girlboss the paper tags
sovdeeth Oct 4, 2024
fcf4c88
basic tests and fix comparisons
sovdeeth Oct 4, 2024
c19703e
custom tags!
sovdeeth Oct 4, 2024
593e5f4
add ways to turn tag into a string
sovdeeth Oct 4, 2024
fbb5e0d
a few more examples
sovdeeth Oct 5, 2024
a106964
requested changes
sovdeeth Oct 12, 2024
d8a9328
Merge branch 'dev/feature' into feature/block-tags
sovdeeth Oct 13, 2024
f1203b2
plural exprtags and parity between tag toString and toVariableString
sovdeeth Nov 10, 2024
10e0645
Merge branch 'dev/feature' into feature/block-tags
sovdeeth Nov 10, 2024
6cfe138
Merge branch 'dev/feature' into feature/block-tags
Moderocky Nov 12, 2024
cd6e699
Fix over-zealous refactor
sovdeeth Dec 15, 2024
80cf6f6
Merge branch 'dev/feature' into feature/block-tags
sovdeeth Dec 15, 2024
3fc9856
Requested changes
sovdeeth Dec 15, 2024
3daec96
Requested changes
sovdeeth Dec 20, 2024
ae7149b
Merge branch 'dev/feature' into feature/block-tags
Efnilite Dec 27, 2024
a85d420
Update src/main/java/ch/njol/util/Pair.java
sovdeeth Dec 27, 2024
f60090a
Merge branch 'dev/feature' into feature/block-tags
sovdeeth Dec 29, 2024
89f40e3
Update src/main/java/org/skriptlang/skript/bukkit/tags/TagType.java
sovdeeth Dec 29, 2024
ac13b99
Merge branch 'dev/feature' into feature/block-tags
sovdeeth Jan 1, 2025
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
2 changes: 2 additions & 0 deletions src/main/java/ch/njol/skript/Skript.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.skriptlang.skript.bukkit.SkriptMetrics;
import org.skriptlang.skript.bukkit.tags.TagModule;
import org.skriptlang.skript.lang.comparator.Comparator;
import org.skriptlang.skript.lang.comparator.Comparators;
import org.skriptlang.skript.lang.converter.Converter;
Expand Down Expand Up @@ -541,6 +542,7 @@ public void onEnable() {
try {
getAddonInstance().loadClasses("ch.njol.skript",
"conditions", "effects", "events", "expressions", "entity", "sections", "structures");
TagModule.load();
} catch (final Exception e) {
exception(e, "Could not load required .class files: " + e.getLocalizedMessage());
setEnabled(false);
Expand Down
72 changes: 24 additions & 48 deletions src/main/java/ch/njol/util/Pair.java
Original file line number Diff line number Diff line change
@@ -1,39 +1,20 @@
/**
* This file is part of Skript.
*
* Skript is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Skript is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package ch.njol.util;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnknownNullability;

import java.io.Serial;
import java.io.Serializable;
import java.util.Map.Entry;
import java.util.Objects;

import org.jetbrains.annotations.Nullable;

/**
* @author Peter Güttinger
*/
public class Pair<T1, T2> implements Entry<T1, T2>, Cloneable, Serializable {
@Serial
private static final long serialVersionUID = 8296563685697678334L;

@Nullable
protected T1 first;
@Nullable
protected T2 second;

protected @UnknownNullability T1 first;
protected @UnknownNullability T2 second;

public Pair() {
first = null;
Expand All @@ -45,22 +26,20 @@ public Pair(final @Nullable T1 first, final @Nullable T2 second) {
this.second = second;
}

public Pair(final Entry<T1, T2> e) {
public Pair(final @NotNull Entry<T1, T2> e) {
this.first = e.getKey();
sovdeeth marked this conversation as resolved.
Show resolved Hide resolved
this.second = e.getValue();
}

@Nullable
public T1 getFirst() {

public @UnknownNullability T1 getFirst() {
return first;
}

public void setFirst(final @Nullable T1 first) {
this.first = first;
}

@Nullable
public T2 getSecond() {

public @UnknownNullability T2 getSecond() {
return second;
}

Expand All @@ -73,23 +52,22 @@ public void setSecond(final @Nullable T2 second) {
*/
@Override
public String toString() {
return "" + first + "," + second;
return first + "," + second;
}

/**
* Checks for equality with Entries to match {@link #hashCode()}
*/
@Override
public final boolean equals(final @Nullable Object obj) {
public final boolean equals(@Nullable Object obj) {
if (obj == this)
return true;
if (!(obj instanceof Entry))
if (!(obj instanceof Entry<?, ?> entry))
return false;
final Entry<?, ?> other = (Entry<?, ?>) obj;
final T1 first = this.first;
final T2 second = this.second;
return (first == null ? other.getKey() == null : first.equals(other.getKey())) &&
sovdeeth marked this conversation as resolved.
Show resolved Hide resolved
(second == null ? other.getValue() == null : second.equals(other.getValue()));
return (first == null ? entry.getKey() == null : first.equals(entry.getKey())) &&
(second == null ? entry.getValue() == null : second.equals(entry.getValue()));
}

/**
Expand All @@ -101,21 +79,19 @@ public final int hashCode() {
}

@Override
@Nullable
public T1 getKey() {
public @UnknownNullability T1 getKey() {
return first;
}

@Override
@Nullable
public T2 getValue() {
public @UnknownNullability T2 getValue() {
return second;
}

@Override
@Nullable
public T2 setValue(final @Nullable T2 value) {
final T2 old = second;

public @UnknownNullability T2 setValue(@Nullable T2 value) {
sovdeeth marked this conversation as resolved.
Show resolved Hide resolved
T2 old = second;
second = value;
return old;
}
Expand Down
90 changes: 90 additions & 0 deletions src/main/java/org/skriptlang/skript/bukkit/tags/CondIsTagged.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package org.skriptlang.skript.bukkit.tags;

import ch.njol.skript.aliases.ItemType;
import ch.njol.skript.bukkitutil.EntityUtils;
import ch.njol.skript.conditions.base.PropertyCondition;
import ch.njol.skript.entity.EntityData;
import ch.njol.skript.lang.Condition;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.util.slot.Slot;
import ch.njol.util.Kleenean;
import org.bukkit.Keyed;
import org.bukkit.Tag;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Entity;
import org.bukkit.event.Event;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;

public class CondIsTagged extends Condition {
sovdeeth marked this conversation as resolved.
Show resolved Hide resolved

static {
PropertyCondition.register(CondIsTagged.class, PropertyCondition.PropertyType.BE,
"tagged (as|with) %minecrafttags%",
"itemtypes/entities/entitydatas");
}

private Expression<Tag<Keyed>> tags;
private Expression<?> elements;

@Override
public boolean init(Expression<?>[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
this.elements = expressions[0];
//noinspection unchecked
this.tags = (Expression<Tag<Keyed>>) expressions[1];
setNegated(matchedPattern == 1);
return true;
}

@Override
public boolean check(Event event) {
Tag<Keyed>[] tags = this.tags.getArray(event);
if (tags.length == 0)
return isNegated();
boolean and = this.tags.getAnd();
return elements.check(event, element -> {
Keyed value = null;
if (element instanceof Entity entity) {
value = entity.getType();
} if (element instanceof EntityData<?> data) {
value = EntityUtils.toBukkitEntityType(data);
} else if (element instanceof ItemType itemType) {
value = itemType.getMaterial();
} else if (element instanceof ItemStack itemStack) {
sovdeeth marked this conversation as resolved.
Show resolved Hide resolved
value = itemStack.getType();
} else if (element instanceof Slot slot) {
ItemStack stack = slot.getItem();
if (stack == null)
return false;
value = stack.getType();
} else if (element instanceof Block block) {
value = block.getType();
} else if (element instanceof BlockData data) {
value = data.getMaterial();
}

if (value == null)
return false;

for (Tag<Keyed> tag : tags) {
if (tag.isTagged(value)) {
if (!and)
return true;
} else if (and) {
return false;
}
}
return and;
}, isNegated());
}

@Override
public String toString(@Nullable Event event, boolean debug) {
String plural = elements.isSingle() ? "is" : "are";
String negated = isNegated() ? " not" : "";
return elements.toString(event, debug) + " " + plural + negated + " tagged as " + tags.toString(event, debug);
}

}
106 changes: 106 additions & 0 deletions src/main/java/org/skriptlang/skript/bukkit/tags/ExprTag.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package org.skriptlang.skript.bukkit.tags;

import ch.njol.skript.Skript;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.SkriptParser;
import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.util.Kleenean;
import org.bukkit.Bukkit;
import org.bukkit.Keyed;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Tag;
import org.bukkit.entity.EntityType;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ExprTag extends SimpleExpression<Tag> {
sovdeeth marked this conversation as resolved.
Show resolved Hide resolved

private record RegistryInfo(String registry, String pattern, Class<? extends Keyed> type) {}

// Fluid and GameEvent registries also exist, but are not useful at this time.
// Any new types added here must be handled in CondIsTagged
private static final List<RegistryInfo> REGISTRIES = new ArrayList<>(List.of(
new RegistryInfo(Tag.REGISTRY_ITEMS, "item", Material.class),
new RegistryInfo(Tag.REGISTRY_BLOCKS, "block", Material.class),
new RegistryInfo(Tag.REGISTRY_ENTITY_TYPES, "entity [type]", EntityType.class)
));

static {
// build pattern
StringBuilder registriesPattern = new StringBuilder("[");
int numRegistries = REGISTRIES.size();
for (int i = 0; i < numRegistries; i++) {
registriesPattern.append(i + 1).append(":").append(REGISTRIES.get(i).pattern());
if (i + 1 != numRegistries)
registriesPattern.append("|");
}
registriesPattern.append("]");

Skript.registerExpression(ExprTag.class, Tag.class, ExpressionType.COMBINED, "[minecraft] " + registriesPattern + " tag %string%");
}

Expression<String> name;
int type;

@Override
public boolean init(Expression<?>[] expressions, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) {
//noinspection unchecked
name = (Expression<String>) expressions[0];
type = parseResult.mark - 1;
return true;
}

@Override
protected Tag<?> @Nullable [] get(Event event) {
String name = this.name.getSingle(event);
if (name == null)
return null;

NamespacedKey key = NamespacedKey.fromString(name);
if (key == null)
return null;


List<RegistryInfo> registries;
if (type == -1) {
registries = REGISTRIES;
} else if (type < REGISTRIES.size()) {
registries = Collections.singletonList(REGISTRIES.get(type));
} else {
return null;
}

Tag<?> tag;
for (RegistryInfo registry : registries) {
tag = Bukkit.getTag(registry.registry(), key, registry.type());
if (tag != null)
return new Tag[]{tag};
}

return null;
}

@Override
public boolean isSingle() {
return true;
}

@Override
@SuppressWarnings("rawtypes")
public Class<? extends Tag> getReturnType() {
return Tag.class;
}

@Override
public String toString(@Nullable Event event, boolean debug) {
String registry = type == -1 ? "" : REGISTRIES.get(type).pattern();
return "minecraft " + registry + "tag " + name.toString(event, debug);
}

}
Loading
Loading