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

Wolf Variants #7041

Merged
merged 18 commits into from
Oct 13, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
21 changes: 21 additions & 0 deletions src/main/java/ch/njol/skript/classes/data/BukkitClasses.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import org.bukkit.enchantments.Enchantment;
import org.bukkit.enchantments.EnchantmentOffer;
import org.bukkit.entity.Cat;
import org.bukkit.entity.Wolf;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
Expand Down Expand Up @@ -107,6 +108,8 @@
import io.papermc.paper.world.MoonPhase;
import org.jetbrains.annotations.Nullable;

import ch.njol.skript.entity.WolfData;

/**
* @author Peter Güttinger
*/
Expand Down Expand Up @@ -1526,6 +1529,24 @@ public String toVariableNameString(EnchantmentOffer eo) {
.name("Transform Reason")
.description("Represents a transform reason of an <a href='events.html#entity transform'>entity transform event</a>.")
.since("2.8.0"));

ClassInfo<?> wolfVariantClassInfo;
if (Skript.classExists("org.bukkit.entity.Wolf$Variant") && BukkitUtils.registryExists("WOLF_VARIANT")) {
wolfVariantClassInfo = new RegistryClassInfo<>(Wolf.Variant.class, Registry.WOLF_VARIANT, "wolfvariant", "wolf variants");
} else {
/*
* Registers a dummy/placeholder class to ensure working operation on MC versions that do not have `Wolf.Variant`
*/
wolfVariantClassInfo = new ClassInfo<>(WolfData.VariantDummy.class, "wolfvariant");
}
Classes.registerClass(wolfVariantClassInfo
.user("wolf ?variants?")
.name("Wolf Variant")
.description("Represents the variant of a wolf entity.",
"NOTE: Minecraft namespaces are supported, ex: 'minecraft:ashen'.")
.since("@VERSION")
.requiredPlugins("Minecraft 1.21 or newer")
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
.documentationId("WolfVariant"));
}

}
44 changes: 40 additions & 4 deletions src/main/java/ch/njol/skript/entity/WolfData.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,39 @@
*/
package ch.njol.skript.entity;

import ch.njol.skript.bukkitutil.BukkitUtils;
import ch.njol.skript.registrations.Classes;
import ch.njol.util.coll.CollectionUtils;
import com.google.common.collect.Iterators;
import org.bukkit.DyeColor;
import org.bukkit.entity.Wolf;
import org.jetbrains.annotations.Nullable;

import ch.njol.skript.Skript;
import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.util.Color;

import java.util.Objects;

public class WolfData extends EntityData<Wolf> {

private static boolean variantsEnabled = false;

static {
EntityData.register(WolfData.class, "wolf", Wolf.class, 1,
"peaceful wolf", "wolf", "angry wolf",
"wild wolf", "tamed wolf");
if (Skript.classExists("org.bukkit.entity.Wolf$Variant") && BukkitUtils.registryExists("WOLF_VARIANT")) {
variantsEnabled = true;
variants = Iterators.toArray(Classes.getExactClassInfo(Wolf.Variant.class).getSupplier().get(), Wolf.Variant.class);
}
}


private static Object[] variants;
@Nullable
private Object variant;
@Nullable
private DyeColor collarColor;
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved

Expand All @@ -47,8 +64,10 @@ protected boolean init(Literal<?>[] exprs, int matchedPattern, ParseResult parse
angry = matchedPattern - 1;
else
tamed = matchedPattern == 3 ? -1 : 1;
if (exprs[0] != null)
collarColor = ((Literal<Color>) exprs[0]).getSingle().asDyeColor();
if (exprs[0] != null && variantsEnabled)
variant = ((Literal<Wolf.Variant>) exprs[0]).getSingle();
if (exprs[1] != null)
collarColor = ((Literal<Color>) exprs[1]).getSingle().asDyeColor();
return true;
}

Expand All @@ -58,6 +77,8 @@ protected boolean init(@Nullable Class<? extends Wolf> c, @Nullable Wolf wolf) {
angry = wolf.isAngry() ? 1 : -1;
tamed = wolf.isTamed() ? 1 : -1;
collarColor = wolf.getCollarColor();
if (variantsEnabled)
variant = wolf.getVariant();
}
return true;
}
Expand All @@ -70,11 +91,17 @@ public void set(Wolf entity) {
entity.setTamed(tamed == 1);
if (collarColor != null)
entity.setCollarColor(collarColor);
Object variantSet = null;
if (variantsEnabled) {
variantSet = variant != null ? variant : CollectionUtils.getRandom(variants);
entity.setVariant((Wolf.Variant) variantSet);
}
}

@Override
public boolean match(Wolf entity) {
return (angry == 0 || entity.isAngry() == (angry == 1)) && (tamed == 0 || entity.isTamed() == (tamed == 1)) && (collarColor == null ? true : entity.getCollarColor() == collarColor);
return (angry == 0 || entity.isAngry() == (angry == 1)) && (tamed == 0 || entity.isTamed() == (tamed == 1)) &&
(collarColor == null ? true : entity.getCollarColor() == collarColor) && (variant == null ? true : entity.getVariant() == variant);
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
}

@Override
Expand All @@ -88,6 +115,8 @@ protected int hashCode_i() {
result = prime * result + angry;
result = prime * result + tamed;
result = prime * result + (collarColor == null ? 0 : collarColor.hashCode());
if (variantsEnabled)
result = prime * result + (variant == null ? 0 : Objects.hashCode(variant));
return result;
}

Expand All @@ -102,6 +131,8 @@ protected boolean equals_i(EntityData<?> obj) {
return false;
if (collarColor != other.collarColor)
return false;
if (variantsEnabled && variant != other.variant)
return false;
return true;
}

Expand All @@ -127,7 +158,7 @@ protected boolean deserialize(String s) {
public boolean isSupertypeOf(EntityData<?> entityData) {
if (entityData instanceof WolfData) {
WolfData wolfData = (WolfData) entityData;
return (angry == 0 || wolfData.angry == angry) && (tamed == 0 || wolfData.tamed == tamed) && (wolfData.collarColor == collarColor);
return (angry == 0 || wolfData.angry == angry) && (tamed == 0 || wolfData.tamed == tamed) && (wolfData.collarColor == collarColor) && (variantsEnabled ? wolfData.variant == variant : true);
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved
}
return false;
}
Expand All @@ -137,4 +168,9 @@ public EntityData<Wolf> getSuperType() {
return new WolfData();
}

/**
* A dummy/placeholder class to ensure working operation on MC versions that do not have `Wolf.Variant`
*/
public static class VariantDummy {};

}
23 changes: 18 additions & 5 deletions src/main/resources/lang/default.lang
Original file line number Diff line number Diff line change
Expand Up @@ -795,19 +795,19 @@ entities:
pattern: wither skull((|1¦s)| projectile(|1¦s))
wolf:
name: wol¦f¦ves
pattern: <age> wol(f|1¦ves) [[with collar] colo[u]r[ed] %-color%]
pattern: <age> [%-wolfvariant%] wol(f|1¦ves) [[with collar] colo[u]r[ed] %-color%]
tamed wolf:
name: tamed wol¦f¦ves
pattern: (<age> dog(|1¦s)|tamed <age> wol(f|1¦ves)|(4¦)pupp(y|1¦ies)) [[with collar] colo[u]r[ed] %-color%]
pattern: (<age> [%-wolfvariant%] dog(|1¦s)|tamed <age> [%-wolfvariant%] wol(f|1¦ves)| [%-wolfvariant%] (4¦)pupp(y|1¦ies)) [[with collar] colo[u]r[ed] %-color%]
wild wolf:
name: wild wol¦f¦ves
pattern: (wild|untamed) <age> wol(f|1¦ves) [[with collar] colo[u]r[ed] %-color%]
pattern: (wild|untamed) <age> [%-wolfvariant%] wol(f|1¦ves) [[with collar] colo[u]r[ed] %-color%]
angry wolf:
name: angry wol¦f¦ves @an
pattern: (angry|aggressive) <age> wol(f|1¦ves) [[with collar] colo[u]r[ed] %-color%]
pattern: (angry|aggressive) <age> [%-wolfvariant%] wol(f|1¦ves) [[with collar] colo[u]r[ed] %-color%]
peaceful wolf:
name: peaceful wol¦f¦ves
pattern: (peaceful|neutral|unaggressive) <age> wol(f|1¦ves) [[with collar] colo[u]r[ed] %-color%]
pattern: (peaceful|neutral|unaggressive) <age> [%-wolfvariant%] wol(f|1¦ves) [[with collar] colo[u]r[ed] %-color%]
zombie:
name: zombie¦s
pattern: <age> zombie(|1¦s)|(4¦)zombie (kid(|1¦s)|child(|1¦ren))
Expand Down Expand Up @@ -1294,6 +1294,18 @@ cat types:
jellie: jellie
all_black: all black

# -- Wolf Variants --
wolf variants:
ashen: ashen
black: black
chestnut: chestnut
pale: pale
rusty: rusty
snowy: snowy
spotted: spotted
striped: striped
woods: woods

# -- Damage Causes --
damage causes:
contact: contact
Expand Down Expand Up @@ -2343,6 +2355,7 @@ types:
blockdata: block data¦s @a
healreason: heal reason¦s @a
cattype: cat type¦s @a
wolfvariant: wolf variant¦s @a
gamerule: gamerule¦s @a
attributetype: attribute type¦s @a
enchantmentoffer: enchantment offer¦s @an
Expand Down
16 changes: 15 additions & 1 deletion src/test/skript/tests/syntaxes/effects/EffSpawn.sk
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,18 @@ test "spawn cats by type" when running minecraft "1.15.2":
delete all siamese cats
assert size of all cats = 5 with "Size of all cats is not 5 after delete 2 siamese cats"
delete all cats
assert size of all cats = 0 with "Size of all cats is greater than 0 after all were deleted"
assert size of all cats = 0 with "Size of all cats is greater than 0 after all were deleted"

test "spawn wolves by variant" when running minecraft "1.21.0":
delete all wolves
set {_l} to location of spawn of world "world"
spawn 5 ashen wolves at {_l}
assert size of all wolves = 5 with "Size of all wolves is not 5"
assert size of all ashen wolves = 5 with "Size of all ashen wolves is not 5"
spawn 2 rusty wolves at {_l}
assert size of all wolves = 7 with "Size of all wolves is not 7"
assert size of all rusty wolves = 2 with "Size of all rusty wolves is not 2"
delete all rusty wolves
assert size of all wolves = 5 with "Size of all wolves is not 5 after delete 2 rusty wolves"
delete all wolves
assert size of all wolves = 0 with "Size of all wolves is greater than 0 after all were deleted"
TheAbsolutionism marked this conversation as resolved.
Show resolved Hide resolved