Jump to content
Sign in to follow this  
A-SUICIDAL

PA System - Need Help with radio on/off actions not working on dedicated server.

Recommended Posts

I created a sample mission of a PA System for my base. I placed a radio (small object) then I added an action to it "Turn on radio" and it plays a sound file by attaching an invisible helipad to the radio and then using "say3D" to make the invisible helipad play the sound. When the the player chooses the action "Turn on Radio", the action is then replaced with a new action "Turn off radio". When the player choose "Turn off radio" the invisible helipad is deleted, which stops the sound from playing and I then use "terminate" command to completely exit the script that plays the music since it uses sleep timers that would need to be stopped. Each time the player turns the radio "on" a new sound plays. There are 10 music sound files in total, each one was saved as a 22050Hz, 45kbps, mono ogg to keep the file size small and yet it still retains good quality - considering that PA systems usually do sound mono and low in quality.

The idea behind this is... to have some sort of PA system at base that plays through a list of 10 music sound files and then loops back to the beginning of the list. If players do not want to hear it, they can turn the radio "off", or if they want to hear a particular song for the moment they are at base, they can cycle through the list of songs fast to get to the song that they want to hear. Basically the radio is meant to be turned on and left alone to do its own thing. Each song has a sleep timer that is matched to the song length. In testing in single player (editor preview) and a hosted environment, everything seems to work as it should, but when I launch a dedicated server from my computer and then connect to it and launch the sample mission, the action to "Turn on radio" appears, but when I then perform the action, nothing happens and the action "Turn on radio" still shows when it was supposed to play a song and be replaced with the action "Turn off radio". So basically the radio never turns "on" at all on a dedicated server and I can't seem to figure out why. I was hoping that somebody could help me get this to work on a dedicated server. It is a cool feature to add to any mission. Battlefield Vietnam had the same kind of PA System featured in the game at base. In the sample mission, the radio object appears on a small pole, which looks lame, but I planned to have the radio appear on a wooden crate in the final version. I also planned to use different music and possibly extend my song list to have more than 10 songs. I in no way take any credit for the music used in the sample mission.

Here's a sample mission:

radio_test.Takistan.zip

init.sqf:

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

if (isServer) then {

radio_on = false; 
publicVariable "radio_on"; 

next_track = 1;  
publicVariable "next_track";

};

description.ext:

class Header
{
 gameType = Coop;
 minPlayers = 1;
 maxPlayers = 4;
};

onLoadMission = "radio_test";
loadScreen = "";
OnLoadMissionTime = false;

respawn = "BASE";
respawndelay = 10;
disabledAI = 0;

#include "sound\sound.cpp"

sound\sound.cpp:

class CfgSounds
{
sounds[] = 
{
	track1,track2,track3,track4,track5,track6,track7,track8,track9,track10
};
class track1
{
	name="track1";
	sound[]={"sound\track1.ogg",0.3,1};
	titles[]={};
};
class track2
{
	name="track2";
	sound[]={"sound\track2.ogg",0.3,1};
	titles[]={};
};
class track3
{
	name="track3";
	sound[]={"sound\track3.ogg",0.3,1};
	titles[]={};
};
class track4
{
	name="track4";
	sound[]={"sound\track4.ogg",0.3,1};
	titles[]={};
};
class track5
{
	name="track5";
	sound[]={"sound\track5.ogg",0.3,1};
	titles[]={};
};
class track6
{
	name="track6";
	sound[]={"sound\track6.ogg",0.3,1};
	titles[]={};
};
class track7
{
	name="track7";
	sound[]={"sound\track7.ogg",0.3,1};
	titles[]={};
};
class track8
{
	name="track8";
	sound[]={"sound\track8.ogg",0.3,1};
	titles[]={};
};
class track9
{
	name="track9";
	sound[]={"sound\track9.ogg",0.3,1};
	titles[]={};
};
class track10
{
	name="track10";
	sound[]={"sound\track10.ogg",0.3,1};
	titles[]={};
};
};

radio\radio_on.sqf:

if (!isServer) exitwith {};

radio removeAction radioOn;

radioOff = radio addAction [("<t color=""#FFFF00"">" + ("Turn radio off") + "</t>"),"radio\radio_off.sqf",nil,+10,true,true,"","radio_on && player distance _target<5"]; 

radio_playing = [radio] execVM "radio\radio_playing.sqf";

radio\radio_off.sqf:

if (!isServer) exitWith {};

radio removeAction radioOff;

radioOn = radio addAction [("<t color=""#FFFF00"">" + ("Turn radio on") + "</t>"),"radio\radio_on.sqf",nil,+10,true,true,"","!radio_on && player distance _target<5"]; 

deleteVehicle radio_H;

radio_on = false;
publicVariable "radio_on";

terminate radio_playing;

hint "Radio Off";

radio\radio_playing.sqf:

if (!isServer) exitwith {};

radio_on = true;
publicVariable "radio_on";

while {radio_on} do {

   radio_H = "HeliHEmpty" createVehicle (position radio);
   radio_H attachTo [radio,[0,0,0]];

   if (next_track == 10) then {

       radio_H say3D ["track10",1,1];
       hint "track 10 playing";

       next_track = 1;
       publicVariable "next_track";

       sleep 224;

       deleteVehicle radio_H;
   };

   if (next_track == 9) then {

       radio_H say3D ["track9",1,1];
       hint "track 9 playing";

       next_track = 10;
       publicVariable "next_track";

       sleep 136;

       deleteVehicle radio_H;
   };

   if (next_track == 8) then {

       radio_H say3D ["track8",1,1];
       hint "track 8 playing";

       next_track = 9;
       publicVariable "next_track";

       sleep 171;

       deleteVehicle radio_H;
   };

   if (next_track == 7) then {

       radio_H say3D ["track7",1,1];
       hint "track 7 playing";

           next_track = 8;
       publicVariable "next_track";

       sleep 151;

       deleteVehicle radio_H;
   };

   if (next_track == 6) then {

       radio_H say3D ["track6",1,1];
       hint "track 6 playing";

       next_track = 7;
       publicVariable "next_track";

       sleep 336;

       deleteVehicle radio_H;
   };

   if (next_track == 5) then {

       radio_H say3D ["track5",1,1];
       hint "track 5 playing";

       next_track = 6;
       publicVariable "next_track";

       sleep 326;

       deleteVehicle radio_H;
   };

   if (next_track == 4) then {

       radio_H say3D ["track4",1,1];
       hint "track 4 playing";

       next_track = 5;
       publicVariable "next_track";

       sleep 251;

       deleteVehicle radio_H;
   };

   if (next_track == 3) then {

       radio_H say3D ["track3",1,1];
       hint "track 3 playing";

       next_track = 4;
       publicVariable "next_track";

       sleep 241;

       deleteVehicle radio_H;
   };

   if (next_track == 2) then {

       radio_H say3D ["track2",1,1];
       hint "track 2 playing";

       next_track = 3;
       publicVariable "next_track";

       sleep 223;

       deleteVehicle radio_H;
   };

   if (next_track == 1) then {

       radio_H say3D ["track1",1,1];
       hint "track 1 playing";

       next_track = 2;
       publicVariable "next_track";

       sleep 342;

       deleteVehicle radio_H;
   };
};

radio object init:

radio addEventHandler ["HandleDamage", {false}];
radioOn = radio addAction [("<t color=""#FFFF00"">" + ("Turn radio on") + "</t>"),"radio\radio_on.sqf",nil,+10,true,true,"","!radio_on && player distance _target<5"];

I left the sample mission running and I fell asleep and when I woke up it was still playing through the song list.

Share this post


Link to post
Share on other sites

Well basically, your scripts don't do nothing unless executed by the server. But the server, which is you in a hosted environment, won't activate them because it's not a player. It actually shouldn't work when you host either. Well, it does for you, as you're the server, but not for clients.The usual issue you stumble upon when using addaction. Do you use CBA? In which case it would be really easy.

If not, you'll have to use your radio_on.sqf to broadcast a PublicVariable to everybody, launch the radio on the client that activated it, and have an PVEH on all the clients to activate the radio on their computer.

Share this post


Link to post
Share on other sites

Well, I'm not currently using CBA. I'm trying not to use any addons at all for the mission that I am currently working on. Actually, this sample mission is in Takistan, but the real mission I want to add this to uses the Island Faysh Khabur by =KCT=BlackMamba, which is the only addon required so far. I'm not sure if you and =KCT=BlackMamba are the same guy, but if you're not, I am still very much appreciative to both of you, for both the island, and the advice you just gave me. I wish I had a better grasp for scripting. I guess at this point I can't really say that I am new to scripting, but I still feel a newb. I now get to try to learn how to use addPublicVariableEventHandler for the first time, which should be a fun learning experience, I just wish I could sit down in a classroom and have somebody teach it to me rather than have to google my brains out looking for any example I can find to school myself on how it use it correctly.

I only just yesterday launched a passworded dedicated server for the first time from my computer, but only for script testing purposes. I have no plans to use the server to play a full mission with others. I launched my game from the same computer and connect to the server. Does the dedicated server treat me like anybody else that joins the server? or does it see me as some sort of host like player since I'm joining the dedicated server from the same computer? I noticed that a lot of my scripts did not work in my mission, so little by little I have been making changes to get everything working as it should. This radio PA system is something new that I started working on 2 days ago. I had a small radio in base playing some terrible Arab music that came with the game and for the last month or so of testing my mission, the radio music has really been getting on my nerves, so I wanted to do something to replace it. I remembered playing Battlefield Vietnam a million years ago and I loved how they had a PA system at base that played Hendrix and stuff, so I just wanted to some how add something similar to my mission. I'm rambling.

I'm still a very confused, but I will do my best to learn how to use a PVEH and implement what you suggested. Thank you.

Share this post


Link to post
Share on other sites

Not the same dude, no. I wish.

So to clarify stuff:

- Yeah, as soon you're on a dedicated server, every clients is treated the same. (Well tht's not entirely true since the latest betas, where some clients can be defined as headless, but that's irrelevant here).

- So basically, if you're gonna start scripting for a dedicated server, you need to keep locality in mind at all times. A bit overwhelming at first but you'll get the hang of it soon enough.

- In the end, what I did was use a lite version of Extended Event Handlers, that Muzzleflash released a while ago, and modified it to better suit my purposes, so that today, even though I play in an addon-free community, I don't have to reinvent the wheel everytime.

In that particular case, here are the tasks (in pseudo code) you'll have to achieve:

if (!isDedicated) then {
"My_MonitoringVariable" addPublicVariableEventHandler {
	_myVar = _this select 1;
	_radioOn = _myVar select 0;
	_soundName = _myVar select 1;
	if (!isnil "radio_H) then {deleteVehicle radio_H;};
	if (_radioOn) then {
		if (!isnil "radio_H) then {deleteVehicle radio_H;};
		radio_H = "HeliHEmpty" createVehicle (position radio);
		radio_H attachTo [radio,[0,0,0]];
		radio_H say3d _soundName;
	};
};
};

This will create the PVEH on all clients. whenever that variable My_MonitoringVariable is broadcasted, everyclient will create its own radio and play its own sound.

The thing is the monitoring variable is an array, [_radioOn, _soundName]

_radioOn is a boolean (true will activate the radio on all clients)

_soundName is a string (the name of the song that will be played)

Now we need to take care of the actual script being called when you use the action. I'd simplify it by using just one "Turn radio On/Off action" for the sake of example.

And we'd like to remove all those successive If then checks you have in there.

So we'll probably create an array of arrays first, somewhere where it's executed globally. Say the init.sqf:

radio_TrackList = [["track1", 342], ["track2", 223] ...

Contains each songname and the sleep associated.

Now on the radioOnOff.sqf

_isRadioOn = My_MonitoringVariable select 0;
if (_isRadioOn) then  {
My_MonitoringVariable set [0, false]
PublicVariable "My_MonitoringVariable";
if (!isnil "radio_H) then {deleteVehicle radio_H;};
} else {
_soundName = radio_TrackList select (floor (random (count radio_TrackList)));
My_MonitoringVariable = [true, _soundName];
PublicVariable "My_MonitoringVariable";
if (!isnil "radio_H) then {deleteVehicle radio_H;};
radio_H = "HeliHEmpty" createVehicle (position radio);
radio_H attachTo [radio,[0,0,0]];
radio_H say3d _soundName;
};

This checks if the radio is currently on or off. If it's on, it deletes the radio object on the local client and broadcast the instruction to do so to everybody.

If it's off, it broadcast to everybody the instruction to create a new radio, then creates the radio on the local client (because the PVEH is not fired on the client where the PV was done.)

Of course this is unfinished, not fool proof and does lack some stuff. But the idea is basically here.

Hope that helps.

Share this post


Link to post
Share on other sites

Wow, thank you! I really appreciate all the help. It's extremely generous of you to take the time out to script all of this and also explain everything in great detail. I'm going to work on this now and do my best to get it functioning correctly.

I downloaded Celery's Jukebox 2 days ago and looked through his scripts a bit and I figured that it wouldn't fit my needs since his Jukebox uses music.cfg and not sound.cfg, but I do remember seeing that he had all of his tracks and times in one long array similar to how you demonstrated above. The one thing that struck me was - that Celery's script featured a sort of pause/resume ability that prevents the music from skipping ahead when the player hits the escape key or pauses the game. From my experience, a sound file currently playing in the game will normally keep playing even when the player hits escape. If I have a sound file playing in single player and I hit escape, the game pauses, but then when resume the game, it's as if the sound file not only continued to play while the game was paused, but it actually seems to have fast forward a little bit too. If I keep hitting escape and pausing and resuming the game many times in a row, the sound file seems to keep skipping far forward and finishes playing much sooner than it normally would have. I don't think I need to worry about that too much since I am trying to get this working on a dedicated. I'm mostly worried that if I use random, some songs might play twice in a row, which would seem weird. Or you might hear track4 play three times in a 20 minute period of time and other songs haven't even had the chance to play yet. I figured if I stuck to playing the songs in a set order, then at least each song would have a fair chance to be heard. Allowing players to cycle through the songlist fast was really not important, but I just figured that it would be a cool additional feature.

Also, I read somewhere that there is an actual PA speaker object that could be seen in the campaign. I'm guessing on the carrier. I've never seen one before, but if it does exist and there is a classname for it that I could spawn, it would look much nicer than the tiny white radio from Giligans island that I feel stuck with, lol. If anybody knows anything about a PA speaker object, let me know.

Share this post


Link to post
Share on other sites

I'm still working on this. I got sidetracked a little, but I'm still on it.

Share this post


Link to post
Share on other sites

Ok, so I had trouble trying to get this working the way you suggested, only because I lack some understanding, but I am certain that your method would have worked great. After many hours I put my new attempt aside and went back to my original fail example and managed to get it working on a dedicated server. I did keep in mind that you had mentioned in your first reply - that I would need to "broadcast a PublicVariable to everybody and launch the radio on the client that activated it", which sounded confusing to me, so I did what comes natural to me and I made it even more confusing - and I tried to do exactly what you said, but "in reverse" lol. I tried to figured out a way to have a client activate it automatically or manually through actions and then PV it to all other players, without using any event handlers. I used my usual poor-mans ghetto scripting abilities, lol, and I actually got this to work. Well, at least so far I haven't hit any big bumps. I tested it on my own dedicated server(the same crappy computer I edit from).

I posted a new topic basically releasing it as a stand alone "Song Playlist PA System". I thought it might get buried here under this thread that started out as a fail.

Here's the link:

Adding a "Song Playlist PA System" Radio to your Base

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  

×