-----------------------------------------------------------------------------------
-- CURSOR HELPERS -----------------------------------------------------------------
-----------------------------------------------------------------------------------

currentCursor = nil
-------------------------------------------------------------------------------

function SetObjectCursor(objName, curName)
    level = GetCurrentLevel()
    assert( level )
    
    level.custom_cursors[objName] = curName
end
-------------------------------------------------------------------------------

function SetCursor(cursor_name, ignoreMDB)
    if play_field and IsMouseBlocked() and not ignoreMDB then
        return
    end

    GetGameApp():SetCustomCursor(cursor_name)
    currentCursor = cursor_name
end
-------------------------------------------------------------------------------

function GetCursor()
    return currentCursor
end
-------------------------------------------------------------------------------

function RestoreCursor()
    local level      = GetCurrentLevel()
	local obj_punish = level.obj_punish
	
	if obj_punish and obj_punish:IsVisible() then
		obj_punish:SetVisible(false)
		obj_punish:DestroyChildren()
		--GetGameApp():SetCursorMode(CURSOR_MODE_CUSTOM)
		GetGameApp():SetTrackMouseNotOverWindow(true)
		MouseHolder:DestroyChildren()
		level.locker:Release()
		SetCursor('CursorDefault')
		
		if level.cur_eff_punish then
		    level.cur_eff_punish = nil
		end
		
		if level.restore_punish_timer then
			level.restore_punish_timer:Kill()
			level.restore_punish_timer = nil
		end
		
		if level.empty_cursor_timer then
		    level.empty_cursor_timer:Kill()
			level.empty_cursor_timer = nil
		end
	end
end
-------------------------------------------------------------------------------

function IsMouseBlocked()
	return GetCurrentLevel().mouseDownBlocked
end
-------------------------------------------------------------------------------

function SetMouseBlocked(state)
	GetCurrentLevel().mouseDownBlocked = state
end
-------------------------------------------------------------------------------

function BlockMouse(duration)
	assert(duration and type(duration) == 'number' and 'Please specify the duration of blocker')
	
	local level = GetCurrentLevel()
	
	level.mouseBlocker:Push()
	level.timer:Add(function() level.mouseBlocker:Pop() end, duration)
end
-------------------------------------------------------------------------------
function PunishPause()
    local level = GetCurrentLevel()
    
    if level.obj_punish then
        level.obj_punish:GetAnimation():Stop()
    end
    if level.cur_eff_punish then
        level.cur_eff_punish:Stop()
    end
    if level.restore_punish_timer then
        level.restore_punish_timer:Enabled(false)
    end
    if level.empty_cursor_timer then
        level.empty_cursor_timer:Enabled(false)
    end
end
-------------------------------------------------------------------------------
function PunishPlay()
    local level = GetCurrentLevel()
    
    if level.obj_punish then
        level.obj_punish:Go()
        SetCursor('CursorEmpty')
    end
    if level.cur_eff_punish then
        level.cur_eff_punish:Play()
    end
    if level.restore_punish_timer then
        level.restore_punish_timer:Enabled(true)
    end
    if level.empty_cursor_timer then
        level.empty_cursor_timer:Enabled(true)
    end
end
-------------------------------------------------------------------------------
function PunishClicking()
    local level = GetCurrentLevel()
    
    if GM:GetShowCustomCursor() then
        if level.obj_punish == nil then
	        local anim = CreateAnimation('data/Texture/GUI/Cursor_Punish/cursor_punish.png',0,0,120,120,24,18)
            anim:SetHotSpot(60,60)
            anim:SetBlendMode(2)
            anim:SetColor('0xFFFFFFFF')
            anim:SetMode(HGEANIM_FWD + HGEANIM_PINGPONG)
            level.obj_punish = play_field:GetLevelScreen():CreateObject('cursor_punish',anim,512,384,1000,0,1,1)
            level.obj_punish:SetVisible(false)
	        level.obj_punish:SetLayer(1000)
        end
        
        local obj_punish = level.obj_punish
        if not obj_punish:IsVisible() then
            local duration_anim = 2 * GetAnimationLength( obj_punish:GetAnimation() ) --obj_punish:GetDuration()
            
            SetCursor('CursorEmpty')
            level.locker:AddRef()
            
            local curMouseX  = MouseHolder:GetX()
            local curMouseY  = MouseHolder:GetY()
            local anim_cursor = GetAnimation('CursorDefault')
            local hot_x = 18
            local hot_y = 20
            
            obj_punish:SetVisible(true)
            obj_punish:GetAnimation():Play()
            obj_punish:SetScrXY(curMouseX + hot_x, curMouseY + hot_y)
            
            local effector = CreateAnimationEffector();
            effector:AttachTo( obj_punish )	
            effector:SetDestroysOnEnd(true)
            effector:SetKey(_TRACK_SX, 0, 1);
            effector:SetKey(_TRACK_SY, 0, 1);
            effector:SetKey(_TRACK_SX, duration_anim/2, 1.5);
            effector:SetKey(_TRACK_SY, duration_anim/2, 1.5);
            effector:SetKey(_TRACK_SX, duration_anim, 1);
            effector:SetKey(_TRACK_SY, duration_anim, 1);
            effector:Play();
            
            local obj_punish_x = obj_punish:GetScrX()
            local obj_punish_y = obj_punish:GetScrY()

            level.empty_cursor_timer = level.timer:Add(function()
                                                            SetCursor('CursorEmpty')
                                                       end, 0, true)
            
            GetGameApp():SetTrackMouseNotOverWindow(false)
            level.restore_punish_timer = level.timer:Add(function()
                                                            RestoreCursor()
                                                         end, duration_anim)
        end
    else
        local duration_anim = 1.5
        level.mouseBlocker:Push()
        level.restore_punish_timer = level.timer:Add(function()
                            level.mouseBlocker:Pop()
                            
                            if level.cur_eff_punish then
                                level.cur_eff_punish = nil
                            end
                            level.restore_punish_timer = nil
                        end, duration_anim)
    
        local curMouseX = MouseHolder:GetX()
        local curMouseY = MouseHolder:GetY()
        local endMouseX = 0
        local endMouseY = 0
        
        if curMouseX < 512 then
            endMouseX = math.random(600, 900)
        else
            endMouseX = math.random(100, 500)
        end
        
        if curMouseY < 384 then
            endMouseY = math.random(450, 668)
        else
            endMouseY = math.random(100, 300)
        end    
        
        local eff = BuildCursorTrajectory(curMouseX, curMouseY, endMouseX, endMouseY)
        eff:AttachTo(MouseHolder)
        eff:Play()
        
        level.cur_eff_punish = eff
    end
    
    if not level.sound_MousePunish then
        level.sound_MousePunish = MakeSoundEntity('MousePunish')
    end
    level.sound_MousePunish:PlaySound(false)
end
-------------------------------------------------------------------------------

function RestorePunishClicking()
    if GM:GetShowCustomCursor() then
        MouseHolder:DestroyChildren()
        GetCurrentLevel().obj_punish:SetVisible(false)

        if GM:GetShowCustomCursor() then
            GetGameApp():SetCursorMode(CURSOR_MODE_CUSTOM)
        end
        local bTrackMouseNotOverWindow = GetGameApp():GetTrackMouseNotOverWindow()
        GetGameApp():SetTrackMouseNotOverWindow(true)

        SetCursor('CursorDefault')
    end
end
-------------------------------------------------------------------------------

function BuildCursorTrajectory(xStart, yStart, xEnd, yEnd)

    local slideUp = function(effector, xOffset, yOffset)
    
        effector:SetKey(_TRACK_X, 0, -9.03971612625702 + xOffset);
        effector:SetKey(_TRACK_Y, 0, -1.087678110588 + yOffset);
        effector:SetKey(_TRACK_X, 0.1, -35.918712415678 + xOffset);
        effector:SetKey(_TRACK_Y, 0.1, -16.35894329572 + yOffset);
        effector:SetKey(_TRACK_X, 0.2, -54.778451206019 + xOffset);
        effector:SetKey(_TRACK_Y, 0.2, -43.08024698882 + yOffset);
        effector:SetKey(_TRACK_X, 0.3, -55.000616747998 + xOffset);
        effector:SetKey(_TRACK_Y, 0.3, -74.294729726322 + yOffset);
        effector:SetKey(_TRACK_X, 0.4, -39.31565486476 + xOffset);
        effector:SetKey(_TRACK_Y, 0.4, -100.419120425399 + yOffset);
        effector:SetKey(_TRACK_X, 0.5, -12.016902848862 + xOffset);
        effector:SetKey(_TRACK_Y, 0.5, -116.980770282281 + yOffset);
        effector:SetKey(_TRACK_X, 0.6, 20.377160021529 + xOffset);
        effector:SetKey(_TRACK_Y, 0.6, -124.538072231797 + yOffset);
        effector:SetKey(_TRACK_X, 0.64, 32.705230134861 + xOffset);
        effector:SetKey(_TRACK_Y, 0.64, -125.99738170922 + yOffset);
        effector:SetKey(_TRACK_X, 0.7, 57.067546766499 + xOffset);
        effector:SetKey(_TRACK_Y, 0.7, -133.883052413855 + yOffset);
        effector:SetKey(_TRACK_X, 0.8, 66.5737743546611 + xOffset);
        effector:SetKey(_TRACK_Y, 0.8, -175.427790836715 + yOffset);
        effector:SetKey(_TRACK_X, 0.84, 56.575004743915 + xOffset);
        effector:SetKey(_TRACK_Y, 0.84, -190.035905964726 + yOffset);
        effector:SetKey(_TRACK_X, 0.9, 32.795787661179 + xOffset);
        effector:SetKey(_TRACK_Y, 0.9, -199.955445026108 + yOffset);
        effector:SetKey(_TRACK_X, 0.96, 12.49305740035 + xOffset);
        effector:SetKey(_TRACK_Y, 0.96, -184.716271154549 + yOffset);
        effector:SetKey(_TRACK_X, 1, 10.519410621768 + xOffset);
        effector:SetKey(_TRACK_Y, 1, -159.032257687091 + yOffset);
        effector:SetKey(_TRACK_X, 1.08, 56.9288506105451 + xOffset);
        effector:SetKey(_TRACK_Y, 1.08, -154.162446362942 + yOffset);
        effector:SetKey(_TRACK_X, 1.1, 66.220540453102 + xOffset);
        effector:SetKey(_TRACK_Y, 1.1, -163.53247458599 + yOffset);
        effector:SetKey(_TRACK_X, 1.16, 74.362822516088 + xOffset);
        effector:SetKey(_TRACK_Y, 1.16, -201.523985031131 + yOffset);
        effector:SetKey(_TRACK_X, 1.2, 71.8900018406169 + xOffset);
        effector:SetKey(_TRACK_Y, 1.2, -217.849626297959 + yOffset);
        effector:SetKey(_TRACK_X, 1.3, 55.310854730489 + xOffset);
        effector:SetKey(_TRACK_Y, 1.3, -255.024304284269 + yOffset);
        effector:SetKey(_TRACK_X, 1.4, 22.532603990254 + xOffset);
        effector:SetKey(_TRACK_Y, 1.4, -283.324869591707 + yOffset);
        effector:SetKey(_TRACK_X, 1.5, -15.771970680188 + xOffset);
        effector:SetKey(_TRACK_Y, 1.5, -294.170972215229 + yOffset);
        effector:SetKey(_TRACK_X, 1.52, -24.881895883868 + xOffset);
        effector:SetKey(_TRACK_Y, 1.52, -294.069968892219 + yOffset);
    
    end
    
    local slideDown = function(effector, xOffset, yOffset)
    
        effector:SetKey(_TRACK_X, 0, 8.99022554700105 + xOffset);
        effector:SetKey(_TRACK_Y, 0, 1.440609568767 + yOffset);
        effector:SetKey(_TRACK_X, 0.1, 36.028422765841 + xOffset);
        effector:SetKey(_TRACK_Y, 0.1, 18.546055327201 + yOffset);
        effector:SetKey(_TRACK_X, 0.2, 51.758827942341 + xOffset);
        effector:SetKey(_TRACK_Y, 0.2, 43.721848202421 + yOffset);
        effector:SetKey(_TRACK_X, 0.3, 51.9543208104041 + xOffset);
        effector:SetKey(_TRACK_Y, 0.3, 76.802873825099 + yOffset);
        effector:SetKey(_TRACK_X, 0.4, 33.915009259882 + xOffset);
        effector:SetKey(_TRACK_Y, 0.4, 102.236925113631 + yOffset);
        effector:SetKey(_TRACK_X, 0.5, 7.33533202798401 + xOffset);
        effector:SetKey(_TRACK_Y, 0.5, 115.800608694381 + yOffset);
        effector:SetKey(_TRACK_X, 0.64, -37.038108729105 + xOffset);
        effector:SetKey(_TRACK_Y, 0.64, 126.154512958838 + yOffset);
        effector:SetKey(_TRACK_X, 0.7, -61.603725710543 + xOffset);
        effector:SetKey(_TRACK_Y, 0.7, 133.014340473786 + yOffset);
        effector:SetKey(_TRACK_X, 0.8, -72.292546397039 + xOffset);
        effector:SetKey(_TRACK_Y, 0.8, 172.63010834575 + yOffset);
        effector:SetKey(_TRACK_X, 0.9, -41.560214157488 + xOffset);
        effector:SetKey(_TRACK_Y, 0.9, 198.041347119345 + yOffset);
        effector:SetKey(_TRACK_X, 0.96, -19.594656236159 + xOffset);
        effector:SetKey(_TRACK_Y, 0.96, 184.30996732763 + yOffset);
        effector:SetKey(_TRACK_X, 1, -15.60402572249 + xOffset);
        effector:SetKey(_TRACK_Y, 1, 158.78166758374 + yOffset);
        effector:SetKey(_TRACK_X, 1.04, -37.486530373706 + xOffset);
        effector:SetKey(_TRACK_Y, 1.04, 144.937110593006 + yOffset);
        effector:SetKey(_TRACK_X, 1.08, -63.902383098331 + xOffset);
        effector:SetKey(_TRACK_Y, 1.08, 151.970715345113 + yOffset);
        effector:SetKey(_TRACK_X, 1.1, -74.10574428385 + xOffset);
        effector:SetKey(_TRACK_Y, 1.1, 160.794966324392 + yOffset);
        effector:SetKey(_TRACK_X, 1.16, -82.512748440206 + xOffset);
        effector:SetKey(_TRACK_Y, 1.16, 199.149385725767 + yOffset);
        effector:SetKey(_TRACK_X, 1.2, -80.46989609807 + xOffset);
        effector:SetKey(_TRACK_Y, 1.2, 215.163812384836 + yOffset);
        effector:SetKey(_TRACK_X, 1.3, -64.751154318798 + xOffset);
        effector:SetKey(_TRACK_Y, 1.3, 252.943713674407 + yOffset);
        effector:SetKey(_TRACK_X, 1.4, -34.445818163542 + xOffset);
        effector:SetKey(_TRACK_Y, 1.4, 281.398356615652 + yOffset);
        effector:SetKey(_TRACK_X, 1.5, 4.97390287573 + xOffset);
        effector:SetKey(_TRACK_Y, 1.5, 294.95593311782 + yOffset);
        effector:SetKey(_TRACK_X, 1.52, 13.354557206115 + xOffset);
        effector:SetKey(_TRACK_Y, 1.52, 294.818437599949 + yOffset);
    
    end
    
    local slideLeft = function(effector, xOffset, yOffset)
    
        effector:SetKey(_TRACK_X, 0, -3.06837694027701 + xOffset);
        effector:SetKey(_TRACK_Y, 0, 8.57231440557001 + yOffset);
        effector:SetKey(_TRACK_X, 0.1, -23.346525897375 + xOffset);
        effector:SetKey(_TRACK_Y, 0.1, 32.144703004253 + yOffset);
        effector:SetKey(_TRACK_X, 0.2, -54.361318185972 + xOffset);
        effector:SetKey(_TRACK_Y, 0.2, 43.159717344779 + yOffset);
        effector:SetKey(_TRACK_X, 0.3, -85.058067013573 + xOffset);
        effector:SetKey(_TRACK_Y, 0.3, 37.60679539729 + yOffset);
        effector:SetKey(_TRACK_X, 0.4, -106.335384420515 + xOffset);
        effector:SetKey(_TRACK_Y, 0.4, 14.820133685241 + yOffset);
        effector:SetKey(_TRACK_X, 0.5, -115.194379016148 + xOffset);
        effector:SetKey(_TRACK_Y, 0.5, -15.332627175341 + yOffset);
        effector:SetKey(_TRACK_X, 0.6, -117.88602018778 + xOffset);
        effector:SetKey(_TRACK_Y, 0.6, -47.315762254909 + yOffset);
        effector:SetKey(_TRACK_X, 0.64, -116.312229914534 + xOffset);
        effector:SetKey(_TRACK_Y, 0.64, -59.897253236076 + yOffset);
        effector:SetKey(_TRACK_X, 0.7, -118.47198148653 + xOffset);
        effector:SetKey(_TRACK_Y, 0.7, -86.482669655594 + yOffset);
        effector:SetKey(_TRACK_X, 0.8, -155.532039146131 + xOffset);
        effector:SetKey(_TRACK_Y, 0.8, -102.972016204771 + yOffset);
        effector:SetKey(_TRACK_X, 0.9, -187.582449794214 + xOffset);
        effector:SetKey(_TRACK_Y, 0.9, -77.051565465185 + yOffset);
        effector:SetKey(_TRACK_X, 0.96, -176.53605962583 + xOffset);
        effector:SetKey(_TRACK_Y, 0.96, -53.610245311822 + yOffset);
        effector:SetKey(_TRACK_X, 1, -152.025122527427 + xOffset);
        effector:SetKey(_TRACK_Y, 1, -45.378799658591 + yOffset);
        effector:SetKey(_TRACK_X, 1.04, -135.591531392891 + xOffset);
        effector:SetKey(_TRACK_Y, 1.04, -64.107242004553 + yOffset);
        effector:SetKey(_TRACK_X, 1.1, -144.854670589658 + xOffset);
        effector:SetKey(_TRACK_Y, 1.1, -100.882751703786 + yOffset);
        effector:SetKey(_TRACK_X, 1.16, -179.705901494543 + xOffset);
        effector:SetKey(_TRACK_Y, 1.16, -117.376804892983 + yOffset);
        effector:SetKey(_TRACK_X, 1.2, -195.991388208058 + xOffset);
        effector:SetKey(_TRACK_Y, 1.2, -119.037704339714 + yOffset);
        effector:SetKey(_TRACK_X, 1.3, -237.468652981892 + xOffset);
        effector:SetKey(_TRACK_Y, 1.3, -110.138710052294 + yOffset);
        effector:SetKey(_TRACK_X, 1.4, -270.465486425857 + xOffset);
        effector:SetKey(_TRACK_Y, 1.4, -85.591244310499 + yOffset);
        effector:SetKey(_TRACK_X, 1.48, -287.882403730511 + xOffset);
        effector:SetKey(_TRACK_Y, 1.48, -56.528686104181 + yOffset);
        effector:SetKey(_TRACK_X, 1.52, -292.250825767185 + xOffset);
        effector:SetKey(_TRACK_Y, 1.52, -41.057401104364 + yOffset);
    
    end
    
    local slideRight = function(effector, xOffset, yOffset)
    
        effector:SetKey(_TRACK_X, 0, 0.88200225637797 + xOffset);
        effector:SetKey(_TRACK_Y, 0, -9.06209596811402 + yOffset);
        effector:SetKey(_TRACK_X, 0.1, 16.432153162213 + xOffset);
        effector:SetKey(_TRACK_Y, 0.1, -36.143623431779 + yOffset);
        effector:SetKey(_TRACK_X, 0.2, 40.391332829886 + xOffset);
        effector:SetKey(_TRACK_Y, 0.2, -54.169515400461 + yOffset);
        effector:SetKey(_TRACK_X, 0.3, 73.1795266975751 + xOffset);
        effector:SetKey(_TRACK_Y, 0.3, -56.593508936083 + yOffset);
        effector:SetKey(_TRACK_X, 0.4, 99.381135117946 + xOffset);
        effector:SetKey(_TRACK_Y, 0.4, -40.411261798199 + yOffset);
        effector:SetKey(_TRACK_X, 0.5, 116.400912290091 + xOffset);
        effector:SetKey(_TRACK_Y, 0.5, -13.495503170807 + yOffset);
        effector:SetKey(_TRACK_X, 0.6, 125.467187337876 + xOffset);
        effector:SetKey(_TRACK_Y, 0.6, 17.529095252879 + yOffset);
        effector:SetKey(_TRACK_X, 0.64, 126.963398402066 + xOffset);
        effector:SetKey(_TRACK_Y, 0.64, 29.822352312656 + yOffset);
        effector:SetKey(_TRACK_X, 0.7, 135.446975376384 + xOffset);
        effector:SetKey(_TRACK_Y, 0.7, 53.734010824257 + yOffset);
        effector:SetKey(_TRACK_X, 0.8, 176.388552559478 + xOffset);
        effector:SetKey(_TRACK_Y, 0.8, 61.712341013617 + yOffset);
        effector:SetKey(_TRACK_X, 0.9, 200.281768985106 + xOffset);
        effector:SetKey(_TRACK_Y, 0.9, 27.685499556685 + yOffset);
        effector:SetKey(_TRACK_X, 0.96, 185.037680472858 + xOffset);
        effector:SetKey(_TRACK_Y, 0.96, 7.03477903415001 + yOffset);
        effector:SetKey(_TRACK_X, 1, 159.900757162837 + xOffset);
        effector:SetKey(_TRACK_Y, 1, 5.69631590068298 + yOffset);
        effector:SetKey(_TRACK_X, 1.04, 146.758894186318 + xOffset);
        effector:SetKey(_TRACK_Y, 1.04, 28.162986476394 + yOffset);
        effector:SetKey(_TRACK_X, 1.08, 153.622706639899 + xOffset);
        effector:SetKey(_TRACK_Y, 1.08, 53.681054986025 + yOffset);
        effector:SetKey(_TRACK_X, 1.1, 163.345076132253 + xOffset);
        effector:SetKey(_TRACK_Y, 1.1, 62.797052901032 + yOffset);
        effector:SetKey(_TRACK_X, 1.16, 202.535815934466 + xOffset);
        effector:SetKey(_TRACK_Y, 1.16, 70.764580548227 + yOffset);
        effector:SetKey(_TRACK_X, 1.2, 219.72382370528 + xOffset);
        effector:SetKey(_TRACK_Y, 1.2, 67.615435689413 + yOffset);
        effector:SetKey(_TRACK_X, 1.3, 257.503976005262 + xOffset);
        effector:SetKey(_TRACK_Y, 1.3, 49.245546043275 + yOffset);
        effector:SetKey(_TRACK_X, 1.4, 283.967626310547 + xOffset);
        effector:SetKey(_TRACK_Y, 1.4, 16.081599360911 + yOffset);
        effector:SetKey(_TRACK_X, 1.5, 294.221432444228 + xOffset);
        effector:SetKey(_TRACK_Y, 1.5, -22.82599589568 + yOffset);
        effector:SetKey(_TRACK_X, 1.52, 293.428698836615 + xOffset);
        effector:SetKey(_TRACK_Y, 1.52, -31.557155228207 + yOffset);
    
    end
    
    local slideRightUp = function(effector, xOffset, yOffset)
    
        effector:SetKey(_TRACK_X, 0, -5.62294000513299 + xOffset);
        effector:SetKey(_TRACK_Y, 0, -7.16114914062302 + yOffset);
        effector:SetKey(_TRACK_X, 0.1, -13.830845383165 + xOffset);
        effector:SetKey(_TRACK_Y, 0.1, -36.965884858066 + yOffset);
        effector:SetKey(_TRACK_X, 0.2, -8.271879529687 + xOffset);
        effector:SetKey(_TRACK_Y, 0.2, -69.196549091659 + yOffset);
        effector:SetKey(_TRACK_X, 0.3, 13.642998123952 + xOffset);
        effector:SetKey(_TRACK_Y, 0.3, -91.425616267855 + yOffset);
        effector:SetKey(_TRACK_X, 0.4, 43.206674851926 + xOffset);
        effector:SetKey(_TRACK_Y, 0.4, -98.80740717525 + yOffset);
        effector:SetKey(_TRACK_X, 0.5, 74.220662441736 + xOffset);
        effector:SetKey(_TRACK_Y, 0.5, -91.215129428317 + yOffset);
        effector:SetKey(_TRACK_X, 0.6, 102.47054342355 + xOffset);
        effector:SetKey(_TRACK_Y, 0.6, -73.652887358457 + yOffset);
        effector:SetKey(_TRACK_X, 0.64, 112.219693026967 + xOffset);
        effector:SetKey(_TRACK_Y, 0.64, -65.967513009712 + yOffset);
        effector:SetKey(_TRACK_X, 0.7, 135.022463552062 + xOffset);
        effector:SetKey(_TRACK_Y, 0.7, -54.316764943519 + yOffset);
        effector:SetKey(_TRACK_X, 0.8, 171.120947804581 + xOffset);
        effector:SetKey(_TRACK_Y, 0.8, -76.971413213853 + yOffset);
        effector:SetKey(_TRACK_X, 0.84, 174.38024727667 + xOffset);
        effector:SetKey(_TRACK_Y, 0.84, -94.371108276504 + yOffset);
        effector:SetKey(_TRACK_X, 0.9, 164.579974962709 + xOffset);
        effector:SetKey(_TRACK_Y, 0.9, -118.199727263561 + yOffset);
        effector:SetKey(_TRACK_X, 0.96, 139.448053534415 + xOffset);
        effector:SetKey(_TRACK_Y, 0.96, -121.780202323334 + yOffset);
        effector:SetKey(_TRACK_X, 1, 119.891134422686 + xOffset);
        effector:SetKey(_TRACK_Y, 1, -105.014441253211 + yOffset);
        effector:SetKey(_TRACK_X, 1.08, 149.264087539416 + xOffset);
        effector:SetKey(_TRACK_Y, 1.08, -68.754534915671 + yOffset);
        effector:SetKey(_TRACK_X, 1.1, 162.459914932197 + xOffset);
        effector:SetKey(_TRACK_Y, 1.1, -68.809928515744 + yOffset);
        effector:SetKey(_TRACK_X, 1.16, 195.081432456547 + xOffset);
        effector:SetKey(_TRACK_Y, 1.16, -89.916520317952 + yOffset);
        effector:SetKey(_TRACK_X, 1.2, 204.876855835255 + xOffset);
        effector:SetKey(_TRACK_Y, 1.2, -103.209040233228 + yOffset);
        effector:SetKey(_TRACK_X, 1.3, 219.440095379941 + xOffset);
        effector:SetKey(_TRACK_Y, 1.3, -141.218734473635 + yOffset);
        effector:SetKey(_TRACK_X, 1.4, 216.273893646389 + xOffset);
        effector:SetKey(_TRACK_Y, 1.4, -184.407979487791 + yOffset);
        effector:SetKey(_TRACK_X, 1.5, 196.857821860992 + xOffset);
        effector:SetKey(_TRACK_Y, 1.5, -219.162756702264 + yOffset);
        effector:SetKey(_TRACK_X, 1.52, 190.344711838745 + xOffset);
        effector:SetKey(_TRACK_Y, 1.52, -225.533026455266 + yOffset);
    
    end
    
    local slideRightDown = function(effector, xOffset, yOffset)
    
        effector:SetKey(_TRACK_X, 0, 7.03153928732297 + xOffset);
        effector:SetKey(_TRACK_Y, 0, -5.78419973430999 + yOffset);
        effector:SetKey(_TRACK_X, 0.1, 37.176688155761 + xOffset);
        effector:SetKey(_TRACK_Y, 0.1, -13.938114294767 + yOffset);
        effector:SetKey(_TRACK_X, 0.2, 66.86461701843 + xOffset);
        effector:SetKey(_TRACK_Y, 0.2, -9.74264632807899 + yOffset);
        effector:SetKey(_TRACK_X, 0.3, 91.7633935117231 + xOffset);
        effector:SetKey(_TRACK_Y, 0.3, 11.728085632032 + yOffset);
        effector:SetKey(_TRACK_X, 0.4, 98.848151817728 + xOffset);
        effector:SetKey(_TRACK_Y, 0.4, 41.697997310104 + yOffset);
        effector:SetKey(_TRACK_X, 0.5, 91.850636224226 + xOffset);
        effector:SetKey(_TRACK_Y, 0.5, 72.765112609022 + yOffset);
        effector:SetKey(_TRACK_X, 0.6, 76.32375686164 + xOffset);
        effector:SetKey(_TRACK_Y, 0.6, 101.113641104391 + yOffset);
        effector:SetKey(_TRACK_X, 0.64, 68.689092421376 + xOffset);
        effector:SetKey(_TRACK_Y, 0.64, 110.864267523804 + yOffset);
        effector:SetKey(_TRACK_X, 0.7, 57.779791345664 + xOffset);
        effector:SetKey(_TRACK_Y, 0.7, 133.771158214032 + yOffset);
        effector:SetKey(_TRACK_X, 0.8, 81.088326824861 + xOffset);
        effector:SetKey(_TRACK_Y, 0.8, 168.362756452112 + yOffset);
        effector:SetKey(_TRACK_X, 0.9, 122.043992520337 + xOffset);
        effector:SetKey(_TRACK_Y, 0.9, 161.197201474475 + yOffset);
        effector:SetKey(_TRACK_X, 0.96, 125.867058678191 + xOffset);
        effector:SetKey(_TRACK_Y, 0.96, 135.815738596584 + yOffset);
        effector:SetKey(_TRACK_X, 1, 109.039006105551 + xOffset);
        effector:SetKey(_TRACK_Y, 1, 117.094813307859 + yOffset);
        effector:SetKey(_TRACK_X, 1.04, 83.859970562661 + xOffset);
        effector:SetKey(_TRACK_Y, 1.04, 123.688447994507 + yOffset);
        effector:SetKey(_TRACK_X, 1.08, 70.669419607438 + xOffset);
        effector:SetKey(_TRACK_Y, 1.08, 146.58589561117 + yOffset);
        effector:SetKey(_TRACK_X, 1.1, 71.098189061699 + xOffset);
        effector:SetKey(_TRACK_Y, 1.1, 159.9066329514 + yOffset);
        effector:SetKey(_TRACK_X, 1.16, 93.176334106938 + xOffset);
        effector:SetKey(_TRACK_Y, 1.16, 193.252563653885 + yOffset);
        effector:SetKey(_TRACK_X, 1.2, 107.556872641374 + xOffset);
        effector:SetKey(_TRACK_Y, 1.2, 203.179538819108 + yOffset);
        effector:SetKey(_TRACK_X, 1.3, 147.260948065385 + xOffset);
        effector:SetKey(_TRACK_Y, 1.3, 216.904667166253 + yOffset);
        effector:SetKey(_TRACK_X, 1.4, 189.424026241209 + xOffset);
        effector:SetKey(_TRACK_Y, 1.4, 212.166842162061 + yOffset);
        effector:SetKey(_TRACK_X, 1.5, 224.186386536905 + xOffset);
        effector:SetKey(_TRACK_Y, 1.5, 191.905553566562 + yOffset);
        effector:SetKey(_TRACK_X, 1.52, 229.799701198938 + xOffset);
        effector:SetKey(_TRACK_Y, 1.52, 185.171144285294 + yOffset);
    
    end
    
    local slideLeftUp = function(effector, xOffset, yOffset)
    
        effector:SetKey(_TRACK_X, 0, -8.23121178834799 + xOffset);
        effector:SetKey(_TRACK_Y, 0, 3.89187150493598 + yOffset);
        effector:SetKey(_TRACK_X, 0.1, -39.238224252716 + xOffset);
        effector:SetKey(_TRACK_Y, 0.1, 6.22125069435299 + yOffset);
        effector:SetKey(_TRACK_X, 0.2, -68.957785532129 + xOffset);
        effector:SetKey(_TRACK_Y, 0.2, -7.92072791495298 + yOffset);
        effector:SetKey(_TRACK_X, 0.3, -86.737156024036 + xOffset);
        effector:SetKey(_TRACK_Y, 0.3, -33.553115935798 + yOffset);
        effector:SetKey(_TRACK_X, 0.4, -85.66988843075 + xOffset);
        effector:SetKey(_TRACK_Y, 0.4, -64.711054376899 + yOffset);
        effector:SetKey(_TRACK_X, 0.5, -70.612921907803 + xOffset);
        effector:SetKey(_TRACK_Y, 0.5, -92.29653120598 + yOffset);
        effector:SetKey(_TRACK_X, 0.6, -49.900707934417 + xOffset);
        effector:SetKey(_TRACK_Y, 0.6, -116.81530062933 + yOffset);
        effector:SetKey(_TRACK_X, 0.64, -39.891412569818 + xOffset);
        effector:SetKey(_TRACK_Y, 0.64, -124.598920445173 + yOffset);
        effector:SetKey(_TRACK_X, 0.7, -22.619859321146 + xOffset);
        effector:SetKey(_TRACK_Y, 0.7, -144.924823658319 + yOffset);
        effector:SetKey(_TRACK_X, 0.8, -37.165548641156 + xOffset);
        effector:SetKey(_TRACK_Y, 0.8, -182.789970502846 + yOffset);
        effector:SetKey(_TRACK_X, 0.9, -78.157137839603 + xOffset);
        effector:SetKey(_TRACK_Y, 0.9, -187.124506722545 + yOffset);
        effector:SetKey(_TRACK_X, 0.96, -86.921676884314 + xOffset);
        effector:SetKey(_TRACK_Y, 0.96, -162.73801288644 + yOffset);
        effector:SetKey(_TRACK_X, 1, -75.410338089164 + xOffset);
        effector:SetKey(_TRACK_Y, 1, -139.585652010555 + yOffset);
        effector:SetKey(_TRACK_X, 1.04, -50.547025774795 + xOffset);
        effector:SetKey(_TRACK_Y, 1.04, -141.208356863968 + yOffset);
        effector:SetKey(_TRACK_X, 1.1, -31.092842025985 + xOffset);
        effector:SetKey(_TRACK_Y, 1.1, -173.762597694997 + yOffset);
        effector:SetKey(_TRACK_X, 1.16, -44.073326872195 + xOffset);
        effector:SetKey(_TRACK_Y, 1.16, -210.069196259872 + yOffset);
        effector:SetKey(_TRACK_X, 1.2, -54.414471700592 + xOffset);
        effector:SetKey(_TRACK_Y, 1.2, -222.759207611574 + yOffset);
        effector:SetKey(_TRACK_X, 1.3, -90.035866093615 + xOffset);
        effector:SetKey(_TRACK_Y, 1.3, -245.795523591847 + yOffset);
        effector:SetKey(_TRACK_X, 1.4, -130.725830266494 + xOffset);
        effector:SetKey(_TRACK_Y, 1.4, -251.77012879079 + yOffset);
        effector:SetKey(_TRACK_X, 1.48, -163.591782586296 + xOffset);
        effector:SetKey(_TRACK_Y, 1.48, -243.53541713796 + yOffset);
        effector:SetKey(_TRACK_X, 1.52, -177.620573968553 + xOffset);
        effector:SetKey(_TRACK_Y, 1.52, -235.684507446136 + yOffset);
    
    end
    
    local slideLeftDown = function(effector, xOffset, yOffset)
    
        effector:SetKey(_TRACK_X, 0, 5.33838465356303 + xOffset);
        effector:SetKey(_TRACK_Y, 0, 7.37571424379797 + yOffset);
        effector:SetKey(_TRACK_X, 0.1, 12.361900567057 + xOffset);
        effector:SetKey(_TRACK_Y, 0.1, 38.589983539307 + yOffset);
        effector:SetKey(_TRACK_X, 0.2, 5.68300287435704 + xOffset);
        effector:SetKey(_TRACK_Y, 0.2, 67.515033574238 + yOffset);
        effector:SetKey(_TRACK_X, 0.3, -17.570580339365 + xOffset);
        effector:SetKey(_TRACK_Y, 0.3, 91.045085453321 + yOffset);
        effector:SetKey(_TRACK_X, 0.4, -48.310890003843 + xOffset);
        effector:SetKey(_TRACK_Y, 0.4, 96.273956067177 + yOffset);
        effector:SetKey(_TRACK_X, 0.5, -76.696532654084 + xOffset);
        effector:SetKey(_TRACK_Y, 0.5, 87.070258692569 + yOffset);
        effector:SetKey(_TRACK_X, 0.64, -115.394609435155 + xOffset);
        effector:SetKey(_TRACK_Y, 0.64, 63.014813745806 + yOffset);
        effector:SetKey(_TRACK_X, 0.7, -137.615754340351 + xOffset);
        effector:SetKey(_TRACK_Y, 0.7, 50.494929947789 + yOffset);
        effector:SetKey(_TRACK_X, 0.8, -173.186470034838 + xOffset);
        effector:SetKey(_TRACK_Y, 0.8, 70.949370461659 + yOffset);
        effector:SetKey(_TRACK_X, 0.9, -169.423888761733 + xOffset);
        effector:SetKey(_TRACK_Y, 0.9, 110.648870245083 + yOffset);
        effector:SetKey(_TRACK_X, 0.96, -144.182342037245 + xOffset);
        effector:SetKey(_TRACK_Y, 0.96, 116.47131343803 + yOffset);
        effector:SetKey(_TRACK_X, 1, -123.309306278753 + xOffset);
        effector:SetKey(_TRACK_Y, 1, 101.241881474389 + yOffset);
        effector:SetKey(_TRACK_X, 1.04, -128.992993576302 + xOffset);
        effector:SetKey(_TRACK_Y, 1.04, 75.979033915497 + yOffset);
        effector:SetKey(_TRACK_X, 1.08, -152.64533178511 + xOffset);
        effector:SetKey(_TRACK_Y, 1.08, 62.273714939489 + yOffset);
        effector:SetKey(_TRACK_X, 1.1, -166.099885376626 + xOffset);
        effector:SetKey(_TRACK_Y, 1.1, 61.298536760653 + yOffset);
        effector:SetKey(_TRACK_X, 1.16, -199.165205072234 + xOffset);
        effector:SetKey(_TRACK_Y, 1.16, 82.474557159416 + yOffset);
        effector:SetKey(_TRACK_X, 1.2, -209.04460001559 + xOffset);
        effector:SetKey(_TRACK_Y, 1.2, 95.242981590946 + yOffset);
        effector:SetKey(_TRACK_X, 1.3, -224.64419550616 + xOffset);
        effector:SetKey(_TRACK_Y, 1.3, 133.072234889203 + yOffset);
        effector:SetKey(_TRACK_X, 1.4, -223.335557784637 + xOffset);
        effector:SetKey(_TRACK_Y, 1.4, 174.621814570719 + yOffset);
        effector:SetKey(_TRACK_X, 1.5, -205.048260006424 + xOffset);
        effector:SetKey(_TRACK_Y, 1.5, 212.082420911209 + yOffset);
        effector:SetKey(_TRACK_X, 1.52, -199.025018485559 + xOffset);
        effector:SetKey(_TRACK_Y, 1.52, 217.911214405935 + yOffset);
    
    end
    
    local functor = slideDown;
    
    if (xStart < 400)
    then
    
        if (yStart < 300)
        then
            functor = slideRightDown;
        elseif (yStart > 500)
        then
            functor = slideRightUp;
        else
            functor = slideRight;
        end
    
    elseif (xStart > 750)
    then
    
        if (yStart < 300)
        then
            functor = slideLeftDown;
        elseif (yStart > 500)
        then
            functor = slideLeftUp;
        else
            functor = slideLeft;
        end
    
    else
    
        if (yStart < 350)
        then
            functor = slideDown;
        else
            functor = slideUp;        
        end
    
    end
    
    local effector = CreateAnimationEffector();
    effector:SetDestroysOnEnd(true)
    functor(effector, xStart, yStart)
    return effector;
    
end