可怜的瞎子,你们的鱼汤很鲜吧?
嗯,到这里,希望读者们也能停下来,好好思考一下,看看这个问题该如何解决。
想到了没有?
这里是答案,看看你的想法是否能不谋而合吧:
这个问题暴雪在Diablo 2时代已经完美解决了: 法术/技能化
所谓化,其实等同于表格化,例如这个随便杜撰出来的简化方案,是设计一个有如下字段的数据表格:
法术ID 效果 作用范围 作用类型 属性 特殊限制 强化类型 特殊设定
其中,特殊设定字段可以是一段LUA代码,可以在其中搜索、设置极其特殊的伤害类型,或者查询顺劈斩/治疗链等奇特技能的传递目标等等。
特殊限制字段设定法术的施法或/和生效条件,如驱散限定为只能作用于魔法性buf/debuf(根据职业不同,可能有进攻性驱散和防守性驱散之一,也可能同时具备——这就体现在可否驱散敌方/友方目标的debuf)
在这个方案下,释放一个法术/技能,就成为一种查表运算——找到此法术ID,找到它的作用类型和伤害属性,计算特殊设定(包括但不限于顺劈斩模式的判断、天赋加成和天赋效果、雕文加成和雕文效果等等)。
于是,到最后,整个法术体系被分为一组组的魔法buf/debuf、物理buf/debuf,这些buf/debuf会影响伤害公式中的某个因子或者造成伤害效果;而伤害效果又分为立即伤害/立即治疗和持续伤害/持续治疗;最后则是一套影响范围判定机制。
举例来说,骑士开圣盾,他同时得到一个buf和一个debuf。
buf是“无敌”,效果相当于设置伤害公式 a*(....) 前面的a因子为0(没有无敌时此因子为1),于是所有伤害无效。
debuf则是“自律”,因为他的圣盾、圣疗技能判断条件里都有“有自律debuf,则不允许使用”的设定,于是禁止他在短时间内再次使用这些无赖技能。代码设计模式
敌方法师对他释放寒冰箭,系统受理,但查询骑士状态,发现他处于无敌状态,返回大大的两个字“免疫”。
然后,有一个敌方牧师对他使用驱散,查询牧师的驱散术发现,在驱散术的可驱散列表里没有圣盾术,于是提示无法驱散或驱散了另外的可驱散(魔法)效果。
敌方牧师迅速反应过来,再次对他使用强力驱散;查询牧师强力驱散术,发现该牧师在不久前使用过强力驱散,提示无法施法。
等待3秒后,敌方牧师发现自己的强力驱散冷却(cool down),再次使用强力驱散,查询发现强力驱散可驱散圣盾术,于是成功移除骑士的无敌状态。
现在,敌方法师再次对他释放寒冰箭,骑士切换冰抗光环,系统查询骑士状态,发现冰抗光环,又查询法师穿透等级,和暴击等级,根据公式计算能否命中、能否造成全额伤害以及能否暴击;然后提取法师和骑士双方装备、天赋数据代入公式计算伤害加成、减免数据,最后给出骑士受到的伤害数字(包括部分抵抗了多少)。
在暴雪设计师的整理之下,如上种种最终构成了几个表格;只要查询并代入相应的数据,即可计算出伤害/治疗数值以及类型;特殊效果可以用存储在中的LUA代码补充完成。
最终的设计效果就好像内嵌了一个解释器,这个解释器会根据法术ID解释执行内部的相关内容。
这样一来,只要伤害公式、伤害/buf类型、效果等等就位,那么新增一个法术就只不过是在中新增一条记录;让某个角色学会一个新法术,则只需在它的可使用法术列表里添加法术名称(或法术ID);释放法术是根据法术ID在中提取;计算伤害是根据法术ID读取伤害公式,然后代入相关字段并求值。
如何?无与伦比的扩展性和便利性,是吧?
这么一整套东西,核心代码很可能只有数千甚至数百行。这是因为看似复杂的光环、buf等等东西,其实都已经抽象到和其他法术同样的流程上来了。最终,所有这些全部归一为解释执行伤害公式、提取执行指定之类寥寥几个通用过程——这显然同样是封装和归一化思想结出的另一颗果实。但为什么你就是想不到封装和归一化还能这样用?很简单,因为你被那些只会就着浅显的多态喋喋不休的笨蛋彻底引偏方向了。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-85281-7.html
至少缩水1000以上
上午10点半飞过广场后各自回场