Warcraft III resources & community, 2003–2006 · archived

MapArrowKeysToUnit

not rated
Submitted by AltSubmitterConversion0 downloads
This code allows you with one simple function call to give arrow key control to the player of a unit. For example:

call MapArrowKeysToUnit(Player(0), grunt)

Now the 1st player can control the grunt with the arrow keys. Normally you'd have to setup several triggers and variables by hand to do this, but this function takes care of all that for you. If at anytime you want to turn the arrow key control off, you do this:

call KillUnitKeyControl(Player(0), grunt)

Notice that you have to specify the unit too. With this code you can have the player controlling multiple units with arrow keys at the same time! This could be used for cool puzzles, like in Zelda when you move your shadow moves too.

When using this code, make sure you set the camera up so that it either follows the unit or stays in place. By default pressing the arrow keys moves the camera in game, and it's hard to focus on the guy you're moving around if everytime you try to move him the camera veers off to the side ;)

NOTE: You will need the return bug exploits and the Handle Variables code for this code to work.

SHAMELESS PLUG: If you want to see this code in a real working map, download the unprotected version of Battledome ]|[ from http://battledome.wc3campaigns.com -- check the Hameka Wave trigger.

Source

function MapArrowKeysToUnit_GetTrigger takes nothing returns trigger
    local trigger temp = GetTriggeringTrigger()

    if(temp == null) then
        return Handle2Trigger(GetHandleHandle(GetExpiredTimer(), "thisTrigger"))
    endif

    return temp
endfunction

function MapArrowKeysToUnit_Child takes nothing returns nothing
    local eventid triggeringId = null
    local trigger thisTrigger = MapArrowKeysToUnit_GetTrigger()

    local unit whichUnit = H2U(GetHandleHandle(thisTrigger, "whichUnit"))
    local player whichPlayer = Handle2Player(GetHandleHandle(thisTrigger, "whichPlayer"))
    local location unitLoc = null

    local boolean UKeyPressed = GetHandleBoolean(thisTrigger, "UKeyPressed")
    local boolean DKeyPressed = GetHandleBoolean(thisTrigger, "DKeyPressed")
    local boolean RKeyPressed = GetHandleBoolean(thisTrigger, "RKeyPressed")
    local boolean LKeyPressed = GetHandleBoolean(thisTrigger, "LKeyPressed")

    local timer t = null
    local location movetargetTemp = null
    local real degreeTemp = 0
    local real signTemp = 1

    local boolean stopBit = GetHandleBoolean(whichPlayer, I2S(H2I(whichUnit)) + "Unmap")

    set t = GetExpiredTimer()

    //Terminate on a timer execution so that the timer can be deleted too
    if(stopBit and t != null) then
        call PauseTimer(t)
        call FlushHandleVars(t)
        call DestroyTimer(t)
        call FlushHandleVars(thisTrigger)
        call DestroyTrigger(thisTrigger)
        return
    endif

    //If this is being fired due to a keypress, store appropriately
    if(t == null) then
        set triggeringId = GetTriggerEventId()

        if(triggeringId == EVENT_PLAYER_ARROW_RIGHT_DOWN) then
            set RKeyPressed = true
        elseif(triggeringId == EVENT_PLAYER_ARROW_RIGHT_UP) then
            set RKeyPressed = false
        elseif(triggeringId == EVENT_PLAYER_ARROW_DOWN_DOWN) then
            set DKeyPressed = true
        elseif(triggeringId == EVENT_PLAYER_ARROW_DOWN_UP) then
            set DKeyPressed = false
        elseif(triggeringId == EVENT_PLAYER_ARROW_UP_DOWN) then
            set UKeyPressed = true
        elseif(triggeringId == EVENT_PLAYER_ARROW_UP_UP) then
            set UKeyPressed = false
        elseif(triggeringId == EVENT_PLAYER_ARROW_LEFT_DOWN) then
            set LKeyPressed = true
        elseif(triggeringId == EVENT_PLAYER_ARROW_LEFT_UP) then
            set LKeyPressed = false
        endif

        call SetHandleBoolean(thisTrigger, "RKeyPressed", RKeyPressed)
        call SetHandleBoolean(thisTrigger, "DKeyPressed", DKeyPressed)
        call SetHandleBoolean(thisTrigger, "UKeyPressed", UKeyPressed)
        call SetHandleBoolean(thisTrigger, "LKeyPressed", LKeyPressed)
    endif

    //If nothing is pressed just chill
    if(UKeyPressed == false and DKeyPressed == false and RKeyPressed == false and LKeyPressed == false) then
        return
    endif

    if(UKeyPressed) then
        set degreeTemp = 90
        set signTemp = 1
    elseif(DKeyPressed) then
        set degreeTemp = 270
        set signTemp = -1
    endif

    if(RKeyPressed and (UKeyPressed or DKeyPressed)) then
        set degreeTemp = degreeTemp - 45*signTemp
    elseif(LKeyPressed and (UKeyPressed or DKeyPressed)) then
        set degreeTemp = degreeTemp + 45*signTemp
    elseif(RKeyPressed and not(UKeyPressed) and not(DKeyPressed)) then
        set degreeTemp = 0
    elseif(LKeyPressed and not(UKeyPressed) and not(DKeyPressed)) then
        set degreeTemp = 180
    endif

    set unitLoc = GetUnitLoc(whichUnit)

    set movetargetTemp = PolarProjectionBJ(unitLoc, 190, degreeTemp)

    //Only order if not already moving, helps stop chicken walk effect
    if(GetUnitCurrentOrder(whichUnit) != 851972) then
        call IssuePointOrderLoc(whichUnit, "move", movetargetTemp )
    endif

    call RemoveLocation(movetargetTemp)
    call RemoveLocation(unitLoc)
endfunction

function KillUnitKeyControl takes player whichPlayer, unit whichUnit returns nothing
    call SetHandleBoolean(whichPlayer, I2S(H2I(whichUnit)) + "Unmap", true)
endfunction

function MapArrowKeysToUnit takes player whichPlayer, unit whichUnit returns nothing
    local trigger ArrowKeyTrigger = null
    local timer t = CreateTimer()

    if(whichPlayer == null or whichUnit == null) then
        return
    endif

    set ArrowKeyTrigger = CreateTrigger()
    call TriggerRegisterPlayerEvent(ArrowKeyTrigger, whichPlayer, EVENT_PLAYER_ARROW_RIGHT_DOWN)
    call TriggerRegisterPlayerEvent(ArrowKeyTrigger, whichPlayer, EVENT_PLAYER_ARROW_RIGHT_UP)
    call TriggerRegisterPlayerEvent(ArrowKeyTrigger, whichPlayer, EVENT_PLAYER_ARROW_LEFT_DOWN)
    call TriggerRegisterPlayerEvent(ArrowKeyTrigger, whichPlayer, EVENT_PLAYER_ARROW_LEFT_UP)
    call TriggerRegisterPlayerEvent(ArrowKeyTrigger, whichPlayer, EVENT_PLAYER_ARROW_UP_DOWN)
    call TriggerRegisterPlayerEvent(ArrowKeyTrigger, whichPlayer, EVENT_PLAYER_ARROW_UP_UP)
    call TriggerRegisterPlayerEvent(ArrowKeyTrigger, whichPlayer, EVENT_PLAYER_ARROW_DOWN_DOWN)
    call TriggerRegisterPlayerEvent(ArrowKeyTrigger, whichPlayer, EVENT_PLAYER_ARROW_DOWN_UP)
    call SetHandleHandle(ArrowKeyTrigger, "whichUnit", whichUnit)
    call SetHandleHandle(ArrowKeyTrigger, "whichPlayer", whichPlayer)
    call SetHandleBoolean(whichPlayer, I2S(H2I(whichUnit)) + "Unmap", false)
    call TriggerAddAction(ArrowKeyTrigger, function MapArrowKeysToUnit_Child)

    //Have to store trigger in timer so that if executed when timer expires
    //can find stuff in the game cache
    call SetHandleHandle(t, "thisTrigger", ArrowKeyTrigger)

    //Have to periodically give move orders too
    //.3 seems to be the magic chicken walk effect avoiding number. No idea why.
    call TimerStart(t, .3, true, function MapArrowKeysToUnit_Child)
endfunction

Comments

3
I don't get it... I tried to download the battledome thing as something to look off of and model this trig from but I can't download it, the lnk brings me up to this "news" page and there are no download things on it so uh, mind helping me with this thing plz?
As I understand it (which is not very well), you want to paste this into the custom text area at the beginning of your map... i.e., when you select the topmost icon in the trigger tree. But you also need various other custom functions that are referenced in the trigger... you'll have to find them on this site somewhere.

I found one of them, SetHandleHandle(), at http://www.ewc3sear.ch/index.php?p=JASS&ID=218 , but I have no idea how many more you'll need. Then paste those triggrs above this one in the custom text area.
I really need this trigger for a RPG map that i am creating. But i do not understand how to use this other then make a trigg into text then copy and paste(didnt work got erros). It would be greatly apretiated if u could put it on a blank map for me plz. And of course i would give you a huge thanks on my map. Oh and the map im creating is no halfassed map i belive it could be one of the best RPGs out there. Thanks ! :D :D