feat: support switch-case replacements and definitions at root level#1459
feat: support switch-case replacements and definitions at root level#1459Pablete1234 merged 7 commits intoPGMDev:devfrom
Conversation
e8cd0a1 to
6135522
Compare
core/src/main/java/tc/oc/pgm/action/replacements/Replacement.java
Outdated
Show resolved
Hide resolved
core/src/main/java/tc/oc/pgm/action/replacements/Replacement.java
Outdated
Show resolved
Hide resolved
core/src/main/java/tc/oc/pgm/action/replacements/ReplacementParser.java
Outdated
Show resolved
Hide resolved
core/src/main/java/tc/oc/pgm/action/replacements/ReplacementParser.java
Outdated
Show resolved
Hide resolved
core/src/main/java/tc/oc/pgm/action/replacements/ReplacementParser.java
Outdated
Show resolved
Hide resolved
core/src/main/java/tc/oc/pgm/action/replacements/ReplacementParser.java
Outdated
Show resolved
Hide resolved
core/src/main/java/tc/oc/pgm/action/replacements/Replacement.java
Outdated
Show resolved
Hide resolved
core/src/main/java/tc/oc/pgm/action/replacements/ReplacementParser.java
Outdated
Show resolved
Hide resolved
6135522 to
64dc8f7
Compare
d2c9388 to
134a7b3
Compare
134a7b3 to
b9c28c2
Compare
a8c582a to
7ed2058
Compare
7ed2058 to
ac17739
Compare
e97f48a to
eeb41ed
Compare
c62a5c5 to
eeebf4e
Compare
c1d58cd to
2f38722
Compare
2f38722 to
9c2ae5d
Compare
9c2ae5d to
c7187eb
Compare
|
Testing with changes from this repo, with the exception of Grand Dueling and Chromatic Conquest which differ too much upstream for me to rebase the changes right now, everything seems to work as intended. |
fd4d849 to
27648ed
Compare
Adds support for switch-case style replacement in message actions, inspired by pattern matching found in modern programming languages, for example
```xml
<action filter="game=1"><message text="`3Up Next: `b[1] Hungry Reindeer"/></action>
<action filter="game=2"><message text="`3Up Next: `b[2] Present Hunt"/></action>
<action filter="game=3"><message text="`3Up Next: `b[3] Winter Speedway"/></action>
<action filter="game=4"><message text="`3Up Next: `b[4] Parkour"/></action>
<action filter="game=5"><message text="`3Up Next: `b[5] Chimney Sweepers"/></action>
<action filter="game=6"><message text="`3Up Next: `b[6] Frosted Corridors"/></action>
```
becomes
```xml
<message text="`3Up Next: `b[{game}] {game-name}">
<replacements>
<decimal id="game" value="game"/>
<switch id="game-name" value="game">
<case value="1" result="Hungry Reindeer"/>
<case value="2" result="Present Hunt"/>
<case value="3" result="Winter Speedway"/>
<case value="4" result="Parkour"/>
<case value="5" result="Chimney Sweepers"/>
<case value="6" result="Frosted Corridors"/>
</switch>
</replacements>
</message>
```
It is also possible to use them with filters:
```xml
<message text="The bomb has been planted on {bombsite} by {holder}">
<replacements>
<player id="holder" var="bomb_holder" fallback="an unknown player"/>
<switch id="bombsite">
<case filter="planted-a" result="`c${bombsite-a-name}"/>
<case filter="planted-b" result="`c${bombsite-b-name}"/>
</switch>
</replacements>
</message>
```
and also to mix them together:
```xml
<message text="Your score is {score} ({score_num})!">
<replacements>
<decimal id="score_num" value="score"/>
<switch id="score" value="score">
<case value="0..70" filter="only-attackers" result="`cvery low :("/>
<case value="0..70" filter="only-defenders" result="`9very low :(" />
<case value="70..100" filter="only-attackers" result="`clow :|"/>
<case value="70..100" filter="only-defenders" result="`9low :|" />
<case value="100..130" filter="only-attackers" result="`chigh :)"/>
<case value="100..130" filter="only-defenders" result="`9high :)" />
<fallback>off the charts :O</fallback>
</switch>
</replacements>
</message>
```
Signed-off-by: TTtie <me@tttie.cz>
…when parsing inline replacement Logical correctness is not guaranteed. Signed-off-by: TTtie <me@tttie.cz>
899e7bc to
1a2a9b8
Compare
core/src/main/java/tc/oc/pgm/util/xml/parsers/FilterBuilder.java
Outdated
Show resolved
Hide resolved
Instead of throwing a parsing error, the parser will now emit an unused node warning. Signed-off-by: TTtie <me@tttie.cz>
The usage of Filter#respondsTo hints that it is meant to be used with dynamic filters, which are covered by FilterBuilder#dynamic. This affects the behavior of the switch-case replacement by allowing any filter to be passed. This also means that filters that abstain will match if used in a case branch. Signed-off-by: TTtie <me@tttie.cz>
| var filter = parser.filter(innerEl, "filter").optional(() -> { | ||
| if (valueRange == null) | ||
| throw new InvalidXMLException( | ||
| "At least a filter or a match attribute must be specified", innerEl); | ||
| return StaticFilter.ALLOW; | ||
| }); |
There was a problem hiding this comment.
If you don't specify a value, and do specify a match, you could end up with a weird error message:
"Unused node 'match'" alongside an "At least a filter or a match..." which may leave you puzzled if you were a mapdev
maybe an option would be:
| var filter = parser.filter(innerEl, "filter").optional(() -> { | |
| if (valueRange == null) | |
| throw new InvalidXMLException( | |
| "At least a filter or a match attribute must be specified", innerEl); | |
| return StaticFilter.ALLOW; | |
| }); | |
| var filterParse = parser.filter(innerEl, "filter"); | |
| var filter = valueRange == null ? filterParse.required() : filterParse.orAllow(); |
which will just mark filter as required (without mentioning match at all) if you've not specified match.
not sure if it's really better or worse, maybe the err message should be different depending on if value is specified or not? i really don't know what's better
There was a problem hiding this comment.
If you don't specify a value, and do specify a match, you could end up with a weird error message:
"Unused node 'match'" alongside an "At least a filter or a match..." which may leave you puzzled if you were a mapdev
That will never happen. Parsing errors interrupt the whole map loading process, and unused node warnings are the very last step in that process. The error message probably needs a rewrite given that match="..." is ignored when there's no value though.
…atch is also unspecified Signed-off-by: TTtie <me@tttie.cz>
Child elements are also allowed, and in that case, the error wouldn't make sense Signed-off-by: TTtie <me@tttie.cz>
Adds support for switch-case style replacement in message actions, inspired by pattern matching found in modern programming languages, for example (preliminary syntax, some details may be subject to change):
Additionally, replacements can now be specified at the root level:
Launch checklist:
<case>than defined in<switch><action><switch>value