TDG: add to schema, and fix schema issues (#9786)

While adding TDG to mainline, I missed adding it to the schema. As a result, a lot of issues went unnoticed.

This PR adds TDG to the schema, and fixes the various discovered errors. This PR also updates the schema to reflect the engine supporting multiple [filter] tags in events, and to reflect the engine supporting [change_theme] without keys.
This commit is contained in:
Dalas121 2025-01-21 19:50:18 -06:00 committed by GitHub
parent 78b86777b5
commit 74da2a1724
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 100 additions and 67 deletions

View File

@ -104,7 +104,11 @@
id,name,canrecruit=Leollyn,_"Leollyn",yes
[modifications]
[trait]
id,name,description=loyal_dummy,loyal,_"Zero upkeep."
#textdomain wesnoth-help
id=loyal_dummy
name=_"loyal"
description=_"Zero upkeep."
#textdomain wesnoth-tdg
[/trait]
{TRAIT_INTELLIGENT}
[/modifications]

View File

@ -93,7 +93,7 @@
[event]
name=side 2 turn
first_time_only=no
{RESET_SIDE_AI 2,3,4,5,6,7,8,9,10 aggressive 0.4 0.25}
{RESET_SIDE_AI 2,3,4,5,6,7,8,9,10 offensive 0.4 0.25}
{VARY_AI_BY_SCHEDULE 3,4,5,6,7,8,9,10} # don't vary side 2; when he goes aggro he goes all-in
[/event]

View File

@ -494,7 +494,6 @@ Bowmen are weaker at range than mages, but are cheaper, tougher, and less helple
[event]
name=attack
{FILTER race=goblin} {FILTER_SECOND side=5}
{FILTER_CONDITION race,x,y,count=goblin,18-99,0-99,3-99}
[message]
speaker=Garard
#po: a goblin has just attacked one of Garard's horsemen. Garard previously told Methor to guard against the goblins, but Delfador led the guards to battle instead

View File

@ -416,7 +416,7 @@ Movement is lost even when revealing level 0 Wose Saplings, who normally (like a
#############################
[event]
name=moveto
{FILTER id,side,x,y,count=Delfador,1,23-25,1,3}
{FILTER id,side,x,y=Delfador,1,23-25,1}
{WOSE_ENDING
#po: peaceful gibberish, spoken by a random wose
_"<span size='x-small'>Hoom. Oom-shoosh-ola-hum-rum-tum...</span>"

View File

@ -392,7 +392,8 @@ In many places there is no path at all, and Delfador senses they are guided more
speaker=narrator
message=_"The sun sets like a dying ember quenched beneath the horizon, and the forest grows dim. Several times even Kalenz becomes lost, but each time manages to find the way again. At last, in the dead of night, a small structure looms out of the forest..."
[/message]
[change_theme] # back to default
[change_theme]
theme= # back to default
[/change_theme]
{REPLACE_SCENARIO_MUSIC into_the_shadows.ogg}
{APPEND_MUSIC phase_shift.ogg}
@ -428,7 +429,7 @@ In many places there is no path at all, and Delfador senses they are guided more
[event]
name=moveto {FILTER side,y=1,0-15}
[remove_shroud]
side,x,y,radius=1,13,10,3}
side,x,y,radius=1,13,10,3
[/remove_shroud]
{SCROLL_TO 13 10}
[message]

View File

@ -147,7 +147,7 @@
[event]
name=side 3 turn
first_time_only=no
{RESET_SIDE_AI 3,4,6,7 aggressive 0.8 0.2}
{RESET_SIDE_AI 3,4,6,7 offensive 0.8 0.2}
{MODIFY_SIDE_AI 3,4,6,7 ({GOAL_LOCATION 99 x,y=17,12})}
{VARY_AI_BY_SCHEDULE_ENEMY 3,4,5,6,7 1,2}
{MODIFY_SIDE_AI 6 (
@ -820,9 +820,9 @@ Fencers are fragile but evasive, and posssess the “<i>skirmisher</i>” abilit
{GENERIC_UNIT 3 "Orcish Nightblade" 14 15} {FACING se} {ROLE killer} {ANIMATE}
{DELAY 500}
{KILL role=killer}
{FAKE_UNIT_MOVE 14 15 15 16 3 "Orcish Nightblade" facing=se}
{FAKE_UNIT_MOVE 15 17 16 15 3 "Orcish Nightblade" facing=se}
{FAKE_UNIT_MOVE 17 17 15 14 3 "Orcish Nightblade" facing=se}
{FAKE_UNIT_MOVE 14 15 15 16 3 "Orcish Nightblade" ()}
{FAKE_UNIT_MOVE 15 17 16 15 3 "Orcish Nightblade" ()}
{FAKE_UNIT_MOVE 17 17 15 14 3 "Orcish Nightblade" ()}
{GENERIC_UNIT 3 "Orcish Nightblade" 17 14} {FACING se} {ROLE killer}
[message]
speaker=Lionel

View File

@ -82,7 +82,7 @@
[unstore_unit]
variable=stored_deoran
side,x,y=2,10,10
x,y=10,10
[/unstore_unit]
{MODIFY_UNIT id=Deoran facing nw}
{GIVE_OBJECT_TO id=Deoran ({EFFECT profile portrait,small_portrait=portraits/deoran-older.webp,portraits/deoran-older.webp})}

View File

@ -387,7 +387,7 @@
side,x,y,radius=1,{X},{Y},1
[/remove_shroud]
[lift_fog]
side,x,y,radius=1,{X},{Y},1
x,y,radius={X},{Y},1
[/lift_fog]
{DELAY {MS}}
#enddef
@ -951,7 +951,7 @@
side,x,y,radius=1,17,26,6
[/remove_shroud]
[lift_fog]
side,x,y,radius=1,17,26,6
x,y,radius=17,26,6
[/lift_fog]
[message]

View File

@ -334,7 +334,8 @@
[heal_unit]
{FILTER side=1}
amount=full
moves,restore_attacks=full,1
moves=full
restore_attacks=yes
[/heal_unit]
#############################
@ -425,6 +426,7 @@
{CLEAR_VARIABLE stored_s09a_units}
{MODIFY_UNIT side=1 facing nw} # otherwise teleport makes them all face se
[reset_fog]
{FILTER_SIDE side=1}
reset_view=yes
[/reset_fog]
{REDRAW}
@ -618,9 +620,11 @@ IT WILL DIE."
#############################
#define INITIALIZE_CAVE ID X Y
{NAMED_UNIT 2 (Cave Entrance) {X} {Y} {ID} "" (
[object]
{EFFECT status add=unhealable}
[/object]
[modifications]
[object]
{EFFECT status add=unhealable}
[/object]
[/modifications]
)}
#------------------------
@ -947,7 +951,8 @@ IT WILL DIE."
{REDRAW}
{REMOVE_OBJECT bonus_vision ()}
[reset_fog] # fog was already close; don't let it expand again
side,reset_view=1,yes
{FILTER_SIDE side=1}
reset_view=yes
[/reset_fog]
{REDRAW}
{SOUND magic-dark-big-miss.ogg} {DELAY 750}
@ -965,10 +970,10 @@ IT WILL DIE."
# ZOMBIES APPEAR
#############################
#define SHOW_ZOMBIE_EMERGING X Y SND X2 Y2
{SCROLL_TO X Y}
{SCROLL_TO {X} {Y}}
{DELAY 250}
[lift_fog]
side,x,y,radius=1,{X},{Y},1
x,y,radius={X},{Y},1
[/lift_fog]
[remove_shroud]
side,x,y,radius=1,{X},{Y},1

View File

@ -99,13 +99,15 @@
{DELAY 500}
[unstore_unit]
variable=stored_delfador
x,y,facing,animate=1,32,ne,yes
x,y,animate=1,32,yes
[/unstore_unit]
{MODIFY_UNIT id=Delfador facing ne}
{CLEAR_VARIABLE stored_delfador}
[heal_unit]
{FILTER side=1}
amount=full
moves,restore_attacks=full,1
moves=full
restore_attacks=yes
[/heal_unit]
{REFRESH_FOG} {DELAY 250}
{MOVE_UNIT id=Delfador 2 31} {REFRESH_FOG}
@ -782,7 +784,7 @@ YOU UNDERSTAND NOTHING."
[/store_unit]
[unit]
{SINGLEUNITWML_MALAL}
name,id=Omaranth,_"Omaranth"
id,name=Omaranth,_"Omaranth"
x,y,overwrite=1,1,yes
[/unit]
{MODIFY_TERRAIN Ai^Qhu $stored_omaranth.x $stored_omaranth.y} # convert to ice before we spawn malal, or else he might be standing on lava

View File

@ -337,7 +337,7 @@ Now form up and get in line, before I have to beat some discipline into you!"
{MOVE_UNIT id=Drakefador 51 2}
{KILL id=Drakefador}
{NAMED_UNIT 11 "Armageddon Drake" 51 2 Drakefador "Omaranth" facing=ne}
{NAMED_UNIT 11 "Armageddon Drake" 51 2 Drakefador _"Omaranth" facing=ne}
[modify_unit] {FILTER id=Drakefador}
[object]
{EFFECT new_animation (
@ -361,8 +361,9 @@ Now form up and get in line, before I have to beat some discipline into you!"
{KILL id=Drakefador}
[unstore_unit]
variable=stored_delfador
x,y,facing=51,2,se
x,y=51,2
[/unstore_unit]
{MODIFY_UNIT id=Delfador facing se}
{CLEAR_VARIABLE stored_delfador}
{FIRE_EVENT refresh_experience}
#define DELFADOR_KEEP DLY
@ -643,9 +644,10 @@ North:<span strikethrough="true"> Dwarven Doors </span>"
#############################
[unstore_unit]
variable=stored_deoran
x,y,facing=30,30,se
x,y=30,30
[/unstore_unit]
{CLEAR_VARIABLE stored_deoran}
{MODIFY_UNIT id=Deoran facing se}
{TRANSFORM_UNIT id=Deoran "Veteran Commander"}
{FULL_HEAL id=Deoran}
@ -659,11 +661,13 @@ North:<span strikethrough="true"> Dwarven Doors </span>"
[modify_unit]
{FILTER id=Deoran}
[trait]
id,name,description=loyal_dummy,loyal,_"Zero upkeep."
[/trait]
[trait]
id,name,description=intelligent_dummy,intelligent,""
#textdomain wesnoth-help
id=loyal_dummy
name=_"loyal"
description=_"Zero upkeep."
#textdomain wesnoth-tdg
[/trait]
{TRAIT_INTELLIGENT}
[/modify_unit]
# restore S06 units, and allow Deoran to recruit them

View File

@ -21,7 +21,7 @@
side,controller,color=2,ai,wesred
type,id,name,facing="Lieutenant",Moreth,_"Moreth",sw
{MODIFICATIONS( {TRAIT_QUICK} {TRAIT_STRONG} )}
hidden,gold,income=yes,yes,0,-2
hidden,gold,income=yes,0,-2
team_name=wesnoth
[/side]
{STARTING_VILLAGES_AREA 2 15 10 9}
@ -498,7 +498,7 @@ Mayhaps as High Advisor I can finally get someone to research that... *yawn*"
[/message]
[message]
speaker=Delfador
message="I dont— wha? Look, Im still a little tipsy myself; maybe not in the best condition to be making decisions!"
message=_"I dont— wha? Look, Im still a little tipsy myself; maybe not in the best condition to be making decisions!"
[/message]
[message]

View File

@ -353,7 +353,7 @@
#############################
# DELFADOR ARRIVES
#############################
{NAMED_UNIT 1 Roc 1 15 roc_delfador "Delfador" (canrecruit,max_hitpoints,hitpoints=yes,65,65)} {FACING ne} {ANIMATE}
{NAMED_UNIT 1 Roc 1 15 roc_delfador _"Delfador" (canrecruit,max_hitpoints,hitpoints=yes,65,65)} {FACING ne} {ANIMATE}
{MOVE_UNIT id=roc_delfador 4 13}
{MOVE_UNIT id=roc_delfador 6 14}
{SOUND skill-polymorph.wav}

View File

@ -65,7 +65,7 @@
# recall escapees, preferring one bandit and one infantry
# but don't spawn new units if there aren't enough escapees
{RECALL_BANDIT 0 14 6 Peasant ({TRAIT_RESILIENT}{TRAIT_QUICK})}
{RECALL_BANDIT 0 14 6 Peasant ({ADD_MODIFICATION {TRAIT_RESILIENT}} {ADD_MODIFICATION {TRAIT_QUICK}})}
{IF} {HAVE_UNIT x,y,type=14,6,Peasant} {THEN(
{KILL x,y=14,6}
{RECALL_INFANTRYMAN 0 14 6 Peasant ({ADD_MODIFICATION {TRAIT_QUICK}} {ADD_MODIFICATION {TRAIT_STRONG}} )}
@ -77,7 +77,7 @@
{RECALL_INFANTRYMAN 0 13 7 Peasant ({ADD_MODIFICATION {TRAIT_QUICK}} {ADD_MODIFICATION {TRAIT_STRONG}} )}
{IF} {HAVE_UNIT x,y,type=13,7,Peasant} {THEN(
{KILL x,y=13,7}
{RECALL_BANDIT 0 13 7 Peasant ({TRAIT_RESILIENT}{TRAIT_QUICK})}
{RECALL_BANDIT 0 13 7 Peasant ({ADD_MODIFICATION {TRAIT_RESILIENT}} {ADD_MODIFICATION {TRAIT_QUICK}})}
{IF} {HAVE_UNIT x,y,type=13,7,Peasant} {THEN( {KILL x,y=13,7} )}
{/IF}
)} {/IF}

View File

@ -310,7 +310,7 @@
side,controller,color=9,ai,blue
type,id,x,y,facing=Bandit,bandit9a,50,15,ne
{MODIFICATIONS( {TRAIT_RESILIENT}{TRAIT_STRONG} )}
gold,income={ON_DIFFICULTY4 15 30 60 60},{ON_DIFFICULTY4 1 4 10 10}}
gold,income={ON_DIFFICULTY4 15 30 60 60},{ON_DIFFICULTY4 1 4 10 10}
recruit=Ruffian
team_name,user_team_name=eldred,_"Wesnoth Auxiliaries" {FLAG_VARIANT6 ragged}
[/side]
@ -323,7 +323,7 @@
side,controller,color=10,ai,blue
type,id,x,y,facing=Trapper,bandit10a,17,6,se
{MODIFICATIONS( {TRAIT_STRONG}{TRAIT_RESILIENT} )}
gold,income={ON_DIFFICULTY4 25 50 100 100},{ON_DIFFICULTY4 1 4 10 10}}
gold,income={ON_DIFFICULTY4 25 50 100 100},{ON_DIFFICULTY4 1 4 10 10}
recruit=Woodsman
team_name,user_team_name=eldred,_"Wesnoth Auxiliaries" {FLAG_VARIANT6 ragged}
[/side]
@ -941,8 +941,7 @@ You like magic so much? Once I drink from Jevyans Cup, Ill have enough mag
[modify_unit]
{FILTER id=Delfador}
[filter_recall]
[false]
[/false]
race=disable_delfador_recalling
[/filter_recall]
[/modify_unit]
@ -1242,7 +1241,7 @@ You like magic so much? Once I drink from Jevyans Cup, Ill have enough mag
{KILL id=MiddleEldred}
[unit]
id,name,type=HunkerEldred,_"Eldred",Hunker Eldred # use a new ID so phase 1 and phase 2 events don't interfere
side,x,y,facing,portrait=2,24,20,ne,portraits/eldred.webp
side,x,y,facing,profile=2,24,20,ne,portraits/eldred.webp
hitpoints=$eldred_hp
[modifications]
{TRAIT_RESILIENT} {TRAIT_INTELLIGENT}
@ -1285,7 +1284,9 @@ You like magic so much? Once I drink from Jevyans Cup, Ill have enough mag
[set_specials]
mode=append
[chance_to_hit]
id,name,description=magical,_"magical","This attack always has a 70% chance to hit regardless of the defensive ability of the unit being attacked."
#textdomain wesnoth-help
id,name,description=magical,_"magical",_"This attack always has a 70% chance to hit regardless of the defensive ability of the unit being attacked."
#textdomain wesnoth-tdg
special_note={INTERNAL:SPECIAL_NOTES_MAGICAL}
value,cumulative=70,no
[filter_opponent] {NOT type="Hunker Eldred"}
@ -1513,7 +1514,7 @@ You like magic so much? Once I drink from Jevyans Cup, Ill have enough mag
{KILL id=FinalEldred}
[unit]
id,name,type=FinalEldred,_"Eldred",King Eldred
side,x,y,facing,portrait=2,$eldredX,$eldredY,ne,portraits/eldred.webp
side,x,y,facing,profile=2,$eldredX,$eldredY,ne,portraits/eldred.webp
hitpoints=1
[modifications]
{TRAIT_RESILIENT} {TRAIT_INTELLIGENT}
@ -1537,7 +1538,7 @@ You like magic so much? Once I drink from Jevyans Cup, Ill have enough mag
{KILL id=FinalEldred}
[unit]
id,name,type=HunkerEldred,_"Eldred",Hunker Eldred
side,x,y,facing,portrait=2,$eldredX,$eldredY,ne,portraits/eldred.webp
side,x,y,facing,profile=2,$eldredX,$eldredY,ne,portraits/eldred.webp
hitpoints=1
[modifications]
{TRAIT_RESILIENT} {TRAIT_INTELLIGENT}

View File

@ -38,7 +38,6 @@
{LOCS}
[/remove_shroud]
[lift_fog]
side=1
{LOCS}
[/lift_fog]
#enddef

View File

@ -395,7 +395,7 @@
[+unit]
[ai]
[micro_ai]
side,ai_type,action=4,zone_guardian,add
ai_type=zone_guardian
[filter_location]
radius={INNER_RADIUS} {FILTER {VIP_FILTER}}
[/filter_location]

View File

@ -952,24 +952,31 @@ Summoned elementals dissipate at the end of each scenario."
array=terrains
[do]
{IF} {VARIABLE_CONDITIONAL this_item.after contains "^"} {THEN(
{VARIABLE layer overlay}
{VARIABLE before "*^$this_item.before"}
)} {ELSE(
{VARIABLE layer base}
{VARIABLE before "$this_item.before^*"}
)} {/IF}
{IF} {HAVE_LOCATION (x,y,terrain={X},{Y},$before)} {THEN(
[terrain]
x,y={X},{Y}
terrain=$this_item.after
layer=$layer
[/terrain]
# can't use {VARIABLE layer overlay} | {VARIABLE layer base}, or we get schema issues
{IF} {VARIABLE_CONDITIONAL this_item.after contains "^"} {THEN(
[terrain]
x,y={X},{Y}
terrain=$this_item.after
layer=overlay
[/terrain]
)} {ELSE(
[terrain]
x,y={X},{Y}
terrain=$this_item.after
layer=base
[/terrain]
)} {/IF}
[break]
[/break]
)} {/IF}
[/do]
[/foreach]
{CLEAR_VARIABLE terrains,before,layer}
{CLEAR_VARIABLE terrains,before}
[item]
x,y,name={X},{Y},snow_overlay
@ -2036,7 +2043,7 @@ Summoned elementals dissipate at the end of each scenario."
[specials]
{WEAPON_SPECIAL_MAGICAL}
[dummy]
id,name,description=chain,_"chain","If this attack kills an enemy, you may attack again."
id,name,description=chain,_"chain",_"If this attack kills an enemy, you may attack again."
[/dummy]
[/specials] )}
[/object]
@ -2106,9 +2113,9 @@ Summoned elementals dissipate at the end of each scenario."
{VARIABLE atks $this_item.attacks_left} {VARIABLE_OP atks add 1 } {MODIFY_UNIT id=$this_item.id attacks_left $atks } {CLEAR_VARIABLE atks }
[modify_unit]
{FILTER id=$this_item.id}
duration=turn # this object should get cleared sooner, but duration=turn is a fallback in case something breaks
[object]
id=skill_time_dilation_buff
duration=turn # this object should get cleared sooner, but duration=turn is a fallback in case something breaks
{EFFECT movement increase=100%} # means this also affects other-side allies when they refresh their turn
{EFFECT max_attacks increase=1}
{EFFECT halo (
@ -2317,7 +2324,7 @@ Summoned elementals dissipate at the end of each scenario."
{OVERLAY_FRAME y,alpha,image=72,0.6~0.0,"halo/cataclysm/sphere/[0001~0024,0001~0024].png~SCALE(1000,1000)~CS(-100,-100,-100):50"}
{OVERLAY_FRAME image=misc/blank-hex.png:99999}
{OVERLAY2_FRAME yalpha,image=-10,5~0,"halo/cataclysm/explosion/[1~9].png~SCALE(700,700):100"}
{OVERLAY2_FRAME y,alpha,image=-10,5~0,"halo/cataclysm/explosion/[1~9].png~SCALE(700,700):100"}
{OVERLAY2_FRAME image=misc/blank-hex.png:99999}
[/standing_anim]
#enddef

View File

@ -14,10 +14,16 @@
canrecruit=yes
[modifications]
[trait]
id,name,description=loyal_dummy,loyal,_"Zero upkeep."
#textdomain wesnoth-help
id=loyal_dummy
name=_"loyal"
description=_"Zero upkeep."
[/trait]
[trait]
id,name,description=intelligent_dummy,intelligent,_""
id=intelligent_dummy
name=_"intelligent"
help_text= _ "Intelligent units require 20% less experience than usual to advance."
#textdomian wesnoth-tdg
[/trait]
[object]
[effect]

View File

@ -834,7 +834,7 @@
[tag]
name="change_theme"
max=infinite
{REQUIRED_KEY theme string}
{SIMPLE_KEY theme string}
[/tag]
[tag]
name="item"

View File

@ -128,14 +128,15 @@
{DEFAULT_KEY delayed_variable_substitution bool no}
{DEFAULT_KEY priority s_real 0.0}
{FILTER_TAG "filter" unit ()}
{FILTER_TAG "filter_second" unit ()}
{FILTER_TAG "filter_attack" weapon ()}
{FILTER_TAG "filter_second_attack" weapon ()}
{FILTER_TAG "filter_side" side ()}
{FILTER_TAG "filter" unit max=infinite}
{FILTER_TAG "filter_second" unit max=infinite}
{FILTER_TAG "filter_attack" weapon max=infinite}
{FILTER_TAG "filter_second_attack" weapon max=infinite}
{FILTER_TAG "filter_side" side max=infinite}
[tag]
name="filter_condition"
super="$conditional_wml"
max=infinite
[/tag]
[/tag]

View File

@ -2,7 +2,7 @@ diff --git a/data/schema/core/actionwml.cfg b/data/schema/core/actionwml.cfg
index 0eff8c99f10..98e94c8cc6c 100644
--- a/data/schema/core/actionwml.cfg
+++ b/data/schema/core/actionwml.cfg
@@ -1445,5 +1445,30 @@
@@ -1445,5 +1445,34 @@
{SIMPLE_KEY y s_unsigned}
[/tag]
[/tag]
@ -23,6 +23,10 @@ index 0eff8c99f10..98e94c8cc6c 100644
+ {DATA_TAG "find_respawn_point" 0 infinite any}
+ # SoF
+ {DATA_TAG "rune_choice" 0 infinite any}
+ # TDG
+ {DATA_TAG "listen_for_mousemove" 0 infinite any}
+ {DATA_TAG "select_delfador_skills" 0 infinite any}
+ {DATA_TAG "display_skills_dialog" 0 infinite any}
+ # TSG
+ {DATA_TAG "display_tip" 0 infinite any}
+ # tutorial

View File

@ -111,7 +111,6 @@ validate_misc "Test" "TEST" || RET=
validate_misc "World_Conquest" "MULTIPLAYER,LOAD_WC2,LOAD_WC2_EVEN_THOUGH_IT_NEEDS_A_NEW_MAINTAINER" || RET=1
validate_campaign "Dead_Water" "CAMPAIGN_DEAD_WATER" "EASY" "NORMAL" "HARD" "NIGHTMARE" || RET=1
validate_campaign "Delfadors_Memoirs" "CAMPAIGN_DELFADORS_MEMOIRS" "EASY" "NORMAL" "HARD" || RET=1
validate_campaign "Descent_Into_Darkness" "CAMPAIGN_DESCENT" "EASY" "NORMAL" "HARD" || RET=1
validate_campaign "Eastern_Invasion" "CAMPAIGN_EASTERN_INVASION" "EASY" "NORMAL" "HARD" || RET=1
validate_campaign "Heir_To_The_Throne" "CAMPAIGN_HEIR_TO_THE_THRONE" "EASY" "NORMAL" "HARD" || RET=1
@ -121,6 +120,7 @@ validate_campaign "Northern_Rebirth" "CAMPAIGN_NORTHERN_REBIRTH" "
validate_campaign "Sceptre_of_Fire" "CAMPAIGN_SCEPTRE_FIRE" "EASY" "NORMAL" "HARD" || RET=1
validate_campaign "Secrets_of_the_Ancients" "CAMPAIGN_SECRETS_OF_THE_ANCIENTS" "EASY" "NORMAL" "HARD" || RET=1
validate_campaign "Son_Of_The_Black_Eye" "CAMPAIGN_SON_OF_THE_BLACK_EYE" "EASY" "NORMAL" "HARD" || RET=1
validate_campaign "The_Deceivers_Gambit" "CAMPAIGN_THE_DECEIVERS_GAMBIT" "EASY" "NORMAL" "HARD" "NIGHTMARE" || RET=1
validate_campaign "The_Hammer_of_Thursagan" "CAMPAIGN_THE_HAMMER_OF_THURSAGAN" "EASY" "NORMAL" "HARD" || RET=1
validate_campaign "The_Rise_Of_Wesnoth" "CAMPAIGN_THE_RISE_OF_WESNOTH" "EASY" "NORMAL" "HARD" || RET=1
validate_campaign "The_South_Guard" "CAMPAIGN_THE_SOUTH_GUARD" "EASY" "NORMAL" "HARD" || RET=1
@ -129,4 +129,4 @@ validate_campaign "Two_Brothers" "CAMPAIGN_TWO_BROTHERS" "
validate_campaign "Under_the_Burning_Suns" "CAMPAIGN_UNDER_THE_BURNING_SUNS" "EASY" "NORMAL" "HARD" || RET=1
validate_campaign "Winds_of_Fate" "CAMPAIGN_WINDS_OF_FATE" "EASY" "NORMAL" "HARD" "NIGHTMARE" || RET=1
exit $RET
exit $RET