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

[vJASS] Attaching integer data from TimerUtils than Table

Status
Not open for further replies.
Level 20
Joined
Aug 13, 2013
Messages
1,696
Is there any difference when attaching integer data to the TimerUtils like this?
set tmr = NewTimerEx(this) than Table by Bribe?

I have this systems in my spell.
DelFx
Table by Bribe
RegisterPlayerUnitEvent
SpellEffectEvent
TimerUtils
AbilityPreload.

Here is the demo code of my vJASS spell:
Pls if you can tell me if there's any mistake or wrong or problem about coding so that I'll fix it properly ^^.

JASS:
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//                 F I R E  B L O W                                                                    //
//                       v1.0                                                                          //
/////////////////////////////////////////////////////////////////////////////////////////////////////////

//Information:

// Spell Author: jakeZinc
// Spell Purpose: Creating a stampede creature that will travel along to the target Location
//                during stampede creature is running, nearby enemy units to the stampede creature 
//                will be damaged and stunned. When the stampede creature reaches the target location
//                it will cause an area damage and knockbacking nearby units to the target.
//
// Spell Changelogs:  v1.0: Initial Release
//                
//
// How to Import:
// Copy and Paste:
// Object Editor - Abilities - Stampede
// Object Editor - Units - Stampede Missile
// Trigger Editor - Folder - Libraries
// Trigger Editor - Folder - Stampede [ vJASS ] v1.0



/*************************************************************************************************************/
/*************************************************************************************************************/
library FireBlow requires /*      Required Libraries
                                 -*/ AbilityPreload /*
                                 -*/ DelFX /*
                                 -*/ SpellEffectEvent/*
                                 -*/ Table /*
                                 -*/ TimerUtils
                                 
/*************************************************************************************************************/                       
/*************************************************************************************************************/
    
globals
    
    private constant integer ABILITY_ID = 'A000'
    private constant integer MISSILE_ID = 'u000'
    private constant string  EXPLOSION_EFFECT = "Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl"
    private constant string  EXPLOSION_EFFECT_ATTACH = "origin"
    private constant string  CASTER_EFFECT = "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.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
    private constant real IMPACT_RADIUS = 300.00
    private constant real IMPACT_DAMAGE = 150.00
    
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
    
    
    
    static method filterUnit takes unit caster, unit picked returns boolean
         
         return /*
        */ IsUnitEnemy(picked, GetOwningPlayer(caster)) and /*
        */ not IsUnitType(picked, UNIT_TYPE_DEAD) and GetUnitTypeId(picked) != 0 and /*
        */ not IsUnitType(picked, UNIT_TYPE_STRUCTURE) and /*
        */ not IsUnitType(picked, UNIT_TYPE_MAGIC_IMMUNE) and /*
        */ not IsUnitType(picked, UNIT_TYPE_FLYING)
    
    endmethod
    
    // Spell Loop //
    
    private static method onLoop takes nothing returns nothing
        
        local timer tmr = GetExpiredTimer ( )
        local thistype this = GetTimerData(tmr)
        
        local unit p
        
        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 CreateDelayedEffectTarget ( EXPLOSION_EFFECT, this.target, EXPLOSION_EFFECT_ATTACH, 0.03, 0.03 )
            call KillUnit ( this.missile )
            call UnitDamageTarget ( this.caster, this.target, this.damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null )
            
            call GroupEnumUnitsInRange( bj_lastCreatedGroup, targX, targY, IMPACT_RADIUS, null )
                loop
                    
                    set p = FirstOfGroup(bj_lastCreatedGroup)
                    
                    exitwhen p == null
                        
                        if thistype.filterUnit ( this.caster, p ) then
                            call UnitDamageTarget ( this.caster, p, IMPACT_DAMAGE, true,false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null ) 
                        endif
                    call GroupRemoveUnit( bj_lastCreatedGroup, p )
                endloop

            
            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
        local thistype this
        
        
        local real     angle2
        local real     targX2
        local real     targY2
        
        if GetSpellAbilityId() == ABILITY_ID then
        
        set this = thistype.allocate()
        
        set            this.caster   =  GetTriggerUnit()
        set            this.target   =  GetSpellTargetUnit()
        set            this.level    =  GetUnitAbilityLevel( this.caster, ABILITY_ID )
        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 )
        
        call CreateDelayedEffect(CASTER_EFFECT, this.castX, this.castY, 0.03, 0.03)
        

        
        set tmr = NewTimerEx(this)
        
        call TimerStart( tmr, INTERVAL, true, function thistype.onLoop)
        
        set            tmr = null
    
        endif
    
        return false
    endmethod



// Spell Initialization //
    private static method onInit takes nothing returns nothing
        
        call RegisterSpellEffectEvent( ABILITY_ID , function thistype.onCast  )
        call AbilityPreload ( ABILITY_ID )


    endmethod
    
endstruct


endlibrary

Remember that I'm new to vJASS world :D!
 
Level 8
Joined
Feb 3, 2013
Messages
277
i think it looks good man :) except I think timerUtils has had some problems with new versions of Table in my experience

using RegisterSpellEffectEvent function allows you to not have deal with if GetUnitAbilityLevel(x, '') == ABIL_ID then and it also doesn't require returning a boolean value or anything
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
@Nestharus

I'm using TimerUtils (red+blue+orange flavors for 1.24b+) v2.0 ^^

@msongyboi

Will try that ;).

EDIT:

Can I use GUI System??? that uses udg_ prefixes??
Example: Knockback System GUI
 
TimerUtils is for both storage and for timer recycling. Table is just for storage.

What Nes meant by "version" is that the storage system of TimerUtils behaves differently depending on which "flavor" you choose. By default, it is set to blue (USE_HASHTABLE = true), which means that it saves through a hashtable. You could use Table for the same thing if you want.

However, if USE_HASHTABLE is false, then it will use an array and index with the timer's id - some offset. The problem with it is that you have to worry about maps with over 8190 handles because the timer has a chance of getting an offset out of the array's index. It doesn't happen often since TimerUtils initializes timers on init but it is still a risk to take note of. It is a little faster than hashtables, but the speed difference is negligible. I prefer the stability of hashtables. If "use flexible offset" is true (and use hashtable is false), then it will reduce the chance of the index issue by adjusting the "offset" subtracted from the timer id.

You can read more about it in the TimerUtils documentation (in the actual script). Usually I just leave it as it is.

EDIT: Yeah you can use GUI systems.
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
-Some people recommend x < y*y rather than SquareRoot(x) < y since apparently sqrt is slow
-Shouldn't you use ReleaseTimer from timer utils and not pause/destroy the timer
-I don't think you can pick units that have unit type id of 0 so no need to check it. Only if the same group is enumed later should the id be checked as only then can the group contain such units
-I recommend CTL by Nestharus since the period is so low. Each instance does not need its own timer
 
Status
Not open for further replies.
Top