Добавлен , опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
Lua
Тип:
Способность
Версия Warcraft:
Reforged
» MUI: да
» Импорт: иконка
» Утечки: нет
» Требования: нет
Длань Господня, способность, которую могли освоить лишь Истинные Паладины. В их руках, эта сила не только излечивала любые раны и болезни. Но и искореняла любое зло, ставшее на пути Паладина.
Божественная вспышка, не знающая пощады для врагов, и дарующая Благодать союзникам.
И самое главное теперь, Паладин может восстановить себе утерянную жизнь, в ровном размере излеченного здоровья или нанесенного урона.
  • Лечит живых или наносит урон андедам в размере "Базовый урон героя * уровень способности".
  • Восстанавливает здоровье кастеру в количестве восстановленного здоровья или нанесённого урона.

Скриншот

Технические подробности

Перенос в свою карту
Триггеры
  • HolyFist
Способности
  • Длань Господня 'SHoF'
Импорт
  • ReplaceableTextures\CommandButtons\BTNSpellHolyFist.blp
  • ReplaceableTextures\CommandButtonsDisabled\DISBTNSpellHolyFist.blp
Настройка
local ABILITY_ID = AbilityId('SHoF')
local EFFECT = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
local EFFECT_ATTACH = "origin"
Код
//! 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 ABILITY_ID = AbilityId('SHoF')
    local EFFECT = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
    local EFFECT_ATTACH = "origin"
    
    -- Заклинание
    local t = CreateTrigger()
    for i = 0, bj_MAX_PLAYER_SLOTS - 1, 1 do
        TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT)
    end
    TriggerAddCondition(t, Condition(function()
        return GetSpellAbilityId() == ABILITY_ID
    end))
    TriggerAddAction(t, function()
        local caster = GetTriggerUnit()
        local target = GetSpellTargetUnit()
        local level = GetUnitAbilityLevel(caster, ABILITY_ID)
        local damage = BlzGetUnitBaseDamage(caster, 1) * level
        local hp_caster = 0

        DestroyEffect(AddSpecialEffectTarget(EFFECT, target, EFFECT_ATTACH))

        if IsUnitType(target, UNIT_TYPE_UNDEAD)
        then
            hp_caster = math.min(damage, GetUnitState(target, UNIT_STATE_LIFE))
            UnitDamageTarget(caster, target, damage, true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS);
        else
            local hp = GetWidgetLife(target)
            SetWidgetLife(target, hp + damage)
            hp_caster = math.min(damage, GetUnitState(target, UNIT_STATE_MAX_LIFE) - hp)
        end
        
        if hp_caster > 0
        then
            SetWidgetLife(caster, GetWidgetLife(caster) + hp_caster)
            DestroyEffect(AddSpecialEffectTarget(EFFECT, caster, EFFECT_ATTACH))
        end
    end)
end
//! endusercode
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
19
5 лет назад
0
Не совсем понял что делает спелл, пока не посмотрел в код. Делай описание по точнее.
Реквестирую больше примеров на луа для чайников, как я.
0
29
5 лет назад
0
Не совсем понял что делает спелл, пока не посмотрел в код.
Описание способностей не моя сильная сторона. Исправил
Реквестирую больше примеров на луа для чайников
Понемногу буду переписывать свои старые заклинания для 1.26 и может новое что-то придумаю)
0
32
5 лет назад
0
NazarPunk, неее, давай сразу новые на луа, чтоб двойной профит..
И у меня вопросы по луа, почему триггер локальный?
И особо луа элементов не заметил, больше на CJ похоже, пропали call и then
а что делает строчка do она обязательна?
0
29
5 лет назад
0
еее, давай сразу новые на луа
Я только любимые перегоню)
больше на CJ похоже
На zinc ещё больше похоже, мой старый код перегонять одно удовольствие)
а что делает строчка do
Блок do end создаёт область видимости и переменные наружу не торчат. Поэтому и триггер локальный)
0
32
5 лет назад
0
Блок do end создаёт область видимости и переменные наружу не торчат. Поэтому и триггер локальный)
а что такое область видимости? то есть это не обязательно? а если ничего не написать всё будет глобально?
про я хз я не програмист
3
29
5 лет назад
3
а что такое область видимости?
Если в кратце изолирование переменных от других областей кода. Вот простейший пример из документации.
local a = 5
print(a) --> 5

do
  local a = 6 -- create a new local inside the do block instead of changing the existing a
  print(a) --> 6
end

print(a) --> 5
0
32
5 лет назад
0
я теперь всё понял, спасибо
0
21
5 лет назад
0
У меня тоже вопрос по Lua. Почему здесь нету функций (кроме условия и действия триггера)? Этот код как-то самоинициализируется или его нужно вызвать где-то?
1
29
5 лет назад
1
Почему здесь нету функций
А зачем они в таком простом заклинании? Я повесил слушатель на событие и спрятал переменные в scope. Что ещё нужно?
0
21
5 лет назад
0
NazarPunk, ну в jass есть функция для инициализации способности, где создаются триигеры и навешиваются события, а здесь такого нет, из-за этого я не понимаю как это работает.
0
32
5 лет назад
0
ScopteRectuS,
как же а это что?
local t = CreateTrigger() - триггер
TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT) - добавление события
этого уже достаточно чтобы проверять условие и делать действия =)
0
21
5 лет назад
0
Bergi_Bear, ну в жасс это еще нужно где-то вызвать. А тут оно само работает или как?
1
29
5 лет назад
1
ну в жасс это еще нужно где-то вызвать
Если конвертировать триггер, то будет тоже самое.
function Trig_cast_Actions takes nothing returns nothing
endfunction

//===========================================================================
function InitTrig_cast takes nothing returns nothing
    set gg_trg_cast = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_cast, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction( gg_trg_cast, function Trig_cast_Actions )
endfunction
Загруженные файлы
0
21
5 лет назад
0
NazarPunk, функция InitTrig_cast будет вызвана в функции InitCustomTriggers, которая, в свою очередь будет вызвана в main. А здесь не понятно, как происходит инициализация способности.
1
29
5 лет назад
1
ScopteRectuS, эх, а я всегда думал, что можно убрать обёртку.
set gg_trg_cast = CreateTrigger(  )
call TriggerRegisterAnyUnitEventBJ( gg_trg_cast, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddAction( gg_trg_cast, function Trig_cast_Actions )
как происходит инициализация способности
Код исполняется и вешает обработчик на событие. А для инициализации, можно использовать старый добрый таймер.
TimerStart(CreateTimer(), 0, false, function()
	print('Init')
end)
0
21
5 лет назад
0
Этот код как функция main сама запускается. Я правильно понимаю? Сори за глупые вопросы, но я кроме жасс не знаю других языков.
0
29
5 лет назад
0
но я кроме жасс не знаю других языков
А я только хотел сравнить с js(
ScopteRectuS:
Этот код как функция main сама запускается
Он сразу исполняется, а так как карта ещё не прогружена оперировать ей неполучится (юнита например разместить на карте не получится). Но можно создавать объекты (триггеры, таймеры, группы) и вешать обработчики событий.
Запуская таймер, вы ставите его в очередь, которая начнёт разгребаться после прогрузки main. Только не забывайте его уничтожать.
TimerStart(CreateTimer(), 0, false, function()
    print('Init')
    DestroyTimer(GetExpiredTimer())
end)
0
21
5 лет назад
0
NazarPunk, спасибо большое, кажется, начинаю понемногу понимать.
0
23
5 лет назад
0
Он сразу исполняется, а так как карта ещё не прогружена оперировать ей неполучится (юнита например разместить на карте не получится).
Но ведь юниты, расставленные в редакторе, на самом деле ставятся в коде. Тот же самый триггер инициализации карты.
0
29
5 лет назад
0
Но ведь юниты, расставленные в редакторе, на самом деле ставятся в коде. Тот же самый триггер инициализации карты.
Только это jass триггер, луа раньше срабатывает.
0
21
5 лет назад
0
Я так полагаю , что работает такой код в тот момент, когда у жасс инициализируются глоб. перменные. Если написать так, то юнит не создается.
Globals
unit u = createUnit( )
endglobals
0
29
5 лет назад
0
Я так полагаю , что работает такой код в тот момент, когда у жасс инициализируются глоб. перменные
Скорее всего сначала lua, потом jass. Можно попробовать BJDebugMsg('jass'), print('lua') ничего не выводит.
0
28
5 лет назад
Отредактирован PT153
0
BJDebugMsg
Не надо эту функцию использовать, внутри её цикл, есть куда более эффективная функция, которая асинхронна.
function DebugMsg takes string s returns nothing
    debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0., 0., 5., s)
endfunction
ScopteRectuS, если так написать, то карта вылетит ещё при нажатии на неё, как мне кажется.
NazarPunk:
Только это jass триггер, луа раньше срабатывает.
Там нет триггера, там просто вызов функции из main.

Я верно понял, что союзная нежить будет получать урон?

Я думаю, что блок do...end выполняется во время клика на карту карты (создания лобби для неё), вот и всё. Если это так, то тогда не стоит использовать GetLocalPlayer(), карта вылетит ещё при клике на неё.

Во время создания карты используется функция config, которая также есть и в Lua, насколько помню. Также создаются все глобалки.
0
29
5 лет назад
0
Я думаю, что блок do...end выполняется во время клика на карту карты
do...end создаёт область видимости и выполняется там, где объявлен.
PT153:
если так написать, то карта вылетит ещё при нажатии на неё, как мне кажется
скорей всего юнит не создатся. хотя тестить нужно
PT153:
Не надо эту функцию использовать
я уже на lua перешёл, а функция для теста приводилась.
PT153:
((цитата
Я верно понял, что союзная нежить будет получать урон?
))
да
PT153:
Во время создания карты используется функция config
Может package.config()? И скорее всего близы её прикрыли.
0
23
5 лет назад
0
NazarPunk, вреш!
Станартный луа
как видим его создает внутри функции и обазначают
Загруженные файлы
Чтобы оставить комментарий, пожалуйста, войдите на сайт.