HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Spell event library

04-17-2009, 02:26 PM#1
0zyx0
Collapse JASS:
library EventModule initializer init

public function interface SpellEvent takes nothing returns nothing

globals
    private constant integer MinAbilityId = 'A000'
    private SpellEvent array SE
    private SpellEvent array SC
    private SpellEvent array SF
endglobals

//! textmacro AbilityEvent takes name, var
function AddAbility$name$Event takes integer abilityid, SpellEvent new returns nothing
    set S$var$[abilityid - MinAbilityId] = new
endfunction

function DestroyAbility$name$Event takes integer abilityid returns nothing
    set S$var$[abilityid - MinAbilityId] = 0
endfunction

private function $name$Execute takes nothing returns nothing
    call S$var$[GetSpellAbilityId() - MinAbilityId].execute()
endfunction
//! endtextmacro

//! runtextmacro AbilityEvent("Effect", "E")
//! runtextmacro AbilityEvent("PreCast", "C")
//! runtextmacro AbilityEvent("Finish", "F")

//! textmacro AbilityEventInit takes name, NAME
    set T = CreateTrigger()
    set i = 0
    loop
        call TriggerRegisterPlayerUnitEvent(T, Player(i),EVENT_PLAYER_UNIT_SPELL_$NAME$, null)
        set i = i+1
        exitwhen i == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddAction(T, function $name$Execute)
//! endtextmacro

private function init takes nothing returns nothing
    local integer i = 0
    local trigger T
    //! runtextmacro AbilityEventInit("Effect", "EFFECT")
    //! runtextmacro AbilityEventInit("PreCast", "CAST")
    //! runtextmacro AbilityEventInit("Finish", "FINISH")
    set T = null
endfunction
endlibrary

This works fine when I test it. However, I'm not sure if there are any other problems with it, except the fact that it doesn't work for all ability IDs (and of course bad names on stuff). I'm asking, are there?
04-17-2009, 02:59 PM#2
azlier
Well, 'A000' would work only for custom abilities that are right after it ('A001', 'A002'). You could probably do some hashing, but I'm no good with it. The absolute simplest method for shrinking those looked something like this.

Collapse JASS:
function S2ID takes string s returns integer
    return s
    return 0
endfunction

function ShrinkRawcode takes integer i returns integer
    return S2ID(I2S(i))
endfunction

This gets erased upon loading the map, however. The next simple method would to use game cache instead.
04-18-2009, 04:08 PM#3
0zyx0
I will probably use gamecache (probably done through tables) if the ability index would be greater than 8190, or less than 0. Or I could use sized arrays, but I don't know how that effects memory usage. If I would use the index [20000] or, would it use memory for all 20000 other indexes below it?
04-18-2009, 09:47 PM#4
Anitarf
I used gamecache when I was writing my library, it's the safest way and speed isn't an issue because you should still save a lot by the virtue of the fact that you don't have as many spell events running.
04-23-2009, 07:30 PM#5
0zyx0
Collapse JASS:
library AbilityEvent initializer init requires xebasic, Table

public function interface AbilityAction takes nothing returns nothing

globals
    private constant integer MIN_ABILITY_ID = 'A000'
    private AbilityAction array SEffect
    private AbilityAction array SPreCast
    private AbilityAction array SFinish
    private Table EffectTable
    private Table PreCastTable
    private Table FinishTable
endglobals

//! textmacro AbilityEvent takes name
function AddAbility$name$Event takes integer abilityid, AbilityAction new returns nothing
    local integer i = (abilityid - MIN_ABILITY_ID)
    if i < 0 or i > 8190 then
        set $name$Table[abilityid] = new
    else
        set S$name$[i] = new
    endif
endfunction

function DestroyAbility$name$Event takes integer abilityid returns nothing
    local integer i = (abilityid - MIN_ABILITY_ID)
    if i < 0 or i > 8190 then
        if $name$Table.exists(abilityid) then
            call $name$Table.flush(abilityid)
        endif
    else
        set S$name$[i] = 0
    endif
endfunction

private function $name$Execute takes nothing returns nothing
    local integer s = GetSpellAbilityId()
    local integer i = s - MIN_ABILITY_ID
    local AbilityAction e
    if i < 0 or i > 8190 then
        if $name$Table.exists(s) then
            set e = $name$Table[s]
            call e.execute()
        endif
    else
        call S$name$[i].execute()
    endif
endfunction
//! endtextmacro

//! runtextmacro AbilityEvent("Effect")
//! runtextmacro AbilityEvent("PreCast")
//! runtextmacro AbilityEvent("Finish")

private function Cond takes nothing returns boolean
    return GetUnitTypeId(GetSpellAbilityUnit()) != XE_DUMMY_UNITID
endfunction

//! textmacro AbilityEventInit takes name, NAME
    set T = CreateTrigger()
    set i = 0
    loop
        call TriggerRegisterPlayerUnitEvent(T, Player(i),EVENT_PLAYER_UNIT_SPELL_$NAME$, null)
        set i = i+1
        exitwhen i == bj_MAX_PLAYER_SLOTS
    endloop
    call TriggerAddCondition(T, Condition(function Cond))
    call TriggerAddAction(T, function $name$Execute)
    set $name$Table = Table.create()
//! endtextmacro

private function init takes nothing returns nothing
    local integer i = 0
    local trigger T
    //! runtextmacro AbilityEventInit("Effect", "EFFECT")
    //! runtextmacro AbilityEventInit("PreCast", "CAST")
    //! runtextmacro AbilityEventInit("Finish", "FINISH")
    set T = null
endfunction
endlibrary

Would this be better?