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

Lua для чайников

Содержание:
Эта часть раздела посвящена тому, как использовать lua в варкрафте. В рефордже есть возможность подключить lua-скрипты. Когда я начинал, мне было не понятно, как другие мапперы подключают луа.

17.1. Что нужно для работы с lua для варкрафта?

кратко: это курс предназначен для новичков, которые мб не понять как работать именно с кодом.
  1. Для начала нам понадобится последняя версия WarCraft III, умение читать справочник и пользоваться английской раскладкой клавиатуры.
  2. Писать код в стандартном редакторе то ещё удовольствие, потому скачиваем специальную программу для работы с кодом. настраиваем себе подсветку. Более стабильная для vs code
Существует также NotePade + (в отличии от первых двух перечисленных, которые могут еще работать и запускать код. здесь придеться больше копипастить: из блокнота копировать copy ctrl+c и вставлять paste ctrl+v в редактор)
Можете еще скачать tesh для рефорджа, хотя он для lua не предназначен (подсветка будет неправильно подсвечивать шрифты), но вы можете видеть хотя бы текст. Мне это было необходим tesh, чтобы частями код jass переносить в lua-редактор, и там переделывать на lua. заметка: зная язык lua, вы можете писать во внешнем редакторе. А потом весь код копировать и вставлять в CustomScript. И запускать редактор варика. Хотя в некоторых внешних редакторах можно запустить саму карту для теста
  1. В самой карте нужно переключить режим lua. Короче, для этого нужно удалить все триггеры - иначе в настройках карты не изменить режим, если присутствует хоть какой то код на jass. По умолчанию карты компилируются в jass, переключим их в режим lua.
  1. Вы должны знать как сделать Инжект функции. Во внешнем редакторе вы прописываете lua-код из того примера. Если не понятно, то можете еще один пример посмотреть. Если не понятно, набираете на xgm lua Сюда вы можете весь код закинуть, или частями.
  1. Если будете работать с луа, нужно быть очень внимательными. Выявлять нужно каждую ошибку. Поскольку нет строгой типизации, и при компилирования кода вам даже могут не все ошибки указать. А в игре какой-то код не заработает, просто оборвется поток. И вы даже знать не будете где. Можно продебажить каждую строчку, и узнать в каком месте обрывается.. Но это очень долго, другой вариант, использовать дебаггер:
Некоторые функции из библиотек lua могут не заработать в варкрафте. По причине разных версии луа, и отсутствии наличия функции в сборке.

Примеры

Заметка: в рефордже не очень хорошо работает string.format. Выдает длинные символы, вместо hex-строки.
пример
	function rgba2hex(r, g, b, a)
	  return string.format('%02x%02x%02x%02x', a or 255, r, g, b)
	end
    
    print('|c'..rgba2hex(255, 0, 0)..'красный перец|r')
получает
Но ва других онлайн-редакторов для lua пример можно легко протестировать через print
или некоторые функции из математических библиотек. Пример математическая функция в рефордже math.randomseed(x) не работает, чем в том же мемхаке на луа. Имейте в виду, что если что-то работает в онлайн-редакторе где можно проверить логику кода. В том же рефордже некоторые функции из библиотек могут не заработать, также и наоборот, в онлвйн-редакторе что-то не работает бывает.

ошибка: не инициирована переменная

В варкрафте есть момент с объектами, включающую себя видимость переменной и ее проинициированность. Пример, если в jass код нужно было функции заранее создать сверху, и только снизу их можно вызвать. То в луа такой проблемы нет, хотя там тоже такая же проблема бывает:
код
этот код меню строительства.
	local path_icon = "ReplaceableTextures\\CommandButtons\\BTNSelectHeroOn"
	local path_active_icon = "ReplaceableTextures\\CommandButtons\\BTN"
	local path_disabled_icon = "ReplaceableTextures\\CommandButtonsDisabled\\DISBTN"
    local path_icon_human_build = "ReplaceableTextures\\CommandButtons\\BTNHumanBuild"
    local path_icon_orc_build = "ReplaceableTextures\\CommandButtons\\BTNBasicStruct"
    local path_icon_cancel = "Cancel"
    
    local build_menu_text_tip = "Вызывает меню постройки"
    local build_menu_text_ubertip = "Показывает весь список здании, который может построить выбранный юнит"
    local cancel_text_tip = "Отмена"
    local cancel_text_ubertip = "Отменяет выбранный приказ"
	
	local gameUI = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)
	
    local button_cancel = BlzCreateFrameByType("SLIDER","button 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)
    BlzFrameSetLevel(button_cancel, 2)
	
	local trigger_button_cancel_click=CreateTrigger()
    BlzTriggerRegisterFrameEvent(trigger_button_cancel_click, button_cancel, FRAMEEVENT_MOUSE_UP)
    for a=0, 24 do
        TriggerRegisterPlayerEventEndCinematic( trigger_button_cancel_click, Player(a) )
        --TriggerRegisterPlayerEvent(trigger_button_cancel_click, Player(a), event)
    end
    TriggerAddAction(trigger_button_cancel_click,function()
        local n = GetPlayerId(GetTriggerPlayer())
        print('click button "cancel"')
        
        --скрываем кнопку отмены
        BlzFrameSetVisible(button_cancel, false)
        --показываем кнопку меню
        BlzFrameSetVisible(button_build_menu, true)
        --скрываем контейнер 
        BlzFrameSetVisible(build_menu[n].conteiner, false)

    end)
	
	
	local button_build_menu = BlzCreateFrameByType("SLIDER","button build menu",gameUI,"",0)
    local icon_button_build_menu = BlzCreateFrameByType("BACKDROP","IconTexture",button_build_menu,"",0)
    BlzFrameSetAbsPoint(button_build_menu, FRAMEPOINT_CENTER, 0.4, 0.3)
    BlzFrameSetAllPoints(icon_button_build_menu,button_build_menu)
    BlzFrameSetTexture(icon_button_build_menu, path_icon_human_build, 0, true)
    BlzFrameSetSize(button_build_menu, size_button, size_button)
    BlzFrameSetVisible(button_build_menu, false)
при запуске у меня не отображалась кнопка "меню строительства", когда я жал кнопку "отмена". по факту ничего не происходит. где я допустил ошибку?
в этой строчке (см. ниже) мы вызываем не существующую кнопку button_build_menu, тк она еще не проиницирована. по логике триггер должен работать, однако, не работает.
--показываем кнопку меню
BlzFrameSetVisible(button_build_menu, true)
для этого мы должно переделать код, и переставить местами. (оч часто вы будете с этой фигней сталкиваться. или мб не будете. казалось магия lua может все, и любой код вызвать: из верхней, нижней)
переделанный код
этот код меню строительства.
	local path_icon = "ReplaceableTextures\\CommandButtons\\BTNSelectHeroOn"
	local path_active_icon = "ReplaceableTextures\\CommandButtons\\BTN"
	local path_disabled_icon = "ReplaceableTextures\\CommandButtonsDisabled\\DISBTN"
    local path_icon_human_build = "ReplaceableTextures\\CommandButtons\\BTNHumanBuild"
    local path_icon_orc_build = "ReplaceableTextures\\CommandButtons\\BTNBasicStruct"
    local path_icon_cancel = "Cancel"
    
    local build_menu_text_tip = "Вызывает меню постройки"
    local build_menu_text_ubertip = "Показывает весь список здании, который может построить выбранный юнит"
    local cancel_text_tip = "Отмена"
    local cancel_text_ubertip = "Отменяет выбранный приказ"
	
	local gameUI = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)
	
    local button_cancel = BlzCreateFrameByType("SLIDER","button 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)
    BlzFrameSetLevel(button_cancel, 2)
	
	local button_build_menu = BlzCreateFrameByType("SLIDER","button build menu",gameUI,"",0)
    local icon_button_build_menu = BlzCreateFrameByType("BACKDROP","IconTexture",button_build_menu,"",0)
    BlzFrameSetAbsPoint(button_build_menu, FRAMEPOINT_CENTER, 0.4, 0.3)
    BlzFrameSetAllPoints(icon_button_build_menu,button_build_menu)
    BlzFrameSetTexture(icon_button_build_menu, path_icon_human_build, 0, true)
    BlzFrameSetSize(button_build_menu, size_button, size_button)
    BlzFrameSetVisible(button_build_menu, false)
	
	
	local trigger_button_cancel_click=CreateTrigger()
    BlzTriggerRegisterFrameEvent(trigger_button_cancel_click, button_cancel, FRAMEEVENT_MOUSE_UP)
    for a=0, 24 do
        TriggerRegisterPlayerEventEndCinematic( trigger_button_cancel_click, Player(a) )
        --TriggerRegisterPlayerEvent(trigger_button_cancel_click, Player(a), event)
    end
    TriggerAddAction(trigger_button_cancel_click,function()
        local n = GetPlayerId(GetTriggerPlayer())
        print('click button "cancel"')
        
        --скрываем кнопку отмены
        BlzFrameSetVisible(button_cancel, false)
        --показываем кнопку меню
        BlzFrameSetVisible(button_build_menu, true)
        --скрываем контейнер 
        BlzFrameSetVisible(build_menu[n].conteiner, false)

    end)

`
ОЖИДАНИЕ РЕКЛАМЫ...
38
Пользуясь случаем, рекомендую читателям не проходить мимо:
Warcraft 3 Lua Package Manager (WLPM) - вносит менеджмент пакетов и es6-подобные Lua модули в проект твоей карты
Чтобы оставить комментарий, пожалуйста, войдите на сайт.