This function I discovered myself (and with the help of Captain Griffein from wc3campaigns). Simply put, if your actually playing a game, it will return true HOWEVER if your viewing the game as a replay it will return false. The function has been tested in MultiPlayer and it now causes no desyncs. There is only one downside, and that is the function uses up one pause (if anyone knows how to prevent this please tell)
How does it work?
Simply put a replay is just a file that contains the inputs from the various players when playing a game. However when
Wc3 views a replay, there are differences then if you were physically playing the game. One of the differences is pausing. If you are actually playing and you pause a game, it is paused. However during a replay, if you pause a game the replay simply finishes at the point you paused the game, if the game is resumed some time later then the replay completely skips the pause phase. There are only a few things that work in real time during pauses when your playing the game (anything else you do during the pause just gets 'suspended' until the game is resumed). The 2 things that work in real time are camera angles and trigger sleep action.
The function works by moving the camera during the pause. If the camera is moved during the pause, then you are playing the actual game. If the camera isn't moved then it is the replay (since the pause phase is totally skipped)
| Notes: |
- You can hide the pause message that happens in multiplayer (i.e. ******** has paused the game) by calling the function in Cinematic Mode. The cinematic mode has to last around 10 seconds to fully hide the message
- It is HIGHLY recommended that you save the returning value of the function into a boolean variable i.e. set someboolean = IsInGame() So you only call the function once (since it takes up a pause) |
HERE IS THE FUNCTION
//<- InGame function created by PandaMine with help from Captain Griffeinfunction IsInGame
takes nothing returns booleanlocal integer counter = 1
local real camerax
local real cameray
local real x
local real y
local boolean output
loop exitwhen counter > 12
if GetLocalPlayer
() == Player
(counter-1
) then set camerax = GetCameraTargetPositionX
() set cameray = GetCameraTargetPositionY
() endif set counter = counter + 1
endloopset counter = 1
call PauseGame
(true)call TriggerSleepAction
(0
)loop exitwhen counter > 12
if GetLocalPlayer
() == Player
(counter-1
) then call SetCameraPosition
(camerax + 1,cameray + 1
) endif set counter = counter + 1
endloopcall TriggerSleepAction
(0
)call PauseGame
(false)set counter = 1
loop exitwhen counter > 12
if GetLocalPlayer
() == Player
(counter-1
) then set x = GetCameraTargetPositionX
() if x == camerax + 1
then set output =
true else set output =
false endif call SetCameraPosition
(camerax,cameray
) endif set counter = counter + 1
endloopreturn output
endfunction
With the new change to the function, it no longer needs to be synchronised however you should still initialize it like this because it has been reported that selecting units + triggersleepaction can cause desyncs
function Initiate
takes nothing returns nothingcall EnableUserControl
(false)call TriggerSleepAction
(.0
)set udg_InGame = IsInGame
()call EnableUserControl
(true)endfunction