| 04-02-2010, 02:12 PM | #1 |
I cannot figure out why everyone is desyncing. This function used to work till I added the variables camSet[] and playerCam to it. I have looked over it more than I think 20 times. I still cannot figure it out, and was wondering if maybe someone would take a look at it for me and figure out why their is a desync. It happens right at the beginning of the game, and this was one of the only things I changed. The function is ran by a timer every .03 seconds. It loops through all the players and if they are playing and not dead locks the camera to their unit. If they die it originally locks the camera to an ally. They can change the camera with the left and right arrow keys in another function, and doing so locks it to one of them. Globals: playing[] is if the player is playing isDead[] is if the unit is dead playerCam[] holds the player number currently the camera is locked too. (Arrow key functions change it, for last part of this function) camSet[] is if the player changed their target with left and right arrow keys. Any help would be extremely useful :). JASS:function timerCameras takes nothing returns nothing local integer i = 0 //! textmacro Camera takes PlayerNum call SetCameraTargetController(players[$PlayerNum$], 0, 0, false) call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 250.00, 0) call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 185.00, 0) call SetCameraField(CAMERA_FIELD_FIELD_OF_VIEW, 100.00, 0) call SetCameraField(CAMERA_FIELD_ROLL, 180.00, 0) call SetCameraField(CAMERA_FIELD_ZOFFSET, 120.00, 0) call SetCameraField(CAMERA_FIELD_ROTATION, GetUnitFacing(players[$PlayerNum$]) + 180, .18) call SetCameraField(CAMERA_FIELD_FARZ, 2500, 0) //! endtextmacro loop if playing[i] == true then //Check if playing if isDead[i] == false then //Keep camera on living target set playerCam[i] = i if GetLocalPlayer() == Player(i) then //! runtextmacro Camera("i") endif else //Swap camera to living person if camSet[i] == false then //Check if they move their own camera if i < 4 then //On Team 1 if isDead[0] == false then set playerCam[i] = 0 if GetLocalPlayer() == Player(i) then //! runtextmacro Camera("0") endif elseif isDead[1] == false then //Change dead player camera to Blue set playerCam[i] = 1 if GetLocalPlayer() == Player(i) then //! runtextmacro Camera("1") endif elseif isDead[2] == false then //Change dead player camera to Teal set playerCam[i] = 2 if GetLocalPlayer() == Player(i) then //! runtextmacro Camera("2") endif elseif isDead[3] == false then //Change dead player camera to Purple set playerCam[i] = 3 if GetLocalPlayer() == Player(i) then //! runtextmacro Camera("3") endif endif else //On Team 2 if isDead[4] == false then //Change dead player camera to Yellow set playerCam[i] = 4 if GetLocalPlayer() == Player(i) then //! runtextmacro Camera("4") endif elseif isDead[5] == false then //Change dead player camera to Orange set playerCam[i] = 5 if GetLocalPlayer() == Player(i) then //! runtextmacro Camera("5") endif elseif isDead[6] == false then //Change dead player camera to Green set playerCam[i] = 6 if GetLocalPlayer() == Player(i) then //! runtextmacro Camera("6") endif elseif isDead[7] == false then //Change dead player camera to Pink set playerCam[i] = 7 if GetLocalPlayer() == Player(i) then //! runtextmacro Camera("7") endif endif endif else //If they set their cam with arrow keys if(GetLocalPlayer() == Player(i)) then //Change camera for local player only //! runtextmacro Camera("playerCam[i]") endif endif endif endif set i = i + 1 exitwhen i > 7 endloop endfunction |
| 04-02-2010, 04:58 PM | #2 |
Are you sure it comes from directly this function, and not a consequence, for example in an other function you use camera target X/Y to create/destroy handles/open a new thread, what ever else which cause a desync. AFAIK you don't have any desync stuff in it. You could even do that : JASS:function timerCameras takes nothing returns nothing local integer i = GetPlayerId(GetLocalPlayer()) //! textmacro Camera takes PlayerNum call SetCameraTargetController(Player($PlayerNum$), 0, 0, false) call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 250.00, 0) call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 185.00, 0) call SetCameraField(CAMERA_FIELD_FIELD_OF_VIEW, 100.00, 0) call SetCameraField(CAMERA_FIELD_ROLL, 180.00, 0) call SetCameraField(CAMERA_FIELD_ZOFFSET, 120.00, 0) call SetCameraField(CAMERA_FIELD_ROTATION, GetUnitFacing(players[$PlayerNum$]) + 180, .18) call SetCameraField(CAMERA_FIELD_FARZ, 2500, 0) //! endtextmacro if playing[i] then //Check if playing if isDead[i] == false then //Keep camera on living target set playerCam[i] = i //! runtextmacro Camera("i") else //Swap camera to living person if camSet[i] == false then //Check if they move their own camera if i < 4 then //On Team 1 if isDead[0] == false then set playerCam[i] = 0 if i == 0 then //! runtextmacro Camera("0") endif elseif isDead[1] == false then //Change dead player camera to Blue set playerCam[i] = 1 if i == 1 then //! runtextmacro Camera("1") endif elseif isDead[2] == false then //Change dead player camera to Teal set playerCam[i] = 2 if i == 2 then //! runtextmacro Camera("2") endif elseif isDead[3] == false then //Change dead player camera to Purple set playerCam[i] = 3 if i == 3 then //! runtextmacro Camera("3") endif else //On Team 2 if isDead[4] == false then //Change dead player camera to Yellow set playerCam[i] = 4 if i == 4 then //! runtextmacro Camera("4") endif elseif isDead[5] == false then //Change dead player camera to Orange set playerCam[i] = 5 if i == 5 then //! runtextmacro Camera("5") endif elseif isDead[6] == false then //Change dead player camera to Green set playerCam[i] = 6 if i == 6 then //! runtextmacro Camera("6") endif elseif isDead[7] == false then //Change dead player camera to Pink set playerCam[i] = 7 if i == 7 then //! runtextmacro Camera("7") endif endif else //If they set their cam with arrow keys //Change camera for local player only //! runtextmacro Camera("playerCam[i]") endif endif endif endfunction if camSet[i] == false == if not camSet[i] and if camSet[i] == true == if camSet[i] On an other note i consider this if/elseif block as overkilled you could really make your code shorter with (very) negligible performance loss. |
| 04-03-2010, 03:28 AM | #3 |
Nah I just use it to set the cameras. The other functions set the variables though, if that helped answer your question. I don't use like GetCameraX or whatever :). I tested it again with 2 people instead of a full house and it didn't desync which was weird. I think I heard someone said there are bugs with macs and cameras, maybe that could be it? Not really sure, or maybe just the bot that hosted the game. |
| 04-04-2010, 12:14 AM | #4 | |
I don't think this function is causing it. Every time you use GetLocalPlayer() you are only using that text macro which only contains camera changes i.e., local functions. Camera changes alone can't cause desyncs. Even if they are taking desynced arguments. Actually everything this function contains is desync-safe. 'If's don't care if they get desynced conditions. Setting variables locally isn't an issue either as long as you're keeping them locally. Quote:
Check your other functions for GetLocalPlayer blocks and watch out for variable settings and function calls. Variable settings won't desync the game instantly but they will once they are used in a global function. Apart from that... what happens if a player changes his target using arrow keys to let's say Blue and then Blue dies? You'd end up in the 'else' section of if camSet[i] == false then which doesn't check if Player(playerCam[i]) is still alive so the camera will target a dead unit. oh and @Troll-Brain: You don't wanna take out those local blocks unless you want to screw up the camera totally for all players. Using local functions like those camera functions in global code will apply these settings to ALL players which would result in a total mess in this case. Some other points: You can take all those lines out of the textmacro. They run always anyway: JASS:call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 250.00, 0) call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 185.00, 0) call SetCameraField(CAMERA_FIELD_FIELD_OF_VIEW, 100.00, 0) call SetCameraField(CAMERA_FIELD_ROLL, 180.00, 0) call SetCameraField(CAMERA_FIELD_ZOFFSET, 120.00, 0) call SetCameraField(CAMERA_FIELD_FARZ, 2500, 0) Also you should maybe use a second loop for the camSet[i] == false case. Currently this looks so like a GUI code :). And yeah... might I recommend this system? Some really awesome guy made this a while ago and seeing you're doing some sort of 3rd person cam too you might find it useful. All you'd have to do would be set up that "death cam" using a "UNIT_DEATH" trigger. Edit: There I even gave it a quick try using OppiCam (not tested): JASS:function PlayerDeath takes nothing returns nothing local integer i = 0 local integer j = 0 local integer id = GetPlayerId(GetOwningPlayer(GetDyingUnit())) // finding first alive and allied player: loop exitwhen ((not IsDead[i]) and IsPlayerAlly(Player(i), Player(id))) or i > 8 // i = 8 will deactivate ThirdPersonCam set i = i+1 endloop // finding all players whose cam was targeted on dying player: loop exitwhen j > 7 if playerCam[j] == id then call EnableThirdPersonCam(Player(j), players[i], 0) set playerCam[j] = i endif set j = j+1 endloop // setting cam for dying player: call EnableThirdPersonCam(Player(id), players[i], 0) set playerCam[id] = i endfunction |
| 04-04-2010, 03:05 AM | #5 |
I found out that the code was actually safe like you guys said. It was the bot. I had a few games of full houses and they worked fine. To answer Opposum: When someone dies it changes the camera and the arrow keys switching between targets checks for death. No its not GUI code lol, just a big coincidence lol. Thank you for the help guys, even though I wasted your time :(. |
| 04-04-2010, 09:58 AM | #6 | |
Quote:
Well, i assumed that the other players are computers or empty slot but not real players, if my guess was wrong then you are right. EDIT : If i'm right, you also don't need some other arrays, just set the variables locally. |
