Obelick, так не работает. Удаляет не сразу, есть микро-задержка. но дебаг срабатывает, почему же спецэффект не удаляется то?
пример
TriggerRegisterDeathEvent(DeleteEffects, d)
QueueOrders.EffectObjects[GetHandleId(d)]= QueueOrders.EffectWayPoint[h][NumberOrder]
local DeleteEffects = CreateTrigger()
TriggerAddAction(DeleteEffects,function()
print("декорация мертва")
local h = GetHandleId(GetTriggerWidget())
DestroyEffect(QueueOrders.EffectObjects[h])
end)
здесь система с очередью приказов. При зажатии на SHIFT вы можете записать триггерами приказы/цели и пр.
полный код
do
local InitGlobalsOrigin = InitGlobals -- хукаем функцию InitGlobals
function InitGlobals()
InitGlobalsOrigin()
--работа с фреймами
function LoadToc(s)
if BlzLoadTOCFile(s) then
print("Loaded: "..s)
else
print("Failed to Load: "..s)
end
end
function ShowInterfaceE()
LoadToc("templates.toc")
--перед созданием юнита отключаем триггер на отлов приказа, тк при создании юнит получает приказ stop. при получении приказа триггер добавляет в структуру
DisableTrigger(detectedtrigger1)
trigger1_enabled = false
local unit = CreateUnit(Player(0), FourCC("hfoo"), 0, 0, 0)
EnableTrigger(detectedtrigger1)
trigger1_enabled = true
SelectUnitSingle(unit)
TimerStart(CreateTimer(), 0.3, false, function()
--создаем консольные текстуры (по сути переделанная в fdf-file ConsoleUI - убраны бока)
local framehandle Console = BlzCreateFrameByType("SIMPLEFRAME","MyConsole",BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0),"MyConsole",0)
--показать ConsoleUIBackdrop (при инициализации почему-то не показывается, только во время игры) w=0.8 h=0.13
BlzFrameClearAllPoints(BlzGetFrameByName("ConsoleUIBackdrop",0))
BlzFrameSetAbsPoint(BlzGetFrameByName("ConsoleUIBackdrop",0), FRAMEPOINT_BOTTOMLEFT, 0.0, 0.0)
--снова возвращаем Portrait на место w=0.06 h=0.08
BlzFrameSetVisible(BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT,0), true)
--BlzFrameClearAllPoints(BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT,0))
--BlzFrameSetAbsPoint(BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT,0), FRAMEPOINT_BOTTOMLEFT, 0.26, 0.03)
--показать Portrait HP/MANA (показываются тексты, когда выделен юнит) text w=0.06 h=0,016
local hpFrame = BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT_HP_TEXT, 0)
BlzFrameClearAllPoints(hpFrame)
BlzFrameSetAbsPoint(hpFrame, FRAMEPOINT_CENTER, 0.253, 0.024)
local mpFrame = BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT_MANA_TEXT, 0)
BlzFrameClearAllPoints(mpFrame)
BlzFrameSetAbsPoint(mpFrame, FRAMEPOINT_CENTER, 0.253, 0.008)
--центральная информационная панель
local BottomCenterUI = BlzFrameGetChild(BlzGetFrameByName("ConsoleUI",0),1)
--BlzFrameSetVisible(BottomCenterUI, true)
BlzFrameClearAllPoints(BottomCenterUI)
BlzFrameSetAbsPoint(BottomCenterUI, FRAMEPOINT_CENTER, 0.4025,0.0583)
--контейнер кнопки неактивного рабочего W=0.039 h=0.039 (Idle worker Button Container)
BlzFrameSetVisible(BlzFrameGetChild(BlzGetFrameByName("ConsoleUI",0),7), true)
BlzFrameClearAllPoints(BlzFrameGetChild(BlzGetFrameByName("ConsoleUI",0),7))
BlzFrameSetAbsPoint(BlzFrameGetChild(BlzGetFrameByName("ConsoleUI",0),7), FRAMEPOINT_BOTTOMLEFT, 0.0, 0.17)
--мини-карта w=0.139375 h=0.138125
BlzFrameClearAllPoints(BlzGetFrameByName("MiniMapFrame",0))
BlzFrameSetAbsPoint(BlzGetFrameByName("MiniMapFrame",0), FRAMEPOINT_BOTTOMLEFT, 0.009375, 0.006875)
--мини-кнопки w=0.023125 h=0.020625*5
BlzFrameClearAllPoints(BlzGetFrameByName("MinimapSignalButton",0))
BlzFrameSetAbsPoint(BlzGetFrameByName("MinimapSignalButton",0), FRAMEPOINT_TOPLEFT, 0.154375, 0.14375)
BlzFrameClearAllPoints(BlzGetFrameByName("MiniMapTerrainButton",0))
BlzFrameSetAbsPoint(BlzGetFrameByName("MiniMapTerrainButton",0), FRAMEPOINT_TOPLEFT, 0.154375, 0.121875)
BlzFrameClearAllPoints(BlzGetFrameByName("MiniMapAllyButton",0))
BlzFrameSetAbsPoint(BlzGetFrameByName("MiniMapAllyButton",0), FRAMEPOINT_TOPLEFT, 0.154375, 0.1)
BlzFrameClearAllPoints(BlzGetFrameByName("MiniMapCreepButton",0))
BlzFrameSetAbsPoint(BlzGetFrameByName("MiniMapCreepButton",0), FRAMEPOINT_TOPLEFT, 0.154375, 0.0775)
BlzFrameClearAllPoints(BlzGetFrameByName("FormationButton",0))
BlzFrameSetAbsPoint(BlzGetFrameByName("FormationButton",0), FRAMEPOINT_TOPLEFT, 0.154375, 0.05)
--коммандная панель w=0.1745 h=0.129
BlzFrameClearAllPoints(BlzGetFrameByName("CommandBarFrame",0))
BlzFrameSetAbsPoint(BlzGetFrameByName("CommandBarFrame",0), FRAMEPOINT_CENTER, 0.7+0.0048, 0.146/2-0.0045)
--панель SimpleInventoryCover w = 0.128 h = 0.175
local InventoryCover = BlzFrameGetChild(BottomCenterUI,7)
--BlzFrameSetVisible(InventoryCover, true)
BlzFrameClearAllPoints(InventoryCover)
BlzFrameSetAbsPoint(InventoryCover, FRAMEPOINT_BOTTOMRIGHT, 0.6, 0.0)
GroupRemoveUnit(QueueOrders.Group,unit)
RemoveUnit(unit)
print("done")
DestroyTimer(GetExpiredTimer())
end)
end
--библиотека скалирования экранных координат от разрешения монитора
function PXTODPI()
return 0.6 / BlzGetLocalClientHeight()
end
function DPITOPX()
return BlzGetLocalClientHeight() / 0.6
end
function FrameBoundWidth()
return (BlzGetLocalClientWidth()-BlzGetLocalClientHeight()/600*800)/2
end
--тут ставим разрешение экрана типа 1920x1080, то в GetScreenPosX(1920)
function GetScreenPosX(x)
return (-FrameBoundWidth()+x)*PXTODPI()
end
function GetScreenPosY(y)
return y*PXTODPI()
end
--0.4 -> 0.3
function ScreenRelativeX(x)
return (x * DPITOPX()) * (0.8/BlzGetLocalClientWidth())
end
function ScreenRelativeX2(x)
return GetScreenPosX((((x^2)^0.5)/1.088)*BlzGetLocalClientWidth())
end
--инициируем игру
--прячем консоль (консольные текстуры вместе с потомками перемещены за пределы экрана, и мы их не видим)
BlzFrameSetAbsPoint(BlzGetFrameByName("ConsoleUI", 0), FRAMEPOINT_BOTTOM, 0.4, -0.18)
--Portrait не прячется, но в начале прячем. Тк не красиво будет, тк задержка появления нижней консоли. задержка создана из-за дурацких текстов под портретом
BlzFrameSetVisible(BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT,0), false)
--BlzFrameClearAllPoints(BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT,0))
--BlzFrameSetAbsPoint(BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT,0), FRAMEPOINT_BOTTOM, 0.4, -0.18)
--прячем неактивную кнопку рабочего
BlzFrameSetVisible(BlzFrameGetChild(BlzGetFrameByName("ConsoleUI",0),7), false)
--отображаем нужные элементы
ShowInterfaceE()
--скрываем мертвую рамку коммандной панели
BlzFrameSetScale(BlzFrameGetChild(BlzGetFrameByName("ConsoleUI",0),5), 0.001)
--чекаем отпускание Shift
--https://www.hiveworkshop.com/threads/oskey-player-key-event.319903/
local ShiftOn = 0
TimerStart(CreateTimer(),0,false, function()
print("Create Keys")
for index = 8,255 do
local trigger = CreateTrigger()
TriggerAddAction(trigger, function()
if index == 160 and ShiftOn ~= BlzGetTriggerPlayerMetaKey() then
if BlzGetTriggerPlayerMetaKey() == 1 then
ShiftOn = 1
print("Shift нажат")
elseif BlzGetTriggerPlayerMetaKey() == 0 then
ShiftOn = 0
print("Shift отпущен")
end
--if GetLocalPlayer() ~= nil then
-- ShiftOn = BlzGetTriggerPlayerMetaKey()
--end
end
--print("OsKey:",index, "meta",BlzGetTriggerPlayerMetaKey())
end)
local key = ConvertOsKeyType(index)
for metaKey = 0,15,1 do
BlzTriggerRegisterPlayerKeyEvent(trigger, Player(0), key, metaKey, true)
BlzTriggerRegisterPlayerKeyEvent(trigger, Player(0), key, metaKey, false)
end
end
print("Done")
print("Press Keys to show the index of that oskey and its metakey")
end)
--чекаем принадлежность курсора в игровом поле
local cursorInGame = true
TimerStart(CreateTimer(),0.0, false,function()
local parent = BlzGetFrameByName("ConsoleUIBackdrop", 0)
local gameUI = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)
DestroyTimer(GetExpiredTimer())
local Screen = BlzCreateFrameByType("FRAME", "FaceFrame", parent, "", 0)
--левая центральная
local ScreenFrame1 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", Screen, "ScriptDialogButton", 0)
BlzFrameSetAlpha(ScreenFrame1, 50)
BlzFrameSetAbsPoint(ScreenFrame1, FRAMEPOINT_CENTER, 0.1,0.154+((0.416)/2))
BlzFrameSetSize(ScreenFrame1, 0.2, 0.416)
--центральная
local ScreenFrame2 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", Screen, "ScriptDialogButton", 0)
BlzFrameSetAlpha(ScreenFrame2, 50)
BlzFrameSetAbsPoint(ScreenFrame2, FRAMEPOINT_CENTER, 0.4,0.128+((0.442)/2))
BlzFrameSetSize(ScreenFrame2, 0.4, 0.442)
--правая центральная
local ScreenFrame3 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", Screen, "ScriptDialogButton", 0)
BlzFrameSetAlpha(ScreenFrame3, 50)
BlzFrameSetAbsPoint(ScreenFrame3, FRAMEPOINT_CENTER, 0.7,0.154+((0.416)/2))
BlzFrameSetSize(ScreenFrame3, 0.2, 0.416)
--левая боковая
local ScreenFrame4 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", Screen, "ScriptDialogButton", 0)
BlzFrameSetAlpha(ScreenFrame4, 50)
BlzFrameSetAbsPoint(ScreenFrame4, FRAMEPOINT_CENTER, -0.144/2,(0.164+0.410)/2)
BlzFrameSetSize(ScreenFrame4, 0.144, 0.164+0.410)
--правая боковая
local ScreenFrame5 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", Screen, "ScriptDialogButton", 0)
BlzFrameSetAlpha(ScreenFrame5, 50)
BlzFrameSetAbsPoint(ScreenFrame5, FRAMEPOINT_CENTER, 0.8+0.144/2,(0.164+0.410)/2)
BlzFrameSetSize(ScreenFrame5, 0.144, 0.164+0.410)
local Sreentools = BlzCreateFrameByType("FRAME", "FaceFrame", parent, "", 0)
BlzFrameSetAlpha(Sreentools, 0)
BlzFrameSetAbsPoint(Sreentools, FRAMEPOINT_BOTTOMLEFT, 0, 0)
BlzFrameSetSize(Sreentools, 0, 0)
BlzFrameSetTooltip(ScreenFrame1, Sreentools)
BlzFrameSetTooltip(ScreenFrame2, Sreentools)
BlzFrameSetTooltip(ScreenFrame3, Sreentools)
BlzFrameSetTooltip(ScreenFrame4, Sreentools)
BlzFrameSetTooltip(ScreenFrame5, Sreentools)
local InterfaceField = BlzCreateFrameByType("FRAME", "FaceFrame", gameUI, "", 0)
--левая нижняя панель
local Interface1 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", InterfaceField, "ScriptDialogButton", 0)
BlzFrameSetAlpha(Interface1, 50)
BlzFrameSetAbsPoint(Interface1, FRAMEPOINT_CENTER, 0.1, 0.144/2)
BlzFrameSetSize(Interface1, 0.2, 0.154) --0.176
--центральная панель
local Interface2 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", InterfaceField, "ScriptDialogButton", 0)
BlzFrameSetAlpha(Interface2, 50)
BlzFrameSetAbsPoint(Interface2, FRAMEPOINT_CENTER, 0.4, 0.118/2)
BlzFrameSetSize(Interface2, 0.4, 0.128) --0.15
--правая нижняя панель
local Interface3 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", InterfaceField, "ScriptDialogButton", 0)
BlzFrameSetAlpha(Interface3, 50)
BlzFrameSetAbsPoint(Interface3, FRAMEPOINT_CENTER, 0.7, 0.146/2)
BlzFrameSetSize(Interface3, 0.2, 0.154) --0.176
--верхняя панель
local Interface4 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(Interface4, 50)
BlzFrameSetAbsPoint(Interface4, FRAMEPOINT_CENTER, 0.4, 0.6-(0.026/2))
BlzFrameSetSize(Interface4, 1.088, 0.026) --0.176
local Interfacetools = BlzCreateFrameByType("FRAME", "FaceFrame", parent, "", 0)
BlzFrameSetAlpha(Interfacetools, 0)
BlzFrameSetAbsPoint(Interfacetools, FRAMEPOINT_BOTTOMLEFT, 0, 0)
BlzFrameSetSize(Interfacetools, 0, 0)
BlzFrameSetTooltip(Interface1, Interfacetools)
BlzFrameSetTooltip(Interface2, Interfacetools)
BlzFrameSetTooltip(Interface3, Interfacetools)
BlzFrameSetTooltip(Interface4, Interfacetools)
TimerStart(CreateTimer(),1/64, true,function()
if BlzFrameIsVisible(Sreentools) then
--print("курсор в игровом поле")
BlzFrameSetVisible(ScreenFrame1,false)
BlzFrameSetVisible(ScreenFrame2,false)
BlzFrameSetVisible(ScreenFrame3,false)
BlzFrameSetVisible(ScreenFrame4,false)
BlzFrameSetVisible(ScreenFrame5,false)
BlzFrameSetVisible(InterfaceField,true)
if GetLocalPlayer() ~= nil then
cursorInGame = true
end
elseif BlzFrameIsVisible(Interfacetools) or BlzFrameIsVisible(BlzGetOriginFrame(ORIGIN_FRAME_UBERTOOLTIP,0)) then
--print("курсор в поле интерфейса")
BlzFrameSetVisible(ScreenFrame1,true)
BlzFrameSetVisible(ScreenFrame2,true)
BlzFrameSetVisible(ScreenFrame3,true)
BlzFrameSetVisible(ScreenFrame4,true)
BlzFrameSetVisible(ScreenFrame5,true)
BlzFrameSetVisible(InterfaceField,false)
if GetLocalPlayer()~=nil then
cursorInGame = false
end
end
end)
end)
--функции поиска юнита интерфейса
-- returns the local current main selected unit, using it in a sync gamestate relevant manner breaks the game.
function GetMainSelectedUnitEx()
return GetMainSelectedUnit(GetSelectedUnitIndex())
end
local containerFrame
local frames = {}
local group
local units = {}
local filterGS = Filter(function()
local unit = GetFilterUnit()
local prio = BlzGetUnitRealField(unit, UNIT_RF_PRIORITY)
local found = false
-- compare the current unit with allready found, to place it in the right slot
for index, value in ipairs(units) do
-- higher prio than this take it's slot
if BlzGetUnitRealField(value, UNIT_RF_PRIORITY) < prio then
table.insert(units, index, unit)
found = true
break
-- equal prio and better colisions Value
elseif BlzGetUnitRealField(value, UNIT_RF_PRIORITY) == prio and GetUnitOrderValue(value) > GetUnitOrderValue(unit) then
table.insert( units, index, unit)
found = true
break
end
end
-- not found add it at the end
if not found then
table.insert(units, unit)
end
unit = nil
return false
end)
function GetSelectedUnitIndex()
-- local player is in group selection?
if BlzFrameIsVisible(containerFrame) then
-- find the first visible yellow Background Frame
for int = 0, #frames do
if BlzFrameIsVisible(frames[int]) then
return int
end
end
end
return nil
end
function GetUnitOrderValue(unit)
--heroes use the handleId
if IsUnitType(unit, UNIT_TYPE_HERO) then
return GetHandleId(unit)
else
--units use unitCode
return GetUnitTypeId(unit)
end
end
function GetMainSelectedUnit(index)
if index then
GroupEnumUnitsSelected(group, GetLocalPlayer(), filterGS)
local unit = units[index + 1]
--clear table
repeat until not table.remove(units)
return unit
else
GroupEnumUnitsSelected(group, GetLocalPlayer(), nil)
return FirstOfGroup(group)
end
end
--init
local console = BlzGetFrameByName("ConsoleUI", 0)
local bottomUI = BlzFrameGetChild(console, 1)
local groupframe = BlzFrameGetChild(bottomUI, 5)
local LastMainSelectedUnit
local NewMainSelectedUnit
--globals
containerFrame = BlzFrameGetChild(groupframe, 0)
group = CreateGroup()
-- give this frames a handleId
for int = 0, BlzFrameGetChildrenCount(containerFrame) - 1 do
local buttonContainer = BlzFrameGetChild(containerFrame, int)
frames[int] = BlzFrameGetChild(buttonContainer, 0)
end
--demo
TimerStart(CreateTimer(), 0.0299, true, function()
NewMainSelectedUnit = GetMainSelectedUnit(GetSelectedUnitIndex())
if not (NewMainSelectedUnit==LastMainSelectedUnit) then
--Build_Button()
LastMainSelectedUnit = NewMainSelectedUnit
print(GetUnitName(NewMainSelectedUnit))
end
end)
local getTerrainZ = function(x,y)
MoveLocation(zTesterLocation, x, y)
return GetLocationZ(zTesterLocation)
end
local _GetUnitZ = function(u)
return GetUnitFlyHeight(u) + getTerrainZ(GetUnitX(u), GetUnitY(u))
end
local _SetUnitZ = function(u, z)
SetUnitFlyHeight(u, z - getTerrainZ(GetUnitX(u), GetUnitY(u)), 0)
end
local _GetItemZ = function(i)
return getTerrainZ(GetItemX(u), GetItemY(u))
end
function GetDestructableZ(d)
return getTerrainZ(GetDestructableX(d), GetDestructableY(d))
end
--нажимание кнопки мыши во время Shift
local clicking_the_mouse_button = 0
local trigger1_enabled = true
local trigger = CreateTrigger()
TriggerRegisterPlayerMouseEventBJ( trigger, Player(0), bj_MOUSEEVENTTYPE_DOWN )
local b = Condition(function()
return( BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT )and(ShiftOn==1)and cursorInGame --and GetUnitCurrentOrder(Paladin)>0
end)
TriggerAddCondition(trigger, b)
TriggerAddAction( trigger, function ()
clicking_the_mouse_button = 1
print("нажатие ПКМ")
trigger1_enabled = false
--DisableTrigger(detectedtrigger1)
--PauseUnit( LastMainSelectedUnit, true )
--BlzPauseUnitEx( LastMainSelectedUnit, true )
--SetUnitPosition(LastMainSelectedUnit,GetUnitX(LastMainSelectedUnit),GetUnitY(LastMainSelectedUnit))
IssueImmediateOrderById( LastMainSelectedUnit, 851972 ) --stop 851972
--BlzPauseUnitEx( LastMainSelectedUnit, false )
--PauseUnit( LastMainSelectedUnit, false )
--EnableTrigger(detectedtrigger1)
trigger1_enabled = true
end)
function DeleteUnit(u)
if u ~= nil then
RemoveUnit(u)
end
end
--отслеживаем приказы
--база данных
local QueueOrders = {}
QueueOrders.Group = CreateGroup() --группа
QueueOrders.CurrentNumberOrder = {} --текущий номер приказа
QueueOrders.CountOrders = {} --кол-во приказов
QueueOrders.EffectWayPoint = {}
QueueOrders.UnitWayPoint = {}
QueueOrders.EffectObjects = {}
--QueueOrders.UnitY = {}
--двумерные таблицы [handle][number of order]
--тип приказа: без цели, таргет-объект или таргет-объект (чтобы знать какие нативки использовать)
QueueOrders.TypeOrder = {}
QueueOrders.TypeTarget = {}
--либо таргет-объект
QueueOrders.TargetOrderObject = {}
--или таргет-точка
QueueOrders.TargetPointOrderX = {}
QueueOrders.TargetPointOrderY = {}
--тип объекта (по id можно получить название типа с GetObjectName)
QueueOrders.TargetOrderTypeObject = {}
--id приказ
QueueOrders.Order = {}
--GroupAddUnit(QueueOrders.Group,Paladin)
local DeleteEffects = CreateTrigger()
TriggerAddAction(DeleteEffects,function()
print("декорация мертва")
local h = GetHandleId(GetTriggerWidget())
DestroyEffect(QueueOrders.EffectObjects[h])
end)
--QueueOrders.UnitWayPoint[h][NumberOrder] =CrateUnitWayPoint(GetTriggerPlayer())
function CrateUnitWayPoint(p)
local u = nil
if GetPlayerRace(p) == RACE_HUMAN then
u = CreateUnit(p,FourCC('h000'),GetOrderPointX(),GetOrderPointY(),0)
elseif GetPlayerRace(p) == RACE_ORC then
u = CreateUnit(p,FourCC('o000'),GetOrderPointX(),GetOrderPointY(),0)
elseif GetPlayerRace(p) == RACE_NIGHTELF then
u = CreateUnit(p,FourCC('n000'),GetOrderPointX(),GetOrderPointY(),0)
elseif GetPlayerRace(p) == RACE_UNDEAD then
u = CreateUnit(p,FourCC('u000'),GetOrderPointX(),GetOrderPointY(),0)
end
if not GetLocalPlayer()==p then
ShowUnit(u, false)
end
--TimerStart(CreateTimer(),0.00,false,function()
-- UnitAddAbility(u,FourCC('Aloc'))
-- --UnitRemoveAbility(u,FourCC('Aloc'))
--end)
--BlzSetUnitBooleanFieldBJ( u, UNIT_BF_SELECTION_CIRCLE_ON_WATER, false )
return u
end
--local effect = CrateEffectWayPoint(GetTriggerPlayer())
function CrateEffectWayPoint(p)
if GetLocalPlayer()==p then
if GetPlayerRace(p) == RACE_HUMAN then
return "UI\\Feedback\\WaypointFlags\\WaypointFlag.mdl"
elseif GetPlayerRace(p) == RACE_ORC then
return "UI\\Feedback\\WaypointFlags\\OrcWaypointFlag.mdl"
elseif GetPlayerRace(p) == RACE_NIGHTELF then
return "UI\\Feedback\\WaypointFlags\\NightElfWaypointFlag.mdl"
elseif GetPlayerRace(p) == RACE_UNDEAD then
return "UI\\Feedback\\WaypointFlags\\UndeadWaypointFlag.mdl"
end
end
end
function DestroyWayPointFlags(max)
--удаляем спецэффекты пред приказов, если они были
for a = 1,max do
if QueueOrders.TypeOrder[h][a]==1 then
DeleteUnit(QueueOrders.UnitWayPoint[h][a])
elseif QueueOrders.TypeOrder[h][a]==2 or QueueOrders.TypeOrder[h][a]==3 then
DeleteUnit(QueueOrders.UnitWayPoint[h][a])
end
end
end
TimerStart(CreateTimer(),0.03,true,function()
local count = BlzGroupGetSize(QueueOrders.Group)
if count > 0 then
--for i = -1, count do
for i=count-1,0,-1 do
local u = BlzGroupUnitAt(QueueOrders.Group, i)
local h = GetHandleId(u)
local current_target = QueueOrders.TargetOrderObject[h][1]
local type_order = QueueOrders.TypeOrder[h][1]
local type_target = QueueOrders.TypeTarget[h][1]
print(i..") "..GetUnitName(u)..", кол-во приказов: "..QueueOrders.CountOrders[GetHandleId(u)])
if GetUnitCurrentOrder(u) == 0 then --or (GetWidgetLife(current_target) <= 0 and type_order==1) then -- or GetUnitCurrentOrder(u) == 851972 then
if QueueOrders.CountOrders[h] <= 1 then
local type_order = QueueOrders.TypeOrder[h][1]
local type_target = QueueOrders.TypeTarget[h][1]
if type_target == 1 then
DestroyEffect(QueueOrders.EffectWayPoint[h][1])
elseif type_target == 2 then
DeleteUnit(QueueOrders.UnitWayPoint[h][1])
end
--обнуляем текущий приказ
QueueOrders.CurrentNumberOrder[h]=0
--обнуляем счетчик приказов
QueueOrders.CountOrders[h]=0
elseif QueueOrders.CountOrders[h] > 1 then
--QueueOrders.CurrentNumberOrder[h]=1
local type_order = QueueOrders.TypeOrder[h][1]
local type_target = QueueOrders.TypeTarget[h][1]
if type_target == 1 then
DestroyEffect(QueueOrders.EffectWayPoint[h][1])
elseif type_target == 2 then
DeleteUnit(QueueOrders.UnitWayPoint[h][1])
end
for a = 1,QueueOrders.CountOrders[h] do
QueueOrders.TargetOrderObject[h][a] = QueueOrders.TargetOrderObject[h][a+1]
QueueOrders.TargetPointOrderX[h][a] = QueueOrders.TargetPointOrderX[h][a+1]
QueueOrders.TargetPointOrderY[h][a] = QueueOrders.TargetPointOrderY[h][a+1]
QueueOrders.TargetOrderTypeObject[h][a] = QueueOrders.TargetOrderTypeObject[h][a+1]
QueueOrders.Order[h][a]=QueueOrders.Order[h][a+1]
QueueOrders.TypeOrder[h][a]=QueueOrders.TypeOrder[h][a+1]
QueueOrders.TypeTarget[h][a]=QueueOrders.TypeTarget[h][a+1]
QueueOrders.EffectWayPoint[h][a]=QueueOrders.EffectWayPoint[h][a+1]
QueueOrders.UnitWayPoint[h][a]=QueueOrders.UnitWayPoint[h][a+1]
end
QueueOrders.CountOrders[h]=QueueOrders.CountOrders[h]-1
--QueueOrders.CurrentNumberOrder[h]=1
local CurrentOrder = 1
local type_order = QueueOrders.TypeOrder[h][CurrentOrder]
local id_order = QueueOrders.Order[h][CurrentOrder]
local id_object = QueueOrders.TargetOrderTypeObject[h][CurrentOrder]
if type_order == 1 then
local target = QueueOrders.TargetOrderObject[h][CurrentOrder]
DisableTrigger(detectedtrigger1)
trigger1_enabled = false
IssueTargetOrderById(u,id_order, target)
--DestroyEffect(QueueOrders.EffectWayPoint[h][CurrentOrder])
trigger1_enabled = true
EnableTrigger(detectedtrigger1)
print("|cffa6373a"..GetUnitName(u).." перенаправляет "..type_order.."-приказ "..OrderId2String(id_order).." в цель "..id_object.."|r")
elseif type_order == 2 then
local x = QueueOrders.TargetPointOrderX[h][CurrentOrder]
local y = QueueOrders.TargetPointOrderY[h][CurrentOrder]
DisableTrigger(detectedtrigger1)
trigger1_enabled = false
IssuePointOrderById(u,id_order, x,y)
--DeleteUnit(QueueOrders.UnitWayPoint[h][CurrentOrder])
trigger1_enabled = true
EnableTrigger(detectedtrigger1)
print("|cffa6373a"..GetUnitName(u).." перенаправляет "..type_order.."-приказ "..OrderId2String(id_order).." в точку "..x..","..y.."|r")
elseif type_order == 3 then
local x = QueueOrders.TargetPointOrderX[h][CurrentOrder]
local y = QueueOrders.TargetPointOrderY[h][CurrentOrder]
DisableTrigger(detectedtrigger1)
trigger1_enabled = false
IssueBuildOrderById(u,id_order, x,y)
--DeleteUnit(QueueOrders.UnitWayPoint[h][CurrentOrder])
trigger1_enabled = true
EnableTrigger(detectedtrigger1)
print("|cffa6373a"..GetUnitName(u).." перенаправляет "..type_order.."-приказ "..OrderId2StringBJ(id_order).." строить в точке "..x..","..y.."|r")
elseif type_order == 4 then
DisableTrigger(detectedtrigger1)
trigger1_enabled = false
IssueImmediateOrderById(u,id_order)
trigger1_enabled = true
EnableTrigger(detectedtrigger1)
print("|cffa6373a"..GetUnitName(u).." перенаправляет "..type_order.."-приказ "..OrderId2StringBJ(id_order).."|r")
end
end
end
end
end
end)
--получаем текущий приказ
local detectedtrigger1 = CreateTrigger()
TriggerRegisterPlayerUnitEventSimple( detectedtrigger1, Player(0), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
TriggerRegisterPlayerUnitEventSimple( detectedtrigger1, Player(0), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
TriggerRegisterPlayerUnitEventSimple( detectedtrigger1, Player(0), EVENT_PLAYER_UNIT_ISSUED_ORDER )
local gb1 = Condition(function()
return trigger1_enabled --and (clicking_the_mouse_button==0)
end)
TriggerAddCondition(detectedtrigger1, gb1)
TriggerAddAction(detectedtrigger1, function()
local h = GetHandleId(GetTriggerUnit())
local id
--инициируем таблицы для юнита
if not IsUnitInGroup(GetTriggerUnit(),QueueOrders.Group)then--QueueOrders.Order[h] == nil then
QueueOrders.Order[h]={}
QueueOrders.TargetOrderObject[h]={}
QueueOrders.TargetOrderTypeObject[h] = {}
QueueOrders.TypeTarget[h] = {}
QueueOrders.TargetPointOrderX[h] = {}
QueueOrders.TargetPointOrderY[h] = {}
QueueOrders.TypeOrder[h] = {}
QueueOrders.EffectWayPoint[h] = {}
QueueOrders.UnitWayPoint[h] = {}
QueueOrders.CountOrders[h]=0
GroupAddUnit(QueueOrders.Group,GetTriggerUnit())
end
--получаем тек приказ
local count = QueueOrders.CountOrders[h]
if (ShiftOn==0) or (ShiftOn>0 and count==0) then
DestroyWayPointFlags(QueueOrders.CountOrders[h])
if GetTriggerEventId()==EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER then
local NumberOrder = 1
QueueOrders.TargetOrderObject[h][NumberOrder] = GetOrderTarget()
QueueOrders.TargetPointOrderX[h][NumberOrder] = nil
QueueOrders.TargetPointOrderY[h][NumberOrder] = nil
QueueOrders.Order[h][NumberOrder]=GetIssuedOrderId()
QueueOrders.TypeOrder[h][NumberOrder]=1
QueueOrders.CurrentNumberOrder[h]=NumberOrder
QueueOrders.CountOrders[h]=NumberOrder
if GetOrderTargetUnit() ~= nil then
id = GetUnitTypeId(GetOrderTargetUnit())
QueueOrders.TargetOrderTypeObject[h][NumberOrder] = GetObjectName(id)
print("|cff00b899"..GetUnitName(GetTriggerUnit()).." получил тек приказ "..OrderId2String(GetIssuedOrderId()).." в цель "..GetObjectName(id).."|r")
elseif GetOrderTargetDestructable() ~= nil then
QueueOrders.TargetOrderTypeObject[h][NumberOrder] = GetDestructableName(GetOrderTargetDestructable())
print("|cff00b899"..GetUnitName(GetTriggerUnit()).." получил тек приказ "..OrderId2String(GetIssuedOrderId()).." в цель "..GetDestructableName(GetOrderTargetDestructable()).."|r")
elseif GetOrderTargetItem() ~= nil then
id = GetItemTypeId(GetOrderTargetItem())
QueueOrders.TargetOrderTypeObject[h][NumberOrder] = GetObjectName(id)
print("|cff00b899"..GetUnitName(GetTriggerUnit()).." получил тек приказ "..OrderId2String(GetIssuedOrderId()).." в цель "..GetObjectName(id).."|r")
end
elseif GetTriggerEventId()==EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER then
local NumberOrder = 1
QueueOrders.TargetOrderObject[h][NumberOrder] = nil
QueueOrders.TargetPointOrderX[h][NumberOrder] = GetOrderPointX()
QueueOrders.TargetPointOrderY[h][NumberOrder] = GetOrderPointY()
QueueOrders.Order[h][NumberOrder]=GetIssuedOrderId()
if GetIssuedOrderId()>850000 and GetIssuedOrderId()<860000 then
QueueOrders.TypeOrder[h][NumberOrder]=2
print("|cff00b899"..GetUnitName(GetTriggerUnit()).." получил тек приказ "..OrderId2String(GetIssuedOrderId()).." в точку "..GetOrderPointX()..","..GetOrderPointY().."|r")
else
QueueOrders.TypeOrder[h][NumberOrder]=3
print("|cff00b899"..GetUnitName(GetTriggerUnit()).." получил тек приказ строить "..OrderId2String(GetIssuedOrderId()).." в точку "..GetOrderPointX()..","..GetOrderPointY().."|r")
end
QueueOrders.CurrentNumberOrder[h]=NumberOrder
QueueOrders.CountOrders[h]=NumberOrder
elseif GetTriggerEventId()==EVENT_PLAYER_UNIT_ISSUED_ORDER then
local NumberOrder = 1
QueueOrders.TargetOrderObject[h][NumberOrder] = nil
QueueOrders.TargetPointOrderX[h][NumberOrder] = nil
QueueOrders.TargetPointOrderY[h][NumberOrder] = nil
QueueOrders.Order[h][NumberOrder]=GetIssuedOrderId()
QueueOrders.TypeOrder[h][NumberOrder]=4
QueueOrders.CurrentNumberOrder[h]=NumberOrder
QueueOrders.CountOrders[h]=NumberOrder
print("|cff00b899"..GetUnitName(GetTriggerUnit()).." получил тек приказ "..OrderId2String(GetIssuedOrderId()).."|r")
end
-- ========тут большой код
else
if GetTriggerEventId()==EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER then
local NumberOrder = QueueOrders.CountOrders[h]+1
QueueOrders.TargetOrderObject[h][NumberOrder] = GetOrderTarget()
QueueOrders.TargetPointOrderX[h][NumberOrder] = nil
QueueOrders.TargetPointOrderY[h][NumberOrder] = nil
QueueOrders.Order[h][NumberOrder]=GetIssuedOrderId()
QueueOrders.TypeOrder[h][NumberOrder]=1
QueueOrders.CountOrders[h]=NumberOrder
if GetOrderTargetUnit() ~= nil then
--тип цели (какие эффекты вешают на цели. 1 - это спецэффекты)
QueueOrders.TypeTarget[h][NumberOrder] = 1
--спецэффект
local effect = CrateEffectWayPoint(GetTriggerPlayer())
QueueOrders.EffectWayPoint[h][NumberOrder] = AddSpecialEffectTarget( effect, GetOrderTarget(), "overhead")
--имя цели
id = GetUnitTypeId(GetOrderTargetUnit())
QueueOrders.TargetOrderTypeObject[h][NumberOrder] = GetObjectName(id)
elseif GetOrderTargetDestructable() ~= nil then
local d = GetOrderTargetDestructable()
BlzPauseUnitEx( LastMainSelectedUnit, true )
BlzPauseUnitEx( LastMainSelectedUnit, false )
--тип цели (какие эффекты вешают на цели. 1 - это спецэффекты)
QueueOrders.TypeTarget[h][NumberOrder] = 1
--спецэффект
local effect = CrateEffectWayPoint(GetTriggerPlayer())
QueueOrders.EffectWayPoint[h][NumberOrder] = AddSpecialEffect(effect, GetDestructableX(d), GetDestructableY(d)) --CrateUnitWayPoint(GetTriggerPlayer())
--имя цели (по id сложно выявить имя декора, поэтому запоминаем так)
QueueOrders.TargetOrderTypeObject[h][NumberOrder] = GetDestructableName(d)
--вешаем событие смерти
TriggerRegisterDeathEvent(DeleteEffects, d)
QueueOrders.EffectObjects[GetHandleId(d)]= QueueOrders.EffectWayPoint[h][NumberOrder]
elseif GetOrderTargetItem() ~= nil then
--тип цели (какие эффекты вешают на цели. 2 - это dummy-units. к предметам сложно прицепить специээфект)
QueueOrders.TypeTarget[h][NumberOrder] = 2
--юнит в качестве спецэффекта
QueueOrders.UnitWayPoint[h][NumberOrder] =CrateUnitWayPoint(GetTriggerPlayer())
--имя предмета
id = GetItemTypeId(GetOrderTargetItem())
QueueOrders.TargetOrderTypeObject[h][NumberOrder] = GetObjectName(id)
end
print("|cff00bfff"..GetUnitName(GetTriggerUnit()).." (кол-во:"..count..") получил след приказ "..OrderId2String(GetIssuedOrderId()).." в цель "..GetObjectName(id).."|r")
elseif GetTriggerEventId()==EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER then
local NumberOrder = QueueOrders.CountOrders[h]+1
QueueOrders.TargetOrderObject[h][NumberOrder] = nil
QueueOrders.TargetPointOrderX[h][NumberOrder] = GetOrderPointX()
QueueOrders.TargetPointOrderY[h][NumberOrder] = GetOrderPointY()
QueueOrders.Order[h][NumberOrder]=GetIssuedOrderId()
--тип цели (какие эффекты вешают на цели. 2 - это dummy-units. к предметам сложно прицепить специээфект)
QueueOrders.TypeTarget[h][NumberOrder] = 2
--юнит в качестве спецэффекта
QueueOrders.UnitWayPoint[h][NumberOrder] =CrateUnitWayPoint(GetTriggerPlayer())
if GetIssuedOrderId()>850000 and GetIssuedOrderId()<860000 then
QueueOrders.TypeOrder[h][NumberOrder]=2
print("|cff00bfff"..GetUnitName(GetTriggerUnit()).." (кол-во:"..count..") получил след приказ "..OrderId2String(GetIssuedOrderId()).." в точку "..GetOrderPointX()..","..GetOrderPointY().."|r")
else
QueueOrders.TypeOrder[h][NumberOrder]=3
print("|cff00bfff"..GetUnitName(GetTriggerUnit()).." (кол-во:"..count..") получил след приказ строить "..OrderId2String(GetIssuedOrderId()).." в точку "..GetOrderPointX()..","..GetOrderPointY().."|r")
end
QueueOrders.CountOrders[h]=NumberOrder
elseif GetTriggerEventId()==EVENT_PLAYER_UNIT_ISSUED_ORDER and GetIssuedOrderId()==851972 then
local NumberOrder = QueueOrders.CountOrders[h]+1
QueueOrders.TargetOrderObject[h][NumberOrder] = nil
QueueOrders.TargetPointOrderX[h][NumberOrder] = nil
QueueOrders.TargetPointOrderY[h][NumberOrder] = nil
QueueOrders.Order[h][NumberOrder]=GetIssuedOrderId()
QueueOrders.TypeOrder[h][NumberOrder]=4
QueueOrders.CountOrders[h]=NumberOrder
print("|cff00bfff"..GetUnitName(GetTriggerUnit()).." (кол-во:"..count..") получил след приказ "..OrderId2String(GetIssuedOrderId()).."|r")
end
print("запись")
clicking_the_mouse_button = 0
local CurrentOrder = QueueOrders.CurrentNumberOrder[h]
local type_order = QueueOrders.TypeOrder[h][CurrentOrder]
local id_order = QueueOrders.Order[h][CurrentOrder]
local id_object = QueueOrders.TargetOrderTypeObject[h][CurrentOrder]
if type_order == 1 then
local target = QueueOrders.TargetOrderObject[h][CurrentOrder]
DisableTrigger(detectedtrigger1)
IssueTargetOrderById(GetTriggerUnit(),id_order, target)
EnableTrigger(detectedtrigger1)
print("|cff660099"..GetUnitName(GetTriggerUnit()).." получил продолжить "..type_order.."-приказ "..OrderId2String(id_order).." в цель "..GetObjectName(id).."|r")
elseif type_order == 2 then
local x = QueueOrders.TargetPointOrderX[h][CurrentOrder]
local y = QueueOrders.TargetPointOrderY[h][CurrentOrder]
DisableTrigger(detectedtrigger1)
IssuePointOrderById(GetTriggerUnit(),id_order, x,y)
EnableTrigger(detectedtrigger1)
print("|cff660099"..GetUnitName(GetTriggerUnit()).." получил продолжить "..type_order.."-приказ "..OrderId2String(id_order).." в точку "..x..","..y.."|r")
elseif type_order == 3 then
local x = QueueOrders.TargetPointOrderX[h][CurrentOrder]
local y = QueueOrders.TargetPointOrderY[h][CurrentOrder]
DisableTrigger(detectedtrigger1)
IssueBuildOrderById(GetTriggerUnit(),id_order, x,y)
EnableTrigger(detectedtrigger1)
print("|cff660099"..GetUnitName(GetTriggerUnit()).." получил продолжить "..type_order.."-приказ "..OrderId2StringBJ(id_order).." строить в точке "..x..","..y.."|r")
else
DisableTrigger(detectedtrigger1)
IssueImmediateOrderById(GetTriggerUnit(),id_order)
EnableTrigger(detectedtrigger1)
print("|cff660099"..GetUnitName(GetTriggerUnit()).." получил продолжить "..type_order.."-приказ "..OrderId2StringBJ(id_order).."|r")
end
end
end)
end
end
Survivalist, я уже объяснял как работает. Тут на каждый фрейм создают подсказку пустышку-фрейм. Когда курсор оказывается внутри фрейма появляется эта самая подсказка. Когда мы уходим из фрейма, подсказка исчезает. Отдельно работают подсказки варивские. Тк в рефорджете нет нативок, определяющих положения фрейма на экране, то на помощь пришли эти подсказки они быстрее.
Есть события у фреймов, которые ловят вход в фрейм/выход из фрейма - они не работают так хорошо как хотелось бы. Там обновляется событие медленно. Можно мышью крутануть в конец экрана, и все, у тебя курсор не внутри фрейма, событие может не зафиксировать вход/выход. Только если очень медленно подводить курсор. вО-ВТОРЫХ, ЕСЛИ КРУТАНУТЬ СИЛЬНО. И КУРСОР ОКАЖЕТСЯ ВНУТРИ, то событие не фиксируется, что мышь внутри, только входы/выходы. В-третьих, не все типы фреймов могут иметь нужными событиями.
Подсказки более приемлемый вариант, ниче более не остается. Подсказки тоже не очень, они мгновенно не могут переключаться, если один фрейм выключить, то подсказка исчезнет не сразу. И точно также не сразу появится след подсказка. Короче, частота обновления подсказки 0.01-0.02 сек. Щас все так используют. Хотя способ немного причудливый.
Survivalist, кажется понял. У тебя клик мыши срабатывается и по интерфейсу.
выше скинул пример как определить лежит ли курсор в игровом поле (см. выше код). там разделил на две части: поле интерфейса и игровое поле. потом есть события нажатия мыши (ЛКМ и ПКМ, еще СКМ). Когда жмешь, ты чекаешь лежит ли курсор в игровом поле, если лежит стреляешь, не лежит, не стреляем.
Survivalist, ты приказом attack отдаешь атаковать? замени на smart. smart - щелчок мыщи, если цель юнит он либо следует за союзником, либо атакует врага, предмет подбирает, а декор - разрушает (если имеет условие для этого, для рубки дерева необходим навык).
А когда юнит находится в зоне игрока, то там можно было отключить ЛКМ атаку.
можно еще маску на экран накрыть фреймом. и открывать в нужный момент. пример
Возможно ли сделать определённую зону для курсора где можно запретить например вывод текста при нажатии на лкм.
Вывод текста - эта всплывающая подсказка Tooltip что ли? Она не активируется нажатием ЛКМ, она сама открывается. Если у вас что-то открывается, значит, это что у вас. Надо в коде смотреть итд
Ее можно попробовать скрыть. За всплывающие подсказки отвечают ORIGIN_FRAME_TOOLTIP и ORIGIN_FRAME_UBERTOOLTIP
f0 = BlzGetOriginFrame(ORIGIN_FRAME_TOOLTIP ,0)
f1 = BlzGetOriginFrame(ORIGIN_FRAME_UBERTOOLTIP,0)
BlzFrameSetVisible(f0,true)
BlzFrameSetVisible(f1,true)
можно определять лежит ли курсор в игровом поле.
Обычно есть статьи
Можно создать каждому фрейму всплывающую подсказку. Tooltips будут у нас невидимыми пустышками, они нужны для проверки. Когда курсор оказывается внутри фрейма, то подсказка становится видимой. Таймером чекаем подсказки. Можно разбить экран на несколько частей.
Еще не забывайте про стандарт фреймы, они тоже подсказки показывают. Эти используют станд подсказку на все ORIGIN_FRAME_TOOLTIP и ORIGIN_FRAME_UBERTOOLTIP
--чекаем принадлежность курсора в игровом поле
local cursorInGame = true
TimerStart(CreateTimer(),0.0, false,function()
local parent = BlzGetFrameByName("ConsoleUIBackdrop", 0)
local gameUI = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)
--DestroyTimer(GetExpiredTimer())
--Screen - родитель игрового поля (т.е. экрана)
local Screen = BlzCreateFrameByType("FRAME", "FaceFrame", parent, "", 0)
--левая центральная
local ScreenFrame1 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", Screen, "ScriptDialogButton", 0)
BlzFrameSetAlpha(ScreenFrame1, 50)
BlzFrameSetAbsPoint(ScreenFrame1, FRAMEPOINT_CENTER, 0.1,0.154+((0.416)/2))
BlzFrameSetSize(ScreenFrame1, 0.2, 0.416)
--центральная игровая
local ScreenFrame2 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", Screen, "ScriptDialogButton", 0)
BlzFrameSetAlpha(ScreenFrame2, 50)
BlzFrameSetAbsPoint(ScreenFrame2, FRAMEPOINT_CENTER, 0.4,0.128+((0.442)/2))
BlzFrameSetSize(ScreenFrame2, 0.4, 0.442)
--правая центральная игровая
local ScreenFrame3 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", Screen, "ScriptDialogButton", 0)
BlzFrameSetAlpha(ScreenFrame3, 50)
BlzFrameSetAbsPoint(ScreenFrame3, FRAMEPOINT_CENTER, 0.7,0.154+((0.416)/2))
BlzFrameSetSize(ScreenFrame3, 0.2, 0.416)
--левая боковая игровая
local ScreenFrame4 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", Screen, "ScriptDialogButton", 0)
BlzFrameSetAlpha(ScreenFrame4, 50)
BlzFrameSetAbsPoint(ScreenFrame4, FRAMEPOINT_CENTER, -0.144/2,(0.164+0.410)/2)
BlzFrameSetSize(ScreenFrame4, 0.144, 0.164+0.410)
--правая боковая игровая
local ScreenFrame5 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", Screen, "ScriptDialogButton", 0)
BlzFrameSetAlpha(ScreenFrame5, 50)
BlzFrameSetAbsPoint(ScreenFrame5, FRAMEPOINT_CENTER, 0.8+0.144/2,(0.164+0.410)/2)
BlzFrameSetSize(ScreenFrame5, 0.144, 0.164+0.410)
--Sreentools - всплывающая подсказка-пустышка
local Sreentools = BlzCreateFrameByType("FRAME", "FaceFrame", parent, "", 0)
BlzFrameSetAlpha(Sreentools, 0)
BlzFrameSetAbsPoint(Sreentools, FRAMEPOINT_BOTTOMLEFT, 0, 0)
BlzFrameSetSize(Sreentools, 0, 0)
BlzFrameSetTooltip(ScreenFrame1, Sreentools)
BlzFrameSetTooltip(ScreenFrame2, Sreentools)
BlzFrameSetTooltip(ScreenFrame3, Sreentools)
BlzFrameSetTooltip(ScreenFrame4, Sreentools)
BlzFrameSetTooltip(ScreenFrame5, Sreentools)
--InterfaceField - родитель интерфейса
local InterfaceField = BlzCreateFrameByType("FRAME", "FaceFrame", gameUI, "", 0)
--левая нижняя панель
local Interface1 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", InterfaceField, "ScriptDialogButton", 0)
BlzFrameSetAlpha(Interface1, 50)
BlzFrameSetAbsPoint(Interface1, FRAMEPOINT_CENTER, 0.1, 0.144/2)
BlzFrameSetSize(Interface1, 0.2, 0.154) --0.176
--центральная панель
local Interface2 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", InterfaceField, "ScriptDialogButton", 0)
BlzFrameSetAlpha(Interface2, 50)
BlzFrameSetAbsPoint(Interface2, FRAMEPOINT_CENTER, 0.4, 0.118/2)
BlzFrameSetSize(Interface2, 0.4, 0.128) --0.15
--правая нижняя панель
local Interface3 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", InterfaceField, "ScriptDialogButton", 0)
BlzFrameSetAlpha(Interface3, 50)
BlzFrameSetAbsPoint(Interface3, FRAMEPOINT_CENTER, 0.7, 0.146/2)
BlzFrameSetSize(Interface3, 0.2, 0.154) --0.176
--верхняя панель
local Interface4 = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(Interface4, 50)
BlzFrameSetAbsPoint(Interface4, FRAMEPOINT_CENTER, 0.4, 0.6-(0.026/2))
BlzFrameSetSize(Interface4, 1.088, 0.026) --0.176
--Interfacetools - всплывающая подсказка поля интерфейса
local Interfacetools = BlzCreateFrameByType("FRAME", "FaceFrame", parent, "", 0)
BlzFrameSetAlpha(Interfacetools, 0)
BlzFrameSetAbsPoint(Interfacetools, FRAMEPOINT_BOTTOMLEFT, 0, 0)
BlzFrameSetSize(Interfacetools, 0, 0)
BlzFrameSetTooltip(Interface1, Interfacetools)
BlzFrameSetTooltip(Interface2, Interfacetools)
BlzFrameSetTooltip(Interface3, Interfacetools)
BlzFrameSetTooltip(Interface4, Interfacetools)
TimerStart(CreateTimer(),1/32, true,function()
if BlzFrameIsVisible(Sreentools) then
print("курсор в игровом поле")
BlzFrameSetVisible(ScreenFrame1,false)
BlzFrameSetVisible(ScreenFrame2,false)
BlzFrameSetVisible(ScreenFrame3,false)
BlzFrameSetVisible(ScreenFrame4,false)
BlzFrameSetVisible(ScreenFrame5,false)
BlzFrameSetVisible(InterfaceField,true)
if GetLocalPlayer() ~= nil then
cursorInGame = true
end
elseif BlzFrameIsVisible(Interfacetools) or BlzFrameIsVisible(BlzGetOriginFrame(ORIGIN_FRAME_UBERTOOLTIP,0)) then
print("курсор в поле интерфейса")
BlzFrameSetVisible(ScreenFrame1,true)
BlzFrameSetVisible(ScreenFrame2,true)
BlzFrameSetVisible(ScreenFrame3,true)
BlzFrameSetVisible(ScreenFrame4,true)
BlzFrameSetVisible(ScreenFrame5,true)
BlzFrameSetVisible(InterfaceField,false)
if GetLocalPlayer()~=nil then
cursorInGame = false
end
end
end)
end)
Как привязать курсор к игровому полю?
чтобы курсор не выходил за пределы есть спец нативка, привязывающая курсор к фрейму
---@param frame framehandle
---@param enable boolean
---@return nothing
function BlzFrameCageMouse(frame, enable) end -- (native)
можно по-разному реализовывать. как у него реализовано мне неведомо
Можно отслеживать положение курсора, находится ли он внутри кнопки. И одновременно отслеживать нажатие кнопки клавиатуры 1,2,3,4,5 итд. И менять.
Можно перетаскивать фрейм. Допустим, у вас есть панель способностей как на скрине, а есть еше большое окно со всеми способностями и описанием.
2.1. Можно фрейм тащить за курсором, у вас есть куча ячеек, и их нужно тоже проверять на присутствие курсора внутри. и когда курсор окажется в ячейке 1, отслеживаем клик, и меняете. Но реализация сложна из-за трудности определения положения мыши
2.2. Можно просто в большом окне изменить. Там кнопочка изменить. И когда жмете на фрейм-кнопку, вам открывают прицел, и вы выбираете.
что мы помним про клавиши
Если нужно зафокусить какую-нибудь клавишу, то можно применить два способа:
указать в самом fdf-file (как на хайве учат)
или попробовать отслеживать событиями нажатия на клавиши (пример специальные клавиши вроде Shift и похожие нельзя будет отслеживать). Но найдено решение
пример с Shift - нажатие и отпускание
do
local InitGlobalsOrigin = InitGlobals -- хукаем функцию InitGlobals
function InitGlobals()
InitGlobalsOrigin()
--чекаем отпускание Shift
--https://www.hiveworkshop.com/threads/oskey-player-key-event.319903/
local ShiftOn = 0
TimerStart(CreateTimer(),0,false, function()
print("Create Keys")
for index = 8,255 do
local trigger = CreateTrigger()
TriggerAddAction(trigger, function()
if index == 160 and ShiftOn ~= BlzGetTriggerPlayerMetaKey() then
if BlzGetTriggerPlayerMetaKey() == 1 then
ShiftOn = 1
print("Shift нажат")
elseif BlzGetTriggerPlayerMetaKey() == 0 then
ShiftOn = 0
print("Shift отпущен")
end
--if GetLocalPlayer() ~= nil then
-- ShiftOn = BlzGetTriggerPlayerMetaKey()
--end
end
--print("OsKey:",index, "meta",BlzGetTriggerPlayerMetaKey())
end)
local key = ConvertOsKeyType(index)
for metaKey = 0,15,1 do
BlzTriggerRegisterPlayerKeyEvent(trigger, Player(0), key, metaKey, true)
BlzTriggerRegisterPlayerKeyEvent(trigger, Player(0), key, metaKey, false)
end
end
print("Done")
print("Press Keys to show the index of that oskey and its metakey")
end)
end
end
я смог отслеживать очереди приказов, записывать. иммитировать триггером отдачу при завершении (приказ равен ноль или чекать изменение точек). Все работает хорошо, немного подправить и все. осталось визуально приукрасить это. создавать фреймы-спрайты (точки зеленые) на мини-карте - там с картой и миникартой пропорции размеров высчитать и отследить в какой части миникарты будет лежать спрайт
код fdf
Пример Sprite
Frame "SPRITE" "MySprite" {
//размеры спрайту задал от балды, тк модели mdx размер не изменишь. Но он нужен, чтобы двигать фрейм
Width 0.362,
Height 0.037,
BackgroundArt "UI\Minimap\Minimap-Waypoint.mdl",
}
формула
и WayPointFlags на карте. WayPointFlag создается норм, а вот в тумане-черной маске его не видно как в оригинале, еще у эффекта тимколор. Ну или можно забить
юнита с нулевым размером радиуса обзора можно создать? как это сделать
Создать для игрока юнита с включенным полем "Расширенный угол обзора" и поставить радиус обзора на 0. Сам юнит обзора давать не будет, но он будет виден. Для других игроков его можно локально прозрачным сделать.
Расширенный угол обзора - это что за параметр.
вспомнил UnitShareVision( u, player, false )
вот параметр
раскрыть
UnitShareVision( u, player, false ) - не работает, видимо без радиуса обзора в тумане не видим
SpecialEffect просмотрел все нативки, но ничего такого для видимости нету.
Пока подумываю присмотреться к декорациям, или trackable.
нашел пока
native CreateTrackable takes string trackableModelPath, real x, real y, real facing returns trackable
trackable - можно заметить в тумане, не может цвет/тимколор менять, нельзя крутить, менять положение, крепить к целям и прочее. идеальный вариант для обычных спецэффектов.
Короче, я разочарован варкрафтом. Сделал для себя вывод. Чтобы эффект был видимым, необходимо, чтобы он находился в видимости части (не в тумане, и черной маске). Не важно наскока у вас большая модель, или наскока растянутая модель, центр-точки должен находится в видимости части.
Пробовал trackable, они создают модель и на этом все, У trackable нет никаких норм функции для работы с ними, их даже не удалишь, тк нет такой функции.
Ну остаются юниты. Юнитов не хотелось бы создавать. Поэтому решил создать модификатор видимости, который совсем работает только с определенными размерами типа 128, 256, 512 - это огромные размеры. Меньше 128 не задашь. Как и юнитам.
do
local InitGlobalsOrigin = InitGlobals -- хукаем функцию InitGlobals
function InitGlobals()
InitGlobalsOrigin()
--работа с фреймами
function LoadToc(s)
if BlzLoadTOCFile(s) then
print("Loaded: "..s)
else
print("Failed to Load: "..s)
end
end
function ShowInterfaceE(b)
LoadToc("templates.toc")
local unit = CreateUnit(Player(0), FourCC("hfoo"), 0, 0, 0)
SelectUnitSingle(unit)
TimerStart(CreateTimer(), 0.3, false, function()
--создаем консольные текстуры (по сути переделанная в fdf-file ConsoleUI - убраны бока)
local framehandle Console = BlzCreateFrameByType("SIMPLEFRAME","MyConsole",BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0),"MyConsole",0)
--показать ConsoleUIBackdrop (при инициализации почему-то не показывается, только во время игры) w=0.8 h=0.13
BlzFrameClearAllPoints(BlzGetFrameByName("ConsoleUIBackdrop",0))
BlzFrameSetAbsPoint(BlzGetFrameByName("ConsoleUIBackdrop",0), FRAMEPOINT_BOTTOMLEFT, 0.0, 0.0)
--снова возвращаем Portrait на место w=0.06 h=0.08
BlzFrameSetVisible(BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT,0), true)
--BlzFrameClearAllPoints(BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT,0))
--BlzFrameSetAbsPoint(BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT,0), FRAMEPOINT_BOTTOMLEFT, 0.26, 0.03)
--показать Portrait HP/MANA (показываются тексты, когда выделен юнит) text w=0.06 h=0,016
local hpFrame = BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT_HP_TEXT, 0)
BlzFrameClearAllPoints(hpFrame)
BlzFrameSetAbsPoint(hpFrame, FRAMEPOINT_CENTER, 0.253, 0.024)
local mpFrame = BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT_MANA_TEXT, 0)
BlzFrameClearAllPoints(mpFrame)
BlzFrameSetAbsPoint(mpFrame, FRAMEPOINT_CENTER, 0.253, 0.008)
--центральная информационная панель
local BottomCenterUI = BlzFrameGetChild(BlzGetFrameByName("ConsoleUI",0),1)
--BlzFrameSetVisible(BottomCenterUI, true)
BlzFrameClearAllPoints(BottomCenterUI)
BlzFrameSetAbsPoint(BottomCenterUI, FRAMEPOINT_CENTER, 0.4025,0.0583)
--контейнер кнопки неактивного рабочего W=0.039 h=0.039 (Idle worker Button Container)
BlzFrameSetVisible(BlzFrameGetChild(BlzGetFrameByName("ConsoleUI",0),7), true) BlzFrameClearAllPoints(BlzFrameGetChild(BlzGetFrameByName("ConsoleUI",0),7))
BlzFrameSetAbsPoint(BlzFrameGetChild(BlzGetFrameByName("ConsoleUI",0),7), FRAMEPOINT_BOTTOMLEFT, 0.0, 0.17)
--мини-карта w=0.139375 h=0.138125
BlzFrameClearAllPoints(BlzGetFrameByName("MiniMapFrame",0))
BlzFrameSetAbsPoint(BlzGetFrameByName("MiniMapFrame",0), FRAMEPOINT_BOTTOMLEFT, 0.009375, 0.006875)
--мини-кнопки w=0.023125 h=0.020625*5
BlzFrameClearAllPoints(BlzGetFrameByName("MinimapSignalButton",0))
BlzFrameSetAbsPoint(BlzGetFrameByName("MinimapSignalButton",0), FRAMEPOINT_TOPLEFT, 0.154375, 0.14375)
BlzFrameClearAllPoints(BlzGetFrameByName("MiniMapTerrainButton",0))
BlzFrameSetAbsPoint(BlzGetFrameByName("MiniMapTerrainButton",0), FRAMEPOINT_TOPLEFT, 0.154375, 0.121875)
BlzFrameClearAllPoints(BlzGetFrameByName("MiniMapAllyButton",0))
BlzFrameSetAbsPoint(BlzGetFrameByName("MiniMapAllyButton",0), FRAMEPOINT_TOPLEFT, 0.154375, 0.1)
BlzFrameClearAllPoints(BlzGetFrameByName("MiniMapCreepButton",0))
BlzFrameSetAbsPoint(BlzGetFrameByName("MiniMapCreepButton",0), FRAMEPOINT_TOPLEFT, 0.154375, 0.0775)
BlzFrameClearAllPoints(BlzGetFrameByName("FormationButton",0))
BlzFrameSetAbsPoint(BlzGetFrameByName("FormationButton",0), FRAMEPOINT_TOPLEFT, 0.154375, 0.05)
--коммандная панель w=0.1745 h=0.129
BlzFrameClearAllPoints(BlzGetFrameByName("CommandBarFrame",0))
BlzFrameSetAbsPoint(BlzGetFrameByName("CommandBarFrame",0), FRAMEPOINT_CENTER, 0.7+0.0048, 0.146/2-0.0045)
RemoveUnit(unit)
print("done")
DestroyTimer(GetExpiredTimer())
end)
end
--инициируем игру
--прячем консоль (консольные текстуры вместе с потомками перемещены за пределы экрана, и мы их не видим)
BlzFrameSetAbsPoint(BlzGetFrameByName("ConsoleUI", 0), FRAMEPOINT_BOTTOM, 0.4, -0.18)
--Portrait не прячется, но в начале прячем. Тк не красиво будет, тк решно мной сделать задержку появления нижней консоли. задержка создана из-за дурацких текстов под портретом, нужно чтобы юнит был выделен.
BlzFrameSetVisible(BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT,0), false)
--BlzFrameClearAllPoints(BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT,0))
--BlzFrameSetAbsPoint(BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT,0), FRAMEPOINT_BOTTOM, 0.4, -0.18)
--прячем кнопку неактивного рабочего
BlzFrameSetVisible(BlzFrameGetChild(BlzGetFrameByName("ConsoleUI",0),7), false)
--отображаем нужные элементы
ShowInterfaceE(true)
--скрываем мертвую рамку коммандной панели
BlzFrameSetScale(BlzFrameGetChild(BlzGetFrameByName("ConsoleUI",0),5), 0.001)
end
end
UPDATE: забыл в карте при инициализации спрятать кнопку неактивного рабочего через BlzFrameSetVisible(BlzFrameGetChild(BlzGetFrameByName("ConsoleUI",0),7), false). И потом после задержки показать. Ну ладно
когда я прячу этой коммандой, многое из интерфейса пропадает, портрет и хп/мана тексты пропадают. Раньше такого не было. Решил поискать на хайве
чтобы отобразить портрет
мы должны не просто сдвинуть портрет, но и нужно, чтобы родитель портрета был видим. Не знаю почему без родителя не хочет портрет появляться.
--родитель портрета и hero-buttons
BlzFrameSetVisible(BlzFrameGetChild(BlzFrameGetChild(BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI ,0), 3),0), b)
--сдвигаем портрет-рамку и вас отобразится, но нужно задать положение на экране и размер (подобрал исходные размер и положение)
BlzFrameClearAllPoints(BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT,0))
BlzFrameSetAbsPoint(BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT,0), FRAMEPOINT_BOTTOMLEFT, 0.26, 0.03)
BlzFrameSetSize(BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT,0),0.06,0.08)
тексты хп / мана - я не смог отобразить, раньше у меня работало
проблема в том, что фреймы этих текстов невидимы/не существуют. Поэтому нужно выделить юнита, и тогда у вас должны отображаться тексты. Короче, можно искусственно перекинуть выделение на юнита
на хайве нашел такой код, нужно перекинуть выделение, сделать задержку 0.03 сек и framepoine_center переместить
do
local real = MarkGameStarted
function MarkGameStarted()
real()
local unit = CreateUnit(Player(0), FourCC("hfoo"), 0, 0, 0)
SelectUnitSingle(unit)
TimerStart(CreateTimer(), 0.3, false, function()
RemoveUnit(unit)
local hpFrame = BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT_HP_TEXT, 0)
BlzFrameClearAllPoints(hpFrame)
BlzFrameSetAbsPoint(hpFrame, FRAMEPOINT_CENTER, 0.4, 0.55)
local mpFrame = BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT_MANA_TEXT, 0)
BlzFrameClearAllPoints(mpFrame)
BlzFrameSetAbsPoint(mpFrame, FRAMEPOINT_CENTER, 0.4, 0.54)
print("done")
DestroyTimer(GetExpiredTimer())
end)
print("done")
end
end
это должно было работать. Но у меня почему не работает (на пустой карте тестил).
полный код (как хотел сделать - наверн не пригодится, другой способ попробую)
do
local InitGlobalsOrigin = InitGlobals -- хукаем функцию InitGlobals
function InitGlobals()
InitGlobalsOrigin()
--работа с фреймами
function LoadToc(s)
if BlzLoadTOCFile(s) then
print("Loaded: "..s)
else
print("Failed to Load: "..s)
end
end
function ShowInterfaceE(b)
LoadToc("templates.toc")
local framehandle Console = BlzCreateFrameByType("SIMPLEFRAME","MyConsole",BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0),"MyConsole",0)
--полоса кнопок меню
BlzFrameSetVisible(BlzGetFrameByName("UpperButtonBarFrame",0), b)
--полоса отображения ресурсов игрока
BlzFrameSetVisible(BlzGetFrameByName("ResourceBarFrame",0), b)
--контейнер кнопки рабочего
BlzFrameSetVisible(BlzFrameGetChild(BlzGetFrameByName("ConsoleUI",0),7), b) --Idle worker Button Container
BlzFrameSetVisible(BlzGetFrameByName("MinimapButtonBar",0), b)
--BlzFrameSetVisible(BlzGetFrameByName("CommandBarFrame",0), b)
BlzFrameSetVisible(BlzGetOriginFrame(ORIGIN_FRAME_MINIMAP,0), b)
--родитель портрета и hero-buttons
BlzFrameSetVisible(BlzFrameGetChild(BlzFrameGetChild(BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI ,0), 3),0), b)
--полоса отображения кнопок героев
BlzFrameSetVisible(BlzGetOriginFrame(ORIGIN_FRAME_HERO_BAR,0), b)
BlzFrameSetVisible(BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT,0), b)
BlzFrameSetVisible(BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT_HP_TEXT,0), b)
BlzFrameSetVisible(BlzGetOriginFrame(ORIGIN_FRAME_PORTRAIT_MANA_TEXT,0), b)
--BottomCenter UI parent
BlzFrameSetVisible(BlzFrameGetChild(BlzGetFrameByName("ConsoleUI",0),1), b)
--часики
BlzFrameSetVisible(BlzFrameGetChild(BlzFrameGetChild(BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI ,0),5),0), b)
BlzFrameSetVisible(BlzGetFrameByName("SimpleConsole",0), b)
end
--инициируем игру
--скрывает все, кроме командных кнопок, чата, сообщений, TimerDialogs, Multiboards и LeaderBoards
BlzHideOriginFrames (true)
--скрываем мертвую рамку коммандной панели
BlzFrameSetScale(BlzFrameGetChild(BlzGetFrameByName("ConsoleUI",0),5), 0.001)
--отображаем нужные элементы
TimerStart(CreateTimer(),0,false, function()
ShowInterfaceE(true)
end)
end
end
портрет работает. а вот хп/мана тексты у меня до сих пор не показываются. Но это должен быть рабочим вариантом
второй способ - просто ConsolUI переместить за пределы экрана или сделать скалирование. Остальное остается за простым. Опять задрачиваться, тк ранее я пошел по первому способу, чтобы убрать каменнные рамки по бокам =(( сейчас похоже нужен второй
ConsoleUI - консольные текстуры. Но сам фрейм является родителем многих важных элементов, и прятать наверное не стоит, тк мб повлиять на потомков. Прячешь предка => и томки тоже исчезают следом, параметры наследуются от родача. Но самого родителя наверное можно сдвинуть или уменьшить до совсем крошечного размера, но как будет с потомками неизвестно, как-то связаны точками не знаю. Думаю все будет хорошо,.
Панель приказов и кнопки на ней - это только интерфейс управления для игрока?
да. это все кнопки. итемы - тоже кнопки. иконка неактивного рабочего - кнопка. кнопки миникарты- кнопки. иконки героев - кнопки. кнопки меню, квест и альянс, журнал - кнопки.
кратко
кнопками являются здания, технолошки, абилки - на панеле приказов. даже когда вы заказываете в здании, в очередь тренировки/исследования встают кнопки юнитов, исследования <= нажав на них можете отменить. кнопками являются и юниты у транспорта (нажав на кнопку юнита, вы можете выкинуть его из транспорта), или когда выделен отряд (кнопки переключения). даже есть кнопка сворачивания мутиборда, ползунок у scroolbar/slider - это же кнопка. checkbox (кнопка с флагом), popupmenu (всплывающее окно), editbox (поле редактирования/ввода текста) и др - эти типы фреймов тоже действуют по типу кнопки.
а все остальное - это уже иконки, модель часов, полоска опыта, полоска жизни. Горячие кнопки напрямую связаны с кнопками, если они скрыты, то значит, ими нельзя воспользоваться.
map_maiker, так события показывают только получение приказа, а не очередь. просто важно запомнить всю очередь. во время SHIFT нельзя ниче получить. Просмотрел все нативки, которые есть. Смотрел наработки у нас на сайте, пример через GetUnitRallyPoint. или на хайве
Пробовал искусственно отпустить эту клавишу SHIFT, но никакими фреймами, ForceUIKey нельзя отменить. Пробовал использовать баг фреймов, когда залипаем кнопки, короче фокус переключить. Но дело в том, что эта системная кнопка никак не относится к фреймовым, даже работает при переключенном фокусе.
Ну раз ниче не получается с клавиатурой, пробуем с юнитом че-нибудь сделать. Отследить это тоже сложновато. Че то такое придумать бы. Типа приказом перебить очередь, и посмотреть изменилось.
Нашел такой способ: Событие нажатия мыши (Down) срабатывает раньше события приказов. Отдаем во время нажатия мыши приказ стоп - очередь тут же сбивается. Но юнит сразу же получает новый приказ, активированный нами только что кликом. А уже при событии приказа мы записываем приказ, и возобновляем пред приказ. Главное не перепутайте с отпускаем мыши (UP), тк отпускание мыши срабатывает позже приказов. Но не знаю не будет ли юнита передергивать. Но это уже завтра потестим
может от модели то зависит скорость? у них не прописана станд анимация? я вот спецэффектом модели юнита создаю, у них анима проигрывает.
есть ли какие зависимости скорость бега анимации от скорости бега, скорости анимации атаки от скорости атаки, скорость анимации постройки от скорости строительства? Я пока не тестил эту функцию, но скором временем туда дойду
Я попробовал сделать по-другому, проверять расстояние точки курсора мыши и точки объекта, если оно меньше радиуса коллизиона, то лежит. Работает не идеально.
Проблема вот в чем:
у юнитов проверять по коллизион не очень точное решение. Иногда размеры больше, чем должны быть, пример здания. Курсор не успел переместить к зданию, как уже сообщение выпрыгивает, что курсор там. Хотя работает, но не всегда. Пример у хуманского работника очень мелкий радиус коллизион, он то есть, то нет. ВОТ С ЛЕТАЮЩИМИ ТАКОЕ СЛОЖНО ПРОВЕРИШЬ. Пробовал разные характеристики в редакторе посмотреть.
у итемов. У итемов такое чувство будто модель съехала от центра. Поэтому сложно.
у декора как и у юнитов. Но еще не пробовал.
код
globals
real XXX
real YYY
endglobals
function Trig_MoveMouse_Actions takes nothing returns nothing
set XXX = BlzGetTriggerPlayerMouseX()
set YYY = BlzGetTriggerPlayerMouseY()
endfunction
//===========================================================================
function InitTrig_MoveMouse takes nothing returns nothing
set gg_trg_MoveMouse = CreateTrigger( )
call TriggerRegisterPlayerMouseEventBJ( gg_trg_MoveMouse, Player(0), bj_MOUSEEVENTTYPE_MOVE )
call TriggerAddAction( gg_trg_MoveMouse, function Trig_MoveMouse_Actions )
endfunction
globals
group GF = CreateGroup()
unit focusunit = null
item focusitem = null
integer countitems = 0
endglobals
function Distance takes real x1, real y1, real x2, real y2 returns real
local real dx = x2 - x1
local real dy = y2 - y1
return SquareRoot(dx * dx + dy * dy)
endfunction
function FindUnit takes nothing returns boolean
return Distance(XXX,YYY,GetUnitX(GetFilterUnit()),GetUnitY(GetFilterUnit()))< BlzGetUnitCollisionSize(GetFilterUnit()) //*BlzGetUnitRealField(GetFilterUnit(), UNIT_RF_SELECTION_SCALE)
endfunction
function FindItem takes nothing returns boolean
return Distance(XXX,YYY,GetItemX(GetFilterItem()),GetItemY(GetFilterItem()))< 30.
endfunction
function ActionWithItems takes nothing returns nothing
if focusitem != GetEnumItem() then
set focusitem =GetEnumItem()
call BJDebugMsg("фокус-итем: "+GetItemName(GetEnumItem()))
set countitems = countitems + 1
endif
endfunction
function Trig_Period_Actions takes nothing returns nothing
set countitems = 0
call EnumItemsInRect(bj_mapInitialPlayableArea, Condition(function FindItem), function ActionWithItems)
if countitems == 0 and focusitem != null then
set focusitem = null
call BJDebugMsg("фокус-итем: null ")
endif
call GroupEnumUnitsInRange(GF,XXX,YYY,250, Condition(function FindUnit))
if FirstOfGroup(GF)!= null then
if focusunit != FirstOfGroup(GF) then
set focusunit = FirstOfGroup(GF)
call BJDebugMsg("фокус-юнит: "+GetUnitName(FirstOfGroup(GF)))
endif
elseif focusunit != null then
set focusunit = null
call BJDebugMsg("фокус-юнит: null")
endif
endfunction
//===========================================================================
function InitTrig_Period takes nothing returns nothing
set gg_trg_Period = CreateTrigger( )
call TriggerRegisterTimerEventPeriodic( gg_trg_Period, 0.03 )
call TriggerAddAction( gg_trg_Period, function Trig_Period_Actions )
endfunction
Короче, курсор подсвечивается если наведен на модель. А как проверить тек функционалом я не знаю. Я размеры модели не знаю. Все что я делал - не думаю, что хорошее решение.
Пробовал станд фреймы дрючить:
курсор
local framehandle GameUI = BlzGetOriginFrame ( ORIGIN_FRAME_GAME_UI , 0 )
local framehandle ParentOfMouseCursor = BlzFrameGetChild(GameUI, 13)
local framehandle MouseCursor = BlzFrameGetChild(ParentOfMouseCursor, 0)
if BlzFrameIsVisible(ParentOfMouseCursor) then
call BJDebugMsg("фокус")
call BJDebugMsg(R2S(BlzFrameGetValue(ParentOfMouseCursor)))
endif
но они вылетают. Инфу никакую не дают. Только спрятать можно и все.
BlzGetMouseFocusUnit() - идеальное решение для юнитов. Но может к десихрону приводить. Но если уметь можно обойти. На хайве находил записи-решения. А вот с остальными, ну ладно.
» WarCraft 3 / нацепить на декорации и итемы спецэффкты? и удаление декора
Ред. MpW
» WarCraft 3 / нацепить на декорации и итемы спецэффкты? и удаление декора
Ред. MpW
» WarCraft 3 / москиты (locust) в рефорджете не работает?
» WarCraft 3 / москиты (locust) в рефорджете не работает?
Ред. MpW
» WarCraft 3 / Запретная зона для лкм.
Есть события у фреймов, которые ловят вход в фрейм/выход из фрейма - они не работают так хорошо как хотелось бы. Там обновляется событие медленно. Можно мышью крутануть в конец экрана, и все, у тебя курсор не внутри фрейма, событие может не зафиксировать вход/выход. Только если очень медленно подводить курсор. вО-ВТОРЫХ, ЕСЛИ КРУТАНУТЬ СИЛЬНО. И КУРСОР ОКАЖЕТСЯ ВНУТРИ, то событие не фиксируется, что мышь внутри, только входы/выходы. В-третьих, не все типы фреймов могут иметь нужными событиями.
» WarCraft 3 / Запретная зона для лкм.
Ред. MpW
» WarCraft 3 / Запретная зона для лкм.
» WarCraft 3 / Запретная зона для лкм.
Ред. MpW
» WarCraft 3 / Запретная зона для лкм.
Ред. MpW
» WarCraft 3 / Запретная зона для лкм.
Ее можно попробовать скрыть. За всплывающие подсказки отвечают ORIGIN_FRAME_TOOLTIP и ORIGIN_FRAME_UBERTOOLTIP
f0 = BlzGetOriginFrame(ORIGIN_FRAME_TOOLTIP ,0)
f1 = BlzGetOriginFrame(ORIGIN_FRAME_UBERTOOLTIP,0)
BlzFrameSetVisible(f0,true)
BlzFrameSetVisible(f1,true)
Можно создать каждому фрейму всплывающую подсказку. Tooltips будут у нас невидимыми пустышками, они нужны для проверки. Когда курсор оказывается внутри фрейма, то подсказка становится видимой. Таймером чекаем подсказки. Можно разбить экран на несколько частей.
чтобы курсор не выходил за пределы есть спец нативка, привязывающая курсор к фрейму
---@param frame framehandle
---@param enable boolean
---@return nothing
function BlzFrameCageMouse(frame, enable) end -- (native)
Ред. MpW
» WarCraft 3 / Бинд клавиш.
Ред. MpW
» WarCraft 3 / видимый спецэффект в тумане и черной маске
вспомнил UnitShareVision( u, player, false )
Ред. MpW
» WarCraft 3 / видимый спецэффект в тумане и черной маске
ответ
Ну остаются юниты. Юнитов не хотелось бы создавать. Поэтому решил создать модификатор видимости, который совсем работает только с определенными размерами типа 128, 256, 512 - это огромные размеры. Меньше 128 не задашь. Как и юнитам.
Ред. MpW
» WarCraft 3 / Пропал портрет и надписи хп и мана под порттретом
Ред. MpW
» WarCraft 3 / Пропал портрет и надписи хп и мана под порттретом
Ред. MpW
» WarCraft 3 / Пропал портрет и надписи хп и мана под порттретом
на хайве нашел такой код, нужно перекинуть выделение, сделать задержку 0.03 сек и framepoine_center переместить
ConsoleUI - консольные текстуры. Но сам фрейм является родителем многих важных элементов, и прятать наверное не стоит, тк мб повлиять на потомков. Прячешь предка => и томки тоже исчезают следом, параметры наследуются от родача. Но самого родителя наверное можно сдвинуть или уменьшить до совсем крошечного размера, но как будет с потомками неизвестно, как-то связаны точками не знаю. Думаю все будет хорошо,.
Ред. MpW
» WarCraft 3 / Пропал портрет и надписи хп и мана под порттретом
надо сдвинуть его, тогда отобразится
Ред. MpW
» WarCraft 3 / Панель приказов
» WarCraft 3 / Модификации редактора
» WarCraft 3 / Триггер
Ред. MpW
» WarCraft 3 / есть ли что то похожее на BlzGetMouseFocusUnit()
Ну раз ниче не получается с клавиатурой, пробуем с юнитом че-нибудь сделать. Отследить это тоже сложновато. Че то такое придумать бы.
Типа приказом перебить очередь, и посмотреть изменилось.Ред. MpW
» WarCraft 3 / Нативка SetUnitTimeScale
есть ли какие зависимости скорость бега анимации от скорости бега, скорости анимации атаки от скорости атаки, скорость анимации постройки от скорости строительства? Я пока не тестил эту функцию, но скором временем туда дойду
Ред. MpW
» WarCraft 3 / есть ли что то похожее на BlzGetMouseFocusUnit()
Проблема вот в чем: