• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!

Library Questions

Status
Not open for further replies.
Level 3
Joined
Oct 25, 2010
Messages
11
Are those libraries supposed to do the same thing?

JASS:
//============================================================================
// SpellEffectEvent
// - Version 1.0.0.1
//
// API
// ---
//     RegisterSpellEffectEvent(integer abil, code onCast)
//
// Requires
// --------
//     Table: hiveworkshop.com/forums/showthread.php?t=188084
//     RegisterPlayerUnitEvent: hiveworkshop.com/forums/showthread.php?t=203338
//
library SpellEffectEvent requires RegisterPlayerUnitEvent, Table
 
globals
    private Table tb
endglobals
 
//============================================================================
function RegisterSpellEffectEvent takes integer abil, code onCast returns nothing
    if not tb.handle.has(abil) then
        set tb.trigger[abil] = CreateTrigger()
    endif
    call TriggerAddCondition(tb.trigger[abil], Filter(onCast))
endfunction
 
//============================================================================
private module M
    static method onCast takes nothing returns boolean
        return TriggerEvaluate(tb.trigger[GetSpellAbilityId()])
    endmethod
 
    private static method onInit takes nothing returns nothing
        set tb = Table.create()
        call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function thistype.onCast)
    endmethod
endmodule
 
//============================================================================
private struct S extends array
    implement M
endstruct
 
endlibrary

JASS:
library SpellEvent initializer Init requires Table

//*****************************************************************
//*  SPELL EVENT LIBRARY
//*
//*  written by: Anitarf
//*  requires: -Table
//*
//*  Maps with many triggered spells require many triggers that run
//*  on spell events and whenever a spell is cast, all those
//*  triggers need to be evaluated by the game even though only one
//*  actually needs to run. This library has been written to reduce
//*  the number of triggers in such maps; instead of having a
//*  trigger per spell, you can use this library's single trigger
//*  to only run the code associated with the spell that's actually
//*  being cast.
//*
//*  Perhaps more significant than the marginal speed gain is the
//*  feature that allows you to access all the spell event
//*  responses from all spell events, something that the native
//*  functions senselessly do not support. With this system you can
//*  for example easily get the target unit of the spell on the
//*  casting finish event.
//*
//*  All functions following the Response function interface that
//*  is defined at the start of this library can be used to respond
//*  to damage events. Simply put them on the call list for any of
//*  the spell events using the appropriate function:
//*
//*    function RegisterSpellChannelResponse takes integer spellId, Response r returns nothing
//*    function RegisterSpellCastResponse takes integer spellId, Response r returns nothing
//*    function RegisterSpellEffectResponse takes integer spellId, Response r returns nothing
//*    function RegisterSpellFinishResponse takes integer spellId, Response r returns nothing
//*    function RegisterSpellEndCastResponse takes integer spellId, Response r returns nothing
//*
//*  The first event occurs at the very start of the spell, when
//*  the spell's casting time begins; most spells have 0 casting
//*  time, so in most cases this first event occurs at the same
//*  time as the second one, which runs when the unit actually
//*  begins casting a spell by starting it's spell animation. The
//*  third event occurs when the spell effect actually takes place,
//*  which happens sometime into the unit's spell animation
//*  depending on the unit's Animation - Cast Point property.
//*  The fourth event runs if the unit finishes casting the spell
//*  uninterrupted, which might be important for channeling spells.
//*  The last event runs when the unit stops casting the spell,
//*  regardless of whether it finished casting or was interrupted.
//*
//*  If you specify a spell id when registering a function then
//*  that function will only run when that ability is cast; only
//*  one function per ability per event is supported, if you
//*  register more functions then only the last one registered will
//*  be called. If, however, you pass 0 as the ability id parameter
//*  then the registered function will run for all spells. Up to
//*  8190 functions can be registered this way for each event.
//*  These functions will be called before the ability's specific
//*  function in the order they were registered.
//*
//*  This library provides it's own event responses that work
//*  better than the Blizzard's bugged native cast event responses.
//*  They still aren't guaranteed to work after a wait, but aside
//*  from that they will work in response functions no matter what
//*  event they are registered to.
//*
//*  Here are usage examples for all event responses:
//*
//*    local integer a = SpellEvent.AbilityId
//*    local unit u = SpellEvent.CastingUnit
//*    local unit t = SpellEvent.TargetUnit
//*    local item i = SpellEvent.TargetItem
//*    local destructable d = SpellEvent.TargetDestructable
//*    local location l = SpellEvent.TargetLoc
//*    local real x = SpellEvent.TargetX
//*    local real y = SpellEvent.TargetY
//*    local boolean b = SpellEvent.CastFinished
//*
//*  SpellEvent.TargetLoc is provided for odd people who insist on
//*  using locations, note that if you use it you have to cleanup
//*  the returned location yourself.
//*
//*  SpellEvent.CastFinished boolean is intended only for the
//*  EndCast event as it tells you whether the spell finished or
//*  was interrupted.
//*
//*****************************************************************

    // use the RegisterSpell*Response functions to add spell event responses to the library
    public function interface Response takes nothing returns nothing

// ================================================================

    private keyword casterTable
    private keyword effectDone
    private keyword init
    private keyword get

    private struct spellEvent
        static HandleTable casterTable
        boolean effectDone=false

        integer AbilityId
        unit CastingUnit
        unit TargetUnit
        item TargetItem=null
        destructable TargetDestructable=null
        real TargetX=0.0
        real TargetY=0.0
        boolean CastFinished=false

        method operator TargetLoc takes nothing returns location
            return Location(.TargetX, .TargetY)
        endmethod
        
        private static method create takes nothing returns spellEvent
            return spellEvent.allocate()
        endmethod
        static method init takes nothing returns spellEvent
            local spellEvent s=spellEvent.allocate()
            set s.AbilityId = GetSpellAbilityId()
            set s.CastingUnit = GetTriggerUnit()
            set s.TargetUnit = GetSpellTargetUnit()
            if s.TargetUnit != null then
                set s.TargetX = GetUnitX(s.TargetUnit)
                set s.TargetY = GetUnitY(s.TargetUnit)
            else
                set s.TargetDestructable = GetSpellTargetDestructable()
                if s.TargetDestructable != null then
                    set s.TargetX = GetDestructableX(s.TargetDestructable)
                    set s.TargetY = GetDestructableY(s.TargetDestructable)
                else
                    set s.TargetItem = GetSpellTargetItem()
                    if s.TargetItem != null then
                        set s.TargetX = GetItemX(s.TargetItem)
                        set s.TargetY = GetItemY(s.TargetItem)
                    else
                        set s.TargetX = GetSpellTargetX()
                        set s.TargetY = GetSpellTargetY()
                    endif
                endif
            endif
            set spellEvent.casterTable[s.CastingUnit]=integer(s)
            return s
        endmethod
        static method get takes unit caster returns spellEvent
            return spellEvent(spellEvent.casterTable[caster])
        endmethod
        method onDestroy takes nothing returns nothing
            call spellEvent.casterTable.flush(.CastingUnit)
            set .CastingUnit=null
        endmethod
    endstruct
    
    globals
        spellEvent SpellEvent=0
    endglobals
    
// ================================================================

    //! textmacro spellEvent_make takes name
    globals
        private Response array $name$CallList
        private integer $name$CallCount=0
        private Table $name$Table
    endglobals

    private function $name$Calls takes nothing returns nothing
        local integer i=0
        local integer id=GetSpellAbilityId()
        local spellEvent previous=SpellEvent
        set SpellEvent=spellEvent.get(GetTriggerUnit())
        loop
            exitwhen i>=$name$CallCount
            call $name$CallList[i].evaluate()
            set i=i+1
        endloop
        if $name$Table.exists(id) then
            call Response($name$Table[id]).evaluate()
        endif
        set SpellEvent=previous
    endfunction

    function RegisterSpell$name$Response takes integer spellId, Response r returns nothing
        if spellId==0 then
            set $name$CallList[$name$CallCount]=r
            set $name$CallCount=$name$CallCount+1
        else
            set $name$Table[spellId]=integer(r)
        endif
    endfunction
    //! endtextmacro

    //! runtextmacro spellEvent_make("Channel")
    //! runtextmacro spellEvent_make("Cast")
    //! runtextmacro spellEvent_make("Effect")
    //! runtextmacro spellEvent_make("Finish")
    //! runtextmacro spellEvent_make("EndCast")

    private function Channel takes nothing returns nothing
        call spellEvent.init()
        call ChannelCalls()
    endfunction
    private function Cast takes nothing returns nothing
        call CastCalls()
    endfunction
    private function Effect takes nothing returns nothing
        local spellEvent s=spellEvent.get(GetTriggerUnit())
        if s!=0 and not s.effectDone then
            set s.effectDone=true
            call EffectCalls()
        endif
    endfunction
    private function Finish takes nothing returns nothing
        set spellEvent.get(GetTriggerUnit()).CastFinished=true
        call FinishCalls()
    endfunction
    private function EndCast takes nothing returns nothing
        call EndCastCalls()
        call spellEvent.get(GetTriggerUnit()).destroy()
    endfunction

// ================================================================

    private function InitTrigger takes playerunitevent e, code c returns nothing
        local trigger t=CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ( t, e )
        call TriggerAddAction(t, c)
        set t=null
    endfunction
    private function Init takes nothing returns nothing
        set spellEvent.casterTable=HandleTable.create()
        set ChannelTable=Table.create()
        set CastTable=Table.create()
        set EffectTable=Table.create()
        set FinishTable=Table.create()
        set EndCastTable=Table.create()
        call InitTrigger(EVENT_PLAYER_UNIT_SPELL_CHANNEL, function Channel)
        call InitTrigger(EVENT_PLAYER_UNIT_SPELL_CAST, function Cast)
        call InitTrigger(EVENT_PLAYER_UNIT_SPELL_EFFECT, function Effect)
        call InitTrigger(EVENT_PLAYER_UNIT_SPELL_FINISH, function Finish)
        call InitTrigger(EVENT_PLAYER_UNIT_SPELL_ENDCAST, function EndCast)
    endfunction

endlibrary

If they do the same thing, can i get rid of one of them?
If the response is yes, then which one do you recommend me to delete?
If the response is no, then I have another question... (I'm getting annoying, I know xD)

As you can see both of them use the library Table, but the problem is that they are not the same library

JASS:
library Table
//***************************************************************
//* Table object 3.0
//* ------------
//*
//*   set t=Table.create() - instanceates a new table object
//*   call t.destroy()     - destroys it
//*   t[1234567]           - Get value for key 1234567
//*                          (zero if not assigned previously)
//*   set t[12341]=32      - Assigning it.
//*   call t.flush(12341)  - Flushes the stored value, so it
//*                          doesn't use any more memory
//*   t.exists(32)         - Was key 32 assigned? Notice
//*                          that flush() unassigns values.
//*   call t.reset()       - Flushes the whole contents of the
//*                          Table.
//*
//*   call t.destroy()     - Does reset() and also recycles the id.
//*
//*   If you use HandleTable instead of Table, it is the same
//* but it uses handles as keys, the same with StringTable.
//*
//*  You can use Table on structs' onInit  if the struct is
//* placed in a library that requires Table or outside a library.
//*
//*  You can also do 2D array syntax if you want to touch
//* mission keys directly, however, since this is shared space
//* you may want to prefix your mission keys accordingly:
//*
//*  set Table["thisstring"][ 7 ] = 2
//*  set Table["thisstring"][ 5 ] = Table["thisstring"][7]
//*
//***************************************************************

//=============================================================
    globals
        private constant integer MAX_INSTANCES=8100 //400000
        //Feel free to change max instances if necessary, it will only affect allocation
        //speed which shouldn't matter that much.

    //=========================================================
        private hashtable ht
    endglobals

    private struct GTable[MAX_INSTANCES]

        method reset takes nothing returns nothing
            call FlushChildHashtable(ht, integer(this) )
        endmethod

        private method onDestroy takes nothing returns nothing
            call this.reset()
        endmethod

        //=============================================================
        // initialize it all.
        //
        private static method onInit takes nothing returns nothing
            set ht = InitHashtable()
        endmethod

    endstruct

    //Hey: Don't instanciate other people's textmacros that you are not supposed to, thanks.
    //! textmacro Table__make takes name, type, key
    struct $name$ extends GTable

        method operator [] takes $type$ key returns integer
            return LoadInteger(ht, integer(this), $key$)
        endmethod

        method operator []= takes $type$ key, integer value returns nothing
            call SaveInteger(ht,  integer(this)  ,$key$, value)
        endmethod

        method flush takes $type$ key returns nothing
            call RemoveSavedInteger(ht, integer(this), $key$)
        endmethod

        method exists takes $type$ key returns boolean
            return HaveSavedInteger( ht,  integer(this)  ,$key$)
        endmethod

        static method flush2D takes string firstkey returns nothing
            call $name$(- StringHash(firstkey)).reset()
        endmethod

        static method operator [] takes string firstkey returns $name$
            return $name$(- StringHash(firstkey) )
        endmethod

    endstruct
    //! endtextmacro

    //! runtextmacro Table__make("Table","integer","key" )
    //! runtextmacro Table__make("StringTable","string", "StringHash(key)" )
    //! runtextmacro Table__make("HandleTable","handle","GetHandleId(key)" )

endlibrary

JASS:
library Table // made by Bribe, special thanks to Nestharus, version 3.0.0.0
/*
    API
    
    ------------
    struct Table
    | static method create takes nothing returns Table
    |     create a new Table
    |    
    | method destroy takes nothing returns nothing
    |     destroy it
    |    
    | method flush takes nothing returns nothing
    |     flush all stored values inside of it
    |    
    | method remove takes integer key returns nothing
    |     remove the value at index "key"
    |    
    | method operator []= takes integer key, $TYPE$ value returns nothing
    |     assign "value" to index "key"
    |    
    | method operator [] takes integer key returns $TYPE$
    |     load the value at index "key"
    |    
    | method has takes integer key returns boolean
    |     whether or not the key was assigned
    |
    ----------------
    struct TableArray
    | static method operator [] takes integer array_size returns TableArray
    |     create a new array of Tables of size "array_size"
    |
    | method destroy takes nothing returns nothing
    |     destroy it
    |
    | method flush takes nothing returns nothing
    |     flush and destroy it
    |
    | method operator size takes nothing returns integer
    |     returns the size of the TableArray
    |
    | method operator [] takes integer key returns Table
    |     returns a Table accessible exclusively to index "key"
*/
    
globals
    private hashtable ht = InitHashtable() //The last hashtable you need
    private integer more = 2 //Index generation for Tables (above 2)
    private integer less = 0 //Index generation for TableArrays (below 0)
endglobals
    
private struct dex extends array
    static method operator size takes nothing returns Table
        return 1
    endmethod
    static method operator list takes nothing returns Table
        return 2
    endmethod
endstruct
    
private struct handles extends array
    method has takes integer key returns boolean
        return HaveSavedHandle(ht, this, key)
    endmethod
    method remove takes integer key returns nothing
        call RemoveSavedHandle(ht, this, key)
    endmethod
endstruct
    
private struct agents extends array
    method operator []= takes integer key, agent value returns nothing
        call SaveAgentHandle(ht, this, key, value)
    endmethod
endstruct
    
//! textmacro NEW_ARRAY_BASIC takes SUPER, FUNC, TYPE
private struct $TYPE$s extends array
    method operator [] takes integer key returns $TYPE$
        return Load$FUNC$(ht, this, key)
    endmethod
    method operator []= takes integer key, $TYPE$ value returns nothing
        call Save$FUNC$(ht, this, key, value)
    endmethod
    method has takes integer key returns boolean
        return HaveSaved$SUPER$(ht, this, key)
    endmethod
    method remove takes integer key returns nothing
        call RemoveSaved$SUPER$(ht, this, key)
    endmethod
endstruct
private module $TYPE$m
    method operator $TYPE$ takes nothing returns $TYPE$s
        return this
    endmethod
endmodule
//! endtextmacro
    
//! textmacro NEW_ARRAY takes FUNC, TYPE
private struct $TYPE$s extends array
    method operator [] takes integer key returns $TYPE$
        return Load$FUNC$Handle(ht, this, key)
    endmethod
    method operator []= takes integer key, $TYPE$ value returns nothing
        call Save$FUNC$Handle(ht, this, key, value)
    endmethod
endstruct
private module $TYPE$m
    method operator $TYPE$ takes nothing returns $TYPE$s
        return this
    endmethod
endmodule
//! endtextmacro
    
//! runtextmacro NEW_ARRAY_BASIC("Real", "Real", "real")
//! runtextmacro NEW_ARRAY_BASIC("Boolean", "Boolean", "boolean")
//! runtextmacro NEW_ARRAY_BASIC("String", "Str", "string")
    
//! runtextmacro NEW_ARRAY("Player", "player")
//! runtextmacro NEW_ARRAY("Widget", "widget")
//! runtextmacro NEW_ARRAY("Destructable", "destructable")
//! runtextmacro NEW_ARRAY("Item", "item")
//! runtextmacro NEW_ARRAY("Unit", "unit")
//! runtextmacro NEW_ARRAY("Ability", "ability")
//! runtextmacro NEW_ARRAY("Timer", "timer")
//! runtextmacro NEW_ARRAY("Trigger", "trigger")
//! runtextmacro NEW_ARRAY("TriggerCondition", "triggercondition")
//! runtextmacro NEW_ARRAY("TriggerAction", "triggeraction")
//! runtextmacro NEW_ARRAY("TriggerEvent", "event")
//! runtextmacro NEW_ARRAY("Force", "force")
//! runtextmacro NEW_ARRAY("Group", "group")
//! runtextmacro NEW_ARRAY("Location", "location")
//! runtextmacro NEW_ARRAY("Rect", "rect")
//! runtextmacro NEW_ARRAY("BooleanExpr", "boolexpr")
//! runtextmacro NEW_ARRAY("Sound", "sound")
//! runtextmacro NEW_ARRAY("Effect", "effect")
//! runtextmacro NEW_ARRAY("UnitPool", "unitpool")
//! runtextmacro NEW_ARRAY("ItemPool", "itempool")
//! runtextmacro NEW_ARRAY("Quest", "quest")
//! runtextmacro NEW_ARRAY("QuestItem", "questitem")
//! runtextmacro NEW_ARRAY("DefeatCondition", "defeatcondition")
//! runtextmacro NEW_ARRAY("TimerDialog", "timerdialog")
//! runtextmacro NEW_ARRAY("Leaderboard", "leaderboard")
//! runtextmacro NEW_ARRAY("Multiboard", "multiboard")
//! runtextmacro NEW_ARRAY("MultiboardItem", "multiboarditem")
//! runtextmacro NEW_ARRAY("Trackable", "trackable")
//! runtextmacro NEW_ARRAY("Dialog", "dialog")
//! runtextmacro NEW_ARRAY("Button", "button")
//! runtextmacro NEW_ARRAY("TextTag", "texttag")
//! runtextmacro NEW_ARRAY("Lightning", "lightning")
//! runtextmacro NEW_ARRAY("Image", "image")
//! runtextmacro NEW_ARRAY("Ubersplat", "ubersplat")
//! runtextmacro NEW_ARRAY("Region", "region")
//! runtextmacro NEW_ARRAY("FogState", "fogstate")
//! runtextmacro NEW_ARRAY("FogModifier", "fogmodifier")
//! runtextmacro NEW_ARRAY("Hashtable", "hashtable")
    
struct Table extends array
    
    // Implement modules for intuitive type-syntax
    implement realm
    implement booleanm
    implement stringm
    implement playerm
    implement widgetm
    implement destructablem
    implement itemm
    implement unitm
    implement abilitym
    implement timerm
    implement triggerm
    implement triggerconditionm
    implement triggeractionm
    implement eventm
    implement forcem
    implement groupm
    implement locationm
    implement rectm
    implement boolexprm
    implement soundm
    implement effectm
    implement unitpoolm
    implement itempoolm
    implement questm
    implement questitemm
    implement defeatconditionm
    implement timerdialogm
    implement leaderboardm
    implement multiboardm
    implement multiboarditemm
    implement trackablem
    implement dialogm
    implement buttonm
    implement texttagm
    implement lightningm
    implement imagem
    implement ubersplatm
    implement regionm
    implement fogstatem
    implement fogmodifierm
    implement hashtablem
    
    method operator handle takes nothing returns handles
        return this
    endmethod
    
    method operator agent takes nothing returns agents
        return this
    endmethod
    
    // set this = a[GetSpellAbilityId()]
    method operator [] takes integer key returns Table
        return LoadInteger(ht, this, key)
    endmethod
    
    // set a[389034] = 8192
    method operator []= takes integer key, Table a returns nothing
        call SaveInteger(ht, this, key, a)
    endmethod
    
    // set b = a.has(2493223)
    method has takes integer key returns boolean
        return HaveSavedInteger(ht, this, key)
    endmethod
    
    // call a.remove(294080)
    method remove takes integer key returns nothing
        call RemoveSavedInteger(ht, this, key)
    endmethod
    
    // Remove all data from a Table instance
    method flush takes nothing returns nothing
        call FlushChildHashtable(ht, this)
    endmethod
    
    // local Table a = Table.create()
    static method create takes nothing returns Table
        local Table this = dex.list[0]
        
        if this == 0 then
            set more = more + 1
            set this = more
        else
            set dex.list[0] = dex.list[this]
            call dex.list.remove(this)
        endif
        
        debug set dex.list[this] = -1
        return this
    endmethod
    
    // Removes all data from a Table instance and recycles its index.
    //
    //     call a.destroy()
    //
    method destroy takes nothing returns nothing
        debug if dex.list[this] != -1 then
            debug call BJDebugMsg("Table Error: Tried to double-free instance: " + I2S(this))
            debug return
        debug endif
        
        call this.flush()
        
        set dex.list[this] = dex.list[0]
        set dex.list[0] = this
    endmethod
    
endstruct
    
struct TableArray extends array
    
    //Returns a new TableArray to do your bidding. Simply use:
    //
    //    local TableArray ta = TableArray[array_size]
    //
    static method operator [] takes integer array_size returns TableArray
        local Table a = dex.size[array_size] //Get the unique recycle list for this array size
        local TableArray this = a[0]         //The last-destroyed TableArray that had this array size
        
        debug if array_size <= 0 then
            debug call BJDebugMsg("TypeError: Invalid specified TableArray size: " + I2S(array_size))
            debug return 0
        debug endif
        
        if this == 0 then
            set less = less - array_size
            set this = less
        else
            set a[0] = a[this]  //Set the last destroyed to the last-last destroyed
            call a.remove(this) //Clear hash memory
        endif
        
        set dex.size[this] = array_size //This remembers the array size
        return this
    endmethod
    
    //Returns the size of the TableArray
    method operator size takes nothing returns integer
        return dex.size[this]
    endmethod
    
    //da[integer a].unit[integer b] = unit u
    //da[integer a][integer c] = integer d
    //
    //Inline-friendly when not running in debug mode
    //
    method operator [] takes integer key returns Table
        static if DEBUG_MODE then
            local integer i = this.size
            if i == 0 then
                call BJDebugMsg("IndexError: Tried to get key from invalid TableArray instance: " + I2S(this))
                return 0
            elseif key < 0 or key >= i then
                call BJDebugMsg("IndexError: Tried to get key [" + I2S(key) + "] from outside TableArray bounds: " + I2S(i))
                return 0
            endif
        endif
        return this + key
    endmethod
    
    //Destroys a TableArray without flushing it; assumed you'd call .flush()
    //if you want it flushed too. This is public so that if you are flushing
    //instances the whole time you don't waste efficiency when disposing the
    //TableArray.
    //
    method destroy takes nothing returns nothing
        local Table a = dex.size[this.size]
        
        debug if this.size <= 0 then
            debug call BJDebugMsg("TypeError: Tried to destroy an invalid TableArray: " + I2S(this))
            debug return
        debug endif
        
        if a == 0 then
            //Create an array to index recycled instances with their array size
            set a = Table.create()
            set dex.size[this.size] = a
        endif
        
        call dex.size.remove(this) //Clear the array size from hash memory
        
        set a[this] = a[0]
        set a[0] = this
    endmethod
    
    //All you need to know about this one is that it won't hit the op limit.
    private static method clean takes Table a, integer end returns nothing
        local integer i = a + 5000
        if i < end then
            call clean.evaluate(i, end)
            set end = i
        endif
        loop
            call a.flush()
            set a = a + 1
            exitwhen a == end
        endloop
    endmethod
    
    //Flushes the TableArray and also destroys it. Doesn't get any more
    //similar to the FlushParentHashtable native than this.
    //
    method flush takes nothing returns nothing
        local integer end = this.size + this
        debug if this == end then
            debug call BJDebugMsg("TypeError: Tried to flush an invalid TableArray instance: " + I2S(this))
            debug return
        debug endif
        call clean.evaluate(this, end)
        call this.destroy()
    endmethod
    
endstruct
    
endlibrary

So the question is: Is there a chance to replace the Table From SpellEvent with the table made by Bribe? (The one from SpellEffectEvent)

Thanks and sorry for my bad english :p

EDIT: I forgot to say that SpellEffectEvent is used in this ability

JASS:
library IllusoryOrb uses RegisterPlayerUnitEvent, SpellEffectEvent, Tt, WorldBounds

//===========================================================================
//                           CONFIGURABLES
//===========================================================================

globals
    private constant integer ABIL_ID = 'A01Y' // raw code of ability "Illusory Orb"
    private constant integer DUM_ABIL_ID = 'A01W' // raw code of ability "Ethereal Jaunt"
    
    private constant integer DUMMY_ID = 'n001' // raw code of unit "Ilusory Orb Dummy"
    private constant integer RED = 255 // red vertex color of DUMMY_ID
    private constant integer GREEN = 255 // green vertex color of DUMMY_ID
    private constant integer BLUE = 255 // blue vertex color of DUMMY_ID
    private constant integer TRANS = 255 // transparency of DUMMY_ID, where 0 is fully transparent
    private constant integer SCALE = 1 // scale size of DUMMY_ID
    private constant real HEIGHT = 150. // height of DUMMY_ID
    
    private constant real SPEED = 600. // distance travelled per second by orb
    private constant real ENUM_RADIUS = 176. // max collision size of a unit in your map
    
    private constant boolean PRELOAD = true // preloads resources if true
    
    private constant attacktype ATK = ATTACK_TYPE_NORMAL // attack type
    private constant damagetype DMG = DAMAGE_TYPE_MAGIC // damage type
endglobals

// area of effect
private constant function GetArea takes integer level returns real
    return 300.0
endfunction

// damage dealt
private constant function GetDamage takes integer level returns real
    return 70.0 * level
endfunction

// distance travelled by orb
private constant function GetDistance takes integer level returns real
    return 600. + 150.0 * level
endfunction

// target types allowed for dealing damage
private constant function GetFilter takes unit caster, unit target returns boolean
    return /*
    */ not IsUnitType(target, UNIT_TYPE_DEAD) and /* // target is alive
    */ IsUnitEnemy(target, GetOwningPlayer(caster)) and /* // target is an enemy of caster
    */ not IsUnitType(target, UNIT_TYPE_STRUCTURE) and /* // target is not a structure
    */ not IsUnitType(target, UNIT_TYPE_MECHANICAL) // target is not mechanic
endfunction

//===========================================================================
//                          END CONFIGURABLES
//===========================================================================

globals
    private constant sound ERROR = CreateSoundFromLabel("InterfaceError", false, false, false, 10, 10)
    private constant player NEUTRAL_PASSIVE = Player(PLAYER_NEUTRAL_PASSIVE)
    
    private group G = bj_lastCreatedGroup
endglobals

private struct Main extends array
    private group g
    private unit u
    private unit dummy
    private real area
    private real dmg
    private real dist
    private real sin
    private real cos
    private static integer array store
    private static constant real TIMEOUT = 0.031250000
    private static constant real TRUE_SPEED = SPEED * TIMEOUT
    
    implement CTTC
        local unit u
        local real x
        local real y
    implement CTTCExpire
        set x = GetUnitX(this.dummy) + this.cos
        set y = GetUnitY(this.dummy) + this.sin
    
        if x > WorldBounds.minX and y > WorldBounds.minY and x < WorldBounds.maxX and y < WorldBounds.maxY then
            call SetUnitX(this.dummy, x)
            call SetUnitY(this.dummy, y)
        endif
        set this.dist = this.dist - TRUE_SPEED
        
        call GroupEnumUnitsInRange(G, x, y, this.area + ENUM_RADIUS, null)
        loop
            set u = FirstOfGroup(G)
            exitwhen u == null
            call GroupRemoveUnit(G, u)
            
            if not IsUnitInGroup(u, this.g) and GetFilter(this.u, u) and IsUnitInRangeXY(u, x, y, this.area) then
                call GroupAddUnit(this.g, u)
                call UnitDamageTarget(this.u, u, this.dmg, true, false, ATK, DMG, null)
            endif
        endloop
    
        if this.dist <= 0 then
            if thistype.store[GetUnitUserData(this.u)] == this then
                set thistype.store[GetUnitUserData(this.u)] = 0
            endif
        
            call GroupClear(this.g)
            call DestroyGroup(this.g)
            call KillUnit(this.dummy)
            
            set this.g = null
            
            call this.destroy()
        endif
    implement CTTCEnd

    private static method onCast takes nothing returns boolean
        local thistype this = thistype.create()
        local integer level
        local real a
        
        set this.g = CreateGroup()
        set this.u = GetTriggerUnit()
        set a = Atan2(GetSpellTargetY() - GetUnitY(this.u), GetSpellTargetX() - GetUnitX(this.u))
        set this.dummy = CreateUnit(NEUTRAL_PASSIVE, DUMMY_ID, GetUnitX(this.u), GetUnitY(this.u), a * bj_RADTODEG)
        set level = GetUnitAbilityLevel(this.u, ABIL_ID)
        set this.area = GetArea(level)
        set this.dmg = GetDamage(level)
        set this.dist = GetDistance(level)
        set this.sin = TRUE_SPEED * Sin(a)
        set this.cos = TRUE_SPEED * Cos(a)
        set thistype.store[GetUnitUserData(this.u)] = this
        
        call SetUnitVertexColor(this.dummy, RED, GREEN, BLUE, TRANS)
        call SetUnitScale(this.dummy, SCALE, 0, 0)
        call SetUnitFlyHeight(this.dummy, 100., 0)
        
        return false
    endmethod
    
    private static method onDummyCast takes nothing returns boolean
        local thistype this
    
        if thistype.store[GetUnitUserData(GetTriggerUnit())] > 0 then
            set this = thistype.store[GetUnitUserData(GetTriggerUnit())]
            set thistype.store[GetUnitUserData(this.u)] = 0
            
            call SetUnitX(this.u, GetUnitX(this.dummy))
            call SetUnitY(this.u, GetUnitY(this.dummy))
            call GroupClear(this.g)
            call DestroyGroup(this.g)
            call KillUnit(this.dummy)
            
            set this.g = null
            
            call this.destroy()
        else
            if GetLocalPlayer() == GetOwningPlayer(GetTriggerUnit()) then
                call ClearTextMessages()
                call StartSound(ERROR)
            endif
            
            call DisplayTimedTextToPlayer(GetOwningPlayer(GetTriggerUnit()), 0.52, -1., 2., "|cffffcc00No Illusory Orb found.|r")
        endif
    
        return false
    endmethod
    
    private static method onLearn takes nothing returns boolean
        if GetLearnedSkill() == ABIL_ID and GetUnitAbilityLevel(GetTriggerUnit(), ABIL_ID) == 1 then
            call UnitAddAbility(GetTriggerUnit(), DUM_ABIL_ID)
        endif
    
        return false
    endmethod

    private static method onInit takes nothing returns nothing
        static if PRELOAD then
            local unit u = CreateUnit(NEUTRAL_PASSIVE, DUMMY_ID, 0, 0, 0)
            call UnitAddAbility(u, DUM_ABIL_ID)
            call RemoveUnit(u)
            set u = null
        endif
        
        call RegisterSpellEffectEvent(ABIL_ID, function thistype.onCast)
        call RegisterSpellEffectEvent(DUM_ABIL_ID, function thistype.onDummyCast)
        call RegisterPlayerUnitEvent(EVENT_PLAYER_HERO_SKILL, function thistype.onLearn)
    endmethod
endstruct

endlibrary

and SpellEvent is used in this ability
JASS:
library Polarisation initializer Init needs TimerUtils, UnitStatus, SpellEvent
//*******************************************************************************************\\
//*******************************************************************************************\\
//*                                 Polarisation By Inferior                                *\\
//*                                                                                         *\\
//*                                          v1.0                                           *\\
//*                                                                                         *\\
//*                                 *************************                               *\\
//*                                 * Requirements:         *                               *\\
//*                                 * - JassNewGenPack      *                               *\\
//*                                 * - TimerUtils          *                               *\\
//*                                 * - UnitStatus          *                               *\\
//*                                 * - SpellEvent          *                               *\\
//*                                 *************************                               *\\
//*                                                                                         *\\
//*                                                                                         *\\
//*                                                                                         *\\
//* How To Import:                                                                          *\\
//* - Copy the Spell called 'Polarisation' into your map                                    *\\
//* - Copy the whole Triggerscript into your map                                            *\\
//* - Now change the values of the 'ABILID' to the Rawcode of the Mainability in your map   *\\
//*                                                                                         *\\
//*    Spelldescription:                                                                    *\\
//*    The Caster creates a static link between the target and himself absorbing the        *\\
//*    Targets life and converting it to Mana. The Target and the caster are pulled         *\\
//*    to the middle between their positions, while the target is disabled. The Health is   *\\
//*    absorbed during the pullphase. After they reached each other the Caster keeps up the *\\
//*    static link between him and the target. The target is now unable to move farther     *\\
//*    away than the link allows him.                                                       *\\
//*                                                                                         *\\
//*******************************************************************************************\\
//*******************************************************************************************\\
// Globals Setting

    globals
        private constant integer          ABILID        = 'A00H'
        // The AbilityId of your Mainability
        
        private constant string           LIGHTNING     = "CHIM"
        // The Lightning Effect of the static link
        
        private constant real             DEFAULTHEIGHT = 50.
        // The Height of the Lightning
        
        private constant real             DEFAULTDIST   = 150.
        // The Minimum Distance which has to be reached until the Pullphase is stopped
        
        private constant real             HEALTHTOMANA  = 0.4
        // The absorbed Health to Mana Factor 
        
        private constant real             PULLPERIOD    = 0.025
        // The Timer Period of this Spell
        
        // The 3 following variables are just important for the damage dealt in this spell
        private constant attacktype       ATKTYPE       = ATTACK_TYPE_NORMAL
        private constant damagetype       DMGTYPE       = DAMAGE_TYPE_UNIVERSAL
        private constant weapontype       WPNTYPE       = WEAPON_TYPE_WHOKNOWS
        
        private constant boolean          PULLDOWNAIR   = true
        // Set this to true weather Air units shall be pulled down to the ground.
        
        private constant boolean          CASTERACTION  = true
        // Set this to false weather the caster should be disabled aswell duration the Pullphase
        
        // For Descriptions for the following Variables see below
        private          real       array PULLDURATION
        private          real       array FIXDURATION
        private          real       array MAXRANGE    
        private          real       array DAMAGEDEALT 
    endglobals
    
    
    
    private function SetupSpellVariables takes nothing returns nothing
        // The time in which the target is pulled in the direction of the caster
        set PULLDURATION[1]=1.25
        set PULLDURATION[2]=1.75
        set PULLDURATION[3]=2.25
        set PULLDURATION[4]=3.
        
        // The time how long the target is fixed to the caster by the static link
        set FIXDURATION[1]=1.5
        set FIXDURATION[2]=2.
        set FIXDURATION[3]=2.5
        set FIXDURATION[4]=3.
        
        // The Maximum range the target can move away from the caster with the static link
        set MAXRANGE[1]=600.
        set MAXRANGE[2]=500.
        set MAXRANGE[3]=400.
        set MAXRANGE[4]=300.
        
        // The Damage dealt during the Pullphase
        set DAMAGEDEALT[1]=60.
        set DAMAGEDEALT[2]=125.
        set DAMAGEDEALT[3]=185.
        set DAMAGEDEALT[4]=250.
    endfunction
    
    // DO NOT TOUCH ANYTHING BELOW THIS COMMENT, ALTHOUGH YOU KNOW WHAT YOU DO.
    // HERE BEGINS THE SPELLS SCRIPT.
    
    private struct MagnetPull
        unit caster
        unit target
        real castX
        real castY
        real targX
        real targY
        real duration
        integer level
        lightning light
        
        static integer count=0
        static timer MagnetTimer
        static MagnetPull array Data
        static boolean array done
        
        // checks if the target is to far away from the caster
        // stops the spell when the static link time expires
        static method callback takes nothing returns nothing
            local integer int=0
            local MagnetPull data
            local real dx
            local real dy
            loop
                exitwhen int==.count
                set data=.Data[int]
                if data.duration>0 and not .done[int] and GetWidgetLife(data.target)>0.405 then
                    set dx=data.castX-data.targX
                    set dy=data.castY-data.targY
                    if SquareRoot(dx*dx+dy*dy)>MAXRANGE[data.level] then
                        set data.targX=data.castX-MAXRANGE[data.level]*Cos(Atan2(dy,dx))
                        set data.targY=data.castY-MAXRANGE[data.level]*Sin(Atan2(dy,dx))
                        call SetUnitX(data.target,data.targX)
                        call SetUnitY(data.target,data.targY)
                    else
                        set data.targX=GetUnitX(data.target)
                        set data.targY=GetUnitY(data.target)
                    endif
                    set data.castX=GetUnitX(data.caster)
                    set data.castY=GetUnitY(data.caster)
                    set data.duration=data.duration-PULLPERIOD
                    call MoveLightningEx(data.light,true,data.castX,data.castY,DEFAULTHEIGHT,data.targX,data.targY,DEFAULTHEIGHT)
                elseif data.light!=null and not .done[int] or GetWidgetLife(data.target)<0.405 and not .done[int] then
                    call DestroyLightning(data.light)
                    if PULLDOWNAIR and IsUnitType(data.target,UNIT_TYPE_FLYING) then
                        call SetUnitFlyHeight(data.target,GetUnitDefaultFlyHeight(data.target),100)
                    endif
                    set .done[int]=true
                    call data.destroy()
                endif
                set int=int+1
            endloop
        endmethod
            
        
        static method create takes nothing returns MagnetPull
            local MagnetPull data=MagnetPull.allocate()
            if .count==0 then
                set .MagnetTimer=NewTimer()
                call TimerStart(.MagnetTimer,PULLPERIOD,true,function MagnetPull.callback)
            endif
            set .Data[.count]=data
            set .count=.count+1
            return data
        endmethod
        
    endstruct
    
    private struct PolarPull 
        unit caster
        unit target
        real castX
        real castY
        real targX
        real targY
        real velZ
        real angle
        real distance
        real speed
        integer level
        lightning light
        
        static integer count=0
        static timer PullTimer
        static PolarPull array Data
        static boolean array done
        
        // pulls the target and the caster to they position between each other
        // Flying Units are pulled down if PULLDOWNAIR=true
        // When the Pullphase is over Flying units regain their default height
        static method callback takes nothing returns nothing
            local integer int=0
            local PolarPull data
            local MagnetPull dat
            loop
                exitwhen int==.count
                set data=.Data[int]
                if data.distance>DEFAULTDIST and not .done[int] and GetWidgetLife(data.target)>0.405 then
                    set data.castX=data.castX-data.speed*Cos(data.angle)
                    set data.castY=data.castY-data.speed*Sin(data.angle)
                    call SetUnitX(data.caster,data.castX)
                    call SetUnitY(data.caster,data.castY)
                    set data.targX=data.targX+data.speed*Cos(data.angle)
                    set data.targY=data.targY+data.speed*Sin(data.angle)
                    call SetUnitX(data.target,data.targX)
                    call SetUnitY(data.target,data.targY)
                    call UnitDamageTarget(data.caster,data.target,(DAMAGEDEALT[data.level]/PULLDURATION[data.level])*PULLPERIOD,true,false,ATKTYPE,DMGTYPE,WPNTYPE)
                    call SetUnitState(data.caster,UNIT_STATE_MANA,GetUnitState(data.caster,UNIT_STATE_MANA)+(DAMAGEDEALT[data.level]*HEALTHTOMANA/PULLDURATION[data.level])*PULLPERIOD)
                    if PULLDOWNAIR and IsUnitType(data.target,UNIT_TYPE_FLYING) then
                        call SetUnitFlyHeight(data.target,GetUnitFlyHeight(data.target)-data.velZ,0)
                        call MoveLightningEx(data.light,true,data.castX,data.castY,DEFAULTHEIGHT,data.targX,data.targY,GetUnitFlyHeight(data.target)+DEFAULTHEIGHT)
                    else
                        call MoveLightningEx(data.light,true,data.castX,data.castY,DEFAULTHEIGHT,data.targX,data.targY,DEFAULTHEIGHT)
                    endif
                    set data.distance=data.distance-2*data.speed
                elseif data.distance<=DEFAULTDIST and not .done[int] and GetWidgetLife(data.target)>0.405 then
                    set dat=MagnetPull.create()
                    set dat.caster=data.caster
                    set dat.target=data.target
                    set dat.castX=data.castX
                    set dat.castY=data.castY
                    set dat.targX=data.targX
                    set dat.targY=data.targY
                    set dat.light=data.light
                    set dat.level=data.level
                    set dat.duration=FIXDURATION[data.level]
                    if not CASTERACTION then
                        call DisableUnit(data.caster,false)
                    endif
                    call DisableUnit(data.target,false)
                    set .done[int]=true
                    call data.destroy()
                elseif GetWidgetLife(data.target)<0.405 and not .done[int] then
                    call DestroyLightning(data.light)
                    if not CASTERACTION then
                        call DisableUnit(data.caster,false)
                    endif
                    call DisableUnit(data.target,false)
                    set .done[int]=true
                    call data.destroy()
                endif
                set int=int+1
            endloop
        endmethod
        
        static method create takes nothing returns PolarPull
            local PolarPull data=PolarPull.allocate()
            if .count==0 then
                set .PullTimer=NewTimer()
                call TimerStart(.PullTimer,PULLPERIOD,true,function PolarPull.callback)
            endif
            set .Data[.count]=data
            set .count=.count+1
            return data
        endmethod
    
    endstruct
    
    // Executed on Spellcast
    // Disables the caster when CASTERACTION=false
    private function PolarisationSpell takes nothing returns nothing
        local unit caster=SpellEvent.CastingUnit
        local unit target=SpellEvent.TargetUnit
        local PolarPull data=PolarPull.create()
        local real dx=0.
        local real dy=0.
        set data.caster=caster
        set data.target=target
        set data.castX=GetUnitX(caster)
        set data.castY=GetUnitY(caster)
        set data.targX=GetUnitX(target)
        set data.targY=GetUnitY(target)
        set dx=data.castX-data.targX
        set dy=data.castY-data.targY
        set data.angle=Atan2(dy,dx)
        set data.distance=SquareRoot(dx*dx+dy*dy)
        set data.level=GetUnitAbilityLevel(caster,ABILID)
        set data.speed=(data.distance/PULLDURATION[data.level])*PULLPERIOD*0.5
        call DisableUnit(data.target,true)
        if not CASTERACTION then
            call DisableUnit(data.caster,true)
        endif
        call SetUnitAnimation(data.caster,"spell channel")
        if PULLDOWNAIR and IsUnitType(target,UNIT_TYPE_FLYING) then
            set data.velZ=(GetUnitFlyHeight(target)/PULLDURATION[data.level])*PULLPERIOD
            set data.light=AddLightningEx(LIGHTNING,true,data.castX,data.castY,DEFAULTHEIGHT,data.targX,data.targY,GetUnitFlyHeight(target)+DEFAULTHEIGHT)
        else
            set data.light=AddLightningEx(LIGHTNING,true,data.castX,data.castY,DEFAULTHEIGHT,data.targX,data.targY,DEFAULTHEIGHT)
            set data.velZ=0
        endif
        
        set caster=null
        set target=null
    endfunction
    
    private function Init takes nothing returns nothing
        call RegisterSpellEffectResponse(ABILID,PolarisationSpell)
        call SetupSpellVariables()
    endfunction
    
endlibrary
 
Remove the Table by Vexorian and then copy and paste this in a new trigger:
JASS:
library TableBC requires Table
/*
    Backwards-compatibility add-on for scripts employing Vexorian's Table.
    
    Disclaimer:
    
    The following error does not occur with HandleTables & StringTables, only
    with the standard, integer-based Table, so you do not need to make any 
    changes to StringTable/HandleTable-employing scripts.
    
    The this.flush(key) method from the original Table cannot be parsed with
    the new Table. For the scripts that use this method, they need to be up-
    dated to use the more fitting this.remove(key) method.
    
    Please don't try using StringTables/HandleTables with features exclusive
    to the new Table as they will cause syntax errors. I do not have any plan
    to endorse these types of Tables because delegation in JassHelper is not 
    advanced enough for three types of Tables without copying every single
    method over again (as you can see this already generates plenty of code).
    StringTable & HandleTable are wrappers for StringHash & GetHandleId, so
    just type them out.
*/

//! textmacro TABLE_BC_METHODS
    method reset takes nothing returns nothing
        call this.flush()
    endmethod
    method exists takes integer key returns boolean
        return this.has(key)
    endmethod
//! endtextmacro

//! textmacro TABLE_BC_STRUCTS
struct HandleTable extends array
    method operator [] takes handle key returns integer
        return Table(this)[GetHandleId(key)]
    endmethod
    method operator []= takes handle key, integer value returns nothing
        set Table(this)[GetHandleId(key)] = value
    endmethod
    method flush takes handle key returns nothing
        call Table(this).remove(GetHandleId(key))
    endmethod
    method exists takes handle key returns boolean
        return Table(this).has(GetHandleId(key))
    endmethod
    method reset takes nothing returns nothing
        call Table(this).flush()
    endmethod
    method destroy takes nothing returns nothing
        call Table(this).destroy()
    endmethod
    static method create takes nothing returns thistype
        return Table.create()
    endmethod
endstruct

struct StringTable extends array
    method operator [] takes string key returns integer
        return Table(this)[StringHash(key)]
    endmethod
    method operator []= takes string key, integer value returns nothing
        set Table(this)[StringHash(key)] = value
    endmethod
    method flush takes string key returns nothing
        call Table(this).remove(StringHash(key))
    endmethod
    method exists takes string key returns boolean
        return Table(this).has(StringHash(key))
    endmethod
    method reset takes nothing returns nothing
        call Table(this).flush()
    endmethod
    method destroy takes nothing returns nothing
        call Table(this).destroy()
    endmethod
    static method create takes nothing returns thistype
        return Table.create()
    endmethod
endstruct
//! endtextmacro

endlibrary
It is a backwards compatibility version to support the API used by Vex's table.

As for SpellEvent and SpellEffectEvent, they do similar things. SpellEvent also stores caster/spell data, so you can get a pseudo-OOP style reference/easier reference to the data. It also handles spell events better than using it manually.

SpellEffectEvent just handles spell events. It has an O(1)-esque approach (as in, it will only evaluate the trigger that is supposed to be evaluated in response to the spell, rather than evaluating every single trigger with a spell event). That is its only goal, and it does it well.

Sadly, because SpellEvent has other parts (storing data), you can't easily switch them. You might be able to switch Bribe's to use that, but I wouldn't recommend it. IMO just replace the Table libraries so it will compile.
 
Status
Not open for further replies.
Top