12

» WarCraft 3 / Читы

Принятый ответ
ReloadGameCachesFromDisk() возвращает true если игра запущена в режиме одиночной игры, можно написать "Игра в режиме одиночной игры не возможно, используйте режим Локальной сети" и вызвать вылет или окно вы проиграли. При этом проблем не возникнет при запуске в локальном режиме одному, работает на 1.26
И можно забыть про читы
12

» WarCraft 3 / [2.0.3 vJass] UI - Move Able Frame - Перетаскиваем фрейм мышкой

Makeba, Обычный плавный таймер, обычно не утекает, но в данном кейсе (Видимо много действий) утекает
Он срабатывает для того, что после прекращения движения(Клик ПКМ), если дистанция далека от конечной точки(Клика ПКМ), через 0.015 сек (Уж точно получить координаты корректные, ведь событие срабатывает не чаще примерно чем раз в 0.15сек) прибыть в нужную точку. Компенсация грубо говоря координат, но конкретно этот участок вызывает десинхрон в Мультиплеере, поэтому я ввёл константу DRAG_TIMER_ENABLE, чтоб кому нужно отключили таймеры
12

» WarCraft 3 / [2.0.0] Как кодом заставить нажать на скил с целью, но без применения

Makeba, Если дать способность и вызвать твой код, то у данного способа задержка 0.025 сек
А как провернуть трюк, если речь о итеме, вызвать по нему ПКМ?
12

» WarRaft / Order

nazarpunk, подскажи, как мне вызвать приказ, когда ПКМ нажимаешь по итему ?
12

» WarRaft / Order

Как эти приказы юзать?
Например связанные с итемом
Hidden orders
constant integer Order_OFFSET = $d0002
constant integer Order_cancel = $d0008
constant integer Order_instant1 = $d0017
constant integer Order_instant2 = $d0013
constant integer Order_instant3 = $d0007
constant integer Order_instant4 = $d0033
constant integer Order_instant5 = $d000b
constant integer Order_moveslot1 = $d0022
constant integer Order_moveslot2 = $d0023
constant integer Order_moveslot3 = $d0024
constant integer Order_moveslot4 = $d0025
constant integer Order_moveslot5 = $d0026
constant integer Order_moveslot6 = $d0027
constant integer Order_scrollofspeed = $d013d
constant integer Order_skillmenu = $d0020
constant integer Order_stunned = $d0005
constant integer Order_useslot1 = $d0028
constant integer Order_useslot2 = $d0029
constant integer Order_useslot3 = $d002a
constant integer Order_useslot4 = $d002b
constant integer Order_useslot5 = $d002c
constant integer Order_useslot6 = $d002d

Сработал только constant integer Order_skillmenu = $d0020 и constant integer Order_stunned = $d0005
Так же тут не хватает этих приказов:
852273 = AoE heal
852272 = Heal Potion
852276 = Mana Potion
852277 = AoE Mana restore
852279 = Wand of Recall (ItemRecall)
852282 = AoE Heal/Mana restore
852609 = Scroll of Regen/ ManaRegen Potion
852261 = Item Summon Skill
852625 = Dust of Appearance
852269 = Свиток защиты
12

» WarCraft 3 / [2.0.3 vJass] UI - Move Able Frame - Перетаскиваем фрейм мышкой

Вышла новая версия!
Прокрутить к ресурсу
Обновление системы перемещения фреймов
🔹 Новые возможности:
✅ Два режима перемещения:
🔘 Удержание ПКМ – фрейм движется, пока зажата правая кнопка мыши.
🔘 Переключение по клику – первый клик ПКМ активирует движение, второй – сбрасывает.
✅ Плавное завершение анимации – фрейм теперь всегда доходит до конечной точки, а не останавливается раньше.
✅ Автоматический сброс масштаба – после завершения движения фрейм возвращается к стандартному размеру (scale = 1.0).
🔹 Исправленные баги:
🛠 Фрейм не возвращался к исходному размеру после клика по нему (теперь работает корректно).
🛠 Прерывание движения – раньше фрейм мог не доходить до цели, теперь анимация всегда завершается.
💡 Оптимизации:
Улучшена плавность движения.
Устранены рывки при резком перемещении мыши.
Логика сброса стала надёжнее (теперь фрейм не застревает в уменьшенном состоянии).
Не смог разобрать, но что то утекает когда я использую таймеры:
function PolledWait2 takes real time returns nothing
local timer t
local real R
    if time>0. then
        set t = CreateTimer()
        call TimerStart(t,time,false,null)
        loop
            set R=TimerGetRemaining(t)
            exitwhen R<=0.
                call TriggerSleepAction(R)
        endloop
        call DestroyTimer(t)
        set t=null
    endif 
endfunction
Обновлённый код движения:
library MoveAbleFrame initializer onTriggerInit requires World2Screen

globals
    real targetX = 0.0
    real targetY = 0.0
    real currentX = 0.0
    real currentY = 0.0
    real moveSpeed = 0.01 // от 0 до 1: выше — быстрее, ниже — плавнее
    real prevTargetX = 0.0
    real prevTargetY = 0.0
    real deltaX = 0.0
    real deltaY = 0.0
    boolean wasMoving // Флаг для того, чтоб сделать фрейм размером 1 после догонки
    boolean PolledMoving = false// Флаг для того, чтоб сделать фрейм размером 1 после догонки
endglobals

struct structMoveAbleFrame
    boolean         Enabled = true
    
    framehandle     Frame = null
    framehandle     PlayerHoveredFrame
    framepointtype  FramePoint
    trigger         TriggerFrameEnter
    triggeraction   TriggerFrameEnterAction
    trigger         TriggerFrameLeave
    triggeraction   TriggerFrameLeaveAction
    trigger         MouseClickTrigger
    triggeraction   MouseClickTriggerAction
    trigger         MouseReleaseTrigger
    triggeraction   MouseReleaseTriggerAction
    trigger         MOUSE_MOVE_Trigger
    triggeraction   MOUSE_MOVE_TriggerAction
endstruct

globals
    structMoveAbleFrame MoveAbleFrame
endglobals

function enable takes player p, boolean flag returns boolean
    if GetLocalPlayer() == p then
        if flag == null then
            set MoveAbleFrame.Enabled = not MoveAbleFrame.Enabled
        else
            set MoveAbleFrame.Enabled = flag
        endif
    endif
    return MoveAbleFrame.Enabled
endfunction

function setup takes framehandle frame returns nothing
    call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameEnter, frame, FRAMEEVENT_MOUSE_ENTER)
    call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameLeave , frame, FRAMEEVENT_MOUSE_LEAVE)
endfunction


function startMoving takes framehandle frame, framepointtype framePoint returns nothing
    set MoveAbleFrame.Frame = frame
    if framePoint == null then
       set framePoint = FRAMEPOINT_CENTER
    endif
    set MoveAbleFrame.FramePoint = framePoint
endfunction


function moveFrame takes real x, real y returns nothing
    call BlzFrameClearAllPoints(MoveAbleFrame.Frame)
    call BlzFrameSetAbsPoint(MoveAbleFrame.Frame, MoveAbleFrame.FramePoint, x, y)
endfunction


function GetTriggerPlayerHoveredFrame takes nothing returns nothing
    local real x = BlzGetTriggerPlayerMouseX()
    local real y = BlzGetTriggerPlayerMouseY()
    if GetLocalPlayer() == GetTriggerPlayer() then
        set MoveAbleFrame.PlayerHoveredFrame = BlzGetTriggerFrame()
    endif
endfunction

function GetTriggerPlayerHoveredFrameNull takes nothing returns nothing
    if GetLocalPlayer() == GetTriggerPlayer() then
        set MoveAbleFrame.PlayerHoveredFrame = null
    endif
endfunction

globals
    location moveLoc = Location(0, 0)
    boolean flag = false
endglobals

function TempFrameSetting takes nothing returns nothing
    call BlzFrameSetEnable(MoveAbleFrame.PlayerHoveredFrame, false)
    call BlzFrameSetLevel(MoveAbleFrame.PlayerHoveredFrame, 9)
    call BlzFrameSetScale(MoveAbleFrame.PlayerHoveredFrame, 0.8)
endfunction

function NormalFrameSetting takes nothing returns nothing
    call BlzFrameSetScale(MoveAbleFrame.Frame, 1.0)
    call BlzFrameSetEnable(MoveAbleFrame.Frame, true)
    call BlzFrameSetLevel(MoveAbleFrame.Frame, 6)
    set MoveAbleFrame.Frame = null
endfunction


globals
    real mouseX = 0.0
    real mouseY = 0.0
    real mouseX_prev = 0.0
    real mouseY_prev = 0.0
    real mouseX_interp = 0.0
    real mouseY_interp = 0.0
    real interpProgress = 1.0
    real interpSpeed  = 0
endglobals

function UpdateTargetXYInstant takes nothing returns nothing
    local real x = BlzGetTriggerPlayerMouseX()
    local real y = BlzGetTriggerPlayerMouseY()
    local real z

    call MoveLocation(moveLoc, x, y)
    set z = GetLocationZ(moveLoc)
    call World2Screen(x, y, z)

    // не трогаем prev/interp — сразу задаём target
    set targetX = ScreenX
    set targetY = ScreenY
endfunction
function UpdateMouseScreenCoords takes nothing returns nothing
    local real x = BlzGetTriggerPlayerMouseX()
    local real y = BlzGetTriggerPlayerMouseY()
    local real z

    call MoveLocation(moveLoc, x, y)
    set z = GetLocationZ(moveLoc)
    call World2Screen(x, y, z)

    set mouseX_prev = mouseX
    set mouseY_prev = mouseY
    set mouseX = ScreenX
    set mouseY = ScreenY
    set mouseX_interp = mouseX
    set mouseY_interp = mouseY
    set interpProgress = 1.0

    set targetX = mouseX
    set targetY = mouseY
endfunction

function PolledWait2 takes real time returns nothing
local timer t
local real R
    if time>0. then
        set t = CreateTimer()
        call TimerStart(t,time,false,null)
        loop
            set R=TimerGetRemaining(t)
            exitwhen R<=0.
                call TriggerSleepAction(R)
        endloop
        call DestroyTimer(t)
        set t=null
    endif 
endfunction

function GetWorld2Screen takes nothing returns real
    local real x = BlzGetTriggerPlayerMouseX()
    local real y = BlzGetTriggerPlayerMouseY()
    local real z
    
    call MoveLocation(moveLoc, x, y)
    set z = GetLocationZ(moveLoc)
    call World2Screen(x, y, z)
    return SquareRoot((currentX - ScreenX)*(currentX - ScreenX) + (currentY - ScreenY)*(currentY - ScreenY))
endfunction

function MouseClick takes nothing returns nothing
    local player p = GetTriggerPlayer()
    local real dist
    local timer t
    if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
        if MoveAbleFrame.Enabled and GetLocalPlayer() == p then
            if RIGHT_MOUSE_BUTTON_FRAME_DRAG_ENABLE then
                // Стандартное поведение (перетаскивание)
                if MoveAbleFrame.PlayerHoveredFrame != null then
                    set flag = true
                    call startMoving(MoveAbleFrame.PlayerHoveredFrame, FRAMEPOINT_CENTER)
                    call TempFrameSetting()
                    call UpdateMouseScreenCoords() 
                    set currentX = targetX
                    set currentY = targetY
                    call moveFrame(currentX, currentY)
                else
                    set flag = false
                    set MoveAbleFrame.Frame = null
                endif
            else
                // Альтернативное поведение (вкл/выкл)
                if MoveAbleFrame.PlayerHoveredFrame != null then
                    set flag = not flag
                    set PolledMoving = not PolledMoving
                    if flag then
                        call startMoving(MoveAbleFrame.PlayerHoveredFrame, FRAMEPOINT_CENTER)
                        call UpdateMouseScreenCoords()
                        set currentX = targetX
                        set currentY = targetY
                        call moveFrame(currentX, currentY)
                        call TempFrameSetting()
                    else
                        // Добавлено: сброс масштаба при flag = false (клик по фрейму)
                        call NormalFrameSetting()
                    endif
                else
                    // Клик вне фрейма — сброс (если PolledMoving = true)
                    if DRAG_TIMER_ENABLE then
                        if PolledMoving then
                            set PolledMoving = not PolledMoving
                            if GetWorld2Screen() > 0.0029 then
                                set t = CreateTimer()
                                call TimerStart(t, 0.15, false, null)
                                loop
                                    set dist = GetWorld2Screen()
                                    exitwhen dist < 0.002 or TimerGetRemaining(t) <= 0.
                                    call TriggerSleepAction(0.01)
                                endloop
                                call DestroyTimer(t)
                                set t = null
                            endif
                        endif
                    endif
                    set flag = false
                    call NormalFrameSetting()
                endif 
            endif
        endif
    endif
endfunction

function MouseRelease takes nothing returns nothing
    local real dist
    if MoveAbleFrame.Frame == null then
        return // нет фрейма — ничего не двигаем
    endif
    if RIGHT_MOUSE_BUTTON_FRAME_DRAG_ENABLE then
        set dist = GetWorld2Screen()

        if dist < 0.003 then
            // Мышь уже почти на фрейме — завершаем немедленно
            set flag = false
            set wasMoving = true
            set targetX = ScreenX
            set targetY = ScreenY
        else
            if DRAG_TIMER_ENABLE then
                 // Мышь далеко — ждём, пока дотянется
                call PolledWait2(0.15)
            endif
            set flag = false
            set wasMoving = true
            call UpdateTargetXYInstant()
        endif 
    endif
endfunction

function OnMouseMove takes nothing returns nothing
    local real newX = BlzGetTriggerPlayerMouseX()
    local real newY = BlzGetTriggerPlayerMouseY()
    //set GetFunctionName_DEBUG = "OnMouseMove"
    set mouseX_prev = mouseX
    set mouseY_prev = mouseY

    set mouseX = newX
    set mouseY = newY
    set interpProgress = 0.0
endfunction

function update2 takes nothing returns nothing
    local real dx
    local real dy
    local real distMouse
    local real dist
    local real dynamicSpeed
    local real speed = moveSpeed
    if MoveAbleFrame.Frame == null then
        return // нет фрейма — ничего не двигаем
    endif
    if flag or wasMoving then
        set dx = mouseX - mouseX_prev
        set dy = mouseY - mouseY_prev
        set distMouse = SquareRoot(dx * dx + dy * dy)

        set interpSpeed = 0.1 + distMouse * 0.6
        if interpSpeed > 0.3 then
            set interpSpeed = 0.3 // Ограничение скорости интерполяции
        endif
        set interpProgress = interpProgress + interpSpeed
        if interpProgress > 1.0 then
            set interpProgress = 1.0
        endif

        set mouseX_interp = mouseX_prev + (mouseX - mouseX_prev) * interpProgress
        set mouseY_interp = mouseY_prev + (mouseY - mouseY_prev) * interpProgress

        set targetX = mouseX_interp
        set targetY = mouseY_interp

        //set dist = SquareRoot((targetX - currentX)*(targetX - currentX) + (targetY - currentY)*(targetY - currentY))
        //set dynamicSpeed = moveSpeed + dist * 0.4
        //if dynamicSpeed > 0.08 then
            //set dynamicSpeed = 0.08
        //endif

        //set currentX = currentX + (targetX - currentX) * dynamicSpeed
        //set currentY = currentY + (targetY - currentY) * dynamicSpeed
        set dist = SquareRoot((targetX - currentX)*(targetX - currentX) + (targetY - currentY)*(targetY - currentY))
        if dist < 0.05 then
            set speed = moveSpeed + (0.05 - dist) * 2.0
            if speed > 0.025 then
                set speed = 0.025 // максимум, чтобы не прыгало
            endif
        endif

        set currentX = currentX * (1.0 - speed) + targetX * speed
        set currentY = currentY * (1.0 - speed) + targetY * speed

        call moveFrame(currentX, currentY)
        

        // завершение
        if not flag and dist < 0.001 then
            set wasMoving = false
            call BlzFrameSetScale(MoveAbleFrame.Frame, 1.0)
            call BlzFrameSetEnable(MoveAbleFrame.Frame, true)
            call BlzFrameSetLevel(MoveAbleFrame.Frame, 6)
        endif
    endif
endfunction


function CoordsMouse takes nothing returns nothing
    local real x = BlzGetTriggerPlayerMouseX()
    local real y = BlzGetTriggerPlayerMouseY()
    local real z
    if flag == true then
        call MoveLocation(moveLoc, x, y)
        set z = GetLocationZ(moveLoc)
        call World2Screen(x,y,z)

        set mouseX_prev = mouseX
        set mouseY_prev = mouseY
        set mouseX = ScreenX
        set mouseY = ScreenY
        set interpProgress = 0.0
    endif
endfunction

function onTriggerInit takes nothing returns nothing
local integer playerIndex = 0
local timer Timer = CreateTimer()
local timer Timer2 = CreateTimer()
    call PolledWait2(0.01)
    set MoveAbleFrame = structMoveAbleFrame.create()
    
    set MoveAbleFrame.TriggerFrameEnter = CreateTrigger()
    set MoveAbleFrame.TriggerFrameEnterAction = TriggerAddAction(MoveAbleFrame.TriggerFrameEnter,function GetTriggerPlayerHoveredFrame)
    
    set MoveAbleFrame.TriggerFrameLeave = CreateTrigger()
    set MoveAbleFrame.TriggerFrameLeaveAction = TriggerAddAction(MoveAbleFrame.TriggerFrameLeave, function GetTriggerPlayerHoveredFrameNull)

    set MoveAbleFrame.MouseClickTrigger = CreateTrigger()
    set MoveAbleFrame.MouseClickTriggerAction = TriggerAddAction(MoveAbleFrame.MouseClickTrigger, function MouseClick)
    
    set MoveAbleFrame.MouseReleaseTrigger = CreateTrigger()
    set MoveAbleFrame.MouseReleaseTriggerAction = TriggerAddAction(MoveAbleFrame.MouseReleaseTrigger, function MouseRelease)
    
    set MoveAbleFrame.MOUSE_MOVE_Trigger = CreateTrigger()
    set MoveAbleFrame.MOUSE_MOVE_TriggerAction = TriggerAddAction(MoveAbleFrame.MOUSE_MOVE_Trigger, function CoordsMouse)

    loop
    exitwhen playerIndex == GetBJMaxPlayers()
        call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseClickTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_DOWN)
        call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseReleaseTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_UP)
        call TriggerRegisterPlayerEvent(MoveAbleFrame.MOUSE_MOVE_Trigger, Player(playerIndex), EVENT_PLAYER_MOUSE_MOVE)
        set playerIndex = playerIndex + 1
    endloop
call ExecuteFunc("Init")
call TimerStart(Timer, 0.001, true, function update2)
call ExecuteFunc("CheckBoxInit")
endfunction

endlibrary

12

» WarCraft 3 / Список дефолтных фреймов-1. Потомки gameUI

Makeba, ну твой баян не виден в поиске, так же заметь, что это теперь 23 индекс.
Ну да работа с этим происходит через :

native BlzEnableCursor                             takes boolean enable returns nothing
native BlzSetMousePos                              takes integer x, integer y returns nothing
native BlzGetMouseFocusUnit
12

» WarCraft 3 / [2.0.3 vJass] UI - Move Able Frame - Перетаскиваем фрейм мышкой

darkowlom, только что обнаружил, что можно по таймеру запускать call BlzFrameClick(MoveAbleFrame.PlayerHoveredFrame), то есть будет срабатывать событие, по которому можно получать координаты и это уже ускоряет процесс.
Надо будет понять есть ли ещё варианты, ну и применить как-то для более идеальной плавности :)
12

» WarCraft 3 / Список дефолтных фреймов-1. Потомки gameUI

Получение фрейма мыши происходит по 24 ребенку(23 индекс)
local framehandle gameUI = BlzGetOriginFrame( ORIGIN_FRAME_GAME_UI, 0 )
local framehandle MouseCursor = BlzFrameGetChild(gameUI, 23)
Всего 24 ребёнка, но иногда появляется 25, я так и не понял что за 25, потому-что если обратится к нему, а его уже нет, то краш
call BlzFrameSetVisible(MouseCursor, false)
Можно мышку скрыть, выделение останется работать, то есть Mouse получит Инвиз
call BlzFrameSetSize(MouseCursor,0.9,0.9) Размер установить мышке нельзя !!!
 call BlzFrameSetScale(MouseCursor,0.25) 
- Зато можем контролировать размер через Scale
 call BlzFrameSetScale(MouseCursor,0.25)
- Зато можем контролировать размер через Scale :DDDDDDDDD
call BlzFrameSetPoint(MouseCursor, FRAMEPOINT_TOPLEFT, BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), FRAMEPOINT_TOPLEFT, 0.23, -0.03) 
Получается сдвинет нашу рабочую зону мышки, при этом кнопки останутся на месте, а курсор будет в стороне. Не знаю как объяснить, но видно будет на фото
call BlzFrameSetAllPoints(MouseCursor, gameUI) 
Вернёт в исходное положение координаты и размер, то есть сделает мышку дефолтной
12

» WarCraft 3 / [2.0.3 vJass] UI - Move Able Frame - Перетаскиваем фрейм мышкой

Вышла новая версия!
Прокрутить к ресурсу
Уменьшил количество Хэндлов до 106 (Победа!)
Убрал FrameGrid, новое решение более оптимизированное через мировые координаты
World2Screen
library World2Screen
globals
    real ScreenX = 0
    real ScreenY = 0
endglobals

function World2Screen takes real x, real y, real z returns nothing
    local real angleOfAttack = -GetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK)
    local real fieldOfView = GetCameraField(CAMERA_FIELD_FIELD_OF_VIEW)
    local real rotation = GetCameraField(CAMERA_FIELD_ROTATION) + bj_PI

    local real cosAttack = Cos(angleOfAttack)
    local real sinAttack = Sin(angleOfAttack)
    local real cosRot = Cos(rotation)
    local real sinRot = Sin(rotation)

    local real M11 = cosAttack*cosRot
    local real M12 = cosAttack*sinRot
    local real M13 = sinAttack
    local real M21 = -sinRot
    local real M22 = cosRot
    local real M23 = 0
    local real M31 = -cosRot*sinAttack
    local real M32 = -sinAttack*sinRot
    local real M33 = cosAttack

    local real dx = x - GetCameraEyePositionX()
    local real dy = y - GetCameraEyePositionY()
    local real dz = z - GetCameraEyePositionZ()

    local real xPrime = M11*dx + M12*dy + M13*dz
    local real yPrime = M21*dx + M22*dy + M23*dz
    local real zPrime = M31*dx + M32*dy + M33*dz

    local real scaling = 1.04 / ( 2 * Tan(fieldOfView / 2) )

    set ScreenX = 0.4 - (scaling * yPrime) / xPrime
    set ScreenY = 0.355 - (scaling * zPrime) / xPrime
endfunction
endlibrary
Три варианта, какой их них лучше я не понял, ибо каждый работает хорошо, но думаю можно ещё лучше)
1.MoveAbleFrame (Основной)
library MoveAbleFrame initializer onTriggerInit requires World2Screen
globals
real targetX = 0.0
real targetY = 0.0
real currentX = 0.0
real currentY = 0.0
real moveSpeed = 0.04 от 0 до 1: выше — быстрее, ниже — плавнее
real prevTargetX = 0.0
real prevTargetY = 0.0
real deltaX = 0.0
real deltaY = 0.0
endglobals
struct structMoveAbleFrame
boolean Enabled = true

framehandle Frame = null
framehandle PlayerHoveredFrame
framepointtype FramePoint
trigger TriggerFrameEnter
triggeraction TriggerFrameEnterAction
trigger TriggerFrameLeave
triggeraction TriggerFrameLeaveAction
trigger MouseClickTrigger
triggeraction MouseClickTriggerAction
trigger MouseReleaseTrigger
triggeraction MouseReleaseTriggerAction
trigger MOUSE_MOVE_Trigger
triggeraction MOUSE_MOVE_TriggerAction
endstruct
globals
structMoveAbleFrame MoveAbleFrame
endglobals
function enable takes player p, boolean flag returns boolean
if GetLocalPlayer() == p then
if flag == null then
set MoveAbleFrame.Enabled = not MoveAbleFrame.Enabled
else
set MoveAbleFrame.Enabled = flag
endif
endif
return MoveAbleFrame.Enabled
endfunction
function setup takes framehandle frame returns nothing
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameEnter, frame, FRAMEEVENT_MOUSE_ENTER)
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameLeave , frame, FRAMEEVENT_MOUSE_LEAVE)
endfunction
function startMoving takes framehandle frame, framepointtype framePoint returns nothing
set MoveAbleFrame.Frame = frame
if framePoint == null then
set framePoint = FRAMEPOINT_CENTER
endif
set MoveAbleFrame.FramePoint = framePoint
endfunction
function moveFrame takes real x, real y returns nothing
call BJDebugMsg("moveFrame: called x=" + R2S(x) + " y=" + R2S(y))
call BlzFrameClearAllPoints(MoveAbleFrame.Frame)
call BlzFrameSetAbsPoint(MoveAbleFrame.Frame, MoveAbleFrame.FramePoint, x, y)
endfunction
function GetTriggerPlayerHoveredFrame takes nothing returns nothing
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
set GetTriggerName_DEBUG = "TriggerFrameEnter"
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = BlzGetTriggerFrame()
endif
endfunction
function GetTriggerPlayerHoveredFrameNull takes nothing returns nothing
set GetTriggerName_DEBUG = "TriggerFrameLeave"
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = null
endif
endfunction
globals
location moveLoc = Location(0, 0)
boolean flag = false
endglobals
function MouseClick takes nothing returns nothing
local player p = GetTriggerPlayer()
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
local real z
call updateDebugFrame()
set GetFunctionName_DEBUG = "MouseClick"
set GetTriggerName_DEBUG = "MouseClickTrigger"
call MoveLocation(moveLoc, x, y)
set z = GetLocationZ(moveLoc)
if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
if MoveAbleFrame.PlayerHoveredFrame != null then
call BJDebugMsg("MouseClick: frame is not null: " + BlzFrameGetName(MoveAbleFrame.PlayerHoveredFrame))
if MoveAbleFrame.Enabled then
if GetLocalPlayer() == p then
set flag = true
call startMoving(MoveAbleFrame.PlayerHoveredFrame, FRAMEPOINT_CENTER)
call BlzFrameSetEnable(MoveAbleFrame.PlayerHoveredFrame, false)
call World2Screen(x,y,z)
set mouseX = ScreenX
set mouseY = ScreenY
set mouseX_prev = ScreenX
set mouseY_prev = ScreenY
set currentX = ScreenX
set currentY = ScreenY
set interpProgress = 1.0
endif
endif
else
call BJDebugMsg("MouseClick: PlayerHoveredFrame is null")
endif
endif
endfunction
function MouseRelease takes nothing returns nothing
set flag = false
set GetFunctionName_DEBUG = "MouseRelease"
set GetTriggerName_DEBUG = "MouseReleaseTrigger"
if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
if MoveAbleFrame.Frame != null then
call BlzFrameSetEnable(MoveAbleFrame.Frame, true)
endif
endif
endfunction
function PolledWait2 takes real time returns nothing
local timer t
local real R
if time>0. then
set t = CreateTimer()
call TimerStart(t,time,false,null)
loop
set R=TimerGetRemaining(t)
exitwhen R<=0.
call TriggerSleepAction(R)
endloop
call DestroyTimer(t)
set t=null
endif
endfunction
globals
real mouseX = 0.0
real mouseY = 0.0
real mouseX_prev = 0.0
real mouseY_prev = 0.0
real mouseX_interp = 0.0
real mouseY_interp = 0.0
real interpProgress = 1.0
real interpSpeed = 0
endglobals
function OnMouseMove takes nothing returns nothing
local real newX = BlzGetTriggerPlayerMouseX()
local real newY = BlzGetTriggerPlayerMouseY()
set GetFunctionName_DEBUG = "OnMouseMove"
set mouseX_prev = mouseX
set mouseY_prev = mouseY
set mouseX = newX
set mouseY = newY
set interpProgress = 0.0
endfunction
function update2 takes nothing returns nothing
local real dist
local real dynamicSpeed
local real dx
local real dy
local real distMouse
if flag == true then
call updateDebugFrame()
set GetFunctionName_DEBUG = "update2"
set dx = mouseX - mouseX_prev
set dy = mouseY - mouseY_prev
set distMouse = SquareRoot(dx * dx + dy * dy)
set interpSpeed = 0.1 + distMouse * 0.6
set interpProgress = interpProgress + interpSpeed
if interpProgress > 1.0 then
set interpProgress = 1.0
endif
set mouseX_interp = mouseX_prev + (mouseX - mouseX_prev) * interpProgress
set mouseY_interp = mouseY_prev + (mouseY - mouseY_prev) * interpProgress
set targetX = mouseX_interp
set targetY = mouseY_interp
set dist = SquareRoot((targetX - currentX)*(targetX - currentX) + (targetY - currentY)*(targetY - currentY))
set dynamicSpeed = moveSpeed + dist * 0.2
if dynamicSpeed > 0.08 then
set dynamicSpeed = 0.08
endif
set currentX = currentX + (targetX - currentX) * dynamicSpeed
set currentY = currentY + (targetY - currentY) * dynamicSpeed
call moveFrame(currentX, currentY)
endif
endfunction
function CoordsMouse takes nothing returns nothing
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
local real z
set GetFunctionName_DEBUG = "CoordsMouse"
set GetTriggerName_DEBUG = "MOUSE_MOVE_Trigger"
if flag == true then
call MoveLocation(moveLoc, x, y)
set z = GetLocationZ(moveLoc)
call World2Screen(x,y,z)
set mouseX_prev = mouseX
set mouseY_prev = mouseY
set mouseX = ScreenX
set mouseY = ScreenY
set interpProgress = 0.0
endif
endfunction
function onTriggerInit takes nothing returns nothing
local integer playerIndex = 0
local timer Timer = CreateTimer()
local timer Timer2 = CreateTimer()
call PolledWait2(0.01)
set MoveAbleFrame = structMoveAbleFrame.create()

set MoveAbleFrame.TriggerFrameEnter = CreateTrigger()
set MoveAbleFrame.TriggerFrameEnterAction = TriggerAddAction(MoveAbleFrame.TriggerFrameEnter,function GetTriggerPlayerHoveredFrame)

set MoveAbleFrame.TriggerFrameLeave = CreateTrigger()
set MoveAbleFrame.TriggerFrameLeaveAction = TriggerAddAction(MoveAbleFrame.TriggerFrameLeave, function GetTriggerPlayerHoveredFrameNull)
set MoveAbleFrame.MouseClickTrigger = CreateTrigger()
set MoveAbleFrame.MouseClickTriggerAction = TriggerAddAction(MoveAbleFrame.MouseClickTrigger, function MouseClick)

set MoveAbleFrame.MouseReleaseTrigger = CreateTrigger()
set MoveAbleFrame.MouseReleaseTriggerAction = TriggerAddAction(MoveAbleFrame.MouseReleaseTrigger, function MouseRelease)

set MoveAbleFrame.MOUSE_MOVE_Trigger = CreateTrigger()
set MoveAbleFrame.MOUSE_MOVE_TriggerAction = TriggerAddAction(MoveAbleFrame.MOUSE_MOVE_Trigger, function CoordsMouse)
loop
exitwhen playerIndex == GetBJMaxPlayers()
call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseClickTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_DOWN)
call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseReleaseTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_UP)
call TriggerRegisterPlayerEvent(MoveAbleFrame.MOUSE_MOVE_Trigger, Player(playerIndex), EVENT_PLAYER_MOUSE_MOVE)
set playerIndex = playerIndex + 1
endloop
call ExecuteFunc("onGameStart")
call TimerStart(Timer, 0.003, true, function update2)
endfunction
endlibrary
2.MoveAbleFrame 2
library MoveAbleFrame initializer onTriggerInit requires World2Screen

globals
    real targetX = 0.0
    real targetY = 0.0
    real currentX = 0.0
    real currentY = 0.0
    real moveSpeed = 0.04 // от 0 до 1: выше — быстрее, ниже — плавнее
    real prevTargetX = 0.0
    real prevTargetY = 0.0
    real deltaX = 0.0
    real deltaY = 0.0
endglobals

struct structMoveAbleFrame
    boolean         Enabled = true
    
    framehandle     Frame = null
    framehandle     PlayerHoveredFrame
    framepointtype  FramePoint
    trigger         TriggerFrameEnter
    triggeraction   TriggerFrameEnterAction
    trigger         TriggerFrameLeave
    triggeraction   TriggerFrameLeaveAction
    trigger         MouseClickTrigger
    triggeraction   MouseClickTriggerAction
    trigger         MouseReleaseTrigger
    triggeraction   MouseReleaseTriggerAction
    trigger         MOUSE_MOVE_Trigger
    triggeraction   MOUSE_MOVE_TriggerAction
endstruct

globals
    structMoveAbleFrame MoveAbleFrame
endglobals

function enable takes player p, boolean flag returns boolean
    if GetLocalPlayer() == p then
        if flag == null then
            set MoveAbleFrame.Enabled = not MoveAbleFrame.Enabled
        else
            set MoveAbleFrame.Enabled = flag
        endif
    endif
    return MoveAbleFrame.Enabled
endfunction

function setup takes framehandle frame returns nothing
    call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameEnter, frame, FRAMEEVENT_MOUSE_ENTER)
    call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameLeave , frame, FRAMEEVENT_MOUSE_LEAVE)
endfunction


function startMoving takes framehandle frame, framepointtype framePoint returns nothing
    set MoveAbleFrame.Frame = frame
    if framePoint == null then
       set framePoint = FRAMEPOINT_CENTER
    endif
    set MoveAbleFrame.FramePoint = framePoint
endfunction


function moveFrame takes real x, real y returns nothing
    call BJDebugMsg("moveFrame: called x=" + R2S(x) + " y=" + R2S(y))
    call BlzFrameClearAllPoints(MoveAbleFrame.Frame)
    call BlzFrameSetAbsPoint(MoveAbleFrame.Frame, MoveAbleFrame.FramePoint, x, y)
endfunction



function GetTriggerPlayerHoveredFrame takes nothing returns nothing
    if GetLocalPlayer() == GetTriggerPlayer() then
        set MoveAbleFrame.PlayerHoveredFrame = BlzGetTriggerFrame()
    endif
endfunction

function GetTriggerPlayerHoveredFrameNull takes nothing returns nothing
    if GetLocalPlayer() == GetTriggerPlayer() then
        set MoveAbleFrame.PlayerHoveredFrame = null
    endif
endfunction

globals
    location moveLoc = Location(0, 0)
    boolean flag = false
endglobals

function MouseClick takes nothing returns nothing
    local player p = GetTriggerPlayer()
    local real x = BlzGetTriggerPlayerMouseX()
    local real y = BlzGetTriggerPlayerMouseY()
    local real z

    call MoveLocation(moveLoc, x, y)
    set z = GetLocationZ(moveLoc)

    call BJDebugMsg("MouseClick")

    if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
        if MoveAbleFrame.PlayerHoveredFrame != null then
            call BJDebugMsg("MouseClick: frame is not null: " + BlzFrameGetName(MoveAbleFrame.PlayerHoveredFrame))
            if MoveAbleFrame.Enabled then
                if GetLocalPlayer() == p then
                    set flag = true // Перемещение только если действительно кликнули по фрейму
                    call startMoving(MoveAbleFrame.PlayerHoveredFrame, FRAMEPOINT_CENTER)
                    call BlzFrameSetEnable(MoveAbleFrame.PlayerHoveredFrame, false)
                    call World2Screen(x,y,z)
                endif
            endif
        else
            call BJDebugMsg("MouseClick: PlayerHoveredFrame is null")
        endif
    endif
endfunction

function MouseRelease takes nothing returns nothing
call BJDebugMsg("MouseRelease")
set flag = false
    if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
        if MoveAbleFrame.Frame != null then
            call BlzFrameSetEnable(MoveAbleFrame.Frame, true)
        endif
    endif
endfunction

function PolledWait2 takes real time returns nothing
local timer t
local real R
    if time>0. then
        set t = CreateTimer()
        call TimerStart(t,time,false,null)
        loop
            set R=TimerGetRemaining(t)
            exitwhen R<=0.
                call TriggerSleepAction(R)
        endloop
        call DestroyTimer(t)
        set t=null
    endif 
endfunction



function update2 takes nothing returns nothing
    local real dist
    local real dynamicSpeed
    if flag == true then
        set dist = SquareRoot((targetX - currentX)*(targetX - currentX) + (targetY - currentY)*(targetY - currentY))
        set dynamicSpeed = moveSpeed + dist * 0.4
        if dynamicSpeed > 0.08 then
            set dynamicSpeed = 0.08
        endif
        // Плавное приближение к целевой позиции
        set currentX = currentX + (targetX - currentX) * moveSpeed
        set currentY = currentY + (targetY - currentY) * moveSpeed

        call moveFrame(currentX, currentY)
    endif
endfunction

function CoordsMouse takes nothing returns nothing
    local real x = BlzGetTriggerPlayerMouseX()
    local real y = BlzGetTriggerPlayerMouseY()
    local real speedLimit = 0.25
    local real deltaLength = SquareRoot(deltaX * deltaX + deltaY * deltaY)
    local real z
    if flag == true then
        call MoveLocation(moveLoc, x, y)
        set z = GetLocationZ(moveLoc)
        call World2Screen(x,y,z)
        set deltaX = ScreenX - prevTargetX
        set deltaY = ScreenY - prevTargetY
        if deltaLength > speedLimit then
            set deltaX = deltaX * speedLimit / deltaLength
            set deltaY = deltaY * speedLimit / deltaLength
        endif
        set targetX = ScreenX + deltaX * 1.4
        set targetY = ScreenY + deltaY * 1.4

        set prevTargetX = ScreenX
        set prevTargetY = ScreenY
    endif
endfunction

function onTriggerInit takes nothing returns nothing
local integer playerIndex = 0
local timer Timer = CreateTimer()
local timer Timer2 = CreateTimer()
    call PolledWait2(0.01)
    set MoveAbleFrame = structMoveAbleFrame.create()
    
    set MoveAbleFrame.TriggerFrameEnter = CreateTrigger()
    set MoveAbleFrame.TriggerFrameEnterAction = TriggerAddAction(MoveAbleFrame.TriggerFrameEnter,function GetTriggerPlayerHoveredFrame)
    
    set MoveAbleFrame.TriggerFrameLeave = CreateTrigger()
    set MoveAbleFrame.TriggerFrameLeaveAction = TriggerAddAction(MoveAbleFrame.TriggerFrameLeave, function GetTriggerPlayerHoveredFrameNull)

    set MoveAbleFrame.MouseClickTrigger = CreateTrigger()
    set MoveAbleFrame.MouseClickTriggerAction = TriggerAddAction(MoveAbleFrame.MouseClickTrigger, function MouseClick)
    
    set MoveAbleFrame.MouseReleaseTrigger = CreateTrigger()
    set MoveAbleFrame.MouseReleaseTriggerAction = TriggerAddAction(MoveAbleFrame.MouseReleaseTrigger, function MouseRelease)
    
    set MoveAbleFrame.MOUSE_MOVE_Trigger = CreateTrigger()
    set MoveAbleFrame.MOUSE_MOVE_TriggerAction = TriggerAddAction(MoveAbleFrame.MOUSE_MOVE_Trigger, function CoordsMouse)

    loop
    exitwhen playerIndex == GetBJMaxPlayers()
        call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseClickTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_DOWN)
        call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseReleaseTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_UP)
        call TriggerRegisterPlayerEvent(MoveAbleFrame.MOUSE_MOVE_Trigger, Player(playerIndex), EVENT_PLAYER_MOUSE_MOVE)
        set playerIndex = playerIndex + 1
    endloop
call ExecuteFunc("onGameStart")
call TimerStart(Timer, 0.003, true, function update2)
endfunction

endlibrary

3. MoveAbleFrame 3 (Можно подогнать скорость под таймер 0.001 и будет ещё лучше)
library MoveAbleFrame initializer onTriggerInit requires World2Screen
globals
real targetX = 0.0
real targetY = 0.0
real currentX = 0.0
real currentY = 0.0
real moveSpeed = 0.02 от 0 до 1: выше — быстрее, ниже — плавнее
real prevTargetX = 0.0
real prevTargetY = 0.0
real deltaX = 0.0
real deltaY = 0.0
endglobals
struct structMoveAbleFrame
boolean Enabled = true

framehandle Frame = null
framehandle PlayerHoveredFrame
framepointtype FramePoint
trigger TriggerFrameEnter
triggeraction TriggerFrameEnterAction
trigger TriggerFrameLeave
triggeraction TriggerFrameLeaveAction
trigger MouseClickTrigger
triggeraction MouseClickTriggerAction
trigger MouseReleaseTrigger
triggeraction MouseReleaseTriggerAction
trigger MOUSE_MOVE_Trigger
triggeraction MOUSE_MOVE_TriggerAction
endstruct
globals
structMoveAbleFrame MoveAbleFrame
endglobals
function enable takes player p, boolean flag returns boolean
if GetLocalPlayer() == p then
if flag == null then
set MoveAbleFrame.Enabled = not MoveAbleFrame.Enabled
else
set MoveAbleFrame.Enabled = flag
endif
endif
return MoveAbleFrame.Enabled
endfunction
function setup takes framehandle frame returns nothing
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameEnter, frame, FRAMEEVENT_MOUSE_ENTER)
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameLeave , frame, FRAMEEVENT_MOUSE_LEAVE)
endfunction
function startMoving takes framehandle frame, framepointtype framePoint returns nothing
set MoveAbleFrame.Frame = frame
if framePoint == null then
set framePoint = FRAMEPOINT_CENTER
endif
set MoveAbleFrame.FramePoint = framePoint
endfunction
function moveFrame takes real x, real y returns nothing
call BJDebugMsg("moveFrame: called x=" + R2S(x) + " y=" + R2S(y))
call BlzFrameClearAllPoints(MoveAbleFrame.Frame)
call BlzFrameSetAbsPoint(MoveAbleFrame.Frame, MoveAbleFrame.FramePoint, x, y)
endfunction
function GetTriggerPlayerHoveredFrame takes nothing returns nothing
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
set GetTriggerName_DEBUG = "TriggerFrameEnter"
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = BlzGetTriggerFrame()
endif
endfunction
function GetTriggerPlayerHoveredFrameNull takes nothing returns nothing
set GetTriggerName_DEBUG = "TriggerFrameLeave"
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = null
endif
endfunction
globals
location moveLoc = Location(0, 0)
boolean flag = false
endglobals
function MouseClick takes nothing returns nothing
local player p = GetTriggerPlayer()
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
local real z
call updateDebugFrame()
set GetFunctionName_DEBUG = "MouseClick"
set GetTriggerName_DEBUG = "MouseClickTrigger"
call MoveLocation(moveLoc, x, y)
set z = GetLocationZ(moveLoc)
if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
if MoveAbleFrame.PlayerHoveredFrame != null then
call BJDebugMsg("MouseClick: frame is not null: " + BlzFrameGetName(MoveAbleFrame.PlayerHoveredFrame))
if MoveAbleFrame.Enabled then
if GetLocalPlayer() == p then
set flag = true
call startMoving(MoveAbleFrame.PlayerHoveredFrame, FRAMEPOINT_CENTER)
call BlzFrameSetEnable(MoveAbleFrame.PlayerHoveredFrame, false)
call World2Screen(x,y,z)
set mouseX = ScreenX
set mouseY = ScreenY
set mouseX_prev = ScreenX
set mouseY_prev = ScreenY
set currentX = ScreenX
set currentY = ScreenY
set interpProgress = 1.0
endif
endif
else
call BJDebugMsg("MouseClick: PlayerHoveredFrame is null")
endif
endif
endfunction
function MouseRelease takes nothing returns nothing
set flag = false
set GetFunctionName_DEBUG = "MouseRelease"
set GetTriggerName_DEBUG = "MouseReleaseTrigger"
if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
if MoveAbleFrame.Frame != null then
call BlzFrameSetEnable(MoveAbleFrame.Frame, true)
endif
endif
endfunction
function PolledWait2 takes real time returns nothing
local timer t
local real R
if time>0. then
set t = CreateTimer()
call TimerStart(t,time,false,null)
loop
set R=TimerGetRemaining(t)
exitwhen R<=0.
call TriggerSleepAction(R)
endloop
call DestroyTimer(t)
set t=null
endif
endfunction
globals
real mouseX = 0.0
real mouseY = 0.0
real mouseX_prev = 0.0
real mouseY_prev = 0.0
real mouseX_interp = 0.0
real mouseY_interp = 0.0
real interpProgress = 1.0
real interpSpeed = 0
endglobals
function OnMouseMove takes nothing returns nothing
local real newX = BlzGetTriggerPlayerMouseX()
local real newY = BlzGetTriggerPlayerMouseY()
set GetFunctionName_DEBUG = "OnMouseMove"
set mouseX_prev = mouseX
set mouseY_prev = mouseY
set mouseX = newX
set mouseY = newY
set interpProgress = 0.0
endfunction
function update2 takes nothing returns nothing
local real dist
local real dynamicSpeed
local real dx
local real dy
local real distMouse
if flag == true then
call updateDebugFrame()
set GetTriggerName_DEBUG = "onTriggerInit"
set GetFunctionName_DEBUG = "update2"
set dx = mouseX - mouseX_prev
set dy = mouseY - mouseY_prev
set distMouse = SquareRoot(dx * dx + dy * dy)
set interpSpeed = 0.04 + distMouse * 0.3
set interpProgress = interpProgress + interpSpeed
if interpProgress > 1.0 then
set interpProgress = 1.0
endif
set mouseX_interp = mouseX_prev + (mouseX - mouseX_prev) * interpProgress
set mouseY_interp = mouseY_prev + (mouseY - mouseY_prev) * interpProgress
set targetX = mouseX_interp
set targetY = mouseY_interp
set dist = SquareRoot((targetX - currentX)*(targetX - currentX) + (targetY - currentY)*(targetY - currentY))
set dynamicSpeed = moveSpeed + dist * 0.1
if dynamicSpeed > 0.05 then
set dynamicSpeed = 0.05
endif
set currentX = currentX + (targetX - currentX) * dynamicSpeed
set currentY = currentY + (targetY - currentY) * dynamicSpeed
call moveFrame(currentX, currentY)
endif
endfunction
function CoordsMouse takes nothing returns nothing
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
local real z
set GetFunctionName_DEBUG = "CoordsMouse"
set GetTriggerName_DEBUG = "MOUSE_MOVE_Trigger"
if flag == true then
call MoveLocation(moveLoc, x, y)
set z = GetLocationZ(moveLoc)
call World2Screen(x,y,z)
set mouseX_prev = mouseX
set mouseY_prev = mouseY
set mouseX = ScreenX
set mouseY = ScreenY
set interpProgress = 0.0
endif
endfunction
function onTriggerInit takes nothing returns nothing
local integer playerIndex = 0
local timer Timer = CreateTimer()
local timer Timer2 = CreateTimer()
call PolledWait2(0.01)
set MoveAbleFrame = structMoveAbleFrame.create()

set MoveAbleFrame.TriggerFrameEnter = CreateTrigger()
set MoveAbleFrame.TriggerFrameEnterAction = TriggerAddAction(MoveAbleFrame.TriggerFrameEnter,function GetTriggerPlayerHoveredFrame)

set MoveAbleFrame.TriggerFrameLeave = CreateTrigger()
set MoveAbleFrame.TriggerFrameLeaveAction = TriggerAddAction(MoveAbleFrame.TriggerFrameLeave, function GetTriggerPlayerHoveredFrameNull)
set MoveAbleFrame.MouseClickTrigger = CreateTrigger()
set MoveAbleFrame.MouseClickTriggerAction = TriggerAddAction(MoveAbleFrame.MouseClickTrigger, function MouseClick)

set MoveAbleFrame.MouseReleaseTrigger = CreateTrigger()
set MoveAbleFrame.MouseReleaseTriggerAction = TriggerAddAction(MoveAbleFrame.MouseReleaseTrigger, function MouseRelease)

set MoveAbleFrame.MOUSE_MOVE_Trigger = CreateTrigger()
set MoveAbleFrame.MOUSE_MOVE_TriggerAction = TriggerAddAction(MoveAbleFrame.MOUSE_MOVE_Trigger, function CoordsMouse)
loop
exitwhen playerIndex == GetBJMaxPlayers()
call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseClickTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_DOWN)
call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseReleaseTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_UP)
call TriggerRegisterPlayerEvent(MoveAbleFrame.MOUSE_MOVE_Trigger, Player(playerIndex), EVENT_PLAYER_MOUSE_MOVE)
set playerIndex = playerIndex + 1
endloop
call ExecuteFunc("onGameStart")
call TimerStart(Timer, 0.001, true, function update2)
endfunction
endlibrary
12

» Администрация XGM / Проблемы при просмотре видео

Могу ли я заливать видео на xgm и указывать альтернативную ссылку на видео?
На случай если у кого-то проблемы с загрузкой?
12

» WarCraft 3 / [2.0.3] Как перетаскивать фрейм мышкой?

ScorpioT1000, что то похожее попытался сделать по твоему примеру + все же по первому предложенному способу Makeba
Мне кажется нужно повысить ещё сильнее плавность или скорость перемещения, но уже выглядит хорошо и не нагружено
real moveSpeed = 0.2:
real moveSpeed = 0.1:
MoveAbleFrame
library MoveAbleFrame initializer onTriggerInit requires World2Screen
globals
real targetX = 0.0
real targetY = 0.0
real currentX = 0.0
real currentY = 0.0
real moveSpeed = 0.2 При скорости ниже 0.2 получаю сильное отставание от иконки, но невероятную плавность
endglobals
struct structMoveAbleFrame
boolean Enabled = true

framehandle Frame = null
framehandle PlayerHoveredFrame
framepointtype FramePoint
trigger TriggerFrameEnter
triggeraction TriggerFrameEnterAction
trigger TriggerFrameLeave
triggeraction TriggerFrameLeaveAction
trigger MouseClickTrigger
triggeraction MouseClickTriggerAction
trigger MouseReleaseTrigger
triggeraction MouseReleaseTriggerAction
trigger MOUSE_MOVE_Trigger
triggeraction MOUSE_MOVE_TriggerAction
endstruct
globals
structMoveAbleFrame MoveAbleFrame
endglobals
function enable takes player p, boolean flag returns boolean
if GetLocalPlayer() == p then
if flag == null then
set MoveAbleFrame.Enabled = not MoveAbleFrame.Enabled
else
set MoveAbleFrame.Enabled = flag
endif
endif
return MoveAbleFrame.Enabled
endfunction
function setup takes framehandle frame returns nothing
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameEnter, frame, FRAMEEVENT_MOUSE_ENTER)
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameLeave , frame, FRAMEEVENT_MOUSE_LEAVE)
endfunction
function startMoving takes framehandle frame, framepointtype framePoint returns nothing
set MoveAbleFrame.Frame = frame
if framePoint == null then
set framePoint = FRAMEPOINT_CENTER
endif
set MoveAbleFrame.FramePoint = framePoint
endfunction
function moveFrame takes real x, real y returns nothing
call BJDebugMsg("moveFrame: called x=" + R2S(x) + " y=" + R2S(y))
call BlzFrameClearAllPoints(MoveAbleFrame.Frame)
call BlzFrameSetAbsPoint(MoveAbleFrame.Frame, MoveAbleFrame.FramePoint, x, y)
endfunction
function GetTriggerPlayerHoveredFrame takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = BlzGetTriggerFrame()
endif
endfunction
function GetTriggerPlayerHoveredFrameNull takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = null
endif
endfunction
globals
location moveLoc = Location(0, 0)
boolean flag = false
endglobals
function MouseClick takes nothing returns nothing
local player p = GetTriggerPlayer()
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
local real z
call MoveLocation(moveLoc, x, y)
set z = GetLocationZ(moveLoc) Получаем Z-координату
call BJDebugMsg("MouseClick")
if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
if MoveAbleFrame.PlayerHoveredFrame != null then
call BJDebugMsg("MouseClick: frame is not null: " + BlzFrameGetName(MoveAbleFrame.PlayerHoveredFrame))
if MoveAbleFrame.Enabled then
if GetLocalPlayer() == p then
set flag = true Перемещение только если действительно кликнули по фрейму
call startMoving(MoveAbleFrame.PlayerHoveredFrame, FRAMEPOINT_CENTER)
call BlzFrameSetEnable(MoveAbleFrame.PlayerHoveredFrame, false)
call World2Screen(x,y,z)
call moveFrame(ScreenX,ScreenY)
endif
endif
else
call BJDebugMsg("MouseClick: PlayerHoveredFrame is null")
endif
endif
endfunction
function MouseRelease takes nothing returns nothing
call BJDebugMsg("MouseRelease")
set flag = false
if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
if MoveAbleFrame.Frame != null then
call BlzFrameSetEnable(MoveAbleFrame.Frame, true)
endif
endif
endfunction
function PolledWait2 takes real time returns nothing
local timer t
local real R
if time>0. then
set t = CreateTimer()
call TimerStart(t,time,false,null)
loop
set R=TimerGetRemaining(t)
exitwhen R<=0.
call TriggerSleepAction(R)
endloop
call DestroyTimer(t)
set t=null
endif
endfunction
function update2 takes nothing returns nothing
if flag == true then
Плавное приближение к целевой позиции
set currentX = currentX + (targetX - currentX) * moveSpeed
set currentY = currentY + (targetY - currentY) * moveSpeed
call moveFrame(currentX, currentY)
endif
endfunction
function CoordsMouse takes nothing returns nothing
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
local real z
if flag == true then
call MoveLocation(moveLoc, x, y)
set z = GetLocationZ(moveLoc)
call World2Screen(x,y,z)
call moveFrame(ScreenX,ScreenY)
set targetX = ScreenX
set targetY = ScreenY
endif
endfunction
function onTriggerInit takes nothing returns nothing
local integer playerIndex = 0
local timer Timer = CreateTimer()
call PolledWait2(0.01)
set MoveAbleFrame = structMoveAbleFrame.create()

set MoveAbleFrame.TriggerFrameEnter = CreateTrigger()
set MoveAbleFrame.TriggerFrameEnterAction = TriggerAddAction(MoveAbleFrame.TriggerFrameEnter,function GetTriggerPlayerHoveredFrame)

set MoveAbleFrame.TriggerFrameLeave = CreateTrigger()
set MoveAbleFrame.TriggerFrameLeaveAction = TriggerAddAction(MoveAbleFrame.TriggerFrameLeave, function GetTriggerPlayerHoveredFrameNull)
set MoveAbleFrame.MouseClickTrigger = CreateTrigger()
set MoveAbleFrame.MouseClickTriggerAction = TriggerAddAction(MoveAbleFrame.MouseClickTrigger, function MouseClick)

set MoveAbleFrame.MouseReleaseTrigger = CreateTrigger()
set MoveAbleFrame.MouseReleaseTriggerAction = TriggerAddAction(MoveAbleFrame.MouseReleaseTrigger, function MouseRelease)

set MoveAbleFrame.MOUSE_MOVE_Trigger = CreateTrigger()
set MoveAbleFrame.MOUSE_MOVE_TriggerAction = TriggerAddAction(MoveAbleFrame.MOUSE_MOVE_Trigger, function CoordsMouse)
loop
exitwhen playerIndex == GetBJMaxPlayers()
call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseClickTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_DOWN)
call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseReleaseTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_UP)
call TriggerRegisterPlayerEvent(MoveAbleFrame.MOUSE_MOVE_Trigger, Player(playerIndex), EVENT_PLAYER_MOUSE_MOVE)
set playerIndex = playerIndex + 1
endloop
call ExecuteFunc("onGameStart")
call TimerStart(Timer, 0.01, true, function update2)
endfunction
endlibrary
12

» WarCraft 3 / [2.0.3 vJass] UI - Move Able Frame - Перетаскиваем фрейм мышкой

darkowlom, я последовал твоей идеи, мы снизили хэндлы до 106, но при этом потеряли плавность, так этот вариант не подходит из-за скорости
Может у тебя появятся идеи как это ускорить?
World2Screen
library World2Screen
globals
    real ScreenX
    real ScreenY
endglobals

function World2Screen takes real x, real y, real z returns nothing
    local real angleOfAttack = -GetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK)
    local real fieldOfView = GetCameraField(CAMERA_FIELD_FIELD_OF_VIEW)
    local real rotation = GetCameraField(CAMERA_FIELD_ROTATION) + bj_PI

    local real cosAttack = Cos(angleOfAttack)
    local real sinAttack = Sin(angleOfAttack)
    local real cosRot = Cos(rotation)
    local real sinRot = Sin(rotation)

    local real M11 = cosAttack*cosRot
    local real M12 = cosAttack*sinRot
    local real M13 = sinAttack
    local real M21 = -sinRot
    local real M22 = cosRot
    local real M23 = 0
    local real M31 = -cosRot*sinAttack
    local real M32 = -sinAttack*sinRot
    local real M33 = cosAttack

    local real dx = x - GetCameraEyePositionX()
    local real dy = y - GetCameraEyePositionY()
    local real dz = z - GetCameraEyePositionZ()

    local real xPrime = M11*dx + M12*dy + M13*dz
    local real yPrime = M21*dx + M22*dy + M23*dz
    local real zPrime = M31*dx + M32*dy + M33*dz

    local real scaling = 1.04 / ( 2 * Tan(fieldOfView / 2) )

    set ScreenX = 0.4 - (scaling * yPrime) / xPrime
    set ScreenY = 0.355 - (scaling * zPrime) / xPrime
endfunction
endlibrary
MoveAbleFrame
library MoveAbleFrame initializer onTriggerInit requires World2Screen

struct structMoveAbleFrame
    boolean         Enabled = true
    
    framehandle     Frame = null
    framehandle     PlayerHoveredFrame
    framepointtype  FramePoint
    trigger         TriggerFrameEnter
    triggeraction   TriggerFrameEnterAction
    trigger         TriggerFrameLeave
    triggeraction   TriggerFrameLeaveAction
    trigger         MouseClickTrigger
    triggeraction   MouseClickTriggerAction
    trigger         MouseReleaseTrigger
    triggeraction   MouseReleaseTriggerAction
    trigger         MOUSE_MOVE_Trigger
    triggeraction   MOUSE_MOVE_TriggerAction
endstruct

globals
    structMoveAbleFrame MoveAbleFrame
endglobals

function enable takes player p, boolean flag returns boolean
    if GetLocalPlayer() == p then
        if flag == null then
            set MoveAbleFrame.Enabled = not MoveAbleFrame.Enabled
        else
            set MoveAbleFrame.Enabled = flag
        endif
    endif
    return MoveAbleFrame.Enabled
endfunction

function setup takes framehandle frame returns nothing
    call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameEnter, frame, FRAMEEVENT_MOUSE_ENTER)
    call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameLeave , frame, FRAMEEVENT_MOUSE_LEAVE)
endfunction


function startMoving takes framehandle frame, framepointtype framePoint returns nothing
    set MoveAbleFrame.Frame = frame
    if framePoint == null then
       set framePoint = FRAMEPOINT_CENTER
    endif
    set MoveAbleFrame.FramePoint = framePoint
endfunction


function moveFrame takes real x, real y returns nothing
    call BJDebugMsg("moveFrame: called x=" + R2S(x) + " y=" + R2S(y))
    call BlzFrameClearAllPoints(MoveAbleFrame.Frame)
    call BlzFrameSetAbsPoint(MoveAbleFrame.Frame, MoveAbleFrame.FramePoint, x, y)
endfunction



function GetTriggerPlayerHoveredFrame takes nothing returns nothing
    if GetLocalPlayer() == GetTriggerPlayer() then
        set MoveAbleFrame.PlayerHoveredFrame = BlzGetTriggerFrame()
    endif
endfunction

function GetTriggerPlayerHoveredFrameNull takes nothing returns nothing
    if GetLocalPlayer() == GetTriggerPlayer() then
        set MoveAbleFrame.PlayerHoveredFrame = null
    endif
endfunction

globals
    location moveLoc = Location(0, 0)
    boolean flag = false
endglobals

function MouseClick takes nothing returns nothing
    local player p = GetTriggerPlayer()
    local real x = BlzGetTriggerPlayerMouseX()
    local real y = BlzGetTriggerPlayerMouseY()
    local real z

    call MoveLocation(moveLoc, x, y)
    set z = GetLocationZ(moveLoc) // Получаем Z-координату

    call BJDebugMsg("MouseClick")

    if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
        if MoveAbleFrame.PlayerHoveredFrame != null then
            call BJDebugMsg("MouseClick: frame is not null: " + BlzFrameGetName(MoveAbleFrame.PlayerHoveredFrame))
            if MoveAbleFrame.Enabled then
                if GetLocalPlayer() == p then
                    set flag = true // Перемещение только если действительно кликнули по фрейму
                    call startMoving(MoveAbleFrame.PlayerHoveredFrame, FRAMEPOINT_CENTER)
                    call BlzFrameSetEnable(MoveAbleFrame.PlayerHoveredFrame, false)
                    call World2Screen(x,y,z)
                    call moveFrame(ScreenX,ScreenY)
                endif
            endif
        else
            call BJDebugMsg("MouseClick: PlayerHoveredFrame is null")
        endif
    endif
endfunction

function MouseRelease takes nothing returns nothing
call BJDebugMsg("MouseRelease")
set flag = false
    if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
        if MoveAbleFrame.Frame != null then
            call BlzFrameSetEnable(MoveAbleFrame.Frame, true)
        endif
        //call show(false, GetTriggerPlayer())
    endif
endfunction

function PolledWait2 takes real time returns nothing
local timer t
local real R
    if time>0. then
        set t = CreateTimer()
        call TimerStart(t,time,false,null)
        loop
            set R=TimerGetRemaining(t)
            exitwhen R<=0.
                call TriggerSleepAction(R)
        endloop
        call DestroyTimer(t)
        set t=null
    endif 
endfunction

function update2 takes nothing returns nothing
    if flag == true then
        call moveFrame(ScreenX,ScreenY)
    endif
endfunction

function CoordsMouse takes nothing returns nothing
    local real x = BlzGetTriggerPlayerMouseX()
    local real y = BlzGetTriggerPlayerMouseY()
    local real z
    if flag == true then
        call BJDebugMsg("CoordsMouse")
        call MoveLocation(moveLoc, x, y)
        set z = GetLocationZ(moveLoc) // Получаем Z-координату
        call World2Screen(x,y,z)
        call moveFrame(ScreenX,ScreenY)
    endif
endfunction

function onTriggerInit takes nothing returns nothing
local integer playerIndex = 0
local timer Timer = CreateTimer()
    call PolledWait2(0.01)
    set MoveAbleFrame = structMoveAbleFrame.create()
    
    set MoveAbleFrame.TriggerFrameEnter = CreateTrigger()
    set MoveAbleFrame.TriggerFrameEnterAction = TriggerAddAction(MoveAbleFrame.TriggerFrameEnter,function GetTriggerPlayerHoveredFrame)
    
    set MoveAbleFrame.TriggerFrameLeave = CreateTrigger()
    set MoveAbleFrame.TriggerFrameLeaveAction = TriggerAddAction(MoveAbleFrame.TriggerFrameLeave, function GetTriggerPlayerHoveredFrameNull)

    set MoveAbleFrame.MouseClickTrigger = CreateTrigger()
    set MoveAbleFrame.MouseClickTriggerAction = TriggerAddAction(MoveAbleFrame.MouseClickTrigger, function MouseClick)
    
    set MoveAbleFrame.MouseReleaseTrigger = CreateTrigger()
    set MoveAbleFrame.MouseReleaseTriggerAction = TriggerAddAction(MoveAbleFrame.MouseReleaseTrigger, function MouseRelease)
    
    set MoveAbleFrame.MOUSE_MOVE_Trigger = CreateTrigger()
    set MoveAbleFrame.MOUSE_MOVE_TriggerAction = TriggerAddAction(MoveAbleFrame.MOUSE_MOVE_Trigger, function CoordsMouse)

    loop
    exitwhen playerIndex == GetBJMaxPlayers()
        call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseClickTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_DOWN)
        call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseReleaseTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_UP)
        call TriggerRegisterPlayerEvent(MoveAbleFrame.MOUSE_MOVE_Trigger, Player(playerIndex), EVENT_PLAYER_MOUSE_MOVE)
        set playerIndex = playerIndex + 1
    endloop
call ExecuteFunc("onGameStart")
call TimerStart(Timer, 0.01, true, function update2)
endfunction

endlibrary

12

» WarCraft 3 / [2.0.3 vJass] UI - Move Able Frame - Перетаскиваем фрейм мышкой

darkowlom, спасибо за попытку))
array в параметрах функций нельзя))
И локалки массивы объявлять нельзя)
Код сформирован солянкой)
Что за нейронка? на Deepseek и ChatGPT не похожа )
12

» WarCraft 3 / [2.0.3] Как перетаскивать фрейм мышкой?

Попробую ваши варианты, вернусь с ответом если выйдет, что то более качественное, спасибо!
12

» WarCraft 3 / GetMainSelectedUnit

Makeba, если внимательно прочитаешь, то я указал потом что работает, а что не работает.
В любом случае я проверил твой код, он является более предпочтительным, он гораздо меньше, что здорово