Добавлен , опубликован
Способ реализации:
Версия Warcraft:

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

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
`
ОЖИДАНИЕ РЕКЛАМЫ...
33
Как бы это делается 1 строчкой на мемхаке, но весьма не плохо, такое 100% пригодится, как способ перезарядки в высших патчах
Такс вопрос, я не вдавался в подробности в код (не удобно с телефона), но по какому принципу идёт перезарядка? героя активирует подменный предмет? если да, то получется что на прервётся текущий приказ
30
о по какому принципу идёт перезарядка? героя активирует подменный предмет? если да, то получется что на прервётся текущий приказ
Замена предмета и UnitUseItem который работает коряво и сбивает приказ. Пробовал давать руну с абилкой, но это две лишние способности и хэндлы утекали.
Как бы это делается 1 строчкой на мемхаке
Хотел бы я увидеть эту волшебную строчку, но не спорю мемхак бы помог в отслеживании/установке кд.

Сейчас хочу сделать универсальную систему, посмотрю что получится.
32
Увы это работает криво, пока многие дефолтные абилки блочат инвентарь.
30
quq_CCCP:
Увы это работает криво, пока многие дефолтные абилки блочат инвентарь.
А какой есть выбор?
  • мемхак
  • не использовать блок инвентаря
  • не использовать эту систему
32
NazarPunk, эмм а как ты откажешься от ветров, заклинания крови, канала, и еще +100500 абилок которые скрывают юнита\героя. Дефолтные шипы неруба и то гадость... Хз почему близзарды не пофиксили именно эти проблемы.
30
quq_CCCP, значит остаётся писать универсальную систему и внутри 100500 проверок/костылей, чтобы всё работало)
33
Хотел бы я увидеть эту волшебную строчку, но не спорю мемхак бы помог в отслеживании/установке кд.
В моей карте про сларков 15 предметов и способностей имеют пассивную перезарядку не сбивающую приказ, но тема без мемхака тоже интересная, у нас есть эксгумация, которая запускает перезарядку у пассивки, и предмет из линки, пассивно перезапускает кд предмета (амулет защиты вроде)
NazarPunk:
Замена предмета и UnitUseItem который работает коряво и сбивает приказ. Пробовал давать руну с абилкой, но это две лишние способности и хэндлы утекали.
ааа так ты всё таки прожимал у героя героя, изначально без мемхак я думаю, что это должно выглдить так:
Дамми прожимает предмет, предмет героя удаляется, дамми передаёт предмет герою, и у героя стартует КД на предмете (но надо что-то в константах подкрутить чтобы передать кд, я точно не помню), потом таймер ждёт конца кд предмета, удаляет предмет, и снова возвращает пассивный
32
Bergi_Bear, эксгумация пассивный каст, сбивает инвизы к примеру...
33
quq_CCCP, так то да, не проверял, кстати спс по твоей же наводке предметы научился мемхаком перезапускать =_
30
но надо что-то в константах подкрутить чтобы передать кд
Если бы можно было передать кд, было бы вообще отлично.
Bergi_Bear:
В моей карте про сларков 15 предметов и способностей имеют пассивную перезарядку
хотел потестить, но видимо у меня варкрафт неправильный((
Загруженные файлы
32
нарушение при сохранении, судя по всему мх, если дело идет на патче 1.26.
33
NazarPunk, а ты запускал карту, даже вместе со мной, но не смог играть потому что проафкал 10 минут, а потом удивился чё, это крипы тебя сливают за 1 удар, и вышел... (но карта 100% рабочая и запускает везде где только можно (на айкапе/ирине/гарене), даже не смотря на мемхак)
А насчет передачи кд, мб я что-то путаю... но точно вроде это было возможно, надо только вспомнить как
26
Наверное, путаешь. Кд висит на инвентаре, а не предмете.
30
но карта 100% рабочая и запускает везде где только можно
Может в новой винде дело, сейчас переутановлю вар, попробую ещё раз.
Bergi_Bear:
проафкал 10 минут
Не проафкал, а не вкурил что куда нажимать.
33
Ладно если уж открыть не вариант моих сларков, то секрет такой
Функция StartUnitAbilityCD (unit,id) где в id указывает равкод способности внутри предмета, но у самого предмета не должна стоять галочка "можно использовать", тогда мемхак может запустить кд у такой способности а игрок нет
NazarPunk:
Не проафкал, а не вкурил что куда нажимать.
щас бы в двух кнопках не разобраться =)
30
тогда мемхак может запустить кд у такой способности а игрок нет
Если было бы в нативках, то сам бы использовал. Но из-за костыля с заменой предмета у меня бонусом получилась замена иконки и описания, чего просто так уже не сделаешь)
26
виджет лайф > .405 ............ серьёзно?
UnitAddItemToSlotById ........... чё правда серьёзно?!
hash...
zinc...
Для кого это вообще создавалось?
30
Для кого это вообще создавалось?
Ну так сделайте лучше на гуи без хэштаблиц))
26
NazarPunk, это можно сделать на гуи... без хэша...
...и без потери юнитом очереди приказов...
Поэтому и спрашивается - чем оно здесь лучше?

. . .
Сейчас бы ещё комменты минусовать... да?
11
NazarPunk, не сбивая приказ можно на основе какой нибудь Книги (типа Книга повышения Ловкости) сделать каст я хз :) варианты то есть :)
26
Не сбивая приказ можно вовсе не отдавая юниту приказов
Но тут нет разницы на чём именно делать
Чтобы оставить комментарий, пожалуйста, войдите на сайт.