Advertisement
Guest User

Untitled

a guest
Oct 21st, 2019
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.26 KB | None | 0 0
  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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement