RobinCode
📚 文章 DOTA2 API 更新日志🛠️ 工具
Power by Vercel & Next.js

简介

如今Dota2分为两种技能制作方式,Data Driven(数据驱动)和Lua Ability两种方式, 所谓的数据驱动是V社的一种文件格式,叫KeyValue格式,如果你知道JSON那么第一眼看起来会有点像JSON, 就算是Lua Ability也要通过数据驱动进行定义才能使用,数据驱动是基础,所以对数据驱动的理解必不可少。

数据驱动

数据驱动是V社设计好的,我们根据提供的功能来实现技能效果,涉及很少的逻辑代码,当然可以混合Lua加入逻辑代码, 数据驱动在游戏执行后会翻译成底层的C++对象,所以数据驱动的技能执行效率也要好一些, 不过这里有一点需要提醒:数据驱动发生错误可能会直接导致客户端崩溃, 基本没有错误信息,好在数据驱动没什么复杂逻辑,通过去掉代码等手段可以排查出来,熟悉之后更是可以很快定位, 建议新手先通过数据驱动制作技能,后面熟悉之后再尝试Lua Ability。

Lua Ability

这是一种很自由的制作方式,可以实现很多复杂的技能,V社已经很多年没有更新数据驱动了,也没加入什么新功能, 自从推出Lua Ability,在Lua Ability方面的API倒是会更新一下,这可以认为是一种纯Lua的制作方式, 所以需要你有Lua的基础功底,涉及的知识也会很多,不推荐新手一上来就使用。

🔸后面开始介绍以数据驱动为主的技能制作,Lua Ability放到后面的高级篇讲解

技能类型

文件入口 game/dota_addons/<你的项目>/scripts/npc/npc_abilities_custom.txt

💡 基础定义

"DOTAAbilities"
{
    "custom_ability"
    {
        "ID"                        "5000"
        "BaseClass"                 "ability_datadriven"
    }
}
  1. ID表示这个技能的ID,并且唯一,虽然并不要求,但是根据我经验,有时候V社的更新会导致没有ID的技能失效,所以还是好好填上。
  2. BaseClass表示这个技能的c++类,数据驱动是abilit_datadriven,Lua Ability是ability_lua,另外有一点官方Dota2的技能都是底层C++写的,所以你看不到源码的,但是可以继承官方技能然后修改数值,然而就仅仅是修改数值,无法添加或者修改效果,填写技能名称即可继承,小心V社大版本更新改了技能!!!

💡 被动技能

"DOTAAbilities"
{
    "custom_ability"
    {
        "ID"                        "5000"
        "BaseClass"                 "ability_datadriven"
        "AbilityBehavior"           "DOTA_ABILITY_BEHAVIOR_PASSIVE"
    }
}

很简单~一般也不需要其他辅助行为,这三种必须有。

AbilityBehavior表示技能的行为,也是技能施放方式。

💡 无目标主动技能

"DOTAAbilities"
{
    "custom_ability"
    {
        "ID"                        "5000"
        "BaseClass"                 "ability_datadriven"
        "AbilityBehavior"           "DOTA_ABILITY_BEHAVIOR_NO_TARGET"
        "AbilityCastPoint"          "0.5"
        "AbilityCastAnimation"      "ACT_DOTA_CAST_ABILITY_1"
    }
}

PASSIVE改成POINT就是无目标技能了,在做完前摇动作后才会施放。

  • AbilityCastPoint表示前摇时长,以秒为单位。
  • AbilityCastAnimation表示前摇动作,参考官方WiKi-GameActivity_t

💡 点目标技能

"DOTAAbilities"
{
    "custom_ability"
    {
        "ID"                        "5000"
        "BaseClass"                 "ability_datadriven"
        "AbilityBehavior"           "DOTA_ABILITY_BEHAVIOR_POINT"
        "AbilityCastRange"          "500"
    }
}

在施放的时候单位会先转身面向目标点,然后做前摇动作,前摇结束才施放;

AbilityCastRange表示施法距离,如果没有定义这个距离默认无限距离;

接下来我们加点辅助效果

"DOTAAbilities"
{
    "custom_ability"
    {
        "ID"                        "5000"
        "BaseClass"                 "ability_datadriven"
        "AbilityBehavior"           "DOTA_ABILITY_BEHAVIOR_POINT | DOTA_ABILITY_BEHAVIOR_IMMEDIATE | DOTA_ABILITY_BEHAVIOR_IGNORE_TURN"
    }
}

这里多了DOTA_ABILITY_BEHAVIOR_IMMEDIATEDOTA_ABILITY_BEHAVIOR_IGNORE_TURN,并且它们使用|隔开(注意在写的时候竖线两边要有空格),这表示合并效果,从代码方面讲这跟c/c++的异或差不多是一个意思的

  • IMMEDIATE表示该技能立即施放,也就是没有前摇
  • IGNORE_TURN表示忽略转身

更多技能行为常量参考:官方WiKi-DOTA_ABILITY_BEHAVIOR

💡 单位目标技能

"DOTAAbilities"
{
    "custom_ability"
    {
        "ID"                        "5000"
        "BaseClass"                 "ability_datadriven"
        "AbilityBehavior"           "DOTA_ABILITY_BEHAVIOR_UNIT_TARGET"
        "AbilityUnitTargetType"     "DOTA_UNIT_TARGET_BASIC | DOTA_UNIT_TARGET_HERO"
		"AbilityUnitTargetTeam"     "DOTA_UNIT_TARGET_TEAM_ENEMY"
		"AbilityUnitTargetFlags"    "DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES"
    }
}

单位目标稍微麻烦些,多了三种常量,这三种常量定义了该技能对哪些单位有用;

💡 开关类技能

"DOTAAbilities"
{
    "custom_ability"
    {
        "ID"                        "5000"
        "BaseClass"                 "ability_datadriven"
        "AbilityBehavior"           "DOTA_ABILITY_BEHAVIOR_TOGGLE"
    }
}

此类技能具有开关状态,具体事件下篇再讲

💡 自动施法

"DOTAAbilities"
{
    "custom_ability"
    {
        "ID"                        "5000"
        "BaseClass"                 "ability_datadriven"
        "AbilityBehavior"           "DOTA_ABILITY_BEHAVIOR_POINT | DOTA_ABILITY_BEHAVIOR_AUTOCAST"
        "AbilityCastRange"          "500"
    }
}

前面的施法类型中可以搭配自动施法,也就是当你右键技能,这个技能就会出现一个转圈圈的特效表示会自动施法, 但是我实验的时候这个自动施法的AI要自己写,正常情况下不会自己施放。

💡 吟唱/蓄力/引导/持续 施法

"DOTAAbilities"
{
    "custom_ability"
    {
        "ID"                        "5000"
        "BaseClass"                 "ability_datadriven"
        "AbilityBehavior"           "DOTA_ABILITY_BEHAVIOR_POINT | DOTA_ABILITY_BEHAVIOR_CHANNELLED"
        "AbilityCastRange"          "500"
        "AbilityChannelTime"        "3.0"
    }
}

这种技能在施法的时候会变成一种读条的形式,AbilityChannelTime就是读条的时间,你可以当做施法前的吟唱, 也可以当做持续施法期间不断下冰雹这种技能,和上面的自动施法一样可以跟前面的施法类型搭配在一起。

💡 带有AOE范围指示的施法

"DOTAAbilities"
{
    "custom_ability"
    {
        "ID"                        "5000"
        "BaseClass"                 "ability_datadriven"
        "AbilityBehavior"           "DOTA_ABILITY_BEHAVIOR_POINT | DOTA_ABILITY_BEHAVIOR_AOE"
        "AbilityCastRange"          "1000"
        "AOERadius"                 "300"
    }
}

点击此技能后鼠标就会同时出现一个范围指示圈,AOERadius表示这个范围。

补充一些通用配置

"DOTAAbilities"
{
    "custom_ability"
    {
        "ID"                        "5000"
        "BaseClass"                 "ability_datadriven"
        "AbilityBehavior"           "DOTA_ABILITY_BEHAVIOR_POINT"
        "MaxLevel"                  "4"
        "RequiredLevel"             "5"
        "LevelsBetweenUpgrades"     "0"
        "FightRecapLevel"           "0"
        "AbilityCooldown"           "3.0"
        "AbilitySharedCooldown"     "common"
        "AbilityManaCost"           "10"
        "AbilityTextureName"		"xxx"
    }
}
  • MaxLevel表示技能最大等级
  • RequiredLevel表示?
  • LevelsBetweenUpgrades表示学习技能的等级要求
  • FightRecapLevel表示跳级?
  • AbilityCooldown表示技能冷却时间
  • AbilitySharedCooldown表示共享冷却时间的字段,相同字段的技能在其中一个使用后其它技能都会一起进入CD
  • AbilityManaCost表示使用技能所需的魔法值
  • AbilityTextureName表示技能图标的文件名,后面再细讲

等级与数值

"DOTAAbilities"
{
    "custom_ability"
    {
        "ID"                        "5000"
        "BaseClass"                 "ability_datadriven"
        "AbilityBehavior"           "DOTA_ABILITY_BEHAVIOR_POINT"
        "MaxLevel"                  "4"
        "AbilityCastRange"          "500 700"
        "AbilityCooldown"           "3.5"
        "AbilityManaCost"           "10 15 20 30"
        "AbilityDamage"             "100 200 300 400"
    }
}

在技能中不同等级使用不同的数值是很常见的,上面定义该技能等级为4,则可以定义4个等级的数值(如AbilityManaCost),每个等级的数值用空格隔开,从左到右依次是从1级到4级的数值。

  • 如果只填写一个数值表示后续等级的数值都是一样的(如AbilityCooldown)
  • 如果填写了两个或者三个数值,后面缺省的数值默认为最后一个的数值(如AbilityCastRange,3级和4级都是700)

💡 自定义字段

"DOTAAbilities"
{
    "custom_ability"
    {
        "ID"                        "5000"
        "BaseClass"                 "ability_datadriven"
        "AbilityBehavior"           "DOTA_ABILITY_BEHAVIOR_POINT"
        "MaxLevel"                  "4"
        
        "AbilitySpecial"
        {
            "01"
            {
                "var_type"          "FIELD_FLOAT"
                "damage"            "20 30 40 50"
            }
            "02"
            {
                "var_type"          "FIELD_INTEGER"
                "radius"            "500"
            }
        }
    }
}

AbilitySpecial用于自定义字段,其下面是字段列表,上面范例中的01,02不必是顺序的,只是用于保证唯一;
在往里是var_type用于指定数值的类型,目前有两种:FIELD_FLOATFIELD_INTEGER,这里说明一下, 对于我们来说这并无区别,因为Lua只有number类型,所以我们获取到的数值都是number,而C++作为强类型的语言是有类型区分的;
在是var_type下面就是需要自定义的字段,上面的范例我们自定义了damageradius字段,数值表示的方式跟前面一样;
AbilitySpecial可以理解为定义变量的地方。

下一篇开始讲如何技能的事件和动作

🏷️DOTA2自定义游戏教程

📅 创建于2020-10-10