Добавлен , опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
Jass
Тип:
Алгоритм
Версия Warcraft:
UjAPI v1.1.0+

О системе

Относительно краткий пример системы контролей (стан/сон/сайленс/замедление), который можно легко дополнять в зависимости от нужд.
Главным бонусом UjAPI в данной наработке является Ability Instance API, который позволяет менять поля заклинаний/баффов без нужды изменений в РО.
Первая система как раз капитализирует это по максимуму, ибо работает через дамми каст.
Вторая система использует Buff API, эксклюзив UjAPI, который позволяет напрямую накладывать бафф без использования дамми кастов, да и заклинаний в целом и так же позволяет менять все поля без нужды использования РО. А так же система использует внутриигровые таймеры, так что не нужно следить за оставшимся временем вручную.
Обе системы в целом полезны и имеют свои преимущества, но я считаю Buff API фаворитом, ввиду простоты использования, да и в целом отсутствия нагрузки на Jass машину, ну и в целом нужды ручного управления/слежения.

Дамми Каст Метод

раскрыть
    globals
        hashtable CC_HT = InitHashtable( )
    endglobals

    function CC_Cast_Dummy takes unit target, string order, string Type returns nothing
        local player p = Player( 13 )
        local unit cc_dummy = LoadUnitHandle( CC_HT, GetHandleId( CC_HT ), 'ccdm' )
        local real x = GetUnitX( target )
        local real y = GetUnitY( target )

        if order == "rejuvination" then
            set p = GetOwningPlayer( target )
        endif

        call SetUnitOwner( cc_dummy, p, false )
        call UnitShareVision( target, p, true )
        call SetUnitPosition( cc_dummy, x, y )
        if Type == "Target" then
            call IssueTargetOrder( cc_dummy, order, target )
    elseif Type == "AoE" then
            call IssuePointOrder( cc_dummy, order, x, y )
        endif
        call UnitShareVision( target, p, false )
        call SetUnitOwner( cc_dummy, Player( 13 ), false )

        set p = null
        set cc_dummy = null
    endfunction

    function CC_Checker_Dummy takes nothing returns nothing
        local timer tmr = GetExpiredTimer( )
        local integer hid = GetHandleId( tmr )
        local unit target = LoadUnitHandle( CC_HT, hid, 'targ' )
        local integer uhid = GetHandleId( target )
        local integer bid = LoadInteger( CC_HT, hid, 'bufi' )
        local integer time = LoadInteger( CC_HT, hid, 'time' )

        if time > 0 then
            call SaveInteger( CC_HT, hid, 'time', time - 1 )
        else
            call UnitRemoveAbility( target, bid )
            call FlushChildHashtable( CC_HT, hid )
            call RemoveSavedHandle( CC_HT, uhid, bid )
            call PauseTimer( tmr )
            call DestroyTimer( tmr )
        endif

        set tmr = null
        set target = null
    endfunction

    function CC_Unit_Dummy takes unit target, string cc_type, real time, boolean isReduced returns nothing
        local string order = ""
        local string t_type = "Target"
        local integer buffId = 0
        local integer uhid = GetHandleId( target )
        local timer tmr = null
        local integer hid = 0
        local boolean isNewTimer = false
        local boolean hasBuff = false
        set cc_type = StringCase( cc_type, false )

        if isReduced then // set Time = Time / CCMitigation
            
        endif

        if cc_type == "stun" then
            set order = "thunderbolt"
            set buffId = 'BPSE'
        endif

        if cc_type == "silence" then
            set order = "silence"
            set t_type = "AoE"
            set buffId = 'BNsi'
        endif

        if cc_type == "sleep" then
            set order = "sleep"
            set buffId = 'BUsl'
        endif

        if cc_type == "slow" then
            set order = "slow"
            set buffId = 'Bslo'
        endif

        if buffId == 0 then
            return
        endif
        set hasBuff = GetUnitAbilityLevel( target, buffId ) != 0
        if not hasBuff then
            // currently redundant check...
        endif

        set tmr = LoadTimerHandle( CC_HT, uhid, buffId )

        if tmr == null then
            set tmr = CreateTimer( )
            call SaveTimerHandle( CC_HT, uhid, buffId, tmr )
            set isNewTimer = true
        endif

        set hid = GetHandleId( tmr )

        if isNewTimer then
            call CC_Cast_Dummy( target, order, t_type )
            call SaveInteger( CC_HT, hid, 'bufi', buffId )
            call SaveUnitHandle( CC_HT, hid, 'targ', target )
        endif

        call SaveInteger( CC_HT, hid, 'time', R2I( time * 100. ) + LoadInteger( CC_HT, hid, 'time' ) )

        if isNewTimer then
            call TimerStart( tmr, .01, true, function CC_Checker_Dummy )
        endif
    endfunction

    function CC_InitSystemTest_Dummy takes nothing returns nothing
        local ability a = null
        local unit u = null
        
        set u = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'uloc', 8000., 8000., 0. )
        call SetUnitRealField( u, UNIT_RF_CAST_BACK_SWING, .0 )
        call SetUnitRealField( u, UNIT_RF_CAST_POINT, .0 )
        call SetUnitRealField( u, UNIT_RF_ACQUISITION_RANGE, .0 )
        call UnitEnableAttack( u, false, false )

        call UnitAddAbility( u, 'AHtb' )
        set a = GetUnitAbility( u, 'AHtb' )
        call SetAbilityRealLevelField( a, ABILITY_RLF_DURATION_NORMAL, 0, .0 )
        call SetAbilityRealLevelField( a, ABILITY_RLF_DURATION_HERO, 0, .0 )
        call SetAbilityRealLevelField( a, ABILITY_RLF_COOLDOWN, 0, .0 )
        call SetAbilityIntegerLevelField( a, ABILITY_ILF_MANA_COST, 0, 0 )
        call SetAbilityRealLevelField( a, ABILITY_RLF_DAMAGE_HTB1, 0, 0. )
        call SetAbilityRealLevelField( a, ABILITY_RLF_CAST_RANGE, 0, 99999. )

        call UnitAddAbility( u, 'ACsp' )
        set a = GetUnitAbility( u, 'ACsp' )
        call SetAbilityRealLevelField( a, ABILITY_RLF_DURATION_NORMAL, 0, .0 )
        call SetAbilityRealLevelField( a, ABILITY_RLF_DURATION_HERO, 0, .0 )
        call SetAbilityRealLevelField( a, ABILITY_RLF_COOLDOWN, 0, .0 )
        call SetAbilityIntegerLevelField( a, ABILITY_ILF_MANA_COST, 0, 0 )
        call SetAbilityRealLevelField( a, ABILITY_RLF_CAST_RANGE, 0, 99999. )

        call UnitAddAbility( u, 'ANsi' )
        set a = GetUnitAbility( u, 'ANsi' )
        call SetAbilityRealLevelField( a, ABILITY_RLF_DURATION_NORMAL, 0, .0 )
        call SetAbilityRealLevelField( a, ABILITY_RLF_DURATION_HERO, 0, .0 )
        call SetAbilityRealLevelField( a, ABILITY_RLF_COOLDOWN, 0, .0 )
        call SetAbilityIntegerLevelField( a, ABILITY_ILF_MANA_COST, 0, 0 )
        call SetAbilityRealLevelField( a, ABILITY_RLF_AREA_OF_EFFECT, 0, 100. )
        call SetAbilityRealLevelField( a, ABILITY_RLF_CAST_RANGE, 0, 99999. )

        call UnitAddAbility( u, 'Aslo' )
        set a = GetUnitAbility( u, 'Aslo' )
        call SetAbilityRealLevelField( a, ABILITY_RLF_DURATION_NORMAL, 0, .0 )
        call SetAbilityRealLevelField( a, ABILITY_RLF_DURATION_HERO, 0, .0 )
        call SetAbilityRealLevelField( a, ABILITY_RLF_COOLDOWN, 0, .0 )
        call SetAbilityIntegerLevelField( a, ABILITY_ILF_MANA_COST, 0, 0 )
        call SetAbilityRealLevelField( a, ABILITY_RLF_CAST_RANGE, 0, 99999. )

        call SaveUnitHandle( CC_HT, GetHandleId( CC_HT ), 'ccdm', u )
        call SetUnitInvulnerable( u, true )
        call ShowUnit( u, false )

        set a = null
        set u = null
    endfunction

    function CC_AutoTestSystem_Dummy takes nothing returns nothing
        local unit u = null
        call CC_InitSystemTest_Dummy( )
        set u = CreateUnit( Player( 0 ), 'Hamg', .0, .0, .0 )
        call TriggerSleepAction( 1. )
        call CC_Unit_Dummy( u, "silence", 5., false )
        set u = null
    endfunction

Buff API Метод

раскрыть
    function CC_UnitEx takes unit target, integer buffId, real time, boolean canStack, boolean isReduced returns nothing
        local real remainTime = .0
        local boolean hasBuff = false
        local buff buf = null

        if isReduced then // set time = time / mitigation
            
        endif

        set hasBuff = GetUnitBuffLevel( target, buffId ) > 0
        if not hasBuff then
            call UnitAddBuffById( target, buffId )
        endif

        set buf = GetUnitBuff( target, buffId )

        if not hasBuff then
            call SetBuffRemainingDuration( buf, time )
        else
            set remainTime = GetBuffRemainingDuration( buf )

            if canStack then
                call SetBuffRemainingDuration( buf, time + remainTime )
            else
                if remainTime >= time then
                    set time = remainTime
                endif
                call SetBuffRemainingDuration( buf, time )
            endif
        endif
    endfunction

    function CC_Unit takes unit target, string cc_type, real time, boolean canStack, boolean isReduced returns nothing
        local integer buffId = 0

        set cc_type = StringCase( cc_type, false )

        if cc_type == "stun" then
            set buffId = 'BPSE'
        endif

        if cc_type == "silence" then
            set buffId = 'BNsi'
        endif

        if cc_type == "sleep" then
            set buffId = 'BUsl'
        endif

        if cc_type == "slow" then
            set buffId = 'Bslo'
        endif

        if cc_type == "banish" then
            set buffId = 'BHbn'
        endif

        call CC_UnitEx( target, buffId, time, canStack, isReduced )
    endfunction

    function CC_AutoTestSystem takes nothing returns nothing
        local unit u = null
        set u = CreateUnit( Player( 0 ), 'Hamg', .0, .0, .0 )
        call CC_Unit( u, "banish", 5., true, false )
        set u = null
    endfunction
`
ОЖИДАНИЕ РЕКЛАМЫ...
2
31
3 месяца назад
Отредактирован Алексей Андреич
2
function CC_UnitEx takes unit target, integer buffId, real time, boolean canStack, boolean isReduced returns nothing
local real remainTime = .0 //инициализация переменной
local boolean hasBuff = false
local buff buf = null
if isReduced then set time = time / mitigation

endif
set hasBuff = GetUnitBuffLevel( target, buffId ) > 0
if not hasBuff then
call UnitAddBuffById( target, buffId )
endif
set buf = GetUnitBuff( target, buffId )
if not hasBuff then
call SetBuffRemainingDuration( buf, time )
else
if canStack then
call SetBuffRemainingDuration( buf, time + remainTime ) //первое использование переменной, я так понимаю, ее значение здесь по-прежнему = 0.0
else
set remainTime = GetBuffRemainingDuration( buf )
if remainTime >= time then
set time = remainTime
endif
call SetBuffRemainingDuration( buf, time )
endif
endif
endfunction

может я что-то пропустил, но, получается, что если бафф стакается, его время не будет увеличиваться..?

потестил... ну да, не стакается время...
...
if canStack then
	set remainTime = GetBuffRemainingDuration( buf ) //тут этой строчки не хватает...
	call SetBuffRemainingDuration( buf, time + remainTime )
else
...
2
20
3 месяца назад
2
Ну, ошибку видно на лицо, нужно было лишь сдвинуть установку remain time, как ты и указал, поправлю.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.