Jump to content
Sign in to follow this  
drivetheory

getting [addAction, PublicVariable, Say3D, hintSilent] to work together MP

Recommended Posts

The end result I am trying to accomplish player activates an addAction attached to an in-game flagpole object ("el_flagpole"), which calls an SQF that executes a say3D ("WarningSiren") sound ("\sounds\danger.ogg") from an in-game object ("el_speaker") as well as sending a hintSilent to all players within a 50m radius of the activation object.

the problem i'm having is making the say3D sound and hintSilent occur on all MP clients, as well as making the global variable work (which it's not when i mp host it?...)

I've tried and tested a couple ideas to make things propagate to all clients but they aren't working so i've come here seeking help. coding is definitely something i'm not very good at and confuses me greatly at times...

below is what i have so far that seems to be working correctly, but only for the client that executed the action added to the object.

init.sqf

if (isNil "AirRaid") then {
AirRaid = false;
if (isServer) then {
publicVariable "AirRaid";
};
};

description.ext

class CfgSounds {
sounds[] = {
	WarningSiren
};
class WarningSiren
{
	name="Warning_Siren";
	sound[] = {"\sounds\danger.ogg",db-10,1};
	titles[] = {};
};
};

"el_flagpole" init field:

this addAction ["Warn The Locals!", "air_raid_warning.sqf"];

"air_raid_warning.sqf"

if !(AirRaid) then {
AirRaid = true;
el_speaker say3D "WarningSiren";
hintSilent "Incoming Aircraft!";
sleep 5;
hintSilent "Hurry! Take Cover!";
sleep 5;
hintSilent "They're Almost Here!";
sleep 5;
hintSilent "";
sleep 1;
AirRaid = false;
}
else {
hintSilent "The Alarm Has Already Been Sounded";
sleep 3;
hintSilent "";
};

Edited by drivetheory
removed spoiler tags

Share this post


Link to post
Share on other sites

Here's my take:

if (isNil "AirRaid") then {
AirRaid = false;
};
airRaidWarn = {
el_speaker say3D "WarningSiren";
hintSilent "Incoming Aircraft!";
sleep 5;
hintSilent "Hurry! Take Cover!";
sleep 5;
hintSilent "They're Almost Here!";
sleep 5;
hintSilent "";
sleep 1;
AirRaid = false;
if (isServer) then {publicVariable "AirRaid";};
};

Your flagpole:

this addAction ["Warn The Locals!", "warning_brodcast.sqf"];

warning_broadcast:

if !(AirRaid) then {
AirRaid = true;
publicVariable AirRaid;
}
else {
hintSilent "The Alarm Has Already Been Sounded";
sleep 3;
hintSilent "";
};

Then a trigger, condition:

AirRaid

On Act.

spawn airRaidWarn;

Share this post


Link to post
Share on other sites

i had thought about using the addAction to toggle the pubvar and making the pubvar value the condition for the trigger (saw this method used before)- but don't triggers check the condition state once every cycle?... and if there's 1 flag pole in every city and 30 cities that's 30 triggers checking pubvar status every cycle? least this was the reasoning that had me continuing in the manual fire script method... thanks for pointing out the re-declaration of the pubvar with the "if (isServer) then {publicVariable "AirRaid";};" line, that part of the client+server what gets executed/updated where still confuses me since i can't get it crystal clear in my mind what does/is-supposed-to happen where.... will re-script, test, and post back

edit: any ideas on how to limit the hint to people only within 50m of flagpole?

Edited by drivetheory
more typos & quick update

Share this post


Link to post
Share on other sites

Create publicVariable EH in the mission init.

"NAME_WHAT_YOU_WANT" addPublicVariableEventHandler {(_this select 1) execVM "YourScript.sqf"};

In the addaction sqf add:

_Falgpole = _this select 0;

_unit = _this select 1;

if (local _unit) then{

[a,b,c,...] execVM "YourScript.sqf"};//Execute sqf if _unit is local which it will be in an addaction

}else{

NAME_WHAT_YOU_WANT =[a,b,c,...];

publicVariable "NAME_WHAT_YOU_WANT";;//If not local then execute via Public variable EH

};

Share this post


Link to post
Share on other sites

addPublicVariableEventHandler .... i was actually reading the wiki for this and wondering about using it before i originally posted. hmmmm.

any ideas on the geographically/marker/area limited hintSilent?

Edited by drivetheory
typos

Share this post


Link to post
Share on other sites

Actually that line

if (isServer) then {publicVariable "AirRaid";}

I just can't figure out why I put it there. There must have been some sort of twisted thinking behind it, but hell. There's no need for it as the script is executed on every machine anyway.

The PVEH is definitely the way to go here. The trigger solution I showed will get you in trouble.

Regarding the distance stuff, just ad an

if (player distance _flagpole < 50) then {hintSilent "Incoming Aircraft!";};
sleep 5;
if (player distance _flagpole < 50) then {hintSilent "They're Almost Here!";};
sleep 5;
...

You can make the economy of the if checks and just use one, but that means if you enter the zone after the first hint you won't get any. That's arguable.

Share this post


Link to post
Share on other sites

i think you put it there to update the pubvar after the local client changed it?

am reworking the method to use the addPublicVariableEventHandler now, it's always slow going- scripting is antithetical to what i can quickly wrap my head around so it always requires an immense amount of focus and concentration.

Share this post


Link to post
Share on other sites

so, after many hours of work and lots of trial & error and wiki page reading (instead of sleep, god im going to be worthless @ work today) this is the final working result:

init.sqf

if (isNil "AirRaid") then {
AirRaid = false;
if (isServer) then {
publicVariable "AirRaid";
};
};

"AirRaid" addPublicVariableEventHandler {
(_this select 0) execVM "air_raid_pt2.sqf";
};

description.ext

class CfgSounds {
sounds[] = {
	WarningSiren
};
class WarningSiren
{
	name="Warning_Siren";
	sound[] = {"\sounds\danger.ogg",db-10,1};
	titles[] = {};
};
};

"el_flagpole" init field:

this addAction ["Begin Air Raid Warning","air_raid_pt1.sqf",["AirRaid"]];

air_raid_pt1.sqf

private ["_params","_PubVar"];

_params = _this select 3;
_PubVar = _params select 0;

if !(AirRaid) then {
call compile format ["%1 = true;",_PubVar];
publicVariable _PubVar;
sleep 1;
el_speaker say3D "WarningSiren";
hintSilent "Incoming Aircraft!";
sleep 5;
hintSilent "Hurry! Take Cover!";
sleep 5;
hintSilent "They're Almost Here!";
sleep 5;
hintSilent "";
call compile format ["%1 = false;",_PubVar];
publicVariable _PubVar;
}
else {
hintSilent "The Alarm Has Already Been Sounded";
sleep 3;
hintSilent "";
};

air_raid_pt2.sqf

if (AirRaid) then {
el_speaker say3D "WarningSiren";
if (player distance el_flagpole < 50) then {hintSilent "Incoming Aircraft!";};
sleep 5;
if (player distance el_flagpole < 50) then {hintSilent "Hurry! Take Cover!";};
sleep 5;
if (player distance el_flagpole < 50) then {hintSilent "They're Almost Here!";};
sleep 5;
if (player distance el_flagpole < 50) then {hintSilent "";};
};

I'm still not 100% certain why:

1) the public variable name has to be passed via command line in the init field of the flagpole

2) "call compile format ["%1 = false;",_PubVar];" has to be used instead of just "AirRaid = false;"

if anyone could explain these 2 things is in a way that someone as incompetent as myself could understand it i would be very appreciative of such generosity.

i tried using "AirRaid = false;" many times but it would only change the public variable locally and never propagate to the server or other clients and when combining "AirRaid = false;" with "PublicVaraiable AirRaid" in pt1 the script seemed to just hang (debugged it with the oh-so-clever use of a million hintsilent lines)

and as i sit here typing this out im wondering why addPublicVariableEventHandler ran when AirRaid was changed to true at the begging of pt1.sqf but did not again when AirRaid was changed back to the original value at the end of the very same script... or is it only run when it's changed from the state originally listed in init.sqf?.....

_Me = "rather confused";

thanks again

Share this post


Link to post
Share on other sites

1) It does not.

You're passing a string.

Note:

"AirRaid"

AirRaid

Big difference.

Don't let the the publicVariable quotes confuse you. It's only used for the PV/PVEH commands.

2) See above :). You don't need to actually pass the variable in an addAction, a global variable is global and can be accessed from anywhere.

Share this post


Link to post
Share on other sites

@cuel I didn't really understand what you are saying...

the problem i ran into is that, if you look at the code i posted, it does NOT work if i don't do it that way. It kept changing the PublicVariable locally and not globally...

EDIT:

I see now...

AirRaid = true;
PublicVariable "AirRaid";

Edited by drivetheory
redacted ignorance

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  

×