Skip to content

Commit

Permalink
vanilla_tag stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Apr 13, 2021
1 parent e8883db commit 557f6dc
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 15 deletions.
Expand Up @@ -7,6 +7,7 @@
import com.denizenscript.denizen.scripts.containers.core.InventoryScriptHelper;
import com.denizenscript.denizen.scripts.containers.core.ItemScriptHelper;
import com.denizenscript.denizen.tags.BukkitTagContext;
import com.denizenscript.denizen.utilities.VanillaTagHelper;
import com.denizenscript.denizen.utilities.implementation.BukkitScriptEntryData;
import com.denizenscript.denizencore.flags.AbstractFlagTracker;
import com.denizenscript.denizencore.objects.core.ScriptTag;
Expand Down Expand Up @@ -43,12 +44,14 @@ public abstract class BukkitScriptEvent extends ScriptEvent {
//
// "<block>" usually indicates that a MaterialTag will be matched against.
// This means you can specify any valid block material name, like "stone" or "air".
// You can also use "vanilla_tagged:<vanilla_tag_name>".
// You can also use "block" or "material" as catch-alls.
//
// "<item>" or similar expects of course an ItemTag.
// You can use any valid item material type like "stick", or the name of an item script, or "item" as a catch-all, or "potion" for any potion item.
// Items can also be used with an "item_flagged" secondary prefix, so for an event that has "with:<item>", you can also do "with:item_flagged:<flag name>".
// For item matchers that aren't switches, this works similarly, like "on player consumes item_flagged:myflag:" (note that this is not a switch).
// You can also use "vanilla_tagged:<vanilla_tag_name>".
//
// "<entity>", "<projectile>", "<vehicle>", etc. are examples of where an EntityTag will be expected.
// You can generally specify any potentially relevant entity type, such as "creeper" under "<entity>", or "arrow" for "<projectile>",
Expand Down Expand Up @@ -255,7 +258,7 @@ public boolean couldMatchVehicle(String text) {
}

public boolean couldMatchBlockOrItem(String text) {
if (text.equals("block") || text.equals("material") || text.equals("item") || text.equals("potion") || text.startsWith("item_flagged:")) {
if (text.equals("block") || text.equals("material") || text.equals("item") || text.equals("potion") || text.startsWith("item_flagged:") || text.startsWith("vanilla_tagged:")) {
return true;
}
if (MaterialTag.matches(text)) {
Expand Down Expand Up @@ -285,7 +288,7 @@ public boolean couldMatchBlockOrItem(String text) {
}

public boolean couldMatchBlock(String text) {
if (text.equals("block") || text.equals("material")) {
if (text.equals("block") || text.equals("material") || text.startsWith("vanilla_tagged:")) {
return true;
}
if (text.equals("item")) {
Expand Down Expand Up @@ -313,7 +316,7 @@ public boolean couldMatchItem(String text) {
if (text.equals("item") || text.equals("potion")) {
return true;
}
if (text.startsWith("item_flagged:")) {
if (text.startsWith("item_flagged:") || text.startsWith("vanilla_tagged:")) {
return true;
}
if (MaterialTag.matches(text)) {
Expand Down Expand Up @@ -913,6 +916,20 @@ public static boolean tryItem(ItemTag item, String comparedto) {
}
return true;
}
if (comparedto.startsWith("vanilla_tagged:")) {
String tagCheck = comparedto.substring("vanilla_tagged:".length());
HashSet<String> tags = VanillaTagHelper.tagsByMaterial.get(item.getItemStack().getType());
if (tags == null) {
return false;
}
MatchHelper matcher = createMatcher(tagCheck);
for (String tag : tags) {
if (matcher.doesMatch(tag)) {
return true;
}
}
return false;
}
if (comparedto.equals("item")) {
return true;
}
Expand All @@ -934,16 +951,34 @@ public static boolean tryItem(ItemTag item, String comparedto) {
}

public static boolean tryMaterial(MaterialTag mat, String comparedto) {
return tryMaterial(mat.getMaterial(), comparedto);
}

public static boolean tryMaterial(Material mat, String comparedto) {
if (comparedto == null || comparedto.isEmpty() || mat == null) {
return false;
}
comparedto = CoreUtilities.toLowerCase(comparedto);
if (comparedto.equals("block") || comparedto.equals("material")) {
return true;
}
if (comparedto.startsWith("vanilla_tagged:")) {
String tagCheck = comparedto.substring("vanilla_tagged:".length());
HashSet<String> tags = VanillaTagHelper.tagsByMaterial.get(mat);
if (tags == null) {
return false;
}
MatchHelper matcher = createMatcher(tagCheck);
for (String tag : tags) {
if (matcher.doesMatch(tag)) {
return true;
}
}
return false;
}
MaterialTag quickOf = MaterialTag.quickOfNamed(comparedto);
if (quickOf != null) {
if (quickOf.getMaterial() != mat.getMaterial()) {
if (quickOf.getMaterial() != mat) {
return false;
}
if (quickOf.equals(mat)) {
Expand Down
Expand Up @@ -2,6 +2,7 @@

import com.denizenscript.denizen.events.BukkitScriptEvent;
import com.denizenscript.denizen.objects.properties.material.*;
import com.denizenscript.denizen.utilities.VanillaTagHelper;
import com.denizenscript.denizen.utilities.debugging.Debug;
import com.denizenscript.denizencore.DenizenCore;
import com.denizenscript.denizencore.flags.AbstractFlagTracker;
Expand All @@ -12,18 +13,22 @@
import com.denizenscript.denizen.tags.BukkitTagContext;
import com.denizenscript.denizencore.objects.core.DurationTag;
import com.denizenscript.denizencore.objects.core.ElementTag;
import com.denizenscript.denizencore.objects.core.ListTag;
import com.denizenscript.denizencore.objects.properties.PropertyParser;
import com.denizenscript.denizencore.tags.Attribute;
import com.denizenscript.denizencore.tags.ObjectTagProcessor;
import com.denizenscript.denizencore.tags.TagContext;
import com.denizenscript.denizencore.tags.TagRunnable;
import com.denizenscript.denizencore.utilities.CoreUtilities;
import com.denizenscript.denizencore.utilities.Deprecations;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.inventory.meta.BlockStateMeta;

import java.util.HashSet;

public class MaterialTag implements ObjectTag, Adjustable, FlaggableObject {

// <--[language]
Expand Down Expand Up @@ -690,14 +695,8 @@ public static void registerTags() {
return new ElementTag(res);
});

// <--[tag]
// @attribute <MaterialTag.has_vanilla_data_tag[<data_tag_name>]>
// @returns ElementTag(Boolean)
// @description
// Returns whether this material has the specified Minecraft vanilla Data Pack Tag.
// See <@link url https://minecraft.gamepedia.com/Tag>.
// -->
registerTag("has_vanilla_data_tag", (attribute, object) -> {
Deprecations.materialHasDataPackTag.warn(attribute.context);
if (!attribute.hasContext(1)) {
attribute.echoError("MaterialTag.has_vanilla_data_tag[...] tag must have an input value.");
return null;
Expand All @@ -711,7 +710,6 @@ public static void registerTags() {
// <--[tag]
// @attribute <MaterialTag.advanced_matches[<matcher>]>
// @returns ElementTag(Boolean)
// @group element checking
// @description
// Returns whether the material matches some matcher text, using the system behind <@link language Advanced Script Event Matching>.
// -->
Expand All @@ -721,6 +719,20 @@ public static void registerTags() {
}
return new ElementTag(BukkitScriptEvent.tryMaterial(object, attribute.getContext(1)));
});

// <--[tag]
// @attribute <MaterialTag.vanilla_tags>
// @returns ListTag
// @description
// Returns a list of vanilla tags that apply to this material. See also <@link url https://minecraft.fandom.com/wiki/Tag>.
// -->
registerTag("vanilla_tags", (attribute, object) -> {
HashSet<String> tags = VanillaTagHelper.tagsByMaterial.get(object.getMaterial());
if (tags == null) {
return null;
}
return new ListTag(tags);
});
}

public static ObjectTagProcessor<MaterialTag> tagProcessor = new ObjectTagProcessor<>();
Expand Down
@@ -1,5 +1,7 @@
package com.denizenscript.denizen.scripts.containers.core;

import com.denizenscript.denizen.Denizen;
import com.denizenscript.denizen.events.BukkitScriptEvent;
import com.denizenscript.denizen.nms.util.jnbt.CompoundTag;
import com.denizenscript.denizen.utilities.Utilities;
import com.denizenscript.denizen.utilities.debugging.Debug;
Expand Down Expand Up @@ -94,16 +96,15 @@ public ItemStack[] textToItemArray(ItemScriptContainer container, String text, b
String entry = ingredientText.get(i);
if (ScriptEvent.isAdvancedMatchable(entry)) {
boolean any = false;
ScriptEvent.MatchHelper matcher = ScriptEvent.createMatcher(entry);
for (Material material : Material.values()) {
if (matcher.doesMatch(CoreUtilities.toLowerCase(material.name()))) {
if (BukkitScriptEvent.tryMaterial(material, entry)) {
outputItems.add(new ItemStack(material, 1));
any = true;
}
}
if (exact) {
for (ItemScriptContainer possibleContainer : ItemScriptHelper.item_scripts.values()) {
if (matcher.doesMatch(CoreUtilities.toLowerCase(possibleContainer.getName()))) {
if (BukkitScriptEvent.tryItem(possibleContainer.getCleanReference(), entry)) {
outputItems.add(possibleContainer.getCleanReference().getItemStack());
any = true;
}
Expand Down
Expand Up @@ -8,6 +8,7 @@
import com.denizenscript.denizen.scripts.containers.core.CommandScriptHelper;
import com.denizenscript.denizen.utilities.ScoreboardHelper;
import com.denizenscript.denizen.utilities.Utilities;
import com.denizenscript.denizen.utilities.VanillaTagHelper;
import com.denizenscript.denizen.utilities.debugging.Debug;
import com.denizenscript.denizen.utilities.depends.Depends;
import com.denizenscript.denizen.utilities.inventory.SlotHelper;
Expand Down Expand Up @@ -2083,6 +2084,37 @@ else if (attribute.startsWith("last_reload")) {
event.setReplacedObject(new TimeTag(Denizen.getInstance().lastReloadTime).getObjectAttribute(attribute.fulfill(1)));
}

// <--[tag]
// @attribute <server.vanilla_tags>
// @returns ListTag
// @description
// Returns a list of vanilla tags (applicable to blocks, fluids, or items). See also <@link url https://minecraft.fandom.com/wiki/Tag>.
// -->
else if (attribute.startsWith("vanilla_tags")) {
event.setReplacedObject(new ListTag(VanillaTagHelper.tagsByKey.keySet()).getObjectAttribute(attribute.fulfill(1)));
}

// <--[tag]
// @attribute <server.vanilla_tagged_materials[<tag>]>
// @returns ListTag(MaterialTag)
// @description
// Returns a list of materials referred to by the specified vanilla tag. See also <@link url https://minecraft.fandom.com/wiki/Tag>.
// -->
else if (attribute.startsWith("vanilla_tagged_materials")) {
if (!attribute.hasContext(1)) {
return;
}
HashSet<Material> materials = VanillaTagHelper.tagsByKey.get(CoreUtilities.toLowerCase(attribute.getContext(1)));
if (materials == null) {
return;
}
ListTag list = new ListTag();
for (Material material : materials) {
list.addObject(new MaterialTag(material));
}
event.setReplacedObject(list.getObjectAttribute(attribute.fulfill(1)));
}

// <--[tag]
// @attribute <server.plugins_handling_event[<bukkit event>]>
// @returns ListTag(PluginTag)
Expand Down
@@ -0,0 +1,34 @@
package com.denizenscript.denizen.utilities;

import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Tag;

import java.util.HashMap;
import java.util.HashSet;

public class VanillaTagHelper {

public static HashMap<Material, HashSet<String>> tagsByMaterial = new HashMap<>();

public static HashMap<String, HashSet<Material>> tagsByKey = new HashMap<>();

static void addTag(Tag<Material> tag) {
tagsByKey.computeIfAbsent(tag.getKey().getKey(), (k) -> new HashSet<>()).addAll(tag.getValues());
for (Material mat : tag.getValues()) {
tagsByMaterial.computeIfAbsent(mat, (k) -> new HashSet<>()).add(tag.getKey().getKey());
}
}

static {
for (Tag<Material> tag : Bukkit.getTags("blocks", Material.class)) {
addTag(tag);
}
/*for (Tag<Material> tag : Bukkit.getTags("fluids", Material.class)) {
addTag(tag);
}*/ // Temporarily exclude fluids due to spigot bug
for (Tag<Material> tag : Bukkit.getTags("items", Material.class)) {
addTag(tag);
}
}
}

0 comments on commit 557f6dc

Please sign in to comment.