Алгоритмы, Наработки и Способности
Способ реализации:
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
30
11 лет назад
Отредактирован Clamp
1
Ну, вообще там действительно нечему лагать =)
Кстати, версия без проблемы с условием:
Код*
library UnitDamaged initializer InitRect
{
    private region  Region
    private group   Group
    private int     TrigsNum = 0
    private trigger array Trigger
    
    private void Adder()
    {
        int i = 0
        loop
        {
            TriggerRegisterUnitEvent(Trigger[i],GetEnteringUnit(),EVENT_UNIT_DAMAGED)
            exitwhen i==TrigsNum
            i++
        }
        GroupAddUnit(Group,GetEnteringUnit())
    }
    
    private void Registrator()
    {
        TriggerRegisterUnitEvent(Trigger[TrigsNum],GetEnumUnit(),EVENT_UNIT_DAMAGED)
    }
    
    void AnyUnitDamagedEvent(trigger trg)
    {
        Trigger[TrigsNum]=trg
        ForGroup(Group,function Registrator)
        TrigsNum++
    }

    private void InitRect()
    {
        trigger trg = CreateTrigger()
        Group = CreateGroup()
        Region = CreateRegion()
        GroupEnumUnitsInRect(Group,bj_mapInitialPlayableArea,null)
        RegionAddRect(Region, bj_mapInitialPlayableArea)
        TriggerRegisterEnterRegion(trg,Region,null)
        TriggerAddAction(trg,function Adder)
    }
}

*не тестировал, но должно работать
0
24
11 лет назад
0
О ужс. Ладно, так и быть, приду с работы напишу по человечески.
0
30
11 лет назад
0
Нахрен не нужно.
ScorpioT1000:
наработка рядовая, хз зачем вы там срач устроили
Faion, успокойся, смысла во всём этом цирке никакого нету. Все системы состоятельны, и эта ничем не хуже любой другой на тему.
0
24
11 лет назад
0
Все системы состоятельны
твоя система подходит только для маленьких проектов. А если кто то додумается юзать это в большом проекте, то этот человек повесит себе проект.
Короче заканчивай ныть. Приду с работы, покажу как над писать, заодно как свои эвенты создавать.
0
30
11 лет назад
0
если кто то додумается юзать это в большом проекте, то этот человек повесит себе проект
Аргументация?
Ах, прости, я забыл, это не твоя сильная сторона, аргументировать своё мнение.
Мнение СВДНа о ней, который сказал, что она не имеет недостатков (версия с массивом триггеров) я ценю (почему бы? а, он не голословит) заметно больше твоего.
0
24
11 лет назад
Отредактирован Faion
0
Аргументация?
А что тут аргументировать, ты не думал что перебор пары тысяч юнитов может стать существенной нагрузкой для большой карты, в которой "параллельно" работают десятки других систем? А если последовательно десяток инитов? В видимо не думал, в прочем тебе простительно.
0
30
11 лет назад
0
перебор пары тысяч юнитов
даже если ты умудришься засрать свою карту таким количеством войск, то это не повлияет ни на что, ибо инициализация системы длиться секунду, после чего никакой нагрузки она не оказывает.
Ты мог бы и увидеть это в коде, имей хоть какой-нибудь запас интеллекта. Впрочем, тебе простительно.
0
24
11 лет назад
0
после чего никакой нагрузки она не оказывает.
А то что у тебя для каждой регистрации перебор всех юнитов(пускай и сохраненных в группе) это типа ок? ))
Я уже не говорю о том, что при появлении нового юнита на карте, ты запускаешь целый цикл, для того что бы регнуть для всех триггеров юнита.
Короче логика идиотская, все эвенты должны быть подписаны а один триггер, точка.
0
37
11 лет назад
0
Clamp, только в дгуи юзал около 800 элементов.
0
24
11 лет назад
0
Мнение СВДНа о ней, который сказал, что она не имеет недостатков
Скорее всего он просто не знает о той функции, через которую будет реализован эвент, т.к. функция вообще малоизвестная, как она работает знает еще меньше, а применение ей вовсе не нашли до сих пор.
0
30
11 лет назад
0
для каждой регистрации перебор всех юнитов
Один раз за всю игру эта регистрация проходит /о
запускаешь целый цикл, для того что бы регнуть для всех триггеров юнита
Лично у меня один триггер на все эти события, а здесь так написано как раз для того, чтобы система была максимально проста для использования. Цель публикации системы не в том, чтобы показать "ололо, я могу", а чтобы её могли использовать те, кто не в состоянии написать.
ScorpioT1000:
только в дгуи юзал около 800 элементов
Исключительный случай, можно просто влепить фильтр, т.к. регистрация урона им бесполезна.
0
24
11 лет назад
0
Один раз за всю игру эта регистрация проходит /о
А это что тогда по твоему? ._.
void AnyUnitDamagedEvent(trigger trg)
    {
        Trigger[TrigsNum]=trg
        ForGroup(Group,function Registrator)
        TrigsNum++
    }
а чтобы её могли использовать те, кто не в состоянии написать.
Не волнуйся, мой вариант еще проще, и в нем даже кода меньше будет :) Не будет никаких переборов кроме инита и тд.
1
37
11 лет назад
1
  1. берешь файона
  2. добавляешь его код к себе
  3. дописываешь его к авторам
  4. ??????
  5. встречаешь маму
Ну тоесть суть была в том чтобы на событие "юнит атакован" делать то же самое
это в 2004 году еще было
0
24
11 лет назад
0
ScorpioT1000, ну мой вброс будет концептуально отличаться от того что имеется на данный момент :)
0
22
11 лет назад
Отредактирован Clamp
0
Не очень система. Та что была создана Скорпом лучше.
0
30
11 лет назад
0
А это что тогда по твоему?
Это триггер в базу пишется, и для каждого триггера это место ровно один раз вызывается -__-
ScorpioT1000:
на событие "юнит атакован" делать то же самое
Я помню, там ещё таймеры зачем-то создавались, чтобы удалить юнита из подборки D:
Bornikkeny:
Та что была создана Скорпом лучше
ссылку же

в целом я запарился, изображай из себя гения дальше, чо :3
0
24
11 лет назад
0
Это триггер в базу пишется, и для каждого триггера это место ровно один раз вызывается -__-
Кэп?
в целом я запарился, изображай из себя гения дальше, чо :3
:facepalm:
Зачем мне изображать? Я просто опишу напишу аналог твоей системы, который будет лучше, и все.
0
37
11 лет назад
0
Bornikkeny, ты не ошибся?
Я помню, там ещё таймеры зачем-то создавались, чтобы удалить юнита из подборки D:
Да, чтобы после этого анрегать эвент, видимо, проседало фпс. Надо почитать векса.
0
30
11 лет назад
0
Clamp:
Один раз за всю игру эта регистрация проходит /о
А это что тогда по твоему? ._.
код
Я тебе сказал "А", ты мне ответил "это не А, это Б", я ткнул, что "я сказал А", ты ответил "кэп?"

ScorpioT1000:
чтобы после этого анрегать эвент
ну вот, там обычно ставили 3 секунды, и если с момента атаки проходило больше - урон не регистрировался. Урон от способностей, где в поле boolean attack стояло "false", также не учитывался.
0
24
11 лет назад
Отредактирован Clamp
0
Я тебе сказал "А", ты мне ответил "это не А, это Б", я ткнул, что "я сказал А", ты ответил "кэп?"
Хватит строить из себя идиота. Ты прекрасно понял что я о:
ForGroup(Group,function Registrator)
0
30
11 лет назад
0
ForGroup(Group,function Registrator)
Один раз для каждого триггера. Мимо.
0
24
11 лет назад
0
Clamp, я в курсе что один раз, для каждого триггера ._. Только ты реально думаешь, что перебор и обвес эвентами пачек юнитов при каждом ините это ок?
3
33
11 лет назад
3
Faion, если работает, в чём проблема? Ты тестил, или споришь о сферическом коне в вакууме?
0
30
11 лет назад
0
уф.
1 юнит - 1 ивент.
Каждый юнит на карте должен иметь этот ивент (за явными исключениями вроде ДГУИ) для полноценной работы системы. Так или иначе, тебе придётся пройтись по каждому юниту, чтобы каждый получил этот ивент. Ты не можешь создать свою переменную типа "event", нету нативных функций для этого.
Советую закончить этот спор, ты ведёшь его очень слабо, предоставляя аргументы по принципу "новое - хорошо забытое старое". Количество триггеров, которые работают с этим событием - это только выбор создателя карты. У меня все способности на одном, а счётчики для кое каких систем - на другом. Итого их два, и мне норм.
Кет:
споришь о сферическом коне в вакууме
Порноактёры меряются длинной МПХ, но Файону здесь не повезло, и он пытается хоть в чём-нибудь выпендриться.
0
24
11 лет назад
0
Кет:
Faion, если работает, в чём проблема? Ты тестил, или споришь о сферическом коне в вакууме?
Работает или не работает в данном случае не обсуждается, ибо к работоспособности нет никаких претензий. Но есть серьезная претензия к логике, мой перфекционизм не позволяет игнорировать данный случай, ибо сейчас не 2002, когда можно было делать "лишь бы работало", сейчас критично важно писать высокопроизводительные библиотеки(к коим данная не относится из за логики).
Так или иначе, тебе придётся пройтись по каждому юниту, чтобы каждый получил этот ивент.
Совершенно верно, ОДНАКО, проход будет 1, который будет происходить во время инита, вместе со всеми системами, причем для любого количества триггеров(в т.ч. подписанных на данный эвент уже после инита и перебора).
Ты не можешь создать свою переменную типа "event", нету нативных функций для этого.
Переменную типа эвент, действительно не могу, она будет другого типа, но будет работать как эвент, нативная функция для этого есть, просто ты ее не знаешь.
Итого, независимо от количества триггеров, будет 1 проход, для всех n триггеров.
но Файону здесь не повезло, и он пытается хоть в чём-нибудь выпендриться.
Файон ничего не пытается, Файон придет с работы, напишет то о чем он написал и опубликует. А вот чего добивается Кламп своими пмсными выходками мне не ясно если честно.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.