woo I've just written some new generic functions enabling me to call multi-choice questions (rather than just Yes/No questions), with up to 5 options. :smile:
could make things interesting... :teethy:
I've just been reading through this thread, and came across this from about 4 years ago. It occurs to me that I never actually used the code, although from what I remember it worked perfectly. Therefore, I thought I'd outline it below, for others to use if they wish.
Please bear in mind that I wrote this four years ago and have barely looked at it since. It's therefore a little fuzzy as to what it all does.
In def.gs:
tab questtab
tab answertab
tab actiontab
int totquest
The above defines the question 'tables' and an integer.
In dialogs.gs:
str g_op1;
str g_op2;
str g_op3;
str g_op4;
str g_op5;
str g_op6;
str g_op7;
str g_op8;
str g_op9;
int g_opt;
/////////////////////////////////////////////////////////////////////////////////
// IN: int; options; number of answer options
// IN: int; default=0; default selected answer
// IN: str; text; question text
// [IN]: str; op1 - op5; option text
// quick call for OpenNewQuestion() with player color settings
/////////////////////////////////////////////////////////////////////////////////
func QuestMessage1(options,default,text,op1,op2,op3,op4,op5,op6)
{
return OpenNewQuestion(text,options,COLOR_WHITE,COLOR_GREEN,default,op1,op2,op3,op4,op5,op6);
}
func QuestMessage2(options,default,text,op1,op2,op3,op4,op5,op6)
{
return OpenNewQuestion(text,options,COLOR_WHITE,COLOR_MAGENTA,default,op1,op2,op3,op4,op5,op6);
}
/////////////////////////////////////////////////////////////////////////////////
// IN: str; text; question text
// IN: int; options; number of answer options
// IN: str; textcol; question text colour
// IN: str; bordcol; question border colour
// IN: int; default=0; default selected answer
// [IN]: str; op1 - op5; option text
// OUT: int; selected answer
// Opens a question dialog.
// Uses DialogNewQuestion() function for dialog creation.
/////////////////////////////////////////////////////////////////////////////////
func OpenNewQuestion(text,options,textcol,bordcol,default,op1,op2,op3,op4,op5,op6)
{
GamePause(1);
if(!?default) default=0;
g_dlgquestion_text = text;
g_op1 = op1;
g_op2 = op2;
g_op3 = op3;
g_op4 = op4;
g_op5 = op5;
g_op6 = op6;
g_opt = options;
select = RunDialogSelect( gs_fid("DialogNewQuestion"), options, default, true );
GamePause(0);
return select;
}
/////////////////////////////////////////////////////////////////////////////////
// IN: int; select; current selection index
// New Question creation function used by NewQuestion().
/////////////////////////////////////////////////////////////////////////////////
func DialogNewQuestion( select )
{
text = "{a:center}"+g_dlgquestion_text+"nn{c:0xff0000}";
if(g_opt==1)
{
if(select==0) text += "{f:1}"+g_op1;
}
if(g_opt==2)
{
if(select==0) text += "{f:1}"+g_op1+"{f:0}n"+g_op2;
if(select==1) text += g_op1+"n{f:1}"+g_op2+"{f:0}";
}
else if(g_opt==3)
{
if(select==0) text += "{f:1}"+g_op1+"{f:0}n"+g_op2+"n"+g_op3;
if(select==1) text += g_op1+"n{f:1}"+g_op2+"{f:0}n"+g_op3;
if(select==2) text += g_op1+"n"+g_op2+"n{f:1}"+g_op3+"{f:0}";
}
else if(g_opt==4)
{
if(select==0) text += "{f:1}"+g_op1+"{f:0}n"+g_op2+"n"+g_op3+"n"+g_op4;
if(select==1) text += g_op1+"n{f:1}"+g_op2+"{f:0}n"+g_op3+"n"+g_op4;
if(select==2) text += g_op1+"n"+g_op2+"n{f:1}"+g_op3+"{f:0}n"+g_op4;
if(select==3) text += g_op1+"n"+g_op2+"n"+g_op3+"n{f:1}"+g_op4+"{f:0}";
}
else if(g_opt==5)
{
if(select==0) text += "{f:1}"+g_op1+"{f:0}n"+g_op2+"n"+g_op3+"n"+g_op4+"n"+g_op5;
if(select==1) text += g_op1+"n{f:1}"+g_op2+"{f:0}n"+g_op3+"n"+g_op4+"n"+g_op5;
if(select==2) text += g_op1+"n"+g_op2+"n{f:1}"+g_op3+"{f:0}n"+g_op4+"n"+g_op5;
if(select==3) text += g_op1+"n"+g_op2+"n"+g_op3+"n{f:1}"+g_op4+"{f:0}n"+g_op5;
if(select==4) text += g_op1+"n"+g_op2+"n"+g_op3+"n"+g_op4+"n{f:1}"+g_op5+"{f:0}";
}
else
{
if(select==0) text += "{f:1}"+g_op1+"{f:0}n"+g_op2+"n"+g_op3+"n"+g_op4+"n"+g_op5+"n"+g_op6;
if(select==1) text += g_op1+"n{f:1}"+g_op2+"{f:0}n"+g_op3+"n"+g_op4+"n"+g_op5+"n"+g_op6;
if(select==2) text += g_op1+"n"+g_op2+"n{f:1}"+g_op3+"{f:0}n"+g_op4+"n"+g_op5+"n"+g_op6;
if(select==3) text += g_op1+"n"+g_op2+"n"+g_op3+"n{f:1}"+g_op4+"{f:0}n"+g_op5+"n"+g_op6;
if(select==4) text += g_op1+"n"+g_op2+"n"+g_op3+"n"+g_op4+"n{f:1}"+g_op5+"{f:0}"+"n"+g_op6;
if(select==5) text += g_op1+"n"+g_op2+"n"+g_op3+"n"+g_op4+"n"+g_op5+"n{f:1}"+g_op6+"{f:0}";
}
DialogPush();
DialogSetText(text);
DialogSetColor(COLOR_DIALOG);
DialogFitCenter();
}
The above code does the 'heavy lifting' of actually running the question functions and sorting it all out - dealing with all the options, and removing a question from that particular selection once it has been 'asked'.
In game.gs:
func Get_Questions()
{
questtab = tab(10);
//answertab = tab(5);
actiontab = tab(10);
qx=1;
if(ObjGet(ObjFind(1001),O_DISABLE)==1) { questtab[qx] = "Question 1";actiontab[qx]=44001;qx=qx+1; }
if(ObjGet(ObjFind(1002),O_DISABLE)==1) { questtab[qx] = "Question 2";actiontab[qx]=44002;qx=qx+1; }
if(ObjGet(ObjFind(1003),O_DISABLE)==1) { questtab[qx] = "Question 3";actiontab[qx]=44003;qx=qx+1; }
if(ObjGet(ObjFind(1004),O_DISABLE)==1) { questtab[qx] = "Question 4";actiontab[qx]=44004;qx=qx+1; }
if(ObjGet(ObjFind(1005),O_DISABLE)==1) { questtab[qx] = "Question 5";actiontab[qx]=44005;qx=qx+1; }
questtab[qx] = "ASK NOTHING";actiontab[qx]=0;qx=qx+1;
totquest = qx-1;
}
func ActionObject_1000()
{
Get_Questions();
idx = ObjFind(1000);
if(ObjGet(idx,O_STATUS)==0 && totquest>1)
{
choice = QuestMessage1(totquest,0,"Choose a question",questtab[1],questtab[2],questtab[3],questtab[4],questtab[5],questtab[6]);
if(choice==0) { Get_Answer(actiontab[1]); }
if(choice==1) { Get_Answer(actiontab[2]); }
if(choice==2) { Get_Answer(actiontab[3]); }
if(choice==3) { Get_Answer(actiontab[4]); }
if(choice==4) { Get_Answer(actiontab[5]); }
if(choice==5) { Get_Answer(actiontab[6]); }
}
}
func Get_Answer(ans)
{
if(ans==44001) ObjSet(ObjFind(1001),O_DISABLE,0);
if(ans==44002) ObjSet(ObjFind(1002),O_DISABLE,0);
if(ans==44003) ObjSet(ObjFind(1003),O_DISABLE,0);
if(ans==44004) ObjSet(ObjFind(1004),O_DISABLE,0);
if(ans==44005) ObjSet(ObjFind(1005),O_DISABLE,0);
}
This code is the 'front-facing' code, which you'll use and modify for your own purposes. I've noticed that it doesn't seem to be completely finished, as the first function uses a generic name, whereas you're likely to need multiple copies of it in the game, if you want to ask different characters different questions. The last function can happily contain all the actions etc for every option in every question - obviously you need to give them all different identifying numbers though! (for example, in the code above, I've used answer numbers 44001 to 44005. The next question would use 44006, 44007 etc etc.
In the map, I had 6 objects, numbered from 1000 to 1005. The above code checked if they were disabled, and if not, enabled the corresponding option in the question.
Basically, the upshot of it all is that if you action object 1000, it will ask you to select one of 5 options ('questions to ask', as this was meant to be for a murder-mystery game). Once you select an option, the corresponding action happens. I think I was also going to add an 'answer' function too, but can't remember why I didn't. It could be that I decided it wasn't needed.
The really clever bit is that once you have asked, say, question 2, the game then removes question 2 from the list when you next action that object. Previously, if you'd wanted to ask a list of questions, you'd have had to code a new dialog for each possible combination of questions - which obviously would be ludicrous. With this code, the function DialogNewQuestion handles all that.
Plus, you can add more than 5 questions into each character's code, as long as the variables only allow 5 to be displayed at once. So for example, once question 2 has been asked, a new question, question 6, can be added to that character's questions, simply by defining the if statements correctly.
Anyway, have a play around with it. To me, it opens up a lot of possibilities - I was intending to use it to write a mystery game, where you had to go around interrogating characters, finding out different information and causing different things to happen, depending on what questions you asked them. I never got round to it though, and probably never will.
It should all work as is; I don't think I've missed anything. There's a line of code '#def O_EXAMINE 32' in gamedef.gs, but I can't see anywhere that I've used it, so I'm thinking it was just a hang-over from an early version of the code.
Once you've had a play, if you still have any questions, please ask and I'll do my best to answer, when I'm next on here!