Jump to content
IndeedPete

Spin-Off Release: Simple Conversation System

Recommended Posts

Perfect, thank you!

edit: This is just the thing I needed. Now I just have to figure out how to add more options how to finish the task (like not only by coming to some place, but also by killing somebody or bringing/finding some item). I'm working on an action-adventure like mod and this was the only thing I missed.

Edited by ramon_dexter

Share this post


Link to post
Share on other sites

Now I have another question...

The example you provided me creates task, but how do I make it succeeded? I was trying to find something in fuctions, found BIS_fnc_taskSetState or BIS_fnc_setTask, but I completely don't know, how to use them (better said, I don't know where to put them. Also, I have problems with writing the syntax right. The lack of documentation is just terrible.). So if you will help me, I will be thankful person.

Share this post


Link to post
Share on other sites

class phoneHangUp
{
exit = 1;
       expression = "['tCheckpoint', 'SUCCEEDED'] call BIS_fnc_taskSetState;";
sentences[] = {
	"(Hang up.)"
};
};

It really is just the native script code put into ""-

Share this post


Link to post
Share on other sites

OK, I got it.

But how do I make the task succeeded by killing a task's target?

Edited by ramon_dexter

Share this post


Link to post
Share on other sites

Yes, there is. But that's outside of this system. I'm sure there are plenty of threads covering task completion on killing an enemy. Look for triggers in combiantion with alive.

Share this post


Link to post
Share on other sites

I thought it is realted to triggers. I know how to set task as succeeded by a trigger.

Another question:

Is there a way to make conversation more dynamic? Like choices based on player's actions - like doing something, visiting a place, etc.

I mean something like I have a conversation with a npc. The npc gives me a task to go to a place. When I visit a place (for example a cemetery) and return to a npc, I can ask the npc questions about the cemetery. But these question will be visible only if I visit the cemetery.

Sorry for bothering you, but you're helping me a lot.

Share this post


Link to post
Share on other sites

Yes, hence there is a condition attribute for conversations.

class MyFirstConversation // Name of the conversation.
{
arguments[] = {"(name player)"}; // Arguments passed to each sentence. Can be used via %1, %2, etc.
[b][color="#FF0000"]condition = "(1 == 1)"; // Condition (Boolean) which causes the conversation to show up as action or response in MC. Empty string means conversation will always show up.[/color][/b]
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.
};

Share this post


Link to post
Share on other sites

Hi, I have another question:

I played around with the condition. Can you tell me the proper way, how to set variables by conversation option?

I tried something like this:

class phoneHangUp
{
exit = 1;
       expression = "player setVariable ['var1', 1];";
sentences[] = {
	"(Hang up.)"
};
};

Option with "expression = "player setVariable ['var1', 1];";" doesn't even shows up in the list. Now I don't know, what I am doing wrong.

I know how to use conditions like this "!alive _unit" to check if _unit is dead (target of the task). But I don't know how to tell the conversation system, that I have chosen an coversation option, or told something some other npc. If you understand, what I mean.

edit:

I found out that when I try to put

condition = "var1 = 1"

into conversation option, this conversation options doesn't show up no matter what is the value of var1. Now I don't know what am I doing wrong.

I tried to set variable with "player seVariable ["var1", 1];" and put it on init.sqf, to have a default variable value.

Edited by ramon_dexter

Share this post


Link to post
Share on other sites

Check your conditions. A global variable should be set like

expression = "var1 = 1;";

or

expression = "var1 = true;";

and checked with

condition = "var1 [b][color="#FF0000"]==[/color][/b] 1";

or

condition = "var1";

Can also be done using a unit's name space by

expression = "unit1 setVariable ['var1', 1];";

and

condition = "(unit1 getVariable ['var1', 0]) == 1";

Share this post


Link to post
Share on other sites

Well, I have tried this. My conv.hpp file looks like this:

////////////////////////////////////////////////////////////////////////////////////////////týpek 1 (guy1) task giver
//////////////////////////no task function here, only player delivers only a message > this is to test variables & conditions
//////////////////////////variable varUkol1 is set 'varUkol1 == 1' in init.sqf
////////////////////////////////////////////////////////////////////////////////////////////////////////////



class Conversations
{



class guy1_opener				/////////////////////////////////opening question
{
	arguments[] = {"(name player)"};
	responses[] = {"prace", "guy1_exit"};		
	sentences[] = {
		"Hey, can I have a question?",
		"Sure, %1. What do you need?"
	};

};

class guy1_exit
{
	exit = 1;
	expression = "nul = [iP_guy1, 'See ya.', 'DIRECT', 3] spawn IP_fnc_simpleSentence;";
	sentences[] = {"Nothing."};
};

class prace  					///////////////////////////////////////////////////////when "varUkol1 == 1", this shows up. This also has to set "varUkol1 = 2". But it doesn't.
{
	condition = "(varUkol1 == 1)";
	expression = "varUkol1 = 2;";
	responses[] = {"to_beru", "guy1_exit"};
	sentences[] = {
		"Can you give me a job?",
		"Yeah. Deliver a message to my brother."
	};
};

class to_beru  				/////////////////////////////////////////////////////this here don't work, since varUkol1 is not 2. the rest does not work.
{
	condition = "(varUkol1 == 2)";
	responses[] = {"to_zvladnu", "guy1_exit"};
	sentences[] = {
		"I can do it",
		"I haven't told you, what I want to tell him."
	};
};

class to_zvladnu
{
	exit = 1;
	condition = "(varUkol1 == 2)";
	expression = "nul = [iP_guy1, 'Tell him he's an asshole!', 'DIRECT', 3] spawn IP_fnc_simpleSentence;";
	sentences[] = {"What was it?"};
};


/////////////////////////////////////////////////////////////////////////////týpek 2 (guy2) - task receiver

class guy2_opener
{
	arguments[] = {"(name player)"};
	responses[] = {"vzkaz", "guy2_exit"};
	sentences[] = {
		"Hey.",
		"Hello."
	};

};

class guy2_exit
{
	exit = 1;
	expression = "nul = [iP_Buddy, 'Take care!', 'DIRECT', 3] spawn IP_fnc_simpleSentence;";
	sentences[] = {"See ya."};
};

class vzkaz						///////////////////////////this is the message
{
	condition = "(varUkol1 == 2)";
	expression = "varUkol1 = 3;";
	responses[] = {"guy2_exit"};
	sentences[] = {
		"Your brother tells you're an asshole.",
		"Yeah. That's him."
	};
};
};

In init.sqf is the variable "varUkol1" defined this way:

varUkol1 = 1;

I have commented the rest in the conv.hpp. Simply, the

expression = "varUkol1 = 2;";

don't work.

here is whole mission:

https://drive.google.com/file/d/0B9x-D_oCGHOdbW9rUGdpNG02OE0/view?usp=sharing

Edited by ramon_dexter

Share this post


Link to post
Share on other sites

Thanks for this great release IndeedPete!

I just want to add one remark: The unit (player) initiating the conversation by action (sentence + response) needs to have a variable name defined (which I did forget as I can always use player to access the unit). If you do not name the unit it has a very strange variable name like "Alpha 1-1:1 ...". As the script relies on saving unit names as strings and call compile them back such an invalid variable name leads to issues.

Share this post


Link to post
Share on other sites

Hence it is mentioned under "limitations" in the first post. ;)

Share this post


Link to post
Share on other sites

Ah. I didn't get this limitation then. Since the first conversation (after activating the action) always showed up and used my profile name as player name - so I thought I'm fine :). Maybe you can clarify that by name you mean the variable name of the unit. On the other hand it seems to have been clear for everyone but me - I'm still pretty newbish when it comes to scripting missions :), sorry about that.

Share this post


Link to post
Share on other sites

No problem, it is pretty unlcear.^^ A nasty workaround because these GUI elements only have limited data holding capabilities.

Share this post


Link to post
Share on other sites

About mylast question - what am I doing wrong? I think I have set changing variable values right, but it don't work. Can you look at it, please?

Share this post


Link to post
Share on other sites

You've got script errors all over the place mostly coming from undefined variables. There's still an IP_VoiceActor and IP_Buddy in your scripts but they're not on the map.

Apart from that it's working fine for me. varUkol1 is being incremented as planned. Try using the -showScriptErrors startup paramter and the debug console to monitor varUkol1. (There are fields for variable / expression monitoring.)

Share this post


Link to post
Share on other sites

Well, if I understand your work well, the IP_Buddy class is for the person, which has the conversation assigned to. I have two conversations, so I have two guys - IP_Guy1 and IP_Guy2. So the IP_Buddy is just a plain empty variable, not used by my conversation/mission. So it shouldn't affect the conversation system at all.

I removed the code pointing to IP_voiceactor.

Then I run the game with -showscripterrors and, it simply don't tell me that there is any error.

My conversation.hpp is set as I posted here, but it don't work. Everything that should be visible under condition "varUkol1 = 2" just don't show up.

Now I'm starting to be a bit frustrated - what command do I use to simply display the value of variable? when I use missionnamespace getVariable "varUkol1", it works (I mean that it execs with no error), but shows nothing.

Edited by ramon_dexter

Share this post


Link to post
Share on other sites

The IP_Buddy is empty yet still used in oen of your classes:

class guy2_exit
{
	exit = 1;
	expression = "nul = [iP_Buddy, 'Take care!', 'DIRECT', 3] spawn IP_fnc_simpleSentence;";
	sentences[] = {"See ya."};
};

I just paste varUkol1 into the variable fields in the debug console (Esc).

Will take a look later again. I've also used a clean start without any mods if that might support the problem. In my tests of your mission varUkol1 was 1 in the beginning, then I talked to the guy and it changed to 2 and finally to 3 once I talked to the other dude.

Share this post


Link to post
Share on other sites

Well its strange. I tested it and changing variable works for me.

class prace
{
	condition = "(varUkol1 == 1)";
	expression = "varUkol1 = 2;";
	responses[] = {"to_beru", "guy1_exit"};
	sentences[] = {
		"Can you give me a job?",
		"Yeah. Deliver a message to my brother."
	};
};

This expression switches the varUkol1 to "2", as intended.

But this don't work. This option don't shows up.

class to_beru
{
	condition = "(varUkol1 == 2)";
	responses[] = {"to_zvladnu", "guy1_exit"};
	sentences[] = {
		"I can do it",
		"I haven't told you, what I want to tell him."
	};
};

Also, I corrected the "IP_Buddy" appearance in conversation code and published a new pack with the mission, so if you will be looking into the code, download the mission again.

For better understanding, here is how is the conversation supposed to look:

A: "Hey, can I have a question?",						
B: "Sure, %1. What do you need?"
A: "Can you give me a job?",	/////varUkol1 == 1; varUkol1 = 2;
B: "Yeah. Deliver a message to my brother."
A: "I can do it", /////varUkol1 == 2;
B: "I haven't told you, what I want to tell him."
A: "What was it?"														
B: 'Tell him he's an asshole!'


A: "Hey.",
C: "Hello."
A: "Your brother tells you're an asshole.", /////varUkol1 == 2; varUkol1 = 3;
C: "Yeah. That's him."
A: "See ya."
C: "Take care!"

Edited by ramon_dexter

Share this post


Link to post
Share on other sites

I disconnected all mods and tested the conversation and even without mods its not showing options with a condition different than "varUkol1 = 1".

Share this post


Link to post
Share on other sites

I see your problem now. You're checking a condition at a point where it can't be satisfied yet. The expression is being spawned, means there is a time delay between opening the next window and setting the variable varUkol1. I'm not sure why you'd do it that way, as to_beru doesn't need a condition in my opinion. It's only accessible after prace anyway. Just leave out the condition on to_beru, increment the variable if you like and both prace and to_beru will show up only once. But keep in mind that players can exit the dialog at any given time by hitting Esc. Hence there's also the possibility, that they read prace, then hit Esc and can't access the quest anymore.

Share this post


Link to post
Share on other sites

I though there might be a problem in this.

Maybe I did it a little bit complicated. I can make visible class "prace" under condition "varUkol1 == 1", response to this make visible under condition "varUkol1 == 1" and then make expression "varUkol1 = 2", which will hide the class "prace" and the response.

Hey, many thanks. You helped me a lot!

edit: YES!!! Now it's properly working. I just have to settle down with my requirements. After all, I'm traing to make a adventure-like action game out of a military simulator.

Edited by ramon_dexter

Share this post


Link to post
Share on other sites

Can you confirm one thing that I found out?

I think that the conversation system checks condition once for every conversation.

I tried setting one option to give task to kill a bandit leader under condition "vTask1 == 1" and reaction to this (which would give player new equipment) under condition "!alive banditLeader". No matter what I tried, the second condition don't work. Is it possible that the condition could be only one for one conversation for one person?

I know I a want too much, but I want to make some immersion - like in real life, you are given a task, you do it and then you return to the task giver for reward. Also, I want to ged rid of the "give task" option from the conversation, once the task is done, because it is obsolete.

Share this post


Link to post
Share on other sites

A condition depending on context is checked either when the player approaches a unit with a conversation added or when loading responses to an already open conversation.

Use the conditions wisely, try to avoid extra variables where possible. Use BIS_fnc_taskExists and BIS_fnc_taskState to check if the task is given / succeeded.

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

×