Для того чтобы создать поведение юнита необходимо соблюсти несколько условий
Юнит в файле npc_units_custom
Базовый класс юнита "BaseClass" "npc_dota_creature"
Ссылка на исполняемый файл у юнита "vscripts" "ai/ai_necro_lord.lua"
Исполняемый файл "ai/ai_necro_lord.lua"
Для примера я привел поведение Босса Некроманта из моей кастомки , который имеет 4 активные способности :
"necrolyte_boss_death_pulse" способность без цели кастуется когда рядом находится герой
"necrolyte_sadist" способность без цели кастуется , когда здоровье юнита меньше 30%
"creature_reapers_scythe" способность кастуется на цель , когда её здоровье меньше 35%
"item_imba_shivas_guard" предмет кастуется без цели , когда здоровье юнита меньше 30%
Скорее всего я что-то упустил , гайд по моему не полный.
Но тем не менее я старался.
Надеюсь у вас все получится !
Юнит в файле npc_units_custom
Базовый класс юнита "BaseClass" "npc_dota_creature"
Ссылка на исполняемый файл у юнита "vscripts" "ai/ai_necro_lord.lua"
Исполняемый файл "ai/ai_necro_lord.lua"
Для примера я привел поведение Босса Некроманта из моей кастомки , который имеет 4 активные способности :
"necrolyte_boss_death_pulse" способность без цели кастуется когда рядом находится герой
"necrolyte_sadist" способность без цели кастуется , когда здоровье юнита меньше 30%
"creature_reapers_scythe" способность кастуется на цель , когда её здоровье меньше 35%
"item_imba_shivas_guard" предмет кастуется без цели , когда здоровье юнита меньше 30%
Код:
"npc_dota_necro_lord"
{
// General
//
"vscripts" "ai/ai_necro_lord.lua"
"BaseClass" "npc_dota_creature"
"Model" "models/heroes/necrolyte/necrolyte.vmdl" // Model.
"SoundSet" "Hero_Necrolyte" // Name of sound set.
"ModelScale" "1.76" // old 1.0
"Level" "50"
"HasInventory" "1"
"UseNeutralCreepBehavior" "0"
"precache"
{
"particle" "particles/econ/items/necrolyte/necrophos_sullen_gold/necro_sullen_pulse_enemy_gold.vpcf"
}
// Abilities
//----------------------------------------------------------------
"Ability1" "necrolyte_boss_death_pulse"
"Ability2" "necrolyte_sadist"
"Ability3" "necrolyte_heartstopper_aura"
"Ability4" "creature_reapers_scythe"
"Ability5" "" // Ability 5.
"Ability6" "" // Ability 6 - Extra.
"Ability7" "" // Ability 7 - Extra.
"Ability8" "" // Ability 8 - Extra.
// Armor
//----------------------------------------------------------------
"ArmorPhysical" "150" // Physical protection.
"MagicalResistance" "25" // Magical protection.
// Attack
//----------------------------------------------------------------
"AttackCapabilities" "DOTA_UNIT_CAP_RANGED_ATTACK"
"AttackDamageMin" "5000" // Damage range min.
"AttackDamageMax" "10000" // Damage range max.
"AttackDamageType" "DAMAGE_TYPE_ArmorPhysical"
"AttackRate" "0.75" // Speed of attack.
"AttackAnimationPoint" "0.01" // Normalized time in animation cycle to attack.
"AttackAcquisitionRange" "1500" // Range within a target can be acquired.
"AttackRange" "750" // Range within a target can be attacked.
"ProjectileModel" "particles/econ/items/necrolyte/necrophos_sullen_gold/necro_sullen_pulse_enemy_gold.vpcf"
"ProjectileSpeed" "1100" // 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" "100" // Experience earn.
"BountyGoldMin" "100" // Gold earned min.
"BountyGoldMax" "100" // Gold earned max.
// Bounds
//----------------------------------------------------------------
"BoundsHullName" "DOTA_HULL_SIZE_REGULAR" // Hull type used for navigation/locomotion.
"RingRadius" "45"
"HealthBarOffset" "150"
// Movement
//----------------------------------------------------------------
"MovementCapabilities" "DOTA_UNIT_CAP_MOVE_GROUND" // Type of locomotion - ground, air
"MovementSpeed" "425" // Speed
"MovementTurnRate" "0.2" // Turning rate.
// Status
//----------------------------------------------------------------
"StatusHealth" "325000" // Base health.
"StatusHealthRegen" "600" // Health regeneration rate.
"StatusMana" "100000" // Base mana.
"StatusManaRegen" "100" // Mana regeneration rate.
// Team
//----------------------------------------------------------------
"TeamName" "DOTA_TEAM_BADGUYS" // Team name.
"CombatClassAttack" "DOTA_COMBAT_CLASS_ATTACK_BASIC"
"CombatClassDefend" "DOTA_COMBAT_CLASS_DEFEND_BASIC"
"UnitRelationshipClass" "DOTA_NPC_UNIT_RELATIONSHIP_TYPE_DEFAULT"
// Vision
//----------------------------------------------------------------
"VisionDaytimeRange" "1750" // Range of vision during day light.
"VisionNighttimeRange" "1750" // Range of vision at night time.
//Inventory
"Creature"
{
"CanRespawn" "0"
"DisableResistance" "95.0"
"AttachWearables"
{
"Wearable1"
{
"ItemDef" "508"
}
"Wearable3"
{
"ItemDef" "212" //body
}
"Wearable4"
{
"ItemDef" "213" //head
}
"Wearable6"
{
"ItemDef" "9089" //weapon
}
"Wearable7"
{
"ItemDef" "7508" //shoulder
}
}
"EquippedItems"
{
"1" {"Item" "item_shivas_guard"}
}
}
}
Код:
function Spawn( entityKeyValues ) -- вызывается когда юнит появляется
if not IsServer() then -- если сервер не отвечает
return
end
if thisEntity == nil then -- если данного юнита не существует
return
end
local waypoint = Entities:FindByName( nil, "d_waypoint19") -- Записываем в переменную 'waypoint' координаты бокса d_waypoint19
if waypoint then thisEntity:SetInitialGoalEntity( waypoint ) end-- Посылаем моба на наш d_waypoint19, координаты которого мы записали в переменную 'waypoint'
NoTargetAbility1 = thisEntity:FindAbilityByName( "necrolyte_boss_death_pulse" )
NoTargetAbility2 = thisEntity:FindAbilityByName( "necrolyte_sadist" )
TargetAbility = thisEntity:FindAbilityByName( "creature_reapers_scythe" )
ItemAbility = FindItemAbility( thisEntity, "item_shivas_guard" )
thisEntity:SetContextThink( "NecroLordThink", NecroLordThink, 1 ) -- поведение юнита каждую секунду
end
function NecroLordThink()
if ( not thisEntity:IsAlive() ) then --если юнит мертв
return -1
end
if GameRules:IsGamePaused() == true then --если игра приостановлена
return 1
end
local enemies = FindUnitsInRadius(
thisEntity:GetTeamNumber(), --команда юнита
thisEntity:GetOrigin(), --местоположение юнита
nil, --айди юнита (необязательно)
1250, --радиус поиска
DOTA_UNIT_TARGET_TEAM_ENEMY, -- юнитов чьей команды ищем вражеской/дружественной
DOTA_UNIT_TARGET_HERO, --юнитов какого типа ищем
DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES + DOTA_UNIT_TARGET_FLAG_NO_INVIS, --поиск по флагам
FIND_CLOSEST, --сортировка от ближнего к дальнему или от дальнего к ближнему
false )
if #enemies > 0 then -- если количество найденных юнитов больше нуля
if NoTargetAbility1 ~= nil and NoTargetAbility1:IsFullyCastable() then --если абилка существует и её можно использовать
return NoTargetAbility1Cast()
end
if NoTargetAbility2 ~= nil and NoTargetAbility2:IsFullyCastable() then --если абилка существует и её можно использовать
if thisEntity:GetHealth() < ( thisEntity:GetMaxHealth() * 0.3 ) then
NoTargetAbility2Cast()
end
end
if TargetAbility ~= nil and TargetAbility:IsFullyCastable() then --если абилка существует и её можно использовать
for i=1, #enemies do
if enemies[i]:GetHealth() < (enemies[i]:GetMaxHealth() * 0.35 ) then
TargetAbilityCast( enemies[i])
end
end
end
if ItemAbility ~= nil and ItemAbility:IsFullyCastable() then --если предмет существует и её можно использовать
if thisEntity:GetHealth() < ( thisEntity:GetMaxHealth() * 0.3 ) then
ItemAbilityCast()
end
end
end
return 0.5
end
function NoTargetAbility1Cast()
ExecuteOrderFromTable({
UnitIndex = thisEntity:entindex(), --индекс кастера
OrderType = DOTA_UNIT_ORDER_CAST_NO_TARGET, -- тип приказа
AbilityIndex = NoTargetAbility1:entindex(), -- индекс способности
Queue = false,
})
return 1.5
end
function NoTargetAbility2Cast()
ExecuteOrderFromTable({
UnitIndex = thisEntity:entindex(), --индекс кастера
OrderType = DOTA_UNIT_ORDER_CAST_NO_TARGET, -- тип приказа
AbilityIndex = NoTargetAbility2:entindex(), -- индекс способности
Queue = false,
})
return 1.5
end
function TargetAbilityCast( enemy )
ExecuteOrderFromTable({
UnitIndex = thisEntity:entindex(), --индекс кастера
OrderType = DOTA_UNIT_ORDER_CAST_TARGET, -- тип приказа
AbilityIndex = TargetAbility:entindex(), -- индекс способности
TargetIndex = enemy:entindex(),
Queue = false,
})
return 1.5
end
function ItemAbilityCast()
ExecuteOrderFromTable({
UnitIndex = thisEntity:entindex(), --индекс кастера
OrderType = DOTA_UNIT_ORDER_CAST_NO_TARGET, -- тип приказа
AbilityIndex = ItemAbility:entindex(), -- индекс способности
Queue = false,
})
return 1
end
function FindItemAbility( hCaster, szItemName ) --необходимая утилита , без нее не будет работать функция FindItemAbility
for i = 0, 5 do
local item = hCaster:GetItemInSlot( i )
if item then
if item:GetAbilityName() == szItemName then
return item
end
end
end
end
Скорее всего я что-то упустил , гайд по моему не полный.
Но тем не менее я старался.
Надеюсь у вас все получится !
Последнее редактирование модератором: