游侠NETSHOW论坛

标题: 【国王的恩赐:戎装公主】MOD学,兵种MOD方向教程 [打印本页]

作者: merlin.zll    时间: 2009-7-7 01:30:37     标题: 【国王的恩赐:戎装公主】MOD学,兵种MOD方向教程

-1. 修改与更新

2009.07.07 - 07.08:修改了一下仙女的.txt文件引用方式,更新仙女示例包。
2009.07.08:调整了2、3章的内容分布。
2009.07.10:全文完,微调各章内容。
2009.07.13:更新了仙女示例包以支持pcbun大的封灵魔书MOD,详情请参见包内readme.txt。

0. 前言

戎装公主(AP)出来了,玩了几天后发现增加了这么多的兵种居然没有一个女性兵种,传奇(KB)时期想要凑齐一队5个全MM兵的怨念落空。郁闷之余动了自己创建一个的念头,经过一星期的学习研究(可怜我玩的时间都还没一星期),终有小成。看了一下论坛的帖子,虽然各种MOD的教程帖已经有不少,但比较完整而详细的兵种MOD介绍还是没有,于是有此文。
事先声明一下:虽然本教程内绝大部分内容都经过本人验证,但毕竟这些东西都是靠研究代码和猜测得来,难保有错,所以以下内容仅供参考。另外感谢游侠网所有的MOD教程帖作者。

OK,先放上教程使用的示例兵种(下载后请一定先看看fairy包内的readme.txt):
[attach]1977238[/attach]
[attach]1977239[/attach][attach]1977240[/attach][attach]1979171[/attach][attach]1977241[/attach]
其中fairy是新兵种本身的包,addon是一些附加的修改(比如修改物品和随从的设定以覆盖仙女这兵种,还有在艾伦大陆增加招募点等),test是增加英雄初始带100个仙女,方便测试。本MOD只是用于参考学习研究用途,可能会和其他正规的MOD冲突,请留意。
数值如下:
仙女:种族精灵 等级5 领导力需求1000 攻击力36 防御力45(防御后+10) 主动性8 移动力5 致命一击率12% 伤害30-40(魔) 近身30-40(魔) 生命值550 价格5000
抗性:魔50%
天赋:飘浮—战场上可以穿越比较低的障碍;不受反击—攻击敌人时不会受到反击;狙击—远程攻击无射程限制;无近战惩罚—生物在近战和远程攻击中造成同样的伤害;魔法抵抗—给予生物50%魔法抗性;美人—男性人形部队攻击时有30%机率因迷醉于其美丽的容颜而失手;净除—每回合开始行动时清除自身所有负面魔法。
技能:
召唤独角兽(3CD)—召唤总领导力为300-450的独角兽来为仙女战斗,直至其死亡或战斗结束。
复活(2CD)—复活一支友军部队中的阵亡者,回复50生命值,消耗英雄15点魔法值。对亡灵及恶魔无效。
流血精灵(0CD)(可开/关)—转换状态。当仙女全身心地投入战斗时,伤害和致命一击的机率上升200%,抗性增加30%,任何对仙女的攻击都会遭到30-40魔法伤害的反击,在仙女2格范围内的敌军部队主动性和行动力减半。相对的,战斗状态的仙女无法使用其他技能,并且每回合减少10%的生命值。

下面的内容大概分为6个部分:
1. 兵种MOD概要
2. atom(兵种模型描述)修改初步
3. 语言文件修改,模型(贴图)、兵种肖像、特技图标等修改
4. atom修改进阶,特技修改初步
5. 特技修改进阶
6. 其他杂项修改

[ 本帖最后由 merlin.zll 于 2009-7-13 00:24 编辑 ]
作者: merlin.zll    时间: 2009-7-7 01:31:57     标题: 兵种MOD概要

1. 兵种MOD概要

1.1 MOD原理
众所周知,AP和KB的游戏系统比较开放,于是有了各种MOD的存在。具体来说,就是在程序exe开始执行的时候,它会读取data和sessions目录下的所有内容,以此来初始化游戏所需的各种资源。这些资源包括了兵种、魔法、地图、英雄的模型、动画、背后的逻辑代码,还有界面和游戏的设定等等等等,总之是除了少数比较核心和基础的东西,其他的都暴露在外。而且,所有的资源都是以压缩包文件的形式放在目录里(就是那些.kfs文件),于是好事者们使用WinRAR之类的解压软件就能轻松取得里面的文件,同样地,也可以把MOD文件压缩成.zip格式,然后改后缀名为.kfs,一样有效(注意不能压成.rar格式)。最为神奇的是当玩家修改了这些游戏文件并放到这两个目录里的任一位置后,游戏开始执行的时候也会自动读取这些文件,并且会用修改版的文件取代相同文件的内容……
举个例子,改善视野和寻路MOD实际就是一个camera.txt文件,放在data\mods文件夹下,游戏启动时会自动读取,并且覆盖sessions\addon\ses.kfs里的camera.txt文件的设置。而界面数据详细显示MOD则是覆盖了sessions\addon\ses.kfs里的config.txt和若干.lua文件(1027227,戎装公主mod,http://game.ali213.net/thread-2673419-1-1.html)。
于是要做一个MOD,就是先解压出对应的游戏文件然后作相应修改,然后放到data目录下等游戏读取时覆盖原来的文件设定;或者是新建一些文件等游戏调用,以达到增、改、删的目的。

1.2 相关文件介绍
如前所述,用WinRAR打开各个.kfs文件,可以看到各种游戏用到的文件,其中data文件夹:
animation.kfs:主要装的是3D模型的动画(.bsa)(比如大法师施法时举起法杖一指的动作)。
data.kfs:包括兵种模型描述(.atom),各种兵的肖像、魔法的图标(.dds),图像注册文件(itextures.dat),图像alpha通道注册文件(textures.sub),用户界面定义(.ui),场景的3D模型(.bma,.cms,.csh),粒子效果(.ptb),镜头追踪(.track),动画鼠标(.ani)等等。
interface_textures.kfs:都是一些.png图像,用于游戏界面,界面MOD主力修改部分。
loc_data.kfs:一些改变游戏语言时需要更改的图,人家专门分开来方便我们汉化。
models.kfs:兵种和物件的3D模型相关文件,包括3D模型(.bma),3D场景?(.bms),碰撞检测数据?(.cms)。
sky.kfs:专门用于天空的3D模型(.bms)和贴图(.dds)。
sounds.kfs:音效文件。
textures.kfs:各种格式的纹理贴图文件(.png,.dds,.tga)。
还有sessions\addon文件夹内:
loc_ses.kfs:游戏用到的所有文字(.lng),同样人家专门分开来放方面汉化……
ses.kfs:各种设定(.txt),相当一部分脚本代码(.lua),地图设定(.loc),对话用的(.chat,.act),英雄数据(.hero),任务设定(.lu,.qst)。
据我所知,目前这些文件中的大部分我们都有能力修改,暂时还没办法修改的文件包括:.bsa,.bma,.cms,.csh,.ptb。对于兵种MOD来说,限制就是只能沿用已有的3D模型和动作效果。

1.3 调用流程
一个兵种,从游戏启动开始到出现在游戏里,大致流程是:
1)系统读取所有的.atom文件(注意是所有的,所以新建兵种的.atom文件不必在任何地方注册都会出现),以文件名作为系统内部使用的兵种名。比如我这里的仙女,用的是fairy.atom,fairy就是游戏系统内的兵种名。
2)系统会寻找和兵种名相应的肖像文件(兵种名.png)和野外兵模型描述(army_兵种名.atom)。所以如果我的兵种定义用了fairy.atom的话,那这两个文件就是fairy.png和army_fairy.atom。注意系统用到的所有图片,都有两种读取方式,这在第3章会详细讲。
3)系统读取你的.atom文件的内容,获取兵种的数据(攻击、防御、伤害值等等),获取3D模型文件名(模型名.bma);还有特技设定,包括特技用到的大小图标(*.png)、特技说明文本标识(在*.lng定义)、调用的脚本函数名(在*.lua定义)等等。
最后还有施展各种动作(攻击、施法等)时的动画、效果、音效等等文件,这些动作和效果文件暂时没法改,忽略之。
4)在3D模型文件(模型名.bma)会有纹理贴图的文件名(纹理名.dds),另外系统还会自动读取 collision_模型名.cms的碰撞检测文件。还以仙女为例,在fairy.atom里定义的模型文件为fairy.bma,所以系统读取fairy.bma和collision_fairy.cms,另外在fairy.bma里有定义纹理贴图名fairy_diff.dds。
5)到这一步,一个兵种,包括各种数值,可用技能,战场上的样子和动作等都齐备,可以显示在玩家面前了。而根据特技的设定,还需要在.lng文件定义说明文字,.lua文件定义相关的脚本函数等等。需要注意的是文本标识和脚本函数可以定义在任何文件里,也就是说.lng和.lua的文件名可以随便取(关于.lng文件的命名其实有限制,请参见第3章)。当然在仙女的例子里我把所有的定义都集中在fairy.lng和fairy.lua两个文件,方便管理。关于自定义技能、魔法会在第4、5章介绍
6)如果新建了特技(魔法)的,根据情况还可能需要增加魔法效果定义(比如说仙女的流血精灵)。相关的定义可以放在任何被items.txt所包含的文件里,引用的语法可以看sessions\addon\ses.kfs\items.txt的头几行:
==medals.txt
==hidden.txt
就是文件名前面加“==”,我是放在specials_fairy.txt,然后修改items_quest.txt包含它,最后因为items_quest.txt默认被items.txt包含,而达到引用的目的。而增加魔法效果定义又可能需要进一步定义对应的图标,脚本函数等等等等……

整个过程涉及文件很多,但可以看出中心点就是.atom文件,所以在第2章,我会介绍一下.atom文件的修改。

[ 本帖最后由 merlin.zll 于 2009-7-9 15:13 编辑 ]
作者: merlin.zll    时间: 2009-7-7 01:32:21     标题: atom(兵种模型描述)修改初步

2. atom(兵种模型描述)修改初步

首先要说的是:本章大量内容参考自kfkxzw 的《【KB修改教程一】自创&修改兵种》,http://game.ali213.net/thread-2114405-1-1.html,该帖内容已经很全,大家可以参考该帖互为补充。而对于该帖描述不清或者有误的地方在这里会有补充描述。
现在开始以仙女为例,开始我们的新兵种制作过程。既然是初步的修改,那我们就从已有的兵种开始。我们以林仙子为基础,找到data.kfs里的sprite.atom,开头的部分如下:

main {
  class=chesspiece // atom类型是兵种
  model=sprite.bma // 兵种用的3D模型
  cullcat=0
}
arena_params {
  features_label=cpi_sprite_feat // 兵种特性列表的文本标识符(对应.lng文件里的标识符)
  features_hints=soars_header/soars_hint,no_retaliation_header/no_retaliation_hint,magic_resistance_header/magic_resistance_hint,fire_weakness_header/fire_weakness_hint,discharge_header/discharge_hint // 每个特性的说明标识
  race=elf // 种族
  cost=20 // 招募价格
  level=1 // 等级
  leadership=9 // 领导力需求
  attack=4 // 攻击力
  defense=2 // 防御力
  defenseup=1 // 选择防御时增加的防御力
  initiative=5 // 主动性
  speed=4 // 速度
  hitpoint=9 // 生命值
  movetype=1 // 移动类型:0步行,1漂浮,2飞行,-2幽灵的移动方式(漂浮+穿越障碍?)
  krit=8 // 暴击率
  ooc=100 // 不明,不过貌似不管或者删除都没区别
  hitback=1 // 反击:1一次反击,2无限反击
  hitbackprotect=1 // 反击保护:0会受到反击,1不受反击
  attacks=moveattack,dispell // 攻击和特技列表,对应下面的名称
  posthitmaster=features_discharge // 每次攻击后调用的脚本函数名,这里的函数实现50%机会驱散被攻击的对手的状态
  resistances { // 各种抵抗力
    physical=0 // 物理抵抗力
    poison=0 // 毒素抵抗力
    magic=25 // 魔法抵抗力
    fire=-50 // 火焰抵抗力
}
// 以下列出和上面攻击和特技列表所对应的详细参数
  moveattack { // 最基本的近战攻击,必须有的
    ad_factor=1 // 意义不明(用于攻击还是防御?)
    damage { // 各种伤害值
      magic=1,3 // 魔法伤害1-3
    }
  }
  dispell { // 更多的攻击方式或特技,这里是驱散特技
    class=scripted // 这种攻击方式/特技需要调用脚本。
    attack_cursor=magicstick // 鼠标显示:magicstick魔法棒,attack普通攻击箭头
    script_attack=special_dispell // 特技调用的脚本函数名
    script_calccells=calccells_all_one_dispell // 特技调用前用于计算可选对象的函数名
    hinthead=special_dispell_head // 特技说明标题
    hint=special_dispell_hint // 特技提示
    moves=1 // 使用次数
    picture=BA1_Dispell_ // 特技按钮图标文件名,第3章会再说明
    picture_small=BA1_Dispell_small.png // 兵种属性窗里的技能小图标
    no_hint=1
  }
}
// 在这之后的内容基本上都是什么动作、效果之类的定义,基本上我们没必要也很难修改。保持别动就好了。

把sprite.atom复制出来,改名为fairy.atom,然后就可以开始我们的修改了。对比一下林仙子和仙女,在这一步我们至少可以把各种基础数值都改好。而对于攻击方式和特技,则可以参照其他的兵种做对应的修改。于是我们参考精灵射手(elf.atom)来做远程攻击,大法师(archmage.atom)来做能力增强技能,德鲁伊(druid.atom)来做召唤技能,圣裁官(priest2.atom)来做复活技能……东拼西凑之后的fairy.atom(拼凑版)文件大致如下:

main {
  class=chesspiece
  model=sprite.bma
  cullcat=0
}
arena_params {
  features_label=cpi_fairy_feat // 改了一下特性的标识符,这样就可以通过在.lng文件增加新内容来实现新的兵种特性描述,在第3章会详述。需要说明的是这个特性文本标识符和特性说明都是用于文本说明,并不起任何实际作用,也就是一个兵种有特性说明是魔免的,实际可能并不魔免。说明的文字要靠后面的各种参数和脚本等等的设定才能具体落实。
  features_hints=soars_header/soars_hint,no_retaliation_header/no_retaliation_hint,sniper_header/sniper_hint,no_melee_header/no_melee_hint,magic_protection_header/magic_protection_hint,beauty_header/beauty_hint,clear_header/clear_hint
  race=elf
  cost=5000
  level=5
  leadership=1000
  attack=36
  defense=45
  defenseup=10
  initiative=8
  speed=5
  hitpoint=550
  features=beauty // 增加特性:美人。其他的特性可以参考其他兵种,比如魅魔(demoness.atom)的demon恶魔,食人花射手(thorn.atom)的shot射手,eyeless目盲,plant植物,mind_immunitet精神魔法免疫等等。这一行的特性是会产生实际效果的,比如各种精神控制魔法对于features里面有mind_immuitet不起作用。
  movetype=1
  krit=12
  hitback=1
  hitbackprotect=1
  attacks=moveattack,shot,battle_mage,cast_bear,respawn
  each_turn_script=features_auto_dispell // 每回合轮到自己之前会自动执行的脚本,这里是大恶魔(archdemon.atom)的自动清除负面魔法
  resistances {
    physical=0
    poison=0
    magic=50
    fire=0
}
moveattack { // 近战攻击
    group=1,1 // 攻击分组,同组的攻击会根据情况有选择地触发。这里近战攻击属于第1组第1种攻击
    nonextifenemy=1 // 只用于近战
    ad_factor=1
    damage { // 近战时的伤害
      magic=30,40
    }
  }
  shot { // 远程攻击
    group=1,2 // 攻击分组和近战同为1组,第2种攻击
    class=throw // 攻击类型为远程攻击
    base_attack=1 // 暴击:0不能暴击,1可以暴击
    ad_factor=1
    distance=100 // 射程(就是多于多少格后鼠标显示折断的箭),因为是狙击,所以写个超越战场范围的100
    mindist=2 // 最短射程
    showdmg=1
    penalty=1 // 超过射程后的伤害比例,比如是原来的50%那就是0.5
    animation=cast/throw/thtarget // 攻击的动作
    //throw=priest2_ball // 扔的东西(这里是圣裁那红球,因为看上去怪而被注销掉了)
    framekey=x // 关键帧?反正跟动画和动画的时间控制有关,具体不明
    damage { // 远程攻击的伤害值
      magic=30,40
    }
  }
  battle_mage { // 大法师的战斗法师
          class=scripted
          script_calccells=
    script_attack=special_battle_mage_attack
    endmove=0 // 使用该特技后是否结束行动,0为不结束
    picture=BA1_Battle_Mage_
    picture_small=BA1_Battle_Mage_small.png
    reload=3 // 冷却时间,是实际介绍的CD + 1,因为施展特技的当回也算一回合
    hinthead=special_battle_mage_head
    hint=special_battle_mage_hint
    custom_params { // 特技所调用的脚本函数还有特技描述所用到的特殊参数。我的理解:并不包括kfkxzw帖子说的“设定的触发攻击方式&几率”
            duration=2 // 持续时间
            power=100 // 加成
            penalty=50 // 防御降低
            type=bonus
            shock=50
            krit=15
          }
  cast_bear { // 德鲁伊的召唤熊
    class=scripted
    hinthead=special_cast_bear_head
    hint=special_cast_bear_hint
    reload=3
    warning=sw_place // 当没有可用施法对象时的提示文字标识符,这里指周围没有空位时的提示
    script_attack=special_cast_bear
    script_calccells=calccells_all_empty_around // 计算施法对象的脚本,这里是找到周围所有空位
    picture=BA1_CastBear_
    picture_small=BA1_CastBear_small.png
    attack_cursor=magicstick
    anim_attack=cast
    custom_params {
      count=20-25 // 召唤的熊的领导力
      caster=5
    }
  }
  respawn { // 圣裁官的复活
    class=scripted
    attack_cursor=magicstick
    hint_gen_script=respawn_hint
    always_hint=1
    warning=warning_resurrect
    picture=ba1_resurection_
    picture_small=ba1_resurection_small.png
    hinthead=special_prist_res_head
    hint=special_prist_res_hint
    nfeatures=undead,magic_immunitet,pawn,boss,plant,golem,demon // 不能使用的对象,这里列出的和上面的features对应,也就是说如果某个兵种的features=plant,那这复活技能就不能使用在它身上。
    moves=1
    script_calccells=calccells_all_need_resurrect_ally_simple
    script_attack=special_presurrect
    custom_params {
      heal=7 // 复活增加的生命值
    }
  }
  // 以下定义动作效果之类的和原来的sprite.atom相同

有了这拼凑版的fairy.atom和第3章要讲的相关语言和肖像文件,再稍微调整一下每个技能的custom_params设定,我们就有了一个会使用战斗法师、召唤熊、复活特技,还能远程攻击的仙女了。而进一步对特技的修改和定制将在第4和第5章介绍。

[ 本帖最后由 merlin.zll 于 2009-7-9 16:24 编辑 ]
作者: merlin.zll    时间: 2009-7-7 01:32:43     标题: 语言文件修改,模型(贴图)、兵种肖像、特技图标等修改

3. 语言文件修改,模型(贴图)、兵种肖像、特技图标等修改

3.1 语言文件
语言文件(.lng)负责定义游戏里出现的所有文本。在游戏加载时,游戏会自动读取data和sessions文件夹内的“语言_*.lng”文件名的语言文件,因为AP现在只有俄文版,所以游戏读取的是所有rus_*.lng文件。之前的KB因为有英文和俄文版,所以可能出现文件名为rus_*.lng的文件无法被英文版自动读取的错误。
游戏里的语言文件都放在sessions\addon\loc_ses.kfs内,这里节选出相关的一些部分:
rus_units.lng:
cpn_sprite=林仙子
cpsn_sprite=林仙子
rus_units_specials.lng:
special_battle_mage_name=聚能一击
special_battle_mage_head=^special_tC^[Good]
special_battle_mage_hint=^special_t^大法师全身心地投入战斗 [duration] 回合.伤害、麻痹和致命一击的机率上升 [power%],自身防御力降低 [penalty%].此技能持续时无法使用其他技能.
special_battle_mage_small=^special_t^增强大法师的攻击能力.
special_cast_bear_name=召唤熊
special_cast_bear_head=^special_tC^[Good]
special_cast_bear_hint=^special_t^召唤 总领导力为 [summon2] 的熊来为德鲁伊战斗,直至死亡或战斗结束.
sw_place=没有空位来召唤生物!
rus_units_features.lng:
cpi_sprite_feat=        飘浮        ,         不受反击        ,         魔法抵抗        ,         畏火        ,         遗忘.
fire_weakness_header=^def_hint_t0^畏火
fire_weakness_hint=^def_hint_t1^火焰造成150%伤害.

从这些例子我们可以看出这些条目的格式大致是:

标识符=^标识类别(可选)^实际描述

而标识符和atom文件里的定义一一对应,比如在sprite.atom里有:
features_label=cpi_sprite_feat
那么在rus_units_features.lng就有对应的:
cpi_sprite_feat=        飘浮        ,         不受反击        ,         魔法抵抗        ,         畏火        ,         遗忘.

回到我们的拼凑版fairy.atom,因为我们新定义了兵种,所以我们增加rus_fairy.lng文件,加上如下内容:
cpn_fairy=仙女
cpsn_fairy=仙女
cpi_fairy_feat=        飘浮        ,         不受反击        ,         狙击        ,         无近战惩罚        ,         魔法抵抗        ,         美人        ,         净除.

头两行cpn_兵种名 和cpsn_兵种名 负责在游戏不同情况下显示兵种名(属性窗口和小提示窗口?)。反正只要新建了一个 兵种名.atom文件,就需要在语言文件定义对应的cpn_兵种名 和cpsn_兵种名。另外因为我们在atom文件的“features_label=cpi_fairy_feat”修改了一下特性说明,所以还需要定义cpi_fairy_feat。注意每一个特性前后需要增加一个tab(制表符),并且中间用逗号分隔。而且特性数量要和atom文件下一行的“features_hints=”数量和顺序一一对应,不然会出现显示错误甚至直接弹出。以后修改特技名称和说明也大致相同,就是在你的新语言文件内增加新的标识符,并参照已有的定义的格式来修改即可。

3.2 肖像、图标等
下一步我们可以自定义兵种的肖像,基本上游戏有两种方式读取图像:
1)直接根据文件名读取,比如需要fairy.png而在data或sessions目录内又有fairy.png这个文件存在。
2)从data.kfs内的itextures.dat内读取相关的位置等信息,然后去分隔相应的.dds文件得到。
关于第2种方式,在rustdragon的《[国王的恩赐]自定义头像完美显示方法》,http://game.ali213.net/thread-2120541-1-1.html里有说明。游戏之所以采用这种麻烦的方式,估计是为了提高读取游戏所需的大量小图像(比如魔法效果图标、各种按钮等)的效率。对于MOD来说,采用这种方式需要修改itextures.dat,并不绿色还增加冲突的机会。所以建议还是直接采用方式1好了。
对于新建的兵种,游戏至少需要 兵种名.png作为兵种的肖像,所以我们准备一张120*153的fairy.png文件即可。另外如果想使用新的特技图标,还需准备图片若干,具体在第4章atom进阶修改的时候详细说。

3.3 3D模型文件
如果想为仙女换身新衣,可参考feisuoleishy 的【国王的恩赐】精灵公主_梦萝仙子造型&数值MOD,http://game.ali213.net/thread-2096811-1-31.html(注,本文的仙女肖像和纹理贴图都来自该帖),准备一张类似该帖中的.dds纹理贴图。游戏原有的纹理贴图在textures.kfs内,可以以它们为基础修改。
而在models.kfs内的3D模型文件*.bma,暂时还无法修改(在国外有个帖子在讨论bma的格式,可惜貌似还没结论,有能力的可以看看:http://forum.xentax.com/viewtopic.php?f=16&t=3485)。
虽然我们没法修改.bma模型,但改变文件内注册的.dds纹理贴图还是可以的,用Ultraedit打开sprite.bma,搜索sprite_diff.dds可以找到2处类似如下的内容:
[attach]1980518[/attach]
其中最前面的0F 00 00 00表示纹理文件名的长度,后面就是纹理贴图文件名。假设我们有了fairy_diff.dds文件,那么可以把sprite.bma复制一份改名为fairy.bma,并且把两处都对应修改为如下内容:
[attach]1980519[/attach]
这样fairy.bma就会调用我们新的fairy_diff.dds作为它的纹理贴图了。有了bma和dds后,我们修改fairy.atom的第3行:“model=sprite.bma”为“model=fairy.bma”就有了穿新衣的仙女。
最后对于fairy_diff.dds,因为它使用了alpha通道来做透明效果(比如蝴蝶翅膀后面的那部分),所以还需要在textures.sub文件内注册,以告诉系统使用图片的alpha通道。具体就是在复制出来的textures.sub文件最后加上一行:
fairy_diff.dds 1
很遗憾貌似只能在textures.sub文件内添加alpha通道信息,所以本文件是到目前为止第一个违反绿色原则,可能造成冲突的文件。

3.4 其他一些需要的文件
到这一步,基本上我们的拼凑版仙女在玩家方面已经可以使用了。但是对于野外兵,如果也有仙女的(特别是有仙女带队的),还需要 army_兵种名.atom和collision_兵种名.cms。前者是该兵种在野外的速度等参数,后者可能是碰撞检测用(不确定,反正没有它的话在野外鼠标右键点击兵种不能看到部队信息)。
于是我们把data.kfs\army_sprite.atom和models.kfs\collision_sprite.cms两文件复制出来,改名为army_sprite.atom和collision_fairy.cms就搞定。

[ 本帖最后由 merlin.zll 于 2009-7-9 17:50 编辑 ]
作者: merlin.zll    时间: 2009-7-7 01:33:05     标题: atom修改进阶,特技修改初步

4. atom修改进阶,特技修改初步

如果不满足于拼凑出来的兵种,想为新兵种添加新特技的话,那么我们就需要lua脚本的帮忙了。Lua是一种相对比较简单灵活的编程语言,因此被很多游戏所采用。本章和第5章会讲下游戏的一些lua脚本API,以达到修改或新创特技的目的,建议有编程基础的人观看。
开始前还要说说调试的环境,对于脚本调试,建议使用开发模式(在1027227的《国王的恩赐》开发模式全解析,http://game1.ali213.net/thread-2260892-1-1.html有详细介绍)。这不仅是因为开发模式下那些杀兵之类的作弊设定可以创造需要的测试条件,而且在脚本有错的时候,游戏会弹出窗口指出:xxx.lua第n行的什么原因出错,而在普通模式下游戏并不会显示任何错误提示。

4.1 继续atom修改
首先还是要先回到之前的拼凑版fairy.atom,讲下之前没讲的特技设定,摘抄召唤熊的部分如下:

  cast_bear {
    class=scripted
    hinthead=special_cast_bear_head
    hint=special_cast_bear_hint
    reload=3
    warning=sw_place
    script_attack=special_cast_bear
    script_calccells=calccells_all_empty_around
    picture=BA1_CastBear_
    picture_small=BA1_CastBear_small.png
    attack_cursor=magicstick
    anim_attack=cast
    custom_params {
      count=20-25
      caster=5
    }
  }

这里我们想把召唤熊改成召唤独角兽,实现脚本暂且不说,首先比较容易修改的就是图标和文字说明。文字说明之前已经说过,比如在这里修改了:
    hinthead=special_fairy_unicorn_head
    hint=special_fairy_unicorn_hint
那么就需要在语言文件(rus_fairy.lng)中添加对应的:
    special_fairy_unicorn_name=召唤独角兽
    special_fairy_unicorn_head=^special_tC^[Good]
    special_fairy_unicorn_hint=^special_t^召唤总领导力为 [summon2] 的独角兽来为仙女战斗,直至其死亡或战斗结束.
注意除了_head和_hint之外还有对应的_name,另外_head那条的[Good]表示特技是增强自己的(说明文字为绿色),[Bad]表示削弱敌人(说明文字为红色)。
而_hint那条的[summon2]会经过ses.kfs\special_hint.lua的计算得出对应的数字,对应的代码为:
  if par=="summon2" then
    local count_min,count_max = text_range_dec(apars.custom_params.count) --从atom文件中的custom_params里的count参数中提取最小和最大值(拼凑版的话是20和25)
    local unit_count=AU.unitcount(unit) --该队兵的数量
    text = math.floor(count_min*unit_count*(1+tonumber(skill_power2("summonner",1)/100))).."-"..math.floor(count_max*unit_count*(1+tonumber(skill_power2("summonner",1)/100))) --总领导力为20*数量到25*数量再加上召唤者能力加成
end
可见特技的custom_params里的参数名和提示数量的计算是对应的,可以查看special_hint.lua寻找合适的计算方法。
然后还有的是特技图片,新文件里修改的对应两行变成:
    picture=BA1_SummonUnicorn_
picture_small=BA1_SummonUnicorn_small.png
其中picture是屏幕右下角的特技按钮所用,共需要4幅,分别代表正常(normal)、鼠标悬停(onmouse)、鼠标按下(onpress)和不可用(disabled)四种状态,分辨率为43*44。贴上图就一目了然了:
BA1_SummonUnicorn_normal.png[attach]1980912[/attach]
BA1_SummonUnicorn_onmouse.png[attach]1980913[/attach]
BA1_SummonUnicorn_onpress.png[attach]1980914[/attach]
BA1_SummonUnicorn_disabled.png[attach]1980915[/attach]
picture_small则是兵种属性里用到的小图标,分辨率为26*26:
BA1_SummonUnicorn_small.png[attach]1980916[/attach]

最后需要特别提醒的是最好不要太多手去修改系统用特技名(第一行的cast_bear),改了虽然对玩家影响不大,但看看负责电脑AI的ses.kfs\arena.lua,第1546行:
        elseif name == "cast_thorn" or name == "cast_bear" or name == "cast_demon" or …
可以知道AI是根据特技名来使用特技的,对于新特技名(比如summon_unicorn),AI轻则不会使用,重则胡乱使用,直接导致游戏出错,所以就让电脑像召唤熊一样召唤独角兽就好了。

最后就是修改调用的脚本函数名了,看原atom文件的:
    script_attack=special_cast_bear
script_calccells=calccells_all_empty_around
其中script_calccells是在按下特技按钮时计算可以施展的目标的,而script_attack则是在施展特技时调用。修改成自己的函数名就可以实现新的特技了,对于召唤独角兽,我们仍然沿用calccells_all_empty_around来找到周围的空格,而定义新的特技函数:
script_attack=special_summon_unicorn_attack

最最最后对于atom文件还需要补充说明下在我们一直忽略的atom后半部分,有类似于:
animations {
  idle=/t:1:4:idlemain:1:1:rarelist
  rarelist=/fwd:1:rare
  idlemain=sprite_idle.bsa/fr:25:50
  rare=sprite_rare.bsa/fr:25:50
  attack=sprite_attack.bsa/fr:35:70
  move=sprite_move.bsa/fr:25:50
  start=sprite_start.bsa/fr:25:50
……
的几行,罗列出该兵种所有的动作名(idle,rare,attack等),这些动作名会在后面的脚本中用到。

4.2 初步修改lua脚本函数
之前说过,所有.lua脚本都是放在ses.kfs里的,而游戏启动时会读取所有后缀为.lua的文件。为了我们的新特技,我们新建个fairy.lua文件,并从ses.kfs\special_attacks.lua复制来召唤熊的代码(注:删去了部分不起作用的代码):

function special_cast_bear()
  local target = Attack.get_target() --找到施法的目标位置
  Attack.aseq_rotate(0,target) --让仙女的朝向转向目标位置
  Attack.act_aseq( 0, "cast" ) --让仙女做cast动作(动作名和atom文件罗列的对应)
local dmgts = Attack.aseq_time(0, "x") --得到一个动作的结束时间
--下面这几行计算新召唤的独角兽的朝向,朝向最近的敌人
  local nearest_dist, nearest_enemy, ang_to_enemy = 10e10, nil, 0
  for i=1,Attack.act_count()-1 do
    if Attack.act_enemy(i) then
      local d = Attack.cell_dist(target,i)
      if d < nearest_dist then nearest_dist = d; nearest_enemy = i; end
    end
  end
  if nearest_enemy ~= nil then ang_to_enemy = Attack.angleto(target, nearest_enemy) end
  local count=Attack.act_size(0) --得到仙女个数
local min_count,max_count=text_range_dec(Attack.get_custom_param("count")) --从atom文件对应的custom_params里的count参数中得到最小最大领导力,注意这种atom的custom_params和脚本函数的联系
--随机选择熊的种类,普通熊和远古熊各50%
  local type_bear=Game.CurLocRand(1,100)
  local count_summon=0
  local unit_summon=""
  if type_bear<50 then
    unit_summon="bear2"
  else
    unit_summon="bear"
  end
count_summon=math.max(1,math.ceil(Game.CurLocRand(min_count*count*(1+tonumber(skill_power2("summonner",1)/100)),max_count*count*(1+tonumber(skill_power2("summonner",1)/100)))/Attack.atom_getpar(unit_summon,"hitpoint"))) –在最小和最大范围内随机生成召唤数量,这里貌似和技能描述不符,使用了HP而不是领导力来计算数量
Attack.act_spawn(target, 0, unit_summon, ang_to_enemy,count_summon) --在目标格子上生成熊
--这段是动画显示用
  Attack.act_nodraw(target, true) --先不显示新出来的熊
  local t = Attack.aseq_time(0) – dmgts –计算个适当的显示时间
  Attack.act_animate(target, "castbear", dmgts) --让熊做castbear动作
Attack.act_nodraw(target, false, dmgts) --同时显示新出来的熊
--在记录窗口记录相关时间
  Attack.log_label("add_blog_summon_")
  Attack.log_special(count_summon)
  return true
end

从这个例子我们可以看出lua函数主要有两个方面的功能:在后台计算并实施各种能力、数量、伤害等数值的增减;在前台控制动画显示和战斗记录。
只要看懂了源文件,修改起来并不是什么难事,既然是召唤独角兽,那可以修改选择熊的种类那段为:
  local type_bear=Game.CurLocRand(1,100)
  local count_summon=0
  local unit_summon=""
  if type_bear<50 then
    unit_summon="unicorn2"
  else
    unit_summon="unicorn"
  end

最终出来的就是白独角兽或黑独角兽。另外对于仙女(实际上是她的原型林仙子),施法时候的动作用special(就是林仙子使用驱散时那旋转n周的动作)比cast好看。而独角兽也没有castbear动作,于是修改相应的几行变成:

Attack.act_aseq(0, "special") --让仙女使用special动作
……
local t = Attack.aseq_time(0) - .3
local dFadeoutTime = 1 --淡出时间1秒
Attack.act_nodraw(target, true)
Attack.act_nodraw(target, false, t)
Attack.act_animate(target, "teleout", t) --独角兽使用teleout动作
Attack.act_fadeout(target, t, t + dFadeoutTime, 1) --同时淡出

总之,通过多看代码多猜测小心调试,就能够制作出自己的特技。

[ 本帖最后由 merlin.zll 于 2009-7-9 23:17 编辑 ]
作者: merlin.zll    时间: 2009-7-7 01:33:21     标题: 特技修改进阶

5. 特技修改进阶

到了这一步,其实对于lua特技脚本其实已经没太多可以说的了,对于lua的MOD,难点就在于猜测并理解游戏里的代码。有趣的是,从游戏的注释中可以看到,就算是游戏的开发者,面对某些奇怪的参数什么的也会觉得困惑,更别说是完全没有文档的我们了。在这一章我会简要介绍下我对游戏代码的理解,以供参考。因为我也没有做太深入的研究,所以如有错漏请多多包涵。

5.1 调用结构和时机以及对应的函数约定
在前面提到过atom里就提供了好几个函数调用的设定,据我所知的有如下几种:
each_turn_script=ets_function
在每回合轮到该兵种行动的那一刻调用,代表为unit_features.lua的features_auto_dispell(大恶魔的净除特性)。一般返回true。

posthitmaster=phm_function
在该兵种攻击别人的那一刻调用,代表为unit_features.lua的features_poison(刺客的毒汁特性)。函数参数为:
function phm_function(damage,addrage,attacker,receiver,minmax,userdata,hitbacking )
其中:
damage猜测为伤害计算到函数调用时刻的伤害值
addrage猜测为函数调用时刻的怒气增加值
attacker为攻击者
receiver为被攻击者
minmax猜测是用来判断是否实施了攻击(经测试电脑AI考虑攻击时函数可能会被调用,此时minmax值为3,而实际实施了攻击后调用的函数minmax值为0)
userdata不明
hitbacking是否是反击
约定的返回值一般为damage, addrage

posthitslave=phs_function
在该兵种被被人攻击的那一刻调用,代表为unit_features.lua的bear_slave(熊的兽性特性)。函数参数和返回值约定posthitmaster一样。

特技/魔法的:script_attack=sa_function
在施展该特技时调用,代表为special_attacks.lua的cast_bear(德鲁伊的召唤熊特技)。上一章已经详细分析了,一般返回true。

特技/魔法的:script_calccells=sc_function
在施展特技/魔法前用于计算可选对象,代表为spells_common.lua的calccells_all_empty_around(召唤时找出周围所有空格),一般返回true。在calccells_all_empty_around中,周围有空位的话会用Attack.marktarget()标记,没有的话就不标记任何格子,无论如何都返回true。

另外,在各种状态(比如中毒,定义的格式可以参照effects.txt的69-102行effect_poison)中也可以定义每回合调用的脚本(each_turn_attack):
script_attack=eta_function
调用时机也是在每回合轮到该兵种行动的那一刻,代表为spell_effects.lua的effect_poison_attack(中毒状态)。函数参数为:
function eta_function(target, pause, duration, attacker)
参数意义没研究过,一般返回true。

同时在状态结束(持续时间到,被驱散,或兵被杀死等)时也可以增加函数调用(参照effects.txt的202-231行effect_sleep)。
onremove=or_function
代表为spell_effects.lua的sleep_onremove(睡眠状态)。函数参数为:
function or_function(caa, duration_end)
其中:
caa为解除状态的单位
duration_end不明,是否因为持续时间到而结束?
约定的返回值一般为true。

5.2 简陋且不完整的API
稍微研究下lua代码,就可以发现系统里有几个内置的对象,比如Attack,Logic等,系统通过这些对象提供各种操作的接口。遗憾的是系统封装了这几个对象的代码,也没有任何的API文档留下,所以对于这些接口函数的作用我们只能通过已有的代码来猜测。以下是一些我研究过程中经常碰到或者用过的函数,姑且作为一个简陋且不完整的API参考:

Attack对象:操作当前的这次攻击
Attack.get_target():得到攻击对象的index,index几乎就可以视作是一个对象,下面所有idx开头的参数都可以使用这个index来调用。另外一般来说index=0的对象就是调用函数的那个兵,比如某兵被攻击调用了posthitslave,那么在该函数里index=0的就是被攻击的兵
Attack.aseq_rotate(idx_actor, idx_target):使idx_actor的朝向转向idx_target。
Attack.act_aseq(idx, action):在idx的动作序列里面增加action动作并立即返回(程序会有专门的另外线程处理动作,会按照动作序列一个个播放)。
Attack.aseq_time(idx, “x”):后面的”x”参数可选,没有的时候貌似是返回当前的动作序列时刻;有的话貌似返回执行一个动作的时间。总之这个函数的返回值是用于控制动作的时间的(比如希望仙女执行完施法动作后独角兽才开始出现)。
Attack.act_enemy(idx, bel),Attack.act_ally(idx, bel):敌我判断,其中bel省略时判断idx和当前对象?(index=0)的关系。bel一般为Attack.act_belligerent()的返回值。
Attack.act_belligerent(idx, bel):bel省略时返回idx的当前敌视方?bel不省略时设置idx的当前敌视方?(用于类似魅惑这种情况)。、
Attack.act_size(idx):返回idx的数量。
Attack.act_totalhp(idx):返回idx的总血量。
Attack.act_get_par(idx, par):返回idx的各种属性(比如par=”initiative”时返回主动性)。
Attack.atom_spawn(idx, t, atom):在t时刻在idx的位置生成一个atom对象(一般用来生成一些特效之类一次性的东西),atom为atom文件名,比如雷击效果可以是Attack.atom_spawn(idx, 0, "effect_lightpower")。
Attack.act_spawn(idx, t, atom, ang, size):在t时刻在idx的位置生成atom对象(一般用来生成召唤出来的兵),size为数量,ang为朝向。
Attack.cell_resurrect(idx, hp, t):在t时刻复活idx,hp为复活的血量。
Attack.get_custom_param(par):读取特技对应的custom_params里的参数,par指定参数名,注意返回值为string类型,可能需要用类似tonumber()之类的函数转换类型。另外对于类似“count=10-20”这种可以用text_range_dec()来得到min,max。
Attack.val_store(idx, par, val),Attack.val_restore(idx, par):把数值存储在idx所指的那个兵上,par指定值的名称,val指定值。
Attack.act_apply_spell_begin(idx, effect, dur, false),Attack.act_apply_spell_end():标记着开始在idx身上增加一个状态,在_begin和_end中间可以加上若干个Attack.act_apply_*_spell()作为状态持续过程中改变的各种能力,在状态消除后这些能力加成/减弱会自动消除。effect为状态名,和effects.txt中的名字对应,如effect_burn。dur为状态持续回数,dur为-100表示永远持续。最后的false意义不明,我见到的都是false。
以下3个函数是用于Attack.act_apply_spell_begin()和Attack.act_apply_spell_end()中间的几个代表函数:
Attack.act_apply_dmgmin_spell(par, bonus1, bonus2, 0, dur, false):修改最小伤害值,par为伤害类型(如physical物理伤害),增加的值为原值增大bonus2%最后加上bonus1。dur为持续时间,0和false意义不明。
Attack.act_apply_par_spell(par, bonus1, bonus2, 0, dur, false):修改一般的参数(比如par=”krit”暴击率),算法同上
Attack.act_apply_res_spell(par, bonus1, bonus2, 0, dur, false):修改抵抗力,par为抵抗类型。
Attack.act_posthitslave(idx, func, dur):为idx增加一个posthitslave的函数(被攻击时会调用),func为函数值(string类型)。dur省略时为无限持续时间,为0时立即取消。
Attack.act_spell_param(idx, effect, par, val):为idx的effect状态存取参数值,该值存在idx所指的兵的effect状态里。par指定参数名,val不省略时存储val,省略时返回之前存储的值。
Attack.act_del_spell(idx, effect):去除idx的effect状态,effect省略时去除所有状态。
Attack.act_enable_attack(idx, attack, enable):允许/禁止idx的某种特技,attack为特技名,enable为true时允许,false时禁止。
Attack.resort(idx):根据主动性重新排列行动的先后顺序(一般在类似召唤了新兵的场合使用)。
Attack.atk_set_damage(type, dmg),common_cell_apply_damage(idx, t):两个函数连用对idx造成伤害,类型type和伤害值dmg需要先由Attack.atk_set_damage()指定,进而用common_cell_apply_damage()指定伤害的对象和时间。

Logic对象:大概是存储着游戏的一些共用变量和参数,我没研究,还是不说了。

AU对象:没用过。

Game对象:只见过两个函数。
Game.CurLocRand(min, max):在min和max之间产生随机数。
Game.GVNumInc(par, val):增加记录参数,par为参数名,val为增加的值。比如在spell_effects.lua中effect_poison_attack就有中毒后使用Game.GVNumInc("burn_poison_enemy", 1)增加中毒和点火记录的(勋章啊)。

显然这里列出的函数是很不全的,而且部分参数和返回值也还不明朗,真正修改时还是需要多看代码多研究。

[ 本帖最后由 merlin.zll 于 2009-7-10 03:36 编辑 ]
作者: merlin.zll    时间: 2009-7-7 01:33:49     标题: 其他杂项修改&后记

6. 其他杂项修改

经过前面的过程,一个新建的兵种应该已经成型,剩下的工作并不是必须的,只是为了让它更好地融入到游戏里。这里的各种修改在别的帖子里都有介绍,且不属于兵种修改的主要工作,所以这里就不详述了。
首先遇到的疑问就是新兵种会不会出现在游戏里呢,答案是肯定的:新兵种和系统原有的兵种一样,都会进入到游戏的随机可能里。而游戏里的野外兵和商店的兵是会有类似精灵族兵种随机这样的设定,因此新建了兵种后只要新开游戏,新兵种就可能会出现(当然RP可能要好点)。如果觉得这种出现机会太低的话,可以参考rustdragon 的《KB在游戏中添加招募自定义兵种方法》,http://game1.ali213.net/thread-2110743-1-2.html,修改对应的地图数据库文件(*. embryos.loc)。进一步利用shadow1983的《KB:MOD教程》,http://game.ali213.net/thread-2670790-1-1.html中提供的KB_DB_EDIT工具把.loc文件编译成比较容易理解的文本文件,修改好后再编译回去。
最后还可以修改下ses.kfs里的一些txt文件,比如英雄的初始兵hero.txt,相关的宝物设定items.txt(比如公主套装的效果增加覆盖仙女),随从设定companion.txt(agvares的攻击加成),士气设定morale.txt(独角兽增加的士气)等等,不一而足。需要注意的是这些修改很可能和其他MOD造成冲突,个人觉得这些附加的修改就自己改来用用就好。


7. 后记

基本上做MOD就是反复研究猜测修改试验的过程,希望本文能对有志做兵种MOD的人起到一点微薄的帮助,节省一些研究的时间。最后再声明一次:本文的内容都是基于个人推测,难免会有错漏,仅供大家参考。
完。

[ 本帖最后由 merlin.zll 于 2009-7-10 03:46 编辑 ]
作者: mmamma    时间: 2009-7-7 07:46:08

仙女是远程?还有狙击 .....
作者: merlin.zll    时间: 2009-7-7 09:17:35

原帖由 mmamma 于 2009-7-7 09:46 发表
仙女是远程?还有狙击 .....

关于仙女的能力,特性,数值什么的就将就一下啊。
我做这个MOD纯粹用来做实验用,当初是想看看把原来的近战兵改成远程兵会怎样来着…… [汗水]
另外仙女能远程攻击并且不受距离影响我觉得也不算太不合理吧?虽然事实证明电脑用这兵的时候还是挺恶心的,高主动还远程狙击,大大影响无损。
作者: latitude    时间: 2009-7-7 10:48:25

很有的研究贴!帮助很大
楼主继续阿 什么时候填坑呢?
作者: york144122    时间: 2009-7-7 17:49:23

哇 这是大容量的研究啊。。。哈哈
作者: 旅思    时间: 2009-7-8 18:12:02

电脑也会有这兵? 数量按他的领导力来还是这么样?
作者: merlin.zll    时间: 2009-7-8 18:53:13

原帖由 旅思 于 2009-7-8 20:12 发表
电脑也会有这兵? 数量按他的领导力来还是这么样?


野外兵是随机的,只要你新加了这种兵,重新开始游戏的话,是有机会随机出来的。比如某地方一个野外兵的随机设定是elf或orc的5级兵,那新建游戏的时候就有机会随机出它。兵力按设定的领导力吧。我加了之后新开几次游戏在艾伦大陆都会碰到仙女,数量大概是1x到2x个之间(普通难度)。
作者: xcz1984    时间: 2009-7-9 00:00:11

留个名,以后再看。。。。。。。。。。。。
作者: shadewither    时间: 2009-7-9 00:11:48

lua語法好像是很簡單,但是那些東西都是怎麽用的,例如Attack和AU,好像有不少東西是差不多的?
作者: merlin.zll    时间: 2009-7-9 16:12:26

原帖由 shadewither 于 2009-7-9 02:11 发表
lua語法好像是很簡單,但是那些東西都是怎麽用的,例如Attack和AU,好像有不少東西是差不多的?

那只能靠看多几个文件来猜,我也懂得很有限,都是靠猜的。
作者: sfzwyg    时间: 2009-7-9 16:31:59

学习了


作者: MickeMouse    时间: 2009-7-9 20:02:06

学习了,这个事好东西啊

作者: merlin.zll    时间: 2009-7-10 01:43:25     标题: 填坑完毕

总算是写好了,填坑还真累啊……
希望对大家能有帮助。
作者: shuiwuxin    时间: 2009-7-10 18:37:16

非常强悍的技术贴,虽然我还没有看懂,但还是非常感谢楼主的热心。
作者: shadewither    时间: 2009-7-12 15:47:22

感谢LZ的经验,我也提一点我走过的弯路:

data和sessions目录:
原帖由 merlin.zll 于 2009-7-7 01:32 发表
就是在程序exe开始执行的时候,它会读取data和sessions目录下的所有内容...

这里不存在严格的目录优先级顺序,如果有同名文件说不清会读取到哪个。例如,hero.txt和arena.lua在data和sessions下面都有,结果可能游戏使用了data下面的arena.lua,和sessions下面的hero.txt……

关于lua:
1。游戏中的LUA是5.0.2,别去看5.1的参考手册了;
2。LUA的语法/语义不算干净,不看参考手册还是有可能中刀的;
3。调试战场脚本可以使用这种打印,第一个类似于printf,不过如果类型不匹配,或者有nil就不对了
function my_blogf(format,...) Attack.log("add_blog_debug_01","special",string.format(format,unpack(arg))) end
function my_blog4(x1,x2,x3,x4)
  v1,v2,v3,v4 = x1,x2,x3,x4
  local sDbgStr = ""
  for i = 1,4 do
        local f = assert(loadstring("return "..("v"..i)))
    if f() == nil then
          sDbgStr = sDbgStr.."(nil),"
        else
          sDbgStr = sDbgStr..f()..","
        end
  end
  Attack.log("add_blog_debug_01","special",sDbgStr)
end
然后在.lng里加个:
add_blog_debug_01=^blog_td0^dbg: [g][special][/c]

注意上面的那个[special],只用[special],[name]这种预先有的字串,否则就不会作为参数替换了。

关于地图信息*. embryos.loc
1。KB_DB_EDIT解出来的东西有些毛文,例如{name}。直接压回去KB_DB_EDIT可能会crash;只要把那些毛文都删了就可以了。
2。*.embryos.loc里面:
A) 把(army_XXX)的{lead1}、{lead2}改大,敌人就变多了(经验不变)。lead1 lead2具体的作用不清楚。
B) 出现几支部队不知道如何控制。好像和lead2,敌人种类有关系。
C) 添加一种敌人很简单,但是{perc}等参数都不知道是什么意思。
D) 部队的经验不知道在哪里控制。
作者: merlin.zll    时间: 2009-7-12 23:01:52

原帖由 shadewither 于 2009-7-12 17:47 发表
感谢LZ的经验,我也提一点我走过的弯路:

data和sessions目录:

这里不存在严格的目录优先级顺序,如果有同名文件说不清会读取到哪个。例如,hero.txt和arena.lua在data和sessions下面都有,结果可能游戏使用了data下面的arena ...

谢谢你的经验    

1.目录优先级确实很诡异,所以我改的时候都是确保只有一份修改过的文件。这也是各种MOD冲突的根源,所以要避免MOD们冲突,就要尽量避免修改这些个系统原有的文件……
2.关于lua:我研究这MOD就研究了不到一星期,lua更是随便看了一下语法就改起来了 所以可以说对lua语言本身是完全没有研究的……不过我用的输出方式和你的很类似,也是在lng里加一行blog_debug。
3.关于*.embryos.loc,我主要研究了一下商店卖兵的,野外兵只是改过一个仙女出来测试用,所以改野兵的没办法了。但是对于商店买兵的话:

{A}{races} = {种族,如果指定了就从指定种族随机(比如elf,orc就从精灵,兽人两族随机)}
{A}{units} = {unit1,min:step:max,unit2,min:max,unit3,fix} //可能出现的兵种(这里的话是三种兵随机出一种),min为随机最小值,max最大值,step为最小步进,比如step为10的话刚开游戏可买的兵就只能是整十个
{A}{level} = {min:max或fix} //兵的等级,指定了的话就在范围内随机
{A}{kolvo} = {min:step:max} //数量,如果没有指定units,这里需要指定数量,格式和units的一样
{U}{prob} = {10} //不明

如果加了兵的话需要把上面类似 // 1 elements 的数量也对应改好。因为毛文crash的我还没试过,可能RP比较好。
对于新兵MOD的话,我觉得在商店里和野外都有新兵出现足矣,所以没有太深入研究(这也是我最后一章一笔带过的原因,实际上就是没怎么研究不敢发言
作者: blueelf    时间: 2009-7-15 11:32:27

这个仙女很黄很暴力,这个教程很长很详细
作者: funfun12345    时间: 2009-7-21 09:24:19

真是强大无比,对楼主充满敬意
作者: show13x    时间: 2009-8-3 10:15:23

好文章啊,我就差个女性兵了,不知道宝物加成有没有
作者: muchheaven    时间: 2009-11-3 23:55:40

fairy.part1.rar这个文件下载出错啊
作者: gamewarlock    时间: 2009-11-5 07:28:40

感谢楼主分享经验,现在觉得制作MOD是门精湛的艺术,学习中,再次感谢楼主
作者: sol00xc    时间: 2009-11-28 20:34:42

看帖要回帖,谢过lz


20202002
作者: leijianhua    时间: 2010-2-22 13:43:48

楼主很强大,感谢分享。
作者: yeabon    时间: 2010-4-13 21:37:58     标题: 学习

顶顶
想修改下魔法啊哈哈,楼主很强了。
作者: fflame    时间: 2010-4-14 10:14:17

参考LZ,把萨满的图腾技能复制一份,起了个新名字,然后安给生菜,顺便改成对5级兵起效并能复活死去的士兵

于是,前4个岛没打完,把游戏删除掉了 [伤心啊] [害怕]
作者: b51368072008    时间: 2010-4-28 01:02:41     标题: 好东西啊 不下可惜了

果然是好东西 我喜欢 爱你们
作者: xeseo    时间: 2010-4-29 17:29:12

太好了,正准备着手自己做单位呢。准备做无限反击的DK。嘿嘿。
作者: baotgwx    时间: 2010-9-3 00:50:03

lLZ~~~~
下不下来~~不知为何
麻烦谁再传一次或者放到网盘上~~~
谢了
哪位好心发我邮箱吧baotgwx@tom.com
作者: qwewqwewq    时间: 2010-10-12 10:20:27

我用了有点小问题啊。仙女在闪避的时候动作不完整,正常应该是有一个躲闪动作,但我这里仅仅出现一个未击中标识,自己稳如泰山啊
作者: hatedark    时间: 2010-10-12 10:28:17

原帖由 qwewqwewq 于 2010-10-12 10:20 发表
我用了有点小问题啊。仙女在闪避的时候动作不完整,正常应该是有一个躲闪动作,但我这里仅仅出现一个未击中标识,自己稳如泰山啊


这很正常,你又没修改仙女的闪避动作效果,当然是只有效果没有动作的

一般来说,修改一个兵种的某种天赋或者能力,如果那种能力需要有动作效果来支持,你通常需要同时修改此兵种的相应动作效果.这个基本已经超出初级MOD学的教程了...
作者: fantsone    时间: 2010-12-10 10:49:51

很好,很强大
作者: yb5162967    时间: 2011-1-25 15:42:24

我是一个超级脚本编程语言的菜鸟,我只想弱弱滴问LZ一下,您老人家做的文件我应该放在游戏目录哪里
作者: zhoushiya    时间: 2011-2-4 19:51:18

真的十分有趣啊!谢谢啊!
作者: 9999avc    时间: 2011-2-9 06:08:21

kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
作者: qaz02463    时间: 2011-3-12 22:15:11

顶顶~!!
作者: chen0123    时间: 2011-3-27 07:40:45

为什么下载不了啊
作者: fate_win    时间: 2011-3-30 20:27:42

感谢楼主分享  受益良多
作者: mg9998    时间: 2011-4-2 20:39:38

攒个~~~~~                                                                                                                                      
作者: 流氓不是牛    时间: 2011-4-6 13:08:01

佩服佩服。好东西需要顶的
作者: c85277760    时间: 2011-5-24 22:35:31

[感激]
作者: mrz524    时间: 2011-6-8 17:40:40

有用的教学帖 不过= =好难
作者: mrz524    时间: 2011-6-8 17:40:57

= =留着慢慢看吧 没几天学不会的
作者: suchyyx    时间: 2011-12-12 20:33:19

学习学习了,这个事好东西啊

作者: suchyyx    时间: 2011-12-12 20:40:59

学习学习打算自己做一个
作者: nas20    时间: 2011-12-15 02:06:02

回复 merlin.zll 的帖子

不错··不解释,太好了
作者: 啊三头    时间: 2011-12-18 19:09:51

学习学习打算自己做一个
作者: 啊三头    时间: 2011-12-18 20:34:59

佩服佩服。好东西需要顶的
作者: tanyaozhi    时间: 2012-2-5 17:55:49

因为下载要钱,所以要回复
作者: w29601    时间: 2012-3-30 21:34:09

太专业了{:18:},留个脚印
作者: wangc0606    时间: 2012-5-2 18:04:02

怎么会没有积分了呢?好晕啊 ,啥情况
作者: wingerxinger    时间: 2013-1-4 22:03:55

楼主,运行时出现NOT FOUND:cpi_angle_feat
作者: kzvs    时间: 2015-4-6 13:44:51

最近闹游戏荒,又捡起老游戏开耍
作者: 々忧郁の风々    时间: 2015-5-12 22:23:02

楼主幸苦了
作者: 63764737    时间: 2016-2-12 16:00:17

本帖最后由 63764737 于 2016-2-12 16:01 编辑

回错帖子了,请无视我
作者: zigguratsl    时间: 2021-1-21 11:33:40

merlin.zll 发表于 2009-7-7 01:32
2. atom(兵种模型描述)修改初步

首先要说的是:本章大量内容参考自kfkxzw 的《【KB修改教程一】自创&修 ...

太有用了!非常感谢1





欢迎光临 游侠NETSHOW论坛 (https://game.ali213.net/) Powered by Discuz! X2