Почему-то фаталит карта. Причину не могу сказать, даже примерно.
логи прилагаются:

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

ScopteRectuS, нет, таймед лайф это своего рода бафф, он сам следит есть ли юнит. Если юнит сдохнет бафф самовыпилится самостоятельно, так что нет. Смотри баффы иллюзий и волков, они не проигрывают анимации смерти. Подбираешь бафф и все, анимации смерти невидно.
Хайдить тоже можно, под хайдом юнит нормально умирает и разлагается.

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
2
32
6 лет назад
2
ScopteRectuS, а вручить сразу то не судьба?
Это вовсе странно нахрена делать в коде то что, изи делается в РО?
0
21
6 лет назад
0
quq_CCCP, не могу так сделать. на самом деле мой даммик - это тот же самый герой, я не стал создавать нового юнита, а использую модель героя также и для даммика, вручая ему москитов и т.д.
2
32
6 лет назад
2
ScopteRectuS, а зачем тебе создавать героя ? Делать нефиг? Если это только анимация, создавай модель и проигрывай ей анимацию мемхаком или делай даммика с моделью героя, создание довольно ресурсозатрано если что.
0
21
6 лет назад
0
quq_CCCP, мемхак убрал с карты, а использовал героя только для того, чтобы не создавать новую боевую единицу, захламляя редактор объектов. Когда в редакторе становится много объектов становится сложно разбираться во всем этом. Ну и собственно, мой первый вопрос, мог ли этот даммик быть причиной фатала?
2
32
6 лет назад
2
ScopteRectuS, а вот хрен его знает, пытайся повторить фатал, бери героя, юзай его способности по кд, пока не фатальнет, пиши лог.
Тогда станет понятно наверняка.
2
16
6 лет назад
2
это могло быть что угодно, без ограничений. если у тебя нет 100% рабочего способа повторить фатал, ты причину хер найдешь
0
21
6 лет назад
Отредактирован scopterectus
0
DracoL1ch, 100% рабочего способа вызвать фатал у меня действительно нету. Но я нашел участок кода, при отключении которого, карта перестает критовать. Это был обычный триггер, который удалял юнита после его смерти, но сам этот триггер не критует, он начинает критовать только если герой прокачивает данный спелл.
spell
scope Omnislash



    globals

//      Ability rawcode.
        private    constant    integer       SPELL_ID            =    'A00K'

//      Dummy image rawcode.
        private    constant    integer       DUMMY_ID            =    'o000'

//      Timer's period.
        private    constant    real          FPS                 =    0.03125

//      Times between slashes.
        private    constant    real          BASE_ATTACK_TIME    =    0.375

        private    constant    real          ENEMY_SEARCH_RADIUS    =    600.0

//      Blademaster's attack range.
        private    constant    real          ATTACK_RANGE        =    100.0

//      Effect on dealing damage.
        private    constant    string        EFFECT_01           =    "Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageCaster.mdl"

//      Effect on weapon.
        private    constant    string        EFFECT_02           =    "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile_mini.mdl"

//      Is damage attack?
        private    constant    boolean       ATTACK_FLAG         =    true

//      Is damage ranged?
        private    constant    boolean       RANGED_FLAG         =    false

//      Attack type.
        private    constant    attacktype    ATTACK_TYPE         =    ATTACK_TYPE_HERO

//      Damage type.
        private    constant    damagetype    DAMAGE_TYPE         =    DAMAGE_TYPE_NORMAL

//      Weapon type.
        private    constant    weapontype    WEAPON_TYPE         =    WEAPON_TYPE_METAL_HEAVY_SLICE

    endglobals



    private function GetUnitAttackDamage takes unit blademaster returns integer
        local  integer  agility  =  GetHeroAgi( blademaster, true )
        local  integer  sides    =  3
        local  integer  dice     =  3

        return GetRandomInt( ( agility + dice ), ( agility + dice * sides ) )
    endfunction



    private function GetAnimationIndex takes nothing returns integer
        local integer i = GetRandomInt( 0, 2 )

        if ( i == 0 ) then
            return 2

        elseif ( i == 1 ) then
            return 3
        endif

        return 8
    endfunction



    struct omnislashdummy
        private        unit     dummy
        private        integer  alpha
        private        effect   fx

        private        thistype prev
        private        thistype next

        private static timer    period = CreateTimer( )



        private method destroy takes nothing returns nothing
            call DestroyEffect( this.fx )
            call RemoveUnit( this.dummy )

            set this.fx        = null
            set this.dummy     = null

            set this.prev.next = this.next
            set this.next.prev = this.prev

            if ( thistype(0).next == 0 ) then
                call PauseTimer( period )
            endif

            call thistype.deallocate( this )
        endmethod



        private static method iterate takes nothing returns nothing
            local thistype this    = thistype(0).next

            loop
                exitwhen ( this == 0 )

                if ( this.alpha <= 0 ) then
                   call this.destroy( )
                else
                    set this.alpha = this.alpha - 8
                    call SetUnitVertexColor( this.dummy, 255, 255, 255, IMaxBJ( this.alpha, 0 ) )
                endif

                set this = this.next
            endloop
        endmethod



        static method create takes unit target, unit caster returns thistype
            local thistype this = thistype.allocate( )
            local real     x    = GetUnitX( target ) + GetRandomReal( -ATTACK_RANGE, ATTACK_RANGE )
            local real     y    = GetUnitY( target ) + GetRandomReal( -ATTACK_RANGE, ATTACK_RANGE )
            local real     f    = bj_RADTODEG * Atan2(GetUnitY( target ) - y , GetUnitX( target ) - x )

            set this.next = thistype(0)
            set this.prev = thistype(0).prev
            set this.next.prev = this
            set this.prev.next = this

            set this.dummy = CreateUnit( GetOwningPlayer( caster ), DUMMY_ID, x, y, f )
            set this.fx    = AddSpecialEffectTarget( EFFECT_02, this.dummy, "weapon" )
            set this.alpha = 255

            call PauseUnit( this.dummy, true )
            call UnitAddAbility( this.dummy, 'Amrf' )
            call UnitRemoveAbility( this.dummy, 'Amrf' )
            call SetUnitFlyHeight( this.dummy, GetUnitFlyHeight( target ), 0.0 )
//          call UnitAddAbility( this.dummy, 'Aloc' )
//          call SetUnitInvulnerable( this.dummy, true )
            call SetUnitPathing( this.dummy, false )
            call SetUnitAnimationByIndex( this.dummy, GetAnimationIndex( ) )

            if ( this.prev == 0 ) then
                call TimerStart( period, FPS, true, function thistype.iterate )
            endif

            return this
        endmethod



    endstruct



    struct omnislash
        private        unit     caster
        private        unit     target
        private        effect   fx
        private        integer  slash
        private        real     bat
        private        real     range
        private        real     casterX
        private        real     casterY
        private        real     targetX
        private        real     targetY

        private        thistype prev
        private        thistype next

        private static group    group   = CreateGroup( )
        private static timer    period  = CreateTimer( )
        private static trigger  trigger = CreateTrigger( )



        private method destroy takes nothing returns nothing
            call DestroyEffect( this.fx )
            call PauseUnit( this.caster, false )
//          call SetUnitInvulnerable( this.caster, false )
            call SetUnitPathing( this.caster, true )
            call SetUnitTimeScale( this.caster, 100 * 0.01)
            call SetUnitVertexColor( this.caster, 255, 255, 255, 255 )
            call SetUnitFlyHeight( this.caster, 0.0, 0.0 )

            set this.caster = null
            set this.target = null
            set this.fx     = null

            set this.prev.next = this.next
            set this.next.prev = this.prev

            if ( thistype(0).next == 0 ) then
                call PauseTimer( period )
            endif

            call thistype.deallocate( this )
        endmethod



        private static method getParabolaZ takes real maxHeight, real maxRange, real currentRange returns real
            return ( 4 * maxHeight / maxRange ) * ( maxRange - currentRange ) * ( currentRange / maxRange )
        endmethod



        private method getRandomUnitFromGroup takes nothing returns unit
            call GroupEnumUnitsInRange( thistype.group, this.casterX, this.casterY, ENEMY_SEARCH_RADIUS, null )

            loop
                set bj_groupRandomConsidered  = 0
                set bj_groupRandomCurrentPick = null
                call ForGroup( thistype.group, function GroupPickRandomUnitEnum )
                exitwhen ( bj_groupRandomCurrentPick == null ) or ( IsUnitEnemy( bj_groupRandomCurrentPick, GetOwningPlayer( this.caster ) ) and IsUnitAlive( bj_groupRandomCurrentPick ) and ( not IsUnitType( bj_groupRandomCurrentPick, UNIT_TYPE_STRUCTURE ) ) )
                call GroupRemoveUnit( thistype.group, bj_groupRandomCurrentPick )
            endloop

            call GroupClear( thistype.group )
            return bj_groupRandomCurrentPick
        endmethod



        private static method iterate takes nothing returns nothing
            local thistype this    = thistype(0).next

            local real     range

            loop
                exitwhen ( this == 0 )

                if ( this.slash > 0 ) and IsUnitAlive( this.caster ) then
                    call SetUnitFacing( this.caster, ( bj_RADTODEG * Atan2( this.targetY - this.casterY, this.targetX - this.casterX ) ) )

                    if ( this.bat <= 0.0 ) then
                        set this.targetX = GetUnitX( this.target )
                        set this.targetY = GetUnitY( this.target )
                        set range = SquareRoot( ( this.targetX - this.casterX ) * ( this.targetX - this.casterX ) + ( this.targetY - this.casterY ) * ( this.targetY - this.casterY ) )

                        if ( range <= 120 ) then
                            set this.casterX = this.targetX + GetRandomReal( -ATTACK_RANGE, ATTACK_RANGE )
                            set this.casterY = this.targetY + GetRandomReal( -ATTACK_RANGE, ATTACK_RANGE )
                            call SetUnitX( this.caster, this.casterX )
                            call SetUnitY( this.caster, this.casterY )
                            call SetUnitFlyHeight( this.caster, 0.0, 0.0 )
                            call omnislashdummy.create( this.target, this.caster )
                            call SetUnitAnimationByIndex( this.caster, GetAnimationIndex( ) )
                            call DestroyEffect( AddSpecialEffectTarget( EFFECT_01, this.target, "origin" ) )
                            call UnitDamageTarget( this.caster, this.target, ( GetHeroAgi( this.caster, true ) + 25.0 ), ATTACK_FLAG, RANGED_FLAG, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE )
                            set this.bat = BASE_ATTACK_TIME

                            set this.target = this.getRandomUnitFromGroup( )
                            if ( this.target != null ) then
                                set this.slash    =  ( this.slash - 1 )
                                set this.targetX  =  GetUnitX( this.target )
                                set this.targetY  =  GetUnitY( this.target )
                                set this.range    =  SquareRoot( ( this.targetX - this.casterX ) * ( this.targetX - this.casterX ) + ( this.targetY - this.casterY ) * ( this.targetY - this.casterY ) )

                            else
                                call this.destroy( )
                            endif

                        else
                            set this.casterX = this.casterX + 60.0 * ( ( this.targetX - this.casterX ) / range )
                            set this.casterY = this.casterY + 60.0 * ( ( this.targetY - this.casterY ) / range )
                            call SetUnitX( this.caster, this.casterX )
                            call SetUnitY( this.caster, this.casterY )
                            call SetUnitFlyHeight( this.caster, thistype.getParabolaZ( 180.0, this.range, ( this.range - range ) ), 0.0 )
                        endif

                    else
                        set this.bat = this.bat - FPS
                    endif

                else
                    call this.destroy( )
                endif

                set this = this.next
            endloop
        endmethod



        private static method actions takes nothing returns nothing
            local eventid  id          = GetTriggerEventId( )
            local thistype this
            local unit     blademaster
            local unit     attacker

            if ( id  == EVENT_PLAYER_UNIT_ATTACKED ) then
                set blademaster = GetTriggerUnit( )
                set attacker    = GetAttacker( )

                call omnislashdummy.create( attacker, blademaster )
                call UnitDamageTarget( blademaster, attacker, GetUnitAttackDamage( blademaster ), ATTACK_FLAG, RANGED_FLAG, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE )

                set blademaster = null
                set attacker    = null

            elseif ( id == EVENT_PLAYER_UNIT_SPELL_EFFECT ) then
                set this = thistype.allocate( )

                set this.next      = thistype(0)
                set this.prev      = thistype(0).prev
                set this.next.prev = this
                set this.prev.next = this

                set this.caster    = GetSpellAbilityUnit( )
                set this.casterX   = GetUnitX( this.caster )
                set this.casterY   = GetUnitY( this.caster )
                set this.target    = GetSpellTargetUnit( )
                set this.targetX   = GetUnitX( this.target )
                set this.targetY   = GetUnitY( this.target )
                set this.fx        = AddSpecialEffectTarget( EFFECT_02, this.caster, "weapon" )
                set this.slash     = GetUnitAbilityLevel( this.caster, SPELL_ID ) * 2 + 10
                set this.bat       = 0.0
                set this.range     = SquareRoot( ( this.targetX - this.casterX ) * ( this.targetX - this.casterX ) + ( this.targetY - this.casterY ) * ( this.targetY - this.casterY ) )

                call UnitAddAbility( this.caster, 'Amrf' )
                call UnitRemoveAbility( this.caster, 'Amrf' )
                call PauseUnit( this.caster, true )
//              call SetUnitInvulnerable( this.caster, true )
                call SetUnitPathing( this.caster, false )
                call SetUnitTimeScale( this.caster, 250 * 0.01 )
                call SetUnitVertexColor( this.caster, 255, 255, 255, 100 )

                if ( this.prev == 0 ) then
                    call TimerStart( period, FPS, true, function thistype.iterate )
                endif
            endif

            set id = null
        endmethod



        private static method conditions takes nothing returns boolean
            local eventid eventId     = GetTriggerEventId( )
            local unit    blademaster = GetTriggerUnit( )
            local integer chance      = GetUnitAbilityLevel( blademaster, SPELL_ID ) * 6 + 10
            local boolean b           = false

            if ( eventId == EVENT_PLAYER_UNIT_ATTACKED ) then
                set b = ( GetUnitAbilityLevel( blademaster, SPELL_ID ) > 0 ) and ( GetRandomReal( 0.0, 100.0 ) <= chance )

            elseif ( eventId == EVENT_PLAYER_UNIT_SPELL_EFFECT ) then
                set b = ( GetSpellAbilityId( ) == SPELL_ID )
            endif

            set eventId     = null
            set blademaster = null

            return b
        endmethod



        private static method onInit takes nothing returns nothing
            call PreloadAbility( SPELL_ID )
            call PreloadUnit( DUMMY_ID )
            call PreloadEffect( EFFECT_01 )

            call TriggerRegisterAnyUnitEventBJ( thistype.trigger, EVENT_PLAYER_UNIT_ATTACKED )
            call TriggerRegisterAnyUnitEventBJ( thistype.trigger, EVENT_PLAYER_UNIT_SPELL_EFFECT )

            call TriggerAddCondition( thistype.trigger, Condition( function thistype.conditions ) )
            call TriggerAddAction( thistype.trigger, function thistype.actions )
        endmethod



    endstruct



endscope
также, если удалить этот триггер, удаляющий юнитов после смерти. А вместо него в редакторе констант выставить минимальные значения разложения трупа, то карта снова начинает критовать.

Но есть еще один маленький шанс, что, то, что я написал выше - ложь. Возможно, карта не критовала лишь потому что это так совпало с отключением выше указанного триггера. И данный триггер вовсе не является причиной фатала, как и сам спелл...))

P.S.: это Omnislash Juggernaut'a из доты, правда немного изменённый. Также, у данной способности есть пассивная составляющая - каждый раз, когда героя атакуют, имеется какой-то шанс, контратаковать атакующего (создается даммик, который проигрывает анимацию атаки и врагу наносится урон).
0
26
6 лет назад
0
так ты без этого кода попробуй убить этого юнита, или удалить, и посмотри что будет
2
16
6 лет назад
2
Ээээ.. А нахера ты юнита удаляешь вручную? И время разложения надо ставить хотя бы долю секунды. Не надо выполнять за движок его работу, он сам всё нормально сделает, RemoveUnit максимально небезопасна. Это объясняет отсутствие объекта хп
0
21
6 лет назад
0
DracoL1ch, причина удаления юнитов у меня странная, - мне не нравится трупы юнитов, которые везде валяются. Если юнитов нельзя удалять, то как мне спрятать юнита? Если спрятать юнита функцией ShowUnit(), удалится ли юнит после полного разложения его трупа? или же это функция может как-то воспрепятствовать удалению юнита движком игры?
0
32
6 лет назад
0
ScopteRectuS, TimedLife с баффом BTLF не не слышал?, при смерти рили можно хайдить, труп разложится как положено.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.