[MOD] 技能:治疗/治愈

  • 治疗:每回合一开始时可以给满足条件单位补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函数,函数大致逻辑是枚举地图上所有单位,对每一个单位执行:

  1. 找出可以治疗/治愈他的医生集合;
  2. 他是不是病人,如果是执行第3步;
  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]

全部评论: 0

    写评论: