Skip to content

Commit 7e650c3

Browse files
Fix trigger terminating sections influencing delay behavior (#8518)
1 parent bd0a2e4 commit 7e650c3

File tree

5 files changed

+43
-20
lines changed

5 files changed

+43
-20
lines changed

src/main/java/ch/njol/skript/lang/ExecutionIntent.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
/**
1212
* Used to describe the intention of a {@link TriggerItem}.
13-
* As of now, it is only used to tell whether the item halts the execution or not and print the appropriate warnings.
1413
*
1514
* @see TriggerItem#executionIntent()
1615
*/

src/main/java/ch/njol/skript/lang/Section.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,16 @@ protected void loadCode(SectionNode sectionNode) {
8686
sections.add(this);
8787
parser.setCurrentSections(sections);
8888

89+
Kleenean hadDelayBefore = parser.getHasDelayBefore();
8990
try {
9091
setTriggerItems(ScriptLoader.loadItems(sectionNode));
9192
} finally {
93+
if (hadDelayBefore != parser.getHasDelayBefore()) { // the loaded elements caused a delay
94+
ExecutionIntent intent = triggerExecutionIntent();
95+
if (intent instanceof ExecutionIntent.StopTrigger) { // execution is guaranteed to stop, delay has no effect
96+
parser.setHasDelayBefore(hadDelayBefore);
97+
}
98+
}
9299
parser.setCurrentSections(previousSections);
93100
}
94101
}
@@ -176,12 +183,12 @@ protected final Trigger loadCode(SectionNode sectionNode, String name,
176183
* if the loaded section has a possible or definite delay in it.
177184
*/
178185
protected void loadOptionalCode(SectionNode sectionNode) {
179-
Kleenean hadDelayBefore = getParser().getHasDelayBefore();
186+
ParserInstance parser = getParser();
187+
Kleenean hadDelayBefore = parser.getHasDelayBefore();
180188
loadCode(sectionNode);
181-
if (hadDelayBefore.isTrue())
182-
return;
183-
if (!getParser().getHasDelayBefore().isFalse())
184-
getParser().setHasDelayBefore(Kleenean.UNKNOWN);
189+
if (!hadDelayBefore.isTrue() && !parser.getHasDelayBefore().isFalse()) {
190+
parser.setHasDelayBefore(Kleenean.UNKNOWN);
191+
}
185192
}
186193

187194
@Nullable

src/main/java/ch/njol/skript/sections/SecConditional.java

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public boolean init(Expression<?>[] exprs,
111111
* set {_uh oh} to true
112112
*/
113113
SecConditional precedingConditional = getPrecedingConditional(triggerItems, null);
114-
if (precedingConditional == null || !precedingConditional.multiline) {
114+
if (precedingConditional == null || !precedingConditional.multiline || precedingConditional.type == ConditionalType.THEN) {
115115
Skript.error("'then' has to placed just after a multiline 'if' or 'else if' section");
116116
return false;
117117
}
@@ -123,8 +123,6 @@ public boolean init(Expression<?>[] exprs,
123123
Skript.error("'else if' has to be placed just after another 'if' or 'else if' section");
124124
} else if (type == ConditionalType.ELSE) {
125125
Skript.error("'else' has to be placed just after another 'if' or 'else if' section");
126-
} else if (type == ConditionalType.THEN) {
127-
Skript.error("'then' has to placed just after a multiline 'if' or 'else if' section");
128126
}
129127
return false;
130128
}
@@ -386,27 +384,28 @@ private static List<SecConditional> getPrecedingConditionals(List<TriggerItem> t
386384
TriggerItem triggerItem = triggerItems.get(i);
387385
if (!(triggerItem instanceof SecConditional conditional))
388386
break;
389-
if (conditional.type == ConditionalType.ELSE)
390-
// if the conditional is an else, break because it belongs to a different condition and ends
391-
// this one
392-
break;
393387
conditionals.add(conditional);
388+
if (conditional.type == ConditionalType.IF)
389+
// if the conditional is an if, break because it is the root of our conditional
390+
break;
394391
}
395392
return conditionals;
396393
}
397394

398-
private static @Nullable Kleenean getPrecedingShouldDelayAfter(List<TriggerItem> triggerItems) {
395+
private @Nullable Kleenean getPrecedingShouldDelayAfter(List<TriggerItem> triggerItems) {
396+
if (this.type == ConditionalType.IF)
397+
// this is the head, meaning there is no preceding conditional
398+
return null;
399399
// loop through the triggerItems in reverse order so that we find the most recent items first
400400
for (int i = triggerItems.size() - 1; i >= 0; i--) {
401401
TriggerItem triggerItem = triggerItems.get(i);
402-
if (!(triggerItem instanceof SecConditional conditional))
402+
if (!(triggerItem instanceof SecConditional precedingSecConditional))
403403
break;
404-
if (conditional.type == ConditionalType.ELSE)
405-
// if the conditional is an else, break because it belongs to a different condition and ends
406-
// this one
404+
if (precedingSecConditional.shouldDelayAfter != null)
405+
return precedingSecConditional.shouldDelayAfter;
406+
if (precedingSecConditional.type == ConditionalType.IF)
407+
// this is the head of the conditional, meaning the search failed
407408
break;
408-
if (conditional.shouldDelayAfter != null)
409-
return conditional.shouldDelayAfter;
410409
}
411410
return null;
412411
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
test "section delays considering execution intent":
2+
parse:
3+
set {_var} to true
4+
if {_var} is true:
5+
wait 1 second
6+
stop
7+
assert has delay before is false with "delay carried beyond section"

src/test/skript/tests/syntaxes/sections/SecConditional.sk

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,17 @@ test "SecConditional - non-multiline conditional at the end":
179179
set {_a} to true
180180
assert {_a} is set with "non-multiline 'if' didn't run used at the end of a multiline 'if'"
181181

182+
test "SecConditional - repeating then sections":
183+
parse:
184+
if:
185+
1 is 1
186+
2 is 2
187+
then:
188+
stop
189+
then:
190+
stop
191+
assert last parse logs is "'then' has to placed just after a multiline 'if' or 'else if' section"
192+
182193
test "SecConditional - delay logic 1":
183194
assert has delay before is false with "should not have delay at start of test"
184195

0 commit comments

Comments
 (0)