战役至少要包含三个文件:
战役概述:<data>\campaigns\Hero_Race\main_.cfg
战役场景:<data>\campaigns\Hero_Race\scenarios\01_hero_race.cfg
战役地图:<data>\campaigns\Hero_Race\maps\sanguo
一、战役概述(main_.cfg)
#textdomain wesnoth-race [textdomain] name="wesnoth-race" [/textdomain]
定义本战役要使用到的多国语言包。cfg文件中类似_"Hero Race"或_ "Hero Race"(下横符和字符串之间有一个空格),这种称为可翻译字符串,也就是说它们显示界面上的字符会随着选择语言不同而不同。像_"Hero Race",英文时显示“Hero Race”,中文则是“群雄争霸”。
在WML语法中‘#’指示以它开始的那一行是注释行,但这里的#textdomain是特殊的,不是。#textdomain wesnoth-race作用是告知该战役使用wesnoth-race.mo这个语言包。
[textdomain]...[/textdomain]块作用是向系统注册wesnoth-race.mo这个语言包。由于wesnoth-race.mo只有群雄争霸才需要,这里需要自注册一下,以让系统包含这个包。
[campaign] id=hero_race rank=110 name=_"Hero Race" abbrev= _ "RACE" define=CAMPAIGN_HERO_RACE icon="data/campaigns/Hero_Race/images/icon.png" first_scenario=hero_race image="data/campaigns/Hero_Race/images/campaign_image.png" description= _ "Hero Race description" hero_data="^xwml/hero.dat" rpg_mode=yes [/campaign]
定义战役概述。
id[/color]:战役标识。你可以认为这等于同剧本标识,像184年的黄巾之乱,208年赤壁之战。id一大作用是编辑器要据它生成bin文件,群雄争霸对应的就是hero_race.bin。
name:战役名。它是显示给用户看的。
abbrev:战役名缩写。像存储文件就使用它作为前缀,WOK-南郡战役_回合_1.gz'中的WOK。
define:选择了该战役后就预定义宏。
icon:选择战役对话框中出现在文字左侧的图标。
first_scenario:王国战争战役设计类似《曹操传》,是一幕接着一幕,first_scenaio是战役的第一场景,就像《曹操传》中的“颖川之战”。
image:选择战役对话框中出现在右侧的图像。
description:战役描述。显示在image正上方的一段描述性文字。
hero_data:战役要使用到的武将数据文件。脱字符表示从游戏目录树根开始,
[player]...[/player]:可选择玩家列表。对列表中每一项,hero:武将序号,像12是马超,136是袁绍,([color=Red]武将序号详见hero.dat[/color])。程序会跟据这个列表弹出一个选择框,选中的那一个玩家控制,其它的就是AI。
#ifdef CAMPAIGN_HERO_RACE [compaign_addon] [binary_path] path=data/campaigns/Hero_Race [/binary_path]
#ifdef CAMPAIGN_WAR_OF_KINGDOM这是一个类似C语言的宏判断。一旦选择了本战投后,CAMPAIGN_HERO_RACE将被WML解析器视为一个已定义宏(见上面[campaign]标签中的[color=Red]define[/color]字段),所以#ifdef/#endif中的语句将被执行。
一旦选择了本战役后,要搜索图像将多出一条搜索路径。在这里可以放置只有本战役才需要的图像文件。
[+units] {campaigns/Hero_Race/units} [/units]
一旦选择了本战役后,多出的单位类型定义。例如你想增加一个兵种:炮车,这个兵种别地方是用不到的,你就可以放在这里。(系统默认放在<data>\core\units目录下,这里是私藏的)
{campaigns/Hero_Race/scenarios} [/compaign_addon] #endif
告知WML解析器,继续解析data/campaigns/War_of_Kingdom/scenarios下的所有*.cfg文件。在这里也就是要解析文件:01_hero_race.cfg
二、战役场景(01_hero_race.cfg)
# scenario是场景块标签。 [scenario] # 本场景标识。注意下二楼[campaign]标签中的first_scenario字段 id=hero_race # 本场景胜利结束后下一场景。群雄争霸只一个场景,结束就没了 next_scenario=null # 本场景叫什么:群雄争霸 name=_"race of hero" # 本场景使用到的地图 map_data="{campaigns/Hero_Race/maps/sanguo}" # 本场景限定回合数。-1表示不限回合 turns=-1 # 一天内分哪些时段。在不同时段不同兵种部队能力可能有不同表现。像守序单位在白天有25%加成 # 第一时段:黎明 {DAWN} # 第二时段:白天(早上) {MORNING} # 第三时段:白天(下午) {AFTERNOON} # 第四时段:黄昏 {DUSK} # 第五时段:晚上(前半夜) {FIRST_WATCH} # 第六时段:晚上(后半夜) {SECOND_WATCH} # 游戏中使用到的背景音乐 {INTRO_AND_SCENARIO_MUSIC legends_of_the_north.ogg transience.ogg} {EXTRA_SCENARIO_MUSIC underground.ogg} {EXTRA_SCENARIO_MUSIC knolls.ogg} {EXTRA_SCENARIO_MUSIC battle.ogg} {EXTRA_SCENARIO_MUSIC vengeful.ogg} {EXTRA_SCENARIO_MUSIC revelation.ogg} # 定义一个事件,触发时机:prestart,初始化场景时被执行 [event] name=prestart # 定义本场景胜利条件和失败条件. (它们只是提示用,不会作为判断条件) [objectives] [objective] description= _"defeat all heros" condition=win [/objective] [objective] description= _"you are defeated" condition=lose [/objective] [/objectives] [/event] # 接下开始定义势力。势力,就是类似魏、吴、蜀。 [side] # 势力编号。它必须从1始,逐1增 side=1 {PLAYER_IF 12} # “选择玩家”中选择了[player]...hero=12[/player]后就会进入这里,一旦选择那它就是玩家 # 是否使用战争黑幕。$指示这是一个全局变量,player.shroud不在if条件中,需要加$ shroud=$player.shroud # 是否使用战争迷雾。 fog=$player.fog # 控制:玩家 controller=human {PLAYER_ELSE} # “选择玩家”时玩家没有选择该势力,那就是作为ai势力 # 控制:ai controller=ai {PLAYER_ENDIF_ELSE} # 势力领袖武将 leader=12 id=machao # 弥补AI不足,让AI每回合有更多金和一开始就能招3级兵 {PLAYER_IF 12} # 玩家选择了该势力,初始金100 gold=100 # 每回合基本收入0 income=0 # 能直接招募的兵种,全是一级兵 recruit=footman1,horseman1,bowman1,catapult1,commander1,pikeman1,mage1 {PLAYER_ELSE} # AI势力,初始金200 gold=200 # 每回合基本收入120 income=120 # 能直接招募的兵种,全是三级兵 recruit=footman3,horseman3,bowman3,catapult3,commander3,pikeman3,whitemage3,redmage3 {PLAYER_ENDIF_ELSE} # 在(19,2)坐标处放置一个城市, 该城市属于side=1,城市编号1, 城市序号125(它和武将被统一编号) {ANONYMITY_LOYAL_MERITORIOUS_CITY 1 1 19 2 125 220} [+artifical] # 城市一开始“空闲武将” service_heros=2,48,113,146,159,199,200,201 # 城市一开始“在野武将” wander_heros=170 # 属于该城市的经济区 economy_area=(25,4) # 该城市辖区(左上角x坐标,左上角y坐标,宽度,高度) district=(17,1,5,4) [/artifical] # 在(19,4)坐标处放置一只部队,兵种commander5,部队主将:12 {ANONYMITY_LOYAL_MERITORIOUS_UNIT 1 (commander5) 19 4 12 25 0 -20% 1 1 1} [+unit] canrecruit=yes [/unit] #{ANONYMITY_LOYAL_MERITORIOUS_UNIT 1 (horseman6) 35 28 48 25 0 -20% 1 1 1} #{ANONYMITY_LOYAL_MERITORIOUS_UNIT 1 (bowman6) 46 5 48 -100 0 -90% 1 1 1} [/side] {STARTING_VILLAGES 1 7} [side] side=2 {PLAYER_IF 136} shroud=$player.shroud fog=$player.fog controller=human recruit=footman1,horseman1,bowman1,catapult1,commander1,pikeman1,mage1 gold=100 income=0 {PLAYER_ELSE} controller=ai recruit=footman3,horseman3,bowman3,catapult3,commander3,pikeman3,whitemage3,redmage3 gold=200 income=120 {PLAYER_ENDIF_ELSE} leader=136 id=yuanshao {ANONYMITY_LOYAL_MERITORIOUS_CITY 2 2 47 2 126 220} [+artifical] service_heros=44,87,119,141,142,144,155,161,163,180,202,204 wander_heros=185 economy_area=(46,5) district=(45,1,5,4) [/artifical] {ANONYMITY_LOYAL_MERITORIOUS_UNIT 2 (commander5) 47 4 136 50 0 -20% 1 1 1} [+unit] canrecruit=yes [/unit] #{ANONYMITY_LOYAL_MERITORIOUS_UNIT 3 (bowman6) 47 5 87 50 15 -90% 0 1 1} [/side] {STARTING_VILLAGES 2 4} [side] side=3 {PLAYER_IF 3} shroud=$player.shroud fog=$player.fog controller=human recruit=footman1,horseman1,bowman1,catapult1,commander1,pikeman1,mage1 gold=100 income=0 {PLAYER_ELSE} controller=ai recruit=footman3,horseman3,bowman3,catapult3,commander3,pikeman3,whitemage3,redmage3 gold=200 income=150 {PLAYER_ENDIF_ELSE} leader=3 id=caocao {ANONYMITY_LOYAL_MERITORIOUS_CITY 3 3 58 16 128 300} [+artifical] service_heros=7,8,9,13,15,16,35,36,37,39,45,46,47,63,64,83,86,88,94,95,97,99,101,102,107,108,122,210 wander_heros=17,18,19,77,79,89,90,91,92,93,96,118 economy_area=(54,18) district=(56,14,5,5) [/artifical] {ANONYMITY_LOYAL_MERITORIOUS_UNIT 3 (commander5) 58 18 3 20 0 -20% 1 1 1} [+unit] canrecruit=yes [/unit] [/side] {STARTING_VILLAGES 3 5} {STARTING_VILLAGES_AREA 3 42 32 4} [side] side=4 {PLAYER_IF 140} shroud=$player.shroud fog=$player.fog controller=human recruit=footman1,horseman1,bowman1,catapult1,commander1,pikeman1,mage1 gold=100 income=0 {PLAYER_ELSE} controller=ai recruit=footman3,horseman3,bowman3,catapult3,commander3,pikeman3,whitemage3,redmage3 gold=200 income=120 {PLAYER_ENDIF_ELSE} leader=140 id=yuanshu #{ANONYMITY_LOYAL_MERITORIOUS_CITY 4 4 54 31 129 220} {ANONYMITY_LOYAL_MERITORIOUS_CITY 4 4 54 31 129 0} [+artifical] service_heros=143,153,158,166,197,198 wander_heros=34,65,66,67,68,69,111 economy_area=(49,29) district=(52,29,5,5) [/artifical] {ANONYMITY_LOYAL_MERITORIOUS_UNIT 4 (commander5) 54 33 140 25 0 -20% 1 1 1} [+unit] canrecruit=yes [/unit] [/side] {STARTING_VILLAGES 4 4} [side] side=5 leader=139 id=sunjian {PLAYER_IF 139} shroud=$player.shroud fog=$player.fog controller=human gold=100 income=0 recruit=footman1,horseman1,bowman1,catapult1,commander1,pikeman1,mage1 {PLAYER_ELSE} controller=ai gold=200 income=150 recruit=footman3,horseman3,bowman3,catapult3,commander3,pikeman3,whitemage3,redmage3 {PLAYER_ENDIF_ELSE} {ANONYMITY_LOYAL_MERITORIOUS_CITY 5 5 63 39 130 300} [+artifical] service_heros=0,6,14,20,21,22,23,24,25,26,27,28,29,30,41,100,115,116,156,187,188,189,191,193 wander_heros=173,182,183,184,190,192 economy_area=(63,36) district=(61,37,5,5) [/artifical] {ANONYMITY_LOYAL_MERITORIOUS_UNIT 5 (commander5) 63 41 139 20 0 -20% 1 1 1} [+unit] canrecruit=yes [/unit] [/side] {STARTING_VILLAGES 5 5} [side] side=6 leader=138 id=liubiao {PLAYER_IF 138} shroud=$player.shroud fog=$player.fog controller=human gold=100 income=0 recruit=footman1,horseman1,bowman1,catapult1,commander1,pikeman1,mage1 {PLAYER_ELSE} controller=ai gold=200 income=120 recruit=footman3,horseman3,bowman3,catapult3,commander3,pikeman3,whitemage3,redmage3 {PLAYER_ENDIF_ELSE} {ANONYMITY_LOYAL_MERITORIOUS_CITY 6 6 39 47 50 220} [+artifical] service_heros=1,33,40,110,145,148,149,160,171,172,177,178,179,196 wander_heros=43,85 economy_area=(40,44) district=(37,45,5,5) [/artifical] {ANONYMITY_LOYAL_MERITORIOUS_UNIT 6 (commander5) 39 49 138 25 0 -20% 1 3 4} [+unit] canrecruit=yes [/unit] [/side] {STARTING_VILLAGES 6 6} {STARTING_VILLAGES_AREA 6 13 2 4} [side] side=7 leader=137 id=menghuo {PLAYER_IF 137} shroud=$player.shroud fog=$player.fog controller=human gold=100 income=0 recruit=footman1,horseman1,bowman1,catapult1,commander1,pikeman1,mage1 {PLAYER_ELSE} controller=ai gold=200 income=100 recruit=footman3,horseman3,bowman3,catapult3,commander3,pikeman3,whitemage3,redmage3 {PLAYER_ENDIF_ELSE} {ANONYMITY_LOYAL_MERITORIOUS_CITY 7 7 18 47 131 220} [+artifical] service_heros=154,167,176,194,195,203,207 economy_area=(23,48) district=(16,45,5,5) [/artifical] {ANONYMITY_LOYAL_MERITORIOUS_UNIT 7 (commander5) 18 49 137 20 0 -20% 1 1 1} [+unit] canrecruit=yes [/unit] [/side] {STARTING_VILLAGES 7 4} [side] side=8 leader=4 id=liubei {PLAYER_IF 4} shroud=$player.shroud fog=$player.fog controller=human gold=100 income=0 recruit=footman1,horseman1,bowman1,catapult1,commander1,pikeman1,mage1 {PLAYER_ELSE} controller=ai gold=200 income=150 recruit=footman3,horseman3,bowman3,catapult3,commander3,pikeman3,whitemage3,redmage3 {PLAYER_ENDIF_ELSE} {ANONYMITY_LOYAL_MERITORIOUS_CITY 8 8 15 33 132 300} [+artifical] service_heros=5,10,11,31,32,42,58,59,60,61,80,81,82,106,162,168,209,212,213 wander_heros=150,211 economy_area=(16,37) district=(13,31,5,5) [/artifical] {ANONYMITY_LOYAL_MERITORIOUS_UNIT 8 (commander5) 15 35 4 20 0 -20% 1 1 1} [+unit] canrecruit=yes [/unit] [/side] [side] side=9 leader=135 id=dongzhuo {PLAYER_IF 135} shroud=$player.shroud fog=$player.fog controller=human gold=100 income=0 recruit=footman1,horseman1,bowman1,catapult1,commander1,pikeman1,mage1 {PLAYER_ELSE} controller=ai gold=200 income=120 recruit=footman3,horseman3,bowman3,catapult3,commander3,pikeman3,whitemage3,redmage3 {PLAYER_ENDIF_ELSE} {ANONYMITY_LOYAL_MERITORIOUS_CITY 9 9 3 22 134 220} [+artifical] service_heros=98,103,104,105,120,121,147,152,157,174,181,186,205,206,208 wander_heros=117,164,165,169,175 economy_area=(7,21) district=(1,20,5,5) [/artifical] {ANONYMITY_LOYAL_MERITORIOUS_UNIT 9 (commander5) 3 24 135 20 0 -20% 1 1 1} [+unit] canrecruit=yes [/unit] [/side] [side] # 演艺圈势力,打这势力中部队很涨经验 side=10 controller=ai # 势力名称 user_team_name=_"actor" leader=123 id=actor name= _"actor" recruit=horseman1 gold=0 income=0 [/side] [event] name=start [unit] # 溜二拐上场 type=stage player profile=liuxiang.png # 部队武将:38 heros_army=38 # 属于势力10:演艺圈 side=10 # 仔细看可以发现,一直都没有定义cityno=0的城市, # 而这里置cityno等于0,是故意要让指向一个不存在城市,也就是说这支部队是流浪部队 cityno=0 #x,y=34, 28 # 溜二拐初始出现在座标(48, 5)格子 x,y=48, 5 [/unit] [unit] type=famous director heros_army=123,124 side=10 cityno=0 #x,y=34, 27 x,y=48, 4 [/unit] [/event] # 挂接新回合时事件。 [event] name=new turn first_time_only=no # 每次新回合,要执行在野武将自荐 [recommend] [/recommend] [ai] # ai是否各顾各。no时,一旦玩家达到压倒性优势,所有敌对ai会自动同盟 selfish=no [/ai] [/event] # 挂接外交事件 [event] name=diplomatism first_time_only=no # ai遇到危情况时,像只剩一城,而且被围攻,会自动向其它AI请求同盟 [ally] [/ally] [/event] # 挂接溜二拐被打得退场时事件 [event] name=last breath # [filter]是个筛选器 [filter] # liuxiang # 快退场角色必须是溜二拐为主将部队,否则不执行以下动作 master_hero=38 [/filter] # 这个事件不仅执行一次 first_time_only=no [if] [variable] # 85%几率执行then块中操作, 15%几率执行[else]块中操作 name=random less_than=85 [/variable] [then] # 定义一个变量。初写mod时定义这变量目的为了简单,使用下来这种方式不行。但先暂时搁着,我是要实现这种方式的 # 为实现同样目的,现在在用的是后面那个变量:lxword [set_variable] name=lxidx rand=1..6 [/set_variable] # 定义一个变量 [set_variable] # 变量名lxword,值是后面那9个字符串中一个,随机取值 name=lxword rand=_"liuxiang word: 1", _"liuxiang word: 2", _"liuxiang word: 3", _"liuxiang word: 4", _"liuxiang word: 5", _"liuxiang word: 6", _"liuxiang word: 7", _"liuxiang word: 8", _"liuxiang word: 9" [/set_variable] # 定义一个变量 [set_variable] # 变量名coor_x,值是18..39中一个数字,随机取值 name=coor_x rand=18..39 [/set_variable] # 定义一个变量 [set_variable] # 变量名coor_y,值是后面那8..29中一个数字,随机取值 name=coor_y rand=8..29 [/set_variable] # 因为头像很难看,暂不显示。等改善对话框开再打开 #ifdef NORMAL # 溜二拐快退场时会干什么呢? # 1. 说出一句至理名言。名言内容就是lxword中内容,也就是或_"liuxiang word: 1", 或_"liuxiang word: 2",类推 [message] speaker=38 #message= _ "liuxiang word: $lxidx" pop_in_fog=no message= $lxword [/message] #endif # 2. 告知我退场了,自我爆炸 [kill] master_hero=38 #animate=yes [/kill] # 3. 他改为出现在coor_x和coor_y指定格子处 [unit] type=stage player profile=liuxiang.png heros_army=38 side=10 cityno=0 x,y=$coor_x, $coor_y [/unit] [/then] [else] # 15%几率是加入高稀屎部队 #ifdef NORMAL [message] speaker=123 pop_in_fog=no message= _"You have perfect potential, Come on!" [/message] [message] speaker=38 pop_in_fog=no message= _"I'm looking forward to it always" [/message] [message] speaker=123 pop_in_fog=no message= _"Bitch work together!" [/message] #endif [kill] master_hero=38 [/kill] # 加入高稀屎部队 [join] master_hero=123 join_hero=38 [/join] [/else] [/if] [/event] # 挂接高稀屎被打得退场时事件 [event] name=last breath [filter] # gxx master_hero=123 [/filter] first_time_only=no [set_variable] name=gxxidx rand=1..6 [/set_variable] [set_variable] name=gxxword rand=_"gxx word: 1", _"gxx word: 2", _"gxx word: 3", _"gxx word: 4", _"gxx word: 5", _"gxx word: 6", _"gxx word: 7", _"gxx word: 8", _"gxx word: 9" [/set_variable] [if] [variable] # 20%几率“信春哥,原地复活” # 80%几率在另一个地方出现 name=random less_than=20 [/variable] [then] [set_variable] name=coor_x value=$unit.x [/set_variable] [set_variable] name=coor_y value=$unit.y [/set_variable] #ifdef NORMAL [message] speaker=123 pop_in_fog=no message= _"Believe chun! Resurrection Man-state in-situ!" [/message] #endif [/then] [else] [set_variable] name=coor_x rand=18..39 [/set_variable] [set_variable] name=coor_y rand=8..29 [/set_variable] [/else] [/if] [kill] master_hero=123 #animate=yes [/kill] # 这个部队中可能有溜二拐,如果是,复活时要出来两只部队 [unit] type=famous director heros_army=123,124 side=10 cityno=0 x,y=$coor_x, $coor_y [/unit] [if] [have_unit] master_hero=38 [/have_unit] [then] [/then] [else] [unit] type=stage player profile=liuxiang.png heros_army=38 side=10 cityno=0 x,y=$coor_x, $coor_y [/unit] [/else] [/if] [/event] [/scenario]
三、战役地图(nanjun)
游戏提供专门编辑器用于编辑地图。
地图除了定义地形还定义了各个玩家阵营。就像以上就须要定义9个阵营,在地图中定义了每个阵营头头所在格子坐标,像阵营1(side=1),头头是除晃,在01_battle_nanjun.cfg中并没有指定站在哪个格子,因为他站的地方已由地图决定。
四、FAQ
A:ANONYMITY_LOYAL_MERITORIOUS_CITY宏
Q:ANONYMITY_LOYAL_MERITORIOUS_CITY宏用于在地图上放置一个城市。以实例说如何使用这宏。
{ANONYMITY_LOYAL_MERITORIOUS_CITY 18 12 117 51 223 220}
- 18: 城市标号。定义城外部队时要用它指示部队归属到的城市。自然数。不同城市必须不一样。一般做法是把第一个城市置为1,然后接下城市不断加1。
- 12: 势力标号。指市该城市归属的势力。[side]中的side值。
- (117, 51):城市在地图上坐标。
- 223:城市在hero.dat中的序号。
- 220:城市HP增加。220就是指该城比默认HP大220,可能是负值,像-100,就是指该城比默认HP小100。
ANONYMITY_LOYAL_MERITORIOUS_CITY在<src>/data/core/macros/unit-utils.cfg中定义。
#define ANONYMITY_LOYAL_MERITORIOUS_CITY CITYNO SIDE X Y HEROS_ARMY HITPOINTS [artifical] side={SIDE} type=city_city0 heros_army={HEROS_ARMY} x={X} y={Y} cityno={CITYNO} random_traits=yes random_gender=yes [modifications] {TRAIT_LOYAL} {TRAIT_ARCHITECTURE {HITPOINTS} 20 0 0 0} [/modifications] [/artifical] #enddef