• 🏆 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!

[Solved] SpellEffectEvent Compile Errors ://

Status
Not open for further replies.
Level 20
Joined
Aug 13, 2013
Messages
1,696
I'm new at vJASS and I'm now practicing using vJASS Systems like Tables,


I'm now trying to learn how to use SpellEffectEvent but it does shows me a compile errors.

Here is my following system used:
I'm using Table 1.3 by Vexorian.
I'm using AbilityPreload
I'm using RegisterPlayerUnitEvent by Magtheridon96
I'm using SpellEffectEvent by Bribe

Here is the screenshot of the error:

231860-albums6686-picture75322.png



Here is the code of the SpellEffectEvent:

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


Here is the code of the RegisterPlayerUnitEvent:

JASS:
/**************************************************************
*
*   RegisterPlayerUnitEvent
*   v5.1.0.1
*   By Magtheridon96
*
*   I would like to give a special thanks to Bribe, azlier
*   and BBQ for improving this library. For modularity, it only 
*   supports player unit events.
*
*   Functions passed to RegisterPlayerUnitEvent must either
*   return a boolean (false) or nothing. (Which is a Pro)
*
*   Warning:
*   --------
*
*       - Don't use TriggerSleepAction inside registered code.
*       - Don't destroy a trigger unless you really know what you're doing.
*
*   API:
*   ----
*
*       - function RegisterPlayerUnitEvent takes playerunitevent whichEvent, code whichFunction returns nothing
*           - Registers code that will execute when an event fires.
*       - function RegisterPlayerUnitEventForPlayer takes playerunitevent whichEvent, code whichFunction, player whichPlayer returns nothing
*           - Registers code that will execute when an event fires for a certain player.
*       - function GetPlayerUnitEventTrigger takes playerunitevent whichEvent returns trigger
*           - Returns the trigger corresponding to ALL functions of a playerunitevent.
*
**************************************************************/
library RegisterPlayerUnitEvent // Special Thanks to Bribe and azlier
    globals
        private trigger array t
    endglobals
    
    function RegisterPlayerUnitEvent takes playerunitevent p, code c returns nothing
        local integer i = GetHandleId(p)
        local integer k = 15
        if t[i] == null then
            set t[i] = CreateTrigger()
            loop
                call TriggerRegisterPlayerUnitEvent(t[i], Player(k), p, null)
                exitwhen k == 0
                set k = k - 1
            endloop
        endif
        call TriggerAddCondition(t[i], Filter(c))
    endfunction
    
    function RegisterPlayerUnitEventForPlayer takes playerunitevent p, code c, player pl returns nothing
        local integer i = 16 * GetHandleId(p) + GetPlayerId(pl)
        if t[i] == null then
            set t[i] = CreateTrigger()
            call TriggerRegisterPlayerUnitEvent(t[i], pl, p, null)
        endif
        call TriggerAddCondition(t[i], Filter(c))
    endfunction
    
    function GetPlayerUnitEventTrigger takes playerunitevent p returns trigger
        return t[GetHandleId(p)]
    endfunction
endlibrary


Here is the demo code of the spell:

JASS:
library FireBlow requires AbilityPreload, Table, SpellEffectEvent


globals
    private HandleTable tab
endglobals
    
globals
    
    private constant integer ABILITY_ID = 'A000'
    private constant integer MISSILE_ID = 'u000'
    private constant string  EXPLOSION_EFFECT = "Abilities\\Spells\\Human\\FlakCannons\\FlakTarget.mdl"
    private constant real MISSILE_DAMAGE = 100.
    private constant real MISSILE_BASE_SPEED = 10.
    private constant real MISSILE_PER_LEVEL_SPEED = 10.
    private constant real MISSILE_DETECTRANGE = 50
    private constant real INTERVAL = 0.03125000
    
endglobals


private function GetMissileDamage takes integer lvl returns real
    return MISSILE_DAMAGE * lvl
endfunction


private function GetMissileSpeed takes integer lvl returns real
    return MISSILE_BASE_SPEED + MISSILE_PER_LEVEL_SPEED * lvl
endfunction



private struct SpellData


    unit caster
    unit target
    unit missile
    real speed
    real detect
    real damage
    real castX
    real castY
    integer level
    
    // Spell Loop //
    
    private static method Loop takes nothing returns nothing
        
        local timer tmr = GetExpiredTimer ( )
        local thistype this = tab[tmr]
        
        local real missileX = GetWidgetX ( this.missile )
        local real missileY = GetWidgetY ( this.missile )
        
        local real targX = GetWidgetX ( this.target )
        local real targY = GetWidgetY ( this.target )
        
        local real angle = Atan2( targY - missileY, targX - missileX )         
        
        call SetUnitX ( this.missile, missileX + this.speed * Cos ( angle ) )
        call SetUnitY ( this.missile, missileY + this.speed * Sin ( angle ) )
        
        call SetUnitFacing ( this.missile, angle * bj_RADTODEG )
        
        if SquareRoot ( ( targX - missileX ) * ( targX - missileX ) + ( targY - missileY ) * ( targY - missileY ) ) <= this.detect then
            
            call KillUnit ( this.missile )
            call UnitDamageTarget ( this.caster, this.target, this.damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null )
            
            call tab.flush(tmr)
            
            call this.deallocate()
            
            call PauseTimer(tmr)
            call DestroyTimer(tmr)
        
        endif
        
        set tmr = null
    endmethod

    // Spell Execution //

    private static method onCast takes nothing returns boolean
        
        local timer    tmr           = CreateTimer()
        local thistype this
        
        
        local real     angle2
        local real     targX2
        local real     targY2
        
        if GetSpellAbilityId() == ABILITY_ID then
        
        set this = thistype.allocate()
        
        set            this.caster   =  u
        set            this.target   =  targ
        set            this.level    =  lvl
        set            this.castX    =  GetWidgetX ( this.caster )
        set            this.castY    =  GetWidgetY ( this.caster )
        
        set            this.speed    =  GetMissileSpeed(this.level)
        set            this.damage   =  GetMissileDamage(this.level)
        set            this.detect   =  MISSILE_DETECTRANGE
        
        set            targX2        =  GetWidgetX ( this.target )
        set            targY2        =  GetWidgetY ( this.target )
        set            angle2        =  Atan2 ( targY2 - this.castY, targX2 - this.castX ) * bj_RADTODEG 
        
        set            this.missile  =  CreateUnit ( GetOwningPlayer ( this.caster ), MISSILE_ID, this.castX, this.castY, angle2 )
        
        set            tab[tmr]      =  this
        
        call TimerStart ( tmr, INTERVAL, true, function thistype.Loop )
        
        set            tmr = null
    
        endif
    
        return false
    endmethod



// Spell Initialization //
    private static method onInit takes nothing returns nothing
    
        call RegisterSpellEffectEvent( ABILITY_ID , Condition ( function thistype.onCast ) )
        set tab = HandleTable.create()
        call AbilityPreload ( ABILITY_ID )

    endmethod
    
endstruct


endlibrary


Links, Suggestions, Fixes are much appreciated.
 
Last edited:
Level 22
Joined
Sep 24, 2005
Messages
4,821
I honestly don't know how to use it either, so the best action here is to read the documentation on Bribe's table. Good luck!
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
TriggerEvaluate(.tb.trigger[GetSpellAbilityId()]) should be call TriggerEvaluate(tb.trigger[GetSpellAbilityId()])

and I think

library SpellEffectEvent requires RegisterPlayerUnitEvent, optional Table should be library SpellEffectEvent requires RegisterPlayerUnitEvent optional Table



That won't change anything...

edit
I met the same problem myself, you could just turn this line:
library SpellEffectEvent requires RegisterPlayerUnitEvent, optional Table
into this line:
library SpellEffectEvent requires RegisterPlayerUnitEvent//, optional Table

nor will that
 
Level 9
Joined
Dec 12, 2007
Messages
489
you're right, I looked on my edited version, this is what it looked like:
JASS:
//============================================================================
// SpellEffectEvent
// - Version 1.1.0.0
//
// API
// ---
//     RegisterSpellEffectEvent(integer abil, code onCast)
//
// Requires
// --------
//     RegisterPlayerUnitEvent: hiveworkshop.com/forums/showthread.php?t=203338
//
// Optional
// --------
//     Table: hiveworkshop.com/forums/showthread.php?t=188084
//
library SpellEffectEvent requires RegisterPlayerUnitEvent//, optional Table

//============================================================================
private module M
   
//    static if LIBRARY_Table then
//        static Table tb
//    else
        static hashtable ht = InitHashtable()
//    endif
   
    static method onCast takes nothing returns nothing
//        static if LIBRARY_Table then
//            call TriggerEvaluate(.tb.trigger[GetSpellAbilityId()])
//        else
            call TriggerEvaluate(LoadTriggerHandle(.ht, 0, GetSpellAbilityId()))
//        endif
    endmethod
 
    private static method onInit takes nothing returns nothing
//        static if LIBRARY_Table then
//            set .tb = Table.create()
//        endif
        call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function thistype.onCast)
    endmethod
endmodule

//============================================================================
private struct S extends array
    implement M
endstruct

//============================================================================
function RegisterSpellEffectEvent takes integer abil, code onCast returns nothing
//    static if LIBRARY_Table then
//        if not S.tb.handle.has(abil) then
//            set S.tb.trigger[abil] = CreateTrigger()
 //       endif
 //       call TriggerAddCondition(S.tb.trigger[abil], Filter(onCast))
 //   else
        if not HaveSavedHandle(S.ht, 0, abil) then
            call SaveTriggerHandle(S.ht, 0, abil, CreateTrigger())
        endif
        call TriggerAddCondition(LoadTriggerHandle(S.ht, 0, abil), Filter(onCast))
//    endif
endfunction
 
endlibrary
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
Thanks dark-axl, nestharus, and triggerhappy. I'll try all of your suggestions later ^^ ( I am in mobile right now xD )
+rep


EDIT:
The problem is now solved, I'll only use Table in the SpellEffectEvent and I download the TimerUtils by Vexorian to attach the integer data. Thanks Everyone =). Solved
 
Last edited:
Status
Not open for further replies.
Top