Добавлен , опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
Zinc
Тип:
Способность
Версия Warcraft:
1.26+

Божественный щит

MUI: да
Импорт: нет
Требования: JNGP
Идея : Bergi_Bear
Описание: Пассивно активируется божественный щит всякий раз, когда здоровье героя падает ниже отметки в 10%. Перезарядка: 20, длительность: 5.

Скринншот

Технические подробности

Перенос в свою карту
Способности
  • 'Asds' Божественный щит (заклинание)
Предметы
  • 'Idsp' Божественный щит
  • 'Idsa' Божественный щит
Триггеры
  • ItemDivineShield
Настройки
constant integer ITEM_ACTIVE = 'Idsa'; // Активный предмет
constant integer ITEM_PASSIVE = 'Idsp'; // Пассивный предмет
constant real ITEM_ABILITY_COOLDOWN = 20; // Перезарядка способности предмета

trigger DAMAGE_DETECT_TRIGGER = CreateTrigger(); // Не трогать
region MAP_REGION;  // Не трогать

hashtable HT = InitHashtable(); // Хэштаблица, можете вписать туда вашу, например:
// hashtable HT = udg_HashTable;
Код заклинания
// !nocjass
//! zinc
library ItemDivineShield {
    
    constant integer ITEM_ACTIVE = 'Idsa'; // Активный предмет
    constant integer ITEM_PASSIVE = 'Idsp'; // Пассивный предмет
    constant real ITEM_ABILITY_COOLDOWN = 20; // Перезарядка способности предмета

    trigger DAMAGE_DETECT_TRIGGER = CreateTrigger(); // Не трогать
    region MAP_REGION;  // Не трогать
    
    hashtable HT = InitHashtable(); // Хэштаблица, можете вписать туда вашу, например:
    // hashtable HT = udg_HashTable;
    
    
    /*
    *
    *
    *
    *
    *
    */
    
    function isUnitAlive(unit target) -> boolean {
        return GetWidgetLife(target) > 0.405;
    }
    
    function itemReplaceInstantly(unit u, integer from, integer to){
        integer i, slot[], slotI = -1;
        item it;
        for(0 <= i < bj_MAX_INVENTORY){
            it = UnitItemInSlot(u, i);
            if (GetItemTypeId(it) == from){
                RemoveItem(it);
                slotI = slotI + 1;
                slot[slotI] = i;
            }
        }
        for(0 <= i <= slotI){
            UnitAddItemToSlotById(u, to, slot[i]);
        }
        it = null;
    }
    
    function itemReplaceDelayed(unit u, integer from, integer to){
        timer t = CreateTimer();
        integer pk = GetHandleId(t);
        SaveUnitHandle(HT, pk, 0, u);
        SaveInteger(HT, pk, 0, from);
        SaveInteger(HT, pk, 1, to);
        TimerStart(t, 0.03125, true, function(){
            timer t = GetExpiredTimer();
            integer pk = GetHandleId(t);
            unit u = LoadUnitHandle(HT, pk, 0);
            if (isUnitAlive(u)){
                itemReplaceInstantly(u, LoadInteger(HT, pk, 0), LoadInteger(HT, pk, 1));
                FlushChildHashtable(HT, pk);
                PauseTimer(t); DestroyTimer(t);
            }
            u = null;
            t = null;
        });
        t = null;
    }
    
    function itemReplace(unit u, integer from, integer to){
        if (isUnitAlive(u)){
            itemReplaceInstantly(u, from, to);
        } else {
            itemReplaceDelayed(u, from, to);
        }
    }
    
    function itemCount(unit u, integer c) -> integer {
        integer i, count = 0;
        item it;
        for(0 <= i < bj_MAX_INVENTORY){
            it = UnitItemInSlot(u, i);
            if(GetItemTypeId(it) == c){
                count = count + 1;
            }
        }
        it = null;
        return count;
    }

    function addUnitToDetect() -> boolean {
        unit u = GetFilterUnit();
        if (IsUnitType(u, UNIT_TYPE_HERO)){
            TriggerRegisterUnitEvent(DAMAGE_DETECT_TRIGGER, u, EVENT_UNIT_DAMAGED);
        }
        u = null;
        return false;
    }
    
    function onInit(){
        trigger t[];
        integer i;
        group g = CreateGroup();
        
        for(0 <= i <= 2){ t[i] = CreateTrigger(); }
        
        MAP_REGION = CreateRegion();
        RegionAddRect(MAP_REGION, bj_mapInitialPlayableArea);
        
        t[0] = CreateTrigger();
        TriggerRegisterEnterRegion(t[0], MAP_REGION, null);
        TriggerAddCondition(t[0], function addUnitToDetect);
        
        GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, function addUnitToDetect);
        GroupClear(g); DestroyGroup(g); g = null;
        
        TriggerAddCondition(DAMAGE_DETECT_TRIGGER, Condition(function() -> boolean {
            unit u = GetTriggerUnit();
            item it;
            integer i, pk;
            real dmg = GetEventDamage();
            timer t;
            if (
                dmg > 0
                &&
                GetUnitCurrentOrder(u) != 851973
                &&
                itemCount(u, ITEM_PASSIVE) > 0
                &&
                GetWidgetLife(u) - dmg <= GetUnitState(u, UNIT_STATE_MAX_LIFE) * 0.1
            ){                
                itemReplace(u, ITEM_PASSIVE, ITEM_ACTIVE);
                for(0 <= i < bj_MAX_INVENTORY){
                    it = UnitItemInSlot(u, i);
                    if(GetItemTypeId(it) == ITEM_ACTIVE){
                        UnitUseItem(u, it);
                        break;
                    }
                }
                
                t = CreateTimer();
                pk = GetHandleId(t);
                SaveUnitHandle(HT, pk, 0, u);
                TimerStart(t, ITEM_ABILITY_COOLDOWN - 0.01, false, function(){
                    timer t = GetExpiredTimer();
                    integer pk = GetHandleId(t);
                    unit u = LoadUnitHandle(HT, pk, 0);
                    itemReplace(u, ITEM_ACTIVE, ITEM_PASSIVE);
                    u = null;
                    FlushChildHashtable(HT, pk);
                    PauseTimer(t); DestroyTimer(t); t = null;
                });
            }
            
            u = null;
            it = null;
            t = null;
            return false;
        }));
        
        for(0 <= i < bj_MAX_PLAYER_SLOTS){
            TriggerRegisterPlayerUnitEvent(t[1], Player(i), EVENT_PLAYER_UNIT_PICKUP_ITEM, null);
            TriggerRegisterPlayerUnitEvent(t[2], Player(i), EVENT_PLAYER_UNIT_DEATH, null);
        }
        TriggerAddCondition(t[1], Condition(function() -> boolean {
            unit u = GetTriggerUnit();
            item it = GetManipulatedItem();
            
            if (GetItemTypeId(it) == ITEM_PASSIVE && itemCount(u, ITEM_ACTIVE) > 0){
                itemReplace(u, ITEM_PASSIVE, ITEM_ACTIVE);
            }
            u = null;
            it = null;
            return false;
        }));
        TriggerAddCondition(t[2], Condition(function() -> boolean {
            unit u = GetTriggerUnit();
            if (itemCount(u, ITEM_ACTIVE) > 0){
                itemReplace(u, ITEM_ACTIVE, ITEM_PASSIVE);
            }
            u = null;
            return false;
        }));
        
        for(0 <= i <= 2){t[i] = null;}
    }
}
//! endzinc
// !endnocjass
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
28
5 лет назад
Отредактирован PT153
0
Ты ничего не путаешь? Или ты специально вводишь всех в заблуждение?
Открываем common.ai и смотрим. Чтобы использовать в обычных картах, её нужно определить после блока глобалок. Если есть vJass, то в любом удобном месте.
Речь о том что юнит мёртв, а игра сообщает обратное. И это так.
В момент перед получением урона (то есть пока триггер на получение урона работает) он ещё считается живым.

И я так и не понял самые первые придирки к реализации, они же ни о чём. Был бы полный комментарий, как сделать лучше, то и разговор был бы другой.
0
29
5 лет назад
0
Ну покажи где она
Несколькими постами выше я её использовал и даже карту приложил.
Ещё можете поискать в common.ai.
Загруженные файлы
0
28
5 лет назад
Отредактирован PT153
0
Лично я предлагаю сделать так: делаем предмет со способностью на основе спеллшилда. Если урон не смертельный, то удаляем предмет и даём новый (чтобы кд обнулить). Если урон смертельный и кд нет, то даём руну. Наличие кд можно проверять с помощью таймера+хеш, при каждом срабатывании стартуем таймер (главное, на паузу его не ставить).
0
26
5 лет назад
0
NazarPunk:
поискать в common.ai
Аа, ну так это же аишка
0
29
5 лет назад
Отредактирован nazarpunk
0
то даём руну
и будет:
Способности
  • Божественный щит (заклинание)
  • Божественный щит (кд)
Предметы
  • Божественный щит (без кд)
  • Божественный щит (с кд)
  • Божественный щит (руна)

Аа, ну так это же аишка
И что с этого?
0
26
5 лет назад
0
NazarPunk:
И что с этого?
То, что нужно качать другой WE
Либо ковырять скрипт руками
2
29
5 лет назад
2
То, что нужно качать другой WE
Это так сложно. Притом в шапке:
  • Версия Warcraft: 1.26
  • Требования: JNGP

А вашу версию на гуи, лишённую всех недостатков, я так и не увидел.
0
28
5 лет назад
Отредактирован PT153
0
Либо ковырять скрипт руками
Я же сказал тебе (страница 1), как использовать эту функцию, не смотря на то, что она в common.ai. Ничего качать не надо.
Даже JNGP необязателен, достаточно иметь JassHelper и уметь им пользоваться.
Загруженные файлы
0
1
3 года назад
0
не работает)
0
17
3 года назад
0
Классный предмет. Щит... Да еще и божественный
0
48
3 года назад
0
SweetFox:
Назар может позже разберется
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.