• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Spell Effect Indexer v1.5

  • Introduction
    • Are you tired of rewriting a spell indexer all over again?
    • Do you want a much easier spell indexer?
    • Then here it is, the Spell Indexer!
    • This helps users who uses a dynamic indexing and linked list for their spells.
  • Features
    • Spell Effect Event with corresponding Event variables for better retrieving
    • Easy registering spells
    • Auto registers looping timer event for every trigger with looping
  • Requires:
  • Code
    JASS:
    //************************************************************************************
    //*
    //*
    //*                      SPELL EFFECT INDEXER
    //*
    //*                             BY : ALMIA
    //*
    //*
    //************************************************************************************
    //*
    //*    Indexes every instance created by a casted spell/ ability
    //*
    //************************************************************************************
    //*
    //*    Requires:
    //*
    //*    Linked List Table = http://www.hiveworkshop.com/forums/spells-569/linked-list-table-v1-2-a-230076/
    //*
    //************************************************************************************
    //*
    //*    Code API
    //*
    //*    constant function SpellDefaultTimeout takes nothing returns real
    //*        - System default timeout for looping spells
    //*
    //*    function TriggerRegisterSpellEffect takes integer spell, trigger onEffect, trigger onLoop  returns nothing
    //*
    //*        - Registers the spell to the system
    //*        - Also, it registers the triggers being evaluated and looped
    //*        - Creates linked lists for every spell registered
    //*
    //*    function RegisterSpellEffect takes integer spell, code onEffect ,code onLoop returns nothing
    //*        - Same goes to TriggerRegisterSpellEffect, though uses code
    //* 
    //*    function OnSpellEffect takes nothing returns boolean
    //*
    //*        - System trigger condition
    //*        - Evaluates the triggers for every spell casted
    //*        - Creates new indexed instance for multi instancability
    //*
    //*    function RecycleSpellIndex takes integer spell, integer index returns nothing 
    //*
    //*        - Recycles the spell's current index
    //*        - Used when the spell's effect ends in the loop
    //*
    //*    function GetSpellNewIndex takes integer spell returns integer
    //*
    //*        - Wrapper for SpellEffectEventIndex
    //*        - Created in case the SpellEffectEventIndex is overwritten
    //*
    //*    function SpellGetFirst takes integer a returns integer
    //*
    //*        - Gets the starting index of the spell's linked list
    //*
    //*    function SpellGetNext takes integer a, integer index returns integer
    //*
    //*        - Gets the next index of the given index from a spell's linked list
    //*
    //*
    //************************************************************************************
    //*
    //*    ITERATION MODULE
    //*
    //*    All variables in between "$" will be replaced by your own variables
    //*    Must be CnPed
    //*
    //*    Variables required:
    //*
    //*    $SPELL$ = your Spell
    //*    $INDEX$ = Your Index variable
    //*
    //*    =====================================================================
    //*
    //*    set $INDEX$ = SpellGetFirst($SPELL$)
    //*
    //*    loop
    //*    
    //*        exitwhen 0 == $INDEX$
    //*
    //*        ( YOUR CODE HERE )
    //*
    //*        ( IF YOUR SPELL'S EFFECT HAS ENDED )
    //*        ( MAKE SURE TO USE "call RecycleSpellIndex($SPELL$, $INDEX$)
    //*
    //*        set $INDEX$ = SpellGetNext($SPELL$, $INDEX$)
    //*
    //*    endloop
    //*
    //*    =====================================================================
    //*
    //************************************************************************************
    //*
    //*    NOTES:
    //*
    //*    - Registers spells only in map initialization triggers.
    //*    - Do not register any events in your trigger which will have the spell's effect
    //*    - Do not register any events in your spell effect loop trigger
    //*    - Iteration module must be followed when iterating instances
    //*    - You can uses either GetSpellNewIndex or SpellEffectEventIndex to get
    //*      the spell being casted
    //*    - Use SpellEffectEventAbility to retrieve the casted spell
    //*
    //************************************************************************************
    //*
    //*    Variables : 
    //*
    //*    SpellEffectEventIndex   = Integer
    //*    SEI_Table = Hashtable
    //*
    //************************************************************************************
    constant function SpellDefaultTimeout takes nothing returns real
        return 0.031250000
    endfunction
    
    //************************************************************************************
    
    function OnSpellEffect takes nothing returns boolean
    
        // Locals
        local integer spell = GetSpellAbilityId()
        local integer count
        local trigger t
        
        if HaveSavedBoolean(udg_SEI_Table, spell, 0) then
    
            set t = LoadTriggerHandle(udg_SEI_Table, spell, 1)
            //Evaluating trigger with event-related variables
    
            set udg_SpellEffectEventIndex = GetNewIndexFromLinkedList(LoadInteger(udg_SEI_Table, spell, 0))
    
            //In case EventIndex is overwritten, save variable
            call SaveInteger(udg_SEI_Table, spell, 4, udg_SpellEffectEventIndex)
        
            //Start evaluating
            if TriggerEvaluate(t) then
                call TriggerExecute(t)
            endif
    
            set t = null
        
            //Count instances
            set count = LoadInteger(udg_SEI_Table, spell, 3) + 1
            call SaveInteger(udg_SEI_Table, spell, 3, count)
    
            //If instances counted is equal to 1
            //then turn on the looping trigger
    
            if 1 == count then
                call EnableTrigger(LoadTriggerHandle(udg_SEI_Table, spell, 2))
            endif
        endif
        return false
    endfunction
    
    //************************************************************************************
    
    function InitSpellIndexer takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( t, Filter(function OnSpellEffect))
        set udg_SEI_Table = InitHashtable()
        set t = null
    endfunction
    
    //************************************************************************************
    
    function TriggerRegisterSpellEffect takes integer spell, trigger onEffect, trigger onLoop  returns nothing
        if null == udg_SEI_Table then
            call InitSpellIndexer()
        endif
        call SaveBoolean(udg_SEI_Table, spell, 0, true)
    
        // Creating new linked list for the registered ability
        call SaveInteger(udg_SEI_Table, spell, 0, CreateLinkedList())
    
        // Saving trigger related to spell
        call SaveTriggerHandle(udg_SEI_Table, spell, 1, onEffect)
        call SaveTriggerHandle(udg_SEI_Table, spell, 2, onLoop)
    
        // registering looping event
        call TriggerRegisterTimerEvent(onLoop, SpellDefaultTimeout(), true)
    endfunction
    
    //************************************************************************************
    
    function RegisterSpellEffect takes integer spell, code onEffect ,code onLoop returns nothing
        local trigger t = CreateTrigger()
        local trigger t2 = CreateTrigger()
        call TriggerAddCondition(t, Condition(onEffect))
        call TriggerAddCondition(t, Condition(onLoop))
        call TriggerRegisterSpellEffect(spell, t, t2)
        set t = null
        set t2 = null
    endfunction
    
    //************************************************************************************
    
    function RecycleSpellIndex takes integer spell, integer index returns nothing 
        
        // Recycling Instance
        local integer count = LoadInteger(udg_SEI_Table, spell, 3) - 1
        call RecycleIndexFromLinkedList(LoadInteger(udg_SEI_Table, spell, 0), index)
        call SaveInteger(udg_SEI_Table, spell, 3, count)
    
        // If number of instance counted is equal to 0
        // Disable trigger
        if 0 == count then
            call DisableTrigger(LoadTriggerHandle(udg_SEI_Table, spell, 2))
        endif
    endfunction
    
    //************************************************************************************
    //*
    //*                       EXTRA FUNCTIONS or UTILS
    //*
    //************************************************************************************
    
    // SPELL EFFECT EVENT RELATED
    function GetSpellNewIndex takes integer spell returns integer
        return LoadInteger(udg_SEI_Table, spell, 4)
    endfunction
    
    // ITERATION RELATED
    function SpellGetFirst takes integer a returns integer
        return GetFirstIndexFromLinkedList(LoadInteger(udg_SEI_Table, a, 0))
    endfunction
    
    function SpellGetNext takes integer a, integer index returns integer
        return GetNextIndexFromLinkedList(LoadInteger(udg_SEI_Table, a, 0), index)
    endfunction
    
    //************************************************************************************
  • Demo
      • TC Start
        • Events
          • Map initialization
        • Conditions
        • Actions
          • Custom script: call RegisterSpellEffect('AHtc', gg_trg_TC_Cast , gg_trg_TC_Loop)
      • TC Cast
        • Events
        • Conditions
        • Actions
          • Set TC_Index = SpellEffectEventIndex
          • Set TC_U[TC_Index] = (Triggering unit)
          • Set TC_Time[TC_Index] = 0.00
          • Set TC_Duration[TC_Index] = 10.00
      • TC Loop
        • Events
        • Conditions
        • Actions
          • Custom script: set udg_TC_Index = SpellGetFirst('AHtc')
          • Custom script: loop
          • Custom script: exitwhen 0 == udg_TC_Index
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • TC_Time[TC_Index] Less than TC_Duration[TC_Index]
            • Then - Actions
              • Custom script: set udg_TC_Time[udg_TC_Index] = udg_TC_Time[udg_TC_Index] + SpellDefaultTimeout()
              • Set TC_Loc = (Position of TC_U[TC_Index])
              • Special Effect - Create a special effect at TC_Loc using Abilities\Spells\Orc\MirrorImage\MirrorImageCaster.mdl
              • Special Effect - Destroy (Last created special effect)
              • Custom script: call RemoveLocation(udg_TC_Loc)
            • Else - Actions
              • Custom script: call RecycleSpellIndex('AHtc', udg_TC_Index)
              • Set TC_U[TC_Index] = No unit
              • Set TC_Duration[TC_Index] = 0.00
              • Set TC_Time[TC_Index] = 0.00
          • Custom script: set udg_TC_Index = SpellGetNext('AHtc',udg_TC_Index)
          • Custom script: endloop
  • Installing
    • Install Linked List Table
    • Copy the Spell Effect Indexer trigger.
    • Create variables listed in the code
  • Changelogs
    • Updated system due to Linked List Table's update.
    • Updated due to Linked List Table's update
    • Code simplified
    • - New Update -
    • Now supports codes
    • Updated to get rid of Wacraft III Header compiler's bug
Contents

SpellEffect Indexer v1.5 (Map)

Reviews
23:02, 2nd Jan 2013 Magtheridon96: Approved, but change the function names used for iteration. They're too short and general. Add more words to them. Something like SpellInstanceListGetFirst and SpellInstanceListGetNext.

Moderator

M

Moderator

23:02, 2nd Jan 2013
Magtheridon96: Approved, but change the function names used for iteration. They're too short and general. Add more words to them. Something like SpellInstanceListGetFirst and SpellInstanceListGetNext.
 
Level 4
Joined
Nov 13, 2012
Messages
28
Very nice system, very hepful for me because I'm a bit bored to do an index system for each spell that I make.

But got a problem, tried the system with a spell which has a bad indexing system and the loop just bugged

1) The dummy always move from a 360° angle (his going to the right, not doing a circle)

2) When the spell is casted likes any MUI spell others instances stop from moving, continue from doing specials effects and don't disappears.

So I dunno why this happen because I done these:

You must add first the raw code id of your wanted spell inside the SI_AbilLib.Every time you put an ability,make sure to use custom script: call SI_RegisterAbil() to register it.
to use the spell effect, add the real value event Game - SpellIndexerEvent becomes Equal to 1.00 to run the effect.Make sure to add the condition SpellIndexerEventAbility Equal to My Ability for your spell to work.
To use the loop,register the event Game - SpellIndexerEvent becomes Equal to 2.00
for you to use the loop.Use the integer SpellIndexerEventLoopIndex for you to use the temp index.You can cache it if you want.If the spell effect of yours end,just run the trigger Recycle Index to recycle the indexer.
 
Last edited:

BUP

BUP

Level 9
Joined
Sep 9, 2012
Messages
172
That's ok.I'm not making spells today,tomorrow and the day after tomorrow
and

  • BUP TIMER
    • Events
      • Time - Every 1 day
    • Conditions
      • ((BUP) is alive) Equal to True
    • Actions
      • Set TDAT = TDAT + 1
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • TDAT is greater than TDAT
        • Then - Actions
          • Unit - Make BUP to make more spells
        • Else - Actions
          • Unit - Make BUP to rest
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • TDAT Equal to 30
        • Then - Actions
          • Trigger - Run BUP Revive(ignoring conditions)
        • Else - Actions


  • BUP Revive
    • Events
    • Conditions
    • Actions
      • Unit - Make BUP to make more spells
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
but still dont got the sense, with this way too u must trigger every spell, no?
then what the difference between this and make trigger spells where Magtheridon96 spellevent system make events for each triggered spell?

what i dont see where is the advantage between this and make mui spell without indexing?
you can show a example where the indexer make it easier and faster the triggered spell? (a normal example with exact data)
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
but unknow variables is auto created even, i often use for this a blank trigger, and put there every variable what i used in jass, and when i copy it then variables are created.

ah you mean if user do more similiar ability then dont need use different variables for special effect/point, caster because it is already in this system?
 
Top