h0nda is sharing code with you

Bitbucket is a code hosting site. Unlimited public and private repositories. Free for small teams.

Don't show this again

h0nda / fpb scripts

set of scripts for FPB

Clone this repository (size: 397.9 KB): HTTPS / SSH
git clone https://bitbucket.org/h0nda/fpb-scripts.git
git clone git@bitbucket.org:h0nda/fpb-scripts.git

fpb scripts / wardScanner.lua

--[[
        Breaking Bad Ward Scanner
        v3.2

        Displays enemy wards / shaco boxes / teemo mushrooms / maokai's saplings / caitlyn and nidalee traps on mini-map and in-game.
        Written by Weee

    What's new in 3.2:
     1) Removed resolution choosing. Now BBWS uses minimap_marks_lib, which runs a minimap_marks_wizard setup when needed. With this tool you can easily find offsets for
        any resolution. Also it's easy now to do for flipped minimap! If you saved wrong offsets - just delete minimap_marks.cfg file in FPB\Scripts\libs folder.
            P.S. - It's some kind of a total-retard bulletproof too. I will keep this thing for future versions too.
     2) Updated BBWS to work with new Animations Lib v0.3

    What's new in 3.1:
     1) Some changes to animations and drawings:
            - Reworked the script for anim lib v0.2
            - Cursor-hooked timers smoothly fade-in now
            - Cursor-hooked timers can't be cut off by the screen edge anymore
            - Added neat notifications like in AutoSmiteee
     2) Added hold hotkey for Vision Range thing like in AutoSmiteee (default: ALT).
     3) Now cursor-hooked timers are optional: you can disable them with setting showCursorHookedTimers to false.
     4) Fixed a bug when expireWarning didn't show up.

    What's new in 3.0:
     1) Now each ward has it's own name (w1, w2, w3, ...) which is used in minimap overlay, messages, timers, etc.
     2) Now you can look up any specific object's (ward/box/trap/etc) actual timer + expiration in-game time by moving your mouse near that object.
     3) Now BBWS uses animations to provide better awareness.
     4) Warning messages when ward is placed or about to expire (like in creepTimers) including it's actual in-game expiration time.
]]

--[[            Config          ]]
loadScan = 1                   -- One-time scan for wards/boxes/traps/etc when script is just loaded. If you have crashes - try to set it to 0.
toggleVisionRangeHotkey = 121  -- Hotkey for toggling vision of wards/boxes/etc (F10 by default).
holdVisionRangeHotkey = 18     -- Let's you to show wards' range even if it's OFF by holding this hotkey (ALT by default). Set it to nil if you don't want to use this feature.
addWarning = 1                 -- Print a warning when someone places a ward. 1 - On, 0 - Off.
expireWarning = 1              -- Print a warning when ward is about to expire. 1 - On, 0 - Off.
expireWarningTime = 20         -- Time (seconds) before the script will notify you about ward/box/trap expiration. This is used for animations and so on, not only PrintChat warnings!
animNotify = true              -- true - new animated notifications; false - old PrintChat notifications
showCursorHookedTimers = true  -- true - show cursor-hooked timers; false - don't show.


--[[            Globals         ]]
wards = {
    wards = {},
    boxes = {},
    traps = {}
}
toggleVisionRange = false
holding = false
animPlayedTick = nil
validatorTick = GetTick()
infoTick = GetTick()
mouse = {}
mouse.x,mouse.y,mouse.z = GetMousePosition()
pos2D = {}
pos2D.x,pos2D.y = GetCursorPosition()


--[[            Code            ]]
dofile(SCRIPT_PATH.."libs/anim.lua")
dofile(SCRIPT_PATH.."libs/minimap_marks_lib.lua")
initMarks()

de = DrawingEngine()
ds = DrawingSets()


ds:Add("notify",DrawingText("BBWS Vision Range: ",14,70,45,1,1,1,1))
ds.notify.objects[1].A = 0

function findUniqueIndex(thistable)
    for i=1, #thistable+1, 1 do
        local flag = 0
        for k,v in pairs(thistable) do
            if v.uniqueID == i then
                flag = 1
                break
            end
        end
        if flag == 0 then return i end
    end
end

function GetDistance2D( o1, o2 )
    if o1.x ~= nil and o1.y ~= nil and o2.x ~= nil and o2.y ~= nil then return math.sqrt( math.pow(o1.x - o2.x, 2) + math.pow(o1.z - o2.z, 2) ) else return 0 end
end

function check_and_add_WardToTheTable(object,wardsTable,isScan)
    if object ~= nil then
        local name = object.charName
        if object.team ~= TEAM_ENEMY or
            (name ~= "SightWard" and name ~= "VisionWard" and name ~= "WriggleLantern"
            and name ~= "ShacoBox"and name ~= "TeemoMushroom" and name ~= "MaokaiSproutling"
            and name ~= "CaitlynTrap" and name ~= "Nidalee_Spear") then
                return
        end
        if object.team == TEAM_ENEMY then
            local wardObject = {}
            wardObject.object = object
            wardObject.tick = GetTick()
            if isScan then
                wardObject.notifyAdd = 1
            else
                wardObject.notifyAdd = 0
            end
            wardObject.notifyExpire = 0
            if name == "SightWard" or name =="WriggleLantern" or name == "VisionWard" then
                if name == "VisionWard" then wardObject.color = {1,0.3,1,1} else wardObject.color = {0,1,0.4,1} end
                wardObject.uniqueID = findUniqueIndex(wards.wards)
                wardObject.overlayMark = "w"..wardObject.uniqueID
                wardObject.inGameMarkType = "wards"
                wardObject.range = 1450
                wardObject.durationTime = 180
                wardObject.showName = wardObject.overlayMark
            end
            if name == "ShacoBox" or name == "MaokaiSproutling" or name == "TeemoMushroom" then
                wardObject.color = {1,0.3,0.3,1}
                wardObject.uniqueID = findUniqueIndex(wards.boxes)
                wardObject.overlayMark = "o"
                wardObject.inGameMarkType = "boxes"
                if name == "TeemoMushroom" then wardObject.range = 425 else wardObject.range = 780 end
                if name == "ShacoBox" then
                    wardObject.showName = "Box"
                    wardObject.durationTime = 60
                elseif name == "MaokaiSproutling" then
                    wardObject.showName = "Bomb"
                    wardObject.durationTime = 35
                else
                    wardObject.showName = "Shroom"
                    wardObject.durationTime = 600
                end
            end
            if name == "CaitlynTrap" or name == "Nidalee_Spear" then
                wardObject.color = {0.9,0.9,1,1}
                wardObject.uniqueID = findUniqueIndex(wards.traps)
                wardObject.overlayMark = "o"
                wardObject.inGameMarkType = "traps"
                wardObject.durationTime = 240
                wardObject.showName = "Trap"
            end
            wardObject.mapx, wardObject.mapz = convertToMinimap(wardObject.object.x, wardObject.object.z)
            if wardObject.inGameMarkType == "wards" then
                ds:Add("circle_wards"..wardObject.uniqueID,DrawingCircle(100,wardObject.object))
            elseif wardObject.inGameMarkType == "boxes" then
                ds:Add("circle_boxes"..wardObject.uniqueID,DrawingCircle(90,wardObject.object),DrawingCircle(45,wardObject.object))
            elseif wardObject.inGameMarkType == "traps" then
                ds:Add("circle_traps"..wardObject.uniqueID,DrawingCircle(60,wardObject.object),DrawingCircle(30,wardObject.object))
            end
            ds:Add("text_"..wardObject.inGameMarkType..wardObject.uniqueID,DrawingText(wardObject.overlayMark,14,wardObject.mapx,wardObject.mapz,wardObject.color[1],wardObject.color[2],wardObject.color[3],wardObject.color[4]))
            table.insert(wardsTable[wardObject.inGameMarkType],wardObject)
        end
    end
end

-- Checking object creations and adding wards/boxes/traps/etc to the table:
function AddWard(object)
    check_and_add_WardToTheTable(object,wards,false)
end

-- Scanning through all objects and adding wards/boxes/traps/etc to the table. This scan runs only once in Load() function.
-- We need it only to show already placed wards/boxes/traps/etc after script reloading or reconnecting.
function scanForCreatedWards()
    for i = 1, GetObjectCount(), 1 do
        object = GetObject(i)
        check_and_add_WardToTheTable(object,wards,true)
    end
end

-- Scanning through wards table and removing invalid objects:
function Validator()
    validatorTick = GetTick()
    if (#wards.wards + #wards.boxes + #wards.traps) < 1 then return end
    for k,wardgrp in pairs(wards) do
        for i,v in pairs(wardgrp) do
            if not v.object.valid then
                if showCursorHookedTimers then ds:Remove("mousetext_"..v.inGameMarkType..v.uniqueID) end
                ds:Remove("circle_"..v.inGameMarkType..v.uniqueID)
                ds:Remove("text_"..v.inGameMarkType..v.uniqueID)
                ds:Remove("visioncircle_"..v.inGameMarkType..v.uniqueID)
                table.remove(wardgrp,i)
            end
        end
    end
end

function Timer( tick )
    de:ComputeAnimations(ds)

    if animPlayedTick ~= nil and tick - animPlayedTick >= 2000 then
        animPlayedTick = nil
        ds:Get("notify"):RunAnimation("fadeinout",FADING,OPACITY,1,0,0.015,0)
        ds:Get("notify"):RunAnimation("slide",FADING,POSITIONX,70,0,0.3,0)
    end

    if tick - infoTick >= 100 then
        infoTick = GetTick()
        for k,wardgrp in pairs(wards) do
            for i,ward in pairs(wardgrp) do
                local timerText, expirationText = FormatTimerText(tick, ward.durationTime, ward.tick)
                if ward.inGameMarkType == "wards" and addWarning == 1 and ward.notifyAdd == 0 then
                    ward.notifyAdd = 1
                    PrintChat(" >> Enemy set "..ward.showName.." "..expirationText)
                end
                if (ward.tick + ward.durationTime*1000) - tick <= expireWarningTime*1000 then
                    if ward.inGameMarkType == "wards" and expireWarning == 1 and ward.notifyExpire == 0 then
                        ward.notifyExpire = 1
                        PrintChat(" >> "..ward.showName.." will expire in less than: "..timerText.." "..expirationText)
                    end
                    if ds["circle_"..ward.inGameMarkType..ward.uniqueID].animation == nil then
                        ds:Get("circle_"..ward.inGameMarkType..ward.uniqueID):RunAnimation("teardrop",FADING,RADIUS,1,0.5,4,1,true)
                    end
                    if ds["text_"..ward.inGameMarkType..ward.uniqueID].animation == nil then
                        ds:Get("text_"..ward.inGameMarkType..ward.uniqueID):RunAnimation("fadeinout",PULSE,OPACITY,1,0.5,4,1,true)
                    end
                    if showCursorHookedTimers and ds["mousetext_"..ward.inGameMarkType..ward.uniqueID] ~= nil and (ds["mousetext_"..ward.inGameMarkType..ward.uniqueID].animation == nil or ds["mousetext_"..ward.inGameMarkType..ward.uniqueID].animation.fadeinout == nil) then
                        ds:Get("mousetext_"..ward.inGameMarkType..ward.uniqueID):RunAnimation("fadeinout",PULSE,OPACITY,1,0.5,4,1,true)
                    end
                end
                if ds["circle_"..ward.inGameMarkType..ward.uniqueID].animation then
                    ds["circle_"..ward.inGameMarkType..ward.uniqueID].animation.teardrop.speed = ds["circle_"..ward.inGameMarkType..ward.uniqueID].animation.teardrop.speed + (GetTick()-ward.tick-(ward.durationTime-expireWarningTime)*1000)*0.00001
                end
                if ds["text_"..ward.inGameMarkType..ward.uniqueID].animation then
                    ds["text_"..ward.inGameMarkType..ward.uniqueID].animation.fadeinout.speed = ds["text_"..ward.inGameMarkType..ward.uniqueID].animation.fadeinout.speed + (GetTick()-ward.tick-(ward.durationTime-expireWarningTime)*1000)*0.00001
                end
                if showCursorHookedTimers and ds["mousetext_"..ward.inGameMarkType..ward.uniqueID] ~= nil and ds["mousetext_"..ward.inGameMarkType..ward.uniqueID].animation and ds["mousetext_"..ward.inGameMarkType..ward.uniqueID].animation.fadeinout then
                    ds["mousetext_"..ward.inGameMarkType..ward.uniqueID].animation.fadeinout.speed = ds["text_"..ward.inGameMarkType..ward.uniqueID].animation.fadeinout.speed + (GetTick()-ward.tick-(ward.durationTime-expireWarningTime)*1000)*0.00001
                end
                if showCursorHookedTimers and GetDistance2D(ward.object,mouse) <= 400 and ds["mousetext_"..ward.inGameMarkType..ward.uniqueID] == nil then
                    ds:Add("mousetext_"..ward.inGameMarkType..ward.uniqueID,DrawingText(ward.showName.." "..timerText.." "..expirationText,14,pos2D.x-25,pos2D.y-15,1,1,1,1))
                    ds["mousetext_"..ward.inGameMarkType..ward.uniqueID].objects[1].A = 0
                    ds:Get("mousetext_"..ward.inGameMarkType..ward.uniqueID):RunAnimation("fadein",FADING,OPACITY,0,1,30,0,true)
                end
                if showCursorHookedTimers and GetDistance2D(ward.object,mouse) > 400 and ds["mousetext_"..ward.inGameMarkType..ward.uniqueID] ~= nil then
                    ds:Remove("mousetext_"..ward.inGameMarkType..ward.uniqueID)
                end
                if ward.inGameMarkType == "wards" or ward.inGameMarkType == "boxes" then
                    if toggleVisionRange and ds["visioncircle_"..ward.inGameMarkType..ward.uniqueID] == nil then
                        ds:Add("visioncircle_"..ward.inGameMarkType..ward.uniqueID,DrawingCircle(ward.range,ward.object))
                    end
                    if not toggleVisionRange and ds["visioncircle_"..ward.inGameMarkType..ward.uniqueID] ~= nil then
                        ds:Remove("visioncircle_"..ward.inGameMarkType..ward.uniqueID)
                    end
                end
            end
        end
    end

    if tick - validatorTick >= 500 then
        Validator()
        if initMarksState == 1 then
            for i,wardtype in pairs(wards) do
                for k,ward in pairs(wardtype) do
                    if ward.object ~= nil 
                    and ds["text_"..ward.inGameMarkType..ward.uniqueID].objects[1].position.x == -100
                    and ds["text_"..ward.inGameMarkType..ward.uniqueID].objects[1].position.y == -100 then
                        local ingamex, ingamez = ward.object.x, ward.object.z
                        ds["text_"..ward.inGameMarkType..ward.uniqueID].objects[1].position.x, ds["text_"..ward.inGameMarkType..ward.uniqueID].objects[1].position.y = convertToMinimap(ingamex, ingamez)
                    end
                end
            end
        else
            initMarks()
        end
    end
end

function WardDrawer()
    mouse.x,mouse.y,mouse.z = GetMousePosition()
    pos2D.x,pos2D.y = GetCursorPosition()
    if de and ds then
        if showCursorHookedTimers then
            mouseTextCounter = 0
            for k,wardgrp in pairs(wards) do
                for i,ward in pairs(wardgrp) do
                    local timerText, expirationText = FormatTimerText(GetTick(), ward.durationTime, ward.tick)
                    if ds["mousetext_"..ward.inGameMarkType..ward.uniqueID] ~= nil then
                        ward.mouseTextCounter = mouseTextCounter + 1
                        mouseTextCounter = mouseTextCounter + 1
                        ds["mousetext_"..ward.inGameMarkType..ward.uniqueID].objects[1].position.x = pos2D.x-25
                        if WINDOW_W - WINDOW_X - pos2D.x <= 100 then ds["mousetext_"..ward.inGameMarkType..ward.uniqueID].objects[1].position.x = pos2D.x-50 end
                        if WINDOW_W - WINDOW_X - pos2D.x <= 50 then ds["mousetext_"..ward.inGameMarkType..ward.uniqueID].objects[1].position.x = pos2D.x-75 end
                        if pos2D.x <= 50 then ds["mousetext_"..ward.inGameMarkType..ward.uniqueID].objects[1].position.x = pos2D.x end
                        ds["mousetext_"..ward.inGameMarkType..ward.uniqueID].objects[1].position.y = pos2D.y-15*ward.mouseTextCounter
                        ds["mousetext_"..ward.inGameMarkType..ward.uniqueID].objects[1].text = ward.showName.." "..timerText.." "..expirationText
                    else
                        ward.mouseTextCounter = nil
                    end
                end
            end
        end

        de:Draw(ds)
    end
end

-- Hotkey stuff for toggling vision range display. On/Off.
function ToggleVision(msg, keycode)
    if keycode ~= toggleVisionRangeHotkey and keycode ~= holdVisionRangeHotkey then return end
    if keycode == toggleVisionRangeHotkey and msg == KEY_UP then
        if toggleVisionRange then
            toggleVisionRange = false
            holding = false
            if animNotify then
                animPlayedTick = GetTick()
                ds:Get("notify"):RunAnimation("fadeinout",FADING,OPACITY,0,1,0.025,0)
                ds:Get("notify"):RunAnimation("slide",FADINGVELOCITY,POSITIONX,-70,70,6.8,0,0.955)
                ds.notify.objects[1].text = "BBWS Vision Range: OFF"
                ds.notify.objects[1].R = 1
                ds.notify.objects[1].G = 0
                ds.notify.objects[1].B = 0
            else
                PrintChat("<font color='#FF4500'> >> BBWS Vision Range: OFF</font>")
            end
        else
            toggleVisionRange = true
            holding = false
            if animNotify then
                animPlayedTick = GetTick()
                ds:Get("notify"):RunAnimation("fadeinout",FADING,OPACITY,0,1,0.025,0)
                ds:Get("notify"):RunAnimation("slide",FADINGVELOCITY,POSITIONX,-70,70,6.8,0,0.955)
                ds.notify.objects[1].text = "BBWS Vision Range: ON"
                ds.notify.objects[1].R = 0
                ds.notify.objects[1].G = 1
                ds.notify.objects[1].B = 0
            else
                PrintChat("<font color='#7CFC00'> >> BBWS Vision Range: ON</font>")
            end
        end
    end
    if keycode == holdVisionRangeHotkey then
        if msg == KEY_DOWN and not toggleVisionRange and not holding then
            toggleVisionRange = true
            holding = true
            if animNotify then 
                animPlayedTick = nil
                ds:Get("notify"):RunAnimation("fadeinout",FADING,OPACITY,0,1,0.025,0)
                ds:Get("notify"):RunAnimation("slide",FADINGVELOCITY,POSITIONX,-70,70,6.8,0,0.955)
                ds.notify.objects[1].text = "BBWS Vision Range: HOLD"
                ds.notify.objects[1].R = 0
                ds.notify.objects[1].G = 1
                ds.notify.objects[1].B = 0
            else
                PrintChat("<font color='#7CFC00'> >> BBWS Vision Range: ON</font>")
            end
        end
        if msg == KEY_UP and toggleVisionRange and holding then
            toggleVisionRange = false
            holding = false
            if animNotify then
                animPlayedTick = nil
                ds:Get("notify"):RunAnimation("fadeinout",FADING,OPACITY,1,0,0.015,0)
                ds:Get("notify"):RunAnimation("slide",FADING,POSITIONX,70,0,0.3,0)
            else
                PrintChat("<font color='#FF4500'> >> BBWS Vision Range: OFF</font>")
            end
        end
    end
end

function FormatTimerText( tick, duration, addTick )
        local timeleft = duration - (tick - addTick) / 1000
    local expirationtime = (addTick - STARTED_TICK) / 1000  + duration
        timeleft = math.max(0,timeleft)
    expirationtime = math.max(0,expirationtime)
        local seconds_tl = timeleft % 60;
        local minutes_tl = timeleft / 60;
        local seconds_et = expirationtime % 60;
        local minutes_et = expirationtime / 60;
        return string.format("%i:%02i",minutes_tl,seconds_tl), string.format("[%i:%02i]",minutes_et,seconds_et)
end

function Load()
    script.createObjectCallback = "AddWard"
    script.timerCallback = {"Timer",10}
    script.drawCallback = "WardDrawer"
    script.keyCallback = "ToggleVision"
    if loadScan == 1 then scanForCreatedWards() end
    PrintChat(" >> Breaking Bad Ward Scanner v3.1 loaded!")
end