1. The Aftermath has been revealed for the 19th Terraining Contest! Be sure to check out the Results and see what came out of it.
    Dismiss Notice
  2. Melee Mapping Contest #3 - Results are out! Congratulate the winners and check plenty of new 4v4 melee maps designed for this competition!
    Dismiss Notice
  3. The winners of our cinematic soundtrack competition have been decided! Step by the Music Contest #11 - Results to check the entries and congratulate the winners!
    Dismiss Notice

GetLocalPlayer

Discussion in 'Trigger (GUI) Editor Tutorials' started by Chaosy, Nov 17, 2012.

  1. Chaosy

    Chaosy

    Joined:
    Jun 9, 2011
    Messages:
    10,500
    Resources:
    17
    Maps:
    1
    Spells:
    10
    Tutorials:
    6
    Resources:
    17

    GetLocalPlayer - By Chaosy


    -feel free to post suggestions and correct me-






    Introduction


    I made this tutorial since I think way to few people know that this exist in GUI, so I want to show you how to use "GetLocalPlayer" in GUI.



    What is needed?


    Decent knowlege of GUI triggering
    Very basic jass knowledge
    A few moments of your time



    What is GetLocalPlayer?



    GetLocalPlayer is a method to create certain things/stuff in JASS, but I will show you how to use this method in the GUI.
    This method will allow you to create this thing/stuff [special effects, multiboards, floating text, etc] for the player of your choice only.
    For example, you can show a multiboard to player 1 only, while the other player wont see any multiboard at all!


    That sounds awesome how do I use this?


    As one example I will create a multiboard for player 1 only, you can use any event you want.
    I will show you 3 ways to do it, tho you should use the recommended one since you use less memory that way.


    NOTICE! We use a player variable named "GetLocalPlayer" or "Player" based on which way you want to use

    Recomended way GUI

    • init
      • Events
        • Map initialization
      • Conditions
      • Actions
        • Custom script: set udg_GetLocalPlayer = GetLocalPlayer()

    • Multiboard for one player
      • Events
        • Player - Player 1 (Red) skips a cinematic sequence
      • Conditions
      • Actions
        • Multiboard - Create a multiboard with 1 columns and 1 rows, titled hellu
        • Multiboard - Hide (Last created multiboard)
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • GetLocalPlayer Equal to Player 1 (Red)
          • Then - Actions
            • Multiboard - Show (Last created multiboard)
          • Else - Actions


    the trigger JASS

    • Multiboard for one player jass
      • Events
        • Player - Player 1 (Red) skips a cinematic sequence
      • Conditions
      • Actions
        • Multiboard - Create a multiboard with 1 columns and 1 rows, titled hellu
        • Multiboard - Hide (Last created multiboard)
        • Custom script: if GetLocalPlayer() == Player(0) then
        • Multiboard - Show (Last created multiboard)
        • Custom script: endif


    the trigger GUI

    • Multiboard for one player
      • Events
        • Player - Player 1 (Red) skips a cinematic sequence
      • Conditions
      • Actions
        • Multiboard - Create a multiboard with 1 columns and 1 rows, titled hellu
        • Multiboard - Hide (Last created multiboard)
        • Custom script: set udg_Player = GetLocalPlayer()
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • Player Equal to Player 1 (Red)
          • Then - Actions
            • Multiboard - Show (Last created multiboard)
          • Else - Actions


    Now I will go through the trigger

    First we create a multiboard just edit it as you want
    • Multiboard - Create a multiboard with 1 columns and 1 rows, titled hellu


    after that we instantly hide it so no player never saw that multiboard
    • Multiboard - Hide (Last created multiboard)


    Now the the hard part, now we use a custom script since the action does not exist within the GUI. It stores the player returned from the GetLocalPlayer() function inside your player variable.
    • Custom script: set udg_Player = GetLocalPlayer()


    And lastly we just select wich players we want it to be showed to, in this case it will ONLY be showed to player red (1) aint that awesome?
    NOTICE! The jass and the GUI version is just the same you can use any of them!
    NOTICE! In jass the player index is between in 0-11 insted of 1-12 in GUI
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • Player Equal to Player 1 (Red)
      • Then - Actions
        • Multiboard - Show (Last created multiboard)
      • Else - Actions


    • Custom script: if GetLocalPlayer() == Player(0) then
    • Multiboard - Show (Last created multiboard)
    • Custom script: endif





    Great, but can I do the same to other things?


    Yes you really can, lets take special effects.
    Recomended way GUI

    • init
      • Events
        • Map initialization
      • Conditions
      • Actions
        • Custom script: set udg_GetLocalPlayer = GetLocalPlayer()

    • special effect trollbrain way
      • Events
        • Player - Player 1 (Red) skips a cinematic sequence
      • Conditions
      • Actions
        • Set Effect = <Empty String>
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • GetLocalPlayer Equal to Player 1 (Red)
          • Then - Actions
            • Set Effect = Abilities\Spells\Other\TalkToMe\TalkToMe.mdl
          • Else - Actions
        • Special Effect - Create a special effect attached to the overhead of Peasant 0001 <gen> using Effect


    the special effect trigger JASS

    • Special effect for one player jass
      • Events
        • Player - Player 1 (Red) Presses the Right Arrow key
        • Player - Player 2 (Blue) Presses the Right Arrow key
      • Conditions
      • Actions
        • Set Effect = <Empty String>
        • Custom script: set udg_Player = GetLocalPlayer()
        • Custom script: if GetLocalPlayer() == Player(0) then
        • Set Effect = Abilities\Spells\Human\DispelMagic\DispelMagicTarget.mdl
        • Custom script: endif
        • Special Effect - Create a special effect attached to the overhead of Peasant 0001 <gen> using Effect


    the special effect trigger GUI

    • Special effect for one player
      • Events
        • Player - Player 1 (Red) skips a cinematic sequence
      • Conditions
      • Actions
        • Set Effect = <Empty String>
        • Custom script: set udg_Player = GetLocalPlayer()
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • Player Equal to Player 1 (Red)
          • Then - Actions
            • Set Effect = Abilities\Spells\Other\TalkToMe\TalkToMe.mdl
          • Else - Actions
        • Special Effect - Create a special effect attached to the overhead of Peasant 0001 <gen> using Effect



    As you see I use the same system, but I will explain the new actions for you anyway.

    Here I simply store a string variable into nothing, this means if the player aint the player I want it to be there wont be any effect. (you will see later)
    • Set Effect = <Empty String>


    Here We check if the player is player red (1) and then we set the string variable to the question mark effect path.
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • Player Equal to Player 1 (Red)
      • Then - Actions
        • Set Effect = Abilities\Spells\Other\TalkToMe\TalkToMe.mdl
      • Else - Actions


    And after that we create the effect simple as that.
    • Special Effect - Create a special effect attached to the overhead of Peasant 0001 <gen> using Effect


    Desyncronization


    Desyncronization only exist in multiplayer due you need both a host and a client to make this happen, it causes clients playing the map do disconnect from the game. Thats why you must keep this in mind, if possible do only use the GetLocalPlayer in conditions.
    So if it does desync do NOT use it, if it does not desync you can just enjoy the game.

    NOTICE! Handles that have their own stack will never desync!

    list

    1. Fade filters for 1 player only

    Question - this cause desyncronization?
    Answer - No, but you have to locally set the alpha (transparency) rather than putting the fade filter in the "if" block.
    Click this link for the technique.

    2. Quest for 1 player only?

    Question - this cause desyncronization?
    Answer - Yes but if u use Enable/Disable quest then No


    3. Special effects, visibile for 1 player only?

    Question - this cause desyncronization?
    Answer - No


    4. Special effects attachment to unit, visibile for 1 player only?

    Question - this cause desyncronization?
    Answer - No



    6. Unit visibility, color, visibile for 1 player only?

    Question - this cause desyncronization?
    Answer - Yes but Vertex color dont desync


    7. Fog of war and black mask, color, visibile for 1 player only?

    Question - this cause desyncronization?
    Answer - Yes


    8. Images, visibile for 1 player only?

    Question - this cause desyncronization?
    Answer - No


    9. Sound & music, for 1 player only?

    Question - this cause desyncronization?
    Answer - Mostly No


    10. Show Multiboard, for 1 player only?

    Question - this cause desyncronization?
    Answer - No



    11. Trackables, for 1-2 player only?

    Question - this cause desyncronization?
    Answer - No


    12. Pause the game, for 1 player only?

    Question - this cause desyncronization?
    Answer - Yes


    13. Create different unit for player?

    Question - this cause desyncronization?
    Answer - Yes
    Note - It might not desync if (1) it is a non hero unit and (2) the two units have only differences in art fields/physical display (such as model or icon) - by PurgeandFire111


    14. Weather effect off for 1 player?

    Question - this cause desyncronization?
    Answer - No?


    15. Desctructible visibility, for 1 player only?

    Question - this cause desyncronization?
    Answer - ?





    Credits


    shadowvzs - http://www.hiveworkshop.com/forums/world-editor-help-zone-98/getlocalplayer-faq-224876/
    Hashjie - Telling me info about GetLocalPlayer and the idea to this tutorial
    Troll-Brain - awesome tip to improve the tutorial
     
    Last edited: Sep 9, 2016
  2. Hashjie

    Hashjie

    Joined:
    Apr 20, 2009
    Messages:
    1,515
    Resources:
    0
    Resources:
    0
    Hmm, I think you should explain more about desynchronizations in detail.
    People don't really know what this is or what it does. Same counts for GetLocalPlayer().
    It's not really clear when you say:

    There is a bit more truth to this part:

    But I think it's better to explain that GetLocalPlayer() is a function in Jass which returns a local player (which can be used to save it inside a variable like you are doing or by putting it in a condition).
    This can then be used to create or display (depending on wether the handle has it's own counter) handles (objects) locally to a player. So that only 1 player can see it (local).
    This explenation needs to be adjusted a bit but it would be more correct so to say.

    Also, you might want to fix some of your grammar mistakes. I can see how some people might not be abled to understand what you are trying to say.

    This is wrong. It stores the player returned from the GetLocalPlayer() function inside your player variable.

    Furthermore, some things should probably be tested with other players before submitted.
    For example: GetLocalPlayer returns a player which is set inside the global variable, however I'm not sure if this could potentially cause problems since GetLocalPlayer returns a (local) player...
    If it does work you need to explain that setting GetLocalPlayer() to a global GUI variable does not mean that you can use that global variable inside GUI actions and that it should solely be used for conditions to check if a player equals the variable.

    It might also be nice to tell people how you can check for desynchronizations?
    For example commenting out/removing lines which might cause a desynch inside local blocks, displaying debug messages of handle ID's.

    Maybe give an example of what happens to the handle ID's of floating texts and explain why?
     
  3. Adiktuz

    Adiktuz

    Joined:
    Oct 16, 2008
    Messages:
    9,674
    Resources:
    23
    Models:
    2
    Packs:
    1
    Maps:
    1
    Spells:
    16
    Tutorials:
    1
    JASS:
    2
    Resources:
    23
    GetLocalPlayer is a function in JASS wich allows you to make multiboards,floating texts, special effects and more.

    --> I think you better say first what GetLocalPlayer actually does, and not go directly to the possibilities of its usage... because reading this, someone might think that GetLocalPlayer() does all those by default, when the fact is that they are only methods in which you can utilize what GetLocalPlayer() does...

    also,

    GetLocalPlayer makes "things" meant to be seen by every player, but with GetLocalPlayer you can make it be shown to one player only or maybe two players only.

    --> The first statement says that GetLocalPlayer makes things meant to be seen by every player, then the second one says that it makes it shown to only a few... Here you will see that your two statements contradict each other... The first is false, first and foremost because GetLocalPlayer() doesn't make things...

    it will better be off as:

    GetLocalPlayer() allows you to make things [effects,variable data, etc] be created for a specific player/s only when utilized...
     
  4. Chaosy

    Chaosy

    Joined:
    Jun 9, 2011
    Messages:
    10,500
    Resources:
    17
    Maps:
    1
    Spells:
    10
    Tutorials:
    6
    Resources:
    17
    @hashjie, I will try to add as much as I can, thanks for your comment

    @adiktuz, I know that you are right here, I will change it in a moment thank you for your comment
     
  5. Adiktuz

    Adiktuz

    Joined:
    Oct 16, 2008
    Messages:
    9,674
    Resources:
    23
    Models:
    2
    Packs:
    1
    Maps:
    1
    Spells:
    16
    Tutorials:
    1
    JASS:
    2
    Resources:
    23
    other than those, this will be helpful for those who needs the power of GLP but haven't come across it yet...
     
  6. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    @Hashjie : There is nothing wrong to give different values to a global (or local) variable, you can even do this.

    To make it even more "GUI", you just have to use a GUI player variable (variable editor) and set it on map initialization with a custom script.
    Here i name this variable " Local_player "

    set udg_Local_player = GetLocalPlayer()


    And then you can use and if/then in GUI, you don't need more custom scripts.

    But yeah of course, since its value will be different for each player's computer, you have to care on how you use it.
     
  7. Hashjie

    Hashjie

    Joined:
    Apr 20, 2009
    Messages:
    1,515
    Resources:
    0
    Resources:
    0
    Yeah, you're right Troll-Brain, I wasn't really thinking clearly.
    Setting it to a global variable will work just as good but people just need to be carefull using it correctly. I agree with you.

    Also, chaosy just tested it with me and there are indeed no problems in using global GUI variables.

    But I can imagine someone trying to create a floating text locally in GUI and then still getting desync's due to CreateTextTagLocBJ.
    A friend of mine tested this and told me it desync'd. (might have something to do with bj_lastCreatedTextTag?) I'll create a test later on to check if he was correct.
    If so text tags should be created locally through jass. Same thing counts for, for example SmartCameraPanBJ.
    I'm just trying to say that using GetLocalPlayer() in a "GUI way" doesn't nessecarely mean that it will work just as well as when using jass.

    Also, lots of BJ's already have a GetLocalPlayer() check so it's not needed for those.
     
    Last edited: Nov 18, 2012
  8. Chaosy

    Chaosy

    Joined:
    Jun 9, 2011
    Messages:
    10,500
    Resources:
    17
    Maps:
    1
    Spells:
    10
    Tutorials:
    6
    Resources:
    17
    Thanks for your idea troll-brain, I will post it in the tutorial as soon I get it working as I want it :)
     
    Last edited: Nov 18, 2012
  9. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    If/then in jass or GUI are the same, excepted that conditions of the if/then in GUI are done in other functions.
    Which makes annoying the use of a local variable in GUI, you have to use a temp global variable if you want to use a local variable in a GUI if/then condition.
    At least it's the case for the if/then multiple, i don't remember for the single one, but i should be the same.

    Now, many and many GUI actions uses and eventually creates handles, such as locations, so ofc if you create an handle in a local block, then you will got a desync (excepted few types such as texttags).
    Also some GUI functions leaks inherently, such as PolledWait.

    So no it's not the fault of the if/then in GUI.

    Finally i don't think that "lot of" GUI functions already use GetLocalPlayer(), but i could be wrong about this last one, it was several years ago that i used GUI ...
     
  10. Chaosy

    Chaosy

    Joined:
    Jun 9, 2011
    Messages:
    10,500
    Resources:
    17
    Maps:
    1
    Spells:
    10
    Tutorials:
    6
    Resources:
    17
    @Troll-Brain I hope you was not talking to me since I do not understand much :p
    anyway I added your tip to the tutorial and added you to credits
     
  11. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    No it was for Hashjie, even if you should understand what i said in order to use GetLocalPlayer() safely.
    But meh, i suppose a list of examples is enough for GUIers, such as how it's done in the "FAQ".
     
  12. Hashjie

    Hashjie

    Joined:
    Apr 20, 2009
    Messages:
    1,515
    Resources:
    0
    Resources:
    0
    Yes, this is indeed a disadvantage of using GUI.
    In fact I've seen this lots of times before, ugly spagetti code created through lots of if/then's in GUI. But I don't really see your point being on this subject?

    That's why I tryed to make a clear point to warn other users not to think that just by using a local block in GUI means they can make things work locally.
    It's also the GUI actions eg BJ's they will have to be careful with.
    Sometimes a BJ simply contains code that will not work in local blocks (code such as creating handles) when done in GUI but will work when using the non BJ version through jass.

    I didn't know about this, thanks! Do you perhaps have any refference on this subject?
    I would like to know how this was discovered. I'll search for it myself in the meanwhile, I suppose it's got somethng to do with the TSA's?

    I never said it was did I?

    I thought there where quite some BJ's which use local blocks but I'm not entirely sure about that. Plus the fact that "lot of" is not really a measurement. Perhaps I find 2 functions a lot already ;)
     
  13. TKF

    TKF

    Joined:
    Nov 29, 2006
    Messages:
    1,238
    Resources:
    5
    Maps:
    5
    Resources:
    5
    How about putting generic sounds in local to happen only to a few players? I know it doesn't cause instant desync, but I suspect it sometimes causes players to desync. I'm right? Or is it host bot related?

    Otherwise I use only multiboards and texts in local
     
  14. Chaosy

    Chaosy

    Joined:
    Jun 9, 2011
    Messages:
    10,500
    Resources:
    17
    Maps:
    1
    Spells:
    10
    Tutorials:
    6
    Resources:
    17
    @TKF, thats a good question I will test this later
     
  15. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    You mean create or play ?

    I don't know about create but play should be fine.
    Anyway it's already local, since a sound is not played if you have turned off the sound in the wc3 menu, and some other cases such as if wc3 is minimized or not.

    @Hashjie :

    Well, it's just because the way you said it, the desync was coz of the GUI if, that's why i made it clear it was not.
    The local thing was just a bonus, as i like to be accurate, but yeah that's off-topic.

    blizzard.j :xxd:

    No it's because it destroys a timer but not null the local variable -> handle id leak
    Well, i've seen it myself but anyway the leak might has been discovered just by browsing blizzard.j

    And leak or not using a TSA or a timer in a local code should desync by itself.
     
  16. Hashjie

    Hashjie

    Joined:
    Apr 20, 2009
    Messages:
    1,515
    Resources:
    0
    Resources:
    0
    Ah, how stupid of me xD I haven't really looked that much inside blizzard.j tbh I think I'll go through the entire thing some time.

    EDIT: Yet another fail of me, I totally forgot that blizzard.j is integrated in the function list of JNGP.


    @TKF:

    There is a BJ that does the following:

    Code (vJASS):
    function StartSoundForPlayerBJ takes player whichPlayer, sound soundHandle returns nothing
        if (whichPlayer == GetLocalPlayer()) then
            call StartSound(soundHandle)
        endif
    endfunction
     


    So yeah I guess that you can start a sound locally but need to create the handle globally.
    (Remember not to use a BJ if it's not nessecary, it's yet another function call for something that can be done directly instead.)
     
    Last edited: Nov 18, 2012
  17. TKF

    TKF

    Joined:
    Nov 29, 2006
    Messages:
    1,238
    Resources:
    5
    Maps:
    5
    Resources:
    5
    Trigger 1
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (Remaining time for WarningTimer[1]) Less than or equal to 0.00
      • Then - Actions
        • Set Temp_Group3 = (Units in Cruiser 2 Interior <gen>((Unit-type of (Matching unit)) Equal to Crew Member))
        • Unit Group - Pick every unit in Temp_Group3 and do (Actions)
          • Loop - Actions
            • Set localplayer = (Owner of (Picked unit))
            • Custom script: if udg_localplayer == GetLocalPlayer() then
            • Game - Display to (Player group(localplayer)) the text: localstring
            • Sound - Play alarm <gen>
            • Custom script: endif
        • Custom script: call DestroyGroup(udg_Temp_Group3)
        • Countdown Timer - Start WarningTimer[1] as a One-shot timer that will expire in 3.00 seconds
      • Else - Actions


    Does this work?


    Trigger 2
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (Remaining time for WarningTimer[0]) Less than or equal to 0.00
      • Then - Actions
        • Set Temp_Group2 = (Units in Cruiser 1 Interior <gen>((Unit-type of (Matching unit)) Equal to Crew Member))
        • Unit Group - Pick every unit in Temp_Group2 and do (Actions)
          • Loop - Actions
            • Set Temp_PlayerGroup = (Player group((Owner of (Picked unit))))
            • Game - Display to Temp_PlayerGroup the text: localstring
            • Custom script: call DestroyForce(udg_Temp_PlayerGroup)
            • Set localplayer = (Owner of (Picked unit))
            • Custom script: if udg_localplayer == GetLocalPlayer() then
            • Sound - Play alarm <gen>
            • Custom script: endif
        • Custom script: call DestroyGroup(udg_Temp_Group2)
        • Countdown Timer - Start WarningTimer[0] as a One-shot timer that will expire in 3.00 seconds
      • Else - Actions


    Or this a safer approach?

    Sorry, I'm only used to GUI. Will this way of setting up local message cause desync? I'm trying will fail and error in last 10 versions, however I cannot test it myself since it only happens with more than 1 player.

    But I would prefer alarm sound for that one team only, not the other.
     
  18. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    I don't know if it's safe to open a new thread in a local block, just as ForForce does. (the display text force thing)
    It probably leads to a desync.
     
  19. TKF

    TKF

    Joined:
    Nov 29, 2006
    Messages:
    1,238
    Resources:
    5
    Maps:
    5
    Resources:
    5
    I don't completely understand. I don't understand JASS language.

    Are you referring to Temp_PlayerGroup? Destroying it every pick causes desync?

    Or are you referring ForForce on something in trigger 1 or 2?
     
  20. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    I'm talking about that :

    Game - Display to Temp_PlayerGroup the text: localstring

    Since i suppose that it uses ForForce.