• 🏆 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!

[JASS] GetLocalPlayer() and Triggers

Status
Not open for further replies.
Level 11
Joined
Sep 30, 2009
Messages
697
So is there any way to register/add an action or condition for only one player without desyncs?

I am thinking of creating a system with a huge amount of trackables and it would be kind of bad if i had to have 12 times more trackables. So it would be great if there was a way to have 12 triggers instead.

Anyone any ideas?
 
You can't do it without it desyncing.

The best way to save handles is to do this:
JASS:
if GetPlayerSlotState(Player(i))==PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i))==MAP_CONTROL_USER then
    //... actions
endif

It will ensure that only the players playing will have trackables created for and whatnot. So with 1 player, it would make 1 trackable and register events for it (3 total), and for 12 players it would make 12 trackables and register events for it (36 total), which is not that bad. Many times, you won't have a full-slot game anyway.
 
Level 11
Joined
Sep 30, 2009
Messages
697
you could sync manually (imho nestharus found a way to do it) but that would cause delay
using (spell/movement) orders instead of trackables might be an option, too
and you could also create the trackables dynamically

did you check if it even matters?
there would be no need if it has no impact on performance

The problem would not be the performance, more the 8190 instances limit for structs. Can you give me a link to the post where Nestharus did manually sync? And how bad would the delay be?


You can't do it without it desyncing.

The best way to save handles is to do this:
JASS:
if GetPlayerSlotState(Player(i))==PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i))==MAP_CONTROL_USER then
    //... actions
endif

It will ensure that only the players playing will have trackables created for and whatnot. So with 1 player, it would make 1 trackable and register events for it (3 total), and for 12 players it would make 12 trackables and register events for it (36 total), which is not that bad. Many times, you won't have a full-slot game anyway.

Well thanks for the suggestion but I am already doing this anyway ;)

So I think Enabling/Disabling Triggers would desync too? *throws a rock at blizzard*
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,191
You could just upgrade to SC2 where all this stuff is supported nativly.

Anyway, the problem is everyone needs a separate isntance of a trackable as GetTriggerPlayer() does not return the hitting player. You can however reduce the scope.

If the actions are universal (affect everyone) then you can use 1 for all players.
If the actions affect a group of players, then you need 1 for each group.
Only if the actions are unique to each player must you use 1 per player.

Remember to hide the wrong trackables (other player's) by creating them with an empty string for everyone but the correct player.

If you want to run stuff locally, write your own game. WC3 is a RTS game and next to the MAC to Windows sync issues its syncs very well for its purpose.
 
Level 19
Joined
Feb 4, 2009
Messages
1,313
Last edited:
Level 11
Joined
Sep 30, 2009
Messages
697
You could just upgrade to SC2 where all this stuff is supported nativly.

trying to get more people to SCII? :p

Anyway, the problem is everyone needs a separate isntance of a trackable as GetTriggerPlayer() does not return the hitting player.

Well thats why I wanted to know if theres a way with using GetTriggeringTrigger()

If the actions are universal (affect everyone) then you can use 1 for all players.
If the actions affect a group of players, then you need 1 for each group.
Only if the actions are unique to each player must you use 1 per player.

Remember to hide the wrong trackables (other player's) by creating them with an empty string for everyone but the correct player.


I think that I don't asked for this anyway I know how to do that.

@ D4RK_G4ND4LF: I think you mixed your answers up a bit :S
 
Why would you get over 8190 instances? That's like 8190*players trackables.

Even if it is a problem, then just use:
JASS:
struct A[MAX_STRUCT_SIZE] //replace with the max
endstruct

It results in a mess of code, but it is an option. Otherwise, use hashtables as that would probably end up being faster if the array size gets too high.

EDIT: I think you can safely enable/disable triggers locally, but everything that is executed by that trigger must be sync-friendly. Regardless, I don't know how much it would help. ;(
 
Last edited:
Level 26
Joined
Aug 18, 2009
Messages
4,097
EDIT: I think you can safely enable/disable triggers locally, but everything that is executed by that trigger must be sync-friendly. Regardless, I don't know how much it would help. ;(

You mean async-friendly but nope, you might know from the DestroyTrigger-bug that some new id is fetched for another instance of a trigger. Starting locally by ExecuteFunc does not seem good either as it wants to have the threads synced, I think.

However,

JASS:
if (GetLocalPlayer() == Player(0)) then
    call ExecuteFunc("a")
else
    call ExecuteFunc("b")
endif

or

JASS:
if (GetLocalPlayer() == Player(0)) then
    call TriggerExecute(a)
else
    call TriggerExecute(b)
endif

worked in my little tests, when the threads are not prolonged by TriggerSleepAction. By the second method you could use GetTriggeringTrigger(). I would also dehort from trying to destroy/modifying the trigger then.

edit: ExecuteFunc halts my game when the host leaves.
 
Status
Not open for further replies.
Top