From d638d162db40e77b6439610b806b92313c352cf9 Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Sun, 13 Oct 2024 13:35:09 +1000 Subject: [PATCH] Adds domestication syntax (#6861) * Adds domestication syntax - An expression with changers - A test for the expression * Hopefully fixes tests * Apply suggestions from code review Co-authored-by: sovdee <10354869+sovdeeth@users.noreply.github.com> * Suggestions * Test suggestions * Removes reset changer and (hopefully) fixes tests * Suggestions * Suggestions * Adds domestication syntax - An expression with changers - A test for the expression * Hopefully fixes tests * Apply suggestions from code review Co-authored-by: sovdee <10354869+sovdeeth@users.noreply.github.com> * Suggestions * Test suggestions * Removes reset changer and (hopefully) fixes tests * Suggestions * Suggestions * Suggestions and some changes * Suggestion --------- Co-authored-by: sovdee <10354869+sovdeeth@users.noreply.github.com> Co-authored-by: Moderocky --- .../skript/expressions/ExprDomestication.java | 103 ++++++++++++++++++ .../syntaxes/expressions/ExprDomestication.sk | 86 +++++++++++++++ 2 files changed, 189 insertions(+) create mode 100644 src/main/java/ch/njol/skript/expressions/ExprDomestication.java create mode 100644 src/test/skript/tests/syntaxes/expressions/ExprDomestication.sk diff --git a/src/main/java/ch/njol/skript/expressions/ExprDomestication.java b/src/main/java/ch/njol/skript/expressions/ExprDomestication.java new file mode 100644 index 00000000000..d061030acfc --- /dev/null +++ b/src/main/java/ch/njol/skript/expressions/ExprDomestication.java @@ -0,0 +1,103 @@ +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.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.util.Kleenean; +import ch.njol.util.Math2; +import ch.njol.util.coll.CollectionUtils; +import org.bukkit.entity.AbstractHorse; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; + +@Name("Horse Domestication") +@Description({ + "Gets and/or sets the (max) domestication of a horse.", + "The domestication of a horse is how close a horse is to becoming tame - the higher the domestication, the closer they are to becoming tame (must be between 1 and the max domestication level of the horse).", + "The max domestication of a horse is how long it will take for a horse to become tame (must be greater than 0)." +}) +@Examples({ + "function domesticateAndTame(horse: entity, p: offline player, i: int = 10):", + "\tadd {_i} to domestication level of {_horse}", + "\tif domestication level of {_horse} >= max domestication level of {_horse}:", + "\t\ttame {_horse}", + "\t\tset tamer of {_horse} to {_p}" +}) +@Since("INSERT VERSION") +public class ExprDomestication extends SimplePropertyExpression { + + static { + register(ExprDomestication.class, Integer.class, "[:max[imum]] domestication level", "livingentities"); + } + + private boolean max; + + @Override + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + max = parseResult.hasTag("max"); + return super.init(exprs, matchedPattern, isDelayed, parseResult); + } + + @Override + public @Nullable Integer convert(LivingEntity entity) { + if (entity instanceof AbstractHorse horse) + return max ? horse.getMaxDomestication() : horse.getDomestication(); + return null; + } + + @Override + public @Nullable Class[] 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) { + assert mode != ChangeMode.REMOVE_ALL && mode != ChangeMode.DELETE; + + int change = delta == null ? 0 : ((Number) delta[0]).intValue(); + + for (LivingEntity entity : getExpr().getArray(event)) { + if (entity instanceof AbstractHorse horse) { + int level = max ? horse.getMaxDomestication() : horse.getDomestication(); + switch (mode) { + case SET -> level = change; + case ADD -> level += change; + case REMOVE -> level -= change; + case RESET -> level = 1; + default -> { + assert false; + return; + } + } + level = max ? Math.max(level, 1) : Math2.fit(1, level, horse.getMaxDomestication()); + if (max) { + horse.setMaxDomestication(level); + if (horse.getDomestication() > level) + horse.setDomestication(level); + } else { + horse.setDomestication(level); + } + } + } + } + + @Override + public Class getReturnType() { + return Integer.class; + } + + @Override + protected String getPropertyName() { + return (max ? "max " : "") + "domestication level"; + } + +} diff --git a/src/test/skript/tests/syntaxes/expressions/ExprDomestication.sk b/src/test/skript/tests/syntaxes/expressions/ExprDomestication.sk new file mode 100644 index 00000000000..005e8821dd0 --- /dev/null +++ b/src/test/skript/tests/syntaxes/expressions/ExprDomestication.sk @@ -0,0 +1,86 @@ +test "domestication": + spawn a horse at (spawn of world "world"): + set {_e} to entity + spawn a zombie at (spawn of world "world"): + set {_z} to entity + + # normal values, horse entity + set max domestication level of {_e} to 100 + set domestication level of {_e} to 50 + assert max domestication level of {_e} is 100 with "setting the max domestication of a horse should do exactly that" + assert domestication level of {_e} is 50 with "setting the domestication of a horse should do exactly that" + + add 10 to max domestication level of {_e} + add 10 to domestication level of {_e} + assert max domestication level of {_e} is 110 with "adding to the max domestication of a horse should do exactly that" + assert domestication level of {_e} is 60 with "adding to the domestication of a horse should do exactly that" + + subtract 10 from max domestication level of {_e} + subtract 10 from domestication level of {_e} + assert max domestication level of {_e} is 100 with "removing from the max domestication of a horse should do exactly that" + assert domestication level of {_e} is 50 with "removing from the domestication of a horse should do exactly that" + + subtract 60 from max domestication level of {_e} + assert domestication level of {_e} is 40 with "removing from the max domestication level of a horse should also clamp the domestication level if need be" + + reset max domestication level of {_e} + reset domestication level of {_e} + assert max domestication level of {_e} is 1 with "resetting the max domestication of a horse should do exactly that" + assert domestication level of {_e} is 1 with "resetting the domestication of a horse should do exactly that" + + set domestication level of {_e} to (max domestication level of {_e}) + 1 + add 100 to domestication level of {_e} + assert domestication level of {_e} is (max domestication level of {_e}) with "the domestication level of a horse should never exceed it's max domestication level" + + set domestication level of {_e} to 0 + subtract 100 from domestication level of {_e} + assert domestication level of {_e} is 1 with "the domestication level of a horse should never be less than 1" + + set max domestication level of {_e} to 0 + subtract 100 from max domestication level of {_e} + assert max domestication level of {_e} is 1 with "the max domestication level of a horse should never be less than 1" + + # infinity values + add infinity value to max domestication level of {_e} + assert max domestication level of {_e} is 1 with "infinity value shouldn't affect the max domestication level of a horse when added" + subtract infinity value from max domestication level of {_e} + assert max domestication level of {_e} is 1 with "infinity value should result in 1 when subtracted from the max domestication level of a horse" + set max domestication level of {_e} to infinity value # set is done last so the domestication level tests can also go to infinity + assert max domestication level of {_e} is 2147483647 with "infinity value should set the max domestication level of a horse to the max integer value" + + add infinity value to domestication level of {_e} + assert domestication level of {_e} is 1 with "infinity value shouldn't affect the domestication level of a horse when added" + subtract infinity value from domestication level of {_e} + assert domestication level of {_e} is 1 with "infinity value should result in 1 when subtracted from the domestication level of a horse" + set domestication level of {_e} to infinity value + assert domestication level of {_e} is 2147483647 with "infinity value should set the domestication level of a horse to the max integer value" + + # NaN values + add NaN value to max domestication level of {_e} + assert max domestication level of {_e} is 2147483647 with "NaN value should result in 2147483647 when added to the max domestication level of a horse" + set max domestication level of {_e} to NaN value + assert max domestication level of {_e} is 1 with "NaN value should result in 1 when used to set the max domestication level of a horse" + subtract NaN value from max domestication level of {_e} + assert max domestication level of {_e} is 1 with "NaN value should not allow the max domestication level of a horse to drop below 1" + + add NaN value to domestication level of {_e} + assert domestication level of {_e} is 1 with "NaN value should result in 1 when used to change the domestication level of a horse" + set domestication level of {_e} to NaN value + assert domestication level of {_e} is 1 with "NaN value should result in 1 when used to set the domestication level of a horse" + subtract NaN value from domestication level of {_e} + assert domestication level of {_e} is 1 with "NaN value should result in 1 when used to change the domestication level of a horse" + + # non-horse entity + assert max domestication level of {_z} is not set with "the max domestication of a non-horse should be null" + assert domestication level of {_z} is not set with "the domestication of a non-horse should be null" + set max domestication level of {_z} to 1 + set domestication level of {_z} to 1 + add 1 to max domestication level of {_z} + add 1 to domestication level of {_z} + subtract 1 from max domestication level of {_z} + subtract 1 from domestication level of {_z} + assert max domestication level of {_z} is not set with "changing the max domestication of a non-horse should do nothing" + assert domestication level of {_z} is not set with "changing the domestication of a non-horse should do nothing" + + delete entity within {_e} + delete entity within {_z}