Skip to content

Commit

Permalink
Merge branch 'dev/feature' into update-some-utils
Browse files Browse the repository at this point in the history
  • Loading branch information
Efnilite authored Nov 10, 2024
2 parents b06fc0c + 0a680d4 commit 9e43c24
Show file tree
Hide file tree
Showing 12 changed files with 295 additions and 177 deletions.
2 changes: 1 addition & 1 deletion skript-aliases
57 changes: 57 additions & 0 deletions src/main/java/ch/njol/skript/bukkitutil/SoundUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package ch.njol.skript.bukkitutil;

import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.bukkit.Sound;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Locale;

/**
* Utility class for working with sounds.
*/
public final class SoundUtils {

// Sound.class is an interface (rather than an enum) as of MC 1.21.3
private static final boolean SOUND_IS_INTERFACE = Sound.class.isInterface();

/**
* Gets the key of a sound, given its enum-name-style name.
* @param soundString The enum name to use to find the sound.
* @return The key of the sound.
*/
public static @Nullable NamespacedKey getKey(String soundString) {
soundString = soundString.toUpperCase(Locale.ENGLISH);
if (SOUND_IS_INTERFACE) {
try {
//noinspection deprecation
return Sound.valueOf(soundString).getKey();
} catch (IllegalArgumentException ignore) {
}
} else {
try {
//noinspection unchecked,rawtypes
Enum soundEnum = Enum.valueOf((Class) Sound.class, soundString);
return ((Keyed) soundEnum).getKey();
} catch (IllegalArgumentException ignore) {
}
}
return null;
}

/**
* returns the key string for a sound. For version compat.
* @param sound The sound to get the key string of.
* @return The key string of the {@link NamespacedKey} of the sound.
*/
public static @NotNull NamespacedKey getKey(Sound sound) {
if (SOUND_IS_INTERFACE) {
//noinspection deprecation
return sound.getKey();
} else {
return ((Keyed) sound).getKey();
}
}

}
55 changes: 13 additions & 42 deletions src/main/java/ch/njol/skript/effects/EffPlaySound.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ch.njol.skript.effects;

import ch.njol.skript.Skript;
import ch.njol.skript.bukkitutil.SoundUtils;
import ch.njol.skript.bukkitutil.sounds.SoundReceiver;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
Expand All @@ -11,7 +12,6 @@
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.util.Kleenean;
import org.bukkit.Keyed;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.Sound;
Expand Down Expand Up @@ -73,7 +73,6 @@ public class EffPlaySound extends Effect {
private static final boolean ENTITY_EMITTER_SOUND = Skript.methodExists(Player.class, "playSound", Entity.class, Sound.class, SoundCategory.class, float.class, float.class);
private static final boolean ENTITY_EMITTER_STRING = Skript.methodExists(Player.class, "playSound", Entity.class, String.class, SoundCategory.class, float.class, float.class);
private static final boolean ENTITY_EMITTER = ENTITY_EMITTER_SOUND || ENTITY_EMITTER_STRING;
private static final boolean SOUND_IS_INTERFACE = Sound.class.isInterface();

public static final Pattern KEY_PATTERN = Pattern.compile("([a-z0-9._-]+:)?([a-z0-9/._-]+)");

Expand All @@ -90,26 +89,20 @@ public class EffPlaySound extends Effect {
);
}

@SuppressWarnings("NotNullFieldNotInitialized")
private Expression<String> sounds;

@Nullable
private Expression<SoundCategory> category;

@Nullable
private Expression<Player> players;
private @Nullable Expression<SoundCategory> category;

@Nullable
private Expression<Number> volume;
private @Nullable Expression<Player> players;

@Nullable
private Expression<Number> pitch;
private @Nullable Expression<Number> volume;

@Nullable
private Expression<Number> seed;
private @Nullable Expression<Number> pitch;

@Nullable
private Expression<?> emitters;
private @Nullable Expression<Number> seed;

private @Nullable Expression<?> emitters;

@Override
@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -151,7 +144,7 @@ protected void execute(Event event) {
// validate strings
List<NamespacedKey> validSounds = new ArrayList<>();
for (String sound : sounds.getArray(event)) {
NamespacedKey key = getSoundKeyFromEnum(sound);
NamespacedKey key = SoundUtils.getKey(sound);
if (key == null) {
sound = sound.toLowerCase(Locale.ENGLISH);
Matcher keyMatcher = KEY_PATTERN.matcher(sound);
Expand Down Expand Up @@ -204,12 +197,12 @@ protected void execute(Event event) {
}
} else if (emitters != null) {
for (Object emitter : emitters.getArray(event)) {
if (ENTITY_EMITTER && emitter instanceof Entity) {
SoundReceiver receiver = SoundReceiver.of(((Entity) emitter).getWorld());
if (ENTITY_EMITTER && emitter instanceof Entity entity) {
SoundReceiver receiver = SoundReceiver.of(entity.getWorld());
for (NamespacedKey sound : validSounds)
receiver.playSound(((Entity) emitter), sound, category, volume, pitch, seed);
} else if (emitter instanceof Location) {
SoundReceiver receiver = SoundReceiver.of(((Location) emitter).getWorld());
} else if (emitter instanceof Location location) {
SoundReceiver receiver = SoundReceiver.of(location.getWorld());
for (NamespacedKey sound : validSounds)
receiver.playSound(((Location) emitter), sound, category, volume, pitch, seed);
}
Expand Down Expand Up @@ -239,26 +232,4 @@ public String toString(@Nullable Event event, boolean debug) {
return builder.toString();
}

@SuppressWarnings({"deprecation", "unchecked", "rawtypes"})
private static @Nullable NamespacedKey getSoundKeyFromEnum(String soundString) {
soundString = soundString.toUpperCase(Locale.ENGLISH);
// Sound.class is an Interface (rather than an enum) as of MC 1.21.3
if (SOUND_IS_INTERFACE) {
try {
Sound sound = Sound.valueOf(soundString);
return sound.getKey();
} catch (IllegalArgumentException ignore) {
}
} else {
try {
Enum soundEnum = Enum.valueOf((Class) Sound.class, soundString);
if (soundEnum instanceof Keyed) {
return ((Keyed) soundEnum).getKey();
}
} catch (IllegalArgumentException ignore) {
}
}
return null;
}

}
88 changes: 43 additions & 45 deletions src/main/java/ch/njol/skript/entity/BoatChestData.java
Original file line number Diff line number Diff line change
@@ -1,54 +1,42 @@
package ch.njol.skript.entity;

import ch.njol.skript.Skript;
import ch.njol.skript.aliases.ItemData;
import ch.njol.skript.aliases.ItemType;
import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.SkriptParser;
import org.bukkit.Material;
import org.bukkit.entity.Boat;
import org.bukkit.entity.ChestBoat;
import org.bukkit.entity.boat.*;
import org.jetbrains.annotations.Nullable;

import java.util.EnumMap;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Random;

// For <1.21.3 compatability only. 1.21.3+ boats are SimpleEntityDatas
public class BoatChestData extends EntityData<ChestBoat> {

private static final boolean IS_RUNNING_1_21_3 = Skript.isRunningMinecraft(1, 21, 3);
private static final EnumMap<Boat.Type, Class<? extends ChestBoat>> typeToClassMap = new EnumMap<>(Boat.Type.class);

private static final Boat.Type[] types = Boat.Type.values();

static {
// This ensures all boats are registered
// As well as in the correct order via 'ordinal'
String[] patterns = new String[types.length + 2];
patterns[0] = "chest boat";
patterns[1] = "any chest boat";
for (Boat.Type boat : types) {
String boatName;
if (boat == Boat.Type.BAMBOO)
boatName = "bamboo chest raft";
else
boatName = boat.toString().replace("_", " ").toLowerCase(Locale.ENGLISH) + " chest boat";
patterns[boat.ordinal() + 2] = boatName;
}

if (IS_RUNNING_1_21_3) {
typeToClassMap.put(Boat.Type.OAK, OakChestBoat.class);
typeToClassMap.put(Boat.Type.SPRUCE, SpruceChestBoat.class);
typeToClassMap.put(Boat.Type.BIRCH, BirchChestBoat.class);
typeToClassMap.put(Boat.Type.JUNGLE, JungleChestBoat.class);
typeToClassMap.put(Boat.Type.ACACIA, AcaciaChestBoat.class);
typeToClassMap.put(Boat.Type.DARK_OAK, DarkOakChestBoat.class);
typeToClassMap.put(Boat.Type.MANGROVE, MangroveChestBoat.class);
typeToClassMap.put(Boat.Type.CHERRY, CherryChestBoat.class);
typeToClassMap.put(Boat.Type.BAMBOO, BambooChestRaft.class);
}
if (!Skript.isRunningMinecraft(1, 21, 2)) {
// This ensures all boats are registered
// As well as in the correct order via 'ordinal'
String[] patterns = new String[types.length + 2];
patterns[0] = "chest boat";
patterns[1] = "any chest boat";
for (Boat.Type boat : types) {
String boatName;
if (boat == Boat.Type.BAMBOO) {
boatName = "bamboo chest raft";
} else {
boatName = boat.toString().replace("_", " ").toLowerCase(Locale.ENGLISH) + " chest boat";
}
patterns[boat.ordinal() + 2] = boatName;
}

if (Skript.classExists("org.bukkit.entity.ChestBoat")) {
EntityData.register(BoatChestData.class, "chest boat", ChestBoat.class, 0, patterns);
}
}
Expand Down Expand Up @@ -92,8 +80,6 @@ protected boolean match(ChestBoat entity) {

@Override
public Class<? extends ChestBoat> getType() {
if (IS_RUNNING_1_21_3)
return typeToClassMap.get(types[matchedPattern - 2]);
return ChestBoat.class;
}

Expand Down Expand Up @@ -121,21 +107,33 @@ public boolean isSupertypeOf(EntityData<?> entity) {
return false;
}

public boolean isOfItemType(ItemType itemType) {
int ordinal = -1;

Material material = itemType.getMaterial();
if (material == Material.OAK_CHEST_BOAT) {
ordinal = 0;
} else {
for (Boat.Type boat : types) {
if (material.name().contains(boat.toString())) {
ordinal = boat.ordinal();
break;
}
private static final Map<Material, Boat.Type> materialToType = new HashMap<>();
static {
materialToType.put(Material.OAK_CHEST_BOAT, Boat.Type.OAK);
materialToType.put(Material.BIRCH_CHEST_BOAT, Boat.Type.BIRCH);
materialToType.put(Material.SPRUCE_CHEST_BOAT, Boat.Type.SPRUCE);
materialToType.put(Material.JUNGLE_CHEST_BOAT, Boat.Type.JUNGLE);
materialToType.put(Material.DARK_OAK_CHEST_BOAT, Boat.Type.DARK_OAK);
materialToType.put(Material.ACACIA_CHEST_BOAT, Boat.Type.ACACIA);
materialToType.put(Material.MANGROVE_CHEST_BOAT, Boat.Type.MANGROVE);
materialToType.put(Material.CHERRY_CHEST_BOAT, Boat.Type.CHERRY);
materialToType.put(Material.BAMBOO_CHEST_RAFT, Boat.Type.BAMBOO);
}

public boolean isOfItemType(ItemType itemType) {
for (ItemData itemData : itemType.getTypes()) {
int ordinal;
Material material = itemData.getType();
Boat.Type type = materialToType.get(material);
// material is a boat AND (data matches any boat OR material and data are same)
if (type != null) {
ordinal = type.ordinal();
if (matchedPattern <= 1 || matchedPattern == ordinal + 2)
return true;
}
}
return hashCode_i() == ordinal + 2 || (matchedPattern + ordinal == 0) || ordinal == 0;
return false;
}

}
Loading

0 comments on commit 9e43c24

Please sign in to comment.