Добавлен nazarpunk,
опубликован
Раздел:
Триггеры и объекты
Если вы пользуетесь подсветкой кода во внешнем редакторе, то наверняка сталкивались с проблемой переноса его в карту. Можно конечно использовать WLPM или его аналоги, но мы пойдём путём наименьшего сопротивления и будем собирать lua с помощью lua.
В данном примере я буду использовать IntelliJ IDEA, но этот способ не привязан к какой либо среде разработки и вы можете, к примеру, настроить VS Code по этой инструкции.
Создадим проэкт и настроим подсветку кода:
С картой нам придётся работать в режиме папки так что сохраним её в проэкт. Не забыв переключить в режим lua.
Существует маленькая хитрость, чтоб новая карта носила гордое разрешение .w3x допишите комментарий в Нестандартный код карты.
Создадим папку build в которой будем держать весь код для сборки. Заодно и заполним её тестовым кодом.
Собранный код можно конечно дописывать в конец war3map.lua, чем и занимаются практически все сборщики, мотивируя тем, что можно хукать main. Но мы пойдём другим путём и будем править war3map.wct чтоб собранный код виделся редактором как Нестандартный код карты. Чтобы избавить нас от неблагодарной работы по разбору формата карт Hodor написал custom-code-replacer.exe, который можно положить в папку проэкта и не забыть сказать автору спасибо.
Теперь можно приступать к самой сборке кода. Так как собирать код мы будем с помощью того же языка, на котором и будем его писать, то не буду вас утруждать разжовыванием каждой строчки. Просто скопируйте папку run в корень проэкта:
/run/lib/DirTree.lua
-- http://lua-users.org/wiki/DirTreeIterator
function DirTree(dir)
assert(dir and dir ~= "", "directory parameter is missing or empty")
if string.sub(dir, -1) == "/" then
dir = string.sub(dir, 1, -2)
end
local function yieldtree(d)
for entry in lfs.dir(d) do
if entry ~= "." and entry ~= ".." then
entry = d .. "\\" .. entry
local attr = lfs.attributes(entry)
coroutine.yield(entry, attr)
if attr.mode == "directory" then
yieldtree(entry)
end
end
end
end
return coroutine.wrap(function() yieldtree(dir) end)
end
/run/lib/FileContent.lua
--https://stackoverflow.com/questions/11201262/how-to-read-data-from-a-file-in-lua
local open = io.open
function FileContent(path)
local file = open(path, 'rb') -- r read mode and b binary mode
if not file then return nil end
local content = file:read '*a' -- *a or *all reads the whole file
file:close()
return content
end
/run/build.lua
require 'lfs' -- подключаем LuaFileSystem https://keplerproject.github.io/luafilesystem/manual.html
local param = {
game = [[D:\Games\Warcraft III\x86_64]], -- папка с игрой
map = [[\map.w3x]], -- папка с картой
customCode = [[\custom-code.lua]], -- файл, в который собирается весь код
patcher = [[\custom-code-replacer.exe]], -- патчер для .wct
files = { -- порядок сборки файлов
[[\build\Ability]],
[[\build\libs]],
[[\build\Init.lua]],
},
tag = [[--CUSTOM_CODE]], -- тэг для вставки кода
current = lfs.currentdir() -- текущая папка проэкта
}
-- подключаем нужные функции
dofile(param.current .. [[\run\lib\DirTree.lua]])
dofile(param.current .. [[\run\lib\FileContent.lua]])
-- собираем всё в один файл
local customCode = io.open(param.current .. param.customCode, 'w+')
customCode:write(param.tag, '\n')
for i = 1, #param.files do
local file = param.files[i]
local path = param.current .. file
if file:match "[^.]+$" == 'lua' then
customCode:write(FileContent(path), '\n')
else
for filepath, attr in DirTree(path) do
if (attr.mode == 'file') then
customCode:write(FileContent(filepath), '\n')
end
end
end
end
customCode:write(param.tag)
customCode:close()
-- заменяем код в war3map.lua
local path = param.current .. param.map .. '\\war3map.lua'
local war3map = io.open(path, 'r')
customCode = io.open(param.current .. param.customCode, 'r')
local content = war3map:read('*a')
war3map:close()
war3map = io.open(path, 'w+')
local repl, count = string.gsub(content, param.tag .. '.*' .. param.tag, customCode:read('*a'))
war3map:write(repl)
war3map:close()
customCode:close()
-- патчим .wct
os.execute('start "" "' .. param.current .. param.patcher .. '" "' .. param.current .. param.map .. '\\war3map.wct" "' .. param.current .. param.customCode .. '"')
-- запускаем игру
if type(IsRunGame) == 'boolean' then
os.execute('start "" "' .. param.game .. '\\' .. 'Warcraft III.exe" -loadfile "' .. param.current .. '\\' .. param.map .. '"')
end
-- запускаем редактор
if type(IsRunEditor) == 'boolean' then
os.execute('start "" "' .. param.game .. '\\' .. 'World Editor.exe" -loadfile "' .. param.current .. '\\' .. param.map .. '"')
end
Единственно стоит обратить внисание на эту часть /run/build.lua
local param = {
game = [[D:\Games\Warcraft III\x86_64]], -- папка с игрой
map = [[\map.w3x]], -- папка с картой
customCode = [[\custom-code.lua]], -- файл, в который собирается весь код
patcher = [[\custom-code-replacer.exe]], -- патчер для .wct
files = { -- порядок сборки файлов
[[\build\Ability]],
[[\build\libs]],
[[\build\Init.lua]],
},
tag = [[--CUSTOM_CODE]], -- тэг для вставки кода
current = lfs.currentdir() -- текущая папка проэкта
}
Теперь проэкт должен выглядеть примерно таким образом.
Если вы дочитали до этого момента и всё ещё задаётесь вопросом, каким же образом мы будем исполнять скрипты lua на компьютере, то ответ будет незамысловат - мы его скачаем с luadist.org
Распаковать скачанный архив можно куда угодно, но я выбрал диск "C:\".
Осталось только настроить запуск скриптов из редактора и можно приступать к первой сборке
Запустим файл /run/build.lua
Если вы всё сделали правильно, то сможете наблюдать файл custom-code.lua в корне проэкта, содержащий весь собранный код.
Теперь можно таким же образом запустить run-in-game.lua и проверить, что карта открывается в игре. И наконец run-in-editor.lua, чтоб убедиться в том, что ваш код попал в редактор.
Важно! Сохраните карту в редакторе и закройте его, чтоб код попал в war3map.lua, при каждой последующей сборке он будет автоматически обновляться.
После долгих мучений, можете назначить привычную клавишу Ctrl+F9 для сборки кода
которая будет запускать скрипт, выбранный в этом меню
Полезные ссылки
P.S.
Статья вышла сжатой и без подробностей, но вы всегда сможете задать вопрос в комментариях или скачать проэкт с github.
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Отредактирован Koladik
Отредактирован Koladik
NazarPunk:
Отредактирован pro100master
jasslua =)Отредактирован nazarpunk