30

» Защитники Хелерии / Обзор героя: Трейм - Повелитель Бурь

в идеале заряды на активной абилке = хп щита
Это вообще в идеале)
Bergi_Bear:
но я про такое знаю только на мемхаке
А какже 100500 способностей с разными иконками?

Ещё можно отображать сферами, на подобии жезла молний, где каждая сфера, например, поглощает 25/50/75/100/125 урона и количетво сфер равно 1*уровень способности. Когда сферы закончатся, щит спадает.
30

» WarCraft 3 / allocate возвращает 0

Не нашёл документации по class, но можете попробоывать
local PHS_Stack this = PHS_Stack.allocate();
30

» WarCraft 3 / JASS фаербол

если да то как это должно выглядеть
Посмотрите в этой наработке, там структуры с хэштаблицами а таймерами.
Не используйте точки
local location point1 = GetUnitLoc(u)
local location point2 = GetSpellTargetLoc()
// Где RemoveLocation() ?
Лучше координаты
local real casterX = GetUnitX(caster)
local real casterY = GetUnitY(caster)
local real targetX = GetSpellTargetX()
local real targetY = GetSpellTargetY()

Или переходите на lua, там всё в разы проще))
30

» Защитники Хелерии / Обзор героя: Трейм - Повелитель Бурь

здоровье щита отображается над героем в виде текстага
Зачем колхозить с текстагом, если можно красивый бар сделать?)
30

» Защитники Хелерии / Обзор героя: Трейм - Повелитель Бурь

Герой создаёт напряжение своей энергии в области
Какието нездоровые ассоциации на ум приходят)
30

» WarCraft 3 / Самый производительный Bullet Hell

а на луа есть какие нить аналоги таймеров?
Есть Sleep Function, но врятли они работать будут.
30

» WarCraft 3 / Самый производительный Bullet Hell

Начал тестить и вообще какая-то магия происходит. Если из другого таймера делать print(timer), то timer не остановится. Но отпадут действия триггеров или новые таймеры не смогут запуститься. Ещё нужно будет попробовать тупо пересоздавать таймер каждые неколько секунд и насыпать оптимизации.
30

» WarCraft 3 / Самый производительный Bullet Hell

Добавил урон и счётчик эффектов
//! beginusercode
do
    -- На момент патча 1.31 эта функция всегда возвращает 0. Поэтому создадим её локальный аналог.
    local function AbilityId(id)
        return id:byte(1) * 0x1000000 + id:byte(2) * 0x10000 + id:byte(3) * 0x100 + id:byte(4)
    end

    local BULLETS = {}
    local TIMER_PERIOD = 0.03125 --> 1/32
    local SPEED = 600
    local SPEED_INC = SPEED/(1/TIMER_PERIOD)

    local DAMAGE_PERIOD = 0.5
    local DAMAGE_TIME = 0
    local IS_DAMAGE = false
    local DAMAGE_GROUP = CreateGroup()
    
    local BOARD

    -- Настройки
    local ABILITY_ID = AbilityId('SIWh')
    local ARC = 0.3
    local EFFECT = 'Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl'
    
    -- Код
    local GetTerrainZ_location = Location(0, 0)
    local function GetTerrainZ(x, y)
        MoveLocation(GetTerrainZ_location, x, y);
        return GetLocationZ(GetTerrainZ_location);
    end

    local function InMapXY(x, y)
        return
            x > GetRectMinX(bj_mapInitialPlayableArea)
            and
            x < GetRectMaxX(bj_mapInitialPlayableArea)
            and
            y > GetRectMinY(bj_mapInitialPlayableArea)
            and
            y < GetRectMaxY(bj_mapInitialPlayableArea)        
    end

    TimerStart(CreateTimer(), TIMER_PERIOD, true, function()
        if #BULLETS == 0 then return end

        DAMAGE_TIME = DAMAGE_TIME + TIMER_PERIOD

        IS_DAMAGE = DAMAGE_TIME >= DAMAGE_PERIOD

        if
            IS_DAMAGE
        then
            DAMAGE_TIME = 0
        end

        for i=#BULLETS, 1, -1
        do
            BULLETS[i].x = BULLETS[i].x + SPEED_INC*BULLETS[i].cos
            BULLETS[i].y = BULLETS[i].y + SPEED_INC*BULLETS[i].sin
            if
                InMapXY(BULLETS[i].x, BULLETS[i].y)
            then
                BlzSetSpecialEffectX(BULLETS[i].effect, BULLETS[i].x)
                BlzSetSpecialEffectY(BULLETS[i].effect, BULLETS[i].y)
                BlzSetSpecialEffectHeight(BULLETS[i].effect, 20)

                if
                    IS_DAMAGE
                then
                    GroupEnumUnitsInRange(DAMAGE_GROUP, BULLETS[i].x, BULLETS[i].y, 100, Filter(function()
                        local target = GetFilterUnit()
                        return
                            UnitAlive(target)
                            and
                            IsPlayerEnemy(GetOwningPlayer(BULLETS[i].caster), GetOwningPlayer(target))
                    end))
                    ForGroup(DAMAGE_GROUP, function()
                        UnitDamageTarget(BULLETS[i].caster, GetEnumUnit(), 50, false, true, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
                    end)
                    GroupClear(DAMAGE_GROUP)
                end
            else
                DestroyEffect(BULLETS[i].effect)
                table.remove(BULLETS, i)
            end 
        end

        if
            BOARD ~= nil
        then
            LeaderboardSetItemValue(BOARD, 0, #BULLETS)
        end
    end)


    local trigger = CreateTrigger()
    for i = 0, bj_MAX_PLAYER_SLOTS - 1, 1 do
        TriggerRegisterPlayerUnitEvent(trigger, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT)
    end
    TriggerAddCondition(trigger, Condition(function() return
        GetOwningPlayer(GetTriggerUnit()) == Player(0)
    end))
    TriggerAddAction(trigger, function()
        local caster = GetTriggerUnit()
        local x
        local y
        local angle
        UnitRemoveAbility(caster, GetSpellAbilityId())

        TimerStart(CreateTimer(), 0.1, true, function()
            x = GetUnitX(caster)
            y = GetUnitY(caster)
            angle = Deg2Rad(GetUnitFacing(caster))

            table.insert(BULLETS, {
                effect = AddSpecialEffect('units\\nightelf\\Wisp\\Wisp.mdl', x, y),
                caster = caster,
                x = x,
                y = y,
                angle = angle,
                cos = Cos(angle),
                sin = Sin(angle)
            })
        end)
    end)


    -- Board
    TimerStart(CreateTimer(), 1, false, function()
        BOARD = CreateLeaderboard()

        PlayerSetLeaderboard(GetLocalPlayer(), BOARD)
        LeaderboardSetLabel(BOARD, 'Статистика')
        LeaderboardDisplay(BOARD, true)
        
        LeaderboardAddItem(BOARD, "Эффекты", #BULLETS, Player(0))

        LeaderboardSetSizeByItemCount(BOARD, 1)
        
        DestroyTimer(GetExpiredTimer())
    end)

end
//! endusercode
В районе 150-200 эффектов общий таймер может тупо остановиться. Хотя таймеры добавления эффектов исправно работают.
Загруженные файлы
30

» WarCraft 3 / Самый производительный Bullet Hell

а insert и remove это стандартный методы структур lua
В lua таблицы) И да, это стандартные методы для таблиц.
Загруженные файлы
30

» WarCraft 3 / Самый производительный Bullet Hell

prog, это только начало, потом как определюсь с функциями добавления снарядов, переделаю.
TimerStart(CreateTimer(), 0, false, function() print('test') end) выполнится после инициализации карты.
30

» WarCraft 3 / Самый производительный Bullet Hell

Начал писать систему
//! beginusercode
do
    -- На момент патча 1.31 эта функция всегда возвращает 0. Поэтому создадим её локальный аналог.
    local function AbilityId(id)
        return id:byte(1) * 0x1000000 + id:byte(2) * 0x10000 + id:byte(3) * 0x100 + id:byte(4)
    end

    local BULLETS = {}
    local TIMER_PERIOD = 0.03125 --> 1/32
    local SPEED = 600
    local SPEED_INC = SPEED/(1/TIMER_PERIOD)

    -- Настройки
    local ABILITY_ID = AbilityId('SIWh')
    local ARC = 0.3
    local EFFECT = 'Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl'
    
    -- Код
    local GetTerrainZ_location = Location(0, 0)
    local function GetTerrainZ(x,y)
        MoveLocation(GetTerrainZ_location, x, y);
        return GetLocationZ(GetTerrainZ_location);
    end

    local function InMapXY(x, y)
        return
            x > GetRectMinX(bj_mapInitialPlayableArea)
            and
            x < GetRectMaxX(bj_mapInitialPlayableArea)
            and
            y > GetRectMinY(bj_mapInitialPlayableArea)
            and
            y < GetRectMaxY(bj_mapInitialPlayableArea)        
    end

    TimerStart(CreateTimer(), TIMER_PERIOD, true, function()
        if #BULLETS == 0 then return end

        for i=#BULLETS, 1, -1
        do
            BULLETS[i].x = BULLETS[i].x + SPEED_INC*BULLETS[i].cos
            BULLETS[i].y = BULLETS[i].y + SPEED_INC*BULLETS[i].sin
            if InMapXY(BULLETS[i].x, BULLETS[i].y)
            then
                BlzSetSpecialEffectX(BULLETS[i].effect, BULLETS[i].x)
                BlzSetSpecialEffectY(BULLETS[i].effect, BULLETS[i].y)
            else
                DestroyEffect(BULLETS[i].effect)
                table.remove(BULLETS, i)
            end
            
        end

    end)

    local trigger = CreateTrigger()
    for i = 0, bj_MAX_PLAYER_SLOTS - 1, 1 do
        TriggerRegisterPlayerUnitEvent(trigger, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT)
    end
    --TriggerAddCondition(trigger, Condition(function() return true end))
    TriggerAddAction(trigger, function()
        TimerStart(CreateTimer(), 0.5, true, function()
            local caster = GetTriggerUnit()
            local x = GetUnitX(caster)
            local y = GetUnitY(caster)
            local angle = GetUnitFacing(caster)

            table.insert(BULLETS, {
                effect = AddSpecialEffect('units\\nightelf\\Wisp\\Wisp.mdl', x, y),
                x = x,
                y = y,
                angle = angle,
                cos = Cos(angle),
                sin = Sin(angle)
            })
        end)
    end)

end
//! endusercode
Вечером тесты напишу и буду над уроном думать.
Загруженные файлы
30

» WarCraft 3 / Заклинание: Вихрь Иллюзий

GetLocalPlayer, а как прикрепить к weapon эффекта другой эффект? И как получить модель юнита?

И как проиграть анимацию эффекта?
30

» WarCraft 3 / как создать свой GetUnitUserData

и тут нет метода delete, он потерялся =)
Метод create тоже потерялся)
А на lua всё ещё проще)
30

» WarCraft 3 / Заклинание: Вихрь Иллюзий

Причем не важно где Jump объявлена, хоть вначале хоть в конце кода?
Да. Я же приводил пример:
TimerStart(CreateTimer(), 0, false, function()
    test() --> test  
end)

function test()
    test1()
end
function test1()
    print('test')
end

Только первый вызов должен быть после инициализации.
30

» WarCraft 3 / как создать свой GetUnitUserData

Bergi_Bear, к структуре же id юнита привязать нужно через таблицы или использовать unit indexer.
local CustomUnitData u = GetUnitUserData(GetTriggerUnit())
u.data1 = 'data1'
u.data2 = 'data2'
30

» WarCraft 3 / Заклинание: Вихрь Иллюзий

новый таймер на отдельную иллюзию верно же?
Да, решил не переусложнять.
А как сделать чтобы функцию Jump можно было использовать в других триггерах? просто убрать local?
Да
А все эти прыжки адекватно реагируют на склон/глубокую воду?
Из-за того, что у юнита не убран угол крена, на склонах немного подёргивается. Как допилят SetUserField, зафиксится.
30

» WarCraft 3 / Заклинание: Вихрь Иллюзий

если можно с тем-же успехом все через эффекты сделать в 1.31
А как проиграть нужную анимацию эффекта с нужной скоростью?
30

» WarCraft 3 / Самый производительный Bullet Hell

Bergi_Bear, всё никак немогу привыкнуть, что в новом патче эффекты можно в трёх плокостях вращать. Можно ещё оптимизировать и икать столкновения таймером помедленнее, держа координаты эффектов в таблице.
30

» WarCraft 3 / Самый производительный Bullet Hell

Из детекта, мне тоже больше нравится аура жара
А таймеры я бы создавал на группу снарядов, например: кольцо снарядов, линия снарядов, змейка и т.д. Так меньше мороки с кодом и по хэндлу таймера например, можно менять поведение всей группе, не заморачиваясь с лишними переборами.
30

» WarCraft 3 / Как найти наибольшее из нескольких чисел?

Очень сложные виды сортировок для не программиста
Тогда можно вообще не сортировать))
  • Создаёшь группу игроков
  • Проходиш циклом и находишь максимального по рейтингу
  • Удаляешь из группы
  • Назначаешь его ИгрокА
  • Проходиш циклом и находишь максимального по рейтингу
  • Назначаешь его ИгрокБ
  • Начинаешь дуель, обнуляешь ИгрокА, ИгрокБ
  • Повторить, пока игроки не закончатся

Если игроков нечётное количество, предлагаешь последнему покурить))