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

Add villager expressions #7250

Merged
merged 22 commits into from
Dec 24, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
d51c7e7
Villager stuff
ShaneBeee Dec 10, 2024
b9d4141
ExprBiome.sk - removed, due to comparator issue
ShaneBeee Dec 10, 2024
8351e74
More changes
ShaneBeee Dec 10, 2024
e217c4e
Comparators - add default comparators for Registry/Enum class infos
ShaneBeee Dec 10, 2024
2d82044
Merge branch 'feature/default-comparators' into feature/villager-stuff
ShaneBeee Dec 10, 2024
b95203b
Remove comparators and ClassUtils.java
ShaneBeee Dec 10, 2024
6689d58
DefaultComparators - revert changes to this class
ShaneBeee Dec 10, 2024
21fecf6
DefaultComparators - stop removing this IJ, we dont need this change,…
ShaneBeee Dec 10, 2024
3416ae6
ExprVillagerLevel - update docs
ShaneBeee Dec 10, 2024
1da125d
Merge branch 'dev/feature' into feature/villager-stuff
Moderocky Dec 15, 2024
06700d9
MathUtils.java - remove
ShaneBeee Dec 15, 2024
69b1b50
ExprVillagerLevel - remove delete
ShaneBeee Dec 15, 2024
650ec8d
default.lang - remove "none" as it may cause conflicts
ShaneBeee Dec 15, 2024
ffb22b3
Merge remote-tracking branch 'origin/feature/villager-stuff' into fea…
ShaneBeee Dec 15, 2024
4475167
default.lang - re-order "none" profession
ShaneBeee Dec 15, 2024
9032a5d
Update src/main/java/ch/njol/skript/expressions/ExprVillagerLevel.java
ShaneBeee Dec 18, 2024
fb4cfe7
Update src/main/java/ch/njol/skript/expressions/ExprVillagerType.java
ShaneBeee Dec 18, 2024
c6a6ed2
Update src/main/java/ch/njol/skript/classes/data/BukkitClasses.java
ShaneBeee Dec 18, 2024
d38de37
Merge branch 'dev/feature' into feature/villager-stuff
ShaneBeee Dec 20, 2024
024b414
EnumClassInfo - remove line i accidentally created
ShaneBeee Dec 20, 2024
820d1ea
Merge branch 'dev/feature' into feature/villager-stuff
Moderocky Dec 24, 2024
c1d6283
Merge branch 'dev/feature' into feature/villager-stuff
Moderocky Dec 24, 2024
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: 4 additions & 0 deletions src/main/java/ch/njol/skript/classes/EnumClassInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import ch.njol.util.coll.iterator.ArrayIterator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.skriptlang.skript.lang.comparator.Comparators;
import org.skriptlang.skript.lang.comparator.Relation;

/**
* This class can be used for an easier writing of ClassInfos that are enums,
Expand Down Expand Up @@ -55,6 +57,8 @@ public EnumClassInfo(Class<T> enumClass, String codeName, String languageNode, D
return enumUtils.toString(constant, StringMode.VARIABLE_NAME);
}
});

Comparators.registerComparator(enumClass, enumClass, (o1, o2) -> Relation.get(o1.ordinal() - o2.ordinal()));
}

}
14 changes: 14 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 @@ -68,6 +68,7 @@
import org.bukkit.enchantments.Enchantment;
import org.bukkit.enchantments.EnchantmentOffer;
import org.bukkit.entity.Cat;
import org.bukkit.entity.Villager;
import org.bukkit.entity.Wolf;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
Expand Down Expand Up @@ -1565,6 +1566,19 @@ public String toVariableNameString(EnchantmentOffer eo) {
.name("Experience Cooldown Change Reason")
.description("Represents a change reason of an <a href='events.html#experience cooldown change event'>experience cooldown change event</a>.")
.since("INSERT VERSION"));

Classes.registerClass(new RegistryClassInfo<>(Villager.Type.class, Registry.VILLAGER_TYPE, "villagertype", "villager types")
.user("villager ?types?")
.name("Villager Type")
.description("Represents the different types of villagers. These are usually the biomes a villager can be from.")
.after("biome")
.since("INSERT VERSION"));

Classes.registerClass(new RegistryClassInfo<>(Villager.Profession.class, Registry.VILLAGER_PROFESSION, "villagerprofession", "villager professions")
.user("villager ?professions?")
.name("Villager Profession")
.description("Represents the different professions of villagers.")
.since("INSERT VERSION"));
}

}
Original file line number Diff line number Diff line change
@@ -1,28 +1,12 @@
/**
* 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;
import org.skriptlang.skript.lang.comparator.Comparators;
import org.skriptlang.skript.lang.comparator.Relation;

/**
* This class can be used for easily creating ClassInfos for {@link Registry}s.
Expand All @@ -48,6 +32,8 @@ public RegistryClassInfo(Class<R> registryClass, Registry<R> registry, String co
.serializer(new RegistrySerializer<R>(registry))
.defaultExpression(defaultExpression)
.parser(registryParser);

Comparators.registerComparator(registryClass, registryClass, (o1, o2) -> Relation.get(o1.getKey() == o2.getKey()));
}

}
92 changes: 92 additions & 0 deletions src/main/java/ch/njol/skript/expressions/ExprVillagerLevel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package ch.njol.skript.expressions;

import ch.njol.skript.Skript;
import ch.njol.skript.classes.Changer.ChangeMode;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.expressions.base.SimplePropertyExpression;
import ch.njol.util.Math2;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Villager;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;

@Name("Villager Level")
@Description({
"Represents the level of a villager.",
"Level must be between 1 and 5, with 1 being the default level.",
"Do note when a villager's level is 1, they may lose their profession."})
@Examples({
"set {_level} to villager level of {_villager}",
"set villager level of last spawned villager to 2",
"add 1 to villager level of target entity",
"remove 1 from villager level of event-entity",
"reset villager level of event-entity"
})
@Since("INSERT VERSION")
public class ExprVillagerLevel extends SimplePropertyExpression<LivingEntity, Number> {

private static final boolean HAS_INCREASE_METHOD = Skript.methodExists(Villager.class, "increaseLevel", int.class);

static {
register(ExprVillagerLevel.class, Number.class, "villager level", "livingentities");
}

@Override
public @Nullable Number convert(LivingEntity from) {
if (from instanceof Villager villager)
return villager.getVillagerLevel();
return null;
}

@Override
public Class<?> @Nullable [] acceptChange(ChangeMode mode) {
return switch (mode) {
case SET, ADD, REMOVE, RESET ->
CollectionUtils.array(Number.class);
default -> null;
};
}

@Override
public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
Number number = delta != null && delta[0] instanceof Number num ? num : 1;
int changeValue = number.intValue();

for (LivingEntity livingEntity : getExpr().getArray(event)) {
if (!(livingEntity instanceof Villager villager)) continue;

int previousLevel = villager.getVillagerLevel();
int newLevel = switch (mode) {
case SET -> changeValue;
case ADD -> previousLevel + changeValue;
case REMOVE -> previousLevel - changeValue;
default -> 1;
};
newLevel = Math2.fit(1, newLevel, 5);
if (newLevel > previousLevel && HAS_INCREASE_METHOD) {
int increase = Math2.fit(1, newLevel - previousLevel, 5);
// According to the docs for this method:
// Increases the level of this villager.
// The villager will also unlock new recipes unlike the raw 'setVillagerLevel' method
villager.increaseLevel(increase);
} else {
villager.setVillagerLevel(newLevel);
}
}
}

@Override
protected String getPropertyName() {
return "villager level";
}

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

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package ch.njol.skript.expressions;

import ch.njol.skript.classes.Changer.ChangeMode;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.expressions.base.SimplePropertyExpression;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Villager;
import org.bukkit.entity.Villager.Profession;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;

@Name("Villager Profession")
@Description("Represents the profession of a villager.")
@Examples({
"set {_p} to villager profession of event-entity",
"villager profession of event-entity = nitwit profession",
"set villager profession of {_villager} to librarian profession",
"delete villager profession of event-entity"
})
@Since("INSERT VERSION")
public class ExprVillagerProfession extends SimplePropertyExpression<LivingEntity, Profession> {

static {
register(ExprVillagerProfession.class, Profession.class, "villager profession", "livingentities");
}

@Override
public @Nullable Profession convert(LivingEntity from) {
if (from instanceof Villager villager)
return villager.getProfession();
return null;
}

@Override
public Class<?> @Nullable [] acceptChange(ChangeMode mode) {
return switch (mode) {
case SET, DELETE -> CollectionUtils.array(Profession.class);
default -> null;
};
}

@Override
public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
Profession profession = delta != null && delta[0] instanceof Profession pro ? pro : Profession.NONE;

for (LivingEntity livingEntity : getExpr().getArray(event)) {
if (livingEntity instanceof Villager villager)
villager.setProfession(profession);
}
}

@Override
protected String getPropertyName() {
return "villager profession";
}

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

}
66 changes: 66 additions & 0 deletions src/main/java/ch/njol/skript/expressions/ExprVillagerType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package ch.njol.skript.expressions;

import ch.njol.skript.classes.Changer.ChangeMode;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.expressions.base.SimplePropertyExpression;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Villager;
import org.bukkit.entity.Villager.Type;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;

@Name("Villager Type")
@Description("Represents the type of a villager. This usually represents the biome the villager is from.")
@Examples({
"set {_type} to villager type of {_villager}",
"villager type of {_villager} = plains",
"set villager type of event-entity to plains"
})
@Since("INSERT VERSION")
public class ExprVillagerType extends SimplePropertyExpression<LivingEntity, Type> {

static {
register(ExprVillagerType.class, Type.class, "villager type", "livingentities");
}

@Override
public @Nullable Type convert(LivingEntity from) {
if (from instanceof Villager villager)
return villager.getVillagerType();
return null;
}

@Override
public Class<?> @Nullable [] acceptChange(ChangeMode mode) {
if (mode == ChangeMode.SET)
return CollectionUtils.array(Type.class);
return null;
}

@Override
public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
Type type = delta != null && delta[0] instanceof Type t ? t : null;
if (type == null)
return;

for (LivingEntity livingEntity : getExpr().getArray(event)) {
if (livingEntity instanceof Villager villager)
villager.setVillagerType(type);
}
}

@Override
protected String getPropertyName() {
return "villager type";
}

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

}
30 changes: 30 additions & 0 deletions src/main/resources/lang/default.lang
Original file line number Diff line number Diff line change
Expand Up @@ -2426,6 +2426,34 @@ item display transforms:
thirdperson_lefthand: third person left handed, third person left hand, left handed in third person
thirdperson_righthand: third person right handed, third person right hand, right handed in third person

# -- Villager Types/Professions --
villager types:
snow: snow
plains: plains
jungle: jungle
taiga: taiga
desert: desert
savanna: savanna
swamp: swamp

villager professions:
# Suffix "profession" options added to help with EntityData conflicts
leatherworker: leatherworker, leatherworker profession
mason: mason, mason profession
fletcher: fletcher, fletcher profession
weaponsmith: weaponsmith, weaponsmith profession
toolsmith: toolsmith, toolsmith profession
librarian: librarian, librarian profession
shepherd: shepherd, shepherd profession
farmer: farmer, farmer profession
cleric: cleric, cleric profession
nitwit: nitwit, nitwit profession
cartographer: cartographer, cartographer profession
armorer: armorer, armorer profession
butcher: butcher, butcher profession
none: no profession, none profession, unemployed
fisherman: fisherman, fisherman profession

# -- Change Reasons --
experience cooldown change reasons:
plugin: plugin
Expand Down Expand Up @@ -2529,6 +2557,8 @@ types:
itemdisplaytransform: item display transform¦s @an
experiencecooldownchangereason: experience cooldown change reason¦s @a
inputkey: input key¦s @an
villagertype: villager type¦s @a
villagerprofession: villager profession¦s @a

# Skript
weathertype: weather type¦s @a
Expand Down
24 changes: 24 additions & 0 deletions src/test/skript/tests/misc/registry-enum-comparators.sk
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
test "registry and enum comparators":
# We're using loops because that is when Skript appears to hate comparing things
# Example errors when Skript doesn't have explicit comparators:
# 'Can't compare a biome with a biome'
# 'Can't compare a attribute type with a attribute type'


# Compare registry entries
loop all biomes:
if loop-value = plains:
assert loop-value = plains with "Should be able to compare biomes"

loop all attribute types:
if loop-value = generic movement speed:
assert loop-value = generic movement speed with "Should be able to compare attribute types"

# Compare enum entries
loop all teleport causes:
if loop-value = ender pearl:
assert loop-value = ender pearl with "Should be able to compare teleport causes"

loop all spawn reasons:
if loop-value = jockey:
assert loop-value = jockey with "Should be able to compare spawn reasons"
Loading
Loading