diff --git a/src/main/java/ch/njol/skript/effects/EffExit.java b/src/main/java/ch/njol/skript/effects/EffExit.java index f74b85b3589..31e469a2b74 100644 --- a/src/main/java/ch/njol/skript/effects/EffExit.java +++ b/src/main/java/ch/njol/skript/effects/EffExit.java @@ -2,6 +2,7 @@ import ch.njol.skript.Skript; import ch.njol.skript.classes.data.JavaClasses; +import ch.njol.skript.config.SectionNode; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Examples; import ch.njol.skript.doc.Name; @@ -15,6 +16,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnknownNullability; +import java.util.Collection; import java.util.List; @Name("Exit") @@ -88,6 +90,42 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye breakLevels = innerSections.size(); } } + + Collection delaySections = getParser().getDelaySections(); + + if (getParser().getCurrentSection(TriggerSection.class) instanceof Section currentSection + && currentSection.getNode() instanceof SectionNode currentNode) { + + // set hasDelay to false if the only delayed section is the current one + if (delaySections.size() == 1 && delaySections.contains(currentNode)) { + getParser().setHasDelayBefore(Kleenean.FALSE); + } + // set hasDelay to false if only child sections are delayed + else if (delaySections.size() >= 1) { + boolean isOnlyChildSectionsDelayed = true; + for (SectionNode delaySection : delaySections) { + if(delaySection == null) + continue; + // check if currentNode is parent of delaySection + boolean isChildSection = false; + SectionNode section = delaySection; + while (section.getParent() != null) { + section = section.getParent(); + if (section == currentNode) { + isChildSection = true; + break; + } + } + if (!isChildSection) { + isOnlyChildSectionsDelayed = false; + break; + } + } + if (isOnlyChildSectionsDelayed) + getParser().setHasDelayBefore(Kleenean.FALSE); + } + } + assert innerSections != null; sectionsToExit = innerSections.stream() .filter(SectionExitHandler.class::isInstance) diff --git a/src/main/java/ch/njol/skript/lang/parser/ParserInstance.java b/src/main/java/ch/njol/skript/lang/parser/ParserInstance.java index 268f2d13d17..92d63c0bdfb 100644 --- a/src/main/java/ch/njol/skript/lang/parser/ParserInstance.java +++ b/src/main/java/ch/njol/skript/lang/parser/ParserInstance.java @@ -5,10 +5,8 @@ import ch.njol.skript.SkriptAPIException; import ch.njol.skript.config.Config; import ch.njol.skript.config.Node; -import ch.njol.skript.lang.Expression; -import ch.njol.skript.lang.SkriptEvent; -import ch.njol.skript.lang.SkriptParser; -import ch.njol.skript.lang.TriggerSection; +import ch.njol.skript.config.SectionNode; +import ch.njol.skript.lang.*; import ch.njol.skript.log.HandlerList; import ch.njol.skript.structures.StructOptions.OptionsData; import ch.njol.skript.variables.HintManager; @@ -400,6 +398,7 @@ public final boolean isCurrentSection(Class... section // Delay API private Kleenean hasDelayBefore = Kleenean.FALSE; + private final Collection delaySectionNodes = new HashSet<>(); /** * This method should be called to indicate that @@ -409,6 +408,14 @@ public final boolean isCurrentSection(Class... section */ public void setHasDelayBefore(Kleenean hasDelayBefore) { this.hasDelayBefore = hasDelayBefore; + if (hasDelayBefore == Kleenean.TRUE + && getCurrentSection(TriggerSection.class) instanceof Section + && getCurrentSection(Section.class).getNode() instanceof SectionNode sectionNode) { + + delaySectionNodes.add(sectionNode); + } else if (hasDelayBefore == Kleenean.FALSE) { + delaySectionNodes.clear(); + } } /** @@ -422,6 +429,13 @@ public Kleenean getHasDelayBefore() { return hasDelayBefore; } + /** + * @return the sections from which a delay has occurred. + */ + public Collection getDelaySections() { + return delaySectionNodes; + } + // Logging API private final HandlerList handlers = new HandlerList();