0
23
4 дня назад
0

» StarCraft 2 / .m3 аддон для Blender

Anime Chan, нужен доброволец, который зальёт новый ресурс с новым аддоном
0
23
5 дней назад
0

» WarCraft 3 / Пулемётный огонь веером

EugeAl, весь дискорд хгма уже на AngelScript
1
23
6 дней назад
Отредактирован Makeba
1

» WarCraft 3 / Пулемётный огонь веером

Во-первых, сообщество XGM настоятельно рекомендует перестать использовать эти решения из 2007-го, с даммиками, вызывающими даммиков, сейчас есть возможность сделать лучше.
Во-вторых, сообщество XGM настоятельно рекомендует перейти на Ujapi и AngelScript.

Немного говнокода на эту тему, набросал на луа в рефе за 1 наносекунду
group = CreateGroup()

--всякие параметры
range = 650
dAngle = 30
stepAngle = 15
projVelocity = 100

Timers = {}
Timers.bullets = CreateTimer()

TimerStart(Timers.bullets, 0.25, true, function()
    launchBullets(GetUnitX(hero), GetUnitY(hero)) -- пусть hero это будет пулемётчик
end)

function launchBullets(x, y) -- выпускаем очередь из пулемёта
    local angle = GetUnitFacing(hero)

    SetUnitAnimation(hero, "attack")
    local segments = getSegments(x, y, range, angle - dAngle, angle + dAngle, stepAngle) --находим конечные точки отрезков, по которым пустим снаряды

    local t = CreateTimer()
    TimerStart(t, 0.03, true, function()
        local p = table.remove(segments, math.random(1, #segments))
        launchBullet(x, y, p.x, p.y) --для красоты пускаем выстрелы с небольшой задержкой

        if #segments <= 0 or IsUnitDeadBJ(t) then
            DestroyTimer(t)
            return
        end
    end)
end

function launchBullet(x, y, x1, y1)
    -- выпускаем "снаряд" и ищем цель
    local eff = AddSpecialEffect("bullets", x, y)
    BlzSetSpecialEffectZ(eff, 60)
    BlzSetSpecialEffectYaw(eff, getAngle(x, y, x1, y1))

    local t = CreateTimer()
    local isProjectileAlive = true
    local xEffect, yEffect = x, y
    TimerStart(t, 0.015, true, function()
        GroupEnumUnitsInRange(group, xEffect, yEffect, 120)
        while true do
            local target = FirstOfGroup(group)
            if target == nil then break end
            GroupRemoveUnit(group, target)
            if UnitAlive(target) and target ~= hero and IsUnitInRangeXY(target, xEffect, yEffect, 50) --ищем юнитов в ренже, кроме пулемётчика
            then
                DestroyEffect(eff)
                isProjectileAlive = false --после первого столкновения уничтожим снаряд, чтобы он не летел дальше
                UnitDamageTargetBJ(hero, target, 20.00, ATTACK_TYPE_PIERCE, DAMAGE_TYPE_NORMAL) -- наносим те самые 20 дальнего урона
            end
        end

        -- двигаем снаряд в нужном направлении
        local sin, cos = getSinCos(xEffect, yEffect, x1, y1)

        xEffect = xEffect + cos * projVelocity
        yEffect = yEffect + sin * projVelocity

        if getDistance(x, y, xEffect, yEffect) >= range or not isProjectileAlive then
            DestroyTimer(t)
            DestroyEffect(eff)
            return
        end
        BlzSetSpecialEffectPosition(eff, xEffect, yEffect, 60)
    end)
end

function getSegments(cx, cy, r, angle1, angle2, angle_step)
    local segments = {}
    local n = math.floor((angle2 - angle1) / angle_step) + 1

    for i = 0, n - 1 do
        local angle = angle1 + i * angle_step
        local x = cx + r * math.cos(math.rad(angle))
        local y = cy + r * math.sin(math.rad(angle))
        table.insert(segments, {x = x, y = y})
    end

    return segments
end

function getSinCos(x1, y1, x2, y2)
    local dX = x2 - x1
    local dY = y2 - y1
    local dist = math.sqrt(dX*dX + dY*dY)
    local sin = dY / dist
    local cos = dX / dist

    return sin, cos
end

function getAngle(x1, y1, x2, y2)
    local deltaX = x2 - x1
    local deltaY = y2 - y1

    local angle
    if deltaX == 0 then
        if deltaY > 0 then
            angle = math.pi / 2
        else
            angle = -math.pi / 2
        end
    else
        angle = math.atan(deltaY / deltaX)
        if deltaX < 0 then
            angle = angle + math.pi
        end
    end

    return angle
end

function getDistance(x1, y1, x2, y2)
    local deltaX = x2 - x1
    local deltaY = y2 - y1

    return math.sqrt(deltaX^2 + deltaY^2)
end

Пример использования, с эффектами и набигающими врагами
Загруженные файлы
0
23
1 неделю назад
0

» WarCraft 3 / Массив в магазине.

лучше на Lua
Lua уже в прошлом, теперь лучше на AngelScript
2
23
1 неделю назад
2

» WarCraft 3 / Где находятся спецэффекты, появляющиеся на земле

Уберсплаты. Путь в архиве что-то типа ReplaceableTextures/splats
0
23
1 неделю назад
0

» WarCraft 3 / Оптимизация Выполнения Последовательности Кода

где-то я это уже видел
В первом ответе то же самое предложено
1
23
1 неделю назад
Отредактирован Makeba
1

» WarCraft 3 / Оптимизация Выполнения Последовательности Кода

Раз уж мы всем хгмом делаем наработку для крафтов, то вкачусь тоже В луа я бы сделал так. Ну, если все предметы разные, без повторений.
RequiredItems = {0x6F646566, 0x6F736C6F, 0x6F666972, 0x6F636F72, 0x6F76656E, 0x4930304C}

function checkItems(u)
    for _, v in ipairs(RequiredItems) do
        if not UnitHasItemOfTypeBJ(u, v) then
            return false
        end
    end
    return true
end
Результат
Загруженные файлы
1
23
1 неделю назад
Отредактирован Makeba
1

» WarCraft 3 / Массив в магазине.

Сразу хочу сказать, что события фреймов в рефе багованные, после патча 1.33 вдвойне багованные, здесь каждый выкручивается как может, но без компромиссов тут не обойтись, как и при любой разработке на рефе чего-то интереснее базовой милишки. Вроде в этой карте автор что-то смог толково сделать, рекомендую посмотреть магазин/инвентарь там. Ещё есть вариант перекатиться на южапи, отсутствие проблем там никто вроде не гарантирует, но там есть перспективы в развитии апи, в отличие от рефа, где разрабы заняты фиксом нежити.
По-моему, событие клика сейчас не особо жалуют, вроде делают через Enter и Leave, но я особо не в курсе.
Я пробую магазин делать я заранее сделал переменные для нужных мне предметов накидал код и заметил что под каждую кнопку нужно функцию клика делать и прикинул что код станет гигантским из за этого.
Нам нужен цикл. Создать какую-то базовую функцию для создания кнопки, вызвать её нужное количество раз, и у нас будет нужное количество кнопок.
Не обязательно на каждую кнопку делать свой триггер, и свою функцию обработки события, это можно сделать в одном триггере, и в одной функции, всё что нужно — это повесить на каждую кнопку своё событие. Естественно, событие можно добавить прямо в этом же цикле, где мы создаём кнопки. В триггере останется лишь получить триггернувшийся фрейм, и узнать связанный с ним предмет, который, естественно, нужно связать заранее, например в массиве.
Набросаю пример на луа, ибо не умею в джасс. Ну это так, база, в мультиплеерную карту как готовое решение это не пойдёт, да и в синглплеерную тоже из-за сломанных в рефе сейвов, чивоуштам. На каждую кнопку создал четыре фрейма. Для отслеживания клика используем тип "BUTTON", его прикроем сверху типом "BACKDROP". Ну и два текстовых фрейма для тултипа и стоимости.
код
-- Список доступных для продажи предметов, 15 штук
ItemDB = {'afac', 'spsh', 'ajen', 'bgst', 'belv', 'bspd', 'cnob', 'ratc','rat6','rat9', 'clfm', 'clsd', 'crys', 'dsum', 'rst1'}

FrameToItem = {} -- в будущем заполним эту таблицу, связав фреймы с кодами итемов
Buttons = {} -- в будущем заполним эту таблицу, связав фреймы со стоимостью итемов
CancelShopFrame = nil -- тут будет кнопка выхода из магазина

function Init()
    hero = CreateUnit(GetLocalPlayer(), FourCC('Hpal'), 0, 0, 0) --герой, которому будем выдавать предметы
    SetPlayerState(GetLocalPlayer(), PLAYER_STATE_RESOURCE_GOLD, 30000) --накинем голды
    initShop() --создадим магазин
end

function initShop()
    local size = 0.03 --размер кнопки
    local startX, y = 0.5, 0.5 --начальная позиция
    local rows, columns = 4, 4 --количество рядов и столбов
    local deltaX, deltaY = 0.05, -0.05 --расстояние между кнопками
    local counter = 1 --счётчик предметов
    local triggor = CreateTrigger()

    for r = 1, rows do --ряды
        y = y + deltaY
        for c = 1, columns do --столбцы
            local x = startX + deltaX * (c - 1)
            if counter >= 16 then -- 16-ую позицию использует для кнопки выхода
                CancelShopFrame = createButton(x, y, size, "ReplaceableTextures\\CommandButtons\\btncancel", "Exit shop", "")
                BlzTriggerRegisterFrameEvent(triggor, CancelShopFrame, FRAMEEVENT_CONTROL_CLICK)
                break
            end
            local item = ItemDB[counter] -- получили равкод итема
            local text, path = getItemInfo(item)
            local cost = math.random(1, 7000) -- в моём примере цена будет рандомная
            local button = createButton(x, y, size, path, text, ""..cost)

            BlzTriggerRegisterFrameEvent(triggor, button, FRAMEEVENT_CONTROL_CLICK)
            FrameToItem[button] = item --записали пару "фрейм = равкод предмета"
            Buttons[button] = cost --записали пару "фрейм = стоимость предмета"
            counter = counter + 1
        end
    end
    TriggerAddCondition(triggor, Condition(clickToShopFrame))
end

function getItemInfo(id) --вернёт иконку и тултип предмета из РО
    --увы, это можно сделать только создав экземпляр предмета, в идеале эти данные ещё бы записать куда, а можно и заранее написать прямо в коде
    local item = CreateItem(FourCC(id), 10000, 10000)
    local text = BlzGetItemTooltip(item)
    local path = BlzGetItemIconPath(item)
    RemoveItem(item)
    return text, path
end

function clickToShopFrame() -- здесь обрабатываем событие из триггора
    local frame = BlzGetTriggerFrame()
    resetFrame(frame) --клик по фрейму блокирует события клавы, так что такой костылёк может пригодиться, но не обязательно
    if frame == CancelShopFrame then
        for k, v in pairs(Buttons) do
            BlzFrameSetVisible(k, false)
        end
        BlzFrameSetVisible(frame, false)
        return
    end
    sellItem(frame)
end

function resetFrame(fr)
    BlzFrameSetEnable(fr, false)
    BlzFrameSetEnable(fr, true)
end

function sellItem(frame)
    -- Здесь мы проверяем голду и делаем что-нибудь с предметом
    local gold = PLAYER_STATE_RESOURCE_GOLD
    local currentGold = GetPlayerState(GetLocalPlayer(), gold)
    local cost = Buttons[frame] --получили цену предмета

    if cost <= currentGold then
        SetPlayerState(GetLocalPlayer(), gold, GetPlayerState(GetLocalPlayer(), gold) - cost)
        local item = CreateItem(FourCC(FrameToItem[frame]), 10000, 10000)
        if not UnitAddItem(hero, item) then -- если в инвентаре нет места, то создаём рядом
            SetItemPosition(item, GetUnitX(hero), GetUnitY(hero))
        end
        outputItemInfo(item, cost)
        return
    end
    print "Not enough gold!"
end

function outputItemInfo(item, cost)
    print("Received a |c0000FF80"..GetItemName(item).. "|r worth |c00FFFF00"..cost.."|r gold")
end

function createButton(x, y, size, iconPath, tooltipText, cost)
    -- Достаточно одного фрейма-кнопки, но для красоты и функциональности можно добавить всё что угодно
    -- В данном случае создаёт кнопку, иконку-бекдроп, тултип и текст фрейм для отображения стоимости

    local button = BlzCreateFrameByType("BUTTON", "", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScoreScreenTabButtonTemplate", 0)
    local icon = BlzCreateFrameByType("BACKDROP", "", button, "", 0)

    BlzFrameSetAllPoints(icon, button) --икнока будет полностью закрывать кнопку
    BlzFrameSetAbsPoint(button, FRAMEPOINT_CENTER, x, y)
    BlzFrameSetSize(button, size, size)
    BlzFrameSetTexture(icon, iconPath, 0, false)

    local tooltip = BlzCreateFrameByType("TEXT", "", button, "", 0)
    BlzFrameSetTooltip(button, tooltip)
    BlzFrameSetPoint(tooltip, FRAMEPOINT_BOTTOMLEFT, button, FRAMEPOINT_TOP, 0, 0)
    BlzFrameSetEnable(tooltip, false)
    BlzFrameSetText(tooltip, "|c00FFFF00"..tooltipText.."|r")

    local costFrame = BlzCreateFrameByType("TEXT", "", button, "", 0)
    BlzFrameSetPoint(costFrame, FRAMEPOINT_TOPLEFT, button, FRAMEPOINT_BOTTOMLEFT, 0, 0)
    BlzFrameSetPoint(costFrame, FRAMEPOINT_BOTTOMRIGHT, button, FRAMEPOINT_BOTTOMRIGHT, 0, -0.01)
    BlzFrameSetEnable(costFrame, false)
    BlzFrameSetText(costFrame, cost)
    BlzFrameSetTextAlignment(costFrame, TEXT_JUSTIFY_CENTER, TEXT_JUSTIFY_MIDDLE)

    return button, icon, tooltip, costFrame
end
На джассе примерно то же самое, только хуже.
Результат на видео и в карте.
Загруженные файлы
0
23
1 неделю назад
Отредактирован Makeba
0

» Блог Storm'а / Суицидальная атака на Maya API

Переключение между клипами чёт вообще колхозноватенько реализовано в майе, по сравнению с тем же блендером. Хотя может это я неправильно делаю, ибо в интерфейсе майи разбирался по шортсам с ютуба, кек

Ещё неожиданным приколом оказалось, что Майа не умеет в 3дмаксовский TCB, который в основном близзы использовали в варкрафте, так что либо безье, либо линейная интерполяция.

Этот эйлер сломался, несите следующего
0
23
2 недели назад
0

» Администрация XGM / XGM предлагает проиграть однокадровые гифки

MpW, коммьюнити попросило, получается
Автозагрузка видосов с ютуба раздражает, кстати
0
23
2 недели назад
0

» Администрация XGM / XGM предлагает проиграть однокадровые гифки

А нафига их вообще делать с кнопкой?
0
23
2 недели назад
0

» Администрация XGM / XGM предлагает проиграть однокадровые гифки

Результат
Чёт вопрос отредачить не могу
Загруженные файлы
0
23
2 недели назад
0

» Warcraft 3: The Lord Of The Rings / удалить

ладно
1
23
2 недели назад
1

» WarCraft 3 / Экспорт модели из Блендера в Mdl формат

Чисто по ощущением, кажется, что не зафиксирована бинд поза. Если все анимации раскиданы на одной линейке, и отмечены маркерами, то в нулевом кадре (до начала анимаций) нужно для всех костей зафиксировать LocRotScale.
Но в твилаковском плагине давно уже есть вариант с экспортом анимаций из экшонов, то есть один Action — одна анимация, и с километровой линейкой можно не возиться
1
23
2 недели назад
1

» Блог Storm'а / Тестим PopcornFX в рефоге

Говорят, что вроде попкорны из диабло 2 ресурректед можно использовать в рефоге
0
23
2 недели назад
0

» Блог Storm'а / Тестим PopcornFX в рефоге

Набросал видос с процессом импорта. Это не то чтобы гайд или руководство к действию, просто обозначить суть. Видно что частицы летят немного не туда, думаю из-за неправильных осей.
3
23
2 недели назад
3
0
23
3 недели назад
0

» Unryze Jass API / UjAPI - AngelScript

nazarpunk, ну так и не откатываюсь
0
23
3 недели назад
0

» WarCraft 3 / RMS Twilac Edition

Вышла новая версия! Прокрутить к ресурсу
Обновил.
Изменения
This one comes equipped with:
  • Snap-transform for Move and Scale
  • Working prompt for choosing installation/resource folder

From _b:
  • Mapping nodes when importing Animation now shows most Nodes instead of only Bones
  • Selection Box now uses color from settings
  • Added "unselectable" to the table in GeosetOverviewPanel
  • Fixed some issues with editing ExtLog
  • The Internal browser no longer resets the camera when changing model
  • Added "Remove If Less Than", "Snap To Step" and "Adjust influence for selected" to SkinningOptionPanel
  • Fixed ReplaceBonesAction not being undoable
  • Fixed KeyframeActionHelpers not checking timeline.getEntryMap != null
  • Added QuickDismiss popup to ModelLoader for when a file isn't found or filetype not supported
  • Added a few filetypes to be opened with FileViewer
  • Fixed saving settings (now human-readable)
  • Removed loading of legacy settings
  • Added checkbox for Optimize On Save to the file menu
  • Added "Cut Edge" to TwilacsTools
  • Added a checkbox for "Preserve Animations" panel on the right when editing T-Pose
  • The "show popup menu"-button is now located in a slightly better spot
  • (Hopefully) fixed selection in perspective viewport being off...
  • Export Animations now has a popup with some options
  • Fixed some instances of selection info not updating properly
  • Fixed changing mode from ANIMATE while playing animation continuing playing the animation
  • Undoing deleting nodes will now put them back in the original order
  • Undoing deleting the last vertices of geosets will now put the geosets back in the original order

From _a:
  • Fixed issue where redoing adding keyframes would accumulating transforms
  • Fixed issues with animating Scaling
  • Merge Geosets now has a more intuitive UI, and puts geosets back in the correct order when undoing
  • Added an option to choose rotation axis to Rotate Model
  • Made Rotate Model now rotates (non uniform) scale-values better
  • ImportPanel now adds GlobalSeqs and used ribbon materials
  • Simplified TimeBoundChooserPanel by removing deprecated stuff
  • Simplified the add new Animation popup by removing unnecessary stuff
  • Fixed layer filter mode Blend not rendering properly
  • Fixed Duplicate Animation not copying Geoset Extents
  • Cleaned up ReorderAnimationsPanel and added options to set when the first animation should be placed and align the start times of the following animations to rounded times
  • Changed some list rendering
  • Can now paste stuff with global sequences, and will match animations only by uppercase alphanumerical name
  • Removed some non-functioning menu settings
  • Edit flip-book textures as text now does a better job parsing file paths
  • Added some model loading messages
  • Added setting for default file extension filter
  • Cleaned up the preferences window
  • GifExportHelper no longer throws an error when trying to export a static pose
  • RecalculateExtents now fully undoable
  • Changing Interp Type now properly undoable after redo
  • Changing Material ShaderString to an SD-string no longer doubles all layers
  • Fixed a bug preventing saving flip-book materials
  • Fixed NodesOverviewPanel not showing Helper count
  • Added save and load buttons to the ShaderEditPanel
  • Made some changes to maybe render transparent geosets better
  • Can now play .flac event sounds
  • Can now propagate expansion by holding [ctrl] for MPQImageBrowser and MPQBrowser
  • The ImageBrowser now has a filter-menu for image type
  • Added some markers to Texture names to warn if the filepath is sus
  • Added a button to ComponentPopcornPanel for exporting with ".pkb" as file extension
  • Added checkboxes for dropShadow and unselectable to ComponentGeosetPanel
  • Can now parse Reforged sound lookup to display sound names for EventObject
  • Prettier names for Materials in lists
  • GeosetAnim will now properly save static alpha
  • Will now properly save GeosetAnim.staticColor=[0,0,0] when saving as .mdl
  • Added MaterialOverviewPanel
  • Wrapped Particle and Particle2 specific settings in a collapsable panel
  • Made Create Back2BackAnimation undoable
  • ScaleSequencesLengthsAction will now properly put things back on undo
  • Added some more options in the SkinningOptionPanel
0
23
3 недели назад
Отредактирован Makeba
0

» Unryze Jass API / UjAPI - AngelScript

Unryze, к хорошему быстро привыкаешь, физически больно откатываться назад к менеджеру импорта и mpq редактору
0
23
3 недели назад
0

» Unryze Jass API / UjAPI - AngelScript

Добавьте файл через менеджер импорта или же MPQ по пути Scripts\\war3map.as или же просто war3map.as.
Режим папки [как в рефе] возможен на 1.26-1.28? Что-нибудь такое в перспективе вообще планируется?
0
23
3 недели назад
Отредактирован Makeba
0

» Прочее / Сэмми Дидье вкатился в Stormgate

привлекли громкое имя для галочки
Имха, сейчас в этом нет особого смысла, ибо карту "Мы – те самые старые Близзард, которых вы любили в детстве, а не эти корпоративные повесточные активижоновские мелгомягкие болваны, которых вы ругаете в интернете" они уже успешно разыграли, кикстартер тому подтверждение.
Может по старой дружбе подкинули халтурку деду.
0
23
3 недели назад
0

» Прочее / Первый взгляд на редактор кастомок Stormgate

KlonRefa, может и целую аниме-расу кошкодевочек добавят. А может и не добавят.
Загруженные файлы
2
23
3 недели назад
Отредактирован Makeba
2

» Прочее / Сэмми Дидье вкатился в Stormgate

Неканон, недостаточно зашакалено
Загруженные файлы