Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- repeat task.wait() until game:IsLoaded()
- -- ========================================
- -- CONFIGURATION - Edit settings below
- -- ========================================
- -- Enable/disable the script
- getgenv().AutoAbilitiesEnabled = true
- -- Game speed multiplier (affects cooldown calculations)
- -- Set to 3 if playing on 3x speed, 1 for normal speed, etc.
- local GAME_SPEED = 3
- -- Tower ability configurations
- -- Format: [TowerName] = { ability1, ability2, ... }
- --
- -- Available options for each ability:
- -- - name: Ability name (required) - cooldown and requiredLevel auto-detected from TowerInfo
- -- - onlyOnBoss: Only use when boss exists (true/false)
- -- - onSpecificWaves: Only use on specific waves (e.g., {25, 50} or single wave 50)
- -- - minWave: Only use on or after this wave number
- -- - maxWave: Only use on or before this wave number
- -- - requireBossInRange: Wait for boss to be in tower's range (true/false)
- -- - rangeDelay: How long (seconds) boss must be in range before using ability
- -- - delayAfterBossSpawn: Wait X seconds after boss spawns before using ability
- local TOWER_ABILITIES = {
- ["AiHoshinoEvo"] = {
- {name = "Concert"}
- },
- ["Bulma"] = {
- {name = "Summon Wish Dragon"},
- {name = "Wish: Power"}
- },
- ["AsuraEvo"] = {
- {name = "Lines of Sanzu", onlyOnBoss = true, onSpecificWaves = 50}
- },
- ["NarutoBaryon"] = {
- {name = "Spiralling Shuriken"},
- {name = "Lava Release: Spiralling Shuriken", onlyOnBoss = true, onSpecificWaves = 50}
- },
- ["LelouchEvo"] = {
- {name = "All of you, Die!", onlyOnBoss = true, onSpecificWaves = 50, requireBossInRange = true},
- {name = "Submission", onlyOnBoss = true, onSpecificWaves = 50, requireBossInRange = true}
- },
- ["LightEvo"] = {
- {name = "Write Names", onlyOnBoss = true, onSpecificWaves = 50, delayAfterBossSpawn = 1}
- }
- }
- -- ========================================
- -- SCRIPT CODE - Do not edit below unless you know what you're doing
- -- ========================================
- local RS = game:GetService("ReplicatedStorage")
- local Towers = workspace.Towers
- local bossSpawnTime = nil
- local lightAbilityUsed = false
- local bossInRangeTracker = {}
- local abilityCooldowns = {}
- local towerInfoCache = {}
- local generalBossSpawnTime = nil
- local function getTowerInfo(towerName)
- if towerInfoCache[towerName] then
- return towerInfoCache[towerName]
- end
- local success, towerData = pcall(function()
- local towerInfoPath = RS:WaitForChild("Modules"):WaitForChild("TowerInfo")
- local towerModule = towerInfoPath:FindFirstChild(towerName)
- if towerModule and towerModule:IsA("ModuleScript") then
- return require(towerModule)
- end
- return nil
- end)
- if success and towerData then
- towerInfoCache[towerName] = towerData
- return towerData
- end
- return nil
- end
- local function getAbilityData(towerName, abilityName)
- local towerInfo = getTowerInfo(towerName)
- if not towerInfo then
- return nil
- end
- for level = 0, 50 do
- if towerInfo[level] then
- if towerInfo[level].Ability then
- local abilityData = towerInfo[level].Ability
- if abilityData.Name == abilityName and not abilityData.AttributeRequired then
- return {
- cooldown = abilityData.Cd,
- requiredLevel = level,
- isGlobal = abilityData.IsCdGlobal
- }
- end
- end
- if towerInfo[level].Abilities then
- for _, abilityData in pairs(towerInfo[level].Abilities) do
- if abilityData.Name == abilityName and not abilityData.AttributeRequired then
- return {
- cooldown = abilityData.Cd,
- requiredLevel = level,
- isGlobal = abilityData.IsCdGlobal
- }
- end
- end
- end
- end
- end
- return nil
- end
- local function getTower(name)
- return Towers:FindFirstChild(name)
- end
- local function getUpgradeLevel(tower)
- if not tower then return 0 end
- local upgradeVal = tower:FindFirstChild("Upgrade")
- if upgradeVal and upgradeVal:IsA("ValueBase") then
- return upgradeVal.Value or 0
- end
- return 0
- end
- local function getCurrentWave()
- local ok, result = pcall(function()
- local player = game:GetService("Players").LocalPlayer
- local gui = player.PlayerGui:FindFirstChild("Top")
- if not gui then return 0 end
- local frame = gui:FindFirstChild("Frame")
- if not frame then return 0 end
- frame = frame:FindFirstChild("Frame")
- if not frame then return 0 end
- frame = frame:FindFirstChild("Frame")
- if not frame then return 0 end
- frame = frame:FindFirstChild("Frame")
- if not frame then return 0 end
- local button = frame:FindFirstChild("TextButton")
- if not button then return 0 end
- local children = button:GetChildren()
- if #children < 3 then return 0 end
- local text = children[3].Text
- return tonumber(text) or 0
- end)
- return ok and result or 0
- end
- local function getTowerInfoName(tower)
- if not tower then return nil end
- local candidates = {
- tower:GetAttribute("TowerType"),
- tower:GetAttribute("Type"),
- tower:GetAttribute("TowerName"),
- tower:GetAttribute("BaseTower"),
- tower:FindFirstChild("TowerType") and tower.TowerType:IsA("ValueBase") and tower.TowerType.Value,
- tower:FindFirstChild("Type") and tower.Type:IsA("ValueBase") and tower.Type.Value,
- tower:FindFirstChild("TowerName") and tower.TowerName:IsA("ValueBase") and tower.TowerName.Value,
- tower.Name
- }
- for _, candidate in ipairs(candidates) do
- if candidate and type(candidate) == "string" and candidate ~= "" then
- return candidate
- end
- end
- return tower.Name
- end
- local function getTower(name)
- return Towers:FindFirstChild(name)
- end
- local function getUpgradeLevel(tower)
- if not tower then return 0 end
- local upgradeVal = tower:FindFirstChild("Upgrade")
- if upgradeVal and upgradeVal:IsA("ValueBase") then
- return upgradeVal.Value or 0
- end
- return 0
- end
- local function useAbility(tower, abilityName)
- if tower then
- pcall(function()
- local Event = RS.Remotes.Ability
- Event:InvokeServer(tower, abilityName)
- end)
- end
- end
- local function isOnCooldown(towerName, abilityName)
- local abilityData = getAbilityData(towerName, abilityName)
- if not abilityData or not abilityData.cooldown then return false end
- local key = towerName .. "_" .. abilityName
- local lastUsed = abilityCooldowns[key]
- if not lastUsed then return false end
- local adjustedCooldown = abilityData.cooldown / GAME_SPEED
- local elapsed = tick() - lastUsed
- return elapsed < adjustedCooldown
- end
- local function setAbilityUsed(towerName, abilityName)
- local key = towerName .. "_" .. abilityName
- abilityCooldowns[key] = tick()
- end
- local function hasAbilityBeenUnlocked(towerName, abilityName, towerLevel)
- local abilityData = getAbilityData(towerName, abilityName)
- if not abilityData then
- return false
- end
- local unlocked = towerLevel >= abilityData.requiredLevel
- if not unlocked then
- end
- return unlocked
- end
- local function isWave50()
- local ok, result = pcall(function()
- local player = game:GetService("Players").LocalPlayer
- local gui = player.PlayerGui:FindFirstChild("Top")
- if not gui then return false end
- local frame = gui:FindFirstChild("Frame")
- if not frame then return false end
- frame = frame:FindFirstChild("Frame")
- if not frame then return false end
- frame = frame:FindFirstChild("Frame")
- if not frame then return false end
- frame = frame:FindFirstChild("Frame")
- if not frame then return false end
- local button = frame:FindFirstChild("TextButton")
- if not button then return false end
- local children = button:GetChildren()
- if #children < 3 then return false end
- local text = children[3].Text
- return text == tostring(BOSS_WAVE) or text == BOSS_WAVE
- end)
- return ok and result
- end
- local function bossExists()
- local ok, result = pcall(function()
- local enemies = workspace:FindFirstChild("Enemies")
- if not enemies then return false end
- return enemies:FindFirstChild("Boss") ~= nil
- end)
- return ok and result
- end
- local function bossReadyForAbilities()
- if bossExists() then
- if not generalBossSpawnTime then
- generalBossSpawnTime = tick()
- end
- local elapsed = tick() - generalBossSpawnTime
- return elapsed >= 1
- else
- generalBossSpawnTime = nil
- return false
- end
- end
- local function checkBossSpawnTime()
- if bossExists() then
- if not bossSpawnTime then
- bossSpawnTime = tick()
- lightAbilityUsed = false
- end
- local elapsed = tick() - bossSpawnTime
- if elapsed >= 16 and not lightAbilityUsed then
- return true
- end
- return false
- else
- bossSpawnTime = nil
- lightAbilityUsed = false
- return false
- end
- end
- local function getBossPosition()
- local ok, result = pcall(function()
- local enemies = workspace:FindFirstChild("Enemies")
- if not enemies then return nil end
- local boss = enemies:FindFirstChild("Boss")
- if not boss then return nil end
- local hrp = boss:FindFirstChild("HumanoidRootPart")
- if hrp then
- return hrp.Position
- end
- return nil
- end)
- return ok and result or nil
- end
- local function getTowerPosition(tower)
- if not tower then return nil end
- local ok, result = pcall(function()
- local hrp = tower:FindFirstChild("HumanoidRootPart")
- if hrp then
- return hrp.Position
- end
- return nil
- end)
- return ok and result or nil
- end
- local function getTowerRange(tower)
- if not tower then return 0 end
- local ok, result = pcall(function()
- local stats = tower:FindFirstChild("Stats")
- if not stats then return 0 end
- local range = stats:FindFirstChild("Range")
- if not range then return 0 end
- return range.Value or 0
- end)
- return ok and result or 0
- end
- local function isBossInRange(tower)
- local bossPos = getBossPosition()
- local towerPos = getTowerPosition(tower)
- if not bossPos or not towerPos then
- return false
- end
- local range = getTowerRange(tower)
- if range <= 0 then return false end
- local distance = (bossPos - towerPos).Magnitude
- return distance <= range
- end
- local function checkBossInRangeForDuration(tower, requiredDuration)
- if not tower then return false end
- local towerName = tower.Name
- local currentTime = tick()
- if isBossInRange(tower) then
- if requiredDuration == 0 then
- return true
- end
- if not bossInRangeTracker[towerName] then
- bossInRangeTracker[towerName] = currentTime
- return false
- else
- local timeInRange = currentTime - bossInRangeTracker[towerName]
- if timeInRange >= requiredDuration then
- return true
- end
- end
- else
- bossInRangeTracker[towerName] = nil
- end
- return false
- end
- while getgenv().AutoAbilitiesEnabled do
- wait(0.5)
- local currentWave = getCurrentWave()
- local hasBoss = bossExists()
- for towerName, abilities in pairs(TOWER_ABILITIES) do
- local tower = getTower(towerName)
- if tower then
- local towerInfoName = getTowerInfoName(tower)
- local towerLevel = getUpgradeLevel(tower)
- for _, abilityConfig in ipairs(abilities) do
- local shouldUse = true
- local failReason = nil
- if not hasAbilityBeenUnlocked(towerInfoName, abilityConfig.name, towerLevel) then
- shouldUse = false
- failReason = "Not unlocked (Level " .. towerLevel .. ")"
- end
- if isOnCooldown(towerInfoName, abilityConfig.name) then
- shouldUse = false
- failReason = "On cooldown"
- end
- if abilityConfig.onlyOnBoss and not hasBoss then
- shouldUse = false
- failReason = "Boss required but not present"
- end
- if abilityConfig.onlyOnBoss and hasBoss and shouldUse then
- if not bossReadyForAbilities() then
- shouldUse = false
- failReason = "Waiting 1s after boss spawn"
- end
- end
- if abilityConfig.onSpecificWaves and shouldUse then
- local onCorrectWave = false
- if type(abilityConfig.onSpecificWaves) == "table" then
- for _, wave in ipairs(abilityConfig.onSpecificWaves) do
- if currentWave == wave then
- onCorrectWave = true
- break
- end
- end
- else
- onCorrectWave = (currentWave == abilityConfig.onSpecificWaves)
- end
- if not onCorrectWave then
- shouldUse = false
- failReason = "Wrong wave (Current: " .. currentWave .. ")"
- end
- end
- if abilityConfig.minWave and currentWave < abilityConfig.minWave then
- shouldUse = false
- end
- if abilityConfig.maxWave and currentWave > abilityConfig.maxWave then
- shouldUse = false
- end
- if abilityConfig.requireBossInRange and shouldUse then
- local rangeDelay = abilityConfig.rangeDelay or 0
- if not checkBossInRangeForDuration(tower, rangeDelay) then
- shouldUse = false
- end
- end
- if shouldUse then
- if abilityConfig.delayAfterBossSpawn then
- if checkBossSpawnTime() then
- useAbility(tower, abilityConfig.name)
- lightAbilityUsed = true
- setAbilityUsed(towerInfoName, abilityConfig.name)
- end
- else
- useAbility(tower, abilityConfig.name)
- setAbilityUsed(towerInfoName, abilityConfig.name)
- end
- end
- end
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment