diff --git a/src/main/java/ch/njol/skript/events/EvtFertilizeEgg.java b/src/main/java/ch/njol/skript/events/EvtFertilizeEgg.java new file mode 100644 index 00000000000..6504f47a3ec --- /dev/null +++ b/src/main/java/ch/njol/skript/events/EvtFertilizeEgg.java @@ -0,0 +1,74 @@ +package ch.njol.skript.events; + +import ch.njol.skript.entity.EntityType; +import ch.njol.skript.lang.Literal; +import ch.njol.skript.lang.SkriptEvent; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import io.papermc.paper.event.entity.EntityFertilizeEggEvent; +import org.bukkit.entity.Entity; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxRegistry; + +public class EvtFertilizeEgg extends SkriptEvent { + + public static void register(SyntaxRegistry registry) { + registry.register( + BukkitSyntaxInfos.Event.KEY, + BukkitSyntaxInfos.Event.builder(EvtFertilizeEgg.class, "Entity Fertilize") + .addEvent(EntityFertilizeEggEvent.class) + .addPatterns("[entity] fertiliz(e|ing) [an] egg [of %-entitytypes%]") + .addDescription( + "Called whenever an entity fertilizes an egg (e.g. a turtle has an egg, a frog becomes pregnant, or a " + + "sniffer finds a sniffer egg).") + .addExample(""" + on fertilizing egg of turtles: + broadcast "A turtle just fertilized an egg!" + """) + .addExample(""" + on fertilizing egg: + if event-entity is a frog: + broadcast "A frog just became pregnant!" + """) + .addSince("INSERT VERSION") + .supplier(EvtFertilizeEgg::new) + .build() + ); + } + + private @Nullable Literal entitiesLiteral; + private EntityType @Nullable [] entities; + + @Override + public boolean init(Literal[] args, int matchedPattern, ParseResult parseResult) { + if (args[0] != null) { + //noinspection unchecked + entitiesLiteral = ((Literal) args[0]); + entities = entitiesLiteral.getAll(); + } + return true; + } + + @Override + public boolean check(Event event) { + return event instanceof EntityFertilizeEggEvent fertilizeEvent && checkEntity(fertilizeEvent.getEntity()); + } + + private boolean checkEntity(Entity entity) { + if (entities != null) { + for (EntityType entityType : entities) { + if (entityType.isInstance(entity)) + return true; + } + return false; + } + return true; + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "on fertilizing egg" + (entitiesLiteral == null ? "" : " of " + entitiesLiteral.toString(event, debug)); + } + +} diff --git a/src/main/java/ch/njol/skript/events/SimpleEvents.java b/src/main/java/ch/njol/skript/events/SimpleEvents.java index 1da15c26671..83b6223a3c8 100644 --- a/src/main/java/ch/njol/skript/events/SimpleEvents.java +++ b/src/main/java/ch/njol/skript/events/SimpleEvents.java @@ -449,11 +449,12 @@ public class SimpleEvents { .description("Called when a horse jumps.") .examples("on horse jump:", "\tpush event-entity upwards at speed 2") .since("2.5.1"); - Skript.registerEvent("Block Fertilize", SimpleEvent.class, BlockFertilizeEvent.class, "[block] fertilize") - .description("Called when a player fertilizes blocks.") - .requiredPlugins("Minecraft 1.13 or newer") - .examples("on block fertilize:", - "\tsend \"Fertilized %size of fertilized blocks% blocks got fertilized.\"") + Skript.registerEvent("Block Fertilize", SimpleEvent.class, BlockFertilizeEvent.class, "[block] (fertilize|bone[ ]meal)") + .description("Called when a player uses bonemeals on blocks.") + .examples(""" + on block bonemeal: + send "%size of fertilized blocks% blocks got bonemealed." + """) .since("2.5"); Skript.registerEvent("Arm Swing", SimpleEvent.class, PlayerAnimationEvent.class, "[player] arm swing") .description("Called when a player swings their arm.") diff --git a/src/main/java/org/skriptlang/skript/bukkit/breeding/BreedingModule.java b/src/main/java/org/skriptlang/skript/bukkit/breeding/BreedingModule.java index 86bf152b78d..600ae7b7619 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/breeding/BreedingModule.java +++ b/src/main/java/org/skriptlang/skript/bukkit/breeding/BreedingModule.java @@ -1,10 +1,17 @@ package org.skriptlang.skript.bukkit.breeding; +import ch.njol.skript.classes.Changer.ChangeMode; +import ch.njol.skript.events.EvtFertilizeEgg; import ch.njol.skript.lang.util.SimpleEvent; import ch.njol.skript.registrations.EventValues; +import ch.njol.skript.util.Experience; +import io.papermc.paper.event.entity.EntityFertilizeEggEvent; +import org.bukkit.entity.Entity; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityEnterLoveModeEvent; +import org.bukkit.inventory.ItemStack; import org.skriptlang.skript.addon.AddonModule; import org.skriptlang.skript.addon.HierarchicalAddonModule; import org.skriptlang.skript.addon.SkriptAddon; @@ -15,6 +22,8 @@ import org.skriptlang.skript.bukkit.breeding.elements.events.EvtBreed; import org.skriptlang.skript.bukkit.breeding.elements.expressions.ExprBreedingFamily; import org.skriptlang.skript.bukkit.breeding.elements.expressions.ExprLoveTime; +import org.skriptlang.skript.bukkit.lang.eventvalue.EventValue; +import org.skriptlang.skript.bukkit.lang.eventvalue.EventValueRegistry; import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos; public class BreedingModule extends HierarchicalAddonModule { @@ -37,6 +46,7 @@ protected void loadSelf(SkriptAddon addon) { EffMakeAdultOrBaby::register, EvtBreed::register, + EvtFertilizeEgg::register, ExprBreedingFamily::register, ExprLoveTime::register @@ -59,6 +69,27 @@ protected void loadSelf(SkriptAddon addon) { EventValues.registerEventValue(EntityEnterLoveModeEvent.class, LivingEntity.class, EntityEnterLoveModeEvent::getEntity); EventValues.registerEventValue(EntityEnterLoveModeEvent.class, HumanEntity.class, EntityEnterLoveModeEvent::getHumanEntity); + + EventValueRegistry eventValueRegistry = addon.registry(EventValueRegistry.class); + eventValueRegistry.register( + EventValue.builder(EntityFertilizeEggEvent.class, Entity.class) + .getter(EntityFertilizeEggEvent::getEntity) + .excludedErrorMessage("Use 'mother' and/or 'father' in fertilize egg events") + .excludes(EntityFertilizeEggEvent.class) + .build() + ); + eventValueRegistry.register( + EventValue.simple(EntityFertilizeEggEvent.class, Player.class, EntityFertilizeEggEvent::getBreeder) + ); + eventValueRegistry.register( + EventValue.simple(EntityFertilizeEggEvent.class, ItemStack.class, EntityFertilizeEggEvent::getBredWith) + ); + eventValueRegistry.register( + EventValue.builder(EntityFertilizeEggEvent.class, Experience.class) + .getter(event -> new Experience(event.getExperience())) + .registerChanger(ChangeMode.SET, (event, value) -> event.setExperience(value.getXP())) + .build() + ); } @Override diff --git a/src/main/java/org/skriptlang/skript/bukkit/breeding/elements/expressions/ExprBreedingFamily.java b/src/main/java/org/skriptlang/skript/bukkit/breeding/elements/expressions/ExprBreedingFamily.java index 4d22275d194..b5130c59968 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/breeding/elements/expressions/ExprBreedingFamily.java +++ b/src/main/java/org/skriptlang/skript/bukkit/breeding/elements/expressions/ExprBreedingFamily.java @@ -5,10 +5,13 @@ import ch.njol.skript.doc.Example; import ch.njol.skript.doc.Name; import ch.njol.skript.doc.Since; +import ch.njol.skript.lang.EventRestrictedSyntax; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.util.Kleenean; +import ch.njol.util.coll.CollectionUtils; +import io.papermc.paper.event.entity.EntityFertilizeEggEvent; import org.bukkit.entity.LivingEntity; import org.bukkit.event.Event; import org.bukkit.event.entity.EntityBreedEvent; @@ -23,7 +26,7 @@ send "When a %breeding mother% and %breeding father% love each other very much, they make a %bred offspring%" to breeder """) @Since("2.10") -public class ExprBreedingFamily extends SimpleExpression { +public class ExprBreedingFamily extends SimpleExpression implements EventRestrictedSyntax { public static void register(SyntaxRegistry registry) { registry.register( @@ -45,27 +48,36 @@ public static void register(SyntaxRegistry registry) { @Override public boolean init(Expression[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { - if (!getParser().isCurrentEvent(EntityBreedEvent.class)) { - Skript.error("The 'breeding family' expression can only be used in an breed event."); + if (getParser().isCurrentEvent(EntityFertilizeEggEvent.class) && matchedPattern >= 2) { + Skript.error("The 'bred child' expression cannot be used in a 'fertilize egg' event."); return false; } - pattern = matchedPattern; return true; } @Override - protected @Nullable LivingEntity [] get(Event event) { - if (!(event instanceof EntityBreedEvent breedEvent)) - return new LivingEntity[0]; + public Class[] supportedEvents() { + return CollectionUtils.array(EntityBreedEvent.class, EntityFertilizeEggEvent.class); + } - return switch (pattern) { - case 0 -> new LivingEntity[]{breedEvent.getMother()}; - case 1 -> new LivingEntity[]{breedEvent.getFather()}; - case 2 -> new LivingEntity[]{breedEvent.getEntity()}; - case 3 -> new LivingEntity[]{breedEvent.getBreeder()}; - default -> new LivingEntity[0]; - }; + @Override + protected @Nullable LivingEntity [] get(Event event) { + if (event instanceof EntityBreedEvent breedEvent) + return switch (pattern) { + case 0 -> new LivingEntity[]{breedEvent.getMother()}; + case 1 -> new LivingEntity[]{breedEvent.getFather()}; + case 2 -> new LivingEntity[]{breedEvent.getEntity()}; + case 3 -> new LivingEntity[]{breedEvent.getBreeder()}; + default -> new LivingEntity[0]; + }; + else if (event instanceof EntityFertilizeEggEvent fertilizeEggEvent) + return switch (pattern) { + case 0 -> new LivingEntity[]{fertilizeEggEvent.getMother()}; + case 1 -> new LivingEntity[]{fertilizeEggEvent.getFather()}; + default -> new LivingEntity[0]; + }; + return new LivingEntity[0]; } @Override diff --git a/src/test/java/org/skriptlang/skript/test/tests/syntaxes/events/EvtFertilizeEggTest.java b/src/test/java/org/skriptlang/skript/test/tests/syntaxes/events/EvtFertilizeEggTest.java new file mode 100644 index 00000000000..7a1eb016602 --- /dev/null +++ b/src/test/java/org/skriptlang/skript/test/tests/syntaxes/events/EvtFertilizeEggTest.java @@ -0,0 +1,47 @@ +package org.skriptlang.skript.test.tests.syntaxes.events; + +import ch.njol.skript.test.runner.SkriptJUnitTest; +import io.papermc.paper.event.entity.EntityFertilizeEggEvent; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Frog; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.easymock.EasyMock; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class EvtFertilizeEggTest extends SkriptJUnitTest { + + static { + setShutdownDelay(1); + } + + private Frog mother; + private Frog father; + private Player player; + + @Before + public void before() { + mother = spawnTestEntity(EntityType.FROG); + father = spawnTestEntity(EntityType.FROG); + + player = EasyMock.niceMock(Player.class); + EasyMock.replay(player); + } + + @Test + public void test() { + Bukkit.getPluginManager().callEvent( + new EntityFertilizeEggEvent(mother, father, player, new ItemStack(Material.SLIME_BALL), 5)); + } + + @After + public void after() { + mother.remove(); + father.remove(); + } + +} diff --git a/src/test/skript/junit/EvtFertilizeEgg.sk b/src/test/skript/junit/EvtFertilizeEgg.sk new file mode 100644 index 00000000000..38a8fe0ed5b --- /dev/null +++ b/src/test/skript/junit/EvtFertilizeEgg.sk @@ -0,0 +1,30 @@ +options: + test: "org.skriptlang.skript.test.tests.syntaxes.events.EvtFertilizeEggTest" + +test "EvtFertilizeEggTest" when running Junit: + add "fertilize egg event - general" to {_evt::*} + add "fertilize egg event - specified entity" to {_evt::*} + add "fertilize egg event - mother" to {_evt::*} + add "fertilize egg event - father" to {_evt::*} + add "fertilize egg event - breeder is player" to {_evt::*} + add "fertilize egg event - item is slime ball" to {_evt::*} + add "fertilize egg event - experience is 5" to {_evt::*} + ensure junit test {@test} completes {_evt::*} + +on fertilize egg: + junit test is {@test} + complete objective "fertilize egg event - general" for {@test} + +on fertilize egg of frog: + junit test is {@test} + complete objective "fertilize egg event - specified entity" for {@test} + breeding mother is frog + complete objective "fertilize egg event - mother" for {@test} + breeding father is frog + complete objective "fertilize egg event - father" for {@test} + if event-player is a player: + complete objective "fertilize egg event - breeder is player" for {@test} + if event-item is slime ball: + complete objective "fertilize egg event - item is slime ball" for {@test} + if event-experience is 5: + complete objective "fertilize egg event - experience is 5" for {@test}