Jump to content
Grumpy Old Man

Using Radio Protocol from script (without usage of description.ext)

Recommended Posts

Hey folks,

wondering how the Radio Protocol is working, especially how commands like "2, move 75 meters, back", "5, join group" come together dynamically and what script commands are being used for this by the engine.

I digged around in the cfgVehicles and some stuff like configfile >> "CfgVehicles" >> "ModuleGenericRadio_F" >> "Arguments" >> "Sentence" >> "values" >> "SentGenBaseSideEnemyGUER" used by "ModuleGenericRadio_F" works just fine like that:

player directsay "SentGenBaseSideEnemyGUER";

Now if I want to add a few sentences and enhance my mission with it the description.ext is getting clogged up with loads of radio sentences, especially if you want the same speakers for unit+message.

After finding the radioprotocol in the cfg there's plenty of stuff to play around with, only thing is I got no clue how to.

configfile >> "RadioProtocolENGB" >> "Words"

Here you can find pretty much every word used by AI soldiers, the only thing I'm missing is the knowledge of how to use that stuff within scripts.

Totally cryptic for me how the engine turns:

speech[] = {"XMIT","VehForward"};

into the player saying "Forward", using the correct combatmode, speaker and radiochannel.

Any clues?

This would be a great achievement for me

  • Like 3

Share this post


Link to post
Share on other sites

After digging around a bit more I've found the .bikb files being able to do this with the kbtell commands.

I used the protocol.bikb from the support provider module and could incorporate it into my own missions, now every unit will play back the correct sentences dynamically over direct, side or global radio.

I'm just struggling when wanting to add custom messages from the radioprotocol.

In the protocol.bikb there's various sentences defined like this:

	class Transport_Request
{
	text = $STR_A3_requesting_airlift_at_the_designated_coordinates__over_;
	speech[] = {SupportRequestRGTransport};
	class Arguments {};
};

Looks like the correct sounds are being chosen by using the speech[] parameter.

I tried to copy a random sentence from the radio protocol which looks like this:

	class Support
{
	text = "";
	speech[] = {"SentSupportAskHeal"};
	class Arguments {};
};

Now when I try it like that:

player kbAddtopic["Transport_Request", "protocol.bikb"];
player kbTell [player,"Transport_Request","Transport_Request"];

1tb9x6B.jpg

it's working fine, but when replacing "Transport_Request" with my custom added "Support" sentence nothing's happening.

Where can I find the correct sentence in the radioprotocol config?

Anyone got any clues?

Edited by Grumpy Old Man
  • Like 1

Share this post


Link to post
Share on other sites

i'd like to know this as well, i'd like to be able to make the AI use the built in languages to say basic words.

Share this post


Link to post
Share on other sites

Hey Gom, have you seen the "find in-game sounds/sentences" utility Larrow posted ?

 

From that I gathered all in-game command paths for "Stop", "MoveThere", "Form on Me", etc.  I then I use string replacing in the folder structure for given command  to give different Language versions of sound file, and different volume of sound file (normal, stealth=whisper, combat=shout).  So my JBOY Dog scripts allow player to command his dog using in-game voice in any language (Eng, GRE, PER, FRE, etc.) and any loudness (stealth, normal, combat).

 

So if you want to say the Stop command below in French, and you want to whisper that command, you replace 'ENG' with 'FRE' and replace 'Normal' with 'Stealth'.

 

playsound3d "A3\Dubbing_Radio_F\data\ENG\Male01ENG\RadioProtocolENG\Normal\100_Commands\Stop.ogg";

 

My script:

 

 

//JBOY_HandlerSpeak.sqf
if (!isServer)  exitwith {};
params["_dog","_handler","_command"];
//if (!alive _handler or !alive _dog) exitwith {};
//if (_handler ==objNull)  exitwith {};
_language = (_dog getVariable "vHandlerLanguageAbbrev");
//if (_language=="none") exitwith {};

_fnc_assembleSoundPath = {
    params["_speaker", "_language", "_behaviour,","_soundFileName","_lastSubDir"];
    _s = "";
    switch _language do
    {     
        case "ENG":
        {
            _s = "A3\Dubbing_Radio_F\data\ENG\Male01ENG\RadioProtocolENG\"+_behaviour+"\"+_lastSubDir+"\" + _soundFileName + ".ogg";
        };
        case "GRE":
        {
            _s = "A3\Dubbing_Radio_F\data\GRE\Male01GRE\RadioProtocolGRE\"+_behaviour+"\"+_lastSubDir+"\" + _soundFileName + ".ogg";
         };
        case "ENGB":
        {
            _s = "A3\Dubbing_Radio_F\data\ENGB\Male01ENGB\RadioProtocolENG\"+_behaviour+"\"+_lastSubDir+"\" + _soundFileName + ".ogg";
         };
        case "PER":
        {
            _s = "A3\Dubbing_Radio_F\data\PER\Male01PER\RadioProtocolPER\"+_behaviour+"\"+_lastSubDir+"\" + _soundFileName + ".ogg";
         };
        case "FRE":
        {
            _s = "A3\Dubbing_Radio_F_EXP\data\FRE\Male01FRE\RadioProtocolFRE\"+_behaviour+"\"+_lastSubDir+"\" + _soundFileName + ".ogg";
         };
        case "ENGFRE":
        {
            _s = "A3\Dubbing_Radio_F_EXP\data\ENGFRE\Male01ENGFRE\RadioProtocolENG\"+_behaviour+"\"+_lastSubDir+"\" + _soundFileName + ".ogg";
         };
        case "CHI":
        {
            _s = "A3\Dubbing_Radio_F_EXP\data\CHI\Male01CHI\RadioProtocolCHI\"+_behaviour+"\"+_lastSubDir+"\" + _soundFileName + ".ogg";
         };
        case "PERVR":
        {
            _s = "A3\Dubbing_Radio_F\data\VR\Male01PERVR\RadioProtocolPER\"+_behaviour+"\"+_lastSubDir+"\" + _soundFileName + ".ogg";
         };
        case "GREVR":
        {
            _s = "A3\Dubbing_Radio_F\data\VR\Male01GREVR\RadioProtocolGRE\"+_behaviour+"\"+_lastSubDir+"\" + _soundFileName + ".ogg";
         };
        case "ENGVR":
        {
            _s = "A3\Dubbing_Radio_F\data\VR\Male01ENGVR\RadioProtocolENG\"+_behaviour+"\"+_lastSubDir+"\" + _soundFileName + ".ogg";
         };
    };
    //diag_log _s;
    playSound3D [_s, _speaker];
};

_behaviour = "Normal";
switch (behaviour _handler) do
{     
    case "COMBAT": { _behaviour = "Combat";
                     if (_command == "Guard") then //"WatchThatTarget" only has voice files for normal and stealth, not combat.
                     { _behaviour = "Normal";} ;
                   };
    case "STEALTH":{ _behaviour = "Stealth";};
    default        { _behaviour = "Normal";};
};
switch _command do
{     
    case "heel":
    {
        if (_language=="boomer") then {
            dummy= [_handler, 0, "boomerHeel","Boomer, Heel."] execVM "JBOY_Dog\delaySay.sqf";
        } else {
            [_handler, _language, _behaviour, "FormOnMe","100_Commands"] call _fnc_assembleSoundPath;  // 3rd parameter is internal sound file name
            _handler sidechat "Heel.";
        };
    };
    case "sit":
    {
        if (_language=="boomer") then {
            dummy= [_handler, 0, "boomerSit","Boomer, Sit."] execVM "JBOY_Dog\delaySay.sqf";
        } else {
            [_handler, _language, _behaviour, "StayLow","100_Commands"] call _fnc_assembleSoundPath;  // 3rd parameter is internal sound file name
            _handler sidechat "Sit.";
        };        
    };
    case "stay":
    {
        if (_language=="boomer") then {
            dummy= [_handler, 0, "boomerStay","Boomer, Stay."] execVM "JBOY_Dog\delaySay.sqf";
        } else {
            [_handler, _language, _behaviour, "Halt","100_Commands"] call _fnc_assembleSoundPath;  // 3rd parameter is internal sound file name
            _handler sidechat "Stop.";
        };               
    };
     case "stop":
    {
        if (_language=="boomer") then {
            dummy= [_handler, 0, "boomerStay","Boomer, Stay."] execVM "JBOY_Dog\delaySay.sqf";
        } else {
            [_handler, _language, "Combat", "Disengage","100_Commands"] call _fnc_assembleSoundPath;  // 3rd parameter is internal sound file name
            _handler sidechat "Stop attacking!";
        };               
    };
    case "moveThere":
    {
        if (_language=="boomer") then {
            dummy= [_handler, 0, "boomerMoveThere","Boomer, Move there."] execVM "JBOY_Dog\delaySay.sqf";
        } else {
            [_handler, _language, _behaviour, "moveUp_1","070_MoveDirectionRelative1"] call _fnc_assembleSoundPath;  // 3rd parameter is internal sound file name
            _handler sidechat "Move there.";
        };               
    };
    case "attack":
    {
        if (_language=="boomer") then {
            dummy= [_handler, 0, "boomerAttack","Boomer, Attack!"] execVM "JBOY_Dog\delaySay.sqf";
        } else {
            [_handler, _language, "Combat", "Attack_1","015_Targeting"] call _fnc_assembleSoundPath;  // 3rd parameter is internal sound file name
            _handler sidechat "Attack!";
        };               
    };
    case "fetch":
    {
       switch _language do
        {     
            case "boomer":
            {
                 dummy= [_handler, 0, "boomerFetch",""] execVM "JBOY_Dog\delaySay.sqf";
            };
            case "ENG":    { dummy= [_handler, 0, ("Eng"+"Fetch"),"Fetch!"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "GRE":    { dummy= [_handler, 0, ("Eng"+"Fetch"),"Fetch!"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "ENGB":   { dummy= [_handler, 0, ("Eng"+"Fetch"),"Fetch!"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "PER":    { dummy= [_handler, 0, ("Per"+"Fetch"),"Fetch!"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "FRE":    { dummy= [_handler, 0, ("Fre"+"Fetch"),"Fetch!"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "ENGFRE": { dummy= [_handler, 0, ("Eng"+"Fetch"),"Fetch!"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "CHI":    { dummy= [_handler, 0, ("Chi"+"Fetch"),"Fetch!"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "PERVR":  { dummy= [_handler, 0, ("Per"+"Fetch"),"Fetch!"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "GREVR":  { dummy= [_handler, 0, ("Eng"+"Fetch"),"Fetch!"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "ENGVR":  { dummy= [_handler, 0, ("Eng"+"Fetch"),"Fetch!"] execVM "JBOY_Dog\delaySay.sqf"; };
        };
    };
    case "detain":
    {
        switch _language do
        {     
            case "boomer":
            {
                 _phrases = [ "boomerDetain", "boomerGuardThisPrick", "boomerGuardThisJoker"] call BIS_fnc_arrayShuffle;
                dummy= [_handler, 0, (_phrases select 0),"Boomer, Detain."] execVM "JBOY_Dog\delaySay.sqf";
            };
            case "ENG":    { dummy= [_handler, 0, ("Eng"+"Detain"),"Detain!"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "GRE":    { dummy= [_handler, 0, ("Eng"+"Detain"),"Detain!"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "ENGB":   { dummy= [_handler, 0, ("Eng"+"Detain"),"Detain!"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "PER":    { dummy= [_handler, 0, ("Per"+"Detain"),"Detain!"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "FRE":    { dummy= [_handler, 0, ("Fre"+"Detain"),"Detain!"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "ENGFRE": { dummy= [_handler, 0, ("Eng"+"Detain"),"Detain!"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "CHI":    { dummy= [_handler, 0, ("Chi"+"Detain"),"Detain!"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "PERVR":  { dummy= [_handler, 0, ("Per"+"Detain"),"Detain!"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "GREVR":  { dummy= [_handler, 0, ("Eng"+"Detain"),"Detain!"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "ENGVR":  { dummy= [_handler, 0, ("Eng"+"Detain"),"Detain!"] execVM "JBOY_Dog\delaySay.sqf"; };
        };
    };
    case "track":
    {
        switch _language do
        {     
            case "boomer":
            {
                 dummy= [_handler, 0, "boomerTrack","Boomer, Track the scent."] execVM "JBOY_Dog\delaySay.sqf";
            };
            case "ENG":    { dummy= [_handler, 0, ("Eng"+"Track"),"Track the scent."] execVM "JBOY_Dog\delaySay.sqf"; };
            case "GRE":    { dummy= [_handler, 0, ("Eng"+"Track"),"Track the scent"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "ENGB":   { dummy= [_handler, 0, ("Eng"+"Track"),"Track the scent"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "PER":    { dummy= [_handler, 0, ("Per"+"Track"),"Track the scent"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "FRE":    { dummy= [_handler, 0, ("Fre"+"Track"),"Track the scent"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "ENGFRE": { dummy= [_handler, 0, ("Eng"+"Track"),"Track the scent"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "CHI":    { dummy= [_handler, 0, ("Chi"+"Track"),"Track the scent"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "PERVR":  { dummy= [_handler, 0, ("Per"+"Track"),"Track the scent"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "GREVR":  { dummy= [_handler, 0, ("Eng"+"Track"),"Track the scent"] execVM "JBOY_Dog\delaySay.sqf"; };
            case "ENGVR":  { dummy= [_handler, 0, ("Eng"+"Track"),"Track the scent"] execVM "JBOY_Dog\delaySay.sqf"; };
        };
    };
     case "dropit":
    {
        switch _language do
        {     
            case "boomer":
            {
                 dummy= [_handler, 0, "boomerDropIt",""] execVM "JBOY_Dog\delaySay.sqf";
            };
            case "ENG":    { dummy= [_handler, 0, ("Eng"+"DropIt"),"Drop it."] execVM "JBOY_Dog\delaySay.sqf"; };
            case "GRE":    { dummy= [_handler, 0, ("Eng"+"DropIt"),"Drop it."] execVM "JBOY_Dog\delaySay.sqf"; };
            case "ENGB":   { dummy= [_handler, 0, ("Eng"+"DropIt"),"Drop it."] execVM "JBOY_Dog\delaySay.sqf"; };
            case "PER":    { dummy= [_handler, 0, ("Per"+"DropIt"),"Drop it."] execVM "JBOY_Dog\delaySay.sqf"; };
            case "FRE":    { dummy= [_handler, 0, ("Fre"+"DropIt"),"Drop it."] execVM "JBOY_Dog\delaySay.sqf"; };
            case "ENGFRE": { dummy= [_handler, 0, ("Eng"+"DropIt"),"Drop it."] execVM "JBOY_Dog\delaySay.sqf"; };
            case "CHI":    { dummy= [_handler, 0, ("Chi"+"DropIt"),"Drop it."] execVM "JBOY_Dog\delaySay.sqf"; };
            case "PERVR":  { dummy= [_handler, 0, ("Per"+"DropIt"),"Drop it."] execVM "JBOY_Dog\delaySay.sqf"; };
            case "GREVR":  { dummy= [_handler, 0, ("Eng"+"DropIt"),"Drop it."] execVM "JBOY_Dog\delaySay.sqf"; };
            case "ENGVR":  { dummy= [_handler, 0, ("Eng"+"DropIt"),"Drop it."] execVM "JBOY_Dog\delaySay.sqf"; };
        };
            _handler sidechat "Drop it.";
    };
    case "atEase":
    {
        if (_language=="boomer") then {
            dummy= [_handler, 0, "boomerAtEase","Boomer, At ease."] execVM "JBOY_Dog\delaySay.sqf";
        } else {
            [_handler, _language, _behaviour,( ["Safe_2", "Relax"] call BIS_fnc_selectRandom),"100_Commands"] call _fnc_assembleSoundPath;  // 3rd parameter is internal sound file name
            _handler sidechat "At ease.";
       };               
    };
    case "scout":
    {
        if (_language=="boomer") then {
            dummy= [_handler, 0, "boomerScout","Boomer, Scout."] execVM "JBOY_Dog\delaySay.sqf";
        } else {
            [_handler, _language, _behaviour,"Dismount_1","100_Commands"] call _fnc_assembleSoundPath;  // 3rd parameter is internal sound file name
            _handler sidechat "Scout.";
        };               
    };
    // TODO: Need to add boomer voice files for these ones!
    case "getin":
    {
        if (_language=="boomer") then {
            dummy= [_handler, 0, "boomerGetin","Boomer, Get in."] execVM "JBOY_Dog\delaySay.sqf";
        } else {
            [_handler, _language, "Normal","BoardThatVehicle","100_Commands"] call _fnc_assembleSoundPath;  // 3rd parameter is internal sound file name
            _handler sidechat "Get in.";
        };               
    };
    case "getout":
    {
        if (_language=="boomer") then {
            dummy= [_handler, 0, "boomerGetout","Boomer, Get out."] execVM "JBOY_Dog\delaySay.sqf";
        } else {
            [_handler, _language, "Normal", "Dismount_1","100_Commands"] call _fnc_assembleSoundPath;  // 3rd parameter is internal sound file name
            _handler sidechat "Get out.";
        };               
    };
    case "speak":
    {
        if (_language=="boomer") then {
            dummy= [_handler, 0, "boomerSitrep","Boomer, SITREP."] execVM "JBOY_Dog\delaySay.sqf";
            //dummy= [_handler, 0, "boomerGetout","Boomer, Get out."] execVM "JBOY_Dog\delaySay.sqf";
        } else {
            [_handler, _language, _behaviour, "Sitrep","120_Com_Ask"] call _fnc_assembleSoundPath;  // 3rd parameter is internal sound file name
            _handler sidechat "SITREP.";
        };               
    };
 };

 

  • Like 2

Share this post


Link to post
Share on other sites

The problem with playsound3d is that you can't stop the audio output from it,

so dead units will continue to play the sound at the commands location.

It's still unknown to me how to use kbTell to whisper or say a command in combat mode.

Using it for regular (normal) voice commands works fine.

 

Cheers

  • Like 1

Share this post


Link to post
Share on other sites
4 hours ago, Grumpy Old Man said:

The problem with playsound3d is that you can't stop the audio output from it,

so dead units will continue to play the sound at the commands location.

It's still unknown to me how to use kbTell to whisper or say a command in combat mode.

Using it for regular (normal) voice commands works fine.

 

Cheers

What's wrong with say3D?

Edit: Ah, I guess it only accepts sounds from description.ext. :/ Is there no way to do it on the fly?

Share this post


Link to post
Share on other sites
5 hours ago, Grumpy Old Man said:

The problem with playsound3d is that you can't stop the audio output from it,

so dead units will continue to play the sound at the commands location.

 

I see.  Maybe if you playsound3d from a dumb invisible object attached to unit, and in killed EH, you setpos the dumb object to [0,0,0].  Might work.  I sure get tired of workarounds though...

Share this post


Link to post
Share on other sites
29 minutes ago, johnnyboy said:

I see.  Maybe if you playsound3d from a dumb invisible object attached to unit, and in killed EH, you setpos the dumb object to [0,0,0].  Might work.  I sure get tired of workarounds though...

Yeah, probably too much to ask for a specific soundTerminate command and maybe make playsound3D command return that sound.

 

@theend3r:

kbTell is pretty much on the fly, it's just a few commands and only works if the unit currently doesn't "say" anything.

 

Cheers

  • Like 1

Share this post


Link to post
Share on other sites
7 hours ago, johnnyboy said:

I see.  Maybe if you playsound3d from a dumb invisible object attached to unit, and in killed EH, you setpos the dumb object to [0,0,0].  Might work.  I sure get tired of workarounds though...


I feel offended actually. I spend a lot of time editing BIKI instead of my own blog and no one even bothers to check :(
 

Quote

Posted on November 8, 2014 - 21:48 (UTC)

Killzone Kid

When object is supplied but not a position, the position is taken from object, otherwise the position is taken from supplied position. That doesn't mean that when position is taken from object it is going to follow object when it changes position. The sound is generated at object position and it stays there.

 

  • Thanks 2

Share this post


Link to post
Share on other sites
48 minutes ago, killzone_kid said:

I feel offended actually. I spend a lot of time editing BIKI instead of my own blog and no one even bothers to check :(
 

I'm sorry KK, you know we all love you buddy!:eyeheart:

  • Like 3

Share this post


Link to post
Share on other sites

Lots of useful info in here! :smile_o:  Turns out I've got a similar query / conundrum:

 

I would like a unit to say something from the Radio Protocol, in this case "Cannot execute, adjust coordinates.", and do so over the radio (again without usage of "description.ext" if possible).

 

The Config entry looks like this:

Spoiler

 

configfile >> "RadioProtocolENG" >> "SentARTYCannotExecuteAdjustCoordinates" >> "Cannot_execute__adjust_coordinates_" >>

gesture = "";

speech[] = {"XMIT","CannotExecuteAdjustCoordinates"};

text = "Cannot execute, adjust coordinates.";

textOrig = "Cannot execute, adjust coordinates.";

wordsClass = "Normal";

 

 

Tried this with playSound3D, and it works!  Like so:

playsound3d [ "A3\Dubbing_Radio_F\data\ENG\Male01ENG\RadioProtocolENG\Normal\100_Commands\CannotExecuteAdjustCoordinates.ogg", Loon];

He says this aloud in-game (no-lip syncing, fine in this case), which is great.

 

But what I really need is how to make him say this over the radio.

 

Anyone ideas?

 

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

×