• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

Formula suggestion

Status
Not open for further replies.
Level 3
Joined
Sep 9, 2009
Messages
658
If I want a loop from 1 to 5 and the actions are these in the order of

move unit to offset towards 0 degrees.
move unit to offset towards 180 degrees.
move unit to offset towards 135 degrees.
move unit to offset towards 315 degrees.
move unit to offset towards 225 degrees.
move unit to offset towards 45 degrees.
move unit to offset towards 90 degrees.
move unit to offset towards 270 degrees.

What would be the best formula to use? Or should I just do it like this?
 
By what you asking I would suggest putting those degrees into arrayed 'real' variables. and loop through those actions like so. Although I don't know why you would want to do these functions under instances. Remember you can use this method for other variable types and situations.
  • Melee Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set DegreesIndex[0] = 0.00
      • Set DegreesIndex[1] = 270.00
      • Set DegreesIndex[2] = 90.00
      • Set DegreesIndex[3] = 135.00
      • Set DegreesIndex[4] = 180.00
      • Set DegreesIndex[5] = 235.00
  • Actions
    • For each (Integer IndexA) from 1 to 5, do (Actions)
      • Loop - Actions
        • -------- ACtionASn Doo WhattEver --------
        • Set Point = (Position of Unit)
        • For each (Integer IndexB) from 0 to 5, do (Actions)
          • Loop - Actions
            • Unit - Move Unit instantly to Point, facing DegreesIndex[IndexB] degrees
        • Custom script: call RemoveLocation(udg_Point)

I've been many times through that...
Just to mention vJass usually can help ALOT in such situations that you may be in.
 
Last edited:
...won't 0.00 be skipped since you loop from 1 to 5?
Right.

Would that work for a polar projection...
You can always try something like this.
  • Actions
    • For each (Integer IndexA) from 1 to 5, do (Actions)
      • Loop - Actions
        • -------- ACtionASn Doo WhattEver --------
        • Set PointA = (Position of Unit)
        • For each (Integer IndexB) from 0 to 5, do (Actions)
          • Loop - Actions
            • Set PointB = (PointA offset by 256.00 towards DegreesIndex[IndexB] degrees)
            • Unit - Move Unit instantly to PointB, facing DegreesIndex[IndexB] degrees
            • Custom script: call RemoveLocation(udg_PointB)
        • Custom script: call RemoveLocation(udg_PointA)
 
Level 3
Joined
Sep 9, 2009
Messages
658
  • Set SS_Loc[1] = (SS_Loc[0] offset by 350.00 towards SS_Angle[1] degrees)
  • Unit - Move SS_Unit[0] instantly to SS_Loc[1], facing SS_Angle[(Integer B)] degrees
  • Animation - Play SS_Unit[0]'s attack animation
  • Special Effect - Create a special effect attached to the chest of SS_Unit[1] using Abilities\Spells\Other\Stampede\StampedeMissileDeath.mdl
  • Special Effect - Destroy (Last created special effect)
  • Animation - Play SS_Unit[1]'s death animation
  • Custom script: call RemoveLocation(udg_SS_Loc[1])
  • Set SS_Loc[2] = (SS_Loc[0] offset by 350.00 towards SS_Angle[2] degrees)
  • Unit - Move SS_Unit[0] instantly to SS_Loc[1], facing SS_Angle[(Integer B)] degrees
  • Animation - Play SS_Unit[0]'s attack animation
  • Special Effect - Create a special effect attached to the chest of SS_Unit[1] using Abilities\Spells\Other\Stampede\StampedeMissileDeath.mdl
  • Special Effect - Destroy (Last created special effect)
  • Animation - Play SS_Unit[1]'s death animation
  • Custom script: call RemoveLocation(udg_SS_Loc[2])
So I'd have to do it like this for all angles if I want a 0.1 second interval?
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
No. You need a local periodic timer with the unit and data stored in a Hashtable. When timer expires you load the data from the hashtable and do your actions. Once the actions has been done, you pause and destroy the timer and flush the hashtable to clear the data and other leaks.

Alternatively, you need a unit group and a periodic trigger (every x time). You save the data on the unit ID in a Hashtable, add the unit to a unit group and turn on the periodic trigger. Load the data from the unit, do the stuff, then remove the unit from the group, clear the data, and check if the unit group is empty, if it's, you turn off the periodic trigger.
 
Level 3
Joined
Sep 9, 2009
Messages
658
JASS:
globals
    hashtable = ExampleHash
    real array angle
endglobals
    
function Periodic takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    
    local unit u = LoadUnitHandle(ExampleHash, id, 0)
    local integer counter = LoadInteger(ExampleHash, id, 1)
    local real tx = LoadReal(ExampleHash, id, 2)
    local real ty = LoadReal(ExampleHash, id, 3)
    local integer i = LoadInteger(ExampleHash, id, 4)
    local real mx = tx + 350 + Cos(angle[i])
    local real my = tx + 350 + Sin(angle[i])
    
    if counter =< 5 then
        if i < 7 then
            set i = i + 1
            call SaveInteger(ExampleHash, id, 4, i)
        else
            set i = 0
            call SaveInteger(ExampleHash, id, 4, i)
        endif
        call SetUnitX(u, mx)
        call SetUnitY(u, my)
    else
        call PauseTimer(t)
        call DestroyTimer(t)
        set t = null
        call FlushChildHashtable(ExampleHash, id)
    endif
    
    set counter = counter + 1
    call SaveInteger(ExampleHash, id, 1, counter)
    
    
endfunction

function Trig_Searing_Slash_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local unit u = GetTriggerUnit()
    local integer id = GetHandleId(t)
    local real tx = GetSpellTargetX()
    local real ty = GetSpellTargetY()
    
    call SaveUnitHandle(ExampleHash, id, 0, u)
    call SaveInteger(ExampleHash, id, 1, 0)
    call SaveReal(ExampleHash, id, 2, tx)
    call SaveReal(ExampleHash, id, 3, ty)
    call SaveInteger(ExampleHash, id, 4, 0)
    
    set angle[0] = 0
    set angle[1] = 360
    set angle[2] = 315
    set angle[3] = 135
    set angle[4] = 225
    set angle[5] = 45
    set angle[6] = 270
    set angle[7] = 90
    
    call TimerStart(t, .1, true, function Periodic)
    
    
endfunction

So it's goint to be something like this? It's just an example though so don't worry about leaks and nulling and stuff like that.

edit: I tried it like this it doesn't work. i increases but the unit just moves at the same angle.

JASS:
globals
    hashtable ExampleHash = InitHashtable()
    real array angle
endglobals
    
function Periodic takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    
    local unit u = LoadUnitHandle(ExampleHash, id, 0)
    local integer counter = LoadInteger(ExampleHash, id, 1)
    local real tx = LoadReal(ExampleHash, id, 2)
    local real ty = LoadReal(ExampleHash, id, 3)
    local integer i = LoadInteger(ExampleHash, id, 4)
    local real mx
    local real my
    
    if counter < 40 then
        if i < 7 then
            //set i = i + 1
            call SaveInteger(ExampleHash, id, 4, i + 1)
            call BJDebugMsg(I2S(i))
        else
            set i = 0
            call SaveInteger(ExampleHash, id, 4, i)
        endif
        set mx = tx + 350 + Cos(bj_DEGTORAD * angle[i])
        set my = ty + 350 + Sin(bj_DEGTORAD * angle[i])
        call SetUnitX(u, mx)
        call SetUnitY(u, my)
    else
        call PauseTimer(t)
        call DestroyTimer(t)
        set t = null
        call FlushChildHashtable(ExampleHash, id)
    endif
    
    set counter = counter + 1
    call SaveInteger(ExampleHash, id, 1, counter)
endfunction

function Searing_Slash_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local unit u = GetTriggerUnit()
    local integer id = GetHandleId(t)
    local real tx = GetSpellTargetX()
    local real ty = GetSpellTargetY()
    
    set angle[0] = 0
    set angle[1] = 360
    set angle[2] = 315
    set angle[3] = 135
    set angle[4] = 225
    set angle[5] = 45
    set angle[6] = 270
    set angle[7] = 90
    
    call SaveUnitHandle(ExampleHash, id, 0, u)
    call SaveInteger(ExampleHash, id, 1, 0)
    call SaveReal(ExampleHash, id, 2, tx)
    call SaveReal(ExampleHash, id, 3, ty)
    call SaveInteger(ExampleHash, id, 4, 0)
    
    call TimerStart(t, .1, true, function Periodic)
endfunction

function Trig_Searing_Slash_Conditions takes nothing returns boolean
    if GetSpellAbilityId() == 'A002' then
        call Searing_Slash_Actions()
    endif
    return false
endfunction
 
Last edited:
Level 20
Joined
Jul 14, 2011
Messages
3,213
You're not setting i = i+1 so i is always 0.

The comparison should be "if i <= 7" not just "< 7"

You have to null "u" too.

Do the angles declaration after the trigger creation (where you put the TriggerAddEvent and stuff, since it runs just once on map initialization)
 
Level 3
Joined
Sep 9, 2009
Messages
658
With this line, call SaveInteger(ExampleHash, id, 4, i + 1) i still increases. The debug message says so too. Besides, I had set i = i + 1 before and it still didn't work.

Do the angles declaration after the trigger creation (where you put the TriggerAddEvent and stuff, since it runs just once on map initialization)
I did what you said here and the Hero still won't move.
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
JASS:
        set mx = tx + 350 + Cos(bj_DEGTORAD * angle[i])
        set my = ty + 350 + Sin(bj_DEGTORAD * angle[i])
// wrong here. It's A + B * C
        set mx = tx + 350 >> * << Cos(bj_DEGTORAD * angle[i])
        set my = ty + 350 >> * << Sin(bj_DEGTORAD * angle[i])
 
Status
Not open for further replies.
Top