, Гильдия «Черамор»

Заклинание: Гнев Деревьев AOE

» опубликован
» Способ реализации: Zinc
» Тип: Способность

AOE реализация заклинания "Гнев деревьев"

MUI: да
Импорт: нет
Утечки: нет
Требования: JNGP
Для каждого игрока используется один даммик. Статистика "войск нанято" соответственно будет врать только на единицу.

Скриншоты

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

» Установка
  • скопировать триггер SpellEntanglingRootsAOE
  • скопировать юнита Dummy. Равкод u000
  • скопировать способности Гнев деревьев (герой), Гнев деревьев (дамми). Равкоды A000, A001
Если равкоды после копирования изменятся, то указать это в настройках:
    constant integer Range      = 300;      // Радиус поражения
    constant integer SpellHero  = 'A000';   // Способность для героя.
    constant integer SpellCast  = 'A001';   // Способность для дамми. В ней производится настройка всех параметров
    constant string SpellOrder  = "entanglingroots"; // Строка приказа для дамми способности
    
    constant integer DummyID    = 'u000';   // Равкод дамми кастера
    constant real DummyLifeTime = 0.1;      // Время жизни дамми кастера
  • Настройки маны и перезарядки производятся в способности Гнев деревьев (герой).
  • Настройки урона и длительности производятся в способности Гнев деревьев (дамми).
» Код заклинания
//! zinc
library SpellEntanglingRootsAOE {

    // Настройки заклинания
    constant integer Range      = 300;      // Радиус поражения
    constant integer SpellHero  = 'A000';   // Способность для героя.
    constant integer SpellCast  = 'A001';   // Способность для дамми. В ней производится настройка всех параметров
    constant string SpellOrder  = "entanglingroots"; // Строка приказа для дамми способности
    
    constant integer DummyID    = 'u000';   // Равкод дамми кастера
    constant real DummyLifeTime = 0.1;      // Время жизни дамми кастера
    
    // ВСЁ, ЧТО НИЖЕ, ПРАВИТЬ НА СВОЙ СТРАХ И РИСК!!!
    unit DummyUnit[];
    
    function DummyCastBuff(unit caster, unit target){
        integer pid = GetPlayerId(GetOwningPlayer(caster));
        
        if (GetUnitState(target, UNIT_STATE_LIFE) > 0.405){
            SetUnitX(DummyUnit[pid], GetUnitX(target));
            SetUnitY(DummyUnit[pid], GetUnitY(target));
            SetUnitAbilityLevel(DummyUnit[pid], SpellCast, GetUnitAbilityLevel(caster, SpellHero));
            IssueTargetOrder(DummyUnit[pid], SpellOrder, target);
        }
    }
    
    function onInit(){
        trigger t = CreateTrigger();
        integer i;
        
        for (0 <= i < bj_MAX_PLAYER_SLOTS) {
            DummyUnit[i] = CreateUnit(Player(i), DummyID, 0, 0, 0);
            UnitAddAbility(DummyUnit[i], SpellCast);
            TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null);
        }

        TriggerAddCondition(t, Condition( function() -> boolean { return SpellHero == GetSpellAbilityId(); }));
        TriggerAddAction(t, function(){
            location loc = GetSpellTargetLoc();
            real x = GetLocationX(loc);
            real y = GetLocationY(loc);
            group g = CreateGroup();
            unit u;
            
            GroupEnumUnitsInRange(g, x, y, Range, Condition(function() -> boolean {
                return 
                    GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0.405 &&
                    IsPlayerEnemy(GetOwningPlayer(GetTriggerUnit()), GetOwningPlayer(GetFilterUnit())) &&
                    !IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) &&
                    !IsUnitType(GetFilterUnit(), UNIT_TYPE_FLYING);
            }));
            
            while(true){
                u = FirstOfGroup(g);
                if (u == null) { break; }
                DummyCastBuff(GetTriggerUnit(), u);
                GroupRemoveUnit(g, u);
            }
            
            RemoveLocation(loc);
            DestroyGroup(g);
            loc = null; g = null;
        });

        t = null;
    }
}
//! endzinc


Просмотров: 1 872

» Лучшие комментарии


8gabriel8 #1 - 1 год назад 2   
А можно теперь сделать так, чтобы на экране статистики не было учтено из-за применения способности кучи нанятых юнитов? Но деньги, опыт и убийства опутанных врагов засчитывались бы игроку?
PT153 #2 - 1 год назад 0
8gabriel8:
А можно теперь сделать так, чтобы на экране статистики не было учтено из-за применения способности кучи нанятых юнитов? Но деньги, опыт и убийства опутанных врагов засчитывались бы игроку?
Можно попробовать через нейтрального игрока и нужные приказы, которые есть только на JASS.
NazarPunk #3 - 1 год назад (отредактировано ) 0
Можно попробовать через нейтрального игрока и нужные приказы, которые есть только на JASS.
Тогда опыт и деньги не засчитаютя. Можно конечно, кастовать от нейтрального, а урон наносить от кастера. Но кастер и умереть может.
Ещё появилась идея создать для каждого игрока только одного дамми и кастовать от его лица. Тогда статистика будет врать всего на единицу. А если таких заклинаний будет много, то ровно на их количество.
PT153 #4 - 1 год назад (отредактировано ) 0
Тогда опыт и деньги не засчитаютя.
Ты проверял? Я про приказы типа.
native IssueNeutralImmediateOrder       takes player forWhichPlayer, unit neutralStructure, string unitToBuild returns boolean
native IssueNeutralImmediateOrderById   takes player forWhichPlayer,unit neutralStructure, integer unitId returns boolean
native IssueNeutralPointOrder           takes player forWhichPlayer,unit neutralStructure, string unitToBuild, real x, real y returns boolean
native IssueNeutralPointOrderById       takes player forWhichPlayer,unit neutralStructure, integer unitId, real x, real y returns boolean
native IssueNeutralTargetOrder          takes player forWhichPlayer,unit neutralStructure, string unitToBuild, widget target returns boolean
native IssueNeutralTargetOrderById      takes player forWhichPlayer,unit neutralStructure, integer unitId, widget target returns boolean
По идее, всё должно достаться игроку, ведь каст делается для него.
NazarPunk #5 - 1 год назад (отредактировано ) 0
По идее, всё должно достаться игроку, ведь каст делается для него.
Проверил, походу движок думает иначе: кому юнит принадлежит, тому и золото за убийство. А если передать юнита игроку, то в "войск произведено" он засчитается. По хорошему, близы должны были не учитывать юнитов с москитами, так что ничего не поделаешь.
PT153 #6 - 1 год назад (отредактировано ) 0
Проверил, походу движок думает иначе: кому юнит принадлежит, тому и золото за убийство.
8gabriel8, тогда никак.
Способ с одним даммиком не подойдёт, потому что даммик не может одновременно делать несколько кастов.
NazarPunk #7 - 1 год назад 0
не может одновременно делать несколько кастов
Если он кастует за 0.0 секунд, то он все касты по очереди то сделает. Щас попробую.
PT153 #8 - 1 год назад (отредактировано ) 0
Если он кастует за 0.0 секунд, то он все касты по очереди то сделает.
Всегда есть задержка в несколько микросекунд для каста, даже если у юнита время каста и время отхода стоит на 0 (или спел игнорирует эти поля).
NazarPunk #9 - 1 год назад 3   
Всегда есть задержка в несколько микросекунд для каста
Я уже убедился, что мир не идеален. Остаётся надеяться, что в Reforged добавят возможность кастануть любое заклинание от любого юнита на любое расстояние и даммики сгинут в пучину забытых кошмаров.
PT153 #10 - 1 год назад 0
Остаётся надеяться, что в Reforged добавят возможность кастануть любое заклинание от любого юнита на любое расстояние и даммики сгинут в пучину забытых кошмаров.
Они общали ещё до анонса рефорджа добавить тип proxy, который принадлежит конкретному юниту, игнорирует кулдауны, дальность, а все награды получает юнит-хозяин.
NazarPunk #11 - 1 год назад 0
Они общали ещё до анонса рефорджа добавить тип proxy, который принадлежит конкретному юниту
Было бы круто)
IssueProxyTargetOrder(caster, target, abilityID, abilityLevel);
8gabriel8 #12 - 1 год назад 0
Это делается триггерным нанесением урона от лица героя.
NazarPunk #13 - 1 год назад 0
Это делается триггерным нанесением урона от лица героя.
Это понятно, только усложнять всё таймерами не особо хочется. Да и если герой ненароком умрёт может печалька быть.
ClotPh #14 - 1 год назад 0
уже который раз слышу про проблему, если умрет герой - а в чем она? мертвый спокойно может дамажить
ну вкрай можно проверку на мертвого поставить
8gabriel8 #15 - 1 год назад 0
NazarPunk:
Это делается триггерным нанесением урона от лица героя.
Это понятно, только усложнять всё таймерами не особо хочется. Да и если герой ненароком умрёт может печалька быть.
Зато так реально интереснее, чем на GUI
EHP_Sequence #16 - 1 год назад 0
Опыта герою все равно не дается.
NazarPunk #17 - 1 год назад 2   
Опыта герою все равно не дается.
В тестмапе герои 10го уровня, враги Нейтрально-врждебные, а настройки по умолчанию. Так конечно опыта не будет, поставьте горою 1й уровень и будет опыт.
EHP_Sequence #18 - 1 год назад 0
NazarPunk:
Опыта герою все равно не дается.
В тестмапе герои 10го уровня, враги Нейтрально-врждебные, а настройки по умолчанию. Так конечно опыта не будет, поставьте горою 1й уровень и будет опыт.
А, лол, все верно. Просто я поменял в игровых константах макс. уровень, а коэффициент для крипов поменять забыл.
ScopteRectuS #19 - 1 год назад 0
Если создать за нейтрального игрока, а в момент каста менять владельца, разве будет даммик учитываться в послематчевой статистике? Да и один юнит спокойно может кастовать множество заклинаний в цикле, если всё правильно настроить.
Так что, я считаю, что создавать по одному даммику на один каст - максимально неправильно.
PT153 #20 - 1 год назад 0
Да и один юнит спокойно может кастовать множество заклинаний в цикле, если всё правильно настроить.
Недавно убедились, что нет.
ScopteRectuS #21 - 1 год назад 0
PT153, в 1.26? Если вы мне не верите, то можете посмотреть библиотеку xecast от Vexorian'a. Там используется всего лишь один даммик на все моментальные касты, а на все ченнелинг касты создаются такие же даммики или берутся из стока, если таковые имеются. Дальше триггерно отлавливается момент завершения ченнелинг каста и даммик recycle'ится.
NazarPunk #22 - 1 год назад 0
то можете посмотреть библиотеку xecast от Vexorian'a.
Глянул, не один даммик там используется.
// xecast 0.9
private constant integer DUMMY_STACK_LIMIT    = 50
Да и один юнит спокойно может кастовать множество заклинаний в цикле
Не в цикле, а через таймер
call TimerStart(.T, .expiretime[0]-TimerGetElapsed(.gametime), false, function xecast.dorecycle)
ScopteRectuS #23 - 1 год назад 0
NazarPunk, не туда смотрели. Смотрите на реализацию применения instant ability (по-моему так называлась)
PT153 #24 - 1 год назад 0
даммик на все моментальные касты
Так у нас каст не мгновенный, а на цель.
И даже с мгновенным есть задержка в пару микросекунд, я замерял не так давно.
ScopteRectuS #25 - 1 год назад 5   
Вот пример
Каст на цель - это тоже мгновенный тип. Немгновенный - это буран, телепортация, поляна кел тузеда и т.д.
Прикрепленные файлы
PT153 #26 - 1 год назад (отредактировано ) 0
Каст на цель - это тоже мгновенный тип. Немгновенный - это буран, телепортация, поляна кел тузеда и т.д.
Спасибо большое, буду знать.
PT153:
И даже с мгновенным есть задержка в пару микросекунд, я замерял не так давно.
Тогда это подходить только для юнитов с моделью.
ScopteRectuS #27 - 1 год назад 2   
PT153, почему? Вмоей карте можете сменить модель на другую. Должно работать.
PT153 #28 - 1 год назад 0
Вмоей карте можете сменить модель на другую. Должно работать.
Работает.
Странно, если поставить таймер с события (начинает поддерживать/кастовать) и брать его значение в событии (начинает эффект способности), то иногда появляется задержка в 2 микросекунды.
NazarPunk #29 - 1 год назад 0
Смотрите на реализацию применения instant ability (по-моему так называлась)
Я смотрел на реализацию, а там прям в настроках
 public real    recycledelay = 0.0  //Please notice, some spells need a recycle delay
                                       // This is, a time period before they get recycle.
                                       // For example, some spells are not instant, there is
                                       // also the problem with damaging spells, this recycle
                                       // delay must be large enough to contain all the time
                                       // in which the spell can do damage.
Вот пример
Спасибо, завтра попробую реализовать заклинание с использовнием одного даммика на игрока.
ScopteRectuS #30 - 1 год назад 0
NazarPunk, зачем на каждого игрока? Создаете одного и используете его для всех игроков, каждый раз меняя владельца.
Или там урон начинает наноситься от другого игрока?
8gabriel8 #31 - 1 год назад 0
Сделай без дамиков игрока вообще, с кучей таймеров и возможностью использовать способность и как мгновенную, и как чаннелинг)
NazarPunk #32 - 1 год назад 0
зачем на каждого игрока?
Чтоб послематчевая статистика войск нанято врала на определённое число. А меняя владельца, мы на единицу увеличиваем войск нанято.
8gabriel8:
Сделай без дамиков игрока вообще
Проще даммикастом завязку бросить, чем реализовывать функционал. Из двух костылей, нужно выбирать помельче и без напильника))
8gabriel8:
возможностью использовать способность и как мгновенную, и как чаннелинг)
Это будет новый ресурс Заклинание: Гнев Деревьев Channel)
PT153 #33 - 1 год назад 0
Чтоб послематчевая статистика войск нанято врала на определённое число. А меняя владельца, мы на единицу увеличиваем войск нанято.
Это точно? Думаю, тоже стоит проверить.
NazarPunk #34 - 1 год назад (отредактировано ) 2   
Это точно? Думаю, тоже стоит проверить.
Проверено. Повыделяйте танчики и посмотрите в статистике "войск нанято".
Прикрепленные файлы
NazarPunk #35 - 1 год назад (отредактировано ) 0
Да и один юнит спокойно может кастовать множество заклинаний в цикле
Посыпаю голову пеплом. Один юнит может кастовать заклинание в цикле. Я тупо не убрал перезарядку и успешно не заметил свой косяк. Заклинание перезалито и теперь на каждого игрока создаётся только один даммик.
PT153 #36 - 1 год назад 0
Каст на цель - это тоже мгновенный тип.
Хм, а с Chain Lighting это не работает.
NazarPunk #37 - 1 год назад 0
Хм, а с Chain Lighting это не работает.
Не со всеми заклинаниям это подходит. С impale тоже такие проблемы.
ScopteRectuS #38 - 1 год назад 0
PT153, потому что Цепь молнии нельзя кастовать, если предыдущие молнии всё еще работают. Импале должен работать по идее.
NazarPunk #39 - 1 год назад 0
Импале должен работать по идее.
Я тут проверял, следующий impale прерывает предыдущий, пришлось даммиков плодить.
ScopteRectuS #40 - 1 год назад 0
NazarPunk, да, действительно не работает. Но я когда-то делал и всё работало.
ClotPh #41 - 1 год назад 0
Импейл вообще кривоватое заклинание. Его и в доте в итоге на триггеры перевели.