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 const char *start;
00269 char *tmp, *mid, *str = NULL;
00270 character *the_player = data::the_player;
00271 string newstr (s);
00272
00273
00274 while (1)
00275 {
00276
00277 start = strchr (newstr.c_str (), '$');
00278 if (start == NULL) break;
00279
00280
00281 if (strncmp (start, "$name", 5) == 0)
00282 {
00283 begin = newstr.length () - strlen (start);
00284 string t (newstr, 0, begin);
00285 t += the_player->get_name ();
00286 t += (start+5);
00287
00288 newstr = t;
00289 continue;
00290 }
00291
00292
00293 if (strncmp (start, "$fm", 3) == 0)
00294 {
00295
00296 end = strcspn (start, "}");
00297 str = new char[end];
00298 str[end-1] = 0;
00299 strncpy (str, start+3, end);
00300
00301 if (the_player->storage::get_val ("gender") == FEMALE)
00302 mid = get_substr (str, "{", "/");
00303 else
00304 mid = get_substr (str, "/", "}");
00305
00306 begin = newstr.length () - strlen(start);
00307 tmp = new char[newstr.length () - end + strlen (mid)];
00308 strncpy (tmp, newstr.c_str (), begin);
00309 tmp[begin] = 0;
00310 strcat (tmp, mid);
00311 strcat (tmp, start+end+1);
00312
00313 delete[] str;
00314 delete[] mid;
00315 newstr = tmp;
00316
00317 continue;
00318 }
00319
00320
00321 cout << "\n*** Error, unknown macro " << start << flush;
00322 newstr[newstr.length () - strlen (start)] = ' ';
00323 }
00324
00325
00326 while (1)
00327 {
00328
00329 start = strchr (newstr.c_str (), '{');
00330 if (start == NULL) break;
00331
00332 end = strcspn (start, "}");
00333 mid = NULL;
00334
00335 str = new char[end];
00336 str[end-1] = 0;
00337
00338
00339 strncpy (str, start+1, end-1);
00340
00341
00342 result = PyObject_CallMethod (dialogue.get_instance (false), str, NULL);
00343
00344 if (result)
00345 if (PyString_Check (result))
00346 mid = (char*) nls::translate (PyString_AS_STRING (result));
00347
00348
00349
00350 len = newstr.length ();
00351 begin = len - strlen (start);
00352 tmp = new char[(mid ? strlen(mid) : 0) + len - strlen(str)];
00353
00354
00355 strncpy (tmp, newstr.c_str (), begin);
00356 tmp[begin] = 0;
00357 if (mid) strcat (tmp, mid);
00358 strcat (tmp, start+end+1);
00359
00360
00361 newstr = tmp;
00362
00363
00364 Py_XDECREF (result);
00365 delete[] str;
00366 delete[] tmp;
00367 }
00368
00369 return newstr;
00370 }
00371
00372 char *dialog::get_substr (const char* string, const char* begin, const char* end)
00373 {
00374 u_int32 b, e;
00375 b = strcspn (string, begin) + 1;
00376 e = strcspn (string, end) - b;
00377
00378 char *result = new char[e+1];
00379 strncpy (result, string+b, e);
00380 result[e] = 0;
00381
00382 return result;
00383 }