Adonthell  0.4
dialog_screen.cc
Go to the documentation of this file.
1 /*
2  $Id: dialog_screen.cc,v 1.12 2004/10/25 06:55:01 ksterker Exp $
3 
4  (C) Copyright 2000/2001/2004 Kai Sterker <kaisterker@linuxgames.com>
5  Part of the Adonthell Project http://adonthell.linuxgames.com
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details
13 */
14 
15 
16 /**
17  * @file dialog_screen.cc
18  * @author Kai Sterker <kaisterker@linuxgames.com>
19  *
20  * @brief Defines the dialog_screen class.
21  *
22  *
23  */
24 
25 
26 #include <iostream>
27 
28 #include "gamedata.h"
29 #include "input.h"
30 #include "image.h"
31 #include "python_class.h"
32 #include "input.h"
33 #include "dialog_screen.h"
34 #include "win_manager.h"
35 
36 #include "audio.h"
37 
38 // Init the dialogue engine
39 dialog_screen::dialog_screen (character_base *mynpc, char * dlg_file, u_int8 size)
40 {
41  init (mynpc, dlg_file, size);
42 }
43 
44 void dialog_screen::init(character_base *mynpc, char * dlg_file, u_int8 size)
45 {
46  string path = dlg_file;
47  string file = strrchr (dlg_file, '.') ? strrchr (dlg_file, '.') + 1 : dlg_file;
48 
49  audio::play_wave (-1, 0);
50  is_running = true;
51  portrait = "None";
52 
53  // Init position & size
54  win_container::move (15, 15);
55  win_container::resize (290, 115);
56 
57  // Load the different fonts
58  fonts[0] = win_manager::get_font ("white");
59  fonts[1] = win_manager::get_font ("yellow");
60  fonts[2] = win_manager::get_font ("red");
61  fonts[3] = win_manager::get_font ("violet");
62  fonts[4] = win_manager::get_font ("blue");
63  fonts[5] = win_manager::get_font ("green");
64 
65  theme = win_manager::get_theme ("original");
66 
67  set_border (*theme);
68  set_background (*theme);
69  set_trans_background (true);
70 
71  // Full or half-sized window
72  if (size)
73  {
74  move (20, 15);
75  resize (280, 210);
76  }
77 
78  // Init the low level dialogue stuff
79  dlg = new dialog (mynpc);
80 
81  // Create dialogue window
82  // The NPC's portrait
83  face = new win_image();
84  face->move (5, 5);
85  ((image*)face)->resize (64, 64);
86  face->pack();
87  face->set_visible (true);
88 
89  // The NPC's name
90  name = new win_label ();
91  name->set_font (*(fonts[0]));
92  name->move (5, 74);
93  ((label*)name)->resize (64, 0);
94  name->set_form (label::AUTO_HEIGHT);
95  name->set_visible (true);
96 
97  // The list with the dialogue
98  sel = new win_select ();
99  sel->set_scrollbar (*theme);
100  sel->move (80, 0);
101  sel->resize (210, height ());
102  sel->set_mode (win_select::MODE_BRIGHTNESS);
103  sel->set_layout (win_container::LIST_LAYOUT);
104  sel->set_space_with_border (5);
105  sel->set_space_with_object (5);
106  sel->set_circle (true);
107  sel->set_visible_scrollbar (true);
108  // Commented 'cause it makes troubles during dialogues right now :)
109  // sel->set_auto_scrollbar (true);
110  sel->set_activate (true);
111 
112  sel->set_visible (true);
113  sel->set_focus (true); //due an error from window system
114 
115  // Notification when a dialogue item get's selected
116  sel->set_signal_connect (makeFunctor (*this, &dialog_screen::on_select),
117  win_event::ACTIVATE_KEY);
118 
119  // add everything to our container
120  add (face);
121  add (name);
122  add (sel);
123  set_focus_object (sel);
124 
125  set_visible_border (true);
126  set_visible_background (true);
127 
128  set_visible (true);
129  set_activate (true);
130 
131  // Make the npc and player available to the dialogue engine
132  PyObject *args = PyTuple_New (2);
133  PyTuple_SetItem (args, 0, python::pass_instance (data::the_player, "character"));
134  PyTuple_SetItem (args, 1, python::pass_instance (mynpc, "character_base"));
135 
136  // Load dialogue
137  if (!dlg->init (path, file, args))
138  {
139  cout << "\n*** Error loading dialogue script " << file << "\n";
140 #ifdef PY_DEBUG
142 #endif
143  cout << flush;
144  answer = -1;
145  }
146  else answer = 0;
147 
148  // Clean up
149  Py_DECREF (args);
150 }
151 
153 {
154  sel->set_activate (false);
155 
156  delete dlg;
157 
158  // get rid of any keys that might have been accidently pressed during dialogue
160 }
161 
163 {
164  u_int32 i = 0;
165  win_label *l;
166 
167  // Possibly error
168  if (answer < 0)
169  {
170  is_running = false;
171  return;
172  }
173 
174  // Continue dialogue with selected answer
175  dlg->run (answer);
176 
177  // End of dialogue
178  if (dlg->text_size () == 0)
179  {
180  is_running = false;
181  return;
182  }
183 
184  // update the NPC's portrait and name
185  set_portrait (dlg->npc_portrait ());
186  set_name (dlg->npc_name ());
187 
188  // Add NPC text and all player reactions to container
189  for (string txt = dlg->text (); txt != ""; txt = dlg->text (), i++)
190  {
191  l = new win_label();
192  l->set_font (i == 0 ? *fonts[dlg->npc_color ()] : *fonts[1]);
193  l->move(0,0);
194  ((label*)l)->resize(190,0);
195  l->set_form(label::AUTO_HEIGHT);
196  l->set_text (txt);
197  l->set_visible (true);
198  l->pack();
199  cur_answers.push_back (l);
200  sel->add (l);
201  }
202 
203  // Either select the single NPC speech ...
204  if (dlg->text_size () == 1)
205  sel->set_default_object (cur_answers.front ());
206 
207  // ... or the player's first answer
208  else
209  {
210  cur_answers[0]->set_can_be_selected (false);
211  sel->set_default_object (cur_answers[1]);
212  }
213 
214  // Center on the NPC answer
215  sel->set_pos (0);
216 }
217 
219 {
220  return (win_container::update() && is_running);
221 }
222 
223 void dialog_screen::on_select ()
224 {
225  // remember choice
226  answer = sel->get_selected_position () - 1;
227 
228  // remove all the text
229  sel->destroy ();
230 
231  cur_answers.clear ();
232 
233  run ();
234 }
235 
236 void dialog_screen::insert_plugin ()
237 {
238 }
239 
240 // Set / change the NPC-portrait
241 void dialog_screen::set_portrait (const string & new_portrait)
242 {
243  if (new_portrait == portrait) return;
244  else portrait = new_portrait;
245 
246  if (new_portrait == "")
247  {
248  face->image::resize (64, 64);
249  face->fillrect (0, 0, 64, 64, 0x00ff00ff);
250  return;
251  }
252  face->load_pnm(string ("gfx/portraits/") + new_portrait);
253  face->set_mask(true);
254  face->pack();
255 }
256 
257 // Set / change the NPC-name
258 void dialog_screen::set_name (const string & new_name)
259 {
260  name->set_text (new_name);
261  name->pack ();
262 }
263 
264 // Set a different NPC
265 void dialog_screen::set_npc (const string & new_npc)
266 {
267  character_base *mynpc = (character_base *) data::characters[new_npc.c_str ()];
268 
269  set_name (mynpc->get_name());
270  set_portrait (mynpc->get_portrait ());
271 }