Добавлен , опубликован

Основы Интерфейса

Содержание:
кратко: в варкрафте 3 такого типа фрейма как TOOLTIP не существует. Даже в fdf-files я даже слова не нашел об ToolTip. Но этот тип смесь Backdrop и TEXT. Возникает в следствии наводки курсора мыши на фрейм. Но я решил ввести это как отдельный тип
источник статьи

Вступление

В исходных UI-фреймах tooltips (всплывающие подсказки) - это фреймы, которые по умолчанию скрыты. При наведении курсора на фрейм, которому назначена всплывающая подсказка, всплывающая подсказка становится видимой. Сами всплывающие подсказки также являются фреймами, которые могут иметь дочерние элементы и быть настроены.
Эта native, которая используется, чтобы сделать tooltip-frame всплывающей подсказкой для некоторых фреймов. Короче, внизу нативка поможет нам создавать подсказки. она прикрепляет к frame подсказку tooltip
BlzFrameSetTooltip takes framehandle frame, framehandle tooltip returns nothing
Пример 1. для ознакомления на BACKDROP
В этом примере разберемся как создается подсказка.
мы создаем 3 фрейма: BACKDROP, TEXT и FRAME. НА BACKDROP отображается изображение Паладина. FRAME копирует точки BACKDROP, и обрабатывает показ всплывающей подсказки. Последним TEXT-Frame является сама всплывающая подсказка, которая отображается при наведении курсора мыши на значок Паладина.
Такой тип как FRAME необходим в этом примере, потому что BACKDROP не может иметь событий, или всплывающих подсказок. На BACKDROP нельзя повесить tooltip. FRAME также не может иметь событий, но может иметь всплывающую подсказку, потому что это предусмотрено игрой.
В этом примере все кадры создаются с помощью BlzCreateFrameByType, это сделано, поэтому в этом примере не нужно беспокоиться о fdf.
BlzCreateFrameByType takes string typeName, string name, framehandle owner, string inherits, integer createContext
код
function Face()
  local face = BlzCreateFrameByType("BACKDROP", "Face", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)--Создан новый фрейм типа BACKDROP
   local faceHover = BlzCreateFrameByType("FRAME", "FaceFrame", face,"", 0) --фрейм типа FRAME. Объясняю: фрейм face является типом BACKDROP, BACKDROP не имеют никаких событии, т.е. нельзя повесить события фрейму BACKDROP. BACKDROP это просто картинка, фон, не отдаст никакой реакции отклика, или еще чего. А еще нельзя повесить на BACKDROP подсказку tooltip через BlzFrameSetTooltip. Поэтому создаем пустышку faceHover типа FRAME, которая невидима для игрока, но на нее можно повесить подсказку. Эту хитрость с FRAME можно использовать не только для создании подсказок, но и отлавливать положение мышки на экрана. Но об этом позже
   local tooltip = BlzCreateFrameByType("TEXT", "FaceFrameTooltip", face,"", 0)--Создаем фрейм типа TEXT
   --фрейм faceHover был бы не нужен, если фрейм face поддерживал events/tooltip. Если у вас кнопка button или любой другой тип фрейм, то вам может этот фрейм faceHover не потребоваться 


   BlzFrameSetAllPoints(faceHover, face) --faceHover копирует размеры и позицию фрейма face.
   BlzFrameSetTooltip(faceHover, tooltip) --когда игрок наводит мышью на faceHover всплывает подсказка tooltip (т.е. становится видимой).

   BlzFrameSetSize(face, 0.04, 0.04)
   BlzFrameSetAbsPoint(face, FRAMEPOINT_CENTER, 0.4, 0.3)
   BlzFrameSetAbsPoint(tooltip, FRAMEPOINT_CENTER, 0.2, 0.3)
   BlzFrameSetText(tooltip, "Human Paladin Face")

   BlzFrameSetTexture(face, "ReplaceableTextures\\CommandButtons\\BTNHeroPaladin",0, true)--фрейм face использует paladin blp как текстуру.
end
Этот код должен быть инициирован. Сам по себе он не работает.
что же получилось. Мы наводим на BACKDROP мышью, а по факту на мышь реагирует FRAME, и запускает отображения текста TEXT.
Пример 2. другой пример на кнопке

Пример 2. Код без импорта на Lua

теперь мы делаем тоже самое. но с кнопкой. Нам не нужно заморачиваться с FRAME. Можно сразу же нацепить на кнопку.
код
do
    local real = MarkGameStarted
 function MarkGameStarted()
    real()
    -- создаем кнопку с шаблоном "ScriptDialogButton"
    local button = BlzCreateFrameByType("GLUETEXTBUTTON", "MyScriptDialogButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScriptDialogButton", 0)
    -- перемещаем кнопку в центр экрана
    BlzFrameSetAbsPoint(button, FRAMEPOINT_CENTER, 0.4, 0.3)
    -- добавляем текст к кнопке
    BlzFrameSetText(button, "My Button Text")

    -- создаем TEXT-Frame
    local tooltipFrame = BlzCreateFrameByType("TEXT", "", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)
    -- tooltipFrame будет всплывающей подсказкой (tooltip) дл нашей кнопки
    BlzFrameSetTooltip(button, tooltipFrame)
    -- связываем подсказку Tooltip с кнопкой Button 
    BlzFrameSetPoint(tooltipFrame, FRAMEPOINT_BOTTOM, button, FRAMEPOINT_TOP, 0, 0.01)
    -- Изначально подсказка скрыта
    BlzFrameSetEnable(tooltipFrame, false)
    BlzFrameSetText(tooltipFrame, "Nothing will Happen when you click this Button.")
 end
end
Пример 3. Развитие примера 1. Добавляем text of tooltip в рамку (box text)
Всплывающая подсказка в предыдущем примере выглядит не очень хорошо, это просто текст на экране. Я хочу, чтобы он был в коробке (box text) и выглядел как стандартная tooltip. Поскольку такой фрейм не существует в стандартном fdf, и нельзя манипулировать показанным текстом фрейма всплывающей подсказки по умолчанию (насколько я знаю), его нужно создать.
Это будет наш текст в рамке fdf. BoxedText - это фрейм, который мы создаем. Что может этот "BoxedText"? Он имитирует поле всплывающей подсказки по умолчанию и имеет 2 дочерних элемента: «BoxedTextTitle» и «BoxedTextValue». Заголовок отображается в первой строке, а под ним будет помещено поле BoxedTextValue. BoxedTextValue имеет меньший размер текста, чем BoxedTextTitle.
fdf код
Frame "BACKDROP" "BoxedTextBackgroundTemplate" {
        DecorateFileNames, //Look-Up Names in some String table (for example gameinterface)
        BackdropTileBackground, //Tile mode enabled
        BackdropBackground  "ToolTipBackground", //BackgroundFile
        BackdropCornerFlags "UL|UR|BL|BR|T|L|B|R",
        BackdropCornerSize  0.008, //higher numbers make the corners bigger.
        BackdropBackgroundInsets 0.0022 0.0022 0.0022 0.0022, //makes the background smaller, from the outside.
        BackdropEdgeFile  "ToolTipBorder", //the border File
        BackdropBlendAll,
}

Frame "BACKDROP" "BoxedText" INHERITS "BoxedTextBackgroundTemplate" {
   UseActiveContext,
 
   Frame "TEXT" "BoxedTextTitle" {
       UseActiveContext,
       DecorateFileNames,
       SetPoint TOPLEFT, "BoxedText", TOPLEFT, 0.005, -0.005, //Positionate "BoxedTextSimpleTitle"'s TOPLEFT to "BoxedText"'s TOPLEFT with an offset
       SetPoint TOPRIGHT, "BoxedText", TOPRIGHT, -0.005, -0.005,
       FontFlags "FIXEDSIZE",
       FrameFont "MasterFont", 0.014, "",
       FontColor 1.0 1.0 1.0 1.0, //Red Green Blue Alpha 0.0 to 1.0
       FontShadowColor 0.0 0.0 0.0 0.9,
       FontShadowOffset 0.001 -0.001,
   }
 
   Frame "TEXT" "BoxedTextValue" {
       UseActiveContext,
       DecorateFileNames,
       SetPoint TOPLEFT, "BoxedText", TOPLEFT, 0.005, -0.02,
       SetPoint BOTTOMRIGHT,  "BoxedText", BOTTOMRIGHT, -0.005, 0.005,
       FontFlags "FIXEDSIZE",
       FrameFont "MasterFont", 0.012, "",
       FontColor 1.0 1.0 1.0 1.0,
       FontShadowColor 0.0 0.0 0.0 0.9,
       FontShadowOffset 0.001 -0.001,
   }
}
Теперь нам нужно немного изменить код. Вместо TEXT мы теперь создаем фрейм с именем «BoxedText». Также всплывающая подсказка больше не TEXT, теперь это поле (box text), что означает, что мы должны получить доступ к дочерним элементам поля (box text), показывающего текст. Это BoxedTextValue и BoxedTextTitle.
код
function Face2()
   BlzLoadTOCFile("war3mapimported\\BoxedText.toc")
  local face = BlzCreateFrameByType("BACKDROP", "Face", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)--Создаем фрейм типа BACKDROP
   local faceHover = BlzCreateFrameByType("FRAME", "FaceFrame", face,"", 0) --фрейм типа FRAME. Объясняю: фрейм face является типом BACKDROP, BACKDROP не имеют никаких событии, т.е. нельзя повесить события фреймов. А еще нельзя повесить на него подсказку tooltip через BlzFrameSetTooltip. Поэтому создаем пустышку faceHover типа FRAME, которая невидима для игрока
   local tooltip = BlzCreateFrame("BoxedText", face, 0, 0)--Создаем фрейм типа TEXT
   --фрейм faceHover был бы не нужен, если фрейм face поддерживал events/tooltip. Если у вас кнопка button или любой другой тип фрейм, то вам может этот фрейм faceHover не потребоваться 

   BlzFrameSetAllPoints(faceHover, face) --faceHover копирует размеры и положение фрейма face.
   BlzFrameSetTooltip(faceHover, tooltip) --когда мышь наводят на фрейм faceHover, всплывает подсказка tooltip.

   BlzFrameSetSize(face, 0.04, 0.04)
   BlzFrameSetAbsPoint(face, FRAMEPOINT_CENTER, 0.4, 0.3)
   BlzFrameSetAbsPoint(tooltip, FRAMEPOINT_CENTER, 0.2, 0.3)
   BlzFrameSetSize(tooltip, 0.15, 0.08)

  BlzFrameSetText(BlzGetFrameByName("BoxedTextValue",0), "Human Paladin Face, but it is not uther.")--BoxedText имеет потомка “BoxedTextValue” - в нем задан шрифт текста, описание текста
    BlzFrameSetText(BlzGetFrameByName("BoxedTextTitle",0), "Paladin")--BoxedText потомка “BoxedTextTitle” - в нем задан шрифт текста, подзаголовок текста

   BlzFrameSetTexture(face, "ReplaceableTextures\\CommandButtons\\BTNHeroPaladin",0, true)--фрейм face задает текстуру паладина
end
Этот код не выполняется сам по себе, его нужно инициировать.
Это приятно, текст в рамке (box), похожий на стандартный. Вместо создания такого BoxedText можно использовать TextArea. TEXTAREA выполняет большую часть BoxedText, но у него есть полоса прокрутки, блокирующая часть правой стороны, и он требует, чтобы поле имело минимальный размер (иначе это приведет к сбою игры / потока). Также становится немного сложно с заголовком.
ChangeLog: Добавлен <UseActiveContext,> дочерним элементам в fdf. Без него текст всплывающей подсказки внутри поля будет работать неправильно, поскольку createcontext не равен 0.
Плюсы 1 способа:
  • Данный способ уникален тем, что благодаря fdf-file можно добавить подзаголовок, так и текст. Не нужно ничего настраивать. Аналогично. думаю, что также можно иконки маны, золота, дерева, пищи к tooltip добавить
Минусы 1 способа:
  • Ограничение текста. Данное описание слишком короткое. Если увеличить кол-во текста во много раз, то текст естественно не влезает в фрейм, и обрезается. В этом регулируют размеры текста фрейма TEXT (ширина, высота). Вы замечали в варкрафте, что размеры подсказок меняют в зависимости от объема текста, вот надо бы также сделать. Пример ниже, один и тот же текст. Слева в примерах 3 и 4 тексты не влезли в рамку, а вот справа это рабочие варианты - примеры 5 и 6, о которых поговорим позже. Справа текст такой большой, что вылез за пределы экрана, и мы уже не видим.
  • BoxedTextValue (TEXT описание) и BoxedTextTitle (TEXT заголовок) привязаны к BoxedText (Bacrdrop). И из-за этого нельзя никак изменять размеры. Нужно в игре чистить BlzFrameClearAllPoints(frame)
Пример 4. Развитие примера 2. добавляем текст в рамку text button
Улучшенная версия примера 2. Код такой же только чуть измененный, добавили рамку
Есть другой пример, в котором не нужно ничего импортировать в карту:
код
do
    local real = MarkGameStarted
 function MarkGameStarted()
    real()
    -- create a new Button which inherits from "ScriptDialogButton"
    local button = BlzCreateFrameByType("GLUETEXTBUTTON", "MyScriptDialogButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScriptDialogButton", 0)
    -- place the Button to the center of the Screen
    BlzFrameSetAbsPoint(button, FRAMEPOINT_CENTER, 0.4, 0.3)
    -- set the Button's text
    BlzFrameSetText(button, "My Button Text")

    -- Create the Background a Backdrop
    local tooltipFrameBackGround = BlzCreateFrame("QuestButtonBaseTemplate", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
    BlzFrameSetSize(tooltipFrameBackGround, 0.25, 0.025)
    -- Create the Text as child of the Background
    local tooltipFrameText = BlzCreateFrameByType("TEXT", "MyScriptDialogButtonTooltip", tooltipFrameBackGround, "", 0)
    -- Copy Size and Position with a small offset.
    BlzFrameSetPoint(tooltipFrameText, FRAMEPOINT_BOTTOMLEFT, tooltipFrameBackGround, FRAMEPOINT_BOTTOMLEFT, 0.01, 0.01)
    BlzFrameSetPoint(tooltipFrameText, FRAMEPOINT_TOPRIGHT, tooltipFrameBackGround, FRAMEPOINT_TOPRIGHT, -0.01, -0.01)
    -- The background becomes the button's tooltip, the Text as child of the background will share the visibility
    BlzFrameSetTooltip(button, tooltipFrameBackGround)
    -- Place the Tooltip above the Button
    BlzFrameSetPoint(tooltipFrameBackGround, FRAMEPOINT_BOTTOM, button, FRAMEPOINT_TOP, 0, 0.01)
    -- Prevent the TEXT from taking mouse control
    BlzFrameSetEnable(tooltipFrameText, false)
    BlzFrameSetText(tooltipFrameText, "Nothing will Happen when you click this Button.")
 end
end
Недостаток примера 4:
  • Размер подсказки не меняется с объемом текста. Этого не предусмотрено.

Как задать оффсеты?

этот краткий курс поможет нам привязать box к text
эти ниже две строчки задают оффсеты
BlzFrameSetPoint(tooltipFrameBackGround, FRAMEPOINT_BOTTOMLEFT, tooltipFrameText, FRAMEPOINT_BOTTOMLEFT, -0.02, -0.02)
BlzFrameSetPoint(tooltipFrameBackGround, FRAMEPOINT_TOPRIGHT, tooltipFrameText, FRAMEPOINT_TOPRIGHT, 0.02, 0.02)
Если обнулить оффсеты, то получим как в первом варианте на картинке выше.
А если задать оффсеты, то получим по краям поля.
Стандартный вариковский offset имеет 0.005

Как расширяется рамка?

Как расширяется рамка? Рамка расширяется вверх, если объем текста увеличивается (можно настроить и по-другому). Тут Привязывают точки рамки к тексту-фрейму. А нижняя точка текст-фрейма к кнопке, ширину задали, а высоту спец обнулили. Текст не может расширяться вниз, поэтому расширяется вверх
-- the text has a Width of 0.25, and starts a new line when the given text is longer
BlzFrameSetSize(tooltipFrameText, 0.25, 0)
BlzFrameSetPoint(tooltipFrameText, FRAMEPOINT_BOTTOM, button, FRAMEPOINT_TOP, 0, 0.03)
Это был пример с подсказкой, когда вертикально вверх растягивали. Можно еще и горизонтально растянуть влево. Пример, кнопка с зарядами, рамка зарядов растягивается от кол-ва цифр.

Ограничения

Единственное, что хочу обратить, что текста выше на картинке оказалось слишком много, и сверху не получилось игре образовать поле, тк рамка уперлась в границы экрана. И даже текст едва не вылез за верхнюю границу.
Тут еще стоит учитывать и ограничения экрана 4:3 для Game_UI. Если создать подсказку за пределами экрана, то подсказка не красиво смотрится, и текст и рамка съезжают, размеры сужаются. Поэтому стоит выбрать другого родителя для подсказки.
Можете предусмотреть лимит текста или размеры рамки.
Пример 5. Улучшенная версия 4
Предыдущий пример хорош, но в нем есть кое-что неприятное, нужно установить размер коробки. Было бы намного лучше, если бы поле соответствовало тексту. Это можно сделать, вместо того, чтобы просто помещать текст в поле, надо заставить размеры рамки меняться в зависимости от объема текста.
Игра даже поддерживает один при обработке мультилиний с использованием 0 в качестве высоты для TEXT-Frame. Но теперь нужно позаботиться о том, чтобы поле было расположено относительно текста, что означает, что нужно разместить текст с дополнительным размером поля.
код
do
    local real = MarkGameStarted
 function MarkGameStarted()
    real()
    -- create a new Button which inherits from "ScriptDialogButton"
    local button = BlzCreateFrameByType("GLUETEXTBUTTON", "MyScriptDialogButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScriptDialogButton", 0)
    -- place the Button to the center of the Screen
    BlzFrameSetAbsPoint(button, FRAMEPOINT_CENTER, 0.4, 0.3)
    -- set the Button's text
    BlzFrameSetText(button, "My Button Text")

    -- Create the Background a Backdrop
    local tooltipFrameBackGround = BlzCreateFrame("QuestButtonBaseTemplate", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
    
    -- Create the Text as child of the Background
    local tooltipFrameText = BlzCreateFrameByType("TEXT", "MyScriptDialogButtonTooltip", tooltipFrameBackGround, "", 0)
    -- the text has a Width of 0.25, and starts a new line when the given text is longer
    BlzFrameSetSize(tooltipFrameText, 0.25, 0)
    -- Copy Size and Position with a small offset.
    BlzFrameSetPoint(tooltipFrameBackGround, FRAMEPOINT_BOTTOMLEFT, tooltipFrameText, FRAMEPOINT_BOTTOMLEFT, -0.02, -0.02)
    BlzFrameSetPoint(tooltipFrameBackGround, FRAMEPOINT_TOPRIGHT, tooltipFrameText, FRAMEPOINT_TOPRIGHT, 0.02, 0.02)
    -- The background becomes the button's tooltip, the Text as child of the background will share the visibility
    BlzFrameSetTooltip(button, tooltipFrameBackGround)
    -- Place the Tooltip above the Button
    BlzFrameSetPoint(tooltipFrameText, FRAMEPOINT_BOTTOM, button, FRAMEPOINT_TOP, 0, 0.03)
    -- Prevent the TEXT from taking mouse control
    BlzFrameSetEnable(tooltipFrameText, false)
    BlzFrameSetText(tooltipFrameText, "Nothing will Happen when you click this Button.")
 end
end
BlzFrameIsVisible (frame) также возвращает правильное значение для фреймов, работающих как всплывающие подсказки. Это асинхронно, поэтому довольно быстро, но также опасно. Его можно использовать для выполнения зависания IsFrame без событий входа / выхода (которые отправляют сетевые пакеты). При этом создается пустой «FRAME» и определяется его как всплывающая подсказка, настраивается способ узнать, какая всплывающая подсказка и фрейм принадлежат друг другу, и периодически проверять видимость всплывающей подсказки «FRAME», если она видна, а не последняя зависшая. у вас есть событие async enter.
Пример 6. Улучшенная версия 3
Мы переделали fdf-code и теперь можем вызывать код отдельно. Но что-то взяли из 5 примера. Короче все то же самое, что было и в предыдущем варианте. Я решил вместо BACKDROP на кнопку BUTTON прикрепить подсказку. И не нужна нам теперь вспомогательный FRAME, что был в первых примерах..
fdf-file
fdf код
Frame "BACKDROP" "BoxedTextBackgroundTemplate" {
        DecorateFileNames, //Look-Up Names in some String table (for example gameinterface)
        BackdropTileBackground, //Tile mode enabled
        BackdropBackground  "ToolTipBackground", //BackgroundFile
        BackdropCornerFlags "UL|UR|BL|BR|T|L|B|R",
        BackdropCornerSize  0.008, //higher numbers make the corners bigger.
        BackdropBackgroundInsets 0.0022 0.0022 0.0022 0.0022, //makes the background smaller, from the outside.
        BackdropEdgeFile  "ToolTipBorder", //the border File
        BackdropBlendAll,
}
    
Frame "TEXT" "BoxedTextTitle" {
    UseActiveContext,
    DecorateFileNames,

    FontFlags "FIXEDSIZE",
    FrameFont "MasterFont", 0.014, "",

    FontColor 1.0 1.0 1.0 1.0, //Red Green Blue Alpha 0.0 to 1.0
    FontShadowColor 0.0 0.0 0.0 0.9,
    FontShadowOffset 0.001 -0.001,
}
    
Frame "TEXT" "BoxedTextValue" {
    UseActiveContext,
    DecorateFileNames,

    FontFlags "FIXEDSIZE",
    FrameFont "MasterFont", 0.012, "",
    FontColor 1.0 1.0 1.0 1.0,
    FontShadowColor 0.0 0.0 0.0 0.9,
    FontShadowOffset 0.001 -0.001,
}
lua-код
do
    local real = MarkGameStarted
 function MarkGameStarted()
    real()
    
    --загрузка toc-file
    function LoadToc(s)
        if BlzLoadTOCFile(s) then
            print("Loaded: "..s)
        else   
            print("Failed to Load: "..s)
        end   
    end
            
    --загружаем toc-file
    LoadToc("templates.toc")
    
    --создаем кнопку
    --local button = BlzCreateFrameByType("GLUETEXTBUTTON", "MyScriptDialogButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScriptDialogButton", 0)
    --BlzFrameSetAbsPoint(button, FRAMEPOINT_CENTER, 0.4, 0.3)
    --BlzFrameSetText(button, "My Button Text")
    
    
   
    local button = BlzCreateFrameByType("BUTTON", "MyIconButton", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScoreScreenTabButtonTemplate", 0)
    local buttonIconFrame = BlzCreateFrameByType("BACKDROP", "MyIconButtonIcon", button, "", 0)
    BlzFrameSetAllPoints(buttonIconFrame, button)
    BlzFrameSetAbsPoint(button, FRAMEPOINT_CENTER, 0.4, 0.3)
    BlzFrameSetSize(button, 0.03, 0.03)
    BlzFrameSetTexture(buttonIconFrame, "ReplaceableTextures\\CommandButtons\\BTNSelectHeroOn", 0, false)
    
    

    --создаем рамку
    local tooltipFrameBackGround = BlzCreateFrame("BoxedTextBackgroundTemplate", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), 0, 0)
    
    --создаем текст
    local tooltipFrameText = BlzCreateFrameByType("TEXT", "MyText", tooltipFrameBackGround, "BoxedTextValue", 0)
    --текст шириной 0.25
    BlzFrameSetSize(tooltipFrameText, 0.25, 0)
    -- рамка копирует размеры с оффсетами
    BlzFrameSetPoint(tooltipFrameBackGround, FRAMEPOINT_BOTTOMLEFT, tooltipFrameText, FRAMEPOINT_BOTTOMLEFT, -0.02, -0.02)
    BlzFrameSetPoint(tooltipFrameBackGround, FRAMEPOINT_TOPRIGHT, tooltipFrameText, FRAMEPOINT_TOPRIGHT, 0.02, 0.02)
    
    BlzFrameSetTooltip(button, tooltipFrameBackGround)
    -- Place the Tooltip above the Button
    BlzFrameSetPoint(tooltipFrameText, FRAMEPOINT_BOTTOM, button, FRAMEPOINT_TOP, 0, 0.03)
    -- Prevent the TEXT from taking mouse control
    BlzFrameSetEnable(tooltipFrameText, false)
    BlzFrameSetText(tooltipFrameText, "Первым человеком, который заразился новым коронавирусом, мог стать сотрудник лаборатории в Ухане, который собирал образцы у летучих мышей в естественной среде, сообщил руководитель группы экспертов Всемирной организации здравоохранения (ВОЗ), датский ученый Питер Эмбарек в интервью датскому каналу tv2. «Сотрудник, который был заражен в полевых условиях во время сбора материала, является одной из вероятных гипотез. Это место, где вирус переходит непосредственно от летучей мыши к человеку. В этом случае это был бы работник лаборатории, а не случайный житель деревни или другой человек, который регулярно контактирует с летучими мышами», -- пояснил Эмбарек. В ВОЗ допустили одобрение «Спутника V» к середине сентябряУченый подчеркнул, что эксперты ВОЗ не нашли прямых доказательств того, что вспышка коронавируса связана с исследованиями летучих мышей в лаборатории Уханя. В марте этого года ВОЗ опубликовала доклад о возникновении COVID-19. ВОЗ представила в нем четыре версии появления вируса. Наиболее вероятной авторы считают версию о передаче коронавируса человеку от летучих мышей через животное-посредника. При этом версию об утечке вируса из лаборатории в Ухане в ВОЗ назвали «крайне маловероятной». Затем гендиректор ВОЗ доктор Тедрос Аданом Гебрейесус заявил, что организация готовится ко второму этапу расследования появления коронавируса и ожидает прозрачности от китайских властей. Он заявил, что исключать версию, что коронавирус распространился после утечки из лаборатории в Китае, пока рано, и призвал Китай к открытому сотрудничеству. Он также сообщил, что ВОЗ планирует проверить лабораторию в Ухане, рядом с которой были зарегистрированы первые случаи заражения COVID-19.")

    
 end
end
Пример 7. Использовать события фреймов.
Можно вместо BlzFrameSetTooltip(frame, tooltip) использовать события входа мыши внутрь фрейма и выхода мыши из фрейма. код неполный, я его выдрал для примера.
код
    if true then -- События кликов по кнопке
        print("создана ативная кнопка")
        local  ClickTrig = CreateTrigger()
        BlzFrameSetEnable(BlzGetTriggerFrame(), false)
        BlzFrameSetEnable(BlzGetTriggerFrame(), true)
        BlzTriggerRegisterFrameEvent(ClickTrig, SelfFrame, FRAMEEVENT_CONTROL_CLICK)
        BlzTriggerRegisterFrameEvent(ClickTrig, ChargeContent, FRAMEEVENT_CONTROL_CLICK)
        TriggerAddAction(ClickTrig, function ()
            print("Нажата кнопка ")
            BlzFrameSetEnable(BlzGetTriggerFrame(), false)
            BlzFrameSetEnable(BlzGetTriggerFrame(), true)
        end)
    end
    local  TrigMOUSE_ENTER = CreateTrigger()
    BlzTriggerRegisterFrameEvent( TrigMOUSE_ENTER, SelfFrame, FRAMEEVENT_MOUSE_ENTER)
    BlzTriggerRegisterFrameEvent( TrigMOUSE_ENTER, ChargeContent, FRAMEEVENT_MOUSE_ENTER)
    TriggerAddAction( TrigMOUSE_ENTER, function ()
        print("показать подсказку")
    end)
    local  TrigMOUSE_LEAVE = CreateTrigger()
    BlzTriggerRegisterFrameEvent( TrigMOUSE_LEAVE, SelfFrame, FRAMEEVENT_MOUSE_LEAVE)
    BlzTriggerRegisterFrameEvent( TrigMOUSE_LEAVE, ChargeContent, FRAMEEVENT_MOUSE_LEAVE)
    TriggerAddAction( TrigMOUSE_LEAVE, function ()
        print("убрать подсказку")
    end)
Недостаток:
  • эти событии реагируют медленнее. И точность падает при быстром перемещении мыши, особенно на маленьких фреймах. Вы зашли, а когда вышли, до сих пор игра будет говорить, что мышь внутри. Короче, этот недостаток событии. Рекомендую использовать BlzFrameSetTooltip(frame, tooltip) , тк игра сама рассчитывать, нечего изобретать велосипед

Изображения + значки (золото, дерево, еда, мана и др)

стандартный фон tooltip и границы фона, плюс вместе с подсказками содержат иногда различные иконки ресурсов. Пример, когда вы наводите мышью на предмет или юнита в магазине, у вас отображается подсказка вместе со иконками золото/дерево и стоимость. Аналогично, когда вы пытаетесь навести мышкой на иконку способности, у вас отображается кол-во маны, которую вы затратите за каст. Все можно посмотреть в редакторе карт в GameInterface.
ToolTipBackground=UI\Widgets\ToolTips\Human\human-tooltip-background.blp
ToolTipBorder=UI\Widgets\ToolTips\Human\human-tooltip-border.blp
ToolTipGoldIcon=UI\Widgets\ToolTips\Human\ToolTipGoldIcon.blp
ToolTipLumberIcon=UI\Widgets\ToolTips\Human\ToolTipLumberIcon.blp
ToolTipStonesIcon=UI\Widgets\ToolTips\Human\ToolTipStonesIcon.blp
ToolTipManaIcon=UI\Widgets\ToolTips\Human\ToolTipManaIcon.blp
ToolTipSupplyIcon=UI\Widgets\ToolTips\Human\ToolTipSupplyIcon.blp
ToolTipHorizontalSeparator=UI\Widgets\ToolTips\Human\HorizontalSeparator.blp
Все эти вышеперечисленные переменные (константы) вы можете вписать в fdf-file, или использовать указанный путь в триггерах или еще где.
Один угол рамки привязываем к Text. Другой угол рамки привязываем к Ttitle Text. Содержимое внутри должно быть связано друг с другом точками, думаю вы поняли как работать?!.
К сожалению нет fdf-file образцов, это похоже внутри движка создается все. для изменения данных текста tooltip нам нужно создать триггерно. Но мы можем сами воссоздать этот шаблон, не так уж и трудно.

примеры Tooltips

подсказка без требовании
обычная подсказка, которая не имеет требовании в аргументах
lua код
используется импорт fdf-file, указанный выше
пусть вас не смущает, что вместо обычной кнопки button или gluebutton указан slider, тк убирает залипание клавиатуры и панорамирование камеры. slider это просто такая же обычная кнопка.
function LoadToc(s)
    if BlzLoadTOCFile(s) then
        print("Loaded: "..s)
    else
        print("Failed to Load: "..s)
    end
end
do
	local real = MarkGameStarted
	function MarkGameStarted()
        real()
		
		BlzLoadTOCFile("war3mapImported\\MySimpleButton.toc")

		local gameUI = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)

		local path_active_icon = "ReplaceableTextures\\CommandButtons\\BTN"
		local path_disabled_icon = "eplaceableTextures\\CommandButtonsDisabled\\DISBTN"
		local path_icon_cancel = "Cancel"
		local cancel_text_tip = "Отмена (|cffffcc00ESC|r)"
		local cancel_text_ubertip = "Отменяет выбранный приказ"
		local size_button = 0.039
		--
		local button_cancel = BlzCreateFrameByType("SLIDER","button cancel",gameUI,"",0)
		local icon_button_cancel = BlzCreateFrameByType("BACKDROP","IconTexture",button_cancel,"",0)
		BlzFrameSetAbsPoint(button_cancel, FRAMEPOINT_CENTER, 0.4, 0.3)
		BlzFrameSetAllPoints(icon_button_cancel,button_cancel)
		BlzFrameSetTexture(icon_button_cancel, path_active_icon .. path_icon_cancel, 0, true)
		BlzFrameSetSize(button_cancel, size_button, size_button)
		--BlzFrameSetVisible(button_cancel, false)

		local tooltip_button_cancel = BlzCreateFrameByType("FRAME","tooltip",button_cancel,"",0)
        BlzFrameSetVisible(tooltip_button_cancel, false)
        
		local backdrop_tooltip_button_cancel = BlzCreateFrameByType("BACKDROP","backdrop tooltip",tooltip_button_cancel,"BoxedTextBackgroundTemplate",0)
		local description_tooltip_button_cancel = BlzCreateFrameByType("TEXT","description tooltip",tooltip_button_cancel,"BoxedTextValue",0)
		local title_tooltip_button_cancel = BlzCreateFrameByType("TEXT","title tooltip",tooltip_button_cancel,"BoxedTextTitle",0)
		local separator_tooltip_button_cancel = BlzCreateFrameByType("BACKDROP","Separator",tooltip_button_cancel,"",0)

		BlzFrameSetAbsPoint(description_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, 0.55, 0.19)
		BlzFrameSetSize(description_tooltip_button_cancel, 0.25, 0)
		BlzFrameSetEnable(description_tooltip_button_cancel, false)
		BlzFrameSetText(description_tooltip_button_cancel,cancel_text_ubertip)

		BlzFrameSetPoint(separator_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, description_tooltip_button_cancel, FRAMEPOINT_TOPLEFT, 0.0025, 0.0025)
		BlzFrameSetPoint(separator_tooltip_button_cancel, FRAMEPOINT_BOTTOMRIGHT, description_tooltip_button_cancel, FRAMEPOINT_TOPRIGHT, 0.0025, 0.0025)
        BlzFrameSetSize(separator_tooltip_button_cancel, 0, 0.0015)
        BlzFrameSetTexture(separator_tooltip_button_cancel, "UI\\Widgets\\ToolTips\\Human\\HorizontalSeparator",0, true) 

		BlzFrameSetPoint(title_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, separator_tooltip_button_cancel, FRAMEPOINT_TOPLEFT, -0.005, 0.005)
		BlzFrameSetSize(title_tooltip_button_cancel, 0.25, 0)
		BlzFrameSetEnable(title_tooltip_button_cancel, false)
		BlzFrameSetText(title_tooltip_button_cancel,cancel_text_tip)

		BlzFrameSetPoint(backdrop_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, description_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, -0.005, -0.005)
		BlzFrameSetPoint(backdrop_tooltip_button_cancel, FRAMEPOINT_TOPRIGHT, title_tooltip_button_cancel, FRAMEPOINT_TOPRIGHT, 0.005, 0.005)
        BlzFrameSetTooltip(button_cancel, tooltip_button_cancel)

		local trigger_button_cancel_click=CreateTrigger()
		BlzTriggerRegisterFrameEvent(trigger_button_cancel_click, button_cancel, FRAMEEVENT_MOUSE_UP)
		TriggerAddAction(trigger_button_cancel_click,function()
		        print('click button "cancel"')
		end)
  end
end
подсказка с требованием ресурсов (определен пример порядка ресов)
в варкрафте у кнопки любой кнопки есть свои требования под ресурсы. Пример, заклинание требует ману, и заюзать кнопку можно только при наличии маны. Или кнопки юнитов или здании, имеют в требованиях стоимостсть золота и дерева. А еще при обучении или наймы требует провиант/пища.
В дефолтном варике всего выделю 4 требовательных ресурса: золото, древесина, мана, пища. Они будет располагаться в таком порядке: 1) золото, 2) древесина, 3) мана, 4) пища. Порядок можно изменить. К чему этот порядок введен? Ну, если я уберу в требованиях ману, то порядок примет вид: золото, древесина, пища. Если какой-то ресурс не указан, то он убирается. В зависимости от условии можно получить разные сочетания: 2^4=16 видов взаимодействии. В игре часто можно увидеть только:
  • золото+древесина => при постройке/найме/обучении/исследовании/покупке
  • золото+древесина +пища => при найме может потребовать провиант
  • мана => часто для заклинании
  • золото+древесина+мана => такое вообще нельзя увидеть, мб у каких то единичных способностей, честно такого не помню.
В своем примере, я специально завел 4 переменные, в которых указаны значения ресурсов.
		 local gold_cost = 11
        local lumber_cost = 22
        local mana_cost = 200
        local food_cost = 70
в первом варианте я забыл про пищу
позднее добавил фреймы пищи
Можно убрать в требованиях древесину (lumber cost = 0), и тогда у вас будет только золото, мана, пища. Можно и совсем убрать требования, обнулив все. Внизу представлены разные варианты взаимодействия (ресы убираются обнулением переменной):
можно и увеличить ресурсы, добавив еще и камень, воду итд. это тоже легко делается. Однако, я просто расчитывал в ряд забивать в трбевание ресурсы. Если у вас ресурсов будет очень много, и не уместиться в ряд. пример просто не расчитан на такое. максимум 3-4 реса. Иначе просто придеться придумывать как опускать не вмещающие ресы на следующую строчкау вниз или придуть что-то еще. может быть FrameList-6LA" >это или это
lua код
function LoadToc(s)
    if BlzLoadTOCFile(s) then
        print("Loaded: "..s)
    else
        print("Failed to Load: "..s)
    end
end
do
	local real = MarkGameStarted
	function MarkGameStarted()
        real()
		
		BlzLoadTOCFile("war3mapImported\\MySimpleButton.toc")

		local gameUI = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)

		local path_active_icon = "ReplaceableTextures\\CommandButtons\\BTN"
		local path_disabled_icon = "eplaceableTextures\\CommandButtonsDisabled\\DISBTN"
		local path_icon_cancel = "Cancel"
		local cancel_text_tip = "Отмена (|cffffcc00ESC|r)"
		local cancel_text_ubertip = "Отменяет выбранный приказ"
		local size_button = 0.039
        
        local gold_cost = 11
        local lumber_cost = 22
        local mana_cost = 200
        local food_cost = 70
        
        --
        ToolTipBackground="UI\\Widgets\\ToolTips\\Human\\human-tooltip-background"
        ToolTipBorder="UI\\Widgets\\ToolTips\\Human\\human-tooltip-border"
        ToolTipGoldIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipGoldIcon"
        ToolTipLumberIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipLumberIcon"
        ToolTipStonesIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipStonesIcon"
        ToolTipManaIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipManaIcon"
        ToolTipSupplyIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipSupplyIcon"
        ToolTipHorizontalSeparator="UI\\Widgets\\ToolTips\\Human\\HorizontalSeparator"
        
		--
		local button_cancel = BlzCreateFrameByType("SLIDER","button cancel",gameUI,"",0)
		local icon_button_cancel = BlzCreateFrameByType("BACKDROP","IconTexture",button_cancel,"",0)
		BlzFrameSetAbsPoint(button_cancel, FRAMEPOINT_CENTER, 0.4, 0.3)
		BlzFrameSetAllPoints(icon_button_cancel,button_cancel)
		BlzFrameSetTexture(icon_button_cancel, path_active_icon .. path_icon_cancel, 0, true)
		BlzFrameSetSize(button_cancel, size_button, size_button)
		--BlzFrameSetVisible(button_cancel, false)

		local tooltip_button_cancel = BlzCreateFrameByType("FRAME","tooltip",button_cancel,"",0)
        BlzFrameSetVisible(tooltip_button_cancel, false)
        
		local backdrop_tooltip_button_cancel = BlzCreateFrameByType("BACKDROP","backdrop tooltip",tooltip_button_cancel,"BoxedTextBackgroundTemplate",0)
		local description_tooltip_button_cancel = BlzCreateFrameByType("TEXT","description tooltip",tooltip_button_cancel,"BoxedTextValue",0)
		local title_tooltip_button_cancel = BlzCreateFrameByType("TEXT","title tooltip",tooltip_button_cancel,"BoxedTextTitle",0)
		local separator_tooltip_button_cancel = BlzCreateFrameByType("BACKDROP","Separator",tooltip_button_cancel,"",0)

		BlzFrameSetAbsPoint(description_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, 0.55, 0.19)
		BlzFrameSetSize(description_tooltip_button_cancel, 0.25, 0)
		BlzFrameSetEnable(description_tooltip_button_cancel, false)
		BlzFrameSetText(description_tooltip_button_cancel,cancel_text_ubertip)

		BlzFrameSetPoint(separator_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, description_tooltip_button_cancel, FRAMEPOINT_TOPLEFT, 0.0025, 0.0025)
		BlzFrameSetPoint(separator_tooltip_button_cancel, FRAMEPOINT_BOTTOMRIGHT, description_tooltip_button_cancel, FRAMEPOINT_TOPRIGHT, -0.003, 0.0025)
        BlzFrameSetSize(separator_tooltip_button_cancel, 0, 0.0015) --толщина линии
        BlzFrameSetTexture(separator_tooltip_button_cancel, "UI\\Widgets\\ToolTips\\Human\\HorizontalSeparator",0, true) 

        BlzFrameSetSize(title_tooltip_button_cancel, 0.25, 0)
		BlzFrameSetEnable(title_tooltip_button_cancel, false)
		BlzFrameSetText(title_tooltip_button_cancel,cancel_text_tip)
        
        local icon_mana_cost = BlzCreateFrameByType("BACKDROP","icon_mana_cost",tooltip_button_cancel,"",0)
        BlzFrameSetSize(icon_mana_cost, 0.012, 0.012)
        BlzFrameSetTexture(icon_mana_cost, ToolTipManaIcon, 0, true)

        local text_mana_cost = BlzCreateFrameByType("TEXT","text_mana_cost",icon_mana_cost,"BoxedTextValue",0)          
        BlzFrameSetEnable(text_mana_cost, false)
        BlzFrameSetPoint(text_mana_cost, FRAMEPOINT_LEFT, icon_mana_cost, FRAMEPOINT_RIGHT, 0.0025, 0.0)
        BlzFrameSetSize(text_mana_cost, 0, 0.012)
        BlzFrameSetText(text_mana_cost,'|cffffcc00'..mana_cost..'|r')
        
        local icon_gold_cost = BlzCreateFrameByType("BACKDROP","icon_gold_cost",tooltip_button_cancel,"",0)  
        BlzFrameSetSize(icon_gold_cost, 0.012, 0.012)
        BlzFrameSetTexture(icon_gold_cost, ToolTipGoldIcon, 0, true)
            
        local text_gold_cost = BlzCreateFrameByType("TEXT","text_gold_cost",icon_gold_cost,"BoxedTextValue",0)          
        BlzFrameSetEnable(text_gold_cost, false)
        BlzFrameSetPoint(text_gold_cost, FRAMEPOINT_LEFT, icon_gold_cost, FRAMEPOINT_RIGHT, 0.0025, 0.0)
        BlzFrameSetSize(text_gold_cost, 0, 0.012)
        BlzFrameSetText(text_gold_cost,'|cffffcc00'..gold_cost..'|r')

        local icon_lumber_cost = BlzCreateFrameByType("BACKDROP","icon_lumber_cost",tooltip_button_cancel,"",0)
        BlzFrameSetSize(icon_lumber_cost, 0.012, 0.012)
        BlzFrameSetTexture(icon_lumber_cost, ToolTipLumberIcon, 0, true)
        
        local text_lumber_cost = BlzCreateFrameByType("TEXT","text_lumber_cost",icon_lumber_cost,"BoxedTextValue",0)          
        BlzFrameSetEnable(text_lumber_cost, false)
        BlzFrameSetPoint(text_lumber_cost, FRAMEPOINT_LEFT, icon_lumber_cost, FRAMEPOINT_RIGHT, 0.0025, 0.0)
        BlzFrameSetSize(text_lumber_cost, 0, 0.012)
        BlzFrameSetText(text_lumber_cost,'|cffffcc00'..lumber_cost..'|r')

        local icon_food_cost = BlzCreateFrameByType("BACKDROP","icon_food_cost",tooltip_button_cancel,"",0)
        BlzFrameSetSize(icon_food_cost, 0.012, 0.012)
        BlzFrameSetTexture(icon_food_cost, ToolTipSupplyIcon, 0, true)
        
        local text_food_cost = BlzCreateFrameByType("TEXT","text_food_cost",icon_food_cost,"BoxedTextValue",0)          
        BlzFrameSetEnable(text_food_cost, false)
        BlzFrameSetPoint(text_food_cost, FRAMEPOINT_LEFT, icon_food_cost, FRAMEPOINT_RIGHT, 0.0025, 0.0)
        BlzFrameSetSize(text_food_cost, 0, 0.012)
        BlzFrameSetText(text_food_cost,'|cffffcc00'..food_cost..'|r')


        --создаем список, определяющий порядок в горизонтальном рядом ресурсов
        local frame_List = {}

        BlzFrameClearAllPoints(icon_gold_cost)
        BlzFrameClearAllPoints(icon_lumber_cost)
        BlzFrameClearAllPoints(icon_mana_cost)
        BlzFrameClearAllPoints(icon_food_cost)

        if gold_cost>0 then
            frame_List[#frame_List+1]=icon_gold_cost
            frame_List[#frame_List+1]=text_gold_cost
            
            BlzFrameSetVisible(icon_gold_cost, true)
        else
            BlzFrameSetVisible(icon_gold_cost, false)
        end
        if lumber_cost>0 then
            frame_List[#frame_List+1]=icon_lumber_cost
            frame_List[#frame_List+1]=text_lumber_cost
            BlzFrameSetVisible(icon_lumber_cost, true)
        else
            BlzFrameSetVisible(icon_lumber_cost, false)
        end
        if mana_cost>0 then
            frame_List[#frame_List+1]=icon_mana_cost
            frame_List[#frame_List+1]=text_mana_cost
            BlzFrameSetVisible(icon_mana_cost, true)
        else
            BlzFrameSetVisible(icon_mana_cost, false)
        end 
        if food_cost>0 then
            frame_List[#frame_List+1]=icon_food_cost
            frame_List[#frame_List+1]=text_food_cost
            BlzFrameSetVisible(icon_food_cost, true)
        else
            BlzFrameSetVisible(icon_food_cost, false)
        end 
        --порядок определен, теперь прикрепляем звенья горизонтального ряда друг с другом
        for a=#frame_List-1, 1, -2 do 
            --у каждого ресурса 2 фрейма: иконка и текст.
            --фреймы между ресурсами крепим друг к другу, иконка одного реса креится к тексту другого реса
            if a>1 then 
                BlzFrameSetPoint(frame_List[a], FRAMEPOINT_LEFT, frame_List[a-1], FRAMEPOINT_RIGHT, 0.005, 0.0)
            end
        end
        
        BlzFrameSetPoint(frame_List[1], FRAMEPOINT_BOTTOMLEFT, separator_tooltip_button_cancel, FRAMEPOINT_TOPLEFT, -0.0018, 0.0025)
        BlzFrameSetPoint(title_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, frame_List[1], FRAMEPOINT_TOPLEFT, 0.00025, 0.0025)

		BlzFrameSetPoint(backdrop_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, description_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, -0.005, -0.005)
		BlzFrameSetPoint(backdrop_tooltip_button_cancel, FRAMEPOINT_TOPRIGHT, title_tooltip_button_cancel, FRAMEPOINT_TOPRIGHT, 0.005, 0.005)
        BlzFrameSetTooltip(button_cancel, tooltip_button_cancel)
  end
end
подсказка с требованием здании
при покупке/найме или исследования необходимо было построить какое-то здание. А если оно уничтожается/игрок теряет над ним контроль, то нужно хотя бы одно здание построить
Обычно, такие требования как постройка здания находится в высшем приоритете, чем требования ресурсов. И кнопка затемняется, а на месте подсказки ресурсов не видно. Решил немного переделать на таблицы требования, тк вдальнейшем будут обращения по индексу кнопки.
        local requirements = {}
        requirements[FourCC('Hate')]={
            gold_cost = 11,
            lumber_cost = 22,
            mana_cost = 200,
            food_cost = 70,
            buildings_required = {'hhou'}
        }
тут добавился список построек, который можно указать как
buildings_required = {'hhou'}
если необходимо несколько здании, можно указать через запятую
buildings_required = {'hhou','hbar'}
тут оказывается сложнее сделать, нужно постоянно фиксировать, что у игрока есть хотя бы одно построенное здание. по идее тут фиксируем заход курсорв мыши в фрейм, и обновляем подсказку. Также можно фикировать игроком получение или потери здания, и тогда сосчитать нужно не обнулись кол-во, чтобы вернуть требование, если че.
код
хотя хоть получился своеобразным. требуется некоторое осмысление как конструкцию делать удобнее.
function LoadToc(s)
    if BlzLoadTOCFile(s) then
        print("Loaded: "..s)
    else
        print("Failed to Load: "..s)
    end
end
do
	local real = MarkGameStarted
	function MarkGameStarted()
        real()
		
		BlzLoadTOCFile("war3mapImported\\MySimpleButton.toc")

		local gameUI = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)

		local path_active_icon = "ReplaceableTextures\\CommandButtons\\BTN"
		local path_disabled_icon = "ReplaceableTextures\\CommandButtonsDisabled\\DISBTN"
		local path_icon_cancel = "Cancel"
		local cancel_text_tip = "Отмена (|cffffcc00ESC|r)"
		local cancel_text_ubertip = "Отменяет выбранный приказ"
		local size_button = 0.039
        
        
        local requirements = {}
        requirements[FourCC('Hate')]={
            gold_cost = 11,
            lumber_cost = 22,
            mana_cost = 200,
            food_cost = 70,
            buildings_required = {'hhou'}
        }
        
        --
        ToolTipBackground="UI\\Widgets\\ToolTips\\Human\\human-tooltip-background"
        ToolTipBorder="UI\\Widgets\\ToolTips\\Human\\human-tooltip-border"
        ToolTipGoldIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipGoldIcon"
        ToolTipLumberIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipLumberIcon"
        ToolTipStonesIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipStonesIcon"
        ToolTipManaIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipManaIcon"
        ToolTipSupplyIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipSupplyIcon"
        ToolTipHorizontalSeparator="UI\\Widgets\\ToolTips\\Human\\HorizontalSeparator"
        
		--
		local button_cancel = BlzCreateFrameByType("SLIDER","button cancel",gameUI,"",0)
		local icon_button_cancel = BlzCreateFrameByType("BACKDROP","IconTexture",button_cancel,"",0)
		BlzFrameSetAbsPoint(button_cancel, FRAMEPOINT_CENTER, 0.4, 0.3)
		BlzFrameSetAllPoints(icon_button_cancel,button_cancel)
		BlzFrameSetTexture(icon_button_cancel, path_active_icon .. path_icon_cancel, 0, true)
		BlzFrameSetSize(button_cancel, size_button, size_button)
		--BlzFrameSetVisible(button_cancel, false)

		local tooltip_button_cancel = BlzCreateFrameByType("FRAME","tooltip",button_cancel,"",0)
        BlzFrameSetVisible(tooltip_button_cancel, false)
        
		local backdrop_tooltip_button_cancel = BlzCreateFrameByType("BACKDROP","backdrop tooltip",tooltip_button_cancel,"BoxedTextBackgroundTemplate",0)
		local description_tooltip_button_cancel = BlzCreateFrameByType("TEXT","description tooltip",tooltip_button_cancel,"BoxedTextValue",0)
		local title_tooltip_button_cancel = BlzCreateFrameByType("TEXT","title tooltip",tooltip_button_cancel,"BoxedTextTitle",0)
		local separator_tooltip_button_cancel = BlzCreateFrameByType("BACKDROP","Separator",tooltip_button_cancel,"",0)

		BlzFrameSetAbsPoint(description_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, 0.55, 0.19)
		BlzFrameSetSize(description_tooltip_button_cancel, 0.25, 0)
		BlzFrameSetEnable(description_tooltip_button_cancel, false)
		BlzFrameSetText(description_tooltip_button_cancel,cancel_text_ubertip)

		BlzFrameSetPoint(separator_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, description_tooltip_button_cancel, FRAMEPOINT_TOPLEFT, 0.0025, 0.0025)
		BlzFrameSetPoint(separator_tooltip_button_cancel, FRAMEPOINT_BOTTOMRIGHT, description_tooltip_button_cancel, FRAMEPOINT_TOPRIGHT, -0.003, 0.0025)
        BlzFrameSetSize(separator_tooltip_button_cancel, 0, 0.0015) --толщина линии
        BlzFrameSetTexture(separator_tooltip_button_cancel, "UI\\Widgets\\ToolTips\\Human\\HorizontalSeparator",0, true) 

        BlzFrameSetSize(title_tooltip_button_cancel, 0.25, 0)
		BlzFrameSetEnable(title_tooltip_button_cancel, false)
		BlzFrameSetText(title_tooltip_button_cancel,cancel_text_tip)
        
        local resourse_bar = BlzCreateFrameByType("FRAME","resourse_bar",tooltip_button_cancel,"",0)
        
        local icon_mana_cost = BlzCreateFrameByType("BACKDROP","icon_mana_cost",resourse_bar,"",0)
        BlzFrameSetSize(icon_mana_cost, 0.012, 0.012)
        BlzFrameSetTexture(icon_mana_cost, ToolTipManaIcon, 0, true)
        BlzFrameSetVisible(icon_mana_cost, false)

        local text_mana_cost = BlzCreateFrameByType("TEXT","text_mana_cost",icon_mana_cost,"BoxedTextValue",0)          
        BlzFrameSetEnable(text_mana_cost, false)
        BlzFrameSetPoint(text_mana_cost, FRAMEPOINT_LEFT, icon_mana_cost, FRAMEPOINT_RIGHT, 0.0025, 0.0)
        BlzFrameSetSize(text_mana_cost, 0, 0.012)
        BlzFrameSetText(text_mana_cost,'|cffffcc00'..requirements[FourCC('Hate')].mana_cost..'|r')
        
        local icon_gold_cost = BlzCreateFrameByType("BACKDROP","icon_gold_cost",resourse_bar,"",0)  
        BlzFrameSetSize(icon_gold_cost, 0.012, 0.012)
        BlzFrameSetTexture(icon_gold_cost, ToolTipGoldIcon, 0, true)
        BlzFrameSetVisible(icon_gold_cost, false)
        
        local text_gold_cost = BlzCreateFrameByType("TEXT","text_gold_cost",icon_gold_cost,"BoxedTextValue",0)          
        BlzFrameSetEnable(text_gold_cost, false)
        BlzFrameSetPoint(text_gold_cost, FRAMEPOINT_LEFT, icon_gold_cost, FRAMEPOINT_RIGHT, 0.0025, 0.0)
        BlzFrameSetSize(text_gold_cost, 0, 0.012)
        BlzFrameSetText(text_gold_cost,'|cffffcc00'..requirements[FourCC('Hate')].gold_cost..'|r')

        local icon_lumber_cost = BlzCreateFrameByType("BACKDROP","icon_lumber_cost",resourse_bar,"",0)
        BlzFrameSetSize(icon_lumber_cost, 0.012, 0.012)
        BlzFrameSetTexture(icon_lumber_cost, ToolTipLumberIcon, 0, true)
        BlzFrameSetVisible(icon_lumber_cost, false)
        
        local text_lumber_cost = BlzCreateFrameByType("TEXT","text_lumber_cost",icon_lumber_cost,"BoxedTextValue",0)          
        BlzFrameSetEnable(text_lumber_cost, false)
        BlzFrameSetPoint(text_lumber_cost, FRAMEPOINT_LEFT, icon_lumber_cost, FRAMEPOINT_RIGHT, 0.0025, 0.0)
        BlzFrameSetSize(text_lumber_cost, 0, 0.012)
        BlzFrameSetText(text_lumber_cost,'|cffffcc00'..requirements[FourCC('Hate')].lumber_cost..'|r')

        local icon_food_cost = BlzCreateFrameByType("BACKDROP","icon_food_cost",resourse_bar,"",0)
        BlzFrameSetSize(icon_food_cost, 0.012, 0.012)
        BlzFrameSetTexture(icon_food_cost, ToolTipSupplyIcon, 0, true)
        BlzFrameSetVisible(icon_food_cost, false)
        
        local text_food_cost = BlzCreateFrameByType("TEXT","text_food_cost",icon_food_cost,"BoxedTextValue",0)          
        BlzFrameSetEnable(text_food_cost, false)
        BlzFrameSetPoint(text_food_cost, FRAMEPOINT_LEFT, icon_food_cost, FRAMEPOINT_RIGHT, 0.0025, 0.0)
        BlzFrameSetSize(text_food_cost, 0, 0.012)
        BlzFrameSetText(text_food_cost,'|cffffcc00'..requirements[FourCC('Hate')].food_cost..'|r')


        local text_building_requirement = BlzCreateFrameByType("TEXT","text_building_requirement",tooltip_button_cancel,"BoxedTextValue",0)          
        BlzFrameSetEnable(text_building_requirement, false)
        BlzFrameSetSize(text_building_requirement, 0.25, 0)

        BlzFrameSetTooltip(button_cancel, tooltip_button_cancel)

        --создаем список, определяющий порядок в горизонтальном рядом ресурсов
        local frame_List = {}
        
        function UpdateTooltip(unitId)
            frame_List = {}
            BlzFrameClearAllPoints(icon_gold_cost)
            BlzFrameClearAllPoints(icon_lumber_cost)
            BlzFrameClearAllPoints(icon_mana_cost)
            BlzFrameClearAllPoints(icon_food_cost)

            if requirements[unitId].gold_cost>0 then
                frame_List[#frame_List+1]=icon_gold_cost
                frame_List[#frame_List+1]=text_gold_cost
                
                BlzFrameSetVisible(icon_gold_cost, true)
            else
                BlzFrameSetVisible(icon_gold_cost, false)
            end
            if requirements[unitId].lumber_cost>0 then
                frame_List[#frame_List+1]=icon_lumber_cost
                frame_List[#frame_List+1]=text_lumber_cost
                BlzFrameSetVisible(icon_lumber_cost, true)
            else
                BlzFrameSetVisible(icon_lumber_cost, false)
            end
            if requirements[unitId].mana_cost>0 then
                frame_List[#frame_List+1]=icon_mana_cost
                frame_List[#frame_List+1]=text_mana_cost
                BlzFrameSetVisible(icon_mana_cost, true)
            else
                BlzFrameSetVisible(icon_mana_cost, false)
            end 
            if requirements[unitId].food_cost>0 then
                frame_List[#frame_List+1]=icon_food_cost
                frame_List[#frame_List+1]=text_food_cost
                BlzFrameSetVisible(icon_food_cost, true)
            else
                BlzFrameSetVisible(icon_food_cost, false)
            end 
            --порядок определен, теперь прикрепляем звенья горизонтального ряда друг с другом
            for a=#frame_List-1, 1, -2 do 
                --у каждого ресурса 2 фрейма: иконка и текст.
                --фреймы между ресурсами крепим друг к другу, иконка одного реса креится к тексту другого реса
                if a>1 then 
                    BlzFrameSetPoint(frame_List[a], FRAMEPOINT_LEFT, frame_List[a-1], FRAMEPOINT_RIGHT, 0.005, 0.0)
                end
            end
            
        end

        
        function update_building_requirement(key_frame, playeR)
            --если что-то указано, значит, проверяем на требование?
            if #requirements[unitId].buildings_required>0 then
                local co,str =  0,"Требуется:"
                for a=1, #requirements[unitId].buildings_required do
                    local Type = FourCC(requirements[key_frame].buildings_required[a])
                    local count = BlzCountLivingPlayerUnitsOfTypeId(Type, playeR)
                    if count==0 then
                        co =co+1
                        str=str.."|n-"..GetObjectName(Type)
                    end
                end 
                
                if co > 0 then
                    BlzFrameSetText(text_building_requirement,'|cffffcc00'..str..'|r')
                    BlzFrameSetVisible(resourse_bar, false) --убираем ресурс бар
                    BlzFrameSetVisible(text_building_requirement, true)

                    BlzFrameSetTexture(icon_button_cancel, path_disabled_icon .. path_icon_cancel, 0, true)

                    BlzFrameSetPoint(text_building_requirement, FRAMEPOINT_BOTTOMLEFT, separator_tooltip_button_cancel, FRAMEPOINT_TOPLEFT, -0.0018, 0.0025)
                    BlzFrameSetPoint(title_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, text_building_requirement, FRAMEPOINT_TOPLEFT, 0.00025, 0.0025)
                elseif co == 0 then
                    BlzFrameSetText(text_building_requirement,'|cffffcc00'..str..'|r')
                    BlzFrameSetVisible(resourse_bar, true)
                    BlzFrameSetVisible(text_building_requirement, false)
                    UpdateTooltip(key_frame)

                    BlzFrameSetTexture(icon_button_cancel, path_active_icon .. path_icon_cancel, 0, true)

                    BlzFrameSetPoint(frame_List[1], FRAMEPOINT_BOTTOMLEFT, separator_tooltip_button_cancel, FRAMEPOINT_TOPLEFT, -0.0018, 0.0025)
                    BlzFrameSetPoint(title_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, frame_List[1]~=nil and frame_List[1] or separator_tooltip_button_cancel, FRAMEPOINT_TOPLEFT, 0.00025, 0.0025)

                end
            
            else
                BlzFrameSetText(text_building_requirement,'|cffffcc00'..str..'|r')
                BlzFrameSetVisible(resourse_bar, true)
                BlzFrameSetVisible(text_building_requirement, false)
                UpdateTooltip(key_frame)

                BlzFrameSetTexture(icon_button_cancel, path_active_icon .. path_icon_cancel, 0, true)

                BlzFrameSetPoint(frame_List[1], FRAMEPOINT_BOTTOMLEFT, separator_tooltip_button_cancel, FRAMEPOINT_TOPLEFT, -0.0018, 0.0025)
                BlzFrameSetPoint(title_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, frame_List[1]~=nil and frame_List[1] or separator_tooltip_button_cancel, FRAMEPOINT_TOPLEFT, 0.00025, 0.0025)
            end
        end
        
        local trigger_button_cancel_click=CreateTrigger()
		BlzTriggerRegisterFrameEvent(trigger_button_cancel_click, button_cancel, FRAMEEVENT_MOUSE_UP)
		TriggerAddAction(trigger_button_cancel_click,function()
            print('click button "cancel"')
		end)
        
        local key_frame = 0 --ключ фрейм
        local trigger_button_cancel_enter=CreateTrigger()
		BlzTriggerRegisterFrameEvent(trigger_button_cancel_enter, button_cancel, FRAMEEVENT_MOUSE_ENTER)
		TriggerAddAction(trigger_button_cancel_enter,function()
            key_frame = FourCC('Hate')
            update_building_requirement(key_frame,GetTriggerPlayer())
            print('cursor mouse enter in frame')
		end)
        local trigger_button_cancel_leave=CreateTrigger()
		BlzTriggerRegisterFrameEvent(trigger_button_cancel_leave, button_cancel, FRAMEEVENT_MOUSE_LEAVE)
		TriggerAddAction(trigger_button_cancel_leave,function()
            --update_building_requirement(FourCC('Hate'),GetTriggerPlayer())
            print('cursor mouse leave frame')
		end)
        
        --триггер фиксирует изменения на поле боя
        --если здание удалилось/сменило владельца/заново построено
        --фиксирует исчезновение, появление юнита, и заносит изменение в подсказку фрейма
        --здания, которые не достроены, не учитываются
        local trigger_update = CreateTrigger()
        TriggerRegisterAnyUnitEventBJ( trigger_update, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH )
        TriggerRegisterAnyUnitEventBJ( trigger_update, EVENT_PLAYER_UNIT_DEATH )
        TriggerRegisterAnyUnitEventBJ( trigger_update, EVENT_PLAYER_UNIT_CHANGE_OWNER )
        TriggerRegisterAnyUnitEventBJ( trigger_update, EVENT_PLAYER_UNIT_UPGRADE_FINISH )
        TriggerAddAction( trigger_update, function()
            update_building_requirement(key_frame,GetTriggerPlayer())
            print('фиксируется изменение')
        end)
        
        --на старте обноваляем инфу
        update_building_requirement(FourCC('Hate'),Player(0))
        
		BlzFrameSetPoint(backdrop_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, description_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, -0.005, -0.005)
		BlzFrameSetPoint(backdrop_tooltip_button_cancel, FRAMEPOINT_TOPRIGHT, title_tooltip_button_cancel, FRAMEPOINT_TOPRIGHT, 0.005, 0.005)

        
  end
end


--почему-то только в InitGlobals норм таймер работает
do 
	local InitGlobalsOrigin = InitGlobals
	function InitGlobals()
		InitGlobalsOrigin()

        local group_construct = CreateGroup()

        local start_construction = CreateTrigger()
        TriggerRegisterAnyUnitEventBJ( start_construction, EVENT_PLAYER_UNIT_CONSTRUCT_START )
        TriggerRegisterAnyUnitEventBJ( start_construction, EVENT_PLAYER_UNIT_UPGRADE_START )
        TriggerAddAction( start_construction, function()
            GroupAddUnit(group_construct, GetTriggerUnit())
        end)

        local end_construction = CreateTrigger()
        TriggerRegisterAnyUnitEventBJ( end_construction, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH )
        TriggerRegisterAnyUnitEventBJ( end_construction, EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL )
        TriggerRegisterAnyUnitEventBJ( end_construction, EVENT_PLAYER_UNIT_UPGRADE_CANCEL )
        TriggerRegisterAnyUnitEventBJ( end_construction, EVENT_PLAYER_UNIT_UPGRADE_FINISH )
        TriggerRegisterAnyUnitEventBJ( end_construction, EVENT_PLAYER_UNIT_DEATH )
        TriggerAddAction( end_construction, function()
            GroupRemoveUnit(group_construct, GetTriggerUnit())
        end)

        function BlzCountLivingPlayerUnitsOfTypeId(unitId, whichPlayer)
            local g = CreateGroup()
            GroupEnumUnitsOfPlayer(g, whichPlayer, Condition(function()
            return GetUnitTypeId(GetFilterUnit())==unitId and (not IsUnitType( GetFilterUnit(), UNIT_TYPE_DEAD )) and (not IsUnitInGroup(GetFilterUnit(),group_construct))
            end))
            local Count = BlzGroupGetSize(g)
            DestroyGroup(g)

            return Count
        end
        
    end
end
подсказка с требованием изучения технологии
некоторые абилки в классических сражениях изнечально заблочекны, пока не выполнится требование завершить исследование.
ничем не отличаются от требовании построить здание. решил доработать с условием, что два вида требования могут быть объединены.
решил немного переделать таблицу
        local requirements = {}
        requirements[FourCC('Hate')]={
            gold_cost = 11,
            lumber_cost = 22,
            mana_cost = 200,
            food_cost = 70,
            tech_required ={},
            buildings_required = {'hhou''}
            
        }
        --записываются  в качестве требования уровни технологии
        requirements[FourCC('Hate')].tech_required['Rhde']=1
При изучении технологии требование убирается, и остается только постройка. или наоборот, при постройке здания, убирается требование.
Можно прописать дополнительно несколько требовании:
        local requirements = {}
        requirements[FourCC('Hate')]={
            gold_cost = 11,
            lumber_cost = 22,
            mana_cost = 200,
            food_cost = 70,
            tech_required ={},
            buildings_required = {'hhou','htow'}
            
        }
        --записываются  в качестве требования уровни технологии
        requirements[FourCC('Hate')].tech_required['Rhde']=1
        requirements[FourCC('Hate')].tech_required['Rhri']=1
будет это вот так выглядеть
lua код
function LoadToc(s)
    if BlzLoadTOCFile(s) then
        print("Loaded: "..s)
    else
        print("Failed to Load: "..s)
    end
end
do
	local real = MarkGameStarted
	function MarkGameStarted()
        real()
		
		BlzLoadTOCFile("war3mapImported\\MySimpleButton.toc")

		local gameUI = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)

		local path_active_icon = "ReplaceableTextures\\CommandButtons\\BTN"
		local path_disabled_icon = "ReplaceableTextures\\CommandButtonsDisabled\\DISBTN"
		local path_icon_cancel = "Cancel"
		local cancel_text_tip = "Отмена (|cffffcc00ESC|r)"
		local cancel_text_ubertip = "Отменяет выбранный приказ"
		local size_button = 0.039
        
        
        local requirements = {}
        requirements[FourCC('Hate')]={
            gold_cost = 11,
            lumber_cost = 22,
            mana_cost = 200,
            food_cost = 70,
            tech_required ={},
            buildings_required = {'hhou'}
            --buildings_required = {'hhou','htow'}
            
        }
        --записываются  в качестве требования уровни технологии
        requirements[FourCC('Hate')].tech_required['Rhde']=1
        --requirements[FourCC('Hate')].tech_required['Rhri']=1
        
        --
        ToolTipBackground="UI\\Widgets\\ToolTips\\Human\\human-tooltip-background"
        ToolTipBorder="UI\\Widgets\\ToolTips\\Human\\human-tooltip-border"
        ToolTipGoldIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipGoldIcon"
        ToolTipLumberIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipLumberIcon"
        ToolTipStonesIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipStonesIcon"
        ToolTipManaIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipManaIcon"
        ToolTipSupplyIcon="UI\\Widgets\\ToolTips\\Human\\ToolTipSupplyIcon"
        ToolTipHorizontalSeparator="UI\\Widgets\\ToolTips\\Human\\HorizontalSeparator"
        
		--
		local button_cancel = BlzCreateFrameByType("SLIDER","button cancel",gameUI,"",0)
		local icon_button_cancel = BlzCreateFrameByType("BACKDROP","IconTexture",button_cancel,"",0)
		BlzFrameSetAbsPoint(button_cancel, FRAMEPOINT_CENTER, 0.4, 0.3)
		BlzFrameSetAllPoints(icon_button_cancel,button_cancel)
		BlzFrameSetTexture(icon_button_cancel, path_active_icon .. path_icon_cancel, 0, true)
		BlzFrameSetSize(button_cancel, size_button, size_button)
		--BlzFrameSetVisible(button_cancel, false)

		local tooltip_button_cancel = BlzCreateFrameByType("FRAME","tooltip",button_cancel,"",0)
        BlzFrameSetVisible(tooltip_button_cancel, false)
        
		local backdrop_tooltip_button_cancel = BlzCreateFrameByType("BACKDROP","backdrop tooltip",tooltip_button_cancel,"BoxedTextBackgroundTemplate",0)
		local description_tooltip_button_cancel = BlzCreateFrameByType("TEXT","description tooltip",tooltip_button_cancel,"BoxedTextValue",0)
		local title_tooltip_button_cancel = BlzCreateFrameByType("TEXT","title tooltip",tooltip_button_cancel,"BoxedTextTitle",0)
		local separator_tooltip_button_cancel = BlzCreateFrameByType("BACKDROP","Separator",tooltip_button_cancel,"",0)

		BlzFrameSetAbsPoint(description_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, 0.55, 0.19)
		BlzFrameSetSize(description_tooltip_button_cancel, 0.25, 0)
		BlzFrameSetEnable(description_tooltip_button_cancel, false)
		BlzFrameSetText(description_tooltip_button_cancel,cancel_text_ubertip)

		BlzFrameSetPoint(separator_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, description_tooltip_button_cancel, FRAMEPOINT_TOPLEFT, 0.0025, 0.0025)
		BlzFrameSetPoint(separator_tooltip_button_cancel, FRAMEPOINT_BOTTOMRIGHT, description_tooltip_button_cancel, FRAMEPOINT_TOPRIGHT, -0.003, 0.0025)
        BlzFrameSetSize(separator_tooltip_button_cancel, 0, 0.0015) --толщина линии
        BlzFrameSetTexture(separator_tooltip_button_cancel, "UI\\Widgets\\ToolTips\\Human\\HorizontalSeparator",0, true) 

        BlzFrameSetSize(title_tooltip_button_cancel, 0.25, 0)
		BlzFrameSetEnable(title_tooltip_button_cancel, false)
		BlzFrameSetText(title_tooltip_button_cancel,cancel_text_tip)
        
        local resourse_bar = BlzCreateFrameByType("FRAME","resourse_bar",tooltip_button_cancel,"",0)
        
        local icon_mana_cost = BlzCreateFrameByType("BACKDROP","icon_mana_cost",resourse_bar,"",0)
        BlzFrameSetSize(icon_mana_cost, 0.012, 0.012)
        BlzFrameSetTexture(icon_mana_cost, ToolTipManaIcon, 0, true)
        BlzFrameSetVisible(icon_mana_cost, false)

        local text_mana_cost = BlzCreateFrameByType("TEXT","text_mana_cost",icon_mana_cost,"BoxedTextValue",0)          
        BlzFrameSetEnable(text_mana_cost, false)
        BlzFrameSetPoint(text_mana_cost, FRAMEPOINT_LEFT, icon_mana_cost, FRAMEPOINT_RIGHT, 0.0025, 0.0)
        BlzFrameSetSize(text_mana_cost, 0, 0.012)
        BlzFrameSetText(text_mana_cost,'|cffffcc00'..requirements[FourCC('Hate')].mana_cost..'|r')
        
        local icon_gold_cost = BlzCreateFrameByType("BACKDROP","icon_gold_cost",resourse_bar,"",0)  
        BlzFrameSetSize(icon_gold_cost, 0.012, 0.012)
        BlzFrameSetTexture(icon_gold_cost, ToolTipGoldIcon, 0, true)
        BlzFrameSetVisible(icon_gold_cost, false)
        
        local text_gold_cost = BlzCreateFrameByType("TEXT","text_gold_cost",icon_gold_cost,"BoxedTextValue",0)          
        BlzFrameSetEnable(text_gold_cost, false)
        BlzFrameSetPoint(text_gold_cost, FRAMEPOINT_LEFT, icon_gold_cost, FRAMEPOINT_RIGHT, 0.0025, 0.0)
        BlzFrameSetSize(text_gold_cost, 0, 0.012)
        BlzFrameSetText(text_gold_cost,'|cffffcc00'..requirements[FourCC('Hate')].gold_cost..'|r')

        local icon_lumber_cost = BlzCreateFrameByType("BACKDROP","icon_lumber_cost",resourse_bar,"",0)
        BlzFrameSetSize(icon_lumber_cost, 0.012, 0.012)
        BlzFrameSetTexture(icon_lumber_cost, ToolTipLumberIcon, 0, true)
        BlzFrameSetVisible(icon_lumber_cost, false)
        
        local text_lumber_cost = BlzCreateFrameByType("TEXT","text_lumber_cost",icon_lumber_cost,"BoxedTextValue",0)          
        BlzFrameSetEnable(text_lumber_cost, false)
        BlzFrameSetPoint(text_lumber_cost, FRAMEPOINT_LEFT, icon_lumber_cost, FRAMEPOINT_RIGHT, 0.0025, 0.0)
        BlzFrameSetSize(text_lumber_cost, 0, 0.012)
        BlzFrameSetText(text_lumber_cost,'|cffffcc00'..requirements[FourCC('Hate')].lumber_cost..'|r')

        local icon_food_cost = BlzCreateFrameByType("BACKDROP","icon_food_cost",resourse_bar,"",0)
        BlzFrameSetSize(icon_food_cost, 0.012, 0.012)
        BlzFrameSetTexture(icon_food_cost, ToolTipSupplyIcon, 0, true)
        BlzFrameSetVisible(icon_food_cost, false)
        
        local text_food_cost = BlzCreateFrameByType("TEXT","text_food_cost",icon_food_cost,"BoxedTextValue",0)          
        BlzFrameSetEnable(text_food_cost, false)
        BlzFrameSetPoint(text_food_cost, FRAMEPOINT_LEFT, icon_food_cost, FRAMEPOINT_RIGHT, 0.0025, 0.0)
        BlzFrameSetSize(text_food_cost, 0, 0.012)
        BlzFrameSetText(text_food_cost,'|cffffcc00'..requirements[FourCC('Hate')].food_cost..'|r')


        local text_building_requirement = BlzCreateFrameByType("TEXT","text_building_requirement",tooltip_button_cancel,"BoxedTextValue",0)          
        BlzFrameSetEnable(text_building_requirement, false)
        BlzFrameSetSize(text_building_requirement, 0.25, 0)
		
		local text_tech_requirement = BlzCreateFrameByType("TEXT","text_tech_requirement",tooltip_button_cancel,"BoxedTextValue",0)          
        BlzFrameSetEnable(text_tech_requirement, false)
        BlzFrameSetSize(text_tech_requirement, 0.25, 0)

        BlzFrameSetTooltip(button_cancel, tooltip_button_cancel)

        --создаем список, определяющий порядок в горизонтальном рядом ресурсов
        local frame_List = {}
        
        function UpdateResourseBarTooltip(unitId) --
            frame_List = {}
            BlzFrameClearAllPoints(icon_gold_cost)
            BlzFrameClearAllPoints(icon_lumber_cost)
            BlzFrameClearAllPoints(icon_mana_cost)
            BlzFrameClearAllPoints(icon_food_cost)

            if requirements[unitId].gold_cost>0 then
                frame_List[#frame_List+1]=icon_gold_cost
                frame_List[#frame_List+1]=text_gold_cost
                
                BlzFrameSetVisible(icon_gold_cost, true)
            else
                BlzFrameSetVisible(icon_gold_cost, false)
            end
            if requirements[unitId].lumber_cost>0 then
                frame_List[#frame_List+1]=icon_lumber_cost
                frame_List[#frame_List+1]=text_lumber_cost
                BlzFrameSetVisible(icon_lumber_cost, true)
            else
                BlzFrameSetVisible(icon_lumber_cost, false)
            end
            if requirements[unitId].mana_cost>0 then
                frame_List[#frame_List+1]=icon_mana_cost
                frame_List[#frame_List+1]=text_mana_cost
                BlzFrameSetVisible(icon_mana_cost, true)
            else
                BlzFrameSetVisible(icon_mana_cost, false)
            end 
            if requirements[unitId].food_cost>0 then
                frame_List[#frame_List+1]=icon_food_cost
                frame_List[#frame_List+1]=text_food_cost
                BlzFrameSetVisible(icon_food_cost, true)
            else
                BlzFrameSetVisible(icon_food_cost, false)
            end 
            --порядок определен, теперь прикрепляем звенья горизонтального ряда друг с другом
            for a=#frame_List-1, 1, -2 do 
                --у каждого ресурса 2 фрейма: иконка и текст.
                --фреймы между ресурсами крепим друг к другу, иконка одного реса креится к тексту другого реса
                if a>1 then 
                    BlzFrameSetPoint(frame_List[a], FRAMEPOINT_LEFT, frame_List[a-1], FRAMEPOINT_RIGHT, 0.005, 0.0)
                end
            end
            
        end

        
        function update_building_requirement(key_frame, playeR)
            --если что-то указано, значит, проверяем на требование?
            if #requirements[key_frame].buildings_required>0 then
                local co,str =  0,"Требуется:"
                for a=1, #requirements[key_frame].buildings_required do
                    local Type = FourCC(requirements[key_frame].buildings_required[a])
                    local count = BlzCountLivingPlayerUnitsOfTypeId(Type, playeR)
                    if count==0 then
                        co =co+1
                        str=str.."|n-"..GetObjectName(Type)
                    end
                end 
                return co,str
            else
                return 0
            end
        end
            
        function update_tech_requirement(key_frame, playeR)
            --requirements[FourCC('Hate')].tech_required['Rhde']
        
            local count,str =  0,"Требуется изучить:"
            local table = requirements[key_frame].tech_required

            for techId, value in pairs(table) do
                local lv = GetPlayerTechCount(playeR,FourCC(techId),true) --текущий уровень технологии
                
                --если текущий уровень lv не достиг требуемого уровня value
                --значит, не изучен еще, записываем список технологии
                if value > lv then
                    count = count + 1
                    str=str.."|n-"..GetObjectName(FourCC(techId))
                end                    
            end
            return count,str
        end
        function UpdateTooltip(key_frame, playeR)
            local c1,str_1 = update_tech_requirement(key_frame, playeR)
			local c2,str_2 = update_building_requirement(key_frame, playeR)
			
			local list_frame = {}
            if c1 > 0 then
				BlzFrameSetText(text_tech_requirement,'|cffffcc00'..str_1..'|r')
				BlzFrameSetVisible(text_tech_requirement, true)
				
				list_frame[#list_frame+1] = text_tech_requirement
            else
                BlzFrameSetVisible(text_tech_requirement, false)
			end
			if c2 > 0 then
				BlzFrameSetText(text_building_requirement,'|cffffcc00'..str_2..'|r')
                BlzFrameSetVisible(text_building_requirement, true)
				
				list_frame[#list_frame+1] = text_building_requirement
            else
                BlzFrameSetVisible(text_building_requirement, false)
			end
			
			if c1>0 or c2>0 then
				BlzFrameSetVisible(resourse_bar, false) --убираем ресурс бар
				BlzFrameSetTexture(icon_button_cancel, path_disabled_icon .. path_icon_cancel, 0, true)
				
				if #list_frame>1 then
					BlzFrameClearAllPoints(list_frame[2])
					BlzFrameSetPoint(list_frame[2], FRAMEPOINT_BOTTOMLEFT, list_frame[1], FRAMEPOINT_TOPLEFT, -0.0018, 0.0025)
				end
				
				BlzFrameClearAllPoints(list_frame[1])
				BlzFrameClearAllPoints(title_tooltip_button_cancel)
				BlzFrameSetPoint(list_frame[1], FRAMEPOINT_BOTTOMLEFT, separator_tooltip_button_cancel, FRAMEPOINT_TOPLEFT, -0.0018, 0.0025)
                BlzFrameSetPoint(title_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, list_frame[#list_frame], FRAMEPOINT_TOPLEFT, 0.00025, 0.0025)
			else
				BlzFrameSetVisible(resourse_bar, true) 
				BlzFrameSetTexture(icon_button_cancel, path_active_icon .. path_icon_cancel, 0, true)
				
				BlzFrameSetVisible(text_building_requirement, false)
                BlzFrameSetVisible(text_tech_requirement, false)
                
				UpdateResourseBarTooltip(key_frame)
				
				BlzFrameClearAllPoints(frame_List[1])
				BlzFrameClearAllPoints(title_tooltip_button_cancel)
				
                BlzFrameSetPoint(frame_List[1], FRAMEPOINT_BOTTOMLEFT, separator_tooltip_button_cancel, FRAMEPOINT_TOPLEFT, -0.0018, 0.0025)
                BlzFrameSetPoint(title_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, frame_List[1]~=nil and frame_List[1] or separator_tooltip_button_cancel, FRAMEPOINT_TOPLEFT, 0.00025, 0.0025)
				
			end
        end
        

        
        local trigger_button_cancel_click=CreateTrigger()
		BlzTriggerRegisterFrameEvent(trigger_button_cancel_click, button_cancel, FRAMEEVENT_MOUSE_UP)
		TriggerAddAction(trigger_button_cancel_click,function()
            print('click button "cancel"')
		end)
        
        local key_frame = 0 --ключ фрейм
        local trigger_button_cancel_enter=CreateTrigger()
		BlzTriggerRegisterFrameEvent(trigger_button_cancel_enter, button_cancel, FRAMEEVENT_MOUSE_ENTER)
		TriggerAddAction(trigger_button_cancel_enter,function()
            key_frame = FourCC('Hate')
            UpdateTooltip(key_frame,GetTriggerPlayer())
            print('cursor mouse enter in frame')
		end)
        local trigger_button_cancel_leave=CreateTrigger()
		BlzTriggerRegisterFrameEvent(trigger_button_cancel_leave, button_cancel, FRAMEEVENT_MOUSE_LEAVE)
		TriggerAddAction(trigger_button_cancel_leave,function()
            --UpdateTooltip(FourCC('Hate'),GetTriggerPlayer())
            print('cursor mouse leave frame')
		end)
        
        --триггер фиксирует изменения на поле боя
        --если здание удалилось/сменило владельца/заново построено
        --фиксирует исчезновение, появление юнита, и заносит изменение в подсказку фрейма
        --здания, которые не достроены, не учитываются
        local trigger_update = CreateTrigger()
        TriggerRegisterAnyUnitEventBJ( trigger_update, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH )
        TriggerRegisterAnyUnitEventBJ( trigger_update, EVENT_PLAYER_UNIT_DEATH )
        TriggerRegisterAnyUnitEventBJ( trigger_update, EVENT_PLAYER_UNIT_CHANGE_OWNER )
        TriggerRegisterAnyUnitEventBJ( trigger_update, EVENT_PLAYER_UNIT_UPGRADE_FINISH )
		TriggerRegisterAnyUnitEventBJ( trigger_update, EVENT_PLAYER_UNIT_RESEARCH_FINISH )
        TriggerAddAction( trigger_update, function()
            UpdateTooltip(key_frame,GetTriggerPlayer())
            print('фиксируется изменение')
        end)
        
        --на старте обноваляем инфу
        UpdateTooltip(FourCC('Hate'),Player(0))
        
		BlzFrameSetPoint(backdrop_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, description_tooltip_button_cancel, FRAMEPOINT_BOTTOMLEFT, -0.005, -0.005)
		BlzFrameSetPoint(backdrop_tooltip_button_cancel, FRAMEPOINT_TOPRIGHT, title_tooltip_button_cancel, FRAMEPOINT_TOPRIGHT, 0.005, 0.005)

        
  end
end


--почему-то только в InitGlobals норм таймер работает
do 
	local InitGlobalsOrigin = InitGlobals
	function InitGlobals()
		InitGlobalsOrigin()

        local group_construct = CreateGroup()

        local start_construction = CreateTrigger()
        TriggerRegisterAnyUnitEventBJ( start_construction, EVENT_PLAYER_UNIT_CONSTRUCT_START )
        TriggerRegisterAnyUnitEventBJ( start_construction, EVENT_PLAYER_UNIT_UPGRADE_START )
        TriggerAddAction( start_construction, function()
            GroupAddUnit(group_construct, GetTriggerUnit())
        end)

        local end_construction = CreateTrigger()
        TriggerRegisterAnyUnitEventBJ( end_construction, EVENT_PLAYER_UNIT_CONSTRUCT_FINISH )
        TriggerRegisterAnyUnitEventBJ( end_construction, EVENT_PLAYER_UNIT_CONSTRUCT_CANCEL )
        TriggerRegisterAnyUnitEventBJ( end_construction, EVENT_PLAYER_UNIT_UPGRADE_CANCEL )
        TriggerRegisterAnyUnitEventBJ( end_construction, EVENT_PLAYER_UNIT_UPGRADE_FINISH )
        TriggerRegisterAnyUnitEventBJ( end_construction, EVENT_PLAYER_UNIT_DEATH )
        TriggerAddAction( end_construction, function()
            GroupRemoveUnit(group_construct, GetTriggerUnit())
        end)

        function BlzCountLivingPlayerUnitsOfTypeId(unitId, whichPlayer)
            local g = CreateGroup()
            GroupEnumUnitsOfPlayer(g, whichPlayer, Condition(function()
            return GetUnitTypeId(GetFilterUnit())==unitId and (not IsUnitType( GetFilterUnit(), UNIT_TYPE_DEAD )) and (not IsUnitInGroup(GetFilterUnit(),group_construct))
            end))
            local Count = BlzGroupGetSize(g)
            DestroyGroup(g)

            return Count
        end
        
    end
end

Содержание
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
16
9 месяцев назад
0
На примерах-скриншотах используется стандартная рамка тултипов.
А в примерах кода везде используется "QuestButtonBaseTemplate".
Как называется рамка подсказки?
0
27
9 месяцев назад
0
avuremybe, ну большинство обучающих примеров взяты с хайва. Я их просто объединил в один. Если я не указал fdf-скрипт, значит, это используется дефолтный шаблон.
А в примерах кода везде используется "QuestButtonBaseTemplate".
где там везде? там вроде дефолтный шаблон, который используется в квестах. Он немного отличается от станд рамки тултипа
Все базовые тултипа обозначены тут:

Как называется рамка подсказки?
Про какую рамку вы говорите? Из 4 примера и ниже? QuestButtonBaseTemplate. Возсожно что то делаете не так. Надо посмотреть в импорте в каком fdf файле лежит QuestButtonBaseTemplate. Потом посмотреть включен ли он игрой.
0
16
9 месяцев назад
0
МрачныйВорон, я говорю про те примеры, где все реализовано кодом, без импорта fdf - там везде используется QuestButtonBaseTemplate.
А на большинстве приведенных скриншотов - использована стандартная рамка тултипа.
Могу я ее использовать, не прибегая к импорту fdf?
Если да, то как называется темплейт, для ее использования в ф-ции BlzCreateFrameByType ?
2
27
9 месяцев назад
Отредактирован MpW
2
Извини, сейчас у меня нет компа. И варкрафта. Так бы скинул пример без фдф файла. Я уже давно в варкрафте не сижу, и уже что то могу не помнить.
Тфу, я уже путаюсь. Вроде ToolTipBackground это изображение фона backdrop. Ну, backdrop не сделать чисто одним фоном, там нужно много сего учесть. Иконки границ, оффсеты итд. Без fdf да никак. Это все указывается внутри. Особенно, без границ, если хотите красивую подсказку.

Почитай вот тут
Как я пытался чисто заменить backdrop. Сейчас, я стал опытнее. И считаю, что без фдф никак. Можно сделать хитрее кодом добавить границы: по углам уголки, по 4 сторона растягивающие линии с помощью привязок. Проблема именно в импорте иконок границ, они не всегда бывают одиночными. Чаще всего выкладывают границы в одну картинку.
Как это использовать? Резать в фотошопе итд. Больше проблем. Я видел одиночные иконки границ, но не знаю по каким правилам они склеиваются, и работают.

Сейчас дефолтной фды на тултипа нет. К сожалению, приходится импортировать с заданнымм параметрами, изображениями из интерфейса редактора
0
27
7 месяцев назад
0
    local tooltip = BlzGetOriginFrame(ORIGIN_FRAME_UBERTOOLTIP, 0)
    BlzFrameClearAllPoints(tooltip)
    BlzFrameSetScale(tooltip, 0.001)
    BlzFrameSetAbsPoint(tooltip, FRAMEPOINT_BOTTOMRIGHT, 0.0, 0.0)
Чтобы оставить комментарий, пожалуйста, войдите на сайт.