From 7ab5fabbf24976a18e6acb92a270dc0aa3d2ab35 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Fri, 30 Mar 2018 13:51:04 -0400 Subject: [PATCH] Schema: Add all known ActionWML and ConditionalWML tags (based on wiki) This also finishes up the StoryWML definition, adds validation for map and shroud data, and a few other small schema fixes --- data/schema/core/actionwml.cfg | 1144 ++++++++++++++++++++++++++- data/schema/core/addons.cfg | 74 +- data/schema/core/conditionalwml.cfg | 46 +- data/schema/game_config.cfg | 122 ++- data/schema/types/subst.cfg | 25 + data/schema/units/abilities.cfg | 4 + 6 files changed, 1404 insertions(+), 11 deletions(-) create mode 100644 data/schema/types/subst.cfg diff --git a/data/schema/core/actionwml.cfg b/data/schema/core/actionwml.cfg index 912be546511d..2c7e2f0d13d6 100644 --- a/data/schema/core/actionwml.cfg +++ b/data/schema/core/actionwml.cfg @@ -1,8 +1,1150 @@ +#define ACTION_TAG NAME EXTRA + [tag] + name="{NAME}" + super="$action_wml" + {EXTRA} + [/tag] +#enddef + +#define SHOW_IF_TAG + [tag] + name="show_if" + super="$conditional_wml" + [/tag] +#enddef + +#define COLOR_KEYS TYPE + {SIMPLE_KEY red {TYPE}} + {SIMPLE_KEY green {TYPE}} + {SIMPLE_KEY blue {TYPE}} +#enddef [tag] name="$action_wml" max=0 + {INSERT_TAG} + {ACTION_TAG "command" max=infinite} + [link] + name="event" + [/link] + [link] + name="lua" + [/link] + # Flow control (ConditionalActionsWML) + [tag] + name="if" + max=infinite + super="$conditional_wml" + {ACTION_TAG "then" ()} + [tag] + name="elseif" + max=infinite + super="$conditional_wml" + {ACTION_TAG "then" ()} + [/tag] + {ACTION_TAG "else" ()} + [/tag] + [tag] + name="switch" + max=infinite + {REQUIRED_KEY variable string} + {INSERT_TAG} + [tag] + name="case" + max=infinite + super="$action_wml" + {REQUIRED_KEY value string} + [/tag] + {ACTION_TAG "else" ()} + [/tag] + [tag] + name="while" + max=infinite + super="$conditional_wml" + {ACTION_TAG "do" max=infinite} + [tag] + name="do" + max=infinite + super="$action_wml" + [/tag] + [/tag] + [tag] + name="for" + max=infinite + {SIMPLE_KEY variable string} + {INSERT_TAG} + [if] + glob_on_array=* + [then] + {SIMPLE_KEY array string} + {DEFAULT_KEY reverse s_bool no} + [/then] + [else] + {SIMPLE_KEY start s_int} + {SIMPLE_KEY end s_int} + {SIMPLE_KEY step s_int} + [/else] + [/if] + {ACTION_TAG "do" max=infinite} + [/tag] + [tag] + name="foreach" + max=infinite + {INSERT_TAG} + {SIMPLE_KEY array string} + {SIMPLE_KEY variable string} + {SIMPLE_KEY index_var string} + {DEFAULT_KEY readonly s_bool no} + {ACTION_TAG "do" max=infinite} + [/tag] + [tag] + name="repeat" + max=infinite + {INSERT_TAG} + {SIMPLE_KEY times s_int} + {ACTION_TAG "do" max=infinite} + [/tag] + # Direct actions (DirectActionsWML) + [tag] + name="endlevel" + max=infinite + {INSERT_TAG} + {REQUIRED_KEY result endlevel_result} + {SIMPLE_KEY side s_unsigned} + [if] + result=victory + [then] + {DEFAULT_KEY bonus s_bool yes} + {DEFAULT_KEY carryover_report s_bool yes} + {DEFAULT_KEY save s_bool yes} + {DEFAULT_KEY replay_save s_bool yes} + {DEFAULT_KEY linger_mode s_bool yes} + {DEFAULT_KEY reveal_map s_bool yes} + {SIMPLE_KEY next_scenario string} + {SIMPLE_KEY carryover_percentage int} + {DEFAULT_KEY carryover_add s_bool no} + {SIMPLE_KEY music string_list} + {DEFAULT_KEY end_credits s_bool yes} + {SIMPLE_KEY end_text s_t_string} + {SIMPLE_KEY end_text_duration s_unsigned} + [tag] + name="result" + max=infinite + {INSERT_TAG} + {REQUIRED_KEY result endlevel_result} + {SIMPLE_KEY side s_unsigned} + {DEFAULT_KEY bonus s_bool yes} + {SIMPLE_KEY carryover_percentage int} + {DEFAULT_KEY carryover_add s_bool no} + [/tag] + [/then] + [/if] + [/tag] + [tag] + name="unit" + max=infinite + super="units/$single" + {INSERT_TAG} + [/tag] + [tag] + name="recall" + max=infinite + super="$filter_unit,$action_wml/role/auto_recall" + {INSERT_TAG} + [/tag] + [tag] + name="teleport" + max=infinite + {INSERT_TAG} + {FILTER_TAG "filter" unit ()} + {SIMPLE_KEY x s_int} + {SIMPLE_KEY y s_int} + {SIMPLE_KEY clear_shroud s_bool} + {SIMPLE_KEY animate s_bool} + {DEFAULT_KEY check_passability s_bool yes} + [/tag] + [tag] + name="terrain_mask" + max=infinite + {INSERT_TAG} + {SIMPLE_KEY x s_int} + {SIMPLE_KEY y s_int} + {SIMPLE_KEY mask map_data} + {DEFAULT_KEY border s_bool no} + [tag] + name="rule" + max=infinite + {INSERT_TAG} + {SIMPLE_KEY old terrain_list} + {SIMPLE_KEY new terrain_list} + {SIMPLE_KEY terrain terrain_code} + {DEFAULT_KEY layer terrain_layer both} + {DEFAULT_KEY replace_if_failed s_bool no} + {DEFAULT_KEY use_old s_bool no} + [/tag] + [/tag] + [tag] + name="terrain" + max=infinite + super="$filter_location" + {INSERT_TAG} + {REQUIRED_KEY terrain terrain_code} + {DEFAULT_KEY layer terrain_layer both} + {DEFAULT_KEY replace_if_failed s_bool no} + [/tag] + [tag] + name="gold" + max=infinite + super="$filter_side" + {INSERT_TAG} + {REQUIRED_KEY amount s_int} + [/tag] + [tag] + name="unstore_unit" + max=infinite + {INSERT_TAG} + {REQUIRED_KEY variable string} + {DEFAULT_KEY find_vacant s_bool no} + {DEFAULT_KEY check_passability s_bool yes} + {SIMPLE_KEY text t_string} + {SIMPLE_KEY male_text t_string} + {SIMPLE_KEY female_text t_string} + {COLOR_KEYS s_unsigned} + {DEFAULT_KEY advance s_bool yes} + {DEFAULT_KEY fire_event s_bool no} + {DEFAULT_KEY animate s_bool yes} + {SIMPLE_KEY x s_int} + {SIMPLE_KEY y s_int} + [/tag] + [tag] + name="allow_recruit,disallow_recruit,set_recruit" + max=infinite + super="$filter_side" + {INSERT_TAG} + {REQUIRED_KEY types string_list} + [/tag] + [tag] + name="allow_extra recruit,disallow_extra_recruit,set_recruit" + max=infinite + super="$filter_unit" + {INSERT_TAG} + {REQUIRED_KEY extra_recruit string_list} + [/tag] + [tag] + name="modify_side" + max=infinite + {INSERT_TAG} + {FILTER_TAG "filter_side" side ()} + {SIMPLE_KEY side s_int} + {SIMPLE_KEY income s_int} + {SIMPLE_KEY recruit string_list} + {SIMPLE_KEY team_name string} + {SIMPLE_KEY user_team_name t_string} + {SIMPLE_KEY gold s_int} + {SIMPLE_KEY village_gold s_int} + {SIMPLE_KEY controller controller} + {SIMPLE_KEY fog s_bool} + {SIMPLE_KEY shroud s_bool} + {SIMPLE_KEY hidden s_bool} + {SIMPLE_KEY color string} + {SIMPLE_KEY switch_ai string} + {SIMPLE_KEY reset_maps s_bool} + {SIMPLE_KEY reset_view s_bool} + {DEPRECATED_KEY share_maps s_bool} + {DEPRECATED_KEY share_view s_bool} + {SIMPLE_KEY shroud_data shroud_data} + {SIMPLE_KEY suppress_end_turn_confirmation s_bool} + {SIMPLE_KEY scroll_to_leader s_bool} + {SIMPLE_KEY flag string} + {SIMPLE_KEY flag_icon string} + {SIMPLE_KEY village_support s_int} + {SIMPLE_KEY defeat_condition defeat_condition} + [tag] + name="ai" + super="$side/ai" + {INSERT_TAG} + [/tag] + [/tag] + [tag] + name="modify_turns" + max=infinite + {INSERT_TAG} + {SIMPLE_KEY value s_unsigned} + {SIMPLE_KEY add s_int} + {SIMPLE_KEY current s_unsigned} + [/tag] + {EMPTY_TAG "allow_end_turn,disallow_end_turn" 0 infinite} + [tag] + name="capture_village" + max=infinite + super="$filter_location" + {INSERT_TAG} + {SIMPLE_KEY side s_unsigned} + {DEFAULT_KEY fire_event s_bool no} + {FILTER_TAG "filter_side" side ()} + [/tag] + [tag] + name="kill" + max=infinite + super="$filter_unit" + {INSERT_TAG} + {SIMPLE_KEY animate s_bool} + {SIMPLE_KEY fire_event s_bool} + {FILTER_TAG "secondary_unit" unit ()} + {FILTER_TAG "primary_attack" weapon ()} + {FILTER_TAG "secondary_attack" weapon ()} + [/tag] + [tag] + name="move_unit" + max=infinite + super="$filter_unit" + {INSERT_TAG} + {SIMPLE_KEY to_x s_int} + {SIMPLE_KEY to_y s_int} + {DEFAULT_KEY fire_event s_bool no} + {DEFAULT_KEY check_passability s_bool yes} + {SIMPLE_KEY force_scroll s_bool} + [/tag] + [tag] + name="modify_ai" + super="$ai/modify_ai" + {INSERT_TAG} + [/tag] + [tag] + name="modify_unit" + max=infinite + super="units/$unit" + {INSERT_TAG} + {FILTER_TAG "filter" unit ()} + [link] + name="units/$modifications/trait" + [/link] + [link] + name="units/$modifications/advancement" + [/link] + [link] + name="units/$modifications/object" + [/link] + [link] + name="units/$modifications/base/effect" + [/link] + [/tag] + [tag] + name="transform_unit" + max=infinite + super="$filter_unit" + {INSERT_TAG} + {SIMPLE_KEY transform_to string} + [/tag] + {FILTER_TAG "petrify,unpetrify" unit ( + max=infinite + {INSERT_TAG} + )} + [tag] + name="object" + max=infinite + super="units/$modifications/object" + {INSERT_TAG} + {DEFAULT_KEY take_only_once s_bool yes} + {DEFAULT_KEY delayed_variable_substitution s_bool no} + {SIMPLE_KEY duration object_duration} + {SIMPLE_KEY silent s_bool} + {SIMPLE_KEY image string} + {SIMPLE_KEY name t_string} + {SIMPLE_KEY description t_string} + {SIMPLE_KEY cannot_use_message t_string} + {FILTER_TAG "filter" unit ()} + {ACTION_TAG "then" ()} + {ACTION_TAG "else" ()} + [/tag] + [tag] + name="remove_object" + max=infinite + super="$filter_unit" + {INSERT_TAG} + {SIMPLE_KEY object_id string} + [/tag] + [tag] + name="place_shroud" + max=infinite + super="$filter_location" + {INSERT_TAG} + {SIMPLE_KEY side s_unsigned} + {FILTER_TAG "filter_side" side ()} + [/tag] + [tag] + name="lift_fog" + max=infinite + super="$filter_location" + {INSERT_TAG} + {FILTER_TAG "filter_side" side ()} + {DEFAULT_KEY multiturn s_bool no} + [/tag] + [tag] + name="reset_fog" + max=infinite + super="$filter_location" + {INSERT_TAG} + {FILTER_TAG "filter_side" side ()} + {DEFAULT_KEY reset_view s_bool no} + [/tag] + {EMPTY_TAG "allow_undo,cancel_action" 0 infinite} + {ACTION_TAG "on_undo" ( + max=infinite + {DEFAULT_KEY delayed_variable_substitution s_bool no} + )} + [tag] + name="heal_unit" + max=infinite + {INSERT_TAG} + {FILTER_TAG "filter" unit ()} + {FILTER_TAG "filter_second" unit ()} + {SIMPLE_KEY amonut heal_amount} + {DEFAULT_KEY animate s_bool no} + {DEFAULT_KEY moves heal_amount 0} + {DEFAULT_KEY restore_attacks s_bool no} + {DEFAULT_KEY restore_statuses s_bool yes} + [/tag] + [tag] + name="harm_unit" + max=infinite + {INSERT_TAG} + {FILTER_TAG "filter" unit ()} + {FILTER_TAG "filter_second" unit ()} + {REQUIRED_KEY amount s_int} + {SIMPLE_KEY alignment alignment} + {SIMPLE_KEY damage_type string} + {DEFAULT_KEY kill s_bool yes} + {DEFAULT_KEY fire_event s_bool no} + {DEFAULT_KEY animate s_bool no} + {SIMPLE_KEY delay s_unsigned} + {SIMPLE_KEY variable string} + {DEFAULT_KEY poisoned s_bool no} + {DEFAULT_KEY slowed s_bool no} + {DEFAULT_KEY petrified s_bool no} + {DEFAULT_KEY unhealable s_bool no} + {SIMPLE_KEY experience s_bool} + {SIMPLE_KEY resistance_modifier s_real} + {FILTER_TAG "primary_attack" weapon ()} + {FILTER_TAG "secondary_attack" weapon ()} + [/tag] + [tag] + name="time_area" + max=infinite + super="scenario/time_area,$filter_location" + {INSERT_TAG} + {SIMPLE_KEY id string} # TODO: Is this allowed in scenario-level areas too? + {DEFAULT_KEY remove s_bool no} + {SIMPLE_KEY current_time s_unsigned} + [/tag] + [tag] + name="remove_time_area" + max=infinite + {INSERT_TAG} + {SIMPLE_KEY id string} + [/tag] + {EMPTY_TAG "end_turn" 0 infinite} + [tag] + name="replace_map" + max=infinite + {INSERT_TAG} + {REQUIRED_KEY map map_data} + {DEFAULT_KEY expand s_bool no} + {DEFAULT_KEY shrink s_bool no} + [/tag] + [tag] + name="replace_schedule" + max=infinite + {INSERT_TAG} + [link] + name="scenario/time" + [/link] + {SIMPLE_KEY current_time s_unsigned} + [/tag] + [tag] + name="tunnel" + max=infinite + super="units/unit_type~core/abilities/teleport/tunnel" + {INSERT_TAG} + {SIMPLE_KEY id string} + {DEFAULT_KEY remove s_bool no} + [/tag] + [tag] + name="do_command" + max=infinite + {INSERT_TAG} + # TODO: Move these to SaveWML schema and link them from here? + [tag] + name="attack" + {INSERT_TAG} + {SIMPLE_KEY weapon int} + {SIMPLE_KEY defender_weapon int} + [tag] + name="source" + {SIMPLE_KEY x int} + {SIMPLE_KEY y int} + [/tag] + [tag] + name="destination" + {SIMPLE_KEY x int} + {SIMPLE_KEY y int} + [/tag] + [/tag] + [tag] + name="move" + {SIMPLE_KEY x int} + {SIMPLE_KEY y int} + {SIMPLE_KEY skip_sighted string} # TODO: Make this an enum type + [/tag] + [tag] + name="recruit" + {INSERT_TAG} + {SIMPLE_KEY type string} + {SIMPLE_KEY x int} + {SIMPLE_KEY y int} + [tag] + name="from" + {SIMPLE_KEY x int} + {SIMPLE_KEY y int} + [/tag] + [/tag] + [tag] + name="recall" + {INSERT_TAG} + {SIMPLE_KEY value string} + {SIMPLE_KEY x int} + {SIMPLE_KEY y int} + [tag] + name="from" + {SIMPLE_KEY x int} + {SIMPLE_KEY y int} + [/tag] + [/tag] + [tag] + name="disband" + {SIMPLE_KEY value string} + [/tag] + [tag] + name="fire_event" + {INSERT_TAG} + {SIMPLE_KEY raise string} + [tag] + name="source" + {SIMPLE_KEY x int} + {SIMPLE_KEY y int} + [/tag] + [tag] + name="set_variable" + deprecated=yes + {SIMPLE_KEY name string} + {SIMPLE_KEY value string} + [/tag] + [/tag] + [tag] + name="lua_ai" + deprecated=yes + {SIMPLE_KEY code string} + [/tag] + [/tag] + [tag] + name="put_to_recall_list" + max=infinite + super="$filter_unit" + {INSERT_TAG} + {DEFAULT_KEY heal s_bool no} + [/tag] + # Display actions (InterfaceActionsWML) + [tag] + name="inspect" + max=infinite + {SIMPLE_KEY name string} + [/tag] + [tag] + name="message" + max=infinite + super="$filter_unit" + {INSERT_TAG} + {SIMPLE_KEY speaker string} + {SIMPLE_KEY message t_string} + {SIMPLE_KEY male_message t_string} + {SIMPLE_KEY female_message t_string} + {SIMPLE_KEY wait_description t_string} + {SIMPLE_KEY side_for range_list} + {SIMPLE_KEY image string} + {SIMPLE_KEY mirror s_bool} + {SIMPLE_KEY second_image string} + {SIMPLE_KEY second_mirror s_bool} + {SIMPLE_KEY image_pos image_pos} + {SIMPLE_KEY caption t_string} + {DEFAULT_KEY scroll s_bool yes} + {DEFAULT_KEY highlight s_bool yes} + {SIMPLE_KEY duration s_unsigned} + {SIMPLE_KEY sound string_list} + {SHOW_IF_TAG} + [tag] + name="option" + max=infinite + {INSERT_TAG} + {DEPRECATED_KEY message t_string} + {SIMPLE_KEY image string} + {SIMPLE_KEY label t_string} + {SIMPLE_KEY description t_string} + {SIMPLE_KEY default s_bool} + {SHOW_IF_TAG} + {ACTION_TAG "command" ()} + [/tag] + [tag] + name="text_input" + {SIMPLE_KEY variable string} + {SIMPLE_KEY label t_string} + {SIMPLE_KEY max_length s_unsigned} + {SIMPLE_KEY text string} + [/tag] + [/tag] + [tag] + name="objectives" + max=infinite + super="$filter_side" + {INSERT_TAG} + {SIMPLE_KEY bullet string} + {SIMPLE_KEY summary t_string} + {SIMPLE_KEY note t_string} + {SIMPLE_KEY victory_string t_string} + {SIMPLE_KEY defeat_string t_string} + {SIMPLE_KEY gold_carryover_string t_string} + {SIMPLE_KEY notes_string t_string} + {DEFAULT_KEY silent s_bool no} + {DEFAULT_KEY delayed_variable_substitution s_bool no} + [tag] + name="objective~base" + max=0 + {SIMPLE_KEY bullet string} + {COLOR_KEYS s_unsigned} + {SHOW_IF_TAG} + [/tag] + [tag] + name="objective" + max=infinite + super="$action_wml/objectives/objective~base" + {SIMPLE_KEY description t_string} + {SIMPLE_KEY caption t_string} + {SIMPLE_KEY condition objective_condition} + {DEFAULT_KEY show_turn_counter s_bool no} + [/tag] + [tag] + name="gold_carryover" + max=infinite + super="$action_wml/objectives/objective~base" + {SIMPLE_KEY bonus s_bool} + {SIMPLE_KEY carryover_percentage int} + [/tag] + [tag] + name="note" + max=infinite + super="$action_wml/objectives/objective~base" + {SIMPLE_KEY description t_string} + [/tag] + [/tag] + [tag] + name="set_menu_item" + max=infinite + {INSERT_TAG} + {SIMPLE_KEY id string} + {SIMPLE_KEY description t_string} + {SIMPLE_KEY image string} + {DEPRECATED_KEY needs_select s_bool} + {DEFAULT_KEY synced s_bool yes} + {DEFAULT_KEY use_hotkey s_bool yes} + {SHOW_IF_TAG} + {FILTER_TAG "filter_location" location ()} + {ACTION_TAG "command" {DEFAULT_KEY delayed_variable_substitution s_bool yes}} + [tag] + name="default_hotkey" + {SIMPLE_KEY key string} + {SIMPLE_KEY alt bool} + {SIMPLE_KEY ctrl bool} + {SIMPLE_KEY shift bool} + {SIMPLE_KEY cmd bool} + {DEFAULT_KEY repeat_on_hold s_bool no} + [/tag] + [/tag] + [tag] + name="clear_menu_item" + max=infinite + {REQUIRED_KEY id string} + [/tag] + [tag] + name="change_theme" + max=infinite + {REQUIRED_KEY theme string} + [/tag] + [tag] + name="item" + max=infinite + super="scenario/item,$filter_location" + {INSERT_TAG} + {DEFAULT_KEY redraw s_bool yes} + [/tag] + [tag] + name="remove_item" + max=infinite + super="$filter_location" + {INSERT_TAG} + {SIMPLE_KEY image string} + [/tag] + [tag] + name="print" + max=infinite + {SIMPLE_KEY text t_string} + {SIMPLE_KEY size s_unsigned} + {SIMPLE_KEY duration s_unsigned} + {COLOR_KEYS s_unsigned} + [/tag] + [tag] + name="move_unit_fake" + max=infinite + {SIMPLE_KEY type string} + {SIMPLE_KEY x range_list} + {SIMPLE_KEY y range_list} + {SIMPLE_KEY side s_unsigned} + {SIMPLE_KEY gender gender} + {SIMPLE_KEY variation string} + {SIMPLE_KEY image_mods string} + {DEFAULT_KEY force_scroll s_bool yes} + [/tag] + [tag] + name="move_units_fake" + max=infinite + {INSERT_TAG} + # TODO: Does it accept force_scroll? + [tag] + name="fake_unit" + # TODO: Does it accept gender, variation, or image_mods? + {SIMPLE_KEY type string} + {SIMPLE_KEY x s_unsigned} + {SIMPLE_KEY y s_unsigned} + {SIMPLE_KEY side s_unsigned} + {SIMPLE_KEY skip_steps s_unsigned} + [/tag] + [/tag] + {FILTER_TAG "hide_unit,unhide_unit" unit ( + max=infinite + {INSERT_TAG} + )} + {EMPTY_TAG "lock_view,unlock_view" 0 infinite} + [tag] + name="scroll" + max=infinite + {INSERT_TAG} + {SIMPLE_KEY x s_int} + {SIMPLE_KEY y s_int} + {SIMPLE_KEY side s_unsigned} + {FILTER_TAG "filter_side" side ()} + [/tag] + [tag] + name="scroll_to" + max=infinite + super="$filter_location" + {INSERT_TAG} + {DEFAULT_KEY check_fogged s_bool no} + {DEFAULT_KEY immediate s_bool no} + {DEFAULT_KEY highlight s_bool no} + {SIMPLE_KEY side s_unsigned} + {FILTER_TAG "filter_side" side ()} + [/tag] + [tag] + name="scroll_to_unit" + max=infinite + super="$filter_unit" + {INSERT_TAG} + {DEFAULT_KEY check_fogged s_bool no} + {DEFAULT_KEY immediate s_bool no} + {DEFAULT_KEY highlight s_bool no} + {SIMPLE_KEY for_side s_unsigned} + {FILTER_TAG "for_side" side ()} + [/tag] + [tag] + name="select_unit" + max=infinite + super="$filter_unit" + {INSERT_TAG} + {DEFAULT_KEY fire_event s_bool no} + {DEFAULT_KEY highlight s_bool yes} + [/tag] + [tag] + name="sound" + max=infinite + {SIMPLE_KEY name string_list} + {DEFAULT_KEY repeat s_unsigned 0} + [/tag] + [tag] + name="sound_source" + max=infinite + {SIMPLE_KEY id string} + {SIMPLE_KEY sounds string_list} + {SIMPLE_KEY delay s_unsigned} + {SIMPLE_KEY chance s_unsigned} + {SIMPLE_KEY check_fogged s_bool} + {SIMPLE_KEY check_shrouded s_bool} + {SIMPLE_KEY x range_list} + {SIMPLE_KEY y range_list} + {DEFAULT_KEY fade_range s_unsigned 3} + {DEFAULT_KEY full_range s_unsigned 14} + {SIMPLE_KEY loop s_int} + [/tag] + [tag] + name="story" + max=infinite + super="scenario/story" + [/tag] + [link] + name="titlescreen_music/music" + [/link] + [tag] + name="volume" + max=infinite + {SIMPLE_KEY music s_unsigned} + {SIMPLE_KEY sound s_unsigned} + [/tag] + [tag] + name="color_adjust" + max=infinite + {COLOR_KEYS s_int} + [/tag] + [tag] + name="delay" + max=infinite + {SIMPLE_KEY time s_unsigned} + {DEFAULT_KEY accelerate s_bool no} + [/tag] + [tag] + name="redraw" + max=infinite + super="$filter_side" + {INSERT_TAG} + {DEFAULT_KEY clear_shroud s_bool no} + {SIMPLE_KEY side s_unsigned} + [/tag] + [tag] + name="unit_overlay" + max=infinite + super="$filter_unit" + {INSERT_TAG} + {SIMPLE_KEY image string} + [/tag] + [tag] + name="animate_unit" + max=infinite + {SIMPLE_KEY flag string} + {SIMPLE_KEY hits anim_hits} + {SIMPLE_KEY text t_string} + {SIMPLE_KEY male_text t_string} + {SIMPLE_KEY female_text t_string} + {COLOR_KEYS s_unsigned} + {SIMPLE_KEY with_bars s_bool} + {FILTER_TAG "filter" unit {INSERT_TAG}} + {FILTER_TAG "primary_attack" weapon {INSERT_TAG}} + {FILTER_TAG "secondary_attack" weapon {INSERT_TAG}} + {FILTER_TAG "facing" location {INSERT_TAG}} + [tag] + name="animate" + super="$action_wml/animate_unit" + # TODO: [filter] is now mandatory rather than optional... + # TODO: Also, is nested [aniamte] allowed? + [/tag] + [/tag] + [tag] + name="label" + max=infinite + super="scenario/label,$filter_location" + {INSERT_TAG} + [/tag] + [tag] + name="floating_text" + max=infinite + super="$filter_location" + {INSERT_TAG} + {SIMPLE_KEY text t_string} + [/tag] + [tag] + name="deprecated_message" + max=infinite + {SIMPLE_KEY message string} + {SIMPLE_KEY level deprecation_level} + {SIMPLE_KEY what string} + {SIMPLE_KEY version version} + [/tag] + [tag] + name="wml_message" + max=infinite + {SIMPLE_KEY message string} + {SIMPLE_KEY logger logger} + [/tag] + [tag] + name="test_condition" + max=infinite + super="$conditional_wml" + {DEFAULT_KEY result s_bool no} + {SIMPLE_KEY logger logger} + [/tag] + [tag] + name="open_help" + max=infinite + {SIMPLE_KEY topic string} + [/tag] + [tag] + name="show_objectives" + max=infinite + super="$filter_side" + {INSERT_TAG} + [/tag] + [tag] + name="chat" + max=infinite + super="$filter_side" + {INSERT_TAG} + {SIMPLE_KEY speaker string} + {SIMPLE_KEY message string} + {DEFAULT_KEY observable s_bool yes} + [/tag] + [tag] + name="zoom" + max=infinite + {SIMPLE_KEY factor s_unsigned} + {SIMPLE_KEY relative s_bool} + [/tag] + # Internal actions (InternalActionsWML) + [tag] + name="set_variable" + max=infinite + {INSERT_TAG} + {SIMPLE_KEY name string} + {SIMPLE_KEY value string} + {SIMPLE_KEY literal string} + {SIMPLE_KEY to_variable string} + {SIMPLE_KEY add s_real} + {SIMPLE_KEY sub s_real} + {SIMPLE_KEY multiply s_real} + {SIMPLE_KEY divide s_real} + {SIMPLE_KEY modulo s_real} + {SIMPLE_KEY rand string_list} + {SIMPLE_KEY time stamp} + {SIMPLE_KEY string_length string} + {SIMPLE_KEY round rounding_method} + {SIMPLE_KEY ipart s_real} + {SIMPLE_KEY fpart s_real} + [tag] + name="join" + {SIMPLE_KEY variable string} + {SIMPLE_KEY key string} + {SIMPLE_KEY separator string} + {SIMPLE_KEY remove_empty s_bool} + [/tag] + [/tag] + [tag] + name="set_variables" + max=infinite + {INSERT_TAG} + {SIMPLE_KEY name string} + {SIMPLE_KEY mode set_variables_mode} + {SIMPLE_KEY to_variable string} + {DATA_TAG value 0 infinite} + {DATA_TAG literal 0 infinite} + [tag] + name="split" + max=infinite + {SIMPLE_KEY list string} + {SIMPLE_KEY key string} + {SIMPLE_KEY separator string} + {SIMPLE_KEY remove_empty s_bool} + [/tag] + [/tag] + [tag] + name="store_gold" + max=infinite + super="$filter_side" + {INSERT_TAG} + {SIMPLE_KEY variable string} + [/tag] + [tag] + name="store_side" + max=infinite + super="$filter_side" + {INSERT_TAG} + {SIMPLE_KEY variable string} + [/tag] + [tag] + name="store_starting_location" + max=infinite + super="$filter_side" + {INSERT_TAG} + {SIMPLE_KEY variable string} + [/tag] + [tag] + name="store_locations" + max=infinite + super="$filter_location" + {INSERT_TAG} + {SIMPLE_KEY variable string} + [/tag] + [tag] + name="store_unit" + max=infinite + {INSERT_TAG} + {FILTER_TAG "filter" unit {INSERT_TAG}} + {SIMPLE_KEY variable string} + {SIMPLE_KEY mode store_unit_mode} + {SIMPLE_KEY kill s_bool} + [/tag] + [tag] + name="store_reachable_locations" + max=infinite + {INSERT_TAG} + {SIMPLE_KEY range reachable_range} + {SIMPLE_KEY moves reachable_moves} + {SIMPLE_KEY viewing_side s_unsigned} + {SIMPLE_KEY variable string} + {FILTER_TAG "filter" unit {INSERT_TAG}} + {FILTER_TAG "filter_location" location {INSERT_TAG}} + [/tag] + [tag] + name="store_map_dimensions" + max=infinite + {SIMPLE_KEY variable string} + [/tag] + [tag] + name="store_time_of_day" + max=infinite + {SIMPLE_KEY x s_unsigned} + {SIMPLE_KEY y s_unsigned} + {SIMPLE_KEY variable string} + {SIMPLE_KEY turn s_unsigned} + [/tag] + [tag] + name="store_turns" + max=infinite + {SIMPLE_KEY variable string} + [/tag] + [tag] + name="store_unit_defense" + max=infinite + super="$filter_unit" + {SIMPLE_KEY loc_x s_unsigned} + {SIMPLE_KEY loc_y s_unsigned} + {SIMPLE_KEY terrain terrain_code} + {SIMPLE_KEY variable string} + [/tag] + [tag] + name="store_unit_type" + max=infinite + {SIMPLE_KEY type string} + {SIMPLE_KEY variable string} + [/tag] + [tag] + name="store_unit_type_ids" + max=infinite + {SIMPLE_KEY variable string} + [/tag] + [tag] + name="store_villages" + max=infinite + super="$action_wml/store_locations" + deprecated=yes + [/tag] + [tag] + name="store_items" + max=infinite + super="$action_wml/store_locations" + [/tag] + [tag] + name="store_relative_direction" + max=infinite + {INSERT_TAG} + {SIMPLE_KEY variable string} # TODO: Is this a string or a direction? + {SIMPLE_KEY mode s_unsigned} # TODO: This should really be an enum type + [tag] + name="source" + {SIMPLE_KEY x s_unsigned} + {SIMPLE_KEY y s_unsigned} + [/tag] + [tag] + name="destination" + {SIMPLE_KEY x s_unsigned} + {SIMPLE_KEY y s_unsigned} + [/tag] + [/tag] + [tag] + name="find_path" + max=infinite + {INSERT_TAG} + {SIMPLE_KEY variable string} + {DEFAULT_KEY allow_multiple_turns s_bool no} + {DEFAULT_KEY check_visibility s_bool no} + {DEFAULT_KEY check_teleport s_bool yes} + {DEFAULT_KEY check_zoc s_bool yes} + {FILTER_TAG "traveler" unit {INSERT_TAG}} + {FILTER_TAG "destination" location {INSERT_TAG}} + [/tag] + [tag] + name="unit_worth" + max=infinite + super="$filter_unit" + {INSERT_TAG} + [/tag] + [tag] + name="clear_variable" + max=infinite + {SIMPLE_KEY name string_list} + [/tag] + [tag] + name="sync_variable" + max=infinite + {SIMPLE_KEY name string} + [/tag] + [tag] + name="fire_event" + max=infinite + {INSERT_TAG} + {SIMPLE_KEY name string} + {SIMPLE_KEY id string} + {FILTER_TAG "primary_unit" unit {INSERT_TAG}} + {FILTER_TAG "secondary_unit" unit {INSERT_TAG}} + {FILTER_TAG "primary_attack" weapon {INSERT_TAG}} + {FILTER_TAG "secondary_attack" weapon {INSERT_TAG}} + [/tag] + [tag] + name="remove_event" + max=infinite + {REQUIRED_KEY id string} + [/tag] + [tag] + name="role" + max=infinite + super="$filter_unit" + {INSERT_TAG} + {SIMPLE_KEY role string} + {SIMPLE_KEY type string_list} + {DEFAULT_KEY search_recall_list search_recall_list yes} + {ACTION_TAG else ()} + [tag] + name="auto_recall" + {DEFAULT_KEY show s_bool yes} + {DEFAULT_KEY fire_event s_bool no} + {DEFAULT_KEY check_passability s_bool yes} + [/tag] + [/tag] + [tag] + name="random_placement" + max=infinite + {INSERT_TAG} + {SIMPLE_KEY num_items f_unsigned} + {SIMPLE_KEY variable string} + {SIMPLE_KEY min_distance s_unsigned} + {DEFAULT_KEY allow_less s_bool no} + {FILTER_TAG "filter_location" location {INSERT_TAG}} + {ACTION_TAG "command" ()} + [/tag] + {EMPTY_TAG "break,continue,return" 0 infinite} any_tag=yes - # TODO: Fill in all known ActionWML here [/tag] diff --git a/data/schema/core/addons.cfg b/data/schema/core/addons.cfg index 2ab556603fd0..638521ce1a41 100644 --- a/data/schema/core/addons.cfg +++ b/data/schema/core/addons.cfg @@ -32,8 +32,8 @@ {DEFAULT_KEY hidden bool no} {SIMPLE_KEY fog bool} {SIMPLE_KEY shroud bool} - {SIMPLE_KEY fog_data string} - {SIMPLE_KEY shroud_data string} + {SIMPLE_KEY fog_data shroud_data} + {SIMPLE_KEY shroud_data shroud_data} {SIMPLE_KEY persistent bool} {SIMPLE_KEY save_id string} {SIMPLE_KEY previous_save_id string} @@ -78,7 +78,7 @@ [tag] name="ai" max=infinite - super="ais/ai" + super="$ai" [/tag] {DEFAULT_KEY allow_player bool yes} @@ -300,7 +300,7 @@ {ADDON_DESCRIPTION} {SIMPLE_KEY next_scenario string} {SIMPLE_KEY name t_string} - {SIMPLE_KEY map_data string} + {SIMPLE_KEY map_data map_data} {DEFAULT_KEY turns int -1} {DEFAULT_KEY turn_at int 1} {DEFAULT_KEY random_start_time bool,int_list no} # Note: Is it random_start_time or random_starting_time? (There's some uses of the latter) @@ -327,12 +327,12 @@ {SIMPLE_KEY force_lock_settings bool} [tag] name="story" - # TODO: Remove this once the actual supported tags are properly documented (basically messages, insert_tag, if/then/else, switch/case) - any_tag=yes + {INSERT_TAG} # TODO: Is this really recognized at story toplevel? Wiki claims it is. [tag] name="image" max=infinite + {INSERT_TAG} {SIMPLE_KEY x int} {SIMPLE_KEY y int} {SIMPLE_KEY centered bool} @@ -349,6 +349,7 @@ [tag] name="part" max=infinite + {INSERT_TAG} {SIMPLE_KEY background string} {DEFAULT_KEY scale_background bool yes} {SIMPLE_KEY story t_string} @@ -362,6 +363,7 @@ [tag] name="background_layer" max=infinite + {INSERT_TAG} {SIMPLE_KEY image string} {SIMPLE_KEY scale_vertically bool} {SIMPLE_KEY scale_horizontally bool} @@ -385,11 +387,67 @@ super="scenario/story/part" [/tag] [/tag] - # TODO: Switch/case + [tag] + name="switch" + max=infinite + {REQUIRED_KEY variable string} + {INSERT_TAG} + [tag] + name="case" + max=infinite + super="scenario/story/part" + {REQUIRED_KEY value string} + [/tag] + [tag] + name="else" + super="scenario/story/part" + [/tag] + [/tag] [link] name="scenario/story/image" [/link] + [link] + name="$action_wml/deprecated_message" + [/link] + [link] + name="$action_wml/wml_message" + [/link] [/tag] + [tag] + name="if" + max=infinite + super="$conditional_wml" + [tag] + name="then" + super="scenario/story" + [/tag] + [tag] + name="else" + super="scenario/story" + [/tag] + [/tag] + [tag] + name="switch" + max=infinite + {REQUIRED_KEY variable string} + {INSERT_TAG} + [tag] + name="case" + max=infinite + super="scenario/story" + {REQUIRED_KEY value string} + [/tag] + [tag] + name="else" + super="scenario/story" + [/tag] + [/tag] + [link] + name="$action_wml/deprecated_message" + [/link] + [link] + name="$action_wml/wml_message" + [/link] [/tag] [tag] name="label" @@ -410,6 +468,8 @@ {SIMPLE_KEY y range_list} {SIMPLE_KEY image string} {SIMPLE_KEY halo string} + {SIMPLE_KEY team_name string} + {DEFAULT_KEY visible_in_fog bool yes} [/tag] [tag] name="time" diff --git a/data/schema/core/conditionalwml.cfg b/data/schema/core/conditionalwml.cfg index 4d715ac93d9f..34246f421238 100644 --- a/data/schema/core/conditionalwml.cfg +++ b/data/schema/core/conditionalwml.cfg @@ -1,7 +1,51 @@ +# All keys here are strings, because there could be variable substitutions [tag] name="$conditional_wml" max=0 + {INSERT_TAG} + [tag] + name="true,false" + max=infinite + {INSERT_TAG} + [/tag] + {FILTER_TAG "have_unit" unit ( + max=infinite + {INSERT_TAG} + {DEFAULT_KEY search_recall_list string no} + {SIMPLE_KEY count string} + )} + {FILTER_TAG "have_location" location ( + max=infinite + {INSERT_TAG} + {SIMPLE_KEY count string} + )} + [tag] + name="variable" + max=infinite + {INSERT_TAG} + {SIMPLE_KEY name string} + {SIMPLE_KEY contains string} + {SIMPLE_KEY equals string} + {SIMPLE_KEY not_equals string} + {SIMPLE_KEY numerical_equals string} + {SIMPLE_KEY numerical_not_equals string} + {SIMPLE_KEY greater_than string} + {SIMPLE_KEY greater_than_equal_to string} + {SIMPLE_KEY less_than string} + {SIMPLE_KEY less_than_equal_to string} + {SIMPLE_KEY boolean_equals string} + {SIMPLE_KEY boolean_not_equals string} + [/tag] + [tag] + name="found_item" + max=infinite + {INSERT_TAG} + {REQUIRED_KEY id string} + [/tag] + [tag] + name="and,or,not" + super="$condition_wml" + [/tag] any_tag=yes - # TODO: Fill in all known ConditionalWML here [/tag] diff --git a/data/schema/game_config.cfg b/data/schema/game_config.cfg index e2dcdfab8807..de1d5826198f 100644 --- a/data/schema/game_config.cfg +++ b/data/schema/game_config.cfg @@ -1,9 +1,19 @@ {./macros.cfg} +#define INSERT_TAG + [tag] + name="insert_tag" + max=infinite + {SIMPLE_KEY name string} + {SIMPLE_KEY variable string} + [/tag] +#enddef + [wml_schema] # TODO: Or should we just include {./types}? {./types/basic.cfg} {./types/formula.cfg} + {./types/subst.cfg} [type] name=int_percent value="-?\d+%?" @@ -14,7 +24,7 @@ [/type] [type] name="version" - value="\d+(\.\d+(\.\d+))" + value="\d+(\.\d+(\.\d+)?)" [/type] [type] name="text_alignment" @@ -101,6 +111,32 @@ [/element] [/list] [/type] + [type] + name="map_data" + [list] + split="\n" + [element] + [list] + [element] + value="([a-zA-Z0-9_]+\s+)?[A-Za-z\\|/\^_]+" + [/element] + [/list] + [/element] + [/list] + [/type] + [type] + name=terrain_layer + value="overlay|base|both" + [/type] + [type] + name="shroud_data" + [list] + split="\n" + [element] + value="\|[01]*" + [/element] + [/list] + [/type] [type] name=irdya_date value="\d+ [A-Z][A-Z]" @@ -132,7 +168,11 @@ [/type] [type] name="anim_hits" - value="(hit|no|miss|kill|yes)(,(hit|no|miss|kill|yes))*" + [list] + [element] + value="hit|no|miss|kill|yes" + [/element] + [/list] [/type] [type] name="color" @@ -170,6 +210,14 @@ name="effect_set_special_mode" value="append|replace" [/type] + [type] + name="set_variables_mode" + value="append|repace|merge|insert" + [/type] + [type] + name="store_unit_mode" + value="append|repace|always_clear" + [/type] [type] name="ai_grouping" value="offensive|defensive|no" @@ -202,6 +250,75 @@ [/type] [/union] [/type] + [type] + name="endlevel_result" + value="victory|defeat" + [/type] + [type] + name="object_duration" + value="scenario|forever|turn|turn[ _]end" + [/type] + [type] + name="heal_amount" + [union] + [type] + link=int + [/type] + [type] + value="full" + [/type] + [/union] + [/type] + [type] + name="image_pos" + value="left|right" + [/type] + [type] + name="objective_condition" + value="win|lose" + [/type] + [type] + name="deprecation_level" + value="[1-4]" + [/type] + [type] + name="logger" + value="err(or)?|warn(ing)?|debug|info" + [/type] + [type] + name="stamp" + value="stamp" + [/type] + [type] + name="rounding_method" + [union] + [type] + link=int + [/type] + [type] + value="floor|ceil|trunc" + [/type] + [/union] + [/type] + [type] + name="reachable_range" + value="movement|attack|vision" + [/type] + [type] + name="reachable_moves" + value="current|max" + [/type] + [type] + name="search_recall_list" + [union] + [type] + link=bool + [/type] + [type] + value="only" + [/type] + [/union] + [/type] [tag] name="root" min=1 @@ -218,6 +335,7 @@ name="code" type="string" [/key] + {DATA_TAG args 0 1} [/tag] [/tag] [/wml_schema] \ No newline at end of file diff --git a/data/schema/types/subst.cfg b/data/schema/types/subst.cfg new file mode 100644 index 000000000000..fe6cb4320e72 --- /dev/null +++ b/data/schema/types/subst.cfg @@ -0,0 +1,25 @@ + +# Note that basic.cfg must also be included for these to work! + +#define SUBST_TYPE BASE +[type] + name=s_{BASE} + [union] + [type] + link={BASE} + [/type] + [type] + # Basically, if there's a non-final $ in it, just give up on trying to validate it + value=".*\$.+" + [/type] + [/union] +[/type] +#enddef + +{SUBST_TYPE bool} +{SUBST_TYPE int} +{SUBST_TYPE unsigned} +{SUBST_TYPE real} +{SUBST_TYPE color} +{SUBST_TYPE point} +{SUBST_TYPE t_string} diff --git a/data/schema/units/abilities.cfg b/data/schema/units/abilities.cfg index e0c55df735a8..c7b71edc660a 100644 --- a/data/schema/units/abilities.cfg +++ b/data/schema/units/abilities.cfg @@ -99,6 +99,10 @@ {FILTER_TAG "filter" unit ()} {FILTER_TAG "source" location ()} {FILTER_TAG "target" location ()} + {DEFAULT_KEY bidirectional bool yes} + {DEFAULT_KEY always_visible bool no} + {DEFAULT_KEY allow_vision bool yes} + {DEFAULT_KEY pass_allied_units bool yes} [/tag] [/tag] [tag]