Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
4 changes: 3 additions & 1 deletion src/main/java/ch/njol/skript/Skript.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
import org.skriptlang.skript.bukkit.brewing.BrewingModule;
import org.skriptlang.skript.bukkit.damagesource.DamageSourceModule;
import org.skriptlang.skript.bukkit.displays.DisplayModule;
import org.skriptlang.skript.bukkit.entity.EntityModule;
import org.skriptlang.skript.bukkit.fishing.FishingModule;
import org.skriptlang.skript.bukkit.furnace.FurnaceModule;
import org.skriptlang.skript.bukkit.input.InputModule;
Expand Down Expand Up @@ -599,7 +600,8 @@ public void onEnable() {
new DamageSourceModule(),
new ItemComponentModule(),
new BrewingModule(),
new CommonModule()
new CommonModule(),
new EntityModule()
);
} catch (final Exception e) {
exception(e, "Could not load required .class files: " + e.getLocalizedMessage());
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/ch/njol/skript/bukkitutil/NamespacedUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import ch.njol.skript.localization.Message;
import ch.njol.skript.util.ValidationResult;
import org.bukkit.NamespacedKey;
import org.jetbrains.annotations.Nullable;
import org.skriptlang.skript.log.runtime.RuntimeErrorProducer;

/**
* Utility class for {@link NamespacedKey}
Expand Down Expand Up @@ -89,4 +91,23 @@ public static boolean isValid(String string) {
return checkValidation(string).valid();
}

/**
* Helper method for converting a {@link String} to {@link NamespacedKey} during runtime, and printing
* errors or warnings.
* @param producer The {@link RuntimeErrorProducer} instance to print an error or warning.
* @param string The {@link String} to convert to {@link NamespacedKey}.
* @return The resulting {@link NamespacedKey} if valid, otherwise {@code null}.
*/
public static @Nullable NamespacedKey getKeyWithErrors(RuntimeErrorProducer producer, String string) {
ValidationResult<NamespacedKey> result = checkValidation(string);
String message = result.message();
if (!result.valid()) {
producer.error(message);
return null;
} else if (message != null) {
producer.warning(message);
}
return result.data();
}

}
29 changes: 26 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 @@ -4,7 +4,11 @@
import ch.njol.skript.bukkitutil.BukkitUtils;
import ch.njol.skript.bukkitutil.EntityUtils;
import ch.njol.skript.bukkitutil.SkriptTeleportFlag;
import ch.njol.skript.classes.*;
import ch.njol.skript.classes.ClassInfo;
import ch.njol.skript.classes.EnumClassInfo;
import ch.njol.skript.classes.Parser;
import ch.njol.skript.classes.PatternedParser;
import ch.njol.skript.classes.Serializer;
import ch.njol.skript.classes.registry.RegistryClassInfo;
import ch.njol.skript.expressions.ExprDamageCause;
import ch.njol.skript.expressions.base.EventValueExpression;
Expand All @@ -26,7 +30,12 @@
import org.bukkit.command.CommandSender;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.enchantments.EnchantmentOffer;
import org.bukkit.entity.*;
import org.bukkit.entity.EntitySnapshot;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.Vehicle;
import org.bukkit.entity.Villager;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityPotionEffectEvent;
Expand All @@ -49,11 +58,18 @@
import org.bukkit.metadata.Metadatable;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.profile.PlayerTextures.SkinModel;
import org.bukkit.util.CachedServerIcon;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.Nullable;
import org.skriptlang.skript.bukkit.base.types.*;
import org.skriptlang.skript.bukkit.base.types.BlockClassInfo;
import org.skriptlang.skript.bukkit.base.types.EntityClassInfo;
import org.skriptlang.skript.bukkit.base.types.EntityClassInfo.EntityChanger;
import org.skriptlang.skript.bukkit.base.types.InventoryClassInfo;
import org.skriptlang.skript.bukkit.base.types.ItemStackClassInfo;
import org.skriptlang.skript.bukkit.base.types.NameableClassInfo;
import org.skriptlang.skript.bukkit.base.types.OfflinePlayerClassInfo;
import org.skriptlang.skript.bukkit.base.types.PlayerClassInfo;
import org.skriptlang.skript.lang.properties.Property;
import org.skriptlang.skript.lang.properties.PropertyHandler.ExpressionPropertyHandler;

Expand Down Expand Up @@ -1140,5 +1156,12 @@ public String toVariableNameString(WorldBorder border) {
.since("2.12")
);

Classes.registerClass(new EnumClassInfo<>(SkinModel.class, "skinmodel", "skin models")
.user("skin ?models?")
.name("Skin Model")
.description("Represents a skin model.")
.since("INSERT VERSION")
);

}
}
35 changes: 17 additions & 18 deletions src/main/java/ch/njol/skript/conditions/CondIsLeftHanded.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,34 @@
import ch.njol.skript.Skript;
import ch.njol.skript.conditions.base.PropertyCondition;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Example;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.RequiredPlugins;
import ch.njol.skript.doc.Since;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.util.Kleenean;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Mannequin;
import org.bukkit.entity.Mob;
import org.bukkit.inventory.MainHand;

@Name("Left Handed")
@Description({
"Checks if living entities or players are left or right-handed. Armor stands are neither right nor left-handed."
})
@Examples({
"on damage of player:",
"\tif victim is left handed:",
"\t\tcancel event"
})
@Since("2.8.0")
@Description("Checks if living entities or players are left or right-handed. Armor stands are neither right nor left-handed.")
@Example("""
on damage of player:
if victim is left handed:
cancel event
""")
@RequiredPlugins("Minecraft 1.21.9+ (mannequins)")
@Since("2.8.0, INSERT VERSION (mannequins)")
public class CondIsLeftHanded extends PropertyCondition<LivingEntity> {

// TODO - remove this when Spigot support is dropped
private static final boolean CAN_USE_ENTITIES = Skript.methodExists(Mob.class, "isLeftHanded");
private static final boolean MANNEQUIN_EXISTS = Skript.classExists("org.bukkit.entity.Mannequin");

static {
if (CAN_USE_ENTITIES) {
register(CondIsLeftHanded.class, "(:left|right)( |-)handed", "livingentities");
} else {
register(CondIsLeftHanded.class, "(:left|right)( |-)handed", "players");
}
register(CondIsLeftHanded.class, "(:left|right)( |-)handed", "entities");
}

private MainHand hand;
Expand All @@ -48,13 +44,16 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed,
@Override
public boolean check(LivingEntity livingEntity) {
// check if entity is a mob and if the method exists
if (CAN_USE_ENTITIES && livingEntity instanceof Mob mob)
if (livingEntity instanceof Mob mob)
return mob.isLeftHanded() == (hand == MainHand.LEFT);

// check if entity is a player
if (livingEntity instanceof HumanEntity humanEntity)
return humanEntity.getMainHand() == hand;

if (MANNEQUIN_EXISTS && livingEntity instanceof Mannequin mannequin)
return mannequin.getMainHand() == hand;

// invalid entity
return false;
}
Expand Down
31 changes: 19 additions & 12 deletions src/main/java/ch/njol/skript/effects/EffHandedness.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,36 @@

import ch.njol.skript.Skript;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Example;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.RequiredPlugins;
import ch.njol.skript.doc.Since;
import ch.njol.skript.lang.Effect;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.util.Kleenean;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Mannequin;
import org.bukkit.entity.Mob;
import org.bukkit.event.Event;
import org.bukkit.inventory.MainHand;
import org.jetbrains.annotations.Nullable;

@Name("Handedness")
@Description("Make mobs left or right-handed. This does not affect players.")
@Examples({
"spawn skeleton at spawn of world \"world\":",
"\tmake entity left handed",
"",
"make all zombies in radius 10 of player right handed"
})
@Since("2.8.0")
@Example("""
spawn skeleton at spawn of world "world":
make entity left handed
""")
@Example("make all zombies in radius 10 of player right handed")
@RequiredPlugins("Minecraft 1.21.9+ (mannequins)")
@Since("2.8.0, INSERT VERSION (mannequins)")
public class EffHandedness extends Effect {

private static final boolean MANNEQUIN_EXISTS = Skript.classExists("org.bukkit.entity.Mannequin");

static {
if (Skript.methodExists(Mob.class, "setLeftHanded", boolean.class))
Skript.registerEffect(EffHandedness.class, "make %livingentities% (:left|right)( |-)handed");
Skript.registerEffect(EffHandedness.class, "make %livingentities% (:left|right)( |-)handed");
}

private boolean leftHanded;
Expand All @@ -42,9 +46,12 @@ public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelaye

@Override
protected void execute(Event event) {
MainHand mainHand = leftHanded ? MainHand.LEFT : MainHand.RIGHT;
for (LivingEntity livingEntity : livingEntities.getArray(event)) {
if (livingEntity instanceof Mob) {
((Mob) livingEntity).setLeftHanded(leftHanded);
if (livingEntity instanceof Mob mob) {
mob.setLeftHanded(leftHanded);
} else if (MANNEQUIN_EXISTS && livingEntity instanceof Mannequin mannequin) {
mannequin.setMainHand(mainHand);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,6 @@ private static void addSuperEntity(String codeName, Class<? extends Entity> enti

if (Skript.isRunningMinecraft(1, 21, 9)) {
addSimpleEntity("copper golem", CopperGolem.class);
addSimpleEntity("mannequin", Mannequin.class);
}

// SuperTypes
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.skriptlang.skript.bukkit.entity;

import org.skriptlang.skript.addon.AddonModule;
import org.skriptlang.skript.addon.SkriptAddon;
import org.skriptlang.skript.bukkit.entity.mannequin.MannequinModule;

public class EntityModule implements AddonModule {

@Override
public void load(SkriptAddon addon) {
addon.loadModules(new MannequinModule());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package org.skriptlang.skript.bukkit.entity.mannequin;

import ch.njol.skript.entity.EntityData;
import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.util.Kleenean;
import org.bukkit.entity.Mannequin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class MannequinData extends EntityData<Mannequin> {

public static void register() {
register(MannequinData.class, "mannequin", Mannequin.class, 0, "mannequin");
}

private Kleenean immovable = Kleenean.UNKNOWN;

public MannequinData() {}

public MannequinData(@Nullable Kleenean immovable) {
this.immovable = immovable == null ? Kleenean.UNKNOWN : immovable;
}

@Override
protected boolean init(Literal<?>[] exprs, int matchedCodeName, int matchedPattern, ParseResult parseResult) {
if (matchedPattern == 1) {
immovable = Kleenean.TRUE;
} else if (matchedPattern == 2) {
immovable = Kleenean.FALSE;
}
return true;
}

@Override
protected boolean init(@Nullable Class<? extends Mannequin> entityClass, @Nullable Mannequin mannequin) {
if (mannequin != null)
immovable = Kleenean.get(mannequin.isImmovable());
return true;
}

@Override
public void set(Mannequin mannequin) {
mannequin.setImmovable(immovable.isTrue());
}

@Override
protected boolean match(Mannequin mannequin) {
return kleeneanMatch(immovable, mannequin.isImmovable());
}

@Override
public Class<? extends Mannequin> getType() {
return Mannequin.class;
}

@Override
public @NotNull EntityData<?> getSuperType() {
return new MannequinData();
}

@Override
protected int hashCode_i() {
return immovable.hashCode();
}

@Override
protected boolean equals_i(EntityData<?> entityData) {
if (!(entityData instanceof MannequinData other))
return false;
return immovable == other.immovable;
}

@Override
public boolean isSupertypeOf(EntityData<?> entityData) {
if (!(entityData instanceof MannequinData other))
return false;
return kleeneanMatch(immovable, other.immovable);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.skriptlang.skript.bukkit.entity.mannequin;

import ch.njol.skript.Skript;
import org.skriptlang.skript.addon.AddonModule;
import org.skriptlang.skript.addon.SkriptAddon;
import org.skriptlang.skript.bukkit.entity.mannequin.elements.*;
import org.skriptlang.skript.registration.SyntaxRegistry;

import java.util.Set;
import java.util.function.Consumer;

public class MannequinModule implements AddonModule {

@Override
public boolean canLoad(SkriptAddon addon) {
return Skript.classExists("org.bukkit.entity.Mannequin");
}

@Override
public void load(SkriptAddon addon) {
Set<Consumer<SyntaxRegistry>> elementsToLoad = Set.of(
CondMannequinImmovable::register,
CondMannequinParts::register,
EffMannequinImmovable::register,
EffMannequinParts::register,
ExprMannequinBody::register,
ExprMannequinCape::register,
ExprMannequinDesc::register,
ExprMannequinElytra::register,
ExprMannequinModel::register,
ExprMannequinSkin::register
);

SyntaxRegistry registry = addon.syntaxRegistry();
elementsToLoad.forEach(element -> element.accept(registry));

MannequinData.register();
}

}
Loading
Loading