Jump to content
IndeedPete

Spin-Off Release: Simple Conversation System

Recommended Posts

Alright so heres my failed attempt at calling comments at random.

if (isServer) then {  _speechopeners = [_one, _two, _three] call BIS_fnc_selectRandom;

[] spawn {
waitUntil {player distance merch < 5};

_one = [merch, "Mhmmm. . .", "DIRECT"] call IP_fnc_simpleSentence; 
_two = [merch, "Be reasonable.", "DIRECT"] call IP_fnc_simpleSentence; 
_three = [merch, "Don't give me that.", "DIRECT"] call IP_fnc_simpleSentence; 

};
};    if(!isServer) then {};

Result is that all of them show in order.

You got my vote in the MANW! Good luck in the contest!

Share this post


Link to post
Share on other sites

Not sure about the isServer, how do you want that to run? In MP it needs to run on every client to make sure the player sees it. However, the player variable is different on every client. So, if you want for a player to walk by and get a sentence told only for him it should work this way (untested):

[] spawn {
   waitUntil {player distance merch < 5};

_speechOpener = ["Mhmmm. . .", "Be reasonable.", "Don't give me that."] call BIS_fnc_selectRandom;
[merch, _speechOpener, "DIRECT"] call IP_fnc_simpleSentence;
};

Thanks for the vote, greatly appreciated! ;)

Share this post


Link to post
Share on other sites

Thanks Pete it worked!!! Tried having the corresponding sound clip play but it broke.

[] spawn {
   waitUntil {player distance merch < 5};

_speechOpener = [["Mhmmm. . .", merch say3D "mer1",],["Be reasonble.", merch say3D "mer2"],["Dont give me that.", merch say3D "mer3"]] call BIS_fnc_selectRandom;
[merch, _speechOpener,"DIRECT"] call IP_fnc_simpleSentence;	

};

also tried this but it also broke

spawn {
   waitUntil {player distance merch < 5};

_speechOpener = ["Mhmmm. . .", "Be reasonble.","Dont give me that."] call BIS_fnc_selectRandom;
[merch, _speechOpener,"DIRECT"] call IP_fnc_simpleSentence;	

_speechOpener1 = ["merch say3D 'merch1'","merch say3D 'merch2'","merch say3D 'merch3'"] call BIS_fnc_selectRandom;
[merch, _speechOpener1,"DIRECT"] call IP_fnc_simpleSentence;	
};

Share this post


Link to post
Share on other sites

That can't work because you're trying to pass code (say3D) to a function which expects strings.

Share this post


Link to post
Share on other sites

Has this been tested on a dedicated server?

Share this post


Link to post
Share on other sites

Search through the pages, I believe some people tried it and confirmed it's working on dedis. Haven't done any testing myself though. But once a conversation has been added on all clients the whole system functions client-side.

Share this post


Link to post
Share on other sites

trying to have a spawned unit (raider) run to another spawned group (_enemygroup1) and Join them.

Using your suggestion Ive spawned unit (raider) with the following:

raiderspawn = {	
_pos = getMarkerPos "raiderstart"; // ToDo: Insert Position!
_grp = createGroup east;
"O_G_Soldier_F" createUnit [_pos, _grp, "raider = this; this setVariable ['BIS_enableRandomization', false];"];
};

the _enemygroup is spawned with

_randomsquad1=["B_medic_F", "B_medic_F","B_medic_F"]; _randomsquad2=["B_medic_F"];  
_randomsquad=[_randomsquad1,_randomsquad2]call BIS_fnc_selectRandom;     

_enemygroup1 = [getMarkerPos "raid1",EAST,_randomsquad,[],[],[],[],[],random 360] call BIS_fnc_spawnGroup;   
{[_x] execVM "loadoutRaid.sqf";} forEach units _enemygroup1;  

_wp1 = _enemygroup1 addWaypoint [getmarkerpos "mkr_IP_Main", 0]; 
_wp1 setWaypointType "MOVE"; 
_wp1 setWaypointSpeed "FULL"; 
_wp1 setWaypointFormation "LINE";

for the waypoint ive tried this butve been unsuccessful:

raiderspawn = {	
_pos = getMarkerPos "raiderstart"; // ToDo: Insert Position!
[color="#FF0000"]_wp1 = raider addWaypoint [getmarkerpos "mkr_IP_Main", 0]; [/color]
_grp = createGroup east;
"O_G_Soldier_F" createUnit [_pos, _grp,[color="#FF0000"] _wp1,[/color] "raider = this; this setVariable ['BIS_enableRandomization', false];"];
};

Can't figure out how to add a waypoint and "loadoutRaid.sqf" to the unit named raider. Any suggestions?

Share this post


Link to post
Share on other sites

First you need to add the waypoint after the unit is created. A simple move is enough to create a move waypoint.

Share this post


Link to post
Share on other sites

:yay: Thanks Pete! Got the move working.

Got a question about tasks. There's

a primary task with subtasks

tpoppa

...tbo

.....ta

.....tb

.....tc

Tried the following to have the primary tasks set to succeeded once the subtasks were complete. Found the following and tried using it but it didnt work.

in a triggers condition there's:

({   if ( [_x] call BIS_fnc_taskExists ) then {    [_x] call BIS_fnc_taskCompleted   }else{    false   };  }count ["ta","tb","tc"] == 3)  

and in the on act:

hint "fire check"; tpoppa setTaskState "SUCCEEDED";tbo setTaskState "SUCCEEDED";

it fires but nothing happens to tpoppa and tbo, they remain not succeeded when ta,tb, and tc are complete.

Share this post


Link to post
Share on other sites

Untested:

_subtasks = ["tSub1", "tSub2", "tSub3"];
if ({_x call BIS_fnc_taskState == "SUCCEEDED"} count _subtasks == count _subtasks) then {
["tSuper", "SUCCEEDED"] call BIS_fnc_taskSetState;
};

Share this post


Link to post
Share on other sites

Greetings Pete,

trying to have a convo choice appear only after a task has been succeeded. Tried the following:

class sanOpener1
{
	condition = "!(taskState tJob == 'SUCCEEDED');";  
	expression  = "san say 'san3';"
	responses[] = {"sanExit"};
	sentences[] = {
		"Alright Santos it's over.", 			
		"I knew you were the right man for the job."

	};
};

and also this different condition but failed:

condition = "!('tJob' call BIS_fnc_taskExists) && {('tJob' call BIS_fnc_taskState) != 'SUCCEEDED'};"

Edited by Xabialonso

Share this post


Link to post
Share on other sites

Leave the '!' out. ;)

condition = "('tJob' call BIS_fnc_taskExists) && {('tJob' call BIS_fnc_taskState) == 'SUCCEEDED'};"

Share this post


Link to post
Share on other sites

Alright!:yay: Thanks a bunch Pete!

Just wanted to say thanks for all your help Pete!

Finally finished what I was working on-- http://steamcommunity.com/sharedfiles/filedetails/?id=365970426

Could have never done it without your help. Really thanks man and have a great New Year!!!

You are too :cool:

Edited by Xabialonso

Share this post


Link to post
Share on other sites

Good day, people!

I'm happy to release an update on this one. Another project required more convo functionality and I don't want to keep the benefits from you. From now on it's possible to run kbTell convos through this system as well as playing sounds and music (check the example mission to see the new possible attributes of the "missionConversations.hpp"). Because the kbTell system is rather closed I had to do some clunky workarounds - if in doubt I'd recommend the use of the vanilla kbTell system. Anyway, the example mission has been updated with new stuff to show how to implement the new features.

Second new feature is a small function to create player-centered ambient chatter. When the script is running and the player is close enough to a group of defined NPCs one of them will most likely throw a random sentence from a given pool towards the player. Good for small camps, i.e. when the player enters a camp a guard automatically says "Welcome back!" or something. It's not meant to fire every time on every NPC, it's just a small addition to create some atmosphere. Works both text and kbTell-based. Check function headers and the example mission for details.

NOTICE: Before messing around with the new functions ambientChatterKB, simpleConversationKB and simpleSentenceKB please familiarise yourself with the kbTell system (keywords "kbTell", "kbAddTopic", "kbWasSaid").

Enjoy!

Features

  • Single sentence radio / direct conversations with live-cam or avatar picture.
  • Full multiple choice conversations with multiple layers.
  • Custom code excecution.
  • Config based, easy to set up.
  • Exclude choices based on user-defined conditions.
  • Support for music, sounds and kbTell. (Latter is still a bit clunky.)
  • MP compatible.

Setup

  1. Download v1.06 example mission.
  2. Copy conv folder to your mission.
  3. Create description.ext and add:
    #include "conv\cfg\defines.hpp"
    #include "conv\cfg\dialogs.hpp"
    
    class CfgFunctions
    {
    #include "conv\cfg\functions.hpp"
    };


  4. (Optional) Create "missionConversations.hpp", fill it with conversations and add to your desciption.ext:
    #include "missionConversations.hpp"

    .

  5. (Optional, needed for kbTell) Create "sentences.bikb", fill it with sentences and add to your desciption.ext:
    #include "sentences.bikb"

    .

  6. (Optional) Set "IP_Avatar", "IP_LiveFeed", "IP_ConvSpecial", "IP_AmbientChatter" and "IP_AmbientSentences" variables on units.

The "missionConversations.hpp"

is the central config file you need in order to create full multiple choice conversations. In its current state it should look like this:

class Conversations // main config class - DO NOT change the name!
{
class MyFirstConversation // Name of the conversation.
{
               arguments[] = {"(name player)"}; // Arguments passed to each sentence. Can be used via %1, %2, etc.
	condition = ""; // Condition (Boolean) which causes the conversation to show up as action or response in MC. Empty string means conversation will always show up.
	expression = "hint 'Sucess, yay!';"; // Expression(s) that is/are called after dialog is created and filled. Passed arguments are: [first speaker, second speaker, conversation].
               music = ""; // Name of music track to play defined in CfgMusic.
	responses[] = {"MyFirstResponse", "exit"}; // Possible responses to this conversation. Must be classname(s) of another conversation(s) in this config.
	sentences[] = {"Hello, I'm %1!", "Cool, I'm Mike, nice to meet you!"}; // Sentences of this conversation. Every even sentence will be said by the first person, every odd by the second. The first sentence of the conversation marks the response / action name in other conversations.
               sound = ""; // Name of sound to play defined in CfgSounds.
};
       class MyFirstResponse // Name of the conversation.
{
	responses[] = {"exit"};
	sentences[] = {"How are you?", "Fine, fine."};
};
       class exit
{
	exit = 1; // Closes conversation.
               expression = "nul = [iP_Buddy, 'See ya!', 'DIRECT', 3] spawn IP_fnc_simpleSentence;";
	sentences[] = {"Good bye!"};
};
};

The Variables

There are currently five variables that can be set on units by:

unit setVariable ["VarName", value, isPublic];

  • "IP_LiveFeed" - True: shows live cam when saying simpleSentence and not in a vehicle. - False: Shows avatar always.
  • "IP_Avatar" - Path to avatar picture, should be roughly 4:3 format. Default avatar picture is used if variable is nil.
  • "IP_ConvSpecial" - Will show user defined text below the avatar in a conversation.
  • "IP_AmbientChatter" - True: Unit will be in the pool of ambient NPCs if Ip_fnc_ambientChatter is running. False: Unit won't be in the pool of units who can throw a random sentence when the player walks by.
  • "IP_IP_AmbientSentences" - Array, overrides the passed sentence(s) (classes) of IP_fnc_ambientChatter(KB) for a certain unit.

The Functions

This system is based on functions defined via CfgFunctions. Below are the header of all current functions. Check them for parameter explanation.

/*
Name: addConversation
Author: IndeedPete
Purpose: Adds conversation from config to unit or object related to unit (e.g. a cellphone), i.e. adds action to start the conversation.
----------
Parameters:
_unit - OBJECT: Unit that the action should be attached to. - MyInterestingConversationPartner
_conversation - STRING: The config entry referring to the desired conversation. - "MyFirstConversation"
_object - OBJECT (Optional): Action will be attached to given object instead of unit. - MyCellphone - DEFAULT: objNull
*/

/*
Name: ambientChatter
Author: IndeedPete
Purpose: Player-centred radio chatter. If player is close, defined NPCs will throw a random sentence.
----------
Parameters:
_receiver - OBJECT: Unit that receives the _sentences. - player
_sentences - ARRAY OF STRINGS: Sentences the NPCs will randomly pick from. - ["Hello world!", "Fuck off!"]
_radius - NUMBER (OPTIONAL): Radius in metres around the _receiver in which random sentences should be triggered. - 10 - DEFAULT: 5
_cycle - NUMBER (OPTIONAL): Interval in seconds in which the script checks for near-by NPCs. - 3 - DEFAULT: 1
_sides - ARAAY OF SIDES: Sides of NPCs who are allowed to speak to the _receiver. - [west, east] - DEFAULT: [civilian, (side _receiver)]
----------
Requires:
IP_fnc_simpleSentence
*/

/*
Name: ambientChatterKB
Author: IndeedPete
Purpose: Player-centred radio chatter. If player is close, defined NPCs will throw a random sentence via kbTell.
----------
Parameters:
_receiver - OBJECT: Unit that receives the _sentences. - player
_topic - STRING: Topic needed for kbTell. - "MyTopic"
_sentences - ARRAY OF STRINGS: Sentence classes the NPCs will randomly pick from, defined in .bikb. - ["Hello world!", "Fuck off!"]
_bikb - STRING (OPTIONAL): Path to the .bikb which contains the _sentence. - "mySentences.bikb" - DEFAULT: "sentences.bikb"
_subs - BOOLEAN (OPTIONAL): Show subtitles. - false - DEFAULT: true
_radius - NUMBER (OPTIONAL): Radius in metres around the _receiver in which random sentences should be triggered. - 10 - DEFAULT: 5
_cycle - NUMBER (OPTIONAL): Interval in seconds in which the script checks for near-by NPCs. - 3 - DEFAULT: 1
_sides - ARAAY OF SIDES: Sides of NPCs who are allowed to speak to the _receiver. - [west, east] - DEFAULT: [civilian, (side _receiver)]
----------
Requires:
IP_fnc_simpleSentenceKB
.bikb - File that contains class sentences. (See BI Wiki / documentation on the kbTell system.)
*/

/*
Name: closeConversation
Author: IndeedPete
Purpose: Closes current conversation, i.e. the dialog. Is in fact just a place holder right now. 
*/

/*
Name: openConversation
Author: IndeedPete
Purpose: Opens a conversation (dialog) from config.
----------
Parameters:
_first - OBJECT: The first conversation participant saying every EVEN sentence. - player
_second - OBJECT: The second conversation participant saying every ODD sentence.  - MyInterestingConversationPartner
_conversation - STRING: The config entry referring to the desired conversation. - "MyFirstConversation"
----------
Requires:
Dialog "IP_DLG_CONVERSATION"
.jpg - "conv\img\defaultAvatar.jpg"
*/

/*
Name: removeConversation
Author: IndeedPete
Purpose: Removes conversation from unit or object, i.e. removes action to start the conversation.
----------
Parameters:
_unit - OBJECT: Unit that the action should be removed from. - MyInterestingConversationPartner
_conversation - STRING: The config entry referring to the desired conversation. - "MyFirstConversation"
*/

/*
Name: selectResponse
Author: IndeedPete
Purpose: Upon response selection, conversation dialog is closed and reopened to show the new conversation based on the selected response.
----------
Parameters:
_this - STRING: Data string which contains the two conversation participants and the response name. Trick to bypass engine limitation in passing additional arguments via dialog EHs. - "['IP_Main', 'IP_Buddy', 'MyFirstConversation']"
*/

/*
Name: simpleConversation
Author: IndeedPete
Purpose: Wrapper function to create a simple conversation from several simple sentences (IP_fnc_simpleSentence).
----------
Parameters:
_speakers - ARRAY OF OBJECTS: Units that alternately say the _sentences. - [player, SomeGuy]
_sentences - ARAAY OF STRINGS: Sentences the _speakers should say. Every Xth sentence will be spoken by the Xth speaker. - ["Hello world!", "Fuck off!"]
_wichChat - STRING (OPTIONAL): Which way of communication should be used. Available chats: "SIDE", "GROUP", "VEHICLE", "CUT" or "DIRECT" - "DIRECT" - DEFAULT: "SIDE"
_isCutscene - BOOL (OPTIONAL): Cutscene mode: If set to true cinema borders will show up and the conversation can be skipped by the player pressing space. - true - DEFAULT: false
----------
Requires:
IP_fnc_simpleSentence
*/

/*
Name: simpleConversationKB
Author: IndeedPete
Purpose: Wrapper function to create a simple conversation from several KB simple sentences (IP_fnc_simpleSentenceKB).
----------
Parameters:
_speakers - ARRAY OF OBJECTS: Units that alternately say the _sentences. Receiver of the Xth _sentence is the X + 1th _speaker. - [player, SomeGuy]
_sentences - ARRAY OF ARRAY OF STRINGS: Topics and sentences the _speakers should say. Every Xth sentence will be spoken by the Xth speaker. - [["MyTopic","Hello world!"], ["MyTopic","Fuck off!"]]
_wichChat - STRING (OPTIONAL): Which way of communication should be used for showing the text. Available chats: "SIDE", "GROUP", "VEHICLE", "CUT" or "DIRECT" - "DIRECT" - DEFAULT: "SIDE"
_isCutscene - BOOL (OPTIONAL): Cutscene mode: If set to true cinema borders will show up and the conversation can be skipped by the player pressing space. - true - DEFAULT: false
_bikb - STRING (OPTIONAL): Path to the .bikb which contains the _sentence. - "mySentences.bikb" - DEFAULT: "sentences.bikb"
----------
Requires:
IP_fnc_simpleSentenceKB
.bikb - File that contains class sentences. (See BI Wiki / documentation on the kbTell system.)
*/

/*
Name: simpleSentence
Author: IndeedPete
Purpose: Simulate radio or direct conversations between units. Calculates delay based on input length. Defines global variable "IP_SimpleSentence_Talking" while someone is talking.
----------
Parameters:
_speaker - OBJECT: Unit that should say the _sentence. - player
_sentence - STRING: Text that the _speaker should say. - "Hello world!"
_wichChat - STRING (OPTIONAL): Which way of communication should be used. Available chats: "SIDE", "GROUP", "VEHICLE", "CUT" or "DIRECT" - "DIRECT" - DEFAULT: "SIDE"
_add - NUMBER (OPTIONAL): Addition in seconds to the calculated delay. Can be negative. - 5 - DEFAULT: 0
_len - NUMBER (OPTIONAL): Fixed delay. - 20 - DEFAULT: ((count (toArray _sentence)) * _x) <- calculation to determine delay
----------
Requires:
Dialog "IP_DLG_SIMPLESENTENCE"
.jpg - "conv\img\defaultAvatar.jpg"
*/

/*
Name: simpleSentenceKB
Author: IndeedPete
Purpose: Plays speech by kbTell; shows text in simple sentence box if defined properly.
----------
Parameters:
_speaker - OBJECT: Unit that should say the _sentence. - player
_receiver - OBJECT: Unit that should say the _sentence. - player
_topic - STRING: Topic the _sentence is part of. - "MyTopic"
_sentence - STRING: Class name defined in .bikb of the _sentence the _speaker should say. - "Hello world!"
_wichChat - STRING (OPTIONAL): Which way of communication should be used for showing the text. Available chats: "SIDE", "GROUP", "VEHICLE", "CUT" or "DIRECT" - "DIRECT" - DEFAULT: "SIDE"
_bikb - STRING (OPTIONAL): Path to the .bikb which contains the _sentence. - "mySentences.bikb" - DEFAULT: "sentences.bikb"
_subs - BOOLEAN (OPTIONAL): Show subtitles. - false - DEFAULT: true
_kbTellParams - ARRAY (OPTIONAL): Additional parameters for the kbTell command. (See BI Wiki on "kbTell" for details.) - [] - DEFAULT: []
_forceRadio - BOOLEAN (OPTIONAL): Forces the kbTell command to use the radio (contrary to automatically determined way of communication). - true - DEFAULT: false
----------
Requires:
Dialog "IP_DLG_SIMPLESENTENCE"
.jpg - "conv\img\defaultAvatar.jpg"
.bikb - File that contains class sentences. (See BI Wiki / documentation on the kbTell system.)
*/

Changelog

v1.06 - Added support for kbTell, music and sounds. Added ambient chatter function.

v1.05 - Talking to dead guys is not possible anymore.

v1.04 - Added IP_fnc_simpleConversation. Changed folder structure. Changed defines to not interfere with other script packages. Added / changed some minor stuff.

v1.03 - Hotfixed wrong defaultAvatar.jpg path error.

v1.02 - Conversations can now have arguments passed to the sentences. All attributes apart from "sentences[]" are optional now and don't need to be set, not even empty (""). Functions will now create a conversation log accessible in the map screen.

v1.01 - Conversations can now have conditions.

v1.00 - Inital Release

Download v1.06

Edited by IndeedPete

Share this post


Link to post
Share on other sites
Guest

New version frontpaged on the Armaholic homepage.

================================================

We have also "connected" these pages to your account on Armaholic.

This means in the future you will be able to maintain these pages yourself if you wish to do so. Once this new feature is ready we will contact you about it and explain how things work and what options you have.

When you have any questions already feel free to PM or email me!

Share this post


Link to post
Share on other sites

Small update ahead. I've made a mistake in a sub-function needed for handling the arguments. Arguments for responses wouldn't be loaded correctly. Download 1.07 to fix the issue on your end. Stay tuned!

Changelog

v1.07 - Fixed a bug with the argument feature.

v1.06 - Added support for kbTell, music and sounds. Added ambient chatter function.

v1.05 - Talking to dead guys is not possible anymore.

v1.04 - Added IP_fnc_simpleConversation. Changed folder structure. Changed defines to not interfere with other script packages. Added / changed some minor stuff.

v1.03 - Hotfixed wrong defaultAvatar.jpg path error.

v1.02 - Conversations can now have arguments passed to the sentences. All attributes apart from "sentences[]" are optional now and don't need to be set, not even empty (""). Functions will now create a conversation log accessible in the map screen.

v1.01 - Conversations can now have conditions.

v1.00 - Inital Release

Download v1.07

Share this post


Link to post
Share on other sites
Guest

New version frontpaged on the Armaholic homepage.

================================================

We have also "connected" these pages to your account on Armaholic.

This means in the future you will be able to maintain these pages yourself if you wish to do so. Once this new feature is ready we will contact you about it and explain how things work and what options you have.

When you have any questions already feel free to PM or email me!

Share this post


Link to post
Share on other sites

Any possibility that this can be made into a addon for random mission background. I use TPW Mods Skirmish a lot when not playing SP or Co-op and this could ? flesh out the randomly spawned Civ population with some relevance.

Thanks,

B

Share this post


Link to post
Share on other sites

Sure, it could probably function as part of TPW or other ambient scripts. However, I'd much rather leave this to the mission editors. There are lots of things to customise, both in texts and dubbing. I have a handful of ambient sentences available, thanks to MrCrazyDude115, who was so kind to contribute his voice to the Contention Zone project. But it's not enough to make a decent addon. Plus players would all need the addon while a scripted solution by the mission editor would function without third party stuff. In the end this release is what the title says: a spin-off. If I need some functionality in it for my own content I'll share the updates with the community, if not it won't get any updates. I'll try to include community wishes when they're not that time consuming. And anyone's welcome to pick up what's there and form an addon from it or tailor it to his own needs.^^

Share this post


Link to post
Share on other sites

Hello Indeedpete, firstly, I want to thank you for a superb script and perfect job!

I need to know a thing or two.

Can the conversation system be used to assign a task? If so, how can I do this? I'm not very good at coding, so if you can make a example script/template, I would be really happy & buy you a virtual beer or two.

Share this post


Link to post
Share on other sites

Easy doing:

class phoneHangUp
{
exit = 1;
       expression = "[player, 'tCheckpoint', ['Engage and clear the <marker name=''mCheckpoint''>AAF Checkpoint at Edessa</marker>!', 'Clear AAF Checkpoint', 'AAF Checkpoint'], 'mCheckpoint', true, 1] call BIS_fnc_taskCreate;";
sentences[] = {
	"(Hang up.)"
};
};

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

×