Алгоритмы, Наработки и Способности
Способ реализации:
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
30
11 лет назад
Отредактирован Clamp
0
мы будет писать ивенты на всех всех мобов на карте даже когда герои небудут их бить
Эвенты пишутся 1 раз за игру, мастер кода.
дальнейшие твои сообщения будут удаляться в силу твоей некомпетентности.
0
37
11 лет назад
0
Faion, в чем разница ? Тот же форгруп, тот же евент демейдж.
0
30
11 лет назад
0
ScorpioT1000, у него эвент урона регистрируется только одному триггеру, остальные работают по изменению переменной.
Хотя в целом не лучше и не хуже.
В общем он типа понтанулся тем, что не надо фогруп делать каждому триггеру, ведь "ОНО В ДИНАМИКЕ ЗАЛАГАЕТ", лолд.
0
37
11 лет назад
0
А зачем вообще TriggerResgister ? сделайте класс, наследуйтесь от него и передавайте системе
0
30
11 лет назад
0
ScorpioT1000, ну я, например, слабый программист, поэтому сделал как проще и понятнее =)
0
37
11 лет назад
Отредактирован ScorpioT1000
0
Кароче вот метод отца:
code
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)
   
    
    interface IUnitDamageEventHandler
    {
        void OnDamage(unit from, unit to, real amount)
    }
    
    private IUnitDamageEventHandler array handlerStack
    private int handlerStackCount = 0
    
    void RegisterUnitDamageEvent(IUnitDamageEventHandler handler)
    {
        handlerStack[handlerStackCount] = handler
        handlerStackCount++
    }

    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()
        {
            int i=0
            whilenot(i >= handlerStackCount) {
                handlerStack[i].OnDamage(GetEventDamageSource(),GetTriggerUnit(),GetEventDamage())
                ++i
            }
        });
    }
}
Пример:
library UnitDamageEventTest uses UnitDamageEvent
{

// простой пример
    struct myUnitDamageEventHandlerSimple extends IUnitDamageEventHandler
    {
        void OnDamage(unit from, unit to, real amount) {
            // ваш код по дамагу
        }
    }

// пример посложнее
    struct myUnitDamageEventHandler extends IUnitDamageEventHandler
    {
        int myData1
        real myData2
        
        static myUnitDamageEventHandler New(int _myData1, real _myData2) {
            thistype h = thistype.create()
            myData1 = _myData1
            myData2 = _myData2
            return h
        }
        
        void OnDamage(unit from, unit to, real amount) {
            // ваш код по дамагу
            BJDebugMsg(I2S(myData1) + " " + R2S(myData2))
        }
    }

// просто
    void somefunc1()
    {
        myUnitDamageEventHandlerSimple myHandler1 = myUnitDamageEventHandlerSimple.create()
        RegisterUnitDamageEvent(myHandler1)
    }

// посложнее
    void somefunc2()
    {
        RegisterUnitDamageEvent( myUnitDamageEventHandler.New(1, 2.0) )
        RegisterUnitDamageEvent( myUnitDamageEventHandler.New(100500, 123456.789) )
    }
}
0
30
11 лет назад
0
ScorpioT1000, а теперь затести =)
0
37
11 лет назад
0
Мне лень
0
24
11 лет назад
Отредактирован Faion
0
А зачем вообще TriggerResgister ? сделайте класс, наследуйтесь от него и передавайте системе
Затем что у нас тут СОП, а не ООП.
Clamp:
Хотя в целом не лучше и не хуже.
Лол. Объясняю для особо одаренных, почему твой код - уг.
Берем из твоей либы:
AnyUnitDamagedEvent(trigger trg)
И регистрируем 100, опустим тот факт, что нефига не зарегистрируется, если на карте много юнитов, ну а далее, мы уничтожаем 99 триггеров(ты же не думал что они будут все статичными, лол).
И смотрим сюда:
private void Adder()
    {
        int i = 0
        loop
        {
            TriggerRegisterUnitEvent(Trigger[i],GetEnteringUnit(),EVENT_UNIT_DAMAGED)
            exitwhen i==TrigsNum
            i++
        }
        GroupAddUnit(Group,GetEnteringUnit())
    }
Лол. Конечно же моя система ничем не лучше :D
Для самых одаренных из одаренных поясняю, в твоей системе еще нужно писать метод для удаления твоей костыльной регистрации ._.
0
30
11 лет назад
Отредактирован Clamp
0
  1. события нельзя удалять
  2. каждое событие существует в единственном экземпляре и имеет ряд ссылок на завязанные на нём триггеры.
  3. количество ссылок на удалённые триггеры никаким образом не влияет на производительность карты и затрачиваемый ею объем оперативной памяти.
Вывод: нет никакой необходимости эти ссылки чистить.
Заметка: аргумент про перманентность событий для каждого динамичного триггера появился только что, а сообщил ты о нём так, как будто уже три дня только об этом и говоришь.
Дополнение: твоя регистрация не менее костыльная ввиду того, что у тебя тоже нельзя её удалить.
P.S.: дискуссия с тобой неприятна ввиду твоей речевой стилистики, низкой грамотности, открытого неуважения к оппоненту и того, что ты не скрываешь, что это неуважение вызвано самим фактом того, что он является твоим оппонентом. Также твоё общение выглядит так, будто ты страдаешь нарциссизмом, однако при этом готов вылизывать обувь людям, от которых зависишь, что является типичным признаком низкой самооценки и вызывает следствие в виде попыток самоутвердиться на тех, кто заведомо слабее тебя в теме дискуссии, и даже при этом ты умудряешься опускаться до переходов на личности и повторов отбитых аргументационных суждений.
P.P.S.: дальнейшие твои сообщения с речевыми конструкциями вида "твоё ... - убогое" или "моё ... лучше по факту того, что оно лучше" будут просто игнорироваться, а в случаях, где будет отсутствовать иное содержание - удаляться.

и да, на все динамичные спелы типа "юнит получит х2 от полученного урона" нормальные люди используют один единственный триггер.

я предупреждал, а за офтоп так ещё и пункты полагаются.
Этот комментарий удален
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.