нормальные пацаны не рисуют, нормальные пацаны генерируют процедурно

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

Тогда

Если вы не знали, то в варкрафте, в лобби, поверх превью минимапы рисуются стартовые позиции и прочие рудники. А в рефе есть дополнительный нюанс — эти рудники рисуются даже поверх кастомной картинки, загруженной вместо минимапы. Решением является удаление файла .mmp из собранного проекта.
Но в момент залива карты на эпиквар я столкнулся с тем, что он ругается на отсутствие mmp. Погуглив формат файла, и проведя эксперимент, я понял, что могу отказаться от удаления файла в пользу его замены на пустой файл, то есть без иконок. Однако мне пришла идея понтануться, и попробовать нарисовать что-то прямо в этом файле. Близзы выделили на него целых 5 иконок 16x16 пикселей, которые можно расставлять по 256x256 канвасу, и менять им цвет и прозрачность. Я тогда даже осилил накидать на луа читалку и писалку файла, но в итоге охладил своё трахание, просто сделал стартовую локацию полностью прозрачной (и никто не догадался, ха!) и оставил так.

Сейчас

Короче на днях я чёт вернулся к этой идее и добил тот луашный скрипт.

Посложнее

Попроще

Да, все эти каляки-маляки сгенерированы несколькими строками луа кода, это не импортированная картинка, это импортированный mmp файл, состоящий из тех самых пяти иконок ужаса.

Навсегда

Из ограничений, похоже есть некий клиппинг по краю минимапы на 8 пикселей. Рабочая зона для рисования скорее [8, 247], а не [0, 255], по крайней мере там результат предсказуем, а на краях у меня были какие-то странности. До ограничения на количество иконок я не доходил, по идее сколько в int32 влезет, столько и может их быть. Кстати, на тысячах иконок на долю секунды можно заметить абсолютно чёрную миникарту, пока всё ещё не прогрузилось.
Наверняка кого-то уже мучает вопрос "А почему нельзя сделать то же самое, только на нормальном жпеге с нормальными пикселями?". Так ведь так интереснее. Может ещё и модели в блокноте мдлвисе перестать делать? Ставь артаса, если хочешь gui редактор mmp на движке LOVE 2D.

API

Для процедурного рисования иконками надо просто гонять 12 байтов, но у меня в какой-то момент оказалось очень много свободного времени, чтобы напечатать кучу методов и обмазаться имитацией инкапсуляции через нотации EmmyLua. На самом деле можно напрямую брать таблицу icons, объекты в ней, и делать с этим всё, что угодно, как делают все тру луашники, и я тоже. Но пусть будет.
Штуки
MMPIconType (Enum)
    Gold = 0
    NeutralBuilding = 1
    StartLoc = 2
    CreepCampSmall = 3
    CreepCampLarge = 4

MMPData (Class)
    MMPData:new() -> MMPData
    MMPData:newFromFile(filePath: string) -> MMPData

    MMPData:write(filePath: string)

    MMPData:countIcons() -> integer
    MMPData:addIcon(icon: MMPIcon, pos?: integer) -> integer|nil
    MMPData:removeIconByNumber(n: integer) -> MMPIcon|nil
    MMPData:removeIconInstance(icon: MMPIcon) -> MMPIcon
    MMPData:enumerateIcons(fn: fun(icon: MMPIcon, index: integer))
    MMPData:newIcon(iconType?: MMPIconType|integer, x?: integer, y?: integer, b?: integer, g?: integer, r?: integer, a?: integer) -> MMPIcon

    MMPData:print()

MMPIcon (Class)
    MMPIcon:setColorBGRA(b: integer, g: integer, r: integer, a: integer)
    MMPIcon:getColorBGRA() -> b: integer, g: integer, r: integer, a: integer
    MMPIcon:adjustColorBGRA(db?: integer, dg?: integer, dr?: integer, da?: integer)
    MMPIcon:setAlpha(a: integer)
    MMPIcon:getAlpha() -> a: integer

    MMPIcon:setPosition(x: integer, y: integer)
    MMPIcon:getPosition() -> x: integer, y: integer
    MMPIcon:translate(dx?: integer, dy?: integer)

    MMPIcon:setType(iconType: MMPIconType|integer)
    MMPIcon:getType() -> MMPIconType|integer
    MMPIcon:getFileName() -> fileName: string

    MMPIcon:print(iconId?: integer)
Пример использования
-- Import
local MMPLib = require("mmp_lib")
local MMPData, IconType = MMPLib.MMPData, MMPLib.MMPIconType

-- Read file
local testFile = "path\\to\\war3map.mmp"
local mmpData = MMPData:newFromFile(testFile)

-- Debug file
mmpData:print()

-- Make all icons red
mmpData:enumerateIcons(function(icon)
    icon:setColorBGRA(0, 0, 255, 255)
end)

-- Write file
mmpData:write(testFile)

-- Create new mmp
mmpData = MMPData:new()

-- Add new icon
local icon = mmpData:newIcon(IconType.CreepCampLarge)
icon:setPosition(125, 125)
icon:setColorBGRA(0, 255, 255, 255)
mmpData:addIcon(icon)

-- Edit icon
icon:setType(IconType.StartLoc)
icon:adjustColorBGRA(25)
icon:translate(-10, 20)

-- Debug icon
icon:print()
`
ОЖИДАНИЕ РЕКЛАМЫ...
27
Чем только не займутся, лишь бы многоэтажную тдшку не пилить...
33
Makeba, а для 1.26 такое будет? Как раз то для эпиквара норм тема
23
Берги, легенда вернулась ради многоэтажной тд. Значит надо Макебе делать
27
ScorpioT1000, а зочем это всё, реквайр что ли сложно написать руками?
19
Ура, контент от главного контентмейкера ру комьюнити на базе 1.26а
Чтобы оставить комментарий, пожалуйста, войдите на сайт.