- 治疗:每回合一开始时可以给满足条件单位补HP,像白袍法师的治疗+16。
- 治愈:每回合一开始时可以给满足条件单位解除中毒状态。
编写mod时,治疗/治愈特技的标签都是、必须是[heals]。是治疗还是治愈,只是[heals]块中的值不一样而已。
[heals]标签下可存在以下键值/标签
poison:
取值:slowed、cured。默认空。
语义:指示如何处理中毒。slowed:不能解除中毒,但可以使中毒者该回合不失血;cured:让中毒者恢复到正常状态。
注:
slowed会让联想到减速,但这个跟减速就没关系。减速是该阵营(被减速部队所在阵营)操作一结束就被去除。
poison=cured,往往就被称作治愈。
poison=slowed,一旦它使得中毒者不失血了,它关联着(如果有)的加HP就自动失效。
在治疗阶段会出现动作
治疗阶段:前一阵营行动结束,轮到本阵营,本阵营在让玩家/AI可操作前先进入治疗阶段。
- 中毒导致失血;
- 治疗技能治疗
- 治愈技能治愈
- 恢复技能恢复
- 正停留在村庄,+8、治愈
- 未行动+2(可叠加)
1:以上除了未行动,其它都不可叠加,未行动则可以叠加到任何一个,当存在多个医生时,取最大HP。举个例子,B和C都能治疗单位A,A将获了B和C中的较大值,另外A还能叠加未行动导致的+2。
2:治愈一旦生效,治疗将自动失效。
3:治愈包括治愈中毒(poison=cured)和使中毒者在该回合不失血(poison=slowed)。
4:友邻之间可以治愈,治疗限于本阵营。
一、软件注释
治疗阶段在程序中对应着calculate_healing函数,函数大致逻辑是枚举地图上所有单位,对每一个单位执行:
- 找出可以治疗/治愈他的医生集合;
- 他是不是病人,如果是执行第3步;
- 执行治疗/治愈。
为叙述方便下的定义
当前单位:治疗阶段要对地图上所有单位进行枚举,正枚举到的单位定义为当前单位。(只是枚举本阵营单位是不够的,治疗阶段不仅能治疗本阵营单位,还有友邻单位。)
A:affect_self和[affect_adjacent]是如何生效的?
Q:calculate_healing调用当前单位的unit.get_abilities("heals"),后者返回一个含有治疗信息和施加该治疗的医生位置的unit_ability_list对象。unit_ability_list可看作是以下这样一个结构:
[#0]<config, loc> [#1]<config, loc> ............. [#N-1]<config, loc>
注:
config:治疗信息,它一般就是在cfg文件定义的[heals]块。
loc:当前情况下,对应施加治疗的医生的格子。除去自医疗,这个格子不是当前单位产生出的可治疗到格子,而是可以治疗他的医生所在的格子。
calculate_healing每次进入都会对当前单位从正站着格子获得unit_ability_list结构,从而使用自单位的affect_selft和其它单位的[afect_adjacent]动态获得可得到可以治疗/治愈当前单位的医生集合。
unit_ability_list unit::get_abilities(const std::string& ability, const map_location& loc) const { unit_ability_list res; // loc是当前单位所在格子 // 检查当前单位是否能自治疗,能就加入医生列表 if (const config &abilities = cfg_.child("abilities")) { foreach (const config &i, abilities.child_range(ability)) { if (ability_active(ability, i, loc) && ability_affects_self(ability, i, loc)) res.cfgs.push_back(std::pair<const config *, map_location>(&i, loc)); } } assert(units_ != NULL); map_location adjacent[6]; get_adjacent_tiles(loc,adjacent); // 检查周围6个格子是否站有能治疗到当前单位的医生,有就加入医生列表 // 注:这里不判断医生和当前单位阵营关系,calculate_healing会在后面进行判断 for(int i = 0; i != 6; ++i) { const unit_map::const_iterator it = units_->find(adjacent[i]); if (it == units_->end() || it->second.incapacitated()) continue; const config &adj_abilities = it->second.cfg_.child("abilities"); if (!adj_abilities) continue; foreach (const config &j, adj_abilities.child_range(ability)) { if (unit_abilities::affects_side(j, teams_manager::get_teams(), side(), it->second.side()) && it->second.ability_active(ability, j, adjacent[i]) && ability_affects_adjacent(ability, j, i, loc)) res.cfgs.push_back(std::pair<const config *, map_location>(&j, adjacent[i])); } } return res; }
[/code]