Я немного не понял этот момент, скорее всего это отслеживает одиночный каст (ну типо по горячей клавише) "автокастной" абилки пока она не активирована? Если да , то у меня такое ощущение что это не работает. Или искать проблему во мне?

Принятый ответ

EviLInside, ну через приказ можно тоже отловить одиночное срабатывание. я не совсем понял, что у тебя изачально не получалось
Да как ты логические там не добавляй, всё равно будет система работать некорректно при определённых обстоятельствах.
Если хотя бы поставить рендж атаки под 1000 и скорость снарядов в 300
или
рендж атаки 1000+ и атаковать цель которая стоит на макс расстоянии, и потом выключить автокаст и сразу атаковать ту сразу ту которая стоит очень близко
Чем меньше скорость снарядов и чем больше рендж атаки, тем больше будут заметны косяки в работе, потому что надо отслеживать каждый снаряд, а как ты это сделаешь если ты их не создаёшь )
Разочарование короче )
`
ОЖИДАНИЕ РЕКЛАМЫ...
2
26
4 года назад
2
Каст абилки - это одно. Срабатывание эффекта стрел при атаке - это уже другой механизм.
Что конкретно ты пытаешься сделать? свои стрелы с особым эффектом? или просто пустышку-автокастовую для отлова атаки?
0
10
4 года назад
Отредактирован EviLInside
0
Это уже от части будет оффтоп но надеюсь кто то в курсе того что я опишу. На Hiveworkshop есть такая система DamageInterface от chopinski (могу ошибаться в правильности никнейма), мне она понравилась , но т.к я далеко не мастер в кодинге, может быть это рутинная системка для вас опытных ребят. Потихоньку ковыряюсь в ней , тем более что у него там есть концепты героев сделанные при использовании его же системы. Есть там сильвана, с автокаст абилкой. Не знаю баги это или невозможность сделать лучше. Сначало код
library BlackArrow requires DamageInterface, RegisterPlayerUnitEvent, Utilities, optional WitheringFire
/* ---------------------- Black Arrow v1.0 by Chopinski --------------------- */
// Credits:
//     Magtheridon96 - RegisterPlayerUnitEvent
//     AZ            - Black Arrow model
//     Darkfang      - Arcane Arrow icon
//     YourArthas    - Skeleton Models
/* ----------------------------------- END ---------------------------------- */

/* ------------------------------ CONFIGURABLES ----------------------------- */
    globals
        // The raw code of the Black Arrow ability
        public  constant integer BLACK_ARROW       = 'A00C'
        // The raw code of the Black Arrow Curse debuff
        public  constant integer BLACK_ARROW_CURSE = 'A00D'
        // The raw code of the melee unit
        private constant integer SKELETON_WARRIOR  = 'u000'
        // The raw code of the ranged unit
        private constant integer SKELETON_ARCHER   = 'n001'
        // The raw code of the Elite unit
        private constant integer SKELETON_ELITE    = 'n000'
        // The effect created when the skelton warrior spawns
        private constant string  RAISE_EFFECT      = "Abilities\\Spells\\Undead\\RaiseSkeletonWarrior\\RaiseSkeleton.mdl"
    endglobals

    // The curse duration
    public function GetCurseDuration takes integer level returns real
        return 10.
    endfunction

    // The damage bonus when Black Arrows is active
    private function GetBonusDamage takes unit u, integer level returns real
        return (5 + 5*level) + ((0.05*level)*GetHeroAgi(u, true))
    endfunction

    // The melee sketelon health amount
    private function GetSkeletonWarriorHealth takes integer level returns integer
        return 50*(level + 6)
    endfunction

    // The melee sketelon damage amount
    private function GetSkeletonWarriorDamage takes integer level returns integer
        return 5*(level + 3)
    endfunction

    // The ranged sketelon health amount
    private function GetSkeletonArcherHealth takes integer level returns integer
        return 50*(level + 3)
    endfunction

    // The ranged sketelon damage amount
    private function GetSkeletonArcherDamage takes integer level returns integer
        return 5*(level + 6)
    endfunction

    // The sketelon duration
    private function GetSkeletonDuration takes integer level returns real
        return 15.
    endfunction

    // The max amount of skeleton warriors a unit can have
    private function GetMaxSkeletonCount takes integer level returns integer
        return 11
    endfunction

    // The elite sketelon health amount
    private function GetEliteHealth takes integer level returns integer
        return 50*(level + 11)
    endfunction

    // The elite sketelon damage amount
    private function GetEliteDamage takes integer level returns integer
        return 5*(level + 11)
    endfunction

    // The elite sketelon duration
    private function GetEliteDuration takes integer level returns real
        return 60.
    endfunction

    // How long it takes to a unit to be able to spawn Elites again after it already has the max amount
    private function GetEliteCountReset takes integer level returns real
        return 30.
    endfunction

    // The Max amount of Elites a unit can have before going into cooldown
    private function GetMaxEliteCount takes integer level returns integer
        return 2
    endfunction

    /* --------------------------------- System --------------------------------- */
    struct BlackArrow
        private static integer array counter
        private static integer array elite
        private static integer array skeletons
        private static player        owner
        static boolean array         active

        timer   t
        integer idx

        private static method onPeriod takes nothing returns nothing
            local thistype this = GetTimerData(GetExpiredTimer())

            call ReleaseTimer(t)
            set elite[idx] = 0
            set t = null
            call deallocate()
        endmethod

        private static method onOrder takes nothing returns nothing
            local unit    source = GetOrderedUnit()
            //---------------------------------------------
            local integer id     = GetIssuedOrderId()
            local integer idx    = GetUnitUserData(source)
            //---------------------------------------------

            if id == 852174 or id == 852175 then
                set active[idx] = id == 852174
                static if LIBRARY_WitheringFire then
                    if GetUnitAbilityLevel(source, WitheringFire_WITHERING_FIRE) > 0 then
                        call WitheringFire.setMissileArt(source, active[idx])
                    endif
                endif
            endif

            set source = null
        endmethod

        static method onDamage takes nothing returns nothing
            local integer  level    = GetUnitAbilityLevel(DamageI.source, BLACK_ARROW)
            local integer  manaCost = BlzGetAbilityIntegerLevelField(BlzGetUnitAbility(DamageI.source, BLACK_ARROW), ABILITY_ILF_MANA_COST, level - 1)
            //----------------------------------------------
            local boolean  hasMana  = GetUnitState(DamageI.source, UNIT_STATE_MANA) > manaCost
            //----------------------------------------------
            local real     damage   = GetEventDamage()
            //----------------------------------------------
            local unit     u
            //----------------------------------------------
            local thistype this
            //----------------------------------------------

            if active[DamageI.sIdx] and DamageI.isEnemy and not DamageI.structure and hasMana and damage > 0 then
                set owner = DamageI.sourcePlayer

                call BlzSetEventDamage(damage + GetBonusDamage(DamageI.source, level))
                if DamageI.targetIsHero then
                    set counter[DamageI.sIdx] = counter[DamageI.sIdx] + 1

                    if counter[DamageI.sIdx] >= 5 then
                        set counter[DamageI.sIdx] = 0

                        if elite[DamageI.sIdx] < GetMaxEliteCount(level) then
                            set elite[DamageI.sIdx] = elite[DamageI.sIdx] + 1 
                            set u = CreateUnit(owner, SKELETON_ELITE, DamageI.targetX, DamageI.targetY, 0)

                            call BlzSetUnitMaxHP(u, GetEliteHealth(level))
                            call BlzSetUnitBaseDamage(u, GetEliteDamage(level), 0)
                            call SetUnitLifePercentBJ(u, 100)
                            call UnitApplyTimedLife(u, 'BTLF', GetEliteDuration(level))
                            call SetUnitAnimation(u, "Birth")
                            call DestroyEffect(AddSpecialEffectEx(RAISE_EFFECT, GetUnitX(u), GetUnitY(u), GetUnitFlyHeight(u), 2))
                            
                            if elite[DamageI.sIdx] == GetMaxEliteCount(level) then
                                set this = thistype.allocate()
                                set .t   = NewTimerEx(this)
                                set .idx = DamageI.sIdx
                                call TimerStart(.t, GetEliteCountReset(level), false, function thistype.onPeriod)
                            endif
                        endif
                    endif
                endif
                call UnitAddAbilityTimed(DamageI.target, BLACK_ARROW_CURSE, GetCurseDuration(level), true)
                call SetUnitAbilityLevel(DamageI.target, BLACK_ARROW_CURSE, level)
            endif

            set u = null
        endmethod

        private static method onDeath takes nothing returns nothing
            local unit    killed   = GetTriggerUnit()
            //---------------------------------------------
            local integer level    = GetUnitAbilityLevel(killed, BLACK_ARROW_CURSE)
            local integer idx      = GetPlayerId(owner)
            local integer id       = GetUnitTypeId(killed)
            //---------------------------------------------
            local boolean ranged   = IsUnitType(killed, UNIT_TYPE_RANGED_ATTACKER)
            local boolean skeleton = id == SKELETON_WARRIOR or id == SKELETON_ARCHER
            //---------------------------------------------
            local unit    u
            local real    x
            local real    y
            //---------------------------------------------

            if skeleton then
                set idx = GetPlayerId(GetOwningPlayer(killed))
                set skeletons[idx] = skeletons[idx] - 1
            elseif level > 0 and skeletons[idx] < GetMaxSkeletonCount(level) then
                set skeletons[idx] = skeletons[idx] + 1
                set x = GetUnitX(killed)
                set y = GetUnitY(killed)
                
                if ranged then
                    set u = CreateUnit(owner, SKELETON_ARCHER, x, y, 0)
                    call BlzSetUnitMaxHP(u, GetSkeletonArcherHealth(level))
                    call BlzSetUnitBaseDamage(u, GetSkeletonArcherDamage(level), 0)
                else
                    set u = CreateUnit(owner, SKELETON_WARRIOR, x, y, 0)
                    call BlzSetUnitMaxHP(u, GetSkeletonWarriorHealth(level))
                    call BlzSetUnitBaseDamage(u, GetSkeletonWarriorDamage(level), 0)
                endif
                
                call UnitApplyTimedLife(u, 'BTLF', GetSkeletonDuration(level))
                call SetUnitLifePercentBJ(u, 100)
                call SetUnitAnimation(u, "Birth")
                call DestroyEffect(AddSpecialEffectEx(RAISE_EFFECT, GetUnitX(u), GetUnitY(u), GetUnitFlyHeight(u), 1))
            endif

            set u      = null
            set killed = null
        endmethod   

        static method onInit takes nothing returns nothing
            call RegisterAttackDamageEvent(function thistype.onDamage)
            call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_DEATH, function thistype.onDeath)
            call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_ISSUED_ORDER, function thistype.onOrder)
        endmethod
    endstruct
endlibrary
Ну так вот. Она не работает если не активную просто горячей клавишей кидать . Так же если активировать в момент полёта уже выпущеной обычной стрелы , она долетев (обычная стрела) сделает эффект как будто была выпущена уже с автокастом. Это невозможность сделать лучше или он просто не довёл до ума абилку"

я пытался добавить что бы сделать с одиночного выстрела что бы работало вот такое :
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, function thistype.onOrderTarg)


        private static method onOrderTarg takes nothing returns nothing
            local unit    source = GetOrderedUnit()
            //---------------------------------------------
            local integer id     = GetIssuedOrderId()
            local integer idx    = GetUnitUserData(source)
            //---------------------------------------------

            if id == 852173  then
                set active[idx] = id == 852173  // Тут типо order c flamingarrowtarg
            endif

            set source = null
        endmethod
но очевидно я делаю что то не так походу
2
8
4 года назад
Отредактирован build
2
EviLInside, думаю, нужно использовать стандартную абилку с автокастом для проверки на ее бафф. Тогда и не будет проблем с отловом атаки. Еще как вариант (но тогда тоже не будет работать при хоткее) - при получении приказа на автокаст давать юниту орб, проверять уже его бафф.
2
32
4 года назад
2
Зачем вам это, у вас же не дота - где по балансу автокасты не должны мешать орбам?
Тут сложная реализация, помнится драколич долго бился чтобы сделать хускару стрелы из леденой брони, чтобы уж точно пахало как надо. Если система не под функционал рефаунда - то не удивительно, хрен ты без мемхака или детекта рефорджа сделаешь норм автокаст орбы, чтобы прямо как 1 в 1 близордовские но без орба.
2
26
4 года назад
2
EviLInside, ну если пофиг на совместимость орбов - можно тупо за счёт отлова урона с баффом от стрелы.
А вот если надо что бы всё работало вместе - нужно делать системку, у которой всё будет орбами на одной базе, тогда по-сути получится что орбов как бы и нет вовсе.
2
16
4 года назад
2
с ледяной броней больше геммороя, чем толку
спасибо мемхаку
2
32
4 года назад
2
DracoL1ch, ну а как сделал, поведай миру =)
2
22
4 года назад
Отредактирован PROSHELDOTU
2
А при чём тут каст
Отдать приказ это одно, каст абилки это другое
Отследить каст Огненных стрел, Чёрная стрела и Ледяные стрелы можно через SPELL CHANNEL, SPELL CAST, SPELL EFFECT, SPELL ENDCAST

Есть там сильвана, с автокаст абилкой. Не знаю баги это или невозможность сделать лучше. Сначало код
Ну так вот. Она не работает если не активную просто горячей клавишей кидать . Так же если активировать в момент полёта уже выпущеной обычной стрелы , она долетев (обычная стрела) сделает эффект как будто была выпущена уже с автокастом. Это невозможность сделать лучше или он просто не довёл до ума абилку"
Правильно, там же событие идёт на отлов приказа, а каст способности как отловить я написал выше )
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_ISSUED_ORDER, function thistype.onOrder)
Да я тоже хотел предложить кое-что, но в том случае так же была бы проблема с включение/выключением автокаста при полёте стрелы
Тут единственный вариант сделать идеально и как тебе надо это сделать кастомные снаряды стрел и атаки, а по другому только извращения
Это всё равно что пытаться на основе стандартной волны силы пытаться отловить столкновение ну или что-то типо того
0
10
4 года назад
Отредактирован EviLInside
0
Правильно, там же событие идёт на отлов приказа, а каст способности как отловить я написал выше )
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_ISSUED_ORDER, function thistype.onOrder)
Да я тоже хотел предложить кое-что, но в том случае так же была бы проблема с включение/выключением автокаста при полёте стрелы
Я почти сделал всё так как нужно через call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, function thistype.onOrderTarg) , и понял что flamingarrowtarg ID это как раз то что мне нужно для соло выстрела и это работает (о том что я спрашивал в начале темы), добавил логических что бы убрать проблемы при сменах цели (когда обычная автоатака летит и активируешь либо кидаешь таргетно способность, щас ещё поковыряюсь и скину код может кому то интересно будет [тем кто читал этот код абилки выше] может кто то подскажет что ещё можно сделать. И закрою тему, А так видимо да
Тут единственный вариант сделать идеально и как тебе надо это сделать кастомные снаряды стрел и атаки, а по другому только извращения
Это первое что пришло в голову для удобной работы с автокастами.

quq_CCCP:
Зачем вам это, у вас же не дота - где по балансу автокасты не должны мешать орбам?
Тут сложная реализация, помнится драколич долго бился чтобы сделать хускару стрелы из леденой брони, чтобы уж точно пахало как надо. Если система не под функционал рефаунда - то не удивительно, хрен ты без мемхака или детекта рефорджа сделаешь норм автокаст орбы, чтобы прямо как 1 в 1 близордовские но без орба.
Буду указывать версию игры всегда в вопросах в начале своих, мой косяк. Сижу в редакторе reforged. Зачем нужно что бы как у близов? не знаю, какой то перфекционист внутри меня хочет что бы было всё идеально что ли если возможно. И при любом желании для любой карты будь то нужен баланс или не нужен или просто для удобной игры я мог вставить это в карту. Мне нравиться сам процесс работы над картой или способностями и того как получается что то делать и работало без багов.
0
22
4 года назад
Отредактирован PROSHELDOTU
0
EviLInside, ну через приказ можно тоже отловить одиночное срабатывание. я не совсем понял, что у тебя изачально не получалось
Да как ты логические там не добавляй, всё равно будет система работать некорректно при определённых обстоятельствах.
Если хотя бы поставить рендж атаки под 1000 и скорость снарядов в 300
или
рендж атаки 1000+ и атаковать цель которая стоит на макс расстоянии, и потом выключить автокаст и сразу атаковать ту сразу ту которая стоит очень близко
Чем меньше скорость снарядов и чем больше рендж атаки, тем больше будут заметны косяки в работе, потому что надо отслеживать каждый снаряд, а как ты это сделаешь если ты их не создаёшь )
Разочарование короче )
Принятый ответ
Чтобы оставить комментарий, пожалуйста, войдите на сайт.