scope StormHammer

    globals
        public    constant    integer      ABILITY_ID                             =    'A019'
        public    constant    integer      THUNDERCLAP_ID                         =    'A00K'
        public    constant    string       THUNDERCLAP_ORDER                      =    "thunderclap"
        public    constant    string       EFFECT_PATH                            =    "Abilities\\Spells\\Human\\Thunderclap\\ThunderClapCaster.mdl"
        public    constant    string       LIGHTNING_NAME                         =    "CLPB"
        public    constant    real         LIGHTNING_HEIGHT                       =    9900.0
        public    constant    real         LIGHTNING_LIFE_TIME                    =    0.1
    endglobals

    globals
        public    constant    group       enumUnits           =    CreateGroup()
        public                boolexpr    boolexprForGroup    =    null
    endglobals

    public function Conditions takes nothing returns boolean
        local integer abilityLevel    = GetUnitAbilityLevel( GetAttacker(), ABILITY_ID )
        local real    currentMana     = GetUnitState( GetAttacker(), UNIT_STATE_MANA )
        local real    abilityManaCost = GetAbilityManaCost( ABILITY_ID, abilityLevel )

        local boolean a = ( abilityLevel >= 1 )
        local boolean b = ( currentMana >= abilityManaCost )
        local boolean c = ( not IsAbilityOnCooldown( GetUnitAbility( GetAttacker(), ABILITY_ID ) ) )

        return ( a ) and ( b ) and ( c )
    endfunction

    public function GroupCallback takes nothing returns boolean
        local unit   filterUnit         = GetFilterUnit()
        local unit   attackingUnit      = bj_lastCreatedUnit
        local player attackingUnitOwner = bj_groupEnumOwningPlayer

        local boolean a = not IsUnitType(filterUnit, UNIT_TYPE_STRUCTURE)
        local boolean b = IsUnitEnemy(filterUnit, attackingUnitOwner)
        local boolean c = GetWidgetLife(filterUnit) > 0.405

        if ( a ) and ( b ) and ( c ) then
            call UnitDamageTarget( attackingUnit, filterUnit, 125.0, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null )
        	call CreateFloatingTextTag( null, FLOATING_TEXTTAG_CRITICAL_STRIKE, R2I( 125.0 ), GetUnitX( filterUnit ), GetUnitY( filterUnit ) )
        endif
        
        set filterUnit    = null
        set attackingUnit = null

        return false
    endfunction

    public function Actions takes nothing returns nothing
        local unit    victim          = GetTriggerUnit()
        local unit    attacker        = GetAttacker()

        local real    victimZ         = GetUnitFlyHeight(victim)
        local real    victimX         = GetUnitX(victim)
        local real    victimY         = GetUnitY(victim)

        local integer abilityLevel    = GetUnitAbilityLevel( attacker, ABILITY_ID )
        local integer abilityManaCost = GetAbilityManaCost( ABILITY_ID, abilityLevel )
        local real    abilityCooldown = GetAbilityDataCooldown( GetUnitAbility( attacker, ABILITY_ID ), abilityLevel )

        local real    newManaState    = GetUnitState( attacker, UNIT_STATE_MANA ) - abilityManaCost

        call IssueImmediateOrder( attacker, "stop" )

        call StartAbilityCooldown( attacker, ABILITY_ID, abilityCooldown )
        call SetUnitState( attacker, UNIT_STATE_MANA, newManaState )

        set bj_lastCreatedUnit       = attacker
        set bj_groupEnumOwningPlayer = GetOwningPlayer(attacker)

        call GroupEnumUnitsInRange( enumUnits, victimX, victimY, 675.0, boolexprForGroup )

//      call GroupClear(enumUnits)
        set bj_lastCreatedUnit       = null
        set bj_groupEnumOwningPlayer = null

        call CreateLightningTimed( LIGHTNING_NAME, true, victimX, victimY, LIGHTNING_HEIGHT, victimX, victimY, victimZ, LIGHTNING_LIFE_TIME )
        call CasterCastAbilityImmediate( GetOwningPlayer(attacker), victimX, victimY, victimZ, THUNDERCLAP_ID, 1, THUNDERCLAP_ORDER )
        call DestroyEffect( AddSpecialEffect( EFFECT_PATH, victimX, victimY ) )

        set victim        = null
        set attacker      = null
    endfunction

endscope

function InitTrig_StormHammer takes nothing returns nothing
    call PreloadAbility  ( StormHammer_ABILITY_ID     )
    call PreloadAbility  ( StormHammer_THUNDERCLAP_ID )
    call PreloadEffect   ( StormHammer_EFFECT_PATH    )
    call PreloadLightning( StormHammer_LIGHTNING_NAME )

    set StormHammer_boolexprForGroup = Condition(function GroupCallback)
    set gg_trg_StormHammer = CreateTrigger()

    call TriggerRegisterAnyUnitEventBJ( gg_trg_StormHammer, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddCondition( gg_trg_StormHammer, Condition( function StormHammer_Conditions ) )
    call TriggerAddAction( gg_trg_StormHammer, function StormHammer_Actions )
endfunction

ScopteRectuS, у тебя где то перезаписывается bj_lastCreatedUnit
причём происходит это после первой итерации GroupEnumUnitsInRange
а вообще не стоит юзать стандартные бж переменные
т.к. они могут конфликтовать с другими системами
используй приватные переменные
если после перехода на приватные глобалки проблема останется то скопируй систему на отдельную карту и кинь эту карту сюда
буду тестить разные варианты
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
23
Похожие вопросы:

ответ
нет
no
ответ
Не boolean а booexpr - это фильтр для группы, там никакие локалка не нужны.
Саму группу можно перебирать в цикле что правда дает шанс попасть в лимит операций и грохнуть поток.
Делать нужно примерно вот так :
function OnlyEnemyGroundAlive takes nothing returns boolean
    return GetUnitState( GetFilterUnit(), UNIT_STATE_LIFE )> 0.405 and IsUnitEnemy( GetFilterUnit(), bj_groupEnumOwningPlayer ) and IsUnitType( GetFilterUnit(), UNIT_TYPE_GROUND )
endfunction

function DamageEnemy takes nothing returns nothing
    call UnitDamageTarget( bj_lastReplacedUnit, GetEnumUnit(), 100.00, false, false, ATTACK_TYPE_NORMAL,  DAMAGE_TYPE_COLD, WEAPON_TYPE_WHOKNOWS )
endfunction

function Temp takes nothing returns nothing
    local group grp = CreateGroup( ) //создаём группу юнитов
    local real dx = 0.00   // координата x 
    local real dy = 0.00   // координата y
    
    set bj_groupEnumOwningPlayer == Player(0) // глобальная переменная чтобы передать данные в фильтр
    call GroupEnumUnitsInRange( grp, dx, dy, 512.00, Condition( function OnlyEnemyGroundAlive) )
    set bj_lastReplacedUnit = GetTriggerUnit( )// глобальная переменная чтобы передать данные в другую функцию.
    call ForGroup( grp, function DamageEnemy )
    
    call DestroyGroup( grp )
    
    set grp = null
endfunction
1 строчка бывает только у гуишников.
ответ
проверь настройки A01P, возможно, там кривые данные выше 3-го уровня
ответ
private function Trigger_Conditions takes nothing returns boolean
     return LoadStr(HASHTABLE, GetSpellAbilityId(), StringHash("abil_id")) != null and LoadStr(HASHTABLE, GetSpellAbilityId(), StringHash("abil_id")) != ""
endfunction
попробуйте так, или уберите:
local boolexpr b = Condition(function Trigger_Conditions)
call DestroyBoolExpr(b)
set b = null
Замените call TriggerAddCondition(TRIGGER, b) на call TriggerAddCondition(TRIGGER, Condition(function Trigger_Conditions))

Добавлю
Ещё бывает что значение из хеш-таблицы строкового показывало "(null)";
ответ
У тебя логическая ошибка в цикле. На первом витке, если группа пустая, то i увеличиться на 400! На следующем еще на 400. В итоге, ты при выходе получаешь индекс 400*400+1. Но я не уверен, что до этого дойдет. При 819*, не помню макс размер массива,у тебя просто накроется все. В общем, у тебя логическая ошибка
И, да, ласткриейтедюнит можно занести в локальную переменную, т.к.лайс* - глобалка из common типа unit

21
nvc123, дебаг в функции GroupCallback не срабатывает. Кстати, плавающий текст тоже не появляется. Но если в функции call GroupEnumUnitsInRange( enumUnits, victimX, victimY, 675.0, boolexprForGroup ) заменить переменную на Сondition( function GroupCallback ), то плавающий текст начинает появляться, но урона всё также нету.
28
ScopteRectuS, не стоит заносить булекспы в переменные
булэкспы кэшируются так что только путаешься с этими переменными
так же функцию инициализации лучше перенести в scope
что касается урона
перед call UnitDamageTarget добавь вывод на экран имён attackingUnit и filterUnit
и функции лучше сделать приватными а не публичными
21
nvc123, Имя filterUnit выдает правильно, но имя attackingUnit выдаёт правильно лишь 1 раз, дальше начинает выдавать (null). Даже если где то есть перезапись данной переменной, то такого быть не должно, ведь тут действия происходят без задержек.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.