• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

GetLocalPlayer Question/About conditions

Status
Not open for further replies.
Level 13
Joined
Mar 24, 2013
Messages
1,105
So I just have 2 questions:

Is this Safe? And will it work?

  • Actions
    • Set TempForce = (All allies of (Owner of (Triggering unit)))
    • Custom script: if IsPlayerInForce(GetLocalPlayer(), udg_TempForce) then
    • Special Effect - Create a special effect attached to the chest of (Target unit of ability being cast) using Abilities\Spells\Other\HowlOfTerror\HowlTarget.mdl
    • Set Charge_SPX[Charge_MaxIndex] = (Last created special effect)
    • Custom script: endif
    • Custom script: call DestroyForce(udg_TempForce)
Do any conditions..."leak"
I'm just curious because I'm planning on using this condition

  • (Current order of (Random unit from (Units in Region[TempInteger]))) Not equal to (!=) (Order(<Empty String>))
And I'm just wondering, to check to see if a unit in this region has a current order of anything, it has to make a unit group then check if one of the units has order x. However since I'm not making this and removing this group, is it leaking ?

JASS:
    if ( not ( GetUnitCurrentOrder(GroupPickRandomUnit(GetUnitsInRectAll(udg_Region[udg_TempInteger]))) != String2OrderIdBJ("") ) ) then
        return false
    endif
    return true

I'm no JASS wiz, but I only see 1 BJ and its on a conversion, and since every where I look BJ's are so bad, the lack of there existence relatively relives me. But any response to this would be helpful!
 
(1) It is not safe. When you locally create a handle, wc3 will respond by kicking players. I believe the best way to understand the sync-issues behind GetLocalPlayer() is to read this quote by Strilanc:
Strilanc said:
Unlike almost all the other functions, GetLocalPlayer returns a different value for each player. On player 1's computer the function returns player 1, etc. That means you can do things like:
JASS:
if GetLocalPlayer() == Player(0) then //0 is the first player, player 1
    call CreateUnit(Player(0), 'hfoo', 0, 0, 0) //create a footman at the center
endif

which will create a footman for player 1, but only if you're player 1!

Suppose the game allowed that. Player 1 orders the new footman to attack. All the other players' computers go "huh? order what footman to attack? there is no footman!". So they ignore the command to the non-existent footman and whatever the footman was attacking only dies for player 1. This effect (called desyncing) gets progressively worse as the effects of the footman spread. Eventually player 1 is looking at a game totally different from player 2, and nothing either of them does makes sense to the other.

To avoid that whole song and dance, desynced players are just instantly removed from the game.

Here is a tutorial on how to safely use it:
http://www.thehelper.net/threads/jass-getlocalplayer.77369/

I updated it recently, and eh it is okay (main issue is that the indenting keeps getting screwed up). I could've included more examples.

However, there is an example of how to create a special effect locally. In your case, this is how you would do it:
  • Set TempForce = (All allies of (Owner of (Triggering unit)))
    • Set TempPath = Abilities\Spells\Other\HowlOfTerror\HowlTarget.mdl
    • Custom script: if not IsPlayerInForce(GetLocalPlayer(), udg_TempForce) then
    • Set TempPath = ""
    • Custom script: endif
    • Special Effect - Create a special effect attached to the chest of (Target unit of ability being cast) using TempPath
    • Set Charge_SPX[Charge_MaxIndex] = (Last created special effect)
    • Custom script: call DestroyForce(udg_TempForce)
It is slightly unorthodox. But first you set the path to the actual effect model. If the player is not in the force, then you will set it to a null string "". This way, the only change is a visual-change. For all people outside the force, they won't see anything (the effect will be using a nonexistent model). For all players inside the force, they will see the regular effect.

(2) Yes, that leaks. You must assign this to a group:
  • (Units in Region[TempInteger])
It creates a group each time.

You just have to look for anything that might creating something new in memory--like a group, special effect, unit, etc. When converting it to JASS, you might not be able to just look for BJ functions (also, BJ functions are just any functions defined in the blizzard.j, and they'll appear as red in TESH or hive's JASS tags). Natives can leak, too. You just have to be careful about it. :)

And don't worry too much. Just post your code occasionally to have people review it, and gradually you'll learn how to deal with leaks. Read up on some tutorials if you have trouble.

---

If you need any more explanations, feel free to ask. These questions that you have are really good--I feel that a lot of people are shaky on them, so clarification is always a good thing.
 
Level 13
Joined
Mar 24, 2013
Messages
1,105
Thanks, I really appreciate you taking the time to type out such a detailed answer.

And now I know what the abbreviation BJ actually stands for. I truly thought the people were just trying to be hilarious. :grin:
 
Status
Not open for further replies.
Top