diff --git a/src/main/java/org/ladysnake/blabber/impl/common/model/ChoiceResult.java b/src/main/java/org/ladysnake/blabber/impl/common/model/ChoiceResult.java index 744eae6..8b72d50 100644 --- a/src/main/java/org/ladysnake/blabber/impl/common/model/ChoiceResult.java +++ b/src/main/java/org/ladysnake/blabber/impl/common/model/ChoiceResult.java @@ -18,5 +18,15 @@ package org.ladysnake.blabber.impl.common.model; public enum ChoiceResult { - DEFAULT, END_DIALOGUE, ASK_CONFIRMATION + DEFAULT(true), END_DIALOGUE(false), ASK_CONFIRMATION(false); + + private final boolean allowsIllustrations; + + ChoiceResult(boolean allowsIllustrations) { + this.allowsIllustrations = allowsIllustrations; + } + + public boolean allowsIllustrations() { + return this.allowsIllustrations; + } } diff --git a/src/main/java/org/ladysnake/blabber/impl/common/validation/DialogueValidator.java b/src/main/java/org/ladysnake/blabber/impl/common/validation/DialogueValidator.java index 77527bb..e1bacd4 100644 --- a/src/main/java/org/ladysnake/blabber/impl/common/validation/DialogueValidator.java +++ b/src/main/java/org/ladysnake/blabber/impl/common/validation/DialogueValidator.java @@ -52,6 +52,10 @@ public static ValidationResult validateStructure(DialogueTemplate dialogue) { ); } } + // TODO Java 21 replace with pattern matching switch to handle all possible results + if (validateIllustrations(dialogue, state) instanceof ValidationResult.Error error) { + return error; + } } while (!waitList.isEmpty()) { @@ -91,16 +95,31 @@ public static ValidationResult validateStructure(DialogueTemplate dialogue) { // Verify that all illustrations are real. We're doing this here because this is a class and not a record // So we have our own constructor. for (Map.Entry state : dialogue.states().entrySet()) { - for (String illustration : state.getValue().illustrations()) { - if (!dialogue.illustrations().containsKey(illustration)) { - return new ValidationResult.Error.NonexistentIllustration(state.getKey(), illustration); - } - } } return warnings.isEmpty() ? ValidationResult.success() : new ValidationResult.Warnings(warnings); } + private static ValidationResult validateIllustrations(DialogueTemplate dialogue, Map.Entry state) { + List illustrations = new ArrayList<>(state.getValue().illustrations()); + + for (DialogueChoice c : state.getValue().choices()) { + illustrations.addAll(c.illustrations()); + } + + if (!illustrations.isEmpty() && !state.getValue().type().allowsIllustrations()) { + return new ValidationResult.Error.InvalidIllustratedState(state.getKey(), state.getValue().type(), illustrations); + } + + for (String illustration : illustrations) { + if (!dialogue.illustrations().containsKey(illustration)) { + return new ValidationResult.Error.NonexistentIllustration(state.getKey(), illustration); + } + } + + return ValidationResult.success(); + } + private enum Reachability { NONE, CONDITIONAL, diff --git a/src/main/java/org/ladysnake/blabber/impl/common/validation/ValidationResult.java b/src/main/java/org/ladysnake/blabber/impl/common/validation/ValidationResult.java index 8c791db..1e5c0ad 100644 --- a/src/main/java/org/ladysnake/blabber/impl/common/validation/ValidationResult.java +++ b/src/main/java/org/ladysnake/blabber/impl/common/validation/ValidationResult.java @@ -17,6 +17,8 @@ */ package org.ladysnake.blabber.impl.common.validation; +import org.ladysnake.blabber.impl.common.model.ChoiceResult; + import java.util.List; import java.util.stream.Collectors; @@ -80,5 +82,12 @@ public String message() { return state() + " references non-existent illustration " + illustration(); } } + + record InvalidIllustratedState(String state, ChoiceResult type, List illustrations) implements Error { + @Override + public String message() { + return state() + " of type " + type + " is not allowed to use illustrations " + illustrations(); + } + } } }