Всем привет я вот не давно нашел код скила оригинальной доты, и вот что я вижу в доте используется одна глобальная переменная GlobalUnit на всех способностях героев и предметов для того чтобы ловить условие и ForGroup. Оказывается глобальная переменная тоже может использоваться как локальная если грамотно сделать способности. А вот loop endloop. Мне кажется что ForGroup с глобалкой работает быстрее чем loop. В общем стоить ли использовать систему дота для своей способности или без разницы?
function C takes nothing returns nothing
local unit c=GetEnumUnit()
call UnitDamageTarget(GlobalUnit,c,200,false,true,ATTACK_TYPE_HERO,DAMAGE_TYPE_NORMAL,WEAPON_TYPE_WHOKNOWS)
set c = null
endfunction
function B takes nothing returns boolean
return IsUnitEnemy(GlobalUnit,GetOwningPlayer(GetFilterUnit())) and (GetUnitAbilityLevel(GetFilterUnit(),'A000')==0 and IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE)==false and (IsUnitType(GetFilterUnit(),UNIT_TYPE_DEATH)==false
endfunction
function A takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit u = LoadUnitHandle(H,GetHandleId(t),0)
local group g = CreateGroup()
set GlobalUnit=u
call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),1200,Condition(function B))
call ForGroup(g,function C)
call DestroyGroup(g)
if TIMER == 5 then
set TIMER = 0
call FlushChildHashtable(H,GetHandleId(t))
call PauseTimer(t)
call DestroyTimer(t)
else
set TIMER = TIMER + 1
endif
set u = null
set g = null
set t = null
endfunction

20 раз кидаю
вся разница что есть - околонулевая...
"Заметно медленнее" вы тролите? на сколько медленнее? прям замечали, прям глазом, как задержки идут при переборе 30 юнитов в лупе и 30 юнитов в ForGroup.. Прям Fps в нули просаживается. В картах типа доты, может быть перебор либо пачки юнитов ну реально в глубоком лейте 30 штук, когда Ember Spirit кастует что-то раз в 10 сек или когда зевс ультует идёт перебор всех героев + клонов + иллюзий раз в 2 минуты. И ту начинается раздуемье, а как же перебрать, может по массиву пройтись и заранее всех занести...
Рили это рофл? что за байтодрочерсво?
DracoL1ch, У тебя есть бенчмарк вызова функций в мемхаке верно? (ну или что-то типа этого)
Давай результаты: 30 юнитов в LOOP и 30 юнитов через ForGroup иначе это всё бесполезнейшее 3,14здабольство и байтодрочерство, я не спорю что быстрее, но эта разница на столько мала, что тема не требует обсуждения.
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
8
Наложения в использовании тоже не будет.
Если быть достаточно неаккуратным - будет. Например вот такой вот код, при использовании глобалок сработает совсем не так, как ожидалось:
globals
    unit u1
    unit u2
    unit u3
endglobals
function Trig_REVENGE_Actions takes nothing returns nothing
    set u1 = GetTriggerUnit()
    set u2 = GetEventDamageSource()
    set u3 = CreateUnit(GetOwningPlayer(u1),'h000',GetUnitX(u2),GetUnitY(u2),0)
    call UnitAddAbility(u3,'A000')
    call IssueTargetOrder(u3,"thunderbolt",u2)
    call RemoveUnit(u3)
endfunction
И все это, о ужас! будет зависить от внешних условий, так что использование глобалок - способ получить обидную и неприятную ошибку.
Загруженные файлы
28
goodlyhero, что этот код вообще должен делать непонятно, ведь юнит даже не сможет кастануть абилку, сразу удалившись
Vlod:
Пожалуйста пруфы
Помимо слов Ханабиши, quq_CCCP говорил, что булекспры вообще другая машина обрабатывает
Гуванч:
по этому я всегда делаю так
set bj_lastCreatedGroup = CreateGroup()
Я тебе говорил юзай спокойно одну глобалку, не нужно создавать и уничтожать, и не только я один, помню Берги ещё писал. Но ты никого не слушаешь как всегда. У тебя происходит 3 действия вместо 1 (если делать действия в булекспре): создание, перебор, удаление

То есть таким образом ты делаешь куда большую нагрузку, чем использование одной глобалки. Бенчмарк в помощь
25
Если быть достаточно неаккуратным - будет. Например вот такой вот код, при использовании глобалок сработает совсем не так, как ожидалось:
Можешь сделать эти переменные локальными - ничего не поменяется. Этот код всегда будет работать так, как ты его написал. Никаких зависимостей от внешних условий тут нет.
18
native GroupEnumUnitsInRange takes group whichGroup, real x, real y, real radius, boolexpr filter returns nothing
  1. Если group==null, то filter не работает. Значит для вызова filter может быть нужна group.
  2. filter срабатывает только у юнитов, которые в радиусе. Значит проверка на радиус идет раньше.
  3. Проверки на радиус и filter происходят сразу перед добавлением в группу, или сначала собирается группа юнитов в радиусе?
3.1 Если сначала собирается группа юнитов в радиусе, то filter -> false вызывает удаление и перестановки?
3.2 Если юнит добавляется в группу только после двух проверок, то где гарантии, что filter будет лучше для маленьких групп, до 10, до 50 юнитов?
28
для маленьких групп, до 10, до 50 юнитов?
вот для таких действий можно спокойно и в лупе делать
8
Можешь сделать эти переменные локальными - ничего не поменяется. Этот код всегда будет работать так, как ты его написал. Никаких зависимостей от внешних условий тут нет.
Вы карту даже не запускали, а я ведь её приложил. Там есть второй триггер, который не делает ничего, только меняет местами значения глобалок. И, в зависсимости от того включен он или нет, первый будет работать определенным образом, несмотря на то, что второй не делает ничего.
rsfghd:
что этот код вообще должен делать непонятно, ведь юнит даже не сможет кастануть абилку, сразу удалившись
Для меня это стало новостью, но если поставить время каста способности и точку каста в ноль даммик успеет кастануть до удаления, посмотрите карту
=(
2
rsfghd, это не мой код, это код фрога, я группу один раз не в периодическом таймере создаю и удаляю после всех выполненных группой действия.
16
чтобы чекнуть твою булэкспр игре нужно все равно создать поток на каждого подходящего юнита, а связный список всё равно чуть проще модерируется на разумных масштабах (до ~1000 юнитов)

игра собирает список юнитов, подходящих под условие дистанции/ректа (не знаю как конкретно, но вроде не просто перебором), и затем все подходящие пролезают в фильтр, если фильтр вернул единичку - юнита садят в группу.

а нет, через каждого юнита проходит и тех, кто в подходящих координатах, отправляет дальше
18
То есть:
Все юниты -> список юнитов в подходящих координатах -> для каждого выполнить условие -> если да, добавить в список-группу -> вернуть список-группу

DracoL1ch, спасибо
28
goodlyhero, посмотрел карту, тут скорее дело в кривом использовании кода, когда ты приказываешь юниту кастовать спелл он получает приказ и в это же время ты запускаешь другой триггер, который и перезаписывает значения, чтобы такого не было нужно удалять юнита перед приказом, в данном случае:
function Trig_REVENGE_Actions takes nothing returns nothing
    set u1 = GetTriggerUnit()
    set u2 = GetEventDamageSource()
    set u3 = CreateUnit(GetOwningPlayer(u1),'h000',GetUnitX(u2),GetUnitY(u2),0)
    call UnitAddAbility(u3,'A000')
    call UnitApplyTimedLife(u3,'BTLF',0.01)
    call IssueTargetOrder(u3,"thunderbolt",u2)
endfunction
и всё будет работать как нужно

нужно понимать в каких областях ты юзаешь глобалки
8
нужно понимать в каких областях ты юзаешь глобалки
Я про это же, куча нативок вызывают обработку разных событий и в них тоже может встретиться вызов какой-то твоей системы, которая использует твои глобалки, поэтому идея "одна глобальная группа на все" тем, что потенциально приведет к неприятной ошибке, которую вы вероятно не сразу заметите, а игрокам жизнь она будет портить, возможно, как в представленном примере, ощутимо, пусть это всего лишь демонстративный пример.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.