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

[JASS] How to create hashtable

Status
Not open for further replies.
Level 6
Joined
Jan 2, 2015
Messages
171
I am trying to copy JASS spell based. how do i create hashtable on it? what trigger should i use to make it work? please look at instruction below

JASS:
// CONFIGURATION

// Constants

// Main spell raw code
constant function FF_GetSpellID takes nothing returns integer
    return 'A004'
endfunction

// Field Effect
constant function FF_FieldFx takes nothing returns string
    return "war3mapimported\\FreezingField.mdx" 
endfunction

// Explosion Effect
constant function FF_ExpFx takes nothing returns string
    return "war3mapimported\\SnowyBlizzardTarget.mdx"
endfunction

// Explosion Effect delay
constant function FF_ExpDelay takes nothing returns real
    return 0.8
endfunction

// Explosion Interval
constant function FF_Interval takes nothing returns real
    return 0.05
endfunction

// Booleans

function FF_FilterUnit takes player casterowner, unit u returns boolean
    return IsUnitEnemy(u, casterowner) and not IsUnitType (u, UNIT_TYPE_DEAD) and GetUnitAbilityLevel(u, 'Avul') == 0 and not IsUnitType (u, UNIT_TYPE_MAGIC_IMMUNE)
endfunction

// Get spell level

function FF_SpellLvl takes unit caster returns integer
    return GetUnitAbilityLevel (caster, FF_GetSpellID()) // Get the spell level of the caster
endfunction

// Level dependable values

function FF_Duration takes integer level returns real
    return 5.
endfunction

function FF_ExpDmg takes integer level returns real
    return 100. + level*20.
endfunction

function FF_ExpAoE takes integer level returns real
    return 100. + level*20.
endfunction

function FF_FieldAoe takes integer level returns real
    return 400. + level*50.
endfunction

// Attack - Damage - Weapon type

function FF_AttackType takes nothing returns attacktype
    return ATTACK_TYPE_NORMAL
endfunction

function FF_DamageType takes nothing returns damagetype
    return DAMAGE_TYPE_MAGIC
endfunction

function FF_WeaponType takes nothing returns weapontype
    return WEAPON_TYPE_WHOKNOWS
endfunction

// END CONFIGURATION

// SPELL FUNCTIONS

// This is the main function of the spell

function FF_TimerLoop takes nothing returns nothing
    local integer ID
    local integer ID2
    local integer listmax = LoadInteger(udg_FF_Hashtable, -1, 0 )
    local unit caster
    local integer i = 0
    local unit u
    local real x
    local real y
    local real x1
    local real y1
    local integer level
    local real t
    local integer j
    local integer modifier
    local real r

    // Now we start looping through all the spell instances
    loop
        exitwhen i >= listmax

        // First we load the saved values of a spell instance
        set i = i + 1
        set ID = LoadInteger(udg_FF_Hashtable, -1, i)
        set caster = LoadUnitHandle(udg_FF_Hashtable, ID, 1)
        set x = LoadReal(udg_FF_Hashtable, ID, 2)
        set y = LoadReal(udg_FF_Hashtable, ID, 3)
        set level = FF_SpellLvl(caster)
        set t = LoadReal(udg_FF_Hashtable, ID, 5)
        set j = LoadInteger(udg_FF_Hashtable, ID, 6)

        if t >= FF_Duration(level) then
            call DestroyEffect(LoadEffectHandle(udg_FF_Hashtable, ID, 4))

            if listmax != i then
                call SaveInteger(udg_FF_Hashtable, LoadInteger(udg_FF_Hashtable, -1, listmax), 0, i)
                call SaveInteger(udg_FF_Hashtable, -1, i, LoadInteger(udg_FF_Hashtable, -1, listmax))
                call RemoveSavedInteger(udg_FF_Hashtable, -1, listmax)
                set i = i - 1
            endif

            set listmax = listmax - 1
            call SaveInteger(udg_FF_Hashtable, -1, 0, listmax)

            if LoadInteger(udg_FF_Hashtable, 0, 0) + 1 == LoadInteger(udg_FF_Hashtable, 0, -1) then
                call FlushChildHashtable(udg_FF_Hashtable, 0)
                call PauseTimer(LoadTimerHandle(udg_FF_Hashtable, -2, 0))
            else
                call SaveInteger (udg_FF_Hashtable, 0, 0, LoadInteger(udg_FF_Hashtable, 0, 0) + 1)
                call SaveInteger(udg_FF_Hashtable, 0, LoadInteger(udg_FF_Hashtable, 0, 0), ID)
            endif

            call FlushChildHashtable(udg_FF_Hashtable, ID)

        else
 
            if LoadBoolean(udg_FF_Hashtable, ID, 7) then
                set r = LoadReal(udg_FF_Hashtable, ID, 10)

                if r >= FF_ExpDelay() then
                    call GroupEnumUnitsInRange(udg_FF_Group, LoadReal(udg_FF_Hashtable, ID, 8), LoadReal(udg_FF_Hashtable, ID, 9), FF_ExpAoE(level), null)

                    loop
                        set u = FirstOfGroup(udg_FF_Group)
                        exitwhen u == null

                        if FF_FilterUnit (GetOwningPlayer(caster), u) and IsUnitVisible(u, GetOwningPlayer(caster)) then
                            call UnitDamageTarget(caster, u, FF_ExpDmg(level), false, false, FF_AttackType(), FF_DamageType(), FF_WeaponType())
                        endif

                        call GroupRemoveUnit(udg_FF_Group, u)
                    endloop

                    if listmax != i then
                        call SaveInteger (udg_FF_Hashtable, LoadInteger (udg_FF_Hashtable, -1, listmax), 0, i)
                        call SaveInteger (udg_FF_Hashtable, -1, i, LoadInteger (udg_FF_Hashtable,-1, listmax))
                        call RemoveSavedInteger (udg_FF_Hashtable, -1, listmax)
                        set i = i - 1
                    endif

                    set listmax = listmax - 1
                    call SaveInteger (udg_FF_Hashtable, -1, 0, listmax )

                    if LoadInteger (udg_FF_Hashtable, 0, 0) + 1 == LoadInteger (udg_FF_Hashtable, 0, -1) then
                        call FlushChildHashtable (udg_FF_Hashtable, 0) 
                        call PauseTimer (LoadTimerHandle (udg_FF_Hashtable, -2, 0))
                    else
                        call SaveInteger (udg_FF_Hashtable, 0, 0, LoadInteger(udg_FF_Hashtable, 0, 0) + 1)
                        call SaveInteger (udg_FF_Hashtable, 0, LoadInteger(udg_FF_Hashtable, 0, 0), ID)
                    endif

                    call FlushChildHashtable (udg_FF_Hashtable, ID)
                else
                    call SaveReal(udg_FF_Hashtable, ID, 10, r + FF_Interval())
                endif

            else

                set modifier = j - (j/4)*4
                set x1 = x + GetRandomReal (135, FF_FieldAoe(FF_SpellLvl(caster)))*Cos(GetRandomReal(-90, 0) + modifier*90.)
                set y1 = y + GetRandomReal (135, FF_FieldAoe(FF_SpellLvl(caster)))*Sin(GetRandomReal(-90, 0) + modifier*90.)
                call DestroyEffect(AddSpecialEffect (FF_ExpFx(), x1, y1))
                set ID2 = LoadInteger (udg_FF_Hashtable, 0, 0)

                if ID2 > 0 then
                    call SaveInteger (udg_FF_Hashtable, 0, 0, ID2 - 1)
                    set ID2 = LoadInteger (udg_FF_Hashtable, 0, ID2)
                else
                    set ID2 = LoadInteger (udg_FF_Hashtable, 0, -1) + 1
                    call SaveInteger (udg_FF_Hashtable, 0,-1, ID2)
                endif

                call SaveUnitHandle (udg_FF_Hashtable, ID2, 1, caster)
                call SaveReal (udg_FF_Hashtable, ID2, 8, x1)
                call SaveReal (udg_FF_Hashtable, ID2, 9, y1)
                call SaveReal(udg_FF_Hashtable, ID2, 10, 0)
                call SaveBoolean (udg_FF_Hashtable, ID2, 7, true)
                set listmax = listmax + 1
                call SaveInteger (udg_FF_Hashtable, -1, 0, listmax )
                call SaveInteger (udg_FF_Hashtable, -1, listmax, ID2)
                call SaveInteger (udg_FF_Hashtable, ID2, 0, listmax)

                call SaveReal(udg_FF_Hashtable, ID, 5, t + FF_Interval())
                call SaveInteger(udg_FF_Hashtable, ID, 6, j + 1)
            endif
        endif

        set caster = null
    endloop
endfunction

function Trig_FF_Conditions takes nothing returns boolean
    local unit caster
    local integer ID
    local integer listmax
    local real x
    local real y

    if GetSpellAbilityId() == FF_GetSpellID() then
        set caster = GetTriggerUnit()
        set x = GetSpellTargetX()
        set y = GetSpellTargetY()
        set ID = LoadInteger(udg_FF_Hashtable, 0, 0)

        // Now we start indexing the spell
        if ID>0 then
            call SaveInteger(udg_FF_Hashtable, 0, 0, ID - 1)
            set ID = LoadInteger (udg_FF_Hashtable, 0, ID)
        else
            set ID = LoadInteger(udg_FF_Hashtable, 0, -1) + 1
            call SaveInteger(udg_FF_Hashtable,0 ,-1, ID)
            if ID == 1 then
                call TimerStart (LoadTimerHandle(udg_FF_Hashtable, -2, 0), FF_Interval(), true, function FF_TimerLoop)
            endif
        endif

        // Save the values related to this spell instance
        call SaveUnitHandle(udg_FF_Hashtable, ID, 1, caster)
        call SaveReal(udg_FF_Hashtable, ID, 2, x)
        call SaveReal(udg_FF_Hashtable, ID, 3, y)
        call SaveEffectHandle(udg_FF_Hashtable, ID, 4, AddSpecialEffect (FF_FieldFx(), x, y))
        call SaveReal(udg_FF_Hashtable, ID, 5, 0)
        call SaveInteger(udg_FF_Hashtable, ID, 6, 0)

        set listmax = LoadInteger (udg_FF_Hashtable, -1, 0) + 1
        call SaveInteger (udg_FF_Hashtable, -1, 0, listmax )
        call SaveInteger (udg_FF_Hashtable, -1, listmax, ID)
        call SaveInteger (udg_FF_Hashtable, ID, 0, listmax)

        set caster = null
    endif
    return false
endfunction

//===========================================================================
function InitTrig_Freezing_Field takes nothing returns nothing
    local trigger FF = CreateTrigger()
    set udg_FF_Hashtable = InitHashtable ()
    call SaveTimerHandle (udg_FF_Hashtable, -2, 0, CreateTimer())
    call TriggerRegisterAnyUnitEventBJ(FF, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(FF, Condition( function Trig_FF_Conditions))
    set FF = null
endfunction

Instruction

Installation prequisites:
+ A hashtable. In this spell we will need udg_FF_Hashtable
+ A basic understanding of JASS.

How to import:
Step 1: Create the hashtable.
Step 2: Copy the spell trigger (Freezing Field).
Step 3: Modify the values in the configuration part of the spell as you like.

Give proper credit where it is due if you use my resources. Thanks.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
basically you have two options, either you go to the Variables...(Where you declare global variables for GUI), or you go to file -> preferences -> general -> tick "Automatically create unknown variables while pasting trigger".

If you decide for the manual way, the variable should be called "FF_Hashtable", and it should be of type "Hashtable"
 
Level 6
Joined
Jan 2, 2015
Messages
171
basically you have two options, either you go to the Variables...(Where you declare global variables for GUI), or you go to file -> preferences -> general -> tick "Automatically create unknown variables while pasting trigger".

If you decide for the manual way, the variable should be called "FF_Hashtable", and it should be of type "Hashtable"

i created FF_Hashtable variable and whats next step to activate this spell?
 
Status
Not open for further replies.
Top