SDL中文论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 6160|回复: 1
打印 上一主题 下一主题

[MOD] 兵种能力(Abilities)

[复制链接]

149

主题

331

帖子

2445

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2445
跳转到指定楼层
楼主
发表于 2020-11-29 10:48:38 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
  • 部队从兵种继承时不会修改能力,因而兵种能力就是部队能力。
  • 系统以集中、预定义方式管理能力。预定义能力被集中存放在[units]块下,一个[units].[abilities]块定义一种能力(参考<data>/core/units.cfg)。任一[abilitys]块下必须有一个全局唯一id,兵种宣称自已要使用哪种能力时使用该id。举个例子,“abilities = illumination, curing, heals16”指示该兵种拥有“照明”、“治愈”、“自疗”能力。如果想向系统增加一种能力,使用下面步骤。
    1:在[units]块下增加一个[abilities]块,赋给该[abilities]块一个和已存在[abilities]不冲突的id。[abilities]块则指示能力实现(以下会叙述如何写[abilities]块)。向系统增加持能可使用“ABILITIES_DEF”宏。
    2:在希望拥有该能力的兵种中设置“abilities”字段。abilities指示了该兵种拥有的能力,当拥有多项能力时,中间用“,”分隔。


如何定义[abilities]块
一个[abilities]块大致可分为三个部分;说明、条件、操作。让结合“治疗+16”进一步说明。
  1. #define ABILITY_HEALS16
  2.     [heals]
  3.         value=16
  4.         id=heals16
  5.         name= _ "heals +16"
  6.         female_name= _ "female^heals +16"
  7.         description= _ "Heals +16:
  8. This unit combines herbal remedies with magic to heal units more quickly than is normally possible on the battlefield.

  9. A unit cared for by this healer may heal up to 8 HP per turn, or stop poison from taking effect for that turn.
  10. A poisoned unit cannot be cured of its poison by a healer, and must seek the care of a village or a unit that can cure."
  11.         affect_self=no
  12.         poison=slowed
  13.         [affect_adjacent]
  14.             adjacent=n,ne,se,s,sw,nw
  15.         [/affect_adjacent]
  16.     [/heals]
  17. #enddef
复制代码
  • 说明:它是对能力的总体描述。块中和说明相关的字段有“id”、“name”、“female_name”和“description”。
  • 条件:它指示能力要能发挥作用需满足的条件。和条件相关的有“affect_self”字段以及“affect_adjacent”块。
  • 操作:它指示一旦满足条件后则执行的操作,它是能力实际产生影响部分。怎么写操作和具体能力相关,“治疗+16”和操作相关是两个字段。“value”、“poison”。“value=16”指示对被能力单位增加16HP;“poison=slowed”指示如果被能力单位正处于中毒状态时,则此回合不降HP(中毒单位每回合降8HP)。

对能力中的三要素,说明没什么好补充的,以下详细叙述“条件”、“操作”。

要素之条件
在描述条件前让先看下能力释放逻辑。释放逻辑指的是能力是怎么被释放的。对能力拥有者来说,释放能力是个被动过程,即拥有技持单位是“等”着被询问是否有该项持能,如果有就释放。以下是通用释放逻辑。
  • 程序运行到特定时刻,被能力单位认为有种能力能强化自已,开始询问是否有该持能。
  • 从自已所在位置到六个相邻位置,依次检查能力条件,如果该位置上存在可释放的单位,把该单位操作加入操作集。
  • 操作集是空,退出释放逻辑。否则进入4。
  • 执行操作集。

治疗能力。程序运行到新回合开始时要进入治疗阶段,程序挑出一个可治疗单位(HP未满),针对该单位从自已所在位置到六个相邻位置依次询问是否有相关单位拥有治疗能力,如果有,把该操作加入操作集。形成的操作集不为空时,从集合中选出个最好治疗操作(像增加的HP最大),执行该操作。此时可治疗单位称被能力单位。

领导持能。当部队要攻击时,针对正要实施的攻击单位从自已所在位置到六个相邻位置询问是否有相关单位拥有领导能力,如果有,把该操作加入操作集。形成的操作集不为空时,从集合中选出个最好领导操作(像增加的攻击力最大)。此时攻击单位称被能力单位。

此种逻辑下,拥用能力单位是被动方,当要判断是否可释放条件时,被能力单位反而成了“中心”单位。条件包括两种:位置条件、被能力单位的特殊要求。

条件I:位置条件
被能力单位和拥有能力单位必须满足一定位置条件才发动能力。

能力可能影响自已,可能影响相邻单位。但最多影响相邻单位,无法影响相邻以外的单位,像隔一格的。
affect_self指示该能力是否影响自已。yes时影响,否则不影响。默认影响。
affect_adjacent块指示该持能影响哪些相邻单位。由于最多影响相邻位置,于是可出现“n”、“ne”、“se”、“s”、“sw”、“nw”中一个或多个。
在任一时刻,能力是否能释放依赖被能力单位的当前位置,affect_self、affect_adjacent等于设定了位置条件。

对“治疗+16”来说,被能力单位和拥有能力单位必须满足相邻关系;而对“自疗+16”来说,被能力单位和拥有能力单位必须是同一个单位。

条件II:被能力单位的特殊要求
“领导”能力能强化等级低的单位的攻击力,也就是说被能力单位(“中心”单位)的等级必须低于拥有能力单位等级。这个低于关系就是对被能力单位的特殊要求。
  1. #define ABILITY_LEADERSHIP_LEVEL_1
  2.     # Canned definition of the Leadership (level 1) ability to be included in an
  3.     # [abilities] clause.
  4.     [leadership]
  5.         id=leadership1
  6.         value=10
  7.         cumulative=no
  8.         name= _ "leadership"
  9.         female_name= _ "female^leadership"
  10.         description= _ "Leadership:
  11. This unit can lead our own units that are next to it, making them fight better.

  12. Adjacent own units of lower level will do more damage in battle. When a unit adjacent to, of a lower level than, and on the same side as a unit with Leadership engages in combat, its attacks do 25% more damage times the difference in their levels."
  13.         affect_self=no
  14.         [affect_adjacent]
  15.             adjacent=n,ne,se,s,sw,nw
  16.             [filter]
  17.                 level=0
  18.             [/filter]
  19.         [/affect_adjacent]
  20.     [/leadership]
  21. #enddef
复制代码
[affect_adjacent]块中的[filter]块就用于描述这个特珠要求,它是一个标准单位过滤器。相应的,[leadership]根下(如果存在)的[filter_self]就用于描述自已既是被能力又是拥有能力单位时的特殊要求。

能力条件中没对拥有者有特殊要求。拥有者只要同时满足拥有该能力和位置条件就行了。
回复

使用道具 举报

149

主题

331

帖子

2445

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2445
沙发
 楼主| 发表于 2020-11-29 10:50:39 | 只看该作者
要素之操作
操作集表示格式
在C/C++程序内,操作集表示格式是unit_ability_list,更具体说是std::vector<std::pair<const config *, unit *> >。

  • unit_ability_list是类,heal是该类类例。cfgs是unit_ability_list一个成员变量,它存储了操作集,它的类型就是“std::vector<std::pair<const config *, unit *> >“。
  • 表示格式是一个std::vector。此例中它有5个元素,也就是说有五个“heals”能力可能对被能力单位产生影响。
  • std::pair中的first是描述能力config块(指针),也就是以上的“[heals]”,“[leadership]”。从展开的values可看到该config具体内部。
  • std::pair中的second是该config块归属的单位,即拥有能力的单位(指针)。虽然heals是五个,但单位是3个,0x0ac696a8、0x0ac6a3b8、0x0ac6aa40。后两个单位有两种[heals]块(治愈、治疗),并且都可以发挥作用。
  • u.get_abilities("heals")返回当前状态下可发挥作用的[heals]操作集,u是被能力单位。相应地把参数"heals"换为"leadership"则是返回当前状态下可发挥作用的[leadership]操作集。即get_abilites是获得操作集的一种统一方法(除它还有get_abilities_bool,它实质是get_abilities简化版,对只须要true/false结果的能力(像游击能力)调用它就可以了)。
  • 接下计算最佳操作时就是基于unit_ability_list,更其体说是当中的cfgs成员变量。


通用操作和私有操作
能力操作分通用操作和私有操作。

对“治疗+16”能力来说,它有两个操作:“value=16”指示对被能力单位增加16HP;“poison=slowed”指示如果被能力单位正处于中毒状态时,则此回合不降HP。对于后者,它是[heals](“治疗+16”是[heals]一个实例)特有的,而对前者(value字段)则是通用的。

要理解为什么说“value=16”是通用,让看“一级领导”(ABILITY_LEADERSHIP_LEVEL_1)能力。该能力也有个“value”字段,即“value=10”,它给等级0单位增加“10”攻击力。

“治疗+16”、“一级领导”,它们的“value”字段意义不一样,一个增加HP,一个增加攻击力,但它们在MOD中采用同一种表示法,它们是能力中的通作操作。当然,通用操作表现出的一致不仅仅是同一表示法,还有施加它们之上的运算。继续以上的有5种[heals]的治疗例子,[0]、[2]、[4]项[heals]都有加HP功能,他们分散在三个单位,增加HP不能累加,于是系统就要在这三个[heals]中选择加HP最大的那个,[0]增加20HP,它最大,于是最后会选它。相应的对领导能力,要是一个要被能力单位旁边站着两个单位,一个有“一级领导”能力,一个有“二级领导”能力,这时系统就要选中能加强攻击力更多的,即拥有“二级领导”的那个单位。以代码来看,这两个操作都是选择最大value值操作,除去这种操作,通用操作还支持更多运算,像加法,乘法。

cumulative意义不是累加,而是指示是否考虑基本值(基本值的默认值是0。对基本值非零例子,参考坚定能力,坚定能力基本值是单位常态下抗性)。true时考虑基本值,并取基本值和value之中最大值;false时不考虑基本值,直接取value值。如果不存在value字段,则会忽略cumulative字段。

效果(运算)集表示格式
效果集是基于操作集上得出的集合,用它就可计算出最后需要的值。在C/C++程序内,效果集表示格式是std::vector<unit_abilities::individual_effect>。由于效果集中的元素会作为最终运算中的操作数,有时把效果集称作运算集。

  • 它是根据上例操作集得到的效果集截图。由于是程序再次运行,3个拥有能力单位的指针有变动。
  • 效果集数据结构std::vector。单元类型是unit_abilities::individual_effect,后者的实例表示参与最后计算的操作数。
  • 效果集中的单元类型可能是赋值(SET,能力块中存在“value”字段)、加法(ADD,能力块中存在“add”字段)、乘法(MUL,能力块中存在“multiply”字段)。
  • 赋值:一个元素对应一个操作数(公式中的value_set),集合中最多存在一个赋值。加法:所有不同能力类别加法(同一类别只取最大值)的累加值对应一个操作数(公式中的addition),集合中可能存在多个加法。乘法:所有不同能力类别乘法(同一类别只取最大值)的累乘值对应一个操作数(公式中的multiplier),集合中可能存在多个乘法。
  • composite_value_指示最后计算出的效果值。它的计算公式:
    1. composite_value_ = (value_set + addition) * multiplier / divisor;
    2. value_set:赋值单元给出的值。当存在多个赋值块时取最大值。
    3. addition:加法单位给出的值。当存在多个加法单元时取累加值。
    4. multiplier/divisor:剩法单元给出的值。当存在多个乘法单元时取累乘值。divisor是为取值百存的,multiplier值是MOD中的值乘上100后的值,因而为恢复回MOD值须除上100。divisor肯定的是100的指数倍。(乘法参考坚定能力)。
    复制代码
  • 实例中的效果集中只存在一个单元。这个单元是赋值单元。因为没有加法、乘法,addition等于0,multiply、divisor都等于1。
  • 除去用于形成composite_value_的各个操作数,效果集另一作用是让上层知道哪些单位/能力参与了此次影响。像以上例子中,虽然操作集中有三个单位,但最后产生作用只有value=20的那个单位,unit_abilities::individual_effect只有一项表示了这个情况,而当中的“ability”字段指示产生影响的能力,“u”字段则指示了产生影响的单位。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|丽谷软件|libsdl.cn

GMT+8, 2025-5-1 23:26 , Processed in 0.063858 second(s), 22 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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