SHARE
TWEET

Untitled

a guest Oct 21st, 2019 85 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. function Spawn( entityKeyValues )
  2.     if not IsServer() then
  3.         return
  4.     end
  5.  
  6.     if thisEntity == nil then
  7.         return
  8.     end
  9.    
  10.     thisEntity:SetContextThink( "NeutralAutoCasterThink", NeutralAutoCasterThink, 1 )
  11. end
  12.  
  13. function NeutralAutoCasterThink()
  14.     if ( not thisEntity:IsAlive() ) then        --если юнит мертв
  15.         return -1  
  16.     end
  17.    
  18.     if GameRules:IsGamePaused() == true then    --если игра приостановлена
  19.         return 1   
  20.     end
  21.  
  22.     if thisEntity:IsChanneling() then   -- если юнит кастует скил
  23.         return 1   
  24.     end
  25.    
  26.     if thisEntity:IsControllableByAnyPlayer() then  -- если юнит принадлежит игроку, то поведение отключается
  27.         return -1
  28.     end
  29.    
  30.     local npc = thisEntity
  31.  
  32.     if not thisEntity.bInitialized then
  33.         npc.vInitialSpawnPos = npc:GetOrigin()      -- точка спавна юнита
  34.         npc.fMaxDist = npc:GetAcquisitionRange()    -- радиус агра
  35.         npc.bInitialized = true                     -- флаг инициализации
  36.         npc.agro = false                            -- флаг агра
  37.        
  38.         npc.ability0 = FindAbility(npc, 0)          -- ищет способность по индексу
  39.         npc.ability1 = FindAbility(npc, 1)          -- ищет способность по индексу
  40.         npc.ability2 = FindAbility(npc, 2)          -- ищет способность по индексу
  41.         npc.ability3 = FindAbility(npc, 3)          -- ищет способность по индексу
  42.         npc.ability4 = FindAbility(npc, 4)          -- ищет способность по индексу
  43.         npc.ability5 = FindAbility(npc, 5)          -- ищет способность по индексу
  44.        
  45.     end
  46.  
  47.     local search_radius                             -- радиус поиска зависит от того, имеет ли юнит агр
  48.     if npc.agro then
  49.         search_radius = npc.fMaxDist * 1.5          -- расшираяется
  50.     else
  51.         search_radius = npc.fMaxDist                -- становится обычным
  52.     end
  53.    
  54.     -- Как далеко юнит находится от своей точки спавна ?
  55.     local fDist = ( npc:GetOrigin() - npc.vInitialSpawnPos ):Length2D()
  56.     if fDist > search_radius then
  57.         RetreatHome()           -- если юнит слишком далеко, то идет на точку спавна
  58.         return 3
  59.     end
  60.    
  61.     local enemies = FindUnitsInRadius(
  62.                         npc:GetTeamNumber(),        --команда юнита
  63.                         npc.vInitialSpawnPos,       --местоположение юнита
  64.                         nil,    --айди юнита (необязательно)
  65.                         search_radius + 50, --радиус поиска
  66.                         DOTA_UNIT_TARGET_TEAM_ENEMY,    -- юнитов чьей команды ищем вражеской/дружественной
  67.                         DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC, --юнитов какого типа ищем
  68.                         DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES + DOTA_UNIT_TARGET_FLAG_FOW_VISIBLE, --поиск по флагам
  69.                         FIND_CLOSEST,   --сортировка от ближнего к дальнему
  70.                         false )
  71.  
  72.     if #enemies == 0 then   -- если найденных юнитов нету
  73.         if npc:HasModifier("modifier_agro") then
  74.             RetreatHome()   -- если юнит под действием агра
  75.         end    
  76.         return 0.5
  77.     end
  78.    
  79.     local enemy = enemies[1]    -- врагом выбирается первый близжайший
  80.    
  81.    
  82.     if npc.agro then    -- если юнит находится под действием агра
  83.        
  84.         AttackMove(npc, enemy)
  85. --      npc:MoveToPositionAggressive(enemy:GetAbsOrigin())
  86.  
  87.         TryCastAbility(npc.ability0, npc, enemy)    -- попытка использовать способность
  88.         TryCastAbility(npc.ability1, npc, enemy)    -- попытка использовать способность
  89.         TryCastAbility(npc.ability2, npc, enemy)    -- попытка использовать способность
  90.         TryCastAbility(npc.ability3, npc, enemy)    -- попытка использовать способность
  91.         TryCastAbility(npc.ability4, npc, enemy)    -- попытка использовать способность
  92.         TryCastAbility(npc.ability5, npc, enemy)    -- попытка использовать способность
  93.     else
  94.         local allies = FindUnitsInRadius(   -- ищет всех союзных братков в радиусе
  95.                 npc:GetTeamNumber(),
  96.                 npc.vInitialSpawnPos,
  97.                 nil,
  98.                 npc.fMaxDist,
  99.                 DOTA_UNIT_TARGET_TEAM_FRIENDLY,
  100.                 DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC,
  101.                 DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES + DOTA_UNIT_TARGET_FLAG_FOW_VISIBLE,
  102.                 FIND_CLOSEST,
  103.                 false )
  104.                
  105.         for i=1,#allies do  -- заставляет братков быть агрессивными и атаковать врага
  106.             local ally = allies[i]
  107.             ally.agro = true    -- накладывает действие агра
  108.             AttackMove(ally, enemy)
  109.         end
  110.     end
  111.     return 1
  112.    
  113. end
  114.  
  115. function FindAbility(unit, index)
  116.     local ability = unit:GetAbilityByIndex(index)
  117.    
  118.     if ability then
  119.         local ability_behavior = ability:GetBehavior()
  120.        
  121.         if bit.band( ability_behavior, DOTA_ABILITY_BEHAVIOR_PASSIVE ) == DOTA_ABILITY_BEHAVIOR_PASSIVE then
  122.             ability.behavior = "passive"    -- способность пассивна
  123.         elseif bit.band( ability_behavior, DOTA_ABILITY_BEHAVIOR_UNIT_TARGET ) == DOTA_ABILITY_BEHAVIOR_UNIT_TARGET then
  124.             ability.behavior = "target"     -- способность направлена на юнита
  125.         elseif bit.band( ability_behavior, DOTA_ABILITY_BEHAVIOR_NO_TARGET ) == DOTA_ABILITY_BEHAVIOR_NO_TARGET then
  126.             ability.behavior = "no_target"  -- способность без цели
  127.         elseif bit.band( ability_behavior, DOTA_ABILITY_BEHAVIOR_POINT ) == DOTA_ABILITY_BEHAVIOR_POINT then
  128.             ability.behavior = "point"      -- способность направлена на точку
  129.         end
  130. --      print("ability #"..index.." name = "..ability:GetAbilityName())
  131. --      print("ability behavior = "..ability.behavior)
  132.        
  133.         return ability
  134.     else
  135. --      print("ability #"..index.."not found !!!")
  136.         return nil
  137.     end
  138.    
  139. end
  140.  
  141. function TryCastAbility(ability, caster, enemy)
  142.    
  143.     if ability == nil -- способность существует ?
  144.     or  not ability:IsFullyCastable()   -- способность можно использовать?
  145.     or ability.behavior == "passive"    -- способность пассивна ?
  146.     or  enemy:IsMagicImmune()  then     -- цель имеет уммунитет к магии ?
  147.         return
  148.     end
  149.    
  150.     local order_type
  151. --[[   
  152.     print("CAST ABIITY")
  153.     print("ability behavior = "..ability.behavior)
  154.     print("enemy = "..enemy:GetUnitName())
  155.     print("caster = "..caster:GetUnitName())
  156. ]] 
  157.     -- теперь определяется каким образом будет использованна способность
  158.    
  159.     if ability.behavior == "target" then
  160.         order_type = DOTA_UNIT_ORDER_CAST_TARGET    -- на цель
  161.     elseif ability.behavior == "no_target" then
  162.         order_type = DOTA_UNIT_ORDER_CAST_NO_TARGET -- без цели
  163.     elseif ability.behavior == "point" then
  164.         order_type = DOTA_UNIT_ORDER_CAST_POSITION  -- на точку
  165.     elseif ability.behavior == "passive" then
  166.         return
  167.     end
  168.    
  169.     ExecuteOrderFromTable({
  170.         UnitIndex = caster:entindex(),      -- индекс кастера
  171.         OrderType = order_type,             -- тип приказа
  172.         AbilityIndex = ability:entindex(),  -- индекс способности
  173.         TargetIndex = enemy:entindex(),     -- индекс врага
  174.         Position = enemy:GetOrigin(),       -- положение врага
  175.         Queue = false,                      -- ждать очереди ?
  176.     })
  177.     caster:SetContextThink( "NeutralAutoCasterThink", NeutralAutoCasterThink, 1 ) -- если способность использована, то поведение начинается заного
  178.    
  179. end
  180.  
  181. function AttackMove( unit, enemy )
  182.     if enemy == nil then
  183.         return
  184.     end
  185. --  print("ATTACK MOVE")
  186.     ExecuteOrderFromTable({
  187.         UnitIndex = unit:entindex(),                --индекс кастера
  188.         OrderType = DOTA_UNIT_ORDER_ATTACK_MOVE,    -- тип приказа атака
  189.         Position = enemy:GetOrigin(),               -- пощиция врага
  190.         Queue = false,
  191.     })
  192.  
  193.     return 1
  194. end
  195.  
  196. function RetreatHome()
  197.     npc.agro = false    -- снимается действие агра
  198.  
  199.     ExecuteOrderFromTable({
  200.         UnitIndex = thisEntity:entindex(),
  201.         OrderType = DOTA_UNIT_ORDER_MOVE_TO_POSITION,
  202.         Position = thisEntity.vInitialSpawnPos     
  203.     })
  204. end
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top