设为首页收藏本站

红警DIY论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 28951|回复: 10

SAGE教程

[复制链接]
发表于 2010-11-29 10:43:04 | 显示全部楼层 |阅读模式
作者:赛特•亮


引言
        SAGE是EA历史上第一个3D战略游戏引擎,具备了基本的3D图像功能,例如可变视角、光影特效等。出自SAGE引擎的游戏平台为数不少,比较出名的如《将军》、《绝命时刻》,《泰伯利亚战争》、《凯恩之怒》,这些游戏平台最大的特色就是抛弃了以前TS引擎的“固定集成电路式”功能结构,改为使用更加底层、更加细腻的“独立元器件式”结构,通过组合嵌套这些元器件,能实现各种各样、花样百出的效果,令游戏开发乃至MOD制作都能够更加广泛地阔宽思路,因此SAGE引擎下的游戏平台被喻为“无所不能的平台”,更适合高级游戏开发者打造王牌战略游戏,这是TS引擎下的RA2、YR甚至PD平台都望尘莫及的强大实力。
        与此同时,TS引擎正在被硬件技术的高速发展所淘汰,这个光吃CPU不吃显卡的引擎将越来越跟不上时代的步伐,而PD平台基本上也算是挖掘了TS引擎的所有潜力,难以再次焕发第三春的活力,MODER们迫切地需要一个更适合他们使用的新平台。
        因此,是时候让高级MODER们转型到SAGE领域了……
 楼主| 发表于 2010-11-29 10:44:45 | 显示全部楼层
本帖最后由 yangqs 于 2010-11-30 10:36 编辑

第一章        入门从绝命时刻开始

      ZH是SAGE引擎的一部巅峰之作,它几乎发挥出了SAGE引擎所有的潜力,虽然图像处理效果确实还不够理想,不能和后来的CNC3相比,但论平台功能,它绝对是最丰富的一个。当然还有最重要的一点,ZH的代码是用我们习以为常的INI来编写的,条理非常清晰是它的最大优点,这比CNC3杂乱无章、看得让人头大的XML更人性化得多。因此我们将从ZH开始入门,进行对SAGE引擎的研究。
      首先我们有必要了解一下ZH的文件目录结构,搞清楚它的代码系统都是如何构成的,方便日后之作MOD时能立刻找到合适的下手点。
      打开ZH的安装目录,我们可以看到一些BIG文件压缩包,这些文件包和RA2时代的MIX有着异曲同工的作用,我们可以用XCC MIXER 打开INI.BIG,这是存放ZH所有规则文件的压缩包,把右侧列表定位到ZH的主目录,然后在左边全选所有内容,右键——复制,不出10秒,所有内容都提取出来了。
      或许你发现了,INI.BIG里的内容并不是以往MIX包那样的纯文件,而是含有一定的路径,例如“Data\INI\Armor.ini”,这是因为ZH平台识别的规则文件不像RA2那样直接放在在游戏主目录下,而是在Data\INI文件夹下。因此我们需要到这个文件夹下去找我们刚才提取出来的所有INI文件。
      如果你看见这个目录下有一大堆INI文件,千万别被吓傻,这就是SAGE引擎的特色——功能细分,整个游戏的重要规则需要很多个INI来定义并相互嵌套调用,而不像RA2那样用一个RULES来定义,自己内部调用。因此我们现在有必要认识清楚ZH的一些常用且非常重要INI各是什么内容,都表达出了哪些定义信息。(其余INI今后遇到了再讲解)
ini文件名作用简述
CommandButton按钮定义:定义各种界面按钮的功能和相关说明字段及图标图像
CommandSet界面布局:定义各种物体的界面按钮布局,需要调用CommandButton里定义的那些按钮
FXList视觉效果列表:定义各种视觉特效的动画效果、声音、震动等元素,例如核弹爆炸效果
Locomotor运动系统:定义各种单位的移动模式,决定了该单位是走还是飞、速度快还是慢、能去哪里
ObjectCreationList物体生成列表:定义各种OCL所生成的具体物体种类和数量(什么叫OCL?后面会讲解)
ParticleSystem粒子系统:3D游戏里95%的动画都是用粒子系统完成的,所以这是SAGE引擎的一大重点
Science将军技能:定义各种将军技能的学习前提及学习费用,是ZH的一大特色
SpecialPower超级武器:定义各种特殊能力及超武的类型、倒记时、范围圈等信息,和TS的原理相似
Upgrade升级项目:定义各种升级项目的研发费用、消耗时间等信息
Weapon武器系统:定义各种武器的伤害值、打击范围、伤害类型、死亡类型等信息,和TS的原理相似


      从这个表可以看出,SAGE和TS的差距是非常大的,所以有必要先转换自己的思维来对待这个外表熟悉,但实际上却陌生的新引擎,千万不要用TS的旧思维去对待SAGE、想当然而行、认为只要向以前那样做就行。如果不能转换思维,就很容易走进一条死胡同,让你成为又一个被SAGE吓倒的MODER。
      要转换自己的思维,首先必须要了解SAGE引擎的操作方式,而多玩ZHMOD或CNC3MOD是掌握它们的最佳途径。以下我列出了SAGE和TS的几大差别:
      1、 建造方式:
      TS的建造方式称为“宏观型”,特点是不管你有几个工厂,所有这些工厂都关联到同一个建造栏上,建造物体时只有被设置为“默认”的那个工厂在开工,其他工厂处于空闲状态。宏观型的建造方式决定了TS系列平台将自动建立单位和工厂之间的关联,你只需要制作好单位,这个单位的建造按钮就会被平台自动放置到建造栏上。
      SAGE的建造方式称为“微观型”,特点是各个工厂具有独立的建造栏,生产物体时相互不干涉,可以同时开工建造各自的单位。微观型的建造方式决定了SAGE系列平台不会插手单位和工厂之间的关联,这个关联是需要你自己去编写的,你不光要制作好单位,还必须要为对应的工厂添加生产这个单位的按钮,否则这个工厂是没办法生产这个单位的。
      2、 物体分类:
      TS对物体的分类是“注册法”,即将建筑、车辆、步兵、飞机等物体分类注册以获得不同的基本属性。注册法决定了一个单位只能属于其中一种类型,要么是建筑,就只能是建筑,不能即是建筑也是车辆,换言之,就是说不能获得所有你想要的基本属性,这一点无疑是限制了MOD的构思范围。
SAGE对物体的分类是“标签法”,即笼而统之将建筑、车辆、步兵、飞机等物体统称为Object,换句话说,建筑其实就是不能移动的坦克,而坦克同时也可以视为可以移动的房子。那么一个Object到底具有什么样的基本属性呢?这就是标签法的意义,一个物体可以拥有多种标签,每种标签代表一种基本属性,因此一个物体可以同时具有建筑、车辆、步兵、飞机的基本属性而成为一种全兼容的怪异单位,使MOD构思可以无限制的扩宽。
      3、 阵营结构:
      TS的阵营结构称为“共享模式”,这也是由于宏观型建造方式的一大特色,几个不同的国家可以属于同一个阵营,使用相同的建造栏、拥有相同的科技树,仅仅替换几种特殊兵种。例如RA2的3阵营10国家。
SAGE的阵营结构称为“独立模式”,这也是由于微观型建造方式带来的后遗症,一个国家只能属于一个阵营,使用各自独立的建造欠,拥有各自独立的科技树,虽然ZH里同一个阵营下属3个将军看起来好像科技树是相互差不多,但实际上他们却是3个完全不相关的独立阵营,拥有不同的建造栏和科技树,只不过是游戏开发者故意把它们做得来比较相似而已,这是一个障眼法。
      4、 图像格式:
      TS支持的图像格式有SHP动画图片和PCX静态图片,其中SHP使用非常广泛,这是一种256色索引图,需要对应的PAL调色板才能正确显示图像,否则将显示为乱色。SHP适合直接用作效果动画,例如弹头爆炸的动画可以直接用一个动画SHP来表现,使用现成的SHP比较方便,但制作新的SHP就麻烦得要死。
      SAGE支持的图像格式只有TGA静态图片(DDS被系统识别为TGA的压缩格式),这是一种32位真彩图,不需要调色板就能直接显示。TGA只能用作3D贴图及界面图片,由于其是静态图片的原因导致了不能直接制作成效果动画,必须依靠粒子系统的调用和运算才能表现出弹头爆炸动画。
      5、 模型格式:
      TS是一个含有半3D属性的2D引擎(假3D引擎),支持的模型格式为VXL像素体,这是一种依靠堆细小的像素点来构成形成一定的外形,用VXLSE来制作模型需要一个点一个点地描绘,虽然技术含量低但非常麻烦,虽然有3DS2VXL工具可以直接将3D模型转换成VXL,但由于TS引擎的低端性能,没办法做出精致的VXL模型。此外不得不提的是,TS的单位开火点、烟雾产生位置全靠RULES里的坐标来设置,因此非常难以调准确。
      SAGE是真正的3D引擎,支持的模型结构为W3D和W3X模型,这是一种用3DMAX制作而成的模型,不需要经过任何转换及后期处理,所有工作都在3DMAX里完成,因此制作过程相当简练,但并不简单,这需要扎实的3DMAX建模功夫及贴图功夫才能做出精致的模型。顺带要提的是,SAGE的单位开火点、炮塔指定、炮管指定、烟雾产生位置等直接由3DMAX里模型块或关节点来关联,因此不需要设置任何坐标,只要把模型画好,然后把这个模型块的名称拿给INI调用即可调节准确。
      6、 摄像机:
      TS的视角是固定的,摄像机机体的XYZ位置大约在(60:60:49)的点上,离地高度永远固定,焦距为无穷大,因此渲染出来的场景也是毫无景深感的二维直观图。
      SAGE的视角是可变的,摄像机的位置虽然有个默认值,但可以通过设置参数来改变它,同时在游戏进行时也可以利用小键盘的8246来变换视角,这样更容易贴近物体,近距离观察精致的模型结构。
      7、 代码结构:
      TS的代码类型很少,而主要发挥作用的只有Rules和Art,因此平台插手了大部分代码间的对应和关联,不需要你去人工编写,就像一个建筑的皮肤能自适应5种地形来现实不同的图像,完全是游戏平台管理了所有对应规律,你不能去改变它,因此工作量很小,只需要按照规律命名即可,使用方便但扩展性很小。
      SAGE的代码类型非常多,光ZH的主要INI就有10种(表1.01),因此平台基本上是不理会这些代码之间的对应和关联,99%的对应和关联需要MODER自己去编写。因此难度相对较大,工作量也提高了不少,但MODER可以自由发挥,扩展性非常大。
      8、 语句功能:
      TS的语句好比集成电路,一条语句实现一个固定的功能,只需要设置一个参数就能获得特定的功能,几条语句共存就能组成一套系统,使用起来相当简便,但由于集成电路的功能单调,因此系统的扩展性不高,也难以实现花样百出的功能效果,限制了MOD的构思范围。
      SAGE的语句好比元器件,一条语句、一个参数只能实现一个细节定义,似乎根本就体现不出SAGE的潜力到底有多强大。但如果用SAGE特有的Behavior模块将一系列语句和参数按照一定的规律组合,就能制作出你自创的集成电路,多个自创的集成电路相互组合嵌套,就能实现花样百出的强大系统,但由于使用元器件要求MODER具备更加扎实的底层技术,因此使用起来容易摸不着头绪,要做出优秀而高效的系统,难度也相当高。
      9、 语法特点:
      TS的语法称为“汇编级”,即用方括号表示段首字(如[MTNK]),没有结束字的概念,一个段落的内容从段首字开始,到下一个相邻的段首字结束,中间并列的所有语句都只能是单行,只实现一个功能,没有功能模块的概念,彼此不能相互嵌套。
      SAGE的语法称为“C语言级”,将单位代码、按钮代码、升级项目等所有内容都视为函数,每个函数都都必须有函数类型+函数名来作为段首字(如Object MTNK、Draw = W3DTankDraw ModuleTag_01、ConditionState = REALLYDAMAGED等)以及结束字End,和C语言里的花括号很相似,夹在段首字和End之间的所有内容便是这个函数的所有定义。而SAGE的函数还分为主函数和子函数,例如Object MTNK就是一个主函数,而Draw = W3DTankDraw ModuleTag_01则是一级子函数,ConditionState = REALLYDAMAGED为二级子函数,子函数能被主函数嵌套调用,低级子函数能被高级子函数调用,但主函数不能被任何函数调用,一个主函数内的所有子函数彼此并列,各自完成一系列功能,相互配合起来以完成一个嵌入式系统功能。

      综上所诉,不难看出SAGE的特点是更加底层化、更加微观化,更加独立化,适合思维宽阔的MODER使用,但正是因为它的这些特点而导致了平台的难度相当高,所以要想学好SAGE,从现在起就必须认真转变思维。
 楼主| 发表于 2010-11-29 10:46:48 | 显示全部楼层
本帖最后由 yangqs 于 2010-11-30 09:25 编辑

第二章        建立一个新单位

      首先我以建立一个新单位——灰熊坦克为例,来讲解SAGE基本代码的结构和相互调用规律。之所以要以灰熊为例,主要是因为这个单位没有什么特殊功能,基本上可以复制原版的现成代码,所以比较容易讲解清楚。
1、        建立单位代码
      比较特别的是,SAGE的Object.ini比较自由,你可以将灰熊的定义代码写在已有的那些Object.ini里,例如AmericaVehicle.ini,也可以单独建立一个全新的GrizzlyTank.ini来单独储存灰熊定义代码。理论上我比较推荐后者,因为这样方便今后迅速找到这个单位并修改其代码和功能,避免了TS里在RULES里翻来覆去地查找一个东西的烦琐。在编写代码的过程中特别要注意End,很多新手最容易犯的错误就是漏掉End,导致游戏无法正确识别函数而报错。

; 灰熊坦克
Object   MTNK

  ;============视觉、图像部分===========
  SelectPortrait          = HEAD122_MTNK                               选取该单位时界面上显示的大头像
  ButtonImage             = ICON64_MTNK                               生产该单位时旋转时钟图标的图像
  
  UpgradeCameo1= Upgrade_SyntheticalFuel   该单位具有的可升级科技项目图标,最多有5个,依次排列在单位大头像的右侧和下侧共5个格子里
  
  Draw = W3DTankDraw ModuleTag_01                                 模型绘制模块
    OkToChangeModelColor  = Yes                                         是否将模型里凡是以HouseColor%02d命名的模型快转换成所属色

    DefaultConditionState                                                      默认状态时的模型规则,通常可以理解为初生状态
      Model               = MTNK                                                 调用哪个W3D来显示其图像,需要自己用3DMAX来画这个模型,今后再讲如何画W3D模型
      Turret              = Turret                                                炮塔对应名称为“Turret”的模型块或骨骼点
      WeaponFireFXBone    = PRIMARY Muzzle                         主武器炮口特效产生位置对应名称为“Muzzle%02d”的模型块或骨骼点
      WeaponRecoilBone    = PRIMARY Barrel                           主武器炮管滑膛部分对应名称为“Barrel%02d”的模型块或骨骼点
      WeaponMuzzleFlash   = PRIMARY Muzzle                         主武器炮口闪光产生位置对应名称为“Muzzle%02d”的模型块或骨骼点
      WeaponLaunchBone    = PRIMARY Muzzle                        主武器开火点位置对应名称为“Muzzle%02d”的模型块或骨骼点
    End

    ConditionState = REALLYDAMAGED                                  破损状态时的模型规则,由于已经写了默认状态,因此其他状态里凡是和默认状态相同的规则可以略掉不写,
      Model               = MTNK_D                                            游戏平台会自动从默认状态里提取规则配给这个状态使用
    End

    ConditionState = RUBBLE                                                尸体/残骸状态时的模型规则,同样可以简略
      Model               = MTNK_D
    End

    TrackMarks            = EXTnkTrack.tga                               坦克在地面上开过后将留下什么样的履带印迹贴图
  End

;--------------------------------------------------------------------------------------------------


;============基本属性定义部分===========
  DisplayName             = VECHILE:MTNK                             鼠标悬停到该单位上时,显示的单位名称,需要CSF翻译
  Side                    = GDI                                                  无实际作用,仅仅为WB分类成列时作为依据,参数可以随便乱写
  EditorSorting           = VEHICLE                                       同上,作为WB的又一个分类成列依据,但参数不能随便乱写
  TransportSlotCount      = 3                                             被装载时需要占用的空间量
  VisionRange             = 90                                               视野范围,只有进入了该单位视野范围的敌人才会引起该单位主动开火
  ShroudClearingRange     = 90                                          能揭开黑雾和灰雾的范围
  MaxSimultaneousOfType   = 16                                        最大名额上限,即任何一方,该单位最多只能同时拥有16个,类似TS的人口限制
  MaxSimultaneousLinkKey  = MTNK   使用哪个人口空间,可以随意设置参数,通常只在特别要求该单位和别的单位共享同一个人口空间时才使用
  BuildCost               = 700                                               造价,这个不用多说
  BuildTime               = 7                                                   生产时间,单位为秒
  ExperienceValue         = 70  140  210  280                       被敌人杀死后送给敌人多少经验值,当自己为新兵、老兵、精英、王牌时分别送出70、140、210、280
  ExperienceRequired      = 0   210  420  630                      需要积累多少经验值才能达到对应级别,新兵级需要0点,老兵级需要210,精英级需要420,王牌级需要630
  IsTrainable             = Yes                                               是否可以训练,仅当参数为Yes时,ExperienceRequired语句才有意义
  CrusherLevel            = 2                                                碾压级别,通常坦克都填2,表示自己属于2级碾压者,可碾压小于2级的被碾压者
  CrushableLevel          = 2                        被碾压级别,通常坦克都填2,表示自己属于2级被碾压者,凡是碾压级别大于2的碾压者都能碾压它
CommandSet = GeneralUnitCommandSet 建造栏/操作栏界面使用哪一套布局,GeneralUnitCommandSet需要在CommandSet.ini里进行编写

  WeaponSet                                                       武器系统,类似模型绘制模块,可以利用Conditions来让单位在不同条件下使用不同的武器
    Conditions            = None
    Weapon                = PRIMARY GrizzlyGun                      主武器为哪个武器,GrizzlyGun需要在Weapon.ini里进行编写
  End

  ArmorSet                                                                       护甲系统,和武器系统差不多的设置原理
    Conditions            = None
    Armor                 = TankArmor    使用哪个护甲类型,护甲设置比较复杂,所以我们暂时借用一个现成的护甲,今后再着重讲解特殊护甲的之作
    DamageFX              = TankDamageFX              被攻击时产生什么样的受损特效(感觉是个没啥意义的花瓶功能,是把游戏变卡的重要途径)
  End

  Prerequisites                                                    建造前提系统,可以用物体作为建造前提(不光是建筑,也可以是坦克、士兵、将军技能等)
    Object                = GAWEAP                                          可以做成与、或逻辑,但尚不知道能不能做出非逻辑
  End
;--------------------------------------------------------------------------------------------------

  ;============单位语音、音效定义部分===========
  VoiceSelect             = GrizzlyTankSelect                             选取时的汇报音
  VoiceMove               = GrizzlyTankMove                             移动时的汇报音
  VoiceGuard              = GrizzlyTankMove                             自由警戒时的汇报音
  VoiceAttack             = GrizzlyTankAttack                            攻击时的汇报音
  SoundMoveLoop= GrizzlyTankMoveLoop 正常移动时发出的车辆运行音效,可做成循环音效,大概就是TS里坦克启动时会发出的发动机轰鸣声
  SoundMoveLoopDamaged    = GrizzlyTankMoveLoop            受损后移动时发出的车辆运行音效

  UnitSpecificSounds                                                           特殊语音及音效
    VoiceCreate           = NoSound                                        建造完毕后的汇报音,让我想起了基洛夫经典的“Kirov Reporting”
    TurretMoveStart       = NoSound                                     炮塔开始旋转时的音效,SAGE特有的功能,不过没啥意思
    TurretMoveLoop        = TurretMoveLoop                          炮塔持续旋转时的音效
    VoiceCrush            = NoSound                                        碾压别人时发出的音效
    VoiceEnter            = GrizzlyTankMove                              装载时的汇报音
  End
;--------------------------------------------------------------------------------------------------


;============基本属性定义部分===========
  RadarPriority = UNIT                          雷达里的标记类型,不同的标记有不同的优先权(没搞懂啥意思,难道优先权越高就越先被显示不成?)
  KindOf = PRELOAD SELECTABLE CAN_ATTACK ATTACK_NEEDS_LINE_OF_SIGHT CAN_CAST_REFLECTIONS VEHICLE INFANTRY SCORE
                                                                    属性标签,这是SAGE里的一大重点,放到后面来讲,先吊个胃口

  Body = ActiveBody ModuleTag_02                 生命值模块,定义了生命值上限、初生时的生命值以及被封冻武器封锁的准备时间和持续时间
    MaxHealth               = 300                         生命值上限
    InitialHealth           = 300                           初生时的生命值,又一个没啥意思的语句,一般都设置得和上限相同,除非你有特别邪恶的目的
    SubdualDamageCap        = 310         被封冻武器封锁的准备时间,其实不叫时间,应该说封冻武器必须“打”够这么多点“血”才能封冻住它
    SubdualDamageHealRate   = 500                下面这两句没测试出啥意思,一般都填成500和50
    SubdualDamageHealAmount = 50
  End
;--------------------------------------------------------------------------------------------------

  ;============功能模块定义部分===========
  Behavior = AIUpdateInterface ModuleTag_03   智能模块,决定该单位在不受玩家人工控制时能自主干些什么事
    Turret                                                       炮塔智能定义
      TurretTurnRate = 120                              自动或手动攻击时炮塔的旋转速度,单位为度每秒
      ControlledWeaponSlots = PRIMARY            手动攻击时发射哪个武器,如果同时并排上PRIMARY、SECONDARY和TERTIARY则表示多种武器同时开火
    End
    AutoAcquireEnemiesWhenIdle = Yes            空闲时是否自动迎击敌人,当然前提是敌人必须进入它的视野范围
  End

  Behavior = PhysicsBehavior ModuleTag_04      物理特性模块,定义了单位的一些物理引擎上能够表现出来的属性
    Mass = 40.0                                              重量,功能不太明显但非常重要的一个语句,今后会详细说明其作用
  End

  Behavior = DestroyDie ModuleTag_07             死亡方式模块 - 消失式死亡,即被杀后将本体的模型删除,安静得什么特效都没有
DeathTypes=NONE+CRUSHED+SPLATTED 当被带有这些DeathTypes类型的武器杀死时引发这种死亡方式,NONE表示无,加号表示“逻辑或”
  End

  Behavior = FXListDie ModuleTag_08               死亡方式模块 - 特效式死亡,即被杀后引发一项FXList来产生诸如爆炸烟雾的特效
    DeathTypes = NONE +CRUSHED +SPLATTED不同的死亡方式模块可以具有相同的死亡方式,这样的结果是,同时引发两种死亡方式,产生叠加效果
    DeathFX = FX_CarCrush                              引发哪一个的FXList
  End

  Behavior = CreateObjectDie ModuleTag_09   死亡方式模块 - OCL式死亡,即被杀后在原地刷出一系列物体,可以刷碎片甚至另一个活单位(刷活单位今后再讲)
    DeathTypes = NONE +CRUSHED +SPLATTED                                       
    CreationList = OCL_CrusaderTank_CrushEffect 根据哪个OCL项目的内容来刷物体
  End

  Behavior = CreateCrateDie ModuleTag_10       死亡方式模块 – 爆箱子式死亡,即被杀后在原地爆出一个垃圾箱,这跟OCL式死亡表现相似,但实际上有区别
    CrateData = SalvageCrateData                     根据哪个垃圾箱规律来爆箱
  End

  Behavior = SlowDeathBehavior ModuleTag_11 延迟死亡模块,使该单位被杀后延迟一段时间再死,利用这段时间来做“死亡过程”的动作
    DeathTypes = ALL -CRUSHED –SPLATTED   ALL表示所有死亡类型,减号表示“逻辑非”
    ProbabilityModifier = 25                               引发几率,单位为百分数,最大为100,即表示100%
    DestructionDelay = 2000                            延迟死亡时间,单位为毫秒,2000毫秒=2秒
    DestructionDelayVariance = 1000                延迟时间的随机偏差为1000毫秒,使得实际的延迟时间从1秒到3秒之间随机出现
    OCL = FINAL OCL_MTNKDebris 死亡动作完成后刷出什么东西来,作用和CreateObjectDie相同,但主要用来刷残骸,你也可以做点邪恶的构思
    FX  = FINAL    FX_BattleMasterExplosionOneFinal  死亡动作完成后引发什么FX特效,作用和FXListDie相同
  End

  Behavior = TransitionDamageFX ModuleTag_12   、受损后的冒烟效果,以及从正常状态变成破损状态的破裂特效
    ReallyDamagedParticleSystem1 = Bone:Smoke RandomBone:Yes PSys:SmokeSmallContinuous01               

                                                                    可定义冒烟点对应W3D里哪些关节点,以及定义烟雾为哪个粒子系统
    ReallyDamagedFXList1 = Loc: X:0 Y:0 Z:0 FXList:FX_BattleMasterDamageTransition

                                                                     破裂特效的产生位置,及定义使用哪个FXList作为破裂特效
  End

  Behavior = FlammableUpdate ModuleTag_13    被火焰类武器攻击后的持续扣血控制模块
    AflameDuration = 5000                               持续扣血的维持时间,单位为毫秒,5000毫秒=5秒
    AflameDamageAmount = 3                          每次扣除多少生命值
    AflameDamageDelay = 500                          相邻两次扣除生命值之间的间隔时间,可推算出整个模块为持续5秒、扣血10次,共扣除30点
  End

  Behavior = LocomotorSetUpgrade ModuleTag_14  运动系统升级模块
    TriggeredBy = Upgrade_SyntheticalFuel         当获得了Upgrade_SyntheticalFuel后,该单位的运动系统将发生更换
  End                                                             Upgrade_SyntheticalFuel需要在Upgrade.ini里进行编写

  Locomotor = SET_NORMAL               GrizzlyTankLocomotor                初始/默认状态下的运动系统
  Locomotor = SET_NORMAL_UPGRADED  GrizzlyTankSFLocomotor        升级运动系统后更换为哪个运动系统,这两个运动系统需要在Locomoto.ini里进行编写
  ; 特别需要注意的是,Locomotor语句必须写在所有功能模块之后,否则很容易引起报错
;--------------------------------------------------------------------------------------------------

;============形体体积及阴影定义===========
  Geometry = BOX                                          形体类型为长方体
  GeometryMajorRadius = 15.0                        半长度(从物体中心到头或尾的距离,即长方体长度的一半)
  GeometryMinorRadius = 10.0                        半宽度(从物体中心到左侧或右侧的距离,即长方体宽度度的一半)
  GeometryHeight = 13                                   全高度(从物体底部到顶部的距离)
  GeometryIsSmall = Yes                                 是否为小型形体,没搞懂有啥特殊作用
  Shadow = SHADOW_VOLUME                        阴影类型为3DMAX里最基础、最粗劣的表现形式——“体积阴影”,但最节省显卡
  ShadowSizeX = 45                                       阴影尺寸,单位为像素,似乎是个没有实际作用的垃圾语句
;--------------------------------------------------------------------------------------------------

End

      到这里,一个新单位的代码才刚刚具备雏形,因为我们还需要给它做很多相关的系统功能,例如武器系统、护甲系统、运动系统、操作栏界面、升级项目等。

2、        建立建造栏/操作界面
      SAGE除公用界面外,每一个物体都具有一个独立的建造栏/操作界面,例如ZH里这个界面上有14个按钮名额,CNC3为4个。你可以将一些特定的按钮放到你所想要的位置上去,形成一套界面:
      首先我们必须要清楚,一个单位需要什么样的界面布局,换句话说,就是指这个单位的界面上需要有些哪些按钮,各是什么功能,所以我们需要首先策划好界面布局。以这里的灰熊为例,由于它没有什么特别的功能,因此只需要具备3个基本的动作按钮就足够了,分别为“范围警戒”、“移动攻击”、“停止”。由于这3个按钮是原版就有的基本按钮,因此暂时不专门讲解按钮的做法,今后会着重讲解。
界面布局的14个按钮位置分别如下:

1        3        5        7         9         11        13
2        4        6        8        10        12        14

CommandSet GeneralUnitCommandSet
12 = Command_AttackMove                           移动攻击按钮,它的摆放位置在第12号空位上
13 = Command_Guard                                   范围警戒按钮,它的摆放位置在第13号空位上
14 = Command_Stop                                     停止按钮,它的摆放位置在第14号空位上
End

3、        建立武器系统
      和TS类似,武器系统也包括伤害值、打击范围、伤害类型(TS里称为弹头比率)、误差范围、射程、攻速、炮口动画等信息,而SAGE在TS的基础上还增加了一些新的功能,并把以前的某些宏观功能替换成了微观功能。打开Weapon.ini,在最后面添加这个武器:

Weapon   GrizzlyGun                                      和刚才定义单位代码一样,武器系统的段首字同样需要定义函数类型和函数名
  PrimaryDamage           = 105.0    直接伤害值,SAGE还有一个SecondaryDamage和SecondaryDamageRadius,表示辅助伤害值及其范围
  PrimaryDamageRadius     = 5.0                     直接打击范围
  ScatterRadiusVsInfantry    = 10.0                 对付步兵时的误差上限,当攻击距离越远时,误差越明显,达到极限射程时误差也达到极限值10
  AttackRange              = 150.0                      射程上限
  MinimumAttackRange      = 20.0                   射程下限
  MinTargetPitch            = -15                        能锁定到目标的最大下俯角度,通常是站在山上打山下时需要考虑,超出角度范围则不能开火
  MaxTargetPitch            = 15                        能锁定到目标的最大上仰角度,通常是站在山下打山上时需要考虑,超出角度范围则不能开火
  DamageType              = ARMOR_PIERCING   伤害类型,跟TS的弹头比率作用差不多,但原理正好相反,这个也是SAGE的难点之一,今后再讲
  DeathType                = NORMAL                  死亡类型,需要根据被杀单位的死亡方式来决定被这个武器杀死后将产生什么效果或死亡动作
  WeaponSpeed             = 800                      射弹体的出膛初速度
  WeaponRecoil             = 5                          后坐力大小,SAGE的特色,每开一炮都能使车身向后晃动以模拟后坐力效果
  ProjectileObject         = NormalShell  射弹体,前面说,SAGE把射弹体也视为Object,因此你甚至可以将一个活单位发射出去(仿人间大炮?)
  FireFX                    = WeaponFX_GenericTankGunNoTracerSmall                炮口特效
  ProjectileDetonationFX      = WeaponFX_GenericTankShellDetonation          射弹体引爆时的特效,作用类似于TS的弹头爆炸动画
FireSound                 = GrizzlyTankFiring                                                   开炮时的声音
  RadiusDamageAffects      = ALLIES ENEMIES NEUTRALS               

                                                               该武器的伤害范围对什么目标有效,ALLIES=本方或盟友,ENEMIES=敌人,NEUTRALS=中立者
  DelayBetweenShots        = 2000                 开炮间隔时间,类似于TS的ROF
  ClipSize                   = 0                            一个弹夹里的弹药总数,SAGE的特殊功能,可以模拟换弹夹效果,0表示无穷大,即不需要换弹夹
  ClipReloadTime            = 0                         换弹夹时间,通常之作枪械武器时才用,可模拟出CS里换弹夹的动作,0表示瞬间换弹夹
  ProjectileCollidesWith       = STRUCTURES WALLS   射弹体会撞到什么东西,STRUCTURES=建筑、WALLS=围墙,这里的参数是类型标签
End

      接下来还要继续为这个武器制作一个射弹体,即NormalShell,特效和语音暂时不做也没关系,我们可以暂时留空(随便写一个参数,游戏不会报错的),或临时借用原版现有的来用,今后再添加或替换也不迟。制作射弹体的方法和前面制作灰熊坦克的过程基本相似,因为它们都属于Object,你也可以专门为它建立一个INI来存放这段代码。

Object NormalShell

;============视觉、图像部分===========
  Draw = W3DModelDraw ModuleTag_01
    ConditionState = NONE                                 作用相当于DefaultConditionState
      Model = NormalShell
    End
  End
;--------------------------------------------------------------------------------------------------

  ;============基本属性定义部分===========
  DisplayName       = OBJECT:TankShell
  EditorSorting       = SYSTEM
  VisionRange        = 0.0                                    射弹体通常不应该具有视野范围及探路范围,所以弄成0        
  
ArmorSet
    Armor           = ProjectileArmor                      射弹体也可以被某种武器杀死,这是SAGE的特色,同时也是TS想都不敢想的特色
  End

;--------------------------------------------------------------------------------------------------

  ;============功能模块定义部分===========
  KindOf = PROJECTILE                                      被贴上了PROJECTILE(射弹体)标签的物体,以任何方式死亡都不会报告Unit Lost
  Body = ActiveBody ModuleTag_02
    MaxHealth       = 100.0                                  如同前面所说,射弹体是可以被杀死的,所以需要给它设置生命值
    InitialHealth      = 100.0
  End

  Behavior = DestroyDie ModuleTag_03  

                                                 没有DeathType语句,则该死亡方式默认为DeathType=ALL,即任何方式死亡都将导致这个模块指定的结果
  End
   
  Behavior = DumbProjectileBehavior ModuleTag_04  

                                                                   贝赛尔曲线弹道逻辑,可以设置特殊的参数,使抛物线变成直线,这也是TS想都不敢想的平射炮
    FirstHeight = 0                                              曲线上第一点的高度
    SecondHeight = 0                                          曲线上第二点的高度,由两个点可以控制一条贝赛尔曲线,两个点高度都为0则形成平射炮
    FirstPercentIndent = 33%                              第一点的位置
    SecondPercentIndent = 66%                          第二点的位置,0%表示炮口,100%表示落点,中间值则介于炮口到落点之间的弹道上
    OrientToFlightPath  = Yes                               使射弹体朝向飞行轨迹,没测试过填No会导致什么结果,难道射弹体会乱飞?
    FlightPathAdjustDistPerSecond = 300              每秒种调整飞行轨迹多少像素,可以使飞行轨迹比较平滑
  End

  Behavior = PhysicsBehavior ModuleTag_05
    Mass = 0.01                                                  射弹体的重力一般设置为0.01,即“非常轻”
  End

  Scale = 0.95                                                    模型缩放比率为W3D原形的95%
  Geometry = Sphere                                          形体类型为球体
  GeometryIsSmall = Yes                                                                                       
  GeometryMajorRadius = 1.0                              球体只一个尺寸参数,即半径
;--------------------------------------------------------------------------------------------------

End

4、        建立升级项目
      前面提到,灰熊坦克有一个切换运动系统的升级项目,因此现在我们需要在Upgrade.ini里来编写这个升级项目的代码:

Upgrade Upgrade_SyntheticalFuel
  DisplayName        = UPGRADE:SyntheticalFuel     升级提示信息时屏幕上出现的文字,需要CSF翻译
  BuildTime           = 60                                       升级准备时间为60秒,其实可以把升级理解为“建造”,因此这个时间相当于建造时间
  BuildCost           = 3000                                   确认此项升级需要花费的费用
  ButtonImage         = ICON64_SyntheticalFuel      正在升级时,旋转时钟图标上的图像,关于图标图像的之作今后再仔细讲解
  ResearchSound      = NoSound                          确认此升级时的汇报音,暂时留空,今后再修改
End

5、        建立运动系统
      通常来说,一个可移动的单位有一套运动系统就足够了,而这里的灰熊由于可以通过升级来替换运动系统,因此我们需要给它做两套运动系统,一套为初生的,另一套为升级之后的,打开Locomotor.ini写入以下这些内容:

Locomotor GrizzlyTankLocomotor                         初生时使用的运动系统
  Surfaces              = GROUND                             可进入的地形为,平地
  Speed                 = 45                                      正常时跑速为每秒45像素
  SpeedDamaged          = 22                                破损时跑速为每秒22像素
  TurnRate              = 50                   正常时车身转向速度为每秒50度(注意,车身转向速度和炮塔转向速度不再是同一个概念,切记不要混淆)
  TurnRateDamaged       = 25                               破损时车身转向速度为每秒25度
  Acceleration          = 40                                     正常时起步加速度为40像素每平方秒
  AccelerationDamaged   = 20                               破损时起步加速度为20像素每平方秒
  Braking               = 40                                       刹车时加速度(减速速度)为40像素每平方秒
  MinTurnSpeed          = 0                                    最小转向速度为0,不知道有啥特别的含义,一般都设置为0
  ZAxisBehavior         = NO_Z_MOTIVE_FORCE      Z轴特性为“无纵方向动力”,因为是坦克,所以要保持贴地不能跑飞起来
  Appearance            = TREADS                       运动表现为“履带式”,凡是用这种方式的单位,可在视觉、图像部分设置履带贴图的滚动效果
  AccelerationPitchLimit = 5                                  突然加速时,最大前后倾覆角度为5度,模拟车辆加速或减速时的头/尾下压效果
  PitchStiffness = 0.05                                        下压效果坚硬程度,属于物理引擎的表象,带有点NFS8的味道,暂时先不要随意乱动
  RollStiffness = 0.025                                         侧身倾斜效果的坚硬程度,同上
  PitchDamping = 0.8                                          下压阻尼强度,使产生下压效果时不必一步到位,而是逐步震荡衰减知道最后稳定下来
  RollDamping = 0.3                                            侧倾阻尼强度,同上
  ForwardAccelerationPitchFactor = 0.5                  前向加速下压比率,同样带有强烈的NFS8味道,没测试出有什么特别的效果
  LateralAccelerationRollFactor = 0.33                    侧向加速倾斜比率,同上
End

Locomotor GrizzlyTankSFLocomotor                     升级之后切换成这套运动系统,对比前后两套可看出仅仅是跑速增加了而已,其他没变
  Surfaces              = GROUND                            因此这个切换运动系统的升级实际上可以理解为“跑速加快”
  Speed                 = 56
  SpeedDamaged          = 28
  TurnRate              = 50
  TurnRateDamaged       = 25
  Acceleration          = 40
  AccelerationDamaged   = 20
  Braking               = 40
  MinTurnSpeed          = 0
  ZAxisBehavior         = NO_Z_MOTIVE_FORCE
  Appearance            = TREADS
  AccelerationPitchLimit = 5
  PitchStiffness = 0.05
  RollStiffness = 0.025
  PitchDamping = 0.8
  RollDamping = 0.3
  ForwardAccelerationPitchFactor = 0.5
  LateralAccelerationRollFactor = 0.33
End

      到此为止,一个完整的单位就算是建立完毕,除了一些相对麻烦切暂时不易讲解的语句,我们暂时借用了原版的参数外,其他必须要新做的代码都有这么几大篇,可见在SAGE上建立一个新单位是多么的复杂,希望MODER好好体会这5大步骤的内容。
或许性急的MODER在做好一个新单位后立刻就要到游戏里去测试这个单位的效果了,但是他们迫不及待地打开了游戏,却发现找不到任何一个地方可以生产这个新单位,于是在QQ上乱叫,“为什么我做的新单位不能被建造啊?”没办法,我只好让他们回过头去看第一章关于TS和SAGE的第一条差别——建造方式了。不用我再多废口舌了吧,不知道原因的自己翻回去看。

6、        让新单位可以被建造出来
      为了迅速说明问题的所在,我们来做个实验,让美国重工来生产灰熊坦克,首先我们要给美国重工的建造栏/操作界面添加一个新的建造键,用这个建造键来生产灰熊坦克,首先打开CommandButton.ini来编写这个新按钮的定义:

CommandButton Command_CreateMTNK        函数名可自己随意设置,只要能被CommandSet.ini正确调用即可,如果调用失败会导致致命报错
  Command               = UNIT_BUILD              按钮动作为“生产物体”
  Object                  = MTNK              生产哪个物体,参数就是我们刚才定义的灰熊坦克MTNK,如果参数不正确,这个按钮将是灰色且不能点击
  TextLabel               = CONTROLBAR:CreateMTNK   鼠标悬停到按钮上时就地显示的说明字段,需要CSF翻译
  ButtonImage            = ICON64_MTNK                  按钮图标
  ButtonBorderType       = BUILD                           外框颜色类型为“生产类”,在原版里为蓝色
  DescriptLabel           = CONTROLBAR:ToolTipCreateMTNK  鼠标悬停到按钮上时,左下方信息框里显示的解说字段,需要CSF翻译
End

      然后要在美国重工的界面布局里将这个按钮布置进去,特别注意,一个物体的界面上最多只能有14个按钮,假如原版已经占满了,我们就没地方可布置,那么就只能将原有的按钮去掉,将其位置空闲出来给这个按钮使用,打开CommandSet.ini,查找到AmericaWarFactoryCommandSet,其内容如下:

CommandSet AmericaWarFactoryCommandSet
  1  = Command_ConstructAmericaTankCrusader
  2  = Command_ConstructAmericaVehicleTomahawk
  3  = Command_ConstructAmericaVehicleHumvee
  4  = Command_ConstructAmericaVehicleMedic
  5  = Command_ConstructAmericaVehiclePaladin
  6  = Command_ConstructAmericaVehicleSentryDrone
  7  = Command_ConstructAmericaVehicleAvenger
  8  = Command_ConstructAmericaVehicleMicrowave
  9  = Command_UpgradeAmericaSentryDroneGun
  11 = Command_UpgradeAmericaTOWMissile
  13 = Command_SetRallyPoint
  14 = Command_Sell
End

      仔细观察可见,原版已经布置好了13个按钮,唯独10号位置上尚没有被任何按钮占据,因此我们正好可以把建造灰熊坦克这个按钮布置到10号位置上去,修改后的内容如下:

CommandSet AmericaWarFactoryCommandSet
  1  = Command_ConstructAmericaTankCrusader
  2  = Command_ConstructAmericaVehicleTomahawk
  3  = Command_ConstructAmericaVehicleHumvee
  4  = Command_ConstructAmericaVehicleMedic
  5  = Command_ConstructAmericaVehiclePaladin
  6  = Command_ConstructAmericaVehicleSentryDrone
  7  = Command_ConstructAmericaVehicleAvenger
  8  = Command_ConstructAmericaVehicleMicrowave
  9  = Command_UpgradeAmericaSentryDroneGun
10 = Command_CreateMTNK                    将刚才我们制作的那个按钮的函数名调用进来,切记必须和CommandButton.ini里设置的函数名一致
  11 = Command_UpgradeAmericaTOWMissile  否则的话,游戏将发生致命报错,根本无法运行
  13 = Command_SetRallyPoint
  14 = Command_Sell
End

      完成了这一系列设置之后,我们稍微修改一下灰熊的建造前提,以便使它在原版里能够被建造,即把Prerequisites(建造前提)里的GAWEAP更换为AmericaWarFactory,再到游戏里去测试,就能发现,美国重工可以生产这个单位了,将它建造出来看看,他的一系列功能是否都能达到你梦想中的要求。
      关于某些人在之作代码之后报错,我教你们一个办法,用地图编辑器WorldBuilder(月光宝盒)可以帮助你查错,启动月光宝盒后,它将自动进行查错,并将凡是有错的地方汇报给你,位置可以精确到一个确切的行上,如果你的英语水平达到了国家4级,你肯定能看懂它都说了些什么内容。当然,用月光宝盒查错,更多的时候查出来的只是一些不痛不痒,可有可无的小缺陷,这些缺陷可能是调用声音失败、调用图像失败等,并不影响游戏的运行,唯独只有出现了Run Time Error致命错误的地方才说明是这个地方导致了游戏的致命错误。
 楼主| 发表于 2010-11-29 10:48:28 | 显示全部楼层
本帖最后由 yangqs 于 2010-11-29 12:20 编辑

第三章  常用Behavior功能模块详解
      在上一章里我们通过新建灰熊坦克的单位定义代码了解到了SAGE精华——功能模块的一些用法,但仅以一个灰熊根本难以穷举SAGE所有的功能,因此本章将专门列举所有的功能模块并详细解说它的作用。
      首先要说明的是功能模块的书写格式,SAGE规定,功能模块属于二级函数,需要有函数类型(Behavior)、函数名(各种各样的功能模块名称),以及模块编号(%s),格式如下:
Behavior = [函数名称]  %s
      其中函数名称是一些平台内码,整个ZH平台一共就提供了这么多种功能,我们只需要调用即可。%s表示随意字符串,通常为ModuleTag_XX,目前尚不知道是否有多少个字符的长度限制,不过通常情况下为了保险,我们最好是按照一个统一的习惯,用ModuleTag_前缀加上两位数字来为函数排序。值得注意的是,任何物体代码中的各个模块不能使用相同的编号,否则会导致排序冲突,引起游戏和月光宝盒报错。

1、        死亡方式模块。这类模块的通用语句是DeathTypes,默认参数为ALL(随意),并可使用加减号来实现或、非逻辑,这些参数后面会着重列举讲解
Behavior = KeepObjectDie ModuleTag_XX                                                保留废墟式死亡,被杀后该物体已经被平台判死,但会留下该物体的RUBBLE阶段模型永远不消失
  DeathTypes = ALL
End
点评:本模块通常用于中立建筑,如民房、油井等,因为这些房子被毁掉后将留下一片废墟占据着地面。因此切记,如果要使用这种死亡方式,该物体必须含有RUBBLE阶段的模型,否则什么都不会显示出来,但该地皮上却不能重建房子,于是导致了视觉BUG

Behavior = DestroyDie ModuleTag_XX                                                        消失式死亡,即被杀后将本体的模型删除,安静得什么特效都没有
  DeathTypes = ALL
End
点评:这是一种最基本的死亡方式,如果希望某个单位死亡后悄悄地消失掉,不引起玩家的注意,那么用它是最好的选择

  Behavior = FXListDie ModuleTag_XX                                                        FX特效式死亡,即被杀后引发一项FXList来产生诸如爆炸烟雾的特效
    DeathTypes = ALL
    DeathFX = FX_CarCrush                                                                                引发哪一个的FXList
  End
点评:这种死亡方式需要专门为之制作一个FX特效,可用这个FX特效来间接调用粒子动画(例如爆炸烟雾、火焰等)、产生闪光、产生爆炸声音或产生屏幕抖动。DeathFX只能调用一个FX特效作参数,如果你需要多个特效组合起来产生效果,你可以考虑编写多个FXListDie模块,每个模块调用一个FX,以达到并列组合效果

  Behavior = CreateObjectDie ModuleTag_XX                                                OCL式死亡,即被杀后在原地刷出一系列物体,可以刷碎片甚至另一个活单位
    DeathTypes = ALL                                       
    CreationList = OCL_CrusaderTank_CrushEffect                                根据哪个OCL项目的内容来刷物体
    TransferPreviousHealth = Yes                                                                刷出来的物体将继承被杀物体的剩余生命值信息
  End
点评:这种死亡方式需要专门为之制作一个OCL列表,也就是说刷出来的物体可以是一种,也可以是多种,可以是一个,也可以是多个,可以使用碎片,也可以使用活单位(把步兵当作人间大炮打出去),总之OCL非常灵活,是SAGE的精华和强力功能之一,后面会着重讲解OCL的原理和制作方法

  Behavior = CreateCrateDie ModuleTag_XX                                                爆箱子式死亡,即被杀后在原地爆出一个垃圾箱,这跟OCL式死亡表现相似,但实际上有区别
    CrateData = SalvageCrateData                                                                根据哪个垃圾箱规律来爆箱
  End
点评:这种死亡方式需要专门为之制作一个CrateDate(垃圾箱逻辑),由于垃圾箱也是一种Object,因此假如你把爆箱子式死亡当成了OCL死亡来用,那简直就是糟蹋了它的实力。不过考虑到垃圾箱逻辑比较复杂,因此会放到后面来重点讲解

Behavior = UpgradeDie ModuleTag_XX                                                        取消升级式死亡,即被杀后可以将原本已获得的一个升级项目删除掉,所有相关单位会恢复到没有升级之前的性能
   UpgradeToRemove = Upgrade_AmericaHellfireDrone                                取消哪个升级项目,如果该项目并没有被升级过或升级尚未完成则不会有任何影响
  End
点评:这种死亡方式多用作后台处理,例如使某个升级键可以反复地使用多次,由于任何一个升级项目都只能升一次,但是可以通过取消来使之可以再重新升级,因此FK3D里辐射工兵的辐射爆发技能、间谍卫星的开屏技能就是用了取消升级的后台处理以实现可多次使用的目的
                                
  Behavior = RebuildHoleExposeDie ModuleTag_XX                                留地洞式死亡,本体死亡后可留下一个地洞,地洞是个特殊的Object,一定时间后可以自动重建成本体
    HoleName = GLAHoleArmsDealer                                                                本体死亡后留下哪个地洞
    HoleMaxHealth = 500.0                                                                                地洞最大生命值
  End
点评:这是来自GLA建筑的特色能力,其作用属于一种特别的延时重生,和魔兽里血巫的火凤凰是一个原理,如果你仅仅杀死火凤凰,它会留下一个蛋,而蛋在一定时间后自动又孵化成火凤凰,反复无穷地相互转变,看起来似乎永远不会死,但实际上只要把蛋杀掉,就能够阻止它继续重生了

  Behavior = SpecialPowerCompletionDie ModuleTag_XX                        超武完结式死亡,当本体死亡后,使对应超武复位,开始新的一轮倒记时
    SpecialPowerTemplate = SupW_SuperweaponNeutronMissile        使哪个超武开始新一轮倒记时,一次只能关联一个
  End
点评:这种死亡方式多用于OCL式超武的射弹体,当射弹体以任何方式死亡(包括引爆)时,将使对应超武复位开始新一轮倒记时。如果不是这个模块的帮助,该超武就只能发射一次

  Behavior = EjectPilotDie ModuleTag_XX                                                        释放驾驶员式死亡,本体死亡后将释放出一个与自身级别相同的驾驶员,和OCL式死亡很相似,但作用有所提高
    ExemptStatus = HIJACKED                                                                        排除状态为被盗取时,即正常状态下才能释放驾驶员,被劫持后是释放劫持犯
    GroundCreationList = OCL_EjectPilotOnGround                                根据哪个OCL列表来刷物体,当然,这里的物体特指驾驶员
    AirCreationList = OCL_EjectPilotViaParachute                                        驾驶员可分为地面和空中二种,前者是直接刷,后者是跳伞下来
    VeterancyLevels = ALL –REGULAR                                                        当本体的级别不是新兵时,释放出来的驾驶员的级别将与本体相等
  End
点评:这种死亡方式来自美军的绝大多数载具,其功能很相似于OCL式死亡,但比OCL式死亡更厉害的时,刷出来的单位可以与本体级别相等

2、        延迟死亡模块。这类模块的通用语句是DestructionDelay,控制死亡延迟的时间。虽然我将之称为延迟死亡,但千万不要误会这个模块可以让单位在变成尸体后还能继续当作骷髅兵使用,事实上当单位的血扣到0时,虽然不会马上死亡,但却已经不能再选中它,自然也就不能再使用它了,它将去做死亡过程动作。
Behavior = SlowDeathBehavior ModuleTag_XX                                        普通延迟,被杀单位将立刻停止一切动作并不再接受控制,静置原地,延迟一段时间后死亡
    DeathTypes = ALL
    ProbabilityModifier = 25                                                                                引发几率百分比,默认值为100,表示100%,即绝对
    DestructionDelay = 2000                                                                                死亡延迟时间,单位为毫秒,2000毫秒=2秒
    DestructionDelayVariance = 1000                                                                延迟时间的随机偏差为1000毫秒,使得实际的延迟时间从1秒到3秒之间随机出现
OCL = INITIAL   OCL_WorkerFlyingOffBikeDeathStart                        死亡动作开始时刷出什么东西来,INITIAL表示初始,即刚开始的时候
    OCL = FINAL    OCL_MTNKDebris                                                        死亡动作完成后刷出什么东西来,FINAL表示最终,即完成之后
FX  = INITIAL   FX_BuggyNewDeathExplosion                                死亡动作开始时引发什么FX特效
    FX  = FINAL    FX_BattleMasterExplosionOneFinal                        死亡动作完成后引发什么FX特效
  End
点评:常用于地面单位的一种死亡动作,用于坦克的话,被消灭的坦克不会像RA2那样立刻爆炸,而是先变成RUBBLE阶段模型,同时不再接受玩家控制、不再显示血格、不能被选中、立刻停止所有动作,静置在原地,延迟一段时间再爆炸,飞出炮塔、炮管残骸。而用于步兵的话,则通常利用这段延迟的时间让步兵做出死亡倒地的动作,逼真感十足。

Behavior = JetSlowDeathBehavior ModuleTag_XX                                        俯冲坠落延迟,被杀单位的死亡动作为从空中俯冲下来撞击地面
    DeathTypes = ALL
    DestructionDelay               = 2000
    RollRate                       = 0.0                                                俯冲坠落过程中本体的旋转速度,0表示不旋转
    RollRateDelta                  = 100%                                                调整旋转速度倍率的,100%表示原样速度,大于100%表示加快,反之则减慢
    PitchRate                      = 0                                                        俯冲角改变速度,0表示保持恒定的俯冲角下落
    FallHowFast                   = 25.0%                                                坠落速度百分比,100%的速度似乎是自由落体速度,和GameData里设置的重力加速度有关
    FXInitialDeath                  = FX_JetBigDeathInitial                被杀瞬间(刚开始俯冲时)引发的特效
    OCLInitialDeath                 = OCL_AmericaJetCargoDeathStart                刚开始俯冲时刷出来的物体
    DelaySecondaryFromInitialDeath  = 2000                                                俯冲状态持续时间
    OCLSecondary                  = OCL_AmericaJetCargoHulkDeath                撞到地面后刷出来的物体
    FXSecondary                   = FX_BigPlaneDeath                        撞到地面后产生的爆炸特效
  End
点评:这是一个逼真度非常高的死亡动作,完美地模拟了攻击机坠毁的全过程

  Behavior = NeutronMissileSlowDeathBehavior ModuleTag_XX                弹头爆炸延迟,被“杀”单位的死亡动作为连续释放出9个阶段的冲击波范围伤害
    DeathTypes = ALL                                                                                       
    DestructionDelay    = 3501                                                                        
    ScorchMarkSize      = 320                                                                        弹坑尺寸,由于是弹头爆炸,因此加入弹坑效果以增加逼真感
    FXList              = SupW_FX_Nuke                                                弹头爆炸过程的FX特效,例如核弹爆炸的蘑菇云
    Blast1Enabled       = Yes                                                                        启动1阶冲击波
    Blast1Delay         = 580                                                                        1阶冲击波产生延迟时间
    Blast1ScorchDelay   = 100                                                                        1阶冲击波导致弹坑的延迟时间
    Blast1InnerRadius   = 60.0                                                                        1阶冲击波内层伤害半径,凡是处于这个范围内的目标将遭受100%的伤害比率
    Blast1OuterRadius   = 120.0                                                                        1阶冲击波外层伤害半径,凡是介于内外层之间的目标遭受的伤害将削弱,不知道是不是按距离线性削弱
    Blast1MaxDamage     = 150.0                                                                1阶冲击波最大伤害值,特别注意冲击波的DamageType默认为EXPLOSION,属于平台内定的,没办法修改和替换
    Blast1MinDamage     = 75.0                                                                1阶冲击波最小伤害值,由最大和最小伤害值来产生一个随机伤害值的效果
    Blast1ToppleSpeed   = 0.5                                                                        1阶冲击波气浪扩散速度,冲击波可将树木冲倒
    Blast1PushForce     = 10.0                                                                        1阶冲击波气浪推力大小,冲击波可将高塔等死后会倒塌的物体推倒
    ………………………                                                                                    2-9阶冲击波的所有设置语句和1阶类似,此处略去。若不需要此阶冲击波,可以不定义
    OCL = MIDPOINT   OCL_NukeRadiationField                                        弹头爆炸后在爆心位置刷出什么物体,原版用它来给核弹刷辐射带,当然也可以刷活单位
  End
点评:我不知道这个模块除了用来做核弹还能用来做什么,虽然任何武器的射弹体都能使用,但由于爆炸伤害的DamageType只能是平台内定的EXPLOSION,不能替换成我们想要的类型,因此也很让人郁闷,而要在爆心刷物体,我们不如使用简单的OCLDie,估计它唯一的作用仅仅就是实现一个能将树木和房子推倒的效果

  Behavior = HelicopterSlowDeathBehavior ModuleTag_XX                        竖直坠落延迟,被杀单位的死亡动作为竖直向下跌落至地面
    DeathTypes = ALL
    DestructionDelay                = 99999999                                        搞不懂为什么竖直坠落的延迟死亡时间要设置这么长,难道是怕单位飞得过于太高,半天落不了地??
    SpiralOrbitTurnRate              = 140.0                                                坠落过程中的公转速度,类似RA2里飞碟那种即以本体中心为圆心自转,还要以体外某个点为圆心公转的坠落动作
    SpiralOrbitForwardSpeed         = 350.0                                                公转轨道前进速度,没搞懂啥意思,难道公转轨道的位置不是固定的?
    SpiralOrbitForwardSpeedDamping  = .9999                                        公转轨道速度阻尼大小,使公转轨道的移动速度不均匀地变动
    MaxBraking                     = 190                                                公转轨道负向加速度,类似于“刹车效果”   
    SoundDeathLoop                = ComancheDamagedLoop        坠落过程中播放的音效
    MinSelfSpin                     = 100                                                最小自转角速度,单位为度每秒
    MaxSelfSpin                     = 300                             最大自转角速度
    SelfSpinUpdateDelay             = 100                                                自转轨迹修正间隔时间
    SelfSpinUpdateAmount           = 10                                                自转轨迹修正量
    FallHowFast                     = 12.0%                                        坠落速度百分比,100%的速度似乎是自由落体速度,和GameData里设置的重力加速度有关
    MinBladeFlyOffDelay             = 750                                                最小碎片爆飞延迟时间,单位为毫秒
    MaxBladeFlyOffDelay             = 1500                                        最大碎片爆飞延迟时间,同上
    AttachParticle                    = SootySmokeTrail                        关联一个粒子系统,用于模拟黑烟效果
    AttachParticleBone               = Propeller02                                关联例子系统的骨骼点,需要对应W3D模型里的模型块/骨骼点名称
    BladeObjectName                = ComancheBlades                        碎片为什么物体,SAGE把碎片也认为是Object,因此可以替换成活单位,又一次邪恶……
    BladeBoneName                 = Propeller01                                关联碎片的骨骼点
    OCLEjectPilot                    = OCL_EjectPilotViaParachute                在半空中刷出一个物体,例如跳伞的飞行员
    FXBlade                         = FX_HelicopterBladeExplosion                爆出碎片时的FX特效
    OCLBlade                        = OCL_HelicopterBladeExplosion        爆出碎片时刷出什么物体,例如其余小残片、飞火等等
    FXHitGround                     = FX_HelicopterHitGround                        坠地时的FX特效
    OCLHitGround                   = OCL_HelicopterHitGround                        坠地时刷出什么物体
    FXFinalBlowUp                  = FX_GroundedHelicopterBlowUp                坠地引发气浪的FX特效
    OCLFinalBlowUp                 = OCL_GroundedHelicopterBlowUp        坠地引发气浪时刷出什么物体
    DelayFromGroundToFinalDeath    = 1500                                                                从坠地到最终死亡之间的死亡延迟时间
    FinalRubbleObject               = ComancheRubbleHull                                最终残骸物体,即死亡后地上残留的尸体
  End
点评:这似乎是SAGE里最复杂的延迟死亡模块,常用于直升机,整个坠落过程分得特别详细,事实上有很多语句都是多余的。

  Behavior = BattleBusSlowDeathBehavior  ModuleTag_XX                        战斗巴士爆炸延迟,不常用的模块,似乎只用于战斗巴士,因此研究不太透彻,若有错误请指出
    DeathTypes = ALL
    ProbabilityModifier = 5                                                                                引发几率百分比
    ModifierBonusPerOverkillPercent = 20%                                                过度伤害值加成几率百分比,正值为增加几率,负值为减少几率
    FXStartUndeath = FX_BattleBusStartUndeath                                        开始死亡过程时引发的FX特效
    OCLStartUndeath = OCL_BattleBusStartUndeath                                开始死亡过程时刷出什么物体
    FXHitGround = FX_BattleBusHitGround                                                死亡过程结束时引发什么FX特效
    OCLHitGround = OCL_BattleBusHitGround                                        死亡过程结束时刷出什么物体
    ThrowForce = 100.0                                                                                        爆飞力度,不知道是把自己爆飞还是把敌人爆飞??
    PercentDamageToPassengers = 50%                                                        本体死亡时对乘员的伤害,0%表示不伤害乘员,50%表示扣半血,100%表示直接扣死
    EmptyHulkDestructionDelay = 1000                                                        空残骸死亡延迟时间,没搞懂什么叫空残骸
    DestructionDelay = 0                                                                                死亡延迟时间,这里的死亡延迟时间相对于空残骸死亡时间来说应该是前一段,设置为0表示不使用
    DestructionDelayVariance = 200                                                                后面这些语句和普通延迟一样,就不多说了
OCL = INITIAL   OCL_WorkerFlyingOffBikeDeathStart                        
    OCL = FINAL    OCL_MTNKDebris                                                        
FX  = INITIAL   FX_BuggyNewDeathExplosion                                
    FX  = FINAL    FX_BattleMasterExplosionOneFinal                        
  End
点评:我对这个模块从来没有研究过,不知道有什么奥秘,而原版也只在战斗巴士上用过它,看语句似乎可以实现爆炸时一定几率的伤害值加成。有兴趣的MODER可以去研究研究。

  Behavior = InstantDeathBehavior DeathModuleTag_XX                        立即死亡(即不延迟),自然也就做不出任何死亡动作,只能产生FX特效和OCL
    DeathTypes = NONE +LASERED
    FX         = FX_GenericMissileDisintegrate
    OCL        = OCL_GenericMissileDisintegrate
  End

3、        加血类模块。这类模块的通用语句为HealingAmount和HealingDelay,用于控制每次加血量与间隔时间,加血模块可以给本体加血,也可以给本体周围的其他物体加血,使用范围非常广泛,包括广播塔和紧急维修技能也是一种变相的自动加血模块,因此我将它们放到一起来解说。
Behavior = AutoHealBehavior ModuleTag_XX                                                普通治疗
    HealingAmount     = 5                                                                                每次加血量
    HealingDelay       = 1000                                                                        加血间隔时间,单位为毫秒
    Radius             = 100.0f                                                                有效作用范围,若超过了自身体积则可以对周围物体加血,后面的“f”不知道有啥含义。默认为0,即只给自己加血
    StartsActive        = Yes                                                                        初始时是否激活。Yes表示自动激活,No则需要Upgrade来将其激活(见下面的TriggeredBy语句),默认为Yes
    KindOf            = VEHICLE INFANTRY                                        对含有哪些类型标签的物体有效
    ForbiddenKindOf   = AIRCRAFT                                                                对含有哪些类型标签的物体无效
    SkipSelfForHealing  = Yes                                                                        是否忽略自己,Yes表示不给自己加血,No则表示可以给自己加血,默认为No。
    TriggeredBy        = Upgrade_GLAJunkRepair                                如果StartsActive = No,则需要这里设置一个Upgrade项目来将之激活才能实现加血功能,否则什么作用都不起
    SingleBurst         = Yes                                                                        是否只作用一次,紧急维修里使用的特殊语句,Yes表示只加一次血,No则会按照间隔时间产生多次加血,默认为No
StartHealingDelay   = 15000                                                                        本体受伤后延迟多长时间再启动加血功能,单位为毫秒,一般只用于本体自加血的情况
  End
点评:这是最基本的一个加血模块,其功能几乎涵盖了以下3种特殊加血模块的所有功能,可以实现任何加血规则和效果,但要特别注意,这个模块里存在相互关联的语句,例如StartsActive为Yes的时候,TriggeredBy将失去意义,即便设置了Upgrade项目也是多余的,还有就是KindOf和ForbiddenKindOf是相互冲突的,其参数不能存在相同标签,胡乱设置的话小心引起逻辑冲突导致加血规则一塌糊涂。顺带说一句,不知道EA是怎么想的,有AutoHealBehavior还嫌不够,还要额外做那么多功能重复的多余模块。

Behavior = BaseRegenerateUpdate ModuleTag_XX                                基地恢复,这是一个宏观模块,没有参数,关于加血量和加血间隔都由GameData控制,原版里用于美军基地建筑
    ;No data                                                                                                        事实上完全可以用AutoHealBehavior来代替
  End
点评:纯属垃圾一个,我讨厌宏观功能。

  Behavior = AutoFindHealingUpdate   ModuleTag_XX                                自动搜索加血源,我没仔细研究过这个模块,从字面意思来看似乎能使本体在受伤后自动跑到维修厂或医院去请求加血
    ScanRate    = 1000                                                                                搜索间隔时间,单位为毫秒
    ScanRange  = 300                                                                                        搜索范围,难道说只要这个范围内存在加血源,他就要自动跑过去?
    NeverHeal   = 0.85                                                                                        当本体的剩余生命值大于多少时就不用去找加血源,0.85表示85%
    AlwaysHeal  = 0.25                                                                                        当本体的剩余生命值小于多少时就立刻去搜索加血源
  End
点评:看起来挺有意思,只是我没研究过,不知道会有啥新发现。有兴趣的MODER可以去探索探索。

  Behavior = PropagandaTowerBehavior ModuleTag_XX                                广播塔加血,用来加血的话简直糟蹋了这个模块,事实上它还有更加高深的用法,就看你是不是醉翁之意不在酒了
    Radius                  = 150.0                                                        有效作用范围,这个模块只能给周围物体加血(对自己无效),所以这个值必须大于自身体积
    DelayBetweenUpdates    = 2000                                                                脉冲特效间隔时间,单位为毫秒,只控制脉冲FX特效的播放间隔,不控制加血间隔时间
    HealPercentEachSecond  = 2%                                                                每秒钟恢复周围物体百分之多少的生命值,这不是一个固定值,而是用接受治疗物体的生命值上限计算出来的
    PulseFX                 = FX_PropagandaTowerPropagandaPulse                初始时的脉冲FX特效
    UpgradeRequired         = Upgrade_ChinaSubliminalMessaging                需要哪个Upgrade来升级成效果更强烈的加血作用
    UpgradedHealPercentEachSecond = 4%                                                                升级完成后,加血作用更改为每秒百分之多少
    UpgradedPulseFX        = FX_PropagandaTowerSubliminalPulse                 升级完成后的脉冲FX特效
  End
点评:之所以说醉翁之意不在酒,就在于广播塔可以利用升级来调用两个FX特效,于是一些怀有邪恶构思的MODER就利用这两个FX特效来做一些特殊效果,比如FK3D里蝰蛇巡航机的ForceField技能效果,以及英雄标志圈等等……感觉好像只有我本人才怀有邪恶的构思一样……

4、        升级切换类模块。这类模块的通用语句包括TriggeredBy和ConflictsWith,前者表示获得了某个Upgrade后开启该模块的功能,后者表示获得了某个Upgrade后关闭该模块的功能,可见二者是相互冲突的,在实际使用时千万要注意参数,否则将把升级功能搞得一塌糊涂。
此外必须要提到的是,TriggeredBy和ConflictsWith的参数可以有多个Upgrade,如果仅仅是单纯的并列时,表示或逻辑(即只要获得了其中任意一种Upgrade就开启/关闭模块功能),而TriggeredBy可以利用RequiresAllTriggers = Yes来将并列的几个Upgrade关系变成与逻辑(即必须获得了所有这些Upgrade才能开启模块功能)

  Behavior = MaxHealthUpgrade ModuleTag_XX                                        增加生命上限,启动模块后,该物体的生命上限增加一定数量
    TriggeredBy    = Upgrade_ChinaAircraftArmor
    AddMaxHealth  = 100.0                                                                                生命上限增量,例如原来是600,启动后就变成700了
    ChangeType    = ADD_CURRENT_HEALTH_TOO                                同时增加当前生命值,例如生命上限600,但物体受损后生命值还剩余200,启动后,当前生命值就变成300了
  End

  Behavior = ExperienceScalarUpgrade ModuleTag_XX                                经验值翻倍,启动模块后,该物体杀人所获得的经验值(包括贡献给将军的经验值)增加一定的倍数
    TriggeredBy   = Upgrade_AmericaAdvancedTraining
    AddXPScalar   = 1.0                                                                                翻1倍,即变成原来的2倍
  End

  Behavior = ObjectCreationUpgrade ModuleTag_XX                                刷物体,启动模块后,该物体将在当前所在位置刷出一系列物体
    UpgradeObject = OCL_AmericanBattleDrone                                        按照哪个OCL来刷物体
    TriggeredBy   = Upgrade_AmericaBattleDrone
    ConflictsWith = Upgrade_AmericaScoutDrone Upgrade_AmericaHellfireDrone                当获得了这两种Upgrade里的任意一种时,该模块关闭,不再发挥作用,也就啥也刷不出来了
  End

  Behavior = WeaponSetUpgrade ModuleTag_XX                                        切换武器系统,启动模块后,该物体的武器系统的条件标签将更换为PLAYER_UPGRADE
    TriggeredBy = Upgrade_AmericaSentryDroneGun
  End
点评:这个模块单独存在是不起任何作用的,必须要配合该物体代码里的武器系统——WeaponSet代码才能发挥作用,这是由于升级后,该物体的武器系统将自动被游戏平台打上一个PLAYER_UPGRADE的条件标签,这个标签影响了WeaponSet的选取情况,于是导致了切换武器的效果。例如我们这样来设置一个物体的武器系统:
  WeaponSet
    Conditions  = None                                                                                默认武器系统,即升级前使用的武器系统
    Weapon    = PRIMARY      SonicZap
    Weapon    = SECONDARY   NormalMissile
  End
  WeaponSet
    Conditions  = PLAYER_UPGRADE                                                        启动了WeaponSetUpgrade模块后使用的武器系统,同时默认武器系统将被屏蔽,暂时不被使用
    Weapon    = PRIMARY     SteadySonicZap
Weapon    = SECONDARY  ExplodeMissile
    Weapon    = TERTIARY     120mmX
  End
那么在升级之前,这个物体将以SonicZap为主武器,NormalMissile为副武器,没有第三武器。升级之后将更换为以SteadySonicZap为主武器,ExplodeMissile为副武器,多出了一个第三武器120mmX。而之前的SonicZap和NormalMissile将暂时不再被使用(除非用邪恶的手段扣掉已经获得的这项升级,如UpgradeDie等,使武器系统的条件标签又退回到None,那么之前的武器将再次被使用,而升级后的武器将暂时不再被使用)。

  Behavior = ArmorUpgrade ModuleTag_XX                                                切换护甲系统,启动模块后,该物体的护甲系统的条件标签将更换为PLAYER_UPGRADE
    TriggeredBy = Upgrade_AmericaChemicalSuits                                        这个模块的原理和WeaponSetUpgrade差不多,也需要配合ArmorSet语句,因此不再多讲,自己去体会它是如何切换的
  End

  Behavior = WeaponBonusUpgrade ModuleTag_XX                                武器强化,启动后,该武器的条件标签将更换为PLAYER_UPGRADE
    TriggeredBy = Upgrade_ChinaChainGuns
  End
点评:这个模块单独存在同样不起任何作用,必须要配合武器代码里的WeaponBonus语句才能发挥作用。例如在某个武器里加上这个语句:
WeaponBonus = PLAYER_UPGRADE  DAMAGE  150%
这里同样出现PLAYER_UPGRADE标签,可见WeaponBonus也是要识别标签才能发挥作用的。后面的DAMAGE表示强化伤害值,此外还可以选用RADIUS(伤害范围)、RANGE(射程)、RATE_OF_FIRE(攻速)、PRE_ATTACK(瞄准时间)。最后的150%表示变为原来的1.5倍。需要说明的是,提升攻速,填150%表示开火间隔时间缩短50%,即攻速加快,与TS正好是反的,同样瞄准时间也是如此,150%表示瞄准时间缩短50%,即更快地瞄准目标然后开火,这与TS又是反的,所以千万不要设置错了,否则就不是强化武器,而是弱化武器了。

  Behavior = LocomotorSetUpgrade ModuleTag_XX                                        切换运动系统,启动模块后,该物体的运动系统的条件标签将更换为SET_NORMAL_UPGRADED
    TriggeredBy = Upgrade_ChinaNuclearTanks
  End
点评:这个模块单独存在同样不起任何作用,必须要配合物体代码里的Locomotor语句才能发挥作用。前面提到过灰熊的运动系统是这样设置的:
  Locomotor = SET_NORMAL              GrizzlyTankLocomotor
  Locomotor = SET_NORMAL_UPGRADED  GrizzlyTankSFLocomotor
这里出现了SET_NORMAL和SET_NORMAL_UPGRADED两个标签,可见Locomotor也要识别标签来选取对应的运动模式给物体使用。有人认为运动系统的切换方向是单向的,但我认为这种说法并不十分确切,因为摩托车模块已经证明了运动模式可以来回切换,因此事实上只能说,SET_NORMAL和SET_NORMAL_UPGRADED之间的切换是单向的,即只能是前者切换成后者,后者永远也不能再倒退回前者,哪怕用邪恶手段扣掉已经获得的Upgrade也退不回去。而它们与其他标签之间的切换却是双向的,这个将在今后的进阶案例里讲解。

  Behavior = UnpauseSpecialPowerUpgrade ModuleTag_XX                        激活超武/技能,启动模块后,对应的超武/技能将恢复倒计时并允许被玩家使用
    SpecialPowerTemplate = SpecialAbilityHelixNapalmBomb                        激活哪一个超武/技能。前提是这个超武/技能处于未激活状态,否则这个模块不起任何作用(已经激活了还需要再激活么?)
    TriggeredBy = Upgrade_HelixNapalmBomb
  End
点评:这个模块单独存在同样不起任何作用,必须要配合SpecialAbility模块和SpecialAbilityUpdate模块才能发挥作用,同时还需要在SpecialAbility模块里设置StartsPaused = Yes使这个超武/技能初始不激活,这样才能使用UnpauseSpecialPowerUpgrade模块来将之激活,否则如果这个超武/技能本身就已经活了,你再激一次也是白激。

  Behavior = ModelConditionUpgrade ModuleTag_XX                                获取模型条件标签,启动模块后,该物体的模型模块将获得一个特定的条件标签,使其外观形状发生变化
    ConditionFlag = USER_1                                                                                
    TriggeredBy = Upgrade_ChinaSatelliteHackOne
  End
点评:这个模块单独存在同样不起任何作用,必须要配合物体代码里的W3DmodelDraw模块才能发挥作用,因为物体的模型也是要判断条件标签来显示对应的外观形状,所以有与没有某个条件标签将导致该物体模型外观发生改变。具体改变的原理将在今后讲解模型模块时专门讲解。

  Behavior = PowerPlantUpgrade ModuleTag_XX                                        获取额外电力,启动模块后,该物体可提供出额外的电力,其模型模块也将获得POWER_PLANT_UPGRADED条件标签
    TriggeredBy = Upgrade_AmericaAdvancedControlRods
  End
点评:这个模块单独存在同样不起任何作用,必须要配合物体代码里的EnergyBonus语句才能发挥作用,升级之后,该物体能提供出来的电力将加上EnergyBonus的参数得到最终电力提供量,例如EnergyProduction = 10,即默认提供10点电力,若有EnergyBonus = 5,则启动PowerPlantUpgrade模块后,该物体总共能提供出15点电力。此外由于W3DmodelDraw也获得了POWER_PLANT_UPGRADED条件标签,因此这个模块同样可以改变模型外观。

  Behavior = ReplaceObjectUpgrade ModuleTag_XX                                变身,启动模块后,该物体将变成另一个物体,而且没有TS那种变身限制,什么物体都可以相互变
    ReplaceObject = Chem_GLACommandCenter                                        变身成什么东西
    TriggeredBy = Upgrade_BecomeRealGLACommandCenter
  End
点评:这个模块看起来蛮吸引人,实际上是个垃圾模块,因为变身前后的两个物体之间没有任何关联,也就是说,变身前的所有状态、经验值、等级、剩余生命值信息将全部丢失,变出来的物体是个新生的物体,不会继承变身前的任何信息。

  Behavior = RadarUpgrade ModuleTag_XX                                                开启雷达,启动模块后,将开启雷达屏幕功能
    TriggeredBy   = Upgrade_GLARadar
    DisableProof  = Yes                                                                                        是否在停电时照常开启,按照TS的惯例,一般情况下应该设置为No,即停电后雷达关闭,来电了再开启
  End

  Behavior = StealthUpgrade ModuleTag_XX                                                启动隐形,启动模块后,该物体将隐形
    TriggeredBy = Upgrade_GLACamouflage
  End

  Behavior = SubObjectsUpgrade ModuleTag_XX                                        显/隐W3D模型块,启动模块后,该物体W3D模型里特定的模型块将被显示或隐藏
    TriggeredBy    = Upgrade_GLABombTruckBioBomb
    ShowSubObjects = Bombload02                                                                 显示哪些模型块
    HideSubObjects = Bombload01 Bombload03 Bombload04                隐藏哪些模型块
  End
点评:这是改变物体外观的一种快速方法,不需要考虑什么条件标签,也不需要设置模型模块的语句

  Behavior = PassengersFireUpgrade ModuleTag_XX                                允许乘员对外开火,启动模块后,封闭型载具将变成开放型载具(好比防空履带车变战斗要塞),内部乘员可以对外开火
    TriggeredBy   = Upgrade_ChinaHelixBattleBunker
  End

  Behavior = GrantScienceUpgrade ModuleTag_XX                                        免费获取技能证书,启动模块后,该玩家将免费获得一项技能证书,不花钱也不花经验点
    GrantScience = SCIENCE_MOAB                                                                取得哪项技能证书
    TriggeredBy = Upgrade_AmericaMOAB
  End
点评:这个模块说明,技能证书并不一定要靠杀敌人升级、积累经验点去学,可以拉关系、走后门非法获取。开个玩笑……

  Behavior = CommandSetUpgrade ModuleTag_XX                                        切换建造栏/操作界面,启动模块后,该物体的建造栏/操作界面将换成你想要的一个,同时还可以扣掉某些已经获得的Upgrade
    TriggeredBy = Upgrade_SwitchToQ
    RemovesUpgrades = Upgrade_SwitchToW Upgrade_SwitchToQ        扣掉哪些已经获得的Upgrade
    CommandSet = FLMCVCommandSetQ                                                更换为哪个建造栏/操作界面
  End
点评:切换建造栏/操作界面在ZH里最精妙的用法就是制作“翻页键”,所谓翻页键就是指一个物体拥有2套以上建造栏/操作界面,相互之间靠一个键来回切换,就像FK3D里的基地车那样,Q页(基地建筑页)上有一个W键,按下之后翻到W页(防御建筑页),W页上也有一个Q键,按下之后又翻回到Q页。翻页之所以可以反复地来回切换,主要就是靠RemovesUpgrades来扣掉已经获得的Upgrade,使这个Upgrade对应的升级键(W键和Q键)可以反复多次的点击,不至于说点过一次就变灰并且“该升级已经完成”。

  Behavior = CostModifierUpgrade ModuleTag_XX                                        调整造价,启动模块后,凡是含有对应类型标签的物体的造价将发生改变
    TriggeredBy  = Upgrade_CostReduction
    EffectKindOf = VEHICLE INFANTRY                                                        只要含有其中任意一种类型标签的物体都将调整造价
    Percentage   = -25%                                                                                造价降低25%,负数表示降价,正数表示抬价
  End
点评:总感觉这个模块缺了点什么东西,那就是没有非逻辑,难以精确地让某些物体调整价格。例如我要想设置,只让所有坦克降价,飞机不降价,这就做不出来,因为飞机和坦克都含有VEHICLE标签,飞机还多一个AIRCRAFT标签,而这个模块缺少非逻辑,因此没办法将含有AIRCRAFT标签的物体排除出去,于是飞机也只有被迫和坦克一起接受价格调整。

  Behavior = ActiveShroudUpgrade ModuleTag_XX                                        产生活动黑雾,启动模块后,该物体走在哪里就在哪里产生一团黑雾笼罩敌人的视野,就像RA2的裂缝发生器一样
    TriggeredBy = Upgrade_EnableGap
    NewShroudRange = 240                                                                                产生黑雾的范围
  End
点评:这是一个可移动的裂缝发生器

  Behavior = StatusBitsUpgrade ModuleTag_XX                                        获取状态标签,启动后,该物体将获得一个特定的状态标签,并可以清除一个自身已经存在的状态标签
    TriggeredBy  = Upgrade_Amphibious
    StatusToSet  = CAN_ATTACK                                                                获得哪个状态标签
StatusToClear = UNSELECTABLE                                                                清除哪个自身已经存在的状态标签
  End
点评:没有被原版使用的模块,似乎可以用作邪恶的构思,因为强制给物体打上某种状态标签后,该物体将反映出相应的属性,因此可以利用升级的方式来改变物体的状态属性以获得特殊效果。关于状态标签的用法将在以后详细讲解。

5、        特殊生成类模块。这类模块启动之后都能免费获得某些特别的东西。但这个“东西”的含义有时候仅仅指被游戏视为什么类型的物体。
  Behavior = VeterancyGainCreate ModuleTag_XX                                        免费获取等级
    StartingLevel = VETERAN                                                                        该单位初始等级为老兵,VETERAN=老兵,ELITE=精英,HERO=王牌
    ScienceRequired = SCIENCE_TechnicalTraining                                需要学到某个技能证书才能启动该模块的功能
  End
点评:从效果上讲,仿佛是靠学习技能证书来切换对应单位的初始等级。

  Behavior = GrantUpgradeCreate ModuleTag_XX                                        免费获取升级项目
    UpgradeToGrant  = Upgrade_Nationalism                                                获得哪个升级项目
    ExemptStatus = UNDER_CONSTRUCTION                                        当该物体在含有UNDER_CONSTRUCTION这个状态标签时不能获取,反过来说,不含这个标签时才能获取
  End
点评:前面说,技能证书可以靠关系走后门,而这里的升级项目也可以靠关系走后门,无需花费资金和时间去搞自主研发,难怪上汽的自主研发能力非常底下,却因为靠着大众和通用的关系坐在了中国汽车行业的头把交椅上,我彻底服了。

  Behavior = SpecialPowerCreate ModuleTag_XX                                        超武/技能关联者
    ;nothing                                                                                                        这个模块没有参数,因此是默认自动启动。凡是使用了这个模块的物体将被游戏平台视为超武/技能关联者
  End
点评:这是超武建筑和指挥中心必有的模块,不过这个模块并不起什么实际作用,仅仅是用来让游戏将本体识别为超武/技能关联者,用于地图编辑器里作判断。因此省略掉也不会影响超武/技能的倒记时和发射

  Behavior = SupplyWarehouseCreate ModuleTag_XX                                矿地(补给站)
    ;nothing                                                                                                        也没有参数,同样是默认自动启动。凡是使用了这个模块的物体将被游戏平台视为补给站,用于地图编辑器里作判断。
  End

  Behavior = SupplyCenterCreate ModuleTag_05                                        矿厂(资源采集中心)
    ;nothing                                                                                                        也是自动启动(都说烦了)。凡是使用了这个模块的物体将被游戏平台视为资源采集中心,用于地图编辑器里作判断
  End

  Behavior = PreorderCreate ModuleTag_XX                                                预定??没搞懂有啥作用
    ;nothing
  End

  Behavior = LockWeaponCreate ModuleTag_XX                                        锁定武器,可将同一套武器系统中其中一种武器锁定为默认使用,而没有被锁定的武器暂时不能被使用
    SlotToLock = PRIMARY                                                                                将主武器锁定为默认使用,而副武器和第三武器则暂时不能被使用,除非利用SwitchWeapon(切换武器键)来更换武器
  End
点评:可以参考游骑兵是如何更换武器的。游骑兵的主武器是重机枪,副武器是闪光弹,而默认情况下是锁定在重机枪上的,因此游骑兵一般情况下攻击敌人是开枪,但绝对不会冒失地丢出一个闪光弹。只有当玩家用他操作界面上那两个切换武器键来将副武器锁定为当前使用时,叫他攻击敌人,他就会只丢闪光弹却不开枪了。

6、        超武/技能类。这类模块的通用语句是SpecialPowerTemplate,调用一个SpecialPower(以后简称SP)来控制该超武/技能的倒记时和施展时的范围指示圈。同TS类似,这类模块也分宏观和微观两种。宏观型模块可以单独存在并发挥作用。微观型模块则必须和其他很多代码组合起来才能发挥作用。需要注意的是,有些模块使用的SP是有讲究的,不能随便乱用,否则会失去作用。这个问题将在后面详细讲解。
  Behavior = CleanupAreaPower ModuleTag_XX                                        范围清扫,微观型。施展后本体在一定范围内侦察潜在危险(如地雷)并将之清扫,需要和CleanupHazardUpdate模块连用
    SpecialPowerTemplate = SpecialAbilityAmbulanceCleanupArea
    MaxMoveDistanceFromLocation = 300.0                                                最大清扫范围,以目标点为中心向周围延伸的距离,通常和对应SP的范围指示圈一样大
  End

  点评:如果使用这个超武/技能,则必须加上一个CleanupHazardUpdate模块来控制侦察范围、侦察频率以及清扫危险时所使用的“武器”
  Behavior = CleanupHazardUpdate ModuleTag_XX                                        清扫危险功能修正模块,将在后面的功能修正类模块中详细讲解
    WeaponSlot            = PRIMARY                                                        使用哪个武器来清扫危险,通常使用DamageType = HAZARD_CLEANUP的武器
    ScanRate              = 1000                                                                侦察频率,1000表示每秒侦察1次
    ScanRange             = 100.0                                                                侦察距离,通常侦察距离不应该大于清扫武器的射程,否则本体会先侦察到危险,然后跑过去清扫,而不是就地处理
  End

  Behavior = CashBountyPower ModuleTag_XX                                        爆金币,宏观型。无需施展,本方任何单位杀死敌人后将获得敌人价格一定比率的金币奖励
    SpecialPowerTemplate = SpecialAbilityCashBounty1                                之所以无须施展,秘诀全在这里,这个SP需要特定的技能证书才能启动,因此只要学到技能证书就能启动该模块
    Bounty              = 5%                                                                        杀死敌人获得的金币为敌人价格的百分之多少,例如杀死一个犀牛,将得到900的5%,即45个金币
  End
点评:由于该模块的功能是由技能证书来进行切换的,因此可以重复做多个这样的模块,每获得一个更高一级的技能证书,爆出的金币价格比率就高一些,但我不太赞同这种结构,因为是宏观模块,比起PD平台的爆金币功能要拘束得多。

  Behavior = SpyVisionSpecialPower SpyTag_XX                                        偷窥基地,微观型。施展后将展示出所有敌人的基地情况,需要和SpyVisionUpdate模块连用
    SpecialPowerTemplate     = SuperweaponCIAIntelligence   
    BaseDuration             = 30000                                                        偷窥持续时间,单位为毫秒
    BonusDurationPerCaptured = 10000                                                        每施展一次获得的偷窥时间奖励,不知道是不是应该这样解释,我估计的……
    MaxDuration              = 240000                                                        最大总偷窥时间
  End

  Behavior = SpecialAbility ModuleTag_XX                                                        特殊能力,微观型。本体将获得一个可以施展的特殊能力,需要和SpecialAbilityUpdate模块连用
    SpecialPowerTemplate     = SpecialAbilityRedGuardCaptureBuilding
    UpdateModuleStartsAttack  = Yes                                                                开始施展该能力时修正该模块,即开始施展时将该SP暂时封冻,施展完成后放开,然后开始下一轮倒记时
    StartsPaused              = Yes                                                        初始时是否已激活。No表示初始时自动激活,Yes则反之,并需要UnpauseSpecialPowerUpgrade模块来将之激活
    InitiateSound              = RedGuardVoiceCapture                        开始施展该能力时播放的声音
  End
点评:特殊能力和超武的最大区别就在于射程,前者可以设置施展距离,若对很远的地方施展该能力,则本体必须先跑过去再施展(有点魔兽的味道),而后者不能设置施展距离,永远可以对全地图任意位置施展。只可惜ZH和CNC3没有好好地强化这个模块,以至于特殊能力模块能实现的功能不远及超武那么丰富,所以要是想用特殊能力来做魔兽里的英雄技能,那简直就是痴心妄想。

  Behavior = FireWeaponPower ModuleTag_XX                                        特殊开火,微观型。施展时本体将用当前一切可发射的武器向目标点开火,需要和WeaponSet语句连用
    SpecialPowerTemplate = SpecialPowerBattleshipBombardment
    MaxShotsToFire      = 3                                                                        开火倍数,施展时,一次性发射出正常情况下的多少倍弹药,假如正常攻击是2秒1炮,施展时则变成2秒3炮。
  End
点评:不太适用的模块。我没仔细测试过施展该超武/技能的时候,本体会不会把3种武器都以开火倍数那么多弹药一起发射出去,甚至根本不顾其中某个武器是否能攻击目标,如果WeaponSet搭配得不合理的话,很容易引起混乱。

  Behavior = OCLSpecialPower ModuleTag_XX                                                刷物体,微观型。施展时,本体将在特殊位置上刷出一系列物体,然后借刷出来的物体执行特定动作以实现超武打击过程
    SpecialPowerTemplate = SuperweaponParadropAmerica
    UpgradeOCL         = SCIENCE_Paradrop3 SUPERWEAPON_Paradrop3        提升到3级时所需要的技能证书,及施展时依据哪个OCL来刷物体(不以OCL_开头的OCL,可别看错)
    UpgradeOCL         = SCIENCE_Paradrop2 SUPERWEAPON_Paradrop2        提升到2级时所需要的技能证书,及施展时依据哪个OCL来刷物体
    OCL                 = SUPERWEAPON_Paradrop1                                                初始情况下(1级),施展时依据哪个OCL来刷物体
    CreateLocation       = CREATE_AT_EDGE_NEAR_SOURCE                                刷物体位置类型,有好几种可选,将在点评里说明
    OCLAdjustPositionToPassable = Yes                                                                                刷出来的物体是否自动调整位置,Yes表示刷出来的物体将自动被调整到可落脚的位置上,好比RA2里的伞兵,
  End        
                                                             你若往水里投掷伞兵,GI的落点不会在水面上,而是会自动调整到距离投掷点最近的岸边
点评:这才是SAGE里最强大的超武/技能模块,感觉基本上就是沿袭了TS的微观超武结构和原理,并作了一定的提升,尤其是ZH的特色——同一个超武/技能可以有多个逐步强化的阶段,完美地和ZH的技能表关联了起来,使超武/技能可以通过学习进阶技能证书来强化,例如学伞兵证书,学完1级,一次性可投3个GI,学完2级就变成一次性投6个,学完3级就变成1次性投9个。需要说明的是,UpgradeOCL语句存在先后次序,你必须把最高级别的一个放在最上面,最低级别的放在最下面,因此上面的例文里是先写3,再写2,最后写1。如果反过来写,则会导致学完进阶技能证书后,超武/技能却没有随之强化,那就等于是白学了。
CreateLocation语句控制着物体刷出位置,总共分为3类,分别为直接刷型(OCL的写法最为简单,直接将OCL里定义的所有物体刷到特定位置)、召唤运载型(OCL的编写比较复杂,在特定地图边界召唤出运载体,将特定的物体运载到目标点,然后投放)、自身运载型(本体就是运载体,因此无需再专门召唤运载体,OCL的写法类似于运载投放型),总共有以下这些参数可选:
CREATE_ABOVE_LOCATION                                                                        直接刷型。刷在目标点上空大约600到1000点之间的高度
CREATE_AT_LOCATION                                                                                直接刷型。刷在目标点所在的地表面上,也是这个语句的缺省参数
CREATE_AT_EDGE_FARTHEST_FROM_TARGET                                召唤运载型。最远离目标点的地图边界
CREATE_AT_EDGE_NEAR_TARGET                                                        召唤运载型。最靠近目标点的地图边界
CREATE_AT_EDGE_FARTHEST_FROM_SOURCE                                召唤运载型。最远离本体的地图边界
CREATE_AT_EDGE_NEAR_SOURCE                                                        召唤运载型。最靠近本体的地图边界
USE_OWNER_OBJECT                                                                                自身运载型。必须和ScriptedSpecialPowerOnly = Yes语句连用
对于召唤运载型和自身运载型,由于是需要运载体,因此它们的OCL写法和一般的OCL不太相同,这个将在后面详细讲解。

  Behavior = DefectorSpecialPower ModuleTag_XX                                        策反,宏观型。施展时,可将任何一个敌方的单位永久性地变成自己的人,有点像NP平台的永久控制
    SpecialPowerTemplate = SpecialPowerDefector
  End
  点评:估计是SAGE里最无聊而且最无能的一个模块,但却往往能引起菜鸟的关注,因为菜鸟肯定会联想起心灵控制。之所以说它无聊,是因为它根本不是真正的心灵控制,但却能吸引菜鸟的关注(主要还是因为菜鸟太菜的缘故),并且它可以不顾一切地控制整个地图上的任何目标,没有任何东西能抵挡它的控制,包括英雄,因此非常容易破坏平衡性,于是被ZH和CNC3作为禁招屏蔽掉了。 之所以说它无能,是因为它一次性只能控制一个单位,总的来说,比TS的心灵控制垃圾得多,根本就找不到任何启用它的理由。在此我奉劝各位MODER,如果不想找抽,最好别启用这个模块。

  Behavior = CashHackSpecialPower ModuleTag_XX                                凭空洗钱,无须施展,只要点下按钮,就能送你多少个金币,因此这些金币并不是从敌人那里偷来的,而是凭空产生的
    SpecialPowerTemplate   = SuperweaponCashHack                                
    UpgradeMoneyAmount  = SCIENCE_CashHack3 4000                        提升到3级时所需要的技能证书,以及洗出来的金币数量
    UpgradeMoneyAmount  = SCIENCE_CashHack2 2000                        提升到2级时所需要的技能证书,以及洗出来的金币数量
    MoneyAmount          = 1000                                                                初始情况下(1级),洗出来的金币数量
  End
  点评:这是个比较无耻的模块,但在原版ZH里比起来还不算最无耻,因为最无耻的是美军的补给平台(用时间换金币)、中国的黑客+网络中心(坐在地上就挣钱,而且挣久了还升级),GLA的黑市(简直就是个变相的油井)。使用的时候注意UpgradeMoneyAmount和MoneyAmount的排序,这跟OCLSpecialPower是一样的,高级在上,低级在下

  Behavior = OverchargeBehavior ModuleTag_XX                                        超负荷运转,姑且算个技能,使本体可以在持续自残的情况下超负荷运转,例如电厂可以输出额外的电力
    HealthPercentToDrainPerSecond    = 3%                                                每秒钟扣掉自己百分之多少的生命值
    NotAllowedWhenHealthBelowPercent = 20%                                        当生命值低于这个百分比时,将强制恢复正常,并且无法再超负荷
  End


7、        功能修正类模块。这类模块通常以Update为后缀,能够定义某个单位的各种细节功能,例如加钱、刷物体、炮塔属性、FX、OCL位置对应的骨骼点等等。但由于其种类过分地繁多,以至于有必要进行二次细分,将这些模块按照用法来分类讲解。
   (1)一般属性修正。
  Behavior = AutoDepositUpdate ModuleTag_XX                                        送金币,油井的关键模块,可以像每隔一定时间加钱,但只能加正钱(涨钱),不能像TS那样加负钱(扣钱)
    DepositTiming     = 2000                                                                        每隔多长时间送一次金币,单位为毫秒
    DepositAmount    = 20                                                                                每次送多少个金币,只能为正值,负值无效,将被视为0处理
    InitialCaptureBonus = 1000                                                                        获得该物体后立刻送多少金币,就像占领油井后马上可获得1000现金
    ActualMoney       = No                                                                        是否在送金币的时候在该物体头顶上显示送的钱数,似乎No才表示显示,Yes是隐藏
UpgradedBoost    = UpgradeType:Upgrade_AmericaSupplyLines  Boost:20                获得某个Upgrade后,每次多送多少金币
  End
  点评:EA脑壳有包,竟然把我们最期望的扣钱功能给干掉,这下做不出维护费概念了。

  Behavior = OCLUpdate ModuleTag_XX                                                        自动刷物体,凡是用上该模块的物体,其建造栏/操作界面将丢失,自动更换为刷物体的倒计时进度条
    OCL         = OCL_AmericaSupplyDropZoneCrateDrop                按照哪个OCL来刷物体
    MinDelay     = 120000                                                                                最短需要延迟多长时间才能开始刷物体,单位为毫秒
    MaxDelay     = 120000                                                                                最长延迟时间,同上
    CreateAtEdge = Yes                                                                                        是否从地图边缘刷出来。Yes表示从地图边缘刷出来(那就需要在OCL里配运载体),No则直接刷在本体身上
  End
  点评:ZH里的美军补给平台就是这样做出来的。事实上我们可以设置CreateAtEdge = No来干一些偷懒的构思,这样可以得到一个不需要手工去按键就能自动刷出物体的东西。AS的房子造房子概念就是用了这个模块实现的。

Behavior = RadiusDecalUpdate ModuleTag_XX                                        范围贴图,没有可设置的语句,尚未测试出它能如何影响物体的贴图
    ; nothing
  End

  Behavior = FloatUpdate UpdateTag_XX                                                        漂浮属性,使本体能像直升机那样在半空中摇曳摆动(终于遇到有史以来第一个不用ModuleTag_作为前缀的模块编号)
    Enabled = No                                                                                                是否允许悬浮,Yes则本体能飘到半空中去摆动,No则只能在地面(似乎应该说是水面才对)上摇曳
  End

  Behavior = LifetimeUpdate ModuleTag_XX                                                生存时间,使本体从诞生起,只能存活多长时间,时间到了自动自杀,这是TS想都不敢想的功能!
    MinLifetime = 3000                                                                                        最短生存时间,单位为毫秒
    MaxLifetime = 6000                                                                                        最长生存时间,通上
  End

  Behavior = DeletionUpdate ModuleTag_XX                                                存留时间,和生存时间的作用有点类似但时间到了不会自杀,而是直接消失掉,同时删除人口空间,等于是不声不响地自杀
    MinLifetime = 125                                                                                        控制时间的语句和生存时间一样,就不多说了(结果还是多说了)
    MaxLifetime = 500
  End
  点评:这两个模块作用非常大,大得我根本不知道从哪里来证明,总之,SAGE引擎如果缺了这两个模块将一事无成。但不得不提3个让人忍俊不禁的BUG,这个BUG似乎是从TS流传下来的。
第一  你给某个单位加上最短30秒的LifetimeUpdate或者DeletionUpdate,然后将它装进运输单位、碉堡、地道或中立房子,等半个小时回来看,那家伙竟然还在里面呆着没死,也没消失。但你一放它出来,它就马上死或者消失在你面前。
第二  还是给它加上最短30秒的LifetimeUpdate或者DeletionUpdate,然后将它装进运输单位、碉堡、地道或中立房子,然后马上放出来,那家伙竟然立刻死或者消失在你面前,明明30秒还没到,那家伙竟然就慌着见阎王去了……
第三  给某个步兵加上最短30秒的LifetimeUpdate或者DeletionUpdate,然后将它装进摩托车,然后再把摩托车装进地道,然后立刻再把摩托车从地道里放出来,结果摩托车刚一出洞口就莫名其妙地倒了。这个BUG在AS的IFV上典型地存在着,但在FK3D里被修复了。想知道我是怎么修复的吗?等后面讲到摩托车运载模块时再告诉你。

  Behavior = StealthUpdate ModuleTag_XX                                                隐形,使本体获得隐形能力,并可设置其隐形能力的属性
    StealthDelay                = 2000                                                        延迟多长时间才恢复隐形(通常表示挨打后被揭露多长时间然后恢复隐形),单位为毫秒,0表示立即恢复隐形
    StealthForbiddenConditions  = NONE                                                        在具备哪些条件标签的时候显形,NONE表示永远隐形,你也可以自己设置一些标签,例如使之开火时显形
    FriendlyOpacityMin          = 0.0%                                                        在盟友眼里的最小半透明程度
    FriendlyOpacityMax          = 0.0%                                                        在盟友眼里的最大半透明程度,两个值不同的时候,可以实现闪烁效果
    InnateStealth                = Yes                                                        初始是否隐形,用No的话则需要StealthUpgrade模块来开启隐形功能
    OrderIdleEnemiesToAttackMeUponReveal  = No                                当被敌人探测到时,是否会被空闲的敌人部队攻击,一般应该使用Yes比较好
  End

  Behavior = StealthDetectorUpdate ModuleTag_XX                                        探测隐形,使本体可以在一定范围内探测敌人的隐形物体并将之揭露出来
    DetectionRate           = 500                                                                探测频率,每500毫秒探测一次
    DetectionRange         = 150                                                                探测范围,缺省值为本体的视野范围,即VisionRange语句的参数
    CanDetectWhileContained = Yes                                                                当本体被装在运载体内部时能否继续探测
    ExtraRequiredKindOf     = INFANTRY                                                只能探测含有哪些类型标签的物体
ExtraForbiddenKindOf    = HERO                                                        不能探测含有哪些类型标签的物体
  End
  点评:再次遇到用类型标签来区分情况的模块,因此千万注意不要搞出冲突。

  Behavior = PowerPlantUpdate ModuleTag_XX                                        电厂修正,对于那些能升级电力的电厂,可以控制升级过程的持续时间,这个时间过了之后才能彻底完成升级
    RodsExtendTime = 600                                                                                完成Upgrade后,外挂部件(例如原版的能量棒,和FK的动力涡轮)在多少毫秒内慢慢地长出来,而不是瞬间刷出来
  End

  Behavior = RadarUpdate ModuleTag_XX                                                        雷达修正,对于具有雷达功能的物体,可以控制雷达屏幕打开的持续时间,在这段时间里,雷达屏幕将慢慢打开
    RadarExtendTime   = 4000                                                                        完成Upgrade后,雷达屏幕将在多少毫秒内慢慢打开,而不是瞬间打开
  End

  Behavior = AnimationSteeringUpdate ModuleTag_XX                                动画控制,可以修正3D动画的持续时间,感觉是个垃圾模块,因为需要它修正的动画修正不了,尽修正些不需要修正的
    MinTransitionTime = 300                                                                                最小动画持续时间,单位为毫秒
  End
  点评:这个模块似乎只和摩托车运载模块一起用,一开始我以为它能控制换乘员时摩托车的变形动作,但屡试屡败后才发现,原来这个模块是控制摩托车倒地动作的,也就是说,不加这个模块,摩托车在失去乘员后会瞬间倒地,加上之后才有一个倾翻的过程动作,当时简直有种想砸显示器的冲动……

  Behavior = HordeUpdate ModuleTag_XX                                                        群聚强化,当一定数量的单位聚集在一定范围内时,这些单位可获得一个临时的WeaponBonus强化标签
    RubOffRadius = 150                                                                                        群聚范围,群聚者最大有效范围
    UpdateRate = 1000                                                                                        每隔多长时间检测一次群聚情况,单位为毫秒
    Radius = 75                                                                                                有效间距,群聚者彼此相距不超过到这个距离才能被认为是有效群聚
    KindOf = VEHICLE                                                                                        允许带有哪些类型标签的群聚者获得强化
    AlliesOnly = Yes                                                                                                是否允许盟友加入群聚时获得强化,No则表示只能自己人与自己人群聚时获得强化
    ExactMatch = Yes                                                                                        是否要求必须是同一种单位才能获得强化,No则表示只要都带有相同类型标签的群聚者就能获得强化
    Count = 5                                                                                                        符合要求的群聚者达到多少数量时才能获得强化
    Action = HORDE                                                                                        获得哪一种强化标签,这种标签同时还会在这些群聚者的脚底下产生一定的特殊图像符号,例如星星或圆圈
  End
  点评:这个模块仅仅只能让群聚者获得一个强化标签,真正要实现强化效果,还需要设置GameData.ini里相应的武器强化规则。

  Behavior = AssistedTargetingUpdate ModuleTag_XX                                引导开火,自身开火时,可以引导周围一定范围类同类单位跟着它一起向目标开火
    AssistingClipSize = 4                                                               被引导者一次性辅助开火的弹药数量
    AssistingWeaponSlot = SECONDARY                                                        被引导者使用哪个武器来进行辅助开火
    LaserFromAssisted = AirF_PatriotBinaryDataStream                                引导者与被引导者之间使用哪个光束来连接
    LaserToTarget     = AirF_PatriotBinaryDataStream                                被引导者与目标之间使用哪个光束来连接
  End
  点评:使用了引导开火模块的物体,同一个WeaponSet里至少必须含有2种以上武器,并且还要确保其主动开火的武器代码里有RequestAssistRange语句来确定引导距离,例如我们把主武器作为主动开火,副武器作用辅助开火,我们就需要在主武器的代码里加上引导距离,假定RequestAssistRange = 240.0。这样一来,只要我们将几个这样的物体放在一堆,彼此之间的距离小于240像素时,只要其中一个物体开火,那么它周围的其他物体就会收到它的引导,并跟随它一起向目标开火。反之,距离开火者大于240像素的同类物体则收不到它的引导,也不会跟随它进行开火。
  另外有必要提的是,使用这个模块后,会将其中一种武器设置成了辅助开火武器(例如上面将副武器设置为辅助开火武器),那么在主动开火时,该物体就不会将这种武器发射出去。同时,当该物体在进行辅助开火的时候,也只将被设置为辅助开火的武器发射出去。

  Behavior = HijackerUpdate ModuleTag_XX                                                劫持犯修正,用于含有进入式占领模块的单位,当它占领了敌方飞机后,该飞机在空中被毁时,它将跳伞逃生
    ParachuteName = AmericaParachute                                                        劫持犯逃生时使用什么降落伞
  End

  Behavior = FireOCLAfterWeaponCooldownUpdate ModuleTag_XX        连续开火刷物体,需要连续开火多少发才能在落点处引发一个持续多长时间的刷物体系统,这个系统将自动刷出物体
    WeaponSlot            = SECONDARY                                                使用哪个武器来产生连续开火刷物体功能
TriggeredBy                        = Upgrade_GLAAnthraxBeta                        拥有了哪个Upgrade后才能启动该模块
    ConflictsWith           = Upgrade_GLAAnthraxGramma                拥有了哪个Upgrade后关闭该模块
    OCL                   = OCL_PoisonFieldMedium                        按照哪个OCL来刷物体
    MinShotsToCreateOCL   = 4                                                                        最少需要连续开火4次才能引发出刷物体系统,这个系统将在生存时间之内按照OCL不停的自动刷物体
    OCLLifetimePerSecond  = 10000                                                        刷物体系统每秒种增加多长的生存时间,单位为毫秒
    OCLLifetimeMaxCap     = 180000                                                        刷物体系统最长累计生存时间,同上
  End

  Behavior = ProductionUpdate ModuleTag_XX                                                工厂修正,定义工厂的成倍生产属性以及厂门属性等
QuantityModifier             = ChinaInfantryRedguard   2                生产某种单位时花一倍的造价可同时产出多少个这样的单位,前提是该工厂能生产这种单位。可多定义几行,每行一种单位
    NumDoorAnimations          = 1                                                        该工厂有多少个活动的门,所谓活动就是指具有3D动画,因此这需要和外观模块的定义以及W3D模型块的命名对应
    DoorOpeningTime            = 2000                                                厂门打开过程持续时间,单位为毫秒
    DoorWaitOpenTime           = 3000                                                厂门保持敞开的持续时间
    DoorCloseTime              = 2000                                                        厂门关闭过程持续时间
    ConstructionCompleteDuration = 1500                                                        从生产完成到单位产生之间需要间隔多长时间,也就是说,生产完成后,单位不会马上出现,必须过了这段时间才出现
  End
  点评:ConstructionCompleteDuration定义的时间,加上被产单位从诞生点走到厂门所需要的时间的总和不能比DoorOpeningTime定义的开门时间短,否则会出现门还没开完,单位就“破门而出”的尴尬局面。由于一个工厂通常能够生产很多种单位,这些单位速度有快有慢,因此要用最快的单位来计算时间,如果你嫌麻烦,最好是将ConstructionCompleteDuration的参数设置得和DoorOpeningTime一样。

  Behavior = ProneUpdate ModuleTag_XX
    DamageToFramesRatio = 5.0 ; I take 20 damage, I go prone for 100.  For this guy, if any of my buds or my building take damage too (I have SlaveUpdate + ProneUpdate) Prone may get cut by itself though
  End

  Behavior = MissileLauncherBuildingUpdate ModuleTag_XX                        超武/技能发射器修正,定义该物体在发射超武/技能时的EFGH动作(什么叫EFGH动作?看点评)
    SpecialPowerTemplate = SuperweaponNeutronMissile                        对应哪个SP,当该SP处于不同倒计时情况时,该物体产生相应的EFGH动作
    DoorOpenTime         = 8000                                                                开门动作持续时间(F),类似RA2里,核弹井打开,核弹竖立起来的这个动作
    DoorWaitOpenTime     = 2000                                                                就绪等待动作持续时间(G),类似RA2里,核弹攻击已经就绪但尚未发射时,核弹一直竖立在核弹井里的动作
    DoorCloseTime        = 8000                                                                关门动作持续时间(H),类似RA2里,核弹已经发射升空,核弹井就自动关闭,然后开始下一轮倒计时
    DoorOpeningFX        = ChinaNuclearMissileLauncherDoorOpen                开门过程中产生什么样的FX特效,比如心灵控制器在开门的时候会出现剧烈闪光
    DoorWaitingToCloseFX  = ChinaNuclearMissileLauncherLaunch                        超武发射升空后,等待关门时产生什么样的FX特效
    DoorClosingFX        = FX_ABPowerPlantExplode                        关门过程中产生什么样的FX特效
    DoorOpenIdleAudio    = BuildingNeutronMissileHiss                        超武已经就绪但未发射的过程中,一直播放的效果音
  End
  点评:对于某些没有做过TSMOD,直接进入SAGE的MODER,我不得不解释一下什么叫EFGH动作。这个称呼的来历是RA2将超武建筑的状态分为空闲、开门、就绪、关门,而他们在Art.ini里定义这4个状态对应模型名称时使用后缀E表示空闲,F表示开门,G表示就绪,H表示关门。因此后来就广泛地被MODER们称为EFGH动作。

  Behavior = RepairDockUpdate ModuleTag_XX                                        维修厂修正,使本体获得维修单位的能力,并定义修到满血需要花费多长时间以及排队位置
    TimeForFullHeal          = 5000                                                        修复时间,单位为毫秒,这是指从死血修到满血需要花费的时间,因此实际上是以当前生命值按照这个比例来计算时间
    NumberApproachPositions = 5                                                                排队等待位置有多少个点,需要对应W3D里的骨骼点,排队的单位将站在这些点上等待进入
  End

  Behavior = DemoTrapUpdate ModuleTag_XX                                                陷阱修正,用于陷阱类物体,控制敌人靠近它时引发它开火的各种方式
    DefaultProximityMode      = Yes                                                        是否使用默认引发模式
    DetonationWeaponSlot     = PRIMARY                                                自动引发时使用哪个武器开火
    ProximityModeWeaponSlot  = SECONDARY                                        敌人靠近时引发它使用哪个武器开火
    ManualModeWeaponSlot    = TERTIARY                                                手动引爆(通过点击界面按钮)时它使用哪个武器开火
    TriggerDetonationRange    = 40.0                                                        引发距离。当敌人离它的距离小于这个值时,引发成功
    IgnoreTargetTypes         = PROJECTILE UNATTACKABLE        排除含有哪些类型标签的“敌人”。含有这些类型标签的敌人不会引发它
    AutoDetonationWithFriendsInvolved = Yes                                                当附近盟友遇到麻烦时自动引发,貌似判断盟友的距离也是由TriggerDetonationRange决定的(连盟友都炸么?)
    DetonateWhenKilled        = Yes                                                        引发后是否自杀
  End

  Behavior = PilotFindVehicleUpdate   ModuleTag_XX                                自动寻找载具,用于驾驶员,它在空闲时能自动扫描身边有没有符合要求的载具,如果有,就自动跑过去
    ScanRate  = 1000                                                                                        每1秒钟扫描一次
    ScanRange = 300                                                                                        扫描范围
    MinHealth  = 0.5                                                                                        当扫描到的载具的生命值不足多少时,它就不去,0.5表示50%
  End
  点评:这个模块只能控制本体在空闲状态时的动作(似乎放到人工智能类里比较合适),至于它能否进入被扫描到的载具,还取决于它是否含有接触类模块,例如驾驶员的VeterancyCrateCollide模块。如果没有的话,它顶多跑到载具面前就不动了,因为进不去……。此外我暂时还不知道能不能把这个模块放到劫持犯上去用,使它自动扫描敌人的载具,然后自动跑过去将之捕获。

Behavior = CommandButtonHuntUpdate  ModuleTag_XX                        猎杀修正,用上这个模块的单位将可以利用触发动作来执行满地图寻找敌人来杀的动作脚本
  End

  Behavior = CleanupHazardUpdate ModuleTag_XX                                        清扫危险功能修正模块,前面讲CleanupAreaPower模块的时候提到过它,因为它才是实际产生作用的模块
    WeaponSlot            = PRIMARY                                                        使用哪个武器来清扫危险,通常使用DamageType = HAZARD_CLEANUP的武器
    ScanRate              = 1000                                                                侦察频率,1000表示每秒侦察1次
    ScanRange             = 100.0                                                                侦察距离,通常侦察距离不应该大于清扫武器的射程,否则本体会先侦察到危险,然后跑过去清扫,而不是就地处理
  End

  Behavior = PointDefenseLaserUpdate ModuleTag_XX                                自动反制修正,使本体时刻扫描周围,当发现符合要求的目标时都能够自动发射特定武器来反制之
    WeaponTemplate      = PaladinPointDefenseLaser                        反制时使用哪个武器,这个武器不需要写在WeaponSet里,也就是说是一种额外的武器
    PrimaryTargetTypes    = BALLISTIC_MISSILE SMALL_MISSILE                遇到含有哪些类型标签的目标时会立刻启动反制
    SecondaryTargetTypes  = INFANTRY                                                        遇到含有哪些类型标签的目标时可能会准备启动反制(优先级别比上面一条低)
    ScanRate              = 500                                                                每半秒种扫描一次
    ScanRange             = 120.0                                                                扫描范围
    PredictTargetVelocityFactor = 3.0                                                                预测目标速度的因素,即常言道的“打提前量”
  End

  Behavior = FirestormDynamicGeometryInfoUpdate ModuleTag_XX        动力学形体尺寸修正,定义一个尺寸不断变化的物体在各个时刻时的形体参数
    InitialDelay         = 800                                                                        初始延迟时间,即初始时刻从哪个时候开始
    InitialHeight        = 10.0                                                                        初始高度
    InitialMajorRadius  = 1.0                                                                                初始主半径
    FinalHeight        = 10.0                                                                        最终高度
    FinalMajorRadius   = 90.0                                                                        最终主半径
    TransitionTime     = 3000                                                                        过渡过程持续时间
    ReverseAtTransitionTime = Yes                                                                是否反转时间,启动双向过渡,即变过去然后又变回来
    ScorchSize        = 100.0                                                                        弹坑尺寸
    ParticleOffsetZ = 0.1                                                                                粒子系统产生点的Z方向偏移量
    ParticleSystem1 = FireStormMain                                                                粒子系统1
    ParticleSystem2 = FireStormMainRing                                                        粒子系统2
    FXList          = FX_FireStorm                                                                引发哪个FX特效
    DelayBetweenDamageFrames = 500                                                        相邻伤害帧之间的延迟间隔时间
    DamageAmount             = 100.0                                                        伤害值大小,尚不知道产生伤害的DamageType是哪个
  End
  点评:从字面上来看好像是用来做一个尺寸不断变化的射弹体或者弹头

  Behavior = HeightDieUpdate ModuleTag_XX                                                高度死亡修正,定义一个物体在处于什么高度时自杀
    TargetHeight                 = 15.0                                                        引发自杀的高度
    TargetHeightIncludesStructures = Yes                                                        当该物体处于建筑头顶上时,是否以建筑的顶面高度作为参考基准
    OnlyWhenMovingDown       = Yes                                                        仅当该物体下落到高度低于TargetHeight参数值时引起自杀
    SnapToGroundOnDeath       = Yes                                                        引发自杀的瞬间立刻闪到地面上,哪怕中途还存在一定距离,换言之就是说死必须死在地面上,不能死在半空中
    InitialDelay                   = 1000                                                初始延迟时间
  End

  Behavior = EnemyNearUpdate ModuleTag_XX                                        靠近敌人修正,暂时不知道有啥作用
    ;nothing
  End

  Behavior = FlammableUpdate ModuleTag_XX                                                持续燃烧修正,当遭受DamageType=Fire的武器攻击之后,会使之持续燃烧受损一段时间
    AflameDuration = 5000                                                                                燃烧持续时间
    AflameDamageAmount = 5                                                                        每隔一定时间扣掉多少生命值
    AflameDamageDelay = 500                                                                        每隔多长时间扣一次生命值
    BurningSoundName = GenericFireMediumLoop                                燃烧时持续播放的效果音
  End

  Behavior = FireSpreadUpdate ModuleTag_XX                                                火种扩散修正,使正在燃烧的物体将周围其他物体点燃,使它们也开始持续燃烧
    OCLEmbers       = OCL_BurningEmbers                                        扩散时刷出什么东西,例如,火球、火星
    MinSpreadDelay   = 1000                                                                        发生火种扩散时的最短延迟时间
    MaxSpreadDelay   = 2000                                                                        发生火种扩散时的最长延迟时间
    SpreadTryRange   = 50                                                                                火种成功扩散的最大距离,超过这个距离的其他物体将无法被点燃
  End

  Behavior = FireWeaponUpdate ModuleTag_XX                                        自动开火修正,使本体在没有开火的时候使用不停地发射一个特定的额外武器,通常这个额外武器是个自释放型武器
    Weapon = SneakAttackShockwaveWeaponSmall                                未开火时不停地发射哪个武器
    InitialDelay = 10                                                                                                第一次发射时延迟多长时间
  End
  点评:原版的微波坦克就是这样做出能把步兵烤焦的能力的。通常来说,这个自动开火的武器应该是自释放型的武器,即以开火点为中心向四周辐射的范围伤害武器,如果是一般武器的话,我怀疑它会盲无目的地乱打。此外还有一点不得不提,带有自动开火修正的物体,如果被装进了运输船之类的“容器”,那么自动开火将立刻停止,等到你放它出来时,它才会继续开火。后面讲到FK3D如何避免到IFV自爆BUG的时候会用到这个修正。

Behavior = WeaponBonusUpdate ModuleTag_XX                                        武器强化修正,使本体不停地释放一个光环效应,周围一定范围内的其他物体在一定时间内获得一个武器强化标签
    RequiredAffectKindOf = CAN_ATTACK                                                含有哪些类型标签的物体能够获得强化标签
    ForbiddenAffectKindOf = STRUCTURE                                                含有哪些类型标签的物体不能获得强化标签
    BonusDuration = 10000                                                                                获得的强化标签能持续有效多长时间
    BonusDelay = 100000                                                                                本体每隔多长时间释放一次光环
    BonusRange = 200                                                                                        距离本体多远距离内的物体能够获得强化标签
    BonusConditionType = FRENZY_ONE                                                        获得哪种的强化标签
  End

  Behavior = EMPUpdate ModuleTag_XX                                                        电磁脉冲修正,使靠近本体一定范围的周围单位遭受一定时间的EMP封锁
    DisabledDuration    = 10000                                                                封锁持续时间
    Lifetime            = 500                                                                        本体生存时间,即脉冲持续时间,控制着本体外观尺寸的变化情况
    StartFadeTime      = 100                                                                        开始淡入的时间
    StartScale          = 0.01                                                                        开始时本体的外观尺寸比率
    TargetScaleMin     = 2.00                                                                        最终时本体的外观尺寸最小比率
    TargetScaleMax     = 3.00                                                                        最终时本体的外观尺寸最大比率
    StartColor          = R:0 G:255 B:255                                                开始时本体的染色情况,RGB分别代表红绿蓝的饱和度,最小0,最大255
    EndColor           = R:0 G:128 B:128                                                最终时本体的染色情况
    EffectRadius        = 60                                                                        EMP效应的作用范围
    DisableFXParticleSystem = EMPSparks                                                被封锁的单位身上出现的电火花粒子系统
    DoesNotAffect      = ALLIES                                                                不封锁哪些类型的目标
    DoesNotAffectMyOwnBuildings = Yes                                                        不封锁自己人的建筑(仅仅是不封锁建筑,但依然还要封锁自己人的部队)
  End

  Behavior = MobMemberSlavedUpdate ModuleTag_XX                                班组修正,控制一个班组里所有组员时刻保持队形
    MustCatchUpRadius      = 40                                                                组员在掉队多远的时候会自动跟近,换言之就是说任何组员不得离开班组多远
    NoNeedToCatchUpRadius = 15                                                                组员在距离班组多近的时候不需要再自动跟近,相当于任何组员和班组之间的距离在15到40之间随时调整
    Squirrelliness            = 0.05                                                                松鼠线形?没搞懂是啥意思
    CatchUpCrisisBailTime    = 30                                                                班组在保持距离时的整队时间,也就是说,掉队的组员会在30帧内快速跑回来靠近其他组员
  End
  点评:班组概念在ZH里暂时还是个初次的尝试,因此暴民还存在不少让人忍俊不禁的BUG,因此暂时不提倡在ZH里使用班组,要用最好到CNC3里去用

Behavior = SlavedUpdate ModuleTag_XX                                                从属修正,没有语句,仅仅让游戏平台把本体视为某个主体的Option,使本体从属于它的主体
    ;nothing
  End

  Behavior = StructureCollapseUpdate ModuleTag_XX                                崩塌修正,使本体在死亡时发生崩塌,刷出一系列物体、引发一系列FX特效
    MinCollapseDelay        = 500                                                                最小崩塌延迟
    MaxCollapseDelay        = 1000                                                        最大崩塌延迟,即死亡瞬间不会马上崩塌,要延迟一段时间才开始崩塌
    CollapseDamping         = 0.0                                                                崩塌阻尼
    MaxShudder              = 0.6                                                                崩塌时的最大抖动程度
    MinBurstDelay           = 250                                                                最小爆炸延迟
    MaxBurstDelay           = 800                                                                最大爆炸延迟
    BigBurstFrequency       = 4                                                                爆炸产生频率,单位大概是次每秒
    OCL                     = INITIAL   OCL_StructureCollapseInitial                        以下是崩塌过程中刷出的物体以及引发的FX特效
    OCL                     = DELAY     OCL_StructureCollapseDelay
    OCL                     = FINAL     OCL_StructureCollapseFinal
    FXList                  = INITIAL   FX_StructureCollapseInitial
    FXList                  = DELAY     FX_StructureCollapseDelay
    FXList                  = BURST     FX_StructureCollapseBurst
    FXList                  = FINAL     FX_StructureCollapseFinal
  End

  Behavior = StructureToppleUpdate ModuleTag_XX                                倾倒修正,使本体在死亡时发生整体倾倒,砸到东西可以产生伤害
    MinToppleDelay      = 250                                                                        最小倾倒延迟
    MaxToppleDelay      = 500                                                                        最大倾倒延迟,同样在死亡瞬间不会马上倾倒,要延迟一段时间才开始倾倒
    MinToppleBurstDelay = 1500                                                                        最小爆炸延迟
    MaxToppleBurstDelay = 2500                                                                        最大爆炸延迟
    StructuralIntegrity    = 0.75                                                                        本体完整程度,1表示100%完整,即从根部断裂,0.75则大约是中部偏下的地方断裂
    StructuralDecay      = 1.0                                                                        本体腐朽程度,没搞懂有啥意义,难道是指在倾倒过程中不会散架?
    DamageFXTypes      = ALL –WATER                                                被哪些DamageType的武器打死后引发受损FX特效
    ToppleStartFX        = FX_DefaultStructureToppleStart                        开始倾倒时引发的FX特效
    ToppleDelayFX        = FX_DefaultStructureToppleDelay                倾倒过程中引发的FX特效
    CrushingFX           = FX_SmallTowerCrushing                                砸到东西时引发的FX特效
    AngleFX              = 20.0 FX_StructureToppleAngle20                倾倒角度以及倒至这个角度时引发的FX特效
    ToppleDoneFX        = FX_DefaultStructureToppleDone                完全倒地时引发的FX特效
    CrushingWeaponName  = ToppledStructureWeapon                        用哪个武器去砸下面的人
  End

  Behavior = ToppleUpdate ModuleTag_XX                                                倾倒反弹修正
    ToppleFX = FX_ToppleLampPost                                                                倾倒时引发的FX特效
    BounceFX = FX_LampPostBounce                                                        反弹时引发的FX特效
  End

  ClientUpdate = SwayClientUpdate ModuleTag_XX                                        摇曳服务修正,使物体能像树木一样摇曳,实际上也就是树木专用的一个模块
    ;nothing
  End

  Behavior = CheckpointUpdate ModuleTag_03                                                检查站修正,使本体获得检查站的功能,至今不知道检查站是个啥东西
    ;nothing
  End

  Behavior = WaveGuideUpdate ModuleTag_04
    WaveDelay                  = 750    ;(in milliseconds)delay till wave starts moving
    YSize                      = 650.0  ;size in Y
    LinearWaveSpacing          = 15.0   ;linear waves get pushed up at these intervals across
    WaveBendMagnitude          = 500.0  ;shape of wave (larger # = more flat and 0 = straight line)
    WaterVelocity              = 2.7    ;in dist per sec, velocity to "push up" the water
    PreferredHeight            = 37.3   ;water level we want to be after the wave
    ShorelineEffectDistance     = 5.0   ;this far behind the wave we "hit" the shores
    DamageRadius               = 25.0   ;damage things this far from us
    DamageAmount               = 99999  ;do this much damage
    ToppleForce                = 0.25   ;force strength we topple things with
    RandomSplashSound          = WaveRandomSplash
    RandomSplashSoundFrequency = 50     ;every so often a # from 1-100 is chosen, if above this number the sound will play
    BridgeParticle             = WaveHitBridge01 ;particle system when wave hits a bridge
    BridgeParticleAngleFudge   = -95.0  ;angle to offset the bridge particle angle
    LoopingSound               = DamBreakWaveLoop
  End

  Behavior = TensileFormationUpdate ModuleTag_XX
    Enabled = No ; Damage condition amt ofhurt to any member of the formation will enable them all
    CrackSound = AvalancheCrack
  End

  Behavior = SmartBombTargetHomingUpdate ModuleTag_XX
    CourseCorrectionScalar = 0.99 ; 1=no homing, 0=snapto; 0.99=smooth, 0.95=too-fast
  End

   (2)位置/骨骼点修正。
  Behavior = SupplyCenterDockUpdate ModuleTag_XX                                资源采集中心修正
    NumberApproachPositions = 9                                                                本体将有多少个卸货位置以对应W3D里的骨骼点
  End

  Behavior = SupplyWarehouseDockUpdate ModuleTag_XX                        补给站修正
    AllowsPassthrough = No                                                                                是否允许其他单位从本体上面踩过,补给站应该使用No,矿石则可以使用Yes
    NumberApproachPositions = -1                                                                本体将有多少个装货位置以对应W3D里的骨骼点,-1表示无穷大
    StartingBoxes     = 400                                                                                初始资源箱数量,乘以箱子单价可以算出一个补给站上的最大资金量是多少
  End

  Behavior = RailedTransportDockUpdate ModuleTag_XX                        火车修正
    NumberApproachPositions = 9                                                                本体将有多少个门口以对应W3D里的骨骼点
    PullInsideDuration      = 4500                                                                拉进持续时间?
    PushOutsideDuration   = 4500                                                                推出时序时间?没搞懂什么叫拉进推出,大概是指旅客上下火车需要走这么长时间
    ToleranceDistance      = 400.0                                                                站台距离门口的最大距离
  End

  Behavior = BoneFXUpdate ModuleTag_XX                                                FX骨骼修正
    DamageFXTypes     = ALL –WATER                                                被什么武器伤害后产生受损FX
    RubbleFXList1       = bone:Smoke02  OnlyOnce:Yes   3000 3000  FXList:FX_DefaultStructureSecondary
                                                        骨骼名称        只引发一次            延迟时间              FX特效
    DamageParticleTypes  = ALL –WATER                                        被什么武器伤害后产生粒子系统
    RubbleParticleSystem1 = bone:Fire02    OnlyOnce:Yes   3000 3000  PSys:StructureToppleSmokeTrail
                                                        骨骼名称        只引发一次            延迟时间              粒子系统
  End
  点评:注意延迟时间的两个值,前面一个是最小值,后面一个是最大值。其含义是在遭受特定DamageType的武器攻击时,需要延迟一定时间,在特定骨骼点引发FX特效或粒子系统,可以通过OnlyOnce:是Yes还是No来决定是只引发一次还是不停地引发下去

  Behavior = SpawnPointProductionExitUpdate ModuleTag_XX                卵生工厂的产出点修正
    SpawnPointBoneName = SpawnPoint                                                        产出点位置对应哪骨骼点
  End

  Behavior = DefaultProductionExitUpdate ModuleTag_XX                        一般工厂修正
    UnitCreatePoint   = X:  0.0  Y:  0.0   Z:0.0                                        被造单位的诞生点坐标
    NaturalRallyPoint  = X: 55.0  Y:  0.0   Z:0.0                                        默认集合点坐标
  End
  点评:不需要关联骨骼点,只需要设置坐标,这里的坐标是指W3D模型里,以世界坐标原点为中心计算出来的相对位置

  Behavior = QueueProductionExitUpdate ModuleTag_XX                        量产型工厂修正,比一般工厂多了一个产出延迟,用来使成倍生产的多个单位依次出来,而非重叠着出来
    UnitCreatePoint   = X:  0.0  Y:  -25.0   Z:0.0
    NaturalRallyPoint  = X: 36.0  Y:  -25.0   Z:0.0
    ExitDelay = 300                                                                                                产出延迟
  End
  点评:用中国兵营造红卫兵时就知道了,虽然红卫兵是造一次出来两个,但他们不是同时出来的,而是一前一后依次出来的,两者之间出来的时间间隔就是ExitDelay的参数

  Behavior = SupplyCenterProductionExitUpdate ModuleTag_11                资源采集中心修正,和一般工厂差不多,但仅仅用于资源采集中心,事实上我怀疑用一般工厂修正也可以
    UnitCreatePoint   = X:  0.0  Y:  0.0   Z:0.0
    NaturalRallyPoint  = X: 52.0  Y:  0.0   Z:0.0
  End

  ClientUpdate = AnimatedParticleSysBoneClientUpdate ModuleTag_XX        活动骨骼点服务修正,大概是指引发粒子系统的骨骼点可以自由改变位置(实际上把骨骼点做成3D动画不就得了?)
  End

   (3)射弹体专用修正。
Behavior = NeutronMissileUpdate ModuleTag_XX                                        核弹弹道修正,使射弹体在发射时先向上飞,然后再转折向前,最后转折落下
    DistanceToTravelBeforeTurning = 500                                                        发射时的垂直爬升高度
    MaxTurnRate = 9000                                                                                最大转向速度,控制两次转折时的转向速度,太小会导致转向不足,进而落点发生偏移
    ForwardDamping = 0.1                                                                                正向阻尼
    RelativeSpeed = 2.0                                                                                        速度倍率,原样速度为该射弹体的运动系统速度,如果没有配运动系统,则为武器代码里的发射速度
    LaunchFX = FX_NeutronMissileLaunch                                                发射时的炮口FX特效
    IgnitionFX = FX_NeutronMissileIgnition                                                点火时的FX特效,想想火箭是怎么发射的,肯定都是先点火再发射
    TargetFromDirectlyAbove = 500                                                                飞到目标点上空多少高度的时候开始转折落下
    SpecialAccelFactor = 1                                                                                平飞阶段的加速度
    SpecialSpeedTime = 1500                                                                        平飞阶段的持续时间,如果为0则没有平飞阶段
    SpecialSpeedHeight = 160                                                                        平飞时保持的高度
    SpecialJitterDistance = 0.4                                                                        抖动距离比率,至今没看出哪里来的抖动……
    DeliveryDecalRadius = 210                                                                        留在地面上的范围指示圈尺寸
    DeliveryDecal                                                                                                范围指示圈定义,二级子函数
      Texture           = SCCNuclearMissile_China                                用哪个TGA贴图来显示范围指示圈
      Style             = SHADOW_ALPHA_DECAL                                贴图风格为半透明贴花
      OpacityMin        = 25%                                                                        最小透明度
      OpacityMax        = 50%                                                                        最大透明度,若二者不同,则可以形成闪烁效果
      OpacityThrobTime  = 500                                                                        闪烁频率,每0.5秒一次
      Color             = R:255 G:0 B:0 A:255                                         染色情况,最后的A代表饱和度(一般都把范围指示圈的TGA贴图做成纯白,这样方便染色)
      OnlyVisibleToOwningPlayer = Yes                                                        是否只让自己看到范围指示圈
    End
  End

  Behavior = DynamicShroudClearingRangeUpdate ModuleTag_XX        侦察范围动态修正,使射弹体获得一个逐渐扩大或缩小的侦察范围
    FinalVision = 250.0                                                                                        最终侦察范围
    ChangeInterval = 50                                                                                        侦察范围收缩量,即每扩大一次,侦察范围减少多少点
    ShrinkDelay = 2000                                                                                        从射弹体诞生起,延迟多长时间后其侦察范围开始缩小
    ShrinkTime = 1000                                                                                        侦察范围缩小过程持续多长时间
    GrowDelay = 0                                                                                                从射弹体诞生起,延迟多长时间后侦察范围开始增大
    GrowTime = 1000                                                                                        侦察范围扩大过程持续多长时间
    GrowInterval = 10                                                                                        侦察范围收缩量,即每扩大一次,侦察范围扩大多少点
    GridDecalTemplate                                                                                        范围指示删格定义,二级子函数,删格实际上和圈没啥区别,个人认为仅仅就是贴图不同而已
      Texture           = EXGrid
      Style             = SHADOW_ADDITIVE_DECAL
      OpacityMin        = 50%
      OpacityMax        = 100%
      OpacityThrobTime  = 500
      Color             = R:32 G:64 B:128 A:0                                        饱和度为0,似乎并非指不染色,应该理解成最小染色情况,在实际使用中可发现,依然还是有很淡的颜色
    End
  End

  Behavior = MissileAIUpdate ModuleTag_XX                                                导弹弹道修正,使用了这个模块的射弹体,需要运动系统的支持,同时武器代码里的一些语句将不再起作用
    TryToFollowTarget = Yes                                                                                是否启动跟踪能力,No的话,这种导弹将打当前点,而不会去跟踪目标
    FuelLifetime = 3000                                                                                        续航时间,单位为毫秒,意思是说,这个射弹体只能飞3秒种,时间一到就自动引爆
    IgnitionDelay = 0                                                                                        点火延迟时间,也就是说导弹出膛多长时间后喷发尾焰
    IgnitionFX = FX_TomahawkIgnition                                                        点火使用哪个FX特效
    InitialVelocity = 50                                                                                        出膛初速度,因此武器代码里的发射速度将不再其作用
    DistanceToTravelBeforeTurning = 80                                                        自由飞行距离,即出膛后必须要沿炮口方向自由飞行多远才开始转向去打目标
    DistanceToTargetBeforeDiving = 100                                                        距离目标多远的时候开始转折命中,这个参数不可设置得过小,否则很容易因为转折不及时而飞过头
    DistanceToTargetForLock = 10                                                                锁定目标的距离,尚未测试出有啥作用,原文说有这个语句能让导弹的飞行轨迹更平稳
  End
  点评:这个模块用于战斧、V3之类弧线发射的巡航导弹时,有些语句如点火、自由飞行距离、转折距离才有实际价值,而用于直线飞行的小型导弹或火箭炮时,这些语句几乎起不到什么作用。有人觉得ZH里的小型导弹弹道在山上打山下时,落点之前有一个很别扭的转折,我觉得似乎可以通过设置转折距离来避免,因为CNC3里就是完美的弧线

Behavior = ProjectileStreamUpdate ModuleTag_XX                                射弹体尾气流修正,一般我们都在射弹体模型里调用粒子系统来做尾气流,因此这个缺少语句的模块几乎没什么价值
    ;nothing
  End

  ClientUpdate = LaserUpdate ModuleTag_XX                                                光束服务修正,可在一条光束首末两端点上产生粒子系统,用于模拟激光效果
    MuzzleParticleSystem = GenericLaserFlare                                                首端点上的粒子系统,通常可理解为炮口闪光
    TargetParticleSystem = GenericLaserFlare                                                末端点上的粒子系统,通常可理解为落点闪光
  End

  ClientUpdate = BeaconClientUpdate ModuleTag_XX                                信标服务修正,使物体能像“感叹号信标”那样在雷达上激起闪烁信号,让盟友注意到你的意图
    RadarPulseFrequency = 1000                                                                雷达信号闪烁频率,每1秒闪烁一次
    RadarPulseDuration = 500                                                                        每次闪烁后,显亮阶段持续多长时间
  End

  Behavior = StickyBombUpdate ModuleTag_XX                                        粘性修正,使本体能够粘贴到目标身上被它带着走
    ; nothing
  End
  点评:需要说明的是,这种带有粘性的射弹体只能通过放置TNT炸弹、圈套、定时炸弹或遥控炸弹等方式粘贴到目标身上,而直接当作炮弹打出去则只会粘贴到地面上,我没有尝试过将它做成带有跟踪能力的导弹发射出去,能否成功粘贴到目标身上,这个值得一试。

  (4)特殊能力修正。这个模块需要根据不同的SP来对应不同的语句,因此使用非常灵活。我特意用蓝色来表示各种技能的关键语句,其他则是通用语句
Behavior = SpecialAbilityUpdate ModuleTag_XX                                       
    SpecialPowerTemplate  = SpecialAbilityRedGuardCaptureBuilding                        外部占领
    StartAbilityRange       = 5.0                                                                施展技能的“射程”。若施展者距离目标的距离大于这个参数,则施展者会自动跑过去然后再施展
    UnpackTime           = 3000                                                                部署准备时间,会影响施展者的部署动作3D动画播放速度
    PreparationTime        = 20000                                                                施展持续时间,必须要走完着段时间才能算技能施展成功,中途放弃会导致前功尽弃
    PackTime              = 2000                                                                回收撤离时间(即收拾装备的时间),同样会影响施展者的部署动作3D动画播放速度
    DoCaptureFX          = Yes                                                                在施展过程中产生闪光效果
    SpecialObject          = BinaryDataStream                                        施展过程中“发射”出去的特殊物体,只能是不含W3D外观模块的光束类物体,否则会报错
    SpecialObjectAttachToBone = Muzzle01                                                光束的首端点关联到施展者的哪个骨骼点上,只有当特殊物体是光束类物体时才能使用这个语句
    PackSound            = BlackLotusPack                                                回收撤离时播放的音效(可以“误会”为单位的语音)
    UnpackSound          = BlackLotusUnpack                                        部署准备时播放的音效
    TriggerSound          = BlackLotusTrigger                                        开始施展时播放的音效(大概是指按下选中了目标时的音效)
    PrepSoundLoop        = BlackLotusPrepLoop                                部署准备过程中持续播放的音效
    AwardXPForTriggering  = 5                                                                        成功施展之后,本体获得多少点经验值,同时也贡献给将军多少经验值
    SkillPointsForTriggering = 20                                                                需要消耗多少点“魔法值”才能施展。ZH里有魔法值概念么?似乎有,只不过不是魔兽那种概念
  End
  点评:第一次发觉原来ZH也有魔法值,虽然作用相同,但并不是魔兽里那种魔法值概念。ZH的魔法值实际上应该理解成技能点,Rank.ini里存在一条语句叫SkillPointsNeeded,用于定义将军的技能点积累到多少时可以升到多少级,而每个单位也存在一条未被使用的SkillPointValue语句,用于定义该单位被杀后贡献给敌人多少技能点。但实际上我们知道,将军升级是靠积累经验值,而非积累技能点,那是因为经验值实际上就等价于技能点,所以技能点的概念就成了多余的垃圾,因此我不太提倡使用“魔法值”概念来限制特殊能力的施展。

  Behavior = SpecialAbilityUpdate ModuleTag_XX                                       
    SpecialPowerTemplate  = SpecialAbilityBlackLotusDisableVehicleHack                        封锁载具
    StartAbilityRange       = 150.0
    UnpackTime           = 2000
    PackTime             = 1000
    PreparationTime       = 2000
    EffectDuration         = 15000                                                                封锁效力持续时间
    DisableFXParticleSystem = DisabledEffectBinaryShower0                被封锁的单位头顶上将出现什么样的FX特效(0101010101,让我想起了黑客帝国)
    SpecialObject           = BinaryDataStream                                        只能是光束类物体
    SpecialObjectAttachToBone = Muzzle01
    PackSound             = BlackLotusPack
    UnpackSound          = BlackLotusUnpack
    TriggerSound          = BlackLotusTrigger
    PrepSoundLoop        = BlackLotusPrepLoop
    AwardXPForTriggering  = 2
    SkillPointsForTriggering = 20
  End

  Behavior = SpecialAbilityUpdate ModuleTag_XX
    SpecialPowerTemplate  = SpecialAbilityBlackLotusStealCashHack                                盗取金币
    StartAbilityRange       = 150.0
    UnpackTime           = 6730
    PackTime              = 5800
    PreparationTime        = 6000
    EffectValue            = 1000                                                                一次成功的盗取能获得多少个金币(同时对方被扣掉多少个金币)
    SpecialObject          = BinaryDataStream                                        只能是光束类物体
    SpecialObjectAttachToBone = Muzzle01
    PackSound            = BlackLotusPack
    UnpackSound          = BlackLotusUnpack
    TriggerSound          = BlackLotusTrigger
    PrepSoundLoop        = BlackLotusPrepLoop
    AwardXPForTriggering  = 20
    SkillPointsForTriggering = 20
  End
  点评:EffectValue实际上是个BUG语句,不管你设置成多少点,在游戏里永远都是1000。

Behavior = SpecialAbilityUpdate ModuleTag_XX
    SpecialPowerTemplate = SpecialAbilityHackerDisableBuilding                                        关闭建筑,这是个自动反复施展的技能,只要一开始施展,你不叫停它就永远不停
    StartAbilityRange      = 150.0
    UnpackTime          = 7300
    PackTime             = 5133
    PreparationTime       = 3000
    PersistentPrepTime    = 333                                                                连续两次施展之间的间隔时间
    EffectDuration         = 2000                                                                关闭效力持续时间,多次施展不会累积,只会把上次的剩余时间冲掉,然后重新计算时间
    DisableFXParticleSystem = DisabledEffectBinaryShower0                被关闭的建筑头顶上出现什么样的FX特效
    SpecialObject          = BinaryDataStream                                        只能是光束类物体
    SpecialObjectAttachToBone = Muzzle01
    PackSound            = HackerPack
    UnpackSound          = HackerUnpack
    PrepSoundLoop        = HackerPrepLoop
    AwardXPForTriggering  = 1                                                                        由于是连续自动施展,所以最好不要获得太多经验值,否则太BT很了
    SkillPointsForTriggering = 20
  End

  Behavior = SpecialAbilityUpdate ModuleTag_XX
    SpecialPowerTemplate = SpecialAbilityDisguiseAsVehicle                                                伪装成载具(只能伪装含有VEHICLE类型标签的目标)
    StartAbilityRange = 1000000.0
    ApproachRequiresLOS = No                                                                        是否只能选取处于自己视野范围内的目标,Yes的话则和施放者的VisionRange参数有关,No则只要看得到就能作为目标
  End
  点评:要想实现伪装成载具的实际功能,还必须依靠一个特殊的隐形修正,否则仅仅只是形状变了,但会被敌人一眼识破,如下:
  Behavior = StealthUpdate ModuleTag_XX
    StealthDelay                            = 1
    DisguisesAsTeam                       = Yes                                伪装成小队?似乎是表示这个隐形能力必须要通过特殊能力来启动
    RevealDistanceFromTarget               = 100.0f                        距离目标多远时被识破
    OrderIdleEnemiesToAttackMeUponReveal  = Yes
    DisguiseFX                             = FX_BombTruckDisguise                        伪装时的FX特效
    DisguiseRevealFX                       = FX_BombTruckDisguiseReveal                败露时的FX特效
    InnateStealth                            = Yes
    DisguiseTransitionTime                   = 2000                        伪装过程持续时间
    DisguiseRevealTransitionTime             = 1000                         败露过程时序时间
  End

  Behavior = SpecialAbilityUpdate ModuleTag_XX
    SpecialPowerTemplate = SpecialAbilityHelixNapalmBomb                                                投掷凝固汽油炸弹
    StartAbilityRange = 3.0
    PreparationTime = 0
    SpecialObject = NapalmBomb                                                                        可以是任何物体,并且不需要具备粘性修正模块,可以理解成“炸弹射弹体”
    MaxSpecialObjects = 1
    SpecialObjectsPersistWhenOwnerDies = Yes
    SpecialObjectsPersistent = Yes
    UniqueSpecialObjectTargets = No
    UnpackTime              = 500
    FlipOwnerAfterUnpacking = No                                                                投放成功后还会继续准备投放第二个特殊物体
    FleeRangeAfterCompletion = 0.0                                                                0表示投放成功后投放者不会跑开,换言之就是站在原地等待第二次投放
    UnpackSound             = DragonTankVoiceFireStorm
    LoseStealthOnTrigger      = No                                                                投放过程中不显形,事实上当特殊物体是炸弹时,根本用不着让它隐形,所以也无所谓显形
    ApproachRequiresLOS     = No
    NeedToFaceTarget         = No                                                                是否需要正面朝向目标才能投放,No表示无所谓,尾巴对着目标也能投放,Yes的话则投放者会在投放前自动调整朝向
    PersistentPrepTime        = 100
    PersistenceRequiresRecharge = Yes                                                        持续投放,又一个加深申明内容的语句
  End

  Behavior = SpecialAbilityUpdate ModuleTag_XX
    SpecialPowerTemplate = SpecialAbilityTankHunterTNTAttack                                        埋设TNT炸弹,将一个指定的物体投放到目标头上,如果该物体含有粘性修正模块则会自动粘贴到目标身上
    StartAbilityRange = 5.0
    PreparationTime = 0
    SpecialObject = TNTStickyBomb                                                                投放什么特殊物体,可以是任何物体,当然最好是含有粘性修正模块和生存时间模块
    MaxSpecialObjects = 8                                                                                最大可连续投放的特殊物体数量,若放满了8个,则必须等到其中一个特殊物体死亡后才能继续放
    SpecialObjectsPersistWhenOwnerDies = Yes                                        特殊物体将在投放者死亡的瞬间自动消失(意味着不会再爆炸),No的话还会继续粘贴在目标身上
    SpecialObjectsPersistent = Yes                                                                特殊物体可以通过投放者的界面按钮来引爆或者生存时间到了之后自动自杀
    UniqueSpecialObjectTargets = Yes                                                        已经被粘贴了特殊物体的目标不能再被粘第二个特殊物体,否则的话,可以被粘上无限多个
    FleeRangeAfterCompletion = 100.0                                                        投放者成功粘贴了特殊物体之后自动跑开多远距离
  End

  Behavior = SpecialAbilityUpdate ModuleTag_XX
    SpecialPowerTemplate = SpecialAbilityBoobyTrap                                                        投放圈套,感觉跟TNT炸弹很相似,可能区别只在于特殊物体上
    StartAbilityRange = 5.0
    PreparationTime = 0
    SpecialObject = BoobyTrap
    MaxSpecialObjects = 100
    SpecialObjectsPersistWhenOwnerDies = Yes
    SpecialObjectsPersistent = Yes
UniqueSpecialObjectTargets = Yes
  End

  Behavior = SpecialAbilityUpdate ModuleTag_XX
    SpecialPowerTemplate = SpecialAbilityColonelBurtonRemoteCharges                        埋设遥控炸弹,和TNT炸弹的语句差不多,仅仅是该炸弹可以通过投放者的界面按钮来引爆
    StartAbilityRange = 0.0
    PreparationTime = 0
    SpecialObject = RemoteC4Charge
    MaxSpecialObjects = 8
    SpecialObjectsPersistWhenOwnerDies = No
    AlwaysValidateSpecialObjects = Yes                                                        特殊物体将永远保持有效,当上一句的参数为No时使用,属于再次强调说明特殊物体不会因为投放者身亡而失效
    SpecialObjectsPersistent = Yes                                                                上面的TNT炸弹不能用按键来引爆,但这里的遥控炸弹则可以,这是由于SP的特殊性造成的
    UniqueSpecialObjectTargets = Yes
    UnpackTime              = 5500
    PackTime                = 0
    SkipPackingWithNoTarget = Yes                                                                没有放置任何特殊物体时引爆无效,应该为Yes,否则会导致空引爆,也引不出来啥东西
    FlipOwnerAfterUnpacking = Yes                                                                埋设成功后埋设者自动停止施展能力,否则会继续投放第二个特殊物体(还粘得起第二个的话)
    FleeRangeAfterCompletion = 100.0
    UnpackSound             = ColonelBurtonPlantCharge
    LoseStealthOnTrigger      = Yes                                                                埋设过程中,特殊物体将处于显形状态,前提是特殊物体具有隐形能力
  End

  Behavior = SpecialAbilityUpdate ModuleTag_XX
    SpecialPowerTemplate = SpecialAbilityColonelBurtonTimedCharges                        埋设定时炸弹,和遥控炸弹基本相似,但特殊物体的外观上有倒计时显示给投放者
    StartAbilityRange = 0.0
    PreparationTime = 0
    SpecialObject = TimedC4Charge                                                                这个特殊物体必须含有生存时间模块,否则就成了只计时不爆炸的“玩具炸弹”,其生存时间参数决定了外观上的倒记时数字
    MaxSpecialObjects = 10
    SpecialObjectsPersistWhenOwnerDies = Yes
    SpecialObjectsPersistent = Yes
    UniqueSpecialObjectTargets = Yes
    UnpackTime              = 5500
    FlipOwnerAfterUnpacking = Yes
    FleeRangeAfterCompletion = 100.0
    UnpackSound             = ColonelBurtonPlantCharge
    LoseStealthOnTrigger      = Yes
  End

  Behavior = SpecialAbilityUpdate ModuleTag_XX
    SpecialPowerTemplate = SpecialAbilityMissileDefenderLaserGuidedMissiles        激光制导
    StartAbilityRange = 200.0
    AbilityAbortRange = 250.0                                                                        取消施展距离,当目标逃出这个距离时,施展者自动取消施展技能的动作
    PreparationTime = 1000
    PersistentPrepTime = 500
    SpecialObject = LaserBeam                                                                        只能是光束类物体
    SpecialObjectAttachToBone = Muzzle01
  End

   (6)人工智能修正。
      这类修正主要是控制单位是否具有矿车能力、是否具有推土机功能、是否自动攻击敌人、各种情况下的炮塔动作,因此往往存在Turrer和AltTurret二级子函数。任何一个人工智能修正最多可以同时拥有Turret和AltTurret,表示单位有两个炮塔(通常只有战列舰才具有双炮塔),它们的语句设置是一样的,我就只举Turret的例子来说明。
      这些修正含有很多通用语句,例如直升机也可以具有矿车的智能(美军支奴干直升机)。所以大家可以尝试将这些语句交错使用,说不定能弄出些意外的惊喜。(当然这些惊喜包括报错信息框)
  Behavior = AIUpdateInterface ModuleTag_XX                                                一般修正,常用于坦克、步兵和防御塔
    Turret
      ControlledWeaponSlots = PRIMARY SECONDARY                        哪些武器被绑定在这个炮塔上
      TurretTurnRate      = 180                                                                炮塔水平转动速度
      AllowsPitch         = Yes                                                                        是否允许炮塔垂直转动
      TurretPitchRate     = 180                                                                        炮塔垂直转动速度(俯仰动作),若AllowsPitch = No,则这句无作用
      NaturalTurretPitch   = 45                                                                        空闲时炮塔垂直方向倾角,以W3D炮塔模型块的绘制角度为0度来计算,若AllowsPitch = No,则本句无作用
      MinPhysicalPitch    = -20                                                                        最小倾角,负数表示向地面倾斜,仅当AllowsPitch = Yes时有作用,缺省值为0,即W3D里的绘制角度
      TurretFireAngleSweep = PRIMARY 25                                                开火时水平摆动角度,像火龙坦克那样摆动开火
      FiresWhileTurning   = Yes                                                                        可在炮塔转动时开火,用于坦克则可产生边走边打的效果(当然前提是该坦克能自动攻击敌人)
      MinIdleScanInterval  = 250                                                                空闲时转动炮塔以巡视周围的最小间隔时间
      MaxIdleScanInterval  = 250                                                                空闲时转动炮塔以巡视周围的最大间隔时间
      MinIdleScanAngle    = 0                                                                        空闲时转动炮塔以巡视周围的最小转动距离
      MaxIdleScanAngle    = 360                                                                空闲时转动炮塔以巡视周围的最小转动距离
    End
    AutoAcquireEnemiesWhenIdle = Yes                                                        允许自动攻击进入视野范围内的敌人
    MoodAttackCheckRate        = 250                                                        士气检测频率,每隔0.25秒检测一次开火者的情绪,听说ZH里有士气概念,能影响单位的战斗积极性
  End

  Behavior = JetAIUpdate ModuleTag_XX                                                        战斗机修正,专用于机场型战斗机
    OutOfAmmoDamagePerSecond  = 10%                                                弹药放完后每秒钟扣掉百分之多少的生命值
    TakeoffDistForMaxLift      = 0%                                                                爬升-平飞比,即要爬升到正常飞行高度,需要平飞多远距离,0%表示直接进入正常飞行高度(但看着有点别扭)
    TakeoffPause              = 500                                                        起飞暂停时间,即点火弹射时间,用于模拟点火弹射动作(因为机场很短……)
    MinHeight                 = 5                                                                最低飞行高度,大概是指着陆时离地面的高度
    ReturnToBaseIdleTime      = 10000                                                        空闲多长时间后自动返航,只要没有执行任何任务(移动、攻击、领空守卫等),那么只在外面旋多长时间就得自动飞回来
                                                                                                                                哪怕并没有开一炮,弹药也是满的,也必须回来
  End
  点评:非常可怜的战斗机,感觉它在开火的时候把油箱也丢下去了,所以才会急切地要求返航(似乎弹药放完之后跑得跟鬼撵似的),万一遇到机场堵塞,它就只能在空中等着扣血扣死,然后掉下来。看样子EA是打算但这种概念来模拟油量,但这样做有个很别扭的BUG,那就是让它执行领空守卫,它可以在空中转半天不扣一点点血,莫非这家伙开了作弊器,无限油量么?

Behavior = SupplyTruckAIUpdate ModuleTag_XX                                        矿车修正,专用于资源采集单位
    MaxBoxes = 4                                                                                                一次性最多可以搬运多少个箱子
    SupplyCenterActionDelay = 400                                                                在补给中心(矿厂)卸载完所有箱子需要花费的时间
    SupplyWarehouseActionDelay = 1000                                                        在补给站(矿区)装载满一车箱子需要花费的时间
    SupplyWarehouseScanDistance = 700                                                        探测身边一定范围内有没有可搬的箱子,如果有就去搬,如果没有就跑回矿厂偷懒(不怕挨将军骂么?)
    UpgradedSupplyBoost         = 60                                                        获得Upgrade_AmericaSupplyLines后,每个箱子能多产生多少金币
    SuppliesDepletedVoice = SupplyTruckVoiceSuppliesDepleted        探测到可搬的箱子后播放什么音效(OMG!那是箱子!大家快上)
  End

  Behavior = DeployStyleAIUpdate ModuleTag_XX                                        部署型单位修正,专用于必须先部署才能开火的单位,例如核子加农炮
    Turret
      TurretTurnRate        = 80
      TurretPitchRate       = 80
      FirePitch             = 0                                                                        开火时炮塔的倾角,以W3D里绘制的方向为0度开始计算(哪怕你把它画斜了,游戏就认为斜着才是0度)
      AllowsPitch           = Yes                                                               
      RecenterTime          = 5000                                                        空闲时等待多长时间才让炮塔归正,只有这种修正才用这个语句,而缺省值为0,即空闲后立刻归正
      ControlledWeaponSlots = PRIMARY SECONDARY
      NaturalTurretAngle    = 0
      InitiallyDisabled     = Yes                                                                        未部署时无效
    End
    AutoAcquireEnemiesWhenIdle = No
    PackTime = 3333                                                                                        回收过程持续时间
    UnpackTime = 3333                                                                                        部署过程持续时间
    TurretsFunctionOnlyWhenDeployed = Yes                                                仅当部署后炮塔才起作用,对应上面那句InitiallyDisabled = Yes
    TurretsMustCenterBeforePacking = Yes                                                回收前炮塔将自动归正,归正完毕才开始回收
    ManualDeployAnimations = Yes                                                                使用手动部署动画?
  End
  点评:不得不提的是,核子加农炮部署前后的炮塔不是同一个炮塔(废话,因为模型都不是同一个W3D),部署前的炮塔仅仅是个不能开火的“零件”,部署后那个才是真正的炮塔,而部署过程动画则是在外观模块里利用ShowSubObject和HindSubObject将假炮塔隐藏掉,把真炮塔显示出来产生3D动画。回收过程则正好相反,真炮塔播放完3D动画后被隐藏掉,然后假炮塔被显示出来。

  Behavior = ChinookAIUpdate ModuleTag_XX                                                直升机修正,直升机即可以是矿车,还可以具有空降绳功能
    MaxBoxes                = 8
    SupplyCenterActionDelay = 3000
    SupplyWarehouseActionDelay = 1250
    SupplyWarehouseScanDistance = 700
    SuppliesDepletedVoice = ChinookVoiceSuppliesDepleted
    NumRopes                = 4                                                                最大空降绳数量,因为一根绳子上只能供一个人降落,在这个人成功落地前,就必须换根绳子来空降下一个人
    PerRopeDelayMin         = 900                                                                投放绳子的最小准备时间
    PerRopeDelayMax         = 1500                                                        投放绳子的最大准备时间
    RopeWidth               = 0.5                                                                绳子的粗细,注意,绳子可不是什么Object,因此没有W3D模型
    RopeColor               = R:0 G:0 B:0                                                绳子颜色
    RopeWobbleLen           = 10                                                                绳子摇摆角度
    RopeWobbleAmplitude     = 0.25                                                        绳子摇摆幅度比
    RopeWobbleRate          = 180                                                        绳子摇摆频率
    RopeFinalHeight          = 10                                                                绳子底部距离地面多高
    RappelSpeed             = 30                                                                乘员在绳子上的下滑速度
    MinDropHeight           = 40                                                                投放绳子时,本体距离正下方最近平面的高度,这个最近的平面,可能是地面,也可能是房顶
  End

  Behavior = TransportAIUpdate ModuleTag_XX                                        一般运载体修正,很大程度上和一般修正基本相同,仅仅只多了一个自动迎接乘员的动作(如直升机会先落地等待乘员登机)
    Turret
      TurretTurnRate = 60
      ControlledWeaponSlots = PRIMARY
    End
    AutoAcquireEnemiesWhenIdle = Yes
  End

  Behavior = AssaultTransportAIUpdate ModuleTag_XX                                救护车修正,和普通运载体基本相同,多了一个让乘员在里面恢复生命的功能
    MembersGetHealedAtLifeRatio = 0.5                                                        当乘员生命值低于50%时,进去可以获得治疗
  End

  Behavior = RailedTransportAIUpdate ModuleTag_XX                                火车修正,定义上客点对应哪个骨骼点
    PathPrefixName    = Ferry                                                                        上客点对应以Ferry为前缀的骨骼点,即Ferry%02d
  End

  Behavior = DozerAIUpdate ModuleTag_XX                                                推土机修正,使本体获得建造房子和修复房子的能力
    RepairHealthPercentPerSecond = 2%                                                        每秒钟修复目标建筑百分之多少的生命值
    BoredRange                  = 150                                                        闲置时自动找活干的探测范围,当闲置时,会探测周围这个范围内有没有可干的活,例如破房子、未完工的地基
    BoredTime                    = 5000                                                偷懒时间,探测到有活可干的时候,先偷懒多长时间再跑过去干
  End

  Behavior = WorkerAIUpdate ModuleTag_XX                                                工人修正,工人比推土机更全能,还能搬箱子,所以是推土机的语句+矿车的语句
    RepairHealthPercentPerSecond  = 2%
    BoredTime                     = 5000
    BoredRange                    = 150
    MaxBoxes                      = 1
    UpgradedSupplyBoost           = 8
    SupplyCenterActionDelay        = 150
    SupplyWarehouseActionDelay    = 150
    SupplyWarehouseScanDistance   = 700
    SuppliesDepletedVoice = WorkerVoiceSuppliesDepleted
    AutoAcquireEnemiesWhenIdle    = Yes
  End

  Behavior = DeliverPayloadAIUpdate ModuleTag_XX                                递交型运载体修正,递交型运载体通常被OCL调用,将需要刷的物体从地图边界上运载到目的地,然后投放
    DoorDelay = 500                                                                                        开门延迟时间,即投放前的准备时间
    MaxAttempts = 4                                                                                        最大投放尝试次数,如果连续这么多次都投放不成功就撤退不投了
    DropOffset = X:0 Y:0 Z:-10                                                                        投放点,以运载体自身W3D模型的中心为原点来计算
    DropDelay = 300                                                                                        相邻物体之间的投放间隔时间
    PutInContainer = AmericaParachute                                                        将被投放的物体放进一个“特别”的容器里,例如降落伞
    DeliveryDistance = 150                                                                                投放距离,距目的地在这个范围内时才能投放
  End
  点评:为了使投放尽可能成功,递交型运载体的线-角速度之比不能太大,否则会导致在开门延迟时间内来不及转向调整,就又飞出投放距离了,反复几次如果都无法调整得好,它就会飞走,这样一来你啥都得不到。

  Behavior = HackInternetAIUpdate ModuleTag_XX                                        黑客刷钱修正,使本体能够坐在地上就来钱,刷不了多长时间还升级,升级之后刷得更多
    UnpackTime          = 7300                                                                开始刷钱部时的署准备动作时间
    PackTime            = 5133                                                                停止刷钱后的回收动作时间
    PackUnpackVariationFactor = 0.5                                                                开始和停止时随机增减百分之多少的动作时间
    CashUpdateDelay     = 2000                                                                在空地上每隔多长时间刷一次钱
    CashUpdateDelayFast = 1800                                                                在网络中心里每隔多长时间刷一次钱
    RegularCashAmount   = 5                                                                        新兵级每次刷出多少金币
    VeteranCashAmount   = 6                                                                        老兵级每次刷出多少金币
    EliteCashAmount     = 8                                                                        精英级每次刷出多少金币
    HeroicCashAmount    = 10                                                                        王牌级每次刷出多少金币
    XpPerCashUpdate     = 1                                                                        每刷一次,自己获得多少经验值(这个经验值是不送给将军的)
  End

  Behavior = WanderAIUpdate ModuleTag_XX                                                乱跑修正,使本体不停地到处乱跑,需要使用一个特别的运动系统才能控制好乱跑时的动作        
  End

8、        容器类模块。这类模块的特点是可以容纳别的物体,并含有一定的容积。而这些容积也分为内部式和外部式两类,其中外部式容积比较特殊,它的乘员会受到外部火力的直接伤害,而内部式容积则可以保护乘员免受伤害。在使用中,这些容器模块含有相当多的通用语句,你也可以尝试一下挪用语句,说不定也能搞出点意外的惊喜,例如报错。
此外一定要谨慎,由于有AllowInsideKindOf和ForbidInsideKindOf语句,所以千万不要搞出冲突。
  Behavior = ParachuteContain ModuleTag_XX                                                降落伞容器,外部式,它把乘员吊在它下面
    PitchRateMax = 60                                                                                        最大摇晃速度,单位为度每秒
    RollRateMax = 60                                                                                        最大滚动速度,同上
    LowAltitudeDamping  = 0.2                                                                        高度衰减比率,越靠近地面,摇晃越小
    ParachuteOpenDist   = 25.0                                                                        从投放开始到降落伞完全打开,需要降落多少高度
    AllowInsideKindOf   = INFANTRY VEHICLE PARACHUTABLE        允许含有哪些类型标签的乘员进来
    ParachuteOpenSound  = ParachuteOpen                                                开伞时播放的音效
  End

  Behavior = OverlordContain ModuleTag_XX                                                炎黄容器,外部式,它把乘员顶在自己头顶上
    Slots                 = 1                                                                        容积,缺省值似乎就是1
    DamagePercentToUnits = 100%                                                                当自己挂掉时,乘员将遭受百分之多少的伤害,100%表示乘员会跟着它一起挂
    AllowInsideKindOf     = PORTABLE_STRUCTURE
    PassengersAllowedToFire = Yes                                                                直接允许乘员对外开火,否则的话需要配PassengersFireUpgrade模块,通过获得Upgrade来激活
    PayloadTemplateName = AmericaTankAvengerLaserTurret                初始时免费塞入一个乘员,和InitialPayload作用相同
    ExperienceSinkForRider = Yes                                                                乘员杀了敌人,经验值将传递给容器来获取(我的乘员帮我打经验值)
  End

  Behavior = HelixContain ModuleTag_XX                                                        蜗牛容器,内部式,感觉是炎黄容器的简化版,仅仅是把乘员装在内部,而非放在头顶上
    Slots                     = 1
    DamagePercentToUnits    = 100%
    AllowInsideKindOf         = PORTABLE_STRUCTURE
    PassengersAllowedToFire  = Yes
    ShouldDrawPips           = No                                                                是否显示容积格子信息,似乎外部式容器默认不显示容积信息,内部式则默认要显示
  End

  Behavior = TunnelContain ModuleTag_XX                                                地道容器,内部式,一种特殊的“时空门”容器,当有多个这种容器时,将乘员从这头放进去,可以马上从另一头放出来
    TimeForFullHeal     = 5000                                                                        进入容积的乘员可以在多长时间内恢复满血
  End

  Behavior = RailedTransportContain ModuleTag_XX                                火车容积,内部式,似乎没觉得有啥特殊
    Slots               = 10
    AllowInsideKindOf   = INFANTRY VEHICLE BOAT
    DoorOpenTime      = 2000                                                                        开门时间
    ScatterNearbyOnExit = No                                                                        乘员出来后是否自动分散,No表示不分散
  End

  Behavior = RiderChangeContain ModuleTag_XX                                        摩托车容器,半外不内式(因为有BUG),放进不同的乘员充当驾驶员,可以使本体的外观和功能发生一定的变化
    Rider1 = GLAInfantryWorker         RIDER1 WEAPON_RIDER1 STATUS_RIDER1 GLAVehicleCombatBikeDefaultCommandSet SET_NORMAL
    Rider2 = GLAInfantryRebel          RIDER2 WEAPON_RIDER2 STATUS_RIDER2 GLAVehicleCombatBikeDefaultCommandSet SET_NORMAL
    Rider3 = GLAInfantryTunnelDefender RIDER3 WEAPON_RIDER3 STATUS_RIDER3 GLAVehicleCombatBikeDefaultCommandSet SET_NORMAL
    Rider4 = GLAInfantryJarmenKell     RIDER4 WEAPON_RIDER4 STATUS_RIDER4 GLAVehicleCombatBikeJarmenKellCommandSet SET_NORMAL
    Rider5 = GLAInfantryTerrorist      RIDER5 WEAPON_RIDER5 STATUS_RIDER5 GLAVehicleCombatBikeDefaultCommandSet SET_SLUGGISH
    Rider6 = GLAInfantryHijacker       RIDER6 WEAPON_RIDER6 STATUS_RIDER6 GLAVehicleCombatBikeDefaultCommandSet SET_NORMAL
    Rider7 = GLAInfantrySaboteur       RIDER7 WEAPON_RIDER7 STATUS_RIDER7 GLAVehicleCombatBikeDefaultCommandSet SET_NORMAL
    以上这些语句分别定义了7种可成为本体驾驶员的乘员以及对应的条件标签、武器标签、状态标签、操作界面以及运动系统标签,这些不同的标签使得本体在不同情况下具有不同的外观和功能,就像RA2的IFV一样,放不同的兵,就变出不同的炮塔,同时更换不同的武器。可惜的是,IFV可以有无限种情况,但摩托车只有最多8种。
    ScuttleDelay         = 1500                        倾翻延迟时间,当乘员丢弃本体,使本体成为缺少驾驶员的空容积时会导致本体自杀(非常LG而且是毒瘤一样的功能,EA脑壳有包)
    ScuttleStatus         = TOPPLED        倾翻时本体获得状态标签(用于播放倾翻动作)
    Slots                = 1
    InitialPayload         = GLAInfantryTerrorist 1                                        初始时送一个乘员,如果不送的话,一诞生就会自杀,因为没有驾驶员(可恶的EA)
    ScatterNearbyOnExit   = No                                                                        乘员下车后自动散开,即跑开一定距离
    HealthRegen%PerSec  = 0                                                                        每秒给乘员加血的数量
    DamagePercentToUnits  = 100%
    BurnedDeathToUnits    = No                                                                驾驶员直接消失,而不是被烧死
    AllowInsideKindOf     = INFANTRY
    ExitDelay             = 250                                                                        下车延迟时间
    NumberOfExitPaths = 1                                                                                下车路径值,1为默认值,表示下车后站在随机位置上,其他值表示固定值,将关联到本体的骨骼点ExitStart和ExitEnd上
    GoAggressiveOnExit = Yes                                                                        若下车前处于攻击状态,那么下车之后继续追杀刚才打的哪个目标(或位置)
    DoorOpenTime = 0
  End
  点评:前面讲生存时间模块时提到摩托车容器的巨大BUG,实际上主要是因为EA脑壳有包,强迫要求摩托车在缺少驾驶员时必须自杀,他们要是不限制这个规则,就不会有这个BUG了:
      给某个步兵加上最短30秒的LifetimeUpdate或者DeletionUpdate,然后将它装进摩托车,然后再把摩托车装进地道,然后立刻再把摩托车从地道里放出来,结果摩托车刚一出洞口就莫名其妙地倒了。这是为什么呢?现在我就来解释一下原因。上面说摩托车容器是一种半外不内式,BUG就在于此。首先我们要回顾一下生存时间模块的第一条BUG:
      给某个单位加上30秒的Lifetime,然后将它装进任何一种容器,等半个小时回来看,那家伙竟然还在里面呆着。但你一放它出来,它就马上死或者消失在你面前。
      这个现象表明,只在当本体处于容积外部时才开始计算生存时间,而当本体被装进容器后,计时将暂停,因此放在容器里的单位是不到放出来时坚决不死的(脸皮还真TM厚)。再看第二条:
      还是给它加上30秒的Lifetime,然后将它装进任何一种容器,然后马上放出来,那家伙竟然立刻死或者消失在你面前,明明30秒还没到,那家伙竟然就慌着见阎王去了……
      这个现象表明,生存时间和消失时间模块的计时在暂停后无法正确恢复,基本上可以理解为暂停后计时立刻变成0秒,按道理来说这家伙该死了吧,可是它在容器里,是“暂时无敌”的,所以只有放它出来时,它才会死,而且是马上死。明白了这两个BUG的原理之后,我们再来看摩托车容积的BUG又是怎么回事:
      将一个反抗军派上摩托车,然后将摩托车装进地道,再立刻将摩托车从地道里放出来,没看到什么奇怪的现象吗?那就反复这样进去、出来、再进去、再出来,偶尔会发现,当摩托车出地道后,会莫名其妙地出现一个“多余”的反抗军从车上跑下来(车上明明还坐着一个,那这家伙是从哪里来的呢),或许你觉得好奇,去点选、框选这个多余的反抗军,但是弄死都选不中,然而当你命令摩托车移动一步的话,这个多余的反抗军就会立刻消失掉。这便是摩托车容器“半外不内”的BUG所在了,也就是说,正常情况下,进入摩托车容器A的乘员将被包含在A内部(若乘员有生存时间模块的话,将停止记时),反之,当装有乘员的A进入另一个容器B中时,这个乘员将存在一定几率被A“漏”给B,也就是说,乘员将有可能和A以平等的地位被装在B里,但由于乘员在本质上依然受到A的牵扯,将会随A的移动而一起移动,因此当A被放出B之后,乘员也会跟着A一起被放出B,如果正好处于“漏”的几率时,你就能看到乘员和A一起跑出来(由于乘员站在里A外面,若乘员有生存时间模块的话,则记时恢复)。之所以乘员不能被选取,那是因为它依然还受A的牵连,属于一个不能自主行动,也不接受直接指挥的从属单位,而当你命令A移动的时候,乘员就会自动回到A的内部(由于是瞬移进去的,所以你会看到反抗军突然消失),如果在乘员的生存时间归0之前,你不让A移动,那么这个乘员就会因生存时间结束而死亡,因此A就会因为缺少乘员而自杀。
      于是乎,AS的作者没有注意到这个BUG,草率地将IFV的虚拟驾驶员做成了一个带有生存时间模块的虚拟步兵(所谓虚拟,即无图像),因此才发生了IFV从运输船里出来时自爆的怪现象。FK3D为了避免这个BUG,舍弃了用生存时间方式来删除虚拟驾驶员,而是改用自杀武器的方式,给虚拟驾驶员添加一个自动开火修正,调用一个只能对本体产生秒杀级伤害的武器。前面讲自动开火修正时已经提过,当本体进入容器内时,将停止自动开火,出来后继续开火,因此用自动开火修正可以代替生存时间修正,不仅如此,它们二者还有一个很大的区别:当乘员被漏给B,而同时还被A牵扯时,生存时间将恢复记时,但自动开火却不会恢复,因此在使用自动开火修正的情况下,即便虚拟驾驶员偶尔“跑”出了IFV,它也不会自动开火,所以就不会杀死自己让IFV自爆。

  Behavior = TransportContain ModuleTag_XX                                                普通运输容器,内部式,常用于运输车、飞机或船舰,可以设置是否允许盟友、中立者以及敌人进入
    Slots               = 3
    HealthRegen%PerSec  = 25
    DamagePercentToUnits = 10%
    AllowInsideKindOf   = INFANTRY
    AllowAlliesInside   = Yes                                                                        是否允许盟友进入
    AllowNeutralInside  = No                                                                        是否允许中立者进入
    AllowEnemiesInside  = No                                                                        是否允许敌人进去,听着咋这么别扭?
    ExitDelay = 250
    NumberOfExitPaths = 3
    GoAggressiveOnExit = Yes
  End

  Behavior = InternetHackContain ModuleTag_XX                                        网络中心容器,内部式,可以让进入的乘员不停地刷钱,前提是这个乘员必须是带有黑客刷钱修正
    PassengersAllowedToFire = No
    Slots                 = 8
    ScatterNearbyOnExit   = No
    HealthRegen%PerSec  = 10
    DamagePercentToUnits = 50%
    AllowInsideKindOf     = MONEY_HACKER
    ExitDelay             = 500
    NumberOfExitPaths = 1
    GoAggressiveOnExit = No
  End

  Behavior = GarrisonContain ModuleTag_XX                                                驻守容器,内部式,切记不能用于可移动物体,否则容器跑开了,乘员却还留在空空如也的“原地”
    ContainMax                   = 4                                                        最大驻守格数,和界面按钮关联,不是按照体积来计算的,也就是说,进去一个步兵扣一格,进去一个坦克还是只扣一格
    EnterSound                   = GarrisonEnter                                驻守者进入时播放的音效
    ExitSound                     = GarrisonExit                                驻守者撤离时播放的音效
    ImmuneToClearBuildingAttacks  = Yes                                                        是否对清除驻守型武器免疫,所谓清除驻守型武器,比如火龙坦克的火焰、游骑兵的闪光弹和毒素坦克的毒液
    DamagePercentToUnits         = 100%
    IsEnclosingContainer           = No                                                        是否是封闭型容器,默认为Yes,没搞懂什么叫封闭型。原版里只有炮兵阵地才这个语句。
  End

  Behavior = HealContain ModuleTag_XX                                                        治疗容器,内部式,使进入的单位在一定时间内恢复满血,然后自动跑出来
    ContainMax         = 10                                                                        最大进入者数量,和驻守类似,进什么东西都只占1格,只是不和界面按钮关联,因为进入者在康复之后会自动跑出来
    TimeForFullHeal     = 2000                                                                        从死血加到满血所需要的时间,有点类似于维修厂修正
    AllowInsideKindOf   = INFANTRY
    AllowAlliesInside     = Yes
    AllowNeutralInside   = No
    AllowEnemiesInside  = No
  End

9、        接触类模块。这类模块的作用是让本体A与其他物体B接触,可以是A主动去接触B,也可以是A被动地遭到B的接触,只要接触成功,就会对B产生一定的效果,例如使B恢复满血、送给B一个免费物体、使B所属参战方地图全黑、将B转换成什么东西等。接触成功之后,A将自动消失并被游戏平台消除人口空间,可以理解为A已经死亡。一些模块还可以设置接触条件,B必须满足接触条件,才能和A成功接触,否则A和B是永远无法相撞的。一说到这里,我就不由自主地想起了RA2的箱子……事实上接触类模块远不只是RA2的箱子那么简单。你还可以做点邪恶的构思,将带有接触模块的物体当作射弹体打出去撞别人,给对手造成点恶意的效果,嘿嘿嘿……
  Behavior = SalvageCrateCollide ModuleTag_XX                                        垃圾箱。可以给含有特定类型标签的B提供对应类型的效果,各种效果各占一定的几率
    ForbiddenKindOf = PROJECTILE                                                                若B含有这些标签,则不能与A成功接触
    PickupScience = SCIENCE_GLA                                                                B所属参战方必须学会了某个技能才能与A成功接触
    ExecuteFX = FX_CratePickup                                                                接触成功后引发的FX特效
    WeaponChance = 100%                                                                                使B获得武器升级的几率,前提是B有捡垃圾升级武器的功能,且尚未获得过武器升级,否则此几率自动被屏蔽
    LevelChance = 25%                                                                                        使B加一等级,前提是B不是王牌级别且可以通过训练升级,否则此几率自动被屏蔽
    MoneyChance = 75%                                                                     使B所属参战方获得随机金币的几率,注意加级的几率和得金币的几率之和必须为100%
    MinMoney = 25                                                                                                得到的最少金币(如果效果是得金币的话)
    MaxMoney = 75                                                                                                得到的最多金币
  End
  点评:这个模块除了用于垃圾箱外,我不知道它到底还能有啥价值。

  Behavior = SabotagePowerPlantCrateCollide SabotageTag_XX                整体断电。B所属参战方整体断电一定时间,前提是B必须含有FS_POWER类型标签
    BuildingPickup = Yes                                                                                是否只能与建筑接触
    SabotagePowerDuration = 30000                                                                B所属参战方整体断电时间,单位为毫秒
  End

  Behavior = SabotageSupplyDropzoneCrateCollide SabotageTag_XX                偷补给平台。B所属参战方将分一定数量的金币给A,前提是B必须含有FS_SUPPLY_DROPZONE类型标签
    BuildingPickup  = Yes
    StealCashAmount = 800                                                                                B所属参战方将分多少个金币给A
  End

  Behavior = SabotageSuperweaponCrateCollide SabotageTag_XX        复位超武。B所关联的所有超武将重新计时,前提是B必须含有FS_SUPERWEAPON标签,且自身关联得有至少一种超武
    BuildingPickup = Yes
  End

  Behavior = SabotageCommandCenterCrateCollide SabotageTag_XX                一直没测试出渗透指挥中心能带来啥结果,难道和复位超武一样,将指挥中心所关联的所有技能全部复位?
    BuildingPickup = Yes
  End

  Behavior = SabotageSupplyCenterCrateCollide SabotageTag_XX        偷补给中心。B所属参战方将分一定数量的金币给A,前提是B必须含有CASH_GENERATOR类型标签
    BuildingPickup  = Yes
    StealCashAmount = 1000                                                                                效果和偷补给平台一样
  End

  Behavior = SabotageMilitaryFactoryCrateCollide SabotageTag_XX        关闭工厂。B将在一段时间内无法生产单位。前提是B必须含有FS_FACTORY标签且带有生产单位的界面按钮
    BuildingPickup = Yes
    SabotageDuration = 30000                                                                        B无法生产单位的持续时间
  End

  Behavior = ConvertToHijackedVehicleCrateCollide ModuleTag_XX        永久控制。B将被A所属参战方永久控制,这才是ZH里最让人满意的心灵控制
    RequiredKindOf = VEHICLE                                                                        可以控制含有哪些类型标签的B,FK3D特意添加上了INFANTRY,于是超能力部队不光能偷车,还能偷人……
  End
  点评:这个模块比较特殊,只能是A在被人工或脚本操作的情况下接触到B(即常言道的命令A去渗透B)才能接触成功。如果将A当作射弹体打出去撞B,即便你看到A和B都重合在一起了,也没有任何结果发生。所以当初我妄图让超能力部队将一个A打到敌人身上去控制敌人,结果失败了……

  Behavior = ConvertToCarBombCrateCollide ModuleTag_XX                能力合体。B将与A合二为一,使B能够使用A武器,例如恐怖分子的自杀炸弹,不知道是否还有别的能力被合体
    RequiredKindOf    = VEHICLE
    ForbiddenKindOf  = TRANSPORT DOZER                                        不能与含有哪些类型标签的B合体
    FXList            = FX_MakeCarBombSuccess                                合体成功后引发什么FX特效
  End
  点评:严重怀疑CNC3的天神机甲是不是用了这个模块,使之可以将别人的武器拆下来装到自己手臂上使用。含有这个模块的A同样不能当作射弹体用,真是郁闷……

  Behavior = VeterancyCrateCollide ModuleTag_XX                                        等级提升。B将增加一定等级,前提是B不是王牌级别,且可以通过训练来升级
    RequiredKindOf = VEHICLE
    ForbiddenKindOf = DOZER
    EffectRange = 0                                                                                        作用范围,0表示只对B产生作用,如果再大一点,就会影响到B周围的其他物体
    AddsOwnerVeterancy = Yes                                                                        是否将A自身的等级全部送给B(即有可能一口气让B提高2到3个等级),No的话则无论如何只给B提高1个等级
    IsPilot = Yes                                                                                                A是否必须是驾驶员?不对吧,我没找到PILOT这个类型标签啊?
  End

  Behavior = UnitCrateCollide ModuleTag_XX                                                免费物体。B所属参战方将在A消失的位置上得到一些特定的免费物体
    RequiredKindOf = WAVEGUIDE                                                                仅当B含有这些类型标签时才能和A接触
    ForbiddenKindOf = PROJECTILE
    ExecuteFX = FX_CratePickup
    UnitName = AmericaTankCrusader                                                                B所属参战方将得到什么样的免费物体
    UnitCount = 2                                                                                                免费物体数量
  End
  点评:让我想起了RA2里捡箱子捡出另一种基地车的喜悦……

  Behavior = ShroudCrateCollide ModuleTag_XX                                        地图全黑。B所属参战方将遭受地图全黑的厄运,将A打到敌人身上去让对手变瞎子吧,很邪恶的哦
    ForbiddenKindOf = PROJECTILE
    ExecuteFX = FX_CratePickup
  End

  Behavior = MoneyCrateCollide ModuleTag_XX                                        爆金币。B所属参战方将凭空获得固定数量的金币。
    ForbiddenKindOf = PROJECTILE
    MoneyProvided = 1000                                                                                得到的金币数量
    ExecuteFX = FX_CratePickup
    ExecuteAnimation       = MoneyPickUp                                                接触成功后引发的2D动画,即那个永远如此诱人的美元符号
    ExecuteAnimationTime   = 4.0                                                                2D动画持续时间
    ExecuteAnimationZRise  = 15.0                                                                2D动画上升距离
    ExecuteAnimationFades  = Yes                                                                2D动画是否在末尾时淡化直到消失
  End

  Behavior = HealCrateCollide ModuleTag_XX                                                免费治疗。B将瞬间恢复满血。似乎SAGE里没有像RA2那样让B所属参战方全体加满血的效果,所以只能影响一个B
    ForbiddenKindOf = PROJECTILE                                                                可以尝试一下用EffectRange语句,看看是否能多影响一些B周边的物体
    ExecuteFX = FX_CratePickup
  End

  Behavior = SquishCollide ModuleTag_XX                                                        无效果。B不会得到任何效果,但A会被游戏平台判死,并立刻执行死亡方式模块或延迟死亡模块的功能。
    ;nothing
  End
  点评:一般用于步兵,当他们在遭受车辆接触时将被撞死,而撞击他们的车辆将不会得到任何效果。

  Behavior = FireWeaponCollide ModuleTag_XX                                        触发开火。A将在与B接触的瞬间发射一个武器,似乎只有这个模块在接触成功后A不会消失。
    CollideWeapon  = TreeFireDealDamageWeapon                                A将发射哪个武器
FireOnce = Yes                                                                                                是否只发射一次就自动停手。No的话则会按照武器代码的设置反复不断地持续开火
    RequiredStatus = AFLAME                                                                        A必须带有这些状态标签时才能接触成功。
  End

10、        特效武器类模块。这类模块一般具有一定的特殊作用
  Behavior = GenerateMinefieldBehavior ModuleTag_XX                        雷区发生器模块。可以产生出一片雷区,并控制对应雷区的重生。
    MineName             = ChinaClusterMine                                        关联哪种雷区
    DistanceAroundObject  = 80                                                                        雷区将被布置在距离本题中心本体多远的圆周上
    GenerateOnlyOnDeath  = Yes                                                                只在死亡的时候产生雷区?那不相当于说只产生一次?
    SmartBorder           = Yes                                                                精确边界?没搞懂有啥意义
    SmartBorderSkipInterior = No                                                                        是否是环形雷区,Yes则只有边界上有一圈地雷,中央地带是空的,反之则整个范围上充满了地雷,
    AlwaysCircular         = Yes                                                                边界是否形成正圆形
    GenerationFX         = WeaponFX_ClusterMineImpact                产生地雷时引发的FX特效
  End

  Behavior = MinefieldBehavior     ModuleTag_XX                                雷区模块。可以被一定类型的目标引爆,然后发射某个武器。需要被雷区发生器关联
    DetonationWeapon            = ClusterMineWeapon                        引爆时发射哪个武器
    DetonatedBy                 = ENEMIES NEUTRAL                        可以被哪些目标引爆
    ScootFromStartingPointTime  = 1000                                                        迅速从起始点跑开的时间?啥意思?
    RepeatDetonateMoveThresh    = 5.0                                                        每隔多长时间检查一次是否有合适的目标来将它引爆
    NumVirtualMines             = 8                                                        闪光点数量,需要对应外观模块里定义的粒子系统骨骼点
    Regenerates                 = Yes                                                        引爆后是否还能重生,即爆炸一次之后过一段时间还能否自动长出来
DegenPercentPerSecondAfterCreatorDies = 3.33%                                当对应的雷区发生器丢失之后,只能再多存活多长时间
StopsRegenAfterCreatorDies  = Yes                                                        当对应的雷区发生器丢失之后将不能再重生
  End

  Behavior = NeutronBlastBehavior ModuleTag_XX                                        中子冲击模块。可以杀死一定范围内的所有驾驶员,那这和杀死驾驶员的DamageType有啥区别?
    BlastRadius = 20                                                                                        有效冲击范围
    AffectAirborne = No                                                                                        是否影响空中单位
    AffectAllies = No                                                                                        是否影响自己人和盟友的单位
  End

尚有一些非常罕见,或者难度过分高的模块我没有例举,如果大家有兴趣可以自己去挖掘。此外,还望大家多给我补充和修正。
 楼主| 发表于 2010-11-29 10:49:29 | 显示全部楼层
本帖最后由 yangqs 于 2010-11-29 12:37 编辑

第四章        常用代码编辑详解
第二章里我们了解了制作一个完整的新单位需要编辑哪些INI,但那个例子非常浅显,以至于不能囊括所有INI的内容。因此我们将在本章来个更加详细的代码编辑讲解。

1、        CommandButton
这个INI用于定义所有界面按钮的功能,以便被CommandSet调用。使用格式如下:
CommandButton  [按钮名称]
[按钮名称]可使用任意字符串,并且暂时不知道是否存在字符数上限。一般情况下为了确保让自己能一眼看出这个键是干什么用的,通常用下划线将其分为多个部分,例如一般的动作键可以使用Command_XX,建造建筑键可以使用BuildCMD_XX,生产单位键可以使用CreateCMD_XX,升级键可以使用UpgradeCMD_XX等等,总之,游戏平台无所谓你取什么名称,只要在调用时能对应得上就行,这是让你自己快速识别的。

CommandButton   Command_XXXX
WeaponSlot = [武器序号]                                即PRIMARY、SECONDARY 或 TERTIARY,多个并列表示同时使用,当然这种情况不能出现在切换武器键里
Upgrade    = [升级项目名称]                        调用一个有效的升级项目,需要对应Upgrade.ini。
Science     = [技能证书名称]                        调用一些有效的技能证书(多个并列时表示与逻辑)
ButtonImage = [图像名称]                                调用一个有效的TGA图象,需要对应MappedImages,这个今后再讲
TextLabel   = [CSF翻译项]                                鼠标悬停在该按钮上时,就地显示的说明字段
DescriptLabel = [CSF翻译项]                        鼠标悬停在该按钮上时,左下角信息栏里显示的介绍信息字段
InvalidCursorName = [CUR指针文件名]        调用一个能够被游戏引擎识别的CUR格式鼠标指针,表示当不能执行该操作时的鼠标指针图像,例如GenericInvalid为原版自带的圆圈斜杠
UnitSpecificSound = [音效名称]                        成功点击这个按钮后播放的效果音        
CursorName = [指针名称]                                使用该命令时的鼠标指针(鼠标图案在 "Mouse.ini" 中设定)

Command = [命令类型]                                定义该按钮到底发挥什么样的功能和作用,有以下这些参数可选
UNIT_BUILD                                                                                        建造物体,可以是推土机、建造房子、兵营训练步兵、重工生产坦克、机场生产飞机
SPECIAL_POWER_FROM_COMMAND_CENTER                        从指挥中心发射超武/技能
SPECIAL_POWER                                                                                使本体对所选目标使用特殊能力或发射超武/技能,几乎可以顶替上面一个
FIRE_WEAPON                                                                                使本体对所选目标或所选位置发射常规武器(需要搭配WeaponSlot语句)
SWITCH_WEAPON                                                                                使本体切换锁定一种武器来单独使用(需要搭配WeaponSlot语句)
SET_RALLY_POINT                                                                        设置集合点,前提是本体必须含有AUTO_RALLYPOINT类型标签
SELL                                                                                                        将本体拆除
TOGGLE_OVERCHARGE                                                                切换到超负荷状态,前提是本体必须含有超负荷修正
CANCEL_UPGRADE                                                                        取消升级,似乎没啥用,因为升级并不需要专门在界面上取消
PLAYER_UPGRADE                                                                        宏观升级,需要搭配Upgrade语句,对应宏观型升级项目
OBJECT_UPGRADE                                                                        微观升级,需要搭配Upgrade语句,对应宏观型升级项目
EXIT_CONTAINER                                                                                命令该按钮所对应的单位离开容器
EVACUATE                                                                                        命令该容器里所有乘员离开容器
EXECUTE_RAILED_TRANSPORT                                                执行铁路运输?莫非是控制火车用的?
COMBATDROP                                                                                绳索空降,本体需要具备绳索空降修正
GUARD                                                                                                范围警戒,使本体在一定范围内自动反击并追击进入视野的敌人
GUARD_WITHOUT_PURSUIT                                                        定点警戒,使本体在一定范围内自动反击敌人,但不会去追击敌人
GUARD_FLYING_UNITS_ONLY                                                        领空防御,使本体在一定范围内自动反击空中敌人,前提是本体必须是机场型战斗机,否则没有任何意义
ATTACK_MOVE                                                                                移动攻击,使本体一边跑一边攻击任何可攻击的目标,前提是本体必须具有可旋转的炮塔
STOP                                                                                                        停止动作,使本体停止当前所有动作,进入空闲状态
CONVERT_TO_CARBOMB                                                                主动合体,使本体主动跑过去与目标合体,例如恐怖分子填装汽车炸弹
HIJACK_VEHICLE                                                                                主动控制,使本体主动跑过去撞击目标以实现对目标的永久控制,例如劫持犯抢劫车辆
HACK_INTERNET                                                                                黑客刷钱,使本体立刻坐下来开始刷钱,前提是本体必须具有黑客刷钱能力                                                        

Options =  [命令属性]                                        定义该按钮在发挥具体功能和作用时有些什么样的特性,有以下这些参数可选
NEED_SPECIAL_POWER_SCIENCE                                         需要SP或技能证书的支持,有这条属性,则可以配上SpecialPower来调用一个SP,或者配上Science来调用一个技能证书
NEED_TARGET_POS                                                                        需要选择目标位置,常用于定点开火式按键,按下键后会叫你选择开火的目标位置(就像超武发射那样)
NEED_TARGET_ENEMY_OBJECT                                                需要选择敌人的物体作目标,同上
NEED_TARGET_NEUTRAL_OBJECT                                        需要选择中立的物体作目标,同上
NEED_TARGET_ALLY_OBJECT                                                        需要选择自己或盟友的物体作目标,同上
CONTEXTMODE_COMMAND                                                        上下文关联,没搞懂有啥意义,似乎凡是用了上面4种NEED_TARGET属性时必须有它才产生作用
SCRIPT_ONLY                                                                                        只能被触发控制,并且不会出现在界面上,因此只能通过WB制作AI触发来“按下”这个键
OK_FOR_MULTI_SELECT                                                                当多个物体同时具有同一个按钮时,是否在操作界面上显示出这个按钮以便让玩家按一次键对所有这些单位都有效
CHECK_LIKE                                                                                        只对状态相同的多个本体有效,通常与上一句连用
OPTION_ONE                                                                                        第一选项
OPTION_TWO                                                                                        第二选项
OPTION_THREE                                                                                第三选项,这3个选项只用在战略中心设置战略方针的按键上,需要配合战略中心的策略修正使用,难度太高……
NOT_QUEUEABLE                                                                                不能排队等候,常用于建造或升级键,若本体正在进行建造或升级过程,则这个键不能点,必须等本体空闲之后才能点
IGNORES_UNDERPOWERED                                                        无视电力,通常用于耗能型主体,使之即便停电后,按键依然可以点击,否则按键会变灰

RadiusCursorType = [范围圈名称]                某些需要选择目标的按钮可以使用一个范围圈来表示有效作用范围,以下参数是一些不能随意修改的平台内码,后面再详细解释。
DAISYCUTTER
NAPALMSTRIKE
PARADROP
CLUSTERMINES
EMPPULSE
A10STRIKE
SPECTREGUNSHIP
CARPETBOMB
NUCLEARMISSILE
SCUDSTORM
ARTILLERYBARRAGE
FRENZY
SPYSATELLITE
SPYDRONE
RADAR
AMBUSH
EMERGENCY_REPAIR
ANTHRAXBOMB
GUARD_AREA
CLEARMINES
ATTACK_SCATTER_AREA
AMBULANCE
HELIX_NAPALM_BOMB        
PARTICLECANNON
End



2、        CommandSet
这个INI用于定义建造栏/操作界面上所有按键的布局位置,以便在单位代码里调用它来作为该单位的建造栏或操作界面。使用格式如下:
CommandSet  [界面名称]
[界面名称]可使用任意字符串。还是老话,取什么名字都无所谓,关键是你自己要能快速识别。
每个建造栏/操作界面可以最多放置14个按键,分为2行7列,其位置对应号码如下:
1        3        5        7         9         11        13
2        4        6        8        10        12        14
                        使用时,将按钮名称作为参数放到对应号码后面即可,就像下面这个例子,特别需要注意的是,这些按键名称不能随意乱写,否则会报错。你必须确定它是一个有效的按键,或者说必须是能够在CommandButton.ini里找得出来的按键。很多新手就是因为不知道这里的对应规律,觉得随便写一个字段作参数就行了,结果就遇到报错还不知道自己错在哪里。

CommandSet   XXXXCommandSet
  1  = Command_ConstructAmericaPowerPlant
  2  = Command_ConstructAmericaStrategyCenter
  3  = Command_ConstructAmericaBarracks
  4  = Command_ConstructAmericaSupplyDropZone
  5  = Command_ConstructAmericaSupplyCenter
  6  = Command_ConstructAmericaParticleCannonUplink
  7  = Command_ConstructAmericaPatriotBattery
  8  = Command_ConstructAmericaCommandCenter
  9  = Command_ConstructAmericaFireBase
  11 = Command_ConstructAmericaWarFactory
  13 = Command_ConstructAmericaAirfield
  14 = Command_DisarmMinesAtPosition
End

上面这个例子里,没有定义12号位置是什么按键,那么游戏平台将把12号位置留空。


3、        FXList
这个INI用于调用一系列闪光、声音、屏幕抖动、粒子系统等来组合成一套FX特效,至于FX是什么东西,我至今没搞清楚,我只知道它是一种视觉特效。使用格式如下:
FXList  [特效名称]
[特效名称]同样可以是任意字符串。
例如下面这个例子,被调用的项目作为FXList的子函数被排成列表存放在FXList的代码中。每个子函数只能调用一个元素,如果想要多个元素同时发生作用,就多建立一个子函数,例如你可以建立10个调用粒子系统的子函数,分别调用10个粒子系统,调整好每个粒子系统的参数,这样就能形成一套华丽的FX特效。
此外有意思的是,这个INI里很多语句的参数可以乱写,即便调用不到东西,或者调用失败也不会报错,仅仅会失去作用,相当于没有调用。但是会被月光宝盒检查出来并给于警告。

FXList  FX_XXXX
  ParticleSystem                                                                                调用粒子系统
    Name = MammothTankSubExplosionSmoke                                粒子系统名称,需要对应ParticleSystem.ini里的一个粒子系统,不过即便乱写也不会报错,仅仅显示不出效果罢了
    Radius = 15 30 UNIFORM                                                                在距中心多大的范围内随机位置产生,两个数字分别为最小值和最大值,UNIFORM表示统一,似乎是必须要有的字段
    Height = 0 20 UNIFORM                                                                粒子系统在多高的高度上产生
    InitialDelay = 167 667 UNIFORM                                                延迟多长时间再产生
  End
  ViewShake                                                                                调用屏幕抖动
Type = STRONG                                                                                抖动级别,可以选择6种级别,强度依次增大,可在GameData.ini里修改具体的抖动强度值
  End                                                                                                        SUBTLE  <  NORMAL  <  STRONG  <  SEVERE  <  CINE_EXTREME  <  CINE_INSANE
  TerrainScorch                                                                                调用弹坑,或者说叫地面烧焦效果更形象
    Type = RANDOM                                                                                RANDOM表示随机选择一种烧焦图案
    Radius = 15                                                                                        图案半径为多少像素
  End
  Sound                                                                                        调用声音
    Name = TankDie                                                                                声音名称,需要对应Voice.ini或SoundEffects.ini里的一个声音事件,随便乱写同样不会报错,仅仅导致无声罢了
  End
  LightPulse                                                                                        调用闪光,闪光在游戏里将被显示成一个带颜色的圆盘区域
    Color = R:180 G:128 B:32                                                                闪光颜色,使用RGB三色方案调色
    Radius = 15                                                                                        闪光半径为多少像素,注意,尺寸过大的闪光很吃显卡,因此建议不要使用大于50点的参数值
    IncreaseTime = 0                                                                                亮度增至最大的持续时间,0表示突然达到最大亮度
    DecreaseTime = 100                                                                        亮度减至消失的持续时间,如果这2个语句的持续时间都比较长,在连续激发闪光的情况下可以看到动态闪光效果。
  End
  Tracer                                                                                                调用线条,常用于模拟机枪子弹在空中划过的光迹,这个功能在CNC3上视觉效果非常好,在ZH里比较难看
DecayAt = 1.0                                                                                衰减削弱程度,似乎只在ZH里有效,因为CNC3的子弹光迹是不衰减的,1表示正常衰减,既到达目标点就淡化消失完
在ZH里值越大,衰减越不明显,会显得子弹跑过了头(把目标打穿了)。反之则衰减很快,会显得子弹还没跑拢
    Length = 10                                                                                        线条长度,当攻击距离小于这个值时开火,会看不到任何线条,因此建议这个值不要大于20
    Width = 0.3                                                                                        线条宽度,当线条宽度被调得比较宽时,你可以发现,原来线条是一个长方形
    Color = R:255 G:0 B:0                                                                线条颜色,同样是RGB三色方案
    Speed = 300                                                                                        线条飞行速度,建议和武器代码里定义的射弹体速度相等,否则容易没中弹就死,或者中弹之后等一会儿才死的怪异情况
    Probability = 0.5                                                                                产生几率,最大1.0,表示100%,一般使用30%到70%之间的参数比较好,这样的光迹比较随机,像真正的机枪
  End
End


4、        Locomotor
这个INI用于定义运动模式,例如速度、加速度等属性,被单位代码调用。使用格式如下:
Locomotor  [运动模式名称]
[运动模式名称]同样可以是任意字符串。但是千万要注意,单位代码里调用一个运动模式时千万不能乱写,一旦调用不到有效的运动模式就会报错。
这个INI基本上是直接调用物理引擎里支持的各种运算,有些表现形式甚至和NFS相似,那是因为当今的3D游戏一般都采用相同的物理引擎,因此建议物理学得不好的MODER先回家补习补习运动学知识。

Locomotor XXXXLocomotor
Speed                                                                                                        移动速度,每秒移动多少个像素
SpeedDamaged                                                                                损伤后移动速度
Acceleration                                                                                        正常时候的加速度,每秒变化多少点速度
AccelerationDamaged                                                                        重伤(红血)时的加速度
Braking                                                                                                刹车时的加速度,也就是减速的速度
TurnRate                                                                                                正常时候的转向角速度,每秒转动多少角度
TurnRateDamaged                                                                                重伤时的转向角速度
MinTurnSpeed                                                                                        最小转向角速度,特别注意,这个参数不能比TurnRateDamaged大!
StickToGround                                                                                        是否紧贴地面,Yes表示随时贴紧地表面,No则可能在特定情况下离开地面(如摩托车飞山),缺省值为No

Surfaces = [移动区域]                                        定义该物体可以在什么区域里行走,多个并列时表示能在这些区域里行走
GROUND                                                                                        地面,只能在平整的干地面行走,遇到障碍会绕行,常用于一般步兵和坦克
RUBBLE                                                                                        碎石,可以在碎石地表行走
CLIFF                                                                                                山脊,可以在山脊上行走,当然,需要配合模型动作,例如贝顿在山脊上行走的动作实际上是攀爬,而摩托车是飞山
AIR                                                                                                空中,可在任意地面行走,无视一切障碍,例如FK3D里的蝰蛇和凤凰经常能“钻”到高大建筑里去呆着
WATER                                                                                        水面,只能在水域里行走,遇到障碍会绕行,常用于船

ZAxisBehavior = [Z方向移动类型]                定义物体在垂直方向上如何移动
NO_Z_MOTIVE_FORCE                                                                无垂直方向移动,用于所有地面单位
SURFACE_RELATIVE_HEIGHT                                                        随地表面高度移动,用于所有飞行器和船只

Appearance = [表现形式]                                定义物体在移动时的动作表现形式,需要配合外观模块来体现
TWO_LEGS                                                                                        步行,用于所有步兵
CLIMBER                                                                                                攀爬,用于贝顿翻山时
FOUR_WHEELS                                                                                轮子,用于轮式车辆,在外观模块里使用特殊语句可以使车轮旋转
TREADS                                                                                                履带,用于坦克,在外观模块里使用特殊语句可以使履带转动
THRUST                                                                                                冲刺,用于射弹体和机场型战斗机
HOVER                                                                                                悬浮,用于直升机、飞艇、飞碟、盘空型战斗机以及船

GroupMovementPriority = [队列位置]        混编部队移动时,各个成员在队伍里会自动调整排位
MOVES_FRONT                                                                                前锋,一般用于近战或突击型单位
MOVES_MIDDLE                                                                                中场,一般用于中程或主力型单位
MOVES_BACK                                                                                        后卫,一般用于远程或辅助型单位

以下这些是正儿八经的物理引擎运算了,很难测试出到底是些什么作用,所以只能使用金山词霸翻译,在实际中使用时可参考原版参数:
AccelerationPitchLimit                                                                        加速时前下压力,或减速时的后下压力,表现为前倾后仰角度
AirborneTargetingHeight                                                                当本体离里面多高时将被游戏平台判定为位于空中(将受到防空火力攻击,且不能被地面火力攻击)
AllowAirborneMotiveForce                                                                允许空气动力??
Apply2DfrictionWhenAirborne                                                        在空中时接受2D摩擦力影响?
BounceAmount                                                                                        颠簸强度,参数为0到200之间,0表示平整,200表示严重颠簸
ForwardAccelerationPitchFactor                                                        多大的加速度才会产生突然的前倾后仰
ForwardVelocityPitchFactor                                                                速度大于多少时产生持续保持的前倾后仰效果
LateralAccelerationRollFactor                                                        多大离心力才会导致突然的侧倾
LateralVelocityRollFactor                                                                转向角速度大于多少时产生持续保持的侧倾效果
LocomotorWorksWhenDead                                                                本体死亡后,尸体是否依然使用这个运动模式,似乎用于悬浮单位时表示本体死亡后,尸体依然浮在空中(飞尸么?)
PitchDamping                                                                                        前后摆动减缓幅度??0为完全减缓,1为随地形摆动
PitchStiffness                                                                                        前后摆动悬挂硬度??
PreferredHeight                                                                                首选离地高度,似乎只能用于空中单位,表示正常情况距离地面的高度
RollDamping                                                                                        侧倾减缓幅度??0 为完全减缓, 1为随地形摆动
RollStiffness                                                                                        侧倾悬挂硬度??
TurnPivotOffset                                                                                转向中心,-1表示后轴定点前轮转向(叉车),0表示以W3D原点为中心自转(坦克),1表示前轴定点后轮转向(汽车)
End


5、        ObjectCreationList
这个INI用于定义刷物体列表,也就是SAGE里最经典的概念,简称OCL,能在需要的时候凭空创建出一系列你想要的东西(免费的!!)。使用格式如下:
ObjectCreationList  [OCL名称]
[OCL名称]同样可以是任意字符串。
同FXList类似,OCL列表也使用多个子函数来调用一些物体,或者直接调用W3D模型,因此也可以随便乱写不会报错,不过还是会被月光宝盒检查出来并给于警告。
OCL总共有3种刷法,分别是直接刷物体、投递运送和刷碎片/残骸。其中投递运送又分为空投乘员和空投武器。
注:为了方便讲解,我将使用OCL的物体称为主体,将被OCL刷出来的物体称为子体。

ObjectCreationList   OCL_XXXX
  CreateObject                                                                        直接刷物体,直接将子体刷到目标位置上
ObjectNames = AmericaInfantryPilot                                刷出什么子体,调用一个物体,调用失败时不会报错,但什么都刷不出来
Offset = X:15 Y:15 Z:5                                                        实际产生点偏离理论产生点的距离,以理论产生点(既刷子体的目标位置)为参考,缺省值为全0,即与理论点重合
Count = 3                                                                                刷出多少个这样的子体,缺省值为1
    IgnorePrimaryObstacle = Yes                                                无视障碍,也就是说对着障碍刷,会把子体刷到障碍物上去
InheritsVeterancy = Yes                                                        继承等级,主体是啥级别,子体就是啥级别,例如FK3D平原游击队将自身复制成3个假像,假像将和主体保持相同级别
    InvulnerableTime = 2000                                                        无敌时间,单位为毫秒,使子体在出现后多长时间内暂时无敌,就像FK3D的铁幕召唤
RequiresLivePlayer = Yes                                                        是否需要活着的玩家,Yes表示当主体所属参战方/玩家战败或退出游戏后,其子体将自动死亡
ContainInsideSourceObject = Yes                                        子体是否被自动装入主体的容器内,前提是主体必须带有任意一种容器修正
    SpreadFormation = Yes                                                        当子体不止一个时,是否自动布成椭圆环形阵列,No则表示使用矩形阵列,缺省值为No
    MinDistanceAFormation = 15.0                                                长轴方向上的阵列最小间距
    MinDistanceBFormation = 15.0                                                短轴方向上的阵列最小间距
    MaxDistanceFormation  = 15.0                                        最大阵列间距,这3句似乎只在椭圆环形阵列时有效
    FadeIn = Yes                                                                        是否使用淡入效果,子体将是慢慢显形而出,而不是直接出现
    FadeTime = 3000                                                                        淡入持续时间,既从诞生到完全显性需要多少毫秒
    DiesOnBadLand = No                                                                如果被刷在不对的地面上是否会立刻死亡。不对的对面,恐怕是指该单位一般情况下不能去的位置,例如障碍上
    FadeSound = ChronoSphereSound                                        淡入音效,淡入过程中播放一个音效

Disposition = [产生动作]                                                        子体出现时将被给于什么样的动作效果,多个并列时表示同时使用这些效果
WHIRLING                                                                                保持不停的原地自转
INHERIT_VELOCITY                                                                继承主体的移动速度
FLOATING                                                                                原地悬浮
RANDOM_FORCE                                                                        随机力,子体将遭受随机力弹飞,加上MinForce和MaxForce那4个语句可以控制随机力的力度和方向取值范围
SEND_IT_OUT                                                                        将之发射出去??
SEND_IT_UP                                                                                将之发射起来??
SEND_IT_FLYING                                                                        将之送飞,貌似经常和随机力一起使用
ON_GROUND_ALIGNED                                                        就地列阵
LIKE_EXISTING                                                                        仿照现有的??

                                        随机力型专用定义,需要Disposition = RANDOM_FORCE的支持
    MinForceMagnitude = 2                                                        随机力的最小力度,这4句需要Disposition = RANDOM_FORCE的支持
    MaxForceMagnitude = 3                                                        随机力的最大力度
    MinForcePitch = 50                                                                随机力的最小角度,似乎是以Z正方向为为参考方向来计算的
    MaxForcePitch = 60                                                                随机力的最大角度
SpinRate = 0                                                                                旋转角速度,0表示不旋转

将之送飞型专用定义,需要Disposition = SEND_IT_FLYING、SEND_IT_OUT或SEND_IT_UP的支持
DispositionIntensity = 4                                                        动作强度,参数值越大,开始飞行的初始速度越快,可达到的高度越高,或者落地点也越远,0表示不飞行
End                                                                                                参数使用0时有特效作用,这个在后面讲解无限弹头法在解释到底是什么作用

;-----------------------------------------------------------------------------------------------------------------------------------------------------

  DeliverPayload                                                                投递运送之空投物体,借助一个投递者将子体运送到目标位置然后投放,就像空降伞兵那样
    Transport               = AmericaJetB52                        调用一个物体作为投递者,该物体必须具有任意一种容器修正,我没试过是否可以使用地面单位来投递
    StartAtPreferredHeight  = Yes                                                投递者一出现就以其运动模式里设置的首选离地高度来飞行,常用于调用飞机作为投递者时
    StartAtMaxSpeed         = Yes                                        投递者一出现就以其运动模式设置的最高能达到的速度来移动
    MaxAttempts             = 1                                                空投时的最大尝试次数,如果连续尝试了这么多次还不能成功投放,它就会放弃投放然后离开
    DropOffset              = X:0 Y:0 Z:-10                        投放偏移,以投递者W3D里的原点为参考点
    Payload                 = DaisyCutterBomb                子体是什么物体,这个子体是被装在投递者里的东西
    DeliveryDistance        = 140                                        投递者在距离目标位置多大的范围内开始尝试投放,若投递者的速度很快,那么这个值不能太小,否则很容易投递失败
    DeliveryDecalRadius     = 170                                        留在地面上的范围指示圈尺寸
    DeliveryDecal                                                                        范围指示圈定义,二级子函数
      Texture           = SCCFuelAirBomb_USA                用哪个TGA贴图来显示范围指示圈
      Style             = SHADOW_ALPHA_DECAL        贴图风格为半透明贴花
      OpacityMin        = 25%                                                最小透明度
      OpacityMax        = 50%                                                最大透明度,若二者不同,则可以形成闪烁效果
      OpacityThrobTime  = 500                                                闪烁频率,每0.5秒一次
      Color             = R:255 G:0 B:0 A:255                染色情况,最后的A代表饱和度(一般都把范围指示圈的TGA贴图做成纯白,这样方便染色)
      OnlyVisibleToOwningPlayer = Yes                                是否只让自己看到范围指示圈
End
  End

  DeliverPayload                                                                投递运送之空投武器,原理和空投物体一样,但效果仿佛是投递者发射一系列武器去攻击目标点,就像地毯轰炸那样
Transport              = ChinaArtilleryCannon               
FormationSize          = 12                                                投放多少个子体
    FormationSpacing       = 1.0                                                相邻子体自动组成圆盘阵形,两两之间的间隔距离
    StartAtPreferredHeight   = Yes
    StartAtMaxSpeed        = Yes
    MaxAttempts            = 1
    DeliveryDistance         = 250
    WeaponErrorRadius     = 100                                        子体落地点的偏离理论落点的误差范围
    DelayDeliveryMax       = 3000                                        最长延迟多长时间投放一个子体,若遇到投放尝试失败,则会延迟到尝试成功为止才投放下一个子体
    VisibleItemsDroppedPerInterval  = 1                                可视项目降落间隔时间??什么是可视项目
    VisibleDropBoneBaseName = RootTransform                可视降落骨骼点基本名称??
    VisibleSubObjectBaseName = Bomb                                可视潜在物体基本名称?这3句似乎起不到任何作用
    VisibleNumBones          = 1                                        可视骨骼点数量
    VisiblePayloadTemplateName = ChinaArtilleryBarrageShell                子体是什么东西,这里的子体必须是一个射弹体,而不能是一般单位
    VisiblePayloadWeaponTemplate = ArtilleryBarrageDamageWeapon                子体落地后使用什么武器来产生爆炸伤害
    InheritTransportVelocity     = Yes                                        子体将继承投递者的速度
    ExitPitchRate              = 30                                        子体被投放的发射角度,以Z负方向为参考
    SelfDestructObject         = Yes                                        是否是自杀物体,Yes的话,投递者在投放完毕后自动死亡(恐怕应该是消失),反之则会飞走
    DeliveryDecalRadius = 125
    DeliveryDecal
      Texture           = SCCArtilleryBarrage_China
      Style             = SHADOW_ALPHA_DECAL
      OpacityMin        = 25%
      OpacityMax        = 50%
      OpacityThrobTime  = 500
      Color             = R:255 G:156 B:0 A:255
      OnlyVisibleToOwningPlayer = Yes
    End
End

;-----------------------------------------------------------------------------------------------------------------------------------------------------

  CreateDebris                                                                        刷碎片或残骸,直接刷出一个不属于任何参战方的模型块,落地后自动沉入地表然后被游戏平台删除掉
    ModelNames = GXMammoth_D09                                        调用什么W3D模型,多个并列表示,可同时刷出多个
    Count = 4                                                                                似乎在多个并列时,表示每一样都刷这么多个
    Mass = 5.0                                                                                碎片/残骸的质量是多少,会影响碎片/残骸的在空中时的物理属性,越重的物体越不容易被弹飞
    Disposition = SEND_IT_UP                                                我怀疑将之发射起来的意思是垂直向上给它一个力将之弹飞,这样说来倒是和随机力有异曲同工的作用
    DispositionIntensity = 1.5                                                        用同样的力去弹质量不同的物体,质量越大的越不容易弹得动,这个是中学物理就讲过的,不知道的赶快回去补习
End

End

6、        Science
这个INI用于定义将军技能证书,以便被一些SP调用来作为施展前提,或者被按键调用来作为学习这项技能的界面键,甚至可以作为建造前提或触发条件,就像美国的帕拉丁坦克,必须要获得了对应技能证书才能生产,而中国的红卫兵,若是获得了步兵训练之后,出来就是老兵级别。使用格式如下:
Science  [证书名称]
[证书名称]同样可以是任意字符串。

Science   SCIENCE_PaladinTank
  PrerequisiteSciences = SCIENCE_AMERICA SCIENCE_Rank3                需要哪些证书作为学习许可前提,多个并列时表示必须同时具备才能开放此证书并允许你学习,否则按键是灰的
  SciencePurchasePointCost = 1                                                学习这个技能证书需要花费的“学费”,也就是消耗的经验点。特别注意0表示不能学习,而不是免费!!
  IsGrantable = Yes                                                                        是否允许通过学习的方式来获得,No的话表示不能学(按键不能点),但并不代表不能走后门买或者免费送
  DisplayName = SCIENCE:USAPaladin                                        鼠标悬停时到对应按键上时显示什么文字介绍
  Description = CONTROLBAR:ToolTipUSASciencePaladin                        鼠标悬停时到对应按键上时左下脚介绍框里显示什么详细信息
End

对于PrerequisiteSciences语句来说,它定义了这个技能证书的学习前提,即“必须先拿到了某个证书才允许你来学这个证书”,就好比“必须先读小学、然后才能读中学,读完中学才能读大学”,你如果非要“先读大学再读小学的话”,教育部门就会以“还没拿到高中毕业证”的理由将你拒之于大学门外。不过要注意的是,这个语句的参数并非一定要是通过学习来获得的证书,也可以是一些天生就具有的“证书”,例如本例里的SCIENCE_AMERICA,这个证书是无论如何都学不到也买不来的,但只要你是美国派系的将军,那么你天生就有这个证书。当然也可以是标志着“年龄”概念的级别,例如本例里的SCIENCE_Rank3,这个证书也是无论如何都学不到也买不来的,但只要你的将军升级到3星,自然就会得到这个证书。而原版还经常性地将一个超武型将军技能分为3个实力逐渐提升的等级,并将相对低一级的证书作为相对高一级的学习前提,就像小学、中学、大学那样的渐进关系一样,因此在实际制作过程中要随时注意,对于这些关联性的调用,参数千万不能随便乱写,否则一旦调用失败,会导致游戏报错。

7、        SpecialPower
这个INI用于定义SP,并控制其类型码标签、倒记时等参数,以便被一些超武、技能、特殊能力调用来作为控制规律。部分SP自身的类型码标签还有一些直接特效。使用格式如下:
SpecialPower  [证书名称]
[证书名称]同样可以是任意字符串。

SpecialPower SuperweaponDaisyCutter
  Enum               = SPECIAL_DAISY_CUTTER                                类型码标签,这个参数是一些不能随意修改的平台内码,部分类型有特殊效果
  ReloadTime          = 360000                                                                        倒记时时间
  RequiredScience     = SCIENCE_DaisyCutter                                        需要哪个技能证书作为启用前提
  PublicTimer         = No                                                                                是否在屏幕右上角显示倒记时信息,No为不显示,缺省为No
  SharedSyncedTimer   = Yes                                                                        是否共享同步计时器,缺省为Yes,似乎同步计时器能保证倒记时时间和游戏速度始终保持相同的倍率不乱变
  ViewObjectDuration  = 30000                                                                        用于超武/技能时,表示发射之后显示目标点周围区域多长时间
  ViewObjectRange     = 250                                                                        同上,表示现实多大范围
  RadiusCursorRadius  = 170                                                                                留在地上的范围指示圈尺寸,这里的范围指示圈将受Enum的控制,不同的Enum关联着不同的图像
  ShortcutPower       = Yes                                                                                是否允许使用右侧快捷键
  AcademyClassify     = ACT_SUPERPOWER                                                动作模式,ACT_SUPERPOWER表示发射超武,这就意味着这个SP只能被超武/技能调用
End

Enum类型码标签总共有以下这些可选:
SPECIAL_BATTLESHIP_BOMBARDMENT
SUPW_SPECIAL_NEUTRON_MISSILE
LAZR_SPECIAL_PARTICLE_UPLINK_CANNON
SUPR_SPECIAL_CRUISE_MISSILE
AIRF_SPECIAL_CARPET_BOMB
SLTH_SPECIAL_GPS_SCRAMBLER
INFA_SPECIAL_PARADROP_AMERICA
AIRF_SPECIAL_SPECTRE_GUNSHIP
AIRF_SPECIAL_A10_THUNDERBOLT_STRIKE
NUKE_SPECIAL_NEUTRON_MISSILE
NUKE_SPECIAL_CLUSTER_MINES
AIRF_SPECIAL_DAISY_CUTTER
SUPW_SPECIAL_PARTICLE_UPLINK_CANNON
SPECIAL_TANK_PARADROP
EARLY_SPECIAL_REPAIR_VEHICLES
SPECIAL_COMMUNICATIONS_DOWNLOAD
EARLY_SPECIAL_FRENZY
EARLY_SPECIAL_LEAFLET_DROP
SPECIAL_LEAFLET_DROP
EARLY_SPECIAL_CHINA_CARPET_BOMB
SPECIAL_CHINA_CARPET_BOMB
SPECIAL_SNEAK_ATTACK
SPECIAL_FRENZY
SPECIAL_GPS_SCRAMBLER
SPECIAL_SPECTRE_GUNSHIP
SPECIAL_LAUNCH_BAIKONUR_ROCKET
SPECIAL_CLEANUP_AREA
SPECIAL_CIA_INTELLIGENCE
SPECIAL_CHANGE_BATTLE_PLANS
SPECIAL_CASH_BOUNTY
SPECIAL_PARTICLE_UPLINK_CANNON
SPECIAL_REPAIR_VEHICLES
SPECIAL_BOOBY_TRAP
SPECIAL_DISGUISE_AS_VEHICLE
SPECIAL_SPY_DRONE
SPECIAL_RADAR_VAN_SCAN
SPECIAL_INFANTRY_CAPTURE_BUILDING
SPECIAL_BLACKLOTUS_STEAL_CASH_HACK
SPECIAL_BLACKLOTUS_DISABLE_VEHICLE_HACK
SPECIAL_BLACKLOTUS_CAPTURE_BUILDING
SPECIAL_TANKHUNTER_TNT_ATTACK
SPECIAL_HACKER_DISABLE_BUILDING
SPECIAL_HELIX_NAPALM_BOMB
SPECIAL_TIMED_CHARGES
SPECIAL_REMOTE_CHARGES
SPECIAL_MISSILE_DEFENDER_LASER_GUIDED_MISSILES
SPECIAL_ARTILLERY_BARRAGE
SPECIAL_DETONATE_DIRTY_NUKE
SPECIAL_A10_THUNDERBOLT_STRIKE
SPECIAL_CRATE_DROP
SPECIAL_DEMORALIZE_OBSOLETE
SPECIAL_SCUD_STORM
SPECIAL_ANTHRAX_BOMB
SPECIAL_BLACK_MARKET_NUKE
SPECIAL_AMBUSH
SPECIAL_TERROR_CELL
SPECIAL_DEFECTOR
SPECIAL_SPY_SATELLITE
SPECIAL_NEUTRON_MISSILE
SPECIAL_CASH_HACK
SPECIAL_NAPALM_STRIKE
SPECIAL_EMP_PULSE
SPECIAL_CLUSTER_MINES
SPECIAL_CARPET_BOMB
SPECIAL_PARADROP_AMERICA
SPECIAL_DAISY_CUTTER
SPECIAL_INVALID
这些标签我没有一个一个地去测试,但是在实际使用时可以发现,这些标签可以反复地被不同的超武使用,也就是说,不同的超武可以使用相同的标签,而它们都能发挥正常作用。这就证明了这些类型码实际上仅仅只是一个普通的标签而已,本身并没有任何特殊含义,所以不需要去看它的字面意思,随便使用就是了。
只不过在使用时要稍加注意,有一少部分类型码带有特殊作用,例如几种核弹、离子炮、生化死雨的类型码标签,如果使用了这些标签的SP被某种超武调用,那么在SP倒记时完成(即超武就绪)时,会听到EVA报告说“XXXX is Ready”,而空降、集束地雷等标签则不会有这样的EVA报告音出现。而还有另一些标签,只能用于特殊能力,反之也有一些标签只能用于超武,乱用会导致无法施展或发射,因此还是不能过分大意。
SP在被超武调用时,还有一个更特殊的意义,那就是关联超武本身和快捷键。换句话说,快捷键到底是用来发射哪个超武,完全是通过Enum来对应的。
我自己就遇到过这样的情况:
我做了一个超武A,调用了一个SP-A来控制它倒记时,这个SP-A的类型码标签是SUPW_SPECIAL_NEUTRON_MISSILE,超武A具有快捷键。
而我又做了一个另一个超武B,调用了另一个SP-B来控制它倒记时,而SP-B的类型吗标签还是SUPW_SPECIAL_NEUTRON_MISSILE,但超武B没有快捷键。
当我在游戏里,同时得到了超武A和超武B时,我意外地发现,怎么超武A的快捷键上出现了“X2”字样,这意味着我拥有了两个超武A??不对吧,明明我只有一个超武A和一个超武B,怎么游戏平台会误认为我有两个超武A呢?
原来就是类型码标签在作怪,因为SP-B和SP-A拥有相同的类型码标签,因此在关联超武本身和快捷键时,会被游戏平台误认为SP-B实际上也是一个SP-A,于是快捷键就变成了两倍。
所以我在此郑重声明:
拥有快捷键的超武不能和其他任何超武使用相同的Enum,否则的话当两种都拥有时会出现双倍快捷键的误判断。


8、        Upgrade
这个INI用于定义升级项目的信息,并控制其类作用效力、研发时间、研发费用等属性,一个定义好的升级项目可以被很多东西调用,例如可以作为功能模块的切换条件(回忆一下第三章的升级切换模块里的TriggeredBy和ConflictsWith语句),因为升级项目最本质的作用就是用来配合升级切换模块来使单位的属性发生改变,以达到“能力提升”、“科技提升”的效果。使用格式如下:
Upgrade  [项目名称]
[项目名称]同样可以是任意字符串。
升级项目总共分为两种效用类型:
PALYER_UPGRADE:称为宏观项目,其作用效力是一个玩家下属的所有物体,例如中国的链炮科技,升级完成之后,所有使用盖特炮的单位,都会切换成威力更强的超级盖特炮。因此宏观项目的研发按键通常可以随意放置。你只需要给那些能获得能力提升的单位添加上对应的升级切换模块,用TriggeredBy和ConflictsWith语句按照你的需求调用好这个项目即可。
OBJECT_UPGRADE:称为微观项目,其作用效力只是研发它的单个物体自身,例如美国十字军坦克的无人机,升级完成之后,只有它一个人能刷出无人机,而它身边的其他十字军坦克则不会跟着他一起刷出无人机。由于微观项目的这种特性,导致它的研发按键只能放在单位自身的界面上,否则的话你将得不到任何效果,假设你把你无人机的研发按键放到美国重工的界面上去,那么点击该按键,开始研发,但研发完成之后,你的任何一个十字军坦克都刷不出任何无人机,因为研发按键放在重工的界面上,因此只对重工自身有效,但事实上重工并不能刷无人机,因此研发完成后你啥都得不到,这个升级项目相当于报废了。

Upgrade Upgrade_ChinaChainGuns                                                链炮升级,没有Type语句的项目,缺省为PLAYER_UPGRADE
  DisplayName        = UPGRADE:ChainGuns                                该升级项目的名称,需要CSF翻译。研发完成后,屏幕左上角会显示一段文字,说这项升级已经完成
  BuildTime          = 45.0                                                                研发时间,单位是秒,而不是一般习惯上的毫秒,这个要留意一下
  BuildCost          = 1500                                                                研发费用
  ButtonImage        = SSGattling                                                研发过程中,显示在操作栏右侧阵营标志框里的时钟完成度图标
  ResearchSound      = GattlingTankVoiceUpgrade                        研发完成后播放的声音
End

Upgrade Upgrade_AmericaBattleDrone                                                攻击蜂无人机
  DisplayName        = UPGRADE:BattleDrone
  Type               = OBJECT                                                        Type = OBJECT表示该项目是一个OBJECT_UPGRADE
  BuildTime          = 5.0
  BuildCost          = 300
  ButtonImage        = SABattleDrone
  ResearchSound      = BattleDroneVoiceCreate
End

特别需要注意的是,整个游戏最多只能有128项升级项目,如果做得太多,超过了128项的话,游戏就会根本无法运行,一运行立刻报错。
于是乎,升级项目是相当珍贵的东西,因为数量有限,所以在实际制作中,对于一些功能切换效果,要尽量避免使用升级切换模块的原理来制作,如果实在无法避免,那就尽量节约使用项目,正如FK3D里有很多单位使用了摩托车容器+刷物体升级模块原理,例如GI、GGI的站立坐下切换、猛犸和武直的变形部署、时空军团和时空队长的步行瞬移切换等,如果完全使用独立的升级项目的话,总共就需要12个项目,但事实上可以全部理解为RA2那样的Deploy和Unpack,因此只需要2个项目,大家共用就OK了。


9、        Weapon
这个INI用于定义武器属性,例如攻击力、攻速、瞄准时间、射程、炮口特效、落点特效等,定义好的武器可以被单位调用作为主、副、第三武器使用。使用格式如下:
Weapon  [武器名称]
[武器名称]同样可以是任意字符串。在实际调用中,如果调用失败并不会报错,仅仅会导致单位无法开火(找不到武器,你说我怎么开火?总不会叫我拿拳头去砸人家的坦克吧)。
前面在讲灰熊坦克的时候提到过武器代码的做发,这里再来个详细的介绍,旨在罗列出所有语句,好让MODER去发挥。
SAGE里的武器分为实体武器和虚体武器两种类型,所谓实体武器,是指有射弹体、看得见射弹体飞行过程的武器,例如坦克炮、导弹等等。而SAGE还有一种TS里想都不敢想的虚体武器,这种虚体武器没有射弹体,但却同样能伤害到目标,例如机枪等等。实体武器相对比较复杂,需要很多语句来定义,但正由于它有射弹体,因此可以做出很多不同的攻击效果,例如导弹的尾气流、《赤色要塞》里的4花弹、FK3D的无限弹头法等等,都必须要靠射弹体才能表现出来,这是虚体武器所不具备的功能。而虚体武器则可以理解为一种简化的武器,没有什么过多的效果,只表现武器的本质作用——“产生伤害”。

Weapon   ScorpionMissileWeapon                                                实体武器:天蝎飞弹
  PrimaryDamage = 100.0                                                                        主要攻击力的理论伤害值,实际伤害力需要根据DamageType对不同装甲类型的比率来计算
  PrimaryDamageRadius = 5.0                                                                主要攻击力的作用范围,凡是处于这个半径内的目标都将遭受100%的伤害,而没办法像RA2那样距离中心越远越衰减
  SecondaryDamage = 80.0                                                                次要攻击力的理论伤害值,和主要攻击力差不多,似乎是个额外的加成伤害
  SecondaryDamageRadius = 25.0                                                        次要攻击力的作用范围
  ScatterRadiusVsInfantry = 10.0                                                        用这个武器攻击含有INFANTRY类型标签的目标时,落点会产生最大多少点的偏差
  AttackRange = 150.0                                                                        射程上限,单位为像素,和TS的换算关系为,TS里的1格相当于SAGE里的25像素
  MinimumAttackRange = 40.0                                                                射程下限
  MinTargetPitch = -15                                                                        炮口的最小俯射角度,通常只在山上打山下时才感觉得出效果
  MaxTargetPitch = 15                                                                        炮口的最大仰射角度,通常只在山下打山上时才感觉得出效果
  DamageType = EXPLOSION                                                                伤害类型,类似于TS的“弹头”概念,主要用来计算该武器对不同装甲类型的比率
  DeathType = EXPLODED                                                                死亡类型,可以通过单位代码里的死亡方式模块和延迟死亡模块来决定被这个武器杀死的单位将如何死法
  WeaponSpeed = 600                                                                        射弹体出膛初速度,单位为像素/秒,似乎对带有LocoMotor语句的射弹体没有任何作用
  WeaponRecoil = 5                                                                                开火时,炮管退缩程度,前提是该单位的W3D里具有可伸缩的炮管模型块,并在外观模块中被指定为炮管
  ProjectileObject = ScorpionMissile                                                射弹体为哪个物体,前面说过,可以把一些邪恶的物体作为射弹体发射出去撞别人
  ProjectileExhaust           = MissileExhaust                                        射弹体在飞行过程中拖拽的尾气流为哪个粒子系统
  VeterancyProjectileExhaust  = HEROIC HeroicMissileExhaust        开火者达到王牌级别时,发射出来的射弹体在飞行过程中拖拽的尾气流
  FireFX                      = FX_BuggyMissileIgnition                炮口FX特效,可以调用烟雾粒子系统、震动、闪光等FX来模拟开炮效果
  FireOCL                     = OCL_NormalCartridge                开火时,在炮口上刷出什么东西,我用这个原来来做滑膛炮退弹壳的效果,每开一炮就蹦出一个弹壳
  ProjectileDetonationFX = WeaponFX_RocketBuggyMissileDetonation        射弹体引爆时的FX特效
  ProjectileDetonationOCL     = OCL_GrizzlyGunVerses                                射弹体引爆时刷出什么东西,用这个原理可做出《赤色要塞》里的4花弹,这个原理的绝妙用法以后再讲
  FireSound                   = ScorpionMissileWeapon                开火时的声音
  RadiusDamageAffects = ALLIES ENEMIES NEUTRALS                        武器作用类型,对于一些特效武器,例如范围加血等,甚至要专门定义作用范围只对自己人和盟友有效
  DelayBetweenShots = 200                                                                开火间隔时间,即相邻两发炮弹发射的间隔时间,单位为毫秒
  ClipSize = 1                                                                                        一个弹夹内的炮弹数量,0表示无限量
  ClipReloadTime = 15000                                                                更换弹夹时间,单位为毫秒,0表示不需要更换弹夹(有点缺乏真实性,所以一般情况下不建议使用0)
  AutoReloadsClip = Yes                                                                        是否自动更换弹夹
  ProjectileCollidesWith = STRUCTURES                                        弹道会被什么类型的东西阻挡,换句话说,就是射弹体将撞到弹道上的什么东西,而不会像RA2那样毫无阻拦地穿过去
  WeaponBonus = PLAYER_UPGRADE DAMAGE 125%                利用升级项目可以使该武器获得特定的效力提升
End

Weapon GLAJarmenKellRifle                                                                虚体武器:贾曼卡尔狙击枪
  PrimaryDamage = 180.0
  PrimaryDamageRadius = 0.0
  AttackRange = 225.0
  DamageType = SNIPER
  DeathType = NORMAL
  ProjectileObject = NONE                                                                无射弹体!!说明这个武器是个虚体武器,但是它在SAGE里却照样能产生伤害,很神奇是吧?
  WeaponSpeed = 999999.0                                                                凡是虚体武器,出膛速度可以设置成“快得变态的级别”,999999的意思实际上就是“开火就中”或者“百发百中”
  FireFX = WeaponFX_GenericMachineGunFire
  FireSound = JarmenKellWeapon
  RadiusDamageAffects = ALLIES ENEMIES NEUTRALS
  DelayBetweenShots = 1000
  ClipSize = 0
  ClipReloadTime = 0
  WeaponBonus = PLAYER_UPGRADE DAMAGE 125%
End

对比实体武器和虚体武器的差别,我们可以发现,虚体武器的出膛速度一般设置到999999似的“无穷大”,而实体武器则很少超过1000。这是为什么呢?原来实体武器由于射弹体的飞行轨迹的特殊性而被迫存在一个不能称为BUG的BUG:
若某实体武器的出膛速度大于500,则开火者对贴身目标开火时什么东西都打不出去,开了10000炮,目标还是滴血没扣。而出膛速度越快,这个打不出任何炮弹的距离就越长,因此我将其称为“射击盲区”,经过实验发现,当出膛速度为1000时,射击盲区大约有40像素,而出膛速度为999999时,射击盲区竟然大到整个地图的对角线那么长!!(相当于说这个武器报废了)。难怪原版的所有实体武器都不敢把出膛速度做得太快,原来是有一定的道理的。从上面的例子可以看出,天蝎飞弹的出膛速度为600点,大约会产生10像素左右的射击盲区,因此EA巧妙地利用射程下限MinimumAttackRange = 40.0来避免了天蝎坦克在攻击距离自身10像素之内的贴身目标时打不出飞弹的尴尬局面,于是乎只要天蝎对贴身目标开火时,它必须先后退,等到它与目标之间的距离大于40像素时才开火,这样就必定能射出飞弹了。当然,用射程下限限制法仅仅是治标不治本的手脚办法,真正要想彻底消除射击盲区,我还是建议:
任何实体武器的出膛速度都不能大于500

10、        ParticleSystem
这个INI用于定义粒子系统的各项属性。粒子系统恐怕是3D引擎最重要的动画表现形式,所有的烟雾、流光、气浪、火焰效果都只能通过粒子系统来制作,而粒子系统是一个非常难于理解和调试的系统,相信玩过3DMAX的人应该有所体会,粒子系统有很多条语句来控制粒子的喷射属性,要调好一个粒子系统,常常需要花费相当多的时间去处理参数,因此如果你没有十足的决心,我建议你还是不要轻易自己制作新的粒子系统。
粒子系统分为好几种表现形式,虽然表面上语句看起来都差不多,但是效果相差很远,我探索了半年,也还无法完全掌握所有形式、所有语句的全部作用,因此我也没办法给出足够详细的教程,只能找几个典型来讲解一些通用语句的作用,具体到不同的形式上,只能让各位自己在体会和实践中去领悟。使用格式如下:
ParticleSystem  [粒子系统名称]
[粒子系统名称]同样可以是任意字符串。在实际调用中,如果调用失败并不会报错,仅仅会显示不出任何效果。

ParticleSystem TsingMaTrailSmoke
  Priority = WEAPON_EXPLOSION                                                显示优先度,分为几种不同的级别,游戏平台根据它来决定在不同的显示性能下,不显示哪些级别的粒子系统
  IsOneShot = No                                                                                只喷射一次??不太像,因为我试过用Yes也无法让它连续喷射
  Shader = ALPHA                                                                                渐变方式为ALPHA的意思是,将贴图按照颜色深浅来安排半透明效果,纯黑为全透明,纯白为不透明
  Type = PARTICLE                                                                                表现形式,PARTICLE表示粒子团,此外还有STREAK(条纹),不知道具体有啥区别
  ParticleName = EXSmokNew1.tga                                                粒子贴图,使每个喷射出来的粒子都变成这个贴图的形状,于是就呈现出了不同的视觉效果(没贴图的粒子是空白方块)
  AngleZ = 0.00 0.25                                                                                Z方向角度??可能是指喷射方向上的随机偏移量,前一个数字为最小值,后一个为最大值(下面语句的都是这样排布)
  AngularRateZ = -0.01 0.01                                                                Z方向角度变化率??
  AngularDamping = 0.99 0.99                                                                角度变化阻尼
  VelocityDamping = 0.99 0.98                                                                喷射速度阻尼
  Gravity = 0.01                                                                                        粒子重力,似乎会使粒子在喷射之后逐渐减速,重力越大,减速越明显,过大的重力甚至可能引起粒子倒流
  Lifetime = 60.00 60.00                                                                        粒子生存时间,粒子从喷射出来之后能持续存在多长时间,单位为帧
  SystemLifetime = 0                                                                                系统生存时间,喷射粒子的这个系统能持续存在多长时间,单位为帧,0表示只喷射出一颗粒子就消失掉
  Size = 5.00 5.00                                                                                粒子体积,即决定未贴图时粒子方块的尺寸,贴上图之后将按照这个尺寸自动拉伸图像以布满整个方块面
  StartSizeRate = 0.00 0.00                                                                初始尺寸变化率,单位为像素/帧,0表示初始时不变化,对相同的变化率来说,粒子生存时间越长,变化量就越大
  SizeRate = 3.00 3.00                                                                        尺寸变化率,似乎是指初始之后的尺寸变化率,同上,0表示始终不变
  SizeRateDamping = 0.95 0.95                                                        尺寸变化阻尼,正数表示变大,貌似负数是表示变小,正负混用则是波动闪烁
  Alpha1 = 0.00 0.00 0                                                                        半透明渐变效果,最后一个数字是粒子生存时间上的时间点,最大值不能超过粒子生存时间参数
  Alpha2 = 1.00 1.00 5                                                                        表示当粒子生存到多少时间点时,半透明效果变成什么样子
  Alpha3 = 0.00 0.00 60                                                                        最多可以定义出8阶渐变过程
  Alpha4 = 0.00 0.00 0                                                                        但超过了粒子生存时间的语句通通都无效,因此这里最多能定义到60,而你非要弄个100的话是白定义了,没有效果的
  Alpha5 = 0.00 0.00 0
  Alpha6 = 0.00 0.00 0
  Alpha7 = 0.00 0.00 0
  Alpha8 = 0.00 0.00 0
  Color1 = R:255 G:255 B:255 0                                                        染色渐变效果,和半透明渐变类似,也是用时间点来控制渐变过程,最多8阶,染色信息是用RGB色光叠加法
  Color2 = R:0 G:0 B:0 0                                                                        如果贴图本身就是彩色的,则染色后的粒子图像颜色很可能会发生变化,例如原来就是蓝色,染上黄色后会变成绿色
  Color3 = R:0 G:0 B:0 0
  Color4 = R:0 G:0 B:0 0
  Color5 = R:0 G:0 B:0 0
  Color6 = R:0 G:0 B:0 0
  Color7 = R:0 G:0 B:0 0
  Color8 = R:0 G:0 B:0 0
  ColorScale = 0.00 0.00                                                                        染色比例,不知道有啥用,难道是控制染色饱和度?
  BurstDelay = 40.00 40.00                                                                当SystemLifetime不为0时,可控制喷射粒子的间隔时间,不知道单位是毫秒还是帧
  BurstCount = 0.00 2.00                                                                        每次喷射出多少个粒子
  InitialDelay = 20.00 20.00                                                                初始化间隔,即喷射第一个粒子需要延迟多长时间
  DriftVelocity = X:0.00 Y:0.00 Z:0.00                                                速度漂移,使粒子的飞行路径发生漂移,通常用在导弹尾气流上,而磁暴束的“漂移”则更加厉害
  VelocityType = OUTWARD                                                                速度类型,OUTWARD表示向外,相对还有SPHERICAL(球体辐射)、HEMISPHERICAL(半球辐射)、ORTHO(跳动)
  VelOutward = 0.00 0.00                                                                        当速度类型为OUTWARD时的匹配语句,控制球体辐射的属性,具体是什么样的属性我自己都不知道
  VelOutwardOther = 0.00 0.00
  VolumeType = SPHERE                                                                        体积类型,SPHERE(球体)、POINT(点)、CYLINDER(圆柱)、LINE(线条),不同的体积有不同的表现效果
  VolSphereRadius = 4.00                                                                        当体积类型为球体时的匹配语句,控制球体的半径
  IsHollow = No                                                                                        是否将所喷射出来的粒子围绕或组合成一定的形状,这个形状就是上面的体积类型
  IsGroundAligned = No                                                                        粒子面是否平行于地面,No的话表示与地面垂直,Yes为平行
  IsEmitAboveGroundOnly = No                                                        是否只在地面以上喷射
  IsParticleUpTowardsEmitter = No                                                        粒子喷射方向是否与发射点轴向一致。No表示与世界坐标一致,即发射点转向但粒子喷射不变向,反之则随发射点而变向
  WindMotion = Unused                                                                        风力影响,Unused表示不使用,我似乎还从来没见过启动了风力影响的粒子系统
  WindAngleChangeMin = 0.149924                                                如果使用了风力影响,那么这几个句子就用来模拟风吹粒子的效果,具体是啥效果只有等你们自己去体会了
  WindAngleChangeMax = 0.449946
  WindPingPongStartAngleMin = 0.000000
  WindPingPongStartAngleMax = 0.785398
  WindPingPongEndAngleMin = 5.497787
  WindPingPongEndAngleMax = 6.283185
End

11、        DeathType标签详解
前面提到,每个武器代码都有一个DeathType语句,这里来详细解释一下它的参数是如何产生作用的。
DeathType的含义是死亡方式,任何物体都可以以多种不同的死亡方式来表现死亡动作,这完全取决于武器的DeathType参数
比如用机枪杀死了步兵,步兵是直接倒下,而用炮弹杀死了步兵,步兵将会被爆飞起来。需要注意的是,这些死亡动作的产生是由被杀单位的ShowDeathBehavior、CreateObjectDie、FXListDie等等和死亡动作相关的模块来控制的,而DeathType仅仅起个标签的作用,用来给死亡动作模块判断,在哪些死亡方式下被执行,实际上你也可以故意编写出有冲突的死亡模块,既多条死亡模块使用相同的DeathTypes标签,这样的话同一个物体在死亡时能呈现出多种动作来(例如一个步兵被杀死后分出4身,一个直接倒地,一个爆飞,一个着火,一个融化,是不是有点恶搞?)

例如:
  Behavior = SlowDeathBehavior ModuleTag_Death01
    DeathTypes          = NONE +BURNED
    DestructionDelay     = 0
    FX                  = INITIAL FX_DieByFireChina
    OCL                 = INITIAL OCL_FlamingInfantry
  End

  Behavior = SlowDeathBehavior ModuleTag_ Death02
    DeathTypes = ALL -CRUSHED -SPLATTED
    ProbabilityModifier = 25
    DestructionDelay = 4000
    DestructionDelayVariance = 1000
    OCL = FINAL    OCL_MMBTNKDebris
    FX  = FINAL    FX_HeavyTankExplodeFinal
  End
第一段代码表示,当该单位在被某种DeathType = BURNED的武器杀死时,会执行该模块。第二段代码表示只要是被DeathType = CRUSHED和SPLATTED以外的其他的武器杀死,就执行该模块。其中DeathTypes语句调用着一些标签,NONE表示无,每用加号添加一个标签表示增加一个可执行的情况,反之也有用ALL表示任意,每用减号添加一个标签表示扣除一个可执行的情况,两者正好是互反逻辑。

关于DeathType的标签一共有以下这些:
前4种可能是特殊标签,但目前尚不能确定是否的确是系统底层方式,因此最好不要随意乱用
DETONATED                                引爆,用于射弹体撞击地面或目标后引发伤害,99%是个特效类型
CRUSHED                                        冲击,常用于坦克撞击步兵或围墙,可能是个特效类型
SPLATTED                                        坠毁,没有被任何武器使用,但当单位从高空跌落而摔死时,自动使用这个标签
EXPLODED                                        爆炸,常用于炮弹、导弹、炸弹等冲击力较大的伤害,和士兵骨骼动作里的EXPLODED_FLAILING关联,乱改会成大麻烦

后面的都是一般标签,有些标签被一些原版武器使用了,因此可以随意改作它用。下面这5种比较常见。
NORMAL                                        普通,常用于枪弹等冲击力较轻的伤害
BURNED                                        燃烧,常用于火焰或高温武器,凡是以这种方式死亡的步兵将全身着火然后到处乱跑
POISONED                                        低毒,只被绿色毒素使用,被我拿给辐射和腐地使用,凡是以这种方式死亡的步兵将会融化(像RA2那样)
POISONED_BETA                        中毒,只被蓝色毒素使用,被我拿给病毒狙击枪使用,凡是以这种方式死亡的单位将OCL出能缓慢飘动的病毒粒子
POISONED_GAMMA                        高毒,只被紫色毒素使用,被我拿给基因突变使用,凡是以这种方式死亡的单位将OCL出核元素箱子,被拾取后就产生核元素

这4种不太常见,可以试着改一改看看效果。
SUICIDED                                        自杀,通常是先用这个武器开火,只将自己杀死,然后利用FireWeaponWhenDeath来释放出带有真正伤害性的爆炸武器去伤害敌人
LASERED                                        反制,常用于拦截导弹的激光,被我拿给电性武器使用,凡是以这种方式死亡的单位将触电烧焦
FLOODED                                        淹没,只在任务里被洪水使用过,被我拿给元素变异使用,凡是以这种方式死亡的单位将OCL出水元素箱子,被拾取后就产生水元素
TOPPLED                                        倒塌,被倒塌的建筑或高塔砸死时自动使用这个标签

还有7种没有被使用的隐藏类型,可供MODER自己随意定义来使用
EXTRA_2        EXTRA_3        EXTRA_4        EXTRA_5        EXTRA_6        EXTRA_7        EXTRA_8

12、        KindOf标签详解
由于SAGE引擎的平台习惯性地将所有物体统一视为OBJECT,而不像RA2那样将分为建筑、车辆、步兵、飞行器这么4大类型来注册新单位,因此KindOf将是SAGE类平台唯一能够用来区分物体类别的方法。
任何一个OBJECT的KindOf都有很多个标签,总共分为3大类:
(1) 基本标签,没有特殊作用,只是个标签而已,可以随意胡乱使用,通常用于特效、特殊功能或特殊武器判断有效对象或无效对象的依据
(2) 触发标签,具备基本标签的作用,还和触发编辑器的触发目标判定相关联,可以随意使用,但不能胡乱使用(但如果不做AI的话,当我白说了)
(3) 功能标签,具备基本标签的作应,还具有一些特殊的平台底层功能,可以让这个单位获得特殊的细节功能,随意使用的话会导致一些莫名其妙的怪异现象
需要说明的是,极少数标签带有一些不太明显的平台底层功能或特性,例如LOCOMOTOR为地面移动型的INFANTRY可以相互穿越同类单位的身体,而VEHICLE就必须绕开,又如INFANTRY可以在运输单位里对外面的任意目标开火,而VEHICLE则只能对外面的空地开火……,因此当INFANTRY和VEHICLE共存时,将产生严重的后果,这会导致一些小BUG,不过基本上是可以修复的,因为这些标签只是用来分类的而已,但大多数没有实际意义,只是一个分类标签而已,是否具有其含义的功能,实际上完全由功能模块来决定,好比你给战神坦克加上TRANSPORT标签,但却不给它添加容器模块,它就不能装人,而反之你只给它添加容器模块,却不给它添加TRANSPORT标签,它却居然能装人,由此说明,这些标签都没有实际意义,所以它们的名称也不重要。

以下这些是基本标签:
BLAST_CRATER                                                爆炸中心,被爆炸产生器占用(SYSTEM.INI)
BOOBY_TRAP                                                诡雷,反抗军的技能相关OBJECT
AIRCRAFT_CARRIER                                        航母,被原版航母占用(原版航母是个建筑!!)
TECH_BASE_DEFENSE                                科技防御塔,被中立炮兵阵地占用
CONSERVATIVE_BUILDING                        保守型建筑,被中立科技建筑占用
DEMOTRAP                                                        爆破筒,被GLA爆破筒占用
ARMOR_SALVAGER                                        捡垃圾者,似乎带上这个标签的单位捡到的垃圾都是升级装甲
WEAPON_SALVAGER                                        捡垃圾者,似乎带上这个标签的单位捡到的垃圾都是升级武器
SALVAGER                                                        捡垃圾者,一般的捡垃圾者捡到的垃圾多种多样,每次按几率出现不同的结果
HERO                                                                英雄,带上此标签的单位在雷达上显示的标志不是一般的点,而是闪烁的十字架
DISGUISER                                                        伪装者
SUPPLY_SOURCE                                        资源站
HULK                                                                残骸,通常给坦克底盘的残骸使用,带上了这个标签的单位死亡时,EVA也不会报告UNITLOSE
BOAT                                                                战舰
PARACHUTE                                                        降落伞
BALLISTIC_MISSILE                                        巡航导弹,通常给体积比较大,能被所有对空火力拦截的射弹体用,例如战斧导弹
SMALL_MISSILE                                                小型导弹,通常用于小体积的普通导弹,例如坦克猎人的单兵导弹
DRONE                                                                OP,被原版的3种蜂型机占用
TECH_BUILDING                                                中立科技建筑
DEFENSIVE_WALL                                        围墙,被原版所有围墙、路障、栅栏占用
PORTABLE_STRUCTURE                                便携式建筑,被炎黄和蜗牛的几种炮塔占用
MINE                                                                地雷,被原版的地雷、诡雷等单位占用
CRATE                                                                箱子,凡是带上该标签的单位,可以主动去接触目标使目标获得一定的效果,例如FK3D的心灵控制弹头
HEAL_PAD                                                        直升机平台,通常给能生产悬浮型飞机的机场使用,自然也就需要HeliPark02%d关节点支持
REPAIR_PAD                                                        维修厂,需要RepairDockUpdate功能模块支持
PROJECTILE                                                        普通射弹体,一般是给坦克炮使用
BRIDGE_TOWER                                                桥头堡,肯定是指用特定方式施加给桥头堡一个动作,就可以将断裂的桥梁修复,不过ZH的桥梁似乎没断过
LANDMARK_BRIDGE                                        贴地桥梁
BRIDGE                                                                架空桥梁标
TRANSPORT                                                        运输者
COMMANDCENTER                                        指挥中心,带上这个标签的物体在开场时会被默认选中,同时当玩家失去了所有这种物体时,杀人也不加经验值了
HARVESTER                                                        矿车,似乎带上这个标签的物体会自动去挖矿,当然,需要SupplyTruckAIUpdate功能模块的支持
DOZER                                                                推土机,带上这个标签的物体将获得把地基建造成建筑的能力以及修复受损建筑的能力,当然需要DozerAIUpdate功能模块的支持
HUGE_VEHICLE                                                大型物体,被炎黄、帝王等大体积的坦克占用
AIRCRAFT                                                        空军,被所有飞机占用
VEHICLE                                                        载具,被所有车辆、坦克、飞机等机械化部队占用
INFANTRY                                                        士兵,被所有步兵和英雄占用,特别注意,带上了这个标签的物体可以进入没有任何限制的容积体(包括驻扎体)并能向外面的目标开火
STRUCTURE                                                        建筑,被所有建筑占用,特别注意带上了这个标签的物体将阻挡其他单位的视线、阻挡物体的移动路径
SHRUBBERY                                                        树木
OBSTACLE                                                        障碍物,被围墙和其他一些栅栏占用
CASH_GENERATOR                                        资金产生器,被矿厂和油井占用
MONEY_HACKER                                        偷钱者,似乎被黑客和黑莲花占用
CLIFF_JUMPER                                                飞檐走壁者,被摩托车占用

触发标签,用于地图编辑器里的触发判断,可以像RA2那样,让小队攻击某一类属性的目标(如工厂类建筑)
FS_AIRFIELD                                                机场标签
FS_WARFACTORY                                        重工标签
FS_BARRACKS                                                兵营标签
FS_ADVANCED_TECH                                实验室标签
FS_INTERNET_CENTER                                股市标签
FS_FAKE                                                        假物体标签
FS_STRATEGY_CENTER                                战略中心标签
FS_SUPPLY_CENTER                                矿厂标签
FS_BLACK_MARKET                                        黑市标签
FS_SUPERWEAPON                                        超武标签
FS_SUPPLY_DROPZONE                                补给站标签
FS_TECHNOLOGY                                        高级物体标签,被部分超武建筑、实验室、机场占用
FS_BASE_DEFENSE                                        防御塔标签,通常给防御塔使用
FS_FACTORY                                                工厂类建筑标签,凡是能生产单位的似乎都有这个标签
FS_POWER                                                        电力类建筑标签,被原版的所有电厂占用

特殊功能标签,带上这些标签的物体能获得一些特殊的平台底层功能,大多数功能还需要相关Behavior功能模块的支持才能发挥实际作用,但这些标签最好不要随意乱用,像POWERED、SELECTABLE之类可以直接发挥作用且效果明显的标签,乱用小心带来意外的混乱
DONT_AUTO_CRUSH_INFANTRY                                用于无武装的单位,在遭遇敌人步兵攻击时不自动进行撞击
IGNORES_SELECT_ALL                                                不能双击类选
INERT                                                                                不活动的,被很多射弹体使用,尤其是光束激光
CAN_CAST_REFLECTIONS                                        可投射阴影,根据3D光影的投射逻辑,该单位身上可投射出其他物体的阴影
STICK_TO_TERRAIN_SLOPE                                        贴合在斜坡面上,即该物体在斜坡上将随斜坡的角度倾斜,常常可看到斜在悬崖上的碉堡就是这样来的
CAN_ATTACK                                                                可攻击,有这个标签的单位才能对地面及其他目标开火,否则将没有攻击指针
IMMOBILE                                                                        稳定的,似乎是给建筑使用的,确保该物体不管遇到什么情况,哪怕是磁电波的吸引也永远不会移动半步
SELECTABLE                                                                可被玩家选中
REVEAL_TO_ALL                                                        能被所有人看到,原本应该给超武使用,但后来被更加微观的ShroudRevealToAllRange语句取代
CANNOT_BUILD_NEAR_SUPPLIES                        建立是不能靠资源站过于太近,通常给矿厂使用,GAMEDATA.INI里的SupplyBuildBorder语句控制着最小距离
SPAWNS_ARE_THE_WEAPONS                                卵生出来的OP是武器,大概是用于类似思金人蜂巢的单位
SHOW_PORTRAIT_WHEN_CONTROLLED                接受操控时显示头像??难道哪个单位又没有被显示头像呢?
IMMUNE_TO_CAPTURE                                                不能被捕获,对外部占领免疫,不知道是否能对进入式占领免疫
CAPTURABLE                                                                可被捕获,与上面相反
GARRISONABLE_UNTIL_DESTROYED                        重伤后依旧提供驻守能力直到被摧毁,被中国碉堡占用
SUPPLY_SOURCE_ON_PREVIEW                                鼠标悬停时可看到剩余资源量(前提是使用该标签的建筑必须具备资源站的关键功能模块),被资源站占用
CAN_SEE_THROUGH_STRUCTURE                        可看穿建筑,不知道有啥效果
ATTACK_NEEDS_LINE_OF_SIGHT                                开火时需要直线视野,也就是当目标处于大体积障碍背后时,开火者不能像RA2那样直接开炮,只能先饶过障碍再开炮
PRODUCED_AT_HELIPAD                                                从直升机平台上生产下线,需要机场建筑W3D模型里的HeliPark02%d关节点支持
POWERED                                                                        需要电力才能发挥作用,通常被耗能防御塔、超武建筑等占用
AUTO_RALLYPOINT                                                        能够由玩家来设置集合点,当然需要配合集合点按键才能完成设置
FORCEATTACKABLE                                                        不需要使用CTRL就能攻击一切目标,通常被空降运输机占用
ALWAYS_SELECTABLE                                                永远能被选取??
IGNORED_IN_GUI                                                        在界面上被忽略,通常用于一次性使用且不被玩家操控的召唤单位
MOB_NEXUS                                                                群体关联者标签,被暴民占用,实际上暴民只是一个带有此标签的无形体,而里面的成员是这个无形体的OP
CAN_BE_REPULSED                                                        能被再次暂停??
PARACHUTABLE                                                                可被降落伞空降
CAN_RAPPEL                                                                可被绳索空降
NO_HEAL_ICON                                                                不显示治疗图标,貌似是指该单位在自动加血、接受修复等过程中,不会显示扳手、医疗的动画图标
SCORE_DESTROY                                                        被破坏时,对方能获得其对应上层建筑的分数,被GLA地洞占用
SCORE_CREATE                                                                分数创造者标签,被GLA所有建筑占用,和上句有关联,大概只干掉GLA的建筑是得不到分的,还必须得干掉地洞才能得分
SCORE                                                                                被破坏时,对方能获得使用该标签单位自身分数,这是给一般物体使用的标签
REBUILD_HOLE                                                                被毁时能产生地洞,需要RebuildHoleBehavior功能模块的支持
MP_COUNT_FOR_VICTORY                                        军用物品,用于判断胜负(是否杀完了敌方所有特定类型的物品)
CLEANUP_HAZARD                                                        拆弹者,被原版推土机占用
UNATTACKABLE                                                                不能被任何东西直接攻击,但是会被误伤,因此不是真正的无敌
ALWAYS_VISIBLE                                                                永远可见??
CLEARED_BY_BUILD                                                        通过建造来清除??
EMP_HARDENED                                                        对EMP效果免疫,被鬼魅炮艇机和空降运输机占用
CANNOT_RETALIATE                                                        被攻击时不主动还击,被原版3个英雄占用,因为原版英雄是隐形的,但攻击时会现形,所以挨打后还击=暴露目标
NO_SELECT                                                                        不选择??被地道网络系统占用
NO_COLLIDE                                                                不被任何物体阻挡其移动路径,通常用于某些可穿透围墙和建筑的射弹体
NO_GARRISON                                                                不能驻守??难道是给步兵使用,使之不具有驻守能力?
PRELOAD                                                                        预加载,貌似是指在载入地图时就预先载入该单位的代码,以免临时出现了再加载,导致游戏突然卡一下
STEALTH_GARRISON                                                隐形驻守??难道被驻守后会隐形?似乎还需要隐形功能模块支持吧?
LINEBUILD                                                                        自动填补中间连接,被各种围墙占用,似乎能做出类似于RA2里的围墙连接功能
WALK_ON_TOP_OF_WALL                                        在围墙顶上行走??
WAVE_EFFECT                                                                波动效果??好像和三峡大坝倾泄而出的洪水有点关系
WAVEGUIDE                                                                        波导?

这几个查不出来被什么东西用了,所以我不便于翻译,如果它们真的是空闲标签的话,那就可以随意使用他们
IGNORE_DOCKING_BONES
LOW_OVERLAPPABLE
AIRCRAFT_PATH_AROUND
DRAWABLE_ONLY
CLICK_THROUGH
REVEALS_ENEMY_PATHS
REJECT_UNMANNED        
OPTIMIZED_TREE
PROP

13、        Status标签详解
Status表示某个物体或小队的状态,触发编辑器里用这个方法来判断该物体或小队当前处于什么状态,例如正在开火、隐形中等等,因此大多数状态跟物体的动作密切相关,物体的动作就决定了它将呈现出什么样的状态,但这里要强调的是,状态并非只能靠物体自身的动作来表现,而是可以靠别人来强加,因此ZH里有一个比较重要的用法,就是用武器将某个特定状态标签贴到目标身上,使目标被迫呈现出这个标签所标示的状态。
      当一个武器的DamageType = STATUS时,用这个武器攻击目标,将会使目标被迫呈现出某种状态,而这个武器的PrimaryDamage参数将决定目标每遭受一次攻击会呈现多长时间的状态,单位为毫秒,那么到底的哪种状态,就取决于这个语句:DamageStatusType = XXXX,这里的XXXX就是Status列表里的其中一个标签。
例如复仇者的锁定光线:
Weapon AvengerTargetDesignator
  PrimaryDamage       = 200.0                                                                        每遭受一次锁定光线的攻击,状态将保持200毫秒
  PrimaryDamageRadius = 0.0                                                                        使用0点的范围伤害表示一次只能锁定一个目标
  AttackRange         = 200.0
  DamageType          = STATUS                                                                伤害类型为“打状态标签”,也是这个武器的关键语句
  DamageStatusType    = FAERIE_FIRE                                                        标签对应什么状态,也就是说被锁定光线攻击的单位将被迫呈现出什么样的状态
  WeaponSpeed         = 999999.0
  DelayBetweenShots   = 200                                                                        一般来说这个参数就不应该大于PrimaryDamage参数,否则将出现间隙性的呈现状态
  ClipSize            = 0
  ClipReloadTime      = 0
  LaserName           = AvengerTargetingLaserBeam
  LaserBoneName       = TurretFX03
  FireFX              = WeaponFX_AvengerTargetDesignator
  FireSound           = AvengerPaintWeaponLoop
  FireSoundLoopTime   = 120
End

Status标签也可以作为单位死亡动作的辅助判断条件,通常可以在死亡模块里添加RequiredStatus或ExemptStatus语句来判断该单位在什么状态下执行什么样的死亡动作。
例如巴库帝利安特有的神族基地建设规则:
  Behavior = CreateObjectDie ModuleTag_Death03A
    CreationList   = OCL_SmallStructureDebris                                                如果该单位没有处于STATUS_RIDER7状态,则执行该死亡动作
    ExemptStatus   = STATUS_RIDER7
  End

  Behavior = CreateObjectDie ModuleTag_Death03B                                        如果该单位处于STATUS_RIDER7状态,并且被一个DeathTypes = SUICIDED的武器杀死时执行该死亡动作
    DeathTypes     = NONE +SUICIDED
    CreationList   = OCL_BALIST_MakeUp
    RequiredStatus = STATUS_RIDER7
  End

全部的标签如下,除了FAERIE_FIRE比较特殊外,其他大多数标签都没有实际意义,可以随意使用,但考虑到有些状态是伴随物体的自身动作而呈现出来的,如果被被强制呈现,则可能会使该物体自动产生相应的动作,因此最好不要胡乱使用这些标签,小心动作混乱,于是一个恶搞的构思便诞生了——强制给建筑贴上一个SOLD标签后,该建筑可能会无缘无故地自动卖掉。
之所以说FAERIE_FIRE比较特殊,就在于它的标签叫FAERIE_FIRE,但还关联着一个WeaponBonus——TARGET_FAERIE_FIRE,因此这个标签是最不能随意使用的标签,除非你下决心彻底废掉TARGET_FAERIE_FIRE功能
FAERIE_FIRE                                                                                                幻觉攻击,不知道是不是该这样翻译……
STATUS_RIDER8                                                                                                内含8种不同乘员时,原版的摩托车用过这些标签
STATUS_RIDER7
STATUS_RIDER6
STATUS_RIDER5
STATUS_RIDER4
STATUS_RIDER3
STATUS_RIDER2
STATUS_RIDER1
DEPLOYED                                                                                                        部署
CAN_ATTACK                                                                                                可攻击敌人
DISGUISED                                                                                                        伪装中
BOOBY_TRAPPED                                                                                        落入陷阱中
REASSIGN_PARKING                                                                                       
KILLING_SELF                                                                                                自杀时
DECK_HEIGHT_OFFSET                                                                                
IS_CARBOMB                                                                                                被恐怖分子转变成了汽车炸弹时
IGNORING_STEALTH                                                                                        显形时
NO_ATTACK_FROM_AI                                                                                没有被电脑攻击时
IS_AIMING_WEAPON                                                                                        追踪武器??
USING_ABILITY                                                                                                施展特殊能力时
IS_ATTACKING                                                                                                正在攻击时,包括开火、开火间歇、换弹等全套攻击动作
MASKED                                                                                                                戴上了面具??难道是指美军的防护服?
RECONSTRUCTING                                                                                        重建上层建筑时,估计是GLA建筑被毁后留下可自动恢复成型的地动
UNDERGOING_REPAIR                                                                                正在接受维修时
SOLD                                                                                                                被拆除掉
CAN_STEALTH                                                                                                可隐形
DETECTED                                                                                                        被探测到
STEALTHED                                                                                                        隐形时
IS_BRAKING
IS_FIRING_WEAPON                                                                                        开火时
WETAFLAME
HIJACKED                                                                                                        被劫持犯捕获后
REPULSOR
PARACHUTING                                                                                                空降中,且尚未落地时
AIRBORNE_TARGET                                                                                        对空攻击时
NO_ATTACK                                                                                                        不能开火
NO_COLLISIONS                                                                                                移动时可穿越一切
UNSELECTABLE                                                                                                不能被玩家选中
UNDER_CONSTRUCTION                                                                                正在建造过程中
DESTROYED                                                                                                        被摧毁后

14、        RadiusCursorType详解
前面在讲解CommandButton.ini时提到一些特殊功能的按钮可以对目标点或目标物体使用鼠标指针,例如Command = GUARD、FIRE_WEAPON、SPECIAL_POWER等,当Option里含有NEED_TARGET_POS、NEED_TARGET_ENEMY_OBJECT、NEED_TARGET_NEUTRAL_OBJECT、NEED_TARGET_ALLY_OBJECT中至少任意一种时,该按钮就成为了一个可对特定目标或区域点执行特定动作的功能键,鼠标指针也就在你往特定目标身上或特定区域的地面上悬停或电击时被显示,这些按钮可以使用两种指针,一种是CUR文件,即WINDOWS基本鼠标指针格式,另一种是ZH的特色——范围圈,通常情况下Command = SPECIAL_POWER的按钮都会使用范围圈,用它来指定该超武的有效作用范围,而设置其圈的大小是在SpecialPower里定义RadiusCursorRadius的参数,100表示TGA的原样大小,大于100表示放大到百分之多少,小于100则缩小到百分之多少

例如空投传单:
CommandButton Command_LeafletDrop
  Command           = SPECIAL_POWER                                                这种Command允许该按钮使用鼠标指针
  SpecialPower      = SuperweaponLeafletDrop
  Options           = NEED_SPECIAL_POWER_SCIENCE NEED_TARGET_POS CONTEXTMODE_COMMAND
  TextLabel         = CONTROLBAReafletDrop
  ButtonImage       = SALeaflet
  ButtonBorderType  = ACTION
  DescriptLabel     = CONTROLBAR:TooltipLeafletDrop
  RadiusCursorType  = DAISYCUTTER                                                        使用DAISYCUTTER来作为范围圈图像
  InvalidCursorName = GenericInvalid
End

SpecialPower SuperweaponLeafletDrop
  Enum                = SPECIAL_LEAFLET_DROP
  ReloadTime          = 300000
  RequiredScience     = SCIENCE_LeafletDrop
  PublicTimer         = No
  SharedSyncedTimer   = Yes
  ViewObjectDuration  = 30000
  ViewObjectRange     = 250
  RadiusCursorRadius  = 110                                                                                实际显示尺寸是TGA原样尺寸的1.1倍
  ShortcutPower       = Yes
  AcademyClassify     = ACT_SUPERPOWER
End

本例使用了一个名为DAISYCUTTER的范围圈,它的图像是在InGameUI.ini里定义的

  DaisyCutterRadiusCursor
    Texture        = SCCFuelAirBomb_USA                                                使用哪个TGA/DDS图像来显示范围圈
    Style          = SHADOW_ALPHA_DECAL                                        风格=类似于半透明阴影贴花的样式
    OpacityMin     = 50%                                                                                最小透明度=50%
    OpacityMax     = 100%                                                                                最大透明度=100%
    OpacityThrobTime  = 1000                                                                        闪烁周期=1秒/次,如果透明度的最大值和最小值不等,那么就可以看到范围圈在不停地闪烁
    Color          = R:255 G:0 B:0 A:255                                                        染色颜色为RGB(255,0,0)的正红色,A表示饱和度,最大255
    OnlyVisibleToOwningPlayer = Yes                                                                只对发射方玩家显示
  End

需要注意的是大多数范围圈类型自动和InGameUI.ini里定义的范围圈图像对应,比如NUCLEARMISSILE将自动关联到NuclearMissileRadiusCursor。这是游戏平台内定的底层对应规则,不能添加新的范围圈类型,也无法修改对应规则。以下是所有范围圈类型和范围圈图像的对应:
DAISYCUTTER                                        DaisyCutterRadiusCursor
NAPALMSTRIKE                                        NapalmStrikeRadiusCursor
PARADROP                                                ParadropRadiusCursor
CLUSTERMINES                                        ClusterMinesRadiusCursor
EMPPULSE                                                EMPPulseRadiusCursor
A10STRIKE                                                A10StrikeRadiusCursor
SPECTREGUNSHIP                                SpectreGunshipRadiusCursor
CARPETBOMB                                        CarpetBombRadiusCursor
NUCLEARMISSILE                                NuclearMissileRadiusCursor
SCUDSTORM                                        ScudStormRadiusCursor
ARTILLERYBARRAGE                        ArtilleryRadiusCursor
FRENZY                                                        FrenzyRadiusCursor
SPYSATELLITE                                        SpySatelliteRadiusCursor
SPYDRONE                                                SpyDroneRadiusCursor
RADAR                                                        RadarRadiusCursor
AMBUSH                                                AmbushRadiusCursor
EMERGENCY_REPAIR                        EmergencyRepairRadiusCursor
ANTHRAXBOMB                                        AnthraxBombRadiusCursor
GUARD_AREA                                        GuardAreaRadiusCursor
CLEARMINES                                        ClearMinesRadiusCursor
ATTACK_SCATTER_AREA                        AttackScatterAreaRadiusCursor
AMBULANCE                                                AmbulanceRadiusCursor
HELIX_NAPALM_BOMB                        HelixNapalmBombRadiusCursor
PARTICLECANNON                                ParticleCannonRadiusCursor

还有一些是找不到对应范围圈类型的范围圈图像,不知道有什么作用,而正是由于找不到对应范围圈类型,因此也无法被我们改作它用
SuperweaponScatterAreaRadiusCursor
OffensiveSpecialPowerRadiusCursor
FriendlySpecialPowerRadiusCursor
AttackContinueAreaRadiusCursor
AttackDamageAreaRadiusCursor
                        
                        由此可见,ZH只提供了24种范围圈给我们使用,并且不能添加新的,因此必须要珍惜着使用。
 楼主| 发表于 2010-11-29 10:55:06 | 显示全部楼层
第五章        游戏外包装
      底层规则和单位代码的制作基本就算告一段落了,现在我们还剩下一个重要的事情要做,那就是要给自己的游戏做出一副足够受看的外包装,否则的话,难道你想让玩家去玩一个只有概念和规则,没有具体形状的骨架式游戏?
游戏外包装的工作量似乎是整个游戏里最大的一部分,分为模型代码、音效编辑、图像编辑、3D建模等等,那么我们就依次来探索这些东西的做法。

1、模型代码。SAGE和TS一样,也有ART代码,通过对一些W3D模型的调用来表现一个物体的外观形状,但和TS不同的是,SAGE没有专门的ART.INI,而是把ART代码作为单位代码的一个模块来对待,并保存在这个单位的代码中,因此它的使用格式和第三章中提到过的所有功能模块相同,也是一个函数,拥有函数名,并占用一个模块编号。
SAGE里的外观模块函数有很多种,不同的函数带有一定的底层功能,虽然都能调用W3D来表现物体外观,但细节上略有差异,这个在遇到的时候再略加点评。

      纵观外观模块的定义法,不难看出两个规律:一是通过不同的条件标签(ConditionState)来区分一个物体在不同状态下的外观,二是通过不同的过渡标签来创建物体在两个状态之间变形时的过程动画。因此在举例之前有必要先讲解一状态标签和过渡过程的作用原理。

      条件标签的作用是用来标志一个物体在不同的条件下具有什么什么样的特征,而这个特征可以是第三章里提到过的武器系统、装甲系统、运动模式等,也可以是本章里将要介绍的外观摸样。因此可以这样来理解,一个单位在游戏中会受到自身动作或外界环境的影响(例如空闲动作、移动动作、开火动作、白天、夜晚、温和、雪地、健康、受伤、获得升级等等)以至于使自己处于不同的情况,因此SAGE用条件标签来作为判断物体处于不同情况的依据,每种情况都可以细分为多中条件标签的组合逻辑,因此我们可以借助对这些条件标签组合逻辑情况的判定来得知这个单位目前处于什么状态,应该显示成什么样的外观,好比一个坦克,初生的时候是正常的外观模样,而在战斗中受伤,变成红血时,外观则变成了破烂不堪的形象。
所有条件标签又分为多种类型,除了NONE表示“没有任何特别情况”(可以理解为默认情况)外,其余的标签分别如下:
(1)破损阶段
DAMAGED                                                                                        轻伤(黄血),生命值介于35%到70%之间
REALLYDAMAGED                                                                        重伤(红血),生命值介于0%到35%之间
RUBBLE                                                                                        尸体/残骸,生命值=0但死亡动作尚未进行完毕的时候,通常体现在有延迟死亡模块作用的情况下
(2)天气时段
NIGHT                                                                                                夜晚,地图编辑器里指定的一个时段
SNOW                                                                                                雪地,地图编辑器里指定的一个环境
(3)自身动作
MOVING                                                                                        移动
ATTACKING                                                                                        攻击,覆盖瞄准、开火、换弹夹等全套动作
USING_WEAPON_[X]                                                                        使用武器,[X]可以取A、B、C,分别对应主、副、第三武器,覆盖该武器的瞄准、开火、开火间隔、换弹夹等全套动作
PREATTACK_[X]                                                                                瞄准,[X]可以取A、B、C,分别对应主、副、第三武器
FIRING_[X]                                                                                        开火,[X]可以取A、B、C,分别对应主、副、第三武器
BETWEEN_FIRING_SHOTS_[X]                                                开火间隔,[X]可以取A、B、C,分别对应主、副、第三武器
RELOADING_[X]                                                                                换弹夹,[X]可以取A、B、C,分别对应主、副、第三武器
RAPPELLING                                                                                下滑,借助空降绳下落,但尚未落地时(让我想起了魂斗罗)
CLIMBING                                                                                        攀爬,用于贝顿越过山脊
UNPACKING                                                                                        部署,用于黑客、红卫兵等开始施展技能,将工具摆设到地面上
PACKING                                                                                        回收,相对上面的部署来说,是把刚才部署下的工具再收回到箱子里装起来
SPECIAL_CHEERING                                                                欢呼,本参战方战胜时部队会挥手并呐喊助威,类似RA2里的C键效果
CARRYING                                                                                        搬运,用于矿车,当车上装着箱子时
PANICKING                                                                                        惊恐,用于平民受到惊吓后到处乱跑
DYING                                                                                                死亡过程,好像是专门配合延迟死亡模块体现死亡动作
RAISING_FLAG                                                                                升旗,似乎特指红卫兵正在占领敌人建筑的过程,好像对类似动作的所有特殊能力都有效
PARACHUTING                                                                                空降,经降落伞空降,但尚未落地时
EXPLODED_BOUNCING                                                                爆飞,被DeathType= EXPLODED的武器杀死后将被爆起来很高
EXPLODED_FLAILING                                                                爆飞到最高点后开始下落的过程
TURRET_ROTATE                                                                        炮塔转动,似乎专用于坦克,但事实上很少有坦克用这个标签来体现状态
OVER_WATER                                                                                位于水面上时
FREEFALL                                                                                        自由落体,不知道有啥特殊含义,似乎和空降以及爆飞后的下落都有关系
(4)级别、特殊升级
VETERAN                                                                                        达到老兵级别
ELITE                                                                                                达到精英级别
HERO                                                                                                达到王牌级别
WEAPONSET_PLAYER_UPGRADE                                        获得武器升级,特指通过Upgrade项目来升级
WEAPONSET_CRATEUPGRADE_ONE                                        捡垃圾捡到武器第1阶升级,特指捡垃圾捡到武器升级项目时
WEAPONSET_CRATEUPGRADE_TWO                                捡垃圾捡到武器第2阶升级,捡垃圾最多能将武器升级2层
WEAPONSET_VETERAN                                                                级别提高到老兵,使武器得到强化时
WEAPONSET_ELITE                                                                        级别提高到精英,使武器得到强化时
WEAPONSET_HERO                                                                        级别提高到王牌,使武器得到强化时
ARMORSET_CRATEUPGRADE_ONE                                        捡垃圾捡到装甲第1阶升级,特指捡垃圾捡到装甲升级项目时                                       
ARMORSET_CRATEUPGRADE_TWO                                        捡垃圾捡到装甲第1阶升级,特指捡垃圾捡到装甲升级项目时
POWER_PLANT_UPGRADING                                                电厂升级过程中,使用时需要有PowerPlantUpdate模块支持,否则的话会报错
POWER_PLANT_UPGRADED                                                        电厂升级完成后,同样需要有PowerPlantUpdate模块支持
RADAR_EXTENDING                                                                        雷达升级过程中,使用时需要有RadarUpdate模块支持,否则的话会报错
RADAR_UPGRADED                                                                        雷达升级完成后,同样需要有PowerPlantUpdate模块支持
(5)摩托车乘员、工厂门
RIDERS_ATTACKING                                                                        乘员在其内部开火时
RIDER[X]                                                                                        装入不同的乘员时,需要摩托车容器的支持,[X]可取1-8共8个整数,分别表示8种不同的乘员装载情况
DOOR_[X]_WAITING_OPEN                                                        工厂门等待打开,通常是单位生产完成时,[X]可取1-4共4个整数,分别表示一个工厂的4个门,每个工厂最多可以有4个门
DOOR_[X]_OPENING                                                                工厂门打开过程,通常是单位准备下线时
DOOR_[X]_WAITING_TO_CLOSE                                                工厂门等待关闭,通常是等待单位开出工厂
DOOR_[X]_CLOSING                                                                        工厂门关闭过程,通常是单位已经完全开出工厂
(6)建造、拆除过程
AWAITING_CONSTRUCTION                                                        地基已经布置完毕,等待基地车前来建设时,完成度停滞在0%
ACTIVELY_CONSTRUCTING                                                        基地车正在建设这个建筑时,完成度保持不断增长的过程中
PARTIALLY_CONSTRUCTED                                                        部分建造完成,但基地车却半途撤离开时,完成度停滞在0%到100%之间的某个百分比上
ACTIVELY_BEING_CONSTRUCTED                                        建造进度已达到100%,但该建筑尚未正式交付使用的时候,这是个非常短暂的过程,似乎只有几帧时间
CONSTRUCTION_COMPLETE                                                建造完成的建筑正式交付使用之后
SOLD                                                                                                拆除建筑过程中,即点下了拆除键,但尚未拆除完毕的这段时间
(7)其他
JAMMED                                                                                        常用于导弹出膛后开始冲刺时
RIGHT_TO_CENTER                                                                        从右边向中间跑
CENTER_TO_RIGHT                                                                        从中间向右边跑
LEFT_TO_CENTER                                                                        从左边向中间跑
CENTER_TO_LEFT                                                                        从中间向左边跑,这4个标签不知道有啥具体作用,原版将之用在了摩托车上
GARRISONED                                                                                被人驻扎之后,需要驻守容器的支持                                                
SECOND_LIFE                                                                                第二次生命时??不明白啥意思,难道原版还有重生概念?
PREORDER                                                                                        预定,似乎是指给工厂类建筑预定生产计划并开始生产时,需要PreorderCreate模块的支持
CAPTURED                                                                                        被捕获之后,可以是通过外部占领或心灵控制的方式来捕获,原版似乎只用在了一些中立科技建筑上
JETEXHAUST                                                                                平飞过程中,似乎专用于机场型战斗机在空中平飞时
JETAFTERBURNER                                                                        弹射起飞时,似乎也只用于机场型战斗机借助弹射板起飞,但尚未进入最大平飞状态时的中间过程
LOADED                                                                                        装有货物时,似乎只用于矿车不空(即装有箱子,哪怕只有一个)时                                                                                                
POST_COLLAPSE                                                                        倒塌过程中,原版只用于一些高塔在死亡后倒塌下来的过程
ENEMYNEAR                                                                                当有敌人靠近时,需要EnemyNearUpdate模块的支持
SPECIAL_DAMAGED                                                                        受到特殊伤害时,没搞懂这个特殊伤害是啥意思
BACKCRUSHED                                                                                当背后受到撞击导致死亡时
FRONTCRUSHED                                                                        当正面受到撞击导致死亡时,似乎需要CrushDie模块的支持
USER_1                                                                                                用户自定义1
USER_2                                                                                                用户自定义2

      过渡过程的作用是连接两个不同情况的中间过程,也就是说,可以理解为变形金刚那样的“变形”,即从机甲状态过渡到车辆状态,或从车辆状态过渡到机甲状态。从这里可以看出,过渡过程是一个可双向的的过渡,而它也需要使用一定的标签来标示前后两个状态,但它所使用的标签最特殊,是玩家自行命名的,你可以给它命任何名称,只要调用得成功都行,如果调用失败,不会报错,但却会丢失过渡过程(就成了瞬间切换)。过渡标签是在ConditionState函数里用一个语句来定义并命名的,就像下面这个例子:
    ConditionState      = SNOW
      Model             = UARADR
      Animation         = UARADR.UARADR
      AnimationMode     = LOOP
      TransitionKey     = Amakeup                                                给这个状态定义一个过渡标签,并将之命名为Amakeup,供后面编写过渡过程时使用
End

    ConditionState      = SNOW SOLD
      Model             = None
      TransitionKey     = Abackout                                                定义另一个过渡标签,并将之命名为Abackout,供后面编写过渡过程时使用
End

    TransitionState     = Abackout Amakeup                                        从Abackout过渡到Amakeup的过程,即从SNOW状态过渡到SNOW SOLD状态的过程
      Model             = UARADRMK                                        过渡过程也调用一个W3D模型
      Animation         = UARADRMK.UARADRMK                        并播放这个W3D模型里所包含的3D动画,点号前面表示W3D内部名称,后面表示3D动画名称
      AnimationMode     = ONCE                                                        动画播放模式,ONCE表示只一次,此外还有其他模式,如无限循环、反向一次等等,这个后面遇到了再说
End

    TransitionState     = Amakeup Abackout                                        从Amakeup过渡到Abackout的过程,相对于上面一个过渡来说,这是它的反向过渡,这意味着3D动画有可能需要反过来播放
      Model             = UARADRMK
      Animation         = UARADRMK.UARADRMK                        模型还是这个模型,动画也还是这个动画
      AnimationMode     = ONCE_BACKWARDS                        唯独不同的是,ONCE_BACKWARDS表示反向一次,即把整个3D动画反过来播放
      Flags             = START_FRAME_LAST                        当使用ONCE_BACKWARDS时,需要加上一句播放说明,START_FRAME_LAST表示将最后一帧作为开头来反向播放
End

所有动画控制如下:
AnimationMode = [播放模式]         所有播放模式默认的播放说明都是START_FRAME_FIRST,因此需要改变的话就要自己用Flags语句来申明
ONCE                                                                正向一次
ONCE_BACKWARDS                                        反向一次,需要搭配Flags = START_FRAME_LAST语句使用
LOOP                                                                正向无限循环
LOOP_BACKWARDS                                        反向无限循环,需要搭配Flags = START_FRAME_LAST语句使用
MANUAL                                                                手动控制,实际上并非是让玩家自行控制,而是由游戏中特定的过程来控制

Flags           = [播放说明]
START_FRAME_FIRST                                以第一帧为起始帧进行播放
START_FRAME_LAST                                以最后一帧为起始帧进行播放,事实上即便是正向播放,你也可以恶意地使用START_FRAME_FIRST来制造特定的反常效果
RANDOMSTART                                                随机选择一帧作为第一帧,剩下的按正常正向顺序播放

      最简单的外观定义是基本式,也就是没有什么特别的定义,只需要写好基本定义的那几种情况即可发挥作用。它与运动模式没有任何关系,也就不会自动地反映出任何特殊运动表现,必须全靠人工根据不同的条件标签和过渡标签来区分状态,以做出微观定义,因此这种基本式往往被步兵、建筑或飞机采用。
  Draw = W3DModelDraw ModuleTag_XX
    OkToChangeModelColor  = Yes

    DefaultConditionState                                                                        默认状态,不仅包含了ConditionState = NONE时的外观定义,而且还作为缺省定义给其他情况时使用
      Model               = STARF                                                使用哪个W3D模型文件
      Turret               = Turret01                                                以哪个模型块作为第一炮塔
      AltTurret             = Turret02                                                以哪个模型块作为第二炮塔,一个单位最多有两个炮塔,每个炮塔都可以发射主、副、第三武器,恐怕只有战列舰才用双炮塔
TurretPitch           = TurretEL01                                        以哪个模型块作为第一炮塔上所有炮管的俯仰控制关节点
AltTurretPitch         = TurretEL02                                        以哪个模型块作为第一炮塔上所有炮管的俯仰控制关节点
      WeaponFireFXBone    = PRIMARY MuzzleP                        用主武器开火时炮口FX的产生点对应哪个骨骼点,PRIMARY表示主武器,后一个是骨骼点名称的前缀,后面自动匹配数字序号
      WeaponRecoilBone    = PRIMARY BarrelP                        用主武器开火时可退缩的炮管为哪个模型块,这个语句使炮管在开炮时沿其自身的X轴负方向退缩
      WeaponMuzzleFlash   = PRIMARY MuzzleP                        用主武器开火时炮口闪光对应哪个骨骼点,原版经常做一些正交的平板放在炮口上充当闪光,不知道有啥意思
      WeaponLaunchBone    = PRIMARY MuzzleP                        用主武器开火时开火点位置对应哪个骨骼点
      WeaponFireFXBone    = SECONDARY MuzzleS                用副武器开火时炮口FX的产生点对应哪个骨骼点,SECONDARY表示副武器
      WeaponRecoilBone    = SECONDARY BarrelS                用副武器开火时可退缩的炮管为哪个模型块
      WeaponMuzzleFlash   = SECONDARY MuzzleS                用副武器开火时炮口闪光对应哪个骨骼点
      WeaponLaunchBone    = SECONDARY MuzzleS                用副武器开火时开火点位置对应哪个骨骼点
      WeaponFireFXBone    = TERTIARY MuzzleT                        用第三武器开火时炮口FX的产生点对应哪个骨骼点,SECONDARY表示副武器
      WeaponRecoilBone    = TERTIARY BarrelT                        用第三武器开火时可退缩的炮管为哪个模型块
      WeaponMuzzleFlash   = TERTIARY MuzzleT                        用第三武器开火时炮口闪光对应哪个骨骼点
      WeaponLaunchBone    = TERTIARY MuzzleT                        用第三武器开火时开火点位置对应哪个骨骼点
    End

    ConditionState        = DAMAGED                                                轻伤时的状态,由于上面用DefaultConditionState定义了缺省值,因此后面就不必全部重新定义,凡是没有定义的语句
      Model               = STARF_D                                        都将自动借用上面的缺省语句,相反,定义了的语句则会覆盖缺省值并发挥作用
    End

    ConditionState        = REALLYDAMAGED                                重伤时的状态
      Model               = STARF_E
    End

    ConditionState        = RUBBLE                                                残骸/尸体时的状态
      Model               = STARF_R
    End

  End
      特别需要注意的是,任何外观模块的函数中,至少必须有DefaultConditionState(默认状态),或者ConditionState = NONE(空状态),总之两者必须有一个,而且只能有一个。从表面上看,这两个子函数的效果差不多,因为默认状态实际上在很多时候都表示“初始状态”,也就是“不具备任何标签的状态”,而这种状态正好就是空状态,所以一般情况下,你把它们混淆是没什么问题的。但是它们的作用依然有差异,因为“空”也是一个特定的状态,与其他诸如轻伤、重伤等状态的级别是平等的,自己的定义只对自己有效,而默认状态则是涵盖所有状态的最高级别,它的定义可以覆盖其他状态,因此默认状态可以给整个外观模块提供一些缺省值,以至于其他状态不需要重复地定义一些相同的语句,这样可以省不少手笔。
此外SAGE还提供一个更加省手笔的写法,称为借用法,通常用在含有组合逻辑的状态中,例如下面这个段落:
    ConditionState      = REALLYDAMAGED                                首先用正常的方法定义重伤时的外观
      Model             = UGRADR_D
      Animation         = UGRADR_D.UGRADR_D
      AnimationMode     = LOOP
      TransitionKey     = Gmakeup
    End
AliasConditionState = NIGHT REALLYDAMAGED
      这里跟一个AliasConditionState语句来让NIGHT REALLYDAMAGED状态借用REALLYDAMAGED状态外观。像这种多个标签并列的参数就是我所谓的组合逻辑状态,并列的标签表示同时具备这些标签时的状态,例如这个例子里的REALLYDAMAGED表示白天+重伤,而NIGHT REALLYDAMAGED则表示夜晚+重伤。而这样的一段语句,展开之后实际上就等效于下面这个样子:
    ConditionState      = REALLYDAMAGED
      Model             = UGRADR_D
      Animation         = UGRADR_D.UGRADR_D
      AnimationMode     = LOOP
      TransitionKey     = Gmakeup
End

ConditionState      = NIGHT REALLYDAMAGED
      Model             = UGRADR_D
      Animation         = UGRADR_D.UGRADR_D
      AnimationMode     = LOOP
      TransitionKey     = Gmakeup
End
      这就是分开写的写法,两个状态使用完全相同的语句及参数。由此可见AliasConditionState能让你节约不少篇幅。
      像这样借用外观的情况,在建筑和步兵里非常常用。


      SAGE在基本式的基础上又增加了一些具有特殊定义的进阶式,这些进阶式的基本定义和基本式一样,也是用不同的ConditionState和TransitionState子函数来定义,我就全部简写以表达意思,仅仅用蓝色文字来表示这种进阶式函数的特殊功能语句。
      坦克通常使用W3DtankDraw函数,它的特色是可以定义履带的转动,以及当坦克处于移动过程中时,自动在车尾产生两道游戏平台默认的沙尘,目前尚不知道沙尘能否做成微观定义,让每个坦克的沙尘都不一样。
  Draw = W3DTankDraw ModuleTag_XX
    OkToChangeModelColor  = Yes

    DefaultConditionState
      Model               = STORM
    End

    ConditionState        = DAMAGED
      Model               = STORM_D
    End

    ConditionState        = REALLYDAMAGED
      Model               = STORM_E
    End

    ConditionState        = RUBBLE
      Model               = STORM_R
    End

    TrackMarks            = EXTnkTrack.tga                                坦克开过之后在地面上留下一条履带痕迹,这条痕迹使用哪个TGA作为贴图
    TreadAnimationRate = 2.0                                                                履带贴图的移动速度,原来履带的转动是靠移动贴图来实现的,因此专门要为坦克做一个履带贴图,这个在W3D制作里再讲
    TreadDriveSpeedFraction = 0.3                                                        当本体的移动速度低于多少时,履带贴图将停止移动,不知道这里的0.3、0.6到底是个什么比率
    TreadPivotSpeedFraction = 0.6                                                        当本体的移动速度高于多少时,履带贴图将开始旋转
  End

      由于SAGE的物理引擎借鉴了NFS里很多运算,以至于SAGE能够做出一种TS里想都不敢想的多轮车辆,这可不仅仅是外观那么简单,而是直接体现运动方式,简直和NFS的感觉差不多,你可以让两轮或四轮后驱车辆急转弯并做出漂移动作,在地上用轮胎印记画出一个8字,同时还能看到后轮摩擦地面杨起的沙尘。因此多轮车辆一般使用W3DtruckDraw函数,它的特色是定义车轮的动作。
  Draw = W3DTruckDraw ModuleTag_XX
    OkToChangeModelColor = Yes

    ConditionState = NONE
      Model = AVAmbulance
    End

    ConditionState = REALLYDAMAGED
      Model = AVAmbulance_D
    End      
   
    ConditionState = RUBBLE
      Model = AVAmbulance_D
    End      
   
    TrackMarks = EXTireTrack.tga
    Dust = RocketBuggyDust                                                                车轮旋转时卷起的沙土,调用一个粒子系统
    DirtSpray = RocketBuggyDirtSpray                                                似乎和上面一句的作用相似,不过貌似特指沙土飞扬时候调用哪个粒子系统(恐怕是指移动过程中)
    PowerslideSpray = RocketBuggyDirtPowerSlide                        还是和上面相似,不过特指刹车时摩擦出来的沙土
    LeftFrontTireBone = Tire01                                                                左前轮对应W3D里哪个模型块
    RightFrontTireBone = Tire02                                                        右前轮对应W3D里哪个模型块
    LeftRearTireBone = Tire03                                                                左后轮对应W3D里哪个模型块
    RightRearTireBone = Tire04                                                        右后轮对应W3D里哪个模型块
    TireRotationMultiplier = 0.2                                                                车轮旋转速度比率,以单位当前的移动速度为基准来决定车轮转速
    PowerslideRotationAddition = 2.5                                                刹车时车轮转速的增量,搞不懂为什么是加2.5而不是减2.5

      SAGE以上面3种外观式为基础又衍生出了下列近阶式,基本上可以说是组合了前击中方式的特殊定义。
W3DScienceModelDraw                                                                        证书式,用于一种需要获得了对应技能证书后才能看到的物体,例例如原版的垃圾箱,特有RequiredScience语句
                                                                                                                                使之调用一些证书,没有获得这种证书的参战方无法看到它。
W3DDependencyModelDraw                                                                加载式,用于定义类似炎黄盖特炮、炎黄广播塔之类需要加载在主体头顶上的物体,特有AttachToBoneInContainer语句
使之与主体上的某个骨骼点关联,确保其加载的位置
W3DTankTruckDraw                                                                                半轮半履带式,可以同时定义车轮和履带的转动
W3DOverlordAircraftDraw                                                                        炎黄飞机式,用于定义一些带有活动粒子系统骨骼点的物体,特有ParticlesAttachedToAnimatedBones = Yes语句
使这些粒子系统能够跟随骨骼点的3D动画而运动。
W3DOverlordTruckDraw                                                                        炎黄多轮车式,同上,同时也具备一般多轮车辆对车轮转动的定义
W3DOverlordTankDraw                                                                        炎黄坦克式,同上,同时也具备一般坦克对履带转动的定义
W3DpoliceCarDraw                                                                                警车式,我没看出它和一般的多轮车辆有啥区别

下面还有一些比较专用的方式,通常用于某种特殊物体的外观定义。
光束式,所有光束激光都用这种方法来产生视觉效果。需要LaserUpdate的支持。
  Draw = W3DLaserDraw ModuleTag_XX
    Texture = EXBinaryStream32.tga                                                        光束上的贴图
    NumBeams = 4                                                                                光束由多少个重叠的圆柱体构成,用于模拟激光的光晕效果
    InnerBeamWidth = 0.4                                                                        内层光束(光束体)宽度
    InnerColor = R:255 G:255 B:255 A:250                                        内层光束的染色效果,同样是RGB算法。最后的A似乎表示光束的透明度
    OuterBeamWidth = 1.2                                                                        外层光束(光晕带)宽度
OuterColor = R:255 G:0 B:0  A:150                                                同内层光束染色效果,特别需要注意,由于内外两层是重叠的,因此相互的染色可能会发生影响
Tile = Yes                                                                                                使用平铺贴图,反之则是将贴图拉伸以适合整条光束
    ScrollRate = -0.25                                                                                使贴图在光束上移动的速度,以模拟激光的动作,正值表示发射出去,负值表示吸收回来
    Segments = 20                                                                                将整条光束分割成相互独立的多少段,每段单独移动贴图,原话说,分割得越多,光束就越细腻
    ArcHeight = 30.0                                                                                光束的弯曲程度,正值表示向上弯,负值表示向下弯,但通常不使用负值
    SegmentOverlapRatio = 0.0000                                                        似乎可以控制相邻分段接头处的贴图交叠效果,正值表示交叠,负值表示拉开
    TilingScalar = 0.25                                                                                拉伸平铺情况,1表示不动,小于1表示收缩,大于1表示伸展
End

树木式,专用用树木式来体现树木的一些特征,所有树木都用这个方式来定义
  Draw = W3DTreeDraw ModuleTag_XX
    ModelName = PTDogwod01                                                        调用哪个W3D作为树木的结构基础,仔细可以看出,树木其实是由很简单的4张正交平面加一根细圆柱体构成的
    TextureName = PTDogwod01.tga                                                表面贴图,树木基本上就全靠这个贴图来体现形状,隔远了看起来倒也不错
    DoTopple         = Yes                                                                被撞击后是否倒塌,怀疑No的话是表示竖直沉入地表,而非先倒塌然后横着沉入地表
    DoShadow         = Yes                                                                是否在地面上投射阴影
    ToppleFX         = FX_ToppleTree                                        倒塌时的FX特效
    BounceFX         = FX_OptTreeBounce                                倒塌时在地表面反弹起来的FX特效
    KillWhenFinishedToppling = Yes                                                        倒塌结束后是否判为死亡
    SinkDistance     = 10                                                                        下沉距离,也就是说将沉入地表以下10像素的地方然后消失
    SinkTime         = 5000                                                                下沉持续时间
  End
        
补给站式,专门定义补给站和补给堆的方式,可以体现出箱子不断不搬走,最后搬空的过程效果,需要SupplyWarehouseDockUpdate模块的支持。                                                               
  Draw = W3DSupplyDraw ModuleTag_XX
    ExtraPublicBone = SUP                                                                特殊通用骨骼点,似乎是关联着补给站上那些箱子的位置
    ConditionState = NONE
      Model = CBToxRepos
    End
    SupplyBonePrefix = SUP                                                                根据SupplyWarehouseDockUpdate里定义的箱子数量来决定隐藏一定比率箱子,若搬空则全部隐藏起来
  End

      尾气流式,专门定义射弹体尾气流用的方式,在毒素车的射弹体里出现过,似乎效果和光束差不多。我很怀疑这个是否能做成效果最好的粒子激光。        
  Draw = W3DProjectileStreamDraw ModuleTag_XX
    Texture       = EXToxinStream.tga                                                尾气流贴图
    Width         = 1.5                                                                        尾气流宽度
    TileFactor    = 2.0                                                                        贴图平铺倍数
    ScrollRate    = 6.0                                                                        贴图卷动速度,以模拟尾气流的喷射效果
    MaxSegments   = 14                                                                        每隔多少个分段显示一次贴图效果,似乎0可以表示显示所有分段
  End

2、音效编辑。好游戏总是需要优秀的听觉效果来刺激观众,因此有必要在音效方面下一定的功夫。

      SAGE的音效比TS相对容易整理得多,因为不需要像TS那样用XCCMIXER注入AUDIO.BAG中,所以操作上来讲便宜了很多多余的步骤。
      SAGE支持两种音效文件,一种是传统的8位或16位PCM,也可以使用压缩过的4位IMA-ADPCM,和TS一样,要求后缀名为WAV。另一种是大家求之不得的MP3,通常用于背景音乐,采样率可支持11000到44000之间的任意值,位速率可支持从64到256之间的一些特定值。从性价比的角度来讲,MP3肯定比WAV划算,但是我没测试过是否所有音效都能使用MP3。
SAGE的音效分为单位语音、武器/环境音效、EVA语音、背景音乐4类,代码的定义法和TS大同小异,我一样举一个例子,剩下的让你们自己去看ZH的代码。

单位语音代码,通常存放在Data\INI\Voice.ini里
AudioEvent RangerVoiceAttack
  Sounds = iranata iranatb iranatc                                                        调用哪些音源,通常是WAV文件
  Control = random                                                                                播放方式,ramdom表示随机抽选一个来播放一次,单位语音通常只能random,用其他方式会显得很怪异
  Volume = 90                                                                                        一般音量倍率,以音源的音量为基准,100表示100%,小于100表示减小,反之则是增大
  MinVolume = 45                                                                                        最小音量倍率,同上,通常要比一般倍率的参数小
  Priority = high                                                                                        优先度,可选critical(实时)、high(高)和low(低),缺省时表示中等
  Type = [类型]               播放类型,可在下面这么多种里选择搭配,当然,相互冲突的不能搭配,否则会出现怪异后果
ui                                                                                                界面型,不知道有啥作用
voice                                                                                        语音型,表示单位语音,似乎没啥作用
player                                                                                        单方型,只能被本方玩家听到,因此和everyone相互冲突
world                                                                                        全局型,该语音不会因为摄像机远离来源而衰减音量,因此全地图上任何位置都听得到
shrouded                                                                                强制型,该语音的来源被黑雾或灰雾笼罩时,照样能发出声音
everyone                                                                                公共型,可以被所有玩家听到,因此和player相互冲突
End

武器/环境音效代码,通常存放在Data\INI\ SoundEffects.ini里,定义法和单位语音一模一样,某些特别的语句和参数可以在这里使用而不会显得很怪异
AudioEvent HumveeMoveStart
  Sounds      = vhumstaa vhumstab vhumstac
  Attack       =  vtoxlo1a                                                                以哪个音源作为淡入阶段
  Decay       =  vtoxlo3a                                                                以哪个音源作为淡出阶段
  Volume      = 60
  PitchShift    = -5 5                                                                                音调浮动范围,从-5到+5之间升降调,缺省为0,即保持原调,这样可以使每次的音效都略有差异,显得很丰富
  Delay       = 0 500                                                                                发音延迟时间,从0到500毫秒之间随机取值
  VolumeShift = -10                                                                                音量变化,-10表示从发音开始到发音结束,音量将衰减10个单位(不知道是不是分贝),正值则表示增强,缺省为0,即不变
  Control     = [播放方式]            播放方式,可在下面这么多种里选择搭配,当然,相互冲突的不能搭配,否则会出现怪异后果
random                                                                        随机抽选并播放一次
interrupt                                                                        强制中断然后播放第一个音源一次(会无视后面的音源)
loop                                                                                无至尽地循环播放第一个音源(会无视后面的音源)
all                                                                                必须将所有音源全部都播放至少一次,通常和loop搭配
  Limit        = 3                                                                                当Control的参数中存在loop时,表示播放一次最多有多少个循环
  Priority      = low
  Type        = world shrouded everyone
End

EVA语音代码,通常存放在Data\INI\Speech.ini里。定义非常简单,仅仅调用音源,最多再设置一下类型和音量倍率即可
DialogEvent Cinx_PlaneLandStereo
  Filename = cplane03.wav                                                                        调用哪个音源,从参数来看貌似可以使用MP3格式
  Volume = 100
  Type = ui                                                                                                EVA语音似乎都最多使用ui类型,通常是缺省的,不知道缺省表示什么
End

      背景音乐代码,通常存放在Data\INI\Music.ini里,和EVA的定义法大同小异。
MusicTrack Game_CHI_03
  Filename = CHI_03.mp3
End

      需要注意的是,SAGE的背景音乐播放方式和TS不同,TS是由平台底层的播放机功能来直接播放你定义好的这些曲目,而SAGE则需要在宏观AI里编写一系列很复杂的触发程序来播放它们,因此很多MODER发现,自己做的MOD只能替换原版音乐源,却不能自己添加。那么在后面的月光宝盒秘籍里,我将讲解如何编写宏观AI以及部分典型的任务流程。
      音源的制作需要专业的音频编辑工具,MP3暂且不用考虑太多,因为一般都是直接从网上下载下来就能用,而WAV则需要处理,至少也需要转换一下格式。我推荐使用GOLDWAVE来编辑音效,这个工具使用非常简单,可以批量转换任何格式的音源,并能在转换过程中批量加入特效设置,例如批量改音量、批量增加滤波效果等等。还能完成精确的音频编辑工作,例如音效合成、剪辑。
      对于使用381M决命时刻中文版为MOD基础的人来说,编辑好的音源,需要存放在\Data\Audio\Sounds\Chinese目录中。如果是以英文版为基础,则需要放到\Data\Audio\Sounds\English目录中。你也可以创建几个BIG包来分别保存它们,当然,在使用BIG保存资源的时候千万要注意路径,不能像以前使用MIX那样不管3721地随意塞进去。

3、图像编辑。图像好不好,直接导致了玩家对这个游戏的第一映像好不好。要知道99 %的玩家都是小白,他们只知道看表面,根本不会去在意这个游戏的内涵到底有多深。因此你不能期望任何玩家都像资深的CNC爱好者那样来仔细品位你的作品,因此空有骨架而无外表的游戏在市场上是站不住脚的。

      说到图像,我就想起了PhotoShop,没错,这是任何游戏都必须使用的图像编辑工具。什么,你说你做MOD就从来没用过?那不好意思,我只能说你还没入行。
      以前在TS里,做一个图像都相当麻烦,因为首先需要用PhotoShop编辑PCX图片,完工之后还要用PaintShop Pro来加载调色板,然后还要用XCCMixer转换成SHP,如果是要制作多帧动画,还得用上AnimShop、ACDSee、FotoCanvas等等工具,累都累死人了。而现在则方便了很多,因为SAGE引擎直接就支持真彩色的图像,并支持Alpha蒙板,可以节约PhotoShop之后的所有工序。但SAGE的2D图像,包括3D模型上的贴图,都只能支持TGA和DDS格式。在上面的教程里我们可以注意到,所有调用贴图的语句参数,后缀名都是TGA,你绝对都看不到DDS这3个字,但事实上这些图像却多数是以DDS格式保存在游戏目录下,之所以还能被游戏识别,就是因为SAGE把DDS图片也视为TGA对待,因此你写代码尽管全部写成TGA好了。
      有人一直找机会反对我,说SAGE还是有不如TS的地方,估计就在图像方面,不知道大家有没有注意到,任何3D游戏都无法支持多帧SHP那样的动画图片,因为现在的3D引擎还不能识别GIF动画,所以绝大多数时候,2D动画方面的表现甚至还不如TS引擎那么简单自如,往往需要借助3D动画来控制2D贴图产生视觉效果,而不能直接用一张动画SHP来表现。

      SAGE的2D图像分为两种类型,一种是映射图像,另一种是贴图,前者经过申请并定义后能被其他INI调用,因此需要制作代码。后者则是图像资源,被INI和3D模型调用,甚至被影射图像的定义语句调用。
      定义映射图像的代码通常在MappedImages\TextureSize_512目录下,有很多个INI,事实上你也可以随意新建一个INI来保存你自己定义的映射图像。被定义过的映射图像可以作为操作栏上的图标图像、单位头像,以及游戏宏观界面上的某些图像等等。一个典型的定义如下:
MappedImage Head122_UAPOWR                                                申请一个映射图像,并为之命名,之后就可以在其他INI里调用这个名称了
  Texture = UAPOWRHead.tga                                                        使用哪个TGA贴图作为其图像源
  TextureWidth = 512                                                                        贴图宽度,单位为像素,这个参数必须和TGA图像源的尺寸一致,否则会发生拉伸导致变形甚至显示错误
  TextureHeight = 512                                                                        贴图高度,同上
  Coords = Left:0 Top:0 Right:122 Bottom:98                                映射区域,从整张TGA的左上脚为原点开始计算,用上下左右4个顶点来选出一个小部分作为映射出来的实际图像
  Status = NONE                                                                                状态,没搞懂有啥作用,似乎很多都是NONE
End
点评:映射图像是SAGE的特色之一,而且也比较难掌握,因为EA图方便,把几十个图标全部混杂地放在一张很大的TGA上,然后用Coords语句来“挖”出各个图标生成每个映射图像的实际图像。EA自己倒是有分割工具,自动生成代码,问题是玩家没有,只能靠人工计算,怎么办呢?我想到了一个无耻的办法,那就是分开定义各个图标。
MappedImage Head122_UAPOWR
  Texture = UAPOWRHead.tga
  TextureWidth = 122
  TextureHeight = 98
  Coords = Left:0 Top:0 Right:122 Bottom:98
  Status = NONE
End
      看看这样一改有啥后果。由于整张贴图的尺寸和挖的区域一样大,事实上也就是说,直接使用整张TGA的全部区域。那么你就可以把每个图标的图像资源像TS那样分开编辑了,如果图像尺寸有变化,只需要将TextureWidth、TextureHeight、Right、Bottom的值改到和TGA图像源尺寸一样大就行,根本不需要学EA那样混杂在一堆,还要慢慢地计算应该怎么挖,万一要改的话,动一张就要动全局。

关于TGA和DDS图像的编辑方法,我就不多说了,这个东西不是一两句话扯得清楚的,尤其是Alpha蒙板部分。所以我建议你最好是去买一本PhotoShop教程,先掌握了图像编辑基本方法了再说。最后做好的TGA和DDS图像源,需要保存到Art\Textures目录下。

4、3D建模。这是3D游戏的灵魂所在,模型做得好不好,直接影响了整个游戏的大局,所以我事先建议某些急功近利的MODER,统统给我滚回去先把3DMAX学扎实了再回来看教程。

      首先需要提的是,SAGE支持的W3D模型,是以3DMAX为基础的一种格式,具备3DMAX里的很多基本功能,但相比MAX来说并不完善,例如不支持凹凸贴图、不支持光线跟踪等等,使得做出来的模型在游戏里看起来很干瘪,像个玩具一样直白,没有任何华丽的表现。没办法,谁叫W3D是EA在3D游戏里的第一次尝试呢?后来EA使用了功能更近似于MAX的W3X,用在CNC3里,效果就华丽了不少。
      那么要想把W3D做得不像玩具,关键就在于材质和贴图技巧。你们去看看《冲击波》、《Contra》等优秀MOD里的坦克模型就知道,优秀的模型,结构并不复杂,复杂的是贴图上包含丰富的迷彩底色和上层细节装饰,甚至精致得连螺丝钉、钢板缝都看得见。关于贴图技巧和材质通道的内容,我放到后面的进阶教程里再讲,其实看完本章,你如果能做出“玩具”来,已经很不错了。
      关于建模的要点,前辈已经写过帖子来讲解,我就直接以附件的形式与教程一起打包,事实上我根本不知道这部分应该如何来讲解,因为3D建模本应该属于一个游戏开发基础技能,如果连3D建模都不会,我只好怀疑你是花钱买进游戏行业来混日子的人。所以我只讲解制作过程中的一些注意事项。
在讲解之前,我建议大家尽可能地提取原版的现成资源来观察,看看人家的标准是怎么做的,千万不要想当然地去自己钻研,否则一但走错方向,就会钻进牛角尖无法自拔。

(1)坐标轴向
      其实我也不知道该怎么说才够详细,但是说得太严谨的话,又好像是在讲CAD,没学过机械制图的菜鸟懂不起……不如直接给一副坦克模型图来说明如何摆放模型才是正确的方向:
01.jpg
      3DMAX的默认视窗布局如上图所示,分别是顶视、前视、左视和透视,每个视角窗口的左下脚都有红绿蓝3个箭头,分别用来指示X、Y、Z的正方向(透视窗口中的3个箭头最容易识别)。
      SAGE规定,在3DMAX的默认视窗里,顶=俯视视角,前=右侧视角,左=背后视角,同时又规定,X+为模型的正面朝向,Y+为模型的左手朝向,Z+为模型的顶面朝向。因此正确的放法,是如上图所示,将坦克的炮管口(正面)朝向X轴正方向,这和机械工业制图的习惯正好逆时针转了个90度,在实际制作模型时必须特别小心,否则做出来的坦克会像螃蟹一样“横行”霸道。
      SAGE还有一些重要的微观轴向,尤其是对于一些可活动的模型块,如炮管的退缩、炮塔的转动,它们的微观轴向就显得尤为重要,如果胡乱设置的话,在游戏中会发生错误的动向或转向。必须注意的是,炮管的微观X+方向必须是从炮尾指向炮口的方向。炮塔的微观Z轴必须与世界坐标的Z轴一致。以上两点不太容易说清楚,请各位读者导入原版ZH的战神坦克模型去看看炮管和炮塔的微观轴向,自然就明了了。

(2)模型的位置和尺寸
      3DMAX里的XY平面相当于游戏里的“地面”,因此模型的底面必须正好落在XY平面上,否则在游戏里会出现“浮空”或“沉地”的怪现象。而模型的前后左右位置则需要从顶视图里来观察,通常坦克以底盘的前后左右4条边界线为标准,建筑以地基板的前后左右4条边界线为标准,人物以脊椎骨骼为基准来计算其中心点位置。以上图的灰熊坦克为例,炮管不属于底盘部件,虽然它长出那么多一截,但不应该参与中心点的计算,因此我们只使用车身来作为计算来源。正确的中心点可以确保车身在X和Y方向上满足,正向最远点的坐标与负向最远点的坐标值几乎相等。那么放到游戏中去的话,灰熊坦克基本上就在其血格范围之内,而不会偏离得太远。
      中心点放好之后,还需要设置模型的尺寸,首先我们要在INI里定义一个单位的理论尺寸作为标准参考值,以它来调整模型的实际尺寸,使模型的实际尺寸尽可能接近理论尺寸但不要大于理论尺寸。而尺寸同样也是只使用底盘作为标准来进行计算,炮管是不参与计算的。假设我们定义灰熊坦克的主半径(X)为15,次半径(Y)为10的话,那么我们就要用整体缩放法在3DMAX里控制模型的底盘尺寸尽可能地逼近30X20,但不要超过30X20。

(3)关节点
      或许一提到关节点,有点经验的读者会立刻联想到士兵模型。其实不仅仅是士兵,坦克和建筑模型模型里照样存在关节点,上图中的左视图可以看到履带中央有两个绿色的小方格,这就是关节点,当坦克在移动时,它们将控制狼烟粒子系统的发射点位置。而透视图中的炮管口上也有一个绿色小方格,这个小方格的意义最重要,它控制着开火点的位置,其微观X+方向还同时决定了射弹体的出射方向。看到这里,或许很多人要开始高兴了——确实,SAGE不需要再像TS那样茫然而又麻烦地调整FireFLH值,你只需要在适当的地方放一个关节点就能直观地控制开火点位置和方向。
当然还不能高兴得太早。关节点不光要放置在模型里,还必须注意INI里对它的调用,前面在讲外观模块时明确提到WeaponLaunchBone等语句的含义,其最后一个参数就是关节点在3DMAX里的名称。返回外观模块定义去看,你还能发现有似乎调用并不是严格和关节点同名,例如:
WeaponLaunchBon = PRIMARY MuzzleP           主武器的开火点位置由一个名称为MuzzleP的关节点来控制
      但在实际模型中,你却找不到MuzzleP这个关节点,只找得到MuzzleP01、MuzzleP02、MuzzleP03……等等带数字后缀的关节点。事实上,这也是一种特殊的、被游戏认可的“同名”规则,专业称呼为[BoneName]%02d,即INI里只调用前缀,实际关节点的命名可在前缀字段后加两位数字,那么凡是前缀和INI对应上的所有关节点都将作为开火点,于是会形成一种“每个开火点轮流开一炮”的现象。此现象在原版炎黄坦克里出现过,大家可以导入进来看看,和INI对照起来分析,看看我说得是不是如此。
      要放置新的关节点,可以使用球体、方块和骨骼等实体,也可以使用点、灯光、辅助物等虚体,两者需要设置不同的输出方式。
      选中一个实体或虚体,在W3D Tools脚本功能栏里可以察看它的输出方式,分为Export Transform(仅输出定位信息)和ExportGeometry(仅输出形体图像)两种方式。3DMAX的默认情况为,实体的两个选项都被钩上,表示既输出定位信息,又输出形体图像。而虚体则正好相反,两个选项都没钩,表示什么都不输出。因此如果使用实体作关节点,在输出W3D时不要忘了取消它的“Export Geometry”选项,使之不输出任何形体图像。而使用虚体作关节点时要记得钩上“Export Transform”选项,使之输出定位信息。
      对于做坦克和建筑模型而言,如果你觉得这样设置很麻烦的话,我提供一个懒人专用方法:用虚体作关节点,模型做完后,全选整个模型的所有部件,统一把Export Geometry和Export Transform都钩上, Geometry Option选择Normal(直接输出),这样输出的话,相当于是让所有部件都同时输出形体图像和定位信息,由于虚体本身并不存在形体图像,因此即便钩上了Export Geometry也不会输出任何东西,在游戏里就不会有异常的显示情况。
      特别注意,上述这个懒人方法只适合做坦克和建筑等“整合模型”(只输出一个W3D的模型)。而对于士兵模型这种“拆分模型”(拆分为SKN、SKL和动作的模型)而言,这个方法会导致巨大的定位信息冲突,会使步兵模型在游戏中显示为半静态的T字形。

(4)所属色
      所属色是RTS的一大特征,通常在模型的一些表面上染上不同的颜色用来表示该单位属于不同的玩家。具体做法很简单,把你希望染上所属色的部件名称改成HouseColor%02d,虽然在3DMAX里不会有任何变换,但该结构块在游戏中就会自动染上所属玩家的阵营颜色。此方法对坦克和建筑模型非常实用,但对步兵不实用,关于步兵的所属色制作,我在后面的人物制作要点里再提。

(5)简模——RTS的本色
      由于RTS的特殊性在于“大军团”和“多兵种”,因此一般情况下,同屏幕内容纳的多边形数必定是FPS游戏的几十到几千倍,所以我们在制作模型时,千万不能按照FPS的精模标准去制作每一个模型,经过我的实践证明,我的蓝宝1950XTX双256显卡运行SAGE引擎,在ZH里同屏幕内多边形数超过10W将使游戏直接崩溃,若在5W到10W之间,游戏速度会慢得不足25帧,所以你们看过原版ZH模型的话应该很清楚一个事实——通常每个模型只有几百个多边形,简陋得简直就像玩具。
      与原版ZH的情况相反,历史上有一个非常著名的ZHMOD,叫《现代战争》,是我师傅QSN的杰作。这个MOD以精致和逼真著称,所有模型都是按照FPS的精模标准制作的,部分坦克模型的多边形数甚至超过了1W,这个游戏被我戏称为“只能看不能玩的军事教科书”,每一样东西你造一个出来看看外观,看看功能还可以,如果非要去玩这个游戏的话则简直是虐待自己的显卡,只要稍微多造几个坦克,直接就会要绝大多数NF系列显卡的命。
与崇尚精致和逼真的RW派作者(RealWar)相反,WC派作者(WorldCompetion)则是崇尚流畅和竞技体育,为了使游戏流畅,他们想方设法地简化模型的多边形数,很多时候为了追求流畅性,不得不干掉了一些模型上的细节表现,我个人的观点来看,这是值得的。
      3DMAX有一个自带的脚本工具,多边形计数器,可以快速地计算出你的模型总共有多少个多边形。需要注意的是,3DMAX计算的多边形数,不是指物体的实际表面数,而是指三角形面数。例如长方体的一个侧面是由2个多边形组成的,而6棱柱的底面则是由6个多边形组成的,由此可以看出模型的多边形数和表面数没有固定的比例系数,但可以肯定的是,表面数越多,多边形数就必定越多。因此简化模型,实际上就是减少形体的表面数量。
    如果决定要走简模路线,那么在建模的时候就要坚持一个建模原则:尽全力使用最少的表面数来表现形体。
       A、方体:通常用来表现建筑的地板等部件,需要注意的不多,因为3DMAX在创建方体时,长宽高的分段默认就是1,总多边形数为12。若无特别的精致要求,例如倒角、圆滑等,那么长宽高的分段数要尽可能保持全1。反之如果有特别的精致要求的话,分段数能少则少,若能用2分段将就体现效果的话,就坚决不使用3分段。
       B、柱体:通常用来表现炮管等长部件,可以通过锥化或编辑网格演变成台体。这是个比较害人的形体,分段数和多边形数基本按照平方比例增减,3DMAX在创建柱体时,默认的分段情况是端面1分段、高度5分段、底面18边。总共的多边形数就是216。因此要尽可能地减少底面边数,同时高度分段只能取1。在不需要特别精致的情况下,4棱柱足够用来表现炮管。反之如果非要表现成圆柱,则12棱柱已经足够精细了。
       C、锥体:和柱体的处理基本相同,事实上柱体通过网格编辑也能演变成锥体,因此这里不再冗诉。
       D、球体:这是个最害人的形体,由于球体的分段数与多边形数呈三次方比例增减。3DMAX在创建球体时,默认的分段数是32分段,总共的多边形数就是960!已经远大于原版一个坦克的总多边形数了。因此无论如何要尽可能减小分段,一般来说,10分段已经足够用了,不到万不得已,切记不要使用10以上的分段数。某些时候也可以使用几何球体来代替球体绘制模型,在相同的精致程度上,几何球体的多边形数往往比球体更少,但是在编辑网格时不太容易处理,大家根据实际情况来选用吧。
       E、环体:和柱体的情况比较类似,也是平方比例增减,默认分段情况为24分段、12边,总多边形数就是576。其中分段表示底面边数,因此12分段就足够表现出圆环。边数则表示环截面的边数,通常使用4边就足够光滑了,不到万不得已不使用5边或6边。
       F、管体:这个是必须严禁使用的基本形体。事实上我们完全可以将管体做成柱体,而在贴图上画出黑洞来模拟“管口”的特殊效果。
       G、比较复杂的形体:这是需要高级建模技术才做得出来的东西,需要在各种基本形体的基础上频繁地使用网格编辑,为了减少面数,高手往往会删除原有的面,而自己重新创建新面来代替。因此我无法在这里进行讲解,你们自己去买书学3DMAX高级建模吧。
       H、输出W3D时的注意事项:除非你认为你的模型实在是简陋得比ZH的玩具级别还烂,否则尽量不要钩选“Smooth Vertex Normals”,这个功能会自动修正定点和法线的光滑程度,容易在一些无关紧要的细节上平白无故地增加很多多边形数,让原版已经简化完成的模型又变成了精致模型,那我们又何必去简化呢?

      不要忘了随时察看模型的总多边形数,为了确保游戏运行最低速度不低于30帧/秒,我实测了3个级别的大致简化要求,根据运行该游戏的电脑配置分别表示如下:
         A、6年前的古董电脑。即图拉丁赛阳1G或毒龙1G                MX440双64显卡或R8500双64显卡                DDR266-256M内存。
                  多边形要求:ZH级别(玩具级别)。即坦克不超过300,建筑不超过600,士兵不超过200
             B、3年前的淘汰配置。即P4HT2.4G或AMD2600+                FX5200双128显卡或R9550双128显卡        DDR400-512M内存
                  多边形要求:FK级别(仿真级别)。即坦克不超过1000,建筑不超过1500,士兵不超过400
             C、主流甚至豪华配置。即CORE2.0或AMD3800+                NF8400单256显卡或1950XT双256显卡        DDR667-1G内存
                  多边形要求:CNC3级别(工艺品级别)。即坦克不超过2000,建筑不超过4000,士兵不超过1000
             D、如果你的配置比上面的豪华配置还高出一大截,那么你可以承受RW级别(真实级别),即现代战争那种变态的精致程度。

(6)无所不能的UVW展开
       没贴过图的模型结构,通常称为“裸体”,你肯定会发现,一些高手制作的模型,只看裸体根本看不出有什么特别,甚至相当简陋,但贴上图之后却显得非常逼真。事实上这就是对游戏美工的一个最高难度要求——用最简陋的结构配上最细腻的贴图,来表现出足够精致的模型,因此专业的游戏美工有一个相同的认识,即3D游戏美工,最重要、且最有技术含量的是贴图,而非结构。
       贴图是3DMAX的一大基本功,但光是看书还不足以学成高级美工,而是需要花费3、5年时间去反复训练和提高的。可以想像,要是随便买本书来看完就可以干游戏美工工作的话,那么那么多游戏美工高手就都该饿死了。
       最牛的贴图方法是UVW展开,关于这个方法,几乎99%的3DMAX书本上都没有讲解,但它却是专业游戏开发中最实用的贴图方法。你可以将整个模型上各个面的图像用PS整合到一张图片上,然后贴给所有结构体,再将这些结构体的各个表面通过UVW展开,移动图片上各个合适的位置去“拼贴”,于是实际模型的表面上就会表现出具体的图像。关于UVW展开,在百度上能搜索到一些详细的教程,我收集到一个老外的金鱼视频教程作为附件,该教程详细地讲解了从0开始建模,到贴图、动画制作的全部操作过程,但由于体积巨大,因此我只能给出地址,你们自己去下载观看吧,我猜想你们在看完之后必定会汗颜——看一遍视频,胜读10年书。
http://www.086g.com/forum-cn/forum.php?mod=viewthread&tid=107689

(7)人物制作要点及W3D输出注意事项
      人物是一种最特殊的模型,所有士兵模型都要用这种方式来制作。看过3DMAX动画书籍的人应该知道,人物模型中通常都含有蒙皮和骨骼这两个概念,蒙皮受到骨骼上的各个关节点的牵引而产生随动的形变,于是产生了肢体动画。这里不便于仔细讲解骨骼的制作过程,你们自己去看书。我只讲解几点制作中的注意事项。
       A、    蒙皮:在制作蒙皮时,可以利用基本形体来进行网格编辑,分别制作出头、躯干、四肢、枪械武器等各个部件,然后将它们整合起来,转换成一个“可编辑网格”,作为蒙皮。当然一些3DMAX动画书籍上讲解的通常是专业方法,即建立一个长方体作基础,利用网格编辑通过复杂的手工分段、表面挤出、网格点焊接等逐步做成一个完整的人体。总之不管怎么样,能用尽量少的多边形表现出足够细腻的人体结构就行。
       B、    贴图:尽可能地用PS将整个人体上所有用得到的图像都整合到一张TGA上,将它贴到蒙皮上去。贴好之后你会发现整个人体上的图像是混乱的。不要紧,只要我们对蒙皮进行UVW展开并拼贴各个表面的位置,就能将贴图和蒙皮表面对应好。
       C、    所属色:由于士兵的模型是蒙皮,它是一个整体,因此无法使用类似于坦克、建筑的HouseColor%02d的方法来表达所属色区域。而经常使用PS的话,不难发现32位TGA是存在ALPHA通道的,这个通道通常用来区分一个TGA图像上的正常显示部分和全透明部分,即处于通道内的图像为正常显示,反之则是全透明,而通道边缘上的羽化区域则显示为半透明。因此SAGE利用TGA的这个特定来表达所属色,使士兵蒙皮上凡是出现了通道外图像的表面,统统显示为全透明。因此我们在保存士兵贴图时,一定要记得保存成32位TGA,否则将不支持ALPHA通道。此外TGA的命名也有讲究,SAGE规定,只有当TGA的文件名以小写的“zhca_”开头时,贴有通道外图像的表面将显示为纯净的所属色,否则,就显示为不可见。你们去观察一下原版ZH的士兵贴图文件就明白了,所有TGA的文件名总是有个小写的zhca_开头。
       D、    输出潜规则:3DMAX有个不成文的规定,那就是凡是被隐藏和冻结的部件是不会产生任何输出的,因此在输出W3D时,不要忘了恢复所有部件的显示和解冻。
       E、    蒙皮、骨骼、动作之间的关联:和坦克模型不同的是,士兵的蒙皮只由骨骼来控制,因此蒙皮需要和骨骼实现绑定。3DMAX可以提供两种空间扭曲用于绑定蒙皮和骨骼,分别是SKIN和WWSKIN,两者的用法大同小异,对于简模来说,后者更方便一些,附件里的骨骼动画制作教程里详细地讲解了如何绑定,这里就不再多说废话了。只需要严格注意以下几个要点:
      (a)     蒙皮只能钩选Export Geometry,并设置Geometry Option为Normal,千万不能钩选Export Transform。因为我们只需要它的形体图像,不能让它输出定位信息,否则会和骨骼发生冲突,导致人物动作不正常
      (b)    骨骼只能钩选Export Transform,千万不能钩选Export Geometry。因为我们只需要它的定位信息,不能让它输出形体图像,否则人物身上会出现一些不应该有的怪异部件
      (c)    绑定时,通常可以使用Auto-Link,可以快速将蒙皮上所有定点都自动绑定到最近的关节点上,但有时候会出现一些意外,即把错误的定点绑定到错误的关节点上,导致动作怪异,因此自动绑定完之后,要手工检查一下那些最密集的定点区域,试着进入“自动关键点”模式,移动一下关节点看看是否绑定到了不该绑定的定点,如果有的话,就要进行人工处理,选择这些绑定错误的顶点,Unlink,然后Link to Bome by Name或Link to Bome Selected。
      (d)    输出W3D时,一定要记得先输出SKL,然后才是输出SKN。
在输出SKL时,要选择Skeleton输出方式。
在输出SKN时,要选择Hierarichical Model方式输出,下面还要钩选“Export Using Existing”,并选取刚才输出的SKL。如果忘了的话,会丢失SKN和SKL之间的绑定,导致人物在游戏里呈现怪异动作或微动的T字形。
      动作动画是比较难做的东西,因为官方那些动作多数都是用光点捕捉器或动作生成器获取到的,而我们是在手工制作,所以可以借用原版里的一些现成动作,将它们略加修改弄成新的动作。导入动作动画时,3DMAX会自动提醒你伴随导入关联的SKL,因此你需要把动作动画和SKL放到同一个路径下,一导入动作,SKL就自动进入3DMAX了。修改好之后,不要忘了给所有关节点都钩选Export Transform,输出时选择Hierarichical Animated方式输出,下面还要钩选“Export Using Existing”,并选取刚才输出的SKL。如果设置错误的话,会使SKL不受动作的控制,导致人物在游戏里发生该动作时呈现纯静态的T字形。
      (e)     必须强调一点,动作动画的第0帧必须保存成基准帧,用来记录T字型基准姿势,并且不允许对它进行编辑,因此任何动作动画都只能从第1帧开始。这样我们可以在必要的时候把SKN导进来与关节点进行绑定,以检验我们做的新动作是否够自然。如果你没保留基准帧,那么绑定SKN的时候,你就找不到一个最合适的姿势,以至于容易出现绑定错误导致无法检验动作效果。
      (f)     如果你实在受不了这么麻烦的输出注意事项,建议你把士兵模型当作坦克来制作,即每个动作都包含完整的蒙皮、骨骼和动作,并整合起来Hierarichical Animated方式输出成单一的W3D,不要像官方那样拆分成相互关联的SKN、SKL和动作。这样做的好处在于输出设置可以偷懒,彻底避免了动作怪异、静态T字形和微动T字形的情况发生,但缺点就是最后得到的W3D含有重复的内容而占据了一些不必要的磁盘空间。
      F、    辅助体: ZH玩多了,可以发现一个现象,那就是我们在点选目标时,鼠标指针必须移动到有形体的部位时才能成功选中该目标。例如中国机场的跑道尽头有一个小缺口,如果你把鼠标移动到该缺口上时,是点不中机场的。这里要解释的是,SAGE规定,既输出形体图像,又输出定位信息的表面,才能被玩家选中。因此对于士兵模型来说,SKN和SKL都没有全钩Export Geometry和Export Transform,因此在游戏里是无法点选该士兵的。因此官方使用了一个隐形的辅助体带代替SKN被玩家点选,因此这个辅助体必须同时钩上Export Geometry和Export Transform,并且Geometry Option里要选择OBBox(辅助体),使之在游戏里不被渲染出任何图像。
      G、   常见错误分析
      (a)    纯静态T字形:一是忘了设置WWSKIN来绑定SKN和SKL;二是忘了给所有关节点钩上Export Transform。三是输出SKN时忘了钩选“Export Using Existing xxxx_SKL”;四是在输出动作动画时,输出方式选成了Hierarichical Model,五是在输出动作动画时忘了钩选“Export Using Existing xxxx_SKL”。
      (b)    微动的T字形:肯定是忘了取消SKN的Export Transform,导致SKN的位置信息由自身的中心点来控制,而不受SKL的控制,因此整个SKL上只有最靠近SKN中心点的那个关节点能发挥控制作用。
      (c)    怪异动作:主要是SKN的顶点和SKL的关节点关联错误。当然也可能是输出动作动画时钩选“Export Using Existing”时选用了另一个步兵的SKL。所以要处理好士兵模型很麻烦,要么就只换SKN,借用原版的SKL和动作,如果要更换SKL,就得把所有动作都重新导入,与新的SKL关联后再重新输出。
      (d)   士兵不能点选:肯定是忘了放置辅助体,要不然就是把辅助体隐藏了忘了在输出W3D前恢复显示。

      至此,基础阶段的教程就全部介绍完了,接下来留给各位作者有两条道路:
      1、    知难而退:SAGE引擎太复杂了,相信大多数作者看了这么久的教程,依旧是恍恍惚惚不知所谓,也做不出什么东西来,当然这也是正常的,无论学什么东西,教程都只能给你指点方向,具体如何去领悟真谛,必须要你们自己去深入研究。所以你们如果没兴趣作深入研究的话,我建议你们还是回TS去算了。
      2、   迎难而上:SAGE引擎确实复杂,但是未必就完全摸索不通,只要对自己有信心的人都应该明白为什么我发到818上的帖子叫“5个月的心血”了,要摸索透这样一个功能庞大的引擎,确实需要认真地花时间去进行走火入魔似的研究和测试,最后才能体会出各个功能模块、各条语句的作用,达到融会贯通,把教程上讲解的文字归纳为自己所能灵活运用的知识,从而制作出像《冲击波》、《五星之光》等那样有深度的好MOD。如果你准备好要迎接新的挑战,就请你继续向下面看,后面全都是高难度的进阶教程了。

                                                                                         <完>
发表于 2010-11-29 14:52:54 | 显示全部楼层
哗,眼花了。还有这等教材啊。顶了。
发表于 2010-12-22 00:21:55 | 显示全部楼层
好久之前的东西了
发表于 2012-1-11 14:09:04 | 显示全部楼层
看得我眼花。。。小试牛刀一下。。。
发表于 2012-9-19 14:03:23 | 显示全部楼层
yangqs 发表于 2010-11-29 10:46
第二章        建立一个新单位

      首先我以建立一个新单位——灰熊坦克为例,来讲解SAGE基本代码的结构 ...

RA3中单位建立在SDK哪个文件夹里
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|小黑屋|手机版|管理员邮箱|红警DIY官方论坛    

GMT+8, 2017-5-28 20:28 , Processed in 0.143318 second(s), 22 queries , Xcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表