Adonthell  0.4
dialog_screen.cc
Go to the documentation of this file.
1 /*
2  (C) Copyright 2000/2001/2004 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 
20 /**
21  * @file dialog_screen.cc
22  * @author Kai Sterker <kai.sterker@gmail.com>
23  *
24  * @brief Defines the dialog_screen class.
25  *
26  *
27  */
28 
29 
30 #include <iostream>
31 
32 #include "gamedata.h"
33 #include "input.h"
34 #include "image.h"
35 #include "python_class.h"
36 #include "input.h"
37 #include "dialog_screen.h"
38 #include "win_manager.h"
39 
40 #include "audio.h"
41 
42 // Init the dialogue engine
43 dialog_screen::dialog_screen (character_base *mynpc, char * dlg_file, u_int8 size)
44 {
45  init (mynpc, dlg_file, size);
46 }
47 
48 void dialog_screen::init(character_base *mynpc, char * dlg_file, u_int8 size)
49 {
50  string path = dlg_file;
51  string file = strrchr (dlg_file, '.') ? strrchr (dlg_file, '.') + 1 : dlg_file;
52 
53  audio::play_wave (-1, 0);
54  is_running = true;
55  portrait = "None";
56 
57  // Init position & size
58  win_container::move (15, 15);
59  win_container::resize (290, 115);
60 
61  // Load the different fonts
62  fonts[0] = win_manager::get_font ("white");
63  fonts[1] = win_manager::get_font ("yellow");
64  fonts[2] = win_manager::get_font ("red");
65  fonts[3] = win_manager::get_font ("violet");
66  fonts[4] = win_manager::get_font ("blue");
67  fonts[5] = win_manager::get_font ("green");
68 
69  theme = win_manager::get_theme ("original");
70 
71  set_border (*theme);
72  set_background (*theme);
73  set_trans_background (true);
74 
75  // Full or half-sized window
76  if (size)
77  {
78  move (20, 15);
79  resize (280, 210);
80  }
81 
82  // Init the low level dialogue stuff
83  dlg = new dialog (mynpc);
84 
85  // Create dialogue window
86  // The NPC's portrait
87  face = new win_image();
88  face->move (5, 5);
89  ((image*)face)->resize (64, 64);
90  face->pack();
91  face->set_visible (true);
92 
93  // The NPC's name
94  name = new win_label ();
95  name->set_font (*(fonts[0]));
96  name->move (5, 74);
97  ((label*)name)->resize (64, 0);
98  name->set_form (label::AUTO_HEIGHT);
99  name->set_visible (true);
100 
101  // The list with the dialogue
102  sel = new win_select ();
103  sel->set_scrollbar (*theme);
104  sel->move (80, 0);
105  sel->resize (210, height ());
106  sel->set_mode (win_select::MODE_BRIGHTNESS);
107  sel->set_layout (win_container::LIST_LAYOUT);
108  sel->set_space_with_border (5);
109  sel->set_space_with_object (5);
110  sel->set_circle (true);
111  sel->set_visible_scrollbar (true);
112  // Commented 'cause it makes troubles during dialogues right now :)
113  // sel->set_auto_scrollbar (true);
114  sel->set_activate (true);
115 
116  sel->set_visible (true);
117  sel->set_focus (true); //due an error from window system
118 
119  // Notification when a dialogue item get's selected
120  sel->set_signal_connect (makeFunctor (*this, &dialog_screen::on_select),
121  win_event::ACTIVATE_KEY);
122 
123  // add everything to our container
124  add (face);
125  add (name);
126  add (sel);
127  set_focus_object (sel);
128 
129  set_visible_border (true);
130  set_visible_background (true);
131 
132  set_visible (true);
133  set_activate (true);
134 
135  // Make the npc and player available to the dialogue engine
136  PyObject *args = PyTuple_New (2);
137  PyTuple_SetItem (args, 0, python::pass_instance (data::the_player, "character"));
138  PyTuple_SetItem (args, 1, python::pass_instance (mynpc, "character_base"));
139 
140  // Load dialogue
141  if (!dlg->init (path, file, args))
142  {
143  cout << "\n*** Error loading dialogue script " << file << "\n";
144 #ifdef PY_DEBUG
146 #endif
147  cout << flush;
148  answer = -1;
149  }
150  else answer = 0;
151 
152  // Clean up
153  Py_DECREF (args);
154 }
155 
157 {
158  sel->set_activate (false);
159 
160  delete dlg;
161 
162  // get rid of any keys that might have been accidently pressed during dialogue
164 }
165 
167 {
168  u_int32 i = 0;
169  win_label *l;
170 
171  // Possibly error
172  if (answer < 0)
173  {
174  is_running = false;
175  return;
176  }
177 
178  // Continue dialogue with selected answer
179  dlg->run (answer);
180 
181  // End of dialogue
182  if (dlg->text_size () == 0)
183  {
184  is_running = false;
185  return;
186  }
187 
188  // update the NPC's portrait and name
189  set_portrait (dlg->npc_portrait ());
190  set_name (dlg->npc_name ());
191 
192  // Add NPC text and all player reactions to container
193  for (string txt = dlg->text (); txt != ""; txt = dlg->text (), i++)
194  {
195  l = new win_label();
196  l->set_font (i == 0 ? *fonts[dlg->npc_color ()] : *fonts[1]);
197  l->move(0,0);
198  ((label*)l)->resize(190,0);
199  l->set_form(label::AUTO_HEIGHT);
200  l->set_text (txt);
201  l->set_visible (true);
202  l->pack();
203  cur_answers.push_back (l);
204  sel->add (l);
205  }
206 
207  // Either select the single NPC speech ...
208  if (dlg->text_size () == 1)
209  sel->set_default_object (cur_answers.front ());
210 
211  // ... or the player's first answer
212  else
213  {
214  cur_answers[0]->set_can_be_selected (false);
215  sel->set_default_object (cur_answers[1]);
216  }
217 
218  // Center on the NPC answer
219  sel->set_pos (0);
220 }
221 
223 {
224  return (win_container::update() && is_running);
225 }
226 
227 void dialog_screen::on_select ()
228 {
229  // remember choice
230  answer = sel->get_selected_position () - 1;
231 
232  // remove all the text
233  sel->destroy ();
234 
235  cur_answers.clear ();
236 
237  run ();
238 }
239 
240 void dialog_screen::insert_plugin ()
241 {
242 }
243 
244 // Set / change the NPC-portrait
245 void dialog_screen::set_portrait (const string & new_portrait)
246 {
247  if (new_portrait == portrait) return;
248  portrait = new_portrait;
249 
250  if (new_portrait == "")
251  {
252  face->image::resize (64, 64);
253  face->fillrect (0, 0, 64, 64, 0x00ff00ff);
254  return;
255  }
256  face->load_pnm(string ("gfx/portraits/") + new_portrait);
257  face->set_mask(true);
258  face->pack();
259 }
260 
261 // Set / change the NPC-name
262 void dialog_screen::set_name (const string & new_name)
263 {
264  if (new_name == name->text_string()) return;
265 
266  name->set_text (new_name);
267  name->pack ();
268 }
269 
270 // Set a different NPC
271 void dialog_screen::set_npc (const string & new_npc)
272 {
273  character_base *mynpc = (character_base *) data::characters[new_npc.c_str ()];
274 
275  set_name (mynpc->get_name());
276  set_portrait (mynpc->get_portrait ());
277 }
u_int16 height() const
Returns the height of the drawing_area.
Definition: drawing_area.h:101
static win_font * get_font(string name)
Returns a pointer to a font.
Definition: win_manager.cc:252
const string & npc_name()
Returns the name to be displayed under the NPC&#39;s portrait.
Definition: dialog.h:134
virtual void move(s_int16 tx, s_int16 ty)
Move the win_*.
Definition: win_base.cc:75
Declares the input class.
void run(u_int32 index)
Run the dialogue.
Definition: dialog.cc:143
void set_portrait(const string &new_portrait)
Changes the displayed NPC portrait.
string text()
Iterates over the dialogue&#39;s text.
Definition: dialog.cc:131
static win_theme * get_theme(string name)
Returns a pointer to a theme.
Definition: win_manager.cc:221
void set_visible(const bool b)
Set the visible parameter.
Definition: win_base.h:140
Image manipulation class.
Definition: image.h:45
void resize(u_int16, u_int16)
Rezise the win_*.
#define u_int32
32 bits long unsigned integer
Definition: types.h:41
void move(s_int16, s_int16)
Move the win_*.
The lowlevel dialog class.
Definition: dialog.h:48
#define u_int8
8 bits long unsigned integer
Definition: types.h:35
string get_portrait() const
Returns the current portrait of the character.
static void show_traceback(void)
Dumps any error information to stderr.
Base character class containing attributes and dialog stuff.
Declares the image class.
void resize(u_int16 tl, u_int16 th)
Rezise the win_*.
Definition: win_scroll.cc:57
Declares the gamedata and data classes.
Declares the dialog_screen class.
~dialog_screen()
Destructor.
void run()
Execute one step of the dialogue.
u_int32 text_size()
Returns the number of text lines available at this point of the dialoge.
Definition: dialog.h:145
Definition: label.h:29
static PyObject * pass_instance(void *instance, const char *class_name)
Magic function that makes any C object available to Python!
void set_focus(const bool b)
Set the focus parameter.
Definition: win_base.h:170
bool update()
React to (keyboard) input.
dialog_screen(character_base *mynpc, char *dlg_file, u_int8 size=1)
Constructor.
Defines the python class. This file is named this way so it doesn&#39;t conflicts with Python...
void set_npc(const string &new_npc)
Changes the whole NPC.
const string & npc_portrait()
Returns the image to be displayed next to the NPC&#39;s speech.
Definition: dialog.h:126
A* pathfinding algorithm implementation class.
Definition: path.h:52
u_int32 npc_color()
Returns the color to be used for displaying the NPC&#39;s speech.
Definition: dialog.h:118
void init(character_base *mynpc, char *dlg_file, u_int8 size=1)
Inits the dialogue engine (similar to a constructor call).
static void clear_keys_queue()
Totally clears the key queue.
Definition: input.cc:168
string get_name() const
Returns the name of the character.
Declares the win_manager class.
virtual bool update()
Update process.
void set_name(const string &new_name)
Changes the displayed NPC name.
void set_activate(const bool b)
Set the activate parameter When a win_* is setup on, the keys queue is cleared.
Definition: win_base.h:156
bool init(string fpath, string name, PyObject *args)
Load and instanciate the dialog object.
Definition: dialog.cc:52