darkowlom, только что обнаружил, что можно по таймеру запускать call BlzFrameClick(MoveAbleFrame.PlayerHoveredFrame), то есть будет срабатывать событие, по которому можно получать координаты и это уже ускоряет процесс.
Надо будет понять есть ли ещё варианты, ну и применить как-то для более идеальной плавности :)
Получение фрейма мыши происходит по 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 BlzFrameSetAllPoints(MouseCursor, gameUI)
Вернёт в исходное положение координаты и размер, то есть сделает мышку дефолтной
Убрал 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
Три варианта, какой их них лучше я не понял, ибо каждый работает хорошо, но думаю можно ещё лучше)
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
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 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
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
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)
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
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
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 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
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
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)
globals
real targetX = 0.0
real targetY = 0.0
real currentX = 0.0
real currentY = 0.0
real moveSpeed = 0.2 При скорости ниже 0.2 получаю сильное отставание от иконки, но невероятную плавность
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 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
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
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)
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
Makeba, если внимательно прочитаешь, то я указал потом что работает, а что не работает.
В любом случае я проверил твой код, он является более предпочтительным, он гораздо меньше, что здорово
С версии 2.0.0 данный код не работает, из-за обращения к "groupframe = BlzFrameGetChild(bottomUI, 5)", когда у фрейма всего 4 ребенка, где индексы с 0 - 3, то есть 5 не существует но пока не понимаю, как определить выделенного юнита в группе
С версии 2.0.2 теперь обращаться к фрейму панели отряда надо так:
private function init_functionAt0s takes nothing returns nothing
local integer i = 0
local framehandle console = BlzGetFrameByName("ConsoleUI", 0)
local framehandle bottomUI = BlzFrameGetChild(console, 1)
local framehandle groupframe = BlzFrameGetChild(bottomUI, 2)
local framehandle SquadPanel = BlzFrameGetChild(groupframe, 5)
local framehandle buttonContainer
set containerFrame = BlzFrameGetChild(SquadPanel, 0)
Это вызовет краш игры в версии 2.0.3:
function InitGlobalsSelect()
console = BlzGetFrameByName("ConsoleUI", 0)
bottomUI = BlzFrameGetChild(console, 1)
groupframe = BlzFrameGetChild(bottomUI, 5) //Детей в версии 2.0.3 4
containerFrame = BlzFrameGetChild(groupframe, 0) //Краш игры
по нему можно щелкнуть, запустив FRAMEEVENT_CONTROL_CLICK. К сожалению, это единственное событие, которое доступно этому simple button. А еще нельзя повесить на эту кнопку несколько событий, при регистре событий старое событие заменяется на новое
Можно повесить 3 события точно и не только FRAMEEVENT_CONTROL_CLICK, но и ещё FRAMEEVENT_MOUSE_ENTER, FRAMEEVENT_MOUSE_LEAVE. С остальным не проверял
Соответственно нужно статью обновлять в нескольких разделах
Obelick, спасибо большое за ОС, при следующем обновлении попытаюсь все учесть 😎
Я уже думаю сделать 9 слотов именно где основные:
Проблема скрыть инвентарь основной(пока не решил как сделать это), потому что он исчезает с панелью где и атака, но можно как вариант наложить текстуру , текстуру под ним даже не сдвинуть, я не нашел как к ней подцепится
Моя система сейчас подвязывается абсолютно к любому герою, их не надо заносить в БД, все автоматизировано
Кнопки (7,8,9 слот) тоже идеально считывают Итемы от описания до кастомных характеристик , поэтому сделать 1-6 будет не проблема
Очень хороши подметил что итемы с активной способностью мертвы становятся из за того что помещаются в слоты через кнопки, учту при следующим обновлении
PUVer, некоторые приказы создают утечки на быдло гуи, например, если отдаёшь приказ юниту или группе юнитов отправиться в область, там создаётся точка и группа
63 мб это много и это как раз та штука что у тебя вызывает краш
PUVer, все верно, есть какой то лимит в 256 мб на один регион памяти (предположение)
Касаемо журнала не знаю, не слышал даже о возможной такой причине )
Когда у игры неполучается выделить память, она показывает сообщение об ошибке "Недостаточно памяти для обработки команды".
Произойти это может, если память доступная процессу игры кончилась.
Даже если у вас 64-битный процессор и десятки гигабайт оперативной памяти, игра 32-битная и не может использовать больше 4-ех гигабайт памяти.
А на практике, даже больше 2-ух гигабайт будет проблемно занять, из-за особенности устройства используемых варкрафтом связных списков.
Регионы памяти:
По моим наблюдениям, выделение памяти может также провалиться в случае, когда размер одного региона менеджера памяти достигает лимита, равного примерно 256-ми мегабайтам.Так что, даже если память еще не закончилась, но блоков памяти в одном регионе выделено слишком много, то игра всё равно может крашнуться. Также, могу предположить, что если игра попытается одним куском выделить много памяти (например, 300 МБ), то последствия будут теми же.
По сигнатуре региона можно попытаться догадаться о причине произошедшего.Например, если имя объекта CUnitListNode, то можно заподозрить утечки памяти, связанные с неудаляемыми групами в скрипте карты.
» WarCraft 3 / Список дефолтных фреймов-1. Потомки gameUI
Ну да работа с этим происходит через :
» WarCraft 3 / [2.0.3 vJass] UI - Move Able Frame - Перетаскиваем фрейм мышкой
Надо будет понять есть ли ещё варианты, ну и применить как-то для более идеальной плавности :)
» WarCraft 3 / Список дефолтных фреймов-1. Потомки gameUI
call BlzFrameSetSize(MouseCursor,0.9,0.9)Размер установить мышке нельзя !!!Ред. Smeto
» WarCraft 3 / [2.0.3 vJass] UI - Move Able Frame - Перетаскиваем фрейм мышкой
Скачать версию карты для Warcraft 3 Reforget 2.0.0
» WarCraft 3 / [2.0.3 vJass] UI - Move Able Frame - Перетаскиваем фрейм мышкой
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
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
structMoveAbleFrame MoveAbleFrame
endglobals
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
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameEnter, frame, FRAMEEVENT_MOUSE_ENTER)
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameLeave , frame, FRAMEEVENT_MOUSE_LEAVE)
endfunction
set MoveAbleFrame.Frame = frame
if framePoint == null then
set framePoint = FRAMEPOINT_CENTER
endif
set MoveAbleFrame.FramePoint = framePoint
endfunction
call BJDebugMsg("moveFrame: called x=" + R2S(x) + " y=" + R2S(y))
call BlzFrameClearAllPoints(MoveAbleFrame.Frame)
call BlzFrameSetAbsPoint(MoveAbleFrame.Frame, MoveAbleFrame.FramePoint, x, y)
endfunction
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
set GetTriggerName_DEBUG = "TriggerFrameEnter"
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = BlzGetTriggerFrame()
endif
endfunction
set GetTriggerName_DEBUG = "TriggerFrameLeave"
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = null
endif
endfunction
location moveLoc = Location(0, 0)
boolean flag = false
endglobals
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 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
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
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
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
local real newX = BlzGetTriggerPlayerMouseX()
local real newY = BlzGetTriggerPlayerMouseY()
set GetFunctionName_DEBUG = "OnMouseMove"
set mouseX_prev = mouseX
set mouseY_prev = mouseY
set mouseY = newY
set interpProgress = 0.0
endfunction
local real dist
local real dynamicSpeed
local real dx
local real dy
local real distMouse
call updateDebugFrame()
set GetFunctionName_DEBUG = "update2"
set dx = mouseX - mouseX_prev
set dy = mouseY - mouseY_prev
set distMouse = SquareRoot(dx * dx + dy * dy)
if interpProgress > 1.0 then
set interpProgress = 1.0
endif
set mouseY_interp = mouseY_prev + (mouseY - mouseY_prev) * interpProgress
set targetY = mouseY_interp
set dynamicSpeed = moveSpeed + dist * 0.2
if dynamicSpeed > 0.08 then
set dynamicSpeed = 0.08
endif
set currentY = currentY + (targetY - currentY) * dynamicSpeed
endif
endfunction
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 mouseY_prev = mouseY
set mouseX = ScreenX
set mouseY = ScreenY
set interpProgress = 0.0
endif
endfunction
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.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)
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
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
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
structMoveAbleFrame MoveAbleFrame
endglobals
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
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameEnter, frame, FRAMEEVENT_MOUSE_ENTER)
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameLeave , frame, FRAMEEVENT_MOUSE_LEAVE)
endfunction
set MoveAbleFrame.Frame = frame
if framePoint == null then
set framePoint = FRAMEPOINT_CENTER
endif
set MoveAbleFrame.FramePoint = framePoint
endfunction
call BJDebugMsg("moveFrame: called x=" + R2S(x) + " y=" + R2S(y))
call BlzFrameClearAllPoints(MoveAbleFrame.Frame)
call BlzFrameSetAbsPoint(MoveAbleFrame.Frame, MoveAbleFrame.FramePoint, x, y)
endfunction
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
set GetTriggerName_DEBUG = "TriggerFrameEnter"
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = BlzGetTriggerFrame()
endif
endfunction
set GetTriggerName_DEBUG = "TriggerFrameLeave"
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = null
endif
endfunction
location moveLoc = Location(0, 0)
boolean flag = false
endglobals
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 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
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
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
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
local real newX = BlzGetTriggerPlayerMouseX()
local real newY = BlzGetTriggerPlayerMouseY()
set GetFunctionName_DEBUG = "OnMouseMove"
set mouseX_prev = mouseX
set mouseY_prev = mouseY
set mouseY = newY
set interpProgress = 0.0
endfunction
local real dist
local real dynamicSpeed
local real dx
local real dy
local real distMouse
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)
if interpProgress > 1.0 then
set interpProgress = 1.0
endif
set mouseY_interp = mouseY_prev + (mouseY - mouseY_prev) * interpProgress
set targetY = mouseY_interp
set dynamicSpeed = moveSpeed + dist * 0.1
if dynamicSpeed > 0.05 then
set dynamicSpeed = 0.05
endif
set currentY = currentY + (targetY - currentY) * dynamicSpeed
endif
endfunction
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 mouseY_prev = mouseY
set mouseX = ScreenX
set mouseY = ScreenY
set interpProgress = 0.0
endif
endfunction
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.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)
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
» WarCraft 3 / [2.0.3 vJass] UI - Move Able Frame - Перетаскиваем фрейм мышкой
» Администрация XGM / Проблемы при просмотре видео
На случай если у кого-то проблемы с загрузкой?
» WarCraft 3 / [2.0.3] Как перетаскивать фрейм мышкой?
real moveSpeed = 0.2:
real targetX = 0.0
real targetY = 0.0
real currentX = 0.0
real currentY = 0.0
real moveSpeed = 0.2 При скорости ниже 0.2 получаю сильное отставание от иконки, но невероятную плавность
endglobals
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
structMoveAbleFrame MoveAbleFrame
endglobals
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
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameEnter, frame, FRAMEEVENT_MOUSE_ENTER)
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameLeave , frame, FRAMEEVENT_MOUSE_LEAVE)
endfunction
set MoveAbleFrame.Frame = frame
if framePoint == null then
set framePoint = FRAMEPOINT_CENTER
endif
set MoveAbleFrame.FramePoint = framePoint
endfunction
call BJDebugMsg("moveFrame: called x=" + R2S(x) + " y=" + R2S(y))
call BlzFrameClearAllPoints(MoveAbleFrame.Frame)
call BlzFrameSetAbsPoint(MoveAbleFrame.Frame, MoveAbleFrame.FramePoint, x, y)
endfunction
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = BlzGetTriggerFrame()
endif
endfunction
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = null
endif
endfunction
location moveLoc = Location(0, 0)
boolean flag = false
endglobals
local player p = GetTriggerPlayer()
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
local real z
set z = GetLocationZ(moveLoc) Получаем Z-координату
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
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
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
if flag == true then
Плавное приближение к целевой позиции
set currentX = currentX + (targetX - currentX) * moveSpeed
set currentY = currentY + (targetY - currentY) * moveSpeed
endif
endfunction
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
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.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)
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
» WarCraft 3 / [2.0.3 vJass] UI - Move Able Frame - Перетаскиваем фрейм мышкой
» WarCraft 3 / [2.0.3 vJass] UI - Move Able Frame - Перетаскиваем фрейм мышкой
array в параметрах функций нельзя))
Что за нейронка? на Deepseek и ChatGPT не похожа )
» WarCraft 3 / [2.0.3] Как перетаскивать фрейм мышкой?
» WarCraft 3 / [2.0.3] Как перетаскивать фрейм мышкой?
» WarCraft 3 / GetMainSelectedUnit
В любом случае я проверил твой код, он является более предпочтительным, он гораздо меньше, что здорово
» WarCraft 3 / GetMainSelectedUnit
Ред. Smeto
» WarCraft 3 / GetMainSelectedUnit
» WarCraft 3 / [2.0.2 vjass] Инвентарь на фреймах 9 слотов (+3 слота)
» WarCraft 3 / SIMPLEBUTTON (кнопка пользовательского интерфейса)
» WarCraft 3 / [2.0.2 vjass] Инвентарь на фреймах 9 слотов (+3 слота)
Ред. Smeto
» WarCraft 3 / [2.0.2 vjass] Инвентарь на фреймах 9 слотов (+3 слота)
Ред. Smeto
» WarCraft 3 / [2.0.2 vjass] Инвентарь на фреймах 9 слотов (+3 слота)
» WarCraft 3 / [2.0.2 vjass] Инвентарь на фреймах 9 слотов (+3 слота)
» WarCraft 3 / Data Chunk Fatal Error
» WarCraft 3 / Data Chunk Fatal Error
Снимаем защиту с процесса игры xgm.guru/p/wc3/jass-view#h1
Ред. Smeto
» WarCraft 3 / Data Chunk Fatal Error
Касаемо журнала не знаю, не слышал даже о возможной такой причине )
» WarCraft 3 / Data Chunk Fatal Error
Произойти это может, если память доступная процессу игры кончилась.
Даже если у вас 64-битный процессор и десятки гигабайт оперативной памяти, игра 32-битная и не может использовать больше 4-ех гигабайт памяти.
А на практике, даже больше 2-ух гигабайт будет проблемно занять, из-за особенности устройства используемых варкрафтом связных списков.
По моим наблюдениям, выделение памяти может также провалиться в случае, когда размер одного региона менеджера памяти достигает лимита, равного примерно 256-ми мегабайтам.Так что, даже если память еще не закончилась, но блоков памяти в одном регионе выделено слишком много, то игра всё равно может крашнуться. Также, могу предположить, что если игра попытается одним куском выделить много памяти (например, 300 МБ), то последствия будут теми же.
По сигнатуре региона можно попытаться догадаться о причине произошедшего.Например, если имя объекта CUnitListNode, то можно заподозрить утечки памяти, связанные с неудаляемыми групами в скрипте карты.