HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Problem with GetLocalPlayer

12-12-2007, 09:51 PM#1
PandaMine
First of all, this is not an issue with desyncs its something more perplexing (at least to me). The issue seems to be, that with certain function (posted later) that if you remove the loop, it works correctly on all computers in multiplayer however if you add the loop in (which is required) although it doesnt desync, it will only succesfully work on the host computer. In fact it will only work if there is just one player, even if the host leaves and there is just one player then it will work, but with more then one player it wont.

This is for my AMHS btw, the script is designed to crash the computer when they turn MH on. The loop is a searching mechanism (if the original point is not visible then it will try and find another), so without the loop it still works if the camera view is fully fogged

Here is a working version, it is without the loop however

Collapse JASS:
function AMHS_FOG_Model_Check takes nothing returns nothing
local integer counter = 1
local integer counter2 = 1
local boolean check = false
local real camerax
local real cameray
local real rotation
local real distance
local real aoa
local real eye
local real topbound
local real midbound
local real lowbound
local real highboundmodifier
local real verticalhighbound
local real verticallowbound
local real base
local real base2
local real angle
local real angle2
local real angle3
local real angle4
local real dist1
local real dist2
local real x
local real y
local real finalx = 999999
local real finaly = 999999
local real x1
local real y1
local real x2
local real y2
local real x3
local real y3
local real x4
local real y4
local real x5
local real y5
local real ax
local real ay
local real bx
local real by
local real cx
local real cy 
local integer tri
loop
    exitwhen counter > 12
    if GetPlayerSlotState(Player(counter -1)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(counter - 1)) == MAP_CONTROL_USER then
         if GetLocalPlayer() == Player(counter-1) then
            //Get and set all camera data
            set check = false
            set camerax = GetCameraTargetPositionX()
            set cameray = GetCameraTargetPositionY()
            set rotation =  GetCameraField(CAMERA_FIELD_ROTATION)
            set distance = GetCameraField(CAMERA_FIELD_TARGET_DISTANCE)
            set aoa = GetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK)
            set eye = GetCameraEyePositionZ()
            set topbound = 11/distance * 180000
            set midbound = distance/11 * 6
            set lowbound = distance/11 * 5
            set highboundmodifier = 957481
            set verticalhighbound = highboundmodifier * 1/eye
            set verticallowbound = 100 *aoa 
            set base = Atan2(verticalhighbound,topbound)
            set base2 = Atan2(verticallowbound,lowbound)
            set angle = base - bj_PI/2 + rotation
            set angle2 = base + bj_PI/2 - rotation
            set angle3 = base2 - bj_PI/2 + rotation
            set angle4 = base2 + bj_PI/2 - rotation
            set dist1 = SquareRoot((topbound*topbound) + (verticalhighbound*verticalhighbound))
            set dist2 = SquareRoot((verticallowbound*verticallowbound) + (lowbound * lowbound))
            //Point at top right
            set x1 = camerax+dist1 * Cos(angle)
            set y1 = cameray +dist1 * Sin(angle)
            //Point at top left
            set x2 = camerax+dist1 * Cos(bj_PI - angle2)
            set y2 = cameray +dist1 * Sin(bj_PI - angle2)
            //Point at bottom right
            set x3 = camerax+dist2 * Cos(-angle4)
            set y3 = cameray +dist2 * Sin(-angle2)
            //Point at bottom left
            set x4 = camerax+dist2 * Cos(bj_PI + angle3)
            set y4 = cameray +dist2 * Sin(bj_PI + angle)
            //Midpoint of p(1) to p(2)
            set x5 = (x1 + x2)/2
            set y5 = (y1 + y2)/2
        endif
        call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, I2S(counter))
        //loop 
            //exitwhen counter2 > udg_AMHS_FogModelBuffer 
            set ax = GetRandomReal(0,1)
            set ay = GetRandomReal(0,1)
            set bx = GetRandomReal(0,1)
            set by = GetRandomReal(0,1)
            set tri = GetRandomInt(1,3)
            if ax + bx > 1 then
                set ax = 1-ax
                set bx = 1-bx
            endif
            if ay + by > 1 then
                set ay = 1-ay
                set by = 1-by
            endif
            set cx = 1-ax-bx
            set cy = 1-ay-by
            if tri == 1 then
                if GetLocalPlayer() == Player(counter - 1) then
                    set x = ax * x2 + bx * x5 + cx * x4
                    set y = ay * y2 + by * y5 + cy * y4
                endif
            elseif tri == 2 then
                if GetLocalPlayer() == Player(counter - 1) then
                    set x = ax * x5 + bx * x4 + cx * x3
                    set y = ay * y5 + by * y4 + cy * y3
                endif
            elseif tri == 3 then
                if GetLocalPlayer() == Player(counter - 1) then
                    set x = ax * x5 + bx * x1 + cx * x3
                    set y = ay * y5 + by * y1 + cy * y3
                endif
            endif
            if GetLocalPlayer() == Player(counter - 1) then
                if IsVisibleToPlayer(x,y,Player(counter-1)) then
                    set check = false
                else
                    set check = true
                endif
            endif
            //set counter2 = counter2 + 1 
        //endloop 
            if check then
                call SetUnitX(udg_AMHS_FogDummy[counter-1],x)
                call SetUnitY(udg_AMHS_FogDummy[counter-1],y)
                call SetUnitAnimationByIndex(udg_AMHS_FogDummy[counter-1],0)
            else    
                call SetUnitAnimationByIndex(udg_AMHS_FogDummy[counter-1],1)
            endif
    endif
set counter = counter + 1
endloop
endfunction

This is a version with the loop, although it doesnt desync it simply doesn't work on other computers unless there is just a single player (where as the first one does)

Collapse JASS:
function AMHS_FogNoCrash takes integer counter returns nothing
call SetUnitAnimationByIndex(udg_AMHS_FogDummy[counter],1)
endfunction

function AMHS_FogCrash takes real x, real y, integer counter returns nothing
call SetUnitX(udg_AMHS_FogDummy[counter-1],x)
call SetUnitY(udg_AMHS_FogDummy[counter-1],y)
call SetUnitAnimationByIndex(udg_AMHS_FogDummy[counter],0)
endfunction

function AMHS_FOG_Model_Check takes nothing returns nothing
local integer counter = 1
local integer counter2 = 1
local boolean check = false
local real camerax
local real cameray
local real rotation
local real distance
local real aoa
local real eye
local real topbound
local real midbound
local real lowbound
local real highboundmodifier
local real verticalhighbound
local real verticallowbound
local real base
local real base2
local real angle
local real angle2
local real angle3
local real angle4
local real dist1
local real dist2
local real x
local real y
local real finalx = 999999
local real finaly = 999999
local real x1
local real y1
local real x2
local real y2
local real x3
local real y3
local real x4
local real y4
local real x5
local real y5
local real ax
local real ay
local real bx
local real by
local real cx
local real cy 
local integer tri
loop
    exitwhen counter > 12
    if GetPlayerSlotState(Player(counter -1)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(counter - 1)) == MAP_CONTROL_USER then
         if GetLocalPlayer() == Player(counter-1) then
            //Get and set all camera data
            set check = false
            set camerax = GetCameraTargetPositionX()
            set cameray = GetCameraTargetPositionY()
            set rotation =  GetCameraField(CAMERA_FIELD_ROTATION)
            set distance = GetCameraField(CAMERA_FIELD_TARGET_DISTANCE)
            set aoa = GetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK)
            set eye = GetCameraEyePositionZ()
            set topbound = 11/distance * 180000
            set midbound = distance/11 * 6
            set lowbound = distance/11 * 5
            set highboundmodifier = 957481
            set verticalhighbound = highboundmodifier * 1/eye
            set verticallowbound = 100 *aoa 
            set base = Atan2(verticalhighbound,topbound)
            set base2 = Atan2(verticallowbound,lowbound)
            set angle = base - bj_PI/2 + rotation
            set angle2 = base + bj_PI/2 - rotation
            set angle3 = base2 - bj_PI/2 + rotation
            set angle4 = base2 + bj_PI/2 - rotation
            set dist1 = SquareRoot((topbound*topbound) + (verticalhighbound*verticalhighbound))
            set dist2 = SquareRoot((verticallowbound*verticallowbound) + (lowbound * lowbound))
            //Point at top right
            set x1 = camerax+dist1 * Cos(angle)
            set y1 = cameray +dist1 * Sin(angle)
            //Point at top left
            set x2 = camerax+dist1 * Cos(bj_PI - angle2)
            set y2 = cameray +dist1 * Sin(bj_PI - angle2)
            //Point at bottom right
            set x3 = camerax+dist2 * Cos(-angle4)
            set y3 = cameray +dist2 * Sin(-angle2)
            //Point at bottom left
            set x4 = camerax+dist2 * Cos(bj_PI + angle3)
            set y4 = cameray +dist2 * Sin(bj_PI + angle)
            //Midpoint of p(1) to p(2)
            set x5 = (x1 + x2)/2
            set y5 = (y1 + y2)/2
        endif
        call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, I2S(counter))
        loop
            exitwhen counter2 > udg_AMHS_FogModelBuffer 
            set ax = GetRandomReal(0,1)
            set ay = GetRandomReal(0,1)
            set bx = GetRandomReal(0,1)
            set by = GetRandomReal(0,1)
            set tri = GetRandomInt(1,3)
            if ax + bx > 1 then
                set ax = 1-ax
                set bx = 1-bx
            endif
            if ay + by > 1 then
                set ay = 1-ay
                set by = 1-by
            endif
            set cx = 1-ax-bx
            set cy = 1-ay-by
            if tri == 1 then
                if GetLocalPlayer() == Player(counter - 1) then
                    set x = ax * x2 + bx * x5 + cx * x4
                    set y = ay * y2 + by * y5 + cy * y4
                endif
            elseif tri == 2 then
                if GetLocalPlayer() == Player(counter - 1) then
                    set x = ax * x5 + bx * x4 + cx * x3
                    set y = ay * y5 + by * y4 + cy * y3
                endif
            elseif tri == 3 then
                if GetLocalPlayer() == Player(counter - 1) then
                    set x = ax * x5 + bx * x1 + cx * x3
                    set y = ay * y5 + by * y1 + cy * y3
                endif
            endif
            if GetLocalPlayer() == Player(counter - 1) then
                if IsVisibleToPlayer(x,y,Player(counter-1)) then
                    set check = false
                else
                    set finalx = x
                    set finaly = y
                    set check = true
                endif
            endif
            set counter2 = counter2 + 1 
        endloop 
            if check then
                call AMHS_FogCrash(finalx,finaly,counter-1)
            else    
                call AMHS_FogNoCrash(counter-1)
            endif
    endif
set counter = counter + 1
endloop
endfunction

Is there any way to make it so that the loop works correctly for all players?
12-13-2007, 08:38 PM#2
Troll-Brain
instead of using always GetLocalPlayer() use a global player variable.
At the initialisation of the map
set udg_player = GetLocalPlayer()

We can execute functions for one player only ?!
12-13-2007, 08:45 PM#3
Vexorian
Should never, NEVER use GetRandomReal inside GetLocalPlayer blocks...
12-13-2007, 08:54 PM#4
cohadar
Quote:
Originally Posted by Vexorian
Should never, NEVER use GetRandomReal inside GetLocalPlayer blocks...

Told you...
12-13-2007, 10:11 PM#5
PandaMine
Quote:
Originally Posted by Vexorian
Should never, NEVER use GetRandomReal inside GetLocalPlayer blocks...

It isn't have a look closer

Here is the first getlocalplayer block that finishes
Collapse JASS:
if GetLocalPlayer() == Player(counter-1) then
            //Get and set all camera data
            set check = false
            set camerax = GetCameraTargetPositionX()
            set cameray = GetCameraTargetPositionY()
            set rotation =  GetCameraField(CAMERA_FIELD_ROTATION)
            set distance = GetCameraField(CAMERA_FIELD_TARGET_DISTANCE)
            set aoa = GetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK)
            set eye = GetCameraEyePositionZ()
            set topbound = 11/distance * 180000
            set midbound = distance/11 * 6
            set lowbound = distance/11 * 5
            set highboundmodifier = 957481
            set verticalhighbound = highboundmodifier * 1/eye
            set verticallowbound = 100 *aoa 
            set base = Atan2(verticalhighbound,topbound)
            set base2 = Atan2(verticallowbound,lowbound)
            set angle = base - bj_PI/2 + rotation
            set angle2 = base + bj_PI/2 - rotation
            set angle3 = base2 - bj_PI/2 + rotation
            set angle4 = base2 + bj_PI/2 - rotation
            set dist1 = SquareRoot((topbound*topbound) + (verticalhighbound*verticalhighbound))
            set dist2 = SquareRoot((verticallowbound*verticallowbound) + (lowbound * lowbound))
            //Point at top right
            set x1 = camerax+dist1 * Cos(angle)
            set y1 = cameray +dist1 * Sin(angle)
            //Point at top left
            set x2 = camerax+dist1 * Cos(bj_PI - angle2)
            set y2 = cameray +dist1 * Sin(bj_PI - angle2)
            //Point at bottom right
            set x3 = camerax+dist2 * Cos(-angle4)
            set y3 = cameray +dist2 * Sin(-angle2)
            //Point at bottom left
            set x4 = camerax+dist2 * Cos(bj_PI + angle3)
            set y4 = cameray +dist2 * Sin(bj_PI + angle)
            //Midpoint of p(1) to p(2)
            set x5 = (x1 + x2)/2
            set y5 = (y1 + y2)/2
        endif

and right after this is the getrandomreal which is not in getlocalplayer

Collapse JASS:
        loop
            exitwhen counter2 > udg_AMHS_FogModelBuffer 
            set ax = GetRandomReal(0,1)
            set ay = GetRandomReal(0,1)
            set bx = GetRandomReal(0,1)
            set by = GetRandomReal(0,1)
            set tri = GetRandomInt(1,3)
            if ax + bx > 1 then
                set ax = 1-ax
                set bx = 1-bx
            endif
            if ay + by > 1 then
                set ay = 1-ay
                set by = 1-by
            endif
            set cx = 1-ax-bx
            set cy = 1-ay-by

As you can clearly see it is not in te getlocalplayer block, can you please read the original thread. The problem is not with desyncs, in fact there is no problem and the script works 100% if you just remove the loop and dont change anything else

Like I said before, it is an issue with the loop and not with anything else. You remove the loop, it works fine, you put it in there, it doesn't work. If it was with getrandomreals it wouldnt workf fine even without the loop
12-13-2007, 11:46 PM#6
Toadcop
Quote:
if IsVisibleToPlayer(x,y,Player(counter-1)) then
looks dangerous ^^ cause i made some tests and it's desync somethimes than use a function which return bool inside of a local block. or something you will not belive it but i had desyncs cause i simple called GetLocalPlayer()


Collapse JASS:
loop
  exitwhen i>11
   if GetLocalPlayer()==Player(i) then
   // and nothing was here
   endif
  set i=i+1
endloop

and this code have desynced =) (but ofc this code after some other code)
there are maybe some internal features =)
and the silution was not to call GetLocaPlayer() every time insted init global var at map init with needed value ;) (i mean init it localy)
12-13-2007, 11:53 PM#7
PandaMine
I just tested it again, like thoroughly. It seems loops are evil when it comes to unsynchronised data. Without the loop it works absolutely fine, no problems or issues whatsoever. As soon as you add that loop in, then the all the unsynchronised reals end up as being nulled on the other computers, and when you do something like call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, R2S(camerax) + " : " + R2S(cameray)) to figure out the values, you get a desync, it only happens when the loop is around.

Seems to be a blizzard issue
12-14-2007, 01:29 AM#8
cohadar
How about you use ForForce() ?