Jump to content
Sign in to follow this  
wiggum2

Markers, triggers and JIP

Recommended Posts

Hi !

I have a question about the JIP behaviour of markers and triggers.

1st Question:

I have a marker on the map (placed in editor) that is green.

Now if any group-member (player group) gets into a trigger area this marker will change to red.

Everything works fine but as soon as someone joins in progress all markers that are already red are now green again (for all players)...

The trigger that changes the markers is set to "Any group-member present" and changes the color vie setMarkerColor.

Is this because of the group now having a new member ?

2nd Question:

I use this script for the player markers and it works:

// [player] execVM "playerMarkers.sqf";

private ["_n","_m","_unit"];

_unit = _this select 0;

if (alive _unit && isplayer _unit) then {

   _n = format ["%1", name _unit];
   _m = createMarker [_n, getPos _unit];
   [_m, true] call CBA_fnc_setMarkerPersistent;
   _m setMarkerType "mil_triangle";
   _m setMarkerColor "ColorBlue";
   _m setMarkerSize [0.3,0.6];
   _m setMarkerDir getDir vehicle _unit;
   _m setMarkerText name _unit;

};

while {alive _unit} do {
   _m setMarkerPos getPos vehicle _unit;
   _m setMarkerDir getDir vehicle _unit;
   sleep 0.5;
};

if (not alive _unit) exitWith {
   deleteMarker _m;
};

But if someone joins in progress his marker will stay at his starting position (although correctly displayed with name) and not update, at least for other players.

Also, the guy who joined in progress dont sees the correct names nextto the markers (player-names), he just sees those random names given by the game (like Jonny Jones).

The script is started inside the init.sqf:

if (!isDedicated) then {
   [] spawn {
       waitUntil {!isNull player};
[player] execVM "playerMarkers.sqf";
   };
};

Can someone tellme how to make it working correct with and for JIP players ?

3rd Question:

Triggers seems to fire again for JIP players.

For example i have a trigger that fires if vehicle x is destroyed, now although vehicle x is already destroyed, the player that joins in progress will get the "mission completed" hint (not alive vehicle x trigger) again as soon as he is in the game...

Looks like for JIP players all triggers are checked again at the time he joins and those who return true will fire because triggers that need a groupmember of the playergroup present will not fire for JIP players.

Cant see how to fix this...

Thanks for your help !

Share this post


Link to post
Share on other sites

I finally found the page i was searching for the whole time...

http://community.bistudio.com/wiki/6thSense.eu:EG#Join_in_Progress

Now, to add something to my questions:

1st Question:

I have a marker on the map (placed in editor) that is green.

Now if any group-member (player group) gets into a trigger area this marker will change to red.

Everything works fine but as soon as someone joins in progress all markers that are already red are now green again (for all players)...

The trigger that changes the markers is set to "Any group-member present" and changes the color vie setMarkerColor.

Is this because of the group now having a new member ?

I think all i would need would be:

CBA_fnc_setMarkerPersistent to sync the marker color for JIP players

Use publicVariable inside the trigger that changes color se it can not be called again by JIP players

2nd Question:

I use this script for the player markers and it works:

// [player] execVM "playerMarkers.sqf";

private ["_n","_m","_unit"];

_unit = _this select 0;

if (alive _unit && isplayer _unit) then {

   _n = format ["%1", name _unit];
   _m = createMarker [_n, getPos _unit];
   [_m, true] call CBA_fnc_setMarkerPersistent;
   _m setMarkerType "mil_triangle";
   _m setMarkerColor "ColorBlue";
   _m setMarkerSize [0.3,0.6];
   _m setMarkerDir getDir vehicle _unit;
   _m setMarkerText name _unit;

};

while {alive _unit} do {
   _m setMarkerPos getPos vehicle _unit;
   _m setMarkerDir getDir vehicle _unit;
   sleep 0.5;
};

if (not alive _unit) exitWith {
   deleteMarker _m;
};

But if someone joins in progress his marker will stay at his starting position (although correctly displayed with name) and not update, at least for other players.

Also, the guy who joined in progress dont sees the correct names nextto the markers (player-names), he just sees those random names given by the game (like Jonny Jones).

The script is started inside the init.sqf:

if (!isDedicated) then {
   [] spawn {
       waitUntil {!isNull player};
   [player] execVM "playerMarkers.sqf";
   };
}; 

Can someone tellme how to make it working correct with and for JIP players ?

Here i dont know what to do, i already use CBA_fnc_setMarkerPersistent and getPos & setMarkerPos should be global and synced.

3rd Question:

Triggers seems to fire again for JIP players.

For example i have a trigger that fires if vehicle x is destroyed, now although vehicle x is already destroyed, the player that joins in progress will get the "mission completed" hint (not alive vehicle x trigger) again as soon as he is in the game...

Looks like for JIP players all triggers are checked again at the time he joins and those who return true will fire because triggers that need a groupmember of the playergroup present will not fire for JIP players.

Cant see how to fix this...

Ok, thats pretty clear now for me i think.

All i need is (again) a publicVariable for the trigger condition so it will only fire once and not again for JIP players.

I sure i still missed something, maybe a better way to do it so any help would be appreciated ! :)

EDIT:

Oh, another small question...

Inside my init.sqf i have this:

tsk1 = false;

Now for a JIP player it would be false again although its aready true (global variable) ?

So i need again publicVariable, now inside the trigger that updates the variable:

tsk1 = true;
publicvariable "tsk1";

But am i correct that inside the init.sqf i should not use publicvariable "tsk1" ?

Edited by Wiggum

Share this post


Link to post
Share on other sites

if this is of any use - http://forums.bistudio.com/showthread.php?t=123821 without using CBA.

i set onplayerconnected - ensuring the marker gets moved

perhaps you could use that for marker colour for when tsk complete - change colour of marker.

just a thought.

oh and dont use tsk1 publicvariable in init.sqf - as every time someone joins the server - the tsk will alway be whatever you set the public variable to be in the init.sqf - wiping whatever the current tsk state.

Edited by Mikie boy
init comment update

Share this post


Link to post
Share on other sites

I usually add

deleteVehicle thisTrigger;

in triggers whenever they have done their job. that should be updated for JiP's. correct me if I'm wrong.

the reason that markers do not move with players is because that while loop is never sent to players. setting a marker to be persistant with CBA will make it persistant - but only for color, name, state etc.

Share this post


Link to post
Share on other sites
EDIT:

Oh, another small question...

Inside my init.sqf i have this:

tsk1 = false;

Now for a JIP player it would be false again although its aready true (global variable) ?

So i need again publicVariable, now inside the trigger that updates the variable:

tsk1 = true;
publicvariable "tsk1";

But am i correct that inside the init.sqf i should not use publicvariable "tsk1" ?

You are correct in that you should not use publicVariable in your init file. However, any JIP player will get "tsk1 = true" via publicVariable before reading the init file; this means that tsk1 will be overwritten by the init and made false for them. To avoid this problem, add an if statement to your init line that sets the variable:

if (isNil "tsk1") then {tsk1 = false}

This will set the variable only if that variable hasn't already been set, so JIP players who get the update from publicVariable will not overwrite that update.

EDIT:

It's also worth noting that the entire problem outlined above can be circumvented by simply not using publicVariable at all. The JIP players will "see" the trigger as well, so as long as the conditions are still true, the on activation line of "tsk1 = true" will be run for them as well, and this will be run after the init so it won't cause any problems.

Edited by ST_Dux

Share this post


Link to post
Share on other sites

Thanks !

For the tasks i now use:

init.sqf:

if (isNil "tsk1") then {
tsk1 = false;
};

trigger to upadte task:

Condition:

(not alive car) && !(tsk1)

On Act:

tsk1 = true; publicvariable "tsk1";

JIP players get the correct state of the variable tsk1 and the trigger will not fire again because the !(tsk1) check inside the condition.

@ST_Dux

It's also worth noting that the entire problem outlined above can be circumvented by simply not using publicVariable at all. The JIP players will "see" the trigger as well, so as long as the conditions are still true, the on activation line of "tsk1 = true" will be run for them as well, and this will be run after the init so it won't cause any problems.

Im not sure if i understand you correct but the problem was that the trigger condition is checked for JIP players again and if you have a "not alive" in the condition that will return true and (in my case) the JIP player will see the task completed hint again...

Edited by Wiggum

Share this post


Link to post
Share on other sites

Ok, its still does not work.

1st Question:

I have a marker on the map (placed in editor) that is green.

Now if any group-member (player group) gets into a trigger area this marker will change to red.

Everything works fine but as soon as someone joins in progress all markers that are already red are now green again (for all players)...

The trigger that changes the markers is set to "Any group-member present" and changes the color vie setMarkerColor.

Is this because of the group now having a new member ?

I created a trigger with:

Condition:

true && isServer

On Act:

["marker1", true] call CBA_fnc_setMarkerPersistent;

But as soon as a player joins in progress (hosted server) the maker switches back from red to green... :eek:

EDIT:

Is it because i change the color of the marker later ingame with another trigger ?

Do i need to CBA_fnc_setMarkerPersistent after every change of the marker (color, size) ?

2nd Question:

I use this script for the player markers and it works:

// [player] execVM "playerMarkers.sqf";

private ["_n","_m","_unit"];

_unit = _this select 0;

if (alive _unit && isplayer _unit) then {

   _n = format ["%1", name _unit];
   _m = createMarker [_n, getPos _unit];
   [_m, true] call CBA_fnc_setMarkerPersistent;
   _m setMarkerType "mil_triangle";
   _m setMarkerColor "ColorBlue";
   _m setMarkerSize [0.3,0.6];
   _m setMarkerDir getDir vehicle _unit;
   _m setMarkerText name _unit;

};

while {alive _unit} do {
   _m setMarkerPos getPos vehicle _unit;
   _m setMarkerDir getDir vehicle _unit;
   sleep 0.5;
};

if (not alive _unit) exitWith {
   deleteMarker _m;
}; 

But if someone joins in progress his marker will stay at his starting position (although correctly displayed with name) and not update, at least for other players.

Also, the guy who joined in progress dont sees the correct names nextto the markers (player-names), he just sees those random names given by the game (like Jonny Jones).

The script is started inside the init.sqf:

if (!isDedicated) then {
   [] spawn {
       waitUntil {!isNull player};
   [player] execVM "playerMarkers.sqf";
   };
}; 

Can someone tellme how to make it working correct with and for JIP players ?

Still, iam not able to get this script working for JIP players correctly.

I know that there are other (similar) scripts out there that work but i really would like to know how to get this script JIP compatible.

Thanks for your help !

Edited by Wiggum

Share this post


Link to post
Share on other sites

You should send the markercolor changer to all machines incl the server,

then the marker color won't change upon JIP.

Edited by Sickboy

Share this post


Link to post
Share on other sites
You should send the markercolor changer to all machines incl the server.

Sorry, im not sure if i understand this correct.

Do you mean i should use this inside my trigger ?

[-2, {_this setMarkerColor "ColorRed"}, "marker1"] call CBA_fnc_globalExecute;

(i think this cant worke because of those strings)

The trigger that changes the markercolor looks like this:

Condition:

Any groupmember present

On Act:

"marker1" setMarkerColor "ColorRed"; hint "Marker changed";

Share this post


Link to post
Share on other sites

If you use setMarkerColor then the change should already be global, as opposed to setMarkerColorLocal.

Are you sure the marker is only created once, and not recreated on every client? E.g is the marker editor placed or created by script only executed on the server (isServer condition)? If not, then perhaps the problem lies there.

Also in case of setMarkerColor, the trigger might not be the best as the setMarkerColor command will broadcast, thus if the trigger is triggered on all machines, you basically cause a short broadcast storm :)

Also, you shouldn't use globalExecute beyond debugging purposes.

Instead you should register an event at init:

["change_marker_color", { _marker = _this select 0; _color = _this select 2; _marker setMarkerColorLocal _color}] call CBA_fnc_addEventHandler;

and raise the event;

["change_marker_color", ["marker1", "ColorRed"]] call CBA_fnc_globalEvent

As this only sends parameters over the network, as opposed to the whole code.

---------- Post added at 13:58 ---------- Previous post was at 13:42 ----------

For unit tracking markers you're also probably better off to use local markers, created and managed on every client machine.

E.g currently you are broadcasting the position and direction of the marker for each player every 0.5s.

But every machine already knows about the position and direction of the units, so instead of having each player broadcast his own marker every 0.5s, you can have a loop running on each client that checks playableUnits or allUnits and isPlayer checks etc.

Take a look at my ACE Tracking Markers system for examples; http://dev-heaven.net/projects/ace-mod2/repository/revisions/develop/show/Addons/sys_tracking

Group tracking is done by; http://dev-heaven.net/projects/ace-mod2/repository/revisions/develop/entry/Addons/sys_tracking/loop_markers.sqf

And there's unit tracking by Robalo, in FSM: http://dev-heaven.net/projects/ace-mod2/repository/revisions/develop/entry/Addons/sys_tracking/gpsmarkers.fsm

You can run the sqf's through a pre-processor, e.g Squint, to expand the macros.

Edited by Sickboy

Share this post


Link to post
Share on other sites

Look again at what Mikie boy says:

getMarkerColor and then setMarkerColor with an addPublicVariableEventHandler

http://community.bistudio.com/wiki/addPublicVariableEventHandler

init.sqf:

onplayerConnected {execVM "setJIPmarker1color.sqf"};

setJIPmarker1color.sqf

if (isServer) then
{
"publicMarker1Color" addPublicVariableEventHandler 
{
               _colour = getMarkerColor "marker1";
	"marker1" setMarkerColor _color;
};
};

Not tested this but it's worth a try.

Edited by PELHAM

Share this post


Link to post
Share on other sites

Ok, then inside my init.sqf:

["change_marker_color", { _marker = _this select 0; _color = _this select 2; _marker setMarkerColorLocal _color}] call CBA_fnc_addEventHandler;

Color changing trigger:

Condition:

(Any groupmember present)

this && isServer

On Act:

["change_marker_color", ["marker1", "ColorRed"]] call CBA_fnc_globalEvent

Im hope this is what you told me to do... :p

EDIT:

Looks like i have to register to dev-heaven.net to take a look at the scripts you posted.

Thanks Sickboy !

Share this post


Link to post
Share on other sites

The trigger is probably still problematic, at least, how do you check "Any groupmember present". Since the server has no "player" thus also no "groupmembers" of a player ;)

Looks like i have to register to dev-heaven.net to take a look at the scripts you posted.
Not having a DH account to at least access CIT is like blasphemy!

Share this post


Link to post
Share on other sites
The trigger is probably still problematic, at least, how do you check "Any groupmember present". Since the server has no "player" thus also no "groupmembers" of a player ;)!

I mean if you group your groupleader (its a MP coop mission with one player group) to the trigger you can choose "Any groupmember present" as activation for the trigger.

Do you want to confuse me ? :D

Not having a DH account to at least access CIT is like blasphemy!

Fixed !

Share this post


Link to post
Share on other sites

Ahhh, no, not on purpose at least :P

It's rather that I barely ever use triggers, especially editor placed :)

Share this post


Link to post
Share on other sites

About the unit tracking markers:

I took a look at the scripts and the FSM but i see ace functions everywhere and my mission is not for the ACE mod.

Also, i dont have a deeper understand on how ACE works.

But i understand what you mean with creating the marker local on every client.

SC_players = playableUnits;

private ["_n","_m"];

waitUntil {!isNil "SC_players"};

_markers=[];
{    
   _n = format ["%1", name _x];
   _m = createMarkerLocal [_n, getPos _x];
   [_m, true] call CBA_fnc_setMarkerPersistent;
   _m setMarkerTypeLocal "mil_triangle";
   _m setMarkerColorLocal "ColorBlue";
   _m setMarkerSizeLocal [0.3,0.6];
   _m setMarkerDirLocal getDir vehicle _x;
   _m setMarkerTextLocal name _x;
   _markers set [count _markers,_m];

} forEach SC_players;

while {true} do {
   {
       _m =_markers select (SC_players find _x);
       _m setMarkerPosLocal getPos vehicle _x;
       _m setMarkerDirLocal getDir vehicle _x;
   } forEach SC_players;
   sleep 0.5;
};

Called in init.sqf for every player and after respawn.

EDIT:

At least it works in SP...but still need to do MP and JIP testing

Edited by Wiggum

Share this post


Link to post
Share on other sites

jips won't be added until the script runs again

Share this post


Link to post
Share on other sites

The purpose was indeed giving you some examples, just ignore the ACE function calls :)

Re the jips;

Better to use something like:

_scPlayers = [];
while {true} do {
 _currentScPlayers = playableUnits;
 _deletedUnits = _scPlayers - _currentScPlayers;
 _newUnits = _currentScPlayers - _scPlayers;
 _scPlayers = _currentScPlayers;

 {
     // TODO: Do stuff with deleted units (aka, delete marker if exist, etc)
 } forEach _deletedUnits;

 {
     // TODO: Do stuff with new units (aka, create marker, etc) 
 } forEach _newUnits;

 {
     // TODO: update marker position, etc
 } forEach _scPlayers;

 sleep 0.5;
};

Also since you are now handling the markers locally, no need to use setMarkerPersistant.

Edited by Sickboy

Share this post


Link to post
Share on other sites

Thanks again guys, i ended up with this:

private ["_m","_n","_markers","_currentScPlayers","_deletedUnits","_newUnits","_scPlayers"];

_scPlayers = [];
_markers = [];
_m = nil;

while {true} do {
   _currentScPlayers = playableUnits;
   _scPlayers = _currentScPlayers;
   _deletedUnits = _scPlayers - _currentScPlayers;
   _newUnits = _currentScPlayers - _scPlayers;

   {
       if (!isNil "_m") then {
           deleteMarkerLocal _m;
       };
   } forEach _deletedUnits;

   {
       _n = format ["%1", name _x];
       _m = createMarkerLocal [_n, getPos _x];
       _m setMarkerTypeLocal "mil_triangle";
       _m setMarkerColorLocal "ColorBlue";
       _m setMarkerSizeLocal [0.3,0.6];
       _m setMarkerDirLocal getDir vehicle _x;
       _m setMarkerTextLocal name _x;
       _markers set [count _markers,_m];
   } forEach _newUnits;

   {
       _m =_markers select (_scPlayers find _x);
       _m setMarkerPosLocal getPos vehicle _x;
       _m setMarkerDirLocal getDir vehicle _x;
   } forEach _scPlayers;

   sleep 0.5;
};

...still need testing.

I will call it from the init.sqf with:

if (!isDedicated) then {
   [] spawn {
       waitUntil {!isNull player};
   execVM "playerMarkers.sqf";
   };
};

And inside my respawn script again with:

execVM "playerMarkers.sqf";

Share this post


Link to post
Share on other sites

while {true} will loop forever. you don't need to call it again from the respawn script.

put the isnull player inside the marker script and remove []spawn

Share this post


Link to post
Share on other sites

init.sqf:

onplayerConnected {execVM "setJIPmarker1color.sqf"};

You do not need OPC for JIP, specially not for moving some player markers.

JIP is nothing more than understanding locality in this game.

Xeno

Share this post


Link to post
Share on other sites

Like in my example, the line "_scPlayers = _currentScPlayers; " needs to move after "_newUnits = _currentScPlayers - _scPlayers;" or those lines do nothing.

Also the markers array index will run out of sync probably. Might be better to simply store the markername on the players;

_x setVariable ["sc_marker_name", _marker];

and

_marker = _x getVariable "sc_marker_name";

Share this post


Link to post
Share on other sites

@ Sickboy

You wrote:

["change_marker_color", { _marker = _this select 0; _color = _this select 2; _marker setMarkerColorLocal _color}] call CBA_fnc_addEventHandler;

But im pretty sure you have a typo here and this is the correct version of that line:

["change_marker_color", { _marker = _this select 0; _color = _this select 1; _marker setMarkerColorLocal _color}] call CBA_fnc_addEventHandler;

Correct my if im wrong. :)

Edited by Wiggum

Share this post


Link to post
Share on other sites

Ok, the markers still change color if a player joins in progress (only for the JIP player the color is not correct)... :headscratch:

init.sqf:

["change_marker_color", { _marker = _this select 0; _color = _this select 1; _marker setMarkerColorLocal _color}] call CBA_fnc_addEventHandler;

if (isNil "tsk1") then {
tsk1 = false;
};

Color changing trigger:

Condition:

(not alive z1) && !(tsk1) && isServer

On Act:

["change_marker_color", ["ziel1", "ColorGreen"]] call CBA_fnc_globalEvent; nul=execVM "task1.sqf"; tsk1 = true; publicvariable "tsk1";

need help... :(

EDIT:

Even if i delete the trigger the color for the JIP player still is not correct or switched back...argggh !

Color changing trigger:

Name of the trigger = trigger1

Condition:

(not alive z1)

On Act:

"ziel1" setMarkerColor "ColorGreen"; nul=execVM "task1.sqf"; tsk1 = true; publicvariable "tsk1"; deleteVehicle trigger1;

I (server) see the correct color but for a JIP player the color is still red !

And another color changing trigger that needs any member of the playergroup present will alos dont work as expected although i used deleteVehicle on it too !

The marker that is changed by this trigger will change back to yellow even it was already blue before the JIP (server and JIP player see the yellow color again although it was already blue before and the trigger got deleted !).

Can it be that hard to get it working ?

Changing markers and JIP = pure nightmare ?

Edited by Wiggum

Share this post


Link to post
Share on other sites

For the JIP player only right? JIP players don't know it has changed color so you need to store that event somewhere and set the color for any JIP player.

Basically, how can any JIP player's machine know the color of the marker is supposed to be different when it wasn't around when the change happened?

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×