• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] OrderID and SetPosition

Status
Not open for further replies.
Level 3
Joined
Jul 15, 2007
Messages
36
Dear all;

I am trying to make a function which:

  • Grabs all units in range of a unit
  • Saves their current order (orderId integer)
  • Moves them to point of unit
  • Applies damage
  • Re-issues the moved units' order (which is a move-to point)

It is for use in a TD, and unit is a dummy unit.

I am wondering if the orderId (integer) that you get by GetUnitCurrentOrder(u) is issuable to the unit again via IssueImmediateOrderById(unit, orderid) and will it remember the location the unit was ordered to, or does it lose the point it was ordered to.

Or simply; Can you take a unit which has been issued a move-to-point order, move it instantly via SetUnitPosition(unit, X, Y), then have it resume that move order?

Thanks!

=====EDIT=====

Here is the code I have assembled:
JASS:
//================== NEXUS SCRIPT =========================
//

//================== NEXUS SCRIPT =========================
//

function Nexus_Actions takes unit u, integer level returns nothing
    local group g = CreateGroup()
    local unit dummy
    local unit manipulate
    local real r = 300
    local integer order
    local integer d = 40
    local real X = GetUnitX(u)
    local real Y = GetUnitY(u)
    call BJDebugMsg( GetUnitName(u) + " has been hit by Nexus ability level" + I2S(level))
    //Set damage amount based on level
    if level == 1 then
        set d = 40
    elseif level == 2 then
        set d = 80
    elseif level == 3 then
        set d = 160
    elseif level == 4 then
        set d = 320
    elseif level == 5 then
        set d = 640
    elseif level == 6 then
        set d = 1280
    endif
    set dummy = CreateUnit(Player(0), 'u00C', X, Y, 270 )
    call UnitApplyTimedLife(dummy, 'u00C', 0.2) 
    call GroupEnumUnitsInRange(g, X, Y, r, null)
    loop
        set manipulate = FirstOfGroup(g)
        exitwhen manipulate == null
        if GetOwningPlayer(manipulate) == Player(11)then     // for all groups in unit, owned by player 11
            set order = GetUnitCurrentOrder(manipulate)     // get current order
            call SetUnitPosition(manipulate, X, Y)     // move unit instantly to nexus
            call UnitDamageTarget( dummy, manipulate, d, true, true, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )     // apply damage to unit
            call IssueImmediateOrderById(manipulate, order)     // issue previous "current order" to unit
        endif
        call GroupRemoveUnit(g, manipulate) //remove unit from group
    endloop
    set manipulate = null
    call RemoveUnit(manipulate)
    set g = null
    call DestroyGroup(g)
    set dummy = null
    call RemoveUnit(dummy)
endfunction

It doesn't seem to give the unit any order in testing, but otherwise works appropriately

Additionally, can the
JASS:
call GroupEnumUnitsInRange(g, X, Y, r, null)
"booleanexp" that I've set to null filter only units of one player? I'm not sure how to use this function, but done some guesswork from GUI/BJ's

Thanks! :)


=============EDIT2==================
I have made the following work-around using (essentially) pre-defined regions for the unit:

JASS:
//================== NEXUS SCRIPT =========================
//

function Nexus_Actions takes unit u, integer level returns nothing
    local group g = CreateGroup()
    local unit dummy
    local unit manipulate
    local real r = 300
    local integer d = 40
    local real X = GetUnitX(u)
    local real Y = GetUnitY(u)
    call BJDebugMsg( GetUnitName(u) + " has been hit by Nexus ability level" + I2S(level))
    //Set damage amount based on level
    if level == 1 then
        set d = 40
    elseif level == 2 then
        set d = 80
    elseif level == 3 then
        set d = 160
    elseif level == 4 then
        set d = 320
    elseif level == 5 then
        set d = 640
    elseif level == 6 then
        set d = 1280
    endif
    //set dummy = CreateUnit(Player(0), 'u00C', X, Y, 270 )
    call UnitApplyTimedLife(dummy, 'u00C', 0.8) 
    call GroupEnumUnitsInRange(g, X, Y, r, null)
    loop
        set manipulate = FirstOfGroup(g)
        exitwhen manipulate == null
        call TriggerSleepAction(0.4)
        if GetOwningPlayer(manipulate) == Player(11)then     // for all groups in unit, owned by player 11
            call SetUnitPosition(manipulate, X, Y)     // move unit instantly to nexus
            call UnitDamageTarget( dummy, manipulate, d, true, true, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )     // apply damage to unit
            if (X <= 800) and (X >= -1056) and (Y <= 416) and (Y >= 96) then //top row
                call IssuePointOrder(manipulate, "Move", 976, 256)
            elseif (X >= 801) and (X <= 1024) and (Y <= 416) and (Y>= -992) then//right hand column
                call IssuePointOrder(manipulate, "Move", 912, -1232)
            elseif (X >= 128) and (X <= 1056) and (Y <= -992) and (Y>= -1280) then//bottomw row
                call IssuePointOrder(manipulate, "Move", -48, -1136)
            elseif (X >= -128) and (X <= 128) and (Y <= -640) and (Y>= -1280) then//middle column
                call IssuePointOrder(manipulate, "Move", 0, -432)
            elseif (X >= -768) and (X <= 128) and (Y <= -384) and (Y>= -640) then//middle row
                call IssuePointOrder(manipulate, "Move", -944, -512)
            elseif (X >= -992) and (X <= -768) and (Y <= -384) and (Y>= -1632) then//left column
                call IssuePointOrder(manipulate, "Move", -88, -1536)
            endif
        endif
        call GroupRemoveUnit(g, manipulate) //remove unit from group
    endloop
    set manipulate = null
    call RemoveUnit(manipulate)
    set g = null
    call DestroyGroup(g)
    set dummy = null
    call RemoveUnit(dummy)
endfunction

If anyone can tell me another (simpler and more generic) way to do it, I'd love to hear from you
 
Last edited:
Level 3
Joined
Jul 15, 2007
Messages
36
Ah, excellent; much cleaner and more usable without those region checks;

JASS:
//================== NEXUS SCRIPT =========================
//

function Nexus_Actions takes unit u, integer level returns nothing
    local group g = CreateGroup()
    local unit dummy
    local unit manipulate
    local real r = 300
    local integer d = 40
    local real X = GetUnitX(u)
    local real Y = GetUnitY(u)
   // call BJDebugMsg( GetUnitName(u) + " has been hit by Nexus ability level" + I2S(level))
    //Set damage amount based on level
    if level == 1 then
        set d = 80
    elseif level == 2 then
        set d = 160
    elseif level == 3 then
        set d = 3200
    elseif level == 4 then
        set d = 640
    elseif level == 5 then
        set d = 1280
    elseif level == 6 then
        set d = 2560
    endif
    set dummy = CreateUnit(Player(0), 'u00C', X, Y, 270 )
    call UnitApplyTimedLife(dummy, 'u00C', 0.6) 
    call GroupEnumUnitsInRange(g, X, Y, r, null)
    loop
        set manipulate = FirstOfGroup(g)
        exitwhen manipulate == null
        call TriggerSleepAction(0.2)
        if GetOwningPlayer(manipulate) == Player(11)then     // for all groups in unit, owned by player 11
            call SetUnitX(manipulate, X)
            call SetUnitY(manipulate, Y)
            call UnitDamageTarget( dummy, manipulate, d, true, true, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )     // apply damage to unit
        endif
        call GroupRemoveUnit(g, manipulate) //remove unit from group
    endloop
    set manipulate = null
    call RemoveUnit(manipulate)
    set g = null
    call DestroyGroup(g)
    set dummy = null
    call RemoveUnit(dummy)
endfunction

Any advice about the "filter" in GroupEnumUnitsInRange, i.e. can i filter out only units of Player(11) ?

Thanks Again!
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
Filter out as in only use or only not use?

Well, here's an example filter:

JASS:
function SomeFilterFunction takes nothing returns boolean
    return GetWidgetLife(GetFilterUnit()) > 0
endfunction

//[...]

call GroupEnumUnitsInRange( g, x, y, r, Filter( function SomeFilterFunction )

Anyhow, if you're asking what the code would be;

If you want to only get units of p11, it would be

return GetOwningPlayer(GetFilterUnit())==Player(11)

If you want to get only units not of p11, it would be

return GetOwningPlayer(GetFilterUnit())!=Player(11)
 
Status
Not open for further replies.
Top