[General] Linked List

Status
Not open for further replies.
Level 7
Joined
Feb 9, 2021
Messages
301
Can someone help me to understand how to use Linked List with a practical example, please? I am using this one: [vJASS] - LinkedList Modules

I have a spell "hook", and I want to add all the links to the list. Then, I want to add new links if the gap between the caster/target and the link is more than x and delete them when the gap is smaller than y. I understand how to do it with arrays, but not with the list. Here is my hook:

JASS:
library CrocHook /*

     */ uses /*

     */ SpellFramework /*
     */ BaseFunctions

    private module SpellConfiguration

        static constant integer SPELL_ABILITY_ID = 'A01J'
        static constant integer SPELL_EVENT_TYPE = EVENT_SPELL_EFFECT
       
        //Models and Effects
        static constant string HOOK_MODEL_ID = "Abilities\\Weapons\\SentinelMissile\\SentinelMissile.mdl"
        static constant string SAND_EFFECT_ID = "Abilities\\Weapons\\WardenMissile\\WardenMissile.mdl"
       
       
        //Params
        static constant real HOOK_BASE_Z = 70
        static constant real HOOK_ANGLE_ADJUSTMENT = 50
        static constant real HOOK_CAST_DIST = 26
        static constant real HOOK_RETURN_DIST = 26
        static constant real HOOK_RANGE = 1000
        static constant real HOOK_AOE = 80
        static constant real HOOK_SPEED = 1100
       
        static method Dmg takes unit caster returns real
            return 10.0 + 0.1 * GetHeroStr(caster, true)
        endmethod
       
        static method Targets takes unit caster, unit target returns boolean
            return GetWidgetLife(target) > 0.405 and /*
             */ not IsUnitType(target, UNIT_TYPE_STRUCTURE) and /*
             */ not IsUnitType(target, UNIT_TYPE_MAGIC_IMMUNE) and /*
             */ IsUnitEnemy(target, GetOwningPlayer(caster))
        endmethod
       
    endmodule

    globals
        private group enemies = CreateGroup()

    endglobals
   
    private struct Link extends array
        implement ListLite
        static constant string SAND_EFFECT_ID = "Abilities\\Weapons\\WardenMissile\\WardenMissile.mdl"
        real x
        real y
        real angle
        effect sfx
       
        method attach takes real x, real y, real z , real angle returns nothing
           
            set this.x     = x
            set this.y     = y
            set this.angle = angle
       
            set this.sfx   = AddSpecialEffect(SAND_EFFECT_ID, x, y)
            call SetEffectZ(this.sfx, z)
            call SetEffectScale(this.sfx, 1.5)
            call SetEffectFacing(this.sfx, angle)
           
        endmethod
       
    endstruct
   
    private struct Missile extends Missiles
        implement SpellConfiguration
       
        private boolean hookReturn
        private boolean hit
        private boolean castFinsihed
        private unit unit
        private real hookBaseX
        private real hookBaseY
        private real hookBaseZ
        private integer linkCounter
        private timer timer
        private boolean linksDeleted
        private real linkTempCounter
        private Link list
       
        Table effectLink
       
        method onPeriod takes nothing returns boolean
            local real cX = GetUnitX(source)
            local real cY = GetUnitY(source)
            local real hookAngle = GetUnitFacing(source) + HOOK_ANGLE_ADJUSTMENT
            local real hookX = GetXWithOffset(cX, HOOK_RETURN_DIST , hookAngle)
            local real hookY = GetYWithOffset(cY, HOOK_RETURN_DIST , hookAngle)
            local real hookZ = GetUnitZ(source) + HOOK_BASE_Z
            local real hookFacing
            local real dist = GetDist(x, this.hookBaseX, y, this.hookBaseY)
            local real distToCaster = GetDist(x, hookX, y, hookY)
           
            if distToCaster < 20 and this.hookReturn then
                //call deflect(x, y, z)
                return true
            endif
           
            if this.unit != null and this.hit then
                call SetUnitX(unit, x)
                call SetUnitY(unit, y)
            endif
           
            if this.hit and dist < 30 then
                call Stun.remove(this.unit)
                set this.hit = false
            endif

           
            if not this.hit and this.hookReturn then
                call deflect(hookX, hookY, hookZ)
            elseif this.hit and this.hookReturn then
                call deflect(this.hookBaseX, this.hookBaseY, this.hookBaseZ)
            endif
           
            //Effect Links
            if not this.hookReturn then
           
                set hookFacing = GetUnitFacing(dummy)
                set this.linkCounter = this.linkCounter + 1
                set this.effectLink.effect[linkCounter] = AddSpecialEffect(SAND_EFFECT_ID, x, y)
                call SetEffectZ(this.effectLink.effect[linkCounter], z)
                call SetEffectScale(this.effectLink.effect[linkCounter], 1.5)
                call SetEffectFacing(this.effectLink.effect[linkCounter], hookFacing)
            elseif this.hookReturn and this.linkCounter > 0 then
                call DestroyEffect(this.effectLink.effect[linkCounter])
                set this.linkCounter = this.linkCounter - 1
            endif
           
            debug call BJDebugMsg("[CrocHook] Links: " + I2S(this.linkCounter))
           
            if this.linkCounter == 0 and not this.linksDeleted then
           
                call this.effectLink.destroy()
                call this.effectLink.flush()
                set  this.linksDeleted = true
               
                //return true
            endif
       
           // set cDist = GetDist(
           
            //call SetEffectX(this.effectLink.effect[linkCounter],
            //call SetEffectY(this.effectLink.effect[linkCounter],
           
            return false
        endmethod
       
        method onHit takes unit u returns boolean
            if (BaseBool(u) and /*
                 */ u != source and /*
                 */ not IsUnitEnemy(u, owner) and /*
                 */ not hookReturn and /*
                 */ not hit ) then
                call Stun.apply(u)
                call SetUnitPathing(u, false)
                set this.unit = u

                call deflect(GetUnitX(source), GetUnitY(source), 50)

                //call Stun.remove(source)
                set this.hit = true
                set this.hookReturn = true
            endif
           
            return false
        endmethod
       
        method onTerrain takes nothing returns boolean
             /*
            call deflect(this.hookBaseX, this.hookBaseY)
            set hookReturn = true
            call Stun.remove(source)
             */
            return false
        endmethod
       
        method onDestructable takes destructable d returns boolean
            //call deflectZ(this.hookBaseX, this.hookBaseY, this.hookBaseZ)
            set this.hookReturn = true
            set this.castFinsihed = true
            call Stun.remove(source)
       
            return false
        endmethod
       
       
        method onFinish takes nothing returns boolean
            if not this.hookReturn then
                set this.hookReturn = true
                call deflect(GetUnitX(source), GetUnitY(source), 50)
            endif
           
            return false
        endmethod
         /*
        method onPause takes nothing returns boolean
            local thistype sourceId = GetUnitId(source)
            call PauseTimer(sourceId.t)
           
            return false
        endmethod
       
        method onResume takes nothing returns boolean
            local thistype sourceId = GetUnitId(source)
            call ResumeTimer(sourceId.t)
           
            return false
        endmethod
         */

        implement SpellConfiguration
       
        private static method onSpellStart takes nothing returns thistype
            local thistype node
            local real cX = GetUnitX(Spell.triggerUnit)
            local real cY = GetUnitY(Spell.triggerUnit)
            local real angle = GetAngle(cX, Spell.targetX, cY, Spell.targetY)
            local real hookAngle = angle + HOOK_ANGLE_ADJUSTMENT
            local real hookX = GetXWithOffset(cX, HOOK_CAST_DIST, hookAngle)
            local real hookY = GetYWithOffset(cY, HOOK_CAST_DIST, hookAngle)
            local real hookZ = GetUnitFlyHeight(Spell.triggerUnit) + HOOK_BASE_Z
            local real hookEndX = GetXWithOffset(cX, HOOK_RANGE, angle)
            local real hookEndY = GetYWithOffset(cY, HOOK_RANGE, angle)
            local thistype this = thistype.create(hookX, hookY , hookZ , hookEndX, hookEndY, HOOK_BASE_Z )
       
            set this.effectLink = Table.create()
            set this.linkCounter = 0
            set this.linksDeleted = false
       
            set this.hookBaseX = hookX
            set this.hookBaseY = hookY
            set this.hookBaseZ = hookZ
            set node = GetUnitId(Spell.triggerUnit)
            set speed = HOOK_SPEED
            set model = HOOK_MODEL_ID
            set source = Spell.triggerUnit
            set collideZ = true
            set collision = HOOK_AOE
            set damage = Dmg(Spell.triggerUnit)
            set owner = Spell.triggerPlayer
       
            set this.hookReturn = false
            set this.unit = null
            set this.hit = false
            set this.castFinsihed = false
            set this.timer = CreateTimer()
       
            //call Stun.apply(Spell.triggerUnit)
       
            call launch()

       
            return node
        endmethod
       
        implement SpellEventEx

    endstruct


endlibrary
 
Status
Not open for further replies.
Top