中级玩家
- 贡献度
- 9
- 金元
- 1665
- 积分
- 203
- 精华
- 0
- 注册时间
- 2009-10-29
|
本帖最后由 galaxys 于 2012-5-18 01:23 编辑
周末在家研究了2天如何写talent脚本,有几点心得,希望跟大家分享一下。也希望MOD强人能够指点一下错误……
下面以一个相当简单的技能为例,分析技能脚本中部分函数的作用:(需要读者懂得lua语法)
newTalent{
newTalent是一个lua函数,作用是定义一个新的技能。它传入的唯一一个参数就是下面所附的表。
name = "Kick",
技能名称。newTalent函数运行时,会把它转为大写字母,并在前面加上T,存入ActorTalents表中,像这样:ActorTalents.T_KICK
type = {"role/combat", 1},
技能分类。后面的1是技能树中的显示层级,
points = 1,
技能通过加点可以加多少点
cooldown = 6,
冷却回合数
stamina = 2,
消耗的耐力。这里比较能体现脚本的灵活性,任何一个技能也可以使用任何一种energy,只要把它写在这里就可以了。
range = 1,
技能射程
action = function(self, t)
当主动使用此技能时,会呼叫的函数。其中self是技能的施展者,t是这个技能本身(也就是前面提到的ActorTalents.T_KICK表)
local tg = {type="hit", range=self:getTalentRange(t)}
技能的影响范围参数表,用来确定技能范围内有哪些敌人。其中type就是范围的类型,如hit是单体,beam是一直线,ball是圆形,等。range是技能射程,为什么不直接把上面那个range拿来用呢?因为有的技能会随着技能等级而改变范围的,所以要从角色身上拿取这个技能的当前射程来用。
local x, y, target = self:getTarget(tg)
把上述的技能的影响范围参数表传入getTarget函数,传回目标的X\Y坐标,以及目标本身。
if not x or not y or not target then return nil end
检查目标的坐标及目标本身是否为空,若为空则啥也不做,传回nil,导致这个技能没放出来,中途取消了。坐标为空表示你鼠标指针超出地图范围了,目标为空表示你点了下空地。
if core.fov.distance(self.x, self.y, x, y) > 1 then return nil end
如果目标离你超过1格,取消技能。这个是近战技能需要做的检查,目前还不知道为啥要做多一个检查。
target:knockback(self.x, self.y, 2 + self:getDex())
技能效果:击退目标。其中self.x, self.y是“击退源”的坐标,2 + self:getDex()是击退的格数。
return true
返回true,表示这个技能已经成功放出去了。
end,
info = function(self, t)
技能的提示信息函数。
return "Kick!"
end,
}
对于一个技能来说,action的部分通常是最复杂、最灵活的部分。例如下面是某个技能的action函数中,一段“给技能影响的所有目标加DEBUFF”的脚本:
local grids = self:project(tg, x, y,
function(x, y, target, self)
local target = game.level.map(x, y, Map.ACTOR)
if target then
target:setEffect(target.EFF_ACIDBURN, 3, {apply_power=2, power = 3})
end
end,
nil, nil)
首先说一下project函数。通常来说,它有2个作用:给tg范围内的所有目标施加伤害,和根据tg范围来显示出爆花特效。例如:
self:project(tg, x, y, DamageType.ACID, 1 + self:getDex()/3, {type="acid"})
其中DamageType.ACID表示它是酸性伤害,1 + self:getDex()/3是伤害值,{type="acid"}表示它会在技能范围内爆出绿色的特效。
但在上述“给技能影响的所有目标加DEBUFF”的脚本中,一个函数取代了通常是DamageType的位置:
function(x, y, target, self)
local target = game.level.map(x, y, Map.ACTOR)
if target then
target:setEffect(target.EFF_ACIDBURN, 3, {apply_power=2, power = 3})
end
end
实际上,project函数的第三个参数本来就是要传入一个函数。project函数会为tg范围内的每个目标运行一次这个函数,而不只是定义伤害类型,影响伤害修正和伤害抗性而已。例如slime类型伤害会使敌人变慢、ice类型伤害有几率冰冻敌人等效果,就是用这个函数来实现的。在本例中,传入的函数给tg范围内的每个目标附加一个DEBUFF。……像这样的灵活运用,在脚本中非常常见,大大降低了脚本的可读性……
……以上,就是这两天的研究成果了。希望各位MOD作者,能多交流交流脚本写法,尤其是某些脚本可读性很差的情况下……
2012/5/18编辑:
遇到的2个错误的现象及原因:
进游戏后读条反复来回,就是进不去游戏:可能是LUA版本问题,在TOME运行环境下,使用--[[...]]来做多行注释是不行的,从第二行开始就不被当做注释处理了。
点“新游戏”后,读条超慢,10分钟才到100%:我把一个文件夹名字打错了,找不到文件。可能是因为TOME会反复在不同的地方找这些文件?
|
评分
-
1
查看全部评分
-
|