Skip to content

Commit

Permalink
Merge branch 'dev/feature' into tooltips
Browse files Browse the repository at this point in the history
  • Loading branch information
cheeezburga authored Jun 21, 2024
2 parents db2554a + 34b303b commit 7953aff
Show file tree
Hide file tree
Showing 16 changed files with 415 additions and 103 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ org.gradle.parallel=true

groupid=ch.njol
name=skript
version=2.8.6
version=2.8.7
jarName=Skript.jar
testEnv=java21/paper-1.20.6
testEnvJavaVersion=21
14 changes: 11 additions & 3 deletions src/main/java/ch/njol/skript/classes/data/BukkitClasses.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.Registry;
import org.bukkit.SoundCategory;
import org.bukkit.World;
import org.bukkit.World.Environment;
Expand Down Expand Up @@ -77,7 +78,6 @@
import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.CachedServerIcon;
import org.bukkit.util.Vector;
import org.eclipse.jdt.annotation.Nullable;

import ch.njol.skript.Skript;
import ch.njol.skript.SkriptConfig;
Expand All @@ -90,6 +90,7 @@
import ch.njol.skript.classes.EnumClassInfo;
import ch.njol.skript.classes.Parser;
import ch.njol.skript.classes.Serializer;
import ch.njol.skript.classes.registry.RegistryClassInfo;
import ch.njol.skript.entity.EntityData;
import ch.njol.skript.expressions.ExprDamageCause;
import ch.njol.skript.expressions.base.EventValueExpression;
Expand All @@ -104,6 +105,7 @@
import ch.njol.util.StringUtils;
import ch.njol.yggdrasil.Fields;
import io.papermc.paper.world.MoonPhase;
import org.jetbrains.annotations.Nullable;

/**
* @author Peter Güttinger
Expand Down Expand Up @@ -976,8 +978,14 @@ public String toVariableNameString(final ItemStack i) {
.name(ClassInfo.NO_DOC)
.since("2.0")
.changer(DefaultChangers.itemChanger));

Classes.registerClass(new EnumClassInfo<>(Biome.class, "biome", "biomes")

ClassInfo<?> biomeClassInfo;
if (Skript.classExists("org.bukkit.Registry") && Skript.fieldExists(Registry.class, "BIOME")) {
biomeClassInfo = new RegistryClassInfo<>(Biome.class, Registry.BIOME, "biome", "biomes");
} else {
biomeClassInfo = new EnumClassInfo<>(Biome.class, "biome", "biomes");
}
Classes.registerClass(biomeClassInfo
.user("biomes?")
.name("Biome")
.description("All possible biomes Minecraft uses to generate a world.")
Expand Down
32 changes: 6 additions & 26 deletions src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
*/
package ch.njol.skript.classes.data;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -664,34 +661,17 @@ public LivingEntity[] get(AreaEffectCloudApplyEvent event) {
}
}, EventValues.TIME_NOW);
EventValues.registerEventValue(AreaEffectCloudApplyEvent.class, PotionEffectType.class, new Getter<PotionEffectType, AreaEffectCloudApplyEvent>() {
@Nullable
private final MethodHandle BASE_POTION_DATA_HANDLE;

{
MethodHandle basePotionDataHandle = null;
if (Skript.methodExists(AreaEffectCloud.class, "getBasePotionData")) {
try {
basePotionDataHandle = MethodHandles.lookup().findVirtual(AreaEffectCloud.class, "getBasePotionData", MethodType.methodType(PotionData.class));
} catch (NoSuchMethodException | IllegalAccessException e) {
Skript.exception(e, "Failed to load legacy potion data support. Potions may not work as expected.");
}
}
BASE_POTION_DATA_HANDLE = basePotionDataHandle;
}

private final boolean HAS_POTION_TYPE_METHOD = Skript.methodExists(AreaEffectCloud.class, "getBasePotionType");
@Override
@Nullable
public PotionEffectType get(AreaEffectCloudApplyEvent e) {
if (BASE_POTION_DATA_HANDLE != null) {
try {
return ((PotionData) BASE_POTION_DATA_HANDLE.invoke(e.getEntity())).getType().getEffectType();
} catch (Throwable ex) {
throw Skript.exception(ex, "An error occurred while trying to invoke legacy area effect cloud potion effect support.");
}
} else {
// TODO needs to be reworked to support multiple values (there can be multiple potion effects)
if (HAS_POTION_TYPE_METHOD) {
PotionType base = e.getEntity().getBasePotionType();
if (base != null) // TODO this is deprecated... this should become a multi-value event value
if (base != null)
return base.getEffectType();
} else {
return e.getEntity().getBasePotionData().getType().getEffectType();
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,7 @@ public String toVariableNameString(final Experience xp) {
.usage(VisualEffects.getAllNames())
.since("2.1")
.user("(visual|particle) effects?")
.after("itemtype")
.parser(new Parser<VisualEffect>() {
@Override
@Nullable
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* 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.skript.classes.registry;

import ch.njol.skript.classes.ClassInfo;
import ch.njol.skript.expressions.base.EventValueExpression;
import ch.njol.skript.lang.DefaultExpression;
import org.bukkit.Keyed;
import org.bukkit.Registry;

/**
* This class can be used for easily creating ClassInfos for {@link Registry}s.
* It registers a language node with usage, a serializer, default expression, and a parser.
*
* @param <R> The Registry class.
*/
public class RegistryClassInfo<R extends Keyed> extends ClassInfo<R> {

public RegistryClassInfo(Class<R> registryClass, Registry<R> registry, String codeName, String languageNode) {
this(registryClass, registry, codeName, languageNode, new EventValueExpression<>(registryClass));
}

/**
* @param registry The registry
* @param codeName The name used in patterns
*/
public RegistryClassInfo(Class<R> registryClass, Registry<R> registry, String codeName, String languageNode, DefaultExpression<R> defaultExpression) {
super(registryClass, codeName);
RegistryParser<R> registryParser = new RegistryParser<>(registry, languageNode);
usage(registryParser.getAllNames())
.supplier(registry::iterator)
.serializer(new RegistrySerializer<R>(registry))
.defaultExpression(defaultExpression)
.parser(registryParser);
}

}
155 changes: 155 additions & 0 deletions src/main/java/ch/njol/skript/classes/registry/RegistryParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/**
* 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.skript.classes.registry;

import ch.njol.skript.classes.Parser;
import ch.njol.skript.lang.ParseContext;
import ch.njol.skript.localization.Language;
import ch.njol.skript.localization.Noun;
import ch.njol.util.NonNullPair;
import ch.njol.util.StringUtils;
import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
* A parser based on a {@link Registry} used to parse data from a string or turn data into a string.
*
* @param <R> Registry class
*/
public class RegistryParser<R extends Keyed> extends Parser<R> {

private final Registry<R> registry;
private final String languageNode;

private final Map<R, String> names = new HashMap<>();
private final Map<String, R> parseMap = new HashMap<>();

public RegistryParser(Registry<R> registry, String languageNode) {
assert !languageNode.isEmpty() && !languageNode.endsWith(".") : languageNode;
this.registry = registry;
this.languageNode = languageNode;
refresh();
Language.addListener(this::refresh);
}

private void refresh() {
names.clear();
parseMap.clear();
for (R registryObject : registry) {
NamespacedKey namespacedKey = registryObject.getKey();
String namespace = namespacedKey.getNamespace();
String key = namespacedKey.getKey();
String keyWithSpaces = key.replace("_", " ");
String languageKey = languageNode + "." + key;

// Put the full namespaced key as a pattern
parseMap.put(namespacedKey.toString(), registryObject);

// If the object is a vanilla Minecraft object, we'll add the key with spaces as a pattern
if (namespace.equalsIgnoreCase(NamespacedKey.MINECRAFT)) {
parseMap.put(keyWithSpaces, registryObject);
}

String[] options = Language.getList(languageKey);
// Missing/Custom registry objects
if (options.length == 1 && options[0].equals(languageKey.toLowerCase(Locale.ENGLISH))) {
if (namespace.equalsIgnoreCase(NamespacedKey.MINECRAFT)) {
// If the object is a vanilla Minecraft object, we'll use the key with spaces as a name
names.put(registryObject, keyWithSpaces);
} else {
// If the object is a custom object, we'll use the full namespaced key as a name
names.put(registryObject, namespacedKey.toString());
}
} else {
for (String option : options) {
option = option.toLowerCase(Locale.ENGLISH);

// Isolate the gender if one is present
NonNullPair<String, Integer> strippedOption = Noun.stripGender(option, languageKey);
String first = strippedOption.getFirst();
Integer second = strippedOption.getSecond();

// Add to name map if needed
names.putIfAbsent(registryObject, first);

parseMap.put(first, registryObject);
if (second != -1) { // There is a gender present
parseMap.put(Noun.getArticleWithSpace(second, Language.F_INDEFINITE_ARTICLE) + first, registryObject);
}
}
}
}
}

/**
* This method attempts to match the string input against one of the string representations of the registry.
*
* @param input a string to attempt to match against one in the registry.
* @param context of parsing, may not be null
* @return The registry object matching the input, or null if no match could be made.
*/
@Override
public @Nullable R parse(String input, @NotNull ParseContext context) {
return parseMap.get(input.toLowerCase(Locale.ENGLISH));
}

/**
* This method returns the string representation of a registry.
*
* @param object The object to represent as a string.
* @param flags not currently used
* @return A string representation of the registry object.
*/
@Override
public @NotNull String toString(R object, int flags) {
return names.get(object);
}

/**
* Returns a registry object's string representation in a variable name.
*
* @param object Object to represent in a variable name.
* @return The given object's representation in a variable name.
*/
@Override
public @NotNull String toVariableNameString(R object) {
return toString(object, 0);
}

/**
* @return A comma-separated string containing a list of all names representing the registry.
* Note that some entries may represent the same registry object.
*/
public String getAllNames() {
List<String> strings = new ArrayList<>(parseMap.keySet());
Collections.sort(strings);
return StringUtils.join(strings, ", ");
}

}
Loading

0 comments on commit 7953aff

Please sign in to comment.