mod common;
use delvewright_dsl::{DSL_VERSION, RawCampaign, check_campaign};
fn campaign_with(quests: &str) -> RawCampaign {
RawCampaign {
world: common::read_valid("world.json"),
npcs: common::read_valid("npcs.json"),
classes: common::read_valid("classes.json"),
quest_plan: common::read_valid("quest-plan.json"),
quests: quests.to_string(),
dialogue: common::read_valid("dialogue.json"),
world_edits: None,
geometry_brief: None,
layout_graph: None,
site_plan: None,
detail_plan: None,
design: None,
}
}
fn quests_with(trigger: &str) -> String {
format!(
r#"{{
"dsl_version": "{DSL_VERSION}",
"campaign_id": "hello-world",
"stage": "quests",
"content": {{
"quests": [
{{
"id": "quest/open-the-door",
"trigger": {{ "type": "campaign-start" }},
"objectives": [
{{ "type": "talk-to", "id": "obj/talk", "npc": "npc/keeper" }},
{{ "type": "reach-anchor", "id": "obj/exit", "anchor": "anchor/exit",
"radius": 2, "after": ["obj/talk"] }}
],
"on_objective_complete": {{
"obj/talk": [ {{ "type": "open-gate", "anchor": "anchor/door" }} ]
}},
"on_complete": [ {{ "type": "campaign-complete" }} ]
}}
],
"triggers": [ {trigger} ]
}}
}}"#
)
}
const NARRATE: &str = r#"[ { "type": "narrate", "style": "chat", "text": "He roars." } ]"#;
fn good_trigger() -> String {
format!(
r#"{{
"id": "trigger/wake",
"on": {{ "on": "strike-npc", "npc": "npc/keeper" }},
"effects": {NARRATE}
}}"#
)
}
#[test]
fn strike_npc_without_an_anchor_is_valid() {
let diags = check_campaign(&campaign_with(&quests_with(&good_trigger())));
assert!(
diags.is_empty(),
"a `strike-npc` trigger naming a declared NPC must validate clean: {diags:#?}"
);
}
#[test]
fn strike_npc_with_an_anchor_is_dw0194() {
let trigger = format!(
r#"{{
"id": "trigger/wake",
"at": "anchor/keeper-stand",
"on": {{ "on": "strike-npc", "npc": "npc/keeper" }},
"effects": {NARRATE}
}}"#
);
let diags = check_campaign(&campaign_with(&quests_with(&trigger)));
assert!(
diags.iter().any(|d| d.code == "DW0194"),
"an `at` on a `strike-npc` trigger must be DW0194: {diags:#?}"
);
}
#[test]
fn strike_without_an_anchor_is_dw0194() {
let trigger = format!(
r#"{{
"id": "trigger/ward",
"on": {{ "on": "strike" }},
"effects": {NARRATE}
}}"#
);
let diags = check_campaign(&campaign_with(&quests_with(&trigger)));
assert!(
diags.iter().any(|d| d.code == "DW0194"),
"a `strike` trigger with no `at` must be DW0194: {diags:#?}"
);
}
#[test]
fn strike_npc_targeting_an_unknown_npc_is_dw0112() {
let trigger = format!(
r#"{{
"id": "trigger/wake",
"on": {{ "on": "strike-npc", "npc": "npc/nobody" }},
"effects": {NARRATE}
}}"#
);
let diags = check_campaign(&campaign_with(&quests_with(&trigger)));
assert!(
diags.iter().any(|d| d.code == "DW0112"),
"an unknown `strike-npc` target must be DW0112: {diags:#?}"
);
}