2
17
3 года назад
2

» WarCraft 3 / Опрос варкрафтеров XGM

Варкрафт - прошлое. Варсмеш - будущее.
1
17
3 года назад
Отредактирован GetLocalPlayer
1

» WarCraft 3 / зачем в lua нужны локальные функции?

а если я создаем локалки в процессе инициализации код, они будут существовать всю игру. Или только существуют в процессе инициализации? И уже перестанут существовать?
Блок кода do/end разделяет те же правила. То есть
Код
do
    local a = 10 -- Локальная переменная внутри блока do/end
end
-- Блок кода завершен, локальной переменной "a" больше не существует.
Я распишу твой пример
Код
do -- создаём область видимости, чтоб не конфликтовать с другим кодом
    local InitGlobalsOrigin = InitGlobals -- хукаем функцию InitGlobals
    -- Переменная InitGlobalsOrigin является локальной и существует
    -- только внутри текущего do/end блока
    function InitGlobals() -- объявляется глобальной и заменяет собой оригинальный InitGlobal
        InitGlobalsOrigin() -- переменная InitGlobalsOrigin продолжает существование внутри текущей функции
        local Table = { {},{},{} } -- локальная таблица, которая существует в передлах текущей функции
    end
    -- Конец функции, здесь Table уже нет.
end
-- Конец блока, локальной переменной InitGlobalsOrigin здесь не существует.
-- Однако, она продолжает свое существование внутри той InitGlobals функции,
-- которая была объявлена внутри do/end блока
3
17
3 года назад
3

» WarCraft 3 / зачем в lua нужны локальные функции?

Для того же, для чего и локальные переменные - ограничить область видимости (а зачастую и время жизни) объекта текущим блоком кода
Код
function MyFunc()
    local a = 10

    local function InnerFunc()
        print(a)
    end
end
Переменная a внутри функции MyFunc объявлена локальной. следовательно, доступ к этой переменной возможен только внутри этой функции. Так как функция InnerFunc так же определена внутри функции MyFunc, она имеет доступ к локальной переменной a.
Поскольку функция InnerFunc так же как и переменная a объявлена локальной, доступ к этой функции возможен только внутри тела функции MyFunc.
При это, функция InnerFunc, конкретно в данном примере, как и переменная a, будучи локальной, существует только до тех пор, пока выполняется код объемлющей функции. То есть, она прекратит свое существование, в момент выхода из функции MyFunc
Но, что важно, если мы уберем слово local при объявлении функции InnerFunc
Код
function MyFunc()
    local a = 10

    function InnerFunc()
        print(a)
    end
end
то внутри тела функции MyFunc мы создаем глобальную функцию с именем InnerFunc. То есть, если до момента вызова функции MyFunc в глобальной области видимости не существовало чего-либо с именем InnerFunc, то оно будет создаваться и назначаться (переназначаться) с каждым вызовом MyFunc.
3
17
3 года назад
3

» WarCraft 3 / Memory hack API v1.4

Спойлер
1
17
3 года назад
1

» WarCraft 3 / Как работать с картой в виде папки?

Сразу уточню, что без использования внешних сборщиков.
Только для импорта и то не уверен.
0
17
3 года назад
0

» WarCraft 3 / Negate Damage library

Опять же, не нужна константа MaxLifeBonus. Присвоить этой переменной значение 0, в теле функции проверить, если оно равно 0, то выщитать MaxLifeBonus при добавлении способности.
И хуки с предупреждением в дебаг моде на функции GetUnitState, GetUnitStateSwap, GetUnitStatePercent, GetUnitLife все таки нужны.
0
17
3 года назад
0

» WarCraft 3 / Negate Damage library

А что это даст? Событие всё равно добавится.
Если порядок исполнения зависит от порядка регистрации событий, то можно было бы зарегистрировать свой триггер на олов урона после регистрации всех пользовательских. Код этого триггера исполнялся бы после всех пользовательских и это хороший момент для выдачи способности/запуска таймера.
Но это прокатило бы если бы хуки вызывали хук-функцию после оригинальной, а не перед.
0
17
3 года назад
Отредактирован GetLocalPlayer
0

» WarCraft 3 / Negate Damage library

Было бы удобнее хукать TriggerRegisterUnitEvent, но поскольку vJass позволяет хукать функции только до их выполнения, наш хук будет выполнятся перед основной функцией, в то время как нам надо после. Шипко изящного решения что-то не высматривается.
Тем не менее, на данном этапе можно намутить хотя бы это
Код
static if DEBUG_MODE then
    private function hook_GetUnitState takes unit u, unitstate state returns nothing
        if state == UNIT_STATE_MAX_LIFE and GetUnitAbilityLevel(u, HealthAbility) > 0 then
            call BJDebugMsg("WARNING: попытка получить максимальное здоровье юнита, увеличенное библиотекой Negate Damage")
        endif
    endfunction

    hook GetUnitState hook_GetUnitState
endif
По крайней мере пользователь будет знать, где ошибся. Аналогичный хук нужен как минимум для ГУИшного GetUnitStateSwap
0
17
3 года назад
Отредактирован GetLocalPlayer
0

» WarCraft 3 / Negate Damage library

PT153, не думаю, что это возможно.
Но!
Но мы вероятно можем контролировать момент, когда мы добавляем макс. хп. Варкрафт ведь линеен, у него нет многопоточности, он не порождает параллельных процессов. Это означает что все триггеры на получение урона юнитом, срабатывают последовательно. Но под влиянием каких правил выстраивается последовательность исполнения триггеров? В порядке назначения им событий? Или в порядке создания триггеров? Зависит ли очередь от величины числового значения хэндла? В порядке регистрации собития (TriggerRegister...Event)? Это очередь или стек?
Зная, как выстраивается последовательность, мы можем хукнуть подходящую функцию таким образом, чтобы максимальное хп юнита увеличивалось не в момент вызова функции, а после того как все пользовательские триггеры отработали.
2
17
3 года назад
Отредактирован PT153
2

» WarCraft 3 / Наличие типа юнита в массиве

Ну самый простой вариант уже дали, с хэш-таблицей, там есть конкретная функция проверки наличия записи
Я вообще не понимаю, почему ГУИшники хэш-таблицу так не любят. С одной стороны, это избавляет их от гигантского массива переменных, с другой стороны, можно использовать хоть русский язык для сохранения значений
Загруженные файлы
0
17
3 года назад
0

» WarCraft 3 / Negate Damage library

А что делать, если пользователь использует другие библиотеки, затрагивающие максимальный запас здоровья? Чужие наработки, сделанные на заказ. Да и что делать тогда ГУИшнику, если в его карте уже тонна обращений к дефолным бж-функциям?
0
17
3 года назад
Отредактирован GetLocalPlayer
0

» WarCraft 3 / Negate Damage library

Ты падажи, у меня еще вопросы остались.
А что если пользователь совершает какие-то операции с максимальным запасом здоровья юнита, после вызова твоей функции? Ведь в таком случае, он будет работать с максимальным запасом здоровья, увеличенным способностью из твоей библиотеки.
Например, у пользователя в карте есть такая способность
Карающее воздаяние мстительного возмездия (пассивное)
Всякий урон против героя провоцирует взрывную волну, которая наносит урон всем противникам в размере 20% от максимального запаса здоровья героя.
Перезарядка: 10 секунд.
Предположим, у владельца способности 1000 ед. здоровья. Если пользовательский триггер, отвечающий за эту способность, срабатывает ДО вызова твоей функции, то все работает ожидаемо и противникам вокруг наносятся запланированные 200 ед. урона. Однако, если очередь триггеров выстроилась таким образом, что триггер, отвечающий за способность срабатывает ПОСЛЕ вызова твоей функции, то из-за того что твоя функция увеличивает макс. запас здоровья на 1 000 000, владелец способности сеет вокруг кровавый апокалипсис нанося более 200000 урона за раз,
Та же невообразимая хурма может получится со всякими щитами, которые накладываются на юнита в момент получения урона и зависят от макс. запаса здоровья. Да и вообще с этой механикой можно наворотить кучу всего.
2
17
3 года назад
Отредактирован GetLocalPlayer
2

» WarCraft 3 / Negate Damage library

То есть, ты исцеляешь юнита на весь миллион, который дает способность. А зачем? С одной стороны, переменная HealthAmount не несет особого смысла, ведь ты можешь просто вычислить то количество здоровья, которое дается юниту. Взять макс. здоровье до вручения способности и макс. здоровье после. Одно вычитаем из другого и вот оно значение. То есть тут открывается простор для ошибок со стороны конечного пользователя, если он решит отредактировать способность но забудет внести соответствующую правку в код.
С другой стороны, библиотека подразумевает уменьшение полученного урона, верно? Соответственно, тебе достаточно добавить юниту текущее здоровье, в размере уменьшенного урона. То есть не
call SetWidgetLife(u, life + HealthAmount)
а
call SetWidgetLife(u, life + negated)
0
17
3 года назад
0

» WarCraft 3 / Negate Damage library

во время выполнения функции у юнита может быть миллион хп
Это откуда они у него возьмутся.
0
17
3 года назад
0

» WarCraft 3 / Negate Damage library

Теперь не ясно назначение функции HealUnits.
Технически, мы даем способность с дополнительным здоровьем только для того чтобы мы могли исцелить юнита, в случае, если необходимое исцеление превышает его максимальный запас здоровья. Следовательно, все, что нам нужно сделать по истечению таймера, это отнять у юнита эту способность. Нас даже не беспокоит, умер ли юнит на тот момент, нам нужно только отнять способность и установить его текущее здоровье равное здоровью до удаления способности, что-то вроде этого
Код
local unit u
local real currentHealth
loop
    set u = FirstOfGroup(...)
exithwen u == null
    set currentHealth = GetWidgetLife(u)
    call UnitRemoveAbiity(...)
    call SetWidgetLife(u, currentHealth)
    call GroupRemoveUnit(...)
endloop
3
17
3 года назад
3

» WarCraft 3 / Использование ShellExecute

Хочу пассивку, которая с шансом при каждой атаке открывает дисковод и закрывает если открыт.
3
17
3 года назад
3

» WarCraft 3 / Друг

задавай вопросы по редактору, ответят
Первые ответов пятнадцать будет о том что от тебя говной воняет, раз тебя даже в гугле забанили, а там где-то в конце может и затерется маломальски вменяемый ответ.
2
17
3 года назад
2

» WarCraft 3 / Обучение jass

quq_CCCP:
Потом видосики мало помогают, нужно запоминать Хотя-бы базовые функции и синтаксис, а по видео это не сделать, особенно с такими предметами.
Не могу согласиться. Есть такое понятие как сопроводительный материал. Статьи по Жассу/вЖассу это замечательно, как и процесс зазубривания, но наблюдение какой-то активности другого человека со стороны заставляет тебя осмысливать эту самую чужую активность, углубляя таким образом понимание процессов, просто хотя бы за счет сверки имеющихся знаний с происходящим перед глазами.
0
17
3 года назад
0

» WarCraft 3 / Get Unit Armor

В таком случае нужно наносить урон 2 раза, чтобы выяснить чистый урон у такого типа брони и урон с вычетом брони у такого типа брони.
Да ну и хрен с ним. Главное чтобы конечный пользователь, по дефолту считающийся дураком, был как можно дальше отстранен от внутренней механики кода.
0
17
3 года назад
0

» WarCraft 3 / Get Unit Armor

Так что он не подходит.
Почему не подходит? Сначала ты делаешь вывод о типе брони, исходя из того как урон был модифицирован, а затем вычисляешь количество брони.
2
17
3 года назад
2

» WarCraft 3 / Get Unit Armor

Присвоить константе AttackType такой тип атаки, у которого одинаковый бонус ко всем типам брони.
В жассе есть дыра с дополнительным типом атаки, она используется для определения типов брони и ее количества в разных системах. Обсуждение можно найти, например, тут.
Вкратце, базовые типы атаки заданы константами
ATTACK_TYPE_NORMAL = ConvertAttackType(0)
ATTACK_TYPE_MELEE = ConvertAttackType(1)
ATTACK_TYPE_PIERCE = ConvertAttackType(2)
ATTACK_TYPE_SIEGE = ConvertAttackType(3)
ATTACK_TYPE_MAGIC = ConvertAttackType(4)
ATTACK_TYPE_CHAOS = ConvertAttackType(5)
ATTACK_TYPE_HERO = ConvertAttackType(6)
Но влындив семерку промеж булочек мы получим тип атаки нерегулируемый игровыми константами
ATTACK_TYPE_HORNY = ConvertAttackType(7)
0
17
3 года назад
0

» WarCraft 3 / Negate Damage library

Поэтому абилка с хп и добавляется
Речь не про абилку а про отхил. Про то что отхиливать нужно в момент получения урона.
2
17
3 года назад
2

» WarCraft 3 / Negate Damage library

Нипанаятна.
С одной стороны, юниту необходимо установить его текущее здоровье в момент выдачи способности с дополнительным хп, поскольку, при увеличении максимального запаса здоровья, процент текущего запаса здоровья сохраняется, что изменяет его численное количество (или нет?).
С другой стороны, отхиливать юнита нужно в момент нанесения урона. Если делать это в таймере с нулевой задержкой, то в момент исполнения кода таймера юнит уже может быть мертв от того самого урона, от которого его полагалось отлечить.
0
17
3 года назад
0

» WarCraft 3 / Спавн юнита с помощью фрейма

А на Wurst мемхак не прикручивали?