Jump to content
Sign in to follow this  
CaptainBravo

Get AI to say a few words of wisdom or not!

Recommended Posts

Hey everyone,

I am wondering if there is a script out there that will get AI to say a few sound clips randomly from a selected voice files in mission. So every 30-60 seconds a specific AI unit will say one of 5 voice clips.

Thanks in advance for any solutions shared.

Share this post


Link to post
Share on other sites

@Günter Severloh: Thanks. I have seen and used those mods. They are great but I am looking to add custom sounds for certain units which can only be done via script.

@2nd Ranger: Thanks for the link. The script looks like it could be the answer .. if only I knew how to use it. Any chance of an example mission somewhere?

There has to be some chat script somewhere ..

Share this post


Link to post
Share on other sites

Well first off, you could try BIS's method that they use in the Arrowhead campaign. This makes use of the conversation system.

Create a new mission and put down a trigger, 50x50 will do, make it a 'Present' activation, for whichever side your speakers are on. So for example Activation: OPFOR Present if you want Russian OPFOR to be shouting things out. Just for ease, name it BIS_combatShoutList.

Now you want your SQF file, call it 'Shouts.sqf' or whatever you want. Here it is:

//prepare combat shouts
{if (side _x == EAST) then {_x kbAddTopic ["combat_shouts", "kb\combat_shouts.bikb", ""]}} forEach allUnits;
[] spawn {
	while {TRUE} do {
		BIS_combatShoutList setPos position Player;
	sleep 3
	}
};
[] spawn {
	while {TRUE } do {
		waitUntil {count list BIS_combatShoutList > 0};
		sleep (2 + random 3 + (10 / count list BIS_combatShoutList));
		_who = (list BIS_combatShoutList) select floor random count list BIS_combatShoutList;
		_shout = format ["combat_shout_%1", floor random 3]; [color="DarkRed"]change this number for how many sounds you have. 2 sounds = floor random 3, 3 sounds = floor random 4 etc.[/color]
		_who kbTell [_who, "combat_shouts", _shout]
	}
};

As you can see, this moves the trigger you have named BIS_combatShoutList onto the player's position every 3 seconds. When there are any East units within that trigger radius, the script selects a random East unit and makes him say a sound file. Now you just have to define the sounds.

In your mission folder create a folder called kb. Now create a new text file in that folder and save it as combat_shouts.bikb. Here is what goes in that file;

class Sentences
{

class combat_shout_1
{
	text = "";
	speech[] = {"\Sound\combat_1.ogg", db+10, 1};
	class Arguments {};

};

class combat_shout_2
{
	text = "";
	speech[] = {"\Sound\combat_2.ogg", db+10, 1};
	class Arguments {};

};

};
class Arguments{};
class Special{};
startWithVocal[] = {hour};
startWithConsonant[] = {europe, university};

Two sounds are defined in that example, obviously you just create new entries for each of your own sounds.

Now create your Sound folder in the main mission directory and just put your sound files in it. Of course the names need to correspond with the names in your bikb file up there (combat_1.ogg, etc). You don't need to define your sounds in the Description.ext if you don't want to, the BIKB file seems to be all that matters.

And that should be it. You just run the script and guys start talking. If you find the kbTell method isn't to your liking, I also have a version using regular description.ext sound defines.

Share this post


Link to post
Share on other sites

Thanks 2nd Ranger. I shall test right away. The only question is I was looking to make units on my own squad say certain things. So for example unit1 will say random voice clips selected (1 out of 3) every 60 seconds. Unit 2 will say another 1 our of 3 clips also every 60 seconds. Is that possible with this script?

Share this post


Link to post
Share on other sites

Ok, so you want each AI to have his own set of sounds to say, that the others don't? This version selects a random squad member and makes him say a random sound selected from his own personal pool of files. Currently it just selects any AI, which could be the same guy who spoke last time. If your goal is to make it seem like team members are talking to eachother, you could modify this so that a different AI speaks each time. This version does not require a trigger like the first one.

The SQF;

//Voices
{if (side _x == WEST) then {

          _x kbAddTopic ["AI_Voices", "kb\AI_Voices.bikb", ""];
}
} forEach units group player;

          [] spawn {
	while {TRUE } do {

		sleep (50 + random 15); // [color="DarkRed"]AI speaks every 50-65 seconds[/color]
		_squad = [ai1,ai2]; // [color="DarkRed"]Name your AI and put them here[/color]
                       _who =  _squad select (floor(random(count _squad)));

  if (_who == ai1) then 
      {

       _line = format ["AI1_line_%1", floor random 3];
       ai1 kbTell [ai1, "AI_Voices", _line];
       };

           if (_who == ai2) then 
                {
                 _line = format ["AI2_line_%1", floor random 3];
                  ai2 kbTell [ai2, "AI_Voices", _line];
                  };
          }
};

The BIKB (AI_Voices.bikb):

class Sentences
{



       class AI1_Line_0
{
	text = "";
	speech[] = {"\Sound\combat_1.ogg", db+10, 1};
	class Arguments {};

};

       class AI1_Line_1
{
	text = "";
	speech[] = {"\Sound\combat_2.ogg", db+10, 1};
	class Arguments {};

};

class AI1_Line_2
{
	text = "";
	speech[] = {"\Sound\combat_3.ogg", db+10, 1};
	class Arguments {};

};


               class AI2_Line_0
{
	text = "";
	speech[] = {"\Sound\combat_4.ogg", db+10, 1};
	class Arguments {};

};

       class AI2_Line_1
{
	text = "";
	speech[] = {"\Sound\combat_5.ogg", db+10, 1};
	class Arguments {};

};

class AI2_Line_2
{
	text = "";
	speech[] = {"\Sound\combat_6.ogg", db+10, 1};
	class Arguments {};

};

};
class Arguments{};
class Special{};
startWithVocal[] = {hour};
startWithConsonant[] = {europe, university};

So in the BIKB you need to name each entry for the AI you want to say it (if it matters which AI is saying a particular sound). Each line that begins AI1 will be said only by the character named AI1, as defined in this part of the sqf:

 if (_who == [color="Blue"]ai1[/color]) then 
      {

       _line = format ["[color="SeaGreen"]AI1_line_[/color]%1", floor random 3];
       ai1 kbTell [ai1, "AI_Voices", _line];
       };

In blue is just the name of the AI unit. The Green part is what you need to change if you only want that particular unit to say certain things. In this example, the unit ai1 will only say sounds that have a class name beginning AI1_line_ numbered 0 to 2 in the BIKB file.

Anyway I just cobbled this together now and it works, maybe if someone with more scripting knowledge happens by, they can improve it or suggest a better method.

Edited by 2nd Ranger

Share this post


Link to post
Share on other sites

Thanks 2nd Ranger. As simple as the instructions are, I just cannot seem to get it working after trying several times.

How many bikb files do we have? Is it an SQF file format?

Any simple example would be highjly appreciated :confused:

Thanks for your help.

Share this post


Link to post
Share on other sites

Just one BIKB. The only script files you need are the ones in my last post above. The BIKB file is in BIKB format. You save the document as AI_Voices.bikb and a duplicate file will be created in BIKB format. That file goes in the folder called kb.

Share this post


Link to post
Share on other sites

Thanks 2nd Ranger. After trying a few more times, still no sucess. The units will just not speak.

Here is a simple test mission. If you can take a look at it and let me know what I am missing I would be very appreciative.

Sample mission:

http://www.gamefront.com/files/20135660/test_sound_conversation_utes_rar

Thanks for your help.

Share this post


Link to post
Share on other sites

Works for me. Are you speeding up time to get to that minute mark where they start talking? You can't hear sounds that play using the conversation system when accelerating time. Just reduce the time delay in the conversation script to something like sleep (7 + random 4) so you don't have to wait so long while testing.

Also in your sqf, you have the sound selection part using floor random 3, but you currently only have 2 sounds for each AI, numbered 0-1 in your BIKB. 'Floor random 3' means that the random number will be 0,1 or 2. Because you don't have, for example, CJ_Line_2 in the BIKB, sometimes the script will not select a sound because there is no entry for 2. So when you are done defining all your sounds, make sure the random number is always equal to the number of sounds you have, and that the entries start from 0 (so at the moment you should use floor random 2 for 2 defined sounds).

Edited by 2nd Ranger

Share this post


Link to post
Share on other sites

Thanks 2nd Ranger. Now that I have reudced the floor random 3 to 2, it works fine.

I am curious where does this code go as I have left it out as I was not sure where to put it:

if (_who == ai1) then

{

_line = format ["AI1_line_%1", floor random 3];

ai1 kbTell [ai1, "AI_Voices", _line];

};

Thanks for your help.

Share this post


Link to post
Share on other sites

That section I highlighted was just an example of how that part of the script worked. You don't need to put it anywhere.

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  

×