• 🏆 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] My spell doesn't work the first time it's casted

Status
Not open for further replies.
Level 3
Joined
Sep 18, 2008
Messages
19
Hi there!

I have a problem that I can't figure out what is the cause in my vJass code.The spell doesn't really work the first time it's casted. With some little tests, I have been able to know where approximately the problem is.

JASS:
call GroupEnumUnitsInRange(bigStompStructs[currentInstance].targets, bigStompStructs[currentInstance].locx, bigStompStructs[currentInstance].locy, radius, Condition(function PickUnitsConditions))

I think it's this part of the code because I added a debug message in the condition (PickUnitsConditions) which is supposed to tell me the current index of the struct array of my spell.

JASS:
unction PickUnitsConditions takes nothing returns boolean
    call BJDebugMsg(I2S(currentInstance))
    return IsPlayerEnemy(bigStompStructs[currentInstance].casterOwner, GetOwningPlayer(GetFilterUnit())) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_FLYING)
endfunction

Here is the main part of my code

JASS:
library BigStomp requires TimerUtils

globals
    constant integer maxInstance = 8191
    BigStomp_BigStompStruct array bigStompStructs[8191]
    integer currentInstance = 0
    constant string buffId = "Objects\\Spawnmodels\\Undead\\ImpaleTargetDust\\ImpaleTargetDust.mdl"
    constant real duration = 0.5
    constant integer maxFrames = R2I(duration / 0.03)
    constant real radius = 281
    constant real distance = 400
    constant real velocity = distance / duration * 0.03
    constant real a = -velocity / Pow(maxFrames, 2)
endglobals

function PickUnitsConditions takes nothing returns boolean
    call BJDebugMsg(I2S(currentInstance))
    return IsPlayerEnemy(bigStompStructs[currentInstance].casterOwner, GetOwningPlayer(GetFilterUnit())) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_FLYING)
endfunction

public struct BigStompStruct
 
integer currentFrame
player casterOwner
group targets
real locx
real locy

    public static method LoopActions takes nothing returns nothing
        local BigStompStruct s = GetTimerData(GetExpiredTimer())
        local integer targetsCount = GroupCountUnits(s.targets)
        local unit u = null
        local group mirrorGroup = CreateGroup()
        local real distance = 0
        local real angle = 0
        local real ux = 0
        local real uy = 0
        local effect e = null
        
        if(s.currentFrame >= maxFrames) then
            call s.destroy()
            call ReleaseTimer(GetExpiredTimer())
        endif
        
        set s.targets = CopyGroupToGroup(s.targets, mirrorGroup)
        
        if(s.currentFrame != 0) then
            loop
                set u = FirstOfGroup(mirrorGroup)
            exitwhen (u == null)
        
                set ux = GetUnitX(u)
                set uy = GetUnitY(u)

                set angle = AngleBetweenRealsRad(s.locx, s.locy, ux, uy)
            
                call SetUnitX(u, PolarProjectionXRad(ux, a * Pow(s.currentFrame, 2) + velocity, angle))
                call SetUnitY(u, PolarProjectionYRad(uy, a * Pow(s.currentFrame, 2) + velocity, angle))
            
                call GroupRemoveUnit(mirrorGroup, u)
            endloop
        else
            loop
                set u = FirstOfGroup(mirrorGroup)
            exitwhen (u == null)
        
                set e = AddSpecialEffectTarget(buffId, u, "origin")
        
                set ux = GetUnitX(u)
                set uy = GetUnitY(u)

                set angle = AngleBetweenRealsRad(s.locx, s.locy, ux, uy)
            
                call SetUnitX(u, PolarProjectionXRad(ux, a * Pow(s.currentFrame, 2) + velocity, angle))
                call SetUnitY(u, PolarProjectionYRad(uy, a * Pow(s.currentFrame, 2) + velocity, angle))
            
                call GroupRemoveUnit(mirrorGroup, u)
                call DestroyEffect(e)
            endloop
        endif
        
        call DestroyGroup(mirrorGroup)
        set mirrorGroup = null
        set e = null
        set u = null
        set s.currentFrame = s.currentFrame + 1
    endmethod
    
   static method create takes unit caster returns BigStompStruct
     local timer t
     
     if(currentInstance > maxInstance) then
        set currentInstance = 0
     endif
   
     set bigStompStructs[currentInstance] = BigStompStruct.allocate()
     set t = NewTimer()
     set bigStompStructs[currentInstance].currentFrame = 0
     set bigStompStructs[currentInstance].locx = GetUnitX(caster)
     set bigStompStructs[currentInstance].locy = GetUnitY(caster)
     set bigStompStructs[currentInstance].casterOwner = GetOwningPlayer(caster)
     call BJDebugMsg("test1")
     call GroupEnumUnitsInRange(bigStompStructs[currentInstance].targets, bigStompStructs[currentInstance].locx, bigStompStructs[currentInstance].locy, radius, Condition(function PickUnitsConditions))
     call BJDebugMsg("test2")
     
     call SetTimerData(t, bigStompStructs[currentInstance])
     
     set currentInstance = currentInstance + 1
     
     call TimerStart(t, 0.03, true, function BigStompStruct.LoopActions )
     
     return bigStompStructs[currentInstance - 1]
   endmethod

   method onDestroy takes nothing returns nothing
        call DestroyGroup(.targets)
        set .targets = null
        set .casterOwner = null
   endmethod

endstruct

function SpellConditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function SpellActions takes nothing returns nothing
    call BigStompStruct.create(GetTriggerUnit())
endfunction

//===========================================================================
function InitTrig_Big_Stomp takes nothing returns nothing
    set gg_trg_Big_Stomp = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Big_Stomp, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Big_Stomp, Condition(function SpellConditions) )
    call TriggerAddAction( gg_trg_Big_Stomp, function SpellActions)
endfunction
endlibrary

I even have a little video that show you the problem :D


The first time the spell is casted, it only shows "test1" and "test2", while it's supposed to also show the index like the other times.

Could you help me please? :)
 
Last edited:
Level 29
Joined
Mar 10, 2009
Messages
5,016
try this...

JASS:
public struct BigStompStruct
 
integer currentFrame
player casterOwner
group targets
real locx
real locy

static thistype DATA // <<< add this

JASS:
static method PickUnitsConditions takes nothing returns boolean
    local thistype this = DATA
    call BJDebugMsg(I2S(currentInstance))
    return IsPlayerEnemy(.casterOwner, GetOwningPlayer(GetFilterUnit())) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_FLYING)
endmethod

JASS:
set DATA = bigStompStructs[currentInstance]
call GroupEnumUnitsInRange(bigStompStructs[currentInstance].targets, bigStompStructs[currentInstance].locx, bigStompStructs[currentInstance].locy, radius, Filter(function thistype.PickUnitsConditions))
 
Status
Not open for further replies.
Top