Добавлен , опубликован
Раздел:
Триггеры и объекты
Если вы пользуетесь подсветкой кода во внешнем редакторе, то наверняка сталкивались с проблемой переноса его в карту. Можно конечно использовать 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.
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
23
4 года назад
0
src - до сборки то есть оригинальный код который не влияет в игре
build - после сборки и компиляции
Странный у вас метод =) Хотя я же на ноде пишу забудь...
0
29
4 года назад
0
Странный у вас метод
Какой есть, конструктивные замечания принимаются.
Хотя я же на ноде пишу забудь...
Возьмите с полки пирожок. А пока будете это делать напишите, какое это имеет отношение к этой теме.
0
32
4 года назад
0
А пока будете это делать напишите, какое это имеет отношение к этой теме
это как говорить, что "я веган"
0
23
4 года назад
0
NazarPunk, из ts компилит в lua а потом дособирает в карту. Все имеет к отношении!
0
7
4 года назад
0
После того собираю проект, запускается не карта, а приложение battle net, можно как-то это избежать ?
2
32
4 года назад
2
Zetox, да, у тебя скорее всего старый сборщик, перекачай и есть новая тема
0
15
2 года назад
Отредактирован DarkLigthing
0
Статья нуждается в доработке, во первых код нуждается в небольшом изменении. В файле Build.lua нехватает дополнительной комманды для запуска экзешников игры "-launch". Без этого ни редактор, ни Wc3 не запустится на современных патчах.
Во вторых, ссылка приведённая в статье luadist.org теперь битая. Там совсем не те ссылки для скачивания, а некие подозрительные APK файлы для андроида.
Загруженные файлы
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.