Simple Temporary Ability System

This bundle is marked as pending. It has not been reviewed by a staff member yet.
Simple Temporary Ability System.
Version: 0.0.3


Now it make sense!


When a unit cast a certain spell, the system will add another spell that correspond to the spell casted.

This spell added will be in the hero spell a certain time, called expiration time.

Is usefull if you want create spell chain, combo, or next spell behaviour

How it works?

1. Create your spells, in this case will use one base, and two more. the flow will be:
1.1 when base you will get combo
1.2 when cast combo you will get wombo
1.3 If you set the icon for all the spell at same values, you will overwrite the spell.
1.4 If you set different pos(x,y) you will get multiple icon, take care about the expiration time, because if the NEXT spell have more time than the BASE you can keep spamming the NEXT spell.

2. In STAS LIBRARY save the globals variable of your spell id, need to the expiration time of the spell. this mean, the amount of time that temporary spell will remain in unit available spells.

3. Use the CreateTemporaryAbility to create the temporary chain between the spell.

4. Use the CastTemporaryAbility to use the system.

5. Enjoy!


Advantages

* Is MUI
* Use timers
* Easy configuration
* Now with Create and Cast function!

Version 0.0.3

JASS:
globals
    hashtable STASSkills = InitHashtable()
    hashtable STASIndexer = InitHashtable()

    integer ONE_SPELL          = 'A000'
    integer ONE_TO_TWO_SPELL   = 'A001'
    integer TWO_TO_THREE_SPELL = 'A002'

    real ONE_TO_TWO_SPELL_ET = 3.00
    real TWO_TO_ONE_SPELL_ET = 1.00

endglobals

library STAS
    function CreateTemporaryAbility takes integer bs, integer ns, real nset returns nothing
        call SaveInteger(STASSkills, bs, StringHash("NEXT"), ns)
        call SaveReal(STASSkills, bs, StringHash("EXPTIME"), nset)
    endfunction

    function STASTemporaryTimeHandler takes nothing returns nothing
        // USE: On timer expiration, remove the next spell

        // Get the expired timer
        local timer t = GetExpiredTimer()

        // Get the caster unit through timer ID
        local unit caster = LoadUnitHandle(STASIndexer, GetHandleId(t), StringHash("CASTER"))

        // Get the next_spell spell ID
        local integer NEXT = LoadInteger(STASIndexer, GetHandleId(t), StringHash("NEXT"))

        // Remove the spell
        call UnitRemoveAbility(caster, NEXT)

        // For avoid bugs of timer, pause it
        call PauseTimer(t)

        // Destroy the timer
        call DestroyTimer(t)

        // Remove leak
        set t = null
        set caster = null
    endfunction

    function CastTemporaryAbility takes unit cu, integer cs returns nothing
        local real et
        local timer t
        local integer ns = LoadInteger(STASSkills, cs, StringHash("NEXT"))

        if (ns != 0) then

            // Initialize the timer
            set t = CreateTimer()

            // Save expiration time
            set et = LoadReal(STASSkills, cs, StringHash("EXPTIME"))
   
            // Save to hashtable the unit that cast the spell
            call SaveUnitHandle(STASIndexer, GetHandleId(t), StringHash("CASTER"), cu)

            // Save the next_spell spell ID
            call SaveInteger(STASIndexer, GetHandleId(t), StringHash("NEXT"), ns)

            // Add new spell to caster
            call UnitAddAbility(cu, ns)

            // Start the timer
            call TimerStart(t, et, false, function STASTemporaryTimeHandler)
        else
             return
        endif
 
        // Avoid leaks
        set cu = null
        set t = null
    endfunction

endlibrary


JASS:
function sca takes nothing returns nothing

    call CreateTemporaryAbility(ONE_SPELL, ONE_TO_TWO_SPELL, ONE_TO_TWO_SPELL_ET)
    call CreateTemporaryAbility(ONE_TO_TWO_SPELL, TWO_TO_THREE_SPELL, TWO_TO_ONE_SPELL_ET)

endfunction

//===========================================================================
function InitTrig_STAS_Creation takes nothing returns nothing
    local trigger tg = CreateTrigger(  )
    call TriggerRegisterTimerEventSingle( tg, 0.00 )
    call TriggerAddAction( tg, function sca )
endfunction

JASS:
function STASActions takes nothing returns nothing
    // Get the caster unit
    local unit c = GetSpellAbilityUnit()

    // Get the casted spell
    local integer cs = GetSpellAbilityId()

    // Call the temporary system
    call CastTemporaryAbility(c, cs)

    set c = null
endfunction

function InitTrig_STAS_Cast takes nothing returns nothing
    local trigger tg = CreateTrigger()
    local integer i = 0

    call TriggerAddAction(tg, function STASActions)

    loop
        call TriggerRegisterPlayerUnitEvent(tg, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        set i = i + 1
    exitwhen i == bj_MAX_PLAYERS
    endloop
endfunction


More Credits:
* Hate, code correction
Contents

Simple Temporal Ability System 0.0.1 (Map)

Simple Temporal Ability System 0.0.2 (Map)

Simple Temporal Ability System 0.0.3 (Map)

Level 14
Joined
Oct 19, 2014
Messages
186
Im still confuse of how the system works, but i have to say this

CAST

why not try to index everything just to prevent create and destroy timer

CONFIGURE

You had the uniqueness idead but much better to infunction those ability id like
JASS:
constant function BASE_SPELL takes nothing returns integer
    return 'A000'
endfunction
Also those saved by handles
 

V

V

Level 7
Joined
Jan 13, 2019
Messages
285
Im still confuse of how the system works, but i have to say this

CAST

why not try to index everything just to prevent create and destroy timer

CONFIGURE

You had the uniqueness idead but much better to infunction those ability id like
JASS:
constant function BASE_SPELL takes nothing returns integer
    return 'A000'
endfunction
Also those saved by handles

Thanks for the comment, i will update the trigger and the post :)
 

V

V

Level 7
Joined
Jan 13, 2019
Messages
285
Im still confuse of how the system works, but i have to say this

CAST

why not try to index everything just to prevent create and destroy timer

CONFIGURE

You had the uniqueness idead but much better to infunction those ability id like
JASS:
constant function BASE_SPELL takes nothing returns integer
    return 'A000'
endfunction
Also those saved by handles

Now it make sense!, see the restructuration of the library :D
 
Level 14
Joined
Oct 19, 2014
Messages
186
hahaha yeah, i learn too fast, is one of my strengths. Thanks :D. i got another post of simple system!
Done testing your system,, i have even test in multiple unit,, and it work so, but one that keeps bugging my mind, or even experts will tell you this,, why not try to avoid creating and destroying timers, instead use one and ingroup those casters as well
 

V

V

Level 7
Joined
Jan 13, 2019
Messages
285
Done testing your system,, i have even test in multiple unit,, and it work so, but one that keeps bugging my mind, or even experts will tell you this,, why not try to avoid creating and destroying timers, instead use one and ingroup those casters as well

i see this on internet: one timer with time 1 and every expiration set a integer to integer - 1 , and this integer is assigned to a hashtable that have the unit id?
 
Level 22
Joined
Feb 27, 2007
Messages
3,784
i see this on internet: one timer with time 1 and every expiration set a integer to integer - 1 , and this integer is assigned to a hashtable that have the unit id?
In general, yes. However when using a single timer your margin of error for any given duration is +-(timerperiod) so timing for a duration of 9s could actually take as long as 9.999... or as short as 8.000..1. I would use a shorter timer period like 0.2, so then instead of storing 9 as the integer to count down you store 9*1/(timerperiod) = 9*5 = 45
 

V

V

Level 7
Joined
Jan 13, 2019
Messages
285
In general, yes. However when using a single timer your margin of error for any given duration is +-(timerperiod) so timing for a duration of 9s could actually take as long as 9.999... or as short as 8.000..1. I would use a shorter timer period like 0.2, so then instead of storing 9 as the integer to count down you store 9*1/(timerperiod) = 9*5 = 45

Thanks for that suggestion, can you check my others system too please?. in my profile page you can get the link :D
 
Level 6
Joined
Feb 9, 2021
Messages
225
Pending call FlushChildHashtable(STASIndexer, GetHandleId(t)) for remove the unit data for the hashtable, this inside the STASIndexer function
I think replacing the old spell with the new spell (new icon appears at the place of the old icon) is better for this type of spells, so they don't take too much space.
 
Top