Алгоритмы, Наработки и Способности
Способ реализации:
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 триггеров
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
24
11 лет назад
0
Кет:
Faion, если работает, в чём проблема? Ты тестил, или споришь о сферическом коне в вакууме?
Работает или не работает в данном случае не обсуждается, ибо к работоспособности нет никаких претензий. Но есть серьезная претензия к логике, мой перфекционизм не позволяет игнорировать данный случай, ибо сейчас не 2002, когда можно было делать "лишь бы работало", сейчас критично важно писать высокопроизводительные библиотеки(к коим данная не относится из за логики).
Так или иначе, тебе придётся пройтись по каждому юниту, чтобы каждый получил этот ивент.
Совершенно верно, ОДНАКО, проход будет 1, который будет происходить во время инита, вместе со всеми системами, причем для любого количества триггеров(в т.ч. подписанных на данный эвент уже после инита и перебора).
Ты не можешь создать свою переменную типа "event", нету нативных функций для этого.
Переменную типа эвент, действительно не могу, она будет другого типа, но будет работать как эвент, нативная функция для этого есть, просто ты ее не знаешь.
Итого, независимо от количества триггеров, будет 1 проход, для всех n триггеров.
но Файону здесь не повезло, и он пытается хоть в чём-нибудь выпендриться.
Файон ничего не пытается, Файон придет с работы, напишет то о чем он написал и опубликует. А вот чего добивается Кламп своими пмсными выходками мне не ясно если честно.
0
30
11 лет назад
0
сейчас не 2002, когда можно было делать "лишь бы работало", сейчас критично важно писать высокопроизводительные библиотеки
железо 2002 года
железо 2013 года
Хо-ро-шо.
нативная функция для этого есть
Как же она называется? Ну-же!
0
24
11 лет назад
0
Как же она называется? Ну-же!
Напишу систему, увидишь собственными глазами не только как она называется, но и как ей пользоваться :)
0
37
11 лет назад
Отредактирован ScorpioT1000
0
TriggerRegisterPlayerUnitEvent ?
0
24
11 лет назад
0
ScorpioT1000, нет :)
Это не попсовая функция, я ж выше писал, о ней мало кто знает, и еще меньше людей знают как ее применять, и по факту до сих пор она нигде не применялась, ну или по крайней мере я не видел что б ее применяли.
Как и обещал:
тык
library UnitDamageEvent
{
    // источник урона
    public unit Source = null;
    // цель урона
    public unit Target = null;
    // урон
    // для регистрации эвента нанесения урона установите значение как -1.0
    // если вы хотите, что бы нулевой урон не вызывал эвент, то установите как 0.0
    #define private EventDamage = -1.0;
    public float Damage = EventDamage;
    
    private trigger EventTrigger = null;
    private trigger SystemTrigger = null;

    // отвечает за включение\отключение фильтрации юнитов
    #define private UnitFilterEnable = true;
    
    #if (UnitFilterEnable)
        public hashtable sysHashtable = InitHashtable();
    #endif
    
    // добавление\удаление типа юнита для фильтрации
    #define AddFilterUnitByTypeId(typeId) = SaveBoolean(UnitDamageEvent_sysHashtable, 0,typeId, true)
    #define RemoveFilterUnitByTypeId(typeId) = RemoveSavedBoolean(UnitDamageEvent_sysHashtable, 0,typeId)
    #define TriggerRegisterAnyUnitTakesDamage(t) = TriggerRegisterVariableEvent(t, "UnitDamageEvent_Damage", GREATER_THAN, EventDamage);

    callback onInit()
    {
        EventTrigger = CreateTrigger(); SystemTrigger = CreateTrigger();
        group g = CreateGroup();region r = null;unit u = null;
        GroupEnumUnitsInRect(g,bj_mapInitialPlayableArea,null);
        ForGroup(g, lambda void(){
            #if(UnitFilterEnable)
                if(LoadBoolean(UnitDamageEvent_sysHashtable, 0,GetUnitTypeId(GetEnumUnit()))){return;}
            #endif
            TriggerRegisterUnitEvent(EventTrigger,GetEnumUnit(),EVENT_UNIT_DAMAGED)
        });
        GroupClear(g);DestroyGroup(g);g = null;
        RegionAddRect(r, bj_mapInitialPlayableArea);
        TriggerRegisterEnterRegion(SystemTrigger,r,null); r = null;
        TriggerAddAction(SystemTrigger, lambda void(){
            #if(UnitFilterEnable)
                if(LoadBoolean(UnitDamageEvent_sysHashtable, 0,GetUnitTypeId(GetEnumUnit()))){return;}
            #endif
            TriggerRegisterUnitEvent(EventTrigger,GetEnteringUnit(),EVENT_UNIT_DAMAGED)
        });
        TriggerAddAction(EventTrigger, lambda void()
        {
            Source = GetEventDamageSource();Target = GetTriggerUnit();Damage = GetEventDamage();
            Source = null;Target = null;Damage = EventDamage
        });
    }
}


library UnitDamageEventTest uses UnitDamageEvent
{
    callback onInit()
    {
        trigger t = CreateTrigger();
        TriggerRegisterAnyUnitTakesDamage(t);
        TriggerAddAction(t, lambda void(){
            /* Ваш код */
        });
        t = null;
    }
}
0
30
11 лет назад
0
И после этого ты говоришь, что у меня слабая архитектура. Ridiculous.
Хотя идея неплохая как таковая, а функцию эту лично я активно использую для других целей.
0
24
11 лет назад
0
Clamp, лол, ну давай жги, что там не тру.
0
30
11 лет назад
0
Пф, я - не ты, чтобы срач ради факта разводить. Система, по крайней мере на первый взгляд, рабочая, хотя и несколько перегруженная, Косяков вроде множественных ссылок события на одного юнита нету, к чему париться?
Сам бы я её такую не использовал точно, но вполне мог бы заюзать идею про событие переменной. Единственная проблема здесь - я не смогу в вызываемой функции использовать GetEventDamageSource() и GetTriggerUnit(), но это больше косметическое, дело привычки. Хотя можно просто дефайном заменить define GetEventDamageSource() = Source, не убудет.
Может быть, её добавить в первый пост?)
0
24
11 лет назад
0
Пф, я - не ты, чтобы срач ради факта разводить.
По барабану. Раз говоришь что у меня "слабая" архитектура, то изволь как то подтвердить свои слова. Я уже свою точку зрения подтвердил своей альтернативной системой, которая полностью реализует то о чем я говорил.
хотя и несколько перегруженная
Чем ж она перегружена?) Анонимными функциями?) Или 2-мя проверками для фильтрации?) :)
Хотя можно просто дефайном заменить define GetEventDamageSource() = Source
Не стоит. Это сделано намеренно, ради совместимости с другими системами.
Может быть, её добавить в первый пост?)
Да как хочешь.
0
30
11 лет назад
0
Я уже свою точку зрения подтвердил своей альтернативной системой, которая полностью реализует то о чем я говорил.
Да ладно? "Твоя система говно, эта лучше" - плохой способ подтвердить.
Чем ж она перегружена?
Ты её как хм... ну в общем очень неаккуратно написал.
0
24
11 лет назад
0
Да ладно? "Твоя система говно, эта лучше" - плохой способ подтвердить.
По моему мой код сам за себя говорит. Думаю тут даже не о чем рассуждать и где лучше совершенно очевидно. Фильтрации есть, лишних действий нету. Тут максимум к чему можно придраться, так это выгрузке параметров в глобалки, и невозможность использование самих нативок. Что в принципе дело привычки, а в плане производительности совершенно не существенно. В твоей же системе совершенно неуклюжая инициализация. Ну и фильтацию твоя система не поддерживает.
Ты её как хм... ну в общем очень неаккуратно написал.
Лень было форматирование делать и комменты проставлять, писал на коленке, больше 15 минут тратить на такую лажу было лень.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.