3DMGAME 3DM首页 新闻中心 前瞻 | 评测 游戏库 热门 | 最新 攻略中心 攻略 | 秘籍 下载中心 游戏 | 汉化 购买正版 论坛

注册 登录

QQ登录

只需一步,快速开始

查看: 8135|回复: 6
打印 上一主题 下一主题

[原创] 关于定制属于自己的talent的lua脚本写法

  [复制链接]

3

主题

147

帖子

204

积分

中级玩家

Rank: 3Rank: 3

贡献度
9
金元
1680
积分
204
精华
0
注册时间
2009-10-29
跳转到指定楼层
主题
发表于 2012-5-14 01:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 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

查看全部评分

回复

使用道具 举报

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

本版积分规则

Archiver|手机版|3DMGAME ( 京ICP备14006952号-1  沪公网安备 31011202006753号

GMT+8, 2026-4-25 21:50 , Processed in 0.030651 second(s), 16 queries , Memcached On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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