• 🏆 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] Strange issue

Status
Not open for further replies.
Level 11
Joined
Sep 30, 2009
Messages
697
I created a spell and have a really odd issue: Whenever i cast the spell again the arrows move faster o_O I think its a stupid mistake but i cant find it D: + rep for help

JASS:
library LightningVolley

globals
    private constant integer SPELL_ABILITY      = 'axa2'
    private constant integer DUMMY              = 'axa0'
    private constant string DUMMY_SFX           = "Abilities\\Spells\\Other\\FrostArrows\\NagaColdArrowMissile.mdl"
    private constant real TIMER_INTERVAL        = 0.03
    private group ENUM_GROUP                    = CreateGroup()
endglobals

private function ArrowCount takes integer level returns integer
    return 4 + 2 * level
endfunction

private function ArrowSpeed takes integer level returns real
    return 1000.
endfunction

private function ArrowTravelDistance takes integer level returns real
    return 500. + 250. * level
endfunction

private function ArrowAoE takes integer level returns real
    return 100.
endfunction

private function ArrowDamage takes integer level returns real
    return  25. + 25. * level
endfunction

private function ArrowStopOnHit takes integer level returns boolean
    return level > 2
endfunction

private function BuffDuration takes integer level returns real
    return  5. + 2.5 * level
endfunction

private function OnCastDamage takes integer level returns real
    return 20. * 20. * level
endfunction

private function OnCastStunTime takes integer level returns real
    return 1. + 0.5 * level
endfunction

private struct volley 
    private static thistype array VOLLEY_INDEXER
    private static timer VOLLEY_LOOP_TIMER = CreateTimer()
    private static integer TOTAL = 0
    
    unit caster                     = null
    player owner                    = null
    integer level                   = 0
    
    integer maxArrows               = 0
    integer arrows                  = 0
    real maxDistance                = 0.
    real distance                   = 0.
    real speed                      = 0.
    real damageHit                  = 0.
    real damageCast                 = 0.
    
    unit array dummy[8190]
    real array dummyX[8190]
    real array dummyY[8190]
    real array dummy_sin[8190]
    real array dummy_cos[8190]
    real array dummy_fac[8190] 
    
    effect array dummy_eff[8190]
    
    
    method moveArrows takes nothing returns nothing
        local integer i = 0
        
        set .distance = .distance + .speed 
        loop
            set .dummyX[i] = .dummyX[i] + .speed * .dummy_cos[i]
            set .dummyY[i] = .dummyY[i] + .speed * .dummy_sin[i]
            call SetUnitX(.dummy[i], .dummyX[i])
            call SetUnitY(.dummy[i], .dummyY[i])
            set i = i + 1
            exitwhen i > .maxArrows
        endloop
    endmethod
    
    method destroy takes nothing returns nothing
        local integer i = 0
        loop
            call DestroyEffect(.dummy_eff[i])
            call RemoveUnit(.dummy[i])
            set i = i + 1
            exitwhen i > .maxArrows
        endloop
        call .deallocate()
    endmethod
    
    static method VOLLEY_LOOP takes nothing returns nothing
        local thistype this
        local integer i = 0
        
        loop
            exitwhen i >= thistype.TOTAL
            set this = thistype.VOLLEY_INDEXER[i]

            if true then
                call .moveArrows()
            else
            
                call .destroy()

                set thistype.TOTAL = thistype.TOTAL - 1
                set thistype.VOLLEY_INDEXER[i] = thistype.VOLLEY_INDEXER[thistype.TOTAL]


                set i = i - 1
            endif

            set i = i + 1
        endloop

        if .TOTAL == 0 then
            call PauseTimer(thistype.VOLLEY_LOOP_TIMER)
        endif
    endmethod
    
    static method create takes unit caster, real x, real y returns thistype
        local thistype this = thistype.allocate()
        local integer i = 0
        set .caster = caster
        set .owner = GetOwningPlayer(.caster)
        set .level = GetUnitAbilityLevel(.caster, SPELL_ABILITY)
        set .maxArrows = ArrowCount(.level) - 1
        set .arrows = .maxArrows
        set .maxDistance = ArrowTravelDistance(.level)
        set .speed = ArrowSpeed(.level) * TIMER_INTERVAL
        set .damageHit = ArrowDamage(.level)
        set .damageCast = OnCastDamage(.level)
        
        loop
            set .dummyX[i] = GetUnitX(.caster)
            set .dummyY[i] = GetUnitY(.caster)
            set .dummy_fac[i] = GetUnitFacing(.caster) + 35. - (70./.maxArrows * i)
            set .dummy_sin[i] = Sin(.dummy_fac[i] * bj_DEGTORAD)
            set .dummy_cos[i] = Cos(.dummy_fac[i] * bj_DEGTORAD)
            set .dummy[i] = CreateUnit(.owner, DUMMY, .dummyX[i], .dummyY[i], .dummy_fac[i])
            set .dummy_eff[i] = AddSpecialEffectTarget(DUMMY_SFX, .dummy[i], "origin")
            
            exitwhen i >= .maxArrows
            set i = i + 1
        endloop
        
        if thistype.TOTAL == 0 then
            call TimerStart(thistype.VOLLEY_LOOP_TIMER, TIMER_INTERVAL, true, function thistype.VOLLEY_LOOP)
        endif

        set thistype.VOLLEY_INDEXER[thistype.TOTAL] = this
        set thistype.TOTAL = thistype.TOTAL + 1
        
        return this
    endmethod
    
    static method onCast takes nothing returns nothing
        call thistype.create(GetTriggerUnit(), GetSpellTargetX(), GetSpellTargetY())
    endmethod
    
    static method onCheck takes nothing returns boolean
        return GetSpellAbilityId() == SPELL_ABILITY
    endmethod
    
    static method onInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddAction(t, function thistype.onCast)
        call TriggerAddCondition(t, Condition(function thistype.onCheck))
        set t = null
    endmethod

endstruct

endlibrary
 
Level 23
Joined
Nov 29, 2006
Messages
2,482
While I have hit this issue before, and currently don't know why it happends (since I thought I did riht myself) I see another flaw of yours which could perhaps help with the issue.

In your struct you create the member arrays with the size 8190. This would lead to that only 1 instance of the spell can be active at the same time with the possibility to screw everything up. Since structs are by default an array of 8190 safe-allocated indexes, an array size of 8190 would only allow 1 instance.
 
Status
Not open for further replies.
Top