Jump to content
Sign in to follow this  
Geosword

The 'Say' Command In Multiplayer

Recommended Posts

Hello everyone. I am putting the final touches on a Multiplayer mission. There is a Russian Colonel you can locate and talk to during the mission. The problem I have is getting the Unit Say "Whatever" to function across all machines.

First... The colonel has the following code in his INIT field

POWS=[Hostage1]; removeAllWeapons Hostage1; Hostage1 setCaptive true; Hostage1 disableAI "MOVE"; Hostage1 disableAI "ANIM"; this addAction ["Interrogate","mission\officertalk.sqf",[POWS],1,false,true,"","(_target distance _this) < 3"];

Basically.. you get within 3 meters of him, interrogate shows up on the player's action menu. Now for the officertalk.sqf code.

if (TalkFired == 1) exitWith {};

waitUntil {(isDedicated) || !(isNull player)};

_per = _this select 0;  // Person who had the addAction
_ldr = _this select 1;  // Person who used the addAction
_act = _this select 2;  // ID of the addAction

// Group given in the arguments section (ie: [POWS]
_grp = _this select 3 select 0;


// Remove the rescue option
_per removeAction _act;

Hostage1 say ["Russian1", 100];
sleep 7;
_ldr say ["US1", 100];
sleep 3;
Hostage1 say ["Russian2", 100];
sleep 6;
_ldr say ["US2", 100];
sleep 10;
Hostage1 say ["Russian3", 100];
sleep 13;
_ldr say ["US3", 100];
sleep 5;

Hostage1 say ["Russian4", 100];
sleep 15;
_ldr say ["US4", 100];
sleep 2;
Hostage1 say ["Russian5", 100];
sleep 16;
_ldr say ["US5", 100];
sleep 3;
Hostage1 say ["Russian6", 100];
sleep 17;
_ldr say ["US6", 100];
sleep 11;

[West,"HQ"] sideRadio "Radio1";
sleep 11;
_ldr say ["US7", 100];
sleep 5;
Hostage1 say ["Russian7", 100];
sleep 9;
_ldr say ["US8", 100];

// Join preselected units (POWS) to callers group, silently.
{[_x] joinSilent _ldr} forEach _grp;
Hostage1 enableAI "MOVE";
Hostage1 enableAI "ANIM";

	{Hostage1 addmagazine "30Rnd_762x39_AK47"} foreach [1,2,3,4,5,6,7,8];
	{Hostage1 addmagazine "HandGrenade_East"} foreach [1,2];
	{Hostage1 addmagazine "SmokeShell"} foreach [1,2];
	Hostage1 addweapon "ACE_AKM";

	Hostage1 selectweapon primaryweapon Hostage1;

Hostage1 setCaptive false;

TalkFired = 1;

if (true) exitWith {};

So, I know that the Say function only fires locally. I need it to fire on all machines so everyone standing within a 30 meter radius can hear the colonel and the soldier who activated the sequence talking to each other.

Using the crude method of a trigger with a publicVarible going true and firing off the script via the Trigger's onActivation area only works half way because I don't know how to pass on the local variables of _LDR (the player that triggered the interrogation sequence) and the rest. So only the colonel can be heard by all players during the Multiplayer session and not the triggering player's part.

I guess the question is how can I pass along globally to all machines who _LDR is so that everyone can hear both sides of the conversation during a multiplayer game?

I hope this makes sense. I am kind of new to the whole local vs. server side stuff but learning a bit daily.

Share this post


Link to post
Share on other sites

you can use MP framework for that, more info on requirements in the link, you need functions module on map.

probably better to create a small local function and just send info to it via a single line, but anyhow, here is cumbersome version.

{
if (isPlayer _x AND (_x distance Hostage1) < 30) then {
	 [Hostage1,_x,"loc",rSAY,["Russian1", 100]] call RE;
};
} foreach playableUnits;

if player is within 30 meter of hostage1 he will hear the say.

not 100% sure myself on using the MP framework, i think i got the parameters right.

Share this post


Link to post
Share on other sites

Looking much better. Thanks a bunch Demonized. One issue left. Here is the new version of the officertalk.sqf file.

if (TalkFired == 1) exitWith {};

_per = _this select 0;  // Person who had the addAction
_ldr = _this select 1;  // Person who used the addAction
_act = _this select 2;  // ID of the addAction

// Group given in the arguments section (ie: [POWS]
_grp = _this select 3 select 0;


// Remove the rescue option
_per removeAction _act;

// _nic = [objNull, _dog, rSAY, "dog_01"] call RE; 

[objNull, Hostage1, rSAY, "Russian1"] call RE;
sleep 7;
[objNull, _ldr, rSAY, "US1"] call RE;
sleep 3;
[objNull, Hostage1, rSAY, "Russian2"] call RE;
sleep 6;
[objNull, _ldr, rSAY, "US2"] call RE;
sleep 10;
[objNull, Hostage1, rSAY, "Russian3"] call RE;
sleep 13;
[objNull, _ldr, rSAY, "US3"] call RE;
sleep 5;

[objNull, Hostage1, rSAY, "Russian4"] call RE;
sleep 15;
[objNull, _ldr, rSAY, "US4"] call RE;
sleep 2;
[objNull, Hostage1, rSAY, "Russian5"] call RE;
sleep 16;
[objNull, _ldr, rSAY, "US5"] call RE;
sleep 3;
[objNull, Hostage1, rSAY, "Russian6"] call RE;
sleep 17;
[objNull, _ldr, rSAY, "US6"] call RE;
sleep 11;

[[west,"HQ"], nil , rsideRadio, "Radio1"] call RE;
sleep 11;
[objNull, _ldr, rSAY, "US7"] call RE;
sleep 5;
[objNull, Hostage1, rSAY, "Russian7"] call RE;
sleep 9;
[objNull, _ldr, rSAY, "US8"] call RE;

// Join preselected units (POWS) to callers group, silently.
[Hostage1] joinSilent (group _ldr);
Hostage1 enableAI "MOVE";
Hostage1 enableAI "ANIM";

	{Hostage1 addmagazine "30Rnd_762x39_AK47"} foreach [1,2,3,4,5,6,7,8];
	{Hostage1 addmagazine "HandGrenade_East"} foreach [1,2];
	{Hostage1 addmagazine "SmokeShell"} foreach [1,2];
	Hostage1 addweapon "ACE_AKM";

	Hostage1 selectweapon primaryweapon Hostage1;

Hostage1 setCaptive false;

TalkFired = 1;

if (true) exitWith {};

The new problem: The speech now works great. Every body can hear it in multiplayer and it selects the correct people when the script is fired. The last part of the script though.. The one that renables the AI's movement and animation and the part that issues him a weapon and magazines won't fire now if anyone but me activates him. He joins the squad alright but then just remains frozen in place and no weapons appear on him if anyone but me actgivates the script. I see that the addWeapon and addMagazines is in the MPF list of commands but the enableAI stuff is not. Any ideas on how to get the guy moving again and armed in multiplayer sessions?

Share this post


Link to post
Share on other sites

Its because when a AI joins a player, it becomes local to that group leader.

make all the enableai, setcaptive, add weapons stuff before joining the group.

You can also use MP framework for adding weapons and magazines from any client, look at bottom of link for possibilities.

Also,

if (true) exitWith {};

is not needed as sqf scripts exit automatically at the end, so you can delete that.

Edited by Demonized

Share this post


Link to post
Share on other sites

Grrrrr... Code looks like this at the end now.

[objNull, _ldr, rSAY, "US8"] call RE;

// Join preselected units (POWS) to callers group, silently.
Hostage1 enableAI "ANIM";
Hostage1 enableAI "MOVE";

Hostage1 setCaptive false;

	{Hostage1 addmagazine "30Rnd_762x39_AK47"} foreach [1,2,3,4,5,6,7,8];
	{Hostage1 addmagazine "HandGrenade_East"} foreach [1,2];
	{Hostage1 addmagazine "SmokeShell"} foreach [1,2];
	Hostage1 addweapon "ACE_AKM";

	Hostage1 selectweapon primaryweapon Hostage1;

[Hostage1] joinSilent _UnitLeader;

If I am the one that talks to the Colonel, all executes fine. If a client talks to him all the speech works and he joins the squad but the weapons he is given only spawn for a second and then vanish from his body and the enableAI stuff does not fire to make it so he can start moving again.

What does the syntax look like for rADDMAGAZINE and rADDWEAPON? It's still a bit confusing. I am slowly getting it and I appreciate the help. This is becoming very frustrating as this one last bug is IT. There are no other bugs on this map. This one little thing is preventing me from releasing this product as completed.

Share this post


Link to post
Share on other sites

Joinsilent is a local command that needs to be executed where the unit is local, in AI case its server when not in a player lead group.

If there are several players in a group and the one activating the addaction is not the leader, there is all kinds of trouble that arise.

Try this for a workaround.

remove everything red in your script, and add the blue part.

[objNull, _ldr, rSAY, "US8"] call RE;

[color="Blue"]hostage1_join = group _UnitLeader;
publicVariable "hostage1_join";[/color]

[color="Red"]// Join preselected units (POWS) to callers group, silently.
Hostage1 enableAI "ANIM";
Hostage1 enableAI "MOVE";

Hostage1 setCaptive false;

	{Hostage1 addmagazine "30Rnd_762x39_AK47"} foreach [1,2,3,4,5,6,7,8];
	{Hostage1 addmagazine "HandGrenade_East"} foreach [1,2];
	{Hostage1 addmagazine "SmokeShell"} foreach [1,2];
	Hostage1 addweapon "ACE_AKM";

	Hostage1 selectweapon primaryweapon Hostage1;

[Hostage1] joinSilent _UnitLeader;[/color]

place this in init of hostage1:

_null = this spawn {
if (!isServer) exitWith {};
_unit = _this;
waitUntil {sleep 1; !isNil ("hostage1_join")};

_unit enableAI "ANIM";
_unit enableAI "MOVE";
_unit setCaptive false;

{_unit addmagazine "30Rnd_762x39_AK47"} foreach [1,2,3,4,5,6,7,8];
{_unit addmagazine "HandGrenade_East"} foreach [1,2];
{_unit addmagazine "SmokeShell"} foreach [1,2];
_unit addweapon "ACE_AKM";
_unit selectweapon primaryweapon Hostage1;

[_unit] joinSilent hostage1_join;
};

what the above means is:

1: we create a global variable containing group to join and broadcast it to all clients with publicVariable.

2: we have a script running in the meantime, checking each second if the global variable is created running only on the server side, this is where AI is local in both SP, hosted MP and dedicated MP servers.

3: once the variable is created, we enableAI etc all that we need and give weapons etc and then join unit to the global variable group and exit.

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  

×