• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[vJASS] Instant Spell Cast not working

Status
Not open for further replies.
Level 3
Joined
May 9, 2011
Messages
37
Hello,
I'm trying to make a spell for my project which I've been working on for about a year and started to convert my GUI stuff to vJASS to learn the language. Basically, the spell gets the closest unit in front of the caster and deals the STR of the hero as damage.

Heres the code:

JASS:
scope MeleeBasicAttack

    globals
        private constant integer PRIMARY_ATTACK_ID = 'A001'
        private constant integer DUMMY = 'h001'
        private constant integer SEARCH_RANGE = 256
    endglobals
        
    private function UnitFilter takes nothing returns boolean
        return (GetUnitTypeId(GetFilterUnit()) != DUMMY and GetWidgetLife(GetFilterUnit()) >= 0.405)
    endfunction
    
    private struct PrimaryAttack
        unit caster
        real damage
        real fov
        string fx
        player owner

        static group TEMP_GROUP
        static integer index
        static thistype array data
        
        method destroy takes nothing returns nothing
            call .deallocate()
            set .caster = null
            set .owner = null
        endmethod
        
        static method run takes nothing returns nothing
            local integer i = 0
            local PrimaryAttack this
            
            local unit target
            local unit temp
            local real x = GetUnitX(this.caster)
            local real y = GetUnitY(this.caster)
            local real eX
            local real eY
            local real minDistance = SEARCH_RANGE
            local real tempDistance
            
            loop
                exitwhen i > index
                set this = data[i]
                
                call GroupEnumUnitsInRange(TEMP_GROUP, x, y, SEARCH_RANGE, Condition(function UnitFilter))
                
                loop
                    set temp = FirstOfGroup(TEMP_GROUP)
                    exitwhen temp == null
                    if (temp != null) then
                        // the part below doesn't run
                        if (IsPlayerEnemy(GetOwningPlayer(temp), this.owner)) then
                            if (IsUnitInSightOfUnit(this.caster, temp, this.fov)) then
                                set tempDistance = SquareRoot((x - GetUnitX(temp))*(x - GetUnitX(temp)) + (y - GetUnitY(temp))*(y - GetUnitY(temp)))
                                if (tempDistance < minDistance) then
                                    set target = temp
                                    set minDistance = tempDistance
                                    set eX = GetUnitX(target)
                                    set eY = GetUnitY(target)
                                endif
                            endif                    
                        endif
                    endif
                    
                    call GroupRemoveUnit(TEMP_GROUP, temp)
                endloop
                
                if (target != null) then
                    if (IsUnitBehindUnit(this.caster, target, this.fov)) then
                        call UnitDamageTarget(this.caster, target, this.damage*2, true, false, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
                    else   
                        call UnitDamageTarget(this.caster, target, this.damage, true, false, ATTACK_TYPE_MELEE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
                    endif
                        
                    // knockback stuff
            
                    call DestroyEffect(AddSpecialEffect(this.fx, eX, eY))
                    call this.destroy()
                        
                    set target = null
                    set temp = null
                
                    set data[i] = data[index]
                    set i = i - 1
                    set index = index - 1
                endif
                
                set i = i + 1
            endloop
        endmethod
        
        // this is also not being called
        static method Check takes nothing returns boolean
            local PrimaryAttack this
            if (GetSpellAbilityId() == PRIMARY_ATTACK_ID) then
                set this = thistype.allocate()
                set this.caster = GetTriggerUnit()
                set this.damage = GetHeroStr(this.caster, true)
                set this.fov = 67.5
                set this.fx = "Objects\\Spawnmodels\\Human\\HumanBlood\\BloodElfSpellThiefBlood.mdl"
                set index = index + 1
                set data[index] = this
                call thistype.run()
            endif
            return false
        endmethod

        static method onInit takes nothing returns nothing
            local trigger t = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
            call TriggerAddCondition(t, Condition(function thistype.Check))
            set index = -1
            set t = null
        endmethod
    endstruct
endscope


Based the whole thing off that vJass dynamic indexing tutorial and use the FieldOfView library by MoCo to detect if the unit is in front (not sure if this is the best)

I can't even get the thing to run. I'm guessing it has something to do with the code inside if (temp != null) then (not sure though)

How can I get it to run and work?
What parts of code can I optimize to make it run faster?
Also should I use a private struct only or make it extend an array? What is the difference between the two?

Thanks,
Tauren_009
 
Last edited:
Level 12
Joined
Feb 22, 2010
Messages
1,115
Your TEMP_GROUP variable is not initialized.

TEMP_GROUP = CreateGroup()

Next time put some text messages in your code so you can see which parts are working or not.
 
Level 3
Joined
May 9, 2011
Messages
37
Updated the main post

The code is still not working. The Check method is not even being called. What is wrong with my code?

Thanks
 
Status
Not open for further replies.
Top