完成后

/Icarus/ServiceFiles//1/2021/8/1628647749094.png

技能的基本需求为:

  • 修改范围所有单位的移动速度为固定值
  • 如果是敌人将会每秒受到一次伤害
  • 每秒将持续耗蓝
  • 损失当前生命50%作为代价释放

语言文件addon_schinese.txt

"DOTA_Tooltip_ability_turtle_slow" "魔神 - 瘟疫主宰 Ex!"
"DOTA_Tooltip_ability_turtle_slow_Description" "和恶魔交易,损失当前血量的50%获得魔神-瘟疫主宰的帮助"
"DOTA_Tooltip_ability_turtle_slow_Lore" "瘟疫主宰虽然被封印了起来,但似乎有一种仪式可以和他进行交易来获得力量!"
"DOTA_Tooltip_ability_turtle_slow_moveSpeed_abs" "范围移动速度变为:"
"DOTA_Tooltip_ability_turtle_slow_mana_cost" "耗蓝"
"DOTA_Tooltip_ability_turtle_slow_damage" "范围伤害"
"DOTA_Tooltip_ability_turtle_slow_interval" "范围伤害间隔"
"DOTA_Tooltip_ability_turtle_slow_leaveDuration" "离开持续时间:"
"DOTA_Tooltip_modifier_turtle_slow_debuff" "瘟疫主宰 - 瘟疫蔓延"
"DOTA_Tooltip_modifier_turtle_slow_debuff_Description" "瘟疫的开始,就是世界崩溃的壮景,让我来欣赏这一美景。"

技能kvnpc_abilities_custom.txt

"turtle_slow"
{
  "BaseClass"                     "ability_lua"
  "AbilityTextureName"            "pudge/scavenger_dragon_ability/pudge_rot"
  "ScriptFile"                    "abilities/turtle_slow"
  //技能为切换型
  "AbilityBehavior"               "DOTA_ABILITY_BEHAVIOR_TOGGLE"
  "AbilityUnitTargetTeam"         "DOTA_UNIT_TARGET_TEAM_ENEMY"
  "AbilityUnitTargetType"         "DOTA_UNIT_TARGET_HERO | DOTA_UNIT_TARGET_BASIC"

  "AbilityCastPoint"				"0"
  "AbilityCooldown"				"1.0"

  "AbilityCastRange"              "275 300 325 350"

  "AbilityManaCost"               "5 10 20 50"

  "AbilityUnitDamageType"         "DAMAGE_TYPE_MAGICAL"   

  //无视技能免疫
  "SpellImmunityType"             "SPELL_IMMUNITY_ENEMIES_YES"
  //无法被驱散
  "SpellDispellableType"          "SPELL_DISPELLABLE_NO"

  "precache"
  {
      "soundfile"	"soundevents/game_sounds_heroes/game_sounds_warlock.vsndevts"
      "particle" "particles/econ/items/pudge/pudge_arcana/pudge_arcana_dismember_wood.vpcf"
      "particle" "particles/units/heroes/hero_shadow_demon/shadow_demon_disruption.vpcf"
  }

  "AbilitySpecial"
  {
      "01"
      {
        "var_type"                "FIELD_INTEGER"
        "moveSpeed_abs"           "200 150 100 50"
      }

      "02"
      {
          "var_type"                "FIELD_INTEGER"
          "mana_cost"           "5 10 20 50"
      }

      "03"
      {
          "var_type"                "FIELD_INTEGER"
          "damage" "10 30 60 200"
      }

      "04"
      {
          "var_type"                "FIELD_FLOAT"
          "interval" "1"
      }

      "05"
      {
          "var_type"                "FIELD_FLOAT"
          "leaveDuration" "0.5"
      }
  }
  "AbilityCastAnimation"      "ACT_DOTA_CAST_ABILITY_3"
}

技能实现turtle_slow.ts

import { BaseAbility, registerAbility } from "../lib/dota_ts_adapter";
import {modifier_turtle_slow} from "../modifiers/modifier_turtle_slow";

/*
* 龟速,切换型(每秒耗蓝),类似全能的光环,改变范围内所有人移动速度,不分敌我,自己除外每秒在对非友军造成伤害
* 使用时会对自己造成伤害,和恶魔做交易,需要付出代价,当前生命的50% 
* */
@registerAbility()
export class turtle_slow extends BaseAbility 
{
    private _damage:number;
    private _moveSpeed_abs:number;
    private _interval:number;
    
    OnUpgrade()
    {
        this._damage = this.GetSpecialValueFor("damage");
        this._moveSpeed_abs = this.GetSpecialValueFor("moveSpeed_abs");
        this._interval = this.GetSpecialValueFor("interval");
    }

    private readonly _onSound = "Hero_Warlock.Incantations";
    private readonly _onEffect = "particles/econ/items/pudge/pudge_arcana/pudge_arcana_dismember_wood.vpcf";
    private readonly _soulEffect = "particles/units/heroes/hero_shadow_demon/shadow_demon_disruption.vpcf"
    private _pID:ParticleID | undefined;
    
    OnToggle()
    { 
        //获取技能开关状态
        const on = this.GetToggleState();
        
        const caster = this.GetCaster();
        
        if (on)
        {
            EmitSoundOn(this._onSound,caster);
            caster.AddNewModifier(caster, this, modifier_turtle_slow.name, undefined);
            
            const sPid = ParticleManager.CreateParticle(this._soulEffect, ParticleAttachment_t.PATTACH_ROOTBONE_FOLLOW, caster);

            GameRules.GetGameModeEntity().SetThink(()=>
            {
                ParticleManager.DestroyParticle(sPid, true);
                return undefined;
            }, this, "___damage___Effect___", 2);


            GameRules.GetGameModeEntity().SetThink(()=>{
                
                this._pID = ParticleManager.CreateParticle(this._onEffect, ParticleAttachment_t.PATTACH_ROOTBONE_FOLLOW, caster);

                let damage = caster.GetHealth() * 0.5;

                //伤害间隔
                const DI = 0.4;

                //每次伤害的量
                const dDamge = damage / (1 / DI);

                GameRules.GetGameModeEntity().SetThink(()=>
                {
                    //施法者还活着才会继续,否则这里会造成0血卡状态
                    if (caster.IsAlive())
                    {
                        caster.SetHealth(caster.GetHealth() - dDamge);

                        damage -= dDamge;

                        if (damage <= 0)
                            return undefined;
                    }
                    else
                        return undefined;

                    return DI;
                }, this, "___damage___", DI);
                
                return undefined;
            },this,"___damage___S___",1);
        }
        else
        {
            //删除光环
            caster.RemoveModifierByName(modifier_turtle_slow.name);
            
            if (this._pID)
            {
                ParticleManager.DestroyParticle(this._pID, true);
                this._pID = undefined;
            }
        }
    }
}

modifiermodifier_turtle_slow.ts

import {BaseModifier, registerModifier} from "../lib/dota_ts_adapter";
import {modifier_turtle_slow_debuff} from "./modifier_turtle_slow_debuff";

@registerModifier()
export class modifier_turtle_slow extends BaseModifier
{
    private _damage:number;
    private _manaCost:number;
    private _interval:number;
    private _range:number;
    private _leaveAuraDuration:number;
    private _damageTable:ApplyDamageOptions;
    
    OnCreated(params: object)
    {
        if (!IsServer())
            return
        
        const ability = this.GetAbility();
        this._damage = ability.GetSpecialValueFor("damage") ?? 1; 
        this._manaCost = ability.GetSpecialValueFor("mana_cost") ?? 1; 
        this._interval = ability.GetSpecialValueFor("interval") ?? 1;
        this._leaveAuraDuration = ability.GetSpecialValueFor("leaveDuration") ?? 1;
        this._range = ability.GetCastRange(ability.GetCaster().GetAbsOrigin(),ability.GetCaster())

        this._damageTable = {
            ability:this.GetAbility(),
            damage : this._damage,
            victim:undefined,
            attacker:this.GetAbility().GetCaster(),
            damage_flags: DOTADamageFlag_t.DOTA_DAMAGE_FLAG_NONE,
            damage_type: ability.GetAbilityDamageType()
        }
        
        this.StartIntervalThink(this._interval)
    }
    
    //隐藏这个buff,不在状态栏显示
    IsHidden(): boolean
    {
        return true;
    }

    //不是负面buff
    IsDebuff(): boolean
    {
        return false;
    }

    OnIntervalThink()
    {
        let ability = this.GetAbility();
        
        const caster = this.GetCaster();
        
        //扣除魔法值
        caster.SpendMana(this._manaCost, ability)

        //寻找周围所有单位
        const targets = FindUnitsInRadius(caster.GetTeam(), caster.GetAbsOrigin(), undefined, this._range, 
            ability.GetAbilityTargetTeam(),
            ability.GetAbilityTargetType(),
            ability.GetAbilityTargetFlags(), FindOrder.FIND_ANY_ORDER, false);
        
        if (targets.length > 0)
        {
            //对周围所有单位造成伤害
            for (let target of targets)
            {
                this._damageTable.victim = target;
                
                ApplyDamage(this._damageTable);
            }
        }
    }
    
    //是光环buff
    IsAura(): boolean
    {
        return true;
    }
    
    //给`GetAuraRadius`内可作用的目标施加的modifier
    GetModifierAura(): string
    {
        return modifier_turtle_slow_debuff.name;
    }
    
    //光环范围
    GetAuraRadius(): number
    {
        return this._range;
    }
    
    //离开光环后`GetModifierAura`施加的modifier还会存在多久
    GetAuraDuration(): number
    {
        return this._leaveAuraDuration;
    }

    //光环可作用的目标
    GetAuraSearchType(): DOTA_UNIT_TARGET_TYPE
    {
        return DOTA_UNIT_TARGET_TYPE.DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_TYPE.DOTA_UNIT_TARGET_BASIC
    }
    
    //光环可作用的团队
    GetAuraSearchTeam(): DOTA_UNIT_TARGET_TEAM
    {
        return DOTA_UNIT_TARGET_TEAM.DOTA_UNIT_TARGET_TEAM_BOTH;
    }
    
    GetAuraSearchFlags(): DOTA_UNIT_TARGET_FLAGS
    {
        return DOTA_UNIT_TARGET_FLAGS.DOTA_UNIT_TARGET_FLAG_NONE;
    }
}

modifiermodifier_turtle_slow_debuff.ts

import {BaseModifier, registerModifier} from "../lib/dota_ts_adapter";

@registerModifier()
export class modifier_turtle_slow_debuff extends BaseModifier
{
    private _moveSpeed:number;

    OnCreated(params: object)
    {
        const ability = this.GetAbility();
        this._moveSpeed = ability.GetSpecialValueFor("moveSpeed_abs");
    }

    //是负面buff
    IsDebuff(): boolean
    {
        return true;
    }

    DeclareFunctions() {
        return [
            //修改绝对速度
            modifierfunction.MODIFIER_PROPERTY_MOVESPEED_ABSOLUTE,
        ];
    }

    //返回绝对速度
    GetModifierMoveSpeed_Absolute(): number
    {
        return this._moveSpeed;
    }
}

表现效果