• 🏆 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] Problems with moving a unit

Status
Not open for further replies.
Level 6
Joined
Sep 9, 2006
Messages
92
So here's the full script (keep in mind that the ability is not done, which may be why some variables are not being used, i.e. one of the global abilities).

The ability right now should create a dummy unit at the caster position and then the dummy should slide to a distance away from the caster, with the angle dependent on where the ability was cast (and also every .5 sec 2 shockwaves are sent backwards at an angle, but that part works perfectly).

The problem is, the unit is created, but it does not move. Ive checked that the angles work and the offset point works, but i think i messed up something simple that stopped the unit from actually moving toward the final offset point...
JASS:
scope Orb

globals
    private constant integer ABILITY_ID = 'A003'           //ability id of Spark Jump
    private constant integer DUMMY_ABILITY_PULSE = 'A004'  //ability id of the pulse damaging ability (i.e. shockwave)
    private constant integer DUMMY_ABILITY_SLOW = 'A006'   //ability id of the slow ability (slow)
    private constant integer DUMMY_ORB_ID = 'h001'         //orb id
    private constant integer DUMMY_ID = 'h000'             //dummy unit id
    private constant integer PULSE_TIMER = 50              // .01's of sec between pulses
    private constant real DUMMY_OFFSET = 2.                //amount dummy is offset by each time
    private constant real PULSE_WIDTH = 45.                //how wide the pulse lines are (degrees from center travel line)
endglobals

private struct data
    static hashtable h = InitHashtable()
    unit c
    unit array dummy [3] //dummy units (orb and casters)
    integer lvl
    integer PT = PULSE_TIMER
    timer tim = CreateTimer()
    real Fx //final position
    real Fy
    real Dx //dummy's position
    real Dy
    real Sx //pulse spell target point
    real Sy
    real angle //from origin of spell to target point
    
    static method periodic takes nothing returns nothing
        local integer id = GetHandleId(GetExpiredTimer())
        local data this = LoadInteger(.h,id,0)
        local real Tx = (.Dx + DUMMY_OFFSET * Cos(.angle * bj_DEGTORAD))
        local real Ty = (.Dy + DUMMY_OFFSET * Sin(.angle * bj_DEGTORAD))
        local real angle
        local integer count
        call SetUnitPosition(.dummy[1], Tx, Ty)
        if .PT > 0 then
            set .PT = .PT - 1
        else
            set count = 3
            set angle = .angle + 135
            loop
                exitwhen count == 1
                set .Sx = (Tx + 10 * Cos(angle * bj_DEGTORAD))
                set .Sy = (Ty + 10 * Sin(angle * bj_DEGTORAD))
                set .dummy[count] = CreateUnit(GetOwningPlayer(.c), DUMMY_ID, Tx, Ty, 0)
                call UnitAddAbility(.dummy[count], DUMMY_ABILITY_PULSE)
                call SetUnitAbilityLevel(.dummy[count], DUMMY_ABILITY_PULSE, .lvl)
                call IssuePointOrder(.dummy[count], "shockwave", .Sx, .Sy)
                set count = count - 1
                set angle = angle + 90
            endloop
            //send pulse; slow units and shoot shockwaves
            set .PT = PULSE_TIMER
        endif
        if SquareRoot((Tx-.Fx)*(Tx-.Fx)+(Ty-.Fy)*(Ty-.Fy)) < 2. then
            call DestroyTimer(.tim)
            call FlushChildHashtable(.h,id)
            call .destroy(id)
            //end spell
        endif
    endmethod

    static method create takes nothing returns data
        local data this = data.allocate()
        local real dist
        set .c = GetTriggerUnit()
        set .lvl = GetUnitAbilityLevel(.c, ABILITY_ID)
        set .Dx = GetLocationX(GetUnitLoc(.c))
        set .Dy = GetLocationY(GetUnitLoc(.c))
        set .angle = bj_RADTODEG * Atan2(GetSpellTargetY() - .Dy, GetSpellTargetX() - .Dx)
        set dist = 400. + (200. * I2R(.lvl))
        set .Fx = (.Dx + dist * Cos(.angle * bj_DEGTORAD))
        set .Fy = (.Dy + dist * Sin(.angle * bj_DEGTORAD))
        set .dummy[1] = CreateUnit(GetOwningPlayer(.c), DUMMY_ORB_ID, .Dx, .Dy, 0)
        call SaveInteger(.h,GetHandleId(.tim),0,this)
        call TimerStart(.tim,.01,true,function data.periodic)
        return this
    endmethod

    static method Conditions takes nothing returns nothing
        if GetSpellAbilityId() == ABILITY_ID then
            call .create()
        endif
    endmethod
/////////////////////////////////////////////////////////////////////////////////////////
    static method onInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddAction( t, function data.Conditions )
    endmethod
 
endstruct
endscope

Also as a side question, would it be more efficient for me to leave "angle" and "count" as locals even if they are only used 1/50 of the time, or make them part of the data (struct?) and only set them 1/50 of the time when they are actually used?
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,467
JASS:
//even faster coordinates, but you gotta get used to the name "widget".
GetWidgetX(.dummy)
GetWidgetY(.dummy)

//Instead of:
GetUnitState(.dummy, UNIT_STATE_LIFE) > 0.435
//do:
GetWidgetLife(.dummy) > 0.435

//Instead of:
SetUnitState(.dummy, UNIT_STATE_LIFE, 500.0)
//do:
SetWidgetLife(.dummy, 500.0)
The money is there.
 
Status
Not open for further replies.
Top