• 🏆 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] Missle (not) moving

Status
Not open for further replies.
Level 13
Joined
Mar 16, 2008
Messages
941
Hey guys. Fixed!

I tried to recreate a spell of mine, however, it completly fails.
It's supposed to create two missles, one at the left side and one at the right side of the caster, both chasing towards the castpoint.

The problem is, that the missles don't move.
They start moving when the spell is used very often, although each of them uses a seperate timer!

JASS:
scope ChillingStreams initializer InitStreams

    globals
        private constant    integer SPELL_ID        = 'A000'
        
        private constant    real    PERIOD          = 0.04
        
        private constant    string  SFX_PATH        = "Abilities\\Weapons\\FrostWyrmMissile\\FrostWyrmMissile.mdl"
        private constant    string  SFX_ATTACH      = "chest"
        
        private constant    real    SPEED           = 400.
        
        private constant    real    SIDEDIST        = 100.
        
        private constant    integer MISSLE_COUNT    = 2
        
        private constant    real    STEP            = SPEED*PERIOD
    endglobals
    
    
    private constant function GetMaxDist takes integer lvl returns real
        return 500.+lvl*200.
    endfunction
    
    private constant function GetDamage takes integer lvl returns real
        return lvl*70.
    endfunction
    

    private struct Streams
        private unit            caster
        private player          owner
        
        private unit    array   missle[MISSLE_COUNT]
        private effect  array   sfx[MISSLE_COUNT]
        private real    array   vecx[MISSLE_COUNT]
        private real    array   vecy[MISSLE_COUNT]
        
        private group   array   hit[MISSLE_COUNT]
        
        private real            dist
        private real            maxdist
        
        private timer           movetim
        
        
        method onDestroy takes nothing returns nothing
            local integer i = 0
            
            set .caster = null
            loop
                exitwhen i >= MISSLE_COUNT
                call ReleaseDummyTimed(.missle[i])
                call DestroyEffect(.sfx[i])
                set .sfx[i] = null
                call ReleaseGroup(.hit[i])
                set .hit[i] = null
                set i = i+1
            endloop
            call ReleaseTimer(movetim)
        endmethod
        
        static method movement takes nothing returns nothing
            local thistype this = GetTimerData(GetExpiredTimer())
            
            local integer i = 0
            
            loop
                exitwhen i >= MISSLE_COUNT
                
                call SetUnitX(.missle[i], GetUnitX(.missle[i])+.vecx[i])
                call SetUnitY(.missle[i], GetUnitY(.missle[i])+.vecy[i])
                
                set i = i+1
            endloop
            
            set .dist = .dist+STEP
            if .dist >= .maxdist then
                call .destroy()
            endif
        endmethod
        
        static method createStreams takes nothing returns nothing
            local thistype this = thistype.allocate()
            
            local real spellx = GetSpellTargetX() 
            local real spelly = GetSpellTargetY()
            local real x
            local real y
            local real casterx
            local real castery
            local real angle
            local real facing
            
            local integer i = 0
            
            set .caster = GetTriggerUnit()
            set casterx = GetUnitX(.caster)
            set castery = GetUnitY(.caster)
            set facing  = Atan2(spelly-castery, spellx-casterx) //Real angle between the caster and the spell
            set .owner  = GetOwningPlayer(.caster)
            
            loop
                exitwhen i >= MISSLE_COUNT
                
                set facing = facing+(i+1)/2*bj_PI
                set x = PolarX(casterx, facing, SIDEDIST)   //Creating points right and left (one per loop)
                set y = PolarY(castery, facing, SIDEDIST)   //of the caster
                set angle = Atan2(spelly-y, spellx-x)
                
                set .missle[i] = NewDummy(x, y, angle)
                call AddSpecialEffectTarget(SFX_PATH, .missle[i], SFX_ATTACH)
                set .vecx[i] = PolarX(0, angle, STEP)
                set .vecy[i] = PolarY(0, angle, STEP)
                
                set .hit[i] = NewGroup()
                
                set i = i+1
            endloop
                
            set .dist = 0.
            set .maxdist = GetMaxDist(GetUnitAbilityLevel(.caster, SPELL_ID))
            
            set .movetim = NewTimer()
            call SetTimerData(.movetim, this)
            call TimerStart(.movetim, PERIOD, true, function thistype.movement)
        endmethod
    endstruct

    private function InitStreams takes nothing returns nothing
        call AddSpellAction(SPELL_ID, Streams.createStreams)
    endfunction
endscope

There are some functions that are required for this.
The others are TimerUtils, GroupUtils and a custom trigger system,
but this works, the spell is started :p
JASS:
    function PolarX takes real x, real angle, real distance returns real
        return x+distance*Cos(angle)
    endfunction
    
    function PolarY takes real y, real angle, real distance returns real
        return y+distance*Sin(angle)
    endfunction

Greets, Justify
 
Last edited:
Level 4
Joined
Jan 27, 2010
Messages
133
Does this even compile...? :p

JASS:
// vecx/y is Array...
private real array vecx[MISSLE_COUNT]
private real array vecy[MISSLE_COUNT]

// ....

// vecx/y is not Array?
call SetUnitX(.missle[i], GetUnitX(.missle[i])+.vecx)
call SetUnitY(.missle[i], GetUnitY(.missle[i])+.vecy)
 
Level 13
Joined
Mar 16, 2008
Messages
941
I'm blind :D
Yes, this was the first mistake.
The missles move now (and yes, it compiled even without the dot and brackets -.-), but there is still only one created.
Okay, two, but they're at the same position.
But why?
The first missle should be created 100 left of the caster (his facing + bj_PI/2, what's a quarter circle). The second should be 100 right of the caster (his facing + bj_PI*3/2, whats a 3/4 circle).
Can someone find the mistake? (Code updated)
 
Level 11
Joined
Apr 29, 2007
Messages
826
It compiles fine without the dots when you're using the latest version of JassHelper. Dots aren't needed there anymore.

Your formula can't be right at any way.
JASS:
set facing = facing+i/2*bj_PI
You're starting with i = 0, so the first is created at facing+i/2(which is 0)*bj_PI(still 0). So at the casters position + 100 distance.
 
Level 13
Joined
Mar 16, 2008
Messages
941
k ,you're right. But why did I only see one missle?

Example: facing = 0
First loop (i=0):angle = 0+0/2*PI = 0
Second loop: angle= 0+1/2*PI = 1/2PI!

Now, I changed it to this line:
set facing = facing+(i+1)/2*bj_PI
Example: facing = 0
First loop (i=0):angle = 0+1/2*PI = 1/2*PI
Second loop: facing = 1/2*PI (from first loop) +2/2*PI = 3/2PI!

However, now one missle is created in front of the caster, the other one behind him.
Still not working :/
 
Level 13
Joined
Mar 16, 2008
Messages
941
LMAO, sorry for using internet-speak :p But warcraft sucks!
Old line:
set facing = facing+(i+1)/2*bj_PI
New line:
set facing = facing+bj_PI*(i+1)/2
Warcraft calculates the upper version wrong by calculating (i+1)/(2*bj_PI),
at least thats the only possibility why the old wasn't working.

Fixed -.- thanks to all.
 
Status
Not open for further replies.
Top