Troll-Brain
You can change this now in User CP.
- Reaction score
- 85
It's a script for the lul'z.
By war3 minimized i mean when you reduce it to use an other software, i'm not talking about the window mode.
It won't work on single player mode because war3 is paused when you minimize it, but war3 won't be paused when you play on local area network, battle.net,whatever.
DrawBacks that shouldn't be fixed :
- Each time the "system" will do a check, a "pan" camera will be applied, so if the player pressed an arrow or moved the camera with the mouse, the movement will be stop.
Unfortunately i don't think it could be fix in any way, even for the arrows, since the arrow press event has delay.
- Theoretically it could fail if the user press the space bar.
- You can't use it when a camerasetup or just a camera field which are currently applied during time, last time i checked it fucks up all the move.
- You can't use a target noise
DrawBacks that should be fixed :
- Theoretically it could fuck up the player unit selection. (game cache sync instead ? but i don't know how to do it for each players, someone ?)
- You can't use it with SetCameraTargetController and such things, i think i could play around that using hooks though.
I know :
- It will fail if the camera is on top right, but fortunately this case can be fixed easily
- The code needs to be improved in some ways, like adding more constants, use the booleexpr of TriggerRegisterPlayerEvent, be able to enable/disable the check, handle leavers, and so one.
It's one second (in)accurate and i don't recommend to try a lower value.
Now, i just want to know your feedbacks, and if they are good enough i will work on removing some cons, fixing known lame things.
PS : If you already pan your camera each 0.03 s or so, you would inline this method instead.
And a short lame example :
By war3 minimized i mean when you reduce it to use an other software, i'm not talking about the window mode.
It won't work on single player mode because war3 is paused when you minimize it, but war3 won't be paused when you play on local area network, battle.net,whatever.
DrawBacks that shouldn't be fixed :
- Each time the "system" will do a check, a "pan" camera will be applied, so if the player pressed an arrow or moved the camera with the mouse, the movement will be stop.
Unfortunately i don't think it could be fix in any way, even for the arrows, since the arrow press event has delay.
- Theoretically it could fail if the user press the space bar.
- You can't use it when a camerasetup or just a camera field which are currently applied during time, last time i checked it fucks up all the move.
- You can't use a target noise
DrawBacks that should be fixed :
- Theoretically it could fuck up the player unit selection. (game cache sync instead ? but i don't know how to do it for each players, someone ?)
- You can't use it with SetCameraTargetController and such things, i think i could play around that using hooks though.
I know :
- It will fail if the camera is on top right, but fortunately this case can be fixed easily
- The code needs to be improved in some ways, like adding more constants, use the booleexpr of TriggerRegisterPlayerEvent, be able to enable/disable the check, handle leavers, and so one.
It's one second (in)accurate and i don't recommend to try a lower value.
Now, i just want to know your feedbacks, and if they are good enough i will work on removing some cons, fixing known lame things.
PS : If you already pan your camera each 0.03 s or so, you would inline this method instead.
JASS:
library IsWc3Minimized initializer onInit needs SyncDatas
globals
private constant real PERIOD = 1.0 // it's the period which the system check for each player if war3 is minimized, don't use a value lower than 1.0 s
endglobals
globals // you should'nt edit them
private constant real MARGIN = 0.03
private constant real EPSILON = 0.1
endglobals
globals
private integer array TimeElapsed
private timer Tim
private real X
private real Y
private sound DummySound
private integer Index
private boolean CheckNeeded = true
private real Xmin
private real Xmax
private real Ymin
private real Ymax
private boolean SecondCheck = false
endglobals
function GetMinimizeTimeForPlayer takes player whichPlayer returns integer
return TimeElapsed[GetPlayerId(whichPlayer)]
endfunction
function IsMinimizeForPlayer takes player whichPlayer returns boolean
return TimeElapsed[GetPlayerId(whichPlayer)] != 0
endfunction
private function Update takes integer i returns nothing
local integer index = GetPlayerId(GetSyncedPlayer())
if GetBooleanForPlayer(SCOPE_PREFIX,GetSyncedPlayer()) then
set TimeElapsed[index] = TimeElapsed[index]+1
else
set TimeElapsed[index] = 0
endif
endfunction
private function Actions takes nothing returns nothing
local real r = TimerGetTimeout(Tim)
local real x
local real y
local boolean b = false
if r == MARGIN then
if SecondCheck then
if CheckNeeded then
set b = (GetCameraTargetPositionX() == X and GetCameraTargetPositionY() == Y)
call SetCameraPosition(X,Y)
endif
call TimerStart(Tim,PERIOD-2.*MARGIN,false,function Actions)
call SyncBoolean(b,SCOPE_PREFIX,Update,0)
return
elseif CheckNeeded and X == GetCameraTargetPositionX() and Y == GetCameraTargetPositionY() then // the camera doesn't move
if X >= Xmax then
set x = Xmax - EPSILON
elseif X <= Xmin then
set x = Xmin + EPSILON
else
set x = X + EPSILON
endif
if Y >= Ymax then
set y = Ymax - EPSILON
elseif Y <= Ymin then
set y = Ymin + EPSILON
else
set y = Y + EPSILON
endif
call SetCameraPosition(x,y)
endif
set SecondCheck = true
call TimerStart(Tim,MARGIN,false,function Actions)
return
elseif r == PERIOD-2.*MARGIN then // yeah i could just use an else here, it's just for the code sense
set SecondCheck = false
set CheckNeeded = true
call StartSound(DummySound)
if GetSoundIsPlaying(DummySound) then // war3 can't be minimized
set CheckNeeded = false
else
set X = GetCameraTargetPositionX()
set Y = GetCameraTargetPositionY()
endif
call TimerStart(Tim,MARGIN,false,function Actions)
endif
endfunction
private function onInit takes nothing returns nothing
local integer i = 0
set Tim = CreateTimer()
call TimerStart(Tim,PERIOD-2.*MARGIN,false,function Actions)
set DummySound = CreateSound("Sound\\Music\\mp3Music\\Credits.mp3", false, false, false, 0, 0, "")
call SetSoundVolume(DummySound,0)
set Xmax = GetCameraBoundMaxX()
set Xmin = GetCameraBoundMinX()
set Ymax = GetCameraBoundMaxY()
set Ymin = GetCameraBoundMinY()
endfunction
endlibrary
JASS:
library SyncDatas initializer onInit
globals
private gamecache GC = null // leave it to null, or use your own but i don't recommend it
// i only let this possibility because of the limit of 256 game caches
endglobals
private function interface FunctionInterface takes integer i returns nothing
globals
private force Players
private integer I
private string TempVariableName
private FunctionInterface TempFunc
private integer TempIndex
private player SyncedPlayer = null
endglobals
private function Crash takes nothing returns nothing // just a test function
call Crash.execute()
endfunction
function GetSyncedPlayer takes nothing returns player
return SyncedPlayer
endfunction
//! runtextmacro t_InitSyncDatas("boolean","Boolean","false")
//! runtextmacro t_InitSyncDatas("integer","Integer","0")
//! runtextmacro t_InitSyncDatas("real","Real","0.")
//! runtextmacro t_InitSyncDatas("string","String","null")
//! textmacro t_InitSyncDatas takes TYPE , TYPE_NAME , TYPE_NULL
globals
private $TYPE$ Temp$TYPE_NAME$ = $TYPE_NULL$
endglobals
private function DoThe$TYPE_NAME$Sync takes nothing returns nothing
local integer i = GetPlayerId(GetEnumPlayer())
local string variableName = TempVariableName
local string s = SCOPE_PREFIX + "$TYPE_NAME$"
local FunctionInterface f = TempFunc
local integer data = TempIndex
if GetLocalPlayer() == Player(i) then
call Store$TYPE_NAME$(GC,s,variableName+I2S(i),Temp$TYPE_NAME$)
endif
call TriggerSyncStart()
//if GetLocalPlayer() == Player(1) then // just to test the case when a player left during the sync
// call Crash()
//endif
if GetLocalPlayer() == Player(i) then
call SyncStored$TYPE_NAME$(GC, s, variableName+I2S(i))
endif
call TriggerSyncReady()
set SyncedPlayer = Player(i)
call f.evaluate(data)
set SyncedPlayer = null
endfunction
private function Callback$TYPE_NAME$ takes nothing returns nothing
call DoThe$TYPE_NAME$Sync.execute()
endfunction
function Get$TYPE_NAME$ForPlayer takes string variableName, player whichPlayer returns $TYPE$
return GetStored$TYPE_NAME$(GC,SCOPE_PREFIX + "$TYPE_NAME$",variableName+I2S(GetPlayerId(whichPlayer)))
endfunction
function Sync$TYPE_NAME$ takes $TYPE$ which$TYPE_NAME$, string variableName, FunctionInterface whichFunction, integer data returns nothing
set TempVariableName = variableName
set Temp$TYPE_NAME$ = which$TYPE_NAME$
set TempFunc = whichFunction
set TempIndex = data
call ForForce(Players,function Callback$TYPE_NAME$)
set TempVariableName = ""
set Temp$TYPE_NAME$ = $TYPE_NULL$
set TempFunc = 0
set TempIndex = 0
endfunction
//! endtextmacro
private function HandleLeavers takes nothing returns boolean
call ForceRemovePlayer(Players,GetTriggerPlayer())
return false
endfunction
private function onInit takes nothing returns nothing
local trigger trig = CreateTrigger()
local integer i = 0
set Players = CreateForce()
if GC == null then
set GC = InitGameCache(SCOPE_PREFIX)
endif
loop
exitwhen i == 12
if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i)) == MAP_CONTROL_USER then
call ForceAddPlayer(Players,Player(i))
call TriggerRegisterPlayerEvent(trig,Player(i),EVENT_PLAYER_LEAVE)
call TriggerAddCondition(trig,function HandleLeavers)
endif
set i = i+1
endloop
endfunction
endlibrary
And a short lame example :
JASS:
scope TestIsWc3Minimized initializer init
private function Handler takes nothing returns nothing
call BJDebugMsg(GetPlayerName(Player(0)) + " : " +I2S(GetMinimizeTimeForPlayer(Player(0))))
call BJDebugMsg(GetPlayerName(Player(1)) + " : " +I2S(GetMinimizeTimeForPlayer(Player(1))))
call BJDebugMsg(" ")
endfunction
private function init takes nothing returns nothing
local timer tim = CreateTimer()
call TimerStart(tim,1.,true,function Handler)
endfunction
endscope