1 /*
2    (C) Copyright 2000/2001/2002 Kai Sterker <kai.sterker@gmail.com>
3    Part of the Adonthell Project <http://adonthell.nongnu.org>
4 
5    Adonthell is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9 
10    Adonthell is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with Adonthell.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #ifndef DIALOG_H__
20 #define DIALOG_H__
21 
22 
23 /**
24  * @file   dialog.h
25  * @author Kai Sterker <kai.sterker@gmail.com>
26  *
27  * @brief  Defines the dialog class.
28  *
29  *
30  */
31 
32 #include "character_base.h"
33 #include "py_object.h"
34 
35 
36 using namespace std;
37 
38 
39 /**
40  * The lowlevel dialog class. It is the link between Python dialogue
41  * scripts and the \link dialog_screen dialogue GUI \endlink . As such
42  * it is responsible for loading dialogue scripts and for stepping through
43  * the dialogue according to the player's %input and the current state
44  * of the %game. After each step, the resulting dialogue %text is available
45  * for display through the GUI.
46  *
47  */
48 class dialog
49 {
50 public:
51 
52     /**
53      * Default constructor.
54      * @param npc The npc this dialogue is assigned to.
55      */
56     dialog (character_base *npc);
57 
58     /**
59      * Destructor.
60      *
61      */
62     ~dialog ();
63 
64     /**
65      * Load and instanciate the dialog object.
66      *
67      * @param fpath full path to the dialogue.
68      * @param name name of the dialogue class.
69      * @param args arguments to pass to the dialogue class
70      *
71      * @return \e true in case of success, \e false otherwise.
72      * @sa reload()
73      */
74     bool init (string fpath, string name, PyObject *args);
75 
76     /**
77      * This method is similar to init. But unlike init, it will
78      * correctly handle dialogues that have changed on disk since
79      * they were first imported. This function can safely be called
80      * several times, although the dialogue will be reset each time.
81      *
82      * @param fpath full path to the dialogue.
83      * @param name name of the dialogue class.
84      * @param args arguments to pass to the dialogue class
85      *
86      * @return \e true in case of success, \e false otherwise.
87      * @sa init()
88      */
89     bool reload (string fpath, string name, PyObject *args);
90 
91     /**
92      * Run the dialogue. Executes one step of the conversation.
93      * Afterwards the NPC's speech and possible reactions of the
94      * player can be retrieved via the text() method.
95      *
96      * @param index the index of the chosen alternative from the
97      *        previous list of %text.
98      */
99     void run (u_int32 index);
100 
101     /**
102      * Returns the Python dialog instance.
103      *
104      *
105      * @return the Python dialog instance.
106      */
get_instance()107     PyObject *get_instance ()
108     {
109         return dialogue.get_instance ();
110     }
111 
112     /**
113      * Returns the color to be used for displaying the NPC's speech.
114      *
115      *
116      * @return the NPC's color.
117      */
npc_color()118     u_int32 npc_color () { return npc_color_; }
119 
120     /**
121      * Returns the image to be displayed next to the NPC's speech.
122      *
123      *
124      * @return name of the image.
125      */
npc_portrait()126     const string & npc_portrait () { return npc_portrait_; }
127 
128     /**
129      * Returns the name to be displayed under the NPC's portrait.
130      *
131      *
132      * @return name of the NPC.
133      */
npc_name()134     const string & npc_name () { return npc_name_; }
135 
136     /**
137      * Returns the number of %text lines available at this point of
138      * the dialoge.
139      *
140      * @return the number of available dialogue texts. 0 if the
141      *         dialogue is finished.
142      *
143      * @sa text()
144      */
text_size()145     u_int32 text_size () { return text_.size (); }
146 
147     /**
148      * Iterates over the dialogue's %text. Depending on the current state
149      * of the dialogue, there can be multiple alternatives. The first
150      * string is always the NPC's speech. Any following strings are
151      * the player's possible reactions. The value passed to the run ()
152      * method is the (zero-based) index of the alternative chosen by
153      * the player.
154      *
155      * @return the next string in the list of text, or the empty string ""
156      *      when the end of the array of strings has been reached.
157      * @sa text_size()
158      */
159     string text ();
160 
161 private:
162     py_object dialogue;             // Points to the instantiated dialogue class
163     vector<string> strings;         // The dialogue text
164     vector<string> text_;           // NPC's speech and according Player responses
165     vector<string>::iterator i_text;// Iterator for the text_ vector
166 
167     u_int32 npc_color_;             // Current NPCs text color
168     string npc_portrait_;           // Current NPCs portrait
169     string npc_name_;               // Current NPCs name
170 
171     vector<s_int32> answers;        // The indices to pass to dialogue.run ()
172     vector<s_int32> choices;        // Strings player can chose from
173     vector<s_int32> used;           // Dialogue parts that are already spoken
174     vector<s_int32> loop;           // Dialogue parts that can be looped
175 
176     void clear ();                  // Cleanup
177     bool setup ();                  // Further dialogue initialisation
178     string scan_string (const string & s);// Look for enclosed code and execute it
179     char* get_substr (const char*, const char*, const char*);
180 };
181 
182 #endif // DIALOG_H__
183 
184