Передача аргументов в функции callback'ов
Воспользовался данным способом, но почему-то не работает.
  • герой сразу же проигрывает анимацию "stand" ( не работает callback на TimerStart( ) ).
» сам код
scope Whirlwind initializer Initialization



    globals
        private  constant  integer     SPELL_ID       =  'A00J'
    endglobals



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

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



    private function StopUnitAnimation_TimerCallback takes unit blademaster returns nothing
        call SetUnitAnimation( blademaster, "stand" )

        call DestroyTimerEx( GetExpiredTimer( ) )
    endfunction



    globals
        private  constant  boolean     ATTACK_FLAG    =  true
        private  constant  boolean     RANGED_FLAG    =  false
        private  constant  attacktype  ATTACK_TYPE    =  ATTACK_TYPE_HERO
        private  constant  damagetype  DAMAGE_TYPE    =  DAMAGE_TYPE_NORMAL
        private  constant  weapontype  WEAPON_TYPE    =  null
    endglobals



    private function DamageTarget_GroupCallback takes unit blademaster returns nothing
        local  unit  enumUnit  =  GetEnumUnit( )

        if IsUnitInRange( enumUnit, blademaster, 220.0 ) and IsUnitEnemy( enumUnit, GetOwningPlayer( blademaster ) ) and IsUnitAlive( enumUnit ) and ( not IsUnitType( enumUnit, UNIT_TYPE_STRUCTURE ) ) then
            call PlayerDamageTarget( GetOwningPlayer( blademaster ), enumUnit, GetUnitAttackDamage( blademaster ), ATTACK_FLAG, RANGED_FLAG, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE )
            call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnBirthMissile.mdl", enumUnit, "chest" ) )
        endif

        set enumUnit  =  null
    endfunction



    globals
        private  constant  group  tempGroup  =  CreateGroup( )
    endglobals


//# +nosemanticerror
    private function Start takes nothing returns nothing
        local  unit   blademaster  =  GetEventDamageSource( )

        call StartAbilityCooldown( blademaster, SPELL_ID, 0.75 )

        call SetUnitAnimation( blademaster, "spin" )
        call TimerStart( CreateTimerEx( ), 0.25, false, SetCodeOneArg( function StopUnitAnimation_TimerCallback, HAND, GetHandleId( blademaster ) ) )

        call GroupEnumUnitsInRange( tempGroup, GetUnitX( blademaster ), GetUnitY( blademaster ), ( 220.0 + MAX_COLLISION_SIZE ), null )
        call ForGroup( tempGroup, SetCodeOneArg( function DamageTarget_GroupCallback, HAND, GetHandleId( blademaster ) ) )
        call GroupClear( tempGroup )

        set blademaster  =  null
    endfunction



    private function Conditions takes nothing returns boolean
        local  unit      blademaster   =  GetEventDamageSource( )
        local  integer   level         =  GetUnitAbilityLevel( blademaster, SPELL_ID )

        local  boolean   condLevel     =  ( level > 0 )
        local  boolean   condCooldown  =  ( not IsAbilityOnCooldown( GetUnitAbility( blademaster, SPELL_ID ) ) )
        local  boolean   condChance    =  true // ( GetRandomInt( 1, 100 ) <= ( level * 5 + 30 ) )
        local  boolean   condEnemy     =  ( IsUnitEnemy( GetTriggerUnit( ), GetOwningPlayer( blademaster ) ) )

        set blademaster  =  null

        return ( condLevel ) and ( condCooldown ) and ( condChance ) and ( condEnemy )
    endfunction



    globals
        private  constant  trigger  trig  =  CreateTrigger( )
    endglobals



    private function Initialization takes nothing returns nothing
        call PreloadAbility( SPELL_ID )
        call PreloadEffect( "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnBirthMissile.mdl" )

        call TriggerRegisterAnyUnitDamaged( trig )
        call TriggerAddCondition( trig, Condition( function Conditions ) )
        call TriggerAddAction( trig, function Start )
    endfunction



endscope

Лучший ответ:
Проблема решена, причина была в моей криворукости.



Просмотров: 114

ScopteRectuS #1 - 1 неделю назад 0

Проблема решена, причина была в моей криворукости.
quq_CCCP #2 - 1 неделю назад 0
Ну как хоть наработка? Помогает?
ScopteRectuS #3 - 1 неделю назад 0
quq_CCCP, да, хорошая наработка! Вот только возникли 2 вопроса к ней:
  • Может ли данная наработка где-то дать сбой?
  • Так и не понял, как передавать аргументы в boolexpr'ы. Раньше я все boolexpr'ы сохранял в глобальные переменные при инициализации, а дальше использовал эти переменные. В этой же наработке нельзя так сделать, ввиду того, что этих аргументов нету во время инициализации. Приходится каждый раз создавать boolexpr'ы, но нужно ли их после этого удалять? Кэшируются ли подобные boolexpr'ы?
quq_CCCP #4 - 1 неделю назад 0
Ну на болекспрах я не проверял, на таймеры и группы работает.
Болекспры должны кешироватся.
Diaboliko #5 - 1 неделю назад (отредактировано ) 0
В этой же наработке нельзя так сделать, ввиду того, что этих аргументов нету во время инициализации. Приходится каждый раз создавать boolexpr'ы, но нужно ли их после этого удалять?
Что запрещает записывать значения в глобалки по мере возможности и потребности?
Сама глобалка едва ли занимает в памяти более 4 байт.
Хотя, учитывая что доступ к переменным у виртуальной машины реализован через поиск переменной по тексту - лучше использовать массивы булекспров.
ScopteRectuS #6 - 1 неделю назад 0
quq_CCCP, кажется, что не кешируется, данный код каждый раз выдает разные цифры:
	local  boolexpr  b  =  Condition( SetCodeOneArg( function DamageTarget_GroupCallback, HAND, GetHandleId( blademaster ) ) )
	call BJDebugMsg( I2S( GetHandleId( b ) ) )
))
quq_CCCP #7 - 1 неделю назад 0
ScopteRectuS, со счетчиком хендлов перепроверь.
IceFog #8 - 1 неделю назад (отредактировано ) 0
данный код каждый раз выдает разные цифры
Boolexpr'ы кэшируются, а вот результат функции SetCodeOneArg — нет.
Каждый её вызов создает абсолютно новую функцию.