--用向量的叉乘判断p在有向直线ab的左边还是右边,直线ab将平面分成两块左边和右边 function GetLeftRightSide(a,b,p) return (b.x-a.x) * (p.y-a.y) - (p.x-a.x) * (b.y-a.y) end --循环判断p是否在有向直线ab,bc,cd,da的同向,这些直线的左边或者右边构成这个四边形 function IsInQuadrangle(point, a, b, c, d) local ab_side = GetLeftRightSide(a,b,point) local bc_side = GetLeftRightSide(b,c,point) local cd_side = GetLeftRightSide(c,d,point) local da_side = GetLeftRightSide(d,a,point) return (ab_side>=0 and bc_side>=0 and cd_side>=0 and da_side>=0) or (ab_side<=0 and bc_side<=0 and cd_side<=0 and da_side<=0) end --这里的width不是长方形的宽,而是直线技能得左右宽度 function THTD_FindUnitsInLine(caster, point, forward, width, length) if caster:THTD_IsTower() then forward = forward:Normalized() local orth_Vec = Vector(forward.y, -forward.x, 0) local a = point + orth_Vec * width local b = a + forward * length local c = b - orth_Vec * width * 2 local d = c - forward * length local targets = {} local enemies = THTD_FindUnitsAll(caster) for _,v in pairs(enemies) do if v~=nil and v:IsNull()==false and IsInQuadrangle(v:GetAbsOrigin(), a, b, c, d) then table.insert(targets, v) end end return targets end end function THTD_RandomUnitSelection(inputs, count) if #inputs<=count then return inputs end for i=2,#inputs do local j = RandomInt(1, i) if j~=i then local tmp = inputs[i] inputs[i] = inputs[j] inputs[j] = tmp end end local outputs = {} for i=1,count do table.insert(outputs, inputs[i]) end return outputs end FirstPointList = { [0] = Vector(-1408, 1056,0), [1] = Vector( 1408, 1056,0), [2] = Vector( 1408,-1056,0), [3] = Vector(-1408,-1056,0), } function GetUnitBackWardVector(unit, id) return (FirstPointList[id] - unit:GetAbsOrigin()):Normalized() end if THTDSystem == nil then THTDSystem = {} end function THTDSystem:FindFriendlyRadiusOneUnitLast( entity, range) if THTD_IsValid(entity.thtd_last_cast_unit) and GetDistanceBetweenTwoVec2D(entity:GetOrigin(),entity.thtd_last_cast_unit:GetOrigin()) <= range then return entity.thtd_last_cast_unit end local friends = THTD_FindFriendlyUnitsInRadius(entity,entity:GetOrigin(),range) if #friends > 0 then local index = RandomInt(1, #friends) entity.thtd_last_cast_unit = friends[index] return friends[index] else return nil end end function THTDSystem:FindRadiusWeakOneUnit( entity, range, ...) local condition = ... if condition == nil then condition = function(...) return true end end local isFlandre = (entity:GetUnitName() == "flandre") local enemies = THTD_FindUnitsInRadius(entity, entity:GetOrigin(), range) if #enemies > 0 then local weakUnit = nil for k,v in pairs(enemies) do if v~=nil and v:IsNull()==false and v:IsAlive() and v.thtd_damage_lock ~= true and condition(v) then if weakUnit == nil or weakUnit:IsNull() or weakUnit:IsAlive() == false then weakUnit = v else local factor = 1.0 local factor2 = 1.0 if isFlandre and v:HasModifier("modifier_remilia_03_debuff") then factor = 1.6 end if isFlandre and weakUnit:HasModifier("modifier_remilia_03_debuff") then factor2 = 1.6 end if v:GetHealth()/factor < weakUnit:GetHealth()/factor2 then weakUnit = v end end end end return weakUnit else return nil end end function THTDSystem:FindRadiusMostHpOneUnit(entity, range, ...) local condition = ... if condition == nil then condition = function(...) return true end end local enemies = THTD_FindUnitsInRadius(entity, entity:GetOrigin(), range) if #enemies > 0 then local weakUnit = nil for k,v in pairs(enemies) do if v~=nil and v:IsNull()==false and v:IsAlive() and v.thtd_damage_lock ~= true and condition(v) then if weakUnit == nil or weakUnit:IsNull() or weakUnit:IsAlive() == false then weakUnit = v elseif v:GetHealth() > weakUnit:GetHealth() then weakUnit = v end end end return weakUnit else return nil end end function THTDSystem:FindRadiusLowHpOneUnit(entity, range, ...) local condition = ... if condition == nil then condition = function(...) return true end end local enemies = THTD_FindUnitsInRadius(entity, entity:GetOrigin(), range) if #enemies > 0 then local weakUnit = nil for k,v in pairs(enemies) do if v~=nil and v:IsNull()==false and v:IsAlive() and v.thtd_damage_lock ~= true and condition(v) then if weakUnit == nil or weakUnit:IsNull() or weakUnit:IsAlive() == false then weakUnit = v elseif v:GetHealth() < weakUnit:GetHealth() then weakUnit = v end end end return weakUnit else return nil end end function THTDSystem:FindRadiusLonelyOneUnit( entity, range , lonelyCount) local enemies = THTD_FindUnitsInRadius(entity, entity:GetOrigin(), range) if #enemies > 0 then local lonelyUnit = nil for k,v in pairs(enemies) do local units = THTD_FindFriendlyUnitsInRadius(entity,v:GetOrigin(),range) if #units <= lonelyCount then lonelyUnit = v break end end return lonelyUnit else return nil end end function THTDSystem:FindFriendlyRadiusOneUnit( entity, range) local friends = THTD_FindFriendlyUnitsInRadius(entity,entity:GetOrigin(),range) if #friends > 0 then local index = RandomInt( 1, #friends ) return friends[index] else return nil end end function THTDSystem:FindFriendlyHighestStarRadiusOneUnit( entity, range) local friends = THTD_FindFriendlyUnitsInRadius(entity,entity:GetOrigin(),range) if #friends > 0 then local highestUnit = nil for k,v in pairs(friends) do if v:THTD_IsTower() and v~=entity and v:THTD_GetLevel()<10 then if highestUnit == nil then highestUnit = v end if v:THTD_GetStar() > highestUnit:THTD_GetStar() then highestUnit = v end end end return highestUnit else return nil end end function THTDSystem:FindRadiusOnePointLastCast( entity, range) local point = entity.thtd_last_cast_point if point == nil or GetDistanceBetweenTwoVec2D(point, entity:GetOrigin()) > range then local unit = THTDSystem:FindRadiusOneUnit(entity, range) if unit~=nil and unit:IsNull()==false then point = unit:GetOrigin() end end return point end function THTDSystem:FindRadiusOnePointPerfectAOE( entity, range, AOErange) local enemies = THTD_FindUnitsInRadius(entity, entity:GetOrigin(), range) if #enemies > 10 then enemies = THTD_RandomUnitSelection(enemies, 10) end local target,maxCount = nil, 0 for k,v in pairs(enemies) do if v~=nil and v:IsNull()==false then local count = THTDSystem:FindUnitCountInPoint(entity, v:GetAbsOrigin(), AOErange) if target == nil or count > maxCount then target = v maxCount = count end end end if target~=nil then return target:GetAbsOrigin(), maxCount, target end return nil, 0 end function THTDSystem:FindRadiusOnePointPerfectLineAOE(entity, range, width, length, onlyInner) local enemies = THTD_FindUnitsInRadius(entity, entity:GetOrigin(), range) if #enemies > 10 then enemies = THTD_RandomUnitSelection(enemies, 10) end local target,maxCount = nil, 0 for k,v in pairs(enemies) do if v~=nil and v:IsNull()==false and not (onlyInner and v.thtd_is_outer==true) then local forward = (v:GetAbsOrigin() - entity:GetAbsOrigin()):Normalized() local count = THTDSystem:FindUnitCountInLine(entity, entity:GetOrigin(), forward, width, length) if target == nil or count > maxCount then target = v maxCount = count end end end if target~=nil then return target:GetAbsOrigin(), maxCount, target end return nil end function THTDSystem:CastAbility(unit,ability) if ability:IsUnitTarget() then local teams = DOTA_UNIT_TARGET_TEAM_ENEMY local types = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC local flags = 0 local target = THTDSystem:FindRadiusOneUnit( unit,ability:GetCastRange(),teams,types,flags) if target then unit:THTD_SetAggressiveLock() unit:CastAbilityOnTarget(target,ability,target:GetPlayerOwnerID()) end elseif ability:IsPoint() or ability:GetBehavior() == 24 then local teams = DOTA_UNIT_TARGET_TEAM_ENEMY local types = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC local flags = 0 local target = THTDSystem:FindRadiusOneUnit( unit,ability:GetCastRange(),teams,types,flags) if target then unit:THTD_SetAggressiveLock() unit:CastAbilityOnPosition(target:GetOrigin(),ability,target:GetPlayerOwnerID()) end elseif ability:IsNoTarget() then unit:THTD_SetAggressiveLock() ability:CastAbility() end end function THTDSystem:CastAbilityFriendly( unit,ability) if ability:IsUnitTarget() then local teams = DOTA_UNIT_TARGET_TEAM_FRIENDLY local types = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC local flags = 0 local target = THTDSystem:FindFriendlyRadiusOneUnit( unit,ability:GetCastRange(),teams,types,flags) if target then unit:THTD_SetAggressiveLock() unit:CastAbilityOnTarget(target,ability,target:GetPlayerOwnerID()) end elseif ability:IsPoint() or ability:GetBehavior() == 24 then local teams = DOTA_UNIT_TARGET_TEAM_FRIENDLY local types = DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC local flags = 0 local target = THTDSystem:FindFriendlyRadiusOneUnit( unit,ability:GetCastRange(),teams,types,flags) if target then unit:THTD_SetAggressiveLock() unit:CastAbilityOnPosition(target:GetOrigin(),ability,target:GetPlayerOwnerID()) end elseif ability:IsNoTarget() then unit:THTD_SetAggressiveLock() ability:CastAbility() end end function THTDSystem:CastAbilityToUnit( unit,ability,target) if ability:IsUnitTarget() then unit:THTD_SetAggressiveLock() unit:CastAbilityOnTarget(target,ability,target:GetPlayerOwnerID()) elseif ability:IsPoint() or ability:GetBehavior() == 24 then unit:THTD_SetAggressiveLock() unit:CastAbilityOnPosition(target:GetOrigin(),ability,target:GetPlayerOwnerID()) end end function THTDSystem:FindRadiusOneUnit( entity, range) local enemies = THTD_FindUnitsInRadius(entity, entity:GetOrigin(), range) if #enemies > 0 then local index = RandomInt( 1, #enemies ) return enemies[index] else return nil end end function THTDSystem:FindRadiusOneUnitHasNoModifier(entity,range,modifierName) local enemies = THTD_FindUnitsInRadius(entity, entity:GetOrigin(), range) if #enemies > 0 then for k,v in pairs(enemies) do if v:HasModifier(modifierName) ~= true and v.thtd_damage_lock ~= true then return v end end return nil else return nil end end function THTDSystem:FindRadiusAllUnitHasNoModifier(entity,range,modifierName) local enemies = THTD_FindUnitsInRadius(entity, entity:GetOrigin(), range) local tb = {} if #enemies > 0 then for k,v in pairs(enemies) do if v:HasModifier(modifierName) ~= true and v.thtd_damage_lock ~= true then tb.insert(tb, v) end end end return tb end function THTDSystem:FindRadiusAllUnitHasModifier(entity,range,modifierName) local enemies = THTD_FindUnitsInRadius(entity, entity:GetOrigin(), range) local tb = {} if #enemies > 0 then for k,v in pairs(enemies) do if v:HasModifier(modifierName) then tb.insert(tb, v) end end end return tb end function THTDSystem:FindRadiusOneUnitHasNoStunned(entity,point,range) local enemies = THTD_FindUnitsInRadius(entity, point, range) if #enemies > 0 then for k,v in pairs(enemies) do if v:IsStunned() ~= true then return v end end return nil else return nil end end function THTDSystem:ChangeTargetHasNoDamageLock(entity, filter) local range = entity:Script_GetAttackRange() if range == nil then range = entity:GetBaseAttackRange() end if range == nil then range = 1000 end local enemies = THTD_FindUnitsInRadius(entity, entity:GetOrigin(), range) if #enemies > 0 then for k,v in pairs(enemies) do if v.thtd_damage_lock ~= true and ((filter ~=nil and filter(v)) or filter == nil) then return v end end end return entity:GetAttackTarget() end function THTDSystem:FindUnitCountInPoint( entity, point, range) local enemies = THTD_FindUnitsInRadius(entity, point, range) if #enemies > 0 then return #enemies else return 0 end end function THTDSystem:FindUnitCountInLine(entity, point, forward, width, length) local enemies = THTD_FindUnitsInLine(entity, point, forward, width, length) if #enemies > 0 then return #enemies else return 0 end end function THTDSystem:FindRadiousMostDangerousUnit(entity, range, ...) local enemies = THTD_FindUnitsInRadius(entity, entity:GetAbsOrigin(), range) local condition = ... if condition == nil then condition = function(...) return true end end local target = nil local maxdist = 0 local firstpoint = FirstPointList[entity:GetPlayerOwnerID()] if #enemies > 0 then for k,v in pairs(enemies) do if v~=nil and v:IsNull()==false and condition(v) then local dist = GetDistanceBetweenTwoVec2D(firstpoint, v:GetAbsOrigin()) if target == nil or dist > maxdist then target = v maxdist = dist end end end end return target, maxdist end function THTDSystem:ChangeAttackTarget(entity, target) local range = entity:Script_GetAttackRange() -- 获取真实射程, 7.20 GetAttackRange() 改名为 Script_GetAttackRange() if range == nil then range = entity:GetBaseAttackRange() end -- 此只能获取无加成的攻击距离 if range == nil then range = 1000 end if entity.thtd_changing_attack_target == true then return end entity.thtd_changing_attack_target = true local count = 3 entity:SetContextThink(DoUniqueString("thtd_change_attack_target"), function() if GameRules:IsGamePaused() then return 0.03 end if target==nil or target:IsNull() or target:IsAlive()==false or entity==nil or entity:IsNull() or entity:GetAttackTarget()==target or GetDistanceBetweenTwoEntity(entity,target)>range or count <= 0 then entity.thtd_changing_attack_target = false return nil end entity:MoveToTargetToAttack(target) count = count - 1 return 0.1 end, 0) end function THTDSystem:FindUtsuhoPerfectPoint(entity, range, AOErange) local unit = THTDSystem:FindRadiousMostDangerousUnit(entity, AOErange) if unit~=nil and unit:IsNull()==false then local Point = unit:GetAbsOrigin() + GetUnitBackWardVector(unit, entity:GetPlayerOwnerID()) * 280 return Point end local enemies = THTD_FindUnitsInRadius(entity, entity:GetAbsOrigin(), range+AOErange) local points = {} for k,v in pairs(enemies) do if v~=nil and v:IsNull()==false then local overlap = false local curpoint = v:GetAbsOrigin() for x,p in pairs(points) do if GetDistanceBetweenTwoVec2D(p, curpoint)<64 then overlap = true break end end if overlap==false then table.insert(points, curpoint) end end end local maxSumEffect = 0 local point = nil for k1,p1 in pairs(points) do if GetDistanceBetweenTwoVec2D(p1, entity:GetAbsOrigin()) <= range then local sumEffect = 0 local count = 0 for k2,p2 in pairs(points) do local dist = GetDistanceBetweenTwoVec2D(p1, p2) if dist < AOErange then sumEffect = sumEffect + dist count = count + 1 end end if sumEffect > maxSumEffect and count > 5 then maxSumEffect = sumEffect point = p1 end end end if maxSumEffect > 999 then return point end return nil end function CDOTA_BaseNPC:IsReadyToCastAbility(ability) return ability:IsFullyCastable() and self:IsChanneling() == false and THTD_IsSpellLock(self, ability:GetAbilityName()) == false end function CDOTA_BaseNPC:EnableAi() -- print("---------- AI start : ", self:GetUnitName()) self:SetContextThink(DoUniqueString("thtd_ai_think"), function() if GameRules:IsGamePaused() then return 0.1 end if self == nil or self:IsNull() or self:IsAlive() == false or self:THTD_IsHidden() then -- print("---------- AI close : ", self:GetUnitName()) return nil end if self.thtd_close_ai ~= true then local func = self["THTD_"..self:GetUnitName().."_thtd_ai"] if func then func(self) elseif self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end return 0.3 end, 0) end function CDOTA_BaseNPC:THTD_lily_thtd_ai() local ability1 = self:FindAbilityByName("thtd_lily_01") local ability2 = self:FindAbilityByName("thtd_lily_02") if self:IsReadyToCastAbility(ability2) and self:HasModifier("thtd_lily_02") == false then local unit = THTDSystem:FindRadiusOneUnit(self, 1000) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability2, self:GetPlayerOwnerID()) return end end if SpawnSystem.IsUnLimited and self:IsReadyToCastAbility(ability1) and THTD_HasUnitsInRadius(self, self:GetAbsOrigin(), ability1:GetCastRange()) then local point = self.thtd_last_cast_point if point == nil then point = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability1:GetCastRange(), ability1:GetSpecialValueFor("radius")) end if point ~= nil then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability1, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then -- IsAttacking() 实测只能判定是否正在攻击动作,不能判断是否在战斗中 self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_cirno_thtd_ai() local ability = self:FindAbilityByName("thtd_cirno_02") if self:IsReadyToCastAbility(ability) then local unit = THTDSystem:FindRadiusOneUnit(self,ability:GetCastRange()) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit, ability, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_letty_thtd_ai() local ability = self:FindAbilityByName("thtd_letty_01") if self:IsReadyToCastAbility(ability) then local unit = THTDSystem:FindRadiusOneUnit(self,ability:GetCastRange()) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(unit:GetAbsOrigin(), ability, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_kogasa_thtd_ai() local ability = self:FindAbilityByName("thtd_kogasa_01") if self:IsReadyToCastAbility(ability) then if self.thtd_last_cast_point ~= nil then local point = self.thtd_last_cast_point if THTD_HasUnitsInRadius(self, point, ability:GetSpecialValueFor("radius") * 0.7) then THTD_SetSpellLock(self, ability:GetAbilityName(), ability:GetSpecialValueFor("duration_time")) self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability, self:GetPlayerOwnerID()) return end else local unit = THTDSystem:FindRadiousMostDangerousUnit(self, ability:GetCastRange()) if unit ~= nil then local point = unit:GetAbsOrigin() if point.x <= -2400 or point.x >= 2400 then THTD_SetSpellLock(self, ability:GetAbilityName(), ability:GetSpecialValueFor("duration_time")) self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability, self:GetPlayerOwnerID()) return end end end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_lyrica_thtd_ai() local ability = self:FindAbilityByName("thtd_lyrica_01") if self:IsReadyToCastAbility(ability) then local unit = THTDSystem:FindRadiusOneUnit(self,ability:GetCastRange()) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(unit:GetAbsOrigin(), ability, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_lunasa_thtd_ai() local ability = self:FindAbilityByName("thtd_lunasa_01") if self:IsReadyToCastAbility(ability) then local unit = THTDSystem:FindRadiusOneUnit(self,ability:GetCastRange()) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(unit:GetAbsOrigin(), ability, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_merlin_thtd_ai() local ability = self:FindAbilityByName("thtd_merlin_01") if self:IsReadyToCastAbility(ability) then local unit = THTDSystem:FindRadiusOneUnit(self,ability:GetCastRange()) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(unit:GetAbsOrigin(), ability, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_satori_thtd_ai() local ability = self:FindAbilityByName("thtd_satori_01") if self:IsReadyToCastAbility(ability) then local unit = THTDSystem:FindRadiusOneUnitHasNoModifier(self, ability:GetCastRange()+500, "modifier_satori_01_debuff") if unit==nil or unit:IsNull()== false then unit = THTDSystem:FindRadiusOneUnit(self, 1000) end if unit~=nil and unit:IsNull()==false then local point = nil if GetDistanceBetweenTwoEntity(self, unit) > ability:GetCastRange() then local forward = (unit:GetAbsOrigin()-self:GetAbsOrigin()):Normalized() point = self:GetAbsOrigin() + forward * ability:GetCastRange() else point = unit:GetAbsOrigin() end self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_iku_thtd_ai() local ability = self:FindAbilityByName("thtd_iku_02") if self:IsReadyToCastAbility(ability) then local unit = THTDSystem:FindRadiusOneUnit(self,ability:GetCastRange()) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(unit:GetAbsOrigin(), ability, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_marisa_thtd_ai() if self.spelling_lock == true then return end local ability1 = self:FindAbilityByName("thtd_marisa_01") local ability3 = self:FindAbilityByName("thtd_marisa_03") if self:IsReadyToCastAbility(ability3) then local point = THTDSystem:FindRadiusOnePointPerfectLineAOE(self, ability3:GetCastRange(), 300, 1200, false) if point~=nil then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability3, self:GetPlayerOwnerID()) return end end if ability3:GetLevel() == 0 and self:IsReadyToCastAbility(ability1) then local point = THTDSystem:FindRadiusOnePointPerfectLineAOE(self, ability1:GetCastRange(), 300, 1200, false) if point~=nil then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability1, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false and self:IsChanneling() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_tenshi_thtd_ai() local ability = self:FindAbilityByName("thtd_tenshi_01") if self:IsReadyToCastAbility(ability) then local _,_,unit = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability:GetCastRange(), 400) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit, ability, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_patchouli_thtd_ai() local ability1 = self:FindAbilityByName("thtd_patchouli_01") local ability2 = self:FindAbilityByName("thtd_patchouli_02") local ability4 = self:FindAbilityByName("thtd_patchouli_04") if (self.thtd_patchouli_02_cast == nil or self.thtd_patchouli_02_cast == true) and self:IsReadyToCastAbility(ability2) then if self.thtd_patchouli_02_type == self.thtd_patchouli_02_cast_type then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability2, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability1) then local point = nil if self.thtd_patchouli_02_type == 1 then point = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability1:GetCastRange(), 300) elseif self.thtd_patchouli_02_type == 2 then local target = THTDSystem:FindRadiusOneUnitHasNoModifier(self, ability1:GetCastRange(), "modifier_patchouli_01_mercury_poison_debuff") if target==nil then target = THTDSystem:FindRadiusOneUnit(self, ability1:GetCastRange()) end if target~=nil then point = target:GetAbsOrigin() end else point = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability1:GetCastRange(), 350) end if point~=nil then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability1, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability4) and (THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), 800) > 5 or THTDSystem:FindRadiousMostDangerousUnit(self,400)~=nil) then THTD_SetSpellLock(self, ability4:GetAbilityName(), ability4:GetSpecialValueFor("duration_time")) self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability4, self:GetPlayerOwnerID()) return end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_hina_thtd_ai() local ability2 = self:FindAbilityByName("thtd_hina_02") if self:IsReadyToCastAbility(ability2) and THTD_HasUnitsInRadius(self, self:GetAbsOrigin(), ability2:GetCastRange()) then local point = self.thtd_last_cast_point if point == nil then point = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability2:GetCastRange(), ability2:GetSpecialValueFor("range")) end if point ~= nil then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability2, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_reisen_thtd_ai() local ability = self:FindAbilityByName("thtd_reisen_03") local range = self:Script_GetAttackRange() if range == nil then range = self:GetBaseAttackRange() end if range == nil then range = 1000 end local target = self:GetAttackTarget() if target == nil or target:IsNull() == true or target.thtd_is_feared_by_reisen_01 == true then target = THTDSystem:FindRadiousMostDangerousUnit(self, range, function(targetunit) return targetunit.thtd_is_feared_by_reisen_01~=true end) if target~=nil and target:IsNull()==false then THTDSystem:ChangeAttackTarget(self, target) end end if self:IsReadyToCastAbility(ability) then local unit = THTDSystem:FindRadiousMostDangerousUnit(self, range-250, function(targetunit) return targetunit.thtd_is_fearing~=true end) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit, ability, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_yuyuko_thtd_ai() local ability1 = self:FindAbilityByName("thtd_yuyuko_01") local ability3 = self:FindAbilityByName("thtd_yuyuko_03") if self.thtd_yuyuko_03_cast == nil then self.thtd_yuyuko_03_cast = true end local target = THTDSystem:FindRadiousMostDangerousUnit(self, ability3:GetCastRange(), function (targetunit) return targetunit:GetHealthPercent() <= (self.thtd_yuyuko_03_health_kill or 30) end) if self.thtd_yuyuko_03_cast==true and self:IsReadyToCastAbility(ability3) and target~=nil and target:IsNull()==false then THTD_SetSpellLock(self, ability3:GetAbilityName(), ability3:GetSpecialValueFor("duration_time")) self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(target:GetAbsOrigin(), ability3, self:GetPlayerOwnerID()) return end if self:IsReadyToCastAbility(ability1) and THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), ability1:GetCastRange()) > 0 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability1, self:GetPlayerOwnerID()) return end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false and self:IsChanneling() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_youmu_thtd_ai() local ability = self:FindAbilityByName("thtd_youmu_03") if self:IsReadyToCastAbility(ability) then local point = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability:GetCastRange(), 550) if point~=nil then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_utsuho_thtd_ai() local ability = self:FindAbilityByName("thtd_utsuho_03") if self:IsReadyToCastAbility(ability) then if self.thtd_last_cast_point ~= nil then local point = self.thtd_last_cast_point if THTD_HasUnitsInRadius(self, point, ability:GetSpecialValueFor("radius")-250) then THTD_SetSpellLock(self, ability:GetAbilityName(), ability:GetSpecialValueFor("duration_time")) self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability, self:GetPlayerOwnerID()) return end else local point = THTDSystem:FindUtsuhoPerfectPoint(self, ability:GetCastRange(), ability:GetSpecialValueFor("radius")-100) if point~=nil then THTD_SetSpellLock(self, ability:GetAbilityName(), ability:GetSpecialValueFor("duration_time")) self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability, self:GetPlayerOwnerID()) return end end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false and self:IsChanneling()==false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_rin_thtd_ai() local ability = self:FindAbilityByName("thtd_rin_01") if self:IsReadyToCastAbility(ability) then local unit = THTDSystem:FindRadiusOneUnit(self,ability:GetCastRange()) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit, ability, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_reimu_thtd_ai() local ability = self:FindAbilityByName("thtd_reimu_03") if self:IsReadyToCastAbility(ability) then if self.thtd_last_cast_point ~= nil then local point = self.thtd_last_cast_point if THTD_HasUnitsInRadius(self, point, ability:GetSpecialValueFor("range") * 0.7) then THTD_SetSpellLock(self, ability:GetAbilityName(), ability:GetSpecialValueFor("stun_time") * 1.5) self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability, self:GetPlayerOwnerID()) return end else local unit = THTDSystem:FindRadiousMostDangerousUnit(self, ability:GetCastRange()) if unit~=nil and unit:IsNull()==false then local point = unit:GetAbsOrigin() THTD_SetSpellLock(self, ability:GetAbilityName(), ability:GetSpecialValueFor("stun_time") * 1.5) self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability, self:GetPlayerOwnerID()) return end end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_daiyousei_thtd_ai() local ability1 = self:FindAbilityByName("thtd_daiyousei_01") local ability2 = self:FindAbilityByName("thtd_daiyousei_02") if SpawnSystem.IsUnLimited == false and GameRules:GetCustomGameDifficulty() < 8 and self:IsReadyToCastAbility(ability1) then local target = THTDSystem:FindFriendlyHighestStarRadiusOneUnit(self,ability1:GetCastRange()) if target~=nil and target:THTD_IsTower() then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(target,ability1,self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability2) then local target = THTDSystem:FindFriendlyRadiusOneUnit(self, 1000) if target~=nil and target:THTD_IsTower() then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability2,self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_remilia_thtd_ai() local ability1 = self:FindAbilityByName("thtd_remilia_01") local ability2 = self:FindAbilityByName("thtd_remilia_03") if self:IsReadyToCastAbility(ability2) then local point,count = THTDSystem:FindRadiusOnePointPerfectLineAOE(self, ability2:GetCastRange(), 300, 2500, false) if point~=nil and count>=3 then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability2, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability1) then local point,count,unit = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability1:GetCastRange(), 800) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit, ability1, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_flandre_thtd_ai() local ability1 = self:FindAbilityByName("thtd_flandre_01") local ability4 = self:FindAbilityByName("thtd_flandre_04") local range = self:Script_GetAttackRange() if range == nil then range = self:GetBaseAttackRange() end if range == nil then range = 1000 end if self:THTD_IsAttackChangeLock() == false and (self.thtd_attatck_target==nil or self.thtd_attatck_target:IsNull() or GetDistanceBetweenTwoEntity(self, self.thtd_attatck_target) > range) then local target = THTDSystem:FindRadiusWeakOneUnit(self,range) if target~=nil and target:IsNull()==false and target:IsAlive() then self.thtd_attatck_target = target THTDSystem:ChangeAttackTarget(self, target) self:THTD_SetAttackChangeLock() end end if self:IsReadyToCastAbility(ability1) then range = ability1:GetCastRange() if ability4:GetLevel() > 0 then range = ability4:GetCastRange() end if THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), range) > 0 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability1, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability4) then range = ability4:GetCastRange() local unit = THTDSystem:FindRadiusWeakOneUnit(self, range) if unit ~= nil and unit:IsNull() == false and unit:IsAlive() then if SpawnSystem.CurTime > ability4:GetCooldownTime() + 3 then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit, ability4, self:GetPlayerOwnerID()) return end -- 溢出伤害占比 local factor = 0.1 + SpawnSystem.CurTime * 0.01 local damage = self:THTD_GetAbilityPowerDamage(ability4) * 4 local crit = 1 local ability3 = self:FindAbilityByName("thtd_flandre_03") if ability3:GetLevel() > 0 then crit = 1 + (100 - unit:GetHealthPercent()) * ability3:GetSpecialValueFor("damage_up") / 100 end if self:IsPower999() then crit = crit * 4 end local DamageTable = { ability = ability4, victim = unit, attacker = self, damage = damage * crit, damage_type = ability4:GetAbilityDamageType(), damage_flags = DOTA_DAMAGE_FLAG_NONE } if UnitDamageTarget(DamageTable, true) <= factor then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit, ability4, self:GetPlayerOwnerID()) return else THTDSystem:ChangeAttackTarget(self,unit) return end end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end require( "../abilities/abilitysakuya") function CDOTA_BaseNPC:NeedRefreshAbility() if self:THTD_IsTower() and self:HasModifier("modifier_sakuya_02_buff") == false then for i=2,5 do local ability = self:GetAbilityByIndex(i) if ability ~= nil and ability:GetAbilityName() ~= "ability_common_ai" and not IsInSakuya02BlackList(ability) and (ability:GetCooldownTimeRemaining() > 0 or ability:GetManaCost(-1) > 0) then local cd = ability:GetCooldownTime() local left = ability:GetCooldownTimeRemaining() if left > 2.0 then if left > cd * 0.4 or self:GetMana() <= self:GetRealManaCost(ability) * 0.6 then return true end end end end end return false end function CDOTA_BaseNPC:THTD_sakuya_thtd_ai() local ability1 = self:FindAbilityByName("thtd_sakuya_01") local ability2 = self:FindAbilityByName("thtd_sakuya_02") local ability3 = self:FindAbilityByName("thtd_sakuya_03") if self:IsReadyToCastAbility(ability2) then local target = THTDSystem:FindFriendlyRadiusOneUnitLast(self,ability2:GetCastRange()) if target~=nil and target:IsNull()==false and target:THTD_IsTower() and target:NeedRefreshAbility() then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(target,ability2,self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability3) and (THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), 800)>5 or THTDSystem:FindRadiousMostDangerousUnit(self,400)~=nil ) then THTD_SetSpellLock(self, ability3:GetAbilityName(), ability3:GetSpecialValueFor("duration_time")) self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability3, self:GetPlayerOwnerID()) return end if self:IsReadyToCastAbility(ability1) then local unit = THTDSystem:FindRadiusOneUnit(self,ability1:GetCastRange()) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit, ability1, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_koishi_thtd_ai() local ability3 = self:FindAbilityByName("thtd_koishi_03") local ability4 = self:FindAbilityByName("thtd_koishi_04") local range = self:Script_GetAttackRange() if range == nil then range = self:GetBaseAttackRange() end if range == nil then range = 1000 end if self:IsReadyToCastAbility(ability3) and THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), range) > 0 then local target = THTDSystem:FindFriendlyRadiusOneUnitLast(self, ability3:GetCastRange()) if target~=nil and target:IsNull()==false and target:THTD_IsTower() and target.thtd_koishi_03_bonus~=true then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(target, ability3, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability4) and self:HasModifier("passive_koishi_04_attack") == false and THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), range) > 0 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability4, self:GetPlayerOwnerID()) return end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_koakuma_thtd_ai() local ability = self:FindAbilityByName("thtd_koakuma_01") if self:IsReadyToCastAbility(ability) then local unit = THTDSystem:FindRadiusOneUnit(self, 800) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit, ability, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_yuuka_thtd_ai() local ability1 = self:FindAbilityByName("thtd_yuuka_01") local ability4 = self:FindAbilityByName("thtd_yuuka_04") if self:IsReadyToCastAbility(ability1) and THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), 800) > 0 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability1, self:GetPlayerOwnerID()) return end if self:IsReadyToCastAbility(ability4) then local point,count = THTDSystem:FindRadiusOnePointPerfectLineAOE(self, ability4:GetCastRange() - 600, 300, 1000, false) if point~=nil and count >= 5 then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability4, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false and self:IsChanneling() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_yukari_thtd_ai() local ability1 = self:FindAbilityByName("thtd_yukari_01") local ability2 = self:FindAbilityByName("thtd_yukari_02") local ability4 = self:FindAbilityByName("thtd_yukari_04") if self.thtd_yukari_01_hidden_table == nil then self.thtd_yukari_01_hidden_table = {} end if self:IsReadyToCastAbility(ability4) and (#THTD_FindUnitsInner(self)>=5 or THTDSystem:FindRadiousMostDangerousUnit(self,400)~=nil) then THTD_SetSpellLock(self, ability4:GetAbilityName(), ability4:GetSpecialValueFor("max_count") * ability4:GetSpecialValueFor("stun_time")) self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability4, self:GetPlayerOwnerID()) return end if self:IsReadyToCastAbility(ability1) and #self.thtd_yukari_01_hidden_table < self:GetAbilityValue("thtd_yukari_01", "max_count") then local unit = THTDSystem:FindRadiousMostDangerousUnit(self, ability1:GetCastRange()-200, function(targetUnit) return (targetUnit.thtd_yukari_01_hidden_count == nil or targetUnit.thtd_yukari_01_hidden_count < self:GetAbilityValue("thtd_yukari_01", "limit_count")) and targetUnit.thtd_is_fearing ~= true end) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit, ability1, self:GetPlayerOwnerID()) end end if self:IsReadyToCastAbility(ability2) and #self.thtd_yukari_01_hidden_table > 0 then local point = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability2:GetCastRange(), 300) if point == nil then point = self:GetAbsOrigin() + ability2:GetCastRange() * GetUnitBackWardVector(self, self:GetPlayerOwnerID()) end local unit = self.thtd_yukari_01_hidden_table[1] if GetDistanceBetweenTwoVec2D(unit.first_move_point, point) < 2000 then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability2, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_ran_thtd_ai() local ability1 = self:FindAbilityByName("thtd_ran_01") local ability2 = self:FindAbilityByName("thtd_ran_02") local range = self:Script_GetAttackRange() if range == nil then range = self:GetBaseAttackRange() end if range == nil then range = 1000 end if self:IsReadyToCastAbility(ability2) and THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), range) > 0 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability2, self:GetPlayerOwnerID()) -- ability2:CastAbility() return end if self:IsReadyToCastAbility(ability1) then local unit = THTDSystem:FindRadiusOneUnit(self,ability1:GetCastRange()) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit, ability1, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_chen_thtd_ai() local ability = self:FindAbilityByName("thtd_chen_01") if self:IsReadyToCastAbility(ability) and THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), ability:GetCastRange())>0 then if self.thtd_chen_01_last_origin ~= nil and GetDistanceBetweenTwoVec2D(self.thtd_chen_01_last_origin, self:GetAbsOrigin()) <= ability:GetCastRange() then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(self.thtd_chen_01_last_origin, ability, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_eirin_thtd_ai() local ability3 = self:FindAbilityByName("thtd_eirin_03") local ability4 = self:FindAbilityByName("thtd_eirin_04") if ability4:GetLevel() < 1 then if self:IsReadyToCastAbility(ability3) then if self.thtd_last_cast_point ~= nil then local point = self.thtd_last_cast_point if THTD_HasUnitsInRadius(self, point, ability3:GetSpecialValueFor("range") * 0.7) then THTD_SetSpellLock(self, ability3:GetAbilityName(), ability3:GetSpecialValueFor("duration_time")) self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability3, self:GetPlayerOwnerID()) return end else local point, count = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability3:GetCastRange(), 400) if count > 3 and point ~= nil then THTD_SetSpellLock(self, ability3:GetAbilityName(), ability3:GetSpecialValueFor("duration_time")) self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability3, self:GetPlayerOwnerID()) return end end end else if self:IsReadyToCastAbility(ability3) and self:IsReadyToCastAbility(ability4) then if self.thtd_last_cast_point ~= nil then local point = self.thtd_last_cast_point if THTD_HasUnitsInRadius(self, point, ability3:GetSpecialValueFor("range") * 0.7) then THTD_SetSpellLock(self, ability3:GetAbilityName(), ability3:GetSpecialValueFor("duration_time")) self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability3, self:GetPlayerOwnerID()) self:SetContextThink(DoUniqueString("dota_timer"), function() if GameRules:IsGamePaused() then return 0.1 end self:CastAbilityOnPosition(point, ability4, self:GetPlayerOwnerID()) return nil end, 0.15) return end else local point, count = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability3:GetCastRange(), 400) if count > 3 and point ~= nil then THTD_SetSpellLock(self, ability3:GetAbilityName(), ability3:GetSpecialValueFor("duration_time")) self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability3, self:GetPlayerOwnerID()) self:SetContextThink(DoUniqueString("dota_timer"), function() if GameRules:IsGamePaused() then return 0.1 end self:CastAbilityOnPosition(point, ability4, self:GetPlayerOwnerID()) return nil end, 0.15) return end end end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_mokou_thtd_ai() local ability = self:FindAbilityByName("thtd_mokou_03") local range = self:Script_GetAttackRange() if range == nil then range = self:GetBaseAttackRange() end if range == nil then range = 1000 end if self:IsReadyToCastAbility(ability) and THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), range) > 0 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability, self:GetPlayerOwnerID()) return end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_kaguya_thtd_ai() local ability = self:FindAbilityByName("thtd_kaguya_01") if self:IsReadyToCastAbility(ability) then local unit = THTDSystem:FindRadiusOneUnit(self, ability:GetCastRange()) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(unit:GetAbsOrigin(), ability, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_aya_thtd_ai() local ability = self:FindAbilityByName("thtd_aya_02") if self:IsReadyToCastAbility(ability) then local point = THTDSystem:FindRadiusOnePointPerfectLineAOE(self, 6666, 300, 1500, true) if point~=nil then local forward = (point - self:GetAbsOrigin()):Normalized() local dist = GetDistanceBetweenTwoVec2D(self:GetAbsOrigin() ,point) point = self:GetAbsOrigin() + (dist + 200) * forward self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_hatate_thtd_ai() local ability1 = self:FindAbilityByName("thtd_hatate_01") local ability2 = self:FindAbilityByName("thtd_hatate_02") if self:IsReadyToCastAbility(ability1) then local unit = THTDSystem:FindRadiusOneUnit(self,ability1:GetCastRange()) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(unit:GetAbsOrigin(), ability1, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability2) and #THTD_FindUnitsInner(self) >= 10 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability2, self:GetPlayerOwnerID()) return end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false and self:IsChanneling() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_sanae_thtd_ai() local ability1 = self:FindAbilityByName("thtd_sanae_01") local ability2 = self:FindAbilityByName("thtd_sanae_02") local ability3 = self:FindAbilityByName("thtd_sanae_03") local ability4 = self:FindAbilityByName("thtd_sanae_04") local range = self:Script_GetAttackRange() if range == nil then range = self:GetBaseAttackRange() end if range == nil then range = 1000 end -- ability1:GetCastRange() 会报错,部分技能这样使用会报错,要求传入参数,被动技能?直接脚本方式?不太确定 if self:IsReadyToCastAbility(ability4) and THTDSystem:FindRadiusOneUnit(self, range)~=nil and self:HasModifier("modifier_sanae_04_buff")==false then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability4, self:GetPlayerOwnerID()) return end if self:IsReadyToCastAbility(ability2) then local point = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability2:GetCastRange(), 300) if point~=nil then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability2, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability1) and THTDSystem:FindRadiusOneUnit(self, range)~=nil then local target = THTDSystem:FindFriendlyRadiusOneUnitLast(self, 800) if target~=nil and target:IsNull()==false and target:THTD_IsTower() and target.thtd_sanae_01_bonus~=true then self:THTD_SetAggressiveLock() THTD_SetSpellLock(self, ability1:GetAbilityName(), ability1:GetSpecialValueFor("duration_time")) self:CastAbilityOnTarget(target, ability1, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability3) then local point, count = nil, 0 local unit = THTDSystem:FindRadiousMostDangerousUnit(self, 400) if unit~=nil and unit:IsNull()==false then point = unit:GetAbsOrigin() + 250 * GetUnitBackWardVector(unit, self:GetPlayerOwnerID()) else point, count = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability3:GetCastRange(), 400) if count < 5 then point=nil end end if point~=nil then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability3, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_kanako_thtd_ai() local ability1 = self:FindAbilityByName("thtd_kanako_01") local ability4 = self:FindAbilityByName("thtd_kanako_04") if self:IsReadyToCastAbility(ability4) and THTDSystem:FindRadiusOneUnit(self,750)~=nil then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability4, self:GetPlayerOwnerID()) return end if self:IsReadyToCastAbility(ability1) then local unit = THTDSystem:FindRadiousMostDangerousUnit(self, 600, function(target) return math.abs(target:GetAbsOrigin().x) > math.abs(self:GetAbsOrigin().x) end) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit, ability1, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_momiji_thtd_ai() local ability = self:FindAbilityByName("thtd_momiji_01") local range = self:Script_GetAttackRange() if range == nil then range = self:GetBaseAttackRange() end if range == nil then range = 1000 end if self:IsReadyToCastAbility(ability) and THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), range)>0 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability, self:GetPlayerOwnerID()) return end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_shinki_thtd_ai() local ability2 = self:FindAbilityByName("thtd_shinki_02") local ability3 = self:FindAbilityByName("thtd_shinki_03") if self:IsReadyToCastAbility(ability3) then local enemies = THTD_FindUnitsInRadius(self, self:GetAbsOrigin(), ability3:GetCastRange()) if #enemies >= 3 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability3, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability2) then local enemies = THTD_FindUnitsInRadius(self, self:GetAbsOrigin(), ability2:GetCastRange() * 0.7) if #enemies >= 3 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability2, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_minamitsu_thtd_ai() local ability2 = self:FindAbilityByName("thtd_minamitsu_02") local ability3 = self:FindAbilityByName("thtd_minamitsu_03") local ability4 = self:FindAbilityByName("thtd_minamitsu_04") local range = self:Script_GetAttackRange() if range == nil then range = self:GetBaseAttackRange() end if range == nil then range = 1000 end if self:IsReadyToCastAbility(ability2) and THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), range) > 0 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability2, self:GetPlayerOwnerID()) return end if self:IsReadyToCastAbility(ability3) then local unit = THTDSystem:FindRadiousMostDangerousUnit(self, ability3:GetCastRange(), function(targetunit) return targetunit:HasModifier("modifier_minamitsu_01_slow_buff") end) if unit ~= nil and unit:IsNull() == false then local isValidPoint = false local targetPoint = unit:GetAbsOrigin() if self.water_end_point ~= nil then if self.thtd_minamitsu_01_first == true then if math.abs(targetPoint.x) > math.abs(self.water_end_point.x) + 800 then isValidPoint = true end else if math.abs(targetPoint.y) > math.abs(self.water_end_point.y) + 800 then isValidPoint = true end end end if isValidPoint then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(targetPoint, ability3, self:GetPlayerOwnerID()) return end end end if self:IsReadyToCastAbility(ability4) then local unit = THTDSystem:FindRadiousMostDangerousUnit(self, range, function(targetunit) return targetunit:HasModifier("modifier_minamitsu_01_slow_buff") end) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability4, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_nue_thtd_ai() local ability1 = self:FindAbilityByName("thtd_nue_01") local ability2 = self:FindAbilityByName("thtd_nue_02") local range = self:Script_GetAttackRange() if range == nil then range = self:GetBaseAttackRange() end if range == nil then range = 1000 end if self:IsReadyToCastAbility(ability1) and ability2:IsInAbilityPhase() == false then if ability2:GetLevel()>0 then range = ability2:GetCastRange() end if THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), range)>0 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability1, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability2) and ability2:IsInAbilityPhase() == false then local unit = THTDSystem:FindRadiusWeakOneUnit(self, ability2:GetCastRange()) if unit~=nil and unit:IsNull()==false and unit:IsAlive() then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(unit:GetAbsOrigin(), ability2, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false and ability2:IsInAbilityPhase() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_toramaru_thtd_ai() local ability1 = self:FindAbilityByName("thtd_toramaru_01") local ability2 = self:FindAbilityByName("thtd_toramaru_02") local ability3 = self:FindAbilityByName("thtd_toramaru_03") local ability4 = self:FindAbilityByName("thtd_toramaru_04") if self:IsReadyToCastAbility(ability1) then local unit = THTDSystem:FindRadiusOneUnit(self, ability1:GetCastRange()) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit, ability1, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability4) and THTD_HasUnitsInRadius(self, self:GetAbsOrigin(), ability4:GetCastRange()) then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability4, self:GetPlayerOwnerID()) return end if SpawnSystem.CurWave > 70 then if self:IsReadyToCastAbility(ability2) and self:GetGold() >= 500 then local unit = THTDSystem:FindRadiousMostDangerousUnit(self, ability2:GetCastRange()) if unit ~= nil then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit,ability2,self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability3) and self:GetGold() >= 5000 and #THTD_EntitiesRectInner[self:GetPlayerOwnerID()] >= 3 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability3, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_suwako_thtd_ai() local ability = self:FindAbilityByName("thtd_suwako_03") local ability4 = self:FindAbilityByName("thtd_suwako_04") if self:IsReadyToCastAbility(ability) then local unit = THTDSystem:FindRadiusOneUnit(self, 500) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() THTD_SetSpellLock(self, ability:GetAbilityName(), 1.0) self:CastAbilityNoTarget(ability, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability4) then if THTDSystem:FindRadiusOneUnit(self, self:Script_GetAttackRange()) ~= nil then local target = THTDSystem:FindFriendlyRadiusOneUnitLast(self,ability4:GetCastRange()) if target~=nil and target:IsNull()==false and target:THTD_IsTower() and target:HasModifier("modifier_suwako_04_buff") == false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(target,ability4,self:GetPlayerOwnerID()) return end end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_soga_thtd_ai() local ability1 = self:FindAbilityByName("thtd_soga_01") local ability2 = self:FindAbilityByName("thtd_soga_02") local ability3 = self:FindAbilityByName("thtd_soga_03") if self:IsReadyToCastAbility(ability1) then local unit1 = THTDSystem:FindRadiousMostDangerousUnit(self, ability1:GetCastRange()) if unit1~=nil and unit1:IsNull()==false then THTD_SetSpellLock(self, "thtd_soga_01", ability1:GetSpecialValueFor("stun_time")) self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(unit1:GetAbsOrigin(),ability1,self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability2) then local point2 = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability2:GetCastRange(), 300) if point2~=nil then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point2,ability2, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability3) then local point3, count3 = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability3:GetCastRange(), 500) if point3~=nil and count3>4 then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point3,ability3,self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_futo_thtd_ai() local ability = self:FindAbilityByName("thtd_futo_03") if self:IsReadyToCastAbility(ability) then local point, count = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability:GetCastRange(), 1000) if point~=nil and count>5 then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_miko_thtd_ai() local ability1 = self:FindAbilityByName("thtd_miko_01") local ability4 = self:FindAbilityByName("thtd_miko_04") if self.thtd_miko_04_cast == nil then self.thtd_miko_04_cast = true end if self.thtd_miko_04_cast == true and self:IsReadyToCastAbility(ability4) and ability4:IsInAbilityPhase() == false and #THTD_FindUnitsInner(self) >= 5 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability4, self:GetPlayerOwnerID()) return end if self:IsReadyToCastAbility(ability1) and ability1:IsInAbilityPhase() == false and THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), 1000)>0 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability1, self:GetPlayerOwnerID()) return end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false and ability1:IsInAbilityPhase() == false and ability4:IsInAbilityPhase() == false and self:IsChanneling() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_yoshika_thtd_ai() local ability = self:FindAbilityByName("thtd_yoshika_02") local range = self:Script_GetAttackRange() if range == nil then range = self:GetBaseAttackRange() end if range == nil then range = 1000 end local target = self:GetAttackTarget() if target==nil or target:IsNull() or target:HasModifier("modifier_yoshika_01_slow") then target = THTDSystem:FindRadiusOneUnitHasNoModifier(self, range, "modifier_yoshika_01_slow") if target~=nil and target:IsNull()==false then THTDSystem:ChangeAttackTarget(self,target) end end if self:IsReadyToCastAbility(ability) and #THTD_FindUnitsInner(self)>0 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability, self:GetPlayerOwnerID()) return end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_seiga_thtd_ai() local ability2 = self:FindAbilityByName("thtd_seiga_02") local range = self:Script_GetAttackRange() if range == nil then range = self:GetBaseAttackRange() end if range == nil then range = 1000 end if self:IsReadyToCastAbility(ability2) and THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), range)>0 then local target = THTDSystem:FindFriendlyRadiusOneUnitLast(self,ability2:GetCastRange()) if target~=nil and target:IsNull()==false and target:THTD_IsTower() then if target:GetUnitName() ~= "komachi" or target:HasModifier("modifier_komachi_04") == false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(target,ability2,self:GetPlayerOwnerID()) return end end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_keine_thtd_ai() local ability1 = self:FindAbilityByName("thtd_keine_01") local ability2 = self:FindAbilityByName("thtd_keine_02") local ability3 = self:FindAbilityByName("thtd_keine_03") local range = self:Script_GetAttackRange() if range == nil then range = self:GetBaseAttackRange() end if range == nil then range = 1000 end local target = self:GetAttackTarget() if target==nil or target:IsNull() or target:HasModifier("thtd_keine_03_debuff") then target = THTDSystem:FindRadiousMostDangerousUnit(self, range, function (targetunit) return targetunit:HasModifier("thtd_keine_03_debuff")==false end) if target~=nil and target:IsNull()==false then THTDSystem:ChangeAttackTarget(self, target) end end if self:IsReadyToCastAbility(ability1) and self.thtd_keine_change~=2 and THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), range)>0 then local target1 = THTDSystem:FindFriendlyRadiusOneUnitLast(self,ability1:GetCastRange()) if target1 ~= nil and target1:IsNull() == false and target1:THTD_IsTower() and target1:HasModifier("modifier_keine_01_buff") == false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(target1,ability1,self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability3) and self.thtd_keine_change==1 then local point3 = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability3:GetCastRange(), 1000) if point3~=nil then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point3, ability3, self:GetPlayerOwnerID()) return end end if self.thtd_keine_02_cast == nil then self.thtd_keine_02_cast = true end if self.thtd_keine_02_cast == true and self:IsReadyToCastAbility(ability2) then local unit = THTDSystem:FindRadiusOneUnit(self, range) if (self.thtd_keine_change == 1 and ability1:GetCooldownTimeRemaining() > 5 and unit ~= nil) or (self.thtd_keine_change == 2 and (ability1:IsCooldownReady() or unit == nil) ) then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability2, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_medicine_thtd_ai() local ability2 = self:FindAbilityByName("thtd_medicine_02") local range = self:Script_GetAttackRange() if range == nil then range = self:GetBaseAttackRange() end if range == nil then range = 1000 end local target = self:GetAttackTarget() if target==nil or target:IsNull() or target:HasModifier("modifier_medicine_01_slow") then target = THTDSystem:FindRadiousMostDangerousUnit(self, range, function (targetunit) return targetunit:HasModifier("modifier_medicine_01_slow")==false end) if target~=nil and target:IsNull()==false then THTDSystem:ChangeAttackTarget(self, target) end end if self:IsReadyToCastAbility(ability2) and THTD_HasUnitsInRadius(self, self:GetAbsOrigin(), ability2:GetCastRange()) then local point = nil local unit = THTDSystem:FindRadiousMostDangerousUnit(self, 400, function(targetunit) return targetunit.thtd_is_fearing~=true end) if unit~=nil and unit:IsNull()==false then point = unit:GetAbsOrigin() + 350*GetUnitBackWardVector(unit,self:GetPlayerOwnerID()) else point = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability2:GetCastRange(), 400) end if point~=nil then if self.thtd_last_cast_point ~= nil then point = self.thtd_last_cast_point end THTD_SetSpellLock(self, ability2:GetAbilityName(), ability2:GetSpecialValueFor("duration_time")) self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability2, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_luna_thtd_ai() local ability2 = self:FindAbilityByName("thtd_luna_02") if self:IsReadyToCastAbility(ability2) and self:HasModifier("modifier_luna_02_buff") == false then local point,count = THTDSystem:FindRadiusOnePointPerfectLineAOE(self, ability2:GetCastRange(), 200, 1000, false) if point~=nil and ((SpawnSystem.IsUnLimited == false and count >= 3) or (SpawnSystem.IsUnLimited and count >= 7)) then THTD_SetSpellLock(self, ability2:GetAbilityName(), 1.0) self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability2, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_sunny_thtd_ai() local ability1 = self:FindAbilityByName("thtd_sunny_01") local ability2 = self:FindAbilityByName("thtd_sunny_02") if self:IsReadyToCastAbility(ability2) and THTD_HasUnitsInRadius(self, self:GetAbsOrigin(), ability2:GetCastRange()) then local point = nil if self.thtd_last_cast_point ~= nil then point = self.thtd_last_cast_point else point = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability2:GetCastRange(), 300) end if point~=nil then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability2, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability1) then local unit = THTDSystem:FindRadiusOneUnit(self, ability1:GetCastRange()) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit, ability1, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_star_thtd_ai() local ability1 = self:FindAbilityByName("thtd_star_01") local ability2 = self:FindAbilityByName("thtd_star_02") if self:IsReadyToCastAbility(ability1) then local unit = THTDSystem:FindRadiusOneUnit(self, ability1:GetCastRange()) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(unit:GetAbsOrigin(), ability1, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability2) then local unit = THTDSystem:FindRadiusOneUnit(self, ability2:GetCastRange()) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(unit:GetAbsOrigin(), ability2, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_suika_thtd_ai() local ability3 = self:FindAbilityByName("thtd_suika_03") local ability4 = self:FindAbilityByName("thtd_suika_04") local unit = THTDSystem:FindRadiusOneUnit(self,800) if self:IsReadyToCastAbility(ability3) then local unit = THTDSystem:FindRadiusOneUnit(self, 800) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit, ability3, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability4) then local unit = THTDSystem:FindRadiusOneUnit(self, 800) if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit, ability4, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_yuugi_thtd_ai() local ability1 = self:FindAbilityByName("thtd_yuugi_01") local ability3 = self:FindAbilityByName("thtd_yuugi_03") local range = self:Script_GetAttackRange() if range == nil then range = self:GetBaseAttackRange() end if range == nil then range = 1000 end local target = self:GetAttackTarget() if target == nil or target:IsNull() == true then target = THTDSystem:FindRadiousMostDangerousUnit(self, range) if target~=nil and target:IsNull()==false then THTDSystem:ChangeAttackTarget(self, target) end end if self:IsReadyToCastAbility(ability1) and THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), range)>0 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability1, self:GetPlayerOwnerID()) return end if self:IsReadyToCastAbility(ability3) then local point, count = nil, 0 local unit = THTDSystem:FindRadiousMostDangerousUnit(self, 400) if unit~=nil and unit:IsNull()==false then point = unit:GetAbsOrigin() + 450 * GetUnitBackWardVector(unit, self:GetPlayerOwnerID()) else point, count = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability3:GetCastRange(), 500) if count < 7 then point=nil end end if point~=nil then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability3, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_junko_thtd_ai() local ability2 = self:FindAbilityByName("thtd_junko_02") local ability3 = self:FindAbilityByName("thtd_junko_03") local ability4 = self:FindAbilityByName("thtd_junko_04") if THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), 1000) >= 2 then if self:IsReadyToCastAbility(ability3) and ability3:GetAutoCastState() then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability3, self:GetPlayerOwnerID()) return end if self:IsReadyToCastAbility(ability2) then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability2, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability4) then local point,count = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability4:GetCastRange(), 500) if point~=nil and count>=3 then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability4, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_mugiyousei_thtd_ai() local target = self:GetAttackTarget() local range = self:Script_GetAttackRange() if range == nil then range = self:GetBaseAttackRange() end if range == nil then range = 1000 end local min_thtd_poison_buff = 0 if target~=nil then min_thtd_poison_buff = target:GetPoisonCount() end local unit = target local enemies = THTD_FindUnitsInRadius(self, self:GetAbsOrigin(), range) if #enemies > 0 then for k,v in pairs(enemies) do if v~=nil and v:IsNull()==false and v:GetPoisonCount() < min_thtd_poison_buff then unit = v min_thtd_poison_buff = v:GetPoisonCount() end end end if unit~=nil and unit:IsNull()==false and unit~=target then THTDSystem:ChangeAttackTarget(self, unit) elseif self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_rumia_thtd_ai() local range = self:Script_GetAttackRange() if range == nil then range = self:GetBaseAttackRange() end if range == nil then range = 1000 end if self.thtd_is_ex == true then local target = self:GetAttackTarget() if target==nil or target:IsNull()==true or target:GetHealthPercent()<=70 then target = THTDSystem:FindRadiousMostDangerousUnit(self, range, function (targetunit) return targetunit:GetHealthPercent() > 70 end) if target~=nil and target:IsNull()==false then target = THTDSystem:ChangeTargetHasNoDamageLock(self, function (targetunit) return targetunit:GetHealthPercent() > 70 end) THTDSystem:ChangeAttackTarget(self, target) end end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_alice_thtd_ai() local ability1 = self:FindAbilityByName("thtd_alice_01") local ability2 = self:FindAbilityByName("thtd_alice_02") local ability4 = self:FindAbilityByName("thtd_alice_03") local enemies = THTD_FindUnitsInRadius(self, self:GetAbsOrigin(), ability4:GetCastRange()) if self:IsReadyToCastAbility(ability4) and ability4:IsInAbilityPhase() == false and #enemies >= 5 then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(enemies[#enemies-2], ability4, self:GetPlayerOwnerID()) return end if self:IsReadyToCastAbility(ability1) and ability1:IsInAbilityPhase() == false then local point = nil if self.thtd_last_cast_point ~= nil then point = self.thtd_last_cast_point else local enemies = THTD_FindUnitsInRadius(self, self:GetAbsOrigin(), ability1:GetCastRange()) if #enemies > 0 then point = enemies[1]:GetAbsOrigin() end end if point ~= nil then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability1, self:GetPlayerOwnerID()) end return end if self:IsReadyToCastAbility(ability2) and self.thtd_summon_unit == nil then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability2, self:GetPlayerOwnerID()) return end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false and ability1:IsInAbilityPhase() == false and ability4:IsInAbilityPhase() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_kokoro_thtd_ai() local ability1 = self:FindAbilityByName("thtd_kokoro_01") local ability2 = self:FindAbilityByName("thtd_kokoro_02") local ability3 = self:FindAbilityByName("thtd_kokoro_03") if self:IsReadyToCastAbility(ability2) then local enemies = THTD_FindUnitsInRadius(self, self:GetAbsOrigin(), ability2:GetCastRange()) if #enemies >= 2 then self:THTD_SetAggressiveLock() THTD_SetSpellLock(self, ability2:GetAbilityName(), ability2:GetSpecialValueFor("stun_time")) self:CastAbilityNoTarget(ability2, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability3) then local enemies = THTD_FindUnitsInRadius(self, self:GetAbsOrigin(), ability3:GetCastRange()) if #enemies >= 1 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability3, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability1) then local enemies = THTD_FindUnitsInRadius(self, self:GetAbsOrigin(), ability1:GetCastRange()) if #enemies >= 2 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability1, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false and ability2:IsInAbilityPhase() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_kagerou_thtd_ai() local ability2 = self:FindAbilityByName("thtd_kagerou_02") local ability3 = self:FindAbilityByName("thtd_kagerou_03") local range = self:Script_GetAttackRange() if range == nil then range = self:GetBaseAttackRange() end if range == nil then range = 800 end if self:IsReadyToCastAbility(ability2) and self:HasModifier("modifier_kagerou_02_buff") == false and THTD_HasUnitsInRadius(self, self:GetAbsOrigin(),range) then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability2, self:GetPlayerOwnerID()) return end if self:IsReadyToCastAbility(ability3) and self:HasModifier("modifier_kagerou_03_wolf") == false and THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), range) >= 3 then self:THTD_SetAggressiveLock() THTD_SetSpellLock(self, ability3:GetAbilityName(), 0.6) self:CastAbilityNoTarget(ability3, self:GetPlayerOwnerID()) return end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_wriggle_thtd_ai() local ability1 = self:FindAbilityByName("death_prophet_exorcism") local ability2 = self:FindAbilityByName("thtd_wriggle_02") local range = 900 if self:IsReadyToCastAbility(ability1) and THTD_HasUnitsInRadius(self, self:GetAbsOrigin(), range) then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability1, self:GetPlayerOwnerID()) return end if self:IsReadyToCastAbility(ability2) then local point,count = THTDSystem:FindRadiusOnePointPerfectAOE(self, range, 700) if point ~= nil and count >= 3 then if self.thtd_last_cast_point ~= nil then point = self.thtd_last_cast_point end THTD_SetSpellLock(self, ability2:GetAbilityName(), ability2:GetSpecialValueFor("max_count") * 1.5 - 0.5) self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability2, self:GetPlayerOwnerID()) return end end if self:THTD_IsAttackChangeLock() == false and (self.thtd_attatck_target==nil or self.thtd_attatck_target:IsNull() or GetDistanceBetweenTwoEntity(self, self.thtd_attatck_target) > self:Script_GetAttackRange()) then local target = THTDSystem:FindRadiusMostHpOneUnit(self,range) if target~=nil and target:IsNull()==false and target:IsAlive() then self.thtd_attatck_target = target THTDSystem:ChangeAttackTarget(self, target) self:THTD_SetAttackChangeLock() end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_inaba_thtd_ai() local ability1 = self:FindAbilityByName("thtd_inaba_01") if self:IsAttacking() and self:IsReadyToCastAbility(ability1) then local target = THTDSystem:FindFriendlyRadiusOneUnitLast(self,ability1:GetCastRange()) if target~=nil then if target:GetUnitName() ~= "komachi" or target:HasModifier("modifier_komachi_04") == false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(target,ability1,self:GetPlayerOwnerID()) return end end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_clownpiece_thtd_ai() local ability1 = self:FindAbilityByName("thtd_clownpiece_01") local ability2 = self:FindAbilityByName("thtd_clownpiece_02") local ability3 = self:FindAbilityByName("thtd_clownpiece_03") if self:IsReadyToCastAbility(ability2) then local point,count = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability2:GetCastRange(), 400) if point ~= nil and count >= 3 then self:THTD_SetAggressiveLock() local powerDuration = 0 local pv = self:GetAbilityPowerValue(ability2:GetAbilityName()) if pv ~= nil then powerDuration = pv[2] end THTD_SetSpellLock(self, ability2:GetAbilityName(), ability2:GetSpecialValueFor("duration_time") + powerDuration) self:CastAbilityOnPosition(point, ability2, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability3) then local point,count = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability3:GetCastRange(), 400) if point ~= nil and count >= 3 then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability3, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability1) then local point,count = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability1:GetCastRange(), 400) if point ~= nil and count >= 2 then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability1, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_kisume_thtd_ai() local ability1 = self:FindAbilityByName("thtd_kisume_01") local ability2 = self:FindAbilityByName("thtd_kisume_02") if self:IsReadyToCastAbility(ability2) then local unit = THTDSystem:FindRadiusOneUnitHasNoModifier(self, ability2:GetCastRange(),"modifier_kisume_02_debuff") if unit~=nil and unit:IsNull()==false then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit, ability2, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability1) and THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), ability1:GetCastRange()) > 0 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability1, self:GetPlayerOwnerID()) return end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_komachi_thtd_ai() local ability2 = self:FindAbilityByName("thtd_komachi_02") local ability3 = self:FindAbilityByName("thtd_komachi_03") local ability4 = self:FindAbilityByName("thtd_komachi_04") if not self:HasModifier("modifier_komachi_04") then if self:IsReadyToCastAbility(ability3) then local target = THTDSystem:FindRadiousMostDangerousUnit(self, ability3:GetCastRange(),function (targetUnit) return targetUnit:GetHealthPercent() > 1 end) if target ~= nil then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(target, ability3, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability2) then local point = nil if self.thtd_last_cast_point ~= nil then if THTD_HasUnitsInRadius(self, self.thtd_last_cast_point, ability2:GetSpecialValueFor("radius") * 0.7) then point = self.thtd_last_cast_point end else local point2,count = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability2:GetCastRange(), ability2:GetSpecialValueFor("radius")) if point2 ~= nil and count >= 3 then point = point2 end end if point ~= nil then THTD_SetSpellLock(self, ability2:GetAbilityName(), ability2:GetSpecialValueFor("duration_time") + 0.3) self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability2, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability4) then local unit = THTDSystem:FindRadiusWeakOneUnit(self, ability4:GetCastRange(), function (targetUnit) return targetUnit:HasModifier("modifier_komachi_04") == false end) if unit~=nil and unit:IsNull()==false then if unit:GetHealthPercent() <= ability4:GetSpecialValueFor("hp_kill") or unit:GetHealth() <= self:GetKillDamage() then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit, ability4, self:GetPlayerOwnerID()) return end end end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_kyouko_thtd_ai() local ability1 = self:FindAbilityByName("thtd_kyouko_01") local ability2 = self:FindAbilityByName("thtd_kyouko_02") if self:IsReadyToCastAbility(ability1) then local point,count = THTDSystem:FindRadiusOnePointPerfectLineAOE(self, ability1:GetCastRange(), ability1:GetSpecialValueFor("final_aoe") * 0.8, ability1:GetSpecialValueFor("distance"), false) if point~=nil and count>=0 then self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability1, self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability2) then local point = nil if self.thtd_last_cast_point ~= nil then if THTD_HasUnitsInRadius(self, self.thtd_last_cast_point, ability2:GetSpecialValueFor("range") * 0.8) then point = self.thtd_last_cast_point end else local point2,count = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability2:GetCastRange(), ability2:GetSpecialValueFor("range")) if point2 ~= nil and count >= 3 then point = point2 end end if point ~= nil then if self.thtd_last_cast_point ~= nil then THTD_SetSpellLock(self, ability2:GetAbilityName(), ability2:GetSpecialValueFor("duration_time")) end self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability2, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_shikieiki_thtd_ai() local ability1 = self:FindAbilityByName("thtd_shikieiki_01") local ability2 = self:FindAbilityByName("thtd_shikieiki_02") local ability3 = self:FindAbilityByName("thtd_shikieiki_03") local ability4 = self:FindAbilityByName("thtd_shikieiki_04") if self:IsReadyToCastAbility(ability1) and THTD_HasUnitsInRadius(self, self:GetAbsOrigin(), ability1:GetCastRange()) then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability1, self:GetPlayerOwnerID()) return end if self:IsReadyToCastAbility(ability2) and THTDSystem:FindUnitCountInPoint(self, self:GetAbsOrigin(), ability2:GetCastRange()) >= 3 then self:THTD_SetAggressiveLock() self:CastAbilityNoTarget(ability2, self:GetPlayerOwnerID()) return end if self:IsReadyToCastAbility(ability3) then local unit = THTDSystem:FindRadiousMostDangerousUnit(self, ability3:GetCastRange(), function(target) return target:HasModifier("modifier_thtd_shikieiki_03_debuff") == false end) if unit ~= nil then self:THTD_SetAggressiveLock() self:CastAbilityOnTarget(unit,ability3,self:GetPlayerOwnerID()) return end end if self:IsReadyToCastAbility(ability4) and ability2:IsCooldownReady() == false then local point = nil if self.thtd_last_cast_point ~= nil then if THTD_HasUnitsInRadius(self, self.thtd_last_cast_point, ability4:GetSpecialValueFor("radius") * 0.75) then point = self.thtd_last_cast_point end else local point2,count = THTDSystem:FindRadiusOnePointPerfectAOE(self, ability4:GetCastRange(), ability4:GetSpecialValueFor("radius")) if point2 ~= nil and count >= 3 then point = point2 end end if point ~= nil then THTD_SetSpellLock(self, ability4:GetAbilityName(), ability4:GetSpecialValueFor("duration_time")) self:THTD_SetAggressiveLock() self:CastAbilityOnPosition(point, ability4, self:GetPlayerOwnerID()) return end end if self:IsAttacking() == false and self:THTD_IsAggressiveLock() == false then self:MoveToPositionAggressive(self:GetOrigin() + self:GetForwardVector() * 100) self:THTD_SetAggressiveLock() end end function CDOTA_BaseNPC:THTD_IsAggressiveLock() if self.thtd_spelled_time == nil then return false end if self.thtd_spelled_time > GameRules:GetGameTime() then return true else return false end end function CDOTA_BaseNPC:THTD_SetAggressiveLock() self.thtd_spelled_time = GameRules:GetGameTime() + 0.9 end function CDOTA_BaseNPC:THTD_IsAttackChangeLock() if self.thtd_attack_changed_time == nil then return false end if self.thtd_attack_changed_time > GameRules:GetGameTime() then return true else return false end end function CDOTA_BaseNPC:THTD_SetAttackChangeLock() self.thtd_attack_changed_time = GameRules:GetGameTime() + 2.0 end