• 🏆 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!

Mouse Movement System v1.2a

  • Like
Reactions: Vegavak and Vinz
Well since new Warcraft 3 patch brought mouse movement I thought why not?
Pretty easy to make System if you have general knowledge of GUI.

The use of this system:
Press and Hold the Right Click button and your hero will follow it around.

WARNING!
Setting the periodic event too low will cause walk animation problems.

UPDATE:
I found this by accident and thought why not update it? people were complaining because it didn't support 24 players before so now it does >_<

Also added a trigger for changing the "MouseUnit" when a player selects a different unit.
  • Mouse Setup
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- ------------Set the Number of Players you want the System to use----------- --------
      • Set MouseMaxPlayers = 24
      • -------- ------------------------------------------------------------------------------------------------------------- --------
      • -------- ------------Register the Units you want to be used for each Player----------- --------
      • Set MouseUnit[1] = Blademaster 0001 <gen>
      • Set MouseUnit[2] = Blademaster 0002 <gen>
      • Set MouseUnit[3] = Blademaster 0003 <gen>
      • Set MouseUnit[4] = Blademaster 0004 <gen>
      • Set MouseUnit[5] = Blademaster 0005 <gen>
      • Set MouseUnit[6] = Blademaster 0006 <gen>
      • Set MouseUnit[7] = Blademaster 0007 <gen>
      • Set MouseUnit[8] = Blademaster 0008 <gen>
      • Set MouseUnit[9] = Blademaster 0009 <gen>
      • Set MouseUnit[10] = Blademaster 0010 <gen>
      • Set MouseUnit[11] = Blademaster 0011 <gen>
      • Set MouseUnit[12] = Blademaster 0012 <gen>
      • Set MouseUnit[13] = Blademaster 0000 <gen>
      • Set MouseUnit[14] = Blademaster 0025 <gen>
      • Set MouseUnit[15] = Blademaster 0026 <gen>
      • Set MouseUnit[16] = Blademaster 0027 <gen>
      • Set MouseUnit[17] = Blademaster 0028 <gen>
      • Set MouseUnit[18] = Blademaster 0029 <gen>
      • Set MouseUnit[19] = Blademaster 0030 <gen>
      • Set MouseUnit[20] = Blademaster 0031 <gen>
      • Set MouseUnit[21] = Blademaster 0032 <gen>
      • Set MouseUnit[22] = Blademaster 0033 <gen>
      • Set MouseUnit[23] = Blademaster 0034 <gen>
      • Set MouseUnit[24] = Blademaster 0035 <gen>
      • -------- ------------------------------------------------------------------------------------------------------------- --------
      • -------- ------------------------------------------------------------------------------------------------------------- --------
      • -------- ---------------------------DONT EDIT ANYTHING BELOW---------------------------- --------
      • -------- ------------------------------------------------------------------------------------------------------------- --------
      • -------- Check if Player is Human --------
      • For each (Integer Mouse_i) from 1 to MouseMaxPlayers, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Player(Mouse_i)) controller) Equal to User
              • ((Player(Mouse_i)) slot status) Equal to Is playing
            • Then - Actions
              • -------- register mouse click --------
              • Trigger - Add to Mouse Click <gen> the event (Player - (Player(Mouse_i)) issues Mouse Down event)
              • -------- register mouse release --------
              • Trigger - Add to Mouse Release <gen> the event (Player - (Player(Mouse_i)) issues Mouse Up event)
              • -------- register mouse detect --------
              • Trigger - Add to Mouse Detect <gen> the event (Player - (Player(Mouse_i)) issues Mouse Move event)
              • -------- register unit selection --------
              • Trigger - Add to Mouse ChangeUnit <gen> the event (Player - (Player(Mouse_i)) Selects a unit)
            • Else - Actions[
  • Mouse Click
    • Events
    • Conditions
      • (Trigger Mouse Button) Equal to Right Mouse Button
    • Actions
      • Set MouseClick[(Player number of (Triggering player))] = True
  • Mouse Release
    • Events
    • Conditions
      • (Trigger Mouse Button) Equal to Right Mouse Button
    • Actions
      • Set MouseClick[(Player number of (Triggering player))] = False
  • Mouse Detect
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • MouseClick[(Player number of (Triggering player))] Equal to True
        • Then - Actions
          • Set MouseX[(Player number of (Triggering player))] = (Mouse Position X for Triggered Mouse Event)
          • Set MouseY[(Player number of (Triggering player))] = (Mouse Position Y for Triggered Mouse Event)
        • Else - Actions
  • Mouse ChangeUnit
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Owner of (Triggering unit)) Equal to (Triggering player)
        • Then - Actions
          • Set MouseUnit[(Player number of (Triggering player))] = (Triggering unit)
        • Else - Actions
  • Mouse UnitMove
    • Events
      • Time - Every 0.50 seconds of game time
    • Conditions
    • Actions
      • For each (Integer Mouse_i) from 1 to MouseMaxPlayers, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • And - All (Conditions) are true
                • Conditions
                  • MouseClick[Mouse_i] Equal to True
                  • MouseX[Mouse_i] Not equal to 0.00
                  • MouseY[Mouse_i] Not equal to 0.00
            • Then - Actions
              • Set MousePoint = (Point(MouseX[Mouse_i], MouseY[Mouse_i]))
              • Unit - Order MouseUnit[Mouse_i] to Move To MousePoint
              • Custom script: call RemoveLocation(udg_MousePoint)
            • Else - Actions
Contents

Mouse Movement System v1.2a (Map)

Reviews
Dr Super Good
Comments and Suggestions: Due to the simplicity it is potentially useful as a starting step for mouse based movement systems similar to those in the Diablo series. Additionally there are a lot of nice comments in the resource thread with alternative...
Level 18
Joined
Oct 17, 2012
Messages
818
  • Untitled Trigger 001
    • Events
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 24, do (Actions)
        • Loop - Actions
          • Trigger - Add to (This trigger) the event (Player - (Player((Integer A))) issues Mouse Down event)
          • Trigger - Add to (This trigger) the event (Player - (Player((Integer A))) issues Mouse Up event)
          • Trigger - Add to (This trigger) the event (Player - (Player((Integer A))) issues Mouse Move event)
  • Player Group - Pick every player in (All players) and do (Actions)
    • Loop - Actions
      • Trigger - Add to (This trigger) the event (Player - (Picked player) issues Mouse Down event)
      • Trigger - Add to (This trigger) the event (Player - (Picked player) issues Mouse Up event)
      • Trigger - Add to (This trigger) the event (Player - (Picked player) issues Mouse Move event)
 
I was thinking of something like that, only utilizing the native native GetTriggerEventId takes nothing returns eventid if it has a GUI equivalent.

On the specified triggers (Mouse Click, Detect and Release), remove the already included events and replace them with map initialization. Upon Map Initialization (this is where GetTriggerEventId() comes in, a condition), do a loop from Player 1 to 24, which will include those events anyway.
 
Level 19
Joined
Jul 12, 2010
Messages
1,713
This would allow you to move your Hero even when you don't have it selected, i never thought of that
yeah it can definitely be helpful in hero arenas, you could theoretically move your hero and keep selected a dummy unit with 12 different abilities for example :D

A little bit of heads up,

How about the other 12 players?

In unit-move, you can remove the condition that both coordinates must not be zero since you only need the flag variable in order to move them.
Adding more players it's not hard actually all you have to do is register the units and increase the loop to 24 players.

I'm not sure I understand what you said about flag variable...although the X & Y mouse detection is essential because if you read the trigger comment in "unit move" I said:
"If MouseX is 0.00 and MouseY is 0.0 then it means the mouse is on the User Interface."
if you order the unit to move while player mouse is on the UI it automatically orders it to move in center of the map so I had to use X & Y detection to avoid that hassle.

  • Untitled Trigger 001
    • Events
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 24, do (Actions)
        • Loop - Actions
          • Trigger - Add to (This trigger) the event (Player - (Player((Integer A))) issues Mouse Down event)
          • Trigger - Add to (This trigger) the event (Player - (Player((Integer A))) issues Mouse Up event)
          • Trigger - Add to (This trigger) the event (Player - (Player((Integer A))) issues Mouse Move event)
  • Player Group - Pick every player in (All players) and do (Actions)
    • Loop - Actions
      • Trigger - Add to (This trigger) the event (Player - (Picked player) issues Mouse Down event)
      • Trigger - Add to (This trigger) the event (Player - (Picked player) issues Mouse Up event)
      • Trigger - Add to (This trigger) the event (Player - (Picked player) issues Mouse Move event)
Yes I know I could have used that but I thought it might bring map lag when you enter game in huge maps with a lot of setup triggers that loop actions.

Perhaps I could include it in a separate trigger and have it disabled.
 
Level 6
Joined
Aug 28, 2015
Messages
213
I got also inspired by the new mouse natives and come up with this system after seeing yours I think this could get some inspiration.

  • Input Initialization
    • Events
      • Time - Elapsed game time is 0.30 seconds
    • Conditions
    • Actions
      • -------- the maximum amount of time that can pass before it's not counted as double ckilck anymore --------
      • Set Input_DCFrequenceTime = 0.20
      • For each (Integer Input_Index) from 1 to Game_MaxPlayer, do (Actions)
        • Loop - Actions
          • Trigger - Add to Input MouseDown <gen> the event (Player - (Player(Input_Index)) issues Mouse Down event)
          • Trigger - Add to Input MouseUp <gen> the event (Player - (Player(Input_Index)) issues Mouse Up event)
          • Trigger - Add to Input MouseMove <gen> the event (Player - (Player(Input_Index)) issues Mouse Move event)
          • Set Input_IsLeftClicked[Input_Index] = False
          • Set Input_IsMiddleClicked[Input_Index] = False
          • Set Input_IsRightClicked[Input_Index] = False
          • Trigger - Add to Input RestetDoubleClick <gen> the event (Time - Input_DCTimerLeft[Input_Index] expires)
          • Set Input_IsDoubleClickingL[Input_Index] = False
          • Trigger - Add to Input RestetDoubleClick <gen> the event (Time - Input_DCTimerMiddle[Input_Index] expires)
          • Set Input_IsDoubleClickingM[Input_Index] = False
          • Trigger - Add to Input RestetDoubleClick <gen> the event (Time - Input_DCTimerRight[Input_Index] expires)
          • Set Input_IsDoubleClickingR[Input_Index] = False
  • Input MouseUp
    • Events
    • Conditions
    • Actions
      • Set Input_PlayerID = (Player number of (Triggering player))
      • Set Input_MousePoint[Input_PlayerID] = (Mouse Position for Triggered Mouse Event)
      • Set Input_MouseX[Input_PlayerID] = (Mouse Position X for Triggered Mouse Event)
      • Set Input_MouseY[Input_PlayerID] = (Mouse Position Y for Triggered Mouse Event)
      • -------- Left --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Trigger Mouse Button) Equal to Left Mouse Button
        • Then - Actions
          • -------- Left Up --------
          • Set Input_IsLeftClicked[Input_PlayerID] = False
          • -------- Start timer to check for double click --------
          • Set Input_IsDoubleClickingL[Input_PlayerID] = True
          • Countdown Timer - Start Input_DCTimerLeft[Input_PlayerID] as a One-shot timer that will expire in Input_DCFrequenceTime seconds
        • Else - Actions
      • -------- Right --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Trigger Mouse Button) Equal to Right Mouse Button
        • Then - Actions
          • -------- Right Up --------
          • Set Input_IsRightClicked[Input_PlayerID] = False
          • -------- Start timer to check for double click --------
          • Set Input_IsDoubleClickingR[Input_PlayerID] = True
          • Countdown Timer - Start Input_DCTimerRight[Input_PlayerID] as a One-shot timer that will expire in Input_DCFrequenceTime seconds
        • Else - Actions
      • -------- Middle --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Trigger Mouse Button) Equal to Middle Mouse Button
        • Then - Actions
          • -------- Middle Up --------
          • Set Input_IsMiddleClicked[Input_PlayerID] = False
          • -------- Start timer to check for double click --------
          • Set Input_IsDoubleClickingM[Input_PlayerID] = True
          • Countdown Timer - Start Input_DCTimerMiddle[Input_PlayerID] as a One-shot timer that will expire in Input_DCFrequenceTime seconds
        • Else - Actions
  • Input MouseDown
    • Events
    • Conditions
    • Actions
      • Set Input_PlayerID = (Player number of (Triggering player))
      • Set Input_MousePoint[Input_PlayerID] = (Mouse Position for Triggered Mouse Event)
      • Set Input_MouseX[Input_PlayerID] = (Mouse Position X for Triggered Mouse Event)
      • Set Input_MouseY[Input_PlayerID] = (Mouse Position Y for Triggered Mouse Event)
      • -------- Left --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Trigger Mouse Button) Equal to Left Mouse Button
          • Input_MouseX[Input_PlayerID] Not equal to 0.00
          • Input_MouseY[Input_PlayerID] Not equal to 0.00
        • Then - Actions
          • -------- Left down --------
          • Set Input_IsLeftClicked[Input_PlayerID] = True
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Input_IsDoubleClickingL[Input_PlayerID] Equal to True
            • Then - Actions
              • -------- Left double click --------
            • Else - Actions
        • Else - Actions
      • -------- Right --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Trigger Mouse Button) Equal to Right Mouse Button
          • Input_MouseX[Input_PlayerID] Not equal to 0.00
          • Input_MouseY[Input_PlayerID] Not equal to 0.00
        • Then - Actions
          • -------- Right down --------
          • Set Input_IsRightClicked[Input_PlayerID] = True
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Input_IsDoubleClickingR[Input_PlayerID] Equal to True
            • Then - Actions
              • -------- Right double click --------
            • Else - Actions
        • Else - Actions
      • -------- Middle --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Trigger Mouse Button) Equal to Middle Mouse Button
          • Input_MouseX[Input_PlayerID] Not equal to 0.00
          • Input_MouseY[Input_PlayerID] Not equal to 0.00
        • Then - Actions
          • -------- Middle down --------
          • Set Input_IsMiddleClicked[Input_PlayerID] = True
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Input_IsDoubleClickingM[Input_PlayerID] Equal to True
            • Then - Actions
              • -------- Middle double click --------
            • Else - Actions
        • Else - Actions
  • Input MouseMove
    • Events
    • Conditions
    • Actions
      • Set Input_PlayerID = (Player number of (Triggering player))
      • Set Input_MousePoint[Input_PlayerID] = (Mouse Position for Triggered Mouse Event)
      • Set Input_MouseX[Input_PlayerID] = (Mouse Position X for Triggered Mouse Event)
      • Set Input_MouseY[Input_PlayerID] = (Mouse Position Y for Triggered Mouse Event)
      • -------- Left --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Input_IsLeftClicked[Input_PlayerID] Equal to True
        • Then - Actions
          • -------- Left click drag --------
        • Else - Actions
      • -------- Right --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Input_IsRightClicked[Input_PlayerID] Equal to True
        • Then - Actions
          • -------- Right click drag --------
        • Else - Actions
      • -------- Middle --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Input_IsMiddleClicked[Input_PlayerID] Equal to True
        • Then - Actions
          • -------- Middle click drag --------
        • Else - Actions
  • Input RestetDoubleClick
    • Events
    • Conditions
    • Actions
      • For each (Integer Input_DCIndex) from 1 to Game_MaxPlayer, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Remaining time for Input_DCTimerLeft[Input_DCIndex]) Less than or equal to 0.00
              • Input_IsDoubleClickingL[Input_DCIndex] Equal to True
            • Then - Actions
              • Set Input_IsDoubleClickingL[Input_DCIndex] = False
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Remaining time for Input_DCTimerMiddle[Input_DCIndex]) Less than or equal to 0.00
              • Input_IsDoubleClickingM[Input_DCIndex] Equal to True
            • Then - Actions
              • Set Input_IsDoubleClickingM[Input_DCIndex] = False
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Remaining time for Input_DCTimerRight[Input_DCIndex]) Less than or equal to 0.00
              • Input_IsDoubleClickingR[Input_DCIndex] Equal to True
            • Then - Actions
              • Set Input_IsDoubleClickingR[Input_DCIndex] = False
            • Else - Actions
 
Last edited:
As logics is anyways not too much, focus could be on providing easy usage, not caring for checks/loops himself. If you want you can take attached code, it's also jass-user friendly.


JASS:
// Threshold timeout to fire event for one player
constant function MouseMovement_Timeout takes nothing returns real
    return 0.2
endfunction

function MouseMovement_onClick takes nothing returns nothing
    if (BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT) then
        set udg_MMS_IsClicked[GetPlayerId(GetTriggerPlayer())] = true
    endif
endfunction

function MouseMovement_onRelease takes nothing returns nothing
    if (BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT) then
        set udg_MMS_IsClicked[GetPlayerId(GetTriggerPlayer())] = false
    endif
endfunction

function MouseMovement_onMove takes nothing returns nothing
    local integer playerId = GetPlayerId(GetTriggerPlayer())
    if (udg_MMS_IsClicked[playerId] and TimerGetRemaining(udg_MMS_Timer[playerId]) == 0 ) then
        if MouseMovement_Timeout() > 0 then
            call TimerStart(udg_MMS_Timer[playerId], MouseMovement_Timeout(), false, null)
        endif
        set udg_MMS_X = BlzGetTriggerPlayerMouseX()
        set udg_MMS_Y = BlzGetTriggerPlayerMouseY()
        set udg_MMS_Location = Location(udg_MMS_X, udg_MMS_Y)
        set udg_MMS_Player = GetTriggerPlayer()
        set udg_MMS_Event = 1
        set udg_MMS_Event = 0
        call RemoveLocation(udg_MMS_Location)
    endif
endfunction

function MouseMovement_MouseRegister takes trigger t, integer ev returns nothing
    local integer i = 0
    loop
        exitwhen i > 24
        call TriggerRegisterPlayerMouseEventBJ(t, Player(i), ev)
        set i = i + 1
    endloop
endfunction

function InitTrig_MouseMovement takes nothing returns nothing
    local trigger t
    local integer i
 
    set t = CreateTrigger()
    call TriggerAddAction(t, function MouseMovement_onClick)
    call MouseMovement_MouseRegister(t, bj_MOUSEEVENTTYPE_DOWN)
 
    set t = CreateTrigger()
    call TriggerAddAction(t, function MouseMovement_onRelease)
    call MouseMovement_MouseRegister(t, bj_MOUSEEVENTTYPE_UP)
 
    set t = CreateTrigger()
    call TriggerAddAction(t, function MouseMovement_onMove)
    call MouseMovement_MouseRegister(t, bj_MOUSEEVENTTYPE_MOVE)
 
    set i = 0
    loop
        exitwhen i > 24
        set udg_MMS_Timer[i] = CreateTimer()
        set i = i + 1
    endloop
endfunction

edit:

It would be even cooler if the timer callback would fire the event, too, so the last event is never ignored. The X/Y would have to be updated for this each run, not only when threshold allows.
 

Attachments

  • Mouse Movement System v1.1.w3x
    32.2 KB · Views: 308
Last edited:
I wonder if there's a way to implement this system into the game instead of a single map?
Could it be done? There's a number of maps where this would be very useful indeed.
It is possible to overwrite/overlap "blizzard.j", with a custom "blizzard.j" in which you added aditional code.
"blizzard.j" is used by most maps.

Problem Multiplayer:
Players using a custom "blizzard.j" would desync from players not using the same custom "blizzard.j".
I am also not sure, if "Battle.net" would let you play at all or that would even count as hacking.
Although It works in Single Player.
Edit: I Tested it now in Lan with 2 computers (V1.30.1.10211) , Having different content in "Blizzard.j" as game lobby owner (host) leads to an autokick.
 
Last edited:

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
Required for Approval:
There are potentially more than just 12 human players. I suggest running a loop at map initialization which adds the mouse events to the triggers. This loop should pick players from all players for maximum future proofing. The players should be filtered for active human players since creating the events for inactive slots or for computer players is pointless.
Comments and Suggestions:
Due to the simplicity it is potentially useful as a starting step for mouse based movement systems similar to those in the Diablo series. Additionally there are a lot of nice comments in the resource thread with alternative implementations, extensions and suggestions that people may find useful.

Why is position (0, 0) not accepted as a valid cursor destination? A comment in the map explaining why might be useful.

The periodic unit movement trigger should only issue a move order if the player has changed the position of their cursor since the last time the trigger ran. This would potentially help reduce animation issues as well as path finder load in some cases.​
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
Comments and Suggestions:
Due to the simplicity it is potentially useful as a starting step for mouse based movement systems similar to those in the Diablo series. Additionally there are a lot of nice comments in the resource thread with alternative implementations, extensions and suggestions that people may find useful.

Why is position (0, 0) not accepted as a valid cursor destination? A comment in the map explaining why might be useful.

The periodic unit movement trigger should only issue a move order if the player has changed the position of their cursor since the last time the trigger ran. This would potentially help reduce animation issues as well as path finder load in some cases.​
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
Comments and Suggestions:
Due to the simplicity it is potentially useful as a starting step for mouse based movement systems similar to those in the Diablo series. Additionally there are a lot of nice comments in the resource thread with alternative implementations, extensions and suggestions that people may find useful.

The periodic unit movement trigger should only issue a move order if the player has changed the position of their cursor since the last time the trigger ran. This would potentially help reduce animation issues as well as path finder load in some cases.​
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
That comment was already there from the first time I uploaded the system.
Ops did not notice the GUI comment. Too used to script style comments where the comments are part of the script rather than in a separate panel. I must have forgotten to look up.

Do note that the multi posts are a result of how moderation works. The moderator comment can only be updated by making a new post.
 
Top