Files
2021-10-24 15:36:18 -04:00

585 lines
16 KiB
Lua
Executable File

--------------------------------------------------------------------------------
function GetEnemyHeroesInRange( hUnit , flRange )
if flRange == nil then
flRange = 1250
end
local enemies = FindUnitsInRadius( hUnit:GetTeamNumber(), hUnit:GetAbsOrigin(), nil, flRange, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES, FIND_CLOSEST, false )
return enemies
end
--------------------------------------------------------------------------------
function GetVisibleEnemyHeroesInRange( hUnit , flRange )
if flRange == nil then
flRange = 1250
end
local enemies = FindUnitsInRadius( hUnit:GetTeamNumber(), hUnit:GetAbsOrigin(), nil, flRange, DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_FLAG_NO_INVIS + DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES, FIND_CLOSEST, false )
return enemies
end
--------------------------------------------------------------------------------
function GetNoteworthyVisibleEnemiesNearby( hUnit, flRange )
if flRange == nil then
flRange = 1250
end
local eTARGETED_UNITS = DOTA_UNIT_TARGET_CREEP + DOTA_UNIT_TARGET_BASIC + DOTA_UNIT_TARGET_HERO
local enemies = FindUnitsInRadius( hUnit:GetTeamNumber(), hUnit:GetAbsOrigin(), nil, flRange, DOTA_UNIT_TARGET_TEAM_ENEMY, eTARGETED_UNITS, DOTA_UNIT_TARGET_FLAG_NO_INVIS + DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES, FIND_CLOSEST, false )
for index, hEnemy in pairs( enemies ) do
if hEnemy:IsRealHero() == false and hEnemy:IsConsideredHero() == false and hEnemy:IsIllusion() == false then
-- Remove the most unimportant units
table.remove( enemies, index )
end
end
return enemies
end
--------------------------------------------------------------------------------
function FilterEntitiesOutsideOfRange( vPosition, hEntitiesTable, flRange )
if hEntitiesTable == nil or #hEntitiesTable == 0 then
return {}
end
for n=#hEntitiesTable,1,-1 do
local hEntity = hEntitiesTable[ n ]
if hEntity ~= nil then
local fDist = ( hEntity:GetOrigin() - vPosition ):Length2D()
if fDist > flRange then
table.remove( hEntitiesTable, n )
end
end
end
return hEntitiesTable
end
--------------------------------------------------------------------------------
-- General Utility Fucntions --
--------------------------------------------------------------------------------
function AdvancedRandomVector( MaxLength, MinLength, vAwayFromVec, vAwayFromDist )
local vCandidate = nil
repeat
vCandidate = RandomVector(1):Normalized()*RandomFloat(MinLength,MaxLength)
until (vAwayFromVec == nil or vAwayFromDist == nil) or ( (vAwayFromVec - vCandidate):Length2D() > vAwayFromDist )
return vCandidate
end
function MoveOrder( hUnit, vPos )
ExecuteOrderFromTable({
UnitIndex = hUnit:entindex(),
OrderType = DOTA_UNIT_ORDER_MOVE_TO_POSITION,
Position = vPos,
})
return 1.0
end
function StopOrder( hUnit )
ExecuteOrderFromTable({
UnitIndex = hUnit:entindex(),
OrderType = DOTA_UNIT_ORDER_STOP,
})
end
--------------------------------------------------------------------------------
function AttackMoveOrder( hAttacker, hEnemy )
if (not hAttacker or not hEnemy or not hAttacker:HasAttackCapability() ) then
return 0.25
end
ExecuteOrderFromTable({
UnitIndex = hAttacker:entindex(),
OrderType = DOTA_UNIT_ORDER_ATTACK_MOVE,
Position = hEnemy:GetOrigin(),
})
return 1.0
end
--------------------------------------------------------------------------------
function AttackTargetOrder( hAttacker, hEnemy )
if ( not hAttacker or not hEnemy or not hAttacker:HasAttackCapability() ) then
return 0.25
end
--printf( "AttackTargetOrder -- attacker: %s, target: %s", hAttacker:GetUnitName(), hEnemy:GetUnitName() )
ExecuteOrderFromTable({
UnitIndex = hAttacker:entindex(),
OrderType = DOTA_UNIT_ORDER_ATTACK_TARGET,
TargetIndex = hEnemy:entindex(),
})
return 1.0
end
--------------------------------------------------------------------------------
function SprintIsReady( hCaster )
local hAbility = hCaster.abilities.hSprint
if hAbility ~= nil and hAbility:IsFullyCastable() then
return true
end
return false
end
--------------------------------------------------------------------------------
function CastSprint( hCaster )
local hAbility = hCaster.abilities.hSprint
ExecuteOrderFromTable({
UnitIndex = hCaster:entindex(),
OrderType = DOTA_UNIT_ORDER_CAST_NO_TARGET,
AbilityIndex = hAbility:entindex(),
Queue = false,
})
return 5.0
end
--------------------------------------------------------------------------------
function TailIsReady( hCaster )
local hAbility = hCaster.abilities.hTailSpinCCW
if hCaster.bEnemiesInFront and hAbility ~= nil and hAbility:IsFullyCastable() then
return true
end
return false
end
--------------------------------------------------------------------------------
function CastTailSpinCCW( hCaster )
local hAbility = hCaster.abilities.hTailSpinCCW
ExecuteOrderFromTable({
UnitIndex = hCaster:entindex(),
OrderType = DOTA_UNIT_ORDER_CAST_NO_TARGET,
AbilityIndex = hAbility:entindex()
})
return 5.0
end
--------------------------------------------------------------------------------
function MindControlIsReady( hCaster, hEnemies )
local nEnemiesAlive = 0
for _, hEnemy in pairs( hEnemies ) do
if hEnemy:IsAlive() then
nEnemiesAlive = nEnemiesAlive + 1
end
end
if nEnemiesAlive <= 1 then
return false
end
local hAbility = hCaster.abilities.hMindControl
if hAbility ~= nil and hAbility:IsFullyCastable() then
return true
end
return false
end
--------------------------------------------------------------------------------
function CastMindControl( hCaster, hEnemies )
local hAbility = hCaster.abilities.hMindControl
local hTarget = hEnemies[ RandomInt( 1, #hEnemies ) ]
ExecuteOrderFromTable({
UnitIndex = hCaster:entindex(),
OrderType = DOTA_UNIT_ORDER_CAST_TARGET,
TargetIndex = hTarget:entindex(),
AbilityIndex = hAbility:entindex(),
Queue = false,
})
return 4.0
end
--------------------------------------------------------------------------------
function TorrentsIsReady( hCaster )
local hAbility = hCaster.abilities.hTorrents
if hAbility ~= nil and hAbility:IsFullyCastable() then
return true
end
return false
end
--------------------------------------------------------------------------------
function CastTorrents( hCaster )
local hAbility = hCaster.abilities.hTorrents
ExecuteOrderFromTable({
UnitIndex = hCaster:entindex(),
OrderType = DOTA_UNIT_ORDER_CAST_NO_TARGET,
AbilityIndex = hAbility:entindex(),
Queue = false,
})
return 10
end
--------------------------------------------------------------------------------
function LineWaveIsReady( hCaster )
local hAbility = hCaster.abilities.hLineWave
if hAbility ~= nil and hAbility:IsFullyCastable() then
return true
end
return false
end
--------------------------------------------------------------------------------
function CastLineWave( hCaster, hEnemies )
local hAbility = hCaster.abilities.hLineWave
local hTarget = hEnemies[ RandomInt( 1, #hEnemies ) ]
local fDist = -1
local fHighestDist = 0
local hFarthestEnemy = nil
for _, hEnemy in pairs( hEnemies ) do
fDist = ( hEnemy:GetOrigin() - hCaster:GetOrigin() ):Length2D()
if fDist > fHighestDist then
fHighestDist = fDist
hFarthestEnemy = hEnemy
end
end
if hFarthestEnemy == nil then
return 0.5
end
ExecuteOrderFromTable({
UnitIndex = hCaster:entindex(),
OrderType = DOTA_UNIT_ORDER_CAST_TARGET,
TargetIndex = hFarthestEnemy:entindex(),
AbilityIndex = hAbility:entindex(),
Queue = false,
})
return 4
end
--------------------------------------------------------------------------------
function WavesIsReady( hCaster )
local hAbility = hCaster.abilities.hWaves
if hAbility ~= nil and hAbility:IsFullyCastable() then
return true
end
return false
end
--------------------------------------------------------------------------------
function CastWaves( hCaster )
local hAbility = hCaster.abilities.hWaves
ExecuteOrderFromTable({
UnitIndex = hCaster:entindex(),
OrderType = DOTA_UNIT_ORDER_CAST_NO_TARGET,
AbilityIndex = hAbility:entindex(),
Queue = false,
})
return 14
end
--------------------------------------------------------------------------------
function SummonMinionsIsReady( hCaster )
local hAbility = hCaster.abilities.hSummonMinions
if hAbility ~= nil and hAbility:IsFullyCastable() then
return true
end
return false
end
--------------------------------------------------------------------------------
function CastSummonMinions( hCaster )
local hAbility = hCaster.abilities.hSummonMinions
ExecuteOrderFromTable({
UnitIndex = hCaster:entindex(),
OrderType = DOTA_UNIT_ORDER_CAST_NO_TARGET,
AbilityIndex = hAbility:entindex(),
Queue = false,
})
return 7
end
--------------------------------------------------------------------------------
function SummonMinionsMediumIsReady( hCaster )
local hAbility = hCaster.abilities.hSummonMinionsMedium
if hAbility ~= nil and hAbility:IsFullyCastable() then
return true
end
return false
end
--------------------------------------------------------------------------------
function CastSummonMinionsMedium( hCaster )
local hAbility = hCaster.abilities.hSummonMinionsMedium
ExecuteOrderFromTable({
UnitIndex = hCaster:entindex(),
OrderType = DOTA_UNIT_ORDER_CAST_NO_TARGET,
AbilityIndex = hAbility:entindex(),
Queue = false,
})
return 7
end
--------------------------------------------------------------------------------
function SummonCloneIsReady( hCaster )
local hAbility = hCaster.abilities.hSummonClone
if hAbility ~= nil and hAbility:IsFullyCastable() and hCaster.nSummonCloneCasts < ( hCaster.Phase - 1 ) then
return true
end
return false
end
--------------------------------------------------------------------------------
function CastSummonClone( hCaster )
local hAbility = hCaster.abilities.hSummonClone
ExecuteOrderFromTable({
UnitIndex = hCaster:entindex(),
OrderType = DOTA_UNIT_ORDER_CAST_NO_TARGET,
AbilityIndex = hAbility:entindex(),
Queue = false,
})
return 2
end
--------------------------------------------------------------------------------
function MouthBeamIsReady( hCaster )
local hAbility = hCaster.abilities.hMouthBeam
if hAbility ~= nil and hAbility:IsFullyCastable() then
return true
end
return false
end
--------------------------------------------------------------------------------
function CastMouthBeam( hCaster, hEnemies )
local hAbility = hCaster.abilities.hMouthBeam
local hTarget = hEnemies[ RandomInt( 1, #hEnemies ) ]
if hTarget == nil then
return 1
end
ExecuteOrderFromTable({
UnitIndex = hCaster:entindex(),
OrderType = DOTA_UNIT_ORDER_CAST_POSITION,
Position = hTarget:GetOrigin(),
AbilityIndex = hAbility:entindex(),
Queue = false,
})
return 10.0
end
--------------------------------------------------------------------------------
function FindItemAbility( hCaster, szItemName )
for i = 0, 5 do
local item = hCaster:GetItemInSlot( i )
if item then
if item:GetAbilityName() == szItemName then
return item
end
end
end
end
--------------------------------------------------------------------------------
function CastTargetedItem( hUnit, hTarget, szItemName )
local hItem = hUnit:FindItemInInventory( szItemName )
return CastTargetedAbility( hUnit, hTarget, hItem )
end
--------------------------------------------------------------------------------
function CastUntargetedItem( hUnit, szItemName )
local hItem = hUnit:FindItemInInventory( szItemName )
return CastUntargetedAbility( hUnit, hItem )
end
--------------------------------------------------------------------------------
function CastPositionalItem( hUnit, vPosition, szItemName )
local hItem = hUnit:FindItemInInventory( szItemName )
return CastPositionalAbility( hUnit, vPosition, hItem )
end
--------------------------------------------------------------------------------
function CastTargetedAbility( hUnit, hTarget, hAbility )
if type(hAbility) == "string" then
hAbility = hUnit:FindAbilityByName(hAbility)
printf("result of string ability is %s", hAbility:GetName())
end
if hAbility and hAbility:IsFullyCastable() then
--printf( "%s casting %s on %s", hUnit:GetName(), hAbility:GetName(), hTarget:GetName() )
ExecuteOrderFromTable({
UnitIndex = hUnit:entindex(),
OrderType = DOTA_UNIT_ORDER_CAST_TARGET,
TargetIndex = hTarget:entindex(),
AbilityIndex = hAbility:entindex()
})
return true
end
return false
end
--------------------------------------------------------------------------------
function CastPositionalAbility( hUnit, vPosition, hAbility )
if type(hAbility) == "string" then
hAbility = hUnit:FindAbilityByName(hAbility)
end
if hAbility and hAbility:IsFullyCastable() then
ExecuteOrderFromTable({
UnitIndex = hUnit:entindex(),
OrderType = DOTA_UNIT_ORDER_CAST_POSITION,
Position = vPosition,
AbilityIndex = hAbility:entindex()
})
return true
end
return false
end
--------------------------------------------------------------------------------
function CastUntargetedAbility( hUnit, hAbility )
if type(hAbility) == "string" then
hAbility = hUnit:FindAbilityByName(hAbility)
end
if hAbility and hAbility:IsFullyCastable() then
ExecuteOrderFromTable({
UnitIndex = hUnit:entindex(),
OrderType = DOTA_UNIT_ORDER_CAST_NO_TARGET,
AbilityIndex = hAbility:entindex()
})
return true
end
return false
end
--------------------------------------------------------------------------------
function GetAlliesInRange( hCaster, flRange )
return FindUnitsInRadius( hCaster:GetTeamNumber(), hCaster:GetOrigin(), nil, flRange,
DOTA_UNIT_TARGET_TEAM_FRIENDLY, DOTA_UNIT_TARGET_HERO + DOTA_UNIT_TARGET_BASIC + DOTA_UNIT_TARGET_OTHER,
DOTA_UNIT_TARGET_FLAG_NO_INVIS + DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES, FIND_CLOSEST, false )
end
function LastAllyCastTime( hCaster, hAbility, flRange, hTarget )
if flRange == nil then
flRange = 1000
end
local flLastCastTime = -999999
local hAllies = GetAlliesInRange( hCaster, flRange )
for index,hAlly in pairs(hAllies) do
local flAllyTime = hAlly["last_cast_time_"..hAbility:GetName()]
local hAllyTarget = hAlly["last_cast_target_"..hAbility:GetName()]
if flAllyTime ~= nil and (hTarget == nil or hTarget == hAllyTarget) then
flLastCastTime = math.max(flAllyTime,flLastCastTime)
end
end
return flLastCastTime
end
--------------------------------------------------------------------------------
function UpdateLastCastTime( hCaster, hAbility, hTarget )
hCaster["last_cast_time_"..hAbility:GetName()] = GameRules:GetGameTime()
hCaster["last_cast_target_"..hAbility:GetName()] = hTarget
end
--------------------------------------------------------------------------------
function TeleportIsReady( hCaster )
if ( GameRules:GetGameTime() > ( hCaster.fLastTeleportChain + hCaster.nTeleportChainCD ) ) then
hCaster.nRecentTeleportsCast = 0
hCaster.fLastTeleportChain = GameRules:GetGameTime()
end
local hAbility = hCaster.abilities.hTeleport
if hAbility ~= nil and hAbility:IsFullyCastable() and ( hCaster.nRecentTeleportsCast < hCaster.nTeleportsToChain ) then
return true
end
return false
end
--------------------------------------------------------------------------------
function CastTeleport( hCaster, hEnemies )
local hAbility = hCaster.abilities.hTeleport
local hFilteredEnemies = {}
for _, hEnemy in pairs( hEnemies ) do
local fDist = ( hEnemy:GetOrigin() - hCaster:GetOrigin() ):Length2D()
if fDist > 500 then
table.insert( hFilteredEnemies, hEnemy )
end
end
local hTarget = nil
if #hFilteredEnemies > 0 then
hTarget = hFilteredEnemies[ RandomInt( 1, #hFilteredEnemies ) ]
else
hTarget = hEnemies[ RandomInt( 1, #hEnemies ) ]
end
local vTargetPos = hTarget:GetOrigin()
ExecuteOrderFromTable({
UnitIndex = hCaster:entindex(),
OrderType = DOTA_UNIT_ORDER_CAST_POSITION,
Position = vTargetPos,
AbilityIndex = hAbility:entindex(),
Queue = false,
})
hCaster.nRecentTeleportsCast = hCaster.nRecentTeleportsCast + 1
if ( hCaster.nRecentTeleportsCast >= hCaster.nTeleportsToChain ) then
return 4.0
end
return 1.8
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------