Решено Не работает поведение нейтрала

Setinder

Пользователь
23 Авг 2022
28
1
Нашёл гайд на поведение крипа, чтобы он мог кастовать спеллы. Всё сделал, но скрипт не работает и выдаёт ошибку
...crpg_bysetinder\scripts\vscripts\heroes\boss\UnitsAI.lua:121: bad argument #1 to 'band' (number expected, got userdata)
stack traceback:
[C]: in function 'band'
...crpg_bysetinder\scripts\vscripts\heroes\boss\UnitsAI.lua:121: in function 'FindAbility'
...crpg_bysetinder\scripts\vscripts\heroes\boss\UnitsAI.lua:41: in function <...crpg_bysetinder\scripts\vscripts\heroes\boss\UnitsAI.lua:13>
Script Runtime Error: ...crpg_bysetinder\scripts\vscripts\heroes\boss\UnitsAI.lua:121: bad argument #1 to 'band' (number expected, got userdata)
stack traceback:
[C]: in function 'band'
...crpg_bysetinder\scripts\vscripts\heroes\boss\UnitsAI.lua:121: in function 'FindAbility'
...crpg_bysetinder\scripts\vscripts\heroes\boss\UnitsAI.lua:41: in function <...crpg_bysetinder\scripts\vscripts\heroes\boss\UnitsAI.lua:13>

вот скрипт
Lua:
function Spawn( entityKeyValues )
    if not IsServer() then
        return
    end

    if thisEntity == nil then
        return
    end
 
    thisEntity:SetContextThink( "NeutralAutoCasterThink", NeutralAutoCasterThink, 1 )
end

function NeutralAutoCasterThink()
    if ( not thisEntity:IsAlive() ) then        --если юнит мертв
        return -1
    end
 
    if GameRules:IsGamePaused() == true then    --если игра приостановлена
        return 1
    end

    if thisEntity:IsChanneling() then    -- если юнит кастует скил
        return 1
    end
 
    if thisEntity:IsControllableByAnyPlayer() then    -- если юнит принадлежит игроку, то поведение отключается
        return -1
    end
 
    local npc = thisEntity

    if not thisEntity.bInitialized then
        npc.vInitialSpawnPos = npc:GetOrigin()        -- точка спавна юнита
        npc.fMaxDist = npc:GetAcquisitionRange()    -- радиус агра
        npc.bInitialized = true                        -- флаг инициализации
        npc.agro = false                            -- флаг агра
      
        npc.ability0 = FindAbility(npc, 0)            -- ищет способность по индексу
        npc.ability1 = FindAbility(npc, 1)            -- ищет способность по индексу
        npc.ability2 = FindAbility(npc, 2)            -- ищет способность по индексу
        npc.ability3 = FindAbility(npc, 3)            -- ищет способность по индексу
        npc.ability4 = FindAbility(npc, 4)            -- ищет способность по индексу
        npc.ability5 = FindAbility(npc, 5)            -- ищет способность по индексу
      
    end

    local search_radius                             -- радиус поиска зависит от того, имеет ли юнит агр
    if npc.agro then
        search_radius = npc.fMaxDist * 1.5            -- расшираяется
    else
        search_radius = npc.fMaxDist                -- становится обычным
    end
 
    -- Как далеко юнит находится от своей точки спавна ?
    local fDist = ( npc:GetOrigin() - npc.vInitialSpawnPos ):Length2D()
    if fDist > search_radius then
        RetreatHome()            -- если юнит слишком далеко, то идет на точку спавна
        return 3
    end
 
    local enemies = FindUnitsInRadius(
                        npc:GetTeamNumber(),        --команда юнита
                        npc.vInitialSpawnPos,        --местоположение юнита
                        nil,    --айди юнита (необязательно)
                        search_radius + 50,    --радиус поиска
                        DOTA_UNIT_TARGET_TEAM_ENEMY,    -- юнитов чьей команды ищем вражеской/дружественной
                        DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,    --юнитов какого типа ищем
                        DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES + DOTA_UNIT_TARGET_FLAG_FOW_VISIBLE,    --поиск по флагам
                        FIND_CLOSEST,    --сортировка от ближнего к дальнему
                        false )

    if #enemies == 0 then    -- если найденных юнитов нету
        if npc.agro then
            RetreatHome()    -- если юнит под действием агра
        end     
        return 0.5
    end
 
    local enemy = enemies[1]    -- врагом выбирается первый близжайший
 
 
    if npc.agro then    -- если юнит находится под действием агра
      
        AttackMove(npc, enemy)
--        npc:MoveToPositionAggressive(enemy:GetAbsOrigin())

        TryCastAbility(npc.ability0, npc, enemy)    -- попытка использовать способность
        TryCastAbility(npc.ability1, npc, enemy)    -- попытка использовать способность
        TryCastAbility(npc.ability2, npc, enemy)    -- попытка использовать способность
        TryCastAbility(npc.ability3, npc, enemy)    -- попытка использовать способность
        TryCastAbility(npc.ability4, npc, enemy)    -- попытка использовать способность
        TryCastAbility(npc.ability5, npc, enemy)    -- попытка использовать способность
    else
        local allies = FindUnitsInRadius(    -- ищет всех союзных братков в радиусе
                npc:GetTeamNumber(),
                npc.vInitialSpawnPos,
                nil,
                npc.fMaxDist,
                DOTA_UNIT_TARGET_TEAM_FRIENDLY,
                DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
                DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES + DOTA_UNIT_TARGET_FLAG_FOW_VISIBLE,
                FIND_CLOSEST,
                false )
              
        for i=1,#allies do    -- заставляет братков быть агрессивными и атаковать врага
            local ally = allies[i]
            ally.agro = true    -- накладывает действие агра
            AttackMove(ally, enemy)
        end
    end
    return 1
 
end

function FindAbility(unit, index)
    local ability = unit:GetAbilityByIndex(index)
 
    if ability then
        local ability_behavior = ability:GetBehavior()
      
        if bit.band( ability_behavior, DOTA_ABILITY_BEHAVIOR_PASSIVE ) == DOTA_ABILITY_BEHAVIOR_PASSIVE then
            ability.behavior = "passive"    -- способность пассивна
        elseif bit.band( ability_behavior, DOTA_ABILITY_BEHAVIOR_UNIT_TARGET ) == DOTA_ABILITY_BEHAVIOR_UNIT_TARGET then
            ability.behavior = "target"        -- способность направлена на юнита
        elseif bit.band( ability_behavior, DOTA_ABILITY_BEHAVIOR_NO_TARGET ) == DOTA_ABILITY_BEHAVIOR_NO_TARGET then
            ability.behavior = "no_target"    -- способность без цели
        elseif bit.band( ability_behavior, DOTA_ABILITY_BEHAVIOR_POINT ) == DOTA_ABILITY_BEHAVIOR_POINT then
            ability.behavior = "point"        -- способность направлена на точку
        end
        print("ability #"..index.." name = "..ability:GetAbilityName())
    print("ability behavior = "..ability.behavior)
      
        return ability
    else
       print("ability #"..index.."not found !!!")
        return nil
    end
 
end

function TryCastAbility(ability, caster, enemy)
 
    if ability == nil -- способность существует ?
    or  not ability:IsFullyCastable()     -- способность можно использовать?
    or ability.behavior == "passive"  then
        return
    end
 
    local order_type

    print("CAST ABIITY")
    print("ability behavior = "..ability.behavior)
    print("enemy = "..enemy:GetUnitName())
    print("caster = "..caster:GetUnitName())

    -- теперь определяется каким образом будет использованна способность
 
    if ability.behavior == "target" then
        order_type = DOTA_UNIT_ORDER_CAST_TARGET    -- на цель
    elseif ability.behavior == "no_target" then
        order_type = DOTA_UNIT_ORDER_CAST_NO_TARGET    -- без цели
    elseif ability.behavior == "point" then
        order_type = DOTA_UNIT_ORDER_CAST_POSITION    -- на точку
    elseif ability.behavior == "passive" then
        return
    end
 
    ExecuteOrderFromTable({
        UnitIndex = caster:entindex(),        -- индекс кастера
        OrderType = order_type,                -- тип приказа
        AbilityIndex = ability:entindex(),    -- индекс способности
        TargetIndex = enemy:entindex(),     -- индекс врага
        Position = enemy:GetOrigin(),         -- положение врага
        Queue = false,                        -- ждать очереди ?
    })
    caster:SetContextThink( "NeutralAutoCasterThink", NeutralAutoCasterThink, 1 ) -- если способность использована, то поведение начинается заного
 
end

function AttackMove( unit, enemy )
    if enemy == nil then
        return
    end
--    print("ATTACK MOVE")
    ExecuteOrderFromTable({
        UnitIndex = unit:entindex(),                --индекс кастера
        OrderType = DOTA_UNIT_ORDER_ATTACK_MOVE,    -- тип приказа атака
        Position = enemy:GetOrigin(),                -- пощиция врага
        Queue = false,
    })

    return 1
end

function RetreatHome()
    thisEntity.agro = false    -- снимается действие агра

    ExecuteOrderFromTable({
        UnitIndex = thisEntity:entindex(),
        OrderType = DOTA_UNIT_ORDER_MOVE_TO_POSITION,
        Position = thisEntity.vInitialSpawnPos     
    })
end

вот код юнита
KV:
"npc_dota_Boss"
    {
        "BaseClass" "npc_dota_creature"
        "Model" "models/heroes/ember_spirit/ember_spirit.vmdl"
        "ModelScale"      "3" //размер модели
        "SoundSet"                    "Hero_EmberSpirit"                   
        "IsNeutralUnitType"            "1"
        "Level"                        "100"
        "IsAncient"          "1"
        "vscripts"                    "heroes/boss/UnitsAI"
        // Abilities
        //----------------------------------------------------------------
        "ConsideredHero"            "1"
        "Ability8"                    "Res"           
                "Ability6"                    "afterburn_lua"       
            
        "Ability1"                    "legion_commander_moment_of_courage"           
        "Ability3"                    "truestrike"           
        "Ability4"                    "Resist_lua"           
        "Ability5"                    "Resist_lua2"           
        "Ability2"                    "zuus_lightning_bolt"           
        "MinimapIcon"        "minimap_candybucket"

        "MinimapIconSize"      "1000"

        // Armor
        //----------------------------------------------------------------
        "ArmorPhysical"                "80"            // Physical protection.
        "MagicalResistance"                "80"            // Magical protection.

        // Attack
        //----------------------------------------------------------------
        "AttackCapabilities"        "DOTA_UNIT_CAP_MELEE_ATTACK"
        "AttackDamageMin"            "1200"        // Damage range min.
        "AttackDamageMax"            "1500"        // Damage range max.
        "AttackDamageType"            "DAMAGE_TYPE_ArmorPhysical"
        "AttackRate"                "0.25"            // Speed of attack.
        "AttackAnimationPoint"        "0.467"        // Normalized time in animation cycle to attack.
        "AttackAcquisitionRange"    "500"        // Range within a target can be acquired.
        "AttackRange"                "100"        // Range within a target can be attacked.
        "ProjectileModel"            ""            // Particle system model for projectile.
        "ProjectileSpeed"            ""            // Speed of projectile.

        // Attributes
        //----------------------------------------------------------------
        "AttributePrimary"            "DOTA_ATTRIBUTE_STRENGTH"
        "AttributeBaseStrength"        "0"            // Base strength
        "AttributeStrengthGain"        "0"            // Strength bonus per level.
        "AttributeBaseIntelligence"    "0"            // Base intelligence
        "AttributeIntelligenceGain"    "0"            // Intelligence bonus per level.
        "AttributeBaseAgility"        "0"            // Base agility
        "AttributeAgilityGain"        "0"            // Agility bonus per level.
        // Bounty
        //----------------------------------------------------------------
        "BountyXP"                    "1000000"        // Experience earn.
        "BountyGoldMin"                "99999"        // Gold earned min.
        "BountyGoldMax"                "99999"        // Gold earned max.

        // Bounds
        //----------------------------------------------------------------
        "BoundsHullName"            "DOTA_HULL_SIZE_REGULAR"            // Hull type used for navigation/locomotion.
        "RingRadius"                "100"
        "HealthBarOffset"            "130"

        // Movement
        //----------------------------------------------------------------
        "MovementCapabilities"        "DOTA_UNIT_CAP_MOVE_GROUND"            // Type of locomotion - ground, air
        "MovementSpeed"                "300"        // Speed
        "MovementTurnRate"            "0.5"        // Turning rate.

        // Status
        //----------------------------------------------------------------
        "StatusHealth"                "500000"        // Base health.
        "StatusHealthRegen"            "70"        // Health regeneration rate.
        "StatusMana"                "1000000"            // Base mana.
        "StatusManaRegen"            "12"            // Mana regeneration rate.

        // Team
        //----------------------------------------------------------------
        "TeamName"                    "DOTA_TEAM_NEUTRALS"            // Team name.
        "CombatClassAttack"            "DOTA_COMBAT_CLASS_ATTACK_BASIC"
        "CombatClassDefend"            "DOTA_COMBAT_CLASS_DEFEND_SOFT"
        "UnitRelationshipClass"        "DOTA_NPC_UNIT_RELATIONSHIP_TYPE_DEFAULT"
            "UseNeutralCreepBehavior"    "0"

        // Vision
        //----------------------------------------------------------------
        "VisionDaytimeRange"        "850"        // Range of vision during day light.
        "VisionNighttimeRange"        "800"        // Range of vision at night time.
        "CanRespawn"                "1"
        "TeamName"                                    "DOTA_TEAM_NEUTRALS"
        "CombatClassAttack"                           "DOTA_COMBAT_CLASS_ATTACK_HERO"
        "CombatClassDefend"                           "DOTA_COMBAT_CLASS_DEFEND_HERO"
        "UnitRelationshipClass"                       "DOTA_NPC_UNIT_RELATIONSHIP_TYPE_HERO"
        "HasInventory"        "1"
        "Creature"
        {
            
            "DisableClumpingBehavior"    "1"   
             "DisableWearables"    "1"
        "AttachWearables"//The Jade General
        {
        "Wearable1" {"ItemDef" "7884"}//belt("Belt of the Smoldering Sage")
        "Wearable2" {"ItemDef" "7883"}//arms("Armguards of the Smoldering Sage")
        "Wearable3" {"ItemDef" "7881"}//shoulder("Mantle of the Smoldering Sage")
        "Wearable4" {"ItemDef" "7880"}//("Sword of the Smoldering Sage")
        "Wearable5" {"ItemDef" "7879"}//offhand_weapon("Off-Hand Sword of the Smoldering Sage")
        "Wearable6" {"ItemDef" "7882"}//head("Cap of the Smoldering Sage")
        }
        }
    }
 
Вижу, что ты не указал первоисточник, это ведь мой гайд.
Ошибку выдает потому что метод название функции поменялось
Было GetBehavir , стало GetBehaviorInt
Обновил гайд
 
Реклама: