Алгоритмы, Наработки и Способности
Способ реализации:
cJass
Тип:
Наработка
Библиотека, которая позволяет добавлять общее событие "юнит получает урон":
cJass
library UnitDamaged initializer InitRect {
    #include "cj_types_priv.j"

    private group   allUnits;
    private region  mapArea;
    private trigger Trigger[];
    private int     TrigsNum = 0;

    private void unitDamagedEvent() {
        TriggerRegisterUnitEvent(Trigger[TrigsNum], GetEnumUnit(), EVENT_UNIT_DAMAGED);
    }

    void AnyUnitDamagedEvent(trigger toTrigger) {
        Trigger[TrigsNum] = toTrigger;
        ForGroup(allUnits, function unitDamagedEvent);
        TrigsNum++;
    }

    private void onUnitSpawn() {
        for (int i = 0; i < TrigsNum; i++) {
            TriggerRegisterUnitEvent(Trigger[i], GetEnteringUnit(), EVENT_UNIT_DAMAGED);
        }
        GroupAddUnit(allUnits, GetEnteringUnit());
    }

    private void onUnitDecay() {
        GroupRemoveUnit(allUnits, GetDecayingUnit());
    }

    private void InitRect() {
        trigger onSpawn = CreateTrigger();
        trigger onDecay = CreateTrigger();
        allUnits = CreateGroup();
        mapArea = CreateRegion();
        GroupEnumUnitsInRect(allUnits, GetWorldBounds(), null);
        RegionAddRect(mapArea, GetWorldBounds());
        TriggerRegisterEnterRegion(onSpawn, mapArea, null);
        for (int i = 0; i < bj_MAX_PLAYER_SLOTS; i++) {
            TriggerRegisterPlayerUnitEvent(onDecay, Player(i), EVENT_PLAYER_UNIT_DECAY, null);
        }
        TriggerAddAction(onSpawn, function onUnitSpawn);
        TriggerAddAction(onDecay, function onUnitDecay);
    }
}
vJass
library UnitDamaged initializer initRect
    globals
        private group   allUnits
        private region  mapArea
        private trigger Trigger[]
        private integer TrigsNum = 0
    endglobals

    private function unitDamagedEvent takes nothing returns nothing
        call TriggerRegisterUnitEvent(Trigger[TrigsNum], GetEnumUnit(), EVENT_UNIT_DAMAGED)
    endfunction

    function AnyUnitDamagedEvent takes trigger toTrigger returns nothing
        set Trigger[TrigsNum] = toTrigger
        call ForGroup(allUnits, function unitDamagedEvent)
        set TrigsNum = TrigsNum + 1
    endfunction

    private function onUnitSpawn takes nothing returns nothing
        local integer i = 0
        loop
            exitwhen (i == TrigsNum)
            call TriggerRegisterUnitEvent(Trigger[i], GetEnteringUnit(), EVENT_UNIT_DAMAGED)
            set i = i + 1
        endloop
        call GroupAddUnit(allUnits, GetEnteringUnit())
    endfunction

    private function onUnitDecay takes nothing returns nothing
        call GroupRemoveUnit(allUnits, GetDecayingUnit())
    endfunction

    private function initRect takes nothing returns nothing
        local integer i = 0
        local trigger onSpawn = CreateTrigger()
        local trigger onDecay = CreateTrigger()
        set allUnits = CreateGroup()
        set mapArea = CreateRegion()
        call GroupEnumUnitsInRect(allUnits, GetWorldBounds(), null)
        call RegionAddRect(mapArea, GetWorldBounds())
        call TriggerRegisterEnterRegion(onSpawn, mapArea, null)
        loop
            exitwhen (i == bj_MAX_PLAYER_SLOTS)
            call TriggerRegisterPlayerUnitEvent(onDecay, Player(i), EVENT_PLAYER_UNIT_DECAY, null)
            set i = i + 1
        endloop
        call TriggerAddAction(onSpawn, function onUnitSpawn)
        call TriggerAddAction(onDecay, function onUnitDecay)
    endfunction
endlibrary

Добавление события:
    call AnyUnitDamagedEvent(subscribingTrigger)

Источник урона (атаковавший юнит):
GetEventDamageSource()
Цель урона (атакованный юнит):
GetTriggerUnit() 
Величина нанесённого урона:
GetEventDamage()

Установка: скопировать в Нестандартный Код Карты, дальнейших действий не требуется.

Ограничения:
  • Нельзя использовать с динамичными триггерами
  • Нельзя использовать более, чем с JASS_MAX_ARRAY_SIZE триггеров
1
21
6 лет назад
Отредактирован Raised
1
Вот только это эвенты вешаются на триггеры, а не наоброт.
ok.
0
30
6 лет назад
Отредактирован Clamp
0
Вызов в Jass
trigger Trig = CreateTrigger()
TriggerRegisterUnitEvent(Trig, GetSomeUnit(), SOME_EVENT)
Можно интерпретировать примерно так:
trigger Trig = trigger.create();
Trig.registerUnitEvent(GetSomeUnit(), SOME_EVENT);
0
21
6 лет назад
Отредактирован Raised
0
В игровом цикле триггерится событие, запускающее бандл триггеров. Не важно как ты это интерпретируешь.
Для этого не нужна сущность триггера, что прекрасно видно из кода системы.
На выходе предназначение системы - все то же, то есть регать событие для для триггеров в одну строку. И ты игнорируешь тот факт что вешать на ивент тучу триггеров - заведомо ущербный подход, а если делать нормально, то твоя система нафиг не нужна.
3
30
6 лет назад
Отредактирован Clamp
3
если делать нормально, то твоя система не нужна
Отлично, делай "нормально" и не пользуйся моей системой.
Этот комментарий удален
0
21
5 лет назад
0
Ограничения:
Нельзя использовать с динамичными триггерами
Почему бы не убрать это ограничение? Легко же делается.
0
30
5 лет назад
0
ScopteRectuS, не то, чтобы мне хотелось возвращаться к этой наработке, но ты можешь сделать свой вариант и скинуть в личку, если всё ок, то обновлю ресурс и добавлю в соавторы.
Но имей в виду, что я против привлечения новых сущностей, система должна оставаться компактной и простой.
0
21
5 лет назад
0
Clamp, OK.
0
19
3 года назад
0
Извиняюсь за археологию. EVENT_PLAYER_UNIT_DECAY ловит событие, когда юнит начал разложение, а не закончил, это означает что для воскрешенных юнитов потеряется ивент?
0
27
3 года назад
0
KaneThaumaturge, в смысле потерялся? ивент срабатывает тогда, когда юнит начал разлагаться, поток не прервётся если воскресить его
1
30
3 года назад
Отредактирован Clamp
1
KaneThaumaturge, уже созданные эвенты получения урона этим юнитом никуда не денутся, но если после воскрешения на событие будет подписан новый триггер, то на урон по воскрешённому юниту он не подпишется. Группа allUnits используется только для создания события получения урона.
0
19
3 года назад
0
но если после воскрешения на событие будет подписан новый триггер, то на урон по воскрешённому юниту он не подпишется.
Да, это я уже понял, спасибо за уточнение.
1
37
3 года назад
1
Давайте продолжим девятилетний срач. Нужно добавить условие, что юнит не неуязвимый, чтоб не регать из систем типа DGUI
0
27
3 года назад
0
ScorpioT1000, неуязвимость может быть не постоянной
0
37
3 года назад
0
rsfghd, нужно сделать флаг в конфиге и уведомить об этом в документации
0
30
3 года назад
0
ScorpioT1000:
Давайте продолжим девятилетний срач. Нужно добавить условие, что юнит не неуязвимый, чтоб не регать из систем типа DGUI
Вот прикинь, нападут на тебя кнопки DGUI, ты отобьёшься, а урон не зарегется. Обидно будет!
0
37
3 года назад
0
Clamp, я помню когда джонни ковырял систему еще до релиза, у него был такой баг, что кнопки начинали нападать на героя, рофлы те ещё были
Чтобы оставить комментарий, пожалуйста, войдите на сайт.