00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <algorithm>
00025 #include <iostream>
00026 #include <string.h>
00027
00028 #include "character.h"
00029 #include "dialog.h"
00030 #include "nls.h"
00031 #include "yarg.h"
00032
00033
00034 dialog::dialog (character_base *npc)
00035 {
00036 strings = NULL;
00037 npc_portrait_= npc->get_portrait ();
00038 npc_name_ = npc->get_name ();
00039 }
00040
00041
00042 dialog::~dialog ()
00043 {
00044 clear ();
00045 }
00046
00047
00048 bool dialog::init (string fpath, string name, PyObject *args)
00049 {
00050
00051 if (!dialogue.create_instance (fpath, name, args))
00052 return false;
00053
00054
00055 if (!setup ())
00056 return false;
00057
00058 return true;
00059 }
00060
00061
00062 bool dialog::setup ()
00063 {
00064 PyObject *list, *s;
00065 u_int32 i, size;
00066
00067
00068 list = dialogue.get_attribute ("loop");
00069 if (list && PyList_Check (list))
00070 {
00071 size = PyList_Size (list);
00072
00073 for (i = 0; i < size; i++)
00074 {
00075 s = PyList_GetItem (list, i);
00076 if (s && PyInt_Check (s)) loop.push_back (PyInt_AsLong (s));
00077 }
00078
00079 Py_DECREF (list);
00080 }
00081
00082
00083 list = dialogue.get_attribute ("text");
00084 if (list && PyList_Check (list))
00085 {
00086 size = PyList_Size (list);
00087 strings = new const char*[size];
00088
00089 for (i = 1; i < size; i++)
00090 {
00091 s = PyList_GetItem (list, i);
00092 if (s && PyString_Check (s)) strings[i] = PyString_AsString (s);
00093 else strings[i] = "*** Error";
00094 }
00095
00096 Py_DECREF (list);
00097 }
00098 else return false;
00099
00100
00101 answers.push_back (0);
00102
00103 return true;
00104 }
00105
00106
00107 bool dialog::reload (string fpath, string name, PyObject *args)
00108 {
00109
00110 if (!dialogue.reload_instance (fpath, name, args))
00111 return false;
00112
00113
00114 if (!setup ())
00115 return false;
00116
00117 return true;
00118 }
00119
00120
00121 void dialog::clear ()
00122 {
00123 if (strings) delete[] strings;
00124 }
00125
00126
00127 string dialog::text ()
00128 {
00129 if (i_text == text_.end ())
00130 {
00131 i_text = text_.begin ();
00132 return "";
00133 }
00134
00135 return *i_text++;
00136 }
00137
00138
00139 void dialog::run (u_int32 index)
00140 {
00141 PyObject *arg, *result, *speaker, *speech;
00142 s_int32 s, answer = answers[index];
00143 u_int32 stop, size;
00144
00145
00146 text_.clear ();
00147 answers.clear ();
00148
00149
00150 if (answer == -1)
00151 return;
00152
00153
00154 if (find (loop.begin (), loop.end (), answer) == loop.end ())
00155 used.push_back (answer);
00156
00157 do
00158 {
00159
00160 arg = Py_BuildValue ("(i)", answer);
00161
00162
00163 dialogue.run (arg);
00164 #ifdef PY_DEBUG
00165 python::show_traceback ();
00166 #endif
00167 Py_XDECREF (arg);
00168
00169
00170
00171 speaker = dialogue.get_attribute ("speaker");
00172 speech = dialogue.get_attribute ("speech");
00173
00174
00175 for (int i = 0; i < PyList_Size (speech); i++)
00176 {
00177 s = PyInt_AsLong (PyList_GetItem (speech, i));
00178
00179
00180 if (find (used.begin (), used.end (), s) != used.end ())
00181 {
00182 PySequence_DelItem (speaker, i);
00183 PySequence_DelItem (speech, i--);
00184 }
00185 }
00186
00187
00188 size = PyList_Size (speech);
00189 if (size == 0)
00190 {
00191 i_text = text_.begin ();
00192 return;
00193 }
00194
00195
00196 yarg::range (0, size - 1);
00197
00198
00199 if (PyList_GetItem (speaker, 0) != Py_None)
00200 {
00201
00202 int rnd = yarg::get ();
00203
00204
00205 answer = PyInt_AsLong (PyList_GetItem (speech, rnd));
00206 text_.push_back (scan_string (nls::translate (strings[answer])));
00207
00208
00209 char *npc = PyString_AsString (PyList_GetItem (speaker, rnd));
00210 if (npc != NULL)
00211 {
00212 if (strcmp ("Narrator", npc) == 0) npc_color_ = 0;
00213 else
00214 {
00215
00216 character_base *mychar = data::characters[npc];
00217
00218 npc_color_ = mychar->get_color ();
00219 npc_portrait_ = mychar->get_portrait ();
00220 npc_name_ = npc;
00221 }
00222 }
00223
00224
00225 arg = Py_BuildValue ("(i)", answer);
00226 result = dialogue.call_method_ret ("stop", arg);
00227 stop = PyInt_AsLong (result);
00228 Py_XDECREF (result);
00229 Py_XDECREF (arg);
00230
00231
00232 if (find (loop.begin (), loop.end (), answer) == loop.end ())
00233 used.push_back (answer);
00234
00235 answers.push_back (answer);
00236 }
00237 else
00238 {
00239
00240 for (u_int32 i = 0; i < size; i++)
00241 {
00242
00243 answer = PyInt_AsLong (PyList_GetItem (speech, i));
00244 text_.push_back (scan_string (nls::translate (strings[answer])));
00245 answers.push_back (answer);
00246 }
00247
00248
00249 stop = true;
00250 }
00251
00252
00253 Py_XDECREF (speaker);
00254 Py_XDECREF (speech);
00255 }
00256 while (!stop);
00257
00258
00259 i_text = text_.begin ();
00260 }
00261
00262
00263
00264 string dialog::scan_string (const char *s)
00265 {
00266 u_int32 begin, end, len;
00267 PyObject *result;
00268 char *tmp, *start, *mid, *str = NULL;
00269 character *the_player = data::the_player;
00270 string newstr (s);
00271
00272
00273 while (1)
00274 {
00275
00276 start = strchr (newstr.c_str (), '$');
00277 if (start == NULL) break;
00278
00279
00280 if (strncmp (start, "$name", 5) == 0)
00281 {
00282 begin = newstr.length () - strlen (start);
00283 string t (newstr, 0, begin);
00284 t += the_player->get_name ();
00285 t += (start+5);
00286
00287 newstr = t;
00288 continue;
00289 }
00290
00291
00292 if (strncmp (start, "$fm", 3) == 0)
00293 {
00294
00295 end = strcspn (start, "}");
00296 str = new char[end];
00297 str[end-1] = 0;
00298 strncpy (str, start+3, end);
00299
00300 if (the_player->storage::get_val ("gender") == FEMALE)
00301 mid = get_substr (str, "{", "/");
00302 else
00303 mid = get_substr (str, "/", "}");
00304
00305 begin = newstr.length () - strlen(start);
00306 tmp = new char[newstr.length () - end + strlen (mid)];
00307 strncpy (tmp, newstr.c_str (), begin);
00308 tmp[begin] = 0;
00309 strcat (tmp, mid);
00310 strcat (tmp, start+end+1);
00311
00312 delete[] str;
00313 delete[] mid;
00314 newstr = tmp;
00315
00316 continue;
00317 }
00318
00319
00320 cout << "\n*** Error, unknown macro " << start << flush;
00321 start[0] = ' ';
00322 }
00323
00324
00325 while (1)
00326 {
00327
00328 start = strchr (newstr.c_str (), '{');
00329 if (start == NULL) break;
00330
00331 end = strcspn (start, "}");
00332 mid = NULL;
00333
00334 str = new char[end];
00335 str[end-1] = 0;
00336
00337
00338 strncpy (str, start+1, end-1);
00339
00340
00341 result = PyObject_CallMethod (dialogue.get_instance (false), str, NULL);
00342
00343 if (result)
00344 if (PyString_Check (result))
00345 mid = (char*) nls::translate (PyString_AS_STRING (result));
00346
00347
00348
00349 len = newstr.length ();
00350 begin = len - strlen (start);
00351 tmp = new char[(mid ? strlen(mid) : 0) + len - strlen(str)];
00352
00353
00354 strncpy (tmp, newstr.c_str (), begin);
00355 tmp[begin] = 0;
00356 if (mid) strcat (tmp, mid);
00357 strcat (tmp, start+end+1);
00358
00359
00360 newstr = tmp;
00361
00362
00363 Py_XDECREF (result);
00364 delete[] str;
00365 delete[] tmp;
00366 }
00367
00368 return newstr;
00369 }
00370
00371 char *dialog::get_substr (const char* string, const char* begin, const char* end)
00372 {
00373 u_int32 b, e;
00374 b = strcspn (string, begin) + 1;
00375 e = strcspn (string, end) - b;
00376
00377 char *result = new char[e+1];
00378 strncpy (result, string+b, e);
00379 result[e] = 0;
00380
00381 return result;
00382 }